CMS 3D CMS Logo

DDAngular.cc
Go to the documentation of this file.
15 
16 #include <cmath>
17 #include <memory>
18 
19 using namespace geant_units::operators;
20 
21 class DDAngular : public DDAlgorithm
22 {
23 public:
25  : m_n( 1 ),
26  m_startCopyNo( 1 ),
27  m_incrCopyNo( 1 ),
28  m_startAngle( 0. ),
29  m_rangeAngle( 360._deg ),
30  m_radius( 0. ),
31  m_delta( 0. )
32  {}
33 
34  void initialize( const DDNumericArguments & nArgs,
35  const DDVectorArguments & vArgs,
36  const DDMapArguments & mArgs,
37  const DDStringArguments & sArgs,
38  const DDStringVectorArguments & vsArgs ) override;
39 
40  void execute( DDCompactView& cpv ) override;
41 
42 private:
43  DD3Vector fUnitVector( double theta, double phi );
44  int m_n; //Number of copies
45  int m_startCopyNo; //Start Copy number
46  int m_incrCopyNo; //Increment in Copy number
47  double m_startAngle; //Start angle
48  double m_rangeAngle; //Range in angle
49  double m_radius; //Radius
50  double m_delta; //Increment in phi
51  std::vector<double> m_center; //Phi values
52  std::vector<double> m_rotateSolid; //Rotation of the solid values
53 
54  std::string m_idNameSpace; //Namespace of this and ALL sub-parts
55  std::pair<std::string, std::string> m_childNmNs; //Child name
56  //Namespace of the child
57 
58  DDRotationMatrix m_solidRot; //Rotation of the solid
59 };
60 
61 void
63  const DDVectorArguments & vArgs,
64  const DDMapArguments & ,
65  const DDStringArguments & sArgs,
66  const DDStringVectorArguments & )
67 {
68  m_n = int(nArgs["N"]);
69  m_startCopyNo = int(nArgs["StartCopyNo"]);
70  m_incrCopyNo = int(nArgs["IncrCopyNo"]);
71  m_rangeAngle = nArgs["RangeAngle"];
72  m_startAngle = nArgs["StartAngle"];
73  m_radius = nArgs["Radius"];
74  m_center = vArgs["Center"];
75  m_rotateSolid = vArgs["RotateSolid"];
76 
77  m_solidRot = DDRotationMatrix();
78 
79  if( std::abs( m_rangeAngle - 360.0_deg ) < 0.001_deg )
80  {
81  m_delta = m_rangeAngle / double( m_n );
82  }
83  else
84  {
85  if( m_n > 1 )
86  {
87  m_delta = m_rangeAngle / double( m_n - 1 );
88  }
89  else
90  {
91  m_delta = 0.;
92  }
93  }
94 
95  LogDebug( "DDAlgorithm" ) << "DDAngular: Parameters for position"
96  << "ing:: n " << m_n << " Start, Range, Delta "
97  << convertRadToDeg( m_startAngle ) << " "
98  << convertRadToDeg( m_rangeAngle ) << " " << convertRadToDeg( m_delta )
99  << " Radius " << m_radius << " Centre " << m_center[0]
100  << ", " << m_center[1] << ", " << m_center[2];
101 
102  //======= collect data concerning the rotation of the solid
103  using sz_type = std::map<std::string, std::vector<double> >::mapped_type::size_type;
104  sz_type sz = m_rotateSolid.size();
105  if( sz%3 )
106  {
107  LogDebug( "DDAlgorithm" ) << "\trotateSolid must occur 3*n times (defining n subsequent rotations)\n"
108  << "\t currently it appears " << sz << " times!\n";
109  }
110  for( sz_type i = 0; i < sz; i += 3 )
111  {
112  if(( m_rotateSolid[i] > 180._deg ) || ( m_rotateSolid[i] < 0._deg ))
113  {
114  LogDebug( "DDAlgorithm" ) << "\trotateSolid \'theta\' must be in range [0,180*deg]\n"
115  << "\t currently it is " << convertRadToDeg( m_rotateSolid[i] )
116  << "*deg in rotateSolid[" << double(i) << "]!\n";
117  }
118  DDAxisAngle temp( fUnitVector( m_rotateSolid[i], m_rotateSolid[i + 1] ),
119  m_rotateSolid[i + 2] );
120  LogDebug( "DDAlgorithm" ) << " rotsolid[" << i << "] axis=" << temp.Axis() << " rot.angle=" << convertRadToDeg( temp.Angle() );
121  m_solidRot = temp * m_solidRot;
122  }
123 
124  m_idNameSpace = DDCurrentNamespace::ns();
125  m_childNmNs = DDSplit( sArgs["ChildName"] );
126  if( m_childNmNs.second.empty())
127  m_childNmNs.second = DDCurrentNamespace::ns();
128 
129  DDName parentName = parent().name();
130  LogDebug( "DDAlgorithm" ) << "DDAngular: Parent " << parentName
131  << "\tChild " << m_childNmNs.first << "\tNameSpace "
132  << m_childNmNs.second;
133 }
134 
135 void
137 {
138  DDName mother = parent().name();
139  DDName ddname( m_childNmNs.first, m_childNmNs.second );
140  double theta = 90._deg;
141  int copy = m_startCopyNo;
142  double phi = m_startAngle;
143 
144  for( int i = 0; i < m_n; ++i )
145  {
146  double phix = phi;
147  double phiy = phix + 90._deg;
148  double phideg = convertRadToDeg( phix );
149 
150  std::string rotstr = m_childNmNs.first + "_" + std::to_string( phideg * 10.);
151  DDRotation rotation = DDRotation( DDName( rotstr, m_idNameSpace ));
152  if( !rotation )
153  {
154  LogDebug( "DDAlgorithm" ) << "DDAngular: Creating a new "
155  << "rotation: " << rotstr << "\t90., "
156  << convertRadToDeg( phix ) << ", 90.,"
157  << convertRadToDeg( phiy ) << ", 0, 0";
158 
159  rotation = DDrot( DDName( rotstr, m_idNameSpace ),
160  std::make_unique<DDRotationMatrix>( *DDcreateRotationMatrix( theta, phix, theta, phiy,
161  0., 0. ) * m_solidRot ));
162  }
163 
164  double xpos = m_radius * cos( phi ) + m_center[0];
165  double ypos = m_radius * sin( phi ) + m_center[1];
166  double zpos = m_center[2];
167  DDTranslation tran( xpos, ypos, zpos );
168 
169  cpv.position( ddname, mother, copy, tran, rotation );
170  LogDebug( "DDAlgorithm" ) << "DDAngular: child " << m_childNmNs.second << ":" << m_childNmNs.first << " number "
171  << copy << " positioned in " << mother << " at "
172  << tran << " with " << rotation << "\n";
173  copy += m_incrCopyNo;
174  phi += m_delta;
175  }
176 }
177 
178 DD3Vector
179 DDAngular::fUnitVector( double theta, double phi )
180 {
181  return DD3Vector( cos( phi ) * sin( theta ),
182  sin( phi ) * sin( theta ),
183  cos( theta ));
184 }
185 
186 DEFINE_EDM_PLUGIN( DDAlgorithmFactory, DDAngular, "global:DDAngular");
#define LogDebug(id)
static AlgebraicMatrix initialize()
def copy(args, dbName)
double m_radius
Definition: DDAngular.cc:49
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
ROOT::Math::Rotation3D DDRotationMatrix
A DDRotationMatrix is currently implemented with a ROOT Rotation3D.
Geom::Theta< T > theta() const
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:15
constexpr NumType convertRadToDeg(NumType radians)
Definition: GeantUnits.h:98
void initialize(const DDNumericArguments &nArgs, const DDVectorArguments &vArgs, const DDMapArguments &mArgs, const DDStringArguments &sArgs, const DDStringVectorArguments &vsArgs) override
Definition: DDAngular.cc:62
static std::string & ns()
DD3Vector fUnitVector(double theta, double phi)
Definition: DDAngular.cc:179
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:80
uint16_t size_type
DDRotationMatrix m_solidRot
Definition: DDAngular.cc:58
double m_delta
Definition: DDAngular.cc:50
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDTranslation.h:7
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:68
void execute(DDCompactView &cpv) override
Definition: DDAngular.cc:136
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DD3Vector
A DD Translation is currently implemented with Root Vector3D.
Definition: DDTranslation.h:6
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int m_incrCopyNo
Definition: DDAngular.cc:46
std::vector< double > m_rotateSolid
Definition: DDAngular.cc:52
DDRotation DDrot(const DDName &name, std::unique_ptr< DDRotationMatrix > rot)
Definition of a uniquely identifiable rotation matrix named by DDName name.
Definition: DDRotation.cc:80
std::unique_ptr< DDRotationMatrix > DDcreateRotationMatrix(double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ)
create a new DDRotationMatrix in the GEANT3 style.
Definition: DDRotation.cc:149
std::vector< double > m_center
Definition: DDAngular.cc:51
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DD3Vector
Definition: DDAngular.cc:15
std::string m_idNameSpace
Definition: DDAngular.cc:54
double m_rangeAngle
Definition: DDAngular.cc:48
void position(const DDLogicalPart &self, const DDLogicalPart &parent, const std::string &copyno, const DDTranslation &trans, const DDRotation &rot, const DDDivision *div=0)
std::pair< std::string, std::string > m_childNmNs
Definition: DDAngular.cc:55
#define DEFINE_EDM_PLUGIN(factory, type, name)
std::pair< std::string, std::string > DDSplit(const std::string &n)
split into (name,namespace), separator = &#39;:&#39;
Definition: DDSplit.cc:3
ROOT::Math::AxisAngle DDAxisAngle
int m_startCopyNo
Definition: DDAngular.cc:45
double m_startAngle
Definition: DDAngular.cc:47