-
Markus Frank authored203fa3b6
AlignmentStack.cpp 6.99 KiB
// $Id: Geant4Setup.cpp 578 2013-05-17 22:33:09Z markus.frank $
//====================================================================
// AIDA Detector description implementation for LCD
//--------------------------------------------------------------------
//
// Author : M.Frank
//
//====================================================================
// Framework include files
#include "DD4hep/LCDD.h"
#include "DD4hep/Objects.h"
#include "DD4hep/Printout.h"
#include "DDAlign/AlignmentStack.h"
using namespace std;
using namespace DD4hep;
using namespace DD4hep::Geometry;
static AlignmentStack* s_alignStack = 0;
/// Fully initializing constructor
AlignmentStack::StackEntry::StackEntry(const DetElement& p, const std::string& placement, const Transform3D& t, double ov, int f)
: detector(p), transform(t), path(placement), overlap(ov), flag(f)
{
}
/// Constructor with partial initialization
AlignmentStack::StackEntry::StackEntry(DetElement element, bool rst, bool rst_children)
: detector(element), transform(), overlap(0.001), flag(0)
{
if ( rst ) flag |= RESET_VALUE;
if ( rst_children ) flag |= RESET_CHILDREN;
if ( detector.isValid() ) path = detector.placementPath();
}
/// Constructor with partial initialization
AlignmentStack::StackEntry::StackEntry(DetElement element, const Transform3D& trafo, bool rst, bool rst_children)
: detector(element), transform(trafo), overlap(0.001), flag(0)
{
flag |= MATRIX_DEFINED;
if ( rst ) flag |= RESET_VALUE;
if ( rst_children ) flag |= RESET_CHILDREN;
if ( detector.isValid() ) path = detector.placementPath();
}
/// Constructor with partial initialization
AlignmentStack::StackEntry::StackEntry(DetElement element, const Position& translation, bool rst, bool rst_children)
: detector(element), transform(translation), overlap(0.001), flag(0)
{
flag |= MATRIX_DEFINED;
if ( rst ) flag |= RESET_VALUE;
if ( rst_children ) flag |= RESET_CHILDREN;
if ( detector.isValid() ) path = detector.placementPath();
}
/// Constructor with partial initialization
AlignmentStack::StackEntry::StackEntry(DetElement element, const RotationZYX& rot, bool rst, bool rst_children)
: detector(element), transform(rot), overlap(0.001), flag(0)
{
flag |= MATRIX_DEFINED;
if ( rst ) flag |= RESET_VALUE;
if ( rst_children ) flag |= RESET_CHILDREN;
if ( detector.isValid() ) path = detector.placementPath();
}
/// Constructor with partial initialization
AlignmentStack::StackEntry::StackEntry(DetElement element, const Position& translation, const RotationZYX& rot, bool rst, bool rst_children)
: detector(element), transform(rot,translation), overlap(0.001), flag(0)
{
flag |= MATRIX_DEFINED;
if ( rst ) flag |= RESET_VALUE;
if ( rst_children ) flag |= RESET_CHILDREN;
if ( detector.isValid() ) path = detector.placementPath();
}
/// Copy constructor
AlignmentStack::StackEntry::StackEntry(const StackEntry& e)
: detector(e.detector), transform(e.transform), path(e.path), overlap(e.overlap), flag(e.flag)
{
}
/// Attach transformation object
AlignmentStack::StackEntry& AlignmentStack::StackEntry::setTransformation(const Transform3D& trafo) {
flag |= MATRIX_DEFINED;
transform = trafo;
return *this;
}
/// Instruct entry to ignore the transformation
AlignmentStack::StackEntry& AlignmentStack::StackEntry::clearTransformation() {
flag &= ~MATRIX_DEFINED;
transform = Transform3D();
return *this;
}
/// Set flag to reset the entry to it's ideal geometrical position
AlignmentStack::StackEntry& AlignmentStack::StackEntry::setReset(bool new_value) {
new_value ? (flag |= RESET_VALUE) : (flag &= ~RESET_VALUE);
return *this;
}
/// Set flag to reset the entry's children to their ideal geometrical position
AlignmentStack::StackEntry& AlignmentStack::StackEntry::setResetChildren(bool new_value) {
new_value ? (flag |= RESET_CHILDREN) : (flag &= ~RESET_CHILDREN);
return *this;
}
/// Set flag to check overlaps
AlignmentStack::StackEntry& AlignmentStack::StackEntry::setOverlapCheck(bool new_value) {
new_value ? (flag |= CHECKOVL_DEFINED) : (flag &= ~CHECKOVL_DEFINED);
return *this;
}
/// Set the precision for the overlap check (otherwise the default is 0.001 cm)
AlignmentStack::StackEntry& AlignmentStack::StackEntry::setOverlapPrecision(double precision) {
flag |= CHECKOVL_DEFINED;
flag |= CHECKOVL_VALUE;
overlap = precision;
return *this;
}
/// Default constructor
AlignmentStack::AlignmentStack()
{
}
/// Default destructor
AlignmentStack::~AlignmentStack() {
destroyObjects(m_stack)();
}
/// Static client accessor
AlignmentStack& AlignmentStack::get() {
if ( s_alignStack ) return *s_alignStack;
throw runtime_error("AlignmentStack> Stack not allocated -- may not be retrieved!");
}
/// Create an alignment stack instance. The creation of a second instance will be refused.
void AlignmentStack::create() {
if ( s_alignStack ) {
throw runtime_error("AlignmentStack> Stack already allocated. Multiple copies are not allowed!");
}
s_alignStack = new AlignmentStack();
}
/// Check existence of alignment stack
bool AlignmentStack::exists() {
return s_alignStack != 0;
}
/// Clear data content and remove the slignment stack
void AlignmentStack::release() {
if ( s_alignStack ) {
delete s_alignStack;
s_alignStack = 0;
return;
}
throw runtime_error("AlignmentStack> Attempt to delete non existing stack.");
}
/// Add a new entry to the cache. The key is the placement path
bool AlignmentStack::insert(const std::string& full_path, StackEntry* entry) {
if ( entry && !full_path.empty() ) {
entry->path = full_path;
return get().add(entry);
}
throw runtime_error("AlignmentStack> Attempt to apply an invalid alignment entry.");
}
/// Add a new entry to the cache. The key is the placement path
bool AlignmentStack::insert(StackEntry* entry) {
return get().add(entry);
}
/// Add a new entry to the cache. The key is the placement path
bool AlignmentStack::add(StackEntry* entry) {
if ( entry && !entry->path.empty() ) {
Stack::const_iterator i = m_stack.find(entry->path);
if ( i == m_stack.end() ) {
m_stack.insert(make_pair(entry->path,entry));
return true;
}
throw runtime_error("AlignmentStack> The entry with path "+entry->path+
" cannot be re-aligned twice in one transaction.");
}
throw runtime_error("AlignmentStack> Attempt to apply an invalid alignment entry.");
}
/// Retrieve an alignment entry of the current stack
auto_ptr<AlignmentStack::StackEntry> AlignmentStack::pop() {
Stack::iterator i = m_stack.begin();
if ( i != m_stack.end() ) {
StackEntry* e = (*i).second;
m_stack.erase(i);
return auto_ptr<StackEntry>(e);
}
throw runtime_error("AlignmentStack> Alignment stack is empty. "
"Cannot pop entries - check size first!");
}
/// Get all pathes to be aligned
vector<const AlignmentStack::StackEntry*> AlignmentStack::entries() const {
vector<const StackEntry*> result;
result.reserve(m_stack.size());
for(Stack::const_iterator i=m_stack.begin(); i != m_stack.end(); ++i)
result.push_back((*i).second);
return result;
}