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..a728ff52126ed65c10785633c52cc5fb6d29723c 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,10 @@ set(SRCS fsd/CbmFsdPoint.cxx fsd/CbmFsdAddress.cxx + must/CbmMustPoint.cxx + must/CbmMustDigi.cxx + must/CbmMustHit.cxx + global/CbmGlobalTrack.cxx global/CbmVertex.cxx global/CbmTrackParam.cxx diff --git a/core/data/CbmDataLinkDef.h b/core/data/CbmDataLinkDef.h index b418995a9fd6172f5b98464b855627f419d9dd94..a4d542f498a494279b8358d24b2aa63c2411b82d 100644 --- a/core/data/CbmDataLinkDef.h +++ b/core/data/CbmDataLinkDef.h @@ -109,6 +109,10 @@ #pragma link C++ namespace CbmFsdAddress; #pragma link C++ enum CbmFsdAddress::Level; +#pragma link C++ class CbmMustPoint + ; +#pragma link C++ class CbmMustDigi + ; +#pragma link C++ class CbmMustHit + ; + // --- data/global #pragma link C++ class CbmGlobalTrack + ; #pragma link C++ class CbmVertex + ; diff --git a/core/data/must/CbmMustDigi.cxx b/core/data/must/CbmMustDigi.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5af6165ae5791ae83071c95efe1d3967ca27bf2e --- /dev/null +++ b/core/data/must/CbmMustDigi.cxx @@ -0,0 +1,46 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław Karabowicz [committer] */ + +// ------------------------------------------------------------------------- +// ----- CbmMustDigi header file ----- +// ----- Created 2025-01-26 by R. Karabowicz ----- +// ------------------------------------------------------------------------- + +#include "CbmMustDigi.h" + +#include "CbmDefs.h" +#include "TMath.h" + +#include <iostream> + +/** Default constructor **/ +CbmMustDigi::CbmMustDigi() : TObject() +{ + // ClearDigi(); +} + +CbmMustDigi::CbmMustDigi(Int_t detectorId, Int_t skew, Double_t signalTime, Double_t signalError, Double_t chargeDep) + : TObject() + , fDetectorId(detectorId) + , fSkewed(skew) + , fSignalTime(signalTime) + , fSignalError(signalError) + , fDepCharge(chargeDep) +{ +} + +/** Public method ClearDigi **/ +void CbmMustDigi::ClearDigi() +{ + fDetectorId = 0; + fSkewed = 0; + fSignalTime = 0.; + fSignalError = 0.; + fDepCharge = 0.; +} + +/** Destructor **/ +CbmMustDigi::~CbmMustDigi() {} + +ClassImp(CbmMustDigi) diff --git a/core/data/must/CbmMustDigi.h b/core/data/must/CbmMustDigi.h new file mode 100644 index 0000000000000000000000000000000000000000..d0d90568bfbddd480f3b52ca05dc52da886487d0 --- /dev/null +++ b/core/data/must/CbmMustDigi.h @@ -0,0 +1,92 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław Karabowicz [committer] */ + +// ------------------------------------------------------------------------- +// ----- CbmMustDigi header file ----- +// ----- Created 2025-01-26 by R. Karabowicz ----- +// ------------------------------------------------------------------------- + +/** + ** + ** Meaning of RefIndex: Index of corresponding MCPoint + ** -1 if fake or background digi + ** + ** Meaning of Flag: 0 = Digi ok + ** -1 : Digi lost due to detection inefficiency + **/ + +#ifndef CBMMUSTDIGI_H +#define CBMMUSTDIGI_H 1 + +#include "FairHit.h" +#include "TObject.h" +#include "TVector3.h" + +class CbmMustDigi : public TObject { + + public: + /** Default constructor **/ + CbmMustDigi(); + + /** Standard constructor + *@param detectorId Tube unique volume ID + *@param skew flag for skewed tube + *@param signalTime The signal drift time + *@param signalError The error on signal + *@param chargeDep Deposited charge (arbitrary unit) + **/ + + // THIS ONE! + CbmMustDigi(Int_t detectorId, Int_t skew, Double_t signalTime, Double_t signalError, Double_t chargeDep); + + /** Destructor **/ + virtual ~CbmMustDigi(); + + /** Output to screen (not yet implemented) **/ + virtual void Print(const Option_t* opt = nullptr) const + { + std::cout << " opt = " << opt << std::endl; + return; + } + + /** Public method ClearDigi + ** Resets the isochrone and it's error to 0 + **/ + void ClearDigi(); + + /** Accessors **/ + Double_t GetSignalTime() const { return fSignalTime; }; + Double_t GetSignalError() const { return fSignalError; }; + Double_t GetDepCharge() const { return fDepCharge; }; + Double_t GetEnergyLoss() const { return fDepCharge / 1e6; }; + + Double_t GetTime() const { return fSignalTime; }; + Double_t GetSkewed() const { return fSkewed; }; + + /** Modifiers **/ + void SetSignalTime(Double_t signalTime) { fSignalTime = signalTime; }; + void SetSignalError(Double_t signalError) { fSignalError = signalError; }; + void SetDepCharge(Double_t depcharge) { fDepCharge = depcharge; } + + void SetTime(Double_t signalTime) { fSignalTime = signalTime; }; + + // tube ID // CHECK added + void SetDetectorId(Int_t detectorId) { fDetectorId = detectorId; } + Int_t GetDetectorId() const { return fDetectorId; } + + protected: + Double_t fSignalTime{0.}; + Double_t fSignalError{0.}; + + /** deposit charge (arbitrary units) **/ + Double_t fDepCharge{0.}; + + /** tube id **/ + Int_t fDetectorId{0}; + Int_t fSkewed{0}; + + ClassDef(CbmMustDigi, 1); +}; + +#endif diff --git a/core/data/must/CbmMustHit.cxx b/core/data/must/CbmMustHit.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6e86ef86668f7251ede5d3d4a0e1b6f79142ed61 --- /dev/null +++ b/core/data/must/CbmMustHit.cxx @@ -0,0 +1,51 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław Karabowicz [committer] */ + +// ------------------------------------------------------------------------- +// ----- CbmMustHit source file ----- +// ----- Created 2024-11-26 by R. Karabowicz ----- +// ------------------------------------------------------------------------- + +#include "CbmMustHit.h" + +#include "CbmDefs.h" +#include "TMath.h" + +#include <iostream> +/** Default constructor **/ +CbmMustHit::CbmMustHit() : FairHit() +{ + // ClearHit(); +} + +CbmMustHit::CbmMustHit(Int_t sysId, Int_t detectorId, Int_t skew, Int_t mcindex, TVector3 pos, TVector3 dpos, + TVector3 dir, Double_t pulse, Double_t isochrone, Double_t isochroneError, Double_t chDep) + : FairHit(sysId, pos, dpos, mcindex) + , fDirection(dir) + , fIsochrone(isochrone) + , fIsochroneError(isochroneError) + , fPulse(pulse) + , fDepCharge(chDep) + , fDetectorId(detectorId) + , fSkewed(skew) +{ + SetTimeStamp(pulse); +} + +/** Public method ClearHit **/ +void CbmMustHit::ClearHit() +{ + fDetectorId = 0; + fSkewed = 0; + fPulse = 0; + fIsochrone = 0.; + fIsochroneError = 0.; + fDepCharge = 0.; + fDirection.SetXYZ(0., 0., 0.); +} + +/** Destructor **/ +CbmMustHit::~CbmMustHit() {} + +ClassImp(CbmMustHit) diff --git a/core/data/must/CbmMustHit.h b/core/data/must/CbmMustHit.h new file mode 100644 index 0000000000000000000000000000000000000000..4d6e21205d51270a7b9a7177b5c6eff32376919b --- /dev/null +++ b/core/data/must/CbmMustHit.h @@ -0,0 +1,132 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław Karabowicz [committer] */ + +// ------------------------------------------------------------------------- +// ----- CbmMustHit header file ----- +// ----- Created 2024-11-26 by R. Karabowicz ----- +// ------------------------------------------------------------------------- + +/** + ** + ** Meaning of RefIndex: Index of corresponding MCPoint + ** -1 if fake or background hit + ** + ** Meaning of Flag: 0 = Hit ok + ** -1 : Hit lost due to detection inefficiency + **/ + +#ifndef CBMMUSTHIT_H +#define CBMMUSTHIT_H 1 + +#include "FairHit.h" +#include "TVector3.h" + +class CbmMustHit : public FairHit { + + public: + /** Default constructor **/ + CbmMustHit(); + + /** Standard constructor + *@param sysId Detector system unique volume ID + *@param detectorId Tube unique ID + *@param skew flag for skewed tube + *@param mcindex Index of corresponding MCPoint + *@param pos Position coordinates of the tube [cm] + *@param dpos Errors in position coordinates [cm] + *@param dir Direction of the tube [radians] + *@param p Pulse + *@param isochrone The radial measurement + *@param isoerror The erroon on the radial measurement + *@param chDep Deposited charge (arbitrary unit) + **/ + + // THIS ONE! + CbmMustHit(Int_t sysId, Int_t detectorId, Int_t skew, Int_t mcindex, TVector3 pos, TVector3 dpos, TVector3 dir, + Double_t pulse, Double_t isochrone, Double_t isochroneError, Double_t chDep); + + /** Destructor **/ + virtual ~CbmMustHit(); + + /** Output to screen (not yet implemented) **/ + virtual void Print(const Option_t* opt = nullptr) const + { + std::cout << " opt = " << opt << std::endl; + return; + } + + /** Public method ClearHit + ** Resets the isochrone and it's error to 0 + **/ + void ClearHit(); + + /** Accessors **/ + Double_t GetIsochrone() const { return fIsochrone; }; + Double_t GetIsochroneError() const { return fIsochroneError; }; + Double_t GetPulse() const { return fPulse; }; + Double_t GetDepCharge() const { return fDepCharge; }; + Double_t GetEnergyLoss() const { return fDepCharge / 1e6; }; + + TVector3 GetDirection() const { return fDirection; }; + + /** Modifiers **/ + void SetIsochrone(Double_t isochrone) { fIsochrone = isochrone; }; + void SetIsochroneError(Double_t isochroneError) { fIsochroneError = isochroneError; }; + void SetDepCharge(Double_t depcharge) { fDepCharge = depcharge; } + + // tube ID // CHECK added + void SetDetSysId(Int_t sysId) { fDetSysId = sysId; } + Int_t GetDetSysId() const { return fDetSysId; } + void SetTubeId(Int_t tubeId) { fDetectorId = tubeId; } + Int_t GetTubeId() const { return fDetectorId; } + Int_t GetSkewed() const { return fSkewed; } + + virtual bool equal(FairTimeStamp* data) + { + CbmMustHit* myHit = dynamic_cast<CbmMustHit*>(data); + if (myHit != nullptr) { + if (fDetectorId == myHit->GetTubeId()) return true; + } + return false; + } + + virtual bool operator<(const CbmMustHit& myHit) const + { + if (fDetectorId < myHit.GetTubeId()) + return true; + else + return false; + } + + friend std::ostream& operator<<(std::ostream& out, CbmMustHit& digi) + { + out << "CbmSttHit in Tube: " << digi.GetTubeId() << " Isochrone: " << digi.GetIsochrone() << " +/- " + << digi.GetIsochroneError() << " Charge: " << digi.GetDepCharge() << " Pulse: " << digi.GetPulse() << std::endl; + return out; + } + + protected: + TVector3 fDirection{0., 0., 0.}; + + /** This variable contains the radial distance to the wire **/ + Double_t fIsochrone{0.}; + ; + /** This variable contains the error on the radial distance to the wire **/ + Double_t fIsochroneError{0.}; + + /** time pulse **/ + Double_t fPulse{0.}; + + /** deposit charge (arbitrary units) **/ + Double_t fDepCharge{0.}; + + /** tube id **/ + Int_t fDetSysId{0}; // CHECK added + Int_t fDetectorId{0}; + Int_t fSkewed{0}; + + ClassDef(CbmMustHit, 1); +}; + +#endif diff --git a/core/data/must/CbmMustPoint.cxx b/core/data/must/CbmMustPoint.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ffce57cf2a5310516c992ec84f80bf5abdfb00de --- /dev/null +++ b/core/data/must/CbmMustPoint.cxx @@ -0,0 +1,116 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław 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) + , fMass(0) + , fLayerID(0) + , fModuleID(0) + , fStrawID(0) +{ +} +// ------------------------------------------------------------------------- + +// ----- Standard constructor ------------------------------------------ +CbmMustPoint::CbmMustPoint(Int_t trackID, Int_t detID, Int_t layerID, Int_t moduleID, Int_t strawID, TVector3 pos, + TVector3 posInLocal, TVector3 posOutLocal, TVector3 momIn, TVector3 momOut, Double_t tof, + Double_t length, Double_t eLoss, Double_t mass) + : 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()) + , fMass(mass) + , fLayerID(layerID) + , fModuleID(moduleID) + , fStrawID(strawID) +{ + // 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) + , fMass(point.fMass) + , fLayerID(point.fLayerID) + , fModuleID(point.fModuleID) + , fStrawID(point.fStrawID) +{ +} +// ------------------------------------------------------------------------- + +// ----- 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 << "/" + << fLayerID << "/" << fModuleID << "/" << fStrawID; + 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..8e782506e2ec16acf4304a253054ace1e510cff0 --- /dev/null +++ b/core/data/must/CbmMustPoint.h @@ -0,0 +1,138 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław 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 LayerID MUST layerID (1...12) + *@param moduleID moduleID in layer (1...36) + *@param strawID strawID in module (1...128) + *@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, Int_t layerID, Int_t moduleID, Int_t strawID, TVector3 pos, + TVector3 posInLocal, TVector3 posOutLocal, TVector3 momIn, TVector3 momOut, Double_t tof, + Double_t length, Double_t eLoss, Double_t mass); + + /** 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; } + + Double_t GetMass() const { return fMass; } + + 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); + + // tube ID // CHECK added + Int_t GetLayerID() const { return fLayerID; } + Int_t GetModuleID() const { return fModuleID; } + Int_t GetStrawID() const { return fStrawID; } + void SetLayerID(Int_t layerid) { fLayerID = layerid; } + void SetModuleID(Int_t moduleid) { fModuleID = moduleid; } + void SetStrawID(Int_t strawid) { fStrawID = strawid; } + + /** 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; + // wire direction + // Double_t fX_wire_dir, fY_wire_dir, fZ_wire_dir; + + // particle mass + Double_t fMass; + Int_t fLayerID; + Int_t fModuleID; + Int_t fStrawID; + + ////// + + 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..a8215fc9d290451d136a3af903a9e0cef310d842 --- /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: Radosław Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmGeoMust source file +// +// Class for geometry of MUST +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmGeoFts by Nafija Ibrišimović 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..f18d4ed53f1b1f468afdf6000f242727f67ade70 --- /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: Radosław Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmGeoMust header file +// +// Class for geometry of MUST +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmGeoFts by Nafija Ibrišimović 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..bc48bc12f18db957a79fe6992e690e4c3ddb1413 --- /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: Radosław Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmGeoMustPar source file +// +// Class for geometry parameters of MUST +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmGeoFtsPar by Nafija Ibrišimović 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..ce3058005ff7b4b37755c173e81771ab6090929f --- /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: Radosław Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmGeoMustPar header file +// +// Class for geometry parameters of MUST +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmGeoFtsPar by Nafija Ibrišimović 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..d9631af9c98794ba874696b5c06a4aabd124f9bd --- /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: Radosław Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmMustContFact source file +// +// Factory for the parameter containers in libMust +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmMustContFact by Nafija Ibrišimović 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..5b1537422e6bad2d8fb3d0db7c03667fb70f1ec2 --- /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: Radosław Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmMustContFact header file +// +// Factory for the parameter containers in libMust +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmMustContFact by Nafija Ibrišimović 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..b9de8c744265e1bba08f569ffe0b094152b30649 --- /dev/null +++ b/core/detectors/must/CbmMustGeoScheme.cxx @@ -0,0 +1,195 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław 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 "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 <TMath.h> // for Cos, Sqrt +#include <TObjArray.h> // for TObjArray +#include <TObject.h> // for TObject +#include <TVector3.h> // for TVector3 + +#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(TObjArray* 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"; + TObjArray* stations = file->Get<TObjArray>("stations"); + LOG_IF(fatal, !stations) << "No TObjArray stations found in file " << parFileName; + file->Close(); + file->Delete(); + + /// Restore old global file and folder pointer to avoid messing with FairRoot + gFile = oldFile; + gDirectory = oldDir; + + Init(stations); +} +// ------------------------------------------------------------------------- + + +// ------------------------------------------------------------------------- +CbmMustStation* CbmMustGeoScheme::GetStation(int iStation) const +{ + + if (!fStations) return nullptr; + Bool_t result = (iStation >= 0) || (iStation < fStations->GetEntriesFast()); + + return result ? (CbmMustStation*) fStations->At(iStation) : nullptr; +} +// ------------------------------------------------------------------------- + +CbmMustStation* CbmMustGeoScheme::FindStation(int detid) +{ + if (!fStations) fStations = new TObjArray(); + for (Int_t iobj = 0; iobj < fStations->GetEntriesFast(); iobj++) { + CbmMustStation* tempStation = (CbmMustStation*) (fStations->At(iobj)); + 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 (Int_t iobj = 0; iobj < fStations->GetEntriesFast(); iobj++) { + CbmMustStation* tempStation = (CbmMustStation*) (fStations->At(iobj)); + if (tempStation->GetDetectorId() == station->GetDetectorId()) return false; + } + + fStations->Add(station); + return true; +} + +void CbmMustGeoScheme::Show() +{ + LOG(info) << "MustGeoScheme:"; + for (Int_t iobj = 0; iobj < fStations->GetEntriesFast(); iobj++) { + CbmMustStation* tempStation = (CbmMustStation*) (fStations->At(iobj)); + 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"; + file->WriteObject(fStations, "stations"); + // fStations->Write(); + 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..896174698bd391616abe2593ba87d1bf174f6dfb --- /dev/null +++ b/core/detectors/must/CbmMustGeoScheme.h @@ -0,0 +1,95 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław 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 <TObjArray.h> // for TObjArray +#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 + TObjArray* GetStations() const { return fStations; }; + CbmMustStation* GetStation(int iStation) const; + CbmMustLayer* GetLayer(int iStation, int iLayer) const; + + int GetNStations() const { return fStations->GetEntriesFast(); } + + CbmMustTube* GetTube(int detid); + + CbmMustStation* FindStation(int detid); + bool AddStation(CbmMustStation* station); + void Show(); + void StoreGeoScheme(); + + void Init(TObjArray* 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}; + TObjArray* fStations{nullptr}; //! + 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..1422079cbb99f8c041ab600677feba06d171e0d8 --- /dev/null +++ b/core/detectors/must/CbmMustLayer.cxx @@ -0,0 +1,89 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław 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 (Int_t iobj = 0; iobj < fModules.GetEntriesFast(); iobj++) { + CbmMustModule* tempModule = (CbmMustModule*) (fModules.At(iobj)); + if (tempModule->GetDetectorId() == detid) return tempModule; + } + return nullptr; +} + +bool CbmMustLayer::AddModule(CbmMustModule* module) +{ + for (Int_t iobj = 0; iobj < fModules.GetEntriesFast(); iobj++) { + CbmMustModule* tempModule = (CbmMustModule*) (fModules.At(iobj)); + if (tempModule->GetDetectorId() == module->GetDetectorId()) return false; + } + + fModules.Add(module); + return true; +} + +void CbmMustLayer::Show() +{ + LOG(info) << " Layer " << fDetectorId << " (@ z = " << fZ << "):"; + for (Int_t iobj = 0; iobj < fModules.GetEntriesFast(); iobj++) { + CbmMustModule* tempModule = (CbmMustModule*) (fModules.At(iobj)); + tempModule->Show(); + } +} + +ClassImp(CbmMustLayer) diff --git a/core/detectors/must/CbmMustLayer.h b/core/detectors/must/CbmMustLayer.h new file mode 100644 index 0000000000000000000000000000000000000000..1c60c30e646db93befe94567a53c3afd60cd3274 --- /dev/null +++ b/core/detectors/must/CbmMustLayer.h @@ -0,0 +1,76 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław 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 <TObjArray.h> // for TObjArray +#include <TObject.h> // for TObject + +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.GetEntriesFast(); } + + CbmMustModule* GetModule(int iModule) const { return (CbmMustModule*) 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 + TObjArray 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..26502ec98de8ed04ef51691e1bb41f8e2896bcd2 --- /dev/null +++ b/core/detectors/must/CbmMustModule.cxx @@ -0,0 +1,78 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław 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 (Int_t iobj = 0; iobj < fTubes.GetEntriesFast(); iobj++) { + CbmMustTube* tempTube = (CbmMustTube*) (fTubes.At(iobj)); + if (tempTube->GetTubeNumber() == detid) return tempTube; + } + return nullptr; +} + +bool CbmMustModule::AddTube(CbmMustTube* tube) +{ + for (Int_t iobj = 0; iobj < fTubes.GetEntriesFast(); iobj++) { + CbmMustTube* tempTube = (CbmMustTube*) (fTubes.At(iobj)); + if (tempTube->GetTubeNumber() == tube->GetTubeNumber()) return false; + } + fTubes.Add(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'); + for (Int_t iobj = 0; iobj < fTubes.GetEntriesFast(); iobj++) { + CbmMustTube* tempTube = (CbmMustTube*) (fTubes.At(iobj)); + // 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] = '*'; + } + 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..65f96123cc6ad2acb7ba8c5fc6c42d2c80487ff5 --- /dev/null +++ b/core/detectors/must/CbmMustModule.h @@ -0,0 +1,73 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław 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 <TObjArray.h> // for TObjArray +#include <TObject.h> // for TObject +#include <TVector3.h> // for TVector3 + +#include <map> // for multimap +#include <utility> // for pair + +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.GetEntriesFast(); } + + CbmMustTube* GetTube(int iTube) const { return (CbmMustTube*) fTubes.At(iTube); } + + CbmMustTube* FindTube(int detid); + bool AddTube(CbmMustTube* tube); + void SortTubes() { fTubes.Sort(); } + 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 + TObjArray 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..b72c53e0570f0b588ebbf87403d719cc2c422477 --- /dev/null +++ b/core/detectors/must/CbmMustStation.cxx @@ -0,0 +1,76 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław 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 +#include <TObjArray.h> // for TObjArray + +// ----- 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 (Int_t iobj = 0; iobj < fLayers.GetEntriesFast(); iobj++) { + CbmMustLayer* tempLayer = (CbmMustLayer*) (fLayers.At(iobj)); + if (tempLayer->GetDetectorId() == detid) return tempLayer; + } + return nullptr; +} +// ------------------------------------------------------------------------- + +// ----- Public method AddSector --------------------------------------- +bool CbmMustStation::AddLayer(CbmMustLayer* layer) +{ + for (Int_t iobj = 0; iobj < fLayers.GetEntriesFast(); iobj++) { + CbmMustLayer* tempLayer = (CbmMustLayer*) (fLayers.At(iobj)); + if (tempLayer->GetDetectorId() == layer->GetDetectorId()) return false; + } + + fLayers.Add(layer); + return true; +} +// ------------------------------------------------------------------------- + +void CbmMustStation::Show() +{ + LOG(info) << " Station " << fDetectorId << " (@ z = " << fZ << "):"; + for (Int_t iobj = 0; iobj < fLayers.GetEntriesFast(); iobj++) { + CbmMustLayer* tempLayer = (CbmMustLayer*) (fLayers.At(iobj)); + tempLayer->Show(); + } +} + +ClassImp(CbmMustStation) diff --git a/core/detectors/must/CbmMustStation.h b/core/detectors/must/CbmMustStation.h new file mode 100644 index 0000000000000000000000000000000000000000..9f9ad649b3cbd533c60982a06bc406462ea593f8 --- /dev/null +++ b/core/detectors/must/CbmMustStation.h @@ -0,0 +1,63 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław 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 <TObjArray.h> // for TObjArray +#include <TObject.h> // for TObject + +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.GetEntriesFast(); } + + CbmMustTube* GetTube(int detid); + + CbmMustLayer* GetLayer(int iLayer) const { return (CbmMustLayer*) 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 + TObjArray 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..0481e23ccdec9e90f056362e64424b7e5a22e4c2 --- /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: Radosław 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..ae5d3bf291c6db38b7cb8de89abe806d8d078dec --- /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: Radosław 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; + + ClassDef(CbmMustTube, 1); +}; + +#endif diff --git a/macro/must/run_digi.C b/macro/must/run_digi.C new file mode 100644 index 0000000000000000000000000000000000000000..81a01e16f4f5250221e4064c817bb802e6f88632 --- /dev/null +++ b/macro/must/run_digi.C @@ -0,0 +1,91 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław Karabowicz [committer] */ + +#include <TStopwatch.h> +#include <TString.h> + +#include <iostream> +#include <memory> + +using std::cout; +using std::endl; + +void run_digi() +{ + FairLogger* logger = FairLogger::GetLogger(); + // logger->SetLogFileName("MyLog.log"); + // logger->SetLogToScreen(kTRUE); + // logger->SetLogToFile(kTRUE); + logger->SetLogVerbosityLevel("LOW"); + // logger->SetLogFileLevel("DEBUG4"); + // logger->SetLogScreenLevel("DEBUG"); + + // Verbosity level (0=quiet, 1=event level, 2=track level, 3=debug) + Int_t iVerbose = 0; // just forget about it, for the moment + + // Input file (MC events) + TString inFile = "points.root"; + + // Parameter file + TString parFile = "params.root"; + + // Output file + TString outFile = "digis.root"; + + // ----- Timer -------------------------------------------------------- + TStopwatch timer; + + // ----- Reconstruction run ------------------------------------------- + FairRunAna run{}; + FairFileSource* fFileSource = new FairFileSource(inFile); + run.SetSource(fFileSource); + run.SetSink(std::make_unique<FairRootFileSink>(outFile)); + run.SetUseFairLinks(kTRUE); + FairLinkManager::Instance()->AddIncludeType(0); + // FairLinkManager::Instance()->AddIncludeType(1); + run.SetGenerateRunInfo(kTRUE); // Create FairRunInfo file + + FairRuntimeDb* rtdb = run.GetRuntimeDb(); + FairParRootFileIo* parInput1 = new FairParRootFileIo(); + parInput1->open(parFile.Data()); + rtdb->setFirstInput(parInput1); + + // ----- TorinoDetector hit producers --------------------------------- + CbmMustDigitize* digiTask = new CbmMustDigitize(); + run.AddTask(digiTask); + + run.Init(); + + timer.Start(); + run.Run(); + + // ----- Finish ------------------------------------------------------- + + cout << endl << endl; + + // Extract the maximal used memory an add is as Dart measurement + // This line is filtered by CTest and the value send to CDash + FairSystemInfo sysInfo; + Float_t maxMemory = sysInfo.GetMaxMemory(); + cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">"; + cout << maxMemory; + cout << "</DartMeasurement>" << endl; + + timer.Stop(); + Double_t rtime = timer.RealTime(); + Double_t ctime = timer.CpuTime(); + + Float_t cpuUsage = ctime / rtime; + cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">"; + cout << cpuUsage; + cout << "</DartMeasurement>" << endl; + + cout << endl << endl; + cout << "Output file is " << outFile << endl; + cout << "Parameter file is " << parFile << endl; + cout << "Real time " << rtime << " s, CPU time " << ctime << "s" << endl << endl; + cout << "Macro finished successfully." << endl; + + // ------------------------------------------------------------------------ +} diff --git a/macro/must/run_hit.C b/macro/must/run_hit.C new file mode 100644 index 0000000000000000000000000000000000000000..de6a780034cda80d7e90148a6ed70aef359157a8 --- /dev/null +++ b/macro/must/run_hit.C @@ -0,0 +1,91 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław Karabowicz [committer] */ + +#include <TStopwatch.h> +#include <TString.h> + +#include <iostream> +#include <memory> + +using std::cout; +using std::endl; + +void run_hit() +{ + FairLogger* logger = FairLogger::GetLogger(); + // logger->SetLogFileName("MyLog.log"); + // logger->SetLogToScreen(kTRUE); + // logger->SetLogToFile(kTRUE); + logger->SetLogVerbosityLevel("LOW"); + // logger->SetLogFileLevel("DEBUG4"); + // logger->SetLogScreenLevel("DEBUG"); + + // Verbosity level (0=quiet, 1=event level, 2=track level, 3=debug) + Int_t iVerbose = 0; // just forget about it, for the moment + + // Input file (MC events) + TString inFile = "digis.root"; + + // Parameter file + TString parFile = "params.root"; + + // Output file + TString outFile = "hits.root"; + + // ----- Timer -------------------------------------------------------- + TStopwatch timer; + + // ----- Reconstruction run ------------------------------------------- + FairRunAna run{}; + FairFileSource* fFileSource = new FairFileSource(inFile); + run.SetSource(fFileSource); + run.SetSink(std::make_unique<FairRootFileSink>(outFile)); + run.SetUseFairLinks(kTRUE); + FairLinkManager::Instance()->AddIncludeType(0); + // FairLinkManager::Instance()->AddIncludeType(1); + run.SetGenerateRunInfo(kTRUE); // Create FairRunInfo file + + FairRuntimeDb* rtdb = run.GetRuntimeDb(); + FairParRootFileIo* parInput1 = new FairParRootFileIo(); + parInput1->open(parFile.Data()); + rtdb->setFirstInput(parInput1); + + // ----- TorinoDetector hit producers --------------------------------- + CbmMustFindHits* hitTask = new CbmMustFindHits(); + run.AddTask(hitTask); + + run.Init(); + + timer.Start(); + run.Run(); + + // ----- Finish ------------------------------------------------------- + + cout << endl << endl; + + // Extract the maximal used memory an add is as Dart measurement + // This line is filtered by CTest and the value send to CDash + FairSystemInfo sysInfo; + Float_t maxMemory = sysInfo.GetMaxMemory(); + cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">"; + cout << maxMemory; + cout << "</DartMeasurement>" << endl; + + timer.Stop(); + Double_t rtime = timer.RealTime(); + Double_t ctime = timer.CpuTime(); + + Float_t cpuUsage = ctime / rtime; + cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">"; + cout << cpuUsage; + cout << "</DartMeasurement>" << endl; + + cout << endl << endl; + cout << "Output file is " << outFile << endl; + cout << "Parameter file is " << parFile << endl; + cout << "Real time " << rtime << " s, CPU time " << ctime << "s" << endl << endl; + cout << "Macro finished successfully." << endl; + + // ------------------------------------------------------------------------ +} diff --git a/macro/must/run_sim.C b/macro/must/run_sim.C new file mode 100644 index 0000000000000000000000000000000000000000..07233784a204d9b142f6e83b8d467f9e204cf141 --- /dev/null +++ b/macro/must/run_sim.C @@ -0,0 +1,134 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław Karabowicz [committer] */ + +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 = "tpassive/targetbox_v22c.gdml"; + // Beam pipe geometry + TString pipeGeom = "pipe/pipe_v22d.geo.root"; + // Magnet geometry and field map + TString magnetGeom = "magnet/magnet_v22b.geo.root"; + TString fieldMap = "field_v22d"; + Double_t fieldZ = 50.; // 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/reco/detectors/CMakeLists.txt b/reco/detectors/CMakeLists.txt index 3b70d1eded69c93bc705a925f5e989f8ccf731e7..0cf3fa93893ce71d50f2c4ef811f10fa7439c25c 100644 --- a/reco/detectors/CMakeLists.txt +++ b/reco/detectors/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(bmon) add_subdirectory(much) +add_subdirectory(must) add_subdirectory(mvd) add_subdirectory(psd) add_subdirectory(fsd) diff --git a/reco/detectors/must/CMakeLists.txt b/reco/detectors/must/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..539d73343a913bd6cfe22256813e0e99e6413ca1 --- /dev/null +++ b/reco/detectors/must/CMakeLists.txt @@ -0,0 +1,39 @@ +set(INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_SOURCE_DIR} + ) + +set(SRCS + CbmMustFindHits.cxx + ) + + +set(LIBRARY_NAME CbmMustReco) +set(LINKDEF ${LIBRARY_NAME}LinkDef.h) +set(PUBLIC_DEPENDENCIES + CbmData + CbmMustBase + CbmRecoBase + FairRoot::Base + ROOT::Core + ROOT::Hist + ) + +set(PRIVATE_DEPENDENCIES + CbmBase + CbmQaBase + FairRoot::ParBase + ROOT::Gpad + ROOT::Graf + ROOT::MathCore + ROOT::Physics + ROOT::RHTTP + ROOT::RIO + ) + +set(INTERFACE_DEPENDENCIES + FairLogger::FairLogger + external::fles_ipc + ) + + +generate_cbm_library() diff --git a/reco/detectors/must/CbmMustFindHits.cxx b/reco/detectors/must/CbmMustFindHits.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8c86fb4e3ab79d20e6ea566f5129c58f247e2c90 --- /dev/null +++ b/reco/detectors/must/CbmMustFindHits.cxx @@ -0,0 +1,105 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław Karabowicz [committer] */ + +// ------------------------------------------------------------------------- +// ----- CbmMustFindHits source file ----- +// ----- Created 2025-01-30 by R. Karabowicz ----- +// ------------------------------------------------------------------------- + +/** @file CbmMustFindHits.cxx + ** @author Radoslaw Karabowicz <r.karabowicz@gsi.de> + ** @since 30.01.2025 + **/ +#include "CbmMustFindHits.h" + +#include "CbmMustDigi.h" +#include "CbmMustHit.h" +#include "CbmMustTube.h" +#include "FairRootManager.h" +#include "TFile.h" +#include "TMath.h" +#include "TStopwatch.h" + +#include <algorithm> +#include <iomanip> +#include <iostream> + +using std::cout; +using std::endl; +using std::fixed; +using std::left; +using std::multimap; +using std::right; +using std::setw; +using std::vector; + +// ------------------------------------------------------------------------- +CbmMustFindHits::CbmMustFindHits() : FairTask("MustFindHits", 1) {} + +// ----- Destructor ---------------------------------------------------- +CbmMustFindHits::~CbmMustFindHits() {} +// ------------------------------------------------------------------------- + +// ----- Task execution ------------------------------------------------ +void CbmMustFindHits::Exec(Option_t* /*opt*/) +{ + assert(fDigiArray); + fHitArray->Delete(); + + // LOG(info) << "got " << fDigiArray->GetEntriesFast() << " points"; + for (Int_t iDigi = 0; iDigi < fDigiArray->GetEntriesFast(); iDigi++) { + const CbmMustDigi* digi = (const CbmMustDigi*) fDigiArray->At(iDigi); + if (!digi) LOG(info) << "no digi"; + auto isochrone = GetIsochrone(digi); + + // LOG(info) << "trying to get tube number " << digi->GetDetectorId(); + CbmMustTube* tube = fGeoScheme->GetTube(digi->GetDetectorId()); + if (!tube) LOG(info) << "no tube"; + + CbmMustHit* hit = new ((*fHitArray)[iDigi]) CbmMustHit( + 7, digi->GetDetectorId(), digi->GetSkewed(), 0, tube->GetPosition(), {0., 0., 0.}, tube->GetWireDirection(), + digi->GetSignalTime(), isochrone.first, isochrone.second, digi->GetDepCharge()); + } +} +// ------------------------------------------------------------------------- + +// ----- Private function to get isochronoe ---------------------------- +std::pair<double, double> CbmMustFindHits::GetIsochrone(const CbmMustDigi* digi) +{ + return std::pair<double, double>(digi->GetSignalTime() / 400., digi->GetSignalError() / 400.); +} +// ------------------------------------------------------------------------- + + +// ----- Initialisation ----------------------------------------------- +InitStatus CbmMustFindHits::Init() +{ + FairRootManager* ioman = FairRootManager::Instance(); + if (!ioman) { + std::cout << "-E- CbmMustFindHits::Init: " /// todo replace with logger! + << "RootManager not instantiated!" << std::endl; + return kFATAL; + } + + fDigiArray = static_cast<TClonesArray*>(ioman->GetObject("MUSTDigi")); + if (!fDigiArray) { + std::cout << "-W- CbmMustFindHits::Init: " + << "No Digi array!" << std::endl; + return kERROR; + } + + // Create and register output array + fHitArray = new TClonesArray("CbmMustHit"); + ioman->Register("MUSTHit", "MUST", fHitArray, kTRUE); + + fGeoScheme = CbmMustGeoScheme::Instance(); + fGeoScheme->Init("$VMCWORKDIR/parameters/must/must_geoScheme.root"); + + fGeoScheme->Show(); + + return kSUCCESS; +} +// ------------------------------------------------------------------------- + +ClassImp(CbmMustFindHits) diff --git a/reco/detectors/must/CbmMustFindHits.h b/reco/detectors/must/CbmMustFindHits.h new file mode 100644 index 0000000000000000000000000000000000000000..ce883f2a729394db1464903e1b16320c2ee6e4ae --- /dev/null +++ b/reco/detectors/must/CbmMustFindHits.h @@ -0,0 +1,48 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław Karabowicz [committer] */ + +// ------------------------------------------------------------------------- +// ----- CbmMustFindHits header file ----- +// ----- Created 2025-01-30 by R. Karabowicz ----- +// ------------------------------------------------------------------------- + +/** @file CbmMustDigitize.cxx + ** @author Radoslaw Karabowicz <r.karabowicz@gsi.de> + ** @since 30.01.2025 + **/ + +#ifndef CBMMUSTFINDHITS_H +#define CBMMUSTFINDHITS_H 1 + +#include "CbmMustDigi.h" +#include "CbmMustGeoScheme.h" +#include "FairTask.h" +#include "TClonesArray.h" +#include "TString.h" + +#include <vector> + +class CbmMustFindHits : public FairTask { + public: + CbmMustFindHits(); + virtual ~CbmMustFindHits(); + virtual void Exec(Option_t* opt); + + private: + virtual InitStatus Init(); + TString fDigiFile = "must_geoScheme.root"; // Digitization file + + TClonesArray* fDigiArray{nullptr}; + TClonesArray* fHitArray{nullptr}; + CbmMustGeoScheme* fGeoScheme{nullptr}; // Geometry scheme + + std::pair<double, double> GetIsochrone(const CbmMustDigi* digi); + + CbmMustFindHits(const CbmMustFindHits&); + CbmMustFindHits operator=(const CbmMustFindHits&); + + ClassDef(CbmMustFindHits, 1); +}; + +#endif diff --git a/reco/detectors/must/CbmMustRecoLinkDef.h b/reco/detectors/must/CbmMustRecoLinkDef.h new file mode 100644 index 0000000000000000000000000000000000000000..2da13a8a0684b39b14242e6004eca012af64d135 --- /dev/null +++ b/reco/detectors/must/CbmMustRecoLinkDef.h @@ -0,0 +1,13 @@ +/* Copyright (C) 2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Florian Uhlig [committer] */ + +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class CbmMustFindHits + ; + +#endif 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..4bc2ceb0b272f280e83953e397a0299fef3c9a5b --- /dev/null +++ b/sim/detectors/must/CMakeLists.txt @@ -0,0 +1,36 @@ +set(INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_SOURCE_DIR} + ) + + +set(SRCS + CbmMust.cxx + CbmMustDigitize.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..a82f025c17e46f8d489df0360dac4e8ec7db6710 --- /dev/null +++ b/sim/detectors/must/CbmMust.cxx @@ -0,0 +1,482 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmMust source file +// +// Class for simulation of MUST +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmMust by Nafija Ibrišimović 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 = 1; + int layerId = atoi(strawName.substr(1, 2).c_str()); + int moduleId = atoi(strawName.substr(3, 2).c_str()); + int strawId = atoi(strawName.substr(5, 3).c_str()); + + 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 == 2 || layerId == 3) { + 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, layerId, moduleId, strawId, 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, fMass); + + 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; + TObjArray* stations = CbmMustGeoScheme::Instance()->GetStations(); + for (Int_t iobj = 0; iobj < stations->GetEntriesFast(); iobj++) { + CbmMustStation* tempStation = (CbmMustStation*) (stations->At(iobj)); + 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) << "Constructing 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, Int_t layID, Int_t modID, Int_t strID, TVector3 pos, + TVector3 posInLocal, TVector3 posOutLocal, TVector3 momIn, TVector3 momOut, Double_t time, + Double_t length, Double_t eLoss, Double_t mass) +{ + TClonesArray& clref = *fMustCollection; + + Int_t size = clref.GetEntriesFast(); + + CbmMustPoint* pointnew = new (clref[size]) CbmMustPoint(trackID, detID, layID, modID, strID, pos, posInLocal, + posOutLocal, momIn, momOut, time, length, eLoss, mass); + + return pointnew; +} +// ------------------------------------------------------------------------- + +ClassImp(CbmMust) diff --git a/sim/detectors/must/CbmMust.h b/sim/detectors/must/CbmMust.h new file mode 100644 index 0000000000000000000000000000000000000000..dcc47e30468ac65326444b064a3b0680d938f4fd --- /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: Radosław Karabowicz [committer] */ + +//////////////////////////////////////////////////////////////////////////// +// CbmMust header file +// +// Class for simulation of MUST +// +// authors: Radoslaw Karabowicz, GSI, 2024 +// +// modified from CbmMust by Nafija Ibrišimović 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, Int_t layID, Int_t modID, Int_t strID, TVector3 pos, + TVector3 posInLocal, TVector3 posOutLocal, TVector3 momIn, TVector3 momOut, Double_t time, + Double_t length, Double_t eLoss, Double_t mass); + + /** 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/CbmMustDigitize.cxx b/sim/detectors/must/CbmMustDigitize.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9e3c402723bced36417d7df99f25fd257adda5f3 --- /dev/null +++ b/sim/detectors/must/CbmMustDigitize.cxx @@ -0,0 +1,118 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław Karabowicz [committer] */ + +// ------------------------------------------------------------------------- +// ----- CbmMustDigitize source file ----- +// ----- Created 2025-01-30 by R. Karabowicz ----- +// ------------------------------------------------------------------------- + +/** @file CbmMustDigitize.cxx + ** @author Radoslaw Karabowicz <r.karabowicz@gsi.de> + ** @since 30.01.2025 + **/ + +// Include class header +#include "CbmMustDigitize.h" + +// Includes from ROOT +#include "TClonesArray.h" + +// Includes from FairRoot +#include "FairEventHeader.h" +#include "FairField.h" +#include "FairLink.h" +#include "FairMCEventHeader.h" +#include "FairMCPoint.h" +#include "FairRunAna.h" +#include "FairRunSim.h" +#include "FairRuntimeDb.h" + +#include <Logger.h> + +// Includes from CbmRoot +#include "CbmMCTrack.h" +#include "CbmMustDigi.h" +#include "CbmMustPoint.h" + +// ----- Standard constructor ------------------------------------------ +CbmMustDigitize::CbmMustDigitize() : FairTask("MustDigitizer") {} +// ------------------------------------------------------------------------- + + +// ----- Destructor ---------------------------------------------------- +CbmMustDigitize::~CbmMustDigitize() {} +// ------------------------------------------------------------------------- + +// ----- Task execution ------------------------------------------------ +void CbmMustDigitize::Exec(Option_t* /*opt*/) +{ + assert(fPointArray); + fDigiArray->Delete(); + + // LOG(info) << "got " << fPointArray->GetEntriesFast() << " points"; + for (Int_t iPoint = 0; iPoint < fPointArray->GetEntriesFast(); iPoint++) { + const CbmMustPoint* point = (const CbmMustPoint*) fPointArray->At(iPoint); + // LOG(info) << "point from " << point->GetXInLocal() << "," << point->GetYInLocal() << "," << point->GetZInLocal() + // << " to " << point->GetXOutLocal() << "," << point->GetYOutLocal() << "," << point->GetZOutLocal(); + int detectorId = 1e7 + point->GetLayerID() * 1e5 + point->GetModuleID() * 1e3 + point->GetStrawID(); + int skew = 0; + if (point->GetLayerID() == 2) skew = 1; + if (point->GetLayerID() == 3) skew = -11; + + double driftTime = GetDriftTime(point); + + // ideal output... + CbmMustDigi* digi = new ((*fDigiArray)[iPoint]) CbmMustDigi(detectorId, skew, driftTime, 5, 1); + } +} +// ------------------------------------------------------------------------- + +// ----- Private function to get drift time ---------------------------- +double CbmMustDigitize::GetDriftTime(const CbmMustPoint* point) +{ + double closestDist = + TMath::Sqrt((point->GetXInLocal() + point->GetXOutLocal()) * (point->GetXInLocal() + point->GetXOutLocal()) + + (point->GetYInLocal() + point->GetYOutLocal()) * (point->GetYInLocal() + point->GetYOutLocal())); + // LOG(info) << "closest distance = " << closestDist << " cm ---> " << closestDist*400. << " ns"; + return closestDist * 400.; +} +// ------------------------------------------------------------------------- + +// ----- Finish run --------------------------------------------------- +void CbmMustDigitize::Finish() {} +// ------------------------------------------------------------------------- + +// ----- Initialisation ----------------------------------------------- +InitStatus CbmMustDigitize::Init() +{ + FairRootManager* ioman = FairRootManager::Instance(); + if (!ioman) { + std::cout << "-E- CbmMustDigitize::Init: " /// todo replace with logger! + << "RootManager not instantiated!" << std::endl; + return kFATAL; + } + + fPointArray = static_cast<TClonesArray*>(ioman->GetObject("MUSTPoint")); + if (!fPointArray) { + std::cout << "-W- CbmMustDigitize::Init: " + << "No Point array!" << std::endl; + return kERROR; + } + + // Create and register output array + fDigiArray = new TClonesArray("CbmMustDigi"); + ioman->Register("MUSTDigi", "MUST", fDigiArray, kTRUE); + + // Set static initialisation flag + fIsInitialised = kTRUE; + + return kSUCCESS; +} +// ------------------------------------------------------------------------- + +// ----- Private method ReInit ----------------------------------------- +InitStatus CbmMustDigitize::ReInit() { return kSUCCESS; } +// ------------------------------------------------------------------------- + +ClassImp(CbmMustDigitize) diff --git a/sim/detectors/must/CbmMustDigitize.h b/sim/detectors/must/CbmMustDigitize.h new file mode 100644 index 0000000000000000000000000000000000000000..8a28b69f2d036ce82a595540d4ef7f3de1951250 --- /dev/null +++ b/sim/detectors/must/CbmMustDigitize.h @@ -0,0 +1,61 @@ +/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Radosław Karabowicz [committer] */ + +// ------------------------------------------------------------------------- +// ----- CbmMustDigitize header file ----- +// ----- Created 2025-01-30 by R. Karabowicz ----- +// ------------------------------------------------------------------------- + +#ifndef CBMMUSTDIGITIZE_H +#define CBMMUSTDIGITIZE_H 1 + +#include "CbmDefs.h" +#include "CbmDigitize.h" +#include "CbmMustDigi.h" +#include "CbmMustPoint.h" + +/** @class CbmMustDigitize + ** @brief Task class for simulating the detector response of the MUST + ** @author Radoslaw Karabowicz <r.karabowicz@gsi.de> + ** @since 30.01.2025 + ** @version 1.0 + ** + **/ +class CbmMustDigitize : public FairTask { + + public: + /** Constructor **/ + CbmMustDigitize(); + + /** Destructor **/ + virtual ~CbmMustDigitize(); + + /** Virtual method Exec **/ + void Exec(Option_t* opt) override; + + /** Re-initialisation **/ + virtual InitStatus ReInit(); + + private: + Bool_t fIsInitialised; ///< kTRUE if Init() was called + + TClonesArray* fPointArray{nullptr}; ///< Input array of CbmMustPoint + TClonesArray* fDigiArray{nullptr}; + + double GetDriftTime(const CbmMustPoint* point); + + /** End-of-run action **/ + void Finish() override; + + /** Initialisation **/ + InitStatus Init() override; + + /** Prevent usage of copy constructor and assignment operator **/ + CbmMustDigitize(const CbmMustDigitize&); + CbmMustDigitize operator=(const CbmMustDigitize&); + + ClassDef(CbmMustDigitize, 1); +}; + +#endif diff --git a/sim/detectors/must/CbmMustSimLinkDef.h b/sim/detectors/must/CbmMustSimLinkDef.h new file mode 100644 index 0000000000000000000000000000000000000000..3f56058f4eb7eb602992b3621e7ea034d0d71fe6 --- /dev/null +++ b/sim/detectors/must/CbmMustSimLinkDef.h @@ -0,0 +1,14 @@ +/* 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 + ; +#pragma link C++ class CbmMustDigitize + ; + +#endif /* __CINT__ */