19#include "BDSAcceleratorModel.hh"
20#include "BDSBeamline.hh"
21#include "BDSBeamlineElement.hh"
22#include "BDSCollimatorJaw.hh"
23#include "BDSComponentFactory.hh"
24#include "BDSCrystalInfo.hh"
26#include "BDSException.hh"
27#include "BDSExtent.hh"
28#include "BDSExtentGlobal.hh"
29#include "BDSGlobalConstants.hh"
30#include "BDSLinkComponent.hh"
31#include "BDSLinkDetectorConstruction.hh"
32#include "BDSLinkOpaqueBox.hh"
33#include "BDSLinkPrimaryGeneratorAction.hh"
34#include "BDSLinkRegistry.hh"
35#include "BDSMaterials.hh"
36#include "BDSParallelWorldSampler.hh"
37#include "BDSParser.hh"
38#include "BDSSampler.hh"
39#include "BDSSamplerInfo.hh"
40#include "BDSSamplerPlane.hh"
41#include "BDSSamplerRegistry.hh"
42#include "BDSSamplerType.hh"
43#include "BDSSDManager.hh"
44#include "BDSTiltOffset.hh"
46#include "parser/element.h"
47#include "parser/elementtype.h"
50#include "G4PVPlacement.hh"
52#include "G4ThreeVector.hh"
54#include "G4Version.hh"
55#include "G4VisAttributes.hh"
56#if G4VERSION_NUMBER > 1039
57#include "G4ChannelingOptrMultiParticleChangeCrossSection.hh"
68 linkBeamline(nullptr),
69 linkRegistry(nullptr),
70 primaryGeneratorAction(nullptr),
71 designParticle(nullptr),
72#if G4VERSION_NUMBER > 1039
73 crystalBiasing(nullptr),
81BDSLinkDetectorConstruction::~BDSLinkDetectorConstruction()
85#if G4VERSION_NUMBER > 1039
86 delete crystalBiasing;
90G4VPhysicalVolume* BDSLinkDetectorConstruction::Construct()
97 std::vector<BDSLinkOpaqueBox*> opaqueBoxes = {};
100 auto acceleratorModel = BDSAcceleratorModel::Instance();
102 for (
const auto& element : beamline)
106 if (eType == GMAD::ElementType::_LINE || eType == GMAD::ElementType::_REV_LINE)
109 std::set<GMAD::ElementType> acceptedTypes = {GMAD::ElementType::_ECOL,
110 GMAD::ElementType::_RCOL,
111 GMAD::ElementType::_JCOL,
112 GMAD::ElementType::_CRYSTALCOL,
113 GMAD::ElementType::_ELEMENT};
114 auto search = acceptedTypes.find(eType);
115 if (search == acceptedTypes.end())
125 element.offsetY * CLHEP::m,
126 element.tilt * CLHEP::rad);
132 opaqueBoxes.push_back(opaqueBox);
137 acceleratorModel->RegisterLinkComponent(comp);
145 G4LogicalVolume* worldLV =
new G4LogicalVolume(worldSolid,
150 debugWorldVis->SetForceWireframe(
true);
151 worldLV->SetVisAttributes(debugWorldVis);
152 worldLV->SetUserLimits(globalConstants->DefaultUserLimits());
154 worldPV =
new G4PVPlacement(
nullptr,
164 for (
auto element : *linkBeamline)
168 G4String samplerName = samplerInfo ? samplerInfo->name :
"unknown";
169 G4String name = lc ? lc->
LinkName() : samplerName;
174 delete componentFactory;
180 const std::string& materialName,
182 G4double halfApertureLeft,
183 G4double halfApertureRight,
187 G4double jawTiltLeft,
188 G4double jawTiltright,
190 G4bool buildRightJaw,
192 G4double crystalAngle,
197 std::map<std::string, std::string> collimatorToCrystal =
199 {
"cry.mio.b1",
"stf75"},
200 {
"cry.mio.b2",
"tcp76"},
201 {
"tcpv.a6l7.b1",
"qmp34"},
202 {
"tcpv.a6r7.b2",
"qmp53"},
203 {
"tcpch.a4l7.b1",
"stf75"},
204 {
"tcpcv.a6l7.b1",
"tcp76"}
207 auto searchC = collimatorToCrystal.find(collimatorLower);
208 G4bool isACrystal = searchC != collimatorToCrystal.end();
209 if (!isACrystal && isACrystalIn)
210 {
throw BDSException(
"BDSLinkDetectorConstruction",
"no matching crystal name found but it is flagged as a crystal in input");}
211 G4cout <<
"XYZ isACrystal " << isACrystal << G4endl;
213 {G4cout <<
"crystal name " << searchC->first <<
" " << searchC->second << G4endl;}
215 std::map<std::string, std::string> sixtrackToBDSIM =
219 {
"C",
"G4_GRAPHITE_POROUS"},
223 std::string g4material;
224 auto search = sixtrackToBDSIM.find(materialName);
225 if (search != sixtrackToBDSIM.end())
226 {g4material = search->second;}
228 {g4material = materialName;}
232 el.
type = GMAD::ElementType::_JCOL;
233 el.name = collimatorName;
234 el.material = g4material;
235 el.
l = length / CLHEP::m;
236 el.xsizeLeft = halfApertureLeft / CLHEP::m;
239 el.
tilt = rotation / CLHEP::rad;
240 el.
offsetX = xOffset / CLHEP::m;
241 el.
offsetY = yOffset / CLHEP::m;
242 el.horizontalWidth = 2.0;
243 el.jawTiltLeft = jawTiltLeft;
248 {el.xsizeLeft = el.horizontalWidth * 1.2;}
256 G4String crystalNameC = searchC->second;
257 G4cout <<
"crystal name " << crystalNameC << G4endl;
258 BDSCrystalInfo* ci = componentFactory->PrepareCrystalInfo(crystalNameC);
259 crystalAngle *= CLHEP::rad;
262 el.xsize = el.xsizeLeft;
264 el.
type = GMAD::ElementType::_CRYSTALCOL;
269 if (collimatorName.find(
'2') != std::string::npos)
271 el.crystalLeft = crystalNameC;
276 el.crystalRight = crystalNameC;
280 G4cout <<
"XYZKEY Crystal angle " << crystalAngle << G4endl;
281 G4cout <<
"xsizeLeft " << el.xsizeLeft << G4endl;
282 G4cout <<
"xsizeRight " << el.
xsizeRight << G4endl;
283 G4cout <<
"l crystal angle " << el.crystalAngleYAxisLeft << G4endl;
284 G4cout <<
"r crystal angle " << el.crystalAngleYAxisRight << G4endl;
285 G4cout <<
"rotation (tilt) " << el.
tilt << G4endl;
293 {component = componentFactory->CreateComponent(&el,
nullptr,
nullptr, 0);}
296 G4cout << e.
what() << G4endl;
297 G4cout <<
"Replacing component " << el.name <<
" with drift" << G4endl;
299 el.
type = GMAD::ElementType::_DRIFT;
301 component = componentFactory->CreateComponent(&el,
nullptr,
nullptr, 0);
307 el.
tilt * CLHEP::rad);
316 BDSAcceleratorModel::Instance()->RegisterLinkComponent(comp);
318 linkBeamline->AddComponent(comp,
nullptr, samplerInfo);
339 worldExtentAbs *= 1.2;
343 worldSolid =
new G4Box(
"world_solid",
350 worldSolid->SetXHalfLength(worldExtentAbs.x());
351 worldSolid->SetYHalfLength(worldExtentAbs.y());
352 worldSolid->SetZHalfLength(worldExtentAbs.z());
355 if (primaryGeneratorAction)
360 const G4String& originalName)
364 std::set<G4VPhysicalVolume*> pvs = element->
PlaceElement(placementName, worldPV,
false, copyNumber,
true);
371 G4Transform3D elCentreToStart = el->TransformToStart();
372 G4Transform3D globalToStart = elCentreToStart * (*placementTransform);
373 G4int linkID = linkRegistry->Register(el, globalToStart);
376 G4Transform3D samplerPosition = globalToStart * G4Transform3D(G4RotationMatrix(), globalToStart.getRotation()*zOffset);
386 G4String samplerName = originalName +
"_in";
391 G4LogicalVolume* samplerWorldLV = samplerWorld->WorldLV();
392 new G4PVPlacement(samplerPosition,
403void BDSLinkDetectorConstruction::BuildPhysicsBias()
405#if G4VERSION_NUMBER > 1039
407 {crystalBiasing =
new G4ChannelingOptrMultiParticleChangeCrossSection();}
410 std::set<G4LogicalVolume*>* crystals = BDSAcceleratorModel::Instance()->
VolumeSet(
"crystals");
411 if (!crystals->empty())
413 G4cout << __METHOD_NAME__ <<
"Using crystal biasing: true" << G4endl;
414 for (
auto crystal : *crystals)
417 if (!crystalBiasing->GetBiasingOperator(crystal))
418 {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 vector of BDSBeamlineElement instances - a beamline.
BeamlineVector::size_type size() const
Get the number of elements.
void AddComponent(BDSAcceleratorComponent *component, BDSTiltOffset *tiltOffset=nullptr, BDSSamplerInfo *samplerInfo=nullptr)
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 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 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
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
ElementType type
element enum
std::string apertureType
beampipe information, new aperture model