SND@LHC Software
Loading...
Searching...
No Matches
Scifi Class Reference

#include <Scifi.h>

Inheritance diagram for Scifi:
Collaboration diagram for Scifi:

Public Member Functions

 Scifi (const char *name, Bool_t Active, const char *Title="Scifi")
 
 Scifi ()
 
virtual ~Scifi ()
 
void ConstructGeometry ()
 
void GetPosition (Int_t id, TVector3 &vLeft, TVector3 &vRight)
 
TVector3 GetLocalPos (Int_t id, TVector3 *glob)
 
void GetSiPMPosition (Int_t SiPMChan, TVector3 &A, TVector3 &B)
 
Double_t GetCorrectedTime (Int_t fDetectorID, Double_t rawTime, Double_t L)
 
Double_t ycross (Double_t a, Double_t R, Double_t x)
 
Double_t integralSqrt (Double_t ynorm)
 
Double_t fraction (Double_t R, Double_t x, Double_t y)
 
Double_t area (Double_t a, Double_t R, Double_t xL, Double_t xR)
 
void SiPMmapping ()
 
std::map< Int_t, std::map< Int_t, std::array< float, 2 > > > GetSiPMmap ()
 
std::map< Int_t, std::map< Int_t, std::array< float, 2 > > > GetFibresMap ()
 
std::map< Int_t, float > GetSiPMPos ()
 
virtual void SiPMOverlap ()
 
void SetConfPar (TString name, Float_t value)
 
void SetConfPar (TString name, Int_t value)
 
void SetConfPar (TString name, TString value)
 
Float_t GetConfParF (TString name)
 
Int_t GetConfParI (TString name)
 
TString GetConfParS (TString name)
 
void InitEvent (SNDLHCEventHeader *e)
 
virtual void Initialize ()
 
virtual Bool_t ProcessHits (FairVolume *v=0)
 
virtual void Register ()
 
virtual TClonesArray * GetCollection (Int_t iColl) const
 
virtual void Reset ()
 
ScifiPointAddHit (Int_t trackID, Int_t detID, TVector3 pos, TVector3 mom, Double_t time, Double_t length, Double_t eLoss, Int_t pdgCode)
 
virtual void CopyClones (TClonesArray *cl1, TClonesArray *cl2, Int_t offset)
 
virtual void SetSpecialPhysicsCuts ()
 
virtual void EndOfEvent ()
 
virtual void FinishPrimary ()
 
virtual void FinishRun ()
 
virtual void BeginPrimary ()
 
virtual void PostTrack ()
 
virtual void PreTrack ()
 
virtual void BeginEvent ()
 
 Scifi (const Scifi &)
 
Scifioperator= (const Scifi &)
 

Public Attributes

ClassDef(Scifi, 3) private Int_t fVolumeID
 track index
 
TLorentzVector fPos
 volume id
 
TLorentzVector fMom
 position at entrance
 
Double32_t fTime
 momentum at entrance
 
Double32_t fLength
 time
 
Double32_t fELoss
 length
 
std::map< Int_t, std::map< Int_t, std::array< float, 2 > > > fibresSiPM
 energy loss
 
std::map< Int_t, std::map< Int_t, std::array< float, 2 > > > siPMFibres
 mapping of fibres to SiPM channels
 
std::map< Int_t, float > SiPMPos
 inverse mapping
 
TClonesArray * fScifiPointCollection
 local SiPM channel position
 
std::map< TString, Float_t > conf_floats
 
std::map< TString, Int_t > conf_ints
 
std::map< TString, TString > conf_strings
 
SNDLHCEventHeadereventHeader
 
std::vector< int > covered_runs_time_alignment
 
std::vector< int > covered_runs_position_alignment
 
int last_run_time
 
int last_run_pos
 
TString last_time_alignment_tag
 
TString last_position_alignment_tag
 
bool alignment_init
 

Protected Member Functions

Int_t InitMedium (const char *name)
 

Detailed Description

Definition at line 19 of file Scifi.h.

Constructor & Destructor Documentation

◆ Scifi() [1/3]

Scifi::Scifi ( const char *  name,
Bool_t  Active,
const char *  Title = "Scifi" 
)

Definition at line 65 of file Scifi.cxx.

66: FairDetector(name, true, kLHCScifi),
67fTrackID(-1),
68fVolumeID(-1),
69fPos(),
70fMom(),
71fTime(-1.),
72fLength(-1.),
73fELoss(-1),
76last_run_pos(-1),
79alignment_init(false),
80fScifiPointCollection(new TClonesArray("ScifiPoint"))
81{
82}
@ kLHCScifi
Double32_t fTime
momentum at entrance
Definition Scifi.h:109
Double32_t fELoss
length
Definition Scifi.h:111
TString last_time_alignment_tag
Definition Scifi.h:127
int last_run_time
Definition Scifi.h:126
bool alignment_init
Definition Scifi.h:129
TClonesArray * fScifiPointCollection
local SiPM channel position
Definition Scifi.h:116
int last_run_pos
Definition Scifi.h:126
TString last_position_alignment_tag
Definition Scifi.h:128
TLorentzVector fPos
volume id
Definition Scifi.h:107
Double32_t fLength
time
Definition Scifi.h:110
ClassDef(Scifi, 3) private Int_t fVolumeID
track index
Definition Scifi.h:98
TLorentzVector fMom
position at entrance
Definition Scifi.h:108
SNDLHCEventHeader * eventHeader
Definition Scifi.h:121

◆ Scifi() [2/3]

Scifi::Scifi ( )

Definition at line 46 of file Scifi.cxx.

47: FairDetector("Scifi", "", kTRUE),
48fTrackID(-1),
49fVolumeID(-1),
50fPos(),
51fMom(),
52fTime(-1.),
53fLength(-1.),
54fELoss(-1),
57last_run_pos(-1),
60alignment_init(false),
61fScifiPointCollection(new TClonesArray("ScifiPoint"))
62{
63}

◆ ~Scifi()

Scifi::~Scifi ( )
virtual

Definition at line 84 of file Scifi.cxx.

85{
87 fScifiPointCollection->Delete();
89 }
90}

◆ Scifi() [3/3]

Scifi::Scifi ( const Scifi )

Member Function Documentation

◆ AddHit()

ScifiPoint * Scifi::AddHit ( Int_t  trackID,
Int_t  detID,
TVector3  pos,
TVector3  mom,
Double_t  time,
Double_t  length,
Double_t  eLoss,
Int_t  pdgCode 
)

This method is an example of how to add your own point of type muonPoint to the clones array

Definition at line 860 of file Scifi.cxx.

864{
865 TClonesArray& clref = *fScifiPointCollection;
866 Int_t size = clref.GetEntriesFast();
867 return new(clref[size]) ScifiPoint(trackID, detID, pos, mom,
868 time, length, eLoss, pdgCode);
869}

◆ area()

Double_t Scifi::area ( Double_t  a,
Double_t  R,
Double_t  xL,
Double_t  xR 
)

Definition at line 735 of file Scifi.cxx.

736{
737 Double_t fracL = -1;
738 Double_t fracR = -1;
739 if (xL<=a-R && xR>=a+R) {return 1;}
740 Double_t leftC = ycross(a,R,xL);
741 Double_t rightC = ycross(a,R,xR);
742 if (leftC<0 && rightC<0) {return -1;}
743 if ( !(rightC<0) ){ fracR = fraction(R,abs(xR-a),rightC);}
744 if ( !(leftC<0) ) { fracL = fraction(R,abs(xL-a),leftC);}
745 Double_t theAnswer = 0;
746 if ( !(leftC<0) ) {
747 if(xL<a){theAnswer += 1-fracL;}
748 else{ theAnswer += fracL;}
749 if ( !(rightC<0) ) {theAnswer -=1;}
750 }
751 if ( !(rightC<0) ){
752 if(xR>a){ theAnswer += 1-fracR;}
753 else{ theAnswer += fracR;}
754 }
755 return theAnswer;
756}
Double_t ycross(Double_t a, Double_t R, Double_t x)
Definition Scifi.cxx:716
Double_t fraction(Double_t R, Double_t x, Double_t y)
Definition Scifi.cxx:728

