CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
FWECALDetailViewBuilder.cc
Go to the documentation of this file.
1 // FIXME - needed to set fixed eta-phi limits. Without the
2 // visible area may change widely depending on energy
3 // deposition availability
4 
5 #include "TEveCaloData.h"
6 #include "TEveViewer.h"
7 #include "TEveCalo.h"
8 #include "TAxis.h"
9 #include "THLimitsFinder.h"
10 #include "TLatex.h"
11 
17 
21 
22 #include "TGeoMatrix.h"
23 #include "TEveTrans.h"
24 
25 #include <utility>
26 
28 {
29  // get the hits from the event
30 
32  const EcalRecHitCollection *hits = 0;
33 
34  if (fabs(m_eta) < 1.5)
35  {
36  try
37  {
38  edm::InputTag tag("ecalRecHit", "EcalRecHitsEB");
39  m_event->getByLabel(tag, handle_hits);
40  if (handle_hits.isValid())
41  hits = &*handle_hits;
42  }
43  catch (...)
44  {
45  fwLog(fwlog::kWarning) <<"no barrel ECAL rechits are available, "
46  "showing crystal location but not energy" << std::endl;
47  }
48  }
49  else
50  {
51  try
52  {
53  edm::InputTag tag("ecalRecHit", "EcalRecHitsEE");
54  m_event->getByLabel(tag, handle_hits);
55  if (handle_hits.isValid())
56  hits = &*handle_hits;
57  }
58  catch (...)
59  {
60  fwLog(fwlog::kWarning) <<"no endcap ECAL rechits are available, "
61  "showing crystal location but not energy" << std::endl;
62  }
63  }
64 
65  // data
66  TEveCaloDataVec* data = new TEveCaloDataVec( 1 + m_colors.size() );
67  data->RefSliceInfo(0).Setup("hits (not clustered)", 0.0, m_defaultColor );
68  for( size_t i = 0; i < m_colors.size(); ++i )
69  {
70  data->RefSliceInfo(i + 1).Setup( "hits (clustered)", 0.0, m_colors[i] );
71  }
72 
73  if( handle_hits.isValid() )
74  // fill
75  fillData( hits, data );
76 
77  // axis
78  Double_t etaMin(0), etaMax(0), phiMin(0), phiMax(0);
79  // it's hard to define properly visible area in X-Y,
80  // so we rely on auto limits
81  data->GetEtaLimits(etaMin, etaMax);
82  data->GetPhiLimits(phiMin, phiMax);
83  Double_t bl, bh, bw;
84  Int_t bn, n = 20;
85  THLimitsFinder::Optimize(etaMin, etaMax, n, bl, bh, bn, bw);
86  data->SetEtaBins( new TAxis(bn, bl, bh));
87  THLimitsFinder::Optimize(phiMin, phiMax, n, bl, bh, bn, bw);
88  data->SetPhiBins( new TAxis(bn, bl, bh));
89 
90  // make tower grid
91  std::vector<double> etaBinsWithinLimits;
92  etaBinsWithinLimits.push_back(etaMin);
93  for (unsigned int i=0; i<83; ++i)
95  etaBinsWithinLimits.push_back(fw3dlego::xbins[i]);
96  etaBinsWithinLimits.push_back(etaMax);
97  Double_t* eta_bins = new Double_t[etaBinsWithinLimits.size()];
98  for (unsigned int i=0; i<etaBinsWithinLimits.size(); ++i)
99  eta_bins[i] = etaBinsWithinLimits[i];
100 
101  std::vector<double> phiBinsWithinLimits;
102  phiBinsWithinLimits.push_back(phiMin);
103  for ( double phi = -M_PI; phi < M_PI; phi += M_PI/36 )
104  if ( phi > phiMin && phi < phiMax ) // it's stupid, I know, but I'm lazy right now
105  phiBinsWithinLimits.push_back(phi);
106  phiBinsWithinLimits.push_back(phiMax);
107  Double_t* phi_bins = new Double_t[phiBinsWithinLimits.size()];
108  for (unsigned int i=0; i<phiBinsWithinLimits.size(); ++i)
109  phi_bins[i] = phiBinsWithinLimits[i];
110  if (fabs(m_eta) > 1.5) {
111  data->GetEtaBins()->SetTitle("X[cm]");
112  data->GetPhiBins()->SetTitle("Y[cm]");
113  data->GetPhiBins()->SetTitleSize(0.03);
114  data->GetEtaBins()->SetTitleSize(0.03);
115  } else {
116  data->SetEtaBins(new TAxis(etaBinsWithinLimits.size()-1,eta_bins));
117  data->SetPhiBins(new TAxis(phiBinsWithinLimits.size()-1,phi_bins));
118  data->GetEtaBins()->SetTitleFont(122);
119  data->GetEtaBins()->SetTitle("h");
120  data->GetPhiBins()->SetTitleFont(122);
121  data->GetPhiBins()->SetTitle("f");
122  data->GetPhiBins()->SetTitleSize(0.05);
123  data->GetEtaBins()->SetTitleSize(0.05);
124  }
125  delete [] eta_bins;
126  delete [] phi_bins;
127 
128  // lego
129  TEveCaloLego *lego = new TEveCaloLego(data);
130  lego->SetDrawNumberCellPixels(100);
131  // scale and translate to real world coordinates
132  lego->SetEta(etaMin, etaMax);
133  lego->SetPhiWithRng((phiMin+phiMax)*0.5, (phiMax-phiMin)*0.5); // phi range = 2* phiOffset
134  Double_t legoScale = ((etaMax - etaMin) < (phiMax - phiMin)) ? (etaMax - etaMin) : (phiMax - phiMin);
135  lego->InitMainTrans();
136  lego->RefMainTrans().SetScale(legoScale, legoScale, legoScale*0.5);
137  lego->RefMainTrans().SetPos((etaMax+etaMin)*0.5, (phiMax+phiMin)*0.5, 0);
138  lego->SetAutoRebin(kFALSE);
139  lego->Set2DMode(TEveCaloLego::kValSizeOutline);
140  lego->SetName("ECALDetail Lego");
141  return lego;
142 
143 }
144 
145 void FWECALDetailViewBuilder::setColor(Color_t color, const std::vector<DetId> &detIds)
146 {
147 
148  m_colors.push_back(color);
149 
150  // get the slice for this group of detIds
151  // note that the zeroth slice is the default one (all else)
152  int slice = m_colors.size();
153  // take a note of which slice these detids are going to go into
154  for (size_t i = 0; i < detIds.size(); ++i)
155  m_detIdsToColor[detIds[i]] = slice;
156 }
157 
158 void
160 {
161  std::vector<DetId> clusterDetIds;
162  const std::vector<std::pair<DetId, float> > &hitsAndFractions = cluster.hitsAndFractions();
163  for (size_t j = 0; j < hitsAndFractions.size(); ++j)
164  {
165  clusterDetIds.push_back(hitsAndFractions[j].first);
166  }
167 
168  setColor( color, clusterDetIds );
169 }
170 
171 void
172 FWECALDetailViewBuilder::showSuperClusters( Color_t color1, Color_t color2 )
173 {
174  // get the superclusters from the event
176 
177  if( fabs( m_eta ) < 1.5 ) {
178  try {
179  m_event->getByLabel(edm::InputTag("correctedHybridSuperClusters"), collection);
180  }
181  catch (...)
182  {
183  fwLog(fwlog::kWarning) <<"no barrel superclusters are available" << std::endl;
184  }
185  } else {
186  try {
187  m_event->getByLabel(edm::InputTag("correctedMulti5x5SuperClustersWithPreshower"), collection);
188  }
189  catch (...)
190  {
191  fwLog(fwlog::kWarning) <<"no endcap superclusters are available" << std::endl;
192  }
193  }
194  if( collection.isValid() )
195  {
196  unsigned int colorIndex = 0;
197  // sort clusters in eta so neighboring clusters have distinct colors
198  reco::SuperClusterCollection sorted = *collection.product();
199  std::sort( sorted.begin(), sorted.end(), superClusterEtaLess );
200  for( size_t i = 0; i < sorted.size(); ++i )
201  {
202  if( !(fabs(sorted[i].eta() - m_eta) < (m_size*0.0172)
203  && fabs(sorted[i].phi() - m_phi) < (m_size*0.0172)) )
204  continue;
205 
206  if( colorIndex %2 == 0 )
207  showSuperCluster( sorted[i], color1 );
208  else
209  showSuperCluster( sorted[i], color2 );
210  ++colorIndex;
211  }
212  }
213 }
214 
215 void
217  TEveCaloDataVec *data )
218 {
219  const float barrelCR = m_size*0.0172; // barrel cell range
220 
221  // loop on all the detids
222  for( EcalRecHitCollection::const_iterator k = hits->begin(), kEnd = hits->end();
223  k != kEnd; ++k )
224  {
225  // get reco geometry
226  double centerEta = 0;
227  double centerPhi = 0;
228  const float* points = m_geom->getCorners( k->id().rawId());
229  if( points != 0 )
230  {
231  TEveVector v;
232  int j = 0;
233  for( int i = 0; i < 8; ++i )
234  {
235  v += TEveVector( points[j], points[j + 1], points[j + 2] );
236  j +=3;
237  }
238  centerEta = v.Eta();
239  centerPhi = v.Phi();
240  }
241  else
242  fwLog( fwlog::kInfo ) << "cannot get geometry for DetId: "<< k->id().rawId() << ". Ignored.\n";
243 
244  double size = k->energy() / cosh( centerEta );
245 
246  // check what slice to put in
247  int slice = 0;
248  std::map<DetId, int>::const_iterator itr = m_detIdsToColor.find(k->id());
249  if (itr != m_detIdsToColor.end()) slice = itr->second;
250 
251  // if in the EB
252  if( k->id().subdetId() == EcalBarrel )
253  {
254  // do phi wrapping
255  if( centerPhi > m_phi + M_PI) centerPhi -= 2 * M_PI;
256  if( centerPhi < m_phi - M_PI) centerPhi += 2 * M_PI;
257 
258  // check if the hit is in the window to be drawn
259  if( !( fabs( centerEta - m_eta ) < barrelCR
260  && fabs( centerPhi - m_phi ) < barrelCR )) continue;
261 
262  double minEta(10), maxEta(-10), minPhi(4), maxPhi(-4);
263  if( points != 0 )
264  {
265  // calorimeter crystalls have slightly non-symetrical form in eta-phi projection
266  // so if we simply get the largest eta and phi, cells will overlap
267  // therefore we get a smaller eta-phi range representing the inner square
268  // we also should use only points from the inner face of the crystal, since
269  // non-projecting direction of crystals leads to large shift in eta on outter
270  // face.
271  int j = 0;
272  for( unsigned int i = 0; i < 8; ++i )
273  {
274  TEveVector crystal( points[j], points[j + 1], points[j + 2] );
275  j += 3;
276  double eta = crystal.Eta();
277  double phi = crystal.Phi();
278  if ( crystal.Perp() > 135 ) continue;
279  if ( minEta - eta > 0.01) minEta = eta;
280  if ( eta - minEta > 0 && eta - minEta < 0.01 ) minEta = eta;
281  if ( eta - maxEta > 0.01) maxEta = eta;
282  if ( maxEta - eta > 0 && maxEta - eta < 0.01 ) maxEta = eta;
283  if ( minPhi - phi > 0.01) minPhi = phi;
284  if ( phi - minPhi > 0 && phi - minPhi < 0.01 ) minPhi = phi;
285  if ( phi - maxPhi > 0.01) maxPhi = phi;
286  if ( maxPhi - phi > 0 && maxPhi - phi < 0.01 ) maxPhi = phi;
287  }
288  }
289  else
290  {
291  double delta = 0.0172 * 0.5;
292  minEta = centerEta - delta;
293  maxEta = centerEta + delta;
294  minPhi = centerPhi - delta;
295  maxPhi = centerPhi + delta;
296  }
297  if( minPhi >= ( m_phi - barrelCR ) && maxPhi <= ( m_phi + barrelCR ) &&
298  minEta >= ( m_eta - barrelCR ) && maxEta <= ( m_eta + barrelCR ))
299  {
300  data->AddTower( minEta, maxEta, minPhi, maxPhi );
301  data->FillSlice( slice, size );
302  }
303  // otherwise in the EE
304  }
305  else if( k->id().subdetId() == EcalEndcap )
306  {
307  // check if the hit is in the window to be drawn
308  double crystalSize = m_size * 0.0172;
309  if( !( fabs( centerEta - m_eta ) < ( crystalSize )
310  && fabs( centerPhi - m_phi ) < ( crystalSize )))
311  continue;
312 
313  if( points != 0 )
314  {
315  double minX(9999), maxX(-9999), minY(9999), maxY(-9999);
316  int j = 0;
317  for( unsigned int i = 0; i < 8; ++i )
318  {
319  TEveVector crystal( points[j], points[j + 1], points[j + 2] );
320  j += 3;
321  double x = crystal.fX;
322  double y = crystal.fY;
323  if( fabs( crystal.fZ ) > 330 ) continue;
324  if( minX - x > 0.01 ) minX = x;
325  if( x - maxX > 0.01 ) maxX = x;
326  if( minY - y > 0.01 ) minY = y;
327  if( y - maxY > 0.01 ) maxY = y;
328  }
329  data->AddTower( minX, maxX, minY, maxY );
330  }
331  data->FillSlice( slice, size );
332  }
333  } // end loop on hits
334 
335  data->DataChanged();
336  }
337 
338 double
340  Color_t clustered1, Color_t clustered2,
341  Color_t supercluster
342  )
343 {
344  Double_t fontsize = 0.07;
345  TLatex* latex = new TLatex();
346  Double_t x = x0;
347  Double_t y = y0;
348  Double_t boxH = 0.25*fontsize;
349  Double_t yStep = 0.04;
350 
351  y -= yStep;
352  latex->DrawLatex(x, y, "Energy types:");
353  y -= yStep;
354 
355  Double_t pos[4];
356  pos[0] = x+0.05;
357  pos[2] = x+0.20;
358 
359  pos[1] = y; pos[3] = pos[1] + boxH;
361  latex->DrawLatex(x+0.25, y, "unclustered");
362  y -= yStep;
363  if (clustered1<0) return y;
364 
365  pos[1] = y; pos[3] = pos[1] + boxH;
366  FWDetailViewBase::drawCanvasBox(pos, clustered1);
367  latex->DrawLatex(x+0.25, y, "clustered");
368  y -= yStep;
369  if (clustered2<0) return y;
370 
371  pos[1] = y; pos[3] = pos[1] + boxH;
372  FWDetailViewBase::drawCanvasBox(pos, clustered2);
373  latex->DrawLatex(x+0.25, y, "clustered");
374  y -= yStep;
375  if (supercluster<0) return y;
376 
377  pos[1] = y; pos[3] = pos[1] + boxH;
378  FWDetailViewBase::drawCanvasBox(pos, supercluster);
379  latex->DrawLatex(x+0.25, y, "super-cluster");
380  y -= yStep;
381 
382  return y;
383 }
dbl * delta
Definition: mlp_gen.cc:36
void showSuperCluster(const reco::SuperCluster &cluster, Color_t color=kYellow)
int i
Definition: DBlmapReader.cc:9
const double xbins[]
double makeLegend(double x0=0.02, double y0=0.95, Color_t clustered1=kGreen+1, Color_t clustered2=kTeal, Color_t supercluster=kYellow)
std::vector< T >::const_iterator const_iterator
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
Definition: CaloCluster.h:178
double maxEta
T eta() const
bool getByLabel(const InputTag &, Handle< T > &) const
Definition: EventBase.h:85
const edm::EventBase * m_event
std::map< DetId, int > m_detIdsToColor
std::vector< SuperCluster > SuperClusterCollection
collection of SuperCluser objectr
int j
Definition: DBlmapReader.cc:9
bool first
Definition: L1TdeRCT.cc:79
bool isValid() const
Definition: HandleBase.h:76
int k[5][pyjets_maxn]
const_iterator end() const
#define M_PI
Definition: BFit3D.cc:3
void showSuperClusters(Color_t color1=kGreen+2, Color_t color2=kTeal)
const float * getCorners(unsigned int id) const
Definition: FWGeometry.cc:278
void fillData(const EcalRecHitCollection *hits, TEveCaloDataVec *data)
#define fwLog(_level_)
Definition: fwLog.h:51
void setColor(Color_t color, const std::vector< DetId > &detIds)
T const * product() const
Definition: Handle.h:74
static bool superClusterEtaLess(const reco::CaloCluster &lhs, const reco::CaloCluster &rhs)
std::vector< Color_t > m_colors
tuple size
Write out results.
mathSSE::Vec4< T > v
const_iterator begin() const
static void drawCanvasBox(Double_t *pos, Color_t fillCol, Int_t fillType=0, bool bg=kTRUE)
Definition: DDAxes.h:10