SND@LHC Software
Loading...
Searching...
No Matches
ConvDriftTubeRawData Class Reference

#include <ConvDriftTubeRawData.h>

Inheritance diagram for ConvDriftTubeRawData:
Collaboration diagram for ConvDriftTubeRawData:

Classes

struct  HitPoint
 

Public Member Functions

 ConvDriftTubeRawData ()
 
 ~ConvDriftTubeRawData ()
 
virtual InitStatus Init ()
 
virtual void Exec (Option_t *opt)
 
void UpdateInput (int n)
 
int SetDetID (const int &chamber, const int &layer, const int &wire)
 
std::vector< HitPointGetNeighbours (const int &L, const int &C)
 
std::vector< std::vector< int > > FindClusters (const TClonesArray *hits)
 
void FindLateralitySlope (const TClonesArray *hits, const std::vector< std::vector< int > > &clusters)
 

Private Member Functions

void Process ()
 
 ConvDriftTubeRawData (const ConvDriftTubeRawData &)
 
ConvDriftTubeRawDataoperator= (const ConvDriftTubeRawData &)
 
 ClassDef (ConvDriftTubeRawData, 1)
 

Private Attributes

DriftTubeDriftTubeDet
 
TTree * fSNDTree
 
TChain * fMiniDTChain
 
int frunNumber
 
int eventNumber
 
long MiniDTeventNumber
 
int fnStart = 0
 
int fnEvents
 
double runStartUTC
 
TFile * fOut
 
TClonesArray * fDigiDriftTube
 

Detailed Description

Definition at line 16 of file ConvDriftTubeRawData.h.

Constructor & Destructor Documentation

◆ ConvDriftTubeRawData() [1/2]

ConvDriftTubeRawData::ConvDriftTubeRawData ( )

Default constructor

Definition at line 28 of file ConvDriftTubeRawData.cxx.

29 : FairTask("ConvDriftTubeRawData"), fSNDTree(nullptr), fMiniDTChain(nullptr), fDigiDriftTube(nullptr),
31{
32}

◆ ~ConvDriftTubeRawData()

ConvDriftTubeRawData::~ConvDriftTubeRawData ( )

Destructor

Definition at line 34 of file ConvDriftTubeRawData.cxx.

34{}

◆ ConvDriftTubeRawData() [2/2]

ConvDriftTubeRawData::ConvDriftTubeRawData ( const ConvDriftTubeRawData )
private

Member Function Documentation

◆ ClassDef()

ConvDriftTubeRawData::ClassDef ( ConvDriftTubeRawData  ,
 
)
private

◆ Exec()

void ConvDriftTubeRawData::Exec ( Option_t *  opt)
virtual

Virtual method Exec

Definition at line 68 of file ConvDriftTubeRawData.cxx.

69{
70
71 fDigiDriftTube->Clear("C");
72
73 // run the conversion
74 Process();
76}

◆ FindClusters()

std::vector< std::vector< int > > ConvDriftTubeRawData::FindClusters ( const TClonesArray *  hits)

Find hit clusters

Definition at line 174 of file ConvDriftTubeRawData.cxx.

