1
C @(#)avwndw.for 19.1 (ESO-DMD) 02/25/03 14:01:40
2
C===========================================================================
3
C Copyright (C) 1995 European Southern Observatory (ESO)
5
C This program is free software; you can redistribute it and/or
6
C modify it under the terms of the GNU General Public License as
7
C published by the Free Software Foundation; either version 2 of
8
C the License, or (at your option) any later version.
10
C This program is distributed in the hope that it will be useful,
11
C but WITHOUT ANY WARRANTY; without even the implied warranty of
12
C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
C GNU General Public License for more details.
15
C You should have received a copy of the GNU General Public
16
C License along with this program; if not, write to the Free
17
C Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,
20
C Correspondence concerning ESO-MIDAS should be addressed as follows:
21
C Internet e-mail: midas@eso.org
22
C Postal address: European Southern Observatory
23
C Data Management Division
24
C Karl-Schwarzschild-Strasse 2
25
C D 85748 Garching bei Muenchen
27
C===========================================================================
31
C++++++++++++++++++++++++++++++++++++++++++++++++++
34
C program AVWNDW version 1.00 890123
35
C K. Banse ESO - Garching
36
C 1.20 890529 1.30 900130
39
C bulk data frames, average
42
C average a no. of image frames, take only values which don't differ too much
43
C from the median value (at each pixel), the result will either be a frame with
44
C size equal to common area of all frames involved or size equal to union of
48
C extract input frames either from given parameter string or from catalogue,
49
C add up all frames + divide in the end
50
C max. 20 frames may be averaged at one time !
53
C the following keys are used:
55
C ACTION/C/1/3 = WIN, MED, MIN or MAX
56
C OUT_A/C/1/60 result frame
57
C P3/C/1/80 list of frames to be averaged
58
C INPUTR/R/1/2 BGERR,SNOISE - Poisson + Gaussian errors
61
C the following descriptors are used with WINDOW option:
62
C LHCUTS/R/5/2 low, high cuts for calculations
63
C FLAT_BKG/R/1/1 background value
64
C O_TIME/D/7/1 exposure time
70
C--------------------------------------------------
74
INTEGER BEGIN,FRMCNT,IAV,ISEQ
75
INTEGER L,LL,LP,M,IOFF
76
INTEGER N,NAXIS,NAXISC,NCHECK,NIN,NP,NPERC,NTL
80
INTEGER NPIX(3),NPIXC(3)
81
INTEGER OFX(20),OFY(20),POFF(20),NPNTS(20)
82
INTEGER IORD(20),NORD(20),REJ(20),TNP(4)
84
INTEGER UNI(1),NULO,MADRID(1)
85
INTEGER LEN,INDEX !system functions
87
CHARACTER FRAME(20)*60,FRAMEC*60,CATFIL*60
88
CHARACTER CUNIT*64,IDENT*72,OUTPUT*80
89
CHARACTER NOCUTS*60,LINE*80,ACTION*3
90
CHARACTER ERROR1*60,ERROR2*50,ERROR3*40,ERROR4*40,ERROR6*40
91
CHARACTER ERROR7*40,ERROR9*60
93
DOUBLE PRECISION STEP(2,20),STEPC(2)
94
DOUBLE PRECISION START(2,20),STARTC(2),OSTART(2),OEND(2)
97
REAL VAL(20),BGV(20),RMS(20),RFC(20)
98
REAL AJCUL(20),AJCUH(20),AJCU(2),SNOISE,BGERR
99
REAL INPUTR(2),EXPTI(20)
101
DOUBLE PRECISION EXPTIM
103
INCLUDE 'MID_INCLUDE:ST_DEF.INC'
106
COMMON /MYREAL/ VAL,BGV,RMS,RFC,AJCUL,AJCUH,SNOISE,BGERR,EXPTI
107
COMMON /MYINT/ IORD,NORD,REJ,TNP
109
DATA IDENT /'average frame '/
110
DATA ERROR1 /'operands do not match in stepsize... '/
111
DATA ERROR2 /'operands do not overlap...'/
112
DATA ERROR3 /'stepsizes of different sign...'/
113
DATA ERROR4 /'catalogue empty...'/
114
DATA ERROR6 /'no. of input frames < 2 ...'/
115
DATA ERROR7 /'more than 20 entries in catalogue...'/
116
DATA ERROR9 /'no. of axes do not match... '/
117
DATA NOCUTS /'LHCUTS(5,6) not there - use LHCUTS(3,4)... '/
118
DATA STARTC /2*0.D0/, STEPC /2*1.D0/
120
INCLUDE 'MID_INCLUDE:ST_DAT.INC'
122
C set up MIDAS environment + enable automatic error abort
123
CALL STSPRO('AVWNDW')
125
C init COMMON variables
134
CALL STKRDC('ACTION',1,1,3,IAV,ACTION,UNI,NULO,STAT) !get option
135
CALL STKRDC('OUT_A',1,1,60,IAV,FRAMEC,UNI,NULO,STAT) !get result frame
136
CALL STKRDC('P3',1,1,80,IAV,LINE,UNI,NULO,STAT) !list of frames
137
CALL UPCAS(ACTION,ACTION)
138
IF (ACTION(1:1).EQ.'W') THEN !only for real window option
139
CALL STKRDR('INPUTR',1,2,IAV,INPUTR,UNI,NULO,STAT)
140
BGERR = INPUTR(1) * INPUTR(1) !take square of errors
141
SNOISE = INPUTR(2) * INPUTR(2)
144
C test, if we have list of frames or catalogue
145
LL = INDEX(LINE,'.cat')
147
LL = INDEX(LINE,'.CAT')
148
IF (LL.LE.0) GOTO 500 !No. Treat list input
151
C here we handle input from a catalog
152
C get name of first image file in catalog
155
CATFIL(1:) = LINE(1:)
156
CALL STCGET(CATFIL,0,FRAME(1),OUTPUT,ISEQ,STAT)
157
IF (FRAME(1)(1:1).EQ.' ') !there must be at least 1 image
158
+ CALL STETER(4,ERROR4)
160
C now loop through catalogue
161
DO 200 N=2,20 !max. 20 frames
162
CALL STCGET(CATFIL,0,FRAME(N),OUTPUT,ISEQ,STAT)
163
IF (FRAME(N)(1:1).EQ.' ') THEN !indicates the end ...
169
CALL STCGET(CATFIL,0,LINE,OUTPUT,ISEQ,STAT)
170
IF (LINE(1:1).NE.' ')
172
+ ('Max. 20 frames are used, following frames ignored...',STAT)
176
C here we handle input from single inout line
177
C pull out operands (max. 20)
180
DO 800 N=1,21 !max. of 20 frames...!
181
CALL EXTRSS(LINE,',',BEGIN,FRAME(N),LL)
186
CALL CLNFRA(FRAME(N),FRAME(N),0)
190
C check no. of input frames
191
1000 IF (FRMCNT.LT.2) CALL STETER(6,ERROR6)
194
DO 1100 M=1,2 !init values...
201
C get initial area from 1. frame
202
DO 1400 M=1,2 !init values...
208
CALL STFOPN(FRAME(1),D_R4_FORMAT,0,F_IMA_TYPE,IMN(1),STAT)
209
CALL STDRDI(IMN(1),'NAXIS',1,1,IAV,NAXISC,UNI,NULO,STAT)
210
IF (NAXISC.GT.2) THEN !we only work on max 2-dim. frames
212
OUTPUT(1:) = 'currently only 1 or 2-dim frames supported... '
213
CALL STTPUT(OUTPUT,STAT)
216
CALL STDRDI(IMN(1),'NPIX',1,2,IAV,NPIX,UNI,NULO,STAT)
218
CALL STDRDD(IMN(1),'START',1,2,IAV,START(1,1),UNI,NULO,STAT)
219
OSTART(1) = START(1,1)
220
OSTART(2) = START(2,1)
221
CALL STDRDD(IMN(1),'STEP',1,2,IAV,STEP(1,1),UNI,NULO,STAT)
224
CALL STDRDC(IMN(1),'CUNIT',1,1,64,IAV,CUNIT,UNI,NULO,STAT)
226
C for "real" window option get exposure-time, low + high cuts and background
227
IF (ACTION(1:1).EQ.'W') THEN
228
CALL STECNT('GET',EC,EL,ED) !disable error abort
229
CALL STECNT('PUT',1,0,0)
231
CALL STDRDD(IMN(1),'O_TIME',7,1,IAV,EXPTIM,UNI,NULO,STAT)
233
EXPTI(1) = 1.0 !default to 1 second
238
C get LHCUTS(5,6) - if not there use LHCUTS(3,4)
239
CALL STDRDR(IMN(1),'LHCUTS',5,2,IAV,AJCU,UNI,NULO,STAT)
241
CALL STTPUT(NOCUTS,STAT)
242
CALL STDRDR(IMN(1),'LHCUTS',3,2,IAV,AJCU,UNI,NULO,STAT)
244
IF (AJCU(2).LE.AJCU(1))
245
+ CALL STETER(43,'invalid LHCUTS: LHCUTS(6).LE.LHCUTS(5)...')
249
CALL STDRDR(IMN(1),'FLAT_BKG',1,1,IAV,BGV(1),UNI,NULO,STAT)
250
IF (STAT.NE.0) BGV(1) = 0. !default to background = 0.
251
CALL STECNT('PUT',EC,EL,ED)
255
EPS(M) = 0.0001 * ABS(STEPC(M)) !0.01% of stepsize as epsilon
256
OEND(M) = OSTART(M) + (NPIX(M)-1)*STEPC(M)
259
C now loop through the other input frames
261
CALL STFOPN(FRAME(N),D_R4_FORMAT,0,F_IMA_TYPE,IMN(N),STAT)
263
CALL STDRDI(IMN(N),'NAXIS',1,1,IAV,NAXIS,UNI,NULO,STAT)
264
IF (NAXISC.NE.NAXIS) CALL STETER(1,ERROR9)
266
CALL STDRDI(IMN(N),'NPIX',1,2,IAV,NPIX,UNI,NULO,STAT)
268
CALL STDRDD(IMN(N),'START',1,2,IAV,START(1,N),UNI,NULO,STAT)
269
CALL STDRDD(IMN(N),'STEP',1,2,IAV,STEP(1,N),UNI,NULO,STAT)
271
IF (ACTION(1:1).EQ.'W') THEN
272
CALL STECNT('GET',EC,EL,ED) !disable error abort
273
CALL STECNT('PUT',1,0,0)
275
CALL STDRDD(IMN(N),'O_TIME',7,1,IAV,EXPTIM,UNI,NULO,STAT)
277
EXPTI(N) = 1.0 !default to 1 second
282
CALL STDRDR(IMN(N),'LHCUTS',5,2,IAV,AJCU,UNI,NULO,STAT)
284
+ CALL STDRDR(IMN(N),'LHCUTS',3,2,IAV,AJCU,UNI,NULO,STAT)
288
CALL STDRDR(IMN(N),'FLAT_BKG',1,1,IAV,BGV(N),UNI,NULO,STAT)
289
IF (STAT.NE.0) BGV(N) = 0. !default to background = 0.
290
CALL STECNT('PUT',EC,EL,ED)
293
C create new result frame with dimension as intersection of input frames
294
C stepsizes should have same sign and not differ too much...
296
IF (STEPC(M)*STEP(M,N).LE.0.) CALL STETER(1,ERROR3)
297
IF (ABS(STEP(M,N)-STEPC(M)).GT.EPS(M))
298
+ CALL STTPUT(ERROR1,STAT) !just warning message
301
C get intersection of image areas
303
IF (STEPC(M).GT.0.) THEN
304
OSTART(M) = MAX(OSTART(M),START(M,N))
305
OEND(M) = MIN(OEND(M),START(M,N) + (NPIX(M)-1)*STEP(M,N))
307
OSTART(M) = MIN(OSTART(M),START(M,N))
308
OEND(M) = MAX(OEND(M),START(M,N) + (NPIX(M)-1)*STEP(M,N))
312
C compute individual offsets
314
OFX(NIN) = NINT((OSTART(1)-START(1,NIN))/STEP(1,NIN)) + 1
315
OFY(NIN) = NINT((OSTART(2)-START(2,NIN))/STEP(2,NIN)) + 1
320
C test, if something is left...
323
IF (STEPC(M)*(OEND(M)-OSTART(M)).LT.0.) CALL STETER(2,ERROR2)
326
C set up standard stuff for result frame
330
STARTC(M) = OSTART(M)
331
NPIXC(M) = NINT((OEND(M)-OSTART(M))/STEPC(M)) + 1
332
SIZEC = SIZEC * NPIXC(M)
338
CALL STIPUT(FRAMEC,D_R4_FORMAT,F_O_MODE,F_IMA_TYPE,
339
+ NAXISC,NPIXC,STARTC,STEPC,
340
+ IDENT,CUNIT,PNTRC,IMNOC,STAT)
342
C initialize some working variables
344
IF (ACTION(1:1).EQ.'W') RFC(N) = 1./EXPTI(N)
345
POFF(N) = (OFY(N)-1)*NPNTS(N) + OFX(N) !determine 1.pixel no.
348
C and allocate working space
350
IF (NTL.LT.512) NTL = 512
351
CALL STFXMP(NTL,D_R4_FORMAT,PNTRT,STAT)
353
C set up counters for calculation of progress
354
NTL = INT(FLOAT(LP)*.2) !20% of total no. of lines
356
NCHECK = LP + 1 !not worth it...
362
C now, loop through lines
365
C and loop through frames
368
CALL COPULA(IOFF,IMN(N),POFF(N),MADRID(PNTRT),NP)
369
POFF(N) = POFF(N) + NPNTS(N) !move to next line
374
IF (ACTION(1:1).EQ.'W') THEN
375
CALL AVWIN1(MADRID(PNTRT),FRMCNT,NP)
377
CALL AVWIN2(ACTION,MADRID(PNTRT),FRMCNT,NP)
379
CALL COPUL(MADRID(PNTRT),MADRID(PNTRC),L,NP) !save resulting line
382
IF (L.GE.NCHECK) CALL PROGRS(20,NTL,NPERC,NCHECK)
386
IF (ACTION(1:1).EQ.'W') THEN
388
WRITE(OUTPUT,10000) AJCUL(N),AJCUH(N)
389
L = INDEX(FRAME(N),' ') - 1
390
IF (L.LE.0) L = LEN(FRAME(N))
391
LINE(1:) = FRAME(N)(1:L)//OUTPUT(1:)
392
CALL STTPUT(LINE,STAT)
393
WRITE(OUTPUT,10001) EXPTI(N),BGV(N),REJ(N)
394
CALL STTPUT(OUTPUT,STAT)
396
WRITE(OUTPUT,10002) TNP(1),TNP(2),TNP(3),TNP(4)
397
CALL STTPUT(OUTPUT,STAT)
400
C copy descriptors + calculate new dynamic range of result frame
401
CALL DSCUPT(IMN(1),IMNOC,' ',STAT)
402
CALL MYMX(MADRID(PNTRC),SIZEC,CUTS(3))
405
CALL STDWRR(IMNOC,'LHCUTS',CUTS,1,4,UNI,STAT)
410
10000 FORMAT(' low and high cuts',G12.5,' ,',G12.5)
411
10001 FORMAT(' EXPTIM',G12.5,', BGV',G12.5,', rej_pix',I8)
412
10002 FORMAT('pixels with N=0:',I8,', N=1:',I8,', N=2:',I8,', N>2:',I8)
415
SUBROUTINE COPULA(IOFF,IMNO,OFFSET,A,NP)
419
INTEGER IOFF,IMNO,OFFSET,NP
424
CALL STFGET(IMNO,OFFSET,NP,IAV,A(IOFF),STAT)
428
SUBROUTINE COPUL(A,B,NLINE,NP)
432
INTEGER IOFF,N,NLINE,NP
436
IOFF = (NLINE-1) * NP
444
SUBROUTINE AVWIN1(T,TOTAL,NP)
449
REAL V,VM,ER,ERR,WG,AM,ALP,F
450
REAL VAL(20),BGV(20),RMS(20),RFC(20)
451
REAL AJCUL(20),AJCUH(20),SNOISE,BGERR
453
REAL SQRT !system function
458
INTEGER IORD(20),NORD(20),REJ(20),TNP(4)
459
INTEGER I,IDX,II,IM1,IO
460
INTEGER N1,N2,NH,NN,NX
461
INTEGER TNP1,TNP2,TNP3,TNP4
463
COMMON /MYREAL/ VAL,BGV,RMS,RFC,AJCUL,AJCUH,SNOISE,BGERR,EXPTI
464
COMMON /MYINT/ IORD,NORD,REJ,TNP
466
EQUIVALENCE (NORD(1),N1),(NORD(2),N2)
467
EQUIVALENCE (TNP(1),TNP1),(TNP(2),TNP2),
468
+ (TNP(3),TNP3),(TNP(4),TNP4)
472
C loop through pixels in each line
474
NN = 0 !init no. of valid pixels
475
IDX = NX !init offset in working area
479
NOK(I) = V.LT.AJCUL(I) .OR. V.GT.AJCUH(I) !set NOK, if outside
481
IF (.NOT.NOK(I)) THEN
483
VAL(I) = RFC(I) * V !fill value stack
484
NN = NN + 1 !increment no. of valid pixels
490
RMS(I) = RFC(I) * SQRT(BGERR + F) !estimate deviation
493
IDX = IDX + NP !increase offset
496
C order pixel values + find median
498
GOTO 2000 !more than 2 pixels o.k.
500
GOTO (1400,1410,1450),NN+1 !branch acc. to no. of good pixels
503
C no good pixels, take 1. frame
504
1400 NOK(1) = .FALSE.
508
C only one good pixel, take it
512
C two good pixels, test them
515
IF (.NOT.NOK(I)) THEN
521
IF (ABS(VAL(N1)-VAL(N2)).LE.RMS(N1)+RMS(N2)) THEN
525
IF (ABS(VAL(N1)-ALP).LE.ABS(VAL(N2)-ALP)) THEN
533
C more than 2 pixels, compare them
534
2000 DO 2500 I=1,TOTAL
535
IF (.NOT.NOK(I)) THEN
538
IF (I.EQ.1) GOTO 2400
541
IF (.NOT.NOK(II)) THEN
542
IF (V.GT.VAL(II)) THEN
545
IORD(II) = IORD(II) + 1
555
IF (.NOT.NOK(I)) THEN
569
C now remove all pixels with high residuals (not close to median...)
571
II = NORD(I) !start at bottom...
573
IF (ABS(VAL(II)-VM).GT.ERR) THEN !discard, if value differs much
577
II = NORD(NH) !and move to top...
580
IF (ABS(VAL(II)-VM).GT.ERR) THEN
587
TNP(NN) = TNP(NN) + 1
589
C calculate final flux
593
IF (.NOT.NOK(I)) THEN
595
AM = AM + EXPTI(I)*VAL(I)
603
5000 CONTINUE !end of loop through pixels
607
SUBROUTINE AVWIN2(ACTION,T,TOTAL,NP)
612
REAL VAL(20),V,O(11),RVAL
613
REAL VVAL(122) !just to pad the COMMON ...
621
COMMON /MYREAL/ VAL,VVAL
625
C handle maximum search
629
IF (ACTION(1:2).EQ.'MA') THEN
631
C loop through pixels in each line
634
IDX = NX !init offset in working area
637
IDX = IDX + NP !increase offset
642
IF (V.LT.VAL(I)) V = VAL(I)
649
C handle minimum search
653
ELSE IF (ACTION(1:2).EQ.'MI') THEN
655
C loop through pixels in each line
658
IDX = NX !init offset in working area
661
IDX = IDX + NP !increase offset
666
IF (V.GT.VAL(I)) V = VAL(I)
673
C handle median search
679
C loop through pixels in each line
684
IDX = NX !init offset in working area
687
IDX = IDX + NP !increase offset
693
C build up lower half of ordered array (including median index)
698
3100 IF ((NN.LE.1) .OR. (O(NN-1).LE.RVAL) ) GOTO 3200
706
C now only merge upper half of array VAL into ordered array O if necessary
710
IF (RVAL.GE.O(NN)) GOTO 4000
712
3700 IF ( (NN.LE.1) .OR. (O(NN-1).LE.RVAL) ) GOTO 3800