Skip to content

Commit 34ec7b5

Browse files
committed
Alpide strobe is divisor of orbit, DEF=9 strobes/orbit
To avoid ROF calculation slippage due to the float errors operate, in continuous mode use ROF length explicitly expressed in number of BCs (must be also divisor of orbit). By default use 9 strobes per orbit
1 parent 0702008 commit 34ec7b5

14 files changed

Lines changed: 152 additions & 96 deletions

File tree

DataFormats/common/include/CommonDataFormat/InteractionRecord.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ struct InteractionRecord {
102102
return (int64_t(orbit) * o2::constants::lhc::LHCMaxBunches) + bc;
103103
}
104104

105+
void setFromLong(int64_t l)
106+
{
107+
// set from long BC counter
108+
bc = l % o2::constants::lhc::LHCMaxBunches;
109+
orbit = l / o2::constants::lhc::LHCMaxBunches;
110+
}
111+
105112
bool operator>(const InteractionRecord& other) const
106113
{
107114
return (orbit == other.orbit) ? (bc > other.bc) : (orbit > other.orbit);
@@ -258,6 +265,11 @@ struct InteractionTimeRecord : public InteractionRecord {
258265
timeNS = 0.;
259266
}
260267

268+
double getTimeOffsetWrtBC() const
269+
{
270+
return timeNS - bc2ns();
271+
}
272+
261273
void print() const;
262274

263275
friend std::ostream& operator<<(std::ostream& stream, InteractionTimeRecord const& ir);

Detectors/GlobalTracking/include/GlobalTracking/MatchTPCITS.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ class MatchTPCITS
314314

315315
///< set ITS ROFrame duration in microseconds
316316
void setITSROFrameLengthMUS(float fums) { mITSROFrameLengthMUS = fums; }
317+
///< set ITS ROFrame duration in BC (continuous mode only)
318+
void setITSROFrameLengthInBC(int nbc);
317319

318320
///< set ITS 0-th ROFrame time start in \mus
319321
void setITSROFrameOffsetMUS(float v) { mITSROFrameOffsetMUS = v; }
@@ -550,6 +552,7 @@ class MatchTPCITS
550552
///< assigned time0 and its track Z position (converted from mTPCTimeEdgeZSafeMargin)
551553
float mTPCTimeEdgeTSafeMargin = 0.f;
552554

555+
int mITSROFrameLengthInBC = 0; ///< ITS RO frame in BC (for ITS cont. mode only)
553556
float mITSROFrameLengthMUS = -1.; ///< ITS RO frame in \mus
554557
float mITSROFrameOffsetMUS = 0; ///< time in \mus corresponding to start of 1st ITS ROFrame,
555558
///< i.e. t = ROFrameID*mITSROFrameLengthMUS - mITSROFrameOffsetMUS

Detectors/GlobalTracking/src/MatchTPCITS.cxx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,11 @@ void MatchTPCITS::init()
339339

340340
assert(mITSROFrameLengthMUS > 0.0f);
341341
mITSROFramePhaseOffset = mITSROFrameOffsetMUS / mITSROFrameLengthMUS;
342-
mITSROFrame2TPCBin = mITSROFrameLengthMUS / mTPCTBinMUS;
342+
if (mITSTriggered) {
343+
mITSROFrame2TPCBin = mITSROFrameLengthMUS / mTPCTBinMUS;
344+
} else {
345+
mITSROFrame2TPCBin = mITSROFrameLengthMUS / mTPCTBinMUS; // RSTODO use both ITS and TPC times BCs once will be available for TPC also
346+
}
343347
mTPCBin2ITSROFrame = 1. / mITSROFrame2TPCBin;
344348
mTPCBin2Z = mTPCTBinMUS * mTPCVDrift0;
345349
mZ2TPCBin = 1. / mTPCBin2Z;
@@ -2574,6 +2578,13 @@ void MatchTPCITS::refitABTrack(int ibest) const
25742578
}
25752579
}
25762580

2581+
//______________________________________________
2582+
void MatchTPCITS::setITSROFrameLengthInBC(int nbc)
2583+
{
2584+
mITSROFrameLengthInBC = nbc;
2585+
mITSROFrameLengthMUS = nbc * o2::constants::lhc::LHCBunchSpacingNS * 1e-3;
2586+
}
2587+
25772588
//<<============================= AfterBurner for TPC-track / ITS cluster matching ===================<<
25782589

25792590
#ifdef _ALLOW_DEBUG_TREES_

