Changeset 41817 for branches/eam_branches/ipp-dev-20210817/psModules
- Timestamp:
- Sep 27, 2021, 11:11:33 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-dev-20210817/psModules/src/detrend/pmPattern.c
r41811 r41817 137 137 138 138 // Comparison and swap functions for sorting values directly 139 #define SORT_COMPARE(A,B) ( value[A] < value[B])140 #define SORT_SWAP( A,B) {\139 #define SORT_COMPARE(A,B) (sampleArray[A] < sampleArray[B]) 140 #define SORT_SWAP(TYPE,A,B) { \ 141 141 if (A != B) { \ 142 float temp = value[A];\143 value[A] = value[B]; \144 value[B] = temp; \142 TYPE temp = sampleArray[A]; \ 143 sampleArray[A] = sampleArray[B]; \ 144 sampleArray[B] = temp; \ 145 145 } \ 146 146 } … … 150 150 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 151 151 152 bool pmPatternRowUnbinned(pmReadout *ro, int order, int iter, float rej, float thresh, 153 psStatsOptions clipMean, psStatsOptions clipStdev, 154 psImageMaskType maskVal, psImageMaskType maskBad); 155 156 157 bool pmPatternRowBinned(pmReadout *ro, int order, int iter, float rej, float thresh, 158 psStatsOptions clipMean, psStatsOptions clipStdev, 159 psImageMaskType maskVal, psImageMaskType maskBad); 160 161 162 bool pmPatternRow(pmReadout *ro, int order, int iter, float rej, float thresh, 163 psStatsOptions clipMean, psStatsOptions clipStdev, 164 psImageMaskType maskVal, psImageMaskType maskBad) { 165 166 // bool status = pmPatternRowBinned(ro, order, iter, rej, thresh, clipMean, clipStdev, maskVal, maskBad); 167 bool status = pmPatternRowUnbinned(ro, order, iter, rej, thresh, clipMean, clipStdev, maskVal, maskBad); 168 return status; 169 } 170 152 171 // USE_BACKGROUND_STDEV: if true, the analysis will use the measured robust stdev to clip the out-of-range pixles 153 172 // if false, the stdev will be estimated based on the Poisson statistics of the median (sky level). 154 173 # define USE_BACKGROUND_STDEV 0 155 174 156 bool pmPatternRow (pmReadout *ro, int order, int iter, float rej, float thresh,175 bool pmPatternRowUnbinned(pmReadout *ro, int order, int iter, float rej, float thresh, 157 176 psStatsOptions clipMean, psStatsOptions clipStdev, 158 177 psImageMaskType maskVal, psImageMaskType maskBad) … … 233 252 234 253 psStats *clip = psStatsAlloc(clipMean | clipStdev); // Clipping statistics 235 // XXX clip->clipIter = iter; 236 clip->clipIter = 1; // XXX skip iteration for a test 254 clip->clipIter = iter; 237 255 clip->clipSigma = rej; 238 256 psVector *clipMask = psVectorAlloc(numCols, PS_TYPE_VECTOR_MASK); // Mask for clipping … … 440 458 } 441 459 442 // bin by Npix in the x-direction to reduce the number of calculations needed to measure 460 # define NPIX 31 461 462 // bin by NPIX in the x-direction to reduce the number of calculations needed to measure 443 463 // the pattern 444 464 bool pmPatternRowBinned(pmReadout *ro, int order, int iter, float rej, float thresh, … … 474 494 } 475 495 496 // if USE_BACKGROUND_STDEV is TRUE, the observed standard deviation is used to set the 497 // thresholds. this is going to be an overestimate if there is any structure in the 498 // image. If FALSE, the thresholds are set based on poisson stats for the background 499 // level. We assume the gain is 1, so this is an overestimate if the gain is > 1 500 476 501 # if (USE_BACKGROUND_STDEV) 477 502 float lower = stats->robustMedian - thresh * stats->robustStdev; // Lower bound for data … … 497 522 # define READNOISE 10 498 523 float sigma = sqrt(stats->robustMedian + PS_SQR(READNOISE)); 499 float lower = stats->robustMedian - thresh * sigma; // Lower bound for data 500 float upper = stats->robustMedian + thresh * sigma; // Upper bound for data 524 float delta = PS_MIN (thresh * sigma, 40); 525 float lower = stats->robustMedian - delta; // Lower bound for data 526 float upper = stats->robustMedian + delta; // Upper bound for data 501 527 float background = stats->robustMedian; 502 528 # endif … … 513 539 psFree(rng); 514 540 515 # define NPIX 15 516 517 // Indices are distributed [-1:1] [-1 = 0, +1 = numCols = indices[nSamples] 541 // the vector 'indices' maps the x-coordinate to a range [-1:1]. the element number (i) of indices 542 // related to the x-coordinate (column number) by x = (i + 0.5) * NPIX 543 518 544 int nSamples = numCols / NPIX; 519 psVector *indices = psVectorAlloc(nSamples, PS_TYPE_F32); // Indices for fitting 520 psVector *fitData = psVectorAlloc(nSAmples, PS_TYPE_F32); // Data to fit 521 522 // indices elements run from 0 - nSamples, element 'sample' corresponds to the middle of the bin sample*NPIX + 0.5*NPIX 545 546 psVector *indices = psVectorAlloc(numCols, PS_TYPE_F32); // Indices for fit solutions 547 psVector *xFit = psVectorAlloc(nSamples, PS_TYPE_F32); // x-coordinate for fitting 548 psVector *yFit = psVectorAlloc(nSamples, PS_TYPE_F32); // flux values for fitting 549 550 // xFit elements run from 0 - nSamples, element 'sample' corresponds to the middle of the bin sample*NPIX + 0.5*NPIX 523 551 524 552 float norm = 2.0 / (float)numCols; // Normalisation for indices 525 553 for (int sample = 0; sample < nSamples; sample ++) { 526 554 int x = (sample + 0.5)*NPIX; 527 indices->data.F32[sample] = x * norm - 1.0; 555 xFit->data.F32[sample] = x * norm - 1.0; 556 } 557 for (int x = 0; x < numCols; x ++) { 558 indices->data.F32[x] = x * norm - 1.0; 528 559 } 529 560 530 561 psStats *clip = psStatsAlloc(clipMean | clipStdev); // Clipping statistics 531 // XXX clip->clipIter = iter; 532 clip->clipIter = 1; // XXX skip iteration for a test 562 clip->clipIter = iter; 533 563 clip->clipSigma = rej; 534 psVector *clipMask = psVectorAlloc(n umCols, PS_TYPE_VECTOR_MASK); // Mask for clipping564 psVector *clipMask = psVectorAlloc(nSamples, PS_TYPE_VECTOR_MASK); // Mask for clipping 535 565 psPolynomial1D *poly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, order); // Polynomial to fit 536 566 psVector *data = psVectorAlloc(numCols, PS_TYPE_F32); // Data to fit … … 539 569 psImageInit(corr, NAN); 540 570 541 #ifdef PATTERN_ROW_BKG_FIX542 571 // CZW: 2011-11-30 543 572 // Define the vectors to hold the "x" and "y" slope trends. … … 556 585 psVector *xaxisData = psVectorAlloc(numRows, PS_TYPE_F32); // Data to fit to the linear term 557 586 psVectorInit(yaxisMask, 0); 558 #endif 559 560 // we really need more than order + 1 points (= 4). 587 588 // validNmin is the minimum number of samples needed to measure the trend. 561 589 // this should be tunable, but let's try 5 - 10% 562 int validNmin = numCols * 0.1;590 int validNmin = PS_MAX (nSamples * 0.1, order + 2); 563 591 564 592 for (int y = 0; y < numRows; y++) { … … 572 600 float validXmax = -1; 573 601 574 // XXX bookkeeping might be easier if this loop is over elements of 'indices'575 // XXX can we do just as well fitting 1/3 of the pixels? (NOT REALLY)576 // (x % 3) ||577 602 for (int sample = 0; sample < nSamples; sample ++) { 578 603 579 // store valid samples in the array 604 // store valid samples in the array to be sorted 580 605 float sampleArray[NPIX]; 581 606 int seq = 0; 582 607 for (int j = 0; j < NPIX; j++) { 583 int pix = sample * NPIX + j; 608 int pix = sample * NPIX + j; // real pixel elements in x-dir 584 609 if ((mask && mask->data.PS_TYPE_IMAGE_MASK_DATA[y][pix] & maskVal)) continue; 585 610 if (data->data.F32[pix] < lower || data->data.F32[pix] > upper) continue; 586 sampleArray[seq] = data->data.F32[pix]; 611 sampleArray[seq] = data->data.F32[pix]; // store the value to be sorted 587 612 seq ++; 588 613 } 589 614 if (seq < 1) { 590 615 clipMask->data.PS_TYPE_VECTOR_MASK_DATA[sample] = 0xFF; 591 } else { 592 clipMask->data.PS_TYPE_VECTOR_MASK_DATA[sample] = 0; 593 num++; 594 validXmin = PS_MIN(indices->data.F32[sample], validXmin); 595 validXmax = PS_MAX(indices->data.F32[sample], validXmax); 596 } 597 598 PSSORT (seq, sampleArray 599 600 } 601 602 // XXX how much time is spent in the fitting 616 yFit->data.F32[sample] = NAN; 617 continue; 618 } 619 // note that we are treating the x-coordinate as the center 620 // of the binned pixel group, even if some or most pixels have 621 // been masked. compared to the amplitude of the slope, this 622 // error is small 623 clipMask->data.PS_TYPE_VECTOR_MASK_DATA[sample] = 0; 624 validXmin = PS_MIN(xFit->data.F32[sample], validXmin); 625 validXmax = PS_MAX(xFit->data.F32[sample], validXmax); 626 num++; 627 628 // PSSORT operates on sampleArray (see define of macro SORT_SWAP above) 629 PSSORT (seq, SORT_COMPARE, SORT_SWAP, float); 630 631 int midPt = 0.5 * seq; 632 float medValue = (seq % 2) ? sampleArray[midPt] : 0.5*(sampleArray[midPt] + sampleArray[midPt-1]); 633 yFit->data.F32[sample] = medValue; 634 } 635 636 // XXX how much time is spent in the fitting? to test: make this always true 603 637 if (num < validNmin) { 604 638 // Not enough points to fit … … 609 643 } 610 644 // XXX does this need to be a clipped fit if we are clipping based on the median poisson noise? 611 if (!psVectorClipFitPolynomial1D(poly, clip, clipMask, 0xFF, data, NULL, indices)) {645 if (!psVectorClipFitPolynomial1D(poly, clip, clipMask, 0xFF, yFit, NULL, xFit)) { 612 646 psWarning("Unable to fit polynomial to row %d", y); 613 647 psErrorClear(); … … 628 662 psErrorClear(); 629 663 patternMaskRow(ro, y, maskBad); 630 #ifdef PATTERN_ROW_BKG_FIX631 664 yaxisMask->data.PS_TYPE_VECTOR_MASK_DATA[y] = 0xFF; 632 #endif633 665 continue; 634 666 } … … 641 673 } 642 674 643 #ifdef PATTERN_ROW_BKG_FIX644 675 // Put the global trends back that were removed by the PATTERN.ROW correction. 645 676 // Set up the indices for the polynomial … … 665 696 corr->data.F64[y][0] -= background; 666 697 } 667 } 668 else { 698 } else { 669 699 psVector *solution = psPolynomial1DEvalVector(yaxisPoly,yaxisIndices); 670 700 if (!solution) { … … 679 709 corr->data.F64[y][0] -= background; 680 710 } 681 } 682 else { 711 } else { 683 712 for (int y = 0; y < numRows; y++) { 684 713 for (int x = 0; x < numCols; x++) { … … 699 728 psWarning("Unable to fit polynomial to x-axis trend"); 700 729 psErrorClear(); 701 } 702 else { 730 } else { 703 731 psVector *solution = psPolynomial1DEvalVector(xaxisPoly,yaxisIndices); 704 732 if (!solution) { 705 733 psWarning("Unable to evaluate polynomial"); 706 734 psErrorClear(); 707 } 708 else { 735 } else { 709 736 for (int y = 0; y < numRows; y++) { 710 737 for (int x = 0; x < numCols; x++) { … … 723 750 psFree(yaxisData); 724 751 psFree(xaxisData); 725 // End PATTERN_ROW_BKG_FIX global trend replacement726 #endif727 752 728 753 psMetadataAddImage(ro->analysis, PS_LIST_TAIL, PM_PATTERN_ROW_CORRECTION, PS_META_REPLACE, … … 731 756 732 757 psFree(indices); 758 psFree(xFit); 759 psFree(yFit); 733 760 psFree(clip); 734 761 psFree(clipMask);
Note:
See TracChangeset
for help on using the changeset viewer.