◆ BeginEvent()

virtual void Scifi::BeginEvent ( )
inlinevirtual

Definition at line 92 of file Scifi.h.

92{;}

◆ BeginPrimary()

virtual void Scifi::BeginPrimary ( )
inlinevirtual

Definition at line 89 of file Scifi.h.

89{;}

◆ ConstructGeometry()

void Scifi::ConstructGeometry ( )

Create the detector geometry

Definition at line 118 of file Scifi.cxx.

119{
120 InitMedium("CarbonComposite");
121 TGeoMedium *CarbonComposite = gGeoManager->GetMedium("CarbonComposite");
122
123 InitMedium("rohacell");
124 TGeoMedium *rohacell = gGeoManager->GetMedium("rohacell");
125
126 InitMedium("air");
127 TGeoMedium *air = gGeoManager->GetMedium("air");
128
129 InitMedium("Polycarbonate");
130 TGeoMedium *PlasticBase = gGeoManager->GetMedium("Polycarbonate");
131
132 InitMedium("Polystyrene");
133 TGeoMedium *Polystyrene = gGeoManager->GetMedium("Polystyrene");
134
135 InitMedium("PMMA");
136 TGeoMedium *PMMA = gGeoManager->GetMedium("PMMA");
137
138 InitMedium("PMMA2");
139 TGeoMedium *PMMA2 = gGeoManager->GetMedium("PMMA2");
140
141 InitMedium("Epoxy");
142 TGeoMedium *Epoxy = gGeoManager->GetMedium("Epoxy");
143
144 TGeoVolume *volTarget = gGeoManager->GetVolume("volTarget");
145
146 InitMedium("iron");
147 TGeoMedium *Fe =gGeoManager->GetMedium("iron");
148
149// external parameters
150 Double_t fXDimension = conf_floats["Scifi/xdim"];
151 Double_t fYDimension = conf_floats["Scifi/ydim"];
152 Double_t fZDimension = conf_floats["Scifi/zdim"];
153
154 Double_t fWidthScifiMat = conf_floats["Scifi/scifimat_width"];
155 Double_t fLengthScifiMat = conf_floats["Scifi/scifimat_length"];
156 Double_t fZScifiMat = conf_floats["Scifi/scifimat_z"];
157 Double_t fZEpoxyMat = conf_floats["Scifi/epoxymat_z"];
158 Double_t fGapScifiMat = conf_floats["Scifi/scifimat_gap"]; //dead zone between mats
159
160 Double_t fFiberLength = conf_floats["Scifi/fiber_length"];
161 Double_t fScintCore_rmax = conf_floats["Scifi/scintcore_rmax"];
162 Double_t fClad1_rmin = conf_floats["Scifi/clad1_rmin"];
163 Double_t fClad1_rmax = conf_floats["Scifi/clad1_rmax"];
164 Double_t fClad2_rmin = conf_floats["Scifi/clad2_rmin"];
165 Double_t fClad2_rmax = conf_floats["Scifi/clad2_rmax"];
166
167 Double_t fHorPitch = conf_floats["Scifi/horizontal_pitch"]; //Fiber position params
168 Double_t fVertPitch = conf_floats["Scifi/vertical_pitch"];
169 Double_t fOffsetRowS = conf_floats["Scifi/rowlong_offset"];
170 Double_t fOffsetRowL = conf_floats["Scifi/rowshort_offset"];
171
172 Double_t fZCarbonFiber = conf_floats["Scifi/carbonfiber_z"];
173 Double_t fZHoneycomb = conf_floats["Scifi/honeycomb_z"];
174
175 Double_t fXPlastBar = conf_floats["Scifi/plastbar_x"]; //Dimension of plastic bar
176 Double_t fYPlastBar = conf_floats["Scifi/plastbar_y"];
177 Double_t fZPlastBar = conf_floats["Scifi/plastbar_z"];
178
179 Int_t fNFibers_Srow = conf_ints["Scifi/nfibers_shortrow"];
180 Int_t fNFibers_Lrow = conf_ints["Scifi/nfibers_longrow"];
181 Int_t fNFibers_z = conf_ints["Scifi/nfibers_z"];
182
183 Double_t fSeparationBrick = conf_floats["Scifi/scifi_separation"]; //Separation between successive SciFi volumes
184 Double_t fZOffset = conf_floats["Scifi/offset_z"];
185 Int_t fNMats = conf_ints["Scifi/nmats"]; //Number of mats in one SciFi plane
186 Int_t fNScifi = conf_ints["Scifi/nscifi"]; //Number of Scifi walls
187 Int_t fNSiPMs = conf_ints["Scifi/nsipm_mat"]; //Number of SiPMs per SciFi mat
188
189 Double_t fWidthChannel = conf_floats["Scifi/channel_width"]; //One channel width
190 Double_t fCharr = conf_floats["Scifi/charr_width"]; //Width of an array of 64 channels without gaps
191 Double_t fEdge = conf_floats["Scifi/sipm_edge"]; //Edge at the left and right sides of the SiPM
192 Double_t fCharrGap = conf_floats["Scifi/charr_gap"]; //Gap between two charr
193 Double_t fBigGap = conf_floats["Scifi/sipm_diegap"]; //Gap between two arrays
194 Int_t fNSiPMChan = conf_ints["Scifi/nsipm_channels"]; //Number of channels in each SiPM
195 Double_t firstChannelX = conf_floats["Scifi/firstChannelX"]; //local X Position of first channel in plane
196
197//edge positions in TI18 survey system:
198 std::map<int,TVector3> Vedges;
199 Vedges[0]=TVector3(-conf_floats["Scifi/Xpos0"],conf_floats["Scifi/Zpos0"],conf_floats["Scifi/Ypos0"]);
200 Vedges[1]=TVector3(-conf_floats["Scifi/Xpos1"],conf_floats["Scifi/Zpos1"],conf_floats["Scifi/Ypos1"]);
201 Vedges[2]=TVector3(-conf_floats["Scifi/Xpos2"],conf_floats["Scifi/Zpos2"],conf_floats["Scifi/Ypos2"]);
202 Vedges[3]=TVector3(-conf_floats["Scifi/Xpos3"],conf_floats["Scifi/Zpos3"],conf_floats["Scifi/Ypos3"]);
203 Vedges[4]=TVector3(-conf_floats["Scifi/Xpos4"],conf_floats["Scifi/Zpos4"],conf_floats["Scifi/Ypos4"]);
204
205//edge position in Scifi engineering drawing, y down, z towards IP1, pos X left.
206// need y up, z away from IP1, pos X left: y and z need to change sign.
207
208 TVector3 Sedge = TVector3(conf_floats["Scifi/EdgeAX"],-conf_floats["Scifi/EdgeAY"],-conf_floats["Scifi/EdgeAZ"]);
209//first channel position in Scifi engineering drawing:
210 TVector3 SHfirst = TVector3(conf_floats["Scifi/FirstChannelHX"],-conf_floats["Scifi/FirstChannelHY"],-conf_floats["Scifi/FirstChannelHZ"]);
211 TVector3 SVfirst = TVector3(conf_floats["Scifi/FirstChannelVX"],-conf_floats["Scifi/FirstChannelVY"],-conf_floats["Scifi/FirstChannelVZ"]);
212
213//first channel position in sndsw local plane:
214 TVector3 LHfirst = TVector3(conf_floats["Scifi/LfirstChannelHX"],conf_floats["Scifi/LfirstChannelHY"],conf_floats["Scifi/LfirstChannelHZ"]);
215 TVector3 LVfirst = TVector3(conf_floats["Scifi/LfirstChannelVX"],conf_floats["Scifi/LfirstChannelVY"],conf_floats["Scifi/LfirstChannelVZ"]);
216// moving plane to match edges:
217 std::map<int,TVector3> DeltasH;
218 std::map<int,TVector3> DeltasV;
219 for (int i=0;i<5;i++){
220 DeltasH[i] = Vedges[i] - LHfirst + SHfirst - Sedge;
221 DeltasV[i] = Vedges[i] - LVfirst + SVfirst - Sedge;
222 }
223
224 //Carbon Fiber Film
225 TGeoVolume *CarbonFiberVolume = gGeoManager->MakeBox("CarbonFiber", CarbonComposite, fXDimension/2, fYDimension/2, fZCarbonFiber/2);
226 CarbonFiberVolume->SetLineColor(kGray - 2);
227 CarbonFiberVolume->SetVisibility(1);
228
229 //Honeycomb Rohacell
230 TGeoVolume *HoneycombVolume = gGeoManager->MakeBox("Honeycomb", rohacell, fXDimension/2, fYDimension/2, fZHoneycomb/2);
231 HoneycombVolume->SetLineColor(kYellow);
232 HoneycombVolume->SetVisibility(1);
233
234 //Plastic/Air
235 //Definition of the box containing polycarbonate pieces and an air gap
236 TGeoVolume *PlasticAirVolume = gGeoManager->MakeBox("PlasticAir", air, fXDimension/2, fYDimension/2, fZPlastBar/2);
237 PlasticAirVolume->SetLineColor(kGray-1);
238 PlasticAirVolume->SetVisibility(1);
239 PlasticAirVolume->SetVisDaughters(1);
240
241 //Plastic bars
242 TGeoVolume *PlasticBarVolume = gGeoManager->MakeBox("PlasticBar", PlasticBase, fXPlastBar/2, fYPlastBar/2, fZPlastBar/2);
243 PlasticBarVolume->SetLineColor(kGray-4);
244 PlasticBarVolume->SetVisibility(1);
245
246 PlasticAirVolume->AddNode(PlasticBarVolume, 0, new TGeoTranslation(- fXDimension/2 + fXPlastBar/2, 0, 0)); //bars are placed || to y
247 PlasticAirVolume->AddNode(PlasticBarVolume, 1, new TGeoTranslation(+ fXDimension/2 - fXPlastBar/2, 0, 0));
248
249 //Fiber volume that contains the scintillating core and double cladding
250 TGeoVolumeAssembly *FiberVolume = new TGeoVolumeAssembly("FiberVolume");
251
252 TGeoVolume *ScintCoreVol = gGeoManager->MakeTube("ScintCoreVol", Polystyrene, 0, fScintCore_rmax, fFiberLength/2);
253 TGeoVolume *Clad1Vol = gGeoManager->MakeTube("Clad1Vol", PMMA, fClad1_rmin, fClad1_rmax, fFiberLength/2);
254 TGeoVolume *Clad2Vol = gGeoManager->MakeTube("Clad2Vol", PMMA2, fClad2_rmin, fClad2_rmax, fFiberLength/2);
255
256 FiberVolume->AddNode(ScintCoreVol, 0);
257 FiberVolume->AddNode(Clad1Vol, 0);
258 FiberVolume->AddNode(Clad2Vol, 0);
259 FiberVolume->SetVisDaughters(kFALSE);
260
261 //Add SciFi fiber as sensitive unit
262 AddSensitiveVolume(ScintCoreVol);
263
264 //Fiber and plane rotations
265 TGeoRotation *rothorfiber = new TGeoRotation("rothorfiber", 90, 90, 0);
266 TGeoRotation *rotvertfiber = new TGeoRotation("rotvertfiber", 0, 90, 0);
267 TGeoRotation *rot = new TGeoRotation("rot", 90, 180, 0);
268
269 //SciFi mats for X and Y fiber planes
270 TGeoVolume *HorMatVolume = gGeoManager->MakeBox("HorMatVolume", Epoxy, fLengthScifiMat/2, fWidthScifiMat/2, fZEpoxyMat/2);
271 TGeoVolume *VertMatVolume = gGeoManager->MakeBox("VertMatVolume", Epoxy, fWidthScifiMat/2, fLengthScifiMat/2, fZEpoxyMat/2);
272
273 Double_t zPosM;
274 Double_t offsetS = -fWidthScifiMat/2 + fOffsetRowS;
275 Double_t offsetL = -fWidthScifiMat/2 + fOffsetRowL;
276
277 // All fibres will be assigned station number 1 and mat number 1, to keep compatibility with the STMRFFF format.
278 int dummy_station = 1;
279 int dummy_mat = 1;
280
281 //Adding horizontal fibers
282 for (int irow = 0; irow < fNFibers_z; irow++){
283 zPosM = -fZScifiMat/2 + fClad2_rmax/2 + irow*fVertPitch;
284 if (irow%2 == 0){
285 for (int ifiber = 0; ifiber < fNFibers_Srow; ifiber++){
286 HorMatVolume->AddNode(FiberVolume, 1e6*dummy_station + 1e5*0 + 1e4*dummy_mat + 1e3*(irow + 1) + ifiber + 1, new TGeoCombiTrans("rottranshor0", 0, offsetS + ifiber*fHorPitch, zPosM, rothorfiber));
287 }
288 }
289 else{
290 for (int ifiber = 0; ifiber < fNFibers_Lrow; ifiber++){
291 HorMatVolume->AddNode(FiberVolume, 1e6*dummy_station + 1e5*0 + 1e4*dummy_mat + 1e3*(irow + 1) + ifiber + 1, new TGeoCombiTrans("rottranshor1", 0, offsetL + ifiber*fHorPitch, zPosM, rothorfiber));
292 }
293 }
294 }
295
296 //Adding vertical fibers
297 for (int irow = 0; irow < fNFibers_z; irow++){
298 zPosM = -fZScifiMat/2 + fClad2_rmax/2 + irow*fVertPitch;
299 if (irow%2 == 0){
300 for (int ifiber = 0; ifiber < fNFibers_Srow; ifiber++){
301 VertMatVolume->AddNode(FiberVolume, 1e6*dummy_station + 1e5*1 + 1e4*dummy_mat + 1e3*(irow + 1) + ifiber + 1, new TGeoCombiTrans("rottransvert0", offsetS + ifiber*fHorPitch, 0, zPosM, rotvertfiber));
302 }
303 }
304 else{
305 for (int ifiber = 0; ifiber < fNFibers_Lrow; ifiber++){
306 VertMatVolume->AddNode(FiberVolume, 1e6*dummy_station + 1e5*1 + 1e4*dummy_mat + 1e3*(irow + 1) + ifiber + 1, new TGeoCombiTrans("rottransvert1", offsetL + ifiber*fHorPitch, 0, zPosM, rotvertfiber));
307 }
308 }
309 }
310
311 // for testbeam 2023
312 // for now the distinct feature of the testbeam could be the 4 SciFi planes
313 std::map<int, TGeoVolume*> volFeTarget;
314 std::map<int, float> fFeTargetX;
315 std::map<int, float> fFeTargetY;
316 std::map<int, float> fFeTargetZ;
317 for ( int i = 0; i < fNScifi; i++){
318 std::string station = std::to_string(i+1);
319 fFeTargetX[i] = conf_floats[TString("Scifi/FeTargetX"+station)];
320 fFeTargetY[i] = conf_floats[TString("Scifi/FeTargetZ"+station)];
321 fFeTargetZ[i] = conf_floats[TString("Scifi/FeTargetY"+station)];
322 }
323
324 // DetID is of the form:
325 // first digit - station number
326 // second digit - type of the plane: 0-horizontal fiber, 1-vertical fiber
327 // third digit - mat number
328 // fourth digit - row number (in Z direction)
329 // last three digits - fiber number
330 // e.g. DetID = 1021074 -> station 1, horizontal fiber plane, mat 2, row 1, fiber 74
331 for (int istation = 0; istation < fNScifi; istation++){
332 Int_t node = 1e6*(istation+1);
333 std::string station = std::to_string(istation+1);
334 TGeoVolumeAssembly *ScifiVolume = new TGeoVolumeAssembly( TString("ScifiVolume"+station) );
335 TGeoVolumeAssembly *ScifiHorPlaneVol = new TGeoVolumeAssembly( TString("ScifiHorPlaneVol"+station) );
336 TGeoVolumeAssembly *ScifiVertPlaneVol = new TGeoVolumeAssembly( TString("ScifiVertPlaneVol"+station) );
337
338 //Adding the first half of the SciFi module that contains horizontal fibres
339 ScifiVolume->AddNode(CarbonFiberVolume, 0, new TGeoTranslation(0, 0, fZCarbonFiber/2));
340 ScifiVolume->AddNode(HoneycombVolume, 0, new TGeoTranslation(0, 0, fZCarbonFiber + fZHoneycomb/2));
341 ScifiVolume->AddNode(CarbonFiberVolume, 1, new TGeoTranslation(0, 0, fZCarbonFiber + fZHoneycomb + fZCarbonFiber/2));
342 ScifiVolume->AddNode(ScifiHorPlaneVol, node, new TGeoTranslation(0, 0, 2*fZCarbonFiber + fZHoneycomb + fZEpoxyMat/2));
343 ScifiVolume->AddNode(PlasticAirVolume, 0, new TGeoTranslation(0, 0, 2*fZCarbonFiber + fZHoneycomb + fZEpoxyMat+ fZPlastBar/2));
344
345 //Adding the second half of the SciFi module that contains vertical fibres
346 ScifiVolume->AddNode(PlasticAirVolume, 1, new TGeoCombiTrans("rottrans0", 0, 0, 2*fZCarbonFiber + fZHoneycomb + fZEpoxyMat + 3*fZPlastBar/2, rot));
347 ScifiVolume->AddNode(ScifiVertPlaneVol, node, new TGeoTranslation(0, 0, 2*fZCarbonFiber + fZHoneycomb + fZEpoxyMat + 2*fZPlastBar + fZEpoxyMat/2));
348 ScifiVolume->AddNode(CarbonFiberVolume, 2, new TGeoTranslation(0, 0, 2*fZCarbonFiber + fZHoneycomb + fZEpoxyMat + 2*fZPlastBar + fZEpoxyMat +fZCarbonFiber/2));
349 ScifiVolume->AddNode(HoneycombVolume, 1, new TGeoTranslation(0, 0, 3*fZCarbonFiber + fZHoneycomb + fZEpoxyMat + 2*fZPlastBar + fZEpoxyMat + fZHoneycomb/2));
350 ScifiVolume->AddNode(CarbonFiberVolume, 3, new TGeoTranslation(0, 0, 3*fZCarbonFiber + 2*fZHoneycomb + fZEpoxyMat + 2*fZPlastBar + fZEpoxyMat + fZCarbonFiber/2));
351
352 Double_t totalThickness = 4*fZCarbonFiber + 2*fZHoneycomb + 2*fZEpoxyMat + 2*fZPlastBar;
353
354 volTarget->AddNode(ScifiVolume, node,
355 new TGeoTranslation(DeltasV[istation][0], DeltasH[istation][1], DeltasH[istation][2]));
356
357 //std::cout<<"deltas "<<DeltasV[istation][0]<<" "<< DeltasH[istation][1]<<" "<< DeltasH[istation][2]<<" "<<totalThickness<<std::endl;
358 // for 2023 testbeam put iron blocks of variable length in between SciFi planes - the planes are dowstream of the blocks!
359 if (fNScifi==4 && istation != 0) {
360 volFeTarget[istation] = gGeoManager->MakeBox(TString("volFeTarget"+station),Fe,fFeTargetX[istation]/2., fFeTargetY[istation]/2., fFeTargetZ[istation]/2.);
361 volFeTarget[istation]->SetLineColor(kGreen-4);
362 volTarget->AddNode(volFeTarget[istation],1,
363 new TGeoTranslation(DeltasV[istation][0] ,
364 DeltasH[istation][1] ,
365 DeltasH[istation][2] - fFeTargetZ[istation]/2.));
366 }
367
368 //Creating Scifi planes by appending fiber mats
369 for (int imat = 0; imat < fNMats; imat++){
370 int N = fNMats==1 ? imat : imat-1;
371
372 //Placing mats along Y
373 ScifiHorPlaneVol->AddNode(HorMatVolume, 1e6*(istation+1) + 1e4*(imat + 1), new TGeoTranslation(0, N*(fWidthScifiMat+fGapScifiMat), 0));
374
375 //Placing mats along X
376 ScifiVertPlaneVol->AddNode(VertMatVolume, 1e6*(istation+1) + 1e5 + 1e4*(imat + 1), new TGeoTranslation(N*(fWidthScifiMat+fGapScifiMat), 0, 0));
377 }
378 }
379
380}
std::map< TString, Int_t > conf_ints
Definition Scifi.h:119
std::map< TString, Float_t > conf_floats
Definition Scifi.h:118
Int_t InitMedium(const char *name)
Definition Scifi.cxx:98
int i
Definition ShipAna.py:86

