1
C===========================================================================
2
C Copyright (C) 1995-2008 European Southern Observatory (ESO)
4
C This program is free software; you can redistribute it and/or
5
C modify it under the terms of the GNU General Public License as
6
C published by the Free Software Foundation; either version 2 of
7
C the License, or (at your option) any later version.
9
C This program is distributed in the hope that it will be useful,
10
C but WITHOUT ANY WARRANTY; without even the implied warranty of
11
C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
C GNU General Public License for more details.
14
C You should have received a copy of the GNU General Public
15
C License along with this program; if not, write to the Free
16
C Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,
19
C Correspondence concerning ESO-MIDAS should be addressed as follows:
20
C Internet e-mail: midas@eso.org
21
C Postal address: European Southern Observatory
22
C Data Management Division
23
C Karl-Schwarzschild-Strasse 2
24
C D 85748 Garching bei Muenchen
26
C===========================================================================
28
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
29
C.IDENTIFICATION: FUTILS
30
C.PURPOSE: subroutines used by centerrow.for
31
C.LANGUAGE: F77+ESOext
33
C.KEYWORDS: Line, centre
34
C.ALGORITHM: Line center is found by:
35
C maximum/minimum - position of the maximum/minimum value
36
C gaussian - center of the fitted gaussian
37
C gravity - gravity center of the 2 highest pixels
38
C with respect to the third one
40
C.VERSION: 840328 JDP Creation
41
C.VERSION: 071016 KB copied from ../src/centerrow.for
44
C-----------------------------------------------------------------
46
SUBROUTINE PLFIND(X,XSTR,XSTP,IPL1,IPL2,IMODE,IMETH,
47
+ XCENTR,PEAK,IFAIL,W1,W2,ACOE,Y1,Y2)
49
C. PURPOSE: Find center
52
INTEGER IPL1,IPL2,IMODE,IMETH
56
DOUBLE PRECISION XSTR,XSTP
57
DOUBLE PRECISION XCENTR,PEAK,CHICHK,XSP,XGO
58
DOUBLE PRECISION W1(*),W2(*),ACOE(*),Y1,Y2
62
XGO = XSTR + (IPL1-1)*XSP
66
IF (IMETH.LT.0) THEN ! gaussian center
67
CALL SGAUS(X(IPL1),W1,W2,IMODE,NPX,IFAIL,XGO,XSP,
68
+ XCENTR,CHICHK,0,PEAK,ACOE)
69
ELSE IF (IMETH.EQ.0) THEN
70
CALL GRAVT(X(IPL1),NPX,IMODE,IFAIL,XGO,XSP,XCENTR,PEAK)
72
CALL CNTRH(X(IPL1),NPX,IMODE,IFAIL,XGO,XSP,XCENTR,PEAK)
79
SUBROUTINE GRAVT(WINDOW,NPIX,IWID,IWERR,XGO,DXSTP,XCNTR,AM)
81
C line centering by finding the center of gravity of 2 highest
83
C the 2 highest points have values relatives to the third
84
C only applicable in emission mode
86
C WINDOW buffer with expected line center in middle
87
C NPIX number of samples in WINDOW
88
C IWID code 0 absorption, 1 emission
89
C IWERR error return, 0 ok, 1 error
90
C XGO xcoordinate first element in WINDOW
92
C XCNTR return x center calculated
93
C AM intensity center pixel
97
INTEGER NPIX, IWID, IWERR, I, K
100
DOUBLE PRECISION AM, AL, AH, DR
101
DOUBLE PRECISION XGO, DXSTP, XCNTR, A, B, XSHIFT
103
IF (IWID.NE.1) GO TO 20
110
IF (WINDOW(K).GT.AM) THEN
118
IF (I.EQ.1 .OR. I.EQ.NPIX) GO TO 20
119
XCNTR = XGO + (I-1)*DXSTP
121
C find lowest of the flanking pixels
134
XSHIFT = (B/ (A+B))*DXSTP
135
XCNTR = XCNTR + XSHIFT*DR
147
SUBROUTINE CNTRH(WINDOW,NPIX,IWID,IWERR,XGO,DXSTP,XCNTR,AM)
149
C center of line found by simple maximum within a window
152
C WINDOW buffer with expected line center in middle
153
C NPIX number of samples in WINDOW
154
C IWID code 0 absorption, 1 emission
155
C IWERR error return, 0 ok, 1 error
156
C XGO xcoordinate first element in WINDOW
158
C XCNTR return x center calculated
159
C AM intensity center pixel
163
INTEGER NPIX, IWID, IWERR
165
DOUBLE PRECISION AM, XGO, DXSTP, XCNTR
177
IF (WINDOW(I).LT.AM) THEN
187
IF (WINDOW(I).GT.AM) THEN
196
IF (IPN.EQ.1 .OR. IPN.EQ.NPIX) GO TO 30
197
XCNTR = XGO + (IPN-1)*DXSTP
206
SUBROUTINE SGAUS(WINDOW,XBUF,YFIT,IWID,NPIX,IWERR,XGO,DXSTP,
207
2 XCNTR,CHICHK,IOUTPT,AM,A)
209
C line center finding with gaussian fit
212
C WINDOW buffer with expected line center in middle
215
C IWID code 0 absorption, 1 emission
216
C NPIX number of samples in WINDOW
217
C IWERR error return, 0 ok, 1 error
218
C XGO xcoordinate first element in WINDOW
220
C XCNTR return x center calculated
221
C CHICHK check chisquare
222
C IOUTPT display intermediate results 0 no, 1 yes
223
C AM intensity center pixel
224
C A array(4) coefficients
226
INTEGER I,K1,K2,NPIX,IWID,IWERR,IOUTPT
227
INTEGER ITCNT,ITCHK,JER,IBRK
230
DOUBLE PRECISION XBUF(*),YFIT(*),A(*)
231
DOUBLE PRECISION DELTAA(4),SIGMAA(4),XCNTR,XGO,CHICHK
232
DOUBLE PRECISION DXSTP,CHISQR,FLAMDA,OLDCH,DIF,HALF,WIDTH
233
DOUBLE PRECISION AM,X,STOP,TOPM
235
C buffer with x values
239
XBUF(I) = XGO + (I-1)*DXSTP
244
CALL CNTRH(WINDOW,NPIX,IWID,IWERR,XGO,DXSTP,A(2),AM)
245
IF (IWERR.NE.0) GO TO 120
246
A(4) = (WINDOW(1)+WINDOW(NPIX))/2.
249
C calculate half width
251
HALF = A(1)/2. + A(4)
253
C calculation of FWHM depends on sign of the line
257
IF (WINDOW(I).LT.HALF) GO TO 30
261
IF (WINDOW(I).GT.HALF) GO TO 50
267
IF (WINDOW(I).GT.HALF) GO TO 70
271
IF (WINDOW(I).LT.HALF) GO TO 90
276
WIDTH = ABS(FLOAT(K2-K1)*DXSTP)
277
A(3) = WIDTH/2.35482 !sigma = fwhm/2.35482
280
C call fitting routine
288
CALL CURFI(XBUF,WINDOW,SIGMAA,NPIX,4,0,A,DELTAA,FLAMDA,YFIT,
290
IF (JER.NE.0) GO TO 120
292
C calc and display intermediate results
294
IF (IBRK.EQ.-1) GO TO 110
296
C see if CHISQR has changed significantly
302
IF (ITCNT.GT.ITCHK) GO TO 120
303
IF (STOP.GT.CHICHK) GO TO 100
306
C last check that we are within the window
309
IF (DXSTP.LT.0.) THEN
310
IF ((XCNTR.GT.XGO) .OR. (XCNTR.LT.TOPM)) GO TO 120
313
IF ((XCNTR.LT.XGO) .OR. (XCNTR.GT.TOPM)) GO TO 120
317
A(3) = A(3)*2.35482 !fwhm = sigma * 2.35482
327
SUBROUTINE CURFI(X,Y,SIGMAY,NPTS,NTERMS,MODE,A,DELTAA,FLAMDA,YFIT,
330
C least squares fit to a non-linear function
333
C X array of data points ind. var.
334
C Y array of data points dep. var.
335
C SIGMAY array of std dev for Y data points
336
C NPTS number of pairs of data points
337
C MODE determines method of weighting least-squares fit
338
C +1 (instrumental) weight = 1./sigmay(i)**2
339
C 0 (no weighting) weight = 1.
340
C -1 (statistical ) weight = 1./y(i)
341
C A array of parameters
342
C DELTAA array of increments for parameters A
343
C SIGMAA array of standard deviations for parameters A
344
C FLAMDA proportion of gradient search included
345
C YFIT array of calculated values of Y
346
C CHISQR reduced chi square for fit
347
C IERR error return 0 ok, 1 not converging
349
C dimension statement valid for NTERMS up to 10
350
C set FLAMDA to 0.001 at the beginning of the search
352
INTEGER I,J,K,NPTS,NFREE ,NTERMS,IERR
353
INTEGER MODE ,ICNT, ISTAT
356
DOUBLE PRECISION X(*), SIGMAY(*), DELTAA(*), YFIT(*)
357
DOUBLE PRECISION A(*), DET, FLAMDA, CHISF, FUNCT
358
DOUBLE PRECISION WEIGHT(2048), ALPHA(10,10), BETA(10)
359
DOUBLE PRECISION DERIV(10), B(10), CHISQR, CHISQ1
360
DOUBLE PRECISION ARRAY(10,10)
365
NFREE = NPTS - NTERMS
376
40 IF (Y(I)) 60,70,50
377
50 WEIGHT(I) = 1./Y(I)
380
60 WEIGHT(I) = 1./ (-Y(I))
386
80 WEIGHT(I) = 1./SIGMAY(I)**2
390
C evaluate alpha and beta matrices
399
CALL FDERI(X,I,A,DELTAA,NTERMS,DERIV)
401
BETA(J) = BETA(J) + WEIGHT(I)* (Y(I)-FUNCT(X,I,A))*
404
ALPHA(J,K) = ALPHA(J,K) + WEIGHT(I)*DERIV(J)*DERIV(K)
410
ALPHA(K,J) = ALPHA(J,K)
414
C evaluate chi square at starting point
417
YFIT(I) = FUNCT(X,I,A)
419
CHISQ1 = CHISF(Y,SIGMAY,NPTS,NFREE,MODE,YFIT)
423
190 DO 210 J = 1,NTERMS
425
IF (ABS(ALPHA(J,J)).LT.1.E-30 .OR.
426
+ ABS(ALPHA(K,K)).LT.1.E-30) THEN
428
+ ('*** WARNING: Insufficient accuracy: NO RESULT',
431
+ (' Scale your input data first',
435
ARRAY(J,K) = ALPHA(J,K)/SQRT(ALPHA(J,J)*ALPHA(K,K))
437
ARRAY(J,J) = 1. + FLAMDA
439
CALL INVMAT(ARRAY,NTERMS,DET)
443
B(J) = B(J) + BETA(K)*ARRAY(J,K)/
444
+ SQRT(ALPHA(J,J)*ALPHA(K,K))
448
C if chi square increased, increase FLAMDA and try again
451
YFIT(I) = FUNCT(X,I,B)
453
CHISQR = CHISF(Y,SIGMAY,NPTS,NFREE,MODE,YFIT)
454
IF (CHISQ1-CHISQR) 250,270,270
459
IF (ICNT.LT.60) GO TO 260
463
260 FLAMDA = 10.*FLAMDA
466
C evaluate parameters
468
270 DO 280 J = 1,NTERMS
476
DOUBLE PRECISION FUNCTION FUNCT(X,I,A)
478
C evaluate terms of function for non-linear least-squares search
479
C with form of gaussian peak
482
C X array of data points
483
C I index of data points
484
C A array of parameters
487
DOUBLE PRECISION X(*),A(*),Z,XI,Z2
494
40 FUNCT = FUNCT + A(1)*EXP(-Z2*0.5)
499
DOUBLE PRECISION FUNCTION CHISF(Y,SIGMAY,NPTS,NFREE,MODE,YFIT)
501
C evaluate reduced chi square for fit to data
502
C chisf = sum((y-yfit)**2/sigma**2)/nfree
505
C Y array of data points
506
C SIGMAY array of standard deviations
507
C NPTS number of data points
508
C NFREE number of degrees of freedom
509
C MODE determines method of weighting least-squares fit
510
C +1 (instrumental) weight = 1./SIGMAY(i)**2
511
C 0 (no weighting) weight = 1.
512
C -1 (statistical ) weight = 1./Y(i)
513
C YFIT array of calculated values of Y
515
INTEGER NFREE,MODE,NPTS,I
517
CC DOUBLE PRECISION SIGMAY(1),YFIT(1),CHISF
518
DOUBLE PRECISION SIGMAY(1),YFIT(1)
519
DOUBLE PRECISION CHISQ,WEIGHT
526
C accumulate chi square
530
50 IF (Y(I)) 70,80,60
534
70 WEIGHT = 1./ (-Y(I))
540
90 WEIGHT = 1./SIGMAY(I)**2
541
100 CHISQ = CHISQ + WEIGHT* (Y(I)-YFIT(I))**2
544
C divide by number of degrees of freedom
551
SUBROUTINE FDERI(X,I,A,DELTAA,NTERMS,DERIV)
553
C evaluates derivatives of function for least squares search
554
C with form of gaussian peak
557
C X array of data points of independent variable
558
C I index of data points
559
C A array of parameters
560
C DELTAA array of parameter increments
561
C NTERMS number of parameters
562
C DERIV derivatives of function
566
DOUBLE PRECISION X(*),A(*),DELTAA(*),DERIV(*)
567
DOUBLE PRECISION Z,Z2,XI
578
C analytical expression for derivatives
580
40 DERIV(1) = EXP(-Z2/2.)
581
DERIV(2) = A(1)*DERIV(1)*Z/A(3)
582
DERIV(3) = DERIV(2)*Z
588
SUBROUTINE INVMAT(ARR,N,DET)
589
C all rights reserved
591
C.VERSION: 1.0 ESO-FORTRAN Conversion, AA 0:26 - 4 DEC 1987
593
C.LANGUAGE: F77+ESOext
596
C inverts a symmetric matrix and calculates its determinant
597
C using a gauss-jordan elimination method. the degree n of
598
C the matrix must not be greater than 10.
599
C the inversion is in double precision, and
600
C the array ARR must be double. the determinant is allways real.
603
C ARR : array containing the (n*n) matrix to be inverted.
604
C the inverted matrix is returned in ARR.
605
C N : degree of matrix
606
C DET : determinant of input-matrix
611
DOUBLE PRECISION ARR(10,10),AMAX,SAVE,DDET
612
INTEGER IK(10),JK(10),I,J,K,N,L
619
C find largest element ARR(i,j) in rest of matrix
623
IF (DABS(AMAX)-DABS(ARR(I,J))) 20,20,30
629
C ----------------------------------------------------
630
C interchange rows and columns to put AMAX in ARR(k,k)
631
C ----------------------------------------------------
651
C -------------------------------------
652
C accumulate elements of inverse matrix
653
C -------------------------------------
656
130 ARR(I,K) = -ARR(I,K)/AMAX
662
150 IF (J-K) 160,170,160
663
160 ARR(I,J) = ARR(I,J) + ARR(I,K)*ARR(K,J)
669
190 ARR(K,J) = ARR(K,J)/AMAX
676
C --------------------------
677
C restore ordering of matrix
678
C --------------------------
700
C -------------------
701
C determinant is zero
702
C -------------------