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 <math.h>
00035 #include <cpl.h>
00036 #include "vircam_mods.h"
00037 #include "vircam_utils.h"
00038 #include "vircam_fits.h"
00039 #include "vircam_stats.h"
00040
00041 #define NTERMAX 15
00042 #define ITERMAX 7
00043 #define OGAP 0.01
00044 #define GAPMIN 0.25
00045 #define CLIPLEV 4.0
00046
00047 static int vircam_defringe_1(vir_fits **infiles, int nimages, vir_fits *fringe,
00048 vir_mask *mask, int nbsize, float *scaleout,
00049 int *status);
00050
00053
00105
00106
00107 extern int vircam_defringe(vir_fits **infiles, int nimages, vir_fits **fringes,
00108 int nfringes, vir_mask *mask, int nbsize,
00109 int *status) {
00110 float *sig_before,*scale,*idata,med,mad,ratio;
00111 unsigned char *bpm;
00112 int i,j,npts;
00113 char pname1[64],comment1[64],pname2[64],comment2[64];
00114 cpl_propertylist *ehu;
00115
00116
00117
00118 if (*status != VIR_OK)
00119 return(*status);
00120
00121
00122
00123 sig_before = cpl_malloc(nimages*sizeof(float));
00124 scale = cpl_malloc(nimages*sizeof(float));
00125
00126
00127
00128 bpm = vircam_mask_get_data(mask);
00129 npts = cpl_image_get_size_x(vircam_fits_get_image(infiles[0]))*
00130 cpl_image_get_size_y(vircam_fits_get_image(infiles[0]));
00131 for (i = 0; i < nimages; i++) {
00132 idata = cpl_image_get_data_float(vircam_fits_get_image(infiles[i]));
00133 vircam_medmad(idata,bpm,(long)npts,&med,&mad);
00134 sig_before[i] = 1.48*mad;
00135 }
00136
00137
00138
00139 for (i = 0; i < nfringes; i++) {
00140 (void)vircam_defringe_1(infiles,nimages,fringes[i],mask,nbsize,scale,
00141 status);
00142
00143
00144
00145 (void)sprintf(pname1,"ESO DRS FRINGE%d",i);
00146 (void)sprintf(comment1,"Fringe frame # %d",i);
00147 (void)sprintf(pname2,"ESO DRS FRNGSC%d",i);
00148 (void)sprintf(comment2,"Fringe scale # %d",i);
00149
00150
00151
00152 for (j = 0; j < nimages; j++) {
00153 ehu = vircam_fits_get_ehu(infiles[j]);
00154 cpl_propertylist_update_string(ehu,pname1,
00155 vircam_fits_get_fullname(fringes[i]));
00156 cpl_propertylist_set_comment(ehu,pname1,comment1);
00157 cpl_propertylist_update_float(ehu,pname2,scale[i]);
00158 cpl_propertylist_set_comment(ehu,pname2,comment2);
00159 }
00160 }
00161
00162
00163
00164
00165 for (i = 0; i < nimages; i++) {
00166 ehu = vircam_fits_get_ehu(infiles[i]);
00167 idata = cpl_image_get_data_float(vircam_fits_get_image(infiles[i]));
00168 vircam_medmad(idata,bpm,(long)npts,&med,&mad);
00169 ratio = sig_before[i]/(1.48*mad);
00170 cpl_propertylist_update_float(ehu,"ESO QC FRINGE_RATIO",ratio);
00171 cpl_propertylist_set_comment(ehu,"ESO QC FRINGE_RATIO",
00172 "Ratio RMS before to after defringing");
00173 }
00174 freespace(sig_before);
00175 freespace(scale);
00176 GOOD_STATUS
00177 }
00178
00179
00210
00211
00212 static int vircam_defringe_1(vir_fits **infiles, int nimages, vir_fits *fringe,
00213 vir_mask *mask, int nbsize, float *scaleout,
00214 int *status) {
00215 cpl_image *frback,*imback,*fringefit,*imfit;
00216 float frmed,immed,*frdata,*frorig,*wptr,*imdata,*data,scaleth,scalemin;
00217 float scaleprev,spreadmin,spreadfbest,gap,offset,clipmax,clip,spreadf;
00218 float scalefound,scale,scalelist[3],diff,spreadlist[3],a,b,c;
00219 long npts,ntot;
00220 int i,iter,nter,k,j;
00221 vir_fits *im;
00222 unsigned char *bpm;
00223
00224
00225
00226 if (*status != VIR_OK)
00227 return(*status);
00228
00229
00230
00231 vircam_backmap(fringe,mask,nbsize,&frback,&frmed);
00232
00233
00234
00235
00236 fringefit = cpl_image_subtract_create(vircam_fits_get_image(fringe),
00237 frback);
00238 cpl_image_subtract_scalar(fringefit,frmed);
00239 frdata = cpl_image_get_data_float(fringefit);
00240 npts = cpl_image_get_size_x(fringefit)*cpl_image_get_size_y(fringefit);
00241 frorig = cpl_image_get_data_float(vircam_fits_get_image(fringe));
00242
00243
00244
00245 wptr = cpl_malloc(npts*sizeof(float));
00246
00247
00248
00249 bpm = vircam_mask_get_data(mask);
00250
00251
00252
00253 for (i = 0; i < nimages; i++) {
00254 im = infiles[i];
00255
00256
00257
00258 vircam_backmap(im,mask,nbsize,&imback,&immed);
00259 imdata = cpl_image_get_data_float(vircam_fits_get_image(im));
00260 imfit = cpl_image_subtract_create(vircam_fits_get_image(im),imback);
00261 cpl_image_subtract_scalar(imfit,immed);
00262 data = cpl_image_get_data_float(imfit);
00263
00264
00265
00266
00267 scaleth = immed/frmed;
00268
00269
00270
00271 scalemin = 0.0;
00272 scaleprev = 1.0e6;
00273 spreadmin = 1.0e3;
00274 spreadfbest = 1.0e6;
00275 iter = 0;
00276 nter = 0;
00277 gap = scaleth;
00278 offset = 0.5;
00279 clipmax = 1.0e3;
00280
00281
00282
00283 while (nter < NTERMAX && iter < ITERMAX && (fabs(offset)*gap > OGAP ||
00284 gap > GAPMIN)) {
00285 iter++;
00286 nter++;
00287
00288
00289
00290 clip = min(clipmax,CLIPLEV*1.48*spreadmin);
00291
00292
00293
00294
00295 if (fabs(scalemin - scaleprev) < 0.5*gap)
00296 iter += 1;
00297 scaleprev = scalemin;
00298 if (fabs(offset) > 0.9)
00299 iter -= 1;
00300 gap = scaleth*pow(2.0,(double)(1-iter));
00301
00302
00303
00304 spreadf = 1.0e6;
00305 scalefound = 2.0;
00306
00307
00308
00309
00310 for (k = 0; k < 3; k++) {
00311 scale = scalemin + gap*(float)(k-1);
00312 scalelist[k] = scale;
00313 ntot = 0;
00314
00315
00316
00317 for (j = 0; j < npts; j++) {
00318 if (bpm[j] == 0) {
00319 diff = fabs(data[j] - scale*frdata[j]);
00320 if (diff < clip)
00321 wptr[ntot++] = diff;
00322 }
00323 }
00324
00325
00326
00327 spreadlist[k] = vircam_med(wptr,NULL,ntot);
00328 if (spreadlist[k] < spreadf) {
00329 spreadf = spreadlist[k];
00330 scalefound = scale;
00331 }
00332 }
00333
00334
00335
00336
00337 if (spreadf > spreadfbest) {
00338 nter = NTERMAX + 1;
00339
00340
00341
00342 } else {
00343 a = spreadlist[1];
00344 b = 0.5*(spreadlist[2] - spreadlist[0]);
00345 c = 0.5*(spreadlist[2] + spreadlist[0] - 2.0*spreadlist[1]);
00346 offset = max(min((-0.5*b/c),1.0),-1.0);
00347 spreadmin = a + b*offset + c*offset*offset;
00348 scalemin = scalelist[1] + offset*gap;
00349
00350
00351
00352
00353 if (spreadmin > spreadf) {
00354 spreadmin = spreadf;
00355 scalemin = scalefound;
00356 }
00357 }
00358
00359
00360
00361 spreadfbest = min(spreadfbest,spreadf);
00362
00363 }
00364
00365
00366
00367 if (iter == 0)
00368 scalemin = scaleth;
00369
00370
00371
00372 for (j = 0; j < npts; j++)
00373 imdata[j] -= scalemin*(frorig[j] - frmed);
00374 scaleout[i] = scalemin;
00375
00376
00377
00378 freeimage(imfit);
00379 freeimage(imback);
00380 }
00381
00382
00383
00384 freeimage(fringefit);
00385 freeimage(frback);
00386 freespace(wptr);
00387 GOOD_STATUS
00388 }
00389
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414