StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StSpaceChargeDistMaker.cxx
1 // //
3 // StSpaceChargeDistMaker looks at the distribution of charge //
4 // in the TPC //
5 // //
7 
8 #include "StSpaceChargeDistMaker.h"
9 #include "StMessMgr.h"
10 #include "StEvent.h"
11 #include "StEventTypes.h"
12 #include "StDetectorDbMaker/St_tpcPadGainT0BC.h"
13 #include "StDetectorDbMaker/St_tss_tssparC.h"
14 #include "StDetectorDbMaker/StDetectorDbTpcRDOMasks.h"
15 #include "StDetectorDbMaker/St_tpcPadConfigC.h"
16 #include "StDetectorDbMaker/St_TpcSecRowBC.h"
17 #include "StDetectorDbMaker/St_TpcAvgCurrentC.h"
18 #include "StDbUtilities/StMagUtilities.h"
19 #include "StDbUtilities/StTpcCoordinateTransform.hh"
20 #include "StdEdxY2Maker/StTpcdEdxCorrection.h"
21 
22 
23 #include "TH2.h"
24 #include "TH3.h"
25 #include "TFile.h"
26 #include "TRandom.h"
27 #include "TMatrixD.h"
28 #include "TVectorD.h"
29 
30 static const Int_t nz = 105;
31 static const Double_t zmin = -205;
32 static const Double_t zmax = 205;
33 static const Int_t nr = 17; //85
34 static const Double_t rmin = 40.;
35 static const Double_t rmax = 210;
36 static const Int_t nph = 12;
37 static const Double_t phmin = -TMath::Pi();
38 static const Double_t phmax = TMath::Pi();
39 static const Double_t PhiMax = TMath::Pi()/12;
40 static const Int_t nrph = nr*nph;
41 static const Double_t ZdcMax = 2e6;
42 
43 static const Double_t MINGAIN = 0.1;
44 
45 static TMatrixD* RPMats[nz];
46 static TMatrixD* RMats[nz];
47 static TVectorD* RPMatHs[nz];
48 static TVectorD* RMatHs[nz];
49 
50 ClassImp(StSpaceChargeDistMaker)
51 
52 //_____________________________________________________________________________
54  event(0), Space3ChargePRZ(0), Space3ChargeU(0),
55  thrownR(0), acceptedR(0),
56  thrownRP(0), acceptedRP(0),
57  thrownP(0), acceptedP(0),
58  ZdcC(0) {
59  run = 0;
60  GGZ = 0; NP = 0; NR = 0; NS = 0;
61  throws = 500000; // default = 500k throws
62  trigs.Set(0);
63  memset(Xpads,0,128*sizeof(Float_t));
64  memset(Npads,0,128*sizeof(UShort_t));
65  memset(XMIN,0,128*sizeof(Float_t));
66  memset(YMIN,0,32768*sizeof(Float_t));
67  memset(LiveRow,0,4096*sizeof(Bool_t));
68  memset(LivePad,0,1048576*sizeof(Bool_t));
69 }
70 //_____________________________________________________________________________
71 StSpaceChargeDistMaker::~StSpaceChargeDistMaker() {
72 }
73 //_____________________________________________________________________________
74 void StSpaceChargeDistMaker::AcceptTrigger(Int_t trig) {
75  Int_t ntrig = trigs.GetSize();
76  if (trig<0) {
77  LOG_INFO << "StSpaceChargeDistMaker: Accepting all triggers." << endm;
78  } else {
79  LOG_INFO << "StSpaceChargeDistMaker: Accepting trigger (" << ntrig << ") : " << trig << endm;
80  }
81  trigs.Set(ntrig+1);
82  trigs.AddAt(trig,ntrig);
83 }
84 //_____________________________________________________________________________
86 
87  TH2D *rGeom = new TH2D(*acceptedR);
88  rGeom->SetName("rGeom");
89  rGeom->Divide(thrownR);
90  TH2D *phGeom = new TH2D(*acceptedP);
91  phGeom->SetName("phGeom");
92  phGeom->Divide(thrownP);
93  TH3D *rpGeom = new TH3D(*acceptedRP);
94  rpGeom->SetName("rpGeom");
95  rpGeom->Divide(thrownRP);
96 
97  TH3D* S3CPRZ = new TH3D(*Space3ChargePRZ);
98  S3CPRZ->SetName(Form("%sOrig",Space3ChargePRZ->GetName()));
99  TH3D* S3CU = new TH3D(*Space3ChargeU);
100  S3CU->SetName(Form("%sOrig",Space3ChargeU->GetName()));
101 
102  TFile* ff = new TFile(Form("SCdist_%d.root",run),"RECREATE");
103  S3CPRZ->Write();
104  S3CU->Write();
105  rGeom->Write();
106  phGeom->Write();
107  rpGeom->Write();
108  ZdcC->Write();
109 
110  // De-smear the real data if possible
111  // Start with matrix of found (rows) and generated (columns),
112  // invert, then apply to found data
113  LOG_INFO << "StSpaceChargeDistMaker: attempting to de-smear..." << endm;
114  for (Int_t zbin=1; zbin<=nz; zbin++) { // do the matrices for each z bin one at a time
115 
116  Int_t bingen,binfnd,desmearing_mode = -1;
117  Double_t denom,Det;
118 
119  Det = 1.0;
120  TMatrixD& MatM = *(RPMats[zbin-1]);
121  TVectorD& MatH = *(RPMatHs[zbin-1]);
122  for (bingen=0; bingen<nrph; bingen++) {
123  denom = MatH[bingen];
124  for (binfnd=0; binfnd<nrph; binfnd++) {
125  if (denom > 0) MatM[binfnd][bingen] /= denom;
126  else if (binfnd==bingen) MatM[binfnd][bingen] = 1.0; // diagonals should be ~1
127  }
128  }
129  if (MatH.Sum()) {
130  MatM.Invert(&Det);
131  MatM.Write(Form("RPMat%03d",zbin));
132  MatH.Write(Form("RPMatH%03d",zbin));
133  }
134 
135  if (Det) {
136  desmearing_mode = 2; // r-phi
137  } else {
138  Det = 1.0;
139  MatM = *(RMats[zbin-1]);
140  MatH = *(RMatHs[zbin-1]);
141  for (bingen=0; bingen<nr; bingen++) {
142  denom = MatH[bingen];
143  for (binfnd=0; binfnd<nr; binfnd++) {
144  if (denom > 0) MatM[binfnd][bingen] /= denom;
145  else if (binfnd==bingen) MatM[binfnd][bingen] = 1.0;
146  }
147  }
148  if (MatH.Sum()) {
149  MatM.Invert(&Det);
150  MatM.Write(Form("RMat%03d",zbin));
151  MatH.Write(Form("RMatH%03d",zbin));
152  }
153 
154  if (Det) {
155  LOG_INFO << "StSpaceChargeDistMaker: z bin " << zbin
156  << " will use r matrices instead of r-phi" << endm;
157  desmearing_mode = 1; // r
158  } else {
159  LOG_WARN << "StSpaceChargeDistMaker: z bin " << zbin
160  << " could not invert matrices, giving up!" << endm;
161  desmearing_mode = 0; // cannot do de-smearing
162  }
163  }
164 
165 
166  if (desmearing_mode > 0) {
167  Double_t newcontPRZ, newcontU, coef;
168  for (Int_t rbin=1; rbin<=nr; rbin++) {
169  for (Int_t phibin=1; phibin<=nph; phibin++) {
170  bingen = (rbin-1) + (desmearing_mode == 2 ? nr*(phibin-1) : 0);
171  newcontPRZ = 0;
172  newcontU = 0;
173  for (Int_t rbin2=1; rbin2<=nr; rbin2++) {
174  for (Int_t phibin2=1; phibin2<=nph; phibin2++) {
175  if (desmearing_mode == 1 && phibin2 != phibin) continue;
176  binfnd = (rbin2-1) + (desmearing_mode == 2 ? nr*(phibin2-1) : 0);
177  coef = MatM[bingen][binfnd];
178  if (TMath::IsNaN(coef)) {
179  LOG_ERROR << "StSpaceChargeDistMaker: de-smearing matrix element ["
180  << bingen << "][" << binfnd << "] (zbin=" << zbin << ") is NaN !"
181  << endm;
182  } else {
183  newcontPRZ += coef * S3CPRZ->GetBinContent(phibin2,rbin2,zbin);
184  newcontU += coef * S3CU ->GetBinContent(phibin2,rbin2,zbin);
185  }
186  }
187  }
188  Space3ChargePRZ->SetBinContent(phibin,rbin,zbin,newcontPRZ);
189  Space3ChargeU ->SetBinContent(phibin,rbin,zbin,newcontU );
190  }
191  }
192  }
193 
194  } // z bins
195 
196 
197  Space3ChargePRZ->Write();
198  Space3ChargeU->Write();
199 
200  ff->Close();
201 
202  delete Space3ChargePRZ;
203  delete Space3ChargeU;
204 
205  return kStOk;
206 }
207 //_____________________________________________________________________________
208 Int_t StSpaceChargeDistMaker::InitRun(Int_t run) {
209  if (thrownR->GetEntries() < 1) GeomInit();
210  return kStOk;
211 }
212 //_____________________________________________________________________________
213 Int_t StSpaceChargeDistMaker::Init() {
214  Space3ChargePRZ = new TH3D("Space3ChargePRZ","Space charged versus Phi(rads), Rho and Z",
215  nph,phmin,phmax,nr,rmin,rmax,nz,zmin,zmax);
216  Space3ChargeU = new TH3D("Space3ChargeU" ,"Space charged versus Phi(rads), Rho and Z (on tracks)",
217  nph,phmin,phmax,nr,rmin,rmax,nz,zmin,zmax);
218  Space3ChargePRZ->Sumw2();
219  Space3ChargeU->Sumw2();
220  thrownR = new TH2D("R","r",nr,rmin,rmax,3,-1.5,1.5);
221  acceptedR = new TH2D("P","pads",nr,rmin,rmax,3,-1.5,1.5);
222  thrownRP = new TH3D("RP","rp",nr,rmin,rmax,nph,phmin,phmax,3,-1.5,1.5);
223  acceptedRP = new TH3D("RPP","pads rp",nr,rmin,rmax,nph,phmin,phmax,3,-1.5,1.5);
224  thrownP = new TH2D("PH","phi",nph,phmin,phmax,3,-1.5,1.5);
225  acceptedP = new TH2D("PP","pads phi",nph,phmin,phmax,3,-1.5,1.5);
226  ZdcC = new TH1D("ZdcC","ZDC coincidence rate",1024,0,ZdcMax);
227 
228  for (int i=0;i<nz;i++) {
229  RPMats[i] = new TMatrixD(nrph,nrph);
230  RPMatHs[i] = new TVectorD(nrph);
231  RMats[i] = new TMatrixD(nr,nr);
232  RMatHs[i] = new TVectorD(nr);
233  RPMats[i]->SetTol(1e-6);
234  RMats[i]->SetTol(1e-6);
235  }
236 
237  return StMaker::Init();
238 }
239 //_____________________________________________________________________________
241 
242  if (trigs.GetSize() < 1) {
243  LOG_ERROR << "StSpaceChargeDistMaker: NO ACCEPTABLE TRIGGERS DEFINED!" << endm;
244  return kStErr;
245  }
246 
247  // Get StEvent and related info, determine if things are OK
248  event = static_cast<StEvent*>(GetInputDS("StEvent"));
249  if (!event) {
250  LOG_WARN << "StSpaceChargeDistMaker: no StEvent; skipping event." << endm;
251  return kStWarn;
252  }
253 
254  // Accept all triggers if first trig id is -1, otherwise compare the list
255  if (trigs.At(0) >= 0) {
256  Bool_t passTrigs = kFALSE;
257  if (event->triggerIdCollection() &&
258  event->triggerIdCollection()->nominal()) {
259  for (Int_t i=0; (!passTrigs) && (i<trigs.GetSize()); i++) {
260  passTrigs = event->triggerIdCollection()->nominal()->isTrigger(trigs.At(i));
261  }
262  if (!passTrigs) { LOG_WARN << "StSpaceChargeDistMaker: Triggers not accepted" << endm; }
263  } else { LOG_WARN << "StSpaceChargeDistMaker: Could not find nominal trigger id collection" << endm; }
264  if (!passTrigs) return kStOK;
265  }
266 
267  if (!gStTpcDb) {
268  LOG_ERROR << "StSpaceChargeDistMaker: no gStTpcDb - should quit!" << endm;
269  return kStFatal;
270  }
271  static StTpcCoordinateTransform transform(gStTpcDb);
272  static StTpcLocalCoordinate coorLT; // local TPC coordinate
273  //static StTpcLocalSectorCoordinate coorLS; // local sector coordinate
274 
275  static dEdxY2_t CdEdx;
276  static Int_t number_dedx_faults = 0;
277  static Int_t warn_dedx_faults = 1;
278  static StTpcdEdxCorrection* m_TpcdEdxCorrection = 0;
279  if (!m_TpcdEdxCorrection) {
280  Int_t Mask = -1; // 22 bits
281  // Don't know dX, so exclude this correction
282  CLRBIT(Mask,StTpcdEdxCorrection::kdXCorrection);
283  m_TpcdEdxCorrection = new StTpcdEdxCorrection(Mask, Debug());
284  }
285  if (!m_TpcdEdxCorrection) {
286  LOG_ERROR << "StSpaceChargeDistMaker: no dE/dx corrections - should quit!" << endm;
287  return kStFatal;
288  }
289 
290 
291  StTpcHitCollection* TpcHitCollection = event->tpcHitCollection();
292  if (TpcHitCollection) {
293  Double_t zdcc = event->runInfo()->zdcCoincidenceRate();
294  ZdcC->Fill(zdcc);
295  if (zdcc>ZdcMax) {
296  LOG_WARN << "StSpaceChargeDistMaker: ZDC rate greater than hist max ( "
297  << zdcc << " > " << ZdcMax << " )" << endm;
298  }
299  if (!run) run = event->runId();
300 
301  UInt_t numberOfSectors = TpcHitCollection->numberOfSectors();
302  for (UInt_t i = 0; i< numberOfSectors; i++) {
303  StTpcSectorHitCollection* sectorCollection = TpcHitCollection->sector(i);
304  if (sectorCollection) {
305  Int_t numberOfPadrows = sectorCollection->numberOfPadrows();
306  for (Int_t j = 0; j< numberOfPadrows; j++) {
307  if (! LiveRow[j + NP*i]) continue;
308  StTpcPadrowHitCollection *rowCollection = TpcHitCollection->sector(i)->padrow(j);
309  if (rowCollection) {
310  UInt_t NoHits = rowCollection->hits().size();
311  for (UInt_t k = 0; k < NoHits; k++) {
312  StTpcHit* tpcHit = TpcHitCollection->sector(i)->padrow(j)->hits().at(k);
313  const StThreeVectorF& positionG = tpcHit->position();
314 
315  // Discard hits near endcaps
316  if (TMath::Abs(positionG.z()) > 200) continue;
317 
318  // Discard outermost 4 pads on any row (pad is [1..Npad])
319  if (tpcHit->pad() < 5 || tpcHit->pad() > Npads[j]-4) continue;
320 
321  // Problematic or false hits?
322  Float_t charge = tpcHit->charge();
323  if (charge <= 0) continue;
324 
325  // Want to fill histograms in TPC local, sector-aligned coordinates
326  // Need to convert global coords to TPC local coords
327  StGlobalCoordinate coorG(positionG);
328  transform(coorG,coorLT,i+1,j+1);
329  StThreeVectorD& positionL = coorLT.position();
330  //transform(coorLT,coorLS);
331 
332  // Discard post-central-membrane and hits at gated grid opening
333  if (positionL.z() * (((Float_t) i)-11.5) > 0) continue;
334  if (TMath::Abs(positionL.z()) > 180) continue;
335 
336  // dE/dx corrections to charge copied from StTpcRSMaker
337  memset(&CdEdx, 0, sizeof(dEdxY2_t));
338  CdEdx.DeltaZ = 5.2;
339  CdEdx.QRatio = -2;
340  CdEdx.QRatioA= -2.;
341  CdEdx.QSumA = 0;
342  CdEdx.sector = i+1;
343  CdEdx.row = j+1;
344  Double_t Qcm = St_TpcAvgCurrentC::instance()->AcChargeRowL(CdEdx.sector,CdEdx.row); // C/cm
345  CdEdx.pad = tpcHit->pad();
346  CdEdx.edge = CdEdx.pad;
347  if (CdEdx.edge > 0.5*Npads[j])
348  CdEdx.edge += 1 - Npads[j];
349  CdEdx.F.dE = charge;
350  CdEdx.adc = tpcHit->adc();
351  CdEdx.F.dx = XWID[j];
352  CdEdx.xyz[0] = positionL.x();
353  CdEdx.xyz[1] = positionL.y();
354  CdEdx.xyz[2] = positionL.z();
355  Double_t probablePad = ((Double_t) Npads[j])/2.;
356  Double_t pitch = St_tpcPadConfigC::instance()->PadPitchAtRow(CdEdx.sector,CdEdx.row);
357  Double_t PhiMax = TMath::ATan2(probablePad*pitch, Xpads[j]);
358  CdEdx.PhiR = TMath::ATan2(CdEdx.xyz[0],CdEdx.xyz[1])/PhiMax;
359  //CdEdx.xyzD[] left as 0 as these hits are not necessarily on tracks
360  CdEdx.zG = CdEdx.xyz[2];
361  CdEdx.Qcm = 1e6*Qcm; // uC/cm
362  CdEdx.Crow = St_TpcAvgCurrentC::instance()->AvCurrRow(CdEdx.sector,CdEdx.row);
363  CdEdx.Zdc = zdcc;
364  //CdEdx.ZdriftDistance = coorLS.position().z(); // drift length
365  // random drift length (may be wrong by as much as +/-full drift length)
366  // is worse than fixed at half full drift length (wrong by as much as
367  // +/-half full drift length, RMS of error down by sqrt(2))
368  CdEdx.ZdriftDistance = 104.3535;
369  St_tpcGas *tpcGas = m_TpcdEdxCorrection->tpcGas();
370  if (tpcGas)
371  CdEdx.ZdriftDistanceO2 = CdEdx.ZdriftDistance*(*tpcGas)[0].ppmOxygenIn;
372  Int_t dedx_status = m_TpcdEdxCorrection->dEdxCorrection(CdEdx);
373  if (dedx_status) {
374  number_dedx_faults++;
375  if (number_dedx_faults == warn_dedx_faults) {
376  LOG_WARN << "StSpaceChargeDistMaker: found at least " <<
377  number_dedx_faults << " dE/dx fault(s), code: " << dedx_status << endm;
378  warn_dedx_faults *= 10;
379  }
380  if (Debug()) {
381  LOG_WARN << Form("FAULT: %d %d %d %g %d %g %g %g %g %g\n",dedx_status,
382  i+1,j+1,tpcHit->pad(),Npads[j],
383  positionL.x(),positionL.y(),positionL.z(),
384  charge,CdEdx.F.dE) << endm;
385  }
386  continue;
387  }
388  charge = CdEdx.F.dE;
389 
390  Space3ChargePRZ->Fill(positionL.phi(),
391  positionL.perp(),
392  positionL.z(),
393  charge);
394  if (tpcHit->trackReferenceCount() > 0)
395  Space3ChargeU ->Fill(positionL.phi(),
396  positionL.perp(),
397  positionL.z(),
398  charge);
399  for (Double_t throwi = throws; throwi>0; throwi--)
400  if (throwi>=1 || ((Int_t) (gRandom->Rndm()/throwi))==0)
401  GeomFill(positionL.z());
402  }
403  }
404  }
405  }
406  }
407  }
408  return kStOk;
409 }
410 //_____________________________________________________________________________
411 void StSpaceChargeDistMaker::GeomInit() {
412 
413  // Calculated in sector 3 coordinates
414 
415  GGZ = St_tpcDimensionsC::instance()->gatingGridZ();
416  NP = St_tpcPadConfigC::instance()->padRows(20); // # padrows (45)
417  NR = 256; // max # pads/padrow (actually 182)
418  NS = NP * NR; // > # pads/sector
419 
420  /*
421  Double_t XWID[2] = {1.2, 2.}; //{1.15, 1.95};
422  Double_t pitches[2] = {0.335, 0.67};
423  Double_t Xpads[NP] = {
424  60.0, 64.8, 69.6, 74.4, 79.2, 84.0, 88.8, 93.6, 98.8, 104.0,109.2,114.4,119.6, // inner Centres
425  127.195, 129.195, 131.195, 133.195, 135.195, //Outer
426  137.195, 139.195, 141.195, 143.195, 145.195,
427  147.195, 149.195, 151.195, 153.195, 155.195,
428  157.195, 159.195, 161.195, 163.195, 165.195,
429  167.195, 169.195, 171.195, 173.195, 175.195,
430  177.195, 179.195, 181.195, 183.195, 185.195,
431  187.195, 189.195};
432  Int_t Npads[NP] = {
433  88,96,104,112,118,126,134,142,150,158,166,174,182, // inner Centres
434  98,100,102,104,106,106,108,110,112,112,114,116,118,120,122,122, //Outer
435  124,126,128,128,130,132,134,136,138,138,140,142,144,144,144,144};
436  */
437 
438  Float_t pitch;
439  Int_t i,j,k,l,m,isec,irow,ipad;
440 
441  LOG_INFO << "StSpaceChargeDistMaker: Now reading live/dead/gains for acceptance" << endm;
442  for (i = 0; i < 24; i++) {
443  isec = i + 1;
444  Float_t* gainScales = St_TpcSecRowBC::instance()->GainScale(i);
445  for (j = 0; j < NP; j++) {
446  irow = j + 1;
447  pitch = St_tpcPadConfigC::instance()->PadPitchAtRow(20,irow);
448  if (i==0) {
449  Npads[j] = St_tpcPadConfigC::instance()->padsPerRow(20,irow);
450  Xpads[j] = St_tpcPadConfigC::instance()->radialDistanceAtRow(20,irow);
451  XWID[j] = St_tpcPadConfigC::instance()->PadLengthAtRow(20,irow);
452  XMIN[j] = Xpads[j] - 0.5*XWID[j];
453  }
454  m = j + NP*i;
455  LiveRow[m] = (StDetectorDbTpcRDOMasks::instance()->isOn(isec,
456  StDetectorDbTpcRDOMasks::instance()->rdoForPadrow(isec,irow)) &&
457  (St_tss_tssparC::instance()->gain(isec,irow) > 0) &&
458  gainScales[j]>0); // gainScales necessary for dE/dx
459 
460  for (k=0; k<Npads[j]; k++) {
461  ipad = Npads[j] - k;
462  l = k + NR*j + NS*i;
463  LivePad[l] = (LiveRow[m] &&
464  k>3 && k<Npads[j]-4 && // exclude outermost 4 pads on any row
465  St_tpcPadGainT0BC::instance()->Gain(isec,irow,ipad) > MINGAIN);
466  if (i==0) YMIN[l] = pitch * (k - 0.5*Npads[j]);
467  }
468  }
469  }
470  LOG_INFO << "StSpaceChargeDistMaker: will throw approximately 12*" << throws << " hits per TPC hit." << endm;
471 
472 }
473 //_____________________________________________________________________________
474 void StSpaceChargeDistMaker::GeomFill(Float_t z) {
475 
476  // Monte Carlo approach to determining geometrical acceptance
477  Float_t pitch;
478  Int_t j,k,l,i=1;
479 
480  // phi0 and phi3 will be in sector 3 local coordinates
481  // phi and phi2 are in TPC local coordinates
482  // already required z as correct side for sector before GeomFill()
483  Float_t phi0,phi,phi2,phi3,phi4,r,r2,r4,x,y,zbin,zpileup;
484  Float_t pos1[3];
485  Float_t pos2[3];
486  Float_t pos4[3];
487  Int_t ix,iy;
488  Int_t rbin,phibin,tempbin,bingen,binfnd,bingenR,binfndR;
489 
490  // must use StEvtTrigDetSumsMaker if reading from event.root
491  StMagUtilities* mExB = StMagUtilities::Instance();
492 
493  // for r^-1.71 in r:
494  static const Double_t rdist0 = -1.71 + 1.0;
495  // static const Double_t rdist1 = TMath::Power(rmin,rdist0);
496  // save some CPU by starting at r=49 since acceptance is zero below that...
497  static const Double_t rdist1 = TMath::Power(49,rdist0);
498  static const Double_t rdist2 = TMath::Power(rmax,rdist0) - rdist1;
499  static const Double_t rdist3 = 1.0/rdist0;
500 
501  while (i < 12*TMath::Max(1,(Int_t) throws)) {
502  // flat in r:
503  // r = rmin + gRandom->Rndm()*(rmax - rmin);
504 
505  // r^-1.71 in r:
506  r = TMath::Power(rdist1 + rdist2*gRandom->Rndm(),rdist3);
507 
508  phi0 = PhiMax*(2*gRandom->Rndm() - 1); //sector 3 coordinates
509  j = (Int_t) (12*gRandom->Rndm());
510  zpileup = GGZ*gRandom->Rndm();
511  if (j>=12) j-=12;
512  if (z > 0) { // west end
513  zbin = 1;
514  k = j; // k = [0..11]
515  phi = phi0 - (k-2)*TMath::Pi()/6.0;
516  } else { // east end
517  zbin = -1;
518  k = j + 12; // k = [12..23]
519  phi = -phi0 + (k-20)*TMath::Pi()/6.0;
520  zpileup *= -1.0;
521  }
522  while (phi>=phmax) phi -= TMath::TwoPi();
523  while (phi< phmin) phi += TMath::TwoPi();
524  thrownR->Fill(r,0);
525  thrownRP->Fill(r,phi,0);
526  thrownP->Fill(phi,0);
527  thrownR->Fill(r,zbin);
528  thrownRP->Fill(r,phi,zbin);
529  thrownP->Fill(phi,zbin);
530 
531  // Apply distortions in TPC local
532  pos1[0] = r*TMath::Cos(phi);
533  pos1[1] = r*TMath::Sin(phi);
534  pos1[2] = zpileup;
535  mExB->DoDistortion(pos1,pos2,k+1);
536  phi2 = TMath::ATan2(pos2[1],pos2[0]);
537  r2 = TMath::Sqrt(pos2[0]*pos2[0]+pos2[1]*pos2[1]);
538 
539  // Ignoring misalignment of TPC
540  // but transforming back to sector 3
541  phi3 = phi0 + ((phi2-phi)*(pos2[2] < 0 ? -1.0 : 1.0));
542  x = r2*TMath::Cos(phi3);
543  y = r2*TMath::Sin(phi3);
544 
545  // Determine if hit falls on a pad
546  ix = (Int_t) (TMath::BinarySearch(NP,&XMIN[0],x));
547  if (ix < 0 || ix >= NP) continue;
548  pitch = St_tpcPadConfigC::instance()->PadPitchAtRow(20,ix+1);
549  if (x > XMIN[ix] + XWID[ix]) continue;
550  iy = (Int_t) (TMath::BinarySearch(Npads[ix],&YMIN[ix*NR],y));
551  if (y > YMIN[iy + ix*NR] + pitch) continue;
552 
553  // Determine if hit falls on an active pad
554  // Use gains file:
555  l = iy + ix*NR + k*NS;
556  if (! LivePad[l]) continue;
557 
558  // The need to exclude channels like the following should no
559  // longer be necessary, but I am leaving it commented here
560  // as an example for possible testing purposes. -GVB
561  //
562  // Sector 20 RDO problem: account for only 23 sectors active
563  // for padrows 9-21.
564  //if (k==19 && ix >=8 && ix <=20) continue;
565  // Sector 5 RDO problem: account for only 23 sectors active
566  // for padrow 39.
567  //if (k==4 && ix == 38) continue;
568 
569  // ACCEPTED!
570 
571  if (Debug()) {
572  LOG_INFO << "r " << r << "\tphi " << phi << "\tx " << x << "\tix " << ix
573  << "\tXMIN[ix] " << XMIN[ix] << "\tRMAX " << XMIN[ix] + XWID[ix];
574  if (ix < 44) { LOG_INFO << "\tXMIN[ix+1] " << XMIN[ix+1]; }
575  if (x <= XMIN[ix] + XWID[ix]) { LOG_INFO << " o.k."; }
576  LOG_INFO << endm;
577  }
578 
579  pos2[2] = z; // generated at zpileup, but found at z
580  mExB->UndoDistortion(pos2,pos4,k+1);
581  phi4 = TMath::ATan2(pos4[1],pos4[0]);
582  r4 = TMath::Sqrt(pos4[0]*pos4[0]+pos4[1]*pos4[1]);
583  // generated at (r,phi), but found at (r4,phi4)
584  acceptedRP->GetBinXYZ(acceptedRP->FindBin(r ,phi ,0),rbin,phibin,tempbin);
585  bingen = (rbin-1) + nr*(phibin-1);
586  bingenR = rbin-1;
587  acceptedRP->GetBinXYZ(acceptedRP->FindBin(r4,phi4,0),rbin,phibin,tempbin);
588  binfnd = (rbin-1) + nr*(phibin-1);
589  binfndR = rbin-1;
590  int zbin4 = Space3ChargePRZ->GetZaxis()->FindBin(z) - 1;
591  (*(RPMats[zbin4]))[binfnd][bingen]++;
592  (*(RPMatHs[zbin4]))[bingen]++;
593  (*(RMats[zbin4]))[binfndR][bingenR]++;
594  (*(RMatHs[zbin4]))[bingenR]++;
595 
596  acceptedR->Fill(r,0);
597  acceptedP->Fill(phi,0);
598  acceptedRP->Fill(r,phi,0);
599  acceptedR->Fill(r,zbin);
600  acceptedP->Fill(phi,zbin);
601  acceptedRP->Fill(r,phi,zbin);
602  i++;
603  } // i
604 }
605 
606 
607 //_____________________________________________________________________________
608 // $Id: StSpaceChargeDistMaker.cxx,v 1.11 2018/10/17 20:45:27 fisyak Exp $
609 // $Log: StSpaceChargeDistMaker.cxx,v $
610 // Revision 1.11 2018/10/17 20:45:27 fisyak
611 // Restore update for Run XVIII dE/dx calibration removed by Gene on 08/07/2018
612 //
613 // Revision 1.10 2018/04/11 02:43:21 smirnovd
614 // Enable TPC/iTPC switch via St_tpcPadConfig
615 //
616 // This is accomplished by substituting St_tpcPadPlanes with St_tpcPadConfig.
617 // A sector ID is passed to St_tpcPadConfig in order to extract parameters for
618 // either TPC or iTPC
619 //
620 // Revision 1.9 2017/02/14 23:38:38 fisyak
621 // Adjustment to structure changes in StTpcdEdxCorrection
622 //
623 // Revision 1.8 2016/05/11 20:44:52 genevb
624 // Initialize vars, cast to double for division
625 //
626 // Revision 1.7 2015/12/18 17:31:40 genevb
627 // Updated copy of TpcRS code for dE/dx
628 //
629 // Revision 1.6 2015/05/19 19:36:09 genevb
630 // Code cleanup in preparation for C++11
631 //
632 // Revision 1.5 2012/11/28 02:08:52 genevb
633 // Remove de-smearing bias in z and treat z more differentially
634 //
635 // Revision 1.4 2012/11/13 22:05:19 genevb
636 // Use TPC dE/dx correction code, and introduce de-smearing
637 //
638 // Revision 1.3 2012/10/15 17:51:12 genevb
639 // Include distortion corrections, which must be evenly sampled per event (per hit)
640 //
641 // Revision 1.2 2012/09/13 20:58:56 fisyak
642 // Corrections for iTpx
643 //
644 // Revision 1.1 2012/07/06 17:23:00 genevb
645 // Introduce StSpaceChargeDistMaker
646 //
647 //
virtual void DoDistortion(const Float_t x[], Float_t Xprime[], Int_t Sector=-1)
Main Entry Point for requests to DO the E and B field distortions (for simulations) ...
Definition: Stypes.h:42
Definition: Stypes.h:40
Definition: Stypes.h:44
Definition: Stypes.h:41