19#include "BDSAcceleratorComponent.hh"
20#include "BDSAcceleratorComponentRegistry.hh"
21#include "BDSAcceleratorModel.hh"
22#include "BDSApertureInfo.hh"
23#include "BDSAuxiliaryNavigator.hh"
24#include "BDSBeamline.hh"
25#include "BDSBeamlineBLMBuilder.hh"
26#include "BDSBeamlineEndPieceBuilder.hh"
27#include "BDSBeamlineElement.hh"
28#include "BDSBeamlineIntegral.hh"
29#include "BDSBeamlinePlacementBuilder.hh"
30#include "BDSBeamlineSet.hh"
31#include "BDSBeamPipeInfo.hh"
33#include "BDSBLMRegistry.hh"
34#include "BDSBOptrMultiParticleChangeCrossSection.hh"
35#include "BDSComponentFactory.hh"
36#include "BDSComponentFactoryUser.hh"
37#include "BDSCurvilinearBuilder.hh"
39#include "BDSDetectorConstruction.hh"
40#include "BDSException.hh"
41#include "BDSExtent.hh"
42#include "BDSFieldBuilder.hh"
43#include "BDSFieldObjects.hh"
44#include "BDSFieldQuery.hh"
45#include "BDSFieldQueryInfo.hh"
46#include "BDSFieldLoaderQueryPoints.hh"
48#include "BDSGeometryComponent.hh"
49#include "BDSGeometryExternal.hh"
50#include "BDSGeometryFactory.hh"
51#include "BDSGlobalConstants.hh"
52#include "BDSHistBinMapper.hh"
53#include "BDSIntegratorSet.hh"
55#include "BDSMaterials.hh"
56#include "BDSParser.hh"
57#include "BDSPhysicalVolumeInfo.hh"
58#include "BDSPhysicalVolumeInfoRegistry.hh"
59#include "BDSRegion.hh"
60#include "BDSSamplerInfo.hh"
61#include "BDSSamplerType.hh"
62#include "BDSScorerFactory.hh"
63#include "BDSScorerInfo.hh"
64#include "BDSScorerMeshInfo.hh"
65#include "BDSScoringMeshBox.hh"
66#include "BDSScoringMeshCylinder.hh"
67#include "BDSSDEnergyDeposition.hh"
68#include "BDSSDManager.hh"
69#include "BDSSDType.hh"
70#include "BDSSurvey.hh"
71#include "BDSTeleporter.hh"
72#include "BDSTrajectoryPoint.hh"
73#include "BDSTunnelBuilder.hh"
74#include "BDSUtilities.hh"
75#include "BDSWarning.hh"
77#include "parser/blmplacement.h"
78#include "parser/element.h"
79#include "parser/fastlist.h"
80#include "parser/options.h"
81#include "parser/physicsbiasing.h"
82#include "parser/placement.h"
83#include "parser/samplerplacement.h"
84#include "parser/scorermesh.h"
87#include "G4AffineTransform.hh"
89#include "G4LogicalVolume.hh"
90#include "G4Material.hh"
91#include "G4ProductionCuts.hh"
92#include "G4PVPlacement.hh"
93#include "G4VPrimitiveScorer.hh"
95#include "G4ScoringManager.hh"
97#include "G4Transform3D.hh"
98#include "G4Version.hh"
99#include "G4VisAttributes.hh"
100#include "G4VPhysicalVolume.hh"
101#if G4VERSION_NUMBER > 1039
102#include "G4ChannelingOptrMultiParticleChangeCrossSection.hh"
104#if G4VERSION_NUMBER > 1109
105#include "G4HadronicParameters.hh"
108#ifdef BDSCHECKUSERLIMITS
109#include "G4UserLimits.hh"
112#include "CLHEP/Units/SystemOfUnits.h"
113#include "CLHEP/Vector/EulerAngles.h"
127 placementBL(nullptr),
128 designParticle(nullptr),
129 userComponentFactory(userComponentFactoryIn),
131 buildPlacementFieldsWorld(false),
132 worldLogicalVolume(nullptr)
135 verbose = globals->Verbose();
136 checkOverlaps = globals->CheckOverlaps();
137 circular = globals->Circular();
139 if (globals->RestoreFTPFDiffractionForAGreater10())
140#if G4VERSION_NUMBER > 1109
142 G4cout << __METHOD_NAME__ <<
"restoring diffraction for target / projectiles with A > 10 in the FTFP hadronic model (even if not used)" << G4endl;
143 G4HadronicParameters::Instance()->SetEnableDiffDissociationForBGreater10(
true);
147 if (globals->RestoreFTPFDiffractionForAGreater10Set())
148 {BDS::Warning(__METHOD_NAME__,
"\"restoreFTPFDiffractionForAGreater10\" is only available for Geant4 v11.1 and later");}
155 acceleratorModel = BDSAcceleratorModel::Instance();
156 canSampleAngledFaces =
true;
158 if ( (integratorSetType == BDSIntegratorSetType::bdsimtwo)
159 || (integratorSetType == BDSIntegratorSetType::geant4)
160#
if G4VERSION_NUMBER > 1039
161 || (integratorSetType == BDSIntegratorSetType::geant4dp)
165 canSampleAngledFaces = globals->SampleElementsWithPoleface();
168 UpdateSamplerDiameterAndCountSamplers();
169 PrepareExtraSamplerSDs();
170 CountPlacementFields();
177 G4double maxBendingRatio = 1e-9;
178 for (
const auto& blElement : beamline)
181 auto st = BDS::DetermineSamplerType(blElement.samplerType);
182 if (st != BDSSamplerType::none)
185 G4double length = blElement.l;
186 G4double angle = blElement.angle;
189 G4double ratio = angle / length;
190 maxBendingRatio = std::max(maxBendingRatio, ratio);
194 G4double curvilinearRadius = 0.5*globals->CurvilinearDiameter();
195 G4double tolerance = 0.9;
196 if (maxBendingRatio > 0.4*tolerance)
198 G4double curvilinearRadiusBends = (tolerance / maxBendingRatio)*CLHEP::m;
199 if (curvilinearRadiusBends < curvilinearRadius)
201 G4cout << __METHOD_NAME__ <<
"Reducing curvilinear diameter from " << 2*curvilinearRadius / CLHEP::m
202 <<
"m to " << 2*curvilinearRadiusBends / CLHEP::m <<
"m" << G4endl;
206 G4double sd = globals->SamplerDiameter();
207 if (curvilinearRadius*2 < sd)
209 G4cout << __METHOD_NAME__ <<
"Reducing sampler diameter from " << sd / CLHEP::m <<
"m to the same" << G4endl;
228 for (
const auto& placement : placements)
230 if (!placement.fieldAll.empty() || !placement.bdsimElement.empty())
233 buildPlacementFieldsWorld = nFields > 0;
239 {G4cout << __METHOD_NAME__ <<
"starting accelerator geometry construction\n" << G4endl;}
258 delete componentFactory;
275 {G4cout << __METHOD_NAME__ <<
"detector Construction done" << G4endl;}
282 G4cout << G4endl << __METHOD_NAME__ <<
"printing material table" << G4endl;
283 G4cout << *(G4Material::GetMaterialTable()) << G4endl << G4endl;
284 if (
verbose || debug) {G4cout <<
"Finished listing materials, returning physiWorld" << G4endl;}
286#ifdef BDSCHECKUSERLIMITS
287 PrintUserLimitsSummary(worldPV);
292BDSDetectorConstruction::~BDSDetectorConstruction()
294#if G4VERSION_NUMBER > 1009
299 for (
auto q : fieldQueries)
309 G4cout <<
"New region defined: " << G4endl << *reg << G4endl;
312 delete defaultRegion;
317 std::map<G4String, BDSApertureInfo*> apertures;
326 apertures[a.name] = ap;
335 {G4cout <<
"parsing the beamline element list..."<< G4endl;}
337 G4Transform3D initialTransform = g->BeamlineTransform();
349 if (finishingPoint->changeOfEnergyEncountered)
350 {G4cout <<
"Design particle properties at end of beam line: " << G4endl << finishingPoint->designParticle;}
353 delete finishingPoint;
355 G4cout <<
"Registry size "
357 G4cout <<
"Parser beam line size "
363 if (!
circular && mainBeamline.massWorld)
366 {BDS::Warning(
"Total sum of all element angles is approximately 2*pi but the circular option was not specified, this simulation may run indefinitely");}
375 for (
const auto& placement : placements)
377 if (placement.sequence.empty())
390 BDSBeamlineIntegral thisBeamlineStartingPoint(startingPoint.designParticle, 0, startS, g->IntegrateKineticEnergyAlongBeamline());
397 G4String beamlineName = placement.name +
"_" + placement.sequence;
400 thisBeamlineStartingPoint,
401 thisBeamlineFinishingPoint,
406 delete thisBeamlineFinishingPoint;
414 if (sType == BDSSamplerType::none)
423 const G4String& name,
426 const G4Transform3D& initialTransform,
427 G4bool beamlineIsCircular,
428 G4bool isPlacementBeamline)
430 if (beamLine.
empty())
436 if (beamlineIsCircular)
441 G4cerr <<
"The first element in the beam line is unsuitable for a circular "
442 <<
"model as the first element will " << G4endl <<
"overlap with the "
443 <<
"teleporter and terminator - the necessary mechanics for a circular "
444 <<
"model in Geant4" << G4endl;
445 throw BDSException(__METHOD_NAME__,
"check construction for circular machine");
449 if (beamLine.
size() <= 1)
450 {
throw BDSException(__METHOD_NAME__,
"BDSIM requires the sequence defined with the use command to have at least one element.");}
452 for (
auto elementIt = beamLine.
begin(); elementIt != beamLine.
end(); ++elementIt)
456 auto prevIt = elementIt;
457 while (prevIt != beamLine.
begin())
462 prevElement = &(*prevIt);
468 auto nextIt = elementIt;
470 G4double nextElementInputFace = 0;
471 while (nextIt != beamLine.
end())
475 nextElement = &(*nextIt);
477 nextElementInputFace = nextElement->
e1;
488 G4bool forceNoSamplerOnThisElement =
false;
490 {forceNoSamplerOnThisElement =
true;}
492 {forceNoSamplerOnThisElement =
true;}
494 {forceNoSamplerOnThisElement =
true;}
497 massWorld->
AddComponent(temp, tiltOffset, samplerInfo, integral);
504 if (beamlineIsCircular && !massWorld->
empty())
508 G4String msg =
"a change in energy was encountered in a circular machine and both\n";
509 msg +=
"integrateKineticEnergyAlongBeamline=1 (default is 1) and circular options were used.\n";
510 msg +=
"This will be wrong for more than one turn...";
511 BDS::Warning(__METHOD_NAME__, msg);
514 G4cout << __METHOD_NAME__ <<
"Circular machine - creating terminator & teleporter" << G4endl;
516 G4double teleporterLength = 0;
519 auto hasBeamPipeInfo = [](
BDSBeamlineElement* ble) {
return ble->GetBeamPipeInfo() !=
nullptr;};
520 auto firstElementWithBPInfo = std::find_if(massWorld->
begin(), massWorld->
end(), hasBeamPipeInfo);
521 auto lastElementWithBPInfo = std::find_if(massWorld->
rbegin(), massWorld->
rend(), hasBeamPipeInfo);
523 G4double firstbeamPipeMaxExtent = (*firstElementWithBPInfo)->GetBeamPipeInfo()->Extent().MaximumAbsTransverse();
524 G4double lastbeamPipeMaxExtent = (*lastElementWithBPInfo)->GetBeamPipeInfo()->Extent().MaximumAbsTransverse();
527 G4double teleporterHorizontalWidth = 2 * std::max(firstbeamPipeMaxExtent, lastbeamPipeMaxExtent);
533 massWorld->
AddComponent(terminator,
nullptr,
nullptr, integral);
537 teleporterHorizontalWidth,
538 teleporterTransform);
542 massWorld->
AddComponent(teleporter,
nullptr,
nullptr, integral);
549 if (isPlacementBeamline)
552 survey->
Write(massWorld);
555 delete theComponentFactory;
558 G4cout << __METHOD_NAME__ <<
"\"" << name <<
"\" " << G4endl << *massWorld;
569 beamlineSet.massWorld = massWorld;
570 beamlineSet.curvilinearWorld = clBeamline;
571 beamlineSet.curvilinearBridgeWorld = clBridgeBeamline;
572 beamlineSet.endPieces = endPieces;
593 std::vector<BDSExtentGlobal> extents;
610 const auto& extras = BDSAcceleratorModel::Instance()->
ExtraBeamlines();
612 for (
const auto& bl : extras)
613 {bl.second.GetExtentGlobals(extents);}
622 G4ThreeVector worldR;
624 for (
const auto& ext : extents)
626 for (G4int i = 0; i < 3; i++)
627 {worldR[i] = std::max(worldR[i], ext.GetMaximumExtentAbsolute()[i]);}
630 G4String worldName =
"World";
631 G4VSolid* worldSolid =
nullptr;
632 G4LogicalVolume* worldLV =
nullptr;
634 G4String worldGeometryFile = globals->WorldGeometryFile();
635 if (!worldGeometryFile.empty())
637 if (globals->WorldMaterialSet())
638 {BDS::Warning(__METHOD_NAME__,
"conflicting options - world material option specified but material will be taken from world GDML file");}
639 G4bool ac = globals->AutoColourWorldGeometryFile();
641 std::vector<G4String> namedWorldVacuumVolumes =
BDS::SplitOnWhiteSpace(globals->WorldVacuumVolumeNames());
648 &namedWorldVacuumVolumes,
650 BDSSDType::energydepworldcontents,
651 BDSSDType::energydepvacuum);
657 for (
auto volume : worldVacuumLogicalVolumes)
658 {allWorldVolumes.erase(volume);}
663 G4bool worldContainsAllBeamlines = worldExtentGlobal.
Encompasses(extents);
665 G4cout <<
"External world geometry: \"" << worldGeometryFile <<
"\"" << G4endl;
666 G4cout <<
"Loaded world extent: \n" <<
worldExtent << G4endl;
669 if (!worldContainsAllBeamlines)
671 G4String message =
"Beamlines cannot be constructed, beamline extents are larger than \n";
672 message +=
"the extents of the external world";
682 if (globals->StoreELossWorld()
683 || globals->StoreELossWorldIntegral()
685 || globals->StoreELossWorldContents()
686 || globals->StoreELossWorldContentsIntegral())
690 worldLV->SetSensitiveDetector(BDSSDManager::Instance()->WorldComplete());
696 G4double margin = globals->WorldVolumeMargin();
697 margin = std::max(margin, 2*CLHEP::m);
698 worldR += G4ThreeVector(margin,margin,margin);
700 G4cout << __METHOD_NAME__ <<
"World dimensions: " << worldR / CLHEP::m <<
" m" << G4endl;
702 G4String worldMaterialName = globals->WorldMaterial();
705 worldSolid =
new G4Box(worldName +
"_solid", worldR.x(), worldR.y(), worldR.z());
708 worldLV =
new G4LogicalVolume(worldSolid,
714 if (globals->StoreELossWorld() || globals->StoreELossWorldIntegral())
715 {worldLV->SetSensitiveDetector(BDSSDManager::Instance()->WorldComplete());}
720 G4VisAttributes* debugWorldVis =
new G4VisAttributes(*(globals->ContainerVisAttr()));
721 debugWorldVis->SetForceWireframe(
true);
722 worldLV->SetVisAttributes(debugWorldVis);
725 worldLV->SetUserLimits(globals->DefaultUserLimits());
728 G4VPhysicalVolume* worldPV =
new G4PVPlacement(
nullptr,
751 worldLogicalVolume = worldLV;
782 const auto& extras = BDSAcceleratorModel::Instance()->
ExtraBeamlines();
783 for (
auto const& bl : extras)
792 G4VPhysicalVolume* containerPV,
793 G4bool checkOverlaps,
796 G4bool useCLPlacementTransform,
797 G4bool useIncrementalCopyNumbers,
798 G4bool registerPlacementNamesForOutput)
804 for (
auto element : *beamline)
807 if (
dynamic_cast<BDSGap*
>(element->GetAcceleratorComponent()))
812 auto accComp = element->GetAcceleratorComponent();
813 const G4String regionName = accComp->GetRegion();
814 if (!regionName.empty())
816 G4Region* region = BDSAcceleratorModel::Instance()->
Region(regionName);
817 auto contLV = accComp->GetContainerLogicalVolume();
818 contLV->SetRegion(region);
819 region->AddRootLogicalVolume(contLV);
824 element->GetAcceleratorComponent()->AttachSensitiveDetectors();
827 G4int copyNumber = useIncrementalCopyNumbers ? i : element->GetCopyNo();
828 G4String placementName = element->GetPlacementName() +
"_pv";
829 std::set<G4VPhysicalVolume*> pvs = element->PlaceElement(placementName, containerPV, useCLPlacementTransform,
836 element->GetSPositionMiddle(),
842 if (registerPlacementNamesForOutput)
852 const G4String& objectTypeForErrorMsg)
854 G4Transform3D result;
862 G4RotationMatrix rm = G4RotationMatrix();
865 G4ThreeVector axis = G4ThreeVector(placement.
axisX,
868 rm = G4RotationMatrix(axis, placement.
angle*CLHEP::rad);
876 CLHEP::HepEulerAngles ang = CLHEP::HepEulerAngles(placement.
phi*CLHEP::rad,
877 placement.
theta*CLHEP::rad,
878 placement.
psi*CLHEP::rad);
879 rm = G4RotationMatrix(ang);
889 {
throw BDSException(__METHOD_NAME__,
"no valid beam line yet for " + objectTypeForErrorMsg +
" w.r.t. a beam line.");}
894 G4cerr << __METHOD_NAME__ <<
"No element named \"" << placement.
referenceElement <<
"\" (instance #"
896 << placement.
name <<
"\"" << G4endl;
897 G4cout <<
"Note, this may be because the element is a bend and split into " << G4endl;
898 G4cout <<
"multiple sections with unique names. Run the visualiser to get " << G4endl;
899 G4cout <<
"the name of the segment, or place w.r.t. the element before / after." << G4endl;
900 throw BDSException(
"Error in "+objectTypeForErrorMsg+
".");
905 G4String message = objectTypeForErrorMsg +
" \"" + placement.
name +
"\" is placed using";
906 message +=
" a referenceElement but the z offset is\n non zero. Note, s should be used to";
907 message +=
" offset the placement in this case and z will\n have no effect.";
908 BDS::Warning(message);
911 sCoordinate += placement.
s * CLHEP::m;
915 G4ThreeVector offset = G4ThreeVector();
920 placement.
x * CLHEP::m + offset.x(),
921 placement.
y * CLHEP::m + offset.y());
922 G4Transform3D localRotation(rm, G4ThreeVector());
923 result = beamlinePart * localRotation;
928 {
throw BDSException(__METHOD_NAME__,
"no valid beam line yet placement w.r.t. a beam line.");}
929 G4ThreeVector offset = G4ThreeVector();
934 placement.
x * CLHEP::m + offset.x(),
935 placement.
y * CLHEP::m + offset.y());
937 G4Transform3D localRotation(rm, G4ThreeVector());
938 result = beamlinePart * localRotation;
940 {*S = placement.
s*CLHEP::m;}
944 G4ThreeVector translation = G4ThreeVector(placement.
x*CLHEP::m,
945 placement.
y*CLHEP::m,
946 placement.
z*CLHEP::m);
949 result = G4Transform3D(rm, translation);
997 G4ThreeVector result = G4ThreeVector();
998 G4String side = G4String(placement.
side);
1003 G4double pathLength = placement.
s*CLHEP::m;
1004 std::pair<G4double, G4double> extentZ = placementExtent.
ExtentZ();
1005 G4double sLow = pathLength + extentZ.first;
1006 G4double sHigh = pathLength + extentZ.second;
1010 if (end != beamLine->
end())
1016 for (
auto iter = start; iter != end; ++iter)
1027 result.setY(sectionMaxExtent.
YPos() + placementExtent.
YPos() + ls);
1028 G4double xOffset = sectionMaxExtent.
XPos() - 0.5*sectionMaxExtent.
DX();
1029 result.setX(xOffset);
1031 else if (side ==
"bottom")
1033 result.setY(sectionMaxExtent.
YNeg() + placementExtent.
YNeg() - ls);
1034 G4double xOffset = sectionMaxExtent.
XPos() - 0.5*sectionMaxExtent.
DX();
1035 result.setX(xOffset);
1037 else if (side ==
"left")
1038 {result.setX(sectionMaxExtent.
XPos() + placementExtent.
XPos() + ls);}
1039 else if (side ==
"right")
1040 {result.setX(sectionMaxExtent.
XNeg() + placementExtent.
XNeg() - ls);}
1041 else if (side !=
"")
1042 {
throw BDSException(std::string(
"Unknown side in placement: " + side));}
1049 if (sp.apertureModel.empty())
1054 sp.aper1 * CLHEP::m,
1055 sp.aper2 * CLHEP::m,
1056 sp.aper3 * CLHEP::m,
1057 sp.aper4 * CLHEP::m,
1059 apertureExtent = aperture.
Extent();
1062 {apertureExtent =
BDSExtent(sp.aper1*CLHEP::m, sp.aper1*CLHEP::m, sp.aper2*CLHEP::m);}
1064 {apertureExtent =
BDSExtent(sp.aper1*CLHEP::m, sp.aper1*CLHEP::m, sp.aper1*CLHEP::m);}
1071 apertureExtent = aperture->
Extent();
1076 apertureExtent.
YNeg(), apertureExtent.
YPos(),
1077 1*CLHEP::um, 1*CLHEP::um);
1085 for (
const auto& samplerPlacement : samplerPlacements)
1098 return recipe.Extent();
1105 for (
const auto& mesh : scorerMeshes)
1115#if G4VERSION_NUMBER > 1009
1118 const std::list<std::string>& defaultBias,
1119 const G4String& elementName)
1122 if (biasList.empty() && defaultBias.empty())
1125 std::list<std::string> biasesAll = biasList.empty() ? defaultBias : biasList;
1128 std::set<std::string> biasNamesSorted = {biasesAll.begin(), biasesAll.end()};
1129 G4String biasSetKey;
1130 G4String biasSetPrintOut;
1131 for (
const auto& n : biasNamesSorted)
1133 biasSetKey += n +
"_";
1134 biasSetPrintOut += n +
" ";
1136 biasSetKey =
BDS::StrStrip(biasSetKey,
'_', BDS::StringStripType::trailing);
1138 auto exists = biasSetObjects.find(biasSetKey);
1139 if (exists != biasSetObjects.end())
1140 {
return exists->second;}
1143 G4cout <<
"Bias> Creating unique set of bias objects ( " << biasSetPrintOut <<
")" << G4endl;
1147 for (std::string
const & bs : biasesAll)
1149 auto result = biasObjectList.
find(bs);
1150 if (result == biasObjectList.end())
1151 {
throw BDSException(
"Error: bias named \"" + bs +
"\" not found for element named \"" + elementName +
"\"");}
1155 {G4cout << __METHOD_NAME__ <<
"bias loop : " << bs <<
" " << pb.
particle <<
" " << pb.
process << G4endl;}
1160 if (pb.
flag.size() != pb.processList.size())
1161 {
throw BDSException(__METHOD_NAME__,
"number of flag entries in \"" + pb.
name +
"\" doesn't match number of processes");}
1162 if (pb.
factor.size() != pb.processList.size())
1163 {
throw BDSException(__METHOD_NAME__,
"number of factor entries in \"" + pb.
name +
"\" doesn't match number of processes");}
1164 for (
unsigned int p = 0; p < pb.processList.size(); ++p)
1169 biasSetObjects[biasSetKey] = eg;
1176#if G4VERSION_NUMBER > 1009
1179 {G4cout << __METHOD_NAME__ <<
"registry=" << registry << G4endl;}
1181#if G4VERSION_NUMBER > 1039
1184 std::set<G4LogicalVolume*>* crystals = BDSAcceleratorModel::Instance()->
VolumeSet(
"crystals");
1185 if (!crystals->empty())
1187 G4cout << __METHOD_NAME__ <<
"Using crystal biasing: true" << G4endl;
1188 auto crystalBiasing =
new G4ChannelingOptrMultiParticleChangeCrossSection();
1189 for (
auto crystal : *crystals)
1190 {crystalBiasing->AttachTo(crystal);}
1195 for (
auto blm : blmSet)
1197 G4String biasNamesS = blm->Bias();
1198 if (biasNamesS.empty())
1201 std::list<std::string> biasNames = {biasNamesV.begin(), biasNamesV.end()};
1202 std::list<std::string> emptyDefaultBias;
1204 for (
auto lv : blm->GetAllLogicalVolumes())
1205 {biasForBLM->AttachTo(lv);}
1206 biasForBLM->AttachTo(blm->GetContainerLogicalVolume());
1212 auto defaultBiasVacuumList = std::list<std::string>(defaultBiasVacuumVector.begin(), defaultBiasVacuumVector.end());
1215 auto defaultBiasMaterialList = std::list<std::string>(defaultBiasMaterialVector.begin(), defaultBiasMaterialVector.end());
1216 G4String biasForWorldVolume = g->BiasForWorldVolume();
1218 auto biasForWorldVolumeList = std::list<std::string>(biasForWorldVolumeVector.begin(), biasForWorldVolumeVector.end());
1219 G4String biasForWorldContents = g->BiasForWorldContents();
1221 auto biasForWorldContentsList = std::list<std::string>(biasForWorldContentsVector.begin(), biasForWorldContentsVector.end());
1222 G4String biasForWorldVacuum = g->BiasForWorldVacuum();
1224 auto biasForWorldVacuumList = std::list<std::string>(biasForWorldVacuumVector.begin(), biasForWorldVacuumVector.end());
1226 G4bool useDefaultBiasVacuum = !defaultBiasVacuum.empty();
1227 G4bool useDefaultBiasMaterial = !defaultBiasMaterial.empty();
1229 G4bool useBiasForWorldVolume = !biasForWorldVolume.
empty();
1230 G4bool useBiasForWorldContents = !biasForWorldContents.empty();
1231 G4bool useBiasForWorldVacuum = !biasForWorldVacuum.empty();
1232 G4bool biasesDefined = !biasObjectList.empty();
1234 G4bool overallUseBiasing = useDefaultBiasVacuum || useDefaultBiasMaterial || biasesDefined || useBiasForWorldVolume || useBiasForWorldContents;
1235 G4cout << __METHOD_NAME__ <<
"Using generic biasing: " << BDS::BoolToString(overallUseBiasing) << G4endl;
1236 if (!overallUseBiasing)
1241 for (
auto const & item : allAcceleratorComponents)
1244 {G4cout << __METHOD_NAME__ <<
"checking component named: " << item.first.componentName << G4endl;}
1249 G4String accName = accCom->
GetName();
1254 if (!vacuumBiasList.empty() && vacuumLVs.empty())
1255 {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.");}
1256 if ((!vacuumBiasList.empty() || useDefaultBiasVacuum) && !vacuumLVs.empty())
1259 for (
auto lv : vacuumLVs)
1262 {G4cout << __METHOD_NAME__ <<
"vacuum volume name: " << lv <<
" " << lv->GetName() << G4endl;}
1263 egVacuum->AttachTo(lv);
1269 if (!materialBiasList.empty() || useDefaultBiasMaterial)
1274 {G4cout << __METHOD_NAME__ <<
"# of logical volumes for biasing under 'material': " << allLVs.size() << G4endl;}
1275 for (
auto lv : allLVs)
1278 {G4cout << __METHOD_NAME__ <<
"Biasing 'material' logical volume: " << lv <<
" " << lv->GetName() << G4endl;}
1279 egMaterial->AttachTo(lv);
1285 if (!nameAndMaterialLVBiasList.empty() || useDefaultBiasMaterial)
1287 std::map<std::string, std::string> namesAndBiasesMap;
1288 for (G4String lvbias : nameAndMaterialLVBiasList)
1290 auto splitpos = lvbias.find(
':');
1291 auto lvname = lvbias.substr(0,splitpos);
1292 auto biasname = lvbias.substr(splitpos+1);
1293 namesAndBiasesMap[lvname] = biasname;
1297 {G4cout << __METHOD_NAME__ <<
"# of logical volumes for biasing under 'materialLV': " << allLVs.size() << G4endl;}
1298 for (
auto lv : allLVs)
1301 {G4cout << __METHOD_NAME__ <<
"Biasing 'materialLV' logical volume: " << lv <<
" " << lv->GetName() << G4endl;}
1302 for (
const auto& nameAndBias : namesAndBiasesMap)
1304 if (lv->GetName().find(nameAndBias.first) != std::string::npos)
1307 egMaterialLV->AttachTo(lv);
1314 if (useBiasForWorldContents)
1316 std::list<std::string> emptyList;
1319 {egWC->AttachTo(lv);}
1321 if (useBiasForWorldVolume)
1323 std::list<std::string> emptyList;
1325 egWV->AttachTo(worldLogicalVolume);
1327 if (useBiasForWorldVacuum)
1329 std::list<std::string> emptyList;
1331 for (
auto lv : worldVacuumLogicalVolumes)
1332 {egWVac->AttachTo(lv);}
1348 while ((*element).type == GMAD::ElementType::_LINE)
1351 if ((*element).type == GMAD::ElementType::_RBEND)
1367 if (scoringMeshes.empty())
1370 G4ScoringManager* scManager = G4ScoringManager::GetScoringManager();
1371 scManager->SetVerboseLevel(1);
1374 std::map<G4String, BDSScorerInfo> scorerRecipes;
1375 for (
const auto& scorer : scorers)
1378 scorerRecipes.insert(std::make_pair(si.
name, si));
1383 for (
const auto& mesh : scoringMeshes)
1389 G4String meshName = meshRecipe.name;
1399 G4String geometryType =
BDS::LowerCase(G4String(mesh.geometryType));
1401 if (geometryType ==
"box")
1404 mapper = scorerBox->Mapper();
1406 else if (geometryType ==
"cylindrical")
1409 mapper = scorerCylindrical->Mapper();
1413 G4String msg =
"mesh geometry type \"" + geometryType +
"\" is not correct. The possible options are \"box\" and \"cylindrical\"";
1418 std::vector<G4String> meshPrimitiveScorerNames;
1419 std::vector<G4double> meshPrimitiveScorerUnits;
1420 std::vector<G4String> scorerNames;
1423 for (
const auto& word : words)
1425 auto search = scorerRecipes.find(word);
1426 if (search == scorerRecipes.end())
1427 {
throw BDSException(__METHOD_NAME__,
"scorerQuantity \"" + word +
"\" for mesh \"" + meshName +
"\" not found.");}
1429 G4double psUnit = 1.0;
1430 G4VPrimitiveScorer* ps = scorerFactory.
CreateScorer(&(search->second), mapper, &psUnit, worldLV);
1435 G4String uniqueName = meshName +
"/" + ps->GetName();
1436 meshPrimitiveScorerNames.push_back(uniqueName);
1437 meshPrimitiveScorerUnits.push_back(psUnit);
1440 if (geometryType ==
"box")
1441 {scorerBox->SetPrimitiveScorer(ps);}
1442 else if (geometryType ==
"cylindrical")
1443 {scorerCylindrical->SetPrimitiveScorer(ps);}
1450 if (geometryType ==
"box")
1451 {scManager->RegisterScoringMesh(scorerBox);}
1452 else if (geometryType ==
"cylindrical")
1453 {scManager->RegisterScoringMesh(scorerCylindrical);}
1464 std::vector<BDSFieldQueryInfo*> result;
1466 for (
const auto& def : parserQueries)
1468 G4bool assumeQueryMagnetic =
false;
1469 if (!def.queryMagneticField && !def.queryElectricField)
1471 assumeQueryMagnetic =
true;
1472 G4cout << __METHOD_NAME__ <<
"neither \"queryMagneticField\" nor \"queryElectricField\" are turned on for definition \""
1473 << def.name <<
"\"" << G4endl;
1474 G4cout <<
"-> querying magnetic field by default" << G4endl;
1477 if (!def.pointsFile.empty())
1479 std::vector<G4String> columnNames;
1482 G4String(def.outfileMagnetic),
1483 G4String(def.outfileElectric),
1484 G4bool(def.queryMagneticField) || assumeQueryMagnetic,
1485 G4bool(def.queryElectricField),
1488 G4bool(def.overwriteExistingFiles),
1489 G4String(def.fieldObject),
1490 def.checkParameters,
1492 def.drawZeroValuePoints,
1499 auto rot = globalTransform3D.getRotation();
1500 rot = rot.inverse();
1501 G4AffineTransform globalTransform(rot, globalTransform3D.getTranslation());
1504 G4String(def.outfileMagnetic),
1505 G4String(def.outfileElectric),
1506 G4bool(def.queryMagneticField) || assumeQueryMagnetic,
1507 G4bool(def.queryElectricField),
1508 {def.nx, def.xmin*CLHEP::m, def.xmax*CLHEP::m},
1509 {def.ny, def.ymin*CLHEP::m, def.ymax*CLHEP::m},
1510 {def.nz, def.zmin*CLHEP::m, def.zmax*CLHEP::m},
1511 {def.nt, def.tmin*CLHEP::ns, def.tmax*CLHEP::ns},
1513 G4bool(def.overwriteExistingFiles),
1514 G4String(def.fieldObject),
1515 G4bool(def.printTransform),
1516 def.checkParameters,
1518 def.drawZeroValuePoints,
1526#ifdef BDSCHECKUSERLIMITS
1527void BDSDetectorConstruction::PrintUserLimitsSummary(
const G4VPhysicalVolume* world)
const
1529 G4cout <<
"USERLIMITS START" << G4endl;
1531 PrintUserLimitsPV(world, globalMinEK);
1532 G4cout <<
"USERLIMITS END" << G4endl;
1535void BDSDetectorConstruction::PrintUserLimitsPV(
const G4VPhysicalVolume* aPV, G4double globalMinEK)
const
1537 const auto lv = aPV->GetLogicalVolume();
1538 const auto ul = lv->GetUserLimits();
1542 G4double ekUL = ul->GetUserMinEkine(dummyTrack);
1544 if (ekUL < globalMinEK)
1545 {G4cout << lv->GetName() <<
" Ek Min: " << ekUL <<
" MeV < global: " << globalMinEK <<
" MeV" << G4endl;}
1548 {G4cout << lv->GetName() <<
" no G4UserLimits" << G4endl;}
1549 for (G4int i = 0; i < (G4int)lv->GetNoDaughters(); i++)
1550 {PrintUserLimitsPV(lv->GetDaughter(i), globalMinEK);}
1556 if (!worldLogicalVolume)
1558 G4cout <<
"\nSensitivity Summary:\n" << G4endl;
1560 G4cout <<
"\n\n" << G4endl;
1565 for (G4int i = 0; i < currentDepth; i++)
1567 G4cout << lv->GetName() <<
" ";
1568 auto sensitiveDetector = lv->GetSensitiveDetector();
1569 if (sensitiveDetector)
1570 {G4cout << sensitiveDetector->GetName();}
1575 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.
static BDSParser * Instance()
Access method.
std::vector< GMAD::Aperture > GetApertures() const
Return the parser list of that object.
const GMAD::Options & GetOptions() const
Return options.
std::vector< GMAD::Query > GetQuery() const
Return the parser list of that object.
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::ScorerMesh > GetScorerMesh() const
Return the parser list of that object.
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.
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)