/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus * * MAUS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MAUS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MAUS. If not, see . * */ #include "src/common_cpp/Simulation/GeometryNavigator.hh" #include #include "CLHEP/Units/SystemOfUnits.h" #include "src/common_cpp/Utils/Exception.hh" namespace MAUS { GeometryNavigator::GeometryNavigator() : _global_volume(NULL), _navigator(NULL), _touchable_history(NULL), _current_position(), _current_volume(NULL), _current_material(NULL) { } GeometryNavigator::~GeometryNavigator() { if (_touchable_history) { delete _touchable_history; _touchable_history = NULL; _current_volume = NULL; _current_material = NULL; } if (_navigator) { delete _navigator; _navigator = NULL; } _global_volume = NULL; // Not ours so don't delete } void GeometryNavigator::Initialise(G4VPhysicalVolume* phys_vol) { if (!phys_vol) { throw(Exception(Exception::recoverable, std::string("No physical volume could be found "), "GeometryNavigator::GeometryNavigator()")); } _global_volume = phys_vol; if (_navigator != NULL) { delete _navigator; _navigator = NULL; } _navigator = new G4Navigator(); _navigator->SetWorldVolume(this->_global_volume); this->_setPoint(G4ThreeVector(0.0, 0.0, 0.0)); } void GeometryNavigator::SetPoint(ThreeVector point) { G4ThreeVector pos = ToG4Vec(point); this->_setPoint(pos); } ThreeVector GeometryNavigator::Step(ThreeVector displacement) { G4ThreeVector disp = ToG4Vec(displacement); return ToMAUSVec(this->_step(disp)); } void GeometryNavigator::_setPoint(G4ThreeVector pos) { if (!_navigator) { throw(Exception(Exception::recoverable, std::string("Navigator not correctly set up. ")+ std::string("Physical volume required"), "GeometryNavigator::_setPoint(G4ThreeVector)")); } _current_position = pos; _navigator->LocateGlobalPointAndSetup(_current_position); if (_touchable_history) { delete _touchable_history; _touchable_history = NULL; } _touchable_history = _navigator->CreateTouchableHistory(); _current_volume = _touchable_history->GetVolume(); _current_material = _current_volume->GetLogicalVolume()->GetMaterial(); } G4ThreeVector GeometryNavigator::_step(G4ThreeVector dir) { _current_position = _current_position + dir; _navigator->LocateGlobalPointAndUpdateTouchable( _current_position, dir, _touchable_history); _current_volume = _touchable_history->GetVolume(); _current_material = _current_volume->GetLogicalVolume()->GetMaterial(); return _current_position; } std::string GeometryNavigator::GetMaterialName() const { return _current_material->GetName(); } bool GeometryNavigator::IsMixture() const { if (_current_material->GetNumberOfElements() > 1) { return true; } else { return false; } } double GeometryNavigator::GetA() const { return _current_material->GetA()/(g/mole); } double GeometryNavigator::GetZ() const { return _current_material->GetZ(); } double GeometryNavigator::GetNuclearInteractionLength() const { // return _current_material->GetNuclearInterLength()/(g/(cm*cm)); return _current_material->GetNuclearInterLength()/cm; } double GeometryNavigator::GetRadiationLength() const { // return _current_material->GetRadlen()/(g/(cm*cm)); return _current_material->GetRadlen()/cm; } double GeometryNavigator::GetDensity() const { return _current_material->GetDensity()/(g/(cm*cm*cm)); } }