14#include <RtypesCore.h>
18#include <boost/range/distance.hpp>
19#include <boost/range/iterator_range_core.hpp>
32 if (
a.getDetector() !=
b.getDetector()) {
33 return a.getDetector() <
b.getDetector();
36 if (
a.getPadRow() !=
b.getPadRow()) {
37 return a.getPadRow() <
b.getPadRow();
40 if (
a.getROB() !=
b.getROB()) {
41 return a.getROB() <
b.getROB();
44 if (
a.getMCM() !=
b.getMCM()) {
45 return a.getMCM() <
b.getMCM();
49 if (
a.getChannel() !=
b.getChannel()) {
50 return a.getChannel() >
b.getChannel();
60 const uint64_t det_row_mask = 0x0ffde00000000000;
63 const uint64_t col_pos_mask = 0x00011fff00000000;
65 auto a_det_row =
a.getTrackletWord() & det_row_mask;
66 auto b_det_row =
b.getTrackletWord() & det_row_mask;
68 if (a_det_row != b_det_row) {
69 return a_det_row < b_det_row;
72 auto a_col_pos =
a.getTrackletWord() & col_pos_mask;
73 auto b_col_pos =
b.getTrackletWord() & col_pos_mask;
75 return a_col_pos < b_col_pos;
80 if (
a.getDetector() !=
b.getDetector()) {
81 return a.getDetector() <
b.getDetector();
84 if (
a.getPadRow() !=
b.getPadRow()) {
85 return a.getPadRow() <
b.getPadRow();
88 if (
a.getPadCol() !=
b.getPadCol()) {
89 return a.getPadCol() <
b.getPadCol();
102template <
typename keyfunc>
106 std::map<uint32_t, RawDataSpan> spanmap;
112 for (
auto cur =
digits.begin(); cur !=
digits.end(); ) {
114 auto key = keyfunc::key(*cur);
116 auto nxt = std::find_if(cur,
digits.end(), [
key](
auto x) { return keyfunc::key(x) != key; });
118 spanmap[
key].digits = boost::make_iterator_range(cur, nxt);
125 auto key = keyfunc::key(*cur);
126 auto nxt = std::find_if(cur,
tracklets.end(), [
key](
auto x) { return keyfunc::key(x) != key; });
127 spanmap[
key].tracklets = boost::make_iterator_range(cur, nxt);
134 std::map<uint32_t, std::vector<HitPoint>::iterator> firsthit;
135 for (
auto cur =
hits.begin(); cur !=
hits.end(); ++cur) {
137 auto keys = keyfunc::keys(*cur);
139 for (
auto key : keys) {
140 firsthit.insert({
key, cur});
143 for (
auto it = firsthit.cbegin(); it != firsthit.cend(); ) {
144 if (keys.find(it->first) == keys.end()) {
145 spanmap[it->first].hits = boost::make_iterator_range(it->second, cur);
146 it = firsthit.erase(it);
155 std::vector<RawDataSpan> spans;
156 transform(spanmap.begin(), spanmap.end(), back_inserter(spans), [](
auto const& pair) {
return pair.second; });
166 template <
typename T>
167 static uint32_t
key(
const T&
x)
169 return 100 *
x.getDetector() +
x.getPadRow();
174 uint32_t
key = 100 *
x.getDetector() +
x.getPadRow();
180 return key == 100 *
x.getDetector() +
x.getPadRow();
185template std::vector<RawDataSpan> RawDataSpan::iterateBy<PadRowID>();
193 template <
typename T>
194 static uint32_t
key(
const T&
x)
196 return 1000 *
x.getDetector() + 8 *
x.getPadRow() + 4 * (
x.getROB() % 2) +
x.getMCM() % 4;
201 uint32_t detrow = 1000 *
x.getDetector() + 8 *
x.getPadRow();
205 float c =
x.getMCMChannel(mcmcol);
207 if (
c >= 19.0 && mcmcol >= 1) {
208 return {detrow + mcmcol - 1, detrow + mcmcol};
209 }
else if (
c <= 1.0 && mcmcol <= 6) {
210 return {detrow + mcmcol, detrow + mcmcol + 1};
212 return {detrow + mcmcol};
222template std::vector<RawDataSpan> RawDataSpan::iterateBy<MCM_ID>();
260 std::map<std::pair<int, int>, SegmentInfo> trackSegmentInfo;
262 for (
int iHit = 0; iHit <
hits.size(); ++iHit) {
263 auto hit =
hits[iHit];
266 if (hit.isFromDriftRegion()) {
268 auto id = std::make_pair(hit.getID(), hit.getDetector());
269 if (hit.getX() > trackSegmentInfo[
id].start) {
270 trackSegmentInfo[
id].firsthit = iHit;
271 trackSegmentInfo[
id].start = hit.getX();
274 if (hit.getX() < trackSegmentInfo[
id].end) {
275 trackSegmentInfo[
id].lasthit = iHit;
276 trackSegmentInfo[
id].end = hit.getX();
281 std::vector<TrackSegment> trackSegments;
282 for (
auto x : trackSegmentInfo) {
283 auto trackid =
x.first.first;
284 auto detector =
x.first.second;
285 auto firsthit =
hits[
x.second.firsthit];
286 auto lasthit =
hits[
x.second.lasthit];
287 trackSegments.emplace_back(firsthit, lasthit, trackid);
289 return trackSegments;
296 if (!std::filesystem::exists(dir) || !std::filesystem::is_directory(dir)) {
297 O2ERROR(
"'%s' is not a directory", dir.c_str());
303 if (!std::filesystem::exists(dir /
"trdtracklets.root")) {
304 O2ERROR(
"'tracklets.root' not found in directory '%s'", dir.c_str());
308 mMainFile =
new TFile((dir /
"trdtracklets.root").c_str());
309 mMainFile->GetObject(
"o2sim", mDataTree);
312 mDataTree->SetBranchAddress(
"Tracklet", &mTracklets);
313 mDataTree->SetBranchAddress(
"TrackTrg", &mTrgRecords);
315 if (std::filesystem::exists(dir /
"trddigits.root")) {
316 mDataTree->AddFriend(
"o2sim", (dir /
"trddigits.root").c_str());
317 mDataTree->SetBranchAddress(
"TRDDigit", &mDigits);
320 if (std::filesystem::exists(dir /
"o2match_itstpc.root")) {
321 mDataTree->AddFriend(
"matchTPCITS", (dir /
"o2match_itstpc.root").c_str());
322 mDataTree->SetBranchAddress(
"TPCITS", &mTracks);
326 if (std::filesystem::exists(dir /
"o2_tfidinfo.root")) {
327 TFile fInTFID((dir /
"o2_tfidinfo.root").c_str());
328 mTFIDs = (std::vector<o2::dataformats::TFIDInfo>*)fInTFID.Get(
"tfidinfo");
332 if (std::filesystem::exists(dir /
"collisioncontext.root")) {
333 TFile fInCollCtx((dir /
"collisioncontext.root").c_str());
339 if (std::filesystem::exists(dir /
"o2sim_Kine.root")) {
340 mMCFile =
new TFile((dir /
"o2sim_Kine.root").c_str());
341 mMCFile->GetObject(
"o2sim", mMCTree);
342 mMCTree->SetBranchAddress(
"MCEventHeader.", &mMCEventHeader);
343 mMCTree->SetBranchAddress(
"MCTrack", &mMCTracks);
347 if (mMCFile && std::filesystem::exists(dir /
"o2sim_HitsTRD.root")) {
348 mMCTree->AddFriend(
"o2sim", (dir /
"o2sim_HitsTRD.root").c_str());
349 mMCTree->SetBranchAddress(
"TRDHit", &mHits);
355 if (!mDataTree->GetEntry(mTimeFrameNo)) {
363 O2INFO(
"Loaded data for time frame #%d with %d TRD trigger records, %d digits and %d tracklets",
364 mTimeFrameNo, mTrgRecords->size(), mDigits->size(), mTracklets->size());
372 if (mEventNo >= mTrgRecords->size()) {
375 mTriggerRecord = mTrgRecords->at(mEventNo);
376 O2INFO(
"Processing event: orbit %d bc %04d with %d digits and %d tracklets",
380 if (mCollisionContext) {
389 mMCTree->GetEntry(
i);
392 O2INFO(
"Loaded matching MC event #%d with time offset %f ns and %d hits",
397 for (
auto& hit : *mHits) {
398 mHitPoints.emplace_back(ctrans->MakeSpacePoint(hit), hit.GetCharge());
415 ev.
hits = boost::make_iterator_range(mHitPoints.begin(), mHitPoints.end());
430 for (
auto& track : *mTracks) {
455 return mTFIDs->at(mTimeFrameNo - 1);
465 if (tfid.isDummy()) {
475 std::ostringstream out;
477 out <<
"RawDataManager is not connected to any files" << std::flush;
481 out <<
"ERROR: main datatree not connected" << std::flush;
484 out <<
"Main file:" << mMainFile->GetPath() <<
" has " << mDataTree->GetEntries() <<
" time frames " << std::endl;
485 if (mDataTree->GetFriend(
"TRDDigit")) {
486 out <<
"digits" << std::endl;
488 if (mDataTree->GetFriend(
"TPCITS")) {
489 out <<
"tpc its matches" << std::endl;
493 out << mTFIDs->size() <<
" TFIDs were read from o2_tfidinfo.root" << std::flush;
500 std::ostringstream out;
501 out <<
"## Time frame " << mTimeFrameNo <<
": ";
508 std::ostringstream out;
509 out <<
"## TF:Event " << mTimeFrameNo <<
":" << mEventNo <<
": "
bool comp_digit(const o2::trd::Digit &a, const o2::trd::Digit &b)
comparison function to order digits by det / row / MCM / -channel
bool comp_tracklet(const o2::trd::Tracklet64 &a, const o2::trd::Tracklet64 &b)
comparison function to order tracklets by det / row / MCM / channel
bool comp_spacepoint(const ChamberSpacePoint &a, const ChamberSpacePoint &b)
std::vector< o2::InteractionTimeRecord > & getEventRecords(bool withQED=false)
int getNCollisions() const
std::string describeEvent()
RawDataManager(std::filesystem::path dir=".")
The RawDataManager constructor: connects all data files and sets up trees, readers etc.
o2::dataformats::TFIDInfo getTimeFrameInfo()
access time frame info
std::string describeFiles()
std::string describeTimeFrame()
const BCData & getBCData() const
int getFirstTracklet() const
int getFirstDigit() const
int getNumberOfDigits() const
int getNumberOfTracklets() const
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
constexpr int NCOLMCM
the number of pads per MCM
static uint32_t key(const T &x)
static std::set< uint32_t > keys(const o2::trd::ChamberSpacePoint &x)
static int getMcmRowCol(uint32_t k)
static int getDetector(uint32_t k)
static uint32_t key(const T &x)
The static key method calculates a padrow ID for digits and tracklets.
static bool match(const uint32_t key, const o2::trd::ChamberSpacePoint &x)
static std::set< uint32_t > keys(const o2::trd::ChamberSpacePoint &x)
uint16_t bc
bunch crossing ID of interaction
static double bc2ns(int bc, unsigned int orbit)
float differenceInBCMUS(const InteractionRecord &other) const
float differenceInBCNS(const InteractionRecord &other) const
std::vector< RawDataSpan > iterateByPadRow()
boost::iterator_range< std::vector< o2::trd::Tracklet64 >::iterator > tracklets
std::vector< TrackSegment > makeMCTrackSegments()
boost::iterator_range< std::vector< o2::trd::Digit >::iterator > digits
std::vector< RawDataSpan > iterateByMCM()
std::vector< RawDataSpan > iterateBy()
boost::iterator_range< std::vector< HitPoint >::iterator > hits