CMS 3D CMS Logo

MuonErrorMatrix.cc

Go to the documentation of this file.
00001 #include "RecoMuon/TrackingTools/interface/MuonErrorMatrix.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 #include "FWCore/ParameterSet/interface/FileInPath.h"
00004 
00005 #include "TROOT.h"
00006 #include "TString.h"
00007 #include "TRandom2.h"
00008 #include "TMath.h"
00009 
00010 #include <sstream>
00011 
00012 using namespace std;
00013 
00014 const TString MuonErrorMatrix::vars[5]={"#frac{q}{|p|}","#lambda","#varphi_{0}","X_{T}","Y_{T}"};
00015 
00016 MuonErrorMatrix::MuonErrorMatrix(const edm::ParameterSet & iConfig):theD(0){
00017   theCategory="MuonErrorMatrix";
00018   std::string action = iConfig.getParameter<std::string>("action");
00019 
00020   bool madeFromCff=iConfig.exists("errorMatrixValuesPSet");
00021   edm::ParameterSet errorMatrixValuesPSet;
00022 
00023   std::string fileName;
00024   if (!madeFromCff){ fileName = iConfig.getParameter<std::string>("rootFileName");}
00025   else { errorMatrixValuesPSet =iConfig.getParameter<edm::ParameterSet>("errorMatrixValuesPSet");}
00026   MuonErrorMatrix::action a= use;
00027 
00028    int NPt=5;
00029    std::vector<double> xBins;
00030    double * xBinsArray = 0;
00031    double minPt=1;
00032    double maxPt=200;
00033    int NEta=5;
00034    std::vector<double> yBins;
00035    double * yBinsArray =0;
00036    double minEta=0;
00037    double maxEta=2.5;
00038    int NPhi=1;
00039    double minPhi=-TMath::Pi();
00040    double maxPhi=TMath::Pi();
00041 
00042   if (action!="use"){
00043     a = constructor;
00044     
00045     NPt = iConfig.getParameter<int>("NPt");
00046     if (NPt!=0){
00047       minPt = iConfig.getParameter<double>("minPt");
00048       maxPt = iConfig.getParameter<double>("maxPt");}
00049     else{
00050       xBins = iConfig.getParameter<std::vector<double> >("PtBins");
00051       if (xBins.size()==0){edm::LogError( theCategory)<<"Npt=0 and no entries in the vector. I will do aseg fault soon.";}
00052       NPt = xBins.size()-1;
00053       xBinsArray = &(xBins.front());
00054       minPt = xBins.front();
00055       maxPt = xBins.back();}
00056 
00057     NEta = iConfig.getParameter<int>("NEta");
00058     if (NEta!=0){
00059       minEta = iConfig.getParameter<double>("minEta");
00060       maxEta = iConfig.getParameter<double>("maxEta");}
00061     else{
00062       yBins = iConfig.getParameter<std::vector<double> >("EtaBins");
00063       if (yBins.size()==0){edm::LogError( theCategory)<<"NEta=0 and no entries in the vector. I will do aseg fault soon.";}
00064       NEta = yBins.size()-1;
00065       yBinsArray = &(yBins.front());
00066       minPt = yBins.front();
00067       maxPt = yBins.back();}
00068 
00069     NPhi = iConfig.getParameter<int>("NPhi");
00070     std::stringstream get(iConfig.getParameter<std::string>("minPhi"));
00071     if (get.str() =="-Pi")
00072       { minPhi =-TMath::Pi();}
00073     else if(get.str() =="Pi")
00074       { minPhi =TMath::Pi();}
00075     else { get>>minPhi;}
00076     get.str(iConfig.getParameter<std::string>("maxPhi"));
00077         if (get.str() =="-Pi")
00078       { maxPhi =-TMath::Pi();}
00079     else if(get.str() =="Pi")
00080       { maxPhi =TMath::Pi();}
00081     else { get>>maxPhi;}
00082   }//action!=use
00083   else if (madeFromCff){
00084 
00085     xBins = errorMatrixValuesPSet.getParameter<std::vector<double> >("xAxis");
00086     NPt = xBins.size()-1;
00087     xBinsArray = &(xBins.front());
00088     minPt = xBins.front();
00089     maxPt = xBins.back();
00090     
00091     yBins = errorMatrixValuesPSet.getParameter<std::vector<double> >("yAxis");
00092     NEta = yBins.size()-1;
00093     yBinsArray = &(yBins.front());
00094     minPt = yBins.front();
00095     maxPt = yBins.back();
00096 
00097     std::vector<double> zBins = errorMatrixValuesPSet.getParameter<std::vector<double> >("zAxis");
00098     NPhi=1;
00099     if (zBins.size()!=2){
00100       edm::LogError(theCategory)<<"please specify a zAxis with 2 entries only. more bins not implemented yet.";}
00101     minPhi=zBins.front();
00102     maxPhi=zBins.back();
00103 
00104   }
00105 
00106   if (a==use){
00107     if (!madeFromCff){
00108       edm::LogInfo(theCategory)<<"using an error matrix object from: "<<fileName;
00109       edm::FileInPath data(fileName);
00110       std::string fullpath = data.fullPath();
00111       gROOT->cd();
00112       theD = new TFile(fullpath.c_str());
00113       theD->SetWritable(false);
00114     }else{
00115       static uint neverTheSame=0;
00116       std::stringstream dirName("MuonErrorMatrixDirectory");
00117       dirName<<neverTheSame++;
00118       edm::LogInfo(theCategory)<<"using an error matrix object from configuration file. putting memory histograms to: "<<dirName.str();
00119       gROOT->cd();
00120       theD = new TDirectory(dirName.str().c_str(),"transient directory to host MuonErrorMatrix TProfile3D");
00121       theD->SetWritable(false);
00122     }
00123   }
00124   else{
00125     edm::LogInfo(theCategory)<<"creating  an error matrix object: "<<fileName;
00126     theD = new TFile(fileName.c_str(),"recreate");
00127   }
00128 
00129   if (a==use && !madeFromCff ){gROOT->cd();}
00130   else {theD->cd();}
00131 
00132   for (int i=0;i!=5;i++){for (int j=i;j!=5;j++){
00133       TString pfname(Form("pf3_V%1d%1d",i+1,j+1));
00134       TProfile3D * pf =0;
00135       if (a==use && !madeFromCff ){
00136         //read from the rootfile
00137         edm::LogVerbatim(theCategory)<<"getting "<<pfname<<" from "<<fileName;
00138         pf = (TProfile3D *)theD->Get(pfname);
00139         theData[Pindex(i,j)]=pf;
00140         theData_fast[i][j]=pf;    theData_fast[j][i]=pf;
00141       }
00142       else{
00143         //        curvilinear coordinate system
00144         //need to make some input parameter to be to change the number of bins
00145 
00146         TString pftitle;
00147         if (i==j){pftitle="#sigma_{"+vars[i]+"}";}
00148         else{pftitle="#rho("+vars[i]+","+vars[j]+")";}
00149         edm::LogVerbatim(theCategory)<<"booking "<<pfname<<" into "<<fileName;
00150         pf = new TProfile3D(pfname,pftitle,NPt,minPt,maxPt,NEta,minEta,maxEta,NPhi,minPhi,maxPhi,"S");      
00151         pf->SetXTitle("muon p_{T} [GeV]");
00152         pf->SetYTitle("muon |#eta|");
00153         pf->SetZTitle("muon #varphi");
00154 
00155         //set variable size binning
00156         if (xBinsArray){
00157           pf->GetXaxis()->Set(NPt,xBinsArray);}
00158         if (yBinsArray){
00159           pf->GetYaxis()->Set(NEta,yBinsArray);}
00160 
00161         if (madeFromCff){
00162           edm::ParameterSet pSet = errorMatrixValuesPSet.getParameter<edm::ParameterSet>(pfname.Data());
00163           //set the values from the configuration file itself
00164           std::vector<double> values = pSet.getParameter<std::vector<double> >("values");
00165           unsigned int iX=pf->GetNbinsX();
00166           unsigned int iY=pf->GetNbinsY();
00167           unsigned int iZ=pf->GetNbinsZ();
00168           uint continuous_i=0;
00169           for(unsigned int ix=1;ix<=iX;++ix){
00170             for(unsigned int iy=1;iy<=iY;++iy){
00171               for(unsigned int iz=1;iz<=iZ;++iz){
00172                 pf->Fill(pf->GetXaxis()->GetBinCenter(ix),
00173                          pf->GetYaxis()->GetBinCenter(iy),
00174                          pf->GetZaxis()->GetBinCenter(iz),
00175                          values[continuous_i++]);
00176               }}}
00177         }
00178       }
00179 
00180       LogDebug(theCategory)<<" index "<<i<<":"<<j<<" -> "<<Pindex(i,j);
00181       theData[Pindex(i,j)]=pf;
00182       theData_fast[i][j]=pf;      theData_fast[j][i]=pf;
00183       if (!pf){
00184         edm::LogError(theCategory)<<" profile "<<pfname<<" in file "<<fileName<<" is not valid. exiting.";
00185         exit(1);
00186       }
00187     }}
00188     
00189   //verify it
00190   for (int i=0;i!=15;i++){ 
00191     if (theData[i]) {edm::LogVerbatim(theCategory)<<i<<" :"<<theData[i]->GetName()
00192                                                   <<" "<< theData[i]->GetTitle()<<std::endl;}}
00193  
00194 }
00195 
00196 //void MuonErrorMatrix::writeIntoCFF(){}
00197 
00198 void MuonErrorMatrix::close(){
00199   //close the file
00200   if (theD){
00201     theD->cd();
00202     //write to it first if constructor
00203     if (theD->IsWritable()){
00204       for (int i=0;i!=15;i++){ if (theData[i]) { theData[i]->Write();}}}
00205     theD->Close();
00206   }}
00207 
00208 MuonErrorMatrix::~MuonErrorMatrix()  {
00209   close();
00210 }
00211 
00212 
00213 
00214 CurvilinearTrajectoryError MuonErrorMatrix::get(GlobalVector momentum)  {
00215   AlgebraicSymMatrix55 V;
00216   for (int i=0;i!=5;i++){for (int j=i;j!=5;j++){
00217       V(i,j) = Value(momentum,i,j);}}
00218   return CurvilinearTrajectoryError(V);}
00219 
00220 CurvilinearTrajectoryError MuonErrorMatrix::getFast(GlobalVector momentum) {
00221   //will be faster but make assumptions that could be broken at some point
00222   //  same bining for all TProfile
00223   AlgebraicSymMatrix55 V;
00224 
00225   double pT = momentum.perp();
00226   double eta = fabs(momentum.eta());
00227   double phi = momentum.phi();
00228 
00229   //assume all the same axis in X,Y,Z
00230   int iBin_x= findBin(theData_fast[0][0]->GetXaxis(),pT);
00231   int iBin_y= findBin(theData_fast[0][0]->GetYaxis(),eta);
00232   int iBin_z= findBin(theData_fast[0][0]->GetZaxis(),phi);
00233 
00234   //retreive values
00235   double values[5][5]; //sigma_i and rho_ij
00236   for (int i=0;i!=5;i++){for (int j=i;j!=5;j++){
00237       values[i][j]=theData_fast[i][j]->GetBinContent(iBin_x, iBin_y, iBin_z);
00238     }}
00239 
00240   for (int i=0;i!=5;i++){for (int j=i;j!=5;j++){
00241       if (i==j){
00242         //sigma_i * sigma_i
00243         V(i,j) = values[i][j];
00244         V(i,j)*=V(i,j);
00245       }
00246       else{
00247         //sigma_i * sigma_j * rho_ij
00248         V(i,j) = values[i][i] * values[j][j] * values[i][j];
00249       }
00250     }}
00251 
00252   return CurvilinearTrajectoryError(V);}
00253 
00254 
00255 
00256 /*CurvilinearTrajectoryError MuonErrorMatrix::get_random(GlobalVector momentum)  { 
00257   static TRandom2 rand;
00258   AlgebraicSymMatrix55 V;//result
00259   //first proceed with diagonal elements
00260   for (int i=0;i!=5;i++){
00261   V(i,i)=rand.Gaus( Value(momentum,i,i), Rms(momentum,i,i));}
00262 
00263   //now proceed with the correlations
00264   for (int i=0;i!=5;i++){for (int j=i+1;j<5;j++){
00265       double corr = rand.Gaus( Value(momentum,i,j), Rms(momentum,i,j));
00266       //assign the covariance from correlation and sigmas
00267       V(i,j)= corr * sqrt( V[i][i] * V[j][j]);}}
00268       return CurvilinearTrajectoryError(V);  }
00269 */
00270 
00271 int MuonErrorMatrix::findBin(TAxis * axis, double value){
00272   //find the proper bin, protecting against under/over flow
00273   int result = axis->FindBin(value);
00274   if (result <= 0) result=1; //protect against under flow
00275   else if (result > axis->GetNbins() ) result = axis->GetNbins();
00276   return result;}
00277 
00278 
00279 double MuonErrorMatrix::Value(GlobalVector & momentum, int i, int j)  {
00280   double result=0;
00281   TProfile3D * ij = Index(i,j);
00282   if (!ij) {edm::LogError(theCategory)<<"cannot get the profile ("<<i<<":"<<j<<")"; return result;}
00283   
00284   double pT = momentum.perp();
00285   double eta = fabs(momentum.eta());
00286   double phi = momentum.phi();
00287 
00288   int iBin_x= findBin(ij->GetXaxis(),pT);
00289   int iBin_y= findBin(ij->GetYaxis(),eta);
00290   int iBin_z= findBin(ij->GetZaxis(),phi);
00291 
00292   if (i!=j){
00293     //return the covariance = correlation*sigma_1 *sigma_2;
00294     TProfile3D * ii = Index(i,i);
00295     TProfile3D * jj = Index(j,j);
00296     if (!ii){edm::LogError(theCategory)<<"cannot get the profile ("<<i<<":"<<i<<")"; return result;}
00297     if (!jj){edm::LogError(theCategory)<<"cannot get the profile ("<<j<<":"<<j<<")"; return result;}
00298 
00299 
00300     int iBin_i_x = findBin(ii->GetXaxis(),pT);
00301     int iBin_i_y = findBin(ii->GetYaxis(),eta);
00302     int iBin_i_z = findBin(ii->GetZaxis(),phi);
00303     int iBin_j_x = findBin(jj->GetXaxis(),pT);
00304     int iBin_j_y = findBin(jj->GetYaxis(),eta);
00305     int iBin_j_z = findBin(jj->GetZaxis(),phi);
00306 
00307     double corr = ij->GetBinContent(iBin_x,iBin_y,iBin_z);
00308     double sigma_1 = (ii->GetBinContent(iBin_i_x,iBin_i_y,iBin_i_z));
00309     double sigma_2 = (jj->GetBinContent(iBin_j_x,iBin_j_y,iBin_j_z));
00310 
00311     LogDebug(theCategory)<<"for: (pT,eta,phi)=("<<pT<<", "<<eta<<", "<<phi<<") nterms are"
00312                        <<"\nrho["<<i<<","<<j<<"]: "<<corr<<" ["<< iBin_x<<", "<<iBin_y<<", "<<iBin_z<<"]"
00313       //                       <<"\nsigma^2["<<i<<","<<i<<"]: "<< sigma2_1<<" ["<< iBin_i_x<<", "<<iBin_i_y<<", "<<iBin_i_z<<"]"
00314       //                       <<"\nsigma^2["<<j<<","<<j<<"]: "<< sigma2_2<<" ["<< iBin_i_x<<", "<<iBin_i_y<<", "<<iBin_i_z<<"]"
00315                        <<"\nsigma["<<i<<","<<i<<"]: "<< sigma_1
00316                        <<"\nsigma["<<j<<","<<j<<"]: "<< sigma_2;
00317     
00318     result=corr*sigma_1*sigma_2;
00319     LogDebug(theCategory)<<"for: (pT,eta,phi)=("<<pT<<", "<<eta<<", "<<phi<<") Covariance["<<i<<","<<j<<"] is: "<<result;
00320     return result;
00321   }
00322   else{
00323     //return the variance = sigma_1 **2
00324     //    result=ij->GetBinContent(iBin);
00325     result=ij->GetBinContent(iBin_x,iBin_y,iBin_z);
00326     result*=result;
00327     LogDebug(theCategory)<<"for: (pT,eta,phi)=("<<pT<<", "<<eta<<", "<<phi<<") sigma^2["<<i<<","<<j<<"] is: "<<result;
00328     return result;
00329   }
00330 }
00331 
00332 double MuonErrorMatrix::Rms(GlobalVector & momentum, int i, int j)  {
00333   double result=0;
00334   TProfile3D * ij = Index(i,j);
00335   if (!ij){edm::LogError(theCategory)<<"cannot get the profile ("<<i<<":"<<i<<")"; return result;} 
00336   double pT = momentum.perp();
00337   double eta = fabs(momentum.eta());
00338   double phi = momentum.phi();
00339   
00340   int iBin_x= ij->GetXaxis()->FindBin(pT);
00341   int iBin_y= ij->GetYaxis()->FindBin(eta);
00342   int iBin_z= ij->GetZaxis()->FindBin(phi);
00343   result=ij->GetBinError(iBin_x,iBin_y,iBin_z);
00344 
00345   LogDebug(theCategory)<<"for: (pT,eta,phi)=("<<pT<<", "<<eta<<", "<<phi<<") error["<<i<<","<<j<<"] is: "<<result;
00346   return result;
00347 }
00348 
00349 double MuonErrorMatrix::Term(const AlgebraicSymMatrix55 & curv, int i, int j){
00350   //return sigma or correlation factor
00351   double result=0;
00352   if (i==j){
00353     result = curv(i,j);
00354     if (result<0){
00355       //check validity of this guy
00356       edm::LogError("MuonErrorMatrix")<<"invalid term in the error matrix.\n sii: "<< result;
00357       return 0;}
00358     return sqrt(result);}
00359   else{
00360     double si = curv(i,i);
00361     double sj = curv(j,j);
00362 
00363     if (si<=0 || sj<=0){
00364       edm::LogError("MuonErrorMatrix")<<"invalid term in the error matrix.\n si: "
00365                                 <<si<<" sj: "<<sj<<". result will be corrupted\n"<<curv;
00366       return 0;}
00367 
00368     si=sqrt(si);
00369     sj=sqrt(sj);
00370     //check validity
00371 
00372     return result = curv(i,j)/(si*sj);}
00373   //by default
00374   return 0;
00375 }
00376 
00377 
00378 void MuonErrorMatrix::multiply(CurvilinearTrajectoryError & initial_error, const CurvilinearTrajectoryError & scale_error){
00379   //scale term by term the matrix
00380   const AlgebraicSymMatrix55 & scale_matrix=scale_error.matrix();
00381   AlgebraicSymMatrix55 revised_matrix = initial_error.matrix();
00382   // the true type of the matrix is such that [i][j] is the same memory object as [j][i]: looping i:0-5, j:0-5 double multiply the terms
00383   // need to loop only on i:0-5, j:i-5
00384   for(int i = 0;i!=5;i++){for(int j = i;j!=5;j++){
00385       revised_matrix(i,j)*=scale_matrix(i,j);
00386     }}
00387   initial_error = CurvilinearTrajectoryError(revised_matrix);
00388 }
00389 bool MuonErrorMatrix::divide(CurvilinearTrajectoryError & num_error, const CurvilinearTrajectoryError & denom_error){
00390   //divide term by term the matrix
00391   const AlgebraicSymMatrix55 & denom_matrix=denom_error.matrix();
00392   AlgebraicSymMatrix55 num_matrix = num_error.matrix();
00393   // the true type of the matrix is such that [i][j] is the same memory object as [j][i]: looping i:0-5, j:0-5 double multiply the terms
00394   // need to loop only on i:0-5, j:i-5
00395   for(int i = 0;i!=5;i++){for(int j = i;j!=5;j++){
00396       if (denom_matrix(i,j)==0) return false;
00397       num_matrix(i,j)/=denom_matrix(i,j);
00398     }}
00399   num_error = CurvilinearTrajectoryError(num_matrix);
00400   return true;
00401 }

Generated on Tue Jun 9 17:44:35 2009 for CMSSW by  doxygen 1.5.4