Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OlapDetConstr.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 // $Id$
31 //
32 //
33 // --------------------------------------------------------------
34 // OlapDetConstr
35 //
36 // Author: Martin Liendl - Martin.Liendl@cern.ch
37 //
38 // --------------------------------------------------------------
39 //
40 #include "OlapDetConstr.hh"
41 #include "OlapGenerator.hh"
42 
43 #include "SolidAnalyser.hh"
44 #include "OlapManager.hh"
45 
46 #include "G4UImanager.hh"
47 #include "G4VVisManager.hh"
48 #include "G4VPhysicalVolume.hh"
49 #include "G4PVPlacement.hh"
50 #include "G4PVReplica.hh"
51 #include "G4PVParameterised.hh"
52 #include "G4LogicalVolume.hh"
53 #include "G4RunManager.hh"
54 #include "G4VisExtent.hh"
55 #include "G4VisAttributes.hh"
56 #include "G4LogicalVolumeStore.hh"
57 #include "G4Box.hh"
58 #include "G4Polyline.hh"
59 #include "G4Polycone.hh"
60 #include "G4Polyhedra.hh"
61 #include "G4ThreeVector.hh"
62 
64  G4VPhysicalVolume *aWorld) :
65  theTheta(0),
66  thePhi(0),
67  theAlpha(0),
68  theNewWorldRot(0),
69  theFullGeometry(aGeometry),
70  theWorld(aWorld),
71  theNewWorld(0),
72  theNewLV(0),
73  theNewWorldBox(new G4Box("world",1.,1.,1.)),
74  syncVis(true),
75  nrLV(0)
76 {
77  //theNewWorldLV = new G4LogicalVolume
78  visMother = new G4VisAttributes(G4Colour(7.0, 0.0, 0.0, 0.4)); // red
79  visMother->SetForceWireframe(true);
80  visDaughterA = new G4VisAttributes(G4Colour(.0, 0.0, 1.0, 0.3)); // blue
81  visDaughterA->SetForceWireframe(false);
82  visDaughterB = new G4VisAttributes(G4Colour(0., 0., 1.0, 0.3)); // light-blue
83  visDaughterB->SetForceWireframe(false);
84  visWorld = new G4VisAttributes(G4Colour(1., 0, 0, 1.)); // red
85  visWorld->SetForceWireframe(false);
86  visWorld->SetVisibility(true);
87 
88  visFullWorld = new G4VisAttributes(G4Colour(1.,1.,1.,0.9));
89  visFullWorld->SetForceWireframe(true);
90  visWorld->SetVisibility(false);
91 
92  visInvisible = new G4VisAttributes(G4Colour(1.,1.,1.,0.9));
93  visInvisible->SetForceWireframe(true);
94  visInvisible->SetVisibility(false);
95 
96  visFirstLevel = new G4VisAttributes(G4Colour(1.,1.,1,1));
97  visFirstLevel->SetForceWireframe(true);
98  visFirstLevel->SetVisibility(true);
99 }
100 
101 
103 {
104 }
105 
106 
108 {
109  theTheta = t;
110  thePhi = p;
111  theAlpha = a;
112 }
113 
114 
116 {
117  if (!theWorld)
118  {
119  theWorld = theFullGeometry->Construct();
120  }
121  if (!theWorld)
122  {
123  G4Exception("OlapDetConstr::Construct()", "InvalidSetup", FatalException,
124  "Cannot create full world. Exiting...");
125  }
126 
127  // logical volume which will have a box with its dimensions derived from
128  // the extent of the 'new-mother' volume positioned inside
129  // the size of this NewWorld will be set in 'SetNewWorld(..)'
130  theNewWorldLV =
131  new G4LogicalVolume(theNewWorldBox,
132  theWorld->GetLogicalVolume()->GetMaterial(),
133  "NewWorld"
134  );
135 
136  // physical volume which will serve as the 'small' NewWorld to be
137  // used for overlap checking
138  theNewWorld =
139  new G4PVPlacement( 0, // rotation
140  G4ThreeVector(), // translation
141  "NewWorld", // name of phys = name of logical!!!
142  theNewWorldLV, // own logical vol
143  0, false, 0 // no mother, not MANY, cpNr=0
144  );
145 
146  theNewWorldLV->SetVisAttributes(visWorld);
147 
148  //ResetColors();
149 
150 
151  theNewLV = theWorld->GetLogicalVolume();
152  nrLV = G4LogicalVolumeStore::GetInstance()->size();
153 
154  return theWorld;
155 }
156 
157 
159  G4bool debugFlag)
160 {
161  if (debugFlag)
162  {
163  G4cout << "Mother: " << aMotherLV->GetName() << " : "
164  << aMotherLV->GetSolid()->GetName() << G4endl;
165  }
166 
167  //ML: ResetColors(theNewLV);
168  theNewLV = aMotherLV;
169 
170  ConstructNewWorld();
171 
172  // set new world to Geant4-Kernel
174 
175  // try to set the OlapGenerator
176  const OlapGenerator * aGen = dynamic_cast<const OlapGenerator *>
178  if ( aGen )
179  {
180  OlapGenerator * aNonConstGen = const_cast<OlapGenerator*>(aGen);
181 
182  // extent which allows arbitrary rotations ...
183  G4Box * bx = dynamic_cast<G4Box*>
184  (theNewWorld->GetLogicalVolume()->GetSolid());
185  aNonConstGen->SetExtent(2.*bx->GetXHalfLength());
186  }
187  else
188  {
189  G4cout << "Warning: Primary generator is not OlapGenerator!" << G4endl
190  << "Overlap Detection will not work!" << G4endl;
191  }
192  return theNewWorld;
193 }
194 
195 
197 {
198  return theNewWorld;
199 }
200 
201 
203 {
204  return theWorld;
205 }
206 
207 
208 void OlapDetConstr::DrawPolyOutline()
209 {
211  G4VSolid * solid = theNewLV->GetSolid();
212  G4Polyline line, endline;
213  G4double ex(0), first_r(0), first_z(0);
214  G4double maxz(0), maxr(0);
215  G4int nr(0);
216  G4Polycone * s = dynamic_cast<G4Polycone*>(solid);
217  G4Polyhedra * sh = dynamic_cast<G4Polyhedra*>(solid);
218  if (s)
219  {
220  nr = s->GetNumRZCorner();
221 
222  first_r = s->GetCorner(0).r;
223  first_z = s->GetCorner(0).z;
224  for (G4int i=0; i<nr; i++)
225  {
226  G4double r = s->GetCorner(i).r;
227  G4double z = s->GetCorner(i).z;
228  //line.push_back(G4ThreeVector(r,0.,z));
229  line.push_back(G4ThreeVector(r,z,0));
230  if (r>maxr)
231  maxr=r;
232  if (z>maxz)
233  maxz=z;
234  G4cout << G4ThreeVector(r,0,z) << G4endl;
235  //endline.push_back(G4ThreeVector(s->GetCorner(nr-1).r, 0.,
236  // s->GetCorner(nr-1).z));
237  endline.push_back(G4ThreeVector(s->GetCorner(nr-1).r,
238  s->GetCorner(nr-1).z,0));
239  }
240  }
241  else if (sh)
242  {
243  nr = sh->GetNumRZCorner();
244 
245  first_r = sh->GetCorner(0).r;
246  first_z = sh->GetCorner(0).z;
247  for (G4int i=0; i<nr; i++)
248  {
249  G4double r = sh->GetCorner(i).r;
250  G4double z = sh->GetCorner(i).z;
251  line.push_back(G4ThreeVector(r,0.,z));
252  if (r>maxr)
253  maxr=r;
254  if (z>maxz)
255  maxz=z;
256  G4cout << G4ThreeVector(r,0,z) << G4endl;
257  endline.push_back(G4ThreeVector(sh->GetCorner(nr-1).r, 0.,
258  sh->GetCorner(nr-1).z));
259  }
260  }
261  else
262  return;
263 
264  //endline.push_back(G4ThreeVector(first_r,0.,first_z));
265  endline.push_back(G4ThreeVector(first_r,first_z,0.));
266  if (maxz>=maxr)
267  ex = maxz;
268  else
269  ex = maxr;
270 
271  G4cout << "ex=" << ex << G4endl;
272  theNewWorldBox->SetXHalfLength(ex + ex/30.);
273  theNewWorldBox->SetYHalfLength(ex + ex/30.);
274  theNewWorldBox->SetZHalfLength(ex + ex/30.);
275 
276  G4Colour colour;
277  colour = G4Colour(1.,0.,0.);
278  line.SetVisAttributes(theNewLV->GetVisAttributes()->GetColor());
280  colour = G4Colour(0.,1.,0.);
281  endline.SetVisAttributes(theNewLV->GetVisAttributes()->GetColor());
282  //endline.SetVisAttributes(attribs3);
284  colour = G4Colour(0.,0.,1.);
285  G4Polyline ax;
286  //ax.push_back(G4ThreeVector(0.,0.,-ex));
287  //ax.push_back(G4ThreeVector(0.,0.,ex));
288  ax.push_back(G4ThreeVector(0.,-ex,0.));
289  ax.push_back(G4ThreeVector(0.,ex,0.));
290  G4VisAttributes attribs2(colour);
291  ax.SetVisAttributes(attribs2);
293 }
294 
295 void OlapDetConstr::ConstructNewWorld()
296 {
297  // delete the current NewWorld
298  DeleteNewWorld();
299 
300  G4int nr = theNewLV->GetNoDaughters();
301 
302  // create a NewWorld with a 2% larger extent than the
303  // solid of the NewMother
304 
305  const G4VisExtent & ext = theNewLV->GetSolid()->GetExtent();
306  G4double extX = (ext.GetXmax()-ext.GetXmin())/2.;
307  G4double extY = (ext.GetYmax()-ext.GetYmin())/2.;
308  G4double extZ = (ext.GetZmax()-ext.GetZmin())/2.;
309  G4ThreeVector pos( (ext.GetXmax()+ext.GetXmin())/2. ,
310  (ext.GetYmax()+ext.GetYmin())/2. ,
311  (ext.GetZmax()+ext.GetZmin())/2.
312  );
313  pos=-pos;
314 
315  /*
316  extX += extX/1000.;
317  extY += extY/1000.;
318  extZ += extZ/1000.;
319  */
320  G4double worldDim = std::sqrt(extX*extX + extY*extY + extZ*extZ);
321  worldDim += worldDim/100.;
322  // this automatically sets the dimensions of the
323  // solid in theNewWorldLV, because it's a ptr to the same solid
324  theNewWorldBox->SetXHalfLength(worldDim);
325  theNewWorldBox->SetYHalfLength(worldDim);
326  theNewWorldBox->SetZHalfLength(worldDim);
327 
328  // create the mother with one layer of daughters
329  G4LogicalVolume * aNewMotherLV =
330  new G4LogicalVolume(theNewLV->GetSolid(),
331  theNewLV->GetMaterial(),
332  theNewLV->GetName()
333  );
334 
335  // below the mother is fixed colored instead as taken from vis-atts of the
336  // full detector
337  aNewMotherLV->SetVisAttributes(theNewLV->GetVisAttributes());
338 
339  delete theNewWorldRot;
340  G4ThreeVector rotAxis(std::cos(thePhi)*std::sin(theTheta),
341  std::sin(thePhi)*std::sin(theTheta),
342  std::cos(theTheta));
343 
344  theNewWorldRot = new G4RotationMatrix(rotAxis,theAlpha);
345 
346  // G4VPhysicalVolume * aNewMotherPV =
347  new G4PVPlacement( theNewWorldRot, // rotation
348  pos, // translation
349  aNewMotherLV, // own logical vol
350  theNewLV->GetName(), // name of phys = name of logical!!!
351 
352  theNewWorldLV, // mother logical vol
353  //aInbetweenLV,
354 
355  false, 0 // not MANY, cpNr=0
356  );
357 
358 
359  // loop over daughters an copy them into the new world ...
360  // - but don't iterate recursively over deeper layers of daughters!
361  for (G4int i=0; i<nr; i++)
362  {
363  G4VPhysicalVolume * pv = theNewLV->GetDaughter(i);
364 
365  // ---------------------------------------------------------------
366  // only do the stuff, if OlapManager.NoOlapMap[lv] is set to false!
367  // otherwise the volume should not be considered for olap detection
368 
370  if (m->NoOlapMap[pv->GetLogicalVolume()])
371  continue;
372  // ---------------------------------------------------------------
373 
374  G4LogicalVolume * myLogical =
376  pv->GetLogicalVolume()->GetMaterial(),
377  pv->GetLogicalVolume()->GetName()
378  );
379 
380  // take vis atts from whole detector instead of fixed values!
382 
383  // select between placements, replicas and parameterizations
384  G4PVPlacement * pvPlace;
385  if (dynamic_cast<G4PVPlacement*>(pv))
386  {
387  pvPlace = dynamic_cast<G4PVPlacement*>(pv);
388  new G4PVPlacement( pvPlace->GetRotation(),
389  pvPlace->GetTranslation(),
390  myLogical, // my own logical vol
391  pvPlace->GetName(),
392  aNewMotherLV, // my mother logical vol
393  false, // not many
394  pvPlace->GetCopyNo()
395  );
396  }
397  else if ( pv->IsReplicated() && ! pv->GetParameterisation() ) // Replicas
398  {
399  // retrieve replication data
400  EAxis aAxis;
401  G4int nReplicas;
402  G4double aWidth, anOffset;
403  G4bool aDummy;
404  pv->GetReplicationData(aAxis, nReplicas, aWidth, anOffset, aDummy);
405 
406  new G4PVReplica( pv->GetName(),
407  myLogical,
408  aNewMotherLV,
409  aAxis,
410  nReplicas,
411  aWidth,
412  anOffset
413  );
414  }
415  else if ( pv->IsReplicated() && pv->GetParameterisation() )
416  {
417  // retrieve replication/parameterisation data
418  EAxis aAxis;
419  G4int nReplicas;
420  G4double aWidth, anOffset;
421  G4bool aDummy;
422  pv->GetReplicationData(aAxis, nReplicas, aWidth, anOffset, aDummy);
424 
425  new G4PVParameterised( pv->GetName(),
426  myLogical,
427  aNewMotherLV,
428  aAxis,
429  nReplicas,
430  pParam
431  );
432  }// end:placement?replica?parameterisation
433 
434  } // end:Loop over Daughters
435 }
436 
437 
438 void OlapDetConstr::DeleteNewWorld()
439 {
440  G4int nr = theNewWorldLV->GetNoDaughters();
441 
442  if (nr==0)
443  {
444  G4cout << "OlapDetConstr::DeleteNewWorld(): no daughter in NewWorld!"
445  << G4endl << G4endl;
446  return;
447  }
448 
449  if (nr>1 || nr<0) // only one daughter is allowed!!!!
450  {
451  G4Exception("OlapDetConstr::DeleteNewWorld()",
452  "InvalidSetup", FatalException,
453  "Too many daughters in NewWorldLV! Exiting...");
454  }
455 
456  G4LogicalVolume * aMother;
457  G4VPhysicalVolume * aDaughter;
458 
459  aMother = theNewWorldLV->GetDaughter(0)->GetLogicalVolume();
460 
461  G4int nrd = aMother->GetNoDaughters();
462  for (G4int i=0; i<nrd; i++)
463  {
464  aDaughter = aMother->GetDaughter(i);
465  G4LogicalVolume * tmp = aDaughter->GetLogicalVolume();
466  delete tmp;
467  delete aDaughter;
468  }
469 
470  aDaughter = theNewWorldLV->GetDaughter(0);
471  theNewWorldLV->RemoveDaughter(aDaughter);
472  delete aDaughter;
473  delete aMother;
474 }
475 
476 
477 // set everything in the full geometry to invisible
478 void OlapDetConstr::ResetColors()
479 {
480 /*
481  G4ColorMap * aColMap = G4ColorMap::GetColorMap();
482  aColMap->SetAllInvisible();
483 */
484  //ColorFirstLevel();
485 }
486 
487 
488 // colors the first layer of daughters of the full geometry
489 void OlapDetConstr::ColorFirstLevel()
490 {
491 /*
492  G4ColorMap * aColMap = G4ColorMap::GetColorMap();
493 
494  G4LogicalVolume * lvWorld = theWorld->GetLogicalVolume();
495  aColMap->SetVisible(lvWorld,true);
496  G4int nr = lvWorld->GetNoDaughters();
497  for (G4int i = 0; i<nr; i++) {
498  aColMap->SetVisible(lvWorld->GetDaughter(i)->GetLogicalVolume(),true);
499  }
500 */
501 }
502 
503 
504 // sets NewWorld invisible
505 void OlapDetConstr::ResetColors(G4LogicalVolume*)
506 {
507 /*
508  G4ColorMap * aColMap = G4ColorMap::GetColorMap();
509  G4int nr = lv->GetNoDaughters();
510  for (G4int i =0; i<nr; i++) {
511  aColMap->SetVisible(lv->GetDaughter(i)->GetLogicalVolume(),false);
512  }
513  aColMap->SetVisible(lv,false);
514 */
515  //ColorFirstLevel();
516 
517 }
518 
519 
521 {
523 
524  return theWorld;
525 }
526 
527 
529 {
530  return theNewLV;
531 }