Project
Loading...
Searching...
No Matches
Param.cxx
Go to the documentation of this file.
1// Copyright 2020-2022 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include "HMPIDBase/Param.h"
13#include "TGeoMatrix.h"
14#include <TLatex.h> //TestTrans()
15#include <TView.h> //TestTrans()
16#include <TPolyMarker3D.h> //TestTrans()
17#include <TRotation.h>
18#include <TParticle.h> //Stack()
19#include <TGeoPhysicalNode.h> //ctor
20#include <TGeoBBox.h>
21#include <TF1.h> //ctor
22#include <iostream>
23
24using namespace o2::hmpid;
25
27
28// Mathieson constant definition
29const double Param::fgkD = 0.222500; // ANODE-CATHODE distance 0.445/2
30// K3 = 0.66 along the wires (anode-cathode/wire pitch=0.5625)
31const double Param::fgkSqrtK3x = TMath::Sqrt(0.66);
32const double Param::fgkK2x = TMath::PiOver2() * (1 - 0.5 * fgkSqrtK3x);
33const double Param::fgkK1x = 0.25 * fgkK2x * fgkSqrtK3x / TMath::ATan(fgkSqrtK3x);
34const double Param::fgkK4x = fgkK1x / (fgkK2x * fgkSqrtK3x);
35// K3 = 0.87 along the wires (anode-cathode/wire pitch=0.5625)
36const double Param::fgkSqrtK3y = TMath::Sqrt(0.87);
37const double Param::fgkK2y = TMath::PiOver2() * (1 - 0.5 * fgkSqrtK3y);
38const double Param::fgkK1y = 0.25 * fgkK2y * fgkSqrtK3y / TMath::ATan(fgkSqrtK3y);
39const double Param::fgkK4y = fgkK1y / (fgkK2y * fgkSqrtK3y);
40//
41
42float Param::fgkMinPcX[] = {0., 0., 0., 0., 0., 0.};
43float Param::fgkMaxPcX[] = {0., 0., 0., 0., 0., 0.};
44float Param::fgkMinPcY[] = {0., 0., 0., 0., 0., 0.};
45float Param::fgkMaxPcY[] = {0., 0., 0., 0., 0., 0.};
46
47bool Param::fgMapPad[160][144][7];
48
49float Param::fgCellX = 0.;
50float Param::fgCellY = 0.;
51float Param::fgHalfCellX = 0.;
52float Param::fgHalfCellY = 0.;
53
54float Param::fgPcX = 0;
55float Param::fgPcY = 0;
56
57float Param::fgAllX = 0;
58float Param::fgAllY = 0;
59
60bool Param::fgInstanceType = kTRUE;
61
62Param* Param::fgInstance = nullptr; // singleton pointer
63
64Int_t Param::fgNSigmas = 4;
65Int_t Param::fgThreshold = 4;
66
67//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
68Param::Param(bool noGeo) : mX(0), mY(0), mRefIdx(1.28947), mPhotEMean(6.675), mTemp(25)
69// just set a refractive index for C6F14 at ephot=6.675 eV @ T=25 C
70{
71 // Here all the intitializition is taken place when Param::Instance() is invoked for the first time.
72 // In particular, matrices to be used for LORS<->MARS trasnformations are initialized from TGeo structure.
73 // Note that TGeoManager should be already initialized from geometry.root file
74
75 /* AliCDBManager *pCDB = AliCDBManager::Instance();
76 if(!pCDB) {
77 AliWarning("No Nmean C6F14 from OCDB. Default is taken from ctor.");
78 } else {
79 AliCDBEntry *pNmeanEnt =pCDB->Get("HMPID/Calib/Nmean"); //contains TObjArray of 42 TF1 + 1 EPhotMean
80 if(!pNmeanEnt) {
81 AliWarning("No Nmean C6F14 from OCDB. Default is taken from ctor.");
82 } else {
83 TObjArray *pNmean = (TObjArray*)pNmeanEnt->GetObject();
84 if(pNmean->GetEntries()==43) { //for backward compatibility
85 double tmin,tmax;
86 ((TF1*)pNmean->At(42))->GetRange(tmin,tmax);
87 fPhotEMean = ((TF1*)pNmean->At(42))->Eval(tmin); //photon eMean from OCDB
88 AliInfo(Form("EPhotMean = %f eV successfully loaded from OCDB",fPhotEMean));
89 } else {
90 AliWarning("For backward compatibility EPhotMean is taken from ctor.");
91 }
92 }
93 }
94*/
95 mRefIdx = meanIdxRad(); // initialization of the running ref. index of freon
96
97 float dead = 2.6; // cm of the dead zones between PCs-> See 2CRC2099P1
98
99 if (noGeo == kTRUE) {
100 fgInstanceType = kFALSE; // instance from ideal geometry, no actual geom is present
101 }
102
103 if (noGeo == kFALSE && !gGeoManager) {
104 TGeoManager::Import("geometry.root");
105 if (!gGeoManager) {
106 Printf("!!!!!!No geometry loaded!!!!!!!");
107 }
108 }
109
110 fgCellX = 0.8;
111 fgCellY = 0.84;
112 fgHalfCellX = fgCellX * 0.5;
113 fgHalfCellY = fgCellY * 0.5;
114
115 if (!noGeo == kTRUE) {
116 TGeoVolume* pCellVol = gGeoManager->GetVolume("Hcel");
117 if (pCellVol) {
118 TGeoBBox* bcell = (TGeoBBox*)pCellVol->GetShape();
119 fgCellX = 2. * bcell->GetDX();
120 fgCellY = 2. * bcell->GetDY(); // overwrite the values with the read ones
121 }
122 }
123 fgPcX = 80. * fgCellX;
124 fgPcY = 48. * fgCellY;
125 fgAllX = 2. * fgPcX + dead;
126 fgAllY = 3. * fgPcY + 2. * dead;
127
128 fgkMinPcX[1] = fgPcX + dead;
129 fgkMinPcX[3] = fgkMinPcX[1];
130 fgkMinPcX[5] = fgkMinPcX[3];
131 fgkMaxPcX[0] = fgPcX;
132 fgkMaxPcX[2] = fgkMaxPcX[0];
133 fgkMaxPcX[4] = fgkMaxPcX[2];
134 fgkMaxPcX[1] = fgAllX;
135 fgkMaxPcX[3] = fgkMaxPcX[1];
136 fgkMaxPcX[5] = fgkMaxPcX[3];
137
138 fgkMinPcY[2] = fgPcY + dead;
139 fgkMinPcY[3] = fgkMinPcY[2];
140 fgkMinPcY[4] = 2. * fgPcY + 2. * dead;
141 fgkMinPcY[5] = fgkMinPcY[4];
142 fgkMaxPcY[0] = fgPcY;
143 fgkMaxPcY[1] = fgkMaxPcY[0];
144 fgkMaxPcY[2] = 2. * fgPcY + dead;
145 fgkMaxPcY[3] = fgkMaxPcY[2];
146 fgkMaxPcY[4] = fgAllY;
147 fgkMaxPcY[5] = fgkMaxPcY[4];
148
149 mX = 0.5 * sizeAllX();
150 mY = 0.5 * sizeAllY();
151
152 for (Int_t ich = kMinCh; ich <= kMaxCh; ich++) {
153 for (Int_t padx = 0; padx < 160; padx++) {
154 for (Int_t pady = 0; pady < 144; pady++) {
155 fgMapPad[padx][pady][ich] = kTRUE; // init all the pads are active at the beginning....
156 }
157 }
158 }
159
160 for (Int_t i = kMinCh; i <= kMaxCh; i++) {
161 if (gGeoManager && gGeoManager->IsClosed()) {
162 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(Form("/HMPID/Chamber%i", i));
163 if (!pne) {
164 // AliErrorClass(Form("The symbolic volume %s does not correspond to any physical entry!",Form("HMPID_%i",i)));
165 mM[i] = new TGeoHMatrix;
166 idealPosition(i, mM[i]);
167 } else {
168 TGeoPhysicalNode* pnode = pne->GetPhysicalNode();
169 if (pnode) {
170 mM[i] = new TGeoHMatrix(*(pnode->GetMatrix()));
171 } else {
172 mM[i] = new TGeoHMatrix;
173 idealPosition(i, mM[i]);
174 }
175 }
176 } else {
177 mM[i] = new TGeoHMatrix;
178 idealPosition(i, mM[i]);
179 }
180 }
181 fgInstance = this;
182} // ctor
183//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
184void Param::print(Option_t* opt) const
185{
186 // print some usefull (hopefully) info on some internal guts of HMPID parametrisation
187
188 for (Int_t i = 0; i < 7; i++) {
189 mM[i]->Print(opt);
190 }
191} // Print()
192//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
193void Param::idealPosition(Int_t iCh, TGeoHMatrix* pMatrix)
194{
195 // Construct ideal position matrix for a given chamber
196 // Arguments: iCh- chamber ID; pMatrix- pointer to precreated unity matrix where to store the results
197 // Returns: none
198 const double kAngHor = 19.5; // horizontal angle between chambers 19.5 grad
199 const double kAngVer = 20; // vertical angle between chambers 20 grad
200 const double kAngCom = 30; // common HMPID rotation with respect to x axis 30 grad
201 const double kTrans[3] = {490, 0, 0}; // center of the chamber is on window-gap surface
202 pMatrix->RotateY(90); // rotate around y since initial position is in XY plane -> now in YZ plane
203 pMatrix->SetTranslation(kTrans); // now plane in YZ is shifted along x
204 switch (iCh) {
205 case 0:
206 pMatrix->RotateY(kAngHor);
207 pMatrix->RotateZ(-kAngVer);
208 break; // right and down
209 case 1:
210 pMatrix->RotateZ(-kAngVer);
211 break; // down
212 case 2:
213 pMatrix->RotateY(kAngHor);
214 break; // right
215 case 3:
216 break; // no rotation
217 case 4:
218 pMatrix->RotateY(-kAngHor);
219 break; // left
220 case 5:
221 pMatrix->RotateZ(kAngVer);
222 break; // up
223 case 6:
224 pMatrix->RotateY(-kAngHor);
225 pMatrix->RotateZ(kAngVer);
226 break; // left and up
227 }
228 pMatrix->RotateZ(kAngCom); // apply common rotation in XY plane
229}
230//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
231/*Int_t Param::Stack(Int_t evt,Int_t tid)
232{
233// Prints some useful info from stack
234// Arguments: evt - event number. if not -1 print info only for that event
235// tid - track id. if not -1 then print it and all it's mothers if any
236// Returns: mother tid of the given tid if any
237 AliRunLoader *pAL=AliRunLoader::Open();
238 if(pAL->LoadHeader()) return -1;
239 if(pAL->LoadKinematics()) return -1;
240
241 Int_t mtid=-1;
242 Int_t iNevt=pAL->GetNumberOfEvents();
243
244 for(Int_t iEvt=0;iEvt<iNevt;iEvt++){//events loop
245 if(evt!=-1 && evt!=iEvt) continue; //in case one needs to print the requested event, ignore all others
246 pAL->GetEvent(iEvt);
247 AliStack *pStack=pAL->Stack();
248 if(tid==-1){ //print all tids for this event
249 for(Int_t i=0;i<pStack->GetNtrack();i++) pStack->Particle(i)->Print();
250 Printf("totally %i tracks including %i primaries for event %i out of %i event(s)",
251 pStack->GetNtrack(),pStack->GetNprimary(),iEvt,iNevt);
252 }else{ //print only this tid and it;s mothers
253 if(tid<0 || tid>pStack->GetNtrack()) {Printf("Wrong tid, valid tid range
254 for event %i is 0-%i",iEvt,pStack->GetNtrack());break;}
255 TParticle *pTrack=pStack->Particle(tid); mtid=pTrack->GetFirstMother();
256 TString str=pTrack->GetName();
257 while((tid=pTrack->GetFirstMother()) >= 0){
258 pTrack=pStack->Particle(tid);
259 str+=" from ";str+=pTrack->GetName();
260 }
261 }//if(tid==-1)
262 }//events loop
263 pAL->UnloadHeader(); pAL->UnloadKinematics();
264 return mtid;
265}*/
266//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
267/*Int_t Param::StackCount(Int_t pid,Int_t evt)
268{
269// Counts total number of particles of given sort (including secondary) for a given event
270 AliRunLoader *pAL=AliRunLoader::Open();
271 pAL->GetEvent(evt);
272 if(pAL->LoadHeader()) return 0;
273 if(pAL->LoadKinematics()) return 0;
274 AliStack *pStack=pAL->Stack();
275
276 Int_t iCnt=0;
277 for(Int_t i=0;i<pStack->GetNtrack();i++) if(pStack->Particle(i)->GetPdgCode()==pid) iCnt++;
278
279 pAL->UnloadHeader(); pAL->UnloadKinematics();
280 return iCnt;
281}*/
282//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
283double Param::sigma2(double trkTheta, double trkPhi, double ckovTh, double ckovPh)
284{
285 // Analithical calculation of total error (as a sum of localization, geometrical and chromatic errors)
286 // on Cerenkov angle for a given Cerenkov photon
287 // created by a given MIP. Fromulae according to CERN-EP-2000-058
288 // Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians]
289 // dip and azimuthal angles for MIP taken at the entrance to radiator, [radians]
290 // MIP beta
291 // Returns: absolute error on Cerenkov angle, [radians]
292
293 TVector3 v(-999, -999, -999);
294 double trkBeta = 1. / (TMath::Cos(ckovTh) * getRefIdx());
295
296 if (trkBeta > 1) {
297 trkBeta = 1; // protection against bad measured thetaCer
298 }
299 if (trkBeta < 0) {
300 trkBeta = 0.0001; //
301 }
302
303 v.SetX(sigLoc(trkTheta, trkPhi, ckovTh, ckovPh, trkBeta));
304 v.SetY(sigGeom(trkTheta, trkPhi, ckovTh, ckovPh, trkBeta));
305 v.SetZ(sigCrom(trkTheta, trkPhi, ckovTh, ckovPh, trkBeta));
306
307 return v.Mag2();
308}
309//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
310double Param::sigLoc(double trkTheta, double trkPhi, double thetaC, double phiC, double betaM)
311{
312 // Analitical calculation of localization error (due to finite segmentation of PC) on Cerenkov angle for a given
313 // Cerenkov photon
314 // created by a given MIP. Fromulae according to CERN-EP-2000-058
315 // Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians]
316 // dip and azimuthal angles for MIP taken at the entrance to radiator, [radians]
317 // MIP beta
318 // Returns: absolute error on Cerenkov angle, [radians]
319
320 double phiDelta = phiC - trkPhi;
321
322 double sint = TMath::Sin(trkTheta);
323 double cost = TMath::Cos(trkTheta);
324 double sinf = TMath::Sin(trkPhi);
325 double cosf = TMath::Cos(trkPhi);
326 double sinfd = TMath::Sin(phiDelta);
327 double cosfd = TMath::Cos(phiDelta);
328 double tantheta = TMath::Tan(thetaC);
329
330 double alpha = cost - tantheta * cosfd * sint; // formula (11)
331 double k = 1. - getRefIdx() * getRefIdx() + alpha * alpha / (betaM * betaM); // formula (after 8 in the text)
332 if (k < 0) {
333 return 1e10;
334 }
335 double mu = sint * sinf + tantheta * (cost * cosfd * sinf + sinfd * cosf); // formula (10)
336 double e = sint * cosf + tantheta * (cost * cosfd * cosf - sinfd * sinf); // formula (9)
337
338 double kk = betaM * TMath::Sqrt(k) / (gapThick() * alpha); // formula (6) and (7)
339 // formula (6)
340 double dtdxc = kk * (k * (cosfd * cosf - cost * sinfd * sinf) - (alpha * mu / (betaM * betaM)) * sint * sinfd);
341 // formula (7) pag.4
342 double dtdyc = kk * (k * (cosfd * sinf + cost * sinfd * cosf) + (alpha * e / (betaM * betaM)) * sint * sinfd);
343
344 double errX = 0.2, errY = 0.25; // end of page 7
345 return TMath::Sqrt(errX * errX * dtdxc * dtdxc + errY * errY * dtdyc * dtdyc);
346}
347//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
348double Param::sigCrom(double trkTheta, double trkPhi, double thetaC, double phiC, double betaM)
349{
350 // Analitical calculation of chromatic error (due to lack of knowledge of Cerenkov photon energy)
351 // on Cerenkov angle for a given Cerenkov photon
352 // created by a given MIP. Fromulae according to CERN-EP-2000-058
353 // Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians]
354 // dip and azimuthal angles for MIP taken at the entrance to radiator, [radians]
355 // MIP beta
356 // Returns: absolute error on Cerenkov angle, [radians]
357
358 double phiDelta = phiC - trkPhi;
359
360 double sint = TMath::Sin(trkTheta);
361 double cost = TMath::Cos(trkTheta);
362 double cosfd = TMath::Cos(phiDelta);
363 double tantheta = TMath::Tan(thetaC);
364
365 double alpha = cost - tantheta * cosfd * sint; // formula (11)
366 double dtdn = cost * getRefIdx() * betaM * betaM / (alpha * tantheta); // formula (12)
367
368 // double f = 0.00928*(7.75-5.635)/TMath::Sqrt(12.);
369 double f = 0.0172 * (7.75 - 5.635) / TMath::Sqrt(24.);
370
371 return f * dtdn;
372} // SigCrom()
373//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
374double Param::sigGeom(double trkTheta, double trkPhi, double thetaC, double phiC, double betaM)
375{
376 // Analitical calculation of geometric error (due to lack of knowledge of creation point in radiator)
377 // on Cerenkov angle for a given Cerenkov photon
378 // created by a given MIP. Formulae according to CERN-EP-2000-058
379 // Arguments: Cerenkov and azimuthal angles for Cerenkov photon, [radians]
380 // dip and azimuthal angles for MIP taken at the entrance to radiator, [radians]
381 // MIP beta
382 // Returns: absolute error on Cerenkov angle, [radians]
383
384 double phiDelta = phiC - trkPhi;
385
386 double sint = TMath::Sin(trkTheta);
387 double cost = TMath::Cos(trkTheta);
388 double sinf = TMath::Sin(trkPhi);
389 double cosfd = TMath::Cos(phiDelta);
390 double costheta = TMath::Cos(thetaC);
391 double tantheta = TMath::Tan(thetaC);
392
393 double alpha = cost - tantheta * cosfd * sint; // formula (11)
394
395 double k = 1. - getRefIdx() * getRefIdx() + alpha * alpha / (betaM * betaM); // formula (after 8 in the text)
396 if (k < 0) {
397 return 1e10;
398 }
399
400 double eTr = 0.5 * radThick() * betaM * TMath::Sqrt(k) / (gapThick() * alpha); // formula (14)
401 double lambda = (1. - sint * sinf) * (1. + sint * sinf); // formula (15)
402
403 double c1 = 1. / (1. + eTr * k / (alpha * alpha * costheta * costheta)); // formula (13.a)
404 double c2 = betaM * TMath::Power(k, 1.5) * tantheta * lambda / (gapThick() * alpha * alpha); // formula (13.b)
405 double c3 = (1. + eTr * k * betaM * betaM) / ((1 + eTr) * alpha * alpha); // formula (13.c)
406 double c4 = TMath::Sqrt(k) * tantheta * (1 - lambda) / (gapThick() * betaM); // formula (13.d)
407 double dtdT = c1 * (c2 + c3 * c4);
408 double trErr = radThick() / (TMath::Sqrt(12.) * cost);
409
410 return trErr * dtdT;
411} // SigGeom()
412//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
413double Param::sigmaCorrFact(Int_t iPart, double occupancy)
414{
415 double corr = 1.0;
416
417 switch (iPart) {
418 case 0:
419 corr = 0.115 * occupancy + 1.166;
420 break;
421 case 1:
422 corr = 0.115 * occupancy + 1.166;
423 break;
424 case 2:
425 corr = 0.115 * occupancy + 1.166;
426 break;
427 case 3:
428 corr = 0.065 * occupancy + 1.137;
429 break;
430 case 4:
431 corr = 0.048 * occupancy + 1.202;
432 break;
433 }
434
435 return corr;
436}
437//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
439{
440 // Return pointer to the AliHMPIDParam singleton.
441 // Arguments: none
442 // Returns: pointer to the instance of AliHMPIDParam or 0 if no geometry
443 if (!fgInstance) {
444 new Param(kFALSE); // default setting for reconstruction, if no geometry.root -> AliFatal
445 }
446 return fgInstance;
447} // Instance()
448
449//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
451{
452 // Return pointer to the AliHMPIDParam singleton without the geometry.root.
453 // Arguments: none
454 // Returns: pointer to the instance of AliHMPIDParam or 0 if no geometry
455 if (!fgInstance) {
456 new Param(kTRUE); // to avoid AliFatal, for MOOD and displays, use ideal geometry parameters
457 }
458 return fgInstance;
459} // Instance()
460//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
461bool Param::isInDead(float x, float y)
462{
463 // Check is the current point is outside of sensitive area or in dead zones
464 // Arguments: x,y -position
465 // Returns: 1 if not in sensitive zone
466 for (Int_t iPc = 0; iPc < 6; iPc++) {
467 if (x >= fgkMinPcX[iPc] && x <= fgkMaxPcX[iPc] && y >= fgkMinPcY[iPc] && y <= fgkMaxPcY[iPc]) {
468 return kFALSE; // in current pc
469 }
470 }
471
472 return kTRUE;
473}
474//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
475bool Param::isDeadPad(Int_t padx, Int_t pady, Int_t ch)
476{
477 // Check is the current pad is active or not
478 // Arguments: padx,pady pad integer coord
479 // Returns: kTRUE if dead, kFALSE if active
480
481 if (fgMapPad[padx - 1][pady - 1][ch]) {
482 return kFALSE; // current pad active
483 }
484
485 return kTRUE;
486}
487//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
488void Param::lors2Pad(float x, float y, Int_t& pc, Int_t& px, Int_t& py)
489{
490 // Check the pad of given position
491 // Arguments: x,y- position [cm] in LORS; pc,px,py- pad where to store the result
492 // Returns: none
493 pc = px = py = -1;
494 if (x > fgkMinPcX[0] && x < fgkMaxPcX[0]) {
495 pc = 0;
496 px = Int_t(x / sizePadX());
497 } // PC 0 or 2 or 4
498 else if (x > fgkMinPcX[1] && x < fgkMaxPcX[1]) {
499 pc = 1;
500 px = Int_t((x - fgkMinPcX[1]) / sizePadX());
501 } // PC 1 or 3 or 5
502 else {
503 return;
504 }
505 if (y > fgkMinPcY[0] && y < fgkMaxPcY[0]) {
506 py = Int_t(y / sizePadY());
507 } // PC 0 or 1
508 else if (y > fgkMinPcY[2] && y < fgkMaxPcY[2]) {
509 pc += 2;
510 py = Int_t((y - fgkMinPcY[2]) / sizePadY());
511 } // PC 2 or 3
512 else if (y > fgkMinPcY[4] && y < fgkMaxPcY[4]) {
513 pc += 4;
514 py = Int_t((y - fgkMinPcY[4]) / sizePadY());
515 } // PC 4 or 5
516 else {
517 return;
518 }
519}
520//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
522{
523 // Calculate the HV sector corresponding to the cluster position
524 // Arguments: y
525 // Returns the HV sector in the single module
526
527 Int_t hvsec = -1;
528 Int_t pc, px, py;
529 lors2Pad(1., y, pc, px, py);
530 if (py == -1) {
531 return hvsec;
532 }
533
534 hvsec = (py + (pc / 2) * (kMaxPy + 1)) / ((kMaxPy + 1) / 2);
535
536 return hvsec;
537}
538//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
539double Param::findTemp(double tLow, double tHigh, double y)
540{
541 // Model for gradient in temperature
542 double yRad = hinRad(y); // height in a given radiator
543 if (tHigh < tLow) {
544 tHigh = tLow; // if Tout < Tin consider just Tin as reference...
545 }
546 if (yRad < 0) {
547 yRad = 0; // protection against fake y values
548 }
549 if (yRad > sizePcY()) {
550 yRad = sizePcY(); // protection against fake y values
551 }
552
553 double gradT = (tHigh - tLow) / sizePcY(); // linear gradient
554 return gradT * yRad + tLow;
555}
556//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
557void Param::setChStatus(Int_t ch, bool status)
558{
559 // Set a chamber on or off depending on the status
560 // Arguments: ch=chamber,status=kTRUE = active, kFALSE=off
561 // Returns: none
562 for (Int_t padx = 0; padx < kMaxPcx + 1; padx++) {
563 for (Int_t pady = 0; pady < kMaxPcy + 1; pady++) {
564 fgMapPad[padx][pady][ch] = status;
565 }
566 }
567}
568//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
569void Param::setSectStatus(Int_t ch, Int_t sect, bool status)
570{
571 // Set a given sector sect for a chamber ch on or off depending on the status
572 // Sector=0,5 (6 sectors)
573 // Arguments: ch=chamber,sect=sector,status: kTRUE = active, kFALSE=off
574 // Returns: none
575
576 Int_t npadsect = (kMaxPcy + 1) / 6;
577 Int_t padSectMin = npadsect * sect;
578 Int_t padSectMax = padSectMin + npadsect;
579
580 for (Int_t padx = 0; padx < kMaxPcx + 1; padx++) {
581 for (Int_t pady = padSectMin; pady < padSectMax; pady++) {
582 fgMapPad[padx][pady][ch] = status;
583 }
584 }
585}
586//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
587void Param::setPcStatus(Int_t ch, Int_t pc, bool status)
588{
589 // Set a given PC pc for a chamber ch on or off depending on the status
590 // Arguments: ch=chamber,pc=PC,status: kTRUE = active, kFALSE=off
591 // Returns: none
592
593 Int_t deltaX = pc % 2;
594 Int_t deltaY = pc / 2;
595 Int_t padPcXMin = deltaX * kPadPcX;
596 Int_t padPcXMax = padPcXMin + kPadPcX;
597 Int_t padPcYMin = deltaY * kPadPcY;
598 Int_t padPcYMax = padPcYMin + kPadPcY;
599
600 for (Int_t padx = padPcXMin; padx < padPcXMax; padx++) {
601 for (Int_t pady = padPcYMin; pady < padPcYMax; pady++) {
602 fgMapPad[padx][pady][ch] = status;
603 }
604 }
605}
606//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
608{
609 // Print the map status of a chamber on or off depending on the status
610 // Arguments: ch=chamber
611 // Returns: none
612 Printf(" ");
613 Printf(" --------- C H A M B E R %d ---------------", ch);
614 for (Int_t pady = kMaxPcy; pady >= 0; pady--) {
615 for (Int_t padx = 0; padx < kMaxPcx + 1; padx++) {
616 if (padx == 80) {
617 printf(" ");
618 }
619 printf("%d", fgMapPad[padx][pady][ch]);
620 }
621 printf(" %d \n", pady + 1);
622 if (pady % 48 == 0) {
623 printf("\n");
624 }
625 }
626 printf("\n");
627}
628//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
630{
631 // Set the real acceptance of the modules, due to ineficciency or hardware problems (up tp 1/6/2010)
632 // Arguments: none
633 // Returns: none
634 setSectStatus(0, 3, kFALSE);
635 setSectStatus(4, 0, kFALSE);
636 setSectStatus(5, 1, kFALSE);
637 setSectStatus(6, 2, kFALSE);
638 setSectStatus(6, 3, kFALSE);
639}
int32_t i
bool const GPUTPCGMMerger::trackCluster * c1
bool const GPUTPCGMMerger::trackCluster const clcomparestruct * c2
ClassImp(o2::hmpid::Param)
static float sizeAllX()
Definition Param.h:82
static bool isDeadPad(Int_t padx, Int_t pady, Int_t ch)
Definition Param.cxx:475
static void idealPosition(Int_t iCh, TGeoHMatrix *m)
Definition Param.cxx:193
static float fgkMinPcX[6]
Definition Param.h:264
static Int_t inHVSector(float y)
Definition Param.cxx:521
static bool isInDead(float x, float y)
Definition Param.cxx:461
void setSectStatus(Int_t ch, Int_t sect, bool status)
Definition Param.cxx:569
void setChStatus(Int_t ch, bool status=kTRUE)
Definition Param.cxx:557
static float fgkMaxPcX[6]
Definition Param.h:266
double getRefIdx() const
Definition Param.h:157
static float fgCellX
Definition Param.h:286
static double hinRad(float y)
Definition Param.h:124
static Param * instanceNoGeo()
Definition Param.cxx:450
static float fgkMinPcY[6]
Definition Param.h:265
static float fgHalfCellX
Definition Param.h:286
static float fgAllY
Definition Param.h:286
void setPcStatus(Int_t ch, Int_t pc, bool status)
Definition Param.cxx:587
static float sizeAllY()
Definition Param.h:83
double sigCrom(double trkTheta, double trkPhi, double ckovTh, double ckovPh, double beta)
Definition Param.cxx:348
double mRefIdx
Definition Param.h:294
static double sigmaCorrFact(Int_t iPart, double occupancy)
Definition Param.cxx:413
static float fgAllX
Definition Param.h:286
static void lors2Pad(float x, float y, Int_t &pc, Int_t &px, Int_t &py)
Definition Param.cxx:488
void print(Option_t *opt="") const
Definition Param.cxx:184
static float fgPcX
Definition Param.h:286
static float fgHalfCellY
Definition Param.h:286
double meanIdxRad() const
Definition Param.h:159
static bool fgInstanceType
Definition Param.h:284
void printChStatus(Int_t ch)
Definition Param.cxx:607
double radThick() const
Definition Param.h:166
static float fgkMaxPcY[6]
Definition Param.h:267
static float sizePadX()
Definition Param.h:70
double sigGeom(double trkTheta, double trkPhi, double ckovTh, double ckovPh, double beta)
Definition Param.cxx:374
static float sizePadY()
Definition Param.h:71
static Param * instance()
Definition Param.cxx:438
TGeoHMatrix * mM[7]
Definition Param.h:291
static float fgPcY
Definition Param.h:286
static double findTemp(double tLow, double tUp, double y)
Definition Param.cxx:539
static float sizePcY()
Definition Param.h:76
double sigLoc(double trkTheta, double trkPhi, double ckovTh, double ckovPh, double beta)
Definition Param.cxx:310
double gapThick() const
Definition Param.h:168
static float fgCellY
Definition Param.h:286
double sigma2(double trkTheta, double trkPhi, double ckovTh, double ckovPh)
Definition Param.cxx:283
static Param * fgInstance
Definition Param.h:289
static bool fgMapPad[160][144][7]
Definition Param.h:269
void setGeomAccept()
Definition Param.cxx:629
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLint GLenum GLint x
Definition glcorearb.h:403
const GLdouble * v
Definition glcorearb.h:832
GLdouble f
Definition glcorearb.h:310