Classes | Public Member Functions | Static Public Member Functions | Protected Member Functions | Private Types | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
EDepSim::RootGeometryManager Class Reference

#include <EDepSimRootGeometryManager.hh>

Classes

struct  DrawAttributes
 

Public Member Functions

virtual ~RootGeometryManager ()
 
void Export (const char *file)
 Export the geometry to a file. More...
 
void Update (const G4VPhysicalVolume *aWorld, bool validate)
 Update the root geometry to match the g4 geometry. More...
 
void Update (std::string gdmlFile, bool validate)
 Set the root geometry from a gdml file. More...
 
void Validate ()
 Make sure that the current geometry passes a bunch of tests. More...
 
int GetNodeId (const G4ThreeVector &pos)
 Get a volume ID base on the volume position. More...
 
void SetDrawAtt (G4Material *material, int color, double opacity=1.0)
 Set material color. More...
 
G4Color GetG4Color (G4Material *material)
 
virtual void ShouldPrintMass (std::string name)
 A method to request that a volume mass should be printed;. More...
 

Static Public Member Functions

static EDepSim::RootGeometryManagerGet (void)
 If a persistency manager has not been created, create one. More...
 

Protected Member Functions

 RootGeometryManager ()
 use Get() instead More...
 
int GetColor (const G4VPhysicalVolume *vol)
 
double GetOpacity (const G4VPhysicalVolume *vol)
 

Private Types

typedef std::map< G4String, DrawAttributesAttributeMap
 

Private Member Functions

TGeoShape * CreateShape (const G4VSolid *theSolid, TGeoMatrix **mat=NULL)
 
TGeoVolume * CreateVolume (const G4VSolid *theSolid, std::string theName, TGeoMedium *theMedium)
 Create a new ROOT volume object. More...
 
bool CreateEnvelope (const G4VPhysicalVolume *theVol, TGeoManager *theEnvelope, TGeoVolume *theMother)
 
int HowManySimilarNodesInVolume (TGeoVolume *theMother, std::string theName)
 
void CreateMaterials (const G4VPhysicalVolume *theVol)
 
virtual bool IgnoreVolume (const G4VPhysicalVolume *theVol)
 
virtual bool PrintMass (const G4VPhysicalVolume *theVol)
 A method to flag that a volume mass should be printed. More...
 
virtual std::string MaterialName (const G4VPhysicalVolume *theVol)
 
virtual TGeoMedium * AverageMaterial (const G4VPhysicalVolume *theVol)
 

Private Attributes

std::map< G4String, TGeoMedium * > fMedium
 A map between G4 material names and Root Material definitions. More...
 
std::map< G4String, TGeoElement * > fIsotope
 A map between G4 isotope names and Root Element definitions. More...
 
std::map< G4String, int > fNodeCount
 A map between G4 volume names and count of volumes with that name. More...
 
AttributeMap fColorMap
 A map between a material name and a color. More...
 
std::vector< G4String > fPrintMass
 A vector of volume names to print. More...
 
std::set< G4String > fPrintedMass
 A map of which masses have been printed. More...
 
std::vector< G4String > fNameStack
 
std::map< G4LogicalVolume *, TGeoVolume * > fKnownVolumes
 
bool fCreateAllVolumes
 

Static Private Attributes

static EDepSim::RootGeometryManagerfThis = NULL
 The pointer to the instantiation of this object. More...
 

Detailed Description

Definition at line 32 of file EDepSimRootGeometryManager.hh.

Member Typedef Documentation

typedef std::map<G4String,DrawAttributes> EDepSim::RootGeometryManager::AttributeMap
private

Definition at line 38 of file EDepSimRootGeometryManager.hh.

Constructor & Destructor Documentation

EDepSim::RootGeometryManager::~RootGeometryManager ( )
virtual

Definition at line 69 of file EDepSimRootGeometryManager.cc.

69 {}
EDepSim::RootGeometryManager::RootGeometryManager ( )
protected

use Get() instead

Definition at line 61 of file EDepSimRootGeometryManager.cc.

61  {
62 }

Member Function Documentation

TGeoMedium * EDepSim::RootGeometryManager::AverageMaterial ( const G4VPhysicalVolume *  theVol)
privatevirtual

Create a medium that describes the average composition for all the materials in the logical volume. This is used when the geometry is simplified by not including sub-volume (i.e. when the internal structure of the scintillating bars is skipped). The averaged material name is based on the name provided in materialBase;

Definition at line 984 of file EDepSimRootGeometryManager.cc.

985  {
986  G4LogicalVolume* theLog = thePhys->GetLogicalVolume();
987  double totalMass = theLog->GetMass(true);
988  double totalVolume = theLog->GetSolid()->GetCubicVolume();
989  double totalDensity = totalMass/totalVolume;
990  std::ostringstream nameStream;
991  nameStream << MaterialName(thePhys)
992  << "Avg" << totalDensity/(CLHEP::g/CLHEP::cm3);
993  std::string averageName = nameStream.str();
994  TGeoMedium* avgMedium = fMedium[averageName];
995  if (avgMedium) return avgMedium;
996  // Create a map of the material pointer and the mass of that material that
997  // is contributing to the mixture. This will be used to calculate the
998  // average radiation length and interaction length.
999  std::map< const G4Material* , double > materialMass;
1000  // Create a map of element names and the amount of that element in the
1001  // mixture.
1002  std::map<std::string,double> componentMass;
1003  // Create a stack to walk the geometry tree.
1004  std::vector<const G4VPhysicalVolume*> stack;
1005  stack.push_back(thePhys);
1006  while (!stack.empty()) {
1007  // Get the new current volume off the stack.
1008  const G4VPhysicalVolume* currentPhys = stack.back();
1009  G4LogicalVolume* currentLog = currentPhys->GetLogicalVolume();
1010  stack.pop_back();
1011  // Add all of the current children to the stack.
1012  for (std::size_t child = 0;
1013  child < currentLog->GetNoDaughters();
1014  ++child) {
1015  stack.push_back(currentLog->GetDaughter(child));
1016  }
1017  // Add the mass of each element in the current volume.
1018  double mass = currentLog->GetMass(true,false);
1019  G4Material *mat = currentLog->GetMaterial();
1020  materialMass[mat] += mass;
1021  for (unsigned i = 0; i < mat->GetNumberOfElements(); ++i) {
1022  const G4Element *elem = mat->GetElement(i);
1023  for (unsigned j = 0; j < elem->GetNumberOfIsotopes(); ++j) {
1024  // Find the isotope for this element and create it if it
1025  // doesn't exist
1026  std::string isoName = elem->GetIsotope(j)->GetName();
1027  componentMass[isoName] += mass
1028  *(mat->GetFractionVector()[i])
1029  *(elem->GetRelativeAbundanceVector()[j]);
1030  }
1031  }
1032  }
1033  TGeoMixture *theMix
1034  = new TGeoMixture(averageName.c_str(),
1035  componentMass.size(),
1036  totalDensity);
1037  for (std::map<std::string,double>::iterator c = componentMass.begin();
1038  c != componentMass.end();
1039  ++c) {
1040  TGeoElement* elem = fIsotope[c->first];
1041  theMix->AddElement(elem,c->second/totalMass);
1042  }
1043  double radLen = 0;
1044  double intLen = 0;
1045  double massSum = 0;
1047  mat = materialMass.begin();
1048  mat != materialMass.end();
1049  ++mat) {
1050  const G4Material* material = mat->first;
1051  double mass = mat->second;
1052  massSum += mass;
1053  radLen += mass/material->GetRadlen();
1054  intLen += mass/material->GetNuclearInterLength();
1055  }
1056  if (massSum>0.0) {
1057  // The minus sign is to make sure this over-rides the approximate ROOT
1058  // radiation and interaction length calculations.
1059  theMix->SetRadLen(-massSum/radLen,-massSum/intLen);
1060  }
1061  int numed = fMedium.size() + 1;
1062  TGeoMedium* theMedium = new TGeoMedium(averageName.c_str(),numed,theMix);
1063  fMedium[averageName] = theMedium;
1064  return theMedium;
1065 }
intermediate_table::iterator iterator
std::map< G4String, TGeoMedium * > fMedium
A map between G4 material names and Root Material definitions.
static constexpr double g
Definition: Units.h:144
std::string string
Definition: nybbler.cc:12
static constexpr double cm3
Definition: Units.h:70
virtual std::string MaterialName(const G4VPhysicalVolume *theVol)
std::map< G4String, TGeoElement * > fIsotope
A map between G4 isotope names and Root Element definitions.
bool EDepSim::RootGeometryManager::CreateEnvelope ( const G4VPhysicalVolume *  theVol,
TGeoManager *  theEnvelope,
TGeoVolume *  theMother 
)
private

