Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:56:42

0001 // -*- C++ -*-
0002 //
0003 // Package:     MuonAlignment
0004 // Class  :     MuonAlignmentInputXML
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Original Author:  Jim Pivarski
0010 //         Created:  Mon Mar 10 16:37:40 CDT 2008
0011 //$Id: MuonAlignmentInputXML.cc,v 1.16 2011/03/22 09:49:50 innocent Exp $
0012 //
0013 
0014 // system include files
0015 #include "FWCore/Framework/interface/ESHandle.h"
0016 #include "Utilities/Xerces/interface/Xerces.h"
0017 
0018 // Xerces include files
0019 #include "xercesc/parsers/XercesDOMParser.hpp"
0020 #include "xercesc/dom/DOM.hpp"
0021 #include "xercesc/sax/HandlerBase.hpp"
0022 #include "xercesc/util/XMLString.hpp"
0023 #include "xercesc/util/PlatformUtils.hpp"
0024 #include "xercesc/util/XercesDefs.hpp"
0025 XERCES_CPP_NAMESPACE_USE
0026 
0027 // user include files
0028 #include "Alignment/MuonAlignment/interface/MuonAlignmentInputXML.h"
0029 #include "Alignment/CommonAlignment/interface/StructureType.h"
0030 #include "Alignment/CommonAlignment/interface/AlignableObjectId.h"
0031 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
0032 #include "DataFormats/MuonDetId/interface/GEMDetId.h"
0033 #include "DataFormats/MuonDetId/interface/DTLayerId.h"
0034 #include "Alignment/CommonAlignment/interface/SurveyDet.h"
0035 #include "DataFormats/GeometryCommonDetAlgo/interface/AlignmentPositionError.h"
0036 #include "Geometry/Records/interface/MuonGeometryRecord.h"
0037 
0038 //
0039 // constants, enums and typedefs
0040 //
0041 
0042 //
0043 // static data member definitions
0044 //
0045 
0046 //
0047 // constructors and destructor
0048 //
0049 MuonAlignmentInputXML::MuonAlignmentInputXML(const std::string &fileName,
0050                                              const DTGeometry *dtGeometry,
0051                                              const CSCGeometry *cscGeometry,
0052                                              const GEMGeometry *gemGeometry,
0053                                              const DTGeometry *dtGeometryIdeal,
0054                                              const CSCGeometry *cscGeometryIdeal,
0055                                              const GEMGeometry *gemGeometryIdeal)
0056     : m_fileName(fileName),
0057       dtGeometry_(dtGeometry),
0058       cscGeometry_(cscGeometry),
0059       gemGeometry_(gemGeometry),
0060       dtGeometryIdeal_(dtGeometryIdeal),
0061       cscGeometryIdeal_(cscGeometryIdeal),
0062       gemGeometryIdeal_(gemGeometryIdeal) {
0063   cms::concurrency::xercesInitialize();
0064   str_operation = XMLString::transcode("operation");
0065   str_collection = XMLString::transcode("collection");
0066   str_name = XMLString::transcode("name");
0067   str_DTBarrel = XMLString::transcode("DTBarrel");
0068   str_DTWheel = XMLString::transcode("DTWheel");
0069   str_DTStation = XMLString::transcode("DTStation");
0070   str_DTChamber = XMLString::transcode("DTChamber");
0071   str_DTSuperLayer = XMLString::transcode("DTSuperLayer");
0072   str_DTLayer = XMLString::transcode("DTLayer");
0073   str_CSCEndcap = XMLString::transcode("CSCEndcap");
0074   str_CSCStation = XMLString::transcode("CSCStation");
0075   str_CSCRing = XMLString::transcode("CSCRing");
0076   str_CSCChamber = XMLString::transcode("CSCChamber");
0077   str_CSCLayer = XMLString::transcode("CSCLayer");
0078   str_GEMEndcap = XMLString::transcode("GEMEndcap");
0079   str_GEMStation = XMLString::transcode("GEMStation");
0080   str_GEMRing = XMLString::transcode("GEMRing");
0081   str_GEMSuperChamber = XMLString::transcode("GEMSuperChamber");
0082   str_GEMChamber = XMLString::transcode("GEMChamber");
0083   str_GEMEtaPartition = XMLString::transcode("GEMEtaPartition");
0084   str_setposition = XMLString::transcode("setposition");
0085   str_setape = XMLString::transcode("setape");
0086   str_setsurveyerr = XMLString::transcode("setsurveyerr");
0087   str_moveglobal = XMLString::transcode("moveglobal");
0088   str_movelocal = XMLString::transcode("movelocal");
0089   str_rotatelocal = XMLString::transcode("rotatelocal");
0090   str_rotatebeamline = XMLString::transcode("rotatebeamline");
0091   str_rotateglobalaxis = XMLString::transcode("rotateglobalaxis");
0092   str_relativeto = XMLString::transcode("relativeto");
0093   str_rawId = XMLString::transcode("rawId");
0094   str_wheel = XMLString::transcode("wheel");
0095   str_station = XMLString::transcode("station");
0096   str_sector = XMLString::transcode("sector");
0097   str_superlayer = XMLString::transcode("superlayer");
0098   str_layer = XMLString::transcode("layer");
0099   str_endcap = XMLString::transcode("endcap");
0100   str_ring = XMLString::transcode("ring");
0101   str_chamber = XMLString::transcode("chamber");
0102   str_superChamber = XMLString::transcode("SuperChamber");
0103   str_etaPartition = XMLString::transcode("etaPartition");
0104   str_axisx = XMLString::transcode("axisx");
0105   str_axisy = XMLString::transcode("axisy");
0106   str_axisz = XMLString::transcode("axisz");
0107   str_angle = XMLString::transcode("angle");
0108   str_x = XMLString::transcode("x");
0109   str_y = XMLString::transcode("y");
0110   str_z = XMLString::transcode("z");
0111   str_phix = XMLString::transcode("phix");
0112   str_phiy = XMLString::transcode("phiy");
0113   str_phiz = XMLString::transcode("phiz");
0114   str_alpha = XMLString::transcode("alpha");
0115   str_beta = XMLString::transcode("beta");
0116   str_gamma = XMLString::transcode("gamma");
0117   str_rphi = XMLString::transcode("rphi");
0118   str_phi = XMLString::transcode("phi");
0119   str_xx = XMLString::transcode("xx");
0120   str_xy = XMLString::transcode("xy");
0121   str_xz = XMLString::transcode("xz");
0122   str_xa = XMLString::transcode("xa");
0123   str_xb = XMLString::transcode("xb");
0124   str_xc = XMLString::transcode("xc");
0125   str_yy = XMLString::transcode("yy");
0126   str_yz = XMLString::transcode("yz");
0127   str_ya = XMLString::transcode("ya");
0128   str_yb = XMLString::transcode("yb");
0129   str_yc = XMLString::transcode("yc");
0130   str_zz = XMLString::transcode("zz");
0131   str_za = XMLString::transcode("za");
0132   str_zb = XMLString::transcode("zb");
0133   str_zc = XMLString::transcode("zc");
0134   str_aa = XMLString::transcode("aa");
0135   str_ab = XMLString::transcode("ab");
0136   str_ac = XMLString::transcode("ac");
0137   str_bb = XMLString::transcode("bb");
0138   str_bc = XMLString::transcode("bc");
0139   str_cc = XMLString::transcode("cc");
0140   str_none = XMLString::transcode("none");
0141   str_ideal = XMLString::transcode("ideal");
0142   str_container = XMLString::transcode("container");
0143 }
0144 
0145 // MuonAlignmentInputXML::MuonAlignmentInputXML(const MuonAlignmentInputXML& rhs)
0146 // {
0147 //    // do actual copying here;
0148 // }
0149 
0150 MuonAlignmentInputXML::~MuonAlignmentInputXML() {
0151   XMLString::release(&str_operation);
0152   XMLString::release(&str_collection);
0153   XMLString::release(&str_name);
0154   XMLString::release(&str_DTBarrel);
0155   XMLString::release(&str_DTWheel);
0156   XMLString::release(&str_DTStation);
0157   XMLString::release(&str_DTChamber);
0158   XMLString::release(&str_DTSuperLayer);
0159   XMLString::release(&str_DTLayer);
0160   XMLString::release(&str_CSCEndcap);
0161   XMLString::release(&str_CSCStation);
0162   XMLString::release(&str_CSCRing);
0163   XMLString::release(&str_CSCChamber);
0164   XMLString::release(&str_CSCLayer);
0165   XMLString::release(&str_GEMEndcap);
0166   XMLString::release(&str_GEMStation);
0167   XMLString::release(&str_GEMRing);
0168   XMLString::release(&str_GEMSuperChamber);
0169   XMLString::release(&str_GEMChamber);
0170   XMLString::release(&str_GEMEtaPartition);
0171   XMLString::release(&str_setposition);
0172   XMLString::release(&str_setape);
0173   XMLString::release(&str_setsurveyerr);
0174   XMLString::release(&str_moveglobal);
0175   XMLString::release(&str_movelocal);
0176   XMLString::release(&str_rotatelocal);
0177   XMLString::release(&str_rotatebeamline);
0178   XMLString::release(&str_rotateglobalaxis);
0179   XMLString::release(&str_relativeto);
0180   XMLString::release(&str_rawId);
0181   XMLString::release(&str_wheel);
0182   XMLString::release(&str_station);
0183   XMLString::release(&str_sector);
0184   XMLString::release(&str_superlayer);
0185   XMLString::release(&str_layer);
0186   XMLString::release(&str_endcap);
0187   XMLString::release(&str_ring);
0188   XMLString::release(&str_chamber);
0189   XMLString::release(&str_superChamber);
0190   XMLString::release(&str_etaPartition);
0191   XMLString::release(&str_axisx);
0192   XMLString::release(&str_axisy);
0193   XMLString::release(&str_axisz);
0194   XMLString::release(&str_angle);
0195   XMLString::release(&str_x);
0196   XMLString::release(&str_y);
0197   XMLString::release(&str_z);
0198   XMLString::release(&str_phix);
0199   XMLString::release(&str_phiy);
0200   XMLString::release(&str_phiz);
0201   XMLString::release(&str_alpha);
0202   XMLString::release(&str_beta);
0203   XMLString::release(&str_gamma);
0204   XMLString::release(&str_rphi);
0205   XMLString::release(&str_phi);
0206   XMLString::release(&str_xx);
0207   XMLString::release(&str_xy);
0208   XMLString::release(&str_xz);
0209   XMLString::release(&str_xa);
0210   XMLString::release(&str_xb);
0211   XMLString::release(&str_xc);
0212   XMLString::release(&str_yy);
0213   XMLString::release(&str_yz);
0214   XMLString::release(&str_ya);
0215   XMLString::release(&str_yb);
0216   XMLString::release(&str_yc);
0217   XMLString::release(&str_zz);
0218   XMLString::release(&str_za);
0219   XMLString::release(&str_zb);
0220   XMLString::release(&str_zc);
0221   XMLString::release(&str_aa);
0222   XMLString::release(&str_ab);
0223   XMLString::release(&str_ac);
0224   XMLString::release(&str_bb);
0225   XMLString::release(&str_bc);
0226   XMLString::release(&str_cc);
0227   XMLString::release(&str_none);
0228   XMLString::release(&str_ideal);
0229   XMLString::release(&str_container);
0230   cms::concurrency::xercesTerminate();
0231 }
0232 
0233 //
0234 // assignment operators
0235 //
0236 // const MuonAlignmentInputXML& MuonAlignmentInputXML::operator=(const MuonAlignmentInputXML& rhs)
0237 // {
0238 //   //An exception safe implementation is
0239 //   MuonAlignmentInputXML temp(rhs);
0240 //   swap(rhs);
0241 //
0242 //   return *this;
0243 // }
0244 
0245 //
0246 // member functions
0247 //
0248 
0249 void MuonAlignmentInputXML::recursiveGetId(std::map<unsigned int, Alignable *> &alignableNavigator,
0250                                            const align::Alignables &alignables) const {
0251   for (align::Alignables::const_iterator ali = alignables.begin(); ali != alignables.end(); ++ali) {
0252     if ((*ali)->alignableObjectId() == align::AlignableDetUnit || (*ali)->alignableObjectId() == align::AlignableDet ||
0253         (*ali)->alignableObjectId() == align::AlignableDTChamber ||
0254         (*ali)->alignableObjectId() == align::AlignableDTSuperLayer ||
0255         (*ali)->alignableObjectId() == align::AlignableDTLayer ||
0256         (*ali)->alignableObjectId() == align::AlignableCSCChamber ||
0257         (*ali)->alignableObjectId() == align::AlignableCSCLayer ||
0258         (*ali)->alignableObjectId() == align::AlignableGEMSuperChamber ||
0259         (*ali)->alignableObjectId() == align::AlignableGEMChamber ||
0260         (*ali)->alignableObjectId() == align::AlignableGEMEtaPartition) {
0261       alignableNavigator[(*ali)->geomDetId().rawId()] = *ali;
0262     }
0263     recursiveGetId(alignableNavigator, (*ali)->components());
0264   }
0265 }
0266 
0267 void MuonAlignmentInputXML::fillAliToIdeal(std::map<Alignable *, Alignable *> &alitoideal,
0268                                            const align::Alignables &alignables,
0269                                            const align::Alignables &ideals) const {
0270   align::Alignables::const_iterator alignable = alignables.begin();
0271   align::Alignables::const_iterator ideal = ideals.begin();
0272 
0273   while (alignable != alignables.end() && ideal != ideals.end()) {
0274     alitoideal[*alignable] = *ideal;
0275 
0276     fillAliToIdeal(alitoideal, (*alignable)->components(), (*ideal)->components());
0277 
0278     ++alignable;
0279     ++ideal;
0280   }
0281 
0282   if (alignable != alignables.end() || ideal != ideals.end()) {
0283     throw cms::Exception("Alignment")
0284         << "alignable and ideal-alignable trees are out of sync (this should never happen)";
0285   }
0286 }
0287 
0288 AlignableMuon *MuonAlignmentInputXML::newAlignableMuon() const {
0289   AlignableMuon *alignableMuon = new AlignableMuon(dtGeometry_, cscGeometry_, gemGeometry_);
0290   std::map<unsigned int, Alignable *> alignableNavigator;  // real AlignableNavigators don't have const methods
0291   recursiveGetId(alignableNavigator, alignableMuon->DTBarrel());
0292   recursiveGetId(alignableNavigator, alignableMuon->CSCEndcaps());
0293   recursiveGetId(alignableNavigator, alignableMuon->GEMEndcaps());
0294 
0295   AlignableMuon *ideal_alignableMuon = new AlignableMuon(dtGeometryIdeal_, cscGeometryIdeal_, gemGeometryIdeal_);
0296   std::map<unsigned int, Alignable *> ideal_alignableNavigator;  // real AlignableNavigators don't have const methods
0297   recursiveGetId(ideal_alignableNavigator, ideal_alignableMuon->DTBarrel());
0298   recursiveGetId(ideal_alignableNavigator, ideal_alignableMuon->CSCEndcaps());
0299   recursiveGetId(ideal_alignableNavigator, ideal_alignableMuon->GEMEndcaps());
0300 
0301   try {
0302     cms::concurrency::xercesInitialize();
0303   } catch (const XMLException &toCatch) {
0304     throw cms::Exception("XMLException") << "Xerces XML parser threw an exception on initialization." << std::endl;
0305   }
0306 
0307   XercesDOMParser *parser = new XercesDOMParser();
0308   parser->setValidationScheme(XercesDOMParser::Val_Always);
0309 
0310   XERCES_CPP_NAMESPACE::ErrorHandler *errHandler = (XERCES_CPP_NAMESPACE::ErrorHandler *)(new HandlerBase());
0311   parser->setErrorHandler(errHandler);
0312 
0313   try {
0314     parser->parse(m_fileName.c_str());
0315   } catch (const XMLException &toCatch) {
0316     char *message = XMLString::transcode(toCatch.getMessage());
0317     throw cms::Exception("XMLException") << "Xerces XML parser threw this exception: " << message << std::endl;
0318   } catch (const DOMException &toCatch) {
0319     char *message = XMLString::transcode(toCatch.msg);
0320     throw cms::Exception("XMLException") << "Xerces XML parser threw this exception: " << message << std::endl;
0321   } catch (const SAXException &toCatch) {
0322     char *message = XMLString::transcode(toCatch.getMessage());
0323     throw cms::Exception("XMLException") << "Xerces XML parser threw this exception: " << message << std::endl;
0324   }
0325 
0326   DOMDocument *doc = parser->getDocument();
0327   DOMElement *node_MuonAlignment = doc->getDocumentElement();
0328   DOMNodeList *collections = doc->getElementsByTagName(str_collection);
0329   DOMNodeList *operations = doc->getElementsByTagName(str_operation);
0330 
0331   std::map<Alignable *, Alignable *> alitoideal;
0332   fillAliToIdeal(alitoideal, alignableMuon->DTBarrel(), ideal_alignableMuon->DTBarrel());
0333   fillAliToIdeal(alitoideal, alignableMuon->CSCEndcaps(), ideal_alignableMuon->CSCEndcaps());
0334   fillAliToIdeal(alitoideal, alignableMuon->GEMEndcaps(), ideal_alignableMuon->GEMEndcaps());
0335 
0336   const auto &alignableObjectId = alignableMuon->objectIdProvider();
0337   std::map<std::string, std::map<Alignable *, bool> > alicollections;
0338   for (unsigned int i = 0; i < collections->getLength(); i++) {
0339     DOMElement *collection = (DOMElement *)(collections->item(i));
0340     if (collection->getParentNode() == node_MuonAlignment) {
0341       DOMNodeList *children = collection->getChildNodes();
0342 
0343       DOMAttr *node_name = collection->getAttributeNode(str_name);
0344       if (node_name == nullptr) {
0345         throw cms::Exception("XMLException") << "<collection> requires a name attribute" << std::endl;
0346       }
0347       char *ascii_name = XMLString::transcode(node_name->getValue());
0348       std::string name(ascii_name);
0349       XMLString::release(&ascii_name);
0350 
0351       std::map<Alignable *, bool> aliset;
0352       for (unsigned int j = 0; j < children->getLength(); j++) {
0353         DOMNode *node = children->item(j);
0354 
0355         if (node->getNodeType() == DOMNode::ELEMENT_NODE) {
0356           Alignable *ali = getNode(alignableNavigator, (DOMElement *)(node), alignableObjectId);
0357           if (ali == nullptr) {
0358             throw cms::Exception("XMLException") << "<collection> must contain only alignables" << std::endl;
0359           }
0360 
0361           aliset[ali] = true;
0362         }  // end if this node is an element
0363       }    // end loop over collection's children
0364 
0365       alicollections[name] = aliset;
0366     }  // end if this is a top-level collection
0367   }    // end loop over collections
0368 
0369   for (unsigned int i = 0; i < operations->getLength(); i++) {
0370     DOMElement *operation = (DOMElement *)(operations->item(i));
0371     if (operation->getParentNode() != node_MuonAlignment) {
0372       throw cms::Exception("XMLException") << "All operations must be top-level elements" << std::endl;
0373     }
0374 
0375     DOMNodeList *children = operation->getChildNodes();
0376 
0377     std::map<Alignable *, bool> aliset;
0378     std::vector<DOMNode *> nodesToRemove;
0379     for (unsigned int j = 0; j < children->getLength(); j++) {
0380       DOMNode *node = children->item(j);
0381 
0382       if (node->getNodeType() == DOMNode::ELEMENT_NODE) {
0383         Alignable *ali = getNode(alignableNavigator, (DOMElement *)(node), alignableObjectId);
0384         if (ali != nullptr) {
0385           aliset[ali] = true;
0386           nodesToRemove.push_back(node);
0387         }  // end if this node is an alignable
0388 
0389         else if (XMLString::equals(node->getNodeName(), str_collection)) {
0390           DOMAttr *node_name = ((DOMElement *)(node))->getAttributeNode(str_name);
0391           if (node_name == nullptr) {
0392             throw cms::Exception("XMLException") << "<collection> requires a name attribute" << std::endl;
0393           }
0394           char *ascii_name = XMLString::transcode(node_name->getValue());
0395           std::string name(ascii_name);
0396           XMLString::release(&ascii_name);
0397 
0398           std::map<std::string, std::map<Alignable *, bool> >::const_iterator alicollections_iter =
0399               alicollections.find(name);
0400           if (alicollections_iter == alicollections.end()) {
0401             throw cms::Exception("XMLException")
0402                 << "<collection name=\"" << name << "\"> hasn't been defined" << std::endl;
0403           }
0404 
0405           for (std::map<Alignable *, bool>::const_iterator aliiter = alicollections_iter->second.begin();
0406                aliiter != alicollections_iter->second.end();
0407                ++aliiter) {
0408             aliset[aliiter->first] = true;
0409           }  // end loop over alignables in this collection
0410 
0411           nodesToRemove.push_back(node);
0412         }  // end if this node is a collection
0413 
0414         else {
0415         }  // anything else? assume it's a position/rotation directive
0416 
0417       }  // end if node is node is an element
0418     }    // end first loop over operation's children
0419 
0420     // from now on, we only want to see position/rotation directives
0421     for (std::vector<DOMNode *>::const_iterator node = nodesToRemove.begin(); node != nodesToRemove.end(); ++node) {
0422       operation->removeChild(*node);
0423     }
0424     children = operation->getChildNodes();
0425 
0426     for (unsigned int j = 0; j < children->getLength(); j++) {
0427       DOMNode *node = children->item(j);
0428       if (node->getNodeType() == DOMNode::ELEMENT_NODE) {
0429         if (XMLString::equals(node->getNodeName(), str_setposition)) {
0430           do_setposition((DOMElement *)(node), aliset, alitoideal);
0431         }
0432 
0433         else if (XMLString::equals(node->getNodeName(), str_setape)) {
0434           do_setape((DOMElement *)(node), aliset, alitoideal);
0435         }
0436 
0437         else if (XMLString::equals(node->getNodeName(), str_setsurveyerr)) {
0438           do_setsurveyerr((DOMElement *)(node), aliset, alitoideal);
0439         }
0440 
0441         else if (XMLString::equals(node->getNodeName(), str_moveglobal)) {
0442           do_moveglobal((DOMElement *)(node), aliset, alitoideal);
0443         }
0444 
0445         else if (XMLString::equals(node->getNodeName(), str_movelocal)) {
0446           do_movelocal((DOMElement *)(node), aliset, alitoideal);
0447         }
0448 
0449         else if (XMLString::equals(node->getNodeName(), str_rotatelocal)) {
0450           do_rotatelocal((DOMElement *)(node), aliset, alitoideal);
0451         }
0452 
0453         else if (XMLString::equals(node->getNodeName(), str_rotatebeamline)) {
0454           do_rotatebeamline((DOMElement *)(node), aliset, alitoideal);
0455         }
0456 
0457         else if (XMLString::equals(node->getNodeName(), str_rotateglobalaxis)) {
0458           do_rotateglobalaxis((DOMElement *)(node), aliset, alitoideal);
0459         }
0460 
0461         else {
0462           char *message = XMLString::transcode(node->getNodeName());
0463           throw cms::Exception("XMLException") << "Unrecognized operation: \"" << message << "\"" << std::endl;
0464         }
0465 
0466       }  // end if node is an element
0467     }    // end second loop over operation's children
0468   }      // end loop over operations
0469 
0470   delete parser;
0471   delete errHandler;
0472 
0473   cms::concurrency::xercesTerminate();
0474 
0475   delete ideal_alignableMuon;
0476   return alignableMuon;
0477 }
0478 
0479 Alignable *MuonAlignmentInputXML::getNode(std::map<unsigned int, Alignable *> &alignableNavigator,
0480                                           const XERCES_CPP_NAMESPACE::DOMElement *node,
0481                                           const AlignableObjectId &alignableObjectId) const {
0482   if (XMLString::equals(node->getNodeName(), str_DTBarrel))
0483     return getDTnode(align::AlignableDTBarrel, alignableNavigator, node, alignableObjectId);
0484   else if (XMLString::equals(node->getNodeName(), str_DTWheel))
0485     return getDTnode(align::AlignableDTWheel, alignableNavigator, node, alignableObjectId);
0486   else if (XMLString::equals(node->getNodeName(), str_DTStation))
0487     return getDTnode(align::AlignableDTStation, alignableNavigator, node, alignableObjectId);
0488   else if (XMLString::equals(node->getNodeName(), str_DTChamber))
0489     return getDTnode(align::AlignableDTChamber, alignableNavigator, node, alignableObjectId);
0490   else if (XMLString::equals(node->getNodeName(), str_DTSuperLayer))
0491     return getDTnode(align::AlignableDTSuperLayer, alignableNavigator, node, alignableObjectId);
0492   else if (XMLString::equals(node->getNodeName(), str_DTLayer))
0493     return getDTnode(align::AlignableDetUnit, alignableNavigator, node, alignableObjectId);
0494   else if (XMLString::equals(node->getNodeName(), str_CSCEndcap))
0495     return getCSCnode(align::AlignableCSCEndcap, alignableNavigator, node, alignableObjectId);
0496   else if (XMLString::equals(node->getNodeName(), str_CSCStation))
0497     return getCSCnode(align::AlignableCSCStation, alignableNavigator, node, alignableObjectId);
0498   else if (XMLString::equals(node->getNodeName(), str_CSCRing))
0499     return getCSCnode(align::AlignableCSCRing, alignableNavigator, node, alignableObjectId);
0500   else if (XMLString::equals(node->getNodeName(), str_CSCChamber))
0501     return getCSCnode(align::AlignableCSCChamber, alignableNavigator, node, alignableObjectId);
0502   else if (XMLString::equals(node->getNodeName(), str_CSCLayer))
0503     return getCSCnode(align::AlignableDetUnit, alignableNavigator, node, alignableObjectId);
0504   else if (XMLString::equals(node->getNodeName(), str_GEMEndcap))
0505     return getGEMnode(align::AlignableGEMEndcap, alignableNavigator, node, alignableObjectId);
0506   else if (XMLString::equals(node->getNodeName(), str_GEMStation))
0507     return getGEMnode(align::AlignableGEMStation, alignableNavigator, node, alignableObjectId);
0508   else if (XMLString::equals(node->getNodeName(), str_GEMRing))
0509     return getGEMnode(align::AlignableGEMRing, alignableNavigator, node, alignableObjectId);
0510   else if (XMLString::equals(node->getNodeName(), str_GEMSuperChamber))
0511     return getGEMnode(align::AlignableGEMSuperChamber, alignableNavigator, node, alignableObjectId);
0512   else if (XMLString::equals(node->getNodeName(), str_GEMChamber))
0513     return getGEMnode(align::AlignableGEMChamber, alignableNavigator, node, alignableObjectId);
0514   else if (XMLString::equals(node->getNodeName(), str_GEMEtaPartition))
0515     return getGEMnode(align::AlignableDetUnit, alignableNavigator, node, alignableObjectId);
0516   else
0517     return nullptr;
0518 }
0519 
0520 Alignable *MuonAlignmentInputXML::getDTnode(align::StructureType structureType,
0521                                             std::map<unsigned int, Alignable *> &alignableNavigator,
0522                                             const XERCES_CPP_NAMESPACE::DOMElement *node,
0523                                             const AlignableObjectId &alignableObjectId) const {
0524   unsigned int rawId = 0;
0525 
0526   DOMAttr *node_rawId = node->getAttributeNode(str_rawId);
0527   if (node_rawId != nullptr) {
0528     try {
0529       rawId = XMLString::parseInt(node_rawId->getValue());
0530     } catch (const XMLException &toCatch) {
0531       throw cms::Exception("XMLException") << "Value of \"rawId\" must be an integer" << std::endl;
0532     }
0533   } else {
0534     int wheel, station, sector, superlayer, layer;
0535     wheel = station = sector = superlayer = layer = 1;
0536 
0537     if (structureType != align::AlignableDTBarrel) {
0538       DOMAttr *node_wheel = node->getAttributeNode(str_wheel);
0539       if (node_wheel == nullptr)
0540         throw cms::Exception("XMLException") << "DT node is missing required \"wheel\" attribute" << std::endl;
0541       try {
0542         wheel = XMLString::parseInt(node_wheel->getValue());
0543       } catch (const XMLException &toCatch) {
0544         throw cms::Exception("XMLException") << "Value of \"wheel\" must be an integer" << std::endl;
0545       }
0546 
0547       if (structureType != align::AlignableDTWheel) {
0548         DOMAttr *node_station = node->getAttributeNode(str_station);
0549         if (node_station == nullptr)
0550           throw cms::Exception("XMLException") << "DT node is missing required \"station\" attribute" << std::endl;
0551         try {
0552           station = XMLString::parseInt(node_station->getValue());
0553         } catch (const XMLException &toCatch) {
0554           throw cms::Exception("XMLException") << "Value of \"station\" must be an integer" << std::endl;
0555         }
0556 
0557         if (structureType != align::AlignableDTStation) {
0558           DOMAttr *node_sector = node->getAttributeNode(str_sector);
0559           if (node_sector == nullptr)
0560             throw cms::Exception("XMLException") << "DT node is missing required \"sector\" attribute" << std::endl;
0561           try {
0562             sector = XMLString::parseInt(node_sector->getValue());
0563           } catch (const XMLException &toCatch) {
0564             throw cms::Exception("XMLException") << "Value of \"sector\" must be an integer" << std::endl;
0565           }
0566 
0567           if (structureType != align::AlignableDTChamber) {
0568             DOMAttr *node_superlayer = node->getAttributeNode(str_superlayer);
0569             if (node_superlayer == nullptr)
0570               throw cms::Exception("XMLException")
0571                   << "DT node is missing required \"superlayer\" attribute" << std::endl;
0572             try {
0573               superlayer = XMLString::parseInt(node_superlayer->getValue());
0574             } catch (const XMLException &toCatch) {
0575               throw cms::Exception("XMLException") << "Value of \"superlayer\" must be an integer" << std::endl;
0576             }
0577 
0578             if (structureType != align::AlignableDTSuperLayer) {
0579               DOMAttr *node_layer = node->getAttributeNode(str_layer);
0580               if (node_layer == nullptr)
0581                 throw cms::Exception("XMLException") << "DT node is missing required \"layer\" attribute" << std::endl;
0582               try {
0583                 layer = XMLString::parseInt(node_layer->getValue());
0584               } catch (const XMLException &toCatch) {
0585                 throw cms::Exception("XMLException") << "Value of \"layer\" must be an integer" << std::endl;
0586               }
0587 
0588             }  // end if we need a layer number
0589           }    // end if we need a superlayer number
0590         }      // end if we need a sector number
0591       }        // end if we need a station number
0592     }          // end if we need a wheel number
0593 
0594     DTLayerId layerId(wheel, station, sector, superlayer, layer);
0595     rawId = layerId.rawId();
0596   }  // end if it's specified by wheel, station, sector, superlayer, layer
0597 
0598   Alignable *ali = alignableNavigator[rawId];
0599   if (ali == nullptr)
0600     throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not recognized" << std::endl;
0601 
0602   while (ali->alignableObjectId() != structureType) {
0603     ali = ali->mother();
0604 
0605     if (ali == nullptr) {
0606       throw cms::Exception("XMLException")
0607           << "rawId \"" << rawId << "\" is not a " << alignableObjectId.idToString(structureType) << std::endl;
0608     }
0609   }
0610   return ali;
0611 }
0612 
0613 Alignable *MuonAlignmentInputXML::getCSCnode(align::StructureType structureType,
0614                                              std::map<unsigned int, Alignable *> &alignableNavigator,
0615                                              const XERCES_CPP_NAMESPACE::DOMElement *node,
0616                                              const AlignableObjectId &alignableObjectId) const {
0617   unsigned int rawId;
0618 
0619   DOMAttr *node_rawId = node->getAttributeNode(str_rawId);
0620   if (node_rawId != nullptr) {
0621     try {
0622       rawId = XMLString::parseInt(node_rawId->getValue());
0623     } catch (const XMLException &toCatch) {
0624       throw cms::Exception("XMLException") << "Value of \"rawId\" must be an integer" << std::endl;
0625     }
0626   } else {
0627     int endcap, station, ring, chamber, layer;
0628     endcap = station = ring = chamber = layer = 1;
0629 
0630     DOMAttr *node_endcap = node->getAttributeNode(str_endcap);
0631     if (node_endcap == nullptr)
0632       throw cms::Exception("XMLException") << "CSC node is missing required \"endcap\" attribute" << std::endl;
0633     try {
0634       endcap = XMLString::parseInt(node_endcap->getValue());
0635     } catch (const XMLException &toCatch) {
0636       throw cms::Exception("XMLException") << "Value of \"endcap\" must be an integer" << std::endl;
0637     }
0638     if (endcap == -1)
0639       endcap = 2;
0640 
0641     if (structureType != align::AlignableCSCEndcap) {
0642       DOMAttr *node_station = node->getAttributeNode(str_station);
0643       if (node_station == nullptr)
0644         throw cms::Exception("XMLException") << "CSC node is missing required \"station\" attribute" << std::endl;
0645       try {
0646         station = XMLString::parseInt(node_station->getValue());
0647       } catch (const XMLException &toCatch) {
0648         throw cms::Exception("XMLException") << "Value of \"station\" must be an integer" << std::endl;
0649       }
0650 
0651       if (structureType != align::AlignableCSCStation) {
0652         DOMAttr *node_ring = node->getAttributeNode(str_ring);
0653         if (node_ring == nullptr)
0654           throw cms::Exception("XMLException") << "CSC node is missing required \"ring\" attribute" << std::endl;
0655         try {
0656           ring = XMLString::parseInt(node_ring->getValue());
0657         } catch (const XMLException &toCatch) {
0658           throw cms::Exception("XMLException") << "Value of \"ring\" must be an integer" << std::endl;
0659         }
0660 
0661         if (structureType != align::AlignableCSCRing) {
0662           DOMAttr *node_chamber = node->getAttributeNode(str_chamber);
0663           if (node_chamber == nullptr)
0664             throw cms::Exception("XMLException") << "CSC node is missing required \"chamber\" attribute" << std::endl;
0665           try {
0666             chamber = XMLString::parseInt(node_chamber->getValue());
0667           } catch (const XMLException &toCatch) {
0668             throw cms::Exception("XMLException") << "Value of \"chamber\" must be an integer" << std::endl;
0669           }
0670 
0671           if (structureType != align::AlignableCSCChamber) {
0672             DOMAttr *node_layer = node->getAttributeNode(str_layer);
0673             if (node_layer == nullptr)
0674               throw cms::Exception("XMLException") << "CSC node is missing required \"layer\" attribute" << std::endl;
0675             try {
0676               layer = XMLString::parseInt(node_layer->getValue());
0677             } catch (const XMLException &toCatch) {
0678               throw cms::Exception("XMLException") << "Value of \"layer\" must be an integer" << std::endl;
0679             }
0680 
0681           }  // end if we need a layer number
0682         }    // end if we need a chamber number
0683       }      // end if we need a ring number
0684     }        // end if we need a station number
0685 
0686     CSCDetId layerId(endcap, station, ring, chamber, layer);
0687     rawId = layerId.rawId();
0688   }  // end if it's specified by endcap, station, ring, chamber, layer
0689 
0690   Alignable *ali = alignableNavigator[rawId];
0691   if (ali == nullptr)
0692     throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not recognized" << std::endl;
0693 
0694   while (ali->alignableObjectId() != structureType) {
0695     ali = ali->mother();
0696 
0697     if (ali == nullptr) {
0698       throw cms::Exception("XMLException")
0699           << "rawId \"" << rawId << "\" is not a " << alignableObjectId.idToString(structureType) << std::endl;
0700     }
0701   }
0702   return ali;
0703 }
0704 
0705 Alignable *MuonAlignmentInputXML::getGEMnode(align::StructureType structureType,
0706                                              std::map<unsigned int, Alignable *> &alignableNavigator,
0707                                              const XERCES_CPP_NAMESPACE::DOMElement *node,
0708                                              const AlignableObjectId &alignableObjectId) const {
0709   unsigned int rawId;
0710 
0711   DOMAttr *node_rawId = node->getAttributeNode(str_rawId);
0712   if (node_rawId != nullptr) {
0713     try {
0714       rawId = XMLString::parseInt(node_rawId->getValue());
0715     } catch (const XMLException &toCatch) {
0716       throw cms::Exception("XMLException") << "Value of \"rawId\" must be an integer" << std::endl;
0717     }
0718   } else {
0719     int endcap, station, ring, superChamber, chamber;
0720     endcap = station = ring = superChamber = chamber = 1;
0721 
0722     DOMAttr *node_endcap = node->getAttributeNode(str_endcap);
0723     if (node_endcap == nullptr)
0724       throw cms::Exception("XMLException") << "GEM node is missing required \"endcap\" attribute" << std::endl;
0725     try {
0726       endcap = XMLString::parseInt(node_endcap->getValue());
0727     } catch (const XMLException &toCatch) {
0728       throw cms::Exception("XMLException") << "Value of \"endcap\" must be an integer" << std::endl;
0729     }
0730 
0731     if (structureType != align::AlignableGEMEndcap) {
0732       DOMAttr *node_station = node->getAttributeNode(str_station);
0733       if (node_station == nullptr)
0734         throw cms::Exception("XMLException") << "GEM node is missing required \"station\" attribute" << std::endl;
0735       try {
0736         station = XMLString::parseInt(node_station->getValue());
0737       } catch (const XMLException &toCatch) {
0738         throw cms::Exception("XMLException") << "Value of \"station\" must be an integer" << std::endl;
0739       }
0740 
0741       if (structureType != align::AlignableGEMStation) {
0742         DOMAttr *node_ring = node->getAttributeNode(str_ring);
0743         if (node_ring == nullptr)
0744           throw cms::Exception("XMLException") << "GEM node is missing required \"ring\" attribute" << std::endl;
0745         try {
0746           ring = XMLString::parseInt(node_ring->getValue());
0747         } catch (const XMLException &toCatch) {
0748           throw cms::Exception("XMLException") << "Value of \"ring\" must be an integer" << std::endl;
0749         }
0750 
0751         if (structureType != align::AlignableGEMRing) {
0752           DOMAttr *node_superChamber = node->getAttributeNode(str_chamber);
0753           if (node_superChamber == nullptr)
0754             throw cms::Exception("XMLException")
0755                 << "GEM node is missing required \"superChamber\" attribute" << std::endl;
0756           try {
0757             superChamber = XMLString::parseInt(node_superChamber->getValue());
0758           } catch (const XMLException &toCatch) {
0759             throw cms::Exception("XMLException") << "Value of \"superChamber\" must be an integer" << std::endl;
0760           }
0761         }  // end if we need a chamber number
0762       }    // end if we need a ring number
0763     }      // end if we need a station number
0764 
0765     GEMDetId chamberId(endcap, ring, station, 0, superChamber, 0);
0766     rawId = chamberId.rawId();
0767   }  // end if it's specified by endcap, station, ring, chamber, layer
0768   Alignable *ali = alignableNavigator[rawId];
0769   if (ali == nullptr)
0770     throw cms::Exception("XMLException") << "rawId \"" << rawId << "\" is not recognized" << std::endl;
0771 
0772   while (ali->alignableObjectId() != structureType) {
0773     ali = ali->mother();
0774 
0775     if (ali == nullptr) {
0776       throw cms::Exception("XMLException")
0777           << "rawId \"" << rawId << "\" is not a " << alignableObjectId.idToString(structureType) << std::endl;
0778     }
0779   }
0780   return ali;
0781 }
0782 
0783 double MuonAlignmentInputXML::parseDouble(const XMLCh *str, const char *attribute) const {
0784   unsigned int len = XMLString::stringLen(str);
0785   char *cstr = XMLString::transcode(str);
0786   std::stringstream errmessage;
0787   errmessage << "Value of \"" << attribute << "\" must be a double, not \"" << cstr << "\"" << std::endl;
0788 
0789   unsigned int i = 0;
0790 
0791   bool minus = false;
0792   if (cstr[i] == '-') {
0793     minus = true;
0794     i++;
0795   } else if (cstr[i] == '+')
0796     i++;
0797 
0798   double output = 0.;
0799 
0800   while (cstr[i] != '.' && cstr[i] != 'e' && cstr[i] != 'E' && i < len) {
0801     if (cstr[i] < '0' || cstr[i] > '9') {
0802       XMLString::release(&cstr);
0803       throw cms::Exception("XMLException") << errmessage.str();
0804     }
0805 
0806     output *= 10;
0807     output += cstr[i] - '0';
0808     i++;
0809   }
0810 
0811   if (cstr[i] == '.') {
0812     double place = 0.1;
0813     i++;
0814 
0815     while (cstr[i] != 'e' && cstr[i] != 'E' && i < len) {
0816       if (cstr[i] < '0' || cstr[i] > '9') {
0817         XMLString::release(&cstr);
0818         throw cms::Exception("XMLException") << errmessage.str();
0819       }
0820 
0821       output += (cstr[i] - '0') * place;
0822       place /= 10.;
0823       i++;
0824     }
0825   }
0826 
0827   if (cstr[i] == 'e' || cstr[i] == 'E') {
0828     i++;
0829 
0830     int exponent = 0;
0831     bool expminus = false;
0832     if (cstr[i] == '-') {
0833       expminus = true;
0834       i++;
0835     } else if (cstr[i] == '+')
0836       i++;
0837 
0838     while (i < len) {
0839       if (cstr[i] < '0' || cstr[i] > '9') {
0840         XMLString::release(&cstr);
0841         throw cms::Exception("XMLException") << errmessage.str();
0842       }
0843 
0844       exponent *= 10;
0845       exponent += cstr[i] - '0';
0846       i++;
0847     }
0848 
0849     if (expminus)
0850       exponent *= -1;
0851 
0852     output *= pow(10., exponent);
0853   }
0854 
0855   if (minus)
0856     output *= -1.;
0857 
0858   XMLString::release(&cstr);
0859   return output;
0860 }
0861 
0862 void MuonAlignmentInputXML::do_setposition(const XERCES_CPP_NAMESPACE::DOMElement *node,
0863                                            std::map<Alignable *, bool> &aliset,
0864                                            std::map<Alignable *, Alignable *> &alitoideal) const {
0865   DOMAttr *node_relativeto = node->getAttributeNode(str_relativeto);
0866   if (node_relativeto == nullptr)
0867     throw cms::Exception("XMLException") << "<setposition> is missing required \"relativeto\" attribute" << std::endl;
0868 
0869   int relativeto = 0;
0870   if (XMLString::equals(node_relativeto->getValue(), str_none)) {
0871     relativeto = 0;
0872   } else if (XMLString::equals(node_relativeto->getValue(), str_ideal)) {
0873     relativeto = 1;
0874   } else if (XMLString::equals(node_relativeto->getValue(), str_container)) {
0875     relativeto = 2;
0876   } else {
0877     char *message = XMLString::transcode(node_relativeto->getValue());
0878     throw cms::Exception("XMLException") << "relativeto must be \"none\", \"ideal\", or \"container\", not \""
0879                                          << message << "\"" << std::endl;
0880   }
0881 
0882   for (std::map<Alignable *, bool>::const_iterator aliiter = aliset.begin(); aliiter != aliset.end(); ++aliiter) {
0883     // first reconstruct the old position: how it would look in this coordinate system
0884 
0885     Alignable *ali = aliiter->first;
0886     Alignable *ideal = alitoideal[ali];
0887 
0888     align::PositionType oldpos = ali->globalPosition();
0889     align::RotationType oldrot = ali->globalRotation();
0890 
0891     if (relativeto == 0) {
0892     }
0893 
0894     else if (relativeto == 1) {
0895       const align::PositionType &idealPosition = ideal->globalPosition();
0896       align::RotationType idealRotation = ideal->globalRotation();
0897 
0898       oldpos = align::PositionType(idealRotation * (oldpos.basicVector() - idealPosition.basicVector()));
0899       oldrot = oldrot * idealRotation.transposed();
0900     }
0901 
0902     else if (relativeto == 2 && ali->mother() != nullptr) {
0903       align::PositionType globalPosition = ali->mother()->globalPosition();
0904       align::RotationType globalRotation = ali->mother()->globalRotation();
0905 
0906       oldpos = align::PositionType(globalRotation * (oldpos.basicVector() - globalPosition.basicVector()));
0907       oldrot = oldrot * globalRotation.transposed();
0908     }
0909 
0910     double x = oldpos.x();
0911     double y = oldpos.y();
0912     double z = oldpos.z();
0913 
0914     double phix = atan2(oldrot.yz(), oldrot.zz());
0915     double phiy = asin(-oldrot.xz());
0916     double phiz = atan2(oldrot.xy(), oldrot.xx());
0917 
0918     align::EulerAngles oldEulerAngles = align::toAngles(oldrot);
0919     double alpha = oldEulerAngles(1);
0920     double beta = oldEulerAngles(2);
0921     double gamma = oldEulerAngles(3);
0922 
0923     // now get the new information; if it's incomplete, use the old position for those coordinates
0924 
0925     DOMAttr *node_x = node->getAttributeNode(str_x);
0926     DOMAttr *node_y = node->getAttributeNode(str_y);
0927     DOMAttr *node_z = node->getAttributeNode(str_z);
0928 
0929     if (node_x != nullptr)
0930       x = parseDouble(node_x->getValue(), "x");
0931     if (node_y != nullptr)
0932       y = parseDouble(node_y->getValue(), "y");
0933     if (node_z != nullptr)
0934       z = parseDouble(node_z->getValue(), "z");
0935     align::PositionType pos(x, y, z);
0936 
0937     DOMAttr *node_phix = node->getAttributeNode(str_phix);
0938     DOMAttr *node_phiy = node->getAttributeNode(str_phiy);
0939     DOMAttr *node_phiz = node->getAttributeNode(str_phiz);
0940     DOMAttr *node_alpha = node->getAttributeNode(str_alpha);
0941     DOMAttr *node_beta = node->getAttributeNode(str_beta);
0942     DOMAttr *node_gamma = node->getAttributeNode(str_gamma);
0943     align::RotationType rot;
0944 
0945     bool phixyz = (node_phix != nullptr || node_phiy != nullptr || node_phiz != nullptr);
0946     bool alphabetagamma = (node_alpha != nullptr || node_beta != nullptr || node_gamma != nullptr);
0947     if (phixyz && alphabetagamma)
0948       throw cms::Exception("XMLException")
0949           << "<setposition> must either have phix, phiy, and phiz or alpha, beta, and gamma, but not both" << std::endl;
0950     if (!phixyz && !alphabetagamma)
0951       alphabetagamma = true;
0952 
0953     if (phixyz) {
0954       if (node_phix != nullptr)
0955         phix = parseDouble(node_phix->getValue(), "phix");
0956       if (node_phiy != nullptr)
0957         phiy = parseDouble(node_phiy->getValue(), "phiy");
0958       if (node_phiz != nullptr)
0959         phiz = parseDouble(node_phiz->getValue(), "phiz");
0960 
0961       // the angle convention originally used in alignment, also known as "non-standard Euler angles with a Z-Y-X convention"
0962       // this also gets the sign convention right
0963       align::RotationType rotX(1., 0., 0., 0., cos(phix), sin(phix), 0., -sin(phix), cos(phix));
0964       align::RotationType rotY(cos(phiy), 0., -sin(phiy), 0., 1., 0., sin(phiy), 0., cos(phiy));
0965       align::RotationType rotZ(cos(phiz), sin(phiz), 0., -sin(phiz), cos(phiz), 0., 0., 0., 1.);
0966 
0967       rot = rotX * rotY * rotZ;
0968     }
0969 
0970     else if (alphabetagamma) {
0971       if (node_alpha != nullptr)
0972         alpha = parseDouble(node_alpha->getValue(), "alpha");
0973       if (node_beta != nullptr)
0974         beta = parseDouble(node_beta->getValue(), "beta");
0975       if (node_gamma != nullptr)
0976         gamma = parseDouble(node_gamma->getValue(), "gamma");
0977 
0978       // standard Euler angles (how they're internally stored in the database)
0979       align::EulerAngles eulerAngles(3);
0980       eulerAngles(1) = alpha;
0981       eulerAngles(2) = beta;
0982       eulerAngles(3) = gamma;
0983       rot = align::RotationType(align::toMatrix(eulerAngles));
0984     }
0985 
0986     else
0987       assert(false);  // see above
0988 
0989     if (relativeto == 0) {
0990       set_one_position(aliiter->first, pos, rot);
0991     }  // end relativeto="none"
0992 
0993     else if (relativeto == 1) {
0994       Alignable *ali = aliiter->first;
0995       Alignable *ideal = alitoideal[ali];
0996 
0997       const align::PositionType &idealPosition = ideal->globalPosition();
0998       align::RotationType idealRotation = ideal->globalRotation();
0999       align::PositionType newpos =
1000           align::PositionType(idealRotation.transposed() * pos.basicVector() + idealPosition.basicVector());
1001       align::RotationType newrot = rot * idealRotation;
1002 
1003       set_one_position(ali, newpos, newrot);
1004     }  // end relativeto="ideal"
1005 
1006     else if (relativeto == 2) {
1007       Alignable *ali = aliiter->first;
1008       Alignable *container = ali->mother();
1009 
1010       if (container != nullptr) {
1011         const align::PositionType &globalPosition = container->globalPosition();
1012         align::RotationType globalRotation = container->globalRotation();
1013         align::PositionType newpos =
1014             align::PositionType(globalRotation.transposed() * pos.basicVector() + globalPosition.basicVector());
1015         align::RotationType newrot = rot * globalRotation;
1016         set_one_position(ali, newpos, newrot);
1017       } else {
1018         set_one_position(ali, pos, rot);
1019       }
1020     }  // end relativeto="container"
1021 
1022   }  // end loop over alignables
1023 }
1024 
1025 void MuonAlignmentInputXML::set_one_position(Alignable *ali,
1026                                              const align::PositionType &pos,
1027                                              const align::RotationType &rot) const {
1028   const align::PositionType &oldpos = ali->globalPosition();
1029   const align::RotationType &oldrot = ali->globalRotation();
1030 
1031   // shift needed to move from current to new position
1032   align::GlobalVector posDiff = pos - oldpos;
1033   align::RotationType rotDiff = oldrot.multiplyInverse(rot);
1034   align::rectify(rotDiff);  // correct for rounding errors
1035   ali->move(posDiff);
1036   ali->rotateInGlobalFrame(rotDiff);
1037 
1038   //    // check for consistency
1039   //    const align::PositionType& newpos = ali->globalPosition();
1040   //    const align::RotationType& newrot = ali->globalRotation();
1041   //    align::GlobalVector posDiff2 = pos - newpos;
1042   //    align::RotationType rotDiff2 = newrot.multiplyInverse(rot);
1043   //    align::rectify(rotDiff2); // correct for rounding errors
1044 
1045   //    if (fabs(posDiff2.x()) > 1e-6  ||  fabs(posDiff2.y()) > 1e-6  ||  fabs(posDiff2.z()) > 1e-6) {
1046   //       std::cout << "zeropos " << posDiff2 << std::endl;
1047   //    }
1048   //    if (fabs(rotDiff2.xx() - 1.) > 1e-4  ||
1049   //        fabs(rotDiff2.yy() - 1.) > 1e-4  ||
1050   //        fabs(rotDiff2.zz() - 1.) > 1e-4  ||
1051   //        fabs(rotDiff2.xy()) > 1e-8  ||
1052   //        fabs(rotDiff2.xz()) > 1e-8  ||
1053   //        fabs(rotDiff2.yz()) > 1e-8) {
1054   //       std::cout << "zerorot " << rotDiff2 << std::endl;
1055   //    }
1056 
1057   align::ErrorMatrix matrix6x6 = ROOT::Math::SMatrixIdentity();
1058   matrix6x6 *= 1000.;  // initial assumption: infinitely weak constraint
1059 
1060   const SurveyDet *survey = ali->survey();
1061   if (survey != nullptr) {
1062     matrix6x6 = survey->errors();  // save the constraint information
1063   }
1064   ali->setSurvey(new SurveyDet(ali->surface(), matrix6x6));
1065 }
1066 
1067 void MuonAlignmentInputXML::do_setape(const XERCES_CPP_NAMESPACE::DOMElement *node,
1068                                       std::map<Alignable *, bool> &aliset,
1069                                       std::map<Alignable *, Alignable *> &alitoideal) const {
1070   DOMAttr *node_xx = node->getAttributeNode(str_xx);
1071   DOMAttr *node_xy = node->getAttributeNode(str_xy);
1072   DOMAttr *node_xz = node->getAttributeNode(str_xz);
1073   DOMAttr *node_xa = node->getAttributeNode(str_xa);
1074   DOMAttr *node_xb = node->getAttributeNode(str_xb);
1075   DOMAttr *node_xc = node->getAttributeNode(str_xc);
1076   DOMAttr *node_yy = node->getAttributeNode(str_yy);
1077   DOMAttr *node_yz = node->getAttributeNode(str_yz);
1078   DOMAttr *node_ya = node->getAttributeNode(str_ya);
1079   DOMAttr *node_yb = node->getAttributeNode(str_yb);
1080   DOMAttr *node_yc = node->getAttributeNode(str_yc);
1081   DOMAttr *node_zz = node->getAttributeNode(str_zz);
1082   DOMAttr *node_za = node->getAttributeNode(str_za);
1083   DOMAttr *node_zb = node->getAttributeNode(str_zb);
1084   DOMAttr *node_zc = node->getAttributeNode(str_zc);
1085   DOMAttr *node_aa = node->getAttributeNode(str_aa);
1086   DOMAttr *node_ab = node->getAttributeNode(str_ab);
1087   DOMAttr *node_ac = node->getAttributeNode(str_ac);
1088   DOMAttr *node_bb = node->getAttributeNode(str_bb);
1089   DOMAttr *node_bc = node->getAttributeNode(str_bc);
1090   DOMAttr *node_cc = node->getAttributeNode(str_cc);
1091 
1092   if (node_xx == nullptr)
1093     throw cms::Exception("XMLException") << "<setape> is missing required \"xx\" attribute" << std::endl;
1094   if (node_xy == nullptr)
1095     throw cms::Exception("XMLException") << "<setape> is missing required \"xy\" attribute" << std::endl;
1096   if (node_xz == nullptr)
1097     throw cms::Exception("XMLException") << "<setape> is missing required \"xz\" attribute" << std::endl;
1098   if (node_xa == nullptr)
1099     throw cms::Exception("XMLException") << "<setape> is missing required \"xa\" attribute" << std::endl;
1100   if (node_xb == nullptr)
1101     throw cms::Exception("XMLException") << "<setape> is missing required \"xb\" attribute" << std::endl;
1102   if (node_xc == nullptr)
1103     throw cms::Exception("XMLException") << "<setape> is missing required \"xc\" attribute" << std::endl;
1104   if (node_yy == nullptr)
1105     throw cms::Exception("XMLException") << "<setape> is missing required \"yy\" attribute" << std::endl;
1106   if (node_yz == nullptr)
1107     throw cms::Exception("XMLException") << "<setape> is missing required \"yz\" attribute" << std::endl;
1108   if (node_ya == nullptr)
1109     throw cms::Exception("XMLException") << "<setape> is missing required \"ya\" attribute" << std::endl;
1110   if (node_yb == nullptr)
1111     throw cms::Exception("XMLException") << "<setape> is missing required \"yb\" attribute" << std::endl;
1112   if (node_yc == nullptr)
1113     throw cms::Exception("XMLException") << "<setape> is missing required \"yc\" attribute" << std::endl;
1114   if (node_zz == nullptr)
1115     throw cms::Exception("XMLException") << "<setape> is missing required \"zz\" attribute" << std::endl;
1116   if (node_za == nullptr)
1117     throw cms::Exception("XMLException") << "<setape> is missing required \"za\" attribute" << std::endl;
1118   if (node_zb == nullptr)
1119     throw cms::Exception("XMLException") << "<setape> is missing required \"zb\" attribute" << std::endl;
1120   if (node_zc == nullptr)
1121     throw cms::Exception("XMLException") << "<setape> is missing required \"zc\" attribute" << std::endl;
1122   if (node_aa == nullptr)
1123     throw cms::Exception("XMLException") << "<setape> is missing required \"aa\" attribute" << std::endl;
1124   if (node_ab == nullptr)
1125     throw cms::Exception("XMLException") << "<setape> is missing required \"ab\" attribute" << std::endl;
1126   if (node_ac == nullptr)
1127     throw cms::Exception("XMLException") << "<setape> is missing required \"ac\" attribute" << std::endl;
1128   if (node_bb == nullptr)
1129     throw cms::Exception("XMLException") << "<setape> is missing required \"bb\" attribute" << std::endl;
1130   if (node_bc == nullptr)
1131     throw cms::Exception("XMLException") << "<setape> is missing required \"bc\" attribute" << std::endl;
1132   if (node_cc == nullptr)
1133     throw cms::Exception("XMLException") << "<setape> is missing required \"cc\" attribute" << std::endl;
1134 
1135   align::ErrorMatrix matrix6x6;
1136   matrix6x6(0, 0) = parseDouble(node_xx->getValue(), "xx");
1137   matrix6x6(0, 1) = parseDouble(node_xy->getValue(), "xy");
1138   matrix6x6(0, 2) = parseDouble(node_xz->getValue(), "xz");
1139   matrix6x6(0, 3) = parseDouble(node_xa->getValue(), "xa");
1140   matrix6x6(0, 4) = parseDouble(node_xb->getValue(), "xb");
1141   matrix6x6(0, 5) = parseDouble(node_xc->getValue(), "xc");
1142   matrix6x6(1, 1) = parseDouble(node_yy->getValue(), "yy");
1143   matrix6x6(1, 2) = parseDouble(node_yz->getValue(), "yz");
1144   matrix6x6(1, 3) = parseDouble(node_ya->getValue(), "ya");
1145   matrix6x6(1, 4) = parseDouble(node_yb->getValue(), "yb");
1146   matrix6x6(1, 5) = parseDouble(node_yc->getValue(), "yc");
1147   matrix6x6(2, 2) = parseDouble(node_zz->getValue(), "zz");
1148   matrix6x6(2, 3) = parseDouble(node_za->getValue(), "za");
1149   matrix6x6(2, 4) = parseDouble(node_zb->getValue(), "zb");
1150   matrix6x6(2, 5) = parseDouble(node_zc->getValue(), "zc");
1151   matrix6x6(3, 3) = parseDouble(node_aa->getValue(), "aa");
1152   matrix6x6(3, 4) = parseDouble(node_ab->getValue(), "ab");
1153   matrix6x6(3, 5) = parseDouble(node_ac->getValue(), "ac");
1154   matrix6x6(4, 4) = parseDouble(node_bb->getValue(), "bb");
1155   matrix6x6(4, 5) = parseDouble(node_bc->getValue(), "bc");
1156   matrix6x6(5, 5) = parseDouble(node_cc->getValue(), "cc");
1157 
1158   for (std::map<Alignable *, bool>::const_iterator aliiter = aliset.begin(); aliiter != aliset.end(); ++aliiter) {
1159     // this sets APEs at this level and (since 2nd argument is true) all lower levels
1160     aliiter->first->setAlignmentPositionError(AlignmentPositionError(matrix6x6), true);
1161   }
1162 }
1163 
1164 void MuonAlignmentInputXML::do_setsurveyerr(const XERCES_CPP_NAMESPACE::DOMElement *node,
1165                                             std::map<Alignable *, bool> &aliset,
1166                                             std::map<Alignable *, Alignable *> &alitoideal) const {
1167   DOMAttr *node_xx = node->getAttributeNode(str_xx);
1168   DOMAttr *node_xy = node->getAttributeNode(str_xy);
1169   DOMAttr *node_xz = node->getAttributeNode(str_xz);
1170   DOMAttr *node_xa = node->getAttributeNode(str_xa);
1171   DOMAttr *node_xb = node->getAttributeNode(str_xb);
1172   DOMAttr *node_xc = node->getAttributeNode(str_xc);
1173   DOMAttr *node_yy = node->getAttributeNode(str_yy);
1174   DOMAttr *node_yz = node->getAttributeNode(str_yz);
1175   DOMAttr *node_ya = node->getAttributeNode(str_ya);
1176   DOMAttr *node_yb = node->getAttributeNode(str_yb);
1177   DOMAttr *node_yc = node->getAttributeNode(str_yc);
1178   DOMAttr *node_zz = node->getAttributeNode(str_zz);
1179   DOMAttr *node_za = node->getAttributeNode(str_za);
1180   DOMAttr *node_zb = node->getAttributeNode(str_zb);
1181   DOMAttr *node_zc = node->getAttributeNode(str_zc);
1182   DOMAttr *node_aa = node->getAttributeNode(str_aa);
1183   DOMAttr *node_ab = node->getAttributeNode(str_ab);
1184   DOMAttr *node_ac = node->getAttributeNode(str_ac);
1185   DOMAttr *node_bb = node->getAttributeNode(str_bb);
1186   DOMAttr *node_bc = node->getAttributeNode(str_bc);
1187   DOMAttr *node_cc = node->getAttributeNode(str_cc);
1188 
1189   if (node_xx == nullptr)
1190     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"xx\" attribute" << std::endl;
1191   if (node_xy == nullptr)
1192     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"xy\" attribute" << std::endl;
1193   if (node_xz == nullptr)
1194     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"xz\" attribute" << std::endl;
1195   if (node_xa == nullptr)
1196     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"xa\" attribute" << std::endl;
1197   if (node_xb == nullptr)
1198     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"xb\" attribute" << std::endl;
1199   if (node_xc == nullptr)
1200     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"xc\" attribute" << std::endl;
1201   if (node_yy == nullptr)
1202     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"yy\" attribute" << std::endl;
1203   if (node_yz == nullptr)
1204     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"yz\" attribute" << std::endl;
1205   if (node_ya == nullptr)
1206     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"ya\" attribute" << std::endl;
1207   if (node_yb == nullptr)
1208     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"yb\" attribute" << std::endl;
1209   if (node_yc == nullptr)
1210     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"yc\" attribute" << std::endl;
1211   if (node_zz == nullptr)
1212     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"zz\" attribute" << std::endl;
1213   if (node_za == nullptr)
1214     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"za\" attribute" << std::endl;
1215   if (node_zb == nullptr)
1216     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"zb\" attribute" << std::endl;
1217   if (node_zc == nullptr)
1218     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"zc\" attribute" << std::endl;
1219   if (node_aa == nullptr)
1220     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"aa\" attribute" << std::endl;
1221   if (node_ab == nullptr)
1222     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"ab\" attribute" << std::endl;
1223   if (node_ac == nullptr)
1224     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"ac\" attribute" << std::endl;
1225   if (node_bb == nullptr)
1226     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"bb\" attribute" << std::endl;
1227   if (node_bc == nullptr)
1228     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"bc\" attribute" << std::endl;
1229   if (node_cc == nullptr)
1230     throw cms::Exception("XMLException") << "<setsurveyerr> is missing required \"cc\" attribute" << std::endl;
1231 
1232   align::ErrorMatrix matrix6x6;
1233   matrix6x6(0, 0) = parseDouble(node_xx->getValue(), "xx");
1234   matrix6x6(0, 1) = parseDouble(node_xy->getValue(), "xy");
1235   matrix6x6(0, 2) = parseDouble(node_xz->getValue(), "xz");
1236   matrix6x6(0, 3) = parseDouble(node_xa->getValue(), "xa");
1237   matrix6x6(0, 4) = parseDouble(node_xb->getValue(), "xb");
1238   matrix6x6(0, 5) = parseDouble(node_xc->getValue(), "xc");
1239   matrix6x6(1, 1) = parseDouble(node_yy->getValue(), "yy");
1240   matrix6x6(1, 2) = parseDouble(node_yz->getValue(), "yz");
1241   matrix6x6(1, 3) = parseDouble(node_ya->getValue(), "ya");
1242   matrix6x6(1, 4) = parseDouble(node_yb->getValue(), "yb");
1243   matrix6x6(1, 5) = parseDouble(node_yc->getValue(), "yc");
1244   matrix6x6(2, 2) = parseDouble(node_zz->getValue(), "zz");
1245   matrix6x6(2, 3) = parseDouble(node_za->getValue(), "za");
1246   matrix6x6(2, 4) = parseDouble(node_zb->getValue(), "zb");
1247   matrix6x6(2, 5) = parseDouble(node_zc->getValue(), "zc");
1248   matrix6x6(3, 3) = parseDouble(node_aa->getValue(), "aa");
1249   matrix6x6(3, 4) = parseDouble(node_ab->getValue(), "ab");
1250   matrix6x6(3, 5) = parseDouble(node_ac->getValue(), "ac");
1251   matrix6x6(4, 4) = parseDouble(node_bb->getValue(), "bb");
1252   matrix6x6(4, 5) = parseDouble(node_bc->getValue(), "bc");
1253   matrix6x6(5, 5) = parseDouble(node_cc->getValue(), "cc");
1254 
1255   for (std::map<Alignable *, bool>::const_iterator aliiter = aliset.begin(); aliiter != aliset.end(); ++aliiter) {
1256     Alignable *ali = aliiter->first;
1257     ali->setSurvey(new SurveyDet(ali->surface(), matrix6x6));
1258   }
1259 }
1260 
1261 void MuonAlignmentInputXML::do_moveglobal(const XERCES_CPP_NAMESPACE::DOMElement *node,
1262                                           std::map<Alignable *, bool> &aliset,
1263                                           std::map<Alignable *, Alignable *> &alitoideal) const {
1264   DOMAttr *node_x = node->getAttributeNode(str_x);
1265   DOMAttr *node_y = node->getAttributeNode(str_y);
1266   DOMAttr *node_z = node->getAttributeNode(str_z);
1267   if (node_x == nullptr)
1268     throw cms::Exception("XMLException") << "<moveglobal> is missing required \"x\" attribute" << std::endl;
1269   if (node_y == nullptr)
1270     throw cms::Exception("XMLException") << "<moveglobal> is missing required \"y\" attribute" << std::endl;
1271   if (node_z == nullptr)
1272     throw cms::Exception("XMLException") << "<moveglobal> is missing required \"z\" attribute" << std::endl;
1273 
1274   double x = parseDouble(node_x->getValue(), "x");
1275   double y = parseDouble(node_y->getValue(), "y");
1276   double z = parseDouble(node_z->getValue(), "z");
1277   align::GlobalVector vect(x, y, z);
1278 
1279   for (std::map<Alignable *, bool>::const_iterator aliiter = aliset.begin(); aliiter != aliset.end(); ++aliiter) {
1280     Alignable *ali = aliiter->first;
1281 
1282     ali->move(vect);
1283 
1284     align::ErrorMatrix matrix6x6 = ROOT::Math::SMatrixIdentity();
1285     matrix6x6 *= 1000.;  // initial assumption: infinitely weak constraint
1286 
1287     const SurveyDet *survey = ali->survey();
1288     if (survey != nullptr) {
1289       matrix6x6 = survey->errors();  // save the constraint information
1290     }
1291     ali->setSurvey(new SurveyDet(ali->surface(), matrix6x6));
1292   }  // end loop over alignables
1293 }
1294 
1295 void MuonAlignmentInputXML::do_movelocal(const XERCES_CPP_NAMESPACE::DOMElement *node,
1296                                          std::map<Alignable *, bool> &aliset,
1297                                          std::map<Alignable *, Alignable *> &alitoideal) const {
1298   DOMAttr *node_x = node->getAttributeNode(str_x);
1299   DOMAttr *node_y = node->getAttributeNode(str_y);
1300   DOMAttr *node_z = node->getAttributeNode(str_z);
1301   if (node_x == nullptr)
1302     throw cms::Exception("XMLException") << "<movelocal> is missing required \"x\" attribute" << std::endl;
1303   if (node_y == nullptr)
1304     throw cms::Exception("XMLException") << "<movelocal> is missing required \"y\" attribute" << std::endl;
1305   if (node_z == nullptr)
1306     throw cms::Exception("XMLException") << "<movelocal> is missing required \"z\" attribute" << std::endl;
1307 
1308   double x = parseDouble(node_x->getValue(), "x");
1309   double y = parseDouble(node_y->getValue(), "y");
1310   double z = parseDouble(node_z->getValue(), "z");
1311   align::LocalVector vect(x, y, z);
1312 
1313   for (std::map<Alignable *, bool>::const_iterator aliiter = aliset.begin(); aliiter != aliset.end(); ++aliiter) {
1314     Alignable *ali = aliiter->first;
1315 
1316     align::GlobalVector globalVector = ali->surface().toGlobal(vect);
1317     ali->move(globalVector);
1318 
1319     align::ErrorMatrix matrix6x6 = ROOT::Math::SMatrixIdentity();
1320     matrix6x6 *= 1000.;  // initial assumption: infinitely weak constraint
1321 
1322     const SurveyDet *survey = ali->survey();
1323     if (survey != nullptr) {
1324       matrix6x6 = survey->errors();  // save the constraint information
1325     }
1326     ali->setSurvey(new SurveyDet(ali->surface(), matrix6x6));
1327   }  // end loop over alignables
1328 }
1329 
1330 void MuonAlignmentInputXML::do_rotatelocal(const XERCES_CPP_NAMESPACE::DOMElement *node,
1331                                            std::map<Alignable *, bool> &aliset,
1332                                            std::map<Alignable *, Alignable *> &alitoideal) const {
1333   DOMAttr *node_axisx = node->getAttributeNode(str_axisx);
1334   DOMAttr *node_axisy = node->getAttributeNode(str_axisy);
1335   DOMAttr *node_axisz = node->getAttributeNode(str_axisz);
1336   DOMAttr *node_angle = node->getAttributeNode(str_angle);
1337   if (node_axisx == nullptr)
1338     throw cms::Exception("XMLException") << "<rotatelocal> is missing required \"axisx\" attribute" << std::endl;
1339   if (node_axisy == nullptr)
1340     throw cms::Exception("XMLException") << "<rotatelocal> is missing required \"axisy\" attribute" << std::endl;
1341   if (node_axisz == nullptr)
1342     throw cms::Exception("XMLException") << "<rotatelocal> is missing required \"axisz\" attribute" << std::endl;
1343   if (node_angle == nullptr)
1344     throw cms::Exception("XMLException") << "<rotatelocal> is missing required \"angle\" attribute" << std::endl;
1345 
1346   double x = parseDouble(node_axisx->getValue(), "x");
1347   double y = parseDouble(node_axisy->getValue(), "y");
1348   double z = parseDouble(node_axisz->getValue(), "z");
1349   double angle = parseDouble(node_angle->getValue(), "angle");
1350   align::LocalVector vect(x, y, z);
1351 
1352   for (std::map<Alignable *, bool>::const_iterator aliiter = aliset.begin(); aliiter != aliset.end(); ++aliiter) {
1353     Alignable *ali = aliiter->first;
1354 
1355     ali->rotateAroundLocalAxis(vect, angle);
1356 
1357     align::ErrorMatrix matrix6x6 = ROOT::Math::SMatrixIdentity();
1358     matrix6x6 *= 1000.;  // initial assumption: infinitely weak constraint
1359 
1360     const SurveyDet *survey = ali->survey();
1361     if (survey != nullptr) {
1362       matrix6x6 = survey->errors();  // save the constraint information
1363     }
1364     ali->setSurvey(new SurveyDet(ali->surface(), matrix6x6));
1365   }  // end loop over alignables
1366 }
1367 
1368 void MuonAlignmentInputXML::do_rotatebeamline(const XERCES_CPP_NAMESPACE::DOMElement *node,
1369                                               std::map<Alignable *, bool> &aliset,
1370                                               std::map<Alignable *, Alignable *> &alitoideal) const {
1371   DOMAttr *node_rphi = node->getAttributeNode(str_rphi);
1372   DOMAttr *node_phi = node->getAttributeNode(str_phi);
1373   if (node_rphi == nullptr && node_phi == nullptr)
1374     throw cms::Exception("XMLException") << "<rotatebeamline> is missing required \"*phi\" attribute" << std::endl;
1375   if (node_rphi != nullptr && node_phi != nullptr)
1376     throw cms::Exception("XMLException") << "<rotatebeamline> can't have both an \"rphi\" and a \"phi\" attribute"
1377                                          << std::endl;
1378 
1379   double value;
1380   if (node_rphi != nullptr) {
1381     value = parseDouble(node_rphi->getValue(), "rphi");
1382   } else {
1383     value = parseDouble(node_phi->getValue(), "phi");
1384   }
1385 
1386   for (std::map<Alignable *, bool>::const_iterator aliiter = aliset.begin(); aliiter != aliset.end(); ++aliiter) {
1387     Alignable *ali = aliiter->first;
1388 
1389     align::GlobalPoint pos = ali->surface().toGlobal(align::LocalPoint(0, 0, 0));
1390 
1391     double radius = pos.perp();
1392     double phi0 = pos.phi();
1393     double deltaphi = value;
1394     if (node_rphi != nullptr)
1395       deltaphi = value / radius;
1396 
1397     ali->rotateAroundGlobalZ(deltaphi);
1398     ali->move(align::GlobalVector(
1399         radius * (cos(phi0 + deltaphi) - cos(phi0)), radius * (sin(phi0 + deltaphi) - sin(phi0)), 0.));
1400 
1401     align::ErrorMatrix matrix6x6 = ROOT::Math::SMatrixIdentity();
1402     matrix6x6 *= 1000.;  // initial assumption: infinitely weak constraint
1403 
1404     const SurveyDet *survey = ali->survey();
1405     if (survey != nullptr) {
1406       matrix6x6 = survey->errors();  // save the constraint information
1407     }
1408     ali->setSurvey(new SurveyDet(ali->surface(), matrix6x6));
1409   }  // end loop over alignables
1410 }
1411 
1412 void MuonAlignmentInputXML::do_rotateglobalaxis(const XERCES_CPP_NAMESPACE::DOMElement *node,
1413                                                 std::map<Alignable *, bool> &aliset,
1414                                                 std::map<Alignable *, Alignable *> &alitoideal) const {
1415   DOMAttr *node_x = node->getAttributeNode(str_x);
1416   DOMAttr *node_y = node->getAttributeNode(str_y);
1417   DOMAttr *node_z = node->getAttributeNode(str_z);
1418   DOMAttr *node_angle = node->getAttributeNode(str_angle);
1419   if (node_x == nullptr)
1420     throw cms::Exception("XMLException") << "<rotateglobalaxis> is missing required \"x\" attribute" << std::endl;
1421   if (node_y == nullptr)
1422     throw cms::Exception("XMLException") << "<rotateglobalaxis> is missing required \"y\" attribute" << std::endl;
1423   if (node_z == nullptr)
1424     throw cms::Exception("XMLException") << "<rotateglobalaxis> is missing required \"z\" attribute" << std::endl;
1425   if (node_angle == nullptr)
1426     throw cms::Exception("XMLException") << "<rotateglobalaxis> is missing required \"angle\" attribute" << std::endl;
1427 
1428   double x = parseDouble(node_x->getValue(), "x");
1429   double y = parseDouble(node_y->getValue(), "y");
1430   double z = parseDouble(node_z->getValue(), "z");
1431   double angle = parseDouble(node_angle->getValue(), "angle");
1432 
1433   for (std::map<Alignable *, bool>::const_iterator aliiter = aliset.begin(); aliiter != aliset.end(); ++aliiter) {
1434     Alignable *ali = aliiter->first;
1435     align::GlobalPoint pos = ali->surface().toGlobal(align::LocalPoint(0, 0, 0));
1436 
1437     ali->rotateAroundGlobalAxis(align::GlobalVector(x, y, z), angle);
1438 
1439     double aprime = x / sqrt(x * x + y * y + z * z);
1440     double bprime = y / sqrt(x * x + y * y + z * z);
1441     double cprime = z / sqrt(x * x + y * y + z * z);
1442     double q0 = cos(angle / 2.);
1443     double q1 = sin(angle / 2.) * aprime;
1444     double q2 = sin(angle / 2.) * bprime;
1445     double q3 = sin(angle / 2.) * cprime;
1446 
1447     double pos2x = (q0 * q0 + q1 * q1 - q2 * q2 - q3 * q3) * pos.x() + 2. * (q1 * q2 - q0 * q3) * pos.y() +
1448                    2. * (q1 * q3 + q0 * q2) * pos.z();
1449     double pos2y = 2. * (q2 * q1 + q0 * q3) * pos.x() + (q0 * q0 - q1 * q1 + q2 * q2 - q3 * q3) * pos.y() +
1450                    2. * (q2 * q3 - q0 * q1) * pos.z();
1451     double pos2z = 2. * (q3 * q1 - q0 * q2) * pos.x() + 2. * (q3 * q2 + q0 * q1) * pos.y() +
1452                    (q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3) * pos.z();
1453 
1454     double movex = pos2x - pos.x();
1455     double movey = pos2y - pos.y();
1456     double movez = pos2z - pos.z();
1457     ali->move(align::GlobalVector(movex, movey, movez));
1458 
1459     align::ErrorMatrix matrix6x6 = ROOT::Math::SMatrixIdentity();
1460     matrix6x6 *= 1000.;  // initial assumption: infinitely weak constraint
1461 
1462     const SurveyDet *survey = ali->survey();
1463     if (survey != nullptr) {
1464       matrix6x6 = survey->errors();  // save the constraint information
1465     }
1466     ali->setSurvey(new SurveyDet(ali->surface(), matrix6x6));
1467   }  // end loop over alignables
1468 }
1469 
1470 //
1471 // const member functions
1472 //
1473 
1474 //
1475 // static member functions
1476 //