FairRoot/PandaRoot
PndEmcErrorMatrix.cxx
Go to the documentation of this file.
1 //--------------------------------------------------------------------------
2 // Description:
3 // Class PndEmcErrorMatrix
4 // Calculate Error Matrix for the given EmcCluster
5 // with parametrization defined by the given parameter PndEmcErrorMatrixPar
6 //
7 //------------------------------------------------------------------------
8 
9 #include "PndEmcErrorMatrix.h"
10 #include "PndEmcErrorMatrixPar.h"
11 #include "TSystem.h"
12 #include <cmath>
13 
15 fErrorMatrixParObject(new PndEmcErrorMatrixParObject())
16 {
17 }
18 
20 {
22 }
23 
24 void PndEmcErrorMatrix::InitFromFile(Int_t geomVersion)
25 {
26  TString fFileName;
27  switch (geomVersion){
28  case 1:
29  case 17:
30  case 19:
31  // correspond to geometries "emc_module12.dat","emc_module3new.root","emc_module4_StraightGeo24.4.root","emc_module5_fsc.root"
32  fFileName="emc_error_matrix_1.root";
33  break;
34  default:
35  std::cout<<"Error matrix for EMC geometry: "<<geomVersion<<" does not exist. Default is used."<<std::endl;
36  fFileName="emc_error_matrix_default.root";
37  }
38 
39  TString emc_error_file_name = gSystem->Getenv("VMCWORKDIR");
40  emc_error_file_name+="/input/";
41  emc_error_file_name+=fFileName;
42 
43  std::cout<<"EMC error matrix is read from: "<<emc_error_file_name<<std::endl;
44 
45  TFile *errorMatrixfile = new TFile(emc_error_file_name.Data());
46  if(errorMatrixfile==NULL){
47  std::cout << "-E- PndEmcErrorMatrix: Could not open file " << emc_error_file_name << " for Emc error matrix parameters" << std::endl;
48  } else {
49  errorMatrixfile->GetObject("PndEmcErrorMatrixParObject",fErrorMatrixParObject);
50  if(fErrorMatrixParObject == NULL){
51  std::cout << "-E- PndEmcErrorMatrix: Could not get Emc error matrix information from file " << emc_error_file_name<< std::endl;
52  }
53  }
54 
55 }
56 
58 
60 {
61  return fErrorMatrixParObject;
62 }
63 
64 
65 
67  Double_t clEnergy=cluster.energy();
68  Double_t clTheta=cluster.theta();
69  Double_t clPhi=cluster.phi();
70 
71  // In which part of EMC the cluster is located
72  // 1,2 - barrel, 3 - fwd endcap, 4- backward endcap, 5 - shashlyk
73  Int_t module=cluster.GetModule();
74 
75  enum {barrel, fwcap, bwcap, fsc};
76  Int_t clusterInComponent=-1; //in which detector component is the cluster
77 
78  if( (module==1)||(module==2) ){
79  clusterInComponent = barrel;
80  }else if( module==3 ){
81  clusterInComponent = fwcap;
82  }else if( module==4 ){
83  clusterInComponent = bwcap;
84  }else if( module==5 ){
85  clusterInComponent = fsc;
86  }else{
87  std::cout<<"Incorrect EMC module in PndEmcErrorMatrix"<<std::endl;
88  abort();
89  }
90 
91  //functions used for parametrization
92  //Energy: Delta(E)/E = (a^2/E^power) + const^2 + (quadr/E)^2
93  //position: Delta(x)=(a*a/E^power) + const^2
94  Double_t pars[10];
95  fErrorMatrixParObject->GetErrorMatrix(clusterInComponent, pars);
96  Double_t engParA, engPower, engConst, engQuadr, pos1ParA, pos1Power, pos1Const, pos2ParA, pos2Power, pos2Const;
97  engParA=pars[0];
98  engPower=pars[1];
99  engConst=pars[2];
100  engQuadr=pars[3];
101  pos1ParA=pars[4];
102  pos1Power=pars[5];
103  pos1Const=pars[6];
104  pos2ParA=pars[7];
105  pos2Power=pars[8];
106  pos2Const=pars[9];
107 
108  //errors on position are estimated w/ respect to
109  //nominal z=100. (for fwcap, bwcap, fsc) ---> dx(z) and dy(z)
110  //and
111  //nominal R=100. (for barrel) ---> dz(r) and dphi(r)
112  //calculated errors are scaled with the following factors
113  //
114  Double_t barrelRadius=54.;
115  Double_t bwCapPosZ = 56.;
116  Double_t fwCapPosZ = 208.2;
117  Double_t fscPosZ = 780.;
118 
119  Double_t scaleFactor[4];
120  scaleFactor[bwcap]=bwCapPosZ/100.;
121  scaleFactor[barrel]=barrelRadius/100.;
122  scaleFactor[fwcap]=fwCapPosZ/100.;
123  scaleFactor[fsc]=fscPosZ/100.;
124 
125  Double_t energyMinCutOff[4]={ 0.1, 0.1, 0.1, 0.5 };
126  Double_t energyMaxCutOff[4]={ 1.5, 5., 7., 7. };
127  Double_t eng=clEnergy;
128  if(clEnergy>energyMaxCutOff[clusterInComponent]) eng=energyMaxCutOff[clusterInComponent];
129  if(clEnergy<energyMinCutOff[clusterInComponent]) eng=energyMinCutOff[clusterInComponent];
130 
131  //std::cout << "+++++++++ Cluster in " << i << std::endl;
132  //enrgy error
133  Double_t errEnergy = engParA*engParA/pow(eng,engPower)
134  + pow(engConst, 2.0)
135  + pow(engQuadr/eng,2.0) ;
136  //std::cout << "Error on energy for " << clEnergy << " GeV is " << errEnergy << std::endl;
137  errEnergy*=clEnergy;
138 
139  //position coordinate errors
140  Double_t pos1Err= pow(pos1ParA,2.)/pow(eng,pos1Power)+pow(pos1Const,2.);
141  //std::cout << "Error on pos1 for " << clEnergy << " GeV is " << pos1Err << std::endl;
142  pos1Err*=scaleFactor[clusterInComponent];
143 
144  Double_t pos2Err= pow(pos2ParA,2.)/pow(eng,pos2Power)+pow(pos2Const,2.);
145  //std::cout << "Error on pos2 for " << clEnergy << " GeV is " << pos2Err << std::endl;
146  if(clusterInComponent!=barrel)
147  pos2Err*=scaleFactor[clusterInComponent];
148 
149 
150  //error matrix for E, pos1, pos2 and arbitrary pos3
151  TMatrixD theError(3,3);
152  theError(0,0)=errEnergy*errEnergy;
153  theError(1,1)=pos1Err*pos1Err;
154  theError(2,2)=pos2Err*pos2Err;
155 
156  //std::cout << "theError before transformation: " << theError << std::endl;
157 
158  Double_t sin_theta=sin(clTheta);
159  Double_t sin_phi =sin(clPhi);
160  Double_t cos_theta=cos(clTheta);
161  Double_t cos_phi =cos(clPhi);
162 
163 
164  TMatrixD trans(4,3);
165  if(clusterInComponent==barrel){
166  barrelRadius=scaleFactor[barrel]*100.;
167 
168  trans(0,0)=1.; //dE/dE
169  trans(0,1)=0.; //dE/dz
170  trans(0,2)=0.; //dE/dphi
171 
172  trans(1,0)=0.; //dTheta/dE
173  trans(1,1)=-sin_theta*sin_theta/barrelRadius; //dTheta/dz
174  trans(1,2)=0.; //dTheta/dphi
175 
176  trans(2,0)=0.; //dPhi/dE
177  trans(2,1)=0.; //dPhi/dz
178  trans(2,2)=1.; //dPhi/dphi
179 
180  trans(3,0)=0.; //dR/dE
181  trans(3,1)=0.; //dR/dz
182  trans(3,2)=0.; //dR/dphi
183 
184  }else{
185  Double_t R=fabs(scaleFactor[clusterInComponent]*100./cos_theta); //a bit ugly, but theta is never 90 deg for these components
186  //trans(row, col)
187  trans(0,0)=1.; //dE/dE
188  trans(0,1)=0.; //dE/dx
189  trans(0,2)=0.; //dE/dy
190 
191  trans(1,0)=0.; //dTheta/dE
192  trans(1,1)= cos_theta * cos_phi /R; //dTheta/dx
193  trans(1,2)= cos_theta * sin_phi /R; //dTheta/dy
194 
195  trans(2,0)=0.;//dPhi/dE
196  trans(2,1)= -sin_phi /(R*sin_theta); //dPhi/dx
197  trans(2,2)= cos_phi/(R*sin_theta); //dPhi/dy
198 
199  trans(3,0)=0.; //dR/dE
200  //trans(4,2)= sin_theta * cos_phi /R; //dR/dx
201  //trans(4,3)= sin_theta * sin_phi /R; //dR/dy
202  trans(3,1)= 0.0; //dR/dx
203  trans(3,2)= 0.0; //dR/dy
204 
205  }
206 
207  // Error matrix in (E, theta, phi, R)
208  TMatrixD errorMatrix=similarityWith(theError,trans);
209 
210  return errorMatrix;
211 
212 }
213 
215  // Conversion from (E, theta, phi, r) to ( px, py, pz, E )
216 
217  double z_cluster = cluster.where().Z();
218  double perp = cluster.where().Perp();
219  double mag = cluster.where().Mag();
220  double cos_theta = z_cluster / mag;
221  double sin_theta = perp / mag;
222  double sin_phi = cluster.where().Y() / perp;
223  double cos_phi = cluster.where().X() / perp;
224  double e=cluster.energy();
225  double p = e;
226 
227  // Create a matrix to transform the error matrix
228  TMatrixD toComp( 4, 4 );
229  toComp(0,0) = sin_theta * cos_phi * e/p;
230  toComp(0,1) = p * cos_theta * cos_phi;
231  toComp(0,2) = -p * sin_theta * sin_phi;
232  toComp(0,3) = 0;
233  toComp(1,0) = sin_theta * sin_phi * e/p;
234  toComp(1,1) = p * cos_theta * sin_phi;
235  toComp(1,2) = p * sin_theta * cos_phi;
236  toComp(1,3) = 0;
237  toComp(2,0) = cos_theta * e/p;
238  toComp(2,1) = -p * sin_theta;
239  toComp(2,2) = 0;
240  toComp(2,3) = 0;
241  toComp(3,0) = 1;
242  toComp(3,1) = 0;
243  toComp(3,2) = 0;
244  toComp(3,3) = 0;
245 
246  TMatrixD errorMatrix=similarityWith(GetErrorMatrix(cluster),toComp);
247 
248  return errorMatrix;
249 }
250 
251 
253  // Conversion from (E, theta, phi, r) to ( x, y, z, px, py, pz, E )
254 
255  double z_cluster = cluster.where().Z();
256  double perp = cluster.where().Perp();
257  double mag = cluster.where().Mag();
258  double cos_theta = z_cluster / mag;
259  double sin_theta = perp / mag;
260  double sin_phi = cluster.where().Y() / perp;
261  double cos_phi = cluster.where().X() / perp;
262  double e=cluster.energy();
263  double p = e;
264 
265  // Create a matrix to transform the error matrix
266  TMatrixD toComp( 7, 4 );
267  toComp(0,0) = 0;
268  toComp(0,1) = mag * cos_theta * cos_phi;
269  toComp(0,2) = -mag* sin_theta * sin_phi;
270  toComp(0,3) = sin_theta * cos_phi;
271  toComp(1,0) = 0;
272  toComp(1,1) = mag * cos_theta * sin_phi;
273  toComp(1,2) = mag * sin_theta * cos_phi;
274  toComp(1,3) = sin_theta * sin_phi;
275  toComp(2,0) = 0;
276  toComp(2,1) = -mag * sin_theta;
277  toComp(2,2) = 0;
278  toComp(2,3) = cos_theta;
279  toComp(3,0) = sin_theta * cos_phi;
280  toComp(3,1) = p * cos_theta * cos_phi;
281  toComp(3,2) = -p * sin_theta * sin_phi;
282  toComp(3,3) = 0;
283  toComp(4,0) = sin_theta * sin_phi;
284  toComp(4,1) = p * cos_theta * sin_phi;
285  toComp(4,2) = p * sin_theta * cos_phi;
286  toComp(4,3) = 0;
287  toComp(5,0) = cos_theta;
288  toComp(5,1) = -p * sin_theta;
289  toComp(5,2) = 0;
290  toComp(5,3) = 0;
291  toComp(6,0) = 1;
292  toComp(6,1) = 0;
293  toComp(6,2) = 0;
294  toComp(6,3) = 0;
295 
296  TMatrixD errorMatrix=similarityWith(GetErrorMatrix(cluster),toComp);
297 
298  return errorMatrix;
299 }
300 
301 // Function is copied from BbrGeom/BbrError.cc
302 // It does the same as m1*mat*m1^T
303 // but with assumption that mat, and output matrix are symmetric
304 
305 TMatrixD similarityWith(const TMatrixD& mat, const TMatrixD& m1)
306 {
307  TMatrixD result(m1.GetNrows(),m1.GetNrows());
308 
309  TMatrixD temp = m1*mat;
310  double tmp;
311 
312  for (int r = 0; r < m1.GetNrows(); r++) {
313  for (int c = 0; c <= r; c++) {
314  tmp = 0.;
315  for (int k = 0; k < m1.GetNcols(); k++) {
316  tmp += temp(r,k)*m1(c,k);
317  }
318  result(r,c) = tmp;
319  // Modification from original code, to make output matrix explicitly symmetric
320  // In original babar code symmetric matrix were stored as lower triangular.
321  if (r!=c)
322  result(c,r) = tmp;
323  }
324  }
325  return result;
326 }
void Init(PndEmcErrorMatrixParObject *par)
Double_t p
Definition: anasim.C:58
friend F32vec4 cos(const F32vec4 &a)
Definition: P4_F32vec4.h:112
TVector3 where() const
double r
Definition: RiemannTest.C:14
Short_t GetModule() const
TMatrixD similarityWith(const TMatrixD &mat, const TMatrixD &m1)
void GetErrorMatrix(Int_t detectorComponent, Double_t *pars)
friend F32vec4 sin(const F32vec4 &a)
Definition: P4_F32vec4.h:111
Container class for EMC error matrix parameter class is inherited from FairParGenericSet.
Double_t par[3]
PndEmcErrorMatrixParObject * fErrorMatrixParObject
TMatrixD GetErrorP7(const PndEmcCluster &cluster) const
void InitFromFile(Int_t geomVersion)
TGeoTranslation * trans
Double_t
TMatrixD Get4MomentumErrorMatrix(const PndEmcCluster &cluster) const
friend F32vec4 fabs(const F32vec4 &a)
Definition: P4_F32vec4.h:47
a cluster (group of neighboring crystals) of hit emc crystals
Definition: PndEmcCluster.h:29
virtual Double_t energy() const
PndEmcErrorMatrixParObject * GetParObject()
Double_t theta() const
Double_t phi() const
Double_t R
Definition: checkhelixhit.C:61
TMatrixT< double > TMatrixD
Definition: PndLmdDim.h:52
TMatrixD GetErrorMatrix(const PndEmcCluster &cluster) const