CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/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.5 2011/11/02 07:29:39 mussgill 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       if (detName.substr(index, 1) == std::string("/")) {
00282          index++;
00283          while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00284             superlayer *= 10;
00285             superlayer += number(detName.substr(index, 1));
00286             superlayer_digit = true;
00287             index++;
00288          }
00289          if (!superlayer_digit) parsing_error = true;
00290 
00291          if (detName.substr(index, 1) == std::string("/")) {
00292             index++;
00293             while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00294                layer *= 10;
00295                layer += number(detName.substr(index, 1));
00296                index++;
00297             }
00298          }
00299       }
00300 
00301       if (!parsing_error) {
00302          bool no_such_chamber = false;
00303          
00304          if (wheel < -2  ||  wheel > 2) no_such_chamber = true;
00305          if (station < 1  ||  station > 4) no_such_chamber = true;
00306          if (station == 4  &&  (sector < 1  ||  sector > 14)) no_such_chamber = true;
00307          if (station < 4  &&  (sector < 1  ||  sector > 12)) no_such_chamber = true;
00308          
00309          if (no_such_chamber) {
00310             throw cms::Exception("BadConfig") << "Chamber doesn't exist: MB" << (plus ? "+" : "-") << wheel << "/" << station << "/" << sector << std::endl;
00311          }
00312 
00313          if (superlayer == 0) {
00314             detector = DTChamberId(wheel, station, sector);
00315             type = kDTChamber;
00316          }
00317          else {
00318             bool no_such_superlayer = false;
00319             if (superlayer < 1  ||  superlayer > 3) no_such_superlayer = true;
00320             if (station == 4  &&  superlayer == 2) no_such_superlayer = true;
00321 
00322             if (no_such_superlayer) {
00323                throw cms::Exception("BadConfig") << "Superlayer doesn't exist: MB" << (plus ? "+" : "-") << wheel << "/" << station << "/" << sector << "/" << superlayer << std::endl;
00324             }
00325 
00326             if (layer == 0) {
00327                detector = DTSuperLayerId(wheel, station, sector, superlayer);
00328                type = kDTSuperLayer;
00329             }
00330             else {
00331                bool no_such_layer = false;
00332                if (layer < 1  ||  layer > 4) no_such_layer = true;
00333 
00334                if (no_such_layer) {
00335                   throw cms::Exception("BadConfig") << "Layer doesn't exist: MB" << (plus ? "+" : "-") << wheel << "/" << station << "/" << sector << "/" << superlayer << "/" << layer << std::endl;
00336                }
00337 
00338                detector = DTLayerId(wheel, station, sector, superlayer, layer);
00339                type = kDTLayer;
00340             }
00341          }
00342       }
00343    }
00344    else if (!parsing_error  &&  endcap) {
00345       int index = 2;
00346 
00347       bool plus = true;
00348       if (detName.substr(index, 1) == std::string("+")) {
00349          plus = true;
00350          index++;
00351       }
00352       else if (detName.substr(index, 1) == std::string("-")) {
00353          plus = false;
00354          index++;
00355       }
00356       else parsing_error = true;
00357 
00358       int station = 0;
00359       bool station_digit = false;
00360       while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00361          station *= 10;
00362          station += number(detName.substr(index, 1));
00363          station_digit = true;
00364          index++;
00365       }
00366       if (!plus) station *= -1;
00367       if (!station_digit) parsing_error = true;
00368 
00369       if (detName.substr(index, 1) != std::string("/")) parsing_error = true;
00370       index++;
00371 
00372       int ring = 0;
00373       bool ring_digit = false;
00374       while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00375          ring *= 10;
00376          ring += number(detName.substr(index, 1));
00377          ring_digit = true;
00378          index++;
00379       }
00380       if (!ring_digit) parsing_error = true;
00381       
00382       if (detName.substr(index, 1) != std::string("/")) parsing_error = true;
00383       index++;
00384       
00385       int chamber = 0;
00386       bool chamber_digit = false;
00387       while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00388          chamber *= 10;
00389          chamber += number(detName.substr(index, 1));
00390          chamber_digit = true;
00391          index++;
00392       }
00393       if (!chamber_digit) parsing_error = true;
00394 
00395       // this is optional
00396       int layer = 0;
00397       bool layer_digit = false;
00398       if (detName.substr(index, 1) == std::string("/")) {
00399          index++;
00400          while (!parsing_error  &&  numeric(detName.substr(index, 1))) {
00401             layer *= 10;
00402             layer += number(detName.substr(index, 1));
00403             layer_digit = true;
00404             index++;
00405          }
00406          if (!layer_digit) parsing_error = true;
00407       }
00408 
00409       if (!parsing_error) {
00410          bool no_such_chamber = false;
00411 
00412          int endcap = (station > 0 ? 1 : 2);
00413          station = abs(station);
00414          if (station < 1  ||  station > 4) no_such_chamber = true;
00415          if (station == 1  &&  (ring < 1  ||  ring > 4)) no_such_chamber = true;
00416          if (station > 1  &&  (ring < 1  ||  ring > 2)) no_such_chamber = true;
00417          if (station == 1  &&  (chamber < 1  ||  chamber > 36)) no_such_chamber = true;
00418          if (station > 1  &&  ring == 1  &&  (chamber < 1  ||  chamber > 18)) no_such_chamber = true;
00419          if (station > 1  &&  ring == 2  &&  (chamber < 1  ||  chamber > 36)) no_such_chamber = true;
00420 
00421          if (no_such_chamber) {
00422             throw cms::Exception("BadConfig") << "Chamber doesn't exist: ME" << (endcap == 1 ? "+" : "-") << station << "/" << ring << "/" << chamber << std::endl;
00423          }
00424 
00425          if (layer == 0) {
00426             detector = CSCDetId(endcap, station, ring, chamber);
00427             type = kCSCChamber;
00428          }
00429          else {
00430             bool no_such_layer = false;
00431             if (layer < 1  ||  layer > 6) no_such_layer = true;
00432 
00433             if (no_such_layer) {
00434                throw cms::Exception("BadConfig") << "Layer doesn't exist: ME" << (endcap == 1 ? "+" : "-") << station << "/" << ring << "/" << chamber << "/" << layer << std::endl;
00435             }
00436 
00437             detector = CSCDetId(endcap, station, ring, chamber, layer);
00438             type = kCSCLayer;
00439          }
00440       }
00441    }
00442 
00443    if (parsing_error) {
00444       throw cms::Exception("BadConfig") << "Detector name is malformed: " << detName << std::endl;
00445    }
00446 
00447    std::string frameName = iConfig.getParameter<std::string>("frame");
00448    const std::map<std::string,const MuonGeometrySanityCheckCustomFrame*>::const_iterator frameIter = frames.find(frameName);
00449    if (frameName == std::string("global")) {
00450       frame = kGlobal;
00451       customFrame = NULL;
00452    }
00453    else if (frameName == std::string("local")) {
00454       frame = kLocal;
00455       customFrame = NULL;
00456    }
00457    else if (frameName == std::string("chamber")) {
00458       frame = kChamber;
00459       customFrame = NULL;
00460    }
00461    else if (frameIter != frames.end()) {
00462       frame = kCustom;
00463       customFrame = frameIter->second;
00464    }
00465    else {
00466       throw cms::Exception("BadConfig") << "Frame \"" << frameName << "\" has not been defined." << std::endl;
00467    }
00468 
00469    std::vector<double> point = iConfig.getParameter<std::vector<double> >("displacement");
00470    if (point.size() != 3) {
00471       throw cms::Exception("BadConfig") << "Displacement relative to detector " << detName << " doesn't have exactly three components." << std::endl;
00472    }
00473 
00474    displacement = GlobalPoint(point[0], point[1], point[2]);
00475 
00476    const edm::Entry *entry = iConfig.retrieveUnknown("expectation");
00477    if (entry != NULL) {
00478       has_expectation = true;
00479 
00480       point = iConfig.getParameter<std::vector<double> >("expectation");
00481       if (point.size() != 3) {
00482          throw cms::Exception("BadConfig") << "Expectation for detector " << detName << ", displacement " << displacement << " doesn't have exactly three components." << std::endl;
00483       }
00484 
00485       expectation = GlobalPoint(point[0], point[1], point[2]);
00486    }
00487    else {
00488       has_expectation = false;
00489    }
00490 
00491    entry = iConfig.retrieveUnknown("name");
00492    if (entry != NULL) {
00493       name = iConfig.getParameter<std::string>("name");
00494    }
00495    else {
00496       name = std::string("anonymous");
00497    }
00498 
00499    entry = iConfig.retrieveUnknown("outputFrame");
00500    if (entry != NULL) {
00501       frameName = iConfig.getParameter<std::string>("outputFrame");
00502       const std::map<std::string,const MuonGeometrySanityCheckCustomFrame*>::const_iterator frameIter = frames.find(frameName);
00503       if (frameName == std::string("global")) {
00504          outputFrame = kGlobal;
00505          outputCustomFrame = NULL;
00506       }
00507       else if (frameName == std::string("local")) {
00508          outputFrame = kLocal;
00509          outputCustomFrame = NULL;
00510       }
00511       else if (frameName == std::string("chamber")) {
00512          outputFrame = kChamber;
00513          outputCustomFrame = NULL;
00514       }
00515       else if (frameIter != frames.end()) {
00516          outputFrame = kCustom;
00517          outputCustomFrame = frameIter->second;
00518       }
00519       else {
00520          throw cms::Exception("BadConfig") << "Frame \"" << frameName << "\" has not been defined." << std::endl;
00521       }
00522    }
00523    else {
00524       outputFrame = kGlobal;
00525       outputCustomFrame = NULL;
00526    }
00527 }
00528 
00529 std::string MuonGeometrySanityCheckPoint::detName() const {
00530    std::stringstream output;
00531    if (type == kDTChamber) {
00532       DTChamberId id(detector);
00533       output << "MB" << (id.wheel() > 0 ? "+" : "") << id.wheel() << "/" << id.station() << "/" << id.sector();
00534    }
00535    else if (type == kDTSuperLayer) {
00536       DTSuperLayerId id(detector);
00537       output << "MB" << (id.wheel() > 0 ? "+" : "") << id.wheel() << "/" << id.station() << "/" << id.sector() << "/" << id.superlayer();
00538    }
00539    else if (type == kDTLayer) {
00540       DTLayerId id(detector);
00541       output << "MB" << (id.wheel() > 0 ? "+" : "") << id.wheel() << "/" << id.station() << "/" << id.sector() << "/" << id.superlayer() << "/" << id.layer();
00542    }
00543    else if (type == kCSCChamber) {
00544       CSCDetId id(detector);
00545       output << "ME" << (id.endcap() == 1 ? "+" : "-") << id.station() << "/" << id.ring() << "/" << id.chamber();
00546    }
00547    else if (type == kCSCLayer) {
00548       CSCDetId id(detector);
00549       output << "ME" << (id.endcap() == 1 ? "+" : "-") << id.station() << "/" << id.ring() << "/" << id.chamber() << "/" << id.layer();
00550    }
00551    else assert(false);
00552    return output.str();
00553 }
00554 
00555 // ------------ method called to for each event  ------------
00556 void
00557 MuonGeometrySanityCheck::analyze(const edm::Event &iEvent, const edm::EventSetup &iSetup) {
00558    edm::ESHandle<DTGeometry> dtGeometry;
00559    iSetup.get<MuonGeometryRecord>().get(dtGeometry);
00560 
00561    edm::ESHandle<CSCGeometry> cscGeometry;
00562    iSetup.get<MuonGeometryRecord>().get(cscGeometry);
00563 
00564    int num_transformed = 0;
00565    int num_tested = 0;
00566    int num_bad = 0;
00567    for (std::vector<MuonGeometrySanityCheckPoint>::const_iterator point = m_points.begin();  point != m_points.end();  ++point) {
00568       num_transformed++;
00569 
00570       bool dt = (point->detector.subdetId() == MuonSubdetId::DT);
00571 
00572       // convert the displacement vector into the chosen coordinate system and add it to the chamber's position
00573       GlobalPoint chamberPos;
00574       if (dt) chamberPos = dtGeometry->idToDet(point->detector)->surface().toGlobal(LocalPoint(0., 0., 0.));
00575       else chamberPos = cscGeometry->idToDet(point->detector)->surface().toGlobal(LocalPoint(0., 0., 0.));
00576 
00577       GlobalPoint result;
00578       if (point->frame == MuonGeometrySanityCheckPoint::kGlobal) {
00579          result = GlobalPoint(chamberPos.x() + point->displacement.x(), chamberPos.y() + point->displacement.y(), chamberPos.z() + point->displacement.z());
00580       }
00581 
00582       else if (point->frame == MuonGeometrySanityCheckPoint::kLocal) {
00583          if (dt) result = dtGeometry->idToDet(point->detector)->surface().toGlobal(LocalPoint(point->displacement.x(), point->displacement.y(), point->displacement.z()));
00584          else result = cscGeometry->idToDet(point->detector)->surface().toGlobal(LocalPoint(point->displacement.x(), point->displacement.y(), point->displacement.z()));
00585       }
00586 
00587       else if (point->frame == MuonGeometrySanityCheckPoint::kChamber) {
00588          if (point->detector.subdetId() == MuonSubdetId::DT) {
00589             DTChamberId id(point->detector);
00590             if (dt) result = dtGeometry->idToDet(id)->surface().toGlobal(LocalPoint(point->displacement.x(), point->displacement.y(), point->displacement.z()));
00591             else result = cscGeometry->idToDet(id)->surface().toGlobal(LocalPoint(point->displacement.x(), point->displacement.y(), point->displacement.z()));
00592          }
00593          else if (point->detector.subdetId() == MuonSubdetId::CSC) {
00594             CSCDetId cscid(point->detector);
00595             CSCDetId id(cscid.endcap(), cscid.station(), cscid.ring(), cscid.chamber());
00596             if (dt) result = dtGeometry->idToDet(id)->surface().toGlobal(LocalPoint(point->displacement.x(), point->displacement.y(), point->displacement.z()));
00597             else result = cscGeometry->idToDet(id)->surface().toGlobal(LocalPoint(point->displacement.x(), point->displacement.y(), point->displacement.z()));
00598          }
00599          else { assert(false); }
00600       }
00601 
00602       else if (point->frame == MuonGeometrySanityCheckPoint::kCustom) {
00603         GlobalPoint transformed = point->customFrame->transform(point->displacement);
00604         result = GlobalPoint(chamberPos.x() + transformed.x(), chamberPos.y() + transformed.y(), chamberPos.z() + transformed.z());
00605       }
00606 
00607       else { assert(false); }
00608 
00609       // convert the result into the chosen output coordinate system
00610       if (point->outputFrame == MuonGeometrySanityCheckPoint::kGlobal) { }
00611 
00612       else if (point->outputFrame == MuonGeometrySanityCheckPoint::kLocal) {
00613         LocalPoint transformed;
00614         if (dt) transformed = dtGeometry->idToDet(point->detector)->surface().toLocal(result);
00615         else transformed = cscGeometry->idToDet(point->detector)->surface().toLocal(result);
00616         result = GlobalPoint(transformed.x(), transformed.y(), transformed.z());
00617       }
00618 
00619       else if (point->outputFrame == MuonGeometrySanityCheckPoint::kChamber) {
00620          if (point->detector.subdetId() == MuonSubdetId::DT) {
00621             DTChamberId id(point->detector);
00622             LocalPoint transformed;
00623             if (dt) transformed = dtGeometry->idToDet(id)->surface().toLocal(result);
00624             else transformed = cscGeometry->idToDet(id)->surface().toLocal(result);
00625             result = GlobalPoint(transformed.x(), transformed.y(), transformed.z());
00626          }
00627          else if (point->detector.subdetId() == MuonSubdetId::CSC) {
00628             CSCDetId cscid(point->detector);
00629             CSCDetId id(cscid.endcap(), cscid.station(), cscid.ring(), cscid.chamber());
00630             LocalPoint transformed;
00631             if (dt) transformed = dtGeometry->idToDet(id)->surface().toLocal(result);
00632             else transformed = cscGeometry->idToDet(id)->surface().toLocal(result);
00633             result = GlobalPoint(transformed.x(), transformed.y(), transformed.z());
00634          }
00635          else { assert(false); }
00636       }
00637 
00638       else if (point->outputFrame == MuonGeometrySanityCheckPoint::kCustom) {
00639          result = point->outputCustomFrame->transformInverse(result);
00640       }
00641 
00642       std::stringstream output;
00643       output << prefix << " " << point->name << " " << point->detName() << " " << result.x() << " " << result.y() << " " << result.z();
00644 
00645       bool bad = false;
00646       if (point->has_expectation) {
00647          num_tested++;
00648          double residx = result.x() - point->expectation.x();
00649          double residy = result.y() - point->expectation.y();
00650          double residz = result.z() - point->expectation.z();
00651 
00652          if (fabs(residx) > tolerance  ||  fabs(residy) > tolerance  ||  fabs(residz) > tolerance) {
00653             num_bad++;
00654             bad = true;
00655             output << " BAD " << residx << " " << residy << " " << residz << std::endl;
00656          }
00657          else {
00658             output << " GOOD " << residx << " " << residy << " " << residz << std::endl;
00659          }
00660       }
00661       else {
00662          output << " UNTESTED 0 0 0" << std::endl;
00663       }
00664 
00665       if (printout == std::string("all")  ||  (printout == std::string("bad")  &&  bad)) {
00666          std::cout << output.str();
00667       }
00668    }
00669 
00670    std::cout << std::endl << "SUMMARY transformed: " << num_transformed << " tested: " << num_tested << " bad: " << num_bad << " good: " << (num_tested - num_bad) << std::endl;
00671 }
00672 
00673 //define this as a plug-in
00674 DEFINE_FWK_MODULE(MuonGeometrySanityCheck);