diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 7fa667426b023d1307b541fb9ed0f8921059f9b8..cf78e94fe012b5ce64d9e07e559eb83353b8d987 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -15,6 +15,7 @@ add_subdirectory(detectors/tof) add_subdirectory(detectors/sts) add_subdirectory(detectors/psd) add_subdirectory(detectors/fsd) +add_subdirectory(detectors/must) If(ROOT_opengl_FOUND) Message(STATUS "OpenGL support found. Build the eventdisplay.") diff --git a/core/data/CMakeLists.txt b/core/data/CMakeLists.txt index b5b59dd07855d9e7f8fb17bbd151c570757e7563..a3de47eb9f35db28bb52468d7ea208f792f19db8 100644 --- a/core/data/CMakeLists.txt +++ b/core/data/CMakeLists.txt @@ -15,6 +15,7 @@ set(INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/rich ${CMAKE_CURRENT_SOURCE_DIR}/psd ${CMAKE_CURRENT_SOURCE_DIR}/fsd + ${CMAKE_CURRENT_SOURCE_DIR}/must ${CMAKE_CURRENT_SOURCE_DIR}/global ) @@ -108,6 +109,8 @@ set(SRCS fsd/CbmFsdPoint.cxx fsd/CbmFsdAddress.cxx + must/CbmMustPoint.cxx + global/CbmGlobalTrack.cxx global/CbmVertex.cxx global/CbmTrackParam.cxx diff --git a/core/data/CbmDataLinkDef.h b/core/data/CbmDataLinkDef.h index b418995a9fd6172f5b98464b855627f419d9dd94..45b359ce4232c15ceaef9b26528813436053de80 100644 --- a/core/data/CbmDataLinkDef.h +++ b/core/data/CbmDataLinkDef.h @@ -109,6 +109,8 @@ #pragma link C++ namespace CbmFsdAddress; #pragma link C++ enum CbmFsdAddress::Level; +#pragma link C++ class CbmMustPoint + ; + // --- data/global #pragma link C++ class CbmGlobalTrack + ; #pragma link C++ class CbmVertex + ; diff --git a/core/data/CbmDefs.h b/core/data/CbmDefs.h index 3b89430788a80b85447bd31f14ab5f24206a1501..34fed8d8a091160479ab72eebdbb0ff88f10ff51 100644 --- a/core/data/CbmDefs.h +++ b/core/data/CbmDefs.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +/* Copyright (C) 2017-2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt SPDX-License-Identifier: GPL-3.0-only Authors: Florian Uhlig, Volker Friese [committer], Semen Lebedev */ @@ -44,19 +44,20 @@ enum class ECbmModuleId kMuch = 4, ///< Muon detection system kTrd = 5, ///< Transition Radiation Detector kTof = 6, ///< Time-of-flight Detector - kEcal = 7, ///< EM-Calorimeter + kMust = 7, ///< MuSt detection system kPsd = 8, ///< Projectile spectator detector kHodo = 9, ///< Hodoscope (for test beam times) kDummyDet = 10, ///< Dummy for tutorials or tests - kBmon = 11, //< Bmon Counter + kBmon = 11, ///< Bmon Counter kTrd2d = 12, ///< TRD-FASP Detector (FIXME) kFsd = 13, ///< Forward spectator detector kNofSystems = 14, ///< For loops over active systems + kEcal = 15, ///< EM-Calorimeter kMagnet = 17, ///< Magnet kTarget = 18, ///< Target kPipe = 19, ///< Beam pipe kShield = 20, ///< Beam pipe shielding in MUCH section - // kBmon = 21, ///< Bmon counter, hallo detector BMON + // kBmon = 21, ///< Bmon counter, halo detector BMON kPlatform = 21, ///< RICH rail platform kCave = 22, ///< Cave kLastModule = 23, ///< For loops over all modules @@ -111,6 +112,12 @@ enum class ECbmDataType kMuchPixelHit, kMuchStrawHit, kMuchTrack, // MUCH + kMustPoint = ToIntegralType(ECbmModuleId::kMust) * 100, + kMustDigi, + kMustCluster, + kMustPixelHit, + kMustStrawHit, + kMustTrack, // MUST kTrdPoint = ToIntegralType(ECbmModuleId::kTrd) * 100, kTrdDigi, kTrdCluster, diff --git a/core/data/must/CbmMustPoint.cxx b/core/data/must/CbmMustPoint.cxx new file mode 100644 index 0000000000000000000000000000000000000000..03b9b81ca66c1b7ecf78c269a8347403f09faac3 --- /dev/null +++ b/core/data/must/CbmMustPoint.cxx @@ -0,0 +1,107 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +// ------------------------------------------------------------------------- +// ----- CbmMustPoint source file ----- +// ----- Created 2024-11-26 by R. Karabowicz ----- +// ------------------------------------------------------------------------- + +#include "CbmMustPoint.h" + +#include "CbmDefs.h" // for kMCTrack +#include "FairLogger.h" +#include "math.h" + +#include <FairLink.h> // for FairLink +#include <FairMCPoint.h> // for FairMCPoint + +#include <iostream> +using std::cout; +using std::endl; + +// ----- Default constructor ------------------------------------------- +CbmMustPoint::CbmMustPoint() + : FairMCPoint() + , fX_out_local(0) + , fY_out_local(0) + , fZ_out_local(0) + , fX_in_local(0.) + , fY_in_local(0) + , fZ_in_local(0) + , fPx_out(0) + , fPy_out(0) + , fPz_out(0) + , fPx_in(0) + , fPy_in(0) + , fPz_in(0) + , fAddress(0) +{ +} +// ------------------------------------------------------------------------- + +// ----- Standard constructor ------------------------------------------ +CbmMustPoint::CbmMustPoint(Int_t trackID, Int_t detID, uint32_t address, TVector3 pos, TVector3 posInLocal, + TVector3 posOutLocal, TVector3 momIn, TVector3 momOut, Double_t tof, Double_t length, + Double_t eLoss) + : FairMCPoint(trackID, detID, pos, momIn, tof, length, eLoss) + , fX_out_local(posOutLocal.X()) + , fY_out_local(posOutLocal.Y()) + , fZ_out_local(posOutLocal.Z()) + , fX_in_local(posInLocal.X()) + , fY_in_local(posInLocal.Y()) + , fZ_in_local(posInLocal.Z()) + , fPx_out(momOut.Px()) + , fPy_out(momOut.Py()) + , fPz_out(momOut.Pz()) + , fPx_in(momIn.Px()) + , fPy_in(momIn.Py()) + , fPz_in(momIn.Pz()) + , fAddress(address) +{ + // reset MC momentum + fPx = (momIn.Px() + momOut.Px()) / 2.; + fPy = (momIn.Py() + momOut.Py()) / 2.; + fPz = (momIn.Pz() + momOut.Pz()) / 2.; + SetLink(FairLink(ToIntegralType(ECbmDataType::kMCTrack), trackID)); +} +// ------------------------------------------------------------------------- + +// ----- Destructor ---------------------------------------------------- +CbmMustPoint::~CbmMustPoint() {} +// ------------------------------------------------------------------------- + +// ----- Copy constructor ------------------------------------------ +CbmMustPoint::CbmMustPoint(const CbmMustPoint& point) + : FairMCPoint(point.fTrackID, point.fDetectorID, TVector3(point.fX, point.fY, point.fZ), + TVector3(point.fPx, point.fPy, point.fPz), point.fTime, point.fLength, point.fELoss, point.fEventId) + , fX_out_local(point.fX_out_local) + , fY_out_local(point.fY_out_local) + , fZ_out_local(point.fZ_out_local) + , fX_in_local(point.fX_in_local) + , fY_in_local(point.fY_in_local) + , fZ_in_local(point.fZ_in_local) + , fPx_out(point.fPx_out) + , fPy_out(point.fPy_out) + , fPz_out(point.fPz_out) + , fPx_in(point.fPx_in) + , fPy_in(point.fPy_in) + , fPz_in(point.fPz_in) + , fAddress(point.fAddress) +{ +} +// ------------------------------------------------------------------------- + +// ----- Public method Print ------------------------------------------- +void CbmMustPoint::Print(const Option_t* opt) const +{ + LOG(info) << " CbmMustPoint: MUST Point for track " << fTrackID << " in det/lay/mod/str " << fDetectorID << " / " + << fAddress; + LOG(info) << " Position (" << fX << ", " << fY << ", " << fZ << ") cm"; + LOG(info) << " Momentum (" << fPx << ", " << fPy << ", " << fPz << ") GeV"; + LOG(info) << " Time " << fTime << " ns, Length " << fLength << " cm, Energy loss " << fELoss * 1.0e06 << " keV" + << " opt=" << opt; +} +// ------------------------------------------------------------------------- + +ClassImp(CbmMustPoint) diff --git a/core/data/must/CbmMustPoint.h b/core/data/must/CbmMustPoint.h new file mode 100644 index 0000000000000000000000000000000000000000..e4d7a321a00ef45f4a03a68cca225a60fda804a6 --- /dev/null +++ b/core/data/must/CbmMustPoint.h @@ -0,0 +1,130 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +// ------------------------------------------------------------------------- +// ----- CbmMustPoint header file ----- +// ----- Created 2024-11-26 by R. Karabowicz ----- +// ------------------------------------------------------------------------- + +#ifndef CBMMUSTPOINT_H +#define CBMMUSTPOINT_H + +#include "FairMCPoint.h" +#include "TObject.h" +#include "TVector3.h" + +class CbmMustPoint : public FairMCPoint { + + public: + /** Default constructor **/ + CbmMustPoint(); + + /** Constructor with arguments + *@param trackID Index of MCTrack + *@param detID Detector ID + *@param address Detector address + *@param pos Coordinates at wire center of active volume [cm] + *@param posInLocal Local coordinates at entrance to active volume [cm] + *@param posOutLocal Local coordinates at exit of active volume [cm] + *@param momIn Momentum of track at entrance [GeV] + *@param momOut Momentum of track at exit [GeV] + *@param tof Time since event start [ns] + *@param length Track length since creation [cm] + *@param eLoss Energy deposit [GeV] + **/ + CbmMustPoint(Int_t trackID, Int_t detID, uint32_t address, TVector3 pos, TVector3 posInLocal, TVector3 posOutLocal, + TVector3 momIn, TVector3 momOut, Double_t tof, Double_t length, Double_t eLoss); + + /** Copy constructor **/ + CbmMustPoint(const CbmMustPoint& point); + + /** Destructor **/ + virtual ~CbmMustPoint(); + + // da cancellare + Double_t GetXtot() const { return GetX(); } + Double_t GetYtot() const { return GetY(); } + Double_t GetZtot() const { return GetZ(); } + + Double_t GetPxOut() const { return fPx_out; } + Double_t GetPyOut() const { return fPy_out; } + Double_t GetPzOut() const { return fPz_out; } + + ////// + + /** Accessors **/ + Double_t GetXOutLocal() const { return fX_out_local; } + Double_t GetYOutLocal() const { return fY_out_local; } + Double_t GetZOutLocal() const { return fZ_out_local; } + Double_t GetXInLocal() const { return fX_in_local; } + Double_t GetYInLocal() const { return fY_in_local; } + Double_t GetZInLocal() const { return fZ_in_local; } + + // Double_t GetXWireDirection() const { return fX_wire_dir; } + // Double_t GetYWireDirection() const { return fY_wire_dir; } + // Double_t GetZWireDirection() const { return fZ_wire_dir; } + + void PositionOutLocal(TVector3& pos) { pos.SetXYZ(fX_out_local, fY_out_local, fZ_out_local); } + void PositionInLocal(TVector3& pos) { pos.SetXYZ(fX_in_local, fY_in_local, fZ_in_local); } + void MomentumOut(TVector3& mom) { mom.SetXYZ(fPx_out, fPy_out, fPz_out); } + // void WireDirection(TVector3& wire) { wire.SetXYZ(fX_wire_dir, fY_wire_dir, fZ_wire_dir); } + + /** Modifiers **/ + void SetPositionOutLocal(TVector3 pos); + void SetPositionInLocal(TVector3 pos); + void SetMomentumOut(TVector3 mom); + // void SetWireDirection(TVector3 wire); + + Int_t GetStationId() const { return (fAddress >> 26) & 15; } + Int_t GetLayerId() const { return (fAddress >> 24) & 3; } + Int_t GetModuleId() const { return (fAddress >> 18) & 63; } + Int_t GetStrawId() const { return (fAddress >> 11) & 127; } + + /** Output to screen **/ + virtual void Print(const Option_t* opt) const; + + protected: + // exit coordinates in straw frame + Double_t fX_out_local, fY_out_local, fZ_out_local; + // entry coordinates in straw frame + Double_t fX_in_local, fY_in_local, fZ_in_local; + + Double_t fPx_out, fPy_out, fPz_out; + Double_t fPx_in, fPy_in, fPz_in; + + // Address composition: + // 4 bits 0 - 3 kMust ??? + // 2 bits 4 - 5 station id (0...3) + // 2 bits 6 - 7 layer id (0...3) in module + // 6 bits 8 - 13 module id (0...63) in layer + // 7 bits 14 - 20 straw id (0...127) in straw + uint32_t fAddress{0}; + + ////// + + ClassDef(CbmMustPoint, 1) +}; + +inline void CbmMustPoint::SetPositionOutLocal(TVector3 pos) +{ + fX_out_local = pos.X(); + fY_out_local = pos.Y(); + fZ_out_local = pos.Z(); +} + +inline void CbmMustPoint::SetPositionInLocal(TVector3 pos) +{ + fX_in_local = pos.X(); + fY_in_local = pos.Y(); + fZ_in_local = pos.Z(); +} + +inline void CbmMustPoint::SetMomentumOut(TVector3 mom) +{ + fPx_out = mom.Px(); + fPy_out = mom.Py(); + fPz_out = mom.Pz(); +} + +#endif diff --git a/core/detectors/must/CMakeLists.txt b/core/detectors/must/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..9a533cd7636454099257879d5e5a9b85e03a9558 --- /dev/null +++ b/core/detectors/must/CMakeLists.txt @@ -0,0 +1,48 @@ +set(INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_SOURCE_DIR} + ) + + +set(SRCS + CbmGeoMust.cxx + CbmGeoMustPar.cxx + CbmMustContFact.cxx + CbmMustGeoScheme.cxx + CbmMustStation.cxx + CbmMustLayer.cxx + CbmMustModule.cxx + CbmMustTube.cxx +) + + +# ---- Enable OpenMP ------------------------------------- +find_package(OpenMP) +if (OPENMP_FOUND) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") +endif() +# --------------------------------------------------------- + +set(LIBRARY_NAME CbmMustBase) +set(LINKDEF ${LIBRARY_NAME}LinkDef.h) +set(PUBLIC_DEPENDENCIES + FairRoot::Base + FairRoot::ParBase + CbmBase + ROOT::Core + ROOT::Geom + ROOT::Gpad + ROOT::Hist + ROOT::MathCore + ROOT::Physics + ) + +set(PRIVATE_DEPENDENCIES + FairLogger::FairLogger + CbmData + ROOT::Graf + ROOT::MLP + ROOT::Tree + ) + +generate_cbm_library() diff --git a/core/detectors/must/CbmGeoMust.cxx b/core/detectors/must/CbmGeoMust.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8780a3fe1fe66653217d6e5c2f9d2ccfc1a26414 --- /dev/null +++ b/core/detectors/must/CbmGeoMust.cxx @@ -0,0 +1,45 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmGeoMust source file +// +// Class for geometry of MUST +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmGeoFts by Nafija Ibrisimovic in 2023 +//////////////////////////////////////////////////////////////////////////// + +#include "CbmGeoMust.h" +// from FairRoot +#include <FairGeoNode.h> +// from fmt +#include <fmt/core.h> + +ClassImp(CbmGeoMust) + + CbmGeoMust::CbmGeoMust() +{ + // Constructor + fName = "must"; + maxSectors = 0; + maxModules = 40; +} + +const char* CbmGeoMust::getModuleName(Int_t m) +{ + // Returns the module name of MUST number m + modName = fmt::format("must{:02d}", m + 1); + + return modName.c_str(); +} + +const char* CbmGeoMust::getEleName(Int_t m) +{ + // Returns the element name of MUST number m + eleName = fmt::format("must{:02d}", m + 1); + + return eleName.c_str(); +} diff --git a/core/detectors/must/CbmGeoMust.h b/core/detectors/must/CbmGeoMust.h new file mode 100644 index 0000000000000000000000000000000000000000..fbeca29fb257f152cec0f607cf0c7408cecd4958 --- /dev/null +++ b/core/detectors/must/CbmGeoMust.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmGeoMust header file +// +// Class for geometry of MUST +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmGeoFts by Nafija Ibrisimovic in 2023 +//////////////////////////////////////////////////////////////////////////// + +#ifndef CBMGEOMUST_H +#define CBMGEOMUST_H + +// from FairRoot +#include <FairGeoSet.h> + +class CbmGeoMust : public FairGeoSet { + protected: + std::string modName; // name of module + std::string eleName; // substring for elements in module + public: + CbmGeoMust(); + ~CbmGeoMust() {} + const char* getModuleName(Int_t); + const char* getEleName(Int_t); + inline Int_t getModNumInMod(const TString&); + ClassDef(CbmGeoMust, 0) // Class for Must +}; + +inline Int_t CbmGeoMust::getModNumInMod(const TString& name) +{ + // returns the module index from module name + + return (Int_t)(name[2] - '0') - 1; +} + +#endif /* !CBMGEOMUST_H */ diff --git a/core/detectors/must/CbmGeoMustPar.cxx b/core/detectors/must/CbmGeoMustPar.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1f79bf4e9a68adf0362698ad376341348a3331b9 --- /dev/null +++ b/core/detectors/must/CbmGeoMustPar.cxx @@ -0,0 +1,68 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmGeoMustPar source file +// +// Class for geometry parameters of MUST +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmGeoFtsPar by Nafija Ibrisimovic in 2023 +//////////////////////////////////////////////////////////////////////////// + +#include "CbmGeoMustPar.h" +// from FairRoot +#include <FairParamList.h> +// standard +#include <iomanip> +#include <iostream> + +ClassImp(CbmGeoMustPar) + + CbmGeoMustPar::CbmGeoMustPar(const char* name, const char* title, const char* context) + : FairParGenericSet(name, title, context) + , fGeoSensNodes(new TObjArray()) + , fGeoPassNodes(new TObjArray()) + , fGeoType(-1) + , fTubeInRad(0) + , fTubeOutRad(0) +{ +} + +CbmGeoMustPar::~CbmGeoMustPar(void) {} + +void CbmGeoMustPar::clear(void) +{ + if (fGeoSensNodes) { + fGeoSensNodes->Delete(); + delete fGeoSensNodes; + } + if (fGeoPassNodes) { + fGeoPassNodes->Delete(); + delete fGeoPassNodes; + } +} + +void CbmGeoMustPar::putParams(FairParamList* l) +{ + if (!l) return; + l->addObject("FairGeoNodes Sensitive List", fGeoSensNodes); + l->addObject("FairGeoNodes Passive List", fGeoPassNodes); + l->add("Tube Innen Radius", fTubeInRad); + l->add("Tube Outer Radius", fTubeOutRad); + l->add("Geometry Type", fGeoType); +} + +Bool_t CbmGeoMustPar::getParams(FairParamList* l) +{ + if (!l) return kFALSE; + if (!l->fillObject("FairGeoNodes Sensitive List", fGeoSensNodes)) return kFALSE; + if (!l->fillObject("FairGeoNodes Passive List", fGeoPassNodes)) return kFALSE; + if (!l->fill("Tube Innen Radius", &fTubeInRad)) return kFALSE; + if (!l->fill("Tube Outer Radius", &fTubeOutRad)) return kFALSE; + if (!l->fill("Geometry Type", &fGeoType)) return kFALSE; + + return kTRUE; +} diff --git a/core/detectors/must/CbmGeoMustPar.h b/core/detectors/must/CbmGeoMustPar.h new file mode 100644 index 0000000000000000000000000000000000000000..dd6d6c2129502335de8347175eff2b398db27c8a --- /dev/null +++ b/core/detectors/must/CbmGeoMustPar.h @@ -0,0 +1,54 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmGeoMustPar header file +// +// Class for geometry parameters of MUST +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmGeoFtsPar by Nafija Ibrisimovic in 2023 +//////////////////////////////////////////////////////////////////////////// + +#ifndef CBMGEOMUSTPAR_H +#define CBMGEOMUSTPAR_H +// from FairRoot +#include <FairParGenericSet.h> +// from ROOT +#include <TH1F.h> +#include <TObjArray.h> + +class CbmGeoMustPar : public FairParGenericSet { + private: + TObjArray* fGeoSensNodes; /** List of FairGeoNodes for sensitive volumes*/ + TObjArray* fGeoPassNodes; /** List of FairGeoNodes for sensitive volumes*/ + Int_t fGeoType; // modif + Double_t fTubeInRad, fTubeOutRad; // modif + + CbmGeoMustPar(const CbmGeoMustPar& L); + CbmGeoMustPar& operator=(const CbmGeoMustPar&) { return *this; } + + public: + CbmGeoMustPar(const char* name = "CbmGeoMustPar", const char* title = "Must Geometry Parameters", + const char* context = "TestDefaultContext"); + ~CbmGeoMustPar(void); + void clear(void); + void putParams(FairParamList*); + Bool_t getParams(FairParamList*); + TObjArray* GetGeoSensitiveNodes() { return fGeoSensNodes; } + TObjArray* GetGeoPassiveNodes() { return fGeoPassNodes; } + + // Additional function + void SetGeometryType(Int_t geoType) { fGeoType = geoType; } + void SetTubeInRad(Double_t inrad) { fTubeInRad = inrad; } + void SetTubeOutRad(Double_t outrad) { fTubeOutRad = outrad; } + Int_t GetGeometryType() { return (Int_t) fGeoType; }; + Double_t GetTubeInRad() { return (Double_t) fTubeInRad; }; + Double_t GetTubeOutRad() { return (Double_t) fTubeOutRad; }; + + ClassDef(CbmGeoMustPar, 1) +}; + +#endif /* !CBMGEOMUSTPAR_H */ diff --git a/core/detectors/must/CbmMustBaseLinkDef.h b/core/detectors/must/CbmMustBaseLinkDef.h new file mode 100644 index 0000000000000000000000000000000000000000..d994d020bb603d003b6cc4249094991fa3c225cd --- /dev/null +++ b/core/detectors/must/CbmMustBaseLinkDef.h @@ -0,0 +1,20 @@ +/* Copyright (C) 2020-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese [committer] */ + +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class CbmGeoMust + ; +#pragma link C++ class CbmGeoMustPar + ; +#pragma link C++ class CbmMustContFact + ; +#pragma link C++ class CbmMustGeoScheme + ; +#pragma link C++ class CbmMustStation + ; +#pragma link C++ class CbmMustLayer + ; +#pragma link C++ class CbmMustModule + ; +#pragma link C++ class CbmMustTube + ; + +#endif /* __CINT__ */ diff --git a/core/detectors/must/CbmMustContFact.cxx b/core/detectors/must/CbmMustContFact.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ae816b670e16aa220e1824459c502aac77ca2ce4 --- /dev/null +++ b/core/detectors/must/CbmMustContFact.cxx @@ -0,0 +1,61 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmMustContFact source file +// +// Factory for the parameter containers in libMust +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmMustContFact by Nafija Ibrisimovic in 2023 +//////////////////////////////////////////////////////////////////////////// + +#include "CbmMustContFact.h" +// from CbnRoot, this library +#include "CbmGeoMustPar.h" +// from FairRoot +#include <FairParAsciiFileIo.h> +#include <FairParRootFileIo.h> +#include <FairRuntimeDb.h> +// standard +#include <iomanip> +#include <iostream> + +ClassImp(CbmMustContFact) + + static CbmMustContFact gCbmMustContFact; + +CbmMustContFact::CbmMustContFact() +{ + // Constructor (called when the library is loaded) + fName = "CbmMustContFact"; + fTitle = "Factory for parameter containers in libMust"; + setAllContainers(); + FairRuntimeDb::instance()->addContFactory(this); +} + +void CbmMustContFact::setAllContainers() +{ + /** Creates the Container objects with all accepted contexts and adds them to + * the list of containers for the MUST library.*/ + FairContainer* p1 = new FairContainer("CbmGeoMustPar", "Must Geometry Parameters", "TestDefaultContext"); + p1->addContext("TestNonDefaultContext"); + containers->Add(p1); +} + +FairParSet* CbmMustContFact::createContainer(FairContainer* c) +{ + /** Calls the constructor of the corresponding parameter container. + * For an actual context, which is not an empty string and not the default context + * of this container, the name is concatinated with the context. */ + const char* name = c->GetName(); + std::cout << "[MUST] CbmMustContFact createContainer name " << name << std::endl; + FairParSet* p = 0; + + if (strcmp(name, "CbmGeoMustPar") == 0) { + p = new CbmGeoMustPar(c->getConcatName().Data(), c->GetTitle(), c->getContext()); + } + return p; +} diff --git a/core/detectors/must/CbmMustContFact.h b/core/detectors/must/CbmMustContFact.h new file mode 100644 index 0000000000000000000000000000000000000000..b8db38e32bc7e70ec661cd28ad2abeb7bd844333 --- /dev/null +++ b/core/detectors/must/CbmMustContFact.h @@ -0,0 +1,35 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmMustContFact header file +// +// Factory for the parameter containers in libMust +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmMustContFact by Nafija Ibrisimovic in 2023 +//////////////////////////////////////////////////////////////////////////// + +#ifndef CBMMUSTCONTFACT_H +#define CBMMUSTCONTFACT_H + +// from FairRoot +#include <FairContFact.h> + +class FairContainer; + +class CbmMustContFact : public FairContFact { + private: + void setAllContainers(); + + public: + CbmMustContFact(); + ~CbmMustContFact() {} + FairParSet* createContainer(FairContainer*); + // void activateParIo(FairParIo* io); + ClassDef(CbmMustContFact, 0) // Factory for all MUST parameter containers +}; + +#endif /* !CBMMUSTCONTFACT_H */ diff --git a/core/detectors/must/CbmMustGeoScheme.cxx b/core/detectors/must/CbmMustGeoScheme.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f312fad6369f9b893084dd74a4a8ce45a5a96133 --- /dev/null +++ b/core/detectors/must/CbmMustGeoScheme.cxx @@ -0,0 +1,222 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +/** CbmMustGeoScheme + *@author R.Karabowicz <r.karabowicz@gsi.de> + *@version 1.0 + *@since 2025.01.08 + ** + ** Based on CbmMuchGeoScheme by Evgeny Kryshen <e.kryshen@gsi.de> + ** + **/ +#include "CbmMustGeoScheme.h" + +#include "CbmDefs.h" +#include "CbmMustLayer.h" // for CbmMustLayer +#include "CbmMustModule.h" +#include "CbmMustStation.h" // for CbmMustStation +#include "CbmMustTube.h" + +#include <Logger.h> // for LOG + +#include <TArrayD.h> // for TArrayD +#include <TArrayI.h> // for TArrayI +#include <TClonesArray.h> // for TClonesArray +#include <TFile.h> // for TFile, gFile +#include <TGeoBBox.h> // for TGeoBBox +#include <TGeoManager.h> // for TGeoManager, gGeoManager +#include <TGeoNode.h> // for TGeoNode +#include <TGeoTube.h> // for TGeoTube +#include <TGeoVolume.h> // for TGeoVolume +#include <TKey.h> // for TKey +#include <TMath.h> // for Cos, Sqrt +#include <TObject.h> // for TObject +#include <TVector3.h> // for TVector3 + +#include <bitset> // for bitset +#include <cassert> // for assert +#include <stdexcept> // for out_of_range +#include <utility> // for pair +#include <vector> + +#include <math.h> // for sqrt + +using std::vector; + +CbmMustGeoScheme* CbmMustGeoScheme::fInstance = nullptr; + +// ------------------------------------------------------------------------- +CbmMustGeoScheme::CbmMustGeoScheme() : TObject() { LOG(debug) << "CbmMustGeoScheme created"; } +// ------------------------------------------------------------------------- + +// ------------------------------------------------------------------------- +CbmMustGeoScheme::~CbmMustGeoScheme() +{ + + if (fInstance != nullptr) delete fInstance; +} +// ------------------------------------------------------------------------- + + +// ------------------------------------------------------------------------- +CbmMustGeoScheme* CbmMustGeoScheme::Instance() +{ + + if (!fInstance) fInstance = new CbmMustGeoScheme(); + return fInstance; +} +// ------------------------------------------------------------------------- + +// ------------------------------------------------------------------------- +void CbmMustGeoScheme::Init(std::vector<CbmMustStation*> stations) +{ + if (!fInitialized) { + fStations = stations; + fInitialized = kTRUE; + } + LOG(debug) << "CbmMustGeoScheme init successful"; +} +// ------------------------------------------------------------------------- + +// ------------------------------------------------------------------------- +void CbmMustGeoScheme::Init(TString parFileName) +{ + /// Save old global file and folder pointer to avoid messing with FairRoot + TFile* oldFile = gFile; + TDirectory* oldDir = gDirectory; + + TFile* file = new TFile(parFileName); + LOG_IF(fatal, !file) << "File " << parFileName << " does not exist"; + for (auto&& keyAsObj : *file->GetListOfKeys()) { + auto key = (TKey*) keyAsObj; + fStations.push_back(static_cast<CbmMustStation*>(key->ReadObj())); + } + file->Close(); + file->Delete(); + + /// Restore old global file and folder pointer to avoid messing with FairRoot + gFile = oldFile; + gDirectory = oldDir; +} +// ------------------------------------------------------------------------- + +// ------------------------------------------------------------------------- +uint32_t CbmMustGeoScheme::GetAddress(int statId, int layId, int modId, int strawId) +{ + // Address composition: + // 4 bits 0 - 3 kMust ??? + // 2 bits 4 - 5 station id (0...3) + // 2 bits 6 - 7 layer id (0...3) in module + // 6 bits 8 - 13 module id (0...63) in layer + // 7 bits 14 - 20 straw id (0...127) in straw + + uint32_t address{static_cast<uint32_t>(ECbmModuleId::kMust)}; + + address = address << 2; + address += statId; + address = address << 2; + address += layId; + address = address << 6; + address += modId; + address = address << 7; + address += strawId; + address = address << 11; + std::bitset<32> x(address); + LOG(debug) << " D S L M S E"; + LOG(debug) << x; + return address; +} +// ------------------------------------------------------------------------- + +// ------------------------------------------------------------------------- +CbmMustStation* CbmMustGeoScheme::GetStation(int iStation) const +{ + Bool_t result = (iStation >= 0) || (iStation < (int) fStations.size()); + + return result ? (CbmMustStation*) fStations.at(iStation) : nullptr; +} +// ------------------------------------------------------------------------- + +CbmMustStation* CbmMustGeoScheme::FindStation(int detid) +{ + for (const auto tempStation : fStations) { + if (tempStation->GetDetectorId() == detid) return tempStation; + } + return nullptr; +} + +CbmMustTube* CbmMustGeoScheme::GetTube(int detid) +{ + int stationid = detid / 1e7 - 1; + CbmMustStation* tempStat = GetStation(stationid); + // LOG(info) << "trying to get tube " << detid % 10000000 << " from station " << stationid; + return tempStat ? tempStat->GetTube(detid % 10000000) : nullptr; +} + +bool CbmMustGeoScheme::AddStation(CbmMustStation* station) +{ + for (const auto tempStation : fStations) { + if (tempStation->GetDetectorId() == station->GetDetectorId()) return false; + } + + fStations.push_back(station); + return true; +} + +void CbmMustGeoScheme::Show() +{ + LOG(info) << "MustGeoScheme:"; + for (const auto tempStation : fStations) { + tempStation->Show(); + } +} + +// ------------------------------------------------------------------------- +void CbmMustGeoScheme::StoreGeoScheme() +{ + + /// Save old global file and folder pointer to avoid messing with FairRoot + TFile* oldFile = gFile; + TDirectory* oldDir = gDirectory; + + std::string geoSchemeFileName("must_geoScheme.root"); + TFile* file = new TFile(geoSchemeFileName.c_str(), "recreate"); + LOG_IF(fatal, !file) << "File " << geoSchemeFileName << " does not exist"; + auto istat{1}; + for (const auto tempStation : fStations) { + LOG(info) << "Store station" << istat << " at z=" << tempStation->GetZ() << "cm with " << tempStation->GetNLayers() + << " layers"; + file->WriteObject(tempStation, Form("station%d", istat)); + istat++; + } + file->Close(); + file->Delete(); + + /// Restore old global file and folder pointer to avoid messing with FairRoot + gFile = oldFile; + gDirectory = oldDir; +} +// ------------------------------------------------------------------------- +CbmMustLayer* CbmMustGeoScheme::GetLayer(int iStation, int iLayer) const +{ + CbmMustStation* station = GetStation(iStation); + return station ? station->GetLayer(iLayer) : nullptr; +} +// ------------------------------------------------------------------------- + +// ------------------------------------------------------------------------- +void CbmMustGeoScheme::NavigateTo(const TString& path) +{ + gGeoManager->cd(path.Data()); + // fGeoPathHash; + // fGeoPathHash = path.Hash(); + // TGeoVolume* fCurrentVolume = gGeoManager->GetCurrentVolume(); + // TGeoBBox* fVolumeBoxShape = (TGeoBBox*) fCurrentVolume->GetShape(); + Double_t local[3] = {0., 0., 0.}; + gGeoManager->LocalToMaster(local, fGlobal); + // LOG(info) << "position: " << fGlobal[0] << "," << fGlobal[1] << "," << fGlobal[2]; +} +// ------------------------------------------------------------------------- + +ClassImp(CbmMustGeoScheme) diff --git a/core/detectors/must/CbmMustGeoScheme.h b/core/detectors/must/CbmMustGeoScheme.h new file mode 100644 index 0000000000000000000000000000000000000000..80ac07f4241936efc92df809a329b285a2a30971 --- /dev/null +++ b/core/detectors/must/CbmMustGeoScheme.h @@ -0,0 +1,96 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +// ------------------------------------------------------------------------- +// ----- CbmMustGeoScheme header file ----- +// ----- Created 18/02/08 by E. Kryshen ----- +// ----- Modified 08/01/2025 by R. Karabowicz ----- +// ------------------------------------------------------------------------- + +/** CbmMustGeoScheme + *@author R.Karabowicz <r.karabowicz@gsi.de> + *@version 1.0 + *@since 2025.01.08 + ** + ** Based on CbmMuchGeoScheme by Evgeny Kryshen <e.kryshen@gsi.de> + ** + **/ + +#ifndef CbmMustGeoScheme_H +#define CbmMustGeoScheme_H 1 + +#include <Rtypes.h> // for THashConsistencyHolder, ClassDef +#include <RtypesCore.h> // for Int_t, Double_t, Bool_t, Float_t, Char_t +#include <TArrayC.h> // for TArrayC +#include <TArrayD.h> // for TArrayD +#include <TArrayI.h> // for TArrayI +#include <TGeoBBox.h> // for TGeoBBox +#include <TGeoCone.h> // for TGeoCone +#include <TObject.h> // for TObject +#include <TString.h> // for TString +#include <TVector3.h> // for TVector3 + +#include <map> // for map +#include <vector> // for vector + +class CbmMustTube; +class CbmMustLayer; +class CbmMustModule; +class CbmMustStation; +class TGeoHMatrix; +class TGeoNode; +class TGeoTrap; +class TGeoVolume; + +class CbmMustGeoScheme : public TObject { + + public: + /** Destructor. */ + ~CbmMustGeoScheme(); + //void Init(Bool_t isSimulation = kFALSE); + static CbmMustGeoScheme* Instance(); + /** Gets whether the geometry scheme is initialized. */ + Bool_t IsInitialized() { return fInitialized; } + + // Get geometry objects by indices + std::vector<CbmMustStation*> GetStations() const { return fStations; }; + CbmMustStation* GetStation(int iStation) const; + CbmMustLayer* GetLayer(int iStation, int iLayer) const; + + uint32_t GetAddress(int statId, int layId, int modId, int strawId); + + int GetNStations() const { return fStations.size(); } + + CbmMustTube* GetTube(int detid); + + CbmMustStation* FindStation(int detid); + bool AddStation(CbmMustStation* station); + void Show(); + void StoreGeoScheme(); + + void Init(std::vector<CbmMustStation*> stations); + void Init(TString parFileName); + + void NavigateTo(const TString& path); + // void NavigateToBBox(const TString& path); + // void NavigateToTube(const TString& path); + + TVector3 GetGlobal() { return TVector3(fGlobal); } + + private: + static CbmMustGeoScheme* fInstance; + + CbmMustGeoScheme(); + + bool fInitialized{false}; //! + std::vector<CbmMustStation*> fStations; + double fGlobal[3]{0., 0., 0.}; + + CbmMustGeoScheme(const CbmMustGeoScheme&); + CbmMustGeoScheme& operator=(const CbmMustGeoScheme&); + + ClassDef(CbmMustGeoScheme, 1); +}; + +#endif diff --git a/core/detectors/must/CbmMustLayer.cxx b/core/detectors/must/CbmMustLayer.cxx new file mode 100644 index 0000000000000000000000000000000000000000..66b7e60560956377ed59b895ce929d4673e49707 --- /dev/null +++ b/core/detectors/must/CbmMustLayer.cxx @@ -0,0 +1,86 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +/** CbmMustLayer.cxx + *@author R.Karabowicz <r.karabowicz@gsi.de> + *@version 1.0 + *@since 2025.01.08 + ** + ** This class holds the transport geometry parameters + ** of one MuST tracking layer. + ** Based on CbmMuchLayer by M.Ryzhinskiy <m.ryzhinskiy@gsi.de> + ** + **/ +#include "CbmMustLayer.h" + +#include <Logger.h> // for LOG + +#include <TMathBase.h> // for Abs +#include <TObject.h> // for TObject +#include <TVector3.h> // for TVector3 + +// ----- Default constructor ------------------------------------------- +CbmMustLayer::CbmMustLayer() : TObject() {} +// ------------------------------------------------------------------------- + +// ----- Standard constructor ------------------------------------------ +CbmMustLayer::CbmMustLayer(int detId, double z, double zRel) + : TObject() + , fDetectorId(detId) + , fZ(z) + , fZtoStationCenter(zRel) +{ +} +// ------------------------------------------------------------------------- + +// ----- Standard constructor ------------------------------------------ +CbmMustLayer::CbmMustLayer(int iStation, int iLayer, double z, double zRel) + : TObject() + , fDetectorId(iStation * 1e7 + iLayer * 1e5) + , fZ(z) + , fZtoStationCenter(zRel) + +{ +} +// ------------------------------------------------------------------------- + +// ----- Destructor ---------------------------------------------------- +CbmMustLayer::~CbmMustLayer() {} +// ------------------------------------------------------------------------- + +CbmMustTube* CbmMustLayer::GetTube(int detid) +{ + int moduleid = detid / 1e3 - 1; + CbmMustModule* tempModule = GetModule(moduleid); + // LOG(info) << "trying to get tube " << detid % 1000 << " from module " << moduleid; + return tempModule ? tempModule->GetTube(detid % 1000 - 1) : nullptr; +} + +CbmMustModule* CbmMustLayer::FindModule(int detid) +{ + for (const auto tempModule : fModules) { + if (tempModule->GetDetectorId() == detid) return tempModule; + } + return nullptr; +} + +bool CbmMustLayer::AddModule(CbmMustModule* module) +{ + for (const auto tempModule : fModules) { + if (tempModule->GetDetectorId() == module->GetDetectorId()) return false; + } + + fModules.push_back(module); + return true; +} + +void CbmMustLayer::Show() +{ + LOG(info) << " Layer " << fDetectorId << " (@ z = " << fZ << "):"; + for (const auto tempModule : fModules) { + tempModule->Show(); + } +} + +ClassImp(CbmMustLayer) diff --git a/core/detectors/must/CbmMustLayer.h b/core/detectors/must/CbmMustLayer.h new file mode 100644 index 0000000000000000000000000000000000000000..6b2901532b2ce83bb5f495130e411b850b845634 --- /dev/null +++ b/core/detectors/must/CbmMustLayer.h @@ -0,0 +1,77 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +/** CbmMustLayer.h + *@author R.Karabowicz <r.karabowicz@gsi.de> + *@version 1.0 + *@since 2025.01.08 + ** + ** This class holds the transport geometry parameters + ** of one MuST tracking layer. + ** Based on CbmMuchLayer by M.Ryzhinskiy <m.ryzhinskiy@gsi.de> + ** + **/ + + +#ifndef CBMMUSTLAYER_H +#define CBMMUSTLAYER_H 1 + +#include "CbmMustModule.h" +#include "CbmMustTube.h" + +#include <Rtypes.h> // for THashConsistencyHolder, ClassDef +#include <RtypesCore.h> // for Double_t, Int_t, Bool_t, Double32_t +#include <TObject.h> // for TObject + +#include <vector> // for vector + +class CbmMustLayer : public TObject { + + public: + /** Default constructor **/ + CbmMustLayer(); + + /** Standard constructor + *@param detId Detector ID + *@param z z position of layer center [cm] + *@param zRel z position of layer center relative to station center [cm] + **/ + CbmMustLayer(int detId, double z, double zRel); + + /** Standard constructor + *@param iStation Station index + *@param iLayer Layer index + *@param z z position of layer center [cm] + *@param zRel z position of layer center relative to station center [cm] + **/ + CbmMustLayer(int iStation, int iLayer, double z, double zRel); + + /** Destructor **/ + virtual ~CbmMustLayer(); + + /** Accessors **/ + int GetDetectorId() const { return fDetectorId; } + double GetZ() const { return fZ; } + double GetZtoStationCenter() const { return fZtoStationCenter; } + + int GetNModules() const { return fModules.size(); } + + CbmMustModule* GetModule(int iModule) const { return fModules.at(iModule); } + + CbmMustTube* GetTube(int detid); + + CbmMustModule* FindModule(int detid); + bool AddModule(CbmMustModule* module); + void Show(); + + protected: + int fDetectorId{0}; // Unique detector ID + double fZ{0.}; + double fZtoStationCenter{0.}; // Relative position of the layer center with respect + // to the station center + std::vector<CbmMustModule*> fModules; // Array of CbmMustModules + + ClassDef(CbmMustLayer, 1); +}; +#endif diff --git a/core/detectors/must/CbmMustModule.cxx b/core/detectors/must/CbmMustModule.cxx new file mode 100644 index 0000000000000000000000000000000000000000..696999c2ef78325e69e02625e9ef7f9842287082 --- /dev/null +++ b/core/detectors/must/CbmMustModule.cxx @@ -0,0 +1,77 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +/** CbmMustModule.cxx + *@author R.Karabowicz <r.karabowicz@gsi.de> + *@version 1.0 + *@since 2025.01.08 + ** + ** This class holds geometry parameters of must modules + ** Based on CbmMuchModule by M.Ryzhinskiy <m.ryzhinskiy@gsi.de> + ** + **/ +#include "CbmMustModule.h" + +#include <Logger.h> // for LOG + +#include <TObject.h> // for TObject +#include <TVector3.h> // for TVector3 + +// ----- Default constructor ------------------------------------------- +CbmMustModule::CbmMustModule() : TObject(), fDetectorId(0), fPosition(TVector3()), fDirection(TVector3()) {} +// ------------------------------------------------------------------------- + + +// ----- Standard constructor ------------------------------------------ +CbmMustModule::CbmMustModule(int iStation, int iLayer, int iModule, TVector3 position, TVector3 direction) + : TObject() + , fDetectorId(iStation * 1e7 + iLayer * 1e5 + iModule * 1e3) + , fPosition(position) + , fDirection(direction) +{ +} +// ------------------------------------------------------------------------- + +CbmMustTube* CbmMustModule::FindTube(int detid) +{ + for (const auto tempTube : fTubes) { + if (tempTube->GetTubeNumber() == detid) return tempTube; + } + return nullptr; +} + +bool CbmMustModule::AddTube(CbmMustTube* tube) +{ + for (const auto tempTube : fTubes) { + if (tempTube->GetTubeNumber() == tube->GetTubeNumber()) return false; + } + fTubes.push_back(tube); + return true; +} + +void CbmMustModule::Show() +{ + LOG(info) << " Module " << fDetectorId << " (@ (" << fPosition.X() << "," << fPosition.Y() << "," + << fPosition.Z() << ") -> (" << fDirection.X() << "," << fDirection.Y() << "," << fDirection.Z() << "):"; + std::string tubeString(128, '.'); + std::string tubeNumbDec(128, '0'); + std::string tubeNumbOne(128, '0'); + int iobj{0}; + for (const auto tempTube : fTubes) { + // if ( iobj == 0 ) + LOG(info) << " Tube " << tempTube->GetDetectorId() << " @ " << tempTube->GetPosition().X() << "," + << tempTube->GetPosition().Y() << "," << tempTube->GetPosition().Z() << " -> " + << tempTube->GetWireDirection().X() << "," << tempTube->GetWireDirection().Y() << "," + << tempTube->GetWireDirection().Z(); + tubeNumbDec[iobj] = char(tempTube->GetTubeNumber() / 10 + 48); + tubeNumbOne[iobj] = char(tempTube->GetTubeNumber() % 10 + 48); + tubeString[tempTube->GetTubeNumber() - 1] = '*'; + iobj++; + } + LOG(info) << " Tubes " << tubeString; + LOG(info) << " - " << tubeNumbDec; + LOG(info) << " - " << tubeNumbOne; +} + +ClassImp(CbmMustModule) diff --git a/core/detectors/must/CbmMustModule.h b/core/detectors/must/CbmMustModule.h new file mode 100644 index 0000000000000000000000000000000000000000..5c37c8b479c4c74e60947e1ca9b43e14198d3556 --- /dev/null +++ b/core/detectors/must/CbmMustModule.h @@ -0,0 +1,78 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +/** CbmMustModule.h + *@author R.Karabowicz <r.karabowicz@gsi.de> + *@version 1.0 + *@since 2025.01.08 + ** + ** This class holds geometry parameters of must modules + ** Based on CbmMuchModule by M.Ryzhinskiy <m.ryzhinskiy@gsi.de> + ** + **/ + +#ifndef CBMMUSTMODULE_H +#define CBMMUSTMODULE_H 1 + +#include "CbmMustTube.h" + +#include <Rtypes.h> // for THashConsistencyHolder, ClassDef +#include <RtypesCore.h> // for Color_t +#include <TObject.h> // for TObject +#include <TVector3.h> // for TVector3 + +#include <map> // for multimap +#include <utility> // for pair +#include <vector> // for vector + +class CbmMustModule : public TObject { + public: + /** Default constructor **/ + CbmMustModule(); + /** Standard constructor + *@param iStation Station index + *@param iLayer Layer index + *@param iModule Module index + *@param position Location of the module center in global c.s. (all dimensions in [cm]) + *@param direction Direction of the module + **/ + CbmMustModule(int iStation, int iLayer, int iModule, TVector3 position, TVector3 direction); + /** Destructor **/ + virtual ~CbmMustModule() {} + + /** Accessors */ + int GetDetectorId() const { return fDetectorId; } + TVector3 GetPosition() const { return fPosition; } + TVector3 GetDirection() const { return fDirection; } + + int GetNTubes() const { return fTubes.size(); } + + CbmMustTube* GetTube(int iTube) const { return fTubes.at(iTube); } + + CbmMustTube* FindTube(int detid); + bool AddTube(CbmMustTube* tube); + void SortTubes() + { + std::sort(fTubes.begin(), fTubes.end(), + [](const CbmMustTube* a, const CbmMustTube* b) { return a->GetTubeNumber() > b->GetTubeNumber(); }); + } + + void Show(); + + virtual bool InitModule() { return kTRUE; } + virtual void DrawModule(Color_t) {} + + protected: + int fDetectorId; // Unique detector ID + TVector3 fPosition; // Location vector of the module center in global c.s. (all dimensions in [cm]) + TVector3 fDirection; // Direction vector of the module + std::vector<CbmMustTube*> fTubes; // Array of CbmMustTubes + + private: + CbmMustModule(const CbmMustModule&); + CbmMustModule& operator=(const CbmMustModule&); + + ClassDef(CbmMustModule, 2); +}; +#endif diff --git a/core/detectors/must/CbmMustStation.cxx b/core/detectors/must/CbmMustStation.cxx new file mode 100644 index 0000000000000000000000000000000000000000..73e6b769f8e0409600abd75b3721311736b0d24b --- /dev/null +++ b/core/detectors/must/CbmMustStation.cxx @@ -0,0 +1,72 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +/** CbmMustStation.cxx + *@author R.Karabowicz <r.karabowicz@gsi.de> + *@version 1.0 + *@since 2025.01.08 + ** + ** This class holds the transport geometry parameters + ** of one Must tracking station. + ** Based on CbmMuchStation by M.Ryzhinskiy <m.ryzhinskiy@gsi.de> + **/ +#include "CbmMustStation.h" + +#include "CbmMustLayer.h" // for CbmMustLayer + +#include <Logger.h> // for LOG + +#include <TMathBase.h> // for Abs + +// ----- Default constructor ------------------------------------------- +CbmMustStation::CbmMustStation() : TObject(), fDetectorId(0), fZ(0.), fLayers() {} +// ------------------------------------------------------------------------- + +// ----- Standard constructor ------------------------------------------ +CbmMustStation::CbmMustStation(int iStation, double z) : TObject(), fDetectorId(iStation * 1e7), fZ(z), fLayers() {} +// ------------------------------------------------------------------------- + +// ----- Destructor ---------------------------------------------------- +CbmMustStation::~CbmMustStation() {} +// ------------------------------------------------------------------------- + +CbmMustTube* CbmMustStation::GetTube(int detid) +{ + int layerid = detid / 1e5 - 1; + CbmMustLayer* tempLay = GetLayer(layerid); + // LOG(info) << "trying to get tube " << detid % 100000 << " from layer " << layerid; + return tempLay ? tempLay->GetTube(detid % 100000) : nullptr; +} + +// ----- Public method AddSector --------------------------------------- +CbmMustLayer* CbmMustStation::FindLayer(int detid) +{ + for (const auto tempLayer : fLayers) { + if (tempLayer->GetDetectorId() == detid) return tempLayer; + } + return nullptr; +} +// ------------------------------------------------------------------------- + +// ----- Public method AddSector --------------------------------------- +bool CbmMustStation::AddLayer(CbmMustLayer* layer) +{ + for (const auto tempLayer : fLayers) { + if (tempLayer->GetDetectorId() == layer->GetDetectorId()) return false; + } + + fLayers.push_back(layer); + return true; +} +// ------------------------------------------------------------------------- + +void CbmMustStation::Show() +{ + LOG(info) << " Station " << fDetectorId << " (@ z = " << fZ << "):"; + for (const auto tempLayer : fLayers) { + tempLayer->Show(); + } +} + +ClassImp(CbmMustStation) diff --git a/core/detectors/must/CbmMustStation.h b/core/detectors/must/CbmMustStation.h new file mode 100644 index 0000000000000000000000000000000000000000..1433b4bbe0f07df25089f56e343a273460f2450e --- /dev/null +++ b/core/detectors/must/CbmMustStation.h @@ -0,0 +1,64 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +/** CbmMustStation.h + *@author R.Karabowicz <r.karabowicz@gsi.de> + *@version 1.0 + *@since 2025.01.08 + ** + ** This class holds the transport geometry parameters + ** of one Must tracking station. + ** Based on CbmMuchStation by M.Ryzhinskiy <m.ryzhinskiy@gsi.de> + ** + **/ + + +#ifndef CBMMUSTSTATION_H +#define CBMMUSTSTATION_H 1 + +#include "CbmMustLayer.h" // for CbmMustLayer +#include "CbmMustTube.h" + +#include <Rtypes.h> // for THashConsistencyHolder, ClassDef +#include <TObject.h> // for TObject + +#include <vector> // for vector + +class CbmMustStation : public TObject { + public: + /** Default constructor **/ + CbmMustStation(); + + + /** Standard constructor + *@param iStation Station index + *@param z z position of station center in global cs [cm] + **/ + CbmMustStation(int iStation, double z); + + + /** Destructor **/ + virtual ~CbmMustStation(); + + /** Accessors **/ + int GetDetectorId() const { return fDetectorId; } + double GetZ() const { return fZ; } + int GetNLayers() const { return fLayers.size(); } + + CbmMustTube* GetTube(int detid); + + CbmMustLayer* GetLayer(int iLayer) const { return fLayers.at(iLayer); } + + /** Add one sector to the array **/ + CbmMustLayer* FindLayer(int detid); + bool AddLayer(CbmMustLayer* layer); + void Show(); + + protected: + int fDetectorId; // Unique detector ID + double fZ; // z position of station center (midplane) [cm] in global cs + std::vector<CbmMustLayer*> fLayers; // Array of CbmMustLayers + ClassDef(CbmMustStation, 1); +}; +#endif diff --git a/core/detectors/must/CbmMustTube.cxx b/core/detectors/must/CbmMustTube.cxx new file mode 100644 index 0000000000000000000000000000000000000000..224e67476a46ec81933eee5c2f309b286759f40a --- /dev/null +++ b/core/detectors/must/CbmMustTube.cxx @@ -0,0 +1,103 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmMustTube header file +// +// Copied from PndFtsTube +// +// authors: Radoslaw Karabowicz, GSI, 2024 +//////////////////////////////////////////////////////////////////////////// + +#include "CbmMustTube.h" +// standard +#include <iostream> + +CbmMustTube::CbmMustTube() + : fCenPosition(TVector3(0, 0, 0)) + , fRotationMatrix(TMatrixT<double>(3, 3)) + , fRadIn(0) + , fRadOut(0) + , fHalfLength(0) +{ + fRotationMatrix[0][0] = -1.; + fRotationMatrix[0][1] = -1.; + fRotationMatrix[0][2] = -1.; + + fRotationMatrix[1][0] = -1.; + fRotationMatrix[1][1] = -1.; + fRotationMatrix[1][2] = -1.; + + fRotationMatrix[2][0] = -1.; + fRotationMatrix[2][1] = -1.; + fRotationMatrix[2][2] = -1.; +} + +CbmMustTube::CbmMustTube(CbmMustTube& tube) + : TObject(tube) + , fTubeNumber(tube.GetTubeNumber()) + , fCenPosition(tube.GetPosition()) + , fRotationMatrix(TMatrixT<double>(3, 3)) + , fRadIn(tube.GetRadIn()) + , fRadOut(tube.GetRadOut()) + , fHalfLength(tube.GetHalfLength()) +{ + fRotationMatrix.ResizeTo(3, 3); + fRotationMatrix = tube.GetRotationMatrix(); +} + +CbmMustTube::CbmMustTube(int detectorId, int tubeNumber, Double_t x, Double_t y, Double_t z, Double_t r11, Double_t r12, + Double_t r13, Double_t r21, Double_t r22, Double_t r23, Double_t r31, Double_t r32, + Double_t r33, Double_t radin, Double_t radout, Double_t hl) + : fDetectorId(detectorId) + , fTubeNumber(tubeNumber) + , fCenPosition(TVector3(x, y, z)) + , fRotationMatrix(TMatrixT<double>(3, 3)) + , fRadIn(radin) + , fRadOut(radout) + , fHalfLength(hl) +{ + + fRotationMatrix[0][0] = r11; + fRotationMatrix[0][1] = r12; + fRotationMatrix[0][2] = r13; + + fRotationMatrix[1][0] = r21; + fRotationMatrix[1][1] = r22; + fRotationMatrix[1][2] = r23; + + fRotationMatrix[2][0] = r31; + fRotationMatrix[2][1] = r32; + fRotationMatrix[2][2] = r33; +} + +CbmMustTube::~CbmMustTube() +{ + // fCenPosition.Delete(); + // fRotationMatrix.Delete(); +} + +TVector3 CbmMustTube::GetPosition() const { return fCenPosition; } + +TMatrixT<Double_t> CbmMustTube::GetRotationMatrix() const { return fRotationMatrix; } + +Double_t CbmMustTube::GetRadIn() const { return fRadIn; } + +Double_t CbmMustTube::GetRadOut() const { return fRadOut; } + +Double_t CbmMustTube::GetHalfLength() const { return fHalfLength; } + +TVector3 CbmMustTube::GetWireDirection() const +{ + return TVector3(-fRotationMatrix[0][1], fRotationMatrix[1][1], fRotationMatrix[2][1]); +} + +Int_t CbmMustTube::Compare(const TObject* obj) const +{ + if (((CbmMustTube*) obj)->GetTubeNumber() == this->GetTubeNumber()) return 0; + if (((CbmMustTube*) obj)->GetTubeNumber() < this->GetTubeNumber()) return 1; + return -1; +} + +ClassImp(CbmMustTube) diff --git a/core/detectors/must/CbmMustTube.h b/core/detectors/must/CbmMustTube.h new file mode 100644 index 0000000000000000000000000000000000000000..5c6ab5330410cef6d8dbba72b1ed04184c28fc98 --- /dev/null +++ b/core/detectors/must/CbmMustTube.h @@ -0,0 +1,57 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmMustTube header file +// +// Copied from PndFtsTube +// +// authors: Radoslaw Karabowicz, GSI, 2024 +//////////////////////////////////////////////////////////////////////////// + +#ifndef CBMMUSTTUBE_H +#define CBMMUSTTUBE_H 1 + +// from ROOT +#include "TMatrixT.h" +#include "TObject.h" +#include "TVector3.h" + +class CbmMustTube : public TObject { + + public: + /** Default constructor **/ + CbmMustTube(); + CbmMustTube(CbmMustTube& tube); + + ~CbmMustTube(); + CbmMustTube(int detectorId, int tubeNumber, Double_t x, Double_t y, Double_t z, Double_t r11, Double_t r12, + Double_t r13, Double_t r21, Double_t r22, Double_t r23, Double_t r31, Double_t r32, Double_t r33, + Double_t radin, Double_t radout, Double_t hl); + + int GetDetectorId() const { return fDetectorId; } + int GetTubeNumber() const { return fTubeNumber; } + TVector3 GetPosition() const; + TMatrixT<Double_t> GetRotationMatrix() const; + Double_t GetRadIn() const; + Double_t GetRadOut() const; + Double_t GetHalfLength() const; + TVector3 GetWireDirection() const; + + bool IsSkew() const { return (0. != GetWireDirection().X()); } + + Int_t Compare(const TObject* obj) const override; + Bool_t IsSortable() const override { return kTRUE; } + + private: + int fDetectorId{0}; + int fTubeNumber{0}; + TVector3 fCenPosition; + TMatrixT<double> fRotationMatrix; + Double_t fRadIn, fRadOut, fHalfLength; + + ClassDefOverride(CbmMustTube, 1); +}; + +#endif diff --git a/macro/mcbm/mcbm_transport.C b/macro/mcbm/mcbm_transport.C index 598122bc5332ae3ad638a97be200c064b59028f6..c53c6dec68b4419a87358431769186227ca7a460 100644 --- a/macro/mcbm/mcbm_transport.C +++ b/macro/mcbm/mcbm_transport.C @@ -21,10 +21,10 @@ void SetTrack(CbmTransport*, Double_t, Int_t, Double_t, Double_t, Double_t); void mcbm_transport(Int_t nEvents = 10, - // const char* setupName = "mcbm_beam_2025_02_14_silver", + const char* setupName = "mcbm_beam_2025_02_14_silver", // const char* setupName = "mcbm_beam_2024_06_20_uranium", // const char* setupName = "mcbm_beam_2024_05_08_nickel", - const char* setupName = "mcbm_beam_2024_03_22_gold", + // const char* setupName = "mcbm_beam_2024_03_22_gold", // const char* setupName = "mcbm_beam_2022_06_16_gold", // const char* setupName = "mcbm_beam_2022_05_23_nickel", // const char* setupName = "mcbm_beam_2022_03_28_uranium", diff --git a/macro/must/run_sim.C b/macro/must/run_sim.C new file mode 100644 index 0000000000000000000000000000000000000000..f10cfd3f11805baab2e45834f152b436d2e90567 --- /dev/null +++ b/macro/must/run_sim.C @@ -0,0 +1,136 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +// clang-format off + +int run_sim(Int_t nEvents = 10, Int_t pid = 13, Float_t p1 = 10.0, Float_t p2 = 10.0) +{ + // 2212 proton + TStopwatch timer; + timer.Start(); + gDebug = 0; + + TString dir = getenv("VMCWORKDIR"); + + TString tut_configdir = dir + "/sim/transport/gconfig/"; + gSystem->Setenv("CONFIG_DIR", tut_configdir.Data()); + + FairRunSim* fRun = new FairRunSim(); + + // set the MC version used + fRun->SetName("TGeant4"); + + // Cave geometry + TString caveGeom = "cave.geo"; + // Target geometry + TString targetGeom = "passive/targetbox_v22c.gdml"; + // Beam pipe geometry + TString pipeGeom = "pipe/pipe_v22d.geo.root"; + // Magnet geometry and field map + TString magnetGeom = "magnet/magnet_v22a.geo.root"; // "magnet/magnet_v22b.geo.root"; + TString fieldMap = "field_v22c"; // "field_v22d"; + Double_t fieldZ = 0.; // z position of field centre + Double_t fieldScale = 1.; // field scaling factor + + std::string outFile = "points.root"; + std::string parFile = "params.root"; + + fRun->SetSink(new FairRootFileSink(outFile)); + + // Fill the Parameter containers for this run + //------------------------------------------- + + FairRuntimeDb* rtdb = fRun->GetRuntimeDb(); + Bool_t kParameterMerged = kTRUE; + FairParRootFileIo* output = new FairParRootFileIo(kParameterMerged); + output->open(parFile.c_str()); + rtdb->setOutput(output); + + // Set Material file Name + fRun->SetMaterials("media.geo"); + + + // ----- Create geometry ---------------------------------------------- + FairModule* cave = new CbmCave("CAVE"); + cave->SetGeometryFileName(caveGeom); + fRun->AddModule(cave); + + FairModule* pipe = new CbmPipe("PIPE"); + pipe->SetGeometryFileName(pipeGeom); + fRun->AddModule(pipe); + + // FairModule* target = new CbmTarget("Target"); + // target->SetGeometryFileName(targetGeom); + // fRun->AddModule(target); + + FairModule* magnet = new CbmMagnet("MAGNET"); + magnet->SetGeometryFileName(magnetGeom); + fRun->AddModule(magnet); + + FairDetector* must = new CbmMust("MUST", kTRUE); + must->SetGeometryFileName("must/must_v24a_mcbm.geo.root"); + fRun->AddModule(must); + + // Create and Set Event Generator + //------------------------------- + + FairPrimaryGenerator* primGen = new FairPrimaryGenerator(); + fRun->SetGenerator(primGen); + + // Box Generator + FairBoxGenerator* boxGen = new FairBoxGenerator(pid, 100); // 13=muon; 2212=proton 1 = multipl. + if (p2 < 0.) p2 = p1; + boxGen->SetPRange(p1, p2); // GeV/c //setPRange vs setPtRange + boxGen->SetPhiRange(270, 450); // Azimuth angle range [degree] + boxGen->SetThetaRange(6, 22); // Polar angle in lab system range [degree] + boxGen->SetCosTheta(); + boxGen->SetXYZ(0., 0., 0.); + primGen->AddGenerator(boxGen); + + fRun->SetStoreTraj(kTRUE); + fRun->SetBeamMom(15.); + + // ----- Create magnetic field ---------------------------------------- + CbmFieldMap* magField = new CbmFieldMapSym3(fieldMap); + magField->SetPosition(0., 0., fieldZ); + magField->SetScale(fieldScale); + fRun->SetField(magField); + + fRun->Init(); + + // Transport nEvents + // ----------------- + fRun->Run(nEvents); + + rtdb->saveOutput(); + rtdb->print(); + + timer.Stop(); + Double_t rtime = timer.RealTime(); + Double_t ctime = timer.CpuTime(); + printf("RealTime=%f seconds, CpuTime=%f seconds\n", rtime, ctime); + + TChain chain("cbmsim"); + chain.Add(outFile.c_str()); + auto nofE = chain.GetEntries(); + auto nofT = chain.Draw("MCTrack.fPx", "", "goff"); + auto nofP = chain.Draw("MUSTPoint.fPx", "", "goff"); + cout << "Output chain has " << nofE << " events, " << nofT << " tracks, " << nofP << " points." << endl; + + if (nofE < nEvents) { + std::cerr << "Not enough events (" << nofE << " < " << nEvents << ") in the output chain." << endl; + return 1; + } + if (nofT < nEvents) { + std::cerr << "Not enough tracks (" << nofT << " < " << nEvents << ") in the output chain." << endl; + return 1; + } + if (nofP < nEvents * 10) { + std::cerr << "Not enough points (" << nofP << " < " << nEvents * 10 << ") in the output chain." << endl; + return 1; + } + cout << "Simulation successful." << endl; + + return 0; +} diff --git a/sim/detectors/CMakeLists.txt b/sim/detectors/CMakeLists.txt index aa91290cdd33469512652d8b7ca4ce8283d5587d..ebbc2b7d867004821a2940ce36ad44abb2282ebc 100644 --- a/sim/detectors/CMakeLists.txt +++ b/sim/detectors/CMakeLists.txt @@ -10,3 +10,4 @@ add_subdirectory(tof) add_subdirectory(fsd) add_subdirectory(psd) add_subdirectory(bmon) +add_subdirectory(must) diff --git a/sim/detectors/must/CMakeLists.txt b/sim/detectors/must/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..41bb26c301722e71d567b2a6a0b5c975fded95a6 --- /dev/null +++ b/sim/detectors/must/CMakeLists.txt @@ -0,0 +1,35 @@ +set(INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_SOURCE_DIR} + ) + + +set(SRCS + CbmMust.cxx + ) + + +set(LIBRARY_NAME CbmMustSim) +set(LINKDEF ${LIBRARY_NAME}LinkDef.h) +set(PUBLIC_DEPENDENCIES + CbmBase + CbmData + CbmMustBase + FairRoot::Base + ROOT::Core + ROOT::Hist + ROOT::MathCore + ) + +set(PRIVATE_DEPENDENCIES + CbmSimBase + FairRoot::ParBase + ROOT::EG + ROOT::Geom + ROOT::Gpad + ROOT::Physics + ROOT::RIO + ) + +generate_cbm_library() + + diff --git a/sim/detectors/must/CbmMust.cxx b/sim/detectors/must/CbmMust.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3ee953ac5de960adf35d14be9b99ce8d6daf825d --- /dev/null +++ b/sim/detectors/must/CbmMust.cxx @@ -0,0 +1,484 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmMust source file +// +// Class for simulation of MUST +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmMust by Nafija Ibrisimovic in 2023 +//////////////////////////////////////////////////////////////////////////// + +#include "CbmMust.h" +// from CbmRoot, this library +#include "CbmDefs.h" +#include "CbmGeoMust.h" +#include "CbmGeoMustPar.h" +#include "CbmMustGeoScheme.h" +#include "CbmMustLayer.h" +#include "CbmMustModule.h" +#include "CbmMustStation.h" +#include "CbmMustTube.h" +#include "CbmStack.h" +// from CbmRoot +#include "CbmGeometryUtils.h" +// from FairRoot +#include <FairGeoInterface.h> +#include <FairGeoLoader.h> +#include <FairGeoNode.h> +#include <FairGeoRootBuilder.h> +#include <FairLogger.h> +#include <FairRootManager.h> +#include <FairRun.h> +#include <FairRuntimeDb.h> +#include <FairVolume.h> +// from ROOT +#include <TClonesArray.h> +#include <TGeoMatrix.h> +#include <TGeoMedium.h> +#include <TGeoTube.h> +#include <TGeoVolume.h> +#include <TLorentzVector.h> +#include <TObjArray.h> +#include <TParticle.h> +#include <TVirtualMC.h> +// standard +#include <iostream> + +using std::string; + +// TODO: read this from geant initialization +#define innerStrawDiameter 1. +// #define redefineLambdaChargedDecay 0 + +// ----- Default constructor ------------------------------------------- +CbmMust::CbmMust() + : fTrackID(0) + , fVolumeID(0) + , fPos(0, 0, 0, 0) + , fPosIn(0, 0, 0, 0) + , fPosOut(0, 0, 0, 0) + , fPosInLocal(0, 0, 0, 0) + , fPosOutLocal(0, 0, 0, 0) + , fMomIn(0, 0, 0, 0) + , fMomOut(0, 0, 0, 0) + , fTime(0) + , fLength(0) + , fELoss(0) + , fMass(0) + , fIsInitialized(kFALSE) + , fPosIndex(0) + , fMustCollection(nullptr) + , fpostot(0, 0, 0, 0) + , fpostotin(0, 0, 0, 0) + , fpostotout(0, 0, 0, 0) + , fPassNodes() + , valid(kFALSE) + , fGeoType(0) +{ + fMustCollection = new TClonesArray("CbmMustPoint"); + fVerboseLevel = 0; +} +// ------------------------------------------------------------------------- + +// ----- Standard constructor ------------------------------------------ +CbmMust::CbmMust(const char* name, Bool_t active) + : FairDetector(name, active) + , fTrackID(0) + , fVolumeID(0) + , fPos(0, 0, 0, 0) + , fPosIn(0, 0, 0, 0) + , fPosOut(0, 0, 0, 0) + , fPosInLocal(0, 0, 0, 0) + , fPosOutLocal(0, 0, 0, 0) + , fMomIn(0, 0, 0, 0) + , fMomOut(0, 0, 0, 0) + , fTime(0) + , fLength(0) + , fELoss(0) + , fMass(0) + , fIsInitialized(kFALSE) + , fPosIndex(0) + , fMustCollection(nullptr) + , fpostot(0, 0, 0, 0) + , fpostotin(0, 0, 0, 0) + , fpostotout(0, 0, 0, 0) + , fPassNodes() + , valid(kFALSE) + , fGeoType(0) +{ + fMustCollection = new TClonesArray("CbmMustPoint"); + fVerboseLevel = 0; + fGeoType = 1; // CHECK +} +// ------------------------------------------------------------------------- + +// ----- Destructor ---------------------------------------------------- +CbmMust::~CbmMust() +{ + if (fMustCollection) { + fMustCollection->Delete(); + delete fMustCollection; + } +} +// ------------------------------------------------------------------------- + +// ----- Private method GetSquaredDistanceFromWire ----------------------- +float CbmMust::GetSquaredDistanceFromWire() +{ + TLorentzVector entryPosition; + + float positionInMother[3], positionInStraw[3]; + + gMC->TrackPosition(entryPosition); + positionInMother[0] = entryPosition.X(); + positionInMother[1] = entryPosition.Y(); + positionInMother[2] = entryPosition.Z(); + gMC->Gmtod(positionInMother, positionInStraw, 1); + + return positionInStraw[0] * positionInStraw[0] + positionInStraw[1] * positionInStraw[1]; +} +// ------------------------------------------------------------------------- + +// ----- Public method ProcessHits -------------------------------------- +Bool_t CbmMust::ProcessHits(FairVolume* vol) +{ + // LOG(info) << "ProcessHits called!"; + // TParticle* particle = gMC->GetStack()->GetCurrentTrack(); //[R.K. 01/2017] unused variable? + // TGeoMedium *medium = (TGeoMedium*) vol->getGeoNode()->getRootVolume()->GetMedium(); //[R.K. 01/2017] unused variable? + // Double_t epsil = medium->GetParam(6); //[R.K. 01/2017] unused variable? + + TString vol_name(gMC->CurrentVolName()); + TGeoHMatrix M; + gMC->GetTransformation(gMC->CurrentVolPath(), M); + TString name(gMC->CurrentVolName()); + // LOG(info) << "\"" << gMC->CurrentVolPath() << "\" - \"" << gMC->CurrentVolName() << "\""; + if (gMC->TrackCharge() != 0.) { + + if (gMC->IsTrackEntering()) { + valid = kTRUE; + + // Set parameters at entrance of volume. Reset ELoss. + fELoss = 0.; + fTime = gMC->TrackTime() * 1.0e09; + fLength = gMC->TrackLength(); + gMC->TrackPosition(fPos); + gMC->TrackMomentum(fMomIn); + gMC->TrackPosition(fpostotin); // da cancellare + Double_t globalPos[3] = {0., 0., 0.}; // stt1 modified + Double_t localPos[3] = {0., 0., 0.}; // stt1 modified + + globalPos[0] = fPos.X(); + globalPos[1] = fPos.Y(); + globalPos[2] = fPos.Z(); + + gMC->Gmtod(globalPos, localPos, 1); + fPosInLocal.SetXYZM(localPos[0], localPos[1], localPos[2], 0.0); + } + + // Sum energy loss for all steps in the active volume + fELoss += gMC->Edep(); + + // Create CbmMustPoint at exit of active volume -- but not into the wire + if (gMC->IsTrackExiting() && valid == kTRUE) { + valid = kFALSE; + fTrackID = gMC->GetStack()->GetCurrentTrackNumber(); + fVolumeID = static_cast<int>(ECbmModuleId::kEcal); // vol->getMCid(); + + if (fTrackID != 0) { + if (fVerboseLevel > 2) LOG(info) << "[MUST] test Vol----------" << vol->getMCid(); + if (fVerboseLevel > 2) LOG(info) << "fTrackID-----" << fTrackID; + } + + fMass = gMC->TrackMass(); // mass (GeV) + gMC->TrackPosition(fPosOut); + gMC->TrackMomentum(fMomOut); + gMC->TrackPosition(fpostotout); // da cancellare + Double_t globalPos[3] = {0., 0., 0.}; // stt1 modified + Double_t localPos[3] = {0., 0., 0.}; // stt1 modified + + gMC->Gdtom(localPos, globalPos, 1); + + fPos.SetXYZM(globalPos[0], globalPos[1], globalPos[2], 0.0); + + globalPos[0] = fPosOut.X(); + globalPos[1] = fPosOut.Y(); + globalPos[2] = fPosOut.Z(); + + gMC->Gmtod(globalPos, localPos, 1); + fPosOutLocal.SetXYZM(localPos[0], localPos[1], localPos[2], 0.0); + + string volPath(gMC->CurrentVolPath()); + + fpostot.SetXYZM((fpostotin.X() + fpostotout.X()) / 2., (fpostotin.Y() + fpostotout.Y()) / 2., + (fpostotin.Z() + fpostotout.Z()) / 2., 0.0); + + LOG(debug) << " --> " << volPath; + string strawName = volPath.substr(volPath.find("strawAssembly_") + 14, 8); + int statId = 0; + int layerId = atoi(strawName.substr(1, 2).c_str()) - 1; + int moduleId = atoi(strawName.substr(3, 2).c_str()) - 1; + int strawId = atoi(strawName.substr(5, 3).c_str()) - 1; + + uint32_t address = CbmMustGeoScheme::Instance()->GetAddress(statId, layerId, moduleId, strawId); + + if (1 == 0) { + CbmMustGeoScheme* mustGeoScheme = CbmMustGeoScheme::Instance(); + // add station + int detId = statId * 1e7; + CbmMustStation* mustStation = mustGeoScheme->FindStation(detId); + if (!mustStation) { + LOG(info) << "STATION --> " << volPath; + string statPath = volPath.substr(0, volPath.find("/layer")); + LOG(info) << "STATION --> " << statPath; + mustGeoScheme->NavigateTo(statPath); + TVector3 globPos = mustGeoScheme->GetGlobal(); + mustStation = new CbmMustStation(statId, globPos[2]); // change z! + } + mustGeoScheme->AddStation(mustStation); + // add layer + detId = detId + layerId * 1e5; + CbmMustLayer* mustLayer = mustStation->FindLayer(detId); + if (!mustLayer) { + LOG(info) << "LAYER --> " << volPath; + string layerPath = volPath.substr(0, volPath.find("/module")); + LOG(info) << "LAYER --> " << layerPath; + mustGeoScheme->NavigateTo(volPath); + TVector3 globPos = mustGeoScheme->GetGlobal(); + mustLayer = new CbmMustLayer(statId, layerId, globPos[2], globPos[2] - mustStation->GetZ()); + } + mustStation->AddLayer(mustLayer); + // add module + detId = detId + moduleId * 1e3; + CbmMustModule* mustModule = mustLayer->FindModule(detId); + TVector3 directionVector(0., 1., 0.); + if (layerId == 1 || layerId == 2) { + double angle = 5. * TMath::DegToRad(); + if (layerId == 3) angle = -angle; + directionVector[0] = TMath::Sin(angle); + directionVector[1] = TMath::Cos(angle); + } + if (!mustModule) { + mustGeoScheme->NavigateTo(volPath); + TVector3 globPos = mustGeoScheme->GetGlobal(); + mustModule = new CbmMustModule(statId, layerId, moduleId, globPos, directionVector); + } + mustLayer->AddModule(mustModule); + // add tube + detId = detId + strawId; + CbmMustTube* mustTube = mustModule->FindTube(detId); + if (!mustTube) { + mustGeoScheme->NavigateTo(volPath); + TVector3 globPos = mustGeoScheme->GetGlobal(); + mustTube = + new CbmMustTube(detId, strawId, globPos[0], globPos[1], globPos[2], directionVector[1], -directionVector[0], + 0., directionVector[0], directionVector[1], 0., 0., 0., 1., 0.0127, 0.49, 110.); + } + mustModule->AddTube(mustTube); + } + + LOG(debug) << " l/m/t = " << layerId << "/" << moduleId << "/" << strawId; + + AddHit(fTrackID, fVolumeID, address, TVector3(fpostot.X(), fpostot.Y(), fpostot.Z()), + TVector3(fPosInLocal.X(), fPosInLocal.Y(), fPosInLocal.Z()), + TVector3(fPosOutLocal.X(), fPosOutLocal.Y(), fPosOutLocal.Z()), + TVector3(fMomIn.Px(), fMomIn.Py(), fMomIn.Pz()), TVector3(fMomOut.Px(), fMomOut.Py(), fMomOut.Pz()), fTime, + fLength, fELoss); + + if (fTrackID != 0) { + if (fVerboseLevel > 2) LOG(info) << "AddHit CbmMust.cxx= " << fTrackID; + } + + // Increment number of stt points for TParticle + CbmStack* stack = (CbmStack*) gMC->GetStack(); + stack->AddPoint(ECbmModuleId::kEcal); + ResetParameters(); + } + } + + return kTRUE; +} +// ------------------------------------------------------------------------- + +// ----- Public method EndOfEvent -------------------------------------- +void CbmMust::EndOfEvent() +{ + if (fVerboseLevel) Print(); + fMustCollection->Delete(); + fPosIndex = 0; + + if (1 == 0) { + int nofTubes = 0; + std::vector<CbmMustStation*> stations = CbmMustGeoScheme::Instance()->GetStations(); + for (const auto tempStation : stations) { + for (int ilay = 0; ilay < tempStation->GetNLayers(); ilay++) { + CbmMustLayer* tempLayer = tempStation->GetLayer(ilay); + for (int imod = 0; imod < tempLayer->GetNModules(); imod++) { + CbmMustModule* tempModule = tempLayer->GetModule(imod); + tempModule->SortTubes(); + nofTubes += tempModule->GetNTubes(); + } + } + } + + LOG(info) << "got " << nofTubes << " tubes"; + if (nofTubes == 256 && !fGeoSchemeSaved) { + CbmMustGeoScheme::Instance()->Show(); + CbmMustGeoScheme::Instance()->StoreGeoScheme(); + fGeoSchemeSaved = true; + } + } +} +// ------------------------------------------------------------------------- + +// ----- Public method Register ---------------------------------------- +void CbmMust::Register() { FairRootManager::Instance()->Register("MUSTPoint", "Must", fMustCollection, kTRUE); } +// ------------------------------------------------------------------------- + +// ----- Public method GetCollection ----------------------------------- +TClonesArray* CbmMust::GetCollection(Int_t iColl) const +{ + if (iColl == 0) + return fMustCollection; + else + return nullptr; +} +// ------------------------------------------------------------------------- + +// ----- Public method Print ------------------------------------------- +void CbmMust::Print(Option_t*) const +{ + Int_t nHits = fMustCollection->GetEntriesFast(); + + LOG(info) << " CbmMust: " << nHits << " points registered in this event."; + + if (fVerboseLevel > 1) + for (Int_t i = 0; i < nHits; i++) + (*fMustCollection)[i]->Print(); +} +// ------------------------------------------------------------------------- + +// ----- Public method Reset ------------------------------------------- +void CbmMust::Reset() +{ + fMustCollection->Delete(); + ResetParameters(); +} +// ------------------------------------------------------------------------- + +// ----- Public method CopyClones -------------------------------------- +void CbmMust::CopyClones(TClonesArray* cl1, TClonesArray* cl2, Int_t offset) +{ + Int_t nEntries = cl1->GetEntriesFast(); + + LOG(info) << " CbmMust: " << nEntries << " entries to add."; + + TClonesArray& clref = *cl2; + + CbmMustPoint* oldpoint = nullptr; + for (Int_t i = 0; i < nEntries; i++) { + oldpoint = (CbmMustPoint*) cl1->At(i); + + Int_t index = oldpoint->GetTrackID() + offset; + + oldpoint->SetTrackID(index); + new (clref[fPosIndex]) CbmMustPoint(*oldpoint); + fPosIndex++; + } + LOG(info) << " CbmMust: " << cl2->GetEntriesFast() << " merged entries."; +} +// ------------------------------------------------------------------------- + +void CbmMust::Initialize() +{ + LOG(info) << " -I- Initializing CbmMust()"; + FairDetector::Initialize(); +} + +// ----- Public method ConstructGeometry ------------------------------- +void CbmMust::ConstructGeometry() +{ + TString fileName = GetGeometryFileName(); + + // --- Only ROOT geometries are supported + if (fileName.EndsWith(".root")) { + LOG(info) << "Importing MUST geometry from ROOT file " << fileName.Data(); + TGeoCombiTrans* fCombiTrans = NULL; + Cbm::GeometryUtils::ImportRootGeometry(fgeoName, this, fCombiTrans); + return; + } + LOG(info) << "Constructing Must geometry from text file " << fileName.Data(); + + FairGeoLoader* geoLoad = FairGeoLoader::Instance(); + FairGeoInterface* geoFace = geoLoad->getGeoInterface(); + CbmGeoMust* Geo = new CbmGeoMust(); + Geo->setGeomFile(GetGeometryFileName()); + geoFace->addGeoModule(Geo); + + Bool_t rc = geoFace->readSet(Geo); + if (rc) Geo->create(geoLoad->getGeoBuilder()); + + TList* volList = Geo->getListOfVolumes(); + + // store geo parameter + FairRun* fRun = FairRun::Instance(); + FairRuntimeDb* rtdb = FairRun::Instance()->GetRuntimeDb(); + CbmGeoMustPar* par; + par = (CbmGeoMustPar*) (rtdb->getContainer("CbmGeoMustPar")); + rtdb->getListOfContainers()->Print(); + TObjArray* fSensNodes = par->GetGeoSensitiveNodes(); + fPassNodes = par->GetGeoPassiveNodes(); + + TListIter iter(volList); + FairGeoNode* node = nullptr; + FairGeoVolume* aVol = nullptr; + + while ((node = (FairGeoNode*) iter.Next())) { + aVol = dynamic_cast<FairGeoVolume*>(node); + // if (fGeoType == 2) + // LOG(info) << "Volume " << aVol->GetName() << " is" << (node->isSensitive() ? "" : " not") << " sensitive"; + if (node->isSensitive()) { + fSensNodes->AddLast(aVol); + } + else { + fPassNodes->AddLast(aVol); + } + } + + par->SetGeometryType(fGeoType); + if (fGeoType == 1) { + par->SetTubeInRad(0.4903 / 2.); // cm + par->SetTubeOutRad(0.00127); // cm + } + else { + LOG(fatal) << "[MUST] GeoType " << fGeoType << " not supported"; + } + + par->setChanged(); + par->setInputVersion(fRun->GetRunId(), 1); + ProcessNodes(volList); +} +// ------------------------------------------------------------------------- + +// ----- Private method AddHit ----------------------------------------- +CbmMustPoint* CbmMust::AddHit(Int_t trackID, Int_t detID, uint32_t address, TVector3 pos, TVector3 posInLocal, + TVector3 posOutLocal, TVector3 momIn, TVector3 momOut, Double_t time, Double_t length, + Double_t eLoss) +{ + TClonesArray& clref = *fMustCollection; + + Int_t size = clref.GetEntriesFast(); + + CbmMustPoint* pointnew = new (clref[size]) + CbmMustPoint(trackID, detID, address, pos, posInLocal, posOutLocal, momIn, momOut, time, length, eLoss); + LOG(debug) << pointnew->GetStationId() << " - " << pointnew->GetLayerId() << " - " << pointnew->GetModuleId() << " - " + << pointnew->GetStrawId(); + + return pointnew; +} +// ------------------------------------------------------------------------- + +ClassImp(CbmMust) diff --git a/sim/detectors/must/CbmMust.h b/sim/detectors/must/CbmMust.h new file mode 100644 index 0000000000000000000000000000000000000000..84ea7d16eececed2d30ed159f5669c78d57c0cd4 --- /dev/null +++ b/sim/detectors/must/CbmMust.h @@ -0,0 +1,195 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radoslaw Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmMust header file +// +// Class for simulation of MUST +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmMust by Nafija Ibrisimovic in 2023 +//////////////////////////////////////////////////////////////////////////// + +#ifndef CBMMUST_H +#define CBMMUST_H + +// from CbmRoot, this library +#include "CbmGeoMustPar.h" +// from CbmRoot, CbmData +#include <CbmMustPoint.h> +// from FairRoot +#include <FairDetector.h> +#include <FairRun.h> +// from ROOT +#include <TClonesArray.h> +#include <TLorentzVector.h> +#include <TVector3.h> +// standard +#include <sstream> +#include <string> + +class TClonesArray; +class FairVolume; + +class CbmMust : public FairDetector { + + public: + /** Default constructor **/ + CbmMust(); + + /** Standard constructor. + *@param name detetcor name + *@param active sensitivity flag + **/ + CbmMust(const char* name, Bool_t active); + + /** Destructor **/ + virtual ~CbmMust(); + + /** Virtual method ProcessHits + ** + ** Defines the action to be taken when a step is inside the + ** active volume. Creates CbmMustPoints and adds them to the + ** collection. + *@param vol Pointer to the active volume + **/ + virtual Bool_t ProcessHits(FairVolume* vol = 0) override; + + /** Virtual method EndOfEvent + ** + ** If verbosity level is set, print hit collection at the + ** end of the event and resets it afterwards. + **/ + virtual void EndOfEvent() override; + + /** @brief Check whether a volume is sensitive. + ** + ** @param(name) Volume name + ** @value kTRUE if volume is sensitive, else kFALSE + ** + ** The decision is based on the volume name (has to contain "Sensor"). + ** Virtual from FairModule. + **/ + virtual Bool_t IsSensitive(const std::string& name) override + { + return (TString(name).Contains("active") ? kTRUE : kFALSE); + } + + /** Virtual method Register + ** + ** Registers the hit collection in the ROOT manager. + **/ + virtual void Register() override; + + /** Accessor to the hit collection **/ + virtual TClonesArray* GetCollection(Int_t iColl) const override; + + /** Virtual method Print + ** + ** Screen output of hit collection. + **/ + virtual void Print(Option_t* /*option*/ = "") const override; + + /** Virtual method Reset + ** + ** Clears the hit collection + **/ + virtual void Reset() override; + + virtual void Initialize() override; + + /** Virtual method CopyClones + ** + ** Copies the hit collection with a given track index offset + *@param cl1 Origin + *@param cl2 Target + *@param offset Index offset + **/ + virtual void CopyClones(TClonesArray* cl1, TClonesArray* cl2, Int_t offset) override; + + /** Virtual method Construct geometry + ** + ** Constructs the STT geometry + **/ + virtual void ConstructGeometry() override; + + private: + /** GFTrack information to be stored until the track leaves the + active volume. **/ + Int_t fTrackID; //! track index + Int_t fVolumeID; //! volume id + TLorentzVector fPos; //! wire position in global frame + TLorentzVector fPosIn; //! entry position in global frame + TLorentzVector fPosOut; //! exit position in global frame + TLorentzVector fPosInLocal; //! entry position in straw frame + TLorentzVector fPosOutLocal; //! exit position in straw frame + TLorentzVector fMomIn; //! momentum + TLorentzVector fMomOut; //! momentum + Double_t fTime; //! time + Double_t fLength; //! length + Double_t fELoss; //! energy loss + Double_t fMass; //! particle mass + Bool_t fIsInitialized; + + Int_t fPosIndex; //! + TClonesArray* fMustCollection; //! Hit collection + TLorentzVector fpostot; // global frame hit position (in)// da cancellare + TLorentzVector fpostotin; // global frame hit position (in)// da cancellare + TLorentzVector fpostotout; // global frame hit position (in)// da cancellare + + TObjArray* fPassNodes; //! + // geometry type + Bool_t valid; + Int_t fGeoType; + bool fGeoSchemeSaved{false}; + + /** Private method AddHit + ** + ** Adds a CbmTrdPoint to the HitCollection + **/ + CbmMustPoint* AddHit(Int_t trackID, Int_t detID, uint32_t address, TVector3 pos, TVector3 posInLocal, + TVector3 posOutLocal, TVector3 momIn, TVector3 momOut, Double_t time, Double_t length, + Double_t eLoss); + + /** Private method ResetParameters + ** + ** Resets the private members for the track parameters + **/ + void ResetParameters(); + + /** Private method GetSquaredDistanceFromWire + ** + ** Returns the square of the distance of the current trackpoint to the wire + *@return distance + **/ + float GetSquaredDistanceFromWire(); + + CbmMust(const CbmMust& L); + CbmMust& operator=(const CbmMust&) { return *this; } + + ClassDef(CbmMust, 1) +}; + +inline void CbmMust::ResetParameters() +{ + fTrackID = fVolumeID = 0; + fPos.SetXYZM(0.0, 0.0, 0.0, 0.0); + fPosInLocal.SetXYZM(0.0, 0.0, 0.0, 0.0); + fPosOutLocal.SetXYZM(0.0, 0.0, 0.0, 0.0); + fMomIn.SetXYZM(0.0, 0.0, 0.0, 0.0); + fMomOut.SetXYZM(0.0, 0.0, 0.0, 0.0); + fTime = fLength = fELoss = 0; + fPosIndex = 0; + fpostot.SetXYZM(0.0, 0.0, 0.0, 0.0); // da cancellare + fpostotin.SetXYZM(0.0, 0.0, 0.0, 0.0); // da cancellare + fpostotout.SetXYZM(0.0, 0.0, 0.0, 0.0); // da cancellare + fPosIn.SetXYZM(0.0, 0.0, 0.0, 0.0); + fPosOut.SetXYZM(0.0, 0.0, 0.0, 0.0); + fMass = 0; + fIsInitialized = kFALSE; + valid = kFALSE; +} + +#endif // CBMMUST_H diff --git a/sim/detectors/must/CbmMustSimLinkDef.h b/sim/detectors/must/CbmMustSimLinkDef.h new file mode 100644 index 0000000000000000000000000000000000000000..e42383441871538a9d5b2184fa56331b54fe43c0 --- /dev/null +++ b/sim/detectors/must/CbmMustSimLinkDef.h @@ -0,0 +1,13 @@ +/* Copyright (C) 2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Volker Friese [committer] */ + +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class CbmMust + ; + +#endif /* __CINT__ */ diff --git a/sim/transport/geosetup/CMakeLists.txt b/sim/transport/geosetup/CMakeLists.txt index 92ab662e9d6293a4d67d130057783e92e8b30729..90b9d7f24348601c6d128e1784d334816dd48a80 100644 --- a/sim/transport/geosetup/CMakeLists.txt +++ b/sim/transport/geosetup/CMakeLists.txt @@ -31,6 +31,7 @@ set(PUBLIC_DEPENDENCIES set(PRIVATE_DEPENDENCIES CbmMuchSim + CbmMustSim CbmMvdSim CbmPassive CbmPsdSim diff --git a/sim/transport/geosetup/CbmGeoSetupProvider.cxx b/sim/transport/geosetup/CbmGeoSetupProvider.cxx index d7147faeac082e5877474cccbd159493aac308ba..66e997c0873accf4ab2a5723b918616f1bceaafa 100644 --- a/sim/transport/geosetup/CbmGeoSetupProvider.cxx +++ b/sim/transport/geosetup/CbmGeoSetupProvider.cxx @@ -1,4 +1,4 @@ -/* Copyright (C) 2019-2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +/* Copyright (C) 2019-2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt SPDX-License-Identifier: GPL-3.0-only Authors: Evgeny Lavrik, Florian Uhlig [committer] */ @@ -13,6 +13,7 @@ #include "CbmDefs.h" #include "CbmMagnet.h" #include "CbmMuch.h" +#include "CbmMust.h" #include "CbmMvd.h" #include "CbmPipe.h" #include "CbmRich.h" @@ -20,9 +21,9 @@ #include "CbmTarget.h" #include "CbmTof.h" #include "CbmTrd.h" - #include "FairModule.h" #include "FairRunSim.h" + #include <Logger.h> //#include "CbmEcal.h" #include "CbmFsdMC.h" @@ -45,8 +46,8 @@ namespace return { ECbmModuleId::kCave, ECbmModuleId::kMagnet, ECbmModuleId::kPipe, ECbmModuleId::kTarget, // ECbmModuleId::kMvd, ECbmModuleId::kSts, ECbmModuleId::kRich, ECbmModuleId::kMuch, ECbmModuleId::kTrd, ECbmModuleId::kTof, ECbmModuleId::kEcal, ECbmModuleId::kPsd, - ECbmModuleId::kMvd, ECbmModuleId::kSts, ECbmModuleId::kRich, ECbmModuleId::kMuch, ECbmModuleId::kTrd, - ECbmModuleId::kTof, ECbmModuleId::kPsd, ECbmModuleId::kFsd, + ECbmModuleId::kMvd, ECbmModuleId::kSts, ECbmModuleId::kRich, ECbmModuleId::kMuch, ECbmModuleId::kMust, + ECbmModuleId::kTrd, ECbmModuleId::kTof, ECbmModuleId::kPsd, ECbmModuleId::kFsd, // ECbmModuleId::kHodo, ECbmModuleId::kShield, ECbmModuleId::kPlatform }; ECbmModuleId::kBmon, ECbmModuleId::kPlatform}; } @@ -104,7 +105,7 @@ void CbmGeoSetupProvider::RegisterSetup() std::vector<std::string> _tag; boost::split(_geom, fileName, [](char c) { return c == ':'; }); boost::split(_tag, geoTag, [](char c) { return c == ':'; }); - int counter {0}; + int counter{0}; for (auto& string : _geom) { LOG(info) << "-I- RegisterSetup: Registering " << modulName << " " << _tag[counter] @@ -119,7 +120,7 @@ void CbmGeoSetupProvider::RegisterSetup() case ECbmModuleId::kMagnet: fairModule = new CbmMagnet("MAGNET"); break; case ECbmModuleId::kBmon: fairModule = new CbmBmon("BMON"); break; case ECbmModuleId::kPipe: { - std::string volname {"PIPE"}; + std::string volname{"PIPE"}; volname += std::to_string(counter); fairModule = new CbmPipe(volname.c_str()); break; @@ -129,6 +130,7 @@ void CbmGeoSetupProvider::RegisterSetup() case ECbmModuleId::kSts: fairModule = new CbmStsMC(isActive); break; case ECbmModuleId::kRich: fairModule = new CbmRich("RICH", isActive); break; case ECbmModuleId::kMuch: fairModule = new CbmMuch("MUCH", isActive); break; + case ECbmModuleId::kMust: fairModule = new CbmMust("MUST", isActive); break; case ECbmModuleId::kTrd: fairModule = new CbmTrd("TRD", isActive); break; case ECbmModuleId::kTof: fairModule = new CbmTof("TOF", isActive); diff --git a/sim/transport/geosetup/CbmGeoSetupRepoProvider.cxx b/sim/transport/geosetup/CbmGeoSetupRepoProvider.cxx index b771e4ed1a468e18704ec5a55cb397e0b3b6cd46..c388c59adc8a931d8f758ec31ad2c053327cb6c3 100644 --- a/sim/transport/geosetup/CbmGeoSetupRepoProvider.cxx +++ b/sim/transport/geosetup/CbmGeoSetupRepoProvider.cxx @@ -1,4 +1,4 @@ -/* Copyright (C) 2019-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +/* Copyright (C) 2019-2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt SPDX-License-Identifier: GPL-3.0-only Authors: Evgeny Lavrik, Florian Uhlig [committer] */ @@ -10,12 +10,11 @@ #include "CbmGeoSetupRepoProvider.h" #include "CbmDefs.h" - -#include <Logger.h> - #include "TSystem.h" #include "TSystemDirectory.h" +#include <Logger.h> + #include <boost/algorithm/string.hpp> #include <fstream> @@ -54,7 +53,7 @@ namespace }; /// lookup map for various module properties - std::map<ECbmModuleId, DetInfo> detectorMap { + std::map<ECbmModuleId, DetInfo> detectorMap{ {ECbmModuleId::kCave, {"caveGeoTag", "cave", "cave", "CAVE"}}, {ECbmModuleId::kMagnet, {"magnetGeoTag", "magnet", "magnet", "MAGNET"}}, {ECbmModuleId::kPipe, {"pipeGeoTag", "pipe", "pipe", "PIPE"}}, @@ -63,6 +62,7 @@ namespace {ECbmModuleId::kSts, {"stsGeoTag", "sts", "sts", "STS"}}, {ECbmModuleId::kRich, {"richGeoTag", "rich", "rich", "RICH"}}, {ECbmModuleId::kMuch, {"muchGeoTag", "much", "much", "MUCH"}}, + {ECbmModuleId::kMust, {"mustGeoTag", "must", "must", "MUST"}}, {ECbmModuleId::kTrd, {"trdGeoTag", "trd", "trd", "TRD"}}, {ECbmModuleId::kTof, {"tofGeoTag", "tof", "tof", "TOF"}}, // { ECbmModuleId::kEcal, {"ecalGeoTag", "ecal", "ecal", "ECAL"} }, @@ -125,7 +125,7 @@ CbmGeoSetup CbmGeoSetupRepoProvider::GetSetupByTag(std::string setupTag, std::st LOG(warn) << "-W- LoadSetup " << setupTag << ": overwriting existing setup " << fSetup.GetTag(); } - LOG(info) << "Loading CbmGeoSetup from svn repository.\nSetup tag: " << setupTag + LOG(info) << "Loading CbmGeoSetup from repository.\nSetup tag: " << setupTag << " Revision: " << (revision.empty() ? "latest" : revision); std::string base = gSystem->Getenv("VMCWORKDIR"); @@ -138,7 +138,7 @@ CbmGeoSetup CbmGeoSetupRepoProvider::GetSetupByTag(std::string setupTag, std::st // remove commented out-lines std::regex commentRegex("/[/]+.*"); - std::string replacementString {""}; + std::string replacementString{""}; fileContents = std::regex_replace(fileContents, commentRegex, replacementString); // setup name @@ -179,8 +179,12 @@ CbmGeoSetup CbmGeoSetupRepoProvider::GetSetupByTag(std::string setupTag, std::st std::regex setModuleRegex(R"(.*SetModule\(.*)" + detector.second.tag + R"(\);)"); std::string tag; bool added = false; - if (std::regex_search(fileContents, match, tagRegex)) { tag = match[1]; } - if (std::regex_search(fileContents, match, setModuleRegex)) { added = true; } + if (std::regex_search(fileContents, match, tagRegex)) { + tag = match[1]; + } + if (std::regex_search(fileContents, match, setModuleRegex)) { + added = true; + } if (tag.size() && added) { ECbmModuleId moduleId = detector.first;