Changeset 42653
- Timestamp:
- Apr 12, 2024, 2:49:40 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/psModules.20240412/src/detrend/pmOverscan.c
r42379 r42653 222 222 } 223 223 224 static int saveVectors = 1; 225 224 226 bool pmOverscanSubtract (pmReadout *input, pmOverscanOptions *overscanOpts) { 225 227 … … 339 341 // We are performing a row-by-row overscan subtraction 340 342 int cellreaddir = psMetadataLookupS32(&mdok, input->parent->concepts, "CELL.READDIR"); // Read direction 341 if ((cellreaddir != 1) && (cellreaddir != 2)) {342 psError(PS_ERR_UNKNOWN, true, "CELL.READDIR must be 1 (rows) or 2 (cols) \n");343 if ((cellreaddir != -1) && (cellreaddir != 1) && (cellreaddir != 2)) { 344 psError(PS_ERR_UNKNOWN, true, "CELL.READDIR must be 1 (rows) or 2 (cols) or 0 (2D)\n"); 343 345 return false; 344 346 } … … 369 371 values = psVectorRealloc(values, values->n + overscan->numCols); 370 372 values->n += overscan->numCols; 373 // XXX double-check the range of values->n here 371 374 memcpy(&values->data.F32[index], overscan->data.F32[j], 372 375 overscan->numCols * PSELEMTYPE_SIZEOF(PS_TYPE_F32)); … … 545 548 } 546 549 550 // 2D bias subtraction with x-dir readout direction: the 551 // bias is constructed by combining a 1D pattern in the 552 // readout direction from the top overscan region and a second 553 // 1D pattern in the cross direction from the overscan 554 if (cellreaddir == -1) { 555 // we require 2 overscan regions, and they must match these directions: 556 if (overscans->n != 2) { 557 psLogMsg (__func__, PS_LOG_ERROR, "CELL.READDIR = -1, requires 2 overscan regions but %d supplied", (int) overscans->n); 558 psLogMsg (__func__, PS_LOG_ERROR, "e.g.: CELL.BIASSEC STR [591:624,1:608],[1:590,598:608]"); 559 psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to generate overscan vector.\n"); 560 psFree(stats); 561 return false; 562 } 563 564 // the serial (fast readout) direction is columns (x-dir) 565 psImage *yscan = psListGet (overscans, 0); // overscan region spanning all rows 566 psImage *xscan = psListGet (overscans, 1); // overscan region spanning all columns 567 568 // Extract the y-dir overscan vector. The overscan and image might not be aligned: 569 // diff represents the offset between the rows in the image data and the overscan. 570 // pixels->data represents the image row pixels. For example, the image region may be 571 // inset in the y-direction but the overscan could cover the entire y-range 572 573 // The read direction is rows 574 psArray *yscanPixels = psArrayAlloc(image->numRows); // Array of vectors containing pixels 575 for (int i = 0; i < yscanPixels->n; i++) { 576 yscanPixels->data[i] = psVectorAlloc(0, PS_TYPE_F32); 577 } 578 579 // XXX this code allows multiple yscans to be appended, but this does not 580 // match the concept of how they are assigned above: biassec[0] = yscan 581 int yDiff = yscan->row0 - image->row0; // Offset between the two regions 582 for (int i = PS_MAX(0,yDiff); i < PS_MIN(image->numRows, yscan->numRows + yDiff); i++) { 583 int j = i - yDiff; 584 // i is row on image, j is row on yscan 585 psVector *values = yscanPixels->data[i]; 586 int index = values->n; // Index in the vector 587 values = psVectorRealloc(values, values->n + yscan->numCols); 588 values->n += yscan->numCols; 589 // XXX double-check the range of values->n here 590 memcpy(&values->data.F32[index], yscan->data.F32[j], 591 yscan->numCols * PSELEMTYPE_SIZEOF(PS_TYPE_F32)); 592 index += yscan->numCols; 593 yscanPixels->data[i] = values; // Update the pointer in case it's moved 594 } 595 596 // Extract the x-dir overscan vector. The overscan and image might not be aligned: 597 // diff represents the offset between the rows in the image data and the overscan. 598 // pixels->data represents the image row pixels. For example, the image region may be 599 // inset in the x-direction but the overscan could cover the entire y-range 600 601 // Extract the top region as a vector of the columns 602 psArray *xscanPixels = psArrayAlloc(image->numCols); // Array of vectors containing pixels 603 for (int i = 0; i < xscanPixels->n; i++) { 604 xscanPixels->data[i] = psVectorAlloc(0, PS_TYPE_F32); 605 } 606 607 int xDiff = xscan->col0 - image->col0; // Offset between the two regions 608 for (int ix = PS_MAX(0,xDiff); ix < PS_MIN(image->numCols, xscan->numCols + xDiff); ix++) { 609 int jx = ix - xDiff; 610 // ix is row on image, jx is column on xscan 611 psVector *values = xscanPixels->data[ix]; 612 values = psVectorRealloc(values, xscan->numRows); 613 values->n = xscan->numRows; 614 for (int iy = 0; iy < xscan->numRows; iy++) { 615 values->data.F32[iy] = xscan->data.F32[iy][jx]; 616 } 617 xscanPixels->data[ix] = values; // Update the pointer in case it's moved 618 } 619 620 // Reduce the overscans 621 // XXX need to save 2 different chi-square values 622 psVector *xReduced = pmOverscanVector(&chi2, overscanOpts, xscanPixels, stats); 623 psFree(xscanPixels); 624 if (!xReduced) { 625 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate x-dir overscan vector.\n"); 626 psFree(stats); 627 return false; 628 } 629 630 // Reduce the overscans 631 // XXX need to save 2 different chi-square values 632 psVector *yReduced = pmOverscanVector(&chi2, overscanOpts, yscanPixels, stats); 633 psFree(yscanPixels); 634 if (!yReduced) { 635 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate y-dir overscan vector.\n"); 636 psFree(stats); 637 return false; 638 } 639 640 641 if (saveVectors) { 642 FILE *foutX = fopen ("xdir.dat", "w"); 643 int fdX = fileno (foutX); 644 p_psVectorPrint (fdX, xReduced, "xscan"); 645 fclose (foutX); 646 FILE *foutY = fopen ("ydir.dat", "w"); 647 int fdY = fileno (foutY); 648 p_psVectorPrint (fdY, yReduced, "yscan"); 649 fclose (foutY); 650 saveVectors = 0; 651 } 652 653 // write info about stats of y-dir overscan vector in header 654 { 655 psString comment = NULL; // Comment to add 656 psStats *vectorStats = psStatsAlloc (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV); 657 if (!psVectorStats (vectorStats, yReduced, NULL, NULL, 0)) { 658 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 659 return false; 660 } 661 psStringAppend(&comment, "Mean Overscan value: %f", vectorStats->sampleMean); 662 psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, comment, ""); 663 psFree(comment); 664 665 // write metadata header value 666 psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_VAL", PS_META_REPLACE, "Overscan mean", vectorStats->sampleMean); 667 psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_SIG", PS_META_REPLACE, "Overscan stdev", vectorStats->sampleStdev); 668 669 // EAM 2022.03.29 : if the calculated overscan value is below the threshold, 670 // declare the readout dead and mask 671 672 if ((vectorStats->sampleMean < overscanOpts->minValid) || (vectorStats->sampleMean > overscanOpts->maxValid)) { 673 fprintf (stderr, "bad overscan (2) %f, masking readout\n", vectorStats->sampleMean); 674 psImage *mask = input->mask; 675 for (int y = 0; y < mask->numRows; y++) { 676 for (int x = 0; x < mask->numCols; x++) { 677 mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= overscanOpts->maskVal; 678 } 679 } 680 } 681 psFree (vectorStats); 682 } 683 684 // XXX apply the 2D bias correction here 685 for (int i = 0; i < image->numRows; i++) { 686 for (int j = 0; j < image->numCols; j++) { 687 image->data.F32[i][j] -= yReduced->data.F32[i]; 688 } 689 } 690 691 // subtract the y-dir vector from the y-dir overscan regions (why?) 692 { 693 // the overscan and image might not be aligned. 694 int diff = yscan->row0 - image->row0; // Offset between the two regions 695 for (int i = PS_MAX(0,diff); i < PS_MIN(image->numRows, yscan->numRows + diff); i++) { 696 int j = i - diff; 697 // i is row on image (aligned with yReduced) 698 // j is row on yscan 699 for (int k = 0; k < yscan->numCols; k++) { 700 yscan->data.F32[j][k] -= yReduced->data.F32[i]; 701 } 702 } 703 } 704 705 // subtract the x-dir vector from the x-dir overscan regions (why?) 706 { 707 // the overscan and image might not be aligned. 708 int diff = xscan->col0 - image->col0; // Offset between the two regions 709 for (int i = PS_MAX(0,diff); i < PS_MIN(image->numCols, xscan->numCols + diff); i++) { 710 int j = i - diff; 711 // i is column on image (aligned with xReduced) 712 // j is column on xscan 713 for (int k = 0; k < xscan->numRows; k++) { 714 xscan->data.F32[k][j] -= xReduced->data.F32[i]; 715 } 716 } 717 } 718 psFree(xReduced); 719 psFree(yReduced); 720 } 721 547 722 pmOverscanUpdateHeader (hdu, overscanOpts, chi2); 548 723 psFree(stats);
Note:
See TracChangeset
for help on using the changeset viewer.
