13 #include "FairLogger.h"
14 #include "FairRootManager.h"
17 #include "FairRuntimeDb.h"
25 #include <TClonesArray.h>
26 #include <TDatabasePDG.h>
32 #include <THnSparse.h>
36 #include <TParticle.h>
37 #include <TParticlePDG.h>
38 #include <TProfile3D.h>
42 #include <TVirtualMC.h>
56 : FairTask(
"Cbm Fast Simulation")
57 , fRand(new TRandom3(0))
58 , fdbPdg(TDatabasePDG::Instance()) {
62 for (Int_t idx = 0; idx <
fgkNParts; idx++) {
65 for (Int_t j = 0; j < 10; j++)
78 FairRootManager* fManager = FairRootManager::Instance();
95 FairRootManager::Instance()->Register(
107 for (Int_t idx = 0; idx <
fgkNParts; idx++) {
111 "Prepare efficiency map and projections for index %d and method %d",
118 for (Int_t j = 0; j <
fEFF[idx]->GetNdimensions(); j++) {
128 if (j < (
fEFF[idx]->GetNdimensions() - 1))
continue;
134 fEFFproj[idx][j]->SetName(Form(
"NOMidx%dj%d", idx, j));
136 TH1* den =
fEFFdenom[idx]->Projection(j,
"E");
137 den->SetName(Form(
"DENidx%dj%d", idx, j));
144 fEFFproj[idx][j]->GetMaximumBin()));
152 fEFFproj[idx][j]->SetName(Form(
"NOMidx%dj%d12", idx, j));
154 TH1* den =
fEFFdenom[idx]->Projection(j, 1, 2,
"E");
155 den->SetName(Form(
"DENidx%dj%d12", idx, j));
172 Info(
"Init",
"Momentum smearing map found for index %d", idx);
187 FairRun* run = FairRun::Instance();
188 if (!run) Fatal(
"SetParContainers",
"No analysis run");
190 FairRuntimeDb* db = run->GetRuntimeDb();
191 if (!db) Fatal(
"SetParContainers",
"No runtime database");
199 fRand->SetSeed(seed);
231 Double_t* vals =
new Double_t[4];
232 Int_t* coord =
new Int_t[4];
235 for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
239 int pdg = t->GetPdgCode();
243 if (!
fdbPdg->GetParticle(pdg))
continue;
244 if (TMath::Abs(
fdbPdg->GetParticle(pdg)->Charge()) < 3)
continue;
249 vals[1] = t->Theta();
250 vals[2] = TVector2::Phi_0_2pi(t->Phi());
255 if (TMath::Abs(pdg) == 11 && fStack->
GetParticle(t->GetMother(0))
256 && fStack->
GetParticle(t->GetMother(0))->GetPdgCode() == 22) {
264 TLorentzVector p4(t->Px(), t->Py(), t->Pz(), t->Energy());
276 new ((*fFastTracks)[iKeep]) TParticle(pdg,
299 Info(
"Exec",
"stack size: \t %d \n", fStack->
GetNtrack());
300 Info(
"Exec",
"kept tracks: \t %d \n", iKeep);
301 Info(
"Exec",
"kept converison tracks: \t %d \n", iConv);
310 switch (TMath::Abs(pdg)) {
323 Warning(
"PassEfficiencyFilter",
"No filter for pdg code %d", pdg);
331 Long_t bin =
fEFF[idx]->GetBin(vals, kFALSE);
338 fEFF[idx]->GetBinContent(bin, coord);
343 err =
fEFF[idx]->GetBinError(bin);
345 if (eff > 0. && err / eff >= 0.10) {
357 Double_t rndm =
fRand->Rndm();
372 switch (TMath::Abs(pdg)) {
378 default:
return kFALSE;
382 Double_t tP = p4->P();
383 Double_t tTheta = p4->Theta();
384 Double_t tPhi = TVector2::Phi_0_2pi(p4->Phi());
385 Double_t mass =
fdbPdg->GetParticle(pdg)->Mass();
389 Double_t sTheta = tTheta;
390 Double_t sPhi = tPhi;
393 Double_t sPx = sP * TMath::Sin(sTheta) * TMath::Cos(sPhi);
394 Double_t sPy = sP * TMath::Sin(sTheta) * TMath::Sin(sPhi);
395 Double_t sPz = sP * TMath::Cos(sTheta);
397 Double_t sPt = TMath::Sqrt(sPx * sPx + sPy * sPy);
398 Double_t eta = -TMath::Log(TMath::Tan(sTheta / 2));
402 p4->SetPtEtaPhiM(sPt, eta, sPhi, mass);
416 if (!map)
return refValue;
419 TAxis* xRec = map->GetXaxis();
420 TAxis* yGen = map->GetYaxis();
423 Int_t binGen = yGen->FindBin(refValue);
429 if (binGen < 1 || binGen > yGen->GetNbins()) {
430 return (
fRand->Gaus(refValue, refValue * 0.02));
434 Float_t* arrayh = map->GetArray();
435 Int_t offset = (yGen->GetNbins() + 2) * (binGen) + 1;
438 Float_t r1 =
fRand->Rndm();
440 TMath::BinarySearch(xRec->GetNbins() + 2, arrayh + offset - 1, r1);
442 Double_t smearedValue = xRec->GetBinLowEdge(binRec + 1);
443 if (r1 > arrayh[offset - 1 + binRec])
445 xRec->GetBinWidth(binRec + 1) * (r1 - arrayh[offset - 1 + binRec])
446 / (arrayh[offset - 1 + binRec + 1] - arrayh[offset - 1 + binRec]);
463 Fatal(
"SetLookupEfficiency",
"Either nominator or denominator is NULL ");
535 for (Int_t j = 10; j >= 0; j--) {
541 eff =
fEFFproj[idx][j]->GetBinContent(coord[j]);
553 for (Int_t c = 0; c < 3; c++) {
554 if (coord[c] == 0) coord[c] += 2;
555 if (coord[c] == 1) coord[c] += 1;
556 if (coord[c] ==
fEFF[idx]->GetAxis(c)->GetNbins()) coord[c] -= 2;
557 if (coord[c] ==
fEFF[idx]->GetAxis(c)->GetNbins() - 1)
560 eff =
fEFFproj[idx][j]->Interpolate(
561 fEFFproj[idx][j]->GetXaxis()->GetBinCenter(coord[0]),
562 fEFFproj[idx][j]->GetYaxis()->GetBinCenter(coord[1]),
563 fEFFproj[idx][j]->GetZaxis()->GetBinCenter(coord[2]));
565 eff =
fEFFproj[idx][j]->Interpolate(vals[0], vals[1], vals[2]);
586 Error(
"GetEfficiency",
"number of dimensions for idx:%d is zero!", idx);
591 return (meanEff / ndim);
600 TVector3* mom =
dynamic_cast<TVector3*
>(sel);
606 switch (TMath::Abs(pdg)) {
623 Warning(
"IsSelected",
"No filter for pdg code %d", pdg);
628 Double_t* vals =
new Double_t[3];
633 vals[1] = mom->Theta();
634 vals[2] = TVector2::Phi_0_2pi(mom->Phi());
637 Long_t bin =
fEFF[idx]->GetBin(vals, kFALSE);
643 if (bin > 0) eff =
fEFF[idx]->GetBinContent(bin);
644 Double_t rndm =
fRand->Rndm();