Skip to content

Commit 692140b

Browse files
tdietelbazinski
andauthored
TRD raw data display (#11552)
* Import classes to analyse TRD digits, tracklets The classes allow to load trdtracklets.root and trddigits.root files, iterate over digits and tracklets and partition the data by MCM. * Add coordinate transformer and DrawMCM routine * Consider ExB in coordinate transformer * Add display of cluster positions * Add method to iterate over RawDataSpan by padrow * Make raw display compatible with real data Fix issue when no MC hits file is found. Switch off ploting of clusters by default to make plots cleaner. * Split RawDisplay code into 3 files The splitting prepares the code for inclusion into O2. The functionality is essentially the same as before. * Move TRD raw data display to QC subdirectory This move prepares the raw data display and analysis utitlities for inclusion in the upstream repository. The classes also move out of the o2::trd::rawdisp into the o2::trd namespace. The DataManager class was renamed RawDataManager. * Clean up and add comments * Add drawing options for RawDisplay * Add example macro * Run clang-format and add copyright message * Run clang-format again * Add test for drawing demo macro * Work on Monte-Carlo hits * Move helper structs from RawDataManager.h to .cxx * Implement visualisation of hits * Apply clang-format * Fix formatting * Clean up output / logging * Use PadPlane for coordinate transformation * Fix formating * Convert RawDataSpan to use boot:iterator_range * Implement drawing of MC track segments * Fix raw display example macro * Fix formatting * remove TTreeReaderArray and fix a bug --------- Co-authored-by: Sean Murray <hamiltonthomas@gmail.com>
1 parent f9103ce commit 692140b

File tree

10 files changed

+1461
-1
lines changed

10 files changed

+1461
-1
lines changed

Detectors/TRD/qc/CMakeLists.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@
99
# granted to it by virtue of its status as an Intergovernmental Organization
1010
# or submit itself to any jurisdiction.
1111

12+
add_subdirectory(macros)
13+
1214
o2_add_library(TRDQC
1315
SOURCES src/Tracking.cxx
1416
src/StatusHelper.cxx
17+
src/CoordinateTransformer.cxx
18+
src/RawDataManager.cxx
19+
src/RawDisplay.cxx
1520
PUBLIC_LINK_LIBRARIES O2::TRDBase
1621
O2::DataFormatsTRD
1722
O2::DataFormatsGlobalTracking
@@ -21,4 +26,7 @@ o2_add_library(TRDQC
2126

2227
o2_target_root_dictionary(TRDQC
2328
HEADERS include/TRDQC/Tracking.h
24-
include/TRDQC/StatusHelper.h)
29+
include/TRDQC/StatusHelper.h
30+
include/TRDQC/CoordinateTransformer.h
31+
include/TRDQC/RawDataManager.h
32+
include/TRDQC/RawDisplay.h)
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
// Copyright 2019-2023 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#ifndef ALICEO2_TRD_COORDINATE_TRANSFORMER_H_
13+
#define ALICEO2_TRD_COORDINATE_TRANSFORMER_H_
14+
15+
///
16+
/// \file CoordinateTransformer.h
17+
/// \author Thomas Dietel, tom@dietel.net
18+
///
19+
20+
#include "DataFormatsTRD/Hit.h"
21+
22+
#include <array>
23+
24+
namespace o2::trd
25+
{
26+
27+
class Geometry;
28+
class CoordinateTransformer;
29+
30+
/// A position in spatial (x,y,z) and raw/digit coordinates (det,row,col,tb).
31+
/// This class is intended to store the converted coordinates of a space point, to avoid
32+
/// repeated transformations between spatial and row/col/tb coordinates.
33+
class ChamberSpacePoint
34+
{
35+
public:
36+
ChamberSpacePoint(int det = -999) : mDetector(det){};
37+
ChamberSpacePoint(int id, int detector, float x, float y, float z, std::array<float, 3> rct, bool inDrift)
38+
: mID(id), mDetector(detector), mX(x), mY(y), mZ(z), mPadrow(rct[0]), mPadcol(rct[1]), mTimebin(rct[2]), mInDrift(inDrift){};
39+
40+
/// check if the space point has been initialized
41+
bool isValid() const { return mDetector >= 0; }
42+
43+
/// check if the space point is in the drift region
44+
bool isFromDriftRegion() const { return mInDrift; }
45+
46+
/// return the ID of the associated track (either MC or reconstructed)
47+
int getID() const { return mID; }
48+
49+
/// spatial x coordinate of space point
50+
float getX() const { return mX; }
51+
52+
/// spatial y coordinate of space point
53+
float getY() const { return mY; }
54+
55+
/// spatial z coordinate of space point
56+
float getZ() const { return mZ; }
57+
58+
/// detector number corresponding to space point
59+
int getDetector() const { return mDetector; }
60+
61+
/// pad row within detector of space point
62+
int getPadRow() const { return int(floor(mPadrow)); }
63+
float getPadRowF() const { return mPadrow; }
64+
65+
/// pad position (a.k.a. column) within pad row
66+
float getPadCol() const { return mPadcol; }
67+
68+
/// time coordinate in drift direction
69+
float getTimeBin() const { return mTimebin; }
70+
71+
/// calculate the channel number within the MCM. 0..21 if valid, -1 if not within this MCM
72+
float getMCMChannel(int mcmcol) const;
73+
74+
bool isInMCM(int detector, int padrow, int mcmcol) const;
75+
76+
/// calculate MCM corresponding to pad row/column
77+
// int getMCM() const { return o2::trd::HelperMethods::getMCMfromPad(mPadrow, mPadcol); }
78+
79+
/// calculate readout board corresponding to pad row/column
80+
// int getROB() const { return o2::trd::HelperMethods::getROBfromPad(mPadrow, mPadcol); }
81+
82+
protected:
83+
float mX, mY, mZ;
84+
bool mInDrift;
85+
int mID;
86+
int mDetector;
87+
float mPadrow, mPadcol, mTimebin;
88+
89+
// static constexpr float xscale = 1.0 / (o2::trd::Geometry::cheight() + o2::trd::Geometry::cspace());
90+
// static constexpr float xoffset = o2::trd::Geometry::getTime0(0);
91+
// static constexpr float alphascale = 1.0 / o2::trd::Geometry::getAlpha();
92+
};
93+
94+
std::ostream& operator<<(std::ostream& os, const ChamberSpacePoint& p);
95+
96+
/// A HitPoint is a ChamberSpacePoint with additional charge information, meant to to hold all information about
97+
/// Monte-Carlo hits within a chamber.
98+
class HitPoint : public ChamberSpacePoint
99+
{
100+
public:
101+
HitPoint(ChamberSpacePoint position, float charge)
102+
: ChamberSpacePoint(position), mCharge(charge)
103+
{
104+
}
105+
106+
HitPoint(){};
107+
108+
float getCharge() { return mCharge; }
109+
110+
private:
111+
float mCharge{0.0};
112+
};
113+
114+
/// A track segment: a straight line connecting two points. The points are generally given in spatial coordinates,
115+
/// which are then converted to pad row / column / timebin coordinates. These are then used to calculate the
116+
/// position and slope of the track segment in a given pad row, which should correspond to the reconstructed
117+
/// tracklet.
118+
class TrackSegment
119+
{
120+
public:
121+
TrackSegment(){}; // default constructor, will create invalid start and end points
122+
TrackSegment(ChamberSpacePoint start, ChamberSpacePoint end, int id)
123+
: mStartPoint(start), mEndPoint(end), mTrackID(id)
124+
{
125+
assert(start.getDetector() == end.getDetector());
126+
}
127+
128+
/// check if the space point has been initialized
129+
bool isValid() const { return mStartPoint.isValid(); }
130+
131+
/// position of track segment at timebin 0
132+
float getPadColAtTimeBin(float timebin = 0) const
133+
{
134+
return mStartPoint.getPadCol() - getSlope() * (mStartPoint.getTimeBin() - timebin);
135+
}
136+
137+
float getSlope() const
138+
{
139+
return (mEndPoint.getPadCol() - mStartPoint.getPadCol()) / (mEndPoint.getTimeBin() - mStartPoint.getTimeBin());
140+
}
141+
142+
/// detector number
143+
int getDetector() const { return mStartPoint.getDetector(); }
144+
145+
ChamberSpacePoint& getStartPoint() { return mStartPoint; }
146+
ChamberSpacePoint& getEndPoint() { return mEndPoint; }
147+
148+
protected:
149+
ChamberSpacePoint mStartPoint, mEndPoint;
150+
int mTrackID;
151+
152+
// int mDetector;
153+
};
154+
155+
// std::ostream& operator<<(std::ostream& os, const ChamberSpacePoint& p);
156+
157+
/// CoordinateTransformer: translate between local spatial and pad/timebin coordinates
158+
///
159+
/// The intention of the CoordinateTransformer is to bundle calculations around coordinate transformations for the TRD and access to the calibration objects.
160+
/// So far it translates local spatial (x/y/z) coordinates within a TRD chamber (detector) to a tuple of pad row, pad column and time bin.
161+
/// In the future, it could translate e.g. track parameters to expected tracklet position and inclination.
162+
/// At the time of writing, only constant drift velocity, Lorentz angle and T0 are considered, and must be set by hand.
163+
class CoordinateTransformer
164+
{
165+
public:
166+
static CoordinateTransformer* instance()
167+
{
168+
static CoordinateTransformer mCTrans;
169+
return &mCTrans;
170+
}
171+
172+
/// Translate local spatial (x/y/z) coordinates within a TRD chamber (detector) to a tuple of pad row, column and time bin.
173+
///
174+
/// Local x,y,z coordinates follow the convention for MC hist and are assumed to be corrrected for alignment.
175+
/// The x-coordinate points in time direction, y in pad and z in row direction.
176+
/// The result is an array of three floating point numbers for row, column and timebin.
177+
/// Time and column can directly be compared with digit or tracklet data.
178+
/// The pad row is returned as a floating point number that indicates also the position within the padrow.
179+
/// The fractional part of the pad row is not available for digits and tracklets, and only
180+
std::array<float, 3> Local2RCT(int det, float x, float y, float z);
181+
182+
/// Wrapper to conveniently calculate the row/column/time coordinate of a MC hit.
183+
std::array<float, 3> Local2RCT(o2::trd::Hit& hit)
184+
{
185+
return Local2RCT(hit.GetDetectorID(), hit.getLocalT(), hit.getLocalC(), hit.getLocalR());
186+
}
187+
188+
o2::trd::ChamberSpacePoint MakeSpacePoint(o2::trd::Hit& hit);
189+
190+
/// Legacy, less accurate method to convert local spatial to row/column/time coordinate.
191+
/// This method is only included for comparision, and should be removed in the future.
192+
std::array<float, 3> OrigLocal2RCT(int det, float x, float y, float z);
193+
194+
/// Legacy, less accurate method to convert local spatial to row/column/time coordinate.
195+
/// This method is only included for comparision, and should be removed in the future.
196+
std::array<float, 3> OrigLocal2RCT(o2::trd::Hit& hit)
197+
{
198+
return OrigLocal2RCT(hit.GetDetectorID(), hit.getLocalT(), hit.getLocalC(), hit.getLocalR());
199+
}
200+
201+
float GetVdrift() { return mVdrift; }
202+
void SetVdrift(float x) { mVdrift = x; }
203+
204+
float GetT0() { return mT0; }
205+
void SetT0(float x) { mT0 = x; }
206+
207+
float GetExB() { return mExB; }
208+
void SetExB(float x) { mExB = x; }
209+
210+
protected:
211+
o2::trd::Geometry* mGeo;
212+
float mVdrift{1.5625}; ///< drift velocity in cm/us
213+
float mT0{4.0}; ///< time offset of start of drift region
214+
float mExB{0.140}; ///< tan(Lorentz angle): tan(8 deg) ~ 0.140
215+
216+
private:
217+
CoordinateTransformer();
218+
};
219+
220+
} // namespace o2::trd
221+
222+
#endif // ALICEO2_TRD_RAWDISPLAY_H_

0 commit comments

Comments
 (0)