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