◆ CopyClones()

virtual void Scifi::CopyClones ( TClonesArray *  cl1,
TClonesArray *  cl2,
Int_t  offset 
)
inlinevirtual

The following methods can be implemented if you need to make any optional action in your detector during the transport.

Definition at line 83 of file Scifi.h.

84 {;}

◆ EndOfEvent()

void Scifi::EndOfEvent ( )
virtual

Definition at line 829 of file Scifi.cxx.

830{
831 fScifiPointCollection->Clear();
832}

◆ FinishPrimary()

virtual void Scifi::FinishPrimary ( )
inlinevirtual

Definition at line 87 of file Scifi.h.

87{;}

◆ FinishRun()

virtual void Scifi::FinishRun ( )
inlinevirtual

Definition at line 88 of file Scifi.h.

88{;}

◆ fraction()

Double_t Scifi::fraction ( Double_t  R,
Double_t  x,
Double_t  y 
)

Definition at line 728 of file Scifi.cxx.

729{
730 Double_t F= 2*R*R*(integralSqrt(y/R) );
731 F-=(2*x*y);
732 Double_t result = F/(R*R*TMath::Pi());
733 return result;
734}
Double_t integralSqrt(Double_t ynorm)
Definition Scifi.cxx:723

◆ GetCollection()

