Skip to content

Commit

Permalink
Merge branch 'main' into perf-sympy-transport-jac
Browse files Browse the repository at this point in the history
  • Loading branch information
kodiakhq[bot] authored Sep 26, 2024
2 parents 36e976c + 782c176 commit 74d708f
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 149 deletions.
68 changes: 57 additions & 11 deletions Examples/Python/src/Svg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ using ViewAndRange =
/// @param portalCache is a portal cache to avoid multiple drawings of the same portal
///
/// Returns an svg object in the right view
actsvg::svg::object viewDetectorVolume(const Svg::ProtoVolume& pVolume,
actsvg::svg::object drawDetectorVolume(const Svg::ProtoVolume& pVolume,
const std::string& identification,
const ViewAndRange& viewAndRange,
PortalCache& portalCache) {
Expand Down Expand Up @@ -154,13 +154,13 @@ actsvg::svg::object viewDetectorVolume(const Svg::ProtoVolume& pVolume,
}

// Helper function to be picked in different access patterns
void viewDetector(
std::vector<actsvg::svg::object> drawDetector(
const Acts::GeometryContext& gctx,
const Acts::Experimental::Detector& detector,
const std::string& identification,
const std::vector<std::tuple<int, Svg::DetectorVolumeConverter::Options>>&
volumeIdxOpts,
const std::vector<ViewAndRange>& viewAndRanges, const std::string& saveAs) {
const std::vector<ViewAndRange>& viewAndRanges) {
PortalCache portalCache;

// The svg object to be returned
Expand All @@ -182,17 +182,13 @@ void viewDetector(
for (auto [iv, var] : Acts::enumerate(viewAndRanges)) {
auto [view, selection, range] = var;
// Get the view and the range
auto svgVolView = viewDetectorVolume(
auto svgVolView = drawDetectorVolume(
pVolume, identification + "_vol" + std::to_string(vidx) + "_" + view,
var, portalCache);
svgDetViews[iv].add_object(svgVolView);
}
}

for (auto [iv, var] : Acts::enumerate(viewAndRanges)) {
auto [view, selection, range] = var;
Svg::toFile({svgDetViews[iv]}, saveAs + "_" + view + ".svg");
}
return svgDetViews;
}

} // namespace
Expand All @@ -206,6 +202,20 @@ void addSvg(Context& ctx) {
// Some basics
py::class_<actsvg::svg::object>(svg, "object");

py::class_<actsvg::svg::file>(svg, "file")
.def(py::init<>())
.def("addObject", &actsvg::svg::file::add_object)
.def("addObjects", &actsvg::svg::file::add_objects)
.def("clip",
[](actsvg::svg::file& self, std::array<actsvg::scalar, 4> box) {
self.set_view_box(box);
})
.def("write", [](actsvg::svg::file& self, const std::string& filename) {
std::ofstream file(filename);
file << self;
file.close();
});

// Core components, added as an acts.svg submodule
{
auto c = py::class_<Svg::Style>(svg, "Style").def(py::init<>());
Expand Down Expand Up @@ -283,6 +293,42 @@ void addSvg(Context& ctx) {
});
}

// Draw primitives
{
svg.def("drawArrow", &actsvg::draw::arrow);

svg.def("drawText", &actsvg::draw::text);
}

// Draw Eta Lines
{
svg.def(
"drawEtaLines",
[](const std::string& id, actsvg ::scalar z, actsvg::scalar r,
const std::vector<actsvg::scalar>& etaMain,
actsvg::scalar strokeWidthMain, unsigned int sizeMain,
bool labelMain, const std::vector<actsvg::scalar>& etaSub,
actsvg::scalar strokeWidthSub, const std::vector<int> strokeDashSub,
unsigned int sizeSub, bool labelSub) {
// The main eta lines
actsvg::style::stroke strokeMain;
strokeMain._width = strokeWidthMain;
actsvg::style::font fontMain;
fontMain._size = sizeMain;

actsvg::style::stroke strokeSub;
strokeSub._width = strokeWidthSub;
strokeSub._dasharray = strokeDashSub;
actsvg::style::font fontSub;
fontSub._size = sizeSub;

return actsvg::display::eta_lines(
id, z, r,
{std::tie(etaMain, strokeMain, labelMain, fontMain),
std::tie(etaSub, strokeSub, labelSub, fontSub)});
});
}

// How detector volumes are drawn: Svg DetectorVolume options & drawning
{
auto c = py::class_<Svg::DetectorVolumeConverter::Options>(
Expand All @@ -304,11 +350,11 @@ void addSvg(Context& ctx) {
svg.def("convertDetectorVolume", &Svg::DetectorVolumeConverter::convert);

// Define the view functions
svg.def("viewDetectorVolume", &viewDetectorVolume);
svg.def("drawDetectorVolume", &drawDetectorVolume);
}

// How a detector is drawn: Svg Detector options & drawning
{ svg.def("viewDetector", &viewDetector); }
{ svg.def("drawDetector", &drawDetector); }

// Legacy geometry drawing
{
Expand Down
44 changes: 22 additions & 22 deletions Examples/Scripts/Python/detector_creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@

# OBJ style output
surfaces = []
viewConfig = acts.ViewConfig()
viewConfig.nSegments = 100
for vol in detector.volumePtrs():
for surf in vol.surfacePtrs():
if surf.geometryId().sensitive() > 0:
surfaces.append(surf)
acts.examples.writeSurfacesObj(
surfaces, geoContext, [0, 120, 120], "odd-surfaces.obj"
)
acts.examples.writeSurfacesObj(surfaces, geoContext, viewConfig, "odd-surfaces.obj")

# SVG style output
surfaceStyle = acts.svg.Style()
Expand All @@ -69,28 +69,28 @@
volumeOptions = acts.svg.DetectorVolumeOptions()
volumeOptions.surfaceOptions = surfaceOptions

for ivol in range(detector.numberVolumes()):
acts.svg.viewDetector(
geoContext,
detector,
"odd-xy",
[[ivol, volumeOptions]],
[["xy", ["sensitives"], viewRange]],
"vol_" + str(ivol),
)

xyRange = acts.Extent([[acts.Binning.z, [-50, 50]]])
zrRange = acts.Extent([[acts.Binning.phi, [-0.1, 0.1]]])

acts.svg.viewDetector(
# Transverse view
xyRange = acts.Extent([[acts.BinningValue.binZ, [-50, 50]]])
xyView = acts.svg.drawDetector(
geoContext,
detector,
"odd",
[[ivol, volumeOptions] for ivol in range(detector.numberVolumes())],
[["xy", ["sensitives"], xyRange], ["zr", ["materials"], zrRange]],
"detector",
[["xy", ["sensitives"], xyRange]],
)
xyFile = acts.svg.file()
xyFile.addObjects(xyView)
xyFile.write("odd_xy.svg")

acts.examples.writeDetectorToJsonDetray(geoContext, detector, "odd-detray")

# det_detector = acts.examples.DetrayConverter(geoContext, detector,"odd-detray")
# Longitudinal view
zrRange = acts.Extent([[acts.BinningValue.binPhi, [-0.1, 0.1]]])
zrView = acts.svg.drawDetector(
geoContext,
detector,
"odd",
[[ivol, volumeOptions] for ivol in range(detector.numberVolumes())],
[["zr", ["sensitives", "portals"], zrRange]],
)
zrFile = acts.svg.file()
zrFile.addObjects(zrView)
zrFile.write("odd_zr.svg")
116 changes: 0 additions & 116 deletions Examples/Scripts/Python/geomodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ def main():

p.add_argument("-i", "--input", type=str, default="", help="Input SQL file")

p.add_argument(
"-o", "--output", type=str, default="GeoModel", help="Output file(s) base name"
)

p.add_argument(
"-q",
"--queries",
Expand Down Expand Up @@ -81,34 +77,6 @@ def main():
default=False,
)

p.add_argument(
"--output-svg",
help="Write the surfaces to SVG files",
action="store_true",
default=False,
)

p.add_argument(
"--output-internals-svg",
help="Write the internal navigation to SVG files",
action="store_true",
default=False,
)

p.add_argument(
"--output-obj",
help="Write the surfaces to OBJ files",
action="store_true",
default=False,
)

p.add_argument(
"--output-json",
help="Write the surfaces to OBJ files",
action="store_true",
default=False,
)

p.add_argument(
"--enable-blueprint",
help="Enable the usage of the blueprint",
Expand Down Expand Up @@ -179,90 +147,6 @@ def main():
gmDetectorBuilder = DetectorBuilder(gmDetectorConfig, args.top_node, logLevel)
detector = gmDetectorBuilder.construct(gContext)

# Output the detector to SVG
if args.output_svg:
surfaceStyle = acts.svg.Style()
surfaceStyle.fillColor = [5, 150, 245]
surfaceStyle.fillOpacity = 0.5

surfaceOptions = acts.svg.SurfaceOptions()
surfaceOptions.style = surfaceStyle

viewRange = acts.Extent([])
volumeOptions = acts.svg.DetectorVolumeOptions()
volumeOptions.surfaceOptions = surfaceOptions

xyRange = acts.Extent([[acts.Binning.z, [-50, 50]]])
zrRange = acts.Extent([[acts.Binning.phi, [-0.8, 0.8]]])

acts.svg.viewDetector(
gContext,
detector,
args.top_node,
[[ivol, volumeOptions] for ivol in range(detector.numberVolumes())],
[
["xy", ["sensitives", "portals"], xyRange],
["zr", ["sensitives", "portals", "materials"], zrRange],
],
args.output + "_detector",
)

gmDetectorBuilder = DetectorBuilder(gmDetectorConfig, args.top_node, logLevel)
detector = gmDetectorBuilder.construct(gContext)

materialSurfaces = detector.extractMaterialSurfaces()
print("Found ", len(materialSurfaces), " material surfaces")

# Output the detector to SVG
if args.output_svg:
surfaceStyle = acts.svg.Style()
surfaceStyle.fillColor = [5, 150, 245]
surfaceStyle.fillOpacity = 0.5

surfaceOptions = acts.svg.SurfaceOptions()
surfaceOptions.style = surfaceStyle

viewRange = acts.Extent([])
volumeOptions = acts.svg.DetectorVolumeOptions()
volumeOptions.surfaceOptions = surfaceOptions

xyRange = acts.Extent([[acts.Binning.z, [-50, 50]]])
zrRange = acts.Extent([[acts.Binning.phi, [-0.8, 0.8]]])

acts.svg.viewDetector(
gContext,
detector,
args.top_node,
[[ivol, volumeOptions] for ivol in range(detector.numberVolumes())],
[
["xy", ["sensitives", "portals"], xyRange],
["zr", ["sensitives", "portals", "materials"], zrRange],
],
args.output + "_detector",
)

# Output the internal navigation to SVG
if args.output_internals_svg:
for vol in detector.volumes():
acts.svg.viewInternalNavigation(
gContext, vol, [66, 111, 245, 245, 203, 66, 0.8], "/;:"
)

# Output the surface to an OBJ file
if args.output_obj:
segments = 720
ssurfaces = [ss[1] for ss in gmFactoryCache.sensitiveSurfaces]
acts.examples.writeSurfacesObj(
ssurfaces,
gContext,
[75, 220, 100],
segments,
args.output + "_sensitives.obj",
)
# Output to a JSON file
if args.output_json:
acts.examples.writeDetectorToJsonDetray(gContext, detector, args.output)

return


Expand Down

0 comments on commit 74d708f

Please sign in to comment.