ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitCommon/Ctvmft/src/ctvmft.F
Revision: 1.3
Committed: Sun Jan 24 18:09:13 2010 UTC (15 years, 3 months ago) by bendavid
Branch: MAIN
CVS Tags: Mit_032, Mit_031, Mit_025c_branch2, Mit_025c_branch1, Mit_030, Mit_029c, Mit_030_pre1, Mit_029a, Mit_029, Mit_029_pre1, Mit_028a, Mit_025c_branch0, Mit_028, Mit_027a, Mit_027, Mit_026, Mit_025e, Mit_025d, Mit_025c, Mit_025b, Mit_025a, Mit_025, Mit_025pre2, Mit_024b, Mit_025pre1, Mit_024a, Mit_024, Mit_023, Mit_022a, Mit_022, Mit_020d, TMit_020d, Mit_020c, Mit_021, Mit_021pre2, Mit_021pre1, Mit_020b, Mit_020a, Mit_020, Mit_020pre1, Mit_018, Mit_017, Mit_017pre3, Mit_017pre2, Mit_017pre1, V07-05-00, Mit_016, Mit_015b, Mit_015a, Mit_015, Mit_014e, Mit_014d, Mit_014c, Mit_014b, ConvRejection-10-06-09, Mit_014a, Mit_014, Mit_014pre3, Mit_014pre2, Mit_014pre1, Mit_013d, Mit_013c, Mit_013b, Mit_013a, Mit_013, Mit_013pre1, HEAD
Branch point for: Mit_025c_branch
Changes since 1.2: +3 -3 lines
Log Message:
Make code and build options compatible with gfortran

File Contents