Detectors/GlobalTrackingWorkflow/src/TPCITSMatchingSpec.cxx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "GlobalTracking/MatchTPCITSParams.h"
3333
#include "ITStracking/IOUtils.h"
3434
#include "DetectorsCommonDataFormats/NameConf.h"
35+
#include "DataFormatsParameters/GRPObject.h"
3536

3637
using namespace o2::framework;
3738
using MCLabelContainer = o2::dataformats::MCTruthContainer<o2::MCCompLabel>;
@@ -47,10 +48,15 @@ void TPCITSMatchingDPL::init(InitContext& ic)
4748
mTimer.Reset();
4849
//-------- init geometry and field --------//
4950
o2::base::GeometryManager::loadGeometry();
50-
o2::base::Propagator::initFieldFromGRP("o2sim_grp.root");
51-
51+
o2::base::Propagator::initFieldFromGRP(o2::base::NameConf::getGRPFileName());
52+
std::unique_ptr<o2::parameters::GRPObject> grp{o2::parameters::GRPObject::loadFrom(o2::base::NameConf::getGRPFileName())};
53+
mMatching.setITSTriggered(!grp->isDetContinuousReadOut(o2::detectors::DetID::ITS));
5254
const auto& alpParams = o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS>::Instance();
53-
mMatching.setITSROFrameLengthMUS(alpParams.roFrameLength / 1.e3); // ITS ROFrame duration in \mus
55+
if (mMatching.isITSTriggered()) {
56+
mMatching.setITSROFrameLengthMUS(alpParams.roFrameLengthTrig / 1.e3); // ITS ROFrame duration in \mus
57+
} else {
58+
mMatching.setITSROFrameLengthInBC(alpParams.roFrameLengthInBC); // ITS ROFrame duration in \mus
59+
}
5460
mMatching.setMCTruthOn(mUseMC);
5561
//
5662
std::string dictPath = ic.options().get<std::string>("its-dictionary-path");

Detectors/ITSMFT/ITS/workflow/src/ClustererSpec.cxx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ void ClustererDPL::init(InitContext& ic)
6666
// settings for the fired pixel overflow masking
6767
const auto& alpParams = o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS>::Instance();
6868
const auto& clParams = o2::itsmft::ClustererParam<o2::detectors::DetID::ITS>::Instance();
69-
mClusterer->setMaxBCSeparationToMask(alpParams.roFrameLength / o2::constants::lhc::LHCBunchSpacingNS + clParams.maxBCDiffToMaskBias);
69+
auto nbc = clParams.maxBCDiffToMaskBias;
70+
nbc += mClusterer->isContinuousReadOut() ? alpParams.roFrameLengthInBC : (alpParams.roFrameLengthTrig / o2::constants::lhc::LHCBunchSpacingNS);
71+
mClusterer->setMaxBCSeparationToMask(nbc);
7072
mClusterer->setMaxRowColDiffToMask(clParams.maxRowColDiffToMask);
7173

7274
std::string dictPath = ic.options().get<std::string>("its-dictionary-path");

Detectors/ITSMFT/MFT/workflow/src/ClustererSpec.cxx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ void ClustererDPL::init(InitContext& ic)
6969
// settings for the fired pixel overflow masking
7070
const auto& alpParams = o2::itsmft::DPLAlpideParam<o2::detectors::DetID::MFT>::Instance();
7171
const auto& clParams = o2::itsmft::ClustererParam<o2::detectors::DetID::MFT>::Instance();
72-
mClusterer->setMaxBCSeparationToMask(alpParams.roFrameLength / o2::constants::lhc::LHCBunchSpacingNS + clParams.maxBCDiffToMaskBias);
72+
auto nbc = clParams.maxBCDiffToMaskBias;
73+
nbc += mClusterer->isContinuousReadOut() ? alpParams.roFrameLengthInBC : (alpParams.roFrameLengthTrig / o2::constants::lhc::LHCBunchSpacingNS);
74+
mClusterer->setMaxBCSeparationToMask(nbc);
7375
mClusterer->setMaxRowColDiffToMask(clParams.maxRowColDiffToMask);
7476

7577
std::string dictPath = ic.options().get<std::string>("mft-dictionary-path");