TClonesArray * Scifi::GetCollection ( Int_t  iColl) const
virtual

Gets the produced collections

Definition at line 848 of file Scifi.cxx.

849{
850 if (iColl == 0) { return fScifiPointCollection; }
851 else { return NULL; }
852}

◆ GetConfParF()

Float_t Scifi::GetConfParF ( TString  name)
inline

Definition at line 49 of file Scifi.h.

◆ GetConfParI()

Int_t Scifi::GetConfParI ( TString  name)
inline

Definition at line 50 of file Scifi.h.

50{return conf_ints[name];}

◆ GetConfParS()

TString Scifi::GetConfParS ( TString  name)
inline

Definition at line 51 of file Scifi.h.

51{return conf_strings[name];}
std::map< TString, TString > conf_strings
Definition Scifi.h:120

◆ GetCorrectedTime()

Double_t Scifi::GetCorrectedTime ( Int_t  fDetectorID,
Double_t  rawTime,
Double_t  L 
)

Definition at line 517 of file Scifi.cxx.

517 {
518/* expect time in u.ns and path length to sipm u.cm */
519 TString tag = "t";
520 TString sID;
521
522 if (eventHeader){
523 Int_t fRunNumber = eventHeader->GetRunId();
524 if (fRunNumber != last_run_time){
525 last_run_time = fRunNumber;
526 if (fRunNumber<1) {
527 LOG(ERROR) << "Scifi::GetCorrectedTime: non valid run number "<<fRunNumber;
528 return rawTime;
529 }
530
531 if (covered_runs_time_alignment.size()!=0){
532 tag = "t_"+std::to_string(covered_runs_time_alignment[covered_runs_time_alignment.size()-1]);
533 for (int i=1; i<covered_runs_time_alignment.size(); i++){
534 if (fRunNumber>=covered_runs_time_alignment[i-1] && fRunNumber<covered_runs_time_alignment[i]){
535 tag = "t_"+std::to_string(covered_runs_time_alignment[i-1]);
536 }
537 }
538 // special case
539 if (fRunNumber<5193 && fRunNumber>5174) tag = "t_"+std::to_string(covered_runs_time_alignment[0]);
540 }
541 else{
542 // allow reading older geo files with letter tags i.e. A, B, C
543 tag = "tA";
544 if (fRunNumber>5116 && !(fRunNumber<5193 && fRunNumber>5174) ) {tag = "tB";}
545 }
546 // 2023 testbeam data doesn't have a custom tag
547 if (fRunNumber>=1e5) {tag = "t";}
549 }
550 }
551 sID.Form("%i",fDetectorID);
552 Double_t cor = conf_floats["Scifi/station"+TString(sID(0,1))+last_time_alignment_tag];
553 if (sID(1,1)=="0"){
554 cor+=conf_floats["Scifi/station"+TString(sID(0,1))+"H"+TString(sID(2,1))+last_time_alignment_tag];
555 }else{
556 cor+=conf_floats["Scifi/station"+TString(sID(0,1))+"V"+TString(sID(2,1))+last_time_alignment_tag];
557 }
558 cor += L/conf_floats["Scifi/signalSpeed"];
559 return rawTime-cor;
560}
std::vector< int > covered_runs_time_alignment
Definition Scifi.h:124

