diff --git a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/SimTraits.h b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/SimTraits.h index 37c4b790d181b..72782d4ed7bdf 100644 --- a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/SimTraits.h +++ b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/SimTraits.h @@ -124,6 +124,10 @@ namespace itsmft { class Hit; } +namespace trkft3 +{ +class Hit; +} namespace tof { class HitType; @@ -246,11 +250,11 @@ struct DetIDToHitTypes { }; template <> struct DetIDToHitTypes { - using HitType = o2::itsmft::Hit; + using HitType = o2::trkft3::Hit; }; template <> struct DetIDToHitTypes { - using HitType = o2::itsmft::Hit; + using HitType = o2::trkft3::Hit; }; template <> struct DetIDToHitTypes { diff --git a/DataFormats/Detectors/Upgrades/ALICE3/CMakeLists.txt b/DataFormats/Detectors/Upgrades/ALICE3/CMakeLists.txt index 360b50d442d7d..3914b8c7ede8d 100644 --- a/DataFormats/Detectors/Upgrades/ALICE3/CMakeLists.txt +++ b/DataFormats/Detectors/Upgrades/ALICE3/CMakeLists.txt @@ -10,4 +10,4 @@ # or submit itself to any jurisdiction. add_subdirectory(FD3) -add_subdirectory(TRK) +add_subdirectory(TRKFT3) diff --git a/DataFormats/Detectors/Upgrades/ALICE3/TRK/CMakeLists.txt b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/CMakeLists.txt similarity index 57% rename from DataFormats/Detectors/Upgrades/ALICE3/TRK/CMakeLists.txt rename to DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/CMakeLists.txt index c239a2a36845d..fd6e02c44a6b6 100644 --- a/DataFormats/Detectors/Upgrades/ALICE3/TRK/CMakeLists.txt +++ b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/CMakeLists.txt @@ -9,16 +9,4 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -o2_add_library(DataFormatsTRK - SOURCES src/Cluster.cxx - src/ROFRecord.cxx - PUBLIC_LINK_LIBRARIES O2::CommonDataFormat - O2::DataFormatsITSMFT - O2::SimulationDataFormat -) - -o2_target_root_dictionary(DataFormatsTRK - HEADERS include/DataFormatsTRK/Cluster.h - include/DataFormatsTRK/ROFRecord.h - LINKDEF src/DataFormatsTRKLinkDef.h -) +add_subdirectory(common) diff --git a/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/CMakeLists.txt b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/CMakeLists.txt new file mode 100644 index 0000000000000..d2a8b73da3455 --- /dev/null +++ b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright 2019-2026 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. + +o2_add_library(DataFormatsTRKFT3 + SOURCES src/Digit.cxx + src/Hit.cxx + src/ROFRecord.cxx + PUBLIC_LINK_LIBRARIES O2::CommonDataFormat + O2::SimulationDataFormat) + +o2_target_root_dictionary(DataFormatsTRKFT3 + HEADERS include/DataFormatsTRKFT3/Cluster.h + include/DataFormatsTRKFT3/Digit.h + include/DataFormatsTRKFT3/Hit.h + include/DataFormatsTRKFT3/ROFRecord.h + LINKDEF src/DataFormatsTRKFT3LinkDef.h) diff --git a/DataFormats/Detectors/Upgrades/ALICE3/TRK/include/DataFormatsTRK/Cluster.h b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/include/DataFormatsTRKFT3/Cluster.h similarity index 50% rename from DataFormats/Detectors/Upgrades/ALICE3/TRK/include/DataFormatsTRK/Cluster.h rename to DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/include/DataFormatsTRKFT3/Cluster.h index ec68191b3c43f..c3517f289d505 100644 --- a/DataFormats/Detectors/Upgrades/ALICE3/TRK/include/DataFormatsTRK/Cluster.h +++ b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/include/DataFormatsTRKFT3/Cluster.h @@ -9,30 +9,44 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef ALICEO2_DATAFORMATSTRK_CLUSTER_H -#define ALICEO2_DATAFORMATSTRK_CLUSTER_H +#ifndef ALICEO2_DATAFORMATSTRKFT3_CLUSTER_H +#define ALICEO2_DATAFORMATSTRKFT3_CLUSTER_H +#include "DetectorsCommonDataFormats/DetID.h" #include #include +#include #include -namespace o2::trk +namespace o2::trkft3 { +template struct Cluster { + static_assert(DetID == o2::detectors::DetID::TRK || DetID == o2::detectors::DetID::FT3, "only TRK and FT3 clusters are supported"); + uint16_t chipID = 0; uint16_t row = 0; uint16_t col = 0; uint16_t size = 1; int16_t subDetID = -1; int16_t layer = -1; - int16_t disk = -1; - std::string asString() const; + std::string asString() const + { + std::ostringstream stream; + stream << o2::detectors::DetID(DetID).getName() << " cluster chip=" << chipID + << " row=" << row << " col=" << col << " size=" << size + << " subDet=" << subDetID << " layer=" << layer; + return stream.str(); + } ClassDefNV(Cluster, 1); }; -} // namespace o2::trk +using TRKCluster = Cluster; +using FT3Cluster = Cluster; + +} // namespace o2::trkft3 #endif diff --git a/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/include/DataFormatsTRKFT3/Digit.h b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/include/DataFormatsTRKFT3/Digit.h new file mode 100644 index 0000000000000..41aa774a2ea06 --- /dev/null +++ b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/include/DataFormatsTRKFT3/Digit.h @@ -0,0 +1,60 @@ +// Copyright 2019-2026 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_DATAFORMATSTRKFT3_DIGIT_H +#define ALICEO2_DATAFORMATSTRKFT3_DIGIT_H + +#include "Rtypes.h" +#include +#include + +namespace o2::trkft3 +{ + +class Digit +{ + public: + Digit(UShort_t chipindex = 0, UShort_t row = 0, UShort_t col = 0, Int_t charge = 0); + ~Digit() = default; + + UShort_t getChipIndex() const { return mChipIndex; } + UShort_t getColumn() const { return mCol; } + UShort_t getRow() const { return mRow; } + Int_t getCharge() const { return mCharge; } + + void setChipIndex(UShort_t index) { mChipIndex = index; } + void setPixelIndex(UShort_t row, UShort_t col) + { + mRow = row; + mCol = col; + } + void setCharge(Int_t charge) { mCharge = charge < USHRT_MAX ? charge : USHRT_MAX; } + void addCharge(int charge) { setCharge(charge + int(mCharge)); } + + std::ostream& print(std::ostream& output) const; + friend std::ostream& operator<<(std::ostream& output, const Digit& digi) + { + digi.print(output); + return output; + } + + private: + UShort_t mChipIndex = 0; + UShort_t mRow = 0; + UShort_t mCol = 0; + UShort_t mCharge = 0; + + ClassDefNV(Digit, 1); +}; + +} // namespace o2::trkft3 + +#endif diff --git a/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/include/DataFormatsTRKFT3/Hit.h b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/include/DataFormatsTRKFT3/Hit.h new file mode 100644 index 0000000000000..bcc51828436f7 --- /dev/null +++ b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/include/DataFormatsTRKFT3/Hit.h @@ -0,0 +1,111 @@ +// Copyright 2019-2026 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_DATAFORMATSTRKFT3_HIT_H +#define ALICEO2_DATAFORMATSTRKFT3_HIT_H + +#include +#include + +#include "CommonUtils/ShmAllocator.h" +#include "SimulationDataFormat/BaseHits.h" +#include "Rtypes.h" +#include "TVector3.h" + +namespace o2::trkft3 +{ + +class Hit : public o2::BasicXYZEHit +{ + public: + enum HitStatus_t { + kTrackEntering = 0x1, + kTrackInside = 0x1 << 1, + kTrackExiting = 0x1 << 2, + kTrackOut = 0x1 << 3, + kTrackStopped = 0x1 << 4, + kTrackAlive = 0x1 << 5 + }; + + Hit() = default; + + Hit(int trackID, unsigned short detID, const TVector3& startPos, const TVector3& endPos, const TVector3& startMom, + double startE, double endTime, double eLoss, unsigned char startStatus, unsigned char endStatus); + + math_utils::Point3D GetPosStart() const { return mPosStart; } + Float_t GetStartX() const { return mPosStart.X(); } + Float_t GetStartY() const { return mPosStart.Y(); } + Float_t GetStartZ() const { return mPosStart.Z(); } + template + void GetStartPosition(F& x, F& y, F& z) const + { + x = GetStartX(); + y = GetStartY(); + z = GetStartZ(); + } + + math_utils::Vector3D GetMomentum() const { return mMomentum; } + math_utils::Vector3D& GetMomentum() { return mMomentum; } + Float_t GetPx() const { return mMomentum.X(); } + Float_t GetPy() const { return mMomentum.Y(); } + Float_t GetPz() const { return mMomentum.Z(); } + Float_t GetE() const { return mE; } + Float_t GetTotalEnergy() const { return GetE(); } + + UChar_t GetStatusEnd() const { return mTrackStatusEnd; } + UChar_t GetStatusStart() const { return mTrackStatusStart; } + + Bool_t IsEntering() const { return mTrackStatusEnd & kTrackEntering; } + Bool_t IsInside() const { return mTrackStatusEnd & kTrackInside; } + Bool_t IsExiting() const { return mTrackStatusEnd & kTrackExiting; } + Bool_t IsOut() const { return mTrackStatusEnd & kTrackOut; } + Bool_t IsStopped() const { return mTrackStatusEnd & kTrackStopped; } + Bool_t IsAlive() const { return mTrackStatusEnd & kTrackAlive; } + + Bool_t IsEnteringStart() const { return mTrackStatusStart & kTrackEntering; } + Bool_t IsInsideStart() const { return mTrackStatusStart & kTrackInside; } + Bool_t IsExitingStart() const { return mTrackStatusStart & kTrackExiting; } + Bool_t IsOutStart() const { return mTrackStatusStart & kTrackOut; } + Bool_t IsStoppedStart() const { return mTrackStatusStart & kTrackStopped; } + Bool_t IsAliveStart() const { return mTrackStatusStart & kTrackAlive; } + + void SetPosStart(const math_utils::Point3D& p) { mPosStart = p; } + + void Print(const Option_t* opt) const; + friend std::ostream& operator<<(std::ostream& of, const Hit& point) + { + of << "-I- Hit: O2 trkft3 point for track " << point.GetTrackID() << " in detector " << point.GetDetectorID() << std::endl; + return of; + } + + private: + math_utils::Vector3D mMomentum; ///< momentum at entrance + math_utils::Point3D mPosStart; ///< position at entrance, base position is at exit + Float_t mE = 0.f; ///< total energy at entrance + UChar_t mTrackStatusEnd = 0; ///< MC status flag at exit + UChar_t mTrackStatusStart = 0; ///< MC status at starting point + + ClassDefNV(Hit, 3); +}; + +} // namespace o2::trkft3 + +#ifdef USESHM +namespace std +{ +template <> +class allocator : public o2::utils::ShmAllocator +{ +}; +} // namespace std +#endif + +#endif diff --git a/DataFormats/Detectors/Upgrades/ALICE3/TRK/include/DataFormatsTRK/ROFRecord.h b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/include/DataFormatsTRKFT3/ROFRecord.h similarity index 78% rename from DataFormats/Detectors/Upgrades/ALICE3/TRK/include/DataFormatsTRK/ROFRecord.h rename to DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/include/DataFormatsTRKFT3/ROFRecord.h index 86ee31389fd5f..633ad7e4af24d 100644 --- a/DataFormats/Detectors/Upgrades/ALICE3/TRK/include/DataFormatsTRK/ROFRecord.h +++ b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/include/DataFormatsTRKFT3/ROFRecord.h @@ -9,8 +9,8 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef ALICEO2_DATAFORMATSTRK_ROFRECORD_H -#define ALICEO2_DATAFORMATSTRK_ROFRECORD_H +#ifndef ALICEO2_DATAFORMATSTRKFT3_ROFRECORD_H +#define ALICEO2_DATAFORMATSTRKFT3_ROFRECORD_H #include "CommonDataFormat/InteractionRecord.h" #include "CommonDataFormat/RangeReference.h" @@ -18,7 +18,7 @@ #include #include -namespace o2::trk +namespace o2::trkft3 { class ROFRecord @@ -56,20 +56,6 @@ class ROFRecord ClassDefNV(ROFRecord, 1); }; -struct MC2ROFRecord { - using ROFtype = unsigned int; - - int eventRecordID = -1; - int rofRecordID = 0; - ROFtype minROF = 0; - ROFtype maxROF = 0; - - MC2ROFRecord() = default; - MC2ROFRecord(int evID, int rofRecID, ROFtype mnrof, ROFtype mxrof) : eventRecordID(evID), rofRecordID(rofRecID), minROF(mnrof), maxROF(mxrof) {} - - ClassDefNV(MC2ROFRecord, 1); -}; - -} // namespace o2::trk +} // namespace o2::trkft3 #endif diff --git a/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/src/DataFormatsTRKFT3LinkDef.h b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/src/DataFormatsTRKFT3LinkDef.h new file mode 100644 index 0000000000000..046f680e42e8a --- /dev/null +++ b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/src/DataFormatsTRKFT3LinkDef.h @@ -0,0 +1,29 @@ +// Copyright 2019-2026 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. + +#ifdef __CLING__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class o2::trkft3::Digit + ; +#pragma link C++ class std::vector < o2::trkft3::Digit> + ; +#pragma link C++ class o2::trkft3::Hit + ; +#pragma link C++ class std::vector < o2::trkft3::Hit> + ; +#pragma link C++ class o2::trkft3::Cluster < o2::detectors::DetID::TRK> + ; +#pragma link C++ class std::vector < o2::trkft3::Cluster < o2::detectors::DetID::TRK>> + ; +#pragma link C++ class o2::trkft3::Cluster < o2::detectors::DetID::FT3> + ; +#pragma link C++ class std::vector < o2::trkft3::Cluster < o2::detectors::DetID::FT3>> + ; +#pragma link C++ class o2::trkft3::ROFRecord + ; +#pragma link C++ class std::vector < o2::trkft3::ROFRecord> + ; + +#endif diff --git a/DataFormats/Detectors/Upgrades/ALICE3/TRK/src/Cluster.cxx b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/src/Digit.cxx similarity index 56% rename from DataFormats/Detectors/Upgrades/ALICE3/TRK/src/Cluster.cxx rename to DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/src/Digit.cxx index 6c96692ea5a9e..f01d98d1e005d 100644 --- a/DataFormats/Detectors/Upgrades/ALICE3/TRK/src/Cluster.cxx +++ b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/src/Digit.cxx @@ -9,20 +9,21 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "DataFormatsTRK/Cluster.h" -#include +#include "DataFormatsTRKFT3/Digit.h" +#include -ClassImp(o2::trk::Cluster); +ClassImp(o2::trkft3::Digit); -namespace o2::trk -{ +using namespace o2::trkft3; -std::string Cluster::asString() const +Digit::Digit(UShort_t chipindex, UShort_t row, UShort_t col, Int_t charge) + : mChipIndex(chipindex), mRow(row), mCol(col) { - std::ostringstream stream; - stream << "chip=" << chipID << " row=" << row << " col=" << col << " size=" << size - << " subDet=" << subDetID << " layer=" << layer << " disk=" << disk; - return stream.str(); + setCharge(charge); } -} // namespace o2::trk +std::ostream& Digit::print(std::ostream& output) const +{ + output << "TRKFT3Digit chip [" << mChipIndex << "] R:" << mRow << " C:" << mCol << " Q: " << mCharge; + return output; +} diff --git a/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/src/Hit.cxx b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/src/Hit.cxx new file mode 100644 index 0000000000000..ff99214cbd994 --- /dev/null +++ b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/src/Hit.cxx @@ -0,0 +1,41 @@ +// Copyright 2019-2026 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 "DataFormatsTRKFT3/Hit.h" + +#include + +ClassImp(o2::trkft3::Hit); + +namespace o2::trkft3 +{ + +Hit::Hit(int trackID, unsigned short detID, const TVector3& startPos, const TVector3& endPos, const TVector3& startMom, + double startE, double endTime, double eLoss, unsigned char startStatus, unsigned char endStatus) + : BasicXYZEHit(endPos.X(), endPos.Y(), endPos.Z(), endTime, eLoss, trackID, detID), + mMomentum(startMom.Px(), startMom.Py(), startMom.Pz()), + mPosStart(startPos.X(), startPos.Y(), startPos.Z()), + mE(startE), + mTrackStatusEnd(endStatus), + mTrackStatusStart(startStatus) +{ +} + +void Hit::Print(const Option_t* opt) const +{ + printf( + "Det: %5d Track: %6d E.loss: %.3e P: %+.3e %+.3e %+.3e\n" + "PosIn: %+.3e %+.3e %+.3e PosOut: %+.3e %+.3e %+.3e\n", + GetDetectorID(), GetTrackID(), GetEnergyLoss(), GetPx(), GetPy(), GetPz(), + GetStartX(), GetStartY(), GetStartZ(), GetX(), GetY(), GetZ()); +} + +} // namespace o2::trkft3 diff --git a/DataFormats/Detectors/Upgrades/ALICE3/TRK/src/ROFRecord.cxx b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/src/ROFRecord.cxx similarity index 85% rename from DataFormats/Detectors/Upgrades/ALICE3/TRK/src/ROFRecord.cxx rename to DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/src/ROFRecord.cxx index 79745f9854eb7..9b2808653cf99 100644 --- a/DataFormats/Detectors/Upgrades/ALICE3/TRK/src/ROFRecord.cxx +++ b/DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/src/ROFRecord.cxx @@ -9,13 +9,12 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "DataFormatsTRK/ROFRecord.h" +#include "DataFormatsTRKFT3/ROFRecord.h" #include -ClassImp(o2::trk::ROFRecord); -ClassImp(o2::trk::MC2ROFRecord); +ClassImp(o2::trkft3::ROFRecord); -namespace o2::trk +namespace o2::trkft3 { std::string ROFRecord::asString() const @@ -26,4 +25,4 @@ std::string ROFRecord::asString() const return stream.str(); } -} // namespace o2::trk +} // namespace o2::trkft3 diff --git a/Detectors/Upgrades/ALICE3/CMakeLists.txt b/Detectors/Upgrades/ALICE3/CMakeLists.txt index 301a82322636d..f587772a1885b 100644 --- a/Detectors/Upgrades/ALICE3/CMakeLists.txt +++ b/Detectors/Upgrades/ALICE3/CMakeLists.txt @@ -10,7 +10,7 @@ # or submit itself to any jurisdiction. add_subdirectory(Passive) -add_subdirectory(TRK) +add_subdirectory(TRKFT3) add_subdirectory(GlobalReconstruction) add_subdirectory(ECal) add_subdirectory(FD3) diff --git a/Detectors/Upgrades/ALICE3/GlobalReconstruction/macros/CMakeLists.txt b/Detectors/Upgrades/ALICE3/GlobalReconstruction/macros/CMakeLists.txt index 8295e490f4d7d..834f11f2cce16 100644 --- a/Detectors/Upgrades/ALICE3/GlobalReconstruction/macros/CMakeLists.txt +++ b/Detectors/Upgrades/ALICE3/GlobalReconstruction/macros/CMakeLists.txt @@ -11,7 +11,7 @@ o2_add_test_root_macro(CheckTracksALICE3.C PUBLIC_LINK_LIBRARIES O2::DataFormatsITS - O2::DataFormatsTRK + O2::DataFormatsTRKFT3 O2::ITStracking O2::SimulationDataFormat O2::DetectorsBase diff --git a/Detectors/Upgrades/ALICE3/GlobalReconstruction/macros/CheckTracksALICE3.C b/Detectors/Upgrades/ALICE3/GlobalReconstruction/macros/CheckTracksALICE3.C index 836327507018c..0aafbf68c0634 100644 --- a/Detectors/Upgrades/ALICE3/GlobalReconstruction/macros/CheckTracksALICE3.C +++ b/Detectors/Upgrades/ALICE3/GlobalReconstruction/macros/CheckTracksALICE3.C @@ -30,7 +30,7 @@ #include #include "DataFormatsITS/TrackITS.h" -#include "DataFormatsTRK/Cluster.h" +#include "DataFormatsTRKFT3/Cluster.h" #include "SimulationDataFormat/MCCompLabel.h" #include "SimulationDataFormat/MCTrack.h" #include "SimulationDataFormat/MCTruthContainer.h" @@ -130,7 +130,7 @@ void CheckTracksALICE3(std::string tracfile = "o2trac_trk.root", std::unordered_map particleClusterMap; static constexpr int nTRKLayers = 11; - std::array*, nTRKLayers> clustersPerLayer{}; + std::array*, nTRKLayers> clustersPerLayer{}; std::array*, nTRKLayers> clusterLabelsPerLayer{}; for (int iLayer = 0; iLayer < nTRKLayers; ++iLayer) { diff --git a/Detectors/Upgrades/ALICE3/GlobalReconstruction/reconstruction/CMakeLists.txt b/Detectors/Upgrades/ALICE3/GlobalReconstruction/reconstruction/CMakeLists.txt index 9cc7222d413e7..68afd31835999 100644 --- a/Detectors/Upgrades/ALICE3/GlobalReconstruction/reconstruction/CMakeLists.txt +++ b/Detectors/Upgrades/ALICE3/GlobalReconstruction/reconstruction/CMakeLists.txt @@ -22,7 +22,7 @@ o2_add_library(ALICE3GlobalReconstruction Microsoft.GSL::GSL O2::CommonConstants O2::DataFormatsITSMFT - O2::DataFormatsTRK + O2::DataFormatsTRKFT3 O2::SimulationDataFormat O2::ITSBase O2::ITSReconstruction diff --git a/Detectors/Upgrades/ALICE3/GlobalReconstruction/reconstruction/include/ALICE3GlobalReconstruction/TimeFrameMixin.h b/Detectors/Upgrades/ALICE3/GlobalReconstruction/reconstruction/include/ALICE3GlobalReconstruction/TimeFrameMixin.h index 6e95be32dd0e1..da1a80b77772b 100644 --- a/Detectors/Upgrades/ALICE3/GlobalReconstruction/reconstruction/include/ALICE3GlobalReconstruction/TimeFrameMixin.h +++ b/Detectors/Upgrades/ALICE3/GlobalReconstruction/reconstruction/include/ALICE3GlobalReconstruction/TimeFrameMixin.h @@ -17,8 +17,8 @@ #define ALICEO2_ALICE3GLOBALRECONSTRUCTION_TIMEFRAMEMIXIN_H #include "CommonDataFormat/InteractionRecord.h" -#include "DataFormatsTRK/Cluster.h" -#include "DataFormatsTRK/ROFRecord.h" +#include "DataFormatsTRKFT3/Cluster.h" +#include "DataFormatsTRKFT3/ROFRecord.h" #include "ITStracking/ROFLookupTables.h" #include "ITStracking/TimeFrame.h" #include "SimulationDataFormat/MCCompLabel.h" @@ -27,7 +27,7 @@ #include "SimulationDataFormat/DigitizationContext.h" #include "Steer/MCKinematicsReader.h" #include "TRKReconstruction/Clusterer.h" -#include "TRKSimulation/Hit.h" +#include "DataFormatsTRKFT3/Hit.h" #include "TRKBase/GeometryTGeo.h" #include "TRKBase/SegmentationChip.h" #include "Framework/Logger.h" @@ -58,8 +58,8 @@ class TimeFrameMixin : public Base int loadROFsFromHitTree(TTree* hitsTree, GeometryTGeo* gman, const nlohmann::json& config); - int loadROFrameData(const std::array, nLayers>& layerROFs, - const std::array, nLayers>& layerClusters, + int loadROFrameData(const std::array, nLayers>& layerROFs, + const std::array, nLayers>& layerClusters, const std::array, nLayers>& layerPatterns, const std::array*, nLayers>* mcLabels = nullptr, float yPlaneMLOT = 0.f); @@ -68,7 +68,7 @@ class TimeFrameMixin : public Base void addTruthSeedingVertices(); - void deriveAndInitTiming(const std::array, nLayers>& layerROFs); + void deriveAndInitTiming(const std::array, nLayers>& layerROFs); const o2::InteractionRecord& getTFAnchorIR() const noexcept { return mTFAnchorIR; } @@ -118,7 +118,7 @@ void TimeFrameMixin::initTimingTables(const std::array -void TimeFrameMixin::deriveAndInitTiming(const std::array, nLayers>& layerROFs) +void TimeFrameMixin::deriveAndInitTiming(const std::array, nLayers>& layerROFs) { if (mTimingTablesInitialised) { return; @@ -180,7 +180,7 @@ int TimeFrameMixin::loadROFsFromHitTree(TTree* hitsTree, Geometry gman->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L) | o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)); - std::vector* trkHit = nullptr; + std::vector* trkHit = nullptr; hitsTree->SetBranchAddress("TRKHit", &trkHit); const int inROFpileup{config.contains("inROFpileup") ? config["inROFpileup"].get() : 1}; @@ -313,8 +313,8 @@ int TimeFrameMixin::loadROFsFromHitTree(TTree* hitsTree, Geometry } template -int TimeFrameMixin::loadROFrameData(const std::array, nLayers>& layerROFs, - const std::array, nLayers>& layerClusters, +int TimeFrameMixin::loadROFrameData(const std::array, nLayers>& layerROFs, + const std::array, nLayers>& layerClusters, const std::array, nLayers>& layerPatterns, const std::array*, nLayers>* mcLabels, float yPlaneMLOT) @@ -391,7 +391,7 @@ int TimeFrameMixin::loadROFrameData(const std::array 1 || c.disk != -1) { + if (c.subDetID < 0 || c.subDetID > 1) { continue; } @@ -403,7 +403,7 @@ int TimeFrameMixin::loadROFrameData(const std::arraygetMatrixL2G(c.chipID) * locXYZ; diff --git a/Detectors/Upgrades/ALICE3/GlobalReconstruction/workflow/CMakeLists.txt b/Detectors/Upgrades/ALICE3/GlobalReconstruction/workflow/CMakeLists.txt index 6a4994e11467b..7b5cd0e735802 100644 --- a/Detectors/Upgrades/ALICE3/GlobalReconstruction/workflow/CMakeLists.txt +++ b/Detectors/Upgrades/ALICE3/GlobalReconstruction/workflow/CMakeLists.txt @@ -18,7 +18,7 @@ o2_add_library(ALICE3GlobalReconstructionWorkflow O2::GPUWorkflow O2::SimConfig O2::DataFormatsITSMFT - O2::DataFormatsTRK + O2::DataFormatsTRKFT3 O2::SimulationDataFormat O2::DPLUtils O2::TRKBase diff --git a/Detectors/Upgrades/ALICE3/GlobalReconstruction/workflow/include/ALICE3GlobalReconstructionWorkflow/TrackerSpecImpl.h b/Detectors/Upgrades/ALICE3/GlobalReconstruction/workflow/include/ALICE3GlobalReconstructionWorkflow/TrackerSpecImpl.h index f6221e485f369..8a2f162019de0 100644 --- a/Detectors/Upgrades/ALICE3/GlobalReconstruction/workflow/include/ALICE3GlobalReconstructionWorkflow/TrackerSpecImpl.h +++ b/Detectors/Upgrades/ALICE3/GlobalReconstruction/workflow/include/ALICE3GlobalReconstructionWorkflow/TrackerSpecImpl.h @@ -15,8 +15,8 @@ #include "ALICE3GlobalReconstructionWorkflow/TrackerSpec.h" #include "CommonDataFormat/IRFrame.h" -#include "DataFormatsTRK/Cluster.h" -#include "DataFormatsTRK/ROFRecord.h" +#include "DataFormatsTRKFT3/Cluster.h" +#include "DataFormatsTRKFT3/ROFRecord.h" #include "DetectorsBase/GeometryManager.h" #include "Field/MagFieldParam.h" #include "Field/MagneticField.h" @@ -26,7 +26,7 @@ #include "SimulationDataFormat/MCEventHeader.h" #include "SimulationDataFormat/MCTruthContainer.h" #include "TRKBase/GeometryTGeo.h" -#include "TRKSimulation/Hit.h" +#include "DataFormatsTRKFT3/Hit.h" #include #include @@ -59,7 +59,7 @@ void TrackerDPL::runTracking(framework::ProcessingContext& pc, TimeFrameT& timeF TFile hitsFile(mHitRecoConfig["inputfiles"]["hits"].get().c_str(), "READ"); TFile mcHeaderFile(mHitRecoConfig["inputfiles"]["mcHeader"].get().c_str(), "READ"); TTree* hitsTree = hitsFile.Get("o2sim"); - std::vector* trkHit = nullptr; + std::vector* trkHit = nullptr; hitsTree->SetBranchAddress("TRKHit", &trkHit); TTree* mcHeaderTree = mcHeaderFile.Get("o2sim"); @@ -92,16 +92,16 @@ void TrackerDPL::runTracking(framework::ProcessingContext& pc, TimeFrameT& timeF TGeoGlobalMagField::Instance()->Lock(); constexpr int nLayers{11}; - std::array, nLayers> layerClusters; + std::array, nLayers> layerClusters; std::array, nLayers> layerPatterns; - std::array, nLayers> layerROFs; + std::array, nLayers> layerROFs; std::array*, nLayers> layerLabels{}; size_t nInputRofs{0}; for (int iLayer = 0; iLayer < nLayers; ++iLayer) { - layerClusters[iLayer] = pc.inputs().get>(std::format("compClusters_{}", iLayer)); + layerClusters[iLayer] = pc.inputs().get>(std::format("compClusters_{}", iLayer)); layerPatterns[iLayer] = pc.inputs().get>(std::format("patterns_{}", iLayer)); - layerROFs[iLayer] = pc.inputs().get>(std::format("ROframes_{}", iLayer)); + layerROFs[iLayer] = pc.inputs().get>(std::format("ROframes_{}", iLayer)); nInputRofs = std::max(nInputRofs, layerROFs[iLayer].size()); if (mIsMC) { layerLabels[iLayer] = pc.inputs().get*>(std::format("trkmclabels_{}", iLayer)).release(); @@ -173,7 +173,7 @@ void TrackerDPL::runTracking(framework::ProcessingContext& pc, TimeFrameT& timeF highestROF = std::max(highestROF, static_cast(clockLayer.getROF(vtx.getTimeStamp().lower()))); } - std::vector allTrackROFs(highestROF); + std::vector allTrackROFs(highestROF); for (size_t iROF = 0; iROF < allTrackROFs.size(); ++iROF) { auto& rof = allTrackROFs[iROF]; o2::InteractionRecord ir; diff --git a/Detectors/Upgrades/ALICE3/GlobalReconstruction/workflow/src/TrackerSpec.cxx b/Detectors/Upgrades/ALICE3/GlobalReconstruction/workflow/src/TrackerSpec.cxx index 0b7ab97d44ee6..f588b07c598bf 100644 --- a/Detectors/Upgrades/ALICE3/GlobalReconstruction/workflow/src/TrackerSpec.cxx +++ b/Detectors/Upgrades/ALICE3/GlobalReconstruction/workflow/src/TrackerSpec.cxx @@ -19,8 +19,8 @@ #include "CommonUtils/DLLoaderBase.h" #include "CommonDataFormat/IRFrame.h" -#include "DataFormatsTRK/Cluster.h" -#include "DataFormatsTRK/ROFRecord.h" +#include "DataFormatsTRKFT3/Cluster.h" +#include "DataFormatsTRKFT3/ROFRecord.h" #include "DetectorsBase/GeometryManager.h" #include "ITStracking/TimeFrame.h" #include "ITStracking/Configuration.h" @@ -35,7 +35,7 @@ #include "SimulationDataFormat/MCTruthContainer.h" #include "TRKBase/GeometryTGeo.h" #include "TRKBase/SegmentationChip.h" -#include "TRKSimulation/Hit.h" +#include "DataFormatsTRKFT3/Hit.h" #include "ALICE3GlobalReconstruction/TimeFrame.h" #include "ALICE3GlobalReconstructionWorkflow/TrackerSpec.h" #include "ALICE3GlobalReconstructionWorkflow/TrackerSpecImpl.h" diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/ChipDigitsContainer.h b/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/ChipDigitsContainer.h deleted file mode 100644 index bf28ace0724bc..0000000000000 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/ChipDigitsContainer.h +++ /dev/null @@ -1,47 +0,0 @@ -// 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_TRK_CHIPDIGITSCONTAINER_ -#define ALICEO2_TRK_CHIPDIGITSCONTAINER_ - -#include "ITSMFTBase/SegmentationAlpide.h" -#include "ITSMFTSimulation/ChipDigitsContainer.h" -#include "TRKBase/SegmentationChip.h" -#include "TRKBase/Specs.h" -#include "TRKSimulation/DigiParams.h" -#include - -namespace o2::trk -{ - -class ChipDigitsContainer : public o2::itsmft::ChipDigitsContainer -{ - public: - explicit ChipDigitsContainer(UShort_t idx = 0); - - using Segmentation = SegmentationChip; - - /// Get global ordering key made of readout frame, column and row - static ULong64_t getOrderingKey(UInt_t roframe, UShort_t row, UShort_t col) - { - return (static_cast(roframe) << (8 * sizeof(UInt_t))) + (static_cast(col) << (8 * sizeof(Short_t))) + row; - } - - /// Adds noise digits, deleted the one using the itsmft::DigiParams interface - void addNoise(UInt_t rofMin, UInt_t rofMax, const o2::itsmft::DigiParams* params, int maxRows = o2::itsmft::SegmentationAlpide::NRows, int maxCols = o2::itsmft::SegmentationAlpide::NCols) = delete; - void addNoise(UInt_t rofMin, UInt_t rofMax, const o2::trk::DigiParams* params, int subDetID, int layer); - - ClassDefNV(ChipDigitsContainer, 1); -}; - -} // namespace o2::trk - -#endif // ALICEO2_TRK_CHIPDIGITSCONTAINER_ diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/ChipDigitsContainer.cxx b/Detectors/Upgrades/ALICE3/TRK/simulation/src/ChipDigitsContainer.cxx deleted file mode 100644 index d8e6df8b6099c..0000000000000 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/ChipDigitsContainer.cxx +++ /dev/null @@ -1,64 +0,0 @@ -// 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 "TRKSimulation/ChipDigitsContainer.h" - -using namespace o2::trk; - -ChipDigitsContainer::ChipDigitsContainer(UShort_t idx) - : o2::itsmft::ChipDigitsContainer(idx) {} - -//______________________________________________________________________ -void ChipDigitsContainer::addNoise(UInt_t rofMin, UInt_t rofMax, const o2::trk::DigiParams* params, int subDetID, int layer) -{ - UInt_t row = 0; - UInt_t col = 0; - Int_t nhits = 0; - constexpr float ns2sec = 1e-9; - float mean = 0.f; - int nel = 0; - int maxRows = 0; - int maxCols = 0; - - // TODO: set different noise and threshold for VD and MLOT - if (subDetID == 0) { // VD - maxRows = constants::VD::petal::layer::nRows[layer]; // TODO: get the layer from the geometry - maxCols = constants::VD::petal::layer::nCols; - mean = params->getNoisePerPixel() * maxRows * maxCols; - nel = static_cast(params->getChargeThreshold() * 1.1); - } else { // ML/OT - maxRows = constants::moduleMLOT::chip::nRows; - maxCols = constants::moduleMLOT::chip::nCols; - mean = params->getNoisePerPixel() * maxRows * maxCols; - nel = static_cast(params->getChargeThreshold() * 1.1); - } - - LOG(debug) << "Adding noise for chip " << mChipIndex << " with mean " << mean << " and charge " << nel; - - for (UInt_t rof = rofMin; rof <= rofMax; rof++) { - nhits = gRandom->Poisson(mean); - for (Int_t i = 0; i < nhits; ++i) { - row = gRandom->Integer(maxRows); - col = gRandom->Integer(maxCols); - LOG(debug) << "Generated noise hit at ROF " << rof << ", row " << row << ", col " << col; - if (mNoiseMap && mNoiseMap->isNoisy(mChipIndex, row, col)) { - continue; - } - if (mDeadChanMap && mDeadChanMap->isNoisy(mChipIndex, row, col)) { - continue; - } - auto key = getOrderingKey(rof, row, col); - if (!findDigit(key)) { - addDigit(key, rof, row, col, nel, o2::MCCompLabel(true)); - } - } - } -} diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRKFT3/CMakeLists.txt new file mode 100644 index 0000000000000..3f9a281e64480 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/CMakeLists.txt @@ -0,0 +1,17 @@ +# 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. + +add_subdirectory(FT3/base) +add_subdirectory(TRK/base) +add_subdirectory(common) +add_subdirectory(FT3/simulation) +add_subdirectory(TRK/macros) +add_subdirectory(TRK/simulation) diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/CMakeLists.txt new file mode 100644 index 0000000000000..3dde618f9d57a --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/CMakeLists.txt @@ -0,0 +1,13 @@ +# 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. + +add_subdirectory(base) +add_subdirectory(simulation) diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/README.md b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/README.md new file mode 100644 index 0000000000000..c11352607db85 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/README.md @@ -0,0 +1,34 @@ + + +# ALICE 3 Tracker Endcaps + +This is top page for the FT3 detector documentation. + +## Specific detector setup + + +Configuration of the endcap disks can be done by setting values for the `FT3Base.layoutFT3` configurable, +the available options are presented in the following Table: + +| Option | Comments | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| `kSegmentedStave` | Segmentation of ML and OT disks: Modules are placed on staggered staves with user defined constants | +| `kSegmentedStaveOTOnly` (default) | Only OT disks are contain staves with modules, ML layers are segmented with strips of modules on front/back | +| `kSegmented` | Segmentation of ML and OT disk with strips of modules of chips on the front and back of a layer | +| `kTrapezoidal` | Simple trapezoidal disks (in both ML and OT), with `FT3Base.nTrapezoidalSegments=32` | +| `kCylindrical` | Simplest possible disks as TGeoTubes (ML and OT), bad for ACTS (wrong digi due to polar coorinates on disk sides) | + +Furthermore, there are more options in the case of stave segmentation -- for only OT or both. The user can set to cut the staves exactly on the nominal inner radii (true by default), and outer radii (false by default) of the disks. This exists since (planned) placements of sensors & staves often protrude out of the nominal radii to be more able to cover the nominal disk area. In addition, it is possible to draw reference circles in root for the stave segmented layouts for both the inner (red) and outer (blue) radii. This is off by default, yet can be toggled if the user wants to see how tight the tiling is to the nominal radii -- for visualisation purposes only. + +[ [Link to definitions](./base/include/FT3Base/FT3BaseParam.h) ] + +For example, see the command below to generate a geometry with the endcaps only, all layers with the stave geometry, and including reference circles of nominal radii for visualisation. +```bash +o2-sim-serial-run5 -n 1 -g pythia8hi -m FT3 \ + --configKeyValues "FT3Base.layoutFT3=kSegmented; FT3Base.drawReferenceCircles=true" +``` + + diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/CMakeLists.txt new file mode 100644 index 0000000000000..1cfb57c4beb84 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/CMakeLists.txt @@ -0,0 +1,19 @@ +# 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. + +o2_add_library(FT3Base + SOURCES src/GeometryTGeo.cxx + SOURCES src/FT3BaseParam.cxx + PUBLIC_LINK_LIBRARIES O2::DetectorsBase) + +o2_target_root_dictionary(FT3Base + HEADERS include/FT3Base/GeometryTGeo.h + HEADERS include/FT3Base/FT3BaseParam.h) diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/include/FT3Base/FT3BaseParam.h b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/include/FT3Base/FT3BaseParam.h new file mode 100644 index 0000000000000..d7156b5c92582 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/include/FT3Base/FT3BaseParam.h @@ -0,0 +1,61 @@ +// 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_FT3_BASEPARAM_H_ +#define ALICEO2_FT3_BASEPARAM_H_ + +#include "CommonUtils/ConfigurableParam.h" +#include "CommonUtils/ConfigurableParamHelper.h" + +namespace o2 +{ +namespace ft3 +{ +// Parameters for FT3 (ML and OT disks) +enum eFT3Layout { + kCylindrical = 0, + kTrapezoidal, + kSegmented, + kSegmentedStave, + kSegmentedStaveOTOnly +}; +struct FT3BaseParam : public o2::conf::ConfigurableParamHelper { + // Geometry Builder parameters + eFT3Layout layoutFT3 = kSegmentedStaveOTOnly; + int nTrapezoidalSegments = 32; // for the simple trapezoidal disks + + // FT3Geometry::Telescope parameters + Int_t nLayers = 10; + Float_t z0 = -16.0; // First layer z position + Float_t zLength = 263.0; // Distance between first and last layers + Float_t etaIn = 4.5; + Float_t etaOut = 1.5; + Float_t Layerx2X0 = 0.01; + + // define tolerance allowed for staves to go outside nominal radii + double staveTolMLInner = 0.; + double staveTolMLOuter = 0.; + double staveTolOTInner = 0.; + double staveTolOTOuter = 0.; + + // What to place over x=0 line in case of full outer-outer stave: Gap or Module + bool placeSensorStackInMiddleOfStave = false; + + // Draw reference circles at inner and outer radius of stave layer, for visualisation + bool drawReferenceCircles = false; + + O2ParamDef(FT3BaseParam, "FT3Base"); +}; + +} // end namespace ft3 +} // end namespace o2 + +#endif // ALICEO2_FT3_BASEPARAM_H_ diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/include/FT3Base/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/include/FT3Base/GeometryTGeo.h new file mode 100644 index 0000000000000..c0314fb090c32 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/include/FT3Base/GeometryTGeo.h @@ -0,0 +1,132 @@ +// 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. + +/// \file GeometryTGeo.h +/// \brief Definition of the GeometryTGeo class +/// \author cvetan.cheshkov@cern.ch - 15/02/2007 +/// \author ruben.shahoyan@cern.ch - adapted to ITSupg 18/07/2012 +/// \author rafael.pezzi@cern.ch - adapted to PostLS4EndCaps 25/06/2020 + +#ifndef ALICEO2_FT3_GEOMETRYTGEO_H_ +#define ALICEO2_FT3_GEOMETRYTGEO_H_ + +#include // for TGeoHMatrix +#include // for TObject +#include +#include +#include +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsCommonDataFormats/DetID.h" +#include "DetectorsCommonDataFormats/DetMatrixCache.h" +#include "MathUtils/Utils.h" +#include "Rtypes.h" // for Int_t, Double_t, Bool_t, UInt_t, etc + +class TGeoPNEntry; + +namespace o2 +{ +namespace ft3 +{ +/// GeometryTGeo is a simple interface class to TGeoManager. It is used in the simulation +/// in order to query the TGeo FT3 geometry. +/// RS: In order to preserve the static character of the class but make it dynamically access +/// geometry, we need to check in every method if the structures are initialized. To be converted +/// to singleton at later stage. + +class GeometryTGeo : public o2::detectors::DetMatrixCache +{ + public: + typedef o2::math_utils::Transform3D Mat3D; + using DetMatrixCache::getMatrixL2G; + using DetMatrixCache::getMatrixT2GRot; + using DetMatrixCache::getMatrixT2L; + // this method is not advised for ITS: for barrel detectors whose tracking frame is just a rotation + // it is cheaper to use T2GRot + using DetMatrixCache::getMatrixT2G; + + static GeometryTGeo* Instance() + { + // get (create if needed) a unique instance of the object + if (!sInstance) { + sInstance = std::unique_ptr(new GeometryTGeo(true, 0)); + } + return sInstance.get(); + } + + // adopt the unique instance from external raw pointer (to be used only to read saved instance from file) + static void adopt(GeometryTGeo* raw); + + // constructor + // ATTENTION: this class is supposed to behave as a singleton, but to make it root-persistent + // we must define public default constructor. + // NEVER use it, it will throw exception if the class instance was already created + // Use GeometryTGeo::Instance() instead + GeometryTGeo(bool build = kFALSE, int loadTrans = 0 + /*o2::base::utils::bit2Mask(o2::TransformType::T2L, // default transformations to load + o2::TransformType::T2G, + o2::TransformType::L2G)*/ + ); + + /// Default destructor + ~GeometryTGeo() = default; + + GeometryTGeo(const GeometryTGeo& src) = delete; + GeometryTGeo& operator=(const GeometryTGeo& geom) = delete; + + void fillMatrixCache(int mask); + + /// Exract FT3 parameters from TGeo + void Build(int loadTrans = 0); + + void Print(Option_t* opt = "") const; + static const char* getFT3VolPattern() { return sVolumeName.c_str(); } + static const char* getFT3InnerVolPattern() { return sInnerVolumeName.c_str(); } + static const char* getFT3LayerPattern() { return sLayerName.c_str(); } + static const char* getFT3ChipPattern() { return sChipName.c_str(); } + static const char* getFT3SensorPattern() { return sSensorName.c_str(); } + static const char* getFT3PassivePattern() { return sPassiveName.c_str(); } + + static const char* composeSymNameFT3(Int_t d) { return Form("%s_%d", o2::detectors::DetID(o2::detectors::DetID::FT3).getName(), d); } + static const char* composeSymNameLayer(Int_t d, Int_t lr); + static const char* composeSymNameChip(Int_t d, Int_t lr); + static const char* composeSymNameSensor(Int_t d, Int_t lr); + + int getNumberOfChips() const { return mSize; } + int getNumberOfLayers() const { return mFirstChipIndexLayer.size() > 0 ? mFirstChipIndexLayer.size() - 1 : 0; } + int getSubDetID(int) const { return 2; } + int getLayer(int index) const; + int getStave(int index) const; + int getChip(int index) const; + int getChipIndex(int layer, int stave, int chip) const; + int getChipIndex(const std::string& volName) const; + void extractChipIdsFT3(std::string const& volName, int& layer, int& stave, int& chip) const; + + protected: + static std::string sInnerVolumeName; ///< Mother inner volume name + static std::string sVolumeName; ///< Mother volume name + static std::string sLayerName; ///< Layer name + static std::string sChipName; ///< Chip name + static std::string sSensorName; ///< Sensor name + static std::string sPassiveName; ///< Passive material name + std::vector mFirstChipIndexLayer; + std::vector mFirstStaveIndexLayer; + std::vector mFirstChipIndexStave; + int mNumberOfLayersPerSide = 0; + + private: + static std::unique_ptr sInstance; ///< singletone instance + + ClassDefNV(GeometryTGeo, 1); // FT3 geometry based on TGeo +}; +} // namespace ft3 +} // namespace o2 + +#endif diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Hit.h b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/src/FT3BaseLinkDef.h similarity index 65% rename from Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Hit.h rename to Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/src/FT3BaseLinkDef.h index 402a343ead472..0a732ea1ec39b 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Hit.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/src/FT3BaseLinkDef.h @@ -9,21 +9,14 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file Hit.h -/// \brief Definition of the TRK Hit class +#ifdef __CLING__ -#ifndef ALICEO2_TRK_HIT_H_ -#define ALICEO2_TRK_HIT_H_ +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; -#include "ITSMFTSimulation/Hit.h" - -namespace o2::trk -{ -class Hit : public o2::itsmft::Hit -{ - public: - using o2::itsmft::Hit::Hit; // Inherit constructors -}; -} // namespace o2::trk +#pragma link C++ class o2::ft3::GeometryTGeo; +#pragma link C++ class o2::ft3::FT3BaseParam + ; +#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::ft3::FT3BaseParam> + ; #endif diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Hit.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/src/FT3BaseParam.cxx similarity index 85% rename from Detectors/Upgrades/ALICE3/TRK/simulation/src/Hit.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/src/FT3BaseParam.cxx index 1f49b84114b9d..a5179299531a2 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Hit.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/src/FT3BaseParam.cxx @@ -9,7 +9,5 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file Hit.cxx -/// \brief Implementation of the Hit class - -#include "TRKSimulation/Hit.h" +#include "FT3Base/FT3BaseParam.h" +O2ParamImpl(o2::ft3::FT3BaseParam); diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/src/GeometryTGeo.cxx new file mode 100644 index 0000000000000..34b5782b4291e --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/src/GeometryTGeo.cxx @@ -0,0 +1,292 @@ +// 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. + +/// \file GeometryTGeo.cxx +/// \brief Implementation of the GeometryTGeo class +/// \author cvetan.cheshkov@cern.ch - 15/02/2007 +/// \author ruben.shahoyan@cern.ch - adapted to ITSupg 18/07/2012 +/// \author rafael.pezzi@cern.ch - adapted to ALICE 3 EndCaps 14/02/2021 + +// ATTENTION: In opposite to old AliITSgeomTGeo, all indices start from 0, not from 1!!! + +#include "FT3Base/GeometryTGeo.h" +#include "DetectorsBase/GeometryManager.h" +#include "MathUtils/Cartesian.h" + +#include // for LOG + +#include // for TGeoBBox +#include // for gGeoManager, TGeoManager +#include // for TGeoPNEntry, TGeoPhysicalNode +#include // for TGeoShape +#include // for Nint, ATan2, RadToDeg +#include // for TString, Form +#include "TClass.h" // for TClass +#include "TGeoMatrix.h" // for TGeoHMatrix +#include "TGeoNode.h" // for TGeoNode, TGeoNodeMatrix +#include "TGeoVolume.h" // for TGeoVolume +#include "TMathBase.h" // for Max +#include "TObjArray.h" // for TObjArray +#include "TObject.h" // for TObject + +#include // for isdigit +#include +#include // for snprintf, NULL, printf +#include // for strstr, strlen +#include + +using namespace TMath; +using namespace o2::ft3; +using namespace o2::detectors; + +ClassImp(o2::ft3::GeometryTGeo); + +std::unique_ptr GeometryTGeo::sInstance; + +std::string GeometryTGeo::sVolumeName = "FT3V"; ///< Mother volume name +std::string GeometryTGeo::sInnerVolumeName = "FT3Inner"; ///< Mother inner volume name +std::string GeometryTGeo::sLayerName = "FT3Layer"; ///< Layer name +std::string GeometryTGeo::sChipName = "FT3Chip"; ///< Chip name +std::string GeometryTGeo::sSensorName = "FT3Sensor"; ///< Sensor name +std::string GeometryTGeo::sPassiveName = "FT3Passive"; ///< Passive material name + +//__________________________________________________________________________ +GeometryTGeo::GeometryTGeo(bool build, int loadTrans) : DetMatrixCache(DetID::FT3) +{ + // default c-tor, if build is true, the structures will be filled and the transform matrices + // will be cached + if (sInstance) { + LOG(fatal) << "Invalid use of public constructor: o2::ft3::GeometryTGeo instance exists"; + // throw std::runtime_error("Invalid use of public constructor: o2::ft3::GeometryTGeo instance exists"); + } + + if (build) { + Build(loadTrans); + } +} + +void GeometryTGeo::adopt(GeometryTGeo* raw) +{ + sInstance.reset(raw); +} + +//__________________________________________________________________________ +void GeometryTGeo::Build(int loadTrans) +{ + if (isBuilt()) { + LOG(warning) << "Already built"; + return; // already initialized + } + + if (!gGeoManager) { + // RSTODO: in future there will be a method to load matrices from the CDB + LOG(fatal) << "Geometry is not loaded"; + } + + mNumberOfLayersPerSide = 0; + for (int dir = 0; dir < 2; ++dir) { + while (gGeoManager->GetVolume(Form("%s%d_%d", getFT3LayerPattern(), dir, mNumberOfLayersPerSide))) { + ++mNumberOfLayersPerSide; + } + if (mNumberOfLayersPerSide > 0) { + break; + } + } + + std::map> chipsPerStavePerLayer; + auto* volumes = gGeoManager->GetListOfVolumes(); + const int nVolumes = volumes ? volumes->GetEntriesFast() : 0; + for (int i = 0; i < nVolumes; ++i) { + auto* volume = static_cast(volumes->At(i)); + if (!volume) { + continue; + } + const std::string name = volume->GetName(); + if (name.find("FT3Sensor") != 0 || name.find("Inactive") != std::string::npos || name.find("inactive") != std::string::npos) { + continue; + } + int layer = -1, stave = 0, chip = 0; + extractChipIdsFT3(name, layer, stave, chip); + if (layer < 0) { + continue; + } + chipsPerStavePerLayer[layer][stave] = std::max(chipsPerStavePerLayer[layer][stave], chip + 1); + } + + int numberOfChips = 0; + int numberOfStaves = 0; + mFirstChipIndexLayer.clear(); + mFirstStaveIndexLayer.clear(); + mFirstChipIndexStave.clear(); + mFirstChipIndexLayer.push_back(0); + mFirstStaveIndexLayer.push_back(0); + mFirstChipIndexStave.push_back(0); + for (const auto& [layer, chipsPerStave] : chipsPerStavePerLayer) { + for (const auto& [stave, nChips] : chipsPerStave) { + numberOfChips += nChips; + mFirstChipIndexStave.push_back(numberOfChips); + ++numberOfStaves; + } + mFirstStaveIndexLayer.push_back(numberOfStaves); + mFirstChipIndexLayer.push_back(numberOfChips); + } + + setSize(numberOfChips); + fillMatrixCache(loadTrans); +} + +//__________________________________________________________________________ +const char* GeometryTGeo::composeSymNameLayer(Int_t d, Int_t lr) +{ + return Form("%s/%s%d", composeSymNameFT3(d), getFT3LayerPattern(), lr); +} + +//__________________________________________________________________________ +const char* GeometryTGeo::composeSymNameChip(Int_t d, Int_t lr) +{ + return Form("%s/%s%d", composeSymNameLayer(d, lr), getFT3ChipPattern(), lr); +} + +//__________________________________________________________________________ +const char* GeometryTGeo::composeSymNameSensor(Int_t d, Int_t lr) +{ + return Form("%s/%s%d", composeSymNameChip(d, lr), getFT3SensorPattern(), lr); +} + +//__________________________________________________________________________ +void GeometryTGeo::fillMatrixCache(int mask) +{ + if (mSize < 1) { + LOG(warning) << "The method Build was not called yet"; + Build(mask); + return; + } + if ((mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)) && !getCacheL2G().isFilled()) { + LOGP(info, "Loading {} L2G matrix cache with {} FT3 sensor slots", getName(), mSize); + getCacheL2G().setSize(mSize); + } +} + +//__________________________________________________________________________ +void GeometryTGeo::Print(Option_t*) const +{ + if (!isBuilt()) { + LOGP(info, "{} geometry is not built yet", getName()); + return; + } + LOGP(info, "Summary of GeometryTGeo: {}", getName()); + LOGP(info, "Number of FT3 layers: {}", getNumberOfLayers()); + LOGP(info, "Number of FT3 layers per side: {}", mNumberOfLayersPerSide); + LOGP(info, "Number of FT3 chips: {}", getNumberOfChips()); + for (int layer = 0; layer < getNumberOfLayers(); ++layer) { + const int nStaves = mFirstStaveIndexLayer[layer + 1] - mFirstStaveIndexLayer[layer]; + const int nChips = mFirstChipIndexLayer[layer + 1] - mFirstChipIndexLayer[layer]; + LOGP(info, "Layer {}: {} staves, {} chips", layer, nStaves, nChips); + } +} + +int GeometryTGeo::getLayer(int index) const +{ + for (int layer = 0; layer + 1 < mFirstChipIndexLayer.size(); ++layer) { + if (index >= mFirstChipIndexLayer[layer] && index < mFirstChipIndexLayer[layer + 1]) { + return layer; + } + } + return -1; +} + +int GeometryTGeo::getStave(int index) const +{ + const int layer = getLayer(index); + if (layer < 0) { + return -1; + } + for (int stave = mFirstStaveIndexLayer[layer]; stave < mFirstStaveIndexLayer[layer + 1]; ++stave) { + if (index >= mFirstChipIndexStave[stave] && index < mFirstChipIndexStave[stave + 1]) { + return stave - mFirstStaveIndexLayer[layer]; + } + } + return -1; +} + +int GeometryTGeo::getChip(int index) const +{ + const int layer = getLayer(index); + const int stave = getStave(index); + if (layer < 0 || stave < 0) { + return -1; + } + return index - mFirstChipIndexStave[mFirstStaveIndexLayer[layer] + stave]; +} + +int GeometryTGeo::getChipIndex(int layer, int stave, int chip) const +{ + if (layer < 0 || layer + 1 >= mFirstStaveIndexLayer.size()) { + return -1; + } + const int absStave = mFirstStaveIndexLayer[layer] + stave; + if (absStave < mFirstStaveIndexLayer[layer] || absStave >= mFirstStaveIndexLayer[layer + 1]) { + return -1; + } + const int chipIndex = mFirstChipIndexStave[absStave] + chip; + return chipIndex < mFirstChipIndexStave[absStave + 1] ? chipIndex : -1; +} + +int GeometryTGeo::getChipIndex(const std::string& volName) const +{ + int layer = -1, stave = 0, chip = 0; + extractChipIdsFT3(volName, layer, stave, chip); + return getChipIndex(layer, stave, chip); +} + +void GeometryTGeo::extractChipIdsFT3(std::string const& volName, int& layer, int& stave, int& chip) const +{ + layer = -1; + stave = 0; + chip = 0; + if (volName.find("FT3Sensor_Active") == 0) { + int idx = volName.find('_') + 1; + idx = volName.find('_', idx) + 1; + const int direction = std::stoi(volName.substr(idx)); + idx = volName.find('_', idx) + 1; + layer = std::stoi(volName.substr(idx)); + idx = volName.find('_', idx) + 1; + stave = std::stoi(volName.substr(idx)); + idx = volName.find('_', idx) + 1; + chip = std::stoi(volName.substr(idx)); + if (direction == 1) { + layer += mNumberOfLayersPerSide; + } + return; + } + if (volName.find("FT3Sensor_front_") == 0 || volName.find("FT3Sensor_back_") == 0) { + int idx = volName.find('_') + 1; + idx = volName.find('_', idx) + 1; + layer = std::stoi(volName.substr(idx)); + idx = volName.find('_', idx) + 1; + const int direction = std::stoi(volName.substr(idx)); + idx = volName.find('_', idx) + 1; + chip = std::stoi(volName.substr(idx)); + if (direction == 1) { + layer += mNumberOfLayersPerSide; + } + return; + } + if (volName.find("FT3Sensor_") == 0) { + int idx = std::string("FT3Sensor_").size(); + const int direction = std::stoi(volName.substr(idx)); + idx = volName.find('_', idx) + 1; + layer = std::stoi(volName.substr(idx)); + if (direction == 1) { + layer += mNumberOfLayersPerSide; + } + } +} diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/CMakeLists.txt new file mode 100644 index 0000000000000..98adea7c6124a --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/CMakeLists.txt @@ -0,0 +1,29 @@ +# 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. + +o2_add_library(FT3Simulation + SOURCES + src/FT3Module.cxx + src/FT3Layer.cxx + src/Detector.cxx + PUBLIC_LINK_LIBRARIES O2::FT3Base + O2::TRKFT3Simulation + O2::DataFormatsTRKFT3 + O2::ITSMFTSimulation + ROOT::Physics) + +o2_target_root_dictionary(FT3Simulation + HEADERS + include/FT3Simulation/FT3Module.h + include/FT3Simulation/Detector.h + include/FT3Simulation/FT3Layer.h) + +o2_data_file(COPY data DESTINATION Detectors/FT3/simulation) diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/data/simcuts.dat b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/data/simcuts.dat new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/include/FT3Simulation/Detector.h b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/include/FT3Simulation/Detector.h new file mode 100644 index 0000000000000..1d54a65dc4932 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/include/FT3Simulation/Detector.h @@ -0,0 +1,170 @@ +// 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. + +/// \file Detector.h +/// \brief Definition of the Detector class + +#ifndef ALICEO2_FT3_DETECTOR_H_ +#define ALICEO2_FT3_DETECTOR_H_ + +#include "Rtypes.h" // for Int_t, Double_t, Float_t, Bool_t, etc + +#include "DetectorsBase/Detector.h" // for Detector +#include "DetectorsBase/GeometryManager.h" // for getSensID +#include "DetectorsCommonDataFormats/DetID.h" // for Detector +#include "DataFormatsTRKFT3/Hit.h" // for Hit + +#include "TArrayD.h" // for TArrayD +#include "TGeoManager.h" // for gGeoManager, TGeoManager (ptr only) +#include "TLorentzVector.h" // for TLorentzVector +#include "TVector3.h" // for TVector3 + +#include +#include + +class FairVolume; +class TGeoVolume; + +class TParticle; + +class TString; + +namespace o2::ft3 +{ +class GeometryTGeo; +class FT3BaseParam; +class FT3Layer; + +class Detector : public o2::base::DetImpl +{ + public: + /// Name : Detector Name + /// Active: kTRUE for active detectors (ProcessHits() will be called) + /// kFALSE for inactive detectors + Detector(Bool_t active); + + /// Default constructor + Detector(); + + /// Default destructor + ~Detector() override; + + /// Initialization of the detector is done here + void InitializeO2Detector() override; + + /// This method is called for each step during simulation (see FairMCApplication::Stepping()) + Bool_t ProcessHits(FairVolume* v = nullptr) override; + + /// Registers the produced collections in FAIRRootManager + void Register() override; + + /// Gets the produced collections + std::vector* getHits(Int_t iColl) const + { + if (iColl == 0) { + return mHits; + } + return nullptr; + } + + /// Has to be called after each event to reset the containers + void Reset() override; + + /// Base class to create the detector geometry + void ConstructGeometry() override; + + /// This method is an example of how to add your own point of type Hit to the clones array + o2::trkft3::Hit* addHit(int trackID, int detID, const TVector3& startPos, const TVector3& endPos, + const TVector3& startMom, double startE, double endTime, double eLoss, + unsigned char startStatus, unsigned char endStatus); + + Int_t chipVolUID(Int_t id) const { return o2::base::GeometryManager::getSensID(o2::detectors::DetID::FT3, id); } + + void EndOfEvent() override; + + void FinishPrimary() override { ; } + virtual void finishRun() { ; } + void BeginPrimary() override { ; } + void PostTrack() override { ; } + void PreTrack() override { ; } + + static constexpr int IdxForwardDisks = 0; + static constexpr int IdxBackwardDisks = 1; + /// Returns the number of layers + size_t getNumberOfLayers() const + { + if (mLayerName[IdxBackwardDisks].size() != mLayerName[IdxForwardDisks].size()) { + LOG(fatal) << "Number of layers in the two directions are different! Returning 0."; + } + return mLayerName[IdxBackwardDisks].size(); + } + + void buildBasicFT3(const FT3BaseParam& param); + void buildFT3V1(); + void buildFT3V3b(); + void buildFT3Scoping(); + void buildFT3NewVacuumVessel(); + void buildFT3ScopingV3(); + + protected: + std::array, 2> mLayerName; // Two sets of layer names, one per direction (forward/backward) + std::unordered_map mActiveSensorMap; + + private: + /// this is transient data about track passing the sensor + struct TrackData { // this is transient + bool mHitStarted; //! hit creation started + unsigned char mTrkStatusStart; //! track status flag + TLorentzVector mPositionStart; //! position at entrance + TLorentzVector mMomentumStart; //! momentum + double mEnergyLoss; //! energy loss + } mTrackData; //! + + /// Container for hit data + std::vector* mHits; + + /// Create the detector materials + virtual void createMaterials(); + + /// Create the detector geometry + void createGeometry(); + + /// Define the sensitive volumes of the geometry + void defineSensitiveVolumes(); + + Detector(const Detector&); + + Detector& operator=(const Detector&); + + std::array, 2> mLayers; // Two sets of layers, one per direction (forward/backward) + bool mIsPipeActivated = true; //! If Alice 3 pipe is present append inner disks to vacuum volume to avoid overlaps + + template + friend class o2::base::DetImpl; + ClassDefOverride(Detector, 2); +}; + +} // namespace o2::ft3 + +#ifdef USESHM +namespace o2 +{ +namespace base +{ +template <> +struct UseShm { + static constexpr bool value = true; +}; +} // namespace base +} // namespace o2 +#endif + +#endif diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/FT3Layer.h b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/include/FT3Simulation/FT3Layer.h similarity index 92% rename from Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/FT3Layer.h rename to Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/include/FT3Simulation/FT3Layer.h index 5ccfc406009a1..282f8fd274ec0 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/FT3Layer.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/include/FT3Simulation/FT3Layer.h @@ -15,15 +15,16 @@ #ifndef ALICEO2_FT3_UPGRADEV3LAYER_H_ #define ALICEO2_FT3_UPGRADEV3LAYER_H_ -#include // for gGeoManager -#include "Rtypes.h" // for Double_t, Int_t, Bool_t, etc -#include "TRKSimulation/FT3Module.h" +#include // for gGeoManager +#include "Rtypes.h" // for Double_t, Int_t, Bool_t, etc +#include "FT3Simulation/Detector.h" // for Detector, Detector::Model +#include "FT3Simulation/FT3Module.h" class TGeoVolume; namespace o2 { -namespace trk +namespace ft3 { /// This class defines the Geometry for the FT3 Layer TGeo. This is a work class used @@ -91,7 +92,7 @@ class FT3Layer : public TObject ClassDefOverride(FT3Layer, 0); // ALICE 3 EndCaps geometry }; -} // namespace trk +} // namespace ft3 } // namespace o2 #endif diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/FT3Module.h b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/include/FT3Simulation/FT3Module.h similarity index 97% rename from Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/FT3Module.h rename to Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/include/FT3Simulation/FT3Module.h index f71bab0a1e882..75c1cfb7210e3 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/FT3Module.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/include/FT3Simulation/FT3Module.h @@ -19,7 +19,7 @@ #include #include -#include "TRKSimulation/FT3ModuleConstants.h" +#include "FT3Simulation/FT3ModuleConstants.h" // define types for y positions, second element is the stack height using PositionType = std::pair; @@ -27,7 +27,7 @@ using PositionTypes = std::vector; using PosNegPositionTypes = std::pair; // define type of the y position range: First pair is (min, max) for positive y using PositionRangeType = std::pair, std::pair>; -namespace Constants = o2::trk::FT3ModuleConstants; +namespace Constants = o2::ft3::ModuleConstants; class FT3Module { diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/FT3ModuleConstants.h b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/include/FT3Simulation/FT3ModuleConstants.h similarity index 99% rename from Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/FT3ModuleConstants.h rename to Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/include/FT3Simulation/FT3ModuleConstants.h index 9069e4cf906bd..4f2bfce5c3f1d 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/FT3ModuleConstants.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/include/FT3Simulation/FT3ModuleConstants.h @@ -20,7 +20,7 @@ #include #include -namespace o2::trk::FT3ModuleConstants +namespace o2::ft3::ModuleConstants { /* CURRENT STATUS: * 25x29mm sensors, 2mm inactive on one side @@ -215,6 +215,6 @@ inline StaveConfig getStaveConfig(bool isInnerDisk) } } -} // namespace o2::trk::FT3ModuleConstants +} // namespace o2::ft3::ModuleConstants #endif // FT3MODULECONSTANTS_H \ No newline at end of file diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/Detector.cxx new file mode 100644 index 0000000000000..07c97e01dbdc9 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/Detector.cxx @@ -0,0 +1,684 @@ +// 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. + +/// \file Detector.cxx +/// \brief Implementation of the Detector class + +#include "FT3Simulation/Detector.h" + +#include "DetectorsBase/Stack.h" +#include "SimulationDataFormat/TrackReference.h" + +#include "FT3Base/FT3BaseParam.h" +#include "FT3Base/GeometryTGeo.h" +#include "FT3Simulation/FT3Layer.h" + +// FairRoot includes +#include "FairDetector.h" // for FairDetector +#include "FairRootManager.h" // for FairRootManager +#include "FairRootManager.h" +#include "FairRun.h" // for FairRun +#include "FairRuntimeDb.h" // for FairRuntimeDb +#include "FairVolume.h" // for FairVolume + +#include "TGeoManager.h" // for TGeoManager, gGeoManager +#include "TGeoPcon.h" // for TGeoPcon +#include "TGeoTube.h" // for TGeoTube +#include "TGeoVolume.h" // for TGeoVolume, TGeoVolumeAssembly +#include "TString.h" // for TString, operator+ +#include "TVirtualMC.h" // for gMC, TVirtualMC +#include "TVirtualMCStack.h" // for TVirtualMCStack + +#include // for LOG, LOG_IF + +#include // for NULL, snprintf + +#define MAX_SENSORS 2000 + +class FairModule; + +class TGeoMedium; + +class TParticle; + +using namespace o2::ft3; +using o2::trkft3::Hit; + +//_________________________________________________________________________________________________ +Detector::Detector() + : o2::base::DetImpl("FT3", kTRUE), + mTrackData(), + mHits(o2::utils::createSimVector()) +{ +} + +//_________________________________________________________________________________________________ +void Detector::buildBasicFT3(const FT3BaseParam& param) +{ + // Build a basic parametrized FT3 detector with nLayers equally spaced between z_first and z_first+z_length + // Covering pseudo rapidity [etaIn,etaOut]. Silicon thinkness computed to match layer x/X0 + + LOG(info) << "Building FT3 Detector: Conical Telescope"; + + const int numberOfLayers = param.nLayers; + const auto z_first = param.z0; + const auto z_length = param.zLength; + const auto etaIn = param.etaIn; + const auto etaOut = param.etaOut; + const auto Layerx2X0 = param.Layerx2X0; + mLayerName[IdxBackwardDisks].resize(numberOfLayers); + mLayerName[IdxForwardDisks].resize(numberOfLayers); + + for (int direction : {IdxBackwardDisks, IdxForwardDisks}) { + for (int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) { + std::string layerName = GeometryTGeo::getFT3LayerPattern() + std::to_string(layerNumber + numberOfLayers * direction); + mLayerName[direction][layerNumber] = layerName; + + // Adds evenly spaced layers + const float layerZ = z_first + (layerNumber * z_length / numberOfLayers) * std::copysign(1, z_first); + const float rIn = std::abs(layerZ * std::tan(2.f * std::atan(std::exp(-etaIn)))); + const float rOut = std::abs(layerZ * std::tan(2.f * std::atan(std::exp(-etaOut)))); + const bool isMiddleLayer = layerNumber < 3; + auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, layerZ, rIn, rOut, Layerx2X0, isMiddleLayer); + } + } +} + +//_________________________________________________________________________________________________ +void Detector::buildFT3V1() +{ + // Build FT3 detector according to + // https://indico.cern.ch/event/992488/contributions/4174473/attachments/2168881/3661331/tracker_parameters_werner_jan_11_2021.pdf + + LOG(info) << "Building FT3 Detector: V1"; + + const int numberOfLayers = 10; + const float sensorThickness = 30.e-4; + const float layersx2X0 = 1.e-2; + const std::vector> layersConfig{ + {26., .5, 3., 0.1f * layersx2X0}, // {z_layer, r_in, r_out, Layerx2X0} + {30., .5, 3., 0.1f * layersx2X0}, + {34., .5, 3., 0.1f * layersx2X0}, + {77., 3.5, 35., layersx2X0}, + {100., 3.5, 35., layersx2X0}, + {122., 3.5, 35., layersx2X0}, + {150., 3.5, 80.f, layersx2X0}, + {180., 3.5, 80.f, layersx2X0}, + {220., 3.5, 80.f, layersx2X0}, + {279., 3.5, 80.f, layersx2X0}}; + + mLayerName[IdxBackwardDisks].resize(numberOfLayers); + mLayerName[IdxForwardDisks].resize(numberOfLayers); + + for (auto direction : {IdxBackwardDisks, IdxForwardDisks}) { + for (int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) { + std::string directionName = std::to_string(direction); + std::string layerName = GeometryTGeo::getFT3LayerPattern() + directionName + std::string("_") + std::to_string(layerNumber); + mLayerName[direction][layerNumber] = layerName; + auto& z = layersConfig[layerNumber][0]; + + auto& rIn = layersConfig[layerNumber][1]; + auto& rOut = layersConfig[layerNumber][2]; + auto& x0 = layersConfig[layerNumber][3]; + + LOG(info) << "Adding Layer " << layerName << " at z = " << z; + // Add layers + const bool isMiddleLayer = layerNumber < 3; + auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, z, rIn, rOut, x0, isMiddleLayer); + } + } +} + +//_________________________________________________________________________________________________ +void Detector::buildFT3V3b() +{ + // Build FT3 detector according to + // https://www.overleaf.com/project/6051acc870e39aaeb4653621 + + LOG(info) << "Building FT3 Detector: V3b"; + + const int numberOfLayers = 12; + float sensorThickness = 30.e-4; + float layersx2X0 = 1.e-2; + std::vector> layersConfig{ + {26., .5, 3., 0.1f * layersx2X0}, // {z_layer, r_in, r_out, Layerx2X0} + {30., .5, 3., 0.1f * layersx2X0}, + {34., .5, 3., 0.1f * layersx2X0}, + {77., 5.0, 35., layersx2X0}, + {100., 5.0, 35., layersx2X0}, + {122., 5.0, 35., layersx2X0}, + {150., 5.5, 80.f, layersx2X0}, + {180., 6.6, 80.f, layersx2X0}, + {220., 8.1, 80.f, layersx2X0}, + {279., 10.2, 80.f, layersx2X0}, + {340., 12.5, 80.f, layersx2X0}, + {400., 14.7, 80.f, layersx2X0}}; + + mLayerName[IdxBackwardDisks].resize(numberOfLayers); + mLayerName[IdxForwardDisks].resize(numberOfLayers); + + for (auto direction : {IdxBackwardDisks, IdxForwardDisks}) { + for (int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) { + std::string directionName = std::to_string(direction); + std::string layerName = GeometryTGeo::getFT3LayerPattern() + directionName + std::string("_") + std::to_string(layerNumber); + mLayerName[direction][layerNumber] = layerName; + auto& z = layersConfig[layerNumber][0]; + + auto& rIn = layersConfig[layerNumber][1]; + auto& rOut = layersConfig[layerNumber][2]; + auto& x0 = layersConfig[layerNumber][3]; + + LOG(info) << "Adding Layer " << layerName << " at z = " << z; + // Add layers + const bool isMiddleLayer = layerNumber < 3; + auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, z, rIn, rOut, x0, isMiddleLayer); + } + } +} + +void Detector::buildFT3NewVacuumVessel() +{ + // Build the FT3 detector according to changes proposed during + // https://indico.cern.ch/event/1407704/ + // to adhere to the changes that were presented at the ALICE 3 Upgrade days in March 2024 + // Inner radius at C-side to 7 cm + // Inner radius at A-side stays at 5 cm + // 06.02.2025 update: IRIS layers are now in TRK + + LOG(info) << "Building FT3 Detector: After Upgrade Days March 2024 version"; + + const int numberOfLayers = 9; + const float sensorThickness = 30.e-4; + const float layersx2X0 = 1.e-2; + const std::vector> layersConfigCSide{ + {77., 7.0, 35., layersx2X0}, // {z_layer, r_in, r_out, Layerx2X0} + {100., 7.0, 35., layersx2X0}, + {122., 7.0, 35., layersx2X0}, + {150., 7.0, 68.f, layersx2X0}, + {180., 7.0, 68.f, layersx2X0}, + {220., 7.0, 68.f, layersx2X0}, + {260., 7.0, 68.f, layersx2X0}, + {300., 7.0, 68.f, layersx2X0}, + {350., 7.0, 68.f, layersx2X0}}; + + const std::vector> layersConfigASide{ + {77., 5.0, 35., layersx2X0}, // {z_layer, r_in, r_out, Layerx2X0} + {100., 5.0, 35., layersx2X0}, + {122., 5.0, 35., layersx2X0}, + {150., 5.0, 68.f, layersx2X0}, + {180., 5.0, 68.f, layersx2X0}, + {220., 5.0, 68.f, layersx2X0}, + {260., 5.0, 68.f, layersx2X0}, + {300., 5.0, 68.f, layersx2X0}, + {350., 5.0, 68.f, layersx2X0}}; + + mLayerName[IdxBackwardDisks].resize(numberOfLayers); + mLayerName[IdxForwardDisks].resize(numberOfLayers); + + for (auto direction : {IdxBackwardDisks, IdxForwardDisks}) { + for (int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) { + std::string directionName = std::to_string(direction); + std::string layerName = GeometryTGeo::getFT3LayerPattern() + directionName + std::string("_") + std::to_string(layerNumber); + mLayerName[direction][layerNumber] = layerName; + float z, rIn, rOut, x0; + if (direction == 0) { // C-Side + z = layersConfigCSide[layerNumber][0]; + rIn = layersConfigCSide[layerNumber][1]; + rOut = layersConfigCSide[layerNumber][2]; + x0 = layersConfigCSide[layerNumber][3]; + } else if (direction == 1) { // A-Side + z = layersConfigASide[layerNumber][0]; + rIn = layersConfigASide[layerNumber][1]; + rOut = layersConfigASide[layerNumber][2]; + x0 = layersConfigASide[layerNumber][3]; + } + + LOG(info) << "Adding Layer " << layerName << " at z = " << z; + // Add layers + const bool isMiddleLayer = layerNumber < 3; + auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, z, rIn, rOut, x0, isMiddleLayer); + } + } +} + +void Detector::buildFT3ScopingV3() +{ + // Build the FT3 detector according to v3 layout + // https://indico.cern.ch/event/1596309/contributions/6728167/attachments/3190117/5677220/2025-12-10-AW-ALICE3planning.pdf + // Middle disks inner radius 10 cm + // Outer disks inner radius 20 cm + + LOG(info) << "Building FT3 Detector: v3 scoping version"; + + const int numberOfLayers = 6; + const float sensorThickness = 30.e-4; + const float layersx2X0 = 1.e-2; + using LayerConfig = std::array; // {z_layer, r_in, r_out, Layerx2X0} + const std::array layersConfigCSide{LayerConfig{77., 10.0, 35., layersx2X0}, + LayerConfig{100., 10.0, 35., layersx2X0}, + LayerConfig{122., 10.0, 35., layersx2X0}, + LayerConfig{150., 20.0, 68.f, layersx2X0}, + LayerConfig{180., 20.0, 68.f, layersx2X0}, + LayerConfig{220., 20.0, 68.f, layersx2X0}}; + + const std::array layersConfigASide{LayerConfig{77., 10.0, 35., layersx2X0}, + LayerConfig{100., 10.0, 35., layersx2X0}, + LayerConfig{122., 10.0, 35., layersx2X0}, + LayerConfig{150., 20.0, 68.f, layersx2X0}, + LayerConfig{180., 20.0, 68.f, layersx2X0}, + LayerConfig{220., 20.0, 68.f, layersx2X0}}; + const std::array enabled{true, true, true, true, true, true}; // To enable or disable layers for debug purpose + + for (int direction : {IdxBackwardDisks, IdxForwardDisks}) { + mLayerName[direction].clear(); + const std::array& layerConfig = (direction == IdxBackwardDisks) ? layersConfigCSide : layersConfigASide; + for (int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) { + if (!enabled[layerNumber]) { + continue; + } + const std::string directionName = std::to_string(direction); + const std::string layerName = GeometryTGeo::getFT3LayerPattern() + directionName + std::string("_") + std::to_string(layerNumber); + mLayerName[direction].push_back(layerName.c_str()); + const float z = layerConfig[layerNumber][0]; + const float rIn = layerConfig[layerNumber][1]; + const float rOut = layerConfig[layerNumber][2]; + const float x0 = layerConfig[layerNumber][3]; + LOG(info) << "buildFT3ScopingV3 -> Adding Layer " << layerNumber << "/" << numberOfLayers << " " << layerName << " at z = " << z; + // Add layers + const bool isMiddleLayer = layerNumber < 3; + auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, z, rIn, rOut, x0, isMiddleLayer); + } + } +} + +//_________________________________________________________________________________________________ +void Detector::buildFT3Scoping() +{ + // Build FT3 detector according to the scoping document + + LOG(info) << "Building FT3 Detector: Scoping document version"; + + const int numberOfLayers = 12; + const float sensorThickness = 30.e-4; + const float layersx2X0 = 1.e-2; + const std::vector> layersConfig{ + {26., .5, 2.5, 0.1f * layersx2X0}, // {z_layer, r_in, r_out, Layerx2X0} + {30., .5, 2.5, 0.1f * layersx2X0}, + {34., .5, 2.5, 0.1f * layersx2X0}, + {77., 5.0, 35., layersx2X0}, + {100., 5.0, 35., layersx2X0}, + {122., 5.0, 35., layersx2X0}, + {150., 5.0, 68.f, layersx2X0}, + {180., 5.0, 68.f, layersx2X0}, + {220., 5.0, 68.f, layersx2X0}, + {260., 5.0, 68.f, layersx2X0}, + {300., 5.0, 68.f, layersx2X0}, + {350., 5.0, 68.f, layersx2X0}}; + + mLayerName[IdxBackwardDisks].resize(numberOfLayers); + mLayerName[IdxForwardDisks].resize(numberOfLayers); + + for (auto direction : {IdxBackwardDisks, IdxForwardDisks}) { + for (int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) { + std::string directionName = std::to_string(direction); + std::string layerName = GeometryTGeo::getFT3LayerPattern() + directionName + std::string("_") + std::to_string(layerNumber); + mLayerName[direction][layerNumber] = layerName; + auto& z = layersConfig[layerNumber][0]; + auto& rIn = layersConfig[layerNumber][1]; + auto& rOut = layersConfig[layerNumber][2]; + auto& x0 = layersConfig[layerNumber][3]; + + LOG(info) << "Adding Layer " << layerName << " at z = " << z; + // Add layers + const bool isMiddleLayer = layerNumber < 3; + auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, z, rIn, rOut, x0, isMiddleLayer); + } + } +} + +//_________________________________________________________________________________________________ +Detector::Detector(bool active) + : o2::base::DetImpl("FT3", active), + mTrackData(), + mHits(o2::utils::createSimVector()) +{ + buildFT3ScopingV3(); // v3 Dec 25 +} + +//_________________________________________________________________________________________________ +Detector::Detector(const Detector& rhs) + : o2::base::DetImpl(rhs), + mTrackData(), + + /// Container for data points + mHits(o2::utils::createSimVector()) +{ + mLayerName = rhs.mLayerName; + mActiveSensorMap = rhs.mActiveSensorMap; +} + +//_________________________________________________________________________________________________ +Detector::~Detector() +{ + + if (mHits) { + // delete mHits; + o2::utils::freeSimVector(mHits); + } +} + +//_________________________________________________________________________________________________ +Detector& Detector::operator=(const Detector& rhs) +{ + // The standard = operator + // Inputs: + // Detector &h the sourse of this copy + // Outputs: + // none. + // Return: + // A copy of the sourse hit h + + if (this == &rhs) { + return *this; + } + + // base class assignment + base::Detector::operator=(rhs); + + mLayerName = rhs.mLayerName; + mActiveSensorMap = rhs.mActiveSensorMap; + mLayers = rhs.mLayers; + mTrackData = rhs.mTrackData; + + /// Container for data points + mHits = nullptr; + + return *this; +} + +//_________________________________________________________________________________________________ +void Detector::InitializeO2Detector() +{ + // Define the list of sensitive volumes + LOG(info) << "Initialize FT3 O2Detector"; + + defineSensitiveVolumes(); +} + +//_________________________________________________________________________________________________ +bool Detector::ProcessHits(FairVolume* vol) +{ + // This method is called from the MC stepping + if (!(fMC->TrackCharge())) { + return kFALSE; + } + + int volID = vol->getMCid(); + + auto it = mActiveSensorMap.find(volID); + if (it == mActiveSensorMap.end()) { + return kFALSE; // Not a sensitive volume + } + + int lay = it->second; + + auto stack = (o2::data::Stack*)fMC->GetStack(); + + bool startHit = false, stopHit = false; + unsigned char status = 0; + if (fMC->IsTrackEntering()) { + status |= Hit::kTrackEntering; + } + if (fMC->IsTrackInside()) { + status |= Hit::kTrackInside; + } + if (fMC->IsTrackExiting()) { + status |= Hit::kTrackExiting; + } + if (fMC->IsTrackOut()) { + status |= Hit::kTrackOut; + } + if (fMC->IsTrackStop()) { + status |= Hit::kTrackStopped; + } + if (fMC->IsTrackAlive()) { + status |= Hit::kTrackAlive; + } + + // track is entering or created in the volume + if ((status & Hit::kTrackEntering) || (status & Hit::kTrackInside && !mTrackData.mHitStarted)) { + startHit = true; + } else if ((status & (Hit::kTrackExiting | Hit::kTrackOut | Hit::kTrackStopped))) { + stopHit = true; + } + + // increment energy loss at all steps except entrance + if (!startHit) { + mTrackData.mEnergyLoss += fMC->Edep(); + } + if (!(startHit | stopHit)) { + return kFALSE; // do noting + } + if (startHit) { + mTrackData.mEnergyLoss = 0.; + fMC->TrackMomentum(mTrackData.mMomentumStart); + fMC->TrackPosition(mTrackData.mPositionStart); + mTrackData.mTrkStatusStart = status; + mTrackData.mHitStarted = true; + } + if (stopHit) { + TLorentzVector positionStop; + fMC->TrackPosition(positionStop); + // Retrieve the indices with the volume path + int chipindex = lay; + + Hit* p = addHit(stack->GetCurrentTrackNumber(), chipindex, mTrackData.mPositionStart.Vect(), positionStop.Vect(), + mTrackData.mMomentumStart.Vect(), mTrackData.mMomentumStart.E(), positionStop.T(), + mTrackData.mEnergyLoss, mTrackData.mTrkStatusStart, status); + // p->SetTotalEnergy(vmc->Etot()); + + // RS: not sure this is needed + // Increment number of Detector det points in TParticle + stack->addHit(GetDetId()); + } + + return kTRUE; +} + +//_________________________________________________________________________________________________ +void Detector::createMaterials() +{ + int ifield = 2; + float fieldm = 10.0; + o2::base::Detector::initFieldTrackingParams(ifield, fieldm); + + float tmaxfdSi = 0.1; // .10000E+01; // Degree + float stemaxSi = 0.0075; // .10000E+01; // cm + float deemaxSi = 0.1; // 0.30000E-02; // Fraction of particle's energy 0RegisterAny(addNameTo("Hit").data(), mHits, kTRUE); + } +} + +//_________________________________________________________________________________________________ +void Detector::Reset() +{ + if (!o2::utils::ShmManager::Instance().isOperational()) { + mHits->clear(); + } +} + +//_________________________________________________________________________________________________ +void Detector::ConstructGeometry() +{ + // Create detector materials + createMaterials(); + + // Construct the detector geometry + createGeometry(); +} + +//_________________________________________________________________________________________________ +void Detector::createGeometry() +{ + + TGeoVolume* volFT3 = new TGeoVolumeAssembly(GeometryTGeo::getFT3VolPattern()); + TGeoVolume* volIFT3 = new TGeoVolumeAssembly(GeometryTGeo::getFT3InnerVolPattern()); + + LOG(info) << "FT3: createGeometry volume name = " << GeometryTGeo::getFT3VolPattern(); + + TGeoVolume* vALIC = gGeoManager->GetVolume("barrel"); + if (!vALIC) { + LOG(fatal) << "Could not find the top volume"; + } + + TGeoVolume* A3IPvac = gGeoManager->GetVolume("OUT_PIPEVACUUM"); + if (!A3IPvac) { + LOG(info) << "Running simulation with no beam pipe."; + } + + // This will need to adapt to the new scheme + if (!A3IPvac) { + for (int direction : {IdxBackwardDisks, IdxForwardDisks}) { // Backward layers at mLayers[0]; Forward layers at mLayers[1] + const std::string directionString = direction ? "Forward" : "Backward"; + LOG(info) << " Creating FT3 without beampipe " << directionString << " layers:"; + for (int iLayer = 0; iLayer < mLayers[direction].size(); iLayer++) { + mLayers[direction][iLayer].createLayer(volFT3); + } + } + vALIC->AddNode(volFT3, 2, new TGeoTranslation(0., 30., 0.)); + } else { // If beampipe is enabled append inner disks to beampipe filling volume, this should be temporary. + for (int direction : {IdxBackwardDisks, IdxForwardDisks}) { + const std::string directionString = direction ? "Forward" : "Backward"; + LOG(info) << " Creating FT3 " << directionString << " layers:"; + for (int iLayer = 0; iLayer < mLayers[direction].size(); iLayer++) { + LOG(info) << " Creating " << directionString << " layer " << iLayer; + if (mLayers[direction][iLayer].getIsInMiddleLayer()) { // ML disks + mLayers[direction][iLayer].createLayer(volIFT3); + } else { + mLayers[direction][iLayer].createLayer(volFT3); + } + } + } + A3IPvac->AddNode(volIFT3, 2, new TGeoTranslation(0., 0., 0.)); + vALIC->AddNode(volFT3, 2, new TGeoTranslation(0., 30., 0.)); + } +} + +//_________________________________________________________________________________________________ +void Detector::defineSensitiveVolumes() +{ + TGeoManager* geoManager = gGeoManager; + + // Get the flat list of ALL volumes present in the geometry + TObjArray* allVolumes = geoManager->GetListOfVolumes(); + int nVolumes = allVolumes->GetEntriesFast(); + + LOG(info) << "Adding FT3 Sensitive Volumes by iterating over all geometry volumes..."; + auto* geom = GeometryTGeo::Instance(); + + for (int direction : {IdxBackwardDisks, IdxForwardDisks}) { + for (int iLayer = 0; iLayer < getNumberOfLayers(); iLayer++) { + int iSens = 0; + + // Build the "signatures" (prefixes) of the names for the various layouts for this specific layer and direction: + + // 1. Trapezoidal/Cylindrical (format: FT3Sensor__) + std::string sig1 = Form("%s_%d_%d", GeometryTGeo::getFT3SensorPattern(), direction, iLayer); + + // 2. Segmented front/back (format: FT3Sensor_front___...) + std::string sig2 = "FT3Sensor_front_" + std::to_string(iLayer) + "_" + std::to_string(direction); + std::string sig3 = "FT3Sensor_back_" + std::to_string(iLayer) + "_" + std::to_string(direction); + + // 3. SegmentedStave (format: FT3Sensor___...) + // Add the trailing underscore to avoid confusing it with sig1 + std::string sig4 = "FT3Sensor_" + std::to_string(direction) + "_" + std::to_string(iLayer) + "_"; + + // Iterate over all existing volumes to find matches + for (int i = 0; i < nVolumes; ++i) { + TGeoVolume* v = (TGeoVolume*)allVolumes->At(i); + std::string vName = v->GetName(); + + // Explicitly exclude the inactive silicon regions created in FT3Module + if (vName.find("Inactive") != std::string::npos || vName.find("inactive") != std::string::npos) { + continue; + } + + // Check if the volume name matches one of our active sensors + bool isMatch = false; + if (vName == sig1) { + isMatch = true; // Exact match for Trapezoidal/Cylindrical layouts + } else if (vName.find(sig2) == 0 || vName.find(sig3) == 0 || vName.find(sig4) == 0) { + isMatch = true; // Prefix match for Segmented and SegmentedStave layouts + } + + if (isMatch) { + AddSensitiveVolume(v); + int volID = gMC ? TVirtualMC::GetMC()->VolId(vName.c_str()) : 0; + if (volID > 0) { + const int chipID = geom->getChipIndex(vName); + mActiveSensorMap[volID] = chipID >= 0 ? chipID : iLayer; + } + iSens++; + } + } + + if (iSens == 0) { + LOG(error) << "NO sensitive volume found for direction " << direction << ", layer " << iLayer; + } else { + LOG(info) << iSens << " sensitive volume(s) added for direction " << direction << " layer " << iLayer; + } + } + } +} + +//_________________________________________________________________________________________________ +Hit* Detector::addHit(int trackID, int detID, const TVector3& startPos, const TVector3& endPos, + const TVector3& startMom, double startE, double endTime, double eLoss, unsigned char startStatus, + unsigned char endStatus) +{ + mHits->emplace_back(trackID, detID, startPos, endPos, startMom, startE, endTime, eLoss, startStatus, endStatus); + return &(mHits->back()); +} + +ClassImp(o2::ft3::Detector); diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/FT3Layer.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Layer.cxx similarity index 84% rename from Detectors/Upgrades/ALICE3/TRK/simulation/src/FT3Layer.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Layer.cxx index f14393dd866d8..7fce06e029764 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/FT3Layer.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Layer.cxx @@ -14,10 +14,10 @@ /// \author Mario Sitta /// \author Chinorat Kobdaj (kobdaj@g.sut.ac.th) -#include "TRKSimulation/FT3Layer.h" -#include "TRKBase/GeometryTGeo.h" -#include "TRKBase/TRKBaseParam.h" -#include "TRKSimulation/FT3ModuleConstants.h" +#include "FT3Simulation/FT3Layer.h" +#include "FT3Base/GeometryTGeo.h" +#include "FT3Base/FT3BaseParam.h" +#include "FT3Simulation/FT3ModuleConstants.h" #include // for TGeoManager, gGeoManager #include // for TGeoCombiTrans, TGeoRotation, etc @@ -31,7 +31,7 @@ class TGeoMedium; using namespace TMath; -using namespace o2::trk; +using namespace o2::ft3; ClassImp(FT3Layer); @@ -234,9 +234,9 @@ void FT3Layer::createReferenceCircles(TGeoVolume* motherVolume, const std::strin TGeoTube* outerCircle = new TGeoTube(mOuterRadius - 0.1, mOuterRadius + 0.1, 0.01); TGeoTube* outerCircleEdge = new TGeoTube(mOuterRadius + 3.3, mOuterRadius + 3.5, 0.01); - TGeoVolume* innerCircleVol = new TGeoVolume((mLayerName + "_InnerCircle").c_str(), innerCircle, gGeoManager->GetMedium("TRK_AIR$")); - TGeoVolume* outerCircleVol = new TGeoVolume((mLayerName + "_OuterCircle").c_str(), outerCircle, gGeoManager->GetMedium("TRK_AIR$")); - TGeoVolume* outerCircleEdgeVol = new TGeoVolume((mLayerName + "_OuterCircleEdge").c_str(), outerCircleEdge, gGeoManager->GetMedium("TRK_AIR$")); + TGeoVolume* innerCircleVol = new TGeoVolume((mLayerName + "_InnerCircle").c_str(), innerCircle, gGeoManager->GetMedium("FT3_AIR$")); + TGeoVolume* outerCircleVol = new TGeoVolume((mLayerName + "_OuterCircle").c_str(), outerCircle, gGeoManager->GetMedium("FT3_AIR$")); + TGeoVolume* outerCircleEdgeVol = new TGeoVolume((mLayerName + "_OuterCircleEdge").c_str(), outerCircleEdge, gGeoManager->GetMedium("FT3_AIR$")); innerCircleVol->SetLineColor(kRed); outerCircleVol->SetLineColor(kBlue); @@ -251,36 +251,36 @@ void FT3Layer::createReferenceCircles(TGeoVolume* motherVolume, const std::strin void FT3Layer::createLayer(TGeoVolume* motherVolume) { - auto& trkParams = TRKBaseParam::Instance(); + auto& ft3Params = FT3BaseParam::Instance(); if (mLayerNumber < 0) { LOG(fatal) << "Invalid layer number " << mLayerNumber << " for FT3 layer."; } - LOG(info) << "FT3: TRKParams.layoutFT3 = " << trkParams.layoutFT3 + LOG(info) << "FT3: ft3Params.layoutFT3 = " << ft3Params.layoutFT3 << " Creating Layer " << mLayerNumber << " at z=" << mZ << " with direction " << mDirection; // ### options for ML and OT disk layout - if (trkParams.layoutFT3 == kTrapezoidal /*|| (mIsMiddleLayer && ft3Params.layoutFT3 == kSegmented)*/) { + if (ft3Params.layoutFT3 == kTrapezoidal /*|| (mIsMiddleLayer && ft3Params.layoutFT3 == kSegmented)*/) { // trapezoidal ML+OT disks // (disks with TGeoTubes doesn'n work properly in ACTS, due to polar coordinates on TGeoTube sides) // (!) Currently (March 12, 2026), only OT disks are segmented --> use Trapezoidal option for ML disks as a simplified segmentation // To be changed to "true" paving with modules, as for the OT disks - std::string chipName = GeometryTGeo::getFT3ChipPattern() + std::to_string(mLayerNumber); + std::string chipName = o2::ft3::GeometryTGeo::getFT3ChipPattern() + std::to_string(mLayerNumber); std::string sensName = Form("%s_%d_%d", GeometryTGeo::getFT3SensorPattern(), mDirection, mLayerNumber); - std::string passiveName = GeometryTGeo::getFT3PassivePattern() + std::to_string(mLayerNumber); + std::string passiveName = o2::ft3::GeometryTGeo::getFT3PassivePattern() + std::to_string(mLayerNumber); - TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$"); - TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$"); + TGeoMedium* medSi = gGeoManager->GetMedium("FT3_SILICON$"); + TGeoMedium* medAir = gGeoManager->GetMedium("FT3_AIR$"); TGeoTube* layer = new TGeoTube(mInnerRadius, mOuterRadius, mChipThickness / 2); TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir); layerVol->SetLineColor(kGray); - const int NtrapezoidalSegments = trkParams.nTrapezoidalSegments; + const int NtrapezoidalSegments = ft3Params.nTrapezoidalSegments; const double dz = mChipThickness / 2; const double dzSensor = mSensorThickness / 2; @@ -375,16 +375,47 @@ void FT3Layer::createLayer(TGeoVolume* motherVolume) auto* diskRotation = new TGeoRotation("TrapezoidalDiskRotation", 0, 0, 0); auto* diskCombiTrans = new TGeoCombiTrans(0, 0, mZ, diskRotation); motherVolume->AddNode(layerVol, 1, diskCombiTrans); - } else if (trkParams.layoutFT3 == kSegmentedFT3 || - (trkParams.layoutFT3 == kSegmentedStaveOTOnly && mIsMiddleLayer)) { + } else if (ft3Params.layoutFT3 == kCylindrical) { + // cylindrical ML+OT disks + + std::string chipName = o2::ft3::GeometryTGeo::getFT3ChipPattern() + std::to_string(mLayerNumber), + sensName = Form("%s_%d_%d", GeometryTGeo::getFT3SensorPattern(), mDirection, mLayerNumber); + TGeoTube* sensor = new TGeoTube(mInnerRadius, mOuterRadius, mChipThickness / 2); + TGeoTube* chip = new TGeoTube(mInnerRadius, mOuterRadius, mChipThickness / 2); + TGeoTube* layer = new TGeoTube(mInnerRadius, mOuterRadius, mChipThickness / 2); + + TGeoMedium* medSi = gGeoManager->GetMedium("FT3_SILICON$"); + TGeoMedium* medAir = gGeoManager->GetMedium("FT3_AIR$"); + + TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi); + sensVol->SetLineColor(kYellow); + TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi); + chipVol->SetLineColor(kYellow); + TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir); + layerVol->SetLineColor(kYellow); + + LOG(info) << "Inserting " << sensVol->GetName() << " inside " << chipVol->GetName(); + chipVol->AddNode(sensVol, 1, nullptr); + + LOG(info) << "Inserting " << chipVol->GetName() << " inside " << layerVol->GetName(); + layerVol->AddNode(chipVol, 1, nullptr); + + // Finally put everything in the mother volume + auto* FwdDiskRotation = new TGeoRotation("FwdDiskRotation", 0, 0, 180); + auto* FwdDiskCombiTrans = new TGeoCombiTrans(0, 0, mZ, FwdDiskRotation); + + LOG(info) << "Inserting " << layerVol->GetName() << " inside " << motherVolume->GetName(); + motherVolume->AddNode(layerVol, 1, FwdDiskCombiTrans); + } else if (ft3Params.layoutFT3 == kSegmented || + (ft3Params.layoutFT3 == kSegmentedStaveOTOnly && mIsMiddleLayer)) { FT3Module module; // layer structure - std::string frontLayerName = GeometryTGeo::getFT3LayerPattern() + std::to_string(mDirection) + std::to_string(mLayerNumber) + "_Front"; - std::string backLayerName = GeometryTGeo::getFT3LayerPattern() + std::to_string(mDirection) + std::to_string(mLayerNumber) + "_Back"; + std::string frontLayerName = o2::ft3::GeometryTGeo::getFT3LayerPattern() + std::to_string(mDirection) + std::to_string(mLayerNumber) + "_Front"; + std::string backLayerName = o2::ft3::GeometryTGeo::getFT3LayerPattern() + std::to_string(mDirection) + std::to_string(mLayerNumber) + "_Back"; std::string separationLayerName = "FT3SeparationLayer" + std::to_string(mDirection) + std::to_string(mLayerNumber); - TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$"); + TGeoMedium* medAir = gGeoManager->GetMedium("FT3_AIR$"); TGeoVolume* layerVol = nullptr; // Add a little additional room in radius TGeoTube* layer = new TGeoTube(mInnerRadius - 0.1, mOuterRadius + 0.1, 1.5); @@ -402,16 +433,16 @@ void FT3Layer::createLayer(TGeoVolume* motherVolume) LOG(info) << "Inserting " << layerVol->GetName() << " (Rmin=" << mInnerRadius << ", Rmax=" << mOuterRadius << ", z=" << mZ << "cm) inside " << motherVolume->GetName(); motherVolume->AddNode(layerVol, 1, FwdDiskCombiTrans); - } else if (trkParams.layoutFT3 == kSegmentedStave || - trkParams.layoutFT3 == kSegmentedStaveOTOnly) { + } else if (ft3Params.layoutFT3 == kSegmentedStave || + ft3Params.layoutFT3 == kSegmentedStaveOTOnly) { FT3Module module; // layer structure - std::string frontLayerName = GeometryTGeo::getFT3LayerPattern() + std::to_string(mDirection) + std::to_string(mLayerNumber) + "_Front"; - std::string backLayerName = GeometryTGeo::getFT3LayerPattern() + std::to_string(mDirection) + std::to_string(mLayerNumber) + "_Back"; + std::string frontLayerName = o2::ft3::GeometryTGeo::getFT3LayerPattern() + std::to_string(mDirection) + std::to_string(mLayerNumber) + "_Front"; + std::string backLayerName = o2::ft3::GeometryTGeo::getFT3LayerPattern() + std::to_string(mDirection) + std::to_string(mLayerNumber) + "_Back"; std::string separationLayerName = "FT3SeparationLayer" + std::to_string(mDirection) + std::to_string(mLayerNumber); - TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$"); + TGeoMedium* medAir = gGeoManager->GetMedium("FT3_AIR$"); TGeoVolume* layerVol = nullptr; // set up stave config, differs between ML and OT disks @@ -421,12 +452,12 @@ void FT3Layer::createLayer(TGeoVolume* motherVolume) // stave face is at z=0 (or +-z_offset_stave), meaning that volumes are at // ~-+1cm < z < ~+-6cm, the +- referring forward/backward discs double z_layer_thickness = // need to shift internally with this - o2::trk::FT3ModuleConstants::staveTriangleHeight + - o2::trk::FT3ModuleConstants::z_offsetStave(staveConfig.x_midpoint_spacing) + - o2::trk::FT3ModuleConstants::siliconThickness + - o2::trk::FT3ModuleConstants::copperThickness + - o2::trk::FT3ModuleConstants::kaptonThickness + - o2::trk::FT3ModuleConstants::epoxyThickness * 2 + + o2::ft3::ModuleConstants::staveTriangleHeight + + o2::ft3::ModuleConstants::z_offsetStave(staveConfig.x_midpoint_spacing) + + o2::ft3::ModuleConstants::siliconThickness + + o2::ft3::ModuleConstants::copperThickness + + o2::ft3::ModuleConstants::kaptonThickness + + o2::ft3::ModuleConstants::epoxyThickness * 2 + 0.5; // add some extra room to ensure all volumes are encapsulated // shift stave volumes into layer volume, since nominal z_{stave face} = 0 @@ -436,7 +467,7 @@ void FT3Layer::createLayer(TGeoVolume* motherVolume) TGeoTube* layer = new TGeoTube(mInnerRadius - 0.2, mOuterRadius + 3.49, z_layer_thickness / 2); layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir); - if (trkParams.drawReferenceCircles) { + if (ft3Params.drawReferenceCircles) { std::string referenceCirclesName = "ReferenceCircles_Dir" + std::to_string(mDirection) + "_Layer" + std::to_string(mLayerNumber); createReferenceCircles(layerVol, referenceCirclesName); // for visualization purposes } @@ -454,6 +485,6 @@ void FT3Layer::createLayer(TGeoVolume* motherVolume) motherVolume->AddNode(layerVol, 1, FwdDiskCombiTrans); } else { - LOG(fatal) << "Unknown FT3 layout option: " << static_cast(trkParams.layoutFT3); + LOG(fatal) << "Unknown FT3 layout option: " << static_cast(ft3Params.layoutFT3); } } diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/FT3Module.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx similarity index 99% rename from Detectors/Upgrades/ALICE3/TRK/simulation/src/FT3Module.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx index 4e89d5c0f7c72..4c9041b17fcec 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/FT3Module.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3Module.cxx @@ -12,8 +12,8 @@ /// \file FT3Module.cxx /// \brief Implementation of the FT3Module class -#include "TRKSimulation/FT3Module.h" -#include "TRKBase/TRKBaseParam.h" +#include "FT3Simulation/FT3Module.h" +#include "FT3Base/FT3BaseParam.h" #include #include #include @@ -132,8 +132,8 @@ std::pair calculate_y_range( } /* - * This function is a helper function to determine the positions of senors on the stave - * by padding out the stave with sensors until there is no more space available. + * This function is a helper function which will pad out the stave with sensors + * until there is no more space available. * * Arguments: * y_positions: a pair of vectors, where each vector contains pairs of @@ -500,7 +500,7 @@ void FT3Module::create_layout_staveGeo(double mZ, int layerNumber, int direction << direction << ", Layer " << layerNumber; FT3Module::initialize_materials(); - auto& trkParams = o2::trk::TRKBaseParam::Instance(); + auto& ft3Params = o2::ft3::FT3BaseParam::Instance(); // First let's define some constants used throughout /* @@ -562,7 +562,7 @@ void FT3Module::create_layout_staveGeo(double mZ, int layerNumber, int direction // default positive and negative starting points has a gap around x-axis for symmetry double stave_half_length = staveConfig.y_lengths[i_stave] / 2; PositionRangeType y_ranges; - if (trkParams.placeSensorStackInMiddleOfStave) { + if (ft3Params.placeSensorStackInMiddleOfStave) { /* * We want a sensor stack to cross over the x-axis for coverage at y=0 * N.B. not necessarily exactly mirrored, only if stack gap is the same @@ -597,11 +597,11 @@ void FT3Module::create_layout_staveGeo(double mZ, int layerNumber, int direction // Define tolerances for cutting staves and placing sensors double tolerance_inner, tolerance_outer; if (staveConfig.isML) { - tolerance_inner = trkParams.staveTolFT3MLInner; - tolerance_outer = trkParams.staveTolFT3MLOuter; + tolerance_inner = ft3Params.staveTolMLInner; + tolerance_outer = ft3Params.staveTolMLOuter; } else { - tolerance_inner = trkParams.staveTolFT3OTInner; - tolerance_outer = trkParams.staveTolFT3OTOuter; + tolerance_inner = ft3Params.staveTolOTInner; + tolerance_outer = ft3Params.staveTolOTOuter; } // cut staves on nominal inner radius if specified if (tolerance_inner > staveConfig.maxToleranceInner) { @@ -735,7 +735,7 @@ void FT3Module::create_layout_staveGeo(double mZ, int layerNumber, int direction x_mid - Constants::active_width / 2, y_mid, z_mid, true); // right single sensor of the 2x1 addSingleSensorVolume( - motherVolume, layerNumber, direction, i_stave, sensor_count + 1, + motherVolume, layerNumber, direction, i_stave, sensor_count, x_mid + Constants::active_width / 2, y_mid, z_mid, false); // ------------ (2) Epoxy glue layer between silicon and copper (FPC) ------------ z_mid = z_offset_to_glue_Si * z_offset_multiplier + z_stave_shift; @@ -759,7 +759,7 @@ void FT3Module::create_layout_staveGeo(double mZ, int layerNumber, int direction x_mid, y_mid, z_mid, "CarbonKapton"); // increment to next sensor: (height + gap of one sensor) y_mid += y_sign * (Constants::sensor2x1_height + Constants::sensor2x1_gap); - sensor_count += 2; // same count for each material in the glued stack of materials + sensor_count++; // same count for each material in the glued stack of materials } // sensors in stack } // for y_sign (writing of positive or negative y positions) } // i_y_pos diff --git a/DataFormats/Detectors/Upgrades/ALICE3/TRK/src/DataFormatsTRKLinkDef.h b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3SimulationLinkDef.h similarity index 60% rename from DataFormats/Detectors/Upgrades/ALICE3/TRK/src/DataFormatsTRKLinkDef.h rename to Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3SimulationLinkDef.h index 36528d9dd2c46..3908f9aa71e5e 100644 --- a/DataFormats/Detectors/Upgrades/ALICE3/TRK/src/DataFormatsTRKLinkDef.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/src/FT3SimulationLinkDef.h @@ -1,4 +1,4 @@ -// Copyright 2019-2026 CERN and copyright holders of ALICE O2. +// 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. // @@ -15,11 +15,8 @@ #pragma link off all classes; #pragma link off all functions; -#pragma link C++ class o2::trk::Cluster + ; -#pragma link C++ class std::vector < o2::trk::Cluster> + ; -#pragma link C++ class o2::trk::ROFRecord + ; -#pragma link C++ class std::vector < o2::trk::ROFRecord> + ; -#pragma link C++ class o2::trk::MC2ROFRecord + ; -#pragma link C++ class std::vector < o2::trk::MC2ROFRecord> + ; +#pragma link C++ class o2::ft3::FT3Layer + ; +#pragma link C++ class o2::ft3::Detector + ; +#pragma link C++ class o2::base::DetImpl < o2::ft3::Detector> + ; #endif diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/TRK/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/CMakeLists.txt new file mode 100644 index 0000000000000..a099bce5e022d --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/CMakeLists.txt @@ -0,0 +1,14 @@ +# 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. + +add_subdirectory(base) +add_subdirectory(macros) +add_subdirectory(simulation) diff --git a/Detectors/Upgrades/ALICE3/TRK/README.md b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/README.md similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/README.md rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/README.md diff --git a/Detectors/Upgrades/ALICE3/TRK/base/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/CMakeLists.txt similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/base/CMakeLists.txt rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/CMakeLists.txt diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/AlmiraParam.h b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/include/TRKBase/AlmiraParam.h similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/AlmiraParam.h rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/include/TRKBase/AlmiraParam.h diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/include/TRKBase/GeometryTGeo.h similarity index 82% rename from Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/include/TRKBase/GeometryTGeo.h index f4a28f233ae9c..53ad7662cbfcd 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/include/TRKBase/GeometryTGeo.h @@ -42,13 +42,6 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache } return sInstance.get(); }; - - static const char* getFT3VolPattern() { return sFT3VolumeName.c_str(); } - static const char* getFT3InnerVolPattern() { return sFT3InnerVolumeName.c_str(); } - static const char* getFT3LayerPattern() { return sFT3LayerName.c_str(); } - static const char* getFT3ChipPattern() { return sFT3ChipName.c_str(); } - static const char* getFT3PassivePattern() { return sFT3PassiveName.c_str(); } - static const char* getFT3SensorPattern() { return sFT3SensorName.c_str(); } static const char* getTRKVolPattern() { return sVolumeName.c_str(); } static const char* getTRKServiceVolPattern() { return sServiceVolName.c_str(); } static const char* getTRKLayerPattern() { return sLayerName.c_str(); } @@ -69,7 +62,6 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache int getNumberOfChips() const { return mSize; } /// Determines the number of active parts in the Geometry - int extractNumberOfDisksMLOT(int dir) const; int extractNumberOfLayersMLOT(); int extractNumberOfLayersVD() const; int extractNumberOfPetalsVD() const; @@ -82,15 +74,12 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache int extractNumberOfChipsMLOT(int lay) const; /// Extract number following the prefix in the name string - void extractChipIdsFT3(std::string const volName, int& layer, int& stave, int& chip) const; int extractVolumeCopy(const char* name, const char* prefix) const; int getNumberOfLayersMLOT() const { return mNumberOfLayersMLOT; } int getNumberOfActivePartsVD() const { return mNumberOfActivePartsVD; } int getNumberOfHalfStaves(int lay) const { return mNumberOfHalfStaves[lay]; } - int getNumberOfDisksMLOT() const { return mNumberOfDisksMLOT; } - int getNumberOfStavesInDisk(int lay) const { return mFirstStaveIndexDisc[lay + 1] - mFirstStaveIndexDisc[lay]; } bool isOwner() const { return mOwner; } void setOwner(bool v) { mOwner = v; } @@ -144,10 +133,9 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache /// This routine computes the chip index number from the subDetID, petal, disk, layer, stave /// TODO: retrieve also from chip when chips will be available /// This routine computes the chip index number from the subDetID, petal, disk, layer, stave, half stave, module, chip - /// The subdetectors are numbers as follows: 0: VD; 1: ML+OT barrels; 2: ML+OT discs /// \param int subDetID The subdetector ID, 0 for VD, 1 for MLOT /// \param int petalcase The petal case number for VD, from 0 to 3 - /// \param int disk The disk number for VD or OT (VD 0-6 if present; OT 0-12 (18 for V1 geometry) + /// \param int disk The disk number for VD, from 0 to 5 /// \param int lay The layer number. Starting from 0 both for VD and MLOT /// \param int stave The stave number for MLOT. Starting from 0 /// \param int halfstave The half stave number for MLOT. Can be 0 or 1 @@ -185,8 +173,6 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache return (petalcase == 0) ? 0 : mLastChipIndexVD[petalcase - 1] + 1; } else if (subDetID == 1) { // MLOT return mLastChipIndex[lay + mNumberOfPetalsVD - 1] + 1; - } else if (subDetID == 2) { - return mFirstChipIndexMLOTDisc[lay]; } return -1; // not found } @@ -205,14 +191,13 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache #endif static const char* composeSymNameLayer(int d, int layer); - static const char* composeSymNameLayerFT3(int dir, int layer); static const char* composeSymNameStave(int d, int layer); static const char* composeSymNameModule(int d, int layer); static const char* composeSymNameChip(int d, int layer); static const char* composeSymNameSensor(int d, int layer); protected: - static constexpr int MAXLAYERS = 25; ///< max number of active layers + static constexpr int MAXLAYERS = 20; ///< max number of active layers static std::string sVolumeName; static std::string sServiceVolName; @@ -231,38 +216,26 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache static std::string sWrapperVolumeName; ///< Wrapper volume name, not implemented at the moment - static std::string sFT3InnerVolumeName; ///< Mother inner volume name - static std::string sFT3VolumeName; ///< Mother volume name - static std::string sFT3LayerName; ///< Layer name - static std::string sFT3ChipName; ///< Chip name - static std::string sFT3PassiveName; ///< Passive material name - static std::string sFT3SensorName; ///< Sensor name - Int_t mNumberOfLayersMLOT; ///< number of layers - Int_t mNumberOfDisksMLOT; ///< number of ML/OT disks (12 for v3) Int_t mNumberOfActivePartsVD; ///< number of layers Int_t mNumberOfLayersVD; ///< number of layers Int_t mNumberOfPetalsVD; ///< number of Petals = chip in each VD layer Int_t mNumberOfDisksVD; ///< number of Disks = 6 - std::vector mNumberOfStaves; ///< Number Of Staves per layer in ML/OT barrels - std::vector mNumberOfStavesMLOTDDiscs; ///< Number Of Staves per layer in ML/OT discs + std::vector mNumberOfStaves; ///< Number Of Staves per layer in ML/OT std::vector mNumberOfHalfStaves; ///< Number Of Half staves in each stave of the layer in ML/OT std::vector mNumberOfModules; ///< Number Of Modules per stave (half stave) in ML/OT std::vector mNumberOfChips; ///< number of chips per module in ML/OT std::vector mNumberOfChipsPerLayerVD; ///< number of chips per layer VD ( = number of petals) std::vector mNumberOfChipsPerLayerMLOT; ///< number of chips per layer MLOT - std::vector mNumberOfChipPerDiskMLOT; ///< number of chips per disc in MLOT std::vector mNumbersOfChipPerDiskVD; ///< numbersOfChipPerDiskVD std::vector mNumberOfChipsPerPetalVD; ///< numbersOfChipPerPetalVD // std::vector mNumberOfChipsPerStave; ///< number of chips per stave in ML/OT // std::vector mNumberOfChipsPerHalfStave; ///< number of chips per half stave in ML/OT // std::vector mNumberOfChipsPerModule; ///< number of chips per module in ML/OT - std::vector mLastChipIndex; ///< max ID of the detector in the petal(VD) or layer(MLOT) - std::vector mLastChipIndexVD; ///< max ID of the detector in the layer for the VD - // std::vector mLastChipIndexMLOT; ///< max ID of the detector in the layer for the MLOT - std::vector mFirstChipIndexMLOTDisc; ///< ID of the first sensor chip in the layer for the MLOT; array size is one larger than the number of disks; last element equals nChips+1 - std::vector mFirstStaveIndexDisc; ///< Index of first stave (abs ID) in each MLOT Disc - std::vector mFirstChipIndexStave; ///< Index of first chip on stave (Discs) + std::vector mLastChipIndex; ///< max ID of the detctor in the petal(VD) or layer(MLOT) + std::vector mLastChipIndexVD; ///< max ID of the detctor in the layer for the VD + std::vector mLastChipIndexMLOT; ///< max ID of the detctor in the layer for the MLOT + std::array mLayerToWrapper; ///< Layer to wrapper correspondence, not implemented yet bool mOwner = true; //! is it owned by the singleton? diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/SegmentationChip.h b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/include/TRKBase/SegmentationChip.h similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/SegmentationChip.h rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/include/TRKBase/SegmentationChip.h diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/Specs.h b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/include/TRKBase/Specs.h similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/Specs.h rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/include/TRKBase/Specs.h diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/include/TRKBase/TRKBaseParam.h similarity index 97% rename from Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/include/TRKBase/TRKBaseParam.h index 7a9f0b5dbb769..829cc5268c18c 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/include/TRKBase/TRKBaseParam.h @@ -69,7 +69,7 @@ struct TRKBaseParam : public o2::conf::ConfigurableParamHelper { eVDLayout layoutVD = kIRIS4; // VD detector layout design eMLOTLayout layoutMLOT = kSegmented; // ML and OT detector layout design eFT3Layout layoutFT3 = kSegmentedStave; - eSrvLayout layoutSRV = kPeacockv1; // Layout of services + eSrvLayout layoutSRV = kPeacockv1; // Layout of services eVDLayout getLayoutVD() const { return layoutVD; } eMLOTLayout getLayoutMLOT() const { return layoutMLOT; } diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/AlmiraParam.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/src/AlmiraParam.cxx similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/base/src/AlmiraParam.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/src/AlmiraParam.cxx diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/src/GeometryTGeo.cxx similarity index 83% rename from Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/src/GeometryTGeo.cxx index 7b4959f43716c..ddfc844cc964d 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/src/GeometryTGeo.cxx @@ -43,15 +43,6 @@ std::string GeometryTGeo::sMetalStackName = "TRKMetalStack"; std::string GeometryTGeo::sWrapperVolumeName = "TRKUWrapVol"; ///< Wrapper volume name, not implemented at the moment -std::string GeometryTGeo::sFT3VolumeName = "FT3V"; ///< Mother volume name -std::string GeometryTGeo::sFT3InnerVolumeName = "FT3Inner"; ///< Mother inner volume name -std::string GeometryTGeo::sFT3LayerName = "FT3Layer"; ///< Layer name -// TODO: chip and passive are only used by trapezoidal geom; use same for all? -std::string GeometryTGeo::sFT3ChipName = "FT3Chip"; ///< Chip name -std::string GeometryTGeo::sFT3PassiveName = "Passive"; ///< Passive material name -// TODO: this is now only used for the not-segmented version; synchronise? -std::string GeometryTGeo::sFT3SensorName = "FT3Sensor"; ///< Sensor name - o2::trk::GeometryTGeo::~GeometryTGeo() { if (!mOwner) { @@ -96,7 +87,6 @@ void GeometryTGeo::Build(int loadTrans) mNumberOfActivePartsVD = extractNumberOfActivePartsVD(); mNumberOfLayersVD = extractNumberOfLayersVD(); mNumberOfDisksVD = extractNumberOfDisksVD(); - mNumberOfDisksMLOT = extractNumberOfDisksMLOT(0) + extractNumberOfDisksMLOT(1); mNumberOfStaves.resize(mNumberOfLayersMLOT); mNumberOfHalfStaves.resize(mNumberOfLayersMLOT); @@ -110,7 +100,7 @@ void GeometryTGeo::Build(int loadTrans) mLastChipIndex.resize(mNumberOfPetalsVD + mNumberOfLayersMLOT); mLastChipIndexVD.resize(mNumberOfPetalsVD); - // mLastChipIndexMLOT.resize(mNumberOfLayersMLOT); /// ML and OT are part of TRK as the same detector, without disks + mLastChipIndexMLOT.resize(mNumberOfLayersMLOT); /// ML and OT are part of TRK as the same detector, without disks for (int i = 0; i < mNumberOfLayersMLOT; i++) { if (mLayoutMLOT == eMLOTLayout::kCylindrical) { @@ -141,99 +131,22 @@ void GeometryTGeo::Build(int loadTrans) mNumberOfChipsPerLayerMLOT[i] = mNumberOfStaves[i] * mNumberOfHalfStaves[i] * mNumberOfModules[i] * mNumberOfChips[i]; numberOfChipsTotal += mNumberOfChipsPerLayerMLOT[i]; mLastChipIndex[i + mNumberOfPetalsVD] = numberOfChipsTotal - 1; + mLastChipIndexMLOT[i] = numberOfChipsTotal - 1; } - // Forward discs (FT3) part - int totDiscs = 0; - int absStaveIdx = 0; - - if (mFirstChipIndexStave.size() == 0) { - mFirstChipIndexStave.push_back(numberOfChipsTotal); - mFirstChipIndexMLOTDisc.push_back(numberOfChipsTotal); - } - if (mFirstStaveIndexDisc.size() == 0) { - mFirstStaveIndexDisc.push_back(0); - } - std::vector numberOfDiscs; - for (int iDir = 0; iDir < 2; iDir++) { - numberOfDiscs.push_back(extractNumberOfDisksMLOT(iDir)); - totDiscs += numberOfDiscs[iDir]; - LOG(debug) << "direction " << iDir << "; disk total " << totDiscs; - - for (int iDisc = 0; iDisc < numberOfDiscs[iDir]; iDisc++) { - TGeoVolume* trkV = gGeoManager->GetVolume(getTRKVolPattern()); - if (trkV == nullptr) { - LOG(fatal) << getName() << " volume " << getTRKVolPattern() << " is not in the geometry"; - } - auto layerNode = trkV->GetNode(Form("%s_1", composeSymNameLayerFT3(iDir, iDisc))); - if (layerNode == nullptr) { - LOG(info) << "Could not find layer node " << Form("%s_1", composeSymNameLayerFT3(iDir, iDisc)); - continue; - } - auto layerVol = layerNode->GetVolume(); - if (layerVol == nullptr) { - LOG(fatal) << "Could not find layer volume " << Form("%s_1", composeSymNameLayerFT3(iDir, iDisc)); - } - TObjArray* nodes = layerVol->GetNodes(); - int nNodes = nodes->GetEntriesFast(); - int nStaves = 0; - int nSensor = 0; - std::vector chipsPerStave; - for (int j = 0; j < nNodes; j++) { - auto nd = dynamic_cast(nodes->At(j)); - const char* name = nd->GetName(); - if (strstr(name, "FT3Sensor") != nullptr && strstr(name, "Inactive") == nullptr) { - int direction = 0, layer = 0; - int stave = 0, chip = 0; - extractChipIdsFT3(name, layer, stave, chip); - if (stave >= chipsPerStave.size()) { - chipsPerStave.resize(stave + 1, 0); - nStaves = stave + 1; - } - // if (chip + 1 > mChipStaveIds.size()) mChipStaveIds.resize(chip+1); - if (chip + 1 >= chipsPerStave[stave]) { - chipsPerStave[stave] = chip + 1; - } - nSensor++; - } - } - LOG(debug) << "direction " << iDir << " disc " << iDisc << " has " << nNodes << " nodes of which " << nSensor << " sensors in " << chipsPerStave.size() << " staves"; - - if (nStaves != chipsPerStave.size()) { - LOG(info) << "Inconsistency in stave count " << nStaves << " " << chipsPerStave.size(); - } - mFirstChipIndexStave.resize(absStaveIdx + chipsPerStave.size() + 1, -1); - for (int nChips : chipsPerStave) { - LOG(debug) << "Absolute Stave ID " << absStaveIdx << " : " << nChips << " sensors, setting first chip ID for next stave to " << mFirstChipIndexStave[absStaveIdx] + nChips; - numberOfChipsTotal += nChips; - mFirstChipIndexStave[absStaveIdx + 1] = mFirstChipIndexStave[absStaveIdx] + nChips; - absStaveIdx++; - } - mFirstStaveIndexDisc.push_back(absStaveIdx); - mFirstChipIndexMLOTDisc.push_back(numberOfChipsTotal); - LOG(debug) << "Total sensors so far " << numberOfChipsTotal; - } - } setSize(numberOfChipsTotal); - if (numberOfChipsTotal > std::numeric_limits::max()) { - LOG(fatal) << "Too many sensor chips in TRK: " << numberOfChipsTotal; - } - // TODO: add corresponding info for FT3 defineMLOTSensors(); fillTrackingFramesCacheMLOT(); fillMatrixCache(loadTrans); - LOG(info) << "Build done"; } //__________________________________________________________________________ int GeometryTGeo::getSubDetID(int index) const { - if (index >= 0 && index <= mLastChipIndexVD[mLastChipIndexVD.size() - 1]) { + if (index <= mLastChipIndexVD[mLastChipIndexVD.size() - 1]) { return 0; - } else if (index <= mLastChipIndex[mLastChipIndex.size() - 1]) { + } else if (index > mLastChipIndexVD[mLastChipIndexVD.size() - 1]) { return 1; - } else if (index < mFirstChipIndexMLOTDisc[mFirstChipIndexMLOTDisc.size() - 1]) { - return 2; } return -1; /// not found } @@ -274,10 +187,10 @@ int GeometryTGeo::getDisk(int index) const int GeometryTGeo::getLayer(int index) const { int subDetID = getSubDetID(index); + int petalcase = getPetalCase(index); int lay = 0; if (subDetID == 0) { /// VD - int petalcase = getPetalCase(index); if (index % mNumberOfChipsPerPetalVD[petalcase] >= mNumberOfLayersVD) { return -1; /// disks } @@ -287,12 +200,6 @@ int GeometryTGeo::getLayer(int index) const lay++; } return lay - mNumberOfPetalsVD; /// numeration of MLOT layers starting from 0 - } else if (subDetID == 2) { - lay = mNumberOfDisksMLOT - 1; - while (index < mFirstChipIndexMLOTDisc[lay] && lay > 0) { - lay--; - } - return lay; } return -1; /// -1 if not found } @@ -303,18 +210,7 @@ int GeometryTGeo::getLayerTRK(int index) const return -1; /// disks do not have a global layer index } int subDetID = getSubDetID(index); - int firstDetLayer = 0; - - // NOTE: taking these from o2::trk::constants, instead - // of the geometry that is constructed in the 'Build' function - // risks inconsistencies... - - if (subDetID == 1) { - firstDetLayer = o2::trk::constants::VD::petal::nLayers; - } else if (subDetID == 2) { - firstDetLayer = o2::trk::constants::VD::petal::nLayers + o2::trk::constants::ML::nLayers + o2::trk::constants::OT::nLayers; - } - return firstDetLayer + getLayer(index); + return subDetID * o2::trk::constants::VD::petal::nLayers + getLayer(index); // MLOT: offset by number of VD layers } //__________________________________________________________________________ int GeometryTGeo::getStave(int index) const @@ -343,13 +239,6 @@ int GeometryTGeo::getStave(int index) const int chipsPerStave = Nmod * chipsPerModule; return index / chipsPerStave; } - } else if (subDetID == 2) { // Disks FT3 - int lay = getLayer(index); - int absStave = mFirstStaveIndexDisc[lay]; - while (index >= mFirstChipIndexStave[absStave] && absStave < mFirstStaveIndexDisc[lay + 1]) { - absStave++; - } - return absStave - 1 - mFirstStaveIndexDisc[lay]; } return -1; } @@ -437,10 +326,6 @@ int GeometryTGeo::getChip(int index) const int chipsPerModule = Nchip; return index % chipsPerModule; } - } else if (subDetID == 2) { // Forward disks (FT3) - int lay = getLayer(index); - int stave = getStave(index); - return index - mFirstChipIndexStave[mFirstStaveIndexDisc[lay] + stave]; } return -1; } @@ -471,7 +356,7 @@ unsigned short GeometryTGeo::getChipIndex(int subDetID, int petalcase, int disk, } } - LOGP(warning, "Chip index not found for subDetID {}, petalcase {}, disk {}, layer {}, stave {}, halfstave {}, module {}, chip {}, returning numeric limit", subDetID, petalcase, disk, lay, stave, halfstave, mod, chip); + LOGP(warning, "Chip index not found for subDetID %d, petalcase %d, disk %d, layer %d, stave %d, halfstave %d, module %d, chip %d, returning numeric limit", subDetID, petalcase, disk, lay, stave, halfstave, mod, chip); return std::numeric_limits::max(); // not found } @@ -496,12 +381,9 @@ unsigned short GeometryTGeo::getChipIndex(int subDetID, int volume, int lay, int int chipsPerStave = Nmod * chipsPerModule; return getFirstChipIndex(lay, -1, subDetID) + stave * chipsPerStave + mod * chipsPerModule + chip; } - } else if (subDetID == 2) { // FT3 - if (lay < mFirstStaveIndexDisc.size() && mFirstStaveIndexDisc[lay] + stave < mFirstChipIndexStave.size()) { - return mFirstChipIndexStave[mFirstStaveIndexDisc[lay] + stave] + chip; - } } - LOGP(warning, "Chip index not found for subDetID {}, volume {}, layer {}, stave {}, halfstave {}, module {}, chip {}, returning numeric limit", subDetID, volume, lay, stave, halfstave, mod, chip); + + LOGP(warning, "Chip index not found for subDetID %d, volume %d, layer %d, stave %d, halfstave %d, module %d, chip %d, returning numeric limit", subDetID, volume, lay, stave, halfstave, mod, chip); return std::numeric_limits::max(); // not found } @@ -563,14 +445,6 @@ TString GeometryTGeo::getMatrixPath(int index) const path += Form("%s%d_%d/", getTRKChipPattern(), layer, chip); // TRKChipx_y path += Form("%s%d_1/", getTRKSensorPattern(), layer); // TRKSensorx_1 } - } else if (subDetID == 2) { - int direction = 0; - if (layer >= mNumberOfDisksMLOT / 2) { - direction = 1; - layer -= mNumberOfDisksMLOT / 2; - } - path += Form("%s%d_%d_1/", getFT3LayerPattern(), direction, layer); - path += Form("FT3Sensor_Active_%d_%d_%d_%d_%d", direction, layer, stave, chip, chip); } return path; } @@ -624,9 +498,10 @@ TGeoHMatrix* GeometryTGeo::extractMatrixSensor(int index) const void GeometryTGeo::defineMLOTSensors() { for (int i = 0; i < mSize; i++) { - if (getSubDetID(i) == 1) { - sensorsMLOT.push_back(i); // TODO: this is now a trivial array where each element is a sequence number (expect that the first elements are skipped) + if (getSubDetID(i) == 0) { + continue; } + sensorsMLOT.push_back(i); } } @@ -634,20 +509,14 @@ void GeometryTGeo::defineMLOTSensors() void GeometryTGeo::fillTrackingFramesCacheMLOT() { // fill for every sensor of ML & OT its tracking frame parameters - int nSensMLOT = sensorsMLOT.size(); - int nSensMLOTDisk = mFirstChipIndexMLOTDisc[mFirstChipIndexMLOTDisc.size() - 1] - mFirstChipIndexMLOTDisc[0]; if (!isTrackingFrameCachedMLOT() && !sensorsMLOT.empty()) { - size_t newSize = nSensMLOT + nSensMLOTDisk; + size_t newSize = sensorsMLOT.size(); mCacheRefXMLOT.resize(newSize); mCacheRefAlphaMLOT.resize(newSize); - for (int i = 0; i < nSensMLOT; i++) { + for (int i = 0; i < newSize; i++) { int sensorId = sensorsMLOT[i]; extractSensorXAlphaMLOT(sensorId, mCacheRefXMLOT[i], mCacheRefAlphaMLOT[i]); } - for (int i = nSensMLOT; i < newSize; i++) { - // LOG(info) << "Getting XAlpha for disk chip " << mFirstChipIndexMLOTDisc[0] + i; - extractSensorXAlphaMLOT(mFirstChipIndexMLOTDisc[0] + i, mCacheRefXMLOT[i], mCacheRefAlphaMLOT[i]); - } } } @@ -698,14 +567,8 @@ const char* GeometryTGeo::composeSymNameLayer(int d, int layer) { return Form("%s/%s%d", composeSymNameTRK(d), getTRKLayerPattern(), layer); } - #endif -const char* GeometryTGeo::composeSymNameLayerFT3(int dir, int layer) -{ - return Form("%s%d_%d", GeometryTGeo::getFT3LayerPattern(), dir, layer); -} - const char* GeometryTGeo::composeSymNameStave(int d, int layer) { return Form("%s/%s%d", composeSymNameLayer(d, layer), getTRKStavePattern(), layer); @@ -726,38 +589,6 @@ const char* GeometryTGeo::composeSymNameSensor(int d, int layer) return Form("%s/%s%d", composeSymNameChip(d, layer), getTRKSensorPattern(), layer); } -//__________________________________________________________________________ -void GeometryTGeo::extractChipIdsFT3(std::string const volName, int& layer, int& stave, int& chip) const -{ - if (volName.find("FT3Sensor_Active") == 0) { - int idx = volName.find('_') + 1; - idx = volName.find('_', idx) + 1; - int direction = std::stoi(volName.substr(idx)); - idx = volName.find('_', idx) + 1; - layer = std::stoi(volName.substr(idx)); - idx = volName.find('_', idx) + 1; - stave = std::stoi(volName.substr(idx)); - idx = volName.find('_', idx) + 1; - chip = std::stoi(volName.substr(idx)); - if (direction == 1) { - layer += mNumberOfDisksMLOT / 2; - } - } else { - LOG(error) << "extractChipIdsFT3: Not a sensor volume " << volName; - layer = -1; - } -} - -//__________________________________________________________________________ -int GeometryTGeo::extractNumberOfDisksMLOT(int dir) const -{ - int numDiscs = 0; - while (gGeoManager->GetVolume(composeSymNameLayerFT3(dir, numDiscs))) { - numDiscs++; - } // Check maybe subvolume? - return numDiscs; // Assume same # layers on both sides -} - //__________________________________________________________________________ int GeometryTGeo::extractVolumeCopy(const char* name, const char* prefix) const { @@ -1329,7 +1160,6 @@ void GeometryTGeo::Print(Option_t*) const } LOGF(info, "Total number of chips: %d", getNumberOfChips()); - /* std::cout << "mLastChipIndex = ["; for (int i = 0; i < mLastChipIndex.size(); i++) { std::cout << mLastChipIndex[i]; @@ -1338,7 +1168,6 @@ void GeometryTGeo::Print(Option_t*) const } } std::cout << "]" << std::endl; - */ std::cout << "mLastChipIndexVD = ["; for (int i = 0; i < mLastChipIndexVD.size(); i++) { std::cout << mLastChipIndexVD[i]; diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/SegmentationChip.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/src/SegmentationChip.cxx similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/base/src/SegmentationChip.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/src/SegmentationChip.cxx diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/TRKBaseLinkDef.h b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/src/TRKBaseLinkDef.h similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/base/src/TRKBaseLinkDef.h rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/src/TRKBaseLinkDef.h diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/TRKBaseParam.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/src/TRKBaseParam.cxx similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/base/src/TRKBaseParam.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/base/src/TRKBaseParam.cxx diff --git a/Detectors/Upgrades/ALICE3/TRK/macros/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/CMakeLists.txt similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/macros/CMakeLists.txt rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/CMakeLists.txt diff --git a/Detectors/Upgrades/ALICE3/TRK/macros/test/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CMakeLists.txt similarity index 95% rename from Detectors/Upgrades/ALICE3/TRK/macros/test/CMakeLists.txt rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CMakeLists.txt index cdae7c9c379fd..6dcbfc8d65d6b 100644 --- a/Detectors/Upgrades/ALICE3/TRK/macros/test/CMakeLists.txt +++ b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CMakeLists.txt @@ -43,7 +43,7 @@ o2_add_test_root_macro(CheckTracksCA.C LABELS trk COMPILE_ONLY) o2_add_test_root_macro(CheckClusters.C - PUBLIC_LINK_LIBRARIES O2::DataFormatsTRK + PUBLIC_LINK_LIBRARIES O2::DataFormatsTRKFT3 O2::SimulationDataFormat O2::Framework O2::TRKBase @@ -51,7 +51,7 @@ o2_add_test_root_macro(CheckClusters.C LABELS trk COMPILE_ONLY) o2_add_test_root_macro(postClusterSizeVsEta.C - PUBLIC_LINK_LIBRARIES O2::DataFormatsTRK + PUBLIC_LINK_LIBRARIES O2::DataFormatsTRKFT3 O2::SimulationDataFormat O2::Framework O2::TRKBase diff --git a/Detectors/Upgrades/ALICE3/TRK/macros/test/CheckBandwidth.C b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CheckBandwidth.C similarity index 99% rename from Detectors/Upgrades/ALICE3/TRK/macros/test/CheckBandwidth.C rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CheckBandwidth.C index c071a06516d30..f92c161e682b3 100644 --- a/Detectors/Upgrades/ALICE3/TRK/macros/test/CheckBandwidth.C +++ b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CheckBandwidth.C @@ -28,11 +28,11 @@ #include #include "TRKBase/GeometryTGeo.h" -#include "DataFormatsITSMFT/Digit.h" +#include "DataFormatsTRKFT3/Digit.h" #include "MathUtils/Utils.h" #include "DetectorsBase/GeometryManager.h" -#include "DataFormatsITSMFT/ROFRecord.h" +#include "DataFormatsTRKFT3/ROFRecord.h" #include "CommonDataFormat/InteractionRecord.h" #include "SimulationDataFormat/DigitizationContext.h" @@ -169,8 +169,8 @@ void CheckBandwidth(std::string digifile = "trkdigits.root", std::string inputGe TTree* digTree = (TTree*)digFile->Get("o2sim"); const int nDigitTreeEntries = digTree->GetEntries(); - std::vector*> digArr(nTotalLayers, nullptr); - std::vector*> rofRecords(nTotalLayers, nullptr); + std::vector*> digArr(nTotalLayers, nullptr); + std::vector*> rofRecords(nTotalLayers, nullptr); for (int nDigitsLayer{0}; nDigitsLayer < nTotalLayers; ++nDigitsLayer) { if (!digTree->GetBranch(Form("TRKDigit_%i", nDigitsLayer))) { break; diff --git a/Detectors/Upgrades/ALICE3/TRK/macros/test/CheckClusters.C b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CheckClusters.C similarity index 97% rename from Detectors/Upgrades/ALICE3/TRK/macros/test/CheckClusters.C rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CheckClusters.C index 7b9365dbe2011..0938ff2438ded 100644 --- a/Detectors/Upgrades/ALICE3/TRK/macros/test/CheckClusters.C +++ b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CheckClusters.C @@ -29,12 +29,12 @@ #include #include -#include "DataFormatsTRK/Cluster.h" -#include "DataFormatsTRK/ROFRecord.h" +#include "DataFormatsTRKFT3/Cluster.h" +#include "DataFormatsTRKFT3/Hit.h" +#include "DataFormatsTRKFT3/ROFRecord.h" #include "TRKBase/AlmiraParam.h" #include "TRKBase/GeometryTGeo.h" #include "TRKBase/SegmentationChip.h" -#include "TRKSimulation/Hit.h" #include "ITSMFTSimulation/AlpideSimResponse.h" #include "CCDB/BasicCCDBManager.h" #include "MathUtils/Cartesian.h" @@ -53,7 +53,7 @@ void CheckClusters(const std::string& clusfile = "o2clus_trk.root", { gROOT->SetBatch(batch); - using HitVec = std::vector; + using HitVec = std::vector; using MC2HITS_map = std::unordered_map>; // maps (trackID << 32) + chipID -> hit indices // ── Chip response (for hit-segment propagation to charge-collection plane) ── @@ -151,8 +151,8 @@ void CheckClusters(const std::string& clusfile = "o2clus_trk.root", // Read per-layer cluster branches and accumulate static constexpr int nLayers = o2::trk::AlmiraParam::kNLayers; - std::vector*> clusArrPerLayer(nLayers, nullptr); - std::vector*> rofRecVecPerLayer(nLayers, nullptr); + std::vector*> clusArrPerLayer(nLayers, nullptr); + std::vector*> rofRecVecPerLayer(nLayers, nullptr); std::vector*> patternsPerLayer(nLayers, nullptr); std::vector*> clusLabArrPerLayer(nLayers, nullptr); std::vector> patternOffsetsPerLayer(nLayers); @@ -350,7 +350,7 @@ void CheckClusters(const std::string& clusfile = "o2clus_trk.root", float clLocX{0.f}, clLocZ{0.f}; o2::trk::SegmentationChip::detectorToLocalUnchecked( cluster.row, cluster.col, clLocX, clLocZ, - cluster.subDetID, cluster.layer, cluster.disk); + cluster.subDetID, cluster.layer, cluster.layer); const float pitchRow = (cluster.subDetID == 0) ? o2::trk::SegmentationChip::PitchRowVD : o2::trk::SegmentationChip::PitchRowMLOT; @@ -377,7 +377,7 @@ void CheckClusters(const std::string& clusfile = "o2clus_trk.root", (float)gloC.X(), (float)gloC.Y(), (float)gloC.Z(), clLocX, clLocZ, (float)rofRec.getROFrame(), (float)cluster.size, (float)cluster.chipID, - (float)cluster.layer, (float)cluster.disk, (float)cluster.subDetID, + (float)cluster.layer, -1.f, (float)cluster.subDetID, (float)cluster.row, (float)cluster.col, -1.f}; nt.Fill(data.data()); continue; @@ -405,7 +405,7 @@ void CheckClusters(const std::string& clusfile = "o2clus_trk.root", nNoMCHit++; continue; } - auto projectHitToResponsePlane = [&](const o2::trk::Hit& hit, float& hitLocX, float& hitLocZ) { + auto projectHitToResponsePlane = [&](const o2::trkft3::Hit& hit, float& hitLocX, float& hitLocZ) { const auto& gloHend = hit.GetPos(); const auto& gloHsta = hit.GetPosStart(); o2::math_utils::Point3D locHsta = gman->getMatrixL2G(cluster.chipID) ^ (gloHsta); // inverse L2G @@ -430,7 +430,7 @@ void CheckClusters(const std::string& clusfile = "o2clus_trk.root", } }; - const o2::trk::Hit* bestHit = nullptr; + const o2::trkft3::Hit* bestHit = nullptr; float hitLocX{0.f}, hitLocZ{0.f}; float bestDist2 = std::numeric_limits::max(); for (const auto ih : hitEntry->second) { @@ -470,7 +470,7 @@ void CheckClusters(const std::string& clusfile = "o2clus_trk.root", (float)gloC.X(), (float)gloC.Y(), (float)gloC.Z(), clLocX, clLocZ, (float)rofRec.getROFrame(), (float)cluster.size, (float)cluster.chipID, - (float)cluster.layer, (float)cluster.disk, (float)cluster.subDetID, + (float)cluster.layer, -1.f, (float)cluster.subDetID, (float)cluster.row, (float)cluster.col, pt}; nt.Fill(data.data()); } diff --git a/Detectors/Upgrades/ALICE3/TRK/macros/test/CheckDigitsTRK.C b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CheckDigitsTRK.C similarity index 98% rename from Detectors/Upgrades/ALICE3/TRK/macros/test/CheckDigitsTRK.C rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CheckDigitsTRK.C index 400457fc98585..ee463f304405e 100644 --- a/Detectors/Upgrades/ALICE3/TRK/macros/test/CheckDigitsTRK.C +++ b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CheckDigitsTRK.C @@ -24,8 +24,8 @@ #include "TRKBase/SegmentationChip.h" #include "TRKBase/GeometryTGeo.h" -#include "DataFormatsITSMFT/Digit.h" -#include "TRKSimulation/Hit.h" +#include "DataFormatsTRKFT3/Digit.h" +#include "DataFormatsTRKFT3/Hit.h" #include "MathUtils/Utils.h" #include "SimulationDataFormat/ConstMCTruthContainer.h" #include "SimulationDataFormat/IOMCTruthContainerView.h" @@ -34,7 +34,7 @@ #include "ITSMFTSimulation/AlpideSimResponse.h" #include "CCDB/BasicCCDBManager.h" -#include "DataFormatsITSMFT/ROFRecord.h" +#include "DataFormatsTRKFT3/ROFRecord.h" #endif @@ -82,8 +82,8 @@ void CheckDigits(std::string digifile = "trkdigits.root", std::string hitfile = using namespace o2::base; using namespace o2::trk; - using o2::itsmft::Digit; - using o2::trk::Hit; + using o2::trkft3::Digit; + using o2::trkft3::Hit; using o2::trk::SegmentationChip; @@ -117,7 +117,7 @@ void CheckDigits(std::string digifile = "trkdigits.root", std::string hitfile = TFile* hitFile = TFile::Open(hitfile.data()); TTree* hitTree = (TTree*)hitFile->Get("o2sim"); int nevH = hitTree->GetEntries(); // hits are stored as one event per entry - std::vector*> hitArray(nevH, nullptr); + std::vector*> hitArray(nevH, nullptr); std::vector> mc2hitVec(nevH); @@ -126,8 +126,8 @@ void CheckDigits(std::string digifile = "trkdigits.root", std::string hitfile = TTree* digTree = (TTree*)digFile->Get("o2sim"); int nDigitLayers = 0; - std::vector*> digArr(nTotalLayers, nullptr); - std::vector*> rofRecordsArr(nTotalLayers, nullptr); + std::vector*> digArr(nTotalLayers, nullptr); + std::vector*> rofRecordsArr(nTotalLayers, nullptr); std::vector plabelsArr(nTotalLayers, nullptr); for (int iLayer = 0; iLayer < nTotalLayers; ++iLayer) { diff --git a/Detectors/Upgrades/ALICE3/TRK/macros/test/CheckTracksCA.C b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CheckTracksCA.C similarity index 99% rename from Detectors/Upgrades/ALICE3/TRK/macros/test/CheckTracksCA.C rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CheckTracksCA.C index f7917ca4203f1..708701789f483 100644 --- a/Detectors/Upgrades/ALICE3/TRK/macros/test/CheckTracksCA.C +++ b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/CheckTracksCA.C @@ -41,7 +41,7 @@ #include "SimulationDataFormat/MCCompLabel.h" #include "SimulationDataFormat/MCTrack.h" #include "Steer/MCKinematicsReader.h" -#include "TRKSimulation/Hit.h" +#include "DataFormatsTRKFT3/Hit.h" #include "TRKBase/GeometryTGeo.h" #include "DetectorsBase/GeometryManager.h" @@ -161,7 +161,7 @@ void CheckTracksCA(std::string trackfile = "o2trac_trk.root", o2::base::GeometryManager::loadGeometry(); auto* gman = o2::trk::GeometryTGeo::Instance(); - std::vector* trkHit = nullptr; + std::vector* trkHit = nullptr; hitsTree->SetBranchAddress("TRKHit", &trkHit); Long64_t nHitsEntries = hitsTree->GetEntries(); diff --git a/Detectors/Upgrades/ALICE3/TRK/macros/test/postClusterSizeVsEta.C b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/postClusterSizeVsEta.C similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/macros/test/postClusterSizeVsEta.C rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/postClusterSizeVsEta.C diff --git a/Detectors/Upgrades/ALICE3/TRK/macros/test/run_test.sh b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/run_test.sh similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/macros/test/run_test.sh rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/macros/test/run_test.sh diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/CMakeLists.txt similarity index 56% rename from Detectors/Upgrades/ALICE3/TRK/simulation/CMakeLists.txt rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/CMakeLists.txt index e8460abe71dc0..0760504c4cf3f 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/CMakeLists.txt +++ b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/CMakeLists.txt @@ -10,36 +10,22 @@ # or submit itself to any jurisdiction. o2_add_library(TRKSimulation - SOURCES src/Hit.cxx - src/TRKLayer.cxx - src/ChipDigitsContainer.cxx - src/ChipSimResponse.cxx + SOURCES src/TRKLayer.cxx src/Detector.cxx - src/DigiParams.cxx - src/Digitizer.cxx - src/FT3Layer.cxx - src/FT3Module.cxx src/TRKServices.cxx - src/DPLDigitizerParam.cxx src/VDLayer.cxx src/VDGeometryBuilder.cxx PUBLIC_LINK_LIBRARIES O2::TRKBase + O2::TRKFT3Simulation + O2::DataFormatsTRKFT3 O2::ITSMFTSimulation O2::DetectorsRaw O2::SimulationDataFormat) o2_target_root_dictionary(TRKSimulation - HEADERS include/TRKSimulation/Hit.h - include/TRKSimulation/ChipDigitsContainer.h - include/TRKSimulation/ChipSimResponse.h - include/TRKSimulation/DigiParams.h - include/TRKSimulation/Digitizer.h - include/TRKSimulation/Detector.h - include/TRKSimulation/FT3Layer.h - include/TRKSimulation/FT3Module.h + HEADERS include/TRKSimulation/Detector.h include/TRKSimulation/TRKLayer.h include/TRKSimulation/TRKServices.h include/TRKSimulation/VDLayer.h include/TRKSimulation/VDGeometryBuilder.h - include/TRKSimulation/VDSensorRegistry.h - include/TRKSimulation/DPLDigitizerParam.h) + include/TRKSimulation/VDSensorRegistry.h) diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Detector.h b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/include/TRKSimulation/Detector.h similarity index 68% rename from Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Detector.h rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/include/TRKSimulation/Detector.h index 444905a1bf18a..a7972d14191a6 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Detector.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/include/TRKSimulation/Detector.h @@ -13,11 +13,10 @@ #define ALICEO2_TRK_DETECTOR_H #include "DetectorsBase/Detector.h" -#include "TRKSimulation/Hit.h" +#include "DataFormatsTRKFT3/Hit.h" #include "TRKSimulation/TRKLayer.h" #include "TRKSimulation/TRKServices.h" -#include "TRKSimulation/FT3Layer.h" #include "TRKBase/GeometryTGeo.h" #include @@ -44,9 +43,9 @@ class Detector : public o2::base::DetImpl void ConstructGeometry() override; - o2::trk::Hit* addHit(int trackID, unsigned short detID, const TVector3& startPos, const TVector3& endPos, - const TVector3& startMom, double startE, double endTime, double eLoss, - unsigned char startStatus, unsigned char endStatus); + o2::trkft3::Hit* addHit(int trackID, unsigned short detID, const TVector3& startPos, const TVector3& endPos, + const TVector3& startMom, double startE, double endTime, double eLoss, + unsigned char startStatus, unsigned char endStatus); // Mandatory overrides void BeginPrimary() override { ; } @@ -60,7 +59,7 @@ class Detector : public o2::base::DetImpl void Reset() override; // Custom member functions - std::vector* getHits(int iColl) const + std::vector* getHits(int iColl) const { if (!iColl) { return mHits; @@ -69,7 +68,6 @@ class Detector : public o2::base::DetImpl } void configMLOT(); - void configFT3ScopingV3(); void configFromFile(std::string fileName = "alice3_TRK_layout.txt"); void configToFile(std::string fileName = "alice3_TRK_layout.txt"); @@ -77,23 +75,20 @@ class Detector : public o2::base::DetImpl void createMaterials(); void createGeometry(); - static constexpr int kForward = 0; - static constexpr int kBackward = 1; - private: int mNumberOfVolumes; int mNumberOfVolumesVD; // Transient data about track passing the sensor struct TrackData { - bool mHitStarted; // hit creation started - unsigned char mTrkStatusStart; // track status flag - TLorentzVector mPositionStart; // position at entrance - TLorentzVector mMomentumStart; // momentum - double mEnergyLoss; // energy loss - } mTrackData; //! transient data - GeometryTGeo* mGeometryTGeo; //! - std::vector* mHits; // Derived from ITSMFT + bool mHitStarted; // hit creation started + unsigned char mTrkStatusStart; // track status flag + TLorentzVector mPositionStart; // position at entrance + TLorentzVector mMomentumStart; // momentum + double mEnergyLoss; // energy loss + } mTrackData; //! transient data + GeometryTGeo* mGeometryTGeo; //! + std::vector* mHits; std::vector> mLayers; TRKServices mServices; // Houses the services of the TRK, but not the Iris tracker @@ -103,21 +98,12 @@ class Detector : public o2::base::DetImpl void defineSensitiveVolumes(); protected: - std::array, 2> mFT3LayerName; // Two sets of layer (disc) names, one per direction (forward/backward) std::vector mSensorID; //! layer identifiers std::vector mSensorName; //! layer names - std::array, 2> mFT3Layers; // Two sets of layers (discs), one per direction (forward/backward) public: static constexpr Int_t sNumberVDPetalCases = 4; //! Number of VD petals int getNumberOfLayers() const { return mLayers.size(); } //! Number of TRK layers - int getNumberOfFT3Layers() const - { - if (mFT3LayerName[kBackward].size() != mFT3LayerName[kForward].size()) { - LOG(fatal) << "Number of layers in the two directions are different! Returning 0."; - } - return mFT3LayerName[kBackward].size(); - } void Print(FairVolume* vol, int volume, int subDetID, int layer, int stave, int halfstave, int mod, int chip, int chipID) const; diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/include/TRKSimulation/TRKLayer.h similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/include/TRKSimulation/TRKLayer.h diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKServices.h b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/include/TRKSimulation/TRKServices.h similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKServices.h rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/include/TRKSimulation/TRKServices.h diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/VDGeometryBuilder.h b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/include/TRKSimulation/VDGeometryBuilder.h similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/VDGeometryBuilder.h rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/include/TRKSimulation/VDGeometryBuilder.h diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/VDLayer.h b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/include/TRKSimulation/VDLayer.h similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/VDLayer.h rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/include/TRKSimulation/VDLayer.h diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/VDSensorRegistry.h b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/include/TRKSimulation/VDSensorRegistry.h similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/VDSensorRegistry.h rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/include/TRKSimulation/VDSensorRegistry.h diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/src/Detector.cxx similarity index 71% rename from Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/src/Detector.cxx index 493b6b024f5c0..eead9a7571fd3 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/src/Detector.cxx @@ -15,7 +15,7 @@ #include "TRKBase/Specs.h" #include "TRKBase/TRKBaseParam.h" -#include "TRKSimulation/Hit.h" +#include "DataFormatsTRKFT3/Hit.h" #include "TRKSimulation/VDGeometryBuilder.h" #include "TRKSimulation/VDSensorRegistry.h" #include @@ -27,7 +27,7 @@ #include #include -using o2::trk::Hit; +using o2::trkft3::Hit; namespace o2 { @@ -42,14 +42,14 @@ float getDetLengthFromEta(const float eta, const float radius) Detector::Detector() : o2::base::DetImpl("TRK", true), mTrackData(), - mHits(o2::utils::createSimVector()) + mHits(o2::utils::createSimVector()) { } Detector::Detector(bool active) : o2::base::DetImpl("TRK", true), mTrackData(), - mHits(o2::utils::createSimVector()) + mHits(o2::utils::createSimVector()) { auto& trkPars = TRKBaseParam::Instance(); @@ -57,9 +57,6 @@ Detector::Detector(bool active) configFromFile(trkPars.configFile); } else { configMLOT(); - if (!trkPars.disableFT3) { - configFT3ScopingV3(); - } configToFile(); configServices(); } @@ -73,7 +70,7 @@ Detector::Detector(bool active) Detector::Detector(const Detector& other) : o2::base::DetImpl(other), mTrackData(), - mHits(o2::utils::createSimVector()) + mHits(o2::utils::createSimVector()) { } @@ -135,56 +132,6 @@ void Detector::configMLOT() } } -void Detector::configFT3ScopingV3() -{ - // Build the FT3 detector according to v3 layout - // https://indico.cern.ch/event/1596309/contributions/6728167/attachments/3190117/5677220/2025-12-10-AW-ALICE3planning.pdf - // Middle disks inner radius 10 cm - // Outer disks inner radius 20 cm - - LOG(info) << "Building FT3 Detector: v3 scoping version"; - - const int numberOfLayers = 6; - const float sensorThickness = 30.e-4; - const float layersx2X0 = 1.e-2; - using LayerConfig = std::array; // {z_layer, r_in, r_out, Layerx2X0} - const std::array layersConfigCSide{LayerConfig{77., 10.0, 35., layersx2X0}, - LayerConfig{100., 10.0, 35., layersx2X0}, - LayerConfig{122., 10.0, 35., layersx2X0}, - LayerConfig{150., 20.0, 68.f, layersx2X0}, - LayerConfig{180., 20.0, 68.f, layersx2X0}, - LayerConfig{220., 20.0, 68.f, layersx2X0}}; - - const std::array layersConfigASide{LayerConfig{77., 10.0, 35., layersx2X0}, - LayerConfig{100., 10.0, 35., layersx2X0}, - LayerConfig{122., 10.0, 35., layersx2X0}, - LayerConfig{150., 20.0, 68.f, layersx2X0}, - LayerConfig{180., 20.0, 68.f, layersx2X0}, - LayerConfig{220., 20.0, 68.f, layersx2X0}}; - const std::array enabled{true, true, true, true, true, true}; // To enable or disable layers for debug purpose - - for (int direction : {kBackward, kForward}) { - mFT3LayerName[direction].clear(); - const std::array& layerConfig = (direction == kBackward) ? layersConfigCSide : layersConfigASide; - for (int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) { - if (!enabled[layerNumber]) { - continue; - } - const std::string directionName = std::to_string(direction); - const std::string layerName = GeometryTGeo::getFT3LayerPattern() + directionName + std::string("_") + std::to_string(layerNumber); - mFT3LayerName[direction].push_back(layerName.c_str()); - const float z = layerConfig[layerNumber][0]; - const float rIn = layerConfig[layerNumber][1]; - const float rOut = layerConfig[layerNumber][2]; - const float x0 = layerConfig[layerNumber][3]; - LOG(info) << "buildFT3ScopingV3 -> Adding Layer " << layerNumber << "/" << numberOfLayers << " " << layerName << " at z = " << z; - // Add layers - const bool isMiddleLayer = layerNumber < 3; - auto& thisLayer = mFT3Layers[direction].emplace_back(direction, layerNumber, layerName, z, rIn, rOut, x0, isMiddleLayer); - } - } -} - void Detector::configFromFile(std::string fileName) { // Override the default geometry if config file provided @@ -430,40 +377,6 @@ void Detector::createGeometry() mServices.excavateFromVacuum("IRIS_CUTOUTsh"); mServices.registerVacuum(vTRK); - - // Place forward tracking discs - - TGeoVolume* A3IPvac = gGeoManager->GetVolume("OUT_PIPEVACUUM"); - if (!A3IPvac) { - LOG(info) << "Running simulation with no beam pipe."; - } - - // TODO: disambiquate layer/disk below - // This will need to adapt to the new scheme - if (!A3IPvac) { - for (int direction : {kBackward, kForward}) { // Backward layers at mLayers[0]; Forward layers at mLayers[1] - const std::string directionString = direction ? "Forward" : "Backward"; - LOG(info) << " Creating FT3 without beampipe " << directionString << " layers:"; - for (int iLayer = 0; iLayer < mFT3Layers[direction].size(); iLayer++) { - mFT3Layers[direction][iLayer].createLayer(vTRK); - } - } - } else { // If beampipe is enabled append inner disks to beampipe filling volume, this should be temporary. - TGeoVolume* volIFT3 = new TGeoVolumeAssembly(GeometryTGeo::getFT3InnerVolPattern()); - for (int direction : {kBackward, kForward}) { - const std::string directionString = direction ? "Forward" : "Backward"; - LOG(info) << " Creating FT3 " << directionString << " layers:"; - for (int iLayer = 0; iLayer < mFT3Layers[direction].size(); iLayer++) { - LOG(info) << " Creating " << directionString << " layer " << iLayer; - if (mFT3Layers[direction][iLayer].getIsInMiddleLayer()) { // ML disks - mFT3Layers[direction][iLayer].createLayer(volIFT3); - } else { - mFT3Layers[direction][iLayer].createLayer(vTRK); - } - } - } - A3IPvac->AddNode(volIFT3, 2, new TGeoTranslation(0., 0., 0.)); - } } void Detector::InitializeO2Detector() @@ -513,69 +426,6 @@ void Detector::defineSensitiveVolumes() LOGP(info, "Adding TRK Sensitive Volume {}", v->GetName()); AddSensitiveVolume(v); } - - // Add FT3 sensitive volumes - // TODO: do we need to loop over all volumes in our code, or can we use the geomanager? - // Get the flat list of ALL volumes present in the geometry - TObjArray* allVolumes = geoManager->GetListOfVolumes(); - int nVolumes = allVolumes->GetEntriesFast(); - - LOG(info) << "Adding FT3 Sensitive Volumes by iterating over all geometry volumes..."; - - for (int direction : {kBackward, kForward}) { - for (int iLayer = 0; iLayer < getNumberOfFT3Layers(); iLayer++) { - int iSens = 0; - - // Build the "signatures" (prefixes) of the names for the various layouts for this specific layer and direction: - - // 1. Trapezoidal/Cylindrical (format: FT3Sensor__) - std::string sig1 = Form("%s_%d_%d", GeometryTGeo::getFT3SensorPattern(), direction, iLayer); - - // 2. Segmented front/back (format: FT3Sensor_front___...) - std::string sig2 = "FT3Sensor_front_" + std::to_string(iLayer) + "_" + std::to_string(direction); - std::string sig3 = "FT3Sensor_back_" + std::to_string(iLayer) + "_" + std::to_string(direction); - - // 3. SegmentedStave (format: FT3Sensor___...) - // Add the trailing underscore to avoid confusing it with sig1 - std::string sig4 = "FT3Sensor_Active_" + std::to_string(direction) + "_" + std::to_string(iLayer) + "_"; - - // Iterate over all existing volumes to find matches - for (int i = 0; i < nVolumes; ++i) { - TGeoVolume* v = (TGeoVolume*)allVolumes->At(i); - std::string vName = v->GetName(); - - // Explicitly exclude the inactive silicon regions created in FT3Module - if (vName.find("Inactive") != std::string::npos || vName.find("inactive") != std::string::npos) { - continue; - } - - // Check if the volume name matches one of our active sensors - bool isMatch = false; - if (vName == sig1) { - isMatch = true; // Exact match for Trapezoidal/Cylindrical layouts - } else if (vName.find(sig2) == 0 || vName.find(sig3) == 0 || vName.find(sig4) == 0) { - isMatch = true; // Prefix match for Segmented and SegmentedStave layouts - } - - if (isMatch) { - AddSensitiveVolume(v); - /* - int volID = gMC ? TVirtualMC::GetMC()->VolId(vName.c_str()) : 0; - if (volID > 0) { - mActiveSensorMap[volID] = iLayer; - } - */ - iSens++; - } - } - - if (iSens == 0) { - LOG(error) << "NO sensitive volume found for FT3 direction " << direction << ", layer " << iLayer; - } else { - LOG(info) << iSens << " sensitive volume(s) added for FT3 direction " << direction << " layer " << iLayer; - } - } - } } void Detector::EndOfEvent() { Reset(); } @@ -627,6 +477,10 @@ bool Detector::ProcessHits(FairVolume* vol) ++volume; /// there are 44 volumes, 36 for the VD (1 for each sensing element) and 8 for the MLOT (1 for each layer) } + if (notSens) { + return kFALSE; // RS: can this happen? This method must be called for sensors only? + } + if (volume < mNumberOfVolumesVD) { subDetID = 0; // VD. For the moment each "chip" is a volume./// TODO: change this logic once the naming scheme is changed } else { @@ -634,21 +488,10 @@ bool Detector::ProcessHits(FairVolume* vol) layer = volume - mNumberOfVolumesVD; } - if (strstr(vol->GetName(), "FT3Sensor_Active") || strstr(vol->GetName(), "FT3Chip")) { - subDetID = 2; - notSens = false; - } - - // TODO: add corresponding logic for disks. I think Ruben is right; this is only called for active volumes! - if (notSens) { - LOG(info) << "ProcessHit called for insensitive volume " << vol->GetName(); - return kFALSE; // RS: can this happen? This method must be called for sensors only? - } - // Is it needed to keep a track reference when the outer ITS volume is encountered? auto stack = (o2::data::Stack*)fMC->GetStack(); // if (fMC->IsTrackExiting() && (lay == 0 || lay == mLayers.size() - 1)) { - if (fMC->IsTrackExiting() && subDetID < 2 && InsideFirstOrLastLayer(vol->GetName())) { + if (fMC->IsTrackExiting() && InsideFirstOrLastLayer(vol->GetName())) { // Keep the track refs for the innermost and outermost layers only o2::TrackReference tr(*fMC, GetDetId()); tr.setTrackID(stack->GetCurrentTrackNumber()); @@ -721,9 +564,7 @@ bool Detector::ProcessHits(FairVolume* vol) } } } /// if VD, for the moment the volume is the "chipID" so no need to retrieve other elments - else if (subDetID == 2) { - mGeometryTGeo->extractChipIdsFT3(vol->GetName(), layer, stave, chip); - } + unsigned short chipID = mGeometryTGeo->getChipIndex(subDetID, volume, layer, stave, halfstave, mod, chip); // Print(vol, volume, subDetID, layer, stave, halfstave, mod, chip, chipID); @@ -743,9 +584,9 @@ bool Detector::ProcessHits(FairVolume* vol) return true; } -o2::trk::Hit* Detector::addHit(int trackID, unsigned short detID, const TVector3& startPos, const TVector3& endPos, - const TVector3& startMom, double startE, double endTime, double eLoss, unsigned char startStatus, - unsigned char endStatus) +o2::trkft3::Hit* Detector::addHit(int trackID, unsigned short detID, const TVector3& startPos, const TVector3& endPos, + const TVector3& startMom, double startE, double endTime, double eLoss, unsigned char startStatus, + unsigned char endStatus) { mHits->emplace_back(trackID, detID, startPos, endPos, startMom, startE, endTime, eLoss, startStatus, endStatus); return &(mHits->back()); diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/src/TRKLayer.cxx similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/src/TRKLayer.cxx diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKServices.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/src/TRKServices.cxx similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKServices.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/src/TRKServices.cxx diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKSimulationLinkDef.h b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/src/TRKSimulationLinkDef.h similarity index 70% rename from Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKSimulationLinkDef.h rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/src/TRKSimulationLinkDef.h index 7a1d5d6d00f94..fa929c590adc2 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKSimulationLinkDef.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/src/TRKSimulationLinkDef.h @@ -15,11 +15,6 @@ #pragma link off all classes; #pragma link off all functions; -#pragma link C++ class o2::trk::Hit + ; -#pragma link C++ class std::vector < o2::trk::Hit> + ; - -#pragma link C++ class o2::trk::FT3Layer + ; - #pragma link C++ class o2::trk::TRKCylindricalLayer + ; #pragma link C++ class o2::trk::TRKSegmentedLayer + ; #pragma link C++ class o2::trk::TRKMLLayer + ; @@ -28,10 +23,4 @@ #pragma link C++ class o2::trk::TRKServices + ; #pragma link C++ class o2::trk::Detector + ; #pragma link C++ class o2::base::DetImpl < o2::trk::Detector> + ; -#pragma link C++ class o2::trk::Digitizer + ; -#pragma link C++ class o2::trk::ChipSimResponse + ; - -#pragma link C++ class o2::trk::DPLDigitizerParam < o2::detectors::DetID::TRK> + ; -#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::trk::DPLDigitizerParam < o2::detectors::DetID::TRK>> + ; - #endif diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/VDGeometryBuilder.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/src/VDGeometryBuilder.cxx similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/simulation/src/VDGeometryBuilder.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/src/VDGeometryBuilder.cxx diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/VDLayer.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/src/VDLayer.cxx similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/simulation/src/VDLayer.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/TRK/simulation/src/VDLayer.cxx diff --git a/Detectors/Upgrades/ALICE3/TRK/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRKFT3/common/CMakeLists.txt similarity index 92% rename from Detectors/Upgrades/ALICE3/TRK/CMakeLists.txt rename to Detectors/Upgrades/ALICE3/TRKFT3/common/CMakeLists.txt index 6e3437c9d841b..6cd471f6f74de 100644 --- a/Detectors/Upgrades/ALICE3/TRK/CMakeLists.txt +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/CMakeLists.txt @@ -9,8 +9,6 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -add_subdirectory(base) -add_subdirectory(macros) add_subdirectory(simulation) add_subdirectory(reconstruction) add_subdirectory(workflow) diff --git a/Detectors/Upgrades/ALICE3/TRK/reconstruction/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/CMakeLists.txt similarity index 96% rename from Detectors/Upgrades/ALICE3/TRK/reconstruction/CMakeLists.txt rename to Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/CMakeLists.txt index 45ce53ba7c3a3..fab32edc7c819 100644 --- a/Detectors/Upgrades/ALICE3/TRK/reconstruction/CMakeLists.txt +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/CMakeLists.txt @@ -20,7 +20,7 @@ o2_add_library(TRKReconstruction PUBLIC_LINK_LIBRARIES Microsoft.GSL::GSL O2::DataFormatsITSMFT - O2::DataFormatsTRK + O2::DataFormatsTRKFT3 O2::SimulationDataFormat O2::TRKBase nlohmann_json::nlohmann_json diff --git a/Detectors/Upgrades/ALICE3/TRK/reconstruction/include/TRKReconstruction/Clusterer.h b/Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/include/TRKReconstruction/Clusterer.h similarity index 84% rename from Detectors/Upgrades/ALICE3/TRK/reconstruction/include/TRKReconstruction/Clusterer.h rename to Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/include/TRKReconstruction/Clusterer.h index 3d30eb5068efe..0e709476d09fd 100644 --- a/Detectors/Upgrades/ALICE3/TRK/reconstruction/include/TRKReconstruction/Clusterer.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/include/TRKReconstruction/Clusterer.h @@ -19,11 +19,11 @@ // | *| #define _ALLOW_DIAGONAL_TRK_CLUSTERS_ -#include "DataFormatsITSMFT/Digit.h" -#include "DataFormatsITSMFT/ROFRecord.h" +#include "DataFormatsTRKFT3/Digit.h" #include "DataFormatsITSMFT/ClusterPattern.h" -#include "DataFormatsTRK/Cluster.h" -#include "DataFormatsTRK/ROFRecord.h" +#include "DataFormatsTRKFT3/Cluster.h" +#include "DataFormatsTRKFT3/ROFRecord.h" +#include "DetectorsCommonDataFormats/DetID.h" #include "SimulationDataFormat/ConstMCTruthContainer.h" #include "SimulationDataFormat/MCCompLabel.h" #include "SimulationDataFormat/MCTruthContainer.h" @@ -41,15 +41,18 @@ namespace o2::trk class GeometryTGeo; +template class Clusterer { + static_assert(DetID == o2::detectors::DetID::TRK || DetID == o2::detectors::DetID::FT3, "only TRK and FT3 clusterers are supported"); + public: static constexpr int MaxLabels = 10; static constexpr int MaxHugeClusWarn = 5; - using Digit = o2::itsmft::Digit; - using DigROFRecord = o2::itsmft::ROFRecord; - using DigMC2ROFRecord = o2::itsmft::MC2ROFRecord; + using Digit = o2::trkft3::Digit; + using DigROFRecord = o2::trkft3::ROFRecord; + using ClusterType = o2::trkft3::Cluster; using ClusterTruth = o2::dataformats::MCTruthContainer; using ConstDigitTruth = o2::dataformats::ConstMCTruthContainerView; using Label = o2::MCCompLabel; @@ -87,7 +90,7 @@ class Clusterer //---------------------------------------------- struct ClustererThread { - Clusterer* parent = nullptr; + Clusterer* parent = nullptr; // column buffers (pre-cluster state); extra sentinel entries at [0] and [size-1] int* column1 = nullptr; int* column2 = nullptr; @@ -106,7 +109,7 @@ class Clusterer std::vector> pixArrBuff; ///< (row,col) pixel buffer for pattern // per-thread output (accumulated, then merged back by caller) - std::vector clusters; + std::vector clusters; std::vector patterns; ClusterTruth labels; @@ -144,19 +147,19 @@ class Clusterer const ConstDigitTruth* labelsDigPtr, ClusterTruth* labelsClusPtr, GeometryTGeo* geom); void processChip(gsl::span digits, int chipFirst, int chipN, - std::vector* clustersOut, std::vector* patternsOut, + std::vector* clustersOut, std::vector* patternsOut, const ConstDigitTruth* labelsDigPtr, ClusterTruth* labelsClusPtr, GeometryTGeo* geom); void streamCluster(const BBox& bbox, const std::vector>& pixbuf, uint32_t totalCharge, bool doLabels, int nlab, - uint16_t chipID, int subDetID, int layer, int disk); + uint16_t chipID, int subDetID, int layer); ~ClustererThread() { delete[] column1; delete[] column2; } - explicit ClustererThread(Clusterer* par = nullptr) : parent(par) {} + explicit ClustererThread(Clusterer* par = nullptr) : parent(par) {} ClustererThread(const ClustererThread&) = delete; ClustererThread& operator=(const ClustererThread&) = delete; }; @@ -164,15 +167,13 @@ class Clusterer virtual void process(gsl::span digits, gsl::span digitROFs, - std::vector& clusters, + std::vector& clusters, std::vector& patterns, - std::vector& clusterROFs, + std::vector& clusterROFs, const ConstDigitTruth* digitLabels = nullptr, - ClusterTruth* clusterLabels = nullptr, - gsl::span digMC2ROFs = {}, - std::vector* clusterMC2ROFs = nullptr); + ClusterTruth* clusterLabels = nullptr); - static o2::math_utils::Point3D getClusterLocalCoordinates(const Cluster& cluster, const uint8_t* patt, + static o2::math_utils::Point3D getClusterLocalCoordinates(const ClusterType& cluster, const uint8_t* patt, float yPlaneMLOT = 0.f) noexcept; protected: @@ -181,6 +182,9 @@ class Clusterer std::vector mSortIdx; ///< reusable per-ROF sort buffer }; +using TRKClusterer = Clusterer; +using FT3Clusterer = Clusterer; + } // namespace o2::trk #endif diff --git a/Detectors/Upgrades/ALICE3/TRK/reconstruction/include/TRKReconstruction/ClustererACTS.h b/Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/include/TRKReconstruction/ClustererACTS.h similarity index 76% rename from Detectors/Upgrades/ALICE3/TRK/reconstruction/include/TRKReconstruction/ClustererACTS.h rename to Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/include/TRKReconstruction/ClustererACTS.h index 37a148aa78afb..f207a6dc0e24c 100644 --- a/Detectors/Upgrades/ALICE3/TRK/reconstruction/include/TRKReconstruction/ClustererACTS.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/include/TRKReconstruction/ClustererACTS.h @@ -26,18 +26,16 @@ namespace o2::trk class GeometryTGeo; -class ClustererACTS : public Clusterer +class ClustererACTS : public TRKClusterer { public: void process(gsl::span digits, gsl::span digitROFs, - std::vector& clusters, + std::vector& clusters, std::vector& patterns, - std::vector& clusterROFs, + std::vector& clusterROFs, const ConstDigitTruth* digitLabels = nullptr, - ClusterTruth* clusterLabels = nullptr, - gsl::span digMC2ROFs = {}, - std::vector* clusterMC2ROFs = nullptr) override; + ClusterTruth* clusterLabels = nullptr) override; private: }; diff --git a/Detectors/Upgrades/ALICE3/TRK/reconstruction/src/Clusterer.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/src/Clusterer.cxx similarity index 80% rename from Detectors/Upgrades/ALICE3/TRK/reconstruction/src/Clusterer.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/src/Clusterer.cxx index d60d6900657ba..0bd64be5efbc4 100644 --- a/Detectors/Upgrades/ALICE3/TRK/reconstruction/src/Clusterer.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/src/Clusterer.cxx @@ -23,8 +23,9 @@ namespace o2::trk { //__________________________________________________ -o2::math_utils::Point3D Clusterer::getClusterLocalCoordinates(const Cluster& cluster, const uint8_t* patt, - float yPlaneMLOT) noexcept +template +o2::math_utils::Point3D Clusterer::getClusterLocalCoordinates(const typename Clusterer::ClusterType& cluster, const uint8_t* patt, + float yPlaneMLOT) noexcept { const uint8_t rowSpan = *patt++; const uint8_t colSpan = *patt++; @@ -49,7 +50,7 @@ o2::math_utils::Point3D Clusterer::getClusterLocalCoordinates(const Clust float x{0.f}, y{0.f}, z{0.f}; SegmentationChip::detectorToLocalUnchecked(cluster.row, cluster.col, x, z, - cluster.subDetID, cluster.layer, cluster.disk); + cluster.subDetID, cluster.layer, cluster.layer); const float pitchRow = (cluster.subDetID == 0) ? SegmentationChip::PitchRowVD : SegmentationChip::PitchRowMLOT; const float pitchCol = (cluster.subDetID == 0) ? SegmentationChip::PitchColVD : SegmentationChip::PitchColMLOT; @@ -68,15 +69,14 @@ o2::math_utils::Point3D Clusterer::getClusterLocalCoordinates(const Clust } //__________________________________________________ -void Clusterer::process(gsl::span digits, - gsl::span digitROFs, - std::vector& clusters, - std::vector& patterns, - std::vector& clusterROFs, - const ConstDigitTruth* digitLabels, - ClusterTruth* clusterLabels, - gsl::span digMC2ROFs, - std::vector* clusterMC2ROFs) +template +void Clusterer::process(gsl::span digits, + gsl::span digitROFs, + std::vector& clusters, + std::vector& patterns, + std::vector& clusterROFs, + const ConstDigitTruth* digitLabels, + ClusterTruth* clusterLabels) { if (!mThread) { mThread = std::make_unique(this); @@ -127,23 +127,17 @@ void Clusterer::process(gsl::span digits, clusterROFs.emplace_back(inROF.getBCData(), inROF.getROFrame(), outFirst, static_cast(clusters.size()) - outFirst); } - - if (clusterMC2ROFs && !digMC2ROFs.empty()) { - clusterMC2ROFs->reserve(clusterMC2ROFs->size() + digMC2ROFs.size()); - for (const auto& in : digMC2ROFs) { - clusterMC2ROFs->emplace_back(in.eventRecordID, in.rofRecordID, in.minROF, in.maxROF); - } - } } //__________________________________________________ -void Clusterer::ClustererThread::processChip(gsl::span digits, - int chipFirst, int chipN, - std::vector* clustersOut, - std::vector* patternsOut, - const ConstDigitTruth* labelsDigPtr, - ClusterTruth* labelsClusPtr, - GeometryTGeo* geom) +template +void Clusterer::ClustererThread::processChip(gsl::span digits, + int chipFirst, int chipN, + std::vector* clustersOut, + std::vector* patternsOut, + const ConstDigitTruth* labelsDigPtr, + ClusterTruth* labelsClusPtr, + GeometryTGeo* geom) { // chipFirst and chipN are relative to mSortIdx (i.e. mSortIdx[chipFirst..chipFirst+chipN-1] // are the global digit indices for this chip, already sorted by col then row). @@ -176,7 +170,8 @@ void Clusterer::ClustererThread::processChip(gsl::span digits, } //__________________________________________________ -void Clusterer::ClustererThread::initChip(gsl::span digits, uint32_t first, GeometryTGeo* geom) +template +void Clusterer::ClustererThread::initChip(gsl::span digits, uint32_t first, GeometryTGeo* geom) { const uint16_t chipID = digits[first].getChipIndex(); @@ -213,7 +208,8 @@ void Clusterer::ClustererThread::initChip(gsl::span digits, uint32_ } //__________________________________________________ -void Clusterer::ClustererThread::updateChip(gsl::span digits, uint32_t ip) +template +void Clusterer::ClustererThread::updateChip(gsl::span digits, uint32_t ip) { const auto& pix = digits[ip]; uint16_t row = pix.getRow(); @@ -268,10 +264,11 @@ void Clusterer::ClustererThread::updateChip(gsl::span digits, uint3 } //__________________________________________________ -void Clusterer::ClustererThread::finishChip(gsl::span digits, - const ConstDigitTruth* labelsDigPtr, - ClusterTruth* labelsClusPtr, - GeometryTGeo* geom) +template +void Clusterer::ClustererThread::finishChip(gsl::span digits, + const ConstDigitTruth* labelsDigPtr, + ClusterTruth* labelsClusPtr, + GeometryTGeo* geom) { const uint16_t chipID = digits[pixels[0].second].getChipIndex(); @@ -314,16 +311,15 @@ void Clusterer::ClustererThread::finishChip(gsl::span digits, } // Determine geometry info - int subDetID = -1, layer = -1, disk = -1; + int subDetID = -1, layer = -1; if (geom) { subDetID = geom->getSubDetID(chipID); layer = geom->getLayer(chipID); - disk = geom->getDisk(chipID); } const bool doLabels = (labelsClusPtr != nullptr); if (bbox.isAcceptableSize()) { - streamCluster(bbox, pixArrBuff, totalCharge, doLabels, nlab, chipID, subDetID, layer, disk); + streamCluster(bbox, pixArrBuff, totalCharge, doLabels, nlab, chipID, subDetID, layer); } else { // Huge cluster: split into MaxRowSpan x MaxColSpan tiles (same as ITS3) auto warnLeft = MaxHugeClusWarn - parent->mNHugeClus; @@ -349,7 +345,7 @@ void Clusterer::ClustererThread::finishChip(gsl::span digits, } } if (!subPix.empty()) { - streamCluster(bboxT, subPix, subCharge, doLabels, nlab, chipID, subDetID, layer, disk); + streamCluster(bboxT, subPix, subCharge, doLabels, nlab, chipID, subDetID, layer); } bboxT.rowMin = bboxT.rowMax + 1; } while (bboxT.rowMin <= bbox.rowMax); @@ -361,10 +357,11 @@ void Clusterer::ClustererThread::finishChip(gsl::span digits, } //__________________________________________________ -void Clusterer::ClustererThread::finishChipSingleHitFast(gsl::span digits, uint32_t hit, - const ConstDigitTruth* labelsDigPtr, - ClusterTruth* labelsClusPtr, - GeometryTGeo* geom) +template +void Clusterer::ClustererThread::finishChipSingleHitFast(gsl::span digits, uint32_t hit, + const ConstDigitTruth* labelsDigPtr, + ClusterTruth* labelsClusPtr, + GeometryTGeo* geom) { const auto& d = digits[hit]; const uint16_t chipID = d.getChipIndex(); @@ -385,7 +382,7 @@ void Clusterer::ClustererThread::finishChipSingleHitFast(gsl::span patterns.emplace_back(1); patterns.emplace_back(0x80); - Cluster cluster; + ClusterType cluster; cluster.chipID = chipID; cluster.row = row; cluster.col = col; @@ -393,17 +390,17 @@ void Clusterer::ClustererThread::finishChipSingleHitFast(gsl::span if (geom) { cluster.subDetID = geom->getSubDetID(chipID); cluster.layer = geom->getLayer(chipID); - cluster.disk = geom->getDisk(chipID); } clusters.emplace_back(cluster); } //__________________________________________________ -void Clusterer::ClustererThread::streamCluster(const BBox& bbox, - const std::vector>& pixbuf, - uint32_t totalCharge, - bool doLabels, int nlab, - uint16_t chipID, int subDetID, int layer, int disk) +template +void Clusterer::ClustererThread::streamCluster(const BBox& bbox, + const std::vector>& pixbuf, + uint32_t totalCharge, + bool doLabels, int nlab, + uint16_t chipID, int subDetID, int layer) { if (doLabels) { const auto cnt = static_cast(clusters.size()); @@ -427,19 +424,19 @@ void Clusterer::ClustererThread::streamCluster(const BBox& bbox, int nBytes = (rowSpanW * colSpanW + 7) / 8; patterns.insert(patterns.end(), patt.begin(), patt.begin() + nBytes); - Cluster cluster; + ClusterType cluster; cluster.chipID = chipID; cluster.row = bbox.rowMin; cluster.col = bbox.colMin; cluster.size = static_cast(pixbuf.size()); cluster.subDetID = static_cast(subDetID); cluster.layer = static_cast(layer); - cluster.disk = static_cast(disk); clusters.emplace_back(cluster); } //__________________________________________________ -void Clusterer::ClustererThread::fetchMCLabels(uint32_t digID, const ConstDigitTruth* labelsDig, int& nfilled) +template +void Clusterer::ClustererThread::fetchMCLabels(uint32_t digID, const ConstDigitTruth* labelsDig, int& nfilled) { if (nfilled >= MaxLabels) { return; @@ -462,4 +459,7 @@ void Clusterer::ClustererThread::fetchMCLabels(uint32_t digID, const ConstDigitT } } +template class Clusterer; +template class Clusterer; + } // namespace o2::trk diff --git a/Detectors/Upgrades/ALICE3/TRK/reconstruction/src/ClustererACTS.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/src/ClustererACTS.cxx similarity index 94% rename from Detectors/Upgrades/ALICE3/TRK/reconstruction/src/ClustererACTS.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/src/ClustererACTS.cxx index 30ab503b7e250..86ac9f508a042 100644 --- a/Detectors/Upgrades/ALICE3/TRK/reconstruction/src/ClustererACTS.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/src/ClustererACTS.cxx @@ -158,13 +158,11 @@ Cluster2D gencluster(int x0, int y0, int x1, int y1, RNG& rng, //__________________________________________________ void ClustererACTS::process(gsl::span digits, gsl::span digitROFs, - std::vector& clusters, + std::vector& clusters, std::vector& patterns, - std::vector& clusterROFs, + std::vector& clusterROFs, const ConstDigitTruth* digitLabels, - ClusterTruth* clusterLabels, - gsl::span digMC2ROFs, - std::vector* clusterMC2ROFs) + ClusterTruth* clusterLabels) { if (!mThread) { mThread = std::make_unique(this); @@ -326,7 +324,7 @@ void ClustererACTS::process(gsl::span digits, } // Create O2 cluster for this tile - o2::trk::Cluster cluster; + o2::trkft3::TRKCluster cluster; cluster.chipID = chipID; cluster.row = tileRowMin; cluster.col = tileColMin; @@ -334,7 +332,6 @@ void ClustererACTS::process(gsl::span digits, if (geom) { cluster.subDetID = static_cast(geom->getSubDetID(chipID)); cluster.layer = static_cast(geom->getLayer(chipID)); - cluster.disk = static_cast(geom->getDisk(chipID)); } clusters.emplace_back(cluster); } @@ -367,7 +364,7 @@ void ClustererACTS::process(gsl::span digits, } // Create O2 cluster - o2::trk::Cluster cluster; + o2::trkft3::TRKCluster cluster; cluster.chipID = chipID; cluster.row = rowMin; cluster.col = colMin; @@ -375,7 +372,6 @@ void ClustererACTS::process(gsl::span digits, if (geom) { cluster.subDetID = static_cast(geom->getSubDetID(chipID)); cluster.layer = static_cast(geom->getLayer(chipID)); - cluster.disk = static_cast(geom->getDisk(chipID)); } clusters.emplace_back(cluster); } @@ -386,11 +382,4 @@ void ClustererACTS::process(gsl::span digits, clusterROFs.emplace_back(inROF.getBCData(), inROF.getROFrame(), outFirst, static_cast(clusters.size()) - outFirst); } - - // if (clusterMC2ROFs && !digMC2ROFs.empty()) { - // clusterMC2ROFs->reserve(clusterMC2ROFs->size() + digMC2ROFs.size()); - // for (const auto& in : digMC2ROFs) { - // clusterMC2ROFs->emplace_back(in.eventRecordID, in.rofRecordID, in.minROF, in.maxROF); - // } - // } } diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/CMakeLists.txt new file mode 100644 index 0000000000000..ce9b79217997e --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/CMakeLists.txt @@ -0,0 +1,31 @@ +# Copyright 2019-2026 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. + +o2_add_library(TRKFT3Simulation + SOURCES src/ChipDigitsContainer.cxx + src/ChipSimResponse.cxx + src/DigiParams.cxx + src/Digitizer.cxx + src/DPLDigitizerParam.cxx + PUBLIC_LINK_LIBRARIES O2::TRKBase + O2::FT3Base + O2::DataFormatsTRKFT3 + O2::ITSMFTSimulation + O2::DetectorsRaw + O2::SimulationDataFormat) + +o2_target_root_dictionary(TRKFT3Simulation + HEADERS include/TRKFT3Simulation/ChipDigitsContainer.h + include/TRKFT3Simulation/ChipSimResponse.h + include/TRKFT3Simulation/DigiParams.h + include/TRKFT3Simulation/Digitizer.h + include/TRKFT3Simulation/DPLDigitizerParam.h + LINKDEF src/TRKFT3SimulationLinkDef.h) diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/ChipDigitsContainer.h b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/ChipDigitsContainer.h new file mode 100644 index 0000000000000..10c55e6163846 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/ChipDigitsContainer.h @@ -0,0 +1,92 @@ +// 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_TRK_CHIPDIGITSCONTAINER_ +#define ALICEO2_TRK_CHIPDIGITSCONTAINER_ + +#include "ITSMFTBase/SegmentationAlpide.h" +#include "ITSMFTSimulation/ChipDigitsContainer.h" +#include "TRKBase/SegmentationChip.h" +#include "TRKBase/Specs.h" +#include "TRKFT3Simulation/DigiParams.h" +#include +#include + +namespace o2::trkft3 +{ + +class ChipDigitsContainer : public o2::itsmft::ChipDigitsContainer +{ + public: + explicit ChipDigitsContainer(UShort_t idx = 0); + + using Segmentation = o2::trk::SegmentationChip; + + /// Get global ordering key made of readout frame, column and row + static ULong64_t getOrderingKey(UInt_t roframe, UShort_t row, UShort_t col) + { + return (static_cast(roframe) << (8 * sizeof(UInt_t))) + (static_cast(col) << (8 * sizeof(Short_t))) + row; + } + + /// Adds noise digits, deleted the one using the itsmft::DigiParams interface + void addNoise(UInt_t rofMin, UInt_t rofMax, const o2::itsmft::DigiParams* params, int maxRows = o2::itsmft::SegmentationAlpide::NRows, int maxCols = o2::itsmft::SegmentationAlpide::NCols) = delete; + template + void addNoise(UInt_t rofMin, UInt_t rofMax, const o2::trkft3::DigiParams* params, int subDetID, int layer); + + ClassDefNV(ChipDigitsContainer, 1); +}; + +} // namespace o2::trkft3 + +template +void o2::trkft3::ChipDigitsContainer::addNoise(UInt_t rofMin, UInt_t rofMax, const o2::trkft3::DigiParams* params, int subDetID, int layer) +{ + UInt_t row = 0; + UInt_t col = 0; + Int_t nhits = 0; + float mean = 0.f; + int nel = 0; + int maxRows = 0; + int maxCols = 0; + + if (subDetID == 0) { + maxRows = o2::trk::constants::VD::petal::layer::nRows[layer]; + maxCols = o2::trk::constants::VD::petal::layer::nCols; + } else { + maxRows = o2::trk::constants::moduleMLOT::chip::nRows; + maxCols = o2::trk::constants::moduleMLOT::chip::nCols; + } + mean = params->getNoisePerPixel() * maxRows * maxCols; + nel = static_cast(params->getChargeThreshold() * 1.1); + + LOG(debug) << "Adding noise for chip " << mChipIndex << " with mean " << mean << " and charge " << nel; + + for (UInt_t rof = rofMin; rof <= rofMax; rof++) { + nhits = gRandom->Poisson(mean); + for (Int_t i = 0; i < nhits; ++i) { + row = gRandom->Integer(maxRows); + col = gRandom->Integer(maxCols); + LOG(debug) << "Generated noise hit at ROF " << rof << ", row " << row << ", col " << col; + if (mNoiseMap && mNoiseMap->isNoisy(mChipIndex, row, col)) { + continue; + } + if (mDeadChanMap && mDeadChanMap->isNoisy(mChipIndex, row, col)) { + continue; + } + auto key = getOrderingKey(rof, row, col); + if (!findDigit(key)) { + addDigit(key, rof, row, col, nel, o2::MCCompLabel(true)); + } + } + } +} + +#endif // ALICEO2_TRK_CHIPDIGITSCONTAINER_ diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/ChipSimResponse.h b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/ChipSimResponse.h similarity index 96% rename from Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/ChipSimResponse.h rename to Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/ChipSimResponse.h index 29147997f66bf..99f966f0c608a 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/ChipSimResponse.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/ChipSimResponse.h @@ -16,7 +16,7 @@ namespace o2 { -namespace trk +namespace trkft3 { class ChipSimResponse : public o2::itsmft::AlpideSimResponse @@ -31,7 +31,7 @@ class ChipSimResponse : public o2::itsmft::AlpideSimResponse ClassDef(ChipSimResponse, 1); }; -} // namespace trk +} // namespace trkft3 } // namespace o2 #endif // ALICEO2_TRKSIMULATION_CHIPSIMRESPONSE_H diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/DPLDigitizerParam.h b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/DPLDigitizerParam.h similarity index 98% rename from Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/DPLDigitizerParam.h rename to Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/DPLDigitizerParam.h index de839b27aefee..f4b37142b6019 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/DPLDigitizerParam.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/DPLDigitizerParam.h @@ -19,7 +19,7 @@ namespace o2 { -namespace trk +namespace trkft3 { template struct DPLDigitizerParam : public o2::conf::ConfigurableParamHelper> { @@ -63,7 +63,7 @@ struct DPLDigitizerParam : public o2::conf::ConfigurableParamHelper DPLDigitizerParam DPLDigitizerParam::sInstance; -} // namespace trk +} // namespace trkft3 } // namespace o2 #endif diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/DigiParams.h b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/DigiParams.h similarity index 72% rename from Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/DigiParams.h rename to Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/DigiParams.h index d7d1ea28bfcf7..004bf6fb40759 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/DigiParams.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/DigiParams.h @@ -16,13 +16,14 @@ #define ALICEO2_TRK_DIGIPARAMS_H #include +#include +#include #include +#include "DetectorsCommonDataFormats/DetID.h" #include "ITSMFTSimulation/AlpideSignalTrapezoid.h" #include "ITSMFTSimulation/AlpideSimResponse.h" #include "TRKBase/AlmiraParam.h" -#include "TRKBase/TRKBaseParam.h" -#include "TRKBase/GeometryTGeo.h" //////////////////////////////////////////////////////////// // // @@ -36,20 +37,41 @@ namespace o2 { -namespace trk +namespace trkft3 { class ChipSimResponse; +namespace detail +{ +template +struct DigiParamsLayerTraits; + +template <> +struct DigiParamsLayerTraits { + static constexpr size_t MaxLayers = o2::trk::AlmiraParam::getNLayers(); +}; + +template <> +struct DigiParamsLayerTraits { + static constexpr size_t MaxLayers = 20; // two FT3 sides with the default 10 layers per side +}; +} // namespace detail + +template class DigiParams { + static_assert(DetIDV == o2::detectors::DetID::TRK || DetIDV == o2::detectors::DetID::FT3, "only TRK and FT3 digit parameters are supported"); using SignalShape = o2::itsmft::AlpideSignalTrapezoid; + static constexpr size_t MaxLayers = detail::DigiParamsLayerTraits::MaxLayers; public: DigiParams(); ~DigiParams() = default; + static constexpr size_t getMaxLayers() { return MaxLayers; } + void setNoisePerPixel(float v) { mNoisePerPixel = v; } float getNoisePerPixel() const { return mNoisePerPixel; } @@ -92,7 +114,7 @@ class DigiParams bool isTimeOffsetSet() const { return mTimeOffset > -infTime; } - const o2::trk::ChipSimResponse* getResponse() const { return mResponse.get(); } + const o2::trkft3::ChipSimResponse* getResponse() const { return mResponse.get(); } void setResponse(const o2::itsmft::AlpideSimResponse*); const SignalShape& getSignalShape() const { return mSignalShape; } @@ -115,22 +137,25 @@ class DigiParams float mIBVbb = 0.0; ///< back bias absolute value for ITS Inner Barrel (in Volt) float mOBVbb = 0.0; ///< back bias absolute value for ITS Outter Barrel (in Volt) - std::array mROFrameLayerLengthInBC; ///< staggering ROF length in BC for continuous mode per layer - std::array mROFrameLayerBiasInBC; ///< staggering ROF bias in BC for continuous mode per layer - std::array mROFrameLayerLength; ///< staggering ROF length in ns for continuous mode per layer - std::array mStrobeLayerLength; ///< staggering strobe length in ns per layer - std::array mStrobeLayerDelay; ///< staggering strobe delay in ns per layer + std::array mROFrameLayerLengthInBC; ///< staggering ROF length in BC for continuous mode per layer + std::array mROFrameLayerBiasInBC; ///< staggering ROF bias in BC for continuous mode per layer + std::array mROFrameLayerLength; ///< staggering ROF length in ns for continuous mode per layer + std::array mStrobeLayerLength; ///< staggering strobe length in ns per layer + std::array mStrobeLayerDelay; ///< staggering strobe delay in ns per layer o2::itsmft::AlpideSignalTrapezoid mSignalShape; ///< signal timeshape parameterization - std::unique_ptr mResponse; //!< pointer on external response + std::unique_ptr mResponse; //!< pointer on external response // auxiliary precalculated parameters - std::array mROFrameLayerLengthInv; ///< inverse length of RO frame in ns per layer + std::array mROFrameLayerLengthInv; ///< inverse length of RO frame in ns per layer // ClassDef(DigiParams, 2); }; -} // namespace trk + +using TRKDigiParams = DigiParams; +using FT3DigiParams = DigiParams; +} // namespace trkft3 } // namespace o2 #endif diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Digitizer.h b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/Digitizer.h similarity index 62% rename from Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Digitizer.h rename to Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/Digitizer.h index a0e5902cc5cde..22c61352c03ee 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/Digitizer.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/include/TRKFT3Simulation/Digitizer.h @@ -10,52 +10,57 @@ // or submit itself to any jurisdiction. /// \file Digitizer.h -/// \brief Definition of the TRK digitizer -#ifndef ALICEO2_TRK_DIGITIZER_H -#define ALICEO2_TRK_DIGITIZER_H +/// \brief Definition of the TRK/FT3 digitizer +#ifndef ALICEO2_TRKFT3_DIGITIZER_H +#define ALICEO2_TRKFT3_DIGITIZER_H #include #include #include +#include #include "Rtypes.h" // for Digitizer::Class #include "TObject.h" // for TObject -#include "TRKSimulation/ChipSimResponse.h" -#include "TRKSimulation/ChipDigitsContainer.h" +#include "TRKFT3Simulation/ChipSimResponse.h" +#include "TRKFT3Simulation/ChipDigitsContainer.h" -#include "TRKSimulation/DigiParams.h" -#include "TRKSimulation/Hit.h" +#include "TRKFT3Simulation/DigiParams.h" +#include "DataFormatsTRKFT3/Hit.h" +#include "DetectorsCommonDataFormats/DetID.h" +#include "FT3Base/GeometryTGeo.h" #include "TRKBase/GeometryTGeo.h" -#include "DataFormatsITSMFT/Digit.h" -#include "DataFormatsITSMFT/ROFRecord.h" +#include "DataFormatsTRKFT3/Digit.h" +#include "DataFormatsTRKFT3/ROFRecord.h" #include "CommonDataFormat/InteractionRecord.h" #include "SimulationDataFormat/MCCompLabel.h" #include "SimulationDataFormat/MCTruthContainer.h" -#endif -namespace o2::trk +namespace o2::trkft3 { +template class Digitizer { + static_assert(DetID == o2::detectors::DetID::TRK || DetID == o2::detectors::DetID::FT3, "only TRK and FT3 digitizers are supported"); + using GeometryTGeo = std::conditional_t; using ExtraDig = std::vector; ///< container for extra contributions to PreDigits public: - void setDigits(std::vector* dig) { mDigits = dig; } + void setDigits(std::vector* dig) { mDigits = dig; } void setMCLabels(o2::dataformats::MCTruthContainer* mclb) { mMCLabels = mclb; } - void setROFRecords(std::vector* rec) { mROFRecords = rec; } + void setROFRecords(std::vector* rec) { mROFRecords = rec; } void setResponseName(const std::string& name) { mRespName = name; } - o2::trk::DigiParams& getParams() { return (o2::trk::DigiParams&)mParams; } - const o2::trk::DigiParams& getParams() const { return mParams; } + o2::trkft3::DigiParams& getParams() { return mParams; } + const o2::trkft3::DigiParams& getParams() const { return mParams; } void init(); - const o2::trk::ChipSimResponse* getChipResponse(int chipID); + const o2::trkft3::ChipSimResponse* getChipResponse(int chipID); /// Steer conversion of hits to digits - void process(const std::vector* hits, int evID, int srcID, int layer); + void process(const std::vector* hits, int evID, int srcID, int layer); void setEventTime(const o2::InteractionTimeRecord& irt, int layer); void fillOutputContainer(uint32_t maxFrame, int layer); @@ -69,12 +74,11 @@ class Digitizer mExtraBuff.clear(); } - const o2::trk::DigiParams& getDigitParams() const { return mParams; } + const o2::trkft3::DigiParams& getDigitParams() const { return mParams; } - // provide the common trk::GeometryTGeo to access matrices and segmentation - void setGeometry(const o2::trk::GeometryTGeo* gm) + void setGeometry(const GeometryTGeo* gm) { - LOG(info) << "trk::Digizer set geom"; + LOG(info) << "trkft3::Digitizer set geom"; mGeometry = gm; } @@ -89,8 +93,8 @@ class Digitizer void setDeadChannelsMap(const o2::itsmft::NoiseMap* mp) { mDeadChanMap = mp; } private: - void processHit(const o2::trk::Hit& hit, uint32_t& maxFr, int evID, int srcID, int rofLayer); - void registerDigits(o2::trk::ChipDigitsContainer& chip, uint32_t roFrame, float tInROF, int nROF, + void processHit(const o2::trkft3::Hit& hit, uint32_t& maxFr, int evID, int srcID, int rofLayer); + void registerDigits(o2::trkft3::ChipDigitsContainer& chip, uint32_t roFrame, float tInROF, int nROF, uint16_t row, uint16_t col, int nEle, o2::MCCompLabel& lbl, int layer); ExtraDig* getExtraDigBuffer(uint32_t roFrame) @@ -112,9 +116,9 @@ class Digitizer int getNCols(int subDetID, int layer) { if (subDetID == 0) { // VD - return constants::VD::petal::layer::nCols; + return o2::trk::constants::VD::petal::layer::nCols; } else if (subDetID == 1 || subDetID == 2) { // ML/OT: the smallest element is a chip of 470 rows and 640 cols - return constants::moduleMLOT::chip::nCols; + return o2::trk::constants::moduleMLOT::chip::nCols; } return 0; } @@ -126,16 +130,34 @@ class Digitizer int getNRows(int subDetID, int layer) { if (subDetID == 0) { // VD - return constants::VD::petal::layer::nRows[layer]; + return o2::trk::constants::VD::petal::layer::nRows[layer]; } else if (subDetID == 1 || subDetID == 2) { // ML/OT - return constants::moduleMLOT::chip::nRows; + return o2::trk::constants::moduleMLOT::chip::nRows; } return 0; } + int getROFLayer(int chipID) const + { + if constexpr (DetID == o2::detectors::DetID::TRK) { + return mGeometry->getLayerTRK(chipID); + } else { + return mGeometry->getLayer(chipID); + } + } + + int getDisk(int chipID) const + { + if constexpr (DetID == o2::detectors::DetID::TRK) { + return mGeometry->getDisk(chipID); + } else { + return -1; + } + } + static constexpr float sec2ns = 1e9; - o2::trk::DigiParams mParams; ///< digitization parameters + o2::trkft3::DigiParams mParams; ///< digitization parameters o2::InteractionTimeRecord mEventTime; ///< global event time and interaction record o2::InteractionRecord mIRFirstSampledTF; ///< IR of the 1st sampled IR, noise-only ROFs will be inserted till this IR only double mCollisionTimeWrtROF{}; @@ -150,9 +172,9 @@ class Digitizer int mNumberOfChips = 0; - const o2::trk::ChipSimResponse* mChipSimResp = nullptr; // simulated response - const o2::trk::ChipSimResponse* mChipSimRespVD = nullptr; // simulated response for VD chips - const o2::trk::ChipSimResponse* mChipSimRespMLOT = nullptr; // simulated response for ML/OT chips + const o2::trkft3::ChipSimResponse* mChipSimResp = nullptr; // simulated response + const o2::trkft3::ChipSimResponse* mChipSimRespVD = nullptr; // simulated response for VD chips + const o2::trkft3::ChipSimResponse* mChipSimRespMLOT = nullptr; // simulated response for ML/OT chips std::string mRespName; /// APTS or ALICE3, depending on the response to be used @@ -166,16 +188,21 @@ class Digitizer float mSimRespVDScaleDepth{1.f}; // scale depth-local coordinate to response function depth-coordinate float mSimRespMLOTScaleDepth{1.f}; // scale depth-local coordinate to response function depth-coordinate - const o2::trk::GeometryTGeo* mGeometry = nullptr; ///< TRK geometry + const GeometryTGeo* mGeometry = nullptr; ///< TRK or FT3 geometry - std::vector mChips; ///< Array of chips digits containers - std::deque> mExtraBuff; ///< buffer (per roFrame) for extra digits + std::vector mChips; ///< Array of chips digits containers + std::deque> mExtraBuff; ///< buffer (per roFrame) for extra digits - std::vector* mDigits = nullptr; //! output digits - std::vector* mROFRecords = nullptr; //! output ROF records + std::vector* mDigits = nullptr; //! output digits + std::vector* mROFRecords = nullptr; //! output ROF records o2::dataformats::MCTruthContainer* mMCLabels = nullptr; //! output labels const o2::itsmft::NoiseMap* mDeadChanMap = nullptr; const o2::itsmft::NoiseMap* mNoiseMap = nullptr; }; -} // namespace o2::trk +} // namespace o2::trkft3 + +extern template class o2::trkft3::Digitizer; +extern template class o2::trkft3::Digitizer; + +#endif diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/ChipDigitsContainer.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/ChipDigitsContainer.cxx new file mode 100644 index 0000000000000..8917062923537 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/ChipDigitsContainer.cxx @@ -0,0 +1,17 @@ +// 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 "TRKFT3Simulation/ChipDigitsContainer.h" + +using namespace o2::trkft3; + +ChipDigitsContainer::ChipDigitsContainer(UShort_t idx) + : o2::itsmft::ChipDigitsContainer(idx) {} diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/ChipSimResponse.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/ChipSimResponse.cxx similarity index 90% rename from Detectors/Upgrades/ALICE3/TRK/simulation/src/ChipSimResponse.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/ChipSimResponse.cxx index 70c4f131b9724..e8a11fb1b15d0 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/ChipSimResponse.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/ChipSimResponse.cxx @@ -9,11 +9,11 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "TRKSimulation/ChipSimResponse.h" +#include "TRKFT3Simulation/ChipSimResponse.h" #include #include -using namespace o2::trk; +using namespace o2::trkft3; void ChipSimResponse::initData(int tableNumber, std::string dataPath, const bool quiet) { diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/DPLDigitizerParam.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/DPLDigitizerParam.cxx similarity index 70% rename from Detectors/Upgrades/ALICE3/TRK/simulation/src/DPLDigitizerParam.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/DPLDigitizerParam.cxx index a13f2e58bd3a4..8d7f4d4b7c767 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/DPLDigitizerParam.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/DPLDigitizerParam.cxx @@ -9,15 +9,15 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "TRKSimulation/DPLDigitizerParam.h" +#include "TRKFT3Simulation/DPLDigitizerParam.h" namespace o2 { -namespace trk +namespace trkft3 { // this makes sure that the constructor of the parameters is statically called // so that these params are part of the parameter database -static auto& sDigitizerParamITS = o2::trk::DPLDigitizerParam::Instance(); -static auto& sDigitizerParamMFT = o2::trk::DPLDigitizerParam::Instance(); -} // namespace trk +static auto& sDigitizerParamITS = o2::trkft3::DPLDigitizerParam::Instance(); +static auto& sDigitizerParamMFT = o2::trkft3::DPLDigitizerParam::Instance(); +} // namespace trkft3 } // namespace o2 diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/DigiParams.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/DigiParams.cxx similarity index 72% rename from Detectors/Upgrades/ALICE3/TRK/simulation/src/DigiParams.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/DigiParams.cxx index 3558a6a87ce71..fd2acbe45411d 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/DigiParams.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/DigiParams.cxx @@ -14,18 +14,20 @@ #include #include "Framework/Logger.h" -#include "TRKSimulation/DigiParams.h" -#include "TRKSimulation/ChipSimResponse.h" +#include "TRKFT3Simulation/DigiParams.h" +#include "TRKFT3Simulation/ChipSimResponse.h" -using namespace o2::trk; +using namespace o2::trkft3; -DigiParams::DigiParams() +template +DigiParams::DigiParams() { // make sure the defaults are consistent setNSimSteps(mNSimSteps); } -void DigiParams::setROFrameLength(float lNS, int layer) +template +void DigiParams::setROFrameLength(float lNS, int layer) { // set ROFrame length in nanosecongs mROFrameLayerLength[layer] = lNS; @@ -33,14 +35,16 @@ void DigiParams::setROFrameLength(float lNS, int layer) mROFrameLayerLengthInv[layer] = 1. / mROFrameLayerLength[layer]; } -void DigiParams::setNSimSteps(int v) +template +void DigiParams::setNSimSteps(int v) { // set number of sampling steps in silicon mNSimSteps = v > 0 ? v : 1; mNSimStepsInv = 1.f / mNSimSteps; } -void DigiParams::setChargeThreshold(int v, float frac2Account) +template +void DigiParams::setChargeThreshold(int v, float frac2Account) { // set charge threshold for digits creation and its fraction to account // contribution from single hit @@ -55,10 +59,11 @@ void DigiParams::setChargeThreshold(int v, float frac2Account) } //______________________________________________ -void DigiParams::print() const +template +void DigiParams::print() const { // print settings - printf("TRK digitization params:\n"); + printf("%s digitization params:\n", o2::detectors::DetID::getName(DetIDV)); printf("Threshold (N electrons) : %d\n", mChargeThreshold); printf("Min N electrons to account : %d\n", mMinChargeToAccount); printf("Number of charge sharing steps : %d\n", mNSimSteps); @@ -68,7 +73,8 @@ void DigiParams::print() const mSignalShape.print(); } -void DigiParams::setResponse(const o2::itsmft::AlpideSimResponse* resp) +template +void DigiParams::setResponse(const o2::itsmft::AlpideSimResponse* resp) { LOG(debug) << "Response function data path: " << resp->getDataPath(); LOG(debug) << "Response function info: "; @@ -76,5 +82,8 @@ void DigiParams::setResponse(const o2::itsmft::AlpideSimResponse* resp) if (!resp) { LOGP(fatal, "cannot set response function from null"); } - mResponse = std::make_unique(resp); + mResponse = std::make_unique(resp); } + +template class o2::trkft3::DigiParams; +template class o2::trkft3::DigiParams; diff --git a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Digitizer.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/Digitizer.cxx similarity index 93% rename from Detectors/Upgrades/ALICE3/TRK/simulation/src/Digitizer.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/Digitizer.cxx index 79642d6ec7b86..5e8faca2830fe 100644 --- a/Detectors/Upgrades/ALICE3/TRK/simulation/src/Digitizer.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/Digitizer.cxx @@ -11,11 +11,10 @@ /// \file Digitizer.cxx -#include "DataFormatsITSMFT/Digit.h" +#include "DataFormatsTRKFT3/Digit.h" #include "TRKBase/SegmentationChip.h" -#include "TRKSimulation/DPLDigitizerParam.h" -#include "TRKSimulation/TRKLayer.h" -#include "TRKSimulation/Digitizer.h" +#include "TRKBase/Specs.h" +#include "TRKFT3Simulation/Digitizer.h" #include "DetectorsRaw/HBFUtils.h" #include @@ -26,15 +25,16 @@ #include #include // for LOG -using o2::itsmft::Digit; -using o2::trk::Hit; +using o2::trkft3::Digit; +using o2::trkft3::Hit; using Segmentation = o2::trk::SegmentationChip; -using namespace o2::trk; +using namespace o2::trkft3; using namespace o2::itsmft; // using namespace o2::base; //_______________________________________________________________________ -void Digitizer::init() +template +void Digitizer::init() { LOG(info) << "Initializing digitizer"; mNumberOfChips = mGeometry->getNumberOfChips(); @@ -88,10 +88,7 @@ void Digitizer::init() mSimRespMLOTShift = mChipSimRespMLOT->getDepthMax() - thicknessMLOT / 2.f; // the shift should be done considering the rescaling done to adapt to the wrong silicon thickness. TODO: remove the scaling factor for the depth when the silicon thickness match the simulated response - // importing the parameters from DPLDigitizerParam.h - auto& dOptTRK = DPLDigitizerParam::Instance(); - - LOGP(info, "TRK Digitizer is initialised."); + LOGP(info, "{} Digitizer is initialised.", o2::detectors::DetID::getName(DetID)); mParams.print(); LOGP(info, "VD shift = {} ; ML/OT shift = {} = {} - {}", mSimRespVDShift, mSimRespMLOTShift, mChipSimRespMLOT->getDepthMax(), thicknessMLOT / 2.f); LOGP(info, "VD pixel scale on x = {} ; z = {}", mSimRespVDScaleX, mSimRespVDScaleZ); @@ -101,7 +98,8 @@ void Digitizer::init() mIRFirstSampledTF = o2::raw::HBFUtils::Instance().getFirstSampledTFIR(); } -const o2::trk::ChipSimResponse* Digitizer::getChipResponse(int chipID) +template +const o2::trkft3::ChipSimResponse* Digitizer::getChipResponse(int chipID) { if (mGeometry->getSubDetID(chipID) == 0) { /// VD return mChipSimRespVD; @@ -114,7 +112,8 @@ const o2::trk::ChipSimResponse* Digitizer::getChipResponse(int chipID) }; //_______________________________________________________________________ -void Digitizer::process(const std::vector* hits, int evID, int srcID, int layer) +template +void Digitizer::process(const std::vector* hits, int evID, int srcID, int layer) { // digitize single event, the time must have been set beforehand @@ -144,14 +143,15 @@ void Digitizer::process(const std::vector* hits, int evID, int srcID, int l if (layer < 0) { return true; } - return mGeometry->getLayerTRK((*hits)[idx].GetDetectorID()) == layer; + return getROFLayer((*hits)[idx].GetDetectorID()) == layer; })) { processHit((*hits)[i], mROFrameMax, evID, srcID, layer); } } //_______________________________________________________________________ -void Digitizer::setEventTime(const o2::InteractionTimeRecord& irt, int layer) +template +void Digitizer::setEventTime(const o2::InteractionTimeRecord& irt, int layer) { LOG(info) << "Setting event time to " << irt.getTimeNS() << " ns after orbit 0 bc 0"; // assign event time in ns @@ -187,7 +187,8 @@ void Digitizer::setEventTime(const o2::InteractionTimeRecord& irt, int layer) } //_______________________________________________________________________ -void Digitizer::fillOutputContainer(uint32_t frameLast, int layer) +template +void Digitizer::fillOutputContainer(uint32_t frameLast, int layer) { // // fill output with digits from min.cached up to requested frame, generating the noise beforehand if (frameLast > mROFrameMax) { @@ -198,7 +199,7 @@ void Digitizer::fillOutputContainer(uint32_t frameLast, int layer) LOG(info) << "Filling " << mGeometry->getName() << " digits output for RO frames " << mROFrameMin << ":" << frameLast; - o2::itsmft::ROFRecord rcROF; /// using temporarly itsmft::ROFRecord + o2::trkft3::ROFRecord rcROF; /// using temporarly trkft3::ROFRecord // we have to write chips in RO increasing order, therefore have to loop over the frames here for (; mROFrameMin <= frameLast; mROFrameMin++) { @@ -207,7 +208,7 @@ void Digitizer::fillOutputContainer(uint32_t frameLast, int layer) auto& extra = *(mExtraBuff.front().get()); for (auto& chip : mChips) { - if (chip.isDisabled() || (layer >= 0 && mGeometry->getLayerTRK(chip.getChipIndex()) != layer)) { + if (chip.isDisabled() || (layer >= 0 && getROFLayer(chip.getChipIndex()) != layer)) { continue; } chip.addNoise(mROFrameMin, mROFrameMin, &mParams, mGeometry->getSubDetID(chip.getChipIndex()), mGeometry->getLayer(chip.getChipIndex())); /// TODO: add noise @@ -251,13 +252,14 @@ void Digitizer::fillOutputContainer(uint32_t frameLast, int layer) } //_______________________________________________________________________ -void Digitizer::processHit(const o2::trk::Hit& hit, uint32_t& maxFr, int evID, int srcID, int rofLayer) +template +void Digitizer::processHit(const o2::trkft3::Hit& hit, uint32_t& maxFr, int evID, int srcID, int rofLayer) { int chipID = hit.GetDetectorID(); //// the chip ID at the moment is not referred to the chip but to a wider detector element (e.g. quarter of layer or disk in VD, stave in ML, half stave in OT) int subDetID = mGeometry->getSubDetID(chipID); int layer = mGeometry->getLayer(chipID); // local layer nr for response - int disk = mGeometry->getDisk(chipID); + int disk = getDisk(chipID); if (disk != -1) { LOG(debug) << "Skipping VD disk " << disk; @@ -401,7 +403,7 @@ void Digitizer::processHit(const o2::trk::Hit& hit, uint32_t& maxFr, int evID, i int rowPrev = -1, colPrev = -1, row, col; float cRowPix = 0.f, cColPix = 0.f; // local coordinate of the current pixel center - const o2::trk::ChipSimResponse* resp = getChipResponse(chipID); + const o2::trkft3::ChipSimResponse* resp = getChipResponse(chipID); // std::cout << "Printing chip response:" << std::endl; // resp->print(); @@ -497,8 +499,9 @@ void Digitizer::processHit(const o2::trk::Hit& hit, uint32_t& maxFr, int evID, i } //________________________________________________________________________________ -void Digitizer::registerDigits(o2::trk::ChipDigitsContainer& chip, uint32_t roFrame, float tInROF, int nROF, - uint16_t row, uint16_t col, int nEle, o2::MCCompLabel& lbl, int layer) +template +void Digitizer::registerDigits(o2::trkft3::ChipDigitsContainer& chip, uint32_t roFrame, float tInROF, int nROF, + uint16_t row, uint16_t col, int nEle, o2::MCCompLabel& lbl, int layer) { // Register digits for given pixel, accounting for the possible signal contribution to // multiple ROFrame. The signal starts at time tInROF wrt the start of provided roFrame @@ -551,3 +554,6 @@ void Digitizer::registerDigits(o2::trk::ChipDigitsContainer& chip, uint32_t roFr } } } + +template class o2::trkft3::Digitizer; +template class o2::trkft3::Digitizer; diff --git a/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/TRKFT3SimulationLinkDef.h b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/TRKFT3SimulationLinkDef.h new file mode 100644 index 0000000000000..e11378f471ec3 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/simulation/src/TRKFT3SimulationLinkDef.h @@ -0,0 +1,27 @@ +// Copyright 2019-2026 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. + +#ifdef __CLING__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class o2::trkft3::ChipDigitsContainer + ; +#pragma link C++ class o2::trkft3::ChipSimResponse + ; +#pragma link C++ class o2::trkft3::Digitizer < o2::detectors::DetID::TRK> + ; +#pragma link C++ class o2::trkft3::Digitizer < o2::detectors::DetID::FT3> + ; +#pragma link C++ class o2::trkft3::DPLDigitizerParam < o2::detectors::DetID::TRK> + ; +#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::trkft3::DPLDigitizerParam < o2::detectors::DetID::TRK>> + ; +#pragma link C++ class o2::trkft3::DPLDigitizerParam < o2::detectors::DetID::FT3> + ; +#pragma link C++ class o2::conf::ConfigurableParamHelper < o2::trkft3::DPLDigitizerParam < o2::detectors::DetID::FT3>> + ; + +#endif diff --git a/Detectors/Upgrades/ALICE3/TRK/workflow/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/CMakeLists.txt similarity index 96% rename from Detectors/Upgrades/ALICE3/TRK/workflow/CMakeLists.txt rename to Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/CMakeLists.txt index e3309d78f47ea..f437b53715149 100644 --- a/Detectors/Upgrades/ALICE3/TRK/workflow/CMakeLists.txt +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/CMakeLists.txt @@ -20,7 +20,7 @@ o2_add_library(TRKWorkflow O2::GPUWorkflow O2::SimConfig O2::DataFormatsITSMFT - O2::DataFormatsTRK + O2::DataFormatsTRKFT3 O2::SimulationDataFormat O2::DPLUtils O2::TRKBase diff --git a/Detectors/Upgrades/ALICE3/TRK/workflow/README.md b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/README.md similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/workflow/README.md rename to Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/README.md diff --git a/Detectors/Upgrades/ALICE3/TRK/workflow/include/TRKWorkflow/ClusterWriterSpec.h b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/include/TRKWorkflow/ClusterWriterSpec.h similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/workflow/include/TRKWorkflow/ClusterWriterSpec.h rename to Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/include/TRKWorkflow/ClusterWriterSpec.h diff --git a/Detectors/Upgrades/ALICE3/TRK/workflow/include/TRKWorkflow/ClustererSpec.h b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/include/TRKWorkflow/ClustererSpec.h similarity index 97% rename from Detectors/Upgrades/ALICE3/TRK/workflow/include/TRKWorkflow/ClustererSpec.h rename to Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/include/TRKWorkflow/ClustererSpec.h index 9d072e85d574a..0166aa14462a8 100644 --- a/Detectors/Upgrades/ALICE3/TRK/workflow/include/TRKWorkflow/ClustererSpec.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/include/TRKWorkflow/ClustererSpec.h @@ -34,7 +34,7 @@ class ClustererDPL : public o2::framework::Task static constexpr int mLayers = o2::trk::AlmiraParam::kNLayers; bool mUseMC = true; int mNThreads = 1; - o2::trk::Clusterer mClusterer; + o2::trk::TRKClusterer mClusterer; #ifdef O2_WITH_ACTS bool mUseACTS = false; o2::trk::ClustererACTS mClustererACTS; diff --git a/Detectors/Upgrades/ALICE3/TRK/workflow/include/TRKWorkflow/DigitReaderSpec.h b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/include/TRKWorkflow/DigitReaderSpec.h similarity index 91% rename from Detectors/Upgrades/ALICE3/TRK/workflow/include/TRKWorkflow/DigitReaderSpec.h rename to Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/include/TRKWorkflow/DigitReaderSpec.h index 92b64e0815cfb..de04358b227eb 100644 --- a/Detectors/Upgrades/ALICE3/TRK/workflow/include/TRKWorkflow/DigitReaderSpec.h +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/include/TRKWorkflow/DigitReaderSpec.h @@ -16,14 +16,13 @@ #include "TFile.h" #include "TTree.h" -#include "DataFormatsITSMFT/Digit.h" +#include "DataFormatsTRKFT3/Digit.h" +#include "DataFormatsTRKFT3/ROFRecord.h" #include "DataFormatsITSMFT/GBTCalibData.h" -#include "DataFormatsITSMFT/ROFRecord.h" #include "SimulationDataFormat/IOMCTruthContainerView.h" #include "Framework/DataProcessorSpec.h" #include "Framework/Task.h" #include "Headers/DataHeader.h" -#include "DataFormatsITSMFT/ROFRecord.h" #include "DetectorsCommonDataFormats/DetID.h" #include "TRKBase/AlmiraParam.h" @@ -51,9 +50,9 @@ class DigitReader : public Task static constexpr int mLayers = o2::trk::AlmiraParam::kNLayers; - std::vector*> mDigits{nullptr}; + std::vector*> mDigits{nullptr}; std::vector mCalib, *mCalibPtr = &mCalib; - std::vector*> mDigROFRec{nullptr}; + std::vector*> mDigROFRec{nullptr}; std::vector mPLabels{nullptr}; o2::header::DataOrigin mOrigin = o2::header::gDataOriginInvalid; diff --git a/Detectors/Upgrades/ALICE3/TRK/workflow/include/TRKWorkflow/DigitWriterSpec.h b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/include/TRKWorkflow/DigitWriterSpec.h similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/workflow/include/TRKWorkflow/DigitWriterSpec.h rename to Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/include/TRKWorkflow/DigitWriterSpec.h diff --git a/Detectors/Upgrades/ALICE3/TRK/workflow/include/TRKWorkflow/RecoWorkflow.h b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/include/TRKWorkflow/RecoWorkflow.h similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/workflow/include/TRKWorkflow/RecoWorkflow.h rename to Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/include/TRKWorkflow/RecoWorkflow.h diff --git a/Detectors/Upgrades/ALICE3/TRK/workflow/src/ClusterWriterSpec.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/ClusterWriterSpec.cxx similarity index 95% rename from Detectors/Upgrades/ALICE3/TRK/workflow/src/ClusterWriterSpec.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/ClusterWriterSpec.cxx index 863915bac0572..7f1adbafc7435 100644 --- a/Detectors/Upgrades/ALICE3/TRK/workflow/src/ClusterWriterSpec.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/ClusterWriterSpec.cxx @@ -22,8 +22,8 @@ #include "Framework/DataRef.h" #include "TRKBase/AlmiraParam.h" #include "DPLUtils/MakeRootTreeWriterSpec.h" -#include "DataFormatsTRK/Cluster.h" -#include "DataFormatsTRK/ROFRecord.h" +#include "DataFormatsTRKFT3/Cluster.h" +#include "DataFormatsTRKFT3/ROFRecord.h" #include "SimulationDataFormat/MCCompLabel.h" #include "SimulationDataFormat/MCTruthContainer.h" @@ -34,11 +34,10 @@ namespace o2::trk template using BranchDefinition = MakeRootTreeWriterSpec::BranchDefinition; -using ClustersType = std::vector; +using ClustersType = std::vector; using PatternsType = std::vector; -using ROFrameType = std::vector; +using ROFrameType = std::vector; using LabelsType = o2::dataformats::MCTruthContainer; -using ROFRecLblType = std::vector; DataProcessorSpec getClusterWriterSpec(bool useMC) { diff --git a/Detectors/Upgrades/ALICE3/TRK/workflow/src/ClustererSpec.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/ClustererSpec.cxx similarity index 94% rename from Detectors/Upgrades/ALICE3/TRK/workflow/src/ClustererSpec.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/ClustererSpec.cxx index f91262e021a55..f299c581956a0 100644 --- a/Detectors/Upgrades/ALICE3/TRK/workflow/src/ClustererSpec.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/ClustererSpec.cxx @@ -11,8 +11,8 @@ #include "TRKWorkflow/ClustererSpec.h" #include "DetectorsBase/GeometryManager.h" -#include "DataFormatsTRK/Cluster.h" -#include "DataFormatsTRK/ROFRecord.h" +#include "DataFormatsTRKFT3/Cluster.h" +#include "DataFormatsTRKFT3/ROFRecord.h" #include "Framework/ConfigParamRegistry.h" #include "Framework/Logger.h" #include "SimulationDataFormat/ConstMCTruthContainer.h" @@ -36,8 +36,8 @@ void ClustererDPL::run(o2::framework::ProcessingContext& pc) uint64_t totalClusters = 0; for (int iLayer = 0; iLayer < mLayers; ++iLayer) { - auto digits = pc.inputs().get>(std::format("digits_{}", iLayer)); - auto rofs = pc.inputs().get>(std::format("ROframes_{}", iLayer)); + auto digits = pc.inputs().get>(std::format("digits_{}", iLayer)); + auto rofs = pc.inputs().get>(std::format("ROframes_{}", iLayer)); gsl::span labelbuffer; if (mUseMC) { @@ -45,9 +45,9 @@ void ClustererDPL::run(o2::framework::ProcessingContext& pc) } o2::dataformats::ConstMCTruthContainerView labels(labelbuffer); - std::vector clusters; + std::vector clusters; std::vector patterns; - std::vector clusterROFs; + std::vector clusterROFs; std::unique_ptr> clusterLabels; if (mUseMC) { clusterLabels = std::make_unique>(); diff --git a/Detectors/Upgrades/ALICE3/TRK/workflow/src/DigitReaderSpec.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/DigitReaderSpec.cxx similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/workflow/src/DigitReaderSpec.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/DigitReaderSpec.cxx diff --git a/Detectors/Upgrades/ALICE3/TRK/workflow/src/DigitWriterSpec.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/DigitWriterSpec.cxx similarity index 94% rename from Detectors/Upgrades/ALICE3/TRK/workflow/src/DigitWriterSpec.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/DigitWriterSpec.cxx index 591b084aee3ba..0e121c4786d50 100644 --- a/Detectors/Upgrades/ALICE3/TRK/workflow/src/DigitWriterSpec.cxx +++ b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/DigitWriterSpec.cxx @@ -16,11 +16,11 @@ #include "Framework/DataRef.h" #include "TRKBase/AlmiraParam.h" #include "DPLUtils/MakeRootTreeWriterSpec.h" -#include "DataFormatsITSMFT/Digit.h" +#include "DataFormatsTRKFT3/Digit.h" #include "DataFormatsITSMFT/GBTCalibData.h" #include "Headers/DataHeader.h" #include "DetectorsCommonDataFormats/DetID.h" -#include "DataFormatsITSMFT/ROFRecord.h" +#include "DataFormatsTRKFT3/ROFRecord.h" #include "SimulationDataFormat/ConstMCTruthContainer.h" #include "SimulationDataFormat/IOMCTruthContainerView.h" #include "SimulationDataFormat/MCCompLabel.h" @@ -49,12 +49,12 @@ DataProcessorSpec getTRKDigitWriterSpec(bool mctruth, bool dec, bool calib) std::string detStrL = dec ? "o2_trk" : "trk"; auto digitSizes = std::make_shared>(mLayers, 0); - auto digitSizeGetter = [digitSizes](std::vector const& inDigits, DataRef const& ref) { + auto digitSizeGetter = [digitSizes](std::vector const& inDigits, DataRef const& ref) { auto const* dh = DataRefUtils::getHeader(ref); (*digitSizes)[dh->subSpecification] = inDigits.size(); }; auto rofSizes = std::make_shared>(mLayers, 0); - auto rofSizeGetter = [rofSizes](std::vector const& inROFs, DataRef const& ref) { + auto rofSizeGetter = [rofSizes](std::vector const& inROFs, DataRef const& ref) { auto const* dh = DataRefUtils::getHeader(ref); (*rofSizes)[dh->subSpecification] = inROFs.size(); }; @@ -114,13 +114,13 @@ DataProcessorSpec getTRKDigitWriterSpec(bool mctruth, bool dec, bool calib) (detStrL + "digits.root").c_str(), MakeRootTreeWriterSpec::TreeAttributes{.name = "o2sim", .title = detStr + " Digits tree"}, MakeRootTreeWriterSpec::CustomClose(finishWriting), - BranchDefinition>{vecInpSpecDig, + BranchDefinition>{vecInpSpecDig, detStr + "Digit", "digit-branch", mLayers, digitSizeGetter, getIndex, getName}, - BranchDefinition>{vecInpSpecROF, + BranchDefinition>{vecInpSpecROF, detStr + "DigitROF", "digit-rof-branch", mLayers, rofSizeGetter, diff --git a/Detectors/Upgrades/ALICE3/TRK/workflow/src/RecoWorkflow.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/RecoWorkflow.cxx similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/workflow/src/RecoWorkflow.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/RecoWorkflow.cxx diff --git a/Detectors/Upgrades/ALICE3/TRK/workflow/src/trk-reco-workflow.cxx b/Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/trk-reco-workflow.cxx similarity index 100% rename from Detectors/Upgrades/ALICE3/TRK/workflow/src/trk-reco-workflow.cxx rename to Detectors/Upgrades/ALICE3/TRKFT3/common/workflow/src/trk-reco-workflow.cxx diff --git a/Steer/DigitizerWorkflow/src/SimpleDigitizerWorkflow.cxx b/Steer/DigitizerWorkflow/src/SimpleDigitizerWorkflow.cxx index bcc9a4ecddc37..9679fdf9248f5 100644 --- a/Steer/DigitizerWorkflow/src/SimpleDigitizerWorkflow.cxx +++ b/Steer/DigitizerWorkflow/src/SimpleDigitizerWorkflow.cxx @@ -665,11 +665,17 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) if (isEnabled(o2::detectors::DetID::TRK)) { detList.emplace_back(o2::detectors::DetID::TRK); // connect the ALICE 3 TRK digitization - specs.emplace_back(o2::trk::getTRKDigitizerSpec(fanoutsize++, mctruth)); + specs.emplace_back(o2::trkft3::getTRKDigitizerSpec(fanoutsize++, mctruth)); // connect the ALICE 3 TRK digit writer specs.emplace_back(o2::trk::getTRKDigitWriterSpec(mctruth)); } + // the ALICE 3 FT3 part + if (isEnabled(o2::detectors::DetID::FT3)) { + detList.emplace_back(o2::detectors::DetID::FT3); + specs.emplace_back(o2::trkft3::getFT3DigitizerSpec(fanoutsize++, mctruth)); + } + // the ALICE 3 IOTOF part if (isEnabled(o2::detectors::DetID::TF3)) { detList.emplace_back(o2::detectors::DetID::TF3); diff --git a/Steer/DigitizerWorkflow/src/TRKDigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/TRKDigitizerSpec.cxx index 32018921c7af7..4a5bb1fc1c6d5 100644 --- a/Steer/DigitizerWorkflow/src/TRKDigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/TRKDigitizerSpec.cxx @@ -18,16 +18,19 @@ #include "Framework/Lifetime.h" #include "Framework/Task.h" #include "Steer/HitProcessingManager.h" -#include "DataFormatsITSMFT/Digit.h" +#include "DataFormatsTRKFT3/Digit.h" +#include "DataFormatsTRKFT3/Hit.h" #include "SimulationDataFormat/ConstMCTruthContainer.h" #include "DetectorsBase/BaseDPLDigitizer.h" #include "DetectorsRaw/HBFUtils.h" #include "DetectorsCommonDataFormats/DetID.h" #include "DetectorsCommonDataFormats/SimTraits.h" #include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsITSMFT/ROFRecord.h" -#include "TRKSimulation/Digitizer.h" -#include "TRKSimulation/DPLDigitizerParam.h" +#include "DataFormatsTRKFT3/ROFRecord.h" +#include "TRKFT3Simulation/Digitizer.h" +#include "TRKFT3Simulation/DPLDigitizerParam.h" +#include "FT3Base/FT3BaseParam.h" +#include "FT3Base/GeometryTGeo.h" #include "TRKBase/AlmiraParam.h" #include "TRKBase/GeometryTGeo.h" #include "TRKBase/Specs.h" @@ -45,14 +48,13 @@ using SubSpecificationType = o2::framework::DataAllocator::SubSpecificationType; namespace { -std::vector makeOutChannels(o2::header::DataOrigin detOrig, bool mctruth) +std::vector makeOutChannels(o2::header::DataOrigin detOrig, int nLayers, bool mctruth) { std::vector outputs; - for (uint32_t iLayer = 0; iLayer < o2::trk::AlmiraParam::getNLayers(); ++iLayer) { + for (uint32_t iLayer = 0; iLayer < static_cast(nLayers); ++iLayer) { outputs.emplace_back(detOrig, "DIGITS", iLayer, Lifetime::Timeframe); outputs.emplace_back(detOrig, "DIGITSROF", iLayer, Lifetime::Timeframe); if (mctruth) { - outputs.emplace_back(detOrig, "DIGITSMC2ROF", iLayer, Lifetime::Timeframe); outputs.emplace_back(detOrig, "DIGITSMCTR", iLayer, Lifetime::Timeframe); } } @@ -61,15 +63,30 @@ std::vector makeOutChannels(o2::header::DataOrigin detOrig, bool mct } } // namespace -namespace o2::trk +namespace o2::trkft3 { using namespace o2::base; -class TRKDPLDigitizerTask : BaseDPLDigitizer + +template +int getNLayers() +{ + if constexpr (N == o2::detectors::DetID::TRK) { + return o2::trk::AlmiraParam::getNLayers(); + } else { + return 2 * o2::ft3::FT3BaseParam::Instance().nLayers; + } +} + +template +class TRKFT3DPLDigitizerTask : BaseDPLDigitizer { public: + static_assert(N == o2::detectors::DetID::TRK || N == o2::detectors::DetID::FT3, "only TRK and FT3 digitizers are supported"); + static constexpr o2::detectors::DetID ID{N == o2::detectors::DetID::TRK ? o2::detectors::DetID::TRK : o2::detectors::DetID::FT3}; + static constexpr o2::header::DataOrigin Origin{N == o2::detectors::DetID::TRK ? o2::header::gDataOriginTRK : o2::header::gDataOriginFT3}; using BaseDPLDigitizer::init; - TRKDPLDigitizerTask(bool mctruth = true) : BaseDPLDigitizer(InitServices::FIELD | InitServices::GEOM), mWithMCTruth(mctruth) {} + TRKFT3DPLDigitizerTask(bool mctruth = true) : BaseDPLDigitizer(InitServices::FIELD | InitServices::GEOM), mWithMCTruth(mctruth) {} void initDigitizerTask(framework::InitContext& ic) override { @@ -88,7 +105,7 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer // read collision context from input auto context = pc.inputs().get("collisioncontext"); - context->initSimChains(mID, mSimChains); + context->initSimChains(ID, mSimChains); const bool withQED = context->isQEDProvided() && !mDisableQED; auto& timesview = context->getEventRecords(withQED); LOG(info) << "GOT " << timesview.size() << " COLLISION TIMES"; @@ -100,7 +117,7 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer } TStopwatch timer; timer.Start(); - LOG(info) << " CALLING TRK DIGITIZATION "; + LOG(info) << " CALLING " << ID.getName() << " DIGITIZATION "; auto& eventParts = context->getEventParts(withQED); uint64_t nDigits{0}; @@ -111,7 +128,6 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer if (mWithMCTruth) { mLabels[iLayer].clear(); mLabelsAccum[iLayer].clear(); - mMC2ROFRecordsAccum[iLayer].clear(); } mDigitizer.setDigits(&mDigits[iLayer]); @@ -120,7 +136,7 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer mDigitizer.resetROFrameBounds(); // digits are directly put into DPL owned resource - auto& digitsAccum = pc.outputs().make>(Output{mOrigin, "DIGITS", iLayer}); + auto& digitsAccum = pc.outputs().make>(Output{Origin, "DIGITS", iLayer}); const int roFrameLengthInBC = mDigitizer.getParams().getROFrameLengthInBC(iLayer); const int nROFsPerOrbit = o2::constants::lhc::LHCMaxBunches / roFrameLengthInBC; @@ -162,7 +178,7 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer mDigitizer.resetEventROFrames(); for (auto& part : eventParts[collID]) { mHits.clear(); - context->retrieveHits(mSimChains, o2::detectors::SimTraits::DETECTORBRANCHNAMES[mID][0].c_str(), part.sourceID, part.entryID, &mHits); + context->retrieveHits(mSimChains, o2::detectors::SimTraits::DETECTORBRANCHNAMES[ID][0].c_str(), part.sourceID, part.entryID, &mHits); if (!mHits.empty()) { LOG(debug) << "For collision " << collID << " eventID " << part.entryID @@ -170,16 +186,13 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer mDigitizer.process(&mHits, part.entryID, part.sourceID, iLayer); } } - if (mWithMCTruth) { - mMC2ROFRecordsAccum[iLayer].emplace_back(collID, -1, mDigitizer.getEventROFrameMin(), mDigitizer.getEventROFrameMax()); - } accumulate(); } mDigitizer.fillOutputContainer(0xffffffff, iLayer); accumulate(); nDigits += digitsAccum.size(); - std::vector expDigitRofVec(nROFsTF); + std::vector expDigitRofVec(nROFsTF); for (int iROF = 0; iROF < nROFsTF; ++iROF) { auto& rof = expDigitRofVec[iROF]; const int orb = iROF * roFrameLengthInBC / o2::constants::lhc::LHCMaxBunches + mFirstOrbitTF; @@ -213,36 +226,16 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer prevFirst = rof.getFirstEntry(); } - pc.outputs().snapshot(Output{mOrigin, "DIGITSROF", iLayer}, expDigitRofVec); + pc.outputs().snapshot(Output{Origin, "DIGITSROF", iLayer}, expDigitRofVec); if (mWithMCTruth) { - std::vector clippedMC2ROFRecords; - clippedMC2ROFRecords.reserve(mMC2ROFRecordsAccum[iLayer].size()); - for (auto mc2rof : mMC2ROFRecordsAccum[iLayer]) { - if (mc2rof.minROF >= static_cast(nROFsTF) || mc2rof.minROF > mc2rof.maxROF) { - mc2rof.rofRecordID = -1; - mc2rof.minROF = 0; - mc2rof.maxROF = 0; - } else { - mc2rof.maxROF = std::min(mc2rof.maxROF, nROFsTF - 1); - if (mc2rof.minROF > mc2rof.maxROF) { - mc2rof.rofRecordID = -1; - mc2rof.minROF = 0; - mc2rof.maxROF = 0; - } else { - mc2rof.rofRecordID = mc2rof.minROF; - } - } - clippedMC2ROFRecords.push_back(mc2rof); - } - pc.outputs().snapshot(Output{mOrigin, "DIGITSMC2ROF", iLayer}, clippedMC2ROFRecords); - auto& sharedlabels = pc.outputs().make>(Output{mOrigin, "DIGITSMCTR", iLayer}); + auto& sharedlabels = pc.outputs().make>(Output{Origin, "DIGITSMCTR", iLayer}); mLabelsAccum[iLayer].flatten_to(sharedlabels); mLabels[iLayer].clear_andfreememory(); mLabelsAccum[iLayer].clear_andfreememory(); } } - LOG(info) << mID.getName() << ": Sending ROMode= " << mROMode << " to GRPUpdater"; - pc.outputs().snapshot(Output{mOrigin, "ROMode", 0}, mROMode); + LOG(info) << ID.getName() << ": Sending ROMode= " << mROMode << " to GRPUpdater"; + pc.outputs().snapshot(Output{Origin, "ROMode", 0}, mROMode); timer.Stop(); LOG(info) << "Digitization took " << timer.CpuTime() << "s"; @@ -270,32 +263,40 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer initOnce = true; auto& digipar = mDigitizer.getParams(); - // configure digitizer - o2::trk::GeometryTGeo* geom = o2::trk::GeometryTGeo::Instance(); - geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)); // make sure L2G matrices are loaded - geom->Print(); - mDigitizer.setGeometry(geom); - - const auto& dopt = o2::trk::DPLDigitizerParam::Instance(); - // pc.inputs().get("TRK_almiraparam"); + const auto& dopt = o2::trkft3::DPLDigitizerParam::Instance(); const auto& aopt = o2::trk::AlmiraParam::Instance(); - mLayers = constants::VD::petal::nLayers + geom->getNumberOfLayersMLOT() + geom->getNumberOfDisksMLOT(); + if constexpr (N == o2::detectors::DetID::TRK) { + auto* geom = o2::trk::GeometryTGeo::Instance(); + geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)); + geom->Print(); + mDigitizer.setGeometry(geom); + mLayers = o2::trk::AlmiraParam::getNLayers(); + } else { + auto* geom = o2::ft3::GeometryTGeo::Instance(); + geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)); + geom->Print(); + mDigitizer.setGeometry(geom); + mLayers = geom->getNumberOfLayers(); + } + if (mLayers > static_cast(o2::trkft3::DigiParams::getMaxLayers())) { + LOGP(fatal, "{} geometry has {} layers, but DigiParams supports at most {}", ID.getName(), mLayers, o2::trkft3::DigiParams::getMaxLayers()); + } mDigits.resize(mLayers); mROFRecords.resize(mLayers); mROFRecordsAccum.resize(mLayers); mLabels.resize(mLayers); mLabelsAccum.resize(mLayers); - mMC2ROFRecordsAccum.resize(mLayers); for (int iLayer = 0; iLayer < mLayers; ++iLayer) { - const auto roFrameLengthInBC = aopt.getROFLengthInBC(iLayer); + const int parLayer = std::min(iLayer, o2::trk::AlmiraParam::getNLayers() - 1); + const auto roFrameLengthInBC = aopt.getROFLengthInBC(parLayer); const auto frameNS = roFrameLengthInBC * o2::constants::lhc::LHCBunchSpacingNS; digipar.setROFrameLengthInBC(roFrameLengthInBC, iLayer); // ROF delay is treated as an additional bias from the digitizer point of view. - digipar.setROFrameBiasInBC(aopt.getROFBiasInBC(iLayer) + aopt.getROFDelayInBC(iLayer), iLayer); - digipar.setStrobeDelay(aopt.getStrobeDelay(iLayer), iLayer); - const auto strobeLengthCont = aopt.getStrobeLengthCont(iLayer); - digipar.setStrobeLength(strobeLengthCont > 0 ? strobeLengthCont : frameNS - aopt.getStrobeDelay(iLayer), iLayer); + digipar.setROFrameBiasInBC(aopt.getROFBiasInBC(parLayer) + aopt.getROFDelayInBC(parLayer), iLayer); + digipar.setStrobeDelay(aopt.getStrobeDelay(parLayer), iLayer); + const auto strobeLengthCont = aopt.getStrobeLengthCont(parLayer); + digipar.setStrobeLength(strobeLengthCont > 0 ? strobeLengthCont : frameNS - aopt.getStrobeDelay(parLayer), iLayer); digipar.setROFrameLength(frameNS, iLayer); } // parameters of signal time response: flat-top duration, max rise time and q @ which rise time is 0 @@ -306,12 +307,12 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer digipar.setNSimSteps(dopt.nSimSteps); mROMode = o2::parameters::GRPObject::CONTINUOUS; - LOG(info) << mID.getName() << " simulated in CONTINUOUS RO mode"; + LOG(info) << ID.getName() << " simulated in CONTINUOUS RO mode"; // if (oTRKParams::Instance().useDeadChannelMap) { // pc.inputs().get("TRK_dead"); // trigger final ccdb update // } - pc.inputs().get("TRK_aptsresp"); + pc.inputs().get((std::string(ID.getName()) + "_aptsresp").c_str()); // init digitizer mDigitizer.init(); @@ -321,8 +322,8 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) { - if (matcher == ConcreteDataMatcher(mOrigin, "ALMIRAPARAM", 0)) { - LOG(info) << mID.getName() << " Almira param updated"; + if (matcher == ConcreteDataMatcher(Origin, "ALMIRAPARAM", 0)) { + LOG(info) << ID.getName() << " Almira param updated"; const auto& par = o2::trk::AlmiraParam::Instance(); par.printKeyValues(); return; @@ -332,8 +333,8 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer // mDigitizer.setDeadChannelsMap((o2::itsmft::NoiseMap*)obj); // return; // } - if (matcher == ConcreteDataMatcher(mOrigin, "APTSRESP", 0)) { - LOG(info) << mID.getName() << " loaded APTSResponseData"; + if (matcher == ConcreteDataMatcher(Origin, "APTSRESP", 0)) { + LOG(info) << ID.getName() << " loaded APTSResponseData"; if (mLocalRespFile.empty()) { LOG(info) << "Using CCDB/APTS response file"; mDigitizer.getParams().setResponse((const o2::itsmft::AlpideSimResponse*)obj); @@ -352,18 +353,15 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer bool mDisableQED{false}; unsigned long mFirstOrbitTF = 0x0; std::string mLocalRespFile{""}; - const o2::detectors::DetID mID{o2::detectors::DetID::TRK}; - const o2::header::DataOrigin mOrigin{o2::header::gDataOriginTRK}; - o2::trk::Digitizer mDigitizer{}; + o2::trkft3::Digitizer mDigitizer{}; int mLayers{0}; - std::vector> mDigits{}; - std::vector> mROFRecords{}; - std::vector> mROFRecordsAccum{}; - std::vector mHits{}; - std::vector* mHitsP{&mHits}; + std::vector> mDigits{}; + std::vector> mROFRecords{}; + std::vector> mROFRecordsAccum{}; + std::vector mHits{}; + std::vector* mHitsP{&mHits}; std::vector> mLabels{}; std::vector> mLabelsAccum{}; - std::vector> mMC2ROFRecordsAccum{}; std::vector mSimChains{}; o2::parameters::GRPObject::ROMode mROMode = o2::parameters::GRPObject::PRESENT; // readout mode }; @@ -381,11 +379,27 @@ DataProcessorSpec getTRKDigitizerSpec(int channel, bool mctruth) inputs.emplace_back("TRK_aptsresp", "TRK", "APTSRESP", 0, Lifetime::Condition, ccdbParamSpec("IT3/Calib/APTSResponse")); return DataProcessorSpec{detStr + "Digitizer", - inputs, makeOutChannels(detOrig, mctruth), - AlgorithmSpec{adaptFromTask(mctruth)}, + inputs, makeOutChannels(detOrig, getNLayers(), mctruth), + AlgorithmSpec{adaptFromTask>(mctruth)}, + Options{ + {"disable-qed", o2::framework::VariantType::Bool, false, {"disable QED handling"}}, + {"local-response-file", o2::framework::VariantType::String, "", {"use response file saved locally at this path/filename"}}}}; +} + +DataProcessorSpec getFT3DigitizerSpec(int channel, bool mctruth) +{ + std::string detStr = o2::detectors::DetID::getName(o2::detectors::DetID::FT3); + auto detOrig = o2::header::gDataOriginFT3; + std::vector inputs; + inputs.emplace_back("collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast(channel), Lifetime::Timeframe); + inputs.emplace_back("FT3_aptsresp", "FT3", "APTSRESP", 0, Lifetime::Condition, ccdbParamSpec("IT3/Calib/APTSResponse")); + + return DataProcessorSpec{detStr + "Digitizer", + inputs, makeOutChannels(detOrig, getNLayers(), mctruth), + AlgorithmSpec{adaptFromTask>(mctruth)}, Options{ {"disable-qed", o2::framework::VariantType::Bool, false, {"disable QED handling"}}, {"local-response-file", o2::framework::VariantType::String, "", {"use response file saved locally at this path/filename"}}}}; } -} // namespace o2::trk +} // namespace o2::trkft3 diff --git a/Steer/DigitizerWorkflow/src/TRKDigitizerSpec.h b/Steer/DigitizerWorkflow/src/TRKDigitizerSpec.h index 5a1a59c3b9f5e..e28401fd14389 100644 --- a/Steer/DigitizerWorkflow/src/TRKDigitizerSpec.h +++ b/Steer/DigitizerWorkflow/src/TRKDigitizerSpec.h @@ -14,11 +14,12 @@ #include "Framework/DataProcessorSpec.h" -namespace o2::trk +namespace o2::trkft3 { o2::framework::DataProcessorSpec getTRKDigitizerSpec(int channel, bool mctruth = true); +o2::framework::DataProcessorSpec getFT3DigitizerSpec(int channel, bool mctruth = true); } -// namespace o2::trk +// namespace o2::trkft3 // end namespace o2 #endif