CbmRoot
Loading...
Searching...
No Matches
CbmSimTracksConverter.cxx
Go to the documentation of this file.
1/* Copyright (C) 2020-2021 Physikalisches Institut, Eberhard Karls Universitaet Tuebingen, Tuebingen
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Daniel Wielanek, Viktor Klochkov [committer] */
4
6
7#include "CbmDefs.h"
8#include "CbmEvent.h"
9#include "CbmMCDataArray.h"
10#include "CbmMCDataManager.h"
11#include "CbmMCTrack.h"
12
13#include "FairMCEventHeader.h"
14#include "FairRootManager.h"
15#include "Logger.h"
16
17#include <TClonesArray.h>
18#include <TDirectory.h>
19#include <TFile.h>
20#include <TRandom.h>
21#include <TString.h>
22#include <TTree.h>
23
24#include <cassert>
25#include <vector>
26
27#include "AnalysisTree/TaskManager.hpp"
28#include "UEvent.h"
29#include "UParticle.h"
30#include "URun.h"
31
33
35{
36 unigen_file_ = TFile::Open(unigen_file_name_.c_str(), "READ");
37 unigen_file_->Print();
38 if (unigen_file_->IsOpen()) {
39 unigen_tree_ = unigen_file_->Get<TTree>("events");
40 if (unigen_tree_) use_unigen_ = kTRUE;
41 unigen_tree_->SetBranchAddress("event", &unigen_event_);
42 URun* run = unigen_file_->Get<URun>("run");
43 if (run == nullptr) {
44 LOG(error) << "CbmSimTracksConverter: No run description in urqmd file!";
45 delete unigen_file_;
46 unigen_file_ = nullptr;
47 use_unigen_ = kFALSE;
48 }
49 else {
50 Double_t mProt = 0.938272;
51 Double_t pTarg = run->GetPTarg(); // target momentum per nucleon
52 Double_t pProj = run->GetPProj(); // projectile momentum per nucleon
53 Double_t eTarg = TMath::Sqrt(pProj * pProj + mProt * mProt);
54 beta_cm_ = pTarg / eTarg;
55 }
56 }
57}
58
60{
61 assert(!out_branch_.empty());
62 auto* ioman = FairRootManager::Instance();
63 // cbm_mc_tracks_ = (TClonesArray*) ioman->GetObject("MCTrack");
64 cbm_header_ = (FairMCEventHeader*) ioman->GetObject("MCEventHeader.");
65
66 cbm_mc_manager_ = dynamic_cast<CbmMCDataManager*>(ioman->GetObject("MCDataManager"));
68
69 AnalysisTree::BranchConfig sim_particles_branch(out_branch_, AnalysisTree::DetType::kParticle);
70 sim_particles_branch.AddField<int>("mother_id", "id of mother particle, -1 for primaries");
71 sim_particles_branch.AddField<int>("cbmroot_id", "track id in CbmRoot transport file");
72 sim_particles_branch.AddField<int>("geant_process_id", "");
73 sim_particles_branch.AddFields<int>({"n_hits_mvd", "n_hits_sts", "n_hits_trd"}, "Number of hits in the detector");
74
75 if (!unigen_file_name_.empty()) { InitUnigen(); }
76 else {
77 LOG(info) << "lack of unigen file" << unigen_file_name_;
78 }
79
80 sim_particles_branch.AddFields<float>({"start_x", "start_y", "start_z"}, "Start position, cm");
81 sim_particles_branch.AddField<float>("start_t", "t freezout coordinate fm/c");
82
83 imother_id_ = sim_particles_branch.GetFieldId("mother_id");
84 igeant_id_ = sim_particles_branch.GetFieldId("geant_process_id");
85 in_hits_ = sim_particles_branch.GetFieldId("n_hits_mvd");
86 icbm_id_ = sim_particles_branch.GetFieldId("cbmroot_id");
87 istart_x_ = sim_particles_branch.GetFieldId("start_x");
88
89 auto* man = AnalysisTree::TaskManager::GetInstance();
90 man->AddBranch(sim_tracks_, sim_particles_branch);
91}
92
94{
95 assert(cbm_mc_tracks_new_);
96 out_indexes_map_.clear();
97
98 float delta_phi {0.f};
99 if (use_unigen_) {
100 unigen_tree_->GetEntry(entry_++);
101 const Double_t unigen_phi = unigen_event_->GetPhi();
102 const Double_t mc_phi = cbm_header_->GetRotZ();
103 delta_phi = mc_phi - unigen_phi;
104 }
105
106 sim_tracks_->ClearChannels();
107 auto* out_config_ = AnalysisTree::TaskManager::GetInstance()->GetConfig();
108 const auto& branch = out_config_->GetBranchConfig(out_branch_);
109
110 int file_id {0}, event_id {0};
111 if (event && event->GetMatch() && event->GetMatch()->GetNofLinks() > 0) {
112 file_id = event->GetMatch()->GetMatchedLink().GetFile();
113 event_id = event->GetMatch()->GetMatchedLink().GetEntry();
114 }
115 else {
116 event_id = FairRootManager::Instance()->GetEntryNr();
117 }
118
119 LOG(info) << "Writing MC-tracks from event # " << event_id << " file " << file_id;
120
121 const int nMcTracks = cbm_mc_tracks_new_->Size(file_id, event_id);
122
123 if (nMcTracks <= 0) {
124 LOG(warn) << "No MC tracks!";
125 return;
126 }
127
128 sim_tracks_->Reserve(nMcTracks);
129
130 const Double_t nsTofmc = 1. / (0.3356 * 1E-15);
131
132 for (int iMcTrack = 0; iMcTrack < nMcTracks; ++iMcTrack) {
133 const auto trackIndex = iMcTrack; //event ? event->GetIndex(ECbmDataType::kMCTrack, iMcTrack) : iMcTrack;
134 const auto* mctrack = (CbmMCTrack*) cbm_mc_tracks_new_->Get(file_id, event_id, trackIndex);
135 if (mctrack->GetPdgCode() == 50000050) { //Cherenkov
136 continue;
137 }
138 auto& track = sim_tracks_->AddChannel(branch);
139
140 out_indexes_map_.insert(std::make_pair(trackIndex, track.GetId()));
141
142 track.SetMomentum(mctrack->GetPx(), mctrack->GetPy(), mctrack->GetPz());
143 track.SetMass(float(mctrack->GetMass()));
144 track.SetPid(int(mctrack->GetPdgCode()));
145 track.SetField(int(mctrack->GetGeantProcessId()), igeant_id_);
146 track.SetField(int(mctrack->GetNPoints(ECbmModuleId::kMvd)), in_hits_);
147 track.SetField(int(mctrack->GetNPoints(ECbmModuleId::kSts)), in_hits_ + 1);
148 track.SetField(int(mctrack->GetNPoints(ECbmModuleId::kTrd)), in_hits_ + 2);
149 track.SetField(int(mctrack->GetUniqueID()), icbm_id_);
150
151 if (mctrack->GetMotherId() >= 0) { // secondary
152 track.SetField(float(mctrack->GetStartX() - cbm_header_->GetX()), istart_x_);
153 track.SetField(float(mctrack->GetStartY() - cbm_header_->GetY()), istart_x_ + 1);
154 track.SetField(float(mctrack->GetStartZ() - cbm_header_->GetZ()), istart_x_ + 2);
155 track.SetField(float(nsTofmc * (mctrack->GetStartT() - cbm_header_->GetT())), istart_x_ + 3);
156 }
157 else { // primary
158 if (use_unigen_ && trackIndex < unigen_event_->GetNpa()) {
159 UParticle* p = unigen_event_->GetParticle(trackIndex);
160 TLorentzVector boostedX = p->GetPosition();
161 boostedX.Boost(0, 0, -beta_cm_);
162 boostedX.RotateZ(delta_phi);
163 track.SetField(float(boostedX.X() * 1e-13), istart_x_);
164 track.SetField(float(boostedX.Y() * 1e-13), istart_x_ + 1);
165 track.SetField(float(boostedX.Z() * 1e-13), istart_x_ + 2);
166 track.SetField(float(boostedX.T()), istart_x_ + 3);
167 }
168 else {
169 track.SetField(0.f, istart_x_);
170 track.SetField(0.f, istart_x_ + 1);
171 track.SetField(0.f, istart_x_ + 2);
172 track.SetField(0.f, istart_x_ + 3);
173 }
174 }
175
176 // mother id should < than track id, so we can do it here
177 if (mctrack->GetMotherId() == -1) { track.SetField(int(-1), imother_id_); }
178 else {
179 auto p = out_indexes_map_.find(mctrack->GetMotherId());
180 if (p == out_indexes_map_.end()) // match is not found
181 track.SetField(int(-999), imother_id_);
182 else {
183 track.SetField(int(p->second), imother_id_);
184 }
185 }
186 }
187}
@ kMvd
Micro-Vertex Detector.
@ kTrd
Transition Radiation Detector.
@ kSts
Silicon Tracking System.
ClassImp(CbmSimTracksConverter)
MapType out_indexes_map_
CbmRoot to AnalysisTree indexes map for output branch.
std::string out_branch_
Class characterising one event by a collection of links (indices) to data objects,...
Definition CbmEvent.h:34
CbmMatch * GetMatch() const
Definition CbmEvent.h:98
TObject * Get(const CbmLink *lnk)
Int_t Size(Int_t fileNumber, Int_t eventNumber)
Task class creating and managing CbmMCDataArray objects.
CbmMCDataArray * InitBranch(const char *name)
int32_t GetNofLinks() const
Definition CbmMatch.h:42
void ProcessData(CbmEvent *event) final
AnalysisTree::Particles * sim_tracks_
CbmMCDataManager * cbm_mc_manager_
FairMCEventHeader * cbm_header_
CbmMCDataArray * cbm_mc_tracks_new_
Double_t beta_cm_
CM velocity in the lab frame.
Double_t GetPhi() const
Definition UEvent.h:38
UParticle * GetParticle(Int_t index) const
Definition UEvent.cxx:101
TLorentzVector GetPosition() const
Definition UParticle.h:68
Definition URun.h:12
Double_t GetPTarg() const
Definition URun.h:49
Double_t GetPProj() const
Definition URun.h:46