00001
00002
00003
00004
00005
00006
00007
00008
00015
00016 #include "Alignment/CommonAlignmentAlgorithm/interface/IntegratedCalibrationBase.h"
00017 #include "Alignment/CommonAlignmentAlgorithm/interface/TkModuleGroupSelector.h"
00018
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
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
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
00068
00069
00070
00071
00072
00073
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
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
00161
00162
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
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
00198
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()) {
00209
00210 const int index = moduleGroupSelector_->getParameterIndexFromDetId(hit.det()->geographicalId(),
00211 eventInfo.eventId_.run());
00212 if (index >= 0) {
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
00218 const double dZ = hit.det()->surface().bounds().thickness();
00219 const double tanPsi = tsos.localParameters().mixedFormatVector()[1];
00220
00221 edm::ESHandle<SiStripLorentzAngle> lorentzAngleHandle;
00222 setup.get<SiStripLorentzAngleRcd>().get(readoutModeName_, lorentzAngleHandle);
00223
00224 const double mobility = lorentzAngleHandle->getLorentzAngle(hit.det()->geographicalId());
00225
00226
00227
00228
00229
00230
00231
00232
00233 const double xDerivative = 0.5 * dZ * (mobility * bFieldLocal.y() + tanPsi);
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 const Values derivs(xDerivative, 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
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 * ,
00297 AlignableExtras *)
00298 {
00299
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
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;
00336
00337
00338 const SiStripBackPlaneCorrection *input = this->getBackPlaneCorrectionInput();
00339 const std::string treeName(this->name() + '_' + readoutModeName_ + '_');
00340 this->writeTree(input, treeInfo, (treeName + "input").c_str());
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 =
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
00358 for (auto iterIdValue = input->getBackPlaneCorrections().begin();
00359 iterIdValue != input->getBackPlaneCorrections().end(); ++iterIdValue) {
00360
00361 const unsigned int detId = iterIdValue->first;
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 const double param = this->getParameterForDetId(detId, firstRunOfIOV);
00389
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) {
00396 this->writeTree(output, treeInfo, (treeName + Form("result_%lld", firstRunOfIOV)).c_str());
00397 }
00398
00399 if (saveToDB_) {
00400 edm::Service<cond::service::PoolDBOutputService> dbService;
00401 if (dbService.isAvailable()) {
00402 dbService->writeOne(output, firstRunOfIOV, recordNameDBwrite_.c_str());
00403
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 }
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
00424
00425
00426 } else {
00427 if (watchBackPlaneCorrRcd_.check(setup)) {
00428 setup.get<SiStripBackPlaneCorrectionRcd>().get(readoutModeName_, backPlaneCorrHandle);
00429 if (backPlaneCorrHandle->getBackPlaneCorrections()
00430 != siStripBackPlaneCorrInput_->getBackPlaneCorrections()) {
00431
00432
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;
00438 }
00439 }
00440 }
00441
00442 return true;
00443 }
00444
00445
00446 const SiStripBackPlaneCorrection* SiStripBackplaneCalibration::getBackPlaneCorrectionInput()
00447 {
00448
00449
00450
00451
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
00456
00457 if (!siStripBackPlaneCorrInput_ || siStripBackPlaneCorrInput_->getBackPlaneCorrections().empty()) {
00458 delete siStripBackPlaneCorrInput_;
00459 siStripBackPlaneCorrInput_ = bpCorr;
00460 } else {
00461
00462 if (bpCorr && !bpCorr->getBackPlaneCorrections().empty() &&
00463 bpCorr->getBackPlaneCorrections() != siStripBackPlaneCorrInput_->getBackPlaneCorrections()) {
00464
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_) {
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
00520 id = iterIdValue->first;
00521 value = iterIdValue->second;
00522
00523 auto treeStructIter = treeInfo.find(id);
00524 if (treeStructIter != treeInfo.end()) {
00525 treeStruct = treeStructIter->second;
00526 } else {
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;
00535
00536 }
00537
00538
00539 SiStripBackPlaneCorrection*
00540 SiStripBackplaneCalibration::createFromTree(const char *fileName, const char *treeName) const
00541 {
00542
00543
00544 TFile* file = 0;
00545 FILE* testFile = fopen(fileName,"r");
00546 if (testFile) {
00547 fclose(testFile);
00548 file = TFile::Open(fileName, "READ");
00549 }
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 {
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;
00574 return result;
00575 }
00576
00577
00578
00579
00580
00581
00582 #include "Alignment/CommonAlignmentAlgorithm/interface/IntegratedCalibrationPluginFactory.h"
00583
00584 DEFINE_EDM_PLUGIN(IntegratedCalibrationPluginFactory,
00585 SiStripBackplaneCalibration, "SiStripBackplaneCalibration");