1
/*===========================================================================
2
Copyright (C) 1989-2009 European Southern Observatory (ESO)
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License as
6
published by the Free Software Foundation; either version 2 of
7
the License, or (at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public
15
License along with this program; if not, write to the Free
16
Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,
19
Correspondence concerning ESO-MIDAS should be addressed as follows:
20
Internet e-mail: midas@eso.org
21
Postal address: European Southern Observatory
22
Data Management Division
23
Karl-Schwarzschild-Strasse 2
24
D 85748 Garching bei Muenchen
26
===========================================================================*/
29
/* ++++++++++++++++++++++++++++++++++++++++++++++++++
32
program AVERAGW version 1.00 090729
33
K. Banse ESO - Garching
36
bulk data frames, average
39
average a no. of weighted image frames, the result will either be a frame
40
with size equal to common area of all frames involved or
41
size equal to union of all frame areas
44
extract input frames either from given parameter string or from catalogue,
45
add up all frames + divide in the end
48
the following keys are used:
50
ACTION/C/1/2 (1:1) = M or N, for merging option
51
(2:2) = I or W, for AVERAGE/IMAGE, /WEIGHTS
52
OUT_A/C/1/60 result frame
53
P3/C/1/80 list of frames to be averaged
58
-------------------------------------------------- */
60
#include <midas_def.h>
65
#define MAXIMSONE MAXIMS+1
75
void wfill(iaux,ww,a,x,z,apix,cpix,npixa,npixc)
76
int *iaux, apix[3][2], *cpix;
83
int nn, nin, nini, jump, indx, cntdx;
84
int nx, ny, xfirst, yfirst, xend, yend;
91
/* ---------------------------
93
the intermediate z-space is structured as follows:
95
pix(1) pix(2) up to pix(FRMCNT) 1 )
96
pix(1) pix(2) up to pix(FRMCNT) 2 )
98
pix(1) pix(2) up to pix(FRMCNT) NPIXC(1) )
101
--------------------------- */
104
/* if here for the first time, init the count `pixels' */
111
nn = npixc[0] * npixc[1];
112
if ((iaux[5] == 0) && (iaux[2] == 0))
113
rr = (float) wsum; /* for `nomerge' and `all data' */
116
for (nr=0; nr<nn; nr++) x[nr] = rr;
119
if (iaux[0] == 0) return; /* if iaux[0] = 0, not much to do */
121
nini = 0; /* input frame begins with 1. valid pixel */
124
/* --------------------------------- */
125
/* here for the non-merging option */
126
/* --------------------------------- */
128
indx = count; /* take all pixels */
129
for (nn=0; nn<npixc[1]; nn++)
132
for (nr=0; nr<npixc[0]; nr++)
134
z[indx] = ww * a[nin++];
137
nini += npixa; /* follow with input index */
142
/* ----------------------------- */
143
/* here for the merging option */
144
/* ----------------------------- */
146
nx = apix[0][1] - apix[0][0]; /* get overlapping part */
147
ny = apix[1][1] - apix[1][0];
152
jump = frmcnt * npixc[0];
157
for (nn=0; nn<npixc[1]; nn++)
160
if ((nn >= yfirst) && (nn <= yend))
163
for (nr=0; nr<npixc[0]; nr++)
165
if ((nr >= xfirst) && (nr <= xend))
167
z[indx] = ww * a[nin++];
168
x[cntdx] += ww; /* increment weight sum */
173
nini += npixa; /* follow with input index */
177
indx += jump; /* jump a whole line; */
183
for (cntdx=0; cntdx<5; cntdx++)
185
printf("x[%d] = %f\n",cntdx,x[cntdx]);
195
void wadd(flag,iaux,x,z,c,cuts,npixc,nc)
197
int flag, *iaux, *nc;
198
float *x, *z, *c, *cuts;
201
int frmcnt, n, mcc, indx, size;
213
size = npixc[0] * npixc[1];
216
/* -------------------------------*/
217
/* here for the normal average */
218
/* -------------------------------*/
220
for (cntdx=0; cntdx<size; cntdx++) /* loop through count buffer */
227
mcc ++; /* increment null count */
232
for (n=indx+1; n<indx+frmcnt; n++) sum += z[n];
237
if (cuts[0] > rval) cuts[0] = rval; /* update min + max */
238
if (cuts[1] < rval) cuts[1] = rval;
252
int uni, ec, ed, el, ln0, ln1;
253
int imnoc, imnox, imnol[MAXIMS];
254
int felm, sizec, chunk[MAXIMS], chunkc;
255
int naxis[MAXIMS], npix[MAXIMS][3], naxisc, npixc[3];
256
int iseq, iav, nulo, zpix[3];
257
int apix[3][2], cpix[3];
259
int stat, nolin, begin;
261
int frmcnt, nulcnt, kk, m, dim3, floff;
262
int debufl=0, planesize=0;
265
char *wpntr, *tmpntr;
266
char line[84], action[4];
267
char frame[84], framec[84], catfil[84];
268
char cunit[64], ident[72], output[84];
269
static char error1[] = "operands do not match in stepsize... ";
270
static char error2[] = "operands do not overlap... ";
271
static char error3[] = "stepsizes of different sign... ";
272
static char error4[] = "catalog empty... ";
273
static char mesalloc[] = "could not allocate virtual memory...";
275
double step[MAXIMS][3], start[MAXIMS][3];
276
double stepc[3], ostep[3], endc[3];
277
double startc[3], ostart[3], oldend[3];
280
float *pntr[MAXIMS], *pntrc, *xpntr, *zpntr;
281
float dif, eps[3], cuts[4], w[MAXIMS];
284
/* set up MIDAS environment + enable automatic error abort */
288
pntrc = zpntr = (float *) 0;
291
for (nr=0; nr<3; nr++)
310
/* get result frame, input frame list, action flag */
312
(void) SCKGETC("OUT_A",1,80,&iav,framec);
313
(void) SCKGETC("P3",1,80,&iav,line);
314
(void) SCKGETC("ACTION",1,2,&iav,action);
315
CGN_UPSTR(action); /* convert to upper case */
317
(void) SCKGETC("MID$SPEC",1,5,&iav,output);
319
if ( strcmp(output,"DEBUG") == 0) debufl = 1; /* set debug flag */
322
/* ---------------------------
324
the auxiliary arrays iaux contains the following:
326
iaux[0] = 1, input data is inside result space
327
0, only initialize counter pixels if necessary
328
iaux[1,2,3,4] = not used
329
iaux[5] = 0, `nomerge' option
331
iaux[6] = frame count
334
--------------------------- */
336
for (nr=0; nr<10; nr++) iaux[nr] = 0;
341
(void) SCKGETC("P5",1,40,&iav,output);
342
if ((output[0] == '+') && (output[1] == '\0')) /* use key NULL(2) */
343
(void) SCKRDR("NULL",2,1,&iav,&usrnul,&uni,&nulo);
346
iav = CGN_CNVT(output,2,1,npixc,&usrnul,&aostep);
348
SCETER(19,"invalid `null value' ...");
353
/* test, if we have list of frames or catalog */
355
kk = CGN_INDEXS(line,".cat");
356
if (kk <= 0) kk = CGN_INDEXS(line,".CAT");
359
/* here we handle input from a catalog - get name of first image file
364
if ((int)strlen(line) > 63)
365
SCETER(3,"catalog name too long...");
367
(void) strcpy(catfil,line);
370
for (frmcnt=0; frmcnt<MAXIMS; frmcnt++) /* max. MAXIMS frames */
372
(void) SCCGET(catfil,0,frame,output,&iseq);
373
if (frame[0] == ' ') break; /* indicates the end ... */
376
(void) SCFOPN(frame,D_R4_FORMAT,0,F_IMA_TYPE,&imnol[frmcnt]);
378
sprintf(output,"%d images from catalog to be processed",frmcnt);
383
/* here we handle input from single input line - pull out operands */
388
m = (int) strlen(line);
389
for (frmcnt=0; frmcnt<MAXIMS; frmcnt++)
391
kk = CGN_EXTRSS(line,m,',',&begin,output,60);
394
CGN_FRAME(output,F_IMA_TYPE,frame,0); /* convert frames */
396
stat = SCFOPN(frame,D_R4_FORMAT,0,F_IMA_TYPE,&imnol[frmcnt]);
400
if (frmcnt <= 0) SCETER(4,error4); /* there must be at least 1 image */
403
/* --------------------------------------------*/
404
/* get initial area from 1. frame */
405
/* --------------------------------------------*/
407
(void) SCDRDI(imnol[0],"NAXIS",1,1,&iav,&naxis[0],&uni,&nulo);
408
(void) SCDRDI(imnol[0],"NPIX",1,3,&iav,&npix[0][0],&uni,&nulo);
409
(void) SCDRDD(imnol[0],"START",1,3,&iav,&start[0][0],&uni,&nulo);
410
(void) SCDRDD(imnol[0],"STEP",1,3,&iav,&step[0][0],&uni,&nulo);
411
(void) SCDGETC(imnol[0],"CUNIT",1,64,&iav,cunit);
414
for (nr=0; nr<3; nr++)
416
ostart[nr] = start[0][nr];
417
ostep[nr] = step[0][nr];
419
if (aostep < 0.0) aostep = - aostep;
420
eps[nr] = 0.0001 * aostep; /* take 0.01% of stepsize */
421
oldend[nr] = ostart[nr] + (npix[0][nr]-1)*ostep[nr];
423
cuts[0] = 999999.0; /* cuts[0] > cuts[1] */
427
/* loop + look for descriptor WEIGHT */
429
stat = SCECNT("GET",&ec,&el,&ed);
431
stat = SCECNT("PUT",&ln1,&ln0,&ln0);
434
for (nr=0; nr< frmcnt; nr++)
436
stat = SCDRDR(imnol[nr],"WEIGHT",1,1,&iav,&w[nr],&uni,&nulo);
437
if (stat != ERR_NORMAL)
440
(void) sprintf(line,"frame no. %d: descr. WEIGHT missing - set to 1.0 ",imnol[nr]);
448
stat = SCECNT("PUT",&ec,&el,&ed);
450
/* now loop through the other input frames */
452
for (nr=1; nr< frmcnt; nr++)
454
for (m=0; m<3; m++) /* init values... */
461
(void) SCDRDI(imnol[nr],"NAXIS",1,1,&iav,&naxis[nr],&uni,&nulo);
462
(void) SCDRDI(imnol[nr],"NPIX",1,3,&iav,&npix[nr][0],&uni,&nulo);
463
(void) SCDRDD(imnol[nr],"START",1,3,&iav,&start[nr][0],&uni,&nulo);
464
(void) SCDRDD(imnol[nr],"STEP",1,3,&iav,&step[nr][0],&uni,&nulo);
467
/* stepsizes should have same sign and not differ too much... */
471
if ((ostep[m]*step[nr][m]) <= 0.) SCETER(1,error3);
472
aostep = step[nr][m] - ostep[m];
473
if (aostep < 0.) aostep = -aostep;
475
if (aostep > eps[m]) SCETER(5,error1);
479
/* get intersection or union of image areas */
481
if (action[0] != 'M') /* intersection */
485
dif = start[nr][m] + (npix[nr][m]-1)*step[nr][m];
488
if (ostart[m] < start[nr][m]) ostart[m] = start[nr][m]; /* MAX */
489
if (oldend[m] > dif) oldend[m] = dif; /* MIN */
493
if (ostart[m] > start[nr][m]) ostart[m] = start[nr][m]; /* MIN */
494
if (oldend[m] < dif) oldend[m] = dif; /* MAX */
502
dif = start[nr][m] + (npix[nr][m]-1)*step[nr][m];
505
if (ostart[m] < start[nr][m]) ostart[m] = start[nr][m]; /* MAX */
506
if (oldend[m] > dif) oldend[m] = dif; /* MIN */
510
if (ostart[m] > start[nr][m]) ostart[m] = start[nr][m]; /* MIN */
511
if (oldend[m] < dif) oldend[m] = dif; /* MAX */
520
/* test, if something is left... */
524
if (ostep[m]*(oldend[m]-ostart[m]) < 0.) SCETER(2,error2);
528
/* create new result frame with dimension as intersection
529
or union of input frames */
532
if (action[0] == 'M')
534
for (nr=1; nr<frmcnt; nr++)
536
if (naxisc < naxis[nr]) naxisc = naxis[nr]; /* MAX */
541
for (nr=1; nr<frmcnt; nr++)
543
if (naxisc > naxis[nr]) naxisc = naxis[nr]; /* MIN */
548
/* check, if input from a cube */
559
/* set up standard stuff for result frame */
562
for (nr=0; nr<naxisc; nr++)
564
startc[nr] = ostart[nr];
565
stepc[nr] = ostep[nr];
566
npixc[nr] = CGN_NINT((oldend[nr]-ostart[nr]) / stepc[nr]) + 1;
567
sizec = sizec * npixc[nr];
571
(void) SCFCRE(framec,D_R4_FORMAT,F_O_MODE,F_IMA_TYPE,sizec,&imnoc);
572
(void) SCDWRI(imnoc,"NAXIS",&naxisc,1,1,&uni);
573
(void) SCDWRI(imnoc,"NPIX",npixc,1,naxisc,&uni);
574
(void) SCDWRD(imnoc,"START",startc,1,naxisc,&uni);
575
(void) SCDWRD(imnoc,"STEP",stepc,1,naxisc,&uni);
576
(void) strcpy(ident,"average frame ");
577
(void) SCDWRC(imnoc,"IDENT",1,ident,1,72,&uni);
578
ln1 = (naxisc+1) * 16;
579
(void) SCDWRC(imnoc,"CUNIT",1,cunit,1,ln1,&uni);
582
/* in case of debugging save the counts in MIDAS image averdumy.dum */
587
(void) strcpy(frame,"averdumy.dum");
588
(void) SCFCRE(frame,D_R4_FORMAT,F_O_MODE,F_IMA_TYPE,sizec,&imnox);
589
(void) SCDWRI(imnox,"NAXIS",&naxisc,1,1,&uni);
590
(void) SCDWRI(imnox,"NPIX",npixc,1,naxisc,&uni);
591
(void) SCDWRD(imnox,"START",startc,1,naxisc,&uni);
592
(void) SCDWRD(imnox,"STEP",stepc,1,naxisc,&uni);
593
(void) strcpy(ident,"valid pixel counts ");
594
(void) SCDWRC(imnox,"IDENT",1,ident,1,72,&uni);
595
(void) SCDWRC(imnox,"CUNIT",1,cunit,1,ln1,&uni);
599
/* see, if keyword MONITPAR(20) holds amount of virtual memory available */
601
(void) SCKRDI("MONITPAR",20,1,&iav,&chunkc,&uni,&nulo);
602
ln1 = (chunkc * chunkc) / 5; /* `chunkc' = x-dim of square image
603
which can be fully mapped */
605
stripe = 1; /* at least a single line */
607
stripe = ln1 / npixc[0];
610
/* get virtual memory buffers */
612
if (npixc[1] < stripe) stripe = npixc[1];
613
chunkc = stripe * npixc[0]; /* size of 1 result strip */
614
kk = chunkc * sizeof(float);
615
wpntr = malloc((size_t)kk);
616
if (wpntr == (char *) 0)
619
pntrc = (float *) wpntr;
623
if (npix[0][1] < stripe)
624
iav = npix[0][1]; /* iav = y-dim */
628
chunk[0] = iav * npix[0][0]; /* always stripe lines */
629
for (nr=0; nr<dim3; nr++)
630
{ /* all chunks like chunk[0] */
631
chunk[nr] = chunk[0];
632
kk = chunk[nr] * sizeof(float);
633
wpntr = malloc((size_t)kk);
634
if (wpntr == (char *) 0)
637
pntr[nr] = (float *) wpntr;
639
imnol[nr] = imnol[0];
640
for (m=0; m<naxisc; m++)
642
npix[nr][m] = npix[0][m];
643
start[nr][m] = start[0][m];
644
step[nr][m] = step[0][m];
650
for (nr=0; nr<frmcnt; nr++)
652
if (npix[nr][1] < stripe)
653
iav = npix[nr][1]; /* iav = y-dim */
657
chunk[nr] = iav * npix[nr][0]; /* always stripe lines */
658
kk = chunk[nr] * sizeof(float);
659
wpntr = malloc((size_t)kk);
660
if (wpntr == (char *) 0)
663
pntr[nr] = (float *) wpntr;
668
/* now map chunk for z-direction and count buffer */
672
planesize = npixc[0] * npixc[1];
678
kk = m * sizeof(float);
679
wpntr = malloc((size_t)kk);
680
if (wpntr == (char *) 0)
683
zpntr = (float *) wpntr;
685
kk = chunkc * sizeof(float);
686
wpntr = malloc((size_t)kk);
687
if (wpntr == (char *) 0)
690
xpntr = (float *) wpntr;
693
/* here the main loops over all chunks
694
first fill the cube chunk, work on it + store result */
696
endc[0] = startc[0] + (npixc[0]-1)*stepc[0];
697
endc[1] = startc[1] + (stripe-1)*stepc[1];
701
for (nolin=0; nolin<npixc[1]; nolin+=stripe)
703
if ((nolin+stripe) > npixc[1]) /* adjust chunk size */
705
stripe = npixc[1] - nolin;
706
chunkc = stripe * npixc[0];
707
for (nr=0; nr<frmcnt; nr++)
708
chunk[nr] = stripe * npix[nr][0];
712
floff = 0; /* for data cube input */
713
for (nr=0; nr<frmcnt; nr++)
716
/* convert start + end of overlap region into pixel no.'s */
718
for (m=0; m<naxisc; m++)
720
dif = (start[nr][m]-startc[m]) / stepc[m];
725
cpix[m] = CGN_NINT(dif); /* offset in output */
726
if (cpix[m] >= zpix[m])
733
dif = (startc[m]-start[nr][m]) / step[nr][m];
734
if (dif < 0.1) /* offset in input */
738
apix[m][0] = CGN_NINT(dif);
739
if (apix[m][0] >= npix[nr][m])
746
dif = (endc[m]-start[nr][m]) / step[nr][m];
747
apix[m][1] = CGN_NINT(dif);
748
if (apix[m][1] >= npix[nr][m]) apix[m][1] = npix[nr][m] - 1;
752
/* remember, SCFGET/SCFPUT begins with 1! */
753
felm = floff + (apix[1][0] * npix[nr][0]) + apix[0][0] + 1;
754
tmpntr = (char *) pntr[nr];
755
stat = SCFGET(imnol[nr],felm,chunk[nr],&iav,tmpntr);
758
sect_5360: /* fill z-buffer */
760
wfill(iaux,w[nr],pntr[nr],xpntr,zpntr,apix,cpix,npix[nr][0],zpix);
765
/* now do the calculus */
767
wadd(optio,iaux,xpntr,zpntr,pntrc,cuts,zpix,&kk);
770
/* and write results to disk */
772
felm = nolin*npixc[0] + 1;
773
tmpntr = (char *) pntrc;
774
(void) SCFPUT(imnoc,felm,chunkc,tmpntr);
775
nulcnt += kk; /* update null count */
778
tmpntr = (char *) xpntr;
779
(void) SCFPUT(imnox,felm,chunkc,tmpntr); /* if debug, update on disk */
783
/* follow chunks with start + end value */
785
aostep = stripe*stepc[1];
791
/* update descriptors + cuts of result frame */
795
CGN_DSCUPD(imnol[0],imnoc,frame);
799
(void) SCDWRR(imnoc,"LHCUTS",cuts,1,4,&uni);
801
cuts[0] = nulcnt; /* update key NULL */
809
(void) SCKWRR("NULL",cuts,1,ln1,&uni);
813
(void) sprintf(output,
814
"%d undefined pixels, set to `null value' (= %12.6f)",nulcnt,usrnul);
816
(void) sprintf(output,
817
"%d undefined pixels, set to `previous pixel'",nulcnt);