Save the detector envelope. This is called recursively to fill in the entire detector. The G4 physical volume, theVol, is used to create a new root TGeoVolume which is added to the existing root TGeoVolume, theMother, as a daughter.

RETURN VALUE: This returns true if one of the immediate daughter volumes was ignored. This tells the mother volume that it will need to adjust it's mass and material to account for the missing detail.

Definition at line 620 of file EDepSimRootGeometryManager.cc.

623  {
624 
625  if (IgnoreVolume(theG4PhysVol)) return true;
626 
627  // The new volume that will be added to the mother volume. This is
628  // created in this function.
629  TGeoVolume* theVolume = NULL;
630  G4LogicalVolume* theLog = theG4PhysVol->GetLogicalVolume();
631 
632  if (PrintMass(theG4PhysVol)) {
633  EDepSimLog("%%% Mass: "
634  << G4BestUnit(theLog->GetMass(true),"Mass")
635  << " Volume: " << theG4PhysVol->GetName());
636  }
637 
638  // Get the name of the expected name of the volume.
639  std::string theVolumeName;
641  n != fNameStack.end();
642  ++n) {
643  theVolumeName += "/";
644  theVolumeName += *n;
645  }
646 
647  // Get the volume information from G4.
648  const G4VSolid* theSolid = theLog->GetSolid();
649  const G4String geometryType = theSolid->GetEntityType();
650  std::string theFullName = theG4PhysVol->GetName();
651  std::string theShortName = theFullName;
652  theShortName.erase(0,theShortName.rfind("/")+1);
653 
654  // The volume name is built from all the short names in the path to this
655  // volume. This is different than the full name which is built based on
656  // the constructor tree.
657  theVolumeName += "/";
658  theVolumeName += theShortName;
659 
660  // Check the volume names for validity. If they don't match then just
661  // force it.
662  if (theShortName == theFullName) {
663  theFullName = theVolumeName;
664  }
665 
666  // Make sure there isn't a bug in the naming. There should never be a
667  // "//" in the name.
668  if (theFullName.find("//") != std::string::npos) {
669  EDepSimError("Invalid volume name: " << theFullName);
670  EDepSimError(" Expected name is: " << theVolumeName);
671  theFullName = theVolumeName;
672  }
673 
674  // Find the medium for this volume.
675  std::string materialName = theLog->GetMaterial()->GetName();
676  TGeoMedium *theMedium = fMedium[materialName];
677  if (!theMedium) {
678  EDepSimError("MISSING MATERIAL IS " << materialName);
679  EDepSimThrow("Material definition is missing");
680  }
681 
682  if (!fCreateAllVolumes) {
684  seenVolume = fKnownVolumes.find(theLog);
685  if (seenVolume != fKnownVolumes.end()) theVolume = seenVolume->second;
686  }
687 
688  if (!theVolume) {
689  // Create the root volume (the solid in G4 lingo).
690  theVolume = CreateVolume(theSolid, theShortName, theMedium);
691  if (!theVolume) theVolume = theMother;
692  theVolume->SetTitle(theVolumeName.c_str());
693 
694  // Set the visual properties of the new volume
695  int color = GetColor(theG4PhysVol);
696  double opacity = GetOpacity(theG4PhysVol);
697  theVolume->SetVisContainers(true);
698  if (color < 0 || opacity < 0.001) {
699  theVolume->SetVisibility(false);
700  }
701  else {
702  int i = 100.0*(1.0-opacity);
703  if (i>100) i = 100;
704  EDepSimInfo("Set color of " << theShortName
705  << " to " << color
706  << " " << opacity
707  << " " << i);
708  theVolume->SetLineColor(color);
709  theVolume->SetTransparency(i);
710  theVolume->SetVisibility(true);
711  }
712 
713  // There is no mother so set this as the top volume.
714  if (!theMother) {
715  EDepSimLog("Making \"" << theVolume->GetName() << "\" the top\n");
716  theEnvelope->SetTopVolume(theVolume);
717  }
718 
719  // Push the name of this volume onto the stack before creating the
720  // children.
721  fNameStack.push_back(theShortName);
722 
723  // Add the children to the daughter.
724  double missingMass = 0.0;
725  for (std::size_t child = 0;
726  child < theLog->GetNoDaughters();
727  ++child) {
728  G4VPhysicalVolume* theChild = theLog->GetDaughter(child);
729  if (theLog->GetNoDaughters() > 20000) {
730  G4LogicalVolume *skippedVolume = theChild->GetLogicalVolume();
731  missingMass += skippedVolume->GetMass(true);
732  }
733  else if (CreateEnvelope(theChild, theEnvelope, theVolume)) {
734  G4LogicalVolume *skippedVolume = theChild->GetLogicalVolume();
735  missingMass += skippedVolume->GetMass(true);
736  }
737  }
738  // Remove this volume from the name stack.
739  fNameStack.pop_back();
740 
741  // A some daughter volumes were ignored and so the density of this
742  // volume needs to be adjusted.
743  if (missingMass > 0.0) {
744  // The correction of the material needs to be implemented.
745  double totalMass = theLog->GetMass(true);
746  double totalVolume = theLog->GetSolid()->GetCubicVolume();
747  double totalDensity = totalMass/totalVolume;
749  "ROOTGeom", "Skipping sub-volumes. Correct "
750  << theMedium->GetName() << " density "
751  << theMedium->GetMaterial()->GetDensity()/(CLHEP::g/CLHEP::cm3)
752  << " g/cm3 to "
753  << totalDensity/(CLHEP::g/CLHEP::cm3) << " g/cm3");
754  TGeoMedium *avgMedium = AverageMaterial(theG4PhysVol);
755  if (avgMedium) theVolume->SetMedium(avgMedium);
756  }
757 
758  // Put this volume into the known volumes.
759  fKnownVolumes[theLog] = theVolume;
760  }
761 
762  // Apply the rotation for theMother volume. This is only done if the
763  // theMother is not the top level volume for the envelope so that the
764  // detector has the proper orientation.
765  if (theMother && (theMother != theVolume)) {
766  G4ThreeVector trans = theG4PhysVol->GetObjectTranslation();
767  G4RotationMatrix* rot = theG4PhysVol->GetObjectRotation();
768  TGeoRotation* rotate =
769  new TGeoRotation("rot",
770  TMath::RadToDeg()*rot->thetaX(),
771  TMath::RadToDeg()*rot->phiX(),
772  TMath::RadToDeg()*rot->thetaY(),
773  TMath::RadToDeg()*rot->phiY(),
774  TMath::RadToDeg()*rot->thetaZ(),
775  TMath::RadToDeg()*rot->phiZ());
776  if (theG4PhysVol->IsReplicated()) {
777  EAxis a; G4int nRep; G4double w; G4double o; G4bool c;
778  G4ThreeVector axis;
779  theG4PhysVol->GetReplicationData(a,nRep,w,o,c);
780  switch (a) {
781  case kXAxis: axis.set(1,0,0); break;
782  case kYAxis: axis.set(0,1,0); break;
783  case kZAxis: axis.set(0,0,1); break;
784  default:
785  EDepSimThrow("EDepSim::RootGeometryManager::CreateEnvelope:"
786  "Bad replication data.");
787  }
788  for (int i=0; i<nRep; ++i) {
789  G4ThreeVector pos = axis*w*(i-0.5*(nRep-1));
790  TGeoCombiTrans* combi
791  = new TGeoCombiTrans(pos.x()/CLHEP::mm,
792  pos.y()/CLHEP::mm,
793  pos.z()/CLHEP::mm,
794  rotate);
795  int index = HowManySimilarNodesInVolume(theMother,
796  theVolume->GetName());
797  theMother->AddNode(theVolume,index,combi);
798  }
799  }
800  else {
801  TGeoCombiTrans* combi
802  = new TGeoCombiTrans(trans.x()/CLHEP::mm,
803  trans.y()/CLHEP::mm,
804  trans.z()/CLHEP::mm,
805  rotate);
806  int index = HowManySimilarNodesInVolume(theMother,
807  theVolume->GetName());
808  theMother->AddNode(theVolume,index,combi);
809  }
810  }
811 
812  return false;
813 }
#define EDepSimLog(outStream)
Definition: EDepSimLog.hh:717
double GetOpacity(const G4VPhysicalVolume *vol)
intermediate_table::iterator iterator
#define EDepSimNamedDebug(trace, outStream)
Definition: EDepSimLog.hh:634
std::map< G4String, TGeoMedium * > fMedium
A map between G4 material names and Root Material definitions.
static constexpr double g
Definition: Units.h:144
std::string string
Definition: nybbler.cc:12
static constexpr double cm3
Definition: Units.h:70
virtual TGeoMedium * AverageMaterial(const G4VPhysicalVolume *theVol)
virtual bool IgnoreVolume(const G4VPhysicalVolume *theVol)
#define EDepSimThrow(message)
Print an error message, and then throw an exception.
#define EDepSimInfo(outStream)
Definition: EDepSimLog.hh:752
TGeoVolume * CreateVolume(const G4VSolid *theSolid, std::string theName, TGeoMedium *theMedium)
Create a new ROOT volume object.
int GetColor(const G4VPhysicalVolume *vol)
std::void_t< T > n
const double a
virtual bool PrintMass(const G4VPhysicalVolume *theVol)
A method to flag that a volume mass should be printed.
std::size_t color(std::string const &procname)
int HowManySimilarNodesInVolume(TGeoVolume *theMother, std::string theName)
bool CreateEnvelope(const G4VPhysicalVolume *theVol, TGeoManager *theEnvelope, TGeoVolume *theMother)
#define EDepSimError(outStream)
Definition: EDepSimLog.hh:503
std::map< G4LogicalVolume *, TGeoVolume * > fKnownVolumes
static constexpr double mm
Definition: Units.h:65
void EDepSim::RootGeometryManager::CreateMaterials ( const G4VPhysicalVolume *  theVol)
private

Create the materials needed for the detector. This called recursively to find all of the materials in the detector.

Definition at line 518 of file EDepSimRootGeometryManager.cc.

519  {
520 
521  G4LogicalVolume* theLog = theG4PhysVol->GetLogicalVolume();
522 
523  // Find the medium for this volume and create it if it doesn't exist.
524  TGeoMedium *theMedium = fMedium[theLog->GetMaterial()->GetName()];
525 
526  if (!theMedium) {
527  G4Material *mat = theLog->GetMaterial();
528  if (mat->GetNumberOfElements()==0) {
529  EDepSimError("Material without elements " << mat->GetName());
530  EDepSimThrow("Material defined without elements");
531  }
532  // Make a mixture
533  TGeoMixture *theMix
534  = new TGeoMixture(mat->GetName(),
535  mat->GetNumberOfElements(),
536  mat->GetDensity());
537  unsigned ielement = 0;
538  theMix->SetTemperature(mat->GetTemperature());
539  // The minus sign is to make sure this over-rides the approximate ROOT
540  // radiation and interaction length calculations.
541  switch (mat->GetState()) {
542  case kStateSolid:
543  theMix->SetState(TGeoMaterial::kMatStateSolid);
544  break;
545  case kStateLiquid:
546  theMix->SetState(TGeoMaterial::kMatStateLiquid);
547  theMix->SetPressure(mat->GetPressure());
548  break;
549  case kStateGas:
550  theMix->SetState(TGeoMaterial::kMatStateGas);
551  theMix->SetPressure(mat->GetPressure());
552  break;
553  default:
554  theMix->SetState(TGeoMaterial::kMatStateUndefined);
555  }
556  for (unsigned i = 0; i < mat->GetNumberOfElements(); ++i) {
557  const G4Element *elem = mat->GetElement(i);
558  for (unsigned j = 0; j < elem->GetNumberOfIsotopes(); ++j) {
559  const G4Isotope *iso = elem->GetIsotope(j);
560  theMix->DefineElement(ielement,
561  iso->GetA()/(CLHEP::g/CLHEP::mole),
562  iso->GetZ(),
563  (mat->GetFractionVector()[i])*
564  (elem->GetRelativeAbundanceVector()[j]));
565  // Find the isotope for this element and create it if it
566  // doesn't exist
567  TGeoElement *theIsotope = fIsotope[iso->GetName()];
568  if (!theIsotope) {
569  // Make an element (isotope)
570  TGeoElement *theEle
571  = new TGeoElement(iso->GetName(),
572  elem->GetSymbol(),
573  iso->GetZ(),
574  iso->GetA()/(CLHEP::g/CLHEP::mole));
575  fIsotope[iso->GetName()] = theEle;
576  }
577  ielement++;
578  }
579  }
580  theMix->SetRadLen(-mat->GetRadlen(), -mat->GetNuclearInterLength());
581  int numed = fMedium.size() + 1;
582  theMedium = new TGeoMedium(mat->GetName(),numed,theMix);
583  fMedium[mat->GetName()] = theMedium;
584  }
585 
586  // Recurse through the children.
587  for (std::size_t child = 0;
588  child < theLog->GetNoDaughters();
589  ++child) {
590  G4VPhysicalVolume* theChild = theLog->GetDaughter(child);
591  CreateMaterials(theChild);
592  }
593 }
std::map< G4String, TGeoMedium * > fMedium
A map between G4 material names and Root Material definitions.
static constexpr double g
Definition: Units.h:144
#define EDepSimThrow(message)
Print an error message, and then throw an exception.
void CreateMaterials(const G4VPhysicalVolume *theVol)
#define EDepSimError(outStream)
Definition: EDepSimLog.hh:503
std::map< G4String, TGeoElement * > fIsotope
A map between G4 isotope names and Root Element definitions.
TGeoShape * EDepSim::RootGeometryManager::CreateShape ( const G4VSolid *  theSolid,
TGeoMatrix **  mat = NULL 
)
private

Create a new ROOT shape object based on the G4 solid. This might be called recursively if a G4 boolean solid is found.

Definition at line 224 of file EDepSimRootGeometryManager.cc.

225  {
226  const G4String geometryType = theSolid->GetEntityType();
227  TGeoShape* theShape = NULL;
228  if (geometryType == "G4Box") {
229  // Create a box
230  const G4Box* box = dynamic_cast<const G4Box*>(theSolid);
231  theShape = new TGeoBBox(box->GetXHalfLength()/CLHEP::mm,
232  box->GetYHalfLength()/CLHEP::mm,
233  box->GetZHalfLength()/CLHEP::mm);
234  }
235  else if (geometryType == "G4Tubs") {
236  const G4Tubs* tube = dynamic_cast<const G4Tubs*>(theSolid);
237  // Root takes the angles in degrees so there is no extra
238  // conversion.
239  double zhalf = tube->GetZHalfLength()/CLHEP::mm;
240  double rmin = tube->GetInnerRadius()/CLHEP::mm;
241  double rmax = tube->GetOuterRadius()/CLHEP::mm;
242  double minPhiDeg = tube->GetStartPhiAngle()/CLHEP::degree;
243  double maxPhiDeg = minPhiDeg + tube->GetDeltaPhiAngle()/CLHEP::degree;
244  theShape = new TGeoTubeSeg(rmin, rmax,
245  zhalf,
246  minPhiDeg, maxPhiDeg);
247  }
248  else if (geometryType == "G4Sphere") {
249  const G4Sphere* sphere = dynamic_cast<const G4Sphere*>(theSolid);
250  // Root takes the angles in degrees so there is no extra
251  // conversion.
252  double minPhiDeg = sphere->GetStartPhiAngle()/CLHEP::degree;
253  double maxPhiDeg = minPhiDeg + sphere->GetDeltaPhiAngle()/CLHEP::degree;
254  double minThetaDeg = sphere->GetStartThetaAngle()/CLHEP::degree;
255  double maxThetaDeg = minThetaDeg + sphere->GetDeltaThetaAngle()/CLHEP::degree;
256  theShape = new TGeoSphere(sphere->GetInnerRadius()/CLHEP::mm,
257  sphere->GetOuterRadius()/CLHEP::mm,
258  minThetaDeg, maxThetaDeg,
259  minPhiDeg, maxPhiDeg);
260  }
261  else if (geometryType == "G4Polyhedra") {
262  const G4Polyhedra* polyhedra
263  = dynamic_cast<const G4Polyhedra*>(theSolid);
264  double phi = polyhedra->GetStartPhi();
265  double dPhi = polyhedra->GetEndPhi() - phi;
266  if (dPhi>2*M_PI) dPhi -= 2*M_PI;
267  if (dPhi<0) dPhi += 2*M_PI;
268  int sides = polyhedra->GetNumSide();
269  int numZ = polyhedra->GetNumRZCorner()/2;
270  // Factor to take into account that ROOT uses the circle that can be
271  // inscribed inside the polygon, and G4 uses the corner
272  double g4Factor = std::cos(0.5*dPhi/sides);
273  TGeoPgon* pgon = new TGeoPgon(phi/CLHEP::degree,
274  dPhi/CLHEP::degree, sides, numZ);
275  for (int i = 0; i< numZ; ++i) {
276  double rMin = g4Factor*polyhedra->GetCorner(numZ-i-1).r;
277  double rMax = g4Factor*polyhedra->GetCorner(numZ+i).r;
278  if (rMax < rMin) std::swap(rMin,rMax);
279  pgon->DefineSection(i,
280  polyhedra->GetCorner(numZ-i-1).z/CLHEP::mm,
281  rMin/CLHEP::mm,
282  rMax/CLHEP::mm);
283  }
284  theShape = pgon;
285  }
286  else if (geometryType == "G4Polycone") {
287  const G4Polycone* polycone
288  = dynamic_cast<const G4Polycone*>(theSolid);
289  double phi = polycone->GetStartPhi();
290  double dPhi = polycone->GetEndPhi() - phi;
291  if (dPhi>2*M_PI) dPhi -= 2*M_PI;
292  if (dPhi<0) dPhi += 2*M_PI;
293 #ifdef G4GEOM_USE_USOLIDS
294 #warning GEANT HAS BEEN COMPILED WITH BROKEN USOLIDS.
295  int numZ = polycone->GetNumRZCorner()/2;
296  TGeoPcon* pcon = new TGeoPcon(phi/CLHEP::degree,
297  dPhi/CLHEP::degree, numZ);
298  // This depends on the (mostly) undocumented order of the corners in
299  // the G4Polycone internals. It's a little unstable...
300  for (int i = 0; i< numZ; ++i) {
301  pcon->DefineSection(i,
302  polycone->GetCorner(numZ-i-1).z/CLHEP::mm,
303  polycone->GetCorner(numZ-i-1).r/CLHEP::mm,
304  polycone->GetCorner(numZ+i).r/CLHEP::mm);
305  }
306 #else
307  const G4PolyconeHistorical* param = polycone->GetOriginalParameters();
308  int numZ = param->Num_z_planes;
309  TGeoPcon* pcon = new TGeoPcon(phi/CLHEP::degree, dPhi/CLHEP::degree, numZ);
310  // This depends on the older interface. It's not marked as
311  // deprecated, but the documentation discourages it's use.
312  for (int i = 0; i< numZ; ++i) {
313  pcon->DefineSection(i,
314  param->Z_values[i]/CLHEP::mm,
315  param->Rmin[i]/CLHEP::mm,
316  param->Rmax[i]/CLHEP::mm);
317  }
318 #endif
319  theShape = pcon;
320  }
321  else if (geometryType == "G4Trap") {
322  const G4Trap* trap
323  = dynamic_cast<const G4Trap*>(theSolid);
324  double dz = trap->GetZHalfLength()/CLHEP::mm;
325  double theta = 0;
326  double phi = 0;
327  double h1 = trap->GetYHalfLength1()/CLHEP::mm;
328  double bl1 = trap->GetXHalfLength1()/CLHEP::mm;
329  double tl1 = trap->GetXHalfLength2()/CLHEP::mm;
330  double alpha1 = std::atan(trap->GetTanAlpha1())/CLHEP::degree;
331  double h2 = trap->GetYHalfLength2()/CLHEP::mm;
332  double bl2 = trap->GetXHalfLength3()/CLHEP::mm;
333  double tl2 = trap->GetXHalfLength4()/CLHEP::mm;
334  double alpha2 = std::atan(trap->GetTanAlpha2())/CLHEP::degree;
335  theShape = new TGeoTrap(dz, theta, phi,
336  h1, bl1, tl1, alpha1,
337  h2, bl2, tl2, alpha2);
338  }
339  else if (geometryType == "G4Trd") {
340  const G4Trd* trd
341  = dynamic_cast<const G4Trd*>(theSolid);
342  double dz = trd->GetZHalfLength()/CLHEP::mm;
343  double dx1 = trd->GetXHalfLength1()/CLHEP::mm;
344  double dx2 = trd->GetXHalfLength2()/CLHEP::mm;
345  double dy1 = trd->GetYHalfLength1()/CLHEP::mm;
346  double dy2 = trd->GetYHalfLength2()/CLHEP::mm;
347  theShape = new TGeoTrd2(dx1,dx2,dy1,dy2,dz);
348  }
349  else if (geometryType == "G4SubtractionSolid") {
350  const G4SubtractionSolid* sub
351  = dynamic_cast<const G4SubtractionSolid*>(theSolid);
352  const G4VSolid* solidA = sub->GetConstituentSolid(0);
353  const G4VSolid* solidB = sub->GetConstituentSolid(1);
354  // solidA - solidB
355  TGeoMatrix* matrixA = NULL;
356  TGeoShape* shapeA = CreateShape(solidA, &matrixA);
357  TGeoMatrix* matrixB = NULL;
358  TGeoShape* shapeB = CreateShape(solidB, &matrixB);
359  TGeoSubtraction* subtractNode = new TGeoSubtraction(shapeA,shapeB,
360  matrixA, matrixB);
361  theShape = new TGeoCompositeShape("name",subtractNode);
362  }
363  else if (geometryType == "G4DisplacedSolid") {
364  const G4DisplacedSolid* disp
365  = dynamic_cast<const G4DisplacedSolid*>(theSolid);
366  const G4VSolid* movedSolid = disp->GetConstituentMovedSolid();
367  G4RotationMatrix rotation = disp->GetObjectRotation();
368  G4ThreeVector displacement = disp->GetObjectTranslation();
369  theShape = CreateShape(movedSolid);
370  if (returnMatrix) {
371  TGeoRotation* rotate
372  = new TGeoRotation("rot",
373  TMath::RadToDeg()*rotation.thetaX(),
374  TMath::RadToDeg()*rotation.phiX(),
375  TMath::RadToDeg()*rotation.thetaY(),
376  TMath::RadToDeg()*rotation.phiY(),
377  TMath::RadToDeg()*rotation.thetaZ(),
378  TMath::RadToDeg()*rotation.phiZ());
379  *returnMatrix = new TGeoCombiTrans(displacement.x()/CLHEP::mm,
380  displacement.y()/CLHEP::mm,
381  displacement.z()/CLHEP::mm,
382  rotate);
383  }
384  }
385  else if (geometryType == "G4UnionSolid") {
386  const G4UnionSolid* sub
387  = dynamic_cast<const G4UnionSolid*>(theSolid);
388  const G4VSolid* solidA = sub->GetConstituentSolid(0);
389  const G4VSolid* solidB = sub->GetConstituentSolid(1);
390  // solidA - solidB
391  TGeoMatrix* matrixA = NULL;
392  TGeoShape* shapeA = CreateShape(solidA, &matrixA);
393  TGeoMatrix* matrixB = NULL;
394  TGeoShape* shapeB = CreateShape(solidB, &matrixB);
395  TGeoUnion* unionNode = new TGeoUnion(shapeA, shapeB,
396  matrixA, matrixB);
397  theShape = new TGeoCompositeShape("name",unionNode);
398  }
399  else if (geometryType == "G4IntersectionSolid") {
400  const G4IntersectionSolid* sub
401  = dynamic_cast<const G4IntersectionSolid*>(theSolid);
402  const G4VSolid* solidA = sub->GetConstituentSolid(0);
403  const G4VSolid* solidB = sub->GetConstituentSolid(1);
404  // solidA - solidB
405  TGeoMatrix* matrixA = NULL;
406  TGeoShape* shapeA = CreateShape(solidA, &matrixA);
407  TGeoMatrix* matrixB = NULL;
408  TGeoShape* shapeB = CreateShape(solidB, &matrixB);
409  TGeoIntersection* intersectionNode = new TGeoIntersection(shapeA, shapeB,
410  matrixA, matrixB);
411  theShape = new TGeoCompositeShape("name",intersectionNode);
412  }
413 
414  else if (geometryType == "G4ExtrudedSolid"){
415  //This following only works when using the 'standard'
416  //G4ExtrudedSolid Constructor.
417 
418  const G4ExtrudedSolid* extr
419  = dynamic_cast<const G4ExtrudedSolid*>(theSolid);
420 
421  //number of z planes
422  const G4int nZ = extr->GetNofZSections();
423  //number of vertices in the polygon
424  const G4int nV = extr->GetNofVertices();
425 
426  //define and pointers
427  const int maxVertices = 1000;
428  double vertices_x[maxVertices];
429  double vertices_y[maxVertices];
430  if (maxVertices < nV) {
431  EDepSimThrow("Polygon with more than maxVertices");
432  }
433 
434 
435  //define an intermediate extrusion constructor with nZ z planes.
436  TGeoXtru *xtru = new TGeoXtru(nZ);
437 
438  //Get the polygons points.
439  std::vector<G4TwoVector> polyPoints = extr->GetPolygon();
440 
441  //fill the vertices arrays
442  for(int i = 0 ; i < nV ; i++){
443  vertices_x[i]= polyPoints[i].x();
444  vertices_y[i]= polyPoints[i].y();
445  }
446 
447  //Define the polygon
448  xtru->DefinePolygon(nV, vertices_x, vertices_y);
449 
450  double z_pos, x_off, y_off, scale;
451 
452  //fill the parameters to define the Root extruded solid
453  for(int i = 0 ; i < nZ ; i++){
454  z_pos = extr->GetZSection(i).fZ;
455  x_off = extr->GetZSection(i).fOffset.x() ;
456  y_off = extr->GetZSection(i).fOffset.y();
457  scale = extr->GetZSection(i).fScale;
458  xtru->DefineSection(i, z_pos, x_off, y_off, scale);
459  }
460  //now assign 'theShape' to this complete extruded object.
461  theShape = xtru;
462  }
463  else {
464  EDepSimThrow(geometryType+" --> shape not implemented");
465  }
466 
467  return theShape;
468 }
#define EDepSimThrow(message)
Print an error message, and then throw an exception.
void swap(Handle< T > &a, Handle< T > &b)
#define M_PI
Definition: includeROOT.h:54
TGeoShape * CreateShape(const G4VSolid *theSolid, TGeoMatrix **mat=NULL)
static constexpr double mm
Definition: Units.h:65
static constexpr double degree
Definition: Units.h:161
std::string sub(const std::string &a, const std::string &b)
Definition: TruthText.cxx:100
TGeoVolume * EDepSim::RootGeometryManager::CreateVolume ( const G4VSolid *  theSolid,
std::string  theName,
TGeoMedium *  theMedium 
)
private

Create a new ROOT volume object.

Definition at line 471 of file EDepSimRootGeometryManager.cc.

473  {
474  TGeoShape* theShape = CreateShape(theSolid);
475  TGeoVolume* theVolume = new TGeoVolume(theName.c_str(),
476  theShape,
477  theMedium);
478  return theVolume;
479 }
TGeoShape * CreateShape(const G4VSolid *theSolid, TGeoMatrix **mat=NULL)
void EDepSim::RootGeometryManager::Export ( const char *  file)

Export the geometry to a file.

Definition at line 71 of file EDepSimRootGeometryManager.cc.

71  {
72  EDepSimLog(" *** Export to " << file);
73  gGeoManager->Export(file);
74 }
#define EDepSimLog(outStream)
Definition: EDepSimLog.hh:717
EDepSim::RootGeometryManager * EDepSim::RootGeometryManager::Get ( void  )
static

If a persistency manager has not been created, create one.

Definition at line 64 of file EDepSimRootGeometryManager.cc.

64  {
66  return fThis;
67 }
static EDepSim::RootGeometryManager * fThis
The pointer to the instantiation of this object.
int EDepSim::RootGeometryManager::GetColor ( const G4VPhysicalVolume *  vol)
protected

Find the right color for a physical volume. This won't necessarily be the same color as set in G4, but should be a reasonable choice for a detector picture. This will return a negative number if the volume should be invisible.

Definition at line 870 of file EDepSimRootGeometryManager.cc.

870  {
871  const G4LogicalVolume* log = vol->GetLogicalVolume();
872  std::string theFullName = vol->GetName();
873 
874  const G4VisAttributes* visAttributes = log->GetVisAttributes();
875  if (!visAttributes) {
876  return -1;
877  }
878 
879  int index = -1;
880  double minDist = 10000;
881  G4Color g4Color = visAttributes->GetColor();
882 
883  // Check the primary color wheel.
884  const int rootPrimaryColors[] = {
885  kRed, kMagenta, kBlue, kCyan, kGreen, kYellow, -1
886  };
887  for(const int* rootBaseColor = rootPrimaryColors;
888  0 <= *rootBaseColor;
889  ++rootBaseColor) {
890  for (int i = -10; i<5; ++i) {
891  int iColor = *rootBaseColor + i;
892  TColor* rootColor = gROOT->GetColor(iColor);
893  if (!rootColor) continue;
894  double dR = (rootColor->GetRed() - g4Color.GetRed());
895  double dG = (rootColor->GetGreen() - g4Color.GetGreen());
896  double dB = (rootColor->GetBlue() - g4Color.GetBlue());
897  double dist = std::sqrt(dR*dR + dG*dG + dB*dB);
898  if (dist > minDist) continue;
899  index = iColor;
900  minDist = dist;
901  }
902  }
903 
904  // Check the secondary colors defined by ROOT.
905  const int rootSecondaryColors[] = {
906  kPink, kMagenta, kViolet, kTeal, kSpring, kOrange, -1
907  };
908  for(const int* rootBaseColor = rootSecondaryColors;
909  0 <= *rootBaseColor;
910  ++rootBaseColor) {
911  for (int i = -9; i<=10; ++i) {
912  int iColor = *rootBaseColor + i;
913  TColor* rootColor = gROOT->GetColor(iColor);
914  if (!rootColor) continue;
915  double dR = (rootColor->GetRed() - g4Color.GetRed());
916  double dG = (rootColor->GetGreen() - g4Color.GetGreen());
917  double dB = (rootColor->GetBlue() - g4Color.GetBlue());
918  double dist = std::sqrt(dR*dR + dG*dG + dB*dB);
919  if (dist > minDist) continue;
920  index = iColor;
921  minDist = dist;
922  }
923  }
924 
925  // Check the different colors of "black"
926  const int rootBlackColors[] = {
927  kGray, kGray+1, kGray+2, kGray+3, kBlack, -1
928  };
929  for(const int* rootBaseColor = rootBlackColors;
930  0 <= *rootBaseColor;
931  ++rootBaseColor) {
932  TColor* rootColor = gROOT->GetColor(*rootBaseColor);
933  if (!rootColor) continue;
934  double dR = (rootColor->GetRed() - g4Color.GetRed());
935  double dG = (rootColor->GetGreen() - g4Color.GetGreen());
936  double dB = (rootColor->GetBlue() - g4Color.GetBlue());
937  double dist = std::sqrt(dR*dR + dG*dG + dB*dB);
938  if (dist > minDist) continue;
939  index = *rootBaseColor;
940  minDist = dist;
941  }
942 
943  // Check the basic colors (the first 50 colors in root).
944  for(int rootBaseColor = 1;
945  rootBaseColor < 50;
946  ++rootBaseColor) {
947  TColor* rootColor = gROOT->GetColor(rootBaseColor);
948  if (!rootColor) continue;
949  double dR = (rootColor->GetRed() - g4Color.GetRed());
950  double dG = (rootColor->GetGreen() - g4Color.GetGreen());
951  double dB = (rootColor->GetBlue() - g4Color.GetBlue());
952  double dist = std::sqrt(dR*dR + dG*dG + dB*dB);
953  if (dist > minDist) continue;
954  index = rootBaseColor;
955  minDist = dist;
956  }
957 
958  return index;
959 }
std::string string
Definition: nybbler.cc:12
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
G4Color EDepSim::RootGeometryManager::GetG4Color ( G4Material *  material)

Get a color for a material. This can be used to create the G4VisAttributes object.

Definition at line 827 of file EDepSimRootGeometryManager.cc.

827  {
828  G4String materialName = material->GetName();
829  AttributeMap::const_iterator colorPair = fColorMap.find(materialName);
830 
831  int index = 0;
832  double alpha = 1.0;
833 
834  if (colorPair == fColorMap.end()) {
835  EDepSimError("Missing color for \"" << materialName << "\"");
836  fColorMap[materialName].color = kOrange+1;
837  fColorMap[materialName].fill = 0;
838  index = kOrange+1;
839  }
840  else {
841  index = colorPair->second.color;
842  alpha = colorPair->second.alpha;
843  }
844 
845 #include "rootColorToG4ColorMap.hxx"
846 
848 
849  return G4Color(color.GetRed(),color.GetGreen(),color.GetBlue(),
850  color.GetAlpha()*alpha);
851 }
AttributeMap fColorMap
A map between a material name and a color.
intermediate_table::const_iterator const_iterator
static std::map< int, G4Color > sRootColorToG4ColorMap
double alpha
Definition: doAna.cpp:15
std::size_t color(std::string const &procname)
#define EDepSimError(outStream)
Definition: EDepSimLog.hh:503
int EDepSim::RootGeometryManager::GetNodeId ( const G4ThreeVector &  pos)

Get a volume ID base on the volume position.

Definition at line 76 of file EDepSimRootGeometryManager.cc.

76  {
77  if (!gGeoManager) return -1;
78  gGeoManager->FindNode(pos.x(), pos.y(), pos.z());
79  return gGeoManager->GetCurrentNodeId();
80 }
double EDepSim::RootGeometryManager::GetOpacity ( const G4VPhysicalVolume *  vol)
protected

Get the opacity of the physical volume. This will return an opacity of zero (i.e. transparent) if the volume should be invisible.

Definition at line 853 of file EDepSimRootGeometryManager.cc.

853  {
854  const G4LogicalVolume* log = vol->GetLogicalVolume();
855  std::string theFullName = vol->GetName();
856 
857  const G4VisAttributes* visAttributes = log->GetVisAttributes();
858  if (!visAttributes) {
859  // Invisible if the visual attributes are missing...
860  return 0.0;
861  }
862 
863  G4Color g4Color = visAttributes->GetColor();
864  double opacity = g4Color.GetAlpha();
865  if (opacity > 1.0) opacity = 1.0;
866 
867  return opacity;
868 }
std::string string
Definition: nybbler.cc:12
int EDepSim::RootGeometryManager::HowManySimilarNodesInVolume ( TGeoVolume *  theMother,
std::string  theName 
)
private

Definition at line 597 of file EDepSimRootGeometryManager.cc.

598  {
599  daughterName = daughterName + "_";
600  int ndaughters = theMother->GetNdaughters();
601 
602  int ndaughters_samename = 0;
603  for(int i = 0; i < ndaughters; i++){
604  TGeoNode *node = theMother->GetNode(i);
605  if(node){
606  std::string name(node->GetName());
607  if(name.find(daughterName.c_str()) != std::string::npos)
608  ndaughters_samename++;
609  }
610  }
611 
612  return ndaughters_samename;
613 
614 }
static QCString name
Definition: declinfo.cpp:673
std::string string
Definition: nybbler.cc:12
int find(char c, int index=0, bool cs=TRUE) const
Definition: qcstring.cpp:41
bool EDepSim::RootGeometryManager::IgnoreVolume ( const G4VPhysicalVolume *  theVol)
privatevirtual

A method to prune the geometry that gets exported from G4 into root. If this returns true, the volume and all of it's children will not be exported to ROOT. This allows the internal structure of low level objects (i.e. the internal "structure" of scintillating bars) to be hidden.

Definition at line 484 of file EDepSimRootGeometryManager.cc.

484  {
485  std::string theFullName = theVol->GetName();
486  std::string theShortName = theFullName;
487  theShortName.erase(0,theShortName.rfind("/")+1);
488 
489  // Don't save the internal structure of extruded scintillating bars. This
490  // is required to make sure that hits get assigned to the right geometry
491  // volume in the ROOT geometry.
492  if (theFullName.find("Bar/Core") != std::string::npos) return true;
493  if (theFullName.find("Bar/CrnrOfBar") != std::string::npos) return true;
494  if (theFullName.find("Bar/SideOfBar") != std::string::npos) return true;
495 
496  return false;
497 }
std::string string
Definition: nybbler.cc:12
std::string EDepSim::RootGeometryManager::MaterialName ( const G4VPhysicalVolume *  theVol)
privatevirtual

A method to translate from the local volume material to the right material for the root geometry. This is required for volumes where the inner structure is not saved, and the material of the outer volume does not provide a good base name.

Definition at line 961 of file EDepSimRootGeometryManager.cc.

962  {
963  std::string theFullName = thePhys->GetName();
964  G4LogicalVolume* theLog = thePhys->GetLogicalVolume();
965  std::string materialName = theLog->GetMaterial()->GetName();
966 
967  // If this is a scintillator bar, then the base material name should be
968  // either FGDScintillator or Scintillator.
969  if (theFullName.find("/Bar") != std::string::npos) {
970  if (theFullName.find("/FGD") != std::string::npos) {
971  materialName = "FGDScintillator";
972  }
973  else if (theFullName.find("/P0D/") != std::string::npos) {
974  materialName = "P0DScintillator";
975  }
976  else {
977  materialName = "Scintillator";
978  }
979  }
980 
981  return materialName;
982 }
std::string string
Definition: nybbler.cc:12
bool EDepSim::RootGeometryManager::PrintMass ( const G4VPhysicalVolume *  theVol)
privatevirtual

A method to flag that a volume mass should be printed.

Definition at line 500 of file EDepSimRootGeometryManager.cc.

500  {
501  std::string theFullName = theVol->GetName();
502 
504  n != fPrintMass.end();
505  ++n) {
506  if (theFullName.find(*n) != std::string::npos) {
507  if (fPrintedMass.find(*n) != fPrintedMass.end()) continue;
508  fPrintedMass.insert(*n);
509  return true;
510  }
511  }
512 
513  return false;
514 }
intermediate_table::iterator iterator
std::string string
Definition: nybbler.cc:12
std::vector< G4String > fPrintMass
A vector of volume names to print.
std::void_t< T > n
std::set< G4String > fPrintedMass
A map of which masses have been printed.
void EDepSim::RootGeometryManager::SetDrawAtt ( G4Material *  material,
int  color,
double  opacity = 1.0 
)

Set material color.

Definition at line 815 of file EDepSimRootGeometryManager.cc.

816  {
817  G4String materialName = material->GetName();
818  fColorMap[materialName].color = color;
819  fColorMap[materialName].alpha = opacity;
820  if (opacity<0.01) fColorMap[materialName].fill = 0;
821  else if (opacity>0.99) fColorMap[materialName].fill = 1;
822  else {
823  fColorMap[materialName].fill = 4000+100*opacity;
824  }
825 }
AttributeMap fColorMap
A map between a material name and a color.
std::size_t color(std::string const &procname)
virtual void EDepSim::RootGeometryManager::ShouldPrintMass ( std::string  name)
inlinevirtual

A method to request that a volume mass should be printed;.

Definition at line 69 of file EDepSimRootGeometryManager.hh.

69  {
70  fPrintMass.push_back(name);
71  }
static QCString name
Definition: declinfo.cpp:673
std::vector< G4String > fPrintMass
A vector of volume names to print.
void EDepSim::RootGeometryManager::Update ( const G4VPhysicalVolume *  aWorld,
bool  validate 
)

Update the root geometry to match the g4 geometry.

Definition at line 93 of file EDepSimRootGeometryManager.cc.

94  {
95  EDepSimLog("%%%%%%%%%%%%%%%%%%%%%%%%%% Update ROOT Geometry "
96  << "%%%%%%%%%%%%%%%%%%%%%%%%%%" );
97  if (gGeoManager) {
98  EDepSimLog("%%%%%%%%%%%%%%% Warning: Replacing ROOT Geometry ");
99  delete gGeoManager;
100  // Clear the node counts definitions.
101  fNodeCount.clear();
102  // Clear the cached materials. The material objects are owned by the
103  // TGeoManager and are invalid after it has been deleted.
104  fMedium.clear();
105  // Clear the cached isotopes. This is a bit complicated since the
106  // isotope pointers may be duplicated in the map.
107  std::set<TGeoElement*> isotope;
109  i != fIsotope.end();
110  ++i) {
111  isotope.insert(i->second);
112  }
113  fIsotope.clear();
114  for (std::set<TGeoElement*>::iterator i = isotope.begin();
115  i != isotope.end();
116  ++i) {
117  delete *i;
118  }
119  }
120  // Create the new geometry.
121  gGeoManager = new TGeoManager("EDepSimGeometry",
122  "Simulated Detector Geometry");
123  gGeoManager->SetVisLevel(20);
124  // Create all of the materials.
125  EDepSimInfo("Create materials");
126  CreateMaterials(aWorld);
127 
128  //Check to see if we can create all of the volumes. This is done by
129  //traversing the GEANT physical volume tree.
130  fCreateAllVolumes = false;
131  if (CountVolumes(aWorld->GetLogicalVolume()) < 100000) {
132  EDepSimInfo("Create all volumes");
133  fCreateAllVolumes = true;
134  }
135 
136  // Create the ROOT geometry definitions.
137  fPrintedMass.clear();
138  fNameStack.clear();
139  fKnownVolumes.clear();
140  EDepSimInfo("Start defining envelope");
141  CreateEnvelope(aWorld,gGeoManager,NULL);
142  EDepSimInfo("Geometry is Filled");
143 
144  gGeoManager->CloseGeometry("di");
145 
146  EDepSimLog("Geometry initialized and closed");
147 
148  if (validateGeometry) return Validate();
149 }
#define EDepSimLog(outStream)
Definition: EDepSimLog.hh:717
intermediate_table::iterator iterator
std::map< G4String, int > fNodeCount
A map between G4 volume names and count of volumes with that name.
std::map< G4String, TGeoMedium * > fMedium
A map between G4 material names and Root Material definitions.
#define EDepSimInfo(outStream)
Definition: EDepSimLog.hh:752
void Validate()
Make sure that the current geometry passes a bunch of tests.
void CreateMaterials(const G4VPhysicalVolume *theVol)
bool CreateEnvelope(const G4VPhysicalVolume *theVol, TGeoManager *theEnvelope, TGeoVolume *theMother)
std::map< G4LogicalVolume *, TGeoVolume * > fKnownVolumes
std::map< G4String, TGeoElement * > fIsotope
A map between G4 isotope names and Root Element definitions.
std::set< G4String > fPrintedMass
A map of which masses have been printed.
void EDepSim::RootGeometryManager::Update ( std::string  gdmlFile,
bool  validate 
)

