IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 41269


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

adding string-type vectors to opihi

Location:
trunk/Ohana/src
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/libdvo/include/dvodb.h

    r40463 r41269  
    55
    66// Some values used by code moved to libdvo from opihi.
    7 enum {OPIHI_NOTYPE, OPIHI_FLT, OPIHI_INT};
     7typedef enum {OPIHI_NOTYPE, OPIHI_FLT, OPIHI_INT, OPIHI_STR} opihiVectorTypes;
     8
    89# define opihi_flt double
    9 // # define opihi_int int64_t
    1010# define opihi_int long long int
    1111# define OPIHI_INT_FMT "%lld"
     12
     13// # define opihi_int int64_t
    1214
    1315typedef enum {
  • trunk/Ohana/src/libkapa/rotfont/helvetica12.h

    r40629 r41269  
    565565{  9,   9, 10.67,   9, helvetica12_37_bits},
    566566{  7,   9,  8.00,   9, helvetica12_38_bits},
    567 {  2,   3,  2.65,   9, helvetica12_39_bits},
     567{  2,   3,  2.66,   9, helvetica12_39_bits},
    568568{  3,  12,  3.99,   9, helvetica12_40_bits},
    569569{  3,  12,  3.99,   9, helvetica12_41_bits},
     
    752752{  6,  10,  0.00,  10, helvetica12_224_bits},
    753753{  6,  10,  0.00,  10, helvetica12_225_bits},
    754 {  6,  10,  0.00,  10, helvetica12_226_bits},
     754{  6,  10, -5708879119777792.00,  10, helvetica12_226_bits},
    755755{  6,  10,  0.00,  10, helvetica12_227_bits},
    756 {  6,   9,  0.00,   9, helvetica12_228_bits},
     756{  6,   9, -5709290899767296.00,   9, helvetica12_228_bits},
    757757{  6,  10,  0.00,  10, helvetica12_229_bits},
    758 {  9,   7,  0.00,   7, helvetica12_230_bits},
    759 {  5,  10,  0.00,   7, helvetica12_231_bits},
     758{  9,   7, -365774995456.00,   7, helvetica12_230_bits},
     759{  5,  10, -439036674048.00,   7, helvetica12_231_bits},
    760760{  5,  10,  0.00,  10, helvetica12_232_bits},
    761 {  5,  10,  0.00,  10, helvetica12_233_bits},
     761{  5,  10, -5710030171013120.00,  10, helvetica12_233_bits},
    762762{  5,  10,  0.00,  10, helvetica12_234_bits},
    763 {  5,   9,  0.00,   9, helvetica12_235_bits},
     763{  5,   9, -5712675870867456.00,   9, helvetica12_235_bits},
    764764{  2,  10,  0.00,  10, helvetica12_236_bits},
    765765{  2,  10,  0.00,  10, helvetica12_237_bits},
     
    767767{  3,   9,  0.00,   9, helvetica12_239_bits},
    768768{  5,  10,  0.00,  10, helvetica12_240_bits},
    769 {  5,  10,  0.00,  10, helvetica12_241_bits},
     769{  5,  10, -0.00,  10, helvetica12_241_bits},
    770770{  5,  10,  0.00,  10, helvetica12_242_bits},
    771771{  5,  10,  0.00,  10, helvetica12_243_bits},
    772 {  5,  10,  0.00,  10, helvetica12_244_bits},
    773 {  5,  10,  0.00,  10, helvetica12_245_bits},
     772{  5,  10, -5710012991143936.00,  10, helvetica12_244_bits},
     773{  5,  10, -5710012991143936.00,  10, helvetica12_245_bits},
    774774{  5,   9,  0.00,   9, helvetica12_246_bits},
    775775{  5,   5,  0.00,   6, helvetica12_247_bits},
    776776{  7,   7,  0.00,   7, helvetica12_248_bits},
    777 {  5,  10,  0.00,  10, helvetica12_249_bits},
     777{  5,  10, -439038246912.00,  10, helvetica12_249_bits},
    778778{  5,  10,  0.00,  10, helvetica12_250_bits},
    779779{  5,  10,  0.00,  10, helvetica12_251_bits},
  • trunk/Ohana/src/opihi/cmd.astro/cgrid.c

    r40625 r41269  
    182182    }
    183183  }
     184
    184185 
    185186  /* set spacings for DEC */
  • trunk/Ohana/src/opihi/cmd.data/create.c

    r40015 r41269  
    77  Vector *vec;
    88 
     9  // create a vector of empty strings
     10  if ((N = get_argument (argc, argv, "-str"))) {
     11    remove_argument (N, &argc, argv);
     12
     13    char *stringValue = NULL;
     14    if ((N = get_argument (argc, argv, "-value"))) {
     15      remove_argument (N, &argc, argv);
     16      stringValue = strcreate (argv[N]);
     17      remove_argument (N, &argc, argv);
     18    }
     19
     20    if (argc != 3) {
     21      gprint (GP_ERR, "USAGE: create vector Nelements -value word\n");
     22      return (FALSE);
     23    }
     24
     25    if ((vec = SelectVector (argv[1], ANYVECTOR, TRUE)) == NULL) return (FALSE);
     26    int Nelements = atoi (argv[2]);
     27
     28    // a newly reset vector has NULL-valued pointers
     29    ResetVector (vec, OPIHI_STR, Nelements);
     30    for (int i = 0; i < Nelements; i++) {
     31      vec[0].elements.Str[i] = stringValue ? strcreate (stringValue) : strcreate ("");
     32    }
     33    return TRUE;
     34  }
     35
    936  INT = FALSE;
    1037  if ((N = get_argument (argc, argv, "-int"))) {
     
    1643    gprint (GP_ERR, "USAGE: create vector start end [delta] [-int]\n");
    1744    gprint (GP_ERR, " -int : resulting vector is integer type (delta must be integer)\n");
     45    gprint (GP_ERR, " -str : resulting vector is string type (only give number of elements)\n");
    1846    return (FALSE);
    1947  }
  • trunk/Ohana/src/opihi/cmd.data/list_vectors.c

    r39457 r41269  
    3232  }
    3333
    34   if (vec->type == OPIHI_FLT) {
    35     if (Variable) {
    36       set_str_variable (Variable, "FLT");
    37     } else {
    38       gprint (GP_LOG, "%s : FLT\n", argv[1]);
    39     }
    40   } else {
    41     if (Variable) {
    42       set_str_variable (Variable, "INT");
    43     } else {
    44       gprint (GP_LOG, "%s : INT\n", argv[1]);
    45     }
     34  switch (vec->type) {
     35    case OPIHI_FLT:
     36      if (Variable) {
     37        set_str_variable (Variable, "FLT");
     38      } else {
     39        gprint (GP_LOG, "%s : FLT\n", argv[1]);
     40      }
     41      break;
     42    case OPIHI_INT:
     43      if (Variable) {
     44        set_str_variable (Variable, "INT");
     45      } else {
     46        gprint (GP_LOG, "%s : INT\n", argv[1]);
     47      }
     48      break;
     49    case OPIHI_STR:
     50      if (Variable) {
     51        set_str_variable (Variable, "STR");
     52      } else {
     53        gprint (GP_LOG, "%s : STR\n", argv[1]);
     54      }
     55      break;
    4656  }
    4757  if (Variable) free (Variable);
  • trunk/Ohana/src/opihi/cmd.data/print_vectors.c

    r40545 r41269  
    5656        if (vec[i][0].type == OPIHI_FLT) {
    5757          gprint (GP_LOG, "%f ", vec[i][0].elements.Flt[j]);
    58         } else {
     58        }
     59        if (vec[i][0].type == OPIHI_INT) {
    5960          gprint (GP_LOG, OPIHI_INT_FMT" ", vec[i][0].elements.Int[j]);
    60         }
     61        }
     62        if (vec[i][0].type == OPIHI_STR) {
     63          gprint (GP_LOG, "%s ", vec[i][0].elements.Str[j]);
     64        }
    6165      }
    6266    }
  • trunk/Ohana/src/opihi/cmd.data/read_vectors.c

    r40519 r41269  
    3535
    3636// vector types
    37 enum {COLTYPE_NONE, COLTYPE_FLT, COLTYPE_INT, COLTYPE_TIME, COLTYPE_CHAR};
     37enum {COLTYPE_NONE, COLTYPE_FLT, COLTYPE_INT, COLTYPE_TIME, COLTYPE_CHAR, COLTYPE_STR};
    3838
    3939static int      Nvec     = 0;
     
    9191    gprint (GP_ERR, "     -skip N : skip N lines before reading\n");
    9292    gprint (GP_ERR, "     column names may include a type: name:type\n");
    93     gprint (GP_ERR, "       type is int, float, char, time\n");
     93    gprint (GP_ERR, "       type is int, float, char, str, time\n");
    9494    gprint (GP_ERR, "       for char, values are placed into a list $name:0 - $name:n\n");
     95    gprint (GP_ERR, "       for str, values are placed into a string-typed vector\n");
    9596    gprint (GP_ERR, "       for time, values are human-readable date/time strings YYYY/MM/DD,hh:mm:ss\n");
    9697    gprint (GP_ERR, "       the resulting vector is a float based on the TIMEFORMAT, TIMEREF values\n");
     
    152153      if (!strcasecmp(ptr, "int"))   { coltype[i] = COLTYPE_INT; }
    153154      if (!strcasecmp(ptr, "char"))  { coltype[i] = COLTYPE_CHAR; }
     155      if (!strcasecmp(ptr, "str"))   { coltype[i] = COLTYPE_STR; }
    154156      if (!strcasecmp(ptr, "time"))  { coltype[i] = COLTYPE_TIME; }
    155157      if (!coltype[i]) goto bad_colname;
     
    213215        // note that COLTYPE_TIME is a type of float
    214216        ResetVector (vec[i], OPIHI_FLT, NELEM);
     217        break;
     218      case COLTYPE_STR:
     219        ResetVector (vec[i], OPIHI_STR, NELEM);
    215220        break;
    216221      case COLTYPE_CHAR:
     
    311316              break;
    312317            }
     318          case COLTYPE_STR:
     319            {
     320              // I need to get an isolated word in 'value' with the string value of this field
     321              char *ptr = IsCSV ? ptrparse_csv (col[i], c0) : ptrparse (col[i], c0);
     322              char *value = NULL;
     323              if (IsCSV) {
     324                char *end = parse_nextword_csv (ptr);
     325                if (end) {
     326                  value = end ? strncreate (ptr, end - ptr) : strcreate (ptr);
     327                }
     328              } else {
     329                value = thisword(ptr);
     330              }
     331              vec[i][0].elements.Str[Nelem] = value; // needs to be freed later.
     332              break;
     333            }
    313334          case COLTYPE_FLT:
    314335            readStatus = IsCSV ? dparse_csv (&dvalue, col[i], c0) : dparse (&dvalue, col[i], c0);
     
    348369              ResetVector (vec[i], OPIHI_FLT, NELEM);
    349370              break;
     371            case COLTYPE_STR:
     372              ResetVector (vec[i], OPIHI_STR, NELEM);
     373              break;
    350374            case COLTYPE_CHAR:
    351375            default:
     
    369393        ResetVector (vec[i], OPIHI_FLT, Nelem);
    370394        break;
     395      case COLTYPE_STR:
     396        ResetVector (vec[i], OPIHI_STR, Nelem);
     397        break;
    371398      case COLTYPE_CHAR:
    372399        sprintf (varname, "%s:n", listname[i]);
     
    469496  }
    470497
    471   // if CharAsVectors, char fields will be saved as vectors NAME:0 -- NAME:n for n characters
    472   // else char fields will be saved as $NAME:0 - $NAME:m for m rows
     498  // by default, we now store a string-type field as a string-type vector.
     499
     500  // if CharAsList is selected (and My < 10000), char fields will be saved as $NAME:0 - $NAME:m for m rows
     501
     502  // if CharAsVectors is selected, char fields will be saved as vectors NAME:0 -- NAME:n for n characters
     503
    473504  // if (Ny > 10000), force CharAsVectors
    474505  int CharAsVectors = FALSE;
     
    476507    remove_argument (N, &argc, argv);
    477508    CharAsVectors = TRUE;
     509  }
     510  int CharAsList = FALSE;
     511  if ((N = get_argument (argc, argv, "-char-list"))) {
     512    remove_argument (N, &argc, argv);
     513    CharAsList = TRUE;
    478514  }
    479515
     
    651687    if (!FITS_TRANSPOSE) {
    652688      // read string column into a list rather than a vector
    653       if (!strcmp (type, "char") && !CharAsVectors && (Ny < 3000)) {
    654         char *fieldName = argv[i];
    655         char *Ptr = data;
    656         char varname[1024];  // used as a buffer for the names of string fields
    657         for (j = 0; j < Ny; j++) {
    658           set_list_varname (varname, fieldName, j, FALSE);
    659           char *value = strncreate (&Ptr[j*Nval], Nval);
    660           // replace instances of $ with _
    661           char *p = strchr (value, '$');
    662           while (p) {
    663             *p = '_';
    664             p = strchr (p, '$');
     689      if (!strcmp (type, "char")) {
     690        // save char-type field as a List:
     691        if (CharAsList && (Ny < 3000)) {
     692          char *fieldName = argv[i];
     693          char *Ptr = data;
     694          char varname[1024];  // used as a buffer for the names of string fields
     695          for (j = 0; j < Ny; j++) {
     696            set_list_varname (varname, fieldName, j, FALSE);
     697            char *value = strncreate (&Ptr[j*Nval], Nval);
     698            // replace instances of $ with _
     699            char *p = strchr (value, '$');
     700            while (p) {
     701              *p = '_';
     702              p = strchr (p, '$');
     703            }
     704            set_str_variable (varname, value);
     705            free (value);
    665706          }
    666           set_str_variable (varname, value);
    667           free (value);
     707          sprintf (varname, "%s:n", fieldName);
     708          set_int_variable (varname, Ny);
     709          continue;
    668710        }
    669         sprintf (varname, "%s:n", fieldName);
    670         set_int_variable (varname, Ny);
    671         continue;
     711        // save char-type field as a string-type vector:
     712        if (!CharAsVectors) {
     713          Vector *myVector = NULL;
     714          sprintf (name, "%s", argv[i]);
     715          if ((myVector = SelectVector (name, ANYVECTOR, TRUE)) == NULL) ESCAPE ("bad vector name\n");
     716          ResetVector (myVector, OPIHI_STR, Ny);
     717
     718          char *Ptr = data;
     719          for (j = 0; j < Ny; j++) {
     720            myVector[0].elements.Str[j] = strncreate (&Ptr[j*Nval], Nval);
     721            // replace instances of $ with _
     722            char *p = strchr (myVector[0].elements.Str[j], '$');
     723            while (p) { *p = '_'; p = strchr (p, '$'); }
     724          }
     725          continue;
     726        }
    672727      }
    673728
    674729      // define the multifield vector names (Nval vectors x Ny elements)
     730      // CharAsVectors is handled below automatically
    675731      ALLOCATE (vec, Vector *, Nval);
    676732      for (j = 0; j < Nval; j++) {
  • trunk/Ohana/src/opihi/cmd.data/rotate.c

    r41164 r41269  
    268268
    269269  out_buff = (float *)buf[0].matrix.buffer;
     270
    270271  for (j = 0; j < Ly; j++) {
    271272    for (i = 0; i < Lx; i++, out_buff++) {
  • trunk/Ohana/src/opihi/cmd.data/tvcolors.c

    r40626 r41269  
    3737    gprint (GP_ERR, "USAGE: tvcolors (colormap) [-nan red green blue]\n");
    3838    gprint (GP_ERR, " colormap options : greyscale, -greyscale, rainbow, heat, fullcolor, ruffcolor (also grayscale, -grayscale)\n");
    39     gprint (GP_ERR, " colormap file name of the for WORD:PATH where WORD = (file,csvf,lgcy,cetf)\n");
    40     gprint (GP_ERR, " lgcy:\n");
    41     gprint (GP_ERR, "   the colormap file must contain 4 columns: f R B G; each line defines a color transition.\n");
    42     gprint (GP_ERR, "   f: 0 - 1 defines the scale value for the transition\n");
    43     gprint (GP_ERR, "   R,B,G: 0 - 1 define the value of the color at the transition point\n");
    44     gprint (GP_ERR, " file:\n");
     39    gprint (GP_ERR, " colormap file: if colormap name is given as file:path/to/file, the colormap is read from the file\n");
    4540    gprint (GP_ERR, "   the colormap file must contain 4 columns: f R G B; each line defines a color transition.\n");
    4641    gprint (GP_ERR, "   f: 0 - 1 defines the scale value for the transition\n");
    4742    gprint (GP_ERR, "   R,G,B: 0 - 1 define the value of the color at the transition point\n");
    48     gprint (GP_ERR, " csvf:\n");
    49     gprint (GP_ERR, "   the colormap file must contain 4 columns: f,R,G,B separate by commas; each line defines a color transition.\n");
    50     gprint (GP_ERR, "   f: 0 - 1 defines the scale value for the transition\n");
    51     gprint (GP_ERR, "   R,G,B: 0 - 1 define the value of the color at the transition point\n");
    52     gprint (GP_ERR, " cetf:\n");
    53     gprint (GP_ERR, "   the colormap file must 256 rows contain 3 columns: R,G,B separate by commas; each line defines a color transition.\n");
    54     gprint (GP_ERR, "   R,G,B: 0 - 1 define the value of the color at the transition point\n");
    55     gprint (GP_ERR, "   CETF-format files can be found at : https://peterkovesi.com/projects/colourmaps\n");
    5643    return (FALSE);
    5744  }
  • trunk/Ohana/src/opihi/cmd.data/write_vectors.c

    r41164 r41269  
    154154  if (ADD_HEADER) {
    155155    for (j = 0; j < Nvec; j++) {
     156      if (j == 0) fprintf (f, "# ");
    156157      if (CSV) {
    157158        fprintf (f, "%s,", vec[j][0].name);
    158159      } else {
    159         if (j == 0) fprintf (f, "# ");
    160160        fprintf (f, "%s ", vec[j][0].name);
    161161      }
     
    166166  /* default output format */
    167167  if (format == (char *) NULL) {
     168    char padChar = CSV ? ',' : ' ';
    168169    for (i = 0; i < vec[0][0].Nelements; i++) {
    169170      for (j = 0; j < Nvec; j++) {
    170         if (vec[j][0].type == OPIHI_FLT) {
    171           if (CSV) {
    172             fprintf (f, "%.12g,", vec[j][0].elements.Flt[i]);
    173           } else {
    174             fprintf (f, "%.12g ", vec[j][0].elements.Flt[i]);
    175           }
    176         } else {
    177           if (CSV) {
    178             fprintf (f, OPIHI_INT_FMT",", vec[j][0].elements.Int[i]);
    179           } else {
    180             fprintf (f, OPIHI_INT_FMT" ", vec[j][0].elements.Int[i]);
    181           }
     171        switch (vec[j][0].type) {
     172          case OPIHI_FLT:
     173            fprintf (f, "%.12g%c", vec[j][0].elements.Flt[i], padChar);
     174            break;
     175          case OPIHI_INT:
     176            fprintf (f, OPIHI_INT_FMT"%c", vec[j][0].elements.Int[i], padChar);
     177            break;
     178          case OPIHI_STR:
     179            fprintf (f, "%s%c", vec[j][0].elements.Str[i], padChar);
     180            break;
    182181        }
    183182      }
     
    226225        fmttype[j] = 'd';
    227226        break;
     227      case 's':
     228        fmttype[j] = 's';
     229        break;
    228230      default:
    229         gprint (GP_ERR, "syntax error in format (only e,f,d,c,x allowed)\n");
     231        gprint (GP_ERR, "syntax error in format (only e,f,d,c,x,s allowed)\n");
    230232        return (FALSE);
    231233    }
     
    234236  strcat (fmtlist[Nvec-1], p0);
    235237 
     238  // check format types against vector types:
     239  for (j = 0; j < Nvec; j++) {
     240    switch (vec[j][0].type) {
     241      case OPIHI_FLT:
     242      case OPIHI_INT:
     243        if (fmttype[j] == 's') {
     244          gprint (GP_ERR, "mismatch between string format and numerical vector for %s\n", vec[j][0].name);
     245          return FALSE;
     246        }
     247        break;
     248      case OPIHI_STR:
     249        if (fmttype[j] != 's') {
     250          gprint (GP_ERR, "mismatch between numerical format and string vector for %s\n", vec[j][0].name);
     251          return FALSE;
     252        }
     253        break;
     254    }
     255  }
     256
    236257  for (i = 0; i < vec[0][0].Nelements; i++) {
    237258    for (j = 0; j < Nvec; j++) {
     
    249270          fprintf (f, fmtlist[j], (opihi_flt)(vec[j][0].elements.Int[i]));
    250271        }
     272      }
     273      if (fmttype[j] == 's') {
     274        fprintf (f, fmtlist[j], vec[j][0].elements.Str[i]);
    251275      }
    252276    }
  • trunk/Ohana/src/opihi/include/dvomath.h

    r41165 r41269  
    66# define OPIHI_NAME_SIZE 1024
    77
     8/* OPIHI_FLT, OPIHI_INT and related are defined in libdvo/include/dvodb.h */
     9
    810# define NCHARS 256
    9 // # define opihi_flt double
    10 // # define opihi_int int
    11 // NOTE: if opihi_int is changed to unsigned, all subtraction and negation operations
    12 // need to result in a float value (or 3 - 5 will yield the unexpected value 2^32 - 2)
    1311
    1412# define REQUIRE_VECTOR_FLT(VECT,RVAL) { \
     
    2624enum {ANYVECTOR, NEWVECTOR, OLDVECTOR};
    2725enum {ANYBUFFER, NEWBUFFER, OLDBUFFER};
    28 #ifdef NOT_MOVED_TO_LIBDVO
    29 enum {OPIHI_FLT, OPIHI_INT};
    30 #endif
    3126
    3227typedef struct {                        /* representation of a variable (0-D) */
     
    4035  union {
    4136    void      *Ptr;
     37    char     **Str;
    4238    opihi_flt *Flt;
    4339    opihi_int *Int;
  • 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    }
  • trunk/Ohana/src/opihi/lib.shell/VectorOps.c

    r39640 r41269  
    129129  if (mode == NEWVECTOR) goto error;
    130130  if (vectors[i]) {
     131    // XXX warning: this will be a leak if vector is type OPIHI_STR
    131132    if (vectors[i][0].elements.Ptr) free (vectors[i][0].elements.Ptr);
    132133    free (vectors[i]);
     
    150151  if (i == Nvectors) return (FALSE);
    151152
     153  // XXX warning: this will be a leak if vector is type OPIHI_STR
    152154  if (vectors[i][0].elements.Ptr) free (vectors[i][0].elements.Ptr);
    153155  free (vectors[i]);
     
    170172  if (i == Nvectors) return (FALSE);
    171173
     174  // XXX warning: this will be a leak if vector is type OPIHI_STR
    172175  if (vectors[i][0].elements.Ptr) free (vectors[i][0].elements.Ptr);
    173176  free (vectors[i]);
     
    191194
    192195int CopyVector (Vector *out, Vector *in) {
     196  // XXX warning: this will be a leak if vector is type OPIHI_STR
    193197  if (out[0].elements.Ptr) free (out[0].elements.Ptr);
    194198  out[0].Nelements = in[0].Nelements;
     
    208212
    209213int MatchVector(Vector *out, Vector *in, char type) {
     214  // XXX warning: this will be a leak if vector is type OPIHI_STR
    210215  if (out[0].elements.Ptr) free (out[0].elements.Ptr);
    211216  out[0].Nelements = in[0].Nelements;
     
    222227int ResetVector (Vector *vec, char type, int Nelements) {
    223228
     229  // if the supplied vector is a string but the output is not a string, we need to free
     230  // the unused elements
     231  if ((vec[0].type == OPIHI_STR) && (vec[0].type != type)) {
     232    for (int i = 0; i < vec[0].Nelements; i++) {
     233      FREE (vec[0].elements.Str[i]);
     234    }
     235  }
     236
    224237  // a vector can only have >= 0 elements
    225238  vec[0].Nelements = MAX(Nelements,0);
    226   if (type == OPIHI_FLT) {
    227     REALLOCATE (vec[0].elements.Flt, opihi_flt, MAX(1, Nelements));
    228     vec[0].type = OPIHI_FLT;
    229   } else {
    230     REALLOCATE (vec[0].elements.Int, opihi_int, MAX(1, Nelements));
    231     vec[0].type = OPIHI_INT;
     239
     240  switch (type) {
     241    case OPIHI_FLT:
     242      REALLOCATE (vec[0].elements.Flt, opihi_flt, MAX(1, Nelements));
     243      vec[0].type = OPIHI_FLT;
     244      break;
     245    case OPIHI_INT:
     246      REALLOCATE (vec[0].elements.Int, opihi_int, MAX(1, Nelements));
     247      vec[0].type = OPIHI_INT;
     248      break;
     249    case OPIHI_STR:
     250      REALLOCATE (vec[0].elements.Str, char *, MAX(1, Nelements));
     251      vec[0].type = OPIHI_STR;
     252      break;
    232253  }
    233254  return TRUE;
     
    251272
    252273// SetVector (vecx, OPIHI_FLT, MAX (Npts, 1));
     274// Use this for an unallocated vector (e.g., static variable)
    253275int SetVector (Vector *vec, char type, int Nelements) {
    254276
    255277  vec[0].Nelements = MAX(Nelements,0);
    256   if (type == OPIHI_FLT) {
    257     ALLOCATE (vec[0].elements.Flt, opihi_flt, MAX(1,Nelements));
    258     vec[0].type = OPIHI_FLT;
    259   } else {
    260     ALLOCATE (vec[0].elements.Int, opihi_int, MAX(1,Nelements));
    261     vec[0].type = OPIHI_INT;
     278
     279  switch (type) {
     280    case OPIHI_FLT:
     281      ALLOCATE (vec[0].elements.Flt, opihi_flt, MAX(1,Nelements));
     282      vec[0].type = OPIHI_FLT;
     283      break;
     284    case OPIHI_INT:
     285      ALLOCATE (vec[0].elements.Int, opihi_int, MAX(1,Nelements));
     286      vec[0].type = OPIHI_INT;
     287      break;
     288    case OPIHI_STR:
     289      ALLOCATE (vec[0].elements.Ptr, char *, MAX(1,Nelements));
     290      vec[0].type = OPIHI_STR;
     291      break;
    262292  }
    263293  return TRUE;
     
    272302  if (vec[0].type == type) return TRUE;
    273303
    274   if (type == OPIHI_FLT) {
    275     opihi_flt *temp;
    276     ALLOCATE (temp, opihi_flt, vec[0].Nelements);
    277     opihi_flt *vo = temp;
    278     opihi_int *vi = vec[0].elements.Int;
    279     for (i = 0; i < vec[0].Nelements; i++, vo++, vi++) {
    280       *vo = *vi;
    281     }
    282     free (vec[0].elements.Int);
    283     vec[0].elements.Flt = temp;
    284     vec[0].type = OPIHI_FLT;
    285   } else {
    286     opihi_int *temp;
    287     ALLOCATE (temp, opihi_int, vec[0].Nelements);
    288     opihi_int *vo = temp;
    289     opihi_flt *vi = vec[0].elements.Flt;
    290     for (i = 0; i < vec[0].Nelements; i++, vo++, vi++) {
    291       *vo = *vi;
    292     }
    293     free (vec[0].elements.Flt);
    294     vec[0].elements.Int = temp;
    295     vec[0].type = OPIHI_INT;
     304  switch (type) {
     305    case OPIHI_FLT: {
     306      opihi_flt *temp;
     307      ALLOCATE (temp, opihi_flt, vec[0].Nelements);
     308      opihi_flt *vo = temp;
     309      opihi_int *vi = vec[0].elements.Int;
     310      for (i = 0; i < vec[0].Nelements; i++, vo++, vi++) {
     311        *vo = *vi;
     312      }
     313      free (vec[0].elements.Int);
     314      vec[0].elements.Flt = temp;
     315      vec[0].type = OPIHI_FLT;
     316      break;
     317    }
     318    case OPIHI_INT: {
     319      opihi_int *temp;
     320      ALLOCATE (temp, opihi_int, vec[0].Nelements);
     321      opihi_int *vo = temp;
     322      opihi_flt *vi = vec[0].elements.Flt;
     323      for (i = 0; i < vec[0].Nelements; i++, vo++, vi++) {
     324        *vo = *vi;
     325      }
     326      free (vec[0].elements.Flt);
     327      vec[0].elements.Int = temp;
     328      vec[0].type = OPIHI_INT;
     329      break;
     330    }
     331    case OPIHI_STR:
     332    default:
     333      // does it make sense to cast an int/flt vector to string?
     334      break;
    296335  }
    297336  return TRUE;
     
    342381  gprint (GP_LOG, "    N       name      size\n");
    343382  for (i = 0; i < Nvectors; i++) {
    344     if (vectors[i][0].type == OPIHI_FLT) {
    345       gprint (GP_LOG, "%5d %10s %10d (FLT)\n", i, vectors[i][0].name, vectors[i][0].Nelements);
    346     } else {
    347       gprint (GP_LOG, "%5d %10s %10d (INT)\n", i, vectors[i][0].name, vectors[i][0].Nelements);
     383    switch (vectors[i][0].type) {
     384      case OPIHI_FLT:
     385        gprint (GP_LOG, "%5d %10s %10d (FLT)\n", i, vectors[i][0].name, vectors[i][0].Nelements);
     386        break;
     387      case OPIHI_INT:
     388        gprint (GP_LOG, "%5d %10s %10d (INT)\n", i, vectors[i][0].name, vectors[i][0].Nelements);
     389        break;
     390      case OPIHI_STR:
     391        gprint (GP_LOG, "%5d %10s %10d (STR)\n", i, vectors[i][0].name, vectors[i][0].Nelements);
     392        break;
    348393    }
    349394  }
Note: See TracChangeset for help on using the changeset viewer.