diff --git a/Detectors/EMCAL/base/include/EMCALBase/Geometry.h b/Detectors/EMCAL/base/include/EMCALBase/Geometry.h index c6e58ceb7cbea..3a46d049c989e 100644 --- a/Detectors/EMCAL/base/include/EMCALBase/Geometry.h +++ b/Detectors/EMCAL/base/include/EMCALBase/Geometry.h @@ -501,6 +501,21 @@ class Geometry /// \throw InvalidCellIDException if cell ID does not exist math_utils::Point3D RelPosCellInSModule(Int_t absId) const; + /// \brief Get link ID, row and column from cell ID, have a look here: https://alice.its.cern.ch/jira/browse/EMCAL-660 + /// \param towerID Cell ID + /// \return link ID + /// \return row + /// \return col + std::tuple getOnlineID(int towerID); + + /// \brief Temporary link assignment (till final link assignment is known - + /// \brief eventually taken from CCDB) + /// \brief Current mapping can be found under https://alice.its.cern.ch/jira/browse/EMCAL-660 + /// \param ddlID DDL ID + /// \return CRORC ID + /// \return CRORC Link + std::tuple getLinkAssignment(int ddlID) const { return std::make_tuple(mCRORCID[ddlID / 2], mCRORCLink[ddlID]); }; + std::vector GetEMCSystem() const { return mEMCSMSystem; } // EMC System, SM type list // Local Coordinates of SM std::vector GetCentersOfCellsEtaDir() const @@ -670,6 +685,9 @@ class Geometry Float_t mSteelFrontThick; ///< Thickness of the front stell face of the support box - 9-sep-04; obsolete? + std::array mCRORCID = {110, 112, 110, 112, 110, 112, 111, 113, 111, 113, 111, 113, 114, 116, 114, 116, 115, 117, 115, 117}; // CRORC ID w.r.t SM + std::array mCRORCLink = {0, 1, 0, 1, 2, 3, 2, 3, 4, 5, 4, 5, 0, 1, 0, 1, 2, 3, 2, 3, 4, -1, 4, 5, 0, 1, 0, 1, 2, 3, 2, 3, 0, 1, 0, 1, 2, 3, 2, -1}; // CRORC limk w.r.t FEE ID + mutable const TGeoHMatrix* SMODULEMATRIX[EMCAL_MODULES]; ///< Orientations of EMCAL super modules std::vector> mCellIndexLookup; ///< Lookup table for cell indices diff --git a/Detectors/EMCAL/base/src/Geometry.cxx b/Detectors/EMCAL/base/src/Geometry.cxx index 239abb334e42d..6f0a00b9bdfdf 100644 --- a/Detectors/EMCAL/base/src/Geometry.cxx +++ b/Detectors/EMCAL/base/src/Geometry.cxx @@ -1762,3 +1762,28 @@ std::tuple Geometry::GetPhiBoundariesOfSMGap(Int_t nPhiSec) cons } return std::make_tuple(mPhiBoundariesOfSM[2 * nPhiSec + 1], mPhiBoundariesOfSM[2 * nPhiSec + 2]); } + +std::tuple Geometry::getOnlineID(int towerID) +{ + auto cellindex = GetCellIndex(towerID); + auto supermoduleID = std::get<0>(cellindex); + auto etaphi = GetCellPhiEtaIndexInSModule(supermoduleID, std::get<1>(cellindex), std::get<2>(cellindex), std::get<3>(cellindex)); + auto etaphishift = ShiftOfflineToOnlineCellIndexes(supermoduleID, std::get<0>(etaphi), std::get<1>(etaphi)); + int row = std::get<0>(etaphishift), col = std::get<1>(etaphishift); + + int ddlInSupermoudel = -1; + if (0 <= row && row < 8) { + ddlInSupermoudel = 0; // first cable row + } else if (8 <= row && row < 16 && 0 <= col && col < 24) { + ddlInSupermoudel = 0; // first half; + } else if (8 <= row && row < 16 && 24 <= col && col < 48) { + ddlInSupermoudel = 1; // second half; + } else if (16 <= row && row < 24) { + ddlInSupermoudel = 1; // third cable row + } + if (supermoduleID % 2 == 1) { + ddlInSupermoudel = 1 - ddlInSupermoudel; // swap for odd=C side, to allow us to cable both sides the same + } + + return std::make_tuple(supermoduleID * 2 + ddlInSupermoudel, row, col); +} diff --git a/Detectors/EMCAL/simulation/include/EMCALSimulation/RawWriter.h b/Detectors/EMCAL/simulation/include/EMCALSimulation/RawWriter.h index 9c2864d2eebb3..c60f9197d0803 100644 --- a/Detectors/EMCAL/simulation/include/EMCALSimulation/RawWriter.h +++ b/Detectors/EMCAL/simulation/include/EMCALSimulation/RawWriter.h @@ -35,7 +35,6 @@ namespace emcal { class Geometry; - struct AltroBunch { int mStarttime; std::vector mADCs; @@ -104,11 +103,9 @@ class RawWriter protected: std::vector findBunches(const std::vector& channelDigits); - std::tuple getOnlineID(int towerID); - std::tuple getLinkAssignment(int ddlID); ChannelHeader createChannelHeader(int hardwareAddress, int payloadSize, bool isBadChannel); - std::vector createRCUTrailer(int payloadsize, int feca, int fecb, double timesample, uint64_t triggertime); + std::vector createRCUTrailer(int payloadsize, double timesample, uint64_t triggertime, int feeID); std::vector encodeBunchData(const std::vector& data); private: diff --git a/Detectors/EMCAL/simulation/src/RawWriter.cxx b/Detectors/EMCAL/simulation/src/RawWriter.cxx index 456b3ff8499a1..20265d275b7b1 100644 --- a/Detectors/EMCAL/simulation/src/RawWriter.cxx +++ b/Detectors/EMCAL/simulation/src/RawWriter.cxx @@ -24,13 +24,31 @@ void RawWriter::init() { mRawWriter = std::make_unique(o2::header::gDataOriginEMC, false); mRawWriter->setCarryOverCallBack(this); + + // initialize mappers + if (!mMappingHandler) { + mMappingHandler = std::make_unique(); + } + for (auto iddl = 0; iddl < 40; iddl++) { // For EMCAL set // - FEE ID = DDL ID // - C-RORC and link increasing with DDL ID // @TODO replace with link assignment on production FLPs, // eventually storing in CCDB - auto [crorc, link] = getLinkAssignment(iddl); + + // initialize containers for SRU + SRUDigitContainer srucont; + srucont.mSRUid = iddl; + mSRUdata.push_back(srucont); + + // Skip empty links with these ddl IDs, + // ddl ID 21 and 39 are empty links, while 23 and 36 are connected to LEDmon only + if (iddl == 21 || iddl == 22 || iddl == 36 || iddl == 39) { + continue; + } + + auto [crorc, link] = mGeometry->getLinkAssignment(iddl); std::string rawfilename = mOutputLocation; switch (mFileFor) { case FileFor_t::kFullDet: @@ -51,17 +69,6 @@ void RawWriter::init() } mRawWriter->registerLink(iddl, crorc, link, 0, rawfilename.data()); } - // initialize mappers - if (!mMappingHandler) { - mMappingHandler = std::make_unique(); - } - - // initialize containers for SRU - for (auto isru = 0; isru < 40; isru++) { - SRUDigitContainer srucont; - srucont.mSRUid = isru; - mSRUdata.push_back(srucont); - } } void RawWriter::digitsToRaw(gsl::span digitsbranch, gsl::span triggerbranch) @@ -86,7 +93,7 @@ bool RawWriter::processTrigger(const o2::emcal::TriggerRecord& trg) if (tower > 20000) { std::cout << "Wrong cell ID " << tower << std::endl; } - auto onlineindices = getOnlineID(tower); + auto onlineindices = mGeometry->getOnlineID(tower); int sruID = std::get<0>(onlineindices); auto towerdata = mSRUdata[sruID].mChannels.find(tower); if (towerdata == mSRUdata[sruID].mChannels.end()) { @@ -115,6 +122,10 @@ bool RawWriter::processTrigger(const o2::emcal::TriggerRecord& trg) std::vector payload; // this must be initialized per SRU, becuase pages are per SRU, therefore the payload was not reset. + if (srucont.mSRUid == 21 || srucont.mSRUid == 22 || srucont.mSRUid == 36 || srucont.mSRUid == 39) { + continue; + } + for (const auto& [tower, channel] : srucont.mChannels) { // Find out hardware address of the channel auto hwaddress = mMappingHandler->getMappingForDDL(srucont.mSRUid).getHardwareAddress(channel.mRow, channel.mCol, ChannelType_t::HIGH_GAIN); // @TODO distinguish between high- and low-gain cells @@ -159,14 +170,14 @@ bool RawWriter::processTrigger(const o2::emcal::TriggerRecord& trg) } // Create RCU trailer - auto trailerwords = createRCUTrailer(payload.size() / 4, 16, 16, 100., trg.getBCData().toLong()); + auto trailerwords = createRCUTrailer(payload.size() / 4, 100., trg.getBCData().toLong(), srucont.mSRUid); for (auto word : trailerwords) { payload.emplace_back(word); } // register output data auto ddlid = srucont.mSRUid; - auto [crorc, link] = getLinkAssignment(ddlid); + auto [crorc, link] = mGeometry->getLinkAssignment(ddlid); LOG(DEBUG1) << "Adding payload with size " << payload.size() << " (" << payload.size() / 4 << " ALTRO words)"; mRawWriter->addData(ddlid, crorc, link, 0, trg.getBCData(), payload, false, trg.getTriggerBits()); } @@ -212,39 +223,6 @@ std::vector RawWriter::findBunches(const std::vector RawWriter::getOnlineID(int towerID) -{ - auto cellindex = mGeometry->GetCellIndex(towerID); - auto supermoduleID = std::get<0>(cellindex); - auto etaphi = mGeometry->GetCellPhiEtaIndexInSModule(supermoduleID, std::get<1>(cellindex), std::get<2>(cellindex), std::get<3>(cellindex)); - auto etaphishift = mGeometry->ShiftOfflineToOnlineCellIndexes(supermoduleID, std::get<0>(etaphi), std::get<1>(etaphi)); - int row = std::get<0>(etaphishift), col = std::get<1>(etaphishift); - - int ddlInSupermoudel = -1; - if (0 <= row && row < 8) { - ddlInSupermoudel = 0; // first cable row - } else if (8 <= row && row < 16 && 0 <= col && col < 24) { - ddlInSupermoudel = 0; // first half; - } else if (8 <= row && row < 16 && 24 <= col && col < 48) { - ddlInSupermoudel = 1; // second half; - } else if (16 <= row && row < 24) { - ddlInSupermoudel = 1; // third cable row - } - if (supermoduleID % 2 == 1) { - ddlInSupermoudel = 1 - ddlInSupermoudel; // swap for odd=C side, to allow us to cable both sides the same - } - - return std::make_tuple(supermoduleID * 2 + ddlInSupermoudel, row, col); -} - -std::tuple RawWriter::getLinkAssignment(int ddlID) -{ - // Temporary link assignment (till final link assignment is known - - // eventually taken from CCDB) - // - Link (0-5) and C-RORC ID linear with ddlID - return std::make_tuple(ddlID / 6, ddlID % 6); -} - std::vector RawWriter::encodeBunchData(const std::vector& data) { std::vector encoded; @@ -286,13 +264,31 @@ ChannelHeader RawWriter::createChannelHeader(int hardwareAddress, int payloadSiz return header; } -std::vector RawWriter::createRCUTrailer(int payloadsize, int feca, int fecb, double timesample, uint64_t triggertime) +std::vector RawWriter::createRCUTrailer(int payloadsize, double timesample, uint64_t triggertime, int feeID) { RCUTrailer trailer; - trailer.setActiveFECsA(feca); - trailer.setActiveFECsB(fecb); trailer.setPayloadSize(payloadsize); trailer.setTimeSamplePhaseNS(triggertime, timesample); + + // You can find details about these settings here https://alice.its.cern.ch/jira/browse/EMCAL-650 + trailer.setRCUID(feeID); + trailer.setFirmwareVersion(2); + trailer.setActiveFECsA(0x0); + trailer.setActiveFECsB(0x1); + trailer.setBaselineCorrection(0); + trailer.setPolarity(false); + trailer.setNumberOfPresamples(0); + trailer.setNumberOfPostsamples(0); + trailer.setSecondBaselineCorrection(false); + trailer.setGlitchFilter(0); + trailer.setNumberOfNonZeroSuppressedPostsamples(1); + trailer.setNumberOfNonZeroSuppressedPresamples(1); + trailer.setNumberOfPretriggerSamples(0); + trailer.setNumberOfSamplesPerChannel(15); + trailer.setZeroSuppression(true); + trailer.setSparseReadout(true); + trailer.setNumberOfAltroBuffers(RCUTrailer::BufferMode_t::NBUFFERS4); + auto trailerwords = trailer.encode(); std::vector encoded(trailerwords.size() * sizeof(uint32_t)); memcpy(encoded.data(), trailerwords.data(), trailerwords.size() * sizeof(uint32_t));