174 {
175 auto nPlanes = static_cast<int>(DriftTubeDet->GetConfParI("DriftTube/nPlanes"));
176 auto nLayers = static_cast<int>(DriftTubeDet->GetConfParI("DriftTube/nLayers"));
177 auto nCells = static_cast<int>(DriftTubeDet->GetConfParI("DriftTube/nCells"));
178
179 auto gridCells = static_cast<size_t>(nPlanes * nLayers * nCells);
180
181 std::vector<int> grid(gridCells, -1);
182
183 auto gridIdx = [&](int p, int l, int c) -> int& {return grid[p * (nLayers * nCells) + l * nCells + c];};
184
185 int nHits {static_cast<int>(hits->GetEntries())};
186 if (nHits == 0) return {};
187 std::vector<bool> visited(nHits, false);
188 std::vector<std::vector<int>> allClusters;
189
190 // Fill grid
191 for (int i = 0; i != nHits; ++i) {
192 auto hit = dynamic_cast<DriftTubeHit*>(hits->At(i));
193 int p = hit->GetPlane();
194 int l = hit->GetLayer();
195 int c = hit->GetCell();
196
197 if (p >= 0 && p < nPlanes && l >= 0 && l < nLayers && c >= 0 && c < nCells) {
198 gridIdx(p, l, c) = i;
199 }
200 }
201
202 // Find cluster
203 for (int p = 0; p != nPlanes; ++p) {
204 for (int l = 0; l != nLayers; ++l) {
205 for (int c = 0; c != nCells; ++c) {
206 int startIdx {gridIdx(p, l, c)};
207
208 if (startIdx == -1 || visited[startIdx]) continue;
209
210 std::vector<int> blob;
211 std::vector<int> stack = {startIdx};
212 visited[startIdx] = true;
213
214 while (!stack.empty()) {
215 int currIdx {stack.back()};
216 stack.pop_back();
217 blob.push_back(currIdx);
218
219 auto hit = dynamic_cast<DriftTubeHit*>(hits->At(currIdx));
220 auto neighbours = GetNeighbours(hit->GetLayer(), hit->GetCell());
221
222 for (const auto& nb : neighbours) {
223 if (nb.C >= 0 && nb.C < nCells) {
224 int nbIdx {gridIdx(p, nb.L, nb.C)};
225
226 if (nbIdx != -1 && !visited[nbIdx]) {
227 visited[nbIdx] = true;
228 stack.push_back(nbIdx);
229 }
230 }
231 }
232 }
233
234 // Split clusters
235 if (blob.size() >= 3) {
236 std::vector<std::vector<int>> layerHits(nLayers);
237 // for (int l = 0; l < nLayers; ++l) {
238 // layerHits[l].clear();
239 // }
240
241 for (int idx : blob) {
242 auto hit = dynamic_cast<DriftTubeHit*>(hits->At(idx));
243 layerHits[hit->GetLayer()].push_back(idx);
244 }
245
246 for (auto& layerVec : layerHits) {
247 if (layerVec.empty()) layerVec.push_back(-1);
248 }
249
250 for (int i0 : layerHits[0]) {
251 for (int i1 : layerHits[1]) {
252 for (int i2 : layerHits[2]) {
253 for (int i3 : layerHits[3]) {
254 std::vector<int> candidate;
255
256 candidate.reserve(nLayers);
257 if (i0 != -1) candidate.push_back(i0);
258 if (i1 != -1) candidate.push_back(i1);
259 if (i2 != -1) candidate.push_back(i2);
260 if (i3 != -1) candidate.push_back(i3);
261
262 if (candidate.size() < 3) continue;
263
264 bool validChain {true};
265 for (size_t k = 0; k < candidate.size() - 1; ++k) {
266 auto hA = dynamic_cast<DriftTubeHit*>(hits->At(candidate[k]));
267 auto hB = dynamic_cast<DriftTubeHit*>(hits->At(candidate[k + 1]));
268
269 int dL {hB->GetLayer() - hA->GetLayer()};
270 int dC {hB->GetCell() - hA->GetCell()};
271
272 if (dL == 1) {
273 if (hA->GetLayer() % 2 == 0) {
274 if (dC != 0 && dC != 1) {
275 validChain = false;
276 break;
277 }
278 } else {
279 if (dC != 0 && dC != -1) {
280 validChain = false;
281 break;
282 }
283 }
284 } else if (dL == 2) {
285 if (std::abs(dC) > 1) {
286 validChain = false;
287 break;
288 }
289 }
290 }
291
292 if (validChain) {
293 allClusters.push_back(candidate);
294 }
295 }
296 }
297 }
298 }
299
300 }
301 }
302 }
303 }
304 return allClusters;
305}
std::vector< HitPoint > GetNeighbours(const int &L, const int &C)
Int_t GetLayer()
Int_t GetConfParI(TString name)
Definition DriftTube.h:34
int i
Definition ShipAna.py:86
c
Definition hnl.py:100

◆ FindLateralitySlope()

void ConvDriftTubeRawData::FindLateralitySlope ( const TClonesArray *  hits,
const std::vector< std::vector< int > > &  clusters 
)

Find lateralities with slopes method

Definition at line 307 of file ConvDriftTubeRawData.cxx.

