1
C @(#)crthmz.for 19.2 (ESO-DMD) 05/20/03 09:41:53
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===========================================================================
30
+COMPUY(RESFMT,EXPRSS,ATOM,APNTRS,UPDA,FRAMEC,CUTS)
32
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
35
C subroutine COMPUY version 4.50 880920
36
C K. Banse ESO - Garching
40
C arithmetic operations, bulk data frames
43
C evaluate an arithmetic expression involving frames, constants and functions
44
C and store the result into a data frame or key OUTPUTR(1), if used as pocket calculator
47
C "clean" the expression by replacing all frame names by F, all constants by C
48
C and all functions by P, convert it to polish (postfix) notation and evaluate it piecewise
49
C intermediate results are stored in OUTPUTR(1) or frame midtempn.bdf
50
C establish special condition handler for arithmetic traps...
51
C copy all descriptors of first frame operand to result frame.
55
C call as COMPUY(RESFMT,EXPRSS,ATOM,APNTRS,UPDA,FRAMEC,CUTS)
58
C RESFMT: I*4 data format for result frame
59
C EXPRSS: char.exp. arithmetic expression in polish postfix notation
60
C ATOM: char. array holds the operands
61
C APNTRS: I*4 array holds the pointers to ATOM
62
C FRAMEC: char. exp. name of result frame
63
C UPDA: I*4 if = 1, result frame is just modified,
64
C else a new result frame is created
67
C CUTS: R*8 array min, max of result frame
71
C-------------------------------------------------------------------------
75
CHARACTER*(*) EXPRSS,ATOM(*),FRAMEC
76
CHARACTER*80 FRAMEA,FRAMEB,FRAME
78
CHARACTER CUNITA*64,CUNITB*64,IDENTA*72,IDENTB*72
79
CHARACTER*60 OPERA,OPERB,OPERC
81
CHARACTER OPERAT*4,LINE*80,DUMMY*20
82
CHARACTER ERROR1*40,ERROR2*30,ERROR4*30
84
DOUBLE PRECISION STEPA(3),STEPB(3),STEPC(3)
85
DOUBLE PRECISION STARTA(3),STARTB(3),STARTC(3)
86
DOUBLE PRECISION BEGIN(3),END(3),DIF,DDUM(1)
87
DOUBLE PRECISION CNSTAB(2),CONST,EPS1,CUTS(2)
92
INTEGER RESFMT,APNTRS(*),UPDA,IMNOC
93
INTEGER APIX(3,2),BPIX(3,2),CPIX(3,2)
94
INTEGER NPIXA(3),NPIXB(3),NPIXC(3)
95
INTEGER IDUM(1),IDUMMY,LL
96
INTEGER MAXDIM,N,NAXISA,NAXISB,NAXISC
98
INTEGER*8 PNTRA,PNTRB,PNTRC
101
INTEGER UNI(1),NULO,MADRID(1)
102
INTEGER APIXDF,BPIXDF,CPIXDF,KK
104
INCLUDE 'MID_INCLUDE:ST_DEF.INC'
106
COMMON /NULCOM/ NULCNT,USRNUL
110
+ERROR1 /'Operands do not match in stepsize... '/
111
DATA ERROR2 /'Operands do not overlap...'/
112
DATA ERROR4 /'Too many operands...'/
114
DATA APIX /6*1/, BPIX /6*1/, CPIX /6*1/
115
DATA DUM /'a','b','c','d','e','f','g','h','i','j',
116
+ 'k','l','m','n','o','p','q','r','s','t',
118
DATA IDENTA /' '/, CUNITA /' '/
119
DATA IDENTB /' '/, CUNITB /' '/
120
DATA NPIXA /3*1/, NPIXB /3*1/, NPIXC /3*1/
121
DATA STARTA /3*0.D0/, STARTB /3*0.D0/, STARTC /3*0.D0/
122
DATA STEPA /3*1.D0/, STEPB /3*1.D0/, STEPC /3*1.D0/
123
DATA DUMMY /'midtemp .bdf '/
125
INCLUDE 'MID_INCLUDE:ST_DAT.INC'
130
CALL STKRDC('MID$SESS',1,11,2,LL,DUMMY(8:),UNI,NULO,STAT)
132
C extract basic operations
133
1000 CALL EXPRDC(WORK(1),WORK(2),OPERAT,PP)
140
IF (OPERAT(1:1).EQ.'Q') THEN !treat 2-arg functions...
145
C find out what kind of OPERA to do
146
IF (INDEX(OPERAT,'C').GT.0) THEN
147
N = INDEX(OPERAT,'F') !also F involved...?
148
IF (N.GT.0) GOTO 1600 !yes.
150
IF (OPERAT(1:1).EQ.'P') THEN
151
GOTO 1600 !handle PF)
153
GOTO 2000 !handle FF or QFF)
158
C only constants involved, do it right now
161
IF (OPERAT(1:2).EQ.'CC') THEN
162
LL = INDEX(OPERA,' ') - 1
164
LINE(1:) = OPERA(1:LL)//','//OPERB
165
CALL GENCNV(LINE(1:61),4,2,IDUM,RDUM,CNSTAB,LL)
166
IF (LL.LE.1) GOTO 9990 !we need 2 values...
167
CALL DOPCC(OPERAT,CNSTAB(1),CNSTAB(2),CONST)
169
IF (OPERAT(1:1).EQ.'P') THEN !1-arg functions
170
CALL GENCNV(OPERB,4,1,IDUM,RDUM,CNSTAB,LL)
171
IF (LL.LE.0) GOTO 9990
172
CALL DF1C(OPERA(1:5),CNSTAB,CONST)
173
ELSE !2-arg functions
174
LINE(1:41) = OPERB//','//OPERC
175
CALL GENCNV(LINE(1:61),4,2,IDUM,RDUM,CNSTAB,LL)
176
IF (LL.LE.0) GOTO 9990
177
CALL DF2CC(OPERA(1:5),CNSTAB,CONST)
181
C put resulting constant back into relevant ATOM + goto loopend
182
IF (WORK(2)(2:2).NE.' ') THEN
183
WRITE(ATOM(P1),10000) CONST
190
C one operand is a file
193
1600 IF (OPERAT(1:2).EQ.'FC') THEN
196
NBRA = 1 !no function
200
IF (OPERAT(1:2).EQ.'CF') THEN
203
NBRA = 1 !no function
207
IF (OPERAT(1:2).EQ.'PF') THEN
209
NBRA = 2 !1-arg function
212
NBRA = 3 !2-arg function
214
IF (OPERAT(1:2).NE.'QC') THEN
222
1700 CALL GENCNV(LINE(1:20),4,1,IDUM,RDUM,DDUM,LL)
224
IF (LL.LE.0) GOTO 9990 !problems with conversion...
226
1800 CALL CLNFRA(FRAME,FRAMEA,0) !take care of & and # ...
228
C now map the result frame
229
IF ( (WORK(2)(2:2).EQ.' ') .AND.
230
+ (FRAMEA.EQ.FRAMEC) ) THEN
231
CALL STIGET(FRAMEA,RESFMT,F_IO_MODE,F_IMA_TYPE,
232
+ 3,NAXISC,NPIXC,STARTC,STEPC,IDENTA,
233
+ CUNITA,PNTRA,IMNOA,STAT)
237
SIZE = SIZE * NPIXC(N)
243
C result frame different from input frames
244
CALL STIGET(FRAMEA,RESFMT,F_I_MODE,F_IMA_TYPE,
245
+ 3,NAXISA,NPIXA,STARTA,STEPA,IDENTA,
246
+ CUNITA,PNTRA,IMNOA,STAT)
251
SIZE = SIZE * NPIXA(N)
253
STARTC(N) = STARTA(N)
258
IF (WORK(2)(2:2).EQ.' ') THEN
260
CALL STIGET(FRAMEC,RESFMT,F_IO_MODE,F_IMA_TYPE,
261
+ 3,NAXISC,NPIXC,STARTC,STEPC,IDENTA,
262
+ CUNITA,PNTRC,IMNOC,STAT)
263
C we have to recalculate SIZE
266
SIZE = SIZE * NPIXC(N)
269
CALL STIPUT(FRAMEC,RESFMT,F_O_MODE,F_IMA_TYPE,
270
+ NAXISC,NPIXC,STARTC,STEPC,IDENTA,
271
+ CUNITA,PNTRC,IMNOC,STAT)
273
ELSE !use dummy result frame
276
IDUMMY = IDUMMY + 1 !increment dummy file counter
277
IF (IDUMMY.GT.24) THEN !check operand count
278
CALL STETER(3,ERROR4)
280
DUMMY(10:10) = DUM(IDUMMY)
282
CALL STIPUT(DUMMY,RESFMT,F_O_MODE,F_IMA_TYPE,
283
+ NAXISC,NPIXC,STARTC,STEPC,IDENTA,
284
+ CUNITA,PNTRC,IMNOC,STAT)
288
C now do the actual operation
289
GOTO (1850,1860,1870),NBRA
291
1850 CALL DOPFC(OPERAT,MADRID(PNTRA),CONST,MADRID(PNTRC),SIZE,
295
1860 CALL DFN1F(OPERA(1:5),MADRID(PNTRA),MADRID(PNTRC),SIZE,
299
1870 CALL DFN2FC(OPERA(1:5),MADRID(PNTRA),CONST,MADRID(PNTRC),SIZE,
302
1900 NULCNT = NULCNT + NNN !update null count
303
IF (WORK(2)(2:2).NE.' ') THEN
304
CALL STFCLO(IMNOA,STAT)
311
C both operands are files
314
2000 IF (OPERAT(1:1).NE.'Q') THEN
315
CALL CLNFRA(OPERA,FRAMEA,0)
316
CALL CLNFRA(OPERB,FRAMEB,0)
318
CALL CLNFRA(OPERB,FRAMEA,0)
319
CALL CLNFRA(OPERC,FRAMEB,0)
322
C get first input frame
323
IF ( (WORK(2)(2:2).EQ.' ') .AND.
324
+ (FRAMEA.EQ.FRAMEC) ) THEN
325
CALL STIGET(FRAMEA,RESFMT,F_IO_MODE,F_IMA_TYPE,
326
+ 3,NAXISC,NPIXC,STARTC,STEPC,IDENTA,
327
+ CUNITA,PNTRA,IMNOA,STAT) !map input/result frame
332
SIZE = SIZE * NPIXC(N)
334
STARTA(N) = STARTC(N)
340
CALL STIGET(FRAMEA,RESFMT,F_I_MODE,F_IMA_TYPE,
341
+ 3,NAXISA,NPIXA,STARTA,STEPA,IDENTA,
342
+ CUNITA,PNTRA,IMNOA,STAT)
345
C handle 2. input frame
346
IF (FRAMEA.EQ.FRAMEB) THEN !check, if both operands are the same
351
STARTB(N) = STARTA(N)
356
CALL STIGET(FRAMEB,RESFMT,F_I_MODE,F_IMA_TYPE,
357
+ 3,NAXISB,NPIXB,STARTB,STEPB,IDENTB,
358
+ CUNITB,PNTRB,IMNOB,STAT)
361
C see, if stepsizes and origins fit + frames overlap
362
IF (NAXISB.GT.NAXISA) THEN
363
MAXDIM = NAXISB !take maximum
369
EPS1 = 0.0001 * ABS(STEPA(N)) !take 0.01% of stepsize as epsilon
370
IF (ABS(STEPA(N)-STEPB(N)).GT.EPS1)
371
+ CALL STETER(1,ERROR1)
372
CALL OVRLAP(STARTA(N),STEPA(N),NPIXA(N),STARTB(N),
373
+ STEPB(N),NPIXB(N),BEGIN(N),END(N),STAT)
374
IF (STAT.NE.0) CALL STETER(3,ERROR2) !if STAT = 1, no overlap...
377
C create new result frame with dimension = intersection of input frames
378
IF ( (WORK(2)(2:2).EQ.' ') .AND.
379
+ (FRAMEA.EQ.FRAMEC) ) GOTO 3000 !we already have the result frame
381
IF (NAXISA.GT.NAXISB) THEN
391
NPIXC(N) = NINT( (END(N)-BEGIN(N)) / STEPC(N) ) + 1
392
SIZE = SIZE * NPIXC(N)
395
C now map the resulting frame
396
IF (WORK(2)(2:2).EQ.' ') THEN !use real result frame
397
IF (UPDA.EQ.1) THEN !test, if update or new file
398
CALL STIGET(FRAMEC,RESFMT,F_IO_MODE,F_IMA_TYPE,
399
+ 3,NAXISC,NPIXC,STARTC,STEPC,IDENTA,
400
+ CUNITA,PNTRC,IMNOC,STAT)
401
SIZE = 1 !we have to recalculate SIZE
403
SIZE = SIZE * NPIXC(N)
406
CALL STIPUT(FRAMEC,RESFMT,F_O_MODE,F_IMA_TYPE,
407
+ NAXISC,NPIXC,STARTC,STEPC,IDENTA,
408
+ CUNITA,PNTRC,IMNOC,STAT)
411
ELSE !use dummy result frame
412
IDUMMY = IDUMMY + 1 !increment dummy file counter
413
IF (IDUMMY.GT.24) THEN !check operand count
414
CALL STETER(2,ERROR4)
416
DUMMY(10:10) = DUM(IDUMMY)
418
CALL STIPUT(DUMMY,RESFMT,F_O_MODE,F_IMA_TYPE,
419
+ NAXISC,NPIXC,STARTC,STEPC,IDENTA,
420
+ CUNITA,PNTRC,IMNOC,STAT)
423
C convert start + end of overlap region into pixel no.'s
424
3000 DO 3100, N=1,MAXDIM
425
DIF = (BEGIN(N)-STARTA(N))/STEPA(N)
426
APIX(N,1) = NINT(DIF) + 1
427
DIF = (END(N)-STARTA(N))/STEPA(N)
428
APIX(N,2) = NINT(DIF) + 1
429
APIXDF = APIX(N,2)-APIX(N,1)
430
DIF = (BEGIN(N)-STARTB(N))/STEPB(N)
431
BPIX(N,1) = NINT(DIF) + 1
432
DIF = (END(N)-STARTB(N))/STEPB(N)
433
BPIX(N,2) = NINT(DIF) + 1
434
BPIXDF = BPIX(N,2)-BPIX(N,1)
435
DIF = (BEGIN(N)-STARTC(N))/STEPC(N)
436
CPIX(N,1) = NINT(DIF) + 1
437
DIF = (END(N)-STARTC(N))/STEPC(N)
438
CPIX(N,2) = NINT(DIF) + 1
439
CPIXDF = CPIX(N,2)-CPIX(N,1)
440
KK = MIN(APIXDF,BPIXDF,CPIXDF) !take smallest size
441
APIX(N,2) = APIX(N,1) + KK
442
BPIX(N,2) = BPIX(N,1) + KK
443
CPIX(N,2) = CPIX(N,1) + KK
446
C now do the actual operation
447
IF (OPERAT(1:1).NE.'Q') THEN
448
CALL DOPFW(OPERAT,MADRID(PNTRA),MADRID(PNTRB),
449
+ MADRID(PNTRC),APIX,BPIX,CPIX,NPIXA,NPIXB,NPIXC)
451
CALL DF2FFW(OPERA(1:5),MADRID(PNTRA),MADRID(PNTRB),
452
+ MADRID(PNTRC),APIX,BPIX,CPIX,NPIXA,NPIXB,NPIXC)
454
IF (WORK(2)(2:2).EQ.' ') GOTO 9000
456
CALL STFCLO(IMNOA,STAT) !release input frames
457
CALL STFCLO(IMNOB,STAT)
459
C put resulting frame back into relevant ATOM, if we are not finished yet
460
4400 ATOM(P1) = DUMMY
461
CALL STFCLO(IMNOC,STAT) !release dummy result frame
463
C loopend for all basic operations
464
5000 IF (OPERAT(1:1).NE.'Q') THEN
470
DO 5050, N=PP+1,45 !update pointers for ATOM
471
APNTRS(N) = APNTRS(N+NBRA)
475
GOTO 1000 !get next operation
478
C we're done. test, if result goes to frame or constant
481
C calculate new dynamic range of result frame
482
9000 CALL DMYMX(MADRID(PNTRC),SIZE,CUTS)
483
CALL STFCLO(IMNOC,STAT) !make sure result frame is closed
485
C delete any dummy frames
486
IF (IDUMMY.GT.0) THEN
488
DUMMY(10:10) = DUM(N)
489
CALL STFDEL(DUMMY,STAT)
496
C error with conversion of ASCII to number
497
9990 CALL STETER(10,'conversion error of ASCII -> number ...')