DDHCalFibreBundle

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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
///////////////////////////////////////////////////////////////////////////////
// File: DDHCalFibreBundle.cc
// Description: Create & Position fibre bundles in mother
///////////////////////////////////////////////////////////////////////////////

#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/DDutils.h"
#include "DetectorDescription/Core/interface/DDLogicalPart.h"
#include "DetectorDescription/Core/interface/DDSolid.h"
#include "DetectorDescription/Core/interface/DDMaterial.h"
#include "DetectorDescription/Core/interface/DDCurrentNamespace.h"
#include "DetectorDescription/Core/interface/DDSplit.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 DDHCalFibreBundle : public DDAlgorithm {
public:
  //Constructor and Destructor
  DDHCalFibreBundle();
  ~DDHCalFibreBundle() 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:
  std::string idNameSpace;          //Namespace of this and ALL sub-parts
  std::string childPrefix;          //Prefix to child name
  std::string material;             //Name of the material for bundles
  double deltaZ;                    //Width in  Z  for mother
  double deltaPhi;                  //Width in phi for mother
  int numberPhi;                    //Number of sections in phi
  double tilt;                      //Tilt angle of the readout box
  std::vector<double> areaSection;  //Area of a bundle
  std::vector<double> rStart;       //Radius at start
  std::vector<double> rEnd;         //Radius at End
  std::vector<int> bundle;          //Bundle to be positioned
};

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

DDHCalFibreBundle::~DDHCalFibreBundle() {}

void DDHCalFibreBundle::initialize(const DDNumericArguments& nArgs,
                                   const DDVectorArguments& vArgs,
                                   const DDMapArguments&,
                                   const DDStringArguments& sArgs,
                                   const DDStringVectorArguments&) {
  deltaPhi = nArgs["DeltaPhi"];
  deltaZ = nArgs["DeltaZ"];
  numberPhi = int(nArgs["NumberPhi"]);
  material = sArgs["Material"];
  areaSection = vArgs["AreaSection"];
  rStart = vArgs["RadiusStart"];
  rEnd = vArgs["RadiusEnd"];
  bundle = dbl_to_int(vArgs["Bundles"]);
  tilt = nArgs["TiltAngle"];

  idNameSpace = DDCurrentNamespace::ns();
  childPrefix = sArgs["Child"];
#ifdef EDM_ML_DEBUG
  edm::LogVerbatim("HCalGeom") << "DDHCalFibreBundle: Parent " << parent().name() << " with " << bundle.size()
                               << " children with prefix " << childPrefix << ", material " << material << " with "
                               << numberPhi << " bundles along phi; width of"
                               << " mother " << deltaZ << " along Z, " << convertRadToDeg(deltaPhi)
                               << " along phi and with " << rStart.size() << " different bundle types";
  for (unsigned int i = 0; i < areaSection.size(); ++i)
    edm::LogVerbatim("HCalGeom") << "DDHCalFibreBundle: Child[" << i << "] Area " << areaSection[i] << " R at Start "
                                 << rStart[i] << " R at End " << rEnd[i];
  edm::LogVerbatim("HCalGeom") << "DDHCalFibreBundle: NameSpace " << idNameSpace << " Tilt Angle "
                               << convertRadToDeg(tilt) << " Bundle type at different positions";
  for (unsigned int i = 0; i < bundle.size(); ++i) {
    edm::LogVerbatim("HCalGeom") << "DDHCalFibreBundle: Position[" << i << "] "
                                 << " with Type " << bundle[i];
  }
#endif
}

void DDHCalFibreBundle::execute(DDCompactView& cpv) {
  DDName mother = parent().name();
  DDName matname(DDSplit(material).first, DDSplit(material).second);
  DDMaterial matter(matname);

  // Create the rotation matrices
  double dPhi = deltaPhi / numberPhi;
  std::vector<DDRotation> rotation;
  for (int i = 0; i < numberPhi; ++i) {
    double phi = -0.5 * deltaPhi + (i + 0.5) * dPhi;
    double phideg = convertRadToDeg(phi);
    std::string rotstr = "R0" + std::to_string(phideg);
    DDRotation rot = DDRotation(DDName(rotstr, idNameSpace));
    if (!rot) {
#ifdef EDM_ML_DEBUG
      edm::LogVerbatim("HCalGeom") << "DDHCalFibreBundle: Creating a new "
                                   << "rotation " << rotstr << "\t" << 90 << "," << phideg << "," << 90 << ","
                                   << (phideg + 90) << ", 0, 0";
#endif
      rot = DDrot(DDName(rotstr, idNameSpace), 90._deg, phi, 90._deg, (90._deg + phi), 0, 0);
    }
    rotation.emplace_back(rot);
  }

  // Create the solids and logical parts
  std::vector<DDLogicalPart> logs;
  for (unsigned int i = 0; i < areaSection.size(); ++i) {
    double r0 = rEnd[i] / std::cos(tilt);
    double dStart = areaSection[i] / (2 * dPhi * rStart[i]);
    double dEnd = areaSection[i] / (2 * dPhi * r0);
    std::string name = childPrefix + std::to_string(i);
    DDSolid solid = DDSolidFactory::cons(DDName(name, idNameSpace),
                                         0.5 * deltaZ,
                                         rStart[i] - dStart,
                                         rStart[i] + dStart,
                                         r0 - dEnd,
                                         r0 + dEnd,
                                         -0.5 * dPhi,
                                         dPhi);
#ifdef EDM_ML_DEBUG
    edm::LogVerbatim("HCalGeom") << "DDHCalFibreBundle: Creating a new solid " << name << " a cons with dZ " << deltaZ
                                 << " rStart " << rStart[i] - dStart << ":" << rStart[i] + dStart << " rEnd "
                                 << r0 - dEnd << ":" << r0 + dEnd << " Phi " << convertRadToDeg(-0.5 * dPhi) << ":"
                                 << convertRadToDeg(0.5 * dPhi);
#endif
    DDLogicalPart log(DDName(name, idNameSpace), matter, solid);
    logs.emplace_back(log);
  }

  // Now posiiton them
  int copy = 0;
  int nY = (int)(bundle.size()) / numberPhi;
  for (unsigned int i = 0; i < bundle.size(); i++) {
    DDTranslation tran(0, 0, 0);
    int ir = (int)(i) / nY;
    if (ir >= numberPhi)
      ir = numberPhi - 1;
    int ib = bundle[i];
    copy++;
    if (ib >= 0 && ib < (int)(logs.size())) {
      cpv.position(logs[ib], mother, copy, tran, rotation[ir]);
#ifdef EDM_ML_DEBUG
      edm::LogVerbatim("HCalGeom") << "DDHCalFibreBundle: " << logs[ib].name() << " number " << copy
                                   << " positioned in " << mother << " at " << tran << " with " << rotation[ir];
#endif
    }
  }
}

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