WCSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
WCSimConstructPMT.cc
Go to the documentation of this file.
2 
3 #include "G4Box.hh"
4 #include "G4Sphere.hh"
5 #include "G4SubtractionSolid.hh"
6 #include "G4LogicalVolume.hh"
7 #include "G4VisAttributes.hh"
8 #include "G4Material.hh"
9 #include "G4Polycone.hh"
10 #include "G4PVPlacement.hh"
11 #include "G4LogicalBorderSurface.hh"
12 
13 #include "G4SDManager.hh"
14 #include "WCSimWCSD.hh"
15 #include "WCSimPMTObject.hh"
16 
17 #include "G4SystemOfUnits.hh"
18 #include "WCSimLC.hh"
19 #include "G4NistManager.hh"
20 
21 //PMT logical volume construction.
22 
24 
25 G4LogicalVolume* WCSimDetectorConstruction::ConstructPMT(G4String PMTName, G4String CollectionName, G4String detectorElement)
26 {
27  PMTKey_t key(PMTName,CollectionName);
28 
29  PMTMap_t::iterator it = PMTLogicalVolumes.find(key);
30  if (it != PMTLogicalVolumes.end()) {
31  //G4cout << "Restore PMT" << G4endl;
32  return it->second;
33  }
34 
35  //G4cout << "Create PMT" << G4endl;
36 
37 
38 if (Vis_Choice == "RayTracer"){
39  // Blue wireframe visual style
40  // Used in the RayTracer visualizer
41  G4VisAttributes* WCPMTVisAtt = new G4VisAttributes(G4Colour(0.0,0.0,1.0));
42  WCPMTVisAtt->SetForceSolid(true); // force the object to be visualized with a surface
43  WCPMTVisAtt->SetForceAuxEdgeVisible(true); // force auxiliary edges to be shown
44 }
45 
46 else
47  { // Gray wireframe visual style
48  // used in OGLSX visualizer
49  G4VisAttributes* WCPMTVisAtt;
50  if(detectorElement == "OD") WCPMTVisAtt = new G4VisAttributes(G4Colour(1.0, 0.0, 0.0));
51  else WCPMTVisAtt = new G4VisAttributes(G4Colour(0.2,0.2,0.2));
52  WCPMTVisAtt->SetForceWireframe(true);}
53 
54  G4double expose;
55  G4double radius;
56  G4double glassThickness;
57 
58  WCSimPMTObject *PMT = GetPMTPointer(CollectionName);
59  expose = PMT->GetExposeHeight();
60  radius = PMT->GetRadius();
61  glassThickness = PMT->GetPMTGlassThickness();
62 
63  G4double sphereRadius = (expose*expose+ radius*radius)/(2*expose);
64  G4double PMTOffset = sphereRadius - expose;
65 
66  //All components of the PMT are now contained in a single logical volume logicWCPMT.
67  //Origin is on the blacksheet, faces positive z-direction.
68 
69  G4double PMTHolderZ[2] = {0, expose};
70  G4double PMTHolderR[2] = {radius, radius};
71  G4double PMTHolderr[2] = {0,0};
72 
73  G4int lightcollector;
74  lightcollector = GetLCType();
75  WCSimLC *logicLightCone = NULL;
76  if (0 < lightcollector && lightcollector < 3){
77  G4cout<<"Building Light Collectors"<<G4endl;
78  G4NistManager* man = G4NistManager::Instance();
79  G4Material* conc_material = man->FindOrBuildMaterial("G4_PLEXIGLASS");
80  logicLightCone = new WCSimLC("LC", conc_material, lightcollector);
81 
82  PMTHolderZ[0] = 0;
83  PMTHolderZ[1] = expose+logicLightCone->GetHeight()-logicLightCone->GetOffset();
84  PMTHolderR[0] = std::max(radius,logicLightCone->GetRadius()+.1);
85  PMTHolderR[1] = std::max(radius,logicLightCone->GetRadius()+.1);//+.1mm for extra space
86  }
87  else if (lightcollector!=0){
88  G4cout<<"Wrong Light Collectors ID is specified!"<<G4endl;
89  }
90 
91  G4Polycone* solidWCPMT =
92  new G4Polycone("WCPMT",
93  0.0*deg,
94  360.0*deg,
95  2,
96  PMTHolderZ,
97  PMTHolderr, // R Inner
98  PMTHolderR);// R Outer
99 
100 
101  G4LogicalVolume* logicWCPMT =
102  new G4LogicalVolume( solidWCPMT,
103  G4Material::GetMaterial("Water"),
104  "WCPMT",
105  0,0,0);
106 
107 if (Vis_Choice == "RayTracer"){
108 // Makes the volume containing the PMT visible, solid, and forces the auxiliary edges to be viewed.
109  G4VisAttributes* WCPMTVisAtt = new G4VisAttributes(G4Colour(0.0,0.0,1.0));
110  WCPMTVisAtt->SetForceSolid(true); // force the object to be visualized with a surface
111  WCPMTVisAtt->SetForceAuxEdgeVisible(true); // force auxiliary edges to be shown
112 
113  logicWCPMT->SetVisAttributes(WCPMTVisAtt);}
114 
115 else{
116 // Makes the volume containg the PMT invisible for normal visualization
117  logicWCPMT->SetVisAttributes(G4VisAttributes::Invisible);}
118 
119  //Need a volume to cut away excess behind blacksheet
120  G4Box* solidCutOffTubs =
121  new G4Box( "cutOffTubs",
122  sphereRadius+1.*cm,
123  sphereRadius+1.*cm,
124  PMTOffset);
125 
126 
127  //Create PMT Interior
128  G4Sphere* tmpSolidInteriorWCPMT =
129  new G4Sphere( "tmpInteriorWCPMT",
130  0.0*m,(sphereRadius-glassThickness),
131  0.0*deg,360.0*deg,
132  0.0*deg,90.0*deg);
133 
134  G4SubtractionSolid* solidInteriorWCPMT =
135  new G4SubtractionSolid( "InteriorWCPMT",
136  tmpSolidInteriorWCPMT,
137  solidCutOffTubs);
138 
139  // "Air" here is not true air, but a modified material
140  // with n = 1 and a very short absorption length
141  G4LogicalVolume* logicInteriorWCPMT =
142  new G4LogicalVolume( solidInteriorWCPMT,
143  G4Material::GetMaterial("Air"),
144  "InteriorWCPMT",
145  0,0,0);
146 
147  G4VPhysicalVolume* physiInteriorWCPMT =
148  new G4PVPlacement(0,
149  G4ThreeVector(0, 0, -1.0*PMTOffset),
150  logicInteriorWCPMT,
151  "InteriorWCPMT",
152  logicWCPMT,
153  false,
154  0,
155  checkOverlaps);
156 
157 if (Vis_Choice == "RayTracer"){
158 // Adding color and forcing the inner portion of the PMT's to be viewed
159  G4VisAttributes* WCPMTVisAtt = new G4VisAttributes(G4Colour(0.0,0.0,1.0));
160  WCPMTVisAtt->SetForceSolid(true); // force the object to be visualized with a surface
161  WCPMTVisAtt->SetForceAuxEdgeVisible(true); // force auxiliary edges to be shown
162 
163  logicInteriorWCPMT->SetVisAttributes(WCPMTVisAtt);}
164 
165 else {
166 // Making the inner portion of the detector invisible for OGLSX visualization
167  logicInteriorWCPMT->SetVisAttributes(G4VisAttributes::Invisible);}
168 
169 
170  //Create PMT Glass Face
171  G4Sphere* tmpGlassFaceWCPMT =
172  new G4Sphere( "tmpGlassFaceWCPMT",
173  (sphereRadius-glassThickness),
174  sphereRadius,
175  0.0*deg,360.0*deg,
176  0.0*deg,90.0*deg);
177 
178  G4SubtractionSolid* solidGlassFaceWCPMT =
179  new G4SubtractionSolid( CollectionName,
180  tmpGlassFaceWCPMT,
181  solidCutOffTubs);
182 
183  G4LogicalVolume *logicGlassFaceWCPMT =
184  new G4LogicalVolume( solidGlassFaceWCPMT,
185  G4Material::GetMaterial("Glass"),
186  CollectionName,
187  0,0,0);
188 
189  G4VPhysicalVolume* physiGlassFaceWCPMT =
190  new G4PVPlacement(0,
191  G4ThreeVector(0, 0, -1.0*PMTOffset),
192  logicGlassFaceWCPMT,
193  CollectionName,
194  logicWCPMT,
195  false,
196  0,
197  checkOverlaps);
198 
199  //*Ugly implementation for Light Cone T.Y. 2018.2.13
200  if (0 < lightcollector && lightcollector < 3){
201  G4cout<<"Registering Light Collectors"<<G4endl;
202  G4VPhysicalVolume* physiLightCone =
203  new G4PVPlacement(0,
204  G4ThreeVector(0, 0, -1.0*logicLightCone->GetOffset()),
205  logicLightCone,
206  "LightConeWCPMT",
207  logicWCPMT,
208  false,
209  0,
210  checkOverlaps);
211  G4cout<<"Registering Light Collectors Done"<<G4endl;
212  }
213  //*Ugly implementation for Light Cone T.Y. 2018.2.13
214 
215 // For either visualization type, logicGlassFaceWCPMT will either be visible or invisible depending on which
216 // line is commented at the end of the respective if statements
217 
218  if (Vis_Choice == "OGLSX")
219  { // Gray wireframe visual style
220  // used in OGLSX visualizer
221  G4VisAttributes* WCPMTVisAtt;
222  if(detectorElement == "OD") WCPMTVisAtt = new G4VisAttributes(G4Colour(1.0, 0.0, 0.0));
223  else WCPMTVisAtt = new G4VisAttributes(G4Colour(0.2,0.2,0.2));
224  WCPMTVisAtt->SetForceWireframe(true);
225  //logicGlassFaceWCPMT->SetVisAttributes(G4VisAttributes::Invisible);
226  logicGlassFaceWCPMT->SetVisAttributes(WCPMTVisAtt);
227  G4VisAttributes* WCLCVisAtt = new G4VisAttributes(G4Colour(.3,.3,0.));
228  WCLCVisAtt->SetForceWireframe(true);
229  WCLCVisAtt->SetForceAuxEdgeVisible(true);
230  //WCLCVisAtt->SetForceSolid(true);
231  //logicLightCone->SetVisAttributes(G4VisAttributes::Invisible);
232  if (logicLightCone!=NULL)
233  logicLightCone->SetVisAttributes(WCLCVisAtt);
234  }
235 
236  if (Vis_Choice == "RayTracer"){
237  // Blue wireframe visual style
238  // Used in the RayTracer visualizer
239  G4VisAttributes* WCPMTVisAtt = new G4VisAttributes(G4Colour(0.0,0.0,1.0));
240  WCPMTVisAtt->SetForceSolid(true); // force the object to be visualized with a surface
241  WCPMTVisAtt->SetForceAuxEdgeVisible(true); // force auxiliary edges to be shown
242  //logicGlassFaceWCPMT->SetVisAttributes(G4VisAttributes::Invisible);
243 
244  logicGlassFaceWCPMT->SetVisAttributes(WCPMTVisAtt);}
245 
246  else
247  { // Gray wireframe visual style
248  // used in OGLSX visualizer
249  G4VisAttributes* WCPMTVisAtt;
250  if(detectorElement == "OD") WCPMTVisAtt = new G4VisAttributes(G4Colour(1.0, 0.0, 0.0));
251  else WCPMTVisAtt = new G4VisAttributes(G4Colour(0.2,0.2,0.2));
252  WCPMTVisAtt->SetForceWireframe(true);
253  //logicGlassFaceWCPMT->SetVisAttributes(G4VisAttributes::Invisible);
254  logicGlassFaceWCPMT->SetVisAttributes(WCPMTVisAtt);}
255 
256  // Instantiate a new sensitive detector
257  // and register this sensitive detector volume with the SD Manager.
258  G4SDManager* SDman = G4SDManager::GetSDMpointer();
259  G4String SDName = "/WCSim/";
260  SDName += CollectionName;
261 
262  // If there is no such sensitive detector with that SDName yet,
263  // make a new one
264  if( ! SDman->FindSensitiveDetector(SDName, false) ) {
265 
266  aWCPMT = new WCSimWCSD(CollectionName,SDName,this,detectorElement);
267  SDman->AddNewDetector( aWCPMT );
268  }
269 
270  logicGlassFaceWCPMT->SetSensitiveDetector( aWCPMT );
271 
272  PMTLogicalVolumes[key] = logicWCPMT;
273 
274  //Add Logical Border Surface
275  new G4LogicalBorderSurface("GlassCathodeSurface",
276  physiGlassFaceWCPMT,
277  physiInteriorWCPMT,
279 
280  return logicWCPMT;
281 }
G4LogicalVolume * ConstructPMT(G4String, G4String, G4String detectorElement="tank")
G4double GetRadius()
Definition: WCSimLC.cc:161
WCSimPMTObject * GetPMTPointer(G4String CollectionName)
G4double GetOffset()
Definition: WCSimLC.cc:166
std::map< PMTKey_t, G4LogicalVolume * > PMTMap_t
G4double GetHeight()
Definition: WCSimLC.cc:156
virtual G4double GetExposeHeight()=0
virtual G4double GetRadius()=0
virtual G4double GetPMTGlassThickness()=0
std::pair< G4String, G4String > PMTKey_t