Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
WLSDetectorConstruction.cc
Go to the documentation of this file.
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 //
28 //
29 //
30 //
31 
32 #include "G4ios.hh"
33 #include "globals.hh"
34 
35 #include "G4Box.hh"
36 #include "G4Tubs.hh"
37 #include "G4EllipticalTube.hh"
38 
39 #include "G4LogicalVolume.hh"
40 #include "G4PVPlacement.hh"
41 
42 #include "G4OpBoundaryProcess.hh"
44 
45 #include "G4Material.hh"
46 #include "G4NistManager.hh"
47 
48 #include "G4GeometryManager.hh"
49 #include "G4SDManager.hh"
50 
51 #include "G4SolidStore.hh"
52 #include "G4RegionStore.hh"
53 #include "G4LogicalVolumeStore.hh"
54 #include "G4PhysicalVolumeStore.hh"
55 
56 #include "G4RunManager.hh"
57 
59 #include "WLSDetectorMessenger.hh"
60 #include "WLSMaterials.hh"
61 #include "WLSPhotonDetSD.hh"
62 
63 #include "G4UserLimits.hh"
64 #include "G4PhysicalConstants.hh"
65 #include "G4SystemOfUnits.hh"
66 
67 WLSPhotonDetSD* WLSDetectorConstruction::mppcSD = NULL;
68 
70  : physiWorld(NULL)
71 {
72 
73  detectorMessenger = new WLSDetectorMessenger(this);
74  materials = NULL;
75 
76  numOfCladLayers = 0;
77 
78  surfaceRoughness = 1;
79 
80  mirrorToggle = true;
81  mirrorPolish = 1.;
82  mirrorReflectivity = 1.;
83 
84  mppcPolish = 1.;
85  mppcReflectivity = 0.;
86 
87  extrusionPolish = 1.;
88  extrusionReflectivity = 1.;
89 
90  XYRatio = 1.0;
91 
92  wlsfiberZ = 1.*m;
93  wlsfiberRY = 0.5*mm;
94  wlsfiberOrigin = 0.0;
95 
96  mppcShape = "Circle";
97  mppcHalfL = wlsfiberRY;
98  mppcDist = 0.00*mm;
99  mppcTheta = 0.0*deg;
100  mppcZ = 0.05*mm;
101 
102  clrfiberZ = mppcZ + 10.*nm ;
103  mirrorZ = 0.1*mm;
104 
105  barLength = 1.*m;
106  barBase = 9.6*mm;
107  holeRadius = 0.9*mm;
108  holeLength = barLength;
109  coatingThickness = 0.25*mm;
110  coatingRadius = 1.875*mm;
111 
112  UpdateGeometryParameters();
113 }
114 
116 {
117  if (detectorMessenger) delete detectorMessenger;
118  if (materials) delete materials;
119 }
120 
122 {
123  materials = WLSMaterials::GetInstance();
124 
125  return ConstructDetector();
126 }
127 
129 {
130  //--------------------------------------------------
131  // World
132  //--------------------------------------------------
133 
134  G4VSolid* solidWorld =
135  new G4Box("World", worldSizeX, worldSizeY, worldSizeZ);
136 
137  logicWorld = new G4LogicalVolume(solidWorld,
138  FindMaterial("G4_AIR"),
139  "World");
140 
141  physiWorld = new G4PVPlacement(0,
142  G4ThreeVector(),
143  logicWorld,
144  "World",
145  0,
146  false,
147  0);
148 
149  //--------------------------------------------------
150  // Extrusion
151  //--------------------------------------------------
152 
153  G4VSolid* solidExtrusion =
154  new G4Box("Extrusion",GetBarBase()/2,GetBarBase()/2,GetBarLength()/2);
155 
156  G4LogicalVolume* logicExtrusion =
157  new G4LogicalVolume(solidExtrusion,
158  FindMaterial("Coating"),
159  "Extrusion");
160 
161  G4OpticalSurface* TiO2Surface = new G4OpticalSurface("TiO2Surface",
162  glisur,
163  ground,
165  extrusionPolish);
166 
167  G4MaterialPropertiesTable* TiO2SurfaceProperty =
169 
170  G4double p_TiO2[2] = {2.00*eV, 3.47*eV};
171  G4double refl_TiO2[2] = {extrusionReflectivity,extrusionReflectivity};
172  G4double effi_TiO2[2] = {0, 0};
173 
174  TiO2SurfaceProperty -> AddProperty("REFLECTIVITY",p_TiO2,refl_TiO2,2);
175  TiO2SurfaceProperty -> AddProperty("EFFICIENCY",p_TiO2,effi_TiO2,2);
176 
177  TiO2Surface -> SetMaterialPropertiesTable(TiO2SurfaceProperty);
178 
179  new G4PVPlacement(0,
180  G4ThreeVector(),
181  logicExtrusion,
182  "Extrusion",
183  logicWorld,
184  false,
185  0);
186 
187  new G4LogicalSkinSurface("TiO2Surface",logicExtrusion,TiO2Surface);
188 
189  //--------------------------------------------------
190  // Scintillator
191  //--------------------------------------------------
192 
193  G4VSolid* solidScintillator = new G4Box("Scintillator",
195  -GetCoatingRadius(),
197  -GetCoatingRadius(),
198  GetBarLength()/2);
199 
200  G4LogicalVolume* logicScintillator =
201  new G4LogicalVolume(solidScintillator,
202  FindMaterial("Polystyrene"),
203  "Scintillator");
204 
205  new G4PVPlacement(0,
206  G4ThreeVector(),
207  logicScintillator,
208  "Scintillator",
209  logicExtrusion,
210  false,
211  0);
212 
213  if (GetCoatingRadius() > 0.*mm) {
214  G4VSolid* solidScintside = new G4Box("SideOfBar",
216  -GetCoatingRadius(),
217  GetCoatingRadius()/2,
218  GetBarLength()/2);
219  G4VSolid* solidScintcrnr = new G4Tubs("CrnrOfBar",
220  0.0*cm,
222  GetBarLength()/2,
223  0.*deg,
224  90.*deg);
225  G4LogicalVolume* logicScintSide =
226  new G4LogicalVolume(solidScintside,
227  FindMaterial("Polystyrene"),
228  "SideOfBar");
229 
230  G4LogicalVolume* logicScintCrnr =
231  new G4LogicalVolume(solidScintcrnr,
232  FindMaterial("Polystyrene"),
233  "CrnrOfBar");
234 
237 
238  new G4PVPlacement(0,
239  G4ThreeVector(0,-y,0),
240  logicScintSide,
241  "SideOfBar",
242  logicExtrusion,
243  false,
244  0);
245  new G4PVPlacement(0,
246  G4ThreeVector(0, y,0),
247  logicScintSide,
248  "SideOfBar",
249  logicExtrusion,
250  false,
251  1);
252 
253  G4RotationMatrix* g4rot = new G4RotationMatrix();
254  *g4rot = stringToRotationMatrix("Z90");
255  *g4rot = g4rot->inverse();
256  if (*g4rot == G4RotationMatrix()) g4rot = NULL;
257 
258  new G4PVPlacement(g4rot,
259  G4ThreeVector(x,0,0),
260  logicScintSide,
261  "SideOfBar",
262  logicExtrusion,
263  false,
264  2);
265  new G4PVPlacement(g4rot,
266  G4ThreeVector(-x,0,0),
267  logicScintSide,
268  "SideOfBar",
269  logicExtrusion,
270  false,
271  3);
272 
275 
276  new G4PVPlacement(0,
277  G4ThreeVector(x,y,0),
278  logicScintCrnr,
279  "CrnrOfBar",
280  logicExtrusion,
281  false,
282  0);
283 
284  new G4PVPlacement(g4rot,
285  G4ThreeVector(-x,y,0),
286  logicScintCrnr,
287  "CrnrOfBar",
288  logicExtrusion,
289  false,
290  1);
291 
292  g4rot = new G4RotationMatrix();
293  *g4rot = stringToRotationMatrix("Z180");
294  *g4rot = g4rot->inverse();
295  if (*g4rot == G4RotationMatrix()) g4rot = NULL;
296 
297  new G4PVPlacement(g4rot,
298  G4ThreeVector(-x,-y,0),
299  logicScintCrnr,
300  "CrnrOfBar",
301  logicExtrusion,
302  false,
303  2);
304 
305  g4rot = new G4RotationMatrix();
306  *g4rot = stringToRotationMatrix("Z270");
307  *g4rot = g4rot->inverse();
308  if (*g4rot == G4RotationMatrix()) g4rot = NULL;
309 
310  new G4PVPlacement(g4rot,
311  G4ThreeVector(x,-y,0),
312  logicScintCrnr,
313  "CrnrOfBar",
314  logicExtrusion,
315  false,
316  3);
317 
318  }
319 
320  if (GetFiberRadius()<GetHoleRadius()) {
321 
322  G4VSolid* solidHole = new G4Tubs("Hole",
323  0.0*cm,
324  GetHoleRadius(),
325  GetHoleLength()/2,
326  0.*deg,
327  360.*deg);
328  logicHole = new G4LogicalVolume(solidHole,
329  FindMaterial("G4_AIR"),
330  "Hole");
331 
332  physiHole = new G4PVPlacement(0,
333  G4ThreeVector(),
334  logicHole,
335  "Hole",
336  logicScintillator,
337  false,
338  0);
339  }
340 
341  //--------------------------------------------------
342  // Fiber
343  //--------------------------------------------------
344 
345  ConstructFiber();
346 
347  //--------------------------------------------------
348  // End of Construction
349  //--------------------------------------------------
350 
351  return physiWorld;
352 }
353 
354 void WLSDetectorConstruction::ConstructFiber()
355 {
356  if (!(logicHole) || !(physiHole) ) {
357  std::ostringstream o;
358  o << "The Fiber Hole has not been constructed";
359  G4Exception("WLSDetectorConstruction::ConstructFiber","",
360  FatalException,o.str().c_str());
361  }
362 
363  // Pointers to the most recently constructed volume
364  G4LogicalVolume* logicPlacement = logicHole;
365  G4VPhysicalVolume* physiPlacement = physiHole;
366 
367  //--------------------------------------------------
368  // Fiber Construction
369  //--------------------------------------------------
370 
371  // Boundary Surface Properties
372  G4OpticalSurface* OpSurface = NULL;
373 
374  if (surfaceRoughness < 1.)
375  OpSurface = new G4OpticalSurface("RoughSurface", // Surface Name
376  glisur, // SetModel
377  ground, // SetFinish
378  dielectric_dielectric, // SetType
379  surfaceRoughness); // SetPolish
380 
381  G4LogicalVolume *logicClad1, *logicClad2;
382  G4VPhysicalVolume *physiClad1, *physiClad2;
383 
384  // Determine the number of cladding layers to be built
385  switch ( numOfCladLayers ) {
386 
387  case 2:
388 
389  //--------------------------------------------------
390  // Cladding 2
391  //--------------------------------------------------
392 
393  G4VSolid* solidClad2;
394 
395  if (XYRatio == 1.)
396  solidClad2 = new G4Tubs("Clad2",0.,clad2RX,clad2Z,0.0*rad,twopi*rad);
397  else
398  solidClad2 = new G4EllipticalTube("Clad2",clad2RX,clad2RY,clad2Z);
399 
400  logicClad2 = new G4LogicalVolume(solidClad2,
401  FindMaterial("FPethylene"),
402  "Clad2");
403 
404  physiClad2 = new G4PVPlacement(0,
405  G4ThreeVector(0.0,0.0,wlsfiberOrigin),
406  logicClad2,
407  "Clad2",
408  logicPlacement,
409  false,
410  0);
411 
412  // Place the rough surface only if needed
413  if (OpSurface) {
414  new G4LogicalBorderSurface("surfaceClad2Out",
415  physiClad2,
416  physiPlacement,
417  OpSurface);
418  new G4LogicalBorderSurface("surfaceClad2In",
419  physiPlacement,
420  physiClad2,
421  OpSurface);
422  }
423 
424  logicPlacement = logicClad2;
425  physiPlacement = physiClad2;
426 
427  case 1:
428 
429  //--------------------------------------------------
430  // Cladding 1
431  //--------------------------------------------------
432 
433  G4VSolid* solidClad1;
434 
435  if (XYRatio == 1.)
436  solidClad1 = new G4Tubs("Clad1",0.,clad1RX,clad1Z,0.0*rad,twopi*rad);
437  else
438  solidClad1 = new G4EllipticalTube("Clad1",clad1RX,clad1RY,clad1Z);
439 
440  logicClad1 = new G4LogicalVolume(solidClad1,
441  FindMaterial("Pethylene"),
442  "Clad1");
443 
444  physiClad1 = new G4PVPlacement(0,
445  G4ThreeVector(0.0,0.0,wlsfiberOrigin),
446  logicClad1,
447  "Clad1",
448  logicPlacement,
449  false,
450  0);
451 
452  // Place the rough surface only if needed
453  if (OpSurface) {
454  new G4LogicalBorderSurface("surfaceClad1Out",
455  physiClad1,
456  physiPlacement,
457  OpSurface);
458  new G4LogicalBorderSurface("surfaceClad1In",
459  physiPlacement,
460  physiClad1,
461  OpSurface);
462  }
463 
464  logicPlacement = logicClad1;
465  physiPlacement = physiClad1;
466 
467  default:
468 
469  //--------------------------------------------------
470  // WLS Fiber
471  //--------------------------------------------------
472 
473  G4VSolid* solidWLSfiber;
474 
475  if (XYRatio == 1.)
476  solidWLSfiber =
477  new G4Tubs("WLSFiber",0.,wlsfiberRX,wlsfiberZ,0.0*rad,twopi*rad);
478  else
479  solidWLSfiber =
480  new G4EllipticalTube("WLSFiber",wlsfiberRX,wlsfiberRY,wlsfiberZ);
481 
482  G4LogicalVolume* logicWLSfiber =
483  new G4LogicalVolume(solidWLSfiber,
484  FindMaterial("PMMA"),
485  "WLSFiber");
486 
487  logicWLSfiber->SetUserLimits(new G4UserLimits(DBL_MAX,DBL_MAX,10*ms));
488 
489  G4VPhysicalVolume* physiWLSfiber = new G4PVPlacement(0,
490  G4ThreeVector(0.0,0.0,wlsfiberOrigin),
491  logicWLSfiber,
492  "WLSFiber",
493  logicPlacement,
494  false,
495  0);
496 
497  // Place the rough surface only if needed
498  if (OpSurface) {
499  new G4LogicalBorderSurface("surfaceWLSOut",
500  physiWLSfiber,
501  physiPlacement,
502  OpSurface);
503  new G4LogicalBorderSurface("surfaceWLSIn",
504  physiPlacement,
505  physiWLSfiber,
506  OpSurface);
507  }
508  }
509 
510  //--------------------------------------------------
511  // Mirror for reflection at one of the end
512  //--------------------------------------------------
513 
514  // Place the mirror only if the user wants the mirror
515  if (mirrorToggle) {
516 
517  G4VSolid* solidMirror = new G4Box("Mirror",
518  mirrorRmax,
519  mirrorRmax,
520  mirrorZ);
521 
522  G4LogicalVolume* logicMirror = new G4LogicalVolume(solidMirror,
523  FindMaterial("G4_Al"),
524  "Mirror");
525 
526  G4OpticalSurface* MirrorSurface = new G4OpticalSurface("MirrorSurface",
527  glisur,
528  ground,
530  mirrorPolish);
531 
532  G4MaterialPropertiesTable* MirrorSurfaceProperty =
534 
535  G4double p_mirror[2] = {2.00*eV, 3.47*eV};
536  G4double refl_mirror[2] = {mirrorReflectivity,mirrorReflectivity};
537  G4double effi_mirror[2] = {0, 0};
538 
539  MirrorSurfaceProperty->AddProperty("REFLECTIVITY",p_mirror,refl_mirror,2);
540  MirrorSurfaceProperty->AddProperty("EFFICIENCY",p_mirror,effi_mirror,2);
541 
542  MirrorSurface -> SetMaterialPropertiesTable(MirrorSurfaceProperty);
543 
544  new G4PVPlacement(0,
545  G4ThreeVector(0.0,0.0,mirrorOrigin),
546  logicMirror,
547  "Mirror",
548  logicWorld,
549  false,
550  0);
551 
552  new G4LogicalSkinSurface("MirrorSurface",logicMirror,MirrorSurface);
553  }
554 
555  //--------------------------------------------------
556  // Coupling at the read-out end
557  //--------------------------------------------------
558 
559  // Clear Fiber (Coupling Layer)
560  G4VSolid* solidCouple = new G4Box("Couple",coupleRX,coupleRY,coupleZ);
561 
562  G4LogicalVolume* logicCouple = new G4LogicalVolume(solidCouple,
563  FindMaterial("G4_AIR"),
564  "Couple");
565 
566  new G4PVPlacement(0,
567  G4ThreeVector(0.0,0.0,coupleOrigin),
568  logicCouple,
569  "Couple",
570  logicWorld,
571  false,
572  0);
573 
574  //--------------------------------------------------
575  // A logical layer in front of PhotonDet
576  //--------------------------------------------------
577 
578  // Purpose: Preventing direct dielectric to metal contact
579 
580  // Check for valid placement of PhotonDet
581  if (mppcTheta > std::atan(mppcDist / mppcHalfL)) {
582 
583  mppcTheta = 0;
584  mppcOriginX = std::sin(mppcTheta) * (mppcDist + clrfiberZ);
585  mppcOriginZ = -coupleZ + std::cos(mppcTheta) * (mppcDist + clrfiberZ);
586  G4cerr << "Invalid alignment. Alignment Reset to 0" << G4endl;
587  }
588 
589  // Clear Fiber (Coupling Layer)
590  G4VSolid* solidClrfiber;
591 
592  if ( mppcShape == "Square" )
593  solidClrfiber =
594  new G4Box("ClearFiber",clrfiberHalfL,clrfiberHalfL,clrfiberZ);
595  else
596  solidClrfiber =
597  new G4Tubs("ClearFiber",0.,clrfiberHalfL,clrfiberZ,0.0*rad,twopi*rad);
598 
599  G4LogicalVolume* logicClrfiber =
600  new G4LogicalVolume(solidClrfiber,
601  FindMaterial("G4_AIR"),
602  "ClearFiber");
603 
605  G4ThreeVector(mppcOriginX,0.0,mppcOriginZ),
606  logicClrfiber,
607  "ClearFiber",
608  logicCouple,
609  false,
610  0);
611 
612  //--------------------------------------------------
613  // PhotonDet (Sensitive Detector)
614  //--------------------------------------------------
615 
616  // Physical Construction
617  G4VSolid* solidPhotonDet;
618 
619  if ( mppcShape == "Square" )
620  solidPhotonDet = new G4Box("PhotonDet",mppcHalfL,mppcHalfL,mppcZ);
621  else
622  solidPhotonDet =
623  new G4Tubs("PhotonDet",0.,mppcHalfL,mppcZ,0.0*rad,twopi*rad);
624 
625  G4LogicalVolume* logicPhotonDet =
626  new G4LogicalVolume(solidPhotonDet,
627  FindMaterial("G4_Al"),
628  "PhotonDet");
629 
630  new G4PVPlacement(0,
631  G4ThreeVector(0.0,0.0,0.0),
632  logicPhotonDet,
633  "PhotonDet",
634  logicClrfiber,
635  false,
636  0);
637 
638  // PhotonDet Surface Properties
639  G4OpticalSurface* PhotonDetSurface = new G4OpticalSurface("PhotonDetSurface",
640  glisur,
641  ground,
643  mppcPolish);
644 
645  G4MaterialPropertiesTable* PhotonDetSurfaceProperty =
647 
648  G4double p_mppc[2] = {2.00*eV, 3.47*eV};
649  G4double refl_mppc[2] = {mppcReflectivity,mppcReflectivity};
650  G4double effi_mppc[2] = {1, 1};
651 
652  PhotonDetSurfaceProperty -> AddProperty("REFLECTIVITY",p_mppc,refl_mppc,2);
653  PhotonDetSurfaceProperty -> AddProperty("EFFICIENCY",p_mppc,effi_mppc,2);
654 
655  PhotonDetSurface -> SetMaterialPropertiesTable(PhotonDetSurfaceProperty);
656 
657  new G4LogicalSkinSurface("PhotonDetSurface",logicPhotonDet,PhotonDetSurface);
658 
659  if (!mppcSD) {
660  G4String mppcSDName = "WLS/PhotonDet";
661  mppcSD = new WLSPhotonDetSD(mppcSDName);
662 
664  SDman->AddNewDetector(mppcSD);
665  }
666 
667  // Setting the detector to be sensitive
668  logicPhotonDet->SetSensitiveDetector(mppcSD);
669 
670 }
671 
673 {
674  if (!physiWorld) return;
675 
676  // clean-up previous geometry
678 
684 
685  //define new one
686  UpdateGeometryParameters();
687 
689 
692 
694 }
695 
696 void WLSDetectorConstruction::UpdateGeometryParameters()
697 {
698  wlsfiberRX = XYRatio * wlsfiberRY;
699 
700  clad1RX = wlsfiberRX + 0.03*wlsfiberRX;
701  clad1RY = wlsfiberRY + 0.03*wlsfiberRY;
702  clad1Z = wlsfiberZ;
703 
704  clad2RX = clad1RX + 0.03*wlsfiberRX;
705  clad2RY = clad1RY + 0.03*wlsfiberRY;
706  clad2Z = wlsfiberZ;
707 
708  worldSizeX = clad2RX + mppcDist + mppcHalfL + 1.*cm;
709  worldSizeY = clad2RY + mppcDist + mppcHalfL + 1.*cm;
710  worldSizeZ = wlsfiberZ + mppcDist + mppcHalfL + 1.*cm;
711 
712  coupleRX = worldSizeX;
713  coupleRY = worldSizeY;
714  coupleZ = (worldSizeZ - wlsfiberZ) / 2;
715 
716  clrfiberHalfL = mppcHalfL;
717 
718  mirrorRmax = clad2RY;
719 
720  coupleOrigin = wlsfiberOrigin + wlsfiberZ + coupleZ;
721  mirrorOrigin = wlsfiberOrigin - wlsfiberZ - mirrorZ;
722  mppcOriginX = std::sin(mppcTheta) * (mppcDist + clrfiberZ);
723  mppcOriginZ = -coupleZ + std::cos(mppcTheta) * (mppcDist + clrfiberZ);
724 }
725 
728 {
729  // We apply successive rotations OF THE OBJECT around the FIXED
730  // axes of the parent's local coordinates; rotations are applied
731  // left-to-right (rotation="r1,r2,r3" => r1 then r2 then r3).
732 
733  G4RotationMatrix rot;
734 
735  unsigned int place = 0;
736 
737  while (place < rotation.size()) {
738 
739  G4double angle;
740  char* p;
741 
742  angle = strtod(rotation.substr(place+1).c_str(),&p) * deg;
743 
744  if (!p || (*p != (char)',' && *p != (char)'\0')) {
745  G4cerr << "Invalid rotation specification: " <<
746  rotation.c_str() << G4endl;
747  return rot;
748  }
749 
750  G4RotationMatrix thisRotation;
751 
752  switch(rotation.substr(place,1).c_str()[0]) {
753  case 'X': case 'x':
754  thisRotation = G4RotationMatrix(CLHEP::HepRotationX(angle));
755  break;
756  case 'Y': case 'y':
757  thisRotation = G4RotationMatrix(CLHEP::HepRotationY(angle));
758  break;
759  case 'Z': case 'z':
760  thisRotation = G4RotationMatrix(CLHEP::HepRotationZ(angle));
761  break;
762  default:
763  G4cerr << " Invalid rotation specification: "
764  << rotation << G4endl;
765  return rot;
766  }
767 
768  rot = thisRotation * rot;
769  place = rotation.find(',',place);
770  if (place > rotation.size()) break;
771  ++place;
772  }
773 
774  return rot;
775 
776 }
777 
778 // Set the Geometry of the PhotonDet detector
779 // Pre: shape must be either "Circle" and "Square"
781 {
782  if (shape == "Circle" || shape == "Square" ) mppcShape = shape;
783 }
784 
785 // Set the number of claddings
786 // Pre: 0 <= num <= 2
788 {
789  numOfCladLayers = num;
790 }
791 
792 // Set the TOTAL length of the WLS fiber
794 {
795  wlsfiberZ = length;
796 }
797 
798 // Set the Y radius of WLS fiber
800 {
801  wlsfiberRY = radius;
802 }
803 
804 // Set the Y radius of Cladding 1
806 {
807  clad1RY = radius;
808 }
809 
810 // Set the Y radius of Cladding 2
812 {
813  clad2RY = radius;
814 }
815 
816 // Set the half length of the PhotonDet detector
817 // The half length will be the radius if PhotonDet is circular
819 {
820  mppcHalfL = halfL;
821 }
822 
823 // Set the distance between fiber end and PhotonDet
824 void WLSDetectorConstruction::SetGap (G4double gap) { mppcDist = gap; }
825 
826 // Set the Aligment of PhotonDet with respect to the z axis
827 // If theta is 0 deg, then the detector is perfectly aligned
828 // PhotonDet will be deviated by theta from z axis
829 // facing towards the center of the fiber
831 {
832  mppcTheta = theta;
833 }
834 
835 // Set the Surface Roughness between Cladding 1 and WLS fiber
836 // Pre: 0 < roughness <= 1
838 {
839  surfaceRoughness = roughness;
840 }
841 
842 // Set the Polish of the mirror, polish of 1 is a perfect mirror surface
843 // Pre: 0 < polish <= 1
845 {
846  mirrorPolish = polish;
847 }
848 
849 // Set the Reflectivity of the mirror, reflectivity of 1 is a perfect mirror
850 // Pre: 0 < reflectivity <= 1
852 {
853  mirrorReflectivity = reflectivity;
854 }
855 
856 // Set the Polish of the PhotonDet, polish of 1 is a perfect mirror surface
857 // Pre: 0 < polish <= 1
859 {
860  mppcPolish = polish;
861 }
862 
863 // Set the Reflectivity of the PhotonDet, reflectivity of 1 is a perfect mirror
864 // Pre: 0 < reflectivity <= 1
866 {
867  mppcReflectivity = reflectivity;
868 }
869 
870 // Toggle to place the mirror or not at one end (-z end) of the fiber
871 // True means place the mirror, false means otherwise
872 void WLSDetectorConstruction::SetMirror(G4bool flag) { mirrorToggle = flag; }
873 
874 // Set the ratio of the x and y radius of the ellipse (x/y)
875 // a ratio of 1 would produce a circle
877 
878 // Set the length of the scintillator bar
880 {
881  barLength = length;
882 }
883 
884 // Set the side of the scintillator bar
886 {
887  barBase = side;
888 }
889 
890 // Set the radius of the fiber hole
892 {
893  holeRadius = radius;
894 }
895 
896 // Set thickness of the coating on the bars
898 {
899  coatingThickness = thick;
900 }
901 
902 // Set inner radius of the corner bar coating
904 {
905  coatingRadius = radius;
906 }
907 
909 
916  { return coatingThickness; }
918 
920 {
921  return wlsfiberOrigin + wlsfiberZ;
922 }
923 
925 {
926  if (numOfCladLayers == 2) return clad2RY;
927  if (numOfCladLayers == 1) return clad1RY;
928  return wlsfiberRY;
929 }
930 
932 {
933  return surfaceRoughness;
934 }
935 
936 // Return True if the fiber construction is ideal
938 {
939  return surfaceRoughness == 1. && XYRatio == 1.
940  && (!mirrorToggle ||
941  (mirrorPolish == 1. && mirrorReflectivity == 1.));
942 }
943 
946  return material;
947 }