CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/Alignment/MuonAlignment/src/MuonAlignmentInputXML.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     MuonAlignment
00004 // Class  :     MuonAlignmentInputXML
00005 // 
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Jim Pivarski
00010 //         Created:  Mon Mar 10 16:37:40 CDT 2008
00011 // $Id: MuonAlignmentInputXML.cc,v 1.16 2011/03/22 09:49:50 innocent Exp $
00012 //
00013 
00014 // system include files
00015 #include "FWCore/Framework/interface/ESHandle.h"
00016 
00017 // Xerces include files
00018 #include "xercesc/parsers/XercesDOMParser.hpp"
00019 #include "xercesc/dom/DOM.hpp"
00020 #include "xercesc/sax/HandlerBase.hpp"
00021 #include "xercesc/util/XMLString.hpp"
00022 #include "xercesc/util/PlatformUtils.hpp"
00023 #include "xercesc/util/XercesDefs.hpp"
00024 XERCES_CPP_NAMESPACE_USE
00025 
00026 // user include files
00027 #include "Alignment/MuonAlignment/interface/MuonAlignmentInputXML.h"
00028 #include "Alignment/CommonAlignment/interface/StructureType.h"
00029 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00030 #include "DataFormats/MuonDetId/interface/DTLayerId.h"
00031 #include "Alignment/CommonAlignment/interface/SurveyDet.h"
00032 #include "DataFormats/TrackingRecHit/interface/AlignmentPositionError.h"
00033 
00034 //
00035 // constants, enums and typedefs
00036 //
00037 
00038 //
00039 // static data member definitions
00040 //
00041 
00042 //
00043 // constructors and destructor
00044 //
00045 MuonAlignmentInputXML::MuonAlignmentInputXML(std::string fileName)
00046    : m_fileName(fileName)
00047 {
00048    str_operation = XMLString::transcode("operation");
00049    str_collection = XMLString::transcode("collection");
00050    str_name = XMLString::transcode("name");
00051    str_DTBarrel = XMLString::transcode("DTBarrel");
00052    str_DTWheel = XMLString::transcode("DTWheel");
00053    str_DTStation = XMLString::transcode("DTStation");
00054    str_DTChamber = XMLString::transcode("DTChamber");
00055    str_DTSuperLayer = XMLString::transcode("DTSuperLayer");
00056    str_DTLayer = XMLString::transcode("DTLayer");
00057    str_CSCEndcap = XMLString::transcode("CSCEndcap");
00058    str_CSCStation = XMLString::transcode("CSCStation");
00059    str_CSCRing = XMLString::transcode("CSCRing");
00060    str_CSCChamber = XMLString::transcode("CSCChamber");
00061    str_CSCLayer = XMLString::transcode("CSCLayer");
00062    str_setposition = XMLString::transcode("setposition");
00063    str_setape = XMLString::transcode("setape");
00064    str_setsurveyerr = XMLString::transcode("setsurveyerr");
00065    str_moveglobal = XMLString::transcode("moveglobal");
00066    str_movelocal = XMLString::transcode("movelocal");
00067    str_rotatelocal = XMLString::transcode("rotatelocal");
00068    str_rotatebeamline = XMLString::transcode("rotatebeamline");
00069    str_rotateglobalaxis = XMLString::transcode("rotateglobalaxis");
00070    str_relativeto = XMLString::transcode("relativeto");
00071    str_rawId = XMLString::transcode("rawId");
00072    str_wheel = XMLString::transcode("wheel");
00073    str_station = XMLString::transcode("station");
00074    str_sector = XMLString::transcode("sector");
00075    str_superlayer = XMLString::transcode("superlayer");
00076    str_layer = XMLString::transcode("layer");
00077    str_endcap = XMLString::transcode("endcap");
00078    str_ring = XMLString::transcode("ring");
00079    str_chamber = XMLString::transcode("chamber");
00080    str_axisx = XMLString::transcode("axisx");
00081    str_axisy = XMLString::transcode("axisy");
00082    str_axisz = XMLString::transcode("axisz");
00083    str_angle = XMLString::transcode("angle");
00084    str_x = XMLString::transcode("x");
00085    str_y = XMLString::transcode("y");
00086    str_z = XMLString::transcode("z");
00087    str_phix = XMLString::transcode("phix");
00088    str_phiy = XMLString::transcode("phiy");
00089    str_phiz = XMLString::transcode("phiz");
00090    str_alpha = XMLString::transcode("alpha");
00091    str_beta = XMLString::transcode("beta");
00092    str_gamma = XMLString::transcode("gamma");
00093    str_rphi = XMLString::transcode("rphi");
00094    str_phi = XMLString::transcode("phi");
00095    str_xx = XMLString::transcode("xx");
00096    str_xy = XMLString::transcode("xy");
00097    str_xz = XMLString::transcode("xz");
00098    str_xa = XMLString::transcode("xa");
00099    str_xb = XMLString::transcode("xb");
00100    str_xc = XMLString::transcode("xc");
00101    str_yy = XMLString::transcode("yy");
00102    str_yz = XMLString::transcode("yz");
00103    str_ya = XMLString::transcode("ya");
00104    str_yb = XMLString::transcode("yb");
00105    str_yc = XMLString::transcode("yc");
00106    str_zz = XMLString::transcode("zz");
00107    str_za = XMLString::transcode("za");
00108    str_zb = XMLString::transcode("zb");
00109    str_zc = XMLString::transcode("zc");
00110    str_aa = XMLString::transcode("aa");
00111    str_ab = XMLString::transcode("ab");
00112    str_ac = XMLString::transcode("ac");
00113    str_bb = XMLString::transcode("bb");
00114    str_bc = XMLString::transcode("bc");
00115    str_cc = XMLString::transcode("cc");
00116    str_none = XMLString::transcode("none");
00117    str_ideal = XMLString::transcode("ideal");
00118    str_container = XMLString::transcode("container");
00119 }
00120 
00121 // MuonAlignmentInputXML::MuonAlignmentInputXML(const MuonAlignmentInputXML& rhs)
00122 // {
00123 //    // do actual copying here;
00124 // }
00125 
00126 MuonAlignmentInputXML::~MuonAlignmentInputXML() {
00127    XMLString::release(&str_operation);
00128    XMLString::release(&str_collection);
00129    XMLString::release(&str_name);
00130    XMLString::release(&str_DTBarrel);
00131    XMLString::release(&str_DTWheel);
00132    XMLString::release(&str_DTStation);
00133    XMLString::release(&str_DTChamber);
00134    XMLString::release(&str_DTSuperLayer);
00135    XMLString::release(&str_DTLayer);
00136    XMLString::release(&str_CSCEndcap);
00137    XMLString::release(&str_CSCStation);
00138    XMLString::release(&str_CSCRing);
00139    XMLString::release(&str_CSCChamber);
00140    XMLString::release(&str_CSCLayer);
00141    XMLString::release(&str_setposition);
00142    XMLString::release(&str_setape);
00143    XMLString::release(&str_setsurveyerr);
00144    XMLString::release(&str_moveglobal);
00145    XMLString::release(&str_movelocal);
00146    XMLString::release(&str_rotatelocal);
00147    XMLString::release(&str_rotatebeamline);
00148    XMLString::release(&str_rotateglobalaxis);
00149    XMLString::release(&str_relativeto);
00150    XMLString::release(&str_rawId);
00151    XMLString::release(&str_wheel);
00152    XMLString::release(&str_station);
00153    XMLString::release(&str_sector);
00154    XMLString::release(&str_superlayer);
00155    XMLString::release(&str_layer);
00156    XMLString::release(&str_endcap);
00157    XMLString::release(&str_ring);
00158    XMLString::release(&str_chamber);
00159    XMLString::release(&str_axisx);
00160    XMLString::release(&str_axisy);
00161    XMLString::release(&str_axisz);
00162    XMLString::release(&str_angle);
00163    XMLString::release(&str_x);
00164    XMLString::release(&str_y);
00165    XMLString::release(&str_z);
00166    XMLString::release(&str_phix);
00167    XMLString::release(&str_phiy);
00168    XMLString::release(&str_phiz);
00169    XMLString::release(&str_alpha);
00170    XMLString::release(&str_beta);
00171    XMLString::release(&str_gamma);
00172    XMLString::release(&str_rphi);
00173    XMLString::release(&str_phi);
00174    XMLString::release(&str_xx);
00175    XMLString::release(&str_xy);
00176    XMLString::release(&str_xz);
00177    XMLString::release(&str_xa);
00178    XMLString::release(&str_xb);
00179    XMLString::release(&str_xc);
00180    XMLString::release(&str_yy);
00181    XMLString::release(&str_yz);
00182    XMLString::release(&str_ya);
00183    XMLString::release(&str_yb);
00184    XMLString::release(&str_yc);
00185    XMLString::release(&str_zz);
00186    XMLString::release(&str_za);
00187    XMLString::release(&str_zb);
00188    XMLString::release(&str_zc);
00189    XMLString::release(&str_aa);
00190    XMLString::release(&str_ab);
00191    XMLString::release(&str_ac);
00192    XMLString::release(&str_bb);
00193    XMLString::release(&str_bc);
00194    XMLString::release(&str_cc);
00195    XMLString::release(&str_none);
00196    XMLString::release(&str_ideal);
00197    XMLString::release(&str_container);
00198 }
00199 
00200 //
00201 // assignment operators
00202 //
00203 // const MuonAlignmentInputXML& MuonAlignmentInputXML::operator=(const MuonAlignmentInputXML& rhs)
00204 // {
00205 //   //An exception safe implementation is
00206 //   MuonAlignmentInputXML temp(rhs);
00207 //   swap(rhs);
00208 //
00209 //   return *this;
00210 // }
00211 
00212 //
00213 // member functions
00214 //
00215 
00216 void MuonAlignmentInputXML::recursiveGetId(std::map<unsigned int, Alignable*> &alignableNavigator, const std::vector<Alignable*> &alignables) const {
00217    for (std::vector<Alignable*>::const_iterator ali = alignables.begin();  ali != alignables.end();  ++ali) {
00218       if ((*ali)->alignableObjectId() == align::AlignableDetUnit  ||  (*ali)->alignableObjectId() == align::AlignableDet  ||
00219           (*ali)->alignableObjectId() == align::AlignableDTChamber  ||  (*ali)->alignableObjectId() == align::AlignableDTSuperLayer  ||  (*ali)->alignableObjectId() == align::AlignableDTLayer  ||
00220           (*ali)->alignableObjectId() == align::AlignableCSCChamber  ||  (*ali)->alignableObjectId() == align::AlignableCSCLayer) {
00221          alignableNavigator[(*ali)->geomDetId().rawId()] = *ali;
00222       }
00223       recursiveGetId(alignableNavigator, (*ali)->components());
00224    }
00225 }
00226 
00227 void MuonAlignmentInputXML::fillAliToIdeal(std::map<Alignable*, Alignable*> &alitoideal, const std::vector<Alignable*> alignables, const std::vector<Alignable*> ideals) const {
00228    std::vector<Alignable*>::const_iterator alignable = alignables.begin();
00229    std::vector<Alignable*>::const_iterator ideal = ideals.begin();
00230 
00231    while (alignable != alignables.end()  &&  ideal != ideals.end()) {
00232       alitoideal[*alignable] = *ideal;
00233 
00234       fillAliToIdeal(alitoideal, (*alignable)->components(), (*ideal)->components());
00235 
00236       ++alignable;
00237       ++ideal;
00238    }
00239 
00240    if (alignable != alignables.end()  ||  ideal != ideals.end()) {
00241       throw cms::Exception("Alignment") << "alignable and ideal-alignable trees are out of sync (this should never happen)";
00242    }
00243 }
00244 
00245 AlignableMuon *MuonAlignmentInputXML::newAlignableMuon(const edm::EventSetup& iSetup) const {
00246    boost::shared_ptr<DTGeometry> dtGeometry = idealDTGeometry(iSetup);
00247    boost::shared_ptr<CSCGeometry> cscGeometry = idealCSCGeometry(iSetup);
00248 
00249    AlignableMuon *alignableMuon = new AlignableMuon(&(*dtGeometry), &(*cscGeometry));
00250    std::map<unsigned int, Alignable*> alignableNavigator;  // real AlignableNavigators don't have const methods
00251    recursiveGetId(alignableNavigator, alignableMuon->DTBarrel());
00252    recursiveGetId(alignableNavigator, alignableMuon->CSCEndcaps());
00253 
00254    AlignableMuon *ideal_alignableMuon = new AlignableMuon(&(*dtGeometry), &(*cscGeometry));
00255    std::map<unsigned int, Alignable*> ideal_alignableNavigator;  // real AlignableNavigators don't have const methods
00256    recursiveGetId(ideal_alignableNavigator, ideal_alignableMuon->DTBarrel());
00257    recursiveGetId(ideal_alignableNavigator, ideal_alignableMuon->CSCEndcaps());
00258 
00259    try {
00260       XMLPlatformUtils::Initialize();
00261    }
00262    catch (const XMLException &toCatch) {
00263       throw cms::Exception("XMLException") << "Xerces XML parser threw an exception on initialization." << std::endl;
00264    }
00265 
00266    XercesDOMParser *parser = new XercesDOMParser();
00267    parser->setValidationScheme(XercesDOMParser::Val_Always);
00268 
00269    ErrorHandler *errHandler = (ErrorHandler*)(new HandlerBase());
00270    parser->setErrorHandler(errHandler);
00271 
00272    try {
00273       parser->parse(m_fileName.c_str());
00274    }
00275    catch (const XMLException &toCatch) {
00276       char *message = XMLString::transcode(toCatch.getMessage());
00277       throw cms::Exception("XMLException") << "Xerces XML parser threw this exception: " << message << std::endl;
00278    }
00279    catch (const DOMException &toCatch) {
00280       char *message = XMLString::transcode(toCatch.msg);
00281       throw cms::Exception("XMLException") << "Xerces XML parser threw this exception: " << message << std::endl;
00282    }
00283    catch (const SAXException &toCatch) {
00284       char *message = XMLString::transcode(toCatch.getMessage());
00285       throw cms::Exception("XMLException") << "Xerces XML parser threw this exception: " << message << std::endl;
00286    }
00287    catch (...) {
00288       throw cms::Exception("XMLException") << "Xerces XML parser threw an unknown exception" << std::endl;
00289    }
00290 
00291    DOMDocument *doc = parser->getDocument();
00292    DOMElement *node_MuonAlignment = doc->getDocumentElement();
00293    DOMNodeList *collections = doc->getElementsByTagName(str_collection);
00294    DOMNodeList *operations = doc->getElementsByTagName(str_operation);
00295 
00296    std::map<Alignable*, Alignable*> alitoideal;
00297    fillAliToIdeal(alitoideal, alignableMuon->DTBarrel(), ideal_alignableMuon->DTBarrel());
00298    fillAliToIdeal(alitoideal, alignableMuon->CSCEndcaps(), ideal_alignableMuon->CSCEndcaps());
00299 
00300    std::map<std::string, std::map<Alignable*, bool> > alicollections;
00301    for (unsigned int i = 0;  i < collections->getLength();  i++) {
00302       DOMElement *collection = (DOMElement*)(collections->item(i));
00303       if (collection->getParentNode() == node_MuonAlignment) {
00304          DOMNodeList *children = collection->getChildNodes();
00305 
00306          DOMAttr *node_name = collection->getAttributeNode(str_name);
00307          if (node_name == NULL) {
00308             throw cms::Exception("XMLException") << "<collection> requires a name attribute" << std::endl;
00309          }
00310          char *ascii_name = XMLString::transcode(node_name->getValue());
00311          std::string name(ascii_name);
00312          XMLString::release(&ascii_name);
00313 
00314          std::map<Alignable*, bool> aliset;
00315          for (unsigned int j = 0;  j < children->getLength();  j++) {
00316             DOMNode *node = children->item(j);
00317 
00318             if (node->getNodeType() == DOMNode::ELEMENT_NODE) {
00319                Alignable *ali = getNode(alignableNavigator, (DOMElement*)(node));
00320                if (ali == NULL) {
00321                   throw cms::Exception("XMLException") << "<collection> must contain only alignables" << std::endl;
00322                }
00323 
00324                aliset[ali] = true;
00325             } // end if this node is an element
00326          } // end loop over collection's children
00327 
00328          alicollections[name] = aliset;
00329       } // end if this is a top-level collection
00330    } // end loop over collections
00331 
00332    for (unsigned int i = 0;  i < operations->getLength();  i++) {
00333       DOMElement *operation = (DOMElement*)(operations->item(i));
00334       if (operation->getParentNode() != node_MuonAlignment) {
00335          throw cms::Exception("XMLException") << "All operations must be top-level elements" << std::endl;
00336       }
00337 
00338       DOMNodeList *children = operation->getChildNodes();
00339 
00340       std::map<Alignable*, bool> aliset;
00341       std::vector<DOMNode*> nodesToRemove;
00342       for (unsigned int j = 0;  j < children->getLength();  j++) {
00343          DOMNode *node = children->item(j);
00344 
00345          if (node->getNodeType() == DOMNode::ELEMENT_NODE) {
00346             Alignable *ali = getNode(alignableNavigator, (DOMElement*)(node));
00347             if (ali != NULL) {
00348                aliset[ali] = true;
00349                nodesToRemove.push_back(node);
00350             } // end if this node is an alignable
00351 
00352             else if (XMLString::equals(node->getNodeName(), str_collection)) {
00353                DOMAttr *node_name = ((DOMElement*)(node))->getAttributeNode(str_name);
00354                if (node_name == NULL) {
00355                   throw cms::Exception("XMLException") << "<collection> requires a name attribute" << std::endl;
00356                }
00357                char *ascii_name = XMLString::transcode(node_name->getValue());
00358                std::string name(ascii_name);
00359                XMLString::release(&ascii_name);
00360 
00361                std::map<std::string, std::map<Alignable*, bool> >::const_iterator alicollections_iter = alicollections.find(name);
00362                if (alicollections_iter == alicollections.end()) {
00363                   throw cms::Exception("XMLException") << "<collection name=\"" << name << "\"> hasn't been defined" << std::endl;
00364                }
00365 
00366                for (std::map<Alignable*, bool>::const_iterator aliiter = alicollections_iter->second.begin();
00367                     aliiter != alicollections_iter->second.end();
00368                     ++aliiter) {
00369                   aliset[aliiter->first] = true;
00370                } // end loop over alignables in this collection
00371 
00372                nodesToRemove.push_back(node);
00373             } // end if this node is a collection
00374 
00375             else {} // anything else? assume it's a position/rotation directive
00376 
00377          } // end if node is node is an element
00378       } // end first loop over operation's children
00379 
00380       // from now on, we only want to see position/rotation directives
00381       for (std::vector<DOMNode*>::const_iterator node = nodesToRemove.begin();  node != nodesToRemove.end();  ++node) {
00382          operation->removeChild(*node);
00383       }
00384       children = operation->getChildNodes();
00385 
00386       for (unsigned int j = 0;  j < children->getLength();  j++) {
00387          DOMNode *node = children->item(j);
00388          if (node->getNodeType() == DOMNode::ELEMENT_NODE) {
00389 
00390             if (XMLString::equals(node->getNodeName(), str_setposition)) {
00391                do_setposition((DOMElement*)(node), aliset, alitoideal);
00392             }
00393 
00394             else if (XMLString::equals(node->getNodeName(), str_setape)) {
00395                do_setape((DOMElement*)(node), aliset, alitoideal);
00396             }
00397 
00398             else if (XMLString::equals(node->getNodeName(), str_setsurveyerr)) {
00399                do_setsurveyerr((DOMElement*)(node), aliset, alitoideal);
00400             }
00401 
00402             else if (XMLString::equals(node->getNodeName(), str_moveglobal)) {
00403                do_moveglobal((DOMElement*)(node), aliset, alitoideal);
00404             }
00405 
00406             else if (XMLString::equals(node->getNodeName(), str_movelocal)) {
00407                do_movelocal((DOMElement*)(node), aliset, alitoideal);
00408             }
00409 
00410             else if (XMLString::equals(node->getNodeName(), str_rotatelocal)) {
00411                do_rotatelocal((DOMElement*)(node), aliset, alitoideal);
00412             }
00413 
00414             else if (XMLString::equals(node->getNodeName(), str_rotatebeamline)) {
00415                do_rotatebeamline((DOMElement*)(node), aliset, alitoideal);
00416             }
00417 
00418             else if (XMLString::equals(node->getNodeName(), str_rotateglobalaxis)) {
00419                do_rotateglobalaxis((DOMElement*)(node), aliset, alitoideal);
00420             }
00421 
00422             else {
00423                char *message = XMLString::transcode(node->getNodeName());
00424                throw cms::Exception("XMLException") << "Unrecognized operation: \"" << message << "\"" << std::endl;
00425             }
00426 
00427          } // end if node is an element
00428       } // end second loop over operation's children
00429    } // end loop over operations
00430 
00431    delete parser;
00432    delete errHandler;
00433 
00434    XMLPlatformUtils::Terminate();
00435 
00436    delete ideal_alignableMuon;
00437    return alignableMuon;
00438 }
00439 
00440 Alignable *MuonAlignmentInputXML::getNode(std::map<unsigned int, Alignable*> &alignableNavigator, const XERCES_CPP_NAMESPACE::DOMElement *node) const {
00441    if (XMLString::equals(node->getNodeName(), str_DTBarrel)) return getDTnode(align::AlignableDTBarrel, alignableNavigator, node);
00442    else if (XMLString::equals(node->getNodeName(), str_DTWheel)) return getDTnode(align::AlignableDTWheel, alignableNavigator, node);
00443    else if (XMLString::equals(node->getNodeName(), str_DTStation)) return getDTnode(align::AlignableDTStation, alignableNavigator, node);
00444    else if (XMLString::equals(node->getNodeName(), str_DTChamber)) return getDTnode(align::AlignableDTChamber, alignableNavigator, node);
00445    else if (XMLString::equals(node->getNodeName(), str_DTSuperLayer)) return getDTnode(align::AlignableDTSuperLayer, alignableNavigator, node);
00446    else if (XMLString::equals(node->getNodeName(), str_DTLayer)) return getDTnode(align::AlignableDetUnit, alignableNavigator, node);
00447    else if (XMLString::equals(node->getNodeName(), str_CSCEndcap)) return getCSCnode(align::AlignableCSCEndcap, alignableNavigator, node);
00448    else if (XMLString::equals(node->getNodeName(), str_CSCStation)) return getCSCnode(align::AlignableCSCStation, alignableNavigator, node);
00449    else if (XMLString::equals(node->getNodeName(), str_CSCRing)) return getCSCnode(align::AlignableCSCRing, alignableNavigator, node);
00450    else if (XMLString::equals(node->getNodeName(), str_CSCChamber)) return getCSCnode(align::AlignableCSCChamber, alignableNavigator, node);
00451    else if (XMLString::equals(node->getNodeName(), str_CSCLayer)) return getCSCnode(align::AlignableDetUnit, alignableNavigator, node);
00452    else return NULL;
00453 }
00454 
00455 Alignable *MuonAlignmentInputXML::getDTnode(align::StructureType structureType, std::map<unsigned int, Alignable*> &alignableNavigator, const XERCES_CPP_NAMESPACE::DOMElement *node) const {
00456    unsigned int rawId = 0;
00457 
00458    DOMAttr *node_rawId = node->getAttributeNode(str_rawId);
00459    if (node_rawId != NULL) {
00460       try {
00461          rawId = XMLString::parseInt(node_rawId->getValue());
00462       }
00463       catch (const XMLException &toCatch) {
00464          throw cms::Exception("XMLException") << "Value of \"rawId\" must be an integer" << std::endl;
00465       }
00466    }
00467    else {
00468       int wheel, station, sector, superlayer, layer;
00469       wheel = station = sector = superlayer = layer = 1;
00470 
00471       if (structureType != align::AlignableDTBarrel) {
00472          DOMAttr *node_wheel = node->getAttributeNode(str_wheel);
00473          if (node_wheel == NULL) throw cms::Exception("XMLException") << "DT node is missing required \"wheel\" attribute" << std::endl;
00474          try {
00475             wheel = XMLString::parseInt(node_wheel->getValue());
00476          }
00477          catch (const XMLException &toCatch) {
00478             throw cms::Exception("XMLException") << "Value of \"wheel\" must be an integer" << std::endl;
00479          }
00480 
00481          if (structureType != align::AlignableDTWheel) {
00482             DOMAttr *node_station = node->getAttributeNode(str_station);
00483             if (node_station == NULL) throw cms::Exception("XMLException") << "DT node is missing required \"station\" attribute" << std::endl;
00484             try {
00485                station = XMLString::parseInt(node_station->getValue());
00486             }
00487             catch (const XMLException &toCatch) {
00488                throw cms::Exception("XMLException") << "Value of \"station\" must be an integer" << std::endl;
00489             }
00490 
00491             if (structureType != align::AlignableDTStation) {
00492                DOMAttr *node_sector = node->getAttributeNode(str_sector);
00493                if (node_sector == NULL) throw cms::Exception("XMLException") << "DT node is missing required \"sector\" attribute" << std::endl;
00494                try {
00495                   sector = XMLString::parseInt(node_sector->getValue());
00496                }
00497                catch (const XMLException &toCatch) {
00498                   throw cms::Exception("XMLException") << "Value of \"sector\" must be an integer" << std::endl;
00499                }
00500 
00501                if (structureType != align::AlignableDTChamber) {
00502                   DOMAttr *node_superlayer = node->getAttributeNode(str_superlayer);
00503                   if (node_superlayer == NULL) throw cms::Exception("XMLException") << "DT node is missing required \"superlayer\" attribute" << std::endl;
00504                   try {
00505                      superlayer = XMLString::parseInt(node_superlayer->getValue());
00506                   }
00507                   catch (const XMLException &toCatch) {
00508                      throw cms::Exception("XMLException") << "Value of \"superlayer\" must be an integer" << std::endl;
00509                   }
00510 
00511                   if (structureType != align::AlignableDTSuperLayer) {
00512                      DOMAttr *node_layer = node->getAttributeNode(str_layer);
00513                      if (node_layer == NULL) throw cms::Exception("XMLException") << "DT node is missing required \"layer\" attribute" << std::endl;
00514                      try {
00515                         layer = XMLString::parseInt(node_layer->getValue());
00516                      }
00517                      catch (const XMLException &toCatch) {
00518                         throw cms::Exception("XMLException") << "Value of \"layer\" must be an integer" << std::endl;
00519                      }
00520 
00521                   } // end if we need a layer number
00522                } // end if we need a superlayer number
00523             } // end if we need a sector number
00524          } // end if we need a station number
00525       } // end if we need a wheel number
00526 
00527       DTLayerId layerId(wheel, station, sector, superlayer, layer);
00528       rawId = layerId.rawId();
00529    } // end if it's specified by wheel, station, sector, superlayer, layer
00530 
00531    Alignable *ali = alignableNavigator[rawId];
00532    if (ali == NULL) throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not recognized" << std::endl;
00533 
00534    while (ali->alignableObjectId() != structureType) {
00535       ali = ali->mother();
00536 
00537       if (ali == NULL) {
00538          if (structureType == align::AlignableDTBarrel) throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not a DTBarrel" << std::endl;
00539          else if (structureType == align::AlignableDTWheel) throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not a DTWheel" << std::endl;
00540          else if (structureType == align::AlignableDTStation) throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not a DTStation" << std::endl;
00541          else if (structureType == align::AlignableDTChamber) throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not a DTChamber" << std::endl;
00542          else if (structureType == align::AlignableDTSuperLayer) throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not a DTSuperLayer" << std::endl;
00543          else if (structureType == align::AlignableDetUnit) throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not a DTLayer" << std::endl;
00544       }
00545    }
00546    return ali;
00547 }
00548 
00549 Alignable *MuonAlignmentInputXML::getCSCnode(align::StructureType structureType, std::map<unsigned int, Alignable*> &alignableNavigator, const XERCES_CPP_NAMESPACE::DOMElement *node) const {
00550    unsigned int rawId;
00551 
00552    DOMAttr *node_rawId = node->getAttributeNode(str_rawId);
00553    if (node_rawId != NULL) {
00554       try {
00555          rawId = XMLString::parseInt(node_rawId->getValue());
00556       }
00557       catch (const XMLException &toCatch) {
00558          throw cms::Exception("XMLException") << "Value of \"rawId\" must be an integer" << std::endl;
00559       }
00560    }
00561    else {
00562       int endcap, station, ring, chamber, layer;
00563       endcap = station = ring = chamber = layer = 1;
00564 
00565       DOMAttr *node_endcap = node->getAttributeNode(str_endcap);
00566       if (node_endcap == NULL) throw cms::Exception("XMLException") << "CSC node is missing required \"endcap\" attribute" << std::endl;
00567       try {
00568          endcap = XMLString::parseInt(node_endcap->getValue());
00569       }
00570       catch (const XMLException &toCatch) {
00571          throw cms::Exception("XMLException") << "Value of \"endcap\" must be an integer" << std::endl;
00572       }
00573       if (endcap == -1) endcap = 2;
00574 
00575       if (structureType != align::AlignableCSCEndcap) {
00576          DOMAttr *node_station = node->getAttributeNode(str_station);
00577          if (node_station == NULL) throw cms::Exception("XMLException") << "CSC node is missing required \"station\" attribute" << std::endl;
00578          try {
00579             station = XMLString::parseInt(node_station->getValue());
00580          }
00581          catch (const XMLException &toCatch) {
00582             throw cms::Exception("XMLException") << "Value of \"station\" must be an integer" << std::endl;
00583          }
00584 
00585          if (structureType != align::AlignableCSCStation) {
00586             DOMAttr *node_ring = node->getAttributeNode(str_ring);
00587             if (node_ring == NULL) throw cms::Exception("XMLException") << "CSC node is missing required \"ring\" attribute" << std::endl;
00588             try {
00589                ring = XMLString::parseInt(node_ring->getValue());
00590             }
00591             catch (const XMLException &toCatch) {
00592                throw cms::Exception("XMLException") << "Value of \"ring\" must be an integer" << std::endl;
00593             }
00594 
00595             if (structureType != align::AlignableCSCRing) {
00596                DOMAttr *node_chamber = node->getAttributeNode(str_chamber);
00597                if (node_chamber == NULL) throw cms::Exception("XMLException") << "CSC node is missing required \"chamber\" attribute" << std::endl;
00598                try {
00599                   chamber = XMLString::parseInt(node_chamber->getValue());
00600                }
00601                catch (const XMLException &toCatch) {
00602                   throw cms::Exception("XMLException") << "Value of \"chamber\" must be an integer" << std::endl;
00603                }
00604 
00605                if (structureType != align::AlignableCSCChamber) {
00606                   DOMAttr *node_layer = node->getAttributeNode(str_layer);
00607                   if (node_layer == NULL) throw cms::Exception("XMLException") << "CSC node is missing required \"layer\" attribute" << std::endl;
00608                   try {
00609                      layer = XMLString::parseInt(node_layer->getValue());
00610                   }
00611                   catch (const XMLException &toCatch) {
00612                      throw cms::Exception("XMLException") << "Value of \"layer\" must be an integer" << std::endl;
00613                   }
00614 
00615                } // end if we need a layer number
00616             } // end if we need a chamber number
00617          } // end if we need a ring number
00618       } // end if we need a station number
00619 
00620       CSCDetId layerId(endcap, station, ring, chamber, layer);
00621       rawId = layerId.rawId();
00622    } // end if it's specified by endcap, station, ring, chamber, layer
00623 
00624    Alignable *ali = alignableNavigator[rawId];
00625    if (ali == NULL) throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not recognized" << std::endl;
00626 
00627    while (ali->alignableObjectId() != structureType) {
00628       ali = ali->mother();
00629 
00630       if (ali == NULL) {
00631          if (structureType == align::AlignableCSCEndcap) throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not a CSCEndcap" << std::endl;
00632          else if (structureType == align::AlignableCSCStation) throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not a CSCStation" << std::endl;
00633          else if (structureType == align::AlignableCSCRing) throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not a CSCRing" << std::endl;
00634          else if (structureType == align::AlignableCSCChamber) throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not a CSCChamber" << std::endl;
00635          else if (structureType == align::AlignableDetUnit) throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not a CSCLayer" << std::endl;
00636       }
00637    }
00638    return ali;
00639 }
00640 
00641 double MuonAlignmentInputXML::parseDouble(const XMLCh *str, const char *attribute) const {
00642    unsigned int len = XMLString::stringLen(str);
00643    char *cstr = XMLString::transcode(str);
00644    std::stringstream errmessage;
00645    errmessage << "Value of \"" << attribute << "\" must be a double, not \"" << cstr << "\"" << std::endl;
00646 
00647    unsigned int i = 0;
00648 
00649    bool minus = false;
00650    if (cstr[i] == '-') {
00651       minus = true;
00652       i++;
00653    }
00654    else if (cstr[i] == '+') i++;
00655 
00656    double output = 0.;
00657 
00658    while (cstr[i] != '.'  &&  cstr[i] != 'e'  &&  cstr[i] != 'E'  &&  i < len) {
00659       if (cstr[i] < '0'  ||  cstr[i] > '9') {
00660          XMLString::release(&cstr);
00661          throw cms::Exception("XMLException") << errmessage.str();       
00662       }
00663 
00664       output *= 10;
00665       output += cstr[i] - '0';
00666       i++;
00667    }
00668 
00669    if (cstr[i] == '.') {
00670       double place = 0.1;
00671       i++;
00672 
00673       while (cstr[i] != 'e'  &&  cstr[i] != 'E'  &&  i < len) {
00674          if (cstr[i] < '0'  ||  cstr[i] > '9') {
00675             XMLString::release(&cstr);
00676             throw cms::Exception("XMLException") << errmessage.str();    
00677          }
00678          
00679          output += (cstr[i] - '0') * place;
00680          place /= 10.;
00681          i++;
00682       }
00683    }
00684 
00685    if (cstr[i] == 'e'  ||  cstr[i] == 'E') {
00686       i++;
00687 
00688       int exponent = 0;
00689       bool expminus = false;
00690       if (cstr[i] == '-') {
00691          expminus = true;
00692          i++;
00693       }
00694       else if (cstr[i] == '+') i++;
00695 
00696       while (i < len) {
00697          if (cstr[i] < '0'  ||  cstr[i] > '9') {
00698             XMLString::release(&cstr);
00699             throw cms::Exception("XMLException") << errmessage.str();    
00700          }
00701       
00702          exponent *= 10;
00703          exponent += cstr[i] - '0';
00704          i++;
00705       }
00706 
00707       if (expminus) exponent *= -1;
00708 
00709       output *= pow(10., exponent);
00710    }
00711 
00712    if (minus) output *= -1.;
00713 
00714    XMLString::release(&cstr);
00715    return output;
00716 }
00717 
00718 void MuonAlignmentInputXML::do_setposition(const XERCES_CPP_NAMESPACE::DOMElement *node, std::map<Alignable*, bool> &aliset, std::map<Alignable*, Alignable*> &alitoideal) const {
00719   DOMAttr *node_relativeto = node->getAttributeNode(str_relativeto);
00720   if (node_relativeto == NULL) throw cms::Exception("XMLException") << "<setposition> is missing required \"relativeto\" attribute" << std::endl;
00721 
00722   int relativeto = 0;
00723   if (XMLString::equals(node_relativeto->getValue(), str_none)) {
00724     relativeto = 0;
00725   }
00726   else if (XMLString::equals(node_relativeto->getValue(), str_ideal)) {
00727     relativeto = 1;
00728   }
00729   else if (XMLString::equals(node_relativeto->getValue(), str_container)) {
00730     relativeto = 2;
00731   }
00732   else {
00733     char *message = XMLString::transcode(node_relativeto->getValue());
00734     throw cms::Exception("XMLException") << "relativeto must be \"none\", \"ideal\", or \"container\", not \"" << message << "\"" << std::endl;
00735   }
00736 
00737   for (std::map<Alignable*, bool>::const_iterator aliiter = aliset.begin();  aliiter != aliset.end();  ++aliiter) {
00738     // first reconstruct the old position: how it would look in this coordinate system
00739 
00740     Alignable *ali = aliiter->first;
00741     Alignable *ideal = alitoideal[ali];
00742 
00743     align::PositionType oldpos = ali->globalPosition();
00744     align::RotationType oldrot = ali->globalRotation();
00745 
00746     if (relativeto == 0) {}
00747 
00748     else if (relativeto == 1) {
00749       align::PositionType idealPosition = ideal->globalPosition();
00750       align::RotationType idealRotation = ideal->globalRotation();
00751 
00752       oldpos = align::PositionType(idealRotation * (oldpos.basicVector() - idealPosition.basicVector()));
00753       oldrot = oldrot * idealRotation.transposed();
00754     }
00755 
00756     else if (relativeto == 2  &&  ali->mother() != NULL) {
00757       align::PositionType globalPosition = ali->mother()->globalPosition();
00758       align::RotationType globalRotation = ali->mother()->globalRotation();
00759 
00760       oldpos = align::PositionType(globalRotation * (oldpos.basicVector() - globalPosition.basicVector()));
00761       oldrot = oldrot * globalRotation.transposed();
00762     }
00763 
00764     double x = oldpos.x();
00765     double y = oldpos.y();
00766     double z = oldpos.z();
00767 
00768     double phix = atan2(oldrot.yz(), oldrot.zz());
00769     double phiy = asin(-oldrot.xz());
00770     double phiz = atan2(oldrot.xy(), oldrot.xx());
00771 
00772     align::EulerAngles oldEulerAngles = align::toAngles(oldrot);
00773     double alpha = oldEulerAngles(1);
00774     double beta = oldEulerAngles(2);
00775     double gamma = oldEulerAngles(3);
00776 
00777     // now get the new information; if it's incomplete, use the old position for those coordinates
00778     
00779     DOMAttr *node_x = node->getAttributeNode(str_x);
00780     DOMAttr *node_y = node->getAttributeNode(str_y);
00781     DOMAttr *node_z = node->getAttributeNode(str_z);
00782 
00783     if (node_x != NULL) x = parseDouble(node_x->getValue(), "x");
00784     if (node_y != NULL) y = parseDouble(node_y->getValue(), "y");
00785     if (node_z != NULL) z = parseDouble(node_z->getValue(), "z");
00786     align::PositionType pos(x, y, z);
00787 
00788     DOMAttr *node_phix = node->getAttributeNode(str_phix);
00789     DOMAttr *node_phiy = node->getAttributeNode(str_phiy);
00790     DOMAttr *node_phiz = node->getAttributeNode(str_phiz);
00791     DOMAttr *node_alpha = node->getAttributeNode(str_alpha);
00792     DOMAttr *node_beta  = node->getAttributeNode(str_beta);
00793     DOMAttr *node_gamma = node->getAttributeNode(str_gamma);
00794     align::RotationType rot;
00795 
00796     bool phixyz = (node_phix != NULL  ||  node_phiy != NULL  ||  node_phiz != NULL);
00797     bool alphabetagamma = (node_alpha != NULL  ||  node_beta != NULL  ||  node_gamma != NULL);
00798     if (phixyz && alphabetagamma) throw cms::Exception("XMLException") << "<setposition> must either have phix, phiy, and phiz or alpha, beta, and gamma, but not both" << std::endl;
00799     if (!phixyz && !alphabetagamma) alphabetagamma = true;
00800 
00801     if (phixyz) {
00802       if (node_phix != NULL) phix = parseDouble(node_phix->getValue(), "phix");
00803       if (node_phiy != NULL) phiy = parseDouble(node_phiy->getValue(), "phiy");
00804       if (node_phiz != NULL) phiz = parseDouble(node_phiz->getValue(), "phiz");
00805 
00806       // the angle convention originally used in alignment, also known as "non-standard Euler angles with a Z-Y-X convention"
00807       // this also gets the sign convention right
00808       align::RotationType rotX( 1.,         0.,         0.,
00809                                 0.,         cos(phix),  sin(phix),
00810                                 0.,        -sin(phix),  cos(phix));
00811       align::RotationType rotY( cos(phiy),  0.,        -sin(phiy), 
00812                                 0.,         1.,         0.,
00813                                 sin(phiy),  0.,         cos(phiy));
00814       align::RotationType rotZ( cos(phiz),  sin(phiz),  0.,
00815                                 -sin(phiz),  cos(phiz),  0.,
00816                                 0.,         0.,         1.);
00817             
00818       rot = rotX * rotY * rotZ;
00819     }
00820 
00821     else if (alphabetagamma) {
00822       if (node_alpha != NULL) alpha = parseDouble(node_alpha->getValue(), "alpha");
00823       if (node_beta != NULL) beta = parseDouble(node_beta->getValue(), "beta");
00824       if (node_gamma != NULL) gamma = parseDouble(node_gamma->getValue(), "gamma");
00825 
00826       // standard Euler angles (how they're internally stored in the database)
00827       align::EulerAngles eulerAngles(3);
00828       eulerAngles(1) = alpha;
00829       eulerAngles(2) = beta;
00830       eulerAngles(3) = gamma;
00831       rot = align::RotationType(align::toMatrix(eulerAngles));
00832     }
00833 
00834     else assert(false); // see above
00835 
00836     if (relativeto == 0) {
00837       set_one_position(aliiter->first, pos, rot);
00838     } // end relativeto="none"
00839 
00840     else if (relativeto == 1) {
00841       Alignable *ali = aliiter->first;
00842       Alignable *ideal = alitoideal[ali];
00843 
00844       align::PositionType idealPosition = ideal->globalPosition();
00845       align::RotationType idealRotation = ideal->globalRotation();
00846       align::PositionType newpos = align::PositionType(idealRotation.transposed() * pos.basicVector() + idealPosition.basicVector());
00847       align::RotationType newrot = rot * idealRotation;
00848 
00849       set_one_position(ali, newpos, newrot);
00850     } // end relativeto="ideal"
00851 
00852     else if (relativeto == 2) {
00853       Alignable *ali = aliiter->first;
00854       Alignable *container = ali->mother();
00855 
00856       if (container != NULL) {
00857         align::PositionType globalPosition = container->globalPosition();
00858         align::RotationType globalRotation = container->globalRotation();
00859         align::PositionType newpos = align::PositionType(globalRotation.transposed() * pos.basicVector() + globalPosition.basicVector());
00860         align::RotationType newrot = rot * globalRotation;
00861         set_one_position(ali, newpos, newrot);
00862       }
00863       else {
00864         set_one_position(ali, pos, rot);
00865       }
00866     } // end relativeto="container"
00867 
00868   } // end loop over alignables
00869 }
00870 
00871 void MuonAlignmentInputXML::set_one_position(Alignable *ali, const align::PositionType &pos, const align::RotationType &rot) const {
00872    const align::PositionType& oldpos = ali->globalPosition();
00873    const align::RotationType& oldrot = ali->globalRotation();
00874                                  
00875    // shift needed to move from current to new position
00876    align::GlobalVector posDiff = pos - oldpos;
00877    align::RotationType rotDiff = oldrot.multiplyInverse(rot);
00878    align::rectify(rotDiff); // correct for rounding errors 
00879    ali->move(posDiff);
00880    ali->rotateInGlobalFrame(rotDiff);
00881 
00882 //    // check for consistency
00883 //    const align::PositionType& newpos = ali->globalPosition();
00884 //    const align::RotationType& newrot = ali->globalRotation();
00885 //    align::GlobalVector posDiff2 = pos - newpos;
00886 //    align::RotationType rotDiff2 = newrot.multiplyInverse(rot);
00887 //    align::rectify(rotDiff2); // correct for rounding errors 
00888    
00889 //    if (fabs(posDiff2.x()) > 1e-6  ||  fabs(posDiff2.y()) > 1e-6  ||  fabs(posDiff2.z()) > 1e-6) {
00890 //       std::cout << "zeropos " << posDiff2 << std::endl;
00891 //    }
00892 //    if (fabs(rotDiff2.xx() - 1.) > 1e-4  ||
00893 //        fabs(rotDiff2.yy() - 1.) > 1e-4  ||
00894 //        fabs(rotDiff2.zz() - 1.) > 1e-4  ||
00895 //        fabs(rotDiff2.xy()) > 1e-8  ||
00896 //        fabs(rotDiff2.xz()) > 1e-8  ||
00897 //        fabs(rotDiff2.yz()) > 1e-8) {
00898 //       std::cout << "zerorot " << rotDiff2 << std::endl;
00899 //    }
00900 
00901    align::ErrorMatrix matrix6x6 = ROOT::Math::SMatrixIdentity();
00902    matrix6x6 *= 1000.;  // initial assumption: infinitely weak constraint
00903 
00904    const SurveyDet *survey = ali->survey();
00905    if (survey != NULL) {
00906       matrix6x6 = survey->errors();  // save the constraint information
00907    }
00908    ali->setSurvey(new SurveyDet(ali->surface(), matrix6x6));
00909 }
00910 
00911 void MuonAlignmentInputXML::do_setape(const XERCES_CPP_NAMESPACE::DOMElement *node, std::map<Alignable*, bool> &aliset, std::map<Alignable*, Alignable*> &alitoideal) const {
00912    DOMAttr *node_xx = node->getAttributeNode(str_xx);
00913    DOMAttr *node_xy = node->getAttributeNode(str_xy);
00914    DOMAttr *node_xz = node->getAttributeNode(str_xz);
00915    DOMAttr *node_yy = node->getAttributeNode(str_yy);
00916    DOMAttr *node_yz = node->getAttributeNode(str_yz);
00917    DOMAttr *node_zz = node->getAttributeNode(str_zz);
00918 
00919    if (node_xx == NULL) throw cms::Exception("XMLException") << "<setape> is missing required \"xx\" attribute" << std::endl;
00920    if (node_xy == NULL) throw cms::Exception("XMLException") << "<setape> is missing required \"xy\" attribute" << std::endl;
00921    if (node_xz == NULL) throw cms::Exception("XMLException") << "<setape> is missing required \"xz\" attribute" << std::endl;
00922    if (node_yy == NULL) throw cms::Exception("XMLException") << "<setape> is missing required \"yy\" attribute" << std::endl;
00923    if (node_yz == NULL) throw cms::Exception("XMLException") << "<setape> is missing required \"yz\" attribute" << std::endl;
00924    if (node_zz == NULL) throw cms::Exception("XMLException") << "<setape> is missing required \"zz\" attribute" << std::endl;
00925 
00926    AlgebraicSymMatrix33 matrix3x3;
00927    matrix3x3(0,0) = parseDouble(node_xx->getValue(), "xx");
00928    matrix3x3(0,1) = parseDouble(node_xy->getValue(), "xy");
00929    matrix3x3(0,2) = parseDouble(node_xz->getValue(), "xz");
00930    matrix3x3(1,1) = parseDouble(node_yy->getValue(), "yy");
00931    matrix3x3(1,2) = parseDouble(node_yz->getValue(), "yz");
00932    matrix3x3(2,2) = parseDouble(node_zz->getValue(), "zz");
00933 
00934    for (std::map<Alignable*, bool>::const_iterator aliiter = aliset.begin();  aliiter != aliset.end();  ++aliiter) {
00935      // this sets APEs at this level and (since 2nd argument is true) all lower levels
00936      aliiter->first->setAlignmentPositionError(AlignmentPositionError(matrix3x3), true);
00937    }
00938 }
00939 
00940 void MuonAlignmentInputXML::do_setsurveyerr(const XERCES_CPP_NAMESPACE::DOMElement *node, std::map<Alignable*, bool> &aliset, std::map<Alignable*, Alignable*> &alitoideal) const {
00941    DOMAttr *node_xx = node->getAttributeNode(str_xx);
00942    DOMAttr *node_xy = node->getAttributeNode(str_xy);
00943    DOMAttr *node_xz = node->getAttributeNode(str_xz);
00944    DOMAttr *node_xa = node->getAttributeNode(str_xa);
00945    DOMAttr *node_xb = node->getAttributeNode(str_xb);
00946    DOMAttr *node_xc = node->getAttributeNode(str_xc);
00947    DOMAttr *node_yy = node->getAttributeNode(str_yy);
00948    DOMAttr *node_yz = node->getAttributeNode(str_yz);
00949    DOMAttr *node_ya = node->getAttributeNode(str_ya);
00950    DOMAttr *node_yb = node->getAttributeNode(str_yb);
00951    DOMAttr *node_yc = node->getAttributeNode(str_yc);
00952    DOMAttr *node_zz = node->getAttributeNode(str_zz);
00953    DOMAttr *node_za = node->getAttributeNode(str_za);
00954    DOMAttr *node_zb = node->getAttributeNode(str_zb);
00955    DOMAttr *node_zc = node->getAttributeNode(str_zc);
00956    DOMAttr *node_aa = node->getAttributeNode(str_aa);
00957    DOMAttr *node_ab = node->getAttributeNode(str_ab);
00958    DOMAttr *node_ac = node->getAttributeNode(str_ac);
00959    DOMAttr *node_bb = node->getAttributeNode(str_bb);
00960    DOMAttr *node_bc = node->getAttributeNode(str_bc);
00961    DOMAttr *node_cc = node->getAttributeNode(str_cc);
00962 
00963    if (node_xx == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"xx\" attribute" << std::endl;
00964    if (node_xy == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"xy\" attribute" << std::endl;
00965    if (node_xz == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"xz\" attribute" << std::endl;
00966    if (node_xa == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"xa\" attribute" << std::endl;
00967    if (node_xb == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"xb\" attribute" << std::endl;
00968    if (node_xc == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"xc\" attribute" << std::endl;
00969    if (node_yy == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"yy\" attribute" << std::endl;
00970    if (node_yz == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"yz\" attribute" << std::endl;
00971    if (node_ya == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"ya\" attribute" << std::endl;
00972    if (node_yb == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"yb\" attribute" << std::endl;
00973    if (node_yc == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"yc\" attribute" << std::endl;
00974    if (node_zz == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"zz\" attribute" << std::endl;
00975    if (node_za == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"za\" attribute" << std::endl;
00976    if (node_zb == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"zb\" attribute" << std::endl;
00977    if (node_zc == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"zc\" attribute" << std::endl;
00978    if (node_aa == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"aa\" attribute" << std::endl;
00979    if (node_ab == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"ab\" attribute" << std::endl;
00980    if (node_ac == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"ac\" attribute" << std::endl;
00981    if (node_bb == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"bb\" attribute" << std::endl;
00982    if (node_bc == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"bc\" attribute" << std::endl;
00983    if (node_cc == NULL) throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"cc\" attribute" << std::endl;
00984 
00985    align::ErrorMatrix matrix6x6;
00986    matrix6x6(0,0) = parseDouble(node_xx->getValue(), "xx");
00987    matrix6x6(0,1) = parseDouble(node_xy->getValue(), "xy");
00988    matrix6x6(0,2) = parseDouble(node_xz->getValue(), "xz");
00989    matrix6x6(0,3) = parseDouble(node_xa->getValue(), "xa");
00990    matrix6x6(0,4) = parseDouble(node_xb->getValue(), "xb");
00991    matrix6x6(0,5) = parseDouble(node_xc->getValue(), "xc");
00992    matrix6x6(1,1) = parseDouble(node_yy->getValue(), "yy");
00993    matrix6x6(1,2) = parseDouble(node_yz->getValue(), "yz");
00994    matrix6x6(1,3) = parseDouble(node_ya->getValue(), "ya");
00995    matrix6x6(1,4) = parseDouble(node_yb->getValue(), "yb");
00996    matrix6x6(1,5) = parseDouble(node_yc->getValue(), "yc");
00997    matrix6x6(2,2) = parseDouble(node_zz->getValue(), "zz");
00998    matrix6x6(2,3) = parseDouble(node_za->getValue(), "za");
00999    matrix6x6(2,4) = parseDouble(node_zb->getValue(), "zb");
01000    matrix6x6(2,5) = parseDouble(node_zc->getValue(), "zc");
01001    matrix6x6(3,3) = parseDouble(node_aa->getValue(), "aa");
01002    matrix6x6(3,4) = parseDouble(node_ab->getValue(), "ab");
01003    matrix6x6(3,5) = parseDouble(node_ac->getValue(), "ac");
01004    matrix6x6(4,4) = parseDouble(node_bb->getValue(), "bb");
01005    matrix6x6(4,5) = parseDouble(node_bc->getValue(), "bc");
01006    matrix6x6(5,5) = parseDouble(node_cc->getValue(), "cc");
01007 
01008    for (std::map<Alignable*, bool>::const_iterator aliiter = aliset.begin();  aliiter != aliset.end();  ++aliiter) {
01009       Alignable *ali = aliiter->first;
01010       ali->setSurvey(new SurveyDet(ali->surface(), matrix6x6));
01011    }
01012 }
01013 
01014 void MuonAlignmentInputXML::do_moveglobal(const XERCES_CPP_NAMESPACE::DOMElement *node, std::map<Alignable*, bool> &aliset, std::map<Alignable*, Alignable*> &alitoideal) const {
01015    DOMAttr *node_x = node->getAttributeNode(str_x);
01016    DOMAttr *node_y = node->getAttributeNode(str_y);
01017    DOMAttr *node_z = node->getAttributeNode(str_z);
01018    if (node_x == NULL) throw cms::Exception("XMLException") << "<moveglobal> is missing required \"x\" attribute" << std::endl;
01019    if (node_y == NULL) throw cms::Exception("XMLException") << "<moveglobal> is missing required \"y\" attribute" << std::endl;
01020    if (node_z == NULL) throw cms::Exception("XMLException") << "<moveglobal> is missing required \"z\" attribute" << std::endl;
01021 
01022    double x = parseDouble(node_x->getValue(), "x");
01023    double y = parseDouble(node_y->getValue(), "y");
01024    double z = parseDouble(node_z->getValue(), "z");
01025    GlobalVector vect(x, y, z);
01026 
01027    for (std::map<Alignable*, bool>::const_iterator aliiter = aliset.begin();  aliiter != aliset.end();  ++aliiter) {
01028       Alignable *ali = aliiter->first;
01029 
01030       ali->move(vect);
01031 
01032       align::ErrorMatrix matrix6x6 = ROOT::Math::SMatrixIdentity();
01033       matrix6x6 *= 1000.;  // initial assumption: infinitely weak constraint
01034 
01035       const SurveyDet *survey = ali->survey();
01036       if (survey != NULL) {
01037          matrix6x6 = survey->errors();  // save the constraint information
01038       }
01039       ali->setSurvey(new SurveyDet(ali->surface(), matrix6x6));
01040    } // end loop over alignables
01041 }
01042 
01043 void MuonAlignmentInputXML::do_movelocal(const XERCES_CPP_NAMESPACE::DOMElement *node, std::map<Alignable*, bool> &aliset, std::map<Alignable*, Alignable*> &alitoideal) const {
01044    DOMAttr *node_x = node->getAttributeNode(str_x);
01045    DOMAttr *node_y = node->getAttributeNode(str_y);
01046    DOMAttr *node_z = node->getAttributeNode(str_z);
01047    if (node_x == NULL) throw cms::Exception("XMLException") << "<movelocal> is missing required \"x\" attribute" << std::endl;
01048    if (node_y == NULL) throw cms::Exception("XMLException") << "<movelocal> is missing required \"y\" attribute" << std::endl;
01049    if (node_z == NULL) throw cms::Exception("XMLException") << "<movelocal> is missing required \"z\" attribute" << std::endl;
01050 
01051    double x = parseDouble(node_x->getValue(), "x");
01052    double y = parseDouble(node_y->getValue(), "y");
01053    double z = parseDouble(node_z->getValue(), "z");
01054    LocalVector vect(x, y, z);
01055 
01056    for (std::map<Alignable*, bool>::const_iterator aliiter = aliset.begin();  aliiter != aliset.end();  ++aliiter) {
01057       Alignable *ali = aliiter->first;
01058 
01059       GlobalVector globalVector = ali->surface().toGlobal(vect);
01060       ali->move(globalVector);
01061 
01062       align::ErrorMatrix matrix6x6 = ROOT::Math::SMatrixIdentity();
01063       matrix6x6 *= 1000.;  // initial assumption: infinitely weak constraint
01064 
01065       const SurveyDet *survey = ali->survey();
01066       if (survey != NULL) {
01067          matrix6x6 = survey->errors();  // save the constraint information
01068       }
01069       ali->setSurvey(new SurveyDet(ali->surface(), matrix6x6));
01070    } // end loop over alignables
01071 }
01072 
01073 void MuonAlignmentInputXML::do_rotatelocal(const XERCES_CPP_NAMESPACE::DOMElement *node, std::map<Alignable*, bool> &aliset, std::map<Alignable*, Alignable*> &alitoideal) const {
01074    DOMAttr *node_axisx = node->getAttributeNode(str_axisx);
01075    DOMAttr *node_axisy = node->getAttributeNode(str_axisy);
01076    DOMAttr *node_axisz = node->getAttributeNode(str_axisz);
01077    DOMAttr *node_angle = node->getAttributeNode(str_angle);
01078    if (node_axisx == NULL) throw cms::Exception("XMLException") << "<rotatelocal> is missing required \"axisx\" attribute" << std::endl;
01079    if (node_axisy == NULL) throw cms::Exception("XMLException") << "<rotatelocal> is missing required \"axisy\" attribute" << std::endl;
01080    if (node_axisz == NULL) throw cms::Exception("XMLException") << "<rotatelocal> is missing required \"axisz\" attribute" << std::endl;
01081    if (node_angle == NULL) throw cms::Exception("XMLException") << "<rotatelocal> is missing required \"angle\" attribute" << std::endl;
01082 
01083    double x = parseDouble(node_axisx->getValue(), "x");
01084    double y = parseDouble(node_axisy->getValue(), "y");
01085    double z = parseDouble(node_axisz->getValue(), "z");
01086    double angle = parseDouble(node_angle->getValue(), "angle");
01087    LocalVector vect(x, y, z);
01088 
01089    for (std::map<Alignable*, bool>::const_iterator aliiter = aliset.begin();  aliiter != aliset.end();  ++aliiter) {
01090       Alignable *ali = aliiter->first;
01091 
01092       ali->rotateAroundLocalAxis(vect, angle);
01093 
01094       align::ErrorMatrix matrix6x6 = ROOT::Math::SMatrixIdentity();
01095       matrix6x6 *= 1000.;  // initial assumption: infinitely weak constraint
01096 
01097       const SurveyDet *survey = ali->survey();
01098       if (survey != NULL) {
01099          matrix6x6 = survey->errors();  // save the constraint information
01100       }
01101       ali->setSurvey(new SurveyDet(ali->surface(), matrix6x6));
01102    } // end loop over alignables
01103 }
01104 
01105 void MuonAlignmentInputXML::do_rotatebeamline(const XERCES_CPP_NAMESPACE::DOMElement *node, std::map<Alignable*, bool> &aliset, std::map<Alignable*, Alignable*> &alitoideal) const {
01106    DOMAttr *node_rphi = node->getAttributeNode(str_rphi);
01107    DOMAttr *node_phi = node->getAttributeNode(str_phi);
01108    if (node_rphi == NULL  &&  node_phi == NULL) throw cms::Exception("XMLException") << "<rotatebeamline> is missing required \"*phi\" attribute" << std::endl;
01109    if (node_rphi != NULL  &&  node_phi != NULL) throw cms::Exception("XMLException") << "<rotatebeamline> can't have both an \"rphi\" and a \"phi\" attribute" << std::endl;
01110 
01111    double value;
01112    if (node_rphi != NULL) {
01113       value = parseDouble(node_rphi->getValue(), "rphi");
01114    }  
01115    else {
01116       value = parseDouble(node_phi->getValue(), "phi");
01117    }  
01118 
01119    for (std::map<Alignable*, bool>::const_iterator aliiter = aliset.begin();  aliiter != aliset.end();  ++aliiter) {
01120       Alignable *ali = aliiter->first;
01121 
01122       GlobalPoint pos = ali->surface().toGlobal(LocalPoint(0,0,0));
01123 
01124       double radius = pos.perp();
01125       double phi0 = pos.phi();
01126       double deltaphi = value;
01127       if (node_rphi != NULL) deltaphi = value / radius;
01128 
01129       ali->rotateAroundGlobalZ(deltaphi);
01130       ali->move(GlobalVector(radius * (cos(phi0 + deltaphi) - cos(phi0)),
01131                              radius * (sin(phi0 + deltaphi) - sin(phi0)),
01132                              0.));
01133 
01134       align::ErrorMatrix matrix6x6 = ROOT::Math::SMatrixIdentity();
01135       matrix6x6 *= 1000.;  // initial assumption: infinitely weak constraint
01136 
01137       const SurveyDet *survey = ali->survey();
01138       if (survey != NULL) {
01139          matrix6x6 = survey->errors();  // save the constraint information
01140       }
01141       ali->setSurvey(new SurveyDet(ali->surface(), matrix6x6));
01142    } // end loop over alignables
01143 }
01144 
01145 void MuonAlignmentInputXML::do_rotateglobalaxis(const XERCES_CPP_NAMESPACE::DOMElement *node, std::map<Alignable*, bool> &aliset, std::map<Alignable*, Alignable*> &alitoideal) const {
01146    DOMAttr *node_x = node->getAttributeNode(str_x);
01147    DOMAttr *node_y = node->getAttributeNode(str_y);
01148    DOMAttr *node_z = node->getAttributeNode(str_z);
01149    DOMAttr *node_angle = node->getAttributeNode(str_angle);
01150    if (node_x == NULL) throw cms::Exception("XMLException") << "<rotateglobalaxis> is missing required \"x\" attribute" << std::endl;
01151    if (node_y == NULL) throw cms::Exception("XMLException") << "<rotateglobalaxis> is missing required \"y\" attribute" << std::endl;
01152    if (node_z == NULL) throw cms::Exception("XMLException") << "<rotateglobalaxis> is missing required \"z\" attribute" << std::endl;
01153    if (node_angle == NULL) throw cms::Exception("XMLException") << "<rotateglobalaxis> is missing required \"angle\" attribute" << std::endl;
01154 
01155    double x = parseDouble(node_x->getValue(), "x");
01156    double y = parseDouble(node_y->getValue(), "y");
01157    double z = parseDouble(node_z->getValue(), "z");
01158    double angle = parseDouble(node_angle->getValue(), "angle");
01159 
01160    for (std::map<Alignable*, bool>::const_iterator aliiter = aliset.begin();  aliiter != aliset.end();  ++aliiter) {
01161       Alignable *ali = aliiter->first;
01162       GlobalPoint pos = ali->surface().toGlobal(LocalPoint(0,0,0));
01163 
01164       ali->rotateAroundGlobalAxis(GlobalVector(x, y, z), angle);
01165 
01166       double aprime = x/sqrt(x*x + y*y + z*z);
01167       double bprime = y/sqrt(x*x + y*y + z*z);
01168       double cprime = z/sqrt(x*x + y*y + z*z);
01169       double q0 = cos(angle/2.);
01170       double q1 = sin(angle/2.) * aprime;
01171       double q2 = sin(angle/2.) * bprime;
01172       double q3 = sin(angle/2.) * cprime;
01173       
01174       double pos2x = (q0*q0 + q1*q1 - q2*q2 - q3*q3) * pos.x()  +  2.*(q1*q2 - q0*q3) * pos.y()  +  2.*(q1*q3 + q0*q2) * pos.z();
01175       double pos2y = 2.*(q2*q1 + q0*q3) * pos.x()  +  (q0*q0 - q1*q1 + q2*q2 - q3*q3) * pos.y()  +  2.*(q2*q3 - q0*q1) * pos.z();
01176       double pos2z = 2.*(q3*q1 - q0*q2) * pos.x()  +  2.*(q3*q2 + q0*q1) * pos.y()  +  (q0*q0 - q1*q1 - q2*q2 + q3*q3) * pos.z();
01177 
01178       double movex = pos2x - pos.x();
01179       double movey = pos2y - pos.y();
01180       double movez = pos2z - pos.z();
01181       ali->move(GlobalVector(movex, movey, movez));
01182 
01183       align::ErrorMatrix matrix6x6 = ROOT::Math::SMatrixIdentity();
01184       matrix6x6 *= 1000.;  // initial assumption: infinitely weak constraint
01185 
01186       const SurveyDet *survey = ali->survey();
01187       if (survey != NULL) {
01188          matrix6x6 = survey->errors();  // save the constraint information
01189       }
01190       ali->setSurvey(new SurveyDet(ali->surface(), matrix6x6));
01191    } // end loop over alignables
01192 }
01193 
01194 //
01195 // const member functions
01196 //
01197 
01198 //
01199 // static member functions
01200 //