36 #include "muse_imagelist.h"
39 #include "muse_pfits.h"
40 #include "muse_quadrants.h"
41 #include "muse_quality.h"
42 #include "muse_utils.h"
85 for (k = 0; k < aList->
size; k++) {
88 cpl_free(aList->
list);
106 cpl_ensure(aList, CPL_ERROR_NULL_INPUT, 0);
129 cpl_ensure(aList, CPL_ERROR_NULL_INPUT, NULL);
130 cpl_ensure(aIdx < aList->size, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
132 return aList->
list[aIdx];
159 cpl_ensure_code(aList && aImage, CPL_ERROR_NULL_INPUT);
162 for (k = 0; k < aList->
size; k++) {
164 cpl_ensure_code(aList->
list[k] != aImage, CPL_ERROR_ILLEGAL_INPUT);
167 if (aIdx >= aList->
size || aList->
list == NULL) {
171 for (k = aList->
size; k <= aIdx; k++) {
172 aList->
list[k] = NULL;
174 aList->
size = aIdx + 1;
178 aList->
list[aIdx] = aImage;
179 return CPL_ERROR_NONE;
203 cpl_ensure(aList, CPL_ERROR_NULL_INPUT, -1);
212 for (k = 1; k < aList->
size; k++) {
236 cpl_msg_info(__func__,
" index median mean stdev scale");
238 for (k = 0; k < aList->
size; k++) {
241 const char *empty =
"----------";
242 cpl_msg_info(__func__,
"%5d %10s %10s %10s %10s" , k,
243 empty, empty, empty, empty);
248 cpl_msg_info(__func__,
"%5d %10.2f %10.2f %10.2f %10.2f", k,
249 cpl_image_get_median(image->
data),
250 cpl_image_get_mean(image->
data),
251 cpl_image_get_stdev(image->
data), scale);
271 cpl_ensure_code(aList, CPL_ERROR_NULL_INPUT);
273 cpl_msg_info(__func__,
"Scale all images to %7.2fs exposure time",
275 cpl_msg_debug(__func__,
"Image EXPTIME scale");
276 cpl_msg_debug(__func__,
" 1 %7.2fs 1.000", t0);
278 for (k = 1; k < aList->
size; k++) {
282 cpl_msg_debug(__func__,
"%4d %7.2fs %6.3f", k+1, t, scale);
284 cpl_propertylist_update_double(image->
header,
"EXPTIME", t0);
286 return CPL_ERROR_NONE;
326 cpl_ensure(aList, CPL_ERROR_NULL_INPUT, NULL);
328 unsigned int nvalues = aList->
size - 1;
331 cpl_image *ronimage = cpl_image_new(4 * 2, nvalues, CPL_TYPE_DOUBLE);
336 for (k = 0; k < nvalues; k++) {
338 cpl_image *diff = cpl_image_subtract_create(aList->
list[k]->
data,
340 for (n = 1; n <= 4; n++) {
345 cpl_stats *s = cpl_stats_new_from_image_window(diff, CPL_STATS_ALL,
346 window[0], window[2],
347 window[1], window[3]);
348 cpl_msg_debug(__func__,
"Quadrant %hhu stats: %f+/-%f %f %f..%f\n", n,
349 cpl_stats_get_mean(s), cpl_stats_get_stdev(s),
350 cpl_stats_get_median(s),
351 cpl_stats_get_min(s), cpl_stats_get_max(s));
354 double ron = 100., ronerr = 1000.;
355 unsigned int niter = 0;
356 #pragma omp critical (cpl_flux_get_noise)
358 srand(niter++ * 100 + 1);
359 cpl_flux_get_noise_window(diff, window, aHalfsize, aNSamples,
361 }
while (ronerr > 0.1 * ron && niter < 5);
363 cpl_msg_debug(__func__,
"--> intermediate RON=%f+/-%f (GAIN=%f)",
367 ron *= gain / sqrt(2);
368 ronerr *= gain / sqrt(2);
369 cpl_image_set(ronimage, n, k+1, ron);
370 cpl_image_set(ronimage, n+4, k+1, ronerr);
373 cpl_image_delete(diff);
377 cpl_vector *ron = cpl_vector_new(4),
378 *ronerr = cpl_vector_new(4);
379 for (n = 1; n <= 4; n++) {
380 #if 0 // for debugging generate and use some more values
381 cpl_stats *ronstats, *ronerrstats;
382 ronstats = cpl_stats_new_from_image_window(ronimage, CPL_STATS_ALL,
384 ronerrstats = cpl_stats_new_from_image_window(ronimage, CPL_STATS_ALL,
385 n+4, 1, n+4, nvalues);
386 cpl_msg_debug(__func__,
"Quadrant %hhu RON: %f+/-%f %f %f..%f\n", n,
387 cpl_stats_get_mean(ronstats),
388 cpl_stats_get_stdev(ronstats),
389 cpl_stats_get_median(ronstats),
390 cpl_stats_get_min(ronstats),
391 cpl_stats_get_max(ronstats));
392 cpl_msg_debug(__func__,
"Quadrant %hhu RONERR: %f+/-%f %f %f..%f\n", n,
393 cpl_stats_get_mean(ronerrstats),
394 cpl_stats_get_stdev(ronerrstats),
395 cpl_stats_get_median(ronerrstats),
396 cpl_stats_get_min(ronerrstats),
397 cpl_stats_get_max(ronerrstats));
398 cpl_stats_delete(ronstats);
399 cpl_stats_delete(ronerrstats);
402 double ronmean = cpl_image_get_mean_window(ronimage, n, 1, n, nvalues),
403 ronmeanerr = cpl_image_get_mean_window(ronimage, n+4, 1, n+4, nvalues);
404 cpl_vector_set(ron, n - 1, ronmean);
405 cpl_vector_set(ronerr, n - 1, ronmeanerr);
409 ron2sl = ronmean - 2 * ronmeanerr,
410 ron2sh = ronmean + 2 * ronmeanerr;
411 if (ronheader < ron2sl || ronheader > ron2sh) {
412 cpl_msg_warning(__func__,
"The RON value for quadrant %hhu in the input "
413 "FITS header (RON=%f) is likely wrong as it is outside "
414 "a 2 sigma range (%f < %f < %f) around the computed "
415 "value", n, ronheader, ron2sl, ronmean, ron2sh);
418 cpl_image_delete(ronimage);
422 for (k = 0; k < nvalues; k++) {
423 for (n = 1; n <= 4; n++) {
429 double variance = (1. + 1. / (pow(2 * aHalfsize + 1, 2) * aNSamples))
430 * pow(cpl_vector_get(ron, n-1)/gain, 2);
432 cpl_msg_info(__func__,
"Quadrant %hhu: RON=%f, RONERR=%f, Variance=%f",
433 n, cpl_vector_get(ron, n-1), cpl_vector_get(ronerr, n-1),
439 cpl_image_fill_window(aList->
list[k]->
stat, window[0], window[2],
440 window[1], window[3], variance);
445 return cpl_bivector_wrap_vectors(ron, ronerr);
Structure definition for a collection of muse_images.
void muse_image_delete(muse_image *aImage)
Deallocate memory associated to a muse_image object.
cpl_size * muse_quadrants_get_window(const muse_image *aImage, unsigned char aQuadrant)
Determine the data window of a given quadrant on the CCD.
int muse_image_scale(muse_image *aImage, double aScale)
Scale a muse_image with correct treatment of variance.
double muse_pfits_get_gain(const cpl_propertylist *aHeaders, unsigned char aQuadrant)
find the detector gain (in units of count/adu)
cpl_image * data
the data extension
cpl_image * stat
the statistics extension
void muse_imagelist_delete(muse_imagelist *aList)
Free the memory of the MUSE image list.
void muse_imagelist_dump_statistics(muse_imagelist *aList)
Show statistics of a muse_image list.
Structure definition of MUSE three extension FITS file.
cpl_propertylist * header
the FITS header
unsigned int muse_imagelist_get_size(muse_imagelist *aList)
Return the number of stored images.
cpl_error_code muse_imagelist_scale_exptime(muse_imagelist *aList)
Scale muse_images to a common exposure time.
muse_image * muse_imagelist_get(muse_imagelist *aList, unsigned int aIdx)
Get the muse_image of given list index.
double muse_pfits_get_ron(const cpl_propertylist *aHeaders, unsigned char aQuadrant)
find the detector read-out noise
int muse_imagelist_is_uniform(muse_imagelist *aList)
Check that all images in the muse_imagelist have the same size.
cpl_bivector * muse_imagelist_compute_ron(muse_imagelist *aList, int aHalfsize, int aNSamples)
Compute the read-out noise from bias images in an imagelist.
muse_imagelist * muse_imagelist_new(void)
Create a new (empty) MUSE image list.
double muse_pfits_get_exptime(const cpl_propertylist *aHeaders)
find out the exposure time
muse_image ** list
The list of muse_images.
cpl_error_code muse_imagelist_set(muse_imagelist *aList, muse_image *aImage, unsigned int aIdx)
Set the muse_image of given list index.