Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/advanced/air_shower/src/UltraDetectorConstruction.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 //
 27 // --------------------------------------------------------------
 28 //                 GEANT 4 - ULTRA experiment example
 29 // --------------------------------------------------------------
 30 //
 31 // Code developed by:
 32 // B. Tome, M.C. Espirito-Santo, A. Trindade, P. Rodrigues
 33 //
 34 //    ****************************************************
 35 //    *      UltraDetectorConstruction.cc
 36 //    ****************************************************
 37 //
 38 //    Class used in the definition of the Ultra setup consisting of:
 39 //      - the UVscope detector
 40 //      - an optional reflecting surface
 41 //    Optical photons can reach the UVscope either directly or after reflection in the
 42 //    surface, which can be polished or diffusing.
 43 //    The main part of the UVscope definition is the Fresnel lens construction based
 44 //    on the UltraFresnelLens class.
 45 //
 46 #include <cmath>
 47 
 48 #include "UltraDetectorConstruction.hh"
 49 #include "UltraDetectorMessenger.hh"
 50 #include "UltraPMTSD.hh"
 51 #include "UltraFresnelLens.hh"
 52 
 53 #include "G4PhysicalConstants.hh"
 54 #include "G4SystemOfUnits.hh"
 55 #include "G4RunManager.hh"
 56 #include "G4MTRunManager.hh"
 57 #include "G4GeometryManager.hh"
 58 #include "G4Material.hh"
 59 #include "G4MaterialTable.hh"
 60 #include "G4Element.hh"
 61 #include "G4ElementTable.hh"
 62 #include "G4LogicalBorderSurface.hh"
 63 #include "G4LogicalSkinSurface.hh"
 64 #include "G4Box.hh"
 65 #include "G4Sphere.hh"
 66 #include "G4Tubs.hh"
 67 #include "G4LogicalVolume.hh"
 68 #include "G4RotationMatrix.hh"
 69 #include "G4ThreeVector.hh"
 70 #include "G4Transform3D.hh"
 71 #include "G4PVPlacement.hh"
 72 #include "G4OpBoundaryProcess.hh"
 73 #include "G4VisAttributes.hh"
 74 #include "G4Colour.hh"
 75 #include "G4Log.hh"
 76 #include "G4SDManager.hh"
 77 
 78 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 79 
 80 UltraDetectorConstruction::UltraDetectorConstruction() :
 81   fReflectorOpticalSurface(0),
 82   logicalPMT(0),
 83   fReflectorLog(0),
 84   fIsReflectorConstructed(false)
 85 {
 86   // Define wavelength limits for materials definition
 87   lambda_min = 200*nm ;
 88   lambda_max = 700*nm ;
 89 
 90   fDetectorMessenger = new UltraDetectorMessenger(this);
 91 
 92   ConstructTableMaterials();
 93 }
 94 
 95 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 96 
 97 UltraDetectorConstruction::~UltraDetectorConstruction()
 98 {
 99   delete fDetectorMessenger;
100 
101   delete fReflectorOpticalSurface;
102 }
103 
104 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
105 
106 G4VPhysicalVolume* UltraDetectorConstruction::Construct()
107 {
108 //  The experimental Hall
109 //  ---------------------
110 
111   auto World_x = 1.*m;
112   auto World_y = 1.*m;
113   auto World_z = 2*m;
114 
115   auto World_box = new G4Box("World",World_x,World_y,World_z);
116 
117   // Get Air pointer from static funcion - (G4Material::GetMaterial)
118   auto Air = G4Material::GetMaterial("Air");
119   auto World_log = new G4LogicalVolume(World_box,Air,"World",0,0,0);
120 
121   fWorld_phys   = new G4PVPlacement(0,G4ThreeVector(),"World",World_log,0,false,0);
122 
123    auto UniverseVisAtt = new G4VisAttributes(G4Colour(1.0,1.0,1.0));
124    UniverseVisAtt->SetVisibility(true);
125    UniverseVisAtt->SetForceWireframe(true);
126    World_log->SetVisAttributes(UniverseVisAtt);
127    World_log->SetVisAttributes (G4VisAttributes::GetInvisible());
128 
129 
130 
131   G4cout << "\n \n \n \n \n \n \n \n \n \n \n \n \n " << G4endl ;
132 
133   G4cout << "######################################################" << G4endl ;
134   G4cout << "#                                                    #" << G4endl ;
135   G4cout << "#                                                    #" << G4endl ;
136   G4cout << "#          UltraDetectorConstruction:                #" << G4endl ;
137   G4cout << "#                                                    #" << G4endl ;
138   G4cout << "#                                                    #" << G4endl ;
139 
140   ConstructUVscope();
141 
142 
143   G4cout << "#                                                    #" << G4endl ;
144   G4cout << "#                                                    #" << G4endl ;
145   G4cout << "######################################################" << G4endl ;
146 
147   fIsReflectorConstructed = false;
148 
149   return fWorld_phys;
150 }
151 
152 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
153 
154 void UltraDetectorConstruction::ConstructSDandField()
155 {
156   auto PMTSD = new UltraPMTSD("PMTSD");
157   G4SDManager::GetSDMpointer()->AddNewDetector(PMTSD);
158   SetSensitiveDetector(logicalPMT,PMTSD);
159 }
160 
161 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
162 
163 void UltraDetectorConstruction::ConstructTableMaterials()
164 {
165   G4double a, z, density;
166 
167 //  ------------- Elements -------------
168   a = 1.01*g/mole;
169   auto elH  = new G4Element("Hydrogen", "H", z=1., a);
170 
171   a = 12.01*g/mole;
172   auto elC  = new G4Element("Carbon", "C", z=6., a);
173 
174   a = 14.01*g/mole;
175   auto elN  = new G4Element("Nitrogen", "N", z=7., a);
176 
177   a = 16.00*g/mole;
178   auto elO  = new G4Element("Oxygen",  "O", z=8., a);
179 
180   a = 28.09*g/mole;
181   auto elSi = new G4Element("Silicon", "Si", z=14., a);
182 
183 
184 //  ------------- Materials -------------
185 
186 
187 // Air
188 // ---
189   density = 1.29e-03*g/cm3;
190   auto Air = new G4Material("Air", density, 2);
191   Air->AddElement(elN, .7);
192   Air->AddElement(elO, .3);
193 
194 
195 // Aluminum
196 // ---------
197   a = 26.98*g/mole;
198   density = 2.7*g/cm3;
199   new G4Material("Aluminum", z=13., a, density);
200 
201 
202 // Quartz
203 // -------
204 //  density = 2.200*g/cm3; // fused quartz
205   density = 2.64*g/cm3;  // crystalline quartz (c.f. PDG)
206   auto Quartz = new G4Material("Quartz",density, 2);
207   Quartz->AddElement(elSi, 1) ;
208   Quartz->AddElement(elO , 2) ;
209 
210 
211 // PMMA C5H8O2 ( Acrylic )
212 // -------------
213    density = 1.19*g/cm3;
214    auto Acrylic = new G4Material("Acrylic", density, 3);
215    Acrylic->AddElement(elC, 5);
216    Acrylic->AddElement(elH, 8);
217    Acrylic->AddElement(elO, 2);
218 
219 
220 /////////////////////////////////////////////
221 // Construct Material Properties Tables
222 /////////////////////////////////////////////
223 
224   // Energy bins
225   std::vector<G4double> X_RINDEX = {h_Planck*c_light/lambda_max, h_Planck*c_light/lambda_min} ;
226 
227 
228   // Air
229   std::vector<G4double> RINDEX_AIR{1.00, 1.00} ;
230 // Air refractive index at 20 oC and 1 atm (from PDG)
231   for(auto&& i : RINDEX_AIR){
232     i = i  + 2.73*std::pow(10.0,-4) ;
233   }
234 
235   auto MPT_Air = new G4MaterialPropertiesTable();
236   MPT_Air->AddProperty("RINDEX", X_RINDEX, RINDEX_AIR);
237   Air->SetMaterialPropertiesTable(MPT_Air);
238 
239 //////////////////////////////////////////////////////////////////////////////////////
240 //           Photomultiplier (PMT) window
241 // The refractive index is for lime glass;
242 // wavelength dependence is not included and value at 400nm is used.
243 //////////////////////////////////////////////////////////////////////////////////////
244 
245   // Refractive index
246 
247   std::vector<G4double> X_RINDEX_QUARTZ{h_Planck*c_light/lambda_max, h_Planck*c_light/lambda_min} ;
248   std::vector<G4double> RINDEX_QUARTZ{1.54, 1.54};
249 
250   auto MPT_PMT = new G4MaterialPropertiesTable();
251   MPT_PMT->AddProperty("RINDEX", X_RINDEX_QUARTZ, RINDEX_QUARTZ);
252 
253   Quartz->SetMaterialPropertiesTable(MPT_PMT);
254 
255 
256 //////////////////////////////////////////////////////////////////
257 //               ACRYLIC Optical properties
258 //////////////////////////////////////////////////////////////////
259 
260 // Refractive index
261 
262   const auto NENTRIES = 11 ;
263 
264   std::vector<G4double> RINDEX_ACRYLIC;
265   std::vector<G4double> ENERGY_ACRYLIC;
266 
267 // Parameterization for refractive index of High Grade PMMA
268 
269   G4double bParam[4] = {1760.7010,-1.3687,2.4388e-3,-1.5178e-6} ;
270   auto lambda = 0.;
271 
272   for(auto i=0;i<NENTRIES; ++i){
273 
274     // want energies in increasing order
275     lambda = lambda_min + (NENTRIES-1-i) * (lambda_max-lambda_min)/float(NENTRIES-1);
276     RINDEX_ACRYLIC.push_back(0.0);
277 
278     for (auto jj=0 ; jj<4 ; jj++)
279     {
280       RINDEX_ACRYLIC[i] +=  (bParam[jj]/1000.0)*std::pow(lambda/nm,jj) ;
281     }
282 
283     ENERGY_ACRYLIC.push_back(h_Planck*c_light/lambda);  // Convert from wavelength to energy ;
284 //  G4cout << ENERGY_ACRYLIC[i]/eV << " " << lambda/nm << " " << RINDEX_ACRYLIC[i] << G4endl ;
285   }
286 
287   auto MPT_Acrylic = new G4MaterialPropertiesTable();
288   MPT_Acrylic->AddProperty("RINDEX", ENERGY_ACRYLIC, RINDEX_ACRYLIC);
289 
290 // Absorption
291   std::vector<G4double> LAMBDAABS
292   {
293     100.0,
294     246.528671, 260.605103, 263.853516, 266.019104, 268.726105,
295     271.433136, 273.598724, 276.305725, 279.554138, 300.127380,
296     320.159241, 340.191101, 360.764343, 381.337585, 399.745239,
297     421.401276, 440.891724, 460.382172, 480.414001, 500.987274,
298     520.477722, 540.509583, 559.458618,
299     700.0
300   } ;
301 
302   std::vector<G4double> T   // Transmission (in %) of 3mm thick PMMA
303   {
304     0.0000000,
305     0.0000000,  5.295952,  9.657321, 19.937695, 29.283491,
306     39.252335, 48.598133, 58.255451, 65.109039, 79.439247,
307     85.669785, 89.719627, 91.277260, 91.588783, 91.900307,
308     91.588783, 91.277260, 91.277260, 91.588783, 91.588783,
309     91.900307, 91.900307, 91.588783,
310     91.5
311   } ;
312 
313 
314   auto abslengthMPV = new G4MaterialPropertyVector();
315   for(size_t i=0;i<T.size(); ++i){
316     auto energy    = h_Planck*c_light/(LAMBDAABS[i]*nm) ;
317     auto abslength = 0.0;
318 
319     if (T[i] <= 0.0) {
320       abslength = 1.0/kInfinity ;
321     }
322     else {
323       abslength = -3.0*mm/(G4Log(T[i]/100.0)) ;
324     }
325 
326     abslengthMPV->InsertValues(energy,abslength);
327 
328     // MPT_Acrylic->AddEntry("ABSLENGTH", energy, abslength);
329   }
330 
331   MPT_Acrylic->AddProperty("ABSLENGTH", abslengthMPV);
332   Acrylic->SetMaterialPropertiesTable(MPT_Acrylic);
333 
334 //////////////////////////////////////////////////////////////////
335 
336   G4cout << *(G4Material::GetMaterialTable()) << G4endl;
337 
338   for (const auto& mat : *(G4Material::GetMaterialTable())) {
339     if (mat->GetMaterialPropertiesTable()) {
340       G4cout << "Material properties  for " << mat->GetName()<< " : " << G4endl;
341       mat->GetMaterialPropertiesTable()->DumpTable();
342     }
343   }
344 }
345 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
346 
347 void UltraDetectorConstruction::ConstructReflector()
348 {
349   const auto x = 40.0*cm;
350   const auto y = 40.0*cm;
351   const auto z = 1*cm;
352 
353   auto box = new G4Box("Mirror",x,y,z);
354 
355   // Get Air pointer from static funcion - (G4Material::GetMaterial)
356   auto Al = G4Material::GetMaterial("Aluminum");
357 
358   fReflectorLog = new G4LogicalVolume(box,Al,"Reflector",0,0,0);
359 
360   auto SurfacePosition = G4ThreeVector(0*m,0*m,1.5*m) ;
361 
362   // Rotate reflecting surface by 45. degrees around the OX axis.
363 
364   auto Surfrot = new G4RotationMatrix(G4ThreeVector(1.0,0.0,0.0),-pi/4.);
365 
366   new G4PVPlacement(Surfrot,SurfacePosition,"MirrorPV",fReflectorLog,fWorld_phys,false,0);
367 
368   auto SurfaceVisAtt = new G4VisAttributes(G4Colour(0.0,0.0,1.0));
369   SurfaceVisAtt->SetVisibility(true);
370   SurfaceVisAtt->SetForceWireframe(true);
371   fReflectorLog->SetVisAttributes(SurfaceVisAtt);
372 
373   fReflectorOpticalSurface = new G4OpticalSurface("ReflectorOpticalSurface");
374   fReflectorOpticalSurface->SetModel(unified);
375   fReflectorOpticalSurface->SetType(dielectric_dielectric);
376 
377   std::vector<G4double> XX{h_Planck*c_light/lambda_max, h_Planck*c_light/lambda_min} ;
378   std::vector<G4double> ICEREFLECTIVITY{ 0.95, 0.95 };
379 
380   auto AirMirrorMPT = new G4MaterialPropertiesTable();
381   AirMirrorMPT->AddProperty("REFLECTIVITY", XX, ICEREFLECTIVITY);
382   fReflectorOpticalSurface->SetMaterialPropertiesTable(AirMirrorMPT);
383 
384   new G4LogicalSkinSurface("ReflectorSurface",fReflectorLog,fReflectorOpticalSurface);
385 
386 #ifdef G4MULTITHREADED
387   auto runManager = G4MTRunManager::GetMasterRunManager();
388   //runManager->SetNumberOfThreads(2);
389 #else
390   auto runManager = G4RunManager::GetRunManager();
391 #endif
392 
393   runManager->GeometryHasBeenModified();
394 
395   fIsReflectorConstructed = true;
396 }
397 
398 
399 void UltraDetectorConstruction::SetReflectorOpticalProperties()
400 {
401   if (fReflectionType == "ground") {
402     G4cout << "Using ground reflecting surface " << G4endl ;
403     if (fReflectorOpticalSurface)
404       fReflectorOpticalSurface->SetFinish(groundfrontpainted);
405   }
406   else {
407     G4cout << "Using mirror reflecting surface " << G4endl ;
408     if (fReflectorOpticalSurface)
409       fReflectorOpticalSurface->SetFinish(polishedfrontpainted);
410   }
411 }
412 
413 
414 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
415 
416 void UltraDetectorConstruction::ConstructUVscope()
417 {
418 
419   //  ------------- Volumes --------------
420 
421   ////////////////////////////////////////////////////////////////////////////////////////////////////////
422 
423   G4cout << "#                                                    #" << G4endl ;
424   G4cout << "#           Building the Telescope    ...            #" << G4endl ;
425   G4cout << "#                                                    #" << G4endl ;
426 
427   /////////////////////////////////////////////////////////////
428   // UVscope housing is a cylinder made of 1 mm thick aluminum
429   /////////////////////////////////////////////////////////////
430 
431   auto UVscopeHeight    = 1030.0*mm ;
432   auto UVscopeDiameter  = 518.0*mm ;
433   auto UVscopeThickness = 1.0*mm   ;
434   auto UVscopeBaffle    = 514.0*mm ;
435 
436   auto UVscopeInnerRadius = UVscopeDiameter/2.0-UVscopeThickness ;
437   auto UVscopeOuterRadius = UVscopeDiameter/2.0 ;
438 
439   auto UVscopePosition = G4ThreeVector(0.0*m,0.0*m,-1.0*m) ;
440   auto Al = G4Material::GetMaterial("Aluminum");
441 
442   auto solidUVscope =
443     new G4Tubs("UVscopeSolid",UVscopeInnerRadius,UVscopeOuterRadius,UVscopeHeight/2.0,0.0,twopi) ;
444   auto logicUVscope =
445     new G4LogicalVolume(solidUVscope,Al,"UVscopeLV",0,0,0);
446   auto physicalUVscope =
447     new G4PVPlacement(0,UVscopePosition,"UVSCopePV",logicUVscope,fWorld_phys,false,0);
448 
449 
450   //////////////////////////////////////
451   // Back cover of the UVscope cylinder
452   //////////////////////////////////////
453 
454   auto solidUVscopeBack =
455     new G4Tubs("UVscopeBackSolid",0.0,UVscopeOuterRadius,UVscopeThickness/2.0,0.0,twopi) ;
456 
457   auto logicUVscopeBack =
458     new G4LogicalVolume(solidUVscopeBack,Al,"UVscopeBackLV",0,0,0);
459 
460   auto UVscopeBackPosition  =
461     UVscopePosition+G4ThreeVector(0.0*mm,0.0*mm,-(UVscopeHeight/2.0+UVscopeThickness/2.0)) ;
462   auto physicalUVscopeBack =
463     new G4PVPlacement(0,UVscopeBackPosition,"UVscopeBack",logicUVscopeBack,fWorld_phys,false,0);
464 
465   ////////////////////////////////////////////////////////////////////////////////////////////////////////
466 
467   G4cout << "#                                                    #" << G4endl ;
468   G4cout << "#           Building the Fresnel lens ...            #" << G4endl ;
469   G4cout << "#                                                    #" << G4endl ;
470 
471   auto      LensDiameter        = 457*mm ; // Size of the optical active area of the lens.
472   auto      LensNumOfGrooves    = 13 ;
473   //auto      LensNumOfGrooves    = 129 ;
474   //auto      LensNumOfGrooves    = 1287 ;
475 
476   auto      LensBorderThickness = 2.8*mm ;     // Thickness of the border area.
477   auto      LensFocalLength     = 441.973*mm ; // This parameter depends on the lens geometry, etc !!
478   auto      LensMaterial        = G4Material::GetMaterial("Acrylic") ;
479   auto      LensPosition        = UVscopePosition+G4ThreeVector(0.0*mm,0.0*mm,UVscopeHeight/2.0-UVscopeBaffle) ;
480 
481 
482   FresnelLens = new UltraFresnelLens(LensDiameter,LensNumOfGrooves,LensMaterial,fWorld_phys,LensPosition) ;
483 
484 
485   ///////////////////////////////////
486   // Lens supporting ring (aluminum)
487   ///////////////////////////////////
488 
489   auto solidLensFrame = new G4Tubs("LensFrame",LensDiameter/2.0,UVscopeInnerRadius,LensBorderThickness/2.0,0.0,twopi) ;
490   auto logicLensFrame = new G4LogicalVolume(solidLensFrame,Al,"LensFrameLV",0,0,0);
491 
492   auto LensFramePosition = LensPosition+G4ThreeVector(0.0*mm,0.0*mm,-((FresnelLens->GetThickness())/2.0+solidLensFrame->GetZHalfLength())) ;
493 
494   auto physicalLensFrame =
495     new G4PVPlacement(0,LensFramePosition,"LensFramePV",logicLensFrame,fWorld_phys,false,0);
496 
497   ////////////////////////////////////////////////////////////////////////////////////////////////////////
498 
499 
500   G4cout << "#                                                    #" << G4endl ;
501   G4cout << "#         Building the photomultiplier ...           #" << G4endl ;
502   G4cout << "#                                                    #" << G4endl ;
503 
504 
505   // Photomultiplier window is a spherical section made of quartz
506 
507   auto PMT_thick   =   1.0*mm ; // Thickness of PMT window
508   auto PMT_curv    =  65.5*mm ; // Radius of curvature of PMT window
509   auto StartTheta  = (180.0-31.2)*pi/180. ;
510   auto EndTheta    = 31.2*pi/180. ;
511 
512   auto solidPMT =
513     new G4Sphere("PMT_solid",PMT_curv-PMT_thick,PMT_curv,0.0,twopi,StartTheta,EndTheta);
514 
515   auto Quartz = G4Material::GetMaterial("Quartz");
516   logicalPMT = new G4LogicalVolume(solidPMT,Quartz,"PMT_log",0,0,0);
517 
518 
519   // Place PMT is at Lens Focus
520 
521   auto PMTpos = LensPosition + G4ThreeVector(0.0*cm,0.0*cm,-(LensFocalLength+PMT_curv)) ;
522 
523   // Rotate PMT window through the axis OX by an angle = 180. degrees
524 
525   auto PMTrot = new G4RotationMatrix(G4ThreeVector(1.0,0.0,0.0),pi);
526   new G4PVPlacement(PMTrot,PMTpos,"PMT1",logicalPMT,fWorld_phys,false,0);
527 
528 
529   auto PMTVisAtt   = new G4VisAttributes(true,G4Colour(0.0,0.0,1.0)) ;
530   logicalPMT->SetVisAttributes(PMTVisAtt);
531 
532   //////////////////////////////////////////////////////////////////////////////////////////
533   //   Optical properties of the interface between the Air and the walls of the
534   //   UVscope cylinder (5% reflectivity)
535 
536 
537   G4cout << "#    Defining interface's optical properties  ...    #" << G4endl ;
538   G4cout << "#                                                    #" << G4endl ;
539 
540 
541   auto OpticalAirPaint = new G4OpticalSurface("AirPaintSurface");
542   OpticalAirPaint->SetModel(unified);
543   OpticalAirPaint->SetType(dielectric_dielectric);
544   OpticalAirPaint->SetFinish(groundfrontpainted);
545 
546   std::vector<G4double> XX = {h_Planck*c_light/lambda_max, h_Planck*c_light/lambda_min} ;
547   std::vector<G4double> BLACKPAINTREFLECTIVITY      = { 0.05, 0.05 };
548   //std::vector<G4double> WHITEPAINTREFLECTIVITY      = { 0.99, 0.99 };
549 
550   auto AirPaintMPT = new G4MaterialPropertiesTable();
551   AirPaintMPT->AddProperty("REFLECTIVITY", XX, BLACKPAINTREFLECTIVITY);
552   OpticalAirPaint->SetMaterialPropertiesTable(AirPaintMPT);
553 
554   //OpticalAirPaint->DumpInfo();
555 
556   new G4LogicalBorderSurface("Air/UVscope Cylinder Surface",fWorld_phys,physicalUVscope,OpticalAirPaint);
557 
558   new G4LogicalBorderSurface("Air/LensFrame Surface",fWorld_phys,physicalLensFrame,OpticalAirPaint);
559 
560   new G4LogicalBorderSurface("Air/UVscope Back Cover Surface",fWorld_phys,physicalUVscopeBack,OpticalAirPaint);
561 
562 
563   /////////////////////////////////////////////////////////////////////////////////////
564 
565   auto LensVisAtt  = new G4VisAttributes(G4Colour(1.0,0.0,0.0)) ;   // Red
566   LensVisAtt ->SetVisibility(true);
567 
568 
569   if (FresnelLens){
570     FresnelLens->GetPhysicalVolume()->GetLogicalVolume()->SetVisAttributes(LensVisAtt);
571   }
572 
573   auto UVscopeVisAtt  = new G4VisAttributes(G4Colour(0.5,0.5,0.5)) ;   // Gray
574   UVscopeVisAtt ->SetVisibility(true);
575 
576   physicalUVscope     ->GetLogicalVolume()->SetVisAttributes(UVscopeVisAtt);
577   physicalUVscopeBack ->GetLogicalVolume()->SetVisAttributes(UVscopeVisAtt);
578   physicalLensFrame   ->GetLogicalVolume()->SetVisAttributes(UVscopeVisAtt);
579 
580   /////////////////////////////////////////////////////////////////////////////////////
581 
582   G4cout << "#                                                    #" << G4endl ;
583   G4cout << "#               UVscope is built ! ...               #" << G4endl ;
584   G4cout << "#                                                    #" << G4endl ;
585 
586 }
587 
588 
589 void UltraDetectorConstruction::SetReflectionType(G4String rtype)
590 {
591 #ifdef G4MULTITHREADED
592   auto runManager = G4MTRunManager::GetMasterRunManager();
593   //runManager->SetNumberOfThreads(2);
594 #else
595   auto runManager = G4RunManager::GetRunManager();
596 #endif
597 
598   fReflectionType = rtype;
599 
600   if (fReflectionType == "none") {
601     if (fIsReflectorConstructed) {
602       // Cleanup old geometry to delete reflecting surface
603       runManager->ReinitializeGeometry(true);
604     }
605   }
606   else {
607     if (!fIsReflectorConstructed) {
608       ConstructReflector();
609     }
610     SetReflectorOpticalProperties();
611   }
612 }
613