Skip to content

Commit

Permalink
[EMCAL-916, EMCAL-537, EMCAL-550, EMCAL-911] Integrate TRU decoding i…
Browse files Browse the repository at this point in the history
…nto sync reco

- EMCAL-916: Add decoding of TRU data (FastORs and patch index)
- EMCAL-911: Add handling of TRU data in RecoContainer
- Provide helper classes for TRU- and FastOR decoding including
  the calculation of the L0timesum
- EMCAL-537: Provide data structure for patches, TRUs and
  Timesums
- EMCAL-550: Integration into RecoWorkflow: Output channels
  and option to disable trigger reconstruction
  • Loading branch information
mfasDa authored and jokonig committed Apr 21, 2024
1 parent 78f6192 commit d08d21a
Show file tree
Hide file tree
Showing 18 changed files with 978 additions and 88 deletions.
1 change: 1 addition & 0 deletions DataFormats/Detectors/EMCAL/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ o2_add_library(DataFormatsEMCAL
src/ErrorTypeFEE.cxx
src/CellLabel.cxx
src/ClusterLabel.cxx
src/CompressedTriggerData.cxx
PUBLIC_LINK_LIBRARIES O2::CommonDataFormat
O2::Headers
O2::MathUtils
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
#ifndef ALICEO2_EMCAL_COMPRESSEDTRIGGERDATA_H
#define ALICEO2_EMCAL_COMPRESSEDTRIGGERDATA_H

#include <cstdint>
#include <iosfwd>

namespace o2::emcal
{

/// \struct CompressedTRU
/// \brief Compressed reconstructed TRU information
/// \ingroup EMCALDataFormat
struct CompressedTRU {
uint8_t mTRUIndex; ///< TRU index
uint8_t mTriggerTime; ///< Trigger time of the TRU
bool mFired; ///< Fired status of the TRU
uint8_t mNumberOfPatches; ///< Number of patches found for the TRU
};

/// \struct CompressedTriggerPatch
/// \brief Compressed reconstructed L0 trigger patch information
/// \ingroup EMCALDataFormat
struct CompressedTriggerPatch {
uint8_t mTRUIndex; ///< Index of the TRU where the trigger patch has been found
uint8_t mPatchIndexInTRU; ///< Index of the trigger patch in the TRU
uint8_t mTime; ///< Reconstructed time of the trigger patch
uint16_t mADC; ///< ADC sum of the trigger patch
};

/// \struct CompressedL0TimeSum
/// \brief Compressed L0 timesum information
/// \ingroup EMCALDataFormat
struct CompressedL0TimeSum {
uint16_t mIndex; ///< Absolute ID of the FastOR
uint16_t mTimesum; ///< ADC value of the time-sum (4-integral)
};

/// \brief Output stream operator of the CompressedTRU
/// \param stream Stream to write to
/// \param tru TRU data to be streamed
/// \return Stream after writing
std::ostream& operator<<(std::ostream& stream, const CompressedTRU& tru);

/// \brief Output stream operator of the CompressedTriggerPatch
/// \param stream Stream to write to
/// \param patch Trigger patch to be streamed
/// \return Stream after writing
std::ostream& operator<<(std::ostream& stream, const CompressedTriggerPatch& patch);

/// \brief Output stream operator of the CompressedL0TimeSum
/// \param stream Stream to write to
/// \param timesum FastOR L0 timesum to be streamed
/// \return Stream after writing
std::ostream& operator<<(std::ostream& stream, const CompressedL0TimeSum& timesum);

} // namespace o2::emcal

#endif // ALICEO2_EMCAL_COMPRESSEDTRIGGERDATA_H
31 changes: 31 additions & 0 deletions DataFormats/Detectors/EMCAL/src/CompressedTriggerData.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

#include <iostream>
#include "DataFormatsEMCAL/CompressedTriggerData.h"

std::ostream& o2::emcal::operator<<(std::ostream& stream, const o2::emcal::CompressedTRU& tru)
{
stream << "TRU " << tru.mTRUIndex << ": Fired " << (tru.mFired ? "yes" : "no") << ", time " << (tru.mFired ? std::to_string(static_cast<int>(tru.mTriggerTime)) : "Undefined") << ", number of patches " << tru.mNumberOfPatches;
return stream;
}

std::ostream& o2::emcal::operator<<(std::ostream& stream, const o2::emcal::CompressedTriggerPatch& patch)
{
stream << "Patch " << patch.mPatchIndexInTRU << " in TRU " << patch.mTRUIndex << ": Time " << patch.mTime << ", ADC " << patch.mADC;
return stream;
}

std::ostream& o2::emcal::operator<<(std::ostream& stream, const o2::emcal::CompressedL0TimeSum& timesum)
{
stream << "FastOR " << timesum.mIndex << ": " << timesum.mTimesum << " ADC counts";
return stream;
}
1 change: 1 addition & 0 deletions Detectors/EMCAL/base/include/EMCALBase/TriggerMappingV2.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class TriggerMappingV2
static constexpr unsigned int FASTORSPHI = (5 * FASTORSPHISM) + (1 * FASTORSPHISM / 3) /*EMCAL*/
+ (3 * FASTORSPHISM) + (1 * FASTORSPHISM / 3) /*DCAL */; ///< Number of FastOR/EMCALs in Phi
static constexpr unsigned int ALLFASTORS = FASTORSETA * FASTORSPHI; ///< Number of FastOR/EMCALs
static constexpr unsigned int PATCHESINTRU = 77;

//********************************************
// Index types
Expand Down
2 changes: 1 addition & 1 deletion Detectors/EMCAL/base/src/TriggerMappingV2.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ TriggerMappingV2::IndexTRU TriggerMappingV2::getTRUIndexFromOnlineHardareAddree(

unsigned short branch = (hardwareAddress >> 11) & 0x1; // 0/1

IndexTRU truIndex = ((ddlID << 1) | branch) - 1; // 0..2
IndexTRU truIndex = (((ddlID % 2) << 1) | branch) - 1; // 0..2

truIndex = (supermoduleID % 2) ? 2 - truIndex : truIndex;

Expand Down
4 changes: 4 additions & 0 deletions Detectors/EMCAL/reconstruction/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ o2_add_library(EMCALReconstruction
src/AltroDecoder.cxx
src/Bunch.cxx
src/Channel.cxx
src/FastORTimeSeries.cxx
src/RecoParam.cxx
src/RawDecodingError.cxx
src/STUDecoderError.cxx
Expand All @@ -32,6 +33,7 @@ o2_add_library(EMCALReconstruction
src/CTFCoder.cxx
src/CTFHelper.cxx
src/StuDecoder.cxx
src/TRUDataHandler.cxx
PUBLIC_LINK_LIBRARIES O2::Headers
AliceO2::InfoLogger
O2::DataFormatsEMCAL
Expand All @@ -49,6 +51,7 @@ o2_target_root_dictionary(
include/EMCALReconstruction/RawPayload.h
include/EMCALReconstruction/Bunch.h
include/EMCALReconstruction/Channel.h
include/EMCALReconstruction/FastORTimeSeries.h
include/EMCALReconstruction/CaloFitResults.h
include/EMCALReconstruction/CaloRawFitter.h
include/EMCALReconstruction/CaloRawFitterStandard.h
Expand All @@ -59,6 +62,7 @@ o2_target_root_dictionary(
include/EMCALReconstruction/DigitReader.h
include/EMCALReconstruction/RecoParam.h
include/EMCALReconstruction/StuDecoder.h
include/EMCALReconstruction/TRUDataHandler.h
)

o2_add_executable(rawreader-file
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
#ifndef ALICEO2_EMCAL_FASTORTIMESERIES_H
#define ALICEO2_EMCAL_FASTORTIMESERIES_H

#include <vector>
#include <gsl/span>
#include "Rtypes.h"

namespace o2::emcal
{

/// \class FastORTimeSeries
/// \brief Container for FastOR time series
/// \author Markus Fasel <[email protected]>, Oak Ridge National Laboratory
/// \ingroup EMCALReconstruction
/// \since April 19, 2024
///
/// Time series are encoded in bunches in the raw data, which are usually time-reversed.
/// The FastORTimeSeries handles the time series of all bunches in the readout window,
/// in proper future-direction time order, correcting the time-reversal from the Fake-ALTRO.
/// Consequently the ADC samples are expected in time-reversed format. The function
/// calculateL1TimeSum calculates the timesum of the timeseries as 4-integral with respect to
/// a given L0 time, which is expected at the end of the time integration range.
class FastORTimeSeries
{
public:
/// @brief Dummy constructor
FastORTimeSeries() = default;

/// \brief Construcor
/// \param maxsamples Maximum number of time samples
/// \param timesamples Time-reversed raw ADC samples
/// \param starttime Start time
FastORTimeSeries(int maxsamples, const gsl::span<const uint16_t> timesamples, uint8_t starttime)
{
setSize(maxsamples);
fillReversed(timesamples, starttime);
}

/// \brief Destructor
~FastORTimeSeries() = default;

void setTimeSamples(const gsl::span<const uint16_t> timesamples, uint8_t starttime) { fillReversed(timesamples, starttime); }

/// \brief Calculate L0 timesum (4-integral of the ADC series) with respect to a given L0 time
/// \param l0time L0 time (end of the time series)
/// \return Timesum of the time series
uint16_t calculateL1TimeSum(uint8_t l0time) const;

/// \brief Access raw ADC values (in forward time order)
/// \return ADC values of the time series in forward time order
const gsl::span<const uint16_t> getADCs() const { return mTimeSamples; }

/// \brief Clear ADC samples in the time series
void clear();

private:
/// \brief Set the container size for the ADC samples
/// \param maxsamples Max. amount of samples to be handled
void setSize(int maxsamples);

/// \brief Fill the internal time samples in proper time order
/// \param timesamples Time-reversed time samples
/// \param starttime Start time
void fillReversed(const gsl::span<const uint16_t> timesamples, uint8_t starttime);

std::vector<uint16_t> mTimeSamples; ///< Raw ADC time samples (in forward time order)

ClassDef(FastORTimeSeries, 1);
};

} // namespace o2::emcal

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
/// \author Markus Fasel <[email protected]>, Oak Ridge National Laboratory
/// \since May 30, 2023

#include <array>
#include <cstdint>
#include <exception>
#include <iosfwd>
#include <string>
#include <tuple>
#include <unordered_map>
Expand All @@ -24,6 +26,9 @@
#include <Rtypes.h>
#include <CommonDataFormat/InteractionRecord.h>
#include <DataFormatsEMCAL/Cell.h>
#include <EMCALBase/TriggerMappingV2.h>
#include <EMCALReconstruction/FastORTimeSeries.h>
#include <EMCALReconstruction/TRUDataHandler.h>

namespace o2::emcal
{
Expand Down Expand Up @@ -53,6 +58,36 @@ struct RecCellInfo {
class EventContainer
{
public:
/// \class TRUIndexException
/// \brief Handler for access of TRU data with invalid TRU index
/// \ingroup EMCALReconstruction
class TRUIndexException final : public std::exception
{
public:
/// \brief Constructor
/// \param index TRU index raising the exception
TRUIndexException(std::size_t index);

/// \brief Destructor
~TRUIndexException() noexcept final = default;

/// \brief Get the error message of the exception
/// \return Error message
const char* what() const noexcept final { return mMessage.data(); }

/// \brief Get the TRU index raising the exception
/// \return TRU index
std::size_t getIndex() const { return mIndex; }

/// \brief Print error message on stream
/// \param stream Stream to print on
void printStream(std::ostream& stream) const;

private:
std::size_t mIndex; ///< TRU index raising the exception
std::string mMessage; ///< Buffer for error message
};

/// \brief Constructor
EventContainer() = default;

Expand Down Expand Up @@ -95,6 +130,22 @@ class EventContainer
/// \return Number of LEDMONs
int getNumberOfLEDMONs() const { return mLEDMons.size(); }

/// \brief Read and write access TRU data of a given TRU
/// \param truIndex Index of the TRU
/// \return TRU data handler for the TRU
/// \throw TRUIndexException in case the TRU index is invalid (>= 52)
TRUDataHandler& getTRUData(std::size_t truIndex);

/// \brief Read-only access TRU data of a given TRU
/// \param truIndex Index of the TRU
/// \return TRU data handler for the TRU
/// \throw TRUIndexException in case the TRU index is invalid (>= 52)
const TRUDataHandler& readTRUData(std::size_t truIndex) const;

/// \brief Access to container with FastOR time series
/// \return Container with time series
const std::unordered_map<uint16_t, FastORTimeSeries>& getTimeSeriesContainer() const { return mL0FastORs; }

/// \brief Add cell information to the event container
/// \param tower Tower ID
/// \param energy Cell energy
Expand Down Expand Up @@ -129,6 +180,16 @@ class EventContainer
setCellCommon(tower, energy, time, celltype, true, hwaddress, ddlID, doMergeHGLG);
}

/// \brief Add bunch of time series to the container
/// \param fastORAbsID Absolute ID of the FastOR
/// \param starttime Start time of the bunch
/// \param timesamples Time samples of the bunch in time-reversed format
///
/// In case a TimeSeries is already present for the given FastOR abs. ID in the container
/// the bunch is added to this, otherwise a new TimeSeries is added with the ADCs of the
/// bunch.
void setFastOR(uint16_t fastORAbsID, uint8_t starttime, const gsl::span<const uint16_t> timesamples);

/// \brief Sort Cells / LEDMONs in container according to tower / module ID
/// \param isLEDmon Switch between Cell and LEDMON
void sortCells(bool isLEDmon);
Expand All @@ -148,21 +209,26 @@ class EventContainer
/// \return True if the energy is in the saturation region, false otherwise
bool isCellSaturated(double energy) const;

o2::InteractionRecord mInteractionRecord;
uint64_t mTriggerBits = 0; ///< Trigger bits of the event
std::vector<RecCellInfo> mCells; ///< Container of cells in event
std::vector<RecCellInfo> mLEDMons; ///< Container of LEDMONs in event
/// \brief Initialize the TRU handlers
void initTRUs();

o2::InteractionRecord mInteractionRecord; ///< Interaction record of the event
uint64_t mTriggerBits = 0; ///< Trigger bits of the event
std::vector<RecCellInfo> mCells; ///< Container of cells in event
std::vector<RecCellInfo> mLEDMons; ///< Container of LEDMONs in event
std::array<TRUDataHandler, TriggerMappingV2::ALLTRUS> mTRUData; ///< TRU status
std::unordered_map<uint16_t, FastORTimeSeries> mL0FastORs; ///< L0 FastOR time series
};

/// \class RecoContainer
/// \brief Handler for cells in
/// \brief Handler for cells/LEDMONS/Trigger data in timeframes
/// \ingroup EMCALReconstruction
class RecoContainer
{
public:
/// \class InteractionNotFoundException
/// \brief Handling of access to trigger interaction record not present in container
class InteractionNotFoundException : public std::exception
class InteractionNotFoundException final : public std::exception
{
public:
/// \brief Constructor
Expand Down
Loading

0 comments on commit d08d21a

Please sign in to comment.