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