307 {
308 auto nLayers = static_cast<int>(DriftTubeDet->GetConfParI("DriftTube/nLayers"));
309
310 struct TrackResult {
311 std::vector<int> latCombination {};
312 double quality;
313 std::vector<int> indices;
314 };
315
316 std::vector<TrackResult> candidates;
317
318 const auto HCELL = static_cast<double>(DriftTubeDet->GetConfParF("DriftTube/cellHeight") + DriftTubeDet->GetConfParF("DriftTube/plateThickness")); // Al plate thickness
319 const auto WCELL = static_cast<double>(DriftTubeDet->GetConfParF("DriftTube/cellWidth"));
320
321 int clusterID {-1};
322
323 for (const auto& hitsIdx : clusters) {
324 int nHits {hitsIdx.size()};
325 if (nHits < 3) continue;
326
327 TrackResult bestInCluster {{}, 1e9, hitsIdx};
328
329 struct Point {
330 double x;
331 double y;
332 };
333
334 std::vector<Point> points;
335
336 int nCombinations {1 << nHits};
337
338 for (int i = 0; i < nCombinations; ++i) {
339 std::vector<int> currentLats(nLayers, 0); // if no hit in that layer, lat stays 0
340 for (int j = 0; j < nHits; ++j) {
341 auto hit = dynamic_cast<DriftTubeHit*>(hits->At(hitsIdx[j]));
342 int layer {hit->GetLayer()};
343
344 int lat = ((i >> j) & 1) ? 1 : -1;
345 currentLats[layer] = lat;
346
347 double y {(layer + 0.5) * HCELL};
348 double x_wire {(hit->GetCell() + (layer % 2 == 1 ? 0.5 : 1.0)) * WCELL};
349 double drift_time = static_cast<double>(hit->GetTimestamp()- drifttube::tped);
350
351 double x {};
352 if (drift_time < 0) {
353 x = x_wire;
354 currentLats[layer] = 0;
355 } else {
356 double dist = std::min(static_cast<double>(drift_time * drifttube::vdrift), WCELL * 0.5);
357 x = x_wire + (lat * dist);
358 }
359 points.push_back({x, y});
360 }
361
362 std::vector<double> slopes {};
363 double slopesMean {};
364 double slopesStdev {};
365
366 for (size_t j = 0; j != points.size(); ++j) {
367 for (size_t k = j + 1; k != points.size(); ++k) {
368 double dx {points[j].x - points[k].x};
369 double dy {points[j].y - points[k].y};
370 if (std::abs(dy) > std::numeric_limits<double>::epsilon()) {
371 slopes.push_back(dx / dy);
372 slopesMean += (dx / dy);
373 }
374 }
375 }
376
377 points.clear();
378
379 slopesMean = slopesMean / slopes.size();
380
381 for (const auto& slope : slopes) {
382 slopesStdev += std::pow(slope - slopesMean, 2);
383 }
384
385 slopesStdev = std::sqrt(slopesStdev / (slopes.size() - 1));
386
387 if (slopesStdev < bestInCluster.quality) {
388 bestInCluster.latCombination = currentLats;
389 bestInCluster.quality = slopesStdev;
390 bestInCluster.indices = hitsIdx;
391 }
392 slopes.clear();
393 }
394 candidates.push_back(bestInCluster);
395 }
396
397 if (!candidates.empty()) {
398 std::sort(candidates.begin(), candidates.end(), [](const TrackResult& a, const TrackResult& b) {return a.quality < b.quality;});
399
400 std::vector<bool> hitUsed(static_cast<int>(hits->GetEntries()), false);
401
402 for (auto& cand : candidates) {
403 bool conflict {false};
404 ++clusterID;
405
406 for (int idx : cand.indices) {
407 if (hitUsed[idx]) {
408 conflict = true;
409 break;
410 }
411 }
412
413 if (!conflict) {
414 for (int idx : cand.indices) {
415 auto hit = dynamic_cast<DriftTubeHit*>(hits->At(idx));
416 int layer {hit->GetLayer()};
417
418 int lat {cand.latCombination[layer]};
419
420 hit->setLaterality(lat);
421 hit->setClusterID(clusterID);
422
423 hitUsed[idx] = true;
424 }
425 }
426 }
427 }
428 candidates.clear();
429}
Float_t GetConfParF(TString name)
Definition DriftTube.h:33
constexpr double vdrift
constexpr double tped
slopes(Nev=-1)

