00001
00002
00003
00004
00005 #include "TEveCaloData.h"
00006 #include "TEveViewer.h"
00007 #include "TEveCalo.h"
00008 #include "TAxis.h"
00009 #include "THLimitsFinder.h"
00010 #include "TLatex.h"
00011
00012 #include "Fireworks/Core/interface/FWDetailViewBase.h"
00013 #include "Fireworks/Calo/interface/FWECALDetailViewBuilder.h"
00014 #include "Fireworks/Core/interface/FWGeometry.h"
00015 #include "Fireworks/Core/interface/fw3dlego_xbins.h"
00016 #include "Fireworks/Core/interface/fwLog.h"
00017
00018 #include "DataFormats/FWLite/interface/Handle.h"
00019 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
00020 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00021
00022 #include "TGeoMatrix.h"
00023 #include "TEveTrans.h"
00024
00025 #include <utility>
00026
00027 TEveCaloLego* FWECALDetailViewBuilder::build()
00028 {
00029
00030
00031 edm::Handle<EcalRecHitCollection> handle_hits;
00032 const EcalRecHitCollection *hits = 0;
00033
00034 if (fabs(m_eta) < 1.5)
00035 {
00036 try
00037 {
00038 edm::InputTag tag("ecalRecHit", "EcalRecHitsEB");
00039 m_event->getByLabel(tag, handle_hits);
00040 if (handle_hits.isValid())
00041 hits = &*handle_hits;
00042 }
00043 catch (...)
00044 {
00045 fwLog(fwlog::kWarning) <<"no barrel ECAL rechits are available, "
00046 "showing crystal location but not energy" << std::endl;
00047 }
00048 }
00049 else
00050 {
00051 try
00052 {
00053 edm::InputTag tag("ecalRecHit", "EcalRecHitsEE");
00054 m_event->getByLabel(tag, handle_hits);
00055 if (handle_hits.isValid())
00056 hits = &*handle_hits;
00057 }
00058 catch (...)
00059 {
00060 fwLog(fwlog::kWarning) <<"no endcap ECAL rechits are available, "
00061 "showing crystal location but not energy" << std::endl;
00062 }
00063 }
00064
00065
00066 TEveCaloDataVec* data = new TEveCaloDataVec( 1 + m_colors.size() );
00067 data->RefSliceInfo(0).Setup("hits (not clustered)", 0.0, m_defaultColor );
00068 for( size_t i = 0; i < m_colors.size(); ++i )
00069 {
00070 data->RefSliceInfo(i + 1).Setup( "hits (clustered)", 0.0, m_colors[i] );
00071 }
00072
00073 if( handle_hits.isValid() )
00074
00075 fillData( hits, data );
00076
00077
00078 Double_t etaMin(0), etaMax(0), phiMin(0), phiMax(0);
00079
00080
00081 data->GetEtaLimits(etaMin, etaMax);
00082 data->GetPhiLimits(phiMin, phiMax);
00083 Double_t bl, bh, bw;
00084 Int_t bn, n = 20;
00085 THLimitsFinder::Optimize(etaMin, etaMax, n, bl, bh, bn, bw);
00086 data->SetEtaBins( new TAxis(bn, bl, bh));
00087 THLimitsFinder::Optimize(phiMin, phiMax, n, bl, bh, bn, bw);
00088 data->SetPhiBins( new TAxis(bn, bl, bh));
00089
00090
00091 std::vector<double> etaBinsWithinLimits;
00092 etaBinsWithinLimits.push_back(etaMin);
00093 for (unsigned int i=0; i<83; ++i)
00094 if ( fw3dlego::xbins[i] > etaMin && fw3dlego::xbins[i] < etaMax )
00095 etaBinsWithinLimits.push_back(fw3dlego::xbins[i]);
00096 etaBinsWithinLimits.push_back(etaMax);
00097 Double_t* eta_bins = new Double_t[etaBinsWithinLimits.size()];
00098 for (unsigned int i=0; i<etaBinsWithinLimits.size(); ++i)
00099 eta_bins[i] = etaBinsWithinLimits[i];
00100
00101 std::vector<double> phiBinsWithinLimits;
00102 phiBinsWithinLimits.push_back(phiMin);
00103 for ( double phi = -M_PI; phi < M_PI; phi += M_PI/36 )
00104 if ( phi > phiMin && phi < phiMax )
00105 phiBinsWithinLimits.push_back(phi);
00106 phiBinsWithinLimits.push_back(phiMax);
00107 Double_t* phi_bins = new Double_t[phiBinsWithinLimits.size()];
00108 for (unsigned int i=0; i<phiBinsWithinLimits.size(); ++i)
00109 phi_bins[i] = phiBinsWithinLimits[i];
00110 if (fabs(m_eta) > 1.5) {
00111 data->GetEtaBins()->SetTitle("X[cm]");
00112 data->GetPhiBins()->SetTitle("Y[cm]");
00113 data->GetPhiBins()->SetTitleSize(0.03);
00114 data->GetEtaBins()->SetTitleSize(0.03);
00115 } else {
00116 data->SetEtaBins(new TAxis(etaBinsWithinLimits.size()-1,eta_bins));
00117 data->SetPhiBins(new TAxis(phiBinsWithinLimits.size()-1,phi_bins));
00118 data->GetEtaBins()->SetTitleFont(122);
00119 data->GetEtaBins()->SetTitle("h");
00120 data->GetPhiBins()->SetTitleFont(122);
00121 data->GetPhiBins()->SetTitle("f");
00122 data->GetPhiBins()->SetTitleSize(0.05);
00123 data->GetEtaBins()->SetTitleSize(0.05);
00124 }
00125 delete [] eta_bins;
00126 delete [] phi_bins;
00127
00128
00129 TEveCaloLego *lego = new TEveCaloLego(data);
00130 lego->SetDrawNumberCellPixels(100);
00131
00132 lego->SetEta(etaMin, etaMax);
00133 lego->SetPhiWithRng((phiMin+phiMax)*0.5, (phiMax-phiMin)*0.5);
00134 Double_t legoScale = ((etaMax - etaMin) < (phiMax - phiMin)) ? (etaMax - etaMin) : (phiMax - phiMin);
00135 lego->InitMainTrans();
00136 lego->RefMainTrans().SetScale(legoScale, legoScale, legoScale*0.5);
00137 lego->RefMainTrans().SetPos((etaMax+etaMin)*0.5, (phiMax+phiMin)*0.5, 0);
00138 lego->SetAutoRebin(kFALSE);
00139 lego->Set2DMode(TEveCaloLego::kValSizeOutline);
00140 lego->SetName("ECALDetail Lego");
00141 return lego;
00142
00143 }
00144
00145 void FWECALDetailViewBuilder::setColor(Color_t color, const std::vector<DetId> &detIds)
00146 {
00147
00148 m_colors.push_back(color);
00149
00150
00151
00152 int slice = m_colors.size();
00153
00154 for (size_t i = 0; i < detIds.size(); ++i)
00155 m_detIdsToColor[detIds[i]] = slice;
00156 }
00157
00158 void
00159 FWECALDetailViewBuilder::showSuperCluster( const reco::SuperCluster &cluster, Color_t color )
00160 {
00161 std::vector<DetId> clusterDetIds;
00162 const std::vector<std::pair<DetId, float> > &hitsAndFractions = cluster.hitsAndFractions();
00163 for (size_t j = 0; j < hitsAndFractions.size(); ++j)
00164 {
00165 clusterDetIds.push_back(hitsAndFractions[j].first);
00166 }
00167
00168 setColor( color, clusterDetIds );
00169 }
00170
00171 void
00172 FWECALDetailViewBuilder::showSuperClusters( Color_t color1, Color_t color2 )
00173 {
00174
00175 edm::Handle<reco::SuperClusterCollection> collection;
00176
00177 if( fabs( m_eta ) < 1.5 ) {
00178 try {
00179 m_event->getByLabel(edm::InputTag("correctedHybridSuperClusters"), collection);
00180 }
00181 catch (...)
00182 {
00183 fwLog(fwlog::kWarning) <<"no barrel superclusters are available" << std::endl;
00184 }
00185 } else {
00186 try {
00187 m_event->getByLabel(edm::InputTag("correctedMulti5x5SuperClustersWithPreshower"), collection);
00188 }
00189 catch (...)
00190 {
00191 fwLog(fwlog::kWarning) <<"no endcap superclusters are available" << std::endl;
00192 }
00193 }
00194 if( collection.isValid() )
00195 {
00196 unsigned int colorIndex = 0;
00197
00198 reco::SuperClusterCollection sorted = *collection.product();
00199 std::sort( sorted.begin(), sorted.end(), superClusterEtaLess );
00200 for( size_t i = 0; i < sorted.size(); ++i )
00201 {
00202 if( !(fabs(sorted[i].eta() - m_eta) < (m_size*0.0172)
00203 && fabs(sorted[i].phi() - m_phi) < (m_size*0.0172)) )
00204 continue;
00205
00206 if( colorIndex %2 == 0 )
00207 showSuperCluster( sorted[i], color1 );
00208 else
00209 showSuperCluster( sorted[i], color2 );
00210 ++colorIndex;
00211 }
00212 }
00213 }
00214
00215 void
00216 FWECALDetailViewBuilder::fillData( const EcalRecHitCollection *hits,
00217 TEveCaloDataVec *data )
00218 {
00219 const float barrelCR = m_size*0.0172;
00220
00221
00222 for( EcalRecHitCollection::const_iterator k = hits->begin(), kEnd = hits->end();
00223 k != kEnd; ++k )
00224 {
00225
00226 double centerEta = 0;
00227 double centerPhi = 0;
00228 const float* points = m_geom->getCorners( k->id().rawId());
00229 if( points != 0 )
00230 {
00231 TEveVector v;
00232 int j = 0;
00233 for( int i = 0; i < 8; ++i )
00234 {
00235 v += TEveVector( points[j], points[j + 1], points[j + 2] );
00236 j +=3;
00237 }
00238 centerEta = v.Eta();
00239 centerPhi = v.Phi();
00240 }
00241 else
00242 fwLog( fwlog::kInfo ) << "cannot get geometry for DetId: "<< k->id().rawId() << ". Ignored.\n";
00243
00244 double size = k->energy() / cosh( centerEta );
00245
00246
00247 int slice = 0;
00248 std::map<DetId, int>::const_iterator itr = m_detIdsToColor.find(k->id());
00249 if (itr != m_detIdsToColor.end()) slice = itr->second;
00250
00251
00252 if( k->id().subdetId() == EcalBarrel )
00253 {
00254
00255 if( centerPhi > m_phi + M_PI) centerPhi -= 2 * M_PI;
00256 if( centerPhi < m_phi - M_PI) centerPhi += 2 * M_PI;
00257
00258
00259 if( !( fabs( centerEta - m_eta ) < barrelCR
00260 && fabs( centerPhi - m_phi ) < barrelCR )) continue;
00261
00262 double minEta(10), maxEta(-10), minPhi(4), maxPhi(-4);
00263 if( points != 0 )
00264 {
00265
00266
00267
00268
00269
00270
00271 int j = 0;
00272 for( unsigned int i = 0; i < 8; ++i )
00273 {
00274 TEveVector crystal( points[j], points[j + 1], points[j + 2] );
00275 j += 3;
00276 double eta = crystal.Eta();
00277 double phi = crystal.Phi();
00278 if ( crystal.Perp() > 135 ) continue;
00279 if ( minEta - eta > 0.01) minEta = eta;
00280 if ( eta - minEta > 0 && eta - minEta < 0.01 ) minEta = eta;
00281 if ( eta - maxEta > 0.01) maxEta = eta;
00282 if ( maxEta - eta > 0 && maxEta - eta < 0.01 ) maxEta = eta;
00283 if ( minPhi - phi > 0.01) minPhi = phi;
00284 if ( phi - minPhi > 0 && phi - minPhi < 0.01 ) minPhi = phi;
00285 if ( phi - maxPhi > 0.01) maxPhi = phi;
00286 if ( maxPhi - phi > 0 && maxPhi - phi < 0.01 ) maxPhi = phi;
00287 }
00288 }
00289 else
00290 {
00291 double delta = 0.0172 * 0.5;
00292 minEta = centerEta - delta;
00293 maxEta = centerEta + delta;
00294 minPhi = centerPhi - delta;
00295 maxPhi = centerPhi + delta;
00296 }
00297 if( minPhi >= ( m_phi - barrelCR ) && maxPhi <= ( m_phi + barrelCR ) &&
00298 minEta >= ( m_eta - barrelCR ) && maxEta <= ( m_eta + barrelCR ))
00299 {
00300 data->AddTower( minEta, maxEta, minPhi, maxPhi );
00301 data->FillSlice( slice, size );
00302 }
00303
00304 }
00305 else if( k->id().subdetId() == EcalEndcap )
00306 {
00307
00308 double crystalSize = m_size * 0.0172;
00309 if( !( fabs( centerEta - m_eta ) < ( crystalSize )
00310 && fabs( centerPhi - m_phi ) < ( crystalSize )))
00311 continue;
00312
00313 if( points != 0 )
00314 {
00315 double minX(9999), maxX(-9999), minY(9999), maxY(-9999);
00316 int j = 0;
00317 for( unsigned int i = 0; i < 8; ++i )
00318 {
00319 TEveVector crystal( points[j], points[j + 1], points[j + 2] );
00320 j += 3;
00321 double x = crystal.fX;
00322 double y = crystal.fY;
00323 if( fabs( crystal.fZ ) > 330 ) continue;
00324 if( minX - x > 0.01 ) minX = x;
00325 if( x - maxX > 0.01 ) maxX = x;
00326 if( minY - y > 0.01 ) minY = y;
00327 if( y - maxY > 0.01 ) maxY = y;
00328 }
00329 data->AddTower( minX, maxX, minY, maxY );
00330 }
00331 data->FillSlice( slice, size );
00332 }
00333 }
00334
00335 data->DataChanged();
00336 }
00337
00338 double
00339 FWECALDetailViewBuilder::makeLegend( double x0, double y0,
00340 Color_t clustered1, Color_t clustered2,
00341 Color_t supercluster
00342 )
00343 {
00344 Double_t fontsize = 0.07;
00345 TLatex* latex = new TLatex();
00346 Double_t x = x0;
00347 Double_t y = y0;
00348 Double_t boxH = 0.25*fontsize;
00349 Double_t yStep = 0.04;
00350
00351 y -= yStep;
00352 latex->DrawLatex(x, y, "Energy types:");
00353 y -= yStep;
00354
00355 Double_t pos[4];
00356 pos[0] = x+0.05;
00357 pos[2] = x+0.20;
00358
00359 pos[1] = y; pos[3] = pos[1] + boxH;
00360 FWDetailViewBase::drawCanvasBox(pos, m_defaultColor);
00361 latex->DrawLatex(x+0.25, y, "unclustered");
00362 y -= yStep;
00363 if (clustered1<0) return y;
00364
00365 pos[1] = y; pos[3] = pos[1] + boxH;
00366 FWDetailViewBase::drawCanvasBox(pos, clustered1);
00367 latex->DrawLatex(x+0.25, y, "clustered");
00368 y -= yStep;
00369 if (clustered2<0) return y;
00370
00371 pos[1] = y; pos[3] = pos[1] + boxH;
00372 FWDetailViewBase::drawCanvasBox(pos, clustered2);
00373 latex->DrawLatex(x+0.25, y, "clustered");
00374 y -= yStep;
00375 if (supercluster<0) return y;
00376
00377 pos[1] = y; pos[3] = pos[1] + boxH;
00378 FWDetailViewBase::drawCanvasBox(pos, supercluster);
00379 latex->DrawLatex(x+0.25, y, "super-cluster");
00380 y -= yStep;
00381
00382 return y;
00383 }