Skip to content
Snippets Groups Projects
Commit 4a93b400 authored by Pierre-Alain Loizeau's avatar Pierre-Alain Loizeau Committed by Florian Uhlig
Browse files

Add aligment compatibility to overlap check macro + missing expected overlaps for mcbm 2019_03

parent 6873c699
No related branches found
No related tags found
1 merge request!1285Add aligment compatibility to overlap check macro + missing expected overlaps for mcbm 2019_03
Pipeline #23672 passed
......@@ -62,6 +62,22 @@ foreach(setup IN LISTS setup_files)
endforeach(setup IN LISTS setup_files)
# ============================================================================
# Example of usage to check overlaps in aligned setup
if(${CBM_TEST_MODEL} MATCHES Nightly OR ${CBM_TEST_MODEL} MATCHES Weekly)
set(setup mcbm_beam_2022_05_23_nickel)
set(align_file ${CBMROOT_SOURCE_DIR}/parameters/mcbm/AlignmentMatrices_mcbm_beam_2022_05_23_nickel.root)
set(testname geo_setup_overlaps_align_${setup})
add_test(${testname} ${MACRO_DIR}/check_overlaps.sh \"data/examine_${setup}\" \"${align_file}\")
set_tests_properties(${testname} PROPERTIES
TIMEOUT 600
FAIL_REGULAR_EXPRESSION "segmentation violation"
PASS_REGULAR_EXPRESSION "Test Passed;All ok"
FIXTURES_REQUIRED fixt_check_overlaps_${setup}
FIXTURES_SETUP fixt_check_overlaps_align_${setup}
)
endIf()
# ============================================================================
Install(FILES .rootrc examine_materials.C check_overlaps.C
DESTINATION share/cbmroot/macro/geometry
)
......
......@@ -219,5 +219,26 @@ root -q 'examine_materials.C("sis100_muon_jpsi_DEC21")'
for file in `ls ../../geometry/setup/setup_mcbm_beam_2022_*`; do tag=`echo $file | awk -F'/' '{print $5}' | sed 's|setup_|"|' | sed 's_.C$_"_'`; echo $tag; root -q './examine_material.C('$tag')'; done > MCBM_2022_EXAMINE
---
## check_overlaps.C
Allow to check overlaps in existing full geometry file (setup, e.g. output of `examine_materials.C`) and detect
expected/unexpected ones.
The lists of expected (known and ignored) overlaps are defined in 4 vectors at the begining of the macro for:
- overlaps between a BMon detector defined in the TOF geometry and the target/pipe vacuum in mCBM (always expected)
- overlaps in mCBM (should be expanded/reduced depending on simulation/analysis progresses)
- overlaps between a BMon detector defined in the TOF geometry and the target/pipe vacuum in CBM (always expected)
- overlaps in CBM (should be expanded/reduced depending on simulation/analysis progresses)
**Usage of the script (see also examples in `CMakeLists.txt`:**
1. With a standard geometry (as defined in setup file, no alignment):
```
root -l -b -q 'check_overlaps.C("<full filename with path>.geo.root")'
```
1. With an aligned geometry (some shifts relative to setup file):
```
root -l -b -q 'check_overlaps.C("<full filename with path>.geo.root", "<full filename with path for alignment matrices>.root")'
```
......@@ -2,7 +2,154 @@
SPDX-License-Identifier: GPL-3.0-only
Authors: Volker Friese, P.-A. Loizeau, Florian Uhlig [committer] */
/**********************************************************************************************************************/
#include "FairLogger.h"
namespace geo_ci
{
/**
** Temporary solution to bring capability of checking geometries after alignment.
** Basically a copy of the FairAlignmentHandler of FairRoot v18.6.9 and v18.8.1
** FIXME: remove once a solution is found to make the FairRoot alignment functionalities available in ROOT CLI.
**/
class FairAlignmentHandler {
public:
std::map<std::string, TGeoHMatrix> fAlignmentMatrices;
void AlignGeometry() const;
void AlignGeometryByFullPath() const;
void AlignGeometryBySymlink() const;
void AddAlignmentMatrices(const std::map<std::string, TGeoHMatrix>& alignmentMatrices, bool invertMatrices);
void RecomputePhysicalAssmbBbox() const;
FairAlignmentHandler();
virtual ~FairAlignmentHandler();
};
/**********************************************************************************************************************/
/**********************************************************************************************************************/
FairAlignmentHandler::FairAlignmentHandler() {}
FairAlignmentHandler::~FairAlignmentHandler() {}
void FairAlignmentHandler::AlignGeometry() const
{
if (fAlignmentMatrices.size() > 0) {
LOG(info) << "aligning the geometry...";
LOG(info) << "aligning in total " << fAlignmentMatrices.size() << " volumes.";
if (gGeoManager->GetNAlignable() > 0) { //
AlignGeometryBySymlink();
}
else {
AlignGeometryByFullPath();
}
// --- Force BoundingBox recomputation for AssemblyVolumes as they may have been corrupted by alignment
// FIXME: will hopefully be fixed in Root in near future, temp fix in meantime
RecomputePhysicalAssmbBbox();
LOG(info) << "Refreshing geometry...";
gGeoManager->RefreshPhysicalNodes(kFALSE);
LOG(info) << "alignment finished!";
}
}
void FairAlignmentHandler::AlignGeometryByFullPath() const
{
TString volume_path;
LOG(info) << "aligning using full path.";
for (auto const& alignment_entry : fAlignmentMatrices) {
volume_path = alignment_entry.first;
gGeoManager->cd(volume_path);
TGeoNode* volume_node = gGeoManager->GetCurrentNode();
TGeoMatrix* volume_matrix = volume_node->GetMatrix();
// Need to do this as since ROOT 6.14 TGeoMatrix has no multiplication operator anymore
// it is implimnted now in TGeoHMatrix
TGeoHMatrix local_volume_matrix = TGeoHMatrix(*volume_matrix);
TGeoHMatrix* new_volume_matrix = new TGeoHMatrix(local_volume_matrix * alignment_entry.second);
// new matrix, representing real position (from new local mis RS to the global one)
TGeoPhysicalNode* pn = gGeoManager->MakePhysicalNode(volume_path);
pn->Align(new_volume_matrix);
}
LOG(info) << "alignments applied!";
}
void FairAlignmentHandler::AlignGeometryBySymlink() const
{
TString volume_path;
LOG(info) << "aligning using symlinks";
for (auto const& alignment_entry : fAlignmentMatrices) {
volume_path = alignment_entry.first;
TGeoPhysicalNode* node = NULL;
TGeoPNEntry* entry = gGeoManager->GetAlignableEntry(volume_path);
if (entry) { //
node = gGeoManager->MakeAlignablePN(entry);
}
TGeoMatrix* volume_matrix = NULL;
if (node) { //
volume_matrix = node->GetMatrix();
}
else {
continue;
}
// Need to do this as since ROOT 6.14 TGeoMatrix has no multiplication operator anymore
// it is implimnted now in TGeoHMatrix
TGeoHMatrix local_volume_matrix = TGeoHMatrix(*volume_matrix);
TGeoHMatrix* new_volume_matrix = new TGeoHMatrix(local_volume_matrix * alignment_entry.second);
// new matrix, representing real position (from new local mis RS to the global one)
node->Align(new_volume_matrix);
}
}
void FairAlignmentHandler::AddAlignmentMatrices(const std::map<std::string, TGeoHMatrix>& alignmentMatrices,
bool invertMatrices)
{
LOG(info) << "adding inverting matrices...";
for (auto const& m : alignmentMatrices) {
if (invertMatrices) //
fAlignmentMatrices[m.first] *= m.second.Inverse();
else
fAlignmentMatrices[m.first] *= m.second;
}
}
void FairAlignmentHandler::RecomputePhysicalAssmbBbox() const
{
TObjArray* pPhysNodesArr = gGeoManager->GetListOfPhysicalNodes();
TGeoPhysicalNode* pPhysNode = nullptr;
TGeoShapeAssembly* pShapeAsb = nullptr;
Int_t iNbNodes = pPhysNodesArr->GetEntriesFast();
for (Int_t iInd = 0; iInd < iNbNodes; ++iInd) {
pPhysNode = dynamic_cast<TGeoPhysicalNode*>(pPhysNodesArr->At(iInd));
if (pPhysNode) {
pShapeAsb = dynamic_cast<TGeoShapeAssembly*>(pPhysNode->GetShape());
if (pShapeAsb) {
// Should reach here only if the original node was a TGeoShapeAssembly
pShapeAsb->ComputeBBox();
}
}
}
}
} // namespace geo_ci
/**********************************************************************************************************************/
std::vector<std::string> mcbm_pipevac_bmon_overlaps = {
"cave/pipe_v19b_0/vacu20_1 overlapping cave/tof_v19d_mcbm_0/tof_v19d_mcbmStand_1/module_5_0",
"cave/pipe_v19b_0/vacu20_1 overlapping cave/tof_v19e_mcbm_0/tof_v19e_mcbmStand_1/module_5_0",
"cave/pipe_v19b_0/vacu20_1 overlapping cave/tof_v20f_mcbm_0/tof_v20f_mcbmStand_1/module_5_0",
"cave/pipe_v19f_0/vacu20_1 overlapping cave/tof_v20c_mcbm_0/tof_v20c_mcbmStand_1/module_5_0",
......@@ -20,6 +167,7 @@ std::vector<std::pair<std::string, std::string>> mcbm_dets_overlaps = {
"between modules 2 and 9 (internal to mTOF v21j)"}};
std::vector<std::pair<std::string, std::string>> mcbm_dets_overlaps_sampling = {
{"tof_v19d_mcbmStand: node module_8_0 overlapping module_8_0", "between module 8 and itself (internal to mTOF v19d)"},
{"tof_v19e_mcbmStand: node module_8_0 overlapping module_8_0", "between module 8 and itself (internal to mTOF v19e)"},
{"gas_box: node counter_0 overlapping counter_1", "between counters 0 and 1 (internal to mTOF v19e)"},
{"gas_box: node counter_1 overlapping counter_2", "between counters 1 and 2 (internal to mTOF v19e)"},
......@@ -116,14 +264,15 @@ bool expected_cbm_sampling(TGeoOverlap* ov)
return false;
}
void check_overlaps(TString dataset = "test")
void check_overlaps(TString dataset = "test", TString alignment_matrices = "")
{
// 2014-07-04 - DE - test CBM setups for collisions in nightly tests
// 2014-07-04 - DE - currently there are 2 overlaps between the PIPE and STS layer 8
// 2014-07-04 - DE - set the default to 0 overlaps, anyway
// 2017-29-11 - FU - define some expected overlaps between magnet and rich or much
// these overlas are accepted for the time being until
// there is a new magnet geometry
// 2014-07-04 - DE - test CBM setups for collisions in nightly tests
// 2014-07-04 - DE - currently there are 2 overlaps between the PIPE and STS layer 8
// 2014-07-04 - DE - set the default to 0 overlaps, anyway
// 2017-29-11 - FU - define some expected overlaps between magnet and rich or much
// these overlaps are accepted for the time being until there is a new magnet geometry
// 2023-07-xx - PAL - Test all setups in nightly tests, make the list of expected overlaps less ad-hoc,
// add all mCBM ones as expected, add a few CBM ones, create redmine issues for the rest
UInt_t unexpectedOverlaps {0};
......@@ -136,6 +285,37 @@ void check_overlaps(TString dataset = "test")
gGeoManager = (TGeoManager*) f->Get("FAIRGeom");
if ("" != alignment_matrices) {
std::cout << " Applying alignment matrices from file " << alignment_matrices << std::endl;
// Define the basic structure which needs to be filled with information
// This structure is stored in the output file and later passed to the
// FairRoot framework to do the (miss)alignment
std::map<std::string, TGeoHMatrix>* matrices {nullptr};
// read matrices from disk
TFile* misalignmentMatrixRootfile = new TFile(alignment_matrices, "READ");
if (misalignmentMatrixRootfile->IsOpen()) {
gDirectory->GetObject("MisalignMatrices", matrices);
misalignmentMatrixRootfile->Close();
}
else {
std::cout << "Could not open file " << alignment_matrices << "\n Exiting";
return;
}
if (matrices) {
geo_ci::FairAlignmentHandler* handler = new geo_ci::FairAlignmentHandler();
handler->AddAlignmentMatrices(*matrices, false);
handler->AlignGeometry();
delete handler;
}
else {
std::cout << "Alignment required but no matrices found. \n Exiting";
return;
}
}
gGeoManager->CheckOverlaps(0.0001);
TIter next(gGeoManager->GetListOfOverlaps());
TGeoOverlap* ov;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment