18#include "BDSAcceleratorComponent.hh"
19#include "BDSAcceleratorComponentRegistry.hh"
20#include "BDSAcceleratorModel.hh"
21#include "BDSApertureInfo.hh"
22#include "BDSAuxiliaryNavigator.hh"
23#include "BDSBeamline.hh"
24#include "BDSBeamlineBLMBuilder.hh"
25#include "BDSBeamlineEndPieceBuilder.hh"
26#include "BDSBeamlineElement.hh"
27#include "BDSBeamlineIntegral.hh"
28#include "BDSBeamlinePlacementBuilder.hh"
29#include "BDSBeamlineSet.hh"
30#include "BDSBeamPipeInfo.hh"
32#include "BDSBLMRegistry.hh"
33#include "BDSBOptrMultiParticleChangeCrossSection.hh"
34#include "BDSComponentFactory.hh"
35#include "BDSComponentFactoryUser.hh"
36#include "BDSCurvilinearBuilder.hh"
38#include "BDSDetectorConstruction.hh"
39#include "BDSException.hh"
40#include "BDSExtent.hh"
41#include "BDSFieldBuilder.hh"
42#include "BDSFieldObjects.hh"
43#include "BDSFieldQuery.hh"
44#include "BDSFieldQueryInfo.hh"
45#include "BDSFieldLoaderQueryPoints.hh"
47#include "BDSGeometryComponent.hh"
48#include "BDSGeometryExternal.hh"
49#include "BDSGeometryFactory.hh"
50#include "BDSGlobalConstants.hh"
51#include "BDSHistBinMapper.hh"
52#include "BDSIntegratorSet.hh"
54#include "BDSMaterials.hh"
55#include "BDSParser.hh"
56#include "BDSPhysicalVolumeInfo.hh"
57#include "BDSPhysicalVolumeInfoRegistry.hh"
58#include "BDSRegion.hh"
59#include "BDSSamplerInfo.hh"
60#include "BDSSamplerType.hh"
61#include "BDSScorerFactory.hh"
62#include "BDSScorerInfo.hh"
63#include "BDSScorerMeshInfo.hh"
64#include "BDSScoringMeshBox.hh"
65#include "BDSScoringMeshCylinder.hh"
66#include "BDSSDEnergyDeposition.hh"
67#include "BDSSDManager.hh"
68#include "BDSSDType.hh"
69#include "BDSSurvey.hh"
70#include "BDSTeleporter.hh"
71#include "BDSTrajectoryPoint.hh"
72#include "BDSTunnelBuilder.hh"
73#include "BDSUtilities.hh"
74#include "BDSWarning.hh"
76#include "parser/blmplacement.h"
77#include "parser/element.h"
78#include "parser/fastlist.h"
79#include "parser/options.h"
80#include "parser/physicsbiasing.h"
81#include "parser/placement.h"
82#include "parser/samplerplacement.h"
83#include "parser/scorermesh.h"
86#include "G4AffineTransform.hh"
88#include "G4LogicalVolume.hh"
89#include "G4Material.hh"
90#include "G4ProductionCuts.hh"
91#include "G4PVPlacement.hh"
92#include "G4VPrimitiveScorer.hh"
94#include "G4ScoringManager.hh"
96#include "G4Transform3D.hh"
97#include "G4Version.hh"
98#include "G4VisAttributes.hh"
99#include "G4VPhysicalVolume.hh"
100#if G4VERSION_NUMBER > 1039
101#include "G4ChannelingOptrMultiParticleChangeCrossSection.hh"
103#if G4VERSION_NUMBER > 1109
104#include "G4HadronicParameters.hh"
107#ifdef BDSCHECKUSERLIMITS
108#include "G4UserLimits.hh"
111#include "CLHEP/Units/SystemOfUnits.h"
112#include "CLHEP/Vector/EulerAngles.h"
126 placementBL(nullptr),
127 designParticle(nullptr),
128 userComponentFactory(userComponentFactoryIn),
130 buildPlacementFieldsWorld(false),
131 worldLogicalVolume(nullptr)
134 verbose = globals->Verbose();
135 checkOverlaps = globals->CheckOverlaps();
136 circular = globals->Circular();
138 if (globals->RestoreFTPFDiffractionForAGreater10())
139#if G4VERSION_NUMBER > 1109
141 G4cout << __METHOD_NAME__ <<
"restoring diffraction for target / projectiles with A > 10 in the FTFP hadronic model (even if not used)" << G4endl;
142 G4HadronicParameters::Instance()->SetEnableDiffDissociationForBGreater10(
true);
146 if (globals->RestoreFTPFDiffractionForAGreater10Set())
147 {BDS::Warning(__METHOD_NAME__,
"\"restoreFTPFDiffractionForAGreater10\" is only available for Geant4 v11.1 and later");}
154 acceleratorModel = BDSAcceleratorModel::Instance();
155 canSampleAngledFaces =
true;
157 if ( (integratorSetType == BDSIntegratorSetType::bdsimtwo)
158 || (integratorSetType == BDSIntegratorSetType::geant4)
159#
if G4VERSION_NUMBER > 1039
160 || (integratorSetType == BDSIntegratorSetType::geant4dp)
164 canSampleAngledFaces = globals->SampleElementsWithPoleface();
167 UpdateSamplerDiameterAndCountSamplers();
168 PrepareExtraSamplerSDs();
169 CountPlacementFields();
176 G4double maxBendingRatio = 1e-9;
177 for (
const auto& blElement : beamline)
180 auto st = BDS::DetermineSamplerType(blElement.samplerType);
181 if (st != BDSSamplerType::none)
184 G4double length = blElement.l;
185 G4double angle = blElement.angle;
188 G4double ratio = angle / length;
189 maxBendingRatio = std::max(maxBendingRatio, ratio);
193 G4double curvilinearRadius = 0.5*globals->CurvilinearDiameter();
194 G4double tolerance = 0.9;
195 if (maxBendingRatio > 0.4*tolerance)
197 G4double curvilinearRadiusBends = (tolerance / maxBendingRatio)*CLHEP::m;
198 if (curvilinearRadiusBends < curvilinearRadius)
200 G4cout << __METHOD_NAME__ <<
"Reducing curvilinear diameter from " << 2*curvilinearRadius / CLHEP::m
201 <<
"m to " << 2*curvilinearRadiusBends / CLHEP::m <<
"m" << G4endl;
205 G4double sd = globals->SamplerDiameter();
206 if (curvilinearRadius*2 < sd)
208 G4cout << __METHOD_NAME__ <<
"Reducing sampler diameter from " << sd / CLHEP::m <<
"m to the same" << G4endl;
227 for (
const auto& placement : placements)
229 if (!placement.fieldAll.empty() || !placement.bdsimElement.empty())
232 buildPlacementFieldsWorld = nFields > 0;
238 {G4cout << __METHOD_NAME__ <<
"starting accelerator geometry construction\n" << G4endl;}
257 delete componentFactory;
274 {G4cout << __METHOD_NAME__ <<
"detector Construction done" << G4endl;}
281 G4cout << G4endl << __METHOD_NAME__ <<
"printing material table" << G4endl;
282 G4cout << *(G4Material::GetMaterialTable()) << G4endl << G4endl;
283 if (
verbose || debug) {G4cout <<
"Finished listing materials, returning physiWorld" << G4endl;}
285#ifdef BDSCHECKUSERLIMITS
286 PrintUserLimitsSummary(worldPV);
291BDSDetectorConstruction::~BDSDetectorConstruction()
293#if G4VERSION_NUMBER > 1009
298 for (
auto q : fieldQueries)
308 G4cout <<
"New region defined: " << G4endl << *reg << G4endl;
311 delete defaultRegion;
316 std::map<G4String, BDSApertureInfo*> apertures;
325 apertures[a.name] = ap;
334 {G4cout <<
"parsing the beamline element list..."<< G4endl;}
336 G4Transform3D initialTransform = g->BeamlineTransform();
348 if (finishingPoint->changeOfEnergyEncountered)
349 {G4cout <<
"Design particle properties at end of beam line: " << G4endl << finishingPoint->designParticle;}
352 delete finishingPoint;
354 G4cout <<
"Registry size "
356 G4cout <<
"Parser beam line size "
362 if (!
circular && mainBeamline.massWorld)
365 {BDS::Warning(
"Total sum of all element angles is approximately 2*pi but the circular option was not specified, this simulation may run indefinitely");}
374 for (
const auto& placement : placements)
376 if (placement.sequence.empty())
389 BDSBeamlineIntegral thisBeamlineStartingPoint(startingPoint.designParticle, 0, startS, g->IntegrateKineticEnergyAlongBeamline());
396 G4String beamlineName = placement.name +
"_" + placement.sequence;
399 thisBeamlineStartingPoint,
400 thisBeamlineFinishingPoint,
405 delete thisBeamlineFinishingPoint;
413 if (sType == BDSSamplerType::none)
422 const G4String& name,
425 const G4Transform3D& initialTransform,
426 G4bool beamlineIsCircular,
427 G4bool isPlacementBeamline)
429 if (beamLine.
empty())
435 if (beamlineIsCircular)
440 G4cerr <<
"The first element in the beam line is unsuitable for a circular "
441 <<
"model as the first element will " << G4endl <<
"overlap with the "
442 <<
"teleporter and terminator - the necessary mechanics for a circular "
443 <<
"model in Geant4" << G4endl;
444 throw BDSException(__METHOD_NAME__,
"check construction for circular machine");
448 if (beamLine.
size() <= 1)
449 {
throw BDSException(__METHOD_NAME__,
"BDSIM requires the sequence defined with the use command to have at least one element.");}
451 for (
auto elementIt = beamLine.
begin(); elementIt != beamLine.
end(); ++elementIt)
455 auto prevIt = elementIt;
456 while (prevIt != beamLine.
begin())
461 prevElement = &(*prevIt);
467 auto nextIt = elementIt;
469 G4double nextElementInputFace = 0;
470 while (nextIt != beamLine.
end())
474 nextElement = &(*nextIt);
476 nextElementInputFace = nextElement->
e1;
487 G4bool forceNoSamplerOnThisElement =
false;
489 {forceNoSamplerOnThisElement =
true;}
491 {forceNoSamplerOnThisElement =
true;}
493 {forceNoSamplerOnThisElement =
true;}
496 massWorld->
AddComponent(temp, tiltOffset, samplerInfo, integral);
503 if (beamlineIsCircular && !massWorld->
empty())
507 G4String msg =
"a change in energy was encountered in a circular machine and both\n";
508 msg +=
"integrateKineticEnergyAlongBeamline=1 (default is 1) and circular options were used.\n";
509 msg +=
"This will be wrong for more than one turn...";
510 BDS::Warning(__METHOD_NAME__, msg);
513 G4cout << __METHOD_NAME__ <<
"Circular machine - creating terminator & teleporter" << G4endl;
515 G4double teleporterLength = 0;
518 auto hasBeamPipeInfo = [](
BDSBeamlineElement* ble) {
return ble->GetBeamPipeInfo() !=
nullptr;};
519 auto firstElementWithBPInfo = std::find_if(massWorld->
begin(), massWorld->
end(), hasBeamPipeInfo);
520 auto lastElementWithBPInfo = std::find_if(massWorld->
rbegin(), massWorld->
rend(), hasBeamPipeInfo);
522 G4double firstbeamPipeMaxExtent = (*firstElementWithBPInfo)->GetBeamPipeInfo()->Extent().MaximumAbsTransverse();
523 G4double lastbeamPipeMaxExtent = (*lastElementWithBPInfo)->GetBeamPipeInfo()->Extent().MaximumAbsTransverse();
526 G4double teleporterHorizontalWidth = 2 * std::max(firstbeamPipeMaxExtent, lastbeamPipeMaxExtent);
532 massWorld->
AddComponent(terminator,
nullptr,
nullptr, integral);
536 teleporterHorizontalWidth,
537 teleporterTransform);
541 massWorld->
AddComponent(teleporter,
nullptr,
nullptr, integral);
549 {fn = fn.erase(fn.length()-4);}
550 G4String surveyFileName = fn +
".dat";
551 if (isPlacementBeamline)
552 {surveyFileName = fn +
"_" + name +
".dat";}
554 survey->
Write(massWorld);
557 delete theComponentFactory;
560 G4cout << __METHOD_NAME__ <<
"\"" << name <<
"\" " << G4endl << *massWorld;
571 beamlineSet.massWorld = massWorld;
572 beamlineSet.curvilinearWorld = clBeamline;
573 beamlineSet.curvilinearBridgeWorld = clBridgeBeamline;
574 beamlineSet.endPieces = endPieces;
595 std::vector<BDSExtentGlobal> extents;
612 const auto& extras = BDSAcceleratorModel::Instance()->
ExtraBeamlines();
614 for (
const auto& bl : extras)
615 {bl.second.GetExtentGlobals(extents);}
624 G4ThreeVector worldR;
626 for (
const auto& ext : extents)
628 for (G4int i = 0; i < 3; i++)
629 {worldR[i] = std::max(worldR[i], ext.GetMaximumExtentAbsolute()[i]);}
632 G4String worldName =
"World";
633 G4VSolid* worldSolid =
nullptr;
634 G4LogicalVolume* worldLV =
nullptr;
636 G4String worldGeometryFile = globals->WorldGeometryFile();
637 if (!worldGeometryFile.empty())
639 if (globals->WorldMaterialSet())
640 {BDS::Warning(__METHOD_NAME__,
"conflicting options - world material option specified but material will be taken from world GDML file");}
641 G4bool ac = globals->AutoColourWorldGeometryFile();
643 std::vector<G4String> namedWorldVacuumVolumes =
BDS::SplitOnWhiteSpace(globals->WorldVacuumVolumeNames());
650 &namedWorldVacuumVolumes,
652 BDSSDType::energydepworldcontents,
653 BDSSDType::energydepvacuum);
659 for (
auto volume : worldVacuumLogicalVolumes)
660 {allWorldVolumes.erase(volume);}
665 G4bool worldContainsAllBeamlines = worldExtentGlobal.
Encompasses(extents);
667 G4cout <<
"External world geometry: \"" << worldGeometryFile <<
"\"" << G4endl;
668 G4cout <<
"Loaded world extent: \n" <<
worldExtent << G4endl;
671 if (!worldContainsAllBeamlines)
673 G4String message =
"Beamlines cannot be constructed, beamline extents are larger than \n";
674 message +=
"the extents of the external world";
684 if (globals->StoreELossWorld()
685 || globals->StoreELossWorldIntegral()
687 || globals->StoreELossWorldContents()
688 || globals->StoreELossWorldContentsIntegral())
692 worldLV->SetSensitiveDetector(BDSSDManager::Instance()->WorldComplete());
698 G4double margin = globals->WorldVolumeMargin();
699 margin = std::max(margin, 2*CLHEP::m);
700 worldR += G4ThreeVector(margin,margin,margin);
702 G4cout << __METHOD_NAME__ <<
"World dimensions: " << worldR / CLHEP::m <<
" m" << G4endl;
704 G4String worldMaterialName = globals->WorldMaterial();
707 worldSolid =
new G4Box(worldName +
"_solid", worldR.x(), worldR.y(), worldR.z());
710 worldLV =
new G4LogicalVolume(worldSolid,
716 if (globals->StoreELossWorld() || globals->StoreELossWorldIntegral())
717 {worldLV->SetSensitiveDetector(BDSSDManager::Instance()->WorldComplete());}
722 G4VisAttributes* debugWorldVis =
new G4VisAttributes(*(globals->ContainerVisAttr()));
723 debugWorldVis->SetForceWireframe(
true);
724 worldLV->SetVisAttributes(debugWorldVis);
727 worldLV->SetUserLimits(globals->DefaultUserLimits());
730 G4VPhysicalVolume* worldPV =
new G4PVPlacement(
nullptr,
753 worldLogicalVolume = worldLV;
784 const auto& extras = BDSAcceleratorModel::Instance()->
ExtraBeamlines();
785 for (
auto const& bl : extras)
794 G4VPhysicalVolume* containerPV,
795 G4bool checkOverlaps,
798 G4bool useCLPlacementTransform,
799 G4bool useIncrementalCopyNumbers,
800 G4bool registerPlacementNamesForOutput)
806 for (
auto element : *beamline)
809 if (
dynamic_cast<BDSGap*
>(element->GetAcceleratorComponent()))
814 auto accComp = element->GetAcceleratorComponent();
815 const G4String regionName = accComp->GetRegion();
816 if (!regionName.empty())
818 G4Region* region = BDSAcceleratorModel::Instance()->
Region(regionName);
819 auto contLV = accComp->GetContainerLogicalVolume();
820 contLV->SetRegion(region);
821 region->AddRootLogicalVolume(contLV);
826 element->GetAcceleratorComponent()->AttachSensitiveDetectors();
829 G4int copyNumber = useIncrementalCopyNumbers ? i : element->GetCopyNo();
830 G4String placementName = element->GetPlacementName() +
"_pv";
831 std::set<G4VPhysicalVolume*> pvs = element->PlaceElement(placementName, containerPV, useCLPlacementTransform,
838 element->GetSPositionMiddle(),
844 if (registerPlacementNamesForOutput)
854 const G4String& objectTypeForErrorMsg)
856 G4Transform3D result;
864 G4RotationMatrix rm = G4RotationMatrix();
867 G4ThreeVector axis = G4ThreeVector(placement.
axisX,
870 rm = G4RotationMatrix(axis, placement.
angle*CLHEP::rad);
878 CLHEP::HepEulerAngles ang = CLHEP::HepEulerAngles(placement.
phi*CLHEP::rad,
879 placement.
theta*CLHEP::rad,
880 placement.
psi*CLHEP::rad);
881 rm = G4RotationMatrix(ang);
891 {
throw BDSException(__METHOD_NAME__,
"no valid beam line yet for " + objectTypeForErrorMsg +
" w.r.t. a beam line.");}
896 G4cerr << __METHOD_NAME__ <<
"No element named \"" << placement.
referenceElement <<
"\" (instance #"
898 << placement.
name <<
"\"" << G4endl;
899 G4cout <<
"Note, this may be because the element is a bend and split into " << G4endl;
900 G4cout <<
"multiple sections with unique names. Run the visualiser to get " << G4endl;
901 G4cout <<
"the name of the segment, or place w.r.t. the element before / after." << G4endl;
902 throw BDSException(
"Error in "+objectTypeForErrorMsg+
".");
907 G4String message = objectTypeForErrorMsg +
" \"" + placement.
name +
"\" is placed using";
908 message +=
" a referenceElement but the z offset is\n non zero. Note, s should be used to";
909 message +=
" offset the placement in this case and z will\n have no effect.";
910 BDS::Warning(message);
913 sCoordinate += placement.
s * CLHEP::m;
917 G4ThreeVector offset = G4ThreeVector();
922 placement.
x * CLHEP::m + offset.x(),
923 placement.
y * CLHEP::m + offset.y());
924 G4Transform3D localRotation(rm, G4ThreeVector());
925 result = beamlinePart * localRotation;
930 {
throw BDSException(__METHOD_NAME__,
"no valid beam line yet placement w.r.t. a beam line.");}
931 G4ThreeVector offset = G4ThreeVector();
936 placement.
x * CLHEP::m + offset.x(),
937 placement.
y * CLHEP::m + offset.y());
939 G4Transform3D localRotation(rm, G4ThreeVector());
940 result = beamlinePart * localRotation;
942 {*S = placement.
s*CLHEP::m;}
946 G4ThreeVector translation = G4ThreeVector(placement.
x*CLHEP::m,
947 placement.
y*CLHEP::m,
948 placement.
z*CLHEP::m);
951 result = G4Transform3D(rm, translation);
999 G4ThreeVector result = G4ThreeVector();
1000 G4String side = G4String(placement.
side);
1005 G4double pathLength = placement.
s*CLHEP::m;
1006 std::pair<G4double, G4double> extentZ = placementExtent.
ExtentZ();
1007 G4double sLow = pathLength + extentZ.first;
1008 G4double sHigh = pathLength + extentZ.second;
1012 if (end != beamLine->
end())
1018 for (
auto iter = start; iter != end; ++iter)
1029 result.setY(sectionMaxExtent.
YPos() + placementExtent.
YPos() + ls);
1030 G4double xOffset = sectionMaxExtent.
XPos() - 0.5*sectionMaxExtent.
DX();
1031 result.setX(xOffset);
1033 else if (side ==
"bottom")
1035 result.setY(sectionMaxExtent.
YNeg() + placementExtent.
YNeg() - ls);
1036 G4double xOffset = sectionMaxExtent.
XPos() - 0.5*sectionMaxExtent.
DX();
1037 result.setX(xOffset);
1039 else if (side ==
"left")
1040 {result.setX(sectionMaxExtent.
XPos() + placementExtent.
XPos() + ls);}
1041 else if (side ==
"right")
1042 {result.setX(sectionMaxExtent.
XNeg() + placementExtent.
XNeg() - ls);}
1043 else if (side !=
"")
1044 {
throw BDSException(std::string(
"Unknown side in placement: " + side));}
1051 if (sp.apertureModel.empty())
1056 sp.aper1 * CLHEP::m,
1057 sp.aper2 * CLHEP::m,
1058 sp.aper3 * CLHEP::m,
1059 sp.aper4 * CLHEP::m,
1061 apertureExtent = aperture.
Extent();
1064 {apertureExtent =
BDSExtent(sp.aper1*CLHEP::m, sp.aper1*CLHEP::m, sp.aper2*CLHEP::m);}
1066 {apertureExtent =
BDSExtent(sp.aper1*CLHEP::m, sp.aper1*CLHEP::m, sp.aper1*CLHEP::m);}
1073 apertureExtent = aperture->
Extent();
1078 apertureExtent.
YNeg(), apertureExtent.
YPos(),
1079 1*CLHEP::um, 1*CLHEP::um);
1087 for (
const auto& samplerPlacement : samplerPlacements)
1100 return recipe.Extent();
1107 for (
const auto& mesh : scorerMeshes)
1117#if G4VERSION_NUMBER > 1009
1120 const std::list<std::string>& defaultBias,
1121 const G4String& elementName)
1124 if (biasList.empty() && defaultBias.empty())
1127 std::list<std::string> biasesAll = biasList.empty() ? defaultBias : biasList;
1130 std::set<std::string> biasNamesSorted = {biasesAll.begin(), biasesAll.end()};
1131 G4String biasSetKey;
1132 G4String biasSetPrintOut;
1133 for (
const auto& n : biasNamesSorted)
1135 biasSetKey += n +
"_";
1136 biasSetPrintOut += n +
" ";
1138 biasSetKey =
BDS::StrStrip(biasSetKey,
'_', BDS::StringStripType::trailing);
1140 auto exists = biasSetObjects.find(biasSetKey);
1141 if (exists != biasSetObjects.end())
1142 {
return exists->second;}
1145 G4cout <<
"Bias> Creating unique set of bias objects ( " << biasSetPrintOut <<
")" << G4endl;
1149 for (std::string
const & bs : biasesAll)
1151 auto result = biasObjectList.
find(bs);
1152 if (result == biasObjectList.end())
1153 {
throw BDSException(
"Error: bias named \"" + bs +
"\" not found for element named \"" + elementName +
"\"");}
1157 {G4cout << __METHOD_NAME__ <<
"bias loop : " << bs <<
" " << pb.
particle <<
" " << pb.
process << G4endl;}
1162 if (pb.
flag.size() != pb.processList.size())
1163 {
throw BDSException(__METHOD_NAME__,
"number of flag entries in \"" + pb.
name +
"\" doesn't match number of processes");}
1164 if (pb.
factor.size() != pb.processList.size())
1165 {
throw BDSException(__METHOD_NAME__,
"number of factor entries in \"" + pb.
name +
"\" doesn't match number of processes");}
1166 for (
unsigned int p = 0; p < pb.processList.size(); ++p)
1171 biasSetObjects[biasSetKey] = eg;
1178#if G4VERSION_NUMBER > 1009
1181 {G4cout << __METHOD_NAME__ <<
"registry=" << registry << G4endl;}
1183#if G4VERSION_NUMBER > 1039
1186 std::set<G4LogicalVolume*>* crystals = BDSAcceleratorModel::Instance()->
VolumeSet(
"crystals");
1187 if (!crystals->empty())
1189 G4cout << __METHOD_NAME__ <<
"Using crystal biasing: true" << G4endl;
1190 auto crystalBiasing =
new G4ChannelingOptrMultiParticleChangeCrossSection();
1191 for (
auto crystal : *crystals)
1192 {crystalBiasing->AttachTo(crystal);}
1197 for (
auto blm : blmSet)
1199 G4String biasNamesS = blm->Bias();
1200 if (biasNamesS.empty())
1203 std::list<std::string> biasNames = {biasNamesV.begin(), biasNamesV.end()};
1204 std::list<std::string> emptyDefaultBias;
1206 for (
auto lv : blm->GetAllLogicalVolumes())
1207 {biasForBLM->AttachTo(lv);}
1208 biasForBLM->AttachTo(blm->GetContainerLogicalVolume());
1214 auto defaultBiasVacuumList = std::list<std::string>(defaultBiasVacuumVector.begin(), defaultBiasVacuumVector.end());
1217 auto defaultBiasMaterialList = std::list<std::string>(defaultBiasMaterialVector.begin(), defaultBiasMaterialVector.end());
1218 G4String biasForWorldVolume = g->BiasForWorldVolume();
1220 auto biasForWorldVolumeList = std::list<std::string>(biasForWorldVolumeVector.begin(), biasForWorldVolumeVector.end());
1221 G4String biasForWorldContents = g->BiasForWorldContents();
1223 auto biasForWorldContentsList = std::list<std::string>(biasForWorldContentsVector.begin(), biasForWorldContentsVector.end());
1224 G4String biasForWorldVacuum = g->BiasForWorldVacuum();
1226 auto biasForWorldVacuumList = std::list<std::string>(biasForWorldVacuumVector.begin(), biasForWorldVacuumVector.end());
1228 G4bool useDefaultBiasVacuum = !defaultBiasVacuum.empty();
1229 G4bool useDefaultBiasMaterial = !defaultBiasMaterial.empty();
1231 G4bool useBiasForWorldVolume = !biasForWorldVolume.
empty();
1232 G4bool useBiasForWorldContents = !biasForWorldContents.empty();
1233 G4bool useBiasForWorldVacuum = !biasForWorldVacuum.empty();
1234 G4bool biasesDefined = !biasObjectList.empty();
1236 G4bool overallUseBiasing = useDefaultBiasVacuum || useDefaultBiasMaterial || biasesDefined || useBiasForWorldVolume || useBiasForWorldContents;
1237 G4cout << __METHOD_NAME__ <<
"Using generic biasing: " << BDS::BoolToString(overallUseBiasing) << G4endl;
1238 if (!overallUseBiasing)
1243 for (
auto const & item : allAcceleratorComponents)
1246 {G4cout << __METHOD_NAME__ <<
"checking component named: " << item.first.componentName << G4endl;}
1251 G4String accName = accCom->
GetName();
1256 if (!vacuumBiasList.empty() && vacuumLVs.empty())
1257 {BDS::Warning(
"biasVacuum set for component \"" + accName +
"\" but there's no 'vacuum' volume for it and it can't be biased.\nRemove biasVacuum or name it with the namedVacuumVolumes parameter.");}
1258 if ((!vacuumBiasList.empty() || useDefaultBiasVacuum) && !vacuumLVs.empty())
1261 for (
auto lv : vacuumLVs)
1264 {G4cout << __METHOD_NAME__ <<
"vacuum volume name: " << lv <<
" " << lv->GetName() << G4endl;}
1265 egVacuum->AttachTo(lv);
1271 if (!materialBiasList.empty() || useDefaultBiasMaterial)
1276 {G4cout << __METHOD_NAME__ <<
"# of logical volumes for biasing under 'material': " << allLVs.size() << G4endl;}
1277 for (
auto lv : allLVs)
1280 {G4cout << __METHOD_NAME__ <<
"Biasing 'material' logical volume: " << lv <<
" " << lv->GetName() << G4endl;}
1281 egMaterial->AttachTo(lv);
1287 if (!nameAndMaterialLVBiasList.empty() || useDefaultBiasMaterial)
1289 std::map<std::string, std::string> namesAndBiasesMap;
1290 for (G4String lvbias : nameAndMaterialLVBiasList)
1292 auto splitpos = lvbias.find(
':');
1293 auto lvname = lvbias.substr(0,splitpos);
1294 auto biasname = lvbias.substr(splitpos+1);
1295 namesAndBiasesMap[lvname] = biasname;
1299 {G4cout << __METHOD_NAME__ <<
"# of logical volumes for biasing under 'materialLV': " << allLVs.size() << G4endl;}
1300 for (
auto lv : allLVs)
1303 {G4cout << __METHOD_NAME__ <<
"Biasing 'materialLV' logical volume: " << lv <<
" " << lv->GetName() << G4endl;}
1304 for (
const auto& nameAndBias : namesAndBiasesMap)
1306 if (lv->GetName().find(nameAndBias.first) != std::string::npos)
1309 egMaterialLV->AttachTo(lv);
1316 if (useBiasForWorldContents)
1318 std::list<std::string> emptyList;
1321 {egWC->AttachTo(lv);}
1323 if (useBiasForWorldVolume)
1325 std::list<std::string> emptyList;
1327 egWV->AttachTo(worldLogicalVolume);
1329 if (useBiasForWorldVacuum)
1331 std::list<std::string> emptyList;
1333 for (
auto lv : worldVacuumLogicalVolumes)
1334 {egWVac->AttachTo(lv);}
1350 while ((*element).type == GMAD::ElementType::_LINE)
1353 if ((*element).type == GMAD::ElementType::_RBEND)
1369 if (scoringMeshes.empty())
1372 G4ScoringManager* scManager = G4ScoringManager::GetScoringManager();
1373 scManager->SetVerboseLevel(1);
1376 std::map<G4String, BDSScorerInfo> scorerRecipes;
1377 for (
const auto& scorer : scorers)
1380 scorerRecipes.insert(std::make_pair(si.
name, si));
1385 for (
const auto& mesh : scoringMeshes)
1391 G4String meshName = meshRecipe.name;
1401 G4String geometryType =
BDS::LowerCase(G4String(mesh.geometryType));
1403 if (geometryType ==
"box")
1406 mapper = scorerBox->Mapper();
1408 else if (geometryType ==
"cylindrical")
1411 mapper = scorerCylindrical->Mapper();
1415 G4String msg =
"mesh geometry type \"" + geometryType +
"\" is not correct. The possible options are \"box\" and \"cylindrical\"";
1420 std::vector<G4String> meshPrimitiveScorerNames;
1421 std::vector<G4double> meshPrimitiveScorerUnits;
1422 std::vector<G4String> scorerNames;
1425 for (
const auto& word : words)
1427 auto search = scorerRecipes.find(word);
1428 if (search == scorerRecipes.end())
1429 {
throw BDSException(__METHOD_NAME__,
"scorerQuantity \"" + word +
"\" for mesh \"" + meshName +
"\" not found.");}
1431 G4double psUnit = 1.0;
1432 G4VPrimitiveScorer* ps = scorerFactory.
CreateScorer(&(search->second), mapper, &psUnit, worldLV);
1437 G4String uniqueName = meshName +
"/" + ps->GetName();
1438 meshPrimitiveScorerNames.push_back(uniqueName);
1439 meshPrimitiveScorerUnits.push_back(psUnit);
1442 if (geometryType ==
"box")
1443 {scorerBox->SetPrimitiveScorer(ps);}
1444 else if (geometryType ==
"cylindrical")
1445 {scorerCylindrical->SetPrimitiveScorer(ps);}
1452 if (geometryType ==
"box")
1453 {scManager->RegisterScoringMesh(scorerBox);}
1454 else if (geometryType ==
"cylindrical")
1455 {scManager->RegisterScoringMesh(scorerCylindrical);}
1466 std::vector<BDSFieldQueryInfo*> result;
1468 for (
const auto& def : parserQueries)
1470 G4bool assumeQueryMagnetic =
false;
1471 if (!def.queryMagneticField && !def.queryElectricField)
1473 assumeQueryMagnetic =
true;
1474 G4cout << __METHOD_NAME__ <<
"neither \"queryMagneticField\" nor \"queryElectricField\" are turned on for definition \""
1475 << def.name <<
"\"" << G4endl;
1476 G4cout <<
"-> querying magnetic field by default" << G4endl;
1479 if (!def.pointsFile.empty())
1481 std::vector<G4String> columnNames;
1484 G4String(def.outfileMagnetic),
1485 G4String(def.outfileElectric),
1486 G4bool(def.queryMagneticField) || assumeQueryMagnetic,
1487 G4bool(def.queryElectricField),
1490 G4bool(def.overwriteExistingFiles),
1491 G4String(def.fieldObject),
1492 def.checkParameters,
1494 def.drawZeroValuePoints,
1501 auto rot = globalTransform3D.getRotation();
1502 rot = rot.inverse();
1503 G4AffineTransform globalTransform(rot, globalTransform3D.getTranslation());
1506 G4String(def.outfileMagnetic),
1507 G4String(def.outfileElectric),
1508 G4bool(def.queryMagneticField) || assumeQueryMagnetic,
1509 G4bool(def.queryElectricField),
1510 {def.nx, def.xmin*CLHEP::m, def.xmax*CLHEP::m},
1511 {def.ny, def.ymin*CLHEP::m, def.ymax*CLHEP::m},
1512 {def.nz, def.zmin*CLHEP::m, def.zmax*CLHEP::m},
1513 {def.nt, def.tmin*CLHEP::ns, def.tmax*CLHEP::ns},
1515 G4bool(def.overwriteExistingFiles),
1516 G4String(def.fieldObject),
1517 G4bool(def.printTransform),
1518 def.checkParameters,
1520 def.drawZeroValuePoints,
1528#ifdef BDSCHECKUSERLIMITS
1529void BDSDetectorConstruction::PrintUserLimitsSummary(
const G4VPhysicalVolume* world)
const
1531 G4cout <<
"USERLIMITS START" << G4endl;
1533 PrintUserLimitsPV(world, globalMinEK);
1534 G4cout <<
"USERLIMITS END" << G4endl;
1537void BDSDetectorConstruction::PrintUserLimitsPV(
const G4VPhysicalVolume* aPV, G4double globalMinEK)
const
1539 const auto lv = aPV->GetLogicalVolume();
1540 const auto ul = lv->GetUserLimits();
1544 G4double ekUL = ul->GetUserMinEkine(dummyTrack);
1546 if (ekUL < globalMinEK)
1547 {G4cout << lv->GetName() <<
" Ek Min: " << ekUL <<
" MeV < global: " << globalMinEK <<
" MeV" << G4endl;}
1550 {G4cout << lv->GetName() <<
" no G4UserLimits" << G4endl;}
1551 for (G4int i = 0; i < (G4int)lv->GetNoDaughters(); i++)
1552 {PrintUserLimitsPV(lv->GetDaughter(i), globalMinEK);}
1558 if (!worldLogicalVolume)
1560 G4cout <<
"\nSensitivity Summary:\n" << G4endl;
1562 G4cout <<
"\n\n" << G4endl;
1567 for (G4int i = 0; i < currentDepth; i++)
1569 G4cout << lv->GetName() <<
" ";
1570 auto sensitiveDetector = lv->GetSensitiveDetector();
1571 if (sensitiveDetector)
1572 {G4cout << sensitiveDetector->GetName();}
1577 for (std::size_t i = 0; i < lv->GetNoDaughters(); i++)
A registry of constructed BDSAcceleratorComponent instances that can be searched.
static BDSAcceleratorComponentRegistry * Instance()
Singleton accessor.
std::unordered_map< ACRegistryKey, BDSAcceleratorComponent * > AllComponentsIncludingUnique() const
void PrintNumberOfEachType() const
Print out the number of each type of component registered.
size_t size() const
Size of registry.
Abstract class that represents a component of an accelerator.
virtual void Initialise()
std::list< std::string > GetBiasMaterialLVList() const
Access the bias list copied from parser.
virtual G4String GetName() const
The name of the component without modification.
virtual std::set< G4LogicalVolume * > GetAcceleratorVacuumLogicalVolumes() const
Access the 'vacuum' volume(s) in this component if any. Default is empty set.
virtual std::set< G4LogicalVolume * > GetAcceleratorMaterialLogicalVolumes() const
Return a set of logical volumes excluding the ones in the 'vacuum' set.
std::list< std::string > GetBiasVacuumList() const
Access the bias list copied from parser.
G4String GetType() const
Get a string describing the type of the component.
std::list< std::string > GetBiasMaterialList() const
Access the bias list copied from parser.
void RegisterFields(std::vector< BDSFieldObjects * > &fieldsIn)
Register all field objects.
void RegisterBeamlineSetExtra(const G4String &name, const BDSBeamlineSet &setIn)
Register a set of beam lines to be managed and cleared up at the end of the simulation.
void RegisterWorldLV(G4LogicalVolume *worldIn)
Register constituent of world.
std::set< G4LogicalVolume * > * VolumeSet(const G4String &name)
Returns pointer to a set of logical volumes. If no set by that name exits, create it.
BDSApertureInfo * Aperture(G4String name) const
const std::map< G4String, BDSBeamlineSet > & ExtraBeamlines() const
Accessor.
BDSBeamline * TunnelBeamline() const
Access the beam line containing all the tunnel segments.
void RegisterApertures(const std::map< G4String, BDSApertureInfo * > &aperturesIn)
Register a map of apertures with associated names.
void RegisterScorerPlacement(const G4String &meshName, const G4Transform3D &placement)
Register a copy of the scorer placement so it can be used in the output.
const BDSBeamlineSet & BeamlineSetMain() const
Accessor.
const BDSBeamline * BeamlineMain() const
Accessor.
void RegisterTunnelBeamline(BDSBeamline *beamlineIn)
Register the beam line containing all the tunnel segments.
BDSBeamline * PlacementBeamline() const
Access the beam line of arbitrary placements.
void RegisterWorldPV(G4VPhysicalVolume *worldIn)
Register constituent of world.
void RegisterPlacementBeamline(BDSBeamline *placementBLIn)
Register the beam line of arbitrary placements.
void RegisterBeamlineSetMain(const BDSBeamlineSet &setIn)
Register the main beam line set.
void RegisterScorerHistogramDefinition(const BDSScorerHistogramDef &def)
G4LogicalVolume * WorldLV() const
Access the logical volume of the world.
void RegisterBLMs(BDSBeamline *blmsIn)
Register a beam line of blm placements.
G4Region * Region(const G4String &name) const
Access region information. Will exit if not found.
void RegisterWorldSolid(G4VSolid *worldIn)
Register constituent of world.
void RegisterRegion(BDSRegion *region)
Register a region.
Holder class for all information required to describe an aperture.
static void AttachWorldVolumeToNavigator(G4VPhysicalVolume *worldPVIn)
Setup the navigator w.r.t. to a world volume - typically real world.
static BDSBLMRegistry * Instance()
Accessor for registry.
Multi-particle cross-section changer.
A class that holds a fully constructed BDSAcceleratorComponent as well as any information relevant to...
G4double GetSPositionEnd() const
Accessor.
G4double GetSPositionMiddle() const
Accessor.
A class that holds the current integrated quantities along a beam line.
G4bool integrateKineticEnergy
On by default, but allow control to not integrate it for old behaviour.
Simple struct to return a beamline plus associated beam lines.
void GetExtentGlobals(std::vector< BDSExtentGlobal > &extents) const
Append global extents of all beamlines to supplied vector.
A vector of BDSBeamlineElement instances - a beamline.
const BDSBeamlineElement * GetElement(G4String acceleratorComponentName, G4int i=0) const
Get the ith placement of an element in the beam line. Returns null pointer if not found.
BDSBeamlineElement * back() const
Return a reference to the last element.
G4bool ElementAnglesSumToCircle() const
Check if the sum of the angle of all elements is two pi.
reverse_iterator rend()
Iterator mechanics.
void AddComponent(BDSAcceleratorComponent *component, BDSTiltOffset *tiltOffset=nullptr, BDSSamplerInfo *samplerInfo=nullptr, const BDSBeamlineIntegral *beamlineIntegral=nullptr)
const_iterator FindFromS(G4double S) const
Returns an iterator to the beamline element at s.
G4bool empty() const
Iterator mechanics.
G4Transform3D GetGlobalEuclideanTransform(G4double s, G4double x=0, G4double y=0, G4int *indexOfFoundElement=nullptr) const
BDSExtentGlobal GetExtentGlobal() const
Get the global extents for this beamline.
reverse_iterator rbegin()
Iterator mechanics.
iterator begin()
Iterator mechanics.
iterator end()
Iterator mechanics.
Factory for user specified accelerator components.
Factory to produce all types of BDSAcceleratorComponents.
BDSAcceleratorComponent * CreateComponent(GMAD::Element const *elementIn, GMAD::Element const *prevElementIn, GMAD::Element const *nextElementIn, BDSBeamlineIntegral &integral)
BDSAcceleratorComponent * CreateTeleporter(const G4double teleporterLength, const G4double teleporterWidth, const G4Transform3D &transformIn)
BDSAcceleratorComponent * CreateTerminator(G4double witdth)
static BDSTiltOffset * CreateTiltOffset(GMAD::Element const *el)
Create the tilt and offset information object by inspecting the parser element.
Factory for simple parallel geometry for curvilinear coordinates.
BDSBeamline * BuildCurvilinearBeamLine1To1(BDSBeamline const *const beamline, const G4bool circular)
Build a beam line of curvilinear geometry based on another beam line.
BDSBeamline * BuildCurvilinearBridgeBeamLine(BDSBeamline const *const beamline)
Build bridging volumes to join the curvilinear ones.
G4bool circular
Whether or not we're building a circular machine.
void UpdateSamplerDiameterAndCountSamplers()
BDSBOptrMultiParticleChangeCrossSection * BuildCrossSectionBias(const std::list< std::string > &biasList, const std::list< std::string > &defaultBias, const G4String &elementName)
Function that creates physics biasing cross section.
void InitialiseRegions()
Create and set parameters for various G4Regions.
std::vector< BDSBOptrMultiParticleChangeCrossSection * > biasObjects
List of bias objects - for memory management.
BDSExtent CalculateExtentOfScorerMesh(const GMAD::ScorerMesh &sm) const
Calculate local extent of scorer mesh in 3D.
BDSAcceleratorModel * acceleratorModel
Accelerator model pointer.
static G4ThreeVector SideToLocalOffset(const GMAD::Placement &placement, const BDSBeamline *beamLine, const BDSExtent &placementExtent)
Attach component with extent2 to component with extent1 with placement.
G4bool verbose
Variable copied from global constants.
BDSBeamline * placementBL
static std::vector< BDSFieldQueryInfo * > PrepareFieldQueries(const BDSBeamline *mainBeamline)
Prepare field queries from parser information.
G4VPhysicalVolume * BuildWorld()
void VerboseSensitivity() const
Print out the sensitivity of every single volume so far constructed in the world.
void InitialiseApertures()
Create all aperture definitions from parser and store in BDSAcceleratorModel.
void CountPlacementFields()
Count number of fields required for placements.
G4bool canSampleAngledFaces
Whether the integrator set permits sampling elements with angled faces.
BDSExtent worldExtent
Record of the world extent.
std::set< G4LogicalVolume * > worldContentsLogicalVolumes
Cache of possibly loaded logical volumes from a world geometry file - used for biasing.
static BDSSamplerInfo * BuildSamplerInfo(const GMAD::Element *element)
BDSExtent CalculateExtentOfSamplerPlacement(const GMAD::SamplerPlacement &sp) const
Calculate local extent of custom user sampler.
void ConstructScoringMeshes()
Construct scoring meshes.
BDSBeamlineSet BuildBeamline(const GMAD::FastList< GMAD::Element > &beamLine, const G4String &name, const BDSBeamlineIntegral &startingIntegral, BDSBeamlineIntegral *&integral, const G4Transform3D &initialTransform=G4Transform3D(), G4bool beamlineIsCircular=false, G4bool isPlacementBeamline=false)
BDSExtentGlobal CalculateExtentOfScorerMeshes(const BDSBeamline *bl) const
G4bool checkOverlaps
Variable copied from global constants.
G4int nSamplers
Count of number of samplers to be built.
void ComponentPlacement(G4VPhysicalVolume *worldPV)
Place beam line, tunnel beam line, end pieces and placements in world.
void BuildBeamlines()
Build the main beam line and then any other required beam lines.
const BDSParticleDefinition * designParticle
Particle definition all components are built w.r.t. Includes rigidity etc.
void BuildTunnel()
Build the tunnel around the already constructed flat beam line.
virtual void ConstructSDandField()
Construct sensitive detectors and fields.
void PrintSensitiveDetectorsOfLV(const G4LogicalVolume *lv, G4int currentDepth) const
Recursive function to print out each sensitive detector name.
void PrepareExtraSamplerSDs()
static void PlaceBeamlineInWorld(BDSBeamline *beamline, G4VPhysicalVolume *containerPV, G4bool checkOverlaps=false, G4bool setRegions=false, G4bool registerInfo=false, G4bool useCLPlacementTransform=false, G4bool useIncrementalCopyNumbers=false, G4bool registerPlacementNamesForOutput=false)
virtual G4VPhysicalVolume * Construct()
static G4Transform3D CreatePlacementTransform(const GMAD::Placement &placement, const BDSBeamline *beamLine, G4double *S=nullptr, BDSExtent *placementExtent=nullptr, const G4String &objectTypeForErrorMsg="placement")
G4bool UnsuitableFirstElement(std::list< GMAD::Element >::const_iterator element)
BDSExtentGlobal CalculateExtentOfSamplerPlacements(const BDSBeamline *beamLine) const
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions with a rotation and translation.
BDSExtentGlobal ExpandToEncompass(const BDSExtentGlobal &other) const
Return a copy of this extent but expanded to encompass another global extent.
G4bool Encompasses(const BDSExtentGlobal &otherExtent)
Return whether the extent encompasses another extent.
Holder for +- extents in 3 dimensions.
G4double XPos() const
Accessor.
G4double XNeg() const
Accessor.
G4double YNeg() const
Accessor.
std::pair< G4double, G4double > ExtentZ() const
Accessor.
G4double DX() const
The difference in a dimension.
G4double YPos() const
Accessor.
static BDSFieldBuilder * Instance()
Singleton pattern accessor.
Holder class for all information required for a field query.
static void AttachWorldVolumeToNavigator(G4VPhysicalVolume *worldPVIn)
Setup the navigator w.r.t. to a world volume.
Gap in accelerator beamline.
G4LogicalVolume * GetContainerLogicalVolume() const
Accessor - see member for more info.
BDSExtent GetExtent() const
Accessor - see member for more info.
virtual void AttachSensitiveDetectors()
Attach a sensitive detector class to all registered sensitive volumes in this component.
virtual std::set< G4LogicalVolume * > GetAllLogicalVolumes() const
Access all logical volumes belonging to this component.
G4VSolid * GetContainerSolid() const
Accessor - see member for more info.
A loaded piece of externally provided geometry.
const std::set< G4LogicalVolume * > & VacuumVolumes() const
Access the vacuum volumes.
BDSGeometryExternal * BuildGeometry(G4String componentName, const G4String &formatAndFilePath, std::map< G4String, G4Colour * > *colourMapping=nullptr, G4bool autoColour=true, G4double suggestedLength=0, G4double suggestedHorizontalWidth=0, std::vector< G4String > *namedVacuumVolumes=nullptr, G4bool makeSensitive=true, BDSSDType sensitivityType=BDSSDType::energydep, BDSSDType vacuumSensitivityType=BDSSDType::energydepvacuum, G4bool stripOuterVolumeAndMakeAssembly=false, G4UserLimits *userLimitsToAttachToAllLVs=nullptr, G4bool dontReloadGeometry=false)
static BDSGeometryFactory * Instance()
Singleton accessor.
A class that holds global options and constants.
void SetCurvilinearDiameterShrunkForBends()
Setter.
static BDSGlobalConstants * Instance()
Access method.
void SetCurvilinearDiameter(G4double curvilinearDiameterIn)
Setter.
void SetSamplerDiameter(G4double samplerDiameterIn)
Setter.
G4bool UseImportanceSampling() const
Is importance sampling being used.
Mapping from axis indices to 1D index.
A class that hold multiple accelerator components.
static BDSMaterials * Instance()
Singleton pattern access.
G4Material * GetMaterial(G4String material) const
Get material by name.
const GMAD::FastList< GMAD::Element > & GetSequence(const std::string &name)
Return sequence.
std::vector< GMAD::Scorer > GetScorers() const
Return the parser list of that object.
std::vector< GMAD::ScorerMesh > GetScorerMeshes() const
Return the parser list of that object.
static BDSParser * Instance()
Access method.
std::vector< GMAD::Query > GetQueries() const
Return the parser list of that object.
std::vector< GMAD::Aperture > GetApertures() const
Return the parser list of that object.
const GMAD::Options & GetOptions() const
Return options.
std::vector< GMAD::SamplerPlacement > GetSamplerPlacements() const
Return the parser list of that object.
std::vector< GMAD::Region > GetRegions() const
Return the parser list of that object.
const GMAD::FastList< GMAD::PhysicsBiasing > & GetBiasing() const
Return biasing list.
std::vector< GMAD::Placement > GetPlacements() const
Return the parser list of that object.
void RegisterPVsForOutput(const BDSBeamlineElement *element, const std::set< G4VPhysicalVolume * > &physicalVolumes)
void RegisterExcludedPV(G4VPhysicalVolume *physicalVolume)
void RegisterInfo(G4VPhysicalVolume *physicalVolume, BDSPhysicalVolumeInfo *info, G4bool isReadOutVolume=false, G4bool isTunnel=false)
static BDSPhysicalVolumeInfoRegistry * Instance()
Singleton accessor.
A class holding any information pertaining to a particular physical volume in a BDSIM geant4 model.
Range cuts for a region. Help with defaults.
void ConstructSamplerSDsForParticleSets(const std::map< int, std::set< int > > &samplerFilterIDtoPDGSetIn)
void RegisterPrimitiveScorerNames(const std::vector< G4String > &namesIn, const std::vector< G4double > *units=nullptr)
Loop over a vector and apply above single name function.
All info required to build a sampler but not place it.
Create primitive scorers on demand.
G4VPrimitiveScorer * CreateScorer(const BDSScorerInfo *info, const BDSHistBinMapper *mapper, G4double *unit=nullptr, G4LogicalVolume *worldLV=nullptr)
Main function to create a scorer.
Definition for a scorer histogram.
Recipe class for scorer. Checks values.
G4String name
Scorer name.
Recipe class for a scoring mesh.
Wrapper for G4ScoringBox to allow full access to placement.
Wrapper for G4ScoringCylinder to allow full access to placement.
A class of functions to output Geant4/Mokka/BDSIM parameters for the beamline.
void Write(BDSBeamlineElement *beamlineElement)
write line
A holder for any placement offsets and rotations for a BDSAcceleratorComponent.
static G4double dEThresholdForScattering
A class that constructs tunnel segments around a beamline.
BDSBeamline * BuildTunnelSections(const BDSBeamline *flatBeamLine) const
List with Efficient Lookup.
bool empty() const
Whether the list is empty.
FastListConstIterator find(std::string name, unsigned int count=1) const
int size() const
size of list
const FastList< Element > & GetBeamline() const
Physics biasing class for parser.
std::vector< double > factor
factors corresponding to process
std::vector< PhysicsBiasingType > flag
flag which particles are biased
std::string particle
particle name
std::string process
geant4 process: single string, but can have multiple processes separated with a space
Placement class for parser.
bool axisAngle
Flag to use the axis angle construction of rotation.
std::string name
Name of this placement.
std::string side
which side to attach to: top, bottom, left, right.
double theta
Euler angle for rotation.
double sideOffset
Gap between side and component.
double psi
Euler angle for rotation.
double s
Curvilinear s position to place w.r.t..
int referenceElementNumber
Index of repetition of element if there are multiple uses.
double phi
Euler angle for rotation.
std::string referenceElement
Name of reference element w.r.t. to place to.
Query structure class for parser.
Sampler placement class for parser.
std::string name
Name of this samplerplacement.
std::string samplerType
Plane, Cylinder, Sphere.
ScorerMesh class for parser.
BDSBeamline * BuildEndPieceBeamline(const BDSBeamline *beamline, const G4bool circularMachine)
G4Transform3D CalculateTeleporterDelta(const BDSBeamline *beamline, G4double &teleporterLength)
std::vector< BDSFourVector< G4double > > LoadFieldQueryPoints(const G4String &fileName, std::vector< G4String > *columnNamesIn)
BDSExtent MaximumCombinedExtent(const BDSExtent &first, const BDSExtent &second)
Returns the extent which is the greatest extent in all six directions.
G4bool EndsWith(const std::string &expression, const std::string &suffix)
Return true if a string "expression" ends with "suffix".
G4String LowerCase(const G4String &str)
Utility function to simplify lots of syntax changes for pedantic g4 changes.
BDSBeamline * BuildPlacementGeometry(const std::vector< GMAD::Placement > &placements, const BDSBeamline *parentBeamLine, BDSComponentFactory *componentFactory, const BDSParticleDefinition *designParticle)
std::vector< G4String > SplitOnWhiteSpace(const G4String &input)
Split a string on whitespace and return a vector of these 'words'.
BDSBeamline * BuildBLMs(const std::vector< GMAD::BLMPlacement > &blmPlacements, const BDSBeamline *parentBeamLine)
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())
G4String StrStrip(const G4String &str, char ch, StringStripType stripType=StringStripType::both)
Utility function to simplify lots of syntax changes for pedantic g4 changes.
std::string samplerType
element has a sampler of this type (default "none")
double e1
input pole face rotation for bends
std::string samplerName
name of sampler (default empty)