IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 24, 2020, 3:19:09 PM (6 years ago)
Author:
eugene
Message:

adding string-type vectors to opihi

File:
1 edited

Legend:

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

    r41176 r41269  
    22void gfits_compress_timing ();
    33 
     4static 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
    416// write a set of vectors to a FITS FTable structure (vectors names become fits column names)
    517static int WriteVectorTable (FTable *ftable, char *extname, Vector **vec, int Nvec, char *format, char nativeOrder) {
     
    4456      }
    4557      ptr = endptr; // this should now point at the letter that is the format type
    46       if ((*ptr != 'B') && (*ptr != 'I') && (*ptr != 'J') && (*ptr != 'K') && (*ptr != 'D') && (*ptr != 'E')) {
     58      if ((*ptr != 'B') && (*ptr != 'I') && (*ptr != 'J') && (*ptr != 'K') && (*ptr != 'D') && (*ptr != 'E') && (*ptr != 'A')) {
    4759        gprint (GP_ERR, "error in binary table format %s: invalid character %c\n", format, *ptr);
    4860        goto escape;
     
    5769      // tformat[2*j + 1] = 0; // a bit sleazy : use a 2xN string to store N 1-byte strings
    5870
    59       j += Nelement[Nfield]; // advance past
     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      }
    6087      if (j > Nvec) {
    6188        gprint (GP_ERR, "error in binary table format %s (too few vectors for listed field)\n", format);
     
    73100  } else {
    74101    for (j = 0; j < Nvec; j++) {
    75       // if the format is not defined, just use the native byte-widths
    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;
     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      }
    80120    }
    81121    Nfield = Nvec;
     
    90130    // this call supported multiple columns per named field
    91131    gfits_define_bintable_column (theader, tformat[j], vec[ivec][0].name, NULL, NULL, 1.0, 0.0);
    92     ivec += Nelement[j];
     132    if (vec[ivec][0].type == OPIHI_STR) {
     133      ivec ++;
     134    } else {
     135      ivec += Nelement[j];
     136    }
    93137  }
    94138
     
    109153    // the first vector provides the name for the field
    110154    char *fieldname = vec[ivec][0].name;
    111     for (int k = 0; k < Nelement[j]; k++, ivec++) {
     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:
    112158      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);
     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 ++;
     169    } 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        }
    117180      }
    118181    }
Note: See TracChangeset for help on using the changeset viewer.