CbmRoot
Loading...
Searching...
No Matches
CbmFsdHitsConverter.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: Viktor Klochkov [committer] */
4
6
7#include "AnalysisTree/Matching.hpp"
8#include "CbmDefs.h"
9#include "CbmDigiManager.h"
10#include "CbmEvent.h"
11#include "CbmFsdDigi.h"
12#include "CbmFsdHit.h"
13#include "CbmFsdPoint.h"
14#include "CbmGlobalTrack.h"
15#include "CbmKFTrack.h"
16#include "CbmMCDataArray.h"
17#include "CbmMCDataManager.h"
18#include "CbmMCTrack.h"
19#include "CbmStsTrack.h"
20#include "CbmTofHit.h"
21#include "CbmTrackMatchNew.h"
22#include "TClonesArray.h"
23
24#include <FairMCPoint.h>
25#include <FairRootManager.h>
26#include <Logger.h>
27
28#include <TGeoManager.h> // for TGeoManager, gGeoManager
29#include <TGeoMatrix.h> // for TGeoMatrix
30#include <TGeoNode.h> // for TGeoIterator, TGeoNode
31#include <TGeoShape.h> // for TGeoBBox etc.
32#include <TGeoVolume.h> // for TGeoVolume
33
34#include <AnalysisTree/TaskManager.hpp>
35#include <cassert>
36
38
40{
41 LOG(debug) << " THIS IS A TEST -> CbmFsdHitsConverter is being initialized LUKAS" << std::endl;
42
43 assert(!out_branch_.empty());
44 auto* ioman = FairRootManager::Instance();
45
46 cbm_fsd_hits_ = (TClonesArray*) ioman->GetObject("FsdHit");
47
48 cbm_global_tracks_ = (TClonesArray*) ioman->GetObject("GlobalTrack");
49 cbm_sts_tracks_ = (TClonesArray*) ioman->GetObject("StsTrack");
50 cbm_tof_hits_ = (TClonesArray*) ioman->GetObject("TofHit");
51 cbm_fsd_hitmatch_ = (TClonesArray*) ioman->GetObject("FsdHitMatch");
52 cbm_mc_tracks_ = (TClonesArray*) ioman->GetObject("MCTrack");
53
55 fDigiMan->Init();
56 if (!fDigiMan->IsMatchPresent(ECbmModuleId::kFsd)) {
57 LOG(error) << " No FsdDigiMatch input array present !!";
58 }
59 //cbm_fsd_digis_ = (TClonesArray*) ioman->GetObject("FsdDigi");
60 //cbm_fsd_digimatch_ = (TClonesArray*) ioman->GetObject("FsdDigiMatch");
61
62 cbm_mc_manager_ = dynamic_cast<CbmMCDataManager*>(ioman->GetObject("MCDataManager"));
63 //cbm_mc_tracks_new_ = cbm_mc_manager_->InitBranch("MCTrack");
64 cbm_fsd_points_new_ = cbm_mc_manager_->InitBranch("FsdPoint");
65
66 AnalysisTree::BranchConfig fsd_branch(out_branch_, AnalysisTree::DetType::kHit);
67
68 fsd_branch.AddField<float>("dEdx", "Energy deposition of given FSD hit [GeV]");
69 fsd_branch.AddField<float>("t", "Reconstructed time of given FSD hit [ps]");
70 fsd_branch.AddField<float>("mass2", "Calculated mass squared from extrapolated global track (by CbmKFTrack) to FSD "
71 "plane and FSD hit time [GeV^2/c^4]");
72 fsd_branch.AddField<float>("l", "Lenght of the extrapolated global track (by CbmKFTrack) to FSD plane [cm]");
73 fsd_branch.AddField<float>(
74 "qp", "charge * momentum of the extrapoleted global track (by CbmKFTrack) to FSD plane [GeV/c]");
75 fsd_branch.AddFields<float>(
76 {"dx", "dy", "dz"},
77 "Component of a 3D distance between FSD hit and extrapolated global track (by CbmKFTrack) [cm]");
78 fsd_branch.AddField<float>(
79 "chi2GtrackHit", "chi2 between extrapolated global track (by CbmKFTrack) to FSD plane (?FIXED Z?) and FSD hit");
80 fsd_branch.AddField<int>(
81 "bestMatchedGtrack2HitId",
82 "Index of best match between extrapolated global track (by CbmKFTrack) and FSD hit based on min chi2GtrackHit");
83 fsd_branch.AddField<int>("multMCtracks", "number of MC particles that cotributed by energy deposition to FSD hit");
84 fsd_branch.AddField<float>("maxWeightMCtrack",
85 "weight of matched link from Hit to Point (?highest energy deposition?)");
86 fsd_branch.AddField<float>("dtHitPoint", "Time difference between FSD hit and matched MC point [ps]");
87 fsd_branch.AddFields<float>({"dxHitPoint", "dyHitPoint", "dzHitPoint"},
88 "Component of a 3D distance between FSD hit and matched MC point [cm]");
89 fsd_branch.AddFields<float>({"xPoint", "yPoint", "zPoint"}, "MC point distribution [cm]");
90 fsd_branch.AddFields<float>({"pxPoint", "pyPoint", "pzPoint"}, "MC point momentum");
91 fsd_branch.AddField<float>({"phiPoint"}, "Angle of the point");
92 fsd_branch.AddField<float>({"lengthPoint"}, "Lenght of the point");
93 fsd_branch.AddField<float>({"tPoint"}, "Time of the point");
94 fsd_branch.AddField<float>({"elossPoint"}, "Energy loss of the point");
95 fsd_branch.AddField<float>({"dist_middle_x"}, "Absolute value of the hit distance x from zero");
96 fsd_branch.AddField<float>({"dist_middle_y"}, "Absolute value of the hit distance y from zero");
97
98
99 i_edep_ = fsd_branch.GetFieldId("dEdx");
100 i_t_ = fsd_branch.GetFieldId("t");
101 i_mass2_ = fsd_branch.GetFieldId("mass2");
102 i_qp_ = fsd_branch.GetFieldId("qp");
103 i_dx_ = fsd_branch.GetFieldId("dx");
104 i_l_ = fsd_branch.GetFieldId("l");
105 i_dtHP_ = fsd_branch.GetFieldId("dtHitPoint");
106 i_dxHP_ = fsd_branch.GetFieldId("dxHitPoint");
107 i_chi2_ = fsd_branch.GetFieldId("chi2GtrackHit");
108 i_bestMatchedGTrack_ = fsd_branch.GetFieldId("bestMatchedGtrack2HitId");
109 i_multMC_ = fsd_branch.GetFieldId("multMCtracks");
110 i_topW_ = fsd_branch.GetFieldId("maxWeightMCtrack");
111 i_xpoint_ = fsd_branch.GetFieldId("xPoint");
112 i_pxpoint_ = fsd_branch.GetFieldId("pxPoint");
113 i_phipoint_ = fsd_branch.GetFieldId("phiPoint");
114 i_lengthpoint_ = fsd_branch.GetFieldId("lengthPoint");
115 i_tpoint_ = fsd_branch.GetFieldId("tPoint");
116 i_eloss_ = fsd_branch.GetFieldId("elossPoint");
117 i_dist_middle_x_ = fsd_branch.GetFieldId("dist_middle_x");
118 i_dist_middle_y_ = fsd_branch.GetFieldId("dist_middle_y");
119
120
122 if (fsdgtrack_maxChi2_ == 0) fsdgtrack_maxChi2_ = 10000.;
123
124 auto* man = AnalysisTree::TaskManager::GetInstance();
125 man->AddBranch(fsd_hits_, fsd_branch);
126 man->AddMatching(match_to_, out_branch_, vtx_tracks_2_fsd_);
127 man->AddMatching(out_branch_, mc_tracks_, fsd_hits_2_mc_tracks_);
128}
129
130FairTrackParam CbmFsdHitsConverter::ExtrapolateGtrack(Double_t zpos, FairTrackParam params)
131{
132 // follow inspiration from CbmL1TofMerger
133 FairTrackParam returnParams;
134 CbmKFTrack kfTrack;
135 kfTrack.SetTrackParam(params);
136 kfTrack.Extrapolate(zpos); //this will do straight track extrapolation
137 kfTrack.GetTrackParam(returnParams);
138 return returnParams;
139}
140
141
142Double_t CbmFsdHitsConverter::Chi2FsdhitGtrack(CbmFsdHit* hit, FairTrackParam inputParams)
143{
144 FairTrackParam params = ExtrapolateGtrack(hit->GetZ(), inputParams);
145
146 Float_t dX = params.GetX() - hit->GetX();
147 Float_t dY = params.GetY() - hit->GetY();
148
149 Double_t cxx = params.GetCovariance(0, 0) + hit->GetDx() * hit->GetDx();
150 Double_t cxy = params.GetCovariance(0, 1) + hit->GetDxy() * hit->GetDxy();
151 Double_t cyy = params.GetCovariance(1, 1) + hit->GetDy() * hit->GetDy();
152 Double_t chi2 = 0.5 * (dX * dX * cxx - 2 * dX * dY * cxy + dY * dY * cyy) / (cxx * cyy - cxy * cxy);
153
154 return chi2;
155}
156
158{
159 assert(cbm_fsd_hits_);
160 fsd_hits_->ClearChannels();
161 vtx_tracks_2_fsd_->Clear();
162 fsd_hits_2_mc_tracks_->Clear();
163
164 auto* out_config_ = AnalysisTree::TaskManager::GetInstance()->GetConfig();
165 const auto& branch = out_config_->GetBranchConfig(out_branch_);
166
167 auto rec_tracks_map = GetMatchMap(match_to_);
168 auto sim_tracks_map = GetMatchMap(mc_tracks_);
169
170 int file_id{0}, event_id{0};
171 if (event) {
172 auto match = event->GetMatch();
173 if (!match) return;
174 file_id = event->GetMatch()->GetMatchedLink().GetFile();
175 event_id = event->GetMatch()->GetMatchedLink().GetEntry();
176 }
177 else {
178 event_id = FairRootManager::Instance()->GetEntryNr();
179 }
180
181 const int n_fsd_hits = event ? event->GetNofData(ECbmDataType::kFsdHit) : cbm_fsd_hits_->GetEntriesFast();
182 if (n_fsd_hits <= 0) {
183 LOG(warn) << "No FSD hits!";
184 return;
185 }
186
187 const int n_tracks = event ? event->GetNofData(ECbmDataType::kGlobalTrack) : cbm_global_tracks_->GetEntriesFast();
188 if (n_tracks <= 0) {
189 LOG(warn) << "No Global Tracks!";
190 return;
191 }
192
193 fsd_hits_->Reserve(n_fsd_hits);
194
195
196 // first loop over all FSD hits
197 for (Int_t ifh = 0; ifh < n_fsd_hits; ifh++) {
198 const auto fsdHI = event ? event->GetIndex(ECbmDataType::kFsdHit, ifh) : ifh;
199 auto* fsdHit = static_cast<CbmFsdHit*>(cbm_fsd_hits_->At(fsdHI));
200
201 auto& hit = fsd_hits_->AddChannel(branch);
202
203 const Float_t hitX = fsdHit->GetX();
204 const Float_t hitY = fsdHit->GetY();
205 const Float_t hitZ = fsdHit->GetZ();
206 const Float_t eLoss = fsdHit->GetEdep();
207 const Float_t time = fsdHit->GetTime();
208
209 const Float_t dist_x = std::fabs(fsdHit->GetX());
210 const Float_t dist_y = std::fabs(fsdHit->GetY());
211
212 hit.SetField(dist_x, i_dist_middle_x_);
213 hit.SetField(dist_y, i_dist_middle_y_);
214
215 hit.SetPosition(hitX, hitY, hitZ);
216 hit.SetSignal(time);
217 hit.SetField(eLoss, i_edep_);
218
219 Float_t phi_hit = atan2(fsdHit->GetY(), fsdHit->GetX());
220 if (phi_hit < 0) {
221 phi_hit = phi_hit + 2 * 3.1415;
222 }
223
224
225 Int_t multMC = 0;
226 Float_t highestWeight = 0.;
227 const auto* fsdHitMatch = dynamic_cast<CbmMatch*>(cbm_fsd_hitmatch_->At(fsdHI));
228 if (fsdHitMatch && fsdHitMatch->GetNofLinks() > 0) {
229 highestWeight = fsdHitMatch->GetMatchedLink().GetWeight();
230
231 for (int32_t ilDigi = 0; ilDigi < fsdHitMatch->GetNofLinks(); ilDigi++) {
232 const auto& digiLink = fsdHitMatch->GetLink(ilDigi);
233 if (digiLink.GetFile() != file_id || digiLink.GetEntry() != event_id) { // match from different event
234 continue;
235 }
236
237 const auto* fsdDigiMatch = fDigiMan->GetMatch(ECbmModuleId::kFsd, digiLink.GetIndex());
238 if (fsdDigiMatch && fsdDigiMatch->GetNofLinks() > 0) {
239 for (int32_t ilPoint = 0; ilPoint < fsdDigiMatch->GetNofLinks(); ilPoint++) {
240 const auto& pointLink = fsdDigiMatch->GetLink(ilPoint);
241 if (pointLink.GetFile() != file_id || pointLink.GetEntry() != event_id) { // match from different event
242 continue;
243 }
244
245 multMC++; // increase counter of MC multiplicity
246 // add matching between FSD hit and MC track
247 //const auto* fsdPoint = dynamic_cast<FairMCPoint*>(cbm_fsd_points_new_->Get(pointLink));
248 const auto* fsdPoint = dynamic_cast<FairMCPoint*>(cbm_fsd_points_new_->Get(digiLink));
249 Int_t mc_track_id = fsdPoint->GetTrackID();
250 if (mc_track_id >= 0) {
251 auto it = sim_tracks_map.find(mc_track_id);
252 if (it != sim_tracks_map.end()) { // match is found
253 fsd_hits_2_mc_tracks_->AddMatch(hit.GetId(), it->second);
254 }
255 }
256 // for the "matched" links store the difference between Hit and Point
259 //if(fsdPoint->GetLength() > 0.1){
260 hit.SetField(float(fsdPoint->GetTime() - time), i_dtHP_);
261 hit.SetField(float(fsdPoint->GetX() - hitX), i_dxHP_);
262 hit.SetField(float(fsdPoint->GetY() - hitY), i_dxHP_ + 1);
263 hit.SetField(float(fsdPoint->GetZ() - hitZ), i_dxHP_ + 2);
264 hit.SetField(float(fsdPoint->GetEnergyLoss()), i_eloss_);
265
266 hit.SetField(float(fsdPoint->GetX()), i_xpoint_);
267 hit.SetField(float(fsdPoint->GetY()), i_xpoint_ + 1);
268 hit.SetField(float(fsdPoint->GetZ()), i_xpoint_ + 2);
269 hit.SetField(float(fsdPoint->GetLength()), i_lengthpoint_);
270 hit.SetField(float(fsdPoint->GetPx()), i_pxpoint_);
271 hit.SetField(float(fsdPoint->GetPy()), i_pxpoint_ + 1);
272 hit.SetField(float(fsdPoint->GetPz()), i_pxpoint_ + 2);
273
274 Float_t phi_point = atan2(fsdPoint->GetY(), fsdPoint->GetX());
275 if (phi_point < 0) {
276 phi_point = phi_point + 2 * 3.1415;
277 }
278 hit.SetField(float(phi_point), i_phipoint_);
279 hit.SetField(float(fsdPoint->GetTime()), i_tpoint_);
281 //}
282
283 } // end of loop over links to points
284 }
285 } // end of loop over links to digis
286 } // end of sanity check of FSD hit matches
287
288 const Int_t hitMCmult = multMC;
289 const Float_t hitTopWeight = highestWeight;
290 hit.SetField(hitMCmult, i_multMC_);
291 hit.SetField(hitTopWeight, i_topW_);
292
293 // now matching with Global (reco) tracks
294 Int_t bestMatchedIndex = -1;
295 Double_t bestChi2 = 0.;
296 for (Int_t igt = 0; igt < n_tracks; igt++) {
297 const auto trackIndex = event ? event->GetIndex(ECbmDataType::kGlobalTrack, igt) : igt;
298 const auto* globalTrack = static_cast<const CbmGlobalTrack*>(cbm_global_tracks_->At(trackIndex));
299 FairTrackParam param_last = *(globalTrack->GetParamLast());
300
301 Double_t matchingChi2 = Chi2FsdhitGtrack(fsdHit, param_last);
302
303 if (bestChi2 > matchingChi2 || bestMatchedIndex < 0) {
304 bestChi2 = matchingChi2;
305 bestMatchedIndex = trackIndex;
306 }
307 } // end of loop over GlobalTracks
308
309 hit.SetField(static_cast<Float_t>(bestChi2), i_chi2_);
310 hit.SetField(static_cast<Int_t>(bestMatchedIndex), i_bestMatchedGTrack_);
311
312 if ((bestMatchedIndex >= 0) && (bestChi2 > fsdgtrack_minChi2_) && (bestChi2 < fsdgtrack_maxChi2_)) {
313 const auto* globalTrack = static_cast<const CbmGlobalTrack*>(cbm_global_tracks_->At(bestMatchedIndex));
314 FairTrackParam param_last = *(globalTrack->GetParamLast());
315 FairTrackParam param_fsd = ExtrapolateGtrack(hitZ, param_last);
316
317 TVector3 p_fsd;
318 param_fsd.Momentum(p_fsd);
319
320 const Float_t p = p_fsd.Mag();
321 const Int_t q = param_fsd.GetQp() > 0 ? 1 : -1;
322 const Float_t l = globalTrack->GetLength(); // l is calculated by global tracking
323 const Float_t beta = event ? l / ((time - event->GetTzero()) * 29.9792458) : 0;
324 const Float_t m2 = event ? p * p * (1. / (beta * beta) - 1.) : -1.;
325
326 hit.SetField(m2, i_mass2_);
327 hit.SetField(float(q * p), i_qp_);
328 hit.SetField(float(param_fsd.GetX() - hitX), i_dx_);
329 hit.SetField(float(param_fsd.GetY() - hitY), i_dx_ + 1);
330 hit.SetField(float(param_fsd.GetZ() - hitZ), i_dx_ + 2);
331 hit.SetField(l, i_l_);
332 hit.SetField(time, i_t_);
333
334 if (rec_tracks_map.empty()) {
335 continue;
336 }
337 const Int_t stsTrackIndex = globalTrack->GetStsTrackIndex();
338 if (rec_tracks_map.find(stsTrackIndex) != rec_tracks_map.end()) {
339 vtx_tracks_2_fsd_->AddMatch(rec_tracks_map.find(stsTrackIndex)->second, hit.GetId());
340 }
341 }
342 } // end of loop over FSD hits
343}
344
345
351
352// end of file
@ kFsd
Forward spectator detector.
Definition CbmDefs.h:59
ClassImp(CbmFsdHitsConverter)
Data class for STS tracks.
float Float_t
int Int_t
std::string match_to_
AT branch to match.
std::string out_branch_
static CbmDigiManager * Instance()
Static instance.
Class characterising one event by a collection of links (indices) to data objects,...
Definition CbmEvent.h:34
void ProcessData(CbmEvent *event) final
CbmMCDataArray * cbm_fsd_points_new_
TClonesArray * cbm_global_tracks_
TClonesArray * cbm_mc_tracks_
TClonesArray * cbm_sts_tracks_
CbmDigiManager * fDigiMan
TClonesArray * cbm_fsd_hitmatch_
AnalysisTree::Matching * vtx_tracks_2_fsd_
TClonesArray * cbm_tof_hits_
TClonesArray * cbm_fsd_hits_
AnalysisTree::Matching * fsd_hits_2_mc_tracks_
const std::map< int, int > & GetMatchMap(const std::string &name) const
Double_t Chi2FsdhitGtrack(CbmFsdHit *hit, FairTrackParam inputParams)
FairTrackParam ExtrapolateGtrack(Double_t zpos, FairTrackParam params)
AnalysisTree::HitDetector * fsd_hits_
CbmMCDataManager * cbm_mc_manager_
double GetZ() const
Definition CbmHit.h:74
Int_t Extrapolate(Double_t z, Double_t *QP0=nullptr)
Access to i-th hit.
void GetTrackParam(FairTrackParam &track)
void SetTrackParam(const FairTrackParam &track)
Task class creating and managing CbmMCDataArray objects.
double GetDy() const
Definition CbmPixelHit.h:76
double GetDx() const
Definition CbmPixelHit.h:75
double GetY() const
Definition CbmPixelHit.h:74
double GetX() const
Definition CbmPixelHit.h:73
double GetDxy() const
Definition CbmPixelHit.h:77