FairShip
Loading...
Searching...
No Matches
exitHadronAbsorber.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
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 "FairVolume.h"
17#include "ShipDetectorList.h"
18#include "ShipStack.h"
19#include "TDatabasePDG.h"
20#include "TGeoBBox.h"
21#include "TGeoBoolNode.h"
22#include "TGeoEltu.h"
23#include "TGeoManager.h"
24#include "TGeoMaterial.h"
25#include "TH1D.h"
26#include "TH2D.h"
27#include "TParticle.h"
28#include "TROOT.h"
29#include "TVirtualMC.h"
30using std::cout;
31using std::endl;
32
33Double_t cm = 1; // cm
34Double_t m = 100 * cm; // m
35Double_t mm = 0.1 * cm; // mm
36
37exitHadronAbsorber::exitHadronAbsorber(const char* Name, Bool_t Active)
38 : Detector(Name, Active, kVETO),
39 fOnlyMuons(kFALSE),
40 fSkipNeutrinos(kFALSE),
41 fVetoName("veto"),
42 fzPos(3E8),
43 withNtuple(kFALSE),
44 fCylindricalPlane(kFALSE) {}
45
47 : Detector("exitHadronAbsorber", kTRUE, kVETO),
48 fUniqueID(-1),
49 fOnlyMuons(kFALSE),
50 fSkipNeutrinos(kFALSE),
51 fVetoName("veto"),
52 fzPos(3E8),
53 withNtuple(kFALSE),
54 fCylindricalPlane(kFALSE),
55 fUseCaveCoordinates(kFALSE) {}
56
57Bool_t exitHadronAbsorber::ProcessHits(FairVolume* vol) {
59 if (gMC->IsTrackEntering()) {
60 fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
61 fEventID = gMC->CurrentEvent();
62 TParticle* p = gMC->GetStack()->GetCurrentTrack();
63 fUniqueID = p->GetUniqueID();
64 Int_t pdgCode = p->GetPdgCode();
65 gMC->TrackMomentum(fMom);
66 if (!fOnlyMuons || TMath::Abs(pdgCode) == 13) {
67 fTime = gMC->TrackTime() * 1.0e09;
68 fLength = gMC->TrackLength();
69 gMC->TrackPosition(fPos);
70 if ((fMom.E() - fMom.M()) > EMax) {
71 AddHit(fEventID, fTrackID, 111, TVector3(fPos.X(), fPos.Y(), fPos.Z()),
72 TVector3(fMom.Px(), fMom.Py(), fMom.Pz()), fTime, fLength, 0,
73 pdgCode, TVector3(p->Vx(), p->Vy(), p->Vz()),
74 TVector3(p->Px(), p->Py(), p->Pz()));
75 ShipStack* stack = dynamic_cast<ShipStack*>(gMC->GetStack());
76 stack->AddPoint(kVETO);
77 }
78 }
79 }
80 if ((!fCylindricalPlane) && fzPos > 1E8) {
81 gMC->StopTrack();
82 }
83 return kTRUE;
84}
85
87 FairDetector::Initialize();
88 TSeqCollection* fileList = gROOT->GetListOfFiles();
89 fout = dynamic_cast<TFile*>(fileList->At(0));
90 // book hists for Genie neutrino momentum distribution
91 // add also leptons, and photon
92 // add pi0 111 eta 221 eta' 331 omega 223 for DM production
93 TDatabasePDG* PDG = TDatabasePDG::Instance();
94 for (Int_t idnu = 11; idnu < 26; idnu += 1) {
95 // nu or anti-nu
96 for (Int_t idadd = -1; idadd < 3; idadd += 2) {
97 Int_t idw = idnu;
98 if (idnu == 18) {
99 idw = 22;
100 }
101 if (idnu == 19) {
102 idw = 111;
103 }
104 if (idnu == 20) {
105 idw = 221;
106 }
107 if (idnu == 21) {
108 idw = 223;
109 }
110 if (idnu == 22) {
111 idw = 331;
112 }
113 if (idnu == 23) {
114 idw = 211;
115 }
116 if (idnu == 24) {
117 idw = 321;
118 }
119 if (idnu == 25) {
120 idw = 2212;
121 }
122 Int_t idhnu = 10000 + idw;
123 if (idadd == -1) {
124 if (idnu > 17) {
125 continue;
126 }
127 idhnu += 10000;
128 idw = -idnu;
129 }
130 TString name = PDG->GetParticle(idw)->GetName();
131 TString title = name;
132 title += " momentum (GeV)";
133 TString key = fVetoName;
134 key += idhnu;
135 [[maybe_unused]] TH1D* Hidhnu = new TH1D(key, title, 400, 0., 400.);
136 title = name;
137 title += " log10-p vs log10-pt";
138 key = fVetoName;
139 key += idhnu + 1000;
140 [[maybe_unused]] TH2D* Hidhnu100 =
141 new TH2D(key, title, 100, -0.3, 1.7, 100, -2., 0.5);
142 title = name;
143 title += " log10-p vs log10-pt";
144 key = fVetoName;
145 key += idhnu + 2000;
146 [[maybe_unused]] TH2D* Hidhnu200 =
147 new TH2D(key, title, 25, -0.3, 1.7, 100, -2., 0.5);
148 }
149 }
150 if (withNtuple) {
151 fNtuple = new TNtuple("4DP", "4DP", "id:px:py:pz:x:y:z");
152 }
153}
154
156 gMC->TrackMomentum(fMom);
157 if ((fMom.E() - fMom.M()) < EMax) {
158 gMC->StopTrack();
159 return;
160 }
161 TParticle* p = gMC->GetStack()->GetCurrentTrack();
162 Int_t pdgCode = p->GetPdgCode();
163 // record statistics for neutrinos, electrons and photons
164 // add pi0 111 eta 221 eta' 331 omega 223
165 Int_t idabs = TMath::Abs(pdgCode);
166 if (idabs < 18 || idabs == 22 || idabs == 111 || idabs == 221 ||
167 idabs == 223 || idabs == 331 || idabs == 211 || idabs == 321 ||
168 idabs == 2212) {
169 Double_t wspill = p->GetWeight();
170 Int_t idhnu = idabs + 10000;
171 if (pdgCode < 0) {
172 idhnu += 10000;
173 }
174 Double_t l10ptot =
175 TMath::Min(TMath::Max(TMath::Log10(fMom.P()), -0.3), 1.69999);
176 Double_t l10pt =
177 TMath::Min(TMath::Max(TMath::Log10(fMom.Pt()), -2.), 0.4999);
178 TString key = fVetoName;
179 key += idhnu;
180 TH1D* h1 = dynamic_cast<TH1D*>(fout->Get(key));
181 if (h1) {
182 h1->Fill(fMom.P(), wspill);
183 }
184 key = fVetoName;
185 key += idhnu + 1000;
186 TH2D* h2 = dynamic_cast<TH2D*>(fout->Get(key));
187 if (h2) {
188 h2->Fill(l10ptot, l10pt, wspill);
189 }
190 key = fVetoName;
191 key += idhnu + 2000;
192 h2 = dynamic_cast<TH2D*>(fout->Get(key));
193 if (h2) {
194 h2->Fill(l10ptot, l10pt, wspill);
195 }
196 if (withNtuple) {
197 fNtuple->Fill(pdgCode, fMom.Px(), fMom.Py(), fMom.Pz(), fPos.X(),
198 fPos.Y(), fPos.Z());
199 }
200 if (fSkipNeutrinos && (idabs == 12 || idabs == 14 || idabs == 16)) {
201 gMC->StopTrack();
202 }
203 }
204}
205
207 for (Int_t idnu = 11; idnu < 23; idnu += 1) {
208 // nu or anti-nu
209 for (Int_t idadd = -1; idadd < 3; idadd += 2) {
210 Int_t idw = idnu;
211 if (idnu == 18) {
212 idw = 22;
213 }
214 if (idnu == 19) {
215 idw = 111;
216 }
217 if (idnu == 20) {
218 idw = 221;
219 }
220 if (idnu == 21) {
221 idw = 223;
222 }
223 if (idnu == 22) {
224 idw = 331;
225 }
226 Int_t idhnu = 10000 + idw;
227 if (idadd == -1) {
228 if (idnu > 17) {
229 continue;
230 }
231 idhnu += 10000;
232 idw = -idnu;
233 }
234 TString key = fVetoName;
235 key += idhnu;
236 TSeqCollection* fileList = gROOT->GetListOfFiles();
237 dynamic_cast<TFile*>(fileList->At(0))->cd();
238 TH1D* Hidhnu = dynamic_cast<TH1D*>(fout->Get(key));
239 Hidhnu->Write();
240 key = fVetoName;
241 key += idhnu + 1000;
242 TH2D* Hidhnu100 = dynamic_cast<TH2D*>(fout->Get(key));
243 Hidhnu100->Write();
244 key = fVetoName;
245 key += idhnu + 2000;
246 TH2D* Hidhnu200 = dynamic_cast<TH2D*>(fout->Get(key));
247 Hidhnu200->Write();
248 }
249 }
250 if (withNtuple) {
251 fNtuple->Write();
252 }
253}
254
256 static FairGeoLoader* geoLoad = FairGeoLoader::Instance();
257 static FairGeoInterface* geoFace = geoLoad->getGeoInterface();
258 static FairGeoMedia* media = geoFace->getMedia();
259 static FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
260
261 FairGeoMedium* ShipMedium = media->getMedium("vacuums");
262 TGeoMedium* vac = gGeoManager->GetMedium("vacuums");
263 if (vac == nullptr) geoBuild->createMedium(ShipMedium);
264 vac = gGeoManager->GetMedium("vacuums");
265 gGeoManager->GetTopVolume();
266 TGeoNavigator* nav = gGeoManager->GetCurrentNavigator();
267 Double_t zLoc;
268 if (fzPos > 1E8) {
269 // Add thin sensitive plane after hadron absorber
270 Float_t distance = 1.;
271 Double_t local[3] = {0, 0, 0};
272 if (!nav->cd("/MuonShieldArea_1/AbsorberVol_1")) {
273 nav->cd("/MuonShieldArea_1/MagnAbsorb_MagRetL_1");
274 distance = -1.;
275 }
276 TGeoBBox* tmp =
277 dynamic_cast<TGeoBBox*>(nav->GetCurrentNode()->GetVolume()->GetShape());
278 local[2] = distance * tmp->GetDZ();
279 Double_t global[3] = {0, 0, 0};
280 nav->LocalToMaster(local, global);
281 zLoc = global[2] + distance * 1. * cm;
282 } else {
283 zLoc = fzPos;
284 } // use external input
285
286 TString myname(this->GetName());
287 TString shapename_prefix(myname); // Use a prefix for shapenames
288
289 Double_t xLocPlane = 0.0;
290 Double_t yLocPlane = 0.0;
291 Double_t zLocPlane = zLoc;
292
293 if (!fCylindricalPlane) {
294 TGeoVolume* sensPlane =
295 gGeoManager->MakeBox(shapename_prefix + fVetoName + "_box", vac,
296 3.56 * m - 1. * mm, 1.7 * m - 1. * mm, 1. * mm);
297 std::cout << this->GetName()
298 << ", ConstructGeometry(): Created Box with dimensions: "
299 "3.56*m-1.*mm,1.7*m-1.*mm,1.*mm"
300 << std::endl;
301
302 if (!fUseCaveCoordinates) {
303 nav->cd("/MuonShieldArea_1/");
304 } else {
305 Double_t local[3] = {0, 0, zLoc};
306 Double_t global[3];
307 nav->cd("/target_vacuum_box_1/TargetArea_1");
308 nav->LocalToMaster(local, global);
309 nav->cd("/cave_1");
310 yLocPlane = global[1];
311 zLocPlane = global[2];
312 xLocPlane = global[0];
313 }
314 sensPlane->SetLineColor(kBlue - 10);
315 nav->GetCurrentNode()->GetVolume()->AddNode(
316 sensPlane, 1, new TGeoTranslation(xLocPlane, yLocPlane, zLocPlane));
317 AddSensitiveVolume(sensPlane);
318 } else { // add cylindrical sensPlane
319 TGeoVolume* sensPlaneCyl =
320 gGeoManager->MakeTube(shapename_prefix + fVetoName + "_tube", vac,
321 12.51 * cm, 12.52 * cm, zLoc / 2.);
322 std::cout << this->GetName()
323 << ", ConstructGeometry(): Created Tube with dimensions: "
324 "12.51*cm,12.52*cm,zLoc/2."
325 << std::endl;
326 nav->cd("/target_vacuum_box_1/TargetArea_1/HeVolume_1");
327 nav->GetCurrentNode()->GetVolume()->AddNode(sensPlaneCyl, 1,
328 new TGeoTranslation(0, 0, 0));
329 AddSensitiveVolume(sensPlaneCyl);
330 }
331}
332
334 fDetPoints = new std::vector<vetoPoint>();
335 TString name = fVetoName + "Point";
336 FairRootManager::Instance()->RegisterAny(name.Data(), fDetPoints, kTRUE);
337}
Double_t cm
Double_t m
Double_t mm
@ kVETO
Int_t fTrackID
event index
Definition: Detector.h:85
std::vector< vetoPoint > * fDetPoints
energy loss
Definition: Detector.h:92
TLorentzVector fPos
volume id
Definition: Detector.h:87
Double_t fTime
momentum at entrance
Definition: Detector.h:89
vetoPoint * AddHit(Args &&... args)
Definition: Detector.h:38
TLorentzVector fMom
position at entrance
Definition: Detector.h:88
void Initialize() override
void ConstructGeometry() override
Bool_t fUseCaveCoordinates
cylindrical sensPlane flag
Bool_t ProcessHits(FairVolume *v=0) override
Bool_t fCylindricalPlane
max energy to transport
Bool_t withNtuple
zPos, optional
void PreTrack() override
void Register() override
TString fVetoName
flag if neutrinos should be ignored
TFile * fout
set position from cave
TNtuple * fNtuple
special option for Dark Photon physics studies
Bool_t fSkipNeutrinos
flag if only muons should be stored
void FinishRun() override
Double_t cm
Double_t m
Double_t mm