Skip to content
Snippets Groups Projects
Commit 1ef83156 authored by Nikiforos Nikiforou's avatar Nikiforos Nikiforou
Browse files

Actually adding GenericSurfaceInstaller.cpp

parent 4e6f1e26
No related branches found
No related tags found
No related merge requests found
//==========================================================================
// Surface installer plugin for generic sliced detector drivers
//--------------------------------------------------------------------------
// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
// All rights reserved.
//
// For the licensing terms see $DD4hepINSTALL/LICENSE.
// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
//
// Author : N. Nikiforou, adapted from DD4hep/SiTrackerBarrel_surfaces.cpp
// by M. Frank. Originally part of the lcgeo package
//==========================================================================
/** \addtogroup SurfacePlugin
* @{
* \package DD4hep_GenericSurfaceInstallerPlugin
* \brief Plugin to install measurement surfaces on a generic sliced detector
*
* Takes up to 13 arguments:
* - dimension: A property of the surface that determines whether the resulting
* measurement is 1-D, e.g. strips (dimension=1) or 2-D, e.g. pixels (dimension=2)
* - u_x, u_y, and u_z The x,y, and z components of the u vector, usually associated
* with the "good" (i.e. best resolution) measurement direction
* - v_x, v_y, and v_z The x,y, and z components of the v vector, usually associated
* with the "bad" (i.e. worst resolution) measurement direction
* - n_x, n_y, and n_z The x,y, and z components of the vector perpendicular to the surface
* plane and usually pointing outwards of the detector.
* - o_x, o_y, and o_z The x,y, and z components of the origin vector, used to shift the origin
* of the surface from where it is placed within the volume (usually in the center
* of a sensitive volume.
*
* All the arguments are conveniently initialized to zero by default,
* therefore only the non-zero components need to be provided.
*
* The plugin assumes boxes are stacked along one of the primary axes, x,y or z
* The normal vector (n) must be along one of the axes (i.e. only one non-zero
* component). The inner/outer thicknesses are calculated according to n.
*
* Note: Assumes module and component volumes are boxes. For Trapezoids,
* a fitting box is built around the trapezoid which means dx1=dx2=dx1 and
* dy1=dy2=dy. This is in principle fine, since we only access the thicknesses
* (DY in the TrackerEncapSurfacePlugin example) which is supposed to be the same
* @}
*/
namespace {
struct UserData {
int dimension ;
double uvector[3];
double vvector[3];
double nvector[3];
double ovector[3];
};
}
// Framework include files
#define SURFACEINSTALLER_DATA UserData
#define DD4HEP_USE_SURFACEINSTALL_HELPER DD4hep_GenericSurfaceInstallerPlugin
#include "DD4hep/SurfaceInstaller.h"
namespace{
template <> void Installer<UserData>::handle_arguments(int argc, char** argv) {
//Initialize defaults to zero
data.dimension=0;
data.uvector[0]=0.;
data.uvector[1]=0.;
data.uvector[2]=0.;
data.vvector[0]=0.;
data.vvector[1]=0.;
data.vvector[2]=0.;
data.nvector[0]=0.;
data.nvector[1]=0.;
data.nvector[2]=0.;
data.ovector[0]=0.;
data.ovector[1]=0.;
data.ovector[2]=0.;
for(int i=0; i<argc; ++i) {
double value = -1;
char* ptr = ::strchr(argv[i],'=');
if ( ptr ) {
std::string name( argv[i] , ptr ) ;
value = DD4hep::Geometry::_toDouble(++ptr);
std::cout << "DD4hep_GenericSurfaceInstallerPlugin: argument[" << i << "] = " << name
<< " = " << value << std::endl;
if( name=="dimension" ) data.dimension = value ;
if( name=="u_x" ) data.uvector[0]=value ;
if( name=="u_y" ) data.uvector[1]=value ;
if( name=="u_z" ) data.uvector[2]=value ;
if( name=="v_x" ) data.vvector[0]=value ;
if( name=="v_y" ) data.vvector[1]=value ;
if( name=="v_z" ) data.vvector[2]=value ;
if( name=="n_x" ) data.nvector[0]=value ;
if( name=="n_y" ) data.nvector[1]=value ;
if( name=="n_z" ) data.nvector[2]=value ;
if( name=="o_x" ) data.ovector[0]=value ;
if( name=="o_y" ) data.ovector[1]=value ;
if( name=="o_z" ) data.ovector[2]=value ;
}
}
std::cout <<"DD4hep_GenericSurfaceInstallerPlugin: vectors: ";
std::cout <<"u( "<<data.uvector[0]<<" , "<<data.uvector[1]<<" , "<<data.uvector[2]<<") ";
std::cout <<"v( "<<data.vvector[0]<<" , "<<data.vvector[1]<<" , "<<data.vvector[2]<<") ";
std::cout <<"n( "<<data.nvector[0]<<" , "<<data.nvector[1]<<" , "<<data.nvector[2]<<") ";
std::cout <<"o( "<<data.ovector[0]<<" , "<<data.ovector[1]<<" , "<<data.ovector[2]<<") "<<std::endl;
}
/// Install measurement surfaces
template <typename UserData>
void Installer<UserData>::install(DetElement component, PlacedVolume pv) {
Volume comp_vol = pv.volume();
if ( comp_vol.isSensitive() ) {
Volume mod_vol = parentVolume(component);
//FIXME: WHAT IF TRAPEZOID? Should work if trapezoid since it will fit minimal box and dy1=dy2=dy
DD4hep::Geometry::Box mod_shape(mod_vol.solid()), comp_shape(comp_vol.solid());
if ( !comp_shape.isValid() || !mod_shape.isValid() ) {
invalidInstaller("DD4hep_GenericSurfaceInstallerPlugin: Components and/or modules are not boxes -- invalid shapes");
}else if ( !handleUsingCache(component,comp_vol) ) {
const double* trans = placementTranslation(component);
double half_module_thickness = 0.;
double sensitive_z_position = 0.;
if (data.nvector[0] !=0 && data.nvector[1] ==0 && data.nvector[2] ==0){
half_module_thickness = mod_shape->GetDX();
sensitive_z_position = data.nvector[0]>0 ? trans[0] : -trans[0];
}else if (data.nvector[1] !=0 && data.nvector[0] ==0 && data.nvector[2] ==0){
half_module_thickness = mod_shape->GetDY();
sensitive_z_position = data.nvector[1]>0 ? trans[1] : -trans[1];
}else if (data.nvector[2] !=0 && data.nvector[0] ==0 && data.nvector[1] ==0){
half_module_thickness = mod_shape->GetDZ();
sensitive_z_position = data.nvector[2]>0 ? trans[2] : -trans[2];
} else {
throw std::runtime_error("**** DD4hep_GenericSurfaceInstallerPlugin: normal vector unsupported! It has to be "
"perpenidcular to one of the box sides, i.e. only one non-zero component.") ;
}
double inner_thickness = half_module_thickness + sensitive_z_position;
double outer_thickness = half_module_thickness - sensitive_z_position;
//Surface is placed at the center of the volume, no need to shift origin
//Make sure u,v,n form a right-handed coordinate system, v along the final z
Vector3D u(data.uvector[0],data.uvector[1],data.uvector[2]);
Vector3D v(data.vvector[0],data.vvector[1],data.vvector[2]);
Vector3D n(data.nvector[0],data.nvector[1],data.nvector[2]);
Vector3D o(data.ovector[0],data.ovector[1],data.ovector[2]);
Type type( Type::Sensitive ) ;
if( data.dimension == 1 ) {
type.setProperty( Type::Measurement1D , true ) ;
} else if( data.dimension != 2 ) {
throw std::runtime_error("**** DD4hep_GenericSurfaceInstallerPlugin: no or wrong "
"'dimension' argument given - has to be 1 or 2") ;
}
VolPlane surf(comp_vol, type, inner_thickness, outer_thickness, u, v, n, o);
addSurface(component,surf);
}
}
}
}// namespace
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