18#include "BDSAcceleratorModel.hh"
19#include "BDSBeamline.hh"
20#include "BDSBeamlineElement.hh"
21#include "BDSBeamlineIntegral.hh"
22#include "BDSComponentFactory.hh"
23#include "BDSCrystalInfo.hh"
25#include "BDSException.hh"
26#include "BDSExtent.hh"
27#include "BDSExtentGlobal.hh"
28#include "BDSGlobalConstants.hh"
29#include "BDSLinkComponent.hh"
30#include "BDSLinkDetectorConstruction.hh"
31#include "BDSLinkOpaqueBox.hh"
32#include "BDSLinkPrimaryGeneratorAction.hh"
33#include "BDSLinkRegistry.hh"
34#include "BDSMaterials.hh"
35#include "BDSParallelWorldSampler.hh"
36#include "BDSParser.hh"
37#include "BDSSampler.hh"
38#include "BDSSamplerInfo.hh"
39#include "BDSSamplerPlane.hh"
40#include "BDSSamplerRegistry.hh"
41#include "BDSSamplerType.hh"
42#include "BDSSDManager.hh"
43#include "BDSTiltOffset.hh"
45#include "parser/element.h"
46#include "parser/elementtype.h"
49#include "G4PVPlacement.hh"
51#include "G4ThreeVector.hh"
53#include "G4Version.hh"
54#include "G4VisAttributes.hh"
55#if G4VERSION_NUMBER > 1039
56#include "G4ChannelingOptrMultiParticleChangeCrossSection.hh"
67 linkBeamline(nullptr),
68 linkRegistry(nullptr),
69 primaryGeneratorAction(nullptr),
70 designParticle(nullptr),
71#if G4VERSION_NUMBER > 1039
72 crystalBiasing(nullptr),
81BDSLinkDetectorConstruction::~BDSLinkDetectorConstruction()
85#if G4VERSION_NUMBER > 1039
86 delete crystalBiasing;
91G4VPhysicalVolume* BDSLinkDetectorConstruction::Construct()
95 auto componentFactory = std::unique_ptr<BDSComponentFactory>(
new BDSComponentFactory(
nullptr,
false));
98 std::vector<BDSLinkOpaqueBox*> opaqueBoxes = {};
101 auto acceleratorModel = BDSAcceleratorModel::Instance();
105 {
throw BDSException(__METHOD_NAME__,
"designParticle must be set first");}
108 for (
const auto& element : beamline)
112 if (eType == GMAD::ElementType::_LINE || eType == GMAD::ElementType::_REV_LINE)
115 std::set<GMAD::ElementType> acceptedTypes = {GMAD::ElementType::_ECOL,
116 GMAD::ElementType::_RCOL,
117 GMAD::ElementType::_BMCOL,
118 GMAD::ElementType::_JCOL,
119 GMAD::ElementType::_CRYSTALCOL,
120 GMAD::ElementType::_ELEMENT};
121 auto search = acceptedTypes.find(eType);
122 if (search == acceptedTypes.end())
132 element.offsetY * CLHEP::m,
133 element.tilt * CLHEP::rad);
139 opaqueBoxes.push_back(opaqueBox);
144 acceleratorModel->RegisterLinkComponent(comp);
152 G4LogicalVolume* worldLV =
new G4LogicalVolume(worldSolid,
157 debugWorldVis->SetForceWireframe(
true);
158 worldLV->SetVisAttributes(debugWorldVis);
159 worldLV->SetUserLimits(globalConstants->DefaultUserLimits());
161 worldPV =
new G4PVPlacement(
nullptr,
171 for (
auto element : *linkBeamline)
175 G4String samplerName = samplerInfo ? samplerInfo->name :
"unknown";
176 G4String name = lc ? lc->
LinkName() : samplerName;
185 const std::string& materialName,
187 G4double halfApertureLeft,
188 G4double halfApertureRight,
192 G4double jawTiltLeft,
193 G4double jawTiltright,
195 G4bool buildRightJaw,
197 G4double crystalAngle,
200 auto componentFactory = std::unique_ptr<BDSComponentFactory>(
new BDSComponentFactory(
nullptr,
false));
205 {
throw BDSException(__METHOD_NAME__,
"designParticle must be set first");}
210 std::map<std::string, std::string> collimatorToCrystal =
212 {
"cry.mio.b1",
"stf75"},
213 {
"cry.mio.b2",
"tcp76"},
214 {
"tcpv.a6l7.b1",
"qmp34"},
215 {
"tcpv.a6r7.b2",
"qmp53"},
216 {
"tcpch.a4l7.b1",
"stf75"},
217 {
"tcpcv.a6l7.b1",
"tcp76"}
220 auto searchC = collimatorToCrystal.find(collimatorLower);
221 G4bool isACrystal = searchC != collimatorToCrystal.end();
222 if (!isACrystal && isACrystalIn)
223 {
throw BDSException(
"BDSLinkDetectorConstruction",
"no matching crystal name found but it is flagged as a crystal in input");}
226 {G4cout <<
"crystal name " << searchC->first <<
" " << searchC->second << G4endl;}
228 std::map<std::string, std::string> sixtrackToBDSIM =
232 {
"C",
"G4_GRAPHITE_POROUS"},
236 std::string g4material;
237 auto search = sixtrackToBDSIM.find(materialName);
238 if (search != sixtrackToBDSIM.end())
239 {g4material = search->second;}
241 {g4material = materialName;}
245 el.
type = GMAD::ElementType::_JCOL;
246 el.name = collimatorName;
247 el.material = g4material;
248 el.
l = length / CLHEP::m;
249 el.xsizeLeft = halfApertureLeft / CLHEP::m;
252 el.
tilt = rotation / CLHEP::rad;
253 el.
offsetX = xOffset / CLHEP::m;
254 el.
offsetY = yOffset / CLHEP::m;
255 el.horizontalWidth = 2.0;
256 el.jawTiltLeft = jawTiltLeft;
261 {el.xsizeLeft = el.horizontalWidth * 1.2;}
269 G4String crystalNameC = searchC->second;
270 G4cout <<
"crystal name " << crystalNameC << G4endl;
271 BDSCrystalInfo* ci = componentFactory->PrepareCrystalInfo(crystalNameC);
272 crystalAngle *= CLHEP::rad;
275 el.xsize = el.xsizeLeft;
277 el.
type = GMAD::ElementType::_CRYSTALCOL;
282 if (collimatorName.find(
'2') != std::string::npos)
284 el.crystalLeft = crystalNameC;
289 el.crystalRight = crystalNameC;
293 G4cout <<
"Crystal angle " << crystalAngle << G4endl;
294 G4cout <<
"xsizeLeft " << el.xsizeLeft << G4endl;
295 G4cout <<
"xsizeRight " << el.
xsizeRight << G4endl;
296 G4cout <<
"l crystal angle " << el.crystalAngleYAxisLeft << G4endl;
297 G4cout <<
"r crystal angle " << el.crystalAngleYAxisRight << G4endl;
298 G4cout <<
"rotation (tilt) " << el.
tilt << G4endl;
306 {component = componentFactory->CreateComponent(&el,
nullptr,
nullptr, *integral);}
309 G4cout << e.
what() << G4endl;
310 G4cout <<
"Replacing component " << el.name <<
" with drift" << G4endl;
312 el.
type = GMAD::ElementType::_DRIFT;
314 component = componentFactory->CreateComponent(&el,
nullptr,
nullptr, *integral);
320 el.
tilt * CLHEP::rad);
329 BDSAcceleratorModel::Instance()->RegisterLinkComponent(comp);
348 const std::string& materialName,
349 const std::string& tipMaterialName,
350 G4double tipThickness,
352 G4double halfApertureLeft,
353 G4double halfApertureRight,
357 G4double jawTiltLeft,
358 G4double jawTiltRight,
360 G4bool buildRightJaw)
362 auto componentFactory = std::unique_ptr<BDSComponentFactory>(
new BDSComponentFactory(
nullptr,
false));
368 throw BDSException(__METHOD_NAME__,
"designParticle must be set first");
373 std::string g4material = materialName;
374 std::string g4tipMaterial = tipMaterialName;
378 el.
type = GMAD::ElementType::_JCOLTIP;
379 el.name = collimatorName;
380 el.material = g4material;
382 el.
l = length / CLHEP::m;
383 el.xsizeLeft = halfApertureLeft / CLHEP::m;
386 el.
tilt = rotation / CLHEP::rad;
387 el.
offsetX = xOffset / CLHEP::m;
388 el.
offsetY = yOffset / CLHEP::m;
389 el.horizontalWidth = 2.0;
390 el.jawTiltLeft = jawTiltLeft;
396 el.xsizeLeft = el.horizontalWidth * 1.2;
409 component = componentFactory->CreateComponent(&el,
nullptr,
nullptr, *integral);
413 G4cout << e.
what() << G4endl;
414 G4cout <<
"Replacing component " << el.name <<
" with drift" << G4endl;
415 el.
type = GMAD::ElementType::_DRIFT;
417 component = componentFactory->CreateComponent(&el,
nullptr,
nullptr, *integral);
428 BDSAcceleratorModel::Instance()->RegisterLinkComponent(comp);
444 auto componentFactory = std::unique_ptr<BDSComponentFactory>(
new BDSComponentFactory(
nullptr,
false));
450 throw BDSException(__METHOD_NAME__,
"designParticle must be set first");
459 component = componentFactory->CreateComponent(&el,
nullptr,
nullptr, *integral);
463 G4cout << e.
what() << G4endl;
464 G4cout <<
"Replacing component " << el.name <<
" with drift" << G4endl;
465 el.
type = GMAD::ElementType::_DRIFT;
467 component = componentFactory->CreateComponent(&el,
nullptr,
nullptr, *integral);
478 BDSAcceleratorModel::Instance()->RegisterLinkComponent(comp);
498 worldExtentAbs *= 1.2;
502 worldSolid =
new G4Box(
"world_solid",
509 worldSolid->SetXHalfLength(worldExtentAbs.x());
510 worldSolid->SetYHalfLength(worldExtentAbs.y());
511 worldSolid->SetZHalfLength(worldExtentAbs.z());
514 if (primaryGeneratorAction)
519 const G4String& originalName)
523 std::set<G4VPhysicalVolume*> pvs = element->
PlaceElement(placementName, worldPV,
false, copyNumber,
true);
530 G4Transform3D elCentreToStart = el->TransformToStart();
531 G4Transform3D globalToStart = elCentreToStart * (*placementTransform);
532 G4int linkID = linkRegistry->Register(el, globalToStart);
535 G4Transform3D samplerPosition = globalToStart * G4Transform3D(G4RotationMatrix(), globalToStart.getRotation()*zOffset);
545 G4String samplerName = originalName +
"_in";
550 G4LogicalVolume* samplerWorldLV = samplerWorld->WorldLV();
551 new G4PVPlacement(samplerPosition,
562void BDSLinkDetectorConstruction::BuildPhysicsBias()
564#if G4VERSION_NUMBER > 1039
566 {crystalBiasing =
new G4ChannelingOptrMultiParticleChangeCrossSection();}
569 std::set<G4LogicalVolume*>* crystals = BDSAcceleratorModel::Instance()->
VolumeSet(
"crystals");
570 if (!crystals->empty())
572 G4cout << __METHOD_NAME__ <<
"Using crystal biasing: true" << G4endl;
573 for (
auto crystal : *crystals)
576 if (!crystalBiasing->GetBiasingOperator(crystal))
577 {crystalBiasing->AttachTo(crystal);}
Abstract class that represents a component of an accelerator.
virtual G4String GetName() const
The name of the component without modification.
std::set< G4LogicalVolume * > * VolumeSet(const G4String &name)
Returns pointer to a set of logical volumes. If no set by that name exits, create it.
A class that holds a fully constructed BDSAcceleratorComponent as well as any information relevant to...
BDSSamplerType GetSamplerType() const
Accessor.
std::set< G4VPhysicalVolume * > PlaceElement(const G4String &pvName, G4VPhysicalVolume *containerPV, G4bool useCLPlacementTransform, G4int copyNumber, G4bool checkOverlaps) const
G4String GetPlacementName() const
Accessor.
G4Transform3D * GetPlacementTransform() const
Accessor.
BDSAcceleratorComponent * GetAcceleratorComponent() const
Accessor.
G4int GetCopyNo() const
Accessor.
G4double GetSPositionStart() const
Accessor.
A class that holds the current integrated quantities along a beam line.
A vector of BDSBeamlineElement instances - a beamline.
BDSBeamlineElement * back() const
Return a reference to the last element.
BeamlineVector::size_type size() const
Get the number of elements.
void AddComponent(BDSAcceleratorComponent *component, BDSTiltOffset *tiltOffset=nullptr, BDSSamplerInfo *samplerInfo=nullptr, const BDSBeamlineIntegral *beamlineIntegral=nullptr)
BDSExtentGlobal GetExtentGlobal() const
Get the global extents for this beamline.
Factory to produce all types of BDSAcceleratorComponents.
Holder for all information required to create a crystal.
G4double bendingAngleYAxis
Bending angle about Y axis.
General exception with possible name of object and message.
const char * what() const noexcept override
Override message in std::exception.
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.
G4ThreeVector GetMaximumExtentAbsolute() const
Get the maximum extent absolute in each dimension.
Holder for +- extents in 3 dimensions.
G4double DZ() const
The difference in a dimension.
BDSExtent TiltOffset(const BDSTiltOffset *tiltOffset) const
Provide a new copy of this extent with both a tilt and an offset applied.
G4double TransverseBoundingRadius() const
Return a radius that would encompass the maximum x,y extent.
G4LogicalVolume * GetContainerLogicalVolume() const
Accessor - see member for more info.
BDSExtent GetExtent() const
Accessor - see member for more info.
virtual G4String GetName() const
Accessor - see member for more info.
A class that holds global options and constants.
static BDSGlobalConstants * Instance()
Access method.
A BDSAcceleratorComponent wrapper for BDSLinkOpaqueBox.
BDSLinkOpaqueBox * Component() const
Accessor.
G4String LinkName() const
Accessor.
G4int AddLinkCollimatorTipJaw(const std::string &collimatorName, const std::string &materialName, const std::string &tipMaterialName, G4double tipThickness, G4double length, G4double halfApertureLeft, G4double halfApertureRight, G4double rotation, G4double xOffset, G4double yOffset, G4double jawTiltLeft=0.0, G4double jawTiltRight=0.0, G4bool buildLeftJaw=true, G4bool buildRightJaw=true)
Interface to append a tip collimator jaw to the linking.
G4int AddLinkCollimatorJaw(const std::string &collimatorName, const std::string &materialName, G4double length, G4double halfApertureLeft, G4double halfApertureRight, G4double rotation, G4double xOffset, G4double yOffset, G4double jawTiltLeft=0.0, G4double jawTiltRight=0.0, G4bool buildLeftJaw=true, G4bool buildRightJaw=true, G4bool isACrystal=false, G4double crystalAngle=0, G4bool sampleIn=false)
Interface to append a collimator of jaw style to the linking.
G4int AddLinkElement(GMAD::Element el)
Interface to append an element.
G4int samplerWorldID
Cache of the index to which parallel world the sampler one is.
G4int PlaceOneComponent(const BDSBeamlineElement *element, const G4String &originalName)
Place a beam line element in the world.
const BDSParticleDefinition * designParticle
Particle definition all components are built w.r.t. Includes rigidity etc.
BDSLinkDetectorConstruction()
Default constructor.
std::map< std::string, G4int > nameToElementIndex
Build up a copy here too.
std::map< G4int, G4int > linkIDToBeamlineIndex
Special linkID to linkBeamline index.
Wrapper box for an accelerator component.
void SetWorldExtent(const BDSExtent worldExtentIn)
Set the world extent that particle coordinates will be checked against.
Registry / map of components for tracker linkage.
static BDSMaterials * Instance()
Singleton pattern access.
A parallel world for sampler planes.
static BDSParser * Instance()
Access method.
Wrapper for particle definition.
void SetLinkRegistry(BDSLinkRegistry *registry)
If samplerLink member exists, set the registry to look up links for that SD.
All info required to build a sampler but not place it.
Rectangular sampler with fixed thickness but variable x,y.
static G4double ChordLength()
Access the sampler plane length in other classes.
static BDSSamplerRegistry * Instance()
Accessor for registry.
G4int RegisterSampler(const G4String &name, BDSSampler *sampler, const G4Transform3D &transform=G4Transform3D(), G4double S=-1000, const BDSBeamlineElement *element=nullptr, BDSSamplerType type=BDSSamplerType::plane, G4double radius=0)
A holder for any placement offsets and rotations for a BDSAcceleratorComponent.
const FastList< Element > & GetBeamline() const
G4String LowerCase(const G4String &str)
Utility function to simplify lots of syntax changes for pedantic g4 changes.
ElementType
types of elements
std::string typestr(ElementType type)
conversion from enum to string
std::string tipMaterial
tip material
double aper1
beampipe information, new aperture model
double xsizeRight
individual collimator jaw half widths
double jawTiltRight
jaw collimator jaw tilts (angle in x-z plane)
std::string region
region with range cuts
double ysize
collimator aperture or laser spotsize for laser
double tipThickness
for jaw collimator with tip
ElementType type
element enum
std::string apertureType
beampipe information, new aperture model