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