CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Alignment/CommonAlignmentAlgorithm/plugins/SiStripBackplaneCalibration.cc

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 //  reference - but the strip local reco foresees also calibration parameters
00008 //  for peak data like for the Lorentz angle.
00015 
00016 #include "Alignment/CommonAlignmentAlgorithm/interface/IntegratedCalibrationBase.h"
00017 #include "Alignment/CommonAlignmentAlgorithm/interface/TkModuleGroupSelector.h"
00018 // include 'locally':
00019 #include "SiStripReadoutModeEnums.h"
00020 #include "TreeStruct.h"
00021 
00022 #include "CondCore/DBOutputService/interface/PoolDBOutputService.h"
00023 #include "CondFormats/DataRecord/interface/SiStripCondDataRecords.h"
00024 #include "CondFormats/SiStripObjects/interface/SiStripLatency.h"
00025 #include "CondFormats/SiStripObjects/interface/SiStripLorentzAngle.h"
00026 // #include "CalibTracker/Records/interface/SiStripDependentRecords.h"
00027 #include "CondFormats/SiStripObjects/interface/SiStripBackPlaneCorrection.h"
00028 
00029 #include "DataFormats/DetId/interface/DetId.h"
00030 #include "DataFormats/SiStripDetId/interface/SiStripDetId.h"
00031 
00032 #include "FWCore/Framework/interface/ESHandle.h"
00033 #include "FWCore/Framework/interface/ESWatcher.h"
00034 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00035 #include "FWCore/ServiceRegistry/interface/Service.h"
00036 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00037 
00038 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00039 #include "MagneticField/Engine/interface/MagneticField.h"
00040 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00041 #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHit.h"
00042 
00043 #include "TTree.h"
00044 #include "TFile.h"
00045 #include "TString.h"
00046 
00047 // #include <iostream>
00048 #include <boost/assign/list_of.hpp>
00049 #include <vector>
00050 #include <map>
00051 #include <sstream>
00052 #include <cstdio>
00053 #include <functional>
00054 
00055 class SiStripBackplaneCalibration : public IntegratedCalibrationBase
00056 {
00057 public:
00059   explicit SiStripBackplaneCalibration(const edm::ParameterSet &cfg);
00060   
00062   virtual ~SiStripBackplaneCalibration();
00063 
00065   virtual unsigned int numParameters() const;
00066 
00067   // /// Return all derivatives,
00068   // /// default implementation uses other derivatives(..) method,
00069   // /// but can be overwritten in derived class for efficiency.
00070   // virtual std::vector<double> derivatives(const TransientTrackingRecHit &hit,
00071   //                                      const TrajectoryStateOnSurface &tsos,
00072   //                                      const edm::EventSetup &setup,
00073   //                                      const EventInfo &eventInfo) const;
00074 
00077   virtual unsigned int derivatives(std::vector<ValuesIndexPair> &outDerivInds,
00078                                    const TransientTrackingRecHit &hit,
00079                                    const TrajectoryStateOnSurface &tsos,
00080                                    const edm::EventSetup &setup,
00081                                    const EventInfo &eventInfo) const;
00082 
00085   virtual bool setParameter(unsigned int index, double value);
00086 
00089   virtual bool setParameterError(unsigned int index, double error);
00090 
00093   virtual double getParameter(unsigned int index) const;
00094 
00097   virtual double getParameterError(unsigned int index) const;
00098 
00099   // /// Call at beginning of job:
00100   virtual void beginOfJob(AlignableTracker *tracker,
00101                           AlignableMuon *muon,
00102                           AlignableExtras *extras);
00103 
00106   virtual void endOfJob();
00107 
00108 private:
00111   bool checkBackPlaneCorrectionInput(const edm::EventSetup &setup, const EventInfo &eventInfo);
00115   const SiStripBackPlaneCorrection* getBackPlaneCorrectionInput();
00116 
00119   double getParameterForDetId(unsigned int detId, edm::RunNumber_t run) const;
00120 
00121   void writeTree(const SiStripBackPlaneCorrection *backPlaneCorr,
00122                  const std::map<unsigned int,TreeStruct> &treeInfo, const char *treeName) const;
00123   SiStripBackPlaneCorrection* createFromTree(const char *fileName, const char *treeName) const;
00124 
00125   const std::string readoutModeName_;
00126   int16_t readoutMode_;
00127   const bool saveToDB_;
00128   const std::string recordNameDBwrite_;
00129   const std::string outFileName_;
00130   const std::vector<std::string> mergeFileNames_;
00131 
00132   edm::ESWatcher<SiStripBackPlaneCorrectionRcd> watchBackPlaneCorrRcd_;
00133 
00134   SiStripBackPlaneCorrection *siStripBackPlaneCorrInput_;
00135 
00136   std::vector<double> parameters_;
00137   std::vector<double> paramUncertainties_;
00138 
00139   TkModuleGroupSelector *moduleGroupSelector_;
00140   const edm::ParameterSet moduleGroupSelCfg_;
00141 
00142 };
00143 
00144 //======================================================================
00145 //======================================================================
00146 //======================================================================
00147 
00148 SiStripBackplaneCalibration::SiStripBackplaneCalibration(const edm::ParameterSet &cfg)
00149   : IntegratedCalibrationBase(cfg),
00150     readoutModeName_(cfg.getParameter<std::string>("readoutMode")),
00151     saveToDB_(cfg.getParameter<bool>("saveToDB")),
00152     recordNameDBwrite_(cfg.getParameter<std::string>("recordNameDBwrite")),
00153     outFileName_(cfg.getParameter<std::string>("treeFile")),
00154     mergeFileNames_(cfg.getParameter<std::vector<std::string> >("mergeTreeFiles")),
00155     siStripBackPlaneCorrInput_(0),
00156     moduleGroupSelector_(0),
00157     moduleGroupSelCfg_(cfg.getParameter<edm::ParameterSet>("BackplaneModuleGroups"))
00158 {
00159 
00160   // SiStripLatency::singleReadOutMode() returns
00161   // 1: all in peak, 0: all in deco, -1: mixed state
00162   // (in principle one could treat even mixed state APV by APV...)
00163   if (readoutModeName_ == "peak") {
00164     readoutMode_ = kPeakMode;
00165   } else if (readoutModeName_ == "deconvolution") {
00166     readoutMode_ = kDeconvolutionMode;
00167   } else {
00168     throw cms::Exception("BadConfig")
00169           << "SiStripBackplaneCalibration:\n" << "Unknown mode '" 
00170           << readoutModeName_ << "', should be 'peak' or 'deconvolution' .\n";
00171   }
00172 
00173 }
00174   
00175 //======================================================================
00176 SiStripBackplaneCalibration::~SiStripBackplaneCalibration()
00177 {
00178   delete moduleGroupSelector_;
00179   //  std::cout << "Destroy SiStripBackplaneCalibration named " << this->name() << std::endl;
00180   delete siStripBackPlaneCorrInput_;
00181 }
00182 
00183 //======================================================================
00184 unsigned int SiStripBackplaneCalibration::numParameters() const
00185 {
00186   return parameters_.size();
00187 }
00188 
00189 //======================================================================
00190 unsigned int
00191 SiStripBackplaneCalibration::derivatives(std::vector<ValuesIndexPair> &outDerivInds,
00192                                          const TransientTrackingRecHit &hit,
00193                                          const TrajectoryStateOnSurface &tsos,
00194                                          const edm::EventSetup &setup,
00195                                          const EventInfo &eventInfo) const
00196 {
00197   // ugly const-cast:
00198   // But it is either only first initialisation or throwing an exception...
00199   const_cast<SiStripBackplaneCalibration*>(this)->checkBackPlaneCorrectionInput(setup, eventInfo);
00200 
00201   outDerivInds.clear();
00202 
00203   edm::ESHandle<SiStripLatency> latency;  
00204   setup.get<SiStripLatencyRcd>().get(latency);
00205   const int16_t mode = latency->singleReadOutMode();
00206 
00207   if(mode == readoutMode_) {
00208     if (hit.det()) { // otherwise 'constraint hit' or whatever
00209       
00210       const int index = moduleGroupSelector_->getParameterIndexFromDetId(hit.det()->geographicalId(),
00211                                                                     eventInfo.eventId_.run());
00212       if (index >= 0) { // otherwise not treated
00213         edm::ESHandle<MagneticField> magneticField;
00214         setup.get<IdealMagneticFieldRecord>().get(magneticField);
00215         const GlobalVector bField(magneticField->inTesla(hit.det()->surface().position()));
00216         const LocalVector bFieldLocal(hit.det()->surface().toLocal(bField));
00217         //std::cout << "SiStripBackplaneCalibration derivatives " << readoutModeName_ << std::endl;
00218         const double dZ = hit.det()->surface().bounds().thickness(); // it's a float only...
00219         const double tanPsi = tsos.localParameters().mixedFormatVector()[1]; //float...
00220 
00221         edm::ESHandle<SiStripLorentzAngle> lorentzAngleHandle;
00222         setup.get<SiStripLorentzAngleRcd>().get(readoutModeName_, lorentzAngleHandle);
00223         // Yes, mobility (= LA/By) stored in object called LA...
00224         const double mobility = lorentzAngleHandle->getLorentzAngle(hit.det()->geographicalId());
00225         // shift due to dead back plane has two parts:
00226         // 1) Lorentz Angle correction formula gets reduced thickness dz*(1-bp)
00227         // 2) 'Direct' effect is shift of effective module position in local z by bp*dz/2
00228         //   (see GF's presentation in alignment meeting 25.10.2012,
00229         //    https://indico.cern.ch/conferenceDisplay.py?confId=174266#2012-10-25)
00230         //        const double xDerivative = 0.5 * dZ * (mobility * bFieldLocal.y() - tanPsi);
00231         //FIXME: +tanPsi? At least that fits the sign of the dr/dw residual 
00232         //       in KarimakiDerivatives...
00233         const double xDerivative = 0.5 * dZ * (mobility * bFieldLocal.y() + tanPsi);
00234         // std::cout << "derivative is " << xDerivative << " for index " << index 
00235         //        << std::endl;
00236 //         if (index >= 10) {
00237 //           std::cout << "mobility * y-field " << mobility * bFieldLocal.y()
00238 //                     << ", \n tanPsi " << tanPsi /*<< ", dZ " << dZ */ << std::endl;
00239 //           std::cout << "|tanPsi| - |mobility * y-field| "
00240 //                     << fabs(tanPsi) - fabs(mobility * bFieldLocal.y())
00241 //                     << std::endl;
00242 //         }
00243         const Values derivs(xDerivative, 0.); // yDerivative = 0.
00244         outDerivInds.push_back(ValuesIndexPair(derivs, index));
00245       }
00246     } else {
00247       edm::LogWarning("Alignment") << "@SUB=SiStripBackplaneCalibration::derivatives1"
00248                                    << "Hit without GeomDet, skip!";
00249     }
00250   } else if (mode != kDeconvolutionMode && mode != kPeakMode) {
00251     // warn only if unknown/mixed mode  
00252     edm::LogWarning("Alignment") << "@SUB=SiStripBackplaneCalibration::derivatives2"
00253                                  << "Readout mode is " << mode << ", but looking for "
00254                                  << readoutMode_ << " (" << readoutModeName_ << ").";
00255   }
00256   
00257   return outDerivInds.size();
00258 }
00259 
00260 //======================================================================
00261 bool SiStripBackplaneCalibration::setParameter(unsigned int index, double value)
00262 {
00263   if (index >= parameters_.size()) {
00264     return false;
00265   } else {
00266     parameters_[index] = value;
00267     return true;
00268   }
00269 }
00270 
00271 //======================================================================
00272 bool SiStripBackplaneCalibration::setParameterError(unsigned int index, double error)
00273 {
00274   if (index >= paramUncertainties_.size()) {
00275     return false;
00276   } else {
00277     paramUncertainties_[index] = error;
00278     return true;
00279   }
00280 }
00281 
00282 //======================================================================
00283 double SiStripBackplaneCalibration::getParameter(unsigned int index) const
00284 {
00285   return (index >= parameters_.size() ? 0. : parameters_[index]);
00286 }
00287 
00288 //======================================================================
00289 double SiStripBackplaneCalibration::getParameterError(unsigned int index) const
00290 {
00291   return (index >= paramUncertainties_.size() ? 0. : paramUncertainties_[index]);
00292 }
00293 
00294 //======================================================================
00295 void SiStripBackplaneCalibration::beginOfJob(AlignableTracker *aliTracker,
00296                                              AlignableMuon * /*aliMuon*/,
00297                                              AlignableExtras */*aliExtras*/)
00298 {
00299   //specify the sub-detectors for which the back plane correction is determined: all strips
00300   const std::vector<int> sdets = boost::assign::list_of(SiStripDetId::TIB)(SiStripDetId::TID)
00301     (SiStripDetId::TOB)(SiStripDetId::TEC);
00302   
00303   moduleGroupSelector_ = new TkModuleGroupSelector(aliTracker, moduleGroupSelCfg_, sdets);
00304   
00305   parameters_.resize(moduleGroupSelector_->getNumberOfParameters(), 0.);
00306   paramUncertainties_.resize(moduleGroupSelector_->getNumberOfParameters(), 0.);
00307 
00308   edm::LogInfo("Alignment") << "@SUB=SiStripBackplaneCalibration" << "Created with name "
00309                             << this->name() << " for readout mode '" << readoutModeName_
00310                             << "',\n" << this->numParameters() << " parameters to be determined."
00311                             << "\nsaveToDB = " << saveToDB_
00312                             << "\n outFileName = " << outFileName_
00313                             << "\n N(merge files) = " << mergeFileNames_.size()
00314                             << "\n number of IOVs = " << moduleGroupSelector_->numIovs();
00315   
00316   if (mergeFileNames_.size()) {
00317     edm::LogInfo("Alignment") << "@SUB=SiStripBackplaneCalibration"
00318                               << "First file to merge: " << mergeFileNames_[0];
00319   }
00320   
00321 }
00322 
00323 
00324 //======================================================================
00325 void SiStripBackplaneCalibration::endOfJob()
00326 {
00327   // loginfo output
00328   std::ostringstream out;
00329   out << "Parameter results for readout mode '" << readoutModeName_ << "'\n";
00330   for (unsigned int iPar = 0; iPar < parameters_.size(); ++iPar) {
00331     out << iPar << ": " << parameters_[iPar] << " +- " << paramUncertainties_[iPar] << "\n";
00332   }
00333   edm::LogInfo("Alignment") << "@SUB=SiStripBackplaneCalibration::endOfJob" << out.str();
00334 
00335   std::map<unsigned int, TreeStruct> treeInfo; // map of TreeStruct for each detId
00336 
00337   // now write 'input' tree
00338   const SiStripBackPlaneCorrection *input = this->getBackPlaneCorrectionInput(); // never NULL
00339   const std::string treeName(this->name() + '_' + readoutModeName_ + '_');
00340   this->writeTree(input, treeInfo, (treeName + "input").c_str()); // empty treeInfo for input...
00341 
00342   if (input->getBackPlaneCorrections().empty()) {
00343     edm::LogError("Alignment") << "@SUB=SiStripBackplaneCalibration::endOfJob"
00344                                << "Input back plane correction map is empty ('"
00345                                << readoutModeName_ << "' mode), skip writing output!";
00346     return;
00347   }
00348 
00349   const unsigned int nonZeroParamsOrErrors =   // Any determined value?
00350     count_if (parameters_.begin(), parameters_.end(), std::bind2nd(std::not_equal_to<double>(),0.))
00351     + count_if(paramUncertainties_.begin(), paramUncertainties_.end(),
00352                std::bind2nd(std::not_equal_to<double>(), 0.));
00353 
00354   for (unsigned int iIOV = 0; iIOV < moduleGroupSelector_->numIovs(); ++iIOV) {
00355     cond::Time_t firstRunOfIOV = moduleGroupSelector_->firstRunOfIOV(iIOV);
00356     SiStripBackPlaneCorrection *output = new SiStripBackPlaneCorrection;
00357     // Loop on map of values from input and add (possible) parameter results
00358     for (auto iterIdValue = input->getBackPlaneCorrections().begin();
00359          iterIdValue != input->getBackPlaneCorrections().end(); ++iterIdValue) {
00360       // type of (*iterIdValue) is pair<unsigned int, float>
00361       const unsigned int detId = iterIdValue->first; // key of map is DetId
00362       // Some code one could use to miscalibrate wrt input:
00363       // double param = 0.;
00364       // const DetId id(detId);
00365       // switch (id.subdetId()) {
00366       // case 3:
00367       //   // delta = 0.025;
00368       //   {
00369       //     TIBDetId tibId(detId);
00370       //     param = tibId.layer() * 0.01;
00371       //   }
00372       //   break;
00373       // case 5:
00374       //   //delta = 0.050;
00375       //   {
00376       //     TOBDetId tobId(detId);
00377       //     param = tobId.layer() * 0.015;
00378       //   }
00379       //   break;
00380       // case 4: // TID
00381       //   param = 0.03; break;
00382       // case 6: // TEC
00383       //   param = 0.05; break;
00384       //   break;
00385       // default:
00386       //   std::cout << "unknown subdet " << id.subdetId() << std::endl;
00387       // }
00388       const double param = this->getParameterForDetId(detId, firstRunOfIOV);
00389       // put result in output, i.e. sum of input and determined parameter:
00390       output->putBackPlaneCorrection(detId, iterIdValue->second + param);
00391       const int paramIndex = moduleGroupSelector_->getParameterIndexFromDetId(detId,firstRunOfIOV);
00392       treeInfo[detId] = TreeStruct(param, this->getParameterError(paramIndex), paramIndex);
00393     }
00394 
00395     if (saveToDB_ || nonZeroParamsOrErrors != 0) { // Skip writing mille jobs...
00396       this->writeTree(output, treeInfo, (treeName + Form("result_%lld", firstRunOfIOV)).c_str());
00397     }
00398 
00399     if (saveToDB_) { // If requested, write out to DB 
00400       edm::Service<cond::service::PoolDBOutputService> dbService;
00401       if (dbService.isAvailable()) {
00402         dbService->writeOne(output, firstRunOfIOV, recordNameDBwrite_.c_str());
00403         // no 'delete output;': writeOne(..) took over ownership
00404       } else {
00405         delete output;
00406         edm::LogError("BadConfig") << "@SUB=SiStripBackplaneCalibration::endOfJob"
00407                                    << "No PoolDBOutputService available, but saveToDB true!";
00408       }
00409     } else {
00410       delete output;
00411     }
00412   } // end loop on IOVs
00413 }
00414 
00415 //======================================================================
00416 bool SiStripBackplaneCalibration::checkBackPlaneCorrectionInput(const edm::EventSetup &setup,
00417                                                                 const EventInfo &eventInfo)
00418 {
00419   edm::ESHandle<SiStripBackPlaneCorrection> backPlaneCorrHandle;
00420   if (!siStripBackPlaneCorrInput_) {
00421     setup.get<SiStripBackPlaneCorrectionRcd>().get(readoutModeName_, backPlaneCorrHandle);
00422     siStripBackPlaneCorrInput_ = new SiStripBackPlaneCorrection(*backPlaneCorrHandle);
00423     // FIXME: Should we call 'watchBackPlaneCorrRcd_.check(setup)' as well?
00424     //        Otherwise could be that next check has to check via following 'else', though
00425     //        no new IOV has started... (to be checked)
00426   } else {
00427     if (watchBackPlaneCorrRcd_.check(setup)) { // new IOV of input - but how to check peak vs deco?
00428       setup.get<SiStripBackPlaneCorrectionRcd>().get(readoutModeName_, backPlaneCorrHandle);
00429       if (backPlaneCorrHandle->getBackPlaneCorrections() // but only bad if non-identical values
00430           != siStripBackPlaneCorrInput_->getBackPlaneCorrections()) { // (comparing maps)
00431         // Maps are containers sorted by key, but comparison problems may arise from
00432         // 'floating point comparison' problems (FIXME?)
00433         throw cms::Exception("BadInput")
00434           << "SiStripBackplaneCalibration::checkBackPlaneCorrectionInput:\n"
00435           << "Content of SiStripBackPlaneCorrection changed at run " << eventInfo.eventId_.run()
00436           << ", but algorithm expects constant input!\n";
00437         return false; // not reached...
00438       }
00439     }
00440   }
00441   
00442   return true;
00443 }
00444 
00445 //======================================================================
00446 const SiStripBackPlaneCorrection* SiStripBackplaneCalibration::getBackPlaneCorrectionInput()
00447 {
00448   // For parallel processing in Millepede II, create SiStripBackPlaneCorrection
00449   // from info stored in files of parallel jobs and check that they are identical.
00450   // If this job has run on events, still check that back plane corrections are
00451   // identical to the ones from mergeFileNames_.
00452   const std::string treeName(((this->name() + '_') += readoutModeName_) += "_input");
00453   for (auto iFile = mergeFileNames_.begin(); iFile != mergeFileNames_.end(); ++iFile) {
00454     SiStripBackPlaneCorrection* bpCorr = this->createFromTree(iFile->c_str(), treeName.c_str());
00455     // siStripBackPlaneCorrInput_ could be non-null from previous file of this loop
00456     // or from checkBackPlaneCorrectionInput(..) when running on data in this job as well
00457     if (!siStripBackPlaneCorrInput_ || siStripBackPlaneCorrInput_->getBackPlaneCorrections().empty()) {
00458       delete siStripBackPlaneCorrInput_; // NULL or empty
00459       siStripBackPlaneCorrInput_ = bpCorr;
00460     } else {
00461       // about comparison of maps see comments in checkBackPlaneCorrectionInput
00462       if (bpCorr && !bpCorr->getBackPlaneCorrections().empty() && // single job might not have got events
00463           bpCorr->getBackPlaneCorrections() != siStripBackPlaneCorrInput_->getBackPlaneCorrections()) {
00464         // Throw exception instead of error?
00465         edm::LogError("NoInput") << "@SUB=SiStripBackplaneCalibration::getBackPlaneCorrectionInput"
00466                                  << "Different input values from tree " << treeName
00467                                  << " in file " << *iFile << ".";
00468         
00469       }
00470       delete bpCorr;
00471     }
00472   }
00473 
00474   if (!siStripBackPlaneCorrInput_) { // no files nor ran on events
00475     siStripBackPlaneCorrInput_ = new SiStripBackPlaneCorrection;
00476     edm::LogError("NoInput") << "@SUB=SiStripBackplaneCalibration::getBackPlaneCorrectionInput"
00477                              << "No input, create an empty one ('" << readoutModeName_ << "' mode)!";
00478   } else if (siStripBackPlaneCorrInput_->getBackPlaneCorrections().empty()) {
00479     edm::LogError("NoInput") << "@SUB=SiStripBackplaneCalibration::getBackPlaneCorrectionInput"
00480                              << "Empty result ('" << readoutModeName_ << "' mode)!";
00481   }
00482 
00483   return siStripBackPlaneCorrInput_;
00484 }
00485 
00486 //======================================================================
00487 double SiStripBackplaneCalibration::getParameterForDetId(unsigned int detId,
00488                                                          edm::RunNumber_t run) const
00489 {
00490   const int index = moduleGroupSelector_->getParameterIndexFromDetId(detId, run);
00491 
00492   return (index < 0 ? 0. : parameters_[index]);
00493 }
00494 
00495 //======================================================================
00496 void SiStripBackplaneCalibration::writeTree(const SiStripBackPlaneCorrection *backPlaneCorrection,
00497                                             const std::map<unsigned int, TreeStruct> &treeInfo,
00498                                             const char *treeName) const
00499 {
00500   if (!backPlaneCorrection) return;
00501 
00502   TFile* file = TFile::Open(outFileName_.c_str(), "UPDATE");
00503   if (!file) {
00504     edm::LogError("BadConfig") << "@SUB=SiStripBackplaneCalibration::writeTree"
00505                                << "Could not open file '" << outFileName_ << "'.";
00506     return;
00507   }
00508 
00509   TTree *tree = new TTree(treeName, treeName);
00510   unsigned int id = 0;
00511   float value = 0.;
00512   TreeStruct treeStruct;
00513   tree->Branch("detId", &id, "detId/i");
00514   tree->Branch("value", &value, "value/F");
00515   tree->Branch("treeStruct", &treeStruct, TreeStruct::LeafList());
00516 
00517   for (auto iterIdValue = backPlaneCorrection->getBackPlaneCorrections().begin();
00518        iterIdValue != backPlaneCorrection->getBackPlaneCorrections().end(); ++iterIdValue) {
00519     // type of (*iterIdValue) is pair<unsigned int, float>
00520     id = iterIdValue->first; // key of map is DetId
00521     value = iterIdValue->second;
00522     // type of (*treeStructIter) is pair<unsigned int, TreeStruct>
00523     auto treeStructIter = treeInfo.find(id); // find info for this id
00524     if (treeStructIter != treeInfo.end()) {
00525       treeStruct = treeStructIter->second; // info from input map
00526     } else { // if none found, fill at least parameter index (using 1st IOV...)
00527       const cond::Time_t run1of1stIov = moduleGroupSelector_->firstRunOfIOV(0);
00528       const int ind = moduleGroupSelector_->getParameterIndexFromDetId(id, run1of1stIov);
00529       treeStruct = TreeStruct(ind);
00530     }
00531     tree->Fill();
00532   }
00533   tree->Write();
00534   delete file; // tree vanishes with the file...
00535 
00536 }
00537 
00538 //======================================================================
00539 SiStripBackPlaneCorrection* 
00540 SiStripBackplaneCalibration::createFromTree(const char *fileName, const char *treeName) const
00541 {
00542   // Check for file existence on your own to work around
00543   // https://hypernews.cern.ch/HyperNews/CMS/get/swDevelopment/2715.html:
00544   TFile* file = 0;
00545   FILE* testFile = fopen(fileName,"r");
00546   if (testFile) {
00547     fclose(testFile);
00548     file = TFile::Open(fileName, "READ");
00549   } // else not existing, see error below
00550 
00551   TTree *tree = 0;
00552   if (file) file->GetObject(treeName, tree);
00553 
00554   SiStripBackPlaneCorrection *result = 0;
00555   if (tree) {
00556     unsigned int id = 0;
00557     float value = 0.;
00558     tree->SetBranchAddress("detId", &id);
00559     tree->SetBranchAddress("value", &value);
00560 
00561     result = new SiStripBackPlaneCorrection;
00562     const Long64_t nEntries = tree->GetEntries();
00563     for (Long64_t iEntry = 0; iEntry < nEntries; ++iEntry) {
00564       tree->GetEntry(iEntry);
00565       result->putBackPlaneCorrection(id, value);
00566     }
00567   } else { // Warning only since could be parallel job on no events.
00568     edm::LogWarning("Alignment") << "@SUB=SiStripBackplaneCalibration::createFromTree"
00569                                  << "Could not get TTree '" << treeName << "' from file '"
00570                                  << fileName << (file ? "'." : "' (file does not exist).");
00571   }
00572 
00573   delete file; // tree will vanish with file
00574   return result;
00575 }
00576 
00577 
00578 //======================================================================
00579 //======================================================================
00580 // Plugin definition
00581 
00582 #include "Alignment/CommonAlignmentAlgorithm/interface/IntegratedCalibrationPluginFactory.h"
00583 
00584 DEFINE_EDM_PLUGIN(IntegratedCalibrationPluginFactory,
00585                    SiStripBackplaneCalibration, "SiStripBackplaneCalibration");