- Timestamp:
- Jun 19, 2012, 5:24:19 PM (14 years ago)
- Location:
- branches/meh_branches/ppstack_test
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
Ohana/src/relphot/src/StarOps.c (modified) (26 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/meh_branches/ppstack_test
- Property svn:mergeinfo changed
-
branches/meh_branches/ppstack_test/Ohana/src/relphot/src/StarOps.c
r31668 r34041 2 2 3 3 static int Nmax; 4 static double *list; 5 static double *dlist; 6 7 // When we rationalize the images/mosaics, we are driving the negative cloud images back 8 // to 0.0. At the same time, we make a guess to the effective impact on all other images, 9 // driven by the coupling of common stars. This array carries the impact of those offsets 10 // on each star 11 static double *Moffset; 12 4 5 typedef struct { 6 int Nfew; 7 int Ncode; 8 int Nsys; 9 int Nbad; 10 int Ncal; 11 int Nmos; 12 int Ngrid; 13 double *list; 14 double *dlist; 15 double *wlist; 16 double *aplist; 17 double *daplist; 18 } SetMrelInfo; 19 20 enum {THREAD_RUN, THREAD_DONE}; 21 22 typedef struct { 23 int entry; 24 int state; 25 Catalog *catalog; 26 int Ncatalog; 27 FlatCorrectionTable *flatcorr; 28 SetMrelInfo summary; 29 } ThreadInfo; 30 31 // ** internal functions: 32 void *setMrel_worker (void *data); 33 int setMrel_threaded (Catalog *catalog, int Ncatalog, FlatCorrectionTable *flatcorr); 34 int setMrel_catalog (Catalog *catalog, int Nc, int pass, FlatCorrectionTable *flatcorr, SetMrelInfo *results, int Nsecfilt); 35 int print_measure_set (Average *average, SecFilt *secfilt, Measure *measure); 36 37 // we want to allocate the stats list,dlist arrays only once (or once per thread). 38 // this function finds the largest array so we can allocate that max size when needed 13 39 void initMrel (Catalog *catalog, int Ncatalog) { 14 40 … … 21 47 } 22 48 } 23 24 ALLOCATE (list, double, MAX (1, Nmax));25 ALLOCATE (dlist, double, MAX (1, Nmax));26 ALLOCATE (Moffset, double, MAX (1, Nmax));27 49 } 28 50 … … 47 69 } 48 70 49 int setMrel (Catalog *catalog, int Ncatalog) { 71 void SetMrelInfoInit (SetMrelInfo *results, int allocLists) { 72 results->Nfew = 0; 73 results->Ncode = 0; 74 results->Nsys = 0; 75 results->Nbad = 0; 76 results->Ncal = 0; 77 results->Nmos = 0; 78 results->Ngrid = 0; 79 if (allocLists) { 80 ALLOCATE (results->list, double, Nmax); 81 ALLOCATE (results->dlist, double, Nmax); 82 ALLOCATE (results->wlist, double, Nmax); 83 } 84 } 85 86 void SetMrelInfoFree (SetMrelInfo *results) { 87 free (results->list); 88 free (results->dlist); 89 free (results->wlist); 90 } 91 92 void SetMrelInfoAccum (SetMrelInfo *summary, SetMrelInfo *results) { 93 summary->Nfew += results->Nfew ; 94 summary->Ncode += results->Ncode ; 95 summary->Nsys += results->Nsys ; 96 summary->Nbad += results->Nbad ; 97 summary->Ncal += results->Ncal ; 98 summary->Nmos += results->Nmos ; 99 summary->Ngrid += results->Ngrid; 100 } 101 102 // mutex to lock setMrel_worker operations 103 static pthread_mutex_t setMrel_mutex = PTHREAD_MUTEX_INITIALIZER; 104 static int nextCatalog = 0; 105 106 // we have an array of catalogs (catalog, Ncatalog). we need to hand out catalogs one at a time to 107 // the worker threads as they need 108 off_t getNextCatalogForThread (int Ncatalog) { 109 110 pthread_mutex_lock (&setMrel_mutex); 111 if (nextCatalog >= Ncatalog) { 112 pthread_mutex_unlock (&setMrel_mutex); 113 return (-1); 114 } 115 int thisCatalog = nextCatalog; 116 nextCatalog ++; 117 118 pthread_mutex_unlock (&setMrel_mutex); 119 return (thisCatalog); 120 } 121 122 // setMrel and setMrelOutput are extremely similar, but have slightly different implications: 123 // * setMrel uses the internal Tiny structures only 124 // * setMrelOutput skips stars for which there are too few good measurements 125 // * setMrelOutput is meant to be called repeatedly, relaxing the criteria for 'good' on each pass 126 // * setMrelOutput updates 2MASS average flags 127 // * setMrelOutput updates average EXT flags (PS1 and 2MASS) 128 129 int setMrel (Catalog *catalog, int Ncatalog, FlatCorrectionTable *flatcorr) { 130 131 int i; 132 133 if (NTHREADS) { 134 int status = setMrel_threaded (catalog, Ncatalog, flatcorr); 135 return status; 136 } 137 138 int Nsecfilt = GetPhotcodeNsecfilt (); 139 140 SetMrelInfo summary, results; 141 SetMrelInfoInit (&summary, FALSE); 142 SetMrelInfoInit (&results, TRUE); 143 144 for (i = 0; i < Ncatalog; i++) { 145 // pass == -1 for anything other than the final pass 146 setMrel_catalog (catalog, i, -1, flatcorr, &results, Nsecfilt); 147 SetMrelInfoAccum (&summary, &results); 148 } 149 if (VERBOSE2) fprintf (stderr, "%d stars with no data in photcode, %d stars marked having too few measurements (Nbad: %d, Ncal: %d, Nmos: %d, Ngrid: %d, Nsys: %d)\n", summary.Ncode, summary.Nfew, summary.Nbad, summary.Ncal, summary.Nmos, summary.Ngrid, summary.Nsys); 150 151 SetMrelInfoFree (&results); 152 153 return (TRUE); 154 } 155 156 int setMrelOutput (Catalog *catalog, int Ncatalog, int pass, FlatCorrectionTable *flatcorr) { 157 158 int i; 159 160 int Nsecfilt = GetPhotcodeNsecfilt (); 161 162 SetMrelInfo summary, results; 163 SetMrelInfoInit (&summary, FALSE); 164 SetMrelInfoInit (&results, TRUE); // allocates results->list,dlist,wlist 165 ALLOCATE (results.aplist, double, Nmax); 166 ALLOCATE (results.daplist, double, Nmax); 167 168 for (i = 0; i < Ncatalog; i++) { 169 setMrel_catalog (catalog, i, pass, flatcorr, &results, Nsecfilt); // XXX add arguments as needed for options 170 SetMrelInfoAccum (&summary, &results); 171 } 172 if (VERBOSE2) fprintf (stderr, "%d stars with no data in photcode, %d stars marked having too few measurements (Nbad: %d, Ncal: %d, Nmos: %d, Ngrid: %d, Nsys: %d)\n", summary.Ncode, summary.Nfew, summary.Nbad, summary.Ncal, summary.Nmos, summary.Ngrid, summary.Nsys); 173 174 SetMrelInfoFree (&results); 175 free (results.aplist); 176 free (results.daplist); 177 return (TRUE); 178 } 179 180 int setMrel_threaded (Catalog *catalog, int Ncatalog, FlatCorrectionTable *flatcorr) { 181 182 int i; 183 184 SetMrelInfo summary; 185 SetMrelInfoInit (&summary, FALSE); 186 187 pthread_attr_t attr; 188 pthread_attr_init (&attr); 189 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); 190 191 pthread_t *threads; 192 ALLOCATE (threads, pthread_t, NTHREADS); 193 194 ThreadInfo *threadinfo; 195 ALLOCATE (threadinfo, ThreadInfo, NTHREADS); 196 197 // each time this function is called, we cycle through the available catalogs. 198 // make sure we start at 0 199 nextCatalog = 0;; 200 201 // launch N worker threads 202 for (i = 0; i < NTHREADS; i++) { 203 threadinfo[i].entry = i; 204 threadinfo[i].state = THREAD_RUN; 205 threadinfo[i].catalog = catalog; 206 threadinfo[i].Ncatalog = Ncatalog; 207 threadinfo[i].flatcorr = flatcorr; 208 SetMrelInfoInit (&threadinfo[i].summary, FALSE); 209 pthread_create (&threads[i], NULL, setMrel_worker, &threadinfo[i]); 210 } 211 pthread_attr_destroy (&attr); 212 213 // wait until all threads have finished 214 while (1) { 215 int allDone = TRUE; 216 for (i = 0; i < NTHREADS; i++) { 217 if (threadinfo[i].state == THREAD_RUN) allDone = FALSE; 218 } 219 if (allDone) { 220 break; 221 } 222 usleep (500000); 223 } 224 225 // all threads are done, free the threads array and grab the info 226 free (threads); 227 228 // report stats & summary from the threads 229 for (i = 0; i < NTHREADS; i++) { 230 if (VERBOSE2) fprintf (stderr, "setMrel thread %d : %d stars with no data in photcode, %d stars marked having too few measurements (Nbad: %d, Ncal: %d, Nmos: %d, Ngrid: %d, Nsys: %d)\n", 231 i, 232 threadinfo[i].summary.Ncode, 233 threadinfo[i].summary.Nfew, 234 threadinfo[i].summary.Nbad, 235 threadinfo[i].summary.Ncal, 236 threadinfo[i].summary.Nmos, 237 threadinfo[i].summary.Ngrid, 238 threadinfo[i].summary.Nsys); 239 SetMrelInfoAccum (&summary, &threadinfo[i].summary); 240 } 241 if (VERBOSE2) fprintf (stderr, "total : %d stars with no data in photcode, %d stars marked having too few measurements (Nbad: %d, Ncal: %d, Nmos: %d, Ngrid: %d, Nsys: %d)\n", summary.Ncode, summary.Nfew, summary.Nbad, summary.Ncal, summary.Nmos, summary.Ngrid, summary.Nsys); 242 free (threadinfo); 243 244 return TRUE; 245 } 246 247 void *setMrel_worker (void *data) { 248 249 ThreadInfo *threadinfo = data; 250 251 int Nsecfilt = GetPhotcodeNsecfilt (); 252 253 SetMrelInfo results; 254 SetMrelInfoInit (&results, TRUE); // allocate list, dlist arrays here 255 256 while (1) { 257 258 off_t i = getNextCatalogForThread(threadinfo->Ncatalog); 259 if (i == -1) { 260 threadinfo->state = THREAD_DONE; 261 return NULL; 262 } 263 264 Catalog *catalog = threadinfo->catalog; 265 FlatCorrectionTable *flatcorr = threadinfo->flatcorr; 266 267 // pass == -1 for anything other than the final pass 268 setMrel_catalog (catalog, i, -1, flatcorr, &results, Nsecfilt); 269 SetMrelInfoAccum (&threadinfo->summary, &results); 270 } 271 272 SetMrelInfoFree (&results); 273 return NULL; 274 } 275 276 # define SKIP_THIS_MEAS(REASON) { \ 277 catalog[Nc].measureT[m].dbFlags |= ID_MEAS_SKIP_PHOTOM; \ 278 if (catalog[Nc].measure) { \ 279 catalog[Nc].measure [m].dbFlags |= ID_MEAS_SKIP_PHOTOM; \ 280 } \ 281 results->REASON ++; \ 282 continue; } 283 284 285 // setMrel_catalog is used in 3 different contexts: 286 287 // * during the main relphot iterations: 288 // ** operations only apply to measureT / averageT 289 // ** we are applying the analysis to the bright subset catalog 290 // ** we skip any stars found to be bad (STAR_BAD) 291 292 // * during the final pass 293 // ** operations are applied to all objects 294 // ** we have special tests for PS1 extended data, 2MASS extended & good data, & synthetic photometry 295 296 // * during the stand-alone '-averages' mode (relphot_objects) 297 // ** no image data is loaded 298 // ** we only use the provided calibration (measure.Mcal) 299 // ** we skip outlier rejection of measurements 300 301 // set the Mrel values for the specified catalog 302 // NOTE: here 'catalog' is a pointer to a specific catalog, not the root of the array 303 int setMrel_catalog (Catalog *catalog, int Nc, int pass, FlatCorrectionTable *flatcorr, SetMrelInfo *results, int Nsecfilt) { 50 304 51 305 off_t j, k, m; 52 int i, N, Nfew, Nsys, Nbad, Ncal, Nmos, Ngrid;306 int N; 53 307 float Msys, Mcal, Mmos, Mgrid; 54 StatType stats; 55 56 int Nsecfilt = GetPhotcodeNsecfilt (); 57 Nfew = Nsys = Nbad = Ncal = Nmos = Ngrid = 0; 58 59 for (i = 0; i < Ncatalog; i++) { 60 for (j = 0; j < catalog[i].Naverage; j++) { 61 62 int Ns; 63 for (Ns = 0; Ns < Nphotcodes; Ns++) { 64 65 int thisCode = photcodes[Ns][0].code; 66 int Nsec = GetPhotcodeNsec(thisCode); 67 68 /* calculate the average value for a single star */ 69 70 // skip bad stars 71 if (catalog[i].secfilt[Nsecfilt*j+Nsec].flags & STAR_BAD) continue; 72 m = catalog[i].averageT[j].measureOffset; 73 74 N = 0; 75 for (k = 0; k < catalog[i].averageT[j].Nmeasure; k++, m++) { 76 // skip measurements that do not match the current photcode 77 int ecode = GetPhotcodeEquivCodebyCode (catalog[i].measureT[m].photcode); 78 if (ecode != thisCode) { continue; } 79 80 if (catalog[i].measureT[m].dbFlags & MEAS_BAD) { 81 Nbad ++; 82 continue; 83 } 84 // XXX allow REF stars (no Image Entry) to be included in the calculation this 85 // should be optionally set, and should allow for REF stars to be downweighted by 86 // more than their reported errors. how such info is carried is unclear... 87 if (getImageEntry (m, i) < 0) { 88 Mcal = Mmos = Mgrid = 0; 89 } else { 90 Mcal = getMcal (m, i); 91 if (isnan(Mcal)) { 92 Ncal ++; 93 continue; 94 } 95 Mmos = getMmos (m, i); 96 if (isnan(Mmos)) { 97 Nmos ++; 98 continue; 99 } 100 Mgrid = getMgrid (m, i); 101 if (isnan(Mgrid)) { 102 Ngrid++; 103 continue; 104 } 105 } 106 107 Msys = PhotSysTiny (&catalog[i].measureT[m], &catalog[i].averageT[j], &catalog[i].secfilt[j*Nsecfilt]); 108 if (isnan(Msys)) { 109 Nsys++; 110 continue; 111 } 112 list[N] = Msys - Mcal - Mmos - Mgrid; 113 dlist[N] = MAX (catalog[i].measureT[m].dM, MIN_ERROR); 114 115 // tie down reference photometry if the -refcode (code) option is selected 116 if (refPhotcode) { 117 if (GetPhotcodeEquivCodebyCode(catalog[i].measureT[m].photcode) == refPhotcode[0].equiv) { 118 // increase the weight by a factor of 100: 119 dlist[N] = 0.01*catalog[i].measureT[m].dM; 120 } 121 } 122 N++; 123 } 124 125 // when performing the grid analysis, STAR_TOOFEW will be set to 1; 126 if (N <= STAR_TOOFEW) { /* too few measurements */ 127 catalog[i].secfilt[Nsecfilt*j+Nsec].flags |= ID_STAR_FEW; 128 Nfew ++; 308 309 StatType stats, apstats; 310 liststats_setmode (&stats, STATMODE); 311 liststats_setmode (&apstats, STATMODE); 312 313 double *list = results->list; 314 double *dlist = results->dlist; 315 double *wlist = results->wlist; 316 double *aplist = results->aplist; 317 double *daplist = results->daplist; 318 319 SetMrelInfoInit (results, FALSE); // do not allocate list,dlist,wlist arrays 320 321 int isSetMrelFinal = (pass >= 0); 322 323 for (j = 0; j < catalog[Nc].Naverage; j++) { 324 // XXX accumulate all secfilt values in a single pass? 325 326 // option for a test print 327 if (FALSE && (catalog[Nc].average[j].objID == 0x46a4) && (catalog[Nc].average[j].catID == 0xf40e)) { 328 fprintf (stderr, "test obj\n"); 329 print_measure_set (&catalog[Nc].average[j], &catalog[Nc].secfilt[j*Nsecfilt], catalog[Nc].measure); 330 } 331 332 int GoodPS1 = FALSE; 333 int Good2MASS = FALSE; 334 int Galaxy2MASS = FALSE; 335 336 int NextPS1 = 0; 337 int NpsfPS1 = 0; 338 339 int Ns; 340 for (Ns = 0; Ns < Nphotcodes; Ns++) { 341 342 int thisCode = photcodes[Ns][0].code; 343 int Nsec = GetPhotcodeNsec(thisCode); 344 345 /* calculate the average mag in this SEC photcode for a single star */ 346 347 /* star/photcodes already calibrated */ 348 if ( isSetMrelFinal && catalog[Nc].found[Nsecfilt*j+Nsec]) continue; 349 350 // skip bad stars 351 if (!isSetMrelFinal && (catalog[Nc].secfilt[Nsecfilt*j+Nsec].flags & STAR_BAD)) continue; 352 353 int Ncode = 0; 354 int Next = 0; 355 int haveSynth = FALSE; 356 357 int forceSynth = FALSE; 358 int forceSynthEntry = -1; 359 360 int haveUbercal = FALSE; 361 362 int minUbercalDist = 1000; 363 364 N = 0; 365 m = catalog[Nc].averageT[j].measureOffset; 366 for (k = 0; k < catalog[Nc].averageT[j].Nmeasure; k++, m++) { 367 368 // skip measurements that do not match the current photcode 369 PhotCode *code = GetPhotcodebyCode (catalog[Nc].measureT[m].photcode); 370 if (!code) continue; 371 if (code->equiv != thisCode) { continue; } 372 Ncode ++; 373 374 if (catalog[Nc].measureT[m].dbFlags & MEAS_BAD) SKIP_THIS_MEAS(Nbad); 375 376 if (getImageEntry (m, Nc) < 0) { 377 // measurements without an image are either external reference photometry or 378 // data for which the associated image has not been loaded (probably because of 379 // overlaps). Msys + measure.Mcal is our best guess of the true magnitude 380 Mmos = Mgrid = 0; 381 Mcal = catalog[Nc].measureT[m].Mcal; // check that this is zero for loaded REF value 129 382 } else { 130 catalog[i].secfilt[Nsecfilt*j+Nsec].flags &= ~ID_STAR_FEW; 131 } 132 133 liststats (list, dlist, N, &stats); 134 135 catalog[i].secfilt[Nsecfilt*j+Nsec].M = stats.mean; 136 catalog[i].secfilt[Nsecfilt*j+Nsec].dM = stats.sigma; 137 catalog[i].secfilt[Nsecfilt*j+Nsec].Xm = (stats.Nmeas > 1) ? 100.0*log10(stats.chisq) : NAN_S_SHORT; 138 } 139 } 140 } 141 fprintf (stderr, "%d stars marked having too few measurements (Nbad: %d, Ncal: %d, Nmos: %d, Ngrid: %d, Nsys: %d)\n", Nfew, Nbad, Ncal, Nmos, Ngrid, Nsys); 142 143 return (TRUE); 144 } 145 146 int setMrelOutput (Catalog *catalog, int Ncatalog, int mark) { 147 148 int i, N; 149 off_t j, k, m, Nmax; 150 float Msys, Mcal, Mmos, Mgrid; 151 double *list, *dlist; 152 StatType stats; 153 int Nsec, Nsecfilt, ecode; 154 155 Nsecfilt = GetPhotcodeNsecfilt (); 156 157 /* Nmeasure is now different, need to reallocate */ 158 Nmax = 0; 159 for (i = 0; i < Ncatalog; i++) { 160 for (j = 0; j < catalog[i].Naverage; j++) { 161 Nmax = MAX (Nmax, catalog[i].averageT[j].Nmeasure); 162 } 163 } 164 ALLOCATE (list, double, MAX (1, Nmax)); 165 ALLOCATE (dlist, double, MAX (1, Nmax)); 166 167 for (i = 0; i < Ncatalog; i++) { 168 for (j = 0; j < catalog[i].Naverage; j++) { 169 /* skip stars already calibrated */ 170 if (catalog[i].found[j]) continue; 171 172 int Ns; 173 for (Ns = 0; Ns < Nphotcodes; Ns++) { 174 int thisCode = photcodes[Ns][0].code; 175 Nsec = GetPhotcodeNsec(thisCode); 176 177 N = 0; 178 m = catalog[i].averageT[j].measureOffset; 179 for (k = 0; k < catalog[i].averageT[j].Nmeasure; k++, m++) { 180 // skip measurements that do not match the current photcode 181 ecode = GetPhotcodeEquivCodebyCode (catalog[i].measureT[m].photcode); 182 if (ecode != thisCode) { continue; } 183 184 if (catalog[i].measureT[m].dbFlags & MEAS_BAD) continue; 185 186 // XXX allow REF stars (no Image Entry) to be included in the calculation this 187 // should be optionally set, and should allow for REF stars to be downweighted by 188 // more than their reported errors. how such info is carried is unclear... 189 if (getImageEntry (m, i) < 0) { 190 Mcal = Mmos = Mgrid = 0; 191 } else { 192 Mcal = getMcal (m, i); 193 if (isnan(Mcal)) continue; 194 Mmos = getMmos (m, i); 195 if (isnan(Mmos)) continue; 196 Mgrid = getMgrid (m, i); 197 if (isnan(Mgrid)) continue; 198 } 199 200 Msys = PhotSysTiny (&catalog[i].measureT[m], &catalog[i].averageT[j], &catalog[i].secfilt[j*Nsecfilt]); 201 list[N] = Msys - Mcal - Mmos - Mgrid; 202 dlist[N] = MAX (catalog[i].measureT[m].dM, MIN_ERROR); 203 N++; 204 } 205 if (N < 1) continue; 206 207 liststats (list, dlist, N, &stats); 208 if (mark) catalog[i].found[j] = TRUE; 209 210 /* use sigma or error in dM for output? */ 211 catalog[i].secfilt[Nsecfilt*j+Nsec].M = stats.mean; 212 catalog[i].secfilt[Nsecfilt*j+Nsec].dM = MAX (stats.error, stats.sigma); 213 catalog[i].secfilt[Nsecfilt*j+Nsec].Xm = (stats.Nmeas > 1) ? 100.0*log10(stats.chisq) : NAN_S_SHORT; 214 } 215 } 216 } 217 218 free (list); 219 free (dlist); 220 return (TRUE); 221 } 222 223 // For each average object, set the average mags based on existing equiv photometry. 224 // NOTE: this function operates on the real Measure & Average structures, not the 225 // MeasureTiny & AverageTiny structures 226 int setMave (Catalog *catalog, int Ncatalog) { 227 228 off_t j, k, m, Nmax; 229 int i, Ns, Nsecfilt, N, Nc; 230 float Msys; 231 double *list, *dlist; 232 StatType stats; 233 PhotCode *code; 234 DVOAverageFlags flagBits; 235 236 flagBits = ID_OBJ_EXT | ID_OBJ_EXT_ALT | ID_OBJ_GOOD | ID_OBJ_GOOD_ALT; 237 238 // pre-allocate a list for stats purposes 239 Nmax = 0; 240 for (i = 0; i < Ncatalog; i++) { 241 for (j = 0; j < catalog[i].Naverage; j++) { 242 Nmax = MAX (Nmax, catalog[i].average[j].Nmeasure); 243 } 244 } 245 ALLOCATE (list, double, MAX (1, Nmax)); 246 ALLOCATE (dlist, double, MAX (1, Nmax)); 247 248 Nsecfilt = GetPhotcodeNsecfilt (); 249 250 # define PSFQUALSTATS 1 251 for (i = 0; i < Ncatalog; i++) { 252 for (j = 0; j < catalog[i].Naverage; j++) { 253 254 // update average photometry for each of the average filters 255 for (Ns = 0; Ns < Nsecfilt; Ns++) { 256 257 code = GetPhotcodebyNsec (Ns); 258 Nc = code[0].code; 259 260 N = 0; 261 m = catalog[i].average[j].measureOffset; 262 for (k = 0; k < catalog[i].average[j].Nmeasure; k++, m++) { 263 if (catalog[i].measure[m].dbFlags & MEAS_BAD) continue; 264 if (GetPhotcodeEquivCodebyCode (catalog[i].measure[m].photcode) != Nc) continue; 265 266 Msys = PhotSys (&catalog[i].measure[m], &catalog[i].average[j], &catalog[i].secfilt[j*Nsecfilt]); 267 if (isnan(Msys)) continue; 268 269 // XXX only apply this filter for psphot data from GPC1 for now... 270 if (PSFQUALSTATS && (catalog[i].measure[m].photcode > 10000) && (catalog[i].measure[m].photcode < 10500)) { 271 if (catalog[i].measure[m].psfQual < 0.85) continue; 272 } 273 274 // XXX make it optional to apply Mcal (do I need an extra field for advisory Mcal?) 275 list[N] = Msys - catalog[i].measure[m].Mcal; 276 dlist[N] = MAX (catalog[i].measure[m].dM, MIN_ERROR); 277 N++; 278 } 279 if (N < 1) continue; 280 281 liststats (list, dlist, N, &stats); 282 283 /* use sigma or error in dM for output? */ 284 catalog[i].secfilt[Nsecfilt*j+Ns].M = stats.mean; 285 catalog[i].secfilt[Nsecfilt*j+Ns].dM = MAX (stats.error, stats.sigma); 286 catalog[i].secfilt[Nsecfilt*j+Ns].Xm = (stats.Nmeas > 1) ? 100.0*log10(stats.chisq) : NAN_S_SHORT; 287 catalog[i].secfilt[Nsecfilt*j+Ns].Ncode = N; 288 catalog[i].secfilt[Nsecfilt*j+Ns].Nused = stats.Nmeas; 289 } 290 291 // update average flags based on the detection stats. 292 // XXX we need to clean this up -- this is a serious set of hacks... 293 if (PSFQUALSTATS) { 294 int Galaxy2MASS, GalaxySDSS, goodPS1, nEXT, nPSF, good2MASS; 295 296 Galaxy2MASS = FALSE; // best guess for galaxy based on 2MASS J measurements (gal_contam == measure.flags[0x00400000 | 0x00800000]) 297 GalaxySDSS = FALSE; // best guess for galaxy based on SDSS measurements (XXX need to fix SDSS flags) 298 goodPS1 = FALSE; // true if any PS1 measurements have psfQual > 0.85 299 good2MASS = FALSE; // true if 2MASS J measurements have significant detections 300 nEXT = nPSF = 0; // number of PS1 PSF vs EXT measurements 301 302 m = catalog[i].average[j].measureOffset; 303 for (k = 0; k < catalog[i].average[j].Nmeasure; k++, m++) { 304 305 // PS1 data : 306 if ((catalog[i].measure[m].photcode >= 10000) && (catalog[i].measure[m].photcode <= 10500)) { 307 if (catalog[i].measure[m].psfQual > 0.85) { 308 goodPS1 = TRUE; 309 if (!isnan(catalog[i].measure[m].Map)) { 310 if (catalog[i].measure[m].M - catalog[i].measure[m].Map > 0.5) { 311 nEXT ++; 312 } else { 313 nPSF ++; 314 } 383 Mcal = getMcal (m, Nc, flatcorr, catalog); 384 if (isnan(Mcal)) SKIP_THIS_MEAS(Ncal); 385 Mmos = getMmos (m, Nc); 386 if (isnan(Mmos)) SKIP_THIS_MEAS(Nmos); 387 Mgrid = getMgrid (m, Nc); 388 if (isnan(Mgrid)) SKIP_THIS_MEAS(Ngrid); 389 } 390 391 Msys = PhotSysTiny (&catalog[Nc].measureT[m], &catalog[Nc].averageT[j], &catalog[Nc].secfilt[j*Nsecfilt]); 392 if (isnan(Msys)) SKIP_THIS_MEAS(Nsys); 393 394 list[N] = Msys - Mcal - Mmos - Mgrid; 395 396 int myUbercalDist = getUbercalDist(m,Nc); 397 minUbercalDist = MIN(minUbercalDist, myUbercalDist); 398 399 if (isSetMrelFinal) { 400 float Map = PhotAper (&catalog[Nc].measure[m]); 401 aplist[N] = Map - Mcal - Mmos - Mgrid; 402 403 // special options for PS1 data 404 if ((catalog[Nc].measure[m].photcode >= 10000) && (catalog[Nc].measure[m].photcode <= 10500)) { 405 // count the extended detections 406 if (!isnan(catalog[Nc].measure[m].Map)) { 407 if (catalog[Nc].measure[m].M - catalog[Nc].measure[m].Map > 0.5) { 408 Next ++; 409 NextPS1 ++; 410 } else { 411 NpsfPS1 ++; 315 412 } 316 413 } 317 414 } 318 319 // 2MASS data:320 if (catalog[i].measure[m].photcode == 2011) {321 if (catalog[i].measure[m].photFlags & 0x00c00000) {415 // count extended detections for 2MASS (XXX NOTE hardwired photcodes 2011, 2012, 2013) 416 if ((catalog[Nc].measure[m].photcode >= 2011) && (catalog[Nc].measure[m].photcode <= 2013)) { 417 if (catalog[Nc].measure[m].photFlags & 0x00c00000) { 418 Next ++; 322 419 Galaxy2MASS = TRUE; 323 420 } 324 if (catalog[i].measure[m].photFlags & 0x00000007) { 325 good2MASS = TRUE; 421 if (pass == 0) { 422 if (catalog[Nc].measure[m].photFlags & 0x00000007) { 423 Good2MASS = TRUE; 424 } else { 425 // detections without one of these bits should only be used in PASS_1 426 SKIP_THIS_MEAS(Nbad); 427 continue; 428 } 326 429 } 327 } 328 } 329 330 // we attempt to set a few flags here; reset those bits before trying: 331 catalog[i].average[j].flags &= ~flagBits; 332 333 if (nEXT && (nEXT > nPSF)) { 334 catalog[i].average[j].flags |= ID_OBJ_EXT; 335 } 336 if (goodPS1) { 337 catalog[i].average[j].flags |= ID_OBJ_GOOD; 338 } 339 if (Galaxy2MASS) { 340 catalog[i].average[j].flags |= ID_OBJ_EXT_ALT; 341 } 342 if (good2MASS) { 343 catalog[i].average[j].flags |= ID_OBJ_GOOD_ALT; 344 } 345 } 346 } 347 } 348 349 free (list); 350 free (dlist); 430 } 431 432 // Blindly accepth the SYNTH mags if we are above saturation, otherwise, 433 // ignore SYNTH photcodes until PASS == 4 (where we also accept saturated stars) 434 if ((catalog[Nc].measure[m].photcode >= 3001) && (catalog[Nc].measure[m].photcode <= 3005)) { 435 // something of a hack: force object to use synth values if synth mags >> 436 // saturation (3pi instrumental mags < -15) 437 float MaxMagForceSynth = NAN; 438 switch (catalog[Nc].measure[m].photcode) { 439 case 3001: 440 MaxMagForceSynth = 13.64; 441 break; 442 case 3002: 443 MaxMagForceSynth = 13.76; 444 break; 445 case 3003: 446 MaxMagForceSynth = 13.74; 447 break; 448 case 3004: 449 MaxMagForceSynth = 12.94; 450 break; 451 case 3005: 452 MaxMagForceSynth = 12.01; 453 break; 454 } 455 if (catalog[Nc].measureT[m].M < MaxMagForceSynth) { 456 forceSynth = TRUE; 457 forceSynthEntry = N; 458 } else { 459 if (pass < 4) { 460 SKIP_THIS_MEAS(Nbad); 461 continue; 462 } 463 haveSynth = TRUE; 464 } 465 } 466 } 467 468 // dlist gives the error per measurement, wlist gives the weight 469 // we can modify the error and weight in a few ways: 470 // 1) MIN_ERROR guarantees a floor 471 // 2) photomErrSys is added in quadrature as a sytematic error, set per photcode 472 // 3) UBERCAL measurements can have their weight increased by a big factor to help tie down the averages 473 // 4) some reference photcode of some kind can be specified as fixed and have a high weight 474 dlist[N] = MAX (hypot(catalog[Nc].measureT[m].dM, code->photomErrSys), MIN_ERROR); 475 wlist[N] = 1.0; 476 477 // up-weight the ubercal values (or convergence can take a long time...) 478 if (catalog[Nc].measureT[m].dbFlags & ID_MEAS_PHOTOM_UBERCAL) { 479 wlist[N] = 10.0; 480 } 481 482 // tie down reference photometry if the -refcode (code) option is selected 483 // eg, -refcode g_SDSS 484 // this probably makes no sense in the context of multifilter analysis 485 if (refPhotcode) { 486 if (code->code == refPhotcode->code) { 487 wlist[N] = 100.0; 488 } 489 } 490 N++; 491 } 492 493 int Nminmeas = isSetMrelFinal ? 1 : STAR_TOOFEW + 1; 494 495 // when performing the grid analysis, STAR_TOOFEW should be set to 1; 496 if (N < Nminmeas) { /* too few measurements */ 497 // fprintf (f, "%10.6f %10.6f %d %d %d\n", catalog[Nc].averageT[j].R, catalog[Nc].averageT[j].D, catalog[Nc].measureT[catalog[Nc].averageT[j].measureOffset].imageID, N, STAR_TOOFEW); 498 catalog[Nc].secfilt[Nsecfilt*j+Nsec].flags |= ID_STAR_FEW; 499 if (Ncode == 0) { 500 results->Ncode ++; 501 } else { 502 results->Nfew ++; 503 } 504 continue; 505 } else { 506 catalog[Nc].secfilt[Nsecfilt*j+Nsec].flags &= ~ID_STAR_FEW; 507 } 508 509 if (forceSynth) { 510 // use the single SYNTH value instead of the other mags here 511 myAssert ((forceSynthEntry < N) && (forceSynthEntry >= 0), "programming error"); 512 list[0] = list[forceSynthEntry]; 513 dlist[0] = dlist[forceSynthEntry]; 514 wlist[0] = wlist[forceSynthEntry]; 515 N = 1; 516 } 517 liststats (list, dlist, wlist, N, &stats); 518 519 catalog[Nc].secfilt[Nsecfilt*j+Nsec].M = stats.mean; 520 catalog[Nc].secfilt[Nsecfilt*j+Nsec].dM = stats.error; 521 catalog[Nc].secfilt[Nsecfilt*j+Nsec].Xm = (stats.Nmeas > 1) ? 100.0*log10(stats.chisq + 1e-4) : NAN_S_SHORT; 522 523 // when running -averages, we have no information about the images, so we cannot set this 524 if (minUbercalDist > -1) { 525 catalog[Nc].secfilt[Nsecfilt*j+Nsec].ubercalDist = minUbercalDist; 526 } 527 528 if (isSetMrelFinal) { 529 catalog[Nc].found[Nsecfilt*j+Nsec] = TRUE; 530 531 catalog[Nc].secfilt[Nsecfilt*j+Nsec].Mstdev = 1000.0*stats.sigma; // Mstdev is in millimags (not enough space for more precision) 532 catalog[Nc].secfilt[Nsecfilt*j+Nsec].Ncode = Ncode; 533 catalog[Nc].secfilt[Nsecfilt*j+Nsec].Nused = stats.Nmeas; 534 535 catalog[Nc].secfilt[Nsecfilt*j+Nsec].M_80 = 1000 * stats.Upper80; 536 catalog[Nc].secfilt[Nsecfilt*j+Nsec].M_20 = 1000 * stats.Lower20; 537 538 // NOTE : use the modified weight for apmags as well as psf mags 539 liststats (aplist, daplist, wlist, N, &apstats); 540 541 catalog[Nc].secfilt[Nsecfilt*j+Nsec].Map = apstats.mean; 542 543 // NOTE: for 2MASS measurements, Next should be 1, as should N 544 if ((Next > 0) && (Next > 0.5*N)) { 545 catalog[Nc].secfilt[Nsecfilt*j+Nsec].flags |= ID_SECF_OBJ_EXT; 546 } 547 548 switch (pass) { 549 case 0: 550 catalog[Nc].secfilt[Nsecfilt*j+Nsec].flags |= ID_PHOTOM_PASS_0; 551 GoodPS1 = TRUE; 552 break; 553 case 1: 554 catalog[Nc].secfilt[Nsecfilt*j+Nsec].flags |= ID_PHOTOM_PASS_1; 555 GoodPS1 = TRUE; 556 break; 557 case 2: 558 catalog[Nc].secfilt[Nsecfilt*j+Nsec].flags |= ID_PHOTOM_PASS_2; 559 GoodPS1 = TRUE; 560 break; 561 case 3: 562 catalog[Nc].secfilt[Nsecfilt*j+Nsec].flags |= ID_PHOTOM_PASS_3; 563 break; 564 case 4: 565 catalog[Nc].secfilt[Nsecfilt*j+Nsec].flags |= ID_PHOTOM_PASS_4; 566 break; 567 } 568 if (haveSynth) { 569 catalog[Nc].secfilt[Nsecfilt*j+Nsec].flags |= ID_SECF_USE_SYNTH; 570 } 571 if (haveUbercal) { 572 catalog[Nc].secfilt[Nsecfilt*j+Nsec].flags |= ID_SECF_USE_UBERCAL; 573 } 574 } 575 } 576 577 if (isSetMrelFinal) { 578 DVOAverageFlags flagBits = ID_OBJ_EXT | ID_OBJ_EXT_ALT | ID_OBJ_GOOD | ID_OBJ_GOOD_ALT; 579 580 // we attempt to set a few flags here; reset those bits before trying: 581 catalog[Nc].average[j].flags &= ~flagBits; 582 583 if (NextPS1 && (NextPS1 > NpsfPS1)) { 584 catalog[Nc].average[j].flags |= ID_OBJ_EXT; 585 } 586 if (GoodPS1) { 587 catalog[Nc].average[j].flags |= ID_OBJ_GOOD; 588 } 589 if (Galaxy2MASS) { 590 catalog[Nc].average[j].flags |= ID_OBJ_EXT_ALT; 591 } 592 if (Good2MASS) { 593 catalog[Nc].average[j].flags |= ID_OBJ_GOOD_ALT; 594 } 595 } 596 } 351 597 return (TRUE); 352 598 } 353 599 600 int print_measure_set (Average *average, SecFilt *secfilt, Measure *measure) { 601 602 off_t k; 603 604 int Nsecfilt = GetPhotcodeNsecfilt (); 605 606 off_t m = average[0].measureOffset; 607 608 for (k = 0; k < average[0].Nmeasure; k++, m++) { 609 fprintf (stderr, "meas: %08x\n", measure[m].dbFlags); 610 } 611 612 int Ns; 613 for (Ns = 0; Ns < Nsecfilt; Ns++) { 614 fprintf (stderr, "secf: %08x\n", secfilt[Ns].flags); 615 } 616 return 1; 617 } 618 354 619 /* set measure.Mcal for all measures except ID_MEAS_NOCAL and ID_IMAGE_PHOTOM_NOCAL */ 355 int setMcalOutput (Catalog *catalog, int Ncatalog ) {620 int setMcalOutput (Catalog *catalog, int Ncatalog, FlatCorrectionTable *flatcorr) { 356 621 357 622 int i; … … 368 633 for (k = 0; k < catalog[i].averageT[j].Nmeasure; k++, m++) { 369 634 if (catalog[i].measureT[m].dbFlags & MEAS_BAD) continue; 370 Mcal = getMcal (m, i );635 Mcal = getMcal (m, i, flatcorr, catalog); 371 636 if (isnan(Mcal)) continue; 372 637 Mmos = getMmos (m, i); … … 375 640 if (isnan(Mgrid)) continue; 376 641 642 // note that measurements for which the image is not selected will not be modified 643 // (that is a good thing! -- we keep a prior calibration) 644 377 645 // set the output calibration 378 646 catalog[i].measure[m].Mcal = Mcal + Mmos + Mgrid; 647 648 if (catalog[i].measureT[m].dbFlags & ID_MEAS_PHOTOM_UBERCAL) { 649 myAssert (isfinite(catalog[i].measure[m].Mcal), "oops, broke an ubercal mag"); 650 } 379 651 } 380 652 } … … 385 657 void clean_stars (Catalog *catalog, int Ncatalog) { 386 658 387 int i, j, Ndel, Nave, Ntot, mark, Ns ;659 int i, j, Ndel, Nave, Ntot, mark, Ns, Nscat, Nchi, Nnan; 388 660 float dM, Xm; 389 661 double Chisq, MaxScatter, MaxChisq; 390 662 double *xlist, *slist, *dlist; 663 391 664 StatType stats; 665 liststats_setmode (&stats, "MEAN"); 392 666 393 667 if (VERBOSE) fprintf (stderr, "marking poor stars\n"); … … 404 678 405 679 // eliminate bad stars using the stats for a single secfilt at a time 406 // XXX DEP replace average.flags with secfilt flags407 680 for (Ns = 0; Ns < Nphotcodes; Ns ++) { 408 681 … … 423 696 } 424 697 425 initstats ("MEAN"); 426 liststats (xlist, dlist, Ntot, &stats); 698 liststats (xlist, dlist, NULL, Ntot, &stats); 427 699 MaxChisq = MAX (STAR_CHISQ, 2*stats.median); 428 liststats (slist, dlist, Ntot, &stats); 700 701 liststats (slist, dlist, NULL, Ntot, &stats); 429 702 MaxScatter = MAX (STAR_SCATTER, 2*stats.median); 430 703 fprintf (stderr, "Max Scatter: %f, Max Chisq: %f\n", MaxScatter, MaxChisq); 431 704 432 Ndel = Nave = 0;705 Ndel = Nave = Nscat = Nnan = Nchi = 0; 433 706 for (i = 0; i < Ncatalog; i++) { 434 707 for (j = 0; j < catalog[i].Naverage; j++) { … … 440 713 catalog[i].secfilt[Nsecfilt*j+Nsec].flags |= ID_STAR_POOR; 441 714 Ndel ++; 715 if (dM > MaxScatter) { Nscat ++; } 716 if (Xm == NAN_S_SHORT) { Nnan ++; } 717 if (Chisq > MaxChisq) { Nchi ++; } 442 718 } else { 443 719 catalog[i].secfilt[Nsecfilt*j+Nsec].flags &= ~ID_STAR_POOR; … … 446 722 } 447 723 } 448 fprintf (stderr, "%d stars marked variable, %d total\n", Ndel, Nave); 449 initstats (STATMODE); 724 fprintf (stderr, "%d stars marked variable (%d scat, %d nan, %d chi), %d total\n", Ndel, Nscat, Nnan, Nchi, Nave); 450 725 } 451 726 free (xlist); … … 454 729 } 455 730 731 // clean_measures examines the stats for a single star. It measures the INNER 50% mean 732 // and sigma, it then re-measures the mean and sigma using all stars with NSIGMA_CLIP (3) 733 // sigma of the INNER 50% mean. it then flags any measurements which are more than 734 // NSIGMA_REJECT (5) sigma of the mean 735 456 736 # define NSIGMA_CLIP 3.0 457 737 # define NSIGMA_REJECT 5.0 458 void clean_measures (Catalog *catalog, int Ncatalog, int final ) {738 void clean_measures (Catalog *catalog, int Ncatalog, int final, FlatCorrectionTable *flatcorr) { 459 739 460 740 off_t j, k, m, Nmax, Ndel, Nave; … … 463 743 double *tlist, *list, *dlist; 464 744 float Msys, Mcal, Mmos, Mgrid; 465 StatType stats;466 745 int Ncal, Nmos, Ngrid, Nfew; 467 746 … … 484 763 TOOFEW = MAX (5, STAR_TOOFEW); 485 764 765 // stats structures for inner and full stats 766 StatType instats, stats; 767 liststats_setmode (&instats, "INNER_MEAN"); 768 liststats_setmode (&stats, "MEAN"); 769 486 770 Ndel = Nave = 0; 487 771 Ncal = Nmos = Ngrid = Nfew = 0; … … 492 776 for (Ns = 0; Ns < Nphotcodes; Ns++) { 493 777 494 /* on final processing, skip stars already measured */495 if (final && catalog[i].found[j]) continue;496 497 778 int thisCode = photcodes[Ns][0].code; 498 779 int Nsec = GetPhotcodeNsec(thisCode); 499 780 781 /* on final processing, skip stars already measured */ 782 if (final && catalog[i].found[Nsecfilt*j + Nsec]) continue; 783 500 784 /* skip bad stars to prevent them from becoming good (on inner sample) */ 501 785 if (catalog[i].secfilt[Nsecfilt*j+Nsec].flags & STAR_BAD) continue; … … 509 793 if (ecode != thisCode) { continue; } 510 794 511 / * if (catalog[i].measureT[m].dbFlags & MEAS_BAD) continue; */512 Mcal = getMcal (m, i );795 // NOTE: we do not skip MEAS_BAD because this measurement is just an internal assessment of the outliers 796 Mcal = getMcal (m, i, flatcorr, catalog); 513 797 if (isnan(Mcal)) { Ncal ++; continue; } 514 798 Mmos = getMmos (m, i); … … 522 806 N++; 523 807 } 524 if (N <= TOOFEW) { Nfew ++; continue; } 808 if (N <= TOOFEW) { 809 Nfew ++; 810 continue; 811 } 525 812 526 813 /* 3-sigma clip based on stats of inner 50% */ 527 814 528 815 // calculated mean of inner 50% 529 initstats ("INNER_MEAN"); 530 liststats (list, dlist, N, &stats); 531 stats.sigma = MAX (MIN_ERROR, stats.sigma); /* if measurements agree too well, sigma -> 0.0 */ 816 liststats (list, dlist, NULL, N, &instats); 817 instats.sigma = MAX (MIN_ERROR, instats.sigma); /* if measurements agree too well, sigma -> 0.0 */ 532 818 533 819 // ignore entries > 3sigma from inner mean 534 820 for (k = m = 0; k < N; k++) { 535 if (fabs (list[k] - stats.median) < NSIGMA_CLIP*stats.sigma) {821 if (fabs (list[k] - instats.median) < NSIGMA_CLIP*instats.sigma) { 536 822 list[m] = list[k]; 537 823 m++; … … 539 825 } 540 826 // recalculate the mean & sigma of the accepted measurements 541 initstats ("MEAN"); 542 liststats (list, dlist, m, &stats); 827 liststats (list, dlist, NULL, m, &stats); 543 828 stats.sigma = MAX (MIN_ERROR, stats.sigma); 544 829 … … 553 838 if (ecode != thisCode) { continue; } 554 839 555 / * if (catalog[i].measureT[m].dbFlags & MEAS_BAD) continue; */556 Mcal = getMcal (m, i );840 // NOTE: we do not skip MEAS_BAD because this measurement is just an internal assessment of the outliers 841 Mcal = getMcal (m, i, flatcorr, catalog); 557 842 if (isnan(Mcal)) continue; 558 843 Mmos = getMmos (m, i); … … 572 857 /* mark bad measures (> 3 sigma deviant) */ 573 858 for (k = 0; k < N; k++) { 574 if (fabs (list[k] - stats.median) > NSIGMA_REJECT*stats.sigma) { 859 // treat the scatter of the star as a systematic term. this is a bit of an 860 // over-estimage (a perfect Gauss distribution with perfect errors would have 861 // mySigma = sqrt(2) too large) 862 float mySigma = hypot (stats.sigma, dlist[k]); 863 if (fabs (list[k] - stats.median) > NSIGMA_REJECT*mySigma) { 575 864 catalog[i].measureT[ilist[k]].dbFlags |= ID_MEAS_POOR_PHOTOM; 576 865 if (final) { … … 585 874 } 586 875 } 587 initstats (STATMODE);588 876 if (VERBOSE) fprintf (stderr, OFF_T_FMT" measures marked poor, "OFF_T_FMT" total\n", Ndel, Nave); 877 589 878 free (list); 590 879 free (dlist); … … 593 882 } 594 883 595 StatType statsStarN (Catalog *catalog, int Ncatalog, int Nsec, int seccode ) {884 StatType statsStarN (Catalog *catalog, int Ncatalog, int Nsec, int seccode, FlatCorrectionTable *flatcorr) { 596 885 597 886 off_t j, k, m, Ntot; … … 625 914 int ecode = GetPhotcodeEquivCodebyCode (catalog[i].measureT[m].photcode); 626 915 if (ecode != seccode) { continue;} 627 Mcal = getMcal (m, i );916 Mcal = getMcal (m, i, flatcorr, catalog); 628 917 if (isnan(Mcal)) { continue;} 629 918 Mmos = getMmos (m, i); … … 640 929 } 641 930 642 // fprintf (stderr, "N1: %d, N2: %d, N3: %d, N4: %d, N0: %d\n", N1, N2, N3, N4, N0); 643 liststats (list, dlist, n, &stats); 931 liststats_setmode (&stats, "MEAN"); 932 933 liststats (list, dlist, NULL, n, &stats); 644 934 free (list); 645 935 free (dlist); … … 680 970 } 681 971 682 liststats (list, dlist, n, &stats); 972 liststats_setmode (&stats, "MEAN"); 973 974 liststats (list, dlist, NULL, n, &stats); 683 975 free (list); 684 976 free (dlist); … … 712 1004 713 1005 dM = catalog[i].secfilt[Nsecfilt*j+Nsec].dM; 1006 if (isnan(dM)) continue; 714 1007 list[n] = dM; 715 1008 dlist[n] = 1; … … 718 1011 } 719 1012 720 liststats (list, dlist, n, &stats); 1013 liststats_setmode (&stats, "MEAN"); 1014 1015 liststats (list, dlist, NULL, n, &stats); 721 1016 free (list); 722 1017 free (dlist);
Note:
See TracChangeset
for help on using the changeset viewer.
