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