Changeset 34279 for trunk/ppTranslate/src/ppMopsWrite.c
- Timestamp:
- Aug 2, 2012, 10:32:09 AM (14 years ago)
- File:
-
- 1 edited
-
trunk/ppTranslate/src/ppMopsWrite.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppTranslate/src/ppMopsWrite.c
r32415 r34279 9 9 #include "ppTranslateVersion.h" 10 10 11 static bool addOutputColumn(psMetadata *table, const psArray *detections, long total, char *outColName, char *inColName, bool convertTo32);11 static bool addOutputColumn(psMetadata *table, const psArray *detections, long total, int extension, char *outColName, char *inColName, bool convertTo32); 12 12 static bool addSkyfileIDColumn(psMetadata *table, const psArray *detections, long total, char *colName); 13 13 14 14 bool ppMopsWrite(const psArray *detections, const ppMopsArguments *args) 15 15 { 16 17 psFits *fits = psFitsOpen(args->output, "w"); // FITS file 18 if (!fits) { 19 psError(PS_ERR_IO, false, "Unable to open output file."); 20 return false; 21 } 22 23 psMetadata *header = psMetadataAlloc(); // Header to write 24 psString source = ppTranslateSource(), version = ppTranslateVersion(); 25 psMetadataAddStr(header, PS_LIST_TAIL, "SWSOURCE", 0, "Software source", source); 26 psMetadataAddStr(header, PS_LIST_TAIL, "SWVERSN", 0, "Software version", version); 27 ppTranslateVersionHeader(header); 28 psFree(source); 29 psFree(version); 30 31 psMetadataAddStr(header, PS_LIST_TAIL, "EXP_NAME", 0, "Exposure name", args->exp_name); 32 psMetadataAddS64(header, PS_LIST_TAIL, "EXP_ID", 0, "Exposure identifier", args->exp_id); 33 psMetadataAddS64(header, PS_LIST_TAIL, "CHIP_ID", 0, "Chip stage identifier", args->chip_id); 34 psMetadataAddS64(header, PS_LIST_TAIL, "CAM_ID", 0, "Cam stage identifier", args->cam_id); 35 psMetadataAddS64(header, PS_LIST_TAIL, "FAKE_ID", 0, "Fake stage identifier", args->fake_id); 36 psMetadataAddS64(header, PS_LIST_TAIL, "WARP_ID", 0, "Warp stage identifier", args->warp_id); 37 psMetadataAddS64(header, PS_LIST_TAIL, "DIFF_ID", 0, "Diff stage identifier", args->diff_id); 38 psMetadataAddBool(header, PS_LIST_TAIL, "DIFF_POS", 0, "Positive subtraction?", args->positive); 39 40 // Get these header words from the first input non null input 41 ppMopsDetections *det = NULL; 42 for (int d = 0; d < detections->n && det == NULL; d++) { 43 det = detections->data[d]; 44 } 45 if (det != NULL) { 46 psMetadataAddF64(header, PS_LIST_TAIL, "MJD-OBS", 0, "MJD of exposure midpoint", det->mjd); 47 psMetadataAddStr(header, PS_LIST_TAIL, "RA", 0, "Right Ascension of boresight", det->raBoresight); 48 psMetadataAddStr(header, PS_LIST_TAIL, "DEC", 0, "Declination of boresight", det->decBoresight); 49 psMetadataAddF64(header, PS_LIST_TAIL, "TEL_ALT", 0, "Telescope altitude", det->alt); 50 psMetadataAddF64(header, PS_LIST_TAIL, "TEL_AZ", 0, "Telescope azimuth", det->az); 51 psMetadataAddF64(header, PS_LIST_TAIL, "EXPTIME", 0, "Exposure time (sec)", det->exptime); 52 psMetadataAddF64(header, PS_LIST_TAIL, "ROTANGLE", 0, "Rotator position angle", det->posangle); 53 psMetadataAddStr(header, PS_LIST_TAIL, "FILTER", 0, "Filter name", det->filter); 54 psMetadataAddF32(header, PS_LIST_TAIL, "AIRMASS", 0, "Airmass of exposure", det->airmass); 55 psMetadataAddF32(header, PS_LIST_TAIL, "SEEING", 0, "Mean seeing", det->seeing); 56 } else { 57 psWarning("no inputs with surviving detections. output header will be incomplete"); 58 } 59 psMetadataAddStr(header, PS_LIST_TAIL, "OBSCODE", 0, "IAU Observatory code", OBSERVATORY_CODE); 60 psMetadataAddF32(header, PS_LIST_TAIL, "MAGZP", 0, "Magnitude zero point", args->zp); 61 psMetadataAddF32(header, PS_LIST_TAIL, "MAGZPERR", 0, "Error in magnitude zero point", args->zpErr); 62 psMetadataAddF32(header, PS_LIST_TAIL, "ASTRORMS", 0, "RMS of astrometric fit", args->rmsAstrom); 63 64 //field in header that tells about the CMF version 65 char cmfVersion[8]; 66 sprintf(cmfVersion, PS1_DV_FORMAT, args->version); 67 psMetadataAddStr(header, PS_LIST_TAIL, "CMFVERSION", 0, "CMF version", cmfVersion); 68 69 // Find the total number of detections 70 71 long total = 0; 16 psFits *fits = psFitsOpen(args->output, "w"); // FITS file 17 if (!fits) { 18 psError(PS_ERR_IO, false, "Unable to open output file."); 19 return false; 20 } 21 22 psMetadata *header = psMetadataAlloc(); // Header to write 23 psString source = ppTranslateSource(), version = ppTranslateVersion(); 24 psMetadataAddStr(header, PS_LIST_TAIL, "SWSOURCE", 0, "Software source", source); 25 psMetadataAddStr(header, PS_LIST_TAIL, "SWVERSN", 0, "Software version", version); 26 ppTranslateVersionHeader(header); 27 psFree(source); 28 psFree(version); 29 30 psMetadataAddStr(header, PS_LIST_TAIL, "EXP_NAME", 0, "Exposure name", args->exp_name); 31 psMetadataAddS64(header, PS_LIST_TAIL, "EXP_ID", 0, "Exposure identifier", args->exp_id); 32 psMetadataAddS64(header, PS_LIST_TAIL, "CHIP_ID", 0, "Chip stage identifier", args->chip_id); 33 psMetadataAddS64(header, PS_LIST_TAIL, "CAM_ID", 0, "Cam stage identifier", args->cam_id); 34 psMetadataAddS64(header, PS_LIST_TAIL, "FAKE_ID", 0, "Fake stage identifier", args->fake_id); 35 psMetadataAddS64(header, PS_LIST_TAIL, "WARP_ID", 0, "Warp stage identifier", args->warp_id); 36 psMetadataAddS64(header, PS_LIST_TAIL, "DIFF_ID", 0, "Diff stage identifier", args->diff_id); 37 psMetadataAddBool(header, PS_LIST_TAIL, "DIFF_POS", 0, "Positive subtraction?", args->positive); 38 39 // Get these header words from the first input non null input 40 ppMopsDetections *det = NULL; 41 for (int d = 0; d < detections->n && det == NULL; d++) { 42 det = detections->data[d]; 43 } 44 if (det != NULL) { 45 psMetadataAddF64(header, PS_LIST_TAIL, "MJD-OBS", 0, "MJD of exposure midpoint", det->mjd); 46 psMetadataAddStr(header, PS_LIST_TAIL, "RA", 0, "Right Ascension of boresight", det->raBoresight); 47 psMetadataAddStr(header, PS_LIST_TAIL, "DEC", 0, "Declination of boresight", det->decBoresight); 48 psMetadataAddF64(header, PS_LIST_TAIL, "TEL_ALT", 0, "Telescope altitude", det->alt); 49 psMetadataAddF64(header, PS_LIST_TAIL, "TEL_AZ", 0, "Telescope azimuth", det->az); 50 psMetadataAddF64(header, PS_LIST_TAIL, "EXPTIME", 0, "Exposure time (sec)", det->exptime); 51 psMetadataAddF64(header, PS_LIST_TAIL, "ROTANGLE", 0, "Rotator position angle", det->posangle); 52 psMetadataAddStr(header, PS_LIST_TAIL, "FILTER", 0, "Filter name", det->filter); 53 psMetadataAddF32(header, PS_LIST_TAIL, "AIRMASS", 0, "Airmass of exposure", det->airmass); 54 psMetadataAddF32(header, PS_LIST_TAIL, "SEEING", 0, "Mean seeing", det->seeing); 55 } else { 56 psWarning("no inputs with surviving detections. output header will be incomplete"); 57 } 58 psMetadataAddStr(header, PS_LIST_TAIL, "OBSCODE", 0, "IAU Observatory code", OBSERVATORY_CODE); 59 psMetadataAddF32(header, PS_LIST_TAIL, "MAGZP", 0, "Magnitude zero point", args->zp); 60 psMetadataAddF32(header, PS_LIST_TAIL, "MAGZPERR", 0, "Error in magnitude zero point", args->zpErr); 61 psMetadataAddF32(header, PS_LIST_TAIL, "ASTRORMS", 0, "RMS of astrometric fit", args->rmsAstrom); 62 63 //field in header that tells about the CMF version 64 char cmfVersion[8]; 65 sprintf(cmfVersion, PS1_DV_FORMAT, args->version); 66 psMetadataAddStr(header, PS_LIST_TAIL, "CMFVERSION", 0, "CMF version", cmfVersion); 67 68 // Find the total number of detections 69 70 long total = 0; 71 for (long i=0; i<detections->n; i++) { 72 ppMopsDetections *det = detections->data[i]; 73 if (!det) { 74 continue; 75 } 76 total += det->num; 77 } 78 79 psTrace("ppMops.write", 1, "Writing %ld rows to %s", total, args->output); 80 81 if (total == 0) { 82 // Write dummy table 83 psMetadata *row = psMetadataAlloc(); // Output row 84 psMetadataAddF64(row, PS_LIST_TAIL, "RA", 0, "Right ascension (degrees)", NAN); 85 psMetadataAddF64(row, PS_LIST_TAIL, "RA_ERR", 0, "Right ascension error (degrees)", NAN); 86 psMetadataAddF64(row, PS_LIST_TAIL, "DEC", 0, "Declination (degrees)", NAN); 87 psMetadataAddF64(row, PS_LIST_TAIL, "DEC_ERR", 0, "Declination error (degrees)", NAN); 88 psMetadataAddF32(row, PS_LIST_TAIL, "MAG", 0, "Magnitude", NAN); 89 psMetadataAddF32(row, PS_LIST_TAIL, "MAG_ERR", 0, "Magnitude error", NAN); 90 psMetadataAddF32(row, PS_LIST_TAIL, "PSF_CHI2", 0, "chi^2 of PSF fit", NAN); 91 psMetadataAddS32(row, PS_LIST_TAIL, "PSF_DOF", 0, "Degrees of freedom of PSF fit", 0); 92 psMetadataAddF32(row, PS_LIST_TAIL, "CR_SIGNIFICANCE", 0, "Significance of CR", NAN); 93 psMetadataAddF32(row, PS_LIST_TAIL, "EXT_SIGNIFICANCE", 0, "Significance of extendedness", NAN); 94 psMetadataAddF32(row, PS_LIST_TAIL, "PSF_MAJOR", 0, "PSF major axis (pixels)", NAN); 95 psMetadataAddF32(row, PS_LIST_TAIL, "PSF_MINOR", 0, "PSF minor axis (pixels)", NAN); 96 psMetadataAddF32(row, PS_LIST_TAIL, "PSF_THETA", 0, "PSF position angle (deg on chip)", NAN); 97 psMetadataAddF32(row, PS_LIST_TAIL, "PSF_QUALITY", 0, "PSF quality factor", NAN); 98 psMetadataAddS32(row, PS_LIST_TAIL, "PSF_NPIX", 0, "Number of pixels in PSF", 0); 99 psMetadataAddF32(row, PS_LIST_TAIL, "MOMENTS_XX", 0, "xx moment", NAN); 100 psMetadataAddF32(row, PS_LIST_TAIL, "MOMENTS_XY", 0, "xy moment", NAN); 101 psMetadataAddF32(row, PS_LIST_TAIL, "MOMENTS_YY", 0, "yy moment", NAN); 102 psMetadataAddU32(row, PS_LIST_TAIL, "FLAGS", 0, "Detection bit flags", 0); 103 psMetadataAddS64(row, PS_LIST_TAIL, "DIFF_SKYFILE_ID", 0, "Identifier for diff skyfile", 0); 104 105 psMetadataAddS32(row, PS_LIST_TAIL, "N_POS", 0, "Number of positive pixels", 0); 106 psMetadataAddF32(row, PS_LIST_TAIL, "F_POS", 0, "Fraction of positive pixels", NAN); 107 psMetadataAddF32(row, PS_LIST_TAIL, "RATIO_BAD", 0, "Ratio of positive pixels to negative", NAN); 108 psMetadataAddF32(row, PS_LIST_TAIL, "RATIO_MASK", 0, "Ratio of positive pixels to masked", NAN); 109 psMetadataAddF32(row, PS_LIST_TAIL, "RATIO_ALL", 0, "Ratio of positive pixels to all", NAN); 110 111 if (args->version == 2) { 112 // Write data of version 2 (see ICD) 113 psMetadataAdd (row, PS_LIST_TAIL, "IPP_IDET", PS_DATA_U32, "IPP detection identifier index", 114 NAN); 115 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_FLUX", PS_DATA_F32, "PSF fit instrumental magnitude", 116 NAN); 117 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_FLUX_SIG",PS_DATA_F32, "Sigma of PSF instrumental magnitude", 118 NAN); 119 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG", PS_DATA_F32, "magnitude in standard aperture", 120 NAN); 121 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RAW", PS_DATA_F32, "magnitude in real aperture", 122 NAN); 123 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", 124 NAN); 125 psMetadataAdd (row, PS_LIST_TAIL, "AP_FLUX", PS_DATA_F32, "instrumental flux in standard aperture", 126 NAN); 127 psMetadataAdd (row, PS_LIST_TAIL, "AP_FLUX_SIG", PS_DATA_F32, "aperture flux error", 128 NAN); 129 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", 130 NAN); 131 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", 132 NAN); 133 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG_SIG", PS_DATA_F32, "measured scatter of zero point calibration", 134 NAN); 135 psMetadataAdd (row, PS_LIST_TAIL, "SKY", PS_DATA_F32, "Sky level", 136 NAN); 137 psMetadataAdd (row, PS_LIST_TAIL, "SKY_SIGMA", PS_DATA_F32, "Sigma of sky level", 138 NAN); 139 psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF_PERFECT", PS_DATA_F32, "PSF coverage/quality factor (poor)", 140 NAN); 141 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_R1", PS_DATA_F32, "first radial moment", 142 NAN); 143 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_RH", PS_DATA_F32, "half radial moment", 144 NAN); 145 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX", PS_DATA_F32, "Kron Flux (in 2.5 R1)", 146 NAN); 147 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_ERR", PS_DATA_F32, "Kron Flux Error", 148 NAN); 149 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_INNER", PS_DATA_F32, "Kron Flux (in 1.0 R1)", 150 NAN); 151 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_OUTER", PS_DATA_F32, "Kron Flux (in 4.0 R1)", 152 NAN); 153 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_R_P", PS_DATA_F32, "distance to positive match source", 154 NAN); 155 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_SN_P", PS_DATA_F32, "signal-to-noise of pos match src", 156 NAN); 157 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_R_M", PS_DATA_F32, "distance to negative match source", 158 NAN); 159 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_SN_M", PS_DATA_F32, "signal-to-noise of neg match src", 160 NAN); 161 psMetadataAdd (row, PS_LIST_TAIL, "FLAGS2", PS_DATA_U32, "psphot analysis flags (group 2)", 162 0); 163 psMetadataAdd (row, PS_LIST_TAIL, "N_FRAMES", PS_DATA_U16, "Number of frames overlapping source center", 164 0); 165 psMetadataAdd (row, PS_LIST_TAIL, "PADDING", PS_DATA_S16, "padding", 166 0); 167 if (args->version == 3) { 168 // TODO: Write data of version 3 (see ICD) 169 } 170 } 171 172 if (!psFitsWriteTableEmpty(fits, header, row, OUT_EXTNAME)) { 173 psErrorStackPrint(stderr, "Unable to write empty table."); 174 psFree(header); 175 psFree(row); 176 return false; 177 } 178 psFree(row); 179 } else { 180 181 #define addColumn(_outName, _inName, _convertTo32) \ 182 if (!addOutputColumn(table, detections, total, 0, _outName, _inName, _convertTo32)) { \ 183 psError(PS_ERR_UNKNOWN, false, "Failed to add column %s", _outName); \ 184 return false; \ 185 } 186 187 // Allocate the output table 188 psMetadata *table = psMetadataAlloc(); 189 addColumn("RA", "RA_PSF", 0); 190 addColumn("RA_ERR", NULL, 0); // calculated from various parameters including X_PSF_SIG Y_PSF_SIG and POSANG 191 addColumn("DEC", "DEC_PSF", 0); 192 addColumn("DEC_ERR", NULL, 0); // calculated from various parameters including X_PSF_SIG Y_PSF_SIG and POSANG 193 addColumn("MAG", "PSF_INST_MAG", 0); 194 addColumn("MAG_ERR", "PSF_INST_MAG_SIG", 0); 195 addColumn("PSF_CHI2", "PSF_CHISQ", 0); 196 addColumn("PSF_DOF", "PSF_NDOF", 1); 197 addColumn("CR_SIGNIFICANCE", "CR_NSIGMA", 0); 198 addColumn("EXT_SIGNIFICANCE", "EXT_NSIGMA", 0); 199 addColumn("PSF_MAJOR", NULL, 0); 200 addColumn("PSF_MINOR", NULL, 0); 201 addColumn("PSF_THETA", NULL, 0); 202 addColumn("PSF_QUALITY", "PSF_QF", 0); 203 addColumn("PSF_NPIX", NULL, 1); 204 addColumn("MOMENTS_XX", NULL, 0); 205 addColumn("MOMENTS_XY", NULL, 0); 206 addColumn("MOMENTS_YY", NULL, 0); 207 addColumn("N_POS", "DIFF_NPOS", 1); 208 addColumn("F_POS", "DIFF_FRATIO", 0); 209 addColumn("RATIO_BAD", "DIFF_NRATIO_BAD", 0); 210 addColumn("RATIO_MASK", "DIFF_NRATIO_MASK", 0); 211 addColumn("RATIO_ALL", "DIFF_NRATIO_ALL", 0); 212 addColumn("FLAGS", "FLAGS", 1); 213 addSkyfileIDColumn(table, detections, total, "DIFF_SKYFILE_ID"); 214 if (args->version >= 2) { 215 addColumn("IPP_IDET", NULL, 1); 216 addColumn("PSF_INST_FLUX", NULL, 0); 217 addColumn("PSF_INST_FLUX_SIG", NULL, 0); 218 addColumn("AP_MAG", NULL, 0); 219 addColumn("AP_MAG_RAW", NULL, 0); 220 addColumn("AP_MAG_RADIUS", NULL, 0); 221 addColumn("AP_FLUX", NULL, 0); 222 addColumn("AP_FLUX_SIG", NULL, 0); 223 addColumn("PEAK_FLUX_AS_MAG", NULL, 0); 224 addColumn("CAL_PSF_MAG", NULL, 0); 225 addColumn("CAL_PSF_MAG_SIG", NULL, 0); 226 addColumn("SKY", NULL, 0); 227 addColumn("SKY_SIGMA", NULL, 0); 228 addColumn("PSF_QF_PERFECT", NULL, 0); 229 addColumn("MOMENTS_R1", NULL, 0); 230 addColumn("MOMENTS_RH", NULL, 0); 231 addColumn("KRON_FLUX", NULL, 0); 232 addColumn("KRON_FLUX_ERR", NULL, 0); 233 addColumn("KRON_FLUX_INNER", NULL, 0); 234 addColumn("KRON_FLUX_OUTER", NULL, 0); 235 addColumn("DIFF_R_P", NULL, 0); 236 addColumn("DIFF_SN_P", NULL, 0); 237 addColumn("DIFF_R_M", NULL, 0); 238 addColumn("DIFF_SN_M", NULL, 0); 239 addColumn("FLAGS2", NULL, 1); 240 addColumn("IPP_IDET", NULL, 0); 241 addColumn("N_FRAMES", NULL, 0); 242 addColumn("PADDING", NULL, 0); 243 if (det->fittedTrails != NULL) { 244 #define addFittedTrailColumn(_outName, _inName, _convertTo32) \ 245 if (!addOutputColumn(table, detections, total, 1, _outName, _inName, _convertTo32)) { \ 246 psTrace("ppMops.write", 1, "Failed to add column %s -> Replaced with NAN", _outName); \ 247 } 248 addFittedTrailColumn("X_EXT", NULL, 0); 249 addFittedTrailColumn("Y_EXT", NULL, 0); 250 addFittedTrailColumn("X_EXT_SIG", NULL, 0); 251 addFittedTrailColumn("Y_EXT_SIG", NULL, 0); 252 addFittedTrailColumn("EXT_INST_MAG", NULL, 0); 253 addFittedTrailColumn("EXT_INST_MAG_SIG", NULL, 0); 254 addFittedTrailColumn("NPARAMS", NULL, 0); 255 addFittedTrailColumn("EXT_WIDTH_MAJ", NULL, 0); 256 addFittedTrailColumn("EXT_WIDTH_MIN", NULL, 0); 257 addFittedTrailColumn("EXT_THETA", NULL, 0); 258 addFittedTrailColumn("EXT_WIDTH_MAJ_ERR", NULL, 0); 259 addFittedTrailColumn("EXT_WIDTH_MIN_ERR", NULL, 0); 260 addFittedTrailColumn("EXT_THETA_ERR", NULL, 0); 261 } 262 } 263 if (!psFitsWriteTableAllColumns(fits, header, table, OUT_EXTNAME)) { 264 psError(psErrorCodeLast(), false, "Unable to write table"); 265 return false; 266 } 267 psFree(table); 268 } 269 270 psFree(header); 271 psFitsClose(fits); 272 273 psTrace("ppMops.write", 1, "Done writing %ld rows to %s", det->num, args->output); 274 275 return true; 276 } 277 278 // extension parameter values: 279 // 0: SkyChip.psf 280 // 1: SkyChip.xfit 281 // Any other value is ignored 282 static bool addOutputColumn(psMetadata *table, const psArray *detections, long outputSize, int extension, char *outColumnName, char *inColumnName, bool convertTo32) 283 { 284 if (inColumnName == NULL) { 285 inColumnName = outColumnName; 286 } 287 psVector *out = NULL; 288 if (convertTo32) { 289 // psFitsReadTableAllColumns reads columns of cfitsio type LONG and ULONG into a 64 bit integers 290 // We want to write 32 bits to the output. 291 int next = 0; 72 292 for (long i=0; i<detections->n; i++) { 73 ppMopsDetections *det = detections->data[i]; 74 if (!det) { 75 continue; 293 ppMopsDetections *det = detections->data[i]; 294 if (!det || det->num == 0) { 295 // no detections survived for this input 296 continue; 297 } 298 psVector *in = NULL; 299 if (extension == 0) { 300 in = psMetadataLookupVector(NULL, det->table, inColumnName); 301 } else if (extension == 1) { 302 in = psMetadataLookupVector(NULL, det->fittedTrails, inColumnName); 303 } else { 304 //Error? 305 } 306 if (!in) { 307 psError(PS_ERR_PROGRAMMING, true, "failed to find input column: %s (convertTo32 is true)", inColumnName); 308 return false; 309 } 310 if (in->type.type != PS_TYPE_S64 && in->type.type != PS_TYPE_U64) { 311 psError(PS_ERR_PROGRAMMING, true, "input column to convert is not S64 or U64: %s %d", 312 inColumnName, in->type.type); 313 return false; 314 } 315 if (out == NULL) { 316 // First time through set up the output vector and the copy parameters 317 if (in->type.type == PS_TYPE_S64) { 318 out = psVectorAlloc(outputSize, PS_TYPE_S32); 319 } else { 320 out = psVectorAlloc(outputSize, PS_TYPE_U32); 76 321 } 77 total += det->num; 78 } 79 80 psTrace("ppMops.write", 1, "Writing %ld rows to %s", total, args->output); 81 82 if (total == 0) { 83 // Write dummy table 84 psMetadata *row = psMetadataAlloc(); // Output row 85 psMetadataAddF64(row, PS_LIST_TAIL, "RA", 0, "Right ascension (degrees)", NAN); 86 psMetadataAddF64(row, PS_LIST_TAIL, "RA_ERR", 0, "Right ascension error (degrees)", NAN); 87 psMetadataAddF64(row, PS_LIST_TAIL, "DEC", 0, "Declination (degrees)", NAN); 88 psMetadataAddF64(row, PS_LIST_TAIL, "DEC_ERR", 0, "Declination error (degrees)", NAN); 89 psMetadataAddF32(row, PS_LIST_TAIL, "MAG", 0, "Magnitude", NAN); 90 psMetadataAddF32(row, PS_LIST_TAIL, "MAG_ERR", 0, "Magnitude error", NAN); 91 psMetadataAddF32(row, PS_LIST_TAIL, "PSF_CHI2", 0, "chi^2 of PSF fit", NAN); 92 psMetadataAddS32(row, PS_LIST_TAIL, "PSF_DOF", 0, "Degrees of freedom of PSF fit", 0); 93 psMetadataAddF32(row, PS_LIST_TAIL, "CR_SIGNIFICANCE", 0, "Significance of CR", NAN); 94 psMetadataAddF32(row, PS_LIST_TAIL, "EXT_SIGNIFICANCE", 0, "Significance of extendedness", NAN); 95 psMetadataAddF32(row, PS_LIST_TAIL, "PSF_MAJOR", 0, "PSF major axis (pixels)", NAN); 96 psMetadataAddF32(row, PS_LIST_TAIL, "PSF_MINOR", 0, "PSF minor axis (pixels)", NAN); 97 psMetadataAddF32(row, PS_LIST_TAIL, "PSF_THETA", 0, "PSF position angle (deg on chip)", NAN); 98 psMetadataAddF32(row, PS_LIST_TAIL, "PSF_QUALITY", 0, "PSF quality factor", NAN); 99 psMetadataAddS32(row, PS_LIST_TAIL, "PSF_NPIX", 0, "Number of pixels in PSF", 0); 100 psMetadataAddF32(row, PS_LIST_TAIL, "MOMENTS_XX", 0, "xx moment", NAN); 101 psMetadataAddF32(row, PS_LIST_TAIL, "MOMENTS_XY", 0, "xy moment", NAN); 102 psMetadataAddF32(row, PS_LIST_TAIL, "MOMENTS_YY", 0, "yy moment", NAN); 103 psMetadataAddU32(row, PS_LIST_TAIL, "FLAGS", 0, "Detection bit flags", 0); 104 psMetadataAddS64(row, PS_LIST_TAIL, "DIFF_SKYFILE_ID", 0, "Identifier for diff skyfile", 0); 105 106 psMetadataAddS32(row, PS_LIST_TAIL, "N_POS", 0, "Number of positive pixels", 0); 107 psMetadataAddF32(row, PS_LIST_TAIL, "F_POS", 0, "Fraction of positive pixels", NAN); 108 psMetadataAddF32(row, PS_LIST_TAIL, "RATIO_BAD", 0, "Ratio of positive pixels to negative", NAN); 109 psMetadataAddF32(row, PS_LIST_TAIL, "RATIO_MASK", 0, "Ratio of positive pixels to masked", NAN); 110 psMetadataAddF32(row, PS_LIST_TAIL, "RATIO_ALL", 0, "Ratio of positive pixels to all", NAN); 111 112 if (args->version == 2) { 113 // Write data of version 2 (see ICD) 114 psMetadataAdd (row, PS_LIST_TAIL, "IPP_IDET", PS_DATA_U32, "IPP detection identifier index", 115 NAN); 116 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_FLUX", PS_DATA_F32, "PSF fit instrumental magnitude", 117 NAN); 118 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_FLUX_SIG",PS_DATA_F32, "Sigma of PSF instrumental magnitude", 119 NAN); 120 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG", PS_DATA_F32, "magnitude in standard aperture", 121 NAN); 122 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RAW", PS_DATA_F32, "magnitude in real aperture", 123 NAN); 124 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", 125 NAN); 126 psMetadataAdd (row, PS_LIST_TAIL, "AP_FLUX", PS_DATA_F32, "instrumental flux in standard aperture", 127 NAN); 128 psMetadataAdd (row, PS_LIST_TAIL, "AP_FLUX_SIG", PS_DATA_F32, "aperture flux error", 129 NAN); 130 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", 131 NAN); 132 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", 133 NAN); 134 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG_SIG", PS_DATA_F32, "measured scatter of zero point calibration", 135 NAN); 136 psMetadataAdd (row, PS_LIST_TAIL, "SKY", PS_DATA_F32, "Sky level", 137 NAN); 138 psMetadataAdd (row, PS_LIST_TAIL, "SKY_SIGMA", PS_DATA_F32, "Sigma of sky level", 139 NAN); 140 psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF_PERFECT", PS_DATA_F32, "PSF coverage/quality factor (poor)", 141 NAN); 142 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_R1", PS_DATA_F32, "first radial moment", 143 NAN); 144 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_RH", PS_DATA_F32, "half radial moment", 145 NAN); 146 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX", PS_DATA_F32, "Kron Flux (in 2.5 R1)", 147 NAN); 148 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_ERR", PS_DATA_F32, "Kron Flux Error", 149 NAN); 150 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_INNER", PS_DATA_F32, "Kron Flux (in 1.0 R1)", 151 NAN); 152 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_OUTER", PS_DATA_F32, "Kron Flux (in 4.0 R1)", 153 NAN); 154 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_R_P", PS_DATA_F32, "distance to positive match source", 155 NAN); 156 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_SN_P", PS_DATA_F32, "signal-to-noise of pos match src", 157 NAN); 158 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_R_M", PS_DATA_F32, "distance to negative match source", 159 NAN); 160 psMetadataAdd (row, PS_LIST_TAIL, "DIFF_SN_M", PS_DATA_F32, "signal-to-noise of neg match src", 161 NAN); 162 psMetadataAdd (row, PS_LIST_TAIL, "FLAGS2", PS_DATA_U32, "psphot analysis flags (group 2)", 163 0); 164 psMetadataAdd (row, PS_LIST_TAIL, "N_FRAMES", PS_DATA_U16, "Number of frames overlapping source center", 165 0); 166 psMetadataAdd (row, PS_LIST_TAIL, "PADDING", PS_DATA_S16, "padding", 167 0); 322 } 323 for (long d=0; d < det->num; d++) { 324 if (in->type.type == PS_TYPE_S64) { 325 out->data.S32[next++] = in->data.S64[d]; 326 } else { 327 out->data.U32[next++] = in->data.U64[d]; 168 328 } 169 170 if (!psFitsWriteTableEmpty(fits, header, row, OUT_EXTNAME)) { 171 psErrorStackPrint(stderr, "Unable to write empty table."); 172 psFree(header); 173 psFree(row); 174 return false; 175 } 176 psFree(row); 177 } else { 178 179 #define addColumn(_outName, _inName, _convertTo32) \ 180 if (!addOutputColumn(table, detections, total, _outName, _inName, _convertTo32)) { \ 181 psError(PS_ERR_UNKNOWN, false, "Failed to add column %s", _outName); \ 182 return false; \ 183 } 184 185 // Allocate the output table 186 psMetadata *table = psMetadataAlloc(); 187 addColumn("RA", "RA_PSF", 0); 188 addColumn("RA_ERR", NULL, 0); // calculated from various parameters including X_PSF_SIG Y_PSF_SIG and POSANG 189 addColumn("DEC", "DEC_PSF", 0); 190 addColumn("DEC_ERR", NULL, 0); // calculated from various parameters including X_PSF_SIG Y_PSF_SIG and POSANG 191 addColumn("MAG", "PSF_INST_MAG", 0); 192 addColumn("MAG_ERR", "PSF_INST_MAG_SIG", 0); 193 addColumn("PSF_CHI2", "PSF_CHISQ", 0); 194 addColumn("PSF_DOF", "PSF_NDOF", 1); 195 addColumn("CR_SIGNIFICANCE", "CR_NSIGMA", 0); 196 addColumn("EXT_SIGNIFICANCE", "EXT_NSIGMA", 0); 197 addColumn("PSF_MAJOR", NULL, 0); 198 addColumn("PSF_MINOR", NULL, 0); 199 addColumn("PSF_THETA", NULL, 0); 200 addColumn("PSF_QUALITY", "PSF_QF", 0); 201 addColumn("PSF_NPIX", NULL, 1); 202 addColumn("MOMENTS_XX", NULL, 0); 203 addColumn("MOMENTS_XY", NULL, 0); 204 addColumn("MOMENTS_YY", NULL, 0); 205 addColumn("N_POS", "DIFF_NPOS", 1); 206 addColumn("F_POS", "DIFF_FRATIO", 0); 207 addColumn("RATIO_BAD", "DIFF_NRATIO_BAD", 0); 208 addColumn("RATIO_MASK", "DIFF_NRATIO_MASK", 0); 209 addColumn("RATIO_ALL", "DIFF_NRATIO_ALL", 0); 210 addColumn("FLAGS", "FLAGS", 1); 211 addSkyfileIDColumn(table, detections, total, "DIFF_SKYFILE_ID"); 212 if (args->version == 2) { 213 addColumn("IPP_IDET", NULL, 1); 214 addColumn("PSF_INST_FLUX", NULL, 0); 215 addColumn("PSF_INST_FLUX_SIG", NULL, 0); 216 addColumn("AP_MAG", NULL, 0); 217 addColumn("AP_MAG_RAW", NULL, 0); 218 addColumn("AP_MAG_RADIUS", NULL, 0); 219 addColumn("AP_FLUX", NULL, 0); 220 addColumn("AP_FLUX_SIG", NULL, 0); 221 addColumn("PEAK_FLUX_AS_MAG", NULL, 0); 222 addColumn("CAL_PSF_MAG", NULL, 0); 223 addColumn("CAL_PSF_MAG_SIG", NULL, 0); 224 addColumn("SKY", NULL, 0); 225 addColumn("SKY_SIGMA", NULL, 0); 226 addColumn("PSF_QF_PERFECT", NULL, 0); 227 addColumn("MOMENTS_R1", NULL, 0); 228 addColumn("MOMENTS_RH", NULL, 0); 229 addColumn("KRON_FLUX", NULL, 0); 230 addColumn("KRON_FLUX_ERR", NULL, 0); 231 addColumn("KRON_FLUX_INNER", NULL, 0); 232 addColumn("KRON_FLUX_OUTER", NULL, 0); 233 addColumn("DIFF_R_P", NULL, 0); 234 addColumn("DIFF_SN_P", NULL, 0); 235 addColumn("DIFF_R_M", NULL, 0); 236 addColumn("DIFF_SN_M", NULL, 0); 237 addColumn("FLAGS2", NULL, 1); 238 addColumn("IPP_IDET", NULL, 0); 239 addColumn("N_FRAMES", NULL, 0); 240 addColumn("PADDING", NULL, 0); 241 } 242 if (!psFitsWriteTableAllColumns(fits, header, table, OUT_EXTNAME)) { 243 psError(psErrorCodeLast(), false, "Unable to write table"); 244 return false; 245 } 246 psFree(table); 247 } 248 249 psFree(header); 250 psFitsClose(fits); 251 252 psTrace("ppMops.write", 1, "Done writing %ld rows to %s", det->num, args->output); 253 254 return true; 329 } 330 } 331 } else { 332 void *next = NULL; 333 int elementSize = 0; // size of elements in vector... We are making assumptions here about the organization of primitives in memory so we can use memcopy 334 for (long i=0; i<detections->n; i++) { 335 ppMopsDetections *det = detections->data[i]; 336 if (!det || det->num == 0) { 337 // no detections survived for this input 338 continue; 339 } 340 psVector *in = NULL; 341 if (extension == 0) { 342 psTrace("ppMops.write", 1, "Using det->table for %s", inColumnName); 343 in = psMetadataLookupVector(NULL, det->table, inColumnName); 344 } else if (extension == 1) { 345 psTrace("ppMops.write", 1, "Using det->fittedTrails for %s", inColumnName); 346 in = psMetadataLookupVector(NULL, det->fittedTrails, inColumnName); 347 } else { 348 //Error? 349 } 350 if (!in) { 351 psError(PS_ERR_PROGRAMMING, true, "failed to find input column: %s (convertTo32 is false)", inColumnName); 352 out = psVectorAlloc(outputSize, PS_TYPE_F32); 353 psVectorInit(out, NAN); 354 psMetadataAddVector(table, PS_LIST_TAIL, outColumnName, 0, NULL, out); 355 return false; 356 } 357 if (out == NULL) { 358 // First time through set up the output vector and the copy parameters 359 out = psVectorAlloc(outputSize, in->type.type); 360 next = (void *) out->data.U8; 361 switch (in->type.type) { 362 case PS_TYPE_S8: 363 elementSize = sizeof(psS8); 364 break; 365 case PS_TYPE_U8: 366 elementSize = sizeof(psU8); 367 break; 368 case PS_TYPE_S16: 369 elementSize = sizeof(psS16); 370 break; 371 case PS_TYPE_U16: 372 elementSize = sizeof(psU16); 373 break; 374 case PS_TYPE_S32: 375 elementSize = sizeof(psS32); 376 break; 377 case PS_TYPE_U32: 378 elementSize = sizeof(psU32); 379 break; 380 case PS_TYPE_S64: 381 elementSize = sizeof(psS64); 382 break; 383 case PS_TYPE_U64: 384 elementSize = sizeof(psU64); 385 break; 386 case PS_TYPE_F32: 387 elementSize = sizeof(psF32); 388 break; 389 case PS_TYPE_F64: 390 elementSize = sizeof(psF64); 391 break; 392 default: 393 psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Unknown vector type %d", in->type.type); 394 return false; 395 } 396 } 397 // We are doing nasty things here so we can use memcpy. 398 // It would be safer to do a proper loop over the elements. 399 long toCopy = det->num * elementSize; 400 memcpy(next, in->data.U8, toCopy); 401 next += toCopy; 402 } 403 } 404 // Finally add the new column to the output table 405 psMetadataAddVector(table, PS_LIST_TAIL, outColumnName, 0, NULL, out); 406 psFree(out); // drop reference 407 return true; 255 408 } 256 409 257 static bool addOutputColumn(psMetadata *table, const psArray *detections, long outputSize, char *outColumnName, char *inColumnName, bool convertTo32)258 {259 if (inColumnName == NULL) {260 inColumnName = outColumnName;261 }262 263 psVector *out = NULL;264 if (convertTo32) {265 // psFitsReadTableAllColumns reads columns of cfitsio type LONG and ULONG into a 64 bit integers266 // We want to write 32 bits to the output.267 int next = 0;268 for (long i=0; i<detections->n; i++) {269 ppMopsDetections *det = detections->data[i];270 if (!det || det->num == 0) {271 // no detections survived for this input272 continue;273 }274 psVector *in = psMetadataLookupVector(NULL, det->table, inColumnName);275 if (!in) {276 psError(PS_ERR_PROGRAMMING, true, "failed to find input column: %s", inColumnName);277 return false;278 }279 if (in->type.type != PS_TYPE_S64 && in->type.type != PS_TYPE_U64) {280 psError(PS_ERR_PROGRAMMING, true, "input column to convert is not S64 or U64: %s %d",281 inColumnName, in->type.type);282 return false;283 }284 if (out == NULL) {285 // First time through set up the output vector and the copy parameters286 if (in->type.type == PS_TYPE_S64) {287 out = psVectorAlloc(outputSize, PS_TYPE_S32);288 } else {289 out = psVectorAlloc(outputSize, PS_TYPE_U32);290 }291 }292 for (long d=0; d < det->num; d++) {293 if (in->type.type == PS_TYPE_S64) {294 out->data.S32[next++] = in->data.S64[d];295 } else {296 out->data.U32[next++] = in->data.U64[d];297 }298 }299 }300 } else {301 void *next = NULL;302 int elementSize = 0; // size of elements in vector... We are making assumptions here about the organization of primitives in memory so we can use memcopy303 for (long i=0; i<detections->n; i++) {304 ppMopsDetections *det = detections->data[i];305 if (!det || det->num == 0) {306 // no detections survived for this input307 continue;308 }309 psVector *in = psMetadataLookupVector(NULL, det->table, inColumnName);310 if (!in) {311 psError(PS_ERR_PROGRAMMING, true, "failed to find input column: %s", inColumnName);312 return false;313 }314 if (out == NULL) {315 // First time through set up the output vector and the copy parameters316 out = psVectorAlloc(outputSize, in->type.type);317 next = (void *) out->data.U8;318 switch (in->type.type) {319 case PS_TYPE_S8:320 elementSize = sizeof(psS8);321 break;322 case PS_TYPE_U8:323 elementSize = sizeof(psU8);324 break;325 case PS_TYPE_S16:326 elementSize = sizeof(psS16);327 break;328 case PS_TYPE_U16:329 elementSize = sizeof(psU16);330 break;331 case PS_TYPE_S32:332 elementSize = sizeof(psS32);333 break;334 case PS_TYPE_U32:335 elementSize = sizeof(psU32);336 break;337 case PS_TYPE_S64:338 elementSize = sizeof(psS64);339 break;340 case PS_TYPE_U64:341 elementSize = sizeof(psU64);342 break;343 case PS_TYPE_F32:344 elementSize = sizeof(psF32);345 break;346 case PS_TYPE_F64:347 elementSize = sizeof(psF64);348 break;349 default:350 psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Unknown vector type %d", in->type.type);351 return false;352 353 }354 }355 // We are doing nasty things here so we can use memcpy.356 // It would be safer to do a proper loop over the elements.357 long toCopy = det->num * elementSize;358 memcpy(next, in->data.U8, toCopy);359 next += toCopy;360 }361 }362 363 // Finally add the new column to the output table364 psMetadataAddVector(table, PS_LIST_TAIL, outColumnName, 0, NULL, out);365 psFree(out); // drop reference366 367 return true;368 }369 410 static bool addSkyfileIDColumn(psMetadata *table, const psArray *detections, long total, char *colName) 370 411 { 371 psVector *out = psVectorAlloc(total, PS_TYPE_S64);372 long next = 0;373 for (long i = 0; i<detections->n; i++) {374 ppMopsDetections *det = detections->data[i];375 if (!det) {376 continue;377 }378 psS64 diffSkyfileId = det->diffSkyfileId;379 for (long j = 0; j < det->num; j++) {380 out->data.S64[next++] = diffSkyfileId;381 }382 }383 psMetadataAddVector(table, PS_LIST_TAIL, colName, 0, NULL, out);384 psFree(out);385 return true;412 psVector *out = psVectorAlloc(total, PS_TYPE_S64); 413 long next = 0; 414 for (long i = 0; i<detections->n; i++) { 415 ppMopsDetections *det = detections->data[i]; 416 if (!det) { 417 continue; 418 } 419 psS64 diffSkyfileId = det->diffSkyfileId; 420 for (long j = 0; j < det->num; j++) { 421 out->data.S64[next++] = diffSkyfileId; 422 } 423 } 424 psMetadataAddVector(table, PS_LIST_TAIL, colName, 0, NULL, out); 425 psFree(out); 426 return true; 386 427 }
Note:
See TracChangeset
for help on using the changeset viewer.