◆ GetNeighbours()

std::vector< ConvDriftTubeRawData::HitPoint > ConvDriftTubeRawData::GetNeighbours ( const int &  L,
const int &  C 
)

Find neighbouring cells to build clusters

Definition at line 142 of file ConvDriftTubeRawData.cxx.

142 {
143 auto nLayers = static_cast<int>(DriftTubeDet->GetConfParI("DriftTube/nLayers"));
144
145 std::vector<HitPoint> neighbours;
146 neighbours.reserve(10);
147
148 neighbours.push_back({L, C - 1});
149 neighbours.push_back({L, C + 1});
150
151 for (int nextL : {L - 1, L + 1}) {
152 if (nextL < 0 || nextL >= nLayers) continue;
153
154 neighbours.push_back({nextL, C});
155
156 if (L % 2 == 0) {
157 neighbours.push_back({nextL, C + 1});
158 } else {
159 neighbours.push_back({nextL, C - 1});
160 }
161 }
162
163 for (int nextL : {L - 2, L + 2}) {
164 if (nextL < 0 || nextL >= nLayers) continue;
165
166 neighbours.push_back({nextL, C});
167 neighbours.push_back({nextL, C - 1});
168 neighbours.push_back({nextL, C + 1});
169 }
170
171 return neighbours;
172}

◆ Init()

InitStatus ConvDriftTubeRawData::Init ( )
virtual

Virtual method Init

Definition at line 36 of file ConvDriftTubeRawData.cxx.

37{
38 FairRootManager *ioman = FairRootManager::Instance();
39 if (!ioman) {
40 LOG(FATAL) << "ConvDriftTubeRawData::Init: RootManager not instantiated!";
41 }
42
43 // Get the DriftTube detector from the list of globals
44 DriftTubeDet = dynamic_cast<DriftTube *>(gROOT->GetListOfGlobals()->FindObject("DriftTube"));
45
46 // Input raw data file is read from the FairRootManager
47 // This allows to have it in custom format, e.g. have arbitary names of TTrees
48
49 // converted SND
50 TFile *f0 = dynamic_cast<TFile *>(ioman->GetObject("rawConv"));
51 fSNDTree = (TTree *)f0->Get("rawConv");
52
53 // load MiniDT data for the current run
54 fMiniDTChain = (TChain *)ioman->GetObject("MiniDTChain");
55
56 // Register the output
57 fDigiDriftTube = new TClonesArray("DriftTubeHit");
58 ioman->Register("Digi_DriftTubeHits", "DigiDriftTubeHit_det", fDigiDriftTube, kTRUE);
59
60 // Get the FairLogger
61 FairLogger *logger = FairLogger::GetLogger();
62
64
65 return kSUCCESS;
66}

◆ operator=()

ConvDriftTubeRawData & ConvDriftTubeRawData::operator= ( const ConvDriftTubeRawData )
private

◆ Process()

void ConvDriftTubeRawData::Process ( )
private

Processing of raw data

Definition at line 78 of file ConvDriftTubeRawData.cxx.

