CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/FastSimulation/CaloGeometryTools/src/CrystalPad.cc

Go to the documentation of this file.
00001 #include "FastSimulation/CaloGeometryTools/interface/CrystalPad.h"
00002 
00003 #include <iostream> 
00004 
00005 std::vector<CLHEP::Hep2Vector> CrystalPad::aVector(4);
00006 
00007 
00008 CrystalPad::CrystalPad(const CrystalPad& right) 
00009 {
00010   corners_ = right.corners_;
00011   dir_ = right.dir_;
00012   number_ = right.number_;
00013   survivalProbability_ = right.survivalProbability_;
00014   center_ = right.center_;
00015   epsilon_ = right.epsilon_;
00016   dummy_ = right.dummy_;
00017 }
00018 
00019 CrystalPad&  
00020 CrystalPad::operator = (const CrystalPad& right ) {
00021   if (this != &right) { // don't copy into yourself
00022     corners_ = right.corners_;
00023     dir_ = right.dir_;
00024     number_ = right.number_;
00025     survivalProbability_ = right.survivalProbability_;
00026     center_ = right.center_;
00027     epsilon_ = right.epsilon_;
00028     dummy_ = right.dummy_;
00029   }
00030   return *this;
00031 }
00032 
00033 CrystalPad::CrystalPad(unsigned number, 
00034                        const std::vector<CLHEP::Hep2Vector>& corners) 
00035   :
00036   corners_(corners),
00037   dir_(aVector),
00038   number_(number),
00039   survivalProbability_(1.),
00040   center_(0.,0.),
00041   epsilon_(0.001)
00042 {
00043 
00044   //  std::cout << " Hello " << std::endl;
00045   if(corners.size()!=4)
00046     {
00047       std::cout << " Try to construct a quadrilateral with " << corners.size() << " points ! " << std::endl;     
00048       dummy_=true;
00049     }
00050   else
00051     {
00052       dummy_=false;
00053       // Set explicity the z to 0 !
00054       for(unsigned ic=0; ic<4;++ic)
00055         {
00056           dir_[ic] = (corners[(ic+1)%4]-corners[ic]).unit();
00057           center_+=corners_[ic];
00058         }
00059       center_*=0.25;
00060     }
00061 //  std::cout << " End of 1 constructor " << std::endl;
00062 //  std::cout << " Ncorners " << corners_.size() << std::endl;
00063 //  std::cout << " Ndirs " << dir_.size() << std::endl;
00064 }
00065 
00066 CrystalPad::CrystalPad(unsigned number, int onEcal, 
00067                        const std::vector<XYZPoint>& corners,
00068                        const XYZPoint& origin, 
00069                        const XYZVector& vec1,
00070                        const XYZVector& vec2) 
00071   : 
00072   corners_(aVector),
00073   dir_(aVector),
00074   number_(number),
00075   survivalProbability_(1.),
00076   center_(0.,0.),
00077   epsilon_(0.001)
00078 {
00079 
00080   //  std::cout << " We are in the 2nd constructor " << std::endl;
00081   if(corners.size()!=4)
00082     {
00083       std::cout << " Try to construct a quadrilateral with " << corners.size() << " points ! " << std::endl;     
00084       dummy_=true;
00085     }
00086   else
00087     {
00088       dummy_=false;
00089       double sign=(onEcal==1) ? -1.: 1.;
00090 
00091       // the good one in the central
00092       trans_=Transform3D((Point)origin,
00093                          (Point)(origin+vec1),
00094                          (Point)(origin+vec2),
00095                          Point(0.,0.,0.),
00096                          Point(0.,0.,sign),
00097                          Point(0.,1.,0.));
00098       trans_.GetDecomposition(rotation_,translation_);
00099       //      std::cout << " Constructor 2; input corners "  << std::endl;
00100       for(unsigned ic=0;ic<4;++ic)
00101         {       
00102           //      std::cout << corners[ic]<< " " ;
00103           XYZPoint corner = rotation_(corners[ic])+translation_;
00104           //      std::cout << corner << std::endl ;
00105           corners_[ic] = CLHEP::Hep2Vector(corner.X(),corner.Y());
00106           center_+=corners_[ic];
00107         }
00108       for(unsigned ic=0;ic<4;++ic)
00109         {
00110           dir_[ic] = (corners_[(ic+1)%4]-corners_[ic]).unit();
00111         }
00112       center_*=0.25;
00113     }  
00114 //  std::cout << " End of 2 constructor " << std::endl;
00115 //  std::cout << " Corners(constructor) " ;
00116 //  std::cout << corners_[0] << std::endl;
00117 //  std::cout << corners_[1] << std::endl;
00118 //  std::cout << corners_[2] << std::endl;
00119 //  std::cout << corners_[3] << std::endl;
00120 }
00121 CrystalPad::CrystalPad(unsigned number, 
00122                        const std::vector<XYZPoint>& corners,
00123                        const Transform3D & trans,double scaf,bool bothdirections) 
00124   : 
00125   corners_(aVector),
00126   dir_(aVector),
00127   number_(number),
00128   survivalProbability_(1.),
00129   center_(0.,0.),
00130   epsilon_(0.001),
00131   yscalefactor_(scaf)
00132 {
00133 
00134   //  std::cout << " We are in the 2nd constructor " << std::endl;
00135   if(corners.size()!=4)
00136     {
00137       std::cout << " Try to construct a quadrilateral with " << corners.size() << " points ! " << std::endl;     
00138       dummy_=true;
00139     }
00140   else
00141     {
00142       dummy_=false;
00143 
00144       // the good one in the central
00145       trans_=trans;
00146       //      std::cout << " Constructor 2; input corners "  << std::endl;
00147       trans_.GetDecomposition(rotation_,translation_);
00148       for(unsigned ic=0;ic<4;++ic)
00149         {       
00150 
00151           XYZPoint corner=rotation_(corners[ic])+translation_;
00152           //      std::cout << corner << std::endl ;
00153           double xscalefactor=(bothdirections) ? yscalefactor_:1.;
00154           corners_[ic] = CLHEP::Hep2Vector(corner.X()*xscalefactor,corner.Y()*yscalefactor_);
00155           center_+=corners_[ic];
00156         }
00157       for(unsigned ic=0;ic<4;++ic)
00158         {
00159           dir_[ic] = (corners_[(ic+1)%4]-corners_[ic]).unit();
00160         }
00161       center_*=0.25;
00162     }  
00163 }
00164 
00165 bool 
00166 CrystalPad::inside(const CLHEP::Hep2Vector & ppoint,bool debug) const
00167 {
00168 //  std::cout << "Inside " << ppoint <<std::endl;
00169 //  std::cout << "Corners " << corners_.size() << std::endl;
00170 //  std::cout << corners_[0] << std::endl;
00171 //  std::cout << corners_[1] << std::endl;
00172 //  std::cout << corners_[2] << std::endl;
00173 //  std::cout << corners_[3] << std::endl;
00174 //  std::cout << " Got the 2D point " << std::endl;
00175   CLHEP::Hep2Vector pv0(ppoint-corners_[0]);
00176   CLHEP::Hep2Vector pv2(ppoint-corners_[2]);
00177   CLHEP::Hep2Vector n1(pv0-(pv0*dir_[0])*dir_[0]);
00178   CLHEP::Hep2Vector n2(pv2-(pv2*dir_[2])*dir_[2]);
00179 
00180   //  double N1(n1.mag());
00181   //  double N2(n2.mag());
00182   double r1(n1*n2);
00183   bool inside1(r1<=0.);
00184 
00185   if (!inside1) return false;
00186 
00187 //  if(debug) 
00188 //    {
00189 //      std::cout << n1 << std::endl;
00190 //      std::cout << n2 << std::endl;
00191 //      std::cout << r1 << std::endl;
00192 //      std::cout << inside1 << std::endl;
00193 //    }
00194 
00195 //  bool close1=(N1<epsilon_||N2<epsilon_);
00196 //  
00197 //  if(!close1&&!inside1) return false;
00198   //  std::cout << " First calculation " << std::endl;
00199   CLHEP::Hep2Vector pv1(ppoint-corners_[1]);
00200   CLHEP::Hep2Vector pv3(ppoint-corners_[3]);
00201   CLHEP::Hep2Vector n3(pv1-(pv1*dir_[1])*dir_[1]);
00202   CLHEP::Hep2Vector n4(pv3-(pv3*dir_[3])*dir_[3]);
00203   //  double N3(n3.mag());
00204   //  double N4(n4.mag());
00205   //  bool close2=(N3<epsilon_||N4<epsilon_);
00206   double r2(n3*n4);
00207   bool inside2(r2<=0.);
00208 //  //  std::cout << " pv1 & pv3 " << pv1.mag() << " " << pv3.mag() << std::endl;
00209 //  //  double tmp=(pv1-(pv1*dir_[1])*dir_[1])*(pv3-(pv3*dir_[3])*dir_[3]);
00210 //  //  std::cout << " Computed tmp " << tmp << std::endl;
00211 //  if(debug) 
00212 //    {
00213 //      std::cout << n3 << std::endl;
00214 //      std::cout << n4 << std::endl;
00215 //      std::cout << r2 << std::endl;
00216 //      std::cout << inside2 << std::endl;
00217 //    }
00218   //  if(!close2&&!inside2) return false;
00219 //  std::cout << " Second calculation " << std::endl;
00220 //  std::cout << " True " << std::endl;
00221   //    return (!close1&&!close2||(close2&&inside1||close1&&inside2));
00222 
00223   return inside2;
00224 }
00225 
00226 /*
00227 bool 
00228 CrystalPad::globalinside(XYZPoint point) const
00229 {
00230   //  std::cout << " Global inside " << std::endl;
00231   //  std::cout << point << " " ;
00232   ROOT::Math::Rotation3D r;
00233   XYZVector t;
00234   point = rotation_(point)+translation_;
00235   //  std::cout << point << std::endl;
00236   //  print();
00237   CLHEP::Hep2Vector ppoint(point.X(),point.Y());
00238   bool result=inside(ppoint);
00239   //  std::cout << " Result " << result << std::endl;
00240   return result;
00241 }
00242 */
00243 
00244 
00245 void CrystalPad::print() const
00246 {
00247   std::cout << " Corners " << std::endl;
00248   std::cout << corners_[0] << std::endl;
00249   std::cout << corners_[1] << std::endl;
00250   std::cout << corners_[2] << std::endl;
00251   std::cout << corners_[3] << std::endl;
00252 }
00253 
00254 /*
00255 CLHEP::Hep2Vector 
00256 CrystalPad::localPoint(XYZPoint point) const
00257 {
00258   point = rotation_(point)+translation_;
00259   return CLHEP::Hep2Vector(point.X(),point.Y());
00260 }
00261 */
00262 
00263 CLHEP::Hep2Vector& CrystalPad::edge(unsigned iside,int n) 
00264 {
00265   return corners_[(iside+n)%4];
00266 }
00267 
00268 CLHEP::Hep2Vector & CrystalPad::edge(CaloDirection dir)
00269 {
00270   switch(dir)
00271     {
00272     case NORTHWEST:
00273       return corners_[0];
00274       break;
00275     case NORTHEAST:
00276       return corners_[1];
00277       break;
00278     case SOUTHEAST:
00279       return corners_[2];
00280       break;
00281     case SOUTHWEST:
00282       return corners_[3];
00283       break;
00284     default:
00285       {
00286         std::cout << " Serious problem in CrystalPad ! " << dir << std::endl;
00287         return corners_[0];
00288       }
00289     }
00290   return corners_[0];
00291 }
00292 
00293 
00294 void 
00295 CrystalPad::extrems(double &xmin,double& xmax,double &ymin, double& ymax) const
00296 {
00297   xmin=ymin=999;
00298   xmax=ymax=-999;
00299   for(unsigned ic=0;ic<4;++ic)
00300     {
00301       if(corners_[ic].x()<xmin) xmin=corners_[ic].x();
00302       if(corners_[ic].x()>xmax) xmax=corners_[ic].x();
00303       if(corners_[ic].y()<ymin) ymin=corners_[ic].y();
00304       if(corners_[ic].y()>ymax) ymax=corners_[ic].y();
00305     }
00306 }
00307 
00308 void 
00309 CrystalPad::resetCorners() {
00310 
00311   // Find the centre-of-gravity of the Quad (after re-organization)
00312   center_ = CLHEP::Hep2Vector(0.,0.);
00313   for(unsigned ic=0;ic<4;++ic) center_ += corners_[ic];
00314   center_ *= 0.25;
00315 
00316   // Rescale the corners to allow for some inaccuracies in 
00317   // in the inside test
00318   for(unsigned ic=0;ic<4;++ic) 
00319     corners_[ic] += 0.001 * (corners_[ic] - center_) ;
00320 
00321 }
00322 
00323 std::ostream & operator << (std::ostream& ost,  CrystalPad & quad)
00324 {
00325   ost << " Number " << quad.getNumber() << std::endl ;
00326   ost << NORTHWEST << quad.edge(NORTHWEST) << std::endl;
00327   ost << NORTHEAST << quad.edge(NORTHEAST) << std::endl;
00328   ost << SOUTHEAST << quad.edge(SOUTHEAST) << std::endl;
00329   ost << SOUTHWEST << quad.edge(SOUTHWEST) << std::endl;
00330   
00331   return ost;
00332 }
00333 
00334 void 
00335 CrystalPad::getDrawingCoordinates(std::vector<float> &x, std::vector<float>&y) const
00336 {
00337   x.clear();
00338   y.clear();
00339   x.push_back(corners_[0].x());
00340   x.push_back(corners_[1].x());
00341   x.push_back(corners_[2].x());
00342   x.push_back(corners_[3].x());
00343   x.push_back(corners_[0].x());
00344   y.push_back(corners_[0].y());
00345   y.push_back(corners_[1].y());
00346   y.push_back(corners_[2].y());
00347   y.push_back(corners_[3].y());
00348   y.push_back(corners_[0].y());
00349 }