Project
Loading...
Searching...
No Matches
genEvents.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#include <iostream>
16#include <fstream>
17#include <cstring>
18#include <sys/stat.h>
19
20#include "Rtypes.h"
21#include "TRandom.h"
22#include "TH1F.h"
23#include "TFile.h"
24#include "TCanvas.h"
25#include "TPad.h"
26
27#include <iostream>
28#include <iomanip>
29#include <limits>
30
31#include "genEvents.h"
32#include "GPUTPCClusterData.h"
33#include "GPUTPCMCInfo.h"
35#include "GPUParam.inc"
37#include "GPUTPCGMPropagator.h"
38#include "GPUTPCGMMerger.h"
39#include "GPUChainTracking.h"
40#include "GPUConstantMem.h"
41#define GPUSETTINGS_STANDALONE
42#define GPUSETTINGS_DISPLAY
43#include "GPUSettings.h"
44
45using namespace o2::gpu;
46using namespace std;
47namespace o2::gpu
48{
49extern GPUSettingsStandalone configStandalone;
50}
51
52int32_t genEvents::GetSector(double GlobalPhi)
53{
54 double phi = GlobalPhi;
55 // std::cout<<" GetSector: phi = "<<phi<<std::endl;
56
57 if (phi >= mTwoPi) {
58 phi -= mTwoPi;
59 }
60 if (phi < 0) {
61 phi += mTwoPi;
62 }
63 return (int32_t)(phi / mSectorDAngle);
64}
65
66int32_t genEvents::GetDSector(double LocalPhi) { return GetSector(LocalPhi + mSectorAngleOffset); }
67
68double genEvents::GetSectorAngle(int32_t iSector) { return mSectorAngleOffset + iSector * mSectorDAngle; }
69
70int32_t genEvents::RecalculateSector(GPUTPCGMPhysicalTrackModel& t, int32_t& iSector)
71{
72 double phi = atan2(t.GetY(), t.GetX());
73 // std::cout<<" recalculate: phi = "<<phi<<std::endl;
74 int32_t dSector = GetDSector(phi);
75
76 if (dSector == 0) {
77 return 0; // nothing to do
78 }
79 // std::cout<<" dSector = "<<dSector<<std::endl;
80 double dAlpha = dSector * mSectorDAngle;
81 // rotate track on angle dAlpha
82
83 t.Rotate(dAlpha);
84
86 if (iSector >= 18) {
87 iSector -= 18;
88 }
89 return 1;
90}
91
92double genEvents::GetGaus(double sigma)
93{
94 double x = 0;
95 do {
96 x = gRandom->Gaus(0., sigma);
97 if (fabs(x) <= 3.5 * sigma) {
98 break;
99 }
100 } while (1);
101 return x;
102}
103
104void genEvents::InitEventGenerator(const std::string& dir)
105{
106 for (int32_t i = 0; i < 3; i++) {
107 for (int32_t j = 0; j < 2; j++) {
108 char name[1024], title[1024];
109
110 snprintf(name, 1024, "clError%s%d", (j == 0 ? "Y" : "Z"), i);
111
112 snprintf(title, 1024, "Cluster %s Error for row region %d", (j == 0 ? "Y" : "Z"), i);
113
114 mClusterError[i][j] = new TH1F(name, title, 1000, 0., .7);
115 mClusterError[i][j]->GetXaxis()->SetTitle("Cluster Error [cm]");
116 }
117 }
118 mRec->rec()->DumpSettings(dir.c_str()); // the chain's own override does not write settings.dump
119}
120
122{
123 TFile* tout = new TFile("generator.root", "RECREATE");
124 TCanvas* c = new TCanvas("ClusterErrors", "Cluste rErrors", 0, 0, 700, 700. * 2. / 3.);
125 c->Divide(3, 2);
126 int32_t ipad = 1;
127 for (int32_t j = 0; j < 2; j++) {
128 for (int32_t i = 0; i < 3; i++) {
129 c->cd(ipad++);
130 int32_t k = i;
131 if (i == 1) {
132 k = 2;
133 }
134 if (i == 2) {
135 k = 1;
136 }
137 if (tout) {
138 mClusterError[k][j]->Write();
139 }
140 gPad->SetLogy();
141 mClusterError[k][j]->Draw();
142 // delete mClusterError[i][j];
143 // mClusterError[i][j]=0;
144 }
145 }
146 c->Print("plots/clusterErrors.pdf");
147 delete c;
148 if (tout) {
149 tout->Close();
150 delete tout;
151 }
152}
153
155{
156 mRec->ClearIOPointers();
157 static int32_t iEvent = -1;
158 iEvent++;
159 if (iEvent == 0) {
160 gRandom->SetSeed(configStandalone.seed);
161 }
162
163 int32_t nTracks = configStandalone.EG.numberOfTracks; // Number of MC tracks, must be at least as large as the largest fMCID assigned above
164 cout << "NTracks " << nTracks << endl;
165 std::vector<GPUTPCMCInfo> mcInfo(nTracks);
166 memset(mcInfo.data(), 0, nTracks * sizeof(mcInfo[0]));
167
168 // double Bz = param.ConstBz();
169 // std::cout<<"Bz[kG] = "<<param.BzkG()<<std::endl;
170
172 {
173 const GPUTPCGMMerger& merger = mRec->GetProcessors()->tpcMerger;
174 prop.SetPolynomialField(&merger.Param().polynomialField);
175 }
176
177 // Bz*=o2::gpu::gpu_common_constants::kCLight;
178
179 std::vector<GenCluster> vClusters;
180 int32_t clusterId = 0; // Here we count up the cluster ids we fill (must be unique).
181 // gRandom->SetSeed(0);
182 // uint32_t seed = gRandom->GetSeed();
183
184 for (int32_t itr = 0; itr < nTracks; itr++) {
185 // std::cout<<"Track "<<itr<<":"<<std::endl;
186 // gRandom->SetSeed(seed);
187
188 mcInfo[itr].pid = -100; //-100: Unknown / other, 0: Electron, 1, Muon, 2: Pion, 3: Kaon, 4: Proton
189 mcInfo[itr].charge = 1;
190 mcInfo[itr].prim = 1; // Primary particle
191 mcInfo[itr].primDaughters = 0; // Primary particle with daughters in the TPC
192 mcInfo[itr].x = 0; // Position of MC track at entry of TPC / first hit in the TPC
193 mcInfo[itr].y = 0;
194 mcInfo[itr].z = 0;
195 mcInfo[itr].pX = 0; // Momentum of MC track at that position
196 mcInfo[itr].pY = 0;
197 mcInfo[itr].pZ = 0;
198
200 double dphi = mTwoPi / nTracks;
201 double phi = mSectorAngleOffset + dphi * itr;
202 double eta = gRandom->Uniform(-1.5, 1.5);
203
204 double theta = 2 * std::atan(1. / exp(eta));
205 double lambda = theta - M_PI / 2;
206 // double theta = gRandom->Uniform(-60,60)*M_PI/180.;
207 double pt = .08 * std::pow(10, gRandom->Uniform(0, 2.2));
208
209 double q = 1.;
210 int32_t iSector = GetSector(phi);
211 phi = phi - GetSectorAngle(iSector);
212
213 // std::cout<<"phi = "<<phi<<std::endl;
214 double x0 = cosf(phi);
215 double y0 = sinf(phi);
216 double z0 = tanf(lambda);
217 t.Set(x0, y0, z0, pt * x0, pt * y0, pt * z0, q);
218
219 if (RecalculateSector(t, iSector) != 0) {
220 std::cout << "Initial sector wrong!!!" << std::endl;
221 // exit(0);
222 }
223
224 for (uint32_t iRow = 0; iRow < GPUTPCGeometry::NROWS; iRow++) {
225 // if( iRow>=50 ) break; //SG!!!
226 float xRow = GPUTPCGeometry::Row2X(iRow);
227 // transport to row
228 int32_t err = 0;
229 for (int32_t itry = 0; itry < 1; itry++) {
230 float B[3];
231 prop.GetBxByBz(GetSectorAngle(iSector), t.GetX(), t.GetY(), t.GetZ(), B);
232 float dLp = 0;
233 err = t.PropagateToXBxByBz(xRow, B[0], B[1], B[2], dLp);
234 if (err) {
235 std::cout << "Can not propagate to x = " << xRow << std::endl;
236 t.Print();
237 break;
238 }
239 if (fabsf(t.GetZ()) >= GPUTPCGeometry::TPCLength()) {
240 std::cout << "Can not propagate to x = " << xRow << ": Z outside the volume" << std::endl;
241 t.Print();
242 err = -1;
243 break;
244 }
245 // rotate track coordinate system to current sector
246 int32_t isNewSector = RecalculateSector(t, iSector);
247 if (!isNewSector) {
248 break;
249 } else {
250 std::cout << "track " << itr << ": new sector " << iSector << " at row " << iRow << std::endl;
251 }
252 }
253 if (err) {
254 break;
255 }
256 // std::cout<<" track "<<itr<<": Sector "<<iSector<<" row "<<iRow<<" params :"<<std::endl;
257 // t.Print();
258 // track at row iRow, sector iSector
259 if (iRow == 0) { // store MC track at first row
260 // std::cout<<std::setprecision( 20 );
261 // std::cout<<"track "<<itr<<": x "<<t.X()<<" y "<<t.Y()<<" z "<<t.Z()<<std::endl;
262 GPUTPCGMPhysicalTrackModel tg(t); // global coordinates
263 tg.Rotate(-GetSectorAngle(iSector));
264
265 mcInfo[itr].pid = 2; // pion
266 mcInfo[itr].charge = 3 * q;
267 mcInfo[itr].x = tg.GetX(); // Position of MC track at entry of TPC / first hit in the TPC
268 mcInfo[itr].y = tg.GetY();
269 mcInfo[itr].z = tg.GetZ();
270 mcInfo[itr].pX = tg.GetPx(); // Momentum of MC track at that position
271 mcInfo[itr].pY = tg.GetPy();
272 mcInfo[itr].pZ = tg.GetPz();
273 // std::cout<<" mc Z = "<<tg.GetZ()<<std::endl;
274 }
275
276 // create cluster
277 GenCluster c;
278 float sigmaY = 0.3;
279 float sigmaZ = 0.5;
280 const int32_t rowType = iRow < 64 ? 0 : (iRow < 128 ? 2 : 1);
281 t.UpdateValues();
282 param.GetClusterErrors2(iSector, rowType, t.GetZ(), t.GetSinPhi(), t.GetDzDs(), -1.f, 0.f, 0.f, sigmaY, sigmaZ);
283 sigmaY = std::sqrt(sigmaY);
284 sigmaZ = std::sqrt(sigmaZ);
285 mClusterError[rowType][0]->Fill(sigmaY);
286 mClusterError[rowType][1]->Fill(sigmaZ);
287 // std::cout<<sigmaY<<" "<<sigmaY<<std::endl;
288 // if( sigmaY > 0.5 ) sigmaY = 0.5;
289 // if( sigmaZ > 0.5 ) sigmaZ = 0.5;
290 c.sector = (t.GetZ() >= 0.) ? iSector : iSector + 18;
291 c.row = iRow;
292 c.mcID = itr;
293 c.x = t.GetX();
294 c.y = t.GetY() + GetGaus(sigmaY);
295 c.z = t.GetZ() + GetGaus(sigmaZ);
296 c.id = clusterId++;
297 vClusters.push_back(c);
298 } // iRow
299 } // itr
300
301 std::vector<AliHLTTPCClusterMCLabel> labels;
302
303 std::unique_ptr<GPUTPCClusterData> clSectors[GPUChainTracking::NSECTORS];
304
305 for (int32_t iSector = 0; iSector < (int32_t)GPUChainTracking::NSECTORS; iSector++) // HLT Sector numbering, sectors go from 0 to 35, all spanning all rows from 0 to 158.
306 {
307 int32_t nNumberOfHits = 0;
308 for (uint32_t i = 0; i < vClusters.size(); i++) {
309 if (vClusters[i].sector == iSector) {
310 nNumberOfHits++;
311 }
312 }
313 // For every sector we first have to fill the number of hits in this sector to the file
314 mRec->mIOPtrs.nClusterData[iSector] = nNumberOfHits;
315
316 GPUTPCClusterData* clusters = new GPUTPCClusterData[nNumberOfHits];
317 clSectors[iSector].reset(clusters);
318 int32_t icl = 0;
319 for (uint32_t i = 0; i < vClusters.size(); i++) {
320 GenCluster& c = vClusters[i];
321 if (c.sector == iSector) {
322 clusters[icl].id = c.id;
323 clusters[icl].row = c.row; // We fill one hit per TPC row
324 clusters[icl].x = c.x;
325 clusters[icl].y = c.y;
326 clusters[icl].z = c.z;
327 clusters[icl].amp = 100; // Arbitrary amplitude
328 icl++;
329 AliHLTTPCClusterMCLabel clusterLabel;
330 for (int32_t j = 0; j < 3; j++) {
331 clusterLabel.fClusterID[j].fMCID = -1;
332 clusterLabel.fClusterID[j].fWeight = 0;
333 }
334 clusterLabel.fClusterID[0].fMCID = c.mcID;
335 clusterLabel.fClusterID[0].fWeight = 1;
336 labels.push_back(clusterLabel);
337 }
338 }
339 mRec->mIOPtrs.clusterData[iSector] = clusters;
340 }
341
342 // Create vector with cluster MC labels, clusters are counter from 0 to clusterId in the order they have been written above. No separation in sectors.
343
344 mRec->mIOPtrs.nMCLabelsTPC = labels.size();
345 mRec->mIOPtrs.mcLabelsTPC = labels.data();
346
347 mRec->mIOPtrs.nMCInfosTPC = mcInfo.size();
348 mRec->mIOPtrs.mcInfosTPC = mcInfo.data();
349 static const GPUTPCMCInfoCol mcColInfo = {0, (uint32_t)mcInfo.size()};
350 mRec->mIOPtrs.mcInfosTPCCol = &mcColInfo;
351 mRec->mIOPtrs.nMCInfosTPCCol = 1;
352
353 mRec->DumpData(filename);
354 labels.clear();
355 mcInfo.clear();
356 return (0);
357}
358
359void genEvents::RunEventGenerator(GPUChainTracking* rec, const std::string& dir)
360{
361 std::unique_ptr<genEvents> gen(new genEvents(rec));
362 mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
363
364 gen->InitEventGenerator(dir);
365
366 for (int32_t i = 0; i < (configStandalone.nEvents == -1 ? 10 : configStandalone.nEvents); i++) {
367 GPUInfo("Generating event %d/%d", i, configStandalone.nEvents == -1 ? 10 : configStandalone.nEvents);
368 gen->GenerateEvent(rec->GetParam(), (dir + GPUCA_EVDUMP_FILE "." + std::to_string(i) + ".dump").c_str());
369 }
370 gen->FinishEventGenerator();
371}
default_random_engine gen(dev())
uint64_t exp(uint64_t base, uint8_t exp) noexcept
int32_t i
#define GPUCA_EVDUMP_FILE
Definition GPUDef.h:47
uint32_t iSector
configStandalone Light OpenGL display display_light Apply smoothing to points Enable Z buffer Highlight links Highlight seeds Highlight sector tracks Highlight final tracks Show individual sector
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in maximum chi2 per attached tracklet for TRD tracks take into account the full likelihood of the slope including exponential tails Tracks with less attached tracklets are discarded after the tracking Post trigger Pile up integration time in BCs fits all iterations but the last one in projections Use material lookup table for TPC refit Apply workarounds to avoid cyclic merge should not be needed tpc dyn configStandalone Processing proc_rtc Replace constant variables static by constexpr expressions Compile RTC in deterministic with NO_FAST_MATH flags and GPUCA_DETERMINISTIC_MODE define Use RTC to optimize GPU code h configStandalone Processing proc_rtctech Use a file lock to serialize access to the cache folder int32_t
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of merger(must be odd to end with inward fit)") AddOptionRTC(trackFitRejectMode
configStandalone rec
std::vector< o2::MCCompLabel > labels
uint32_t j
Definition RawData.h:0
uint32_t c
Definition RawData.h:2
Definition B.h:16
static constexpr int32_t NSECTORS
Definition GPUChain.h:58
void InitEventGenerator(const std::string &dir)
Definition genEvents.h:31
int32_t GenerateEvent(const GPUParam &sectorParam, const char *filename)
Definition genEvents.h:32
void FinishEventGenerator()
Definition genEvents.h:33
static void RunEventGenerator(GPUChainTracking *rec, const std::string &dir)
Definition genEvents.h:35
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint const GLchar * name
Definition glcorearb.h:781
GLuint GLfloat x0
Definition glcorearb.h:5034
GLenum GLfloat param
Definition glcorearb.h:271
GLuint GLfloat GLfloat y0
Definition glcorearb.h:5034
std::ostream & cout()
GPUSettingsStandalone configStandalone
Definition genEvents.cxx:49
float dSector(float phi, int nSectors=18, float sectorPhaseRad=0.f)
Fractional azimuthal position inside a periodic sector pattern.
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
std::string filename()
AliHLTTPCClusterMCWeight fClusterID[3]
const int nEvents
Definition test_Fifo.cxx:27
std::vector< Cluster > clusters