Skip to content

Commit

Permalink
Add functionality to track in a BeamPipeChain (#768)
Browse files Browse the repository at this point in the history
### Briefly, what does this PR introduce?
An option had been added to include sensitive elements at the start
and/or end of beam pipe vacuum. This allows easy tracking of the shape
and position of beam electrons/protons to compare with accelerator group
and stand alone simulations. The segment in which scattered electrons of
different kinematics can also be studied/verified.

### What kind of change does this PR introduce?
- [ ] Bug fix (issue #__)
- [x] New feature (issue #__)
- [ ] Documentation update
- [ ] Other: __

### Please check if this PR fulfills the following:
- [ ] Tests for the changes have been added
- [ ] Documentation has been added / updated
- [ ] Changes have been communicated to collaborators

### Does this PR introduce breaking changes? What changes might users
need to make to their code?
No
### Does this PR change default behavior?
No

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
simonge and pre-commit-ci[bot] authored Oct 12, 2024
1 parent 335a7f7 commit b3588d6
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 3 deletions.
1 change: 1 addition & 0 deletions compact/definitions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ The unused IDs below are saved for future use.
<constant name="LumiSpecCAL_ID" value="194"/>
<constant name="LumiDirectPCAL_ID" value="195"/>

<constant name="BackwardsBeamline_ID" value="197"/>
<constant name="TaggerTracker_ID" value="198"/>
<constant name="TaggerCalorimeter_ID" value="199"/>

Expand Down
3 changes: 2 additions & 1 deletion compact/far_backward/beamline_extension_electron.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
<pipe id="2" name="Pipe_in_Q4eR"
xcenter="Q4eR_CenterX" zcenter="Q4eR_CenterZ"
length="Q4eR_Length" theta="Q4eR_Theta"
rout1="Q4eR_InnerRadius" rout2="Q4eR_InnerRadius">
rout1="Q4eR_InnerRadius" rout2="Q4eR_InnerRadius"
limits="kill_limits">
</pipe>
<pipe id="3" name="Pipe_Q4eR_to_B3eR"/>
<pipe id="4" name="Pipe_in_B3eR"
Expand Down
80 changes: 80 additions & 0 deletions compact/far_backward/beamline_tracking.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@

<lccdd>

<detectors>
<detector
id="BackwardsBeamline_ID"
type="BeamPipeTracking"
name="Pipe_tracker"
readout="BackwardsBeamlineHits">

<slice
pipe_id="0"
grandmother="Pipe_Q1eR_to_B2BeR"
mother="Pipe_to_Q1eR_vacuum"
name="Pipe_to_Q1eR_tracker"/>

<slice
pipe_id="1"
grandmother="Pipe_Q1eR_to_B2BeR"
mother="Pipe_in_Q1eR_vacuum"
name="Pipe_in_Q1eR_tracker"/>

<slice
pipe_id="2"
grandmother="Pipe_Q1eR_to_B2BeR"
mother="Pipe_in_Q2eR_vacuum"
name="Pipe_in_Q2eR_tracker"/>

<slice
pipe_id="3"
grandmother="Pipe_Q1eR_to_B2BeR"
mother="Pipe_in_B2AeR_vacuum"
name="Pipe_in_B2AeR_tracker"/>

<slice
pipe_id="4"
grandmother="Pipe_Q1eR_to_B2BeR"
mother="Pipe_in_B2BeR_vacuum"
name="Pipe_in_B2BeR_tracker"/>

<slice
pipe_id="5"
grandmother="Pipe_Q3eR_to_B7eR"
mother="Pipe_in_Q3eR_vacuum"
name="Pipe_in_Q3eR_tracker_start"
end="false"/>

<slice
pipe_id="6"
grandmother="Pipe_Q3eR_to_B7eR"
mother="Pipe_in_Q3eR_vacuum"
name="Pipe_in_Q3eR_tracker_end"/>

<slice
pipe_id="7"
grandmother="Pipe_Q3eR_to_B7eR"
mother="Pipe_in_Q4eR_vacuum"
name="Pipe_in_Q4eR_tracker"/>

</detector>

<detector
type="BeamPipeStop"
name="Backwards_Pipe_Stop"
grandmother="Pipe_Q3eR_to_B7eR"
mother="Pipe_Q4eR_to_B3eR_vacuum"
/>

</detectors>

<readouts>

<readout name="BackwardsBeamlineHits">
<segmentation type="NoSegmentation"/>
<id>system:8,pipe:8,end:2</id>
</readout>

</readouts>

</lccdd>
2 changes: 2 additions & 0 deletions compact/far_backward/extended.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@
<!-- Luminosity detector -->
<include ref="lumi.xml"/>

<include ref="beamline_tracking.xml"/>

</lccdd>
10 changes: 8 additions & 2 deletions src/BeamPipeChain_geo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector /
double thickness = getAttrOrDefault<double>(x_det, _Unicode(wall_thickness), 0);

vector<string> names;
vector<int> ids;
vector<double> xCenters;
vector<double> zCenters;
vector<double> lengths;
Expand All @@ -44,6 +45,7 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector /
xml_comp_t pipe(pipe_coll);

names.push_back(getAttrOrDefault<string>(pipe, _Unicode(name), ""));
ids.push_back(getAttrOrDefault<int>(pipe, _Unicode(id), 0));

// Vectors momentarily filled with zeros for pipes in between magnets
xCenters.push_back(getAttrOrDefault<double>(pipe, _Unicode(xcenter), 0));
Expand Down Expand Up @@ -108,8 +110,12 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector /

assembly.placeVolume(v_tube, Transform3D(RotationY(thetas[pipeN]),
Position(xCenters[pipeN], 0, zCenters[pipeN])));
assembly.placeVolume(v_vacuum, Transform3D(RotationY(thetas[pipeN]),
Position(xCenters[pipeN], 0, zCenters[pipeN])));
auto placed_vacuum =
assembly.placeVolume(v_vacuum, Transform3D(RotationY(thetas[pipeN]),
Position(xCenters[pipeN], 0, zCenters[pipeN])));

DetElement vacuum_element(sdet, names[pipeN] + "_vacuum", ids[pipeN]);
vacuum_element.setPlacement(placed_vacuum);
}

// Final placement
Expand Down
68 changes: 68 additions & 0 deletions src/BeamPipeStop_geo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright (C) 2024 Simon Gardner

//==========================================================================
//
// Places a small sensitive disk of vacuum at the end of beam pipes
//
//==========================================================================

#include "DD4hep/DetFactoryHelper.h"
#include "DD4hep/Printout.h"
#include "TMath.h"
#include <XML/Helper.h>

using namespace std;
using namespace dd4hep;

static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector /* sens */) {

using namespace ROOT::Math;
xml_det_t x_det = e;
string det_name = x_det.nameStr();
int det_id = x_det.id();
Material m_Vacuum = description.material("Vacuum");
string vis_name = dd4hep::getAttrOrDefault<std::string>(x_det, _Unicode(vis), "BeamPipeVis");

string grandmotherName = x_det.attr<string>(_Unicode(grandmother));
string motherName = x_det.attr<string>(_Unicode(mother));
bool detStart = getAttrOrDefault<bool>(x_det, _Unicode(end), true);
DetElement mother = description.detector(grandmotherName).child(motherName);

DetElement sdet(det_name, det_id);

// Get the mother volume
Volume mother_vol = mother.volume();

// Get mother volume shape as cone segment
ConeSegment mother_shape = mother_vol.solid();

// Get the parameters of the mother volume
double rOuter1 = mother_shape.rMax1();
double rOuter2 = mother_shape.rMax2();
double length = 2 * mother_shape.dZ();

double sensitive_thickness = 100 * mm;

//Calculate R or cone after sensitive layer
double rEnd = rOuter2 - (rOuter2 - rOuter1) * sensitive_thickness / length;
double zPos = length / 2.0 - sensitive_thickness / 2.0;
if (detStart) {
rEnd = rOuter1 - (rOuter1 - rOuter2) * sensitive_thickness / length;
zPos = -length / 2.0 + sensitive_thickness / 2.0;
}

ConeSegment s_start_disk(sensitive_thickness / 2, 0.0, rOuter2, 0.0, rEnd);
Volume v_start_disk("stop_disk_" + motherName, s_start_disk, m_Vacuum);

v_start_disk.setLimitSet(description, "kill_limits");

auto disk_placement = mother_vol.placeVolume(v_start_disk, Position(0.0, 0.0, zPos));

sdet.setPlacement(disk_placement);
description.declareParent(det_name, mother);

return sdet;
}

DECLARE_DETELEMENT(BeamPipeStop, create_detector)
86 changes: 86 additions & 0 deletions src/BeamPipeTracking_geo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright (C) 2024 Simon Gardner

//==========================================================================
//
// Places a small sensitive disk of vacuum at the end of beam pipes
//
//==========================================================================

#include "DD4hep/DetFactoryHelper.h"
#include "DD4hep/Printout.h"
#include "TMath.h"
#include <XML/Helper.h>

using namespace std;
using namespace dd4hep;

static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {

using namespace ROOT::Math;
xml_det_t x_det = e;
string det_name = x_det.nameStr();
int det_id = x_det.id();
Material m_Vacuum = description.material("Vacuum");
string vis_name = dd4hep::getAttrOrDefault<std::string>(x_det, _Unicode(vis), "BeamPipeVis");

sens.setType("tracker");

DetElement sdet(det_name, det_id);
Assembly assembly(det_name + "_assembly");

// Grab info for beamline magnets
for (xml_coll_t slice_coll(x_det, _Unicode(slice)); slice_coll; slice_coll++) { // pipes

string grandmotherName = slice_coll.attr<string>(_Unicode(grandmother));
string motherName = slice_coll.attr<string>(_Unicode(mother));
bool detStart = getAttrOrDefault<bool>(slice_coll, _Unicode(end), true);
int pipe_id = getAttrOrDefault<int>(slice_coll, _Unicode(pipe_id), 0);
string slice_name = slice_coll.attr<string>(_Unicode(name));
DetElement mother = description.detector(grandmotherName).child(motherName);

// Get the mother volume
Volume mother_vol = mother.volume();

// Get mother volume shape as cone segment
ConeSegment mother_shape = mother_vol.solid();

// Get the parameters of the mother volume
double rOuter1 = mother_shape.rMax1();
double rOuter2 = mother_shape.rMax2();
double length = 2 * mother_shape.dZ();

double sensitive_thickness = 0.1 * mm;

//Calculate R or cone after sensitive layer

double rEnd = rOuter2 - (rOuter2 - rOuter1) * sensitive_thickness / length;
double zPos = length / 2.0 - sensitive_thickness / 2.0;
if (detStart) {
rEnd = rOuter1 - (rOuter1 - rOuter2) * sensitive_thickness / length;
zPos = -length / 2.0 + sensitive_thickness / 2.0;
}

ConeSegment s_start_disk(sensitive_thickness / 2, 0.0, rOuter2, 0.0, rEnd);
Volume v_start_disk("v_start_disk_" + motherName, s_start_disk, m_Vacuum);
v_start_disk.setSensitiveDetector(sens);

auto disk_placement = mother_vol.placeVolume(v_start_disk, Position(0.0, 0.0, zPos));
disk_placement.addPhysVolID("end", detStart);
disk_placement.addPhysVolID("pipe", pipe_id);
disk_placement.addPhysVolID("system", det_id);

DetElement slice_element(sdet, slice_name, pipe_id);

slice_element.setPlacement(disk_placement);
description.declareParent(slice_name, mother);
}

auto pv_assembly = description.worldVolume().placeVolume(assembly, Position(0.0, 0.0, 0.0));
pv_assembly.addPhysVolID("system", det_id);
sdet.setPlacement(pv_assembly);

return sdet;
}

DECLARE_DETELEMENT(BeamPipeTracking, create_detector)
3 changes: 3 additions & 0 deletions templates/epic.xml.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@
<limit name="ekin_min" particles="*" value="0.001" unit="MeV" />
<limit name="range_min" particles="*" value="0.1" unit="mm" />
</limitset>
<limitset name="kill_limits">
<limit name="time_max" particles="*" value="0.0" unit="ns"/>
</limitset>
<limitset name="cal_limits">
<limit name="step_length_max" particles="*" value="5.0" unit="mm"/>
</limitset>
Expand Down

0 comments on commit b3588d6

Please sign in to comment.