diff --git a/Common/SimConfig/src/SimConfig.cxx b/Common/SimConfig/src/SimConfig.cxx index 868cb93a8d854..5b0f947a094ea 100644 --- a/Common/SimConfig/src/SimConfig.cxx +++ b/Common/SimConfig/src/SimConfig.cxx @@ -63,7 +63,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 && d != DetID::FT3) { + if (d != DetID::IT3 && d != DetID::TRK && d != DetID::FT3 && d != DetID::PSR) { 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 f88871bebb0ae..3ec2a51585340 100644 --- a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID.h +++ b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID.h @@ -24,7 +24,8 @@ } printf("joint mask: 0x%lx\n",mskTot.to_ulong()); */ - +// +// #ifndef O2_BASE_DETID_ #define O2_BASE_DETID_ @@ -81,7 +82,8 @@ class DetID static constexpr ID IT3 = 17; static constexpr ID TRK = 18; static constexpr ID FT3 = 19; - static constexpr ID Last = FT3; + static constexpr ID PSR = 20; + static constexpr ID Last = PSR; #else static constexpr ID Last = CTP; ///< if extra detectors added, update this !!! #endif @@ -167,10 +169,21 @@ class DetID // detector names, will be defined in DataSources 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", "CTP", "IT3", "TRK", "FT3", nullptr}; + {"ITS", "TPC", "TRD", "TOF", "PHS", "CPV", "EMC", "HMP", "MFT", "MCH", "MID", "ZDC", "FT0", "FV0", "FDD", "ACO", "CTP", "IT3", "TRK", "FT3", "PSR", nullptr}; #else {"ITS", "TPC", "TRD", "TOF", "PHS", "CPV", "EMC", "HMP", "MFT", "MCH", "MID", "ZDC", "FT0", "FV0", "FDD", "ACO", "CTP", nullptr}; #endif + // detector names, will be defined in DataSources + static constexpr std::array sMasks = ///< detectot masks + {math_utils::bit2Mask(ITS), math_utils::bit2Mask(TPC), math_utils::bit2Mask(TRD), math_utils::bit2Mask(TOF), math_utils::bit2Mask(PHS), + math_utils::bit2Mask(CPV), math_utils::bit2Mask(EMC), math_utils::bit2Mask(HMP), math_utils::bit2Mask(MFT), math_utils::bit2Mask(MCH), + math_utils::bit2Mask(MID), math_utils::bit2Mask(ZDC), math_utils::bit2Mask(FT0), math_utils::bit2Mask(FV0), math_utils::bit2Mask(FDD), + math_utils::bit2Mask(ACO) +#ifdef ENABLE_UPGRADES + , + math_utils::bit2Mask(IT3), math_utils::bit2Mask(TRK), math_utils::bit2Mask(FT3), math_utils::bit2Mask(PSR) +#endif + }; static constexpr std::array sOrigins = ///< detector data origins @@ -180,7 +193,7 @@ class DetID o2h::gDataOriginACO, o2h::gDataOriginCTP #ifdef ENABLE_UPGRADES , - o2h::gDataOriginIT3, o2h::gDataOriginTRK, o2h::gDataOriginFT3 + o2h::gDataOriginIT3, o2h::gDataOriginTRK, o2h::gDataOriginFT3, o2h::gDataOriginPSR #endif }; #endif // GPUCA_GPUCODE_DEVICE diff --git a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID_BACKUP_450708.h b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID_BACKUP_450708.h new file mode 100644 index 0000000000000..616ef7b574126 --- /dev/null +++ b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID_BACKUP_450708.h @@ -0,0 +1,226 @@ +// 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. + +/// @brief ALICE detectors ID's, names, masks +/// +/// @author Ruben Shahoyan, ruben.shahoyan@cern.ch + +/*! + Example of class usage: + using namespace o2::base; + DetID det[3] = {DetID(DetID::ITS), DetID(DetID::TPC), DetID(DetID::TRD)}; + DetID::mask_t mskTot; + for (int i=0;i<3;i++) { + printf("detID: %2d %10s 0x%lx\n",det[i].getID(),det[i].getName(),det[i].getMask().to_ulong()); + mskTot |= det[i].getMask(); + } + printf("joint mask: 0x%lx\n",mskTot.to_ulong()); + */ + +#ifndef O2_BASE_DETID_ +#define O2_BASE_DETID_ + +#include "GPUCommonRtypes.h" +#include "GPUCommonBitSet.h" +#include "MathUtils/Utils.h" +#include "DetectorsCommonDataFormats/UpgradesStatus.h" +#ifndef GPUCA_GPUCODE_DEVICE +#include "Headers/DataHeader.h" +#include +#include +#include +#include +#include +#include +#include +#endif + +namespace o2 +{ +namespace header +{ +} +namespace detectors +{ + +namespace o2h = o2::header; + +/// Static class with identifiers, bitmasks and names for ALICE detectors +class DetID +{ + public: + /// Detector identifiers: continuous, starting from 0 + typedef int ID; + + static constexpr ID ITS = 0; + static constexpr ID TPC = 1; + static constexpr ID TRD = 2; + static constexpr ID TOF = 3; + static constexpr ID PHS = 4; + static constexpr ID CPV = 5; + static constexpr ID EMC = 6; + static constexpr ID HMP = 7; + static constexpr ID MFT = 8; + static constexpr ID MCH = 9; + static constexpr ID MID = 10; + static constexpr ID ZDC = 11; + static constexpr ID FT0 = 12; + static constexpr ID FV0 = 13; + static constexpr ID FDD = 14; + static constexpr ID ACO = 15; + static constexpr ID CTP = 16; +#ifdef ENABLE_UPGRADES + static constexpr ID IT3 = 17; + static constexpr ID TRK = 18; + static constexpr ID FT3 = 19; + static constexpr ID PSR = 20; + static constexpr ID Last = PSR; +#else + static constexpr ID Last = CTP; ///< if extra detectors added, update this !!! +#endif + static constexpr ID First = ITS; + + static constexpr int nDetectors = Last + 1; ///< number of defined detectors + typedef o2::gpu::gpustd::bitset<32> mask_t; + static_assert(nDetectors <= 32, "bitset<32> insufficient"); + + static constexpr mask_t FullMask = (0x1u << nDetectors) - 1; + +#ifndef GPUCA_GPUCODE_DEVICE + static constexpr std::string_view NONE{"none"}; ///< keywork for no-detector + static constexpr std::string_view ALL{"all"}; ///< keywork for all detectors +#endif // GPUCA_GPUCODE_DEVICE + + GPUdi() DetID(ID id) : mID(id) + { + } + DetID(const char* name); + GPUdDefault() DetID(const DetID& src) = default; + GPUdDefault() DetID& operator=(const DetID& src) = default; + // we need default c-tor only for root persistency, code must use c-tor with argument + DetID() : mID(First) {} + + /// get derector id + GPUdi() ID getID() const { return mID; } + /// get detector mask + GPUdi() mask_t getMask() const { return getMask(mID); } +#ifndef GPUCA_GPUCODE_DEVICE + /// get detector origin + GPUdi() o2h::DataOrigin getDataOrigin() const { return getDataOrigin(mID); } + /// get detector name + const char* getName() const { return getName(mID); } +#endif // GPUCA_GPUCODE_DEVICE + /// conversion operator to int + GPUdi() operator int() const { return static_cast(mID); } + + // ---------------- general static methods ----------------- + /// get number of defined detectors + GPUdi() static constexpr int getNDetectors() { return nDetectors; } + // detector ID to mask conversion + GPUd() static constexpr mask_t getMask(ID id); + +#ifndef GPUCA_GPUCODE_DEVICE + /// names of defined detectors + static constexpr const char* getName(ID id) { return sDetNames[id]; } + // detector ID to DataOrigin conversions + static constexpr o2h::DataOrigin getDataOrigin(ID id) { return sOrigins[id]; } + + // detector masks from any non-alpha-num delimiter-separated list (empty if NONE is supplied) + static mask_t getMask(const std::string_view detList); + + static std::string getNames(mask_t mask, char delimiter = ','); + + inline static constexpr int nameToID(char const* name, int id = First) + { + return id > Last ? -1 : sameStr(name, sDetNames[id]) ? id + : nameToID(name, id + 1); + } + +#endif // GPUCA_GPUCODE_DEVICE + + static bool upgradesEnabled() + { +#ifdef ENABLE_UPGRADES + return true; +#else + return false; +#endif + } + + private: + // are 2 strings equal ? (trick from Giulio) + GPUdi() static constexpr bool sameStr(char const* x, char const* y) + { + return !*x && !*y ? true : /* default */ (*x == *y && sameStr(x + 1, y + 1)); + } + + ID mID = First; ///< detector ID + +#ifndef GPUCA_GPUCODE_DEVICE + // detector names, will be defined in DataSources + 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", "CTP", "IT3", "TRK", "FT3", "PSR", nullptr}; +#else + {"ITS", "TPC", "TRD", "TOF", "PHS", "CPV", "EMC", "HMP", "MFT", "MCH", "MID", "ZDC", "FT0", "FV0", "FDD", "ACO", "CTP", nullptr}; +#endif +<<<<<<< HEAD +======= + // detector names, will be defined in DataSources + static constexpr std::array sMasks = ///< detectot masks + {math_utils::bit2Mask(ITS), math_utils::bit2Mask(TPC), math_utils::bit2Mask(TRD), math_utils::bit2Mask(TOF), math_utils::bit2Mask(PHS), + math_utils::bit2Mask(CPV), math_utils::bit2Mask(EMC), math_utils::bit2Mask(HMP), math_utils::bit2Mask(MFT), math_utils::bit2Mask(MCH), + math_utils::bit2Mask(MID), math_utils::bit2Mask(ZDC), math_utils::bit2Mask(FT0), math_utils::bit2Mask(FV0), math_utils::bit2Mask(FDD), + math_utils::bit2Mask(ACO) +#ifdef ENABLE_UPGRADES + , + math_utils::bit2Mask(IT3), math_utils::bit2Mask(TRK), math_utils::bit2Mask(FT3), math_utils::bit2Mask(PSR) +#endif + }; +>>>>>>> Si-only-Preshower + + static constexpr std::array + sOrigins = ///< detector data origins + {o2h::gDataOriginITS, o2h::gDataOriginTPC, o2h::gDataOriginTRD, o2h::gDataOriginTOF, o2h::gDataOriginPHS, + o2h::gDataOriginCPV, o2h::gDataOriginEMC, o2h::gDataOriginHMP, o2h::gDataOriginMFT, o2h::gDataOriginMCH, + o2h::gDataOriginMID, o2h::gDataOriginZDC, o2h::gDataOriginFT0, o2h::gDataOriginFV0, o2h::gDataOriginFDD, + o2h::gDataOriginACO, o2h::gDataOriginCTP +#ifdef ENABLE_UPGRADES + , + o2h::gDataOriginIT3, o2h::gDataOriginTRK, o2h::gDataOriginFT3, o2h::gDataOriginPSR +#endif + }; +#endif // GPUCA_GPUCODE_DEVICE + + ClassDefNV(DetID, 3); +}; + +namespace detid_internal +{ +// static constexpr array class members not possible on the GPU, thus we use this trick. +GPUconstexpr() DetID::mask_t sMasks[DetID::nDetectors] = ///< detectot masks + {DetID::mask_t(math_utils::bit2Mask(DetID::ITS)), DetID::mask_t(math_utils::bit2Mask(DetID::TPC)), DetID::mask_t(math_utils::bit2Mask(DetID::TRD)), DetID::mask_t(math_utils::bit2Mask(DetID::TOF)), DetID::mask_t(math_utils::bit2Mask(DetID::PHS)), + DetID::mask_t(math_utils::bit2Mask(DetID::CPV)), DetID::mask_t(math_utils::bit2Mask(DetID::EMC)), DetID::mask_t(math_utils::bit2Mask(DetID::HMP)), DetID::mask_t(math_utils::bit2Mask(DetID::MFT)), DetID::mask_t(math_utils::bit2Mask(DetID::MCH)), + DetID::mask_t(math_utils::bit2Mask(DetID::MID)), DetID::mask_t(math_utils::bit2Mask(DetID::ZDC)), DetID::mask_t(math_utils::bit2Mask(DetID::FT0)), DetID::mask_t(math_utils::bit2Mask(DetID::FV0)), DetID::mask_t(math_utils::bit2Mask(DetID::FDD)), + DetID::mask_t(math_utils::bit2Mask(DetID::ACO)), DetID::mask_t(math_utils::bit2Mask(DetID::CTP)) +#ifdef ENABLE_UPGRADES + , + DetID::mask_t(math_utils::bit2Mask(DetID::IT3)), DetID::mask_t(math_utils::bit2Mask(DetID::TRK)), DetID::mask_t(math_utils::bit2Mask(DetID::FT3)) +#endif +}; +} // namespace detid_internal + +GPUdi() constexpr DetID::mask_t DetID::getMask(ID id) { return detid_internal::sMasks[id]; } + +} // namespace detectors +} // namespace o2 + +#endif diff --git a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID_BASE_450708.h b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID_BASE_450708.h new file mode 100644 index 0000000000000..277f9b6e10c63 --- /dev/null +++ b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID_BASE_450708.h @@ -0,0 +1,173 @@ +// 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. + +/// @brief ALICE detectors ID's, names, masks +/// +/// @author Ruben Shahoyan, ruben.shahoyan@cern.ch + +/*! + Example of class usage: + using namespace o2::base; + DetID det[3] = {DetID(DetID::ITS), DetID(DetID::TPC), DetID(DetID::TRD)}; + DetID::mask_t mskTot; + for (int i=0;i<3;i++) { + printf("detID: %2d %10s 0x%lx\n",det[i].getID(),det[i].getName(),det[i].getMask().to_ulong()); + mskTot |= det[i].getMask(); + } + printf("joint mask: 0x%lx\n",mskTot.to_ulong()); + */ + +#ifndef O2_BASE_DETID_ +#define O2_BASE_DETID_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "MathUtils/Utils.h" +#include "Headers/DataHeader.h" + +namespace o2 +{ +namespace detectors +{ + +namespace o2h = o2::header; + +/// Static class with identifiers, bitmasks and names for ALICE detectors +class DetID +{ + public: + /// Detector identifiers: continuous, starting from 0 + typedef std::int32_t ID; + + static constexpr ID ITS = 0; + static constexpr ID TPC = 1; + static constexpr ID TRD = 2; + static constexpr ID TOF = 3; + static constexpr ID PHS = 4; + static constexpr ID CPV = 5; + static constexpr ID EMC = 6; + static constexpr ID HMP = 7; + static constexpr ID MFT = 8; + static constexpr ID MCH = 9; + static constexpr ID MID = 10; + static constexpr ID ZDC = 11; + static constexpr ID FT0 = 12; + static constexpr ID FV0 = 13; + static constexpr ID FDD = 14; + static constexpr ID ACO = 15; + static constexpr ID CTP = 16; +#ifdef ENABLE_UPGRADES + static constexpr ID IT3 = 17; + static constexpr ID TRK = 18; + static constexpr ID FT3 = 19; + static constexpr ID Last = FT3; +#else + static constexpr ID Last = CTP; ///< if extra detectors added, update this !!! +#endif + static constexpr ID First = ITS; + + static constexpr int nDetectors = Last + 1; ///< number of defined detectors + + static constexpr std::string_view NONE{"none"}; ///< keywork for no-detector + static constexpr std::string_view ALL{"all"}; ///< keywork for all detectors + + typedef std::bitset<32> mask_t; + + DetID(ID id) : mID(id) {} + DetID(const char* name); + DetID(const DetID& src) = default; + DetID& operator=(const DetID& src) = default; + + /// get derector id + ID getID() const { return mID; } + /// get detector mask + mask_t getMask() const { return getMask(mID); } + /// get detector mask + o2h::DataOrigin getDataOrigin() const { return getDataOrigin(mID); } + /// get detector name + const char* getName() const { return getName(mID); } + /// conversion operator to int + operator int() const { return static_cast(mID); } + + // ---------------- general static methods ----------------- + /// get number of defined detectors + static constexpr int getNDetectors() { return nDetectors; } + /// names of defined detectors + static constexpr const char* getName(ID id) { return sDetNames[id]; } + // detector ID to mask conversion + static constexpr mask_t getMask(ID id) { return sMasks[id]; } + // detector ID to DataOrigin conversions + static constexpr o2h::DataOrigin getDataOrigin(ID id) { return sOrigins[id]; } + + // detector masks from any non-alpha-num delimiter-separated list (empty if NONE is supplied) + static mask_t getMask(const std::string_view detList); + + static std::string getNames(mask_t mask, char delimiter = ','); + + // we need default c-tor only for root persistency, code must use c-tor with argument + DetID() : mID(First) {} + + private: + // are 2 strings equal ? (trick from Giulio) + inline static constexpr bool sameStr(char const* x, char const* y) + { + return !*x && !*y ? true : /* default */ (*x == *y && sameStr(x + 1, y + 1)); + } + + inline static constexpr int nameToID(char const* name, int id) + { + return id > Last ? id : sameStr(name, sDetNames[id]) ? id : nameToID(name, id + 1); + } + + ID mID = First; ///< detector ID + + 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", "CTP", "IT3", "TRK", "FT3", nullptr}; +#else + {"ITS", "TPC", "TRD", "TOF", "PHS", "CPV", "EMC", "HMP", "MFT", "MCH", "MID", "ZDC", "FT0", "FV0", "FDD", "ACO", "CTP", nullptr}; +#endif + // detector names, will be defined in DataSources + static constexpr std::array sMasks = ///< detectot masks + {math_utils::bit2Mask(ITS), math_utils::bit2Mask(TPC), math_utils::bit2Mask(TRD), math_utils::bit2Mask(TOF), math_utils::bit2Mask(PHS), + math_utils::bit2Mask(CPV), math_utils::bit2Mask(EMC), math_utils::bit2Mask(HMP), math_utils::bit2Mask(MFT), math_utils::bit2Mask(MCH), + math_utils::bit2Mask(MID), math_utils::bit2Mask(ZDC), math_utils::bit2Mask(FT0), math_utils::bit2Mask(FV0), math_utils::bit2Mask(FDD), + math_utils::bit2Mask(ACO) +#ifdef ENABLE_UPGRADES + , + math_utils::bit2Mask(IT3), math_utils::bit2Mask(TRK), math_utils::bit2Mask(FT3) +#endif + }; + + static constexpr std::array + sOrigins = ///< detector data origins + {o2h::gDataOriginITS, o2h::gDataOriginTPC, o2h::gDataOriginTRD, o2h::gDataOriginTOF, o2h::gDataOriginPHS, + o2h::gDataOriginCPV, o2h::gDataOriginEMC, o2h::gDataOriginHMP, o2h::gDataOriginMFT, o2h::gDataOriginMCH, + o2h::gDataOriginMID, o2h::gDataOriginZDC, o2h::gDataOriginFT0, o2h::gDataOriginFV0, o2h::gDataOriginFDD, + o2h::gDataOriginACO, o2h::gDataOriginCTP +#ifdef ENABLE_UPGRADES + , + o2h::gDataOriginIT3, o2h::gDataOriginTRK, o2h::gDataOriginFT3 +#endif + }; + + ClassDefNV(DetID, 2); +}; + +} // namespace detectors +} // namespace o2 + +#endif diff --git a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID_LOCAL_450708.h b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID_LOCAL_450708.h new file mode 100644 index 0000000000000..f88871bebb0ae --- /dev/null +++ b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID_LOCAL_450708.h @@ -0,0 +1,211 @@ +// 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. + +/// @brief ALICE detectors ID's, names, masks +/// +/// @author Ruben Shahoyan, ruben.shahoyan@cern.ch + +/*! + Example of class usage: + using namespace o2::base; + DetID det[3] = {DetID(DetID::ITS), DetID(DetID::TPC), DetID(DetID::TRD)}; + DetID::mask_t mskTot; + for (int i=0;i<3;i++) { + printf("detID: %2d %10s 0x%lx\n",det[i].getID(),det[i].getName(),det[i].getMask().to_ulong()); + mskTot |= det[i].getMask(); + } + printf("joint mask: 0x%lx\n",mskTot.to_ulong()); + */ + +#ifndef O2_BASE_DETID_ +#define O2_BASE_DETID_ + +#include "GPUCommonRtypes.h" +#include "GPUCommonBitSet.h" +#include "MathUtils/Utils.h" +#include "DetectorsCommonDataFormats/UpgradesStatus.h" +#ifndef GPUCA_GPUCODE_DEVICE +#include "Headers/DataHeader.h" +#include +#include +#include +#include +#include +#include +#include +#endif + +namespace o2 +{ +namespace header +{ +} +namespace detectors +{ + +namespace o2h = o2::header; + +/// Static class with identifiers, bitmasks and names for ALICE detectors +class DetID +{ + public: + /// Detector identifiers: continuous, starting from 0 + typedef int ID; + + static constexpr ID ITS = 0; + static constexpr ID TPC = 1; + static constexpr ID TRD = 2; + static constexpr ID TOF = 3; + static constexpr ID PHS = 4; + static constexpr ID CPV = 5; + static constexpr ID EMC = 6; + static constexpr ID HMP = 7; + static constexpr ID MFT = 8; + static constexpr ID MCH = 9; + static constexpr ID MID = 10; + static constexpr ID ZDC = 11; + static constexpr ID FT0 = 12; + static constexpr ID FV0 = 13; + static constexpr ID FDD = 14; + static constexpr ID ACO = 15; + static constexpr ID CTP = 16; +#ifdef ENABLE_UPGRADES + static constexpr ID IT3 = 17; + static constexpr ID TRK = 18; + static constexpr ID FT3 = 19; + static constexpr ID Last = FT3; +#else + static constexpr ID Last = CTP; ///< if extra detectors added, update this !!! +#endif + static constexpr ID First = ITS; + + static constexpr int nDetectors = Last + 1; ///< number of defined detectors + typedef o2::gpu::gpustd::bitset<32> mask_t; + static_assert(nDetectors <= 32, "bitset<32> insufficient"); + + static constexpr mask_t FullMask = (0x1u << nDetectors) - 1; + +#ifndef GPUCA_GPUCODE_DEVICE + static constexpr std::string_view NONE{"none"}; ///< keywork for no-detector + static constexpr std::string_view ALL{"all"}; ///< keywork for all detectors +#endif // GPUCA_GPUCODE_DEVICE + + GPUdi() DetID(ID id) : mID(id) + { + } + DetID(const char* name); + GPUdDefault() DetID(const DetID& src) = default; + GPUdDefault() DetID& operator=(const DetID& src) = default; + // we need default c-tor only for root persistency, code must use c-tor with argument + DetID() : mID(First) {} + + /// get derector id + GPUdi() ID getID() const { return mID; } + /// get detector mask + GPUdi() mask_t getMask() const { return getMask(mID); } +#ifndef GPUCA_GPUCODE_DEVICE + /// get detector origin + GPUdi() o2h::DataOrigin getDataOrigin() const { return getDataOrigin(mID); } + /// get detector name + const char* getName() const { return getName(mID); } +#endif // GPUCA_GPUCODE_DEVICE + /// conversion operator to int + GPUdi() operator int() const { return static_cast(mID); } + + // ---------------- general static methods ----------------- + /// get number of defined detectors + GPUdi() static constexpr int getNDetectors() { return nDetectors; } + // detector ID to mask conversion + GPUd() static constexpr mask_t getMask(ID id); + +#ifndef GPUCA_GPUCODE_DEVICE + /// names of defined detectors + static constexpr const char* getName(ID id) { return sDetNames[id]; } + // detector ID to DataOrigin conversions + static constexpr o2h::DataOrigin getDataOrigin(ID id) { return sOrigins[id]; } + + // detector masks from any non-alpha-num delimiter-separated list (empty if NONE is supplied) + static mask_t getMask(const std::string_view detList); + + static std::string getNames(mask_t mask, char delimiter = ','); + + inline static constexpr int nameToID(char const* name, int id = First) + { + return id > Last ? -1 : sameStr(name, sDetNames[id]) ? id + : nameToID(name, id + 1); + } + +#endif // GPUCA_GPUCODE_DEVICE + + static bool upgradesEnabled() + { +#ifdef ENABLE_UPGRADES + return true; +#else + return false; +#endif + } + + private: + // are 2 strings equal ? (trick from Giulio) + GPUdi() static constexpr bool sameStr(char const* x, char const* y) + { + return !*x && !*y ? true : /* default */ (*x == *y && sameStr(x + 1, y + 1)); + } + + ID mID = First; ///< detector ID + +#ifndef GPUCA_GPUCODE_DEVICE + // detector names, will be defined in DataSources + 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", "CTP", "IT3", "TRK", "FT3", nullptr}; +#else + {"ITS", "TPC", "TRD", "TOF", "PHS", "CPV", "EMC", "HMP", "MFT", "MCH", "MID", "ZDC", "FT0", "FV0", "FDD", "ACO", "CTP", nullptr}; +#endif + + static constexpr std::array + sOrigins = ///< detector data origins + {o2h::gDataOriginITS, o2h::gDataOriginTPC, o2h::gDataOriginTRD, o2h::gDataOriginTOF, o2h::gDataOriginPHS, + o2h::gDataOriginCPV, o2h::gDataOriginEMC, o2h::gDataOriginHMP, o2h::gDataOriginMFT, o2h::gDataOriginMCH, + o2h::gDataOriginMID, o2h::gDataOriginZDC, o2h::gDataOriginFT0, o2h::gDataOriginFV0, o2h::gDataOriginFDD, + o2h::gDataOriginACO, o2h::gDataOriginCTP +#ifdef ENABLE_UPGRADES + , + o2h::gDataOriginIT3, o2h::gDataOriginTRK, o2h::gDataOriginFT3 +#endif + }; +#endif // GPUCA_GPUCODE_DEVICE + + ClassDefNV(DetID, 3); +}; + +namespace detid_internal +{ +// static constexpr array class members not possible on the GPU, thus we use this trick. +GPUconstexpr() DetID::mask_t sMasks[DetID::nDetectors] = ///< detectot masks + {DetID::mask_t(math_utils::bit2Mask(DetID::ITS)), DetID::mask_t(math_utils::bit2Mask(DetID::TPC)), DetID::mask_t(math_utils::bit2Mask(DetID::TRD)), DetID::mask_t(math_utils::bit2Mask(DetID::TOF)), DetID::mask_t(math_utils::bit2Mask(DetID::PHS)), + DetID::mask_t(math_utils::bit2Mask(DetID::CPV)), DetID::mask_t(math_utils::bit2Mask(DetID::EMC)), DetID::mask_t(math_utils::bit2Mask(DetID::HMP)), DetID::mask_t(math_utils::bit2Mask(DetID::MFT)), DetID::mask_t(math_utils::bit2Mask(DetID::MCH)), + DetID::mask_t(math_utils::bit2Mask(DetID::MID)), DetID::mask_t(math_utils::bit2Mask(DetID::ZDC)), DetID::mask_t(math_utils::bit2Mask(DetID::FT0)), DetID::mask_t(math_utils::bit2Mask(DetID::FV0)), DetID::mask_t(math_utils::bit2Mask(DetID::FDD)), + DetID::mask_t(math_utils::bit2Mask(DetID::ACO)), DetID::mask_t(math_utils::bit2Mask(DetID::CTP)) +#ifdef ENABLE_UPGRADES + , + DetID::mask_t(math_utils::bit2Mask(DetID::IT3)), DetID::mask_t(math_utils::bit2Mask(DetID::TRK)), DetID::mask_t(math_utils::bit2Mask(DetID::FT3)) +#endif +}; +} // namespace detid_internal + +GPUdi() constexpr DetID::mask_t DetID::getMask(ID id) { return detid_internal::sMasks[id]; } + +} // namespace detectors +} // namespace o2 + +#endif diff --git a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID_REMOTE_450708.h b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID_REMOTE_450708.h new file mode 100644 index 0000000000000..2ee6a8ae0d623 --- /dev/null +++ b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID_REMOTE_450708.h @@ -0,0 +1,174 @@ +// 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. + +/// @brief ALICE detectors ID's, names, masks +/// +/// @author Ruben Shahoyan, ruben.shahoyan@cern.ch + +/*! + Example of class usage: + using namespace o2::base; + DetID det[3] = {DetID(DetID::ITS), DetID(DetID::TPC), DetID(DetID::TRD)}; + DetID::mask_t mskTot; + for (int i=0;i<3;i++) { + printf("detID: %2d %10s 0x%lx\n",det[i].getID(),det[i].getName(),det[i].getMask().to_ulong()); + mskTot |= det[i].getMask(); + } + printf("joint mask: 0x%lx\n",mskTot.to_ulong()); + */ + +#ifndef O2_BASE_DETID_ +#define O2_BASE_DETID_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "MathUtils/Utils.h" +#include "Headers/DataHeader.h" + +namespace o2 +{ +namespace detectors +{ + +namespace o2h = o2::header; + +/// Static class with identifiers, bitmasks and names for ALICE detectors +class DetID +{ + public: + /// Detector identifiers: continuous, starting from 0 + typedef std::int32_t ID; + + static constexpr ID ITS = 0; + static constexpr ID TPC = 1; + static constexpr ID TRD = 2; + static constexpr ID TOF = 3; + static constexpr ID PHS = 4; + static constexpr ID CPV = 5; + static constexpr ID EMC = 6; + static constexpr ID HMP = 7; + static constexpr ID MFT = 8; + static constexpr ID MCH = 9; + static constexpr ID MID = 10; + static constexpr ID ZDC = 11; + static constexpr ID FT0 = 12; + static constexpr ID FV0 = 13; + static constexpr ID FDD = 14; + static constexpr ID ACO = 15; + static constexpr ID CTP = 16; +#ifdef ENABLE_UPGRADES + static constexpr ID IT3 = 17; + static constexpr ID TRK = 18; + static constexpr ID FT3 = 19; + static constexpr ID PSR = 20; + static constexpr ID Last = PSR; +#else + static constexpr ID Last = CTP; ///< if extra detectors added, update this !!! +#endif + static constexpr ID First = ITS; + + static constexpr int nDetectors = Last + 1; ///< number of defined detectors + + static constexpr std::string_view NONE{"none"}; ///< keywork for no-detector + static constexpr std::string_view ALL{"all"}; ///< keywork for all detectors + + typedef std::bitset<32> mask_t; + + DetID(ID id) : mID(id) {} + DetID(const char* name); + DetID(const DetID& src) = default; + DetID& operator=(const DetID& src) = default; + + /// get derector id + ID getID() const { return mID; } + /// get detector mask + mask_t getMask() const { return getMask(mID); } + /// get detector mask + o2h::DataOrigin getDataOrigin() const { return getDataOrigin(mID); } + /// get detector name + const char* getName() const { return getName(mID); } + /// conversion operator to int + operator int() const { return static_cast(mID); } + + // ---------------- general static methods ----------------- + /// get number of defined detectors + static constexpr int getNDetectors() { return nDetectors; } + /// names of defined detectors + static constexpr const char* getName(ID id) { return sDetNames[id]; } + // detector ID to mask conversion + static constexpr mask_t getMask(ID id) { return sMasks[id]; } + // detector ID to DataOrigin conversions + static constexpr o2h::DataOrigin getDataOrigin(ID id) { return sOrigins[id]; } + + // detector masks from any non-alpha-num delimiter-separated list (empty if NONE is supplied) + static mask_t getMask(const std::string_view detList); + + static std::string getNames(mask_t mask, char delimiter = ','); + + // we need default c-tor only for root persistency, code must use c-tor with argument + DetID() : mID(First) {} + + private: + // are 2 strings equal ? (trick from Giulio) + inline static constexpr bool sameStr(char const* x, char const* y) + { + return !*x && !*y ? true : /* default */ (*x == *y && sameStr(x + 1, y + 1)); + } + + inline static constexpr int nameToID(char const* name, int id) + { + return id > Last ? id : sameStr(name, sDetNames[id]) ? id : nameToID(name, id + 1); + } + + ID mID = First; ///< detector ID + + 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", "CTP", "IT3", "TRK", "FT3", "PSR", nullptr}; +#else + {"ITS", "TPC", "TRD", "TOF", "PHS", "CPV", "EMC", "HMP", "MFT", "MCH", "MID", "ZDC", "FT0", "FV0", "FDD", "ACO", "CTP", nullptr}; +#endif + // detector names, will be defined in DataSources + static constexpr std::array sMasks = ///< detectot masks + {math_utils::bit2Mask(ITS), math_utils::bit2Mask(TPC), math_utils::bit2Mask(TRD), math_utils::bit2Mask(TOF), math_utils::bit2Mask(PHS), + math_utils::bit2Mask(CPV), math_utils::bit2Mask(EMC), math_utils::bit2Mask(HMP), math_utils::bit2Mask(MFT), math_utils::bit2Mask(MCH), + math_utils::bit2Mask(MID), math_utils::bit2Mask(ZDC), math_utils::bit2Mask(FT0), math_utils::bit2Mask(FV0), math_utils::bit2Mask(FDD), + math_utils::bit2Mask(ACO) +#ifdef ENABLE_UPGRADES + , + math_utils::bit2Mask(IT3), math_utils::bit2Mask(TRK), math_utils::bit2Mask(FT3), math_utils::bit2Mask(PSR) +#endif + }; + + static constexpr std::array + sOrigins = ///< detector data origins + {o2h::gDataOriginITS, o2h::gDataOriginTPC, o2h::gDataOriginTRD, o2h::gDataOriginTOF, o2h::gDataOriginPHS, + o2h::gDataOriginCPV, o2h::gDataOriginEMC, o2h::gDataOriginHMP, o2h::gDataOriginMFT, o2h::gDataOriginMCH, + o2h::gDataOriginMID, o2h::gDataOriginZDC, o2h::gDataOriginFT0, o2h::gDataOriginFV0, o2h::gDataOriginFDD, + o2h::gDataOriginACO, o2h::gDataOriginCTP +#ifdef ENABLE_UPGRADES + , + o2h::gDataOriginIT3, o2h::gDataOriginTRK, o2h::gDataOriginFT3, o2h::gDataOriginPSR +#endif + }; + + ClassDefNV(DetID, 2); +}; + +} // namespace detectors +} // namespace o2 + +#endif diff --git a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/SimTraits.h b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/SimTraits.h index 523d4e06ee94c..b4cf204326daa 100644 --- a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/SimTraits.h +++ b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/SimTraits.h @@ -93,7 +93,8 @@ class SimTraits , /*IT3*/ VS{ "IT3Hit" }, /*TRK*/ VS{ "TRKHit" }, - /*FT3*/ VS{ "FT3Hit" } + /*FT3*/ VS{ "FT3Hit" }, + /*PSR*/ VS{ "PSRHit" } #endif }; // clang-format on @@ -238,6 +239,11 @@ 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 356d6e78fea5c..de8816835d01c 100644 --- a/DataFormats/Detectors/Common/src/DetID.cxx +++ b/DataFormats/Detectors/Common/src/DetID.cxx @@ -33,6 +33,7 @@ constexpr DetID::ID DetID::ITS, DetID::TPC, DetID::TRD, DetID::TOF, DetID::PHS, constexpr DetID::ID DetID::IT3; constexpr DetID::ID DetID::TRK; constexpr DetID::ID DetID::FT3; +constexpr DetID::ID DetID::PSR; #endif constexpr int DetID::nDetectors; diff --git a/DataFormats/Headers/include/Headers/DataHeader.h b/DataFormats/Headers/include/Headers/DataHeader.h index 62afee27882bf..6f24bfd8bfc82 100644 --- a/DataFormats/Headers/include/Headers/DataHeader.h +++ b/DataFormats/Headers/include/Headers/DataHeader.h @@ -570,6 +570,7 @@ constexpr o2::header::DataOrigin gDataOriginZDC{"ZDC"}; constexpr o2::header::DataOrigin gDataOriginIT3{"IT3"}; constexpr o2::header::DataOrigin gDataOriginTRK{"TRK"}; constexpr o2::header::DataOrigin gDataOriginFT3{"FT3"}; +constexpr o2::header::DataOrigin gDataOriginPSR{"PSR"}; //possible data types constexpr o2::header::DataDescription gDataDescriptionAny{"***************"}; diff --git a/Detectors/Upgrades/ALICE3/CMakeLists.txt b/Detectors/Upgrades/ALICE3/CMakeLists.txt index 3aa6f4bbf613b..744d3d4dd67f1 100644 --- a/Detectors/Upgrades/ALICE3/CMakeLists.txt +++ b/Detectors/Upgrades/ALICE3/CMakeLists.txt @@ -12,4 +12,6 @@ add_subdirectory(Passive) add_subdirectory(TRK) add_subdirectory(FT3) +add_subdirectory(PSR) add_subdirectory(AOD) + diff --git a/Detectors/Upgrades/ALICE3/FT3/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/FT3/simulation/src/Detector.cxx index 6d3beabb4ded8..bffe4d9ba1899 100644 --- a/Detectors/Upgrades/ALICE3/FT3/simulation/src/Detector.cxx +++ b/Detectors/Upgrades/ALICE3/FT3/simulation/src/Detector.cxx @@ -160,7 +160,7 @@ void Detector::buildBasicFT3(const FT3BaseParam& param) mLayerID.clear(); mLayers.resize(2); - for (Int_t direction : {0, 1}) { + for (Int_t direction : {1}) { for (Int_t layerNumber = 0; layerNumber < mNumberOfLayers; layerNumber++) { std::string layerName = GeometryTGeo::getFT3LayerPattern() + std::to_string(layerNumber + mNumberOfLayers * direction); mLayerName[direction][layerNumber] = layerName; diff --git a/Detectors/Upgrades/ALICE3/PSR/CMakeLists.txt b/Detectors/Upgrades/ALICE3/PSR/CMakeLists.txt new file mode 100644 index 0000000000000..532a914632a0c --- /dev/null +++ b/Detectors/Upgrades/ALICE3/PSR/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/PSR/README.md b/Detectors/Upgrades/ALICE3/PSR/README.md new file mode 100644 index 0000000000000..981b04f7fc28b --- /dev/null +++ b/Detectors/Upgrades/ALICE3/PSR/README.md @@ -0,0 +1,13 @@ + + +# PostLS4EndCaps + +This is a simple 8 layered preshower detector named PSR. This is a cylindrical detector of length 100 cm whose shower layers are made up of Pb (0.5 cm) and the detector layers are made up of Si (45 microns). PSR is based on the ITSMFT classes and the code is structurally similar to that of FT3. Each layer is made of a monolithic silicon disk with a thin sensitive layer for hit generation. Silicon chip thickness is tuned to match the layer x/X0 to allow a minimal evaluation of material budget effects. + +One should get a file o2sim_HitsPSR.root by running +$ o2-sim -m PSR -e TGeant3 -g boxgen -n 10 + + diff --git a/Detectors/Upgrades/ALICE3/PSR/base/CMakeLists.txt b/Detectors/Upgrades/ALICE3/PSR/base/CMakeLists.txt new file mode 100644 index 0000000000000..88e6eff871f1b --- /dev/null +++ b/Detectors/Upgrades/ALICE3/PSR/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(PSRBase + SOURCES src/GeometryTGeo.cxx + PUBLIC_LINK_LIBRARIES O2::DetectorsBase O2::ITSMFTBase) + +o2_target_root_dictionary(PSRBase + HEADERS include/PSRBase/GeometryTGeo.h) diff --git a/Detectors/Upgrades/ALICE3/PSR/base/include/PSRBase/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/PSR/base/include/PSRBase/GeometryTGeo.h new file mode 100644 index 0000000000000..e73e3da231cf1 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/PSR/base/include/PSRBase/GeometryTGeo.h @@ -0,0 +1,122 @@ +// 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 +/// \author aabhishek.naath@gmail.com- adapted for Preshower 12/05/2021 + +#ifndef ALICEO2_PSR_GEOMETRYTGEO_H_ +#define ALICEO2_PSR_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 psr +{ +/// GeometryTGeo is a simple interface class to TGeoManager. It is used in the simulation +/// in order to query the TGeo Preshower 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 Preshower parameters from TGeo + void Build(int loadTrans = 0) override; + + void Print(Option_t* opt = "") const; + static const char* getPSRVolPattern() { return sVolumeName.c_str(); } + static const char* getPSRLayerPattern() { return sLayerName.c_str(); } + static const char* getPSRChipPattern() { return sChipName.c_str(); } + static const char* getPSRSensorPattern() { return sSensorName.c_str(); } + static const char* getPSRShowerlayerPattern() { return sShowerlayerName.c_str(); } + + static const char* composeSymNamePSR(Int_t d) { return Form("%s_%d", o2::detectors::DetID(o2::detectors::DetID::PSR).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); + static const char* composeSymNameShowerlayer(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 + static std::string sShowerlayerName; ///< Showerlayer name + + private: + static std::unique_ptr sInstance; ///< singletone instance + + ClassDefOverride(GeometryTGeo, 1); // Preshower geometry based on TGeo +}; +} // namespace psr +} // namespace o2 + +#endif diff --git a/Detectors/Upgrades/ALICE3/PSR/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/PSR/base/src/GeometryTGeo.cxx new file mode 100644 index 0000000000000..214453304612d --- /dev/null +++ b/Detectors/Upgrades/ALICE3/PSR/base/src/GeometryTGeo.cxx @@ -0,0 +1,120 @@ +// 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 +/// \author aabhishek.naath@gmail.com - adapted for ALICE3 preshower + +// ATTENTION: In opposite to old AliITSgeomTGeo, all indices start from 0, not from 1!!! + +#include "PSRBase/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::psr; +using namespace o2::detectors; + +ClassImp(o2::psr::GeometryTGeo); + +std::unique_ptr GeometryTGeo::sInstance; + +std::string GeometryTGeo::sVolumeName = "PSRV"; ///< Mother volume name +std::string GeometryTGeo::sLayerName = "PSRLayer"; ///< Layer name +std::string GeometryTGeo::sChipName = "PSRChip"; ///< Chip name +std::string GeometryTGeo::sSensorName = "PSRSensor"; ///< Sensor name +std::string GeometryTGeo::sShowerlayerName = "PSRShowerlayer"; ///< Showerlayer name + +//__________________________________________________________________________ +GeometryTGeo::GeometryTGeo(bool build, int loadTrans) : o2::itsmft::GeometryTGeo(DetID::PSR) +{ + // 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::psr::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", composeSymNamePSR(d), getPSRLayerPattern(), lr); +} + +//__________________________________________________________________________ +const char* GeometryTGeo::composeSymNameShowerlayer(Int_t d, Int_t lr) +{ + LOG(INFO) << "composenamelayer works_0"; + return Form("%s/%s%d", composeSymNameShowerlayer(d, lr), getPSRShowerlayerPattern(), lr); + LOG(INFO) << "composenamelayer works_1"; +} + +//__________________________________________________________________________ +const char* GeometryTGeo::composeSymNameChip(Int_t d, Int_t lr) +{ + return Form("%s/%s%d", composeSymNameLayer(d, lr), getPSRChipPattern(), lr); +} + +//__________________________________________________________________________ +const char* GeometryTGeo::composeSymNameSensor(Int_t d, Int_t lr) +{ + return Form("%s/%s%d", composeSymNameChip(d, lr), getPSRSensorPattern(), lr); +} + +//__________________________________________________________________________ +void GeometryTGeo::fillMatrixCache(int mask) +{ + // populate matrix cache for requested transformations + // +} diff --git a/Detectors/Upgrades/ALICE3/PSR/base/src/PSRBaseLinkDef.h b/Detectors/Upgrades/ALICE3/PSR/base/src/PSRBaseLinkDef.h new file mode 100644 index 0000000000000..7c8dbd8c78c28 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/PSR/base/src/PSRBaseLinkDef.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::psr::GeometryTGeo; + +#endif diff --git a/Detectors/Upgrades/ALICE3/PSR/simulation/CMakeLists.txt b/Detectors/Upgrades/ALICE3/PSR/simulation/CMakeLists.txt new file mode 100644 index 0000000000000..2f00ce608fca8 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/PSR/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(PSRSimulation + SOURCES src/PSRLayer.cxx + src/Detector.cxx + PUBLIC_LINK_LIBRARIES O2::PSRBase + O2::ITSMFTSimulation + ROOT::Physics) + +o2_target_root_dictionary(PSRSimulation + HEADERS include/PSRSimulation/Detector.h + include/PSRSimulation/PSRLayer.h) + +o2_data_file(COPY data DESTINATION Detectors/PSR/simulation) diff --git a/Detectors/Upgrades/ALICE3/PSR/simulation/data/simcuts.dat b/Detectors/Upgrades/ALICE3/PSR/simulation/data/simcuts.dat new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/Detectors/Upgrades/ALICE3/PSR/simulation/include/PSRSimulation/Detector.h b/Detectors/Upgrades/ALICE3/PSR/simulation/include/PSRSimulation/Detector.h new file mode 100644 index 0000000000000..1f28cbda8e40a --- /dev/null +++ b/Detectors/Upgrades/ALICE3/PSR/simulation/include/PSRSimulation/Detector.h @@ -0,0 +1,171 @@ +// 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_PSR_DETECTOR_H_ +#define ALICEO2_PSR_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 psr +{ +class GeometryTGeo; +} // namespace psr +} // namespace o2 +namespace o2 +{ +namespace psr +{ +class PSRLayer; +} +} // namespace o2 + +namespace o2 +{ +namespace psr +{ +class PSRLayer; + +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::PSR, 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 buildBasicPSR(int nLayers = 8, Float_t r_del = 0.5045, Float_t z_length = 400.0, Float_t RIn = 100.0, Float_t Pb_t = 0.5, Float_t Layerx2X0 = 0.0045); + void buildPSRV1(); + + 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 psr +} // 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/PSR/simulation/include/PSRSimulation/PSRLayer.h b/Detectors/Upgrades/ALICE3/PSR/simulation/include/PSRSimulation/PSRLayer.h new file mode 100644 index 0000000000000..0684376a5336c --- /dev/null +++ b/Detectors/Upgrades/ALICE3/PSR/simulation/include/PSRSimulation/PSRLayer.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 PSRLayer.h +/// \brief Definition of the PreshowerLayer class + +#ifndef ALICEO2_PSR_UPGRADEV3LAYER_H_ +#define ALICEO2_PSR_UPGRADEV3LAYER_H_ + +#include // for gGeoManager +#include "Rtypes.h" // for Double_t, Int_t, Bool_t, etc +#include "PSRSimulation/Detector.h" // for Detector, Detector::Model + +class TGeoVolume; + +namespace o2 +{ +namespace psr +{ + +/// This class defines the Geometry for the Preshower Layer TGeo. This is a work class used +/// to study different configurations during the development of the ALICE3 EndCaps +class PSRLayer : public TObject +{ + public: + // Default constructor + PSRLayer() = default; + + // Sample layer constructor (deleted option: Int_t layerDirection) + PSRLayer(Int_t layerDirection, Int_t layerNumber, std::string layerName, Float_t z, Float_t rIn, Float_t Pb_t, Float_t sensorThickness, Float_t Layerx2X0); + + /// Copy constructor + PSRLayer(const PSRLayer&) = default; + + /// Assignment operator + PSRLayer& operator=(const PSRLayer&) = default; + + /// Default destructor + ~PSRLayer() 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 mPb_thick; ///< Pb Layer thickness + 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 + //Double_t mThickness; ///< Thickness of the Pb layer + ClassDefOverride(PSRLayer, 0); // ALICE 3 EndCaps geometry +}; +} // namespace psr +} // namespace o2 + +#endif diff --git a/Detectors/Upgrades/ALICE3/PSR/simulation/src/Detector.cxx b/Detectors/Upgrades/ALICE3/PSR/simulation/src/Detector.cxx new file mode 100644 index 0000000000000..089e00ad9c05d --- /dev/null +++ b/Detectors/Upgrades/ALICE3/PSR/simulation/src/Detector.cxx @@ -0,0 +1,440 @@ +// 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 "PSRBase/GeometryTGeo.h" +#include "PSRSimulation/Detector.h" +#include "PSRSimulation/PSRLayer.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::psr; +using o2::itsmft::Hit; + +//_________________________________________________________________________________________________ +Detector::Detector() + : o2::base::DetImpl("PSR", kTRUE), + mTrackData(), + mHits(o2::utils::createSimVector()) +{ +} + +//_________________________________________________________________________________________________ +//void buildBasicPSR(int nLayers = 3, Float_t r_del = 20.0, Float_t z_length = 400.0, Float_t RIn = 100.0, Float_t Pb_t = 1.0, Float_t Layerx2X0 = .01); +void Detector::buildBasicPSR(int nLayers, Float_t r_del, Float_t z_length, Float_t RIn, Float_t Pb_t, Float_t Layerx2X0) +{ + // Build a basic parametrized PSR 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 : {1}) { + for (Int_t layerNumber = 0; layerNumber < mNumberOfLayers; layerNumber++) { + std::string layerName = GeometryTGeo::getPSRLayerPattern() + std::to_string(layerNumber + mNumberOfLayers * direction); + mLayerName[direction][layerNumber] = layerName; + + LOG(INFO) << "The program ran till here 1" << endl; + // Adds evenly spaced layers + float_t layerR = RIn + (layerNumber * r_del); + //PSRLayer::PSRLayer(Int_t layerDirection, Int_t layerNumber, std::string layerName, Float_t z, Float_t rIn, Float_t Pb_t, Float_t sensorThickness, Float_t Layerx2X0 + auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, z_length, layerR, Pb_t, sensorThickness, Layerx2X0); + } + } +} + +//_________________________________________________________________________________________________ +void Detector::buildPSRV1() +{ + + //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 PSR 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 : {1}) { + for (int layerNumber = 0; layerNumber < mNumberOfLayers; layerNumber++) { + std::string directionName = std::to_string(direction); + std::string layerName = GeometryTGeo::getPSRLayerPattern() + 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); + auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, z, rIn, rOut, thickness, x0); + } + } +} + +//_________________________________________________________________________________________________ +Detector::Detector(Bool_t active) + : o2::base::DetImpl("PSR", active), + mTrackData(), + mHits(o2::utils::createSimVector()) +{ + + LOG(INFO) << "The program ran till here 2" << endl; + buildBasicPSR(); // BasicPSR = Parametrized detector equidistant layers + //buildPSRV1(); // FT3V1 = Werner's layout +} + +//_________________________________________________________________________________________________ +Detector::Detector(const Detector& rhs) + : o2::base::DetImpl(rhs), + mTrackData(), + + /// Container for data points + mHits(o2::utils::createSimVector()) +{ + LOG(INFO) << "The program ran till here 3" << endl; + mLayerID = rhs.mLayerID; + mLayerName = rhs.mLayerName; + mNumberOfLayers = rhs.mNumberOfLayers; +} + +//_________________________________________________________________________________________________ +Detector::~Detector() +{ + + if (mHits) { + LOG(INFO) << "The program ran till here 4" << endl; + // 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; + LOG(INFO) << "The program ran till here 5" << endl; +} + +//_________________________________________________________________________________________________ +void Detector::InitializeO2Detector() +{ + // Define the list of sensitive volumes + LOG(INFO) << "Initialize Preshower O2Detector"; + + mGeometryTGeo = GeometryTGeo::Instance(); + + LOG(INFO) << "The program ran till here 6" << endl; + 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()); + } + + //LOG(INFO) << "The program ran till here 7" << endl; + return kTRUE; +} + +//_________________________________________________________________________________________________ +void Detector::createMaterials() +{ + LOG(INFO) << "The program ran till here 8" << endl; + 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(); + LOG(INFO) << "The program ran till here 9" << endl; + // Construct the detector geometry + createGeometry(); + LOG(INFO) << "The program ran till here 10" << endl; +} + +//_________________________________________________________________________________________________ +void Detector::createGeometry() +{ + LOG(INFO) << "The program ran till here 11" << endl; + mGeometryTGeo = GeometryTGeo::Instance(); + + TGeoVolume* volPSR = new TGeoVolumeAssembly(GeometryTGeo::getPSRVolPattern()); + + LOG(INFO) << "GeometryBuilder::buildGeometry volume name = " << GeometryTGeo::getPSRVolPattern(); + + 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 : {1}) { + + for (Int_t iLayer = 0; iLayer < mNumberOfLayers; iLayer++) { + mLayers[direction][iLayer].createLayer(volPSR); + } + } + vALIC->AddNode(volPSR, 1, new TGeoTranslation(0., 30., 0.)); + + for (auto direction : {1}) { + for (int iLayer = 0; iLayer < mNumberOfLayers; iLayer++) { + mLayerID[direction][iLayer] = gMC ? TVirtualMC::GetMC()->VolId(Form("%s_%d_%d", GeometryTGeo::getPSRSensorPattern(), 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; + + LOG(INFO) << "The program ran till here 12" << endl; + TString volumeName; + LOG(INFO) << "Adding Preshower Sensitive Volumes"; + // The names of the PSR sensitive volumes have the format: PSRSensor_(0,1)_(0...sNumberLayers-1) + for (Int_t direction : {1}) { + for (Int_t iLayer = 0; iLayer < mNumberOfLayers; iLayer++) { + volumeName = o2::psr::GeometryTGeo::getPSRSensorPattern() + std::to_string(iLayer); + v = geoManager->GetVolume(Form("%s_%d_%d", GeometryTGeo::getPSRSensorPattern(), direction, iLayer)); + LOG(INFO) << "Adding PSR 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::psr::Detector); diff --git a/Detectors/Upgrades/ALICE3/PSR/simulation/src/PSRLayer.cxx b/Detectors/Upgrades/ALICE3/PSR/simulation/src/PSRLayer.cxx new file mode 100644 index 0000000000000..69d76b2febbb2 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/PSR/simulation/src/PSRLayer.cxx @@ -0,0 +1,120 @@ +// 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 PSRLayer.cxx +/// \brief Implementation of the PSR Layer class +/// \author Mario Sitta +/// \author Chinorat Kobdaj (kobdaj@g.sut.ac.th) +/// \author Abhishek Nath (aabhishek.naath@gmail.com) + +#include "PSRSimulation/PSRLayer.h" +#include "PSRBase/GeometryTGeo.h" +#include "PSRSimulation/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::psr; +using namespace o2::itsmft; + +ClassImp(PSRLayer); + +PSRLayer::~PSRLayer() = default; + +// PSRLayer(Int_t layerDirection, Int_t layerNumber, std::string layerName, Float_t z, Float_t rIn, Float_t rOut, Float_t sensorThickness, Float_t Layerx2X0); +PSRLayer::PSRLayer(Int_t layerDirection, Int_t layerNumber, std::string layerName, Float_t z, Float_t rIn, Float_t Pb_t, 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; + mPb_thick = Pb_t; + + 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 PSR Layer " << mLayerNumber << ": z = " << mZ << " ; R_Pb = " << mInnerRadius << " ; R_Si = " << mInnerRadius + mPb_thick << " ; ChipThickness = " << mChipThickness; +} + +void PSRLayer::createLayer(TGeoVolume* motherVolume) +{ + if (mLayerNumber >= 0) { + LOG(INFO) << "CHECKING 2"; + // Create tube, set sensitive volume, add to mother volume + + std::string showerlayerName = o2::psr::GeometryTGeo::getPSRShowerlayerPattern() + std::to_string(mLayerNumber), + chipName = o2::psr::GeometryTGeo::getPSRChipPattern() + std::to_string(mLayerNumber), + sensName = Form("%s_%d_%d", GeometryTGeo::getPSRSensorPattern(), mDirection, mLayerNumber); + + TGeoTube* showerlayer = new TGeoTube(mInnerRadius, mInnerRadius + mPb_thick, mZ / 2); + TGeoTube* sensor = new TGeoTube(mInnerRadius + mPb_thick, mInnerRadius + mPb_thick + mSensorThickness, mZ / 2); + TGeoTube* chip = new TGeoTube(mInnerRadius + mPb_thick, mInnerRadius + mPb_thick + mChipThickness, mZ / 2); + TGeoTube* layer = new TGeoTube(mInnerRadius, mInnerRadius + mPb_thick + mChipThickness, mZ / 2); + + TGeoMedium* medSi = gGeoManager->GetMedium("PSR_SI$"); + TGeoMedium* medPb = gGeoManager->GetMedium("PSR_PB$"); + TGeoMedium* medAir = gGeoManager->GetMedium("PSR_AIR$"); + + TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi); + sensVol->SetVisibility(kTRUE); + sensVol->SetLineColor(2); + + TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi); + chipVol->SetVisibility(kTRUE); + chipVol->SetLineColor(3); + + TGeoVolume* showerlayerVol = new TGeoVolume(showerlayerName.c_str(), chip, medPb); + showerlayerVol->SetVisibility(kTRUE); + showerlayerVol->SetLineColor(4); + + TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir); + layerVol->SetVisibility(kTRUE); + layerVol->SetLineColor(5); + + 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); + + LOG(INFO) << "Inserting " << showerlayerVol->GetName() << " inside " << layerVol->GetName(); + layerVol->AddNode(showerlayerVol, 2, 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, nullptr); + + return; + } +} diff --git a/Detectors/Upgrades/ALICE3/PSR/simulation/src/PSRSimulationLinkDef.h b/Detectors/Upgrades/ALICE3/PSR/simulation/src/PSRSimulationLinkDef.h new file mode 100644 index 0000000000000..a81b9b3984f12 --- /dev/null +++ b/Detectors/Upgrades/ALICE3/PSR/simulation/src/PSRSimulationLinkDef.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::psr::PSRLayer + ; +#pragma link C++ class o2::psr::Detector + ; +#pragma link C++ class o2::base::DetImpl < o2::psr::Detector> + ; + +#endif diff --git a/macro/CMakeLists.txt b/macro/CMakeLists.txt index 97ffe710215e0..2b35df618eb1d 100644 --- a/macro/CMakeLists.txt +++ b/macro/CMakeLists.txt @@ -109,7 +109,7 @@ o2_add_test_root_macro(analyzeOriginHits.C O2::DetectorsCommonDataFormats) if(ENABLE_UPGRADES) - set(upgradeTargets O2::Alice3DetectorsPassive O2::ITS3Simulation O2::TRKSimulation O2::FT3Simulation) + set(upgradeTargets O2::Alice3DetectorsPassive O2::ITS3Simulation O2::TRKSimulation O2::FT3Simulation O2::PSRSimulation) endif() o2_add_test_root_macro(build_geometry.C diff --git a/macro/build_geometry.C b/macro/build_geometry.C index 0f6e749bfb407..3a2de33569af0 100644 --- a/macro/build_geometry.C +++ b/macro/build_geometry.C @@ -51,6 +51,7 @@ #include #include #include +#include #include #endif @@ -202,6 +203,11 @@ void build_geometry(FairRunSim* run = nullptr) auto ft3 = new o2::ft3::Detector(true); run->AddModule(ft3); } + if (isActivated("PSR")) { + // ALICE 3 PSR + auto psr = new o2::psr::Detector(true); + run->AddModule(psr); + } #endif if (isActivated("ITS")) { diff --git a/macro/duplicateHits.C b/macro/duplicateHits.C index f22b0957dea4f..73c8832321889 100644 --- a/macro/duplicateHits.C +++ b/macro/duplicateHits.C @@ -202,6 +202,7 @@ void duplicateHits(const char* filebase = "o2sim", const char* newfilebase = "o2 #ifdef ENABLE_UPGRADES duplicateV(grp, filebase, DetID::FT3, newfilebase, factor); + duplicateV(grp, filebase, DetID::PSR, newfilebase, factor); #endif // duplicateACO(reftree); diff --git a/run/CMakeLists.txt b/run/CMakeLists.txt index 315c033fc2ea3..333f85949e899 100644 --- a/run/CMakeLists.txt +++ b/run/CMakeLists.txt @@ -41,6 +41,7 @@ target_link_libraries(allsim $<$:O2::ITS3Simulation> $<$:O2::TRKSimulation> $<$:O2::FT3Simulation> + $<$:O2::PSRSimulation> O2::Generators) add_library(internal::allsim ALIAS allsim) diff --git a/run/O2HitMerger.h b/run/O2HitMerger.h index 7492cc8c6b1fb..6ddf39815e016 100644 --- a/run/O2HitMerger.h +++ b/run/O2HitMerger.h @@ -71,6 +71,7 @@ #include #include #include +#include #endif namespace o2 @@ -919,6 +920,10 @@ void O2HitMerger::initDetInstances() mDetectorInstances[i] = std::move(std::make_unique(true)); counter++; } + if (i == DetID::PSR) { + mDetectorInstances[i] = std::move(std::make_unique(true)); + counter++; + } #endif } if (counter != DetID::nDetectors) {