◆ GetFibresMap()

std::map< Int_t, std::map< Int_t, std::array< float, 2 > > > Scifi::GetFibresMap ( )
inline

Definition at line 43 of file Scifi.h.

43{return siPMFibres;}
std::map< Int_t, std::map< Int_t, std::array< float, 2 > > > siPMFibres
mapping of fibres to SiPM channels
Definition Scifi.h:113

◆ GetLocalPos()

TVector3 Scifi::GetLocalPos ( Int_t  id,
TVector3 *  glob 
)

Transform global position to local position in plane

Definition at line 607 of file Scifi.cxx.

607 {
608 TString sID;
609 sID.Form("%i",id);
610 TString path = "/cave_1/Detector_0/volTarget_1/ScifiVolume"+TString(sID(0,1))+"_"+TString(sID(0,1))+"000000/";
611 if (sID(1,1)=="0"){
612 path+="ScifiHorPlaneVol"+TString(sID(0,1))+"_"+TString(sID(0,1))+"000000";
613 }else{
614 path+="ScifiVertPlaneVol"+TString(sID(0,1))+"_"+TString(sID(0,1))+"000000";
615 }
616 TGeoNavigator* nav = gGeoManager->GetCurrentNavigator();
617 nav->cd(path);
618 Double_t aglob[3];
619 Double_t aloc[3];
620 glob->GetXYZ(aglob);
621 nav->MasterToLocal(aglob,aloc);
622 return TVector3(aloc[0],aloc[1],aloc[2]);
623}

◆ GetPosition()

void Scifi::GetPosition ( Int_t  id,
TVector3 &  vLeft,
TVector3 &  vRight 
)

Get position of single fibre in global coordinate system

Definition at line 562 of file Scifi.cxx.

563{
564// TGeoVolumeAssembly *SiPMmapVol = gGeoManager->FindVolumeFast("SiPMmapVol");
565// if(!SiPMmapVol ){SiPMmapVol=SiPMOverlap();}
566
567/* STMRFFF
568 First digit S: station # within the sub-detector
569 Second digit T: type of the plane: 0-horizontal fiber plane, 1-vertical fiber plane
570 Third digit M: determines the mat number
571 Fourth digit R: row number (in Z direction)
572 Last three digits F: fiber number
573*/
574
575 Int_t station_number = int(fDetectorID/1e6);
576 Int_t mat_number = int(fDetectorID/1e4)%int(fDetectorID/1e5);
577
578 Int_t local_fibre_id = fDetectorID - (station_number-1)*1e6 - (mat_number-1)*1e4;
579 TString sLocalID;
580 sLocalID.Form("%i", local_fibre_id);
581
582 TString sID;
583 sID.Form("%i",fDetectorID);
584 TString path = "/cave_1/Detector_0/volTarget_1/ScifiVolume"+TString(sID(0,1))+"_"+TString(sID(0,1))+"000000/";
585 if (sID(1,1)=="0"){
586 path+="ScifiHorPlaneVol"+TString(sID(0,1))+"_"+TString(sID(0,1))+"000000/";
587 path+="HorMatVolume_"+TString(sID(0,3))+"0000/";
588 }else{
589 path+="ScifiVertPlaneVol"+TString(sID(0,1))+"_"+TString(sID(0,1))+"000000/";
590 path+="VertMatVolume_"+TString(sID(0,3))+"0000/";
591 }
592 path+="FiberVolume_"+sLocalID;
593 TGeoNavigator* nav = gGeoManager->GetCurrentNavigator();
594 nav->cd(path);
595 LOG(DEBUG) <<path<<" "<<fDetectorID;
596 TGeoNode* W = nav->GetCurrentNode();
597 TGeoBBox* S = dynamic_cast<TGeoBBox*>(W->GetVolume()->GetShape());
598
599 Double_t top[3] = {0,0,S->GetDZ()};
600 Double_t bot[3] = {0,0,-(S->GetDZ())};
601 Double_t Gtop[3],Gbot[3];
602 nav->LocalToMaster(top, Gtop); nav->LocalToMaster(bot, Gbot);
603 A.SetXYZ(Gtop[0],Gtop[1],Gtop[2]);
604 B.SetXYZ(Gbot[0],Gbot[1],Gbot[2]);
605
606}
dict S
Definition MufiCTR.py:12

◆ GetSiPMmap()

std::map< Int_t, std::map< Int_t, std::array< float, 2 > > > Scifi::GetSiPMmap ( )
inline

Definition at line 42 of file Scifi.h.

42{return fibresSiPM;}
std::map< Int_t, std::map< Int_t, std::array< float, 2 > > > fibresSiPM
energy loss
Definition Scifi.h:112

◆ GetSiPMPos()

std::map< Int_t, float > Scifi::GetSiPMPos ( )
inline

Definition at line 44 of file Scifi.h.

44{return SiPMPos;}
std::map< Int_t, float > SiPMPos
inverse mapping
Definition Scifi.h:114

◆ GetSiPMPosition()

void Scifi::GetSiPMPosition ( Int_t  SiPMChan,
TVector3 &  A,
TVector3 &  B 
)

mean position of fibre2 associated with SiPM channel

Definition at line 625 of file Scifi.cxx.

626{
627/* STMRFFF
628 First digit S: station # within the sub-detector
629 Second digit T: type of the plane: 0-horizontal fiber plane, 1-vertical fiber plane
630 Third digit M: determines the mat number 0-2
631 Fourth digit S: SiPM number 0-3
632 Last three digits F: local SiPM channel number in one mat 0-127
633*/
634 Int_t locNumber = SiPMChan%100000;
635 Int_t globNumber = int(SiPMChan/100000)*100000;
636 Float_t locPosition = SiPMPos[locNumber]; // local position in plane of reference plane.
637 Double_t fFiberLength = conf_floats["Scifi/fiber_length"];
638 Int_t fNMats = conf_ints["Scifi/nmats"];
639
640 TString tag = "";
641
642 // in case of old data with FairEventHeader, user will be responsible to use the correct geofile.
643 if (eventHeader){
644 Int_t fRunNumber = eventHeader->GetRunId();
645 if (fRunNumber != last_run_pos){
646 last_run_pos = fRunNumber;
647
648 if (fRunNumber<1) {
649 LOG(ERROR) << "Scifi::GetSiPMPosition: non valid run number "<<fRunNumber;
650 return;
651 }
652
653 if (covered_runs_position_alignment.size()!=0){
655 for (int i=1; i<covered_runs_position_alignment.size(); i++){
656 if (fRunNumber>=covered_runs_position_alignment[i-1] && fRunNumber<covered_runs_position_alignment[i]){
657 tag = "t_"+std::to_string(covered_runs_position_alignment[i-1]);
658 }
659 }
660 }
661 else{
662 // allow reading older geo files with letter tags i.e. A, B, C
663 tag = "E";
664 if (fRunNumber<4575) {tag = "A";}
665 else if (fRunNumber<4855) {tag = "B";}
666 else if (fRunNumber<5172) {tag = "C";}
667 else if (fRunNumber<5431) {tag = "D";}
668 }
669 // 2023 testbeam data doesn't have a custom tag
670 if (fRunNumber>=1e5) {tag = "";}
672 }
673 }
674 TString sID;
675 sID.Form("%i",SiPMChan);
676 Int_t digits = fNMats==1 ? 2 : 1;
677 locPosition += conf_floats["Scifi/LocM"+TString(sID(0,3))+last_position_alignment_tag];
678 Float_t rotPhi = conf_floats["Scifi/RotPhiS"+TString(sID(0,digits))+last_position_alignment_tag];
679 Float_t rotPsi = conf_floats["Scifi/RotPsiS"+TString(sID(0,digits))+last_position_alignment_tag];
680 Float_t rotTheta = conf_floats["Scifi/RotThetaS"+TString(sID(0,digits))+last_position_alignment_tag];
681
682 Double_t loc[3] = {0,0,0};
683 TString path = "/cave_1/Detector_0/volTarget_1/ScifiVolume"+TString(sID(0,1))+"_"+TString(sID(0,1))+"000000/";
684 TGeoNavigator* nav = gGeoManager->GetCurrentNavigator();
685 Double_t glob[3] = {0,0,0};
686
687 if (sID(1,1)=="0"){
688 path+="ScifiHorPlaneVol"+TString(sID(0,1))+"_"+TString(sID(0,1))+"000000";
689 loc[0] = -fFiberLength/2 - (rotPhi + rotPsi)*locPosition ;
690 loc[1] = locPosition - fFiberLength/2 * (rotPhi + rotPsi) ;
691 loc[2] = rotTheta*locPosition;
692 nav->cd(path);
693 nav->LocalToMaster(loc, glob);
694 A.SetXYZ( glob[0], glob[1],glob[2] );
695 loc[0] = fFiberLength/2 - (rotPhi + rotPsi)*locPosition ;
696 loc[1] = locPosition + fFiberLength/2 * (rotPhi + rotPsi) ;
697 loc[2] = - rotTheta*locPosition;
698 nav->LocalToMaster(loc, glob);
699 B.SetXYZ( glob[0], glob[1],glob[2] );
700 }else{
701 path+="ScifiVertPlaneVol"+TString(sID(0,1))+"_"+TString(sID(0,1))+"000000";
702 loc[0] = locPosition + fFiberLength/2*(rotPhi + rotPsi);
703 loc[1] = -fFiberLength/2 + locPosition*(rotPhi + rotPsi);
704 loc[2] = -fFiberLength/2*rotTheta;
705 nav->cd(path);
706 nav->LocalToMaster(loc, glob);
707 A.SetXYZ( glob[0], glob[1],glob[2] );
708 loc[0] = locPosition - fFiberLength/2*(rotPhi + rotPsi);
709 loc[1] = fFiberLength/2 + locPosition*(rotPhi + rotPsi);
710 loc[2] = -fFiberLength/2*rotTheta;
711 nav->LocalToMaster(loc, glob);
712 B.SetXYZ( glob[0], glob[1],glob[2] );
713 }
714}
std::vector< int > covered_runs_position_alignment
Definition Scifi.h:125

◆ InitEvent()

void Scifi::InitEvent ( SNDLHCEventHeader e)

Definition at line 425 of file Scifi.cxx.

425 {
426 // get mapping to eventHeader
427 eventHeader = e;
428
429 // Initialize
430 if (not alignment_init) {
431 alignment_init = true;
432 // Get available tags from the geometry file
433 std::string tag_string;
434
435 // Time alignment tags
436 for (auto key : conf_floats){
437 tag_string = key.first.Data();
438 if (tag_string.find("Scifi/station1t_") != std::string::npos){
439 covered_runs_time_alignment.push_back(stoi(tag_string.substr(tag_string.find("t_")+2)));
440 }
441 }
443 // Position alignment tags
444 for (auto key : conf_floats){
445 tag_string = key.first.Data();
446 if (tag_string.find("Scifi/LocM100t_") != std::string::npos){
447 covered_runs_position_alignment.push_back(stoi(tag_string.substr(tag_string.find("t_")+2)));
448 }
449 }
451 }
452};

◆ Initialize()

void Scifi::Initialize ( )
virtual

Initialization of the detector is done here

Definition at line 92 of file Scifi.cxx.

93{
94 FairDetector::Initialize();
95}

◆ InitMedium()

Int_t Scifi::InitMedium ( const char *  name)
protected

Definition at line 98 of file Scifi.cxx.

99{
100 static FairGeoLoader *geoLoad=FairGeoLoader::Instance();
101 static FairGeoInterface *geoFace=geoLoad->getGeoInterface();
102 static FairGeoMedia *media=geoFace->getMedia();
103 static FairGeoBuilder *geoBuild=geoLoad->getGeoBuilder();
104
105 FairGeoMedium *ShipMedium=media->getMedium(name);
106
107 if (!ShipMedium)
108 {
109 Fatal("InitMedium","Material %s not defined in media file.", name);
110 return -1111;
111 }
112 TGeoMedium* medium=gGeoManager->GetMedium(name);
113 if (medium!=NULL)
114 return ShipMedium->getMediumIndex();
115 return geoBuild->createMedium(ShipMedium);
116}

◆ integralSqrt()

Double_t Scifi::integralSqrt ( Double_t  ynorm)

Definition at line 723 of file Scifi.cxx.

