CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/FastSimulation/ParticlePropagator/src/MagneticFieldMap.cc

Go to the documentation of this file.
00001 #include "MagneticField/Engine/interface/MagneticField.h"
00002 #include "FastSimulation/ParticlePropagator/interface/MagneticFieldMap.h"
00003 #include "FastSimulation/TrackerSetup/interface/TrackerInteractionGeometry.h"
00004 
00005 #include <iostream>
00006 
00007 MagneticFieldMap::MagneticFieldMap(const MagneticField* pMF,
00008                                    const TrackerInteractionGeometry* myGeo) : 
00009   pMF_(pMF), 
00010   geometry_(myGeo),
00011   bins(101), 
00012   fieldBarrelHistos(200,static_cast<std::vector<double> >
00013                     (std::vector<double>(bins,static_cast<double>(0.)))),
00014   fieldEndcapHistos(200,static_cast<std::vector<double> > 
00015                      (std::vector<double>(bins,static_cast<double>(0.)))),
00016   fieldBarrelBinWidth(200,static_cast<double>(0.)),
00017   fieldBarrelZMin(200,static_cast<double>(0.)),
00018   fieldEndcapBinWidth(200,static_cast<double>(0.)),
00019   fieldEndcapRMin(200,static_cast<double>(0.))
00020 
00021 {
00022   
00023   std::list<TrackerLayer>::const_iterator cyliter;
00024   std::list<TrackerLayer>::const_iterator cylitBeg=geometry_->cylinderBegin();
00025   std::list<TrackerLayer>::const_iterator cylitEnd=geometry_->cylinderEnd();
00026   
00027   // Prepare the histograms
00028   // std::cout << "Prepare magnetic field local database for FAMOS speed-up" << std::endl;
00029   for ( cyliter=cylitBeg; cyliter != cylitEnd; ++cyliter ) {
00030     int layer = cyliter->layerNumber();
00031     //    cout << " Fill Histogram " << hist << endl;
00032 
00033     // Cylinder bounds
00034     double zmin = 0.;
00035     double zmax; 
00036     double rmin = 0.;
00037     double rmax; 
00038     if ( cyliter->forward() ) {
00039       zmax = cyliter->disk()->position().z();
00040       rmax = cyliter->disk()->outerRadius();
00041     } else {
00042       zmax = cyliter->cylinder()->bounds().length()/2.;
00043       rmax = cyliter->cylinder()->bounds().width()/2.
00044            - cyliter->cylinder()->bounds().thickness()/2.;
00045     }
00046 
00047     // Histograms
00048     double step;
00049 
00050     // Disk histogram characteristics
00051     step = (rmax-rmin)/(bins-1);
00052     fieldEndcapBinWidth[layer] = step;
00053     fieldEndcapRMin[layer] = rmin;
00054 
00055     // Fill the histo
00056     int endcapBin = 0;
00057     for ( double radius=rmin+step/2.; radius<rmax+step; radius+=step ) {
00058       double field = inTeslaZ(GlobalPoint(radius,0.,zmax));
00059       fieldEndcapHistos[layer][endcapBin++] = field;
00060     }
00061 
00062     // Barrel Histogram characteritics
00063     step = (zmax-zmin)/(bins-1);
00064     fieldBarrelBinWidth[layer] = step;
00065     fieldBarrelZMin[layer] = zmin;
00066 
00067     // Fill the histo
00068     int barrelBin = 0;
00069     for ( double zed=zmin+step/2.; zed<zmax+step; zed+=step ) {
00070       double field = inTeslaZ(GlobalPoint(rmax,0.,zed));
00071       fieldBarrelHistos[layer][barrelBin++] = field;
00072     }
00073   }
00074 }
00075 
00076 
00077 const GlobalVector
00078 MagneticFieldMap::inTesla( const GlobalPoint& gp) const {
00079 
00080   if (!pMF_) {
00081     return GlobalVector( 0., 0., 4.);
00082   } else {
00083     return pMF_->inTesla(gp);
00084   }
00085 
00086 }
00087 
00088 const GlobalVector
00089 MagneticFieldMap::inTesla(const TrackerLayer& aLayer, double coord, int success) const {
00090 
00091   if (!pMF_) {
00092     return GlobalVector( 0., 0., 4.);
00093   } else {
00094     return GlobalVector(0.,0.,inTeslaZ(aLayer,coord,success));
00095   }
00096 
00097 }
00098 
00099 const GlobalVector 
00100 MagneticFieldMap::inKGauss( const GlobalPoint& gp) const {
00101   
00102   return inTesla(gp) * 10.;
00103 
00104 }
00105 
00106 const GlobalVector
00107 MagneticFieldMap::inInverseGeV( const GlobalPoint& gp) const {
00108   
00109   return inKGauss(gp) * 2.99792458e-4;
00110 
00111 } 
00112 
00113 double 
00114 MagneticFieldMap::inTeslaZ(const GlobalPoint& gp) const {
00115 
00116     return pMF_ ? pMF_->inTesla(gp).z() : 4.0;
00117 
00118 }
00119 
00120 double
00121 MagneticFieldMap::inTeslaZ(const TrackerLayer& aLayer, double coord, int success) const 
00122 {
00123 
00124   if (!pMF_) {
00125     return 4.;
00126   } else {
00127     // Find the relevant histo
00128     double theBinWidth;
00129     double theXMin;
00130     unsigned layer = aLayer.layerNumber();
00131     const std::vector<double>* theHisto;
00132 
00133     if ( success == 1 ) { 
00134       theHisto = theFieldBarrelHisto(layer);
00135       theBinWidth = fieldBarrelBinWidth[layer];
00136       theXMin = fieldBarrelZMin[layer];
00137     } else {
00138       theHisto = theFieldEndcapHisto(layer);
00139       theBinWidth = fieldEndcapBinWidth[layer];
00140       theXMin = fieldEndcapRMin[layer];
00141     }
00142     
00143     // Find the relevant bin
00144     double x = fabs(coord);
00145     unsigned bin = (unsigned) ((x-theXMin)/theBinWidth);
00146     if ( bin+1 == (unsigned)bins ) bin -= 1; // Add a protection against coordinates near the layer edge
00147     double x1 = theXMin + (bin-0.5)*theBinWidth;
00148     double x2 = x1+theBinWidth;      
00149 
00150     // Determine the field
00151     double field1 = (*theHisto)[bin];
00152     double field2 = (*theHisto)[bin+1];
00153 
00154     return field1 + (field2-field1) * (x-x1)/(x2-x1);
00155 
00156   }
00157 
00158 }
00159 
00160 double 
00161 MagneticFieldMap::inKGaussZ(const GlobalPoint& gp) const {
00162 
00163     return inTeslaZ(gp)/10.;
00164 
00165 }
00166 
00167 double 
00168 MagneticFieldMap::inInverseGeVZ(const GlobalPoint& gp) const {
00169 
00170    return inKGaussZ(gp) * 2.99792458e-4;
00171 
00172 }
00173