diff --git a/Alignment/CocoaApplication/BuildFile.xml b/Alignment/CocoaApplication/BuildFile.xml
new file mode 100644
index 0000000000000..833bad49ac850
--- /dev/null
+++ b/Alignment/CocoaApplication/BuildFile.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/Alignment/CocoaApplication/README.md b/Alignment/CocoaApplication/README.md
new file mode 100644
index 0000000000000..101cf9a5233ec
--- /dev/null
+++ b/Alignment/CocoaApplication/README.md
@@ -0,0 +1,47 @@
+# **CMS Object-oriented Code for Optical Alignment**
+
+
+## General COCOA documentation
+
+General documentation is at [1].
+COCOA website is at [2].
+Notably, a user guide can be found at [3].
+
+[1] https://cds.cern.ch/record/1047121/files/p193.pdf
+[2] http://cmsdoc.cern.ch/cms/MUON/alignment/software/COCOA/doc/cocoa.html
+[3] http://cmsdoc.cern.ch/cms/MUON/alignment/software/COCOA/doc/tex/users_guide.ps
+
+
+
+## Run COCOA
+This shows how to:
+- Run the COCOA simulation of an optical alignment system (described in .txt or XML format, with adjustments from DB description);
+- Run the least-squared fit on the alignment system;
+- Store results back into DB.
+
+### Input XML file
+An XML file describing the optical alignment system of interest needs to be provided as input to COCOA.
+
+Such an XML file can be generated from a .txt description, by an independent cocoa application in `Alignment/CocoaApplication/bin`.
+For example, one can generate an XML optical alignment system description, by simply doing the following:
+
+ cd Alignment/CocoaApplication/bin
+ cocoa simple2D.txt
+
+### Input DB OpticalAlignmentsRcd
+For testing purposes, an example input DB `OpticalAlignmentsRcd` can now be found at `Alignment/CocoaApplication/test/OpticalAlignments.db`.
+It was generated by adding the following, in `CocoaAnalyzer::analyze`, after `readXMLFile` returns:
+
+ Model& model = Model::getInstance();
+ model.BuildSystemDescriptionFromOA(oaList_);
+ CocoaDBMgr::getInstance()->DumpCocoaResults();
+Of course, in practice, one would actually just need to call the OpticalAlignmentsRcd of interest to the desired alignment study.
+
+### Run COCOA
+One can now just do:
+
+ cd Alignment/CocoaApplication/test
+ cmsRun cocoaAnalyzer_cfg.py
+This will perform the least-squared fit, and store all results in `Alignment/CocoaApplication/test/OpticalAlignments.db`.
+The `OpticalAlignmentsRcd` obtained after fit, is stored with `OpticalAlignmentsRcdOutput` tag.
+It should also be possible to use the feature of dumping the results into ROOT format.
diff --git a/Alignment/CocoaApplication/interface/CocoaAnalyzer.h b/Alignment/CocoaApplication/interface/CocoaAnalyzer.h
new file mode 100644
index 0000000000000..3438b652fa2cc
--- /dev/null
+++ b/Alignment/CocoaApplication/interface/CocoaAnalyzer.h
@@ -0,0 +1,43 @@
+#ifndef ALIGNMENT_COCOA_APPLICATION_COCOA_ANALYZER_H
+#define ALIGNMENT_COCOA_APPLICATION_COCOA_ANALYZER_H
+
+#include "FWCore/Framework/interface/one/EDAnalyzer.h"
+#include "DetectorDescription/DDCMS/interface/DDSpecParRegistry.h"
+#include "CondFormats/OptAlignObjects/interface/OpticalAlignments.h"
+#include "CondFormats/OptAlignObjects/interface/OpticalAlignMeasurements.h"
+
+class CocoaAnalyzer : public edm::one::EDAnalyzer {
+public:
+ explicit CocoaAnalyzer(edm::ParameterSet const& p);
+ explicit CocoaAnalyzer(int i) {}
+ ~CocoaAnalyzer() override {}
+
+ void beginJob() override;
+ void analyze(const edm::Event& e, const edm::EventSetup& c) override;
+
+private:
+ void readXMLFile(const edm::EventSetup& evts);
+
+ std::vector readCalibrationDB(const edm::EventSetup& evts);
+ void correctAllOpticalAlignments(std::vector& allDBOpticalAlignments);
+ void correctOpticalAlignmentParameter(OpticalAlignParam& myXMLParam, const OpticalAlignParam& myDBParam);
+
+ void runCocoa();
+
+ template
+ std::vector getAllParameterValuesFromSpecParSections(const cms::DDSpecParRegistry& allSpecParSections,
+ const std::string& nodePath,
+ const std::string& parameterName);
+ template
+ T getParameterValueFromSpecParSections(const cms::DDSpecParRegistry& allSpecParSections,
+ const std::string& nodePath,
+ const std::string& parameterName,
+ const unsigned int parameterValueIndex);
+
+private:
+ OpticalAlignments oaList_;
+ OpticalAlignMeasurements measList_;
+ std::string theCocoaDaqRootFileName_;
+};
+
+#endif
diff --git a/Alignment/CocoaApplication/src/CocoaAnalyzer.cc b/Alignment/CocoaApplication/src/CocoaAnalyzer.cc
new file mode 100644
index 0000000000000..f9aab2322b4ce
--- /dev/null
+++ b/Alignment/CocoaApplication/src/CocoaAnalyzer.cc
@@ -0,0 +1,606 @@
+#include "FWCore/ServiceRegistry/interface/Service.h"
+#include "CondCore/DBOutputService/interface/PoolDBOutputService.h"
+#include "CondFormats/DataRecord/interface/OpticalAlignmentsRcd.h"
+#include "CondFormats/OptAlignObjects/interface/OpticalAlignMeasurementInfo.h"
+#include "DataFormats/Math/interface/CMSUnits.h"
+#include "DetectorDescription/DDCMS/interface/DDCompactView.h"
+#include "DetectorDescription/DDCMS/interface/DDFilteredView.h"
+#include "FWCore/ParameterSet/interface/ParameterSet.h"
+#include "FWCore/Framework/interface/ESHandle.h"
+#include "FWCore/Framework/interface/ESTransientHandle.h"
+#include "FWCore/Framework/interface/Event.h"
+#include "FWCore/Framework/interface/EventSetup.h"
+#include "Geometry/Records/interface/IdealGeometryRecord.h"
+
+#include "Alignment/CocoaApplication/interface/CocoaAnalyzer.h"
+#include "Alignment/CocoaUtilities/interface/ALIUtils.h"
+#include "Alignment/CocoaModel/interface/Model.h"
+#include "Alignment/CocoaFit/interface/Fit.h"
+#include "Alignment/CocoaModel/interface/Entry.h"
+#include "Alignment/CocoaUtilities/interface/ALIFileOut.h"
+#include "Alignment/CocoaModel/interface/CocoaDaqReaderRoot.h"
+#include "Alignment/CocoaModel/interface/OpticalObject.h"
+#include "Alignment/CocoaUtilities/interface/GlobalOptionMgr.h"
+#include "Alignment/CocoaFit/interface/CocoaDBMgr.h"
+
+using namespace cms_units::operators;
+
+CocoaAnalyzer::CocoaAnalyzer(edm::ParameterSet const& pset) {
+ theCocoaDaqRootFileName_ = pset.getParameter("cocoaDaqRootFile");
+ int maxEvents = pset.getParameter("maxEvents");
+ GlobalOptionMgr::getInstance()->setDefaultGlobalOptions();
+ GlobalOptionMgr::getInstance()->setGlobalOption("maxEvents", maxEvents);
+ GlobalOptionMgr::getInstance()->setGlobalOption("writeDBAlign", 1);
+ GlobalOptionMgr::getInstance()->setGlobalOption("writeDBOptAlign", 1);
+ usesResource("CocoaAnalyzer");
+}
+
+void CocoaAnalyzer::beginJob() {}
+
+void CocoaAnalyzer::analyze(const edm::Event& evt, const edm::EventSetup& evts) {
+ ALIUtils::setDebugVerbosity(5);
+
+ // Get ideal geometry description + measurements for simulation.
+ readXMLFile(evts);
+
+ // Correct ideal geometry with data from DB.
+ std::vector oaListCalib = readCalibrationDB(evts);
+ correctAllOpticalAlignments(oaListCalib);
+
+ // Run the least-squared fit and store results in DB.
+ runCocoa();
+}
+
+/*
+ * This is used to create the ideal geometry description from the XMLs.
+ * Also get measurements from XMLs for simulation.
+ * Resulting optical alignment info is stored in oaList_ and measList_.
+ */
+void CocoaAnalyzer::readXMLFile(const edm::EventSetup& evts) {
+ edm::ESTransientHandle myCompactView;
+ evts.get().get(myCompactView);
+
+ const cms::DDDetector* mySystem = myCompactView->detector();
+
+ if (mySystem) {
+ // Always store world volume first.
+ const dd4hep::Volume& worldVolume = mySystem->worldVolume();
+
+ if (ALIUtils::debug >= 3) {
+ edm::LogInfo("Alignment") << "CocoaAnalyzer::ReadXML: world object = " << worldVolume.name();
+ }
+
+ OpticalAlignInfo worldInfo;
+ worldInfo.ID_ = 0;
+ worldInfo.name_ = worldVolume.name();
+ worldInfo.type_ = "system";
+ worldInfo.parentName_ = "";
+ worldInfo.x_.value_ = 0.;
+ worldInfo.x_.error_ = 0.;
+ worldInfo.x_.quality_ = 0;
+ worldInfo.y_.value_ = 0.;
+ worldInfo.y_.error_ = 0.;
+ worldInfo.y_.quality_ = 0;
+ worldInfo.z_.value_ = 0.;
+ worldInfo.z_.error_ = 0.;
+ worldInfo.z_.quality_ = 0;
+ worldInfo.angx_.value_ = 0.;
+ worldInfo.angx_.error_ = 0.;
+ worldInfo.angx_.quality_ = 0;
+ worldInfo.angy_.value_ = 0.;
+ worldInfo.angy_.error_ = 0.;
+ worldInfo.angy_.quality_ = 0;
+ worldInfo.angz_.value_ = 0.;
+ worldInfo.angz_.error_ = 0.;
+ worldInfo.angz_.quality_ = 0;
+ oaList_.opticalAlignments_.emplace_back(worldInfo);
+
+ // This gathers all the 'SpecPar' sections from the loaded XMLs.
+ // NB: Definition of a SpecPar section:
+ // It is a block in the XML file(s), containing paths to specific volumes,
+ // and ALLOWING THE ASSOCIATION OF SPECIFIC PARAMETERS AND VALUES TO THESE VOLUMES.
+ const cms::DDSpecParRegistry& allSpecParSections = myCompactView->specpars();
+
+ // CREATION OF A COCOA FILTERED VIEW
+ // Creation of the dd4hep-based filtered view.
+ // NB: not filtered yet!
+ cms::DDFilteredView myFilteredView(mySystem, worldVolume);
+ // Declare a container which will gather all the filtered SpecPar sections.
+ cms::DDSpecParRefs cocoaParameterSpecParSections;
+ // Define a COCOA filter
+ const std::string cocoaParameterAttribute = "COCOA";
+ const std::string cocoaParameterValue = "COCOA";
+ // All the COCOA SpecPar sections are filtered from allSpecParSections,
+ // and assigned to cocoaParameterSpecParSections.
+ allSpecParSections.filter(cocoaParameterSpecParSections, cocoaParameterAttribute, cocoaParameterValue);
+ // This finally allows to filter the filtered view, with the COCOA filter.
+ // This means that we now have, in myFilteredView, all volumes whose paths were selected:
+ // ie all volumes with "COCOA" parameter and value in a SpecPar section from a loaded XML.
+ myFilteredView.mergedSpecifics(cocoaParameterSpecParSections);
+
+ // Loop on parts
+ int nObjects = 0;
+ bool doCOCOA = myFilteredView.firstChild();
+
+ // Loop on all COCOA volumes from filtered view
+ while (doCOCOA) {
+ ++nObjects;
+
+ OpticalAlignInfo oaInfo;
+ OpticalAlignParam oaParam;
+ OpticalAlignMeasurementInfo oaMeas;
+
+ // Current volume
+ const dd4hep::PlacedVolume& myPlacedVolume = myFilteredView.volume();
+ const std::string& name = myPlacedVolume.name();
+ const std::string& nodePath = myFilteredView.path();
+ oaInfo.name_ = nodePath;
+
+ // Parent name
+ oaInfo.parentName_ = nodePath.substr(0, nodePath.rfind('/', nodePath.length()));
+
+ if (ALIUtils::debug >= 4) {
+ edm::LogInfo("Alignment") << " CocoaAnalyzer::ReadXML reading object " << name;
+ edm::LogInfo("Alignment") << " @@ Name built= " << oaInfo.name_ << " short_name= " << name
+ << " parent= " << oaInfo.parentName_;
+ }
+
+ // TRANSLATIONS
+
+ // A) GET TRANSLATIONS FROM DDETECTOR.
+ // Directly get translation from parent to child volume
+ const dd4hep::Direction& transl = myPlacedVolume.position();
+
+ if (ALIUtils::debug >= 4) {
+ edm::LogInfo("Alignment") << "Local translation in cm = " << transl;
+ }
+
+ // B) READ INFO FROM XMLS
+ // X
+ oaInfo.x_.name_ = "X";
+ oaInfo.x_.dim_type_ = "centre";
+ oaInfo.x_.value_ = transl.x() / (1._m); // COCOA units are m
+ oaInfo.x_.error_ = getParameterValueFromSpecParSections(allSpecParSections,
+ nodePath,
+ "centre_X_sigma",
+ 0) /
+ (1._m); // COCOA units are m
+ oaInfo.x_.quality_ = static_cast(
+ getParameterValueFromSpecParSections(allSpecParSections, nodePath, "centre_X_quality", 0));
+ // Y
+ oaInfo.y_.name_ = "Y";
+ oaInfo.y_.dim_type_ = "centre";
+ oaInfo.y_.value_ = transl.y() / (1._m); // COCOA units are m
+ oaInfo.y_.error_ = getParameterValueFromSpecParSections(allSpecParSections,
+ nodePath,
+ "centre_Y_sigma",
+ 0) /
+ (1._m); // COCOA units are m
+ oaInfo.y_.quality_ = static_cast(
+ getParameterValueFromSpecParSections(allSpecParSections, nodePath, "centre_Y_quality", 0));
+ // Z
+ oaInfo.z_.name_ = "Z";
+ oaInfo.z_.dim_type_ = "centre";
+ oaInfo.z_.value_ = transl.z() / (1._m); // COCOA units are m
+ oaInfo.z_.error_ = getParameterValueFromSpecParSections(allSpecParSections,
+ nodePath,
+ "centre_Z_sigma",
+ 0) /
+ (1._m); // COCOA units are m
+ oaInfo.z_.quality_ = static_cast(
+ getParameterValueFromSpecParSections(allSpecParSections, nodePath, "centre_Z_quality", 0));
+
+ // ROTATIONS
+
+ // A) GET ROTATIONS FROM DDETECTOR.
+
+ // Unlike in the initial code, here we manage to directly get the rotation matrix placement
+ // of the child in parent, EXPRESSED IN THE PARENT FRAME OF REFERENCE.
+ // Hence the (ugly) initial block of code is replaced by just 2 lines.
+ // PlacedVolume::matrix() returns the rotation matrix IN THE PARENT FRAME OF REFERENCE.
+ // NB: Not using DDFilteredView::rotation(),
+ // because it returns the rotation matrix IN THE WORLD FRAME OF REFERENCE.
+ const TGeoHMatrix parentToChild = myPlacedVolume.matrix();
+ // COCOA convention is FROM CHILD TO PARENT
+ const TGeoHMatrix& childToParent = parentToChild.Inverse();
+
+ // Convert it to CLHEP::Matrix
+ // Below is not my code, below block is untouched (apart from bug fix).
+ // I would just directly use childToParent...
+ const Double_t* rot = childToParent.GetRotationMatrix();
+ const double xx = rot[0];
+ const double xy = rot[1];
+ const double xz = rot[2];
+ const double yx = rot[3];
+ const double yy = rot[4];
+ const double yz = rot[5];
+ const double zx = rot[6];
+ const double zy = rot[7];
+ const double zz = rot[8];
+ if (ALIUtils::debug >= 4) {
+ edm::LogInfo("Alignment") << "Local rotation = ";
+ edm::LogInfo("Alignment") << xx << " " << xy << " " << xz;
+ edm::LogInfo("Alignment") << yx << " " << yy << " " << yz;
+ edm::LogInfo("Alignment") << zx << " " << zy << " " << zz;
+ }
+ const CLHEP::Hep3Vector colX(xx, yx, zx);
+ const CLHEP::Hep3Vector colY(xy, yy, zy);
+ const CLHEP::Hep3Vector colZ(xz, yz, zz);
+ const CLHEP::HepRotation rotclhep(colX, colY, colZ);
+ const std::vector& angles = ALIUtils::getRotationAnglesFromMatrix(rotclhep, 0., 0., 0.);
+
+ // B) READ INFO FROM XMLS
+ // X
+ oaInfo.angx_.name_ = "X";
+ oaInfo.angx_.dim_type_ = "angles";
+ oaInfo.angx_.value_ =
+ getParameterValueFromSpecParSections(allSpecParSections, nodePath, "angles_X_value", 0);
+ oaInfo.angx_.error_ =
+ getParameterValueFromSpecParSections(allSpecParSections, nodePath, "angles_X_sigma", 0);
+ oaInfo.angx_.quality_ = static_cast(
+ getParameterValueFromSpecParSections(allSpecParSections, nodePath, "angles_X_quality", 0));
+ // Y
+ oaInfo.angy_.name_ = "Y";
+ oaInfo.angy_.dim_type_ = "angles";
+ oaInfo.angy_.value_ =
+ getParameterValueFromSpecParSections(allSpecParSections, nodePath, "angles_Y_value", 0);
+ oaInfo.angy_.error_ =
+ getParameterValueFromSpecParSections(allSpecParSections, nodePath, "angles_Y_sigma", 0);
+ oaInfo.angy_.quality_ = static_cast(
+ getParameterValueFromSpecParSections(allSpecParSections, nodePath, "angles_Y_quality", 0));
+ // Z
+ oaInfo.angz_.name_ = "Z";
+ oaInfo.angz_.dim_type_ = "angles";
+ oaInfo.angz_.value_ =
+ getParameterValueFromSpecParSections(allSpecParSections, nodePath, "angles_Z_value", 0);
+ oaInfo.angz_.error_ =
+ getParameterValueFromSpecParSections(allSpecParSections, nodePath, "angles_Z_sigma", 0);
+ oaInfo.angz_.quality_ = static_cast(
+ getParameterValueFromSpecParSections(allSpecParSections, nodePath, "angles_Z_quality", 0));
+
+ oaInfo.type_ = getParameterValueFromSpecParSections(allSpecParSections, nodePath, "cocoa_type", 0);
+
+ oaInfo.ID_ =
+ static_cast(getParameterValueFromSpecParSections(allSpecParSections, nodePath, "cmssw_ID", 0));
+
+ if (ALIUtils::debug >= 4) {
+ edm::LogInfo("Alignment") << "CocoaAnalyzer::ReadXML OBJECT " << oaInfo.name_ << " pos/angles read ";
+ }
+
+ // Check that rotations match with values from XMLs.
+ // Same, that ugly code is not mine ;p
+ if (fabs(oaInfo.angx_.value_ - angles[0]) > 1.E-9 || fabs(oaInfo.angy_.value_ - angles[1]) > 1.E-9 ||
+ fabs(oaInfo.angz_.value_ - angles[2]) > 1.E-9) {
+ edm::LogError("Alignment") << " WRONG ANGLE IN OBJECT " << oaInfo.name_ << oaInfo.angx_.value_ << " =? "
+ << angles[0] << oaInfo.angy_.value_ << " =? " << angles[1] << oaInfo.angz_.value_
+ << " =? " << angles[2];
+ }
+
+ // EXTRA PARAM ENTRIES (FROM XMLS)
+ // Here initial code to define the containers was fully removed, this is much more compact.
+ const std::vector& names =
+ getAllParameterValuesFromSpecParSections(allSpecParSections, nodePath, "extra_entry");
+ const std::vector& dims =
+ getAllParameterValuesFromSpecParSections(allSpecParSections, nodePath, "dimType");
+ const std::vector& values =
+ getAllParameterValuesFromSpecParSections(allSpecParSections, nodePath, "value");
+ const std::vector& errors =
+ getAllParameterValuesFromSpecParSections(allSpecParSections, nodePath, "sigma");
+ const std::vector& quality =
+ getAllParameterValuesFromSpecParSections(allSpecParSections, nodePath, "quality");
+
+ if (ALIUtils::debug >= 4) {
+ edm::LogInfo("Alignment") << " CocoaAnalyzer::ReadXML: Fill extra entries with read parameters ";
+ }
+
+ if (names.size() == dims.size() && dims.size() == values.size() && values.size() == errors.size() &&
+ errors.size() == quality.size()) {
+ for (size_t i = 0; i < names.size(); ++i) {
+ double dimFactor = 1.;
+ const std::string& type = dims[i];
+ if (type == "centre" || type == "length") {
+ dimFactor = 1. / (1._m); // was converted to cm with getParameterValueFromSpecPar, COCOA unit is m
+ } else if (type == "angles" || type == "angle" || type == "nodim") {
+ dimFactor = 1.;
+ }
+ oaParam.value_ = values[i] * dimFactor;
+ oaParam.error_ = errors[i] * dimFactor;
+ oaParam.quality_ = static_cast(quality[i]);
+ oaParam.name_ = names[i];
+ oaParam.dim_type_ = dims[i];
+ oaInfo.extraEntries_.emplace_back(oaParam);
+ oaParam.clear();
+ }
+
+ oaList_.opticalAlignments_.emplace_back(oaInfo);
+ } else {
+ edm::LogInfo("Alignment") << "WARNING FOR NOW: sizes of extra parameters (names, dimType, value, quality) do"
+ << " not match! Did not add " << nObjects << " item to OpticalAlignments.";
+ }
+
+ // MEASUREMENTS (FROM XMLS)
+ const std::vector& measNames =
+ getAllParameterValuesFromSpecParSections(allSpecParSections, nodePath, "meas_name");
+ const std::vector& measTypes =
+ getAllParameterValuesFromSpecParSections(allSpecParSections, nodePath, "meas_type");
+
+ std::map> measObjectNames;
+ std::map> measParamNames;
+ std::map> measParamValues;
+ std::map> measParamSigmas;
+ std::map> measIsSimulatedValue;
+ for (const auto& name : measNames) {
+ measObjectNames[name] = getAllParameterValuesFromSpecParSections(
+ allSpecParSections, nodePath, "meas_object_name_" + name);
+ measParamNames[name] = getAllParameterValuesFromSpecParSections(
+ allSpecParSections, nodePath, "meas_value_name_" + name);
+ measParamValues[name] =
+ getAllParameterValuesFromSpecParSections(allSpecParSections, nodePath, "meas_value_" + name);
+ measParamSigmas[name] =
+ getAllParameterValuesFromSpecParSections(allSpecParSections, nodePath, "meas_sigma_" + name);
+ measIsSimulatedValue[name] = getAllParameterValuesFromSpecParSections(
+ allSpecParSections, nodePath, "meas_is_simulated_value_" + name);
+ }
+
+ if (ALIUtils::debug >= 4) {
+ edm::LogInfo("Alignment") << " CocoaAnalyzer::ReadXML: Fill measurements with read parameters ";
+ }
+
+ if (measNames.size() == measTypes.size()) {
+ for (size_t i = 0; i < measNames.size(); ++i) {
+ oaMeas.ID_ = i;
+ oaMeas.name_ = measNames[i];
+ oaMeas.type_ = measTypes[i];
+ oaMeas.measObjectNames_ = measObjectNames[oaMeas.name_];
+ if (measParamNames.size() == measParamValues.size() && measParamValues.size() == measParamSigmas.size()) {
+ for (size_t i2 = 0; i2 < measParamNames[oaMeas.name_].size(); i2++) {
+ oaParam.name_ = measParamNames[oaMeas.name_][i2];
+ oaParam.value_ = measParamValues[oaMeas.name_][i2];
+ oaParam.error_ = measParamSigmas[oaMeas.name_][i2];
+ oaParam.quality_ = 2;
+ if (oaMeas.type_ == "SENSOR2D" || oaMeas.type_ == "COPS" || oaMeas.type_ == "DISTANCEMETER" ||
+ oaMeas.type_ == "DISTANCEMETER!DIM" || oaMeas.type_ == "DISTANCEMETER3DIM") {
+ oaParam.dim_type_ = "length";
+ } else if (oaMeas.type_ == "TILTMETER") {
+ oaParam.dim_type_ = "angle";
+ } else {
+ edm::LogError("Alignment") << "CocoaAnalyzer::readXMLFile. Invalid measurement type: " << oaMeas.type_;
+ }
+
+ oaMeas.values_.emplace_back(oaParam);
+ oaMeas.isSimulatedValue_.emplace_back(measIsSimulatedValue[oaMeas.name_][i2]);
+ if (ALIUtils::debug >= 5) {
+ edm::LogInfo("Alignment") << oaMeas.name_ << " copying issimu "
+ << oaMeas.isSimulatedValue_[oaMeas.isSimulatedValue_.size() - 1] << " = "
+ << measIsSimulatedValue[oaMeas.name_][i2];
+ }
+ oaParam.clear();
+ }
+ } else {
+ if (ALIUtils::debug >= 2) {
+ edm::LogWarning("Alignment") << "WARNING FOR NOW: sizes of measurement parameters (name, value, sigma) do"
+ << " not match! for measurement " << oaMeas.name_
+ << " !Did not fill parameters for this measurement ";
+ }
+ }
+ measList_.oaMeasurements_.emplace_back(oaMeas);
+ if (ALIUtils::debug >= 5) {
+ edm::LogInfo("Alignment") << "CocoaAnalyser: MEASUREMENT " << oaMeas.name_ << " extra entries read "
+ << oaMeas;
+ }
+ oaMeas.clear();
+ }
+
+ } else {
+ if (ALIUtils::debug >= 2) {
+ edm::LogWarning("Alignment") << "WARNING FOR NOW: sizes of measurements (names, types do"
+ << " not match! Did not add " << nObjects << " item to XXXMeasurements";
+ }
+ }
+
+ oaInfo.clear();
+ doCOCOA = myFilteredView.firstChild();
+ } // while (doCOCOA)
+
+ if (ALIUtils::debug >= 3) {
+ edm::LogInfo("Alignment") << "CocoaAnalyzer::ReadXML: Finished building " << nObjects + 1
+ << " OpticalAlignInfo objects"
+ << " and " << measList_.oaMeasurements_.size()
+ << " OpticalAlignMeasurementInfo objects ";
+ }
+ if (ALIUtils::debug >= 5) {
+ edm::LogInfo("Alignment") << " @@@@@@ OpticalAlignments " << oaList_;
+ edm::LogInfo("Alignment") << " @@@@@@ OpticalMeasurements " << measList_;
+ }
+ }
+}
+
+/*
+ * This is used to get the OpticalAlignInfo from DB,
+ * which can be used to correct the OpticalAlignInfo from IdealGeometry.
+ */
+std::vector CocoaAnalyzer::readCalibrationDB(const edm::EventSetup& evts) {
+ if (ALIUtils::debug >= 3) {
+ edm::LogInfo("Alignment") << "$$$ CocoaAnalyzer::readCalibrationDB: ";
+ }
+
+ using namespace edm::eventsetup;
+ edm::ESHandle pObjs;
+ evts.get().get(pObjs);
+ const std::vector& infoFromDB = pObjs.product()->opticalAlignments_;
+
+ if (ALIUtils::debug >= 5) {
+ edm::LogInfo("Alignment") << "CocoaAnalyzer::readCalibrationDB: Number of OpticalAlignInfo READ "
+ << infoFromDB.size();
+ for (const auto& myInfoFromDB : infoFromDB) {
+ edm::LogInfo("Alignment") << "CocoaAnalyzer::readCalibrationDB: OpticalAlignInfo READ " << myInfoFromDB;
+ }
+ }
+
+ return infoFromDB;
+}
+
+/*
+ * Correct all OpticalAlignInfo from IdealGeometry with values from DB.
+ */
+void CocoaAnalyzer::correctAllOpticalAlignments(std::vector& allDBOpticalAlignments) {
+ if (ALIUtils::debug >= 3) {
+ edm::LogInfo("Alignment") << "$$$ CocoaAnalyzer::correctAllOpticalAlignments: ";
+ }
+
+ for (const auto& myDBInfo : allDBOpticalAlignments) {
+ if (ALIUtils::debug >= 5) {
+ edm::LogInfo("Alignment") << "CocoaAnalyzer::findOpticalAlignInfoXML: Looking for OAI " << myDBInfo.name_;
+ }
+
+ std::vector& allXMLOpticalAlignments = oaList_.opticalAlignments_;
+ const auto& myXMLInfo = std::find_if(
+ allXMLOpticalAlignments.begin(), allXMLOpticalAlignments.end(), [&](const auto& myXMLInfoCandidate) {
+ return myXMLInfoCandidate.name_ == myDBInfo.name_;
+ });
+
+ if (myXMLInfo != allXMLOpticalAlignments.end()) {
+ if (ALIUtils::debug >= 4) {
+ edm::LogInfo("Alignment") << "CocoaAnalyzer::findOpticalAlignInfoXML: OAI found " << myXMLInfo->name_;
+ edm::LogInfo("Alignment")
+ << "CocoaAnalyzer::correctAllOpticalAlignments: correcting data from XML with DB info.";
+ }
+ correctOpticalAlignmentParameter(myXMLInfo->x_, myDBInfo.x_);
+ correctOpticalAlignmentParameter(myXMLInfo->y_, myDBInfo.y_);
+ correctOpticalAlignmentParameter(myXMLInfo->z_, myDBInfo.z_);
+ correctOpticalAlignmentParameter(myXMLInfo->angx_, myDBInfo.angx_);
+ correctOpticalAlignmentParameter(myXMLInfo->angy_, myDBInfo.angy_);
+ correctOpticalAlignmentParameter(myXMLInfo->angz_, myDBInfo.angz_);
+
+ // Also correct extra entries
+ const std::vector& allDBExtraEntries = myDBInfo.extraEntries_;
+ std::vector& allXMLExtraEntries = myXMLInfo->extraEntries_;
+ for (const auto& myDBExtraEntry : allDBExtraEntries) {
+ const auto& myXMLExtraEntry = std::find_if(
+ allXMLExtraEntries.begin(), allXMLExtraEntries.end(), [&](const auto& myXMLExtraEntryCandidate) {
+ return myXMLExtraEntryCandidate.name_ == myDBExtraEntry.name_;
+ });
+
+ if (myXMLExtraEntry != allXMLExtraEntries.end()) {
+ correctOpticalAlignmentParameter(*myXMLExtraEntry, myDBExtraEntry);
+ } else {
+ if (myDBExtraEntry.name_ != "None") {
+ if (ALIUtils::debug >= 2) {
+ edm::LogError("Alignment")
+ << "CocoaAnalyzer::correctAllOpticalAlignments: extra entry read from DB is not present in XML "
+ << myDBExtraEntry << " in object " << myDBInfo;
+ }
+ }
+ }
+ }
+
+ if (ALIUtils::debug >= 5) {
+ edm::LogInfo("Alignment") << "CocoaAnalyzer::correctAllOpticalAlignments: corrected OpticalAlingInfo "
+ << oaList_;
+ }
+ } else {
+ if (ALIUtils::debug >= 2) {
+ edm::LogError("Alignment") << "CocoaAnalyzer::correctAllOpticalAlignments: OpticalAlignInfo read from DB "
+ << myDBInfo << " is not present in XML.";
+ }
+ }
+ }
+}
+
+/*
+ * Correct an OpticalAlignment parameter from IdealGeometry with the value from DB.
+ */
+void CocoaAnalyzer::correctOpticalAlignmentParameter(OpticalAlignParam& myXMLParam,
+ const OpticalAlignParam& myDBParam) {
+ if (myDBParam.value_ != -9.999E9) {
+ const std::string& type = myDBParam.dimType();
+ double dimFactor = 1.;
+
+ if (type == "centre" || type == "length") {
+ dimFactor = 1. / 1._m; // in DB it is in cm
+ } else if (type == "angles" || type == "angle" || type == "nodim") {
+ dimFactor = 1.;
+ } else {
+ edm::LogError("Alignment") << "Incorrect OpticalAlignParam type = " << type;
+ }
+
+ const double correctedValue = myDBParam.value_ * dimFactor;
+ if (ALIUtils::debug >= 4) {
+ edm::LogInfo("Alignment") << "CocoaAnalyzer::correctOpticalAlignmentParameter old value= " << myXMLParam.value_
+ << " new value= " << correctedValue;
+ }
+ myXMLParam.value_ = correctedValue;
+ }
+}
+
+/*
+ * Collect all information, do the fitting, and store results in DB.
+ */
+void CocoaAnalyzer::runCocoa() {
+ if (ALIUtils::debug >= 3) {
+ edm::LogInfo("Alignment") << "$$$ CocoaAnalyzer::runCocoa: ";
+ }
+
+ // Geometry model built from XML file (corrected with values from DB)
+ Model& model = Model::getInstance();
+ model.BuildSystemDescriptionFromOA(oaList_);
+
+ if (ALIUtils::debug >= 3) {
+ edm::LogInfo("Alignment") << "$$ CocoaAnalyzer::runCocoa: geometry built ";
+ }
+
+ // Build measurements
+ model.BuildMeasurementsFromOA(measList_);
+
+ if (ALIUtils::debug >= 3) {
+ edm::LogInfo("Alignment") << "$$ CocoaAnalyzer::runCocoa: measurements built ";
+ }
+
+ // Do fit and store results in DB
+ Fit::getInstance();
+ Fit::startFit();
+
+ if (ALIUtils::debug >= 0)
+ edm::LogInfo("Alignment") << "............ program ended OK";
+ if (ALIUtils::report >= 1) {
+ ALIFileOut& fileout = ALIFileOut::getInstance(Model::ReportFName());
+ fileout << "............ program ended OK";
+ }
+}
+
+/* Helper: For a given node, get the values associated to a given parameter, from the XMLs SpecPar sections.
+ * NB: The same parameter can appear several times WITHIN the same SpecPar section (hence, we have a std::vector).
+ * WARNING: This stops at the first relevant SpecPar section encountered.
+ * Hence, if A GIVEN NODE HAS SEVERAL SPECPAR XML SECTIONS RE-DEFINING THE SAME PARAMETER,
+ * only the first XML SpecPar block will be considered.
+ */
+template
+std::vector CocoaAnalyzer::getAllParameterValuesFromSpecParSections(const cms::DDSpecParRegistry& allSpecParSections,
+ const std::string& nodePath,
+ const std::string& parameterName) {
+ cms::DDSpecParRefs filteredSpecParSections;
+ allSpecParSections.filter(filteredSpecParSections, parameterName);
+ for (const auto& mySpecParSection : filteredSpecParSections) {
+ if (mySpecParSection->hasPath(nodePath)) {
+ return mySpecParSection->value>(parameterName);
+ }
+ }
+
+ return std::vector();
+}
+
+/* Helper: For a given node, get the value associated to a given parameter, from the XMLs SpecPar sections.
+ * This is the parameterValueIndex-th value (within a XML SpecPar block.) of the desired parameter.
+ */
+template
+T CocoaAnalyzer::getParameterValueFromSpecParSections(const cms::DDSpecParRegistry& allSpecParSections,
+ const std::string& nodePath,
+ const std::string& parameterName,
+ const unsigned int parameterValueIndex) {
+ const std::vector& allParameterValues =
+ getAllParameterValuesFromSpecParSections(allSpecParSections, nodePath, parameterName);
+ if (parameterValueIndex < allParameterValues.size()) {
+ return allParameterValues.at(parameterValueIndex);
+ }
+ return T();
+}
diff --git a/Alignment/CocoaApplication/src/SealModule.cc b/Alignment/CocoaApplication/src/SealModule.cc
new file mode 100644
index 0000000000000..6fabe6d7c6341
--- /dev/null
+++ b/Alignment/CocoaApplication/src/SealModule.cc
@@ -0,0 +1,4 @@
+#include "FWCore/Framework/interface/MakerMacros.h"
+#include "Alignment/CocoaApplication/interface/CocoaAnalyzer.h"
+
+DEFINE_FWK_MODULE(CocoaAnalyzer);
diff --git a/Alignment/CocoaApplication/test/OpticalAlignments.db b/Alignment/CocoaApplication/test/OpticalAlignments.db
index b460a70969f7b..50944ced13d43 100644
Binary files a/Alignment/CocoaApplication/test/OpticalAlignments.db and b/Alignment/CocoaApplication/test/OpticalAlignments.db differ
diff --git a/Alignment/CocoaApplication/test/cmsCocoaTable2DWithMirror.xml b/Alignment/CocoaApplication/test/cmsCocoaTable2DWithMirror.xml
new file mode 100644
index 0000000000000..6950b6b7f8b66
--- /dev/null
+++ b/Alignment/CocoaApplication/test/cmsCocoaTable2DWithMirror.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Alignment/CocoaApplication/test/cocoaAnalyzer_cfg.py b/Alignment/CocoaApplication/test/cocoaAnalyzer_cfg.py
new file mode 100644
index 0000000000000..021816597169b
--- /dev/null
+++ b/Alignment/CocoaApplication/test/cocoaAnalyzer_cfg.py
@@ -0,0 +1,84 @@
+import FWCore.ParameterSet.Config as cms
+
+process = cms.Process("TestCocoa")
+
+process.load("FWCore.MessageService.MessageLogger_cfi")
+process.MessageLogger.debugModules = cms.untracked.vstring('cocoa')
+process.MessageLogger.cout = cms.untracked.PSet(
+ threshold = cms.untracked.string('DEBUG')
+)
+
+process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(1) )
+
+# A data source must always be defined. We don't need it, so here's a dummy one.
+process.source = cms.Source("EmptyIOVSource",
+ timetype = cms.string('runnumber'),
+ firstValue = cms.uint64(1),
+ lastValue = cms.uint64(1),
+ interval = cms.uint64(1)
+)
+
+
+# dd4hep-based geometry
+process.DDDetectorESProducer = cms.ESSource("DDDetectorESProducer",
+ confGeomXMLFiles = cms.FileInPath('Alignment/CocoaApplication/test/cmsCocoaTable2DWithMirror.xml'),
+ appendToDataLabel = cms.string('')
+ )
+
+process.DDCompactViewESProducer = cms.ESProducer("DDCompactViewESProducer",
+ appendToDataLabel = cms.string('')
+ )
+
+
+process.load("CondCore.CondDB.CondDB_cfi")
+process.CondDB.connect = 'sqlite_file:OpticalAlignments.db'
+
+
+# Read DB: this is used to correct internal geometry with geo from DB.
+process.PoolDBESSource = cms.ESSource("PoolDBESSource",
+ process.CondDB,
+ DumpStat=cms.untracked.bool(True),
+ toGet = cms.VPSet(cms.PSet(
+ record = cms.string('OpticalAlignmentsRcd'),
+ tag = cms.string("OpticalAlignmentsRcdInput")
+ )),
+)
+
+
+# Write COCOA output to DB ('Output tag')
+process.PoolDBOutputService = cms.Service("PoolDBOutputService",
+ process.CondDB,
+ timetype = cms.untracked.string('runnumber'),
+ toPut = cms.VPSet(
+ cms.PSet(
+ record = cms.string('OpticalAlignmentsRcd'),
+ tag = cms.string('OpticalAlignmentsRcdOutput')
+ ),
+ cms.PSet(
+ record = cms.string('DTAlignmentRcd'),
+ tag = cms.string('DTAlignmentRcdOutput')
+ ),
+ cms.PSet(
+ record = cms.string('DTAlignmentErrorExtendedRcd'),
+ tag = cms.string('DTAlignmentErrorExtendedRcdOutput')
+ ),
+ cms.PSet(
+ record = cms.string('CSCAlignmentRcd'),
+ tag = cms.string('CSCAlignmentRcdOutput')
+ ),
+ cms.PSet(
+ record = cms.string('CSCAlignmentErrorExtendedRcd'),
+ tag = cms.string('CSCAlignmentErrorExtendedRcdOutput')
+ ),
+ )
+)
+
+
+# Run COCOA
+process.cocoa = cms.EDAnalyzer('CocoaAnalyzer',
+ maxEvents = cms.int32(1),
+ cocoaDaqRootFile = cms.string("cocoaDaqTest.root")
+ )
+
+process.p = cms.Path(process.cocoa)
+
diff --git a/Alignment/CocoaApplication/test/table2DWithMirror.xml b/Alignment/CocoaApplication/test/table2DWithMirror.xml
index db979e6a6a681..69376dff18d3f 100644
--- a/Alignment/CocoaApplication/test/table2DWithMirror.xml
+++ b/Alignment/CocoaApplication/test/table2DWithMirror.xml
@@ -1,303 +1,312 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Alignment/CocoaFit/src/CocoaDBMgr.cc b/Alignment/CocoaFit/src/CocoaDBMgr.cc
index 12f00903d6182..3b54402d34106 100644
--- a/Alignment/CocoaFit/src/CocoaDBMgr.cc
+++ b/Alignment/CocoaFit/src/CocoaDBMgr.cc
@@ -3,6 +3,7 @@
#include "CondFormats/Alignment/interface/AlignTransform.h"
#include "CondFormats/Alignment/interface/AlignTransformErrorExtended.h"
#include "DataFormats/GeometryCommonDetAlgo/interface/GlobalError.h"
+#include "DataFormats/Math/interface/CMSUnits.h"
#include "FWCore/ServiceRegistry/interface/Service.h"
#include "CondCore/DBOutputService/interface/PoolDBOutputService.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
@@ -31,6 +32,8 @@
#include "CondCore/CondDB/interface/Serialization.h"
+using namespace cms_units::operators;
+
CocoaDBMgr* CocoaDBMgr::instance = nullptr;
//----------------------------------------------------------------------
@@ -165,7 +168,7 @@ bool CocoaDBMgr::DumpCocoaResults() {
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
OpticalAlignInfo CocoaDBMgr::GetOptAlignInfoFromOptO(OpticalObject* opto) {
- std::cout << " CocoaDBMgr::GetOptAlignInfoFromOptO " << opto->name() << std::endl;
+ LogDebug("Alignment") << " CocoaDBMgr::GetOptAlignInfoFromOptO " << opto->name();
OpticalAlignInfo data;
data.ID_ = opto->getCmsswID();
data.type_ = opto->type();
@@ -177,48 +180,80 @@ OpticalAlignInfo CocoaDBMgr::GetOptAlignInfoFromOptO(OpticalObject* opto) {
centreLocal = parentRmGlobInv * centreLocal;
const std::vector& theCoordinateEntryVector = opto->CoordinateEntryList();
- std::cout << " CocoaDBMgr::GetOptAlignInfoFromOptO starting coord " << std::endl;
-
- data.x_.value_ = centreLocal.x() / 100.; // in cm
- std::cout << " matrix " << Fit::GetAtWAMatrix() << std::endl;
- std::cout << " matrix " << Fit::GetAtWAMatrix()->Mat() << " " << theCoordinateEntryVector[0]->fitPos() << std::endl;
- data.x_.error_ = GetEntryError(theCoordinateEntryVector[0]) / 100.; // in cm
-
- data.y_.value_ = centreLocal.y() / 100.; // in cm
- std::cout << " matrix " << Fit::GetAtWAMatrix()->Mat() << " " << theCoordinateEntryVector[1]->fitPos() << std::endl;
- data.y_.error_ = GetEntryError(theCoordinateEntryVector[1]) / 100.; // in cm
-
- data.z_.value_ = centreLocal.z() / 100.; // in cm
- std::cout << " matrix " << Fit::GetAtWAMatrix()->Mat() << " " << theCoordinateEntryVector[2]->fitPos() << std::endl;
- data.z_.error_ = GetEntryError(theCoordinateEntryVector[2]) / 100.; // in cm
-
- //----- angles in local coordinates
- std::vector anglocal = opto->getLocalRotationAngles(theCoordinateEntryVector);
-
- data.angx_.value_ = anglocal[0] * 180. / M_PI; // in deg
- std::cout << " matrix " << Fit::GetAtWAMatrix()->Mat() << theCoordinateEntryVector[3]->fitPos() << std::endl;
- data.angx_.error_ = GetEntryError(theCoordinateEntryVector[3]) * 180. / M_PI; // in deg;
-
- data.angy_.value_ = anglocal[1] * 180. / M_PI; // in deg
- std::cout << " matrix " << Fit::GetAtWAMatrix()->Mat() << theCoordinateEntryVector[4]->fitPos() << std::endl;
- data.angy_.error_ = GetEntryError(theCoordinateEntryVector[4]) * 180. / M_PI; // in deg;;
-
- data.angz_.value_ = anglocal[2] * 180. / M_PI; // in deg
- std::cout << " matrix " << Fit::GetAtWAMatrix()->Mat() << theCoordinateEntryVector[5]->fitPos() << std::endl;
- data.angz_.error_ = GetEntryError(theCoordinateEntryVector[5]) * 180. / M_PI; // in deg;
+ LogDebug("Alignment") << " CocoaDBMgr::GetOptAlignInfoFromOptO starting coord ";
+ if (theCoordinateEntryVector.size() == 6) {
+ const Entry* const translationX = theCoordinateEntryVector.at(0);
+ OpticalAlignParam translationXDataForDB;
+ translationXDataForDB.name_ = translationX->name();
+ translationXDataForDB.dim_type_ = translationX->type();
+ translationXDataForDB.value_ = centreLocal.x() * 1._m; // m in COCOA, cm in DB
+ translationXDataForDB.error_ = GetEntryError(translationX) * 1._m; // m in COCOA, cm in DB
+ translationXDataForDB.quality_ = translationX->quality();
+ data.x_ = translationXDataForDB;
+
+ const Entry* const translationY = theCoordinateEntryVector.at(1);
+ OpticalAlignParam translationYDataForDB;
+ translationYDataForDB.name_ = translationY->name();
+ translationYDataForDB.dim_type_ = translationY->type();
+ translationYDataForDB.value_ = centreLocal.y() * 1._m; // m in COCOA, cm in DB
+ translationYDataForDB.error_ = GetEntryError(translationY) * 1._m; // m in COCOA, cm in DB
+ translationYDataForDB.quality_ = translationY->quality();
+ data.y_ = translationYDataForDB;
+
+ const Entry* const translationZ = theCoordinateEntryVector.at(2);
+ OpticalAlignParam translationZDataForDB;
+ translationZDataForDB.name_ = translationZ->name();
+ translationZDataForDB.dim_type_ = translationZ->type();
+ translationZDataForDB.value_ = centreLocal.z() * 1._m; // m in COCOA, cm in DB
+ translationZDataForDB.error_ = GetEntryError(translationZ) * 1._m; // m in COCOA, cm in DB
+ translationZDataForDB.quality_ = translationZ->quality();
+ data.z_ = translationZDataForDB;
+
+ //----- angles in local coordinates
+ std::vector anglocal = opto->getLocalRotationAngles(theCoordinateEntryVector);
+ if (anglocal.size() == 3) {
+ const Entry* const rotationX = theCoordinateEntryVector.at(3);
+ OpticalAlignParam rotationXDataForDB;
+ rotationXDataForDB.name_ = rotationX->name();
+ rotationXDataForDB.dim_type_ = rotationX->type();
+ rotationXDataForDB.value_ = anglocal.at(0);
+ rotationXDataForDB.error_ = GetEntryError(rotationX);
+ rotationXDataForDB.quality_ = rotationX->quality();
+ data.angx_ = rotationXDataForDB;
+
+ const Entry* const rotationY = theCoordinateEntryVector.at(4);
+ OpticalAlignParam rotationYDataForDB;
+ rotationYDataForDB.name_ = rotationY->name();
+ rotationYDataForDB.dim_type_ = rotationY->type();
+ rotationYDataForDB.value_ = anglocal.at(1);
+ rotationYDataForDB.error_ = GetEntryError(rotationY);
+ rotationYDataForDB.quality_ = rotationY->quality();
+ data.angy_ = rotationYDataForDB;
+
+ const Entry* const rotationZ = theCoordinateEntryVector.at(5);
+ OpticalAlignParam rotationZDataForDB;
+ rotationZDataForDB.name_ = rotationZ->name();
+ rotationZDataForDB.dim_type_ = rotationZ->type();
+ rotationZDataForDB.value_ = anglocal.at(2);
+ rotationZDataForDB.error_ = GetEntryError(rotationZ);
+ rotationZDataForDB.quality_ = rotationZ->quality();
+ data.angz_ = rotationZDataForDB;
+ }
+ }
- const std::vector& theExtraEntryVector = opto->ExtraEntryList();
std::cout << " CocoaDBMgr::GetOptAlignInfoFromOptO starting entry " << std::endl;
-
- std::vector::const_iterator ite;
- for (ite = theExtraEntryVector.begin(); ite != theExtraEntryVector.end(); ++ite) {
+ for (const auto& myDBExtraEntry : opto->ExtraEntryList()) {
OpticalAlignParam extraEntry;
- extraEntry.name_ = (*ite)->name();
- extraEntry.dim_type_ = (*ite)->type();
- extraEntry.value_ = (*ite)->value();
- extraEntry.error_ = (*ite)->sigma();
- extraEntry.quality_ = (*ite)->quality();
- data.extraEntries_.push_back(extraEntry);
+ extraEntry.name_ = myDBExtraEntry->name();
+ extraEntry.dim_type_ = myDBExtraEntry->type();
+ extraEntry.value_ = myDBExtraEntry->value();
+ extraEntry.error_ = myDBExtraEntry->sigma();
+ if (extraEntry.dim_type_ == "centre" || extraEntry.dim_type_ == "length") {
+ extraEntry.value_ *= 1._m; // m in COCOA, cm in DB
+ extraEntry.error_ *= 1._m; // m in COCOA, cm in DB
+ }
+ extraEntry.quality_ = myDBExtraEntry->quality();
+ data.extraEntries_.emplace_back(extraEntry);
std::cout << " CocoaDBMgr::GetOptAlignInfoFromOptO done extra entry " << extraEntry.name_ << std::endl;
}
@@ -330,12 +365,12 @@ AlignTransformErrorExtended* CocoaDBMgr::GetAlignInfoErrorFromOptO(OpticalObject
CLHEP::HepMatrix errm(3, 3);
const std::vector& theCoordinateEntryVector = opto->CoordinateEntryList();
std::cout << "@@@ CocoaDBMgr::GetAlignInfoFromOptOfill errm " << opto->name() << std::endl;
- errm(0, 0) = GetEntryError(theCoordinateEntryVector[0]) / 100.; // in cm
- errm(1, 1) = GetEntryError(theCoordinateEntryVector[1]) / 100.; // in cm
- errm(2, 2) = GetEntryError(theCoordinateEntryVector[2]) / 100.; // in cm
- errm(0, 1) = GetEntryError(theCoordinateEntryVector[0], theCoordinateEntryVector[1]) / 100.; // in cm
- errm(0, 2) = GetEntryError(theCoordinateEntryVector[0], theCoordinateEntryVector[2]) / 100.; // in cm
- errm(1, 2) = GetEntryError(theCoordinateEntryVector[1], theCoordinateEntryVector[2]) / 100.; // in cm
+ errm(0, 0) = GetEntryError(theCoordinateEntryVector[0]) * 1._m; // m in COCOA, cm in DB
+ errm(1, 1) = GetEntryError(theCoordinateEntryVector[1]) * 1._m; // m in COCOA, cm in DB
+ errm(2, 2) = GetEntryError(theCoordinateEntryVector[2]) * 1._m; // m in COCOA, cm in DB
+ errm(0, 1) = GetEntryError(theCoordinateEntryVector[0], theCoordinateEntryVector[1]) * 1._m; // m in COCOA, cm in DB
+ errm(0, 2) = GetEntryError(theCoordinateEntryVector[0], theCoordinateEntryVector[2]) * 1._m; // m in COCOA, cm in DB
+ errm(1, 2) = GetEntryError(theCoordinateEntryVector[1], theCoordinateEntryVector[2]) * 1._m; // m in COCOA, cm in DB
// errm(1,0) = errm(0,1);
// errm(2,0) = errm(0,2);
// errm(2,1) = errm(1,2);
diff --git a/Alignment/CocoaUtilities/interface/ALIUtils.h b/Alignment/CocoaUtilities/interface/ALIUtils.h
index 965729b7cab66..5772049595d4b 100644
--- a/Alignment/CocoaUtilities/interface/ALIUtils.h
+++ b/Alignment/CocoaUtilities/interface/ALIUtils.h
@@ -89,7 +89,7 @@ class ALIUtils {
static ALIdouble getMaximumDeviationDerivative() { return maximum_deviation_derivative; }
static void setMaximumDeviationDerivative(ALIdouble val) { maximum_deviation_derivative = val; }
- static std::vector getRotationAnglesFromMatrix(CLHEP::HepRotation& rmLocal,
+ static std::vector getRotationAnglesFromMatrix(const CLHEP::HepRotation& rmLocal,
double origAngleX,
double origAngleY,
double origAngleZ);
@@ -97,7 +97,7 @@ class ALIUtils {
static bool eq2ang(double ang1, double ang2);
static double approxTo0(double val);
static double addPii(double val);
- static int checkMatrixEquations(double angleX, double angleY, double angleZ, CLHEP::HepRotation* rot);
+ static int checkMatrixEquations(double angleX, double angleY, double angleZ, const CLHEP::HepRotation& rot);
private:
static ALIdouble _LengthValueDimensionFactor;
diff --git a/Alignment/CocoaUtilities/src/ALIUtils.cc b/Alignment/CocoaUtilities/src/ALIUtils.cc
index ca34c6e25ddb8..d0c03f1cdfc42 100644
--- a/Alignment/CocoaUtilities/src/ALIUtils.cc
+++ b/Alignment/CocoaUtilities/src/ALIUtils.cc
@@ -12,7 +12,7 @@
#include
#include
-ALIint ALIUtils::debug = -1;
+ALIint ALIUtils::debug = 99;
ALIint ALIUtils::report = 1;
ALIdouble ALIUtils::_LengthValueDimensionFactor = 1.;
ALIdouble ALIUtils::_LengthSigmaDimensionFactor = 1.;
@@ -546,7 +546,7 @@ std::string ALIUtils::changeName(const std::string& oldName, const std::string&
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-std::vector ALIUtils::getRotationAnglesFromMatrix(CLHEP::HepRotation& rmLocal,
+std::vector ALIUtils::getRotationAnglesFromMatrix(const CLHEP::HepRotation& rmLocal,
double origAngleX,
double origAngleY,
double origAngleZ) {
@@ -691,7 +691,7 @@ std::vector ALIUtils::getRotationAnglesFromMatrix(CLHEP::HepRotation& rm
}
// double rotnewyx = cos( newang[1] ) * sin( newang[2] );
- if (checkMatrixEquations(newang[0], newang[1], newang[2], &rmLocal) != 0) {
+ if (checkMatrixEquations(newang[0], newang[1], newang[2], rmLocal) != 0) {
std::cerr << " wrong rotation matrix " << newang[0] << " " << newang[1] << " " << newang[2] << std::endl;
ALIUtils::dumprm(rmLocal, " matrix is ");
}
@@ -759,14 +759,7 @@ double ALIUtils::addPii(double val) {
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-int ALIUtils::checkMatrixEquations(double angleX, double angleY, double angleZ, CLHEP::HepRotation* rot) {
- //- std::cout << " cme " << angleX << " " << angleY << " " << angleZ << std::endl;
- if (rot == nullptr) {
- rot = new CLHEP::HepRotation();
- rot->rotateX(angleX);
- rot->rotateY(angleY);
- rot->rotateZ(angleZ);
- }
+int ALIUtils::checkMatrixEquations(double angleX, double angleY, double angleZ, const CLHEP::HepRotation& rot) {
double sx = sin(angleX);
double cx = cos(angleX);
double sy = sin(angleY);
@@ -785,43 +778,11 @@ int ALIUtils::checkMatrixEquations(double angleX, double angleY, double angleZ,
double rotzz = cx * cy;
int matrixElemBad = 0;
- if (!eq2ang(rot->xx(), rotxx)) {
- std::cerr << " EQUATION for xx() IS BAD " << rot->xx() << " <> " << rotxx << std::endl;
- matrixElemBad++;
- }
- if (!eq2ang(rot->xy(), rotxy)) {
- std::cerr << " EQUATION for xy() IS BAD " << rot->xy() << " <> " << rotxy << std::endl;
- matrixElemBad++;
- }
- if (!eq2ang(rot->xz(), rotxz)) {
- std::cerr << " EQUATION for xz() IS BAD " << rot->xz() << " <> " << rotxz << std::endl;
- matrixElemBad++;
- }
- if (!eq2ang(rot->yx(), rotyx)) {
- std::cerr << " EQUATION for yx() IS BAD " << rot->yx() << " <> " << rotyx << std::endl;
- matrixElemBad++;
- }
- if (!eq2ang(rot->yy(), rotyy)) {
- std::cerr << " EQUATION for yy() IS BAD " << rot->yy() << " <> " << rotyy << std::endl;
- matrixElemBad++;
- }
- if (!eq2ang(rot->yz(), rotyz)) {
- std::cerr << " EQUATION for yz() IS BAD " << rot->yz() << " <> " << rotyz << std::endl;
- matrixElemBad++;
- }
- if (!eq2ang(rot->zx(), rotzx)) {
- std::cerr << " EQUATION for zx() IS BAD " << rot->zx() << " <> " << rotzx << std::endl;
- matrixElemBad++;
- }
- if (!eq2ang(rot->zy(), rotzy)) {
- std::cerr << " EQUATION for zy() IS BAD " << rot->zy() << " <> " << rotzy << std::endl;
- matrixElemBad++;
- }
- if (!eq2ang(rot->zz(), rotzz)) {
- std::cerr << " EQUATION for zz() IS BAD " << rot->zz() << " <> " << rotzz << std::endl;
+ if (!eq2ang(rot.xx(), rotxx) || !eq2ang(rot.xy(), rotxy) || !eq2ang(rot.xz(), rotxz) || !eq2ang(rot.yx(), rotyx) ||
+ !eq2ang(rot.yy(), rotyy) || !eq2ang(rot.yz(), rotyz) || !eq2ang(rot.zx(), rotzx) || !eq2ang(rot.zy(), rotzy) ||
+ !eq2ang(rot.zz(), rotzz)) {
matrixElemBad++;
}
- //- std::cout << " cme: matrixElemBad " << matrixElemBad << std::endl;
return matrixElemBad;
}
diff --git a/Alignment/CocoaUtilities/src/GlobalOptionMgr.cc b/Alignment/CocoaUtilities/src/GlobalOptionMgr.cc
index 2fff48aae433b..f10a1fc155dff 100644
--- a/Alignment/CocoaUtilities/src/GlobalOptionMgr.cc
+++ b/Alignment/CocoaUtilities/src/GlobalOptionMgr.cc
@@ -79,7 +79,7 @@ void GlobalOptionMgr::setDefaultGlobalOptions() {
theGlobalOptions[ALIstring("stopAfter1stIteration")] = 0;
theGlobalOptions[ALIstring("calParamInyfMatrix")] = 0;
- theGlobalOptions[ALIstring("writeXML")] = 0;
+ theGlobalOptions[ALIstring("writeXML")] = 1;
theGlobalOptions[ALIstring("dumpInAllFrames")] = 0;
theGlobalOptions[ALIstring("rootResults")] = 0;
theGlobalOptions[ALIstring("writeDBAlign")] = 0;