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#include "GPUSettings.h"
42
43using namespace o2::gpu;
44using namespace std;
45namespace o2::gpu
46{
47extern GPUSettingsStandalone configStandalone;
48}
49
50int32_t genEvents::GetSector(double GlobalPhi)
51{
52 double phi = GlobalPhi;
53 // std::cout<<" GetSector: phi = "<<phi<<std::endl;
54
55 if (phi >= mTwoPi) {
56 phi -= mTwoPi;
57 }
58 if (phi < 0) {
59 phi += mTwoPi;
60 }
61 return (int32_t)(phi / mSectorDAngle);
62}
63
64int32_t genEvents::GetDSector(double LocalPhi) { return GetSector(LocalPhi + mSectorAngleOffset); }
65
66double genEvents::GetSectorAngle(int32_t iSector) { return mSectorAngleOffset + iSector * mSectorDAngle; }
67
68int32_t genEvents::RecalculateSector(GPUTPCGMPhysicalTrackModel& t, int32_t& iSector)
69{
70 double phi = atan2(t.GetY(), t.GetX());
71 // std::cout<<" recalculate: phi = "<<phi<<std::endl;
72 int32_t dSector = GetDSector(phi);
73
74 if (dSector == 0) {
75 return 0; // nothing to do
76 }
77 // std::cout<<" dSector = "<<dSector<<std::endl;
78 double dAlpha = dSector * mSectorDAngle;
79 // rotate track on angle dAlpha
80
81 t.Rotate(dAlpha);
82
83 iSector += dSector;
84 if (iSector >= 18) {
85 iSector -= 18;
86 }
87 return 1;
88}
89
90double genEvents::GetGaus(double sigma)
91{
92 double x = 0;
93 do {
94 x = gRandom->Gaus(0., sigma);
95 if (fabs(x) <= 3.5 * sigma) {
96 break;
97 }
98 } while (1);
99 return x;
100}
101
103{
104 for (int32_t i = 0; i < 3; i++) {
105 for (int32_t j = 0; j < 2; j++) {
106 char name[1024], title[1024];
107
108 snprintf(name, 1024, "clError%s%d", (j == 0 ? "Y" : "Z"), i);
109
110 snprintf(title, 1024, "Cluster %s Error for row region %d", (j == 0 ? "Y" : "Z"), i);
111
112 mClusterError[i][j] = new TH1F(name, title, 1000, 0., .7);
113 mClusterError[i][j]->GetXaxis()->SetTitle("Cluster Error [cm]");
114 }
115 }
116}
117
119{
120 TFile* tout = new TFile("generator.root", "RECREATE");
121 TCanvas* c = new TCanvas("ClusterErrors", "Cluste rErrors", 0, 0, 700, 700. * 2. / 3.);
122 c->Divide(3, 2);
123 int32_t ipad = 1;
124 for (int32_t j = 0; j < 2; j++) {
125 for (int32_t i = 0; i < 3; i++) {
126 c->cd(ipad++);
127 int32_t k = i;
128 if (i == 1) {
129 k = 2;
130 }
131 if (i == 2) {
132 k = 1;
133 }
134 if (tout) {
135 mClusterError[k][j]->Write();
136 }
137 gPad->SetLogy();
138 mClusterError[k][j]->Draw();
139 // delete mClusterError[i][j];
140 // mClusterError[i][j]=0;
141 }
142 }
143 c->Print("plots/clusterErrors.pdf");
144 delete c;
145 if (tout) {
146 tout->Close();
147 delete tout;
148 }
149}
150
151int32_t genEvents::GenerateEvent(const GPUParam& param, const char* filename)
152{
153 mRec->ClearIOPointers();
154 static int32_t iEvent = -1;
155 iEvent++;
156 if (iEvent == 0) {
157 gRandom->SetSeed(configStandalone.seed);
158 }
159
160 int32_t nTracks = configStandalone.EG.numberOfTracks; // Number of MC tracks, must be at least as large as the largest fMCID assigned above
161 cout << "NTracks " << nTracks << endl;
162 std::vector<GPUTPCMCInfo> mcInfo(nTracks);
163 memset(mcInfo.data(), 0, nTracks * sizeof(mcInfo[0]));
164
165 // double Bz = param.ConstBz();
166 // std::cout<<"Bz[kG] = "<<param.BzkG()<<std::endl;
167
169 {
170 const GPUTPCGMMerger& merger = mRec->GetProcessors()->tpcMerger;
171 prop.SetPolynomialField(&merger.Param().polynomialField);
172 }
173
174 // Bz*=o2::gpu::gpu_common_constants::kCLight;
175
176 std::vector<GenCluster> vClusters;
177 int32_t clusterId = 0; // Here we count up the cluster ids we fill (must be unique).
178 // gRandom->SetSeed(0);
179 // uint32_t seed = gRandom->GetSeed();
180
181 for (int32_t itr = 0; itr < nTracks; itr++) {
182 // std::cout<<"Track "<<itr<<":"<<std::endl;
183 // gRandom->SetSeed(seed);
184
185 mcInfo[itr].pid = -100; //-100: Unknown / other, 0: Electron, 1, Muon, 2: Pion, 3: Kaon, 4: Proton
186 mcInfo[itr].charge = 1;
187 mcInfo[itr].prim = 1; // Primary particle
188 mcInfo[itr].primDaughters = 0; // Primary particle with daughters in the TPC
189 mcInfo[itr].x = 0; // Position of MC track at entry of TPC / first hit in the TPC
190 mcInfo[itr].y = 0;
191 mcInfo[itr].z = 0;
192 mcInfo[itr].pX = 0; // Momentum of MC track at that position
193 mcInfo[itr].pY = 0;
194 mcInfo[itr].pZ = 0;
195
197 double dphi = mTwoPi / nTracks;
198 double phi = mSectorAngleOffset + dphi * itr;
199 double eta = gRandom->Uniform(-1.5, 1.5);
200
201 double theta = 2 * std::atan(1. / exp(eta));
202 double lambda = theta - M_PI / 2;
203 // double theta = gRandom->Uniform(-60,60)*M_PI/180.;
204 double pt = .08 * std::pow(10, gRandom->Uniform(0, 2.2));
205
206 double q = 1.;
207 int32_t iSector = GetSector(phi);
208 phi = phi - GetSectorAngle(iSector);
209
210 // std::cout<<"phi = "<<phi<<std::endl;
211 double x0 = cosf(phi);
212 double y0 = sinf(phi);
213 double z0 = tanf(lambda);
214 t.Set(x0, y0, z0, pt * x0, pt * y0, pt * z0, q);
215
216 if (RecalculateSector(t, iSector) != 0) {
217 std::cout << "Initial sector wrong!!!" << std::endl;
218 // exit(0);
219 }
220
221 for (uint32_t iRow = 0; iRow < GPUTPCGeometry::NROWS; iRow++) {
222 // if( iRow>=50 ) break; //SG!!!
223 float xRow = GPUTPCGeometry::Row2X(iRow);
224 // transport to row
225 int32_t err = 0;
226 for (int32_t itry = 0; itry < 1; itry++) {
227 float B[3];
228 prop.GetBxByBz(GetSectorAngle(iSector), t.GetX(), t.GetY(), t.GetZ(), B);
229 float dLp = 0;
230 err = t.PropagateToXBxByBz(xRow, B[0], B[1], B[2], dLp);
231 if (err) {
232 std::cout << "Can not propagate to x = " << xRow << std::endl;
233 t.Print();
234 break;
235 }
236 if (fabsf(t.GetZ()) >= GPUTPCGeometry::TPCLength()) {
237 std::cout << "Can not propagate to x = " << xRow << ": Z outside the volume" << std::endl;
238 t.Print();
239 err = -1;
240 break;
241 }
242 // rotate track coordinate system to current sector
243 int32_t isNewSector = RecalculateSector(t, iSector);
244 if (!isNewSector) {
245 break;
246 } else {
247 std::cout << "track " << itr << ": new sector " << iSector << " at row " << iRow << std::endl;
248 }
249 }
250 if (err) {
251 break;
252 }
253 // std::cout<<" track "<<itr<<": Sector "<<iSector<<" row "<<iRow<<" params :"<<std::endl;
254 // t.Print();
255 // track at row iRow, sector iSector
256 if (iRow == 0) { // store MC track at first row
257 // std::cout<<std::setprecision( 20 );
258 // std::cout<<"track "<<itr<<": x "<<t.X()<<" y "<<t.Y()<<" z "<<t.Z()<<std::endl;
259 GPUTPCGMPhysicalTrackModel tg(t); // global coordinates
260 tg.Rotate(-GetSectorAngle(iSector));
261
262 mcInfo[itr].pid = 2; // pion
263 mcInfo[itr].charge = 3 * q;
264 mcInfo[itr].x = tg.GetX(); // Position of MC track at entry of TPC / first hit in the TPC
265 mcInfo[itr].y = tg.GetY();
266 mcInfo[itr].z = tg.GetZ();
267 mcInfo[itr].pX = tg.GetPx(); // Momentum of MC track at that position
268 mcInfo[itr].pY = tg.GetPy();
269 mcInfo[itr].pZ = tg.GetPz();
270 // std::cout<<" mc Z = "<<tg.GetZ()<<std::endl;
271 }
272
273 // create cluster
274 GenCluster c;
275 float sigmaY = 0.3;
276 float sigmaZ = 0.5;
277 const int32_t rowType = iRow < 64 ? 0 : iRow < 128 ? 2 : 1;
278 t.UpdateValues();
279 param.GetClusterErrors2(iSector, rowType, t.GetZ(), t.GetSinPhi(), t.GetDzDs(), -1.f, 0.f, 0.f, sigmaY, sigmaZ);
280 sigmaY = std::sqrt(sigmaY);
281 sigmaZ = std::sqrt(sigmaZ);
282 mClusterError[rowType][0]->Fill(sigmaY);
283 mClusterError[rowType][1]->Fill(sigmaZ);
284 // std::cout<<sigmaY<<" "<<sigmaY<<std::endl;
285 // if( sigmaY > 0.5 ) sigmaY = 0.5;
286 // if( sigmaZ > 0.5 ) sigmaZ = 0.5;
287 c.sector = (t.GetZ() >= 0.) ? iSector : iSector + 18;
288 c.row = iRow;
289 c.mcID = itr;
290 c.x = t.GetX();
291 c.y = t.GetY() + GetGaus(sigmaY);
292 c.z = t.GetZ() + GetGaus(sigmaZ);
293 c.id = clusterId++;
294 vClusters.push_back(c);
295 } // iRow
296 } // itr
297
298 std::vector<AliHLTTPCClusterMCLabel> labels;
299
300 std::unique_ptr<GPUTPCClusterData> clSectors[GPUChainTracking::NSECTORS];
301
302 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.
303 {
304 int32_t nNumberOfHits = 0;
305 for (uint32_t i = 0; i < vClusters.size(); i++) {
306 if (vClusters[i].sector == iSector) {
307 nNumberOfHits++;
308 }
309 }
310 // For every sector we first have to fill the number of hits in this sector to the file
311 mRec->mIOPtrs.nClusterData[iSector] = nNumberOfHits;
312
313 GPUTPCClusterData* clusters = new GPUTPCClusterData[nNumberOfHits];
314 clSectors[iSector].reset(clusters);
315 int32_t icl = 0;
316 for (uint32_t i = 0; i < vClusters.size(); i++) {
317 GenCluster& c = vClusters[i];
318 if (c.sector == iSector) {
319 clusters[icl].id = c.id;
320 clusters[icl].row = c.row; // We fill one hit per TPC row
321 clusters[icl].x = c.x;
322 clusters[icl].y = c.y;
323 clusters[icl].z = c.z;
324 clusters[icl].amp = 100; // Arbitrary amplitude
325 icl++;
326 AliHLTTPCClusterMCLabel clusterLabel;
327 for (int32_t j = 0; j < 3; j++) {
328 clusterLabel.fClusterID[j].fMCID = -1;
329 clusterLabel.fClusterID[j].fWeight = 0;
330 }
331 clusterLabel.fClusterID[0].fMCID = c.mcID;
332 clusterLabel.fClusterID[0].fWeight = 1;
333 labels.push_back(clusterLabel);
334 }
335 }
336 mRec->mIOPtrs.clusterData[iSector] = clusters;
337 }
338
339 // 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.
340
341 mRec->mIOPtrs.nMCLabelsTPC = labels.size();
342 mRec->mIOPtrs.mcLabelsTPC = labels.data();
343
344 mRec->mIOPtrs.nMCInfosTPC = mcInfo.size();
345 mRec->mIOPtrs.mcInfosTPC = mcInfo.data();
346 static const GPUTPCMCInfoCol mcColInfo = {0, (uint32_t)mcInfo.size()};
347 mRec->mIOPtrs.mcInfosTPCCol = &mcColInfo;
348 mRec->mIOPtrs.nMCInfosTPCCol = 1;
349
350 mRec->DumpData(filename);
351 labels.clear();
352 mcInfo.clear();
353 return (0);
354}
355
356void genEvents::RunEventGenerator(GPUChainTracking* rec, const std::string& dir)
357{
358 std::unique_ptr<genEvents> gen(new genEvents(rec));
359 mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
360 rec->DumpSettings(dir.c_str());
361
362 gen->InitEventGenerator();
363
364 for (int32_t i = 0; i < (configStandalone.nEvents == -1 ? 10 : configStandalone.nEvents); i++) {
365 GPUInfo("Generating event %d/%d", i, configStandalone.nEvents == -1 ? 10 : configStandalone.nEvents);
366 gen->GenerateEvent(rec->GetParam(), (dir + GPUCA_EVDUMP_FILE "." + std::to_string(i) + ".dump").c_str());
367 }
368 gen->FinishEventGenerator();
369}
std::vector< std::string > labels
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:37
uint32_t iSector
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
const GPUParam & GetParam() const
void DumpSettings(const char *dir="")
float const GPUParam float float float float float int32_t int16_t uint8_t float float float charge
static constexpr uint32_t NROWS
void InitEventGenerator()
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:47
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
std::string filename()
GPUReconstruction * rec
AliHLTTPCClusterMCWeight fClusterID[3]
const int nEvents
Definition test_Fifo.cxx:27
std::vector< Cluster > clusters