29 #include "G4Material.hh"
32 #include "G4Polyhedra.hh"
33 #include "G4Sphere.hh"
34 #include "G4GenericTrap.hh"
35 #include "G4Polycone.hh"
37 #include "G4LogicalVolume.hh"
38 #include "G4AssemblyVolume.hh"
40 #include "G4PVPlacement.hh"
41 #include "G4PVParameterised.hh"
42 #include "G4UserLimits.hh"
43 #include "G4VisAttributes.hh"
44 #include "G4Colour.hh"
46 #include "G4SubtractionSolid.hh"
47 #include "G4UnionSolid.hh"
48 #include "G4IntersectionSolid.hh"
50 #include "G4PhysicalVolumeStore.hh"
51 #include "G4LogicalVolumeStore.hh"
52 #include "G4SDManager.hh"
53 #include "G4UnitsTable.hh"
68 G4VSolid *SToGS::AGATA::AGATAShaper(G4Polycone *polycone,
69 G4double *xfront, G4double *yfront, G4double *xback, G4double *yback,
71 G4double added_dilatation)
73 G4String name = polycone->GetName(), tmp;
75 const G4int nb_edges = 6;
76 G4double lxfront[nb_edges], lyfront[nb_edges], lxback[nb_edges], lyback[nb_edges] ;
79 if ( added_dilatation == 0.0 ) {
80 for (G4int i = 0; i < nb_edges; i++) {
81 lxfront[i] = xfront[i];
82 lyfront[i] = yfront[i];
89 for (G4int i = 0; i < nb_edges; i++) {
90 D = std::sqrt( xfront[i]*xfront[i] + yfront[i]*yfront[i] );
91 lxfront[i] = xfront[i] + added_dilatation*xfront[i]/D ;
92 lyfront[i] = yfront[i] + added_dilatation*yfront[i]/D ;
93 D = std::sqrt( xback[i]*xback[i] + yback[i]*yback[i] );
94 lxback[i] = xback[i] + added_dilatation*xback[i]/D ;
95 lyback[i] = yback[i] + added_dilatation*yback[i]/D ;
99 G4double edge_length_x = 40*CLHEP::mm, edge_width_y = 10*CLHEP::mm, edge_depth_z = 1.2*zback/2.;
102 G4VSolid *result = polycone;
103 for (G4int i = 0; i < nb_edges; i++) {
106 tmp = name; tmp +=
"_edge_";
107 std::stringstream s1;
111 G4Box *edge =
new G4Box(tmp,edge_length_x,edge_width_y,edge_depth_z);
114 if ( i == nb_edges-1 ) {
122 G4ThreeVector v_RotX_1((lxback[i]+lxback[inext])/2.-(lxfront[i]+lxfront[inext])/2.,
123 (lyback[i]+lyback[inext])/2.-(lyfront[i]+lyfront[inext])/2.,zback);
128 G4ThreeVector v_RotZ_0(lxfront[inext]+lxfront[i],lyfront[inext]+lyfront[i] , 0 );
131 G4ThreeVector v_RotZ_1(lxfront[inext]-lxfront[i],lyfront[inext]-lyfront[i] , 0 );
136 R.rotateX(v_RotX_1.theta());
137 R.rotateZ(v_RotZ_1.phi());
139 T.setX( (lxback[inext]+lxfront[i])/2. );
140 T.setY( (lyback[inext]+lyfront[i])/2. );
141 T.setZ( zback / 2. );
143 G4ThreeVector offset( std::cos(v_RotZ_0.phi())*edge_width_y, std::sin(v_RotZ_0.phi())*edge_width_y , 0 );
146 G4cout <<
"Building Edges " << tmp << G4endl;
147 G4cout <<
" hexogone def @ 0 and " << zback
148 <<
" " << lxfront[i] <<
" " << lyfront[i] <<
" " << lxback[i] <<
" " << lyback[i] << G4endl;
149 G4cout <<
" RotX[theta] " << v_RotX_1.theta()/CLHEP::deg <<
" RotZ[phi] " << v_RotZ_1.phi()/CLHEP::deg << G4endl;
150 G4cout <<
"Translation to bring to center " << T << G4endl;
151 G4cout <<
"Additionnal offset dur to edge width " << offset << G4endl;
156 tmp = name; tmp +=
"_step_";
157 std::stringstream s2;
160 result =
new G4SubtractionSolid(tmp, result, edge, G4Transform3D(R,T) );
168 G4LogicalVolume *SToGS::AGATA::MakeAGATACapsule(G4String detname, G4String opt)
170 G4bool do_caps =
true, do_passive =
false; G4String tmp;
173 G4double px[6], py[6], pX[6], pY[6], pz[6], pZ[6];
194 G4double eps = 0.*CLHEP::mm;
198 ifstream infil; infil.open(faSolid.data());
199 if ( !infil.is_open() ) {
200 G4cout <<
"[SToGS] *** Cannot open file " << faSolid.data() << endl;
206 if ( detname.contains(
"Green") ) {
209 if ( detname.contains(
"Blue") ) {
212 if ( opt.contains(
"bare") )
217 int i1,i2,i3, nb_line = 0, nb_point = 0;
double x,y,z,X,Y,Z; std::string line;
218 while( infil.good() ) {
222 if ( line.size() < 2u )
224 if ( line[0] ==
'#' )
228 if(sscanf(line.data(),
"%d %d %d %lf %lf %lf %lf %lf %lf", &i1, &i2, &i3, &x, &y, &z, &X, &Y, &Z) != 9) {
238 HoleR = x * CLHEP::mm;
239 CylR = y * CLHEP::mm;
240 CylL = z * CLHEP::mm;
241 CylX = X * CLHEP::mm;
242 CylY = Y * CLHEP::mm;
243 CylZ = Z * CLHEP::mm;
245 else if(i2==0 && i3==1) {
246 HoleL = x * CLHEP::mm;
247 ThickB = y * CLHEP::mm;
248 ThickC = z * CLHEP::mm;
249 CapS = X * CLHEP::mm;
250 CapT = Y * CLHEP::mm;
251 Tolerance = Z * CLHEP::mm;
253 else if(i2==0 && i3==2) {
260 px[i3] = x * CLHEP::mm;
261 py[i3] = y * CLHEP::mm;
262 pX[i3] = X * CLHEP::mm;
263 pY[i3] = Y * CLHEP::mm;
265 pz[i3] = z * CLHEP::mm;
266 pZ[i3] = Z * CLHEP::mm;
272 G4cout <<
" the file " << faSolid.data() <<
" has been read " << endl;
275 G4RotationMatrix R; G4ThreeVector T; G4Transform3D Tr;
279 G4double *zSliceGe =
new G4double[4];
280 zSliceGe[0] = (0)*CLHEP::mm;
281 zSliceGe[1] = (HoleL)*CLHEP::mm;
282 zSliceGe[2] = (HoleL+0.1)*CLHEP::mm;
283 zSliceGe[3] = (+CylL)*CLHEP::mm;
285 G4double *InnRadGe =
new G4double[4];
288 InnRadGe[2] = HoleR*CLHEP::mm;
289 InnRadGe[3] = HoleR*CLHEP::mm;
291 G4double *OutRadGe =
new G4double[4];
292 OutRadGe[0] = CylR*CLHEP::mm;
293 OutRadGe[1] = CylR*CLHEP::mm;
294 OutRadGe[2] = CylR*CLHEP::mm;
295 OutRadGe[3] = CylR*CLHEP::mm;
299 G4Polycone *coax =
new G4Polycone(tmp, 0.*CLHEP::deg, 360.*CLHEP::deg, 4, zSliceGe, InnRadGe, OutRadGe ) ;
303 G4VSolid *crystal = AGATAShaper(coax,px,py,pX,pY,CylL);
304 crystal->SetName(tmp);
307 G4LogicalVolume *crystal_logic =
308 new G4LogicalVolume(crystal,
309 SToGS::MaterialConsultant::theConsultant()->FindOrBuildMaterial(
"Ge"),tmp,0,0,0);
310 G4VisAttributes *crystal_visatt =
new G4VisAttributes( G4Colour(ColX, ColY, ColZ,1) );
311 crystal_logic->SetVisAttributes( crystal_visatt );
316 G4LogicalVolume *capsule_logic = 0x0, *spacing_logic = 0x0;
319 zSliceGe[0] = (0.0)*CLHEP::mm;
320 zSliceGe[1] = (CylL + 2*CapT)*CLHEP::mm;
325 OutRadGe[0] = (CylR + CapT)*CLHEP::mm;
326 OutRadGe[1] = (CylR + CapT)*CLHEP::mm;
329 tmp +=
"_coax_spacing";
330 G4Polycone *coax_spacing_shape =
new G4Polycone(tmp, 0.*CLHEP::deg, 360.*CLHEP::deg, 2, zSliceGe, InnRadGe, OutRadGe);
333 tmp +=
"_capsule_spacing";
334 G4VSolid *spacing = AGATAShaper(coax_spacing_shape,px,py,pX,pY,CylL,CapT);
335 spacing->SetName(tmp);
338 spacing_logic =
new G4LogicalVolume(spacing,
339 SToGS::MaterialConsultant::theConsultant()->FindOrBuildMaterial(
"AIR"),tmp,0,0,0);
340 G4VisAttributes *spacing_visatt =
new G4VisAttributes( G4Colour(1, 1, 1,0.1) );
341 spacing_logic->SetVisAttributes( spacing_visatt );
344 zSliceGe[0] = (0.0)*CLHEP::mm;
345 zSliceGe[1] = (2*(CapT + CapS))*CLHEP::mm;
350 OutRadGe[0] = (CylR + CapT + CapS)*CLHEP::mm;
351 OutRadGe[1] = (CylR + CapT + CapS)*CLHEP::mm;
354 tmp +=
"_coax_encapsulation";
355 G4Polycone *coax_caps_shape =
new G4Polycone(tmp, 0.*CLHEP::deg, 360.*CLHEP::deg, 2, zSliceGe, InnRadGe, OutRadGe);
359 G4VSolid *capsule = AGATAShaper(coax_caps_shape,px,py,pX,pY,CylL,(CapT+CapS));
360 capsule->SetName(tmp);
363 capsule_logic =
new G4LogicalVolume(capsule,
364 SToGS::MaterialConsultant::theConsultant()->FindOrBuildMaterial(
"Al"),tmp,0,0,0);
365 G4VisAttributes *capsule_visatt =
new G4VisAttributes( G4Colour(0.3, 0.3, 0.3, 0.6) );
366 capsule_logic->SetVisAttributes( capsule_visatt );
369 if ( capsule_logic && spacing_logic ) {
370 return capsule_logic;
373 return crystal_logic;
376 G4AssemblyVolume *SToGS::AGATA::MakeAGATACluster(G4String opt)
378 G4AssemblyVolume *theCluster = 0x0; G4VPhysicalVolume *caps; std::vector < G4LogicalVolume * > capsules(3);
380 ifstream infil; infil.open(faCluster.data());
381 if ( !infil.is_open() ) {
382 G4cout <<
"[SToGS] *** Cannot open file " << faCluster.data() << G4endl;
386 capsules[0] = MakeAGATACapsule(
"AGATA-ARed",
"bare");
387 capsules[1] = MakeAGATACapsule(
"AGATA-BGreen",
"bare");
388 capsules[2] = MakeAGATACapsule(
"AGATA-CBlue",
"bare");
390 theCluster =
new G4AssemblyVolume();
392 G4int i1,i2,i3, nb_line = 0, which = 0; G4double x,y,z,ps, th, ph; std::string line;
393 while( infil.good() ) {
398 if ( line.size() < 2u )
400 if ( line[0] ==
'#' )
402 if(sscanf(line.data(),
"%d %d %d %lf %lf %lf %lf %lf %lf", &i1, &i2, &i3, &ps, &th, &ph, &x, &y, &z) != 9) {
406 G4ThreeVector T;G4RotationMatrix R; R.set(0,0,0);
421 R.rotateZ(G4double(ps)*CLHEP::deg);
422 R.rotateY(G4double(th)*CLHEP::deg);
423 R.rotateZ(G4double(ph)*CLHEP::deg);
425 G4Transform3D Tr(R,T) ;
426 theCluster->AddPlacedVolume( capsules[which] , Tr);
429 G4cout <<
" the file " << faCluster.data() <<
" has been read " << endl;
435 #include "G4GDMLParser.hh"
439 G4VPhysicalVolume *theDetector = 0x0;
442 ifstream infil; infil.open(faEuler.data());
443 if ( !infil.is_open() )
446 G4LogicalVolume *detlogicWorld;
448 detWorld =
new G4Box(
"AGATA",2.*CLHEP::m,2.*CLHEP::m,2.*CLHEP::m);
450 new G4LogicalVolume(detWorld,
451 SToGS::MaterialConsultant::theConsultant()->FindOrBuildMaterial(
"AIR"),
"AGATA", 0, 0, 0);
452 detlogicWorld->SetVisAttributes(G4VisAttributes::Invisible);
454 theDetector =
new G4PVPlacement(0,
463 G4cout <<
"\n Reading description of AGATA from file " << faEuler.data() <<
" ..." << endl;
465 G4AssemblyVolume *cluster = MakeAGATACluster(
"");
467 G4int i1, i2, nclust = 0; G4double ps, th, ph, x, y, z; std::string line;
468 while(infil.good()) {
473 if ( line.size() < 2u )
475 if ( line[0] ==
'#' )
477 if(sscanf(line.data(),
"%d %d %lf %lf %lf %lf %lf %lf", &i1, &i2, &ps, &th, &ph, &x, &y, &z) != 8)
480 G4ThreeVector T(x*CLHEP::mm,y*CLHEP::mm,z*CLHEP::mm); G4RotationMatrix R;
481 R.rotateZ(ps*CLHEP::deg);
482 R.rotateY(th*CLHEP::deg);
483 R.rotateZ(ph*CLHEP::deg);
485 G4Transform3D Tr(R,T);
486 cluster->MakeImprint(detlogicWorld, Tr );
491 cout << nclust <<
" cluster(s) composed this geometry " << endl;
495 parser.Write(
"toto.gdml",detlogicWorld,
false);
virtual G4VPhysicalVolume * Construct()
One of the mandatory class to be implemented in order to have G4 working properly.
static G4VSensitiveDetector * GetCopClusterSD(G4String name="/SToGS/SD/CopCluster")
to get a general SToGS Calorimeter. In Multi-threading mode, return a new instance otherwise a global...