Changeset 16949 for trunk/psModules/src/detrend/pmDark.c
- Timestamp:
- Mar 12, 2008, 10:49:46 AM (18 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/detrend/pmDark.c (modified) (27 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/detrend/pmDark.c
r16847 r16949 1 1 #include <stdio.h> 2 2 #include <pslib.h> 3 #include <string.h> 3 4 4 5 #include "psPolynomialMD.h" … … 95 96 96 97 97 bool pmDarkCombine(pmCell *output, const psArray *inputs, psArray *ordinates, int iter, float rej,98 psMaskType maskVal)98 bool pmDarkCombine(pmCell *output, const psArray *inputs, psArray *ordinates, const char *normConcept, 99 int iter, float rej, psMaskType maskVal) 99 100 { 100 101 PS_ASSERT_PTR_NON_NULL(output, false); … … 109 110 int numBadInputs = 0; // Number of bad inputs 110 111 psArray *values = psArrayAlloc(numInputs); 112 psVector *roMask = psVectorAlloc(numInputs, PS_TYPE_U8); // Mask for bad readouts 113 psVectorInit(roMask, 0); 114 psVector *norm = normConcept ? psVectorAlloc(numInputs, PS_TYPE_F32) : NULL; // Normalisations for each 111 115 for (int i = 0; i < numInputs; i++) { 112 116 values->data[i] = psVectorAlloc(numOrdinates, PS_TYPE_F32); 113 } 114 psVector *roMask = psVectorAlloc(numInputs, PS_TYPE_U8); // Mask for bad readouts 115 psVectorInit(roMask, 0); 117 if (norm) { 118 pmReadout *ro = inputs->data[i]; // Readout of interest 119 float normValue; // Normalisation value 120 if (!ordinateLookup(&normValue, normConcept, false, NAN, NAN, ro)) { 121 psWarning("Unable to find value of %s for readout %d", normConcept, i); 122 roMask->data.U8[i] = 0xff; 123 norm->data.F32[i] = NAN; 124 numBadInputs++; 125 continue; 126 } 127 if (normValue == 0.0) { 128 psWarning("Normalisation value (%s) for readout %d is zero", normConcept, i); 129 roMask->data.U8[i] = 0xff; 130 norm->data.F32[i] = NAN; 131 numBadInputs++; 132 continue; 133 } 134 norm->data.F32[i] = 1.0 / normValue; 135 } 136 } 116 137 psVector *orders = psVectorAlloc(numOrdinates, PS_TYPE_U8); // Orders for each concept 117 138 for (int i = 0; i < numOrdinates; i++) { … … 135 156 136 157 for (int j = 0; j < numInputs; j++) { 158 psVector *val = values->data[j]; // Value vector for readout 159 if (roMask->data.U8[j]) { 160 val->data.F32[i] = NAN; 161 continue; 162 } 163 137 164 pmReadout *ro = inputs->data[j]; // Readout of interest 138 psVector *val = values->data[j]; // Value vector for readout139 140 165 float value = NAN; // Value of ordinate 141 166 if (!ordinateLookup(&value, ord->name, ord->scale, ord->min, ord->max, ro)) { … … 148 173 } 149 174 } 150 numInputs -= numBadInputs;151 175 152 176 if (psTraceGetLevel("psModules.detrend") > 9) { … … 162 186 psFree(orders); 163 187 int numTerms = poly->coeff->n; // Number of terms in polynomial 164 if (numTerms > numInputs ) {188 if (numTerms > numInputs - numBadInputs) { 165 189 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Insufficient inputs (%d) to fit polynomial terms (%d).", 166 numInputs , numTerms);190 numInputs - numBadInputs, numTerms); 167 191 psFree(values); 168 192 psFree(roMask); 193 psFree(norm); 169 194 return false; 170 195 } … … 176 201 inputs)) { 177 202 psError(PS_ERR_UNKNOWN, false, "No valid input readouts."); 203 psFree(values); 204 psFree(roMask); 205 psFree(norm); 178 206 return false; 179 207 } … … 224 252 225 253 pixels->data.F32[r] = readout->image->data.F32[yIn][xIn]; 254 if (norm) { 255 pixels->data.F32[r] *= norm->data.F32[r]; 256 } 226 257 if (readout->mask) { 227 258 mask->data.PS_TYPE_MASK_DATA[r] = readout->mask->data.PS_TYPE_MASK_DATA[yIn][xIn]; … … 240 271 } 241 272 273 psFree(norm); 242 274 psFree(roMask); 243 275 psFree(poly); … … 248 280 psMetadataAddPtr(output->analysis, PS_LIST_TAIL, PM_DARK_ANALYSIS_ORDINATES, 249 281 PS_DATA_ARRAY | PS_META_REPLACE, "Dark ordinates", ordinates); 282 psMetadataAddStr(output->analysis, PS_LIST_TAIL, PM_DARK_ANALYSIS_NORM, 283 PS_META_REPLACE, "Dark normalisation", normConcept); 250 284 251 285 for (int i = 0; i < numTerms; i++) { … … 286 320 return false; 287 321 } 322 bool mdok; // Status of MD lookup 323 psString normConcept = psMetadataLookupStr(&mdok, dark->analysis, PM_DARK_ANALYSIS_NORM); // Normalisation 288 324 289 325 int numOrdinates = ordinates->n; // Number of ordinates … … 299 335 values->data.F32[i] = value; 300 336 } 337 float norm = NAN; // Normalisation value 338 if (normConcept) { 339 if (!ordinateLookup(&norm, normConcept, false, NAN, NAN, readout)) { 340 psError(PS_ERR_UNKNOWN, true, "Unable to find value for %s", normConcept); 341 psFree(values); 342 return false; 343 } 344 } 301 345 302 346 psVector *orders = psVectorAlloc(numOrdinates, PS_TYPE_U8); // Order for each polynomial … … 322 366 } 323 367 float value = psPolynomialMDEval(poly, values); // Value of dark current 368 if (normConcept) { 369 value *= norm; 370 } 324 371 readout->image->data.F32[y][x] -= value; 325 372 if (readout->mask && !isfinite(value)) { … … 352 399 353 400 psArray *ordinates = NULL; // Dark ordinates, to write 401 const char *normConcept = NULL; // Normalisation concept 354 402 psArray *chips = fpa->chips; // Component chips 355 403 for (int i = 0; i < chips->n; i++) { … … 359 407 pmCell *cell = cells->data[j]; // Cell of interest 360 408 bool mdok; // Status of MD lookup 361 psArray *new = psMetadataLookupPtr(&mdok, cell->analysis, PM_DARK_ANALYSIS_ORDINATES);409 psArray *newOrd = psMetadataLookupPtr(&mdok, cell->analysis, PM_DARK_ANALYSIS_ORDINATES); // Ords 362 410 if (!mdok) { 363 411 continue; 364 412 } 413 psString newNorm = psMetadataLookupPtr(&mdok, cell->analysis, PM_DARK_ANALYSIS_NORM); // Norm 365 414 if (ordinates) { 366 if (new != ordinates) {415 if (newOrd != ordinates) { 367 416 psError(PS_ERR_UNKNOWN, true, "Dark ordinates differ across cells."); 368 417 return false; 369 418 } 419 if ((normConcept && (!newNorm || strcmp(normConcept, newNorm) != 0)) || 420 (!normConcept && newNorm)) { 421 psError(PS_ERR_UNKNOWN, true, "Dark normalisations differ across cells."); 422 return false; 423 } 370 424 } else { 371 ordinates = new; 425 ordinates = newOrd; 426 normConcept = newNorm; 372 427 } 373 428 } … … 379 434 } 380 435 381 return pmDarkWrite(fits, hdu->header, ordinates );436 return pmDarkWrite(fits, hdu->header, ordinates, normConcept); 382 437 } 383 438 … … 399 454 400 455 psArray *ordinates = NULL; // Dark ordinates, to write 456 const char *normConcept = NULL; // Normalisation concept 401 457 psArray *cells = chip->cells; // Component cells 402 458 for (int j = 0; j < cells->n; j++) { 403 459 pmCell *cell = cells->data[j]; // Cell of interest 404 460 bool mdok; // Status of MD lookup 405 psArray *new = psMetadataLookupPtr(&mdok, cell->analysis, PM_DARK_ANALYSIS_ORDINATES);461 psArray *newOrd = psMetadataLookupPtr(&mdok, cell->analysis, PM_DARK_ANALYSIS_ORDINATES); // Ordinates 406 462 if (!mdok) { 407 463 continue; 408 464 } 465 psString newNorm = psMetadataLookupPtr(&mdok, cell->analysis, PM_DARK_ANALYSIS_NORM); // Normalisation 409 466 if (ordinates) { 410 if (new != ordinates) {467 if (newOrd != ordinates) { 411 468 psError(PS_ERR_UNKNOWN, true, "Dark ordinates differ across cells."); 412 469 return false; 413 470 } 471 if ((normConcept && (!newNorm || strcmp(normConcept, newNorm) != 0)) || 472 (!normConcept && newNorm)) { 473 psError(PS_ERR_UNKNOWN, true, "Dark normalisations differ across cells."); 474 return false; 475 } 414 476 } else { 415 ordinates = new; 477 ordinates = newOrd; 478 normConcept = newNorm; 416 479 } 417 480 } … … 422 485 } 423 486 424 return pmDarkWrite(fits, hdu->header, ordinates );487 return pmDarkWrite(fits, hdu->header, ordinates, normConcept); 425 488 } 426 489 … … 447 510 return false; 448 511 } 449 450 return pmDarkWrite(fits, hdu->header, ordinates); 451 } 452 453 bool pmDarkWrite(psFits *fits, const psMetadata *header, const psArray *ordinates) 512 bool mdok; // Status of MD lookup 513 psString normConcept = psMetadataLookupPtr(&mdok, cell->analysis, PM_DARK_ANALYSIS_NORM); // Normalisation 514 515 return pmDarkWrite(fits, hdu->header, ordinates, normConcept); 516 } 517 518 bool pmDarkWrite(psFits *fits, psMetadata *header, const psArray *ordinates, const char *normConcept) 454 519 { 455 520 PS_ASSERT_FITS_NON_NULL(fits, false); … … 472 537 } 473 538 474 // Format ordinates into FITS table 475 int numOrdinates = ordinates->n;// Number of ordinates 476 psArray *table = psArrayAlloc(numOrdinates); // FITS table, constructed from ordinates 477 for (int i = 0; i < ordinates->n; i++) { 478 pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate of interest 479 psMetadata *row = psMetadataAlloc(); // FITS table row 480 psMetadataAddStr(row, PS_LIST_TAIL, PM_DARK_FITS_NAME, 0, "Concept name", ord->name); 481 psMetadataAddS32(row, PS_LIST_TAIL, PM_DARK_FITS_ORDER, 0, "Polynomial order", ord->order); 482 psMetadataAddBool(row, PS_LIST_TAIL, PM_DARK_FITS_SCALE, 0, "Scale values?", ord->scale); 483 psMetadataAddF32(row, PS_LIST_TAIL, PM_DARK_FITS_MIN, 0, "Minimum value", ord->min); 484 psMetadataAddF32(row, PS_LIST_TAIL, PM_DARK_FITS_MAX, 0, "Maximum value", ord->max); 485 table->data[i] = row; 486 } 487 488 if (!psFitsWriteTable(fits, header, table, PM_DARK_FITS_EXTNAME)) { 489 psError(PS_ERR_IO, false, "Unable to write dark ordinates."); 539 if (!psMemIncrRefCounter((psMetadata*)header)) { 540 header = psMetadataAlloc(); 541 } 542 psMetadataAddStr(header, PS_LIST_TAIL, PM_DARK_HEADER_NORM, PS_META_REPLACE, 543 "Dark normalisation concept", normConcept); 544 545 if (ordinates->n > 0) { 546 // Format ordinates into FITS table 547 int numOrdinates = ordinates->n;// Number of ordinates 548 psArray *table = psArrayAlloc(numOrdinates); // FITS table, constructed from ordinates 549 for (int i = 0; i < ordinates->n; i++) { 550 pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate of interest 551 psMetadata *row = psMetadataAlloc(); // FITS table row 552 psMetadataAddStr(row, PS_LIST_TAIL, PM_DARK_FITS_NAME, 0, "Concept name", ord->name); 553 psMetadataAddS32(row, PS_LIST_TAIL, PM_DARK_FITS_ORDER, 0, "Polynomial order", ord->order); 554 psMetadataAddBool(row, PS_LIST_TAIL, PM_DARK_FITS_SCALE, 0, "Scale values?", ord->scale); 555 psMetadataAddF32(row, PS_LIST_TAIL, PM_DARK_FITS_MIN, 0, "Minimum value", ord->min); 556 psMetadataAddF32(row, PS_LIST_TAIL, PM_DARK_FITS_MAX, 0, "Maximum value", ord->max); 557 table->data[i] = row; 558 } 559 560 if (!psFitsWriteTable(fits, header, table, PM_DARK_FITS_EXTNAME)) { 561 psError(PS_ERR_IO, false, "Unable to write dark ordinates."); 562 psFree(table); 563 psFree(header); 564 return false; 565 } 490 566 psFree(table); 491 return false; 492 } 493 psFree(table); 567 } else { 568 // No ordinates to write to a table, so write to a blank header. 569 if (!psFitsWriteBlank(fits, header, PM_DARK_FITS_EXTNAME)) { 570 psError(PS_ERR_IO, false, "Unable to write dark header."); 571 psFree(header); 572 return false; 573 } 574 } 575 psFree(header); 494 576 495 577 return true; … … 507 589 } 508 590 509 psArray *ordinates = pmDarkRead(fits); 591 psString normConcept = NULL; // Normalisation concept 592 psArray *ordinates = pmDarkRead(&normConcept, fits); // Dark ordinates 510 593 if (!ordinates) { 511 594 psError(PS_ERR_IO, false, "Unable to read dark ordinates."); … … 521 604 psMetadataAddPtr(cell->analysis, PS_LIST_TAIL, PM_DARK_ANALYSIS_ORDINATES, 522 605 PS_DATA_ARRAY | PS_META_REPLACE, "Dark ordinates", ordinates); 606 psMetadataAddStr(cell->analysis, PS_LIST_TAIL, PM_DARK_ANALYSIS_NORM, PS_META_REPLACE, 607 "Dark normalisation", normConcept); 523 608 } 524 609 } 525 610 psFree(ordinates); 611 psFree(normConcept); 526 612 527 613 return true; … … 538 624 } 539 625 540 psArray *ordinates = pmDarkRead(fits); 626 psString normConcept = NULL; // Normalisation concept 627 psArray *ordinates = pmDarkRead(&normConcept, fits); // Dark ordinates 541 628 if (!ordinates) { 542 629 psError(PS_ERR_IO, false, "Unable to read dark ordinates."); … … 549 636 psMetadataAddPtr(cell->analysis, PS_LIST_TAIL, PM_DARK_ANALYSIS_ORDINATES, 550 637 PS_DATA_ARRAY | PS_META_REPLACE, "Dark ordinates", ordinates); 638 psMetadataAddStr(cell->analysis, PS_LIST_TAIL, PM_DARK_ANALYSIS_NORM, PS_META_REPLACE, 639 "Dark normalisation", normConcept); 551 640 } 552 641 psFree(ordinates); 642 psFree(normConcept); 553 643 554 644 return true; … … 567 657 } 568 658 569 psArray *ordinates = pmDarkRead(fits); 659 psString normConcept = NULL; // Normalisation concept 660 psArray *ordinates = pmDarkRead(&normConcept, fits); // Dark ordinates 570 661 if (!ordinates) { 571 662 psError(PS_ERR_IO, false, "Unable to read dark ordinates."); … … 574 665 psMetadataAddPtr(cell->analysis, PS_LIST_TAIL, PM_DARK_ANALYSIS_ORDINATES, 575 666 PS_DATA_ARRAY | PS_META_REPLACE, "Dark ordinates", ordinates); 667 psMetadataAddStr(cell->analysis, PS_LIST_TAIL, PM_DARK_ANALYSIS_NORM, PS_META_REPLACE, 668 "Dark normalisation", normConcept); 576 669 psFree(ordinates); 670 psFree(normConcept); 577 671 578 672 return true; 579 673 } 580 674 581 psArray *pmDarkRead(psFits *fits) 582 { 583 PS_ASSERT_FITS_NON_NULL(fits, false); 675 psArray *pmDarkRead(psString *normConcept, psFits *fits) 676 { 677 PS_ASSERT_PTR_NON_NULL(normConcept, NULL); 678 PS_ASSERT_PTR_NULL(*normConcept, NULL); 679 PS_ASSERT_FITS_NON_NULL(fits, NULL); 584 680 585 681 if (!psFitsMoveExtName(fits, PM_DARK_FITS_EXTNAME)) { … … 589 685 } 590 686 591 psArray *table = psFitsReadTable(fits); // FITS Table with ordinates 592 int numOrdinates = table->n; // Number of ordinates 593 psArray *ordinates = psArrayAlloc(numOrdinates); // Parsed ordinates 594 595 for (int i = 0; i < numOrdinates; i++) { 596 psMetadata *row = table->data[i]; // Row of interest 597 const char *name = psMetadataLookupStr(NULL, row, PM_DARK_FITS_NAME); // Concept name 598 int order = psMetadataLookupS32(NULL, row, PM_DARK_FITS_ORDER); // Polynomial order 599 if (!name || order <= 0) { 600 psError(PS_ERR_UNKNOWN, false, "Bad value reading dark ordinates table."); 601 psFree(table); 602 psFree(ordinates); 603 return false; 604 } 605 pmDarkOrdinate *ord = pmDarkOrdinateAlloc(name, order); // Ordinate data 606 ord->scale = psMetadataLookupBool(NULL, row, PM_DARK_FITS_SCALE); 607 ord->min = psMetadataLookupF32(NULL, row, PM_DARK_FITS_MIN); 608 ord->max = psMetadataLookupF32(NULL, row, PM_DARK_FITS_MAX); 609 610 ordinates->data[i] = ord; 611 } 612 psFree(table); 687 psMetadata *header = psFitsReadHeader(NULL, fits); // Header 688 bool mdok; // Status of MD lookup 689 *normConcept = psMemIncrRefCounter(psMetadataLookupStr(&mdok, header, PM_DARK_HEADER_NORM)); 690 691 psArray *ordinates = NULL; // Dark ordinates to return 692 693 psFitsType type = psFitsGetExtType(fits); // Type of FITS extension 694 switch (type) { 695 case PS_FITS_TYPE_IMAGE: { 696 // Check that it's of zero size; otherwise we might have some conflict 697 int numCols = psMetadataLookupS32(&mdok, header, "NAXIS1"); 698 int numRows = psMetadataLookupS32(&mdok, header, "NAXIS2"); 699 if (numCols != 0 || numRows != 0) { 700 psError(PS_ERR_UNKNOWN, true, "Extension %s is not a DARK table.", PM_DARK_FITS_EXTNAME); 701 psFree(header); 702 return NULL; 703 } 704 // No ordinates fit --- only a constant term 705 ordinates = psArrayAlloc(0); 706 break; 707 } 708 case PS_FITS_TYPE_BINARY_TABLE: 709 case PS_FITS_TYPE_ASCII_TABLE: { 710 psArray *table = psFitsReadTable(fits); // FITS Table with ordinates 711 int numOrdinates = table->n; // Number of ordinates 712 ordinates = psArrayAlloc(numOrdinates); 713 714 for (int i = 0; i < numOrdinates; i++) { 715 psMetadata *row = table->data[i]; // Row of interest 716 const char *name = psMetadataLookupStr(NULL, row, PM_DARK_FITS_NAME); // Concept name 717 int order = psMetadataLookupS32(NULL, row, PM_DARK_FITS_ORDER); // Polynomial order 718 if (!name || order <= 0) { 719 psError(PS_ERR_UNKNOWN, false, "Bad value reading dark ordinates table."); 720 psFree(table); 721 psFree(ordinates); 722 return false; 723 } 724 pmDarkOrdinate *ord = pmDarkOrdinateAlloc(name, order); // Ordinate data 725 ord->scale = psMetadataLookupBool(NULL, row, PM_DARK_FITS_SCALE); 726 ord->min = psMetadataLookupF32(NULL, row, PM_DARK_FITS_MIN); 727 ord->max = psMetadataLookupF32(NULL, row, PM_DARK_FITS_MAX); 728 729 ordinates->data[i] = ord; 730 } 731 psFree(table); 732 break; 733 } 734 default: 735 psError(PS_ERR_UNKNOWN, true, "Unrecognised FITS extension type."); 736 return NULL; 737 } 738 psFree(header); 613 739 614 740 return ordinates;
Note:
See TracChangeset
for help on using the changeset viewer.
