14 #include "StTpcRSMaker.h"
17 #include "StGlobals.hh"
18 #include "StThreeVectorD.hh"
19 #include "StPhysicalHelixD.hh"
21 #include "TClassTable.h"
22 #include "TDataSetIter.h"
23 #include "TTableSorter.h"
27 #include "TBenchmark.h"
28 #include "TProfile2D.h"
30 #include "TVirtualMC.h"
31 #include "TInterpreter.h"
32 #include "Math/SpecFuncMathMore.h"
33 #include "StDbUtilities/StCoordinates.hh"
34 #include "StDbUtilities/StTpcCoordinateTransform.hh"
36 #include "StDbUtilities/StMagUtilities.h"
38 #include "StDetectorDbMaker/St_tpcAltroParamsC.h"
39 #include "StDetectorDbMaker/St_asic_thresholdsC.h"
40 #include "StDetectorDbMaker/St_tss_tssparC.h"
41 #include "StDetectorDbMaker/St_tpcPadGainT0BC.h"
42 #include "StDetectorDbMaker/St_TpcResponseSimulatorC.h"
43 #include "StDetectorDbMaker/St_tpcAnodeHVavgC.h"
44 #include "StDetectorDbMaker/StDetectorDbTpcRDOMasks.h"
45 #include "StDetectorDbMaker/St_tpcPadConfigC.h"
46 #include "StDetectorDbMaker/St_tpcGainCorrectionC.h"
47 #include "StDetectorDbMaker/St_TpcAvgCurrentC.h"
48 #include "StDetectorDbMaker/St_TpcAvgPowerSupplyC.h"
49 #include "StDetectorDbMaker/St_trigDetSumsC.h"
50 #include "StDetectorDbMaker/St_tpcBXT0CorrEPDC.h"
51 #include "StDetectorDbMaker/St_TpcPadPedRMSC.h"
52 #include "StEventUtilities/StEbyET0.h"
53 #include "StDetectorDbMaker/St_beamInfoC.h"
54 #include "StDetectorDbMaker/St_GatingGridBC.h"
55 #include "StDetectorDbMaker/St_starTriggerDelayC.h"
57 #include "StParticleTable.hh"
58 #include "StParticleDefinition.hh"
62 #include "StBichsel/Bichsel.h"
63 #include "StBichsel/StdEdxModel.h"
64 #include "StdEdxY2Maker/StTpcdEdxCorrection.h"
66 #include "tables/St_g2t_track_Table.h"
67 #include "tables/St_g2t_vertex_Table.h"
68 #include "tables/St_g2t_tpc_hit_Table.h"
69 #include "StEventTypes.h"
75 g2t_tpc_hit_st *tpc_hitC;
84 #ifdef __TFG__VERSION__
86 #define __CHECK_RDOMAP_AND_VOLTAGE__
88 #if defined(__DEBUG__)
89 #define PrPP(A,B) if (Debug()%10 > 2) {LOG_INFO << "StTpcRSMaker::" << (#A) << "\t" << (#B) << " = \t" << (B) << endm;}
93 static const char rcsid[] =
"$Id: StTpcRSMaker.cxx,v 1.92 2020/05/22 20:49:19 fisyak Exp $";
95 static Bool_t ClusterProfile = kFALSE;
97 static Bool_t ClusterProfile = kTRUE;
102 static Double_t t0IO[2] = {1.20868e-9, 1.43615e-9};
103 static const Double_t tauC[2] = {999.655e-9, 919.183e-9};
104 TF1* StTpcRSMaker::fgTimeShape3[2] = {0, 0};
105 TF1* StTpcRSMaker::fgTimeShape0[2] = {0, 0};
106 static Double_t fgTriggerT0 = 0;
107 static Double_t timeBinMin = -0.5;
108 static Double_t timeBinMax = 44.5;
110 static const Int_t nx[4] = {200,500, 145, 401};
111 static const Double_t xmin[4] = {-10., -6, -0.5, -0.5};
112 static const Double_t xmax[4] = { 10., 44,144.5, 400.5};
113 static const Int_t nz = 42;
114 static const Double_t zmin = -210;
115 static const Double_t zmax = -zmin;
117 static TProfile2D *hist[4][2] = {0};
118 static TProfile2D *PixelHist[2] = {0};
119 static TProfile2D *GainHist[2] = {0};
120 static const Int_t nChecks = 22;
121 static TH1 *checkList[2][22] = {0};
122 static TString TpcMedium(
"TPCE_SENSITIVE_GAS");
123 Short_t StTpcRSMaker::mADCs[__MaxNumberOfTimeBins__];
127 StTpcRSMaker::StTpcRSMaker(
const char *name):
131 ElectronRange(0.0055),
132 ElectronRangeEnergy(3000),
133 ElectronRangePower(1.78),
136 NoOfTimeBins(__MaxNumberOfTimeBins__),
139 memset(beg, 0, end-beg+1);
142 SETBIT(m_Mode,kBICHSEL);
143 SETBIT(m_Mode,kdEdxCorr);
144 SETBIT(m_Mode,kDistortion);
147 StTpcRSMaker::~StTpcRSMaker() {
153 if (m_SignalSum) {free(m_SignalSum); m_SignalSum = 0;}
154 for (Int_t io = 0; io < 2; io++) {
155 for (Int_t sec = 0; sec < NoOfSectors; sec++) {
156 if (mShaperResponses[io][sec] && !mShaperResponses[io][sec]->TestBit(kNotDeleted)) {SafeDelete(mShaperResponses[io][sec]);}
157 if (mChargeFraction[io][sec] && !mChargeFraction[io][sec]->TestBit(kNotDeleted)) {SafeDelete(mChargeFraction[io][sec]);}
158 if (mPadResponseFunction[io][sec] && !mPadResponseFunction[io][sec]->TestBit(kNotDeleted)) {SafeDelete(mPadResponseFunction[io][sec]);}
159 if (mAltro[io][sec] && !mAltro[io][sec]->TestBit(kNotDeleted)) {SafeDelete(mAltro[io][sec]);}
161 SafeDelete(mPolya[io]);
163 if (m_TpcdEdxCorrection && m_TpcdEdxCorrection->TestBit(kCanDelete))
delete m_TpcdEdxCorrection;
164 m_TpcdEdxCorrection = 0;
168 Int_t StTpcRSMaker::InitRun(Int_t ) {
169 SetAttr(
"minSector",1);
170 SetAttr(
"maxSector",24);
172 SetAttr(
"maxRow",St_tpcPadConfigC::instance()->numberOfRows(20));
174 LOG_ERROR <<
"Database Missing! Can't initialize TpcRS" << endm;
177 mCutEle = GetCutEle();
179 LOG_INFO <<
"StTpcRSMaker::InitRun: mCutEle set to = " << mCutEle <<
" from geant \"" << TpcMedium.Data() <<
"\" parameters" << endm;
182 LOG_ERROR <<
"StTpcRSMaker::InitRun: mCutEle has not been found in GEANT3 for \"" << TpcMedium.Data() <<
"\" parameters."
183 <<
"Probably due to missing Set it to default " << mCutEle << endm;
186 if (TESTBIT(
m_Mode,kdEdxCorr)) {
187 LOG_INFO <<
"StTpcRSMaker:: use Tpc dE/dx correction from calibaration" << endm;
189 CLRBIT(Mask,StTpcdEdxCorrection::kAdcCorrection);
190 CLRBIT(Mask,StTpcdEdxCorrection::kAdcCorrectionC);
191 CLRBIT(Mask,StTpcdEdxCorrection::kEdge);
192 CLRBIT(Mask,StTpcdEdxCorrection::kAdcCorrectionMDF);
193 CLRBIT(Mask,StTpcdEdxCorrection::kAdcCorrection3MDF);
194 CLRBIT(Mask,StTpcdEdxCorrection::kAdcCorrection4MDF);
195 CLRBIT(Mask,StTpcdEdxCorrection::kAdcCorrection5MDF);
196 CLRBIT(Mask,StTpcdEdxCorrection::kAdcCorrection6MDF);
197 CLRBIT(Mask,StTpcdEdxCorrection::kEtaCorrection);
198 CLRBIT(Mask,StTpcdEdxCorrection::knTbk);
199 CLRBIT(Mask,StTpcdEdxCorrection::kzCorrectionC);
200 CLRBIT(Mask,StTpcdEdxCorrection::kzCorrection);
202 CLRBIT(Mask,StTpcdEdxCorrection::kdXCorrection);
203 CLRBIT(Mask,StTpcdEdxCorrection::kTpcPadTBins);
204 CLRBIT(Mask,StTpcdEdxCorrection::kTanL);
205 CLRBIT(Mask,StTpcdEdxCorrection::kAdcI);
206 CLRBIT(Mask,StTpcdEdxCorrection::knPad);
207 CLRBIT(Mask,StTpcdEdxCorrection::kdZdY);
208 CLRBIT(Mask,StTpcdEdxCorrection::kdXdY);
211 m_TpcdEdxCorrection->SetSimulation();
213 if (TESTBIT(
m_Mode,kDistortion)) {
214 LOG_INFO <<
"StTpcRSMaker:: use Tpc distortion correction" << endm;
216 Double_t samplingFrequency = 1.e6*gStTpcDb->Electronics()->samplingFrequency();
217 Double_t TimeBinWidth = 1./samplingFrequency;
226 numberOfInnerSectorAnodeWires = gStTpcDb->WirePlaneGeometry()->numberOfInnerSectorAnodeWires ();
227 firstInnerSectorAnodeWire = gStTpcDb->WirePlaneGeometry()->firstInnerSectorAnodeWire();
228 lastInnerSectorAnodeWire = gStTpcDb->WirePlaneGeometry()->lastInnerSectorAnodeWire ();
229 numberOfOuterSectorAnodeWires = gStTpcDb->WirePlaneGeometry()->numberOfOuterSectorAnodeWires ();
230 firstOuterSectorAnodeWire = gStTpcDb->WirePlaneGeometry()->firstOuterSectorAnodeWire();
231 lastOuterSectorAnodeWire = gStTpcDb->WirePlaneGeometry()->lastOuterSectorAnodeWire ();
232 anodeWirePitch = gStTpcDb->WirePlaneGeometry()->anodeWirePitch ();
233 anodeWireRadius = gStTpcDb->WirePlaneGeometry()->anodeWireRadius();
234 if (St_tpcPadConfigC::instance()->iTPC(1)) {
235 NoOfPads = St_tpcPadConfigC::instance()->numberOfPadsAtRow(1,72);
238 Float_t xyz[3] = {0,0,0};
239 StMagF::Agufld(xyz,BFieldG);
241 const Char_t *Names[2] = {
"I",
"O"};
242 Double_t CathodeAnodeGap[2] = {0.2, 0.4};
243 for (Int_t sector = 1; sector <= 24; sector++) {
244 innerSectorAnodeVoltage[sector-1] = outerSectorAnodeVoltage[sector-1] = 0;
245 Int_t nAliveInner = 0;
246 Int_t nAliveOuter = 0;
247 for (Int_t row = 1; row <= St_tpcPadConfigC::instance()->numberOfRows(sector); row++) {
248 if (St_tpcPadConfigC::instance()->IsRowInner(sector,row)) {
250 innerSectorAnodeVoltage[sector-1] += St_tpcAnodeHVavgC::instance()->voltagePadrow(sector,row);
253 outerSectorAnodeVoltage[sector-1] += St_tpcAnodeHVavgC::instance()->voltagePadrow(sector,row);
256 if (! nAliveInner && ! nAliveOuter) {
257 LOG_INFO <<
"Illegal date/time. Tpc sector " << sector <<
" Anode Voltage is not set to run condition: AliveInner: " << nAliveInner
258 <<
"\tAliveOuter: " << nAliveOuter
259 <<
"\tStop the run" << endm;
260 assert(nAliveInner || nAliveOuter);
262 if (nAliveInner > 1) innerSectorAnodeVoltage[sector-1] /= nAliveInner;
263 if (nAliveOuter > 1) outerSectorAnodeVoltage[sector-1] /= nAliveOuter;
265 if (GetTFile()) GetTFile()->cd();
266 #ifdef __CHECK_RDOMAP_AND_VOLTAGE__
267 static TH3F *AlivePads = 0;
269 Int_t nrows = St_tpcPadConfigC::instance()->numberOfRows(20);
270 AlivePads =
new TH3F(
"AlivePads",
"Active pads from RDO map, tpcGainPadT0, and Tpc Anode Voltage:sector:row:pad",24,0.5,24.5,nrows,0.5,nrows+.5,NoOfPads,0.5,NoOfPads+0.5);
272 for(Int_t row = 1; row <= St_tpcPadConfigC::instance()->numberOfRows(sector); row++) {
273 Int_t noOfPadsAtRow = St_tpcPadConfigC::instance()->numberOfPadsAtRow(sector,row);
274 if ( ! St_tpcAnodeHVavgC::instance()->livePadrow(sector,row))
continue;
275 for(Int_t pad = 1; pad<=noOfPadsAtRow; pad++) {
276 Int_t iRdo = StDetectorDbTpcRDOMasks::instance()->rdoForPadrow(sector,row,pad);
277 if ( ! StDetectorDbTpcRDOMasks::instance()->isOn(sector,iRdo)) {
280 Double_t gain = St_tpcPadGainT0BC::instance()->Gain(sector,row,pad);
284 AlivePads->Fill(sector, row, pad, gain);
290 for (Int_t io = 0; io < 2; io++) {
292 if (sector > 1 && TMath::Abs(innerSectorAnodeVoltage[sector-1] - innerSectorAnodeVoltage[sector-2]) < 1) {
293 InnerAlphaVariation[sector-1] = InnerAlphaVariation[sector-2];
295 LOG_INFO <<
"Inner Sector " << sector <<
" ======================" << endm;
296 InnerAlphaVariation[sector-1] = InducedCharge(anodeWirePitch,
299 innerSectorAnodeVoltage[sector-1], t0IO[io]);
303 if (sector > 1 && TMath::Abs(outerSectorAnodeVoltage[sector-1] - outerSectorAnodeVoltage[sector-2]) < 1) {
304 OuterAlphaVariation[sector-1] = OuterAlphaVariation[sector-2];
306 LOG_INFO <<
"Outer Sector " << sector <<
" ======================" << endm;
307 OuterAlphaVariation[sector-1] = InducedCharge(anodeWirePitch,
310 outerSectorAnodeVoltage[sector-1], t0IO[io]);
316 for (Int_t io = 0; io < 2; io++) {
330 if (!io ) gamma = St_TpcResponseSimulatorC::instance()->PolyaInner();
331 else gamma = St_TpcResponseSimulatorC::instance()->PolyaOuter();
332 if (gamma <= 0) gamma = 1.38;
333 mPolya[io] =
new TF1F(io == 0 ?
"PolyaInner;x = G/G_0;signal" :
"PolyaOuter;x = G/G_0;signal",polya,0,10,3);
334 mPolya[io]->SetParameters(gamma, 0., 1./gamma);
335 Double_t params3[9] = {t0IO[io],
336 St_TpcResponseSimulatorC::instance()->tauF(),
337 St_TpcResponseSimulatorC::instance()->tauP(),
338 St_TpcResponseSimulatorC::instance()->tauIntegration(),
339 TimeBinWidth, 0, (Double_t ) io, 1.,
340 St_TpcResponseSimulatorC::instance()->tMax()[io]
342 Double_t params0[7] = {t0IO[io], St_TpcResponseSimulatorC::instance()->tauX()[io], TimeBinWidth, St_TpcResponseSimulatorC::instance()->tauC()[io], (Double_t ) io, 1.,
343 St_TpcResponseSimulatorC::instance()->tMax()[io]
345 if (! fgTimeShape3[io]) {
346 fgTimeShape3[io] =
new TF1(Form(
"TimeShape3%s",Names[io]),
347 shapeEI3,timeBinMin*TimeBinWidth,timeBinMax*TimeBinWidth,9);
348 fgTimeShape3[io]->SetParNames(
"t0",
"tauF",
"tauP",
"tauI",
"width",
"tauC",
"io",
"norm",
"tMax");
350 fgTimeShape3[io]->SetParameters(params3);
351 params3[7] = fgTimeShape3[io]->Integral(timeBinMin*TimeBinWidth,timeBinMax*TimeBinWidth);
352 fgTimeShape3[io]->SetTitle(fgTimeShape3[io]->
GetName());
353 fgTimeShape3[io]->GetXaxis()->SetTitle(
"time (secs)");
354 fgTimeShape3[io]->GetYaxis()->SetTitle(
"signal");
355 fgTimeShape3[io]->SetNpx(200);
356 fgTimeShape3[io]->Save(timeBinMin*TimeBinWidth,timeBinMax*TimeBinWidth, 0,0,0,0);
357 if (GetTFile()) fgTimeShape3[io]->Write();
359 if (! fgTimeShape0[io]) {
360 fgTimeShape0[io] =
new TF1(Form(
"TimeShape0%s",Names[io]),
361 shapeEI,timeBinMin*TimeBinWidth,timeBinMax*TimeBinWidth,7);
362 fgTimeShape0[io]->SetParNames(
"t0",
"tauI",
"width",
"tauC",
"io",
"norm",
"tMax");
364 fgTimeShape0[io]->SetParameters(params0);
365 params0[5] = fgTimeShape0[io]->Integral(0,timeBinMax*TimeBinWidth);
366 fgTimeShape0[io]->SetTitle(fgTimeShape0[io]->
GetName());
367 fgTimeShape0[io]->GetXaxis()->SetTitle(
"time (secs)");
368 fgTimeShape0[io]->GetYaxis()->SetTitle(
"signal");
369 fgTimeShape3[io]->SetNpx(200);
370 fgTimeShape0[io]->Save(timeBinMin*TimeBinWidth,timeBinMax*TimeBinWidth, 0,0,0,0);
371 if (GetTFile()) fgTimeShape0[io]->Write();
376 Double_t xmaxP = 4.5;
377 Double_t xminP = -xmaxP;
378 Double_t paramsPad[6];
379 for (Int_t sector = 1; sector <= NoOfSectors; sector++) {
380 if (! mPadResponseFunction[io][sector-1]) {
382 paramsPad[0] = St_tpcPadConfigC::instance()->innerSectorPadWidth(sector);
383 paramsPad[1] = gStTpcDb->WirePlaneGeometry()->innerSectorAnodeWirePadPlaneSeparation();
384 paramsPad[2] = gStTpcDb->WirePlaneGeometry()->anodeWirePitch();
385 paramsPad[3] = St_TpcResponseSimulatorC::instance()->K3IP();
387 paramsPad[5] = St_tpcPadConfigC::instance()->innerSectorPadPitch(sector);
389 paramsPad[0] = St_tpcPadConfigC::instance()->outerSectorPadWidth(sector);
390 paramsPad[1] = gStTpcDb->WirePlaneGeometry()->outerSectorAnodeWirePadPlaneSeparation();
391 paramsPad[2] = gStTpcDb->WirePlaneGeometry()->anodeWirePitch();
392 paramsPad[3] = St_TpcResponseSimulatorC::instance()->K3OP();
394 paramsPad[5] = St_tpcPadConfigC::instance()->outerSectorPadPitch(sector);
398 for (Int_t sec = 1; sec < sector; sec++) {
399 if (mPadResponseFunction[io][sec-1]) {
400 if (! memcmp(paramsPad, mPadResponseFunction[io][sec-1]->GetParameters(),
sizeof(paramsPad))) {
401 mPadResponseFunction[io][sector-1] = mPadResponseFunction[io][sec-1];
407 if (! mPadResponseFunction[io][sector-1]) {
408 mPadResponseFunction[io][sector-1] =
new TF1F(Form(
"%s_%02i",io == 0 ?
"PadResponseFunctionInner" :
"PadResponseFunctionOuter",sector),StTpcRSMaker::PadResponseFunc,xminP,xmaxP,6);
409 mPadResponseFunction[io][sector-1]->SetParameters(paramsPad);
410 mPadResponseFunction[io][sector-1]->SetParNames(
"PadWidth",
"Anode-Cathode gap",
"wire spacing",
"K3OP",
"CrossTalk",
"PadPitch");
411 mPadResponseFunction[io][sector-1]->SetTitle(mPadResponseFunction[io][sector-1]->
GetName());
412 mPadResponseFunction[io][sector-1]->GetXaxis()->SetTitle(
"pads");
413 mPadResponseFunction[io][sector-1]->GetYaxis()->SetTitle(
"Signal");
417 Double_t ymax = mPadResponseFunction[io][sector-1]->Eval(0);
418 for (; x > 1.5; x -= 0.05) {
419 Double_t r = mPadResponseFunction[io][sector-1]->Eval(x)/ymax;
423 mPadResponseFunction[io][sector-1]->SetRange(-x,x);
424 mPadResponseFunction[io][sector-1]->Save(xminP,xmaxP,0,0,0,0);
425 if (GetTFile()) mPadResponseFunction[io][sector-1]->Write();
428 Double_t paramsRow[6] = {0};
429 if (! mChargeFraction[io][sector-1]) {
433 paramsRow[0] = St_tpcPadConfigC::instance()->innerSectorPadLength(sector);
434 paramsRow[1] = gStTpcDb->WirePlaneGeometry()->innerSectorAnodeWirePadPlaneSeparation();
435 paramsRow[2] = gStTpcDb->WirePlaneGeometry()->anodeWirePitch();
436 paramsRow[3] = St_TpcResponseSimulatorC::instance()->K3IR();
440 paramsRow[0] = St_tpcPadConfigC::instance()->outerSectorPadLength(sector);
441 paramsRow[1] = gStTpcDb->WirePlaneGeometry()->innerSectorAnodeWirePadPlaneSeparation();
442 paramsRow[2] = gStTpcDb->WirePlaneGeometry()->anodeWirePitch();
443 paramsRow[3] = St_TpcResponseSimulatorC::instance()->K3OR();
447 for (Int_t sec = 1; sec < sector; sec++) {
448 if (mChargeFraction[io][sec-1]) {
449 if (! memcmp(paramsRow, mChargeFraction[io][sec-1]->GetParameters(),
sizeof(paramsRow))) {
450 mChargeFraction[io][sector-1] = mChargeFraction[io][sec-1];
456 if (! mChargeFraction[io][sector-1]) {
457 mChargeFraction[io][sector-1] =
new TF1F(Form(
"%s_%02i", io == 0 ?
"ChargeFractionInner" :
"ChargeFractionOuter", sector),
458 StTpcRSMaker::PadResponseFunc,xminP,xmaxP,6);
459 mChargeFraction[io][sector-1]->SetParameters(paramsRow);
460 mChargeFraction[io][sector-1]->SetParNames(
"PadLength",
"Anode-Cathode gap",
"wire spacing",
"K3IR",
"CrossTalk",
"RowPitch");
461 mChargeFraction[io][sector-1]->SetTitle(mChargeFraction[io][sector-1]->
GetName());
462 mChargeFraction[io][sector-1]->GetXaxis()->SetTitle(
"Distance (cm)");
463 mChargeFraction[io][sector-1]->GetYaxis()->SetTitle(
"Signal");
466 Double_t ymax = mChargeFraction[io][sector-1]->Eval(0);
467 for (; x > 1.5; x -= 0.05) {
468 Double_t r = mChargeFraction[io][sector-1]->Eval(x)/ymax;
471 mChargeFraction[io][sector-1]->SetRange(-x,x);
472 mChargeFraction[io][sector-1]->Save(xminP,xmaxP,0,0,0,0);
473 if (GetTFile()) mChargeFraction[io][sector-1]->Write();
476 memset(mLocalYDirectionCoupling[io][sector-1], 0,
sizeof(mLocalYDirectionCoupling[io][sector-1]));
477 for (Int_t j = 0; j < 7; j++) {
478 mLocalYDirectionCoupling[io][sector-1][j] = mChargeFraction[io][sector-1]->Eval(anodeWirePitch*j);
482 if (St_tpcAltroParamsC::instance()->Table()->GetNRows() > sector) l = sector - 1;
483 if (io == 0 && St_tpcAltroParamsC::instance()->Table()->GetNRows() > 24 + sector) l += 24;
486 tpcAltroParams_st *Ssector = St_tpcAltroParamsC::instance()->Struct(l);
487 for (Int_t sec = 1; sec < sector; sec++) {
489 if (St_tpcAltroParamsC::instance()->Table()->GetNRows() > sec) lc = sec - 1;
490 if (io == 0 && St_tpcAltroParamsC::instance()->Table()->GetNRows() > 24 + sector) lc += 24;
491 if (mShaperResponses[io][sec-1]) {
492 tpcAltroParams_st *Ssec = St_tpcAltroParamsC::instance()->Struct(lc);
493 if (! memcmp(Ssector,Ssec,
sizeof(tpcAltroParams_st))) {
494 mShaperResponses[io][sector-1] = mShaperResponses[io][sec-1];
495 mAltro[io][sector-1] = mAltro[io][sec-1];
500 if (mShaperResponses[io][sector-1])
continue;
502 if (St_tpcAltroParamsC::instance()->N(l) < 0) {
503 mShaperResponses[io][sector-1] =
new TF1F(Form(
"ShaperFunc_%s_S%02i",Names[io],sector),
504 StTpcRSMaker::shapeEI3_I,timeBinMin,timeBinMax,9);
505 mShaperResponses[io][sector-1]->SetParameters(params3);
506 mShaperResponses[io][sector-1]->SetParNames(
"t0",
"tauF",
"tauP",
"tauI",
"width",
"tauC",
"io",
"norm");
507 mShaperResponses[io][sector-1]->SetTitle(mShaperResponses[io][sector-1]->
GetName());
508 mShaperResponses[io][sector-1]->GetXaxis()->SetTitle(
"time (buckets)");
509 mShaperResponses[io][sector-1]->GetYaxis()->SetTitle(
"signal");
510 assert(! mAltro[io][sector-1]);
511 }
else if (St_tpcAltroParamsC::instance()->N(l) >= 0) {
512 mShaperResponses[io][sector-1] =
new TF1F(Form(
"ShaperFunc_%s_S%02i",Names[io],sector),
513 StTpcRSMaker::shapeEI_I,timeBinMin,timeBinMax,7);
514 mShaperResponses[io][sector-1]->SetParameters(params0);
515 mShaperResponses[io][sector-1]->SetParNames(
"t0",
"tauI",
"width",
"tauC",
"io",
"norm");
516 mShaperResponses[io][sector-1]->SetTitle(mShaperResponses[io][sector-1]->
GetName());
517 mShaperResponses[io][sector-1]->GetXaxis()->SetTitle(
"time (buckets)");
518 mShaperResponses[io][sector-1]->GetYaxis()->SetTitle(
"signal");
520 mAltro[io][sector-1] =
new Altro(__MaxNumberOfTimeBins__,mADCs);
521 if (St_tpcAltroParamsC::instance()->N(l) == 0) {
522 mAltro[io][sector-1] =
new Altro(__MaxNumberOfTimeBins__,mADCs);
530 St_tpcAltroParamsC::instance()->K2(l),
531 St_tpcAltroParamsC::instance()->K3(l),
532 St_tpcAltroParamsC::instance()->L1(l),
533 St_tpcAltroParamsC::instance()->L2(l),
534 St_tpcAltroParamsC::instance()->L3(l));
536 if (mAltro[io][sector-1]) {
538 St_tpcAltroParamsC::instance()->MinSamplesaboveThreshold(l),
544 Double_t t = timeBinMax;
545 Double_t ymax = mShaperResponses[io][sector-1]->Eval(0.5);
546 for (; t > 5; t -= 1) {
547 Double_t r = mShaperResponses[io][sector-1]->Eval(t)/ymax;
550 mShaperResponses[io][sector-1]->SetRange(timeBinMin,t);
551 mShaperResponses[io][sector-1]->Save(timeBinMin,t,0,0,0,0);
552 if (GetTFile()) mShaperResponses[io][sector-1]->Write();
555 if (Debug()) Print();
556 if (ClusterProfile && GetTFile()) GetTFile()->cd();
558 StMagUtilities::SetDoDistortionT(gFile);
559 StMagUtilities::SetUnDoDistortionT(gFile);
561 mHeed = fEc(St_TpcResponseSimulatorC::instance()->W());
562 if ( ClusterProfile) {
568 const Name_t InOut[6] = {
569 {
"Inner",
"Inner old electronics or iTPC"},
570 {
"Outer",
"Outer old electronics or ITPC"},
571 {
"InnerX",
"Inner new electronics"},
572 {
"OuterX",
"Outer new electronics"},
576 const Name_t PadTime[4] = {
577 {
"Pad",
"Pad - <PadMC> ; Z"},
578 {
"Time",
"Time - <TimeMC> ; Z"},
579 {
"PixelPad",
"Pad ; row ; pad"},
580 {
"PixelTime",
"Time ; row ; time "},
582 for (Int_t io = 2; io < 4; io++) {
583 for (Int_t pt = 0; pt < 2; pt++) {
584 TString Name(InOut[io].Name); Name += PadTime[pt].Name; Name +=
"Mc";
585 TString Title(InOut[io].Title); Title += PadTime[pt].Title; Title +=
" Mc";
586 hist[io][pt] = (TProfile2D *) gDirectory->Get(Name);
587 if (! hist[io][pt]) {
588 hist[io][pt] =
new TProfile2D(Name,Title,nx[pt],xmin[pt],xmax[pt],nz,zmin,zmax,
"");
589 hist[io][pt]->SetMarkerStyle(20);
590 hist[io][pt]->SetMarkerColor(color++);
594 GainHist[0] =
new TProfile2D(
"dEdxCorSecRow",
"dEdx correction ; sector ; row",
595 NoOfSectors,0.5,NoOfSectors+0.5,
596 St_tpcPadConfigC::instance()->numberOfRows(20),0.5,St_tpcPadConfigC::instance()->numberOfRows(20)+0.5,
"");
597 GainHist[1] =
new TProfile2D(
"GainSecRow",
"Overall gain ; sector ; row",
598 NoOfSectors,0.5,NoOfSectors+0.5,
599 St_tpcPadConfigC::instance()->numberOfRows(20),0.5,St_tpcPadConfigC::instance()->numberOfRows(20)+0.5,
"");
600 for (Int_t pt = 0; pt < 2; pt++) {
601 TString Name(PadTime[pt+2].Name);
602 TString Title(PadTime[pt+2].Title); Title +=
" Mc";
603 PixelHist[pt] =
new TProfile2D(Name,Title, 72, 0.5, 72.5, nx[pt+2],xmin[pt+2],xmax[pt+2],
"");
605 const Name_t Checks[22] = {
606 {
"dEGeant",
"dE in Geant"},
607 {
"dSGeant",
"ds in Geant"},
608 {
"Gain",
"Gas Gain after Voltage"},
609 {
"GainMc",
"Gas Gain after MC correction"},
610 {
"dEdxCor",
"correction of dEdx"},
612 {
"NPGEANT",
"no. of primary electros from GEANT"},
613 {
"NP",
"no. of primary electros"},
614 {
"Nt",
"total no. of electors per cluster"},
615 {
"Qav",
"Gas gain flactuations"},
616 {
"localYDirectionCoupling",
"localYDirectionCoupling"},
617 {
"n0",
"No. electrons per primary interaction"},
618 {
"padGain",
"padGain"},
619 {
"localXDirectionCoupling",
"localXDirectionCoupling"},
620 {
"XYcoupling",
"XYcoupling"},
624 {
"NE",
"Total no. of generated electors"},
625 {
"dECl",
"Total log(signal/Nt) in a cluster ; Wire Index"},
626 {
"nPdT",
"log(Total no. of conducting electrons) - log(no. of primary one) ; log(no. primary electrons)"},
627 {
"bgVsbg",
"log10(bg_from_gkin) ; log10(bg_from_mom"}
629 const Int_t Npbins = 151;
630 const Int_t NpbinsL = 10;
631 const Double_t Xmax = 1e5;
632 Double_t dX = TMath::Log(Xmax/10)/(Npbins - NpbinsL);
633 Double_t *pbins =
new Double_t[Npbins];
634 Double_t *pbinsL =
new Double_t[Npbins];
636 pbinsL[0] = TMath::Log(pbins[0]);
637 for (Int_t bin = 1; bin < Npbins; bin++) {
638 if (bin <= NpbinsL) {
639 pbins[bin] = pbins[bin-1] + 1;
640 }
else if (bin == Npbins - 1) {
643 Int_t nM = 0.5*(pbins[NpbinsL-2] + pbins[NpbinsL-1])*TMath::Exp(dX*(bin-NpbinsL));
644 Double_t dbin = TMath::Nint(nM - pbins[bin-1]);
645 if (dbin < 1.0) dbin = 1.0;
646 pbins[bin] = pbins[bin-1] + dbin;
648 pbinsL[bin] = TMath::Log(pbins[bin]);
650 for (Int_t io = 0; io < 2; io++) {
651 for (Int_t i = 0; i < nChecks; i++) {
652 TString Name(Checks[i].Name); Name += InOut[4+io].Name;
653 TString Title(Checks[i].Title); Title += InOut[4+io].Title;
654 if (i == 11) checkList[io][i] =
new TH2D(Name,Title,nz,zmin,zmax,100,-0.5,99.5);
655 else if (i == 19) checkList[io][i] =
new TH2D(Name,Title,173,-.5,172.5,200,-10,10);
657 else if (i == 20) checkList[io][i] =
new TH2D(Name,Title,Npbins-1,pbinsL,500,-2.0,8.0);
658 else if (i == 21) checkList[io][i] =
new TH2D(Name,Title,100,-5,5,100,-5,5);
659 else checkList[io][i] =
new TProfile(Name,Title,nz,zmin,zmax,
"");
669 static Int_t minSector = IAttr(
"minSector");
670 static Int_t maxSector = IAttr(
"maxSector");
671 static Int_t minRow = IAttr(
"minRow");
672 static Int_t maxRow = IAttr(
"maxRow");
675 static Int_t iBreak = 0;
679 gBenchmark->Start(
"TpcRS");
680 LOG_INFO <<
"\n -- Begin TpcRS Processing -- \n";
683 Double_t vminI = St_tpcGainCorrectionC::instance()->Struct(1)->min;
684 Double_t vminO = St_tpcGainCorrectionC::instance()->Struct(0)->min;
685 St_g2t_tpc_hit *
g2t_tpc_hit = (St_g2t_tpc_hit *) GetDataSet(
"geant/g2t_tpc_hit");
686 if (!g2t_tpc_hit)
return kStWarn;
687 Int_t no_tpc_hits = g2t_tpc_hit->GetNRows();
if (no_tpc_hits<1)
return kStOK;
688 if (Debug() > 1) g2t_tpc_hit->Print(0,10);
689 St_g2t_track *g2t_track = (St_g2t_track *) GetDataSet(
"geant/g2t_track");
690 Int_t NoTpcTracks = 0;
691 if (g2t_track) NoTpcTracks = g2t_track->GetNRows();
692 mNoTpcHitsAll = TArrayI(NoTpcTracks+1);
693 mNoTpcHitsReal = TArrayI(NoTpcTracks+1);
694 g2t_track_st *tpc_track = 0;
695 if (g2t_track) tpc_track = g2t_track->GetTable();
696 St_g2t_vertex *g2t_ver = (St_g2t_vertex *) GetDataSet(
"geant/g2t_vertex");
697 g2t_vertex_st *gver = 0;
700 Double_t mTimeBinWidth = 1./StTpcDb::instance()->Electronics()->samplingFrequency();
701 Double_t driftVelocity = StTpcDb::instance()->DriftVelocity(1);
703 gver = g2t_ver->GetTable();
704 NV = g2t_ver->GetNRows();
706 if (pEvent && StTpcBXT0CorrEPDC::instance()->nrows() && pEvent->epdCollection() ) {
711 StSPtrVecEpdHit &epdHits = epdCol->epdHits();
712 int nEpdHits = epdHits.size();
714 for(
int i = 0; i < nEpdHits; i++) {
717 if (epdHit->
tile() > 9)
continue;
720 if (epdHit->
adc() < 100)
continue;
722 if (TAC > maxTAC) maxTAC = TAC;
725 fgTriggerT0 = - StTpcBXT0CorrEPDC::instance()->getCorrection(maxTAC, driftVelocity, mTimeBinWidth)*mTimeBinWidth*1e-6;
726 }
else if (pEvent && IAttr(
"EbyET0")) {
728 fgTriggerT0 = - StEbyET0::Instance()->getT0(pEvent)*1e-6;
730 }
else if (g2t_ver->GetNRows() > 0) {
731 Double_t beta = St_beamInfoC::instance()->BetaYellow();
732 fgTriggerT0 = gver->ge_x[2]/(beta*TMath::Ccgs());
736 g2t_tpc_hit_st *tpc_hit_begin = g2t_tpc_hit->GetTable();
737 g2t_tpc_hit_st *tpc_hit = tpc_hit_begin;
738 if (m_TpcdEdxCorrection) {
739 St_tpcGainCorrectionC::instance()->Struct(0)->min = -500;
740 St_tpcGainCorrectionC::instance()->Struct(1)->min = -500;
742 LOG_INFO <<
"Reset min for gain Correction to I/O\t"
743 << St_tpcGainCorrectionC::instance()->Struct(1)->min
745 << St_tpcGainCorrectionC::instance()->Struct(0)->min
752 Int_t sortedIndex = 0;
753 tpc_hit = tpc_hit_begin;
754 for (Int_t sector = minSector; sector <= maxSector; sector++) {
755 Int_t NoHitsInTheSector = 0;
756 free(m_SignalSum); m_SignalSum = 0;
757 ResetSignalSum(sector);
759 for (; sortedIndex < no_tpc_hits; sortedIndex++) {
760 Int_t indx = sorter.
GetIndex(sortedIndex);
762 tpc_hit = tpc_hit_begin + indx;
763 Int_t volId = tpc_hit->volume_id%10000;
764 Int_t iSector = volId/100;
765 Int_t row = volId%100;
766 if (row < minRow || row > maxRow)
continue;
767 if (iSector != sector) {
768 if (! ( iSector > sector ) ) {
769 LOG_ERROR <<
"StTpcRSMaker::Make: g2t_tpc_hit table has not been ordered by sector no. " << sector <<
" and iSector = " << iSector <<
". Skip the hit." << endm;
770 g2t_tpc_hit->Print(indx,1);
776 if (tpc_hit->volume_id <= 0 || tpc_hit->volume_id > 1000000)
continue;
777 Int_t Id = tpc_hit->track_p;
778 if (Id <= 0 || Id > NoTpcTracks) {
779 LOG_ERROR <<
"StTpcRSMaker::Make: g2t_tpc_hit table does not matched with g2t_track: track Id = " << Id <<
" and NoTpcTracks = " << NoTpcTracks <<
" skip the hit" << endm;
780 g2t_tpc_hit->Print(indx,1);
783 Int_t id3 = 0, ipart = 8, charge = 1;
786 id3 = tpc_track[Id-1].start_vertex_p;
788 if (id3 <= 0 || id3 > NV) {
789 LOG_ERROR <<
"StTpcRSMaker::Make: g2t_tpc_hit table does not matched with g2t_vertex: id3 = " << id3 <<
" and NV = " << NV <<
" skip the hit" << endm;
790 g2t_tpc_hit->Print(indx,1);
791 if (Id > 0) g2t_track->Print(Id-1,1);
794 ipart = tpc_track[Id-1].ge_pid;
795 charge = (Int_t) tpc_track[Id-1].charge;
798 if (ipart == Laserino || ipart == Chasrino) {
810 enum {NoMaxTrackSegmentHits = 100};
811 static HitPoint_t TrackSegmentHits[NoMaxTrackSegmentHits];
815 Int_t sIndex = sortedIndex;
816 if (Debug() > 13) cout <<
"sortedIndex = " << sortedIndex <<
"\tno_tpc_hits = " << no_tpc_hits << endl;
819 Double_t zOld = -999;
820 Int_t TrackDirection = 0;
821 for (nSegHits = 0, sIndex = sortedIndex;
822 sIndex < no_tpc_hits && nSegHits < NoMaxTrackSegmentHits; sIndex++) {
824 g2t_tpc_hit_st *tpc_hitC = tpc_hit_begin + indx;
825 if ((tpc_hitC->volume_id%10000)/100 != sector)
break;
826 if (ID > 0 && ID != tpc_hitC->track_p)
break;
828 Double_t pNew = TMath::Sqrt(tpc_hitC->p[0]*tpc_hitC->p[0] + tpc_hitC->p[1]*tpc_hitC->p[1] + tpc_hitC->p[2]*tpc_hitC->p[2]);
829 Double_t zNew = tpc_hitC->x[2];
831 Double_t rNewOld = pNew/pOld;
832 if (rNewOld < 0.1 || rNewOld > 10)
break;
833 if (zOld > -999 && TMath::Abs(zNew - zOld) > 10)
break;
837 ID = tpc_hitC->track_p;
840 if (TrackSegmentHits[nSegHits-1].tpc_hitC->volume_id%100 <= tpc_hitC->volume_id%100) {
845 }
else if (nSegHits > 1) {
846 if ((! TrackDirection && TrackSegmentHits[nSegHits-1].tpc_hitC->volume_id%100 > tpc_hitC->volume_id%100) ||
847 ( TrackDirection && TrackSegmentHits[nSegHits-1].tpc_hitC->volume_id%100 < tpc_hitC->volume_id%100))
850 if (Debug() > 13) cout <<
"sIndex = " << sIndex <<
"\tindx = " << indx <<
"\ttpc_hitC = " << tpc_hitC << endl;
851 TrackSegmentHits[nSegHits].indx = indx;
852 TrackSegmentHits[nSegHits].s = tpc_hitC->length;
853 if (tpc_hitC->length == 0 && nSegHits > 0) {
854 TrackSegmentHits[nSegHits].s = TrackSegmentHits[nSegHits-1].s + tpc_hitC->ds;
856 TrackSegment2Propagate(tpc_hitC, &gver[id3-1],TrackSegmentHits[nSegHits]);
857 if (TrackSegmentHits[nSegHits].
Pad.timeBucket() < 0 || TrackSegmentHits[nSegHits].Pad.timeBucket() > NoOfTimeBins)
continue;
860 if (! nSegHits)
continue;
863 for (Int_t s = 0; s < nSegHits; s++) {
864 cout <<
"Seg[" << Form(
"%2i",s) <<
"]\tId " << TrackSegmentHits[s].TrackId <<
"\ts = " << TrackSegmentHits[s].s
865 <<
"\tvolumeID :" << Form(
"%6i",TrackSegmentHits[s].tpc_hitC->volume_id) <<
"\t" << TrackSegmentHits[s].Pad
866 <<
"\ts1/s2 = " << TrackSegmentHits[s].tpc_hitC->length - TrackSegmentHits[s].tpc_hitC->ds/2
867 <<
"\t" << TrackSegmentHits[s].tpc_hitC->length + TrackSegmentHits[s].tpc_hitC->ds/2 <<
"\tds = " << TrackSegmentHits[s].tpc_hitC->ds
871 sortedIndex = sIndex-1;
873 memset (rowsdE, 0,
sizeof(rowsdE));
874 Double_t zIntDr = - TMath::Log(gRandom->Rndm());
875 for (Int_t iSegHits = 0; iSegHits < nSegHits && s < msMax; iSegHits++) {
876 memset (rowsdEH, 0,
sizeof(rowsdEH));
877 g2t_tpc_hit_st *tpc_hitC = TrackSegmentHits[iSegHits].tpc_hitC;
878 Double_t dStep = TMath::Abs(tpc_hitC->ds);
884 memset (tpc_hitC->adcs, 0,
sizeof(tpc_hitC->adcs));
885 volId = tpc_hitC->volume_id%100000;
887 Int_t row = TrackSegmentHits[iSegHits].coorLS.fromRow();
888 Int_t io = (row <= St_tpcPadConfigC::instance()->numberOfInnerRows(sector)) ? 0 : 1;
892 if (sector > 12) iowe += 4;
894 Float_t *AdditionalMcCorrection = St_TpcResponseSimulatorC::instance()->SecRowCor();
895 Float_t *AddSigmaMcCorrection = St_TpcResponseSimulatorC::instance()->SecRowSig();
897 Double_t sigmaJitterT = St_TpcResponseSimulatorC::instance()->SigmaJitterTI();
898 Double_t sigmaJitterX = St_TpcResponseSimulatorC::instance()->SigmaJitterXI();
900 sigmaJitterT = St_TpcResponseSimulatorC::instance()->SigmaJitterTO();
901 sigmaJitterX = St_TpcResponseSimulatorC::instance()->SigmaJitterXO();
904 Double_t
Gain = St_tss_tssparC::instance()->gain(sector,row);
905 if (ClusterProfile) {
906 checkList[io][2]->Fill(TrackSegmentHits[iSegHits].xyzG.position().z(),Gain);
908 Double_t GainXCorrectionL = AdditionalMcCorrection[iowe] + row*AdditionalMcCorrection[iowe+1];
909 Gain *= TMath::Exp(-GainXCorrectionL);
910 Double_t GainXSigma = AddSigmaMcCorrection[iowe] + row*AddSigmaMcCorrection[iowe+1];
911 if (GainXSigma > 0) Gain *= TMath::Exp(gRandom->Gaus(0.,GainXSigma));
912 if (ClusterProfile) {
913 checkList[io][3]->Fill(TrackSegmentHits[iSegHits].xyzG.position().z(),Gain);
916 Double_t dEdxCor = 1.0;
917 if (TrackSegmentHits[iSegHits].coorLS.position().z() < -0.6) {
920 dEdxCor = dEdxCorrection(TrackSegmentHits[iSegHits]);
923 if (TMath::IsNaN(dEdxCor)) {
927 if (dEdxCor < minSignal)
continue;
928 if (ClusterProfile) {
929 checkList[io][4]->Fill(TrackSegmentHits[iSegHits].xyzG.position().z(),dEdxCor);
930 GainHist[0]->Fill(TrackSegmentHits[iSegHits].
Pad.sector(),TrackSegmentHits[iSegHits].Pad.row(),dEdxCor);
933 Float_t BField[3] = {(Float_t ) TrackSegmentHits[iSegHits].BLS.position().x(),
934 (Float_t ) TrackSegmentHits[iSegHits].BLS.position().y(),
935 (Float_t ) TrackSegmentHits[iSegHits].BLS.position().z()};
937 TrackSegmentHits[iSegHits].coorLS.position(),
938 BField[2]*kilogauss,charge);
939 StThreeVectorD unit = TrackSegmentHits[iSegHits].dirLS.position().unit();
940 Double_t *cxyz = unit.xyz();
942 cxyz[2], - cxyz[0]*cxyz[2] , cxyz[0],
943 cxyz[0], - cxyz[1]*cxyz[2] , cxyz[1],
944 0.0 , cxyz[0]*cxyz[0] + cxyz[1]*cxyz[1], cxyz[2]);
950 StThreeVectorD rowPlane(0,transform.yFromRow(TrackSegmentHits[iSegHits].Pad.sector(),TrackSegmentHits[iSegHits].Pad.row()),0);
951 Double_t sR =
track.pathLength(rowPlane,normal);
954 PrPP(
Make,TrackSegmentHits[iSegHits].coorLS);
956 TrackSegmentHits[iSegHits].coorLS.setPosition(xyzP); PrPP(
Make,TrackSegmentHits[iSegHits].coorLS);
958 PrPP(
Make,TrackSegmentHits[iSegHits].
Pad);
959 transform(TrackSegmentHits[iSegHits].coorLS,TrackSegmentHits[iSegHits].Pad,kFALSE,kFALSE);
960 PrPP(
Make,TrackSegmentHits[iSegHits].Pad);
963 if (St_tpcAltroParamsC::instance()->N(sector-1) >= 0) ioH += 2;
965 Double_t lgam = tpc_hitC->lgam;
966 if (ClusterProfile) {
967 checkList[io][5]->Fill(TrackSegmentHits[iSegHits].xyzG.position().z(),lgam);
969 Double_t gamma = TMath::Power(10.,lgam) + 1;
970 Double_t betaGamma = TMath::Sqrt(gamma*gamma - 1.);
971 StThreeVectorD pxyzG(tpc_hitC->p[0],tpc_hitC->p[1],tpc_hitC->p[2]);
973 static const Double_t m_e = .51099907e-3;
974 if (mass > 0) bg = pxyzG.mag()/mass;
975 if (ClusterProfile && bg > 0) {
976 checkList[io][21]->Fill(TMath::Log10(betaGamma),TMath::Log10(bg));
978 if (bg > betaGamma) betaGamma = bg;
979 Double_t bg2 = betaGamma*betaGamma;
980 gamma = TMath::Sqrt(bg2 + 1.);
983 if (charge > 0) Tmax = m_e*(gamma - 1);
984 else Tmax = 0.5*m_e*(gamma - 1);
986 Double_t r = m_e/mass;
987 Tmax = 2*m_e*bg2/(1 + 2*gamma*r + r*r);
989 if (Tmax > mCutEle) Tmax = mCutEle;
990 Double_t padH = TrackSegmentHits[iSegHits].Pad.pad();
991 Double_t tbkH = TrackSegmentHits[iSegHits].Pad.timeBucket();
992 tpc_hitC->pad = padH;
993 tpc_hitC->timebucket = tbkH;
994 pad0 = TMath::Max(1,TMath::Nint(padH + xmin[0]));
995 tbk0 = TMath::Max(0,TMath::Nint(tbkH + xmin[1]));
996 Double_t OmegaTau = St_TpcResponseSimulatorC::instance()->OmegaTau()*
997 TrackSegmentHits[iSegHits].BLS.position().z()/5.0;
998 Double_t NP = TMath::Abs(tpc_hitC->de)/(St_TpcResponseSimulatorC::instance()->W()*eV*
999 St_TpcResponseSimulatorC::instance()->Cluster());
1000 if (ClusterProfile) {
1001 checkList[io][6]->Fill(TrackSegmentHits[iSegHits].xyzG.position().z(),NP);
1003 Double_t driftLength = TMath::Abs(TrackSegmentHits[iSegHits].coorLS.position().z());
1004 Double_t D = 1. + OmegaTau*OmegaTau;
1005 Double_t SigmaT = St_TpcResponseSimulatorC::instance()->transverseDiffusion()* TMath::Sqrt( driftLength/D);
1006 Double_t SigmaL = St_TpcResponseSimulatorC::instance()->longitudinalDiffusion()*TMath::Sqrt( driftLength );
1007 if (St_tpcPadConfigC::instance()->IsRowInner(sector,row)) {
1008 if ( St_TpcResponseSimulatorC::instance()->transverseDiffusionI() > 0.0)
1009 SigmaT = St_TpcResponseSimulatorC::instance()->transverseDiffusionI()* TMath::Sqrt( driftLength/D);
1010 if (St_TpcResponseSimulatorC::instance()->longitudinalDiffusionI() > 0.0)
1011 SigmaL = St_TpcResponseSimulatorC::instance()->longitudinalDiffusionI()*TMath::Sqrt( driftLength );
1014 if (sigmaJitterX > 0) {SigmaT = TMath::Sqrt(SigmaT*SigmaT + sigmaJitterX*sigmaJitterX);}
1015 Double_t NoElPerAdc = St_TpcResponseSimulatorC::instance()->NoElPerAdc();
1016 if (NoElPerAdc <= 0) {
1017 if (St_tpcPadConfigC::instance()->iTPC(sector) && St_tpcPadConfigC::instance()->IsRowInner(sector,row)) {
1018 NoElPerAdc = St_TpcResponseSimulatorC::instance()->NoElPerAdcX();
1019 }
else if (St_tpcPadConfigC::instance()->IsRowInner(sector,row)) {
1020 NoElPerAdc = St_TpcResponseSimulatorC::instance()->NoElPerAdcI();
1022 NoElPerAdc = St_TpcResponseSimulatorC::instance()->NoElPerAdcO();
1025 #ifndef __NO_1STROWCORRECTION__
1026 if (row == 1) dEdxCor *= TMath::Exp(St_TpcResponseSimulatorC::instance()->FirstRowC());
1028 mGainLocal = Gain/dEdxCor/NoElPerAdc;
1031 NP = StdEdxModel::instance()->dNdx(betaGamma,charge);
1032 if (ClusterProfile) {
1033 checkList[io][7]->Fill(TrackSegmentHits[iSegHits].xyzG.position().z(),NP);
1035 memset (padsdE, 0,
sizeof(padsdE));
1036 memset (tbksdE, 0,
sizeof(tbksdE));
1038 tpc_hitC->dNdx = NP;
1042 NP = tpc_hitC->dNdx;
1045 dE = StdEdxModel::instance()->dNdE();
1049 dS = dE*eV/(TMath::Abs(mLaserScale*tpc_hitC->de/tpc_hitC->ds));
1052 Double_t step = dStep - tpc_hitC->dSSum;
1055 tpc_hitC->dSSum += step;
1058 LOG_INFO <<
"dESum = " << tpc_hitC->dESum <<
" /\tdSSum " << tpc_hitC->dSSum <<
" /\tds " << tpc_hitC->ds << endm;
1063 tpc_hitC->dSSum += dS;
1064 zIntDr = - TMath::Log(gRandom->Rndm());
1066 if (dE < St_TpcResponseSimulatorC::instance()->W()/2 || E > Tmax)
continue;
1067 tpc_hitC->dESum += E;
1071 LOG_INFO <<
"dESum = " << tpc_hitC->dESum <<
" /\tdSSum " << tpc_hitC->dSSum <<
" /\tds " << tpc_hitC->ds << endm;
1074 Double_t xRange = 0;
1075 if (dE > ElectronRangeEnergy) xRange = ElectronRange*TMath::Power((dE+dEr)/ElectronRangeEnergy,ElectronRangePower);
1077 Float_t dET = dE + dEr;
1081 if (xRange > 0) {Nr = rs.GetSize();}
1082 while ((EC = mHeed->GetRandom()) < dEr) {
1085 if (Nr <= Nt) {Nr = 2*Nt+1; rs.Set(Nr); }
1086 rs[Nt] = 1 - dEr/dET;
1091 if (ClusterProfile) {
1092 checkList[io][8]->Fill(TrackSegmentHits[iSegHits].xyzG.position().z(),Nt);
1093 checkList[io][11]->Fill(TrackSegmentHits[iSegHits].xyzG.position().z(),Nt);
1096 Double_t phiXY = 2*TMath::Pi()*gRandom->Rndm();
1097 Double_t rX = TMath::Cos(phiXY);
1098 Double_t rY = TMath::Sin(phiXY);
1099 Double_t sigmaT = SigmaT;
1100 Double_t sigmaL = SigmaL;
1101 TotalSignalInCluster = 0;
1102 Int_t WireIndex = 0;
1103 for (Int_t ie = 0; ie < Nt; ie++) {
1105 gRandom->Rannor(rX,rY);
1108 xyzC.z()+gRandom->Gaus(0,sigmaL), sector, row);
1110 Double_t xR = rs[ie]*xRange;
1111 TRVector xyzRangeL(3, xR*rX, xR*rY, 0.);
1112 TRVector xyzR(L2L,TRArray::kAxB,xyzRangeL);
1115 LOG_INFO <<
"xyzRangeL: " << xyzRangeL << endm;
1116 LOG_INFO <<
"L2L: " << L2L << endm;
1117 LOG_INFO <<
"xyzR: " << xyzR << endm;
1120 TCL::vadd(xyzE.position().xyz(),xyzR.GetArray(),xyzE.position().xyz(),3);
1123 Double_t zGG = xyzE.position().z();
1124 Double_t GGTransperency = 1.0;
1126 Double_t driftTime = 1e6*zGG/driftVelocity;
1127 driftTime -= St_starTriggerDelayC::instance()->TrigT0GG(io);
1128 Double_t lGGTransperency = St_GatingGridBC::instance()->CalcCorrection(0,driftTime);
1129 if (lGGTransperency < -9)
continue;
1130 GGTransperency = TMath::Exp(lGGTransperency);
1131 if (GGTransperency < minSignal)
continue;
1134 QAv = GGTransperency*mPolya[io]->GetRandom();
1135 Double_t y = xyzE.position().y();
1136 Double_t alphaVariation = InnerAlphaVariation[sector-1];
1138 if (y <= lastInnerSectorAnodeWire) {
1139 WireIndex = TMath::Nint((y - firstInnerSectorAnodeWire)/anodeWirePitch) + 1;
1140 #ifndef __NO_1STROWCORRECTION__
1141 if (St_tpcPadConfigC::instance()->iTPC(sector)) {
1142 if (WireIndex <= 3 || WireIndex >= numberOfInnerSectorAnodeWires - 3)
continue;
1144 if (WireIndex <= 1 || WireIndex >= numberOfInnerSectorAnodeWires)
continue;
1147 if (WireIndex <= 1 || WireIndex >= numberOfInnerSectorAnodeWires)
continue;
1149 yOnWire = firstInnerSectorAnodeWire + (WireIndex-1)*anodeWirePitch;
1151 WireIndex = TMath::Nint((y - firstOuterSectorAnodeWire)/anodeWirePitch) + 1;
1152 if (WireIndex <= 1 || WireIndex >= numberOfOuterSectorAnodeWires)
continue;
1153 yOnWire = firstOuterSectorAnodeWire + (WireIndex-1)*anodeWirePitch;
1154 alphaVariation = OuterAlphaVariation[sector-1];
1156 Double_t distanceToWire = y - yOnWire;
1157 xOnWire = xyzE.position().x();
1158 zOnWire = xyzE.position().z();
1160 Int_t iGridWire = (Int_t ) TMath::Abs(10.*distanceToWire);
1161 Double_t dist2Grid = TMath::Sign(0.05 + 0.1*iGridWire, distanceToWire);
1163 Int_t iGroundWire = (Int_t ) TMath::Abs(10.*dist2Grid);
1164 Double_t distFocused = TMath::Sign(0.05 + 0.1*iGroundWire, dist2Grid);
1166 Double_t tanLorentz = 0;
1167 if (y < firstOuterSectorAnodeWire) {
1168 if (St_TpcResponseSimulatorC::instance()->OmegaTauScaleI() > 0) tanLorentz = OmegaTau/St_TpcResponseSimulatorC::instance()->OmegaTauScaleI();
1170 if (St_TpcResponseSimulatorC::instance()->OmegaTauScaleO() > 0) tanLorentz = OmegaTau/St_TpcResponseSimulatorC::instance()->OmegaTauScaleO();
1172 xOnWire += distFocused*tanLorentz;
1173 zOnWire += TMath::Abs(distFocused);
1174 if (! iGroundWire ) QAv *= TMath::Exp( alphaVariation);
1175 else QAv *= TMath::Exp(-alphaVariation);
1176 if (ClusterProfile) {
1177 checkList[io][9]->Fill(TrackSegmentHits[iSegHits].xyzG.position().z(),QAv);
1179 Double_t dY = mChargeFraction[io][sector-1]->GetXmax();
1180 Double_t yLmin = yOnWire - dY;
1181 Double_t yLmax = yLmin + 2*dY;
1182 Int_t rowMin = transform.rowFromLocalY(yLmin,sector);
1183 Int_t rowMax = transform.rowFromLocalY(yLmax,sector);
1184 Double_t yRmin = transform.yFromRow(sector,rowMin) - St_tpcPadConfigC::instance()->PadLengthAtRow(sector,rowMin)/2;
1185 Double_t yRmax = transform.yFromRow(sector,rowMax) + St_tpcPadConfigC::instance()->PadLengthAtRow(sector,rowMax)/2;
1186 if (yRmin > yLmax || yRmax < yLmin) {
1189 GenerateSignal(TrackSegmentHits[iSegHits],sector,rowMin, rowMax, sigmaJitterT, sigmaJitterX);
1191 if (ClusterProfile) {
1192 if (TotalSignalInCluster > 0 && checkList[io][19]) {
1193 checkList[io][19]->Fill(WireIndex,TMath::Log(TotalSignalInCluster));
1197 TotalSignal += TotalSignalInCluster;
1200 if (tpc_hitC->dESum > 0 && tpc_hitC->dSSum > 0) {
1203 LOG_INFO <<
"sIndex = " << sIndex <<
" volId = " << volId
1204 <<
" tpc_hitC->de/eV = " << tpc_hitC->de/eV <<
" /\tdSSum " << tpc_hitC->dSSum <<
" /\t TotalSignal " << TotalSignal << endm;
1207 if (row > 1) tpc_hitC->adcs[0] += rowsdEH[row-2];
1208 tpc_hitC->adcs[1] += rowsdEH[row-1];
1209 if (row <= kRowMax) tpc_hitC->adcs[2] += rowsdEH[row];
1210 if (ClusterProfile) {
1211 if (TotalSignal > 0) {
1213 for (Int_t p = 0; p < kPadMax; p++) {
1214 hist[ioH][0]->Fill((p+pad0)-padH,TrackSegmentHits[iSegHits].xyzG.position().z(),padsdE[p]/TotalSignal);
1215 PixelHist[0]->Fill(row, p+pad0,padsdE[p]/TotalSignal);
1219 for (Int_t t = 0; t < kTimeBacketMax; t++) {
1220 hist[ioH][1]->Fill((t+tbk0+0.5)-tbkH,TrackSegmentHits[iSegHits].xyzG.position().z(),tbksdE[t]/TotalSignal);
1221 PixelHist[1]->Fill(row, (t+tbk0+0.5),tbksdE[t]/TotalSignal);
1225 checkList[io][15]->Fill(TrackSegmentHits[iSegHits].xyzG.position().z(),tpc_hitC->de);
1226 checkList[io][16]->Fill(TrackSegmentHits[iSegHits].xyzG.position().z(),tpc_hitC->ds);
1227 checkList[io][18]->Fill(TrackSegmentHits[iSegHits].xyzG.position().z(),tpc_hitC->ne);
1228 if (tpc_hitC->np > 0 && tpc_hitC->ne > 0)
1229 checkList[io][20]->Fill(TMath::Log(tpc_hitC->np),TMath::Log(tpc_hitC->ne) - TMath::Log(tpc_hitC->np));
1232 NoHitsInTheSector++;
1234 for (Int_t iSegHits = 0; iSegHits < nSegHits; iSegHits++) {
1235 g2t_tpc_hit_st *tpc_hitC = TrackSegmentHits[iSegHits].tpc_hitC;
1236 if (tpc_hitC->volume_id > 10000)
continue;
1237 Int_t row = tpc_hitC->volume_id%100;
1239 tpc_hitC->adc += rowsdE[row-1];
1240 Int_t io = (row <= St_tpcPadConfigC::instance()->numberOfInnerRows(sector)) ? 0 : 1;
1241 if (checkList[io][17])
1242 checkList[io][17]->Fill(TrackSegmentHits[iSegHits].xyzG.position().z(),tpc_hitC->adc);
1245 if (NoHitsInTheSector) {
1247 if (Debug()) LOG_INFO <<
"StTpcRSMaker: Done with sector\t" << sector <<
" total no. of hit = " << NoHitsInTheSector << endm;
1248 if (Debug() > 2) digitalSector->Print();
1251 if (m_SignalSum) {free(m_SignalSum); m_SignalSum = 0;}
1252 if (Debug()%10) gBenchmark->Show(
"TpcRS");
1253 if (m_TpcdEdxCorrection) {
1254 St_tpcGainCorrectionC::instance()->Struct(1)->min = vminI;
1255 St_tpcGainCorrectionC::instance()->Struct(0)->min = vminO;
1257 LOG_INFO <<
"Reset min for gain Correction to I/O\t"
1258 << St_tpcGainCorrectionC::instance()->Struct(1)->min
1260 << St_tpcGainCorrectionC::instance()->Struct(0)->min
1266 tpc_track = g2t_track->GetTable();
1267 for (Int_t i = 0; i < NoTpcTracks; i++, tpc_track++) {
1268 Int_t Id = tpc_track->id;
1269 tpc_track->n_tpc_hit = (mNoTpcHitsReal[Id-1] << 8) + (0xff & mNoTpcHitsAll[Id-1]);
1275 Double_t StTpcRSMaker::ShaperFunc(Double_t *x, Double_t *par) {
1276 Double_t tau = par[0];
1277 Double_t width = par[1];
1278 Double_t p = par[2];
1279 Double_t t = x[0]*width/tau;
1280 Double_t Delta = width/tau;
1281 Double_t t1 = t - Delta/2.;
1282 Double_t t2 = t1 + Delta;
1283 Double_t val = TMath::Gamma(p,t2) - TMath::Gamma(p,t1);
1287 Double_t StTpcRSMaker::PadResponseFunc(Double_t *x, Double_t *par) {
1288 Double_t CrossTalk = 0;
1290 Double_t X = par[5]*x[0];
1291 if (CrossTalk > 0) {
1292 for (Int_t i = -1; i <= 1; i++) {
1293 Double_t xx = X + par[5]*i;
1294 if (i == 0) Value += (1. - 2.*CrossTalk)*Gatti(&xx,par);
1295 else Value += CrossTalk *Gatti(&xx,par);
1297 }
else Value = Gatti(&X,par);
1301 Double_t StTpcRSMaker::Gatti(Double_t *x, Double_t *par) {
1320 Double_t w = par[0];
1321 Double_t h = par[1];
1322 Double_t K3 = par[3];
1323 Double_t lambda = y/h;
1324 Double_t K2 = TMath::PiOver2()*(1. - 0.5*TMath::Sqrt(K3));
1326 Double_t sqK3 = TMath::Sqrt(K3);
1327 Double_t ATsqK3 = 0.5/TMath::ATan(sqK3);
1328 Double_t Y1 = lambda - w/h/2;
1329 Double_t Y2 = Y1 + w/h;
1330 Double_t X1 = K2*Y1;
1331 Double_t X2 = K2*Y2;
1332 Double_t Z1 = sqK3*TMath::TanH(X1);
1333 Double_t Z2 = sqK3*TMath::TanH(X2);
1334 Double_t val = ATsqK3*(TMath::ATan(Z2) - TMath::ATan(Z1));
1338 void StTpcRSMaker::Print(Option_t *)
const {
1339 PrPP(Print, NoOfSectors);
1340 PrPP(Print, St_tpcPadConfigC::instance()->numberOfRows(1));
1341 PrPP(Print, St_tpcPadConfigC::instance()->numberOfRows(20));
1342 PrPP(Print, St_tpcPadConfigC::instance()->numberOfInnerRows(20));
1343 PrPP(Print, NoOfPads);
1344 PrPP(Print, St_TpcResponseSimulatorC::instance()->W());
1345 PrPP(Print, St_TpcResponseSimulatorC::instance()->Cluster());
1346 PrPP(Print, St_TpcResponseSimulatorC::instance()->longitudinalDiffusion());
1347 PrPP(Print, St_TpcResponseSimulatorC::instance()->longitudinalDiffusionI());
1348 PrPP(Print, St_TpcResponseSimulatorC::instance()->transverseDiffusion());
1349 PrPP(Print, St_TpcResponseSimulatorC::instance()->transverseDiffusionI());
1351 PrPP(Print, NoOfTimeBins);
1352 PrPP(Print, numberOfInnerSectorAnodeWires);
1353 PrPP(Print, firstInnerSectorAnodeWire);
1354 PrPP(Print, lastInnerSectorAnodeWire);
1355 PrPP(Print, numberOfOuterSectorAnodeWires);
1356 PrPP(Print, firstOuterSectorAnodeWire);
1357 PrPP(Print, lastOuterSectorAnodeWire);
1358 PrPP(Print, anodeWirePitch);
1359 PrPP(Print,St_TpcResponseSimulatorC::instance()->OmegaTau());
1360 PrPP(Print, St_TpcResponseSimulatorC::instance()->NoElPerAdcI());
1361 PrPP(Print, St_TpcResponseSimulatorC::instance()->NoElPerAdcO());
1362 PrPP(Print, St_TpcResponseSimulatorC::instance()->NoElPerAdcX());
1363 PrPP(Print, anodeWireRadius);
1364 PrPP(Print, St_TpcResponseSimulatorC::instance()->AveragePedestal());
1365 PrPP(Print, St_TpcResponseSimulatorC::instance()->AveragePedestalRMS());
1366 PrPP(Print, St_TpcResponseSimulatorC::instance()->AveragePedestalRMSX());
1367 PrPP(Print, St_TpcResponseSimulatorC::instance()->FanoFactor());
1368 for (Int_t sector = 1; sector <= 24; sector++) {
1369 PrPP(Print, innerSectorAnodeVoltage[sector-1]);
1370 PrPP(Print, outerSectorAnodeVoltage[sector-1]);
1372 PrPP(Print, St_TpcResponseSimulatorC::instance()->K3IP());
1373 PrPP(Print, St_TpcResponseSimulatorC::instance()->K3IR());
1374 PrPP(Print, St_TpcResponseSimulatorC::instance()->K3OP());
1375 PrPP(Print, St_TpcResponseSimulatorC::instance()->K3OR());
1376 PrPP(Print, St_TpcResponseSimulatorC::instance()->SigmaJitterTI());
1377 PrPP(Print, St_TpcResponseSimulatorC::instance()->SigmaJitterTO());
1381 static Int_t iBreak = 0;
1382 static Int_t AdcCut = 500;
1384 TDataSet *
event = GetData(
"Event");
1397 Int_t row, pad, bin;
1398 Int_t Sector = TMath::Abs(sector);
1400 if (! digitalSector) {
1402 data->setSector(Sector,digitalSector);
1404 digitalSector->clear();
1405 for (row = 1; row <= St_tpcPadConfigC::instance()->numberOfRows(sector); row++) {
1406 Int_t noOfPadsAtRow = St_tpcPadConfigC::instance()->St_tpcPadConfigC::instance()->numberOfPadsAtRow(sector,row);
1407 Double_t pedRMS = St_TpcResponseSimulatorC::instance()->AveragePedestalRMS();
1409 if ( St_tpcPadConfigC::instance()->IsRowInner(sector,row) ) ioA = 0;
1410 if (St_tpcAltroParamsC::instance()->N(sector-1) > 0) {
1411 if (! (St_tpcPadConfigC::instance()->iTPC(sector) && St_tpcPadConfigC::instance()->IsRowInner(sector,row))) {
1412 pedRMS = St_TpcResponseSimulatorC::instance()->AveragePedestalRMSX();
1416 Float_t AdcSumBeforeAltro = 0, AdcSumAfterAltro = 0;
1418 for (pad = 1; pad <= noOfPadsAtRow; pad++) {
1419 gain = St_tpcPadGainT0BC::instance()->Gain(Sector,row,pad);
1420 if (gain <= 0.0)
continue;
1421 ped = St_TpcResponseSimulatorC::instance()->AveragePedestal();
1422 #ifdef __TFG__VERSION__
1423 static Int_t IDTs[__MaxNumberOfTimeBins__];
1425 static UShort_t IDTs[__MaxNumberOfTimeBins__];
1427 Double_t pedRMSpad = pedRMS;
1428 if (pedRMSpad < 0) {
1429 Double_t NPads = St_tpcPadConfigC::instance()->numberOfPadsAtRow(sector,row);
1430 Double_t x = pad/NPads - 0.5;
1431 pedRMSpad = St_TpcPadPedRMSC::instance()->CalcCorrection(1-ioA, x);
1432 ped = gRandom->Gaus(St_TpcPadPedRMSC::instance()->a(1-ioA)[3],St_TpcPadPedRMSC::instance()->a(1-ioA)[4]);
1434 memset(mADCs, 0,
sizeof(mADCs));
1435 memset(IDTs, 0,
sizeof(IDTs));
1437 index = NoOfTimeBins*((row-1)*NoOfPads+pad-1);
1438 for (bin = 0; bin < NoOfTimeBins; bin++,index++) {
1442 Double_t pRMS = pedRMSpad;
1444 if (bin >= 21 && bin <= 56) {
1445 pRMS = TMath::Sqrt(pedRMSpad*pedRMSpad + 4.76658e+01*TMath::Exp(-2.87987e-01*(bin-1.46222e+01)));
1449 adc = (Int_t) (SignalSum[index].Sum/gain + gRandom->Gaus(ped,pRMS));
1450 adc = adc - (Int_t) ped;
1452 else adc = (Int_t) (SignalSum[index].Sum/gain);
1453 if (adc > 1023) adc = 1023;
1454 if (adc < 1)
continue;
1455 SignalSum[index].Adc = adc;
1458 IDTs[bin] = SignalSum[index].TrackId;
1460 if (adc > 3*pRMS) AdcSumBeforeAltro += adc;
1461 if (Debug() > 11 && SignalSum[index].Sum > 0) {
1462 LOG_INFO <<
"digi R/P/T/I = " << row <<
" /\t" << pad <<
" /\t" << bin <<
" /\t" << index
1463 <<
"\tSum/Adc/TrackId = " << SignalSum[index].Sum <<
" /\t"
1464 << SignalSum[index].Adc <<
" /\t" << SignalSum[index].TrackId << endm;
1468 if (! NoTB)
continue;
1469 if (mAltro[ioA][sector-1]) {
1472 static Short_t ADCsSaved[__MaxNumberOfTimeBins__];
1473 memcpy(ADCsSaved, mADCs,
sizeof(ADCsSaved));
1477 ofstream *out =
new ofstream(
"digi.dump",ios_base::app);
1478 for (Int_t i = 0; i < __MaxNumberOfTimeBins__; i++) {
1479 if (ADCsSaved[i] > 0 || mADCs[i] > 0) {
1480 LOG_INFO << Form(
"s %2i r %i p %3i t %3i: %10i => %10i keep %10i",sector,row,pad,i,ADCsSaved[i],mADCs[i],mAltro[ioA][sector-1]->ADCkeep[i]) << endm;
1481 *out << Form(
"s %2i r %i p %3i t %3i: %10i => %10i keep %10i",sector,row,pad,i,ADCsSaved[i],mADCs[i],mAltro[ioA][sector-1]->ADCkeep[i]) << endl;
1488 for (Int_t i = 0; i < __MaxNumberOfTimeBins__; i++) {
1489 if (mADCs[i] && ! mAltro[ioA][sector-1]->ADCkeep[i]) {mADCs[i] = 0;}
1494 if (mADCs[i] > 3*pedRMSpad) AdcSumAfterAltro += mADCs[i];
1496 LOG_INFO <<
"Altro R/P/T/I = " << row <<
" /\t" << pad <<
" /\t" << i
1497 <<
"\tAdc/TrackId = " << mADCs[i] <<
" /\t" << IDTs[i] << endm;
1500 }
else {IDTs[i] = 0;}
1503 if (ADCsum > AdcCut) {
1509 if (St_tpcAltroParamsC::instance()->N(sector-1) < 0) NoTB = AsicThresholds();
1511 if (NoTB > 0 && digitalSector) {
1512 digitalSector->putTimeAdc(row,pad,mADCs,IDTs);
1517 LOG_INFO <<
"row = " << row <<
"\tAdcSumBeforeAltro = " << AdcSumBeforeAltro <<
"\tAdcSumAfterAltro = " << AdcSumAfterAltro << endm;
1521 return digitalSector;
1524 Int_t StTpcRSMaker::AsicThresholds() {
1529 for (UInt_t tb = 0; tb < __MaxNumberOfTimeBins__; tb++) {
1530 if (mADCs[tb] <= St_asic_thresholdsC::instance()->thresh_lo()) {
1531 if (! t1) mADCs[tb] = 0;
1533 if (nSeqLo <= St_asic_thresholdsC::instance()->n_seq_lo() ||
1534 nSeqHi <= St_asic_thresholdsC::instance()->n_seq_hi())
1535 for (UInt_t t = t1; t <= tb; t++) mADCs[t] = 0;
1536 else noTbleft += nSeqLo;
1538 t1 = nSeqLo = nSeqHi = 0;
1542 if (mADCs[tb] > St_asic_thresholdsC::instance()->thresh_hi()) {nSeqHi++;}
1547 Double_t StTpcRSMaker::InducedCharge(Double_t s, Double_t h, Double_t ra, Double_t Va, Double_t &t0) {
1550 LOG_INFO <<
"wire spacing = " << s <<
" cm"
1551 <<
"\tcathode anode gap = " << h <<
" cm"
1552 <<
"\tanode wire radius = " << ra <<
" cm"
1553 <<
"\tpotential on anode wire = " << Va <<
" V" << endm;
1554 const Double_t B = 30e-3;
1555 const Double_t E0 = 20e3;
1556 const Double_t mu = 2.26;
1558 Double_t alpha[2] = {-26., -70.};
1559 Double_t pi = TMath::Pi();
1561 Double_t rc = s/(2*pi)*TMath::Exp(pi*h/s); LOG_INFO <<
"rc(Cylinder approx) = " << rc <<
" cm" << endm;
1563 Double_t C = 1./(2*TMath::Log(rc/ra)); LOG_INFO <<
"C = " << C << endm;
1564 Double_t E = 2*pi*C*Va/s; LOG_INFO <<
"E = " << E <<
" V/cm" << endm;
1566 Double_t k = 2*B/3.*TMath::Power((pi/E0/s),2)*TMath::Power(C*Va,3); LOG_INFO <<
"k = " << k << endm;
1568 t0 = ra*ra/(4*mu*C*Va);
1569 LOG_INFO <<
"t0 = " << 1e9*t0 <<
" ns" << endm;
1570 Double_t Tav = t0*h/s/(2*pi*C); LOG_INFO <<
"Tav = " << 1e9*Tav <<
" ns" << endm;
1572 Double_t t = 180e-9; LOG_INFO <<
"t = " << 1e9*t <<
" ns" << endm;
1573 Double_t rp = TMath::Sqrt(1. + t/t0); LOG_INFO <<
"r' = " << rp << endm;
1575 Double_t Aconstant = rp*ra/(2*h); LOG_INFO <<
"Aconstant = " << Aconstant << endm;
1576 Double_t Bconstant = C/2*TMath::Log(1 + t/t0); LOG_INFO <<
"Bconstant = " << Bconstant << endm;
1578 for (Int_t i = 0; i < 2; i++) {
1579 Gains[i] = Aconstant*TMath::Sin(pi/180*alpha[i]) + Bconstant;
1580 LOG_INFO <<
"Gain = " << Gains[i] <<
" at alpha = " << alpha[i] <<
" degree" << endm;
1582 Double_t GainsAv = TMath::Sqrt(Gains[0]*Gains[1]);
1584 for (Int_t i = 0; i < 2; i++) {
1585 r = TMath::Log(Gains[i]/GainsAv); LOG_INFO <<
"Relative gain " << r <<
" at alpha = " << alpha[i] << endm;
1590 Int_t StTpcRSMaker::SearchT(
const void *elem1,
const void **elem2) {
1591 g2t_tpc_hit_st *value1 = (g2t_tpc_hit_st *) elem1;
1592 g2t_tpc_hit_st *value2 = (g2t_tpc_hit_st *) *elem2;
1594 if ((value1->volume_id%100000)/100 != (value2->volume_id%100000)/100)
1595 return (value1->volume_id%100000)/100 - (value2->volume_id%100000)/100;
1597 if (value1->track_p != value2->track_p)
return value1->track_p - value2->track_p;
1601 return (Int_t) 100*(value1->length - value2->length);
1604 Int_t StTpcRSMaker::CompareT(
const void **elem1,
const void **elem2) {
1605 return SearchT(*elem1, elem2);
1609 Double_t StTpcRSMaker::DriftLength(Double_t x, Double_t y) {
1610 static const Double_t
Step = 5e-2;
1611 Double_t r = TMath::Sqrt(x*x + y*y);
1612 if (r < 0.25)
return r;
1616 while (x > Step || y > Step) {
1617 Double_t Slope = TMath:SinH(TMath::Pi()*y/s)/TMath:Sin(TMath::Pi()*x/s);
1618 Double_t Co2 = 1./(1. + Slope*Slope);
1619 Double_t Si = TMath::Sqrt(1. - Co2);
1620 Double_t Co = TMath::Sqrt(Co2);
1621 x = TMath::Abs(x - Step*Co);
1622 y = TMath::Abs(y - Step*Si);
1629 TF1 *StTpcRSMaker::Fei() {
1630 TF1 *f = (TF1 *) gROOT->GetListOfFunctions()->FindObject(
"Fei");
1632 f =
new TF1(
"Fei", feiFunc, 0, 5e-6, 2);
1633 f->SetParNames(
"t0",
"T");
1634 f->SetParameters(1.11582e-09, 6e-08);
1639 Double_t StTpcRSMaker::fei(Double_t t, Double_t t0, Double_t T) {
1640 static const Double_t xmaxD = 100;
1641 if (t < t0)
return 0;
1642 Double_t t01 = xmaxD, t11 = xmaxD;
1647 if (t11 > xmaxD) t11 = xmaxD;
1648 if (t01 > xmaxD) t01 = xmaxD;
1649 if (t01 >= t11)
return 0;
1650 Double_t ex1 = ROOT::Math::expint(t11);
1651 Double_t ex0 = ROOT::Math::expint(t01);
1653 return TMath::Exp(-t11)*(ex1 - ex0);
1656 Double_t StTpcRSMaker::shapeEI(Double_t *x, Double_t *par) {
1662 Double_t tmax = par[6];
1663 if (tmax <= 0.0) tmax = 1.5e-6;
1665 if (t <= 0 || t > tmax)
return value;
1666 Double_t t0 = par[0];
1667 Double_t T1 = par[1];
1668 Double_t T2 = par[3];
1669 if (TMath::Abs((T1-T2)/(T1+T2)) < 1e-7) {
1670 return TMath::Max(0.,(t + t0)/T1*fei(t,t0,T1) + TMath::Exp(-t/T1) - 1);
1672 if (T2 <= 0)
return fei(t,t0,T1);
1673 if (T1 <= 0)
return 0;
1674 return T1/(T1 - T2)*(fei(t,t0,T1) - fei(t,t0,T2));
1677 Double_t StTpcRSMaker::shapeEI3(Double_t *x, Double_t *par) {
1680 if (t <= 0)
return value;
1681 Double_t t0 = par[0];
1682 Double_t tau_F = par[1];
1683 Double_t tau_P = par[2];
1684 Double_t tau_I = par[3];
1685 Double_t tau_C = par[5];
1686 Double_t d = 1./tau_P;
1687 Double_t a[3] = {- 1./tau_I, - 1./tau_F, 0};
1688 Double_t A[3] = {(a[0]+d)/(a[0]-a[1]), (a[1]+d)/(a[1]-a[0]), 0};
1693 A[0] = (a[0] + d)/a[0]/(a[0] - a[1])/(a[0] - a[2]);
1694 A[1] = (a[1] + d)/a[1]/(a[1] - a[0])/(a[1] - a[2]);
1695 A[2] = (a[2] + d)/a[2]/(a[2] - a[0])/(a[2] - a[1]);
1697 for (Int_t i = 0; i < N; i++) {
1698 value += A[i]*TMath::Exp(a[i]*(t+t0))*(ROOT::Math::expint(-a[i]*(t+t0))-ROOT::Math::expint(-a[i]*t0));
1703 Double_t StTpcRSMaker::shapeEI_I(Double_t *x, Double_t *par) {
1704 static Double_t sqrt2 = TMath::Sqrt(2.);
1705 Double_t TimeBinWidth = par[2];
1706 static Double_t norm = 1;
1707 static Double_t params0[5] = {0};
1708 Int_t io = (Int_t) par[4];
1709 assert(io >= 0 && io <= 1);
1710 Int_t ok = memcmp(par,params0,
sizeof(params0));
1712 fgTimeShape0[io]->SetParameters(par);
1713 norm = fgTimeShape0[io]->Integral(TimeBinWidth*timeBinMin,TimeBinWidth*timeBinMax);
1714 memcpy(params0, par,
sizeof(params0));
1716 Double_t t1 = TimeBinWidth*(x[0] - 0.5);
1717 Double_t t2 = t1 + TimeBinWidth;
1718 return sqrt2*fgTimeShape0[io]->Integral(t1,t2)/norm;
1721 Double_t StTpcRSMaker::shapeEI3_I(Double_t *x, Double_t *par) {
1722 static Double_t sqrt2 = TMath::Sqrt(2.);
1723 Double_t TimeBinWidth = par[4];
1724 static Double_t norm = 1;
1725 static Double_t params3[7] = {0};
1726 Int_t io = (Int_t) par[4];
1727 assert(io >= 0 && io <= 1);
1728 Int_t ok = memcmp(par,params3,
sizeof(params3));
1730 fgTimeShape0[io]->SetParameters(par);
1731 norm = fgTimeShape0[io]->Integral(TimeBinWidth*timeBinMin,TimeBinWidth*timeBinMax);
1732 memcpy(par, params3,
sizeof(params3));
1734 Double_t t1 = TimeBinWidth*(x[0] - 0.5);
1735 Double_t t2 = t1 + TimeBinWidth;
1736 return sqrt2*fgTimeShape3[io]->Integral(t1,t2)/norm;
1739 SignalSum_t *StTpcRSMaker::GetSignalSum(Int_t sector) {
1741 m_SignalSum = (
SignalSum_t *) malloc(St_tpcPadConfigC::instance()->numberOfRows(sector)*NoOfPads*NoOfTimeBins*
sizeof(
SignalSum_t));
1745 SignalSum_t *StTpcRSMaker::ResetSignalSum(Int_t sector) {
1746 GetSignalSum(sector);
1747 memset (m_SignalSum, 0, St_tpcPadConfigC::instance()->numberOfRows(sector)*NoOfPads*NoOfTimeBins*
sizeof(
SignalSum_t));
1751 Double_t StTpcRSMaker::polya(Double_t *x, Double_t *par) {
1752 return TMath::GammaDist(x[0],par[0],par[1],par[2]);
1755 Double_t StTpcRSMaker::Ec(Double_t *x, Double_t *p) {
1756 if (x[0] < p[0]/2 || x[0] > 3.064*p[0])
return 0;
1757 if (x[0] < p[0])
return 1;
1758 return TMath::Power(p[0]/x[0],4);
1761 TF1 *StTpcRSMaker::StTpcRSMaker::fEc(Double_t w) {
1762 TF1 *f =
new TF1(
"Ec",Ec,0,3.064*w,1);
1763 f->SetParameter(0,w);
1768 # define gcomad gcomad_
1770 # define gcomad GCOMAD
1775 void type_of_call gcomad(DEFCHARD, Int_t*& DEFCHARL);
1777 Float_t StTpcRSMaker::GetCutEle() {
1793 gcomad(PASSCHARD(
"GCBANK"),(
int*&) fGcbank PASSCHARL(
"GCBANK"));
1821 gcomad(PASSCHARD(
"GCLINK"),(
int*&) fGclink PASSCHARL(
"GCLINK"));
1841 gcomad(PASSCHARD(
"GCCUTS"),(
int*&) fGccuts PASSCHARL(
"GCCUTS"));
1859 gcomad(PASSCHARD(
"GCNUM"), (
int*&) fGcnum PASSCHARL(
"GCNUM"));
1862 gcomad(PASSCHARD(
"IQ"), addr PASSCHARL(
"IQ"));
1864 gcomad(PASSCHARD(
"LQ"), addr PASSCHARL(
"LQ"));
1866 Float_t *fZq = (
float*)fZiq;
1868 Int_t JTMED = fGclink->jtmed;
1869 for (Int_t i = 1; i <= fGcnum->ntmed; i++) {
1870 Int_t JTM = fZlq[JTMED-i];
1871 if (! JTM)
continue;
1872 TString Medium((Char_t *)(&fZiq[JTM+1]),20);
1873 if (!Medium.BeginsWith(TpcMedium))
continue;
1874 Int_t JTMN = fZlq[JTM];
1875 if (! JTMN)
continue;
1876 Float_t cutele = fZq[JTMN+ITPAR];
1879 LOG_INFO <<
"StTpcRSMaker::GetCutEle: specific CutEle for medium \"" << TpcMedium.Data() <<
"\" has not been found. Use default." << endm;
1880 return fGccuts->cutele;
1883 Bool_t StTpcRSMaker::TrackSegment2Propagate(g2t_tpc_hit_st *tpc_hitC, g2t_vertex_st *gver,
HitPoint_t &TrackSegmentHits) {
1884 static Int_t iBreak = 0;
1888 Int_t Id = tpc_hitC->track_p;
1889 mNoTpcHitsAll[Id-1]++;
1890 if (tpc_hitC->volume_id < 10000) {
1892 mNoTpcHitsReal[Id-1]++;
1894 if (tpc_hitC->de > 0) {
1896 }
else if (! mNSplittedHits) {
1899 Int_t volId = tpc_hitC->volume_id%10000;
1900 Int_t sector = volId/100;
1902 TrackSegmentHits.xyzG =
1904 coorG = TrackSegmentHits.xyzG;
1910 transform(coorG, coorS,sector,0); PrPP(
Make,coorS);
1911 Int_t row = coorS.fromRow();
1912 transform(coorG, coorLT,sector,row); PrPP(
Make,coorLT);
1913 Int_t io = (row <= St_tpcPadConfigC::instance()->numberOfInnerRows(sector)) ? 0 : 1;
1914 TrackSegmentHits.TrackId = Id;
1915 TrackSegmentHits.tpc_hitC = tpc_hitC;
1917 if (ClusterProfile) {
1918 checkList[io][0]->Fill(TrackSegmentHits.tpc_hitC->x[2],TMath::Abs(TrackSegmentHits.tpc_hitC->de));
1919 checkList[io][1]->Fill(TrackSegmentHits.tpc_hitC->x[2], TrackSegmentHits.tpc_hitC->ds );
1921 TrackSegmentHits.sMin = TrackSegmentHits.s - TrackSegmentHits.tpc_hitC->ds;
1922 TrackSegmentHits.sMax = TrackSegmentHits.s;
1923 if (TrackSegmentHits.sMin < msMin) msMin = TrackSegmentHits.sMin;
1924 if (TrackSegmentHits.sMax > msMax) msMax = TrackSegmentHits.sMax;
1926 static Float_t BFieldG[3];
1927 StMagF::Agufld(tpc_hitC->x,BFieldG);
1930 StThreeVectorD pxyzG(tpc_hitC->p[0],tpc_hitC->p[1],tpc_hitC->p[2]);
1933 transform( dirG, dirLT,sector,row); PrPP(
Make,dirLT);
1934 transform( BG, BLT,sector,row); PrPP(
Make,BLT);
1936 if (TESTBIT(
m_Mode, kDistortion) && StMagUtilities::Instance()) {
1937 Float_t pos[3] = {(Float_t ) coorLT.position().x(), (Float_t ) coorLT.position().y(), (Float_t ) coorLT.position().z()};
1938 Float_t posMoved[3];
1939 StMagUtilities::Instance()->
DoDistortion(pos,posMoved,sector);
1941 coorLT.setPosition(position);
1942 transform(coorLT,TrackSegmentHits.xyzG); PrPP(
Make,coorLT);
1945 transform(coorLT,TrackSegmentHits.coorLS); PrPP(
Make,TrackSegmentHits.coorLS);
1946 transform( dirLT, TrackSegmentHits.dirLS); PrPP(
Make,TrackSegmentHits.dirLS);
1947 transform( BLT, TrackSegmentHits.BLS); PrPP(
Make,TrackSegmentHits.BLS);
1948 Double_t
tof = gver->ge_tof + fgTriggerT0;
1950 tof += tpc_hitC->tof;
1951 Double_t driftLength = TrackSegmentHits.coorLS.position().z() + tof*gStTpcDb->DriftVelocity(sector);
1953 if (driftLength > -1.0 && driftLength <= 0) {
1954 if ((row > St_tpcPadConfigC::instance()->numberOfInnerRows(sector) && driftLength > -gStTpcDb->WirePlaneGeometry()->outerSectorAnodeWirePadPlaneSeparation()) ||
1955 (row <= St_tpcPadConfigC::instance()->numberOfInnerRows(sector) && driftLength > -gStTpcDb->WirePlaneGeometry()->innerSectorAnodeWirePadPlaneSeparation()))
1956 driftLength = TMath::Abs(driftLength);
1959 TrackSegmentHits.coorLS.position().setZ(driftLength); PrPP(
Make,TrackSegmentHits.coorLS);
1961 transform(TrackSegmentHits.coorLS,TrackSegmentHits.Pad,kFALSE,kFALSE);
1962 PrPP(
Make,TrackSegmentHits.Pad);
1966 void StTpcRSMaker::GenerateSignal(
HitPoint_t &TrackSegmentHits, Int_t sector, Int_t rowMin, Int_t rowMax, Double_t sigmaJitterT, Double_t sigmaJitterX) {
1969 for(Int_t row = rowMin; row <= rowMax; row++) {
1971 if ( ! St_tpcAnodeHVavgC::instance()->livePadrow(sector,row))
continue;
1973 Int_t io = (row <= St_tpcPadConfigC::instance()->numberOfInnerRows(sector)) ? 0 : 1;
1975 TF1F *ShaperResponse = mShaperResponses[io][sector-1];
1978 transform(xyzW,Pad,kFALSE,kFALSE);
1979 Float_t bin = Pad.timeBucket();
1980 Int_t binT = TMath::Nint(bin);
1981 if (binT < 0 || binT >= NoOfTimeBins)
continue;
1982 Double_t dT = bin - binT + St_TpcResponseSimulatorC::instance()->T0offset();
1983 dT += (row <= St_tpcPadConfigC::instance()->numberOfInnerRows(sector)) ?
1984 St_TpcResponseSimulatorC::instance()->T0offsetI() :
1985 St_TpcResponseSimulatorC::instance()->T0offsetO();
1986 if (sigmaJitterT) dT += gRandom->Gaus(0,sigmaJitterT);
1988 Double_t dely = {transform.yFromRow(sector,row)-yOnWire};
1989 Double_t localYDirectionCoupling = mChargeFraction[io][sector-1]->GetSaveL(&dely);
1991 Int_t idWire = TMath::Abs(TMath::Nint((transform.yFromRow(sector,row)-yOnWire)/anodeWirePitch));
1992 if (idWire > 6)
continue;
1993 Double_t localYDirectionCoupling = mLocalYDirectionCoupling[io][sector-1][idWire];
1995 if (ClusterProfile) {
1996 checkList[io][10]->Fill(TrackSegmentHits.xyzG.position().z(),localYDirectionCoupling);
1998 if(localYDirectionCoupling < minSignal)
continue;
1999 Float_t padX = Pad.pad();
2000 Int_t CentralPad = TMath::Nint(padX);
2001 if (CentralPad < 1)
continue;
2002 Int_t PadsAtRow = St_tpcPadConfigC::instance()->numberOfPadsAtRow(sector,row);
2003 if(CentralPad > PadsAtRow)
continue;
2004 Int_t DeltaPad = TMath::Nint(mPadResponseFunction[io][sector-1]->GetXmax()) + 1;
2005 Int_t padMin = TMath::Max(CentralPad - DeltaPad ,1);
2006 Int_t padMax = TMath::Min(CentralPad + DeltaPad ,PadsAtRow);
2007 Int_t Npads = TMath::Min(padMax-padMin+1, kPadMax);
2008 Double_t xPadMin = padMin - padX;
2009 static Double_t XDirectionCouplings[kPadMax];
2010 static Double_t TimeCouplings[kTimeBacketMax];
2011 mPadResponseFunction[io][sector-1]->GetSaveL(Npads,xPadMin,XDirectionCouplings);
2013 for(Int_t pad = padMin; pad <= padMax; pad++) {
2014 if ( ! StDetectorDbTpcRDOMasks::instance()->isRowOn(sector,row,pad))
continue;
2015 Double_t gain = QAv*mGainLocal;
2018 if (! TESTBIT(
m_Mode, kGAINOAtALL)) {
2019 Double_t GC = St_tpcPadGainT0BC::instance()->Gain(sector,row,pad);
2020 if (GC <= 0.0)
continue;
2022 dt -= St_tpcPadGainT0BC::instance()->T0(sector,row,pad);
2024 if (ClusterProfile) {
2025 checkList[io][12]->Fill(TrackSegmentHits.xyzG.position().z(),gain);
2026 GainHist[1]->Fill(sector,row,gain);
2029 Double_t localXDirectionCoupling = gain*XDirectionCouplings[pad-padMin];
2030 if (localXDirectionCoupling < minSignal)
continue;
2031 if (ClusterProfile) {
2032 checkList[io][13]->Fill(TrackSegmentHits.xyzG.position().z(),localXDirectionCoupling);
2034 Double_t XYcoupling = localYDirectionCoupling*localXDirectionCoupling;
2035 if (ClusterProfile) {
2036 checkList[io][14]->Fill(TrackSegmentHits.xyzG.position().z(),XYcoupling);
2038 if(XYcoupling < minSignal)
continue;
2039 Int_t bin_low = TMath::Max(0 ,binT + TMath::Nint(dt+ShaperResponse->GetXmin()-0.5));
2040 Int_t bin_high = TMath::Min(NoOfTimeBins-1,binT + TMath::Nint(dt+ShaperResponse->GetXmax()+0.5));
2041 Int_t index = NoOfTimeBins*((row-1)*NoOfPads+pad-1)+bin_low;
2042 Int_t Ntbks = TMath::Min(bin_high-bin_low+1, kTimeBacketMax);
2043 Double_t tt = -dt + (bin_low - binT);
2044 ShaperResponse->GetSaveL(Ntbks,tt,TimeCouplings);
2045 for(Int_t itbin=bin_low;itbin<=bin_high;itbin++, index++){
2046 Double_t signal = XYcoupling*TimeCouplings[itbin-bin_low];
2047 if (signal < minSignal)
continue;
2049 static Int_t iBreak = 0;
2050 if (TMath::IsNaN(signal) || TMath::IsNaN(SignalSum[index].Sum)) {
2054 TotalSignalInCluster += signal;
2055 SignalSum[index].Sum += signal;
2056 if (ClusterProfile) {
2057 if (pad >= pad0 && pad < pad0 + kPadMax &&
2058 itbin >= tbk0 && itbin < tbk0 + kTimeBacketMax) {
2059 padsdE[pad-pad0] += signal;
2060 tbksdE[itbin-tbk0] += signal;
2063 rowsdE[row-1] += signal;
2064 rowsdEH[row-1] += signal;
2065 if ( TrackSegmentHits.TrackId ) {
2066 if (! SignalSum[index].TrackId ) SignalSum[index].TrackId = TrackSegmentHits.TrackId;
2068 if ( SignalSum[index].TrackId != TrackSegmentHits.TrackId && SignalSum[index].Sum < 2*signal)
2069 SignalSum[index].TrackId = TrackSegmentHits.TrackId;
2072 if (Debug() > 13 && (SignalSum[index].Sum > 0 || ! TMath::Finite(SignalSum[index].Sum)) ) {
2073 LOG_INFO <<
"simu row = " << TrackSegmentHits.tpc_hitC->volume_id%100 <<
"\tR/P/T/I = " << row <<
" /\t" << pad <<
" /\t" << itbin <<
" /\t" << index
2074 <<
"\tSum/Adc/TrackId = " << SignalSum[index].Sum <<
" /\t"
2075 << SignalSum[index].Adc <<
" /\t" << SignalSum[index].TrackId
2076 <<
"\tsignal = " << signal
2077 <<
"\trow Min/Max = " << rowMin <<
"/" << rowMax
2079 if (! TMath::Finite(SignalSum[index].Sum)) {
2080 LOG_INFO <<
"Not Finite" << endm;
2089 Double_t StTpcRSMaker::dEdxCorrection(
HitPoint_t &TrackSegmentHits) {
2090 Double_t dEdxCor = 1;
2091 if (m_TpcdEdxCorrection) {
2093 Double_t dStep = TMath::Abs(TrackSegmentHits.tpc_hitC->ds);
2095 memset (&CdEdx, 0,
sizeof(
dEdxY2_t));
2098 CdEdx.QRatioA = -2.;
2100 CdEdx.sector = TrackSegmentHits.Pad.sector();
2101 CdEdx.row = TrackSegmentHits.Pad.row();
2102 CdEdx.pad = TMath::Nint(TrackSegmentHits.Pad.pad());
2103 CdEdx.edge = CdEdx.pad;
2104 if (CdEdx.edge > 0.5*St_tpcPadConfigC::instance()->numberOfPadsAtRow(CdEdx.sector,CdEdx.row))
2105 CdEdx.edge += 1 - St_tpcPadConfigC::instance()->numberOfPadsAtRow(CdEdx.sector,CdEdx.row);
2109 Int_t p1 = tpcHit->minPad();
2110 Int_t p2 = tpcHit->maxPad();
2111 Int_t t1 = tpcHit->minTmbk();
2112 Int_t t2 = tpcHit->maxTmbk();
2113 CdEdx.rCharge= 0.5*m_TpcdEdxCorrection->Adc2GeV()*TMath::Pi()/4.*(p2-p1+1)*(t2-t1+1);
2114 if (TESTBIT(
m_Mode, kEmbeddingShortCut) &&
2115 (tpcHit->idTruth() && tpcHit->qaTruth() > 95)) CdEdx.lSimulated = tpcHit->idTruth();
2118 CdEdx.xyz[0] = TrackSegmentHits.coorLS.position().x();
2119 CdEdx.xyz[1] = TrackSegmentHits.coorLS.position().y();
2120 CdEdx.xyz[2] = TrackSegmentHits.coorLS.position().z();
2121 Double_t probablePad = St_tpcPadConfigC::instance()->numberOfPadsAtRow(CdEdx.sector,CdEdx.row)/2;
2122 Double_t pitch = (CdEdx.row <= St_tpcPadConfigC::instance()->numberOfInnerRows(CdEdx.sector)) ?
2123 St_tpcPadConfigC::instance()->innerSectorPadPitch(CdEdx.sector) :
2124 St_tpcPadConfigC::instance()->outerSectorPadPitch(CdEdx.sector);
2125 Double_t PhiMax = TMath::ATan2(probablePad*pitch, St_tpcPadConfigC::instance()->radialDistanceAtRow(CdEdx.sector,CdEdx.row));
2126 CdEdx.PhiR = TMath::ATan2(CdEdx.xyz[0],CdEdx.xyz[1])/PhiMax;
2127 CdEdx.xyzD[0] = TrackSegmentHits.dirLS.position().x();
2128 CdEdx.xyzD[1] = TrackSegmentHits.dirLS.position().y();
2129 CdEdx.xyzD[2] = TrackSegmentHits.dirLS.position().z();
2130 CdEdx.ZdriftDistance = CdEdx.xyzD[2];
2131 CdEdx.zG = CdEdx.xyz[2];
2132 if (St_trigDetSumsC::instance()) CdEdx.Zdc = St_trigDetSumsC::instance()->zdcX();
2133 CdEdx.ZdriftDistance = TrackSegmentHits.coorLS.position().z();
2134 St_tpcGas *tpcGas = m_TpcdEdxCorrection->tpcGas();
2136 CdEdx.ZdriftDistanceO2 = CdEdx.ZdriftDistance*(*tpcGas)[0].ppmOxygenIn;
2137 Int_t iok = m_TpcdEdxCorrection->dEdxCorrection(CdEdx);
2139 dEdxCor = CdEdx.F.dE;
virtual void AddData(TDataSet *data, const char *dir=".data")
User methods.
void ConfigAltro(int ONBaselineCorrection1, int ONTailcancellation, int ONBaselineCorrection2, int ONClipping, int ONZerosuppression)
Configures which modules of the Altro should be on.
Int_t GetIndex(UInt_t sortedIndex) const
returns the original index of the row by its sorted index
int adc() const
ADC value [0,4095].
void ConfigTailCancellationFilter(int K1, int K2, int K3, int L1, int L2, int L3)
Configures the Tail Cancellation Filter (TCF) Module.
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) ...
This the header File for the Altro class.
Stores information for tiles in STAR Event Plane Detector.
void PrintParameters()
Prints the set Parameters, if module is configured.
virtual const char * GetName() const
special overload
void RunEmulation()
Runs the emulation of all configured Modules.
int tile() const
tile on the supersector [1,31]
void ConfigZerosuppression(int Threshold, int MinSamplesaboveThreshold, int Presamples, int Postsamples)
Configures the Zero Suppression Module (ZSU)
int tac() const
TAC value [0,4095].