|
DD4hep
1.30.0
Detector Description Toolkit for High Energy Physics
|
Go to the documentation of this file. 1 #ifndef DDREC_DCH_INFO_H
2 #define DDREC_DCH_INFO_H
10 namespace dd4hep {
namespace rec {
136 auto Pitch_z0 =
database.at(nlayer).Pitch_z0(r_z0);
164 return (1 ==
layer%2);
173 return TMath::TwoPi()*r_z0/
nwires;
197 inline std::ostream&
operator<<( std::ostream& io ,
const DCH_info& d ){d.Show_DCH_info_database(io);
return io;}
204 auto ff_check_positive_parameter = [](
double p, std::string pname) ->
void {
205 if(p<=0)
throw std::runtime_error(Form(
"DCH: %s must be positive",pname.c_str()));
208 ff_check_positive_parameter(this->
rin ,
"inner radius");
209 ff_check_positive_parameter(this->
rout ,
"outer radius");
210 ff_check_positive_parameter(this->
Lhalf,
"half length" );
216 ff_check_positive_parameter(this->
ncell0,
"ncells in the first layer" );
217 ff_check_positive_parameter(this->
ncell_increment,
"ncells increment per superlayer" );
223 throw std::runtime_error(
"dch_ncell_per_sector is not divisor of dch_ncell0 or dch_ncell_increment");
225 ff_check_positive_parameter(this->
nsuperlayers,
"number of superlayers" );
232 ff_check_positive_parameter(this->
first_width,
"width of first layer cells" );
233 ff_check_positive_parameter(this->
first_sense_r,
"radius of first layer cells" );
239 layer1_info.
layer = 1;
253 for(
int ilayer = 2; ilayer<= this->
nlayers; ++ilayer)
259 layer_info.
layer = ilayer;
264 const auto& previousLayer = this->
database.at(ilayer-1);
268 double h = previousLayer.height_z0;
269 double ru = previousLayer.radius_fuw_z0;
270 double rd = previousLayer.radius_fdw_z0;
275 layer_info.
height_z0 = TMath::TwoPi()*ru/(0.5*layer_info.
nwires - TMath::Pi());
287 throw std::runtime_error(
"fabs(l.width_z0 - l.height_z0)>1e-4");
291 this->
database.emplace(ilayer, layer_info);
294 std::cout <<
"\t+ Total size of DCH database = " <<
database.size() << std::endl;
301 oss <<
"Global parameters of DCH:\n";
302 oss <<
"\tGas, half length/mm = " <<
Lhalf/dd4hep::mm <<
'\n';
303 oss <<
"\tGas, radius in/mm = " <<
rin/dd4hep::mm <<
'\n';
304 oss <<
"\tGas, radius out/mm = " <<
rout/dd4hep::mm<<
'\n';
308 oss <<
"\tTwist angle (2*alpha) / deg = " <<
twist_angle/dd4hep::deg <<
'\n';
312 oss <<
"\tN layers = " <<
nlayers <<
'\n';
314 oss <<
"\tN cells layer1 = " <<
ncell0 <<
'\n';
315 oss <<
"\tN cells increment per superlayer = " <<
ncell_increment <<
'\n';
318 oss <<
"Layer parameters of DCH:\n";
322 <<
"\t" <<
"height_z0/mm"
323 <<
"\t" <<
"width_z0/mm"
324 <<
"\t" <<
"radius_fdw_z0/mm"
325 <<
"\t" <<
"radius_sw_z0/mm"
326 <<
"\t" <<
"radius_fuw_z0/mm"
327 <<
"\t" <<
"stereoangle_z0/deg"
328 <<
"\t" <<
"Pitch_z0/mm"
329 <<
"\t" <<
"radius_sw_zLhalf/mm"
330 <<
"\t" <<
"WireLength/mm"
331 <<
"\n" << std::endl;
335 oss <<
"\nDatabase empty\n";
339 for(
const auto& [nlayer, l] :
database )
344 <<
"\t" << l.height_z0/dd4hep::mm
345 <<
"\t" << l.width_z0/dd4hep::mm
346 <<
"\t" << l.radius_fdw_z0/dd4hep::mm
347 <<
"\t" << l.radius_sw_z0/dd4hep::mm
348 <<
"\t" << l.radius_fuw_z0/dd4hep::mm
349 <<
"\t" << l.StereoSign()*this->
stereoangle_z0(l.radius_sw_z0)/dd4hep::deg
350 <<
"\t" << l.Pitch_z0(l.radius_sw_z0)/dd4hep::mm
352 <<
"\t" << this->
WireLength(l.layer,l.radius_sw_z0)/dd4hep::mm
353 <<
"\n" << std::endl;
364 auto& l = this->
database.at(ilayer);
370 int stereosign = l.StereoSign();
371 double rz0 = l.radius_sw_z0;
374 double kappa = (1. / this->
Lhalf) * tan(dphi / 2);
381 double y1 = -stereosign * rz0 * kappa * this->
Lhalf;
382 double z1 = -this->
Lhalf;
384 TVector3 p1(x1, y1, z1);
388 double y2 = stereosign * rz0 * kappa * this->
Lhalf;
389 double z2 = this->
Lhalf;
391 TVector3 p2(x2, y2, z2);
400 return (p2 - p1).Unit();
404 auto& l = this->
database.at(ilayer);
405 double rz0 = l.radius_sw_z0;
406 TVector3 p1(rz0, 0, 0);
414 auto& l = this->
database.at(ilayer);
415 int ncells = l.nwires / 2;
416 double phistep = TMath::TwoPi() / ncells;
417 double phi_z0 = (nphi + 0.25 * (l.layer % 2)) * phistep;
432 TVector3 a_minus_p = a - hit_position;
433 double a_minus_p_dot_n = a_minus_p.Dot(n);
434 TVector3 scaled_n = a_minus_p_dot_n * n;
436 return (a_minus_p - scaled_n);
441 #endif // DDREC_DCH_INFO_H
TVector3 Calculate_wire_z0_point(int ilayer, int nphi) const
DCH_layer CalculateILayerFromCellIDFields(int layer, int superlayer) const
void Set_ncell_increment(int _ncell_increment)
DCH_angle_t stereoangle_zLhalf(DCH_length_t r_zLhalf) const
tan(stereoangle) = R(z=L/2) / (L/2) * sin( twist_angle/2)
int Get_nsuperlayer_minus_1(int ilayer)
DCH_length_t Pitch_z0(DCH_length_t r_z0) const
separation between wires (along the circle)
TVector3 Calculate_hitpos_to_wire_vector(int ilayer, int nphi, const TVector3 &hit_position) const
int Get_ncells(int ilayer)
bool IsValid() const
Check if outer volume is not zero (0 < Lhalf*rout), and if the database was filled.
void Set_ncell0(int _ncell0)
int ncell_per_sector
cells within the same layer may be grouped into sectors, not in use atm
DCH_length_t first_sense_r
Cell radius for the first layer.
void Set_first_sense_r(double _first_sense_r)
DCH_layer nlayersPerSuperlayer
input number of layers in each superlayer
void Set_lhalf(DCH_length_t _dch_Lhalf)
double DCH_length_t
tpye for lengths
DCH_length_t guard_outer_r_at_zL2
Outer guard wires radius.
void BuildLayerDatabase()
double DCH_angle_t
tpye for angles
int ncell0
number of cells of first layer
DCH_length_t Lhalf
Half length of the active volume.
void Set_nlayersPerSuperlayer(int _nlayersPerSuperlayer)
bool IsDatabaseEmpty() const
void Set_ncell_per_sector(int _ncell_per_sector)
bool IsStereoPositive() const
double first_width
Cell width for the first layer.
int StereoSign() const
calculate sign based on IsStereoPositive
int DCH_layer
type for layer number
DCH_length_t WireLength(int nlayer, DCH_length_t r_z0) const
WireLength = 2*dch_Lhalf/cos(atan(Pitch_z0(r_z0)/(2*dch_Lhalf)))/cos(stereoangle_z0(r_z0))
DCH_layer layer
layer number
void Set_nsuperlayers(int _nsuperlayers)
DCH_layer nlayers
Calculated as dch_nlayersPerSuperlayer * dch_nsuperlayers.
double Calculate_wire_phi_z0(int ilayer, int nphi) const
DCH_length_t radius_sw_z0
radius (cylindral coord) of sensitive wire
DCH_length_t rin
Inner radius of the active volume.
DCH_length_t radius_fdw_z0
radius (cylindral coord) of 'down' field wires
void Set_first_width(double _first_width)
double width_z0
cell parameter
DCH_length_t guard_inner_r_at_z0
Inner guard wires radius.
void Set_twist_angle(DCH_length_t _dch_twist_angle)
void Set_guard_rin_at_z0(DCH_length_t _dch_rin_z0_guard)
void Set_rin(DCH_length_t _dch_rin)
std::map< DCH_layer, DCH_info_layer > database
map to store parameters for each layer
DCH_length_t radius_fuw_z0
radius (cylindral coord) of 'up' field wires
int nwires
2x number of cells in that layer
Internal helper struct for defining the layer layout.
DCH_angle_t stereoangle_z0(DCH_length_t r_z0) const
tan(stereoangle) = R(z=0) / (L/2) * tan( twist_angle/2)
Namespace for the AIDA detector description toolkit.
StructExtension< DCH_info_struct > DCH_info
std::ostream & operator<<(std::ostream &io, const DCH_info &d)
TVector3 Calculate_wire_vector_ez(int ilayer, int nphi) const
void Show_DCH_info_database(std::ostream &io) const
double height_z0
cell parameter
void Set_guard_rout_at_zL2(DCH_length_t _dch_rout_zL2_guard)
DCH_length_t rout
Outer radius of the active volume.
DCH_length_t Radius_zLhalf(DCH_length_t r_z0) const
Calculate radius at z=L/2 given at z=0.
DCH_angle_t Get_cell_phi_angle(int ilayer, int nphi)
DCH_angle_t Get_phi_width(int ilayer)
Get phi width for the twisted tube and the step (phi distance between cells)
void Set_rout(DCH_length_t _dch_rout)