@@ -127,6 +127,18 @@ class BtlLocalRecoValidation : public DQMEDAnalyzer {
127127 MonitorElement* meCluHits_;
128128 MonitorElement* meCluZvsPhi_;
129129
130+ MonitorElement* meCluTimeRes_;
131+ MonitorElement* meCluEnergyRes_;
132+ MonitorElement* meCluTPullvsE_;
133+ MonitorElement* meCluTPullvsEta_;
134+ MonitorElement* meCluRhoRes_;
135+ MonitorElement* meCluPhiRes_;
136+ MonitorElement* meCluXRes_;
137+ MonitorElement* meCluYRes_;
138+ MonitorElement* meCluZRes_;
139+ MonitorElement* meCluYXLocal_;
140+ MonitorElement* meCluYXLocalSim_;
141+
130142 // --- UncalibratedRecHits histograms
131143
132144 static constexpr int nBinsQ_ = 20 ;
@@ -211,7 +223,6 @@ void BtlLocalRecoValidation::analyze(const edm::Event& iEvent, const edm::EventS
211223
212224 // --- Loop over the BTL RECO hits
213225 unsigned int n_reco_btl = 0 ;
214-
215226 for (const auto & recHit : *btlRecHitsHandle) {
216227 BTLDetId detId = recHit.id ();
217228 DetId geoId = detId.geographicalId (MTDTopologyMode::crysLayoutFromTopoMode (topology->getMTDTopologyMode ()));
@@ -260,9 +271,9 @@ void BtlLocalRecoValidation::analyze(const edm::Event& iEvent, const edm::EventS
260271 float time_res = recHit.time () - m_btlSimHits[detId.rawId ()].time ;
261272 float energy_res = recHit.energy () - m_btlSimHits[detId.rawId ()].energy ;
262273
263- Local3DPoint local_point_sim (m_btlSimHits[detId.rawId ()].x_local ,
264- m_btlSimHits[detId.rawId ()].y_local ,
265- m_btlSimHits[detId.rawId ()].z_local );
274+ Local3DPoint local_point_sim (convertMmToCm ( m_btlSimHits[detId.rawId ()].x_local ) ,
275+ convertMmToCm ( m_btlSimHits[detId.rawId ()].y_local ) ,
276+ convertMmToCm ( m_btlSimHits[detId.rawId ()].z_local ) );
266277 local_point_sim =
267278 topo.pixelToModuleLocalPoint (local_point_sim, detId.row (topo.nrows ()), detId.column (topo.nrows ()));
268279 const auto & global_point_sim = thedet->toGlobal (local_point_sim);
@@ -301,8 +312,8 @@ void BtlLocalRecoValidation::analyze(const edm::Event& iEvent, const edm::EventS
301312 const ProxyMTDTopology& topoproxy = static_cast <const ProxyMTDTopology&>(genericDet->topology ());
302313 const RectangularMTDTopology& topo = static_cast <const RectangularMTDTopology&>(topoproxy.specificTopology ());
303314
304- Local3DPoint local_point (cluster. x () * topo. pitch (). first , cluster. y () * topo. pitch (). second , 0 .);
305- local_point = topo. pixelToModuleLocalPoint ( local_point, cluId. row (topo.nrows ( )), cluId. column (topo. ncolumns ()));
315+ // --- Cluster position in the module reference frame
316+ Local3DPoint local_point (topo.localX (cluster. x ( )), topo. localY (cluster. y ()), 0 . );
306317 const auto & global_point = genericDet->toGlobal (local_point);
307318
308319 meCluEnergy_->Fill (cluster.energy ());
@@ -312,8 +323,95 @@ void BtlLocalRecoValidation::analyze(const edm::Event& iEvent, const edm::EventS
312323 meCluEta_->Fill (global_point.eta ());
313324 meCluZvsPhi_->Fill (global_point.z (), global_point.phi ());
314325 meCluHits_->Fill (cluster.size ());
315- }
316- }
326+
327+ // --- Get the SIM hits associated to the cluster and calculate
328+ // the cluster SIM energy, time and position
329+
330+ double cluEneSIM = 0 .;
331+ double cluTimeSIM = 0 .;
332+ double cluLocXSIM = 0 .;
333+ double cluLocYSIM = 0 .;
334+ double cluLocZSIM = 0 .;
335+
336+ for (int ihit = 0 ; ihit < cluster.size (); ++ihit) {
337+ int hit_row = cluster.minHitRow () + cluster.hitOffset ()[ihit * 2 ];
338+ int hit_col = cluster.minHitCol () + cluster.hitOffset ()[ihit * 2 + 1 ];
339+
340+ // Match the RECO hit to the corresponding SIM hit
341+ for (const auto & recHit : *btlRecHitsHandle) {
342+ BTLDetId hitId (recHit.id ().rawId ());
343+
344+ if (m_btlSimHits.count (hitId.rawId ()) == 0 )
345+ continue ;
346+
347+ // Check the hit position
348+ if (hitId.mtdSide () != cluId.mtdSide () || hitId.mtdRR () != cluId.mtdRR () || recHit.row () != hit_row ||
349+ recHit.column () != hit_col)
350+ continue ;
351+
352+ // Check the hit energy and time
353+ if (recHit.energy () != cluster.hitENERGY ()[ihit] || recHit.time () != cluster.hitTIME ()[ihit])
354+ continue ;
355+
356+ // SIM hit's position in the module reference frame
357+ Local3DPoint local_point_sim (convertMmToCm (m_btlSimHits[recHit.id ().rawId ()].x_local ),
358+ convertMmToCm (m_btlSimHits[recHit.id ().rawId ()].y_local ),
359+ convertMmToCm (m_btlSimHits[recHit.id ().rawId ()].z_local ));
360+ local_point_sim =
361+ topo.pixelToModuleLocalPoint (local_point_sim, hitId.row (topo.nrows ()), hitId.column (topo.nrows ()));
362+
363+ // Calculate the SIM cluster's position in the module reference frame
364+ cluLocXSIM += local_point_sim.x () * m_btlSimHits[recHit.id ().rawId ()].energy ;
365+ cluLocYSIM += local_point_sim.y () * m_btlSimHits[recHit.id ().rawId ()].energy ;
366+ cluLocZSIM += local_point_sim.z () * m_btlSimHits[recHit.id ().rawId ()].energy ;
367+
368+ // Calculate the SIM cluster energy and time
369+ cluEneSIM += m_btlSimHits[recHit.id ().rawId ()].energy ;
370+ cluTimeSIM += m_btlSimHits[recHit.id ().rawId ()].time * m_btlSimHits[recHit.id ().rawId ()].energy ;
371+
372+ } // recHit loop
373+
374+ } // ihit loop
375+
376+ // --- Fill the cluster resolution histograms
377+ if (cluTimeSIM > 0 . && cluEneSIM > 0 .) {
378+ cluTimeSIM /= cluEneSIM;
379+
380+ Local3DPoint cluLocalPosSIM (cluLocXSIM / cluEneSIM, cluLocYSIM / cluEneSIM, cluLocZSIM / cluEneSIM);
381+ const auto & cluGlobalPosSIM = genericDet->toGlobal (cluLocalPosSIM);
382+
383+ float time_res = cluster.time () - cluTimeSIM;
384+ float energy_res = cluster.energy () - cluEneSIM;
385+ meCluTimeRes_->Fill (time_res);
386+ meCluEnergyRes_->Fill (energy_res);
387+
388+ float rho_res = global_point.perp () - cluGlobalPosSIM.perp ();
389+ float phi_res = global_point.phi () - cluGlobalPosSIM.phi ();
390+
391+ meCluRhoRes_->Fill (rho_res);
392+ meCluPhiRes_->Fill (phi_res);
393+
394+ if (LocalPosDebug_) {
395+ float x_res = global_point.x () - cluGlobalPosSIM.x ();
396+ float y_res = global_point.y () - cluGlobalPosSIM.y ();
397+ float z_res = global_point.z () - cluGlobalPosSIM.z ();
398+
399+ meCluXRes_->Fill (x_res);
400+ meCluYRes_->Fill (y_res);
401+ meCluZRes_->Fill (z_res);
402+
403+ meCluYXLocal_->Fill (local_point.x (), local_point.y ());
404+ meCluYXLocalSim_->Fill (cluLocalPosSIM.x (), cluLocalPosSIM.y ());
405+ }
406+
407+ meCluTPullvsEta_->Fill (std::abs (cluGlobalPosSIM.eta ()), time_res / cluster.timeError ());
408+ meCluTPullvsE_->Fill (cluEneSIM, time_res / cluster.timeError ());
409+
410+ } // if ( cluTimeSIM > 0. && cluEneSIM > 0. )
411+
412+ } // cluster loop
413+
414+ } // DetSetClu loop
317415
318416 // --- Loop over the BTL Uncalibrated RECO hits
319417 if (uncalibRecHitsPlots_) {
@@ -471,10 +569,10 @@ void BtlLocalRecoValidation::bookHistograms(DQMStore::IBooker& ibook,
471569 5 .,
472570 " S" );
473571 meTPullvsE_ = ibook.bookProfile (
474- " BtlTPullvsE" , " BTL time pull vs E;E_{SIM} [MeV];T_{RECO}-T_{SIM}/#sigma_{T_{RECO}}" , 20 , 0 ., 20 ., -5 ., 5 ., " S" );
572+ " BtlTPullvsE" , " BTL time pull vs E;E_{SIM} [MeV];( T_{RECO}-T_{SIM}) /#sigma_{T_{RECO}}" , 20 , 0 ., 20 ., -5 ., 5 ., " S" );
475573 meTPullvsEta_ = ibook.bookProfile (" BtlTPullvsEta" ,
476- " BTL time pull vs #eta;|#eta_{RECO}|;T_{RECO}-T_{SIM}/#sigma_{T_{RECO}}" ,
477- 32 ,
574+ " BTL time pull vs #eta;|#eta_{RECO}|;( T_{RECO}-T_{SIM}) /#sigma_{T_{RECO}}" ,
575+ 30 ,
478576 0 ,
479577 1.55 ,
480578 -5 .,
@@ -489,6 +587,52 @@ void BtlLocalRecoValidation::bookHistograms(DQMStore::IBooker& ibook,
489587 meCluZvsPhi_ = ibook.book2D (
490588 " BtlOccupancy" , " BTL cluster Z vs #phi;Z_{RECO} [cm]; #phi_{RECO} [rad]" , 144 , -260 ., 260 ., 50 , -3.2 , 3.2 );
491589
590+ meCluTimeRes_ = ibook.book1D (" BtlCluTimeRes" , " BTL cluster time resolution;T_{RECO}-T_{SIM} [ns]" , 100 , -0.5 , 0.5 );
591+ meCluEnergyRes_ =
592+ ibook.book1D (" BtlCluEnergyRes" , " BTL cluster energy resolution;E_{RECO}-E_{SIM} [MeV]" , 100 , -0.5 , 0.5 );
593+ meCluTPullvsE_ = ibook.bookProfile (" BtlCluTPullvsE" ,
594+ " BTL cluster time pull vs E;E_{SIM} [MeV];(T_{RECO}-T_{SIM})/#sigma_{T_{RECO}}" ,
595+ 20 ,
596+ 0 .,
597+ 20 .,
598+ -5 .,
599+ 5 .,
600+ " S" );
601+ meCluTPullvsEta_ =
602+ ibook.bookProfile (" BtlCluTPullvsEta" ,
603+ " BTL cluster time pull vs #eta;|#eta_{RECO}|;(T_{RECO}-T_{SIM})/#sigma_{T_{RECO}}" ,
604+ 30 ,
605+ 0 ,
606+ 1.55 ,
607+ -5 .,
608+ 5 .,
609+ " S" );
610+ meCluRhoRes_ =
611+ ibook.book1D (" BtlCluRhoRes" , " BTL cluster #rho resolution;#rho_{RECO}-#rho_{SIM} [cm]" , 100 , -0.5 , 0.5 );
612+ meCluPhiRes_ =
613+ ibook.book1D (" BtlCluPhiRes" , " BTL cluster #phi resolution;#phi_{RECO}-#phi_{SIM} [rad]" , 100 , -0.03 , 0.03 );
614+ if (LocalPosDebug_) {
615+ meCluXRes_ = ibook.book1D (" BtlCluXRes" , " BTL cluster X resolution;X_{RECO}-X_{SIM} [cm]" , 100 , -3.1 , 3.1 );
616+ meCluYRes_ = ibook.book1D (" BtlCluYRes" , " BTL cluster Y resolution;Y_{RECO}-Y_{SIM} [cm]" , 100 , -3.1 , 3.1 );
617+ meCluZRes_ = ibook.book1D (" BtlCluZRes" , " BTL cluster Z resolution;Z_{RECO}-Z_{SIM} [cm]" , 100 , -0.2 , 0.2 );
618+ meCluYXLocal_ = ibook.book2D (" BtlCluYXLocal" ,
619+ " BTL cluster local Y vs X;X^{local}_{RECO} [cm];Y^{local}_{RECO} [cm]" ,
620+ 200 ,
621+ -9.5 ,
622+ 9.5 ,
623+ 200 ,
624+ -2.8 ,
625+ 2.8 );
626+ meCluYXLocalSim_ = ibook.book2D (" BtlCluYXLocalSim" ,
627+ " BTL cluster local Y vs X;X^{local}_{SIM} [cm];Y^{local}_{SIM} [cm]" ,
628+ 200 ,
629+ -9.5 ,
630+ 9.5 ,
631+ 200 ,
632+ -2.8 ,
633+ 2.8 );
634+ }
635+
492636 // --- UncalibratedRecHits histograms
493637
494638 if (uncalibRecHitsPlots_) {
0 commit comments