4 #include <TDatabasePDG.h>
7 #include <TStopwatch.h>
12 #include <AliESDtrackCuts.h>
13 #include <AliESDtrack.h>
14 #include <AliTPCLaserTrack.h>
16 #include "AliToyMCEvent.h"
18 #include "AliToyMCEventGeneratorSimple.h"
25 ClassImp(AliToyMCEventGeneratorSimple);
28 AliToyMCEventGeneratorSimple::AliToyMCEventGeneratorSimple()
29 :AliToyMCEventGenerator()
33 ,fInputFileNameESD("")
48 //________________________________________________________________
49 AliToyMCEventGeneratorSimple::AliToyMCEventGeneratorSimple(const AliToyMCEventGeneratorSimple &gen)
50 :AliToyMCEventGenerator(gen)
51 ,fVertexMean(gen.fVertexMean)
52 ,fVertexSigma(gen.fVertexSigma)
53 ,fNtracks(gen.fNtracks)
54 ,fInputFileNameESD(gen.fInputFileNameESD)
55 ,fESDCuts(gen.fESDCuts)
56 ,fInputIndex(gen.fInputIndex)
57 ,fESDEvent(gen.fESDEvent)
58 ,fESDTree(gen.fESDTree)
59 ,fInputFile(gen.fInputFile)
63 ,fHistosSet(gen.fHistosSet)
67 //________________________________________________________________
68 AliToyMCEventGeneratorSimple::~AliToyMCEventGeneratorSimple()
71 //________________________________________________________________
72 AliToyMCEventGeneratorSimple& AliToyMCEventGeneratorSimple::operator = (const AliToyMCEventGeneratorSimple &gen)
75 if (&gen == this) return *this;
76 new (this) AliToyMCEventGeneratorSimple(gen);
80 //________________________________________________________________
81 void AliToyMCEventGeneratorSimple::SetParametersToyGen(const Char_t* parfilename/*="files/params.root*/, Double_t vertexMean/*=0*/, Double_t vertexSigma/*=7.*/) {
82 fVertexMean = vertexMean;
83 fVertexSigma = vertexSigma;
84 // fParamFile = new TFile(parfilename, "read");
87 fHPt = (TH1F*) f.Get("hPt");
88 fHEta = (TH1F*) f.Get("hEta");
89 fHMult = (TH1I*) f.Get("hMult") ;
95 //________________________________________________________________
96 AliToyMCEvent* AliToyMCEventGeneratorSimple::Generate(Double_t time)
99 // Generate an event at 'time'
102 // iterate over space charge maps in case they are set
105 AliToyMCEvent *retEvent = new AliToyMCEvent();
106 retEvent->SetT0(time);
110 //limit vertex to +- 10cm
111 while ( TMath::Abs(vertexZ=gRandom->Gaus(fVertexMean,fVertexSigma))>10. );
112 retEvent->SetZ(vertexZ);
114 Double_t etaCuts=0.9;
115 Double_t mass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
116 static TF1 fpt("fpt",Form("x*(1+(sqrt(x*x+%f^2)-%f)/([0]*[1]))^(-[0])",mass,mass),0.3,100);
117 if (fpt.GetParameter(0)<1){
118 printf("Set Parameters\n");
119 fpt.SetParameters(7.24,0.120);
122 // Int_t nTracks = 400; //TODO: draw from experim dist
123 // Int_t nTracks = 20; //TODO: draw from experim dist
124 Int_t nTracksLocal = fNtracks;
126 nTracksLocal = fHMult->GetRandom();
127 if(nTracksLocal > fNtracks) nTracksLocal = fNtracks;
129 std::cout << "Generating " << nTracksLocal << " tracks " << std::endl;
131 for(Int_t iTrack=0; iTrack<nTracksLocal; iTrack++){
132 Double_t phi = gRandom->Uniform(0.0, 2*TMath::Pi());
136 if(fHistosSet) {//draw from histograms if set
137 eta = fHEta->GetRandom();
138 pt = fHPt->GetRandom();
141 eta = gRandom->Uniform(-etaCuts, etaCuts);
142 pt = fpt.GetRandom(); // momentum for f1
145 if(gRandom->Rndm() < 0.5){
151 Double_t theta = 2*TMath::ATan(TMath::Exp(-eta))-TMath::Pi()/2.;
153 pxyz[0]=pt*TMath::Cos(phi);
154 pxyz[1]=pt*TMath::Sin(phi);
155 pxyz[2]=pt*TMath::Tan(theta);
156 Double_t vertex[3]={0,0,retEvent->GetZ()};
158 AliToyMCTrack *tempTrack = retEvent->AddTrack(vertex,pxyz,cv,sign);
159 // use unique ID for track number
160 // this will be used in DistortTrack track to set the cluster label
161 // in one simulation the track id should be unique for performance studies
162 tempTrack->SetUniqueID(fCurrentTrack++);
163 DistortTrack(*tempTrack, time);
169 //________________________________________________________________
170 void AliToyMCEventGeneratorSimple::RunSimulation(const Int_t nevents/*=10*/, const Int_t ntracks/*=400*/, const Int_t rate/*=50*/)
173 // run simple simulation with equal event spacing
177 if (!ConnectOutputFile()) return;
178 //initialise the space charge. Should be done after the tree was set up
181 // number of tracks to simulate per interaction
183 // within one simulation the track count should be unique for effeciency studies
184 // don't use the track ID 0 since the label -0 is not different from 0
187 Double_t eventTime=0.;
188 const Double_t eventSpacing=1./rate/1e3; //50kHz equally spaced
190 for (Int_t ievent=0; ievent<nevents; ++ievent){
191 printf("Generating event %3d (%.3g)\n",ievent,eventTime);
192 fEvent = Generate(eventTime);
193 SetSCScalingFactor();
197 eventTime+=eventSpacing;
205 //________________________________________________________________
206 void AliToyMCEventGeneratorSimple::RunSimulationLaser(const Int_t nevents/*=1*/)
209 // run simple simulation with equal event spacing
212 if (!ConnectOutputFile()) return;
213 //initialise the space charge. Should be done after the tree was set up
216 // within one simulation the track count should be unique for effeciency studies
219 Double_t eventTime=0.;
220 const Double_t eventSpacing=1./10.; //laser is running at 10Hz equally spaced
222 for (Int_t ievent=0; ievent<nevents; ++ievent){
223 printf("Generating event %3d (%.3g)\n",ievent,eventTime);
224 fEvent = GenerateLaser(eventTime);
228 eventTime+=eventSpacing;
236 //________________________________________________________________
237 AliToyMCEvent* AliToyMCEventGeneratorSimple::GenerateESD(AliESDEvent &esdEvent, Double_t time) {
240 AliToyMCEvent *retEvent = new AliToyMCEvent();
241 retEvent->SetT0(time);
242 retEvent->SetX(esdEvent.GetPrimaryVertex()->GetX());
243 retEvent->SetY(esdEvent.GetPrimaryVertex()->GetY());
244 retEvent->SetZ(esdEvent.GetPrimaryVertex()->GetZ());
248 if(!fNtracks) fNtracks = esdEvent.GetNumberOfTracks();
249 Int_t nUsedTracks = 0;
250 for(Int_t iTrack=0; iTrack<esdEvent.GetNumberOfTracks(); iTrack++){
252 AliESDtrack *part = esdEvent.GetTrack(iTrack);
254 if (!fESDCuts->AcceptTrack(/*(AliESDtrack*)*/part))continue;
255 if(part->Pt() < 0.3) continue; //avoid tracks that fail to propagate through entire volume
260 Double_t vertex[3]={retEvent->GetX(),retEvent->GetY(),retEvent->GetZ()};
263 Int_t sign = part->Charge();
264 AliToyMCTrack *tempTrack = retEvent->AddTrack(vertex,pxyz,cv,sign);
265 // use unique ID for track number
266 // this will be used in DistortTrack track to set the cluster label
267 // in one simulation the track id should be unique for performance studies
268 tempTrack->SetUniqueID(fCurrentTrack++);
269 DistortTrack(*tempTrack, time);
272 if(nUsedTracks >= fNtracks) break;
277 //________________________________________________________________
278 void AliToyMCEventGeneratorSimple::RunSimulationESD(const Int_t nevents/*=10*/, const Int_t ntracks/*=400*/)
281 // run simulation using esd input with equal event spacing
284 if (!ConnectOutputFile()) return;
285 TFile f(Form("%s%s",fInputFileNameESD.Data(),"#AliESDs.root"));
287 std::cout << "file "<<fInputFileNameESD.Data() <<" could not be opened" << std::endl;
290 TTree* esdTree = (TTree*) f.Get("esdTree");
292 std::cout <<"no esdTree in file " << std::endl;
296 AliESDEvent* esdEvent = new AliESDEvent();
299 esdEvent->ReadFromTree(esdTree);
302 // within one simulation the track count should be unique for effeciency studies
305 Double_t eventTime=0.;
306 const Double_t eventSpacing=1./50e3; //50kHz equally spaced
309 fESDCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE,1);
311 Int_t nUsedEvents = 0;
312 for (Int_t ievent=0; ievent<esdTree->GetEntries(); ++ievent){
313 printf("Generating event %3d (%.3g)\n",nUsedEvents,eventTime);
314 esdTree->GetEvent(ievent);
315 if(esdEvent->GetNumberOfTracks()==0) {
316 std::cout << " tracks == 0" << std::endl;
320 fEvent = GenerateESD(*esdEvent, eventTime);
321 if(fEvent->GetNumberOfTracks() >=10) {
324 eventTime+=eventSpacing;
329 if(nUsedEvents>=nevents) break;
337 //________________________________________________________________
338 void AliToyMCEventGeneratorSimple::RunSimulationBunchTrain(const Int_t nevents/*=10*/, const Int_t ntracks/*=400*/)
341 // run simple simulation with equal event spacing
344 //Parameters for bunc
345 const Double_t abortGap = 3e-6; //
346 const Double_t collFreq = 50e3;
347 const Double_t bSpacing = 50e-9; //bunch spacing
348 const Int_t nTrainBunches = 48;
349 const Int_t nTrains = 12;
350 const Double_t revFreq = 1.11e4; //revolution frequency
351 const Double_t collProb = collFreq/(nTrainBunches*nTrains*revFreq);
352 const Double_t trainLength = bSpacing*(nTrainBunches-1);
353 const Double_t totTrainLength = nTrains*trainLength;
354 const Double_t trainSpacing = (1./revFreq - abortGap - totTrainLength)/(nTrains-1);
355 Bool_t equalSpacing = kFALSE;
357 TRandom3 *rand = new TRandom3();
360 if (!ConnectOutputFile()) return;
361 //initialise the space charge. Should be done after the tree was set up
365 // within one simulation the track count should be unique for effeciency studies
368 Double_t eventTime=0.;
369 // const Double_t eventSpacing=1./50e3; //50kHz equally spaced
371 Int_t nGeneratedEvents = 0;
372 Int_t bunchCounter = 0;
373 Int_t trainCounter = 0;
375 //for (Int_t ievent=0; ievent<nevents; ++ievent){
376 while (nGeneratedEvents<nevents){
377 // std::cout <<trainCounter << " " << bunchCounter << " "<< "eventTime " << eventTime << std::endl;
380 printf("Generating event %3d (%.3g)\n",nGeneratedEvents,eventTime);
381 fEvent = Generate(eventTime);
382 SetSCScalingFactor();
387 eventTime+=1./collFreq;
390 Int_t nCollsInCrossing = rand -> Poisson(collProb);
391 for(Int_t iColl = 0; iColl<nCollsInCrossing; iColl++){
392 printf("Generating event %3d (%.3g)\n",nGeneratedEvents,eventTime);
393 fEvent = Generate(eventTime);
394 SetSCScalingFactor();
403 if(bunchCounter>=nTrainBunches){
406 if(trainCounter>=nTrains){
410 else eventTime+=trainSpacing;
414 else eventTime+= bSpacing;
430 //________________________________________________________________
431 Int_t AliToyMCEventGeneratorSimple::OpenInputAndGetMaxEvents(const Int_t type, const Int_t nevents) {
435 if(type==0) return nevents;
439 fInputFile = new TFile(Form("%s%s",fInputFileNameESD.Data(),"#AliESDs.root"),"read");
440 if(!fInputFile->IsOpen()) {
441 std::cout << "file "<<fInputFileNameESD.Data() <<" could not be opened" << std::endl;
444 fESDTree = (TTree*) fInputFile->Get("esdTree");
446 std::cout <<"no esdTree in file " << std::endl;
449 fESDEvent = new AliESDEvent();
450 fESDEvent->ReadFromTree(fESDTree);
451 fESDCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE,1);
456 return fESDTree->GetEntries();
460 std::cout << " no available input type (toymc, esd) specified" << std::endl;
467 //________________________________________________________________
468 void AliToyMCEventGeneratorSimple::RunSimulation2(const Bool_t equalspacing, const Int_t type, const Int_t nevents, const Int_t ntracks) {
473 Int_t nMaxEvents = OpenInputAndGetMaxEvents(type,nevents);
474 if (!ConnectOutputFile()) return;
480 // within one simulation the track count should be unique for effeciency studies
483 Double_t eventTime=0.;
485 // const Double_t eventSpacing=1./50e3; //50kHz equally spaced
487 Int_t nGeneratedEvents = 0;
489 for (Int_t ievent=0; ievent<nMaxEvents; ++ievent){
490 printf("Generating event %3d (%.3g)\n",ievent,eventTime);
493 Double_t spacing = 0;
494 GetNGeneratedEventsAndSpacing(equalspacing, nColls, spacing);
496 for(Int_t iColl = 0; iColl<nColls; iColl++){
497 if(type==0) fEvent = Generate(eventTime);
498 else if(type==1) fEvent = GenerateESD2(eventTime);
507 if(nGeneratedEvents >= nevents) break;
517 //________________________________________________________________
518 AliToyMCEvent* AliToyMCEventGeneratorSimple::GenerateESD2(Double_t time) {
520 //test that enough tracks will pass cuts (and that there is tracks at all)
521 Bool_t testEvent = kTRUE;
523 // iterate over space charge maps in case they are set
525 while(fESDTree->GetEvent(fInputIndex) && testEvent) {
527 Int_t nPassedCuts = 0;
528 for(Int_t iTrack = 0; iTrack<fESDEvent->GetNumberOfTracks(); iTrack++){
529 if(fESDCuts->AcceptTrack(fESDEvent->GetTrack(iTrack)) && (fESDEvent->GetTrack(iTrack)->Pt() < 0.3) ) nPassedCuts++;
531 if(nPassedCuts<fNtracks || (fNtracks>100 && nPassedCuts <100) ) fInputIndex++; //100 is a perhaps bit arbitrary, do we want the events were only a small number of tracks are accepted?
532 else testEvent = kFALSE;
535 if(fInputIndex>=fESDTree->GetEntries()) return 0;
539 AliToyMCEvent *retEvent = new AliToyMCEvent();
540 retEvent->SetT0(time);
541 retEvent->SetX(fESDEvent->GetPrimaryVertex()->GetX());
542 retEvent->SetY(fESDEvent->GetPrimaryVertex()->GetY());
543 retEvent->SetZ(fESDEvent->GetPrimaryVertex()->GetZ());
547 if(!fNtracks) fNtracks = fESDEvent->GetNumberOfTracks();
548 Int_t nUsedTracks = 0;
549 for(Int_t iTrack=0; iTrack<fESDEvent->GetNumberOfTracks(); iTrack++){
551 AliESDtrack *part = fESDEvent->GetTrack(iTrack);
553 if (!fESDCuts->AcceptTrack(/*(AliESDtrack*)*/part))continue;
554 if(part->Pt() < 0.3) continue; //avoid tracks that fail to propagate through entire volume
560 Double_t vertex[3]={retEvent->GetX(),retEvent->GetY(),retEvent->GetZ()};
562 Int_t sign = part->Charge();
564 AliToyMCTrack *tempTrack = retEvent->AddTrack(vertex,pxyz,cv,sign);
565 // use unique ID for track number
566 // this will be used in DistortTrack track to set the cluster label
567 // in one simulation the track id should be unique for performance studies
568 tempTrack->SetUniqueID(fCurrentTrack++);
569 DistortTrack(*tempTrack, time);
572 if(nUsedTracks >= fNtracks) break;
579 //________________________________________________________________
580 AliToyMCEvent* AliToyMCEventGeneratorSimple::GenerateLaser(Double_t time)
583 // Generate an Event with laser tracks
586 // iterate over space charge maps in case they are set
589 AliToyMCEvent *retEvent = new AliToyMCEvent();
590 retEvent->SetEventType(AliToyMCEvent::kLaser);
592 retEvent->SetT0(time);
597 AliTPCLaserTrack::LoadTracks();
598 TObjArray *arr=AliTPCLaserTrack::GetTracks();
600 //since we have a laser track force no material budges
601 Bool_t materialBudget=GetUseMaterialBudget();
602 SetUseMaterialBudget(kFALSE);
604 //the laser tracks have partially large inclination angles over the pads
605 // -> relax the propagation contraint and switch off error messages
607 Int_t debug=AliLog::GetDebugLevel("","AliToyMCEventGeneratorSimple");
608 AliLog::SetClassDebugLevel("AliToyMCEventGeneratorSimple",-3);
610 for (Int_t iTrack=0; iTrack<arr->GetEntriesFast(); ++iTrack){
611 AliExternalTrackParam *track=(AliExternalTrackParam*)arr->At(iTrack);
612 AliToyMCTrack *tempTrack = retEvent->AddTrack(AliToyMCTrack(*track));
613 // for laser only TPC clusters exist
614 tempTrack->SetUniqueID(fCurrentTrack++);
615 MakeTPCClusters(*tempTrack, time);
619 AliLog::SetClassDebugLevel("AliToyMCEventGeneratorSimple",debug);
620 SetUseMaterialBudget(materialBudget);
624 //________________________________________________________________
625 void AliToyMCEventGeneratorSimple::GetNGeneratedEventsAndSpacing(const Bool_t equalSpacing, Int_t &ngen, Double_t &spacing)
628 static Int_t bunchCounter = 0;
629 static Int_t trainCounter = 0;
633 spacing = 1./50e3; //50kHz equally spaced
636 else if(!equalSpacing) {
637 //parameters for bunch train
638 const Double_t abortGap = 3e-6; //
639 const Double_t collFreq = 50e3;
640 const Double_t bSpacing = 50e-9; //bunch spacing
641 const Int_t nTrainBunches = 48;
642 const Int_t nTrains = 12;
643 const Double_t revFreq = 1.11e4; //revolution frequency
644 const Double_t collProb = collFreq/(nTrainBunches*nTrains*revFreq);
645 const Double_t trainLength = bSpacing*(nTrainBunches-1);
646 const Double_t totTrainLength = nTrains*trainLength;
647 const Double_t trainSpacing = (1./revFreq - abortGap - totTrainLength)/(nTrains-1);
649 Int_t nCollsInCrossing = 0;
650 while(nCollsInCrossing ==0){
655 if(bunchCounter>=nTrainBunches){
658 if(trainCounter>=nTrains){
662 else time+=trainSpacing;
666 else time+= bSpacing;
669 nCollsInCrossing = gRandom -> Poisson(collProb);
670 //std::cout << " nCollsInCrossing " << nCollsInCrossing << std::endl;
672 ngen = nCollsInCrossing;
673 if(nCollsInCrossing > 1)std::cout << " nCollsInCrossing " << nCollsInCrossing << std::endl;
681 //________________________________________________________________
682 Bool_t AliToyMCEventGeneratorSimple::CloseInputFile()
685 // close the input file
687 if (!fInputFile) return kFALSE;