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