CbmRoot
Loading...
Searching...
No Matches
CbmTaskStsHitFinderParWrite.cxx
Go to the documentation of this file.
1/* Copyright (C) 2024-2025 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Felix Weiglhofer [committer] */
4
6
7#include "CbmAddress.h"
8#include "CbmStsModule.h"
10#include "CbmStsParSetSensor.h"
12#include "CbmStsParSim.h"
13#include "CbmStsPhysics.h"
14#include "CbmStsRecoModule.h"
15#include "CbmStsSetup.h"
16#include "CbmYaml.h"
18
19#include <FairField.h>
20#include <FairRootManager.h>
21#include <FairRun.h>
22#include <FairRuntimeDb.h>
23
24#include <TGeoBBox.h>
25#include <TGeoPhysicalNode.h>
26
27#include <boost/filesystem.hpp>
28
29#include <iomanip>
30
31// ----- Constructor ---------------------------------------------------
32CbmTaskStsHitFinderParWrite::CbmTaskStsHitFinderParWrite() : FairTask("CbmTaskStsHitFinderParWrite", 1) {}
33// -------------------------------------------------------------------------
34
35
36// ----- Destructor ----------------------------------------------------
38// -------------------------------------------------------------------------
39
40
41// ----- Initialise the cluster finding modules ------------------------
43{
44 assert(fSetup);
45
46 std::vector<cbm::algo::sts::HitfinderPars::Module> gpuModules; // for gpu reco
47
48 LOG(info) << GetName() << ": Creating modules";
49 LOG(info) << fParSetSensor->ToString();
50
51 for (Int_t iModule = 0; iModule < fSetup->GetNofModules(); iModule++) {
52
53 // --- Setup module and sensor
54 CbmStsModule* setupModule = fSetup->GetModule(iModule);
55 assert(setupModule);
56 Int_t moduleAddress = Int_t(setupModule->GetAddress());
57 assert(setupModule->GetNofDaughters() == 1);
58 CbmStsElement* setupSensor = setupModule->GetDaughter(0);
59 assert(setupSensor);
60 Int_t sensorAddress = Int_t(setupSensor->GetAddress());
61
62 // --- Module parameters
63 const CbmStsParModule& modPar = fParSetModule->GetParModule(moduleAddress);
64 const CbmStsParSensor& sensPar = fParSetSensor->GetParSensor(sensorAddress);
65 const CbmStsParSensorCond& sensCond = fParSetCond->GetParSensor(sensorAddress);
66
67 // --- Calculate and set average Lorentz shift
68 // --- This will be used in hit finding for correcting the position.
69 Double_t lorentzF = 0.;
70 Double_t lorentzB = 0.;
71 if (fParSim->LorentzShift()) {
72
73 TGeoBBox* shape = dynamic_cast<TGeoBBox*>(setupSensor->GetPnode()->GetShape());
74 assert(shape);
75 Double_t dZ = 2. * shape->GetDZ(); // Sensor thickness
76
77 // Get the magnetic field in the sensor centre
78 Double_t by = 0.;
79 if (FairRun::Instance()->GetField()) {
80 Double_t local[3] = {0., 0., 0.}; // sensor centre in local C.S.
81 Double_t global[3]; // sensor centre in global C.S.
82 setupSensor->GetPnode()->GetMatrix()->LocalToMaster(local, global);
83 Double_t field[3] = {0., 0., 0.}; // magnetic field components
84 FairRun::Instance()->GetField()->Field(global, field);
85 by = field[1] / 10.; // kG->T
86 } //? field present
87
88 // Calculate average Lorentz shift on sensor sides.
89 // This is needed in hit finding for correcting the cluster position.
90 auto lorentzShift = LorentzShift(sensCond, dZ, by);
91 lorentzF = lorentzShift.first;
92 lorentzB = lorentzShift.second;
93 } //? Lorentz-shift correction
94
95 // --- Create reco module
96 CbmStsRecoModule recoModule{setupModule, modPar, sensPar, lorentzF, lorentzB};
97
98 // Get Transformation Matrix
100 TGeoHMatrix* matrix = recoModule.getMatrix();
101 std::copy_n(matrix->GetRotationMatrix(), 9, localToGlobal.rotation.begin());
102 std::copy_n(matrix->GetTranslation(), 3, localToGlobal.translation.begin());
103
104 // Collect GPU parameters
106 .address = moduleAddress,
107 .dY = sensPar.GetPar(3),
108 .pitch = sensPar.GetPar(6),
109 .stereoF = sensPar.GetPar(8),
110 .stereoB = sensPar.GetPar(9),
111 .lorentzF = float(lorentzF),
112 .lorentzB = float(lorentzB),
113 .localToGlobal = localToGlobal,
114 };
115 gpuModules.emplace_back(gpuModulePars);
116 }
117
118 const CbmStsParModule& firstModulePars = fParSetModule->GetParModule(gpuModules[0].address);
119
120 CbmStsParAsic asic = firstModulePars.GetParAsic(0);
122 .nAdc = asic.GetNofAdc(),
123 .dynamicRange = float(asic.GetDynRange()),
124 .threshold = float(asic.GetThreshold()),
125 .timeResolution = float(asic.GetTimeResol()),
126 .deadTime = float(asic.GetDeadTime()),
127 .noise = float(asic.GetNoise()),
128 .zeroNoiseRate = float(asic.GetZeroNoiseRate()),
129 };
130
131 int nChannels = firstModulePars.GetNofChannels();
132
133 auto [landauValues, landauStepSize] = CbmStsPhysics::Instance()->GetLandauWidthTable();
134 std::vector<float> landauValuesF;
135 std::copy(landauValues.begin(), landauValues.end(), std::back_inserter(landauValuesF));
137 .asic = algoAsic,
138 .nChannels = nChannels,
139 .modules = gpuModules,
140 .landauTable =
141 {
142 .values = landauValuesF,
143 .stepSize = float(landauStepSize),
144 },
145 };
146
147 // Write to file
148 {
149 namespace fs = boost::filesystem;
150 fs::path filePath = fs::absolute(fs::weakly_canonical(fsRecoParOutputDir + "/StsHitfinder.yaml"));
151 std::ofstream{filePath.string()} << cbm::algo::yaml::Dump{}(pars, 4);
152 }
153
154 return pars.modules.size();
155}
156// -------------------------------------------------------------------------
157
158
159// ----- Initialisation ------------------------------------------------
161{
162
163 // --- Something for the screen
164 LOG(info) << "==========================================================";
165 LOG(info) << GetName() << ": Initialising ";
166
167 // --- Check IO-Manager
168 FairRootManager* ioman = FairRootManager::Instance();
169 assert(ioman);
170
171 // --- Simulation settings
172 assert(fParSim); // Set from SetParContainers()
173 LOG(info) << GetName() << ": Sim settings " << fParSim->ToString();
174
175 // --- Parameters
176 InitParams();
177
178 // --- Initialise STS setup
180 fSetup->Init(nullptr);
181 //fSetup->SetSensorParameters(fParSetSensor);
182
183 // --- Create reconstruction modules
184 UInt_t nModules = CreateModules();
185 LOG(info) << GetName() << ": Created " << nModules << " modules";
186
187 LOG(info) << GetName() << ": Initialisation successful.";
188 LOG(info) << "==========================================================";
189
190 return kSUCCESS;
191}
192// -------------------------------------------------------------------------
193
194
195// ----- Parameter initialisation --------------------------------------
197{
198
199 // --- Module parameters
200 TString sourceModu = "database";
201 assert(fParSetModule);
202 if (fUserParSetModule) {
203 fParSetModule->clear();
205 fParSetModule->setChanged();
206 fParSetModule->setInputVersion(-2, 1);
207 sourceModu = "user-defined";
208 }
209 if (fUserParModule) { // global settings override
210 fParSetModule->clear();
211 fParSetModule->SetGlobalPar(*fUserParModule);
212 fParSetModule->setChanged();
213 fParSetModule->setInputVersion(-2, 1);
214 sourceModu = "user-defined, global";
215 }
216 LOG(info) << GetName() << ": Module parameters (" << sourceModu << ") " << fParSetModule->ToString();
217
218 // --- Sensor parameters
219 TString sourceSens = "database";
220 assert(fParSetSensor);
221 if (fUserParSetSensor) {
222 fParSetSensor->clear();
224 fParSetSensor->setChanged();
225 fParSetSensor->setInputVersion(-2, 1);
226 sourceSens = "user-defined";
227 }
228 if (fUserParSensor) { // global settings override
229 fParSetSensor->clear();
230 fParSetSensor->SetGlobalPar(*fUserParSensor);
231 fParSetSensor->setChanged();
232 fParSetSensor->setInputVersion(-2, 1);
233 sourceSens = "user-defined, global";
234 }
235 LOG(info) << GetName() << ": Sensor parameters (" << sourceSens << ")" << fParSetSensor->ToString();
236
237 // --- Sensor conditions
238 TString sourceCond = "database";
239 assert(fParSetCond);
240 if (fUserParSetCond) {
241 fParSetCond->clear();
243 fParSetCond->setChanged();
244 fParSetCond->setInputVersion(-2, 1);
245 sourceSens = "user-defined";
246 }
247 if (fUserParCond) { // global settings override
248 fParSetCond->clear();
249 fParSetCond->SetGlobalPar(*fUserParCond);
250 fParSetCond->setChanged();
251 fParSetCond->setInputVersion(-2, 1);
252 sourceCond = "user-defined, global";
253 }
254 LOG(info) << GetName() << ": Sensor conditions (" << sourceCond << ")" << fParSetCond->ToString();
255}
256// -------------------------------------------------------------------------
257
258// ----- Calculate the mean Lorentz shift in a sensor ------------------
259std::pair<Double_t, Double_t> CbmTaskStsHitFinderParWrite::LorentzShift(const CbmStsParSensorCond& conditions,
260 Double_t dZ, Double_t bY)
261{
262
263 Double_t vBias = conditions.GetVbias(); // Bias voltage
264 Double_t vFd = conditions.GetVfd(); // Full-depletion voltage
265 Double_t eField = (vBias + vFd) / dZ; // Electric field
266
267 // --- Integrate in 1000 steps over the sensor thickness
268 Int_t nSteps = 1000;
269 Double_t deltaZ = dZ / nSteps;
270 Double_t dxMeanE = 0.;
271 Double_t dxMeanH = 0.;
272 for (Int_t j = 0; j <= nSteps; j++) {
273 eField -= 2 * vFd / dZ * deltaZ / dZ; // Electric field [V/cm]
274 Double_t muHallE = conditions.GetHallMobility(eField, 0);
275 Double_t muHallH = conditions.GetHallMobility(eField, 1);
276 dxMeanE += muHallE * (dZ - Double_t(j) * deltaZ);
277 dxMeanH += muHallH * Double_t(j) * deltaZ;
278 }
279 dxMeanE /= Double_t(nSteps);
280 dxMeanH /= Double_t(nSteps);
281 Double_t shiftF = dxMeanE * bY * 1.e-4;
282 Double_t shiftB = dxMeanH * bY * 1.e-4;
283 // The factor 1.e-4 is because bZ is in T = Vs/m**2, but muHall is in
284 // cm**2/(Vs) and z in cm.
285
286 return {shiftF, shiftB};
287}
288// -------------------------------------------------------------------------
289
290// ----- Connect parameter container -----------------------------------
292{
293 FairRuntimeDb* db = FairRun::Instance()->GetRuntimeDb();
294 fParSim = dynamic_cast<CbmStsParSim*>(db->getContainer("CbmStsParSim"));
295 fParSetModule = dynamic_cast<CbmStsParSetModule*>(db->getContainer("CbmStsParSetModule"));
296 fParSetSensor = dynamic_cast<CbmStsParSetSensor*>(db->getContainer("CbmStsParSetSensor"));
297 fParSetCond = dynamic_cast<CbmStsParSetSensorCond*>(db->getContainer("CbmStsParSetSensorCond"));
298}
299// -------------------------------------------------------------------------
int Int_t
Class representing an element of the STS setup.
Int_t GetAddress() const
TGeoPhysicalNode * GetPnode() const
Int_t GetNofDaughters() const
CbmStsElement * GetDaughter(Int_t index) const
Class representing an instance of a readout unit in the CBM-STS.
Parameters of the STS readout ASIC.
double GetDynRange() const
Dynamic range of ADC.
uint16_t GetNofAdc() const
Number of ADC channels.
double GetZeroNoiseRate() const
Zero-crossing noise rate.
double GetNoise() const
Electronic noise RMS.
double GetThreshold() const
ADC Threshold.
double GetTimeResol() const
Time resolution.
double GetDeadTime() const
Single-channel dead time.
Parameters for one STS module.
uint32_t GetNofChannels() const
Number of channels.
const CbmStsParAsic & GetParAsic(uint32_t channel) const
ASIC parameters for a given channel.
Parameters for operating conditions of a STS sensor.
Double_t GetVbias() const
Bias voltage.
Double_t GetHallMobility(Double_t eField, Int_t chargeType) const
Hall mobility.
Constructional parameters of a STS sensor.
Float_t GetPar(UInt_t index) const
Get a parameter.
Parameters container for CbmStsParModule.
Parameters container for CbmStsParSensorCond.
Parameters container for CbmStsParSensor.
Settings for STS simulation (digitizer)
std::pair< std::vector< double >, double > GetLandauWidthTable() const
Raw values of landau width interpolation table.
static CbmStsPhysics * Instance()
Accessor to singleton instance.
Class for reconstruction in one STS module.
static CbmStsSetup * Instance()
CbmStsParSetSensorCond * fParSetCond
Sensor conditions.
virtual void SetParContainers()
Define the needed parameter containers.
void InitParams()
Initialise parameters.
std::pair< Double_t, Double_t > LorentzShift(const CbmStsParSensorCond &conditions, Double_t dZ, Double_t bY)
Average Lorentz Shift in a sensor.
UInt_t CreateModules()
Instantiate reconstruction modules @value Number of modules created.
CbmStsParSetModule * fParSetModule
Module parameters.
CbmStsParSim * fParSim
Instance of STS setup.
virtual ~CbmTaskStsHitFinderParWrite()
Destructor.
CbmStsParSetSensor * fParSetSensor
Sensor parameters.
virtual InitStatus Init()
Initialisation.
std::vector< Module > modules