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