00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <sys/stat.h>
00023 #include <math.h>
00024 #include <stdio.h>
00025 #include "qfits.h"
00026 #include "midiGlobal.h"
00027 #include "midiLib.h"
00028 #include "imageProcessing.h"
00029 #include "statistics.h"
00030 #include "errorHandling.h"
00031 #include "diagnostics.h"
00032 #include "cpl_image_io.h"
00033 #include "cpl_image_basic.h"
00034 #include "complex_midi.h"
00035 #include "fft.h"
00036 #include <cpl.h>
00037
00038
00039
00040
00041 #define CIRCLE_TO_SQUARE (0.350)
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 void getUndispersedPowerSpectrum (
00064 ImageFormat *imageFormat,
00065 CompressedData *compressed)
00066 {
00067
00068
00069
00070 const char routine[] = "getUndispersedPowerSpectrum";
00071 double *inputPtr;
00072 struct Complex *input2ft;
00073 int i, s, R;
00074 float accum, *allSpectrumPtr, *dcLevelsPtr;
00075
00076
00077
00078 if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
00079 if (diagnostic > 4) fprintf (midiReportPtr, "Invoking routine '%s' \n", routine);
00080
00081
00082 SetFFTsize (imageFormat->fftsize);
00083
00084
00085 FFTarray = (struct Complex *) malloc (MAXFFTSIZE * (sizeof(struct Complex)));
00086 input2ft = (struct Complex *) malloc (imageFormat->fftsize * (sizeof(struct Complex)));
00087
00088
00089 allSpectrumPtr = compressed->allSpectrum;
00090 dcLevelsPtr = compressed->dcLevels;
00091
00092 for (R = 0; R < REGIONS_UNDISPERSED; R++)
00093 {
00094 if (R == 0)
00095 inputPtr = compressed->iFringe;
00096 else if (R == 1)
00097 inputPtr = compressed->iFringe1;
00098 else
00099 inputPtr = compressed->iFringe2;
00100
00101
00102 for (s = 0; s < imageFormat->numOfScans; s++)
00103 {
00104
00105 if (!(compressed->badScanList[s]))
00106 {
00107
00108 memset (input2ft, 0, (sizeof(struct Complex)) * imageFormat->fftsize);
00109 accum = 0.F;
00110 for (i = 0; i < imageFormat->framesPerScan; i++)
00111 {
00112
00113 accum += *inputPtr;
00114
00115
00116 input2ft[i].r = *inputPtr;
00117 inputPtr++;
00118 }
00119
00120
00121 *dcLevelsPtr = accum / ((float) imageFormat->framesPerScan);
00122
00123
00124 for (i = 0; i < imageFormat->framesPerScan; i++)
00125 input2ft[i].r -= *dcLevelsPtr;
00126
00127
00128 dcLevelsPtr++;
00129
00130
00131 FFT (input2ft, FFTlevel);
00132
00133
00134 for (i = 0; i < imageFormat->fftsize/2; i++)
00135 {
00136 *allSpectrumPtr = Cmag2(FFTarray[i]);
00137 allSpectrumPtr++;
00138 }
00139 }
00140 else
00141 {
00142
00143 dcLevelsPtr++;
00144 for (i = 0; i < imageFormat->framesPerScan; i++)
00145 inputPtr++;
00146 for (i = 0; i < imageFormat->fftsize/2; i++)
00147 allSpectrumPtr++;
00148 }
00149 }
00150 }
00151
00152
00153 if (plotFile)
00154 {
00155 if (strcmp (imageFormat->beamCombiner, "SCI_PHOT") == 0)
00156 midiCreatePlotFile2D ("SpectrumCombinedDATA2DATA3", "DATA2-DATA3, DATA2 and DATA3 Spectrum",
00157 "FFT bins for each Scan", "Power Spectrum", 0, compressed->allSpectrum, 0,
00158 imageFormat->allSpectrumLength, 1, 0);
00159 else
00160 midiCreatePlotFile2D ("SpectrumCombinedDATA1DATA2", "DATA1-DATA2, DATA1 and DATA2 Spectrum",
00161 "FFT bins for each Scan", "Power Spectrum", 0, compressed->allSpectrum, 0,
00162 imageFormat->allSpectrumLength, 1, 0);
00163 }
00164
00165 free (input2ft);
00166 free (FFTarray);
00167
00168 return;
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 void normalizeSignal (
00186 int arraySize,
00187 float *signal)
00188 {
00189
00190
00191
00192 const char routine[] = "normalizeSignal";
00193 int i;
00194 float maxSignal;
00195
00196
00197
00198 if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
00199 if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
00200
00201
00202 maxSignal = signal[0];
00203 for (i = 0; i < arraySize; i++)
00204 if (signal[i] > maxSignal) maxSignal = signal[i];
00205
00206
00207 for (i = 0; i < arraySize; i++)
00208 signal[i] /= maxSignal;
00209
00210 return;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 void computeFrameFlux (
00229 short int *inData,
00230 int frame,
00231 int scalingOffset,
00232 ImageFormat *format,
00233 MidiCoords *target,
00234 float *flux,
00235 int *pixelCount,
00236 int *error)
00237
00238 {
00239
00240
00241
00242 const char routine[] = "computeFrameFlux";
00243 int i, yWin, xWin, fileSpan, frameSpan, subWindowSize;
00244
00245
00246
00247 if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
00248 if (diagnostic > 4) fprintf (midiReportPtr, "Invoking routine '%s' \n", routine);
00249
00250
00251 *error = 0;
00252 *flux = 0.0;
00253 *pixelCount = 0;
00254
00255
00256 subWindowSize = format->iXWidth * format->iYWidth;
00257 fileSpan = frame * subWindowSize;
00258 for (yWin = 0; yWin < format->iYWidth; yWin++)
00259 {
00260 frameSpan = yWin * format->iXWidth;
00261 for (xWin = 0; xWin < format->iXWidth; xWin++)
00262 {
00263
00264 i = fileSpan + frameSpan + xWin;
00265 if (isnan (inData[i]))
00266 {
00267 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Corrupted data");
00268 *error = 1;
00269 return;
00270 }
00271 if (xWin >= (int) (target->xCoord) && xWin <= (int) (target->dxCoord) &&
00272 yWin >= (int) (target->yCoord) && yWin <= (int) (target->dyCoord))
00273 {
00274 *flux += (float) (inData[i] + scalingOffset);
00275 (*pixelCount)++;
00276 }
00277 }
00278 }
00279
00280 if (diagnostic)
00281 {
00282 cpl_msg_info(cpl_func,"\nCoordinates and flux results for frame %d: \n", frame);
00283 cpl_msg_info(cpl_func,"====================================== \n");
00284 cpl_msg_info(cpl_func," Image coordinates = %f %f %f %f\n", target->xCoord, target->yCoord, target->dxCoord, target->dyCoord);
00285 cpl_msg_info(cpl_func," Flux = %f\n", *flux);
00286 cpl_msg_info(cpl_func," Pixel count = %d\n", *pixelCount);
00287 fprintf (midiReportPtr, "\nCoordinates and flux results for frame %d: \n", frame);
00288 fprintf (midiReportPtr, "====================================== \n");
00289 fprintf (midiReportPtr, " Image coordinates = %f %f %f %f\n", target->xCoord, target->yCoord, target->dxCoord, target->dyCoord);
00290 fprintf (midiReportPtr, " Flux = %f\n", *flux);
00291 fprintf (midiReportPtr, " Pixel count = %d\n", *pixelCount);
00292 }
00293
00294 return;
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 void computeImageFlux (
00313 float *image,
00314 ImageFormat *format,
00315 MidiCoords *target,
00316 float *flux,
00317 int *pixelCount,
00318 int *error)
00319
00320 {
00321
00322
00323
00324 const char routine[] = "computeImageFlux";
00325 int i, yWin, xWin, frameSpan;
00326
00327
00328
00329 if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
00330 if (diagnostic > 4) fprintf (midiReportPtr, "Invoking routine '%s' \n", routine);
00331
00332
00333 *error = 0;
00334 *flux = 0.0;
00335 *pixelCount = 0;
00336
00337
00338 for (yWin = 0; yWin < format->iYWidth; yWin++)
00339 {
00340 frameSpan = yWin * format->iXWidth;
00341 for (xWin = 0; xWin < format->iXWidth; xWin++)
00342 {
00343
00344 i = frameSpan + xWin;
00345 if (xWin >= (int) (target->xCoord) && xWin <= (int) (target->dxCoord) &&
00346 yWin >= (int) (target->yCoord) && yWin <= (int) (target->dyCoord))
00347 {
00348 *flux += (float) (image[i]);
00349 (*pixelCount)++;
00350 }
00351 }
00352 }
00353
00354 return;
00355 }
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 void createAveragedImage (
00371 short int *inData,
00372 float scalingOffset,
00373 ImageFormat *format,
00374 float *image)
00375
00376 {
00377
00378
00379 const char routine[] = "createAveragedImage";
00380 int i, count, pixel, frame, subWindowSize;
00381
00382
00383
00384 if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
00385 if (diagnostic > 4) fprintf (midiReportPtr, "Invoking routine '%s' \n", routine);
00386
00387
00388 subWindowSize = format->iXWidth * format->iYWidth;
00389
00390 for (pixel = 0; pixel < subWindowSize; pixel++)
00391 {
00392
00393 image[pixel] = 0;
00394 count = 0;
00395 for (frame = 0; frame < format->numOfFrames; frame++)
00396 {
00397
00398 i = frame * subWindowSize + pixel;
00399 if (isnan (inData[i]))
00400 {
00401 sprintf (midiMessage, "Found bad pixel on frame %d", frame);
00402 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
00403 }
00404 else
00405 {
00406 count++;
00407 image[pixel] += (float) (inData[i] + scalingOffset);
00408 }
00409 }
00410
00411
00412 image[pixel] /= count;
00413 }
00414
00415 return;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 void createFitsImage (
00436 const char *regionOrFile,
00437 const char *name,
00438 char *inFitsName,
00439 int xLength,
00440 int yLength,
00441 float *image)
00442 {
00443
00444
00445
00446 const char routine[] = "createFitsImage";
00447 qfits_header *pHeaderOut;
00448 FILE *imagePtr;
00449 qfitsdumper qdImage;
00450 char *sWidthX, *sWidthY, *stringOut;
00451 struct stat buf;
00452
00453
00454
00455 if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
00456 if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
00457
00458 cpl_msg_info(cpl_func,"\nCreating an image from %s for batch %d \n", regionOrFile, batchNumber);
00459 cpl_msg_info(cpl_func,"----------------------------------- \n");
00460 fprintf (midiReportPtr, "\nCreating an image from %s for batch %d \n", regionOrFile, batchNumber);
00461 fprintf (midiReportPtr, "----------------------------------- \n");
00462
00463
00464 stringOut = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00465 sWidthY = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
00466 sWidthX = (char *) calloc (MIN_STRING_LENGTH, sizeof (char));
00467
00468
00469 sprintf (sWidthY, "%d", yLength);
00470 sprintf (sWidthX, "%d", xLength);
00471
00472
00473 if (diagnostic)cpl_msg_info(cpl_func," Extracting primary header from input FITS file %s \n", inFitsName);
00474 fprintf(midiReportPtr, " Extracting primary header from input FITS file %s \n", inFitsName);
00475 pHeaderOut = qfits_header_read (inFitsName);
00476 if (pHeaderOut == NULL)
00477 {
00478 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot extract primary header from input FITS file");
00479 free (sWidthY);
00480 free (sWidthX);
00481 free (stringOut);
00482 return;
00483 }
00484
00485
00486 qfits_header_mod (pHeaderOut, "BITPIX","-32", "number of bits per pixel");
00487 qfits_header_mod (pHeaderOut, "NAXIS", "2", "number of data axes");
00488 qfits_header_add (pHeaderOut, "NAXIS1", sWidthX, "", "");
00489 qfits_header_add (pHeaderOut, "NAXIS2", sWidthY, "", "");
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 qfits_header_mod (pHeaderOut, "INSTRUME", "MIDI", "MIDI Raw Data Display FITS created by DRS pipeline" );
00505
00506
00507 sprintf (stringOut, "%s%s.%s.fits", outFileDir, outRootName, name);
00508 if (stat (stringOut, &buf) == 0) remove (stringOut);
00509 if ((imagePtr = fopen (stringOut, "w")) == NULL)
00510 {
00511 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot create Image of the data file");
00512 free (sWidthY);
00513 free (sWidthX);
00514 free (stringOut);
00515 qfits_header_destroy (pHeaderOut);
00516 return;
00517 }
00518
00519 cpl_msg_info(cpl_func," Created an Image file: %s \n", stringOut);
00520 fprintf (midiReportPtr, " Created an Image file: %s \n", stringOut);
00521
00522 qfits_header_dump (pHeaderOut, imagePtr);
00523 fclose (imagePtr);
00524
00525
00526 qfits_header_destroy (pHeaderOut);
00527
00528
00529 qdImage.filename = stringOut;
00530 qdImage.npix = xLength * yLength;
00531 qdImage.ptype = PTYPE_FLOAT;
00532 qdImage.fbuf = image;
00533 qdImage.out_ptype = BPP_IEEE_FLOAT;
00534
00535 qfits_pixdump (&qdImage);
00536
00537
00538 qfits_zeropad((char *)stringOut);
00539
00540
00541 free (sWidthY);
00542 free (sWidthX);
00543 free (stringOut);
00544
00545 return;
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 void midiGaussianFit (
00563 int fileNumber,
00564 int dimension,
00565 float *image,
00566 int xImage,
00567 int yImage,
00568 int xP,
00569 int yP,
00570 int sizeP,
00571 double *xT,
00572 double *yT,
00573 double *sizeXT,
00574 double *sizeYT,
00575 int *error)
00576
00577 {
00578
00579
00580
00581 const char routine[] = "midiGaussianFit";
00582 cpl_image *cplImage;
00583 double sigX, sigY, norm;
00584
00585
00586
00587 if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
00588 if (diagnostic > 4) fprintf (midiReportPtr, "Invoking routine '%s' \n", routine);
00589
00590
00591 *error = 0;
00592 *xT = 0.0;
00593 *yT = 0.0;
00594 *sizeXT = 0.0;
00595 *sizeYT = 0.0;
00596
00597 if (dimension == 1)
00598 {
00599 midiGetFWHM (fileNumber, image, xImage, yImage, sizeP, xT, yT, sizeXT, sizeYT, error);
00600 if (*error) midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot find centroid");
00601 }
00602 else if (dimension == 2)
00603 {
00604
00605 cplImage = cpl_image_wrap_float (xImage, yImage, image);
00606
00607
00608 if (cpl_image_fit_gaussian (cplImage, xP, yP, sizeP, &norm, xT, yT, &sigX, &sigY, NULL, NULL)!=CPL_ERROR_NONE){
00609 *error = 1;
00610 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot find the centroid");
00611 cpl_image_unwrap (cplImage);
00612 return;
00613 }
00614
00615 *sizeXT = 0.5 * (sigX + sigY);
00616 *sizeYT = 0.5 * (sigX + sigY);
00617
00618 cpl_image_unwrap (cplImage);
00619 }
00620 else
00621 {
00622 *error = 1;
00623 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Invalid dimensionality");
00624 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot find centroid");
00625 return;
00626 }
00627
00628
00629 if (!(*error))
00630 {
00631 cpl_msg_info(cpl_func," Target centroid = (x, y, X-Width, Y-Width) %f %f %f %f\n",
00632 *xT, *yT, *sizeXT, *sizeYT);
00633 fprintf (midiReportPtr, " Target centroid = (x, y, X-Width, Y-Width) %f %f %f %f\n",
00634 *xT, *yT, *sizeXT, *sizeYT);
00635 }
00636
00637 return;
00638 }
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 void midiGaussian_1d_fit (
00654 float *array,
00655 int length,
00656 int sizeS,
00657 float *centre,
00658 float *sizeT,
00659 float *fluxErr2Min,
00660 int *error)
00661
00662 {
00663
00664
00665
00666 const char routine[] = "midiGaussian_1d_fit";
00667 int i, j, l, searchLimit, halfGauss;
00668 float *gaussian, sigma, exponentConst, fluxErr2;
00669 char *fileString, *title;
00670
00671
00672
00673 if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
00674 if (diagnostic > 4) fprintf (midiReportPtr, "Invoking routine '%s' \n", routine);
00675
00676
00677 *error = 0;
00678 *fluxErr2Min = 0.0;
00679 *centre = 0.0;
00680 *sizeT = 0.0;
00681 sigma = 0.0;
00682
00683
00684 if (diagnostic > 2) cpl_msg_info(cpl_func,"search span before = %d\n", sizeS);
00685 if (!(sizeS & 1)) sizeS += 1;
00686 if (diagnostic > 2) cpl_msg_info(cpl_func,"search span after = %d\n", sizeS);
00687 searchLimit = length - sizeS;
00688 if (searchLimit <= sizeS)
00689 {
00690 *error = 1;
00691 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Search window too large");
00692 return;
00693 }
00694
00695
00696 gaussian = (float *) calloc (sizeS, sizeof (float));
00697
00698
00699 halfGauss = (sizeS >> 1);
00700
00701
00702 if (diagnostic > 2)
00703 midiCreatePlotFile2D ("InputArray", "Input Array", "X", "Y", 0, array, 0, length, 1, 0);
00704
00705
00706 for (l = 0; l < GAUSSIAN_SIGMA_SPAN; l++)
00707 {
00708
00709 sigma += 0.25;
00710 exponentConst = (-0.5) / (sigma * sigma);
00711 for (i = -halfGauss; i <= halfGauss; i++)
00712 {
00713 j = halfGauss+i;
00714 gaussian[j] = exp (exponentConst * i * i);
00715 if (plotFile && diagnostic > 2)
00716 {
00717 fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00718 title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00719 sprintf (fileString , "GaussianWithSigma%f", sigma);
00720 sprintf (title , "Gaussian with %f Sigma", sigma);
00721 midiCreatePlotFile2D (fileString, title, "Span", "Sigma", 0, gaussian, 0, sizeS, 1, 0);
00722 free (fileString);
00723 free (title);
00724 if (diagnostic > 2)
00725 {
00726 cpl_msg_info(cpl_func," Gaussian %d = %8.8f\n", i, gaussian[j]);
00727 fprintf (midiReportPtr, " Gaussian %d = %8.8f\n", i, gaussian[j]);
00728 }
00729 }
00730 }
00731
00732
00733
00734 for (i = 0; i < searchLimit; i++)
00735 {
00736
00737 fluxErr2 = 0.0;
00738 for (j = 0; j < sizeS; j++)
00739 fluxErr2 += ( (gaussian[j] - array[i+j]) * (gaussian[j] - array[i+j]) );
00740
00741
00742 if (l == 0 && i == 0) *fluxErr2Min = fluxErr2;
00743 else
00744 {
00745 if (fluxErr2 < *fluxErr2Min)
00746 {
00747 *fluxErr2Min = fluxErr2;
00748 *centre = (float) (i + 0.5 * sizeS);
00749 *sizeT = (float) (3.0 * sigma);
00750 }
00751 }
00752 }
00753 }
00754
00755
00756 free (gaussian);
00757
00758 return;
00759 }
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775 float midiGaussianSmooth (
00776 float *array,
00777 int length,
00778 int peakIn,
00779 int searchSpan,
00780 int *error)
00781
00782 {
00783
00784
00785
00786 const char routine[] = "midiGaussianSmooth";
00787 int i, j, l, start, end, halfGauss;
00788 float *gaussian, sigma, exponentConst, fluxErr2, xCPH, fluxErr2Min;
00789 char *fileString, *title;
00790
00791
00792
00793 if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
00794 if (diagnostic > 4) fprintf (midiReportPtr, "Invoking routine '%s' \n", routine);
00795
00796
00797 *error = 0;
00798 fluxErr2Min = 0.0;
00799 sigma = 0.0;
00800 xCPH = 0.0;
00801
00802
00803 if (diagnostic > 2) cpl_msg_info(cpl_func,"search span before = %d\n", searchSpan);
00804 if (!(searchSpan & 1)) searchSpan += 1;
00805 if (diagnostic > 2) cpl_msg_info(cpl_func,"search span after = %d\n", searchSpan);
00806 halfGauss = (searchSpan >> 1);
00807 start = peakIn - searchSpan;
00808 end = peakIn + searchSpan;
00809 if ((end > length) || (start < 0))
00810 {
00811 *error = 1;
00812 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Search window too large");
00813 return (-1);
00814 }
00815
00816
00817 gaussian = (float *) calloc (searchSpan, sizeof (float));
00818
00819
00820 for (l = 0; l < GAUSSIAN_SIGMA_SPAN; l++)
00821 {
00822
00823 sigma += 0.25;
00824 exponentConst = (-0.5) / (sigma * sigma);
00825 for (i = -halfGauss; i <= halfGauss; i++)
00826 {
00827 j = halfGauss+i;
00828 gaussian[j] = exp (exponentConst * i * i);
00829 if (plotFile && diagnostic > 2)
00830 {
00831 fileString = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00832 title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
00833 sprintf (fileString , "GaussianWithSigma%f", sigma);
00834 sprintf (title , "Gaussian with %f Sigma", sigma);
00835 midiCreatePlotFile2D (fileString, title, "Span", "Sigma", 0, gaussian, 0, searchSpan, 1, 0);
00836 cpl_msg_info(cpl_func," Gaussian %d = %8.8f\n", i, gaussian[j]);
00837 fprintf (midiReportPtr, " Gaussian %d = %8.8f\n", i, gaussian[j]);
00838 }
00839 }
00840
00841
00842
00843 for (i = start; i < end; i++)
00844 {
00845
00846 fluxErr2 = 0.0;
00847 for (j = 0; j < searchSpan; j++)
00848 fluxErr2 += ( (gaussian[j] - array[i+j]) * (gaussian[j] - array[i+j]) );
00849
00850
00851 if ((l == 0) && (i == start))
00852 fluxErr2Min = fluxErr2;
00853 else
00854 {
00855 if (fluxErr2 < fluxErr2Min)
00856 {
00857 fluxErr2Min = fluxErr2;
00858 xCPH = (float) (i + 0.5 * searchSpan);
00859 }
00860 }
00861 }
00862 }
00863
00864
00865 free (gaussian);
00866
00867 return (xCPH);
00868 }
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883 void getBadScansFromSpectrumUndisp (
00884 FilterData *filterInfo,
00885 ImageFormat *format,
00886 CompressedData *compressed,
00887 int *error)
00888 {
00889
00890
00891 const char routine[] = "getBadScansFromSpectrumUndisp";
00892 int i;
00893 float *tempArray;
00894
00895
00896
00897 if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
00898 if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
00899
00900 cpl_msg_info(cpl_func,"\nRejecting scans based on Signal/Noise \n");
00901 cpl_msg_info(cpl_func,"------------------------------------- \n");
00902 fprintf (midiReportPtr, "\nRejecting scans based on Signal/Noise \n");
00903 fprintf (midiReportPtr, "------------------------------------- \n");
00904
00905
00906 *error = 0;
00907
00908
00909 rejectScansOnWeakSNRUndisp (filterInfo, format, compressed, error);
00910
00911
00912 format->numOfScansRejected = 0;
00913 format->numOfScansProcessed = 0;
00914 for (i = 0; i < format->numOfScans; i++)
00915 {
00916 if (compressed->badScanList[i])
00917 format->numOfScansRejected++;
00918 }
00919 format->numOfScansProcessed = format->numOfScans - format->numOfScansRejected;
00920
00921
00922 if (plotFile && diagnostic)
00923 {
00924 tempArray = (float *) calloc (format->numOfScans, sizeof (float));
00925 for (i = 0; i < format->numOfScans; i++)
00926 {
00927 if (compressed->badScanList[i] == 0)
00928 tempArray[i] = 0.0;
00929 else
00930 tempArray[i] = compressed->badScanList[i];
00931 }
00932 midiCreatePlotFile2D ("BadScanList", "Bad Scan List", "Scan", "Failure ID",
00933 0, tempArray, 0, format->numOfScans, 1, 0);
00934 free (tempArray);
00935 }
00936
00937
00938 if (diagnostic) cpl_msg_info(cpl_func,"\nBad Scan List \n");
00939 if (diagnostic) cpl_msg_info(cpl_func,"------------- \n");
00940 fprintf (midiReportPtr, "\nBad Scan List QCLOG \n");
00941 fprintf (midiReportPtr, "------------- QCLOG \n");
00942 for (i = 0; i < format->numOfScans; i++)
00943 {
00944 if (diagnostic) cpl_msg_info(cpl_func,"%3d %3d \n", i, compressed->badScanList[i]);
00945 fprintf (midiReportPtr, "%3d %3d QCLOG \n", i, compressed->badScanList[i]);
00946 }
00947
00948 cpl_msg_info(cpl_func,"Number of scans to process = %3d \n", format->numOfScansProcessed);
00949 cpl_msg_info(cpl_func,"Number of scans rejected = %3d \n", format->numOfScansRejected);
00950 fprintf (midiReportPtr, "Number of scans to process = %3d QCLOG \n", format->numOfScansProcessed);
00951 fprintf (midiReportPtr, "Number of scans rejected = %3d QCLOG \n", format->numOfScansRejected);
00952 if (diagnostic)
00953 {
00954 cpl_msg_info(cpl_func,"Failure ID \n");
00955 cpl_msg_info(cpl_func,"---------- \n");
00956 cpl_msg_info(cpl_func,"1 = Bit 1, indicates a TIME error \n");
00957 cpl_msg_info(cpl_func,"2 = Bit 2, indicates an LOCALOPD error \n");
00958 cpl_msg_info(cpl_func,"4 = Bit 3, indicates an OPD error \n");
00959 cpl_msg_info(cpl_func,"8 = Bit 4, indicates a Bad DATA \n");
00960 cpl_msg_info(cpl_func,"16 = Bit 5, indicates a chopping problem (TARTYPE2) \n");
00961 cpl_msg_info(cpl_func,"32 = Bit 6, indicates a Delay Line Jump \n");
00962 cpl_msg_info(cpl_func,"64 = Bit 7, indicates an Unwanted Region \n");
00963 cpl_msg_info(cpl_func,"128 = Bit 8, indicates a Weak Signal/Noise \n");
00964 cpl_msg_info(cpl_func,"256 = Bit 9, indicates a SKY Background \n");
00965 cpl_msg_info(cpl_func,"512 = Bit 10, indicates a TARTYPE Cross error. e.g. region 0 different to region 1 \n");
00966 cpl_msg_info(cpl_func,"\nHence a number such as 168 indicates bits 4, 6 and 8 were set \n\n");
00967 }
00968
00969 fprintf (midiReportPtr, "Failure ID QCLOG \n");
00970 fprintf (midiReportPtr, "---------- QCLOG \n");
00971 fprintf (midiReportPtr, "1 = Bit 1, indicates a TIME error \n");
00972 fprintf (midiReportPtr, "2 = Bit 2, indicates an LOCALOPD error \n");
00973 fprintf (midiReportPtr, "4 = Bit 3, indicates an OPD error \n");
00974 fprintf (midiReportPtr, "8 = Bit 4, indicates a Bad DATA \n");
00975 fprintf (midiReportPtr, "16 = Bit 5, indicates a chopping problem (TARTYPE2) \n");
00976 fprintf (midiReportPtr, "32 = Bit 6, indicates a Delay Line Jump \n");
00977 fprintf (midiReportPtr, "64 = Bit 7, indicates an Unwanted Region \n");
00978 fprintf (midiReportPtr, "128 = Bit 8, indicates a Weak Signal/Noise \n");
00979 fprintf (midiReportPtr, "256 = Bit 9, indicates a SKY Background \n");
00980 fprintf (midiReportPtr, "512 = Bit 10, indicates a TARTYPE Cross error. e.g. region 0 different to region 1 \n");
00981 fprintf (midiReportPtr, "\nHence a number such as 168 indicates bits 4, 6 and 8 were set QCLOG \n\n");
00982
00983 if (format->numOfScansProcessed < 1)
00984 {
00985 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "No Scan to process");
00986 *error = 1;
00987 }
00988
00989 return;
00990 }
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008 void rejectScansOnWeakSNRUndisp (
01009 FilterData *filterInfo,
01010 ImageFormat *format,
01011 CompressedData *compressed,
01012 int *error)
01013 {
01014
01015
01016 const char routine[] = "rejectScansOnWeakSNRUndisp";
01017 float *sigPtr, *spectrum, median, peak, ratio, calib;
01018 int i, j, fftSizeHalf, peakIndex, loF, hiF;
01019 char *fileName, *title;
01020
01021
01022
01023 if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
01024 if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
01025
01026
01027 *error = 0;
01028 fftSizeHalf = (format->fftsize >> 1);
01029
01030
01031 calib = format->optFreqCal / ((float) format->fftsize);
01032 loF = (int) (filterInfo->optFreqLo / calib);
01033 hiF = (int) (filterInfo->optFreqHi / calib);
01034 if (hiF > format->fftsize/2) hiF = format->fftsize/2;
01035
01036
01037 spectrum = (float *) calloc (fftSizeHalf, sizeof (float));
01038
01039
01040 for (i = 0; i < format->numOfScans; i++)
01041 {
01042 sigPtr = compressed->allSpectrum + i * fftSizeHalf;
01043
01044
01045 if (!(compressed->badScanList[i]))
01046 {
01047
01048 for (j = 0; j < fftSizeHalf; j++)
01049 spectrum[j] = *sigPtr++;
01050
01051
01052 peak = signalPeak (spectrum, 0, fftSizeHalf, &peakIndex);
01053 median = signalMedian (spectrum, 0, fftSizeHalf);
01054 ratio = peak/median;
01055
01056
01057 if ((ratio < 10.0) || (peakIndex < loF) || (peakIndex > hiF))
01058 compressed->badScanList[i] |= BSL_SNR_ERROR;
01059
01060
01061 if (plotFile && diagnostic > 2)
01062 {
01063 if (compressed->badScanList[i]) cpl_msg_info(cpl_func,"\n <<ERROR>>: Scan %3d rejected \n\n", i);
01064 cpl_msg_info(cpl_func," Expected low frequency index = %3d \n", loF);
01065 cpl_msg_info(cpl_func," Expected high frequency index = %3d \n", hiF);
01066 cpl_msg_info(cpl_func," Found peak index at = %3d \n", peakIndex);
01067 cpl_msg_info(cpl_func," peak/median = %f \n", ratio);
01068 if (compressed->badScanList[i]) fprintf (midiReportPtr, "\n <<ERROR>>: Scan %3d rejected \n\n", i);
01069 fprintf (midiReportPtr, " Expected low frequency index = %3d \n", loF);
01070 fprintf (midiReportPtr, " Expected high frequency index = %3d \n", hiF);
01071 fprintf (midiReportPtr, " Found peak index at = %3d \n", peakIndex);
01072 fprintf (midiReportPtr, " peak/median = %f \n", ratio);
01073
01074 fileName = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01075 title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01076 sprintf (fileName, "SpectrumScan%d", i);
01077 sprintf (title, "Power Spectrum. Scan %d", i);
01078 midiCreatePlotFile2D (fileName, title, "Frequancy bin", "Power Spectrum",
01079 1, spectrum, 0, fftSizeHalf, 1, 0);
01080 free (fileName);
01081 free (title);
01082 }
01083 }
01084 }
01085
01086
01087 free (spectrum);
01088
01089 return;
01090 }
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109 void midiGetFWHM (
01110 int imageCount,
01111 float *image,
01112 int xImage,
01113 int yImage,
01114 int sizeP,
01115 double *xT,
01116 double *yT,
01117 double *sizeXT,
01118 double *sizeYT,
01119 int *error)
01120
01121 {
01122
01123
01124
01125 const char routine[] = "midiGetFWHM";
01126 int i, j, k, l, length, maxLength, start, end;
01127 float *arrayData, centre, *centrePositions, *centreFluxErr2Min,
01128 fluxErr2Min, *span, siztT, fluxMax, *buffImage, max;
01129 char *fileName, *title;
01130
01131
01132
01133 if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
01134 if (diagnostic > 4) fprintf (midiReportPtr, "Invoking routine '%s' \n", routine);
01135
01136
01137 *error = 0;
01138
01139
01140 length = xImage * yImage;
01141 maxLength = (xImage > yImage) ? xImage : yImage;
01142 arrayData = (float *) calloc (maxLength, sizeof (float));
01143 centrePositions = (float *) calloc (maxLength, sizeof (float));
01144 centreFluxErr2Min = (float *) calloc (maxLength, sizeof (float));
01145 span = (float *) calloc (maxLength, sizeof (float));
01146 buffImage = (float *) calloc (length, sizeof (float));
01147
01148
01149 for (i = 0; i < length; i++)
01150 buffImage[i] = image[i];
01151
01152
01153 fluxMax = buffImage[0];
01154 for (i = 0; i < length; i++)
01155 if (buffImage[i] > fluxMax) fluxMax = buffImage[i];
01156 for (i = 0; i < length; i++)
01157 buffImage[i] /= fluxMax;
01158
01159
01160
01161
01162 for (i = 0; i < yImage; i++)
01163 {
01164
01165 for (j = 0; j < xImage; j++)
01166 {
01167 k = j + i * xImage;
01168 arrayData[j] = buffImage[k];
01169 }
01170
01171
01172 midiGaussian_1d_fit (arrayData, xImage, sizeP, ¢re, &siztT, &fluxErr2Min, error);
01173 if (*error)
01174 {
01175 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot determine target parameters");
01176 free (arrayData);
01177 free (centrePositions);
01178 free (centreFluxErr2Min);
01179 free (span);
01180 free (buffImage);
01181 return;
01182 }
01183 centrePositions[i] = centre;
01184 centreFluxErr2Min[i] = fluxErr2Min;
01185 span[i] = siztT;
01186 }
01187
01188
01189 *sizeXT = 0;
01190 for (i = 0; i < yImage; i++)
01191 {
01192 if (span[i] > *sizeXT)
01193 {
01194 *yT = i;
01195 *sizeXT = span[i];
01196 }
01197 }
01198
01199
01200 max = 0.0;
01201 l = *yT * xImage;
01202 for (j = 0; j < xImage; j++)
01203 {
01204
01205 k = j + l;
01206 arrayData[j] = buffImage[k];
01207 if (arrayData[j] > max) max = arrayData[j];
01208 }
01209 start = 0;
01210 end = 0;
01211 for (j = 0; j < xImage; j++)
01212 {
01213 if (arrayData[j] > max/2.0)
01214 {
01215 start = j;
01216 break;
01217 }
01218 }
01219 for (j = xImage-1; j >= 0; j--)
01220 {
01221 if (arrayData[j] > max/2.0)
01222 {
01223 end = j;
01224 break;
01225 }
01226 }
01227 *sizeXT = (end - start) * CIRCLE_TO_SQUARE;
01228
01229
01230 if (plotFile)
01231 {
01232 fileName = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01233 title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01234
01235 sprintf (fileName, "TargetFluxMinVarX%d", imageCount);
01236 sprintf (title, "Target Flux Minimum Variance for each Y, beam %d", imageCount);
01237 midiCreatePlotFile2D (fileName, title, "Y", "Flux", 0, centreFluxErr2Min, 0, yImage, 1, 0);
01238
01239 sprintf (fileName, "TargetPositionX%d", imageCount);
01240 sprintf (title, "Target Centre along Y, beam %d", imageCount);
01241 midiCreatePlotFile2D (fileName, title, "Y", "X", 0, centrePositions, 0, yImage, 1, 0);
01242
01243 sprintf (fileName, "TargetX_WidthAlongY%d", imageCount);
01244 sprintf (title, "Target X-Width along Y, beam %d", imageCount);
01245 midiCreatePlotFile2D (fileName, title, "Y", "X-Width", 0, span, 0, yImage, 1, 0);
01246
01247 sprintf (fileName, "TargetMaximumProfileAlongY%d", imageCount);
01248 sprintf (title, "Target Maximum Profile at Y = %f, beam %d", *yT, imageCount);
01249 midiCreatePlotFile2D (fileName, title, "X", "Flux", 0, arrayData, 0, xImage, 1, 0);
01250
01251
01252 free (fileName);
01253 free (title);
01254 }
01255
01256
01257
01258
01259 for (i = 0; i < xImage; i++)
01260 {
01261
01262 for (j = 0; j < yImage; j++)
01263 {
01264 k = i + j * xImage;
01265 arrayData[j] = buffImage[k];
01266 }
01267
01268
01269 midiGaussian_1d_fit (arrayData, yImage, sizeP, ¢re, &siztT, &fluxErr2Min, error);
01270 if (*error)
01271 {
01272 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, "Cannot determine target parameters");
01273 free (arrayData);
01274 free (centrePositions);
01275 free (centreFluxErr2Min);
01276 free (buffImage);
01277 free (span);
01278 return;
01279 }
01280 centrePositions[i] = centre;
01281 centreFluxErr2Min[i] = fluxErr2Min;
01282 span[i] = siztT;
01283 }
01284
01285 *sizeYT = 0;
01286 for (i = 0; i < xImage; i++)
01287 {
01288 if (span[i] > *sizeYT)
01289 {
01290 *xT = i;
01291 *sizeYT = span[i];
01292 }
01293 }
01294
01295
01296 max = 0.0;
01297 for (i = 0; i < yImage; i++)
01298 {
01299
01300 k = *xT + i * xImage;
01301 arrayData[i] = buffImage[k];
01302 if (arrayData[i] > max) max = arrayData[i];
01303 }
01304 start = 0;
01305 end = 0;
01306 for (j = 0; j < yImage; j++)
01307 {
01308 if (arrayData[j] > max/2.0)
01309 {
01310 start = j;
01311 break;
01312 }
01313 }
01314 for (j = yImage-1; j >= 0; j--)
01315 {
01316 if (arrayData[j] > max/2.0)
01317 {
01318 end = j;
01319 break;
01320 }
01321 }
01322 *sizeYT = (end - start) * CIRCLE_TO_SQUARE;
01323
01324
01325 if (plotFile)
01326 {
01327 fileName = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01328 title = (char *) calloc (MAX_STRING_LENGTH, sizeof (char));
01329
01330 sprintf (fileName, "TargetFluxMinVarY%d", imageCount);
01331 sprintf (title, "Target Flux Minimum Variance for each X, beam %d", imageCount);
01332 midiCreatePlotFile2D (fileName, title, "X", "Flux", 0, centreFluxErr2Min, 0, xImage, 1, 0);
01333
01334 sprintf (fileName, "TargetPositionY%d", imageCount);
01335 sprintf (title, "Target Centre along Y, beam %d", imageCount);
01336 midiCreatePlotFile2D (fileName, title, "X", "Y", 0, centrePositions, 0, xImage, 1, 0);
01337
01338 sprintf (fileName, "TargetY_WidthAlongY%d", imageCount);
01339 sprintf (title, "Target Y-Width along Y, beam %d", imageCount);
01340 midiCreatePlotFile2D (fileName, title, "X", "Y-Width", 0, span, 0, xImage, 1, 0);
01341
01342 sprintf (fileName, "TargetMaximumProfileAlongX%d", imageCount);
01343 sprintf (title, "Target Maximum Profile at X = %f, beam %d", *xT, imageCount);
01344 midiCreatePlotFile2D (fileName, title, "Y", "Flux", 0, arrayData, 0, yImage, 1, 0);
01345
01346
01347 free (fileName);
01348 free (title);
01349 }
01350
01351
01352 free (arrayData);
01353 free (centrePositions);
01354 free (centreFluxErr2Min);
01355 free (span);
01356 free (buffImage);
01357
01358 return;
01359 }
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375 void removeSkyBackground (
01376 const char *shutterId,
01377 enum ProcessingMode processing,
01378 ImageFormat *format,
01379 CompressedData *compressed,
01380 int *error)
01381
01382 {
01383
01384
01385 const char routine[] = "removeSkyBackground";
01386 int i, j, S, T, R, X, shift, start;
01387 char lastType;
01388
01389
01390
01391 if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
01392 if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
01393
01394 sprintf (midiMessage, "Removing sky background from %s", shutterId);
01395 midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01396
01397
01398 S = T = 0;
01399 start = 0;
01400 lastType = ' ';
01401 *error = 0;
01402
01403
01404 for (i = 0; i < format->numOfFrames; i++)
01405 {
01406 if (compressed->tarType[i] == 'T')
01407 {
01408 if (lastType == 'U' && T && S)
01409 {
01410 T = 0;
01411 S = 0;
01412 }
01413 T++;
01414 if (S)
01415 {
01416 shift = i-start;
01417 for (j = start; j < start+S; j++)
01418 {
01419 if (compressed->tarType[j] != 'U')
01420 {
01421 if (diagnostic > 4)
01422 {
01423 cpl_msg_info(cpl_func,"%4d-%4d %c-%c \n", j+shift, j,
01424 compressed->tarType[j+shift], compressed->tarType[j]);
01425 fprintf (midiReportPtr, "%4d-%4d %c-%c \n", j+shift, j,
01426 compressed->tarType[j+shift], compressed->tarType[j]);
01427 }
01428 compressed->iFringe[j] = compressed->iFringe[j+shift] - compressed->iFringe[j];
01429 compressed->iFringe1[j] = compressed->iFringe1[j+shift] - compressed->iFringe1[j];
01430 compressed->iFringe2[j] = compressed->iFringe2[j+shift] - compressed->iFringe2[j];
01431 if (processing == DISPERSED)
01432 {
01433 for (R = 0; R < format->numOfRegionsToProcess; R++)
01434 {
01435 for (X = 0; X < format->iXWidth; X++)
01436 {
01437 (((compressed->iDispFringe)[R])[X])[j] = (((compressed->iDispFringe)[R])[X])[j+shift] -
01438 (((compressed->iDispFringe)[R])[X])[j];
01439 }
01440 }
01441 }
01442 }
01443 }
01444 i = j+shift-1;
01445 }
01446 }
01447 else if (compressed->tarType[i] == 'S')
01448 {
01449 if (lastType == 'U' && T && S)
01450 {
01451 S = 0;
01452 T = 0;
01453 }
01454 S++;
01455 if (T)
01456 {
01457 shift = i-start;
01458 for (j = start; j < start+T; j++)
01459 {
01460 if (compressed->tarType[j] != 'U')
01461 {
01462 if (diagnostic > 4)
01463 {
01464 cpl_msg_info(cpl_func,"%4d-%4d %c-%c \n", j, j+shift,
01465 compressed->tarType[j], compressed->tarType[j+shift]);
01466 fprintf (midiReportPtr, "%4d-%4d %c-%c \n", j, j+shift,
01467 compressed->tarType[j], compressed->tarType[j+shift]);
01468 }
01469 compressed->iFringe[j] = compressed->iFringe[j] - compressed->iFringe[j+shift];
01470 compressed->iFringe1[j] = compressed->iFringe1[j] - compressed->iFringe1[j+shift];
01471 compressed->iFringe2[j] = compressed->iFringe2[j] - compressed->iFringe2[j+shift];
01472 if (processing == DISPERSED)
01473 {
01474 for (R = 0; R < format->numOfRegionsToProcess; R++)
01475 {
01476 for (X = 0; X < format->iXWidth; X++)
01477 {
01478 (((compressed->iDispFringe)[R])[X])[j] = (((compressed->iDispFringe)[R])[X])[j] -
01479 (((compressed->iDispFringe)[R])[X])[j+shift];
01480 }
01481 }
01482 }
01483 }
01484 }
01485 i = j+shift-1;
01486 }
01487 }
01488 else
01489 {
01490 if (diagnostic > 4)
01491 {
01492 fprintf (midiReportPtr, "%4d %c \n", i, compressed->tarType[i]);
01493 cpl_msg_info(cpl_func,"%4d %c \n", i, compressed->tarType[i]);
01494 }
01495 lastType = 'U';
01496 if ((S && T) || (!S && !T))
01497 {
01498 start = i+1;
01499 }
01500 }
01501 }
01502
01503 return;
01504 }
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522 long correctTarType (
01523 const char *shutterId,
01524 char *tarType,
01525 float *TimeStamp,
01526 int length,
01527 int *error)
01528 {
01529
01530
01531
01532 const char routine[] = "correctTarType";
01533 int i, j, foundT, foundS, S, T, U, start, end, min, newPair;
01534 char *mask, lastType, lastShot;
01535 long CounterBad=0;
01536
01537
01538
01539 if (diagnostic > 4) cpl_msg_info(cpl_func,"Invoking routine '%s' \n", routine);
01540 if (diagnostic > 4) fprintf(midiReportPtr, "Invoking routine '%s' \n", routine);
01541
01542 sprintf (midiMessage, "Checking tarType inconsistencies for %s", shutterId);
01543 midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01544
01545
01546 foundT = foundS = 0;
01547 T = S = U = 0;
01548 start = 0;
01549 lastType = ' ';
01550 lastShot = ' ';
01551 newPair = 0;
01552 *error = 0;
01553 i=0;
01554 j=0 ;
01555 CounterBad=0;
01556
01557 mask = (char *) calloc (length, sizeof (char));
01558
01559
01560
01561
01562
01563
01564
01565 for (i = 0; i < length; i++)
01566 {
01567 if(isnan(TimeStamp[i]))
01568 {
01569 cpl_msg_warning(cpl_func,"Corrupted time stamp in table! ");
01570 cpl_msg_warning(cpl_func,"Changing target type of frame %d "
01571 "from %c to %c", i, tarType[i], 'U');
01572 tarType[i]='U';
01573 CounterBad++;
01574 if(i>0 && i<(length-1) && tarType[i-1]=='S' && tarType[i+1]=='S')
01575 {
01576 j=i-1;
01577 while(tarType[j]!='T' && j>=0)
01578 {
01579 cpl_msg_warning(cpl_func,"Changing target type of frame %d "
01580 "from %c to %c", j, tarType[j], 'U');
01581 tarType[j]='U';
01582 CounterBad++;
01583 j--;
01584 }
01585 }
01586 if(i>0 && i<(length-1) && tarType[i-1]=='T' && tarType[i+1]=='T')
01587 {
01588 j=i-1;
01589 while(tarType[j]!='S' && j>=0)
01590 {
01591 cpl_msg_warning(cpl_func,"Changing target type of frame %d "
01592 "from %c to %c", j, tarType[j], 'U');
01593 tarType[j]='U';
01594 CounterBad++;
01595 j--;
01596 }
01597
01598 }
01599
01600 }
01601 }
01602
01603 for (i = 1; i < length-2; i++)
01604 {
01605 if(tarType[i-1]=='U' && (tarType[i]=='S' || tarType[i]=='T') &&
01606 tarType[i+1]=='U')
01607 {
01608 cpl_msg_warning(cpl_func,"UTU or USU sequence found, "
01609 "correcting to UUU");
01610 tarType[i]='U';
01611 }
01612 }
01613
01614
01615 for (i = 0; i < length-1; i++)
01616 {
01617 if(tarType[i]=='T' && tarType[i+1]=='S')
01618 {
01619 cpl_msg_warning(cpl_func,"Switching from T to S without U at "
01620 "frame %d", i);
01621 cpl_msg_warning(cpl_func,"Changing target type of frame %d and %d"
01622 " to %c", i, i+1, 'U');
01623 tarType[i]='U';
01624 CounterBad++;
01625 tarType[i+1]='U';
01626 CounterBad++;
01627 }
01628
01629 if(tarType[i]=='S' && tarType[i+1]=='T')
01630 {
01631 cpl_msg_warning(cpl_func,"Switching from S to T without U at "
01632 "frame %d", i);
01633 cpl_msg_warning(cpl_func,"Changing target type of frame %d and %d"
01634 " to %c", i, i+1, 'U');
01635 tarType[i]='U';
01636 CounterBad++;
01637 tarType[i+1]='U';
01638 CounterBad++;
01639 }
01640
01641 }
01642
01643
01644 for (i = 0; i < length; i++)
01645 {
01646
01647 if (tarType[i] == 'T')
01648 {
01649 if (lastType == 'S')
01650 {
01651 sprintf (midiMessage, "Switching from S to T without U at frame %d. QCLOG", i);
01652 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01653 *error = 1;
01654 }
01655 if (lastShot == 'T')
01656 {
01657 sprintf (midiMessage, "Switching from T to T without S at frame %d. QCLOG", i);
01658 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01659 *error = 1;
01660 }
01661 T++;
01662 mask[i] = 'T';
01663 lastType = 'T';
01664 newPair = 0;
01665 }
01666
01667 else if (tarType[i] == 'S')
01668 {
01669 if (lastType == 'T')
01670 {
01671 sprintf (midiMessage, "Switching from T to S without U at frame %d. QCLOG", i);
01672 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01673 *error = 1;
01674 }
01675 if (lastShot == 'S')
01676 {
01677 sprintf (midiMessage, "Switching from S to S without T at frame %d. QCLOG", i);
01678 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01679 *error = 1;
01680 }
01681 S++;
01682 mask[i] = 'S';
01683 lastType = 'S';
01684 newPair = 0;
01685 }
01686 else
01687 {
01688 mask[i] = 'U';
01689 if (lastType == 'T')
01690 {
01691 lastShot = 'T';
01692 foundT = 1;
01693 }
01694 if (lastType == 'S')
01695 {
01696 lastShot = 'S';
01697 foundS = 1;
01698 }
01699 lastType = 'U';
01700 if (newPair)
01701 start++;
01702 }
01703
01704 if ((foundS && foundT) || (foundS && T && (i == length-1)) || (foundT && S && (i == length-1)))
01705 {
01706 end = i+1;
01707 if (S < T)
01708 min = S;
01709 else
01710 min = T;
01711
01712 T = S = 0;
01713 for (j = start; j < end; j++)
01714 {
01715 if (mask[j] == 'T')
01716 {
01717 T++;
01718 if (T > min)
01719 {
01720 mask[j] = 'U';
01721 sprintf (midiMessage, "Chopping inconsistency. Found extra 'T' at frame %d. Corrected. QCLOG", j);
01722 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01723 }
01724 }
01725 else if (mask[j] == 'S')
01726 {
01727 S++;
01728 if (S > min)
01729 {
01730 mask[j] = 'U';
01731 sprintf (midiMessage, "Chopping inconsistency. Found extra 'S' at frame %d. Corrected. QCLOG", j);
01732 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01733 }
01734 }
01735 }
01736 T = S = 0;
01737 if (foundS && foundT)
01738 {
01739 newPair = 1;
01740 start = i;
01741 --i;
01742 }
01743 foundS = foundT = 0;
01744 }
01745 else if ((!foundS && T && (i == length-1)) || (!foundT && S && (i == length-1)))
01746 {
01747 for (j = start; j <= i; j++)
01748 {
01749 mask[j] = 'U';
01750 sprintf (midiMessage, "Chopping inconsistency. Found extra 'S' or 'T' at frame %d. Corrected. QCLOG", j);
01751 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
01752 }
01753 }
01754 }
01755
01756
01757 for (i = 0; i < length; i++)
01758 tarType[i] = mask[i];
01759
01760
01761 if (diagnostic > 4)
01762 {
01763 for (i = 0; i < length; i++)
01764 {
01765 cpl_msg_info(cpl_func,"%4d %c \n", i, tarType[i]);
01766 fprintf (midiReportPtr, "%4d %c \n", i, tarType[i]);
01767 }
01768 }
01769
01770
01771 free (mask);
01772
01773 return CounterBad;
01774 }
01775
01776