-
Notifications
You must be signed in to change notification settings - Fork 173
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: cylindrical detector from DD4hep (#2582)
This PR introduces the possibility to build cylindrical detectors via a blue print definition from `DD4hep`. It mainly adds two classes: - `DD4hepBlueprint` which parses the DD4hep Detector Element tree and creates a blueprint - `DD4hepDetectorStructure` which can turn this into a detector Working with the Blueprint allows to get rid of the `DD4hepVolumeStructure` as this is part of the blueprint definition. For debugging, is also refines the drawing of the `Blueprint` to `.dot` which is now decoupled from the class into a helper function. It adds an extensive test on a simple detector, and to make sure it does what it should do, I introduced a new - `DD4hepDiscLayerStructureTests` unit test. ![Screenshot 2023-10-25 at 17 00 06](https://github.com/acts-project/acts/assets/26623879/a69cf5e1-fcc4-4257-8c5a-179923c0a3c5) The building seems to work, navigation is not tested yet on this one. ![Screenshot 2023-10-25 at 17 01 31](https://github.com/acts-project/acts/assets/26623879/6616b652-0b45-48f4-9889-8f081b963357)
- Loading branch information
1 parent
0547774
commit d4842c7
Showing
24 changed files
with
1,569 additions
and
535 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// This file is part of the Acts project. | ||
// | ||
// Copyright (C) 2023 CERN for the benefit of the Acts project | ||
// | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
||
#pragma once | ||
|
||
#include "Acts/Detector/Blueprint.hpp" | ||
|
||
#include <ostream> | ||
#include <string> | ||
|
||
namespace Acts { | ||
|
||
namespace Experimental { | ||
|
||
namespace detail { | ||
namespace BlueprintDrawer { | ||
|
||
/// @brief Nested options struct for the drawer | ||
struct Options { | ||
struct Node { | ||
/// ROOT node definitions | ||
std::string shape = "circle"; | ||
std::string color = "darkorange"; | ||
|
||
/// Font properties | ||
std::string face = "sans-serif"; | ||
int labelText = 12; | ||
int infoText = 10; | ||
|
||
/// Info properties | ||
int precision = 1; | ||
}; | ||
|
||
/// @brief The name of the graph | ||
std::string graphName = "blueprint"; | ||
|
||
// Main node types to come | ||
Node root = Node{}; | ||
Node branch = Node{"diamond", "white"}; | ||
Node leaf = Node{"box", "darkolivegreen1"}; | ||
Node gap = Node{"box", "darkolivegreen3"}; | ||
|
||
// Sub node types to come | ||
Node shape = Node{"cylinder", "lightgrey"}; | ||
Node virtualShape = Node{"cylinder", "white"}; | ||
Node internals = Node{"doubleoctagon", "cadetblue1"}; | ||
Node geoID = Node{"box", "azure"}; | ||
Node roots = Node{"box", "darkkhaki"}; | ||
}; | ||
|
||
/// @brief Turn into a dot output by writing into a stream | ||
/// | ||
/// @tparam the stream type to be used | ||
/// | ||
/// @param ss the stream into which the dot output should be written | ||
/// @param node the node to be drawn | ||
/// @param options the options for the drawer | ||
void dotStream(std::ostream& ss, const Blueprint::Node& node, | ||
const Options& options = Options{}); | ||
|
||
} // namespace BlueprintDrawer | ||
} // namespace detail | ||
} // namespace Experimental | ||
} // namespace Acts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
// This file is part of the Acts project. | ||
// | ||
// Copyright (C) 2023 CERN for the benefit of the Acts project | ||
// | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
||
#include "Acts/Detector/detail/BlueprintDrawer.hpp" | ||
|
||
#include <vector> | ||
|
||
namespace { | ||
|
||
/// @brief Generate the shape string | ||
/// @param s the shape of the object | ||
/// @param c the color of the object | ||
/// @return a string with the shape and color | ||
std::string shapeStr( | ||
const Acts::Experimental::detail::BlueprintDrawer::Options::Node& node) { | ||
return "[shape=\"" + node.shape + "\";style=\"filled\";fillcolor=\"" + | ||
node.color + "\"];"; | ||
} | ||
|
||
/// @brief Generate text output | ||
/// | ||
/// @param node the node options | ||
/// @param label the label text | ||
/// @param info the info text | ||
std::string labelStr( | ||
const Acts::Experimental::detail::BlueprintDrawer::Options::Node& node, | ||
const std::string& label, const std::vector<std::string>& info = {}) { | ||
std::string lText = "[label=<<font face=\""; | ||
lText += node.face; | ||
lText += "\" point-size=\""; | ||
lText += std::to_string(node.labelText); | ||
lText += "\">" + label; | ||
if (!info.empty()) { | ||
lText += "</font><br/>"; | ||
lText += "<font face=\""; | ||
lText += node.face; | ||
lText += "\" point-size=\""; | ||
lText += std::to_string(node.infoText); | ||
lText += "\">"; | ||
for (const auto& i : info) { | ||
lText += i; | ||
lText += "<br/>"; | ||
} | ||
} | ||
lText += "</font>"; | ||
lText += ">];"; | ||
return lText; | ||
} | ||
|
||
} // namespace | ||
|
||
void Acts::Experimental::detail::BlueprintDrawer::dotStream( | ||
std::ostream& ss, const Acts::Experimental::Blueprint::Node& node, | ||
const Options& options) { | ||
// Root / leaf or branch | ||
if (node.isRoot()) { | ||
ss << "digraph " << options.graphName << " {" << '\n'; | ||
ss << node.name << " " << labelStr(options.root, node.name, node.auxiliary) | ||
<< '\n'; | ||
ss << node.name << " " << shapeStr(options.root) << '\n'; | ||
|
||
} else if (node.isLeaf()) { | ||
ss << node.name << " " << labelStr(options.leaf, node.name, node.auxiliary) | ||
<< '\n'; | ||
ss << node.name << " " | ||
<< ((node.internalsBuilder != nullptr) ? shapeStr(options.leaf) | ||
: shapeStr(options.gap)) | ||
<< '\n'; | ||
} else { | ||
ss << node.name << " " | ||
<< labelStr(options.branch, node.name, node.auxiliary) << '\n'; | ||
ss << node.name << " " << shapeStr(options.branch) << '\n'; | ||
} | ||
// Recursive for children | ||
for (const auto& c : node.children) { | ||
ss << node.name << " -> " << c->name << ";" << '\n'; | ||
dotStream(ss, *c, options); | ||
} | ||
|
||
// Shape | ||
Options::Node shape = node.isLeaf() ? options.shape : options.virtualShape; | ||
ss << node.name + "_shape " << shapeStr(shape) << '\n'; | ||
ss << node.name + "_shape " | ||
<< labelStr(shape, VolumeBounds::s_boundsTypeNames[node.boundsType], | ||
{"t = " + toString(node.transform.translation(), 1), | ||
"b = " + toString(node.boundaryValues, 1)}) | ||
<< '\n'; | ||
ss << node.name << " -> " << node.name + "_shape [ arrowhead = \"none\" ];" | ||
<< '\n'; | ||
|
||
// Sub node detection | ||
if (node.internalsBuilder != nullptr) { | ||
ss << node.name + "_int " << shapeStr(options.internals) << '\n'; | ||
ss << node.name << " -> " << node.name + "_int;" << '\n'; | ||
} | ||
|
||
if (node.geoIdGenerator != nullptr) { | ||
ss << node.name + "_geoID " << shapeStr(options.geoID) << '\n'; | ||
ss << node.name << " -> " << node.name + "_geoID;" << '\n'; | ||
} | ||
|
||
if (node.rootVolumeFinderBuilder != nullptr) { | ||
ss << node.name + "_roots " << shapeStr(options.roots) << '\n'; | ||
ss << node.name << " -> " << node.name + "_roots;" << '\n'; | ||
} | ||
|
||
if (node.isRoot()) { | ||
ss << "}" << '\n'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.