724{
725 Double_t y = 1./2.*(ynorm*TMath::Sqrt(1-ynorm*ynorm)+TMath::ASin(ynorm));
726 return y;
727}

◆ operator=()

Scifi & Scifi::operator= ( const Scifi )

◆ PostTrack()

virtual void Scifi::PostTrack ( )
inlinevirtual

Definition at line 90 of file Scifi.h.

90{;}

◆ PreTrack()

virtual void Scifi::PreTrack ( )
inlinevirtual

Definition at line 91 of file Scifi.h.

91{;}

◆ ProcessHits()

Bool_t Scifi::ProcessHits ( FairVolume *  v = 0)
virtual

this method is called for each step during simulation (see FairMCApplication::Stepping())

This method is called from the MC stepping

Definition at line 454 of file Scifi.cxx.

455{
457 //Set parameters at entrance of volume. Reset ELoss.
458 if ( gMC->IsTrackEntering() )
459 {
460 fELoss = 0.;
461 fTime = gMC->TrackTime() * 1.0e09;
462 fLength = gMC->TrackLength();
463 gMC->TrackPosition(fPos);
464 gMC->TrackMomentum(fMom);
465 TGeoNavigator* nav = gGeoManager->GetCurrentNavigator();
466
467 int fibre_local_id = nav->GetMother()->GetNumber() - 1e6 - 1e4; // Local ID within the mat.
468 int fibre_mat_id = nav->GetMother(2)->GetNumber(); // Get mat ID.
469
470 int fibre_station_number = int( fibre_mat_id / 1e6); // Get the station number from the mat
471
472 int fibre_mat_id_station_removed = fibre_mat_id - fibre_station_number*1e6;
473 int fibre_mat_number = int((fibre_mat_id_station_removed - int(fibre_mat_id_station_removed/1e5)*1e5)/1e4);
474
475 fVolumeID = fibre_local_id + fibre_station_number*1e6 + fibre_mat_number*1e4;
476
477 if (fVolumeID==0){std::cout<<"fiber vol id "<<nav->GetMother()->GetName()<<std::endl;}
478
479 }
480 // Sum energy loss for all steps in the active volume
481 fELoss += gMC->Edep();
482
483 // Create ScifiPoint at exit of active volume
484 if ( gMC->IsTrackExiting() ||
485 gMC->IsTrackStop() ||
486 gMC->IsTrackDisappeared() ) {
487 if (fELoss == 0. ) { return kFALSE; }
488 fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
489/* STMRFFF
490First digit S: station # within the sub-detector
491Second digit T: type of the plane: 0-horizontal fiber plane, 1-vertical fiber plane
492Third digit M: determines the mat number
493Fourth digit R: row number (in Z direction)
494Last three digits F: fiber number
495*/
496 TParticle* p=gMC->GetStack()->GetCurrentTrack();
497 Int_t pdgCode = p->GetPdgCode();
498
499 TLorentzVector Pos;
500 gMC->TrackPosition(Pos);
501 Double_t xmean = (fPos.X()+Pos.X())/2. ;
502 Double_t ymean = (fPos.Y()+Pos.Y())/2. ;
503 Double_t zmean = (fPos.Z()+Pos.Z())/2. ;
504
505 AddHit(fTrackID,fVolumeID, TVector3(xmean, ymean, zmean),
506 TVector3(fMom.Px(), fMom.Py(), fMom.Pz()), fTime, fLength,
507 fELoss, pdgCode);
508
509 // Increment number of det points in TParticle
510 ShipStack* stack = (ShipStack*) gMC->GetStack();
511 stack->AddPoint(kLHCScifi);
512 }
513
514 return kTRUE;
515}
ScifiPoint * AddHit(Int_t trackID, Int_t detID, TVector3 pos, TVector3 mom, Double_t time, Double_t length, Double_t eLoss, Int_t pdgCode)
Definition Scifi.cxx:860

◆ Register()

void Scifi::Register ( )
virtual

Registers the produced collections in FAIRRootManager.

This will create a branch in the output tree called ScifiPoint, setting the last parameter to kFALSE means: this collection will not be written to the file, it will exist only during the simulation.

Definition at line 835 of file Scifi.cxx.

836{
837
844 FairRootManager::Instance()->Register("ScifiPoint", "Scifi",
845 fScifiPointCollection, kTRUE);
846}

◆ Reset()

void Scifi::Reset ( )
virtual

has to be called after each event to reset the containers

Definition at line 854 of file Scifi.cxx.

855{
856 fScifiPointCollection->Clear();
857}

◆ SetConfPar() [1/3]

void Scifi::SetConfPar ( TString  name,
Float_t  value 
)
inline

Definition at line 46 of file Scifi.h.

46{conf_floats[name]=value;}

◆ SetConfPar() [2/3]

void Scifi::SetConfPar ( TString  name,
Int_t  value 
)
inline

Definition at line 47 of file Scifi.h.

47{conf_ints[name]=value;}

◆ SetConfPar() [3/3]

void Scifi::SetConfPar ( TString  name,
TString  value 
)
inline

Definition at line 48 of file Scifi.h.

48{conf_strings[name]=value;}

◆ SetSpecialPhysicsCuts()

virtual void Scifi::SetSpecialPhysicsCuts ( )
inlinevirtual

Definition at line 85 of file Scifi.h.

85{;}

◆ SiPMmapping()

void Scifi::SiPMmapping ( )

Definition at line 758 of file Scifi.cxx.

758 {
759 Float_t fibresRadius = -1;
760 Float_t dSiPM = -1;
761 TGeoNode* vol;
762 TGeoNode* fibre;
763 SiPMOverlap(); // 12 SiPMs per mat, made for horizontal mats, fibres staggered along y-axis.
764 auto sipm = gGeoManager->FindVolumeFast("SiPMmapVol");
765 TObjArray* Nodes = sipm->GetNodes();
766 auto plane = gGeoManager->FindVolumeFast("ScifiHorPlaneVol1");
767 for (int imat = 0; imat < plane->GetNodes()->GetEntriesFast(); imat++){
768 auto mat = static_cast<TGeoNode*>(plane->GetNodes()->At(imat));
769 Float_t t1 = mat->GetMatrix()->GetTranslation()[1];
770 auto vmat = mat->GetVolume();
771 for (int ifibre = 0; ifibre < vmat->GetNodes()->GetEntriesFast(); ifibre++){
772 fibre = static_cast<TGeoNode*>(vmat->GetNodes()->At(ifibre));
773 if (fibresRadius<0){
774 auto tmp = fibre->GetVolume()->GetShape();
775 auto S = dynamic_cast<TGeoBBox*>(tmp);
776 fibresRadius = S->GetDX();
777 }
778 Float_t t2 = fibre->GetMatrix()->GetTranslation()[1];
779 Int_t fID = fibre->GetNumber()%100000 + imat*1e4; // local fibre number, global fibre number = SO+fID
780 Float_t a = t1+t2;
781
782 // check for overlap with any of the SiPM channels in the same mat
783 for(Int_t nChan = 0; nChan< Nodes->GetEntriesFast();nChan++){ // 12 SiPMs total and 4 SiPMs per mat times 128 channels
784 vol = static_cast<TGeoNode*>(Nodes->At(nChan));
785 Int_t N = vol->GetNumber()%100000;
786 if (imat!=int(N/10000)){continue;}
787 Float_t xcentre = vol->GetMatrix()->GetTranslation()[1];
788 if (dSiPM<0){
789 TGeoBBox* B = dynamic_cast<TGeoBBox*>(vol->GetVolume()->GetShape());
790 dSiPM = B->GetDY();
791 }
792 if (TMath::Abs(xcentre-a)>4*fibresRadius){ continue;} // no need to check further
793 Float_t W = area(a,fibresRadius,xcentre-dSiPM,xcentre+dSiPM);
794 if (W<0){ continue;}
795 std::array<float, 2> Wa;
796 Wa[0] = W;
797 Wa[1] = a;
798 fibresSiPM[N][fID] = Wa;
799 }
800 }
801 }
802 // calculate also local SiPM positions based on fibre positions and their fraction
803 // probably an overkill, maximum difference between weighted average and central position < 6 micron.
804 std::map<Int_t,std::map<Int_t,std::array<float, 2>>>::iterator it;
805 std::map<Int_t,std::array<float, 2>>::iterator itx;
806 for (it = fibresSiPM.begin(); it != fibresSiPM.end(); it++)
807 {
808 Int_t N = it->first;
809 Float_t m = 0;
810 Float_t w = 0;
811 for (itx = it->second.begin(); itx != it->second.end(); itx++)
812 {
813 m+=(itx->second)[0]*(itx->second)[1];
814 w+=(itx->second)[0];
815 }
816 SiPMPos[N]=m/w;
817 }
818// make inverse mapping, which fibre is associated to which SiPMs
819 for (it = fibresSiPM.begin(); it != fibresSiPM.end(); it++)
820 {
821 Int_t N = it->first;
822 for (itx = it->second.begin(); itx != it->second.end(); itx++)
823 {
824 Int_t nfibre = itx->first;
825 siPMFibres[nfibre][N]=itx->second;
826 }
827 }
828}
Double_t m
virtual void SiPMOverlap()
Definition Scifi.cxx:382
Double_t area(Double_t a, Double_t R, Double_t xL, Double_t xR)
Definition Scifi.cxx:735
t1
Definition g4Ex.py:302

