// Include files // local #include "Millepede.h" #include #include #include #include "math.h" //----------------------------------------------------------------------------- // Implementation file for class : Millepede // // 2005-07-29 : Sebastien Viret //----------------------------------------------------------------------------- using namespace std; //============================================================================= // Standard constructor, initializes variables //============================================================================= Millepede::Millepede():indst(0),arest(0),arenl(0),storeind(0),storeplace(0),storeare(0),storenl(0) {} //============================================================================= // Destructor //============================================================================= Millepede::~Millepede() {}; //============================================================================= /* ------------------------------------------------------ INITMILLE: first initialization of Millepede this part is sub-detector independant ------------------------------------------------------ ------------------------------------------------------ */ bool Millepede::InitMille(bool DOF[], double Sigm[], int nglo , int nloc, double startfact, int nstd , double res_cut, double res_cut_init) { cout << " " << endl; cout << " * o o o " << endl; cout << " o o o " << endl; cout << " o ooooo o o o oo ooo oo ooo oo " << endl; cout << " o o o o o o o o o o o o o o o o " << endl; cout << " o o o o o o oooo o o oooo o o oooo " << endl; cout << " o o o o o o o ooo o o o o " << endl; cout << " o o o o o o oo o oo ooo oo ++ starts" << endl; cout << " " << endl; if (debug_mode) cout << "" << endl; if (debug_mode) cout << "----------------------------------------------------" << endl; if (debug_mode) cout << "" << endl; if (debug_mode) cout << " Entering InitMille" << endl; if (debug_mode) cout << "" << endl; if (debug_mode) cout << "-----------------------------------------------------" << endl; if (debug_mode) cout << "" << endl; ncs = 0; loctot = 0; // Total number of local fits locrej = 0; // Total number of local fits rejected cfactref = 1.0; // Reference value for Chi^2/ndof cut // cfactref = 2.0; // Reference value for Chi^2/ndof cut Millepede::SetTrackNumber(0); // Number of local fits (starts at 0) m_residual_cut = res_cut; m_residual_cut_init = res_cut_init; nagb = 6*nglo; // Number of global derivatives nalc = nloc; // Number of local derivatives nstdev = nstd; // Number of StDev for local fit chisquare cut if (debug_mode) cout << "Number of global parameters : " << nagb << endl; if (debug_mode) cout << "Number of local parameters : " << nalc << endl; if (debug_mode) cout << "Number of standard deviations : " << nstdev << endl; if (nagb>mglobl || nalc>mlocal) { if (debug_mode) cout << "Two many parameters !!!!!" << endl; return false; } // All parameters initializations for (int i=0; i=nagb) {return false;} else {pparm[index] = param;} cout << "Fix param " << index << " to the value " << param << endl; return true; } /* ----------------------------------------------------------- PARSIG: define a constraint for a single global param param is 'encouraged' to vary within [-sigma;sigma] range ----------------------------------------------------------- index = the index of the global parameter in the result array (equivalent to dparm[]). sigma = value of the constraint (sigma <= 0. will mean that parameter is FIXED !!!) ----------------------------------------------------------- */ bool Millepede::ParSig(int index, double sigma) { if (index>=nagb) {return false;} else {psigm[index] = sigma;} return true; } /* ----------------------------------------------------------- INITUN: unit for iteration ----------------------------------------------------------- cutfac is used by Fitloc to define the Chi^2/ndof cut value A large cutfac value enables to take a wider range of tracks for first iterations, which might be useful if misalignments are large. As soon as cutfac differs from 0 iteration are requested. cutfac is then reduced, from one iteration to the other, and iterations are stopped when it reaches the value 1. At least one more iteration is often needed in order to remove tracks containing outliers. ----------------------------------------------------------- */ bool Millepede::InitUn(double cutfac) { cfactr = std::max(1.0, cutfac); cout << "Initial cut factor is " << cfactr << endl; itert = 1; // Initializes the iteration process return true; } /* ----------------------------------------------------------- CONSTF: define a constraint equation in Millepede ----------------------------------------------------------- dercs = the row containing constraint equation derivatives (put into the final matrix) rhs = the lagrange multiplier value (sum of equation) ----------------------------------------------------------- */ bool Millepede::ConstF(double dercs[], double rhs) { if (ncs>=mcs) // mcs is defined in Millepede.h { cout << "Too many constraints !!!" << endl; return false; } for (int i=0; i= m_residual_cut_init && itert <= 1) { if (verbose_mode) cout << "Rejected track !!!!!" << endl; locrej++; indst.clear(); // reset stores and go to the next track arest.clear(); return false; } if (fabs(rmeas) >= m_residual_cut && itert > 1) { if (verbose_mode){ cout<<"fabs(rmeas) = "<= "< 0) rms = summ/float(ndf); // Chi^2/dof if (single_fit == 0) loctot++; if (nstdev != 0 && ndf > 0 && single_fit != 1) // Chisquare cut { cutval = Millepede::chindl(nstdev, ndf)*cfactr; if (debug_mode) cout << "Reject if Chisq/Ndf = " << rms << " > " << cutval << endl; if (rms > cutval) // Reject the track if too much... { if (verbose_mode) cout << "Rejected track !!!!!" << endl; if (single_fit == 0) locrej++; indst.clear(); // reset stores and go to the next track arest.clear(); return false; } } if (single_fit == 1) // Stop here if just updating the track parameters { indst.clear(); // Reset store for the next track arest.clear(); return true; } // Store the track number of DOFs (for the final chisquare estimation) track_params[2*nalc] = float(ndf); track_params[2*nalc+1] = summ; // // THIRD LOOP: local operations are finished, track is accepted // We now update the global parameters (other matrices) // ist = 0; ja = -1; jb = 0; while (ist <= nst) { if (indst[ist] == -1) { if (ja == -1) {ja = ist;} // First 0 : rmeas else if (jb == 0) {jb = ist;} // Second 0 : weight else // Third 0 : end of equation { rmeas = arest[ja]; wght = arest[jb]; for (int i=(jb+1); i local_params; local_params.resize(mlocal*ntotal_start); for (int i=0; i " << itert << endl; ntotal = Millepede::GetTrackNumber(); cout << "...using " << ntotal << " tracks..." << endl; final_cor = 0.0; final_chi2 = 0.0; final_ndof = 0.0; // Start by saving the diagonal elements for (int i=0; i 0) // Then the constraint equation { for (int i=0; i 1.2*cfactref) { cfactr = sqrt(cfactr); } else { cfactr = cfactref; // itert = itelim; } if (itert == itelim) break; // End of story cout << "Iteration " << itert << " with cut factor " << cfactr << endl; // Reset global variables for (int i=0; i0) ? rank_i = abs(storeplace[i-1]) : rank_i = 0; rank_f = storeplace[i]; if (debug_mode) cout << "Track " << i << " : " << endl; if (debug_mode) cout << "Starts at " << rank_i << endl; if (debug_mode) cout << "Ends at " << rank_f << endl; if (rank_f >= 0) // Fit is still OK { indst.clear(); arest.clear(); for (int j=rank_i; j= r[i]) r[i] = fabs(v[i][j]); // Max elemt of row i if (fabs(v[j][i]) >= c[i]) c[i] = fabs(v[j][i]); // Max elemt of column i } } for (int i=0; i= r[i]) r[i] = 0.0; // Max elemt of row i not wihin requested precision if (eps >= c[i]) c[i] = 0.0; // Max elemt of column i not wihin requested precision } for (int i=0; istd::max(fabs(vkk),eps*diag[j]))) { vkk = v[j][j]; k = j; } } if (k >= 0) // pivot found { nrank++; flag[k] = false; vkk = 1.0/vkk; v[k][k] = -vkk; // Replace pivot by its inverse for (int j=0; j 0) { cout << std::setprecision(4) << std::fixed; gcor = sqrt(fabs(1.0-1.0/(cgmat[i][i]*diag[i]))); cout << std::setw(4) << i << " / " << std::setw(10) << pparm[i] << " / " << std::setw(10) << pparm[i]+ dparm[i] << " / " << std::setw(13) << dparm[i] << " / " << std::setw(13) << bgvec[i] << " / " << std::setw(10) << std::setprecision(5) << err << " / " << std::setw(10) << gcor << endl; } else { cout << std::setw(4) << i << " / " << std::setw(10) << "OFF" << " / " << std::setw(10) << "OFF" << " / " << std::setw(13) << "OFF" << " / " << std::setw(13) << "OFF" << " / " << std::setw(10) << "OFF" << " / " << std::setw(10) << "OFF" << endl; } } return true; } /* ---------------------------------------------------------------- CHINDL: return the limit in chi^2/nd for n sigmas stdev authorized ---------------------------------------------------------------- Only n=1, 2, and 3 are expected in input ---------------------------------------------------------------- */ double Millepede::chindl(int n, int nd) { int m; double sn[3] = {0.47523, 1.690140, 2.782170}; double table[3][30] = {{1.0000, 1.1479, 1.1753, 1.1798, 1.1775, 1.1730, 1.1680, 1.1630, 1.1581, 1.1536, 1.1493, 1.1454, 1.1417, 1.1383, 1.1351, 1.1321, 1.1293, 1.1266, 1.1242, 1.1218, 1.1196, 1.1175, 1.1155, 1.1136, 1.1119, 1.1101, 1.1085, 1.1070, 1.1055, 1.1040}, {4.0000, 3.0900, 2.6750, 2.4290, 2.2628, 2.1415, 2.0481, 1.9736, 1.9124, 1.8610, 1.8171, 1.7791, 1.7457, 1.7161, 1.6897, 1.6658, 1.6442, 1.6246, 1.6065, 1.5899, 1.5745, 1.5603, 1.5470, 1.5346, 1.5230, 1.5120, 1.5017, 1.4920, 1.4829, 1.4742}, {9.0000, 5.9146, 4.7184, 4.0628, 3.6410, 3.3436, 3.1209, 2.9468, 2.8063, 2.6902, 2.5922, 2.5082, 2.4352, 2.3711, 2.3143, 2.2635, 2.2178, 2.1764, 2.1386, 2.1040, 2.0722, 2.0428, 2.0155, 1.9901, 1.9665, 1.9443, 1.9235, 1.9040, 1.8855, 1.8681}}; if (nd < 1) { return 0.0; } else { m = std::max(1,std::min(n,3)); if (nd <= 30) { return table[m-1][nd-1]; } else // approximation { return ((sn[m-1]+sqrt(float(2*nd-3)))*(sn[m-1]+sqrt(float(2*nd-3))))/float(2*nd-2); } } } int Millepede::GetTrackNumber() {return m_track_number;} void Millepede::SetTrackNumber(int value) {m_track_number = value;}