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