10 #include <TGeoManager.h> 11 #include <TGeoVolume.h> 12 #include <TGeoMedium.h> 13 #include <TGeoElement.h> 16 #include <TGeoSphere.h> 19 #include <TGeoBoolNode.h> 20 #include <TGeoCompositeShape.h> 21 #include <TGeoMatrix.h> 22 #include <TGeoOverlap.h> 29 #include <G4LogicalVolume.hh> 30 #include <G4VPhysicalVolume.hh> 31 #include <G4Material.hh> 32 #include <G4Element.hh> 33 #include <G4Isotope.hh> 34 #include <G4UnitsTable.hh> 36 #include <G4VisAttributes.hh> 37 #include <G4VSolid.hh> 41 #include <G4Sphere.hh> 42 #include <G4Polyhedra.hh> 43 #include <G4Polycone.hh> 45 #include <G4SubtractionSolid.hh> 46 #include <G4UnionSolid.hh> 47 #include <G4IntersectionSolid.hh> 48 #include <G4ExtrudedSolid.hh> 50 #include <G4SystemOfUnits.hh> 51 #include <G4PhysicalConstants.hh> 73 gGeoManager->Export(file);
77 if (!gGeoManager)
return -1;
78 gGeoManager->FindNode(pos.x(), pos.y(), pos.z());
79 return gGeoManager->GetCurrentNodeId();
83 int CountVolumes(G4LogicalVolume*
volume) {
85 for (std::size_t i = 0; i<volume->GetNoDaughters(); ++i) {
86 G4VPhysicalVolume* daughter = volume->GetDaughter(i);
87 count += CountVolumes(daughter->GetLogicalVolume());
94 bool validateGeometry) {
95 EDepSimLog(
"%%%%%%%%%%%%%%%%%%%%%%%%%% Update ROOT Geometry " 96 <<
"%%%%%%%%%%%%%%%%%%%%%%%%%%" );
98 EDepSimLog(
"%%%%%%%%%%%%%%% Warning: Replacing ROOT Geometry ");
107 std::set<TGeoElement*> isotope;
111 isotope.insert(i->second);
121 gGeoManager =
new TGeoManager(
"EDepSimGeometry",
122 "Simulated Detector Geometry");
123 gGeoManager->SetVisLevel(20);
131 if (CountVolumes(aWorld->GetLogicalVolume()) < 100000) {
144 gGeoManager->CloseGeometry(
"di");
146 EDepSimLog(
"Geometry initialized and closed");
148 if (validateGeometry)
return Validate();
152 bool validateGeometry) {
153 EDepSimLog(
"%%%%%%%%%%%%%%%%%% Update ROOT Geometry from GDML" 154 <<
"%%%%%%%%%%%%%%%%%%" );
156 EDepSimLog(
"%%%%%%%%%%%%%%% Warning: Replacing ROOT Geometry ");
165 std::set<TGeoElement*> isotope;
169 isotope.insert(i->second);
181 gGeoManager->SetName(
"EDepSimGeometry");
182 gGeoManager->SetTitle(
"Simulated Detector Geometry");
184 EDepSimLog(
"####################### Geometry initialized and closed");
186 if (validateGeometry)
return Validate();
193 gGeoManager->CheckOverlaps(0.1*
CLHEP::mm);
195 TIter next(gGeoManager->GetListOfOverlaps());
196 TGeoOverlap* overlap;
197 while ((overlap=(TGeoOverlap*)next())) {
199 overlap->PrintInfo();
204 gGeoManager->CheckOverlaps(0.1*
CLHEP::mm,
"s100000");
206 TIter next(gGeoManager->GetListOfOverlaps());
207 TGeoOverlap* overlap;
208 while ((overlap=(TGeoOverlap*)next())) {
210 overlap->PrintInfo();
216 "The geometry has overlaps and will produce incorrect" 217 " results. To use the geometry, specify the '-C' option" 218 " on the command line.");
225 TGeoMatrix **returnMatrix) {
226 const G4String geometryType = theSolid->GetEntityType();
227 TGeoShape* theShape = NULL;
228 if (geometryType ==
"G4Box") {
230 const G4Box* box =
dynamic_cast<const G4Box*
>(theSolid);
231 theShape =
new TGeoBBox(box->GetXHalfLength()/
CLHEP::mm,
235 else if (geometryType ==
"G4Tubs") {
236 const G4Tubs* tube =
dynamic_cast<const G4Tubs*
>(theSolid);
239 double zhalf = tube->GetZHalfLength()/
CLHEP::mm;
240 double rmin = tube->GetInnerRadius()/
CLHEP::mm;
241 double rmax = tube->GetOuterRadius()/
CLHEP::mm;
243 double maxPhiDeg = minPhiDeg + tube->GetDeltaPhiAngle()/
CLHEP::degree;
244 theShape =
new TGeoTubeSeg(rmin, rmax,
246 minPhiDeg, maxPhiDeg);
248 else if (geometryType ==
"G4Sphere") {
249 const G4Sphere* sphere =
dynamic_cast<const G4Sphere*
>(theSolid);
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,
258 minThetaDeg, maxThetaDeg,
259 minPhiDeg, maxPhiDeg);
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;
267 if (dPhi<0) dPhi += 2*
M_PI;
268 int sides = polyhedra->GetNumSide();
269 int numZ = polyhedra->GetNumRZCorner()/2;
272 double g4Factor = std::cos(0.5*dPhi/sides);
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;
279 pgon->DefineSection(i,
280 polyhedra->GetCorner(numZ-i-1).z/
CLHEP::mm,
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;
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;
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);
307 const G4PolyconeHistorical* param = polycone->GetOriginalParameters();
308 int numZ = param->Num_z_planes;
312 for (
int i = 0; i< numZ; ++i) {
313 pcon->DefineSection(i,
321 else if (geometryType ==
"G4Trap") {
323 =
dynamic_cast<const G4Trap*
>(theSolid);
324 double dz = trap->GetZHalfLength()/
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;
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);
339 else if (geometryType ==
"G4Trd") {
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);
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);
355 TGeoMatrix* matrixA = NULL;
357 TGeoMatrix* matrixB = NULL;
359 TGeoSubtraction* subtractNode =
new TGeoSubtraction(shapeA,shapeB,
361 theShape =
new TGeoCompositeShape(
"name",subtractNode);
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();
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,
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);
391 TGeoMatrix* matrixA = NULL;
393 TGeoMatrix* matrixB = NULL;
395 TGeoUnion* unionNode =
new TGeoUnion(shapeA, shapeB,
397 theShape =
new TGeoCompositeShape(
"name",unionNode);
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);
405 TGeoMatrix* matrixA = NULL;
407 TGeoMatrix* matrixB = NULL;
409 TGeoIntersection* intersectionNode =
new TGeoIntersection(shapeA, shapeB,
411 theShape =
new TGeoCompositeShape(
"name",intersectionNode);
414 else if (geometryType ==
"G4ExtrudedSolid"){
418 const G4ExtrudedSolid* extr
419 =
dynamic_cast<const G4ExtrudedSolid*
>(theSolid);
422 const G4int nZ = extr->GetNofZSections();
424 const G4int nV = extr->GetNofVertices();
427 const int maxVertices = 1000;
428 double vertices_x[maxVertices];
429 double vertices_y[maxVertices];
430 if (maxVertices < nV) {
436 TGeoXtru *xtru =
new TGeoXtru(nZ);
439 std::vector<G4TwoVector> polyPoints = extr->GetPolygon();
442 for(
int i = 0 ; i < nV ; i++){
443 vertices_x[i]= polyPoints[i].x();
444 vertices_y[i]= polyPoints[i].y();
448 xtru->DefinePolygon(nV, vertices_x, vertices_y);
450 double z_pos, x_off, y_off, scale;
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);
464 EDepSimThrow(geometryType+
" --> shape not implemented");
473 TGeoMedium* theMedium) {
475 TGeoVolume* theVolume =
new TGeoVolume(theName.c_str(),
487 theShortName.erase(0,theShortName.rfind(
"/")+1);
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;
506 if (theFullName.find(*
n) != std::string::npos) {
519 const G4VPhysicalVolume* theG4PhysVol) {
521 G4LogicalVolume* theLog = theG4PhysVol->GetLogicalVolume();
524 TGeoMedium *theMedium =
fMedium[theLog->GetMaterial()->GetName()];
527 G4Material *mat = theLog->GetMaterial();
528 if (mat->GetNumberOfElements()==0) {
529 EDepSimError(
"Material without elements " << mat->GetName());
534 =
new TGeoMixture(mat->GetName(),
535 mat->GetNumberOfElements(),
537 unsigned ielement = 0;
538 theMix->SetTemperature(mat->GetTemperature());
541 switch (mat->GetState()) {
543 theMix->SetState(TGeoMaterial::kMatStateSolid);
546 theMix->SetState(TGeoMaterial::kMatStateLiquid);
547 theMix->SetPressure(mat->GetPressure());
550 theMix->SetState(TGeoMaterial::kMatStateGas);
551 theMix->SetPressure(mat->GetPressure());
554 theMix->SetState(TGeoMaterial::kMatStateUndefined);
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,
563 (mat->GetFractionVector()[i])*
564 (elem->GetRelativeAbundanceVector()[j]));
567 TGeoElement *theIsotope =
fIsotope[iso->GetName()];
571 =
new TGeoElement(iso->GetName(),
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;
587 for (std::size_t child = 0;
588 child < theLog->GetNoDaughters();
590 G4VPhysicalVolume* theChild = theLog->GetDaughter(child);
599 daughterName = daughterName +
"_";
600 int ndaughters = theMother->GetNdaughters();
602 int ndaughters_samename = 0;
603 for(
int i = 0; i < ndaughters; i++){
604 TGeoNode *node = theMother->GetNode(i);
607 if(
name.
find(daughterName.c_str()) != std::string::npos)
608 ndaughters_samename++;
612 return ndaughters_samename;
621 const G4VPhysicalVolume* theG4PhysVol,
622 TGeoManager* theEnvelope,
623 TGeoVolume* theMother) {
629 TGeoVolume* theVolume = NULL;
630 G4LogicalVolume* theLog = theG4PhysVol->GetLogicalVolume();
634 << G4BestUnit(theLog->GetMass(
true),
"Mass")
635 <<
" Volume: " << theG4PhysVol->GetName());
643 theVolumeName +=
"/";
648 const G4VSolid* theSolid = theLog->GetSolid();
649 const G4String geometryType = theSolid->GetEntityType();
652 theShortName.erase(0,theShortName.rfind(
"/")+1);
657 theVolumeName +=
"/";
658 theVolumeName += theShortName;
662 if (theShortName == theFullName) {
663 theFullName = theVolumeName;
668 if (theFullName.find(
"//") != std::string::npos) {
671 theFullName = theVolumeName;
675 std::string materialName = theLog->GetMaterial()->GetName();
676 TGeoMedium *theMedium =
fMedium[materialName];
685 if (seenVolume !=
fKnownVolumes.end()) theVolume = seenVolume->second;
690 theVolume =
CreateVolume(theSolid, theShortName, theMedium);
691 if (!theVolume) theVolume = theMother;
692 theVolume->SetTitle(theVolumeName.c_str());
697 theVolume->SetVisContainers(
true);
698 if (color < 0 || opacity < 0.001) {
699 theVolume->SetVisibility(
false);
702 int i = 100.0*(1.0-opacity);
708 theVolume->SetLineColor(color);
709 theVolume->SetTransparency(i);
710 theVolume->SetVisibility(
true);
715 EDepSimLog(
"Making \"" << theVolume->GetName() <<
"\" the top\n");
716 theEnvelope->SetTopVolume(theVolume);
724 double missingMass = 0.0;
725 for (std::size_t child = 0;
726 child < theLog->GetNoDaughters();
728 G4VPhysicalVolume* theChild = theLog->GetDaughter(child);
729 if (theLog->GetNoDaughters() > 20000) {
730 G4LogicalVolume *skippedVolume = theChild->GetLogicalVolume();
731 missingMass += skippedVolume->GetMass(
true);
734 G4LogicalVolume *skippedVolume = theChild->GetLogicalVolume();
735 missingMass += skippedVolume->GetMass(
true);
743 if (missingMass > 0.0) {
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 " 755 if (avgMedium) theVolume->SetMedium(avgMedium);
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;
779 theG4PhysVol->GetReplicationData(a,nRep,w,o,c);
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;
785 EDepSimThrow(
"EDepSim::RootGeometryManager::CreateEnvelope:" 786 "Bad replication data.");
788 for (
int i=0; i<nRep; ++i) {
789 G4ThreeVector
pos = axis*w*(i-0.5*(nRep-1));
790 TGeoCombiTrans* combi
796 theVolume->GetName());
797 theMother->AddNode(theVolume,index,combi);
801 TGeoCombiTrans* combi
802 =
new TGeoCombiTrans(trans.x()/
CLHEP::mm,
807 theVolume->GetName());
808 theMother->AddNode(theVolume,index,combi);
816 int color,
double opacity) {
817 G4String materialName = material->GetName();
820 if (opacity<0.01)
fColorMap[materialName].fill = 0;
821 else if (opacity>0.99)
fColorMap[materialName].fill = 1;
823 fColorMap[materialName].fill = 4000+100*opacity;
828 G4String materialName = material->GetName();
835 EDepSimError(
"Missing color for \"" << materialName <<
"\"");
836 fColorMap[materialName].color = kOrange+1;
841 index = colorPair->second.color;
842 alpha = colorPair->second.alpha;
849 return G4Color(color.GetRed(),color.GetGreen(),color.GetBlue(),
850 color.GetAlpha()*
alpha);
854 const G4LogicalVolume* log = vol->GetLogicalVolume();
857 const G4VisAttributes* visAttributes = log->GetVisAttributes();
858 if (!visAttributes) {
863 G4Color g4Color = visAttributes->GetColor();
864 double opacity = g4Color.GetAlpha();
865 if (opacity > 1.0) opacity = 1.0;
871 const G4LogicalVolume* log = vol->GetLogicalVolume();
874 const G4VisAttributes* visAttributes = log->GetVisAttributes();
875 if (!visAttributes) {
880 double minDist = 10000;
881 G4Color g4Color = visAttributes->GetColor();
884 const int rootPrimaryColors[] = {
885 kRed, kMagenta, kBlue, kCyan, kGreen, kYellow, -1
887 for(
const int* rootBaseColor = rootPrimaryColors;
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;
905 const int rootSecondaryColors[] = {
906 kPink, kMagenta, kViolet, kTeal, kSpring, kOrange, -1
908 for(
const int* rootBaseColor = rootSecondaryColors;
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;
926 const int rootBlackColors[] = {
927 kGray, kGray+1, kGray+2, kGray+3, kBlack, -1
929 for(
const int* rootBaseColor = rootBlackColors;
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;
944 for(
int rootBaseColor = 1;
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;
962 const G4VPhysicalVolume* thePhys) {
964 G4LogicalVolume* theLog = thePhys->GetLogicalVolume();
965 std::string materialName = theLog->GetMaterial()->GetName();
969 if (theFullName.find(
"/Bar") != std::string::npos) {
970 if (theFullName.find(
"/FGD") != std::string::npos) {
971 materialName =
"FGDScintillator";
973 else if (theFullName.find(
"/P0D/") != std::string::npos) {
974 materialName =
"P0DScintillator";
977 materialName =
"Scintillator";
985 const G4VPhysicalVolume* thePhys) {
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;
994 TGeoMedium* avgMedium =
fMedium[averageName];
995 if (avgMedium)
return avgMedium;
999 std::map< const G4Material* , double > materialMass;
1002 std::map<std::string,double> componentMass;
1004 std::vector<const G4VPhysicalVolume*> stack;
1005 stack.push_back(thePhys);
1006 while (!stack.empty()) {
1008 const G4VPhysicalVolume* currentPhys = stack.back();
1009 G4LogicalVolume* currentLog = currentPhys->GetLogicalVolume();
1012 for (std::size_t child = 0;
1013 child < currentLog->GetNoDaughters();
1015 stack.push_back(currentLog->GetDaughter(child));
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) {
1026 std::string isoName = elem->GetIsotope(j)->GetName();
1027 componentMass[isoName] += mass
1028 *(mat->GetFractionVector()[i])
1029 *(elem->GetRelativeAbundanceVector()[j]);
1034 =
new TGeoMixture(averageName.c_str(),
1035 componentMass.size(),
1038 c != componentMass.end();
1041 theMix->AddElement(elem,
c->second/totalMass);
1047 mat = materialMass.begin();
1048 mat != materialMass.end();
1050 const G4Material*
material = mat->first;
1051 double mass = mat->second;
1053 radLen += mass/material->GetRadlen();
1054 intLen += mass/material->GetNuclearInterLength();
1059 theMix->SetRadLen(-massSum/radLen,-massSum/intLen);
1061 int numed =
fMedium.size() + 1;
1062 TGeoMedium* theMedium =
new TGeoMedium(averageName.c_str(),numed,theMix);
1063 fMedium[averageName] = theMedium;
#define EDepSimLog(outStream)
double GetOpacity(const G4VPhysicalVolume *vol)
virtual ~RootGeometryManager()
std::map< G4String, int > fNodeCount
A map between G4 volume names and count of volumes with that name.
#define EDepSimNamedDebug(trace, outStream)
std::map< G4String, TGeoMedium * > fMedium
A map between G4 material names and Root Material definitions.
static constexpr double g
G4Color GetG4Color(G4Material *material)
void Update(const G4VPhysicalVolume *aWorld, bool validate)
Update the root geometry to match the g4 geometry.
AttributeMap fColorMap
A map between a material name and a color.
static constexpr double cm3
static const std::string volume[nvol]
virtual TGeoMedium * AverageMaterial(const G4VPhysicalVolume *theVol)
virtual bool IgnoreVolume(const G4VPhysicalVolume *theVol)
#define EDepSimThrow(message)
Print an error message, and then throw an exception.
std::vector< G4String > fNameStack
virtual std::string MaterialName(const G4VPhysicalVolume *theVol)
#define EDepSimInfo(outStream)
void Validate()
Make sure that the current geometry passes a bunch of tests.
static std::map< int, G4Color > sRootColorToG4ColorMap
int find(char c, int index=0, bool cs=TRUE) const
std::vector< G4String > fPrintMass
A vector of volume names to print.
void Export(const char *file)
Export the geometry to a file.
TGeoVolume * CreateVolume(const G4VSolid *theSolid, std::string theName, TGeoMedium *theMedium)
Create a new ROOT volume object.
void CreateMaterials(const G4VPhysicalVolume *theVol)
static EDepSim::RootGeometryManager * fThis
The pointer to the instantiation of this object.
int GetColor(const G4VPhysicalVolume *vol)
void swap(Handle< T > &a, Handle< T > &b)
RootGeometryManager()
use Get() instead
virtual bool PrintMass(const G4VPhysicalVolume *theVol)
A method to flag that a volume mass should be printed.
void SetDrawAtt(G4Material *material, int color, double opacity=1.0)
Set material color.
std::size_t color(std::string const &procname)
int HowManySimilarNodesInVolume(TGeoVolume *theMother, std::string theName)
TGeoShape * CreateShape(const G4VSolid *theSolid, TGeoMatrix **mat=NULL)
bool CreateEnvelope(const G4VPhysicalVolume *theVol, TGeoManager *theEnvelope, TGeoVolume *theMother)
#define EDepSimError(outStream)
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
std::map< G4LogicalVolume *, TGeoVolume * > fKnownVolumes
std::map< G4String, TGeoElement * > fIsotope
A map between G4 isotope names and Root Element definitions.
static constexpr double mm
int GetNodeId(const G4ThreeVector &pos)
Get a volume ID base on the volume position.
static constexpr double degree
std::set< G4String > fPrintedMass
A map of which masses have been printed.
std::string sub(const std::string &a, const std::string &b)
static EDepSim::RootGeometryManager * Get(void)
If a persistency manager has not been created, create one.