# User Rev Content
1 bendavid 1.3 c $Id: ctvmft.F,v 1.2 2008/09/30 16:54:49 paus Exp $
2 loizides 1.1 #include "MitCommon/Ctvmft/interface/dimensions.hh"
3    
4     C DEC/CMS REPLACEMENT HISTORY, Element CTVMFT.CDF
5     C
6     C 16-Feb-2004 12:00:00 PAUS use .h files and synchronize dimensions
7     C 05-JUN-2003 12:00:00 PAUS allow for multiple single track pointing
8     C 09-JAN-2003 14:30 F. BEDESCHI Introduce beam line constrain option
9     C 15-SEP-2002 17:50 J. GUIMARAES Increased maximum number of tracks
10     C to 50 (MaxTrk)
11     C
12     C 09-AUG-2002 14:13 msmartin : Zero track vertexing supported from
13     C the work of Jonas Radamacker, Mat Martin and Bill Ashmanskas.
14     C *36 27-JUN-1995 16:30:55 BERGE "ooops??? do what I said I wanted to do. How
15     C did I fail?"
16     C *35 27-JUN-1995 15:35:32 BERGE "improve the aesthetic aspects of I*2 handlin
17     C g"
18     C *34 24-JUN-1995 16:59:17 LAMMEL "correct bad FORMAT statments and I*2 intrin
19     C sic functions"
20     C *33 27-MAY-1995 16:56:37 BERGE "protect against negative mass conversion fit
21     C results"
22     C *32 11-MAY-1995 13:43:30 BERGE "fix IJK name"
23     C *31 9-MAY-1995 12:02:02 BERGE "fix first approximation, STV's"
24     C *30 6-APR-1995 12:29:06 BERGE "minus sign screwup"
25     C *29 5-APR-1995 14:00:06 BERGE "bug fixes, error handling rationalization, D
26     C CALC cahnges, debug dump formatting, etcetra"
27     C *28 28-FEB-1995 10:44:28 BERGE "bug fix in vertex/track initialization"
28     C *27 10-FEB-1995 21:13:26 BERGE "modify DCALC to return both Lxy and Lxyz"
29     C *26 12-AUG-1994 13:31:33 BERGE "fix bug in CTVMFA call of GETTRK"
30     C *25 10-FEB-1994 19:08:21 BERGE "fix setting of EXCUSE ME"
31     C *24 28-JAN-1994 14:10:28 BERGE "modify for D_KLINE debugging"
32     C *23 20-DEC-1993 10:41:29 BERGE "modify error handling, improve print routine
33     C "
34     C *22 5-NOV-1993 14:52:42 BERGE "minor bug fixes, idiot-proofing, format impr
35     C ovements, = ?improvements?"
36     C *21 15-SEP-1993 14:02:04 BERGE "another. it's getting to be a bad habit."
37     C *20 15-SEP-1993 13:51:47 BERGE "TRIV"
38     C *19 14-SEP-1993 14:25:56 BERGE "TRIV"
39     C *18 13-SEP-1993 14:05:24 BERGE "assuage Stephan's worries."
40     C *17 12-SEP-1993 12:18:10 BERGE "buffer ERLOGR calls left in DCALC"
41     C *16 12-SEP-1993 11:11:55 BERGE "Bells and whistles. Idiot-proofing."
42     C *15 9-SEP-1993 16:53:46 BERGE "changes to convergence testing, format fixes
43     C "
44     C *14 8-SEP-1993 17:28:12 BERGE "new(er) include file, convergence testing/li
45     C mits"
46     C *13 5-SEP-1993 18:57:50 BERGE "Modify to multi-vertex version"
47     C *12 26-JUL-1993 14:02:45 BERGE "fix GETTRK calling sequence"
48     C *11 6-JUL-1993 14:01:49 BERGE "prepare for new GETTRK calling sequence"
49     C *10 9-JUN-1993 16:49:57 BERGE "correct comment on bank name specification"
50     C *9 12-OCT-1992 15:51:02 BERGE "protect the print routine from nonsense cova
51     C riances"
52     C *8 9-JUL-1992 16:26:35 BERGE "use GETTRK, change mass constraint conventio
53     C n"
54     C *7 19-APR-1992 10:26:30 LAMMEL "re-re-port to rs6000: FORMAT"
55     C *6 3-APR-1992 18:39:51 BERGE "Fix pointing constraint, use DINV"
56     C *5 22-MAR-1992 02:46:43 LAMMEL "re-port to rs6000: FORMAT"
57     C *4 12-MAR-1992 11:10:48 BERGE "fix initialization bug (Gerry Lynch)"
58     C *3 25-FEB-1992 14:54:38 BERGE "bug fixes, error print suppression"
59     C *2 12-JAN-1992 22:24:01 LAMMEL "port to rs6000: FORMAT statement"
60     C *1 17-SEP-1991 13:25:19 BERGE "combined vertex/mass/pointing constrained fi
61     C t"
62     C DEC/CMS REPLACEMENT HISTORY, Element CTVMFT.CDF
63     C===============================================================================
64     SUBROUTINE CTVMFT (PRINT,LEVPRT, IERR)
65     C===============================================================================
66     C Authors: John Marriner & J.P. Berge
67     C Original Creation: 22 Oct 4004 B.C.E. J.P. Marriner
68     C revision: 1 Sep 2746 A.U.C. J.P. Berge Multiple vertices
69     C revision: 10 Rabi` 1415 A.H. W.J. Ashmanskas Conversion fitting,
70     C 1-track vertex
71     C revision: May 2002 M.S. Martin 0-track vertex
72     C CDF multiple vertex and mass constrained fit package.
73     C This package is documented in CDF/DOC/SEC_VTX/PUBLIC/1996
74     C (which needs revision)
75     C Allows the specification of tracks at one or more vertices, and performs
76     C (geometrical) fits such that at each vertex all tracks at that vertex are
77     C constrained to pass through the same space point ("Vertex fits").
78     C There is a special case of the vertex fit that is designed to treat vertices
79     C with two tracks where the two tracks originate from a photon conversion.
80     C In this case, the two tracks have such a small space opening angle that
81     C the usual vertex fit becomes unstable. For a vertex flagged as a conversion
82     C candidate, extra constraints are imposed. The r-phi opening at the point
83     C where they meet in space. The further requirement that the r-z opening angle
84     C is zero may be optionally imposed.
85     C These fits are not optional. They are always performed.
86     C Allows constraining sub-groups of tracks to specified masses ("mass fit").
87     C Tracks in such a mass fit may be attached to different vertices (consider
88     C the case of the decay Bd -> (psj)(k0). where the Bd mass is constra=ined).
89     C These fits are optional.
90     C Allows constraints such that the momentum sum of tracks at a vertex "points"
91     C to another vertex ("pointing fits").
92     C "Target" vertices may be treated as "primary"; In these cases, vertex
93     C coordinates and covariances are required input and are treated as
94     C measurements in the fit. Such vertices have no attached tracks.
95     C Alternatively, target vertices may be one of the vertices formed from
96     C track intersection fitting in the current fit. Such vertices are considered
97     C "secondary". A secondary vertex that is pointed at a secondary vertex is
98     C a tertiary vertex. There is allowed a special case of a "one-track" vertex
99     C (consider decays Xi -> (lambda)(pi) or B* -> (D0)(pi)). Here the fit
100     C constrains the momentum vector from the tertiary vertex to intersect the
101     C single track at the secondary vertex.
102     C Note that "conversion vertices may point to parent vertices. Note that the
103     C two tracks at such a vertex may appear in a multi-vertex mass-constrained
104     C fit (consider the case Chi -> (psj)(gamma->ee)), but may not appear in any
105     C mass constraint fit restricted only to this vertex.
106     C These fits are optional.
107     C NOTA BENE: Considerable care has been exercized in designing a formatted
108     C dump of the CTVMFT fit results. This dump is activated through setting the
109     C imput parameter PRINT to some non-zero value. If this effort has achieved
110     C its purpose, many points which may remain unclear to the first time user
111     C should be clarified through inspection of dumps of a few fits of interesting
112     C fits. This formattewd output should be printed with 124 columns.
113     C
114     C Additional beam constraint option
115     C =================================
116     C F. Bedeschi, January 2003
117     C
118     C An option to use a beamline constraint in the fit of the primary vertex
119     C has been added. This option does not make sense in the case of secondary
120     C vertex fits and has to be turned on only when fitting the primary with
121     C no additional constraints. The routine is protected and will not function
122     C if those options are selected as well as the bea line constraint.
123     C In case this option is chosen the fit will calculate a result also with
124     C just one track in input.
125     C In order to enable this option the user must do the following:
126     C - set NVERTX = 1
127     C - set Mv=VtxPnt(1,1) = -100 (no pointing constraints when <0. -100 is a new code to
128     C enable this type of fit.)
129     C NB. In this case PRIMARY should be .FALSE. in the code
130     C - set Cvtx(1) = 0 (no mass constraints)
131     C - provide the beamline parameters:
132     C --> assume xv = xb + axb*z, yv = yb + ayb*z, where (xv, yv) is the transverse
133     C beam position at z, (xb, yb) is the transverse beam position at z = 0
134     C as returned by the beam line fit and axb, ayb are the slopes of the beam
135     C line as returned by the beam line fit
136     C --> set XYZPV0 to (xb, yb, 0)
137     C --> set EXYZPV(1,1) = sigma**2 of beam spread in x (~30 - 50 um)**2
138     C EXYZPV(2,2) = sigma**2 of beam spread in y (~30 - 50 um)**2
139     C EXYZPV(3,3) = sigma**2 of beam spread in z (~30 cm)**2
140     C all other elements of EXYZPV should be set to 0
141     C --> set XZSLOPE = axb (this is new parameter in the COMMON/CTVMQ/
142     C YZSLOPE = ayb (this is new parameter in the COMMON/CTVMQ/
143     C
144     C=== End beamline constraint description
145     C
146     C--Input parameters
147     C PRINT If non-zero, dumps formatted fit results to unit PRINT
148     C LEVPRT Controls the level of (optional) printing. Inoperative if PRINT=0.
149     C Avoid this (other than 0,1) unless you know what you are doing.
150     C--Input data communicated through the include file CTVMFT (COMMON /CTVMFC/)
151     C Gross fit specifications (INTEGER);
152     C NTRACK Number of tracks in this fit. (must be at least 2)
153     C NVERTX Number of vertices in this fit (at least one is required)
154     C NMASSC Number of mass constraints (may be zero)
155     C Required topological and constraint information;
156     C TrkVtx(MaxTrk,MaxVtx) LOGICAL
157     C Specifies vertex to which each track is associated.
158     C TrkVtx(Nt,Nv) is .TRUE. if track Nt is attached to vertex Nv.
159     C VtxPnt(MaxVtx,2) INTEGER
160     C Vertex association fit specification.
161     C If Mv=VtxPnt(Nv,1) < 0, no pointing fit is done.
162     C If Mv=VtxPnt(1,1) = -100 a primary vertex fit with beamline constraint
163     C is assumed.
164     C If Mv=VtxPnt(Nv,1) (Nv>Mv) is .GE.0, vertex Nv "points" to vertex Mv.
165     C If Mv=0, the target vertex Mv is supplied as a measurement; the vertex
166     C (x,y,z) together with its 3x3 covariance matrix must be furnished by
167     C the user through the REAL arrays XYZPV0,EXYZPV. "Primary" vertices
168     C are the most usual type of such vertices.
169     C If Mv > 0, the target vertex Mv is a secondary vertex and its coord-
170     C inates are parameters resulting from a track intersection fit.
171     C The kind of "pointing" of vertex Nv to vertex Mv is specified by
172     C setting VtxPnt(Nv,2) to 1, 2, 3 or 4 as desired.
173     C Note that more than one vertex can "point" to the same target vertex.
174     C The constraint is that the sum of the momenta of all the tracks at
175     C vertex Nv together with the summed momenta of all tracks at vertices
176     C which point to Nv must be parallel OR anti-parallel to the vector
177     C from the vertex Nv to vertex Mv. Allowed values of VtxPnt(Nv,2) are;
178     C 1 = constrain pointing of Nv towards Mv in the (R,Phi) plane.
179     C 2 = ALSO constrain pointing in (R,Z) plane (3 dimensional pointing).
180     C 3 = point Nv toward single-track vertex Mv
181     C 4 = point Nv toward zero-track vertex Mv
182     C Note that vertices connected via a charged track are not correctly
183     C handled.
184     C Cvtx(MaxVtx) INTEGER
185     C Conversion constraint fit specification. (The conversion fit
186     C constrains the two tracks at a vertex to be parallel at the vertex.)
187     C 0 = no conversion fit is performed, the vertex is treated normally.
188     C 1 = constrain the track directions in the r-phi plane to be the same
189     C at the radius of the vertex (at the point where the tracks are
190     C copunctual, they are clinear).
191     C 2 = ALSO constrain opening angle to zero in r-z.
192     C TrkMcn(MaxTrk,MaxMcn) LOGICAL
193     C Specifies the tracks that participate in each mass constraint.
194     C Track Nt participates in constraint Nm if TrkMcn(Nt,Nm) is .TRUE.
195     C CMASS(MaxMcn) REAL
196     C The Nmth cluster of tracks is constrained to have mass CMASS(Nm).
197     C Track bank and data specifications;
198     C TKBANK(MaxTrk) CHARACTER*4
199     C Bank name (exempli gratia, 'QTRK','TRKS','SVXS','CTCS') from which
200     C to get each track's helix parameter and covariance data.
201     C These bank names are used in any substantive way only in the data
202     C access subroutine. In CDF, this routine is C$TRK:GETTRK.
203     C LIST (MaxTrk) INTEGER
204     C Bank numbers of the tracks to be used.
205     C TMASS (MaxTrk) REAL
206     C Masses (GeV/c**2) to be associated with the tracks, for purposes of
207     C dE/dX and multiple Coulomb scattering calculations, and for any mass-
208     C constrained fitting.
209     C Output parameter
210     C IERR = 0 (No error), or error code
211     C Returned through the common /CTVMFC/
212     C PAR(5,NTRACK) = The track parameter fit results
213     C XYZVRT(3,0:MaxVtx) The vertex x,y,z fit results.
214     C VMAT(Maxdim,Maxdim) The covariance matrix on the fit parameters
215     C FMCDIF(NMASSC) Residuals of the mass constraints (if used)
216     C PCON(MaxVtx,1) Residual of the (R,Phi) pointing constraint (if used)
217     C PCON(MaxVtx,2) Residual of the (R,Z) pointing constraint (if used)
218     C SANG(MaxVtx,1) sin(ang) between vertex direction and momentum in x-y
219     C SANG(MaxVtx,2) sin(ang) between vertex direction and momentum in rho-z
220     C CHISQR(0:MaxItr) fit Chi Square result(s)
221     C ... other goodies ... Go look at the include file.
222     C Convenient access to VMAT entries for the fit results for vertex and track
223     C parameters is provided by the offset pointer lists VOFF and TOFF.
224     C VOFF(Nv+i) (i=1:3) gives row/column indices for vertex Nv (x,y,z).
225     C TOFF(Nt+i) (i=1:3) gives row/column indices for track Nt (Crv,Phi,Ctg)
226     C Subroutines;
227     C CTVM00 Checks the input for completeness and consistency
228     C CTVMFA Makes the vertex first approximations (uses GETTRK).
229     C CTVM01 Collects the track data (uses GETTRK).
230     C CTVMVF Calculates the derivative contributions for vertex fitting.
231     C CTVMCF conversion fitting.
232     C CTVMPF pointing fittting.
233     C CTVMMF mass constraint fitting.
234     C CTVMPR Prints the fit results, if desired, to output unit PRINT.
235     C-------------------------------------------------------------------------------
236     IMPLICIT NONE
237     #include "MitCommon/Ctvmft/interface/ctvmdi.h"
238     #include "MitCommon/Ctvmft/interface/ctvmft.h"
239     #include "MitCommon/Ctvmft/interface/ctvmfi.h"
240     #include "MitCommon/Ctvmft/interface/ctvmuv.h"
241     INTEGER PRINT, IERR
242     LOGICAL PRIMARY
243     REAL*8 VXI(MAXDIM)
244     REAL*8 WXYZPV(3,3), SUM
245     REAL*8 LMAT(3,3), LTV(3,3), LTVL(3,3)
246     REAL*8 LTVLX0(3), LTVXV(3), DXBEAM(3)
247     REAL C,PHI,COTH, D,Z, PT, RADV, TWOC, S,TS,TRAD, T1,T2,T3,T4
248     REAL SP,CP, XCYS,XSYC,XC2YC2, SINCS,COSCS,TWOCS, PMAG, XMAG
249     REAL XSVT,YSVT, WORK(MAXDIM), ADDCHIV
250     REAL PARFAC,CUTFAC, DELVS(3,MaxVtx)
251     REAL PCSAVE(MaxVtx,2), MFSAVE(MaxMcn), MFTEST(MaxMcn)
252     REAL STPTK,STEP(5), PARDJF(5,MaxTrk)
253     INTEGER Nv,Mv,Nt,Np,Nm, NvF,NtF,LpF,LmF,LcF
254     INTEGER NITER, NMAXCT,ISCUT,NPC
255     INTEGER I,J,K,L, II(2), I1,I2, IFAIL, IMAX, VERTEX,VRTX
256     INTEGER KTRACK,NPOINT,NCONV, KPRINT
257     C Local variables pertaining to single-track vertices
258     INTEGER STVCOUNT,STVFLAG(MaxVtx)
259     INTEGER BEAM
260     LOGICAL FIRST
261     INTEGER MRUN,MNEV
262     CHARACTER*6 NAME
263     CHARACTER*80 STRING
264     C LEVPRT = print level (0=print disabled)
265     INTEGER LEVPRT
266     REAL ZERO,MINUS,SHOUT, TEST
267     SAVE FIRST,BEAM
268     SAVE NMAXCT, MRUN,MNEV
269     SAVE ZERO,MINUS
270     c DATA ME /0/
271     DATA ZERO /0.0/, MINUS /-1.0/
272     C Maximum number of cut steps allowed in any step
273     DATA NMAXCT / 7 /
274     DATA FIRST /.TRUE./
275     DATA MRUN /-1/, MNEV /-1/
276     C*******************************************************************************
277     DBGPRT = IABS(LEVPRT)
278     C avoid terminating on error in CTVM00
279     C Comment out the following line so that instead of bombing on an error,
280     C CTVMFT returns to VertexFit, so that the error can be properly handled.
281     C Craig Blocker July 19, 2001
282     C EXCUSE = ME
283     IF (LEVPRT.LT.0) THEN
284     EXCUSE =-1
285     END IF
286     IF (PRINT.EQ.0) DBGPRT=0
287     KPRINT = 0
288     IF (PRINT.GT.0 .AND. DBGPRT.GT.10) KPRINT=PRINT
289     C First entrance initializations
290     IF (FIRST) THEN
291     FIRST =.FALSE.
292     C do NOT use beam constrained parameters
293     BEAM = 0
294     WRITE(print,'(A)') ' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
295     WRITE(print,'(A)') ' CTVMFT First call in program '
296     WRITE(print,'(A)') ' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
297     WRITE(print,'(3(A9,I4),/,3(A9,I4))')
298     + ' VtxsMax:',MAXVTX,' TrksMax:',MAXTRK,' ConsMax:',MAXMCN,
299     + ' DimsMax:',MAXDIM,' ItrsMax:',MAXITR,' UDim: ',UDIM
300     WRITE(print,'(A)') ' XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
301     END IF
302     IF (MRUN.NE.RUNNUM .OR. MNEV.NE.TRGNUM) THEN
303     C New event, reset track "memory"
304     DO I=1,MaxTrk
305     TKERR(I) =-1.0
306     END DO
307     MRUN = RUNNUM
308     MNEV = TRGNUM
309     END IF
310     IERR = 0
311     DO I=1,3
312     IJKERR(I) = 0
313     END DO
314     NTSCUT = 0
315     CALL VZERO(CHISQR,MaxItr+1)
316     CHISQR(0) =-1.
317     CALL VZERO(CHIV ,MaxVtx+1)
318     CALL VZERO(CHIT ,MaxTrk)
319     CALL VZERO(PARDIF,MaxTrk*5)
320     CALL VZERO(PARDJF,MaxTrk*5)
321     CALL VZERO(PARERR,MaxTrk*5)
322     CALL VZERO(TrkP4, MaxTrk*6)
323     CALL VZERO(DDA, MaxTrk*8)
324     CALL VZERO(XYZVRT,MaxVtx*3+3)
325     CALL VZERO(DELVS, MaxVtx*3)
326     CALL VZERO(PCSAVE,MaxVtx*2)
327     CALL VZERO(LMAT, 2*3*3)
328     CALL VZERO(LTV, 2*3*3)
329     CALL VZERO(LTVL, 2*3*3)
330     CALL VZERO(LTVLX0,2*3)
331     CALL VZERO(LTVXV, 2*3)
332     CALL VZERO(MFSAVE,MaxMcn)
333     CALL VZERO(MFTEST,MaxMcn)
334     CALL VZERO(STVFLAG,MaxVtx)
335     STVCOUNT = 0
336     C Check Input Conditions for illegal conditions
337     C------------------------------------------------------------------------------
338     C Check input specifications
339     CALL CTVM00 (IERR,WXYZPV)
340     IF (IERR.NE.0) THEN
341     RETURN
342     END IF
343     TRAD = ABS(XYZPV0(1)) + ABS(XYZPV0(2))
344     C flag the appearance of a primary vertex
345     PRIMARY =.FALSE.
346     C check for a primary vertex
347     DO Nv=1,NVERTX
348     IF (VtxPnt(Nv,1).EQ.0) THEN
349     PRIMARY =.TRUE.
350     END IF
351     END DO
352     C primary vertex coordinates - Joao 02/11/03
353     IF (PRIMARY .OR. (TRAD.GT.0.0.AND.VTXPNT(1,1).NE.-100)) THEN
354     DO I=1,3
355     XYZVRT(I,0) = XYZPV0(I)
356     C primary vertex fit displacement
357     DXYZPV(I) = 0.0
358     END DO
359     ENDIF
360     C beamline constraint initializations
361     IF (VTXPNT(1,1) .EQ.-100) THEN
362     DO I = 1,3
363     LMAT(I,I) = 1.0D0
364     ENDDO
365     LMAT(1,3) = -XZSLOPE
366     LMAT(2,3) = -YZSLOPE
367     C Calculate Lt*V**-1
368     CALL VZERO(LTV,2*3*3)
369     DO I = 1,3
370     DO J = 1,3
371     DO K = 1,3
372     LTV(I,J) = LTV(I,J) + LMAT(K,I)*WXYZPV(K,J)
373     ENDDO
374     ENDDO
375     ENDDO
376     C Calculate Lt*V**-1*L
377     CALL VZERO(LTVL,2*3*3)
378     DO I = 1,3
379     DO J = 1,3
380     DO K = 1,3
381     LTVL(I,J) = LTVL(I,J) + LTV(I,K)*LMAT(K,J)
382     ENDDO
383     ENDDO
384     ENDDO
385     D IF (DBGPRT.GT.0) THEN
386     D write(print,5110)
387     D5110 format(1x,'CTVMFT: Beamline initialization done')
388     D write(print,5120)XYZPV0,XZSLOPE, YZSLOPE
389     D5120 format(1x,'Starting vertex x,y,z: ',3(E10.4,2x),
390     D > 'Slopes: x,y: ',2(e10.4,2x))
391     D do i=1,3
392     D write(print,5130)(WXYZPV(i,j), j=1,3)
393     D enddo
394     D5130 format(1x,'WXYZPV: ',3(e10.4,2x))
395     D do i = 1,3
396     D write(print,5140)(ltv(i,j),j=1,3),(ltvl(i,j),j=1,3)
397     D5140 format(1x,'LTV: ',3(E10.4,2x)'LTVL: ',3(e10.4,2x))
398     D enddo
399     D ENDIF
400     ENDIF
401    
402     D IF (DBGPRT.GT.0) THEN
403     D WRITE(PRINT,1000) RUNNUM,TRGNUM, NTRACK,NVERTX,NMASSC
404     D IF (PRIMARY) THEN
405     D WRITE(PRINT,1005) XYZPV0
406     D DO I=1,3
407     D WORK(I) = SQRT(EXYZPV(I,I))
408     D END DO
409     D DO I=1,3
410     D DO J=1,3
411     D VMAT(I,J) = EXYZPV(I,J)/(WORK(I)*WORK(J))
412     D END DO
413     D END DO
414     D WRITE(PRINT,1006) (WORK(I),I=1,3)
415     D WRITE(PRINT,1006) ((VMAT(I,J),I=1,3),J=1,3)
416     D END IF
417     D WRITE(PRINT,1001) (I, LIST(I),TkBank(I),Tmass(I),I=1,NTRACK)
418     D1000 FORMAT('1Event ',I5,'.',I6,'; CTVMFT fit results,'
419     D &,' (Tracks,Vertices,Mass Constraints) ',2(I2,','),I2, /)
420     D1001 FORMAT(' Track',I3,';',I5,A5,F8.3 )
421     D1005 FORMAT( ' Primary vertex ',3F10.4)
422     D1006 FORMAT(16X,3F10.4)
423     D END IF
424     C Vertex fit matrix dimensions;
425     C 3 vertex parameters (x,y,z) per (possible) primary vertex
426     C 3 vertex parameters per secondary vertex
427     C + 0, 1, or 2 "pointing" parameters
428     C + 3 parameters (curvature,phi0,coth(theta0)) per track
429     C + N mass constraints
430     C VOFF(Nv),TOFF(Nt) are offset pointers to ((Vertex,Pointing),Track) parameters
431     C in (the 1st derivative vector, 2nd derivative matrix) VXI, VMAT
432     C VOFF(Nv) points to the start of the 3, 4, or 5 variables for vertex Nv;
433     C vertex Nv (x,y,z, p1,p2)
434     C TOFF(Nt) points to the start of the 3 parameters; track Nt (Crv,Phi,Ctg)
435     C POFF(Lp) points to the start of the Lagrangian multiplier values for the
436     C pointing constraint Lp.
437     C COFF(Lc) points to the start of the Lagrangian multiplier values for the
438     C conversion constraint Lc.
439     C MOFF points to the start of the Lagrangian multiplier values for the
440     C mass constraints
441     C initialize the parameter offset pointer
442     NvF = 0
443     IF (PRIMARY) NvF = 3
444     C offsets to vertex parameters
445     DO Nv=1,NVERTX
446     VOFF(Nv) = NvF
447     NvF = NvF + 3
448     END DO
449     NtF = NvF
450     C offsets to track parameters
451     DO Nt=1,NTRACK
452     TOFF(Nt) = NtF
453     NtF = NtF + 3
454     END DO
455     C count the number of "pointing" constraints
456     NPOINT = 0
457     LpF = NtF
458     C offsets to pointing Lagrangian multipliers
459     DO Nv=1,NVERTX
460     IF (VtxPnt(Nv,1).GE.0) THEN
461     POFF(Nv) = LpF
462     IF (VtxPnt(Nv,2).EQ.1.OR.VtxPnt(Nv,2).EQ.2) THEN
463     NPOINT = NPOINT + VtxPnt(Nv,2)
464     LpF = LpF + VtxPnt(Nv,2)
465     C "one-track vertex"
466     ELSE IF (VtxPnt(Nv,2).EQ.3) THEN
467     IF (STVFLAG(VtxPnt(Nv,1)).EQ.0) THEN
468     C Count number of unique single-track vertices
469     STVFLAG(VtxPnt(Nv,1)) = 1
470     STVCOUNT = STVCOUNT+1
471     ENDIF
472     NPOINT = NPOINT + 2
473     LpF = LpF + 2
474     C "zero-track vertex"
475     ELSE IF (VtxPnt(Nv,2).EQ.4) THEN
476     NPOINT = NPOINT + 2
477     LpF = LpF + 2
478     END IF
479     END IF
480     END DO
481     C count number of "conversion" constraints
482     NCONV = 0
483     LcF = LpF
484     C offsets to zero-opening-angle constraint
485     DO Nv=1,NVERTX
486     C Lagrangian multipliers
487     IF (Cvtx(Nv).GT.0) THEN
488     COFF(Nv) = LcF
489     NCONV = NCONV + Cvtx(Nv)
490     LcF = LcF + Cvtx(Nv)
491     END IF
492     END DO
493     C offset to mass cnst Lagrangian multipliers
494     MOFF = LcF
495     C Fit dimension (number of degrees of freedom)
496     NDOF = 2*NTRACK - 3*NVERTX + NPOINT+NMASSC+NCONV
497     IF (VTXPNT(1,1) .eq. -100)NDOF = NDOF + 3
498     C Dimension of matrix equations
499     MATDIM = NtF + NMASSC+NPOINT+NCONV
500     C Data Collection and Checking, Fit Initialization, Vertex first approximation
501     C------------------------------------------------------------------------------
502     C Loop (backward) over secondary vertices. Ignore for primary vertex fits with
503     C beamline constraint.
504     DO Nv=NVERTX,1,-1
505     IERR = 0
506     CALL CTVMFA (Nv, PRINT,IERR)
507     IF (IERR.NE.0) THEN
508     WRITE (STRING,2000) IJKERR
509     2000 FORMAT(I4,2I3,' vertex first approximation failure')
510     GO TO 990
511     END IF
512     END DO
513     C------------------------------------------------------------------------------
514     C-------------- Fit iteration start -------------------------------------------
515     ITER = 0
516     NITER = MAXITR
517     C fit iteration (re)entrance point
518     100 CONTINUE
519     D IF (DBGPRT.GT.0) THEN
520     D WRITE(PRINT,1020) ITER
521     D1020 FORMAT(/,' Start Iteration step',I2)
522     D END IF
523     C (re)initialize VXI, VMAT
524     CALL VZERO(VXI, 2*MAXDIM)
525     CALL VZERO(VMAT,2*MAXDIM*(MAXDIM+1))
526     c?? DO I=1,MAXDIM
527     c?? VXI(I) = 0.0D0
528     c?? DO J=1,MAXDIM
529     c?? VMAT(J,I) = 0.0D0
530     c?? END DO
531     c?? END DO
532     C stuff the primary Vtx covariance into VMAT
533     IF (PRIMARY) THEN
534     DO I=1,3
535     DO J=1,3
536     VMAT(I,J) = WXYZPV(I,J)
537     C (measured - this fit)
538     VXI(I) = VXI(I) - VMAT(I,J)*DXYZPV(J)
539     END DO
540     END DO
541     END IF
542     C Caclulate terms for the vertex fits via track inentersection.
543     DO Nv=NVERTX,1,-1
544     CALL CTVMVF (KPRINT, Nv, VXI)
545     END DO
546     C accumulate vertex momentum sums, for (possible) pointing constraint fitting
547     C 4-momentum sums for vertex pointing
548     CALL VZERO(VtxP4,MaxVtx*4)
549     DO Nv=NVERTX,1,-1
550     DO Nt=1,NTRACK
551     IF (TrkVtx(Nt,Nv)) THEN
552     DO I=1,4
553     VtxP4(I,Nv) = VtxP4(I,Nv) + TrkP4(Nt,I)
554     END DO
555     END IF
556     C end track loop
557     END DO
558     C does Nv point?
559     Mv = VtxPnt(Nv,1)
560     C tertiary; add P(Nv) to P(Mv)
561     IF (Mv.GT.0) THEN
562     DO I=1,4
563     VtxP4(I,Mv) = VtxP4(I,Mv) + VtxP4(I,Nv)
564     END DO
565     END IF
566     C End vertex loop
567     END DO
568     C calculate terms for "conversion" (zero opening angle) constraint
569     DO Nv=1,NVERTX
570     C conversion constraint, this vertex
571     IF (Cvtx(Nv).GT.0) THEN
572     CALL CTVMCF (KPRINT, Nv, VXI)
573     END IF
574     C end of the vertex loop
575     END DO
576     C calculate terms for pointing from this vertex towards its parent
577     DO Nv=NVERTX,1,-1
578     C pointing constraint, this vertex
579     IF (VtxPnt(Nv,1).GE.0) THEN
580     CALL CTVMPF (KPRINT, Nv, VXI)
581     C save the last step quality
582     LpF = POFF(Nv)
583     PCSAVE(Nv,1) = ABS(VXI(LpF+1))
584     PCSAVE(Nv,2) = ABS(VXI(LpF+2))
585     END IF
586     C end of the vertex loop
587     END DO
588     C accumulate momentum sums, for (possible) mass constraint fitting
589     C 4-momentum sums for mass constraints
590     CALL VZERO(McnP4,MaxMcn*4)
591     DO Nm=1,NMASSC
592     DO Nt=1,NTRACK
593     IF (TrkMcn(Nt,Nm)) THEN
594     DO I=1,4
595     McnP4(I,Nm) = McnP4(I,Nm) + TrkP4(Nt,I)
596     END DO
597     END IF
598     END DO
599     END DO
600     C loop over mass constraints
601     DO Nm=1,NMASSC
602     CALL CTVMMF (KPRINT, Nm, VXI)
603     LmF = MOFF
604     MFSAVE(Nm) = ABS(VXI(LmF+Nm))
605     END DO
606     C
607     C Additional terms for beamline constraint
608     C
609     IF (VTXPNT(1,1) .EQ. -100) THEN
610     D IF (DBGPRT.GT.0) THEN
611     D write(print,5150)NTRACK, (XYZVRT(i,1),i=1,3)
612     D5150 format(1x,'Ntracks: ',i3,
613     D > 'Vertex before iteration: ',3(e10.4,2x))
614     D ENDIF
615     C Update VMAT
616     DO I = 1,3
617     DO J = 1,3
618     VMAT(I,J) = VMAT(I,J) + LTVL(I,J)
619     ENDDO
620     ENDDO
621     C Update VXI
622     CALL VZERO(LTVXV, 2*3)
623     CALL VZERO(LTVLX0,2*3)
624     DO I = 1,3
625     DO J = 1,3
626     LTVXV(I) = LTVXV(I) + LTV(I,J)*XYZPV0(J)
627     LTVLX0(I) = LTVLX0(I) + LTVL(I,J)*XYZVRT(J,1)
628     ENDDO
629     VXI(I) = VXI(I) + LTVXV(I) - LTVLX0(I)
630     ENDDO
631     ENDIF
632     C End of the derivative accumulation phase; Now solve matrix equations
633     C Find solution without finding inverse
634     IF (ITER.EQ.0) THEN
635     CALL MYDEQN (MATDIM,VMAT,MAXDIM,WORK,IFAIL,1,VXI)
636     C Find solution + covariance matrix
637     ELSE
638     CALL MYDEQINV(MATDIM,VMAT,MAXDIM,WORK,IFAIL,1,VXI)
639     ENDIF
640     IF (IFAIL.NE.0) THEN
641     IERR = 9
642     IJKERR(2) = 1
643     WRITE(STRING,2030)
644     2030 FORMAT(' singular solution matrix')
645     ccc write(*,9000) string
646     ccc 9000 format(' Error in CTVMFT: ',A)
647     RETURN
648     END IF
649     C Check the step just taken for acceptability and for possible convergence
650     C Initialize cut steps counter
651     ISCUT = 0
652     C Step size scale factor - normally 1
653     CUTFAC = 1.0
654     C Fraction of the step already taken
655     PARFAC = 0.0
656     C Check that track turning angles to the new vertex points are acceptable
657     110 CONTINUE
658     C x,y for this vertex, this step cut factor
659     DO 150 Nv=1,NVERTX
660     NvF = VOFF(Nv)
661     XSVT = XYZVRT(1,Nv) + CUTFAC*VXI(NvF+1)
662     YSVT = XYZVRT(2,Nv) + CUTFAC*VXI(NvF+2)
663     C track loop, checking turning angle
664     DO 140 Nt=1,NTRACK
665     IF (.NOT.TrkVtx(Nt,Nv)) GO TO 140
666     NtF = TOFF(Nt)
667     C = PAR0(1,Nt) + PARDIF(1,Nt) + CUTFAC*VXI(NtF+1)
668     PHI = PAR0(2,Nt) + PARDIF(2,Nt) + CUTFAC*VXI(NtF+2)
669     TS = 2.0*C*(XSVT*COS(PHI)+YSVT*SIN(PHI))
670     C track turns too much, cut step size
671     IF (ABS(TS).GT.TRNMAX) THEN
672     ISCUT = ISCUT+1
673     NTSCUT = NTSCUT + 1
674     C maximum number of cut steps exceeded
675     IF (ISCUT.GT.NMAXCT) THEN
676     IERR = 9
677     IJKERR(2) = 2
678     IJKERR(3) = ITER
679     WRITE(STRING,2050) IJKERR
680     2050 FORMAT(' too many cut steps', I5,2I3)
681     GO TO 990
682     END IF
683     CUTFAC = 0.5*(CUTFAC-PARFAC)
684     D IF (DBGPRT.GT.1) THEN
685     D WRITE(PRINT,1050) ITER,ISCUT,Nv,Nt,XSVT,YSVT
686     D1050 FORMAT(' Iter',I2,' Cut',I2,', Nv,Nt ',I1,I4,2F10.4)
687     D END IF
688     GO TO 110
689     END IF
690     140 CONTINUE
691     150 CONTINUE
692     PARFAC = PARFAC+CUTFAC
693     C Provisionally acceptable step;
694     C Update all the fit parameters and calculate Chi Square, this step
695     C Re-initialize, recompute momentum sums with the new step results
696     C Update primary vertex coordinates
697     IF (PRIMARY) THEN
698     DO I=1,3
699     DXYZPV(I) = DXYZPV(I) + CUTFAC*VXI(I)
700     XYZVRT(I,0) = XYZPV0(I) + DXYZPV(I)
701     END DO
702     END IF
703     C Contribution from the "primary" vertex
704     CHIV(0) = 0.0
705     IF (PRIMARY) THEN
706     DO I=1,3
707     DO J=1,3
708     CHIV(0)= CHIV(0) + DXYZPV(I)*WXYZPV(I,J)*DXYZPV(J)
709     END DO
710     END DO
711     END IF
712     CHISQR(ITER) = CHIV(0)
713     C Update secondary vertex coordinates
714     DO Nv=1,NVERTX
715     Nvf = VOFF(Nv)
716     DO I=1,3
717     XYZVRT(I,Nv) = XYZVRT(I,Nv) + CUTFAC*VXI(NvF+I)
718     Mv = VtxPnt(Nv,1)
719     C vertex separation vector
720     IF (Mv.GE.0) THEN
721     DELVS(I,Nv) = XYZVRT(I,Mv) - XYZVRT(I,Nv)
722     END IF
723     END DO
724     END DO
725     D IF (DBGPRT.GT.0) THEN
726     D write(print,5160)NTRACK, (XYZVRT(i,1),i=1,3)
727     D5160 format(1x,'Ntracks: ',i3,
728     D > ', Vertex after iteration: ',3(e10.4,2x))
729     D END IF
730     DO 210 Nv=1,NVERTX
731     CHIV(Nv) = 0.0
732     C Update the track parameters
733     DO 210 Nt=1,NTRACK
734     IF (.NOT.TrkVtx(Nt,Nv)) GO TO 210
735     NtF = TOFF(Nt)
736     C half curvature step
737     PARDIF(1,Nt) = PARDIF(1,Nt) + CUTFAC*VXI(NtF+1)
738     C phi step
739     PARDIF(2,Nt) = PARDIF(2,Nt) + CUTFAC*VXI(NtF+2)
740     C cot(theta) step
741     PARDIF(3,Nt) = PARDIF(3,Nt) + CUTFAC*VXI(NtF+3)
742     C new half curvature
743     C = PAR0(1,Nt) + PARDIF(1,Nt)
744     C new phi
745     PHI = PAR0(2,Nt) + PARDIF(2,Nt)
746     C new coth(theta)
747     COTH = PAR0(3,Nt) + PARDIF(3,Nt)
748     SP = SIN(PHI)
749     CP = COS(PHI)
750     C Xsv*cos(phi) + Ysv*sin(phi), -Xsv*sin(phi) + Ysv*cos(phi), 2C
751     XCYS = XYZVRT(1,Nv)*CP + XYZVRT(2,Nv)*SP
752     XSYC =-XYZVRT(1,Nv)*SP + XYZVRT(2,Nv)*CP
753     TWOC = 2.0*C
754     C 10/23/02 Protect against TWOC begin zero. Craig Blocker
755     c?? if(twoc .eq. 0.) then
756     IF (ABS(TWOC) .LT. 1E-24) THEN
757     S = XCYS
758     else
759     S = ASIN(TWOC*XCYS)/TWOC
760     endif
761     TS = TWOC*XCYS
762     TRAD = SQRT((1.-TS)*(1.+TS))
763     C Constrained d0
764     C 10/23/02 Protect against C being zero. Craig Blocker
765     c?? if(c .eq. 0.) then
766     IF (ABS(C) .LT. 1E-24) THEN
767     D = XSYC
768     else
769     D = XSYC - SIN(C*S)**2/C
770     endif
771     C Constrained z0
772     Z = XYZVRT(3,Nv) - COTH*S
773     C fit d0 - CTC fit d0
774     PARDIF(4,Nt) = D - PAR0(4,Nt)
775     C fit z0 - CTC fit z0
776     PARDIF(5,Nt) = Z - PAR0(5,Nt)
777     C 1/20/04 Protect against C being zero. Here it is not
778     C clear what to set PT to. I chose 999. GeV since this is
779     C a very large Pt in CDF, this is roughly a standard deviation
780     C from infinite, and should be clearly recognizable. Craig Blocker
781     c?? if(c .eq. 0.) then
782     IF (ABS(C) .LT. 1E-24) THEN
783     PT = 999.
784     else
785     PT = PSCALE/ABS(C)
786     endif
787     C x component of momentum
788     TrkP4(Nt,1) = PT*(CP*TRAD-SP*TS)
789     C y component of momentum
790     TrkP4(Nt,2) = PT*(SP*TRAD+CP*TS)
791     C z component of momentum
792     TrkP4(Nt,3) = PT*COTH
793     C Transverse momentum
794     TrkP4(Nt,5) = PT
795     C total momentum
796     TrkP4(Nt,6) = SQRT(PT**2+TrkP4(Nt,3)**2)
797     C energy
798     TrkP4(Nt,4) = SQRT(TrkP4(Nt,6)**2+TMASS(NT)**2)
799     C Calculate contribution to chi-squared for this track
800     CHIT(Nt) = 0.0
801     C Loop over rows of the weight matrix
802     DO I=1,5
803     C Loop over columns of the weight matrix
804     DO J=1,5
805     CHIT(Nt) = CHIT(Nt) + PARDIF(I,Nt)*G(J,I,Nt)*PARDIF(J,Nt)
806     END DO
807     END DO
808     CHIV(Nv) = CHIV(Nv) + CHIT(Nt)
809     CHISQR(ITER) = CHISQR(ITER) + CHIT(Nt)
810     C End the loop on tracks
811     210 CONTINUE
812     C Beamline constraint contribution
813     IF(VTXPNT(1,1).EQ.-100)THEN
814     DO I = 1,3
815     DXBEAM(I) = -XYZPV0(I)
816     DO J = 1,3
817     DXBEAM(I) = DXBEAM(I) + LMAT(I,J)*XYZVRT(J,1)
818     ENDDO
819     ENDDO
820     ADDCHIV = 0.0
821     DO I = 1,3
822     DO J = 1,3
823     ADDCHIV = ADDCHIV + DXBEAM(I)*DXBEAM(J)*WXYZPV(I,J)
824     ENDDO
825     ENDDO
826     CHIV(NV) = CHIV(NV) + ADDCHIV
827     CHISQR(ITER) = CHISQR(ITER) + ADDCHIV
828     ENDIF
829     CALL VZERO(VtxP4,MaxVtx*4)
830     CALL VZERO(McnP4,MaxMcn*4)
831     DO Nt=1,NTRACK
832     DO Nv=NVERTX,1,-1
833     IF (TrkVtx(Nt,Nv)) THEN
834     C accumulate vertex sums
835     DO I=1,4
836     VtxP4(I,Nv) = VtxP4(I,Nv) + TrkP4(Nt,I)
837     END DO
838     END IF
839     END DO
840     C accumulate mass constraint sums
841     DO Nm=1,NMASSC
842     IF (TrkMcn(Nt,Nm)) THEN
843     DO I=1,4
844     McnP4(I,Nm) = McnP4(I,Nm) + TrkP4(Nt,I)
845     END DO
846     END IF
847     END DO
848     END DO
849     DO Nv=1,NVERTX
850     C does Nv point?
851     Mv = VtxPnt(Nv,1)
852     C tertiary; add P(Nv) to P(Mv)
853     IF (Mv.GT.0) THEN
854     DO I=1,4
855     VtxP4(I,Mv) = VtxP4(I,Mv) + VtxP4(I,Nv)
856     END DO
857     END IF
858     END DO
859     C Check the quality of satisfaction of the pointing constraints, this step
860     DO 220 Nv=1,NVERTX
861     Mv = VtxPnt(Nv,1)
862     IF (Mv.LT.0) GO TO 220
863     C IMAX points to larger PSUM component (1=x,2=y)
864     IMAX = 1
865     IF (ABS(VtxP4(1,Nv)).LT.ABS(VtxP4(2,Nv))) IMAX = 2
866     NPC = VtxPnt(Nv,2)
867     IF (NPC.EQ.3) NPC = 2
868     IF (NPC.EQ.4) NPC = 2
869     DO Np=1,NPC
870     IF (Np.EQ.1) THEN
871     C Residual of first pointing constraint, this step
872     SUM = VtxP4(1,Nv)*DELVS(2,Nv) - VtxP4(2,Nv)*DELVS(1,Nv)
873     PMAG = SQRT(VtxP4(1,Nv)**2+VtxP4(2,Nv)**2)
874     XMAG = SQRT(DELVS(1,Nv)**2+DELVS(2,Nv)**2)
875     ELSE
876     C Residual of second pointing constraint, this step
877     SUM = DELVS(3,Nv)*VtxP4(IMAX,Nv) - DELVS(IMAX,Nv)*VtxP4(3,Nv)
878     PMAG = SQRT(VtxP4(IMAX,Nv)**2 + VtxP4(3,Nv)**2)
879     XMAG = SQRT(DELVS(IMAX,Nv)**2+DELVS(3,Nv)**2)
880     END IF
881     PCON(Nv,Np) = SUM
882     C Check for very small vertex separation
883     IF (XMAG .GT. .001) THEN
884     C OK. Get sin(angle)
885     SANG(Nv,Np) = PCON(Nv,Np)/(PMAG*XMAG)
886     ELSE
887     SANG(Nv,Np) = 2.0
888     ENDIF
889     END DO
890     C end vertex loop
891     220 CONTINUE
892     C Check the quality of satisfaction pf the mass constraints, this step
893     DO Nm=1,NMASSC
894     C Residual of mass constraint.
895     SUM = SQRT(McnP4(1,Nm)**2+McnP4(2,Nm)**2+McnP4(3,Nm)**2)
896     SUM = (McnP4(4,Nm)+SUM) * (McnP4(4,Nm)-SUM)
897     IF (SUM.LE.0.0) THEN
898     SUM = 0.0
899     ELSE
900     SUM = SQRT(SUM)
901     END IF
902     FMCDIF(Nm) = (SUM + CMASS(Nm)) * (SUM - CMASS(Nm))
903     MFTEST(Nm) = 0.5 * FMCDIF(Nm)
904     C Convert to Delta m in MeV from Delta m**2 in GeV
905     FMCDIF(Nm) = 500.*FMCDIF(Nm)/CMASS(Nm)
906     END DO
907     C Check the improvements(?) in pointing and mass constraints, this step
908     C If step size is too large the constraints will not be satisfied.
909     C If there is a problem, the step size will be halved
910     C Check pointing constraints
911     DO 230 Nv=1,NVERTX
912     Mv = VtxPnt(Nv,1)
913     IF (Mv.LT.0) GO TO 230
914     NPC = VtxPnt(Nv,2)
915     IF (NPC.EQ.3) NPC = 2
916     IF (NPC.EQ.4) NPC = 2
917     DO I=1,NPC
918     C = PCON(Nv,I) / (PCSAVE(Nv,I) + 0.001)
919     IF ((ABS(C).GT.1.0) .AND. (ABS(SANG(Nv,I)).GT..01)) THEN
920     D IF (DBGPRT.GT.1) THEN
921     D WRITE(PRINT,1051) ITER,ISCUT,Nv,Mv,I,C,SANG(Nv,I)
922     D1051 FORMAT(' Iter',I2,' Cut',I2,', Nv,Mv,I',2I3,I4,2F10.5)
923     D END IF
924     GO TO 250
925     END IF
926     END DO
927     C End vertex loop
928     230 CONTINUE
929     C Check mass constraints
930     DO Nm=1,NMASSC
931     C = ABS(MFTEST(Nm) / (MFSAVE(Nm) + 0.1))
932     IF (C.GT.1.0) THEN
933     D IF (DBGPRT.GT.1) THEN
934     D WRITE(PRINT,1052) ITER,ISCUT,Nm,C,MFTEST(Nm)
935     D1052 FORMAT(' Iter',I2,' Cut',I2,', Nm',I2,2F10.5)
936     D END IF
937     GO TO 250
938     END IF
939     END DO
940     GO TO 300
941     250 CONTINUE
942     C Count a cut step
943     ISCUT = ISCUT + 1
944     NTSCUT = NTSCUT + 1
945     C maximum number of cut steps exceeded
946     IF (ISCUT .GT. NMAXCT) THEN
947     IERR = 9
948     IJKERR(2) = 3
949     IJKERR(3) = ITER
950     WRITE(STRING,2050) IJKERR
951     GO TO 990
952     END IF
953     C Prepare to subtract off 1/2 step size taken
954     CUTFAC = -0.5*PARFAC
955     GO TO 110
956     C Accept this step
957     300 CONTINUE
958     CHISQR(0) = CHISQR(ITER)
959     STPTK = 1.0
960     IF (ITER.GT.0) THEN
961     STPTK = 0.0
962     DO NT=1,NTRACK
963     C make the difference between this step and the previous
964     DO I=1,5
965     PARDJF(I,NT) = PARDIF(I,NT) - PARDJF(I,NT)
966     STEP(I) = PARDJF(I,NT)/PARERR(I,NT)
967     STPTK = AMAX1(STPTK,ABS(STEP(I)))
968     END DO
969     END DO
970     END IF
971     D IF (DBGPRT.GT.1) THEN
972     D C = AMIN1(CHISQR(0),9999.0)
973     D L = 1
974     D IF (PRIMARY) L=0
975     D DO I=L,NVERTX
976     D WORK(I) = AMIN1(CHIV(I),999.0)
977     D END DO
978     D IF (NVERTX.EQ.1 .AND. L.EQ.1) THEN
979     D WRITE(PRINT,1070) stptk, C
980     D1070 FORMAT(/,' StpTk ',F8.3,'; ChiSqr =',F7.2)
981     D ELSE
982     D WRITE(PRINT,1071) stptk, C, (I,WORK(I),I=L,NVERTX)
983     D1071 FORMAT(/,' StpTk ',F8.3,'; ChiSqr =',F7.2, 4(3X,'ChiV',I2,F7.2) )
984     D END IF
985     D IF (ITER.EQ.0) GO TO 500
986     D DO NT=1,NTRACK
987     D WORK(Nt) = AMIN1(CHIT(Nt),999.0)
988     D DO I=1,5
989     D STEP(I) = PARDJF(I,NT)/PARERR(I,NT)
990     D END DO
991     D WRITE(PRINT,1075) nt, WORK(Nt), STEP
992     D1075 FORMAT(i5,F10.4,2x,5F10.6)
993     D END DO
994     D END IF
995     C Check for step acceptability
996     500 CONTINUE
997     IF (ITER.EQ.0) GO TO 550
998     IF (STPTK.LT.0.1) THEN
999     C accept the convergence
1000     GO TO 900
1001     ELSE IF (ITER.GE.MAXITR) THEN
1002     C "convergence", sort of. Accept the stinker?
1003     IF (STPTK.LT.0.2) THEN
1004     GO TO 900
1005     ELSE
1006     STPTK = AMIN1(STPTK,9999.0)
1007     IERR = 9
1008     IJKERR(2) = 4
1009     WRITE(STRING,2090) ITER,StpTk,CHISQR(0)
1010     2090 FORMAT('; Convergence failure, Itr =',I2,'; StpTk ',F7.2
1011     &, ' ChiSqr(i) ', 1P,E9.2)
1012     GO TO 990
1013     END IF
1014     ELSE
1015     IF (ITER.GT.2) THEN
1016     C after the 2nd step, if the "ChiSquare"
1017     TEST = FLOAT(NDOF) * chisqmx
1018     C is >15 "standard deviations", and if
1019     IF (CHISQR(0).GT.TEST) THEN
1020     C the last step was did not do much good
1021     IF (STPTK.GT.0.5) THEN
1022     STPTK = AMIN1(STPTK,9999.0)
1023     C give up in disgust
1024 paus 1.2 CP WRITE(*,*) 'Chi2: ',CHISQR(0)
1025 loizides 1.1 IERR = 9
1026     IJKERR(2) = 5
1027     WRITE(STRING,2095) ITER,StpTk,CHISQR(0)
1028     2095 FORMAT('; Bad convergence, Itr =',I2,'; StpTk ',F7.2
1029     &, ' ChiSqr(i) ', 1P, 6E9.2)
1030     GO TO 990
1031     END IF
1032     END IF
1033     END IF
1034     END IF
1035     550 CONTINUE
1036     C return for the next iteration step
1037     DO NT=1,NTRACK
1038     C save the last step on this track
1039     DO I=1,5
1040     PARDJF(I,NT) = PARDIF(I,NT)
1041     END DO
1042     END DO
1043     ITER = ITER + 1
1044     GO TO 100
1045     C Successful Return
1046     C------------------------------------------------------------------------------
1047     900 CONTINUE
1048     C final track parameters
1049     DO Nt=1,NTRACK
1050     DO I=1,5
1051     PAR(I,NT) = PAR0(I,Nt) + PARDIF(I,Nt)
1052     END DO
1053     D IF (DBGPRT.GT.0) THEN
1054     D write(print,5170)NT,(par(i,nt),i=1,5)
1055     D5170 format(1x,'Final track ',i3,' params ',5(1x,e10.4))
1056     D ENDIF
1057     END DO
1058     IF (PRINT.GT.0) THEN
1059     CALL CTVMPR (PRINT,DBGPRT, PARERR)
1060     END IF
1061     C Check for peculiar case of non-positive diagonal matrix elements, which
1062     C should never happen, but if it happens, better to report it than to
1063     C let it slip by unnoticed. All errors of this sort should be reported
1064     C immediately to the guilty parties.
1065     DO I = 1,TOFF(NTRACK)+3
1066     IF (VMAT(I,I).LE.0) THEN
1067     STRING = 'SERIOUS problem with ill-formed covariance matrix'
1068     IERR = 9
1069     IJKERR(1) = 9
1070     IJKERR(2) = 9
1071     CALL ERROR('CTVMFT',IERR,STRING)
1072     IF (PRINT.GT.0) WRITE (PRINT,*) MRUN,MNEV,I,VMAT(I,I)
1073     GOTO 999
1074     END IF
1075     END DO
1076     RETURN
1077     C Error Return
1078     C-------------------------------------------------------------------------------
1079     990 CONTINUE
1080     IF (IERR.NE.0) THEN
1081     IJKERR(1) = IERR
1082     NAME = 'CTVMFT'
1083     ccc write(*,9001) name,ierr,string
1084     ccc 9001 format(1x,A,": Ierr = ",i3," => ",A)
1085     D IF (PRINT.GT.0 .OR. IERR.GT.50) THEN
1086     D CALL ERROR (NAME,IERR,STRING)
1087     D END IF
1088     END IF
1089     999 CONTINUE
1090     RETURN
1091     END
1092     SUBROUTINE ERROR (NAME,IERR,STRING)
1093     INTEGER IERR
1094     CHARACTER*6 NAME
1095     CHARACTER*80 STRING
1096     INTEGER COUNT
1097     SAVE COUNT
1098     DATA COUNT /0/
1099     ccc WRITE(*,1000) NAME,IERR,STRING
1100     ccc 1000 FORMAT(1X,'subroutine ',A6,', Err',I3,' comment; ',A80)
1101     COUNT = COUNT+1
1102     RETURN
1103     END
1104     C===============================================================================
1105     SUBROUTINE CTVM00 (IERR, WXYZPV)
1106     C===============================================================================
1107     C Checks the current input specifications at the beginning of this call to
1108     C CTVMFT: (Vertex, conversion, Pointing, Mass Constraints) compound fit.
1109     C Any error detected in CTVM00 is a structural failure on the input conditions
1110     C and is (by default) treated as a fatal error. We attempt to crash the job
1111     C (after printing a specific error condition message). The studious who are
1112     C running interactively can discover how to avoid this crash; cf. the variables
1113     C "EXCUSE" and "ME", set in a local common block in CTVMFT.
1114     C If an error is detected, IERR = IJKERR(1) = 1
1115     C IJKERR(2) = the precise detected trouble.
1116     C WXYZPV is returned, it is the primary vertex double precision weight matrix
1117     C VtxVtx, the vertex "geneology", association structure is made and returned.
1118     C--Input data in the include file CTVMFT (COMMON /CTVMFC/)
1119     C NVERTX Number of vertices in this fit (MUST be at least 1)
1120     C NTRACK Number of tracks in this fit. NTRACK MUST be at least 2.
1121     C TrkVtx(MAXTRK,MAXVTX) (Logical) See the discussion in CTVMFT.
1122     C VtxPnt(MAXVTX,2) (Integer) See the discussion in CTVMFT.
1123     C TrkMcn(MAXTRK,NMASSC) (Logical) See the discussion in CTVMFT.
1124     C CMASS(NMASSC) (Real) See the discussion in CTVMFT.
1125     C TKBANK(MAXTRK) (Character*4)
1126     C Bank name (exempli gratia, 'QTRK','TRKS','SVXS','CTCS') from which
1127     C to get each track`s helix parameter and covariance data (GETTRK).
1128     C LIST (MAXTRK) (Integer)
1129     C Bank numbers of the tracks to be used.
1130     C Note that if LIST(i) is a negative integer it is assumed that the
1131     C information for this track is present unchanged from a previous call.
1132     C Edit log:
1133     C ---- ---
1134     C 11/28/94 WJA Require exactly 2 tracks for conversion vertex; always
1135     C require 1 or more tracks per vertex; If there is a "single
1136     C track vertex", this vertex must be contain at least one
1137     C multi-track exclusive vertex in its descendant chain.
1138     C 30 Jan 2003 F. Bedeschi: add checks specific to beamline constraint option
1139     C 04 FEB 2003 J. Guimaraes: Fixed bug in fiddle common block (missing chisqmx)
1140     C==============================================================================
1141     IMPLICIT NONE
1142     #include "MitCommon/Ctvmft/interface/ctvmdi.h"
1143     #include "MitCommon/Ctvmft/interface/ctvmft.h"
1144     #include "MitCommon/Ctvmft/interface/ctvmfi.h"
1145     INTEGER IERR
1146     REAL*8 WXYZPV(3,3)
1147     INTEGER Nv,Mv,Kv, Nt,Kt, Np,Nm
1148     INTEGER I,J, II,JJ
1149     INTEGER NtrVtx(MaxVtx)
1150     REAL SUM, WORK(MAXDIM)
1151     REAL SCR
1152     CHARACTER*4 NAME
1153     CHARACTER*80 STRING
1154     REAL ZERO,MINUS,SHOUT
1155     SAVE ZERO,MINUS
1156     DATA ZERO /0.0/, MINUS /-1.0/
1157     C Local variables pertaining to zero-track vertices
1158     INTEGER NMULTI
1159     C--------------- Check Input Conditions for illegal conditions -----------------
1160     C
1161    
1162     IF ((NTRACK.LT.2 .AND. VTXPNT(1,1) .NE. -100) .OR.
1163     > (NTRACK.LT.1 .AND. VTXPNT(1,1) .EQ. -100) .OR.
1164     > NTRACK.GT.MAXTRK) THEN
1165     IJKERR(2) = 1
1166     WRITE(STRING,1001) NTRACK
1167     1001 FORMAT('Inadequate or improper number of tracks;',I2)
1168     GO TO 900
1169     END IF
1170     IF (NVERTX.LT.1 .OR. NVERTX.GT.MAXVTX) THEN
1171     IJKERR(2) = 2
1172     WRITE(STRING,1002) NVERTX
1173     1002 FORMAT('Inadequate or improper number of vertices;',I2)
1174     GO TO 900
1175     END IF
1176     IF (NMASSC.LT.0 .OR. NMASSC.GT.MAXMCN) THEN
1177     IJKERR(2) = 3
1178     WRITE(STRING,1003) NMASSC
1179     1003 FORMAT('Improper number of mass constraints;',I2)
1180     GO TO 900
1181     END IF
1182     C count the number of measured tracks
1183     DO Nv=1,MaxVtx
1184     C present at each vertex
1185     NtrVtx(Nv) = 0
1186     Do Nt=1,NTRACK
1187     IF (TrkVtx(Nt,Nv)) NtrVtx(Nv) = NtrVtx(Nv)+1
1188     END DO
1189     END DO
1190     C make the vertex geneology table
1191     DO Kv=NVERTX,1,-1
1192     DO Nv =NVERTX,1,-1
1193     VtxVtx(Kv,Nv) =.FALSE.
1194     END DO
1195     VtxVtx(Kv,Kv) = .TRUE.
1196     C Kv is a descendant of its parent,
1197     1 IF (Nv.GT.0) THEN
1198     C its parent`s parent, ...
1199     VtxVtx(Kv,Nv) = .TRUE.
1200     Nv = VtxPnt(Nv,1)
1201     GO TO 1
1202     END IF
1203     END DO
1204     C Check the logic of vertex specifications
1205     DO 10 Kv=NVERTX,1,-1
1206     IJKERR(3) = Kv
1207     C exactly 2 tracks for conversion
1208     IF (Cvtx(Kv).NE.0) THEN
1209     IF (NtrVtx(Kv).NE.2) THEN
1210     IJKERR(2) = 12
1211     WRITE (STRING,'(A,I2,A,I2,A)')
1212     & 'Conversion vertex ',Kv,' with ',NtrVtx(Kv),' tracks'
1213     GO TO 900
1214     END IF
1215     END IF
1216     C If not a beamline constrained fit -- Joao 02/09/03
1217     IF (VtxPnt(1,1) .NE. -100) THEN
1218     C a one-track vertex must have a
1219     IF (NtrVtx(Kv).EQ.1) THEN
1220     C descendant with at least 2 tracks
1221     Mv = Kv
1222     DO Nv=Kv+1,NVERTX
1223     IF (VtxPnt(Nv,1).EQ.Mv) THEN
1224     C override the vertexpointing for 1track to only 1track
1225     C IF (NtrVtx(Nv).GT.1) GO TO 5
1226     IF (NtrVtx(Nv).GT.0) GO TO 5
1227     C Craig Blocker 1/9/03 - Changed the following line from
1228     C Mv = VtxPnt(Nv,1)
1229     C to get proper test done here.
1230     Mv = Nv
1231     END IF
1232     END DO
1233     IJKERR(2) = 13
1234     WRITE(STRING,'(A,I2,A,I2,A)')
1235     & 'Vertex ',Kv,' with ',NtrVtx(Kv),
1236     & ' tracks is not legally pointed at'
1237     GO TO 900
1238     C a zero-track vertex must have 2 or more
1239     ELSE IF (NtrVtx(Kv).EQ.0) THEN
1240     C descendants with at least 2 tracks.
1241     NMULTI = 0
1242     Mv = Kv
1243     DO Nv=Kv+1,NVERTX
1244     IF (VtxPnt(Nv,1).EQ.Mv) THEN
1245     IF (NtrVtx(Nv).GT.1) NMULTI = NMULTI + 1
1246     END IF
1247     END DO
1248     C If there are only 2 vertices pointed to this one
1249     C AND they both have >1 tracks then this is a valid
1250     C zero track vertex.
1251     IF (NMULTI.GE.2) GO TO 5
1252     IJKERR(2) = 13
1253     WRITE(STRING,'(A,I2,A,I2,A)')
1254     & 'Vertex ',Kv,' with ',NtrVtx(Kv),
1255     & ' tracks is not legally pointed at'
1256    
1257     GO TO 900
1258     END IF
1259     END IF
1260     C Check that Kv`s pointing is valid
1261     5 CONTINUE
1262     Nv = VtxPnt(Kv,1)
1263     IF (Nv.LE.0) THEN
1264     IF (Nv.LT.0) VtxPnt(Kv,2) = -1
1265     ELSE
1266     C Daughter vertex number must exceed
1267     IF (Nv.GE.Kv) THEN
1268     C mother vertex number
1269     IJKERR(2) = 14
1270     WRITE (STRING,'(A,I2,A,I2)')
1271     & 'Vertex ',Kv,' has illegal target vertex number ',Nv
1272     GO TO 900
1273     END IF
1274     C conversion vertex cannot be a target
1275     IF (Cvtx(Nv).GT.0) THEN
1276     IJKERR(2) = 15
1277     WRITE (STRING,'(A,I2,A)')
1278     & 'Vertex ',Kv,' has illegal target vertex type'
1279     GO TO 900
1280     END IF
1281     C Single-track pointing if and only if to single-track vertex
1282 bendavid 1.3 IF (VtxPnt(Kv,2).EQ.3.NEQV.NtrVtx(Nv).EQ.1) THEN
1283 loizides 1.1 IJKERR(2) = 16
1284     WRITE (STRING,'(I2,A,I2,A)')
1285     & Kv,' ==> ',Nv,' is an illegal 1-track vertex pointing'
1286     GO TO 900
1287     END IF
1288     C zero-track pointing if and only if to zero-track vertex
1289 bendavid 1.3 IF (VtxPnt(Kv,2).EQ.4.NEQV.NtrVtx(Nv).EQ.0) THEN
1290 loizides 1.1 IJKERR(2) = 17
1291     WRITE (STRING,'(I2,A,I2,A)')
1292     & Kv,' ==> ',Nv,' is an illegal 0-track vertex pointing'
1293     GO TO 900
1294     END IF
1295     END IF
1296     10 CONTINUE
1297     IJKERR(3) = 0
1298     C If VtxPnt requires a primary vertex, checks that the input primary vertex
1299     C covariance matrix is "reasonable" (id est, non-singular).
1300     NP = 0
1301     DO NV=1,NVERTX
1302     IF (VtxPnt(Nv,1).EQ.0) NP = NP+1
1303     END DO
1304     IF (NP.GT.0) THEN
1305     DO I=1,3
1306     C primary vertex input position
1307     XYZPV(I) = XYZPV0(I)
1308     DO J=1,3
1309     C primary vertex error matrix
1310     WXYZPV(J,I)= EXYZPV(J,I)
1311     END DO
1312     END DO
1313     C make the primary vertex weight matrix
1314     CALL DINV(3,WXYZPV,3,WORK,I)
1315     IF (I.NE.0) THEN
1316     IJKERR(2) = 19
1317     WRITE(STRING,'(A)')
1318     & 'The input primary vertex covariance matrix is singular.'
1319     GO TO 900
1320     END IF
1321     END IF
1322     C Check the specification of tracks
1323     C every track must be at a vertex
1324     DO 20 Nt=1,NTRACK
1325     IJKERR(3) = Nt
1326     IF (LIST(Nt).LE.0) THEN
1327     IJKERR(2) = 20
1328     C some track failed TkSlct
1329     IF (LIST(Nt).LT.0) THEN
1330     IJKERR(1) = 2
1331     IERR = 2
1332     RETURN
1333     END IF
1334     WRITE(STRING,'(A,I2,A)') 'Track ',Nt,' is not specified'
1335     GO TO 900
1336     END IF
1337     IF (TKBANK(NT).EQ.'QTRK') GO TO 11
1338     IF (TKBANK(NT).EQ.'TRKS') GO TO 11
1339     IF (TKBANK(NT).EQ.'TRKV') GO TO 11
1340     IF (TKBANK(NT).EQ.'SVXS') GO TO 11
1341     IF (TKBANK(NT).EQ.'CTCS') GO TO 11
1342     IJKERR(2) = 20
1343     WRITE(STRING,1005) NT,LIST(NT),TKBANK(NT)
1344     GO TO 900
1345     1005 FORMAT('Track ',I2,',',I4,2X,A4,' is improperly specified.')
1346     11 CONTINUE
1347     II = 0
1348     DO NV=1,NVERTX
1349     IF (TrkVtx(NT,NV)) II=II+1
1350     END DO
1351     C every track belongs to a vertex
1352     IF (II.LT.1) THEN
1353     IJKERR(2) = 21
1354     WRITE (STRING,'(A,I2,A)')
1355     & 'track ',Nt,' is not at a vertex.'
1356     GO TO 900
1357     C and to only one vertex
1358     ELSE IF (II.GT.1) THEN
1359     IJKERR(2) = 22
1360     WRITE(STRING,'(A,I2,A)')
1361     & 'Track ',Nt,' appears at two vertices'
1362     GO TO 900
1363     END IF
1364     C each track may appear only once
1365     DO Kt=Nt+1,NTRACK
1366     IF (IABS(LIST(Nt)).EQ.IABS(LIST(Kt))) THEN
1367     IF (TkBank(Nt).EQ.TkBank(Kt)) THEN
1368     IJKERR(2) = 23
1369     WRITE(STRING,'(A,I2,A,I2,A)')
1370     & 'Track ',Nt,' and Track ',Kt,' are identical'
1371     GO TO 900
1372     END IF
1373     END IF
1374     END DO
1375     20 CONTINUE
1376     IJKERR(3) = 0
1377     C Check the Mass Constraint/Track/Vertex specifications
1378     DO NM=1,NMASSC
1379     II = 0
1380     SUM = 0.0
1381     DO NT=1,NTRACK
1382     IF (TrkMcn(NT,NM)) THEN
1383     II=II+1
1384     SUM = SUM + TMASS(NT)
1385     END IF
1386     END DO
1387     C check for enough tracks
1388     IF (II.LT.2) THEN
1389     IJKERR(2) = 31
1390     WRITE(STRING,1021) NM
1391     1021 FORMAT('Mass Constraint',I2,' has too few tracks.')
1392     GO TO 900
1393     END IF
1394     C check for possible mass constraint
1395     IF (CMASS(NM).LE.SUM) THEN
1396     IJKERR(2) = 32
1397     WRITE(STRING,1022) NM,CMASS(NM),SUM
1398     1022 FORMAT('Mass Constraint',I2,', mass',F6.3,' has track mass0',F6.3)
1399     GO TO 900
1400     END IF
1401     END DO
1402     C
1403     C Check for beamline constraint specifications
1404     C
1405     IF (VTXPNT(1,1) .EQ. -100) THEN
1406     SCR = 0
1407     DO I = 1,3
1408     DO J = 1,3
1409     WXYZPV(I,J) = EXYZPV(I,J)
1410     IF (I .NE. J)SCR = SCR + ABS(EXYZPV(I,J))
1411     ENDDO
1412     ENDDO
1413     IF (EXYZPV(1,1) .LE. 0.0 .OR.
1414     > EXYZPV(2,2) .LE. 0.0 .OR.
1415     > EXYZPV(3,3) .LE. 0.0) THEN
1416     IJKERR(2) = 33
1417     WRITE(STRING, 1023)EXYZPV(1,1), EXYZPV(2,2), EXYZPV(3,3)
1418     1023 FORMAT('Beamline constraint.COVARIANCE NOT SET PROPERLY. C(I,I)='
1419     > ,3(F6.3,2X))
1420     GO TO 900
1421     ENDIF
1422     IF (SCR .NE. 0.0) THEN
1423     IJKERR(2) = 34
1424     WRITE(STRING, 1024)
1425     1024 FORMAT('Beamline constraint. COVARIANCE has non diagonal terms.')
1426     GO TO 900
1427     ENDIF
1428     C Make primary vertex weight matrix
1429     CALL DINV(3,WXYZPV,3,WORK,I)
1430     IF (I .NE. 0) THEN
1431     IJKERR(2) = 35
1432     WRITE(STRING, 1025)
1433     1025 FORMAT('Beamline constraint. PV covariance cannot be inverted.')
1434     GO TO 900
1435     ENDIF
1436     IF (NVERTX .NE. 1)THEN
1437     IJKERR(2) = 36
1438     WRITE(STRING, 1026)NVERTX
1439     1026 FORMAT('Beamline constraint. NVERTX not 0: = ',F6.3)
1440     GO TO 900
1441     ENDIF
1442     ENDIF
1443     100 CONTINUE
1444     IERR = 0
1445     IJKERR(1) = 0
1446     RETURN
1447     C Executive action; Terminate with extreme prejudice.
1448     900 CONTINUE
1449     IERR = 1
1450     IJKERR(1) = 1
1451     ccc PRINT 1999, IJKERR
1452     ccc 1999 FORMAT('Improper input specification, IJKERR=',3I3)
1453     CALL ERROR ('CTVM00',IERR,STRING)
1454     C Escape hatch, for debuggery
1455     IF (EXCUSE.EQ.0) THEN
1456     SHOUT = SQRT(MINUS) / ZERO
1457     STOP
1458     ELSE
1459     RETURN
1460     END IF
1461     END
1462     C==============================================================================
1463     SUBROUTINE CTVMFA (Nv, PRINT,IERR)
1464     C==============================================================================
1465     C
1466     C Calculates the initial approximation to the vertex position.
1467     C This subroutine tries to intersect circles that are (R,Phi) projections
1468     C of the helical trajectories of the two tracks specified in the calling
1469     C sequence.
1470     C If the circles intersect, the intersection with smaller z difference
1471     C between the 2 helices extrapolated to the intersection is chosen.
1472     C If the circles do not intersect, the vertex approximation is taken as
1473     C the point of closest appraoch of the two circles. Both cases of non-
1474     C intersection ("interiour", "exteriour") are treated.
1475     C Note that the tracks are required to travel "forwards" to the vertex,
1476     C and this requirement may override the "smallest delta Z" criterion.
1477     C Tests are made on the vertex radius and Z difference between the two
1478     C tracks, and error codes are returned for unacceptable vertices.
1479     C Note that, where possible, the calculation is completed, even if an
1480     C error condition is flagged.
1481     C Test parameter settings used to accept/reject vertex approximations;
1482     C DRMAX,DZMAX,RVMAX, TRNMAX,DSMIN
1483     C appear as data statements in the include file CTVMFT.INC.
1484     C IERR = 2 = IJKERR(1) marks failure in vertex first approximation
1485     C IJKERR(2)= 1 Concentric circles, in the first approximation
1486     C 2 (conversion) widely separated exteriour circles at the midpoint
1487     C 3 (conversion) widely separated interiour circles at the midpoint
1488     C 4 widely separated exteriour circles at the approximate vertex
1489     C 5 widely separated interiour circles at the approximate vertex
1490     C 6 Rv is too large at the chosen intersection point.
1491     C 7 delta(Z) is too large at the chosen intersection point.
1492     C 8 a track turning angle to the chosen vertex is too large
1493     C 19 no acceptable solution with an adequately positive arc length
1494     C 21 zero-track vertexing: either/both vertex momenta are too small (<0.01 MeV)
1495     C 22 zero-track vertexing: Two lines are parallel/antiparallel
1496     C Edit log:
1497     C ---- ---
1498     C 10/xx/94 WJA Allow NTRK = 1 or 2, for possible 1-track vertex; add
1499     C line-intersects-circle approximation for 1-track vertex;
1500     C add split-the-difference approximation for conversions;
1501     C detect negative JJ() values to trigger these special-case
1502     C first approximations.
1503     C 05/xx/02 MSM Allow NTRK = 0, for possible zero-track vertex; add
1504     C line-intersects-line approximation for zero-track vertex;
1505     C Detect JJ(1)=JJ(2)=0 to trigger this.
1506     C===============================================================================
1507     IMPLICIT NONE
1508     #include "MitCommon/Ctvmft/interface/ctvmco.h"
1509     #include "MitCommon/Ctvmft/interface/ctvmdi.h"
1510     #include "MitCommon/Ctvmft/interface/ctvmft.h"
1511     #include "MitCommon/Ctvmft/interface/ctvmuv.h"
1512     INTEGER Nv, PRINT, IERR
1513     INTEGER I,J,K,L,M,N, JJ(2),II(2), NSOL, KPRINT
1514     INTEGER Nt, Mv, NTRK
1515     REAL HELIX(5,2), P(5),Q(5,5)
1516     REAL A,B, RA(2), RVI(2), TANG(2,2)
1517     REAL Xsvt,Ysvt, AA,BB,CC,DD,RR, Pt
1518     REAL TMP,PZV,FITA,FITB
1519     COMPLEX XYP0,PXYV,XYVR,PXYVR,XYTMP
1520     C Local variables for accumulating first-approximation momentum sums
1521     REAL SPh0,CPh0,SPhs,CPhs,SPhi,CPhi
1522     LOGICAL CONV
1523     REAL*8 XC(2),YC(2),RC(2)
1524     REAL*8 AB(2), XX,YY,Y0,YY2,COST,SINT,DX,DY,D,U,V
1525     INTEGER BEAM
1526     C Map the parameter order to CTVMFT form:
1527     INTEGER MAP(5)
1528     SAVE BEAM, MAP
1529     DATA BEAM /0/
1530     C (Ctg,Crv,Z0,D0,Phi)->(Crv,Phi,Ctg,D0,Z0)
1531     DATA MAP / 3,1,5,4,2 /
1532     C Variables for the first appx for zero track vertexing case
1533     C (line intersects line)
1534     C ZV="Zero-Vertex" :
1535     C First the two un-rotated vertex positions and momenta (2D)
1536     REAL ZVX1,ZVY1,ZVX2,ZVY2,ZVPX1,ZVPY1,ZVPX2,ZVPY2
1537     C Next the two rotated vertex postions and momenta (2D)
1538     REAL ZVRX1,ZVRY1,ZVRX2,ZVRY2,ZVRPX1,ZVRPY1,ZVRPX2,ZVRPY2
1539     C Next some double versions for a magnitude check (see code)
1540     REAL*8 ZVDPX1,ZVDPY1,ZVDPX2,ZVDPY2,ZVDPS1,ZVDPS2
1541     C Next some doubles for calculating sin and cos from dot and cross prod
1542     REAL*8 ZVDCS1,ZVDCS2,ZVDSN1,ZVDSN2,ZVDRSN
1543     C Next some real versions of the dot and cross products
1544     REAL ZVCS1,ZVCS2,ZVSN1,ZVSN2
1545     C Next the anticlockwise angles from right x axis to the vertex momentum
1546     REAL ZVANG1,ZVANG2
1547     C Next the rotation angle, and its sine and cosine
1548     REAL ZVROTANG,ZVSIN,ZVCOS
1549     C Next the two roated gradients (M) and intercepts (C)
1550     REAL ZVRM1,ZVRM2,ZVRC1,ZVRC2
1551     C Next some swim variables for the Z calculation
1552     REAL ZVZSWIM1,ZVZSWIM2,ZVZ1,ZVZ2,ZVPZ1,ZVPZ2
1553     C Finally the rotated point of intersection..and a temp.
1554     REAL ZVRINTX,ZVRINTY,ZVMDIFF
1555     C local variables to determine the average z of the input track set
1556     REAL SUMZOS, SUMOOS, ZAVG
1557     C Start of code
1558     C------------------------------------------------------------------------------
1559     KPRINT = 0
1560     IF (PRINT.GT.0 .AND. DBGPRT.GT.10) KPRINT=PRINT
1561     IERR = 0
1562     IJKERR(1) = 0
1563     C Special case beamline constraint -Joao 02/11/03
1564     IF (VTXPNT(1,1) .EQ.-100) THEN
1565     DO I=1,3
1566     XYZVRT(I,Nv) = XYZPV0(I)
1567     END DO
1568     GOTO 50
1569     ENDIF
1570     C Find first two tracks (if they exist)
1571     JJ(1) = 0
1572     JJ(2) = 0
1573     DO Nt=1,NTRACK
1574     IF (TrkVtx(Nt,Nv)) THEN
1575     IF (JJ(1).EQ.0) THEN
1576     JJ(1) = Nt
1577     ELSE
1578     JJ(2) = Nt
1579     GO TO 1
1580     END IF
1581     END IF
1582     END DO
1583     1 CONTINUE
1584     CONV = .FALSE.
1585     NTRK = 2
1586     C special case; conversion vertex
1587     IF (Cvtx(Nv).GT.0) CONV=.TRUE.
1588     C special case; "single track vertex"
1589     IF (JJ(2).EQ.0 .AND. JJ(1).NE.0) THEN
1590     DO Mv=Nv+1,NVERTX
1591     IF (VtxPnt(Mv,1).EQ.Nv) THEN
1592     C For 1-track vertex, JJ(2) is a vertex
1593     NTRK = 1
1594     C that points to this vertex
1595     JJ(2) = Mv
1596     END IF
1597     END DO
1598     END IF
1599     C special case: "zero track vertex"
1600     IF (JJ(2).EQ.0 .AND. JJ(1).EQ.0) THEN
1601     NTRK = 0
1602     DO Mv=Nv+1,NVERTX
1603     IF (VtxPnt(Mv,1).EQ.Nv) THEN
1604     C For 0-track vertex, JJ(2) and JJ(1) are the vertices
1605     C that point to this vertex
1606     IF (JJ(1).EQ.0) THEN
1607     JJ(1) = Mv
1608     ELSE
1609     JJ(2) = Mv
1610     END IF
1611     END IF
1612     END DO
1613     END IF
1614     C Continue if this is a zero track vertex.
1615     C Otherwise leapfrog to the right place.
1616     IF (NTRK.EQ.0) THEN
1617     C Initialise the position and momenta of 2
1618     C Vertices. This gives the 2 lines to intersect
1619     ZVX1 = XYZVRT(1,JJ(1))
1620     ZVY1 = XYZVRT(2,JJ(1))
1621     ZVX2 = XYZVRT(1,JJ(2))
1622     ZVY2 = XYZVRT(2,JJ(2))
1623     ZVPX1 = VtxP4(1,JJ(1))
1624     ZVPY1 = VtxP4(2,JJ(1))
1625     ZVPX2 = VtxP4(1,JJ(2))
1626     ZVPY2 = VtxP4(2,JJ(2))
1627     C And Z:
1628     ZVZ1 = XYZVRT(3,JJ(1))
1629     ZVZ2 = XYZVRT(3,JJ(2))
1630     ZVPZ1 = VtxP4(3,JJ(1))
1631     ZVPZ2 = VtxP4(3,JJ(2))
1632     C Initialise rotation angle to zero
1633     ZVROTANG = 0
1634     C Calculate mag**2 of each momenta
1635     ZVDPX1=ZVPX1
1636     ZVDPY2=ZVPY1
1637     ZVDPX2=ZVPX2
1638     ZVDPY2=ZVPY2
1639     ZVDPS1=ZVDPX1**2 + ZVDPY1**2
1640     ZVDPS2=ZVDPX2**2 + ZVDPY2**2
1641     C Require each mag**2>1.0E-10 which means
1642     C the mag>1.0E-5 which is 0.01 MeV which is safe.
1643     IF(ZVDPS1.LE.1.0E-10 .OR. ZVDPS2.LE.1.0E-10) THEN
1644     C One or both vertex momenta are too small!
1645     IJKERR(2) = 21
1646     GO TO 1000
1647     ENDIF
1648     C Require abs(sin(relative angle))>0.00001 (ie 1/100 millirad)
1649     C To catch parallel momenta
1650     ZVDRSN = (ZVDPX1*ZVDPY2 - ZVDPX2*ZVDPY1)
1651     & /(SQRT(ZVDPS1)*SQRT(ZVDPS2))
1652     IF(ABS(ZVDRSN).LE.1.0E-5) THEN
1653     C Vertex Momenta are too parallel
1654     IJKERR(2) = 22
1655     GO TO 1000
1656     ENDIF
1657     C Calculate Angle between each momenta and x axis:
1658     ZVDCS1 = ZVDPX1/(SQRT(ZVDPS1))
1659     ZVDCS2 = ZVDPX2/(SQRT(ZVDPS2))
1660     ZVDSN1 = ZVDPY1/(SQRT(ZVDPS1))
1661     ZVDSN2 = ZVDPY2/(SQRT(ZVDPS2))
1662     C Explicit cast to real
1663     ZVCS1 = ZVDCS1
1664     ZVCS2 = ZVDCS2
1665     ZVSN1 = ZVDSN1
1666     ZVSN2 = ZVDSN2
1667     C Pick right trig solution:
1668     C First Vertex Momentum:
1669     IF(ZVCS1.LT.0.0) THEN
1670     IF(ZVSN1.LT.0.0) THEN
1671     ZVANG1 = PI - ACOS(ZVCS1)
1672     ELSE
1673     ZVANG1 = ACOS(ZVCS1)
1674     ENDIF
1675     ELSE
1676     IF(ZVSN1.LT.0.0) THEN
1677     ZVANG1 = TWOPI - ACOS(ZVCS1)
1678     ELSE
1679     ZVANG1 = PI + ACOS(ZVCS1)
1680     ENDIF
1681     ENDIF
1682     C And second:
1683     IF(ZVCS2.LT.0.0) THEN
1684     IF(ZVSN2.LT.0.0) THEN
1685     ZVANG2 = PI - ACOS(ZVCS2)
1686     ELSE
1687     ZVANG2 = ACOS(ZVCS2)
1688     ENDIF
1689     ELSE
1690     IF(ZVSN2.LT.0.0) THEN
1691     ZVANG2 = TWOPI - ACOS(ZVCS2)
1692     ELSE
1693     ZVANG2 = PI + ACOS(ZVCS2)
1694     ENDIF
1695     ENDIF
1696     C Set rotation angle:
1697     ZVROTANG = ZVANG1 + 0.5*(ZVANG2 - ZVANG1)
1698     C Do the rotation:
1699     ZVSIN = SIN(ZVROTANG)
1700     ZVCOS = COS(ZVROTANG)
1701     ZVRX1 = ZVX1*ZVCOS - ZVY1*ZVSIN
1702     ZVRY1 = ZVX1*ZVSIN + ZVY1*ZVCOS
1703     ZVRX2 = ZVX2*ZVCOS - ZVY2*ZVSIN
1704     ZVRY2 = ZVX2*ZVSIN + ZVY2*ZVCOS
1705     ZVRPX1 = ZVPX1*ZVCOS - ZVPY1*ZVSIN
1706     ZVRPY1 = ZVPX1*ZVSIN + ZVPY1*ZVCOS
1707     ZVRPX2 = ZVPX2*ZVCOS - ZVPY2*ZVSIN
1708     ZVRPY2 = ZVPX2*ZVSIN + ZVPY2*ZVCOS
1709     C Now solve intersection in "safe" coordinates
1710     C (ie ZVRPX1 and ZVRPX2 should both be non-zero)
1711     C Calculate gradients and intercepts:
1712     ZVRM1 = ZVRPY1/ZVRPX1
1713     ZVRM2 = ZVRPY2/ZVRPX2
1714     ZVRC1 = ZVRY1 - ZVRM1*ZVRX1
1715     ZVRC2 = ZVRY2 - ZVRM2*ZVRX2
1716     C Calculate the rotated intersection:
1717     ZVRINTX = (ZVRC2-ZVRC1)/(ZVRM1-ZVRM2)
1718     ZVRINTY = (ZVRM1*ZVRINTX + ZVRC1)
1719     C Now rotate back:
1720     ZVROTANG=-1.0*ZVROTANG
1721     ZVSIN = SIN(ZVROTANG)
1722     ZVCOS = COS(ZVROTANG)
1723     XSVI(1) = ZVRINTX*ZVCOS - ZVRINTY*ZVSIN
1724     YSVI(1) = ZVRINTX*ZVSIN + ZVRINTY*ZVCOS
1725     C Now calculate how many momentum vectors to swim
1726     C to get to the right Z:
1727     C First Line:
1728     ZVZSWIM1 = (XSVI(1) - ZVX1)/ZVPX1
1729     C Second Line:
1730     ZVZSWIM2 = (XSVI(1) - ZVX2)/ZVPX2
1731     C And calculate the two z points:
1732     ZZ(1,1) = ZVZ1 + ZVZSWIM1*ZVPZ1
1733     ZZ(2,1) = ZVZ2 + ZVZSWIM2*ZVPZ2
1734     J = 1
1735     RVI(J) = SQRT(XSVI(J)**2+YSVI(J)**2)
1736     DZSVI(J) = ZZ(2,J) - ZZ(1,J)
1737     C Jump to end:
1738     GO TO 45
1739     ENDIF
1740     C loop over the two vertex-tracks
1741     DO I=1,NTRK
1742     C Track bank number
1743     J = IABS(LIST(JJ(I)))
1744     C dummy out MASS,RADIUS
1745     A = 0.0
1746     CALL GETTRK (J,TKBANK(JJ(I)), A,A,0
1747     >, K,P,Q, IERR)
1748     C Quit, if error finding track data
1749     IF (IERR .NE. 0) THEN
1750     TKERR(JJ(I)) = IJKERR(2)
1751     GO TO 1000
1752     END IF
1753     DO K=1,5
1754     HELIX(MAP(K),I) = P(K)
1755     END DO
1756     END DO
1757     C For convenience, order the circles so that the first has smaller radius...
1758     II(1) = 1
1759     II(2) = 2
1760     IF (NTRK.EQ.2) THEN
1761     IF (ABS(HELIX(1,1)).LT.ABS(HELIX(1,2))) THEN
1762     II(1) = 2
1763     II(2) = 1
1764     END IF
1765     END IF
1766     C make the circle radii, centers
1767     DO I=1,NTRK
1768     C there are two tracks (circles)
1769     RC(I) = 0.5D0/HELIX(1,II(I))
1770     U = RC(I)+HELIX(4,II(I))
1771     XC(I) =-U*SIN(HELIX(2,II(I)))
1772     YC(I) = U*COS(HELIX(2,II(I)))
1773     RA(I) = ABS(RC(I))
1774     END DO
1775     C there are usually two intersections
1776     DO J=1,2
1777     XSVI(J) = 0.0
1778     YSVI(J) = 0.0
1779     RVI (J) = 2.0*RVMAX
1780     DZSVI(J)= 2.0*DZMAX
1781     DO I=1,2
1782     SS(I,J) = 0.0
1783     ZZ(I,J) = 0.0
1784     TANG(I,J) = PI
1785     END DO
1786     END DO
1787     IF (NTRK.GT.1) GOTO 10
1788     C Special handling of single-track vertex
1789     TMP = 1.0/(1.0+2.0*HELIX(1,1)*HELIX(4,1))
1790     C Track parametrization
1791     FITA = HELIX(1,1)*TMP
1792     FITB = HELIX(4,1)*(1+HELIX(1,1)*HELIX(4,1))*TMP
1793     XYP0 = CMPLX(COS(HELIX(2,1)),SIN(HELIX(2,1)))
1794     C Daughter vertex momentum
1795     PXYV = CMPLX(VTXP4(1,JJ(2)),VTXP4(2,JJ(2)))
1796     TMP = 1.0/ABS(PXYV)
1797     PXYV = PXYV*TMP
1798     PZV = VTXP4(3,JJ(2))*TMP
1799     C Position & momentum, rotated to PHI0=0 coordinate system
1800     XYVR = CMPLX(XYZVRT(1,JJ(2)),XYZVRT(2,JJ(2)))*CONJG(XYP0)
1801     PXYVR = PXYV*CONJG(XYP0)
1802     C Solve quadratic equation for displacement DD from vertex to track
1803     AA = FITA
1804     BB = 0.5*IMAG(PXYVR)-FITA*REAL(XYVR*CONJG(PXYVR))
1805     CC = FITA*ABS(XYVR)**2+FITB-IMAG(XYVR)
1806     TMP = BB*BB-AA*CC
1807     IF (TMP.GT.0.) THEN
1808     NSOL = 2
1809     IF (BB.LT.0.) THEN
1810     AA = -AA
1811     BB = -BB
1812     CC = -CC
1813     ENDIF
1814     BB = BB+SQRT(TMP)
1815     DD = CC/BB
1816     DO I=1,2
1817     XSVI(I) = XYZVRT(1,JJ(2))+DD*REAL(PXYV)
1818     YSVI(I) = XYZVRT(2,JJ(2))+DD*IMAG(PXYV)
1819     ZZ(2,I) = XYZVRT(3,JJ(2))+DD*PZV
1820     TANG(2,I) = 0.0
1821     DD = BB/AA
1822     ENDDO
1823     GOTO 20
1824     ENDIF
1825     C No intersection; find closest approach and use half the distance
1826     NSOL = 1
1827     C Check for line and circle antiparallel at closest approach
1828     IF (REAL(PXYVR).LT.0) THEN
1829     PXYV = -PXYV
1830     PXYVR = -PXYVR
1831     PZV = -PZV
1832     ENDIF
1833     C Use SIN(PHI)**2/(1+COS(PHI)) for (1-COS(PHI)) to reduce roundoff
1834     CC = IMAG(PXYVR)**2/(1.0+REAL(PXYVR))
1835     C Store 1/(2c) to avoid recalculation
1836     AA = 0.5/HELIX(1,1)
1837     C TMP is signed distance from circle to line, along (-SIN(PHI),COS(PHI))
1838     TMP = (IMAG(XYVR)-HELIX(4,1))*REAL(PXYVR)
1839     & -REAL(XYVR)*IMAG(PXYVR)+CC*AA
1840     XYTMP = CMPLX(IMAG(PXYV),CC)*AA
1841     & +CMPLX(0.0,HELIX(4,1))+0.5*TMP*CMPLX(-IMAG(PXYV),REAL(PXYV))
1842     DD = REAL((XYTMP-XYVR)*CONJG(PXYVR))
1843     XYTMP = XYTMP*XYP0
1844     XSVI(1) = REAL(XYTMP)
1845     YSVI(1) = IMAG(XYTMP)
1846     ZZ(2,1) = XYZVRT(3,JJ(2))+DD*PZV
1847     TANG(2,1) = 0
1848     GOTO 20
1849     C two track (or more) vertex
1850     10 CONTINUE
1851     C get the circle center separation
1852     DX = XC(2) - XC(1)
1853     DY = YC(2) - YC(1)
1854     D = DX*DX+DY*DY
1855     C the circles are concentric
1856     IF (D.LE.0.D0) THEN
1857     IJKERR(2) = 1
1858     GO TO 1000
1859     END IF
1860     D = DSQRT(D)
1861     C Separation (signed quantity); if >0, the
1862     U = D-RA(1)-RA(2)
1863     C two circles do not intersect, <0, they may
1864     FMCDIF(1) = U
1865     C Special handling of conversion vertex
1866     IF (CONV) THEN
1867     C the circles are too far appart to accept
1868     IF (ABS(U).GT.DRMAX) THEN
1869     IF (U.GT.0.0) THEN
1870     C ...exteriour
1871     IJKERR(2) = 2
1872     ELSE
1873     C ...interiour
1874     IJKERR(2) = 3
1875     END IF
1876     GO TO 1000
1877     END IF
1878     NSOL = 1
1879     C Vertex is track radius plus half of separation away from each center
1880     XSVI(1) = (XC(1)*(RA(2)+0.5*U)+XC(2)*(RA(1)+0.5*U))/D
1881     YSVI(1) = (YC(1)*(RA(2)+0.5*U)+YC(2)*(RA(1)+0.5*U))/D
1882     C Branch down to vertex acceptability checking
1883     GO TO 20
1884     END IF
1885     C Rotate, translate to a system where the
1886     COST = DX/D
1887     C two circle centers lie on the X axis.
1888     SINT = DY/D
1889     C Y` = Y1` = Y2`
1890     Y0 = (-XC(1)*YC(2)+XC(2)*YC(1))/D
1891     C X1', X2'
1892     DO I=1,2
1893     AB(I) = COST*XC(I) + SINT*YC(I)
1894     END DO
1895     U = (XC(2)+XC(1))*(XC(2)-XC(1)) + (YC(2)+YC(1))*(YC(2)-YC(1))
1896     V = (RA(2)+RA(1))*(RA(2)-RA(1))
1897     C the common circle X` (if they intersect)
1898     XX = 0.5D0 * (U-V)/D
1899     U = DSQRT((XX-AB(1))**2)
1900     C Y''**2 is positive if they intersect
1901     YY2= (RA(1)+U) * (RA(1)-U)
1902     C the circles intersect;
1903     IF (YY2.GT.0.0) THEN
1904     C two intersection points (+/- Y)
1905     YY = DSQRT(YY2)
1906     C invert the translation, rotation
1907     DO J=1,2
1908     U = YY+Y0
1909     XSVI(J) = COST*XX - SINT*U
1910     YSVI(J) = SINT*XX + COST*U
1911     YY =-YY
1912     END DO
1913     NSOL = 2
1914     GO TO 20
1915     END IF
1916     C We get here if the two circles do not intersect;
1917     C Find how close in the XY plane they approach each other,
1918     C and take the point half way between them as our vertex approximation.
1919     U = D - (RA(1)+RA(2))
1920     C A is outside of B
1921     IF (U.GT.0.0D0) THEN
1922     V = U
1923     J = 2
1924     IF (AB(1).LT.AB(2)) J=1
1925     XX = AB(J) + RA(J)
1926     C A is inside of B
1927     ELSE
1928     IF (AB(1).LT.AB(2)) THEN
1929     XX = AB(2) - RA(2)
1930     V = AB(1) - RA(1) - XX
1931     ELSE
1932     XX = AB(1) + RA(1)
1933     V = AB(2) + RA(2) - XX
1934     END IF
1935     END IF
1936     XX = XX + 0.5D0*V
1937     C rotate back to the original system
1938     XSVI(1) = COST*XX - SINT*Y0
1939     YSVI(1) = SINT*XX + COST*Y0
1940     NSOL = 1
1941     C the circles are too far appart to accept
1942     IF (V.GT.DRMAX) THEN
1943     IF (U.GT.0.0D0) THEN
1944     C ...exteriour
1945     IJKERR(2) = 4
1946     ELSE
1947     C ...interiour
1948     IJKERR(2) = 5
1949     END IF
1950     GO TO 1000
1951     END IF
1952     20 CONTINUE
1953     C loop over solutions
1954     DO 30 J=1,NSOL
1955     C loop over tracks
1956     DO I=1,NTRK
1957     C point from circle center
1958     U = (XSVI(J)-XC(I))/RC(I)
1959     C to the intersection vertex
1960     V =-(YSVI(J)-YC(I))/RC(I)
1961     C turning angle from the track origin
1962     U = ATAN2(U,V) - HELIX(2,II(I))
1963     IF (U.LT.-PI) THEN
1964     U = U + TWOPI
1965     ELSE IF (U.GT. PI) THEN
1966     U = U - TWOPI
1967     END IF
1968     TANG(I,J) = U
1969     C arc length
1970     SS(I,J) = RC(I)*U
1971     ZZ(I,J) = HELIX(5,II(I)) + SS(I,J)*HELIX(3,II(I))
1972     END DO
1973     RVI(J) = SQRT(XSVI(J)**2+YSVI(J)**2)
1974     DZSVI(J) = ZZ(2,J) - ZZ(1,J)
1975     30 CONTINUE
1976     C Check that there is at least one potentially acceptable solution!
1977     A = AMIN1(RVI(1),RVI(2))
1978     C check the vertex radius is acceptable
1979     IF (A.GT.RVMAX) THEN
1980     IJKERR(2) = 6
1981     GO TO 1000
1982     END IF
1983     A = AMIN1(ABS(DZSVI(1)),ABS(DZSVI(2)))
1984     C check the Z difference is acceptable
1985     IF (A.GT.DZMAX) THEN
1986     IJKERR(2) = 7
1987     GO TO 1000
1988     END IF
1989     A = AMAX1(ABS(TANG(1,1)),ABS(TANG(2,1)))
1990     B = AMAX1(ABS(TANG(1,2)),ABS(TANG(2,2)))
1991     C check there is an acceptable TANG
1992     IF (AMIN1(A,B).GT.TRNMAX) THEN
1993     IJKERR(2) = 8
1994     GO TO 1000
1995     END IF
1996     C minimum track arc length, sol`n 1
1997     A = AMIN1(SS(1,1),SS(2,1))
1998     C minimum track arc length, sol`n 2
1999     B = AMIN1(SS(1,2),SS(2,2))
2000     C limit the minimum arc length
2001     IF (AMAX1(A,B).LT.DSMIN) THEN
2002     WRITE(*,*) ' DSMIN,A,B: ',DSMIN,A,B
2003     IJKERR(2) = 9
2004     GO TO 1000
2005     END IF
2006     C there may be a possible acceptable solution, in (R,deltaZ,S,Tang)
2007     J = 1
2008     IF (NSOL.EQ.1) GO TO 40
2009     IF (ABS(DZSVI(2)).LT.ABS(DZSVI(1))) J=2
2010     FLIP = 0
2011     A = AMAX1(ABS(TANG(1,J)),ABS(TANG(2,J)))
2012     B = AMIN1(SS(1,J),SS(2,J))
2013     IF (RVI(J).GT.RVMAX) FLIP = 1
2014     IF (ABS(DZSVI(J)).GT.DZMAX) FLIP = FLIP+2
2015     IF (A.GT.TRNMAX) FLIP = FLIP+4
2016     IF (B.LT.DSMIN) FLIP = FLIP+8
2017     IF (FLIP.NE.0) THEN
2018     IF (J.EQ.1) THEN
2019     J = 2
2020     ELSE
2021     J = 1
2022     END IF
2023     END IF
2024     C final checks of the final solution...
2025     40 CONTINUE
2026     A = AMAX1(ABS(TANG(1,J)),ABS(TANG(2,J)))
2027     B = AMIN1(SS(1,J),SS(2,J))
2028     C check that TANG is acceptable
2029     IF (A.GT.TRNMAX) THEN
2030     IJKERR(2) = 8
2031     GO TO 1000
2032     END IF
2033     C limit the minimum arc length
2034     IF (B.LT.DSMIN) THEN
2035     IJKERR(2) = 9
2036     GO TO 1000
2037     END IF
2038     C Continue point from zero track case:
2039     45 CONTINUE
2040     C check the vertex radius
2041     IF (RVI(J).GT.RVMAX) THEN
2042     IJKERR(2) = 6
2043     GO TO 1000
2044     END IF
2045     C check the Z difference
2046     IF (ABS(DZSVI(J)).GT.DZMAX) THEN
2047     IJKERR(2) = 7
2048     GO TO 1000
2049     END IF
2050     C "acceptable" solution. Set initial vertex approximation
2051     XYZVRT(1,Nv) = XSVI(J)
2052     XYZVRT(2,Nv) = YSVI(J)
2053     XYZVRT(3,Nv) = 0.5 * (ZZ(1,J) + ZZ(2,J))
2054     C Go off and collect (GETTRK) the track data, and make the first approximation
2055     C vertex momentum sums (which will be needed for single track vertex first
2056     C approximation calculations).
2057     C GETTRK failures or failures in transporting the tracks not used in the vertex
2058     C finding to the vertex will return IERR = IJKERR(1) = 3.
2059     50 CONTINUE
2060     D IF (DBGPRT.GT.0) THEN
2061     D RR = SQRT(XYZVRT(1,Nv)**2+XYZVRT(2,Nv)**2)
2062     D WRITE (PRINT,1010) Nv,(XYZVRT(I,Nv),I=1,3),RR
2063     D1010 FORMAT (/,' Vertex',I2,
2064     D & ' Approximation; ',3F10.4,5X,'RR',F7.2)
2065     D END IF
2066     C Initialize vertex 3-momentum to the sum
2067     VtxP4(1,Nv) = 0
2068     C of daughter vertex 3-momenta
2069     VtxP4(2,Nv) = 0
2070     C (needed for 1-track vertex CTVMFA)
2071     VtxP4(3,Nv) = 0
2072     DO Mv=Nv+1,NVERTX
2073     IF (VtxPnt(Mv,1).EQ.Nv) THEN
2074     VtxP4(1,Nv) = VtxP4(1,Nv)+VtxP4(1,Mv)
2075     VtxP4(2,Nv) = VtxP4(2,Nv)+VtxP4(2,Mv)
2076     VtxP4(3,Nv) = VtxP4(3,Nv)+VtxP4(3,Mv)
2077     END IF
2078     END DO
2079     C Collect track information for this vertex
2080     SUMZOS = 0.0
2081     SUMOOS = 0.0
2082     DO Nt=1,NTRACK
2083     IF (TrkVtx(Nt,Nv)) THEN
2084     CALL CTVM01(KPRINT,Nt,BEAM,PARERR(1,Nt),IERR)
2085     IF (IERR.NE.0) THEN
2086     C GETTRK failure, or, track cannot reach vertex
2087     GO TO 1000
2088     END IF
2089     TKERR(Nt) = 0
2090     SPh0 = SIN(Par0(2,Nt))
2091     CPh0 = COS(Par0(2,Nt))
2092     Xsvt = XYZVRT(1,Nv)*CPh0+XYZVRT(2,Nv)*SPh0
2093     Ysvt = XYZVRT(2,Nv)*CPh0-XYZVRT(1,Nv)*SPh0
2094     C Proceed blissfully
2095     SPhs = 2*Par0(1,Nt)*Xsvt
2096     C 10/23/02 Add protection here against unphysical Sphs.
2097     C Craig Blocker
2098     Sphs = max(-1.,min(1.,SPhs))
2099     CPhs = SQRT((1-SPhs)*(1+SPhs))
2100     SPhi = CPh0*Sphs+SPh0*CPhs
2101     CPhi = CPh0*CPhs-SPh0*SPhs
2102     C add this track`s contribution to vertex momentum
2103     PT = PSCALE/ABS(Par0(1,Nt))
2104     VtxP4(1,Nv) = VtxP4(1,Nv)+PT*CPhi
2105     VtxP4(2,Nv) = VtxP4(2,Nv)+PT*SPhi
2106     VtxP4(3,Nv) = VtxP4(3,Nv)+PT*Par0(3,Nt)
2107     C increment sums for average z0. Use only track with z measurement
2108     IF(PARERR(5,NT).GT.0.0.AND.VTXPNT(1,1).EQ.-100)THEN
2109     SUMZOS = SUMZOS + PAR0(5,NT)/(PARERR(5,NT)**2)
2110     SUMOOS = SUMOOS + 1.0/(PARERR(5,NT)**2)
2111     D IF (DBGPRT.GT.0) THEN
2112     D write(print,5161)NT, (par0(i,NT),i=1,5)
2113     D5161 format(1x,'track ',i3,' Par: C,phi,ctg,D,Z',5(1x,e10.4))
2114     D write(print,5162)NT, (parerr(i,NT),i=1,5)
2115     D5162 format(1x,'track ',i3,' Err: C,phi,ctg,D,Z',5(1x,e10.4))
2116     D END IF
2117     END IF
2118     END IF
2119     END DO
2120     C Get z average to get good starting point in beamline fit
2121     IF (VTXPNT(1,1).EQ.-100) THEN
2122     ZAVG = 0.0
2123     IF (SUMOOS.GT.0.0)THEN
2124     ZAVG = SUMZOS/SUMOOS
2125     XYZVRT(3,NV) = ZAVG
2126     END IF
2127     END IF
2128     1000 CONTINUE
2129     IF (IERR.NE.0) THEN
2130     IJKERR(1) = IERR
2131     ELSE IF (IJKERR(2).NE.0) THEN
2132     IERR = 2
2133     IJKERR(1) = 2
2134     IJKERR(3) = Nv
2135     END IF
2136     RETURN
2137     END
2138     C==============================================================================
2139     SUBROUTINE CTVM01 (PRINT, NT,BEAM, PARERR, IERR)
2140     C==============================================================================
2141     C===Description:
2142     C Collects/checks track data for the use of CTVMFT for track NT (uses GETTRK),
2143     C with bank number LIST(NT), bank type TKBANK(NT), and mass TMASS(NT).
2144     C The track/vertex configuration TrkVtx and vertex approximation
2145     C XYZVRT(xyz,NV) are communicated through the include file CTVMFT.INC.
2146     C The vertex approximation is used to find the RADIUS at which dE/dX and
2147     C Coulomb multiple scattering contributions are evaluated.
2148     C===Input Arguments:
2149     C PRINT If compiled DEBUG, outputs formatted output to unit PRINT
2150     C NT Desired track, in the array LIST
2151     C BEAM Beam constraint flag, for GETTRK
2152     C===Output Arguments:
2153     C PARERR Track helix parameter errors
2154     C IERR = IJKERR(1) = 3 flags an error getting the track parameters
2155     C IJKERR(2) = 1 GETTRK returns an error for this track
2156     C 2 the track covariasnce matrix is uninvertable
2157     C 3 turns through too large an angle to the vertex
2158     C 4 moves too far backwards to the vertex
2159     C===Author:
2160     C see CTVMFT
2161     C-------------------------------------------------------------------------------
2162     IMPLICIT NONE
2163     #include "MitCommon/Ctvmft/interface/ctvmco.h"
2164     #include "MitCommon/Ctvmft/interface/ctvmdi.h"
2165     #include "MitCommon/Ctvmft/interface/ctvmft.h"
2166     C===Local Declarations:
2167     INTEGER NT, PRINT, IERR
2168     REAL PARERR(5)
2169     LOGICAL BEAM
2170     INTEGER I,J,K,L, NV
2171     REAL P(5),Q(5,5), HELIX(5,MaxTrk),HWGT(5,5,MaxTrk)
2172     REAL RADV, TS,S
2173     REAL WORK(MAXDIM)
2174     REAL*8 RC,XYC(2),U,V, ELM(5,5)
2175     CHARACTER*80 STRING
2176     C Map the parameter order to CTVMFT form:
2177     INTEGER MAP(5)
2178     C (Ctg,Crv,Z0,D0,Phi)->(Crv,Phi,Ctg,D0,Z0)
2179     DATA MAP / 3,1,5,4,2 /
2180     C===Start of Code:
2181     C-------------------------------------------------------------------------------
2182     C get the vertex for this track
2183     DO NV=1,NVERTX
2184     IF (TrkVtx(NT,NV)) GO TO 11
2185     END DO
2186     11 RADV = SQRT(XYZVRT(1,NV)**2 + XYZVRT(2,NV)**2)
2187     C call GETTRK for track data
2188     IF (LIST(NT).GT.0) THEN
2189     CALL GETTRK (LIST(NT),TKBANK(NT),TMASS(NT),RADV, BEAM
2190     > ,K,P,Q, IERR)
2191     C Quit on error finding track data bank
2192     IF (IERR.NE.0) THEN
2193     TKERR(NT) = IERR
2194     IJKERR(2) = 1
2195     GO TO 100
2196     END IF
2197     C save the parameter vector
2198     DO I=1,5
2199     K = MAP(I)
2200     HELIX(K,NT) = P(I)
2201     PARERR(K) = SQRT(Q(I,I))
2202     DO J=1,5
2203     L = MAP(J)
2204     ELM(L,K) = Q(J,I)
2205     END DO
2206     END DO
2207     C make -and save- the weight matrix
2208     CALL DINV(5,ELM,5,WORK,IERR)
2209     IF (IERR.NE.0) THEN
2210     TKERR(NT) = IERR
2211     IJKERR(2) = 2
2212     GO TO 100
2213     END IF
2214     DO I=1,5
2215     DO J=1,5
2216     HWGT(J,I,NT) = ELM(J,I)
2217     END DO
2218     END DO
2219     END IF
2220     C load the fit parameter vector,
2221     DO I=1,5
2222     PAR0(I,NT) = HELIX(I,NT)
2223     C and the corresponding weight matrix
2224     DO J=1,5
2225     G(J,I,NT) = HWGT(J,I,NT)
2226     END DO
2227     END DO
2228     RC = 0.5D0/HELIX(1,NT)
2229     U = RC + HELIX(4,NT)
2230     XYC(1)=-U*SIN(HELIX(2,NT))
2231     XYC(2)= U*COS(HELIX(2,NT))
2232     U = (XYZVRT(1,NV)-XYC(1))/RC
2233     V =-(XYZVRT(2,NV)-XYC(2))/RC
2234     TS = ATAN2(U,V) - HELIX(2,NT)
2235     IF (TS.LT.-PI) THEN
2236     TS = TS + TWOPI
2237     ELSE IF (TS.GT. PI) THEN
2238     TS = TS - TWOPI
2239     END IF
2240     S = RC*TS
2241     C it turns too much
2242     IF (ABS(TS).GT.TRNMAX) THEN
2243     IJKERR(2) = 3
2244     C ?what to do?
2245     ELSE IF (S.LT.DSMIN) THEN
2246     IJKERR(2) = 4
2247     END IF
2248     D IF (PRINT.GT.0) THEN
2249     D IF (IJKERR(2).NE.0) THEN
2250     D WRITE(STRING,1023) NT,LIST(NT), S
2251     D1023 FORMAT(' negative arc length, track',I2,I6 ,F7.2)
2252     D END IF
2253     D IF (PRINT.GT.0) THEN
2254     D IF (NT.EQ.1) WRITE(PRINT,1025)
2255     D WRITE(PRINT,1026) NT,(HELIX(I,NT),I=1,5), S
2256     D1025 FORMAT(/,' Track Initial helix parameters, arc length to Vtx')
2257     D1026 FORMAT(I6,2X,1P,E11.3,0P,F10.4,3F10.4, F12.2)
2258     D END IF
2259     D END IF
2260     C===Return to Caller:
2261     100 CONTINUE
2262     IF (IJKERR(2).NE.0) THEN
2263     IERR = 3
2264     IJKERR(1) = 3
2265     IJKERR(3) = NT
2266     END IF
2267     RETURN
2268     END
2269     C==============================================================================
2270     SUBROUTINE CTVMVF (PRINT, Nv, VXI)
2271     C==============================================================================
2272     C===Description:
2273     C Calculates contributions from track Nt (at vertex Nv) to the derivative
2274     C vector VXI and derivitive matrix VMAT for the vertex fit section of CTVMFT.
2275     C This portion of the code is somewhat awkward to follow. See the derivation
2276     C of these formulae in CDF note 19zz (J.P. Marriner)
2277     C NB: this code does not properly handle tracks that turn through more than
2278     C 90 degrees between the distance of closest approach to the z axis and
2279     C the vertex. These tracks are considered pathological. The code will
2280     C be correct everywhere, however, if the proper branch of the arcsin
2281     C function is taken. (The initial approximation may be so bad that the
2282     C desired solution will not be found, however).
2283     C===Input Arguments:
2284     C Nv vertex
2285     C===Output Arguments:
2286     C VXI first derivative contributions for this track to the vertex fit
2287     C VMAT second derivative matrix (in common, include file CTVMFT.INC)
2288     C------------------------------------------------------------------------ ------
2289     C===Implicit None Declaration:
2290     IMPLICIT NONE
2291     #include "MitCommon/Ctvmft/interface/ctvmco.h"
2292     #include "MitCommon/Ctvmft/interface/ctvmdi.h"
2293     #include "MitCommon/Ctvmft/interface/ctvmft.h"
2294     C===Local Declarations:
2295     INTEGER PRINT
2296     INTEGER NV
2297     REAL*8 VXI(MAXDIM)
2298     INTEGER I,J,K,L
2299     INTEGER NT, NtF,NvF, TI,TJ, VI,Vj
2300     REAL C,PHI,COTH, D,Z, PT
2301     REAL TWOC, S,TS,TRAD
2302     REAL SP,CP, XCYS,XSYC,XC2YS2, SINCS,COSCS,TWOCS
2303     REAL DPXDT, DPYDT, DSDC,DSDP,DSDX,DSDY
2304     REAL EMAT(3,2), FMAT(3,2)
2305     C------------------------------------------------------------------------ ------
2306     C===Start of Code:
2307     DO 50 Nt=1,NTRACK
2308     IF (.NOT.TrkVtx(Nt,Nv)) GO TO 50
2309     C current half curvature
2310     C = PAR0(1,NT) + PARDIF(1,NT)
2311     C current phi
2312     PHI = PAR0(2,NT) + PARDIF(2,NT)
2313     C current coth(theta)
2314     COTH = PAR0(3,NT) + PARDIF(3,NT)
2315     TWOC = 2.0*C
2316     C Xsv*cos(phi) + Ysv*sin(phi), -Xsv*sin(phi) + Ysv*cos(phi)
2317     C (Xsv*cos(phi))**2 + (Ysv*sin(phi))**2
2318     SP = SIN(PHI)
2319     CP = COS(PHI)
2320     XCYS = XYZVRT(1,Nv)*CP + XYZVRT(2,Nv)*SP
2321     XSYC = -XYZVRT(1,Nv)*SP + XYZVRT(2,Nv)*CP
2322     XC2YS2 = (XYZVRT(1,Nv)*CP)**2 + (XYZVRT(2,Nv)*SP)**2
2323     C t = 2.0 * c * (Xsv*cos(phi) + Ysv*sin(phi)) = argument of arcsin
2324     C s = projected distance in xy plane along helix to vertex
2325     C sin ( c*s), cos ( c*s ), 2.0 * sin(c*s) * cos(c*s)
2326     C d(arcsin(t))/dt = 1 / sqrt (1 - t**2 )
2327     TS = TWOC*XCYS
2328     C 1/20/04 Protect against TWOC begin zero. Craig Blocker
2329     if(twoc .eq. 0.) then
2330     s = xcys
2331     else
2332     S = ASIN(TS)/TWOC
2333     endif
2334     SINCS = SIN(C*S)
2335     COSCS = COS(C*S)
2336     TWOCS = 2.0*SINCS*COSCS
2337     TRAD = SQRT((1.-TS)*(1.+TS))
2338     C Helix parameters d0 and z0 are dependent variables.
2339     C They are functions of the vertex and track parameters.
2340     C 1/20/04 Protect against C being zero. Craig Blocker
2341     if(c .eq. 0.) then
2342     D = xsyc
2343     else
2344     D = XSYC - SINCS**2/C
2345     endif
2346     Z = XYZVRT(3,Nv) - COTH*S
2347     C Difference between fitted and measured d0, z0
2348     PARDIF(4,NT) = D - PAR0(4,NT)
2349     PARDIF(5,NT) = Z - PAR0(5,NT)
2350     C Remember all flavors of momentum for this track
2351     C 1/20/04 Protect against C being zero. Here it is not
2352     C clear what to set PT to. I chose 999. GeV since this is
2353     C a very large Pt in CDF, this is roughly a standard deviation
2354     C from infinite, and should be clearly recognizable. Craig Blocker
2355     if(c .eq. 0.) then
2356     PT = 999.
2357     else
2358     PT = PSCALE/ABS(C)
2359     endif
2360     C x component of momentum
2361     TrkP4(NT,1) = PT*(CP*TRAD-SP*TS)
2362     C y component of momentum
2363     TrkP4(NT,2) = PT*(SP*TRAD+CP*TS)
2364     C z component of momentum
2365     TrkP4(NT,3) = PT*COTH
2366     C Transverse momentum
2367     TrkP4(NT,5) = PT
2368     C total momentum
2369     TrkP4(NT,6) = PT*SQRT(1.0+COTH**2)
2370     C energy
2371     TrkP4(NT,4) = SQRT(TrkP4(NT,6)**2+TMASS(NT)**2)
2372     C dPx/dt
2373     DPXDT =-PT*(SP+TS*CP/TRAD)
2374     C dPy/dt
2375     DPYDT = PT*(CP-TS*SP/TRAD)
2376     C dPx/dc
2377     if(c.ne.0.) then
2378     DDA(NT,1) =-TrkP4(NT,1)/C + 2.0*XCYS*DPXDT
2379     else
2380     dda(nt,1) = 999.
2381     endif
2382     C dPx/dPhi
2383     DDA(NT,2) =-PT*(TRAD*SP+TS*CP) + TWOC*XSYC*DPXDT
2384     C dPx/dXsv
2385     DDA(NT,3) = TWOC*CP*DPXDT
2386     C dPx/dYsv
2387     DDA(NT,4) = TWOC*SP*DPXDT
2388     C dPy/dc
2389     if(c .ne. 0.) then
2390     DDA(NT,5) =-TrkP4(NT,2)/C + 2.0*XCYS*DPYDT
2391     else
2392     dda(nt,5) = 999.
2393     endif
2394     C dPy/dPhi
2395     DDA(NT,6) = PT*(TRAD*CP-TS*SP) + TWOC*XSYC*DPYDT
2396     C dPy/dXsv
2397     DDA(NT,7) = TWOC*CP*DPYDT
2398     C dPy/dYsv
2399     DDA(NT,8) = TWOC*SP*DPYDT
2400     C Get the derivatives of s with respect to the fit parameters
2401     C See if argument of arcsin is small
2402     C (track with a small turning angle to the vertex point)
2403     C Yes. use power series approximation
2404     IF (ABS(TS).LT.5.E-3) THEN
2405     DSDC =-(0.666667 - 0.3*TS**2)*TS**3
2406     C No. Use full functional form
2407     ELSE
2408     DSDC = TS/TRAD - TWOC*S
2409     ENDIF
2410     C Get full derivative ds/dc
2411     if(twoc .ne. 0.) then
2412     DSDC = DSDC/(TWOC*C)
2413     else
2414     dsdx = 999.
2415     endif
2416     C ds/dphi
2417     DSDP = XSYC/TRAD
2418     C ds/dXsv
2419     DSDX = CP/TRAD
2420     C ds/dYsv
2421     DSDY = SP/TRAD
2422     C d(d0)/dc, d(d0)/dphi, d(d0)/dcot(theta)
2423     if(c .ne. 0.) then
2424     EMAT(1,1) = -SINCS*(TWOC*S*COSCS-SINCS)/C**2 - TWOCS*DSDC
2425     else
2426     emat(1,1) = 999.
2427     endif
2428     EMAT(2,1) = -XCYS - TWOCS*DSDP
2429     EMAT(3,1) = 0.0
2430     C d(z0)/dc, d(z0)/dphi, d(z0)/dcot(theta)
2431     EMAT(1,2) = -COTH*DSDC
2432     EMAT(2,2) = -COTH*DSDP
2433     EMAT(3,2) = -S
2434     C d(d0)/dXsv, d(d0)/dYsv, d(d0)/dZsv
2435     FMAT(1,1) = -SP - TWOCS*CP/TRAD
2436     FMAT(2,1) = CP - TWOCS*SP/TRAD
2437     FMAT(3,1) = 0.0
2438     C d(z0)/dXsv, d(z0)/dYsv, d(z0)/dZsv
2439     FMAT(1,2) = -COTH*DSDX
2440     FMAT(2,2) = -COTH*DSDY
2441     FMAT(3,2) = 1.0
2442     C Index into matrix equations for track NT
2443     NtF = TOFF(NT)
2444     C Index into matrix equations for vertex NV
2445     NvF = VOFF(Nv)
2446     DO 20 I=1,3
2447     TI = NtF + I
2448     VI = NvF + I
2449     C loop over (d0,z0)
2450     DO K=1,2
2451     C Ft * G2 * Xi2
2452     VXI(Vi) = VXI(Vi) - FMAT(I,K)* (G(K+3,4,NT)*PARDIF(4,NT)
2453     & + G(K+3,5,NT)*PARDIF(5,NT))
2454     C (Gd + Et * G2 ) * Xi2
2455     VXI(Ti) = VXI(Ti) - PARDIF(K+3,NT) *
2456     & (G(I,K+3,NT) + EMAT(I,1)*G(4,K+3,NT) + EMAT(I,2)*G(5,K+3,NT))
2457     END DO
2458     DO 10 J=1,3
2459     TJ = NtF + J
2460     VJ = NvF + J
2461     C Ft * Gd * Xi3
2462     VXI(Vi) = VXI(Vi)
2463     & - (FMAT(I,1)*G(4,J,NT)+FMAT(I,2)*G(5,J,NT))*PARDIF(J,NT)
2464     C (G3 + Et * Gd) * Xi3
2465     VXI(Ti) = VXI(Ti) - (G(I,J,NT)
2466     & + EMAT(I,1)*G(4,J,NT)+EMAT(I,2)*G(5,J,NT))*PARDIF(J,NT)
2467     C G3
2468     VMAT(Ti,Tj) = G(I,J,NT)
2469     DO K=1,2
2470     C Gd * F
2471     VMAT(Vi,Tj) = VMAT(Vi,Tj)+FMAT(I,K)*G(K+3,J,NT)
2472     C Et * Gdt + Gd * E
2473     VMAT(Ti,Tj) = VMAT(Ti,Tj)
2474     & + EMAT(I,K)*G(K+3,J,NT)+ G(I,K+3,NT)*EMAT(J,K)
2475     DO L=1,2
2476     C Ft * G2 * F
2477     VMAT(Vi,Vj) = VMAT(Vi,Vj)
2478     & + FMAT(I,K)*G(K+3,L+3,NT)*FMAT(J,L)
2479     C Et * G2 * F
2480     VMAT(Vi,Tj) = VMAT(Vi,Tj)
2481     & + FMAT(I,K)*G(K+3,L+3,NT)*EMAT(J,L)
2482     C Et * G2 * E
2483     VMAT(Ti,Tj) = VMAT(Ti,Tj)
2484     & + EMAT(I,K)*G(K+3,L+3,NT)*EMAT(J,L)
2485     C end of loop on L
2486     END DO
2487     C end of loop on K
2488     END DO
2489     C end of loop on J
2490     10 CONTINUE
2491     C end of loop on I
2492     20 CONTINUE
2493     D IF (PRINT.GT.0) THEN
2494     D TS = TS/C
2495     D WRITE(PRINT,1045) NT,(PARDIF(I,NT),I=1,5), D,Z,TS
2496     D1045 FORMAT(/,' Track',I3,1X,1P,5E11.3,3X,0P,3F11.4)
2497     D WRITE(PRINT,1047) (DDA(Nt,J),J=1,8)
2498     D1047 FORMAT(10X,1P,8E11.3)
2499     D WRITE(PRINT,1046) (VXI(I),I=1,MATDIM)
2500     D DO I=1,MATDIM
2501     D WRITE(PRINT,1046) (VMAT(J,I),J=1,I)
2502     D1046 FORMAT(5X,0P,10E11.3)
2503     D END DO
2504     D END IF
2505     C end of the track loop, this vertex
2506     50 CONTINUE
2507     C------------------------------------------------------------------------ ------
2508     C===Return to Caller:
2509     C Symmetrize the derivative matrix
2510     DO I=1,MATDIM-1
2511     DO J=I+1,MATDIM
2512     VMAT(J,I) = VMAT(I,J)
2513     END DO
2514     END DO
2515     RETURN
2516     END
2517     C===============================================================================
2518     SUBROUTINE CTVMCF (PRINT, NV, VXI)
2519     C===============================================================================
2520     C CTVMCF calculates "conversion constraint" contributions to the derivative
2521     C vector and matrix for vertex Nv (08/29/94 JPB and WJA)
2522     C--Input parameters
2523     C Input data in the include file CTVMFT (COMMON /CTVMFC/)
2524     C A physically reasonable constraint to impose in fitting a vertex at which
2525     C a photon conversion is believed to have occurred is that the invariant
2526     C mass of the two tracks be as small as possible, i.e. that the opening angle
2527     C of the two tracks at the vertex be zero. Where the tracks are copunctual,
2528     C they should be collinear.
2529     C In r-phi, a convenient way to express this constraint is that at the radius
2530     C of conversion, the sum of the azimuth and the turning angle is equal for
2531     C both tracks, i.e. Phi1+2*Crv1*S1(r) = Phi2+2*Crv2*S2(r), where S_i(r) is
2532     C the arc length (projected into r-phi) of track i at radius r, and Phi_i
2533     C and Crv_i are the azimuth and half-curvature of track i. In other words,
2534     C we equate the r-phi momentum directions of the two tracks at the vertex.
2535     C In r-z, the constraint is clearly that Ctg1 = Ctg2.
2536     C-------------------------------------------------------------------------------
2537     IMPLICIT NONE
2538     #include "MitCommon/Ctvmft/interface/ctvmco.h"
2539     #include "MitCommon/Ctvmft/interface/ctvmdi.h"
2540     #include "MitCommon/Ctvmft/interface/ctvmft.h"
2541     INTEGER PRINT
2542     INTEGER Nv
2543     REAL*8 VXI(MaxDim)
2544     INTEGER Trk1,Trk2,NvF,NcF,I,J,IT1F,IT2F
2545     REAL XV,YV,Crv1,Crv2,Phi1,Phi2,Ctg1,Ctg2,Phs1,Phs2,S1,S2
2546     REAL DS1DX,DS2DX,DS1DY,DS2DY,DSDCrv1,DSDCrv2,DSDPhi1,DSDPhi2
2547     REAL CPhi1,CPhi2,SPhi1,SPhi2,CPhs1,CPhs2,SPhs1,SPhs2
2548     REAL SHOUT,MINUS/-1/,ZERO/0/
2549     CHARACTER*80 STRING
2550     C-------------------------------------------------------------------------------
2551     C Find the first two tracks for this vertex
2552     Trk1 = 0
2553     Trk2 = 0
2554     DO I=1,NTRACK
2555     IF (TrkVtx(I,Nv)) THEN
2556     IF (Trk1.EQ.0) THEN
2557     Trk1 = I
2558     ELSE
2559     Trk2 = I
2560     GO TO 100
2561     END IF
2562     END IF
2563     END DO
2564     100 CONTINUE
2565     C Save some possibly useful offsets into VMAT
2566     IT1F = TOFF(Trk1)
2567     IT2F = TOFF(Trk2)
2568     NvF = VOFF(Nv)
2569     NcF = COFF(Nv)
2570     C Vertex position
2571     XV = XYZVRT(1,Nv)
2572     YV = XYZVRT(2,Nv)
2573     C Track parameters
2574     Crv1 = PAR0(1,Trk1)+PARDIF(1,Trk1)
2575     Crv2 = PAR0(1,Trk2)+PARDIF(1,Trk2)
2576     Phi1 = PAR0(2,Trk1)+PARDIF(2,Trk1)
2577     Phi2 = PAR0(2,Trk2)+PARDIF(2,Trk2)
2578     Ctg1 = PAR0(3,Trk1)+PARDIF(3,Trk1)
2579     Ctg2 = PAR0(3,Trk2)+PARDIF(3,Trk2)
2580     C Simple functions of track parameters
2581     SPhi1 = SIN(Phi1)
2582     SPhi2 = SIN(Phi2)
2583     CPhi1 = COS(Phi1)
2584     CPhi2 = COS(Phi2)
2585     C Track turning angles (to get momentum direction)
2586     SPhs1 = 2*Crv1*(XV*CPhi1+YV*SPhi1)
2587     SPhs2 = 2*Crv2*(XV*CPhi2+YV*SPhi2)
2588     CPhs1 = SQRT((1+SPhs1)*(1-SPhs1))
2589     CPhs2 = SQRT((1+SPhs2)*(1-SPhs2))
2590     Phs1 = ASIN(SPhs1)
2591     Phs2 = ASIN(SPhs2)
2592     C Arc length in XY plane
2593     S1 = 0.5*Phs1/Crv1
2594     S2 = 0.5*Phs2/Crv2
2595     C d(arc length)/d(vertex position)
2596     DS1DX = CPhi1/CPhs1
2597     DS2DX = CPhi2/CPhs2
2598     DS1DY = SPhi1/CPhs1
2599     DS2DY = SPhi2/CPhs2
2600     C d(arc length)/d(track parameters)
2601     IF (ABS(CPhs1).GT.0.005) THEN
2602     DSDCrv1 = 0.5*(SPhs1/CPhs1-Phs1)/(Crv1*Crv1)
2603     ELSE
2604     DSDCrv1 = 0.33333333*SPhs1**3*(0.9*SPhs1*SPhs1-1)/(Crv1*Crv1)
2605     END IF
2606     IF (ABS(CPhs2).GT.0.005) THEN
2607     DSDCrv2 = 0.5*(SPhs2/CPhs2-Phs2)/(Crv2*Crv2)
2608     ELSE
2609     DSDCrv2 = 0.33333333*SPhs2**3*(0.9*SPhs2*SPhs2-1)/(Crv2*Crv2)
2610     END IF
2611     DSDPhi1 = (-XV*SPhi1+YV*CPhi1)/CPhs1
2612     DSDPhi2 = (-XV*SPhi2+YV*CPhi2)/CPhs2
2613     C Constraint in r-phi, C_rphi = (Phi1+2*Crv1*S1)-(Phi2+2*Crv2*S2)
2614     VXI(NcF+1) = (Phi2+Phs2)-(Phi1+Phs1)
2615     IF (VXI(NcF+1).LT.-PI) VXI(NcF+1) = VXI(NcF+1)+2D0*PI
2616     IF (VXI(NcF+1).GT.+PI) VXI(NcF+1) = VXI(NcF+1)-2D0*PI
2617     C Optional constraint in r-z, C_rz = Ctg1-Ctg2
2618     IF (Cvtx(Nv).EQ.2) THEN
2619     VXI(NcF+2) = Ctg2-Ctg1
2620     END IF
2621     C Derivatives of the r-phi constraint C_rphi with respect to the fit
2622     C parameters (X,Y,Z,Crv1,Phi1,Ctg1,Crv2,Phi2,Ctg2)
2623     C d/dXv
2624     VMAT(NVF+1,NCF+1) = 2D0*(Crv1*DS1DX-Crv2*DS2DX)
2625     C d/dYv
2626     VMAT(NVF+2,NCF+1) = 2D0*(Crv1*DS1DY-Crv2*DS2DY)
2627     C d/dCrv1
2628     VMAT(IT1F+1,NCF+1) = +(1D0+2D0*(S1+Crv1*DSDCrv1))
2629     C d/dCrv2
2630     VMAT(IT2F+1,NCF+1) = -(1D0+2D0*(S2+Crv2*DSDCrv2))
2631     C d/dPhi1
2632     VMAT(IT1F+2,NCF+1) = +(1D0+2D0*Crv1*DSDPhi1)
2633     C d/dPhi2
2634     VMAT(IT2F+2,NCF+1) = -(1D0+2D0*Crv2*DSDPhi2)
2635     C Optional derivatives of the r-z constraint C_rz with respect to
2636     C the fit parameters
2637     IF (Cvtx(Nv).EQ.2) THEN
2638     C d/dCtg1
2639     VMAT(IT1F+3,NcF+2) = +1D0
2640     C d/dCtg2
2641     VMAT(IT2F+3,NcF+2) = -1D0
2642     END IF
2643     C Symmetrize
2644     DO I=1,MATDIM-1
2645     DO J=I+1,MATDIM
2646     VMAT(J,I) = VMAT(I,J)
2647     END DO
2648     END DO
2649     C All done
2650     RETURN
2651     END
2652     C===============================================================================
2653     SUBROUTINE CTVMPF (PRINT, NV, VXI)
2654     C===============================================================================
2655     C CTVMPD calculates "pointing constraint" contributions to the derivative
2656     C vector and matrix for vertex Nv, "pointing" at vertex Mv =VtxPnt(Nv,2)
2657     C--Input parameters
2658     C Input data in the include file CTVMFT (COMMON /CTVMFC/)
2659     C Let dX, dY, dZ = difference between the first and the second vertex
2660     C Px = VtxP4(1,Nv), etc
2661     C dX = DELV(1), etc
2662     C The first pointing constraint is Px * dY - Py * dX = 0,
2663     C The second is Pi * dZ - Pz * di = 0
2664     C (where i is x if |Px| > |Py|, otherwise i is y)
2665     C The first pointing constraint constrains the projections of the two vectors
2666     C P and d onto the x,y plane to be parallel (or antiparallel).
2667     C The second constraint constrains the vectors to be parallel or antiparallel
2668     C in 3 dimensions.
2669     C NB: The program makes this explicit choice of axes so that one can apply an
2670     C x,y pointing constraint or (optionally) a 3 dimensional constraint.
2671     C This choice of axes will not produce the desired results for the case
2672     C Px = Py = 0. This case is thought to be unlikely; It might occur for massive
2673     C objects (Z`s, eg) produced with no transverse momentum. For these types of
2674     C events one is probably better advised to use the "beam constraint" anyway.
2675     C Edit log:
2676     C ---- ---
2677     C 10/xx/94 WJA To handle 1-track vertex, add NPC variable and set it to
2678     C the number of Lagrange multipliers needed to effect the
2679     C desired pointing constraint: normally equal to VtxPnt(Nv,2)
2680     C but equal to 2 if VtxPnt(Nv,2) is zero, since 1-track point
2681     C points in both projections.
2682     C 05/xx/02 MSM Similar for zero-track vertexing.
2683     C-------------------------------------------------------------------------------
2684     IMPLICIT NONE
2685     #include "MitCommon/Ctvmft/interface/ctvmdi.h"
2686     #include "MitCommon/Ctvmft/interface/ctvmft.h"
2687     INTEGER PRINT
2688     INTEGER Nv
2689     REAL*8 VXI(MaxDim)
2690     REAL TEMP(5), C, DELV(3)
2691     INTEGER I1,I2, IMAT,JMAT
2692     INTEGER NvF,MvF,Kv,KvF,NtF, LpF,Lp, I,J, Nt,Mv, Np
2693     INTEGER NPC
2694     C-------------------------------------------------------------------------------
2695     C IMAT points to larger PSUM component (1=x,2=y)
2696     IF (ABS(VtxP4(1,Nv)).GT.ABS(VtxP4(2,Nv))) THEN
2697     IMAT = 1
2698     JMAT = 0
2699     ELSE
2700     IMAT = 2
2701     JMAT = 4
2702     END IF
2703     C vertex towards which Nv "points"
2704     Mv = VtxPnt(Nv,1)
2705     C vertex displacement vector
2706     DO I=1,3
2707     DELV(I) = XYZVRT(I,Mv) - XYZVRT(I,Nv)
2708     END DO
2709     C offset to 2nd vertex
2710     NvF = VOFF(Nv)
2711     C offset to this pointing constraint
2712     LpF = POFF(Nv)
2713     C offset to target (primary) vertex
2714     MvF = 0
2715     C the target vertex is NOT primary
2716     IF (Mv.GT.0) MvF=VOFF(Mv)
2717     NPC = VtxPnt(Nv,2)
2718     C Use both constraints for 1-track vertex
2719     IF (NPC.EQ.3) NPC = 2
2720     IF (NPC.EQ.4) NPC = 2
2721     C Loop over pointing constraints
2722     DO 50 Np=1,NPC
2723     C offset to the current pointing constraint
2724     Lp = LpF + Np
2725     C First constraint. 1=x, 2=y
2726     IF (Np.EQ.1) THEN
2727     I1 = 1
2728     I2 = 2
2729     C otherwise 2nd constraint
2730     ELSE
2731     C 1=bigger of px,py (IMAT), 2=z
2732     I1 = IMAT
2733     I2 = 3
2734     ENDIF
2735     C "residual" (Pi)
2736     VXI(Lp) =-VtxP4(I1,Nv)*DELV(I2) +VtxP4(I2,Nv)*DELV(I1)
2737     C dPi/dI1p (1st vtx)
2738     VMAT(MvF+I1,Lp) =-VtxP4(I2,Nv)
2739     C dPi/dI2p
2740     VMAT(MvF+I2,Lp) = VtxP4(I1,Nv)
2741     C dPi/dI1s (2nd vtx)
2742     VMAT(NvF+I1,Lp) =-VMAT(MvF+I1,Lp)
2743     C dPi/dI2s
2744     VMAT(NvF+I2,Lp) =-VMAT(MvF+I2,Lp)
2745     D IF (PRINT.GT.0) THEN
2746     D WRITE(PRINT,2040) Lp, Nv,Mv, I1,I2, VXI(Lp)
2747     D @, VMAT(MVF+I1,Lp),VMAT(MvF+I2,Lp),VMAT(NvF+I1,Lp),VMAT(NvF+I2,Lp)
2748     D2040 FORMAT(/,' Pnt Lp',I3, 2X,2I2,I4,I3, 1P,E11.3,3X,4E11.3)
2749     D END IF
2750     C Scan over ancestor vertices
2751     DO 40 Kv=NVERTX,Nv,-1
2752     IF (.NOT.VtxVtx(Kv,Nv)) THEN
2753     GO TO 40
2754     END IF
2755     KvF = VOFF(Kv)
2756     C Loop over tracks
2757     DO 20 Nt=1,NTRACK
2758     C check vertex association
2759     IF (.NOT.TrkVtx(Nt,Kv)) GO TO 20
2760     C offset for track Nt
2761     NtF = TOFF(Nt)
2762     IF (Np .EQ. 1) THEN
2763     C (R,Phi) pointing constraint, dP1/dc, dP1/dphi, dP1/dcotg, dP1/dXsv, dP1/dYsv
2764     TEMP(1) = DDA(Nt,1)*DELV(2) - DDA(Nt,5)*DELV(1)
2765     TEMP(2) = DDA(Nt,2)*DELV(2) - DDA(Nt,6)*DELV(1)
2766     TEMP(3) = 0.0
2767     TEMP(4) = DDA(Nt,3)*DELV(2) - DDA(Nt,7)*DELV(1)
2768     TEMP(5) = DDA(Nt,4)*DELV(2) - DDA(Nt,8)*DELV(1)
2769     ELSE
2770     C (R,Z) pointing constraint, dP2/dc, dP2/dphi, dP2/dcotg, dP2/dXsv, dP2/dYsv
2771     C = PAR0(1,Nt) + PARDIF(1,Nt)
2772     TEMP(1) = DDA(Nt,JMAT+1)*DELV(3)
2773     TEMP(1) = TEMP(1) + TrkP4(Nt,3)*DELV(IMAT)/C
2774     TEMP(2) = DDA(Nt,JMAT+2)*DELV(3)
2775     TEMP(3) =-DELV(IMAT)*TrkP4(Nt,5)
2776     TEMP(4) = DDA(Nt,JMAT+3)*DELV(3)
2777     TEMP(5) = DDA(Nt,JMAT+4)*DELV(3)
2778     END IF
2779     VMAT(NtF+1,Lp) = TEMP(1)
2780     VMAT(NtF+2,Lp) = TEMP(2)
2781     VMAT(NtF+3,Lp) = TEMP(3)
2782     VMAT(KvF+1,Lp) = TEMP(4) + VMAT(KvF+1,Lp)
2783     VMAT(KvF+2,Lp) = TEMP(5) + VMAT(KvF+2,Lp)
2784     D IF (PRINT.GT.0) THEN
2785     D WRITE(PRINT,2041) NT,LP, TEMP
2786     D2041 FORMAT(7X,I3,I5,22X,7E11.3)
2787     D END IF
2788     C End track loop
2789     20 CONTINUE
2790     C End ancestor vertex loop
2791     40 CONTINUE
2792     C End pointing constraints loop
2793     50 CONTINUE
2794     C===Return to Caller:
2795     100 CONTINUE
2796     C Symmetrize the derivative matrix
2797     DO I=1,MATDIM-1
2798     DO J=I+1,MATDIM
2799     VMAT(J,I) = VMAT(I,J)
2800     END DO
2801     END DO
2802     RETURN
2803     END
2804     C===============================================================================
2805     SUBROUTINE CTVMMF (PRINT, NM, VXI)
2806     C===============================================================================
2807     C Derivative contributions for the CTVM mass constraint fitting
2808     C--Input parameter
2809     C Nm The mass constraint index
2810     C-------------------------------------------------------------------------------
2811     IMPLICIT NONE
2812     #include "MitCommon/Ctvmft/interface/ctvmdi.h"
2813     #include "MitCommon/Ctvmft/interface/ctvmft.h"
2814     INTEGER PRINT
2815     INTEGER NM
2816     REAL*8 VXI(MAXDIM)
2817     REAL*8 SUM
2818     INTEGER I,J, Nt,Nv, LmF,NvF,NtF
2819     REAL C
2820     C-------------------------------------------------------------------------------
2821     LmF = MOFF + Nm
2822     C Difference in m**2 of tracks and constraint / 2
2823     SUM = SQRT(McnP4(1,Nm)**2 + McnP4(2,Nm)**2 + McnP4(3,Nm)**2)
2824     SUM = (McnP4(4,Nm) + SUM) * (McnP4(4,Nm) - SUM)
2825     SUM = DSQRT(SUM)
2826     VXI(LmF) = 0.5D0 * (CMASS(Nm)+SUM) * (CMASS(Nm)-SUM)
2827     C Loop over tracks contributing to this mass constraint
2828     DO 50 Nv=1,NVERTX
2829     NvF = VOFF(Nv)
2830     DO 40 NT=1,NTRACK
2831     IF (.NOT.TrkVtx(Nt,Nv)) GO TO 40
2832     IF (.NOT.TrkMcn(Nt,Nm)) GO TO 40
2833     C Index into matrix equations for track NT
2834     NtF = TOFF(Nt)
2835     C dM**2/dc, dM**2/dphi, dM**2/dcot(theta)
2836     C = PAR0(1,Nt) + PARDIF(1,Nt)
2837     SUM = -McnP4(4,Nm)*TrkP4(Nt,6)**2/TrkP4(Nt,4)
2838     SUM = (SUM + McnP4(3,Nm)*TrkP4(Nt,3)) / C
2839     SUM = SUM - McnP4(1,Nm)*DDA(Nt,1) - McnP4(2,Nm)*DDA(Nt,5)
2840     VMAT(NtF+1,LmF) = SUM
2841     SUM =-McnP4(1,Nm)*DDA(Nt,2) - McnP4(2,Nm)*DDA(Nt,6)
2842     VMAT(NtF+2,LmF) = SUM
2843     SUM = (McnP4(4,Nm)*TrkP4(Nt,3) / TrkP4(Nt,4)-McnP4(3,Nm))
2844     SUM = TrkP4(Nt,5) * SUM
2845     VMAT(NtF+3,LmF) = SUM
2846     C dM**2/dXsv, dM**2/dYsv
2847     VMAT(NvF+1,LmF) = VMAT(NvF+1,LmF)
2848     & - McnP4(1,Nm)*DDA(Nt,3)-McnP4(2,Nm)*DDA(Nt,7)
2849     VMAT(NvF+2,LmF) = VMAT(NvF+2,LmF)
2850     & - McnP4(1,Nm)*DDA(Nt,4)-McnP4(2,Nm)*DDA(Nt,8)
2851     D IF (PRINT.GT.0) THEN
2852     D WRITE(PRINT,1045) NT, VXI(LmF)
2853     D @, (VMAT(NvF+J,LmF),J=1,2),(VMAT(NtF+J,LmF),J=1,3)
2854     D1045 FORMAT(/,' Mcn, Tk',I3, 1P,E11.3,2X,5E11.3)
2855     D END IF
2856     40 CONTINUE
2857     C Continue loop on tracks
2858     50 CONTINUE
2859     C-------------------------------------------------------------------------------
2860     C===Return to Caller:
2861     C Symmetrize the derivative matrix
2862     DO I=1,MATDIM-1
2863     DO J=I+1,MATDIM
2864     VMAT(J,I) = VMAT(I,J)
2865     END DO
2866     END DO
2867     RETURN
2868     END
2869     C===============================================================================
2870     SUBROUTINE CTVMPR (LSUNIT,DBGPRT, PARERR)
2871     C===============================================================================
2872     C Author: John Marriner, CDF, FNAL (with a little help from his friends)
2873     C print the fit results of CTVMFT
2874     C Input parameters
2875     C LSUNIT = fortran logical unit for write
2876     C DBGPRT = print level
2877     C PARERR Original (input) track parameters
2878     C Preconditions
2879     C CTVMFT must have been called and returned no error
2880     C CTVMPR assumes fit information is stored in common defined by CTVMFT.INC
2881     C-------------------------------------------------------------------------------
2882     IMPLICIT NONE
2883     #include "MitCommon/Ctvmft/interface/ctvmdi.h"
2884     #include "MitCommon/Ctvmft/interface/ctvmft.h"
2885     INTEGER DBGPRT, LSUNIT
2886     REAL PARERR(5,MaxTrk)
2887     INTEGER I,J,K,L,M,N, IFAIL, IM, IN, INDEX(5)
2888     INTEGER Nt,Nv,Mv, Nc,Np,Nm, NtF,NvF, NPAR, NVPAR, NPC
2889     INTEGER NtrVtx(0:Maxvtx), TMcn(MaxTrk)
2890     LOGICAL PRIMARY
2891     REAL CHIP, VALUE,SIGMA, U,V,W, ERRRAT(5), PULL(3)
2892     REAL DXYZ(3), Dr,Dz, Dl(3)
2893     REAL ERR(MAXDIM), WORK(MAXDIM), CORR(MAXDIM,MAXDIM)
2894     REAL*8 P4(4), EPAR(5,5)
2895     INTEGER MRUN,MNEV
2896     INTEGER MTRACK(MaxTrk)
2897     LOGICAL FIRST
2898     CHARACTER*9 VN, VP, VS, VB
2899     SAVE MRUN,MNEV, VP,VS,VB
2900     DATA VP / 'primary ' /, VS / 'secondary' /, VB / ' ' /
2901     DATA MRUN /-1/, MNEV /-1/
2902     C-------------------------------------------------------------------------------
2903     C Write header, chi-squared, # deg of freedom
2904     IF (RunNum.NE.MRUN .OR. TrgNum.NE.MNEV) THEN
2905     WRITE(LSUNIT,1000)
2906     1000 FORMAT('1',123('=') )
2907     MRUN = RunNum
2908     MNEV = TrgNum
2909     END IF
2910     DO I=1,MaxTrk
2911     MTRACK(I) = I
2912     END DO
2913     Nc = 0
2914     Np = 0
2915     PRIMARY =.FALSE.
2916     NtrVtx(0) = 0
2917     DO Nv=1,NVERTX
2918     NtrVtx(Nv) = 0
2919     Do Nt=1,NTRACK
2920     IF (TrkVtx(Nt,Nv)) NtrVtx(Nv) = NtrVtx(Nv)+1
2921     END DO
2922     IF (VtxPnt(Nv,1).EQ.0) PRIMARY =.TRUE.
2923     Nc = Nc + Cvtx(Nv)
2924     IF (VtxPnt(Nv,1).GE.0) THEN
2925     NPC = VtxPnt(Nv,2)
2926     IF (NPC.EQ.3) NPC = 2
2927     IF (NPC.EQ.4) NPC = 2
2928     Np = Np+NPC
2929     END IF
2930     END DO
2931     C make the fit errors and the correlation matrix
2932     NPAR = TOFF(NTRACK)+3
2933     C Loop over fitted parameters
2934     DO I=1,NPAR
2935     C Get error = sqrt(diagonal element)
2936     ERR(I) = DSQRT(VMAT(I,I))
2937     END DO
2938     C Correlation matrix
2939     DO I=1,NPAR
2940     DO J=1,NPAR
2941     CORR(I,J) = VMAT(I,J)/(ERR(I)*ERR(J))
2942     END DO
2943     END DO
2944     I = RunNum
2945     J = TrgNum
2946     CHIP = AMIN1(CHISQR(0),999.0)
2947     CALL MCALC(NTRACK,MTRACK, Value,SIGMA, P4)
2948     VALUE = AMIN1(VALUE,999.999)
2949     SIGMA = AMIN1(SIGMA, 99.999)
2950     WRITE(LSUNIT,1001) I,J,CHIP,NDOF,ITER,NTSCUT
2951     &, NTRACK,NVERTX,Np,Nc,NMASSC,Value,SIGMA
2952     1001 FORMAT
2953     &(1X,123('-'), /,' Event ',I5,'.',I6,'; Ct_VM fit results'
2954     &, 5X,'Chi square =',F7.2,' Ndof',I3,' (Iter',I3,', NtCut',I3,')'
2955     &, 20X,'Mass Sigma'
2956     &, /, 18X,I2,' Tracks,',I2,' Vertices; Constraints (Pointing',I3
2957     &, ', Conversion',I2,', Mass',I2,')',16X,F8.3,F7.3
2958     & )
2959     C write vertex fit Chi-Square results
2960     WRITE(LSUNIT,1010)
2961     1010 FORMAT(' Vertex coordinate fit results' ,/
2962     &, 11X,'Vtx Ntr',5X,'Xv',7X,'Yv',8X,'Zv',7X,'Chisq'
2963     &, 3X,'Np Nc DLr Dlz'
2964     &, 12X,'SumPx SumPy SumPz Sum_E')
2965     L = 1
2966     IF (PRIMARY) L=0
2967     DO Nv=L,NVERTX
2968     IF (Nv.GT.0) THEN
2969     NvF = VOFF(Nv)
2970     END IF
2971     CHIP = AMIN1(CHIV(Nv),999.0)
2972     Dr = 0
2973     Dz = 0
2974     IF (Nv.EQ.0) THEN
2975     NvF = 0
2976     Np =-1
2977     Nc =-1
2978     WRITE(LSUNIT,1015) VP,Nv,NtrVtx(Nv),(XYZVRT(I,Nv),I=1,3),CHIP
2979     WRITE(LSUNIT,1016) (ERR(NvF+I),I=1,3)
2980     ELSE
2981     VN = VS
2982     IF (Nv.GT.1) VN=VB
2983     Mv = VtxPnt(Nv,1)
2984     Nc = Cvtx(Nv)
2985     Np = VtxPnt(Nv,2)
2986     IF (Np.LT.0) Np = 0
2987     IF (NP.EQ.3) NP = 2
2988     IF (NP.EQ.4) NP = 2
2989     IF (Np.LT.1) PCON(Nv,1)=0.0
2990     IF (Np.LT.2) PCON(Nv,2)=0.0
2991     NvF = VOFF(Nv)
2992     IF (Np.LE.0) THEN
2993     WRITE(LSUNIT,1015) VN,Nv,NtrVtx(Nv),(XYZVRT(I,Nv),I=1,3)
2994     &, CHIP, Np,Nc, (VtxP4(I,Nv),I=1,4)
2995     WRITE(LSUNIT,1016) (ERR(NvF+I),I=1,3)
2996     ELSE
2997     CALL DCALC(Nv,Mv, DXYZ, Dr,Dz, Dl)
2998     WRITE(LSUNIT,1017) VN,Nv,Mv,NtrVtx(Nv),(XYZVRT(I,Nv),I=1,3)
2999     &, CHIP, Np,Nc,Dr,Dz,(VtxP4(I,Nv),I=1,4)
3000     WRITE(LSUNIT,1018) (ERR(NvF+I),I=1,3),Dl
3001     END IF
3002     END IF
3003     1015 FORMAT(1X,A9,I3,I5, F11.4,F9.4,F10.4,F9.2
3004     &, I5,I4,20X ,F14.3,3F8.3)
3005     1016 FORMAT(20X,2F9.4,F10.4 , 58X,3F6.3)
3006     1017 FORMAT(1X,A9,I3,',',I1,I3,2X, F9.4,F9.4,F10.4,F9.2
3007     &, I5,I4,F9.4,F10.4,5X,F10.3,3F8.3)
3008     1018 FORMAT(20X,2F9.4,F10.4,15X,2F7.4,F8.4, 20X,3F6.3)
3009     END DO
3010     WRITE(LSUNIT,*)
3011     C Write information on mass constraints
3012     IF (NMASSC.GT.0) THEN
3013     DO Nm=1,NMASSC
3014     L = 0
3015     DO Nt=1,NTRACK
3016     IF (TrkMcn(Nt,Nm)) THEN
3017     L = L+1
3018     TMcn(L) = Nt
3019     END IF
3020     END DO
3021     IF (Nm.EQ.1) THEN
3022     WRITE(LSUNIT,1020) Nm, CMASS(Nm),FMCDIF(Nm),(TMcn(I),I=1,L)
3023     1020 FORMAT(' Mass Constraints; Mcn',I2,' Mass ',F7.4,' Gev/c**2'
3024     &, ' Residual ' ,1P,E9.1,' Mev/c**2 Tracks',10I3)
3025     ELSE
3026     WRITE(LSUNIT,1021) Nm, CMASS(Nm),FMCDIF(Nm),(TMcn(I),I=1,L)
3027     1021 FORMAT(I24, F13.4,17X,1P,E12.1 ,18X ,10I3)
3028     END IF
3029     END DO
3030     WRITE(LSUNIT,*)
3031     END IF
3032     C Now, print the track fit results
3033     WRITE(LSUNIT,1050)
3034     1050 FORMAT(' Track parameter fit results -'
3035     &,/,5X,'Vtx Bank Mass Crv',10X,'Phi',7X,'Ctg',8X,'D0'
3036     &, 7X,'Z0',8X,'Chisq',22X,'ErrFit / ErrMst')
3037     DO 50 Nv=1,Nvertx
3038     WRITE(LSUNIT,*)
3039     DO 49 Nt=1,Ntrack
3040     IF (.NOT.TrkVtx(Nt,Nv)) GO TO 49
3041     NtF = TOFF(Nt)
3042     VALUE = AMIN1(CHIT(Nt),999.0)
3043     DO I=1,3
3044     ERRRAT(I) = ERR(NtF+I) / PARERR(I,Nt)
3045     END DO
3046     WRITE(LSUNIT,1055) Nt,Nv, TKBANK(Nt),LIST(Nt),TMASS(Nt)
3047     &, (PAR(J,Nt),J=1,5), VALUE
3048     WRITE(LSUNIT,1056) (ERR(NtF+J),J=1,3), (ERRRAT(J),J=1,3)
3049     1055 FORMAT(I3,')',I3,3X,A4,I3,F8.4,1P,E12.3,0P,2F10.5,2F10.4,F9.2)
3050     1056 FORMAT(25X,1P,E12.3,0P,2F10.5, 49X, 3F6.3)
3051     IF (DBGPRT.LT.987654) GO TO 49
3052     C Loop over weight matrix
3053     DO I = 1, 5
3054     DO J = 1, 5
3055     EPAR(I,J) = G(I,J,NT)
3056     END DO
3057     END DO
3058     C Invert weight matrix to get error matrix
3059     CALL DINV(5,EPAR,5,WORK,IFAIL)
3060     C Get index into fit error matrix for track NT
3061     C Loop over fitted parameters (first 3 in a track)
3062     DO I = 1, 3
3063     C Get sigma = denominator for pull
3064     SIGMA = EPAR(I,I) - VMAT(NtF+I,NtF+I)
3065     C Allow modest underflow (rounding errors?)
3066     IF (ABS(SIGMA) .LT. 0.001D0*EPAR(I,I)) SIGMA = 0.001D0*EPAR(I,I)
3067     C Test for negative argument
3068     IF (SIGMA .LT. 0.0) GO TO 45
3069     C Pull = (Fitted value - CTC fit)/sigma
3070     PULL(I) = PARDIF(I,NT)/SQRT(SIGMA)
3071     C Continue loop on fitted parameters
3072     END DO
3073     C Write pulls, contribution to chi-squared for this track
3074     WRITE (LSUNIT,1062) (PULL(I),I=1,3)
3075     1062 FORMAT(6X,' Pulls',0P,3F9.4)
3076     GO TO 49
3077     45 CONTINUE
3078     WRITE (LSUNIT,21)
3079     21 FORMAT (3X,' Pulls. Error in calculating pulls.',
3080     & ' Fit is suspect.')
3081     C Continue loop on tracks
3082     49 CONTINUE
3083     50 CONTINUE
3084     C Loop over fitted parameters
3085     60 CONTINUE
3086     IF (DBGPRT.LE.99) GO TO 900
3087     C Write header for error matrix print
3088     WRITE (LSUNIT,1060)
3089     1060 FORMAT(/,' Correlation matrix')
3090     DO I=1,NPAR
3091     WRITE(LSUNIT,1065) (CORR(I,J),J=1,I)
3092     1065 FORMAT( 8(1X,3F5.2) )
3093     IF (MOD(I,3).EQ.0) WRITE(LSUNIT,*)
3094     END DO
3095     C Done. Exit
3096     900 CONTINUE
3097     RETURN
3098     END
3099     C===============================================================================
3100     SUBROUTINE CTVMsv (WHICH, WHERE)
3101     C===============================================================================
3102     C Silly, trivial little routine to save, interchange, or restore the results
3103     C of a CTVMFT fit.
3104     C WHICH < 0 Copy the CTVMFT fit results to local storage for preservation
3105     C = 0 Interchange the stored fit result with that in the CTVMFT common
3106     C > 0 Overwrite the CTVMFT fit result with the stored result
3107     C WHERE An index specifying where to store or where to extract fit
3108     C information.
3109     C-------------------------------------------------------------------------------
3110     IMPLICIT NONE
3111     #include "MitCommon/Ctvmft/interface/ctvmdi.h"
3112     #include "MitCommon/Ctvmft/interface/ctvmft.h"
3113     INTEGER IJKLMN
3114     PARAMETER(IJKLMN = MAXDIM*(MAXDIM+1))
3115     INTEGER WHICH, WHERE
3116     INTEGER I
3117     INTEGER SAVRSL(UDIM,4), SLUSH(UDIM)
3118     REAL*8 UMAT (MAXDIM*(MAXDIM+1),4)
3119     REAL*8 BLUSH(MAXDIM*(MAXDIM+1))
3120     REAL SCREAM, MINUS, ZERO
3121     SAVE SAVRSL, UMAT, MINUS,ZERO
3122     DATA MINUS /-1.0/, ZERO /0.0/
3123     C============ save or restore existing constrained fit results ===============
3124     IF (WHERE.LE.0 .OR. WHERE.GT.4) THEN
3125     PRINT 1000, WHERE
3126     1000 FORMAT (' CTVMsave; nonsense WHERE!' )
3127     SCREAM = SQRT(MINUS) / ZERO
3128     STOP
3129     END IF
3130     IF (WHICH) 10,20,30
3131     C save the existing fit from CTVMFq,r
3132     10 CONTINUE
3133     DO I=1,UDIM
3134     SAVRSL(I,WHERE) = UVWXYZ(I)
3135     END DO
3136     DO I=1,IJKLMN
3137     UMAT(I,WHERE) = VMAT(I,1)
3138     END DO
3139     GO TO 100
3140     C flip the stored fit with that in CTVMFq,r
3141     20 CONTINUE
3142     DO I=1,UDIM
3143     SLUSH (I) = SAVRSL(I,WHERE)
3144     SAVRSL(I,WHERE) = UVWXYZ(I)
3145     UVWXYZ(I) = SLUSH (I)
3146     END DO
3147     DO I=1,IJKLMN
3148     BLUSH(I) = UMAT(I,WHERE)
3149     UMAT (I,WHERE) = VMAT(I,1)
3150     VMAT(I,1) = BLUSH(I)
3151     END DO
3152     GO TO 100
3153     C restore the CTVMFq,r contents
3154     30 CONTINUE
3155     DO I=1,UDIM
3156     UVWXYZ(I) = SAVRSL(I,WHERE)
3157     END DO
3158     DO I=1,IJKLMN
3159     VMAT(I,1) = UMAT(I,WHERE)
3160     END DO
3161     100 CONTINUE
3162     RETURN
3163     END
3164     C======================================================================= =======
3165     SUBROUTINE MCALC (NTRKQ,MTRACK, FMASS,DMASS, P4)
3166     C======================================================================= =======
3167     C
3168     C=======Description
3169     C
3170     C Input parameters:
3171     C Requires the common in the CTVMFT include file to have relevant information
3172     C stored from a CTVMFT entrance.
3173     C NTRKQ = Number of tracks comprising the invariant mass.
3174     C MTRACK(i) selects the track specified in LIST(i) in the CTVMFT call
3175     C Output parameters:
3176     C FMASS = invariant mass of track combination
3177     C DMASS = computed error on the mass (will be returned as negative if
3178     C DMASS**2 was computed to be negative. This should not happen
3179     C if the matrix VMAT is valid)
3180     C=======Author
3181     C John Marriner
3182     C 6 April 1992
3183     C----------------------------------------------------------------------- -------
3184     IMPLICIT NONE
3185     #include "MitCommon/Ctvmft/interface/ctvmdi.h"
3186     #include "MitCommon/Ctvmft/interface/ctvmft.h"
3187     INTEGER NTRKQ
3188     INTEGER MTRACK(MAXTRK)
3189     REAL FMASS, DMASS
3190     INTEGER I,J, IERR, Nv,NvF, Nt,NtF, NDIM, Nvx,NVRTX(MaxVtx)
3191     REAL DMASSQ
3192     REAL*8 SUM,QMASS, P4(4), DM(MAXDIM)
3193     CHARACTER*80 STRING
3194     CHARACTER*6 NAME
3195     DATA NAME /'MCALC '/
3196     C===============================================================================
3197     CALL VZERO(P4,2*4)
3198     CALL VZERO(DM,2*MAXDIM)
3199     FMASS = 0.0
3200     DMASS = 0.0
3201     C complain
3202     IF (NTRKQ.GT.MAXTRK) THEN
3203     IERR = 91
3204     WRITE(STRING,901) NAME,IERR,NTRKQ
3205     901 FORMAT(A6,I3,'; ',I2,' is too many tracks')
3206     CALL ERROR('MCALC ',IERR,STRING)
3207     FMASS =-1.0
3208     GO TO 100
3209     END IF
3210     DO J=1,NTRKQ
3211     Nt = MTRACK(J)
3212     C energy
3213     TrkP4(NT,4) = SQRT(TrkP4(NT,6)**2+TMASS(NT)**2)
3214     DO I=1,4
3215     P4(I) = P4(I) + TrkP4(Nt,I)
3216     END DO
3217     END DO
3218     NDIM = 0
3219     Nvx = 0
3220     CALL VZERO(NVRTX,MAXVTX)
3221     DMASSQ = 0.0
3222     C Loop over tracks in the fit, find dM
3223     DO 10 J=1,NTRKQ
3224     Nt = MTRACK(J)
3225     NtF = TOFF(Nt)
3226     C find the vertex for this track
3227     Nv = 1
3228     DMASSQ = DMASSQ + TMASS(Nt)
3229     DO WHILE (.NOT.TrkVtx(Nt,Nv))
3230     Nv = Nv+1
3231     END DO
3232     C count number of vertices involved
3233     IF (NVRTX(Nv).EQ.0) THEN
3234     Nvx = Nvx+1
3235     NVRTX(Nv) = Nv
3236     END IF
3237     NvF = VOFF(Nv)
3238     C maximum matrix dimension in VMAT
3239     NDIM = MAX0(NDIM,NtF+3)
3240     C first,dM**2/dXsv and dM**2/dYsv, treat the displacement to this vertex
3241     DM(NvF+1) = DM(NvF+1)-2.0*(P4(1)*DDA(Nt,3)+P4(2)*DDA(Nt,7))
3242     DM(NvF+2) = DM(NvF+2)-2.0*(P4(1)*DDA(Nt,4)+P4(2)*DDA(Nt,8))
3243     C then, dM**2/dc, dM**2/dphi, dM**2/dcot(theta), helix parameters for this track
3244     SUM = -P4(4)*TrkP4(Nt,6)**2/TrkP4(Nt,4) + P4(3)*TrkP4(Nt,3)
3245     SUM = SUM/PAR(1,Nt) - (P4(1)*DDA(Nt,1) + P4(2)*DDA(Nt,5))
3246     DM(NtF+1) = 2.0*SUM
3247     DM(NtF+2) =-2.0*(P4(1)*DDA(Nt,2) + P4(2)*DDA(Nt,6))
3248     SUM = (P4(4)*TrkP4(Nt,3)/TrkP4(Nt,4) - P4(3)) * TrkP4(Nt,5)
3249     DM(NtF+3) = 2.0*SUM
3250     10 CONTINUE
3251     C mass, mass**2
3252     QMASS = DSQRT(P4(1)**2+P4(2)**2+P4(3)**2)
3253     IF (P4(4).LE.QMASS) THEN
3254     IF (Nvx.EQ.1 .AND. Cvtx(Nv).GT.0) THEN
3255     QMASS = DMASSQ
3256     ELSE
3257     C ? crunch
3258     C 10/23/02 Change next line by adding minus signs so that code
3259     C does not bomb is energy is less than momentum due to roundoff error.
3260     C Craig Blocker
3261     QMASS = -DSQRT(-(P4(4)+QMASS)*(P4(4)-QMASS))
3262     END IF
3263     ELSE
3264     QMASS = DSQRT((P4(4)+QMASS)*(P4(4)-QMASS))
3265     END IF
3266     FMASS = QMASS
3267     C Set error in mass squared = 0 for summing
3268     DMASSQ = 0.0
3269     DO I=1,NDIM
3270     DO J=1,NDIM
3271     DMASSQ = DMASSQ + DM(I)*VMAT(J,I)*DM(J)
3272     END DO
3273     END DO
3274     C check for, and flag, negative error**2
3275     IF (DMASSQ.GE.0.) THEN
3276     DMASS = SQRT(DMASSQ)
3277     ELSE
3278     DMASS = -SQRT(-DMASSQ)
3279     ENDIF
3280     IF (QMASS.EQ.0.0) THEN
3281     FMASS = -0.001
3282     ELSE
3283     DMASS = DMASS/(2.*QMASS)
3284     END IF
3285     100 CONTINUE
3286     RETURN
3287     END
3288     C======================================================================= =======
3289     SUBROUTINE EMASSQ (NTRKQ,QMASS, PXYZE,IERR)
3290     C======================================================================= =======
3291     C EMASSQ calculates M**2, sigma(M**2), via a call th MCALC
3292     C This is furnished as a convenience for people who have calls to this
3293     C obsolescent routine. Note the more restrictive set of track pointers
3294     C as compared with MCALC.
3295     C----------------------------------------------------------------------- -------
3296     IMPLICIT NONE
3297     #include "MitCommon/Ctvmft/interface/ctvmdi.h"
3298     #include "MitCommon/Ctvmft/interface/ctvmft.h"
3299     INTEGER NTRKQ, IERR
3300     REAL QMASS(MAXTRK), PXYZE(6)
3301     INTEGER I,N, MTRACK(MAXTRK)
3302     REAL FMASS, DMASS
3303     REAL*8 P4(4)
3304     C----------------------------------------------------------------------- -------
3305     IERR = 0
3306     CALL VZERO(P4, 2*4)
3307     CALL VZERO(PXYZE,6)
3308     N = MIN0(MaxTrk,NTRKQ)
3309     DO I=1,N
3310     MTRACK(I) = I
3311     TMASS(I) = QMASS(I)
3312     END DO
3313     CALL MCALC (NTRKQ,MTRACK,FMASS,DMASS, P4)
3314     IF (FMASS.LT.0.0) THEN
3315     IERR = FMASS
3316     GO TO 900
3317     END IF
3318     DO I=1,4
3319     PXYZE(I) = P4(I)
3320     END DO
3321     PXYZE(5) = FMASS**2
3322     PXYZE(6) = 2.0 * FMASS * DMASS
3323     900 CONTINUE
3324     RETURN
3325     END
3326     C===============================================================================
3327     SUBROUTINE DCALC (Nv,Mv, DXYZ, Dr,Dz, Dl)
3328     C===============================================================================
3329     C Auxialliary subroutine for use with CTVMFT.
3330     C Calculates the distance between the two vertices Nv, Mv and its error.
3331     C Mostly useful only if Nv "points at" Mv.
3332     C Input parameters: Nv, Mv The vertex indices.
3333     C The rest of the Input data comes from the common block /CTVMFT/
3334     C which must contain a valid fit
3335     C Output parameters:
3336     C DXYZ = (unrotated) x, y, and z components of vertex displacement
3337     C Dr = (signed) radial vertex separation (dot product of Dxy * VtxPxy)
3338     C Dz = (signed) vertex separation (dot product of Dz * VtxPz)
3339     C Dl = uncertainty of the three-vector (Dr,Dphi,Dz) (note Dphi~0)
3340     C-------------------------------------------------------------------------------
3341     IMPLICIT NONE
3342     #include "MitCommon/Ctvmft/interface/ctvmdi.h"
3343     #include "MitCommon/Ctvmft/interface/ctvmft.h"
3344     INTEGER Nv,Mv
3345     REAL Dxyz(3), Dr,Dz, Dl(3), FL(3), U
3346     INTEGER I,J,K, IERR, NvF,MvF
3347     REAL*8 S, ROT(3,3), E(3,3),F(3,3)
3348     CHARACTER*80 STRING
3349     C-------------------------------------------------------------------------------
3350     C Setup vertex offset pointers, check for primary
3351     IF (Nv.LT. 1 .OR. Nv.GT.NVERTX) THEN
3352     IERR = 99
3353     WRITE(STRING,900) Nv
3354     900 FORMAT(' Vertex Nv',I3,' is invalid')
3355     CALL ERROR ('DCALC ',IERR,STRING)
3356     ccc STOP
3357     ELSE IF (Mv.LT.0 .OR. Mv.GE.Nv) THEN
3358     IERR = 98
3359     WRITE(STRING,901) Mv
3360     901 FORMAT(' Vertex Mv',I3,' is invalid')
3361     CALL ERROR ('DCALC ',IERR,STRING)
3362     ccc STOP
3363     END IF
3364     DO I=1,9
3365     ROT(I,1) = 0.0D0
3366     END DO
3367     C Pointers to information in VMAT for the two vertices
3368     NvF = VOFF(Nv)
3369     IF (Mv.GT.0) THEN
3370     MvF = VOFF(Mv)
3371     ELSE
3372     MvF =-1
3373     DO I=1,NVERTX
3374     C the primary participated in this fit
3375     IF (VtxPnt(I,1).EQ.0) THEN
3376     MvF = 0
3377     END IF
3378     END DO
3379     END IF
3380     C covariance matrix on vertex separation
3381     DO I=1,3
3382     DO J=I,3
3383     E(I,J) = VMAT(NvF+I,NvF+J)
3384     IF (MvF.GE.0) THEN
3385     E(I,J) = E(I,J) + VMAT(MvF+I,MvF+J)
3386     E(I,J) = E(I,J) - VMAT(NvF+J,MvF+I) * 2.0D0
3387     ELSE
3388     E(I,J) = E(I,J) + EXYZPV(I,J)
3389     END IF
3390     E(J,I) = E(I,J)
3391     END DO
3392     END DO
3393     C vertex separation vector
3394     IF (MvF.GE.0) THEN
3395     DO I=1,3
3396     DXYZ(I) = XYZVRT(I,Nv) - XYZVRT(I,Mv)
3397     END DO
3398     ELSE
3399     DO I=1,3
3400     DXYZ(I) = XYZVRT(I,Nv) - XYZPV0(I)
3401     END DO
3402     END IF
3403     S = SQRT(DXYZ(1)**2 + DXYZ(2)**2)
3404     c If the two vertices have exactly the same x and y, then S is
3405     c zero and we need to protect against dividing by S. C. Blocker 11/20/03
3406     c if(s.le.0.) then
3407     IF (ABS(S).LE.1E-42) THEN
3408     dr = 0.
3409     dz = 0.
3410     dl(1) = -999.
3411     dl(2) = -999.
3412     dl(3) = -999.
3413     return
3414     endif
3415     ROT(1,1) = DXYZ(1)/S
3416     ROT(1,2) = DXYZ(2)/S
3417     ROT(2,1) =-ROT(1,2)
3418     ROT(2,2) = ROT(1,1)
3419     ROT(3,3) = 1.0D0
3420     do i=1,2
3421     s = 0.0D0
3422     do j=1,2
3423     s = s + rot(i,j)*DXYZ(J)
3424     end do
3425     fl(i) = s
3426     end do
3427     C pre and post multiply xy part
3428     DO I=1,2
3429     DO J=1,2
3430     S = 0.0D0
3431     DO K=1,2
3432     S = S + ROT(I,K) * E(K,J)
3433     END DO
3434     F(I,J) = S
3435     END DO
3436     END DO
3437     DO I=1,2
3438     DO J=1,2
3439     S = 0.0D0
3440     DO K=1,2
3441     S = S + F(I,K) * ROT(J,K)
3442     END DO
3443     E(I,J) = S
3444     END DO
3445     END DO
3446     U = DXYZ(1)*VtxP4(1,Nv) + DXYZ(2)*VtxP4(2,Nv)
3447     C (signed) xy vertex separation
3448     Dr = SIGN(SQRT(DXYZ(1)**2+DXYZ(2)**2),U)
3449     U = DXYZ(3)*VtxP4(3,Nv)
3450     C (signed) z vertex separation
3451     Dz = SIGN(ABS(DXYZ(3)),U)
3452     DO I=1,3
3453     IF (E(I,I).GT.0.0) THEN
3454     Dl(I) = SQRT(E(I,I))
3455     ELSE
3456     Dl(I) = 0.0
3457     END IF
3458     END DO
3459     RETURN
3460     END