26 #include "midiGlobal.h"
28 #include "imageProcessing.h"
29 #include "statistics.h"
30 #include "errorHandling.h"
31 #include "diagnostics.h"
32 #include "cpl_image_io.h"
33 #include "cpl_image_basic.h"
34 #include "complex_midi.h"
41 #define CIRCLE_TO_SQUARE (0.350)
63 void getUndispersedPowerSpectrum (
64 ImageFormat *imageFormat,
65 CompressedData *compressed)
70 const char routine[] =
"getUndispersedPowerSpectrum";
72 struct Complex *input2ft;
74 float accum, *allSpectrumPtr, *dcLevelsPtr;
78 if (diagnostic > 4) cpl_msg_info(cpl_func,
"Invoking routine '%s' \n", routine);
79 if (diagnostic > 4) fprintf (midiReportPtr,
"Invoking routine '%s' \n", routine);
82 SetFFTsize (imageFormat->fftsize);
85 FFTarray = (
struct Complex *) malloc (MAXFFTSIZE * (
sizeof(
struct Complex)));
86 input2ft = (
struct Complex *) malloc (imageFormat->fftsize * (
sizeof(
struct Complex)));
89 allSpectrumPtr = compressed->allSpectrum;
90 dcLevelsPtr = compressed->dcLevels;
92 for (R = 0; R < REGIONS_UNDISPERSED; R++)
95 inputPtr = compressed->iFringe;
97 inputPtr = compressed->iFringe1;
99 inputPtr = compressed->iFringe2;
102 for (s = 0; s < imageFormat->numOfScans; s++)
105 if (!(compressed->badScanList[s]))
108 memset (input2ft, 0, (
sizeof(
struct Complex)) * imageFormat->fftsize);
110 for (i = 0; i < imageFormat->framesPerScan; i++)
116 input2ft[i].r = *inputPtr;
121 *dcLevelsPtr = accum / ((float) imageFormat->framesPerScan);
124 for (i = 0; i < imageFormat->framesPerScan; i++)
125 input2ft[i].r -= *dcLevelsPtr;
131 FFT (input2ft, FFTlevel);
134 for (i = 0; i < imageFormat->fftsize/2; i++)
136 *allSpectrumPtr = Cmag2(FFTarray[i]);
144 for (i = 0; i < imageFormat->framesPerScan; i++)
146 for (i = 0; i < imageFormat->fftsize/2; i++)
155 if (strcmp (imageFormat->beamCombiner,
"SCI_PHOT") == 0)
156 midiCreatePlotFile2D (
"SpectrumCombinedDATA2DATA3",
"DATA2-DATA3, DATA2 and DATA3 Spectrum",
157 "FFT bins for each Scan",
"Power Spectrum", 0, compressed->allSpectrum, 0,
158 imageFormat->allSpectrumLength, 1, 0);
160 midiCreatePlotFile2D (
"SpectrumCombinedDATA1DATA2",
"DATA1-DATA2, DATA1 and DATA2 Spectrum",
161 "FFT bins for each Scan",
"Power Spectrum", 0, compressed->allSpectrum, 0,
162 imageFormat->allSpectrumLength, 1, 0);
185 void normalizeSignal (
192 const char routine[] =
"normalizeSignal";
198 if (diagnostic > 4) cpl_msg_info(cpl_func,
"Invoking routine '%s' \n", routine);
199 if (diagnostic > 4) fprintf(midiReportPtr,
"Invoking routine '%s' \n", routine);
202 maxSignal = signal[0];
203 for (i = 0; i < arraySize; i++)
204 if (signal[i] > maxSignal) maxSignal = signal[i];
207 for (i = 0; i < arraySize; i++)
208 signal[i] /= maxSignal;
228 void computeFrameFlux (
242 const char routine[] =
"computeFrameFlux";
243 int i, yWin, xWin, fileSpan, frameSpan, subWindowSize;
247 if (diagnostic > 4) cpl_msg_info(cpl_func,
"Invoking routine '%s' \n", routine);
248 if (diagnostic > 4) fprintf (midiReportPtr,
"Invoking routine '%s' \n", routine);
256 subWindowSize = format->iXWidth * format->iYWidth;
257 fileSpan = frame * subWindowSize;
258 for (yWin = 0; yWin < format->iYWidth; yWin++)
260 frameSpan = yWin * format->iXWidth;
261 for (xWin = 0; xWin < format->iXWidth; xWin++)
264 i = fileSpan + frameSpan + xWin;
265 if (isnan (inData[i]))
267 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
"Corrupted data");
271 if (xWin >= (
int) (target->xCoord) && xWin <= (
int) (target->dxCoord) &&
272 yWin >= (
int) (target->yCoord) && yWin <= (
int) (target->dyCoord))
274 *flux += (float) (inData[i] + scalingOffset);
282 cpl_msg_info(cpl_func,
"\nCoordinates and flux results for frame %d: \n", frame);
283 cpl_msg_info(cpl_func,
"====================================== \n");
284 cpl_msg_info(cpl_func,
" Image coordinates = %f %f %f %f\n", target->xCoord, target->yCoord, target->dxCoord, target->dyCoord);
285 cpl_msg_info(cpl_func,
" Flux = %f\n", *flux);
286 cpl_msg_info(cpl_func,
" Pixel count = %d\n", *pixelCount);
287 fprintf (midiReportPtr,
"\nCoordinates and flux results for frame %d: \n", frame);
288 fprintf (midiReportPtr,
"====================================== \n");
289 fprintf (midiReportPtr,
" Image coordinates = %f %f %f %f\n", target->xCoord, target->yCoord, target->dxCoord, target->dyCoord);
290 fprintf (midiReportPtr,
" Flux = %f\n", *flux);
291 fprintf (midiReportPtr,
" Pixel count = %d\n", *pixelCount);
312 void computeImageFlux (
324 const char routine[] =
"computeImageFlux";
325 int i, yWin, xWin, frameSpan;
329 if (diagnostic > 4) cpl_msg_info(cpl_func,
"Invoking routine '%s' \n", routine);
330 if (diagnostic > 4) fprintf (midiReportPtr,
"Invoking routine '%s' \n", routine);
338 for (yWin = 0; yWin < format->iYWidth; yWin++)
340 frameSpan = yWin * format->iXWidth;
341 for (xWin = 0; xWin < format->iXWidth; xWin++)
344 i = frameSpan + xWin;
345 if (xWin >= (
int) (target->xCoord) && xWin <= (
int) (target->dxCoord) &&
346 yWin >= (
int) (target->yCoord) && yWin <= (
int) (target->dyCoord))
348 *flux += (float) (image[i]);
370 void createAveragedImage (
379 const char routine[] =
"createAveragedImage";
380 int i, count, pixel, frame, subWindowSize;
384 if (diagnostic > 4) cpl_msg_info(cpl_func,
"Invoking routine '%s' \n", routine);
385 if (diagnostic > 4) fprintf (midiReportPtr,
"Invoking routine '%s' \n", routine);
388 subWindowSize = format->iXWidth * format->iYWidth;
390 for (pixel = 0; pixel < subWindowSize; pixel++)
395 for (frame = 0; frame < format->numOfFrames; frame++)
398 i = frame * subWindowSize + pixel;
399 if (isnan (inData[i]))
401 sprintf (midiMessage,
"Found bad pixel on frame %d", frame);
402 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
407 image[pixel] += (float) (inData[i] + scalingOffset);
412 image[pixel] /= count;
435 void createFitsImage (
436 const char *regionOrFile,
446 const char routine[] =
"createFitsImage";
447 qfits_header *pHeaderOut;
450 char *sWidthX, *sWidthY, *stringOut;
455 if (diagnostic > 4) cpl_msg_info(cpl_func,
"Invoking routine '%s' \n", routine);
456 if (diagnostic > 4) fprintf(midiReportPtr,
"Invoking routine '%s' \n", routine);
458 cpl_msg_info(cpl_func,
"\nCreating an image from %s for batch %d \n", regionOrFile, batchNumber);
459 cpl_msg_info(cpl_func,
"----------------------------------- \n");
460 fprintf (midiReportPtr,
"\nCreating an image from %s for batch %d \n", regionOrFile, batchNumber);
461 fprintf (midiReportPtr,
"----------------------------------- \n");
464 stringOut = (
char *) calloc (MAX_STRING_LENGTH,
sizeof (
char));
465 sWidthY = (
char *) calloc (MIN_STRING_LENGTH,
sizeof (
char));
466 sWidthX = (
char *) calloc (MIN_STRING_LENGTH,
sizeof (
char));
469 sprintf (sWidthY,
"%d", yLength);
470 sprintf (sWidthX,
"%d", xLength);
473 if (diagnostic)cpl_msg_info(cpl_func,
" Extracting primary header from input FITS file %s \n", inFitsName);
474 fprintf(midiReportPtr,
" Extracting primary header from input FITS file %s \n", inFitsName);
475 pHeaderOut = qfits_header_read (inFitsName);
476 if (pHeaderOut == NULL)
478 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
"Cannot extract primary header from input FITS file");
486 qfits_header_mod (pHeaderOut,
"BITPIX",
"-32",
"number of bits per pixel");
487 qfits_header_mod (pHeaderOut,
"NAXIS",
"2",
"number of data axes");
488 qfits_header_add (pHeaderOut,
"NAXIS1", sWidthX,
"",
"");
489 qfits_header_add (pHeaderOut,
"NAXIS2", sWidthY,
"",
"");
504 qfits_header_mod (pHeaderOut,
"INSTRUME",
"MIDI",
"MIDI Raw Data Display FITS created by DRS pipeline" );
507 sprintf (stringOut,
"%s%s.%s.fits", outFileDir, outRootName, name);
508 if (stat (stringOut, &buf) == 0)
remove (stringOut);
509 if ((imagePtr = fopen (stringOut,
"w")) == NULL)
511 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
"Cannot create Image of the data file");
515 qfits_header_destroy (pHeaderOut);
519 cpl_msg_info(cpl_func,
" Created an Image file: %s \n", stringOut);
520 fprintf (midiReportPtr,
" Created an Image file: %s \n", stringOut);
522 qfits_header_dump (pHeaderOut, imagePtr);
526 qfits_header_destroy (pHeaderOut);
529 qdImage.filename = stringOut;
530 qdImage.npix = xLength * yLength;
531 qdImage.ptype = PTYPE_FLOAT;
532 qdImage.fbuf = image;
533 qdImage.out_ptype = BPP_IEEE_FLOAT;
535 qfits_pixdump (&qdImage);
538 qfits_zeropad((
char *)stringOut);
562 void midiGaussianFit (
581 const char routine[] =
"midiGaussianFit";
583 double sigX, sigY, norm;
587 if (diagnostic > 4) cpl_msg_info(cpl_func,
"Invoking routine '%s' \n", routine);
588 if (diagnostic > 4) fprintf (midiReportPtr,
"Invoking routine '%s' \n", routine);
599 midiGetFWHM (fileNumber, image, xImage, yImage, sizeP, xT, yT, sizeXT, sizeYT, error);
600 if (*error) midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
"Cannot find centroid");
602 else if (dimension == 2)
605 cplImage = cpl_image_wrap_float (xImage, yImage, image);
608 if (cpl_image_fit_gaussian (cplImage, xP, yP, sizeP, &norm, xT, yT, &sigX, &sigY, NULL, NULL)!=CPL_ERROR_NONE){
610 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
"Cannot find the centroid");
611 cpl_image_unwrap (cplImage);
615 *sizeXT = 0.5 * (sigX + sigY);
616 *sizeYT = 0.5 * (sigX + sigY);
618 cpl_image_unwrap (cplImage);
623 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
"Invalid dimensionality");
624 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
"Cannot find centroid");
631 cpl_msg_info(cpl_func,
" Target centroid = (x, y, X-Width, Y-Width) %f %f %f %f\n",
632 *xT, *yT, *sizeXT, *sizeYT);
633 fprintf (midiReportPtr,
" Target centroid = (x, y, X-Width, Y-Width) %f %f %f %f\n",
634 *xT, *yT, *sizeXT, *sizeYT);
653 void midiGaussian_1d_fit (
666 const char routine[] =
"midiGaussian_1d_fit";
667 int i, j, l, searchLimit, halfGauss;
668 float *gaussian, sigma, exponentConst, fluxErr2;
669 char *fileString, *title;
673 if (diagnostic > 4) cpl_msg_info(cpl_func,
"Invoking routine '%s' \n", routine);
674 if (diagnostic > 4) fprintf (midiReportPtr,
"Invoking routine '%s' \n", routine);
684 if (diagnostic > 2) cpl_msg_info(cpl_func,
"search span before = %d\n", sizeS);
685 if (!(sizeS & 1)) sizeS += 1;
686 if (diagnostic > 2) cpl_msg_info(cpl_func,
"search span after = %d\n", sizeS);
687 searchLimit = length - sizeS;
688 if (searchLimit <= sizeS)
691 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
"Search window too large");
696 gaussian = (
float *) calloc (sizeS,
sizeof (
float));
699 halfGauss = (sizeS >> 1);
703 midiCreatePlotFile2D (
"InputArray",
"Input Array",
"X",
"Y", 0, array, 0, length, 1, 0);
706 for (l = 0; l < GAUSSIAN_SIGMA_SPAN; l++)
710 exponentConst = (-0.5) / (sigma * sigma);
711 for (i = -halfGauss; i <= halfGauss; i++)
714 gaussian[j] = exp (exponentConst * i * i);
715 if (plotFile && diagnostic > 2)
717 fileString = (
char *) calloc (MAX_STRING_LENGTH,
sizeof (
char));
718 title = (
char *) calloc (MAX_STRING_LENGTH,
sizeof (
char));
719 sprintf (fileString ,
"GaussianWithSigma%f", sigma);
720 sprintf (title ,
"Gaussian with %f Sigma", sigma);
721 midiCreatePlotFile2D (fileString, title,
"Span",
"Sigma", 0, gaussian, 0, sizeS, 1, 0);
726 cpl_msg_info(cpl_func,
" Gaussian %d = %8.8f\n", i, gaussian[j]);
727 fprintf (midiReportPtr,
" Gaussian %d = %8.8f\n", i, gaussian[j]);
734 for (i = 0; i < searchLimit; i++)
738 for (j = 0; j < sizeS; j++)
739 fluxErr2 += ( (gaussian[j] - array[i+j]) * (gaussian[j] - array[i+j]) );
742 if (l == 0 && i == 0) *fluxErr2Min = fluxErr2;
745 if (fluxErr2 < *fluxErr2Min)
747 *fluxErr2Min = fluxErr2;
748 *centre = (float) (i + 0.5 * sizeS);
749 *sizeT = (float) (3.0 * sigma);
775 float midiGaussianSmooth (
786 const char routine[] =
"midiGaussianSmooth";
787 int i, j, l, start, end, halfGauss;
788 float *gaussian, sigma, exponentConst, fluxErr2, xCPH, fluxErr2Min;
789 char *fileString, *title;
793 if (diagnostic > 4) cpl_msg_info(cpl_func,
"Invoking routine '%s' \n", routine);
794 if (diagnostic > 4) fprintf (midiReportPtr,
"Invoking routine '%s' \n", routine);
803 if (diagnostic > 2) cpl_msg_info(cpl_func,
"search span before = %d\n", searchSpan);
804 if (!(searchSpan & 1)) searchSpan += 1;
805 if (diagnostic > 2) cpl_msg_info(cpl_func,
"search span after = %d\n", searchSpan);
806 halfGauss = (searchSpan >> 1);
807 start = peakIn - searchSpan;
808 end = peakIn + searchSpan;
809 if ((end > length) || (start < 0))
812 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
"Search window too large");
817 gaussian = (
float *) calloc (searchSpan,
sizeof (
float));
820 for (l = 0; l < GAUSSIAN_SIGMA_SPAN; l++)
824 exponentConst = (-0.5) / (sigma * sigma);
825 for (i = -halfGauss; i <= halfGauss; i++)
828 gaussian[j] = exp (exponentConst * i * i);
829 if (plotFile && diagnostic > 2)
831 fileString = (
char *) calloc (MAX_STRING_LENGTH,
sizeof (
char));
832 title = (
char *) calloc (MAX_STRING_LENGTH,
sizeof (
char));
833 sprintf (fileString ,
"GaussianWithSigma%f", sigma);
834 sprintf (title ,
"Gaussian with %f Sigma", sigma);
835 midiCreatePlotFile2D (fileString, title,
"Span",
"Sigma", 0, gaussian, 0, searchSpan, 1, 0);
836 cpl_msg_info(cpl_func,
" Gaussian %d = %8.8f\n", i, gaussian[j]);
837 fprintf (midiReportPtr,
" Gaussian %d = %8.8f\n", i, gaussian[j]);
843 for (i = start; i < end; i++)
847 for (j = 0; j < searchSpan; j++)
848 fluxErr2 += ( (gaussian[j] - array[i+j]) * (gaussian[j] - array[i+j]) );
851 if ((l == 0) && (i == start))
852 fluxErr2Min = fluxErr2;
855 if (fluxErr2 < fluxErr2Min)
857 fluxErr2Min = fluxErr2;
858 xCPH = (float) (i + 0.5 * searchSpan);
883 void getBadScansFromSpectrumUndisp (
884 FilterData *filterInfo,
886 CompressedData *compressed,
891 const char routine[] =
"getBadScansFromSpectrumUndisp";
897 if (diagnostic > 4) cpl_msg_info(cpl_func,
"Invoking routine '%s' \n", routine);
898 if (diagnostic > 4) fprintf(midiReportPtr,
"Invoking routine '%s' \n", routine);
900 cpl_msg_info(cpl_func,
"\nRejecting scans based on Signal/Noise \n");
901 cpl_msg_info(cpl_func,
"------------------------------------- \n");
902 fprintf (midiReportPtr,
"\nRejecting scans based on Signal/Noise \n");
903 fprintf (midiReportPtr,
"------------------------------------- \n");
909 rejectScansOnWeakSNRUndisp (filterInfo, format, compressed, error);
912 format->numOfScansRejected = 0;
913 format->numOfScansProcessed = 0;
914 for (i = 0; i < format->numOfScans; i++)
916 if (compressed->badScanList[i])
917 format->numOfScansRejected++;
919 format->numOfScansProcessed = format->numOfScans - format->numOfScansRejected;
922 if (plotFile && diagnostic)
924 tempArray = (
float *) calloc (format->numOfScans, sizeof (
float));
925 for (i = 0; i < format->numOfScans; i++)
927 if (compressed->badScanList[i] == 0)
930 tempArray[i] = compressed->badScanList[i];
932 midiCreatePlotFile2D (
"BadScanList",
"Bad Scan List",
"Scan",
"Failure ID",
933 0, tempArray, 0, format->numOfScans, 1, 0);
938 if (diagnostic) cpl_msg_info(cpl_func,
"\nBad Scan List \n");
939 if (diagnostic) cpl_msg_info(cpl_func,
"------------- \n");
940 fprintf (midiReportPtr,
"\nBad Scan List QCLOG \n");
941 fprintf (midiReportPtr,
"------------- QCLOG \n");
942 for (i = 0; i < format->numOfScans; i++)
944 if (diagnostic) cpl_msg_info(cpl_func,
"%3d %3d \n", i, compressed->badScanList[i]);
945 fprintf (midiReportPtr,
"%3d %3d QCLOG \n", i, compressed->badScanList[i]);
948 cpl_msg_info(cpl_func,
"Number of scans to process = %3d \n", format->numOfScansProcessed);
949 cpl_msg_info(cpl_func,
"Number of scans rejected = %3d \n", format->numOfScansRejected);
950 fprintf (midiReportPtr,
"Number of scans to process = %3d QCLOG \n", format->numOfScansProcessed);
951 fprintf (midiReportPtr,
"Number of scans rejected = %3d QCLOG \n", format->numOfScansRejected);
954 cpl_msg_info(cpl_func,
"Failure ID \n");
955 cpl_msg_info(cpl_func,
"---------- \n");
956 cpl_msg_info(cpl_func,
"1 = Bit 1, indicates a TIME error \n");
957 cpl_msg_info(cpl_func,
"2 = Bit 2, indicates an LOCALOPD error \n");
958 cpl_msg_info(cpl_func,
"4 = Bit 3, indicates an OPD error \n");
959 cpl_msg_info(cpl_func,
"8 = Bit 4, indicates a Bad DATA \n");
960 cpl_msg_info(cpl_func,
"16 = Bit 5, indicates a chopping problem (TARTYPE2) \n");
961 cpl_msg_info(cpl_func,
"32 = Bit 6, indicates a Delay Line Jump \n");
962 cpl_msg_info(cpl_func,
"64 = Bit 7, indicates an Unwanted Region \n");
963 cpl_msg_info(cpl_func,
"128 = Bit 8, indicates a Weak Signal/Noise \n");
964 cpl_msg_info(cpl_func,
"256 = Bit 9, indicates a SKY Background \n");
965 cpl_msg_info(cpl_func,
"512 = Bit 10, indicates a TARTYPE Cross error. e.g. region 0 different to region 1 \n");
966 cpl_msg_info(cpl_func,
"\nHence a number such as 168 indicates bits 4, 6 and 8 were set \n\n");
969 fprintf (midiReportPtr,
"Failure ID QCLOG \n");
970 fprintf (midiReportPtr,
"---------- QCLOG \n");
971 fprintf (midiReportPtr,
"1 = Bit 1, indicates a TIME error \n");
972 fprintf (midiReportPtr,
"2 = Bit 2, indicates an LOCALOPD error \n");
973 fprintf (midiReportPtr,
"4 = Bit 3, indicates an OPD error \n");
974 fprintf (midiReportPtr,
"8 = Bit 4, indicates a Bad DATA \n");
975 fprintf (midiReportPtr,
"16 = Bit 5, indicates a chopping problem (TARTYPE2) \n");
976 fprintf (midiReportPtr,
"32 = Bit 6, indicates a Delay Line Jump \n");
977 fprintf (midiReportPtr,
"64 = Bit 7, indicates an Unwanted Region \n");
978 fprintf (midiReportPtr,
"128 = Bit 8, indicates a Weak Signal/Noise \n");
979 fprintf (midiReportPtr,
"256 = Bit 9, indicates a SKY Background \n");
980 fprintf (midiReportPtr,
"512 = Bit 10, indicates a TARTYPE Cross error. e.g. region 0 different to region 1 \n");
981 fprintf (midiReportPtr,
"\nHence a number such as 168 indicates bits 4, 6 and 8 were set QCLOG \n\n");
983 if (format->numOfScansProcessed < 1)
985 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
"No Scan to process");
1008 void rejectScansOnWeakSNRUndisp (
1009 FilterData *filterInfo,
1010 ImageFormat *format,
1011 CompressedData *compressed,
1016 const char routine[] =
"rejectScansOnWeakSNRUndisp";
1017 float *sigPtr, *spectrum, median, peak, ratio, calib;
1018 int i, j, fftSizeHalf, peakIndex, loF, hiF;
1019 char *fileName, *title;
1023 if (diagnostic > 4) cpl_msg_info(cpl_func,
"Invoking routine '%s' \n", routine);
1024 if (diagnostic > 4) fprintf(midiReportPtr,
"Invoking routine '%s' \n", routine);
1028 fftSizeHalf = (format->fftsize >> 1);
1031 calib = format->optFreqCal / ((float) format->fftsize);
1032 loF = (int) (filterInfo->optFreqLo / calib);
1033 hiF = (int) (filterInfo->optFreqHi / calib);
1034 if (hiF > format->fftsize/2) hiF = format->fftsize/2;
1037 spectrum = (
float *) calloc (fftSizeHalf,
sizeof (
float));
1040 for (i = 0; i < format->numOfScans; i++)
1042 sigPtr = compressed->allSpectrum + i * fftSizeHalf;
1045 if (!(compressed->badScanList[i]))
1048 for (j = 0; j < fftSizeHalf; j++)
1049 spectrum[j] = *sigPtr++;
1052 peak = signalPeak (spectrum, 0, fftSizeHalf, &peakIndex);
1053 median = signalMedian (spectrum, 0, fftSizeHalf);
1054 ratio = peak/median;
1057 if ((ratio < 10.0) || (peakIndex < loF) || (peakIndex > hiF))
1058 compressed->badScanList[i] |= BSL_SNR_ERROR;
1061 if (plotFile && diagnostic > 2)
1063 if (compressed->badScanList[i]) cpl_msg_info(cpl_func,
"\n <<ERROR>>: Scan %3d rejected \n\n", i);
1064 cpl_msg_info(cpl_func,
" Expected low frequency index = %3d \n", loF);
1065 cpl_msg_info(cpl_func,
" Expected high frequency index = %3d \n", hiF);
1066 cpl_msg_info(cpl_func,
" Found peak index at = %3d \n", peakIndex);
1067 cpl_msg_info(cpl_func,
" peak/median = %f \n", ratio);
1068 if (compressed->badScanList[i]) fprintf (midiReportPtr,
"\n <<ERROR>>: Scan %3d rejected \n\n", i);
1069 fprintf (midiReportPtr,
" Expected low frequency index = %3d \n", loF);
1070 fprintf (midiReportPtr,
" Expected high frequency index = %3d \n", hiF);
1071 fprintf (midiReportPtr,
" Found peak index at = %3d \n", peakIndex);
1072 fprintf (midiReportPtr,
" peak/median = %f \n", ratio);
1074 fileName = (
char *) calloc (MAX_STRING_LENGTH,
sizeof (
char));
1075 title = (
char *) calloc (MAX_STRING_LENGTH,
sizeof (
char));
1076 sprintf (fileName,
"SpectrumScan%d", i);
1077 sprintf (title,
"Power Spectrum. Scan %d", i);
1078 midiCreatePlotFile2D (fileName, title,
"Frequancy bin",
"Power Spectrum",
1079 1, spectrum, 0, fftSizeHalf, 1, 0);
1125 const char routine[] =
"midiGetFWHM";
1126 int i, j, k, l, length, maxLength, start, end;
1127 float *arrayData, centre, *centrePositions, *centreFluxErr2Min,
1128 fluxErr2Min, *span, siztT, fluxMax, *buffImage, max;
1129 char *fileName, *title;
1133 if (diagnostic > 4) cpl_msg_info(cpl_func,
"Invoking routine '%s' \n", routine);
1134 if (diagnostic > 4) fprintf (midiReportPtr,
"Invoking routine '%s' \n", routine);
1140 length = xImage * yImage;
1141 maxLength = (xImage > yImage) ? xImage : yImage;
1142 arrayData = (
float *) calloc (maxLength,
sizeof (
float));
1143 centrePositions = (
float *) calloc (maxLength,
sizeof (
float));
1144 centreFluxErr2Min = (
float *) calloc (maxLength,
sizeof (
float));
1145 span = (
float *) calloc (maxLength,
sizeof (
float));
1146 buffImage = (
float *) calloc (length,
sizeof (
float));
1149 for (i = 0; i < length; i++)
1150 buffImage[i] = image[i];
1153 fluxMax = buffImage[0];
1154 for (i = 0; i < length; i++)
1155 if (buffImage[i] > fluxMax) fluxMax = buffImage[i];
1156 for (i = 0; i < length; i++)
1157 buffImage[i] /= fluxMax;
1162 for (i = 0; i < yImage; i++)
1165 for (j = 0; j < xImage; j++)
1168 arrayData[j] = buffImage[k];
1172 midiGaussian_1d_fit (arrayData, xImage, sizeP, ¢re, &siztT, &fluxErr2Min, error);
1175 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
"Cannot determine target parameters");
1177 free (centrePositions);
1178 free (centreFluxErr2Min);
1183 centrePositions[i] = centre;
1184 centreFluxErr2Min[i] = fluxErr2Min;
1190 for (i = 0; i < yImage; i++)
1192 if (span[i] > *sizeXT)
1202 for (j = 0; j < xImage; j++)
1206 arrayData[j] = buffImage[k];
1207 if (arrayData[j] > max) max = arrayData[j];
1211 for (j = 0; j < xImage; j++)
1213 if (arrayData[j] > max/2.0)
1219 for (j = xImage-1; j >= 0; j--)
1221 if (arrayData[j] > max/2.0)
1227 *sizeXT = (end - start) * CIRCLE_TO_SQUARE;
1232 fileName = (
char *) calloc (MAX_STRING_LENGTH,
sizeof (
char));
1233 title = (
char *) calloc (MAX_STRING_LENGTH,
sizeof (
char));
1235 sprintf (fileName,
"TargetFluxMinVarX%d", imageCount);
1236 sprintf (title,
"Target Flux Minimum Variance for each Y, beam %d", imageCount);
1237 midiCreatePlotFile2D (fileName, title,
"Y",
"Flux", 0, centreFluxErr2Min, 0, yImage, 1, 0);
1239 sprintf (fileName,
"TargetPositionX%d", imageCount);
1240 sprintf (title,
"Target Centre along Y, beam %d", imageCount);
1241 midiCreatePlotFile2D (fileName, title,
"Y",
"X", 0, centrePositions, 0, yImage, 1, 0);
1243 sprintf (fileName,
"TargetX_WidthAlongY%d", imageCount);
1244 sprintf (title,
"Target X-Width along Y, beam %d", imageCount);
1245 midiCreatePlotFile2D (fileName, title,
"Y",
"X-Width", 0, span, 0, yImage, 1, 0);
1247 sprintf (fileName,
"TargetMaximumProfileAlongY%d", imageCount);
1248 sprintf (title,
"Target Maximum Profile at Y = %f, beam %d", *yT, imageCount);
1249 midiCreatePlotFile2D (fileName, title,
"X",
"Flux", 0, arrayData, 0, xImage, 1, 0);
1259 for (i = 0; i < xImage; i++)
1262 for (j = 0; j < yImage; j++)
1265 arrayData[j] = buffImage[k];
1269 midiGaussian_1d_fit (arrayData, yImage, sizeP, ¢re, &siztT, &fluxErr2Min, error);
1272 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__,
"Cannot determine target parameters");
1274 free (centrePositions);
1275 free (centreFluxErr2Min);
1280 centrePositions[i] = centre;
1281 centreFluxErr2Min[i] = fluxErr2Min;
1286 for (i = 0; i < xImage; i++)
1288 if (span[i] > *sizeYT)
1297 for (i = 0; i < yImage; i++)
1300 k = *xT + i * xImage;
1301 arrayData[i] = buffImage[k];
1302 if (arrayData[i] > max) max = arrayData[i];
1306 for (j = 0; j < yImage; j++)
1308 if (arrayData[j] > max/2.0)
1314 for (j = yImage-1; j >= 0; j--)
1316 if (arrayData[j] > max/2.0)
1322 *sizeYT = (end - start) * CIRCLE_TO_SQUARE;
1327 fileName = (
char *) calloc (MAX_STRING_LENGTH,
sizeof (
char));
1328 title = (
char *) calloc (MAX_STRING_LENGTH,
sizeof (
char));
1330 sprintf (fileName,
"TargetFluxMinVarY%d", imageCount);
1331 sprintf (title,
"Target Flux Minimum Variance for each X, beam %d", imageCount);
1332 midiCreatePlotFile2D (fileName, title,
"X",
"Flux", 0, centreFluxErr2Min, 0, xImage, 1, 0);
1334 sprintf (fileName,
"TargetPositionY%d", imageCount);
1335 sprintf (title,
"Target Centre along Y, beam %d", imageCount);
1336 midiCreatePlotFile2D (fileName, title,
"X",
"Y", 0, centrePositions, 0, xImage, 1, 0);
1338 sprintf (fileName,
"TargetY_WidthAlongY%d", imageCount);
1339 sprintf (title,
"Target Y-Width along Y, beam %d", imageCount);
1340 midiCreatePlotFile2D (fileName, title,
"X",
"Y-Width", 0, span, 0, xImage, 1, 0);
1342 sprintf (fileName,
"TargetMaximumProfileAlongX%d", imageCount);
1343 sprintf (title,
"Target Maximum Profile at X = %f, beam %d", *xT, imageCount);
1344 midiCreatePlotFile2D (fileName, title,
"Y",
"Flux", 0, arrayData, 0, yImage, 1, 0);
1353 free (centrePositions);
1354 free (centreFluxErr2Min);
1375 void removeSkyBackground (
1376 const char *shutterId,
1377 enum ProcessingMode processing,
1378 ImageFormat *format,
1379 CompressedData *compressed,
1385 const char routine[] =
"removeSkyBackground";
1386 int i, j, S, T, R, X, shift, start;
1391 if (diagnostic > 4) cpl_msg_info(cpl_func,
"Invoking routine '%s' \n", routine);
1392 if (diagnostic > 4) fprintf(midiReportPtr,
"Invoking routine '%s' \n", routine);
1394 sprintf (midiMessage,
"Removing sky background from %s", shutterId);
1395 midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
1404 for (i = 0; i < format->numOfFrames; i++)
1406 if (compressed->tarType[i] ==
'T')
1408 if (lastType ==
'U' && T && S)
1417 for (j = start; j < start+S; j++)
1419 if (compressed->tarType[j] !=
'U')
1423 cpl_msg_info(cpl_func,
"%4d-%4d %c-%c \n", j+shift, j,
1424 compressed->tarType[j+shift], compressed->tarType[j]);
1425 fprintf (midiReportPtr,
"%4d-%4d %c-%c \n", j+shift, j,
1426 compressed->tarType[j+shift], compressed->tarType[j]);
1428 compressed->iFringe[j] = compressed->iFringe[j+shift] - compressed->iFringe[j];
1429 compressed->iFringe1[j] = compressed->iFringe1[j+shift] - compressed->iFringe1[j];
1430 compressed->iFringe2[j] = compressed->iFringe2[j+shift] - compressed->iFringe2[j];
1431 if (processing == DISPERSED)
1433 for (R = 0; R < format->numOfRegionsToProcess; R++)
1435 for (X = 0; X < format->iXWidth; X++)
1437 (((compressed->iDispFringe)[R])[X])[j] = (((compressed->iDispFringe)[R])[X])[j+shift] -
1438 (((compressed->iDispFringe)[R])[X])[j];
1447 else if (compressed->tarType[i] ==
'S')
1449 if (lastType ==
'U' && T && S)
1458 for (j = start; j < start+T; j++)
1460 if (compressed->tarType[j] !=
'U')
1464 cpl_msg_info(cpl_func,
"%4d-%4d %c-%c \n", j, j+shift,
1465 compressed->tarType[j], compressed->tarType[j+shift]);
1466 fprintf (midiReportPtr,
"%4d-%4d %c-%c \n", j, j+shift,
1467 compressed->tarType[j], compressed->tarType[j+shift]);
1469 compressed->iFringe[j] = compressed->iFringe[j] - compressed->iFringe[j+shift];
1470 compressed->iFringe1[j] = compressed->iFringe1[j] - compressed->iFringe1[j+shift];
1471 compressed->iFringe2[j] = compressed->iFringe2[j] - compressed->iFringe2[j+shift];
1472 if (processing == DISPERSED)
1474 for (R = 0; R < format->numOfRegionsToProcess; R++)
1476 for (X = 0; X < format->iXWidth; X++)
1478 (((compressed->iDispFringe)[R])[X])[j] = (((compressed->iDispFringe)[R])[X])[j] -
1479 (((compressed->iDispFringe)[R])[X])[j+shift];
1492 fprintf (midiReportPtr,
"%4d %c \n", i, compressed->tarType[i]);
1493 cpl_msg_info(cpl_func,
"%4d %c \n", i, compressed->tarType[i]);
1496 if ((S && T) || (!S && !T))
1522 long correctTarType (
1523 const char *shutterId,
1532 const char routine[] =
"correctTarType";
1533 int i, j, foundT, foundS, S, T, U, start, end, min, newPair;
1534 char *mask, lastType, lastShot;
1539 if (diagnostic > 4) cpl_msg_info(cpl_func,
"Invoking routine '%s' \n", routine);
1540 if (diagnostic > 4) fprintf(midiReportPtr,
"Invoking routine '%s' \n", routine);
1542 sprintf (midiMessage,
"Checking tarType inconsistencies for %s", shutterId);
1543 midiReportInfo (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
1546 foundT = foundS = 0;
1557 mask = (
char *) calloc (length,
sizeof (
char));
1565 for (i = 0; i < length; i++)
1567 if(isnan(TimeStamp[i]))
1569 cpl_msg_warning(cpl_func,
"Corrupted time stamp in table! ");
1570 cpl_msg_warning(cpl_func,
"Changing target type of frame %d "
1571 "from %c to %c", i, tarType[i],
'U');
1574 if(i>0 && i<(length-1) && tarType[i-1]==
'S' && tarType[i+1]==
'S')
1577 while(tarType[j]!=
'T' && j>=0)
1579 cpl_msg_warning(cpl_func,
"Changing target type of frame %d "
1580 "from %c to %c", j, tarType[j],
'U');
1586 if(i>0 && i<(length-1) && tarType[i-1]==
'T' && tarType[i+1]==
'T')
1589 while(tarType[j]!=
'S' && j>=0)
1591 cpl_msg_warning(cpl_func,
"Changing target type of frame %d "
1592 "from %c to %c", j, tarType[j],
'U');
1603 for (i = 1; i < length-2; i++)
1605 if(tarType[i-1]==
'U' && (tarType[i]==
'S' || tarType[i]==
'T') &&
1608 cpl_msg_warning(cpl_func,
"UTU or USU sequence found, "
1609 "correcting to UUU");
1615 for (i = 0; i < length-1; i++)
1617 if(tarType[i]==
'T' && tarType[i+1]==
'S')
1619 cpl_msg_warning(cpl_func,
"Switching from T to S without U at "
1621 cpl_msg_warning(cpl_func,
"Changing target type of frame %d and %d"
1622 " to %c", i, i+1,
'U');
1629 if(tarType[i]==
'S' && tarType[i+1]==
'T')
1631 cpl_msg_warning(cpl_func,
"Switching from S to T without U at "
1633 cpl_msg_warning(cpl_func,
"Changing target type of frame %d and %d"
1634 " to %c", i, i+1,
'U');
1644 for (i = 0; i < length; i++)
1647 if (tarType[i] ==
'T')
1649 if (lastType ==
'S')
1651 sprintf (midiMessage,
"Switching from S to T without U at frame %d. QCLOG", i);
1652 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
1655 if (lastShot ==
'T')
1657 sprintf (midiMessage,
"Switching from T to T without S at frame %d. QCLOG", i);
1658 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
1667 else if (tarType[i] ==
'S')
1669 if (lastType ==
'T')
1671 sprintf (midiMessage,
"Switching from T to S without U at frame %d. QCLOG", i);
1672 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
1675 if (lastShot ==
'S')
1677 sprintf (midiMessage,
"Switching from S to S without T at frame %d. QCLOG", i);
1678 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
1689 if (lastType ==
'T')
1694 if (lastType ==
'S')
1704 if ((foundS && foundT) || (foundS && T && (i == length-1)) || (foundT && S && (i == length-1)))
1713 for (j = start; j < end; j++)
1721 sprintf (midiMessage,
"Chopping inconsistency. Found extra 'T' at frame %d. Corrected. QCLOG", j);
1722 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
1725 else if (mask[j] ==
'S')
1731 sprintf (midiMessage,
"Chopping inconsistency. Found extra 'S' at frame %d. Corrected. QCLOG", j);
1732 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
1737 if (foundS && foundT)
1743 foundS = foundT = 0;
1745 else if ((!foundS && T && (i == length-1)) || (!foundT && S && (i == length-1)))
1747 for (j = start; j <= i; j++)
1750 sprintf (midiMessage,
"Chopping inconsistency. Found extra 'S' or 'T' at frame %d. Corrected. QCLOG", j);
1751 midiReportWarning (midiReportPtr, routine, __FILE__, __LINE__, midiMessage);
1757 for (i = 0; i < length; i++)
1758 tarType[i] = mask[i];
1763 for (i = 0; i < length; i++)
1765 cpl_msg_info(cpl_func,
"%4d %c \n", i, tarType[i]);
1766 fprintf (midiReportPtr,
"%4d %c \n", i, tarType[i]);