SND@LHC Software
Loading...
Searching...
No Matches
EmulsionDet.cxx
Go to the documentation of this file.
1//
2// EmulsionDet.cxx
3//
4//
5//
6//
7
8#include "EmulsionDet.h"
9
10#include "EmulsionDetPoint.h"
11
12#include "TGeoManager.h"
13#include "FairRun.h" // for FairRun
14#include "FairRuntimeDb.h" // for FairRuntimeDb
15#include "TList.h" // for TListIter, TList (ptr only)
16#include "TObjArray.h" // for TObjArray
17#include "TString.h" // for TString
18
19#include "TClonesArray.h"
20#include "TVirtualMC.h"
21
22#include "TGeoBBox.h"
23#include "TGeoMaterial.h"
24#include "TGeoMedium.h"
25
26#include "TParticle.h"
27#include "TParticlePDG.h"
28#include "TParticleClassPDG.h"
29#include "TVirtualMCStack.h"
30#include "TGeoCompositeShape.h"
31
32#include "FairVolume.h"
33#include "FairGeoVolume.h"
34#include "FairGeoNode.h"
35#include "FairRootManager.h"
36#include "FairGeoLoader.h"
37#include "FairGeoInterface.h"
38#include "FairGeoTransform.h"
39#include "FairGeoMedia.h"
40#include "FairGeoMedium.h"
41#include "FairGeoBuilder.h"
42#include "FairRun.h"
43#include "FairRuntimeDb.h"
44
45#include "FairLogger.h"
46
47#include "ShipDetectorList.h"
48#include "ShipUnit.h"
49#include "ShipStack.h"
50
51#include "TGeoUniformMagField.h"
52#include <stddef.h> // for NULL
53#include <iostream> // for operator<<, basic_ostream,etc
54#include <string.h>
55
56using std::cout;
57using std::endl;
58
59using namespace ShipUnit;
60
62: FairDetector("EmulsionDet", "",kTRUE),
63fTrackID(-1),
64fVolumeID(-1),
65fPos(),
66fMom(),
67fTime(-1.),
68fLength(-1.),
69fELoss(-1),
70fEmulsionDetPointCollection(new TClonesArray("EmulsionDetPoint"))
71{
72}
73
74EmulsionDet::EmulsionDet(const char* name, Bool_t Active,const char* Title)
75: FairDetector(name, true, kEmulsionDet),
76fTrackID(-1),
77fVolumeID(-1),
78fPos(),
79fMom(),
80fTime(-1.),
81fLength(-1.),
82fELoss(-1),
83fEmulsionDetPointCollection(new TClonesArray("EmulsionDetPoint"))
84{
85}
86
94
96{
97 FairDetector::Initialize();
98}
99
100// ----- Private method InitMedium
101Int_t EmulsionDet::InitMedium(const char* name)
102{
103 static FairGeoLoader *geoLoad=FairGeoLoader::Instance();
104 static FairGeoInterface *geoFace=geoLoad->getGeoInterface();
105 static FairGeoMedia *media=geoFace->getMedia();
106 static FairGeoBuilder *geoBuild=geoLoad->getGeoBuilder();
107
108 FairGeoMedium *ShipMedium=media->getMedium(name);
109
110 if (!ShipMedium)
111 {
112 Fatal("InitMedium","Material %s not defined in media file.", name);
113 return -1111;
114 }
115 TGeoMedium* medium=gGeoManager->GetMedium(name);
116 if (medium!=NULL)
117 return ShipMedium->getMediumIndex();
118 return geoBuild->createMedium(ShipMedium);
119}
120
121void EmulsionDet::DecodeBrickID(Int_t detID, Int_t &NWall, Int_t &NRow, Int_t &NColumn, Int_t &NPlate){
122
123 NWall = detID/1E4;
124 Int_t NTransverse = (detID - NWall*1E4)/1E3;
125 switch (NTransverse){
126 case (1):
127 NColumn = 1;
128 NRow = 2;
129 break;
130
131 case (2):
132 NColumn = 1;
133 NRow = 1;
134 break;
135
136 case (3):
137 NColumn = 2;
138 NRow = 2;
139 break;
140
141 case (4):
142 NColumn = 2;
143 NRow = 1;
144 break;
145 }
146
147 NPlate = detID - NWall*1E4 - NTransverse*1E3;
148
149
150}
151
152TString EmulsionDet::PathBrickID(Int_t detID){
153 //provide path to the node, from the detectorID
154 Int_t NWall, NRow, NColumn, NPlate;
155 DecodeBrickID(detID, NWall, NRow, NColumn, NPlate);
156
157 TString emulsionpath = TString::Format("/cave_1/Detector_0/volTarget_1/Wall_%i/Row_%i/Brick_%i/Emulsion_%i",NWall-1,NRow-1,NColumn-1,NPlate -1);
158
159 return emulsionpath;
160}
161
163{
164 // configuration parameters
165 XDimension = conf_floats["EmulsionDet/xdim"];
166 YDimension = conf_floats["EmulsionDet/ydim"];
167 ZDimension = conf_floats["EmulsionDet/zdim"];
168 fNCol = conf_ints["EmulsionDet/col"];
169 fNRow = conf_ints["EmulsionDet/row"];
170 fNWall = conf_ints["EmulsionDet/wall"];
171 fNTarget = conf_ints["EmulsionDet/target"];
172 WallXDim = conf_floats["EmulsionDet/WallXDim"];
173 WallYDim = conf_floats["EmulsionDet/WallYDim"];
174 WallZDim = conf_floats["EmulsionDet/WallZDim"];
175 TotalWallZDim = conf_floats["EmulsionDet/TotalWallZDim"];
176 WallZBorder_offset = conf_floats["EmulsionDet/WallZBorder_offset"];
177 EmulsionThickness = conf_floats["EmulsionDet/EmTh"];
178 EmulsionX = conf_floats["EmulsionDet/EmX"];
179 EmulsionY = conf_floats["EmulsionDet/EmY"];
180 PlasticBaseThickness = conf_floats["EmulsionDet/PBTh"];
181 EmPlateWidth = conf_floats["EmulsionDet/EPlW"];
182 PassiveThickness = conf_floats["EmulsionDet/PassiveTh"];
183 AllPlateWidth = conf_floats["EmulsionDet/AllPW"];
184 fPassiveOption = conf_ints["EmulsionDet/PassiveOption"];
185 BrickPackageX = conf_floats["EmulsionDet/BrPackX"];
186 BrickPackageY = conf_floats["EmulsionDet/BrPackY"];
187 BrickPackageZ = conf_floats["EmulsionDet/BrPackZ"];
188 BrickX = conf_floats["EmulsionDet/BrX"];
189 BrickY = conf_floats["EmulsionDet/BrY"];
190 BrickZ = conf_floats["EmulsionDet/BrZ"];
191 number_of_plates = conf_ints["EmulsionDet/n_plates"];
192 TTrackerZ = conf_floats["EmulsionDet/TTz"];
193 ShiftX = conf_floats["EmulsionDet/ShiftX"];
194 ShiftY = conf_floats["EmulsionDet/ShiftY"];
195
196 TGeoVolume *top=gGeoManager->FindVolumeFast("Detector");
197 if(!top) LOG(ERROR) << "no Detector volume found " ;
198 gGeoManager->SetVisLevel(10);
199
200 LOG(INFO) << " X: "<< XDimension<< " "<< YDimension<<" Z: "<<ZDimension;
201 LOG(INFO) <<" BrickX: "<< BrickX<<" Y: "<< BrickY<< " Z: "<< BrickZ;
202 //Materials
203 InitMedium("vacuum");
204 TGeoMedium *vacuum =gGeoManager->GetMedium("vacuum");
205
206 InitMedium("air");
207 TGeoMedium *air =gGeoManager->GetMedium("air");
208
209 InitMedium("Aluminum");
210 TGeoMedium *Al = gGeoManager->GetMedium("Aluminum");
211
212 InitMedium("PlasticBase");
213 TGeoMedium *PBase =gGeoManager->GetMedium("PlasticBase");
214
215 InitMedium("NuclearEmulsion");
216 TGeoMedium *NEmu =gGeoManager->GetMedium("NuclearEmulsion");
217
218 TGeoMaterial *NEmuMat = NEmu->GetMaterial(); //I need the materials to build the mixture
219 TGeoMaterial *PBaseMat = PBase->GetMaterial();
220
221 TGeoMixture * emufilmmixture = new TGeoMixture("EmulsionFilmMixture", 2.00); // two nuclear emulsions separated by the plastic base
222 Double_t frac_emu = NEmuMat->GetDensity() * 2 * EmulsionThickness /(NEmuMat->GetDensity() * 2 * EmulsionThickness + PBaseMat->GetDensity() * PlasticBaseThickness);
223
224 emufilmmixture->AddElement(NEmuMat,frac_emu);
225 emufilmmixture->AddElement(PBaseMat,1. - frac_emu);
226
227 TGeoMedium *Emufilm = new TGeoMedium("EmulsionFilm",100,emufilmmixture);
228
229 InitMedium("tungstensifon");
230 TGeoMedium *tungsten = gGeoManager->GetMedium("tungstensifon");
231
232
233 Int_t NPlates = number_of_plates; //Number of doublets emulsion + Pb
234
235
236 //TGeoVolume *top = gGeoManager->MakeBox("Top",vacuum,10.,10.,10.);
237 //gGeoManager->SetTopVolume(top);
238
239 //Definition of the target box containing emulsion bricks + target trackers (TT)
240 TGeoVolumeAssembly *volTarget = new TGeoVolumeAssembly("volTarget");
241
242 //
243 // //Volumes definition
244 // //
245
246
247 TGeoBBox *Walltot = new TGeoBBox("walltot",XDimension/2, YDimension/2, TotalWallZDim/2);
248 TGeoBBox *Wallint = new TGeoBBox("wallint",WallXDim/2, WallYDim/2, WallZDim/2);
249
250 TGeoTranslation * Wallborderpos = new TGeoTranslation("Walborderpos",0,0,WallZBorder_offset);
251 Wallborderpos->RegisterYourself();
252
253 TGeoCompositeShape *Wallborder = new TGeoCompositeShape("wallborder","walltot - (wallint:Walborderpos)");
254 TGeoVolume *volWallborder = new TGeoVolume("volWallborder", Wallborder, Al);
255 volWallborder->SetLineColor(kGray);
256
257 TGeoVolume *volWall = new TGeoVolume("Wall",Wallint,air);
258
259 //Rows
260 TGeoBBox *Row = new TGeoBBox("row",WallXDim/2, BrickY/2, BrickZ/2);
261 TGeoVolume *volRow = new TGeoVolume("Row",Row,air);
262
263 //Bricks
264 TGeoBBox *Brick = new TGeoBBox("brick", BrickX/2, BrickY/2, BrickZ/2);
265 TGeoVolume *volBrick = new TGeoVolume("Brick",Brick,air);
266 volBrick->SetLineColor(kCyan);
267 volBrick->SetTransparency(1);
268
269 TGeoBBox *Passive = new TGeoBBox("Passive", EmulsionX/2, EmulsionY/2, PassiveThickness/2);
270 TGeoVolume *volPassive = new TGeoVolume("volPassive",Passive,tungsten);
271 volPassive->SetTransparency(1);
272 volPassive->SetLineColor(kGray);
273
274 for(Int_t n=0; n<NPlates; n++)
275 {
276 volBrick->AddNode(volPassive, n, new TGeoTranslation(0,0,-BrickZ/2+ EmPlateWidth + PassiveThickness/2 + n*AllPlateWidth)); //LEAD
277 }
278
279 TGeoBBox *EmulsionFilm = new TGeoBBox("EmulsionFilm", EmulsionX/2, EmulsionY/2, EmPlateWidth/2);
280 TGeoVolume *volEmulsionFilm = new TGeoVolume("Emulsion",EmulsionFilm,Emufilm); //TOP
281 volEmulsionFilm->SetLineColor(kBlue);
282 LOG(INFO) << "EmulsionDet : Passive option (0: all active, 1: all passive) set to " << fPassiveOption ;
283 if (fPassiveOption == 0) AddSensitiveVolume(volEmulsionFilm);
284 for(Int_t n=0; n<NPlates+1; n++)
285 {
286 volBrick->AddNode(volEmulsionFilm, n, new TGeoTranslation(0,0,-BrickZ/2+ EmPlateWidth/2 + n*AllPlateWidth));
287 }
288
289 volBrick->SetVisibility(kTRUE);
290
291//alignment
292 double dx_survey[5] = {conf_floats["EmulsionDet/Xpos0"],conf_floats["EmulsionDet/Xpos1"],conf_floats["EmulsionDet/Xpos2"],conf_floats["EmulsionDet/Xpos3"],conf_floats["EmulsionDet/Xpos4"]};
293 double dy_survey[5] = {conf_floats["EmulsionDet/Ypos0"],conf_floats["EmulsionDet/Ypos1"],conf_floats["EmulsionDet/Ypos2"],conf_floats["EmulsionDet/Ypos3"],conf_floats["EmulsionDet/Ypos4"]};
294 double dz_survey[5] = {conf_floats["EmulsionDet/Zpos0"],conf_floats["EmulsionDet/Zpos1"],conf_floats["EmulsionDet/Zpos2"],conf_floats["EmulsionDet/Zpos3"],conf_floats["EmulsionDet/Zpos4"]};
295
296 top->AddNode(volTarget,1,new TGeoTranslation(0,0,0));
297
298 //adding walls
299
300 Double_t d_cl_z = - ZDimension/2;
301
302 for(int l = 0; l < fNWall; l++)
303 {
304 volTarget->AddNode(volWallborder,l,new TGeoTranslation(-dx_survey[l]-XDimension/2., dz_survey[l]+YDimension/2., dy_survey[l]+TotalWallZDim/2.)); //the survey points refer to the down-left corner
305 volTarget->AddNode(volWall,l,new TGeoTranslation(-dx_survey[l]-XDimension/2., dz_survey[l]+YDimension/2., dy_survey[l]+TotalWallZDim/2.+WallZBorder_offset)); //the survey points refer to the down-left corner
306 d_cl_z += BrickZ + TTrackerZ;
307 }
308
309 //adding rows
310 Double_t d_cl_y = -WallYDim/2;
311
312 for(int k= 0; k< fNRow; k++)
313 {
314 volWall->AddNode(volRow,k,new TGeoTranslation(0, d_cl_y + BrickY/2,0));
315
316 // 2mm is the distance for the structure that holds the brick
317 d_cl_y += BrickY;
318 }
319
320 //adding columns of bricks
321 Double_t d_cl_x = -WallXDim/2;
322 for(int j= 0; j < fNCol; j++)
323 {
324 volRow->AddNode(volBrick,j,new TGeoTranslation(d_cl_x+BrickX/2, 0, 0));
325 d_cl_x += BrickX;
326 }
327}
328
329
330
331
332
333Bool_t EmulsionDet::ProcessHits(FairVolume* vol)
334{
336 //Set parameters at entrance of volume. Reset ELoss.
337 if ( gMC->IsTrackEntering() ) {
338 fELoss = 0.;
339 fTime = gMC->TrackTime() * 1.0e09;
340 fLength = gMC->TrackLength();
341 gMC->TrackPosition(fPos);
342 gMC->TrackMomentum(fMom);
343 }
344 // Sum energy loss for all steps in the active volume
345 fELoss += gMC->Edep();
346
347 // Create EmulsionDetPoint at exit of active volume
348 if ( gMC->IsTrackExiting() ||
349 gMC->IsTrackStop() ||
350 gMC->IsTrackDisappeared() ) {
351 fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
352 gMC->CurrentVolID(fVolumeID);
353
354 //finding number of wall, row and column
355 Int_t detID = fVolumeID;
356 Int_t MaxLevel = gGeoManager->GetLevel();
357 const Int_t MaxL = MaxLevel;
358 //cout << "MaxLevel = " << MaxL << endl;
359 //cout << gMC->CurrentVolPath()<< endl;
360
361
362 Int_t motherV[MaxL];
363 Int_t NPlate =0;
364 const char *name;
365
366 name = gMC->CurrentVolName();
367 //cout << name << endl;
368 NPlate = detID;
369
370 Int_t NWall = -2, NColumn =-2, NRow =-2;
371
372 for(Int_t i = 0; i <= MaxL;i++)
373 {
374 gMC->CurrentVolOffID(i, motherV[i]);
375 const char *mumname = gMC->CurrentVolOffName(i);
376
377 if(strcmp(mumname, "Brick") == 0) NColumn = (1-motherV[i]); //0 or 1 (0 higher x, 1 lower x, x are negative, so higher x are closer to the beam)
378 if(strcmp(mumname, "Row") == 0) NRow = motherV[i]; // 0 or 1 (0 lower y, 1 higher y)
379 if(strcmp(mumname, "Wall") == 0) NWall = motherV[i]; //0,1,2,3 (increasing along the beam verse)
380
381 }
382
383 detID = (NWall+1)*1E4+(NRow*2+NColumn+1)*1E3+(NPlate+1);
384 fVolumeID = detID;
385 //found number of row, column and wall
386 //if (NColumn > 2 || NRow > 2 || NWall > 5) cout<<"Debug test for detID "<<detID<<" is "<<NColumn<<" "<<NRow<<" "<<NWall<<" "<<NPlate<<endl;
387 TParticle* p=gMC->GetStack()->GetCurrentTrack();
388 Int_t pdgCode = p->GetPdgCode();
389 if (pdgCode == 22) { return kFALSE; } //discard only photons
390
391 TLorentzVector Pos;
392 gMC->TrackPosition(Pos);
393 Double_t xmean = (fPos.X()+Pos.X())/2. ;
394 Double_t ymean = (fPos.Y()+Pos.Y())/2. ;
395 Double_t zmean = (fPos.Z()+Pos.Z())/2. ;
396
397 TLorentzVector Mom;
398 gMC->TrackMomentum(Mom);
399 AddHit(fTrackID, fVolumeID, TVector3(xmean, ymean, zmean),
400 TVector3(fMom.Px(), fMom.Py(), fMom.Pz()), fTime, fLength,
401 fELoss,pdgCode,TVector3(Pos.X(), Pos.Y(), Pos.Z()),TVector3(Mom.Px(), Mom.Py(), Mom.Pz()) );
402
403 // Increment number of muon det points in TParticle
404 ShipStack* stack = (ShipStack*) gMC->GetStack();
405 stack->AddPoint(kEmulsionDet);
406 }
407
408 return kTRUE;
409}
410
411
412
417
418
420{
421
428 FairRootManager::Instance()->Register("EmulsionDetPoint", "EmulsionDet",
430}
431
432TClonesArray* EmulsionDet::GetCollection(Int_t iColl) const
433{
434 if (iColl == 0) { return fEmulsionDetPointCollection; }
435 else { return NULL; }
436}
437
439{
441}
442
443
444EmulsionDetPoint* EmulsionDet::AddHit(Int_t trackID,Int_t detID,
445 TVector3 pos, TVector3 mom,
446 Double_t time, Double_t length,
447 Double_t eLoss, Int_t pdgCode,TVector3 Lpos, TVector3 Lmom)
448{
449 TClonesArray& clref = *fEmulsionDetPointCollection;
450 Int_t size = clref.GetEntriesFast();
451 return new(clref[size]) EmulsionDetPoint(trackID,detID, pos, mom,
452 time, length, eLoss, pdgCode,Lpos,Lmom);
453}
@ kEmulsionDet
Double_t PassiveThickness
virtual void EndOfEvent()
Double_t BrickPackageZ
Int_t fPassiveOption
Double_t BrickPackageY
Double_t WallZBorder_offset
Double_t AllPlateWidth
virtual Bool_t ProcessHits(FairVolume *v=0)
Double_t TotalWallZDim
Double_t WallYDim
Double_t ShiftY
Double_t PlasticBaseThickness
virtual TClonesArray * GetCollection(Int_t iColl) const
Double_t TTrackerZ
Int_t InitMedium(const char *name)
Double_t WallXDim
virtual void Reset()
Double_t EmPlateWidth
Double32_t fLength
time
Definition EmulsionDet.h:87
TClonesArray * fEmulsionDetPointCollection
energy loss
Definition EmulsionDet.h:91
void DecodeBrickID(Int_t detID, Int_t &NWall, Int_t &NRow, Int_t &NColumn, Int_t &NPlate)
virtual ~EmulsionDet()
Double_t BrickY
EmulsionDetPoint * AddHit(Int_t trackID, Int_t detID, TVector3 pos, TVector3 mom, Double_t time, Double_t length, Double_t eLoss, Int_t pdgcode, TVector3 Lpos, TVector3 Lmom)
Double_t ZDimension
ClassDef(EmulsionDet, 5) private Int_t fVolumeID
track index
Definition EmulsionDet.h:77
Double_t BrickPackageX
Double_t EmulsionThickness
void ConstructGeometry()
Double_t ShiftX
std::map< TString, Float_t > conf_floats
Definition EmulsionDet.h:93
TLorentzVector fPos
volume id
Definition EmulsionDet.h:84
Double_t XDimension
Definition EmulsionDet.h:99
Double_t BrickX
Double_t WallZDim
Double32_t fTime
momentum at entrance
Definition EmulsionDet.h:86
virtual void Register()
std::map< TString, Int_t > conf_ints
Definition EmulsionDet.h:94
Int_t number_of_plates
TString PathBrickID(Int_t detID)
TLorentzVector fMom
position at entrance
Definition EmulsionDet.h:85
Double_t YDimension
virtual void Initialize()
Double32_t fELoss
length
Definition EmulsionDet.h:88
Double_t BrickZ
Double_t EmulsionY
Double_t EmulsionX
ClassImp(ecalContFact) ecalContFact