38 #include "vircam_utils.h"
39 #include "vircam_pfits.h"
40 #include "vircam_dfs.h"
41 #include "vircam_mods.h"
42 #include "vircam_channel.h"
43 #include "vircam_stats.h"
44 #include "vircam_paf.h"
48 static int vircam_linearity_analyse_create(cpl_plugin *) ;
49 static int vircam_linearity_analyse_exec(cpl_plugin *) ;
50 static int vircam_linearity_analyse_destroy(cpl_plugin *) ;
51 static int vircam_linearity_analyse(cpl_parameterlist *, cpl_frameset *) ;
52 static int vircam_linearity_analyse_lastbit(
int jext, cpl_frameset *framelist,
53 cpl_parameterlist *parlist);
54 static int vircam_linearity_analyse_save(cpl_frameset *framelist,
55 cpl_parameterlist *parlist);
56 static int vircam_linearity_analyse_domedark_groups(
void);
57 static double *vircam_linearity_analyse_genstat(vir_fits *fframe,
int *bpm,
59 static double *vircam_linearity_tweakfac(
double **fdata,
double *mjd,
int nim,
60 int nchan,
double *facrng,
62 static void vircam_mjdsort(
double **fdata,
double *mjd,
int n);
63 static cpl_table *vircam_linearity_analyse_diagtab_init(
int np,
int nrows);
64 static void vircam_linearity_analyse_init(
void);
65 static void vircam_linearity_analyse_tidy(
int level);
90 } vircam_linearity_analyse_config;
103 #define SATURATE_FLAG 1
106 #define SUBSET2 (SUBSET/2)
110 cpl_frameset *domelist;
112 cpl_frameset *darklist;
114 cpl_frameset *domecheck;
116 cpl_frameset *darkcheck;
122 cpl_array *bpm_array;
127 cpl_propertylist *plist;
128 cpl_propertylist *elist;
131 cpl_propertylist *phupaf;
141 static cpl_frame *product_frame_chantab = NULL;
142 static cpl_frame *product_frame_bpm = NULL;
143 static cpl_frame *product_frame_diag1 = NULL;
144 static cpl_frame *product_frame_diag2 = NULL;
146 static char vircam_linearity_analyse_description[] =
147 "vircam_linearity_analyse -- VIRCAM linearity mapping recipe.\n\n"
148 "Form master dark images from the input raw frames and use these to\n"
149 "dark correct a series of dome flat exposures Using the dark\n"
150 "corrected dome flat series, work out linearity coefficients for\n"
151 "each data channel. The program expects the following files in the SOF\n"
153 " -----------------------------------------------------------------------\n"
154 " %-21s A list of raw dome flat images\n"
155 " %-21s A list of raw dark images\n"
156 " %-21s The channel table\n"
157 " %-21s A list of raw dome flat images at the monitor exposure time\n"
158 " %-21s A list of raw dark images at the monitor exposure time\n"
159 "The first three of these are required. The last two are only required if"
160 "the light source monitoring algorithm is to be used"
296 int cpl_plugin_get_info(cpl_pluginlist *list) {
297 cpl_recipe *recipe = cpl_calloc(1,
sizeof(*recipe));
298 cpl_plugin *plugin = &recipe->interface;
299 char alldesc[SZ_ALLDESC];
300 (void)snprintf(alldesc,SZ_ALLDESC,vircam_linearity_analyse_description,
301 VIRCAM_LIN_DOME_RAW,VIRCAM_LIN_DARK_RAW,
302 VIRCAM_CAL_CHANTAB_INIT,VIRCAM_LIN_DOME_CHECK,
303 VIRCAM_LIN_DARK_CHECK);
305 cpl_plugin_init(plugin,
307 VIRCAM_BINARY_VERSION,
308 CPL_PLUGIN_TYPE_RECIPE,
309 "vircam_linearity_analyse",
310 "VIRCAM linearity analysis recipe",
315 vircam_linearity_analyse_create,
316 vircam_linearity_analyse_exec,
317 vircam_linearity_analyse_destroy);
319 cpl_pluginlist_append(list,plugin);
335 static int vircam_linearity_analyse_create(cpl_plugin *plugin) {
341 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
342 recipe = (cpl_recipe *)plugin;
348 recipe->parameters = cpl_parameterlist_new();
352 p = cpl_parameter_new_range(
"vircam.vircam_linearity_analyse.norder",
354 "Order of polynomial fit",
355 "vircam.vircam_linearity_analyse",
357 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"nord");
358 cpl_parameterlist_append(recipe->parameters,p);
362 p = cpl_parameter_new_value(
"vircam.vircam_linearity_analyse.lthr",
364 "Lower bad pixel threshold",
365 "vircam.vircam_linearity_analyse",8.0);
366 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"lthr");
367 cpl_parameterlist_append(recipe->parameters,p);
371 p = cpl_parameter_new_value(
"vircam.vircam_linearity_analyse.hthr",
373 "Upper bad pixel threshold",
374 "vircam.vircam_linearity_analyse",8.0);
375 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"hthr");
376 cpl_parameterlist_append(recipe->parameters,p);
380 p = cpl_parameter_new_value(
"vircam.vircam_linearity_analyse.maxbpmfr",
382 "Maximum # frames used in bpm analysis",
383 "vircam.vircam_linearity_analyse",10);
384 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"maxbpmfr");
385 cpl_parameterlist_append(recipe->parameters,p);
390 p = cpl_parameter_new_value(
"vircam.vircam_linearity_analyse.adjust",
392 "Adjust stats with monitor set",
393 "vircam.vircam_linearity_analyse",1);
394 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"adjust");
395 cpl_parameterlist_append(recipe->parameters,p);
399 p = cpl_parameter_new_value(
"vircam.vircam_linearity_analyse.diagnostic",
401 "Write out diagnostic tables",
402 "vircam.vircam_linearity_analyse",0);
403 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"diagnostic");
404 cpl_parameterlist_append(recipe->parameters,p);
408 p = cpl_parameter_new_range(
"vircam.vircam_linearity_analyse.extenum",
410 "Extension number to be done, 0 == all",
411 "vircam.vircam_linearity_analyse",
413 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"ext");
414 cpl_parameterlist_append(recipe->parameters,p);
429 static int vircam_linearity_analyse_exec(cpl_plugin *plugin) {
434 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
435 recipe = (cpl_recipe *)plugin;
439 return(vircam_linearity_analyse(recipe->parameters,recipe->frames));
450 static int vircam_linearity_analyse_destroy(cpl_plugin *plugin) {
455 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
456 recipe = (cpl_recipe *)plugin;
460 cpl_parameterlist_delete(recipe->parameters);
473 static int vircam_linearity_analyse(cpl_parameterlist *parlist,
474 cpl_frameset *framelist) {
475 const char *fctid=
"vircam_linearity_analyse";
477 int i,jst,jfn,j,status,k,nbad,ngood,krem,n;
478 int ndarks,ndomes,kk,live,ngood_flats,*bpm,nalloc,adjust,ndit;
481 float med,mindit,*exps,badfrac,expt;
482 unsigned char *rejmask,*rejplus;
483 double *dexps,**fdata,*d,*mjds,*mjdcheck,mjd,**cdata,*cf,fac;
484 double facrng,maxdiff,*lindata;
485 vir_fits **darks,**domes,*test,*outdark,*fframe;
488 cpl_propertylist *drs,*plist;
494 if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
495 cpl_msg_error(fctid,
"Input framelist NULL or has no input data");
502 cpl_msg_error(fctid,
"Input frameset is missing files. Check SOF");
508 vircam_linearity_analyse_init();
512 p = cpl_parameterlist_find(parlist,
513 "vircam.vircam_linearity_analyse.norder");
514 vircam_linearity_analyse_config.norder = cpl_parameter_get_int(p);
515 p = cpl_parameterlist_find(parlist,
516 "vircam.vircam_linearity_analyse.lthr");
517 vircam_linearity_analyse_config.lthr = (float)cpl_parameter_get_double(p);
518 p = cpl_parameterlist_find(parlist,
519 "vircam.vircam_linearity_analyse.hthr");
520 vircam_linearity_analyse_config.hthr = (float)cpl_parameter_get_double(p);
521 p = cpl_parameterlist_find(parlist,
522 "vircam.vircam_linearity_analyse.maxbpmfr");
523 vircam_linearity_analyse_config.maxbpmfr = cpl_parameter_get_int(p);
524 p = cpl_parameterlist_find(parlist,
525 "vircam.vircam_linearity_analyse.adjust");
526 vircam_linearity_analyse_config.adjust = cpl_parameter_get_bool(p);
527 p = cpl_parameterlist_find(parlist,
528 "vircam.vircam_linearity_analyse.diagnostic");
529 vircam_linearity_analyse_config.diagnostic = cpl_parameter_get_bool(p);
530 p = cpl_parameterlist_find(parlist,
531 "vircam.vircam_linearity_analyse.extenum");
532 vircam_linearity_analyse_config.extenum = cpl_parameter_get_int(p);
537 cpl_msg_error(fctid,
"Cannot identify RAW and CALIB frames");
538 vircam_linearity_analyse_tidy(2);
546 cpl_msg_error(fctid,
"Cannot labelise the input frames");
547 vircam_linearity_analyse_tidy(2);
554 VIRCAM_LIN_DOME_RAW)) == NULL) {
555 cpl_msg_error(fctid,
"Cannot find dome flat frames in input frameset");
556 vircam_linearity_analyse_tidy(2);
559 ps.ndomes = cpl_frameset_get_size(ps.domelist);
560 ps.inherit = cpl_frameset_get_first(ps.domelist);
564 plist = cpl_propertylist_load(cpl_frame_get_filename(cpl_frameset_get_frame(ps.domelist,0)),0);
566 freepropertylist(plist);
569 "NDIT=%" CPL_SIZE_FORMAT
". Recipe requires that ndit == 1",
571 vircam_linearity_analyse_tidy(2);
578 VIRCAM_LIN_DARK_RAW)) == NULL) {
579 cpl_msg_error(fctid,
"Cannot find dark frames in input frameset");
580 vircam_linearity_analyse_tidy(2);
583 ps.ndarks = cpl_frameset_get_size(ps.darklist);
588 if (vircam_linearity_analyse_config.adjust) {
590 VIRCAM_LIN_DOME_CHECK)) == NULL) {
591 cpl_msg_info(fctid,
"No monitor frames found in sof. No adjustments made to stats");
592 vircam_linearity_analyse_config.adjust = 0;
595 ps.ndomecheck = cpl_frameset_get_size(ps.domecheck);
597 nlab,VIRCAM_LIN_DARK_CHECK)) == NULL) {
598 cpl_msg_info(fctid,
"No darks for monitor frames found in sof. No adjustments made to stats");
599 vircam_linearity_analyse_config.adjust = 0;
601 freeframeset(ps.domecheck);
604 ps.ndarkcheck = cpl_frameset_get_size(ps.darkcheck);
612 VIRCAM_CAL_CHANTAB_INIT)) == NULL) {
613 cpl_msg_error(fctid,
"No initial channel table found");
614 vircam_linearity_analyse_tidy(2);
620 if (vircam_linearity_analyse_domedark_groups() != 0) {
621 vircam_linearity_analyse_tidy(2);
628 if (ps.nddg < vircam_linearity_analyse_config.norder+1) {
629 cpl_msg_warning(fctid,
630 "Number of exposure times is too small: %" CPL_SIZE_FORMAT
", order: %" CPL_SIZE_FORMAT
"\nTaking fit down to order %" CPL_SIZE_FORMAT,
632 (cpl_size)(vircam_linearity_analyse_config.norder),
633 (cpl_size)(ps.nddg-1));
634 vircam_linearity_analyse_config.norder = ps.nddg - 1;
642 (
const cpl_frame *)cpl_frameset_get_frame(ps.ddg[0].darks,0),
644 if (jst == -1 || jfn == -1) {
645 cpl_msg_error(fctid,
"Unable to continue");
646 vircam_linearity_analyse_tidy(2);
652 for (j = jst; j <= jfn; j++) {
653 cpl_msg_info(fctid,
"Beginning BPM work on extension %" CPL_SIZE_FORMAT,
655 isfirst = (j == jst);
657 vircam_linearity_analyse_config.bad_pixel_stat = 0.0;
658 vircam_linearity_analyse_config.bad_pixel_num = 0;
659 vircam_linearity_analyse_config.linerror = 0.0;
660 vircam_linearity_analyse_config.linearity = 0.0;
661 vircam_linearity_analyse_config.facrng = 0.0;
662 vircam_linearity_analyse_config.maxdiff = 0.0;
678 if (ps.chantab == NULL) {
680 "Channel table extension %" CPL_SIZE_FORMAT
" failed to load",
683 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
689 "Channel table extension %" CPL_SIZE_FORMAT
" has errors",
692 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
699 "Channel table extension header %" CPL_SIZE_FORMAT
" missing saturation info",
702 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
704 vircam_linearity_analyse_tidy(1);
714 if (vircam_linearity_analyse_config.diagnostic) {
715 ps.diag1 = vircam_linearity_analyse_diagtab_init(np,ps.ndomes);
716 if (vircam_linearity_analyse_config.adjust)
717 ps.diag2 = vircam_linearity_analyse_diagtab_init(np,ps.ndomecheck);
724 cpl_msg_error(fctid,
"No DET LIVE keyword in this extension");
726 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
728 vircam_linearity_analyse_tidy(1);
732 cpl_msg_info(fctid,
"Detector flagged dead");
734 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
736 vircam_linearity_analyse_tidy(1);
744 &mindit) != VIR_OK) {
746 "No value of MINDIT found in extension %" CPL_SIZE_FORMAT,
749 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
759 exps = cpl_malloc(ps.nddg*
sizeof(
float));
761 for (i = 0; i < ps.nddg; i++) {
765 med *= (1.0 + mindit/ps.ddg[i].exptime);
767 ps.ddg[i].flag = SATURATE_FLAG;
770 exps[ngood-1] = ps.ddg[i].exptime;
771 ngood_flats += ps.ddg[i].ndomes;
772 ps.ddg[i].flag = OK_FLAG;
776 exps = cpl_realloc(exps,ngood*
sizeof(
float));
780 if (ngood < vircam_linearity_analyse_config.norder+1) {
782 "Too few unsaturated flats for linearity fit for extension %" CPL_SIZE_FORMAT,
786 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
798 ps.nuse = min(vircam_linearity_analyse_config.maxbpmfr,ngood_flats);
800 ps.flatlist = cpl_malloc(ps.nuse*
sizeof(vir_fits *));
801 for (i = ngood-1; i >= 0; i--) {
803 for (k = 0; k <= ps.nddg; k++) {
804 if (ps.ddg[k].exptime == exps[i]) {
813 ndarks = ps.ddg[krem].ndarks;
816 "Error loading darks extension %" CPL_SIZE_FORMAT
", exptime %g",
817 (cpl_size)j,ps.ddg[krem].exptime);
829 &rejmask,&rejplus,&drs,&status);
832 freepropertylist(drs);
833 if (status != VIR_OK) {
835 "Dark combine failure extension %" CPL_SIZE_FORMAT
" exposure %g",
836 (cpl_size)j,ps.ddg[krem].exptime);
837 freefitslist(darks,ndarks);
842 freefitslist(darks,ndarks);
847 ndomes = ps.ddg[krem].ndomes;
850 "Error loading domes extension %" CPL_SIZE_FORMAT
", exptime %g",
851 (cpl_size)j,ps.ddg[i].exptime);
859 for (kk = 0; kk < ndomes; kk++) {
863 ps.ddg[krem].proc[kk] = ps.flatlist[ps.nflatlist];
865 if (ps.nflatlist == ps.nuse)
871 freefitslist(domes,ndomes);
876 if (ps.nflatlist == ps.nuse)
880 ps.flatlist = cpl_realloc(ps.flatlist,
881 (ps.nflatlist)*
sizeof(vir_fits *));
887 vircam_linearity_analyse_config.lthr,
888 vircam_linearity_analyse_config.hthr,
889 &(ps.bpm_array),&nbad,&badfrac,&status);
890 bpm = cpl_array_get_data_int(ps.bpm_array);
894 vircam_linearity_analyse_config.bad_pixel_num = nbad;
895 vircam_linearity_analyse_config.bad_pixel_stat = badfrac;
901 freespace(ps.flatlist);
907 fdata = cpl_malloc(nalloc*
sizeof(
double *));
908 dexps = cpl_malloc(nalloc*
sizeof(
double));
909 mjds = cpl_malloc(nalloc*
sizeof(
double));
916 "Beginning linearity work on extension %" CPL_SIZE_FORMAT,
920 for (i = 0; i < ps.nddg; i++) {
921 if (ps.ddg[i].flag == SATURATE_FLAG)
923 for (k = 0; k < ps.ddg[i].ndomes; k++) {
928 if (ps.ddg[i].proc[k] == NULL) {
929 if (outdark == NULL) {
935 ndarks = ps.ddg[i].ndarks;
938 "Error loading darks extension %" CPL_SIZE_FORMAT
", exptime %g",
939 (cpl_size)j,ps.ddg[i].exptime);
947 if (ps.ddg[i].ndarks == 1) {
952 &outimage,&rejmask,&rejplus,
956 freepropertylist(drs);
957 if (status != VIR_OK) {
959 "Dark combine failure extension %" CPL_SIZE_FORMAT
" exposure %g",
960 (cpl_size)j,ps.ddg[i].exptime);
961 freefitslist(darks,ndarks);
967 freefitslist(darks,ndarks);
972 frame = cpl_frameset_get_frame(ps.ddg[i].domes,k);
979 fframe = ps.ddg[i].proc[k];
984 d = vircam_linearity_analyse_genstat(fframe,bpm,pp,np);
985 if (ps.nfdata >= nalloc) {
987 fdata = cpl_realloc(fdata,nalloc*
sizeof(
double *));
988 dexps = cpl_realloc(dexps,nalloc*
sizeof(
double));
989 mjds = cpl_realloc(mjds,nalloc*
sizeof(
double));
992 mjds[ps.nfdata] = mjd;
993 dexps[ps.nfdata] = (double)(ps.ddg[i].exptime);
994 fdata[ps.nfdata] = d;
999 if (ps.diag1 != NULL) {
1000 cpl_table_set_string(ps.diag1,
"filename",
1001 (cpl_size)(ps.nfdata),
1003 cpl_table_set_double(ps.diag1,
"exptime",
1004 (cpl_size)ps.nfdata,
1006 cpl_table_set_double(ps.diag1,
"mjd",(cpl_size)(ps.nfdata),
1008 for (n = 1; n <= np; n++) {
1009 snprintf(colname,16,
"rawflux_%02d",n);
1010 cpl_table_set_double(ps.diag1,colname,
1011 (cpl_size)(ps.nfdata),d[n-1]);
1014 if (ps.ddg[i].proc[k] != NULL) {
1015 freefits(ps.ddg[i].proc[k]);
1024 if (ps.diag1 != NULL)
1025 cpl_table_set_size(ps.diag1,(cpl_size)(ps.nfdata));
1030 if (vircam_linearity_analyse_config.adjust) {
1034 cdata = cpl_malloc(ps.ndomecheck*
sizeof(
double *));
1043 med *= (1.0 + mindit/expt);
1046 cpl_msg_info(fctid,
"Monitor exposures saturated. No drift adjustment made");
1056 ndarks = ps.ndarkcheck;
1057 if (darks == NULL) {
1058 cpl_msg_error(fctid,
1059 "Error loading check darks extension %" CPL_SIZE_FORMAT,
1073 &outimage,&rejmask,&rejplus,
1077 freepropertylist(drs);
1078 if (status != VIR_OK) {
1079 cpl_msg_error(fctid,
1080 "Combine failure extension %" CPL_SIZE_FORMAT
" monitor",
1082 freefitslist(darks,ndarks);
1088 freefitslist(darks,ndarks);
1093 mjdcheck = cpl_malloc(ps.ndomecheck*
sizeof(
double));
1094 for (i = 0; i < ps.ndomecheck; i++) {
1095 frame = cpl_frameset_get_frame(ps.domecheck,i);
1098 d = vircam_linearity_analyse_genstat(fframe,bpm,pp,np);
1106 if (ps.diag2 != NULL) {
1107 cpl_table_set_string(ps.diag2,
"filename",(cpl_size)i,
1109 cpl_table_set_double(ps.diag2,
"exptime",
1110 (cpl_size)i,(
double)expt);
1111 cpl_table_set_double(ps.diag2,
"mjd",
1113 for (n = 1; n <= np; n++) {
1114 snprintf(colname,16,
"rawflux_%02d",n);
1115 cpl_table_set_double(ps.diag2,colname,(cpl_size)i,
1117 snprintf(colname,16,
"linflux_%02d",n);
1118 cpl_table_set_double(ps.diag2,colname,(cpl_size)i,
1128 cf = vircam_linearity_tweakfac(cdata,mjdcheck,ps.ndomecheck,
1129 np,&facrng,&maxdiff);
1130 vircam_linearity_analyse_config.facrng = 100.0*(float)facrng;
1131 vircam_linearity_analyse_config.maxdiff = 100.0*(float)maxdiff;
1132 if (ps.diag2 != NULL) {
1133 for (i = 0; i < ps.ndomecheck; i++)
1134 cpl_table_set_double(ps.diag2,
"adjust_fac",
1141 for (i = 0; i < ps.nfdata; i++) {
1144 for (k = 0; k < ps.ndomecheck; k++) {
1145 if (mjd < mjdcheck[k]) {
1151 fac = cf[ps.ndomecheck-1];
1152 }
else if (krem == 0) {
1155 fac = 0.5*(cf[krem -1] + cf[krem]);
1157 for (k = 0; k < np; k++)
1159 if (ps.diag1 != NULL)
1160 cpl_table_set_double(ps.diag1,
"adjust_fac",
1166 freespace2(cdata,ps.ndomecheck);
1168 freespace(mjdcheck);
1181 vircam_linearity_analyse_config.norder,
1182 &(ps.lchantab),&lindata,&status);
1183 if (ps.diag1 != NULL) {
1184 for (i = 0; i < ps.nfdata; i++) {
1185 for (n = 0; n < np; n++) {
1186 snprintf(colname,16,
"linflux_%02d",n+1);
1187 cpl_table_set_double(ps.diag1,colname,
1188 (cpl_size)i,lindata[i*np+n]);
1192 freespace2(fdata,ps.nfdata);
1195 if (status != VIR_OK) {
1196 cpl_msg_error(fctid,
1197 "Linearity curve fit failed extension %" CPL_SIZE_FORMAT,
1200 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
1202 vircam_linearity_analyse_tidy(1);
1209 vircam_linearity_analyse_config.linearity =
1210 (float)cpl_table_get_column_mean(ps.lchantab,
"lin_10000");
1211 vircam_linearity_analyse_config.linerror =
1212 (float)cpl_table_get_column_mean(ps.lchantab,
"lin_10000_err");
1216 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
1222 vircam_linearity_analyse_tidy(2);
1236 static int vircam_linearity_analyse_save(cpl_frameset *framelist,
1237 cpl_parameterlist *parlist) {
1238 cpl_propertylist *plist,*elist,*pafprop;
1240 const char *outtab =
"lchantab.fits";
1241 const char *outbpm =
"bpm.fits";
1242 const char *outtabpaf =
"lchantab";
1243 const char *outbpmpaf =
"bpm";
1244 const char *outdiag1 =
"ldiag1.fits";
1245 const char *outdiag2 =
"ldiag2.fits";
1246 const char *fctid =
"vircam_linearity_analyse_save";
1247 const char *recipeid =
"vircam_linearity_analyse";
1248 int nx,ny,nord,*bpm,i;
1252 nord = vircam_linearity_analyse_config.norder;
1257 product_frame_chantab = cpl_frame_new();
1258 cpl_frame_set_filename(product_frame_chantab,outtab);
1259 cpl_frame_set_tag(product_frame_chantab,VIRCAM_PRO_CHANTAB);
1260 cpl_frame_set_type(product_frame_chantab,CPL_FRAME_TYPE_TABLE);
1261 cpl_frame_set_group(product_frame_chantab,CPL_FRAME_GROUP_PRODUCT);
1262 cpl_frame_set_level(product_frame_chantab,CPL_FRAME_LEVEL_FINAL);
1266 ps.phupaf = vircam_paf_phu_items(ps.plist);
1267 plist = cpl_propertylist_duplicate(ps.plist);
1271 "PRO-1.15",ps.inherit,0);
1276 elist = cpl_propertylist_duplicate(ps.elist);
1277 cpl_propertylist_update_float(elist,
"ESO DET SATURATION",sat);
1279 framelist,parlist,(
char *)recipeid,
1280 "PRO-1.15",ps.inherit);
1284 cpl_propertylist_update_float(elist,
"ESO QC LINEARITY",
1285 vircam_linearity_analyse_config.linearity);
1286 cpl_propertylist_set_comment(elist,
"ESO QC LINEARITY",
1287 "% non-linearity at 10000 ADU");
1288 cpl_propertylist_update_float(elist,
"ESO QC LINERROR",
1289 vircam_linearity_analyse_config.linerror);
1290 cpl_propertylist_set_comment(elist,
"ESO QC LINERROR",
1291 "% error non-linearity at 10000 ADU");
1292 cpl_propertylist_update_float(elist,
"ESO QC SCREEN_TOTAL",
1293 vircam_linearity_analyse_config.facrng);
1294 cpl_propertylist_set_comment(elist,
"ESO QC SCREEN_TOTAL",
1295 "total % range in screen variation");
1296 cpl_propertylist_update_float(elist,
"ESO QC SCREEN_STEP",
1297 vircam_linearity_analyse_config.maxdiff);
1298 cpl_propertylist_set_comment(elist,
"ESO QC SCREEN_STEP",
1299 "maximum % step in screen variation");
1300 cpl_propertylist_update_int(elist,
"ESO PRO DATANCOM",ps.nfdata);
1306 if (ps.lchantab == NULL)
1312 if (cpl_table_save(ps.lchantab,plist,elist,outtab,CPL_IO_DEFAULT)
1313 != CPL_ERROR_NONE) {
1314 cpl_msg_error(fctid,
"Cannot save product table extension");
1315 freepropertylist(plist);
1316 freepropertylist(elist);
1319 cpl_frameset_insert(framelist,product_frame_chantab);
1323 pafprop = vircam_paf_req_items(elist);
1325 vircam_paf_append(pafprop,plist,
"ESO INS FILT1 NAME");
1326 vircam_paf_append(pafprop,elist,
"ESO PRO CATG");
1327 vircam_paf_append(pafprop,elist,
"ESO PRO DATANCOM");
1328 if (vircam_paf_print((
char *)outtabpaf,
"VIRCAM/vircam_linearity_analyse",
1329 "QC file",pafprop) != VIR_OK)
1330 cpl_msg_warning(fctid,
"Unable to save PAF for linearity table");
1331 cpl_propertylist_delete(pafprop);
1335 freepropertylist(plist);
1336 freepropertylist(elist);
1340 product_frame_bpm = cpl_frame_new();
1341 cpl_frame_set_filename(product_frame_bpm,outbpm);
1342 cpl_frame_set_tag(product_frame_bpm,VIRCAM_PRO_BPM);
1343 cpl_frame_set_type(product_frame_bpm,CPL_FRAME_TYPE_IMAGE);
1344 cpl_frame_set_group(product_frame_bpm,CPL_FRAME_GROUP_PRODUCT);
1345 cpl_frame_set_level(product_frame_bpm,CPL_FRAME_LEVEL_FINAL);
1352 (
char *)recipeid,
"PRO-1.15",
1357 if (cpl_image_save(NULL,outbpm,CPL_TYPE_UCHAR,plist,
1358 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
1359 cpl_msg_error(fctid,
"Cannot save product PHU");
1360 cpl_frame_delete(product_frame_bpm);
1363 cpl_frameset_insert(framelist,product_frame_bpm);
1368 if (ps.diag1 != NULL) {
1372 product_frame_diag1 = cpl_frame_new();
1373 cpl_frame_set_filename(product_frame_diag1,outdiag1);
1374 cpl_frame_set_tag(product_frame_diag1,VIRCAM_PRO_LIN_DIAG1);
1375 cpl_frame_set_type(product_frame_diag1,CPL_FRAME_TYPE_TABLE);
1376 cpl_frame_set_group(product_frame_diag1,CPL_FRAME_GROUP_PRODUCT);
1377 cpl_frame_set_level(product_frame_diag1,CPL_FRAME_LEVEL_FINAL);
1381 plist = cpl_propertylist_duplicate(ps.plist);
1385 "PRO-1.15",ps.inherit,0);
1390 elist = cpl_propertylist_duplicate(ps.elist);
1393 (
char *)recipeid,
"PRO-1.15",
1403 if (cpl_table_save(ps.diag1,plist,elist,outdiag1,CPL_IO_DEFAULT)
1404 != CPL_ERROR_NONE) {
1405 cpl_msg_error(fctid,
"Cannot save product table extension");
1406 freepropertylist(plist);
1407 freepropertylist(elist);
1410 cpl_frameset_insert(framelist,product_frame_diag1);
1411 freepropertylist(plist);
1412 freepropertylist(elist);
1417 if (ps.diag2 != NULL) {
1421 product_frame_diag2 = cpl_frame_new();
1422 cpl_frame_set_filename(product_frame_diag2,outdiag2);
1423 cpl_frame_set_tag(product_frame_diag2,VIRCAM_PRO_LIN_DIAG2);
1424 cpl_frame_set_type(product_frame_diag2,CPL_FRAME_TYPE_TABLE);
1425 cpl_frame_set_group(product_frame_diag2,CPL_FRAME_GROUP_PRODUCT);
1426 cpl_frame_set_level(product_frame_diag2,CPL_FRAME_LEVEL_FINAL);
1430 plist = cpl_propertylist_duplicate(ps.plist);
1434 "PRO-1.15",ps.inherit,0);
1439 elist = cpl_propertylist_duplicate(ps.elist);
1442 (
char *)recipeid,
"PRO-1.15",
1452 if (cpl_table_save(ps.diag2,plist,elist,outdiag2,CPL_IO_DEFAULT)
1453 != CPL_ERROR_NONE) {
1454 cpl_msg_error(fctid,
"Cannot save product table extension");
1455 freepropertylist(plist);
1456 freepropertylist(elist);
1459 cpl_frameset_insert(framelist,product_frame_diag2);
1460 freepropertylist(plist);
1461 freepropertylist(elist);
1470 elist = cpl_propertylist_duplicate(ps.elist);
1471 cpl_propertylist_update_float(elist,
"ESO DET SATURATION",sat);
1475 "PRO-1.15",ps.inherit);
1479 cpl_propertylist_update_float(elist,
"ESO QC LINEARITY",
1480 vircam_linearity_analyse_config.linearity);
1481 cpl_propertylist_set_comment(elist,
"ESO QC LINEARITY",
1482 "% non-linearity at 10000 ADU");
1483 cpl_propertylist_update_float(elist,
"ESO QC LINERROR",
1484 vircam_linearity_analyse_config.linerror);
1485 cpl_propertylist_set_comment(elist,
"ESO QC LINERROR",
1486 "% error non-linearity at 10000 ADU");
1487 cpl_propertylist_update_float(elist,
"ESO QC SCREEN_TOTAL",
1488 vircam_linearity_analyse_config.facrng);
1489 cpl_propertylist_set_comment(elist,
"ESO QC SCREEN_TOTAL",
1490 "total % range in screen variation");
1491 cpl_propertylist_update_float(elist,
"ESO QC SCREEN_STEP",
1492 vircam_linearity_analyse_config.maxdiff);
1493 cpl_propertylist_set_comment(elist,
"ESO QC SCREEN_STEP",
1494 "maximum % step in screen variation");
1495 cpl_propertylist_update_int(elist,
"ESO PRO DATANCOM",ps.nfdata);
1501 if (ps.lchantab == NULL)
1507 if (cpl_table_save(ps.lchantab,NULL,elist,outtab,CPL_IO_EXTEND)
1508 != CPL_ERROR_NONE) {
1509 cpl_msg_error(fctid,
"Cannot save product table extension");
1510 freepropertylist(elist);
1516 pafprop = vircam_paf_req_items(elist);
1518 vircam_paf_append(pafprop,ps.plist,
"ESO INS FILT1 NAME");
1519 vircam_paf_append(pafprop,elist,
"ESO PRO CATG");
1520 vircam_paf_append(pafprop,elist,
"ESO PRO DATANCOM");
1521 if (vircam_paf_print((
char *)outtabpaf,
"VIRCAM/vircam_linearity_analyse",
1522 "QC file",pafprop) != VIR_OK)
1523 cpl_msg_warning(fctid,
"Unable to save PAF for BPM");
1524 cpl_propertylist_delete(pafprop);
1528 freepropertylist(elist);
1532 if (ps.diag1 != NULL) {
1533 elist = cpl_propertylist_duplicate(ps.elist);
1536 (
char *)recipeid,
"PRO-1.15",
1546 if (cpl_table_save(ps.diag1,NULL,elist,outdiag1,CPL_IO_EXTEND)
1547 != CPL_ERROR_NONE) {
1548 cpl_msg_error(fctid,
"Cannot save product table extension");
1549 freepropertylist(elist);
1552 freepropertylist(elist);
1554 if (ps.diag2 != NULL) {
1555 elist = cpl_propertylist_duplicate(ps.elist);
1558 (
char *)recipeid,
"PRO-1.15",
1568 if (cpl_table_save(ps.diag2,NULL,elist,outdiag2,CPL_IO_EXTEND)
1569 != CPL_ERROR_NONE) {
1570 cpl_msg_error(fctid,
"Cannot save product table extension");
1571 freepropertylist(elist);
1574 freepropertylist(elist);
1584 if (dummy && ps.bpm_array == NULL) {
1585 ps.bpm_array = cpl_array_new((cpl_size)(nx*ny),CPL_TYPE_INT);
1586 bpm = cpl_array_get_data_int(ps.bpm_array);
1587 for (i = 0; i < nx*ny; i++)
1590 bpm = cpl_array_get_data_int(ps.bpm_array);
1592 framelist,parlist,(
char *)recipeid,
1593 "PRO-1.15",ps.inherit);
1594 cpl_propertylist_update_float(plist,
"ESO QC BAD_PIXEL_STAT",
1595 vircam_linearity_analyse_config.bad_pixel_stat);
1596 cpl_propertylist_set_comment(plist,
"ESO QC BAD_PIXEL_STAT",
1597 "Fraction of pixels that are bad");
1598 cpl_propertylist_update_int(plist,
"ESO QC BAD_PIXEL_NUM",
1599 vircam_linearity_analyse_config.bad_pixel_num);
1600 cpl_propertylist_set_comment(plist,
"ESO QC BAD_PIXEL_NUM",
1601 "Number of pixels that are bad");
1602 cpl_propertylist_update_int(plist,
"ESO PRO DATANCOM",ps.nuse);
1605 outimg = cpl_image_wrap_int((cpl_size)nx,(cpl_size)ny,bpm);
1606 if (cpl_image_save(outimg,outbpm,CPL_TYPE_UCHAR,plist,
1607 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
1608 cpl_msg_error(fctid,
"Cannot save product image extension");
1614 pafprop = vircam_paf_req_items(plist);
1616 vircam_paf_append(pafprop,ps.plist,
"ESO INS FILT1 NAME");
1617 vircam_paf_append(pafprop,ps.plist,
"ESO PRO CATG");
1618 vircam_paf_append(pafprop,plist,
"ESO PRO DATANCOM");
1619 if (vircam_paf_print((
char *)outbpmpaf,
"VIRCAM/vircam_linearity_analyse",
1620 "QC file",pafprop) != VIR_OK)
1621 cpl_msg_warning(fctid,
"Unable to save PAF for linearity table");
1622 cpl_propertylist_delete(pafprop);
1626 cpl_image_unwrap(outimg);
1641 static int vircam_linearity_analyse_lastbit(
int jext, cpl_frameset *framelist,
1642 cpl_parameterlist *parlist) {
1644 const char *fctid =
"vircam_linearity_analyse_lastbit";
1649 "Saving linearity table and bpm for extension %" CPL_SIZE_FORMAT,
1651 retval = vircam_linearity_analyse_save(framelist,parlist);
1653 vircam_linearity_analyse_tidy(2);
1659 vircam_linearity_analyse_tidy(1);
1669 static int vircam_linearity_analyse_domedark_groups(
void) {
1673 cpl_propertylist *plist;
1674 const char *fctid =
"vircam_linearity_analyse_domedark_groups";
1678 ps.ddg = cpl_calloc(ps.ndomes,
sizeof(ddgrp));
1684 for (i = 0; i < ps.ndomes; i++) {
1685 frame = cpl_frameset_get_frame(ps.domelist,i);
1686 plist = cpl_propertylist_load(cpl_frame_get_filename(frame),0);
1688 cpl_msg_warning(fctid,
"No exposure time found in %s",
1689 cpl_frame_get_filename(frame));
1690 cpl_propertylist_delete(plist);
1693 cpl_propertylist_delete(plist);
1700 for (j = 0; j < ps.nddg; j++) {
1701 if (ps.ddg[j].exptime == texp) {
1707 cpl_frameset_insert(ps.ddg[j].domes,cpl_frame_duplicate(frame));
1708 ps.ddg[j].ndomes += 1;
1710 ps.ddg[ps.nddg].exptime = texp;
1711 ps.ddg[ps.nddg].darks = cpl_frameset_new();
1712 ps.ddg[ps.nddg].domes = cpl_frameset_new();
1713 ps.ddg[ps.nddg].ndarks = 0;
1714 ps.ddg[ps.nddg].ndomes = 1;
1715 ps.ddg[ps.nddg].flag = OK_FLAG;
1716 cpl_frameset_insert(ps.ddg[ps.nddg].domes,
1717 cpl_frame_duplicate(frame));
1724 for (i = 0; i < ps.ndarks; i++) {
1725 frame = cpl_frameset_get_frame(ps.darklist,i);
1726 plist = cpl_propertylist_load(cpl_frame_get_filename(frame),0);
1728 cpl_msg_warning(fctid,
"No exposure time found in %s",
1729 cpl_frame_get_filename(frame));
1730 cpl_propertylist_delete(plist);
1733 cpl_propertylist_delete(plist);
1740 for (j = 0; j < ps.nddg; j++) {
1741 if (ps.ddg[j].exptime == texp) {
1747 cpl_frameset_insert(ps.ddg[j].darks,cpl_frame_duplicate(frame));
1748 ps.ddg[j].ndarks += 1;
1756 while (i < ps.nddg) {
1757 if (ps.ddg[i].ndarks == 0) {
1758 cpl_msg_warning(fctid,
1759 "No dark frames exist for exposure %g\nThrowing these away",
1761 freeframeset(ps.ddg[i].darks);
1762 freeframeset(ps.ddg[i].domes);
1763 for (j = i+1; j < ps.nddg; j++)
1764 ps.ddg[j-1] = ps.ddg[j];
1772 for (i = 0; i < ps.nddg; i++) {
1773 ps.ddg[i].proc = cpl_malloc(ps.ddg[i].ndomes*
sizeof(vir_fits *));
1774 for (j = 0; j < ps.ddg[i].ndomes; j++)
1775 ps.ddg[i].proc[j] = NULL;
1782 ps.ddg = cpl_realloc(ps.ddg,ps.nddg*
sizeof(ddgrp));
1785 cpl_msg_error(fctid,
"There are no darks defined for input domes");
1801 static double *vircam_linearity_analyse_genstat(vir_fits *fframe,
int *bpm,
1802 parquet *p,
int np) {
1803 int i,ist,ifn,jst,jfn,n,jind2,iind2,jj,nx,ii;
1810 d = cpl_malloc(np*
sizeof(
double));
1819 tmp = cpl_malloc(SUBSET*SUBSET*
sizeof(
float));
1823 for (i = 0; i < np; i++) {
1828 ist = ((pp->delta_i)/2 - SUBSET2);
1829 ifn = ist + SUBSET - 1;
1830 jst = ((pp->delta_j)/2 - SUBSET2);
1831 jfn = jst + SUBSET - 1;
1836 for (jj = jst; jj <= jfn; jj++) {
1837 jind2 = (jj + pp->iymin - 1)*nx;
1838 for (ii = ist; ii <= ifn; ii++) {
1839 iind2 = jind2 + ii + pp->ixmin - 1;
1840 if (bpm[iind2] == 0)
1841 tmp[n++] = data[iind2];
1867 static double *vircam_linearity_tweakfac(
double **fdata,
double *mjd,
int nim,
1868 int nchan,
double *facrng,
1871 double *factors,sum,midval,minfac,maxfac;
1875 factors = cpl_malloc(nim*
sizeof(
double));
1879 vircam_mjdsort(fdata,mjd,nim);
1893 for (i = 0; i < nchan; i++) {
1897 midval = 0.5*(fdata[ist][i] + fdata[ifn][i]);
1901 for (j = 0; j < nim; j++)
1902 fdata[j][i] /= midval;
1911 for (j = 0; j < nim; j++) {
1913 for (i = 0; i < nchan; i++)
1915 factors[j] = sum/(double)nchan;
1917 maxfac = factors[j];
1918 minfac = factors[j];
1920 minfac = min(minfac,factors[j]);
1921 maxfac = max(maxfac,factors[j]);
1922 *maxdiff = max(*maxdiff,fabs(factors[j]-factors[j-1]));
1925 *facrng = maxfac - minfac;
1942 static void vircam_mjdsort(
double **fdata,
double *mjd,
int n) {
1943 int iii,ii,i,ifin,j;
1944 double tmpmjd,*tmpdata;
1950 iii = min(n,(3*iii)/4 - 1);
1955 for (ii = 0; ii < ifin; ii++) {
1958 if (mjd[i] > mjd[j]) {
1963 fdata[j] = fdata[i];
1966 if (i < 0 || mjd[0] <= tmpmjd)
1985 static cpl_table *vircam_linearity_analyse_diagtab_init(
int np,
int nrows) {
1992 t = cpl_table_new(nrows);
1996 cpl_table_new_column(t,
"filename",CPL_TYPE_STRING);
1997 cpl_table_new_column(t,
"exptime",CPL_TYPE_DOUBLE);
1998 cpl_table_set_column_unit(t,
"exptime",
"seconds");
1999 cpl_table_new_column(t,
"mjd",CPL_TYPE_DOUBLE);
2000 cpl_table_set_column_unit(t,
"mjd",
"days");
2005 for (i = 1; i <= np; i++) {
2006 (void)snprintf(colname,16,
"rawflux_%02d",i);
2007 cpl_table_new_column(t,colname,CPL_TYPE_DOUBLE);
2008 cpl_table_set_column_unit(t,colname,
"ADU");
2009 (void)snprintf(colname,16,
"linflux_%02d",i);
2010 cpl_table_new_column(t,colname,CPL_TYPE_DOUBLE);
2011 cpl_table_set_column_unit(t,colname,
"ADU");
2016 cpl_table_new_column(t,
"adjust_fac",CPL_TYPE_DOUBLE);
2029 static void vircam_linearity_analyse_init(
void) {
2033 ps.domecheck = NULL;
2034 ps.darkcheck = NULL;
2043 ps.bpm_array = NULL;
2059 static void vircam_linearity_analyse_tidy(
int level) {
2062 freetfits(ps.chantab);
2063 freearray(ps.bpm_array);
2064 freefitslist(ps.flatlist,ps.nflatlist);
2065 freetable(ps.lchantab);
2066 freepropertylist(ps.plist);
2067 freepropertylist(ps.elist);
2068 freetable(ps.diag1);
2069 freetable(ps.diag2);
2073 freespace(ps.labels);
2074 freeframeset(ps.domelist);
2075 freeframeset(ps.darklist);
2076 freeframeset(ps.domecheck);
2077 freeframeset(ps.darkcheck);
2078 freeframe(ps.chanfrm);
2079 if (ps.ddg != NULL) {
2080 for (i = 0; i < ps.nddg; i++) {
2081 freeframeset(ps.ddg[i].darks);
2082 freeframeset(ps.ddg[i].domes);
2083 freefitslist(ps.ddg[i].proc,ps.ddg[i].ndomes);
2087 freepropertylist(ps.phupaf);
const char * vircam_get_license(void)
char * vircam_fits_get_filename(vir_fits *p)
cpl_table * vircam_tfits_get_table(vir_tfits *p)
int vircam_compare_tags(const cpl_frame *frame1, const cpl_frame *frame2)
int vircam_chantab_verify(cpl_table *intab)
void vircam_merge_propertylists(cpl_propertylist *p1, cpl_propertylist *p2)
vir_fits ** vircam_fits_load_list(cpl_frameset *f, cpl_type type, int exten)
cpl_frame * vircam_frameset_subgroup_1(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
vir_fits * vircam_fits_wrap(cpl_image *im, vir_fits *model, cpl_propertylist *phu, cpl_propertylist *ehu)
cpl_table * vircam_chantab_new(int nord, cpl_table *template)
cpl_propertylist * vircam_tfits_get_ehu(vir_tfits *p)
int vircam_pfits_get_exptime(const cpl_propertylist *plist, float *exptime)
Get the value of exposure time.
void vircam_fits_delete(vir_fits *p)
void vircam_sort(float **a, int n, int m)
int vircam_genlincur(double **fdata, int nimages, double *exps, double mindit, vir_tfits *chantab, int norder, cpl_table **lchantab, double **lindata, int *status)
Generate a linearity curve for each readout channel in a list of images.
cpl_image * vircam_fits_get_image(vir_fits *p)
int vircam_darkcor(vir_fits *infile, vir_fits *darksrc, float darkscl, int *status)
Correct input data for dark current.
cpl_frameset * vircam_frameset_subgroup(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
void vircam_dfs_set_product_exten_header(cpl_propertylist *plist, cpl_frame *frame, cpl_frameset *frameset, cpl_parameterlist *parlist, char *recipeid, const char *dict, cpl_frame *inherit)
void vircam_dfs_set_product_primary_header(cpl_propertylist *plist, cpl_frame *frame, cpl_frameset *frameset, cpl_parameterlist *parlist, char *recipeid, const char *dict, cpl_frame *inherit, int synch)
int vircam_pfits_get_mindit(const cpl_propertylist *plist, float *mindit)
Get the value of mindit time.
vir_fits * vircam_fits_duplicate(vir_fits *in)
float vircam_med(float *data, unsigned char *bpm, long npts)
int vircam_pfits_get_ndit(const cpl_propertylist *plist, int *ndit)
Get the value of NDIT.
void vircam_dummy_property(cpl_propertylist *p)
cpl_propertylist * vircam_fits_get_phu(vir_fits *p)
int vircam_genbpm(vir_fits **flatlist, int nflatlist, float lthr, float hthr, cpl_array **bpm_array, int *nbad, float *badfrac, int *status)
Generate a bad pixel mask from a list of dome flats.
vir_fits * vircam_fits_load(cpl_frame *frame, cpl_type type, int nexten)
vir_tfits * vircam_tfits_load(cpl_frame *table, int nexten)
cpl_propertylist * vircam_fits_get_ehu(vir_fits *p)
int vircam_frameset_fexists(cpl_frameset *frameset)
int vircam_chan_fill(cpl_table *tab, parquet **p, long *np)
int vircam_pfits_get_detlive(const cpl_propertylist *plist, int *detlive)
Get the value of DET_LIVE.
int vircam_imcombine(vir_fits **fset, int nfits, int combtype, int scaletype, int xrej, float thresh, cpl_image **outimage, unsigned char **rejmask, unsigned char **rejplus, cpl_propertylist **drs, int *status)
Stack images into a mean or median image with rejection.
int vircam_pfits_get_saturation(const cpl_propertylist *plist, float *saturation)
Get the saturation level for this detector.
void vircam_exten_range(int inexten, const cpl_frame *fr, int *out1, int *out2)
void vircam_chan_free(int np, parquet **p)
int vircam_pfits_get_mjd(const cpl_propertylist *plist, double *mjd)
Get the value of the modified Julian date.
int vircam_dfs_set_groups(cpl_frameset *set)