29 #include "G4Material.hh"
31 #include "G4Sphere.hh"
32 #include "G4LogicalVolume.hh"
33 #include "G4PVPlacement.hh"
34 #include "G4PVParameterised.hh"
35 #include "G4UserLimits.hh"
36 #include "G4VisAttributes.hh"
37 #include "G4Colour.hh"
47 SToGS::TwoShellsDetectorConstruction::aShell::aShell()
60 SToGS::TwoShellsDetectorConstruction::aShell::aShell(
const aShell &from)
63 MatName = from.MatName;
66 PhiStart = from.PhiStart;
67 PhiDelta = from.PhiDelta;
68 ThetaStart = from.ThetaStart;
69 ThetaDelta = from.ThetaDelta;
70 IsActive = from.IsActive;
73 void SToGS::TwoShellsDetectorConstruction::aShell::Print(std::ostream &out)
75 out << Name <<
" " << MatName <<
" "
76 << RMin/CLHEP::cm <<
" " << RMax/CLHEP::cm <<
" "
77 << PhiStart<<
" " << PhiDelta/CLHEP::deg <<
" " << ThetaStart/CLHEP::deg <<
" " << ThetaDelta/CLHEP::deg <<
" " << IsActive << endl;
85 Inner.Name =
"Shell:0";
86 Inner.MatName =
"NaI";
88 Inner.RMin = 10.*CLHEP::cm;
89 Inner.RMax = 15.*CLHEP::cm;
90 Inner.PhiStart = 0.*CLHEP::deg;
91 Inner.PhiDelta = 360.*CLHEP::deg;
92 Inner.ThetaStart = 0.*CLHEP::deg;
93 Inner.ThetaDelta = 180.*CLHEP::deg;
96 Outer.Name =
"Shell:1";
97 Outer.MatName =
"BGO";
99 Outer.RMin = 25.*CLHEP::cm;
100 Outer.RMax = 40.*CLHEP::cm;
101 Outer.PhiStart = 0.*CLHEP::deg;
102 Outer.PhiDelta = 360.*CLHEP::deg;
103 Outer.ThetaStart = 0.*CLHEP::deg;
104 Outer.ThetaDelta = 180.*CLHEP::deg;
116 Inner.Name =
"Shell:0";
117 Inner.MatName =
"NaI";
119 Inner.RMin = 10.*CLHEP::cm;
120 Inner.RMax = 15.*CLHEP::cm;
121 Inner.PhiStart = 0.0*CLHEP::deg;
122 Inner.PhiDelta = 360.*CLHEP::deg;
123 Inner.ThetaStart = 0.*CLHEP::deg;
124 Inner.ThetaDelta = 180.*CLHEP::deg;
127 Outer.Name =
"Shell:1";
128 Outer.MatName =
"BGO";
130 Outer.RMin = 25.*CLHEP::cm;
131 Outer.RMax = 40.*CLHEP::cm;
132 Outer.PhiStart = 0.*CLHEP::deg;
133 Outer.PhiDelta = 360.*CLHEP::deg;
134 Outer.ThetaStart = 0.*CLHEP::deg;
135 Outer.ThetaDelta = 180.*CLHEP::deg;
144 for(
unsigned int i = 0; i < otherShells.size() ; i++ ) {
145 delete otherShells[i];
151 G4cout <<
" ------ INF ------ from SToGS::TwoShellsDetectorConstruction::ComputeParameters with " << filename << G4endl;
154 SToGS::MaterialConsultant *materialFactory = SToGS::MaterialConsultant::theConsultant();
157 ifstream file; file.open(filename.data());
158 if ( file.is_open() == false ) {
159 G4cout <<
" ** WARNING ** cannot open file " << filename << G4endl;
160 G4cout <<
" ==> Current parameters are used " << G4endl;
167 const G4int MAXWIDTH = 300;
char aline[MAXWIDTH]; file.getline(aline,MAXWIDTH);
169 G4int nb_active = 0, nb_mandatory = 0; G4double rlastmin = 0.0, rlastmax = 0.0;
170 while ( file.good() ) {
172 if ( aline[0] ==
'#' ) {
173 file.getline(aline,MAXWIDTH);
178 char name[30], mat[30];
179 G4float tmp1, tmp2, tmp3, tmp4, tmp5, tmp6; G4int tmpi;
181 G4int format = sscanf(aline,
"%s %s %f %f %f %f %f %f %d",name,mat,&tmp1,&tmp2,&tmp3,&tmp4,&tmp5,&tmp6,&tmpi);
183 tmp.Name = name; tmp.MatName = mat;
185 tmp.RMin = tmp1*CLHEP::cm;
186 tmp.RMax = tmp2*CLHEP::cm;
187 tmp.PhiStart = tmp3*CLHEP::deg;
188 tmp.PhiDelta = tmp4*CLHEP::deg;
189 tmp.ThetaStart = tmp5*CLHEP::deg;
190 tmp.ThetaDelta = tmp6*CLHEP::deg;
198 if ( tmp.RMin > tmp.RMax )
200 if ( tmp.PhiStart < 0.0 || tmp.PhiStart > 360.0/CLHEP::deg )
202 if ( tmp.PhiDelta < 0.0 || tmp.PhiDelta > 360.0/CLHEP::deg )
204 if ( tmp.ThetaStart < 0.0 || tmp.ThetaStart > 180.0/CLHEP::deg )
206 if ( tmp.ThetaDelta < 0.0 || tmp.ThetaDelta > 180.0/CLHEP::deg )
210 G4cout <<
" ** WARNING ** the following shell has geometrical problems (removed from the final geometry) ";
214 if ( materialFactory->FindOrBuildMaterial(tmp.MatName) == NULL ) {
215 G4cout <<
" ** WARNING ** the material of the following shell is unknown: "; tmp.Print(G4cout);
216 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
219 if ( ( tmp.RMin > rlastmin && tmp.RMin < rlastmax ) || ( tmp.RMax > rlastmin && tmp.RMax < rlastmax ) ) {
220 G4cout <<
" ** WARNING ** the following shell overlaps with a previous one: "; tmp.Print(G4cout);
224 file.getline(aline,MAXWIDTH);
230 rlastmin = tmp.RMin; rlastmax = tmp.RMax;
232 if ( tmp.Name ==
"Shell:0" ) {
233 if ( tmp.MatName ==
"AIR" )
236 Inner = tmp; nb_mandatory++;
if ( tmp.IsActive ) nb_active++;
239 if ( tmp.Name ==
"Shell:1" ) {
240 if ( tmp.MatName ==
"AIR" )
243 Outer = tmp; nb_mandatory++;
if ( tmp.IsActive ) nb_active++;
249 aShell *ptshell =
new aShell(); (*ptshell) = tmp; otherShells.push_back(ptshell);
253 else { G4cout <<
" ** WARNING ** the following line does not have the expected format:" << G4endl << aline << G4endl; }
255 file.getline(aline,MAXWIDTH);
260 if ( nb_active == 0 ) {
261 G4cout <<
" ** WARNING **, there is no active shell defined " << G4endl;
263 if ( nb_mandatory != 2 ) {
264 G4cout <<
" ** WARNING **, " << 2 - nb_mandatory <<
" shell(s) missing " << G4endl;
267 G4cout <<
" Shell:0 and Shell:1 definitions: " << G4endl;
268 G4cout <<
"\t"; Inner.Print(G4cout); G4cout <<
"\t"; Outer.Print(G4cout);
269 if ( otherShells.size() ) {
270 G4cout <<
" List of passive materials: " << G4endl;
271 for(
unsigned int i = 0; i < otherShells.size() ; i++ ) { G4cout <<
"\t"; otherShells[i]->Print(G4cout); }
273 G4cout <<
" ------ END ------ from SToGS::TwoShellsDetectorConstruction::ComputeParameters " << G4endl;
278 G4cout <<
" ------ INF ------ from SToGS::TwoShellsDetectorConstruction::Construct() " << G4endl;
288 G4double HalfWorldLength = 1.5*Outer.RMax;
291 for (
unsigned int i = 0; i < otherShells.size() ; i++ ) {
292 if ( otherShells[i]->RMax > Outer.RMax )
293 HalfWorldLength = 1.5*otherShells[i]->RMax;
296 solidWorld=
new G4Box(
"TwoShells",HalfWorldLength,HalfWorldLength,HalfWorldLength);
297 logicWorld=
new G4LogicalVolume(solidWorld, SToGS::MaterialConsultant::theConsultant()->FindOrBuildMaterial(
"AIR"),
"TheWorld", 0, 0, 0);
299 logicWorld->SetVisAttributes(G4VisAttributes::Invisible);
302 physiWorld =
new G4PVPlacement(0,
311 G4Sphere *asolidShell; G4LogicalVolume *alogicShell; G4VPhysicalVolume *aphysiShell; G4VisAttributes *visatt;
313 asolidShell =
new G4Sphere(Inner.Name, Inner.RMin, Inner.RMax, Inner.PhiStart, Inner.PhiDelta, Inner.ThetaStart, Inner.ThetaDelta);
314 logicInner =
new G4LogicalVolume(asolidShell,
315 SToGS::MaterialConsultant::theConsultant()->FindOrBuildMaterial(Inner.MatName),
317 visatt =
new G4VisAttributes( G4Colour(0.0, 0.0, 1.0) ); visatt->SetVisibility(
true);
318 logicInner->SetVisAttributes( visatt );
319 aphysiShell =
new G4PVPlacement(0,
328 asolidShell =
new G4Sphere(Outer.Name, Outer.RMin, Outer.RMax, Outer.PhiStart, Outer.PhiDelta, Outer.ThetaStart, Outer.ThetaDelta);
329 logicOuter =
new G4LogicalVolume(asolidShell,
330 SToGS::MaterialConsultant::theConsultant()->FindOrBuildMaterial(Outer.MatName),
332 visatt =
new G4VisAttributes( G4Colour(1.0, 0.0, 0.) ); visatt->SetVisibility(
true);
333 logicOuter->SetVisAttributes( visatt );
334 aphysiShell =
new G4PVPlacement(0,
343 for (
unsigned int i = 0; i < otherShells.size() ; i++ ) {
344 aShell *tmp = otherShells[i];
346 asolidShell =
new G4Sphere(tmp->Name, tmp->RMin, tmp->RMax, tmp->PhiStart, tmp->PhiDelta, tmp->ThetaStart, tmp->ThetaDelta);
347 alogicShell =
new G4LogicalVolume(asolidShell,
348 SToGS::MaterialConsultant::theConsultant()->FindOrBuildMaterial(tmp->MatName),
350 visatt =
new G4VisAttributes( G4Colour(0.3, 0.3, 0.3) ); visatt->SetVisibility(
true);
351 alogicShell->SetVisAttributes( visatt );
352 aphysiShell =
new G4PVPlacement(0,
361 #ifdef G4MULTITHREADED
363 ConstructSDandField();
365 G4cout <<
" ------ END ------ from SToGS::TwoShellsDetectorConstruction::Construct() " << G4endl;
373 G4cout <<
" ------ INF ------ from SToGS::TwoShellsDetectorConstruction::ConstructSDandField() " << G4endl;
378 if ( sd && Inner.IsActive ) {
380 logicInner->SetSensitiveDetector( sd );
384 if ( sd && Outer.IsActive ) {
386 logicOuter->SetSensitiveDetector( sd );
388 G4cout <<
" ------ END ------ from SToGS::TwoShellsDetectorConstruction::ConstructSDandField() " << G4endl;
void ComputeParameters(G4String filename="DetectorFactory/Generics/TwoShells.geo")
from a given file, it computes the parameters of the two shells
static G4VSensitiveDetector * GetSD(G4String opt, const char sd_type= 'S')
Get a particular SD. S means a SD while s is for Scorers.
virtual G4VPhysicalVolume * Construct()
One of the mandatory class to be implemented in order to have G4 working properly.
virtual void ConstructSDandField()
NEW G4.10 ... but also define for G4.9 except is is called explicitely at the end of Construct...
virtual ~TwoShellsDetectorConstruction()
TwoShellsDetectorConstruction()
constructor