Set the root geometry from a gdml file.

Definition at line 151 of file EDepSimRootGeometryManager.cc.

152  {
153  EDepSimLog( "%%%%%%%%%%%%%%%%%% Update ROOT Geometry from GDML"
154  << "%%%%%%%%%%%%%%%%%%" );
155  if (gGeoManager) {
156  EDepSimLog("%%%%%%%%%%%%%%% Warning: Replacing ROOT Geometry ");
157  delete gGeoManager;
158  // Clear the node counts definitions.
159  fNodeCount.clear();
160  // Clear the cached materials. The material objects are owned by the
161  // TGeoManager and are invalid after it has been deleted.
162  fMedium.clear();
163  // Clear the cached isotopes. This is a bit complicated since the
164  // isotope pointers may be duplicated in the map.
165  std::set<TGeoElement*> isotope;
167  i != fIsotope.end();
168  ++i) {
169  isotope.insert(i->second);
170  }
171  fIsotope.clear();
172  for (std::set<TGeoElement*>::iterator i = isotope.begin();
173  i != isotope.end();
174  ++i) {
175  delete *i;
176  }
177  }
178 
179  // Create the new geometry.
180  TGeoManager::Import(gdmlFile.c_str());
181  gGeoManager->SetName("EDepSimGeometry");
182  gGeoManager->SetTitle("Simulated Detector Geometry");
183 
184  EDepSimLog("####################### Geometry initialized and closed");
185 
186  if (validateGeometry) return Validate();
187 }
#define EDepSimLog(outStream)
Definition: EDepSimLog.hh:717
intermediate_table::iterator iterator
std::map< G4String, int > fNodeCount
A map between G4 volume names and count of volumes with that name.
std::map< G4String, TGeoMedium * > fMedium
A map between G4 material names and Root Material definitions.
void Validate()
Make sure that the current geometry passes a bunch of tests.
#define Import
std::map< G4String, TGeoElement * > fIsotope
A map between G4 isotope names and Root Element definitions.
void EDepSim::RootGeometryManager::Validate ( )

Make sure that the current geometry passes a bunch of tests.

Definition at line 189 of file EDepSimRootGeometryManager.cc.

189  {
190 
191  int count = 0;
192  // Check for overlaps at volume corners. Look for overlaps at 0.1 mm size.
193  gGeoManager->CheckOverlaps(0.1*CLHEP::mm);
194  {
195  TIter next(gGeoManager->GetListOfOverlaps());
196  TGeoOverlap* overlap;
197  while ((overlap=(TGeoOverlap*)next())) {
198  ++count;
199  overlap->PrintInfo();
200  }
201  }
202 
203  // Check for overlaps with sampling. Look for overlaps at 0.1 mm size.
204  gGeoManager->CheckOverlaps(0.1*CLHEP::mm,"s100000");
205  {
206  TIter next(gGeoManager->GetListOfOverlaps());
207  TGeoOverlap* overlap;
208  while ((overlap=(TGeoOverlap*)next())) {
209  ++count;
210  overlap->PrintInfo();
211  }
212  }
213 
214  if (count > 0) {
215  EDepSimThrow(
216  "The geometry has overlaps and will produce incorrect"
217  " results. To use the geometry, specify the '-C' option"
218  " on the command line.");
219  }
220 
221  EDepSimLog("Geometry validated");
222 }
#define EDepSimLog(outStream)
Definition: EDepSimLog.hh:717
#define EDepSimThrow(message)
Print an error message, and then throw an exception.
static constexpr double mm
Definition: Units.h:65

Member Data Documentation

AttributeMap EDepSim::RootGeometryManager::fColorMap
private

A map between a material name and a color.

Definition at line 101 of file EDepSimRootGeometryManager.hh.

bool EDepSim::RootGeometryManager::fCreateAllVolumes
private

A flag whether to brute force the geometry or not. If this is true, then a new volume is created for every object in the geometry. This means that replicated volumes, and duplicated volume trees occur multiple times. This is good for small detectors since it means that each volume in the detector will have a unique TGeoNode associated with it. It is bad for large detectors since the ROOT geometry will become impractially large. The decision is made based on traversing the geant geometry and counting the number of unique volumes.

Definition at line 126 of file EDepSimRootGeometryManager.hh.

std::map<G4String,TGeoElement*> EDepSim::RootGeometryManager::fIsotope
private

A map between G4 isotope names and Root Element definitions.

Definition at line 95 of file EDepSimRootGeometryManager.hh.

std::map<G4LogicalVolume*,TGeoVolume*> EDepSim::RootGeometryManager::fKnownVolumes
private

A map between the G4 logical volumes and the root volumes. This keeps track of which volumes have already been created. It needs to be cleared before starting to build a new root geometry.

Definition at line 116 of file EDepSimRootGeometryManager.hh.

std::map<G4String,TGeoMedium*> EDepSim::RootGeometryManager::fMedium
private

A map between G4 material names and Root Material definitions.

Definition at line 92 of file EDepSimRootGeometryManager.hh.

std::vector<G4String> EDepSim::RootGeometryManager::fNameStack
private

A stack of volume names that have been seen. These are the "short" volume names of all of the parents to the current volue.

Definition at line 111 of file EDepSimRootGeometryManager.hh.

std::map<G4String,int> EDepSim::RootGeometryManager::fNodeCount
private

A map between G4 volume names and count of volumes with that name.

Definition at line 98 of file EDepSimRootGeometryManager.hh.

std::set<G4String> EDepSim::RootGeometryManager::fPrintedMass
private

A map of which masses have been printed.

Definition at line 107 of file EDepSimRootGeometryManager.hh.

std::vector<G4String> EDepSim::RootGeometryManager::fPrintMass
private

A vector of volume names to print.

Definition at line 104 of file EDepSimRootGeometryManager.hh.

EDepSim::RootGeometryManager * EDepSim::RootGeometryManager::fThis = NULL
staticprivate

The pointer to the instantiation of this object.

Definition at line 89 of file EDepSimRootGeometryManager.hh.


The documentation for this class was generated from the following files: