36 #include "vircam_mods.h"
37 #include "vircam_utils.h"
38 #include "vircam_fits.h"
39 #include "vircam_stats.h"
40 #include "vircam_pfits.h"
68 unsigned char clipped;
73 static dstrct *fileptrs = NULL;
74 static float *odata = NULL;
75 static float *owdata = NULL;
76 static keeptabs *clipmon = NULL;
80 static float sumweight;
84 static void average(keeptabs *,
float *,
float *,
float,
float,
float);
85 static keeptabs *clip_open(
int);
86 static void clip_close(keeptabs **);
87 static void fileptrs_close(
void);
88 static void skyest(
float *,
int *,
long,
float,
float *,
float *);
89 static void tidy(
void);
157 int nconfs,
float lthr,
float hthr,
158 cpl_propertylist **p, cpl_image **out,
159 cpl_image **outc,
int *status) {
161 int i,itx,iy,ccur,clast,ix,n,iline,icol,jy,jx,*ocdata,j;
162 long npts,ielm,iloc,index_y,index;
165 float minxoff,minyoff,expref,sky,skynoise,clip1,clip2,outdata;
166 float outconf,avlev,avvar,renorm,exposure;
167 double crpix1,crpix2;
168 cpl_propertylist *ehu,*p2;
169 const char *fctid =
"vircam_imdither";
177 if (*status != VIR_OK)
183 cpl_msg_error(fctid,
"No input files to combine");
195 fileptrs = cpl_malloc(nimages*
sizeof(dstrct));
197 expref = max(0.5,exposure);
200 for (i = 0; i < nimages; i++) {
206 }
else if (nconfs == 1) {
207 dd->conf = inconf[0];
210 dd->conf = inconf[i];
216 minxoff = min(dd->xoff,minxoff);
217 minyoff = min(dd->yoff,minyoff);
219 dd->expscale = exposure/expref;
225 npts = dd->nx*dd->ny;
226 skyest(dd->data,dd->cdata,npts,3.0,&sky,&skynoise);
228 dd->noise = skynoise;
235 cpl_msg_error(fctid,
"VIRCAM_IMDITHER: Image %s and Confidence map %s don't match",
245 for (i = 0; i < nimages; i++) {
249 dd->ixoff = (int)(dd->xoff + 0.5);
250 dd->iyoff = (int)(dd->yoff + 0.5);
257 fileptrs->sky /= fileptrs->expscale;
258 fileptrs->skydiff = 0.0;
259 fileptrs->weight = 1.0;
261 for (i = 1; i < nimages; i++) {
263 dd->sky /= dd->expscale;
264 dd->skydiff = fileptrs->sky - dd->sky;
265 dd->noise /= (float)sqrt((
double)dd->expscale);
266 dd->weight = (float)(pow((
double)fileptrs->noise,2.0)/pow((
double)dd->noise,2.0));
267 sumweight += dd->weight;
272 for (i = 1; i < nimages; i++) {
274 npts = dd->nx*dd->ny;
275 for (j = 0; j < npts; j++)
276 dd->data[j] = dd->data[j]/dd->expscale + dd->skydiff;
281 clip1 = fileptrs->sky - lthr*fileptrs->noise;
282 clip2 = fileptrs->sky + hthr*fileptrs->noise;
289 for (i = 0; i < nimages; i++) {
291 itx = dd->nx + dd->ixoff;
293 itx = dd->ny + dd->iyoff;
299 *out = cpl_image_new((cpl_size)nxo,(cpl_size)nyo,CPL_TYPE_FLOAT);
304 *outc = cpl_image_new((cpl_size)nxo,(cpl_size)nyo,CPL_TYPE_INT);
311 odata = cpl_image_get_data_float(*out);
313 owdata = cpl_malloc(npts*
sizeof(
float));
314 clipmon = clip_open(nimages);
319 for (iy = 0; iy < nyo; iy++) {
322 for (ix = 0; ix < nxo; ix++) {
323 c = clipmon + ccur + ix;
327 for (i = 0; i < nimages; i++) {
329 iline = iy - dd->iyoff;
330 if (iline < 0 || iline >= dd->ny)
332 icol = ix - dd->ixoff;
333 if (icol < 0 || icol >= dd->nx)
339 ielm = dd->nx*iline + icol;
340 c->values[n] = dd->data[ielm];
341 c->confs[n] = dd->cdata[ielm];
342 c->weights[n] = dd->weight;
343 c->iff[n] = (
short int)i;
346 c->outindex = nxo*iy + ix;
348 average(c,&outdata,&outconf,clip1,clip2,0.0);
349 odata[c->outindex] = outdata;
351 owdata[c->outindex] = outconf;
360 for (ix = 1; ix < nxo-1; ix++) {
361 c = clipmon + clast + ix;
370 for (jy = -1; jy <= 1; jy++) {
371 index_y = iloc + jy*nxo;
372 for (jx = -1; jx <= 1; jx++) {
373 index = index_y + jx;
374 avlev += odata[index];
379 for (jy = -1; jy <= 1; jy++) {
380 index_y = iloc + jy*nxo;
381 for (jx = -1; jx <= 1; jx++) {
382 index = index_y + jx;
383 avvar += fabs(odata[index] - avlev);
392 if (avlev < clip2 || avvar <= 2.0*fileptrs->noise)
397 average(c,&outdata,&outconf,clip1,clip2,3.0*avvar);
398 odata[c->outindex] = outdata;
400 owdata[c->outindex] = outconf;
406 if (owdata != NULL) {
407 skyest(owdata,NULL,npts,3.0,&sky,&skynoise);
409 ocdata = cpl_image_get_data_int(*outc);
410 for (i = 0; i < npts; i++)
411 ocdata[i] = max(0,min(1000,((
int)(owdata[i]*renorm + 0.5))));
423 cpl_propertylist_update_string(p2,
"VIR_TIME",timestamp);
424 cpl_propertylist_set_comment(p2,
"VIR_TIME",
425 "Timestamp for matching to conf map");
431 crpix1 += fileptrs->xoff;
432 crpix2 += fileptrs->yoff;
433 cpl_propertylist_update_double(*p,
"CRPIX1",crpix1);
434 cpl_propertylist_update_double(*p,
"CRPIX2",crpix2);
442 static void average(keeptabs *c,
float *outdata,
float *outconf,
float cliplow,
443 float cliphigh,
float extra) {
445 float valuemax,valuemin,cwmin,cwmax,sum,cnumb,numb,cw,cv,reflev,noise;
453 *outdata = fileptrs->sky;
474 for (i = 0; i < c->n; i++) {
475 cw = c->weights[i]*c->confs[i];
492 *outdata = sum/cnumb;
494 *outdata = fileptrs->sky;
498 if (valuemax > cliphigh && numb > 150.0 && cnumb > 150.0) {
499 reflev = (sum - valuemax*cwmax)/(cnumb - cwmax);
500 noise = (fileptrs+c->iff[imax])->noise;
501 sky = (fileptrs+c->iff[imax])->sky;
502 clipval = reflev + hsig*noise*max(1.0,reflev)/max(1.0,sky) + extra;
503 if (valuemax > clipval) {
504 sum -= valuemax*cwmax;
513 if (valuemin < cliplow && numb > 150.0 && cnumb > 150.0) {
514 reflev = (sum - valuemin*cwmin)/(cnumb - cwmin);
515 noise = (fileptrs+c->iff[imin])->noise;
516 clipval = reflev - lsig*noise;
517 if (valuemin < clipval) {
525 *outconf = cnumb/sumweight;
529 static keeptabs *clip_open(
int nimages) {
535 c = cpl_malloc(2*nxo*
sizeof(keeptabs));
536 for (i = 0; i < 2*nxo; i++) {
537 dptr = cpl_malloc(3*nimages*
sizeof(*dptr));
538 iff = cpl_malloc(nimages*
sizeof(*iff));
539 (c+i)->values = dptr;
540 (c+i)->confs = dptr + nimages;
541 (c+i)->weights = dptr + 2*nimages;
544 (c+i)->outindex = -1;
550 static void clip_close(keeptabs **c) {
553 for (i = 0; i < 2*nxo; i++) {
554 freespace((*c+i)->values);
555 freespace((*c+i)->iff);
560 static void fileptrs_close(
void) {
567 static void skyest(
float *data,
int *cdata,
long npts,
float thresh,
568 float *skymed,
float *skynoise) {
574 bpm = cpl_calloc(npts,
sizeof(*bpm));
576 for (i = 0; i < npts; i++)
577 bpm[i] = (cdata[i] == 0);
582 vircam_qmedsig(data,bpm,npts,thresh,2,-1000.0,65535.0,skymed,skynoise);
589 static void tidy(
void) {
592 clip_close(&clipmon);