00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include <string.h>
00037 #include <math.h>
00038 #include <assert.h>
00039 #include <cpl.h>
00040
00041 #include "irplib_utils.h"
00042
00043 #include "visir_inputs.h"
00044 #include "visir_utils.h"
00045 #include "visir_pfits.h"
00046 #include "visir_spc_distortion.h"
00047
00048
00049
00050
00051
00052 #define VISIR_BACKGD_START 76
00053 #define VISIR_BACKGD_STOP 172
00054
00055
00061
00062
00063
00064
00065
00066
00067
00068 static double visir_great_circle_dist(double, double, double, double);
00069 static double ra_hms2deg(int, int, double);
00070 static double dec_hms2deg(int, int, double);
00071
00072 static const char * visir_get_capa(const cpl_propertylist *);
00073 static double visir_hcycle_background(const irplib_framelist *, int, int);
00074
00075 #ifdef VISIR_MASK_HAS
00076 static cpl_boolean visir_mask_has(const cpl_mask *, cpl_binary, int);
00077 #endif
00078
00079
00082
00091
00092 double * visir_utils_get_wls(const irplib_framelist * self)
00093 {
00094
00095 const int size = irplib_framelist_get_size(self);
00096 double * wls = NULL;
00097 int i;
00098
00099
00100 skip_if (0);
00101
00102 skip_if(irplib_framelist_contains(self, VISIR_PFITS_DOUBLE_MONOC_POS,
00103 CPL_TYPE_DOUBLE, CPL_FALSE, 0.0));
00104
00105
00106 wls = cpl_malloc(size * sizeof(double));
00107
00108
00109 for (i=0; i < size; i++) {
00110 const cpl_propertylist * plist
00111 = irplib_framelist_get_propertylist_const(self, i);
00112
00113 wls[i] = visir_pfits_get_monoc_pos(plist);
00114
00115 skip_if (0);
00116 }
00117
00118 end_skip;
00119
00120 if (cpl_error_get_code()) {
00121 cpl_free(wls);
00122 wls = NULL;
00123 }
00124
00125 return wls;
00126 }
00127
00128
00138
00139 cpl_image * visir_create_disk_intimage(
00140 int nx,
00141 int ny,
00142 int x_pos,
00143 int y_pos,
00144 int radius)
00145 {
00146 cpl_image * intima;
00147 int * pintima;
00148 double dist;
00149 int i, j;
00150
00151
00152 intima = cpl_image_new(nx, ny, CPL_TYPE_INT);
00153 pintima = cpl_image_get_data_int(intima);
00154
00155
00156 for (j=0;j<ny ; j++) {
00157 for (i=0;i<nx ; i++) {
00158 dist = (i+1-x_pos)*(i+1-x_pos)+(j+1-y_pos)*(j+1-y_pos);
00159 if (dist < radius*radius) {
00160 pintima[i+j*nx] = 1;
00161 } else {
00162 pintima[i+j*nx] = 0;
00163 }
00164 }
00165 }
00166 return intima;
00167 }
00168
00169
00180
00181 cpl_image * visir_create_ring_intimage(
00182 int nx,
00183 int ny,
00184 int x_pos,
00185 int y_pos,
00186 int radius1,
00187 int radius2)
00188 {
00189 cpl_image * intima;
00190 int * pintima;
00191 double dist;
00192 int i, j;
00193
00194
00195 intima = cpl_image_new(nx, ny, CPL_TYPE_INT);
00196 pintima = cpl_image_get_data_int(intima);
00197
00198
00199 for (j=0;j<ny ; j++) {
00200 for (i=0;i<nx ; i++) {
00201 dist = (i+1-x_pos)*(i+1-x_pos)+(j+1-y_pos)*(j+1-y_pos);
00202 if ((dist < radius2*radius2) && (dist > radius1*radius1)) {
00203 pintima[i+j*nx] = 1;
00204 } else {
00205 pintima[i+j*nx] = 0;
00206 }
00207 }
00208 }
00209 return intima;
00210 }
00211
00212
00223
00224 double visir_image_sigma_clip(const cpl_image * self, double * pstdev)
00225 {
00226 const int dimx = cpl_image_get_size_x(self);
00227 const int dimy = cpl_image_get_size_y(self);
00228 const cpl_type type = cpl_image_get_type(self);
00229
00230
00231 cpl_image * noise = cpl_image_new(dimx, dimy, type);
00232 cpl_mask * bpm = NULL;
00233 cpl_mask * kernel = cpl_mask_new(3, 3);
00234 const int niterations = 5;
00235 const double sigma = 3.0;
00236 const double median_corr = 0.94;
00237 double bgnoise = -1;
00238 int i = -1;
00239
00240
00241 bug_if (0);
00242
00243 bug_if(cpl_mask_not(kernel));
00244 bug_if(cpl_image_filter_mask(noise, self, kernel, CPL_FILTER_MEDIAN,
00245 CPL_BORDER_FILTER));
00246
00247
00248 bug_if (cpl_image_subtract(noise, self));
00249
00250 for (i=0; i < niterations ; i++) {
00251
00252 cpl_stats * stats =
00253 cpl_stats_new_from_image(noise, CPL_STATS_MEAN | CPL_STATS_STDEV);
00254
00255 const double mean = cpl_stats_get_mean(stats);
00256 const double stdev = cpl_stats_get_stdev(stats);
00257
00258
00259 const double low_thresh = mean - sigma * stdev;
00260 const double high_thresh = mean + sigma * stdev;
00261
00262
00263 cpl_stats_delete(stats);
00264
00265
00266 skip_if (0);
00267
00268
00269 bpm = cpl_mask_threshold_image_create(noise, low_thresh, high_thresh);
00270
00271 bug_if (0);
00272
00273 bug_if (cpl_mask_not(bpm));
00274
00275 bug_if (cpl_image_reject_from_mask(noise, bpm));
00276
00277 cpl_mask_delete(bpm);
00278 bpm = NULL;
00279
00280 }
00281
00282 if (pstdev != NULL) {
00283
00284
00285 cpl_stats * stats =
00286 cpl_stats_new_from_image(noise, CPL_STATS_MEAN | CPL_STATS_STDEV);
00287
00288
00289 bgnoise = cpl_stats_get_stdev(stats);
00290 *pstdev = cpl_image_get_median(self) - cpl_stats_get_mean(stats);
00291
00292 cpl_stats_delete(stats);
00293 } else {
00294
00295 bgnoise = cpl_image_get_stdev(noise);
00296 }
00297
00298 bug_if(0);
00299
00300 bgnoise /= median_corr;
00301
00302 end_skip;
00303
00304 if (cpl_error_get_code())
00305 cpl_msg_error(cpl_func, "Computation of background noise using sigma=%g"
00306 " failed in iteration %d of %d", sigma, i+1, niterations);
00307
00308 cpl_mask_delete(kernel);
00309 cpl_mask_delete(bpm);
00310 cpl_image_delete(noise);
00311
00312 return bgnoise;
00313 }
00314
00315
00325
00326 double visir_img_phot_sigma_clip(const cpl_image * self)
00327 {
00328
00329 const double noise = visir_image_sigma_clip(self, NULL);
00330
00331 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), noise);
00332
00333 return noise;
00334
00335 }
00336
00337
00355
00356 int visir_star_find(const cpl_vector * v_ra, const cpl_vector * v_dec,
00357 double ra, double dec, double maxdist, double * pdist)
00358 {
00359 const int nra = cpl_vector_get_size(v_ra);
00360 const int ndec = cpl_vector_get_size(v_dec);
00361 double dmin = 0.0;
00362 int minind = 0;
00363 int i;
00364
00365
00366
00367 cpl_ensure(nra > 0, cpl_error_get_code(), -2);
00368 cpl_ensure(ndec > 0, cpl_error_get_code(), -3);
00369
00370
00371
00372
00373 cpl_ensure(nra == ndec, CPL_ERROR_INCOMPATIBLE_INPUT, -4);
00374
00375 cpl_ensure(maxdist >= 0, CPL_ERROR_ILLEGAL_INPUT, -5);
00376
00377
00378 for (i=0 ; i < nra ; i++) {
00379 const double rai = cpl_vector_get(v_ra, i);
00380 const double deci = cpl_vector_get(v_dec, i);
00381 const double gdist = visir_great_circle_dist(rai, deci, ra, dec);
00382
00383 cpl_msg_debug(cpl_func, "DISTANCE (RAi,DECi)=(%g,%g) <=> "
00384 "(RA,DEC)=(%g,%g): %g", rai, deci, ra, dec, gdist);
00385
00386 if (i == 0 || gdist < dmin) {
00387 minind = i;
00388 dmin = gdist;
00389 }
00390 }
00391
00392 if (pdist != NULL) *pdist = dmin;
00393
00394
00395 if (dmin > maxdist) {
00396 cpl_msg_error(cpl_func, "Nearest standard star (%d of %d) at (RA,DEC)="
00397 "(%g,%g) is too distant from (RA,DEC)=(%g, %g): %g > %g",
00398 1+minind, nra, cpl_vector_get(v_ra, minind),
00399 cpl_vector_get(v_dec, minind), ra, dec, dmin, maxdist);
00400 cpl_ensure(0, CPL_ERROR_DATA_NOT_FOUND, -1);
00401 }
00402
00403 return minind;
00404 }
00405
00406
00425
00426 cpl_error_code visir_star_convert(const char * line, int ra_hh, int ra_mm,
00427 double ra_ss, char isign, int dec_hh,
00428 int dec_mm, double dec_ss,
00429 const double * jys, int njys,
00430 double * pra, double * pdec)
00431 {
00432
00433 double sign;
00434 int i;
00435
00436 assert( line );
00437 assert( pra );
00438 assert( pdec );
00439 assert( jys );
00440 assert( njys > 0 );
00441
00442
00443 if (isign == '+')
00444 sign = 1.0;
00445 else if (isign == '-')
00446 sign = -1.0;
00447 else {
00448 cpl_msg_error(cpl_func, "Line has illegal declination-sign character "
00449 "(%c): %s", isign, line);
00450 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00451 }
00452
00453 if (ra_hh < 0) {
00454 cpl_msg_error(cpl_func, "Line has negative RA hh (%d): %s",
00455 ra_hh, line);
00456 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00457 }
00458 if (ra_mm < 0) {
00459 cpl_msg_error(cpl_func, "Line has negative RA mm (%d): %s",
00460 ra_hh, line);
00461 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00462 }
00463 if (ra_mm >= 60) {
00464 cpl_msg_error(cpl_func, "Line has too large RA mm (%d): %s ",
00465 ra_mm, line);
00466 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00467 }
00468 if (ra_ss < 0) {
00469 cpl_msg_error(cpl_func, "Line has negative RA ss (%g): %s",
00470 ra_ss, line);
00471 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00472 }
00473 if (ra_ss >= 60) {
00474 cpl_msg_error(cpl_func, "Line has too large RA ss (%g): %s ",
00475 ra_ss, line);
00476 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00477 }
00478
00479 if (dec_hh < 0) {
00480 cpl_msg_error(cpl_func, "Line has negative DEC hh (%d): %s",
00481 dec_hh, line);
00482 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00483 }
00484 if (dec_mm < 0) {
00485 cpl_msg_error(cpl_func, "Line has negative DEC mm (%d): %s",
00486 dec_hh, line);
00487 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00488 }
00489 if (dec_mm >= 60) {
00490 cpl_msg_error(cpl_func, "Line has too large DEC mm (%d): %s ",
00491 dec_mm, line);
00492 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00493 }
00494 if (dec_ss < 0) {
00495 cpl_msg_error(cpl_func, "Line has negative DEC ss (%g): %s",
00496 dec_ss, line);
00497 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00498 }
00499 if (dec_ss >= 60) {
00500 cpl_msg_error(cpl_func, "Line has too large DEC ss (%g): %s ",
00501 dec_ss, line);
00502 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00503 }
00504
00505 *pra = ra_hms2deg(ra_hh, ra_mm, ra_ss);
00506 if (*pra >= 360.0) {
00507 cpl_msg_error(cpl_func, "Line has too large RA (%g): %s ",
00508 *pra, line);
00509 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00510 }
00511
00512 *pdec = sign * dec_hms2deg(dec_hh, dec_mm, dec_ss);
00513 if (*pdec > 90.0) {
00514 cpl_msg_error(cpl_func, "Line has too large RA (%g): %s ",
00515 *pdec, line);
00516 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00517 }
00518 if (*pdec < -90.0) {
00519 cpl_msg_error(cpl_func, "Line has too small RA (%g): %s ",
00520 *pdec, line);
00521 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00522 }
00523
00524 for (i=0; i < njys; i++) if (jys[i] <= 0.0) {
00525 cpl_msg_error(cpl_func,"Line has non-positive Jy value (%g) at %d: %s ",
00526 jys[i], i+1, line);
00527 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00528 }
00529
00530 return CPL_ERROR_NONE;
00531
00532 }
00533
00534
00547
00548 cpl_table * visir_table_new_xypos(const cpl_imagelist * images,
00549 const char * label)
00550 {
00551 cpl_errorstate cleanstate = cpl_errorstate_get();
00552 const int nsize = cpl_imagelist_get_size(images);
00553 double psigmas[] = {5, 2, 1, 0.5};
00554 cpl_vector * sigmas = NULL;
00555 cpl_table * self = NULL;
00556 const int nsigmas = sizeof(psigmas)/sizeof(double);
00557 int isigma;
00558 int isflux = 0;
00559 int nfail, i;
00560
00561 cpl_ensure(nsize > 0, cpl_error_get_code(), NULL);
00562 cpl_ensure(label, CPL_ERROR_NULL_INPUT, NULL);
00563 cpl_ensure(!strcmp(label, "FLUX") || !strcmp(label, "FWHM"),
00564 CPL_ERROR_UNSUPPORTED_MODE, NULL);
00565
00566 self = cpl_table_new(nsize);
00567
00568 skip_if (cpl_table_new_column(self, "X_POS", CPL_TYPE_DOUBLE));
00569 skip_if (cpl_table_new_column(self, "Y_POS", CPL_TYPE_DOUBLE));
00570
00571 if (!strcmp(label,"FLUX")) {
00572 isflux = 1;
00573 skip_if (cpl_table_new_column(self, label, CPL_TYPE_DOUBLE));
00574 } else {
00575 skip_if (cpl_table_new_column(self, "X_FWHM", CPL_TYPE_DOUBLE));
00576 skip_if (cpl_table_new_column(self, "Y_FWHM", CPL_TYPE_DOUBLE));
00577 }
00578
00579 sigmas = cpl_vector_wrap(4, psigmas);
00580 skip_if (sigmas == NULL);
00581
00582 cpl_msg_info(cpl_func, "Detecting apertures using %d sigma-levels "
00583 "ranging from %g down to %g", nsigmas, psigmas[0],
00584 psigmas[nsigmas-1]);
00585
00586
00587 nfail = 0;
00588 for (i=0 ; i < nsize ; i++) {
00589 const cpl_image * image = cpl_imagelist_get_const(images, i);
00590 cpl_apertures * apert;
00591
00592 double posx = -1;
00593 double posy = -1;
00594 double fwhmx = -1;
00595 double fwhmy = -1;
00596 double flux = -1;
00597 int iflux;
00598
00599 skip_if (0);
00600
00601
00602 apert = cpl_apertures_extract(image, sigmas, &isigma);
00603
00604 if (apert != NULL && cpl_error_get_code()) {
00605
00606 cpl_msg_error(cpl_func, "cpl_apertures_extract() returned non-NULL "
00607 "while setting the CPL error-state to '%s' at '%s'",
00608 cpl_error_get_message(), cpl_error_get_where());
00609 cpl_msg_debug(cpl_func, "Deleting the spurious aperture list at %p:",
00610 (void*)apert);
00611 if (cpl_msg_get_level() <= CPL_MSG_DEBUG)
00612 cpl_apertures_dump(apert, stdout);
00613 cpl_apertures_delete(apert);
00614 apert = NULL;
00615 }
00616
00617 if (apert != NULL &&
00618 !irplib_apertures_find_max_flux(apert, &iflux, 1) &&
00619 cpl_apertures_get_flux(apert, iflux) > 0) {
00620
00621 posx = cpl_apertures_get_centroid_x(apert, iflux);
00622 posy = cpl_apertures_get_centroid_y(apert, iflux);
00623 flux = cpl_apertures_get_flux(apert, iflux);
00624 if (!isflux)
00625 cpl_image_get_fwhm(image, (int)posx, (int)posy, &fwhmx, &fwhmy);
00626
00627 cpl_msg_info(cpl_func, "Detected an aperture with flux=%g at "
00628 "sigma=%g, at position: %g %g", flux,
00629 psigmas[isigma], posx, posy);
00630
00631 }
00632
00633 if (cpl_error_get_code()) {
00634 visir_error_reset("Aperture detection in image %d of %d failed",
00635 i+1, nsize);
00636 nfail++;
00637 } else if (flux <= 0) {
00638 cpl_msg_warning(cpl_func, "Ignoring %d-pixel aperture %d (out of %d) "
00639 "in file %d of %d with non-positive flux: %g",
00640 cpl_apertures_get_npix(apert, iflux), iflux,
00641 cpl_apertures_get_size(apert), i+1, nsize, flux);
00642 nfail++;
00643 }
00644
00645 cpl_apertures_delete(apert);
00646 apert = NULL;
00647
00648 skip_if (cpl_table_set_double(self, "X_POS", i, posx));
00649 skip_if (cpl_table_set_double(self, "Y_POS", i, posy));
00650
00651 if (isflux)
00652 skip_if (cpl_table_set_double(self, "FLUX", i, flux));
00653 else {
00654 skip_if (cpl_table_set_double(self, "X_FWHM", i, fwhmx));
00655 skip_if (cpl_table_set_double(self, "Y_FWHM", i, fwhmy));
00656 }
00657
00658 }
00659
00660
00661 if (nfail == nsize) {
00662 cpl_msg_error(cpl_func, "Aperture detection failed in all %d images",
00663 nsize);
00664 visir_error_set(CPL_ERROR_DATA_NOT_FOUND);
00665 skip_if(1);
00666 }
00667
00668 end_skip;
00669
00670 cpl_vector_unwrap(sigmas);
00671
00672 if (self && cpl_error_get_code()) {
00673 cpl_table_delete(self);
00674 self = NULL;
00675 }
00676
00677 return self;
00678 }
00679
00680
00687
00688 int visir_vector_minpos(const cpl_vector * v)
00689 {
00690 const double * x = cpl_vector_get_data_const(v);
00691 const int n = cpl_vector_get_size(v);
00692 int minpos = 0;
00693 int i;
00694
00695 cpl_ensure(x, CPL_ERROR_NULL_INPUT, -1);
00696
00697 for (i = 1; i < n; i++) if (x[i] < x[minpos]) minpos = i;
00698
00699 return minpos;
00700 }
00701
00702
00717
00718 cpl_error_code visir_bivector_load(cpl_bivector * self, FILE * stream)
00719 {
00720 cpl_vector * v1;
00721 cpl_vector * v2;
00722 int np = 0;
00723 int xsize, ysize;
00724 char line[1024];
00725
00726 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
00727 cpl_ensure_code(stream, CPL_ERROR_NULL_INPUT);
00728
00729
00730 v1 = cpl_bivector_get_x(self);
00731 v2 = cpl_bivector_get_y(self);
00732
00733 xsize = cpl_vector_get_size(v1);
00734 ysize = cpl_vector_get_size(v2);
00735
00736 while (fgets(line, 1024, stream) != NULL) {
00737 double x, y;
00738 if (line[0] != '#' && sscanf(line, "%lg %lg", &x, &y) == 2) {
00739
00740
00741
00742
00743 if (np == xsize) {
00744 xsize *= 2;
00745 cpl_vector_set_size(v1, xsize);
00746 }
00747 if (np == ysize) {
00748 ysize *= 2;
00749 cpl_vector_set_size(v2, ysize);
00750 }
00751 cpl_vector_set(v1, np, x);
00752 cpl_vector_set(v2, np, y);
00753 np++;
00754 }
00755 }
00756
00757
00758 cpl_ensure_code(!ferror(stream), CPL_ERROR_FILE_IO);
00759
00760
00761 if (np == 0 || cpl_vector_set_size(v1, np) || cpl_vector_set_size(v2, np)) {
00762 cpl_ensure_code(0, CPL_ERROR_BAD_FILE_FORMAT);
00763 }
00764
00765 return CPL_ERROR_NONE;
00766
00767 }
00768
00769
00782
00783 double visir_star_dist_min(const double * pras, const double * pdecs, int nloc,
00784 int * piloc1, int * piloc2)
00785 {
00786
00787 int i, j;
00788 double dmin = 180;
00789
00790
00791 assert( pras != NULL);
00792 assert( pdecs != NULL);
00793 assert( piloc1 != NULL);
00794 assert( piloc2 != NULL);
00795 assert( nloc > 0 );
00796
00797 for (j = 0; j < nloc; j++) {
00798 for (i = 0; i < j; i++) {
00799 const double dist = visir_great_circle_dist(pras[i], pdecs[i],
00800 pras[j], pdecs[j]);
00801 if (dist < dmin) {
00802 dmin = dist;
00803 *piloc1 = i;
00804 *piloc2 = j;
00805 }
00806 if (dist < VISIR_STAR_MAX_RADIUS)
00807 cpl_msg_warning(cpl_func,"The two stars (%d,%d) have a distance"
00808 ": %g < %g", i, j, dist, VISIR_STAR_MAX_RADIUS);
00809 }
00810 }
00811
00812 return dmin;
00813 }
00814
00815
00816
00830
00831 const char ** visir_framelist_set_tag(irplib_framelist * self,
00832 char * (*pftag)(const cpl_frame *,
00833 const cpl_propertylist *,
00834 int),
00835 int *pntags)
00836 {
00837
00838
00839
00840 const char ** taglist = NULL;
00841 int iframe, size;
00842
00843 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
00844 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
00845 cpl_ensure(pftag != NULL, CPL_ERROR_NULL_INPUT, NULL);
00846 cpl_ensure(pntags != NULL, CPL_ERROR_NULL_INPUT, NULL);
00847
00848 size = irplib_framelist_get_size(self);
00849
00850 cpl_ensure(size > 0, CPL_ERROR_DATA_NOT_FOUND, NULL);
00851
00852 *pntags = 0;
00853
00854 for (iframe = 0; iframe < size ; iframe++) {
00855 cpl_frame * frame = irplib_framelist_get(self, iframe);
00856 const cpl_propertylist * plist
00857 = irplib_framelist_get_propertylist_const(self, iframe);
00858 char * tag;
00859 const char * newtag;
00860 int i;
00861
00862
00863
00864 cpl_ensure(frame != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
00865 cpl_ensure(plist != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
00866
00867 tag = (*pftag)(frame, plist, iframe);
00868
00869 cpl_ensure(tag != NULL, cpl_error_get_code(), NULL);
00870
00871
00872
00873 (void)cpl_frame_set_tag(frame, tag);
00874 cpl_free(tag);
00875
00876 newtag = cpl_frame_get_tag(frame);
00877
00878 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), NULL);
00879
00880
00881 for (i=0; i < *pntags; i++)
00882 if (strcmp(newtag, taglist[i]) == 0) break;
00883
00884 if (i == *pntags) {
00885
00886
00887 (*pntags)++;
00888 taglist = (const char **)cpl_realloc(taglist, *pntags *
00889 sizeof(const char *));
00890 taglist[i] = newtag;
00891 }
00892
00893 }
00894
00895 return taglist;
00896
00897 }
00898
00899
00909
00910 cpl_error_code visir_qc_append_background(cpl_propertylist * self,
00911 const irplib_framelist * rawframes,
00912 int icol1, int icol2)
00913 {
00914
00915
00916 const double bg_mean = visir_hcycle_background(rawframes, icol1, icol2);
00917
00918 skip_if (0);
00919
00920 bug_if (cpl_propertylist_append_double(self, "ESO QC BACKGD MEAN",
00921 bg_mean));
00922
00923 end_skip;
00924
00925 return cpl_error_get_code();
00926
00927 }
00928
00929
00930
00939
00940 cpl_error_code visir_qc_append_capa(cpl_propertylist * self,
00941 const irplib_framelist * rawframes)
00942 {
00943
00944 cpl_errorstate cleanstate = cpl_errorstate_get();
00945 const cpl_propertylist * plist
00946 = irplib_framelist_get_propertylist_const(rawframes, 0);
00947 const char * capa;
00948
00949
00950 bug_if (0);
00951
00952 capa = visir_get_capa(plist);
00953
00954 if (cpl_error_get_code()) {
00955 visir_error_reset("Could not determine capa");
00956 } else {
00957 bug_if (cpl_propertylist_append_string(self, "ESO QC CAPA", capa));
00958 }
00959
00960 end_skip;
00961
00962 return cpl_error_get_code();
00963
00964 }
00965
00966
00974
00975 cpl_error_code visir_qc_append_filter(cpl_propertylist * self,
00976 const irplib_framelist * rawframes)
00977 {
00978
00979 const cpl_propertylist * plist
00980 = irplib_framelist_get_propertylist_const(rawframes, 0);
00981 const char * value = visir_pfits_get_filter(plist);
00982
00983
00984 skip_if (0);
00985
00986 bug_if (cpl_propertylist_append_string(self, "ESO QC FILTER", value));
00987
00988 end_skip;
00989
00990 return cpl_error_get_code();
00991
00992 }
00993
00994
01002
01003 cpl_error_code visir_qc_append_exptime(cpl_propertylist * self,
01004 const irplib_framelist * rawframes)
01005 {
01006
01007 const cpl_propertylist * plist
01008 = irplib_framelist_get_propertylist_const(rawframes, 0);
01009
01010
01011
01012 const double dit = visir_pfits_get_dit(plist);
01013
01014 const int ndit = visir_pfits_get_ndit(plist);
01015
01016 const int nnod = irplib_framelist_get_size(rawframes);
01017
01018 const int ncycles = visir_pfits_get_chop_ncycles(plist);
01019
01020
01021 const double value = 2 * dit * ndit * nnod * ncycles;
01022
01023
01024 skip_if (0);
01025
01026 if (value <= 0) {
01027 cpl_msg_error(cpl_func, "Illegal exposure time "
01028 "(dit=%g:ndit=%d:ncycles=%d:nnod=%d): %g",
01029 dit, ndit, ncycles, nnod, value);
01030 skip_if(1);
01031 }
01032
01033 bug_if (cpl_propertylist_append_double(self, "ESO QC EXPTIME", value));
01034
01035 end_skip;
01036
01037 return cpl_error_get_code();
01038
01039 }
01040
01043
01054
01055 static double visir_great_circle_dist(double ra1, double dec1,
01056 double ra2, double dec2)
01057 {
01058
01059
01060 const double dra = sin( CPL_MATH_RAD_DEG * (ra2 - ra1 )/2.0 );
01061 const double ddec = sin( CPL_MATH_RAD_DEG * (dec2 - dec1)/2.0 );
01062
01063 dec1 *= CPL_MATH_RAD_DEG;
01064 dec2 *= CPL_MATH_RAD_DEG;
01065
01066 return 2.0 * asin(sqrt( ddec*ddec + cos(dec1)*cos(dec2)*dra*dra))
01067 * CPL_MATH_DEG_RAD;
01068
01069 }
01070
01071
01084
01085 static double ra_hms2deg(int hh, int mm, double ss)
01086 {
01087 return 15.0 * dec_hms2deg(hh, mm, ss);
01088 }
01089
01090
01102
01103 static double dec_hms2deg(int dd, int mm, double ss)
01104 {
01105 return ((double)ss/60.0 + (double)mm)/60.0 + dd;
01106 }
01107
01108
01121
01122 static double visir_hcycle_background(const irplib_framelist * rawframes,
01123 int icol1, int icol2)
01124 {
01125 cpl_imagelist * iset = NULL;
01126
01127 const int nfiles = irplib_framelist_get_size(rawframes);
01128 double bgsum = 0;
01129 double bgmean = -1;
01130 int nsum = 0;
01131 int i, j;
01132
01133
01134 skip_if (nfiles < 1);
01135
01136 if (icol1 == 0) icol1 = VISIR_BACKGD_START;
01137 if (icol2 == 0) icol2 = VISIR_BACKGD_STOP;
01138
01139 cpl_msg_info(cpl_func, "Computing Half-cycle background level from column %d "
01140 "through %d", icol1, icol2);
01141
01142
01143 for (i=0; i < nfiles; i++) {
01144
01145 iset = visir_load_hcycle(rawframes, i);
01146
01147 skip_if (0);
01148
01149 for (j = 0; j < cpl_imagelist_get_size(iset) ; j++) {
01150 const double median =
01151 cpl_image_get_median_window(cpl_imagelist_get(iset, j),
01152 VISIR_BACKGD_START, icol1,
01153 VISIR_BACKGD_STOP, icol2);
01154
01155 skip_if (0);
01156
01157 if (median != median) {
01158 const cpl_frame * frame = irplib_framelist_get_const(rawframes,
01159 i);
01160
01161 cpl_msg_error(cpl_func, "Image window (%d, %d, %d, %d) "
01162 "(image %d of %d) in %s (frame %d of %d) "
01163 "has NaN median",
01164 VISIR_BACKGD_START, icol1,
01165 VISIR_BACKGD_STOP, icol2,
01166 j+1, cpl_imagelist_get_size(iset),
01167 cpl_frame_get_filename(frame), i+1, nfiles);
01168 visir_error_set(CPL_ERROR_BAD_FILE_FORMAT);
01169 skip_if(1);
01170 }
01171 bgsum += median;
01172 }
01173 nsum += j;
01174 cpl_imagelist_delete(iset);
01175 iset = NULL;
01176 }
01177
01178
01179 skip_if (nsum < 1);
01180
01181 bgmean = bgsum / nsum;
01182
01183 end_skip;
01184
01185 cpl_imagelist_delete(iset);
01186
01187
01188 return bgmean - VISIR_HCYCLE_OFFSET;
01189 }
01190
01191
01197
01198 static const char * visir_get_capa(const cpl_propertylist * plist)
01199 {
01200 const char * capa = "Pb with Capa";
01201 const char * sval;
01202 double mean;
01203
01204
01205 skip_if (0);
01206
01207
01208
01209 sval = visir_pfits_get_insmode(plist);
01210 skip_if (0);
01211
01212
01213 if (!strcmp(sval, "IMG")) {
01214
01215 mean = visir_pfits_get_volt1dcta9(plist);
01216 mean += visir_pfits_get_volt1dctb9(plist);
01217 } else if (!strcmp(sval, "SPC") || !strcmp(sval, "SPCIMG")) {
01218
01219 mean = visir_pfits_get_volt2dcta9(plist);
01220 mean += visir_pfits_get_volt2dctb9(plist);
01221 } else
01222 skip_if (1);
01223
01224 skip_if (0);
01225
01226 mean *= 0.5;
01227
01228
01229 if (mean < 1.0) {
01230 capa = "Large Capa";
01231 } else if (mean > 4.5) {
01232 capa = "Small Capa";
01233 }
01234
01235 end_skip;
01236
01237 return capa;
01238 }
01239
01240 #ifdef VISIR_MASK_HAS
01241
01261
01262 static cpl_boolean visir_mask_has(const cpl_mask * self, cpl_binary value,
01263 int ngood)
01264 {
01265 const cpl_binary * pself = cpl_mask_get_data_const(self);
01266 int size = cpl_mask_get_size_x(self)
01267 * cpl_mask_get_size_y(self);
01268 int i;
01269
01270 cpl_ensure(self, CPL_ERROR_NULL_INPUT, CPL_FALSE);
01271 cpl_ensure(ngood >= 0, CPL_ERROR_ILLEGAL_INPUT, CPL_FALSE);
01272 cpl_ensure(ngood <= size, CPL_ERROR_ACCESS_OUT_OF_RANGE, CPL_FALSE);
01273 cpl_ensure(value == CPL_BINARY_0 || value == CPL_BINARY_1,
01274 CPL_ERROR_INCOMPATIBLE_INPUT, CPL_FALSE);
01275
01276 for (i = 0; i < ngood; i++) {
01277
01278 const cpl_binary * ppos = memchr(pself, value, (size_t)size);
01279 if (ppos == NULL) break;
01280
01281 size -= 1 + (int)(ppos - pself);
01282 pself = 1 + ppos;
01283 }
01284
01285 return i == ngood ? CPL_TRUE : CPL_FALSE;
01286 }
01287 #endif