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
00029
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033
00034 #include <stdio.h>
00035 #include <cpl.h>
00036 #include <math.h>
00037 #include <string.h>
00038
00039 #include "vircam_utils.h"
00040 #include "vircam_mask.h"
00041 #include "vircam_dfs.h"
00042 #include "vircam_stats.h"
00043 #include "vircam_pfits.h"
00044 #include "vircam_paf.h"
00045
00046
00047
00048 static int vircam_detector_noise_create(cpl_plugin *) ;
00049 static int vircam_detector_noise_exec(cpl_plugin *) ;
00050 static int vircam_detector_noise_destroy(cpl_plugin *) ;
00051 static int vircam_detector_noise(cpl_parameterlist *, cpl_frameset *) ;
00052 static int vircam_detector_noise_save(cpl_frameset *framelist,
00053 cpl_parameterlist *parlist);
00054 static void vircam_detector_noise_init(void);
00055 static void vircam_detector_noise_tidy(void);
00056
00057
00058
00059 static struct {
00060
00061
00062
00063 float thresh;
00064 int extenum;
00065
00066
00067
00068 float gain;
00069 float readnoise;
00070 float counts;
00071 float lampflux;
00072 } vircam_detector_noise_config ;
00073
00074 static struct {
00075 cpl_size *labels;
00076 cpl_frameset *darklist;
00077 cpl_frameset *domelist;
00078 cpl_frame *inherit;
00079 cpl_image *darkim1;
00080 cpl_image *darkim2;
00081 cpl_image *domeim1;
00082 cpl_image *domeim2;
00083 vir_mask *master_mask;
00084 cpl_propertylist *ph;
00085 cpl_propertylist *eh;
00086 cpl_propertylist *phupaf;
00087 } ps;
00088
00089 static cpl_frame *product_frame = NULL;
00090 static int isfirst;
00091 static int dummy;
00092
00093 #define BUZZ_OFF {vircam_detector_noise_tidy(); return(-1);}
00094
00095 static char vircam_detector_noise_description[] =
00096 "vircam_detector_noise -- VIRCAM readnoise and gain recipe.\n\n"
00097 "Measures the read noise and gain of a chip using two dome flat exposures\n"
00098 "and two dark exposures. The flats should have the same illumination.\n"
00099 "All four frames should have the same exposure time. If the SOF\n"
00100 "contains more than two files of a given type, the others are ignored.\n\n"
00101 "The program requires the following files in the SOF:\n\n"
00102 " Tag Description\n"
00103 " -----------------------------------------------------------------------\n"
00104 " %-21s A list of two raw dark images\n"
00105 " %-21s A list of two raw dome flat image\n"
00106 " %-21s Optional master bad pixel map or\n"
00107 " %-21s Optional master confidence map\n"
00108 "\n";
00109
00175
00176
00177
00185
00186
00187 int cpl_plugin_get_info(cpl_pluginlist *list) {
00188 cpl_recipe *recipe = cpl_calloc(1,sizeof(*recipe));
00189 cpl_plugin *plugin = &recipe->interface;
00190 char alldesc[SZ_ALLDESC];
00191 (void)snprintf(alldesc,SZ_ALLDESC,vircam_detector_noise_description,
00192 VIRCAM_NOISE_DARK_RAW,VIRCAM_NOISE_FLAT_RAW,VIRCAM_CAL_BPM,
00193 VIRCAM_CAL_CONF);
00194
00195 cpl_plugin_init(plugin,
00196 CPL_PLUGIN_API,
00197 VIRCAM_BINARY_VERSION,
00198 CPL_PLUGIN_TYPE_RECIPE,
00199 "vircam_detector_noise",
00200 "VIRCAM recipe to determine readout noise and gain",
00201 alldesc,
00202 "Jim Lewis",
00203 "jrl@ast.cam.ac.uk",
00204 vircam_get_license(),
00205 vircam_detector_noise_create,
00206 vircam_detector_noise_exec,
00207 vircam_detector_noise_destroy);
00208
00209 cpl_pluginlist_append(list,plugin);
00210
00211 return(0);
00212 }
00213
00214
00215
00224
00225
00226 static int vircam_detector_noise_create(cpl_plugin *plugin) {
00227 cpl_recipe *recipe;
00228 cpl_parameter *p;
00229
00230
00231
00232 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00233 recipe = (cpl_recipe *)plugin;
00234 else
00235 return(-1);
00236
00237
00238
00239 recipe->parameters = cpl_parameterlist_new();
00240
00241
00242
00243 p = cpl_parameter_new_value("vircam.vircam_detector_noise.thresh",
00244 CPL_TYPE_DOUBLE,
00245 "Rejection threshold in sigma above background", "vircam.vircam_detector_noise",5.0);
00246 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"thresh");
00247 cpl_parameterlist_append(recipe->parameters,p);
00248
00249
00250
00251 p = cpl_parameter_new_range("vircam.vircam_detector_noise.extenum",
00252 CPL_TYPE_INT,
00253 "Extension number to be done, 0 == all",
00254 "vircam.vircam_detector_noise",
00255 1,0,16);
00256 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ext");
00257 cpl_parameterlist_append(recipe->parameters,p);
00258
00259
00260
00261 return(0);
00262 }
00263
00264
00270
00271
00272 static int vircam_detector_noise_destroy(cpl_plugin *plugin) {
00273 cpl_recipe *recipe ;
00274
00275
00276
00277 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00278 recipe = (cpl_recipe *)plugin;
00279 else
00280 return(-1);
00281
00282 cpl_parameterlist_delete(recipe->parameters);
00283 return(0);
00284 }
00285
00286
00292
00293
00294 static int vircam_detector_noise_exec(cpl_plugin *plugin) {
00295 cpl_recipe *recipe;
00296
00297
00298
00299 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00300 recipe = (cpl_recipe *)plugin;
00301 else
00302 return(-1);
00303
00304 return(vircam_detector_noise(recipe->parameters,recipe->frames));
00305 }
00306
00307
00314
00315
00316 static int vircam_detector_noise(cpl_parameterlist *parlist,
00317 cpl_frameset *framelist) {
00318 const char *fctid="vircam_detector_noise";
00319 cpl_parameter *p;
00320 int j,jst,jfn,retval,nx,ny,live;
00321 cpl_size nlab;
00322 long nptsdark;
00323 float meandark1,meandome1,meandark2,meandome2,sigdark,lcut,hcut;
00324 float meandarkdiff,sigdarkdiff,counts;
00325 float meandomediff,sigdomediff,gain,readnoise,exptime;
00326 cpl_frame *dark1,*dark2,*dome1,*dome2;
00327 cpl_propertylist *plist;
00328 unsigned char *bpm;
00329
00330
00331
00332 if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
00333 cpl_msg_error(fctid,"Input framelist NULL or has no input data");
00334 return(-1);
00335 }
00336
00337
00338
00339 if (vircam_frameset_fexists(framelist) != VIR_OK) {
00340 cpl_msg_error(fctid,"Input frameset is missing files. Check SOF");
00341 return(-1);
00342 }
00343
00344
00345
00346 vircam_detector_noise_init();
00347
00348
00349
00350 p = cpl_parameterlist_find(parlist,"vircam.vircam_detector_noise.thresh");
00351 vircam_detector_noise_config.thresh = (float)cpl_parameter_get_double(p);
00352 p = cpl_parameterlist_find(parlist,"vircam.vircam_detector_noise.extenum");
00353 vircam_detector_noise_config.extenum = cpl_parameter_get_int(p);
00354
00355
00356
00357 if (vircam_dfs_set_groups(framelist) != VIR_OK) {
00358 cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
00359 vircam_detector_noise_tidy();
00360 return(-1);
00361 }
00362
00363
00364
00365 if ((ps.labels = cpl_frameset_labelise(framelist,vircam_compare_tags,
00366 &nlab)) == NULL) {
00367 cpl_msg_error(fctid,"Cannot labelise the input frameset");
00368 BUZZ_OFF
00369 }
00370 if ((ps.darklist = vircam_frameset_subgroup(framelist,ps.labels,nlab,
00371 VIRCAM_NOISE_DARK_RAW)) == NULL) {
00372 cpl_msg_error(fctid,"Cannot find dark frames in input frameset");
00373 BUZZ_OFF
00374 }
00375 if (cpl_frameset_get_size(ps.darklist) < 2) {
00376 cpl_msg_error(fctid,"Dark frameset doesn't have enough frames");
00377 BUZZ_OFF
00378 }
00379 if ((ps.domelist = vircam_frameset_subgroup(framelist,ps.labels,nlab,
00380 VIRCAM_NOISE_FLAT_RAW)) == NULL) {
00381 cpl_msg_error(fctid,"Cannot find dome flat frames in input frameset");
00382 BUZZ_OFF
00383 }
00384 if (cpl_frameset_get_size(ps.domelist) < 2) {
00385 cpl_msg_error(fctid,"Dome flat frameset doesn't have enough frames");
00386 BUZZ_OFF
00387 }
00388
00389
00390
00391
00392 ps.master_mask = vircam_mask_define(framelist,ps.labels,nlab);
00393
00394
00395
00396 dark1 = cpl_frameset_get_frame(ps.darklist,0);
00397 dark2 = cpl_frameset_get_frame(ps.darklist,1);
00398 dome1 = cpl_frameset_get_frame(ps.domelist,0);
00399 dome2 = cpl_frameset_get_frame(ps.domelist,1);
00400 ps.inherit = dome1;
00401
00402
00403
00404 ps.ph = cpl_propertylist_load(cpl_frame_get_filename(dome1),0);
00405 (void)vircam_pfits_get_exptime((const cpl_propertylist *)ps.ph,&exptime);
00406
00407
00408
00409 vircam_exten_range(vircam_detector_noise_config.extenum,
00410 (const cpl_frame *)dark1,&jst,&jfn);
00411 if (jst == -1 || jfn == -1) {
00412 cpl_msg_error(fctid,"Unable to continue");
00413 vircam_detector_noise_tidy();
00414 return(-1);
00415 }
00416 for (j = jst; j <= jfn; j++) {
00417 cpl_msg_info(fctid,"Beginning work on extension %" CPL_SIZE_FORMAT,
00418 (cpl_size)j);
00419 isfirst = (j == jst);
00420 vircam_detector_noise_config.readnoise = 0.0;
00421 vircam_detector_noise_config.gain = 0.0;
00422 vircam_detector_noise_config.counts = 0.0;
00423 vircam_detector_noise_config.lampflux = 0.0;
00424 dummy = 1;
00425
00426
00427
00428 ps.darkim1 = cpl_image_load(cpl_frame_get_filename(dark1),
00429 CPL_TYPE_FLOAT,0,(cpl_size)j);
00430 ps.darkim2 = cpl_image_load(cpl_frame_get_filename(dark2),
00431 CPL_TYPE_FLOAT,0,(cpl_size)j);
00432 ps.domeim1 = cpl_image_load(cpl_frame_get_filename(dome1),
00433 CPL_TYPE_FLOAT,0,(cpl_size)j);
00434 ps.domeim2 = cpl_image_load(cpl_frame_get_filename(dome2),
00435 CPL_TYPE_FLOAT,0,(cpl_size)j);
00436 if (ps.darkim1 == NULL || ps.darkim2 == NULL || ps.domeim1 == NULL ||
00437 ps.domeim2 == NULL) {
00438 cpl_error_reset();
00439 cpl_msg_error(fctid,
00440 "NULL image input for extension %" CPL_SIZE_FORMAT,
00441 (cpl_size)j);
00442 retval = vircam_detector_noise_save(framelist,parlist);
00443 freeimage(ps.darkim1);
00444 freeimage(ps.darkim2);
00445 freeimage(ps.domeim1);
00446 freeimage(ps.domeim2);
00447 continue;
00448 }
00449
00450
00451
00452 ps.eh = cpl_propertylist_load(cpl_frame_get_filename(dome1),
00453 (cpl_size)j);
00454
00455
00456
00457 plist = cpl_propertylist_load(cpl_frame_get_filename(dark1),
00458 (cpl_size)j);
00459 vircam_pfits_get_detlive(plist,&live);
00460 if (! live) {
00461 cpl_msg_warning(fctid,"First dark image detector not live");
00462 retval = vircam_detector_noise_save(framelist,parlist);
00463 cpl_propertylist_delete(plist);
00464 freeimage(ps.darkim1);
00465 freeimage(ps.darkim2);
00466 freeimage(ps.domeim1);
00467 freeimage(ps.domeim2);
00468 freepropertylist(ps.eh);
00469 continue;
00470 }
00471 cpl_propertylist_delete(plist);
00472 plist = cpl_propertylist_load(cpl_frame_get_filename(dark2),
00473 (cpl_size)j);
00474 vircam_pfits_get_detlive(plist,&live);
00475 if (! live) {
00476 cpl_msg_warning(fctid,"Second dark image detector not live");
00477 retval = vircam_detector_noise_save(framelist,parlist);
00478 cpl_propertylist_delete(plist);
00479 freeimage(ps.darkim1);
00480 freeimage(ps.darkim2);
00481 freeimage(ps.domeim1);
00482 freeimage(ps.domeim2);
00483 freepropertylist(ps.eh);
00484 continue;
00485 }
00486 cpl_propertylist_delete(plist);
00487 plist = cpl_propertylist_load(cpl_frame_get_filename(dome1),
00488 (cpl_size)j);
00489 vircam_pfits_get_detlive(plist,&live);
00490 if (! live) {
00491 cpl_msg_warning(fctid,"First dome image detector not live");
00492 retval = vircam_detector_noise_save(framelist,parlist);
00493 cpl_propertylist_delete(plist);
00494 freeimage(ps.darkim1);
00495 freeimage(ps.darkim2);
00496 freeimage(ps.domeim1);
00497 freeimage(ps.domeim2);
00498 freepropertylist(ps.eh);
00499 continue;
00500 }
00501 cpl_propertylist_delete(plist);
00502 plist = cpl_propertylist_load(cpl_frame_get_filename(dome2),
00503 (cpl_size)j);
00504 vircam_pfits_get_detlive(plist,&live);
00505 if (! live) {
00506 cpl_msg_warning(fctid,"Second dome image detector not live");
00507 retval = vircam_detector_noise_save(framelist,parlist);
00508 cpl_propertylist_delete(plist);
00509 freeimage(ps.darkim1);
00510 freeimage(ps.darkim2);
00511 freeimage(ps.domeim1);
00512 freeimage(ps.domeim2);
00513 freepropertylist(ps.eh);
00514 continue;
00515 }
00516 cpl_propertylist_delete(plist);
00517
00518
00519
00520 nx = (int)cpl_image_get_size_x(ps.darkim1);
00521 ny = (int)cpl_image_get_size_y(ps.darkim1);
00522 nptsdark = (long)(nx*ny);
00523
00524
00525
00526 if (vircam_mask_load(ps.master_mask,j,nx,ny) == VIR_FATAL) {
00527 cpl_msg_info(fctid,
00528 "Unable to load mask image %s[%" CPL_SIZE_FORMAT "]",
00529 vircam_mask_get_filename(ps.master_mask),(cpl_size)j);
00530 cpl_msg_info(fctid,"Forcing all pixels to be good from now on");
00531 vircam_mask_force(ps.master_mask,nx,ny);
00532 }
00533 bpm = vircam_mask_get_data(ps.master_mask);
00534
00535
00536
00537 vircam_medmad((float *)cpl_image_get_data(ps.darkim1),bpm,
00538 nptsdark,&meandark1,&sigdark);
00539 sigdark *= 1.48;
00540 lcut = meandark1 - vircam_detector_noise_config.thresh*sigdark;
00541 hcut = meandark1 + vircam_detector_noise_config.thresh*sigdark;
00542 vircam_medmadcut((float *)cpl_image_get_data(ps.darkim1),bpm,
00543 nptsdark,lcut,hcut,&meandark1,&sigdark);
00544 vircam_medmad((float *)cpl_image_get_data(ps.domeim1),bpm,
00545 nptsdark,&meandome1,&sigdark);
00546 sigdark *= 1.48;
00547 lcut = meandome1 - vircam_detector_noise_config.thresh*sigdark;
00548 hcut = meandome1 + vircam_detector_noise_config.thresh*sigdark;
00549 vircam_medmadcut((float *)cpl_image_get_data(ps.domeim1),bpm,
00550 nptsdark,lcut,hcut,&meandome1,&sigdark);
00551
00552
00553
00554 vircam_medmad((float *)cpl_image_get_data(ps.darkim2),bpm,
00555 nptsdark,&meandark2,&sigdark);
00556 sigdark *= 1.48;
00557 lcut = meandark2 - vircam_detector_noise_config.thresh*sigdark;
00558 hcut = meandark2 + vircam_detector_noise_config.thresh*sigdark;
00559 vircam_medmadcut((float *)cpl_image_get_data(ps.darkim2),bpm,
00560 nptsdark,lcut,hcut,&meandark2,&sigdark);
00561 vircam_medmad((float *)cpl_image_get_data(ps.domeim2),bpm,
00562 nptsdark,&meandome2,&sigdark);
00563 sigdark *= 1.48;
00564 lcut = meandome2 - vircam_detector_noise_config.thresh*sigdark;
00565 hcut = meandome2 + vircam_detector_noise_config.thresh*sigdark;
00566 vircam_medmadcut((float *)cpl_image_get_data(ps.domeim2),bpm,
00567 nptsdark,lcut,hcut,&meandome2,&sigdark);
00568
00569
00570
00571 cpl_image_subtract(ps.darkim1,ps.darkim2);
00572 cpl_image_subtract(ps.domeim1,ps.domeim2);
00573
00574
00575
00576 vircam_medmad((float *)cpl_image_get_data(ps.darkim1),bpm,
00577 nptsdark,&meandarkdiff,&sigdarkdiff);
00578 sigdarkdiff *= 1.48;
00579 lcut = meandarkdiff - vircam_detector_noise_config.thresh*sigdarkdiff;
00580 hcut = meandarkdiff + vircam_detector_noise_config.thresh*sigdarkdiff;
00581 vircam_medmadcut((float *)cpl_image_get_data(ps.darkim1),bpm,
00582 nptsdark,lcut,hcut,&meandarkdiff,&sigdarkdiff);
00583 sigdarkdiff *= 1.48;
00584 vircam_medmad((float *)cpl_image_get_data(ps.domeim1),bpm,
00585 nptsdark,&meandomediff,&sigdomediff);
00586 sigdomediff *= 1.48;
00587 lcut = meandomediff - vircam_detector_noise_config.thresh*sigdomediff;
00588 hcut = meandomediff + vircam_detector_noise_config.thresh*sigdomediff;
00589 vircam_medmadcut((float *)cpl_image_get_data(ps.domeim1),bpm,
00590 nptsdark,lcut,hcut,&meandomediff,&sigdomediff);
00591 sigdomediff *= 1.48;
00592
00593
00594
00595 counts = (meandome1 + meandome2) - (meandark1 + meandark2);
00596 vircam_detector_noise_config.counts = 0.5*counts;
00597 vircam_detector_noise_config.lampflux = 0.5*counts/exptime;
00598 gain = counts/(sigdomediff*sigdomediff - sigdarkdiff*sigdarkdiff);
00599 vircam_detector_noise_config.gain = gain;
00600
00601
00602
00603 readnoise = gain*sigdarkdiff/sqrt(2.0);
00604 vircam_detector_noise_config.readnoise = readnoise;
00605 dummy = 0;
00606
00607
00608
00609 retval = vircam_detector_noise_save(framelist,parlist);
00610 if (retval != 0) {
00611 cpl_msg_error(fctid,"Error saving results");
00612 BUZZ_OFF
00613 }
00614
00615
00616
00617 freeimage(ps.darkim1);
00618 freeimage(ps.darkim2);
00619 freeimage(ps.domeim1);
00620 freeimage(ps.domeim2);
00621 vircam_mask_clear(ps.master_mask);
00622 freepropertylist(ps.eh);
00623 }
00624 vircam_detector_noise_tidy();
00625 return(0);
00626 }
00627
00628
00635
00636
00637 static int vircam_detector_noise_save(cpl_frameset *framelist,
00638 cpl_parameterlist *parlist) {
00639 const char *fctid = "vircam_detector_noise_save";
00640 const char *outpaf = "vircam_detector_noise";
00641 const char *outfile = "detector_noise.fits";
00642 const char *recipeid = "vircam_detector_noise";
00643 cpl_propertylist *plist,*p;
00644 cpl_table *o;
00645
00646
00647
00648 if (isfirst) {
00649
00650
00651
00652 product_frame = cpl_frame_new();
00653 cpl_frame_set_filename(product_frame,outfile);
00654 cpl_frame_set_tag(product_frame,VIRCAM_PRO_READGAINFILE);
00655 cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_IMAGE);
00656 cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
00657 cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
00658
00659
00660
00661 plist = cpl_propertylist_duplicate(ps.ph);
00662 ps.phupaf = vircam_paf_phu_items(plist);
00663 vircam_dfs_set_product_primary_header(plist,product_frame,framelist,
00664 parlist,(char *)recipeid,
00665 "PRO-1.15",ps.inherit,0);
00666 vircam_paf_append(ps.phupaf,plist,"ESO PRO CATG");
00667 vircam_paf_append(ps.phupaf,plist,"ESO INS FILT1 NAME");
00668
00669
00670
00671 if (cpl_image_save(NULL,outfile,CPL_TYPE_UCHAR,plist,
00672 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00673 cpl_msg_error(fctid,"Cannot save product PHU");
00674 cpl_frame_delete(product_frame);
00675 cpl_propertylist_delete(plist);
00676 return(-1);
00677 }
00678 cpl_propertylist_delete(plist);
00679 cpl_frameset_insert(framelist,product_frame);
00680 }
00681
00682
00683
00684 plist = cpl_propertylist_duplicate(ps.eh);
00685
00686
00687
00688 cpl_propertylist_update_float(plist,"ESO QC READNOISE",
00689 vircam_detector_noise_config.readnoise);
00690 cpl_propertylist_set_comment(plist,"ESO QC READNOISE",
00691 "[e-] Calculated detector readnoise");
00692 cpl_propertylist_update_float(plist,"ESO QC CONAD",
00693 vircam_detector_noise_config.gain);
00694 cpl_propertylist_set_comment(plist,"ESO QC CONAD",
00695 "[e-/ADU] Calculated detector gain");
00696 cpl_propertylist_update_float(plist,"ESO QC COUNTS",
00697 vircam_detector_noise_config.counts);
00698 cpl_propertylist_set_comment(plist,"ESO QC COUNTS",
00699 "[ADU] Dark corrected dome counts");
00700 cpl_propertylist_update_float(plist,"ESO QC LAMPFLUX",
00701 vircam_detector_noise_config.lampflux);
00702 cpl_propertylist_set_comment(plist,"ESO QC LAMPFLUX",
00703 "[ADU/sec] Dark corrected flux level");
00704
00705
00706
00707 vircam_dfs_set_product_exten_header(plist,product_frame,framelist,
00708 parlist,(char *)recipeid,
00709 "PRO-1.15",ps.inherit);
00710 if (dummy)
00711 vircam_dummy_property(plist);
00712
00713
00714
00715 o = cpl_table_new(1);
00716 cpl_table_new_column(o,"EXTNAME",CPL_TYPE_STRING);
00717 cpl_table_new_column(o,"READNOISE",CPL_TYPE_FLOAT);
00718 cpl_table_new_column(o,"GAIN",CPL_TYPE_FLOAT);
00719
00720
00721
00722 cpl_table_set_string(o,"EXTNAME",0,
00723 cpl_propertylist_get_string(plist,"EXTNAME"));
00724 cpl_table_set_float(o,"READNOISE",0,
00725 vircam_detector_noise_config.readnoise);
00726 cpl_table_set_float(o,"GAIN",0,vircam_detector_noise_config.gain);
00727
00728
00729
00730 if (cpl_table_save(o,NULL,plist,outfile,CPL_IO_EXTEND) != CPL_ERROR_NONE) {
00731 cpl_msg_error(fctid,"Cannot save product");
00732 cpl_propertylist_delete(plist);
00733 cpl_frame_delete(product_frame);
00734 freetable(o);
00735 return(-1);
00736 }
00737 freetable(o);
00738
00739
00740
00741 p = vircam_paf_req_items(plist);
00742 vircam_merge_propertylists(p,ps.phupaf);
00743 if (vircam_paf_print((char *)outpaf,"VIRCAM/vircam_detector_noise",
00744 "QC file",p) != VIR_OK)
00745 cpl_msg_warning(fctid,"Unable to write PAF");
00746 cpl_propertylist_delete(p);
00747
00748
00749
00750 freepropertylist(plist);
00751 return(0);
00752 }
00753
00754
00758
00759
00760 static void vircam_detector_noise_init(void) {
00761 ps.labels = NULL;
00762 ps.darklist = NULL;
00763 ps.domelist = NULL;
00764 ps.darkim1 = NULL;
00765 ps.darkim2 = NULL;
00766 ps.domeim1 = NULL;
00767 ps.domeim2 = NULL;
00768 ps.master_mask = NULL;
00769 ps.inherit = NULL;
00770 ps.ph = NULL;
00771 ps.eh = NULL;
00772 ps.phupaf = NULL;
00773 return;
00774 }
00775
00776
00780
00781
00782 static void vircam_detector_noise_tidy(void) {
00783 freespace(ps.labels);
00784 freeframeset(ps.darklist);
00785 freeframeset(ps.domelist);
00786 freeimage(ps.darkim1);
00787 freeimage(ps.darkim2);
00788 freeimage(ps.domeim1);
00789 freeimage(ps.domeim2);
00790 freemask(ps.master_mask);
00791 freepropertylist(ps.ph);
00792 freepropertylist(ps.eh);
00793 freepropertylist(ps.phupaf);
00794 return;
00795 }
00796
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987