IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Apr 16, 2020, 1:54:47 PM (6 years ago)
Author:
tdeboer
Message:

revert to working Ohana build

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/opihi/lib.shell/VectorIO.c

    r41269 r41340  
    22void gfits_compress_timing ();
    33 
    4 static int VectorGetMaxStringLength (Vector *vec) {
    5 
    6   int MaxLength = 0;
    7 
    8   if (vec[0].type != OPIHI_STR) return 0;
    9 
    10   for (int i = 0; i < vec[0].Nelements; i++) {
    11     MaxLength = MAX (MaxLength, strlen(vec[0].elements.Str[i]));
    12   }
    13   return MaxLength;
    14 }
    15 
    164// write a set of vectors to a FITS FTable structure (vectors names become fits column names)
    175static int WriteVectorTable (FTable *ftable, char *extname, Vector **vec, int Nvec, char *format, char nativeOrder) {
     
    197  int j;
    208
     9  char *tformat = NULL;
     10
    2111  Header *theader = ftable->header;
    2212  gfits_create_table_header (theader, "BINTABLE", extname);
    2313
    24   // allocate an array of strings to represent the format for each output field
    25   // formats include single column formats (BIJKDE) and multi-column formats (e.g., 2I)
    26   // we will have no more than Nvec fields (but we can have fewer)
    27   int Nfield = 0;
    28   ALLOCATE_PTR (tformat, char *, Nvec);
    29   ALLOCATE_PTR (Nelement, int, Nvec);
    30 
     14  ALLOCATE (tformat, char, 2*Nvec);
    3115  if (format) {
    32     // the bintable format string can defines the byte-width of each field and number of elements (columns per field).
    33     // valid output columns are currently:
     16    // the bintable format string can only define the byte-width of each field.  valid output columns are currently:
    3417    // B (char), I (16 bit short), J (32 bit int), E (32 bit float), D (64 bit double).
    35     // the format string is just the sequence of types, eg: LIIJEED.
    36     // it may have spaces or integer element counts:
    37     // "2D 4I EEJ"
    38 
    39     // *** validate the format string
    40 
    41     // as I parse each elements, if it is a digit, I need parse that value
    42 
     18    // the format string is just the sequence of types, eg: LIIJEED
     19    // validate the format string
    4320    char *ptr = format;
    44     for (j = 0; j < Nvec; ) {
     21    for (j = 0; j < Nvec; j++) {
    4522      while (*ptr && OHANA_WHITESPACE (*ptr)) ptr++;
    4623      if (*ptr == 0) {
     
    4825        goto escape;
    4926      }
    50 
    51       // is there a leading integer?
    52       char *endptr;
    53       Nelement[Nfield] = strtol (ptr, &endptr, 10);
    54       if (endptr == ptr) {
    55         Nelement[Nfield] = 1;
    56       }
    57       ptr = endptr; // this should now point at the letter that is the format type
    58       if ((*ptr != 'B') && (*ptr != 'I') && (*ptr != 'J') && (*ptr != 'K') && (*ptr != 'D') && (*ptr != 'E') && (*ptr != 'A')) {
     27      if ((*ptr != 'B') && (*ptr != 'I') && (*ptr != 'J') && (*ptr != 'K') && (*ptr != 'D') && (*ptr != 'E')) {
    5928        gprint (GP_ERR, "error in binary table format %s: invalid character %c\n", format, *ptr);
    6029        goto escape;
    6130      }
    62 
    63       int Nchar = snprintf (tformat[Nfield], 0, "%d%c", Nelement[Nfield], *ptr);
    64       ALLOCATE (tformat[Nfield], char, Nchar + 1);
    65       int Nout = snprintf (tformat[Nfield], Nchar + 1, "%d%c", Nelement[Nfield], *ptr);
    66       myAssert (Nout <= Nchar, "oops");
    67 
    68       // tformat[2*j + 0] = *ptr;
    69       // tformat[2*j + 1] = 0; // a bit sleazy : use a 2xN string to store N 1-byte strings
    70 
    71       // For numeric multi-valued fields, the number of elements from the format defines the number of
    72       // vectors which go into that field.  For string-type vectors, the format specifies the maximum number of characters
    73       // that go into the field.
    74 
    75       // for example, a format code of 3E should match a list of three numeric-type vectors while a format code of 15A should
    76       // match a single string-type vector which will supply up to 15 chars per row.
    77 
    78       if (*ptr != 'A') {
    79         j += Nelement[Nfield]; // advance past Nelement vectors
    80       } else {
    81         if (vec[j][0].type != OPIHI_STR) {
    82           gprint (GP_ERR, "error in binary table format %s (mismatch between string format and numeric vector %s)\n", format, vec[j][0].name);
    83           goto escape;
    84         }
    85         j ++; // advance past a single string-type vector (validate that?)
    86       }
    87       if (j > Nvec) {
    88         gprint (GP_ERR, "error in binary table format %s (too few vectors for listed field)\n", format);
    89         goto escape;
    90       }
    91 
     31      tformat[2*j + 0] = *ptr;
     32      tformat[2*j + 1] = 0; // a bit sleazy : use a 2xN string to store N 1-byte strings
    9233      ptr ++;
    93       Nfield ++;
    9434    }
    9535    while (*ptr && OHANA_WHITESPACE (*ptr)) ptr++;
     
    10040  } else {
    10141    for (j = 0; j < Nvec; j++) {
    102       switch (vec[j][0].type) {
    103         case OPIHI_FLT:
    104         case OPIHI_INT:
    105           // if the format is not defined, just use the native byte-widths
    106           ALLOCATE (tformat[j], char, 2);
    107           tformat[j][0] = (vec[j][0].type == OPIHI_FLT) ? 'D' : 'K';
    108           tformat[j][1] = 0;
    109           Nelement[j] = 1;
    110           break;
    111         case OPIHI_STR:
    112           // we need to examine the vector to determine the length
    113           Nelement[j] = VectorGetMaxStringLength(vec[j]);
    114           int Nchar = snprintf (tformat[j], 0, "%d%c", Nelement[j], 'A');
    115           ALLOCATE (tformat[j], char, Nchar + 1);
    116           int Nout = snprintf (tformat[j], Nchar + 1, "%d%c", Nelement[j], 'A');
    117           myAssert (Nout <= Nchar, "oops");
    118           break;
    119       }
    120     }
    121     Nfield = Nvec;
     42      // if the format is not defined, just use the native byte-widths
     43      tformat[2*j + 0] = (vec[j][0].type == OPIHI_FLT) ? 'D' : 'K'; // this depends on opihi_int == int64_t for Int
     44      tformat[2*j + 1] = 0;
     45    }
    12246  }
    12347
     
    12549  // output table (because the data goes to the named column below).  need to enforce
    12650  // this somehow
    127   int ivec = 0;
    128   for (j = 0; j < Nfield; j++) {
    129     // XX need to loop over fields, and skip the additional vectors that are part of a field
    130     // this call supported multiple columns per named field
    131     gfits_define_bintable_column (theader, tformat[j], vec[ivec][0].name, NULL, NULL, 1.0, 0.0);
    132     if (vec[ivec][0].type == OPIHI_STR) {
    133       ivec ++;
    134     } else {
    135       ivec += Nelement[j];
    136     }
    137   }
    138 
    139   // need to free the array
    140   for (j = 0; j < Nfield; j++) {
    141     free (tformat[j]);
     51  for (j = 0; j < Nvec; j++) {
     52    gfits_define_bintable_column (theader, &tformat[2*j], vec[j][0].name, NULL, NULL, 1.0, 0.0);
    14253  }
    14354  free (tformat);
     
    14657  gfits_create_table (theader, ftable);
    14758
    148   // I need to add each vector in order, but I need to
    149   // track which field it corresponds to.
    150 
    15159  // add the vectors to the output array
    152   for (ivec = 0, j = 0; j < Nfield; j++) {
    153     // the first vector provides the name for the field
    154     char *fieldname = vec[ivec][0].name;
    155 
    156     if (vec[ivec][0].type == OPIHI_STR) {
    157       // string-type vectors need to be copied into a contiguous buffer with the right dimensions:
    158       Vector *thisvec = vec[ivec];
    159 
    160       ALLOCATE_PTR (strbuffer, char, Nelement[j]*thisvec->Nelements);
    161       for (int i = 0; i < thisvec->Nelements; i++) {
    162         int nChar = MIN (strlen (thisvec->elements.Str[i]), Nelement[j]);
    163         // fprintf (stderr, "%d %d %d : %d : %d : %s\n", ivec, j, i, Nelement[j], nChar, thisvec->elements.Str[i]);
    164         memcpy (&strbuffer[i*Nelement[j]], thisvec->elements.Str[i], nChar);
    165       }
    166       gfits_set_bintable_column (theader, ftable, fieldname, strbuffer, thisvec->Nelements);
    167       free (strbuffer);
    168       ivec ++;
     60  for (j = 0; j < Nvec; j++) {
     61    if (vec[j][0].type == OPIHI_FLT) {
     62      gfits_set_bintable_column_reformat (theader, ftable, vec[j][0].name, "double",  vec[j][0].elements.Flt, vec[j][0].Nelements, nativeOrder);
    16963    } else {
    170       for (int k = 0; k < Nelement[j]; k++, ivec++) {
    171         Vector *thisvec = vec[ivec];
    172         switch (thisvec->type) {
    173           case OPIHI_FLT:
    174             gfits_set_bintable_column_reformat (theader, ftable, fieldname, "double",  thisvec->elements.Flt, thisvec->Nelements, k, nativeOrder);
    175             break;
    176           case OPIHI_INT:
    177             gfits_set_bintable_column_reformat (theader, ftable, fieldname, "int64_t", thisvec->elements.Int, thisvec->Nelements, k, nativeOrder);
    178             break;
    179         }
    180       }
     64//    gfits_set_bintable_column_reformat (theader, ftable, vec[j][0].name, "int",     vec[j][0].elements.Int, vec[j][0].Nelements, nativeOrder);
     65      gfits_set_bintable_column_reformat (theader, ftable, vec[j][0].name, "int64_t", vec[j][0].elements.Int, vec[j][0].Nelements, nativeOrder);
    18166    }
    18267  }
     
    225110}
    226111
    227 // insert a new header line, return end pointer
    228 char *gfits_insert_header_line (Header *header, char *endptr, char *newline) {
    229 
    230   if (0) {
    231     char temp1[32], temp2[32];
    232     memset (temp1, 0, 32);
    233     memset (temp2, 0, 32);
    234 
    235     if (endptr) {
    236       memcpy (temp1, endptr, 8);
    237     }
    238     memcpy (temp2, newline, 8);
    239     fprintf (stderr, "insert: %s : %s\n", temp1, temp2);
    240   }
    241 
    242   /* find the END of the header, if not supplied */
    243   if (!endptr) {
    244     endptr = gfits_header_field (header, "END", 1);
    245     if (endptr == NULL) return NULL;
    246   }
    247 
    248   /* is there enough space for 1 more line? */
    249   if (header[0].datasize - (endptr - (header[0].buffer)) < 2*FT_LINE_LENGTH) {
    250     // no, so expand by a full header block (FT_RECORD_SIZE = 32*80 = 2880)
    251     header[0].datasize += FT_RECORD_SIZE;
    252     REALLOCATE (header[0].buffer, char, header[0].datasize);
    253     // re-find the "END" marker, in case new memory block is used
    254     endptr = gfits_header_field (header, "END", 1);
    255     if (endptr == NULL) return NULL;
    256     memset (endptr + FT_LINE_LENGTH, ' ', FT_RECORD_SIZE);
    257   }
    258 
    259   /* push END line back 1 */
    260   memmove ((endptr + FT_LINE_LENGTH), endptr, FT_LINE_LENGTH);
    261   memset (endptr, ' ', FT_LINE_LENGTH);
    262 
    263   strncpy (endptr, newline, 80);
    264   endptr += FT_LINE_LENGTH;
    265 
    266   return endptr;
    267 }
    268  
    269 static char *rawkeywords[] = {"SIMPLE", "BITPIX", "NAXIS", "PCOUNT", "GCOUNT", "EXTEND", "EXTNAME", "BSCALE", "BZERO", "TFIELDS", "TFORM", "TZERO", "TSCAL", "        ", NULL};
    270 
    271112// write a set of vectors to a FITS file (vectors names become fits column names)
    272 int WriteVectorTableFITS (char *filename, char *extname, Header *extraheader, Vector **vec, int Nvec, int append, char *compress, char *format, int Ntile) {
     113int WriteVectorTableFITS (char *filename, char *extname, Vector **vec, int Nvec, int append, char *compress, char *format, int Ntile) {
    273114 
    274115  Header rawheader;
     
    298139  rawtable.header = &rawheader;
    299140  if (!WriteVectorTable (&rawtable, extname, vec, Nvec, format, (compress != NULL))) goto escape;
    300   // NOTE : for compression, the table is constructed in native byte order
     141  // NOTE : for compression, the table is constructed in native by order
    301142
    302143  FTable *outtable = &rawtable;
     
    322163
    323164  if (!append) {
    324     // generate a blank PHU header
    325165    Header header;
    326166    Matrix matrix;
     
    336176  }
    337177
    338   if (extraheader) {
    339     // copy keywords which are not the standard or table keywords
    340     char *buf = extraheader->buffer;
    341     char *endptr = NULL;
    342     for (int i = 0; i < extraheader->datasize; i+= FT_LINE_LENGTH, buf += FT_LINE_LENGTH) {
    343 
    344       if (0) {
    345         char temp1[32];
    346         memset (temp1, 0, 32);
    347         memcpy (temp1, buf, 8);
    348         fprintf (stderr, "buffer: %s\n", temp1);
    349       }
    350 
    351       for (int j = 0; rawkeywords[j] != NULL; j++) {
    352         if (!strncmp (buf, rawkeywords[j], strlen(rawkeywords[j]))) goto skip_insert;
    353       }
    354       endptr = gfits_insert_header_line (outheader, endptr, buf);
    355       if (!endptr) {
    356         gprint (GP_ERR, "failed to update FITS header with extra keywords\n");
    357         return (FALSE);
    358       }
    359     skip_insert:
    360       continue;
    361     }
    362   }
    363 
    364178  // write the actual table data
    365179  gfits_fwrite_Theader (f, outheader);
Note: See TracChangeset for help on using the changeset viewer.