FDsimG4Camera.cc
Go to the documentation of this file.
1 #include "FDsimG4Camera.hh"
3 #include "FDsimG4CameraFoot.hh"
4 #include "FDsimG4Colours.hh"
5 
6 #include "FDsimG4Mercedes.hh"
7 #include "FDsimG4PMT.hh"
8 #include "FDsimG4PMT_SD.hh"
11 
12 #include "G4RunManager.hh"
13 #include "G4UnitsTable.hh"
14 #include "G4IntersectionSolid.hh"
15 #include "G4Box.hh"
16 #include "G4Sphere.hh"
17 
18 #include "G4LogicalSkinSurface.hh"
19 #include "G4SDManager.hh"
20 #include "G4Material.hh"
21 #include "G4MaterialTable.hh"
22 #include "G4Polyhedra.hh"
23 #include "G4BREPSolidPolyhedra.hh"
24 #include "G4LogicalVolume.hh"
25 #include "G4PVPlacement.hh"
26 #include "G4OpticalSurface.hh"
27 #include "G4LogicalBorderSurface.hh"
28 #include "G4ThreeVector.hh"
29 #include "G4VisAttributes.hh"
30 
31 #include <unconfig.h>
32 #include <utl/config.h>
33 #include "G4Version.hh"
34 
35 
36 using namespace TelescopeSimulatorLX;
37 using namespace std;
38 
39 
40 FDsimG4Camera::FDsimG4Camera(G4VPhysicalVolume* mother)
41 {
42  const G4RunManager* runManager = G4RunManager::GetRunManager();
43  const FDsimG4DetectorConstruction* DetectorConstruction =
44  dynamic_cast<const FDsimG4DetectorConstruction*>(runManager->GetUserDetectorConstruction());
45 
46  fCurvRadius = DetectorConstruction->fCameraRadiusCurvature;
47  fNumCols = DetectorConstruction->fCameraNCols;
48  fNumRows = DetectorConstruction->fCameraNRows;
49  fMercedesEfficiency = DetectorConstruction->fMercedesEfficiency;
50  fMERCEDESCOUNT=966;
51  fMotherPhysicalVolume = mother;
52  fVerbosity = DetectorConstruction->fVerbosityLevel;
53 
54  CheckParameters();
55  BuildCamera();
56 }
57 
58 
60 {
61 }
62 
63 
65 {
66 }
67 
68 
70 {
71 }
72 
73 
75 {
76  const G4int nMercedes_col = 42;
77  const G4double deltaAz = 1.5*pi/180.;
78  const G4double deltaEl = 1.5*pi/180.*cos(pi/6.);
79 
80  G4double TOLERANCE = FDsimG4DetectorConstruction::fgTOLERANCE;
81  G4double offsetAz = 10.*deltaAz;
82  // G4double offsetEl=(-28.6*pi/180./2.)-deltaEl;
83  G4double offsetEl = -(11.*deltaEl)-deltaEl-deltaEl/3;
84 
85  G4int i = 0;
86  G4int j = 0;
87  char mercedesname[32];
88  char pmtname[32];
89  G4double elevation,azimuth;
90  G4int numOfCopy = 0;
91 
92  G4ThreeVector PMTPos;
93  G4double PMT_thick = 0.0;
94  G4VPhysicalVolume* PMT_phys;
95  G4RotationMatrix* PMTRot;
96  FDsimG4PMT_SD* PMT_SD = NULL;
97  G4int colPMT;
98  G4int rowPMT;
99  G4int PMT_id;
100 
101  // Sensitive Detector Manager
102  G4SDManager* SDmanager = G4SDManager::GetSDMpointer();
103 
104  if(!PMT_SD){
105  PMT_SD = new FDsimG4PMT_SD("PMTSD");
106  SDmanager->AddNewDetector(PMT_SD);
107  }
108 
109  FDsimG4Mercedes* Mercedes = new FDsimG4Mercedes();
110  G4LogicalVolume* Mercedes_log = Mercedes->GetMercedesLogicalVolume();
111  G4double Mercedes_height = Mercedes->GetMercedesHeight();
112  G4PVPlacement* Mercedes_phys = NULL;
113 
114  // define mercedes - air optical surface
115 
116  G4OpticalSurface* OpticalAirMercedes = new G4OpticalSurface("MercedesSurface");
117  OpticalAirMercedes->SetModel(unified);
118  OpticalAirMercedes->SetType(dielectric_metal);
119 
120  G4MaterialPropertiesTable* MercedesMPT = new G4MaterialPropertiesTable();
121  G4double Efficiency = fMercedesEfficiency;
122  MercedesMPT->AddProperty("REFLECTIVITY", new G4MaterialPropertyVector());
123  MercedesMPT->AddEntry("REFLECTIVITY", 0.0*eV,Efficiency);
124  MercedesMPT->AddEntry("REFLECTIVITY",10.0*eV,Efficiency);
125 
126  OpticalAirMercedes->SetMaterialPropertiesTable(MercedesMPT);
127 
128  G4ThreeVector MercedesPos;
129  G4RotationMatrix* MercedesRot;
130  for(i=0; i<fMERCEDESCOUNT; i++){
131  sprintf(mercedesname,"Mercedes_%03i",i);
132 
133  // place Mercedes stars
134 
135  MercedesRot=new G4RotationMatrix();
136  MercedesRot->rotateZ(pi/2.0);
137 
138  G4int row = (G4int)floor((double)i/nMercedes_col);
139  G4int col= i%nMercedes_col;
140 
141  if(col == 0) offsetEl=offsetEl+deltaEl; // start new row
142  azimuth = col*deltaAz/2.;
143  if ((row%2 == 0 && col%2 == 0) || (row%2 != 0 && col%2 != 0))
144  {
145  elevation=offsetEl;
146  MercedesRot->rotateY(3.0*pi/2.0); // inverted mercedes : Y
147  // place Mercedes tangent to camera plane
148  MercedesRot->rotateZ(((-offsetAz)+azimuth));
149  MercedesRot->rotateX(elevation);
150  }
151  else
152  {
153  elevation=offsetEl+deltaEl/3.;
154  MercedesRot->rotateY(pi/2.0); // mercedes
155  // place Mercedes tangent to camera plane
156  MercedesRot->rotateZ(offsetAz-azimuth);
157  MercedesRot->rotateX(-elevation);
158  }
159 
160  MercedesPos.setRThetaPhi(fCurvRadius,(pi/2.-offsetAz)+azimuth,elevation);
161  Mercedes_phys =
162  new G4PVPlacement(MercedesRot,MercedesPos,mercedesname,
163  Mercedes_log,fMotherPhysicalVolume,false,numOfCopy++);
164 
165 #if (G4VERSION_NUMBER>=800)
166  if (fVerbosity > 2 && Mercedes_phys)
167  Mercedes_phys->CheckOverlaps(10000);
168 #endif
169 
170  if (Mercedes_phys)
171  new G4LogicalBorderSurface("MercedesSurface",
172  fMotherPhysicalVolume,Mercedes_phys,OpticalAirMercedes);
173 
174  // place PMTs
175 
176  if (row != 22 && col < 40) {
177  if ((row%2 != 0 && col%2 ==0) || (row%2 ==0 && col%2!=0)){
178  j=j+1;
179 
180  // colPMT and rowPMT start at 0
181 
182  if (row%2 != 0)
183  colPMT = col;
184  else
185  colPMT = col-1;
186 
187  colPMT = G4int(colPMT/2.);
188  rowPMT = row;
189 
190  PMT_id = fNumRows*(colPMT)+rowPMT+1;
191  sprintf(pmtname,"PMT_%03i",PMT_id);
192 
193  FDsimG4PMT* PMT = new FDsimG4PMT(pmtname);
194  G4LogicalVolume* PMT_log = PMT->GetPMTLogicalVolume();
195  PMT_thick = PMT->GetThickness();
196 
197  PMTRot = new G4RotationMatrix();
198  PMTRot->rotateY(pi/2.0);
199  PMTRot->rotateZ(pi/2.0);
200  // place PMT tangent to camera plane
201  PMTRot->rotateX((-offsetAz)+azimuth+deltaAz/2.);
202  PMTRot->rotateY(-offsetEl-2*deltaEl/3.);
203 
204  PMTPos.setRThetaPhi(fCurvRadius-Mercedes_height-PMT_thick/2.- 1.0*mm,
205  (pi/2.-offsetAz)+azimuth+deltaAz/2.,
206  offsetEl+2*deltaEl/3.);
207  PMT_phys =
208  new G4PVPlacement(PMTRot,PMTPos,pmtname,PMT_log,fMotherPhysicalVolume,false,PMT_id);
209 #if (G4VERSION_NUMBER>=800)
210  if (fVerbosity > 2 && PMT_phys)
211  PMT_phys->CheckOverlaps(10000);
212 #endif
213  if (PMT_log && PMT_SD) PMT_log->SetSensitiveDetector(PMT_SD);
214  if (PMT_log){
215  PMT_log->SetVisAttributes(new G4VisAttributes(yellow));
216  if(j==1)
217  PMT_log->SetVisAttributes(new G4VisAttributes(magenta));
218  }
219  delete PMT;
220  }
221  }
222  } // end of loop on mercedes
223 
224  delete Mercedes;
225 
226  G4VPhysicalVolume* Support_phys = NULL;
227  G4VPhysicalVolume* Foot1_phys = NULL;
228  G4VPhysicalVolume* Foot2_phys = NULL;
229  G4VPhysicalVolume* Electronics_phys = NULL;
230 
231  // Place camera support
232 
233  G4double SupportPlaceX = fCurvRadius-Mercedes_height-PMT_thick - 1.0*mm;
234 
235  FDsimG4CameraSupport* Support =
236  new FDsimG4CameraSupport(SupportPlaceX-TOLERANCE*5.);
237  G4LogicalVolume* Support_log =
238  Support->GetCameraSupportLogicalVolume();
239  G4RotationMatrix* SupportRot =
240  new G4RotationMatrix(G4ThreeVector(0.,0.,1.),pi/2.0);
241 
242  Support_phys =
243  new G4PVPlacement(SupportRot,G4ThreeVector(),"CameraSupport",Support_log,
244  fMotherPhysicalVolume,false,0);
245 
246  // Place camera feet
247 
248  FDsimG4CameraFoot* Foot = new FDsimG4CameraFoot();
249  G4LogicalVolume* Foot_log = Foot->GetCameraFootLogicalVolume();
250 
251  G4double dx=
252  SupportPlaceX-(Support->GetThickness())-(Foot->GetFootSide())/2.;
253 
254  G4double angle = std::atan((Support->GetHside())/2./fCurvRadius);
255  G4double FromCamera=22.58*cm;
256  dx = dx - FromCamera*std::cos(angle);
257 
258  G4double dz = (Support->GetHside())/2.;
259  dz = dz - FromCamera*std::sin(angle);
260 
261  G4ThreeVector FootPlace1 = G4ThreeVector(dx,0.,dz);
262  G4ThreeVector FootPlace2 = G4ThreeVector(dx,0.,-dz);
263 
264  G4RotationMatrix* rot1 = new G4RotationMatrix(G4ThreeVector(1.,0.,0.),pi);
265  G4RotationMatrix* rot2 = new G4RotationMatrix(G4ThreeVector(1.,0.,0.),pi);
266 
267  Foot1_phys = new G4PVPlacement(rot1,FootPlace1,"CameraFoot1",Foot_log,
268  fMotherPhysicalVolume,false,0);
269  Foot2_phys = new G4PVPlacement(rot2,FootPlace2,"CameraFoot2",Foot_log,
270  fMotherPhysicalVolume,false,1);
271 
272  // Place electronics box
273 
274  G4double dxEl = Foot->GetFootSide()+20*cm;
275  G4double dyEl = Foot->GetTopSide();
276  G4double dzEl = 2.0*((Support->GetHside())/2. -
277  FromCamera*std::sin(angle)-Foot->GetFootThick());
278 
279  G4Box* Electronics = new G4Box("Top",dxEl/2.,dyEl/2.,dzEl/2.);
280 
281  const G4Material* ElectronicsMaterial = G4Material::GetMaterial("Aluminum");
282 
283  G4LogicalVolume* Electronics_log =
284  new G4LogicalVolume(Electronics,(G4Material*)ElectronicsMaterial,"CameraElectronics",0,0,0);
285 
286  Electronics_log->SetVisAttributes(new G4VisAttributes(gray));
287 
288  // surface proprieties
289  G4OpticalSurface* OpticalAirCameraElect= new G4OpticalSurface("CameraElectSurface");
290  OpticalAirCameraElect->SetModel(unified);
291  OpticalAirCameraElect->SetType(dielectric_metal);
292 
293  G4MaterialPropertiesTable* CameraElectMPT = new G4MaterialPropertiesTable();
294  CameraElectMPT->AddProperty("REFLECTIVITY", new G4MaterialPropertyVector());
295  CameraElectMPT->AddEntry("REFLECTIVITY", 0.0*eV,0.);
296  CameraElectMPT->AddEntry("REFLECTIVITY",10.0*eV,0.);
297  OpticalAirCameraElect->SetMaterialPropertiesTable(CameraElectMPT);
298 
299  new G4LogicalSkinSurface("CameraElectSurface",Electronics_log,OpticalAirCameraElect);
300  G4ThreeVector ElPlace=G4ThreeVector(dx,0.,0.);
301  Electronics_phys =
302  new G4PVPlacement(0,ElPlace,"CameraElectronics",Electronics_log,
303  fMotherPhysicalVolume,false,0);
304 
305 #if (G4VERSION_NUMBER>=800)
306  if (fVerbosity > 2){
307  if (Support_phys) Support_phys->CheckOverlaps(10000);
308  if (Foot1_phys) Foot1_phys->CheckOverlaps(10000);
309  if (Foot2_phys) Foot2_phys->CheckOverlaps(10000);
310  if (Electronics_phys) Electronics_phys->CheckOverlaps(10000);
311  }
312 #endif
313 
314 
315 
316  G4bool useSD =
317  (dynamic_cast<const FDsimG4DetectorConstruction*>((G4RunManager::GetRunManager())->GetUserDetectorConstruction()))->fUseSensitiveDetectors;
318 
319  if(useSD){
320  // Define a virtual focal surface
321  G4double rMax = fCurvRadius + 0.5*mm;
322  G4double rMin = rMax - 0.1*mm;
323  G4double ThetaMin = Support->GetThetaMin();
324  G4double ThetaMax = Support->GetThetaMax();
325  G4double PhiMin = Support->GetPhiMin();
326  G4double PhiMax = Support->GetPhiMax();
327 
328  G4Material* Material = fMotherPhysicalVolume->GetLogicalVolume()->GetMaterial();
329  G4Sphere* FocalSurf =
330  new G4Sphere("sphere",rMin,rMax,ThetaMin,ThetaMax,PhiMin,PhiMax);
331 
332  G4LogicalVolume* FocalSurface_log =
333  new G4LogicalVolume(FocalSurf,Material,"VirtualFocalSurface",0,0,0);
334 
335  G4VPhysicalVolume* FocalSurface_phys = NULL;
336  FocalSurface_phys =
337  new G4PVPlacement(SupportRot,G4ThreeVector(),"VirtualFocalSurface",
338  FocalSurface_log, fMotherPhysicalVolume,false,0);
339 
340  FocalSurface_log->SetVisAttributes(new G4VisAttributes(yellow));
341  FDsimG4FocalSurfaceSD* FocalSurfaceSD = new FDsimG4FocalSurfaceSD("FocalSurfaceSD");
342  SDmanager->AddNewDetector(FocalSurfaceSD);
343  FocalSurface_log->SetSensitiveDetector(FocalSurfaceSD);
344 
345 #if (G4VERSION_NUMBER>=800)
346  if (fVerbosity > 2 && FocalSurface_phys)
347  FocalSurface_phys->CheckOverlaps(10000);
348 #endif
349 
350  }
351 
352 
353 }
G4LogicalVolume * GetPMTLogicalVolume() const
Definition: FDsimG4PMT.hh:20
const double eV
Definition: GalacticUnits.h:35
constexpr double mm
Definition: AugerUnits.h:113
G4LogicalVolume * GetMercedesLogicalVolume() const
static const G4Colour gray(0.5, 0.5, 0.5)
static const G4Colour magenta(1.0, 0.5, 1.0)
G4LogicalVolume * GetCameraSupportLogicalVolume() const
G4double GetThickness() const
Definition: FDsimG4PMT.hh:22
G4LogicalVolume * GetCameraFootLogicalVolume() const
constexpr double cm
Definition: AugerUnits.h:117
static const G4Colour yellow(1.0, 1.0, 0.5)

, generated on Tue Sep 26 2023.