Changeset 41625 for branches/eam_branches/relphot.20210521/src/StarOps.c
- Timestamp:
- May 31, 2021, 11:45:18 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/relphot.20210521/src/StarOps.c
r41624 r41625 1 1 # include "relphot.h" 2 3 # define STAR_BAD (ID_SECF_STAR_FEW | ID_SECF_STAR_POOR) 2 4 3 5 enum {THREAD_RUN, THREAD_DONE}; … … 290 292 291 293 // setMrel and setMrelOutput are extremely similar, but have slightly different implications: 294 // * both call setMrelCatalog, but setMrel set isSetMrelFinal to FALSE 292 295 // * setMrel only uses the internal Tiny structures 293 // * setMrel skips stars for which there are too few good measurements (setMrelOutput assigns an average mag with only 1) 296 // * setMrel skips stars for which there are too few good measurements 297 // -> (setMrelOutput assigns an average mag for all objects, even those with only 1 measurement) 294 298 // * setMrelOutput sets psfQF, psfQFperf, extNsigma, rank info, etc 295 299 // * setMrelOutput sets average Map 296 300 // * setMrelOutput updates 2MASS average flags 297 301 // * setMrelOutput updates average EXT flags (PS1 and 2MASS) 298 // * setMrelOutput sets average stack & warp photometry (if requested) 302 // * setMrelOutput sets average stack & warp photometry (if requested), setMrel always skips those 303 // * setMrelOutput is NOT threaded it reads/writes catalogs one at a time 299 304 300 305 int setMrel (Catalog *catalog, int Ncatalog) { … … 325 330 } 326 331 327 // setMrelOutput is NOT threaded because we read/write catalogs one at a time (for now)328 332 int setMrelOutput (Catalog *catalog, int Ncatalog) { 329 333 … … 443 447 } 444 448 445 # define SKIP_THIS_MEAS(REASON) { \446 catalog[Nc].measureT[m].dbFlags |= ID_MEAS_SKIP_PHOTOM; \447 if (catalog[Nc].measure) { \448 catalog[Nc].measure [m].dbFlags |= ID_MEAS_SKIP_PHOTOM; \449 } \450 results->REASON ++; \451 continue; }452 453 454 449 int print_measure_set (Average *average, SecFilt *secfilt, Measure *measure) { 455 450 … … 471 466 } 472 467 473 /* set measure.Mcal for all measures except ID_MEAS_NOCAL and ID_IMAGE_PHOTOM_NOCAL*/468 /* set measure.Mcal for all measures except ID_MEAS_NOCAL */ 474 469 int setMcalOutput (Catalog *catalog, int Ncatalog) { 475 470 … … 477 472 off_t j, k, m; 478 473 479 MEAS_BAD = ID_MEAS_NOCAL;480 IMAGE_BAD = ID_IMAGE_PHOTOM_NOCAL;481 482 474 for (i = 0; i < Ncatalog; i++) { 483 475 for (j = 0; j < catalog[i].Naverage; j++) { … … 485 477 m = catalog[i].averageT[j].measureOffset; 486 478 for (k = 0; k < catalog[i].averageT[j].Nmeasure; k++, m++) { 487 if (catalog[i].measureT[m].dbFlags & MEAS_BAD) continue;479 if (catalog[i].measureT[m].dbFlags & ID_MEAS_NOCAL) continue; 488 480 float McalPSF = getMcal (m, i, MAG_CLASS_PSF); 489 481 float McalAPER = getMcal (m, i, MAG_CLASS_APER); 490 482 if (isnan(McalPSF)) continue; 491 float Mmos = getMmos (m, i); 492 if (isnan(Mmos)) continue; 493 float Mgrp = getMgrp (m, i, catalog[i].measureT[m].airmass, NULL); 494 if (isnan(Mgrp)) continue; 495 float Mgrid = getMgridTiny (&catalog[i].measureT[m]); 496 if (isnan(Mgrid)) continue; 483 484 // Mmos, Mgrp have already been transfered to Mcal and should be zero here 485 // float Mmos = getMmos (m, i); 486 // if (isnan(Mmos)) continue; 487 // float Mgrp = getMgrp (m, i, catalog[i].measureT[m].airmass, NULL); 488 // if (isnan(Mgrp)) continue; 489 490 // Mgrid is applied to Mflat and should be ignored here 491 // float Mgrid = getMgridTiny (&catalog[i].measureT[m]); 492 // if (isnan(Mgrid)) continue; 497 493 498 494 // Note that this operation is setting measure->McalAPER to image->McalAPER only … … 507 503 508 504 // set the output calibration 509 // float Moff = Mmos + Mgrp + Mgrid; 510 float Moff = Mmos + Mgrid; // Mgrp has already been applied to the image.Mcal 511 catalog[i].measure[m].McalPSF = McalPSF + Moff; 512 catalog[i].measure[m].McalAPER = useStackAper ? McalAPER + Moff : McalPSF + Moff; 505 catalog[i].measure[m].McalPSF = McalPSF; 506 catalog[i].measure[m].McalAPER = useStackAper ? McalAPER : McalPSF; 513 507 514 508 if (catalog[i].measureT[m].dbFlags & ID_MEAS_PHOTOM_UBERCAL) { … … 612 606 for (i = Ntot = 0; i < Ncatalog; i++) { 613 607 for (j = 0; j < catalog[i].Naverage; j++) { 614 if ( catalog[i].secfilt[Nsecfilt*j+Nsec].flags & STAR_BAD) continue;608 if (catalog[i].secfilt[Nsecfilt*j+Nsec].flags & STAR_BAD) continue; 615 609 float Mchisq = catalog[i].secfilt[Nsecfilt*j+Nsec].Mchisq; 616 610 if (isnan(Mchisq)) continue; … … 621 615 } 622 616 } 623 617 618 // XXX the limits for MaxChisq and MaxScatter should be 619 // user-defined. This uses 624 620 liststats (xlist, dlist, NULL, Ntot, &stats); 625 MaxChisq = MAX (STAR_CHISQ, 2*stats.median); 621 float ChiSqUpper90 = stats.Upper90; 622 MaxChisq = MAX (STAR_CHISQ, ChiSqUpper90); 626 623 627 624 liststats (slist, dlist, NULL, Ntot, &stats); 628 MaxScatter = MAX (STAR_SCATTER, 2*stats.median); 625 float ScatterUpper90 = stats.Upper90; 626 MaxScatter = MAX (STAR_SCATTER, ScatterUpper90); 629 627 fprintf (stderr, "Max Scatter: %f, Max Chisq: %f\n", MaxScatter, MaxChisq); 630 628 … … 636 634 mark = (dM > MaxScatter) || (isnan(Mchisq)) || (Mchisq > MaxChisq); 637 635 if (mark) { 638 catalog[i].secfilt[Nsecfilt*j+Nsec].flags |= ID_ OBJ_POOR;636 catalog[i].secfilt[Nsecfilt*j+Nsec].flags |= ID_SECF_STAR_POOR; 639 637 Ndel ++; 640 638 if (dM > MaxScatter) { Nscat ++; } … … 642 640 if (Mchisq > MaxChisq) { Nchi ++; } 643 641 } else { 644 catalog[i].secfilt[Nsecfilt*j+Nsec].flags &= ~ID_ OBJ_POOR;642 catalog[i].secfilt[Nsecfilt*j+Nsec].flags &= ~ID_SECF_STAR_POOR; 645 643 } 646 644 Nave ++; … … 652 650 free (slist); 653 651 free (dlist); 654 }655 656 // clean_measures examines the stats for a single star. It measures the INNER 50% mean657 // and sigma, it then re-measures the mean and sigma using all stars with NSIGMA_CLIP (3)658 // sigma of the INNER 50% mean. it then flags any measurements which are more than659 // NSIGMA_REJECT (5) sigma of the mean660 661 // this function only operations on the PSF magnitudes662 663 // XXX EAM clean_measures is no longer used -- we rely on IRLS to down-weight outliers664 665 # define NSIGMA_CLIP 3.0666 # define NSIGMA_REJECT 5.0667 void clean_measures (Catalog *catalog, int Ncatalog, int final) {668 669 off_t j, k, m, Nmax, Ndel, Nave;670 int i, N, image_bad, TOOFEW;671 off_t *ilist;672 double *tlist, *list, *dlist;673 float Msys, Mcal, Mmos, Mgrp, Mgrid;674 int Ncal, Nmos, Ngrp, Ngrid, Nfew;675 676 int Nsecfilt = GetPhotcodeNsecfilt ();677 678 if (VERBOSE) fprintf (stderr, "marking poor measures\n");679 /* Nmeasure is now different, need to reallocate */680 Nmax = 0;681 for (i = 0; i < Ncatalog; i++) {682 for (j = 0; j < catalog[i].Naverage; j++) {683 Nmax = MAX (Nmax, catalog[i].averageT[j].Nmeasure);684 }685 }686 ALLOCATE (list, double, MAX (1, Nmax));687 ALLOCATE (dlist, double, MAX (1, Nmax));688 ALLOCATE (ilist, off_t, Nmax);689 ALLOCATE (tlist, double, Nmax);690 691 /* it makes no sense to mark 3-sigma outliers with <5 measurements */692 TOOFEW = MAX (5, STAR_TOOFEW);693 694 // stats structures for inner and full stats695 StatType instats, stats;696 liststats_setmode (&instats, "INNER_MEAN");697 liststats_setmode (&stats, "MEAN");698 699 Ndel = Nave = 0;700 Ncal = Nmos = Ngrp = Ngrid = Nfew = 0;701 for (i = 0; i < Ncatalog; i++) {702 for (j = 0; j < catalog[i].Naverage; j++) {703 704 int Ns;705 for (Ns = 0; Ns < Nphotcodes; Ns++) {706 707 int thisCode = photcodes[Ns][0].code;708 int Nsec = GetPhotcodeNsec(thisCode);709 710 /* on final processing, skip stars already measured */711 if (final && catalog[i].found_t[Nsecfilt*j + Nsec]) continue;712 713 /* skip bad stars to prevent them from becoming good (on inner sample) */714 if (catalog[i].secfilt[Nsecfilt*j+Nsec].flags & STAR_BAD) continue;715 716 /* accumulate list of valid measurements */717 m = catalog[i].averageT[j].measureOffset;718 N = 0;719 for (k = 0; k < catalog[i].averageT[j].Nmeasure; k++, m++) {720 // skip measurements that do not match the current photcode721 int ecode = GetPhotcodeEquivCodebyCode (catalog[i].measureT[m].photcode);722 if (ecode != thisCode) { continue; }723 724 // SKIP gpc1 stack data725 if (isGPC1stack(catalog[i].measureT[m].photcode)) continue;726 727 // SKIP gpc1 forced-warp data728 if (isGPC1warp(catalog[i].measureT[m].photcode)) continue;729 730 // NOTE: we do not skip MEAS_BAD because this measurement is just an internal assessment of the outliers731 Mcal = getMcal (m, i, MAG_CLASS_PSF);732 if (isnan(Mcal)) { Ncal ++; continue; }733 Mmos = getMmos (m, i);734 if (isnan(Mmos)) { Nmos ++; continue; }735 Mgrp = getMgrp (m, i, catalog[i].measureT[m].airmass, NULL);736 if (isnan(Mgrp)) { Ngrp ++; continue; }737 Mgrid = getMgridTiny (&catalog[i].measureT[m]);738 if (isnan(Mgrid)) { Ngrid ++; continue; }739 740 Msys = PhotSysTiny (&catalog[i].measureT[m], &catalog[i].averageT[j], &catalog[i].secfilt[j*Nsecfilt], MAG_CLASS_PSF);741 list[N] = Msys - Mcal - Mmos - Mgrp - Mgrid;742 dlist[N] = MAX (catalog[i].measureT[m].dM, MIN_ERROR);743 N++;744 }745 if (N <= TOOFEW) {746 Nfew ++;747 continue;748 }749 750 /* 3-sigma clip based on stats of inner 50% */751 752 // calculated mean of inner 50%753 liststats (list, dlist, NULL, N, &instats);754 instats.sigma = MAX (MIN_ERROR, instats.sigma); /* if measurements agree too well, sigma -> 0.0 */755 756 // ignore entries > 3sigma from inner mean757 for (k = m = 0; k < N; k++) {758 if (fabs (list[k] - instats.median) < NSIGMA_CLIP*instats.sigma) {759 list[m] = list[k];760 m++;761 }762 }763 // recalculate the mean & sigma of the accepted measurements764 liststats (list, dlist, NULL, m, &stats);765 stats.sigma = MAX (MIN_ERROR, stats.sigma);766 767 /* apply to list of all relevant measurements, including IMAGE_POOR & IMAGE_FEW */768 image_bad = IMAGE_BAD;769 IMAGE_BAD = ID_IMAGE_PHOTOM_NOCAL;770 m = catalog[i].averageT[j].measureOffset;771 N = 0;772 for (k = 0; k < catalog[i].averageT[j].Nmeasure; k++, m++) {773 // skip measurements that do not match the current photcode774 int ecode = GetPhotcodeEquivCodebyCode (catalog[i].measureT[m].photcode);775 if (ecode != thisCode) { continue; }776 777 // SKIP gpc1 stack data778 if (isGPC1stack(catalog[i].measureT[m].photcode)) continue;779 780 // SKIP gpc1 forced-warp data781 if (isGPC1warp(catalog[i].measureT[m].photcode)) continue;782 783 // NOTE: we do not skip MEAS_BAD because this measurement is just an internal assessment of the outliers784 Mcal = getMcal (m, i, MAG_CLASS_PSF);785 if (isnan(Mcal)) continue;786 Mmos = getMmos (m, i);787 if (isnan(Mmos)) continue;788 Mgrid = getMgridTiny (&catalog[i].measureT[m]);789 if (isnan(Mgrid)) continue;790 791 Msys = PhotSysTiny (&catalog[i].measureT[m], &catalog[i].averageT[j], &catalog[i].secfilt[j*Nsecfilt], MAG_CLASS_PSF);792 list[N] = Msys - Mcal - Mmos - Mgrid;793 dlist[N] = MAX (catalog[i].measureT[m].dM, MIN_ERROR);794 ilist[N] = m;795 N++;796 Nave ++;797 }798 if (N < TOOFEW) continue;799 800 /* mark bad measures (> 5 sigma deviant) */801 for (k = 0; k < N; k++) {802 // treat the scatter of the star as a systematic term. this is a bit of an803 // over-estimage (a perfect Gauss distribution with perfect errors would have804 // mySigma = sqrt(2) too large)805 float mySigma = hypot (stats.sigma, dlist[k]);806 if (fabs (list[k] - stats.median) > NSIGMA_REJECT*mySigma) {807 catalog[i].measureT[ilist[k]].dbFlags |= ID_MEAS_POOR_PHOTOM;808 if (final) {809 // for the final pass, we have a duplicate set of values in measure and measureT810 catalog[i].measure[ilist[k]].dbFlags |= ID_MEAS_POOR_PHOTOM;811 }812 Ndel ++;813 } else {814 catalog[i].measureT[ilist[k]].dbFlags &= ~ID_MEAS_POOR_PHOTOM;815 if (final) {816 // for the final pass, we have a duplicate set of values in measure and measureT817 catalog[i].measure[ilist[k]].dbFlags &= ~ID_MEAS_POOR_PHOTOM;818 }819 }820 }821 IMAGE_BAD = image_bad;822 }823 }824 }825 if (VERBOSE) fprintf (stderr, OFF_T_FMT" measures marked poor, "OFF_T_FMT" total\n", Ndel, Nave);826 827 free (list);828 free (dlist);829 free (ilist);830 free (tlist);831 652 } 832 653
Note:
See TracChangeset
for help on using the changeset viewer.
