BOSS 7.0.1
BESIII Offline Software System
Loading...
Searching...
No Matches
Millepede.cxx
Go to the documentation of this file.
1// Include files
2
3#include <iostream>
4#include <iomanip>
5#include "cstdlib"
6#include "math.h"
7
8// local
9#include "MdcAlignAlg/Millepede.h"
10//#include "include/MdcCosParams.h" // added by wulh on 06/08/28
11
12//-----------------------------------------------------------------------------
13// Implementation file for class : Millepede
14//
15// 2005-07-29 : Sebastien Viret
16//-----------------------------------------------------------------------------
17
18
19using namespace std;
20
21//=============================================================================
22// Standard constructor, initializes variables
23//=============================================================================
25{}
26//=============================================================================
27// Destructor
28//=============================================================================
30
31//=============================================================================
32
33
34/*
35 ------------------------------------------------------
36 INITMILLE: first initialization of Millepede
37 this part is sub-detector independant
38 ------------------------------------------------------
39
40
41
42
43 ------------------------------------------------------
44*/
45
46bool Millepede::InitMille(bool DOF[], double Sigm[], int nglo
47 , int nloc, double startfact, int nstd
48 , double res_cut, double res_cut_init)
49{
50
51 cout << " " << endl;
52 cout << " * o o o " << endl;
53 cout << " o o o " << endl;
54 cout << " o ooooo o o o oo ooo oo ooo oo " << endl;
55 cout << " o o o o o o o o o o o o o o o o " << endl;
56 cout << " o o o o o o oooo o o oooo o o oooo " << endl;
57 cout << " o o o o o o o ooo o o o o " << endl;
58 cout << " o o o o o o oo o oo ooo oo ++ starts" << endl;
59 cout << " " << endl;
60
61 if (debug_mode) cout << "" << endl;
62 if (debug_mode) cout << "----------------------------------------------------" << endl;
63 if (debug_mode) cout << "" << endl;
64 if (debug_mode) cout << " Entering InitMille" << endl;
65 if (debug_mode) cout << "" << endl;
66 if (debug_mode) cout << "-----------------------------------------------------" << endl;
67 if (debug_mode) cout << "" << endl;
68
69 ncs = 0;
70 loctot = 0; // Total number of local fits
71 locrej = 0; // Total number of local fits rejected
72 cfactref = 1.0; // Reference value for Chi^2/ndof cut
73
74 Millepede::SetTrackNumber(0); // Number of local fits (starts at 0)
75
76 m_residual_cut = res_cut;
77 m_residual_cut_init = res_cut_init;
78
79 // nagb = 6*nglo; // Number of global derivatives
80 nagb = 3*nglo; // modified by wulh
81 nalc = nloc; // Number of local derivatives
82 nstdev = nstd; // Number of StDev for local fit chisquare cut
83
84 if (debug_mode) cout << "Number of global parameters : " << nagb << endl;
85 if (debug_mode) cout << "Number of local parameters : " << nalc << endl;
86 if (debug_mode) cout << "Number of standard deviations : " << nstdev << endl;
87
88 if (nagb>mglobl || nalc>mlocal)
89 {
90 if (debug_mode) cout << "Two many parameters !!!!!" << endl;
91 return false;
92 }
93
94 // Global parameters initializations
95
96 for (int i=0; i<nagb; i++)
97 {
98 bgvec[i]=0.;
99 pparm[i]=0.;
100 dparm[i]=0.;
101 psigm[i]=-1.;
102 indnz[i]=-1;
103 indbk[i]=-1;
104 nlnpa[i]=0;
105
106 for (int j=0; j<nagb;j++)
107 {
108 cgmat[i][j]=0.;
109 }
110 }
111
112 // Local parameters initializations
113
114 for (int i=0; i<nalc; i++)
115 {
116 blvec[i]=0.;
117
118 for (int j=0; j<nalc;j++)
119 {
120 clmat[i][j]=0.;
121 }
122 }
123
124 // Then we fix all parameters...
125
126 for (int j=0; j<nagb; j++) {Millepede::ParSig(j,0.0);}
127
128 // ...and we allow them to move if requested
129
130 // for (int i=0; i<3; i++)
131 for (int i=0; i<3; i++) // modified by wulh on 06/08/27
132 {
133 if (verbose_mode) cout << "GetDOF(" << i << ")= " << DOF[i] << endl;
134
135 if (DOF[i])
136 {
137 for (int j=i*nglo; j<(i+1)*nglo; j++)
138 {Millepede::ParSig(j,Sigm[i]);}
139 }
140 }
141
142 // Activate iterations (if requested)
143
144 itert = 0; // By default iterations are turned off
145 cfactr = 500.0;
146 if (m_iteration) Millepede::InitUn(startfact);
147
148 arest.clear(); // Number of stored parameters when doing local fit
149 arenl.clear(); // Is it linear or not?
150 indst.clear();
151
152 storeind.clear();
153 storeare.clear();
154 storenl.clear();
155 storeplace.clear();
156
157 if (debug_mode) cout << "" << endl;
158 if (debug_mode) cout << "----------------------------------------------------" << endl;
159 if (debug_mode) cout << "" << endl;
160 if (debug_mode) cout << " InitMille has been successfully called!" << endl;
161 if (debug_mode) cout << "" << endl;
162 if (debug_mode) cout << "-----------------------------------------------------" << endl;
163 if (debug_mode) cout << "" << endl;
164
165 return true;
166}
167
168
169/*
170 -----------------------------------------------------------
171 PARGLO: initialization of global parameters
172 -----------------------------------------------------------
173
174 index = the index of the global parameter in the
175 result array (equivalent to dparm[]).
176
177 param = the starting value
178
179 -----------------------------------------------------------
180*/
181
182bool Millepede::ParGlo(int index, double param)
183{
184 if (index<0 || index>=nagb)
185 {return false;}
186 else
187 {pparm[index] = param;}
188
189 return true;
190}
191
192
193/*
194 -----------------------------------------------------------
195 PARSIG: define a constraint for a single global param
196 param is 'encouraged' to vary within [-sigma;sigma]
197 range
198 -----------------------------------------------------------
199
200 index = the index of the global parameter in the
201 result array (equivalent to dparm[]).
202
203 sigma = value of the constraint (sigma <= 0. will
204 mean that parameter is FIXED !!!)
205
206 -----------------------------------------------------------
207*/
208
209bool Millepede::ParSig(int index, double sigma)
210{
211 if (index>=nagb)
212 {return false;}
213 else
214 {psigm[index] = sigma;}
215
216 return true;
217}
218
219
220/*
221 -----------------------------------------------------------
222 INITUN: unit for iteration
223 -----------------------------------------------------------
224
225 cutfac is used by Fitloc to define the Chi^2/ndof cut value
226
227 A large cutfac value enables to take a wider range of tracks
228 for first iterations, which might be useful if misalignments
229 are large.
230
231 As soon as cutfac differs from 0 iteration are requested.
232 cutfac is then reduced, from one iteration to the other,
233 and iterations are stopped when it reaches the value 1.
234
235 At least one more iteration is often needed in order to remove
236 tracks containing outliers.
237
238 -----------------------------------------------------------
239*/
240
241bool Millepede::InitUn(double cutfac)
242{
243 cfactr = std::max(1.0, cutfac);
244
245 cout << "Initial cut factor is " << cfactr << endl;
246 itert = 1; // Initializes the iteration process
247 return true;
248}
249
250/*
251 -----------------------------------------------------------
252 CONSTF: define a constraint equation in Millepede
253 -----------------------------------------------------------
254
255 dercs = the row containing constraint equation
256 derivatives (put into the final matrix)
257
258 rhs = the lagrange multiplier value (sum of equation)
259
260 -----------------------------------------------------------
261*/
262
263bool Millepede::ConstF(double dercs[], double rhs)
264{
265 if (ncs>=mcs) // mcs is defined in Millepede.h
266 {
267 cout << "Too many constraints !!!" << endl;
268 return false;
269 }
270
271 for (int i=0; i<nagb; i++) {adercs[ncs][i] = dercs[i];}
272
273 arhs[ncs] = rhs;
274 ncs++ ;
275 cout << "Number of constraints increased to " << ncs << endl;
276 return true;
277}
278
279
280/*
281 -----------------------------------------------------------
282 EQULOC: write ONE equation in the matrices
283 -----------------------------------------------------------
284
285 dergb[1..nagb] = global parameters derivatives
286 derlc[1..nalc] = local parameters derivatives
287 rmeas = measured value
288 sigma = error on measured value (nothin to do with ParSig!!!)
289
290 -----------------------------------------------------------
291*/
292
293bool Millepede::EquLoc(double dergb[], double derlc[], double dernl[], double rmeas, double sigma)
294{
295
296 if (sigma<=0.0) // If parameter is fixed, then no equation
297 {
298 for (int i=0; i<nalc; i++)
299 {
300 derlc[i] = 0.0;
301 }
302 for (int i=0; i<nagb; i++)
303 {
304 dergb[i] = 0.0;
305 }
306 return true;
307 }
308
309 // Serious equation, initialize parameters
310
311 double wght = 1.0/(sigma*sigma);
312 int nonzer = 0;
313 int ialc = -1;
314 int iblc = -1;
315 int iagb = -1;
316 int ibgb = -1;
317
318 for (int i=0; i<nalc; i++) // Retrieve local param interesting indices
319 {
320 if (derlc[i]!=0.0)
321 {
322 nonzer++;
323 if (ialc == -1) ialc=i; // first index
324 iblc = i; // last index
325 }
326 }
327
328 if (verbose_mode) cout << ialc << " / " << iblc << endl;
329
330 for (int i=0; i<nagb; i++) // Idem for global parameters
331 {
332 if (dergb[i]!=0.0)
333 {
334 nonzer++;
335 if (iagb == -1) iagb=i; // first index
336 ibgb = i; // last index
337 }
338 }
339
340 if (verbose_mode) cout << iagb << " / " << ibgb << endl;
341
342 indst.push_back(-1);
343 arest.push_back(rmeas);
344 arenl.push_back(0.);
345
346 for (int i=ialc; i<=iblc; i++)
347 {
348 if (derlc[i]!=0.0)
349 {
350 indst.push_back(i);
351 arest.push_back(derlc[i]);
352 arenl.push_back(0.0);
353 derlc[i] = 0.0;
354 }
355 }
356
357 indst.push_back(-1);
358 arest.push_back(wght);
359 arenl.push_back(0.0);
360
361 for (int i=iagb; i<=ibgb; i++)
362 {
363 if (dergb[i]!=0.0)
364 {
365 indst.push_back(i);
366 arest.push_back(dergb[i]);
367 arenl.push_back(dernl[i]);
368 dergb[i] = 0.0;
369 }
370 }
371
372 if (verbose_mode) cout << "Out Equloc -- NST = " << arest.size() << endl;
373
374 return true;
375}
376
377/*
378 -----------------------------------------------------------
379 ZERLOC: reset the derivative vectors
380 -----------------------------------------------------------
381
382 dergb[1..nagb] = global parameters derivatives
383 dergb[1..nalc] = local parameters derivatives
384
385 -----------------------------------------------------------
386*/
387
388bool Millepede::ZerLoc(double dergb[], double derlc[], double dernl[])
389{
390 for(int i=0; i<nalc; i++) {derlc[i] = 0.0;}
391 for(int i=0; i<nagb; i++) {dergb[i] = 0.0;}
392 for(int i=0; i<nagb; i++) {dernl[i] = 0.0;}
393
394 return true;
395}
396
397/*
398 -----------------------------------------------------------
399 FITLOC: perform local params fit, once all the equations
400 have been written by EquLoc
401 -----------------------------------------------------------
402
403 n = number of the fit, it is used to store
404 fit parameters and then retrieve them
405 for iterations (via STOREIND and STOREARE)
406
407 track_params = contains the fitted track parameters and
408 related errors
409
410 single_fit = is an option, if it is set to 1, we don't
411 perform the last loop. It is used to update
412 the track parameters without modifying global
413 matrices
414
415 -----------------------------------------------------------
416*/
417
418bool Millepede::FitLoc(int n, double track_params[], int single_fit)
419{
420 // Few initializations
421
422 int i, j, k, ik, ij, ist, nderlc, ndergl, ndf;
423 int ja = -1;
424 int jb = 0;
425 int nagbn = 0;
426
427 double rmeas, wght, rms, cutval;
428
429 double summ = 0.0;
430 int nsum = 0;
431 nst = 0;
432 nst = arest.size();
433
434
435 // Fill the track store at first pass
436
437 if (itert < 2 && single_fit != 1) // Do it only once
438 {
439 if (debug_mode) cout << "Store equation no: " << n << endl;
440
441 for (i=0; i<nst; i++) // Store the track parameters
442 {
443 storeind.push_back(indst[i]);
444 storeare.push_back(arest[i]);
445 storenl.push_back(arenl[i]);
446
447 if (arenl[i] != 0.) arest[i] = 0.0; // Reset global derivatives if non linear and first iteration
448 }
449
450 arenl.clear();
451
452 storeplace.push_back(storeind.size());
453
454 if (verbose_mode) cout << "StorePlace size = " << storeplace[n] << endl;
455 if (verbose_mode) cout << "StoreInd size = " << storeind.size() << endl;
456 }
457
458
459 for (i=0; i<nalc; i++) // reset local params
460 {
461 blvec[i] = 0.0;
462
463 for (j=0; j<nalc; j++) {clmat[i][j] = 0.0;}
464 }
465
466 for (i=0; i<nagb; i++) {indnz[i] = -1;} // reset mixed params
467
468
469 /*
470
471 LOOPS : HOW DOES IT WORKS ?
472
473 Now start by reading the informations stored with EquLoc.
474 Those informations are in vector INDST and AREST.
475 Each -1 in INDST delimits the equation parameters:
476
477 First -1 ---> rmeas in AREST
478 Then we have indices of local eq in INDST, and derivatives in AREST
479 Second -1 ---> weight in AREST
480 Then follows indices and derivatives of global eq.
481 ....
482
483 We took them and store them into matrices.
484
485 As we want ONLY local params, we substract the part of the estimated value
486 due to global params. Indeed we could have already an idea of these params,
487 with previous alignment constants for example (set with PARGLO). Also if there
488 are more than one iteration (FITLOC could be called by FITGLO)
489
490 */
491
492
493 //
494 // FIRST LOOP : local track fit
495 //
496
497 ist = 0;
498 indst.push_back(-1);
499
500 while (ist <= nst)
501 {
502 if (indst[ist] == -1)
503 {
504 if (ja == -1) {ja = ist;} // First 0 : rmeas
505 else if (jb == 0) {jb = ist;} // Second 0 : weight
506 else // Third 0 : end of equation
507 {
508 rmeas = arest[ja];
509 wght = arest[jb];
510 if (verbose_mode) cout << "rmeas = " << rmeas << endl ;
511 if (verbose_mode) cout << "wght = " << wght << endl ;
512
513 for (i=(jb+1); i<ist; i++) // Now suppress the global part
514 // (only relevant with iterations)
515 {
516 j = indst[i]; // Global param indice
517 if (verbose_mode) cout << "dparm[" << j << "] = " << dparm[j] << endl;
518 if (verbose_mode) cout << "Starting misalignment = " << pparm[j] << endl;
519 rmeas -= arest[i]*(pparm[j]+dparm[j]);
520 }
521
522 if (verbose_mode) cout << "rmeas after global stuff removal = " << rmeas << endl ;
523
524 for (i=(ja+1); i<jb; i++) // Finally fill local matrix and vector
525 {
526 j = indst[i]; // Local param indice (the matrix line)
527 blvec[j] += wght*rmeas*arest[i]; // See note for precisions
528
529 if (verbose_mode) cout << "blvec[" << j << "] = " << blvec[j] << endl ;
530
531 for (k=(ja+1); k<=i ; k++) // Symmetric matrix, don't bother k>j coeffs
532 {
533 ik = indst[k];
534 clmat[j][ik] += wght*arest[i]*arest[k];
535
536 if (verbose_mode) cout << "clmat[" << j << "][" << ik << "] = " << clmat[j][ik] << endl;
537 }
538 }
539 ja = -1;
540 jb = 0;
541 ist--;
542 } // End of "end of equation" operations
543 } // End of loop on equation
544 ist++;
545 } // End of loop on all equations used in the fit
546
547
548 //
549 // Local params matrix is completed, now invert to solve...
550 //
551
552 nrank = 0; // Rank is the number of nonzero diagonal elements
553 nrank = Millepede::SpmInv(clmat, blvec, nalc, scdiag, scflag);
554
555 if (debug_mode) cout << "" << endl;
556 if (debug_mode) cout << " __________________________________________________" << endl;
557 if (debug_mode) cout << " Printout of local fit (FITLOC) with rank= "<< nrank << endl;
558 if (debug_mode) cout << " Result of local fit : (index/parameter/error)" << endl;
559
560 for (i=0; i<nalc; i++)
561 {
562 if (debug_mode) cout << std::setprecision(4) << std::fixed;
563 if (debug_mode) cout << std::setw(20) << i << " / " << std::setw(10)
564 << blvec[i] << " / " << sqrt(clmat[i][i]) << endl;
565 }
566
567
568 // Store the track params and errors
569
570 for (i=0; i<nalc; i++)
571 {
572 track_params[2*i] = blvec[i];
573 track_params[2*i+1] = sqrt(fabs(clmat[i][i]));
574 }
575
576
577 //
578 // SECOND LOOP : residual calculation
579 //
580
581 ist = 0;
582 ja = -1;
583 jb = 0;
584
585 while (ist <= nst)
586 {
587 if (indst[ist] == -1)
588 {
589 if (ja == -1) {ja = ist;} // First 0 : rmeas
590 else if (jb == 0) {jb = ist;} // Second 0 : weight
591 else // Third 0 : end of equation
592 {
593 rmeas = arest[ja];
594 wght = arest[jb];
595
596 nderlc = jb-ja-1; // Number of local derivatives involved
597 ndergl = ist-jb-1; // Number of global derivatives involved
598
599 // Print all (for debugging purposes)
600
601 if (verbose_mode) cout << "" << endl;
602 if (verbose_mode) cout << std::setprecision(4) << std::fixed;
603 if (verbose_mode) cout << ". equation: measured value " << std::setw(13)
604 << rmeas << " +/- " << std::setw(13) << 1.0/sqrt(wght) << endl;
605 if (verbose_mode) cout << "Number of derivatives (global, local): "
606 << ndergl << ", " << nderlc << endl;
607 if (verbose_mode) cout << "Global derivatives are: (index/derivative/parvalue) " << endl;
608
609 for (i=(jb+1); i<ist; i++)
610 {if (verbose_mode) cout << indst[i] << " / " << arest[i]
611 << " / " << pparm[indst[i]] << endl;}
612
613 if (verbose_mode) cout << "Local derivatives are: (index/derivative) " << endl;
614
615 for (i=(ja+1); i<jb; i++) {if (verbose_mode) cout << indst[i] << " / " << arest[i] << endl;}
616
617 // Now suppress local and global parts to RMEAS;
618
619 for (i=(ja+1); i<jb; i++) // First the local part
620 {
621 j = indst[i];
622 rmeas -= arest[i]*blvec[j];
623 }
624
625 for (i=(jb+1); i<ist; i++) // Then the global part
626 {
627 j = indst[i];
628 rmeas -= arest[i]*(pparm[j]+dparm[j]);
629 }
630
631 // rmeas contains now the residual value
632 // if (verbose_mode) cout << "Residual value : "<< rmeas << endl;
633 if (verbose_reject) cout << "Residual value : "<< rmeas << endl;
634
635 // reject the track if rmeas is too important (outlier)
636 if (fabs(rmeas) >= m_residual_cut_init && itert <= 1)
637 {
638 // if (verbose_mode) cout << "Rejected track !!!!!" << endl;
639 if (verbose_reject) cout << "Rejected track !!!!!" << endl;
640 locrej++;
641 indst.clear(); // reset stores and go to the next track
642 arest.clear();
643 return false;
644 }
645
646 if (fabs(rmeas) >= m_residual_cut && itert > 1)
647 {
648 // if (verbose_mode) cout << "Rejected track !!!!!" << endl;
649 if (verbose_reject) cout << "Rejected track !!!!!" << endl;
650 locrej++;
651 indst.clear(); // reset stores and go to the next track
652 arest.clear();
653 return false;
654 }
655
656 summ += wght*rmeas*rmeas ; // total chi^2
657 nsum++; // number of equations
658 ja = -1;
659 jb = 0;
660 ist--;
661 } // End of "end of equation" operations
662 } // End of loop on equation
663 ist++;
664 } // End of loop on all equations used in the fit
665
666 ndf = nsum-nrank;
667 rms = 0.0;
668
669 if (debug_mode) cout << "Final chi square / degrees of freedom "<< summ << " / " << ndf << endl;
670
671 if (ndf > 0) rms = summ/float(ndf); // Chi^2/dof
672
673 if (single_fit == 0) loctot++;
674
675 if (nstdev != 0 && ndf > 0 && single_fit != 1) // Chisquare cut
676 {
677 cutval = Millepede::chindl(nstdev, ndf)*cfactr;
678
679 if (debug_mode) cout << "Reject if Chisq/Ndf = " << rms << " > " << cutval << endl;
680
681 if (rms > cutval) // Reject the track if too much...
682 {
683 if (verbose_mode) cout << "Rejected track !!!!!" << endl;
684 if (single_fit == 0) locrej++;
685 indst.clear(); // reset stores and go to the next track
686 arest.clear();
687 return false;
688 }
689 }
690
691 if (single_fit == 1) // Stop here if just updating the track parameters
692 {
693 indst.clear(); // Reset store for the next track
694 arest.clear();
695 return true;
696 }
697
698 //
699 // THIRD LOOP: local operations are finished, track is accepted
700 // We now update the global parameters (other matrices)
701 //
702
703 ist = 0;
704 ja = -1;
705 jb = 0;
706
707 while (ist <= nst)
708 {
709 if (indst[ist] == -1)
710 {
711 if (ja == -1) {ja = ist;} // First 0 : rmeas
712 else if (jb == 0) {jb = ist;} // Second 0 : weight
713 else // Third 0 : end of equation
714 {
715 rmeas = arest[ja];
716 wght = arest[jb];
717
718 for (i=(jb+1); i<ist; i++) // Now suppress the global part
719 {
720 j = indst[i]; // Global param indice
721 rmeas -= arest[i]*(pparm[j]+dparm[j]);
722 }
723
724 // First of all, the global/global terms (exactly like local matrix)
725
726 for (i=(jb+1); i<ist; i++)
727 {
728 j = indst[i]; // Global param indice (the matrix line)
729
730 bgvec[j] += wght*rmeas*arest[i]; // See note for precisions
731 if (verbose_mode) cout << "bgvec[" << j << "] = " << bgvec[j] << endl ;
732
733 for (k=(jb+1); k<ist ; k++)
734 {
735 ik = indst[k];
736 cgmat[j][ik] += wght*arest[i]*arest[k];
737 if (verbose_mode) cout << "cgmat[" << j << "][" << ik << "] = " << cgmat[j][ik] << endl;
738 }
739 }
740
741 // Now we have also rectangular matrices containing global/local terms.
742
743 for (i=(jb+1); i<ist; i++)
744 {
745 j = indst[i]; // Global param indice (the matrix line)
746 ik = indnz[j]; // Index of index
747
748 if (ik == -1) // New global variable
749 {
750 for (k=0; k<nalc; k++) {clcmat[nagbn][k] = 0.0;} // Initialize the row
751
752 indnz[j] = nagbn;
753 indbk[nagbn] = j;
754 ik = nagbn;
755 nagbn++;
756 }
757
758 for (k=(ja+1); k<jb ; k++) // Now fill the rectangular matrix
759 {
760 ij = indst[k];
761 clcmat[ik][ij] += wght*arest[i]*arest[k];
762 if (verbose_mode) cout << "clcmat[" << ik << "][" << ij << "] = " << clcmat[ik][ij] << endl;
763 }
764 }
765 ja = -1;
766 jb = 0;
767 ist--;
768 } // End of "end of equation" operations
769 } // End of loop on equation
770 ist++;
771 } // End of loop on all equations used in the fit
772
773 // Third loop is finished, now we update the correction matrices (see notes)
774
775 Millepede::SpAVAt(clmat, clcmat, corrm, nalc, nagbn);
776 Millepede::SpAX(clcmat, blvec, corrv, nalc, nagbn);
777
778 for (i=0; i<nagbn; i++)
779 {
780 j = indbk[i];
781 bgvec[j] -= corrv[i];
782
783 for (k=0; k<nagbn; k++)
784 {
785 ik = indbk[k];
786 cgmat[j][ik] -= corrm[i][k];
787 }
788 }
789
790 indst.clear(); // Reset store for the next track
791 arest.clear();
792
793 return true;
794}
795
796
797/*
798 -----------------------------------------------------------
799 MAKEGLOBALFIT: perform global params fit, once all the 'tracks'
800 have been fitted by FitLoc
801 -----------------------------------------------------------
802
803 par[] = array containing the computed global
804 parameters (the misalignment constants)
805
806 error[] = array containing the error on global
807 parameters (estimated by Millepede)
808
809 pull[] = array containing the corresponding pulls
810
811 -----------------------------------------------------------
812*/
813
814bool Millepede::MakeGlobalFit(double par[], double error[], double pull[])
815{
816 int i, j, nf, nvar;
817 int itelim = 0;
818
819 int nstillgood;
820
821 double sum;
822
823 double step[150];
824
825 double trackpars[2*mlocal];
826
827 int ntotal_start, ntotal;
828
829 cout << "..... Making global fit ....." << endl;
830
831 ntotal_start = Millepede::GetTrackNumber();
832
833 std::vector<double> track_slopes;
834
835 track_slopes.resize(2*ntotal_start);
836
837 for (i=0; i<2*ntotal_start; i++) track_slopes[i] = 0.;
838
839 if (itert <= 1) itelim=10; // Max number of iterations
840
841 while (itert < itelim) // Iteration for the final loop
842 {
843 if (debug_mode) cout << "ITERATION --> " << itert << endl;
844
845 ntotal = Millepede::GetTrackNumber();
846 cout << "...using " << ntotal << " tracks..." << endl;
847
848 // Start by saving the diagonal elements
849
850 for (i=0; i<nagb; i++) {diag[i] = cgmat[i][i];}
851
852 // Then we retrieve the different constraints: fixed parameter or global equation
853
854 nf = 0; // First look at the fixed global params
855
856 for (i=0; i<nagb; i++)
857 {
858 if (psigm[i] <= 0.0) // fixed global param
859 {
860 nf++;
861
862 for (j=0; j<nagb; j++)
863 {
864 cgmat[i][j] = 0.0; // Reset row and column
865 cgmat[j][i] = 0.0;
866 }
867 }
868 else if (psigm[i] > 0.0)
869 {
870 cgmat[i][i] += 1.0/(psigm[i]*psigm[i]);
871 }
872 }
873
874 nvar = nagb; // Current number of equations
875 if (debug_mode) cout << "Number of constraint equations : " << ncs << endl;
876
877 if (ncs > 0) // Then the constraint equation
878 {
879 for (i=0; i<ncs; i++)
880 {
881 sum = arhs[i];
882 for (j=0; j<nagb; j++)
883 {
884 cgmat[nvar][j] = float(ntotal)*adercs[i][j];
885 cgmat[j][nvar] = float(ntotal)*adercs[i][j];
886 sum -= adercs[i][j]*(pparm[j]+dparm[j]);
887 }
888
889 cgmat[nvar][nvar] = 0.0;
890 bgvec[nvar] = float(ntotal)*sum;
891 nvar++;
892 }
893 }
894
895
896 // Intended to compute the final global chisquare
897
898 double final_cor = 0.0;
899
900 if (itert > 1)
901 {
902 for (j=0; j<nagb; j++)
903 {
904 for (i=0; i<nagb; i++)
905 {
906 if (psigm[i] > 0.0)
907 {
908 final_cor += step[j]*cgmat[j][i]*step[i];
909 if (i == j) final_cor -= step[i]*step[i]/(psigm[i]*psigm[i]);
910 }
911 }
912 }
913 }
914
915 cout << " Final coeff is " << final_cor << endl;
916 cout << " Final NDOFs = " << nagb << endl;
917
918 // The final matrix inversion
919
920 nrank = Millepede::SpmInv(cgmat, bgvec, nvar, scdiag, scflag);
921
922 for (i=0; i<nagb; i++)
923 {
924 dparm[i] += bgvec[i]; // Update global parameters values (for iterations)
925 if (verbose_mode) cout << "dparm[" << i << "] = " << dparm[i] << endl;
926 if (verbose_mode) cout << "cgmat[" << i << "][" << i << "] = " << cgmat[i][i] << endl;
927 if (verbose_mode) cout << "err = " << sqrt(fabs(cgmat[i][i])) << endl;
928
929 step[i] = bgvec[i];
930
931 if (itert == 1) error[i] = cgmat[i][i]; // Unfitted error
932 }
933
934 cout << "" << endl;
935 cout << "The rank defect of the symmetric " << nvar << " by " << nvar
936 << " matrix is " << nvar-nf-nrank << " (bad if non 0)" << endl;
937
938 if (itert == 0) break;
939 itert++;
940
941 cout << "" << endl;
942 cout << "Total : " << loctot << " local fits, "
943 << locrej << " rejected." << endl;
944
945 // Reinitialize parameters for iteration
946
947 loctot = 0;
948 locrej = 0;
949
950 if (cfactr != cfactref && sqrt(cfactr) > 1.2*cfactref)
951 {
952 cfactr = sqrt(cfactr);
953 }
954 else
955 {
956 cfactr = cfactref;
957 // itert = itelim;
958 }
959
960 if (itert == itelim) break; // End of story
961
962 cout << "Iteration " << itert << " with cut factor " << cfactr << endl;
963
964 // Reset global variables
965
966 for (i=0; i<nvar; i++)
967 {
968 bgvec[i] = 0.0;
969 for (j=0; j<nvar; j++)
970 {
971 cgmat[i][j] = 0.0;
972 }
973 }
974
975 //
976 // We start a new iteration
977 //
978
979 // First we read the stores for retrieving the local params
980
981 nstillgood = 0;
982
983 for (i=0; i<ntotal_start; i++)
984 {
985 int rank_i = 0;
986 int rank_f = 0;
987
988 (i>0) ? rank_i = abs(storeplace[i-1]) : rank_i = 0;
989 rank_f = storeplace[i];
990
991 if (verbose_mode) cout << "Track " << i << " : " << endl;
992 if (verbose_mode) cout << "Starts at " << rank_i << endl;
993 if (verbose_mode) cout << "Ends at " << rank_f << endl;
994
995 if (rank_f >= 0) // Fit is still OK
996 {
997
998 if (itert > 3)
999 {
1000 indst.clear();
1001 arest.clear();
1002
1003 for (j=rank_i; j<rank_f; j++)
1004 {
1005 indst.push_back(storeind[j]);
1006
1007 if (storenl[j] == 0) arest.push_back(storeare[j]);
1008 if (storenl[j] == 1) arest.push_back(track_slopes[2*i]*storeare[j]);
1009 if (storenl[j] == 2) arest.push_back(track_slopes[2*i+1]*storeare[j]);
1010 }
1011
1012 for (j=0; j<2*nalc; j++) {trackpars[j] = 0.;}
1013
1014 Millepede::FitLoc(i,trackpars,1);
1015
1016 track_slopes[2*i] = trackpars[2];
1017 track_slopes[2*i+1] = trackpars[6];
1018 }
1019
1020 indst.clear();
1021 arest.clear();
1022
1023 for (j=rank_i; j<rank_f; j++)
1024 {
1025 indst.push_back(storeind[j]);
1026
1027 if (storenl[j] == 0) arest.push_back(storeare[j]);
1028 if (storenl[j] == 1) arest.push_back(track_slopes[2*i]*storeare[j]);
1029 if (storenl[j] == 2) arest.push_back(track_slopes[2*i+1]*storeare[j]);
1030 }
1031
1032 for (j=0; j<2*nalc; j++) {trackpars[j] = 0.;}
1033
1034 bool sc = Millepede::FitLoc(i,trackpars,0);
1035
1036 (sc)
1037 ? nstillgood++
1038 : storeplace[i] = -rank_f;
1039 }
1040 } // End of loop on fits
1041
1042 Millepede::SetTrackNumber(nstillgood);
1043
1044 } // End of iteration loop
1045
1046 Millepede::PrtGlo(); // Print the final results
1047
1048 for (j=0; j<nagb; j++)
1049 {
1050 par[j] = dparm[j];
1051 dparm[j] = 0.;
1052 pull[j] = par[j]/sqrt(psigm[j]*psigm[j]-cgmat[j][j]);
1053 error[j] = sqrt(fabs(cgmat[j][j]));
1054 }
1055
1056 cout << std::setw(10) << " " << endl;
1057 cout << std::setw(10) << " * o o o " << endl;
1058 cout << std::setw(10) << " o o o " << endl;
1059 cout << std::setw(10) << " o ooooo o o o oo ooo oo ooo oo " << endl;
1060 cout << std::setw(10) << " o o o o o o o o o o o o o o o o " << endl;
1061 cout << std::setw(10) << " o o o o o o oooo o o oooo o o oooo " << endl;
1062 cout << std::setw(10) << " o o o o o o o ooo o o o o " << endl;
1063 cout << std::setw(10) << " o o o o o o oo o oo ooo oo ++ ends." << endl;
1064 cout << std::setw(10) << " o " << endl;
1065
1066 return true;
1067}
1068
1069
1070
1071
1072/*
1073 -----------------------------------------------------------
1074 SPMINV: obtain solution of a system of linear equations with symmetric matrix
1075 and the inverse (using 'singular-value friendly' GAUSS pivot)
1076 -----------------------------------------------------------
1077
1078 Solve the equation : V * X = B
1079
1080 V is replaced by inverse matrix and B by X, the solution vector
1081 -----------------------------------------------------------
1082*/
1083
1084int Millepede::SpmInv(double v[][mgl], double b[], int n, double diag[], bool flag[])
1085{
1086 int i, j, jj, k;
1087 double vkk, *temp;
1088 double *r, *c;
1089 double eps = 0.00000000000001;
1090
1091 r = new double[n];
1092 c = new double[n];
1093
1094 temp = new double[n];
1095
1096 for (i=0; i<n; i++)
1097 {
1098 r[i] = 0.0;
1099 c[i] = 0.0;
1100 flag[i] = true;
1101
1102 for (j=0; j<=i; j++) {if (v[j][i] == 0) {v[j][i] = v[i][j];}}
1103 }
1104
1105 // Small loop for matrix equilibration (gives a better conditioning)
1106
1107 for (i=0; i<n; i++)
1108 {
1109 for (j=0; j<n; j++)
1110 {
1111 if (fabs(v[i][j]) >= r[i]) r[i] = fabs(v[i][j]); // Max elemt of row i
1112 if (fabs(v[j][i]) >= c[i]) c[i] = fabs(v[j][i]); // Max elemt of column i
1113 }
1114 }
1115
1116 for (i=0; i<n; i++)
1117 {
1118 if (0.0 != r[i]) r[i] = 1./r[i]; // Max elemt of row i
1119 if (0.0 != c[i]) c[i] = 1./c[i]; // Max elemt of column i
1120
1121 // if (eps >= r[i]) r[i] = 0.0; // Max elemt of row i
1122 // if (eps >= c[i]) c[i] = 0.0; // Max elemt of column i
1123 }
1124
1125 for (i=0; i<n; i++) // Equilibrate the V matrix
1126 {
1127 for (j=0; j<n; j++) {v[i][j] = sqrt(r[i])*v[i][j]*sqrt(c[j]);}
1128 }
1129
1130 nrank = 0;
1131
1132 // save diagonal elem absolute values
1133 for (i=0; i<n; i++) {diag[i] = fabs(v[i][i]);}
1134
1135 for (i=0; i<n; i++)
1136 {
1137 vkk = 0.0;
1138 k = -1;
1139
1140 for (j=0; j<n; j++) // First look for the pivot, ie max unused diagonal element
1141 {
1142 if (flag[j] && (fabs(v[j][j])>std::max(fabs(vkk),eps*diag[j])))
1143 {
1144 vkk = v[j][j];
1145 k = j;
1146 }
1147 }
1148
1149 if (k >= 0) // pivot found
1150 {
1151 if (verbose_mode) cout << "Pivot value :" << vkk << endl;
1152 nrank++;
1153 flag[k] = false; // This value is used
1154 vkk = 1.0/vkk;
1155 v[k][k] = -vkk; // Replace pivot by its inverse
1156
1157 for (j=0; j<n; j++)
1158 {
1159 for (jj=0; jj<n; jj++)
1160 {
1161 if (j != k && jj != k) // Other elements (!!! do them first as you use old v[k][j]'s !!!)
1162 {
1163 v[j][jj] = v[j][jj] - vkk*v[j][k]*v[k][jj];
1164 }
1165 }
1166 }
1167
1168 for (j=0; j<n; j++)
1169 {
1170 if (j != k) // Pivot row or column elements
1171 {
1172 v[j][k] = (v[j][k])*vkk; // Column
1173 v[k][j] = (v[k][j])*vkk; // Line
1174 }
1175 }
1176 }
1177 else // No more pivot value (clear those elements)
1178 {
1179 for (j=0; j<n; j++)
1180 {
1181 if (flag[j])
1182 {
1183 b[j] = 0.0;
1184
1185 for (k=0; k<n; k++)
1186 {
1187 v[j][k] = 0.0;
1188 v[k][j] = 0.0;
1189 }
1190 }
1191 }
1192
1193 break; // No more pivots anyway, stop here
1194 }
1195 }
1196
1197 for (i=0; i<n; i++) // Correct matrix V
1198 {
1199 for (j=0; j<n; j++) {v[i][j] = sqrt(c[i])*v[i][j]*sqrt(r[j]);}
1200 }
1201
1202 for (j=0; j<n; j++)
1203 {
1204 temp[j] = 0.0;
1205
1206 for (jj=0; jj<n; jj++) // Reverse matrix elements
1207 {
1208 v[j][jj] = -v[j][jj];
1209 temp[j] += v[j][jj]*b[jj];
1210 }
1211 }
1212
1213 for (j=0; j<n; j++) {b[j] = temp[j];} // The final result
1214
1215 delete temp;
1216 delete r;
1217 delete c;
1218
1219 return nrank;
1220}
1221
1222//
1223// Same method but for local fit, so heavily simplified
1224//
1225
1226
1227int Millepede::SpmInv(double v[][mlocal], double b[], int n, double diag[], bool flag[])
1228{
1229 int i, j, jj, k;
1230 double vkk, *temp;
1231 double eps = 0.0000000000001;
1232
1233 temp = new double[n];
1234
1235 for (i=0; i<n; i++)
1236 {
1237 flag[i] = true;
1238 diag[i] = fabs(v[i][i]); // save diagonal elem absolute values
1239
1240 for (j=0; j<=i; j++)
1241 {
1242 v[j][i] = v[i][j] ;
1243 }
1244 }
1245
1246 nrank = 0;
1247
1248 for (i=0; i<n; i++)
1249 {
1250 vkk = 0.0;
1251 k = -1;
1252
1253 for (j=0; j<n; j++) // First look for the pivot, ie max unused diagonal element
1254 {
1255 if (flag[j] && (fabs(v[j][j])>std::max(fabs(vkk),eps*diag[j])))
1256 {
1257 vkk = v[j][j];
1258 k = j;
1259 }
1260 }
1261
1262 if (k >= 0) // pivot found
1263 {
1264 nrank++;
1265 flag[k] = false;
1266 vkk = 1.0/vkk;
1267 v[k][k] = -vkk; // Replace pivot by its inverse
1268
1269 for (j=0; j<n; j++)
1270 {
1271 for (jj=0; jj<n; jj++)
1272 {
1273 if (j != k && jj != k) // Other elements (!!! do them first as you use old v[k][j]'s !!!)
1274 {
1275 v[j][jj] = v[j][jj] - vkk*v[j][k]*v[k][jj];
1276 }
1277 }
1278 }
1279
1280 for (j=0; j<n; j++)
1281 {
1282 if (j != k) // Pivot row or column elements
1283 {
1284 v[j][k] = (v[j][k])*vkk; // Column
1285 v[k][j] = (v[k][j])*vkk; // Line
1286 }
1287 }
1288 }
1289 else // No more pivot value (clear those elements)
1290 {
1291 for (j=0; j<n; j++)
1292 {
1293 if (flag[j])
1294 {
1295 b[j] = 0.0;
1296
1297 for (k=0; k<n; k++)
1298 {
1299 v[j][k] = 0.0;
1300 }
1301 }
1302 }
1303
1304 break; // No more pivots anyway, stop here
1305 }
1306 }
1307
1308 for (j=0; j<n; j++)
1309 {
1310 temp[j] = 0.0;
1311
1312 for (jj=0; jj<n; jj++) // Reverse matrix elements
1313 {
1314 v[j][jj] = -v[j][jj];
1315 temp[j] += v[j][jj]*b[jj];
1316 }
1317 }
1318
1319 for (j=0; j<n; j++)
1320 {
1321 b[j] = temp[j];
1322 }
1323
1324 delete temp;
1325
1326 return nrank;
1327}
1328
1329
1330/*
1331 -----------------------------------------------------------
1332 SPAVAT
1333 -----------------------------------------------------------
1334
1335 multiply symmetric N-by-N matrix from the left with general M-by-N
1336 matrix and from the right with the transposed of the same general
1337 matrix to form symmetric M-by-M matrix.
1338
1339 T
1340 CALL SPAVAT(V,A,W,N,M) W = A * V * A
1341 M*M M*N N*N N*M
1342
1343 where V = symmetric N-by-N matrix
1344 A = general N-by-M matrix
1345 W = symmetric M-by-M matrix
1346 -----------------------------------------------------------
1347*/
1348
1349
1350bool Millepede::SpAVAt(double v[][mlocal], double a[][mlocal], double w[][mglobl], int n, int m)
1351{
1352 int i,j, k, l;
1353
1354 for (i=0; i<m; i++)
1355 {
1356 for (j=0; j<m; j++) // Could be improved as matrix symmetric
1357 {
1358 w[i][j] = 0.0; // Reset final matrix
1359
1360 for (k=0; k<n; k++)
1361 {
1362 for (l=0; l<n; l++)
1363 {
1364 w[i][j] += a[i][k]*v[k][l]*a[j][l]; // fill the matrix
1365 }
1366 }
1367 }
1368 }
1369
1370 return true;
1371}
1372
1373
1374/*
1375 -----------------------------------------------------------
1376 SPAX
1377 -----------------------------------------------------------
1378
1379 multiply general M-by-N matrix A and N-vector X
1380
1381 CALL SPAX(A,X,Y,M,N) Y = A * X
1382 M M*N N
1383
1384 where A = general M-by-N matrix (A11 A12 ... A1N A21 A22 ...)
1385 X = N vector
1386 Y = M vector
1387 -----------------------------------------------------------
1388*/
1389
1390bool Millepede::SpAX(double a[][mlocal], double x[], double y[], int n, int m)
1391{
1392 int i,j;
1393
1394 for (i=0; i<m; i++)
1395 {
1396 y[i] = 0.0; // Reset final vector
1397
1398 for (j=0; j<n; j++)
1399 {
1400 y[i] += a[i][j]*x[j]; // fill the vector
1401 }
1402 }
1403
1404 return true;
1405}
1406
1407
1408/*
1409 -----------------------------------------------------------
1410 PRTGLO
1411 -----------------------------------------------------------
1412
1413 Print the final results into the logfile
1414
1415 -----------------------------------------------------------
1416*/
1417
1418
1419bool Millepede::PrtGlo()
1420{
1421 double err, gcor;
1422
1423 cout << "" << endl;
1424 cout << " Result of fit for global parameters" << endl;
1425 cout << " ===================================" << endl;
1426 cout << " I initial final differ "
1427 << " lastcor Error gcor" << endl;
1428 cout << "-----------------------------------------"
1429 << "------------------------------------------" << endl;
1430
1431 for (int i=0; i<nagb; i++)
1432 {
1433 err = sqrt(fabs(cgmat[i][i]));
1434 if (cgmat[i][i] < 0.0) err = -err;
1435 gcor = 0.0;
1436
1437 if (i%(nagb/6) == 0)
1438 {
1439 cout << "-----------------------------------------"
1440 << "------------------------------------------" << endl;
1441 }
1442
1443// cout << "cgmat[" << i << "][" << i << "] = " << cgmat[i][i];
1444// cout << " diag[" << i << "] = " << diag[i] << endl;
1445 if (fabs(cgmat[i][i]*diag[i]) > 0)
1446 {
1447 cout << std::setprecision(4) << std::fixed;
1448 gcor = sqrt(fabs(1.0-1.0/(cgmat[i][i]*diag[i])));
1449 cout << std::setw(4) << i << " / " << std::setw(10) << pparm[i]
1450 << " / " << std::setw(10) << pparm[i]+ dparm[i]
1451 << " / " << std::setw(13) << dparm[i]
1452 << " / " << std::setw(13) << bgvec[i] << " / " << std::setw(10)
1453 << std::setprecision(5) << err << " / " << std::setw(10) << gcor << endl;
1454 }
1455 else
1456 {
1457 cout << std::setw(4) << i << " / " << std::setw(10) << "OFF"
1458 << " / " << std::setw(10) << "OFF"
1459 << " / " << std::setw(13) << "OFF"
1460 << " / " << std::setw(13) << "OFF"
1461 << " / " << std::setw(10) << "OFF"
1462 << " / " << std::setw(10) << "OFF" << endl;
1463 }
1464 }
1465 return true;
1466}
1467
1468
1469/*
1470 ----------------------------------------------------------------
1471 CHINDL: return the limit in chi^2/nd for n sigmas stdev authorized
1472 ----------------------------------------------------------------
1473
1474 Only n=1, 2, and 3 are expected in input
1475 ----------------------------------------------------------------
1476*/
1477
1478double Millepede::chindl(int n, int nd)
1479{
1480 int m;
1481 double sn[3] = {0.47523, 1.690140, 2.782170};
1482 double table[3][30] = {{1.0000, 1.1479, 1.1753, 1.1798, 1.1775, 1.1730, 1.1680, 1.1630,
1483 1.1581, 1.1536, 1.1493, 1.1454, 1.1417, 1.1383, 1.1351, 1.1321,
1484 1.1293, 1.1266, 1.1242, 1.1218, 1.1196, 1.1175, 1.1155, 1.1136,
1485 1.1119, 1.1101, 1.1085, 1.1070, 1.1055, 1.1040},
1486 {4.0000, 3.0900, 2.6750, 2.4290, 2.2628, 2.1415, 2.0481, 1.9736,
1487 1.9124, 1.8610, 1.8171, 1.7791, 1.7457, 1.7161, 1.6897, 1.6658,
1488 1.6442, 1.6246, 1.6065, 1.5899, 1.5745, 1.5603, 1.5470, 1.5346,
1489 1.5230, 1.5120, 1.5017, 1.4920, 1.4829, 1.4742},
1490 {9.0000, 5.9146, 4.7184, 4.0628, 3.6410, 3.3436, 3.1209, 2.9468,
1491 2.8063, 2.6902, 2.5922, 2.5082, 2.4352, 2.3711, 2.3143, 2.2635,
1492 2.2178, 2.1764, 2.1386, 2.1040, 2.0722, 2.0428, 2.0155, 1.9901,
1493 1.9665, 1.9443, 1.9235, 1.9040, 1.8855, 1.8681}};
1494
1495 if (nd < 1)
1496 {
1497 return 0.0;
1498 }
1499 else
1500 {
1501 m = std::max(1,std::min(n,3));
1502
1503 if (nd <= 30)
1504 {
1505 return table[m-1][nd-1];
1506 }
1507 else // approximation
1508 {
1509 return ((sn[m-1]+sqrt(float(2*nd-3)))*(sn[m-1]+sqrt(float(2*nd-3))))/float(2*nd-2);
1510 }
1511 }
1512}
1513
1514
1515int Millepede::GetTrackNumber() {return m_track_number;}
1516void Millepede::SetTrackNumber(int value) {m_track_number = value;}
const Int_t n
Double_t x[10]
EvtTensor3C eps(const EvtVector3R &v)
Definition: EvtTensor3C.cc:307
**********Class see also m_nmax DOUBLE PRECISION m_amel DOUBLE PRECISION m_x2 DOUBLE PRECISION m_alfinv DOUBLE PRECISION m_Xenph INTEGER m_KeyWtm INTEGER m_idyfs DOUBLE PRECISION m_zini DOUBLE PRECISION m_q2 DOUBLE PRECISION m_Wt_KF DOUBLE PRECISION m_WtCut INTEGER m_KFfin *COMMON c_KarLud $ !Input CMS energy[GeV] $ !CMS energy after beam spread beam strahlung[GeV] $ !Beam energy spread[GeV] $ !z boost due to beam spread $ !electron beam mass *ff pair spectrum $ !minimum v
Definition: KarLud.h:35
bool InitMille(bool DOF[], double Sigm[], int nglo, int nloc, double startfact, int nstd, double res_cut, double res_cut_init)
Definition: Millepede.cxx:46
void SetTrackNumber(int value)
Definition: Millepede.cxx:1516
bool ZerLoc(double dergb[], double derlc[], double dernl[])
Definition: Millepede.cxx:388
bool EquLoc(double dergb[], double derlc[], double dernl[], double rmeas, double sigma)
Definition: Millepede.cxx:293
bool MakeGlobalFit(double par[], double error[], double pull[])
Definition: Millepede.cxx:814
bool ParGlo(int index, double param)
Definition: Millepede.cxx:182
bool FitLoc(int n, double track_params[], int single_fit)
Definition: Millepede.cxx:418
int GetTrackNumber()
Definition: Millepede.cxx:1515
bool ParSig(int index, double sigma)
Definition: Millepede.cxx:209
~Millepede()
Destructor.
Definition: Millepede.cxx:29
Millepede()
Standard constructor.
Definition: Millepede.cxx:24
bool ConstF(double dercs[], double rhs)
Definition: Millepede.cxx:263