diff --git a/core/data/tof/CbmTofAddress.cxx b/core/data/tof/CbmTofAddress.cxx index 1af204ebf90b631b561c1961a102ee1628f75aa8..0ed83293f27f2576da1de3ffdb02ab3330afa363 100644 --- a/core/data/tof/CbmTofAddress.cxx +++ b/core/data/tof/CbmTofAddress.cxx @@ -31,3 +31,12 @@ const int32_t CbmTofAddress::fgkiModFullIdMask = (((1 << fgkSystemBits) - 1)) + (((1 << fgkSmIdBits) - 1) << fgkSmIdOffset) + (((1 << fgkSmTypeBits) - 1) << fgkSmTypeOffset) + (((1 << fgkRpcIdBits) - 1) << fgkRpcIdOffset) + (((1 << fgkRpcTypeBits) - 1) << fgkRpcTypeOffset); + +const int32_t CbmTofAddress::fgkiRpcFullIdMask = + (((1 << fgkSystemBits) - 1)) + (((1 << fgkSmIdBits) - 1) << fgkSmIdOffset) + + (((1 << fgkSmTypeBits) - 1) << fgkSmTypeOffset) + (((1 << fgkRpcIdBits) - 1) << fgkRpcIdOffset); + +const int32_t CbmTofAddress::fgkiStripFullIdMask = + (((1 << fgkSystemBits) - 1)) + (((1 << fgkSmIdBits) - 1) << fgkSmIdOffset) + + (((1 << fgkSmTypeBits) - 1) << fgkSmTypeOffset) + (((1 << fgkRpcIdBits) - 1) << fgkRpcIdOffset) + + (((1 << fgkChannelIdBits) - 1) << fgkChannelIdOffset); diff --git a/core/data/tof/CbmTofAddress.h b/core/data/tof/CbmTofAddress.h index 7a4d4471b09bbbfd8dc488914c19c588fd5e7a39..f8954d532e759804afcb121c715e7852627fb345 100644 --- a/core/data/tof/CbmTofAddress.h +++ b/core/data/tof/CbmTofAddress.h @@ -13,20 +13,23 @@ ** @version 1.0 ** ** CbmTofAddress is the class for the concrete interfaces to the - ** unique address, which is encoded in a 32-bit field (int32_t), for the + ** unique address, which is encoded in a 32-bit field (int32_t), for the ** ToF detector elements. ** Difference to CbmTofDetectorId is that this class is adapted to ** real data instead of simulated data => no Gap info but instead info ** on strip side. ** Conversion functions are provided for now, but version dependent! + ** + ** Bit table since transition to v21a ** 3 2 1 0 Shift Bits Values ** Current definition: 10987654321098765432109876543210 ** System ID (kTof=6) on bits 0- 3 00000000000000000000000000001111 << 0 4 15 - ** Super Module (SM) on bits 4-11 00000000000000000000111111110000 << 4 8 256 - ** SM Type on bits 12-14 00000000000000001111000000000000 <<12 4 15 - ** RPC ID on bits 16-22 00000000011111110000000000000000 <<16 7 128 - ** Channel Side on bits 23-23 00000000100000000000000000000000 <<23 1 2 - ** Channel ID on bits 24-31 11111111000000000000000000000000 <<24 8 256 + ** Super Module (SM) on bits 4-10 00000000000000000000011111110000 << 4 7 128 + ** SM Type on bits 11-14 00000000000000000111100000000000 <<11 4 15 + ** RPC ID on bits 15-20 00000000000111111000000000000000 <<15 6 64 + ** Channel Side on bits 21-21 00000000001000000000000000000000 <<21 1 2 + ** Channel ID on bits 22-27 00001111110000000000000000000000 <<22 6 64 + ** RPC Type on bits 28-31 11110000000000000000000000000000 <<28 4 16 ** ** Changing the number of bits of a fields automatically shift all others ** => to adapt field length, just change its size and the size of one of the other fields @@ -52,73 +55,83 @@ public: /** Field size accessors **/ /** Number of bits for Super Module Id in the address field - ** @return Number of bits - **/ + ** @return Number of bits + **/ static int32_t GetNofSmIdBits() { return fgkSmIdBits; }; /** Number of bits for Super Module Type in the address field - ** @return Number of bits - **/ + ** @return Number of bits + **/ static int32_t GetNofSmTypeBits() { return fgkSmTypeBits; }; /** Number of bits for Rpc Id in the address field - ** @return Number of bits - **/ + ** @return Number of bits + **/ static int32_t GetNofRpcIdBits() { return fgkRpcIdBits; }; /** Number of bits for Channel Id in the address field - ** @return Number of bits - **/ + ** @return Number of bits + **/ static int32_t GetNofChannelIdBits() { return fgkChannelIdBits; }; /** Number of bits for Channel Side in the address field - ** @return Number of bits - **/ + ** @return Number of bits + **/ static int32_t GetNofChSideBits() { return fgkChannelSideBits; }; /** Maskers **/ /** Get the Super Module Id from the address - ** @param address Unique address - ** @return systemId - **/ + ** @param address Unique address + ** @return systemId + **/ static int32_t GetSmId(uint32_t address) { return ((address >> fgkSmIdOffset) & ((1 << fgkSmIdBits) - 1)); }; /** Get the Super Module Type from the address - ** @param address Unique address - ** @return systemId - **/ + ** @param address Unique address + ** @return systemId + **/ static int32_t GetSmType(uint32_t address) { return ((address >> fgkSmTypeOffset) & ((1 << fgkSmTypeBits) - 1)); }; /** Get the Rpc Id from the address - ** @param address Unique address - ** @return systemId - **/ + ** @param address Unique address + ** @return systemId + **/ static int32_t GetRpcId(uint32_t address) { return ((address >> fgkRpcIdOffset) & ((1 << fgkRpcIdBits) - 1)); }; /** Get the Channel Id from the address - ** @param address Unique address - ** @return systemId - **/ + ** @param address Unique address + ** @return systemId + **/ static int32_t GetChannelId(uint32_t address) { return ((address >> fgkChannelIdOffset) & ((1 << fgkChannelIdBits) - 1)); }; /** Get the Channel Side from the address - ** @param address Unique address - ** @return systemId - **/ + ** @param address Unique address + ** @return systemId + **/ static int32_t GetChannelSide(uint32_t address) { return ((address >> fgkChannelSideOffset) & ((1 << fgkChannelSideBits) - 1)); }; /** Get the module Full Id from the address - ** @param address Unique address - ** @return systemId - **/ + ** @param address Unique address + ** @return systemId + **/ static int32_t GetModFullId(uint32_t address) { return (address & fgkiModFullIdMask); }; + /** Get the detector Full Id (module ID without RPC type) from the address + ** @param address Unique address + ** @return systemId + **/ + static int32_t GetRpcFullId(uint32_t address) { return (address & fgkiRpcFullIdMask); }; + /** Get the strip Full Id from the address + ** @param address Unique address + ** @return systemId + **/ + static int32_t GetStripFullId(uint32_t address) { return (address & fgkiStripFullIdMask); }; /** Builder **/ /** Get the unique address from all parameters - ** @param[in] Sm Super Module Id. - ** @param[in] Rpc Rpc Id. - ** @param[in] Channel Channel Id. - ** @param[in] Side Channel Side (optional, used for strips). - ** @param[in] Sm Type Super Module Type (optional). - ** @return address - **/ + ** @param[in] Sm Super Module Id. + ** @param[in] Rpc Rpc Id. + ** @param[in] Channel Channel Id. + ** @param[in] Side Channel Side (optional, used for strips). + ** @param[in] Sm Type Super Module Type (optional). + ** @return address + **/ static uint32_t GetUniqueAddress(uint32_t Sm, uint32_t Rpc, uint32_t Channel, uint32_t Side = 0, uint32_t SmType = 0, uint32_t RpcType = 0) { @@ -159,9 +172,9 @@ public: private: /** - ** To adapt the address sub-fields repartition in size, - ** you just need to change number of bits of the two sub-fields changing length. - **/ + ** To adapt the address sub-fields repartition in size, + ** you just need to change number of bits of the two sub-fields changing length. + **/ /** Sub-fields sizes in bits **/ @@ -194,9 +207,9 @@ private: // Number of bits for Rpc Type in the address field static const int32_t fgkRpcTypeBits = 4; /** - ** To adapt the address sub-fields repartition in order, - ** you just need to change the way the offset are calculated. - **/ + ** To adapt the address sub-fields repartition in order, + ** you just need to change the way the offset are calculated. + **/ /** Sub-fields offsets in bits **/ /** Offset in bits for Super Module Id in the address field **/ @@ -213,9 +226,19 @@ private: static const int32_t fgkRpcTypeOffset; /** - ** For the module Full Id determination - **/ + ** For the module Full Id determination + **/ static const int32_t fgkiModFullIdMask; + + /** + ** For the RPC Full Id determination (ignore RPC type and side) + **/ + static const int32_t fgkiRpcFullIdMask; + + /** + ** For the detector strip Id determination (ignore RPC type and side) + **/ + static const int32_t fgkiStripFullIdMask; }; #endif // CBMTOFADDRESS_H diff --git a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx index 6e1ca1adae7e17b3407c44500c7214c699f9af5c..da1397bf84a52067d267edb764ba635b504dabdf 100644 --- a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx +++ b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx @@ -374,6 +374,47 @@ void CbmAlgoBuildRawEvents::CheckSeed(Double_t dSeedTime, UInt_t uSeedDigiIdx) CheckTriggerCondition(dSeedTime); } +//---------------------------------------------------------------------- +/// Specialization of the GetDigi variants has to happen before first usage + +template<> +const CbmStsDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi) +{ + return &((*fStsDigis)[uDigi]); +} +template<> +const CbmMuchBeamTimeDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi) +{ + return &((*fMuchBeamTimeDigis)[uDigi]); +} +template<> +const CbmMuchDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi) +{ + return &((*fMuchDigis)[uDigi]); +} +template<> +const CbmTrdDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi) +{ + return &((*fTrdDigis)[uDigi]); +} +template<> +const CbmTofDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi) +{ + return &((*fTofDigis)[uDigi]); +} +template<> +const CbmRichDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi) +{ + return &((*fRichDigis)[uDigi]); +} +template<> +const CbmPsdDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi) +{ + return &((*fPsdDigis)[uDigi]); +} + +//---------------------------------------------------------------------- + void CbmAlgoBuildRawEvents::SearchMatches(Double_t dSeedTime, RawEventBuilderDetector& detMatch) { switch (detMatch.detId) { @@ -566,14 +607,104 @@ Bool_t CbmAlgoBuildRawEvents::CheckTriggerConditions(CbmEvent* event, RawEventBu return kFALSE; } - /// Check trigger rejection by maximal number - else if (0 < det.fiTriggerMaxDigis && det.fiTriggerMaxDigis < iNbDigis) { + /// Check trigger rejection by maximal number (if enabled) + if (0 < det.fiTriggerMaxDigis && det.fiTriggerMaxDigis < iNbDigis) { LOG(debug2) << "Event Has too many digis: " << iNbDigis << " vs " << det.fiTriggerMaxDigis << " for " << det.sName; return kFALSE; } - else { - return kTRUE; + + /// Check trigger rejection by minimal number of fired layers (if enabled) + if (0 < det.fuTriggerMinLayers) { + switch (det.detId) { + case ECbmModuleId::kSts: { + LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => Fired layers check not implemented yet for " + << det.sName; + return kFALSE; + break; + } + case ECbmModuleId::kMuch: { + LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => Fired layers check not implemented yet for " + << det.sName; + return kFALSE; + break; + } + case ECbmModuleId::kTrd2d: // Same data storage as trd 1d + case ECbmModuleId::kTrd: { + LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => Fired layers check not implemented yet for " + << det.sName; + return kFALSE; + break; + } + case ECbmModuleId::kTof: { + /// check for requested number of different counters + /// loop over tof digis and count different RPCs + std::set<uint32_t> setRpcs; // Use set instead of vector as search by value later + std::map<uint32_t, int> mStrips; + std::map<uint32_t, int>::iterator it; + + for (int idigi = 0; idigi < iNbDigis; ++idigi) { + uint idx = event->GetIndex(det.dataType, idigi); + const CbmTofDigi* pDigi = GetDigi<CbmTofDigi>(idx); + if (nullptr == pDigi) continue; + + int iAddr = pDigi->GetAddress(); + int iStripAddr = CbmTofAddress::GetStripFullId(iAddr); + int iRpcAddr = CbmTofAddress::GetRpcFullId(iAddr); + + std::map<uint32_t, int>::iterator itStrip = mStrips.find(iStripAddr); + if (itStrip == mStrips.end()) { + // LOG(info) << Form("Found new strip 0x%08x, side %u", iStripAddr, pDigi->GetSide()); + mStrips[iStripAddr] = (int) pDigi->GetSide(); // extend map + } + else { + // LOG(info) << Form("Check side %u of strip 0x%08x: %d ?", pDigi->GetSide(), iStripAddr, itStrip->second); + if ((int) pDigi->GetSide() == (1 - itStrip->second)) { + /// Found other end => full strip, insert into counter vector + auto itRpc = setRpcs.find(iRpcAddr); + if (itRpc == setRpcs.end()) { + // LOG(info) << Form("Add counter 0x%08x ", iRpcAddr); + setRpcs.insert(iRpcAddr); + } + } + } + } + // LOG(info) << "Found " << setRpcs.size() << " Tof RPCs, " << " in " << iNbDigis << " Tof digis"; + if (setRpcs.size() < det.fuTriggerMinLayers) { + LOG(debug2) << "Event does not have enough RPCs fired: " << setRpcs.size() << " vs " << det.fuTriggerMinLayers + << " for " << det.sName; + return kFALSE; + } + break; + } + case ECbmModuleId::kRich: { + LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => Fired layers check not implemented yet for " + << det.sName; + return kFALSE; + break; + } + case ECbmModuleId::kPsd: { + LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => Fired layers check not implemented yet for " + << det.sName; + return kFALSE; + break; + } + case ECbmModuleId::kT0: { + LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => Fired layers check not implemented yet for " + << det.sName; + return kFALSE; + break; + } + default: { + LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => Fired layers check not implemented yet for " + << det.sName; + return kFALSE; + break; + } + } } + + /// All checks passed, event is good + return kTRUE; } //---------------------------------------------------------------------- @@ -659,42 +790,6 @@ UInt_t CbmAlgoBuildRawEvents::GetNofDigis(ECbmModuleId detId) } } -template<> -const CbmStsDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi) -{ - return &((*fStsDigis)[uDigi]); -} -template<> -const CbmMuchBeamTimeDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi) -{ - return &((*fMuchBeamTimeDigis)[uDigi]); -} -template<> -const CbmMuchDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi) -{ - return &((*fMuchDigis)[uDigi]); -} -template<> -const CbmTrdDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi) -{ - return &((*fTrdDigis)[uDigi]); -} -template<> -const CbmTofDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi) -{ - return &((*fTofDigis)[uDigi]); -} -template<> -const CbmRichDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi) -{ - return &((*fRichDigis)[uDigi]); -} -template<> -const CbmPsdDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi) -{ - return &((*fPsdDigis)[uDigi]); -} - //---------------------------------------------------------------------- void CbmAlgoBuildRawEvents::CreateHistograms() { @@ -1090,7 +1185,7 @@ void CbmAlgoBuildRawEvents::SetReferenceDetector(RawEventBuilderDetector refDetI for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) { if ((*det) == refDetIn) { LOG(warning) << "CbmAlgoBuildRawEvents::SetReferenceDetector => " - "Reference detector already in selection detector list!" + "Reference detector already in selection detector list! " << refDetIn.sName; LOG(warning) << " => " "It will be automatically removed from selection detector list!"; @@ -1112,7 +1207,7 @@ void CbmAlgoBuildRawEvents::SetReferenceDetector(RawEventBuilderDetector refDetI LOG(warning) << " => " "You may want to use AddDetector after this command to add in " "selection " - << refDetIn.sName; + << fRefDet.sName; LOG(warning) << " => " "Please also remember to update the selection windows!"; } @@ -1209,6 +1304,28 @@ void CbmAlgoBuildRawEvents::SetTriggerMaxNumber(ECbmModuleId selDet, Int_t iVal) << selDet; } +void CbmAlgoBuildRawEvents::SetTriggerMinLayersNumber(ECbmModuleId selDet, UInt_t uVal) +{ + /// Check first if reference detector + if (fRefDet.detId == selDet) { + fRefDet.fuTriggerMinLayers = uVal; + LOG(debug) << "Set Trigger min fired layers limit for " << fRefDet.sName << " to " << uVal; + return; + } + + /// Loop on selection detectors + for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) { + if ((*det).detId == selDet) { + (*det).fuTriggerMinLayers = uVal; + LOG(debug) << "Set Trigger min fired layers limit for " << (*det).sName << " to " << uVal; + return; + } + } + LOG(warning) << "CbmAlgoBuildRawEvents::SetTriggerMinLayersNumber => " + "Doing nothing, detector neither reference nor in selection list!" + << selDet; +} + void CbmAlgoBuildRawEvents::SetTriggerWindow(ECbmModuleId selDet, Double_t dWinBeg, Double_t dWinEnd) { /// Check if valid time window: end strictly after beginning diff --git a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h index cd9892df6711ef1f74985e8279f152e115728e60..1309b0d296b9c4b80bfdcc957954ee3d065e01a4 100644 --- a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h +++ b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h @@ -57,13 +57,15 @@ public: } RawEventBuilderDetector(ECbmModuleId detIdIn, ECbmDataType dataTypeIn, std::string sNameIn, UInt_t uTriggerMinDigisIn, - Int_t iTriggerMaxDigisIn, Double_t fdTimeWinBegIn, Double_t fdTimeWinEndIn) + Int_t iTriggerMaxDigisIn, Double_t fdTimeWinBegIn, Double_t fdTimeWinEndIn, + UInt_t uTriggerMinLayersIn = 0) : RawEventBuilderDetector(detIdIn, dataTypeIn, sNameIn) { - fuTriggerMinDigis = uTriggerMinDigisIn; - fiTriggerMaxDigis = iTriggerMaxDigisIn; - fdTimeWinBeg = fdTimeWinBegIn; - fdTimeWinEnd = fdTimeWinEndIn; + fuTriggerMinDigis = uTriggerMinDigisIn; + fiTriggerMaxDigis = iTriggerMaxDigisIn; + fuTriggerMinLayers = uTriggerMinLayersIn; + fdTimeWinBeg = fdTimeWinBegIn; + fdTimeWinEnd = fdTimeWinEndIn; } bool operator==(const RawEventBuilderDetector& other) const { return (other.detId == this->detId); } @@ -75,10 +77,12 @@ public: ECbmModuleId detId = ECbmModuleId::kNotExist; ECbmDataType dataType = ECbmDataType::kUnknown; std::string sName = "Invalid"; - /// Minimum number of T0 digis needed to generate a trigger, 0 means don't use for trigger generation + /// Minimum number of digis per detector needed to generate an event, 0 means do not use for event selection UInt_t fuTriggerMinDigis = 0; - /// Maximum number of digis per detector to generate an event, -1 means no cut, 0 means anti-coinc trigger + /// Maximum number of digis per detector needed to generate an event, -1 means no cut, 0 means anti-coinc trigger Int_t fiTriggerMaxDigis = -1; + /// Minimum number of fired layers needed to generate an event, 0 means do not require for event selection + UInt_t fuTriggerMinLayers = 0; /// Selection Window Double_t fdTimeWinBeg = -100; Double_t fdTimeWinEnd = 100; @@ -148,6 +152,7 @@ public: void SetTriggerMinNumber(ECbmModuleId selDet, UInt_t uVal); void SetTriggerMaxNumber(ECbmModuleId selDet, Int_t iVal); + void SetTriggerMinLayersNumber(ECbmModuleId selDet, UInt_t uVal); void SetTriggerWindow(ECbmModuleId selDet, Double_t dWinBeg, Double_t dWinEnd); void SetTsParameters(Double_t dTsStartTime, Double_t dTsLength, Double_t dTsOverLength)