001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064 #ifndef VERTEXFIT_CC
065 #define VERTEXFIT_CC
066
067
068
069
070 #include "VertexAlg/VertexFit.hh"
071
072 extern "C" void ctvmft_(int&,int&,int&);
073 extern "C" float prob_(float&,int&);
074 extern "C" bool mcalc_(int&,int*,float&,float&,double*);
075 extern "C" void dcalc_(int&,int&,float*,float&,float&,float*);
076
077
078
079 #if defined(DEFECT_OLD_IOSTREAM_HEADERS)
080 #include <iostream>
081 #else
082 #include <iostream>
083 #endif
084
085 #if defined(DEFECT_NO_STDLIB_NAMESPACES)
086
087 #else
088 using std::cerr ;
089 using std::cout ;
090 using std::endl ;
091 #endif
092
093 #include <algorithm>
094 #include <math.h>
095
096
097
098
099 #include "TrackingObjects/Tracks/CdfTrack.hh"
100 #include "CLHEP/Matrix/Matrix.h"
101 #include "TrackingUserHL/Utility/TrackExtrapolator.hh"
102
103
104 #include <csignal>
105 #include <csetjmp>
106
107
108
109
110
111
112
113
114
115 jmp_buf env;
116 extern "C" void VertexFitSetStatus(int i) {
117 std::cout << "Warning, you are handling a severe error in VertexFit" << std::endl;
118 longjmp(env,-66);
119 }
120
121 VertexFit::VertexFit() :
122 _currentAllocatedVertexNumber(0),
123 _referencePoint( 0,0,0 ),
124 _primaryVertex( 0,0,0 ),
125 _cdfPrimaryVertex( 0,0,0 )
126 {
127
128 _expert="Craig Blocker (blocker@fnal.gov)";
129
130 _ctvmq_com = (CTVMQ*) ctvmq_address_();
131 _ctvmfr_com = (CTVMFR*) ctvmfr_address_();
132 _fiddle_com = (FIDDLE*) fiddle_address_();
133 _trkprm_com = (TRKPRM*) trkprm_address_();
134
135 init();
136
137 _fiddle.excuse=1;
138
139 _extrapolateTrackErrors = false;
140 }
141
142
143
144
145
146
147 VertexFit::~VertexFit(){ }
148
149
150
151
152 const float VertexFit::EL_MASS = 0.000510998902;
153 const float VertexFit::MU_MASS = 0.105658357;
154 const float VertexFit::PI_MASS = 0.13957018;
155 const float VertexFit::K_MASS = 0.493677;
156 const float VertexFit::PROTON_MASS = 0.938272;
157
158
159
160
161
162 void VertexFit::init()
163 {
164 double bmag = 1.4116;
165 init(bmag);
166 }
167
168 void VertexFit::init(double bmag)
169 {
170
171
172 _ctvmq.runnum=1;
173 _ctvmq.trgnum=100;
174
175
176
177
178 _ctvmq.pscale=0.00149896*bmag;
179
180 _fiddle.chisqmax = 225.;
181
182
183 setPrimaryVertex(0.,0.,0.);
184 float xverr[3][3];
185 for(int j = 0; j<3; j++) {
186 for(int k = 0; k<3; k++) {
187 xverr[j][k] = 0.;
188 }
189 }
190 xverr[0][0]=.005;
191 xverr[1][1]=.005;
192 xverr[2][2]=1.;
193 setPrimaryVertexError(xverr);
194
195 _ctvmq.ntrack=0;
196 _ctvmq.nvertx=0;
197 _ctvmq.nmassc=0;
198
199
200 for(int j=0; j<_maxtrk; ++j) {
201 _ctvmq.list[j]=0;
202 for(int jv=0; jv<_maxvtx; ++jv) {
203 _ctvmq.trkvtx[jv][j]=false;
204 }
205 for(int jmc=0; jmc<_maxmcn; ++jmc) {
206 _ctvmq.trkmcn[jmc][j]=false;
207 }
208 }
209
210 for(int jv=0; jv<_maxvtx; ++jv) {
211 _ctvmq.cvtx[jv]=0;
212 _ctvmq.vtxpnt[0][jv]=-1;
213 _ctvmq.vtxpnt[1][jv]=0;
214 }
215 _ctvmq.drmax=2.;
216 _ctvmq.dzmax=20.;
217 _ctvmq.rvmax=70.;
218 _ctvmq.trnmax=0.5;
219 _ctvmq.dsmin=-2.;
220
221 stat=-999;
222 _ctvmq.chisqr[0]=-1.;
223
224 _primaryVertex = Hep3Vector(0,0,0);
225 _cdfPrimaryVertex = Hep3Vector(0,0,0);
226 _referencePoint = Hep3Vector(0,0,0);
227 }
228
229
230
231
232
233 bool VertexFit::addTrack(const CdfTrack* trk, float mass,
234 vertexNumber jv)
235 {
236
237 if(jv<VERTEX_1 || jv>_maxvtx) return false;
238 _ctvmq.nvertx = jv>_ctvmq.nvertx ? jv : _ctvmq.nvertx;
239
240
241 if(_ctvmq.ntrack>=_maxtrk) return false;
242
243
244
245 HepVector w = trk->par();
246 HepSymMatrix m = trk->getHelixFit().getErrorMatrix();
247 if ( _extrapolateTrackErrors ) {
248
249 moveReferencePoint( w, m );
250 }
251
252
253 _ctvmq.list[_ctvmq.ntrack]=trk->id().value();
254 _ctvmq.tkbank[_ctvmq.ntrack][0]='Q';
255 _ctvmq.tkbank[_ctvmq.ntrack][1]='T';
256 _ctvmq.tkbank[_ctvmq.ntrack][2]='R';
257 _ctvmq.tkbank[_ctvmq.ntrack][3]='K';
258 _ctvmq.tmass[_ctvmq.ntrack]=mass;
259 _ctvmq.trkvtx[jv-1][_ctvmq.ntrack]=true;
260
261
262
263
264 _trkprm.trhelix[_ctvmq.ntrack][0]=w[0];
265 _trkprm.trhelix[_ctvmq.ntrack][1]=w[1];
266 _trkprm.trhelix[_ctvmq.ntrack][2]=w[2];
267 _trkprm.trhelix[_ctvmq.ntrack][3]=w[3];
268 _trkprm.trhelix[_ctvmq.ntrack][4]=w[4];
269
270 for(int j=0; j<5; ++j) {
271 for(int k=0; k<5; ++k) {
272 _trkprm.trem[_ctvmq.ntrack][j][k]=m[j][k];
273 }
274 }
275 _ctvmq.ntrack++;
276
277 return true;
278 }
279
280
281
282
283
284
285
286
287
288
289 bool VertexFit::addTrack( const HepVector & v,
290 const HepSymMatrix & cov,
291 int trackId,
292 float mass,
293 vertexNumber jv)
294 {
295
296 if(jv<VERTEX_1 || jv>_maxvtx) return false;
297 _ctvmq.nvertx = jv>_ctvmq.nvertx ? jv : _ctvmq.nvertx;
298
299
300
301 HepVector w = v;
302 HepSymMatrix m = cov;
303 if ( _extrapolateTrackErrors ) {
304
305 moveReferencePoint( w, m );
306 }
307
308
309 if(_ctvmq.ntrack>=_maxtrk) return false;
310
311
312 _ctvmq.list[_ctvmq.ntrack]=trackId;
313 _ctvmq.tkbank[_ctvmq.ntrack][0]='Q';
314 _ctvmq.tkbank[_ctvmq.ntrack][1]='T';
315 _ctvmq.tkbank[_ctvmq.ntrack][2]='R';
316 _ctvmq.tkbank[_ctvmq.ntrack][3]='K';
317 _ctvmq.tmass[_ctvmq.ntrack]=mass;
318 _ctvmq.trkvtx[jv-1][_ctvmq.ntrack]=true;
319
320
321
322
323 _trkprm.trhelix[_ctvmq.ntrack][0]=w[0];
324 _trkprm.trhelix[_ctvmq.ntrack][1]=w[1];
325 _trkprm.trhelix[_ctvmq.ntrack][2]=w[2];
326 _trkprm.trhelix[_ctvmq.ntrack][3]=w[3];
327 _trkprm.trhelix[_ctvmq.ntrack][4]=w[4];
328
329 for(int j=0; j<5; ++j) {
330 for(int k=0; k<5; ++k) {
331 _trkprm.trem[_ctvmq.ntrack][j][k]=m[j][k];
332
333 }
334 }
335 _ctvmq.ntrack++;
336
337 return true;
338 }
339
340
341
342
343
344 bool VertexFit::vertexPoint_2d(vertexNumber jv1, vertexNumber jv2)
345 {
346
347
348 if(jv1>_maxvtx || jv1<VERTEX_1) return false;
349 if(jv2>_maxvtx || jv2<PRIMARY_VERTEX) return false;
350 if(jv1 <= jv2) return false;
351
352
353 _ctvmq.vtxpnt[0][jv1-1]=jv2;
354 _ctvmq.vtxpnt[1][jv1-1]=1;
355
356 return true;
357 }
358
359
360
361
362
363 bool VertexFit::vertexPoint_3d(vertexNumber jv1, vertexNumber jv2)
364 {
365
366
367 if(jv1>_maxvtx || jv1<VERTEX_1) return false;
368 if(jv2>_maxvtx || jv2<PRIMARY_VERTEX) return false;
369 if(jv1 <= jv2) return false;
370
371 _ctvmq.vtxpnt[0][jv1-1]=jv2;
372 _ctvmq.vtxpnt[1][jv1-1]=2;
373
374 return true;
375 }
376
377
378
379
380
381 bool VertexFit::vertexPoint_1track(vertexNumber jv1, vertexNumber jv2)
382 {
383
384 if(jv1>_maxvtx || jv1<VERTEX_1) return false;
385 if(jv2>_maxvtx || jv2<PRIMARY_VERTEX) return false;
386 if(jv1 <= jv2) return false;
387
388
389 _ctvmq.vtxpnt[0][jv1-1]=jv2;
390 _ctvmq.vtxpnt[1][jv1-1]=3;
391
392 return true;
393 }
394
395
396
397
398 bool VertexFit::vertexPoint_0track(vertexNumber jv1, vertexNumber jv2)
399 {
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414 if(jv1>_maxvtx || jv1<VERTEX_1) return false;
415 if(jv2>_maxvtx || jv2<PRIMARY_VERTEX) return false;
416 if(jv1 <= jv2) return false;
417
418
419 _ctvmq.vtxpnt[0][jv1-1]=jv2;
420 _ctvmq.vtxpnt[1][jv1-1]=4;
421
422 return true;
423 }
424
425
426
427
428
429 bool VertexFit::conversion_2d(vertexNumber jv)
430 {
431 if(jv<VERTEX_1 || jv>_ctvmq.nvertx) {
432 return false;
433 }
434 _ctvmq.cvtx[jv-1]=1;
435 return true;
436 }
437
438
439
440
441
442 bool VertexFit::conversion_3d(vertexNumber jv)
443 {
444 if(jv<VERTEX_1 || jv>_ctvmq.nvertx) {
445 return false;
446 }
447 _ctvmq.cvtx[jv-1]=2;
448 return true;
449 }
450
451
452
453
454
455 bool VertexFit::massConstrain(const CdfTrack* trk1,
456 const CdfTrack* trk2, float mass)
457 {
458 int ntrk=2;
459 const CdfTrack* tracks[2];
460 tracks[0]=trk1;
461 tracks[1]=trk2;
462 return massConstrain(ntrk,tracks,mass);
463 }
464
465 bool VertexFit::massConstrain(const CdfTrack* trk1, const CdfTrack* trk2,
466 const CdfTrack* trk3, float mass)
467 {
468 int ntrk=3;
469 const CdfTrack* tracks[3];
470 tracks[0]=trk1;
471 tracks[1]=trk2;
472 tracks[2]=trk3;
473 return massConstrain(ntrk,tracks,mass);
474 }
475
476 bool VertexFit::massConstrain(const CdfTrack* trk1, const CdfTrack* trk2,
477 const CdfTrack* trk3, const CdfTrack* trk4,float mass)
478 {
479 int ntrk=4;
480 const CdfTrack* tracks[4];
481 tracks[0]=trk1;
482 tracks[1]=trk2;
483 tracks[2]=trk3;
484 tracks[3]=trk4;
485 return massConstrain(ntrk,tracks,mass);
486 }
487
488 bool VertexFit::massConstrain(int ntrk, const CdfTrack* tracks[], float mass)
489 {
490
491 if(_ctvmq.nmassc>=_maxmcn) return false;
492
493
494 _ctvmq.cmass[_ctvmq.nmassc]=mass;
495
496
497
498
499 for(int jt=0; jt<ntrk; ++jt) {
500 bool found=false;
501 for(int kt=0; kt<_ctvmq.ntrack; ++kt) {
502 if(tracks[jt]->id().value()==_ctvmq.list[kt]) {
503 _ctvmq.trkmcn[_ctvmq.nmassc][kt]=true;
504 found=true;
505 }
506 }
507 if(!found) return false;
508 }
509
510 _ctvmq.nmassc++;
511
512 return true;
513 }
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544 bool VertexFit::beamlineConstraint(float xb, float yb, HepSymMatrix berr,
545 float xzbslope, float yzbslope)
546 {
547
548 setPrimaryVertex(xb,yb,0);
549 if (_extrapolateTrackErrors) {
550 float newXb = xb - _referencePoint.x() +
551 _referencePoint.z() * xzbslope;
552 float newYb = yb - _referencePoint.y() +
553 _referencePoint.z() * yzbslope;
554 setPrimaryVertex( newXb, newYb, 0);
555 }
556
557 bool success = setPrimaryVertexError(berr);
558
559 _ctvmq.xzslope= xzbslope;
560 _ctvmq.yzslope= yzbslope;
561
562 _ctvmq.vtxpnt[0][0]=-100;
563
564 return success;
565 }
566
567 bool VertexFit::beamlineConstraint(Hep3Vector pv, HepSymMatrix berr,
568 float xzbslope, float yzbslope)
569 {
570
571 if (pv.z() != 0) return false;
572
573 return beamlineConstraint(pv.x(),pv.y(),berr,xzbslope,yzbslope);
574 }
575
576
577
578
579
580 void VertexFit::setPrimaryVertex(float xv, float yv, float zv)
581 {
582
583 _ctvmq.xyzpv0[0]=xv;
584 _ctvmq.xyzpv0[1]=yv;
585 _ctvmq.xyzpv0[2]=zv;
586
587 _primaryVertex = Hep3Vector( xv, yv, zv );
588 return;
589 }
590
591 void VertexFit::setPrimaryVertex(Hep3Vector pv)
592 {
593
594 _ctvmq.xyzpv0[0]=pv.x();
595 _ctvmq.xyzpv0[1]=pv.y();
596 _ctvmq.xyzpv0[2]=pv.z();
597
598 _primaryVertex = pv;
599 return;
600 }
601
602
603
604
605
606 void VertexFit::setPrimaryVertexError(const float xverr[3][3])
607 {
608
609 for(int j=0; j<3; ++j) {
610 for(int k=0; k<3; ++k) {
611 _ctvmq.exyzpv[j][k]=xverr[j][k];
612 }
613 }
614 return;
615 }
616
617 bool VertexFit::setPrimaryVertexError(const HepSymMatrix &xverr)
618 {
619
620
621 if(xverr.num_row() != 3) return false;
622 for(int j=0; j<3; j++) {
623 for(int k=0; k<3; k++) {
624 _ctvmq.exyzpv[j][k]=xverr[j][k];
625 }
626 }
627 return true;
628 }
629
630
631
632
633
634 bool VertexFit::fit()
635 {
636
637
638 bool mstat = true;
639 for(int trk=0; trk<_ctvmq.ntrack; ++trk) {
640 for(int j=0; j<5; ++j) {
641
642 if(_trkprm.trem[trk][j][j] < 0.) {
643
644
645 mstat = false;
646 _ctvmq.ijkerr[0] = 3;
647 _ctvmq.ijkerr[1] = 2;
648 _ctvmq.ijkerr[2] = trk + 1;
649 }
650 }
651
652
653
654 if(fabs(_trkprm.trhelix[trk][1]) > 0.01) {
655 mstat = false;
656 _ctvmq.ijkerr[0] = 3;
657 _ctvmq.ijkerr[1] = 5;
658 _ctvmq.ijkerr[2] = trk + 1;
659 }
660 }
661
662 if(!mstat) {
663 stat = 1;
664 return false;
665 }
666
667
668 *_ctvmq_com=_ctvmq;
669 *_ctvmfr_com=_ctvmfr;
670 *_fiddle_com=_fiddle;
671 *_trkprm_com=_trkprm;
672
673 int print=0;
674 int level=0;
675
676 #if ( defined(LINUX) && defined(__USE_BSD) ) || defined(OSF1)
677 struct sigaction myaction = {VertexFitSetStatus, 0, 0, 0}, oldaction;
678 sigaction(SIGFPE, &myaction, &oldaction);
679 if (setjmp(env)!=0) {
680 sigaction(SIGFPE, &oldaction,0);
681 return -999;
682 }
683 #endif
684
685 ctvmft_(print,level,stat);
686
687 #if ( defined(LINUX) && defined(__USE_BSD) ) || defined(OSF1)
688 sigaction(SIGFPE, &oldaction,0);
689 #endif
690
691
692 _ctvmq=*_ctvmq_com;
693 _ctvmfr=*_ctvmfr_com;
694 _fiddle=*_fiddle_com;
695 _trkprm=*_trkprm_com;
696
697 return stat==0;
698 }
699
700
701
702
703
704 void VertexFit::print() const
705 {
706 print(std::cout);
707 }
708
709 void VertexFit::print(std::ostream& os) const
710 {
711 os << "****************************** VertexFit "
712 << "******************************" << std::endl;
713 os << "Number of tracks: " << _ctvmq.ntrack << std::endl;
714 os << " Tracks: ";
715 for(int jt=0; jt<_ctvmq.ntrack; ++jt) {
716 if(jt != 0) os << ", ";
717 CdfTrack::Id trkId(_ctvmq.list[jt]);
718 os << trkId;
719 }
720 os << std::endl;
721 os << "Number of vertices: " << _ctvmq.nvertx << std::endl;
722 for(int jv=0; jv<_ctvmq.nvertx; ++jv) {
723 os << " Vertex " << jv+1 << " tracks: ";
724 for(int jt=0; jt<_ctvmq.ntrack; ++jt) {
725 if(_ctvmq.trkvtx[jv][jt]) {
726 os << " " << _ctvmq.list[jt];
727 }
728 }
729 os << std::endl;
730 }
731 for(int jv=0; jv<_ctvmq.nvertx; ++jv) {
732 if(_ctvmq.vtxpnt[0][jv]==0) {
733 os << " Vertex " << jv+1 << " points to the primary vertex ";
734 }
735 else if(_ctvmq.vtxpnt[0][jv]>0) {
736 os << " Vertex " << jv+1 << " points to vertex "
737 << _ctvmq.vtxpnt[0][jv];
738 }
739 if(_ctvmq.vtxpnt[1][jv]==1) {
740 os << " in 2 dimensions" << std::endl;
741 }
742 else if(_ctvmq.vtxpnt[1][jv]==2) {
743 os << " in 3 dimensions" << std::endl;
744 }
745 else if(_ctvmq.vtxpnt[1][jv]==3) {
746 os << ", a single track vertex" << std::endl;
747 }
748 if(_ctvmq.cvtx[jv]>0) {
749 os << " Vertex " << jv+1 << " is a conversion" << std::endl;
750 }
751 }
752 os << "Number of mass constraints: " << _ctvmq.nmassc << std::endl;
753 for(int jmc=0; jmc<_ctvmq.nmassc; ++jmc) {
754 os << " Tracks ";
755 for(int jt=0; jt<_ctvmq.ntrack; ++jt) {
756 if(_ctvmq.trkmcn[jmc][jt]) {
757 os << " " << _ctvmq.list[jt];
758 }
759 }
760 os << " constrained to mass " << _ctvmq.cmass[jmc]
761 << " Gev/c^2" << std::endl;
762 }
763 if(stat==-999) {
764 os << "No fit has been done." << std::endl;
765 }
766 else {
767 os << "***** Results of Fit *****" << std::endl;
768 printErr(os);
769 os << " Status = " << stat << std::endl;
770 os << " Chi-square = " << _ctvmq.chisqr[0]
771 << " for " << _ctvmq.ndof << " degrees of freedom." << std::endl;
772 os << " => probability = " << prob() << std::endl;
773 for(int jv=0; jv<_ctvmq.nvertx; ++jv) {
774 os << "Vertex " << jv+1 << " position: "
775 << _ctvmq.xyzvrt[jv+1][0] << " "
776 << _ctvmq.xyzvrt[jv+1][1] << " "
777 << _ctvmq.xyzvrt[jv+1][2] << std::endl;
778 }
779 for(int jt=0; jt<_ctvmq.ntrack; ++jt) {
780 os << "Track " << _ctvmq.list[jt] << " P4: "
781 << _ctvmq.trkp4[0][jt] << " "
782 << _ctvmq.trkp4[1][jt] << " "
783 << _ctvmq.trkp4[2][jt] << " "
784 << _ctvmq.trkp4[3][jt] << " " << std::endl;
785 }
786 }
787 os << "****************************************"
788 << "**************************" << std::endl;
789
790 return;
791 }
792
793
794
795
796
797 void VertexFit::printErr() const
798 {
799 printErr(std::cout);
800 }
801
802 void VertexFit::printErr(std::ostream& os) const
803 {
804 os << "VertexFit: IJKERR = " << _ctvmq.ijkerr[0] << ", "
805 << _ctvmq.ijkerr[1] << ", "
806 << _ctvmq.ijkerr[2] << std::endl;
807 if(status()==0 && _ctvmq.ijkerr[0]==0) return;
808 if(_ctvmq.ijkerr[0] == -1) {
809 os << " Problem with GETTRK: track requested is not in list."
810 << std::endl
811 << " This should not happen - Contact VertexFit expert "
812 << _expert << "." <<std::endl;
813 }
814 else if(_ctvmq.ijkerr[0]==1) {
815 os << " Problem in CTVM00:" << std::endl;
816 if(_ctvmq.ijkerr[1]==1) {
817 os << " Number of tracks is " << _ctvmq.ntrack
818 << "." << std::endl;
819 if(_ctvmq.ntrack < 2) {
820 os << ", which is too few (must be at least 2)." << std::endl;
821 }
822 else if(_ctvmq.ntrack > _maxtrk) {
823 os << ", which is too many (maximum is " << _maxtrk
824 << ")." << std::endl;
825 }
826 else {
827 os << " Problem with number of tracks"
828 << " for unknown reasons." << std::endl;
829 }
830 }
831 else if(_ctvmq.ijkerr[1]==2) {
832 os << " Number of vertices is " << _ctvmq.nvertx
833 << "." << std::endl;
834 if(_ctvmq.nvertx < 1) {
835 os << ", which is too few (must be at least 1)." << std::endl;
836 }
837 else if(_ctvmq.nvertx > _maxvtx) {
838 os << ", which is too many (maximum is " << _maxvtx
839 << ")." << std::endl;
840 }
841 else {
842 os << std::endl << " Problem with number of vertices"
843 << " for unknown reasons." << std::endl;
844 }
845 }
846 else if(_ctvmq.ijkerr[1]==3) {
847 os << " Number of mass constraints is " << _ctvmq.nmassc
848 << "." << std::endl;
849 if(_ctvmq.nmassc < 0) {
850 os << ", which is negative." << std::endl;
851 }
852 else if(_ctvmq.nmassc > _maxmcn) {
853 os << ", which is too many (maximum is " << _maxmcn
854 << ")." << std::endl;
855 }
856 else {
857 os << std::endl << " Problem with number of mass"
858 << " constraints for unknown reasons." << std::endl;
859 }
860 }
861 else if(_ctvmq.ijkerr[1]==11) {
862 os << " Vertex " << _ctvmq.ijkerr[2]
863 << " has less than one track." << std::endl;
864 }
865 else if(_ctvmq.ijkerr[1]==12) {
866 os << " Vertex " << _ctvmq.ijkerr[2]
867 << " is a conversion vertex with a number of tracks"
868 << " different than two." << std::endl;
869 }
870 else if(_ctvmq.ijkerr[1]==13) {
871 os << " Vertex " << _ctvmq.ijkerr[2]
872 << " is a one track vertex that has no multi-track"
873 << " descendents." << std::endl;
874 }
875 else if(_ctvmq.ijkerr[1]==14) {
876 os << " Vertex " << _ctvmq.ijkerr[2]
877 << " does not point at a vertex with a lower number."
878 << std::endl;
879 }
880 else if(_ctvmq.ijkerr[1]==15) {
881 os << " Vertex " << _ctvmq.ijkerr[2]
882 << " has a parent vertex that is a conversion." << std::endl;
883 }
884 else if(_ctvmq.ijkerr[1]==16) {
885 os << " Vertex " << _ctvmq.ijkerr[2]
886 << " does 1 track pointing to a vertex with"
887 << " more than 1 track." << std::endl;
888 }
889 else if(_ctvmq.ijkerr[1]==17) {
890 os << " Vertex " << _ctvmq.ijkerr[2]
891 << " does 0 track pointing to a vertex with"
892 << " more than 0 track (?)." << std::endl;
893 }
894 else if(_ctvmq.ijkerr[1]==19) {
895 os << " Primary vertex error matrix is singular." << std::endl;
896 }
897 else if(_ctvmq.ijkerr[1]==21) {
898 os << " Track with Id " << _ctvmq.ijkerr[2]
899 << "is not in any vertex." << std::endl;
900 }
901 else if(_ctvmq.ijkerr[1]==22) {
902 os << " Track with Id " << _ctvmq.ijkerr[2]
903 << "is in multiple vertices." << std::endl;
904 }
905 else if(_ctvmq.ijkerr[1]==23) {
906 os << " Track with Id " << _ctvmq.ijkerr[2]
907 << "occurs more than once." << std::endl;
908 }
909 else if(_ctvmq.ijkerr[1]==31) {
910 os << " A mass constraint has less than 2 tracks." << std::endl;
911 }
912 else if(_ctvmq.ijkerr[1]==32) {
913 os << " The sum masses of the tracks in a mass constraint"
914 << " exceeds the constraint mass." << std::endl;
915 }
916 else if(_ctvmq.ijkerr[1]==33) {
917 os << " Beamline constraint. Beam covariance not set properly."
918 << " Negative diagonal elements." << std::endl;
919 }
920 else if(_ctvmq.ijkerr[1]==34) {
921 os << " Beamline constraint. Beam covariance not set properly."
922 << " Off-diagonal elements not zero." << std::endl;
923 }
924 else if(_ctvmq.ijkerr[1]==36) {
925 os << " Beamline constraint. Number of vertices = "
926 << _ctvmq.nvertx << " Should be 1." << std::endl;
927 }
928 }
929 else if(_ctvmq.ijkerr[0] == 2) {
930 if(_ctvmq.ijkerr[1] == 20) {
931 os << " Problem in CTVM00: " << std::endl;
932 os << " Track has negative Id = "
933 << _ctvmq.list[_ctvmq.ijkerr[2]-1] << "." << std::endl;
934 }
935 else {
936 os << " Problem in CTVMFA with vertex "
937 << _ctvmq.ijkerr[2] << ": " << std::endl;
938 os << " Failure in vertex first approximation." << std::endl;
939 if(_ctvmq.ijkerr[1] == 1) {
940 os << " Tracks are concentric circles." << std::endl;
941 }
942 if(_ctvmq.ijkerr[1] == 2) {
943 os << " Conversion vertex has widely separated"
944 << " exterior circles at midpoint." << std::endl;
945 }
946 if(_ctvmq.ijkerr[1] == 3) {
947 os << " Conversion vertex has widely separated"
948 << " interior circles at midpoint." << std::endl;
949 }
950 if(_ctvmq.ijkerr[1] == 4) {
951 os << " Vertex has widely separated"
952 << " exterior circles at approximate vertex." << std::endl;
953 }
954 if(_ctvmq.ijkerr[1] == 5) {
955 os << " Vertex has widely separated"
956 << " interior circles at approximate vertex." << std::endl;
957 }
958 if(_ctvmq.ijkerr[1] == 6) {
959 os << " Rv is too large at the chosen"
960 << " intersection point." << std::endl;
961 }
962 if(_ctvmq.ijkerr[1] == 7) {
963 os << " Delta z is too large at the chosen"
964 << " intersection point." << std::endl;
965 }
966 if(_ctvmq.ijkerr[1] == 8) {
967 os << " A track's turning to the chosen vertex"
968 << " is too large." << std::endl;
969 }
970 if(_ctvmq.ijkerr[1] == 9) {
971 os << " There is no solution with an adequately"
972 << " positive arc length." << std::endl;
973 }
974 if(_ctvmq.ijkerr[1] == 21) {
975 os << " zero-track vertexing: either/both vertex "
976 << " momenta are too small (<0.01 MeV)." << std::endl;
977 }
978 if(_ctvmq.ijkerr[1] == 22) {
979 os << " zero-track vertexing: Two lines (tracks) are "
980 << " parallel/antiparallel." << std::endl;
981 }
982
983 }
984 }
985 else if(_ctvmq.ijkerr[0] == 3) {
986 os << " Problem in CTVM01 with track with Id = "
987 << _ctvmq.list[_ctvmq.ijkerr[2]-1] << ": " << std::endl;
988 if(_ctvmq.ijkerr[1] == 1) {
989 os << " GETTRK cannot find Id in list." << std::endl;
990 }
991 if(_ctvmq.ijkerr[1] == 2) {
992 os << " Covariance matrix could not be inverted." << endl
993 << " Offending track number (in order addded) is "
994 << _ctvmq.ijkerr[2] << "." << std::endl;
995 }
996 if(_ctvmq.ijkerr[1] == 3) {
997 os << " Track turns through too large an angle"
998 << " to the vertex." << std::endl;
999 }
1000 if(_ctvmq.ijkerr[1] == 4) {
1001 os << " Track moves too far backward to vertex." << std::endl;
1002 }
1003 if(_ctvmq.ijkerr[1] == 5) {
1004 os << " Track with curvature > 0.01." << std::endl
1005 << " Offending track number is "
1006 << _ctvmq.ijkerr[2] << "." << std::endl;
1007 }
1008 }
1009 else if(status() == 9) {
1010 os << " General fit problem: " << std::endl;
1011 if(_ctvmq.ijkerr[1] == 1) {
1012 os << " Singular solution matrix." << std::endl;
1013 }
1014 if(_ctvmq.ijkerr[1] == 2 || _ctvmq.ijkerr[1] == 3) {
1015 os << " Too many iterations ( "
1016 << _ctvmq.ijkerr[2] << "(." << std::endl;
1017 }
1018 if(_ctvmq.ijkerr[1] == 4) {
1019 os << " Convergence failure." << std::endl;
1020 }
1021 if(_ctvmq.ijkerr[1] == 5) {
1022 os << " Bad convergence." << std::endl;
1023 }
1024 if(_ctvmq.ijkerr[1] == 9) {
1025 os << " Ill-formed covariance matrix." << std::endl;
1026 }
1027 }
1028 else {
1029 os << " The error codes above are not recognized." << std::endl
1030 << " Contact VertexFit expert " << _expert << "." << std::endl;
1031 }
1032 return;
1033 }
1034
1035
1036
1037
1038
1039
1040 void VertexFit::getIJKErr(int& err0, int& err1, int& err2) const
1041 {
1042 err0 = _ctvmq.ijkerr[0];
1043 err1 = _ctvmq.ijkerr[1];
1044 err2 = _ctvmq.ijkerr[2];
1045 return;
1046 }
1047
1048 int VertexFit::getIJKErr0() const
1049 {
1050 return _ctvmq.ijkerr[0];
1051 }
1052 int VertexFit::getIJKErr1() const
1053 {
1054 return _ctvmq.ijkerr[1];
1055 }
1056 int VertexFit::getIJKErr2() const
1057 {
1058 return _ctvmq.ijkerr[2];
1059 }
1060
1061
1062
1063
1064
1065 int VertexFit::getErrTrackId() const
1066 {
1067 if (status() == 0) return 0;
1068 int trkId = 0;
1069
1070
1071 if ((_ctvmq.ijkerr[0] == 2 && _ctvmq.ijkerr[1] == 20) ||
1072 _ctvmq.ijkerr[0] == 3) {
1073 trkId = _ctvmq.list[_ctvmq.ijkerr[2]-1];
1074 }
1075
1076 return trkId;
1077 }
1078
1079
1080
1081
1082
1083 string VertexFit::expert() const
1084 {
1085 return _expert;
1086 }
1087
1088
1089
1090
1091
1092 int VertexFit::status() const
1093 {
1094
1095 return stat;
1096 }
1097
1098
1099
1100
1101
1102 float VertexFit::chisq() const
1103 {
1104
1105 return _ctvmq.chisqr[0];
1106 }
1107
1108
1109
1110
1111
1112 int VertexFit::ndof() const
1113 {
1114
1115 if(_ctvmq.chisqr[0] >= 0) {
1116 return _ctvmq.ndof; }
1117 else {
1118 return 0;}
1119 }
1120
1121
1122
1123
1124
1125 float VertexFit::prob() const
1126 {
1127
1128 if(_ctvmq.chisqr[0]>=0.) {
1129 float chisq=_ctvmq.chisqr[0];
1130 int nd=_ctvmq.ndof;
1131 return prob_(chisq,nd);
1132 }
1133 else {
1134 return -999.;
1135 }
1136 }
1137
1138
1139
1140
1141
1142 float VertexFit::chisq(const CdfTrack* trk) const
1143 {
1144
1145
1146 if(_ctvmq.chisqr[0] < 0) return -1.;
1147
1148 for(int jt = 0; jt < _ctvmq.ntrack; ++jt) {
1149 if(trk->id().value() == _ctvmq.list[jt]) {
1150
1151 return _ctvmq.chit[jt];
1152 }
1153 }
1154
1155 return -1.;
1156 }
1157
1158
1159
1160
1161
1162 float VertexFit::chisq_rphi() const
1163 {
1164
1165 int index[3] = {0,1,3};
1166
1167 if(_ctvmq.chisqr[0] < 0) return -1.;
1168
1169 float chisq = 0.;
1170 for(int jt=0; jt<_ctvmq.ntrack; ++jt) {
1171
1172 for(int k1=0; k1<3; ++k1) {
1173 for(int k2=0; k2<3; ++k2) {
1174
1175 chisq += _ctvmq.pardif[jt][index[k1]] *
1176 _ctvmq.g[jt][index[k1]][index[k2]] *
1177 _ctvmq.pardif[jt][index[k2]];
1178 }
1179 }
1180 }
1181
1182 return chisq;
1183 }
1184
1185
1186
1187
1188
1189
1190 float VertexFit::chisq_z() const
1191 {
1192
1193 int index[2] = {2,4};
1194
1195 if(_ctvmq.chisqr[0] < 0) return -1.;
1196
1197 float chisq = 0.;
1198 for(int jt=0; jt<_ctvmq.ntrack; ++jt) {
1199
1200 for(int k1=0; k1<2; ++k1) {
1201 for(int k2=0; k2<2; ++k2) {
1202
1203 chisq += _ctvmq.pardif[jt][index[k1]] *
1204 _ctvmq.g[jt][index[k1]][index[k2]] *
1205 _ctvmq.pardif[jt][index[k2]];
1206 }
1207 }
1208 }
1209
1210 return chisq;
1211 }
1212
1213
1214
1215
1216
1217
1218 float VertexFit::chisq_rphiz() const
1219 {
1220
1221
1222 int index1[2] = {2,4};
1223 int index2[3] = {0,1,3};
1224
1225 if(_ctvmq.chisqr[0] < 0) return -1.;
1226
1227 float chisq = 0.;
1228 for(int jt=0; jt<_ctvmq.ntrack; ++jt) {
1229
1230 for(int k1=0; k1<2; ++k1) {
1231 for(int k2=0; k2<3; ++k2) {
1232
1233 chisq += _ctvmq.pardif[jt][index1[k1]] *
1234 _ctvmq.g[jt][index1[k1]][index2[k2]] *
1235 _ctvmq.pardif[jt][index2[k2]];
1236 }
1237 }
1238 }
1239
1240 return 2.*chisq;
1241 }
1242
1243
1244
1245
1246
1247 float VertexFit::chisq_rphi(const CdfTrack* trk) const
1248 {
1249
1250 int index[3] = {0,1,3};
1251
1252 if(_ctvmq.chisqr[0] < 0) return -1.;
1253
1254 for(int jt=0; jt<_ctvmq.ntrack; ++jt) {
1255 if(trk->id().value() == _ctvmq.list[jt]) {
1256
1257 float chisq = 0.;
1258
1259 for(int k1=0; k1<3; ++k1) {
1260 for(int k2=0; k2<3; ++k2) {
1261
1262 chisq += _ctvmq.pardif[jt][index[k1]] *
1263 _ctvmq.g[jt][index[k1]][index[k2]] *
1264 _ctvmq.pardif[jt][index[k2]];
1265 }
1266 }
1267 return chisq;
1268 }
1269 }
1270
1271 return -1.;
1272 }
1273
1274
1275
1276
1277
1278
1279 float VertexFit::chisq_z(const CdfTrack* trk) const
1280 {
1281
1282 int index[2] = {2,4};
1283
1284 if(_ctvmq.chisqr[0] < 0) return -1.;
1285
1286 for(int jt=0; jt<_ctvmq.ntrack; ++jt) {
1287 if(trk->id().value() == _ctvmq.list[jt]) {
1288
1289 float chisq = 0.;
1290
1291 for(int k1=0; k1<2; ++k1) {
1292 for(int k2=0; k2<2; ++k2) {
1293
1294 chisq += _ctvmq.pardif[jt][index[k1]] *
1295 _ctvmq.g[jt][index[k1]][index[k2]] *
1296 _ctvmq.pardif[jt][index[k2]];
1297 }
1298 }
1299 return chisq;
1300 }
1301 }
1302
1303 return -1.;
1304 }
1305
1306
1307
1308
1309
1310
1311 float VertexFit::chisq_rphiz(const CdfTrack* trk) const
1312 {
1313
1314
1315 int index1[2] = {2,4};
1316 int index2[3] = {0,1,3};
1317
1318 if(_ctvmq.chisqr[0] < 0) return -1.;
1319
1320 for(int jt=0; jt<_ctvmq.ntrack; ++jt) {
1321 if(trk->id().value() == _ctvmq.list[jt]) {
1322
1323 float chisq = 0.;
1324
1325 for(int k1=0; k1<2; ++k1) {
1326 for(int k2=0; k2<3; ++k2) {
1327
1328 chisq += _ctvmq.pardif[jt][index1[k1]] *
1329 _ctvmq.g[jt][index1[k1]][index2[k2]] *
1330 _ctvmq.pardif[jt][index2[k2]];
1331 }
1332 }
1333 return 2.*chisq;
1334 }
1335 }
1336
1337 return -1.;
1338 }
1339
1340
1341
1342
1343
1344 HepLorentzVector VertexFit::getTrackP4(const CdfTrack* trk) const
1345 {
1346 if(stat != 0) return HepLorentzVector(0,0,0,0);
1347
1348 for(int jt=0; jt<_ctvmq.ntrack; ++jt) {
1349
1350 if(trk->id().value()==_ctvmq.list[jt]) {
1351 HepLorentzVector p4((double)_ctvmq.trkp4[0][jt],
1352 (double)_ctvmq.trkp4[1][jt],
1353 (double)_ctvmq.trkp4[2][jt],
1354 (double)_ctvmq.trkp4[3][jt]);
1355 return p4;
1356 }
1357 }
1358 return HepLorentzVector(0,0,0,0);
1359 }
1360
1361
1362
1363
1364
1365 Helix VertexFit::getHelix(const CdfTrack* trk) const
1366 {
1367 if(stat != 0) return Helix(0,0,0,0,0);
1368
1369 for(int jt=0; jt<_ctvmq.ntrack; ++jt) {
1370
1371 if(trk->id().value()==_ctvmq.list[jt]) {
1372 Helix trhelix((double)_ctvmq.par[jt][2],
1373 (double)_ctvmq.par[jt][0],
1374 (double)_ctvmq.par[jt][4],
1375 (double)_ctvmq.par[jt][3],
1376 (double)_ctvmq.par[jt][1]);
1377 return trhelix;
1378 }
1379 }
1380 return Helix(0,0,0,0,0);
1381 }
1382
1383
1384
1385
1386
1387 float VertexFit::getMass(const CdfTrack* trk1,
1388 const CdfTrack* trk2, float& dmass) const
1389 {
1390
1391
1392
1393
1394
1395 #if ( defined(LINUX) && defined(__USE_BSD) ) || defined(OSF1)
1396 struct sigaction myaction = {VertexFitSetStatus, 0, 0, 0}, oldaction;
1397 sigaction(SIGFPE, &myaction, &oldaction);
1398 if (setjmp(env)!=0) {
1399 sigaction(SIGFPE, &oldaction,0);
1400 return -999;
1401 }
1402 #endif
1403
1404 dmass=-999.;
1405 if(stat!=0) return -999.;
1406
1407
1408 int ntrk=2;
1409 const CdfTrack* trks[2];
1410 trks[0]=trk1;
1411 trks[1]=trk2;
1412
1413 double result = getMass(ntrk,trks,dmass);
1414
1415
1416 #if ( defined(LINUX) && defined(__USE_BSD) ) || defined(OSF1)
1417 sigaction(SIGFPE, &oldaction,0);
1418 #endif
1419
1420 return result;
1421 }
1422
1423 float VertexFit::getMass(const CdfTrack* trk1, const CdfTrack* trk2,
1424 const CdfTrack* trk3,float& dmass) const
1425 {
1426
1427
1428
1429
1430
1431 #if ( defined(LINUX) && defined(__USE_BSD) ) || defined(OSF1)
1432 struct sigaction myaction = {VertexFitSetStatus, 0, 0, 0}, oldaction;
1433 sigaction(SIGFPE, &myaction, &oldaction);
1434 if (setjmp(env)!=0) {
1435 sigaction(SIGFPE, &oldaction,0);
1436 return -999;
1437 }
1438 #endif
1439
1440
1441
1442 dmass=-999.;
1443 if(stat!=0) return -999.;
1444
1445
1446 int ntrk=3;
1447 const CdfTrack* trks[3];
1448 trks[0]=trk1;
1449 trks[1]=trk2;
1450 trks[2]=trk3;
1451
1452
1453 double result = getMass(ntrk,trks,dmass);
1454
1455 #if ( defined(LINUX) && defined(__USE_BSD) ) || defined(OSF1)
1456 sigaction(SIGFPE, &oldaction,0);
1457 #endif
1458
1459 return result;
1460 }
1461
1462 float VertexFit::getMass(const CdfTrack* trk1, const CdfTrack* trk2,
1463 const CdfTrack* trk3, const CdfTrack* trk4, float& dmass) const
1464 {
1465 dmass=-999.;
1466 if(stat!=0) return -999.;
1467
1468
1469 int ntrk=4;
1470 const CdfTrack* trks[4];
1471 trks[0]=trk1;
1472 trks[1]=trk2;
1473 trks[2]=trk3;
1474 trks[3]=trk4;
1475
1476
1477
1478
1479 #if ( defined(LINUX) && defined(__USE_BSD) ) || defined(OSF1)
1480 struct sigaction myaction = {VertexFitSetStatus, 0, 0, 0}, oldaction;
1481 sigaction(SIGFPE, &myaction, &oldaction);
1482 if (setjmp(env)!=0) {
1483 sigaction(SIGFPE, &oldaction,0);
1484 return -999;
1485 }
1486 #endif
1487
1488 double result = getMass(ntrk,trks,dmass);
1489
1490
1491
1492 #if ( defined(LINUX) && defined(__USE_BSD) ) || defined(OSF1)
1493 sigaction(SIGFPE, &oldaction,0);
1494 #endif
1495
1496 return result;
1497 }
1498
1499 float VertexFit::getMass(int ntrk, const CdfTrack* tracks[],
1500 float& dmass) const
1501 {
1502
1503
1504
1505
1506 #if ( defined(LINUX) && defined(__USE_BSD) ) || defined(OSF1)
1507 struct sigaction myaction = {VertexFitSetStatus, 0, 0, 0}, oldaction;
1508 sigaction(SIGFPE, &myaction, &oldaction);
1509 if (setjmp(env)!=0) {
1510 sigaction(SIGFPE, &oldaction,0);
1511 return -999;
1512 }
1513 #endif
1514
1515 dmass=-999.;
1516 if(stat!=0) return -999.;
1517
1518
1519 dmass=-999.;
1520 if(ntrk <= 0) return 0;
1521 int jtrks[_maxtrk];
1522 for(int jt=0; jt<ntrk; ++jt) {
1523 bool found=false;
1524 for(int kt=0; kt<_ctvmq.ntrack; ++kt) {
1525 if(tracks[jt]->id().value()==_ctvmq.list[kt]) {
1526 found=true;
1527 jtrks[jt]=kt+1;
1528 }
1529 }
1530 if(!found) return 0;
1531 }
1532
1533 *_ctvmq_com=_ctvmq;
1534 *_ctvmfr_com=_ctvmfr;
1535 int ntr=ntrk;
1536 float mass;
1537 double p4[4];
1538 mcalc_(ntr, jtrks, mass, dmass, p4);
1539
1540
1541 #if ( defined(LINUX) && defined(__USE_BSD) ) || defined(OSF1)
1542 sigaction(SIGFPE, &oldaction,0);
1543 #endif
1544
1545 return mass;
1546 }
1547
1548
1549
1550
1551
1552 float VertexFit::getDecayLength(vertexNumber nv, vertexNumber mv,
1553 const Hep3Vector& dir, float& dlerr) const
1554 {
1555 dlerr=-999.;
1556 if(stat!=0) return -999.;
1557
1558
1559
1560
1561
1562 if(nv<0 || nv>=_ctvmq.nvertx) return -999.;
1563 if(mv<1 || mv>_ctvmq.nvertx) return -999.;
1564 if(nv>=mv) return -999.;
1565 float dir_t=sqrt(dir.x()*dir.x()+dir.y()*dir.y());
1566 if(dir_t <= 0.) return -999.;
1567 Hep3Vector dv=getVertex(mv)-getVertex(nv);
1568 float dl=(dv.x()*dir.x()+dv.y()*dir.y())/dir_t;
1569
1570 HepMatrix A(4,1);
1571 A(1,1)=dir.x()/dir_t;
1572 A(2,1)=dir.y()/dir_t;
1573 A(3,1)=-dir.x()/dir_t;
1574 A(4,1)=-dir.y()/dir_t;
1575
1576
1577
1578
1579 int nvf=0;
1580 if(nv==0) {
1581 nvf=-1;
1582 for(int jv=0; jv<_ctvmq.nvertx; ++jv) {
1583 if(_ctvmq.vtxpnt[0][jv]==0) nvf=0;
1584 }
1585 }
1586
1587 HepMatrix V(4,4,0);
1588 if(nvf < 0) {
1589 V(1,1)=getErrorMatrix(_ctvmq.voff[mv-1]+1,_ctvmq.voff[mv-1]+1);
1590 V(1,2)=getErrorMatrix(_ctvmq.voff[mv-1]+1,_ctvmq.voff[mv-1]+2);
1591 V(2,1)=getErrorMatrix(_ctvmq.voff[mv-1]+2,_ctvmq.voff[mv-1]+1);
1592 V(2,2)=getErrorMatrix(_ctvmq.voff[mv-1]+2,_ctvmq.voff[mv-1]+2);
1593 V(3,3)=_ctvmq.exyzpv[0][0];
1594 V(3,4)=_ctvmq.exyzpv[0][1];
1595 V(4,3)=_ctvmq.exyzpv[1][0];
1596 V(4,4)=_ctvmq.exyzpv[1][1];
1597 }
1598 else {
1599
1600 int index[4]={_ctvmq.voff[mv-1]+1,_ctvmq.voff[mv-1]+2,0,0};
1601 if(nv==0) {
1602 index[2]=1;
1603 index[3]=2;
1604 }
1605 else {
1606 index[2] = _ctvmq.voff[nv-1]+1;
1607 index[3] = _ctvmq.voff[nv-1]+2;
1608 }
1609 for(int j=0; j<4; ++j) {
1610 for(int k=0; k<4; ++k) {
1611 V[j][k]=getErrorMatrix(index[j],index[k]);
1612 }
1613 }
1614 }
1615
1616 dlerr=(A.T()*V*A)(1,1);
1617 if(dlerr >= 0.) {
1618 dlerr=sqrt(dlerr);
1619 }
1620 else {
1621 dlerr=-sqrt(-dlerr);
1622 }
1623
1624 return dl;
1625 }
1626
1627
1628
1629
1630
1631 float VertexFit::get_dr(vertexNumber nv, vertexNumber mv,
1632 float& drerr) const
1633 {
1634 drerr=-999.;
1635 if(stat!=0) return -999.;
1636
1637
1638
1639
1640 float dxyz[3];
1641 float dr;
1642 float dz;
1643 float dl[3];
1644
1645 int mvert=mv;
1646 int nvert=nv;
1647
1648 *_ctvmq_com=_ctvmq;
1649 *_ctvmfr_com=_ctvmfr;
1650
1651 dcalc_(mvert,nvert,dxyz,dr,dz,dl);
1652 drerr=dl[0];
1653 return dr;
1654 }
1655
1656
1657
1658
1659
1660 float VertexFit::get_dz(vertexNumber nv, vertexNumber mv,
1661 float& dzerr) const
1662 {
1663 dzerr=-999.;
1664 if(stat!=0) return -999.;
1665
1666
1667
1668
1669 float dxyz[3];
1670 float dr;
1671 float dz;
1672 float dl[3];
1673
1674 int mvert=mv;
1675 int nvert=nv;
1676
1677 *_ctvmq_com=_ctvmq;
1678 *_ctvmfr_com=_ctvmfr;
1679
1680 dcalc_(mvert,nvert,dxyz,dr,dz,dl);
1681 dzerr=dl[1];
1682 return dz;
1683 }
1684
1685
1686
1687
1688
1689 Hep3Vector VertexFit::getVertex(vertexNumber nv) const
1690 {
1691 if(stat!=0) return -999.;
1692
1693 if(nv<0 || nv>_ctvmq.nvertx) return Hep3Vector(0,0,0);
1694
1695
1696
1697
1698 int nvf=0;
1699 if(nv==0) {
1700 nvf=-1;
1701 for(int jv=0; jv<_ctvmq.nvertx; ++jv) {
1702 if(_ctvmq.vtxpnt[0][jv]==0) nvf=0;
1703 }
1704 }
1705 Hep3Vector vertex;
1706
1707
1708 if(nvf < 0) {
1709 vertex.setX(_ctvmq.xyzpv0[0]);
1710 vertex.setY(_ctvmq.xyzpv0[1]);
1711 vertex.setZ(_ctvmq.xyzpv0[2]);
1712 }
1713 else{
1714 vertex.setX(_ctvmq.xyzvrt[nv][0]);
1715 vertex.setY(_ctvmq.xyzvrt[nv][1]);
1716 vertex.setZ(_ctvmq.xyzvrt[nv][2]);
1717 }
1718
1719 vertex += _referencePoint;
1720 return vertex;
1721 }
1722
1723
1724
1725
1726
1727 double VertexFit::getErrorMatrix(int j, int k) const
1728 {
1729 if(stat!=0) return -999.;
1730
1731
1732
1733
1734
1735
1736 if(j<1 || k<1 || j>_maxdim+1 || k>_maxdim) {
1737 return -999.;
1738 }
1739 return _ctvmfr.vmat[k-1][j-1];
1740 }
1741
1742 HepSymMatrix VertexFit::getErrorMatrix(VertexFit::vertexNumber nv) const
1743 {
1744
1745
1746 HepSymMatrix cov(3,0);
1747
1748
1749
1750 if(nv==PRIMARY_VERTEX) {
1751 for(int j=0; j<3; j++)
1752 for(int k=0; k<3; k++)
1753 cov[j][k] = _ctvmq.exyzpv[j][k];
1754 return cov;
1755 }
1756
1757 if(stat!=0) return cov;
1758
1759 if(nv<VERTEX_1 || nv>_ctvmq.nvertx) return cov;
1760
1761 int voff = _ctvmq.voff[nv-1];
1762
1763 for(int i = 0 ; i < 3 ; ++i)
1764 for(int j = i ; j < 3 ; ++j)
1765 cov[i][j] = _ctvmfr.vmat[voff+i][voff+j];
1766 return cov;
1767 }
1768
1769 HepSymMatrix VertexFit::getErrorMatrix(const CdfTrack* trk) const
1770 {
1771 HepSymMatrix cov(3,0);
1772 if (stat != 0) return cov;
1773
1774 for (int nt=0; nt<_ctvmq.ntrack; ++nt) {
1775
1776
1777 if (trk->id().value() == _ctvmq.list[nt]) {
1778
1779
1780 int toff = _ctvmq.toff[nt];
1781
1782
1783 for(int i = 0 ; i < 3 ; ++i)
1784 for(int j = i ; j < 3 ; ++j)
1785 cov[i][j] = _ctvmfr.vmat[toff+i][toff+j];
1786 }
1787 }
1788 return cov;
1789 }
1790
1791 float VertexFit::getPtError(const CdfTrack* trk) const
1792 {
1793 if (stat != 0) return 0;
1794
1795 int toff;
1796 float pt,curv,curvErr,ptErr;
1797
1798 for (int nt=0; nt<_ctvmq.ntrack; ++nt) {
1799
1800
1801 if (trk->id().value() == _ctvmq.list[nt]) {
1802
1803
1804 toff = _ctvmq.toff[nt];
1805
1806
1807 pt = sqrt(_ctvmq.trkp4[0][nt]*_ctvmq.trkp4[0][nt] +
1808 _ctvmq.trkp4[1][nt]*_ctvmq.trkp4[1][nt]);
1809 curv = _ctvmq.pscale/pt;
1810 curvErr = sqrt(_ctvmfr.vmat[toff+0][toff+0]);
1811 ptErr = _ctvmq.pscale/curv/curv*curvErr;
1812 return ptErr;
1813 }
1814 }
1815
1816 return 0;
1817 }
1818
1819
1820
1821
1822 void VertexFit::getPosMomErr(HepMatrix& errors) const
1823 {
1824
1825
1826
1827
1828 double cosph[_maxtrk];
1829 double sinph[_maxtrk];
1830 double cosdph[_maxtrk];
1831 double sindph[_maxtrk];
1832 Hep3Vector mom3[_maxtrk];
1833 HepLorentzVector pmom[_maxtrk];
1834 HepLorentzVector total_mom;
1835
1836 for(int lvtx = 0; lvtx < _ctvmq.nvertx; lvtx++){
1837 for(int ltrk = 0; ltrk < _ctvmq.ntrack; ltrk++){
1838 if(!_ctvmq.trkvtx[lvtx][ltrk]) continue;
1839 cosph[ltrk] = cos(_ctvmq.par[ltrk][1]);
1840 sinph[ltrk] = sin(_ctvmq.par[ltrk][1]);
1841 double dphi = 0;
1842 sindph[ltrk] = 2 * _ctvmq.par[ltrk][0] *
1843 (_ctvmq.xyzvrt[lvtx + 1][0] * cosph[ltrk] +
1844 _ctvmq.xyzvrt[lvtx + 1][1] * sinph[ltrk]);
1845 cosdph[ltrk] = sqrt(1.0 - sindph[ltrk] * sindph[ltrk]);
1846 if(fabs(sindph[ltrk]) <= 1.0){
1847 dphi = asin(sindph[ltrk]);
1848 }
1849 double pt = _ctvmq.pscale * fabs(1./_ctvmq.par[ltrk][0]);
1850 mom3[ltrk].setX(pt * cos(_ctvmq.par[ltrk][1] + dphi));
1851 mom3[ltrk].setY(pt * sin(_ctvmq.par[ltrk][1] + dphi));
1852 mom3[ltrk].setZ(pt * _ctvmq.par[ltrk][2]);
1853 double e = sqrt(_ctvmq.tmass[ltrk] * _ctvmq.tmass[ltrk]
1854 + mom3[ltrk].mag2());
1855 pmom[ltrk].setVect(mom3[ltrk]);
1856 pmom[ltrk].setE(e);
1857
1858 total_mom += pmom[ltrk];
1859 }
1860 }
1861
1862
1863
1864
1865
1866 int ctvmft_dim = 3 * (_ctvmq.nvertx + _ctvmq.ntrack);
1867 HepMatrix deriv(ctvmft_dim, 7, 0);
1868 HepMatrix dp_dpar[_maxvtx] = {deriv, deriv, deriv};
1869
1870
1871
1872 for(int nvtx = 0; nvtx < _ctvmq.nvertx; nvtx++){
1873 for(int lcomp = 0; lcomp < 3; lcomp++){
1874 dp_dpar[nvtx][(3 * nvtx) + lcomp][lcomp] = 1.0;
1875 }
1876
1877
1878
1879 for(int lvtx = 0; lvtx < _ctvmq.nvertx; lvtx++){
1880 for(int ltrk = 0; ltrk < _ctvmq.ntrack; ltrk++){
1881 if(!_ctvmq.trkvtx[lvtx][ltrk]) continue;
1882
1883
1884
1885 double dphi_dx = 2.0 * _ctvmq.par[ltrk][0] * cosph[ltrk]/cosdph[ltrk];
1886 double dphi_dy = 2.0 * _ctvmq.par[ltrk][0] * sinph[ltrk]/cosdph[ltrk];
1887 double dphi_dc = 2.0 *
1888 (_ctvmq.xyzvrt[lvtx + 1][0] * cosph[ltrk] +
1889 _ctvmq.xyzvrt[lvtx + 1][1] * sinph[ltrk])/cosdph[ltrk];
1890 double dphi_dp = 2.0 * _ctvmq.par[ltrk][0] *
1891 (-_ctvmq.xyzvrt[lvtx + 1][0] * sinph[ltrk] +
1892 _ctvmq.xyzvrt[lvtx + 1][1] * cosph[ltrk])/cosdph[ltrk];
1893
1894
1895
1896 int lvele = 3 * lvtx;
1897
1898 dp_dpar[nvtx][lvele][3] += -pmom[ltrk].y() * dphi_dx;
1899
1900 dp_dpar[nvtx][lvele][4] += pmom[ltrk].x() * dphi_dx;
1901
1902 dp_dpar[nvtx][lvele][5] = 0.;
1903
1904 dp_dpar[nvtx][lvele][6] = 0.;
1905
1906 lvele++;
1907
1908 dp_dpar[nvtx][lvele][3] += -pmom[ltrk].y() * dphi_dy;
1909
1910 dp_dpar[nvtx][lvele][4] += pmom[ltrk].x() * dphi_dy;
1911
1912 dp_dpar[nvtx][lvele][5] = 0.;
1913
1914 dp_dpar[nvtx][lvele][6] = 0.;
1915
1916 lvele++;
1917
1918 dp_dpar[nvtx][lvele][3] = 0.;
1919
1920 dp_dpar[nvtx][lvele][4] = 0.;
1921
1922 dp_dpar[nvtx][lvele][5] = 0.;
1923
1924 dp_dpar[nvtx][lvele][6] = 0.;
1925
1926 lvele = 3 * (ltrk + _ctvmq.nvertx);
1927
1928 dp_dpar[nvtx][lvele][3] = -(pmom[ltrk].x()/_ctvmq.par[ltrk][0])
1929 - pmom[ltrk].y() * dphi_dc;
1930
1931 dp_dpar[nvtx][lvele][4] = -(pmom[ltrk].y()/_ctvmq.par[ltrk][0])
1932 + pmom[ltrk].x() * dphi_dc;
1933
1934 dp_dpar[nvtx][lvele][5] = -(pmom[ltrk].z()/_ctvmq.par[ltrk][0]);
1935
1936 dp_dpar[nvtx][lvele][6] =
1937 -mom3[ltrk].mag2()/(_ctvmq.par[ltrk][0] * pmom[ltrk].e());
1938
1939 lvele++;
1940
1941 dp_dpar[nvtx][lvele][3] = -pmom[ltrk].y() * (1.0 + dphi_dp);
1942
1943 dp_dpar[nvtx][lvele][4] = pmom[ltrk].x() * (1.0 + dphi_dp);
1944
1945 dp_dpar[nvtx][lvele][5] = 0.;
1946
1947 dp_dpar[nvtx][lvele][6] = 0.;
1948
1949 lvele++;
1950
1951 dp_dpar[nvtx][lvele][3] = 0;
1952
1953 dp_dpar[nvtx][lvele][4] = 0;
1954
1955 dp_dpar[nvtx][lvele][5] = pmom[ltrk].perp();
1956
1957 dp_dpar[nvtx][lvele][6] =
1958 pmom[ltrk].perp2() * _ctvmq.par[ltrk][2] / pmom[ltrk].e();
1959 }
1960 }
1961 }
1962
1963
1964
1965
1966 HepMatrix vmat(ctvmft_dim,ctvmft_dim,0);
1967 for(int lpar = 0; lpar < ctvmft_dim; lpar++){
1968 int l = lpar%3;
1969 int lvele = 0;
1970 if(lpar < 3 * _ctvmq.nvertx){
1971 int lvtx = lpar/3;
1972 lvele = _ctvmq.voff[lvtx] + l;
1973 }
1974 else{
1975 int ltrk = (lpar - 3 * _ctvmq.nvertx)/3;
1976 lvele = _ctvmq.toff[ltrk] + l;
1977 }
1978 for(int kpar = 0; kpar < ctvmft_dim; kpar++){
1979 int k = kpar%3;
1980 int kvele = 0;
1981 if(kpar < 3 * _ctvmq.nvertx){
1982 int kvtx = kpar/3;
1983 kvele = _ctvmq.voff[kvtx] + k;
1984 }
1985 else{
1986 int ktrk = (kpar - 3 * _ctvmq.nvertx)/3;
1987 kvele = _ctvmq.toff[ktrk] + k;
1988 }
1989 vmat[kpar][lpar] = _ctvmfr.vmat[kvele][lvele];
1990 }
1991 }
1992
1993 HepMatrix ans(7,7,0);
1994 HepMatrix answer[_maxvtx] = {ans, ans, ans};
1995 for(int nvtx = 0; nvtx < _ctvmq.nvertx; nvtx++){
1996 answer[nvtx] = (dp_dpar[nvtx].T() * vmat) * dp_dpar[nvtx];
1997 }
1998 errors = answer[0];
1999 }
2000
2001
2002
2003
2004 int VertexFit::vOff(vertexNumber jv) const
2005 { if(jv < VERTEX_1 || jv > _maxvtx) {return -999;}
2006 else {return _ctvmq.voff[jv-1];}
2007 }
2008
2009
2010
2011
2012 int VertexFit::tOff(const CdfTrack* trk) const
2013 { for(int kt=0; kt<_ctvmq.ntrack; ++kt) {
2014 if(trk->id().value()==_ctvmq.list[kt]) return _ctvmq.toff[kt];
2015 }
2016 return -999;
2017 }
2018
2019
2020
2021
2022 int VertexFit::pOff(int lp) const
2023 { if(lp < 1) {
2024 return -999;
2025 }
2026 else return _ctvmq.poff[lp-1];
2027 }
2028
2029
2030
2031
2032 int VertexFit::cOff(int lc) const
2033 { if(lc < 1) {
2034 return -999;
2035 }
2036 else return _ctvmq.coff[lc-1];
2037 }
2038
2039
2040
2041
2042 int VertexFit::mOff() const
2043 { return _ctvmq.moff; }
2044
2045
2046
2047
2048 double VertexFit::VMat(int i, int j) const
2049 { if(i <0 || j < 0) {return -999.;}
2050 else return _ctvmfr.vmat[i][j];
2051 }
2052
2053
2054
2055
2056
2057
2058
2059 VertexFit::vertexNumber VertexFit::allocateVertexNumber()
2060 {
2061 if ((_currentAllocatedVertexNumber < PRIMARY_VERTEX) ||
2062 (_currentAllocatedVertexNumber > _maxvtx)) {
2063 std::cout << "VertexFit::allocateVertexNumber: out of range!" << std::endl;
2064 return PRIMARY_VERTEX;
2065 }
2066 return vertexNumber(++_currentAllocatedVertexNumber);
2067 }
2068
2069 void VertexFit::resetAllocatedVertexNumber()
2070 {
2071 _currentAllocatedVertexNumber = 0;
2072 }
2073
2074
2075
2076
2077
2078 void VertexFit::restoreFromCommons() {
2079 stat=0;
2080 _ctvmq_com = (CTVMQ*) ctvmq_address_();
2081 _ctvmfr_com = (CTVMFR*) ctvmfr_address_();
2082 _fiddle_com = (FIDDLE*) fiddle_address_();
2083 _trkprm_com = (TRKPRM*) trkprm_address_();
2084 _ctvmq = *_ctvmq_com;
2085 _ctvmfr = *_ctvmfr_com;
2086 _fiddle = *_fiddle_com;
2087 _trkprm = *_trkprm_com;
2088 }
2089
2090
2091
2092
2093
2094 void VertexFit::setTrackReferencePoint( const Hep3Vector & ref )
2095 {
2096
2097 _extrapolateTrackErrors = true;
2098
2099 _referencePoint = ref;
2100
2101 _cdfPrimaryVertex = _primaryVertex;
2102
2103 setPrimaryVertex( _cdfPrimaryVertex - _referencePoint);
2104 }
2105
2106
2107
2108
2109
2110 void VertexFit::moveReferencePoint( HepVector & v,
2111 HepSymMatrix & m ) {
2112
2113
2114 if ( !_extrapolateTrackErrors )
2115 return;
2116
2117 TrackExtrapolator e;
2118
2119
2120 e.moveReferencePoint( v, m, _referencePoint );
2121 }
2122
2123
2124 #endif
2125
2126
Send problems or questions to cdfcode@fnal.gov