FairShip
Loading...
Searching...
No Matches
SiliconTarget.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 "SiliconTarget.h"
6
7#include "ShipDetectorList.h"
8#include "ShipGeoUtil.h"
9#include "ShipStack.h"
10#include "ShipUnit.h"
11
12// ROOT / TGeo headers
13#include "TGeoBBox.h"
14#include "TGeoCompositeShape.h"
15#include "TGeoManager.h"
16#include "TGeoMaterial.h"
17#include "TGeoMedium.h"
18#include "TGeoVolume.h"
19#include "TParticle.h"
20#include "TVector3.h"
21
22// FairROOT headers
23#include "FairVolume.h"
24#include "TVirtualMC.h"
25
26using namespace ShipUnit;
27
29 : Detector("SiliconTarget", kTRUE, kSiliconTarget) {}
30
31SiliconTarget::SiliconTarget(const char* name, Bool_t Active,
32 const char* /*Title*/)
33 : Detector(name, Active, kSiliconTarget) {}
34
36 Double_t targetWidth, Double_t targetHeight, Double_t sensorWidth,
37 Double_t sensorLength, Int_t nLayers, Double_t zPosition,
38 Double_t targetThickness, Double_t targetSpacing, Double_t moduleOffset) {
39 fTargetWidth = targetWidth;
40 fTargetHeight = targetHeight;
41 fSensorWidth = sensorWidth;
42 fSensorLength = sensorLength;
43 fLayers = nLayers;
44 fZPosition = zPosition;
45 fTargetThickness = targetThickness;
46 fTargetSpacing = targetSpacing;
47 fModuleOffset = moduleOffset;
48}
49
50TGeoVolume* SiliconTarget::CreateSiliconPlanes(const char* name, Double_t width,
51 Double_t length,
52 Double_t spacing,
53 TGeoMedium* silicon,
54 Int_t layerId) {
55 Double_t strip_pitch = 75.5 * um;
56 Int_t nRows = 2;
57 Int_t nCols = 4;
58 Int_t nPlanes = 2;
59
60 TGeoBBox* SensorShape =
61 new TGeoBBox("SensorShape", width / 2, length / 2, 0.3 * mm / 2);
62 TGeoVolume* SensorVolume =
63 new TGeoVolume("SensorVolume", SensorShape, silicon);
64 SensorVolume->SetLineColor(kRed);
65 SensorVolume->SetTransparency(40);
66
67 auto* Strips =
68 SensorVolume->Divide("SLICEX", 1, 1298, -width / 2, strip_pitch);
69 AddSensitiveVolume(Strips);
70
71 TGeoVolumeAssembly* trackingStation =
72 new TGeoVolumeAssembly("TrackingStation");
73 // Each tracking station consists of X and Y planes
74 for (Int_t plane = 0; plane < nPlanes; plane++) {
75 TGeoVolumeAssembly* trackerPlane = new TGeoVolumeAssembly("TrackerPlane");
76 // Each plane consists of 8 modules
77 for (Int_t column = 0; column < nCols; column++) {
78 for (Int_t row = 0; row < nRows; row++) {
79 Int_t sensor_id =
80 (layerId << 5) + (plane << 4) + (column << 2) + (row << 1);
81 // Add 1mm gap between sensors for realistic placement
82 trackerPlane->AddNode(
83 SensorVolume, sensor_id,
84 new TGeoTranslation(
85 (-1.5 * width - 2. * mm) + (column * width + column * 1 * mm),
86 (length / 2. + 0.5 * mm) - row * (length + 1. * mm), 0));
87 }
88 }
89 if (plane == 0) {
90 trackingStation->AddNode(trackerPlane, plane);
91 } else if (plane == 1) {
92 // Rotate the second plane by 90 degrees and translate such that the
93 // planes are evenly spaced.
94 trackingStation->AddNode(
95 trackerPlane, plane,
96 new TGeoCombiTrans(TGeoTranslation(0, 0, spacing),
97 TGeoRotation("y_rot", 0, 0, 90)));
98 }
99 }
100
101 return trackingStation;
102}
104 ShipGeo::InitMedium("tungstensifon");
105 TGeoMedium* tungsten = gGeoManager->GetMedium("tungstensifon");
106 ShipGeo::InitMedium("air");
107 TGeoMedium* air = gGeoManager->GetMedium("air");
108 ShipGeo::InitMedium("silicon");
109 TGeoMedium* Silicon = gGeoManager->GetMedium("silicon");
110
111 Double_t totalLength = fLayers * fTargetSpacing;
112
113 // --- Create an envelope volume for the detector (green, semi-transparent)
114 // ---
115 auto envBox = new TGeoBBox("SiliconTarget_env", fTargetWidth / 2.,
116 fTargetHeight / 2., totalLength / 2.);
117 auto envVol = new TGeoVolume("SiliconTarget", envBox, air);
118 envVol->SetLineColor(kGreen);
119 envVol->SetTransparency(50);
120
121 auto target = new TGeoBBox("Target", fTargetWidth / 2., fTargetHeight / 2.,
122 fTargetThickness / 2.);
123 auto targetVol = new TGeoVolume("TargetVol", target, tungsten);
124 targetVol->SetLineColor(kGray);
125 targetVol->SetTransparency(40);
126
127 for (Int_t i = 0; i < fLayers; i++) {
128 // Compute the center position (z) for the current W layer
129 Double_t zPos = -totalLength / 2 + i * fTargetSpacing;
130
131 // Place the tungsten layer
132 envVol->AddNode(targetVol, i,
133 new TGeoTranslation(0, 0, zPos + fTargetThickness / 2.));
134
135 TGeoVolume* siliconPlanes = CreateSiliconPlanes(
136 "TrackerPlane", fSensorWidth, fSensorLength,
137 fTargetSpacing - fTargetThickness - 2. * fModuleOffset, Silicon, i);
138 envVol->AddNode(
139 siliconPlanes, i,
140 new TGeoTranslation(0, 0, zPos + fTargetThickness + fModuleOffset));
141 }
142
143 // Finally, add the envelope to the top volume with the global z offset
144 // fZCenter
145 gGeoManager->GetTopVolume()->AddNode(envVol, 1,
146 new TGeoTranslation(0, 0, fZPosition));
147}
148
149Bool_t SiliconTarget::ProcessHits(FairVolume* vol) {
151 // Set parameters at entrance of volume. Reset ELoss.
152 if (gMC->IsTrackEntering()) {
153 fELoss = 0.;
154 fTime = gMC->TrackTime() * 1.0e09;
155 fLength = gMC->TrackLength();
156 gMC->TrackPosition(fPos);
157 gMC->TrackMomentum(fMom);
158 }
159
160 // Sum energy loss for all steps in the active volume
161 fELoss += gMC->Edep();
162
163 // Create SiliconTargetPoint at exit of active volume
164 if (gMC->IsTrackExiting() || gMC->IsTrackStop() ||
165 gMC->IsTrackDisappeared()) {
166 if (fELoss == 0.) {
167 return kFALSE;
168 }
169
170 TParticle* p = gMC->GetStack()->GetCurrentTrack();
171 fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
172 Int_t pdgCode = p->GetPdgCode();
173 TLorentzVector Pos;
174 gMC->TrackPosition(Pos);
175 TLorentzVector Mom;
176 gMC->TrackMomentum(Mom);
177
178 Double_t xmean = (fPos.X() + Pos.X()) / 2.;
179 Double_t ymean = (fPos.Y() + Pos.Y()) / 2.;
180 Double_t zmean = (fPos.Z() + Pos.Z()) / 2.;
181
182 Int_t strip_id = 0;
183 Int_t sensor_id = 0;
184 gMC->CurrentVolID(strip_id);
185 gMC->CurrentVolOffID(1, sensor_id);
186 fVolumeID = (sensor_id << 12) + strip_id;
187
188 AddHit(fTrackID, fVolumeID, TVector3(xmean, ymean, zmean),
189 TVector3(fMom.Px(), fMom.Py(), fMom.Pz()), fTime, fLength, fELoss,
190 pdgCode);
191
192 ShipStack* stack = dynamic_cast<ShipStack*>(gMC->GetStack());
193 stack->AddPoint(kSiliconTarget);
194 }
195 return kTRUE;
196}
Double_t mm
@ kSiliconTarget
TLorentzVector fPos
volume id
Definition: Detector.h:87
Double_t fTime
momentum at entrance
Definition: Detector.h:89
SiliconTargetPoint * AddHit(Args &&... args)
Definition: Detector.h:38
TLorentzVector fMom
position at entrance
Definition: Detector.h:88
Double_t fModuleOffset
Definition: SiliconTarget.h:43
Double_t fSensorLength
Definition: SiliconTarget.h:38
Double_t fTargetWidth
Definition: SiliconTarget.h:35
Double_t fTargetHeight
Definition: SiliconTarget.h:36
Bool_t ProcessHits(FairVolume *vol=0) override
void SetSiliconTargetParameters(Double_t targetWidth, Double_t targetHeight, Double_t sensorWidth, Double_t sensorLength, Int_t nLayers, Double_t zPosition, Double_t targetThickness, Double_t targetSpacing, Double_t moduleOffset)
Double_t fSensorWidth
Definition: SiliconTarget.h:37
Double_t fZPosition
Definition: SiliconTarget.h:40
Double_t fTargetSpacing
Definition: SiliconTarget.h:42
Double_t fTargetThickness
Definition: SiliconTarget.h:41
TGeoVolume * CreateSiliconPlanes(const char *name, Double_t sensorWidth, Double_t sensorLength, Double_t planeSpacing, TGeoMedium *material, Int_t layerId)
void ConstructGeometry() override
Int_t InitMedium(const char *name)
Definition: ShipGeoUtil.h:20