79{
80 int indexDriftTube{}; // index of DT hits
81 int detID;
82 fSNDTree->GetEvent(eventNumber);
83 auto eventTimestamp = fSNDTree->GetLeaf("EventHeader.fEventTime")->GetValue();
84
85 TTreeReader MiniDTReader(fMiniDTChain);
86
87 TTreeReaderValue<Long64_t> hit_oc(MiniDTReader, "hit_orbit");
88 TTreeReaderValue<int> hit_bx(MiniDTReader, "hit_bx");
89 TTreeReaderValue<int> hit_tdc(MiniDTReader, "hit_tdc");
90 TTreeReaderValue<int> hit_chamber(MiniDTReader, "hit_chamber");
91 TTreeReaderValue<int> hit_layer(MiniDTReader, "hit_layer");
92 TTreeReaderValue<int> hit_wire(MiniDTReader, "hit_wire");
93
94 const double T_o {3564. * 4. / (ShipUnit::snd_freq * 1e9)};
95 const double T_bx {1. * 4. / (ShipUnit::snd_freq * 1e9)};
96 const double tdc_conv {T_bx / 32.};
97
98 MiniDTReader.SetEntry(MiniDTeventNumber);
99 int MatchedHits {};
100 while (MiniDTReader.Next()) {
101 auto SNDtimestamp = static_cast<double>(eventTimestamp / (ShipUnit::snd_freq * 1e9));
102 auto hit_timestamp = static_cast<double>(*hit_oc * T_o + *hit_bx * T_bx + *hit_tdc * tdc_conv);
103 if (((hit_timestamp - SNDtimestamp) > -50e-9) && ((hit_timestamp - SNDtimestamp) < 650e-9)) {
104 if (MatchedHits == 0) {
105 MiniDTeventNumber = MiniDTReader.GetCurrentEntry();
106 }
107 detID = SetDetID(*hit_chamber, *hit_layer, *hit_wire);
108 (*fDigiDriftTube)[MatchedHits] = new DriftTubeHit(detID, hit_timestamp - SNDtimestamp);
109 auto hit = dynamic_cast<DriftTubeHit*>(fDigiDriftTube->At(MatchedHits));
110 ++MatchedHits;
111 } else if ((hit_timestamp - SNDtimestamp) > 650e-9) {
112 // run laterality computation and hit redefinition
113 std::vector<std::vector<int>> hitsClusters = FindClusters(fDigiDriftTube);
114 FindLateralitySlope(fDigiDriftTube, hitsClusters);
115 MatchedHits = 0;
116 break;
117 } else {
118 continue;
119 }
120 }
121
122 // LOG(INFO) << eventNumber << " events processed out of " << fSNDTree->GetEntries() << " number of events in file.";
124}
std::vector< std::vector< int > > FindClusters(const TClonesArray *hits)
int SetDetID(const int &chamber, const int &layer, const int &wire)
void FindLateralitySlope(const TClonesArray *hits, const std::vector< std::vector< int > > &clusters)

◆ SetDetID()

int ConvDriftTubeRawData::SetDetID ( const int &  chamber,
const int &  layer,
const int &  wire 
)

Set DriftTubeHit detID as in the SND geometry

Definition at line 131 of file ConvDriftTubeRawData.cxx.

132{
133 int detID = 40000 + 1000 * (1 - chamber) + 100 * (3 - layer) + (15 - wire);
134 return detID;
135}

◆ UpdateInput()

void ConvDriftTubeRawData::UpdateInput ( int  n)

Update input raw-data file and first-to-process event

Definition at line 126 of file ConvDriftTubeRawData.cxx.

127{
128 eventNumber = NewStart;
129}

Member Data Documentation

◆ DriftTubeDet

DriftTube* ConvDriftTubeRawData::DriftTubeDet
private

Definition at line 51 of file ConvDriftTubeRawData.h.

◆ eventNumber

int ConvDriftTubeRawData::eventNumber
private

Definition at line 57 of file ConvDriftTubeRawData.h.

◆ fDigiDriftTube

TClonesArray* ConvDriftTubeRawData::fDigiDriftTube
private

Definition at line 64 of file ConvDriftTubeRawData.h.

◆ fMiniDTChain

TChain* ConvDriftTubeRawData::fMiniDTChain
private

Definition at line 56 of file ConvDriftTubeRawData.h.

◆ fnEvents

int ConvDriftTubeRawData::fnEvents
private

Definition at line 60 of file ConvDriftTubeRawData.h.

◆ fnStart

int ConvDriftTubeRawData::fnStart = 0
private

Definition at line 59 of file ConvDriftTubeRawData.h.

◆ fOut

TFile* ConvDriftTubeRawData::fOut
private

Definition at line 63 of file ConvDriftTubeRawData.h.

◆ frunNumber

int ConvDriftTubeRawData::frunNumber
private

Definition at line 57 of file ConvDriftTubeRawData.h.

◆ fSNDTree

TTree* ConvDriftTubeRawData::fSNDTree
private

Definition at line 55 of file ConvDriftTubeRawData.h.

◆ MiniDTeventNumber

long ConvDriftTubeRawData::MiniDTeventNumber
private

Definition at line 58 of file ConvDriftTubeRawData.h.

◆ runStartUTC

double ConvDriftTubeRawData::runStartUTC
private

Definition at line 61 of file ConvDriftTubeRawData.h.


The documentation for this class was generated from the following files: