Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:51:37

0001 #include "DetectorDescription/Core/interface/DDAlgorithm.h"
0002 #include "DetectorDescription/Core/interface/DDAlgorithmFactory.h"
0003 #include "DetectorDescription/Core/interface/DDCompactView.h"
0004 #include "DetectorDescription/Core/interface/DDCurrentNamespace.h"
0005 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
0006 #include "DetectorDescription/Core/interface/DDName.h"
0007 #include "DetectorDescription/Core/interface/DDSplit.h"
0008 #include "DetectorDescription/Core/interface/DDTransform.h"
0009 #include "DetectorDescription/Core/interface/DDRotationMatrix.h"
0010 #include "DetectorDescription/Core/interface/DDTranslation.h"
0011 #include "DetectorDescription/Core/interface/DDTypes.h"
0012 #include "DataFormats/Math/interface/GeantUnits.h"
0013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0014 #include "FWCore/PluginManager/interface/PluginFactory.h"
0015 
0016 #include <cmath>
0017 #include <memory>
0018 
0019 using namespace geant_units::operators;
0020 
0021 class DDAngular : public DDAlgorithm {
0022 public:
0023   DDAngular()
0024       : m_n(1), m_startCopyNo(1), m_incrCopyNo(1), m_startAngle(0.), m_rangeAngle(360._deg), m_radius(0.), m_delta(0.) {}
0025 
0026   void initialize(const DDNumericArguments& nArgs,
0027                   const DDVectorArguments& vArgs,
0028                   const DDMapArguments& mArgs,
0029                   const DDStringArguments& sArgs,
0030                   const DDStringVectorArguments& vsArgs) override;
0031 
0032   void execute(DDCompactView& cpv) override;
0033 
0034 private:
0035   DD3Vector fUnitVector(double theta, double phi);
0036   int m_n;                            //Number of copies
0037   int m_startCopyNo;                  //Start Copy number
0038   int m_incrCopyNo;                   //Increment in Copy number
0039   double m_startAngle;                //Start angle
0040   double m_rangeAngle;                //Range in angle
0041   double m_radius;                    //Radius
0042   double m_delta;                     //Increment in phi
0043   std::vector<double> m_center;       //Phi values
0044   std::vector<double> m_rotateSolid;  //Rotation of the solid values
0045 
0046   std::string m_idNameSpace;                        //Namespace of this and ALL sub-parts
0047   std::pair<std::string, std::string> m_childNmNs;  //Child name
0048                                                     //Namespace of the child
0049 
0050   DDRotationMatrix m_solidRot;  //Rotation of the solid
0051 };
0052 
0053 void DDAngular::initialize(const DDNumericArguments& nArgs,
0054                            const DDVectorArguments& vArgs,
0055                            const DDMapArguments&,
0056                            const DDStringArguments& sArgs,
0057                            const DDStringVectorArguments&) {
0058   m_n = int(nArgs["N"]);
0059   m_startCopyNo = int(nArgs["StartCopyNo"]);
0060   m_incrCopyNo = int(nArgs["IncrCopyNo"]);
0061   m_rangeAngle = nArgs["RangeAngle"];
0062   m_startAngle = nArgs["StartAngle"];
0063   m_radius = nArgs["Radius"];
0064   m_center = vArgs["Center"];
0065   m_rotateSolid = vArgs["RotateSolid"];
0066 
0067   m_solidRot = DDRotationMatrix();
0068 
0069   if (std::abs(m_rangeAngle - 360.0_deg) < 0.001_deg) {
0070     m_delta = m_rangeAngle / double(m_n);
0071   } else {
0072     if (m_n > 1) {
0073       m_delta = m_rangeAngle / double(m_n - 1);
0074     } else {
0075       m_delta = 0.;
0076     }
0077   }
0078 
0079   LogDebug("DDAlgorithm") << "DDAngular: Parameters for position"
0080                           << "ing:: n " << m_n << " Start, Range, Delta " << convertRadToDeg(m_startAngle) << " "
0081                           << convertRadToDeg(m_rangeAngle) << " " << convertRadToDeg(m_delta) << " Radius " << m_radius
0082                           << " Centre " << m_center[0] << ", " << m_center[1] << ", " << m_center[2];
0083 
0084   //======= collect data concerning the rotation of the solid
0085   using sz_type = std::map<std::string, std::vector<double> >::mapped_type::size_type;
0086   sz_type sz = m_rotateSolid.size();
0087   if (sz % 3) {
0088     LogDebug("DDAlgorithm") << "\trotateSolid must occur 3*n times (defining n subsequent rotations)\n"
0089                             << "\t  currently it appears " << sz << " times!\n";
0090   }
0091   for (sz_type i = 0; i < sz; i += 3) {
0092     if ((m_rotateSolid[i] > 180._deg) || (m_rotateSolid[i] < 0._deg)) {
0093       LogDebug("DDAlgorithm") << "\trotateSolid \'theta\' must be in range [0,180*deg]\n"
0094                               << "\t  currently it is " << convertRadToDeg(m_rotateSolid[i]) << "*deg in rotateSolid["
0095                               << double(i) << "]!\n";
0096     }
0097     DDAxisAngle temp(fUnitVector(m_rotateSolid[i], m_rotateSolid[i + 1]), m_rotateSolid[i + 2]);
0098     LogDebug("DDAlgorithm") << "  rotsolid[" << i << "] axis=" << temp.Axis()
0099                             << " rot.angle=" << convertRadToDeg(temp.Angle());
0100     m_solidRot = temp * m_solidRot;
0101   }
0102 
0103   m_idNameSpace = DDCurrentNamespace::ns();
0104   m_childNmNs = DDSplit(sArgs["ChildName"]);
0105   if (m_childNmNs.second.empty())
0106     m_childNmNs.second = DDCurrentNamespace::ns();
0107 
0108   DDName parentName = parent().name();
0109   LogDebug("DDAlgorithm") << "DDAngular: Parent " << parentName << "\tChild " << m_childNmNs.first << "\tNameSpace "
0110                           << m_childNmNs.second;
0111 }
0112 
0113 void DDAngular::execute(DDCompactView& cpv) {
0114   DDName mother = parent().name();
0115   DDName ddname(m_childNmNs.first, m_childNmNs.second);
0116   double theta = 90._deg;
0117   int copy = m_startCopyNo;
0118   double phi = m_startAngle;
0119 
0120   for (int i = 0; i < m_n; ++i) {
0121     double phix = phi;
0122     double phiy = phix + 90._deg;
0123     double phideg = convertRadToDeg(phix);
0124 
0125     std::string rotstr = m_childNmNs.first + "_" + std::to_string(phideg * 10.);
0126     DDRotation rotation = DDRotation(DDName(rotstr, m_idNameSpace));
0127     if (!rotation) {
0128       LogDebug("DDAlgorithm") << "DDAngular: Creating a new "
0129                               << "rotation: " << rotstr << "\t90., " << convertRadToDeg(phix) << ", 90.,"
0130                               << convertRadToDeg(phiy) << ", 0, 0";
0131 
0132       rotation = DDrot(
0133           DDName(rotstr, m_idNameSpace),
0134           std::make_unique<DDRotationMatrix>(*DDcreateRotationMatrix(theta, phix, theta, phiy, 0., 0.) * m_solidRot));
0135     }
0136 
0137     double xpos = m_radius * cos(phi) + m_center[0];
0138     double ypos = m_radius * sin(phi) + m_center[1];
0139     double zpos = m_center[2];
0140     DDTranslation tran(xpos, ypos, zpos);
0141 
0142     cpv.position(ddname, mother, copy, tran, rotation);
0143     LogDebug("DDAlgorithm") << "DDAngular: child " << m_childNmNs.second << ":" << m_childNmNs.first << " number "
0144                             << copy << " positioned in " << mother << " at " << tran << " with " << rotation << "\n";
0145     copy += m_incrCopyNo;
0146     phi += m_delta;
0147   }
0148 }
0149 
0150 DD3Vector DDAngular::fUnitVector(double theta, double phi) {
0151   return DD3Vector(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta));
0152 }
0153 
0154 DEFINE_EDM_PLUGIN(DDAlgorithmFactory, DDAngular, "global:DDAngular");