Skip to content

Commit

Permalink
feat: adding dot graph possibility (#3730)
Browse files Browse the repository at this point in the history
This PR adds the option to create a dot graph from GeoModel in the Gen2
geometry, which will help debugging as long as Gen2 is alive and around.
  • Loading branch information
asalzburger authored Oct 14, 2024
1 parent 6709342 commit a108ee9
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 19 deletions.
41 changes: 24 additions & 17 deletions Core/src/Detector/detail/BlueprintDrawer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,58 +57,65 @@ std::string labelStr(
void Acts::Experimental::detail::BlueprintDrawer::dotStream(
std::ostream& ss, const Acts::Experimental::Blueprint::Node& node,
const Options& options) {
// Replace the "/" in node names
std::string nodeName = node.name;
std::replace(nodeName.begin(), nodeName.end(), '/', '_');

// Root / leaf or branch
if (node.isRoot()) {
ss << "digraph " << options.graphName << " {" << '\n';
ss << node.name << " " << labelStr(options.root, node.name, node.auxiliary)
ss << nodeName << " " << labelStr(options.root, nodeName, node.auxiliary)
<< '\n';
ss << node.name << " " << shapeStr(options.root) << '\n';
ss << nodeName << " " << shapeStr(options.root) << '\n';

} else if (node.isLeaf()) {
ss << node.name << " " << labelStr(options.leaf, node.name, node.auxiliary)
ss << nodeName << " " << labelStr(options.leaf, nodeName, node.auxiliary)
<< '\n';
ss << node.name << " "
ss << nodeName << " "
<< ((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';
ss << nodeName << " " << labelStr(options.branch, nodeName, node.auxiliary)
<< '\n';
ss << nodeName << " " << shapeStr(options.branch) << '\n';
}
// Recursive for children
for (const auto& c : node.children) {
ss << node.name << " -> " << c->name << ";" << '\n';
// Replace the "/" in node names
std::string childName = c->name;
std::replace(childName.begin(), childName.end(), '/', '_');
ss << nodeName << " -> " << childName << ";" << '\n';
dotStream(ss, *c, options);
}

// Shape
Options::Node shape = node.isLeaf() ? options.shape : options.virtualShape;
std::stringstream bts;
bts << node.boundsType;
ss << node.name + "_shape " << shapeStr(shape) << '\n';
ss << node.name + "_shape "
ss << nodeName + "_shape " << shapeStr(shape) << '\n';
ss << nodeName + "_shape "
<< labelStr(shape, bts.str(),
{"t = " + toString(node.transform.translation(), 1),
"b = " + toString(node.boundaryValues, 1)})
<< '\n';
ss << node.name << " -> " << node.name + "_shape [ arrowhead = \"none\" ];"
ss << nodeName << " -> " << nodeName + "_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';
ss << nodeName + "_int " << shapeStr(options.internals) << '\n';
ss << nodeName << " -> " << nodeName + "_int;" << '\n';
}

if (node.geoIdGenerator != nullptr) {
ss << node.name + "_geoID " << shapeStr(options.geoID) << '\n';
ss << node.name << " -> " << node.name + "_geoID;" << '\n';
ss << nodeName + "_geoID " << shapeStr(options.geoID) << '\n';
ss << nodeName << " -> " << nodeName + "_geoID;" << '\n';
}

if (node.rootVolumeFinderBuilder != nullptr) {
ss << node.name + "_roots " << shapeStr(options.roots) << '\n';
ss << node.name << " -> " << node.name + "_roots;" << '\n';
ss << nodeName + "_roots " << shapeStr(options.roots) << '\n';
ss << nodeName << " -> " << nodeName + "_roots;" << '\n';
}

if (node.isRoot()) {
Expand Down
5 changes: 3 additions & 2 deletions Examples/Python/src/GeoModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,9 @@ void addGeoModel(Context& ctx) {
.def_readwrite(
"topBoundsOverride",
&Acts::GeoModelBlueprintCreater::Options::topBoundsOverride)
.def_readwrite("table",
&Acts::GeoModelBlueprintCreater::Options::table);
.def_readwrite("table", &Acts::GeoModelBlueprintCreater::Options::table)
.def_readwrite("dotGraph",
&Acts::GeoModelBlueprintCreater::Options::dotGraph);
}

gm.def(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ class GeoModelBlueprintCreater {
std::string topEntry;
/// Optionally override the top node bounds
std::string topBoundsOverride = "";
/// Export dot graph
std::string dotGraph = "";
};

/// The Blueprint return object
Expand Down
11 changes: 11 additions & 0 deletions Plugins/GeoModel/src/GeoModelBlueprintCreater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "Acts/Detector/GeometryIdGenerator.hpp"
#include "Acts/Detector/LayerStructureBuilder.hpp"
#include "Acts/Detector/detail/BlueprintDrawer.hpp"
#include "Acts/Detector/detail/BlueprintHelper.hpp"
#include "Acts/Detector/interface/IGeometryIdGenerator.hpp"
#include "Acts/Plugins/GeoModel/GeoModelTree.hpp"
Expand All @@ -20,6 +21,8 @@
#include "Acts/Utilities/Helpers.hpp"
#include "Acts/Utilities/RangeXD.hpp"

#include <fstream>

#include <boost/algorithm/string.hpp>

using namespace Acts::detail;
Expand Down Expand Up @@ -128,6 +131,14 @@ Acts::GeoModelBlueprintCreater::create(const GeometryContext& gctx,
blueprint.topNode =
createNode(cache, gctx, topEntry->second, blueprintTableMap, Extent());

// Export to dot graph if configured
if (!options.dotGraph.empty()) {
std::ofstream dotFile(options.dotGraph);
Experimental::detail::BlueprintDrawer::dotStream(dotFile,
*blueprint.topNode);
dotFile.close();
}

// Return the ready-to-use blueprint
return blueprint;
}
Expand Down

0 comments on commit a108ee9

Please sign in to comment.