Commit 559efb87 authored by Eoin Clerkin's avatar Eoin Clerkin Committed by Florian Uhlig
Browse files

Macro for scanning geometry binaries

Outputs the structure of a root geometry binaries which comparison by standard unix text based diff tools.

Creates a GRAPHVIZ graph of the geometry structure.

Short README gives some basic command examples.

Applied clang format
parent 1a94d85e
Tools in the Geometry Macro Folder
==================================
Scan Geometry (scan_geometry.C)
===============================
Scan geometry travels through the root geometry hierachy of a typical root geometry binary and outputs standard information regarding the node to the screen. There are several options, some of which are commented out in the file, which allows the easy comparison of root binaries. A GRAPHVIZ file named geo.gv is also output to the working directory.
Examing Text
------------
A typical use may be
```
root -l -q scan_geometry.C("pipe_v16b_1e.geo.root") | less
```
to look at output on screen. To save this output to a file, something like
```
root -l -q '~/cbmroot/macro/geometry/scan_geometry.C("tof_v20a_1h.geo.root")' 2>&1 1>tof_v20a_1h
```
Outputing two files may be compared with standard unix diff such as
```
diff -y -W 200 tof_v20a_1h tof_v20b_1h | less
```
Examining Graphical Represetation
---------------------------------
Sometimes, especially if the output is very large, it can be more insighted, to get the overall picture to look at a graph tree of the volumes in a geometry instead. This can be done for a single detector or indeed the whole experimental setup, e.g. test.geo.root To make a pdf graph, a basic graph may be made with a command like
```
sed -n '2,$p' geo.gv | head -n -1 | sort | uniq -c | awk 'BEGIN{print "digraph {"}{printf "%s -> %s [label=\"%d\"]\n", $2, $4, $1}END{print "}"}' > geo2.gv
dot -Tpdf geo2.gv > geo.pdf
```
/* Copyright (C) 2021 Facility for Antiproton and Ion Research in Europe, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Eoin Clerkin [committer] */
#if !defined(__CLING__)
#include "CbmSetup"
#include "CbmTransport.h"
#include "FairSystemInfo.h"
#include "TCanvas.h"
#include "TStopwatch.h"
#endif
#include <cstdlib>
#include <fstream>
#include <iostream>
#define NODE_DEPTH 25
TGeoNode* node[NODE_DEPTH];
TGeoMedium* med;
TGeoManager* gman;
TGeoVolume* top;
//const char* seekstr1 = "cable";
const char* seekstr2 = "cable";
void scan_geometry(const char* fileName = "test.geo.root")
{
TString myName = "scan_and_graph";
TFile file(fileName, "READ");
if (!file.IsOpen()) {
std::cerr << "Was a root geo file supplied?" << endl;
exit(1);
};
file.GetListOfKeys()->Print();
file.GetSize();
char geo_tag[100];
strcpy(geo_tag, basename(fileName));
char* ptr = strstr(geo_tag, ".geo.root");
*(ptr) = '\0';
gman = (TGeoManager*) file.Get("FAIRGeom");
if (gman != NULL) { top = gman->GetTopVolume(); };
if (top == NULL) top = (TGeoVolume*) file.Get(geo_tag);
if (top == NULL) top = (TGeoVolume*) file.Get("FAIRGeom");
if (top == NULL) top = (TGeoVolume*) file.Get("top");
if (top == NULL) top = (TGeoVolume*) file.Get("TOP");
if (top == NULL) top = (TGeoVolume*) file.Get("Top");
if (top == NULL) top = (TGeoVolume*) file.Get("geometryFromGDML");
if (top == NULL) {
std::cerr << "No Top Volume found. Is the TGeoManager or Top Volume unusally named" << endl;
exit(1);
}
FILE* graph = fopen("geo.gv", "w+");
fprintf(graph, "digraph D {\n");
TObjArray* nodes = top->GetNodes();
nodes->Print();
int i_array[NODE_DEPTH], num_array[NODE_DEPTH], j;
for (int i = 0; i < NODE_DEPTH; i++)
i_array[i] = 0;
for (int i = 0; i < NODE_DEPTH; i++)
num_array[i] = 0;
//TGeoNode* node[NODE_DEPTH];
//TGeoMedium* med;
j = 0;
i_array[0] = 0;
num_array[0] = nodes->GetEntries();
std::cout << "\n" << endl;
int k = 0;
while (num_array[0] != 0) {
k++; // Only used for stop.
//if(k==3)break;
if (j == 0) { node[0] = static_cast<TGeoNode*>(nodes->At(i_array[0])); }
else {
node[j] = static_cast<TGeoNode*>(node[j - 1]->GetDaughter(i_array[j]));
};
i_array[j]++; // Update number.
std::cout << "Node: \t";
for (int i = 0; i < j + 1; i++)
printf("%d/%d \t", i_array[i], num_array[i]);
printf("\n");
fprintf(graph, "%s -> %s \n", node[j]->GetMotherVolume()->GetName(), node[j]->GetVolume()->GetName());
std::cout << "Name: ";
node[j]->Print();
//std::cout << "Mother: ";
//node[j]->GetMotherVolume()->Print();
std::cout << "Shape: ";
node[j]->GetVolume()->GetShape()->Print();
std::cout << "Medium: ";
med = node[j]->GetMedium();
med->Print();
med->GetMaterial()->Print();
std::cout << "Position: ";
node[j]->GetMatrix()->Print();
num_array[j + 1] = node[j]->GetNdaughters();
std::cout << "Number of daughters: " << num_array[j + 1];
std::cout << endl << endl << endl;
if (num_array[j + 1] > 0) {
j++;
num_array[j + 2] = 0;
};
while (i_array[j] == num_array[j]) {
num_array[j] = 0;
i_array[j] = 0; // Reset the counter before falling back.
j--;
};
if (j >= NODE_DEPTH) {
std::cerr << "Maximum depth of " << NODE_DEPTH << " exceeded. Increase NODE_DEPTH in header of macro," << endl;
exit(NODE_DEPTH);
};
};
fprintf(graph, "}\n");
fclose(graph);
printf("Processed %d nodes.\n", k);
std::cout << "Program Ends" << endl;
} // End of macro
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment