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);
196 eventTime+=eventSpacing;
204 //________________________________________________________________
205 void AliToyMCEventGeneratorSimple::RunSimulationLaser(const Int_t nevents/*=1*/)
208 // run simple simulation with equal event spacing
211 if (!ConnectOutputFile()) return;
212 //initialise the space charge. Should be done after the tree was set up
215 // within one simulation the track count should be unique for effeciency studies
218 Double_t eventTime=0.;
219 const Double_t eventSpacing=1./10.; //laser is running at 10Hz equally spaced
221 for (Int_t ievent=0; ievent<nevents; ++ievent){
222 printf("Generating event %3d (%.3g)\n",ievent,eventTime);
223 fEvent = GenerateLaser(eventTime);
227 eventTime+=eventSpacing;
235 //________________________________________________________________
236 AliToyMCEvent* AliToyMCEventGeneratorSimple::GenerateESD(AliESDEvent &esdEvent, Double_t time) {
239 AliToyMCEvent *retEvent = new AliToyMCEvent();
240 retEvent->SetT0(time);
241 retEvent->SetX(esdEvent.GetPrimaryVertex()->GetX());
242 retEvent->SetY(esdEvent.GetPrimaryVertex()->GetY());
243 retEvent->SetZ(esdEvent.GetPrimaryVertex()->GetZ());
247 if(!fNtracks) fNtracks = esdEvent.GetNumberOfTracks();
248 Int_t nUsedTracks = 0;
249 for(Int_t iTrack=0; iTrack<esdEvent.GetNumberOfTracks(); iTrack++){
251 AliESDtrack *part = esdEvent.GetTrack(iTrack);
253 if (!fESDCuts->AcceptTrack(/*(AliESDtrack*)*/part))continue;
254 if(part->Pt() < 0.3) continue; //avoid tracks that fail to propagate through entire volume
259 Double_t vertex[3]={retEvent->GetX(),retEvent->GetY(),retEvent->GetZ()};
262 Int_t sign = part->Charge();
263 AliToyMCTrack *tempTrack = retEvent->AddTrack(vertex,pxyz,cv,sign);
264 // use unique ID for track number
265 // this will be used in DistortTrack track to set the cluster label
266 // in one simulation the track id should be unique for performance studies
267 tempTrack->SetUniqueID(fCurrentTrack++);
268 DistortTrack(*tempTrack, time);
271 if(nUsedTracks >= fNtracks) break;
276 //________________________________________________________________
277 void AliToyMCEventGeneratorSimple::RunSimulationESD(const Int_t nevents/*=10*/, const Int_t ntracks/*=400*/)
280 // run simulation using esd input with equal event spacing
283 if (!ConnectOutputFile()) return;
284 TFile f(Form("%s%s",fInputFileNameESD.Data(),"#AliESDs.root"));
286 std::cout << "file "<<fInputFileNameESD.Data() <<" could not be opened" << std::endl;
289 TTree* esdTree = (TTree*) f.Get("esdTree");
291 std::cout <<"no esdTree in file " << std::endl;
295 AliESDEvent* esdEvent = new AliESDEvent();
298 esdEvent->ReadFromTree(esdTree);
301 // within one simulation the track count should be unique for effeciency studies
304 Double_t eventTime=0.;
305 const Double_t eventSpacing=1./50e3; //50kHz equally spaced
308 fESDCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE,1);
310 Int_t nUsedEvents = 0;
311 for (Int_t ievent=0; ievent<esdTree->GetEntries(); ++ievent){
312 printf("Generating event %3d (%.3g)\n",nUsedEvents,eventTime);
313 esdTree->GetEvent(ievent);
314 if(esdEvent->GetNumberOfTracks()==0) {
315 std::cout << " tracks == 0" << std::endl;
319 fEvent = GenerateESD(*esdEvent, eventTime);
320 if(fEvent->GetNumberOfTracks() >=10) {
323 eventTime+=eventSpacing;
328 if(nUsedEvents>=nevents) break;
336 //________________________________________________________________
337 void AliToyMCEventGeneratorSimple::RunSimulationBunchTrain(const Int_t nevents/*=10*/, const Int_t ntracks/*=400*/)
340 // run simple simulation with equal event spacing
343 //Parameters for bunc
344 const Double_t abortGap = 3e-6; //
345 const Double_t collFreq = 50e3;
346 const Double_t bSpacing = 50e-9; //bunch spacing
347 const Int_t nTrainBunches = 48;
348 const Int_t nTrains = 12;
349 const Double_t revFreq = 1.11e4; //revolution frequency
350 const Double_t collProb = collFreq/(nTrainBunches*nTrains*revFreq);
351 const Double_t trainLength = bSpacing*(nTrainBunches-1);
352 const Double_t totTrainLength = nTrains*trainLength;
353 const Double_t trainSpacing = (1./revFreq - abortGap - totTrainLength)/(nTrains-1);
354 Bool_t equalSpacing = kFALSE;
356 TRandom3 *rand = new TRandom3();
359 if (!ConnectOutputFile()) return;
360 //initialise the space charge. Should be done after the tree was set up
364 // within one simulation the track count should be unique for effeciency studies
367 Double_t eventTime=0.;
368 // const Double_t eventSpacing=1./50e3; //50kHz equally spaced
370 Int_t nGeneratedEvents = 0;
371 Int_t bunchCounter = 0;
372 Int_t trainCounter = 0;
374 //for (Int_t ievent=0; ievent<nevents; ++ievent){
375 while (nGeneratedEvents<nevents){
376 // std::cout <<trainCounter << " " << bunchCounter << " "<< "eventTime " << eventTime << std::endl;
379 printf("Generating event %3d (%.3g)\n",nGeneratedEvents,eventTime);
380 fEvent = Generate(eventTime);
385 eventTime+=1./collFreq;
388 Int_t nCollsInCrossing = rand -> Poisson(collProb);
389 for(Int_t iColl = 0; iColl<nCollsInCrossing; iColl++){
390 printf("Generating event %3d (%.3g)\n",nGeneratedEvents,eventTime);
391 fEvent = Generate(eventTime);
400 if(bunchCounter>=nTrainBunches){
403 if(trainCounter>=nTrains){
407 else eventTime+=trainSpacing;
411 else eventTime+= bSpacing;
427 //________________________________________________________________
428 Int_t AliToyMCEventGeneratorSimple::OpenInputAndGetMaxEvents(const Int_t type, const Int_t nevents) {
432 if(type==0) return nevents;
436 fInputFile = new TFile(Form("%s%s",fInputFileNameESD.Data(),"#AliESDs.root"),"read");
437 if(!fInputFile->IsOpen()) {
438 std::cout << "file "<<fInputFileNameESD.Data() <<" could not be opened" << std::endl;
441 fESDTree = (TTree*) fInputFile->Get("esdTree");
443 std::cout <<"no esdTree in file " << std::endl;
446 fESDEvent = new AliESDEvent();
447 fESDEvent->ReadFromTree(fESDTree);
448 fESDCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE,1);
453 return fESDTree->GetEntries();
457 std::cout << " no available input type (toymc, esd) specified" << std::endl;
464 //________________________________________________________________
465 void AliToyMCEventGeneratorSimple::RunSimulation2(const Bool_t equalspacing, const Int_t type, const Int_t nevents, const Int_t ntracks) {
470 Int_t nMaxEvents = OpenInputAndGetMaxEvents(type,nevents);
471 if (!ConnectOutputFile()) return;
477 // within one simulation the track count should be unique for effeciency studies
480 Double_t eventTime=0.;
482 // const Double_t eventSpacing=1./50e3; //50kHz equally spaced
484 Int_t nGeneratedEvents = 0;
486 for (Int_t ievent=0; ievent<nMaxEvents; ++ievent){
487 printf("Generating event %3d (%.3g)\n",ievent,eventTime);
490 Double_t spacing = 0;
491 GetNGeneratedEventsAndSpacing(equalspacing, nColls, spacing);
493 for(Int_t iColl = 0; iColl<nColls; iColl++){
494 if(type==0) fEvent = Generate(eventTime);
495 else if(type==1) fEvent = GenerateESD2(eventTime);
504 if(nGeneratedEvents >= nevents) break;
514 //________________________________________________________________
515 AliToyMCEvent* AliToyMCEventGeneratorSimple::GenerateESD2(Double_t time) {
517 //test that enough tracks will pass cuts (and that there is tracks at all)
518 Bool_t testEvent = kTRUE;
520 // iterate over space charge maps in case they are set
522 while(fESDTree->GetEvent(fInputIndex) && testEvent) {
524 Int_t nPassedCuts = 0;
525 for(Int_t iTrack = 0; iTrack<fESDEvent->GetNumberOfTracks(); iTrack++){
526 if(fESDCuts->AcceptTrack(fESDEvent->GetTrack(iTrack)) && (fESDEvent->GetTrack(iTrack)->Pt() < 0.3) ) nPassedCuts++;
528 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?
529 else testEvent = kFALSE;
532 if(fInputIndex>=fESDTree->GetEntries()) return 0;
536 AliToyMCEvent *retEvent = new AliToyMCEvent();
537 retEvent->SetT0(time);
538 retEvent->SetX(fESDEvent->GetPrimaryVertex()->GetX());
539 retEvent->SetY(fESDEvent->GetPrimaryVertex()->GetY());
540 retEvent->SetZ(fESDEvent->GetPrimaryVertex()->GetZ());
544 if(!fNtracks) fNtracks = fESDEvent->GetNumberOfTracks();
545 Int_t nUsedTracks = 0;
546 for(Int_t iTrack=0; iTrack<fESDEvent->GetNumberOfTracks(); iTrack++){
548 AliESDtrack *part = fESDEvent->GetTrack(iTrack);
550 if (!fESDCuts->AcceptTrack(/*(AliESDtrack*)*/part))continue;
551 if(part->Pt() < 0.3) continue; //avoid tracks that fail to propagate through entire volume
557 Double_t vertex[3]={retEvent->GetX(),retEvent->GetY(),retEvent->GetZ()};
559 Int_t sign = part->Charge();
561 AliToyMCTrack *tempTrack = retEvent->AddTrack(vertex,pxyz,cv,sign);
562 // use unique ID for track number
563 // this will be used in DistortTrack track to set the cluster label
564 // in one simulation the track id should be unique for performance studies
565 tempTrack->SetUniqueID(fCurrentTrack++);
566 DistortTrack(*tempTrack, time);
569 if(nUsedTracks >= fNtracks) break;
576 //________________________________________________________________
577 AliToyMCEvent* AliToyMCEventGeneratorSimple::GenerateLaser(Double_t time)
580 // Generate an Event with laser tracks
583 // iterate over space charge maps in case they are set
586 AliToyMCEvent *retEvent = new AliToyMCEvent();
587 retEvent->SetEventType(AliToyMCEvent::kLaser);
589 retEvent->SetT0(time);
594 AliTPCLaserTrack::LoadTracks();
595 TObjArray *arr=AliTPCLaserTrack::GetTracks();
597 //since we have a laser track force no material budges
598 Bool_t materialBudget=GetUseMaterialBudget();
599 SetUseMaterialBudget(kFALSE);
601 //the laser tracks have partially large inclination angles over the pads
602 // -> relax the propagation contraint and switch off error messages
604 Int_t debug=AliLog::GetDebugLevel("","AliToyMCEventGeneratorSimple");
605 AliLog::SetClassDebugLevel("AliToyMCEventGeneratorSimple",-3);
607 for (Int_t iTrack=0; iTrack<arr->GetEntriesFast(); ++iTrack){
608 AliExternalTrackParam *track=(AliExternalTrackParam*)arr->At(iTrack);
609 AliToyMCTrack *tempTrack = retEvent->AddTrack(AliToyMCTrack(*track));
610 // for laser only TPC clusters exist
611 tempTrack->SetUniqueID(fCurrentTrack++);
612 MakeTPCClusters(*tempTrack, time);
616 AliLog::SetClassDebugLevel("AliToyMCEventGeneratorSimple",debug);
617 SetUseMaterialBudget(materialBudget);
621 //________________________________________________________________
622 void AliToyMCEventGeneratorSimple::GetNGeneratedEventsAndSpacing(const Bool_t equalSpacing, Int_t &ngen, Double_t &spacing)
625 static Int_t bunchCounter = 0;
626 static Int_t trainCounter = 0;
630 spacing = 1./50e3; //50kHz equally spaced
633 else if(!equalSpacing) {
634 //parameters for bunch train
635 const Double_t abortGap = 3e-6; //
636 const Double_t collFreq = 50e3;
637 const Double_t bSpacing = 50e-9; //bunch spacing
638 const Int_t nTrainBunches = 48;
639 const Int_t nTrains = 12;
640 const Double_t revFreq = 1.11e4; //revolution frequency
641 const Double_t collProb = collFreq/(nTrainBunches*nTrains*revFreq);
642 const Double_t trainLength = bSpacing*(nTrainBunches-1);
643 const Double_t totTrainLength = nTrains*trainLength;
644 const Double_t trainSpacing = (1./revFreq - abortGap - totTrainLength)/(nTrains-1);
646 Int_t nCollsInCrossing = 0;
647 while(nCollsInCrossing ==0){
652 if(bunchCounter>=nTrainBunches){
655 if(trainCounter>=nTrains){
659 else time+=trainSpacing;
663 else time+= bSpacing;
666 nCollsInCrossing = gRandom -> Poisson(collProb);
667 //std::cout << " nCollsInCrossing " << nCollsInCrossing << std::endl;
669 ngen = nCollsInCrossing;
670 if(nCollsInCrossing > 1)std::cout << " nCollsInCrossing " << nCollsInCrossing << std::endl;
678 //________________________________________________________________
679 Bool_t AliToyMCEventGeneratorSimple::CloseInputFile()
682 // close the input file
684 if (!fInputFile) return kFALSE;