45 TPCDistributeIDCSpec(
const std::vector<uint32_t>& crus,
const unsigned int timeframes,
const int nTFsBuffer,
const unsigned int outlanes,
const int firstTF, std::shared_ptr<o2::base::GRPGeomRequest> req)
46 : mCRUs{crus}, mTimeFrames{timeframes}, mNTFsBuffer{nTFsBuffer}, mOutLanes{outlanes}, mProcessedCRU{{std::vector<unsigned int>(timeframes), std::vector<unsigned int>(timeframes)}}, mTFStart{{firstTF, firstTF + timeframes}}, mTFEnd{{firstTF + timeframes - 1, mTFStart[1] + timeframes - 1}}, mCCDBRequest(req), mSendCCDBOutputOrbitReset(outlanes), mSendCCDBOutputGRPECS(outlanes)
49 mDataDescrOut.reserve(mOutLanes);
50 for (
unsigned int i = 0;
i < mOutLanes; ++
i) {
51 mDataDescrOut.emplace_back(getDataDescriptionIDC(
i));
55 std::sort(mCRUs.begin(), mCRUs.end());
57 for (
auto& processedCRUbuffer : mProcessedCRUs) {
58 processedCRUbuffer.resize(mTimeFrames);
59 for (
auto& crusMap : processedCRUbuffer) {
60 crusMap.reserve(mCRUs.size());
61 for (
const auto cruID : mCRUs) {
62 crusMap.emplace(cruID,
false);
68 for (
auto side : sides) {
69 const std::string
name = (
side ==
Side::A) ?
"idcsgroupa" :
"idcsgroupc";
109 if (mCCDBRequest->askTime) {
110 const bool grpecsValid = pc.inputs().isValid(
"grpecs");
111 const bool orbitResetValid = pc.inputs().isValid(
"orbitReset");
115 if (orbitResetValid) {
116 pc.inputs().get<std::vector<Long64_t>*>(
"orbitReset");
118 if (pc.inputs().countValidInputs() == (grpecsValid + orbitResetValid)) {
126 if (mTFStart.front() <= -1) {
127 const auto firstTF =
tf;
128 const long offsetTF = std::abs(mTFStart.front() + 1);
129 const auto nTotTFs = getNRealTFs();
130 mTFStart = {firstTF + offsetTF, firstTF + offsetTF + nTotTFs};
131 mTFEnd = {mTFStart[1] - 1, mTFStart[1] - 1 + nTotTFs};
132 LOGP(info,
"Setting {} as first TF", mTFStart[0]);
133 LOGP(info,
"Using offset of {} TFs for setting the first TF", offsetTF);
137 const bool currentBuffer = (
tf > mTFEnd[mBuffer]) ? !mBuffer : mBuffer;
138 if (mTFStart[currentBuffer] >
tf) {
139 LOGP(warning,
"Current TF {} is older than start of currentBuffer {}. Skipping this TF",
tf, mTFStart[currentBuffer]);
143 const unsigned int currentOutLane = getOutLane(
tf);
144 const unsigned int relTF = (
tf - mTFStart[currentBuffer]) / mNTFsBuffer;
145 LOGP(
debug,
"current TF: {} relative TF: {} current buffer: {} current output lane: {} mTFStart: {}",
tf, relTF, currentBuffer, currentOutLane, mTFStart[currentBuffer]);
147 if (relTF >= mProcessedCRU[currentBuffer].
size()) {
148 LOGP(warning,
"Skipping tf {} for lane {}: relative tf {} is larger than size of buffer [{}, {}]: {}",
tf, currentOutLane, relTF, mTFStart[currentBuffer], mTFEnd[currentBuffer], mProcessedCRU[currentBuffer].
size());
151 mProcessedTotalData = mCheckEveryNData;
152 checkIntervalsForMissingData(pc, currentBuffer, relTF, currentOutLane,
tf);
156 if (mProcessedCRU[currentBuffer][relTF] == mCRUs.size()) {
157 LOGP(warning,
"All CRUs for current TF {} (relTF {}, lane {}) already received. Skipping this TF",
tf, relTF, currentOutLane);
162 if (mSendOutputStartInfo[currentBuffer]) {
163 mSendOutputStartInfo[currentBuffer] =
false;
167 if (mSendCCDBOutputOrbitReset[currentOutLane] && mSendCCDBOutputGRPECS[currentOutLane]) {
168 mSendCCDBOutputOrbitReset[currentOutLane] =
false;
169 mSendCCDBOutputGRPECS[currentOutLane] =
false;
174 for (
auto it = inputs.begin(); it != inputs.end(); ++it) {
175 auto const* tpcCRUHeader = o2::framework::DataRefUtils::getHeader<o2::header::DataHeader*>(*it);
176 const unsigned int cru = tpcCRUHeader->subSpecification >> 7;
179 if (!std::binary_search(mCRUs.begin(), mCRUs.end(), cru)) {
180 LOGP(
debug,
"Received data from CRU: {} which was not specified as input. Skipping", cru);
184 if (mProcessedCRUs[currentBuffer][relTF][cru]) {
185 LOGP(warning,
"CRU {} for current TF {} (relTF {}, lane {}) already processed. Skipping ...", cru,
tf, relTF, currentOutLane);
189 ++mProcessedCRU[currentBuffer][relTF];
192 mProcessedCRUs[currentBuffer][relTF][cru] =
true;
196 if (
auto* payloadMsg = it.getPayload()) {
198 }
else [[unlikely]] {
200 LOGP(warning,
"No IDCGROUP payload for CRU {} (TF {}, relTF {}); sending empty IDCAGG{} payload", cru,
tf, relTF, currentOutLane);
201 sendEmptyIDCOutput(pc, currentOutLane, cru);
205 LOGP(info,
"number of received CRUs for current TF: {} Needed a total number of processed CRUs of: {} Current TF: {}", mProcessedCRU[currentBuffer][relTF], mCRUs.size(),
tf);
208 if (mNTFsDataDrop > 0) {
209 checkIntervalsForMissingData(pc, currentBuffer, relTF, currentOutLane,
tf);
212 if (mProcessedCRU[currentBuffer][relTF] == mCRUs.size()) {
213 ++mProcessedTFs[currentBuffer];
216 if (mProcessedTFs[currentBuffer] == mTimeFrames) {
217 finishInterval(pc, currentOutLane, currentBuffer,
tf);