IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Nov 27, 2019, 12:09:13 PM (6 years ago)
Author:
eugene
Message:

enable multicolumn output fits tables; add bitshifts using <~ and ~>

Location:
trunk/Ohana
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana

  • trunk/Ohana/src/opihi/lib.shell/VectorIO.c

    r41161 r41176  
    77  int j;
    88
    9   char *tformat = NULL;
    10 
    119  Header *theader = ftable->header;
    1210  gfits_create_table_header (theader, "BINTABLE", extname);
    1311
    14   ALLOCATE (tformat, char, 2*Nvec);
     12  // allocate an array of strings to represent the format for each output field
     13  // formats include single column formats (BIJKDE) and multi-column formats (e.g., 2I)
     14  // we will have no more than Nvec fields (but we can have fewer)
     15  int Nfield = 0;
     16  ALLOCATE_PTR (tformat, char *, Nvec);
     17  ALLOCATE_PTR (Nelement, int, Nvec);
     18
    1519  if (format) {
    16     // the bintable format string can only define the byte-width of each field.  valid output columns are currently:
     20    // the bintable format string can defines the byte-width of each field and number of elements (columns per field).
     21    // valid output columns are currently:
    1722    // B (char), I (16 bit short), J (32 bit int), E (32 bit float), D (64 bit double).
    18     // the format string is just the sequence of types, eg: LIIJEED
    19     // validate the format string
     23    // the format string is just the sequence of types, eg: LIIJEED.
     24    // it may have spaces or integer element counts:
     25    // "2D 4I EEJ"
     26
     27    // *** validate the format string
     28
     29    // as I parse each elements, if it is a digit, I need parse that value
     30
    2031    char *ptr = format;
    21     for (j = 0; j < Nvec; j++) {
     32    for (j = 0; j < Nvec; ) {
    2233      while (*ptr && OHANA_WHITESPACE (*ptr)) ptr++;
    2334      if (*ptr == 0) {
     
    2536        goto escape;
    2637      }
     38
     39      // is there a leading integer?
     40      char *endptr;
     41      Nelement[Nfield] = strtol (ptr, &endptr, 10);
     42      if (endptr == ptr) {
     43        Nelement[Nfield] = 1;
     44      }
     45      ptr = endptr; // this should now point at the letter that is the format type
    2746      if ((*ptr != 'B') && (*ptr != 'I') && (*ptr != 'J') && (*ptr != 'K') && (*ptr != 'D') && (*ptr != 'E')) {
    2847        gprint (GP_ERR, "error in binary table format %s: invalid character %c\n", format, *ptr);
    2948        goto escape;
    3049      }
    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
     50
     51      int Nchar = snprintf (tformat[Nfield], 0, "%d%c", Nelement[Nfield], *ptr);
     52      ALLOCATE (tformat[Nfield], char, Nchar + 1);
     53      int Nout = snprintf (tformat[Nfield], Nchar + 1, "%d%c", Nelement[Nfield], *ptr);
     54      myAssert (Nout <= Nchar, "oops");
     55
     56      // tformat[2*j + 0] = *ptr;
     57      // tformat[2*j + 1] = 0; // a bit sleazy : use a 2xN string to store N 1-byte strings
     58
     59      j += Nelement[Nfield]; // advance past
     60      if (j > Nvec) {
     61        gprint (GP_ERR, "error in binary table format %s (too few vectors for listed field)\n", format);
     62        goto escape;
     63      }
     64
    3365      ptr ++;
     66      Nfield ++;
    3467    }
    3568    while (*ptr && OHANA_WHITESPACE (*ptr)) ptr++;
     
    4174    for (j = 0; j < Nvec; j++) {
    4275      // 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     }
     76      ALLOCATE (tformat[j], char, 2);
     77      tformat[j][0] = (vec[j][0].type == OPIHI_FLT) ? 'D' : 'K'; // this depends on opihi_int == int64_t for Int
     78      tformat[j][1] = 0;
     79      Nelement[j] = 1;
     80    }
     81    Nfield = Nvec;
    4682  }
    4783
     
    4985  // output table (because the data goes to the named column below).  need to enforce
    5086  // this somehow
    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);
     87  int ivec = 0;
     88  for (j = 0; j < Nfield; j++) {
     89    // XX need to loop over fields, and skip the additional vectors that are part of a field
     90    // this call supported multiple columns per named field
     91    gfits_define_bintable_column (theader, tformat[j], vec[ivec][0].name, NULL, NULL, 1.0, 0.0);
     92    ivec += Nelement[j];
     93  }
     94
     95  // need to free the array
     96  for (j = 0; j < Nfield; j++) {
     97    free (tformat[j]);
    5398  }
    5499  free (tformat);
     
    57102  gfits_create_table (theader, ftable);
    58103
     104  // I need to add each vector in order, but I need to
     105  // track which field it corresponds to.
     106
    59107  // add the vectors to the output array
    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);
    63     } else {
    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);
     108  for (ivec = 0, j = 0; j < Nfield; j++) {
     109    // the first vector provides the name for the field
     110    char *fieldname = vec[ivec][0].name;
     111    for (int k = 0; k < Nelement[j]; k++, ivec++) {
     112      Vector *thisvec = vec[ivec];
     113      if (thisvec->type == OPIHI_FLT) {
     114        gfits_set_bintable_column_reformat (theader, ftable, fieldname, "double",  thisvec->elements.Flt, thisvec->Nelements, k, nativeOrder);
     115      } else {
     116        gfits_set_bintable_column_reformat (theader, ftable, fieldname, "int64_t", thisvec->elements.Int, thisvec->Nelements, k, nativeOrder);
     117      }
    66118    }
    67119  }
Note: See TracChangeset for help on using the changeset viewer.