Detectors/ITSMFT/common/base/include/ITSMFTBase/DPLAlpideParam.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,24 @@ namespace o2
2121
{
2222
namespace itsmft
2323
{
24-
25-
constexpr float DEFROFLength = o2::constants::lhc::LHCOrbitNS / 15; // ROF length, divisor of the orbit
24+
/// allowed values: 1,2,3,4,6,9,11,12,18
25+
constexpr int DEFROFLengthBC = o2::constants::lhc::LHCMaxBunches / 9; // default ROF length in BC for continuos mode
2626
constexpr float DEFStrobeDelay = o2::constants::lhc::LHCBunchSpacingNS * 4; // ~100 ns delay
2727

2828
template <int N>
2929
struct DPLAlpideParam : public o2::conf::ConfigurableParamHelper<DPLAlpideParam<N>> {
3030
static_assert(N == o2::detectors::DetID::ITS || N == o2::detectors::DetID::MFT, "only DetID::ITS orDetID:: MFT are allowed");
31+
static_assert(o2::constants::lhc::LHCMaxBunches % DEFROFLengthBC == 0); // make sure ROF length is divisor of the orbit
3132

3233
static constexpr std::string_view getParamName()
3334
{
3435
return N == o2::detectors::DetID::ITS ? ParamName[0] : ParamName[1];
3536
}
36-
float roFrameLength = DEFROFLength; ///< length of RO frame in ns
37+
int roFrameLengthInBC = DEFROFLengthBC; ///< ROF length in BC for continuos mode
38+
float roFrameLengthTrig = 6000.; ///< length of RO frame in ns for triggered mode
3739
float strobeDelay = DEFStrobeDelay; ///< strobe start (in ns) wrt ROF start
38-
float strobeLength = DEFROFLength - DEFStrobeDelay; ///< length of the strobe in ns (sig. over threshold checked in this window only)
40+
float strobeLengthCont = -1.; ///< if < 0, full ROF length - delay
41+
float strobeLengthTrig = 100.; ///< length of the strobe in ns (sig. over threshold checked in this window only)
3942

4043
// boilerplate stuff + make principal key
4144
O2ParamDef(DPLAlpideParam, getParamName().data());

Detectors/ITSMFT/common/simulation/include/ITSMFTSimulation/DigiParams.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ class DigiParams
5050
void setContinuous(bool v) { mIsContinuous = v; }
5151
bool isContinuous() const { return mIsContinuous; }
5252

53+
int getROFrameLengthInBC() const { return mROFrameLengthInBC; }
54+
void setROFrameLengthInBC(int n) { mROFrameLengthInBC = n; }
55+
5356
void setROFrameLength(float ns);
5457
float getROFrameLength() const { return mROFrameLength; }
5558
float getROFrameLengthInv() const { return mROFrameLengthInv; }
@@ -87,9 +90,10 @@ class DigiParams
8790
static constexpr double infTime = 1e99;
8891
bool mIsContinuous = false; ///< flag for continuous simulation
8992
float mNoisePerPixel = 1.e-7; ///< ALPIDE Noise per chip
90-
float mROFrameLength = DEFROFLength; ///< length of RO frame in ns
91-
float mStrobeDelay = DEFStrobeDelay; ///< strobe start (in ns) wrt ROF start
92-
float mStrobeLength = DEFROFLength - DEFStrobeDelay; ///< length of the strobe in ns (sig. over threshold checked in this window only)
93+
int mROFrameLengthInBC = 0; ///< ROF length in BC for continuos mode
94+
float mROFrameLength = 0; ///< length of RO frame in ns
95+
float mStrobeDelay = 0.; ///< strobe start (in ns) wrt ROF start
96+
float mStrobeLength = 0; ///< length of the strobe in ns (sig. over threshold checked in this window only)
9397
double mTimeOffset = -2 * infTime; ///< time offset (in seconds!) to calculate ROFrame from hit time
9498

9599
int mChargeThreshold = 150; ///< charge threshold in Nelectrons
@@ -105,7 +109,7 @@ class DigiParams
105109
float mROFrameLengthInv = 0; ///< inverse length of RO frame in ns
106110
float mNSimStepsInv = 0; ///< its inverse
107111

108-
ClassDefNV(DigiParams, 1);
112+
ClassDefNV(DigiParams, 2);
109113
};
110114
} // namespace itsmft
111115
} // namespace o2

Detectors/ITSMFT/common/simulation/include/ITSMFTSimulation/Digitizer.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "ITSMFTBase/GeometryTGeo.h"
2828
#include "DataFormatsITSMFT/Digit.h"
2929
#include "DataFormatsITSMFT/ROFRecord.h"
30+
#include "CommonDataFormat/InteractionRecord.h"
3031
#include "SimulationDataFormat/MCCompLabel.h"
3132

3233
namespace o2
@@ -61,8 +62,7 @@ class Digitizer : public TObject
6162

6263
/// Steer conversion of hits to digits
6364
void process(const std::vector<Hit>* hits, int evID, int srcID);
64-
void setEventTime(double t);
65-
double getEventTime() const { return mEventTime; }
65+
void setEventTime(const o2::InteractionTimeRecord& irt);
6666
double getEndTimeOfROFMax() const
6767
{
6868
///< return the time corresponding to end of the last reserved ROFrame : mROFrameMax
@@ -107,8 +107,8 @@ class Digitizer : public TObject
107107
static constexpr float sec2ns = 1e9;
108108

109109
o2::itsmft::DigiParams mParams; ///< digitization parameters
110-
double mEventTime = 0; ///< global event time
111-
bool mContinuous = false; ///< flag for continuous simulation
110+
o2::InteractionTimeRecord mEventTime; ///< global event time and interaction record
111+
double mCollisionTimeWrtROF;
112112
UInt_t mROFrameMin = 0; ///< lowest RO frame of current digits
113113
UInt_t mROFrameMax = 0; ///< highest RO frame of current digits
114114
UInt_t mNewROFrame = 0; ///< ROFrame corresponding to provided time

Detectors/ITSMFT/common/simulation/src/Digitizer.cxx

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ void Digitizer::process(const std::vector<Hit>* hits, int evID, int srcID)
5252
// digitize single event, the time must have been set beforehand
5353

5454
LOG(INFO) << "Digitizing " << mGeometry->getName() << " hits of entry " << evID << " from source "
55-
<< srcID << " at time " << mEventTime + mParams.getTimeOffset() << " (TOff.= "
56-
<< mParams.getTimeOffset() << " ROFrame= " << mNewROFrame << ")"
55+
<< srcID << " at time " << mEventTime << " ROFrame= " << mNewROFrame << ")"
5756
<< " cont.mode: " << isContinuous()
5857
<< " Min/Max ROFrames " << mROFrameMin << "/" << mROFrameMax;
5958

@@ -82,33 +81,29 @@ void Digitizer::process(const std::vector<Hit>* hits, int evID, int srcID)
8281
}
8382

8483
//_______________________________________________________________________
85-
void Digitizer::setEventTime(double t)
84+
void Digitizer::setEventTime(const o2::InteractionTimeRecord& irt)
8685
{
8786
// assign event time in ns
88-
mEventTime = t;
89-
// to randomize the RO phase wrt the event time we use a random offset
90-
if (mParams.isContinuous()) { // in continuous mode we set the offset only in the very beginning
91-
if (!mParams.isTimeOffsetSet()) { // offset is initially at -inf
92-
mParams.setTimeOffset(0); ///*mEventTime + */ mParams.getROFrameLength() * (gRandom->Rndm() - 0.5));
93-
}
94-
} else { // in the triggered mode we start from 0 ROFrame in every event, is this correct?
95-
mParams.setTimeOffset(mEventTime); // + mParams.getROFrameLength() * (gRandom->Rndm() - 0.5));
96-
mROFrameMin = 0; // so we reset the frame counters
87+
mEventTime = irt;
88+
if (!mParams.isContinuous()) {
89+
mROFrameMin = 0; // in triggered mode reset the frame counters
9790
mROFrameMax = 0;
9891
}
99-
100-
mEventTime -= mParams.getTimeOffset(); // subtract common offset
101-
if (mEventTime < 0.) {
102-
mEventTime = 0.;
103-
} else if (mEventTime > UINT_MAX * mParams.getROFrameLength()) {
104-
LOG(FATAL) << "ROFrame for event time " << t << " exceeds allowe maximum " << UINT_MAX;
105-
}
106-
10792
// RO frame corresponding to provided time
108-
mNewROFrame = static_cast<UInt_t>(mEventTime * mParams.getROFrameLengthInv());
93+
mCollisionTimeWrtROF = mEventTime.getTimeOffsetWrtBC();
94+
if (mParams.isContinuous()) {
95+
auto nbc = mEventTime.toLong();
96+
if (mCollisionTimeWrtROF < 0 && nbc > 0) {
97+
nbc--;
98+
}
99+
mNewROFrame = nbc / mParams.getROFrameLengthInBC();
100+
mCollisionTimeWrtROF = mEventTime.timeNS - mNewROFrame * mParams.getROFrameLength();
101+
} else {
102+
mNewROFrame = 0;
103+
}
109104

110105
if (mNewROFrame < mROFrameMin) {
111-
LOG(FATAL) << "New ROFrame (time=" << t << ") precedes currently cashed " << mROFrameMin;
106+
LOG(FATAL) << "New ROFrame (time=" << irt.timeNS << ") precedes currently cashed " << mROFrameMin;
112107
}
113108

114109
if (mParams.isContinuous() && mROFrameMax < mNewROFrame) {
@@ -166,7 +161,11 @@ void Digitizer::fillOutputContainer(UInt_t frameLast)
166161
}
167162
// finalize ROF record
168163
rcROF.setNEntries(mDigits->size() - rcROF.getFirstEntry()); // number of digits
169-
rcROF.getBCData().setFromNS(mROFrameMin * mParams.getROFrameLength() + mParams.getTimeOffset());
164+
if (isContinuous()) {
165+
rcROF.getBCData().setFromLong(mROFrameMin * mParams.getROFrameLengthInBC());
166+
} else {
167+
rcROF.getBCData() = mEventTime; // RSTODO do we need to add trigger delay?
168+
}
170169
if (mROFRecords) {
171170
mROFRecords->push_back(rcROF);
172171
}
@@ -181,33 +180,33 @@ void Digitizer::fillOutputContainer(UInt_t frameLast)
181180
void Digitizer::processHit(const o2::itsmft::Hit& hit, UInt_t& maxFr, int evID, int srcID)
182181
{
183182
// convert single hit to digits
184-
double hTime0 = hit.GetTime() * sec2ns;
185-
if (hTime0 > 20e3) {
183+
float timeInROF = hit.GetTime() * sec2ns;
184+
if (timeInROF > 20e3) {
186185
const int maxWarn = 10;
187186
static int warnNo = 0;
188187
if (warnNo < maxWarn) {
189-
LOG(WARNING) << "Ignoring hit with time_in_event = " << hTime0 << " ns"
188+
LOG(WARNING) << "Ignoring hit with time_in_event = " << timeInROF << " ns"
190189
<< ((++warnNo < maxWarn) ? "" : " (suppressing further warnings)");
191190
}
192191
return;
193192
}
194-
hTime0 += mEventTime; // time from the RO start, in ns
195-
193+
if (isContinuous()) {
194+
timeInROF += mCollisionTimeWrtROF;
195+
}
196196
// calculate RO Frame for this hit
197-
if (hTime0 < 0) {
198-
hTime0 = 0.;
197+
if (timeInROF < 0) {
198+
timeInROF = 0.;
199199
}
200200
float tTot = mParams.getSignalShape().getMaxDuration();
201-
// frame of the hit signal start
202-
UInt_t roFrame = UInt_t(hTime0 * mParams.getROFrameLengthInv());
203-
// frame of the hit signal end: in the triggered mode we read just 1 frame
204-
UInt_t roFrameMax = mParams.isContinuous() ? UInt_t((hTime0 + tTot) * mParams.getROFrameLengthInv()) : roFrame;
205-
int nFrames = roFrameMax + 1 - roFrame;
201+
// frame of the hit signal start wrt event ROFrame
202+
int roFrameRel = int(timeInROF * mParams.getROFrameLengthInv());
203+
// frame of the hit signal end wrt event ROFrame: in the triggered mode we read just 1 frame
204+
UInt_t roFrameRelMax = mParams.isContinuous() ? (timeInROF + tTot) * mParams.getROFrameLengthInv() : roFrameRel;
205+
int nFrames = roFrameRelMax + 1 - roFrameRel;
206+
UInt_t roFrameMax = mNewROFrame + roFrameRelMax;
206207
if (roFrameMax > maxFr) {
207208
maxFr = roFrameMax; // if signal extends beyond current maxFrame, increase the latter
208209
}
209-
// delay of the signal start wrt 1st ROF start
210-
float timeInROF = float(hTime0 - (roFrame * mParams.getROFrameLength()));
211210

212211
// here we start stepping in the depth of the sensor to generate charge diffision
213212
float nStepsInv = mParams.getNSimStepsInv();
@@ -322,7 +321,7 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, UInt_t& maxFr, int evID,
322321
// fire the pixels assuming Poisson(n_response_electrons)
323322
o2::MCCompLabel lbl(hit.GetTrackID(), evID, srcID, false);
324323
auto& chip = mChips[hit.GetDetectorID()];
325-
324+
auto roFrameAbs = mNewROFrame + roFrameRel;
326325
for (int irow = rowSpan; irow--;) {
327326
UShort_t rowIS = irow + rowS;
328327
for (int icol = colSpan; icol--;) {
@@ -337,7 +336,7 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, UInt_t& maxFr, int evID,
337336
}
338337
UShort_t colIS = icol + colS;
339338
//
340-
registerDigits(chip, roFrame, timeInROF, nFrames, rowIS, colIS, nEle, lbl);
339+
registerDigits(chip, roFrameAbs, timeInROF, nFrames, rowIS, colIS, nEle, lbl);
341340
}
342341
}
343342
}

0 commit comments

Comments
 (0)