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 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
//   COCOA class implementation file
//Id:  OptOMirror.cc
//CAT: Model
//
//   History: v1.0
//   Pedro Arce

#include "Alignment/CocoaModel/interface/OptOMirror.h"
#include "Alignment/CocoaModel/interface/LightRay.h"
#include "Alignment/CocoaModel/interface/ALIPlane.h"
#include "Alignment/CocoaModel/interface/Measurement.h"
#include <iostream>
#include <iomanip>
#ifdef COCOA_VIS
#include "Alignment/IgCocoaFileWriter/interface/IgCocoaFileMgr.h"
#include "Alignment/CocoaVisMgr/interface/ALIColour.h"
#endif
#include "Alignment/CocoaDDLObjects/interface/CocoaSolidShapeBox.h"
#include "Alignment/CocoaUtilities/interface/GlobalOptionMgr.h"

using namespace CLHEP;

//---------- Default behaviour: create a LightRay object
void OptOMirror::defaultBehaviour(LightRay& lightray, Measurement& meas) { detailedDeviatesLightRay(lightray); }

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@ Detailed simulation of Reflection in Mirror
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void OptOMirror::detailedDeviatesLightRay(LightRay& lightray) {
  if (ALIUtils::debug >= 2)
    std::cout << "LR: DETAILED REFLECTION IN MIRROR " << name() << std::endl;
  if (ALIUtils::debug >= 3)
    ALIUtils::dump3v(centreGlob(), " centre Global ");

  //---------- Get forward plate and intersect lightray with it
  ALIPlane plate = getPlate(true, false);
  lightray.intersect(plate);
  CLHEP::Hep3Vector inters = lightray.point();

  //---------- Get centre of forward plate
  //----- Get Z axis
  CLHEP::Hep3Vector ZAxis = getZAxis();
  CLHEP::HepRotation rmt = rmGlob();
  ZAxis = rmt * ZAxis;
  //----- Get centre
  ALIdouble width = findExtraEntryValue("width");
  CLHEP::Hep3Vector plate_centre = centreGlob() - 0.5 * width * ZAxis;
  //-  if(ALIUtils::debug >= 4) std::cout << " mirror width " << width << std::endl;

  //---------- Get the distance between the intersection point and the centre of the forward plate
  ALIdouble distance = (plate_centre - inters).mag();

  //---------- Get normal to mirror at intersection point
  //------- Get angle of mirror surface (angle between plate centre and intersection)
  ALIdouble flatness = findExtraEntryValue("flatness");
  //-- flatness is defined as number of 632 nm wavelengths
  flatness *= 632.E-9;
  ALIdouble length = 0.;

  ALIdouble curvature_radius;
  ALIdouble angFlatness;
  if (flatness != 0) {
    length = findExtraEntryValueMustExist("length");
    curvature_radius = (flatness * flatness + length * length) / (2 * flatness);
    angFlatness = asin(distance / curvature_radius);
  } else {
    curvature_radius = ALI_DBL_MAX;
    angFlatness = 0;
  }

  if (ALIUtils::debug >= 3) {
    std::cout << " intersection with plate " << inters << std::endl;
    std::cout << " plate_centre " << plate_centre << std::endl;
    std::cout << " distance plate_centre - intersection " << distance << std::endl;
    std::cout << " flatness " << flatness << ", length " << length;
    std::cout << ", curvature radius " << curvature_radius << " angle of flatness " << angFlatness << std::endl;
  }

  //----- Axis of rotation is perpendicular to Z Axis and to line plate_centre - intersection
  CLHEP::Hep3Vector ipcV = inters - plate_centre;
  if (ipcV.mag() != 0)
    ipcV *= 1. / ipcV.mag();
  CLHEP::HepRotation rtm = rmGlob();
  ipcV = rtm * ipcV;
  CLHEP::Hep3Vector rotationAxis = ipcV.cross(ZAxis);
  //----- normal is object normal rotated around this axis
  CLHEP::Hep3Vector inters_normal = CLHEP::Hep3Vector(0., 0., 1.);
  inters_normal.rotate(angFlatness, rotationAxis);
  inters_normal = rmt * inters_normal;

  if (ALIUtils::debug >= 2) {
    ALIUtils::dump3v(ipcV, " intersection -  plate_centre std::vector ");
    std::cout << "rotation Axis " << rotationAxis << std::endl;
    std::cout << " plate normal at intersection point " << inters_normal << std::endl;
  }
  //---------- Reflect in plate
  ALIdouble cosang = -(inters_normal * lightray.direction()) / inters_normal.mag() / lightray.direction().mag();
  CLHEP::Hep3Vector lrold = lightray.direction();
  lightray.setDirection(lightray.direction() + inters_normal * 2 * cosang);

  if (ALIUtils::debug >= 2) {
    lightray.dumpData("Reflected in mirror");
  }
}

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@ Fast simulation of Reflection in Mirror
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void OptOMirror::fastDeviatesLightRay(LightRay& lightray) {
  if (ALIUtils::debug >= 2)
    std::cout << "LR: FAST REFLECTION IN MIRROR " << name() << std::endl;

  //---------- Get forward plate
  ALIPlane plate = getPlate(true, false);

  //---------- Reflect in plate (including intersection with it)
  lightray.reflect(plate);
  if (ALIUtils::debug >= 2) {
    lightray.dumpData("Reflected in plate");
  }
  //---------- Deviate Lightray
  //  ALIdouble deviX = findExtraEntryValue("deviX");
  // ALIdouble deviY = findExtraEntryValue("deviY");
  //  lightray.shiftAndDeviateWhileTraversing( this, 0., 0., 0., deviX, deviY, 0.);
  lightray.shiftAndDeviateWhileTraversing(this, 'R');
  if (ALIUtils::debug >= 2) {
    lightray.dumpData("Deviated ");
  }
}

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void OptOMirror::detailedTraversesLightRay(LightRay& lightray) {
  if (ALIUtils::debug >= 2)
    std::cout << "LR: DETAILED TRAVERSE IN MIRROR " << name() << std::endl;

  //---------- Get forward plate
  ALIPlane plate = getPlate(true, true);
  //---------- If width is 0, just keep the same point
  ALIdouble width = findExtraEntryValue("width");
  if (width == 0) {
    if (ALIUtils::debug >= 3)
      lightray.dumpData("Traversed with 0 width");
    return;
  }

  //---------- Refract while entering mirror
  ALIdouble refra_ind1 = 1.;
  ALIdouble refra_ind2 = findExtraEntryValue("refra_ind");
  lightray.refract(plate, refra_ind1, refra_ind2);
  if (ALIUtils::debug >= 2) {
    lightray.dumpData("Refracted in first plate");
  }

  //---------- Get backward plate
  plate = getPlate(false, true);
  //---------- Refract while exiting mirror
  lightray.refract(plate, refra_ind2, refra_ind1);
  if (ALIUtils::debug >= 2) {
    lightray.dumpData("Refracted in first plate");
  }
}

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void OptOMirror::fastTraversesLightRay(LightRay& lightray) {
  if (ALIUtils::debug >= 2)
    std::cout << "LR: TRAVERSE MIRROR  " << name() << std::endl;

  //---------- Get backward plate
  ALIPlane plate = getPlate(false, false);
  lightray.intersect(plate);
  if (ALIUtils::debug >= 2) {
    lightray.dumpData("Intersected with plate");
  }
  //---------- Shift and Deviate
  lightray.shiftAndDeviateWhileTraversing(this, 'T');
  if (ALIUtils::debug >= 2) {
    lightray.dumpData("Shifted and Deviated");
  }
}

#ifdef COCOA_VIS
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void OptOMirror::fillIguana() {
  ALIdouble width;
  ALIbool wexists = findExtraEntryValueIfExists("width", width);
  if (!wexists)
    width = 1.;
  ALIdouble length;
  wexists = findExtraEntryValueIfExists("length", length);
  if (!wexists)
    length = 4.;

  ALIColour* col = new ALIColour(0., 0., 1., 0.);
  std::vector<ALIdouble> spar;
  spar.push_back(length);
  spar.push_back(length);
  spar.push_back(width);
  IgCocoaFileMgr::getInstance().addSolid(*this, "BOX", spar, col);
}
#endif

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void OptOMirror::constructSolidShape() {
  ALIdouble go;
  GlobalOptionMgr* gomgr = GlobalOptionMgr::getInstance();
  gomgr->getGlobalOptionValue("VisScale", go);

  theSolidShape = new CocoaSolidShapeBox(
      "Box", go * 5. * cm / m, go * 5. * cm / m, go * 1. * cm / m);  //COCOA internal units are meters
}