CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/Alignment/MuonAlignment/plugins/MuonGeometrySanityCheck.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    MuonGeometrySanityCheck
00004 // Class:      MuonGeometrySanityCheck
00005 //
00013 //
00014 // Original Author:  Jim Pivarski
00015 //         Created:  Sat Jul  3 13:33:13 CDT 2010
00016 // $Id: MuonGeometrySanityCheck.cc,v 1.2 2010/07/10 03:21:26 pivarski Exp $
00017 //
00018 //
00019 
00020 
00021 // system include files
00022 #include "FWCore/Framework/interface/Frameworkfwd.h"
00023 #include "FWCore/Framework/interface/EDAnalyzer.h"
00024 #include "FWCore/Framework/interface/EventSetup.h"
00025 #include "FWCore/Framework/interface/ESHandle.h"
00026 #include "FWCore/Framework/interface/Event.h"
00027 #include "FWCore/Framework/interface/MakerMacros.h"
00028 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00029 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00030 
00031 #include "Geometry/DTGeometry/interface/DTGeometry.h"
00032 #include "Geometry/CSCGeometry/interface/CSCGeometry.h"
00033 #include "Geometry/Records/interface/MuonGeometryRecord.h"
00034 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00035 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00036 #include "DataFormats/DetId/interface/DetId.h"
00037 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00038 #include "DataFormats/MuonDetId/interface/DTChamberId.h"
00039 #include "DataFormats/MuonDetId/interface/DTSuperLayerId.h"
00040 #include "DataFormats/MuonDetId/interface/DTLayerId.h"
00041 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00042 #include "DataFormats/CLHEP/interface/AlgebraicObjects.h"
00043 
00044 //
00045 // class decleration
00046 //
00047 
00048 class MuonGeometrySanityCheckCustomFrame {
00049    public:
00050       MuonGeometrySanityCheckCustomFrame(const edm::ParameterSet &iConfig, std::string name);
00051 
00052       GlobalPoint transform(GlobalPoint point) const;
00053       GlobalPoint transformInverse(GlobalPoint point) const;
00054       AlgebraicMatrix matrix;
00055       AlgebraicMatrix matrixInverse;
00056 };
00057 
00058 class MuonGeometrySanityCheckPoint {
00059    public:
00060       MuonGeometrySanityCheckPoint(const edm::ParameterSet &iConfig, const std::map<std::string,const MuonGeometrySanityCheckCustomFrame*> &frames);
00061 
00062       enum {
00063          kDTChamber,
00064          kDTSuperLayer,
00065          kDTLayer,
00066          kCSCChamber,
00067          kCSCLayer
00068       };
00069 
00070       enum {
00071          kGlobal,
00072          kLocal,
00073          kChamber,
00074          kCustom
00075       };
00076 
00077       std::string detName() const;
00078 
00079       int type;
00080       DetId detector;
00081       int frame;
00082       const MuonGeometrySanityCheckCustomFrame *customFrame;
00083       GlobalPoint displacement;
00084       bool has_expectation;
00085       GlobalPoint expectation;
00086       std::string name;
00087       int outputFrame;
00088       const MuonGeometrySanityCheckCustomFrame *outputCustomFrame;
00089 
00090    private:
00091       bool numeric(std::string s);
00092       int number(std::string s);
00093 };
00094 
00095 class MuonGeometrySanityCheck : public edm::EDAnalyzer {
00096    public:
00097       explicit MuonGeometrySanityCheck(const edm::ParameterSet &iConfig);
00098       ~MuonGeometrySanityCheck();
00099 
00100    private:
00101       virtual void analyze(const edm::Event&, const edm::EventSetup &iConfig);
00102 
00103       std::string printout;
00104       double tolerance;
00105       std::string prefix;
00106       std::map<std::string,const MuonGeometrySanityCheckCustomFrame*> m_frames;
00107       std::vector<MuonGeometrySanityCheckPoint> m_points;
00108 };
00109 
00110 //
00111 // constants, enums and typedefs
00112 //
00113 
00114 //
00115 // static data member definitions
00116 //
00117 
00118 //
00119 // constructors and destructor
00120 //
00121 
00122 MuonGeometrySanityCheck::MuonGeometrySanityCheck(const edm::ParameterSet &iConfig) {
00123    printout = iConfig.getParameter<std::string>("printout");
00124    if (printout != std::string("all")  &&  printout != std::string("bad")) {
00125       throw cms::Exception("BadConfig") << "Printout must be \"all\" or \"bad\"." << std::endl;
00126    }
00127 
00128    tolerance = iConfig.getParameter<double>("tolerance");
00129    if (tolerance <= 0) {
00130       throw cms::Exception("BadConfig") << "Tolerance must be positive." << std::endl;
00131    }
00132 
00133    prefix = iConfig.getParameter<std::string>("prefix");
00134 
00135    std::vector<edm::ParameterSet> frames = iConfig.getParameter<std::vector<edm::ParameterSet> >("frames");
00136    for (std::vector<edm::ParameterSet>::const_iterator frame = frames.begin();  frame != frames.end();  ++frame) {
00137       std::string name = frame->getParameter<std::string>("name");
00138       if (m_frames.find(name) != m_frames.end()) {
00139          throw cms::Exception("BadConfig") << "Custom frame \"" << name << "\" has been defined twice." << std::endl;
00140       }
00141       m_frames[name] = new MuonGeometrySanityCheckCustomFrame(*frame, name);
00142    }
00143 
00144    std::vector<edm::ParameterSet> points = iConfig.getParameter<std::vector<edm::ParameterSet> >("points");
00145    for (std::vector<edm::ParameterSet>::const_iterator point = points.begin();  point != points.end();  ++point) {
00146       m_points.push_back(MuonGeometrySanityCheckPoint(*point, m_frames));
00147    }
00148 }
00149 
00150 MuonGeometrySanityCheck::~MuonGeometrySanityCheck() {
00151    for (std::map<std::string,const MuonGeometrySanityCheckCustomFrame*>::iterator iter = m_frames.begin();  iter != m_frames.end();  ++iter) {
00152       delete iter->second;
00153    }
00154 }
00155 
00156 MuonGeometrySanityCheckCustomFrame::MuonGeometrySanityCheckCustomFrame(const edm::ParameterSet &iConfig, std::string name) {
00157    std::vector<double> numbers = iConfig.getParameter<std::vector<double> >("matrix");
00158    if (numbers.size() != 9) {
00159       throw cms::Exception("BadConfig") << "Custom frame \"" << name << "\" has a matrix which is not 3x3." << std::endl;
00160    }
00161 
00162    matrix = AlgebraicMatrix(3, 3);
00163    matrix[0][0] = numbers[0];
00164    matrix[0][1] = numbers[1];
00165    matrix[0][2] = numbers[2];
00166    matrix[1][0] = numbers[3];
00167    matrix[1][1] = numbers[4];
00168    matrix[1][2] = numbers[5];
00169    matrix[2][0] = numbers[6];
00170    matrix[2][1] = numbers[7];
00171    matrix[2][2] = numbers[8];
00172 
00173    int ierr;
00174    matrixInverse = matrix;
00175    matrixInverse.invert(ierr);
00176    if (ierr != 0) {
00177       throw cms::Exception("BadConfig") << "Could not invert matrix for custom frame \"" << name << "\"." << std::endl;
00178    }
00179 }
00180 
00181 GlobalPoint MuonGeometrySanityCheckCustomFrame::transform(GlobalPoint point) const {
00182    AlgebraicVector input(3);
00183    input[0] = point.x();
00184    input[1] = point.x();
00185    input[2] = point.x();
00186    AlgebraicVector output = matrix * input;
00187    return GlobalPoint(output[0], output[1], output[3]);
00188 }
00189 
00190 GlobalPoint MuonGeometrySanityCheckCustomFrame::transformInverse(GlobalPoint point) const {
00191    AlgebraicVector input(3);
00192    input[0] = point.x();
00193    input[1] = point.x();
00194    input[2] = point.x();
00195    AlgebraicVector output = matrixInverse * input;
00196    return GlobalPoint(output[0], output[1], output[3]);
00197 }
00198 
00199 bool MuonGeometrySanityCheckPoint::numeric(std::string s) {
00200   return (s == std::string("0")  ||  s == std::string("1")  ||  s == std::string("2")  ||  s == std::string("3")  ||  s == std::string("4")  ||
00201           s == std::string("5")  ||  s == std::string("6")  ||  s == std::string("7")  ||  s == std::string("8")  ||  s == std::string("9"));
00202 }
00203 
00204 int MuonGeometrySanityCheckPoint::number(std::string s) {
00205   if (s == std::string("0")) return 0;
00206   else if (s == std::string("1")) return 1;
00207   else if (s == std::string("2")) return 2;
00208   else if (s == std::string("3")) return 3;
00209   else if (s == std::string("4")) return 4;
00210   else if (s == std::string("5")) return 5;
00211   else if (s == std::string("6")) return 6;
00212   else if (s == std::string("7")) return 7;
00213   else if (s == std::string("8")) return 8;
00214   else if (s == std::string("9")) return 9;
00215   else assert(false);
00216 }
00217 
00218 MuonGeometrySanityCheckPoint::MuonGeometrySanityCheckPoint(const edm::ParameterSet &iConfig, const std::map<std::string,const MuonGeometrySanityCheckCustomFrame*> &frames) {
00219    std::string detName = iConfig.getParameter<std::string>("detector");
00220 
00221    bool parsing_error = false;
00222 
00223    bool barrel = (detName.substr(0, 2) == std::string("MB"));
00224    bool endcap = (detName.substr(0, 2) == std::string("ME"));
00225    if (!barrel  &&  !endcap) parsing_error = true;
00226 
00227    if (!parsing_error  &&  barrel) {
00228       int index = 2;
00229 
00230       bool plus = true;
00231       if (detName.substr(index, 1) == std::string("+")) {
00232          plus = true;
00233          index++;
00234       }
00235       else if (detName.substr(index, 1) == std::string("-")) {
00236          plus = false;
00237          index++;
00238       }
00239 
00240       int wheel = 0;
00241       bool wheel_digit = false;
00242       while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00243          wheel *= 10;
00244          wheel += number(detName.substr(index, 1));
00245          wheel_digit = true;
00246          index++;
00247       }
00248       if (!plus) wheel *= -1;
00249       if (!wheel_digit) parsing_error = true;
00250       
00251       if (detName.substr(index, 1) != std::string("/")) parsing_error = true;
00252       index++;
00253       
00254       int station = 0;
00255       bool station_digit = false;
00256       while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00257          station *= 10;
00258          station += number(detName.substr(index, 1));
00259          station_digit = true;
00260          index++;
00261       }
00262       if (!station_digit) parsing_error = true;
00263       
00264       if (detName.substr(index, 1) != std::string("/")) parsing_error = true;
00265       index++;
00266       
00267       int sector = 0;
00268       bool sector_digit = false;
00269       while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00270          sector *= 10;
00271          sector += number(detName.substr(index, 1));
00272          sector_digit = true;
00273          index++;
00274       }
00275       if (!sector_digit) parsing_error = true;
00276       
00277       // these are optional
00278       int superlayer = 0;
00279       bool superlayer_digit = false;
00280       int layer = 0;
00281       bool layer_digit = false;
00282       if (detName.substr(index, 1) == std::string("/")) {
00283          index++;
00284          while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00285             superlayer *= 10;
00286             superlayer += number(detName.substr(index, 1));
00287             superlayer_digit = true;
00288             index++;
00289          }
00290          if (!superlayer_digit) parsing_error = true;
00291 
00292          if (detName.substr(index, 1) == std::string("/")) {
00293             index++;
00294             while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00295                layer *= 10;
00296                layer += number(detName.substr(index, 1));
00297                layer_digit = true;
00298                index++;
00299             }
00300          }
00301       }
00302 
00303       if (!parsing_error) {
00304          bool no_such_chamber = false;
00305          
00306          if (wheel < -2  ||  wheel > 2) no_such_chamber = true;
00307          if (station < 1  ||  station > 4) no_such_chamber = true;
00308          if (station == 4  &&  (sector < 1  ||  sector > 14)) no_such_chamber = true;
00309          if (station < 4  &&  (sector < 1  ||  sector > 12)) no_such_chamber = true;
00310          
00311          if (no_such_chamber) {
00312             throw cms::Exception("BadConfig") << "Chamber doesn't exist: MB" << (plus ? "+" : "-") << wheel << "/" << station << "/" << sector << std::endl;
00313          }
00314 
00315          if (superlayer == 0) {
00316             detector = DTChamberId(wheel, station, sector);
00317             type = kDTChamber;
00318          }
00319          else {
00320             bool no_such_superlayer = false;
00321             if (superlayer < 1  ||  superlayer > 3) no_such_superlayer = true;
00322             if (station == 4  &&  superlayer == 2) no_such_superlayer = true;
00323 
00324             if (no_such_superlayer) {
00325                throw cms::Exception("BadConfig") << "Superlayer doesn't exist: MB" << (plus ? "+" : "-") << wheel << "/" << station << "/" << sector << "/" << superlayer << std::endl;
00326             }
00327 
00328             if (layer == 0) {
00329                detector = DTSuperLayerId(wheel, station, sector, superlayer);
00330                type = kDTSuperLayer;
00331             }
00332             else {
00333                bool no_such_layer = false;
00334                if (layer < 1  ||  layer > 4) no_such_layer = true;
00335 
00336                if (no_such_layer) {
00337                   throw cms::Exception("BadConfig") << "Layer doesn't exist: MB" << (plus ? "+" : "-") << wheel << "/" << station << "/" << sector << "/" << superlayer << "/" << layer << std::endl;
00338                }
00339 
00340                detector = DTLayerId(wheel, station, sector, superlayer, layer);
00341                type = kDTLayer;
00342             }
00343          }
00344       }
00345    }
00346    else if (!parsing_error  &&  endcap) {
00347       int index = 2;
00348 
00349       bool plus = true;
00350       if (detName.substr(index, 1) == std::string("+")) {
00351          plus = true;
00352          index++;
00353       }
00354       else if (detName.substr(index, 1) == std::string("-")) {
00355          plus = false;
00356          index++;
00357       }
00358       else parsing_error = true;
00359 
00360       int station = 0;
00361       bool station_digit = false;
00362       while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00363          station *= 10;
00364          station += number(detName.substr(index, 1));
00365          station_digit = true;
00366          index++;
00367       }
00368       if (!plus) station *= -1;
00369       if (!station_digit) parsing_error = true;
00370 
00371       if (detName.substr(index, 1) != std::string("/")) parsing_error = true;
00372       index++;
00373 
00374       int ring = 0;
00375       bool ring_digit = false;
00376       while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00377          ring *= 10;
00378          ring += number(detName.substr(index, 1));
00379          ring_digit = true;
00380          index++;
00381       }
00382       if (!ring_digit) parsing_error = true;
00383       
00384       if (detName.substr(index, 1) != std::string("/")) parsing_error = true;
00385       index++;
00386       
00387       int chamber = 0;
00388       bool chamber_digit = false;
00389       while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00390          chamber *= 10;
00391          chamber += number(detName.substr(index, 1));
00392          chamber_digit = true;
00393          index++;
00394       }
00395       if (!chamber_digit) parsing_error = true;
00396 
00397       // this is optional
00398       int layer = 0;
00399       bool layer_digit = false;
00400       if (detName.substr(index, 1) == std::string("/")) {
00401          index++;
00402          while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00403             layer *= 10;
00404             layer += number(detName.substr(index, 1));
00405             layer_digit = true;
00406             index++;
00407          }
00408          if (!layer_digit) parsing_error = true;
00409       }
00410 
00411       if (!parsing_error) {
00412          bool no_such_chamber = false;
00413 
00414          int endcap = (station > 0 ? 1 : 2);
00415          station = abs(station);
00416          if (station < 1  ||  station > 4) no_such_chamber = true;
00417          if (station == 1  &&  (ring < 1  ||  ring > 4)) no_such_chamber = true;
00418          if (station > 1  &&  (ring < 1  ||  ring > 2)) no_such_chamber = true;
00419          if (station == 1  &&  (chamber < 1  ||  chamber > 36)) no_such_chamber = true;
00420          if (station > 1  &&  ring == 1  &&  (chamber < 1  ||  chamber > 18)) no_such_chamber = true;
00421          if (station > 1  &&  ring == 2  &&  (chamber < 1  ||  chamber > 36)) no_such_chamber = true;
00422 
00423          if (no_such_chamber) {
00424             throw cms::Exception("BadConfig") << "Chamber doesn't exist: ME" << (endcap == 1 ? "+" : "-") << station << "/" << ring << "/" << chamber << std::endl;
00425          }
00426 
00427          if (layer == 0) {
00428             detector = CSCDetId(endcap, station, ring, chamber);
00429             type = kCSCChamber;
00430          }
00431          else {
00432             bool no_such_layer = false;
00433             if (layer < 1  ||  layer > 6) no_such_layer = true;
00434 
00435             if (no_such_layer) {
00436                throw cms::Exception("BadConfig") << "Layer doesn't exist: ME" << (endcap == 1 ? "+" : "-") << station << "/" << ring << "/" << chamber << "/" << layer << std::endl;
00437             }
00438 
00439             detector = CSCDetId(endcap, station, ring, chamber, layer);
00440             type = kCSCLayer;
00441          }
00442       }
00443    }
00444 
00445    if (parsing_error) {
00446       throw cms::Exception("BadConfig") << "Detector name is malformed: " << detName << std::endl;
00447    }
00448 
00449    std::string frameName = iConfig.getParameter<std::string>("frame");
00450    const std::map<std::string,const MuonGeometrySanityCheckCustomFrame*>::const_iterator frameIter = frames.find(frameName);
00451    if (frameName == std::string("global")) {
00452       frame = kGlobal;
00453       customFrame = NULL;
00454    }
00455    else if (frameName == std::string("local")) {
00456       frame = kLocal;
00457       customFrame = NULL;
00458    }
00459    else if (frameName == std::string("chamber")) {
00460       frame = kChamber;
00461       customFrame = NULL;
00462    }
00463    else if (frameIter != frames.end()) {
00464       frame = kCustom;
00465       customFrame = frameIter->second;
00466    }
00467    else {
00468       throw cms::Exception("BadConfig") << "Frame \"" << frameName << "\" has not been defined." << std::endl;
00469    }
00470 
00471    std::vector<double> point = iConfig.getParameter<std::vector<double> >("displacement");
00472    if (point.size() != 3) {
00473       throw cms::Exception("BadConfig") << "Displacement relative to detector " << detName << " doesn't have exactly three components." << std::endl;
00474    }
00475 
00476    displacement = GlobalPoint(point[0], point[1], point[2]);
00477 
00478    const edm::Entry *entry = iConfig.retrieveUnknown("expectation");
00479    if (entry != NULL) {
00480       has_expectation = true;
00481 
00482       point = iConfig.getParameter<std::vector<double> >("expectation");
00483       if (point.size() != 3) {
00484          throw cms::Exception("BadConfig") << "Expectation for detector " << detName << ", displacement " << displacement << " doesn't have exactly three components." << std::endl;
00485       }
00486 
00487       expectation = GlobalPoint(point[0], point[1], point[2]);
00488    }
00489    else {
00490       has_expectation = false;
00491    }
00492 
00493    entry = iConfig.retrieveUnknown("name");
00494    if (entry != NULL) {
00495       name = iConfig.getParameter<std::string>("name");
00496    }
00497    else {
00498       name = std::string("anonymous");
00499    }
00500 
00501    entry = iConfig.retrieveUnknown("outputFrame");
00502    if (entry != NULL) {
00503       frameName = iConfig.getParameter<std::string>("outputFrame");
00504       const std::map<std::string,const MuonGeometrySanityCheckCustomFrame*>::const_iterator frameIter = frames.find(frameName);
00505       if (frameName == std::string("global")) {
00506          outputFrame = kGlobal;
00507          outputCustomFrame = NULL;
00508       }
00509       else if (frameName == std::string("local")) {
00510          outputFrame = kLocal;
00511          outputCustomFrame = NULL;
00512       }
00513       else if (frameName == std::string("chamber")) {
00514          outputFrame = kChamber;
00515          outputCustomFrame = NULL;
00516       }
00517       else if (frameIter != frames.end()) {
00518          outputFrame = kCustom;
00519          outputCustomFrame = frameIter->second;
00520       }
00521       else {
00522          throw cms::Exception("BadConfig") << "Frame \"" << frameName << "\" has not been defined." << std::endl;
00523       }
00524    }
00525    else {
00526       outputFrame = kGlobal;
00527       outputCustomFrame = NULL;
00528    }
00529 }
00530 
00531 std::string MuonGeometrySanityCheckPoint::detName() const {
00532    std::stringstream output;
00533    if (type == kDTChamber) {
00534       DTChamberId id(detector);
00535       output << "MB" << (id.wheel() > 0 ? "+" : "") << id.wheel() << "/" << id.station() << "/" << id.sector();
00536    }
00537    else if (type == kDTSuperLayer) {
00538       DTSuperLayerId id(detector);
00539       output << "MB" << (id.wheel() > 0 ? "+" : "") << id.wheel() << "/" << id.station() << "/" << id.sector() << "/" << id.superlayer();
00540    }
00541    else if (type == kDTLayer) {
00542       DTLayerId id(detector);
00543       output << "MB" << (id.wheel() > 0 ? "+" : "") << id.wheel() << "/" << id.station() << "/" << id.sector() << "/" << id.superlayer() << "/" << id.layer();
00544    }
00545    else if (type == kCSCChamber) {
00546       CSCDetId id(detector);
00547       output << "ME" << (id.endcap() == 1 ? "+" : "-") << id.station() << "/" << id.ring() << "/" << id.chamber();
00548    }
00549    else if (type == kCSCLayer) {
00550       CSCDetId id(detector);
00551       output << "ME" << (id.endcap() == 1 ? "+" : "-") << id.station() << "/" << id.ring() << "/" << id.chamber() << "/" << id.layer();
00552    }
00553    else assert(false);
00554    return output.str();
00555 }
00556 
00557 // ------------ method called to for each event  ------------
00558 void
00559 MuonGeometrySanityCheck::analyze(const edm::Event &iEvent, const edm::EventSetup &iSetup) {
00560    edm::ESHandle<DTGeometry> dtGeometry;
00561    iSetup.get<MuonGeometryRecord>().get(dtGeometry);
00562 
00563    edm::ESHandle<CSCGeometry> cscGeometry;
00564    iSetup.get<MuonGeometryRecord>().get(cscGeometry);
00565 
00566    int num_transformed = 0;
00567    int num_tested = 0;
00568    int num_bad = 0;
00569    for (std::vector<MuonGeometrySanityCheckPoint>::const_iterator point = m_points.begin();  point != m_points.end();  ++point) {
00570       num_transformed++;
00571 
00572       bool dt = (point->detector.subdetId() == MuonSubdetId::DT);
00573 
00574       // convert the displacement vector into the chosen coordinate system and add it to the chamber's position
00575       GlobalPoint chamberPos;
00576       if (dt) chamberPos = dtGeometry->idToDet(point->detector)->surface().toGlobal(LocalPoint(0., 0., 0.));
00577       else chamberPos = cscGeometry->idToDet(point->detector)->surface().toGlobal(LocalPoint(0., 0., 0.));
00578 
00579       GlobalPoint result;
00580       if (point->frame == MuonGeometrySanityCheckPoint::kGlobal) {
00581          result = GlobalPoint(chamberPos.x() + point->displacement.x(), chamberPos.y() + point->displacement.y(), chamberPos.z() + point->displacement.z());
00582       }
00583 
00584       else if (point->frame == MuonGeometrySanityCheckPoint::kLocal) {
00585          if (dt) result = dtGeometry->idToDet(point->detector)->surface().toGlobal(LocalPoint(point->displacement.x(), point->displacement.y(), point->displacement.z()));
00586          else result = cscGeometry->idToDet(point->detector)->surface().toGlobal(LocalPoint(point->displacement.x(), point->displacement.y(), point->displacement.z()));
00587       }
00588 
00589       else if (point->frame == MuonGeometrySanityCheckPoint::kChamber) {
00590          if (point->detector.subdetId() == MuonSubdetId::DT) {
00591             DTChamberId id(point->detector);
00592             if (dt) result = dtGeometry->idToDet(id)->surface().toGlobal(LocalPoint(point->displacement.x(), point->displacement.y(), point->displacement.z()));
00593             else result = cscGeometry->idToDet(id)->surface().toGlobal(LocalPoint(point->displacement.x(), point->displacement.y(), point->displacement.z()));
00594          }
00595          else if (point->detector.subdetId() == MuonSubdetId::CSC) {
00596             CSCDetId cscid(point->detector);
00597             CSCDetId id(cscid.endcap(), cscid.station(), cscid.ring(), cscid.chamber());
00598             if (dt) result = dtGeometry->idToDet(id)->surface().toGlobal(LocalPoint(point->displacement.x(), point->displacement.y(), point->displacement.z()));
00599             else result = cscGeometry->idToDet(id)->surface().toGlobal(LocalPoint(point->displacement.x(), point->displacement.y(), point->displacement.z()));
00600          }
00601          else { assert(false); }
00602       }
00603 
00604       else if (point->frame == MuonGeometrySanityCheckPoint::kCustom) {
00605          GlobalPoint transformed = point->customFrame->transform(point->displacement);
00606          result = GlobalPoint(chamberPos.x() + transformed.x(), chamberPos.y() + transformed.y(), chamberPos.z() + transformed.z());
00607       }
00608 
00609       else { assert(false); }
00610 
00611       // convert the result into the chosen output coordinate system
00612       if (point->outputFrame == MuonGeometrySanityCheckPoint::kGlobal) { }
00613 
00614       else if (point->outputFrame == MuonGeometrySanityCheckPoint::kLocal) {
00615          LocalPoint transformed;
00616          if (dt) transformed = dtGeometry->idToDet(point->detector)->surface().toLocal(result);
00617          else transformed = cscGeometry->idToDet(point->detector)->surface().toLocal(result);
00618          result = GlobalPoint(transformed.x(), transformed.y(), transformed.z());
00619       }
00620 
00621       else if (point->outputFrame == MuonGeometrySanityCheckPoint::kChamber) {
00622          if (point->detector.subdetId() == MuonSubdetId::DT) {
00623             DTChamberId id(point->detector);
00624             LocalPoint transformed;
00625             if (dt) transformed = dtGeometry->idToDet(id)->surface().toLocal(result);
00626             else transformed = cscGeometry->idToDet(id)->surface().toLocal(result);
00627             result = GlobalPoint(transformed.x(), transformed.y(), transformed.z());
00628          }
00629          else if (point->detector.subdetId() == MuonSubdetId::CSC) {
00630             CSCDetId cscid(point->detector);
00631             CSCDetId id(cscid.endcap(), cscid.station(), cscid.ring(), cscid.chamber());
00632             LocalPoint transformed;
00633             if (dt) transformed = dtGeometry->idToDet(id)->surface().toLocal(result);
00634             else transformed = cscGeometry->idToDet(id)->surface().toLocal(result);
00635             result = GlobalPoint(transformed.x(), transformed.y(), transformed.z());
00636          }
00637          else { assert(false); }
00638       }
00639 
00640       else if (point->outputFrame == MuonGeometrySanityCheckPoint::kCustom) {
00641          result = point->outputCustomFrame->transformInverse(result);
00642       }
00643 
00644       std::stringstream output;
00645       output << prefix << " " << point->name << " " << point->detName() << " " << result.x() << " " << result.y() << " " << result.z();
00646 
00647       bool bad = false;
00648       if (point->has_expectation) {
00649          num_tested++;
00650          double residx = result.x() - point->expectation.x();
00651          double residy = result.y() - point->expectation.y();
00652          double residz = result.z() - point->expectation.z();
00653 
00654          if (fabs(residx) > tolerance  ||  fabs(residy) > tolerance  ||  fabs(residz) > tolerance) {
00655             num_bad++;
00656             bad = true;
00657             output << " BAD " << residx << " " << residy << " " << residz << std::endl;
00658          }
00659          else {
00660             output << " GOOD " << residx << " " << residy << " " << residz << std::endl;
00661          }
00662       }
00663       else {
00664          output << " UNTESTED 0 0 0" << std::endl;
00665       }
00666 
00667       if (printout == std::string("all")  ||  (printout == std::string("bad")  &&  bad)) {
00668          std::cout << output.str();
00669       }
00670    }
00671 
00672    std::cout << std::endl << "SUMMARY transformed: " << num_transformed << " tested: " << num_tested << " bad: " << num_bad << " good: " << (num_tested - num_bad) << std::endl;
00673 }
00674 
00675 //define this as a plug-in
00676 DEFINE_FWK_MODULE(MuonGeometrySanityCheck);