Skip to content

Commit 64f5566

Browse files
authored
[QC-429] Require nOrbitPerTF at each update by TFID (#1843)
because it is not accessible during initialization.
1 parent c704271 commit 64f5566

8 files changed

Lines changed: 53 additions & 58 deletions

File tree

Framework/include/QualityControl/Timekeeper.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const static TimeframeIdRange gInvalidTimeframeIdRange{
3737
class Timekeeper
3838
{
3939
public:
40-
explicit Timekeeper(uint64_t nOrbitsPerTF);
40+
Timekeeper();
4141
virtual ~Timekeeper() = default;
4242

4343
/// \brief sets activity (run) duration
@@ -50,7 +50,7 @@ class Timekeeper
5050
/// \brief updates the validity based on the provided timestamp (ms since epoch)
5151
virtual void updateByCurrentTimestamp(validity_time_t timestampMs) = 0;
5252
/// \brief updates the validity based on the provided TF ID
53-
virtual void updateByTimeFrameID(uint32_t tfID) = 0;
53+
virtual void updateByTimeFrameID(uint32_t tfID, uint64_t nOrbitsPerTF) = 0;
5454

5555
/// \brief resets the state of the mCurrent* counters
5656
virtual void reset() = 0;
@@ -71,8 +71,6 @@ class Timekeeper
7171
ValidityInterval mCurrentValidityTimespan = gInvalidValidityInterval; // since the last reset time until `update()` call
7272
ValidityInterval mCurrentSampleTimespan = gInvalidValidityInterval; // since the last reset
7373
TimeframeIdRange mCurrentTimeframeIdRange = gInvalidTimeframeIdRange; // since the last reset
74-
75-
uint64_t mNOrbitsPerTF = 0;
7674
};
7775

7876
} // namespace o2::quality_control::core

Framework/include/QualityControl/TimekeeperAsynchronous.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ namespace o2::quality_control::core
2525
class TimekeeperAsynchronous : public Timekeeper
2626
{
2727
public:
28-
explicit TimekeeperAsynchronous(uint64_t nOrbitsPerTF, validity_time_t windowLengthMs = 0);
28+
explicit TimekeeperAsynchronous(validity_time_t windowLengthMs = 0);
2929
~TimekeeperAsynchronous() = default;
3030

3131
void updateByCurrentTimestamp(validity_time_t timestampMs) override;
32-
void updateByTimeFrameID(uint32_t tfID) override;
32+
void updateByTimeFrameID(uint32_t tfID, uint64_t nOrbitsPerTF) override;
3333
void reset() override;
3434

3535
protected:

Framework/include/QualityControl/TimekeeperSynchronous.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ namespace o2::quality_control::core
2525
class TimekeeperSynchronous : public Timekeeper
2626
{
2727
public:
28-
explicit TimekeeperSynchronous(uint64_t nOrbitsPerTF);
28+
TimekeeperSynchronous();
2929
~TimekeeperSynchronous() = default;
3030

3131
void updateByCurrentTimestamp(validity_time_t timestampMs) override;
32-
void updateByTimeFrameID(uint32_t tfID) override;
32+
void updateByTimeFrameID(uint32_t tfID, uint64_t nOrbitsPerTF) override;
3333

3434
void reset() override;
3535

Framework/src/TaskRunner.cxx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,9 @@ void TaskRunner::init(InitContext& iCtx)
167167
// fixme: use DataTakingContext.deployment once we can get it during initialization
168168
// fixme: use DataTakingContext.nOrbitsPerTF once we can get it during initialization
169169
if (mTaskConfig.fallbackActivity.mProvenance == "qc") {
170-
mTimekeeper = std::make_shared<TimekeeperSynchronous>(32);
170+
mTimekeeper = std::make_shared<TimekeeperSynchronous>();
171171
} else {
172-
mTimekeeper = std::make_shared<TimekeeperAsynchronous>(32);
172+
mTimekeeper = std::make_shared<TimekeeperAsynchronous>();
173173
}
174174

175175
// setup user's task
@@ -213,7 +213,7 @@ void TaskRunner::run(ProcessingContext& pCtx)
213213
auto [dataReady, timerReady] = validateInputs(pCtx.inputs());
214214

215215
if (dataReady) {
216-
mTimekeeper->updateByTimeFrameID(pCtx.services().get<TimingInfo>().tfCounter);
216+
mTimekeeper->updateByTimeFrameID(pCtx.services().get<TimingInfo>().tfCounter, pCtx.services().get<DataTakingContext>().nOrbitsPerTF);
217217
mTask->monitorData(pCtx);
218218
updateMonitoringStats(pCtx);
219219
}

Framework/src/Timekeeper.cxx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,8 @@
2121
namespace o2::quality_control::core
2222
{
2323

24-
Timekeeper::Timekeeper(uint64_t nOrbitsPerTF)
25-
: mNOrbitsPerTF(nOrbitsPerTF)
24+
Timekeeper::Timekeeper()
2625
{
27-
if (nOrbitsPerTF == 0) {
28-
ILOG(Warning, Support) << "nOrbitsPerTF was set to 0, object validity may be incorrectly marked" << ENDM;
29-
}
3026
}
3127

3228
void Timekeeper::setActivityDuration(ValidityInterval validity)

Framework/src/TimekeeperAsynchronous.cxx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
namespace o2::quality_control::core
2323
{
2424

25-
TimekeeperAsynchronous::TimekeeperAsynchronous(uint64_t nOrbitsPerTF, validity_time_t windowLengthMs)
26-
: Timekeeper(nOrbitsPerTF), mWindowLengthMs(windowLengthMs)
25+
TimekeeperAsynchronous::TimekeeperAsynchronous(validity_time_t windowLengthMs)
26+
: Timekeeper(), mWindowLengthMs(windowLengthMs)
2727
{
2828
}
2929

@@ -32,7 +32,7 @@ void TimekeeperAsynchronous::updateByCurrentTimestamp(validity_time_t timestampM
3232
// async QC should ignore current timestamp
3333
}
3434

35-
void TimekeeperAsynchronous::updateByTimeFrameID(uint32_t tfid)
35+
void TimekeeperAsynchronous::updateByTimeFrameID(uint32_t tfid, uint64_t nOrbitsPerTF)
3636
{
3737
// fixme: We might want to use this once we know how to get orbitResetTime:
3838
// std::ceil((timingInfo.firstTForbit * o2::constants::lhc::LHCOrbitNS / 1000 + orbitResetTime) / 1000);
@@ -50,7 +50,7 @@ void TimekeeperAsynchronous::updateByTimeFrameID(uint32_t tfid)
5050
return;
5151
}
5252

53-
auto tfDurationMs = constants::lhc::LHCOrbitNS / 1000000 * mNOrbitsPerTF;
53+
auto tfDurationMs = constants::lhc::LHCOrbitNS / 1000000 * nOrbitsPerTF;
5454
auto tfStart = static_cast<validity_time_t>(mActivityDuration.getMin() + tfDurationMs * (tfid - 1));
5555
auto tfEnd = static_cast<validity_time_t>(mActivityDuration.getMin() + tfDurationMs * tfid - 1);
5656
mCurrentSampleTimespan.update(tfStart);

Framework/src/TimekeeperSynchronous.cxx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
namespace o2::quality_control::core
2323
{
2424

25-
TimekeeperSynchronous::TimekeeperSynchronous(uint64_t nOrbitsPerTF) : Timekeeper(nOrbitsPerTF)
25+
TimekeeperSynchronous::TimekeeperSynchronous() : Timekeeper()
2626
{
2727
}
2828

@@ -32,7 +32,7 @@ void TimekeeperSynchronous::updateByCurrentTimestamp(validity_time_t timestampMs
3232
mActivityDuration.update(timestampMs);
3333
}
3434

35-
void TimekeeperSynchronous::updateByTimeFrameID(uint32_t tfid)
35+
void TimekeeperSynchronous::updateByTimeFrameID(uint32_t tfid, uint64_t nOrbitsPerTF)
3636
{
3737
if (tfid == 0) {
3838
if (!mWarnedAboutTfIdZero) {
@@ -56,7 +56,7 @@ void TimekeeperSynchronous::updateByTimeFrameID(uint32_t tfid)
5656
// fixme: We might want to use this once we know how to get orbitResetTime:
5757
// std::ceil((timingInfo.firstTForbit * o2::constants::lhc::LHCOrbitNS / 1000 + orbitResetTime) / 1000);
5858
// Until then, we use a less precise method:
59-
auto tfDuration = constants::lhc::LHCOrbitNS / 1000000 * mNOrbitsPerTF;
59+
auto tfDuration = constants::lhc::LHCOrbitNS / 1000000 * nOrbitsPerTF;
6060
auto tfStart = mActivityDuration.getMin() + tfDuration * (tfid - 1);
6161
auto tfEnd = tfStart + tfDuration - 1;
6262
mCurrentSampleTimespan.update(tfStart);

Framework/test/testTimekeeper.cxx

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ TEST_CASE("timekeeper_synchronous")
2828
{
2929
SECTION("defaults")
3030
{
31-
auto tk = std::make_shared<TimekeeperSynchronous>(32);
31+
auto tk = std::make_shared<TimekeeperSynchronous>();
3232
CHECK(tk->getValidity() == gInvalidValidityInterval);
3333
CHECK(tk->getSampleTimespan() == gInvalidValidityInterval);
3434
CHECK(tk->getTimerangeIdRange() == gInvalidTimeframeIdRange);
@@ -41,8 +41,8 @@ TEST_CASE("timekeeper_synchronous")
4141

4242
SECTION("one_data_point_no_timer")
4343
{
44-
auto tk = std::make_shared<TimekeeperSynchronous>(32);
45-
tk->updateByTimeFrameID(5);
44+
auto tk = std::make_shared<TimekeeperSynchronous>();
45+
tk->updateByTimeFrameID(5, 32);
4646

4747
CHECK(tk->getValidity() == gInvalidValidityInterval);
4848
CHECK(tk->getSampleTimespan() == gInvalidValidityInterval);
@@ -56,7 +56,7 @@ TEST_CASE("timekeeper_synchronous")
5656

5757
SECTION("no_data_one_timer")
5858
{
59-
auto tk = std::make_shared<TimekeeperSynchronous>(32);
59+
auto tk = std::make_shared<TimekeeperSynchronous>();
6060
tk->updateByCurrentTimestamp(1653000000000);
6161

6262
CHECK(tk->getValidity() == ValidityInterval{ 1653000000000, 1653000000000 });
@@ -71,9 +71,9 @@ TEST_CASE("timekeeper_synchronous")
7171

7272
SECTION("one_data_point_sor_timer")
7373
{
74-
auto tk = std::make_shared<TimekeeperSynchronous>(32);
74+
auto tk = std::make_shared<TimekeeperSynchronous>();
7575
tk->setActivityDuration(ValidityInterval{ 1653000000000, 1653000000000 });
76-
tk->updateByTimeFrameID(5);
76+
tk->updateByTimeFrameID(5, 32);
7777

7878
CHECK(tk->getValidity() == gInvalidValidityInterval);
7979
// we need at least one update with timestamp for a valid validity
@@ -85,9 +85,9 @@ TEST_CASE("timekeeper_synchronous")
8585

8686
SECTION("one_data_point_one_timer")
8787
{
88-
auto tk = std::make_shared<TimekeeperSynchronous>(32);
88+
auto tk = std::make_shared<TimekeeperSynchronous>();
8989
tk->updateByCurrentTimestamp(1653000000000);
90-
tk->updateByTimeFrameID(5);
90+
tk->updateByTimeFrameID(5, 32);
9191

9292
CHECK(tk->getValidity() == ValidityInterval{ 1653000000000, 1653000000000 });
9393
CHECK(tk->getSampleTimespan() == ValidityInterval{ 1653000000011, 1653000000013 });
@@ -101,7 +101,7 @@ TEST_CASE("timekeeper_synchronous")
101101

102102
SECTION("no_data_many_timers")
103103
{
104-
auto tk = std::make_shared<TimekeeperSynchronous>(32);
104+
auto tk = std::make_shared<TimekeeperSynchronous>();
105105
tk->updateByCurrentTimestamp(1655000000000);
106106
tk->updateByCurrentTimestamp(1656000000000);
107107
tk->updateByCurrentTimestamp(1654000000000); // a timer from the past is rather unexpected, but it should not break anything
@@ -119,12 +119,12 @@ TEST_CASE("timekeeper_synchronous")
119119

120120
SECTION("many_data_points_many_timers")
121121
{
122-
auto tk = std::make_shared<TimekeeperSynchronous>(32);
122+
auto tk = std::make_shared<TimekeeperSynchronous>();
123123
tk->updateByCurrentTimestamp(1653000000000);
124-
tk->updateByTimeFrameID(5);
125-
tk->updateByTimeFrameID(7);
126-
tk->updateByTimeFrameID(3);
127-
tk->updateByTimeFrameID(10);
124+
tk->updateByTimeFrameID(5, 32);
125+
tk->updateByTimeFrameID(7, 32);
126+
tk->updateByTimeFrameID(3, 32);
127+
tk->updateByTimeFrameID(10, 32);
128128
tk->updateByCurrentTimestamp(1653500000000);
129129

130130
CHECK(tk->getValidity() == ValidityInterval{ 1653000000000, 1653500000000 });
@@ -136,8 +136,8 @@ TEST_CASE("timekeeper_synchronous")
136136
CHECK(tk->getSampleTimespan() == gInvalidValidityInterval);
137137
CHECK(tk->getTimerangeIdRange() == gInvalidTimeframeIdRange);
138138

139-
tk->updateByTimeFrameID(12);
140-
tk->updateByTimeFrameID(54);
139+
tk->updateByTimeFrameID(12, 32);
140+
tk->updateByTimeFrameID(54, 32);
141141
tk->updateByCurrentTimestamp(1653600000000);
142142

143143
CHECK(tk->getValidity() == ValidityInterval{ 1653500000000, 1653600000000 });
@@ -147,7 +147,7 @@ TEST_CASE("timekeeper_synchronous")
147147

148148
SECTION("boundary_selection")
149149
{
150-
auto tk = std::make_shared<TimekeeperSynchronous>(32);
150+
auto tk = std::make_shared<TimekeeperSynchronous>();
151151

152152
// ECS first
153153
tk->setStartOfActivity(1, 2, 3);
@@ -181,7 +181,7 @@ TEST_CASE("timekeeper_asynchronous")
181181
{
182182
SECTION("defaults")
183183
{
184-
auto tk = std::make_shared<TimekeeperAsynchronous>(32);
184+
auto tk = std::make_shared<TimekeeperAsynchronous>();
185185
CHECK(tk->getValidity() == gInvalidValidityInterval);
186186
CHECK(tk->getSampleTimespan() == gInvalidValidityInterval);
187187
CHECK(tk->getTimerangeIdRange() == gInvalidTimeframeIdRange);
@@ -194,7 +194,7 @@ TEST_CASE("timekeeper_asynchronous")
194194

195195
SECTION("timers_have_no_effect")
196196
{
197-
auto tk = std::make_shared<TimekeeperAsynchronous>(32);
197+
auto tk = std::make_shared<TimekeeperAsynchronous>();
198198
tk->setActivityDuration(ValidityInterval{ 1653000000000, 1655000000000 });
199199
CHECK(tk->getValidity() == gInvalidValidityInterval);
200200
tk->updateByCurrentTimestamp(1654000000000);
@@ -203,16 +203,16 @@ TEST_CASE("timekeeper_asynchronous")
203203

204204
SECTION("sor_eor_not_set")
205205
{
206-
auto tk = std::make_shared<TimekeeperAsynchronous>(32);
206+
auto tk = std::make_shared<TimekeeperAsynchronous>();
207207
// duration not set
208-
tk->updateByTimeFrameID(1234);
208+
tk->updateByTimeFrameID(1234, 32);
209209
CHECK(tk->getValidity() == gInvalidValidityInterval);
210210
CHECK(tk->getSampleTimespan() == gInvalidValidityInterval);
211211
CHECK(tk->getTimerangeIdRange() == gInvalidTimeframeIdRange);
212212

213213
// sor set, not eor - not enough
214214
tk->setActivityDuration(ValidityInterval{ 1653000000000, 0 });
215-
tk->updateByTimeFrameID(1234);
215+
tk->updateByTimeFrameID(1234, 32);
216216
CHECK(tk->getValidity() == gInvalidValidityInterval);
217217
CHECK(tk->getSampleTimespan() == gInvalidValidityInterval);
218218
CHECK(tk->getTimerangeIdRange() == gInvalidTimeframeIdRange);
@@ -226,11 +226,11 @@ TEST_CASE("timekeeper_asynchronous")
226226

227227
SECTION("data_no_moving_window")
228228
{
229-
auto tk = std::make_shared<TimekeeperAsynchronous>(32);
229+
auto tk = std::make_shared<TimekeeperAsynchronous>();
230230
tk->setActivityDuration(ValidityInterval{ 1653000000000, 1655000000000 });
231231

232-
tk->updateByTimeFrameID(3);
233-
tk->updateByTimeFrameID(10);
232+
tk->updateByTimeFrameID(3, 32);
233+
tk->updateByTimeFrameID(10, 32);
234234
CHECK(tk->getValidity() == ValidityInterval{ 1653000000000, 1655000000000 });
235235
CHECK(tk->getSampleTimespan() == ValidityInterval{ 1653000000005, 1653000000027 });
236236
CHECK(tk->getTimerangeIdRange() == TimeframeIdRange{ 3, 10 });
@@ -240,8 +240,8 @@ TEST_CASE("timekeeper_asynchronous")
240240
CHECK(tk->getSampleTimespan() == gInvalidValidityInterval);
241241
CHECK(tk->getTimerangeIdRange() == gInvalidTimeframeIdRange);
242242

243-
tk->updateByTimeFrameID(12);
244-
tk->updateByTimeFrameID(54);
243+
tk->updateByTimeFrameID(12, 32);
244+
tk->updateByTimeFrameID(54, 32);
245245
CHECK(tk->getValidity() == ValidityInterval{ 1653000000000, 1655000000000 });
246246
CHECK(tk->getSampleTimespan() == ValidityInterval{ 1653000000031, 1653000000152 });
247247
CHECK(tk->getTimerangeIdRange() == TimeframeIdRange{ 12, 54 });
@@ -250,43 +250,44 @@ TEST_CASE("timekeeper_asynchronous")
250250
SECTION("data_moving_window")
251251
{
252252
// for "simplicity" assuming TF length of 11246 orbits, which gives us 1.0005 second TF duration
253-
auto tk = std::make_shared<TimekeeperAsynchronous>(11246, 30 * 1000);
253+
const auto nOrbitPerTF = 11246;
254+
auto tk = std::make_shared<TimekeeperAsynchronous>(30 * 1000);
254255
tk->setActivityDuration(ValidityInterval{ 1653000000000, 1653000095000 }); // 95 seconds: 0-30, 30-60, 60-95
255256

256257
// hitting only the 1st window
257-
tk->updateByTimeFrameID(1);
258-
tk->updateByTimeFrameID(10);
258+
tk->updateByTimeFrameID(1, nOrbitPerTF);
259+
tk->updateByTimeFrameID(10, nOrbitPerTF);
259260
CHECK(tk->getValidity() == ValidityInterval{ 1653000000000, 1653000030000 });
260261
CHECK(tk->getSampleTimespan() == ValidityInterval{ 1653000000000, 1653000009999 });
261262
CHECK(tk->getTimerangeIdRange() == TimeframeIdRange{ 1, 10 });
262263

263264
// hitting the 1st and 2nd window
264265
tk->reset();
265-
tk->updateByTimeFrameID(1);
266-
tk->updateByTimeFrameID(55);
266+
tk->updateByTimeFrameID(1, nOrbitPerTF);
267+
tk->updateByTimeFrameID(55, nOrbitPerTF);
267268
CHECK(tk->getValidity() == ValidityInterval{ 1653000000000, 1653000060000 });
268269
CHECK(tk->getSampleTimespan() == ValidityInterval{ 1653000000000, 1653000055001 });
269270
CHECK(tk->getTimerangeIdRange() == TimeframeIdRange{ 1, 55 });
270271

271272
// hitting the 3rd, extended window in the main part.
272273
// there is no 4th window, since we merge the last two to avoid having the last one with too little statistics
273274
tk->reset();
274-
tk->updateByTimeFrameID(80);
275+
tk->updateByTimeFrameID(80, nOrbitPerTF);
275276
CHECK(tk->getValidity() == ValidityInterval{ 1653000060000, 1653000095000 });
276277
CHECK(tk->getSampleTimespan() == ValidityInterval{ 1653000079003, 1653000080002 });
277278
CHECK(tk->getTimerangeIdRange() == TimeframeIdRange{ 80, 80 });
278279

279280
// hitting the 3rd window with a sample which is in the extended part.
280281
tk->reset();
281-
tk->updateByTimeFrameID(93);
282+
tk->updateByTimeFrameID(93, nOrbitPerTF);
282283
CHECK(tk->getValidity() == ValidityInterval{ 1653000060000, 1653000095000 });
283284
CHECK(tk->getSampleTimespan() == ValidityInterval{ 1653000092004, 1653000093003 });
284285
CHECK(tk->getTimerangeIdRange() == TimeframeIdRange{ 93, 93 });
285286
}
286287

287288
SECTION("boundary_selection")
288289
{
289-
auto tk = std::make_shared<TimekeeperAsynchronous>(32);
290+
auto tk = std::make_shared<TimekeeperAsynchronous>();
290291

291292
// ECS first
292293
tk->setStartOfActivity(1, 2, 3);

0 commit comments

Comments
 (0)