DDHCalXtalAlgo

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
///////////////////////////////////////////////////////////////////////////////
// File: DDHCalXtalAlgo.cc
// Description: Positioning the crystal (layers) in the mother volume
///////////////////////////////////////////////////////////////////////////////

#include <cmath>
#include <algorithm>
#include <map>
#include <string>
#include <vector>

#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/PluginManager/interface/PluginFactory.h"
#include "DataFormats/Math/interface/angle_units.h"
#include "DetectorDescription/Core/interface/DDLogicalPart.h"
#include "DetectorDescription/Core/interface/DDCurrentNamespace.h"
#include "DetectorDescription/Core/interface/DDTypes.h"
#include "DetectorDescription/Core/interface/DDAlgorithm.h"
#include "DetectorDescription/Core/interface/DDAlgorithmFactory.h"

//#define EDM_ML_DEBUG
using namespace angle_units::operators;

class DDHCalXtalAlgo : public DDAlgorithm {
public:
  //Constructor and Destructor
  DDHCalXtalAlgo();
  ~DDHCalXtalAlgo() override;

  void initialize(const DDNumericArguments& nArgs,
                  const DDVectorArguments& vArgs,
                  const DDMapArguments& mArgs,
                  const DDStringArguments& sArgs,
                  const DDStringVectorArguments& vsArgs) override;

  void execute(DDCompactView& cpv) override;

private:
  double radius;                   //Pointing distance from front surface
  double offset;                   //Offset along Z
  double dx;                       //Half size along x
  double dz;                       //Half size along z
  double angwidth;                 //Angular width
  int iaxis;                       //Axis of rotation
  std::vector<std::string> names;  //Names for rotation matrices

  std::string idNameSpace;  //Namespace of this and ALL sub-parts
  std::string idName;       //Children name
};

DDHCalXtalAlgo::DDHCalXtalAlgo() {
#ifdef EDM_ML_DEBUG
  edm::LogVerbatim("HCalGeom") << "DDHCalXtalAlgo info: Creating an instance";
#endif
}

DDHCalXtalAlgo::~DDHCalXtalAlgo() {}

void DDHCalXtalAlgo::initialize(const DDNumericArguments& nArgs,
                                const DDVectorArguments&,
                                const DDMapArguments&,
                                const DDStringArguments& sArgs,
                                const DDStringVectorArguments& vsArgs) {
  radius = nArgs["Radius"];
  offset = nArgs["Offset"];
  dx = nArgs["Dx"];
  dz = nArgs["Dz"];
  angwidth = nArgs["AngWidth"];
  iaxis = int(nArgs["Axis"]);
  names = vsArgs["Names"];

#ifdef EDM_ML_DEBUG
  edm::LogVerbatim("HCalGeom") << "DDHCalXtalAlgo::Parameters for positioning:"
                               << " Axis " << iaxis << "\tRadius " << radius << "\tOffset " << offset << "\tDx " << dx
                               << "\tDz " << dz << "\tAngWidth " << convertRadToDeg(angwidth) << "\tNumbers "
                               << names.size();
  for (unsigned int i = 0; i < names.size(); i++)
    edm::LogVerbatim("HCalGeom") << "\tnames[" << i << "] = " << names[i];
#endif
  idNameSpace = DDCurrentNamespace::ns();
  idName = sArgs["ChildName"];
#ifdef EDM_ML_DEBUG
  edm::LogVerbatim("HCalGeom") << "DDHCalXtalAlgo: Parent " << parent().name() << "\tChild " << idName << " NameSpace "
                               << idNameSpace;
#endif
}

void DDHCalXtalAlgo::execute(DDCompactView& cpv) {
  double theta[3], phi[3], pos[3];
  phi[0] = 0;
  phi[1] = 90._deg;
  theta[1 - iaxis] = 90._deg;
  pos[1 - iaxis] = 0;
  int number = (int)(names.size());
  for (int i = 0; i < number; i++) {
    double angle = 0.5 * angwidth * (2 * i + 1 - number);
    theta[iaxis] = 90._deg + angle;
    if (angle > 0) {
      theta[2] = angle;
      phi[2] = iaxis * 90._deg;
    } else {
      theta[2] = -angle;
      phi[2] = (2 - 3 * iaxis) * 90._deg;
    }
    pos[iaxis] = angle * (dz + radius);
    pos[2] = dx * std::abs(sin(angle)) + offset;

    DDRotation rotation;
    std::string rotstr = names[i];
    DDTranslation tran(pos[0], pos[1], pos[2]);
    DDName parentName = parent().name();

    static const double tol = 0.01_deg;  // 0.01 degree
    if (std::abs(angle) > tol) {
#ifdef EDM_ML_DEBUG
      edm::LogVerbatim("HCalGeom") << "DDHCalXtalAlgo: Creating a rotation " << rotstr << "\t"
                                   << convertRadToDeg(theta[0]) << "," << convertRadToDeg(phi[0]) << ","
                                   << convertRadToDeg(theta[1]) << "," << convertRadToDeg(phi[1]) << ","
                                   << convertRadToDeg(theta[2]) << "," << convertRadToDeg(phi[2]);
#endif
      rotation = DDrot(DDName(rotstr, idNameSpace), theta[0], phi[0], theta[1], phi[1], theta[2], phi[2]);
    }
    cpv.position(DDName(idName, idNameSpace), parentName, i + 1, tran, rotation);
#ifdef EDM_ML_DEBUG
    edm::LogVerbatim("HCalGeom") << "DDHCalXtalAlgo: " << DDName(idName, idNameSpace) << " number " << i + 1
                                 << " positioned in " << parentName << " at " << tran << " with " << rotation;
#endif
  }
}

DEFINE_EDM_PLUGIN(DDAlgorithmFactory, DDHCalXtalAlgo, "hcal:DDHCalXtalAlgo");