All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
BcEnergyDensity.cc
Go to the documentation of this file.
1 // BcEnergyDensity class by A.Sapronov (sapronov@cern.ch)
2 // 18/07/2008
3 
4 #include "iostream"
5 
6 #include "TFile.h"
7 #include "TTree.h"
8 
9 #include "TMath.h"
10 #include "Math/Interpolator.h"
11 #include "Math/InterpolationTypes.h"
12 
13 #include "BcEnergyDensity.h"
14 
15 using namespace ROOT::Math;
16 
17 void BcEnergyDensity::Init(const char* inputfilename){
18  //const char filename[100] = "bg_aver_LDC_4T_14mrad_AntiDID.root.root";
19  TFile f(inputfilename, "READ");
20  if ( f.IsZombie() ) {
21  cerr << "Could not read data file. Exit." << endl;
22  exit(1);
23  }
24  TTree *t = (TTree*) f.Get("tBcDensAverage");
25  if ( t->IsZombie() ) {
26  cerr << "Could not find data tree \"tBcDensAverage\". Exit." << endl;
27  exit(1);
28  }
29 
30  Int_t cell_id[msSize];
31  Double_t r_max;
32  Double_t r_min;
33  Double_t s_phi;
34  Double_t d_phi;
35  Double_t en_dens;
36  Double_t en_dens_err;
37 
38  t->SetBranchAddress("sPos", cell_id);
39  t->SetBranchAddress("sRin", &r_min); // cm
40  t->SetBranchAddress("sRout", &r_max); // cm
41  t->SetBranchAddress("sSphi", &s_phi); // rad
42  t->SetBranchAddress("sDphi", &d_phi); // rad
43  t->SetBranchAddress("sEnDens", &en_dens); // GeV/mm2
44  t->SetBranchAddress("sEnDensErr", &en_dens_err);
45 
46  Int_t ne = t->GetEntries();
47 
48  for (int ie = 0; ie<ne; ie++){
49  t->GetEntry(ie);
50  r_min *= 10; // switch to mm
51  r_max *= 10;
52  CellType *cell = new CellType;
53  for (int i = 0; i<msSize; i++){ cell->Id[i] = cell_id[i]; }
54  cell->R = 0.5*( r_max + r_min );
55  cell->Phi = s_phi + 0.5*d_phi;
56  cell->EnDens = en_dens;
57  cell->EnDensErr = en_dens_err;
58 
59  mCellStorage.push_back(cell);
60 
61  if ( (cell_id[0] == 1) && (cell_id[2] == 0) ) {
62  mSegmentDeltaPhi.push_back(d_phi);
63  if ( cell_id[1] == 0 ) {
64  mRMin = r_min;
65  mPhiMin = s_phi;
66  mRingDeltaR = r_max - r_min;
67  }
68  }
69  }
70 
71  mNumberOfRings = mSegmentDeltaPhi.size();
72  mNumbersOfSegments.assign(mNumberOfRings, 0);
73 
74  for (int ie = 0; ie<ne; ie++){
75  t->GetEntry(ie);
76  r_min *= 10; // switch to mm
77  r_max *= 10;
78 
79  if ( cell_id[1] == ( mNumberOfRings - 1 ) ){
80  mRMax = r_max;
81  }
82 
83  if ( cell_id[0] == 1 ) {
84  mNumbersOfSegments.at(cell_id[1]) += 1;
85  }
86  }
87 
88  f.Close();
89 }
90 
92  vector<CellType*>::iterator it;
93  for (it = mCellStorage.begin(); it!=mCellStorage.end(); it++){
94  delete *it;
95  }
96 }
97 
98 
99 Bool_t BcEnergyDensity::GetEnergyDensity(const Int_t& rLayer,
100  const Double_t& rRadius, const Double_t& rPhi,
101  Double_t* pEnDens, Double_t* pEnDensError) const
102 {
103  // initialize to zero such that 0 is returned in keyhole region!
104  *pEnDens = 0.;
105  *pEnDensError = 0.;
106 // const Double_t TWO_PI = 2*TMath::Pi();
107  Double_t the_phi = rPhi;
108 // if ( the_phi < 0. ) the_phi += TWO_PI;
109 // if ( the_phi > TWO_PI) the_phi -= TWO_PI;
110  Int_t the_cell = 0;
111  the_cell = GetCellNumber(rLayer, rRadius, the_phi); // central cell
112  if ( the_cell < 0 ) return false;
113  Int_t the_ring = mCellStorage.at(the_cell)->Id[1];
114 
115  *pEnDens = mCellStorage.at(the_cell)->EnDens;
116  *pEnDensError = mCellStorage.at(the_cell)->EnDensErr;
117 
118  // skip all the interpolation stuff for now (JL, 26.9.12)
119  return true;
120 
121  const Int_t nsegs = 3;
122  const Int_t nrings = 3;
123  Int_t i_cell[nrings][nsegs];
124  // nrings: 0 - down ring, 1 - original ring, 2 - up ring
125  // nsegs: 0 - prev segment, 1 - original, 2 - next segment
126  for ( int ir = 0; ir<nrings; ir++ ){
127  for ( int is = 0; is<nsegs; is++ ){
128  Double_t radius = rRadius + (ir - 1)*mRingDeltaR;
129  Int_t i_ring = the_ring + ir - 1;
130  if ( i_ring < 0 || i_ring >= mNumberOfRings ){
131  i_cell[ir][is] = -1;
132  } else {
133  Double_t phi = the_phi + (is - 1)*mSegmentDeltaPhi.at(i_ring);
134  i_cell[ir][is] = GetCellNumber(rLayer, radius, phi);
135  }
136  }
137  }
138 
139  vector<double> phis[nrings];
140  vector<ValErrType> en_dens[nrings];
141 
142  for (int is = 0; is<nsegs; is++){
143  for (int ir = 0; ir<nrings; ir++){
144  if ( !( i_cell[ir][is]<0 ) ){
145  CellType *cell = mCellStorage.at(i_cell[ir][is]);
146  Double_t phi = cell->Phi;
147  if ( the_phi < mSegmentDeltaPhi.at(the_ring + ir - 1) && is == 0 ) {
148  phi -= 2*TMath::Pi();
149  }
150  if ( 2*TMath::Pi() - the_phi < mSegmentDeltaPhi.at(the_ring + ir - 1)
151  && is == 2 ) {
152  phi += 2*TMath::Pi();
153  }
154  phis[ir].push_back(phi);
155  ValErrType ed;
156  ed.Val = cell->EnDens;
157  Double_t ed_err = cell->EnDensErr;
158  ed.Lb = ed.Val - ed_err;
159  ed.Ub = ed.Val + ed_err;
160  en_dens[ir].push_back(ed);
161  }
162  }
163  }
164 
165  // interpolate over phi in rings original, down and up
166  vector<double> r;
167  vector<ValErrType> ed_int_by_phi; // values interpolated by phi in diff. rings
168  for (int ir=0; ir<nrings; ir++){
169  if ( en_dens[ir].size() != 0 && i_cell[ir][1] > 0 ){
170  r.push_back(mCellStorage.at(i_cell[ir][1])->R);
171  ValErrType ed_int;
172  Bool_t int_result = MakeInterpolation(the_phi, phis[ir], en_dens[ir], &ed_int);
173  if( int_result ){
174  ed_int_by_phi.push_back(ed_int);
175  } else {
176  cerr << "Interpolation failed." << endl;
177  return false;
178  }
179  }
180  }
181 
182  if (ed_int_by_phi.size()!=0){
183  ValErrType ed_int;
184  Bool_t int_result = MakeInterpolation(rRadius, r, ed_int_by_phi, &ed_int);
185  if ( int_result ) {
186  *pEnDens = ed_int.Val;
187  *pEnDensError = 0.5*(ed_int.Ub - ed_int.Lb);
188  } else {
189  cerr << "Interpolation failed." << endl;
190  return false;
191  }
192  } else {
193  return false;
194  }
195 
196  return true;
197 }
198 
199 
200 // returns absolute number of cell which contains given coords
201 Int_t BcEnergyDensity::GetCellNumber(const Int_t& rLayer, const Double_t& rRadius,
202  const Double_t& rPhi) const
203 {
204  unsigned int cell_cnt = 0; // cell counter
205 
206  if ( rRadius < mRMin || rRadius > mRMax ) return -1;
207 
208  Int_t layer_number = TMath::Abs(rLayer) - 1; // should start with 0
209  Int_t layer_sign = ( rLayer>0 ) ? 0 : 1; // 0 - forward, 1 - backward
210  Int_t ring_number = (Int_t) TMath::Floor( (rRadius - mRMin)/mRingDeltaR );
211  double phi = ( rPhi < mPhiMin) ? rPhi + 2*TMath::Pi() : rPhi;
212  Int_t segm_number =
213  (Int_t) TMath::Floor( (phi - mPhiMin)/mSegmentDeltaPhi.at(ring_number) );
214  if ( segm_number >= mNumbersOfSegments.at(ring_number) ) return -1;
215 
216  Int_t n_in_layer = 0;
217  for (int ir=0; ir<mNumberOfRings; ir++){
218  n_in_layer += mNumbersOfSegments.at(ir);
219  }
220 
221  for (int ir=0; ir<ring_number; ir++){
222  cell_cnt += mNumbersOfSegments.at(ir);
223  }
224  cell_cnt += n_in_layer*layer_number + segm_number;
225  cell_cnt *= 2;
226  cell_cnt += layer_sign;
227 
228  if ( cell_cnt > mCellStorage.size() ) return -1;
229 
230  return cell_cnt;
231 }
232 
233 Bool_t BcEnergyDensity::MakeInterpolation ( const Double_t& rX,
234  const vector<Double_t>& rXData,
235  const vector<ValErrType>& rYData,
236  ValErrType* pResult) const
237 {
238 /* cout<<rXData.size()<<" "<<rYData.size()<<endl;
239  cout << rX <<"\t";
240  for (size_t i=0; i<rXData.size(); i++){
241  cout << rXData.at(i) << "\t";
242  }
243  for (size_t i=0; i<rXData.size(); i++){
244  cout << rYData.at(i).Val << "\t";
245  }
246  cout<<endl;
247 */
248 
249 
250 // #if ROOT_VERSION_CODE < ROOT_VERSION(5,20,0)
251 // Interpolation::Type interp_type = Interpolation::CSPLINE;
252 // if (rXData.size()<10) interp_type = Interpolation::LINEAR;
253 // #else
254 // Interpolation::Type interp_type = Interpolation::kCSPLINE;
255 // if (rXData.size()<10) interp_type = Interpolation::kLINEAR;
256 // #endif
257 
258  Interpolation::Type interp_type = Interpolation::kLINEAR;
259 
260 
261 // Interpolator interp(rXData.size(), interp_type);
262  Interpolator *interp=0;
263 
264  //cout<<interp->TypeGet()<<endl;
265  vector<double> y_data;
266  for (size_t i=0; i<rYData.size(); i++) y_data.push_back(rYData.at(i).Val);
267  interp = new Interpolator (rXData, y_data, interp_type);
268  //interp.SetData(rXData, y_data);
269  if (interp > 0) {
270  pResult->Val = interp->Eval(rX);
271  delete interp;
272  }
273  y_data.clear();
274 
275  for (size_t i=0; i<rYData.size(); i++) y_data.push_back(rYData.at(i).Lb);
276  interp = new Interpolator (rXData, y_data, interp_type);
277  //interp.SetData(rXData, y_data);
278  if (interp >0) {
279  pResult->Lb = interp->Eval(rX);
280  delete interp;
281  }
282  y_data.clear();
283 
284  for (size_t i=0; i<rYData.size(); i++) y_data.push_back(rYData.at(i).Ub);
285  interp = new Interpolator (rXData, y_data, interp_type);
286  //interp.SetData(rXData, y_data);
287  if (interp > 0) {
288  pResult->Ub = interp->Eval(rX);
289  delete interp;
290  }
291 
292  y_data.clear();
293 
294  return true;
295 }
Bool_t GetEnergyDensity(const Int_t &rLayer, const Double_t &rRadius, const Double_t &rPhi, Double_t *pEnDens, Double_t *pEnDensError) const
Bool_t MakeInterpolation(const Double_t &rX, const vector< Double_t > &rXData, const vector< ValErrType > &rYData, ValErrType *pResult) const
void Init(const char *inputfilename)
Int_t GetCellNumber(const Int_t &rLayer, const Double_t &rRadius, const Double_t &rPhi) const