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 }
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
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
00144
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
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
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
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
00197
00198 void MuonErrorMatrix::close(){
00199
00200 if (theD){
00201 theD->cd();
00202
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
00222
00223 AlgebraicSymMatrix55 V;
00224
00225 double pT = momentum.perp();
00226 double eta = fabs(momentum.eta());
00227 double phi = momentum.phi();
00228
00229
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
00235 double values[5][5];
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
00243 V(i,j) = values[i][j];
00244 V(i,j)*=V(i,j);
00245 }
00246 else{
00247
00248 V(i,j) = values[i][i] * values[j][j] * values[i][j];
00249 }
00250 }}
00251
00252 return CurvilinearTrajectoryError(V);}
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 int MuonErrorMatrix::findBin(TAxis * axis, double value){
00272
00273 int result = axis->FindBin(value);
00274 if (result <= 0) result=1;
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
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
00314
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
00324
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
00351 double result=0;
00352 if (i==j){
00353 result = curv(i,j);
00354 if (result<0){
00355
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
00371
00372 return result = curv(i,j)/(si*sj);}
00373
00374 return 0;
00375 }
00376
00377
00378 void MuonErrorMatrix::multiply(CurvilinearTrajectoryError & initial_error, const CurvilinearTrajectoryError & scale_error){
00379
00380 const AlgebraicSymMatrix55 & scale_matrix=scale_error.matrix();
00381 AlgebraicSymMatrix55 revised_matrix = initial_error.matrix();
00382
00383
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
00391 const AlgebraicSymMatrix55 & denom_matrix=denom_error.matrix();
00392 AlgebraicSymMatrix55 num_matrix = num_error.matrix();
00393
00394
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 }