FairShip
Loading...
Searching...
No Matches
splitcal.cxx
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-3.0-or-later
2// SPDX-FileCopyrightText: Copyright CERN for the benefit of the SHiP
3// Collaboration
4
5#include "splitcal.h"
6
7#include <iostream>
8
9#include "FairGeoBuilder.h"
10#include "FairGeoInterface.h"
11#include "FairGeoLoader.h"
12#include "FairGeoMedia.h"
13#include "FairGeoNode.h"
14#include "FairGeoVolume.h"
15#include "FairRootManager.h"
16#include "FairRun.h"
17#include "FairRuntimeDb.h"
18#include "FairVolume.h"
19#include "ShipDetectorList.h"
20#include "ShipGeoUtil.h"
21#include "ShipStack.h"
22#include "TCanvas.h"
23#include "TClonesArray.h"
24#include "TGeoBBox.h"
25#include "TGeoCompositeShape.h"
26#include "TGeoManager.h"
27#include "TGeoMaterial.h"
28#include "TGeoMedium.h"
29#include "TGeoShapeAssembly.h"
30#include "TGeoTube.h"
31#include "TParticle.h"
32#include "TROOT.h"
33#include "TView3D.h"
34#include "TVirtualMC.h"
35#include "splitcalPoint.h"
36using std::cout;
37using std::endl;
38
39splitcal::splitcal() : Detector("splitcal", kTRUE, kSplitCal) {}
40
41splitcal::splitcal(const char* name, Bool_t active)
42 : Detector(name, active, kSplitCal) {}
43
44Bool_t splitcal::ProcessHits(FairVolume* vol) {
46 // Set parameters at entrance of volume. Reset ELoss.
47 if (gMC->IsTrackEntering()) {
48 fELoss = 0.;
49 fTime = gMC->TrackTime() * 1.0e09;
50 fLength = gMC->TrackLength();
51 gMC->TrackPosition(fPos);
52 gMC->TrackMomentum(fMom);
53 }
54
55 // Sum energy loss for all steps in the active volume
56 fELoss += gMC->Edep();
57
58 // Create splitcalPoint at exit of active volume
59 if (gMC->IsTrackExiting() || gMC->IsTrackStop() ||
60 gMC->IsTrackDisappeared()) {
61 fEventID = gMC->CurrentEvent();
62 fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
63 Int_t detID = 0;
64 gMC->CurrentVolID(detID);
65
66 fVolumeID = detID;
67 if (fELoss == 0.) {
68 return kFALSE;
69 }
70 TParticle* p = gMC->GetStack()->GetCurrentTrack();
71 Int_t pdgCode = p->GetPdgCode();
73 TVector3(fPos.X(), fPos.Y(), fPos.Z()),
74 TVector3(fMom.Px(), fMom.Py(), fMom.Pz()), fTime, fLength, fELoss,
75 pdgCode);
76
77 // Increment number of splitcal det points in TParticle
78 ShipStack* stack = dynamic_cast<ShipStack*>(gMC->GetStack());
79 stack->AddPoint(kSplitCal);
80 }
81
82 return kTRUE;
83}
84
85void splitcal::SetZStart(Double_t ZStart) { fZStart = ZStart; }
86void splitcal::SetEmpty(Double_t Empty, Double_t BigGap,
87 Double_t ActiveECAL_gas_gap,
88 Double_t first_precision_layer,
89 Double_t second_precision_layer,
90 Double_t third_precision_layer,
91 Double_t num_precision_layers) {
92 fEmpty = Empty;
93 fBigGap = BigGap;
94 fActiveECAL_gas_gap = ActiveECAL_gas_gap;
95 ffirst_precision_layer = first_precision_layer;
96 fsecond_precision_layer = second_precision_layer;
97 fthird_precision_layer = third_precision_layer;
98 fnum_precision_layers = num_precision_layers;
99}
100
101void splitcal::SetThickness(Double_t ActiveECALThickness,
102 Double_t ActiveHCALThickness,
103 Double_t FilterECALThickness,
104 Double_t FilterECALThickness_first,
105 Double_t FilterHCALThickness,
106 Double_t ActiveECAL_gas_Thickness) {
107 fActiveECALThickness = ActiveECALThickness;
108 fActiveHCALThickness = ActiveHCALThickness;
109 fFilterECALThickness = FilterECALThickness;
110 fFilterECALThickness_first = FilterECALThickness_first;
111 fFilterHCALThickness = FilterHCALThickness;
112 fActiveECAL_gas_Thickness = ActiveECAL_gas_Thickness;
113}
114void splitcal::SetMaterial(Double_t ActiveECALMaterial,
115 Double_t ActiveHCALMaterial,
116 Double_t FilterECALMaterial,
117 Double_t FilterHCALMaterial) {
118 fActiveECALMaterial = ActiveECALMaterial;
119 fActiveHCALMaterial = ActiveHCALMaterial;
120 fFilterECALMaterial = FilterECALMaterial;
121 fFilterHCALMaterial = FilterHCALMaterial;
122}
123
124void splitcal::SetNSamplings(Int_t nECALSamplings, Int_t nHCALSamplings,
125 Double_t ActiveHCAL) {
126 fnHCALSamplings = nHCALSamplings;
127 fnECALSamplings = nECALSamplings;
128 fActiveHCAL = ActiveHCAL;
129}
130
131void splitcal::SetNModules(Int_t nModulesInX, Int_t nModulesInY) {
132 fNModulesInX = nModulesInX;
133 fNModulesInY = nModulesInY;
134}
135
136void splitcal::SetNStrips(Int_t nStrips) { fNStripsPerModule = nStrips; }
137
138void splitcal::SetStripSize(Double_t stripHalfWidth, Double_t stripHalfLength) {
139 fStripHalfWidth = stripHalfWidth;
140 fStripHalfLength = stripHalfLength;
141}
142
143void splitcal::SetXMax(Double_t xMax) { fXMax = xMax; }
144void splitcal::SetYMax(Double_t yMax) { fYMax = yMax; }
150 TGeoVolume* top = gGeoManager->GetTopVolume();
151 TGeoVolume* tSplitCal = new TGeoVolumeAssembly("SplitCalDetector");
152
153 ShipGeo::InitMedium("iron");
154 ShipGeo::InitMedium("lead");
155 ShipGeo::InitMedium("Scintillator");
156 ShipGeo::InitMedium("argon");
157 ShipGeo::InitMedium("GEMmixture");
158
159 TGeoMedium* A2 = gGeoManager->GetMedium("iron");
160 TGeoMedium* A3 = gGeoManager->GetMedium("lead");
161 TGeoMedium* A4 = gGeoManager->GetMedium("GEMmixture");
162 TGeoMedium* A1 = gGeoManager->GetMedium("Scintillator");
163
164 Double_t zStartSplitCal = fZStart;
165
166 TGeoVolume* newECALfilter_first; // first layer can have different thickeness
167 TGeoVolume* newECALfilter;
168 TGeoVolume* newECALdet_gas;
169 TGeoVolume* stripGivingX;
170 TGeoVolume* stripGivingY;
171
172 TGeoVolume* newHCALfilter[100];
173 TGeoVolume* newHCALdet[100];
174 const char* char_labelHCALfilter[100];
175 TString labelHCALfilter;
176 const char* char_labelHCALdet[100];
177 TString labelHCALdet;
178
179 Double_t z_splitcal = 0;
180
181 // logical volume for the absorbing layers
182 // first absorbing layer can have different thinkens from the others
183 newECALfilter_first = gGeoManager->MakeBox(
184 "ECALfilter_first", A3, fXMax, fYMax, fFilterECALThickness_first / 2);
185 newECALfilter_first->SetLineColor(kGray);
186 newECALfilter = gGeoManager->MakeBox("ECALfilter", A3, fXMax, fYMax,
188 newECALfilter->SetLineColor(kGray);
189
190 stripGivingX =
191 gGeoManager->MakeBox("stripGivingX", A1, fStripHalfWidth,
193 stripGivingX->SetVisibility(kTRUE);
194 AddSensitiveVolume(stripGivingX);
195 stripGivingX->SetLineColor(kGreen);
196
197 stripGivingY =
198 gGeoManager->MakeBox("stripGivingY", A1, fStripHalfLength,
200 stripGivingY->SetVisibility(kTRUE);
201 AddSensitiveVolume(stripGivingY);
202 stripGivingY->SetLineColor(kGreen);
203
204 // logical volume for the high precision sensitive layers
205 newECALdet_gas = gGeoManager->MakeBox("ECALdet_gas", A4, fXMax, fYMax,
207 AddSensitiveVolume(newECALdet_gas);
208 newECALdet_gas->SetLineColor(kRed);
209
210 // now position layer volumes in tSplitCal mother volume
211 for (Int_t i_nlayECAL = 0; i_nlayECAL < fnECALSamplings; i_nlayECAL++) {
212 // position absorber layers
213 // thinkness of first layer can be different from others
214 if (i_nlayECAL == 0) {
215 z_splitcal += fFilterECALThickness_first / 2;
216 tSplitCal->AddNode(newECALfilter_first, i_nlayECAL * 1e5,
217 new TGeoTranslation(0, 0, z_splitcal));
218 z_splitcal += fFilterECALThickness_first / 2;
219 } else {
220 z_splitcal += fFilterECALThickness / 2;
221 tSplitCal->AddNode(newECALfilter, i_nlayECAL * 1e5,
222 new TGeoTranslation(0, 0, z_splitcal));
223 z_splitcal += fFilterECALThickness / 2;
224 }
225
226 if (i_nlayECAL == 0)
227 z_splitcal += fEmpty; // space after first layer? set to 0 in the
228 // config file? for whar is it for?
229 if (i_nlayECAL == 7) z_splitcal += fBigGap;
230
231 // position high precision sensitive layers
232 if (i_nlayECAL == ffirst_precision_layer ||
233 i_nlayECAL == fsecond_precision_layer ||
234 i_nlayECAL == fthird_precision_layer) {
235 z_splitcal += fActiveECAL_gas_Thickness / 2;
236
237 tSplitCal->AddNode(newECALdet_gas, 1e8 + (i_nlayECAL + 1) * 1e5,
238 new TGeoTranslation(0, 0, z_splitcal));
239 z_splitcal += fActiveECAL_gas_Thickness / 2;
240 if (fnum_precision_layers == 2) {
241 z_splitcal += fActiveECAL_gas_gap;
242 z_splitcal += fActiveECAL_gas_Thickness / 2;
243 tSplitCal->AddNode(newECALdet_gas, 1e8 + (i_nlayECAL + 1) * 1e5,
244 new TGeoTranslation(0, 0, z_splitcal));
245 z_splitcal += fActiveECAL_gas_Thickness / 2;
246 }
247 } else {
248 // position sensitive layers
249 z_splitcal += fActiveECALThickness / 2;
250 if (i_nlayECAL % 2 == 0) {
251 // strips giving x information
252 for (int mx = 0; mx < fNModulesInX; mx++) {
253 for (int my = 0; my < fNModulesInY; my++) {
254 for (int j = 0; j < fNStripsPerModule; j++) {
255 int index = (i_nlayECAL + 1) * 1e5 + (mx + 1) * 1e4 +
256 (my + 1) * 1e3 + j + 1;
257 double xCoordinate =
258 -fXMax + (fNStripsPerModule * mx + j + 0.5) *
260 2; // the times 2 is to get the total width
261 // from the half-width
262 double yCoordinate =
263 -fYMax + (my + 0.5) * fStripHalfLength *
264 2; // the times 2 is to get the total length
265 // from the half-length
266 tSplitCal->AddNode(
267 stripGivingX, index,
268 new TGeoTranslation(xCoordinate, yCoordinate, z_splitcal));
269
270 } // end loop on strips
271 } // end loop on modules in y
272 } // end loop on modules in x
273 } // end layer stripped in X
274 else {
275 // strips giving y information
276 for (int mx = 0; mx < fNModulesInX; mx++) {
277 for (int my = 0; my < fNModulesInY; my++) {
278 for (int j = 0; j < fNStripsPerModule; j++) {
279 int index = (i_nlayECAL + 1) * 1e5 + (mx + 1) * 1e4 +
280 (my + 1) * 1e3 + j + 1;
281 double xCoordinate =
282 -fXMax + (mx + 0.5) * fStripHalfLength *
283 2; // the times 2 is to get the total length
284 // from the half-length
285 double yCoordinate =
286 -fYMax + (fNStripsPerModule * my + j + 0.5) *
288 2; // the times 2 is to get the total width
289 // from the half-width
290 tSplitCal->AddNode(
291 stripGivingY, index,
292 new TGeoTranslation(xCoordinate, yCoordinate, z_splitcal));
293
294 } // end loop on strips
295 } // end loop on modules in y
296 } // end loop on modules in x
297 } // end layer stripped in Y
298
299 z_splitcal += fActiveECALThickness / 2;
300 } // end loop on sensitive scintillator layers
301
302 } // end loop in ecal layers
303
304 for (Int_t i_nlayHCAL = 0; i_nlayHCAL < 1; i_nlayHCAL++) {
305 labelHCALfilter = "HCALfilter_";
306 labelHCALfilter += i_nlayHCAL;
307 char_labelHCALfilter[i_nlayHCAL] = labelHCALfilter;
308 labelHCALdet = "HCAL_det";
309 labelHCALdet += i_nlayHCAL;
310 char_labelHCALdet[i_nlayHCAL] = labelHCALdet;
311 newHCALfilter[i_nlayHCAL] =
312 gGeoManager->MakeBox(char_labelHCALfilter[i_nlayHCAL], A2, fXMax, fYMax,
314 if (fActiveHCAL) {
315 newHCALdet[i_nlayHCAL] =
316 gGeoManager->MakeBox(char_labelHCALdet[i_nlayHCAL], A4, fXMax, fYMax,
318
319 AddSensitiveVolume(newHCALdet[i_nlayHCAL]);
320
321 newHCALdet[i_nlayHCAL]->SetLineColor(kRed);
322 }
323 newHCALfilter[i_nlayHCAL]->SetLineColor(kBlue);
324 }
325 for (Int_t i_nlayHCAL = 0; i_nlayHCAL < fnHCALSamplings; i_nlayHCAL++) {
326 z_splitcal += fFilterHCALThickness / 2;
327 tSplitCal->AddNode(newHCALfilter[i_nlayHCAL], 1,
328 new TGeoTranslation(0, 0, z_splitcal));
329 z_splitcal += fFilterHCALThickness / 2;
330
331 z_splitcal += fActiveHCALThickness / 2;
332 if (fActiveHCAL)
333 tSplitCal->AddNode(newHCALdet[i_nlayHCAL], 1,
334 new TGeoTranslation(0, 0, z_splitcal));
335 z_splitcal += fActiveHCALThickness / 2;
336 }
337
338 // finish assembly and position
339 TGeoShapeAssembly* asmb =
340 dynamic_cast<TGeoShapeAssembly*>(tSplitCal->GetShape());
341 Double_t totLength = asmb->GetDZ();
342 top->AddNode(tSplitCal, 1,
343 new TGeoTranslation(0, 0, zStartSplitCal + totLength));
344}
@ kSplitCal
Int_t fTrackID
event index
Definition: Detector.h:85
Int_t fVolumeID
track index
Definition: Detector.h:86
TLorentzVector fPos
volume id
Definition: Detector.h:87
Double_t fTime
momentum at entrance
Definition: Detector.h:89
splitcalPoint * AddHit(Args &&... args)
Definition: Detector.h:38
TLorentzVector fMom
position at entrance
Definition: Detector.h:88
void SetStripSize(Double_t stripHalfWidth, Double_t stripHalfLength)
Definition: splitcal.cxx:138
Double_t fFilterHCALThickness
Definition: splitcal.h:70
Double_t fnum_precision_layers
Definition: splitcal.h:81
Double_t fActiveHCALThickness
Definition: splitcal.h:69
Int_t fNModulesInY
Definition: splitcal.h:82
Bool_t ProcessHits(FairVolume *v=0) override
Definition: splitcal.cxx:44
Double_t fFilterECALThickness_first
Definition: splitcal.h:70
Double_t fActiveECALThickness
Definition: splitcal.h:69
Double_t fFilterHCALMaterial
Definition: splitcal.h:72
void SetNModules(Int_t nModulesInX, Int_t nModulesInY)
Definition: splitcal.cxx:131
Double_t fActiveHCALMaterial
Definition: splitcal.h:71
Double_t fthird_precision_layer
Definition: splitcal.h:81
Double_t fActiveHCAL
Definition: splitcal.h:75
void SetXMax(Double_t xMax)
Definition: splitcal.cxx:143
Int_t fNStripsPerModule
Definition: splitcal.h:83
void SetZStart(Double_t ZStart)
Definition: splitcal.cxx:85
void ConstructGeometry() override
Definition: splitcal.cxx:145
void SetNSamplings(Int_t nECALSamplings, Int_t nHCALSamplings, Double_t ActiveHCAL)
Definition: splitcal.cxx:124
void SetYMax(Double_t yMax)
Definition: splitcal.cxx:144
void SetThickness(Double_t ActiveECALThickness, Double_t ActiveHCALThickness, Double_t FilterECALThickness, Double_t FilterECALThickness_first, Double_t FilterHCALThickness, Double_t ActiveECAL_gas_Thickness)
Definition: splitcal.cxx:101
Double_t fFilterECALMaterial
Definition: splitcal.h:71
Int_t fNModulesInX
Definition: splitcal.h:82
Double_t fActiveECAL_gas_gap
Definition: splitcal.h:73
Double_t fBigGap
Definition: splitcal.h:77
Double_t fActiveECAL_gas_Thickness
Definition: splitcal.h:73
Double_t fActiveECALMaterial
Definition: splitcal.h:71
Double_t fStripHalfLength
Definition: splitcal.h:84
Double_t fEmpty
Definition: splitcal.h:77
void SetNStrips(Int_t nStrips)
Definition: splitcal.cxx:136
Double_t fZStart
Definition: splitcal.h:76
Double_t fYMax
Definition: splitcal.h:79
Int_t fnHCALSamplings
Definition: splitcal.h:74
splitcal()
Definition: splitcal.cxx:39
Double_t fXMax
Definition: splitcal.h:78
Double_t fsecond_precision_layer
Definition: splitcal.h:80
Double_t ffirst_precision_layer
Definition: splitcal.h:80
Double_t fStripHalfWidth
Definition: splitcal.h:84
Double_t fFilterECALThickness
Definition: splitcal.h:69
void SetEmpty(Double_t Empty, Double_t BigGap, Double_t ActiveECAL_gas_gap, Double_t first_precision_layer, Double_t second_precision_layer, Double_t third_precision_layer, Double_t num_precision_layers)
Definition: splitcal.cxx:86
Int_t fnECALSamplings
Definition: splitcal.h:74
void SetMaterial(Double_t ActiveECALMaterial, Double_t ActiveHCALMaterial, Double_t FilterECALMaterial, Double_t FilterHCALMaterial)
Definition: splitcal.cxx:114
Int_t InitMedium(const char *name)
Definition: ShipGeoUtil.h:20