CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/src/CalibMuon/DTCalibration/plugins/DTVDriftCalibration.cc

Go to the documentation of this file.
00001 
00002 /*
00003  *  See header file for a description of this class.
00004  *
00005  *  $Date: 2010/12/02 19:43:40 $
00006  *  $Revision: 1.11 $
00007  *  \author M. Giunta
00008  */
00009 
00010 #include "CalibMuon/DTCalibration/plugins/DTVDriftCalibration.h"
00011 #include "CalibMuon/DTCalibration/interface/DTMeanTimerFitter.h"
00012 #include "CalibMuon/DTCalibration/interface/DTCalibDBUtils.h"
00013 
00014 #include "FWCore/Framework/interface/Event.h"
00015 #include "FWCore/Framework/interface/ESHandle.h"
00016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00017 
00018 #include "Geometry/DTGeometry/interface/DTGeometry.h"
00019 #include "Geometry/Records/interface/MuonGeometryRecord.h"
00020 
00021 #include "CalibMuon/DTDigiSync/interface/DTTTrigSyncFactory.h"
00022 #include "CalibMuon/DTDigiSync/interface/DTTTrigBaseSync.h"
00023 
00024 #include "DataFormats/DTRecHit/interface/DTRecSegment4DCollection.h"
00025 #include "CondFormats/DTObjects/interface/DTMtime.h"
00026 
00027 #include "CondFormats/DataRecord/interface/DTStatusFlagRcd.h"
00028 #include "CondFormats/DTObjects/interface/DTStatusFlag.h"
00029 
00030 /* C++ Headers */
00031 #include <map>
00032 #include <iostream>
00033 #include <fstream>
00034 #include <string>
00035 #include <sstream>
00036 #include "TFile.h"
00037 #include "TH1.h"
00038 #include "TF1.h"
00039 #include "TROOT.h" 
00040 
00041 // Declare histograms.
00042 TH1F * hChi2;
00043 extern void bookHistos();
00044 
00045 using namespace std;
00046 using namespace edm;
00047 using namespace dttmaxenums;
00048 
00049 
00050 DTVDriftCalibration::DTVDriftCalibration(const ParameterSet& pset): select_(pset) {
00051 
00052   // The name of the 4D rec hits collection
00053   theRecHits4DLabel = pset.getParameter<InputTag>("recHits4DLabel");
00054 
00055   // The root file which will contain the histos
00056   string rootFileName = pset.getUntrackedParameter<string>("rootFileName");
00057   theFile = new TFile(rootFileName.c_str(), "RECREATE");
00058   theFile->cd();
00059 
00060   debug = pset.getUntrackedParameter<bool>("debug", false);
00061 
00062   theFitter = new DTMeanTimerFitter(theFile);
00063   if(debug)
00064     theFitter->setVerbosity(1);
00065 
00066   hChi2 = new TH1F("hChi2","Chi squared tracks",100,0,100);
00067   h2DSegmRPhi = new h2DSegm("SLRPhi");
00068   h2DSegmRZ = new h2DSegm("SLRZ");
00069   h4DSegmAllCh = new h4DSegm("AllCh");
00070   bookHistos();
00071 
00072   findVDriftAndT0 = pset.getUntrackedParameter<bool>("fitAndWrite", false);
00073 
00074   // Chamber/s to calibrate
00075   theCalibChamber =  pset.getUntrackedParameter<string>("calibChamber", "All");
00076 
00077   // the txt file which will contain the calibrated constants
00078   theVDriftOutputFile = pset.getUntrackedParameter<string>("vDriftFileName");
00079 
00080   // Get the synchronizer
00081   theSync = DTTTrigSyncFactory::get()->create(pset.getParameter<string>("tTrigMode"),
00082                                               pset.getParameter<ParameterSet>("tTrigModeConfig"));
00083 
00084   // get parameter set for DTCalibrationMap constructor
00085   theCalibFilePar =  pset.getUntrackedParameter<ParameterSet>("calibFileConfig");
00086 
00087   // the granularity to be used for tMax
00088   string tMaxGranularity = pset.getUntrackedParameter<string>("tMaxGranularity","bySL");
00089 
00090   // Enforce it to be by SL since rest is not implemented
00091   if(tMaxGranularity != "bySL"){
00092      LogError("Calibration") << "[DTVDriftCalibration] tMaxGranularity will be fixed to bySL.";
00093      tMaxGranularity = "bySL";
00094   }
00095   // Initialize correctly the enum which specify the granularity for the calibration
00096   if(tMaxGranularity == "bySL") {
00097     theGranularity = bySL;
00098   } else if(tMaxGranularity == "byChamber"){
00099     theGranularity = byChamber;
00100   } else if(tMaxGranularity== "byPartition") {
00101     theGranularity = byPartition;
00102   } else throw cms::Exception("Configuration") << "[DTVDriftCalibration] Check parameter tMaxGranularity: "
00103                                                << tMaxGranularity << " option not available";
00104   
00105 
00106   LogVerbatim("Calibration") << "[DTVDriftCalibration]Constructor called!";
00107 }
00108 
00109 DTVDriftCalibration::~DTVDriftCalibration(){
00110   theFile->Close();
00111   delete theFitter;
00112   LogVerbatim("Calibration") << "[DTVDriftCalibration]Destructor called!";
00113 }
00114 
00115 void DTVDriftCalibration::analyze(const Event & event, const EventSetup& eventSetup) {
00116   LogTrace("Calibration") << "--- [DTVDriftCalibration] Event analysed #Run: " << event.id().run()
00117                           << " #Event: " << event.id().event();
00118   theFile->cd();
00119   DTChamberId chosenChamberId;
00120 
00121   if(theCalibChamber != "All") {
00122     stringstream linestr;
00123     int selWheel, selStation, selSector;
00124     linestr << theCalibChamber;
00125     linestr >> selWheel >> selStation >> selSector;
00126     chosenChamberId = DTChamberId(selWheel, selStation, selSector);
00127     LogTrace("Calibration") << "chosen chamber " << chosenChamberId;
00128   }
00129 
00130   // Get the DT Geometry
00131   ESHandle<DTGeometry> dtGeom;
00132   eventSetup.get<MuonGeometryRecord>().get(dtGeom);
00133 
00134   // Get the rechit collection from the event
00135   Handle<DTRecSegment4DCollection> all4DSegments;
00136   event.getByLabel(theRecHits4DLabel, all4DSegments); 
00137 
00138   // Get the map of noisy channels
00139   /*ESHandle<DTStatusFlag> statusMap;
00140   if(checkNoisyChannels) {
00141     eventSetup.get<DTStatusFlagRcd>().get(statusMap);
00142   }*/
00143 
00144   // Set the event setup in the Synchronizer 
00145   theSync->setES(eventSetup);
00146 
00147   // Loop over segments by chamber
00148   DTRecSegment4DCollection::id_iterator chamberIdIt;
00149   for (chamberIdIt = all4DSegments->id_begin();
00150        chamberIdIt != all4DSegments->id_end();
00151        ++chamberIdIt){
00152 
00153     // Get the chamber from the setup
00154     const DTChamber* chamber = dtGeom->chamber(*chamberIdIt);
00155     LogTrace("Calibration") << "Chamber Id: " << *chamberIdIt;
00156 
00157     // Calibrate just the chosen chamber/s    
00158     if((theCalibChamber != "All") && ((*chamberIdIt) != chosenChamberId)) 
00159       continue;
00160 
00161     // Get the range for the corresponding ChamberId
00162     DTRecSegment4DCollection::range  range = all4DSegments->get((*chamberIdIt));
00163 
00164     // Loop over the rechits of this DetUnit
00165     for (DTRecSegment4DCollection::const_iterator segment = range.first;
00166          segment!=range.second; ++segment){
00167 
00168       if( !(*segment).hasZed() && !(*segment).hasPhi() ){
00169          LogError("Calibration") << "4D segment without Z and Phi segments";
00170          continue;   
00171       } 
00172 
00173       LogTrace("Calibration") << "Segment local pos (in chamber RF): " << (*segment).localPosition()
00174                               << "\nSegment global pos: " << chamber->toGlobal((*segment).localPosition());
00175 
00176       if( !select_(*segment, event, eventSetup) ) continue;
00177 
00178       LocalPoint phiSeg2DPosInCham;  
00179       LocalVector phiSeg2DDirInCham;
00180       map<DTSuperLayerId,vector<DTRecHit1D> > hitsBySLMap; 
00181       if((*segment).hasPhi()){
00182         const DTChamberRecSegment2D* phiSeg = (*segment).phiSegment();  // phiSeg lives in the chamber RF
00183         phiSeg2DPosInCham = phiSeg->localPosition();  
00184         phiSeg2DDirInCham = phiSeg->localDirection();
00185         vector<DTRecHit1D> phiHits = phiSeg->specificRecHits();
00186         for(vector<DTRecHit1D>::const_iterator hit = phiHits.begin();
00187             hit != phiHits.end(); ++hit) {
00188           DTWireId wireId = (*hit).wireId();
00189           DTSuperLayerId slId =  wireId.superlayerId();
00190           hitsBySLMap[slId].push_back(*hit); 
00191         }
00192       }
00193       // Get the Theta 2D segment and plot the angle in the chamber RF
00194       LocalVector zSeg2DDirInCham;
00195       LocalPoint zSeg2DPosInCham;
00196       if((*segment).hasZed()) {
00197         const DTSLRecSegment2D* zSeg = (*segment).zSegment();  // zSeg lives in the SL RF
00198         const DTSuperLayer* sl = chamber->superLayer(zSeg->superLayerId());
00199         zSeg2DPosInCham = chamber->toLocal(sl->toGlobal((*zSeg).localPosition())); 
00200         zSeg2DDirInCham = chamber->toLocal(sl->toGlobal((*zSeg).localDirection()));
00201         hitsBySLMap[zSeg->superLayerId()] = zSeg->specificRecHits();
00202       } 
00203 
00204       LocalPoint segment4DLocalPos = (*segment).localPosition();
00205       LocalVector segment4DLocalDir = (*segment).localDirection();
00206       double chiSquare = ((*segment).chi2()/(*segment).degreesOfFreedom());
00207 
00208       hChi2->Fill(chiSquare);
00209       if((*segment).hasPhi())
00210         h2DSegmRPhi->Fill(phiSeg2DPosInCham.x(), phiSeg2DDirInCham.x()/phiSeg2DDirInCham.z());
00211       if((*segment).hasZed())
00212         h2DSegmRZ->Fill(zSeg2DPosInCham.y(), zSeg2DDirInCham.y()/zSeg2DDirInCham.z());
00213 
00214       if((*segment).hasZed() && (*segment).hasPhi()) 
00215         h4DSegmAllCh->Fill(segment4DLocalPos.x(), 
00216                            segment4DLocalPos.y(),
00217                            atan(segment4DLocalDir.x()/segment4DLocalDir.z())*180./Geom::pi(),
00218                            atan(segment4DLocalDir.y()/segment4DLocalDir.z())*180./Geom::pi(),
00219                            180 - segment4DLocalDir.theta()*180./Geom::pi());
00220       else if((*segment).hasPhi())
00221         h4DSegmAllCh->Fill(segment4DLocalPos.x(), 
00222                            atan(segment4DLocalDir.x()/segment4DLocalDir.z())*180./Geom::pi());
00223       else if((*segment).hasZed())
00224         LogWarning("Calibration") << "4d segment with only Z";
00225 
00226       //loop over the segments 
00227       for(map<DTSuperLayerId,vector<DTRecHit1D> >::const_iterator slIdAndHits = hitsBySLMap.begin(); slIdAndHits != hitsBySLMap.end();  ++slIdAndHits) {
00228         if (slIdAndHits->second.size() < 3) continue;
00229         DTSuperLayerId slId = slIdAndHits->first;
00230 
00231         // Create the DTTMax, that computes the 4 TMax
00232         DTTMax slSeg(slIdAndHits->second, *(chamber->superLayer(slIdAndHits->first)),chamber->toGlobal((*segment).localDirection()), chamber->toGlobal((*segment).localPosition()), theSync);
00233 
00234         if(theGranularity == bySL) {
00235           vector<const TMax*> tMaxes = slSeg.getTMax(slId);
00236           DTWireId wireId(slId, 0, 0);
00237           theFile->cd();
00238           cellInfo* cell = theWireIdAndCellMap[wireId];
00239           if (cell==0) {
00240             TString name = (((((TString) "TMax"+(long) slId.wheel()) +(long) slId.station())
00241                              +(long) slId.sector())+(long) slId.superLayer());
00242             cell = new cellInfo(name);
00243             theWireIdAndCellMap[wireId] = cell;
00244           }
00245           cell->add(tMaxes);
00246           cell->update(); // FIXME to reset the counter to avoid triple counting, which actually is not used...
00247         }
00248         else {
00249           LogWarning("Calibration") << "[DTVDriftCalibration] ###Warning: the chosen granularity is not implemented yet, only bySL available!";
00250         }
00251         // to be implemented: granularity different from bySL
00252 
00253         //       else if (theGranularity == byPartition) {
00254         //      // Use the custom granularity defined by partition(); 
00255         //      // in this case, add() should be called once for each Tmax of each layer 
00256         //      // and triple counting should be avoided within add()
00257         //      vector<cellInfo*> cells;
00258         //      for (int i=1; i<=4; i++) {
00259         //        const DTTMax::InfoLayer* iLayer = slSeg.getInfoLayer(i);
00260         //        if(iLayer == 0) continue;
00261         //        cellInfo * cell = partition(iLayer->idWire); 
00262         //        cells.push_back(cell);
00263         //        vector<const TMax*> tMaxes = slSeg.getTMax(iLayer->idWire);
00264         //        cell->add(tMaxes);
00265         //      }
00266         //      //reset the counter to avoid triple counting
00267         //      for (vector<cellInfo*>::const_iterator i = cells.begin();
00268         //           i!= cells.end(); i++) {
00269         //        (*i)->update();
00270         //      }
00271         //       } 
00272       }
00273     }
00274   }
00275 }
00276 
00277 void DTVDriftCalibration::endJob() {
00278   theFile->cd();
00279   gROOT->GetList()->Write();
00280   h2DSegmRPhi->Write();
00281   h2DSegmRZ->Write();
00282   h4DSegmAllCh->Write();
00283   hChi2->Write();
00284   // Instantiate a DTCalibrationMap object if you want to calculate the calibration constants
00285   DTCalibrationMap calibValuesFile(theCalibFilePar);  
00286   // Create the object to be written to DB
00287   DTMtime* mTime = new DTMtime();
00288 
00289   // write the TMax histograms of each SL to the root file
00290   if(theGranularity == bySL) {
00291     for(map<DTWireId, cellInfo*>::const_iterator  wireCell = theWireIdAndCellMap.begin();
00292         wireCell != theWireIdAndCellMap.end(); wireCell++) {
00293       cellInfo* cell= theWireIdAndCellMap[(*wireCell).first];
00294       hTMaxCell* cellHists = cell->getHists();
00295       theFile->cd();
00296       cellHists->Write();
00297       if(findVDriftAndT0) {  // if TRUE: evaluate calibration constants from TMax hists filled in this job  
00298         // evaluate v_drift and sigma from the TMax histograms
00299         DTWireId wireId = (*wireCell).first;
00300         vector<float> newConstants;
00301         TString N=(((((TString) "TMax"+(long) wireId.wheel()) +(long) wireId.station())
00302                     +(long) wireId.sector())+(long) wireId.superLayer());
00303         vector<float> vDriftAndReso = theFitter->evaluateVDriftAndReso(N);
00304 
00305         // Don't write the constants for the SL if the vdrift was not computed
00306         if(vDriftAndReso.front() == -1)
00307           continue;
00308         const DTCalibrationMap::CalibConsts* oldConstants = calibValuesFile.getConsts(wireId);
00309         if(oldConstants != 0) {
00310           newConstants.push_back((*oldConstants)[0]);
00311           newConstants.push_back((*oldConstants)[1]);
00312           newConstants.push_back((*oldConstants)[2]);
00313         } else {
00314           newConstants.push_back(-1);
00315           newConstants.push_back(-1);
00316           newConstants.push_back(-1);
00317         }
00318         for(int ivd=0; ivd<=5;ivd++) { 
00319           // 0=vdrift, 1=reso, 2=(3deltat0-2deltat0), 3=(2deltat0-1deltat0),
00320           //  4=(1deltat0-0deltat0), 5=deltat0 from hists with max entries,
00321           newConstants.push_back(vDriftAndReso[ivd]); 
00322         }
00323 
00324         calibValuesFile.addCell(calibValuesFile.getKey(wireId), newConstants);
00325 
00326         // vdrift is cm/ns , resolution is cm
00327         mTime->set((wireId.layerId()).superlayerId(),
00328                    vDriftAndReso[0],
00329                    vDriftAndReso[1],
00330                    DTVelocityUnits::cm_per_ns);
00331         LogTrace("Calibration") << " SL: " << (wireId.layerId()).superlayerId()
00332                                 << " vDrift = " << vDriftAndReso[0]
00333                                 << " reso = " << vDriftAndReso[1];
00334       }
00335     }
00336   }
00337 
00338   // to be implemented: granularity different from bySL
00339 
00340   //   if(theGranularity == "byChamber") {
00341   //     const vector<DTChamber*> chambers = dMap.chambers();
00342 
00343   //     // Loop over all chambers
00344   //     for(vector<MuBarChamber*>::const_iterator chamber = chambers.begin();
00345   //    chamber != chambers.end(); chamber ++) {
00346   //       MuBarChamberId chamber_id = (*chamber)->id();
00347   //       MuBarDigiParameters::Key wire_id(chamber_id, 0, 0, 0);
00348   //       vector<float> newConstants;
00349   //       vector<float> vDriftAndReso = evaluateVDriftAndReso(wire_id, f);
00350   //       const CalibConsts* oldConstants = digiParams.getConsts(wire_id);
00351   //       if(oldConstants !=0) {
00352   //    newConstants = *oldConstants;
00353   //    newConstants.push_back(vDriftAndReso[0]);
00354   //    newConstants.push_back(vDriftAndReso[1]);
00355   //    newConstants.push_back(vDriftAndReso[2]);
00356   //    newConstants.push_back(vDriftAndReso[3]);
00357   //       } else {
00358   //    newConstants.push_back(-1);
00359   //    newConstants.push_back(-1);
00360   //    newConstants.push_back(vDriftAndReso[0]);
00361   //    newConstants.push_back(vDriftAndReso[1]);
00362   //    newConstants.push_back(vDriftAndReso[2]);
00363   //    newConstants.push_back(vDriftAndReso[3]);
00364   //       }
00365   //       digiParams.addCell(wire_id, newConstants);
00366   //     }
00367   //   }
00368 
00369   // Write values to a table  
00370   calibValuesFile.writeConsts(theVDriftOutputFile);
00371 
00372   LogVerbatim("Calibration") << "[DTVDriftCalibration]Writing vdrift object to DB!";
00373 
00374   // Write the vdrift object to DB
00375   string record = "DTMtimeRcd";
00376   DTCalibDBUtils::writeToDB<DTMtime>(record, mTime);
00377 }
00378 
00379 // to be implemented: granularity different from bySL
00380 
00381 // // Create partitions 
00382 // DTVDriftCalibration::cellInfo* DTVDriftCalibration::partition(const DTWireId& wireId) {
00383 //   for( map<MuBarWireId, cellInfo*>::const_iterator iter =
00384 //       mapCellTmaxPart.begin(); iter != mapCellTmaxPart.end(); iter++) {
00385 //     // Divide wires per SL (with phi symmetry)
00386 //     if(iter->first.wheel() == wireId.wheel() &&
00387 //        iter->first.station() == wireId.station() &&
00388 //        //       iter->first.sector() == wireId.sector() && // phi symmetry!
00389 //        iter->first.superlayer() == wireId.superlayer()) {
00390 //       return iter->second;
00391 //     }
00392 //   }
00393 //   cellInfo * result = new cellInfo("dummy string"); // FIXME: change constructor; create tree?
00394 //   mapCellTmaxPart.insert(make_pair(wireId, result));
00395 //   return result;
00396 //}
00397 
00398 
00399 void DTVDriftCalibration::cellInfo::add(vector<const TMax*> tMaxes) {
00400   float tmax123 = -1.;
00401   float tmax124 = -1.;
00402   float tmax134 = -1.;  
00403   float tmax234 = -1.;
00404   SigmaFactor s124 = noR;
00405   SigmaFactor s134 = noR;
00406   unsigned t0_123 = 0;
00407   unsigned t0_124 = 0;
00408   unsigned t0_134 = 0;
00409   unsigned t0_234 = 0;
00410   unsigned hSubGroup = 0;
00411   for (vector<const TMax*>::const_iterator it=tMaxes.begin(); it!=tMaxes.end();
00412        ++it) {
00413     if(*it == 0) {
00414       continue;  
00415     }
00416     else { 
00417       //FIXME check cached,
00418       if (addedCells.size()==4 || 
00419           find(addedCells.begin(), addedCells.end(), (*it)->cells) 
00420           != addedCells.end()) {
00421         continue;
00422       }
00423       addedCells.push_back((*it)->cells);    
00424       SigmaFactor sigma = (*it)->sigma;
00425       float t = (*it)->t;
00426       TMaxCells cells = (*it)->cells;
00427       unsigned t0Factor = (*it)->t0Factor;
00428       hSubGroup = (*it)->hSubGroup;
00429       if(t < 0.) continue;
00430       switch(cells) {
00431       case notInit : cout << "Error: no cell type assigned to TMax" << endl; break;
00432       case c123 : tmax123 =t; t0_123 = t0Factor; break;
00433       case c124 : tmax124 =t; s124 = sigma; t0_124 = t0Factor; break;
00434       case c134 : tmax134 =t; s134 = sigma; t0_134 = t0Factor; break;
00435       case c234 : tmax234 =t; t0_234 = t0Factor; break;
00436       } 
00437     }
00438   }
00439   //add entries to the TMax histograms
00440   histos->Fill(tmax123, tmax124, tmax134, tmax234, s124, s134, t0_123, 
00441                t0_124, t0_134, t0_234, hSubGroup); 
00442 }