BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSLinkDetectorConstruction.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) BDSIM Collaboration, 2001 - 2026.
3
4This file is part of BDSIM.
5
6BDSIM is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published
8by the Free Software Foundation version 3 of the License.
9
10BDSIM is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
17*/
18#include "BDSAcceleratorModel.hh"
19#include "BDSBeamline.hh"
20#include "BDSBeamlineElement.hh"
21#include "BDSBeamlineIntegral.hh"
22#include "BDSComponentFactory.hh"
23#include "BDSCrystalInfo.hh"
24#include "BDSDebug.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"
44
45#include "parser/element.h"
46#include "parser/elementtype.h"
47
48#include "G4Box.hh"
49#include "G4PVPlacement.hh"
50#include "G4String.hh"
51#include "G4ThreeVector.hh"
52#include "G4Types.hh"
53#include "G4Version.hh"
54#include "G4VisAttributes.hh"
55#if G4VERSION_NUMBER > 1039
56#include "G4ChannelingOptrMultiParticleChangeCrossSection.hh"
57#endif
58
59#include <set>
60#include <vector>
61
63
65 worldSolid(nullptr),
66 worldPV(nullptr),
67 linkBeamline(nullptr),
68 linkRegistry(nullptr),
69 primaryGeneratorAction(nullptr),
70 designParticle(nullptr),
71#if G4VERSION_NUMBER > 1039
72 crystalBiasing(nullptr),
73#endif
74 samplerWorldID(-1),
75 integral(nullptr)
76{
77 linkRegistry = new BDSLinkRegistry();
78 BDSSDManager::Instance()->SetLinkRegistry(linkRegistry);
79}
80
81BDSLinkDetectorConstruction::~BDSLinkDetectorConstruction()
82{
83 delete linkBeamline;
84 delete linkRegistry;
85#if G4VERSION_NUMBER > 1039
86 delete crystalBiasing;
87#endif
88 delete integral;
89}
90
91G4VPhysicalVolume* BDSLinkDetectorConstruction::Construct()
92{
94
95 auto componentFactory = std::unique_ptr<BDSComponentFactory>(new BDSComponentFactory(nullptr, false));
96 auto beamline = BDSParser::Instance()->GetBeamline();
97
98 std::vector<BDSLinkOpaqueBox*> opaqueBoxes = {};
99 linkBeamline = new BDSBeamline();
100
101 auto acceleratorModel = BDSAcceleratorModel::Instance();
102 if (!integral)
103 {
104 if (!designParticle)
105 {throw BDSException(__METHOD_NAME__, "designParticle must be set first");}
106 integral = new BDSBeamlineIntegral(*designParticle);
107 }
108 for (const auto& element : beamline)
109 {
110 GMAD::ElementType eType = element.type;
111
112 if (eType == GMAD::ElementType::_LINE || eType == GMAD::ElementType::_REV_LINE)
113 {continue;}
114
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())
123 {throw BDSException(G4String("Unsupported element type for link = " + GMAD::typestr(eType)));}
124
125 // Only need first argument, the rest pertain to beamlines.
126 BDSAcceleratorComponent* component = componentFactory->CreateComponent(&element,
127 nullptr,
128 nullptr,
129 *integral);
130
131 BDSTiltOffset* to = new BDSTiltOffset(element.offsetX * CLHEP::m,
132 element.offsetY * CLHEP::m,
133 element.tilt * CLHEP::rad);
134 auto extentTiltOffset = component->GetExtent().TiltOffset(to);
135 G4double encompassingRadius = extentTiltOffset.TransverseBoundingRadius();
136 BDSLinkOpaqueBox* opaqueBox = new BDSLinkOpaqueBox(component, to, encompassingRadius);
137
138 delete to; // opaqueBox doesn't own it
139 opaqueBoxes.push_back(opaqueBox);
140
141 BDSLinkComponent* comp = new BDSLinkComponent(opaqueBox->GetName(),
142 opaqueBox,
143 opaqueBox->GetExtent().DZ());
144 acceleratorModel->RegisterLinkComponent(comp); // memory management
145 nameToElementIndex[element.name] = (G4int)linkBeamline->size();
146 linkBeamline->AddComponent(comp);
147 }
148
149 // update world extents and world solid
151
152 G4LogicalVolume* worldLV = new G4LogicalVolume(worldSolid,
153 BDSMaterials::Instance()->GetMaterial("G4_Galactic"),
154 "world_lv");
155
156 G4VisAttributes* debugWorldVis = new G4VisAttributes(*(BDSGlobalConstants::Instance()->ContainerVisAttr()));
157 debugWorldVis->SetForceWireframe(true);//just wireframe so we can see inside it
158 worldLV->SetVisAttributes(debugWorldVis);
159 worldLV->SetUserLimits(globalConstants->DefaultUserLimits());
160
161 worldPV = new G4PVPlacement(nullptr,
162 G4ThreeVector(),
163 worldLV,
164 "world_pv",
165 nullptr,
166 false,
167 0,
168 true);
169
170 // place any defined link elements in input
171 for (auto element : *linkBeamline)
172 {
173 BDSLinkComponent* lc = dynamic_cast<BDSLinkComponent*>(element->GetAcceleratorComponent());
174 BDSSamplerInfo* samplerInfo = element->GetSamplerInfo();
175 G4String samplerName = samplerInfo ? samplerInfo->name : "unknown";
176 G4String name = lc ? lc->LinkName() : samplerName;
177 G4int linkID = PlaceOneComponent(element, name);
178 nameToElementIndex[name] = linkID;
179 }
180
181 return worldPV;
182}
183
184G4int BDSLinkDetectorConstruction::AddLinkCollimatorJaw(const std::string& collimatorName,
185 const std::string& materialName,
186 G4double length,
187 G4double halfApertureLeft,
188 G4double halfApertureRight,
189 G4double rotation,
190 G4double xOffset,
191 G4double yOffset,
192 G4double jawTiltLeft,
193 G4double jawTiltright,
194 G4bool buildLeftJaw,
195 G4bool buildRightJaw,
196 G4bool isACrystalIn,
197 G4double crystalAngle,
198 G4bool /*sampleIn*/)
199{
200 auto componentFactory = std::unique_ptr<BDSComponentFactory>(new BDSComponentFactory(nullptr, false));
201
202 if (!integral)
203 {
204 if (!designParticle)
205 {throw BDSException(__METHOD_NAME__, "designParticle must be set first");}
206 integral = new BDSBeamlineIntegral(*designParticle);
207 }
208 // TBC - here we could just update the synchronous time in the integral object if we need it
209
210 std::map<std::string, std::string> collimatorToCrystal =
211 {
212 {"cry.mio.b1", "stf75"}, // b1 h
213 {"cry.mio.b2", "tcp76"}, // b2 h
214 {"tcpv.a6l7.b1", "qmp34"}, // b1 v
215 {"tcpv.a6r7.b2", "qmp53"}, // b2 v
216 {"tcpch.a4l7.b1", "stf75"},// b1 h new name
217 {"tcpcv.a6l7.b1", "tcp76"} // b2 v new name
218 };
219 G4String collimatorLower = BDS::LowerCase(collimatorName);
220 auto searchC = collimatorToCrystal.find(collimatorLower); // will use later if needed
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");}
224 //G4cout << "XYZ isACrystal " << isACrystal << G4endl;
225 if (isACrystal)
226 {G4cout << "crystal name " << searchC->first << " " << searchC->second << G4endl;}
227
228 std::map<std::string, std::string> sixtrackToBDSIM =
229 {
230 {"CU", "Cu"},
231 {"W", "W"},
232 {"C", "G4_GRAPHITE_POROUS"},
233 {"Si", "Si"},
234 {"SI", "Si"}
235 };
236 std::string g4material;
237 auto search = sixtrackToBDSIM.find(materialName);
238 if (search != sixtrackToBDSIM.end())
239 {g4material = search->second;}
240 else
241 {g4material = materialName;}
242
243 // build component
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;
250 el.xsizeRight = halfApertureRight / CLHEP::m;
251 el.ysize = 0.2; // half size
252 el.tilt = rotation / CLHEP::rad;
253 el.offsetX = xOffset / CLHEP::m;
254 el.offsetY = yOffset / CLHEP::m;
255 el.horizontalWidth = 2.0; // m
256 el.jawTiltLeft = jawTiltLeft; // rad
257 el.jawTiltRight = jawTiltright; // rad
258
259 // if we don't want to build a jaw, then we set it to outside the width.
260 if (!buildLeftJaw)
261 {el.xsizeLeft = el.horizontalWidth * 1.2;}
262 if (!buildRightJaw)
263 {el.xsizeRight = el.horizontalWidth * 1.2;}
264
265 if (isACrystal)
266 {
267 // find the bending angle of this particular crystal
268 // so we can add half of that on for the BDSIM convention of the 0 about the centre for crystals
269 G4String crystalNameC = searchC->second;
270 G4cout << "crystal name " << crystalNameC << G4endl;
271 BDSCrystalInfo* ci = componentFactory->PrepareCrystalInfo(crystalNameC);
272 crystalAngle *= CLHEP::rad;
273
274 // crucial - crystal only responds to xsize - not xsizeLeft
275 el.xsize = el.xsizeLeft;
276
277 el.type = GMAD::ElementType::_CRYSTALCOL;
278 el.apertureType = "circularvacuum";
279 el.aper1 = 0.5; // m
280 // need a small margin in length as crystal may have angled face and be rotated
281 el.l += 10e-6; // TODO - confirm margin with sixtrack interface backtracking on input side
282 if (collimatorName.find('2') != std::string::npos) // b2
283 {
284 el.crystalLeft = crystalNameC;
285 el.crystalAngleYAxisLeft = crystalAngle + 0.5 * ci->bendingAngleYAxis;
286 }
287 else
288 {
289 el.crystalRight = crystalNameC;
290 el.crystalAngleYAxisRight = crystalAngle + 0.5 * ci->bendingAngleYAxis;
291 }
292
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;
299 delete ci; // no longer needed
300 }
301 else
302 {el.region = "r1";} // stricter range cuts for default collimators
303
304 BDSAcceleratorComponent* component = nullptr;
305 try
306 {component = componentFactory->CreateComponent(&el, nullptr, nullptr, *integral);}
307 catch (const BDSException& e)
308 {
309 G4cout << e.what() << G4endl;
310 G4cout << "Replacing component " << el.name << " with drift" << G4endl;
311 // well it didn't work (maybe ridiculous unphysical gap - so replace it with a drift
312 el.type = GMAD::ElementType::_DRIFT;
313 el.apertureType = "circularvacuum";
314 component = componentFactory->CreateComponent(&el, nullptr, nullptr, *integral);
315 }
316
317 // wrap in box
318 BDSTiltOffset* to = new BDSTiltOffset(el.offsetX * CLHEP::m,
319 el.offsetY * CLHEP::m,
320 el.tilt * CLHEP::rad);
321 auto extentTiltOffset = component->GetExtent().TiltOffset(to);
322 G4double encompassingRadius = extentTiltOffset.TransverseBoundingRadius();
323 BDSLinkOpaqueBox* opaqueBox = new BDSLinkOpaqueBox(component, to, encompassingRadius);
324
325 // add to beam line
326 BDSLinkComponent* comp = new BDSLinkComponent(opaqueBox->GetName(),
327 opaqueBox,
328 opaqueBox->GetExtent().DZ());
329 BDSAcceleratorModel::Instance()->RegisterLinkComponent(comp);
330 BDSSamplerInfo* samplerInfo = new BDSSamplerInfo(comp->GetName() + "_out", BDSSamplerType::plane);
331 linkBeamline->AddComponent(comp, nullptr, samplerInfo);
332
333 // update world extents and world solid
335
336 // place that one element
337 G4int linkID = PlaceOneComponent(linkBeamline->back(), collimatorName);
338 nameToElementIndex[collimatorName] = linkID;
339 linkIDToBeamlineIndex[linkID] = (G4int)linkBeamline->size() - 1;
340
341 // update crystal biasing
342 BuildPhysicsBias();
343
344 return linkID;
345}
346
347G4int BDSLinkDetectorConstruction::AddLinkCollimatorTipJaw(const std::string& collimatorName,
348 const std::string& materialName,
349 const std::string& tipMaterialName,
350 G4double tipThickness,
351 G4double length,
352 G4double halfApertureLeft,
353 G4double halfApertureRight,
354 G4double rotation,
355 G4double xOffset,
356 G4double yOffset,
357 G4double jawTiltLeft,
358 G4double jawTiltRight,
359 G4bool buildLeftJaw,
360 G4bool buildRightJaw)
361{
362 auto componentFactory = std::unique_ptr<BDSComponentFactory>(new BDSComponentFactory(nullptr, false));
363
364 if (!integral)
365 {
366 if (!designParticle)
367 {
368 throw BDSException(__METHOD_NAME__, "designParticle must be set first");
369 }
370 integral = new BDSBeamlineIntegral(*designParticle);
371 }
372
373 std::string g4material = materialName;
374 std::string g4tipMaterial = tipMaterialName;
375
376 // Create the element definition
377 GMAD::Element el;
378 el.type = GMAD::ElementType::_JCOLTIP;
379 el.name = collimatorName;
380 el.material = g4material;
381 el.tipMaterial = g4tipMaterial;
382 el.l = length / CLHEP::m;
383 el.xsizeLeft = halfApertureLeft / CLHEP::m;
384 el.xsizeRight = halfApertureRight / CLHEP::m;
385 el.ysize = 0.006; // half height
386 el.tilt = rotation / CLHEP::rad;
387 el.offsetX = xOffset / CLHEP::m;
388 el.offsetY = yOffset / CLHEP::m;
389 el.horizontalWidth = 2.0; // m
390 el.jawTiltLeft = jawTiltLeft; // rad
391 el.jawTiltRight = jawTiltRight; // rad
392 el.tipThickness = tipThickness / CLHEP::m;
393
394 if (!buildLeftJaw)
395 {
396 el.xsizeLeft = el.horizontalWidth * 1.2;
397 }
398 if (!buildRightJaw)
399 {
400 el.xsizeRight = el.horizontalWidth * 1.2;
401 }
402
403 el.region = "r1"; // stricter range cuts for default collimators
404
405 // Create the component
406 BDSAcceleratorComponent* component = nullptr;
407 try
408 {
409 component = componentFactory->CreateComponent(&el, nullptr, nullptr, *integral);
410 }
411 catch (const BDSException& e)
412 {
413 G4cout << e.what() << G4endl;
414 G4cout << "Replacing component " << el.name << " with drift" << G4endl;
415 el.type = GMAD::ElementType::_DRIFT;
416 el.apertureType = "circularvacuum";
417 component = componentFactory->CreateComponent(&el, nullptr, nullptr, *integral);
418 }
419
420 // Wrap in box
421 BDSTiltOffset* to = new BDSTiltOffset(el.offsetX * CLHEP::m, el.offsetY * CLHEP::m, el.tilt * CLHEP::rad);
422 auto extentTiltOffset = component->GetExtent().TiltOffset(to);
423 G4double encompassingRadius = extentTiltOffset.TransverseBoundingRadius();
424 BDSLinkOpaqueBox* opaqueBox = new BDSLinkOpaqueBox(component, to, encompassingRadius);
425
426 // Add to beamline
427 BDSLinkComponent* comp = new BDSLinkComponent(opaqueBox->GetName(), opaqueBox, opaqueBox->GetExtent().DZ());
428 BDSAcceleratorModel::Instance()->RegisterLinkComponent(comp);
429 BDSSamplerInfo* samplerInfo = new BDSSamplerInfo(comp->GetName() + "_out", BDSSamplerType::plane);
430 linkBeamline->AddComponent(comp, nullptr, samplerInfo);
431
432 // Update world extents and solid
434
435 // Place the new component
436 G4int linkID = PlaceOneComponent(linkBeamline->back(), collimatorName);
437 nameToElementIndex[collimatorName] = linkID;
438 linkIDToBeamlineIndex[linkID] = (G4int)linkBeamline->size() - 1;
439
440 return linkID;
441}
442
444 auto componentFactory = std::unique_ptr<BDSComponentFactory>(new BDSComponentFactory(nullptr, false));
445
446 if (!integral)
447 {
448 if (!designParticle)
449 {
450 throw BDSException(__METHOD_NAME__, "designParticle must be set first");
451 }
452 integral = new BDSBeamlineIntegral(*designParticle);
453 }
454
455 // Create the component
456 BDSAcceleratorComponent* component = nullptr;
457 try
458 {
459 component = componentFactory->CreateComponent(&el, nullptr, nullptr, *integral);
460 }
461 catch (const BDSException& e)
462 {
463 G4cout << e.what() << G4endl;
464 G4cout << "Replacing component " << el.name << " with drift" << G4endl;
465 el.type = GMAD::ElementType::_DRIFT;
466 el.apertureType = "circularvacuum";
467 component = componentFactory->CreateComponent(&el, nullptr, nullptr, *integral);
468 }
469
470 // Wrap in box
471 BDSTiltOffset* to = new BDSTiltOffset(el.offsetX * CLHEP::m, el.offsetY * CLHEP::m, el.tilt * CLHEP::rad);
472 auto extentTiltOffset = component->GetExtent().TiltOffset(to);
473 G4double encompassingRadius = extentTiltOffset.TransverseBoundingRadius();
474 BDSLinkOpaqueBox* opaqueBox = new BDSLinkOpaqueBox(component, to, encompassingRadius);
475
476 // Add to beamline
477 BDSLinkComponent* comp = new BDSLinkComponent(opaqueBox->GetName(), opaqueBox, opaqueBox->GetExtent().DZ());
478 BDSAcceleratorModel::Instance()->RegisterLinkComponent(comp);
479 BDSSamplerInfo* samplerInfo = new BDSSamplerInfo(comp->GetName() + "_out", BDSSamplerType::plane);
480 linkBeamline->AddComponent(comp, nullptr, samplerInfo);
481
482 // Update world extents and solid
484
485 // Place the new component
486 G4int linkID = PlaceOneComponent(linkBeamline->back(), el.name);
487 nameToElementIndex[el.name] = linkID;
488 linkIDToBeamlineIndex[linkID] = (G4int)linkBeamline->size() - 1;
489
490 return linkID;
491}
492
494{
495 BDSExtentGlobal we = linkBeamline->GetExtentGlobal();
496 we = we.ExpandToEncompass(BDSExtentGlobal(BDSExtent(10*CLHEP::m, 10*CLHEP::m, 10*CLHEP::m))); // minimum size
497 G4ThreeVector worldExtentAbs = we.GetMaximumExtentAbsolute();
498 worldExtentAbs *= 1.2;
499
500 if (!worldSolid)
501 {
502 worldSolid = new G4Box("world_solid",
503 worldExtentAbs.x(),
504 worldExtentAbs.y(),
505 worldExtentAbs.z());
506 }
507 else
508 {
509 worldSolid->SetXHalfLength(worldExtentAbs.x());
510 worldSolid->SetYHalfLength(worldExtentAbs.y());
511 worldSolid->SetZHalfLength(worldExtentAbs.z());
512 }
513 worldExtent = BDSExtent(worldExtentAbs);
514 if (primaryGeneratorAction)
515 {primaryGeneratorAction->SetWorldExtent(worldExtent);}
516}
517
519 const G4String& originalName)
520{
521 G4String placementName = element->GetPlacementName() + "_pv";
522 G4int copyNumber = element->GetCopyNo();
523 std::set<G4VPhysicalVolume*> pvs = element->PlaceElement(placementName, worldPV, false, copyNumber, true);
524
525 auto lc = dynamic_cast<BDSLinkComponent*>(element->GetAcceleratorComponent());
526 if (!lc)
527 {return -1;}
528 BDSLinkOpaqueBox* el = lc->Component();
529 G4Transform3D* placementTransform = element->GetPlacementTransform();
530 G4Transform3D elCentreToStart = el->TransformToStart();
531 G4Transform3D globalToStart = elCentreToStart * (*placementTransform);
532 G4int linkID = linkRegistry->Register(el, globalToStart);
533
534 G4ThreeVector zOffset = G4ThreeVector(0,0,BDSGlobalConstants::Instance()->LengthSafety()+BDSSamplerPlane::ChordLength());
535 G4Transform3D samplerPosition = globalToStart * G4Transform3D(G4RotationMatrix(), globalToStart.getRotation()*zOffset);
536
537 if (element->GetSamplerType() == BDSSamplerType::plane && samplerWorldID >= 0)
538 {
539 auto samplerWorldRaw = GetParallelWorld(samplerWorldID);
540 auto samplerWorld = dynamic_cast<BDSParallelWorldSampler*>(samplerWorldRaw);
541 if (!samplerWorld)
542 {return -1;}
543
544 BDSSamplerPlane* sampler = samplerWorld->GeneralPlane();
545 G4String samplerName = originalName + "_in";
546 G4double sStart = element->GetSPositionStart();
547
548 G4int samplerID = BDSSamplerRegistry::Instance()->RegisterSampler(samplerName, sampler, samplerPosition, sStart, element);
549
550 G4LogicalVolume* samplerWorldLV = samplerWorld->WorldLV();
551 new G4PVPlacement(samplerPosition,
552 sampler->GetContainerLogicalVolume(),
553 samplerName + "_pv",
554 samplerWorldLV,
555 false,
556 samplerID,
557 false);
558 }
559 return linkID;
560}
561
562void BDSLinkDetectorConstruction::BuildPhysicsBias()
563{
564#if G4VERSION_NUMBER > 1039
565 if (!crystalBiasing) // cache it because we may have to dynamically add later
566 {crystalBiasing = new G4ChannelingOptrMultiParticleChangeCrossSection();}
567
568 // crystal biasing necessary for implementation of variable density
569 std::set<G4LogicalVolume*>* crystals = BDSAcceleratorModel::Instance()->VolumeSet("crystals");
570 if (!crystals->empty())
571 {
572 G4cout << __METHOD_NAME__ << "Using crystal biasing: true" << G4endl; // to match print out style further down
573 for (auto crystal : *crystals)
574 {
575 // if it hasn't been added already - g4 will whine for double registration
576 if (!crystalBiasing->GetBiasingOperator(crystal))
577 {crystalBiasing->AttachTo(crystal);}
578 }
579 }
580#endif
581}
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.
Definition BDSExtent.hh:38
G4double DZ() const
The difference in a dimension.
Definition BDSExtent.hh:84
BDSExtent TiltOffset(const BDSTiltOffset *tiltOffset) const
Provide a new copy of this extent with both a tilt and an offset applied.
Definition BDSExtent.cc:104
G4double TransverseBoundingRadius() const
Return a radius that would encompass the maximum x,y extent.
Definition BDSExtent.cc:182
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.
Definition BDSParser.cc:29
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
Definition parser.cc:1073
G4String LowerCase(const G4String &str)
Utility function to simplify lots of syntax changes for pedantic g4 changes.
ElementType
types of elements
Definition elementtype.h:27
std::string typestr(ElementType type)
conversion from enum to string
Element class.
Definition element.h:47
std::string tipMaterial
tip material
Definition element.h:220
double aper1
beampipe information, new aperture model
Definition element.h:112
double xsizeRight
individual collimator jaw half widths
Definition element.h:132
double jawTiltRight
jaw collimator jaw tilts (angle in x-z plane)
Definition element.h:133
std::string region
region with range cuts
Definition element.h:247
double offsetX
offset X
Definition element.h:134
double ysize
collimator aperture or laser spotsize for laser
Definition element.h:130
double tilt
tilt
Definition element.h:129
double l
length in metres
Definition element.h:53
double tipThickness
for jaw collimator with tip
Definition element.h:219
ElementType type
element enum
Definition element.h:48
double offsetY
offset Y
Definition element.h:135
std::string apertureType
beampipe information, new aperture model
Definition element.h:116