CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/DQM/DTMonitorModule/src/DTEfficiencyTask.cc

Go to the documentation of this file.
00001 
00002 
00003 /*
00004  *  See header file for a description of this class.
00005  *
00006  *  $Date: 2011/11/12 09:18:42 $
00007  *  $Revision: 1.17 $
00008  *  \author G. Mila - INFN Torino
00009  */
00010 
00011 
00012 #include "DTEfficiencyTask.h"
00013 
00014 
00015 // Framework
00016 #include "FWCore/Framework/interface/Event.h"
00017 #include "FWCore/Framework/interface/EventSetup.h"
00018 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00019 #include "FWCore/Framework/interface/ESHandle.h"
00020 #include "FWCore/ServiceRegistry/interface/Service.h"
00021 
00022 #include "DQMServices/Core/interface/DQMStore.h"
00023 #include "DQMServices/Core/interface/MonitorElement.h"
00024 
00025 //Geometry
00026 #include "Geometry/DTGeometry/interface/DTGeometry.h"
00027 #include "Geometry/Records/interface/MuonGeometryRecord.h"
00028 
00029 //RecHit
00030 #include "DataFormats/DTRecHit/interface/DTRecSegment4DCollection.h"
00031 #include "DataFormats/DTRecHit/interface/DTRecHitCollection.h"
00032 #include "DataFormats/DTRecHit/interface/DTRangeMapAccessor.h"
00033 
00034 #include "CondFormats/DataRecord/interface/DTStatusFlagRcd.h"
00035 #include "CondFormats/DTObjects/interface/DTStatusFlag.h"
00036 
00037 #include <iterator>
00038 
00039 using namespace edm;
00040 using namespace std;
00041 
00042 
00043 DTEfficiencyTask::DTEfficiencyTask(const ParameterSet& pset) {
00044 
00045   debug = pset.getUntrackedParameter<bool>("debug",false);
00046 
00047   // Get the DQM needed services
00048   theDbe = edm::Service<DQMStore>().operator->();
00049   theDbe->setCurrentFolder("DT/DTEfficiencyTask");
00050 
00051   parameters = pset;
00052 }
00053 
00054 
00055 DTEfficiencyTask::~DTEfficiencyTask(){
00056 }  
00057 
00058 
00059 void DTEfficiencyTask::beginJob(){
00060   // the name of the 4D rec hits collection
00061   theRecHits4DLabel = parameters.getParameter<string>("recHits4DLabel");
00062   // the name of the rechits collection
00063   theRecHitLabel = parameters.getParameter<string>("recHitLabel");
00064 }
00065 
00066 
00067 void DTEfficiencyTask::beginLuminosityBlock(LuminosityBlock const& lumiSeg, EventSetup const& context) {
00068 
00069   
00070   if(lumiSeg.id().luminosityBlock()%parameters.getUntrackedParameter<int>("ResetCycle", 3) == 0) {
00071     for(map<DTLayerId, vector<MonitorElement*> > ::const_iterator histo = histosPerL.begin();
00072         histo != histosPerL.end();
00073         histo++) {
00074       int size = (*histo).second.size();
00075       for(int i=0; i<size; i++){
00076         (*histo).second[i]->Reset();
00077       }
00078     }
00079   }
00080   
00081 }
00082 
00083 
00084 void DTEfficiencyTask::endJob(){
00085   theDbe->rmdir("DT/DTEfficiencyTask");
00086 }
00087   
00088 
00089 void DTEfficiencyTask::analyze(const edm::Event& event, const edm::EventSetup& setup) {
00090 
00091 
00092   if(debug)
00093     cout << "[DTEfficiencyTask] Analyze #Run: " << event.id().run()
00094          << " #Event: " << event.id().event() << endl;
00095 
00096 
00097   // Get the 4D segment collection from the event
00098   edm::Handle<DTRecSegment4DCollection> all4DSegments;
00099   event.getByLabel(theRecHits4DLabel, all4DSegments);
00100 
00101   // Get the rechit collection from the event
00102   Handle<DTRecHitCollection> dtRecHits;
00103   event.getByLabel(theRecHitLabel, dtRecHits);
00104 
00105   // Get the DT Geometry
00106   ESHandle<DTGeometry> dtGeom;
00107   setup.get<MuonGeometryRecord>().get(dtGeom);
00108 
00109   // Loop over all chambers containing a segment
00110   DTRecSegment4DCollection::id_iterator chamberId;
00111   for (chamberId = all4DSegments->id_begin();
00112        chamberId != all4DSegments->id_end();
00113        ++chamberId) {
00114 
00115     // Get the chamber
00116     const DTChamber* chamber = dtGeom->chamber(*chamberId); 
00117 
00118     // Get all 1D RecHits to be used for searches of hits not associated to segments and map them by wire
00119     const vector<const DTSuperLayer*> SLayers = chamber->superLayers();
00120     map<DTWireId, int> wireAnd1DRecHits;
00121     for(vector<const DTSuperLayer*>::const_iterator superlayer = SLayers.begin();
00122         superlayer != SLayers.end();
00123         superlayer++) {
00124         DTRecHitCollection::range  range = dtRecHits->get(DTRangeMapAccessor::layersBySuperLayer((*superlayer)->id()));
00125         // Loop over the rechits of this ChamberId
00126         for (DTRecHitCollection::const_iterator rechit = range.first;
00127              rechit!=range.second;
00128              ++rechit){
00129           wireAnd1DRecHits[(*rechit).wireId()] = (*rechit).wireId().wire();
00130         }
00131       }
00132 
00133 
00134     // Get the 4D segment range for the corresponding ChamerId
00135     DTRecSegment4DCollection::range  range = all4DSegments->get(*chamberId);
00136     int nsegm = distance(range.first, range.second);
00137     if(debug)
00138       cout << "   Chamber: " << *chamberId << " has " << nsegm
00139            << " 4D segments" << endl;
00140 
00141     
00142     // Loop over the rechits of this ChamerId
00143     for (DTRecSegment4DCollection::const_iterator segment4D = range.first;
00144          segment4D!=range.second;
00145          ++segment4D) {
00146       if(debug)
00147         cout << "   == RecSegment dimension: " << (*segment4D).dimension() << endl;
00148 
00149       // If Statio != 4 skip RecHits with dimension != 4
00150       // For the Station 4 consider 2D RecHits
00151       if((*chamberId).station() != 4 && (*segment4D).dimension() != 4) {
00152         if(debug)
00153           cout << "[DTEfficiencyTask]***Warning: RecSegment dimension is not 4 but "
00154                << (*segment4D).dimension() << ", skipping!" << endl;
00155         continue;
00156       } else if((*chamberId).station() == 4 && (*segment4D).dimension() != 2) {
00157         if(debug)
00158           cout << "[DTEfficiencyTask]***Warning: RecSegment dimension is not 2 but "
00159                << (*segment4D).dimension() << ", skipping!" << endl;
00160         continue;
00161       }
00162 
00163       vector<DTRecHit1D> recHits1D;   
00164       bool rPhi = false;
00165       bool rZ = false;
00166 
00167       // Get 1D RecHits and select only events with 7 or 8 hits in phi and 3 or 4 hits in theta (if any)
00168       const DTChamberRecSegment2D* phiSeg = (*segment4D).phiSegment();
00169       vector<DTRecHit1D> phiRecHits = phiSeg->specificRecHits();
00170       rPhi = true;
00171       if(phiRecHits.size() < 7 || phiRecHits.size() > 8 ) {
00172         if(debug)
00173           cout << "[DTEfficiencyTask] Phi segments has: " << phiRecHits.size()
00174                << " hits, skipping" << endl; // FIXME: info output
00175         continue;
00176       }
00177       copy(phiRecHits.begin(), phiRecHits.end(), back_inserter(recHits1D));
00178       const DTSLRecSegment2D* zSeg = 0;
00179       if((*segment4D).dimension() == 4) {
00180         rZ = true;
00181         zSeg = (*segment4D).zSegment();
00182         vector<DTRecHit1D> zRecHits = zSeg->specificRecHits();
00183         if(zRecHits.size() < 3 || zRecHits.size() > 4 ) {
00184           if(debug)
00185             cout << "[DTEfficiencyTask] Theta segments has: " << zRecHits.size()
00186                  << " hits, skipping" << endl; // FIXME: info output
00187           continue;
00188         }
00189         copy(zRecHits.begin(), zRecHits.end(), back_inserter(recHits1D));
00190       }
00191 
00192       // Skip the segment if it has more than 1 hit on the same layer
00193       vector<DTWireId> wireMap; 
00194       for(vector<DTRecHit1D>::const_iterator recHit1D = recHits1D.begin();
00195           recHit1D != recHits1D.end();
00196           recHit1D++) {
00197         wireMap.push_back((*recHit1D).wireId());
00198       }
00199 
00200       bool hitsOnSameLayer = false;
00201       for(vector<DTWireId>::const_iterator channelId = wireMap.begin();
00202           channelId != wireMap.end(); channelId++) {
00203         vector<DTWireId>::const_iterator next = channelId;
00204         next++;
00205         for(vector<DTWireId>::const_iterator ite = next; ite != wireMap.end(); ite++) {
00206           if((*channelId).layerId() == (*ite).layerId()) {
00207             hitsOnSameLayer = true;
00208           }
00209         }
00210       }
00211       if(hitsOnSameLayer) {
00212         if(debug)
00213           cout << "[DTEfficiencyTask] This RecHit has 2 hits on the same layer, skipping!" << endl;
00214         continue;
00215       }
00216 
00217 
00218       // Select 2D segments with angle smaller than 45 deg
00219       LocalVector phiDirectionInChamber = (*phiSeg).localDirection();
00220       if(rPhi && fabs(phiDirectionInChamber.x()/phiDirectionInChamber.z()) > 1) {
00221         if(debug) {
00222           cout << "         RPhi segment has angle > 45 deg, skipping! " << endl;
00223           cout << "              Theta = " << phiDirectionInChamber.theta() << endl;
00224         }
00225         continue;
00226       }
00227       if(rZ) {
00228          LocalVector zDirectionInChamber = (*zSeg).localDirection();
00229          if(fabs(zDirectionInChamber.y()/zDirectionInChamber.z()) > 1) {
00230            if(debug){
00231              cout << "         RZ segment has angle > 45 deg, skipping! "  << endl;
00232              cout << "              Theta = " << zDirectionInChamber.theta() << endl;
00233            }
00234            continue;
00235          }
00236       }
00237 
00238 
00239       // Skip if the 4D segment has only 10 hits
00240       if(recHits1D.size() == 10) {
00241         if(debug)
00242           cout << "[DTEfficiencyTask] 4D Segment with only 10 hits, skipping!" << endl;
00243         continue;
00244       }
00245 
00246 
00247       // Analyse the case of 11 recHits for MB1,MB2,MB3 and of 7 recHits for MB4
00248       if((rPhi && recHits1D.size() == 7) || (rZ && recHits1D.size() == 11)) {
00249 
00250         if(debug) {
00251           if(rPhi && recHits1D.size() == 7)
00252             cout << "[DTEfficiencyTask] MB4 Segment with only 7 hits!" << endl;
00253           if(rZ && recHits1D.size() == 11)
00254              cout << "[DTEfficiencyTask] 4D Segment with only 11 hits!" << endl;
00255         }
00256 
00257         // Find the layer without RecHits ----------------------------------------
00258         const vector<const DTSuperLayer*> SupLayers = chamber->superLayers();
00259         map<DTLayerId, bool> layerMap; 
00260         map<DTWireId, float> wireAndPosInChamberAtLayerZ;
00261         // Loop over layers and wires to fill a map
00262         for(vector<const DTSuperLayer*>::const_iterator superlayer = SupLayers.begin();
00263             superlayer != SupLayers.end();
00264             superlayer++) {
00265           const vector<const DTLayer*> Layers = (*superlayer)->layers();
00266           for(vector<const DTLayer*>::const_iterator layer = Layers.begin();
00267               layer != Layers.end();
00268               layer++) {
00269             layerMap.insert(make_pair((*layer)->id(), false));
00270             const int firstWire = dtGeom->layer((*layer)->id())->specificTopology().firstChannel();
00271             const int lastWire = dtGeom->layer((*layer)->id())->specificTopology().lastChannel();
00272             for(int i=firstWire; i - lastWire <= 0; i++) {
00273               DTWireId wireId((*layer)->id(), i);            
00274               float wireX = (*layer)->specificTopology().wirePosition(wireId.wire());
00275               LocalPoint wirePosInLay(wireX,0,0);
00276               GlobalPoint wirePosGlob = (*layer)->toGlobal(wirePosInLay);
00277               LocalPoint wirePosInChamber = chamber->toLocal(wirePosGlob); 
00278               if((*superlayer)->id().superlayer() == 1 || (*superlayer)->id().superlayer() == 3) {
00279                 wireAndPosInChamberAtLayerZ.insert(make_pair(wireId, wirePosInChamber.x()));
00280               } else {
00281                 wireAndPosInChamberAtLayerZ.insert(make_pair(wireId, wirePosInChamber.y()));
00282               }
00283             }
00284           }
00285         }
00286 
00287         // Loop over segment 1D RecHit
00288         map<DTLayerId, int> NumWireMap; 
00289         for(vector<DTRecHit1D>::const_iterator recHit = recHits1D.begin();
00290             recHit != recHits1D.end();
00291             recHit++) {
00292           layerMap[(*recHit).wireId().layerId()]= true;
00293           NumWireMap[(*recHit).wireId().layerId()]= (*recHit).wireId().wire();
00294         }
00295 
00296         DTLayerId missLayerId;
00297         //Loop over the map and find the layer without hits
00298         for(map<DTLayerId, bool>::const_iterator iter = layerMap.begin();
00299             iter != layerMap.end(); iter++) {
00300           if(!(*iter).second) missLayerId = (*iter).first;
00301         }
00302         if(debug)
00303           cout << "[DTEfficiencyTask] Layer without recHits is: " << missLayerId << endl;
00304         // -------------------------------------------------------
00305 
00306 
00307 
00308         const DTLayer* missLayer = chamber->layer(missLayerId);
00309         
00310         LocalPoint missLayerPosInChamber = chamber->toLocal(missLayer->toGlobal(LocalPoint(0,0,0)));
00311         
00312         // Segment position at Wire z in chamber local frame
00313         LocalPoint segPosAtZLayer = (*segment4D).localPosition()
00314           + (*segment4D).localDirection()*missLayerPosInChamber.z()/cos((*segment4D).localDirection().theta());
00315         
00316         DTWireId missWireId;
00317 
00318         // Find the id of the cell without hit ---------------------------------------------------
00319         for(map<DTWireId, float>::const_iterator wireAndPos = wireAndPosInChamberAtLayerZ.begin();
00320             wireAndPos != wireAndPosInChamberAtLayerZ.end();
00321             wireAndPos++) {
00322           DTWireId wireId = (*wireAndPos).first;
00323           if(wireId.layerId() == missLayerId) {
00324             if(missLayerId.superlayerId().superlayer() == 1 || missLayerId.superlayerId().superlayer() == 3 ) {
00325               if(fabs(segPosAtZLayer.x() - (*wireAndPos).second) < 2.1)
00326                 missWireId = wireId;  
00327             } else {
00328               if(fabs(segPosAtZLayer.y() - (*wireAndPos).second) < 2.1)
00329                 missWireId = wireId;
00330             }
00331           }
00332         }
00333         if(debug)
00334           cout << "[DTEfficiencyTask] Cell without hit is: " << missWireId << endl;
00335         // ----------------------------------------------------------
00336 
00337 
00338         bool foundUnAssRechit = false;
00339 
00340         // Look for unassociated hits in this cell
00341         if(wireAnd1DRecHits.find(missWireId) != wireAnd1DRecHits.end()) {
00342           if(debug)
00343             cout << "[DTEfficiencyTask] Unassociated Hit found!" << endl;
00344           foundUnAssRechit = true;
00345         }
00346 
00347 
00348         for(map<DTLayerId, bool>::const_iterator iter = layerMap.begin();
00349             iter != layerMap.end(); iter++) {
00350           if((*iter).second) 
00351             fillHistos((*iter).first, dtGeom->layer((*iter).first)->specificTopology().firstChannel(), dtGeom->layer((*iter).first)->specificTopology().lastChannel(), NumWireMap[(*iter).first]);
00352           else
00353             fillHistos((*iter).first, dtGeom->layer((*iter).first)->specificTopology().firstChannel(), dtGeom->layer((*iter).first)->specificTopology().lastChannel(), missWireId.wire(), foundUnAssRechit);
00354         }
00355 
00356       } // End of the loop for segment with 7 or 11 recHits
00357       
00358       if((rPhi && recHits1D.size() == 8) || (rZ && recHits1D.size() == 12)) {
00359         map<DTLayerId, int> NumWireMap; 
00360         DTLayerId LayerID;
00361         for(vector<DTRecHit1D>::const_iterator recHit = recHits1D.begin();
00362             recHit != recHits1D.end();
00363             recHit++) {
00364           LayerID = (*recHit).wireId().layerId();
00365           NumWireMap[LayerID]= (*recHit).wireId().wire();
00366         }
00367         for(map<DTLayerId, int>::const_iterator iter = NumWireMap.begin();
00368             iter != NumWireMap.end(); iter++) {
00369           fillHistos((*iter).first, dtGeom->layer((*iter).first)->specificTopology().firstChannel(), dtGeom->layer((*iter).first)->specificTopology().lastChannel(), NumWireMap[(*iter).first]);
00370         }
00371       }
00372 
00373     } // End of loop over the 4D segments inside a sigle chamber
00374   } // End of loop over all tha chamber with at least a 4D segment in the event
00375 }
00376 
00377 
00378 // Book a set of histograms for a given Layer
00379 void DTEfficiencyTask::bookHistos(DTLayerId lId, int firstWire, int lastWire) {
00380   if(debug)
00381     cout << "   Booking histos for L: " << lId << endl;
00382 
00383   // Compose the chamber name
00384   stringstream wheel; wheel << lId.superlayerId().chamberId().wheel();  
00385   stringstream station; station << lId.superlayerId().chamberId().station();    
00386   stringstream sector; sector << lId.superlayerId().chamberId().sector();       
00387   stringstream superLayer; superLayer << lId.superlayerId().superlayer();       
00388   stringstream layer; layer << lId.layer();
00389 
00390   string lHistoName =
00391     "_W" + wheel.str() +
00392     "_St" + station.str() +
00393     "_Sec" + sector.str() +
00394     "_SL" + superLayer.str()+
00395     "_L" + layer.str();
00396   
00397   theDbe->setCurrentFolder("DT/DTEfficiencyTask/Wheel" + wheel.str() +
00398                            "/Station" + station.str() +
00399                            "/Sector" + sector.str() +
00400                            "/SuperLayer" +superLayer.str());
00401   // Create the monitor elements
00402   vector<MonitorElement *> histos;
00403   // histo for hits associated to the 4D reconstructed segment
00404   histos.push_back(theDbe->book1D("hEffOccupancy"+lHistoName, "4D segments recHits occupancy",lastWire-firstWire+1, firstWire-0.5, lastWire+0.5));
00405   // histo for hits not associated to the segment
00406   histos.push_back(theDbe->book1D("hEffUnassOccupancy"+lHistoName, "4D segments recHits and Hits not associated occupancy",lastWire-firstWire+1, firstWire-0.5, lastWire+0.5));
00407   // histo for cells associated to the 4D reconstructed segment
00408   histos.push_back(theDbe->book1D("hRecSegmOccupancy"+lHistoName, "4D segments cells occupancy",lastWire-firstWire+1, firstWire-0.5, lastWire+0.5));
00409   
00410   histosPerL[lId] = histos;
00411 }
00412 
00413 
00414 // Fill a set of histograms for a given Layer 
00415 void DTEfficiencyTask::fillHistos(DTLayerId lId,
00416                                   int firstWire, int lastWire,
00417                                   int numWire) {
00418   if(histosPerL.find(lId) == histosPerL.end()){
00419       bookHistos(lId, firstWire, lastWire);
00420   }
00421   vector<MonitorElement *> histos =  histosPerL[lId]; 
00422   histos[0]->Fill(numWire);
00423   histos[1]->Fill(numWire);
00424   histos[2]->Fill(numWire);
00425 }
00426 
00427 // Fill a set of histograms for a given Layer
00428 void DTEfficiencyTask::fillHistos(DTLayerId lId,
00429                                   int firstWire, int lastWire,
00430                                   int missingWire,
00431                                   bool unassHit) {
00432  if(histosPerL.find(lId) == histosPerL.end()){
00433       bookHistos(lId, firstWire, lastWire);
00434   }
00435  vector<MonitorElement *> histos =  histosPerL[lId];
00436  if(unassHit) 
00437    histos[1]->Fill(missingWire);
00438  histos[2]->Fill(missingWire);
00439 }