◆ SiPMOverlap()

void Scifi::SiPMOverlap ( )
virtual

Definition at line 382 of file Scifi.cxx.

383{
384 if (gGeoManager->FindVolumeFast("SiPMmapVol")){return;}
385 Double_t fLengthScifiMat = conf_floats["Scifi/scifimat_length"];
386 Double_t fWidthChannel = conf_floats["Scifi/channel_width"];
387 Double_t fZEpoxyMat = conf_floats["Scifi/epoxymat_z"];
388 Int_t fNSiPMChan = conf_ints["Scifi/nsipm_channels"];
389 Int_t fNSiPMs = conf_ints["Scifi/nsipm_mat"];
390 Int_t fNMats = conf_ints["Scifi/nmats"];
391 Double_t fEdge = conf_floats["Scifi/sipm_edge"];
392 Double_t fCharr = conf_floats["Scifi/charr_width"];
393 Double_t fCharrGap = conf_floats["Scifi/charr_gap"];
394 Double_t fBigGap = conf_floats["Scifi/sipm_diegap"];
395 Double_t firstChannelX = conf_floats["Scifi/firstChannelX"];
396
397 //Contains all plane SiPMs, defined for horizontal fiber plane
398 //To obtain SiPM map for vertical fiber plane rotate by 90 degrees around Z
399 TGeoVolumeAssembly *SiPMmapVol = new TGeoVolumeAssembly("SiPMmapVol");
400
401 TGeoVolume*ChannelVol = gGeoManager->MakeBox("ChannelVol", 0, fLengthScifiMat/2, fWidthChannel/2, fZEpoxyMat/2);
402
403 //DetID for each channel:
404 //first digit: mat number (0-2)
405 //second digit: SiPM number (0-3)
406 //last three digits: channel number (0-127)
407
408 Double_t SiPMArray_fullwidth = fEdge+fCharr+fCharrGap+fCharr+fEdge;
409 TGeoVolumeAssembly *SiPMArrayVol;
410 int N = fNMats == 1 ? 1 : 0;
411 Double_t pos = -fEdge+firstChannelX + N*fLengthScifiMat;
412 for (int imat = 0; imat < fNMats; imat++){
413 for (int isipms = 0; isipms < fNSiPMs; isipms++){
414 pos+= fEdge;
415 for (int ichannel = 0; ichannel < fNSiPMChan; ichannel++){
416 SiPMmapVol->AddNode(ChannelVol, imat*10000+isipms *1000 + ichannel, new TGeoTranslation(0, pos, 0));
417 pos += fWidthChannel;
418 if (ichannel==(fNSiPMChan/2-1)){pos += fCharrGap;}
419 }
420 pos+=fEdge+fBigGap;
421 }
422 }
423}

◆ ycross()

Double_t Scifi::ycross ( Double_t  a,
Double_t  R,
Double_t  x 
)

Definition at line 716 of file Scifi.cxx.

717{
718 Double_t y = -1;
719 Double_t A = R*R - (x-a)*(x-a);
720 if ( !(A<0) ){y = TMath::Sqrt(A);}
721 return y;
722}

Member Data Documentation

◆ alignment_init

bool Scifi::alignment_init

Definition at line 129 of file Scifi.h.

◆ conf_floats

std::map<TString,Float_t> Scifi::conf_floats

configuration parameters

Definition at line 118 of file Scifi.h.

◆ conf_ints

std::map<TString,Int_t> Scifi::conf_ints

Definition at line 119 of file Scifi.h.

◆ conf_strings

std::map<TString,TString> Scifi::conf_strings

Definition at line 120 of file Scifi.h.

◆ covered_runs_position_alignment

std::vector<int> Scifi::covered_runs_position_alignment

Definition at line 125 of file Scifi.h.

◆ covered_runs_time_alignment

std::vector<int> Scifi::covered_runs_time_alignment

Definition at line 124 of file Scifi.h.

◆ eventHeader

SNDLHCEventHeader* Scifi::eventHeader

Definition at line 121 of file Scifi.h.

◆ fELoss

Double32_t Scifi::fELoss

length

Definition at line 111 of file Scifi.h.

◆ fibresSiPM

std::map<Int_t,std::map<Int_t,std::array<float, 2> > > Scifi::fibresSiPM

energy loss

Definition at line 112 of file Scifi.h.

◆ fLength

Double32_t Scifi::fLength

time

Definition at line 110 of file Scifi.h.

◆ fMom

TLorentzVector Scifi::fMom

position at entrance

Definition at line 108 of file Scifi.h.

◆ fPos

TLorentzVector Scifi::fPos

volume id

Definition at line 107 of file Scifi.h.

◆ fScifiPointCollection

TClonesArray* Scifi::fScifiPointCollection

local SiPM channel position

container for data points

Definition at line 116 of file Scifi.h.

◆ fTime

Double32_t Scifi::fTime

momentum at entrance

Definition at line 109 of file Scifi.h.

◆ fVolumeID

ClassDef (Scifi,3) private Int_t Scifi::fVolumeID

track index

Track information to be stored until the track leaves the active volume.

Definition at line 106 of file Scifi.h.

◆ last_position_alignment_tag

TString Scifi::last_position_alignment_tag

Definition at line 128 of file Scifi.h.

◆ last_run_pos

int Scifi::last_run_pos

Definition at line 126 of file Scifi.h.

◆ last_run_time

int Scifi::last_run_time

Definition at line 126 of file Scifi.h.

◆ last_time_alignment_tag

TString Scifi::last_time_alignment_tag

Definition at line 127 of file Scifi.h.

◆ siPMFibres

std::map<Int_t,std::map<Int_t,std::array<float, 2> > > Scifi::siPMFibres

mapping of fibres to SiPM channels

Definition at line 113 of file Scifi.h.

◆ SiPMPos

std::map<Int_t,float> Scifi::SiPMPos

inverse mapping

Definition at line 114 of file Scifi.h.


The documentation for this class was generated from the following files: