Changeset 41269 for trunk/Ohana/src/opihi/lib.shell/VectorIO.c
- Timestamp:
- Feb 24, 2020, 3:19:09 PM (6 years ago)
- File:
-
- 1 edited
-
trunk/Ohana/src/opihi/lib.shell/VectorIO.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Ohana/src/opihi/lib.shell/VectorIO.c
r41176 r41269 2 2 void gfits_compress_timing (); 3 3 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 4 16 // write a set of vectors to a FITS FTable structure (vectors names become fits column names) 5 17 static int WriteVectorTable (FTable *ftable, char *extname, Vector **vec, int Nvec, char *format, char nativeOrder) { … … 44 56 } 45 57 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')) { 47 59 gprint (GP_ERR, "error in binary table format %s: invalid character %c\n", format, *ptr); 48 60 goto escape; … … 57 69 // tformat[2*j + 1] = 0; // a bit sleazy : use a 2xN string to store N 1-byte strings 58 70 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 } 60 87 if (j > Nvec) { 61 88 gprint (GP_ERR, "error in binary table format %s (too few vectors for listed field)\n", format); … … 73 100 } else { 74 101 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 } 80 120 } 81 121 Nfield = Nvec; … … 90 130 // this call supported multiple columns per named field 91 131 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 } 93 137 } 94 138 … … 109 153 // the first vector provides the name for the field 110 154 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: 112 158 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 } 117 180 } 118 181 }
Note:
See TracChangeset
for help on using the changeset viewer.
