Back to home page

EIC code displayed by LXR

 
 

    


Warning, /geant4/examples/extended/optical/LXe/README.md is written in an unsupported language. File is not indexed.

0001 \page ExampleLXe Example LXe
0002 
0003 ## Introduction
0004 
0005 This example demonstrates usage of optical physics. 
0006 
0007 ## Geometry and primary particle
0008 
0009 The main volume is a box of LXe. PMTs are placed around the outside. There
0010 may be a reflective sphere placed inside the box, and a wavelength shifting
0011 slab and fibers.
0012 
0013 The geometry implementation is different from many of the other examples. 
0014 See the discussion below.
0015 
0016 G4ParticleGun creates the primary particle. The type of particle is selectable
0017 by the user.
0018 
0019 ## Physics
0020 
0021 The physics list is FTFP_BERT, with G4EmStandard_option4 electromagnetic
0022 physics and G4OpticalPhysics.
0023 
0024 ## Physics Macro files
0025 
0026 cerenkov.mac disables scintillation, so the optical photons that are produced
0027 are Cerenkov photons.
0028 
0029 wls.mac implements a scintillating slab and wavelength shifting fibers.
0030 
0031 ## List of built-in histograms
0032 
0033 - 1  "hits per event"
0034 - 2  "hits per event above threshold"
0035 - 3  "scintillation photons per event"
0036 - 4  "Cerenkov photons per event"
0037 - 5  "absorbed photons per event"
0038 - 6  "photons absorbed at boundary per event"
0039 - 7  "energy deposition in scintillator per event"
0040 
0041 ## How to start?
0042 
0043   - execute LXe in 'batch' mode from macro files, e.g.
0044 ```
0045 $ ./LXe cerenkov.mac
0046 ```
0047   - execute LXe in 'interactive' mode with visualization, e.g.
0048 ```
0049 $ ./LXe
0050 Then type commands, for instance
0051 Idle> /run/beamOn 1
0052 ```
0053 
0054 ## Macros included
0055 
0056 Several macros are include in the distribution:
0057 
0058 - cerenkov.mac: Shoot a 200 MeV mu+ and only allow it to take one step. The
0059                 Cerenkov cone and PMTs hit are visible. (Reduce the number
0060                 of particles for visualization.)
0061 - LXe.mac:      Shoot a 511 keV gamma with the default geometry.
0062 - photon.mac:   Primary beam is an optical photon, with the default geometry.
0063 - wls.mac:      Geometry includes 15 WLS fibers. A 511 keV electron is the
0064                 primary.
0065 
0066 
0067 ## Detailed Explanation of Geometry Implementation
0068 
0069 The way the geometry is constructed is an experiment for a new, more object
0070 oriented, way to construct geometry. It separates the concept of how a volume
0071 is built from where it is placed. Each major volume in the geometry is defined
0072 as a class derived from G4PVPlacement. In this example, just the main LXe
0073 volume, the WLS scintillator slab, and the WLS fibers were chosen. To place
0074 one of these volumes, simply create an instance of it with the appropriate
0075 rotation, translation, and mother volumes.
0076 
0077 ```cpp
0078     LXeMainVolume(G4RotationMatrix *pRot,
0079                   const G4ThreeVector &tlate,
0080                   G4LogicalVolume *pMotherLogical,
0081                   G4bool pMany,
0082                   G4int pCopyNo,
0083                   LXeDetectorConstruction* c);
0084 ```
0085 
0086 Also necessary are the pMany and pCopyNo variables with the same usage as in 
0087 G4PVPlacement. Additionally, the detector construction must be passed to the
0088 main volume as a way to communicate the many parameters to the volume and its
0089 sub-volumes. The communication is done from the CopyValues() function which
0090 retrieves the information from the detector constructor.
0091 
0092 Notably, the name and logical volume parameters are no longer part of the
0093 constructor. This is because they are both to be decided by the volume itself.
0094 The volume must specify its own name and a temporary logical volume. The
0095 constructor will then procede to define its logical volume in the normal way.
0096 Once complete, the logical volume can be assigned to the physical volume using
0097 the SetLogicalVolume() function.
0098 
0099 To handle instances of the same type of volume, a new logical volume should not
0100 be defined for each one. Instead, the logical volume is kept as a static member
0101 and defined only once. 
0102 
0103 ```cpp
0104     if (!housing_log || updated) {
0105       //...
0106       //Define logical volume
0107       //...
0108     }
0109     SetLogicalVolume(housing_log);
0110 ```
0111 
0112 The updated variable is to signal that the volume needs to be updated and a new
0113 logical volume made.
0114 
0115 ## Modifying the geometry at runtime
0116 
0117 This example allows the user to modify the geometry definition at runtime. This
0118 is accomplished through LXeDetectorMessenger, a derived class of G4UImessenger.
0119 The commands it adds change variables stored in LXeDetectorConstructor that
0120 are used when constructing the geometry. 
0121 
0122 ```cpp
0123     void LXeDetectorConstruction::UpdateGeometry(){
0124       // clean-up previous geometry
0125       G4SolidStore::GetInstance()->Clean();
0126       G4LogicalVolumeStore::GetInstance()->Clean();
0127       G4PhysicalVolumeStore::GetInstance()->Clean();
0128 
0129       //define new one
0130       G4RunManager::GetRunManager()->DefineWorldVolume(ConstructDetector());
0131       G4RunManager::GetRunManager()->GeometryHasBeenModified();
0132     }
0133 ```
0134 
0135 ## PMT sensitive detector
0136 
0137 The PMT sensitive detector cannot be triggered like a normal sensitive detector
0138 because the sensitive volume does not allow photons to pass through it. Rather,
0139 it detects them in the OpBoundary process based on an efficiency set on the
0140 skin of the volume.
0141 
0142 ```cpp
0143     G4OpticalSurface* photocath_opsurf=
0144        new G4OpticalSurface("photocath_opsurf",glisur,polished,
0145                              dielectric_metal);
0146     G4double photocath_EFF[num]={1.,1.};
0147     G4double photocath_REFL[num]={0.,0.};
0148     G4MaterialPropertiesTable* photocath_mt = new G4MaterialPropertiesTable();
0149     photocath_mt->AddProperty("EFFICIENCY",Ephoton,photocath_EFF,num);
0150     photocath_mt->AddProperty("REFLECTIVITY",Ephoton,photocath_REFL,num);
0151     photocath_opsurf->SetMaterialPropertiesTable(photocath_mt);
0152     new G4LogicalSkinSurface("photocath_surf",photocath_log,photocath_opsurf);
0153 ```
0154 
0155 A normal sensitive detector would have its ProcessHits 
0156 function called for each step by a particle inside the volume. So, to record
0157 these hits with a sensitive detector we watched the status of the OpBoundary
0158 process from the stepping manager whenever a photon hit the sensitive volume
0159 of the pmt. If the status was 'Detection', we retrieve the sensitive detector
0160 from G4SDManager and call its ProcessHits function.
0161 
0162 ```cpp
0163     boundaryStatus=boundary->GetStatus();
0164     //Check to see if the particle was actually at a boundary
0165     //Otherwise the boundary status may not be valid
0166     //Prior to Geant4.6.0-p1 this would not have been enough to check
0167     if(thePostPoint->GetStepStatus()==fGeomBoundary){
0168       switch(boundaryStatus){
0169       //...    
0170         case Detection: //Note, this assumes that the volume causing detection
0171                         //is the photocathode because it is the only one with
0172                   //non-zero efficiency
0173     {
0174       //Trigger sensitive detector manually since photon is
0175       //absorbed but status was Detection
0176       G4SDManager* SDman = G4SDManager::GetSDMpointer();
0177       G4String sdName="/LXeDet/pmtSD";
0178       LXePMTSD* pmtSD = (LXePMTSD*)SDman
0179         ->FindSensitiveDetector(sdName);
0180       if(pmtSD)
0181         pmtSD->ProcessHits_constStep(theStep,NULL);
0182       break;
0183     }
0184         //...
0185       }
0186 ```
0187 
0188 ## Selectively drawing trajectories or highlighting volumes
0189 
0190 In a simulation such as this one, where an average of 6000 trajectories are
0191 generated in a small space, there is little use in drawing all of them. There
0192 are two ways to select which ones to draw. The first of which is to decide
0193 while looping through the trajectory container which ones to draw and only call
0194 DrawTrajectory on the important ones. However, trajectories only contain a
0195 small portion of the information from the track it represents. This may not
0196 be enough to decide if a trajectory is worth drawing.
0197 
0198 The alternative is to define your own trajectory class to store additional
0199 information to help decide if it should be drawn. To use your custom trajectory
0200 you must create it in the PreUserTrackingAction:
0201 
0202 ```cpp
0203 fpTrackingManager->SetTrajectory(new LXeTrajectory(aTrack));
0204 ```
0205 
0206 Then at any point you can get access to the trajectory you can update the extra
0207 information within it. When it comes to drawing, you can then use this to
0208 decide if you want to call DrawTrajectory. Or you can call DrawTrajectory for
0209 all trajectories and have the logic decide how and if a trajectory should
0210 be drawn inside the DrawTrajectory function itself.
0211 
0212 Selectively highlighting volumes is useful to show which volumes were hit. To
0213 do this, you simply need a pointer to the physical volume. With that, you can
0214 modify its vis attributes and instruct the vis manager to redraw the volume
0215 with the new vis attributes.
0216 
0217 ```cpp
0218     G4VisAttributes attribs(G4Colour(1.,0.,0.));
0219     attribs.SetForceSolid(true);
0220     G4RotationMatrix rot;
0221     if(physVol->GetRotation())//If a rotation is defined use it
0222       rot=*(physVol->GetRotation());
0223     G4Transform3D trans(rot,physVol->GetTranslation());//Create transform
0224     pVVisManager->Draw(*physVol,attribs,trans);//Draw it
0225 ```
0226 
0227 In this case, it is done in Draw function of a PMT hit but it can be placed
0228 anywhere. The logic to decide if it should be drawn or not may be similar to
0229 the logic used in choosing which trajectories to draw.
0230 
0231 See /LXe/detector/volumes/sphere in "UI commands" below for info on what 
0232 trajectories are drawn in this simulation.
0233 
0234 ## Saving random engine seeds
0235 
0236 At times it may be necessary to review a particular event of interest. To do
0237 this without redoing an entire run, which may take a long time, you must store
0238 the random engine seed from the beginning of the event. The run manager
0239 has some functions that help in this task.
0240 
0241 ```cpp
0242 G4RunManager::SetRandomNumberStore(G4bool)
0243 ```
0244 
0245 When set to true, this causes the run manager to write the seed for the
0246 beginning of the current run to CurrentRun.rndm and the current event to 
0247 CurrentEvent.rndm. However, at the beginning of each event this file will be 
0248 overwritten with the new event. To keep a copy for a particular event there is
0249 a function to copy this file to "run###evt###.rndm".
0250 
0251 ```cpp
0252 G4RunManager::rndmSaveThisEvent()
0253 ```
0254 
0255 This can be done for every event so you can review any event you like but this
0256 may be awkward for runs with very large numbers of events. Instead, implement
0257 some form of logic in EndOfEventAction to decide if the event is worth saving.
0258 If it is, then call rndmSaveThisEvent(). By default, these files are stored in
0259 the current working directory. There is a function to change this as well.
0260 Typically you would call that at the same time SetRandomNumberStore. The
0261 directory to save in must exist first. GEANT4 will not create it for you.
0262 
0263 ```cpp
0264 G4RunManager::SetRandomNumberStoreDir(G4String)
0265 ```
0266 
0267 ## UI commands
0268 
0269 Directories:
0270 ```
0271 /LXe/ - All custom commands belong below this directory
0272 /LXe/detector/ - Geometry related commands
0273 /LXe/detector/volumes/ - Commands to enable/disable volumes in the geometry
0274 ```
0275 
0276 Commands:
0277 ```
0278 /LXe/saveThreshold <int, default = 4500>
0279 ```
0280 - Specifies a threshold for saving the random seed for an event. If the number
0281 of photons generated in an event is below this number then the random seed is
0282 saved to "./random/run###evt###.rndm". See "Saving random engine seeds".
0283 
0284 ```
0285 /LXe/eventVerbose <int, default = 1>
0286 ```
0287 - Enables end of event verbose data to be printed. This includes information
0288 counted and calculated by the user action classes.
0289 
0290 ```
0291 /LXe/pmtThreshold <int, default = 1>
0292 ```
0293 - Sets the PMT threshold in # of photons being detected by the PMT. PMTs below
0294 with fewer hits than the threshold will not count as being hit and will also
0295 not be highlighted at the end of the event.
0296 
0297 ```
0298 /LXe/oneStepPrimaries <bool>
0299 ```
0300 - This causes primary particles to be killed after going only one step inside
0301 the scintillator volume. This is useful to view the photons generated during 
0302 the initial conversion of the primary particle.
0303 
0304 ```
0305 /LXe/forceDrawPhotons <bool>
0306 ```
0307 - Forces all optical photon trajectories to be drawn at the end of the event 
0308 regardless of the scheme mentioned in /LXe/detector/volumes/sphere below.
0309 
0310 ```
0311 /LXe/forceDrawNoPhotons <bool>
0312 ```
0313 - Forces all optical photon trajectories to NOT be drawn at the end of the 
0314 event regardless of the scheme mentioned in /LXe/detector/volumes/sphere below.
0315 - If /LXe/forceDrawPhotons is set to true, this has no effect.
0316 
0317 ```
0318 /LXe/detector/dimensions <double x y z> <unit, default = cm>
0319 ```
0320 - Sets the dimensions of the main scintillator volume.
0321 
0322 ```
0323 /LXe/detector/housingThickness <double>
0324 ```
0325 - Sets the thickness of the housing surrounding the main detector volume.
0326 
0327 ```
0328 /LXe/detector/pmtRadius <double> <unit, default = cm>
0329 ```
0330 - Sets the radius of the PMTs
0331 
0332 ```
0333 /LXe/detector/nx
0334 /LXe/detector/ny
0335 /LXe/detector/nz
0336 ```
0337 - Sets the number of PMTs placed in a row along each axis.
0338 
0339 ```
0340 /LXe/detector/reflectivity <double>
0341 ```
0342 - Sets the reflectivity of the inside of the aluminum housing. The geometry
0343 uses a default value of 1.00 for a fully reflective surface.
0344 
0345 ```
0346 /LXe/detector/nfibers <int>
0347 ```
0348 - Sets the number of WLS fibers placed in the WLS scintillator slab. The
0349 geometry uses a default value of 15 fibers.
0350 
0351 ```
0352 /LXe/detector/MainScintYield <double>
0353 ```
0354 - Sets the yield factor for the scintillation process of main volume. This is cumulative with
0355 the yield factor set on individual materials. Set to 0 to produce no 
0356 scintillation photons.
0357 
0358 ```
0359 /LXe/detector/WLSScintYield <double>
0360 ```
0361 - Sets the yield factor for the scintillation process of WLS Slab. Specified in photons/MeV.
0362 ```
0363 /LXe/detector/defaults
0364 ```
0365 - Resets all detector values customizable with commands above to their defaults.
0366 
0367 ```
0368 /LXe/detector/volumes/sphere <bool>
0369 ```
0370 - Enables/disables the sphere placed inside the main scintillator volume. When
0371 the sphere is enabled, only photons that hit the sphere and hit a PMT are
0372 drawn. If it is disabled, then all photons that hit PMTs are drawn.
0373 
0374 ```
0375 /LXe/detector/volumes/wls <bool>
0376 ```
0377 - Enables/disables the WLS scintillator slab containing WLS fibers. By default
0378 this is not part of the geometry. Enabling it will place it behind the LXe
0379 scintillator volume.
0380 
0381 ```
0382 /LXe/detector/volumes/lxe <bool>
0383 ```
0384 - Enables/disables the main LXe scintillator volume. By default this is part of
0385 the geometry.