19#include "BDSAcceleratorModel.hh"
20#include "BDSBeamline.hh"
21#include "BDSBeamlineElement.hh"
22#include "BDSBeamlineIntegral.hh"
23#include "BDSCollimatorJaw.hh"
24#include "BDSCollimatorTipJaw.hh"
25#include "BDSComponentFactory.hh"
26#include "BDSCrystalInfo.hh"
28#include "BDSException.hh"
29#include "BDSExtent.hh"
30#include "BDSExtentGlobal.hh"
31#include "BDSGlobalConstants.hh"
32#include "BDSLinkComponent.hh"
33#include "BDSLinkDetectorConstruction.hh"
34#include "BDSLinkOpaqueBox.hh"
35#include "BDSLinkPrimaryGeneratorAction.hh"
36#include "BDSLinkRegistry.hh"
37#include "BDSMaterials.hh"
38#include "BDSParallelWorldSampler.hh"
39#include "BDSParser.hh"
40#include "BDSSampler.hh"
41#include "BDSSamplerInfo.hh"
42#include "BDSSamplerPlane.hh"
43#include "BDSSamplerRegistry.hh"
44#include "BDSSamplerType.hh"
45#include "BDSSDManager.hh"
46#include "BDSTiltOffset.hh"
48#include "parser/element.h"
49#include "parser/elementtype.h"
52#include "G4PVPlacement.hh"
54#include "G4ThreeVector.hh"
56#include "G4Version.hh"
57#include "G4VisAttributes.hh"
58#if G4VERSION_NUMBER > 1039
59#include "G4ChannelingOptrMultiParticleChangeCrossSection.hh"
70 linkBeamline(nullptr),
71 linkRegistry(nullptr),
72 primaryGeneratorAction(nullptr),
73 designParticle(nullptr),
74#if G4VERSION_NUMBER > 1039
75 crystalBiasing(nullptr),
84BDSLinkDetectorConstruction::~BDSLinkDetectorConstruction()
88#if G4VERSION_NUMBER > 1039
89 delete crystalBiasing;
94G4VPhysicalVolume* BDSLinkDetectorConstruction::Construct()
98 auto componentFactory = std::unique_ptr<BDSComponentFactory>(
new BDSComponentFactory(
nullptr,
false));
101 std::vector<BDSLinkOpaqueBox*> opaqueBoxes = {};
104 auto acceleratorModel = BDSAcceleratorModel::Instance();
108 {
throw BDSException(__METHOD_NAME__,
"designParticle must be set first");}
111 for (
const auto& element : beamline)
115 if (eType == GMAD::ElementType::_LINE || eType == GMAD::ElementType::_REV_LINE)
118 std::set<GMAD::ElementType> acceptedTypes = {GMAD::ElementType::_ECOL,
119 GMAD::ElementType::_RCOL,
120 GMAD::ElementType::_BMCOL,
121 GMAD::ElementType::_JCOL,
122 GMAD::ElementType::_CRYSTALCOL,
123 GMAD::ElementType::_ELEMENT};
124 auto search = acceptedTypes.find(eType);
125 if (search == acceptedTypes.end())
135 element.offsetY * CLHEP::m,
136 element.tilt * CLHEP::rad);
142 opaqueBoxes.push_back(opaqueBox);
147 acceleratorModel->RegisterLinkComponent(comp);
155 G4LogicalVolume* worldLV =
new G4LogicalVolume(worldSolid,
160 debugWorldVis->SetForceWireframe(
true);
161 worldLV->SetVisAttributes(debugWorldVis);
162 worldLV->SetUserLimits(globalConstants->DefaultUserLimits());
164 worldPV =
new G4PVPlacement(
nullptr,
174 for (
auto element : *linkBeamline)
178 G4String samplerName = samplerInfo ? samplerInfo->name :
"unknown";
179 G4String name = lc ? lc->
LinkName() : samplerName;
188 const std::string& materialName,
190 G4double halfApertureLeft,
191 G4double halfApertureRight,
195 G4double jawTiltLeft,
196 G4double jawTiltright,
198 G4bool buildRightJaw,
200 G4double crystalAngle,
203 auto componentFactory = std::unique_ptr<BDSComponentFactory>(
new BDSComponentFactory(
nullptr,
false));
208 {
throw BDSException(__METHOD_NAME__,
"designParticle must be set first");}
213 std::map<std::string, std::string> collimatorToCrystal =
215 {
"cry.mio.b1",
"stf75"},
216 {
"cry.mio.b2",
"tcp76"},
217 {
"tcpv.a6l7.b1",
"qmp34"},
218 {
"tcpv.a6r7.b2",
"qmp53"},
219 {
"tcpch.a4l7.b1",
"stf75"},
220 {
"tcpcv.a6l7.b1",
"tcp76"}
223 auto searchC = collimatorToCrystal.find(collimatorLower);
224 G4bool isACrystal = searchC != collimatorToCrystal.end();
225 if (!isACrystal && isACrystalIn)
226 {
throw BDSException(
"BDSLinkDetectorConstruction",
"no matching crystal name found but it is flagged as a crystal in input");}
229 {G4cout <<
"crystal name " << searchC->first <<
" " << searchC->second << G4endl;}
231 std::map<std::string, std::string> sixtrackToBDSIM =
235 {
"C",
"G4_GRAPHITE_POROUS"},
239 std::string g4material;
240 auto search = sixtrackToBDSIM.find(materialName);
241 if (search != sixtrackToBDSIM.end())
242 {g4material = search->second;}
244 {g4material = materialName;}
248 el.
type = GMAD::ElementType::_JCOL;
249 el.name = collimatorName;
250 el.material = g4material;
251 el.
l = length / CLHEP::m;
252 el.xsizeLeft = halfApertureLeft / CLHEP::m;
255 el.
tilt = rotation / CLHEP::rad;
256 el.
offsetX = xOffset / CLHEP::m;
257 el.
offsetY = yOffset / CLHEP::m;
258 el.horizontalWidth = 2.0;
259 el.jawTiltLeft = jawTiltLeft;
264 {el.xsizeLeft = el.horizontalWidth * 1.2;}
272 G4String crystalNameC = searchC->second;
273 G4cout <<
"crystal name " << crystalNameC << G4endl;
274 BDSCrystalInfo* ci = componentFactory->PrepareCrystalInfo(crystalNameC);
275 crystalAngle *= CLHEP::rad;
278 el.xsize = el.xsizeLeft;
280 el.
type = GMAD::ElementType::_CRYSTALCOL;
285 if (collimatorName.find(
'2') != std::string::npos)
287 el.crystalLeft = crystalNameC;
292 el.crystalRight = crystalNameC;
296 G4cout <<
"Crystal angle " << crystalAngle << G4endl;
297 G4cout <<
"xsizeLeft " << el.xsizeLeft << G4endl;
298 G4cout <<
"xsizeRight " << el.
xsizeRight << G4endl;
299 G4cout <<
"l crystal angle " << el.crystalAngleYAxisLeft << G4endl;
300 G4cout <<
"r crystal angle " << el.crystalAngleYAxisRight << G4endl;
301 G4cout <<
"rotation (tilt) " << el.
tilt << G4endl;
309 {component = componentFactory->CreateComponent(&el,
nullptr,
nullptr, *integral);}
312 G4cout << e.
what() << G4endl;
313 G4cout <<
"Replacing component " << el.name <<
" with drift" << G4endl;
315 el.
type = GMAD::ElementType::_DRIFT;
317 component = componentFactory->CreateComponent(&el,
nullptr,
nullptr, *integral);
323 el.
tilt * CLHEP::rad);
332 BDSAcceleratorModel::Instance()->RegisterLinkComponent(comp);
351 const std::string& materialName,
352 const std::string& tipMaterialName,
353 G4double tipThickness,
355 G4double halfApertureLeft,
356 G4double halfApertureRight,
360 G4double jawTiltLeft,
361 G4double jawTiltRight,
363 G4bool buildRightJaw)
365 auto componentFactory = std::unique_ptr<BDSComponentFactory>(
new BDSComponentFactory(
nullptr,
false));
371 throw BDSException(__METHOD_NAME__,
"designParticle must be set first");
376 std::string g4material = materialName;
377 std::string g4tipMaterial = tipMaterialName;
381 el.
type = GMAD::ElementType::_JCOLTIP;
382 el.name = collimatorName;
383 el.material = g4material;
385 el.
l = length / CLHEP::m;
386 el.xsizeLeft = halfApertureLeft / CLHEP::m;
389 el.
tilt = rotation / CLHEP::rad;
390 el.
offsetX = xOffset / CLHEP::m;
391 el.
offsetY = yOffset / CLHEP::m;
392 el.horizontalWidth = 2.0;
393 el.jawTiltLeft = jawTiltLeft;
399 el.xsizeLeft = el.horizontalWidth * 1.2;
412 component = componentFactory->CreateComponent(&el,
nullptr,
nullptr, *integral);
416 G4cout << e.
what() << G4endl;
417 G4cout <<
"Replacing component " << el.name <<
" with drift" << G4endl;
418 el.
type = GMAD::ElementType::_DRIFT;
420 component = componentFactory->CreateComponent(&el,
nullptr,
nullptr, *integral);
431 BDSAcceleratorModel::Instance()->RegisterLinkComponent(comp);
447 auto componentFactory = std::unique_ptr<BDSComponentFactory>(
new BDSComponentFactory(
nullptr,
false));
453 throw BDSException(__METHOD_NAME__,
"designParticle must be set first");
462 component = componentFactory->CreateComponent(&el,
nullptr,
nullptr, *integral);
466 G4cout << e.
what() << G4endl;
467 G4cout <<
"Replacing component " << el.name <<
" with drift" << G4endl;
468 el.
type = GMAD::ElementType::_DRIFT;
470 component = componentFactory->CreateComponent(&el,
nullptr,
nullptr, *integral);
481 BDSAcceleratorModel::Instance()->RegisterLinkComponent(comp);
501 worldExtentAbs *= 1.2;
505 worldSolid =
new G4Box(
"world_solid",
512 worldSolid->SetXHalfLength(worldExtentAbs.x());
513 worldSolid->SetYHalfLength(worldExtentAbs.y());
514 worldSolid->SetZHalfLength(worldExtentAbs.z());
517 if (primaryGeneratorAction)
522 const G4String& originalName)
526 std::set<G4VPhysicalVolume*> pvs = element->
PlaceElement(placementName, worldPV,
false, copyNumber,
true);
533 G4Transform3D elCentreToStart = el->TransformToStart();
534 G4Transform3D globalToStart = elCentreToStart * (*placementTransform);
535 G4int linkID = linkRegistry->Register(el, globalToStart);
538 G4Transform3D samplerPosition = globalToStart * G4Transform3D(G4RotationMatrix(), globalToStart.getRotation()*zOffset);
548 G4String samplerName = originalName +
"_in";
553 G4LogicalVolume* samplerWorldLV = samplerWorld->WorldLV();
554 new G4PVPlacement(samplerPosition,
565void BDSLinkDetectorConstruction::BuildPhysicsBias()
567#if G4VERSION_NUMBER > 1039
569 {crystalBiasing =
new G4ChannelingOptrMultiParticleChangeCrossSection();}
572 std::set<G4LogicalVolume*>* crystals = BDSAcceleratorModel::Instance()->
VolumeSet(
"crystals");
573 if (!crystals->empty())
575 G4cout << __METHOD_NAME__ <<
"Using crystal biasing: true" << G4endl;
576 for (
auto crystal : *crystals)
579 if (!crystalBiasing->GetBiasingOperator(crystal))
580 {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