diff --git a/Common/SimConfig/src/SimConfig.cxx b/Common/SimConfig/src/SimConfig.cxx index a6f4192949ec1..757fc79642bef 100644 --- a/Common/SimConfig/src/SimConfig.cxx +++ b/Common/SimConfig/src/SimConfig.cxx @@ -60,7 +60,7 @@ bool SimConfig::resetFromParsedMap(boost::program_options::variables_map const& active.clear(); for (int d = DetID::First; d <= DetID::Last; ++d) { #ifdef ENABLE_UPGRADES - if (d != DetID::IT3 && d != DetID::TRK) { + if (d != DetID::IT3 && d != DetID::TRK && d != DetID::FT3) { active.emplace_back(DetID::getName(d)); } #else diff --git a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID.h b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID.h index fd963354f030d..4dbb3fb6ba8b9 100644 --- a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID.h +++ b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID.h @@ -71,7 +71,8 @@ class DetID #ifdef ENABLE_UPGRADES static constexpr ID IT3 = 16; static constexpr ID TRK = 17; - static constexpr ID Last = TRK; + static constexpr ID FT3 = 18; + static constexpr ID Last = FT3; #else static constexpr ID Last = ACO; ///< if extra detectors added, update this !!! #endif @@ -133,7 +134,7 @@ class DetID static constexpr const char* sDetNames[nDetectors + 1] = ///< defined detector names #ifdef ENABLE_UPGRADES - {"ITS", "TPC", "TRD", "TOF", "PHS", "CPV", "EMC", "HMP", "MFT", "MCH", "MID", "ZDC", "FT0", "FV0", "FDD", "ACO", "IT3", "TRK", nullptr}; + {"ITS", "TPC", "TRD", "TOF", "PHS", "CPV", "EMC", "HMP", "MFT", "MCH", "MID", "ZDC", "FT0", "FV0", "FDD", "ACO", "IT3", "TRK", "FT3", nullptr}; #else {"ITS", "TPC", "TRD", "TOF", "PHS", "CPV", "EMC", "HMP", "MFT", "MCH", "MID", "ZDC", "FT0", "FV0", "FDD", "ACO", nullptr}; #endif @@ -145,7 +146,7 @@ class DetID math_utils::bit2Mask(ACO) #ifdef ENABLE_UPGRADES , - math_utils::bit2Mask(IT3), math_utils::bit2Mask(TRK) + math_utils::bit2Mask(IT3), math_utils::bit2Mask(TRK), math_utils::bit2Mask(FT3) #endif }; @@ -156,7 +157,7 @@ class DetID o2h::gDataOriginMID, o2h::gDataOriginZDC, o2h::gDataOriginFT0, o2h::gDataOriginFV0, o2h::gDataOriginFDD, o2h::gDataOriginACO #ifdef ENABLE_UPGRADES , - o2h::gDataOriginIT3, o2h::gDataOriginTRK + o2h::gDataOriginIT3, o2h::gDataOriginTRK, o2h::gDataOriginFT3 #endif }; diff --git a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/SimTraits.h b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/SimTraits.h index 018e6c4a54054..9bf2b048337a9 100644 --- a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/SimTraits.h +++ b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/SimTraits.h @@ -35,8 +35,8 @@ class SimTraits // initialization fragile since depends on correct order. Can we do better? // clang-format off - static inline const std::array, DetID::nDetectors> DETECTORBRANCHNAMES = - { /*ITS*/ VS{ "ITSHit" }, + static inline const std::array, DetID::nDetectors> DETECTORBRANCHNAMES = + { /*ITS*/ VS{ "ITSHit" }, /*TPC*/ VS{ "TPCHitsShiftedSector0", "TPCHitsShiftedSector1", "TPCHitsShiftedSector2", @@ -90,7 +90,8 @@ class SimTraits #ifdef ENABLE_UPGRADES , /*IT3*/ VS{ "IT3Hit" }, - /*TRK*/ VS{ "TRKHit" } + /*TRK*/ VS{ "TRKHit" }, + /*FT3*/ VS{ "FT3Hit" } #endif }; // clang-format on @@ -227,11 +228,14 @@ template <> struct DetIDToHitTypes { using HitType = o2::itsmft::Hit; }; - template <> struct DetIDToHitTypes { using HitType = o2::itsmft::Hit; }; +template <> +struct DetIDToHitTypes { + using HitType = o2::itsmft::Hit; +}; #endif } // namespace detectors diff --git a/DataFormats/Detectors/Common/src/DetID.cxx b/DataFormats/Detectors/Common/src/DetID.cxx index 1706990322a36..1c4801fe2b7f4 100644 --- a/DataFormats/Detectors/Common/src/DetID.cxx +++ b/DataFormats/Detectors/Common/src/DetID.cxx @@ -31,6 +31,7 @@ constexpr DetID::ID DetID::ITS, DetID::TPC, DetID::TRD, DetID::TOF, DetID::PHS, #ifdef ENABLE_UPGRADES constexpr DetID::ID DetID::IT3; constexpr DetID::ID DetID::TRK; +constexpr DetID::ID DetID::FT3; #endif constexpr int DetID::nDetectors; diff --git a/DataFormats/Headers/include/Headers/DataHeader.h b/DataFormats/Headers/include/Headers/DataHeader.h index ea674174997b5..3baf42d526302 100644 --- a/DataFormats/Headers/include/Headers/DataHeader.h +++ b/DataFormats/Headers/include/Headers/DataHeader.h @@ -638,6 +638,8 @@ constexpr o2::header::DataOrigin gDataOriginZDC{"ZDC"}; #ifdef ENABLE_UPGRADES constexpr o2::header::DataOrigin gDataOriginIT3{"IT3"}; constexpr o2::header::DataOrigin gDataOriginTRK{"TRK"}; +constexpr o2::header::DataOrigin gDataOriginFT3{"FT3"}; + #endif //possible data types diff --git a/Detectors/Upgrades/ALICE3/CMakeLists.txt b/Detectors/Upgrades/ALICE3/CMakeLists.txt index 8de7049b05dee..4d561ecdaba59 100644 --- a/Detectors/Upgrades/ALICE3/CMakeLists.txt +++ b/Detectors/Upgrades/ALICE3/CMakeLists.txt @@ -10,4 +10,5 @@ add_subdirectory(Passive) add_subdirectory(TRK) -add_subdirectory(AOD) \ No newline at end of file +add_subdirectory(FT3) +add_subdirectory(AOD) diff --git a/Detectors/Upgrades/ALICE3/FT3/CMakeLists.txt b/Detectors/Upgrades/ALICE3/FT3/CMakeLists.txt new file mode 100644 index 0000000000000..532a914632a0c --- /dev/null +++ b/Detectors/Upgrades/ALICE3/FT3/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright CERN and copyright holders of ALICE O2. This software is distributed +# under the terms of the GNU General Public License v3 (GPL Version 3), copied +# verbatim in the file "COPYING". +# +# See http://alice-o2.web.cern.ch/license for full licensing information. +# +# 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(simulation) +add_subdirectory(base) diff --git a/Detectors/Upgrades/ALICE3/FT3/README.md b/Detectors/Upgrades/ALICE3/FT3/README.md new file mode 100644 index 0000000000000..1ed7e0cf1b041 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/FT3/README.md @@ -0,0 +1,10 @@ + + +# PostLS4EndCaps + +This is a top page for the PostLS4EndCaps detector documentation. + + diff --git a/Detectors/Upgrades/ALICE3/FT3/base/CMakeLists.txt b/Detectors/Upgrades/ALICE3/FT3/base/CMakeLists.txt new file mode 100644 index 0000000000000..34d0d064dd501 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/FT3/base/CMakeLists.txt @@ -0,0 +1,16 @@ +# Copyright CERN and copyright holders of ALICE O2. This software is distributed +# under the terms of the GNU General Public License v3 (GPL Version 3), copied +# verbatim in the file "COPYING". +# +# See http://alice-o2.web.cern.ch/license for full licensing information. +# +# 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 + PUBLIC_LINK_LIBRARIES O2::DetectorsBase O2::ITSMFTBase) + +o2_target_root_dictionary(FT3Base + HEADERS include/FT3Base/GeometryTGeo.h) diff --git a/Detectors/Upgrades/ALICE3/FT3/base/include/FT3Base/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/FT3/base/include/FT3Base/GeometryTGeo.h new file mode 100644 index 0000000000000..38ee598d6dadb --- /dev/null +++ b/Detectors/Upgrades/ALICE3/FT3/base/include/FT3Base/GeometryTGeo.h @@ -0,0 +1,119 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// 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 "ITSMFTBase/GeometryTGeo.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::itsmft::GeometryTGeo +{ + 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() override = default; + + GeometryTGeo(const GeometryTGeo& src) = delete; + GeometryTGeo& operator=(const GeometryTGeo& geom) = delete; + + // implement filling of the matrix cache + using o2::itsmft::GeometryTGeo::fillMatrixCache; + void fillMatrixCache(int mask) override; + + /// Exract FT3 parameters from TGeo + void Build(int loadTrans = 0) override; + + void Print(Option_t* opt = "") const; + static const char* getFT3VolPattern() { return sVolumeName.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* 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); + + protected: + static constexpr int MAXLAYERS = 15; ///< max number of active layers + + Int_t mNumberOfLayers; ///< number of layers + 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 + + private: + static std::unique_ptr sInstance; ///< singletone instance + + ClassDefOverride(GeometryTGeo, 1); // FT3 geometry based on TGeo +}; +} // namespace ft3 +} // namespace o2 + +#endif diff --git a/Detectors/Upgrades/ALICE3/FT3/base/src/FT3BaseLinkDef.h b/Detectors/Upgrades/ALICE3/FT3/base/src/FT3BaseLinkDef.h new file mode 100644 index 0000000000000..297fa1eab5eaa --- /dev/null +++ b/Detectors/Upgrades/ALICE3/FT3/base/src/FT3BaseLinkDef.h @@ -0,0 +1,19 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// 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::ft3::GeometryTGeo; + +#endif diff --git a/Detectors/Upgrades/ALICE3/FT3/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/FT3/base/src/GeometryTGeo.cxx new file mode 100644 index 0000000000000..86ced428738f5 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/FT3/base/src/GeometryTGeo.cxx @@ -0,0 +1,110 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// 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 "FairLogger.h" // 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 // for snprintf, NULL, printf +#include // for strstr, strlen + +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::sLayerName = "FT3Layer"; ///< Layer name +std::string GeometryTGeo::sChipName = "FT3Chip"; ///< Sensor name +std::string GeometryTGeo::sSensorName = "FT3Sensor"; ///< Sensor name + +//__________________________________________________________________________ +GeometryTGeo::GeometryTGeo(bool build, int loadTrans) : o2::itsmft::GeometryTGeo(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::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"; + } + + 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) +{ + // populate matrix cache for requested transformations + // +} diff --git a/Detectors/Upgrades/ALICE3/FT3/simulation/CMakeLists.txt b/Detectors/Upgrades/ALICE3/FT3/simulation/CMakeLists.txt new file mode 100644 index 0000000000000..2b436585f8470 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/FT3/simulation/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright CERN and copyright holders of ALICE O2. This software is distributed +# under the terms of the GNU General Public License v3 (GPL Version 3), copied +# verbatim in the file "COPYING". +# +# See http://alice-o2.web.cern.ch/license for full licensing information. +# +# 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/FT3Layer.cxx + src/Detector.cxx + PUBLIC_LINK_LIBRARIES O2::FT3Base + O2::ITSMFTSimulation + ROOT::Physics) + +o2_target_root_dictionary(FT3Simulation + HEADERS include/FT3Simulation/Detector.h + include/FT3Simulation/FT3Layer.h) + +o2_data_file(COPY data DESTINATION Detectors/FT3/simulation) diff --git a/Detectors/Upgrades/ALICE3/FT3/simulation/data/simcuts.dat b/Detectors/Upgrades/ALICE3/FT3/simulation/data/simcuts.dat new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/Detectors/Upgrades/ALICE3/FT3/simulation/include/FT3Simulation/Detector.h b/Detectors/Upgrades/ALICE3/FT3/simulation/include/FT3Simulation/Detector.h new file mode 100644 index 0000000000000..15326bceed496 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/FT3/simulation/include/FT3Simulation/Detector.h @@ -0,0 +1,172 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// 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 // for vector +#include "DetectorsBase/GeometryManager.h" // for getSensID +#include "DetectorsBase/Detector.h" // for Detector +#include "DetectorsCommonDataFormats/DetID.h" // for Detector +#include "ITSMFTSimulation/Hit.h" // for Hit +#include "Rtypes.h" // for Int_t, Double_t, Float_t, Bool_t, etc +#include "TArrayD.h" // for TArrayD +#include "TGeoManager.h" // for gGeoManager, TGeoManager (ptr only) +#include "TLorentzVector.h" // for TLorentzVector +#include "TVector3.h" // for TVector3 + +class FairVolume; +class TGeoVolume; + +class TParticle; + +class TString; + +namespace o2 +{ +namespace ft3 +{ +class GeometryTGeo; +} +} // namespace o2 +namespace o2 +{ +namespace ft3 +{ +class FT3Layer; +} +} // namespace o2 + +namespace o2 +{ +namespace ft3 +{ +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; + } + + public: + /// 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::itsmft::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 { ; } + + /// Returns the number of layers + Int_t getNumberOfLayers() const { return mNumberOfLayers; } + + void buildBasicFT3(int nLayers = 10, Float_t z_first = -16.0, Float_t z_length = 263, Float_t etaIn = -4.5, Float_t etaOut = -1.5, Float_t Layerx2X0 = 0.01); + void buildFT3V1(); + + GeometryTGeo* mGeometryTGeo; //! access to geometry details + + protected: + std::vector> mLayerID; + std::vector> mLayerName; + Int_t mNumberOfLayers; + + 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::vector> mLayers; + + template + friend class o2::base::DetImpl; + ClassDefOverride(Detector, 1); +}; + +} // namespace ft3 +} // namespace o2 + +#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/FT3/simulation/include/FT3Simulation/FT3Layer.h b/Detectors/Upgrades/ALICE3/FT3/simulation/include/FT3Simulation/FT3Layer.h new file mode 100644 index 0000000000000..e4c9258446c3e --- /dev/null +++ b/Detectors/Upgrades/ALICE3/FT3/simulation/include/FT3Simulation/FT3Layer.h @@ -0,0 +1,68 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// 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 FT3Layer.h +/// \brief Definition of the FT3Layer class + +#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 "FT3Simulation/Detector.h" // for Detector, Detector::Model + +class TGeoVolume; + +namespace o2 +{ +namespace ft3 +{ + +/// This class defines the Geometry for the FT3 Layer TGeo. This is a work class used +/// to study different configurations during the development of the ALICE3 EndCaps +class FT3Layer : public TObject +{ + public: + // Default constructor + FT3Layer() = default; + + // Sample layer constructor + FT3Layer(Int_t layerDirection, Int_t layerNumber, std::string layerName, Float_t z, Float_t rIn, Float_t rOut, Float_t sensorThickness, Float_t Layerx2X0); + + /// Copy constructor + FT3Layer(const FT3Layer&) = default; + + /// Assignment operator + FT3Layer& operator=(const FT3Layer&) = default; + + /// Default destructor + ~FT3Layer() override; + + /// Creates the actual Layer and places inside its mother volume + /// \param motherVolume the TGeoVolume owing the volume structure + virtual void createLayer(TGeoVolume* motherVolume); + + private: + Int_t mLayerNumber = -1; ///< Current layer number + Int_t mDirection; ///< Layer direction 0=Forward 1 = Backward + std::string mLayerName; ///< Current layer name + Double_t mInnerRadius; ///< Inner radius of this layer + Double_t mOuterRadius; ///< Outer radius of this layer + Double_t mZ; ///< Z position of the layer + Double_t mSensorThickness; ///< Sensor thickness + Double_t mChipThickness; ///< Chip thickness + Double_t mx2X0; ///< Layer material budget x/X0 + + ClassDefOverride(FT3Layer, 0); // ALICE 3 EndCaps geometry +}; +} // namespace ft3 +} // namespace o2 + +#endif diff --git a/Detectors/Upgrades/ALICE3/FT3/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/FT3/simulation/src/Detector.cxx new file mode 100644 index 0000000000000..2efd0a11f48d2 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/FT3/simulation/src/Detector.cxx @@ -0,0 +1,422 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// 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 "ITSMFTSimulation/Hit.h" +#include "FT3Base/GeometryTGeo.h" +#include "FT3Simulation/Detector.h" +#include "FT3Simulation/FT3Layer.h" + +#include "SimulationDataFormat/Stack.h" +#include "SimulationDataFormat/TrackReference.h" + +// FairRoot includes +#include "FairDetector.h" // for FairDetector +#include "FairLogger.h" // for LOG, LOG_IF +#include "FairRootManager.h" // for FairRootManager +#include "FairRun.h" // for FairRun +#include "FairRuntimeDb.h" // for FairRuntimeDb +#include "FairVolume.h" // for FairVolume +#include "FairRootManager.h" + +#include "TGeoManager.h" // for TGeoManager, gGeoManager +#include "TGeoTube.h" // for TGeoTube +#include "TGeoPcon.h" // for TGeoPcon +#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 NULL, snprintf + +class FairModule; + +class TGeoMedium; + +class TParticle; + +using std::cout; +using std::endl; + +using namespace o2::ft3; +using o2::itsmft::Hit; + +//_________________________________________________________________________________________________ +Detector::Detector() + : o2::base::DetImpl("FT3", kTRUE), + mTrackData(), + mHits(o2::utils::createSimVector()) +{ +} + +//_________________________________________________________________________________________________ +void Detector::buildBasicFT3(int nLayers, Float_t z_first, Float_t z_length, Float_t etaIn, Float_t etaOut, Float_t Layerx2X0) +{ + // Build a basic parametrized FT3 detector with nLayers equally spaced between z_first and z_first+z_length + // Covering pseudo rapidity [etaIn,etaOut]. Passive silicon thinkness computed to match layer x/X0 + + mNumberOfLayers = nLayers; + Float_t sensorThickness = 30.e-4; + mLayerName.resize(2); + mLayerName[0].resize(mNumberOfLayers); + mLayerName[1].resize(mNumberOfLayers); + mLayerID.resize(2); + mLayerID[0].resize(mNumberOfLayers); + mLayerID[1].resize(mNumberOfLayers); + mLayers.resize(2); + + for (Int_t direction : {0, 1}) { + for (Int_t layerNumber = 0; layerNumber < mNumberOfLayers; layerNumber++) { + std::string layerName = GeometryTGeo::getFT3LayerPattern() + std::to_string(layerNumber + mNumberOfLayers * direction); + mLayerName[direction][layerNumber] = layerName; + + // Adds evenly spaced layers + Float_t layerZ = z_first + (layerNumber * z_length / (mNumberOfLayers - 1)) * std::copysign(1, z_first); + Float_t rIn = std::abs(layerZ * std::tan(2.f * std::atan(std::exp(-etaIn)))); + Float_t rOut = std::abs(layerZ * std::tan(2.f * std::atan(std::exp(-etaOut)))); + + auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, layerZ, rIn, rOut, sensorThickness, Layerx2X0); + } + } +} + +//_________________________________________________________________________________________________ +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"; + + mNumberOfLayers = 10; + Float_t sensorThickness = 30.e-4; + Float_t layersx2X0 = 1.e-2; + std::vector> layersConfig{ + {16., .5, 3., sensorThickness, 0.1f * layersx2X0}, // {z_layer, r_in, r_out, sensor_thickness, Layerx2X0} + {20., .5, 3., sensorThickness, 0.1f * layersx2X0}, + {24., .5, 3., sensorThickness, 0.1f * layersx2X0}, + {77., 3.5, 35., sensorThickness, layersx2X0}, + {100., 3.5, 35., sensorThickness, layersx2X0}, + {122., 3.5, 35., sensorThickness, layersx2X0}, + {150., 3.5, 100., sensorThickness, layersx2X0}, + {180., 3.5, 100., sensorThickness, layersx2X0}, + {220., 3.5, 100., sensorThickness, layersx2X0}, + {279., 3.5, 100., sensorThickness, layersx2X0}}; + + mLayerName.resize(2); + mLayerName[0].resize(mNumberOfLayers); + mLayerName[1].resize(mNumberOfLayers); + mLayerID.resize(2); + mLayerID[0].resize(mNumberOfLayers); + mLayerID[1].resize(mNumberOfLayers); + mLayers.resize(2); + + for (auto direction : {0, 1}) { + for (int layerNumber = 0; layerNumber < mNumberOfLayers; layerNumber++) { + std::string directionName = std::to_string(direction); + std::string layerName = GeometryTGeo::getFT3LayerPattern() + directionName + "_" + std::to_string(layerNumber); + mLayerName[direction][layerNumber] = layerName; + auto& z = layersConfig[layerNumber][0]; + + auto& rIn = layersConfig[layerNumber][1]; + auto& rOut = layersConfig[layerNumber][2]; + auto& thickness = layersConfig[layerNumber][3]; + auto& x0 = layersConfig[layerNumber][4]; + + LOG(INFO) << "Adding Layer " << layerName << " at z = " << z; + // Add layers + auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, z, rIn, rOut, thickness, x0); + } + } +} + +//_________________________________________________________________________________________________ +Detector::Detector(Bool_t active) + : o2::base::DetImpl("FT3", active), + mTrackData(), + mHits(o2::utils::createSimVector()) +{ + + //buildBasicFT3(); // BasicFT3 = Parametrized detector equidistant layers + buildFT3V1(); // FT3V1 = Werner's layout +} + +//_________________________________________________________________________________________________ +Detector::Detector(const Detector& rhs) + : o2::base::DetImpl(rhs), + mTrackData(), + + /// Container for data points + mHits(o2::utils::createSimVector()) +{ + mLayerID = rhs.mLayerID; + mLayerName = rhs.mLayerName; + mNumberOfLayers = rhs.mNumberOfLayers; +} + +//_________________________________________________________________________________________________ +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); + + mLayerID = rhs.mLayerID; + mLayerName = rhs.mLayerName; + mNumberOfLayers = rhs.mNumberOfLayers; + 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"; + + mGeometryTGeo = GeometryTGeo::Instance(); + + defineSensitiveVolumes(); +} + +//_________________________________________________________________________________________________ +Bool_t Detector::ProcessHits(FairVolume* vol) +{ + // This method is called from the MC stepping + if (!(fMC->TrackCharge())) { + return kFALSE; + } + + Int_t lay = 0, volID = vol->getMCid(); + while ((lay <= mNumberOfLayers * 2) && (volID != mLayerID[lay % 2][lay / 2])) { + ++lay; + } + + 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_t ifield = 2; + Float_t fieldm = 10.0; + o2::base::Detector::initFieldTrackingParams(ifield, fieldm); + + Float_t tmaxfdSi = 0.1; // .10000E+01; // Degree + Float_t stemaxSi = 0.0075; // .10000E+01; // cm + Float_t 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() +{ + + mGeometryTGeo = GeometryTGeo::Instance(); + + TGeoVolume* volFT3 = new TGeoVolumeAssembly(GeometryTGeo::getFT3VolPattern()); + + LOG(INFO) << "GeometryBuilder::buildGeometry volume name = " << GeometryTGeo::getFT3VolPattern(); + + TGeoVolume* vALIC = gGeoManager->GetVolume("barrel"); + if (!vALIC) { + LOG(FATAL) << "Could not find the top volume"; + } + + LOG(DEBUG) << "buildGeometry: " + << Form("gGeoManager name is %s title is %s", gGeoManager->GetName(), gGeoManager->GetTitle()); + + for (Int_t direction : {0, 1}) { + + for (Int_t iLayer = 0; iLayer < mNumberOfLayers; iLayer++) { + mLayers[direction][iLayer].createLayer(volFT3); + } + } + vALIC->AddNode(volFT3, 2, new TGeoTranslation(0., 30., 0.)); + + for (auto direction : {0, 1}) { + for (int iLayer = 0; iLayer < mNumberOfLayers; iLayer++) { + mLayerID[direction][iLayer] = gMC ? TVirtualMC::GetMC()->VolId(Form("%s_%d_%d", GeometryTGeo::getFT3SensorPattern(), direction, iLayer)) : 0; + std::string directionString = direction ? "Forward" : "Backward"; + LOG(INFO) << "mLayerID for " << directionString << " layer " << iLayer << " = " << mLayerID[direction][iLayer]; + } + } +} + +//_________________________________________________________________________________________________ +void Detector::defineSensitiveVolumes() +{ + TGeoManager* geoManager = gGeoManager; + TGeoVolume* v; + + TString volumeName; + LOG(INFO) << "Adding FT3 Sensitive Volumes"; + + // The names of the FT3 sensitive volumes have the format: FT3Sensor_(0,1)_(0...sNumberLayers-1) + for (Int_t direction : {0, 1}) { + for (Int_t iLayer = 0; iLayer < mNumberOfLayers; iLayer++) { + volumeName = o2::ft3::GeometryTGeo::getFT3SensorPattern() + std::to_string(iLayer); + v = geoManager->GetVolume(Form("%s_%d_%d", GeometryTGeo::getFT3SensorPattern(), direction, iLayer)); + LOG(INFO) << "Adding FT3 Sensitive Volume => " << v->GetName() << std::endl; + AddSensitiveVolume(v); + } + } +} + +//_________________________________________________________________________________________________ +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/FT3/simulation/src/FT3Layer.cxx b/Detectors/Upgrades/ALICE3/FT3/simulation/src/FT3Layer.cxx new file mode 100644 index 0000000000000..fcd6604a56163 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/FT3/simulation/src/FT3Layer.cxx @@ -0,0 +1,98 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// 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 FT3Layer.cxx +/// \brief Implementation of the FT3Layer class +/// \author Mario Sitta +/// \author Chinorat Kobdaj (kobdaj@g.sut.ac.th) + +#include "FT3Simulation/FT3Layer.h" +#include "FT3Base/GeometryTGeo.h" +#include "FT3Simulation/Detector.h" + +#include "FairLogger.h" // for LOG + +#include // for TGeoManager, gGeoManager +#include // for TGeoCombiTrans, TGeoRotation, etc +#include // for TGeoTube, TGeoTubeSeg +#include // for TGeoVolume, TGeoVolumeAssembly +#include // for TGeoCompositeShape +#include "TMathBase.h" // for Abs +#include // for Sin, RadToDeg, DegToRad, Cos, Tan, etc + +#include // for snprintf + +class TGeoMedium; + +using namespace TMath; +using namespace o2::ft3; +using namespace o2::itsmft; + +ClassImp(FT3Layer); + +FT3Layer::~FT3Layer() = default; + +FT3Layer::FT3Layer(Int_t layerDirection, Int_t layerNumber, std::string layerName, Float_t z, Float_t rIn, Float_t rOut, Float_t sensorThickness, Float_t Layerx2X0) +{ + // Creates a simple parametrized EndCap layer covering the given + // pseudorapidity range at the z layer position + mDirection = layerDirection; + mLayerNumber = layerNumber; + mLayerName = layerName; + mZ = layerDirection ? std::abs(z) : -std::abs(z); + mx2X0 = Layerx2X0; + mSensorThickness = sensorThickness; + mInnerRadius = rIn; + mOuterRadius = rOut; + + LOG(INFO) << " Using silicon Radiation Length = " << 9.5 << " to emulate layer radiation length."; + + mChipThickness = Layerx2X0 * 9.5; + if (mChipThickness < mSensorThickness) { + LOG(INFO) << " WARNING: Chip cannot be thinner than sensor. Setting minimal chip thickness."; + mChipThickness = mSensorThickness; + } + LOG(INFO) << "Creating FT3 Layer " << mLayerNumber << ": z = " << mZ << " ; R_in = " << mInnerRadius << " ; R_out = " << mOuterRadius << " ; ChipThickness = " << mChipThickness; +} + +void FT3Layer::createLayer(TGeoVolume* motherVolume) +{ + if (mLayerNumber >= 0) { + // Create tube, set sensitive volume, add to mother volume + + 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, mSensorThickness / 2); + TGeoTube* chip = new TGeoTube(mInnerRadius, mOuterRadius, mChipThickness / 2); + TGeoTube* layer = new TGeoTube(mInnerRadius, mOuterRadius, mChipThickness / 2); + + TGeoMedium* medSi = gGeoManager->GetMedium("FT3_SI$"); + TGeoMedium* medAir = gGeoManager->GetMedium("FT3_AIR$"); + + TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi); + TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi); + TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir); + + 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); + + return; + } +} diff --git a/Detectors/Upgrades/ALICE3/FT3/simulation/src/FT3SimulationLinkDef.h b/Detectors/Upgrades/ALICE3/FT3/simulation/src/FT3SimulationLinkDef.h new file mode 100644 index 0000000000000..02c16d9a6cf12 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/FT3/simulation/src/FT3SimulationLinkDef.h @@ -0,0 +1,21 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// 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::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/TRK/macros/test/CMakeLists.txt b/Detectors/Upgrades/ALICE3/TRK/macros/test/CMakeLists.txt index 10bb6dd71f256..73aa18e55d56b 100644 --- a/Detectors/Upgrades/ALICE3/TRK/macros/test/CMakeLists.txt +++ b/Detectors/Upgrades/ALICE3/TRK/macros/test/CMakeLists.txt @@ -6,4 +6,4 @@ # # 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. \ No newline at end of file +# submit itself to any jurisdiction. diff --git a/macro/CMakeLists.txt b/macro/CMakeLists.txt index 1e8b05f703b98..b35fecbc3c0bd 100644 --- a/macro/CMakeLists.txt +++ b/macro/CMakeLists.txt @@ -108,7 +108,7 @@ o2_add_test_root_macro(analyzeOriginHits.C O2::DetectorsCommonDataFormats) if(ENABLE_UPGRADES) - set(upgradeTargets O2::Alice3DetectorsPassive O2::ITS3Simulation O2::TRKSimulation) + set(upgradeTargets O2::Alice3DetectorsPassive O2::ITS3Simulation O2::TRKSimulation O2::FT3Simulation) endif() o2_add_test_root_macro(build_geometry.C diff --git a/macro/build_geometry.C b/macro/build_geometry.C index ef2247c92958a..3ffc608c3647e 100644 --- a/macro/build_geometry.C +++ b/macro/build_geometry.C @@ -48,6 +48,7 @@ #ifdef ENABLE_UPGRADES #include #include +#include #include #endif @@ -193,6 +194,12 @@ void build_geometry(FairRunSim* run = nullptr) auto trk = new o2::trk::Detector(true); run->AddModule(trk); } + + if (isActivated("FT3")) { + // ALICE 3 FT3 + auto ft3 = new o2::ft3::Detector(true); + run->AddModule(ft3); + } #endif if (isActivated("ITS")) { diff --git a/macro/duplicateHits.C b/macro/duplicateHits.C index e42c6f2e4e0d4..9bd7f7f3dd1a0 100644 --- a/macro/duplicateHits.C +++ b/macro/duplicateHits.C @@ -17,6 +17,11 @@ #include "CPVBase/Hit.h" #include "DataFormatsZDC/Hit.h" #include "SimulationDataFormat/MCEventHeader.h" + +#ifdef ENABLE_UPGRADES +#include "EndCapsSimulation/Hit.h" +#endif + #endif template @@ -191,6 +196,11 @@ void duplicateHits(const char* filebase = "o2sim", const char* newfilebase = "o2 duplicateV(grp, filebase, DetID::MID, newfilebase, factor); duplicateV(grp, filebase, DetID::MCH, newfilebase, factor); duplicateV(grp, filebase, DetID::TPC, newfilebase, factor); + +#ifdef ENABLE_UPGRADES + duplicateV(grp, filebase, DetID::FT3, newfilebase, factor); +#endif + // duplicateACO(reftree); // outfile.Write(); } diff --git a/run/CMakeLists.txt b/run/CMakeLists.txt index f0010f4d3745a..8020d73125211 100644 --- a/run/CMakeLists.txt +++ b/run/CMakeLists.txt @@ -39,6 +39,7 @@ target_link_libraries(allsim $<$:O2::Alice3DetectorsPassive> $<$:O2::ITS3Simulation> $<$:O2::TRKSimulation> + $<$:O2::FT3Simulation> O2::Generators) add_library(internal::allsim ALIAS allsim) diff --git a/run/O2HitMerger.h b/run/O2HitMerger.h index edf69637d1981..621911001ac63 100644 --- a/run/O2HitMerger.h +++ b/run/O2HitMerger.h @@ -66,6 +66,7 @@ #ifdef ENABLE_UPGRADES #include #include +#include #endif namespace o2 @@ -749,6 +750,10 @@ void O2HitMerger::initDetInstances() mDetectorInstances[i] = std::move(std::make_unique(true)); counter++; } + if (i == DetID::FT3) { + mDetectorInstances[i] = std::move(std::make_unique(true)); + counter++; + } #endif // init the detector specific output files initHitTreeAndOutFile(i);