14#include <RtypesCore.h>
18#include <boost/range/distance.hpp>
19#include <boost/range/iterator_range_core.hpp>
34 if (
a.getDetector() !=
b.getDetector()) {
35 return a.getDetector() <
b.getDetector();
38 if (
a.getPadRow() !=
b.getPadRow()) {
39 return a.getPadRow() <
b.getPadRow();
42 if (
a.getROB() !=
b.getROB()) {
43 return a.getROB() <
b.getROB();
46 if (
a.getMCM() !=
b.getMCM()) {
47 return a.getMCM() <
b.getMCM();
51 if (
a.getChannel() !=
b.getChannel()) {
52 return a.getChannel() >
b.getChannel();
62 const uint64_t det_row_mask = 0x0ffde00000000000;
65 const uint64_t col_pos_mask = 0x00011fff00000000;
67 auto a_det_row =
a.getTrackletWord() & det_row_mask;
68 auto b_det_row =
b.getTrackletWord() & det_row_mask;
70 if (a_det_row != b_det_row) {
71 return a_det_row < b_det_row;
74 auto a_col_pos =
a.getTrackletWord() & col_pos_mask;
75 auto b_col_pos =
b.getTrackletWord() & col_pos_mask;
77 return a_col_pos < b_col_pos;
82 if (
a.getDetector() !=
b.getDetector()) {
83 return a.getDetector() <
b.getDetector();
86 if (
a.getPadRow() !=
b.getPadRow()) {
87 return a.getPadRow() <
b.getPadRow();
90 if (
a.getPadCol() !=
b.getPadCol()) {
91 return a.getPadCol() <
b.getPadCol();
104template <
typename keyfunc>
108 std::map<uint32_t, RawDataSpan> spanmap;
114 for (
auto cur =
digits.begin(); cur !=
digits.end(); ) {
116 auto key = keyfunc::key(*cur);
118 auto nxt = std::find_if(cur,
digits.end(), [
key](
auto x) { return keyfunc::key(x) != key; });
120 spanmap[
key].digits = boost::make_iterator_range(cur, nxt);
127 auto key = keyfunc::key(*cur);
128 auto nxt = std::find_if(cur,
tracklets.end(), [
key](
auto x) { return keyfunc::key(x) != key; });
129 spanmap[
key].tracklets = boost::make_iterator_range(cur, nxt);
136 std::map<uint32_t, std::vector<HitPoint>::iterator> firsthit;
137 for (
auto cur =
hits.begin(); cur !=
hits.end(); ++cur) {
139 auto keys = keyfunc::keys(*cur);
141 for (
auto key : keys) {
142 firsthit.insert({
key, cur});
145 for (
auto it = firsthit.cbegin(); it != firsthit.cend(); ) {
146 if (keys.find(it->first) == keys.end()) {
147 spanmap[it->first].hits = boost::make_iterator_range(it->second, cur);
148 it = firsthit.erase(it);
157 std::vector<RawDataSpan> spans;
158 transform(spanmap.begin(), spanmap.end(), back_inserter(spans), [](
auto const& pair) {
return pair.second; });
168 template <
typename T>
169 static uint32_t
key(
const T&
x)
171 return 100 *
x.getDetector() +
x.getPadRow();
176 uint32_t
key = 100 *
x.getDetector() +
x.getPadRow();
182 return key == 100 *
x.getDetector() +
x.getPadRow();
187template std::vector<RawDataSpan> RawDataSpan::iterateBy<PadRowID>();
195 template <
typename T>
196 static uint32_t
key(
const T&
x)
198 return 1000 *
x.getDetector() + 8 *
x.getPadRow() + 4 * (
x.getROB() % 2) +
x.getMCM() % 4;
203 uint32_t detrow = 1000 *
x.getDetector() + 8 *
x.getPadRow();
207 float c =
x.getMCMChannel(mcmcol);
209 if (
c >= 19.0 && mcmcol >= 1) {
210 return {detrow + mcmcol - 1, detrow + mcmcol};
211 }
else if (
c <= 1.0 && mcmcol <= 6) {
212 return {detrow + mcmcol, detrow + mcmcol + 1};
214 return {detrow + mcmcol};
224template std::vector<RawDataSpan> RawDataSpan::iterateBy<MCM_ID>();
262 std::map<std::pair<int, int>, SegmentInfo> trackSegmentInfo;
264 for (
int iHit = 0; iHit <
hits.size(); ++iHit) {
265 auto hit =
hits[iHit];
268 if (hit.isFromDriftRegion()) {
270 auto id = std::make_pair(hit.getID(), hit.getDetector());
271 if (hit.getX() > trackSegmentInfo[
id].start) {
272 trackSegmentInfo[
id].firsthit = iHit;
273 trackSegmentInfo[
id].start = hit.getX();
276 if (hit.getX() < trackSegmentInfo[
id].end) {
277 trackSegmentInfo[
id].lasthit = iHit;
278 trackSegmentInfo[
id].end = hit.getX();
283 std::vector<TrackSegment> trackSegments;
284 for (
auto x : trackSegmentInfo) {
285 auto trackid =
x.first.first;
286 auto detector =
x.first.second;
287 auto firsthit =
hits[
x.second.firsthit];
288 auto lasthit =
hits[
x.second.lasthit];
289 trackSegments.emplace_back(firsthit, lasthit, trackid);
291 return trackSegments;
298 if (!std::filesystem::exists(dir) || !std::filesystem::is_directory(dir)) {
299 O2ERROR(
"'%s' is not a directory", dir.c_str());
305 if (!std::filesystem::exists(dir /
"trdtracklets.root")) {
306 O2ERROR(
"'tracklets.root' not found in directory '%s'", dir.c_str());
310 mMainFile =
new TFile((dir /
"trdtracklets.root").c_str());
311 mMainFile->GetObject(
"o2sim", mDataTree);
314 mDataTree->SetBranchAddress(
"Tracklet", &mTracklets);
315 mDataTree->SetBranchAddress(
"TrackTrg", &mTrgRecords);
317 if (std::filesystem::exists(dir /
"trddigits.root")) {
318 mDataTree->AddFriend(
"o2sim", (dir /
"trddigits.root").c_str());
319 mDataTree->SetBranchAddress(
"TRDDigit", &mDigits);
322 if (std::filesystem::exists(dir /
"o2match_itstpc.root")) {
323 mDataTree->AddFriend(
"matchTPCITS", (dir /
"o2match_itstpc.root").c_str());
324 mDataTree->SetBranchAddress(
"TPCITS", &mTracks);
328 if (std::filesystem::exists(dir /
"o2_tfidinfo.root")) {
329 TFile fInTFID((dir /
"o2_tfidinfo.root").c_str());
330 mTFIDs = (std::vector<o2::dataformats::TFIDInfo>*)fInTFID.Get(
"tfidinfo");
334 if (std::filesystem::exists(dir /
"collisioncontext.root")) {
335 TFile fInCollCtx((dir /
"collisioncontext.root").c_str());
341 if (std::filesystem::exists(dir /
"o2sim_Kine.root")) {
342 mMCFile =
new TFile((dir /
"o2sim_Kine.root").c_str());
343 mMCFile->GetObject(
"o2sim", mMCTree);
344 mMCTree->SetBranchAddress(
"MCEventHeader.", &mMCEventHeader);
345 mMCTree->SetBranchAddress(
"MCTrack", &mMCTracks);
349 if (mMCFile && std::filesystem::exists(dir /
"o2sim_HitsTRD.root")) {
350 mMCTree->AddFriend(
"o2sim", (dir /
"o2sim_HitsTRD.root").c_str());
351 mMCTree->SetBranchAddress(
"TRDHit", &mHits);
357 if (!mDataTree->GetEntry(mTimeFrameNo)) {
365 O2INFO(
"Loaded data for time frame #%d with %d TRD trigger records, %d digits and %d tracklets",
366 mTimeFrameNo, mTrgRecords->size(), mDigits->size(), mTracklets->size());
374 if (mEventNo >= mTrgRecords->size()) {
377 mTriggerRecord = mTrgRecords->at(mEventNo);
378 O2INFO(
"Processing event: orbit %d bc %04d with %d digits and %d tracklets",
382 if (mCollisionContext) {
391 mMCTree->GetEntry(
i);
394 O2INFO(
"Loaded matching MC event #%d with time offset %f ns and %d hits",
399 for (
auto& hit : *mHits) {
400 mHitPoints.emplace_back(ctrans->MakeSpacePoint(hit), hit.GetCharge());
417 ev.
hits = boost::make_iterator_range(mHitPoints.begin(), mHitPoints.end());
432 for (
auto& track : *mTracks) {
457 return mTFIDs->at(mTimeFrameNo - 1);
467 if (tfid.isDummy()) {
477 std::ostringstream out;
479 out <<
"RawDataManager is not connected to any files" << std::flush;
483 out <<
"ERROR: main datatree not connected" << std::flush;
486 out <<
"Main file:" << mMainFile->GetPath() <<
" has " << mDataTree->GetEntries() <<
" time frames " << std::endl;
487 if (mDataTree->GetFriend(
"TRDDigit")) {
488 out <<
"digits" << std::endl;
490 if (mDataTree->GetFriend(
"TPCITS")) {
491 out <<
"tpc its matches" << std::endl;
495 out << mTFIDs->size() <<
" TFIDs were read from o2_tfidinfo.root" << std::flush;
502 std::ostringstream out;
503 out <<
"## Time frame " << mTimeFrameNo <<
": ";
510 std::ostringstream out;
511 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