18 inline constexpr
T square(
const T&
x ) {
return x*
x; }
26 inline T bind_angle(
const T&
angle )
28 if( angle >=
M_PI )
return angle - 2*
M_PI;
29 else if( angle < -M_PI )
return angle + 2*
M_PI;
38 assert( tileid <
m_tiles.size() );
41 std::array<double,3> master;
42 world_coordinates.GetXYZ( &master[0] );
45 std::array<double,3>
local;
48 return TVector3( &local[0] );
55 assert( tileid <
m_tiles.size() );
58 std::array<double,3>
local;
59 local_coordinates.GetXYZ( &local[0] );
62 std::array<double,3> master;
65 return TVector3( &master[0] );
72 assert( tileid <
m_tiles.size() );
75 std::array<double,3>
local;
76 local_vect.GetXYZ( &local[0] );
79 std::array<double,3> master;
82 return TVector3( &master[0] );
89 assert( tileid <
m_tiles.size() );
92 std::array<double,3> master;
93 world_vect.GetXYZ( &master[0] );
96 std::array<double,3>
local;
99 return TVector3( &local[0] );
110 const auto phi = std::atan2( world_coordinates.y(), world_coordinates.x() );
111 const auto z = world_coordinates.z();
113 for(
size_t itile = 0; itile <
m_tiles.size(); ++itile )
115 const auto& tile =
m_tiles.at(itile);
117 if(
std::abs( z - tile.m_centerZ ) > tile.m_sizeZ/2 )
continue;
118 if(
std::abs( bind_angle(
phi - tile.m_centerPhi ) ) > tile.m_sizePhi/2 )
continue;
130 for(
size_t itile = 0; itile <
m_tiles.size(); ++itile )
137 const auto& tile =
m_tiles.at(itile);
146 if(
std::abs( local_coordinates.z() ) > tile.m_sizeZ/2 )
continue;
162 for(
int i = 0; i < 2; ++i )
165 const TVector3 world_coordinates( hit->
get_x(i), hit->
get_y(i), hit->
get_z(i) );
168 const double delta_radius =
get_r( world_coordinates.x(), world_coordinates.y() ) -
m_radius;
175 const double delta_y = delta_radius - local_coordinates.y();
176 TVector3 new_local_coordinates(
177 local_coordinates.x() + delta_y*local_direction.x()/local_direction.y(),
178 local_coordinates.y() + delta_y,
179 local_coordinates.z() + delta_y*local_direction.z()/local_direction.y() );
183 hit->
set_x(i, new_world_coordinates.x() );
184 hit->
set_y(i, new_world_coordinates.y() );
185 hit->
set_z(i, new_world_coordinates.z() );
205 const auto& tile =
m_tiles.at(tileid);
211 if(
std::abs( local_coordinates.z() ) > tile.m_sizeZ/2 )
return -1;
221 return (
int) std::floor( (local_coordinates.z() + tile.m_sizeZ/2)/
m_pitch );
231 assert( tileid <
m_tiles.size() );
235 return m_tiles[tileid].m_sizeZ;
248 assert( tileid <
m_tiles.size() );
265 assert( tileid <
m_tiles.size() );
268 const auto& tile =
m_tiles[tileid];
276 return TVector3( 0, 0, (0.5+stripnum)*
m_pitch - tile.m_sizeZ/2 );
286 assert( tileid <
m_tiles.size() );
293 out <<
"CylinderGeomMicromegas" << std::endl;
294 out <<
"layer: " <<
m_layer << std::endl;
296 out <<
"drift_direction: " << (
m_drift_direction == MicromegasDefs::DriftDirection::INWARD ?
"INWARD":
"OUTWARD") << std::endl;
297 out <<
"radius: " <<
m_radius <<
"cm" << std::endl;
298 out <<
"thickness: " <<
m_thickness <<
"cm" << std::endl;
299 out <<
"zmin: " <<
m_zmin <<
"cm" << std::endl;
300 out <<
"zmax: " <<
m_zmax <<
"cm" << std::endl;
301 out <<
"pitch: " <<
m_pitch <<
"cm" << std::endl;
308 const auto radius =
get_r( world_coordinates.x(), world_coordinates.y() );
315 assert( tileid <
m_tiles.size() );
316 const auto& tile =
m_tiles[tileid];
322 matrix.RotateZ( tile.m_centerPhi*180./
M_PI - 90 );
325 matrix.SetDx(
m_radius*std::cos( tile.m_centerPhi ) );
326 matrix.SetDy(
m_radius*std::sin( tile.m_centerPhi ) );
327 matrix.SetDz( tile.m_centerZ );