Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@ class PHOSL1phaseCalibDevice
{
o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj);
}
void sendCCDB(DataAllocator& outputs);

private:
unsigned long mRunStartTime = 0; /// start time of the run (ms)
int mPrevCalibration = -1; /// calibration produced so far, -1: not yet
int mNprocessed = 0; /// number of TFs processed so far
int minStatisticsForCalib = 100000; /// minimal statistics to try to calculate calibration
std::unique_ptr<o2::phos::PHOSL1phaseCalibrator> mCalibrator; /// Agregator of calibration TimeFrameSlots
std::shared_ptr<o2::base::GRPGeomRequest> mCCDBRequest;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class PHOSL1phaseSlot
void clear();

void addMeanRms(std::array<std::array<float, 4>, 14>& sumMean, std::array<std::array<float, 4>, 14>& sumRMS, std::array<float, 14>& sumNorm);
void addQcHistos(std::array<unsigned int, 1400> (&sum)[4]);
void addQcHistos(std::array<unsigned int, 1400> (&sum)[5]);

void setRunStartTime(long tf) { mRunStartTime = tf; }

Expand Down Expand Up @@ -81,7 +81,7 @@ class PHOSL1phaseCalibrator final : public o2::calibration::TimeSlotCalibration<
void endOfStream();

int getCalibration() { return mL1phase; }
std::array<unsigned int, 1400>& getQcHistos() { return mQcHisto[0]; }
std::array<unsigned int, 1400>& getQcHistos() { return mQcHisto[4]; }

private:
static constexpr int mDDL = 14; /// Number of PHOS DDLs
Expand All @@ -90,9 +90,9 @@ class PHOSL1phaseCalibrator final : public o2::calibration::TimeSlotCalibration<
std::array<std::array<float, 4>, mDDL> mMean; /// Collected RMS
std::array<float, mDDL> mNorm; /// Normalization
int mL1phase = 0; /// Final calibration
std::array<unsigned int, 1400> mQcHisto[4]; ///! Histograms for QC
std::array<unsigned int, 1400> mQcHisto[5]; ///! Histograms for QC

ClassDefOverride(PHOSL1phaseCalibrator, 2);
ClassDefOverride(PHOSL1phaseCalibrator, 3);
};

} // namespace phos
Expand Down
37 changes: 32 additions & 5 deletions Detectors/PHOS/calib/src/PHOSL1phaseCalibDevice.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,46 @@ void PHOSL1phaseCalibDevice::run(o2::framework::ProcessingContext& pc)
auto cellTR = pc.inputs().get<gsl::span<TriggerRecord>>("cellTR");
LOG(detail) << "Processing TF with " << cells.size() << " cells and " << cellTR.size() << " TrigRecords";
mCalibrator->process(tfcounter, cells, cellTR);

++mNprocessed;
// If sufficient statistics was collected, try to calculate L1phases
// If statistics reached N*thresholds try to re-calculate L1phases
// if they changed wrt previous, replace ccdb object, otherwise do nothing
if (mNprocessed % minStatisticsForCalib == 0) {
minStatisticsForCalib *= 2;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that you update the calibration not at N*trhesholds but at 2^(N-1) * thresholds. Why do you need to minStatisticsForCalib *= 2; after each update?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L1 object is unique for whole run. Normally it should be calculated from minimal threshold. If in the run we have noisy channels, I think it is better to collect considerably more statistics before next try. This should reduce the number of overlapped objects in ccdb.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, thanks, though then the comment about N*thresholds is somewhat misleading...

mCalibrator->checkSlotsToFinalize(o2::calibration::INFINITE_TF);
mCalibrator->endOfStream();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to be sure: mCalibrator->endOfStream() does not really mean endOfStream, but just to finalize the calibration for the next portion of TFs, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, mCalibrator::endOfStream() calculates calibrations but does not reset anything.

if (mPrevCalibration != mCalibrator->getCalibration()) {
mPrevCalibration = mCalibrator->getCalibration();
// send this version of calibration to replace old one
sendCCDB(pc.outputs());
}
}
}

void PHOSL1phaseCalibDevice::endOfStream(o2::framework::EndOfStreamContext& ec)
{
mCalibrator->checkSlotsToFinalize(o2::calibration::INFINITE_TF);
mCalibrator->endOfStream();

// try to re-calculate L1phases. If they was not calculated yet, or
// they changed wrt previous, replace ccdb object, otherwise do nothing

if (mRunStartTime == 0 || mCalibrator->getCalibration() == 0) { // run not started || calibration was not produced
return; // do not create CCDB object
}
// already uploaded, no need to repeat
if (mPrevCalibration == mCalibrator->getCalibration()) {
return;
}
mPrevCalibration = mCalibrator->getCalibration();
sendCCDB(ec.outputs());
}
void PHOSL1phaseCalibDevice::sendCCDB(DataAllocator& outputs)
{

std::vector<int> l1phase{mCalibrator->getCalibration()};
LOG(info) << "End of stream reached, sending output to CCDB";
std::vector<int> l1phase{mPrevCalibration};
LOG(info) << "Sending L1phase to CCDB";
// prepare all info to be sent to CCDB
auto flName = o2::ccdb::CcdbApi::generateFileName("L1phase");
std::map<std::string, std::string> md;
Expand All @@ -67,11 +94,11 @@ void PHOSL1phaseCalibDevice::endOfStream(o2::framework::EndOfStreamContext& ec)
<< " bytes, valid for " << info.getStartValidityTimestamp()
<< " : " << info.getEndValidityTimestamp();

ec.outputs().snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "PHOS_L1phase", 0}, *image.get());
ec.outputs().snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "PHOS_L1phase", 0}, info);
outputs.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "PHOS_L1phase", 0}, *image.get());
outputs.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "PHOS_L1phase", 0}, info);
// Send summary to QC
LOG(info) << "Sending histos to QC ";
ec.outputs().snapshot(o2::framework::Output{"PHS", "L1PHASEHISTO", 0}, mCalibrator->getQcHistos());
outputs.snapshot(o2::framework::Output{"PHS", "L1PHASEHISTO", 0}, mCalibrator->getQcHistos());
}

o2::framework::DataProcessorSpec o2::phos::getPHOSL1phaseCalibDeviceSpec()
Expand Down
32 changes: 15 additions & 17 deletions Detectors/PHOS/calib/src/PHOSL1phaseCalibrator.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ void PHOSL1phaseSlot::addMeanRms(std::array<std::array<float, 4>, 14>& sumMean,
sumNorm[d] += mNorm[d];
}
}
void PHOSL1phaseSlot::addQcHistos(std::array<unsigned int, 1400> (&sum)[4])
void PHOSL1phaseSlot::addQcHistos(std::array<unsigned int, 1400> (&sum)[5])
{
for (int bc = 4; bc--;) {
for (int it = 1400; it--;) {
Expand Down Expand Up @@ -181,7 +181,6 @@ void PHOSL1phaseCalibrator::finalizeSlot(Slot& slot)
{
// Extract results for the single slot
PHOSL1phaseSlot* ct = slot.getContainer();
LOG(info) << "Finalize slot " << slot.getTFStart() << " <= TF <= " << slot.getTFEnd();
ct->addMeanRms(mMean, mRMS, mNorm);
ct->addQcHistos(mQcHisto);
ct->clear();
Expand Down Expand Up @@ -224,29 +223,29 @@ void PHOSL1phaseCalibrator::endOfStream()
}
float minMean = 0, minRMS = 0, subminRMS = 0;
for (int b = 0; b < 4; b++) {
mMean[d][b] /= mNorm[d];
mRMS[d][b] /= mNorm[d];
mRMS[d][b] -= mMean[d][b] * mMean[d][b];
mMean[d][b] = abs(mMean[d][b]);
float av = mMean[d][b] / mNorm[d];
float avRMS = mRMS[d][b] / mNorm[d] - av * av;
av = abs(av);

if (b == 0) {
minRMS = mRMS[d][b];
minMean = mMean[d][b];
minRMS = avRMS;
minMean = av;
} else {
if (minRMS > mRMS[d][b]) {
if (minRMS > avRMS) {
subminRMS = minRMS;
minRMS = mRMS[d][b];
minRMS = avRMS;
iMinRMS = b;
} else {
if (subminRMS == 0) {
subminRMS = mRMS[d][b];
subminRMS = avRMS;
} else {
if (mRMS[d][b] < subminRMS) {
subminRMS = mRMS[d][b];
if (avRMS < subminRMS) {
subminRMS = avRMS;
}
}
}
if (minMean > mMean[d][b]) {
minMean = mMean[d][b];
if (minMean > av) {
minMean = av;
iMinMean = b;
}
}
Expand All @@ -262,10 +261,9 @@ void PHOSL1phaseCalibrator::endOfStream()
}
if (bestB != 0) { // copy the histogram content to final histo
for (int it = 100; it--;) {
mQcHisto[0][d * 100 + it] = mQcHisto[bestB][d * 100 + it];
mQcHisto[4][d * 100 + it] = mQcHisto[bestB][d * 100 + it];
}
}
mL1phase |= (bestB << (2 * d));
}
LOG(info) << "Calculated L1phase=" << mL1phase;
}