-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Convert Geant4 logical and physical volumes (#1170)
* Add logical volume converter * Add physical volume converter * Add test for physical volume converter * Add backdoor option to ignore fatal exceptions in logic converter * Add additional tests * Create a NoTransformation in the simple case * Check for identity and remove now-unneeded function * Remove gendered hierarchy names * Add scale factor to volume converter * Add helper for genericizing pointers * IWYU * Use material instead of physics-based material * Incorporate review feedback
- Loading branch information
Showing
21 changed files
with
1,286 additions
and
50 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
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,126 @@ | ||
//----------------------------------*-C++-*----------------------------------// | ||
// Copyright 2023-2024 UT-Battelle, LLC, and other Celeritas developers. | ||
// See the top-level COPYRIGHT file for details. | ||
// SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
//---------------------------------------------------------------------------// | ||
//! \file orange/g4org/LogicalVolumeConverter.cc | ||
//---------------------------------------------------------------------------// | ||
#include "LogicalVolumeConverter.hh" | ||
|
||
#include <G4LogicalVolume.hh> | ||
#include <G4Material.hh> | ||
#include <G4MaterialCutsCouple.hh> | ||
#include <G4VSolid.hh> | ||
|
||
#include "corecel/Assert.hh" | ||
#include "corecel/io/Logger.hh" | ||
#include "corecel/sys/Environment.hh" | ||
#include "geocel/GeantGeoUtils.hh" | ||
|
||
#include "SolidConverter.hh" | ||
#include "Volume.hh" | ||
|
||
namespace celeritas | ||
{ | ||
namespace g4org | ||
{ | ||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Construct with solid conversion helper. | ||
*/ | ||
LogicalVolumeConverter::LogicalVolumeConverter(SolidConverter& convert_solid) | ||
: convert_solid_(convert_solid) | ||
{ | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Convert a Geant4 logical volume to an ORANGE LogicalVolume. | ||
* | ||
* This uses a cache to look up any previously converted volume. | ||
*/ | ||
auto LogicalVolumeConverter::operator()(arg_type lv) -> result_type | ||
{ | ||
SPLV result; | ||
auto [cache_iter, inserted] = cache_.insert({&lv, {}}); | ||
if (inserted || cache_iter->second.expired()) | ||
{ | ||
// First time converting the volume, or it has expired | ||
result = this->construct_impl(lv); | ||
cache_iter->second = result; | ||
} | ||
else | ||
{ | ||
result = cache_iter->second.lock(); | ||
} | ||
|
||
CELER_ENSURE(result); | ||
return {result, inserted}; | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Convert the raw logical volume without processing any daughters. | ||
*/ | ||
auto LogicalVolumeConverter::construct_impl(arg_type g4lv) -> SPLV | ||
{ | ||
auto result = std::make_shared<LogicalVolume>(); | ||
|
||
// Save Geant4 volume pointer for later mappings | ||
result->g4lv = &g4lv; | ||
|
||
// Save name | ||
result->name = g4lv.GetName(); | ||
if (result->name.find("0x") == std::string::npos) | ||
{ | ||
// No pointer address: add one | ||
result->name = make_gdml_name(g4lv); | ||
} | ||
|
||
// Save material ID | ||
// NOTE: this is *not* the physics material ("cut couple") | ||
if (auto* mat = g4lv.GetMaterial()) | ||
{ | ||
result->material_id | ||
= MaterialId{static_cast<size_type>(mat->GetIndex())}; | ||
} | ||
|
||
// Convert solid | ||
try | ||
{ | ||
result->solid = convert_solid_(*g4lv.GetSolid()); | ||
} | ||
catch (celeritas::RuntimeError const& e) | ||
{ | ||
CELER_LOG(error) << "Failed to convert solid type '" | ||
<< g4lv.GetSolid()->GetEntityType() << "' named '" | ||
<< g4lv.GetSolid()->GetName() | ||
<< "': " << e.details().what; | ||
result->solid = this->convert_solid_.to_sphere(*g4lv.GetSolid()); | ||
CELER_LOG(warning) << "Replaced unknown solid with sphere (" | ||
<< to_string(*result->solid) << ")"; | ||
CELER_LOG(info) << "Unsupported solid belongs to logical volume " | ||
<< PrintableLV{&g4lv}; | ||
} | ||
catch (celeritas::DebugError const& e) | ||
{ | ||
CELER_LOG(error) << "Failed to convert solid type '" | ||
<< g4lv.GetSolid()->GetEntityType() << "' named '" | ||
<< g4lv.GetSolid()->GetName(); | ||
CELER_LOG(info) << "Unsupported solid belongs to logical volume " | ||
<< PrintableLV{&g4lv}; | ||
|
||
static bool const allow_errors | ||
= !celeritas::getenv("G4ORG_ALLOW_ERRORS").empty(); | ||
if (!allow_errors) | ||
{ | ||
throw; | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
} // namespace g4org | ||
} // namespace celeritas |
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,68 @@ | ||
//----------------------------------*-C++-*----------------------------------// | ||
// Copyright 2023-2024 UT-Battelle, LLC, and other Celeritas developers. | ||
// See the top-level COPYRIGHT file for details. | ||
// SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
//---------------------------------------------------------------------------// | ||
//! \file orange/g4org/LogicalVolumeConverter.hh | ||
//---------------------------------------------------------------------------// | ||
#pragma once | ||
|
||
#include <unordered_map> | ||
|
||
#include "geocel/Types.hh" | ||
#include "orange/orangeinp/ObjectInterface.hh" | ||
|
||
//---------------------------------------------------------------------------// | ||
// Forward declarations | ||
//---------------------------------------------------------------------------// | ||
|
||
class G4LogicalVolume; | ||
|
||
namespace celeritas | ||
{ | ||
namespace g4org | ||
{ | ||
//---------------------------------------------------------------------------// | ||
struct LogicalVolume; | ||
class SolidConverter; | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Convert a Geant4 base LV to an ORANGE temporary LV. | ||
* | ||
* This does not convert or add any of the daughters, which must be placed as | ||
* physical volumes. | ||
*/ | ||
class LogicalVolumeConverter | ||
{ | ||
public: | ||
//!@{ | ||
//! \name Type aliases | ||
using arg_type = G4LogicalVolume const&; | ||
using SPLV = std::shared_ptr<LogicalVolume>; | ||
using result_type = std::pair<SPLV, bool>; | ||
//!@} | ||
|
||
public: | ||
explicit LogicalVolumeConverter(SolidConverter& convert_solid); | ||
|
||
// Convert a volume, return result plus insertion | ||
result_type operator()(arg_type); | ||
|
||
private: | ||
using WPLV = std::weak_ptr<LogicalVolume>; | ||
|
||
//// DATA //// | ||
|
||
SolidConverter& convert_solid_; | ||
std::unordered_map<G4LogicalVolume const*, WPLV> cache_; | ||
|
||
//// HELPER FUNCTIONS //// | ||
|
||
// Convert an LV that's not in the cache | ||
SPLV construct_impl(arg_type); | ||
}; | ||
|
||
//---------------------------------------------------------------------------// | ||
} // namespace g4org | ||
} // namespace celeritas |
Oops, something went wrong.