FairRoot/PandaRoot
PndDsk.cxx
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // ----- PndDsk source file -----
3 // ----- Created 23/10/07 by P. Koch -----
4 // ----------------------------------------------------------------------------
5 
6 #include <iostream>
7 #include <math.h>
8 using std::endl;
9 using std::cout;
10 
11 #include "TClonesArray.h"
12 #include "TLorentzVector.h"
13 #include "TParticle.h"
14 #include "TVector3.h"
15 #include "TVirtualMC.h"
16 #include "TFile.h"
17 
18 #include "TGeoCone.h"
19 #include "TGeoManager.h"
20 #include "TLorentzVector.h"
21 #include "TParticle.h"
22 #include "TVirtualMC.h"
23 #include "TGeoPgon.h"
24 #include "TGeoSphere.h"
25 #include "TGeoBBox.h"
26 #include "TGeoCompositeShape.h"
27 #include "TGeoMatrix.h"
28 #include "TObject.h"
29 
30 #include "FairRootManager.h"
31 #include "FairRun.h"
32 #include "FairRuntimeDb.h"
33 #include "FairVolume.h"
34 
35 #include "FairGeoInterface.h"
36 #include "FairGeoLoader.h"
37 #include "FairGeoNode.h"
38 #include "FairRootManager.h"
39 #include "FairGeoMedia.h"
40 #include "FairGeoMedium.h"
41 #include "FairGeoRootBuilder.h"
42 
43 #include "PndDetectorList.h"
44 #include "PndStack.h"
45 
46 #include "PndDsk.h"
47 #include "PndDskCerenkov.h"
48 #include "PndDskParticle.h"
49 #include "PndDskTrackPoint.h"
50 
51 
52 
53 
54 // ----- Default constructor ----------------------------------------------
56  : fDebugLevel(0),
57  fStoreCerenkovs(kTRUE),
58  fStoreParticles(kTRUE),
59  fStoreTrackPoints(kFALSE),
60  fStoreFLGHits(kFALSE),
61  fCalcPWay(kFALSE),
62  fMeasureTotalRefAngle(kFALSE),
63  fPDE(1.)
64 {
65  fDskCerenkovCollection = new TClonesArray("PndDskCerenkov");
66  fDskParticleCollection = new TClonesArray("PndDskParticle");
67  fDskTrackPointCollection = new TClonesArray("PndDskTrackPoint");
68  fDskFLGHitArray = new TClonesArray("PndDskFLGHit");
69  fGeo = new PndGeoDskFLG();
70 }
71 // ----------------------------------------------------------------------------
72 
73 
74 
75 // ----- Standard constructor ---------------------------------------------
76 PndDsk::PndDsk(const char* name, Bool_t active)
77  : FairDetector(name, active),
78  fDebugLevel(0),
79  fStoreCerenkovs(kTRUE),
80  fStoreParticles(kTRUE),
81  fStoreTrackPoints(kFALSE),
82  fStoreFLGHits(kFALSE),
83  fCalcPWay(kFALSE),
84  fMeasureTotalRefAngle(kFALSE),
85  fPDE(1.)
86 {
87  fDskCerenkovCollection = new TClonesArray("PndDskCerenkov");
88  fDskParticleCollection = new TClonesArray("PndDskParticle");
89  fDskTrackPointCollection = new TClonesArray("PndDskTrackPoint");
90  fDskFLGHitArray = new TClonesArray("PndDskFLGHit");
91  fGeo = new PndGeoDskFLG();
92 }
93 // ----------------------------------------------------------------------------
94 
95 
96 
97 // ----- Destructor -------------------------------------------------------
99 {
100  if (0 != fDskCerenkovCollection) {
101  fDskCerenkovCollection->Delete();
102  delete fDskCerenkovCollection;
103  }
104  if (0 != fDskParticleCollection) {
105  fDskParticleCollection->Delete();
106  delete fDskParticleCollection;
107  }
108  if (0 != fDskTrackPointCollection) {
109  fDskTrackPointCollection->Delete();
111  }
112  if (0 != fDskFLGHitArray) {
113  fDskFLGHitArray->Delete();
114  delete fDskFLGHitArray;
115  }
116 
117  if (fGeo) delete fGeo;
118 
119 }
120 // ----------------------------------------------------------------------------
121 
122 
123 
124 // ----- Public method Intialize ------------------------------------------
125 void
127 {
129  //FairRun *sim = FairRun::Instance(); //[R.K. 01/2017] unused variable?
130  //FairRuntimeDb *rtdb = sim->GetRuntimeDb(); //[R.K. 01/2017] unused variable?
131  SetTrapFraction("$VMCWORKDIR/input/trapfrac_disc.root");
132 }
133 
134 void
136 {
137  TFile *f=new TFile(name.c_str());
138 
139  for (int i=0;i<5;i++)
140  {
141  trapfrac[i]=0;
142  }
143 
144  if (f->IsZombie())
145  {
146  cout <<" -W- (PndDsk::Initialize) - trapfrac_disc file "
147  <<" doesn't exist. Using constant trapping fraction _trap="<< 0.7<<endl;
148  }
149  else
150  {
151  trapfrac[0]=(TH2F*)f->Get("hacc0");
152  trapfrac[1]=(TH2F*)f->Get("hacc1");
153  trapfrac[2]=(TH2F*)f->Get("hacc2");
154  trapfrac[3]=(TH2F*)f->Get("hacc3");
155  trapfrac[4]=(TH2F*)f->Get("hacc4");
156 
157  for (int i=0;i<5;i++) trapfrac[i]->SetDirectory(0);
158 
159  f->Close();
160  }
161  delete f;
162 }
163 // ----------------------------------------------------------------------------
164 
165 
166 
167 // ----- Public method ProcessHits -----------------------------------------
168 Bool_t
169 PndDsk::ProcessHits(FairVolume* vol)
170 {
171  fPdgCode = gMC->TrackPid();
172  if (fPdgCode == 50000050 ) {
173  return ProcessHitsCerenkov_FLG(vol);
174  } else {
175 
176  return ProcessHitsParticle(vol);
177  }
178 }
179 // ----------------------------------------------------------------------------
180 
181 
182 
183 // ----- Public method EndOfEvent -----------------------------------------
184 void
186 {
187  Reset();
188 }
189 // ----------------------------------------------------------------------------
190 
191 
192 
193 // ----- Public method Register -------------------------------------------
194 void
196 {
197  FairRootManager::Instance()->Register("DskCerenkov", "Dsk", fDskCerenkovCollection, fStoreCerenkovs);
198  FairRootManager::Instance()->Register("DskParticle", "Dsk", fDskParticleCollection, fStoreParticles);
199  FairRootManager::Instance()->Register("DskTrackPoints","Dsk", fDskTrackPointCollection, fStoreTrackPoints);
200  FairRootManager::Instance()->Register("DskFLGHit", "Dsk", fDskFLGHitArray, fStoreFLGHits);
201 }
202 // ----------------------------------------------------------------------------
203 
204 
205 
206 // ----- Public method GetCollection --------------------------------------
207 TClonesArray*
208 PndDsk::GetCollection(Int_t iColl) const
209 {
210  if (iColl == 0) return fDskCerenkovCollection;
211  if (iColl == 1) return fDskParticleCollection;
212  if (iColl == 2) return fDskTrackPointCollection;
213  if (iColl == 3) return fDskFLGHitArray;
214  return NULL;
215 }
216 // ----------------------------------------------------------------------------
217 
218 
219 
220 // ----- Public method Print ----------------------------------------------
221 void
223 {
224  cout << "-I- PndDsk::Print() was called, but is not yet implemented." << endl;
225 }
226 // ----------------------------------------------------------------------------
227 
228 
229 
230 // ----- Public method Reset ----------------------------------------------
231 void
233 {
234  fDskCerenkovCollection->Clear();
235  fDskParticleCollection->Clear();
236  fDskTrackPointCollection->Clear();
237  fDskFLGHitArray->Clear();
238 }
239 // ----------------------------------------------------------------------------
240 
241 
242 
243 // ----- Public method CopyClones -----------------------------------------
244 void
245 PndDsk::CopyClones(TClonesArray* , TClonesArray* , Int_t ) // cl1 cl2 offset //[R.K.03/2017] unused variable(s)
246 {
247  cout << "-I- PndDsk::CopyClones() was called, but is not yet implemented." << endl;
248 }
249 // ----------------------------------------------------------------------------
250 
251 
252 
253 // ----- Public method ConstructGeometry ----------------------------------
254 void
256 {
257  TString fileName = GetGeometryFileName();
258  if (fileName.EndsWith("_top.root")) {
259  ConstructRootGeometry();
260 // } else if (fileName.EndsWith(".geo")) {
261 // ConstructASCIIGeometry();
262  } else { //FLG Version
263 
264  FairGeoLoader* drcgeoLoad = FairGeoLoader::Instance();
265  FairGeoInterface* drcgeoFace = drcgeoLoad->getGeoInterface();
266 
267  FairGeoMedia *Media = drcgeoFace->getMedia();
268  FairGeoBuilder *geobuild = drcgeoLoad->getGeoBuilder();
269 
270  // Call materials
271  FairGeoMedium *fusedSil = Media->getMedium("FusedSil");
272  geobuild->createMedium(fusedSil);
273  FairGeoMedium *nlak33a = Media->getMedium("NLAK33A");
274  geobuild->createMedium(nlak33a);
275  FairGeoMedium *air = Media->getMedium("DIRCair");
276  geobuild->createMedium(air);
277  FairGeoMedium *airNoSens = Media->getMedium("DIRCairNoSens");
278  geobuild->createMedium(airNoSens);
279  FairGeoMedium *mirror = Media->getMedium("Mirror");
280  geobuild->createMedium(mirror);
281  FairGeoMedium *marcol82 = Media->getMedium("Marcol82");
282  geobuild->createMedium(marcol82);
283 
284  TGeoVolume *cave = gGeoManager->GetTopVolume();
285 
286 
287  double rmax = fGeo->radius() / 10.; //maximum radius cm
288  double rmin = 0; //minimum radius cm
289  double thickness = fGeo->thickness() / 10.; // thickness of plate cm
290  double z_position = fGeo->postion_plate() / 10.; //position of plate cm
291 
292  // window
293  Double_t const fWindowHeightHalf = z_position * TMath::Tan( 5.*TMath::DegToRad()); // ~17.15 cm
294  Double_t const fWindowWidthHalf = z_position * TMath::Tan(10.*TMath::DegToRad()); // ~34.56 cm
295 
296  new TGeoBBox("DW",fWindowWidthHalf,fWindowHeightHalf,thickness);
297 
298 
299  TGeoCone* baseVol = new TGeoCone("baseVol",thickness+0.1, rmin, rmax+0.1, rmin, rmax+0.1);
300  new TGeoCone("logicPlate", thickness, rmin, rmax, rmin, rmax);
301  TGeoCompositeShape* logicPlate_DW = new TGeoCompositeShape("logicPlate - DW");
302 
303  TGeoVolume *dskVol = new TGeoVolume("DskBase", baseVol, gGeoManager->GetMedium("DIRCairNoSens"));
304  TGeoVolume *plateVol = new TGeoVolume("Plate", logicPlate_DW, gGeoManager->GetMedium("FusedSil"));
305 
306  cave->AddNode(dskVol, 1, new TGeoCombiTrans(0, 0, z_position, new TGeoRotation(0)));
307  dskVol->AddNode(plateVol, 1, new TGeoCombiTrans(0, 0, 0, new TGeoRotation(0)));
308  AddSensitiveVolume(plateVol);
309 
310 
311  }
312 }
313 // ----------------------------------------------------------------------------
314 
315 
316 
317 // ----- Public method CheckIfSensitive -----------------------------------
318 Bool_t
319 PndDsk::CheckIfSensitive(std::string ) // name //[R.K.03/2017] unused variable(s)
320 {
321  return kTRUE;
322 // if (name.compare("radiator") == 0) { // "radiator"
323 // return kTRUE;
324 // }
325 // if (name.find("mcp") == 0) { // "mcp*"
326 // return kTRUE;
327 // }
328 // if (name.find("mirror") == 0) { // "mirror*"
329 // return kTRUE;
330 // }
331 }
332 // ----------------------------------------------------------------------------
333 
334 
335 // ----- Add Hit to HitCollection --------------------------------------
337 PndDsk::AddHit(Int_t trackID, Int_t detectorID,
338  TVector3 position_store, TVector3 momentum_store, Double_t time,
339  Double_t angIn, Double_t thetaC_store,
340  TVector3 Cherenkov_photon, Int_t light_guide, Int_t pixel)
341  {
342  TClonesArray& clref = *fDskFLGHitArray;
343  Int_t size = clref.GetEntriesFast();
344  return new(clref[size]) PndDskFLGHit( trackID,detectorID,position_store,momentum_store,time,
345  angIn,thetaC_store,Cherenkov_photon,light_guide,pixel);
346 }
347 
348 
349 
350 // ----- Public method AddCerenkov ----------------------------------------
352 PndDsk::AddCerenkov(Int_t trackID, Int_t detectorID, TVector3 position,
353  TVector3 momentum, Double_t time, Double_t energy, Double_t wavelength,
354  Int_t motherTrackID, Int_t motherPdgCode, TString motherPdgName)
355 {
356  TClonesArray& clRef = *fDskCerenkovCollection;
357  Int_t size = clRef.GetEntriesFast();
358 
359  return new(clRef[size]) PndDskCerenkov(trackID, detectorID,
360  position, momentum, time, energy, wavelength,
361  motherTrackID, motherPdgCode, motherPdgName);
362 }
363 // ----------------------------------------------------------------------------
364 
365 
366 
367 // ----- Public method AddParticle ----------------------------------------
369 PndDsk::AddParticle(Int_t trackID, Int_t detectorID,
370  TVector3 position, TVector3 momentum, Double_t time,
371  Int_t pdgCode, TString pdgName, Double_t energy,
372  Int_t motherTrackID, Int_t motherPdgCode, TString motherPdgName, Double_t mass,
373  Double_t angIn, Double_t thetaC, Int_t nPhot)
374 {
375  TClonesArray& clRef = *fDskParticleCollection;
376  Int_t size = clRef.GetEntriesFast();
377 
378  return new(clRef[size]) PndDskParticle(trackID, detectorID,
379  position, momentum, time, pdgCode, pdgName, energy,
380  motherTrackID, motherPdgCode, motherPdgName, mass, angIn, thetaC, nPhot);
381 }
382 // ----------------------------------------------------------------------------
383 
384 
385 
386 // ----- Public method AddTrackPoint ----------------------------------------
388 PndDsk::AddTrackPoint(Int_t trackID, Int_t detectorID, TVector3 position, TVector3 momentum,
389  Double_t time, Double_t length, Double_t eLoss)
390 {
391  TClonesArray& clRef = *fDskTrackPointCollection;
392  Int_t size = clRef.GetEntriesFast();
393 
394  return new(clRef[size]) PndDskTrackPoint(trackID, detectorID,
395  position, momentum, time, length, eLoss);
396 }
397 // ----------------------------------------------------------------------------
398 
399 // ----- Private method ProcessHitsCerenkov, focusing light guide version -------------------------------
400 Bool_t
402 {
403  // gather information
404  fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
405 
406  // search the photon in our collection
407  Bool_t searching = kTRUE;
408  PndDskCerenkov* pCerenkov = 0;
409  TIter iter(fDskCerenkovCollection);
410  while ( searching && (pCerenkov = (PndDskCerenkov*)iter.Next()) ) {
411  if ( pCerenkov->GetTrackID() == fTrackID )
412  searching = kFALSE;
413  }
414 
415  gMC->TrackPosition(tmpLVec);
416  fPosition = tmpLVec.Vect();
417  gMC->TrackMomentum(tmpLVec);
418  fMomentum = tmpLVec.Vect() * 1.e9;
419 
420  // if fStoreTrackPoints is set gather all necessary data now
421  if (fStoreTrackPoints) {
422  fDetectorID = vol->getMCid();
423  gMC->TrackPosition(tmpLVec);
424  fPosition = tmpLVec.Vect(); // in [cm]
425  fTime = gMC->TrackTime() * 1.e9; // in [ns], global time
426  gMC->TrackMomentum(tmpLVec);
427  fMomentum = tmpLVec.Vect() * 1.e9; // in [eV]
428  fLength = gMC->TrackLength(); // in [cm]
429  fELoss = gMC->Edep(); // in [GeV]
431  }
432 
433  // if it is a new photon
434  if (searching) {
435  // gather informations, if not already done
436  if (!fStoreTrackPoints) {
437  fDetectorID = vol->getMCid();
438  gMC->TrackPosition(tmpLVec);
439  fPosition = tmpLVec.Vect(); // in [cm]
440  fTime = gMC->TrackTime() * 1.e9; // in [ns], global time
441  gMC->TrackMomentum(tmpLVec);
442  fMomentum = tmpLVec.Vect() * 1.e9; // in [eV]
443  }
444  fEnergy = tmpLVec.E() * 1.e9; // in [eV], photon energy
445  fWavelength = 1.239841874e3/fEnergy; // hc = 4.13566733e-15[eVs] * 299792458e+09[nm/s]
446 
447  fMotherTrackID = gMC->GetStack()->GetCurrentTrack()->GetFirstMother();
448  if (fMotherTrackID>-1) {
449  TParticle* mother = ((PndStack*)(gMC->GetStack()))->GetParticle(fMotherTrackID);
450  fMotherPdgCode = mother->GetPdgCode();
451  fMotherPdgName = mother->GetName();
452  } else {
453  fMotherPdgCode = 0;
454  fMotherPdgName = "unknown";
455  }
456 
457  PndStack* stack = (PndStack*)gMC->GetStack();
458  stack->AddPoint(kDSK);
459 
460  // after we collected all information that is available on its creation
461  // we will add it to the collection
462  AddCerenkov(
463  // data of first appearance (FairMCPoint)
465  // (PndDskCerenkov)
467  // data of mother
469  );
470 
471  // if the cerenkov doesnt meet our criteria, add it to collection (already done)
472  // but stopp the track imediately. no need to track it further.
473 
474  if (DoNotTrackCerenkov()) {
475  gMC->StopTrack();
476  return kTRUE;
477  }
478 
479 
480  // is Cerenkov is in our collection
481  } else {
482  gMC->TrackPosition(tmpLVec);
483  TVector3 pos = tmpLVec.Vect();
484  gMC->TrackMomentum(tmpLVec);
485  TVector3 dir = tmpLVec.Vect();
486 
487  //if(pos.Perp()>0.9*fGeo->radius()&&dir.Z()>0) {
488  if(dir.Z()>0){ //deal with the cherenkov photon myself
489  Int_t i_FLG = -99, i_Pixel = -99;
490  //cout<<"pos: "<<pos.X()<<" "<<pos.Y()<<" "<<pos.Z()<<" dir: "<<dir.X()<<" "<<dir.Y()<<" "<<dir.Z()<<" phi: "<<dir.Phi()<<endl;
491 
492  if(dir.Theta()>fGeo->reflect_threshold()) fGeo->Propagate(pos, dir, i_FLG, i_Pixel);
493 
494  double effi = 0.1;
495 
496  if(i_FLG != -99&&gRandom->Rndm()<effi){
497  TVector3 Cherenkov_photon(0,0,1);
498  double angIn = 0, thetaC_store = 0;
500  angIn,thetaC_store,Cherenkov_photon,i_FLG, i_Pixel);
501  }
502  gMC->StopTrack();
503  }
504 
505  }
506  return kTRUE;
507 }
508 
509 // ----- Private method ProcessHitsCerenkov -------------------------------
510 Bool_t
512 {
513 
515 // fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
516 // cout << "New Step @ " << gMC->TrackTime() * 1.e9 << endl;
517 // if (gMC->IsNewTrack()) {
518 // cout << "Track " << fTrackID << " is new, called from volume: " << vol->GetName() << endl;
519 // }
520 // if (gMC->IsTrackOut()) {
521 // cout << "Track " << fTrackID << " is out, called from volume: " << vol->GetName() << endl;
522 // }
523 // if (gMC->IsTrackDisappeared()) {
524 // cout << "Track " << fTrackID << " disappeared, called from volume: " << vol->GetName() << endl;
525 // }
526 // if (gMC->IsTrackStop()) {
527 // cout << "Track " << fTrackID << " stopped, called from volume: " << vol->GetName() << endl;
528 // }
529 // if (! gMC->IsTrackInside()) {
530 // cout << "Track " << fTrackID << " on boundary, called from volume: " << vol->GetName() << endl;
531 // }
532 // if (gMC->IsTrackInside()) {
533 // cout << "Track " << fTrackID << " is inside, called from volume: " << vol->GetName() << endl;
534 // }
535 // if (gMC->IsTrackExiting()) {
536 // cout << "Track " << fTrackID << " is exiting, called from volume: " << vol->GetName() << endl;
537 // }
538 // if (gMC->IsTrackEntering()) {
539 // cout << "Track " << fTrackID << " is entering, called from volume: " << vol->GetName() << endl;
540 // }
541 
542  // gather information
543  fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
544 
545  // search the photon in our collection
546  Bool_t searching = kTRUE;
547  PndDskCerenkov* pCerenkov = 0;
548  TIter iter(fDskCerenkovCollection);
549  while ( searching && (pCerenkov = (PndDskCerenkov*)iter.Next()) ) {
550  if ( pCerenkov->GetTrackID() == fTrackID )
551  searching = kFALSE;
552  }
553 
554  //cout<<"trackID: "<<fTrackID<<endl;
555  gMC->TrackPosition(tmpLVec);
556  fPosition = tmpLVec.Vect();
557  //cout<<"position: "<<fPosition.X()<<" "<<fPosition.Y()<<" "<<fPosition.Z()<<endl;
558  gMC->TrackMomentum(tmpLVec);
559  fMomentum = tmpLVec.Vect() * 1.e9;
560  //cout<<"momentum: "<<fMomentum.X()<<" "<<fMomentum.Y()<<" "<<fMomentum.Z()<<endl;
561 
562  // if fStoreTrackPoints is set gather all necessary data now
563  if (fStoreTrackPoints) {
564  fDetectorID = vol->getMCid();
565  gMC->TrackPosition(tmpLVec);
566  fPosition = tmpLVec.Vect(); // in [cm]
567  fTime = gMC->TrackTime() * 1.e9; // in [ns], global time
568  gMC->TrackMomentum(tmpLVec);
569  fMomentum = tmpLVec.Vect() * 1.e9; // in [eV]
570  fLength = gMC->TrackLength(); // in [cm]
571  fELoss = gMC->Edep(); // in [GeV]
573  }
574 
575  // if it is a new photon
576  if (searching) {
577  // gather informations, if not already done
578  if (!fStoreTrackPoints) {
579  fDetectorID = vol->getMCid();
580  gMC->TrackPosition(tmpLVec);
581  fPosition = tmpLVec.Vect(); // in [cm]
582  fTime = gMC->TrackTime() * 1.e9; // in [ns], global time
583  gMC->TrackMomentum(tmpLVec);
584  fMomentum = tmpLVec.Vect() * 1.e9; // in [eV]
585  }
586  fEnergy = tmpLVec.E() * 1.e9; // in [eV], photon energy
587  fWavelength = 1.239841874e3/fEnergy; // hc = 4.13566733e-15[eVs] * 299792458e+09[nm/s]
588 
589  fMotherTrackID = gMC->GetStack()->GetCurrentTrack()->GetFirstMother();
590  if (fMotherTrackID>-1) {
591  TParticle* mother = ((PndStack*)(gMC->GetStack()))->GetParticle(fMotherTrackID);
592  fMotherPdgCode = mother->GetPdgCode();
593  fMotherPdgName = mother->GetName();
594  } else {
595  fMotherPdgCode = 0;
596  fMotherPdgName = "unknown";
597  }
598 
599  PndStack* stack = (PndStack*)gMC->GetStack();
600  stack->AddPoint(kDSK);
601 
602  // after we collected all information that is available on its creation
603  // we will add it to the collection
604  AddCerenkov(
605  // data of first appearance (FairMCPoint)
607  // (PndDskCerenkov)
609  // data of mother
611  );
612 
613  // if the cerenkov doesnt meet our criteria, add it to collection (already done)
614  // but stopp the track imediately. no need to track it further.
615 
616  if (DoNotTrackCerenkov()) {
617  gMC->StopTrack();
618  return kTRUE;
619  }
620 
621 
622  // is Cerenkov is in our collection
623  } else {
624  // gather informations, if not already done
625  if (!fStoreTrackPoints) {
626  gMC->TrackPosition(tmpLVec);
627  fPosition = tmpLVec.Vect(); // in [cm]
628  }
629 
630  // add projected way
631  if (fCalcPWay) {
632  pCerenkov->AddPWay(fPosition);
633  }
634  // and numer of reflections if IsTrackEntering() in the radiator
636  TString volName = vol->GetName();
637  if ((gMC->IsTrackEntering()) && (volName.BeginsWith("radiator"))) {
638  pCerenkov->AddReflection();
639 
640  // get simulated total reflection angle
641  if (fMeasureTotalRefAngle) {
642  if (pCerenkov->GetNofReflections() == 5) {
643  pCerenkov->Set5RefPosition(fPosition);
645  gMC->TrackMomentum(tmpLVec);
646  fMomentum = tmpLVec.Vect();
647  pCerenkov->SetTotalRefAngle(TMath::PiOver2() - TVector3(0.,0.,-1.).Angle(fMomentum));
648  }
649  }
650  }
651 
652 
653  // the dichroic mirrors need to be simulated inhere as it cant be done
654  // with material definitions.
655  // unfortunately there is no way to tell a Cerenkov to be reflected or not.
656  // At the moment, ever Cerenkov is reflected (ideal mirror) if its not stopped
657  // in here (already in the mirror, not the mcp ...).
658  // So the following code will give a simple MC, but wont work for a more
659  // more complicated setup behind the mirrors!
660 
661 
662 // this is what it should be:
663 // // if cerenkov reaches mcp: detect it
664 // if ((vol->getName()).BeginsWith("mcp")) {
665 // and this is what is is at the moment:
666  if (volName.BeginsWith("mirror")) {
667 
668 // sscanf((vol->getName()).Data(),"mcp%hu",&fDetType);
669  sscanf(volName.Data(),"mirror%hu",&fDetType);
670 
671 
672  // decide if photon is detected
674 
675  // detector number. They are counted as the createRootGeoFile script created them.
676  // we need the copy number of the mother of the mcp, thats the copy number of the detector.
677  gMC->CurrentVolOffID(1, fDetNumber); // detector
678 
679  // other data
681  fDetTime = gMC->TrackTime() * 1.0e09; // in [ns]
682  gMC->TrackMomentum(tmpLVec);
683  fDetMomentum = tmpLVec.Vect() * 1.e9; // in [eV]
684  // calculations for resolution study
685  // this angle is between 0deg and 180deg!
686  TVector3 tmpMom; pCerenkov->Momentum(tmpMom);
688  .Angle(TVector3(tmpMom.Px(),tmpMom.Py(),0.));
689  // and keep the track length
690  fLength = gMC->TrackLength(); // [cm]
691  // now store our values
694  // and finally: stopp the track as it got absorbed in mcp
695  gMC->StopTrack();
696  }
697  }
698  }
699 
700  return kTRUE;
701 }
702 // ----------------------------------------------------------------------------
703 
704 
705 // ----- Private method DichroicMirrorTransmitted -------------------------
706 Bool_t
708 {
709  // this is a VERY simple implementation, but better a lot better than
710  // using media definitions
711  if ( ( (det==0) && ((wl>=400.) && (wl<=500.)) )
712  ||( (det==1) && ((wl> 500.) && (wl<=700.)) )
713  )
714  {
715  return kTRUE;
716  } else {
717  return kFALSE;
718  }
719 }
720 // ----------------------------------------------------------------------------
721 
722 
723 // ----- Private method ProcessHitsParticle -------------------------------
724 Bool_t
726 {
727 
728  // it is entering any sensitive volume
729  if (gMC->TrackCharge()!=0.&& gMC->IsTrackEntering() ) {
730 
731  // we need its TrackID
732  fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
733 
734  // find it in our collection
735  Bool_t searching = true;
736  TIter iter(fDskParticleCollection);
737  PndDskParticle *pParticle;
738  while ( searching && (pParticle = (PndDskParticle *)iter.Next()) ) {
739  if ( pParticle->GetTrackID() == fTrackID )
740  searching = false;
741  }
742 
743  // this track is not yet in out collection
744  if (searching) {
745 
746  PndStack* stack = (PndStack*) gMC->GetStack();
747  stack->AddPoint(kDSK);
748 
749  // this particle is a new one, so store its values, as we want to know which particle
750  // created the Cerenkovs.
751  // other data of CmbMCPoint. Position and Time is the point of first appearance
752  fDetectorID = vol->getMCid();
753  gMC->TrackPosition(tmpLVec);
754  fPosition = tmpLVec.Vect(); // in [cm]
755  fTime = gMC->TrackTime() * 1.e9; // in [ns], global time
756  gMC->TrackMomentum(tmpLVec);
757  fMomentum = tmpLVec.Vect(); // in [GeV]
758  fEnergy = tmpLVec.E(); // in [GeV], particle energy
759  // PDG code was already stored, but we want the name too
760  fPdgName = ((PndStack*)(gMC->GetStack()))->GetCurrentTrack()->GetName();
761  // gather needed information about mother
762  fMotherTrackID = gMC->GetStack()->GetCurrentTrack()->GetFirstMother();
763  if (fMotherTrackID>-1) {
764  TParticle* mother = ((PndStack*)(gMC->GetStack()))->GetParticle(fMotherTrackID);
765  fMotherPdgCode = mother->GetPdgCode();
766  fMotherPdgName = mother->GetName();
767  } else {
768  fMotherPdgCode = 0;
769  fMotherPdgName = "unknown";
770  }
771 
773  Double_t Px = fMomentum.Px();
774  Double_t Py = fMomentum.Py();
775  Double_t Pz = fMomentum.Pz();
776  Double_t fP = sqrt(Px*Px + Py*Py +Pz*Pz);
777  Double_t fMass = gMC->TrackMass();
778 
779  //Double_t fAngIn;
780  if ( fabs(Pz/fP) > 1. || fP == 0.){ fAngIn = -1.;
781  }else{ fAngIn = acos(Pz/fP);}
782  //Double_t fThetaC;
783  if (fabs(1./(1.47*(fP/fEnergy))) > 1. || fP == 0. || fEnergy == 0.){
784  fThetaC = -1.;
785  }else{
786  fThetaC = acos(1/(1.47*(fP/fEnergy)));
787  }
788 
789  //calc number of produced photons
790  double lambda1 = 280e-9; //range of wavelength, which is seen by the PMT/PD: copied from fsim
791  double lambda2 = 330e-9;
792  double alpha=7.2974e-3; //finestructure constant
793  double thickness = 20e-3; //disc thickness, 20mm
794  double l = fabs(thickness/cos(fMomentum.Theta()));
795  double effNphotons = 0.2;
796  double nPhotMin = 5;
797  // deteremine trapping fraction
798  double trapped = 0.7; //use constant now...
799  // estimate the number of initially produced cherenkov photons
800  double nPhot, res = 0;
801  double thtdeg = fMomentum.Theta()*180/TMath::Pi();
802  int npid=-1;
803  if (fPdgCode==11) npid=0;
804  else if (fPdgCode==13) npid=1;
805  else if (fPdgCode==211) npid=2;
806  else if (fPdgCode==321) npid=3;
807  else if (fPdgCode==2212) npid=4;
808 
809  if (npid>=0 && trapfrac[npid])
810  trapped = npid<0 ? 0.0 : trapfrac[npid]->GetBinContent(trapfrac[npid]->FindBin(fP<6.0?fP:6.0,thtdeg));
811 
812 
813  if(fP != 0){
814  nPhot = 2*TMath::Pi()*alpha*l*(1./lambda1 - 1./lambda2)*(1 - (fEnergy*fEnergy)/(fP*fP*1.47*1.47));
815  nPhot = gRandom->Poisson(nPhot);
816  nPhot *= trapped*effNphotons;
817  if(nPhot <= nPhotMin){
818  //cout<<"too few photons detected..."<<endl;
819  }
820  if(nPhot>100) nPhot=100;
821 
822  if(nPhot > 0)res = 0.01/sqrt(nPhot);
823  }
824 
825  //cout<<"dsk dirc.... fMass: "<<fMass<<" fP: "<<fP<<" fEnergy: "<<fEnergy<<" fThetaC: "<<fThetaC<<" fPdgCode: "<<fPdgCode<<endl;
826  //cout<<"position: "<<fPosition.Px()<<" "<<fPosition.Py()<<" "<<fPosition.Pz()<<endl;
827  //cout<<"momentum: "<<Px<<" "<<Py<<" "<<Pz<<endl;
828  fThetaC = gRandom->Gaus(fThetaC,res);
829 // fErrThetaC = 0.; //rad
830 
831  // if this is the primary particle (TrackID == 0), save its momentum for further use
832  // these values need to be initialised in constructor, cause we need to know if the primary
833  // ever reaches the disk:
834  // if fPrimaryHitAngle is 0, the primary never reached the disk, as a value of 0 is impossible
835  // for the disk (would be along the beampipe)
836  // As the Cerenkovs will use the fPrimaryHitMomentum the primary needs to call ProcessHits
837  // before the first Cerenkov does, but i assume thats this will always be the case.
838  if (fTrackID == 0) {
840  // angle between momentum and z-axis
841  fPrimaryHitAngle = fMomentum.Angle(TVector3(0.,0.,1.));
842  }
843 
844  // now add particle
845  AddParticle(
846  // data of first appearance (FairMCPoint)
848  // (PndDskCerenkov)
850  // data of mother
852  fAngIn, fThetaC, int(nPhot));
853  }
854  }
855 
856  // The other case we are interested in is when the particles leaves the disk or is stopped in some way
857  if ( gMC->IsTrackExiting() ||
858  gMC->IsTrackStop() ||
859  gMC->IsTrackDisappeared() ) {
860 
861  // we need its TrackID
862  fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
863 
864  // find it in our collection
865  Bool_t searching = true;
866  TIter iter(fDskParticleCollection);
867  PndDskParticle *pParticle;
868  while ( searching && (pParticle = (PndDskParticle *)iter.Next()) ) {
869  if ( pParticle->GetTrackID() == fTrackID )
870  searching = false;
871  }
872 
873  if (searching) {
874  // cout << "-W- PndDskDetector::ProcessHitsParticle: Particle with trackID = " << fTrackID
875  // << "disappeared without being in the collection! Something is badly wrong here." << endl;
876  // we found it
877  } else {
878  gMC->TrackPosition(tmpLVec);
879  fEndPosition = tmpLVec.Vect(); // in [cm]
880  fEndTime = tmpLVec.T() * 1.e9; // in [ns]
881  gMC->TrackMomentum(tmpLVec);
882  fEndMomentum = tmpLVec.Vect(); // in [GeV]
883  fEndEnergy = tmpLVec.E(); // in [GeV]
885  }
886  }
887 
888  return kTRUE;
889 
890 }
891 // ----------------------------------------------------------------------------
892 
893 
894 // ----- Private method TrackCerenkov -----------------------------------
895 Bool_t
897 {
898  //available data:
899  // fDetectorID
900  // fPosition in [cm]
901  // fTime in [ns], global time
902  // fMomentum in [eV]
903  // fEnergy in [eV]
904  // fWavelength in [nm]
905 
906  // in our interval?
907  if ((fWavelength < 400.) || (fWavelength > 700.)) {
908  return kTRUE;
909  }
910 
911  // detect every Cerenkov
912  if (1. == fPDE) {
913  return kFALSE;
914  }
915 
916  Double_t pdeValue;
917 
918  // if equal to 2, we will use formula: fit for BINP_MCP, done by Avetik
919  if (2. == fPDE) {
920  pdeValue = (
921  fWavelength * (
922  fWavelength * (
923  fWavelength * (
924  fWavelength * (
925  fWavelength * (
926  fWavelength * (
927  0.24980E-13
928  ) - 0.10697E-09
929  ) + 0.18451E-06
930  ) - 0.16338E-03
931  ) + 0.77842E-01
932  ) - 18.806
933  ) + 1806.4 ) * 0.004;
934  // 0.004: pdeValue /= 100, cause it returns percent;
935  // *= 0.4, cause faktor of 40% given by MCP
936  }
937 
938  // apply quantum efficiency
939  if (gRandom->Uniform() > pdeValue) {
940  // the Cerenkov wont be detected. So no need to track it.
941  return kTRUE;
942  }
943 
944  // in general we detect
945  return kFALSE;
946 }
947 // ----------------------------------------------------------------------------
948 
949 
Int_t fPdgCode
Photon Detection Efficiency [0-1, 2].
Definition: PndDsk.h:205
TH2F * trapfrac[5]
Definition: PndDsk.h:177
TVector3 pos
friend F32vec4 acos(const F32vec4 &a)
Definition: P4_F32vec4.h:113
TClonesArray * fDskTrackPointCollection
Particle collection.
Definition: PndDsk.h:185
Double_t fELoss
Track length since creation (without mothers) [cm].
Definition: PndDsk.h:202
virtual void Register()
Definition: PndDsk.cxx:195
friend F32vec4 cos(const F32vec4 &a)
Definition: P4_F32vec4.h:112
void SetFinalValues(Int_t detNumber, Short_t detType, Double_t detTime, TVector3 detMomentum, Double_t length, Double_t primaryHitAngle, Double_t primaryAngleToCerenkov)
Double_t thickness()
Definition: PndGeoDskFLG.h:41
virtual void ConstructGeometry()
Definition: PndDsk.cxx:255
Int_t res
Definition: anadigi.C:166
Int_t i
Definition: run_full.C:25
FairGeoMedia * Media
TClonesArray * fDskCerenkovCollection
Debug level.
Definition: PndDsk.h:183
TClonesArray * fDskFLGHitArray
TrackPoint collection.
Definition: PndDsk.h:187
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
Double_t fEndEnergy
Momentum when particle disappears.
Definition: PndDsk.h:226
virtual void Print() const
Definition: PndDsk.cxx:222
Int_t fMotherTrackID
Vacuum wavelength hc/fEnergy [nm].
Definition: PndDsk.h:209
virtual Bool_t ProcessHits(FairVolume *vol=0)
Definition: PndDsk.cxx:169
Int_t fTrackID
Whether to measure total reflection angle or not (default)
Definition: PndDsk.h:196
Double_t reflect_threshold()
Definition: PndGeoDskFLG.h:43
PndDsk()
Definition: PndDsk.cxx:55
virtual void Initialize()
Definition: PndDsk.cxx:126
float Tan(float x)
Definition: PndCAMath.h:165
Bool_t fCalcPWay
Whether to store FLGHits (default) or not.
Definition: PndDsk.h:193
void SetTrapFraction(std::string name)
Definition: PndDsk.cxx:135
Double_t thickness
TGeoManager * gGeoManager
Bool_t fStoreTrackPoints
Whether to store Particles (default) or not.
Definition: PndDsk.h:191
Double_t fLength
Global time (since event start) [ns].
Definition: PndDsk.h:201
void AddPoint(DetectorId iDet)
Definition: PndStack.cxx:408
Double_t radius()
Definition: PndGeoDskFLG.h:40
TClonesArray * fDskParticleCollection
Cerenkov collection.
Definition: PndDsk.h:184
virtual void EndOfEvent()
Definition: PndDsk.cxx:185
PndGeoDskFLG * fGeo
Definition: PndDsk.h:179
void Set5RefPosition(TVector3 pos)
TVector3 fEndMomentum
Time when particle disappears.
Definition: PndDsk.h:225
Double_t fThetaC
Definition: PndDsk.h:229
#define cave
Definition: createSTT.C:62
Double_t fEnergy
PDG code of current particle.
Definition: PndDsk.h:206
void AddReflection()
FairGeoBuilder * geobuild
Bool_t fMeasureTotalRefAngle
Whether to calc Projected Way or not (default)
Definition: PndDsk.h:194
Double_t fTime
Momentum [GeV].
Definition: PndDsk.h:200
void AddPWay(TVector3 pos)
Double_t
Bool_t ProcessHitsParticle(FairVolume *vol=0)
Definition: PndDsk.cxx:725
void SetTotalRefAngle(Double_t angle)
PndDskCerenkov * AddCerenkov(Int_t trackID, Int_t detectorID, TVector3 position, TVector3 momentum, Double_t time, Double_t energy, Double_t wavelength, Int_t motherTrackID, Int_t motherPdgCode, TString motherPdgName)
Definition: PndDsk.cxx:352
PndDskParticle * AddParticle(Int_t trackID, Int_t detectorID, TVector3 position, TVector3 momentum, Double_t time, Int_t pdgCode, TString pdgName, Double_t energy, Int_t motherTrackID, Int_t motherPdgCode, TString motherPdgName, Double_t mass, Double_t angIn, Double_t thetaC, Int_t nPhot)
Definition: PndDsk.cxx:369
PndDskFLGHit * AddHit(Int_t trackID, Int_t detectorID, TVector3 position_store, TVector3 momentum_store, Double_t time, Double_t angIn, Double_t thetaC_store, TVector3 Cherenkov_photon, Int_t light_guide, Int_t pixel)
Definition: PndDsk.cxx:337
TFile * f
Definition: bump_analys.C:12
Bool_t fStoreCerenkovs
DSK hits.
Definition: PndDsk.h:189
void SetFinalValues(TVector3 exitPosition, TVector3 exitMomentum, Double_t exitTime, Double_t exitEnergy)
friend F32vec4 fabs(const F32vec4 &a)
Definition: P4_F32vec4.h:47
virtual Bool_t CheckIfSensitive(std::string name)
Definition: PndDsk.cxx:319
TVector3 fMomentum
Position [cm].
Definition: PndDsk.h:199
Double_t const fWindowHeightHalf
Bool_t ProcessHitsCerenkov(FairVolume *vol=0)
Definition: PndDsk.cxx:511
TString name
Double_t GetNofReflections() const
TLorentzVector tmpLVec
Definition: PndDsk.h:231
Double_t postion_plate()
Definition: PndGeoDskFLG.h:42
Bool_t fStoreFLGHits
Whether to store TrackPoints or not (default)
Definition: PndDsk.h:192
virtual TClonesArray * GetCollection(Int_t iColl) const
Definition: PndDsk.cxx:208
Bool_t fStoreParticles
Whether to store Cerenkovs (default) or not.
Definition: PndDsk.h:190
Bool_t DichroicMirrorTransmitted(Double_t wavelength, Int_t detector_type)
Definition: PndDsk.cxx:707
Double_t GetWavelength() const
TString fPdgName
Angle between momentum of eachs first appearance.
Definition: PndDsk.h:222
Double_t fPrimaryHitAngle
Angle at the moment of first appearance.
Definition: PndDsk.h:219
Int_t fDetNumber
Detectortype that registered the Cerenkov.
Definition: PndDsk.h:214
Bool_t ProcessHitsCerenkov_FLG(FairVolume *vol=0)
Definition: PndDsk.cxx:401
Double_t fDetTime
Number of the Detector that registered the Cerenkov.
Definition: PndDsk.h:215
Double_t fWavelength
Energy [eV / GeV].
Definition: PndDsk.h:207
ClassImp(PndAnaContFact)
PndDskTrackPoint * AddTrackPoint(Int_t trackID, Int_t detectorID, TVector3 position, TVector3 momentum, Double_t time, Double_t length, Double_t eLoss)
Definition: PndDsk.cxx:388
TVector3 fEndPosition
PDG name according to fPdgCode.
Definition: PndDsk.h:223
void Propagate(TVector3 pos, TVector3 dir, Int_t &i_FLG, Int_t &i_Pixel)
TVector3 fDetMomentum
Global time when Cerenkov was detected [ns].
Definition: PndDsk.h:216
Double_t const fWindowWidthHalf
TString fMotherPdgName
PDG code of the particle that emitted this Cerenkov.
Definition: PndDsk.h:211
double alpha
Definition: f_Init.h:9
virtual void Reset()
Definition: PndDsk.cxx:232
Definition: PndDsk.h:23
Double_t Pi
Mvd Initialize()
TVector3 fPosition
Detector ID (volume)
Definition: PndDsk.h:198
Bool_t DoNotTrackCerenkov()
Definition: PndDsk.cxx:896
Double_t fPrimaryAngleToCerenkov
Momentum when detected [eV].
Definition: PndDsk.h:218
Double_t thetaC
Definition: plot_dirc.C:16
Int_t fDetectorID
Index of MCTrack.
Definition: PndDsk.h:197
#define air
Definition: createSTT.C:72
Double_t fPDE
Energy deposit [GeV].
Definition: PndDsk.h:204
Short_t fDetType
translation of PDG code
Definition: PndDsk.h:213
Double_t fEndTime
Position when particles disappears.
Definition: PndDsk.h:224
Double_t fAngIn
Energy when particle disappears.
Definition: PndDsk.h:228
virtual ~PndDsk()
Definition: PndDsk.cxx:98
TVector3 fPrimaryHitMomentum
Angle to the z-Axis at first appearance.
Definition: PndDsk.h:220
Double_t energy
Definition: plot_dirc.C:15
Int_t fMotherPdgCode
Track ID of the particle that emitted this Cerenkov.
Definition: PndDsk.h:210
virtual void CopyClones(TClonesArray *cl1, TClonesArray *cl2, Int_t offset)
Definition: PndDsk.cxx:245