SND@LHC Software
Loading...
Searching...
No Matches
MuFilter.cxx
Go to the documentation of this file.
1//
2// MuFilter.cxx
3//
4// by A.Buonaura
5//
6
7#include "MuFilter.h"
8#include "MuFilterPoint.h"
9
10#include "TGeoManager.h"
11#include "TString.h" // for TString
12
13#include "TClonesArray.h"
14#include "TVirtualMC.h"
15
16#include "TGeoBBox.h"
17#include "TGeoMaterial.h"
18#include "TGeoMedium.h"
19#include "TGeoBBox.h"
20#include "TGeoCompositeShape.h"
21
22#include "TParticle.h"
23#include "TParticlePDG.h"
24#include "TParticleClassPDG.h"
25#include "TVirtualMCStack.h"
26
27#include "FairVolume.h"
28#include "FairGeoVolume.h"
29#include "FairGeoNode.h"
30#include "FairRootManager.h"
31#include "FairGeoLoader.h"
32#include "FairGeoInterface.h"
33#include "FairGeoTransform.h"
34#include "FairGeoMedia.h"
35#include "FairGeoMedium.h"
36#include "FairGeoBuilder.h"
37#include "FairRun.h"
38
39#include "ShipDetectorList.h"
40#include "ShipUnit.h"
41#include "ShipStack.h"
42
43#include <stddef.h> // for NULL
44#include <iostream> // for operator<<, basic_ostream,etc
45#include <string.h>
46#include <cstring>
47
48using std::cout;
49using std::endl;
50using std::to_string;
51using std::string;
52using namespace ShipUnit;
53
55: FairDetector("MuonFilter", "",kTRUE),
56 fTrackID(-1),
57fVolumeID(-1),
58fPos(),
59fMom(),
60fTime(-1.),
61fLength(-1.),
62fELoss(-1),
63eventHeader(0),
64last_run_time(-1),
65last_run_pos(-1),
66last_time_alignment_tag(""),
67alignment_init(false),
68fMuFilterPointCollection(new TClonesArray("MuFilterPoint"))
69{
70}
71
72MuFilter::MuFilter(const char* name, Bool_t Active,const char* Title)
73: FairDetector(name, true, kMuFilter),
74 fTrackID(-1),
75fVolumeID(-1),
76fPos(),
77fMom(),
78fTime(-1.),
79fLength(-1.),
80fELoss(-1),
81eventHeader(0),
82last_run_time(-1),
83last_run_pos(-1),
84last_time_alignment_tag(""),
85alignment_init(false),
86fMuFilterPointCollection(new TClonesArray("MuFilterPoint"))
87{
88}
89
97
99{
100 FairDetector::Initialize();
101}
102
103// ----- Private method InitMedium
104Int_t MuFilter::InitMedium(const char* name)
105{
106 static FairGeoLoader *geoLoad=FairGeoLoader::Instance();
107 static FairGeoInterface *geoFace=geoLoad->getGeoInterface();
108 static FairGeoMedia *media=geoFace->getMedia();
109 static FairGeoBuilder *geoBuild=geoLoad->getGeoBuilder();
110
111 FairGeoMedium *ShipMedium=media->getMedium(name);
112
113 if (!ShipMedium)
114 {
115 Fatal("InitMedium","Material %s not defined in media file.", name);
116 return -1111;
117 }
118 TGeoMedium* medium=gGeoManager->GetMedium(name);
119 if (medium!=NULL)
120 return ShipMedium->getMediumIndex();
121 return geoBuild->createMedium(ShipMedium);
122}
123
125{
126 TGeoVolume *top=gGeoManager->FindVolumeFast("Detector");
127 if(!top) LOG(ERROR) << "no Detector volume found " ;
128
129 //Materials
130
131 InitMedium("iron");
132 TGeoMedium *Fe =gGeoManager->GetMedium("iron");
133 InitMedium("aluminium");
134 TGeoMedium *Al =gGeoManager->GetMedium("aluminium");
135 InitMedium("polyvinyltoluene");
136 TGeoMedium *Scint =gGeoManager->GetMedium("polyvinyltoluene");
137 InitMedium("Concrete");
138 TGeoMedium *concrete = gGeoManager->GetMedium("Concrete");
139
140 Float_t nSiPMs[3]; // number of SiPMs per side
141 Float_t nSides[3]; // number of sides readout
142 nSiPMs[0] = conf_ints["MuFilter/VetonSiPMs"];
143 nSiPMs[1] = conf_ints["MuFilter/UpstreamnSiPMs"];
144 nSiPMs[2] = conf_ints["MuFilter/DownstreamnSiPMs"];
145 nSides[0] = conf_ints["MuFilter/VetonSides"];
146 nSides[1] = conf_ints["MuFilter/DownstreamnSides"];
147 nSides[2] = conf_ints["MuFilter/UpstreamnSides"];
148
149 Int_t fNUpstreamPlanes = conf_ints["MuFilter/NUpstreamPlanes"]; // Number of planes
150 Int_t fNUpstreamBars = conf_ints["MuFilter/NUpstreamBars"]; // Number of staggered bars
151 Int_t fNDownstreamPlanes = conf_ints["MuFilter/NDownstreamPlanes"]; // Number of planes
152 Int_t fNDownstreamBars = conf_ints["MuFilter/NDownstreamBars"]; // Number of staggered bars
153 Double_t fDownstreamBarX_ver = conf_floats["MuFilter/DownstreamBarX_ver"]; // Staggered bars of upstream section, vertical bars for x measurement
154 Double_t fDownstreamBarY_ver = conf_floats["MuFilter/DownstreamBarY_ver"];
155 Double_t fDownstreamBarZ_ver = conf_floats["MuFilter/DownstreamBarZ_ver"];
156 Double_t fDS4ZGap = conf_floats["MuFilter/DS4ZGap"];
157
158 // position of left bottom edges in survey coordinate system converted to physicist friendly coordinate system
159 std::map<int, TVector3 > edge_Veto;
160 edge_Veto[1] = TVector3( -conf_floats["MuFilter/Veto1Dx"],conf_floats["MuFilter/Veto1Dz"],conf_floats["MuFilter/Veto1Dy"]);
161 edge_Veto[2] = TVector3( -conf_floats["MuFilter/Veto2Dx"],conf_floats["MuFilter/Veto2Dz"],conf_floats["MuFilter/Veto2Dy"]);
162 edge_Veto[3] = TVector3( -conf_floats["MuFilter/Veto3Dx"],conf_floats["MuFilter/Veto3Dz"],conf_floats["MuFilter/Veto3Dy"]);
163 std::map<int, TVector3 > edge_Iron;
164 std::map<int, TVector3 > edge_MuFilter;
165 for (int i=1;i<10;i++){
166 string si = to_string(i);
167 edge_Iron[i] = TVector3( -conf_floats["MuFilter/Iron"+si+"Dx"],conf_floats["MuFilter/Iron"+si+"Dz"],conf_floats["MuFilter/Iron"+si+"Dy"]);
168 edge_MuFilter[i] = TVector3( -conf_floats["MuFilter/Muon"+si+"Dx"],conf_floats["MuFilter/Muon"+si+"Dz"],conf_floats["MuFilter/Muon"+si+"Dy"]);
169 }
170 // system alignment parameters
171 Double_t fVetoShiftX = conf_floats["MuFilter/VetoShiftX"];
172 Double_t fVetoShiftY = conf_floats["MuFilter/VetoShiftY"];
173 Double_t fVetoShiftZ = conf_floats["MuFilter/VetoShiftZ"];
174 Double_t fShiftX = conf_floats["MuFilter/ShiftX"];
175 Double_t fShiftY = conf_floats["MuFilter/ShiftY"];
176 Double_t fShiftZ = conf_floats["MuFilter/ShiftZ"];
177
178 TVector3 displacement;
179
180 //Definition of the box containing veto planes
181 TGeoVolumeAssembly *volVeto = new TGeoVolumeAssembly("volVeto");
182
183 //Veto Planes
184 Double_t fVetoBarX = conf_floats["MuFilter/VetoBarX"]; // Veto Bar dimensions
185 Double_t fVetoBarY = conf_floats["MuFilter/VetoBarY"];
186 Double_t fVetoBarZ = conf_floats["MuFilter/VetoBarZ"];
187 Double_t fVeto3BarX = conf_floats["MuFilter/Veto3BarX"]; // 3rd Veto plane Bar dimensions
188 Double_t fVeto3BarY = conf_floats["MuFilter/Veto3BarY"];
189 Double_t fVeto3BarZ = conf_floats["MuFilter/Veto3BarZ"];
190 Double_t fVetoBarGap = conf_floats["MuFilter/VetoBarGap"];
191 Int_t fNVetoPlanes = conf_ints["MuFilter/NVetoPlanes"];
192 Int_t fNVetoBars = conf_ints["MuFilter/NVetoBars"];
193 Double_t fSupportBoxVW = conf_floats["MuFilter/SupportBoxVW"]; // SupportBox dimensions
194 // thickness of bottom part of Veto 3 SupportBox
195 Double_t fSupportBoxVB3 = conf_floats["MuFilter/SupportBoxVB3"];
196 // local position of bottom horizontal bar to survey edge
197 TVector3 LocBarVeto = TVector3(-conf_floats["MuFilter/VETOLocX"], conf_floats["MuFilter/VETOLocZ"],conf_floats["MuFilter/VETOLocY"]);
198 TVector3 LocBarVeto_v = TVector3(-conf_floats["MuFilter/VETOLocX3"], conf_floats["MuFilter/VETOLocZ3"],conf_floats["MuFilter/VETOLocY3"]);
199
200 TVector3 VetoBox1 = TVector3(-conf_floats["MuFilter/VETOBoxX1"],conf_floats["MuFilter/VETOBoxZ1"],conf_floats["MuFilter/VETOBoxY1"]); // bottom front left
201 TVector3 VetoBox2 = TVector3(-conf_floats["MuFilter/VETOBoxX2"],conf_floats["MuFilter/VETOBoxZ2"],conf_floats["MuFilter/VETOBoxY2"]); // top back right
202 TVector3 VetoBoxDim = TVector3( VetoBox1.X()-VetoBox2.X(), VetoBox2.Y()-VetoBox1.Y(), VetoBox2.Z()-VetoBox1.Z() ) ;
203 // support box
204 TGeoBBox *supVetoBoxInner = new TGeoBBox("supVetoBoxI",VetoBoxDim.X()/2,VetoBoxDim.Y()/2,VetoBoxDim.Z()/2);
205 TGeoBBox *supVetoBoxOuter = new TGeoBBox("supVetoBoxO",VetoBoxDim.X()/2+fSupportBoxVW,VetoBoxDim.Y()/2+fSupportBoxVW,VetoBoxDim.Z()/2+fSupportBoxVW);
206 TGeoCompositeShape *subVetoBoxShape = new TGeoCompositeShape("subVetoBoxShape", "supVetoBoxO-supVetoBoxI");
207 TGeoVolume *subVetoBox = new TGeoVolume("subVetoBox", subVetoBoxShape, Al);
208 subVetoBox->SetLineColor(kGray+1);
209
210 // support box for the 3rd veto plane
211 TVector3 VetoBox3 = TVector3(-conf_floats["MuFilter/VETOBoxX3"],conf_floats["MuFilter/VETOBoxZ3"],conf_floats["MuFilter/VETOBoxY3"]); // bottom front left
212 TVector3 VetoBox4 = TVector3(-conf_floats["MuFilter/VETOBoxX4"],conf_floats["MuFilter/VETOBoxZ4"],conf_floats["MuFilter/VETOBoxY4"]); // top back right
213 TVector3 Veto3BoxDim = TVector3( VetoBox3.X()-VetoBox4.X(), VetoBox4.Y()-VetoBox3.Y(), VetoBox4.Z()-VetoBox3.Z() ) ;
214 // support box
215 TGeoBBox *supVeto3BoxInner = new TGeoBBox("supVeto3BoxI",Veto3BoxDim.X()/2,Veto3BoxDim.Y()/2,Veto3BoxDim.Z()/2);
216 TGeoBBox *supVeto3BoxOuter = new TGeoBBox("supVeto3BoxO",Veto3BoxDim.X()/2+fSupportBoxVW,Veto3BoxDim.Y()/2+fSupportBoxVB3,Veto3BoxDim.Z()/2+fSupportBoxVW);
217 TGeoCompositeShape *subVeto3BoxShape = new TGeoCompositeShape("subVeto3BoxShape", "supVeto3BoxO-supVeto3BoxI");
218 TGeoVolume *subVeto3Box = new TGeoVolume("subVeto3Box", subVeto3BoxShape, Al);
219 subVeto3Box->SetLineColor(kGray+1);
220
221 //Veto bars
222 TGeoVolume *volVetoBar = gGeoManager->MakeBox("volVetoBar",Scint,fVetoBarX/2., fVetoBarY/2., fVetoBarZ/2.);
223 // 3rd plane
224 TGeoVolume *volVetoBar_ver = gGeoManager->MakeBox("volVetoBar_ver",Scint,fVeto3BarX/2., fVeto3BarY/2., fVeto3BarZ/2.);
225
226 volVetoBar->SetLineColor(kRed-3);
227 AddSensitiveVolume(volVetoBar);
228
229 volVetoBar_ver->SetLineColor(kRed-3);
230 AddSensitiveVolume(volVetoBar_ver);
231
232 //adding veto planes
233 TGeoVolume* volVetoPlane;
234 for (int iplane=0; iplane < fNVetoPlanes; iplane++){
235
236 string name = "volVetoPlane_"+to_string(iplane);
237 volVetoPlane = new TGeoVolumeAssembly(name.c_str());
238
239 if (iplane < 2){
240 displacement = edge_Veto[iplane+1] + LocBarVeto + TVector3(-fVetoBarX/2, 0, 0);
241 volVeto->AddNode(volVetoPlane,iplane,
242 new TGeoTranslation(displacement.X(),displacement.Y(),displacement.Z()));
243 // VETOBox1 = bottom front left
244 displacement = edge_Veto[iplane+1] + VetoBox1 + TVector3(-VetoBoxDim.X()/2,VetoBoxDim.Y()/2,VetoBoxDim.Z()/2);
245 volVeto->AddNode(subVetoBox,iplane,
246 new TGeoTranslation(displacement.X(),displacement.Y(),displacement.Z()));
247
248 displacement = TVector3(0, 0, 0);
249 for (Int_t ibar = 0; ibar < fNVetoBars; ibar++){
250 Double_t dy_bar = (fVetoBarY + fVetoBarGap)*ibar;
251 volVetoPlane->AddNode(volVetoBar, 1e+4+iplane*1e+3+ibar,
252 new TGeoTranslation(displacement.X(),displacement.Y()+dy_bar,displacement.Z()));
253 }
254 } // Veto planes 1 & 2
255 else {
256 displacement = edge_Veto[iplane+1] + LocBarVeto_v + TVector3(-fVeto3BarX/2, fVeto3BarY/2, 0);
257 volVeto->AddNode(volVetoPlane,iplane,
258 new TGeoTranslation(displacement.X(),displacement.Y(),displacement.Z()));
259 // VETOBox3 = bottom front left
260 displacement = edge_Veto[iplane+1] + VetoBox3 + TVector3(-fVeto3BarX/2, 0, 0) + TVector3(-Veto3BoxDim.X()/2,Veto3BoxDim.Y()/2,Veto3BoxDim.Z()/2);
261 volVeto->AddNode(subVeto3Box,iplane,
262 new TGeoTranslation(displacement.X(),displacement.Y(),displacement.Z()));
263
264 displacement = TVector3(0, 0, 0);
265 for (Int_t ibar = 0; ibar < fNVetoBars; ibar++){
266 Double_t dx_bar = (fVeto3BarX + fVetoBarGap)*ibar;
267 volVetoPlane->AddNode(volVetoBar_ver, 1e+4+iplane*1e+3+ibar,
268 new TGeoTranslation(displacement.X()-dx_bar,displacement.Y(),displacement.Z())); // detID of type 12xxx
269 }
270 }// Veto plane 3
271 }
272
273 //adding to detector volume
274 top->AddNode(volVeto, 1,new TGeoTranslation(fVetoShiftX,fVetoShiftY,fVetoShiftZ)) ;
275
276 //*****************************************UPSTREAM SECTION*********************************//
277
278 //Definition of the box containing Fe Blocks + Timing Detector planes
279 TGeoVolumeAssembly *volMuFilter = new TGeoVolumeAssembly("volMuFilter");
280
281 //Iron blocks volume definition
282 Double_t fFeBlockX = conf_floats["MuFilter/FeX"]; // Passive Iron blocks dimensions
283 Double_t fFeBlockY = conf_floats["MuFilter/FeY"];
284 Double_t fFeBlockZ = conf_floats["MuFilter/FeZ"];
285 Double_t fFeBlockEndX = conf_floats["MuFilter/FeEndX"]; // last Iron block dimensions
286 Double_t fFeBlockEndY = conf_floats["MuFilter/FeEndY"];
287 Double_t fFeBlockEndZ = conf_floats["MuFilter/FeEndZ"];
288 Double_t fFeBlockBotX = conf_floats["MuFilter/FeBotX"]; // bottom Iron block dimensions
289 Double_t fFeBlockBotY = conf_floats["MuFilter/FeBotY"];
290 Double_t fFeBlockBotZ = conf_floats["MuFilter/FeBotZ"];
291 Double_t fSupportBoxW = conf_floats["MuFilter/SupportBoxW"]; // SupportBox dimensions
292
293 TVector3 DSBox1 = TVector3(-conf_floats["MuFilter/DSBoxX1"],conf_floats["MuFilter/DSBoxZ1"],conf_floats["MuFilter/DSBoxY1"]); // bottom front left
294 TVector3 DSBox2 = TVector3(-conf_floats["MuFilter/DSBoxX2"],conf_floats["MuFilter/DSBoxZ2"],conf_floats["MuFilter/DSBoxY2"]); // top back right
295 TVector3 DSBoxDim = TVector3( DSBox1.X()-DSBox2.X(), DSBox2.Y()-DSBox1.Y(), DSBox2.Z()-DSBox1.Z() ) ;
296 TVector3 USBox1 = TVector3(-conf_floats["MuFilter/DSBoxX1"],conf_floats["MuFilter/DSBoxZ1"],conf_floats["MuFilter/USBoxY1"]); // bottom front left
297 TVector3 USBox2 = TVector3(-conf_floats["MuFilter/DSBoxX2"],conf_floats["MuFilter/DSBoxZ2"],conf_floats["MuFilter/USBoxY2"]); // top back right
298 TVector3 USBoxDim = TVector3( USBox1.X()-USBox2.X(), USBox2.Y()-USBox1.Y(), USBox2.Z()-USBox1.Z() ) ;
299
300 //Iron blocks volume definition
301 TGeoVolume *volFeBlock = gGeoManager->MakeBox("volFeBlock",Fe,fFeBlockX/2, fFeBlockY/2, fFeBlockZ/2);
302 volFeBlock->SetLineColor(kGreen-4);
303 TGeoVolume *volFeBlockEnd = gGeoManager->MakeBox("volFeBlockEnd",Fe,fFeBlockEndX/2, fFeBlockEndY/2, fFeBlockEndZ/2);
304 volFeBlockEnd->SetLineColor(kGreen-4);
305 TGeoVolume *volBlockBot = gGeoManager->MakeBox("volBlockBot",concrete,fFeBlockBotX/2, fFeBlockBotY/2, fFeBlockBotZ/2);
306 volBlockBot->SetLineColor(kGreen-4);
307
308 // support box
309 TGeoBBox *supDSBoxInner = new TGeoBBox("supDSBoxI",DSBoxDim.X()/2,DSBoxDim.Y()/2,DSBoxDim.Z()/2);
310 TGeoBBox *supDSBoxOuter = new TGeoBBox("supDSBoxO",DSBoxDim.X()/2+fSupportBoxW,DSBoxDim.Y()/2+fSupportBoxW,DSBoxDim.Z()/2+fSupportBoxW);
311 TGeoCompositeShape *subDSBoxShape = new TGeoCompositeShape("subDSBoxShape", "supDSBoxO-supDSBoxI");
312 TGeoVolume *subDSBox = new TGeoVolume("subDSBox", subDSBoxShape, Al);
313 subDSBox->SetLineColor(kGray+1);
314 TGeoBBox *supUSBoxInner = new TGeoBBox("supUSBoxI",USBoxDim.X()/2,USBoxDim.Y()/2,USBoxDim.Z()/2);
315 TGeoBBox *supUSBoxOuter = new TGeoBBox("supUSBoxO",USBoxDim.X()/2+fSupportBoxW,USBoxDim.Y()/2+fSupportBoxW,USBoxDim.Z()/2+fSupportBoxW);
316 TGeoCompositeShape *subUSBoxShape = new TGeoCompositeShape("subUSBoxShape", "supUSBoxO-supUSBoxI");
317 TGeoVolume *subUSBox = new TGeoVolume("subUSBox", subUSBoxShape, Al);
318 subUSBox->SetLineColor(kGray+1);
319
320 top->AddNode(volMuFilter,1,new TGeoTranslation(fShiftX,fShiftY,fShiftZ ));
321
322 Double_t dy = 0;
323 Double_t dz = 0;
324 //Upstream Detector planes definition
325 Double_t fUpstreamDetZ = conf_floats["MuFilter/UpstreamDetZ"];
326
327 // local position of bottom horizontal bar to survey edge
328 TVector3 LocBarUS = TVector3(
329 -conf_floats["MuFilter/DSHLocX"],
330 conf_floats["MuFilter/DSHLocZ"] - conf_floats["MuFilter/DownstreamBarY"]/2 + conf_floats["MuFilter/UpstreamBarY"]/2,
331 conf_floats["MuFilter/DSHLocY"]);
332
333 TGeoVolume* volUpstreamDet;
334 Double_t fUpstreamBarX = conf_floats["MuFilter/UpstreamBarX"]; //Staggered bars of upstream section
335 Double_t fUpstreamBarY = conf_floats["MuFilter/UpstreamBarY"];
336 Double_t fUpstreamBarZ = conf_floats["MuFilter/UpstreamBarZ"];
337 Double_t fUpstreamBarGap = conf_floats["MuFilter/UpstreamBarGap"];
338
339 //adding staggered bars, first part, only 11 bars, (single stations, readout on both ends)
340 TGeoVolume *volMuUpstreamBar = gGeoManager->MakeBox("volMuUpstreamBar",Scint,fUpstreamBarX/2, fUpstreamBarY/2, fUpstreamBarZ/2);
341 volMuUpstreamBar->SetLineColor(kBlue+2);
342 AddSensitiveVolume(volMuUpstreamBar);
343 for(Int_t l=0; l<fNUpstreamPlanes; l++)
344 {
345 string name = "volMuUpstreamDet_"+std::to_string(l);
346 volUpstreamDet = new TGeoVolumeAssembly(name.c_str());
347
348 displacement = edge_Iron[l+1] - TVector3(fFeBlockX/2,-fFeBlockY/2,-fFeBlockZ/2);
349 volMuFilter->AddNode(volFeBlock,l,
350 new TGeoTranslation(displacement.X(),displacement.Y(),displacement.Z()));
351// place for H8 mockup target 20cm in front of US1
352 if (edge_Iron[9][2] <0.1 && l==0) {
353 TGeoVolume *volFeTarget = gGeoManager->MakeBox("volFeTarget",Fe,80./2, 60./2, 29.5/2);
354 volFeTarget->SetLineColor(kGreen-4);
355 displacement = edge_Iron[l+1] - TVector3(80/2,-60/2,29.5/2+fFeBlockZ );
356 volMuFilter->AddNode(volFeTarget,1,
357 new TGeoTranslation(displacement.X(),displacement.Y(),displacement.Z()));
358 }
359 displacement = edge_MuFilter[l+1]+LocBarUS + TVector3(-fUpstreamBarX/2, 0, 0);
360 volMuFilter->AddNode(volUpstreamDet,fNVetoPlanes+l,
361 new TGeoTranslation(displacement.X(),displacement.Y(),displacement.Z()));
362
363 // USBox1 = bottom front left
364 displacement = edge_MuFilter[l+1] +USBox1 + TVector3(-USBoxDim.X()/2,USBoxDim.Y()/2,USBoxDim.Z()/2);
365 volMuFilter->AddNode(subUSBox,l+fNVetoPlanes,
366 new TGeoTranslation(displacement.X(),displacement.Y(),displacement.Z()));
367
368 displacement = TVector3(0, 0, 0);
369 for (Int_t ibar = 0; ibar < fNUpstreamBars; ibar++){
370 Double_t dy_bar = (fUpstreamBarY + fUpstreamBarGap)*ibar;
371 volUpstreamDet->AddNode(volMuUpstreamBar,2e+4+l*1e+3+ibar,
372 new TGeoTranslation(displacement.X(),displacement.Y()+conf_floats["MuFilter/USOffZ"+to_string(l+1)]+dy_bar,displacement.Z()));
373 }
374
375 }
376
377 //*************************************DOWNSTREAM (high granularity) SECTION*****************//
378
379 // first loop, adding detector main boxes
380 TGeoVolume* volDownstreamDet;
381
382 // local position of bottom horizontal bar to survey edge
383 TVector3 LocBarH = TVector3(-conf_floats["MuFilter/DSHLocX"],conf_floats["MuFilter/DSHLocZ"],conf_floats["MuFilter/DSHLocY"]);
384 // local position of l left vertical bar to survey edge
385 TVector3 LocBarV = TVector3(-conf_floats["MuFilter/DSVLocX"],conf_floats["MuFilter/DSVLocZ"],conf_floats["MuFilter/DSVLocY"]);
386
387 Double_t fDownstreamBarX = conf_floats["MuFilter/DownstreamBarX"]; // Staggered bars of upstream section
388 Double_t fDownstreamBarY = conf_floats["MuFilter/DownstreamBarY"];
389 Double_t fDownstreamBarZ = conf_floats["MuFilter/DownstreamBarZ"];
390 Double_t fDownstreamBarGap = conf_floats["MuFilter/DownstreamBarGap"];
391
392 TGeoVolume *volMuDownstreamBar_hor = gGeoManager->MakeBox("volMuDownstreamBar_hor",Scint,fDownstreamBarX/2, fDownstreamBarY/2, fDownstreamBarZ/2);
393 volMuDownstreamBar_hor->SetLineColor(kAzure+7);
394 AddSensitiveVolume(volMuDownstreamBar_hor);
395
396 //vertical bars, for x measurement
397 TGeoVolume *volMuDownstreamBar_ver = gGeoManager->MakeBox("volMuDownstreamBar_ver",Scint,fDownstreamBarX_ver/2, fDownstreamBarY_ver/2, fDownstreamBarZ/2);
398 volMuDownstreamBar_ver->SetLineColor(kViolet-2);
399 AddSensitiveVolume(volMuDownstreamBar_ver);
400
401 // In testbeam 2023 det. layout, there is an iron block in front of the single DS plane!
402 int n_planes;
403 n_planes = fNDownstreamPlanes>1 ? fNDownstreamPlanes-1 : fNDownstreamPlanes;
404
405 for(Int_t l=0; l<fNDownstreamPlanes; l++)
406 {
407 if (l<n_planes){
408 displacement = edge_Iron[l+fNUpstreamPlanes+1] - TVector3(fFeBlockX/2,-fFeBlockY/2,-fFeBlockZ/2);
409 volMuFilter->AddNode(volFeBlock,l+fNUpstreamPlanes+fNVetoPlanes,
410 new TGeoTranslation(displacement.X(),displacement.Y(),displacement.Z()));
411 }else if (edge_Iron[9][2] >0.1) {
412// more iron
413 displacement = edge_Iron[l+fNUpstreamPlanes+1] - TVector3(fFeBlockEndX/2,-fFeBlockEndY/2,-fFeBlockEndZ/2);
414 volMuFilter->AddNode(volFeBlockEnd,1,
415 new TGeoTranslation(displacement.X(),displacement.Y(),displacement.Z()));
416 displacement = edge_Iron[l+fNUpstreamPlanes+1] - TVector3(fFeBlockBotX/2-10.0, fFeBlockBotY/2,fFeBlockBotZ/2-fFeBlockEndZ);
417 volMuFilter->AddNode(volBlockBot,1,
418 new TGeoTranslation(displacement.X(),displacement.Y(),displacement.Z()));
419 }
420
421 // add detectors
422 string name = "volMuDownstreamDet_"+std::to_string(l);
423 volDownstreamDet = new TGeoVolumeAssembly(name.c_str());
424 displacement = edge_MuFilter[l+fNUpstreamPlanes+1] + LocBarH + TVector3(-fDownstreamBarX/2, 0,0);
425
426 volMuFilter->AddNode(volDownstreamDet,l+fNUpstreamPlanes+fNVetoPlanes,
427 new TGeoTranslation(displacement.X(),displacement.Y(),displacement.Z()));
428
429 //adding bars within each detector box
430 if (l!=n_planes) {
431 displacement = TVector3(0, 0,0);
432 for (Int_t ibar = 0; ibar < fNDownstreamBars; ibar++){
433 //adding horizontal bars for y
434 Double_t dy_bar = (fDownstreamBarY + fDownstreamBarGap)*ibar;
435 volDownstreamDet->AddNode(volMuDownstreamBar_hor,3e+4+l*1e+3+ibar,
436 new TGeoTranslation(displacement.X(),displacement.Y()+dy_bar,displacement.Z()));
437 }
438 }
439 // DSBox1 = bottom front left
440 displacement = edge_MuFilter[l+fNUpstreamPlanes+1] +DSBox1 +
441 TVector3(-DSBoxDim.X()/2,DSBoxDim.Y()/2,DSBoxDim.Z()/2);
442 volMuFilter->AddNode(subDSBox,l+fNUpstreamPlanes+fNVetoPlanes,
443 new TGeoTranslation(displacement.X(),displacement.Y(),displacement.Z()));
444 //adding vertical bars for x
445 displacement = LocBarV + TVector3(0, -fDownstreamBarY_ver/2,0) - LocBarH - TVector3(-fDownstreamBarX/2, 0,0);
446 for (Int_t i_vbar = 0; i_vbar<fNDownstreamBars; i_vbar++) {
447 Double_t dx_bar = (fDownstreamBarX_ver+ fDownstreamBarGap)*i_vbar;
448 Int_t i_vbar_rev = fNDownstreamBars-1-i_vbar;
449 volDownstreamDet->AddNode(volMuDownstreamBar_ver,3e+4+l*1e+3+i_vbar_rev+60,
450 new TGeoTranslation(displacement.X()+dx_bar,displacement.Y(),displacement.Z()));
451 // Andrew added a 60 here to make each horizontal + vertical sub-plane contain bars given detIDs as one plane. So the first bar in the vert. sub plane is the 60th etc.
452 }
453 }
454}
455
457 // get mapping to eventHeader
458 eventHeader = e;
459
460 // Initialize
461 if (not alignment_init) {
462 alignment_init = true;
463 // Get available tags from the geometry file
464 std::string tag_string;
465 for (auto key : conf_floats){
466 tag_string = key.first.Data();
467 if (tag_string.find("MuFilter/DSTcorslopet_") != string::npos){
468 covered_runs_time_alignment.push_back(stoi(tag_string.substr(tag_string.find("t_")+2)));
469 }
470 }
472 }
473};
474
475
476Bool_t MuFilter::ProcessHits(FairVolume* vol)
477{
479 //Set parameters at entrance of volume. Reset ELoss.
480 if ( gMC->IsTrackEntering() )
481 {
482 fELoss = 0.;
483 fTime = gMC->TrackTime() * 1.0e09;
484 fLength = gMC->TrackLength();
485 gMC->TrackPosition(fPos);
486 gMC->TrackMomentum(fMom);
487 }
488 // Sum energy loss for all steps in the active volume
489 fELoss += gMC->Edep();
490
491 // Create MuFilterPoint at exit of active volume
492 if ( gMC->IsTrackExiting() ||
493 gMC->IsTrackStop() ||
494 gMC->IsTrackDisappeared() ) {
495 fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
496 gMC->CurrentVolID(fVolumeID);
497
498 if (fELoss == 0. ) { return kFALSE; }
499 TParticle* p=gMC->GetStack()->GetCurrentTrack();
500 Int_t pdgCode = p->GetPdgCode();
501
502 TLorentzVector Pos;
503 gMC->TrackPosition(Pos);
504 Double_t xmean = (fPos.X()+Pos.X())/2. ;
505 Double_t ymean = (fPos.Y()+Pos.Y())/2. ;
506 Double_t zmean = (fPos.Z()+Pos.Z())/2. ;
507
508
509 AddHit(fTrackID,fVolumeID, TVector3(xmean, ymean, zmean),
510 TVector3(fMom.Px(), fMom.Py(), fMom.Pz()), fTime, fLength,
511 fELoss, pdgCode);
512
513 // Increment number of muon det points in TParticle
514 ShipStack* stack = (ShipStack*) gMC->GetStack();
515 stack->AddPoint(kMuFilter);
516 }
517
518 return kTRUE;
519}
520
522{
524}
525
526
528{
529
536 FairRootManager::Instance()->Register("MuFilterPoint", "MuFilter",
538}
539
540TClonesArray* MuFilter::GetCollection(Int_t iColl) const
541{
542 if (iColl == 0) { return fMuFilterPointCollection; }
543 else { return NULL; }
544}
545
547{
549}
550
551
552MuFilterPoint* MuFilter::AddHit(Int_t trackID,Int_t detID,
553 TVector3 pos, TVector3 mom,
554 Double_t time, Double_t length,
555 Double_t eLoss, Int_t pdgCode)
556{
557 TClonesArray& clref = *fMuFilterPointCollection;
558 Int_t size = clref.GetEntriesFast();
559 return new(clref[size]) MuFilterPoint(trackID,detID, pos, mom,
560 time, length, eLoss, pdgCode);
561}
562
563void MuFilter::GetLocalPosition(Int_t fDetectorID, TVector3& vLeft, TVector3& vRight)
564{
565 GetPosition(fDetectorID, vLeft, vRight);
566 TGeoNavigator* nav = gGeoManager->GetCurrentNavigator();
567 TString path = nav->GetPath();
568 TString loc( path(0, path.Last('/') ) );
569 nav->cd(loc);
570 Double_t A[3] = {vLeft.X(),vLeft.Y(),vLeft.Z()};
571 Double_t B[3] = {vRight.X(),vRight.Y(),vRight.Z()};
572 Double_t locA[3] = {0,0,0};
573 Double_t locB[3] = {0,0,0};
574 nav->MasterToLocal(A, locA); nav->MasterToLocal(B, locB);
575 vLeft.SetXYZ(locA[0],locA[1],locA[2]);
576 vRight.SetXYZ(locB[0],locB[1],locB[2]);
577}
578
579Float_t MuFilter::GetCorrectedTime(Int_t fDetectorID, Int_t channel, Double_t rawTime, Double_t L){
580/* expect time in u.ns and path length to sipm u.cm */
581/* calibration implemented only for DS! */
582/* channel 0 left or top, channel 1 right */
583 if (fDetectorID<30000){
584 LOG(ERROR) << "MuFilter::GetCorrectedTime: not yet implemented for Veto and DS, no correction applied" ;
585 return rawTime;
586 }
587 TString tag = "";
588 if (eventHeader){
589 Int_t fRunNumber = eventHeader->GetRunId();
590 if (fRunNumber != last_run_time){
591 last_run_time = fRunNumber;
592
593 if (fRunNumber<1){
594 LOG(ERROR) << "MuFilter::GetCorrectedTime: non valid run number "<<fRunNumber;
595 return rawTime;
596 }
597
598 if (covered_runs_time_alignment.size()!=0){
599 tag = "t_"+to_string(covered_runs_time_alignment[covered_runs_time_alignment.size()-1]);
600 for (int i=1; i<covered_runs_time_alignment.size(); i++){
601 if (fRunNumber>=covered_runs_time_alignment[i-1] && fRunNumber<covered_runs_time_alignment[i]){
602 tag = "t_"+to_string(covered_runs_time_alignment[i-1]);
603 }
604 }
605 //special case
606 if (fRunNumber<5193 && fRunNumber>5174) tag = "t_"+to_string(covered_runs_time_alignment[0]);
607 }
608 else{
609 // allow reading older geo files with letter tags i.e. A, B, C
610 tag = "A";
611 if (fRunNumber>5116 && !(fRunNumber<5193 && fRunNumber>5174) ) {tag = "B";}
612 }
613 // 2023 testbeam data doesn't have a custom tag
614 if (fRunNumber>=1e5) {tag = "";}
616 }
617 }
618 Float_t cor = rawTime;
619 int l = (fDetectorID-30000)/1000;
620 int ichannel60 = fDetectorID%1000;
621 int p;
622 if (channel==0 && ichannel60<30 ){p=0+l*6;}
623 if (channel==0 && ichannel60>29 && ichannel60<60 ){p=1+l*6;}
624 if (channel==1 && ichannel60<30 ){p=2+l*6;}
625 if (channel==1 && ichannel60>29 && ichannel60<60 ){p=3+l*6;}
626 if (channel==0 && ichannel60>59 && ichannel60<90 ){p=4+l*6;}
627 if (channel==0 && ichannel60>89 && ichannel60<120 ){p=5+l*6;}
628 if (l==3){p-=4;}
629 if (ichannel60>59) {ichannel60-=60;}
630 // DS time alignment first order
631 if (ichannel60<30){cor += conf_floats["MuFilter/DSTcorslope"+last_time_alignment_tag]*(ichannel60-15);}
632 else{ cor -= conf_floats["MuFilter/DSTcorslope"+last_time_alignment_tag]*(ichannel60-45);}
633 string si = to_string(p);
634 cor -= conf_floats["MuFilter/DSTcorC"+si+last_time_alignment_tag];
635 cor -= L/conf_floats["MuFilter/DsPropSpeed"];
636 return cor;
637}
638
639void MuFilter::GetPosition(Int_t fDetectorID, TVector3& vLeft, TVector3& vRight)
640{
641
642 int subsystem = floor(fDetectorID/10000);
643 int plane = floor(fDetectorID/1000) - 10*subsystem;
644 int bar_number = fDetectorID%1000;
645
646 TString path = "/cave_1/Detector_0/";
647 TString barName;
648 Float_t shift;
649 switch(subsystem) {
650 // VETO/US/DS alignment relativ to Scifi only done once.
651 // should be done after each emulsion exchange.
652 case 1:
653 path+="volVeto_1/volVetoPlane_"+std::to_string(plane)+"_"+std::to_string(plane);
654 // keeping the name of horizontal Veto planes for backward compatibility
655 barName = "/volVetoBar_";
656 // the third Veto plane is vertical
657 if (plane>=2) barName+="ver_";
658 shift = conf_floats["MuFilter/Veto"+std::to_string(plane+1)+"ShiftX"];
659 break;
660 case 2:
661 path+="volMuFilter_1/volMuUpstreamDet_"+std::to_string(plane)+"_"
662 +std::to_string(plane+conf_ints["MuFilter/NVetoPlanes"]);
663 barName = "/volMuUpstreamBar_";
664 shift = conf_floats["MuFilter/US"+std::to_string(plane+1)+"ShiftY"];
665 break;
666 case 3:
667 path+="volMuFilter_1/volMuDownstreamDet_"+std::to_string(plane)+"_"
668 +std::to_string(plane+conf_ints["MuFilter/NVetoPlanes"]
669 +conf_ints["MuFilter/NUpstreamPlanes"]);
670 barName = "/volMuDownstreamBar_";
671 if (bar_number<60){
672 barName+="hor_";
673 shift = conf_floats["MuFilter/DS"+std::to_string(plane+1)+"ShiftY"];
674 }
675 else{
676 barName+="ver_";
677 shift = conf_floats["MuFilter/DS"+std::to_string(plane+1)+"ShiftX"];
678 }
679 break;
680 }
681 path += barName+std::to_string(fDetectorID);
682
683 TGeoNavigator* nav = gGeoManager->GetCurrentNavigator();
684 nav->cd(path);
685 LOG(DEBUG) <<path<<" "<<fDetectorID<<" "<<subsystem<<" "<<bar_number;
686 TGeoNode* W = nav->GetCurrentNode();
687 TGeoBBox* S = dynamic_cast<TGeoBBox*>(W->GetVolume()->GetShape());
688
689 if ( (subsystem == 3 and bar_number >59) or
690 (subsystem == 1 and plane ==2) ){ // vertical bars
691 Double_t top[3] = {shift,S->GetDY(), 0};
692 Double_t bot[3] = {shift,-S->GetDY(),0};
693 Double_t Gtop[3],Gbot[3];
694 nav->LocalToMaster(top, Gtop); nav->LocalToMaster(bot, Gbot);
695 vLeft.SetXYZ(Gtop[0],Gtop[1],Gtop[2]);
696 vRight.SetXYZ(Gbot[0],Gbot[1],Gbot[2]);
697 }
698 else { // horizontal bars
699 Double_t posXend[3] = {S->GetDX(),shift,0};
700 Double_t negXend[3] = {-S->GetDX(),shift,0};
701 Double_t GposXend[3],GnegXend[3];
702 nav->LocalToMaster(posXend, GposXend); nav->LocalToMaster(negXend, GnegXend);
703 vLeft.SetXYZ(GposXend[0],GposXend[1],GposXend[2]);
704 vRight.SetXYZ(GnegXend[0],GnegXend[1],GnegXend[2]);
705 }
706}
707
708 Int_t MuFilter::GetnSiPMs(Int_t detID){
709 int subsystem = floor(detID/10000)-1;
710 if (subsystem==0){return conf_ints["MuFilter/VetonSiPMs"];}
711 if (subsystem==1){return conf_ints["MuFilter/UpstreamnSiPMs"];}
712 return conf_ints["MuFilter/DownstreamnSiPMs"];
713
714 }
715 Int_t MuFilter::GetnSides(Int_t detID){
716 int subsystem = floor(detID/10000)-1;
717 if (subsystem==0){
718 // vertical Veto 3 has the readout on the top only
719 if (detID>=12000) return conf_ints["MuFilter/VetonSides"]-1;
720 else {return conf_ints["MuFilter/VetonSides"];}
721 }
722 if (subsystem==1){return conf_ints["MuFilter/UpstreamnSides"];}
723 if (subsystem==2){
724 if (detID%1000>59) return conf_ints["MuFilter/DownstreamnSides"]-1;
725 else {return conf_ints["MuFilter/DownstreamnSides"];}
726 }
727 }
728
@ kMuFilter
bool alignment_init
Definition MuFilter.h:110
Int_t GetnSides(Int_t detID)
Definition MuFilter.cxx:715
ClassDef(MuFilter, 4) private Int_t fVolumeID
track index
Definition MuFilter.h:84
void GetPosition(Int_t id, TVector3 &vLeft, TVector3 &vRight)
Definition MuFilter.cxx:639
Double32_t fLength
time
Definition MuFilter.h:94
TString last_time_alignment_tag
Definition MuFilter.h:108
std::map< TString, Float_t > conf_floats
Definition MuFilter.h:101
void GetLocalPosition(Int_t id, TVector3 &vLeft, TVector3 &vRight)
Definition MuFilter.cxx:563
Float_t GetCorrectedTime(Int_t id, Int_t c, Double_t t, Double_t L)
Definition MuFilter.cxx:579
void InitEvent(SNDLHCEventHeader *e)
Definition MuFilter.cxx:456
virtual ~MuFilter()
Definition MuFilter.cxx:90
TLorentzVector fMom
position at entrance
Definition MuFilter.h:92
virtual void Reset()
Definition MuFilter.cxx:546
std::vector< int > covered_runs_time_alignment
Definition MuFilter.h:107
Int_t GetnSiPMs(Int_t detID)
Definition MuFilter.cxx:708
virtual TClonesArray * GetCollection(Int_t iColl) const
Definition MuFilter.cxx:540
TLorentzVector fPos
volume id
Definition MuFilter.h:91
SNDLHCEventHeader * eventHeader
Definition MuFilter.h:104
virtual void EndOfEvent()
Definition MuFilter.cxx:521
Double32_t fELoss
length
Definition MuFilter.h:95
void ConstructGeometry()
Definition MuFilter.cxx:124
Double32_t fTime
momentum at entrance
Definition MuFilter.h:93
MuFilterPoint * AddHit(Int_t trackID, Int_t detID, TVector3 pos, TVector3 mom, Double_t time, Double_t length, Double_t eLoss, Int_t pdgCode)
Definition MuFilter.cxx:552
virtual void Initialize()
Definition MuFilter.cxx:98
std::map< TString, Int_t > conf_ints
Definition MuFilter.h:102
virtual Bool_t ProcessHits(FairVolume *v=0)
Definition MuFilter.cxx:476
TClonesArray * fMuFilterPointCollection
energy loss
Definition MuFilter.h:98
int last_run_time
Definition MuFilter.h:109
virtual void Register()
Definition MuFilter.cxx:527
Int_t InitMedium(const char *name)
Definition MuFilter.cxx:104
ClassImp(ecalContFact) ecalContFact