TEveCaloData.cxx

Go to the documentation of this file.
00001 // @(#)root/eve:$Id: TEveCaloData.cxx 36816 2010-11-20 22:41:48Z matevz $
00002 // Author: Matevz Tadel 2007
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "TEveCaloData.h"
00013 #include "TEveCalo.h"
00014 
00015 #include "TGLSelectRecord.h"
00016 
00017 #include "TAxis.h"
00018 #include "THStack.h"
00019 #include "TH2.h"
00020 #include "TMath.h"
00021 #include "TList.h"
00022 
00023 #include <cassert>
00024 #include <algorithm>
00025 #include <set>
00026 
00027 //------------------------------------------------------------------------------
00028 // TEveCaloData::CellGeom_t
00029 //------------------------------------------------------------------------------
00030 
00031 
00032 //______________________________________________________________________________
00033 void TEveCaloData::CellGeom_t::Dump() const
00034 {
00035    // Print member data.
00036 
00037    printf("%f, %f %f, %f \n", fEtaMin, fEtaMax, fPhiMin, fPhiMax);
00038 }
00039 
00040 //______________________________________________________________________________
00041 void TEveCaloData::CellGeom_t::Configure(Float_t etaMin, Float_t etaMax, Float_t phiMin, Float_t phiMax)
00042 {
00043    fEtaMin = etaMin;
00044    fEtaMax = etaMax;
00045 
00046    fPhiMin = phiMin;
00047    fPhiMax = phiMax;
00048 
00049    fThetaMin = EtaToTheta(fEtaMax);
00050    fThetaMax = EtaToTheta(fEtaMin);
00051 }
00052 
00053 //------------------------------------------------------------------------------
00054 // TEveCaloData::CellData_t
00055 //------------------------------------------------------------------------------
00056 
00057 //______________________________________________________________________________
00058 Float_t TEveCaloData::CellData_t::Value(Bool_t isEt) const
00059 {
00060    // Return energy value associated with the cell, usually Et.
00061    // If isEt is false it is transformed into energy E.
00062 
00063    if (isEt)
00064       return fValue;
00065    else
00066       return TMath::Abs(fValue/TMath::Sin(Theta()));
00067 }
00068 
00069 //______________________________________________________________________________
00070 void TEveCaloData::CellData_t::Dump() const
00071 {
00072    // Print member data.
00073 
00074    printf("%f, %f %f, %f \n", fEtaMin, fEtaMax, fPhiMin, fPhiMax);
00075 }
00076 
00077 //______________________________________________________________________________
00078 Float_t* TEveCaloData::RebinData_t::GetSliceVals(Int_t bin)
00079 {
00080 
00081    //   printf("get val vec bin %d size %d\n", bin, fBinData.size());
00082    if (fBinData[bin] == -1)
00083    {
00084       fBinData[bin] = fSliceData.size();
00085 
00086       for (Int_t i=0; i<fNSlices; i++)
00087          fSliceData.push_back(0.f);
00088    }
00089 
00090    return &fSliceData[fBinData[bin]];
00091 }
00092 
00093 //==============================================================================
00094 // TEveCaloData
00095 //==============================================================================
00096 
00097 //______________________________________________________________________________
00098 //
00099 //  A central manager for calorimeter event data. It provides a list of
00100 //  cells within requested phi and eta range.
00101 //
00102 
00103 ClassImp(TEveCaloData);
00104 
00105 //______________________________________________________________________________
00106 TEveCaloData::TEveCaloData(const char* n, const char* t):
00107    TEveElement(),
00108    TNamed(n, t),
00109 
00110    fEtaAxis(0),
00111    fPhiAxis(0),
00112 
00113    fWrapTwoPi(kTRUE),
00114 
00115    fMaxValEt(0),
00116    fMaxValE(0),
00117 
00118    fEps(0)
00119 {
00120    // Constructor.
00121 }
00122 
00123 //______________________________________________________________________________
00124 void TEveCaloData::UnSelected()
00125 {
00126    // Virtual method TEveElement::UnSelect.
00127    // Clear selected towers when deselected.
00128 
00129    fCellsSelected.clear();
00130 }
00131 
00132 //______________________________________________________________________________
00133 void TEveCaloData::UnHighlighted()
00134 {
00135    // Virtual method TEveElement::UnHighlighted.
00136 
00137    fCellsHighlighted.clear();
00138 }
00139 
00140 //______________________________________________________________________________
00141 TString TEveCaloData::GetHighlightTooltip()
00142 {
00143    if (fCellsHighlighted.empty()) return "";
00144 
00145    CellData_t cellData;
00146 
00147    Bool_t single = fCellsHighlighted.size() == 1;
00148    Float_t sum = 0;
00149    TString s;
00150    for (vCellId_i i = fCellsHighlighted.begin(); i!=fCellsHighlighted.end(); ++i)
00151    {
00152       GetCellData(*i, cellData);
00153       
00154       s += TString::Format("%s %.2f (%.3f, %.3f)", 
00155                            fSliceInfos[i->fSlice].fName.Data(), cellData.fValue,
00156                            cellData.Eta(), cellData.Phi());
00157 
00158       if (single) return s;
00159       s += "\n";
00160       sum += cellData.fValue;
00161    }
00162    s += TString::Format("Sum = %.2f", sum);
00163    return s;
00164 }
00165 
00166 //______________________________________________________________________________
00167 void TEveCaloData::FillImpliedSelectedSet(Set_t& impSelSet)
00168 {
00169    // Populate set impSelSet with derived / dependant elements.
00170    //
00171 
00172    for (List_ci i=fChildren.begin(); i!=fChildren.end(); ++i)
00173    {
00174       impSelSet.insert(*i);
00175    }
00176 }
00177 
00178 //______________________________________________________________________________
00179 void TEveCaloData::PrintCellsSelected()
00180 {
00181    // Print selected cells info.
00182 
00183    printf("%d Selected selected cells:\n", (Int_t)fCellsSelected.size());
00184    CellData_t cellData;
00185 
00186    for (vCellId_i i = fCellsSelected.begin(); i != fCellsSelected.end(); ++i)
00187    {
00188       GetCellData(*i, cellData);
00189       printf("Tower [%d] Slice [%d] Value [%.2f] ", i->fTower, i->fSlice, cellData.fValue);
00190       printf("Eta:(%f, %f) Phi(%f, %f)\n",  cellData.fEtaMin, cellData.fEtaMax, cellData.fPhiMin, cellData.fPhiMax);
00191    }
00192 }
00193 
00194 //______________________________________________________________________________
00195 void TEveCaloData::ProcessSelection(vCellId_t& sel_cells, TGLSelectRecord& rec)
00196 {
00197    // Process newly selected cells with given select-record.
00198    // Secondary-select status is set.
00199    // CellSelectionChanged() is called if needed.
00200 
00201    typedef std::set<CellId_t>           sCellId_t;
00202    typedef std::set<CellId_t>::iterator sCellId_i;
00203 
00204    struct helper
00205    {
00206       static void fill_cell_set(sCellId_t& cset, vCellId_t& cvec)
00207       {
00208          for (vCellId_i i = cvec.begin(); i != cvec.end(); ++i)
00209             cset.insert(*i);
00210       }
00211       static void fill_cell_vec(vCellId_t& cvec, sCellId_t& cset)
00212       {
00213          for (sCellId_i i = cset.begin(); i != cset.end(); ++i)
00214             cvec.push_back(*i);
00215       }
00216    };
00217 
00218    vCellId_t& cells = rec.GetHighlight() ? fCellsHighlighted : fCellsSelected;
00219  
00220    if (cells.empty())
00221    {
00222       if (!sel_cells.empty())
00223       {
00224          cells.swap(sel_cells);
00225          rec.SetSecSelResult(TGLSelectRecord::kEnteringSelection);
00226       }
00227    }
00228    else
00229    {
00230       if (!sel_cells.empty())
00231       {
00232          if (rec.GetMultiple())
00233          {
00234             sCellId_t cs;
00235             helper::fill_cell_set(cs, cells);
00236             for (vCellId_i i = sel_cells.begin(); i != sel_cells.end(); ++i)
00237             {
00238                std::set<CellId_t>::iterator csi = cs.find(*i);
00239                if (csi == cs.end())
00240                   cs.insert(*i);
00241                else
00242                   cs.erase(csi);
00243             }
00244             cells.clear();
00245             if (cs.empty())
00246             {
00247                rec.SetSecSelResult(TGLSelectRecord::kLeavingSelection);
00248             }
00249             else
00250             {
00251                helper::fill_cell_vec(cells, cs);
00252                rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
00253             }
00254          }
00255          else
00256          {
00257             Bool_t differ = kFALSE;
00258             if (cells.size() == sel_cells.size())
00259             {
00260                sCellId_t cs;
00261                helper::fill_cell_set(cs, cells);
00262                for (vCellId_i i = sel_cells.begin(); i != sel_cells.end(); ++i)
00263                {
00264                   if (cs.find(*i) == cs.end())
00265                   {
00266                      differ = kTRUE;
00267                      break;
00268                   }
00269                }
00270             }
00271             else
00272             {
00273                differ = kTRUE;
00274             }
00275             if (differ)
00276             {
00277                cells.swap(sel_cells);
00278                rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
00279             }
00280          }
00281       }
00282       else
00283       {
00284          if (!rec.GetMultiple())
00285          {
00286             cells.clear();
00287             rec.SetSecSelResult(TGLSelectRecord::kLeavingSelection);
00288          }
00289       }
00290    }
00291 
00292    if (rec.GetSecSelResult() != TGLSelectRecord::kNone)
00293    {
00294       CellSelectionChanged();
00295    }
00296 }
00297 
00298 
00299 //==============================================================================
00300 
00301 //______________________________________________________________________________
00302 void TEveCaloData::SetSliceThreshold(Int_t slice, Float_t val)
00303 {
00304    // Set threshold for given slice.
00305 
00306    fSliceInfos[slice].fThreshold = val;
00307    InvalidateUsersCellIdCache();
00308 }
00309 
00310 //______________________________________________________________________________
00311 Float_t TEveCaloData::GetSliceThreshold(Int_t slice) const
00312 {
00313    // Get threshold for given slice.
00314 
00315    return fSliceInfos[slice].fThreshold;
00316 }
00317 
00318 //______________________________________________________________________________
00319 void TEveCaloData::SetSliceColor(Int_t slice, Color_t col)
00320 {
00321    // Set color for given slice.
00322 
00323    fSliceInfos[slice].fColor = col;
00324    for (List_ci i=fChildren.begin(); i!=fChildren.end(); ++i)
00325    {
00326       (*i)->AddStamp(TEveElement::kCBObjProps);
00327    }
00328 }
00329 
00330 //______________________________________________________________________________
00331 Color_t TEveCaloData::GetSliceColor(Int_t slice) const
00332 {
00333    // Get color for given slice.
00334 
00335    return fSliceInfos[slice].fColor;
00336 }
00337 
00338 //______________________________________________________________________________
00339 void TEveCaloData::SetSliceTransparency(Int_t slice, Char_t t)
00340 {
00341    // Set transparency for given slice.
00342 
00343    fSliceInfos[slice].fTransparency = t;
00344    for (List_ci i=fChildren.begin(); i!=fChildren.end(); ++i)
00345    {
00346       (*i)->AddStamp(TEveElement::kCBObjProps);
00347    }
00348 }
00349 
00350 //______________________________________________________________________________
00351 Char_t TEveCaloData::GetSliceTransparency(Int_t slice) const
00352 {
00353    // Get transparency for given slice.
00354 
00355    return fSliceInfos[slice].fTransparency;
00356 }
00357 
00358 //______________________________________________________________________________
00359 void TEveCaloData::InvalidateUsersCellIdCache()
00360 {
00361    // Invalidate cell ids cache on back ptr references.
00362 
00363    TEveCaloViz* calo;
00364    for (List_ci i=fChildren.begin(); i!=fChildren.end(); ++i)
00365    {
00366       calo = dynamic_cast<TEveCaloViz*>(*i);
00367       calo->InvalidateCellIdCache();
00368       calo->StampObjProps();
00369    }
00370 }
00371 
00372 //______________________________________________________________________________
00373 void TEveCaloData::DataChanged()
00374 {
00375    // Tell users (TEveCaloViz instances using this data) that data
00376    // has changed and they should update the limits/scales etc.
00377    // This is done by calling TEveCaloViz::DataChanged().
00378 
00379    TEveCaloViz* calo;
00380    for (List_ci i=fChildren.begin(); i!=fChildren.end(); ++i)
00381    {
00382       calo = dynamic_cast<TEveCaloViz*>(*i);
00383       calo->DataChanged();
00384       calo->StampObjProps();
00385    }
00386 }
00387 
00388 //______________________________________________________________________________
00389 void TEveCaloData::CellSelectionChanged()
00390 {
00391    // Tell users (TEveCaloViz instances using this data) that cell selection
00392    // has changed and they should update selection cache if necessary. 
00393    // This is done by calling TEveCaloViz::CellSelectionChanged().
00394 
00395    TEveCaloViz* calo;
00396    for (List_ci i=fChildren.begin(); i!=fChildren.end(); ++i)
00397    {
00398       calo = dynamic_cast<TEveCaloViz*>(*i);
00399       calo->CellSelectionChanged();
00400       calo->StampColorSelection();
00401    }
00402 }
00403 
00404 //______________________________________________________________________________
00405 Float_t TEveCaloData::EtaToTheta(Float_t eta)
00406 {
00407    using namespace TMath;
00408 
00409    if (eta < 0)
00410       return Pi() - 2*ATan(Exp(- Abs(eta)));
00411    else
00412       return 2*ATan(Exp(- Abs(eta)));
00413 }
00414 
00415 
00416 //==============================================================================
00417 // TEveCaloDataVec
00418 //==============================================================================
00419 
00420 //______________________________________________________________________________
00421 //
00422 // Calo data for universal cell geometry.
00423 
00424 ClassImp(TEveCaloDataVec);
00425 
00426 //______________________________________________________________________________
00427 TEveCaloDataVec::TEveCaloDataVec(Int_t nslices):
00428    TEveCaloData(),
00429 
00430    fTower(0),
00431    fEtaMin( 1e3),
00432    fEtaMax(-1e3),
00433    fPhiMin( 1e3),
00434    fPhiMax(-1e3)
00435 {
00436    // Constructor.
00437 
00438    fSliceInfos.assign(nslices, SliceInfo_t());
00439 
00440    fSliceVec.assign(nslices, std::vector<Float_t> ());
00441 }
00442 
00443 //______________________________________________________________________________
00444 TEveCaloDataVec::~TEveCaloDataVec()
00445 {
00446    // Destructor.
00447 
00448    if (fEtaAxis) delete fEtaAxis;
00449    if (fPhiAxis) delete fPhiAxis;
00450 }
00451 
00452 //______________________________________________________________________________
00453 Int_t TEveCaloDataVec::AddSlice()
00454 {
00455   // Add new slice.
00456   
00457   fSliceInfos.push_back(SliceInfo_t());
00458   fSliceVec.push_back(std::vector<Float_t> ()); 
00459   fSliceVec.back().resize(fGeomVec.size(), 0.f);
00460 
00461   return fSliceInfos.size() - 1;
00462 }
00463   
00464 //______________________________________________________________________________
00465 Int_t TEveCaloDataVec::AddTower(Float_t etaMin, Float_t etaMax, Float_t phiMin, Float_t phiMax)
00466 {
00467    // Add tower within eta/phi range.
00468 
00469    assert (etaMin < etaMax);
00470    assert (phiMin < phiMax);
00471 
00472    fGeomVec.push_back(CellGeom_t(etaMin, etaMax, phiMin, phiMax));
00473 
00474    for (vvFloat_i it=fSliceVec.begin(); it!=fSliceVec.end(); ++it)
00475       (*it).push_back(0);
00476 
00477    if (etaMin < fEtaMin) fEtaMin = etaMin;
00478    if (etaMax > fEtaMax) fEtaMax = etaMax;
00479 
00480    if (phiMin < fPhiMin) fPhiMin = phiMin;
00481    if (phiMax > fPhiMax) fPhiMax = phiMax;
00482   
00483    fTower = fGeomVec.size() - 1;
00484    return fTower;
00485 }
00486 
00487 //______________________________________________________________________________
00488 void TEveCaloDataVec::FillSlice(Int_t slice, Float_t val)
00489 {
00490    // Fill given slice in the current tower.
00491 
00492    fSliceVec[slice][fTower] = val;
00493 }
00494 
00495 //______________________________________________________________________________
00496 void TEveCaloDataVec::FillSlice(Int_t slice, Int_t tower, Float_t val)
00497 {
00498    // Fill given slice in a given tower.
00499 
00500    fSliceVec[slice][tower] = val;
00501 }
00502 
00503 
00504 //______________________________________________________________________________
00505 void TEveCaloDataVec::GetCellList(Float_t eta, Float_t etaD,
00506                                   Float_t phi, Float_t phiD,
00507                                   TEveCaloData::vCellId_t &out) const
00508 {
00509    // Get list of cell-ids for given eta/phi range.
00510 
00511    using namespace TMath;
00512 
00513    Float_t etaMin = eta - etaD*0.5;
00514    Float_t etaMax = eta + etaD*0.5;
00515 
00516    Float_t phiMin = phi - phiD*0.5;
00517    Float_t phiMax = phi + phiD*0.5;
00518 
00519    Int_t nS = fSliceVec.size();
00520 
00521    Int_t tower = 0;
00522    Float_t fracx=0, fracy=0, frac;
00523    Float_t minQ, maxQ;
00524 
00525    for(vCellGeom_ci i=fGeomVec.begin(); i!=fGeomVec.end(); i++)
00526    {
00527       const CellGeom_t &cg = *i;
00528       fracx = TEveUtil::GetFraction(etaMin, etaMax, cg.fEtaMin, cg.fEtaMax);
00529       if (fracx > 1e-3)
00530       {
00531          minQ = cg.fPhiMin;
00532          maxQ = cg.fPhiMax;
00533 
00534          if (fWrapTwoPi)
00535          {
00536             if (maxQ < phiMin)
00537             {
00538                minQ += TwoPi(); maxQ += TwoPi();
00539             }
00540             else if (minQ > phiMax)
00541             {
00542                minQ -= TwoPi(); maxQ -= TwoPi();
00543             }
00544          }
00545 
00546          if (maxQ >= phiMin && minQ <= phiMax)
00547          {
00548             fracy = TEveUtil::GetFraction(phiMin, phiMax, minQ, maxQ);
00549             if (fracy > 1e-3)
00550             {
00551                frac = fracx*fracy;
00552                for (Int_t s=0; s<nS; s++)
00553                {
00554                   if (fSliceVec[s][tower] > fSliceInfos[s].fThreshold)
00555                      out.push_back(CellId_t(tower, s, frac));
00556                }
00557             }
00558          }
00559       }
00560       tower++;
00561    }
00562 }
00563 
00564 //______________________________________________________________________________
00565 void TEveCaloDataVec::Rebin(TAxis* ax, TAxis* ay, vCellId_t &ids, Bool_t et, RebinData_t& rdata) const
00566 {
00567    // Rebin cells.
00568 
00569    rdata.fNSlices = GetNSlices();
00570    rdata.fBinData.assign((ax->GetNbins()+2)*(ay->GetNbins()+2), -1);
00571 
00572    CellData_t cd;
00573    for (vCellId_i it = ids.begin(); it != ids.end(); ++it)
00574    {
00575       GetCellData(*it, cd);
00576       Int_t iMin = ax->FindBin(cd.EtaMin());
00577       Int_t iMax = ax->FindBin(cd.EtaMax());
00578       Int_t jMin = ay->FindBin(cd.PhiMin());
00579       Int_t jMax = ay->FindBin(cd.PhiMax());
00580       for (Int_t i = iMin; i <= iMax; ++i)
00581       {
00582          if (i < 0 || i > ax->GetNbins()) continue;
00583          for (Int_t j = jMin; j <= jMax; ++j)
00584          {
00585             if (j < 0 || j > ay->GetNbins()) continue;
00586 
00587             Double_t ratio = TEveUtil::GetFraction(ax->GetBinLowEdge(i), ax->GetBinUpEdge(i), cd.EtaMin(), cd.EtaMax())
00588                            * TEveUtil::GetFraction(ay->GetBinLowEdge(j), ay->GetBinUpEdge(j), cd.PhiMin(), cd.PhiMax());
00589             
00590             if (ratio > 1e-6f)
00591             {
00592                Float_t* slices = rdata.GetSliceVals(i + j*(ax->GetNbins()+2));
00593                slices[(*it).fSlice] += ratio * cd.Value(et);
00594             }
00595          }
00596       }
00597    }
00598 }
00599 
00600 //______________________________________________________________________________
00601 void TEveCaloDataVec::GetCellData(const TEveCaloData::CellId_t &id,
00602                                   TEveCaloData::CellData_t& cellData) const
00603 {
00604    // Get cell geometry and value from cell ID.
00605 
00606    cellData.CellGeom_t::operator=( fGeomVec[id.fTower] );
00607    cellData.fValue = fSliceVec[id.fSlice][id.fTower];
00608 }
00609 
00610 //______________________________________________________________________________
00611 void TEveCaloDataVec::DataChanged()
00612 {
00613    // Update limits and notify data users.
00614 
00615    using namespace TMath;
00616 
00617    // update max E/Et values
00618 
00619    fMaxValE = 0;
00620    fMaxValEt = 0;
00621    Float_t sum=0;
00622    //   printf("geom vec %d slices %d\n",fGeomVec.size(), fSliceVec.size() );
00623 
00624    for (UInt_t tw=0; tw<fGeomVec.size(); tw++)
00625    {
00626       sum=0;
00627       for (vvFloat_i it=fSliceVec.begin(); it!=fSliceVec.end(); ++it)
00628          sum += (*it)[tw];
00629 
00630       if (sum > fMaxValEt ) fMaxValEt=sum;
00631 
00632       sum /= Abs(Sin(EtaToTheta(fGeomVec[tw].Eta())));
00633 
00634       if (sum > fMaxValE) fMaxValE=sum;
00635    }
00636 
00637    TEveCaloData::DataChanged();
00638 }
00639 
00640 
00641 //______________________________________________________________________________
00642 void  TEveCaloDataVec::SetAxisFromBins(Double_t epsX, Double_t epsY)
00643 {
00644    // Set XY axis from cells geometry.
00645 
00646    std::vector<Double_t> binX;
00647    std::vector<Double_t> binY;
00648 
00649    for(vCellGeom_ci i=fGeomVec.begin(); i!=fGeomVec.end(); i++)
00650    {
00651       const CellGeom_t &ch = *i;
00652 
00653       binX.push_back(ch.EtaMin());
00654       binX.push_back(ch.EtaMax());
00655       binY.push_back(ch.PhiMin());
00656       binY.push_back(ch.PhiMax());
00657    }
00658 
00659    std::sort(binX.begin(), binX.end());
00660    std::sort(binY.begin(), binY.end());
00661 
00662    Int_t cnt = 0;
00663    Double_t sum = 0;
00664    Double_t val;
00665 
00666    // X axis
00667    Double_t dx = binX.back() - binX.front();
00668    epsX *= dx;
00669    std::vector<Double_t> newX;
00670    newX.push_back(binX.front()); // underflow
00671    Int_t nX = binX.size()-1;
00672    for(Int_t i=0; i<nX; i++)
00673    {
00674       val = (sum +binX[i])/(cnt+1);
00675       if (binX[i+1] -val > epsX)
00676       {
00677          newX.push_back(val);
00678          cnt = 0;
00679          sum = 0;
00680       }
00681       else
00682       {
00683          sum += binX[i];
00684          cnt++;
00685       }
00686    }
00687    newX.push_back(binX.back()); // overflow
00688 
00689    // Y axis
00690    cnt = 0;
00691    sum = 0;
00692    std::vector<Double_t> newY;
00693    Double_t dy = binY.back() - binY.front();
00694    epsY *= dy;
00695    newY.push_back(binY.front());// underflow
00696    Int_t nY = binY.size()-1;
00697    for(Int_t i=0 ; i<nY; i++)
00698    {
00699       val = (sum +binY[i])/(cnt+1);
00700       if (binY[i+1] -val > epsY )
00701       {
00702          newY.push_back(val);
00703          cnt = 0;
00704          sum = 0;
00705       }
00706       else
00707       {
00708          sum += binY[i];
00709          cnt++;
00710       }
00711 
00712    }
00713    newY.push_back(binY.back()); // overflow
00714 
00715    if (fEtaAxis) delete fEtaAxis;
00716    if (fPhiAxis) delete fPhiAxis;
00717 
00718    fEtaAxis = new TAxis(newX.size()-1, &newX[0]);
00719    fPhiAxis = new TAxis(newY.size()-1, &newY[0]);
00720    fEtaAxis->SetNdivisions(510);
00721    fPhiAxis->SetNdivisions(510);
00722 }
00723 
00724 //==============================================================================
00725 // TEveCaloDataHist
00726 //==============================================================================
00727 
00728 //______________________________________________________________________________
00729 //
00730 // A central manager for calorimeter data of an event written in TH2F.
00731 // X axis is used for eta and Y axis for phi.
00732 //
00733 
00734 ClassImp(TEveCaloDataHist);
00735 
00736 //______________________________________________________________________________
00737 TEveCaloDataHist::TEveCaloDataHist():
00738    TEveCaloData(),
00739 
00740    fHStack(0)
00741 {
00742    // Constructor.
00743 
00744    fHStack = new THStack();
00745    fEps    = 1e-5;
00746 }
00747 
00748 //______________________________________________________________________________
00749 TEveCaloDataHist::~TEveCaloDataHist()
00750 {
00751    // Destructor.
00752 
00753    delete fHStack;
00754 }
00755 
00756 //______________________________________________________________________________
00757 void TEveCaloDataHist::DataChanged()
00758 {
00759    // Update limits and notify data users.
00760 
00761    using namespace TMath;
00762 
00763    // update max E/Et values
00764    fMaxValE  = 0;
00765    fMaxValEt = 0;
00766 
00767    if (GetNSlices() < 1) return;
00768 
00769    TH2* hist = GetHist(0);
00770    fEtaAxis  = hist->GetXaxis();
00771    fPhiAxis  = hist->GetYaxis();
00772    for (Int_t ieta = 1; ieta <= fEtaAxis->GetNbins(); ++ieta)
00773    {
00774       Double_t eta = fEtaAxis->GetBinCenter(ieta); // conversion E/Et
00775       for (Int_t iphi = 1; iphi <= fPhiAxis->GetNbins(); ++iphi)
00776       {
00777          Double_t value = 0;
00778          for (Int_t i = 0; i < GetNSlices(); ++i)
00779          {
00780             hist = GetHist(i);
00781             Int_t bin = hist->GetBin(ieta, iphi);
00782             value += hist->GetBinContent(bin);
00783          }
00784 
00785          if (value > fMaxValEt ) fMaxValEt = value;
00786 
00787          value /= Abs(Sin(EtaToTheta(eta)));
00788 
00789          if (value > fMaxValE) fMaxValE = value;
00790       }
00791    }
00792    TEveCaloData::DataChanged();
00793 }
00794 
00795 //______________________________________________________________________________
00796 void TEveCaloDataHist::GetCellList(Float_t eta, Float_t etaD,
00797                                    Float_t phi, Float_t phiD,
00798                                    TEveCaloData::vCellId_t &out) const
00799 {
00800    // Get list of cell IDs in given eta and phi range.
00801 
00802    using namespace TMath;
00803 
00804    Float_t etaMin = eta - etaD*0.5 -fEps;
00805    Float_t etaMax = eta + etaD*0.5 +fEps;
00806 
00807    Float_t phiMin = phi - phiD*0.5 -fEps;
00808    Float_t phiMax = phi + phiD*0.5 +fEps;
00809 
00810    Int_t nEta = fEtaAxis->GetNbins();
00811    Int_t nPhi = fPhiAxis->GetNbins();
00812    Int_t nSlices = GetNSlices();
00813 
00814    Int_t bin  = 0;
00815 
00816    Bool_t accept;
00817    for (Int_t ieta = 1; ieta <= nEta; ++ieta)
00818    {
00819       if (fEtaAxis->GetBinLowEdge(ieta) >= etaMin && fEtaAxis->GetBinUpEdge(ieta) <= etaMax)
00820       {
00821          for (Int_t iphi = 1; iphi <= nPhi; ++iphi)
00822          {
00823             if (fWrapTwoPi )
00824             {
00825                accept = TEveUtil::IsU1IntervalContainedByMinMax
00826                   (phiMin, phiMax, fPhiAxis->GetBinLowEdge(iphi), fPhiAxis->GetBinUpEdge(iphi));
00827             }
00828             else
00829             {
00830                accept = fPhiAxis->GetBinLowEdge(iphi) >= phiMin &&  fPhiAxis->GetBinUpEdge(iphi) <= phiMax &&
00831                   fPhiAxis->GetBinLowEdge(iphi) >= phiMin &&  fPhiAxis->GetBinUpEdge(iphi) <= phiMax;
00832             }
00833 
00834             if (accept)
00835             {
00836                for (Int_t s = 0; s < nSlices; ++s)
00837                {
00838                   TH2F *hist = GetHist(s);
00839                   bin = hist->GetBin(ieta, iphi);
00840                   if (hist->GetBinContent(bin) > fSliceInfos[s].fThreshold)
00841                      out.push_back(TEveCaloData::CellId_t(bin, s));
00842                } // hist slices
00843             }
00844          } // phi bins
00845       }
00846    } // eta bins
00847 }
00848 
00849 
00850 //______________________________________________________________________________
00851 void TEveCaloDataHist::Rebin(TAxis* ax, TAxis* ay, TEveCaloData::vCellId_t &ids, Bool_t et, RebinData_t &rdata) const
00852 {
00853    rdata.fNSlices = GetNSlices();
00854    rdata.fBinData.assign((ax->GetNbins()+2)*(ay->GetNbins()+2), -1);
00855    TEveCaloData::CellData_t cd;
00856    Float_t *val;
00857    Int_t i, j, w;
00858    Int_t binx, biny;
00859    Int_t bin;
00860 
00861    for (vCellId_i it=ids.begin(); it!=ids.end(); ++it)
00862    {
00863       GetCellData(*it, cd);
00864       GetHist(it->fSlice)->GetBinXYZ((*it).fTower, i, j, w);
00865       binx = ax->FindBin(fEtaAxis->GetBinCenter(i));
00866       biny = ay->FindBin(fPhiAxis->GetBinCenter(j));
00867       bin = biny*(ax->GetNbins()+2)+binx;
00868       val = rdata.GetSliceVals(bin);
00869       Double_t ratio = TEveUtil::GetFraction(ax->GetBinLowEdge(binx), ax->GetBinUpEdge(binx), cd.EtaMin(), cd.EtaMax())
00870                      * TEveUtil::GetFraction(ay->GetBinLowEdge(biny), ay->GetBinUpEdge(biny), cd.PhiMin(), cd.PhiMax());
00871       
00872       val[(*it).fSlice] += cd.Value(et)*ratio;
00873    }
00874 }
00875 
00876 //______________________________________________________________________________
00877 void TEveCaloDataHist::GetCellData(const TEveCaloData::CellId_t &id,
00878                                    TEveCaloData::CellData_t& cellData) const
00879 {
00880    // Get cell geometry and value from cell ID.
00881 
00882    TH2F* hist = GetHist(id.fSlice);
00883 
00884    Int_t x, y, z;
00885    hist->GetBinXYZ(id.fTower, x, y, z);
00886 
00887    cellData.fValue =  hist->GetBinContent(id.fTower);
00888    cellData.Configure(hist->GetXaxis()->GetBinLowEdge(x),
00889                       hist->GetXaxis()->GetBinUpEdge(x),
00890                       hist->GetYaxis()->GetBinLowEdge(y),
00891                       hist->GetYaxis()->GetBinUpEdge(y));
00892 }
00893 
00894 
00895 //______________________________________________________________________________
00896 Int_t TEveCaloDataHist::AddHistogram(TH2F* hist)
00897 {
00898    // Add new slice to calo tower. Updates cached variables fMaxValE
00899    // and fMaxValEt
00900    // Return last index in the vector of slice infos.
00901 
00902    fHStack->Add(hist);
00903    fSliceInfos.push_back(SliceInfo_t());
00904    fSliceInfos.back().fName  = hist->GetName();
00905    fSliceInfos.back().fColor = hist->GetLineColor();
00906    
00907    DataChanged();
00908    
00909    return fSliceInfos.size() - 1;
00910 }
00911 
00912 //______________________________________________________________________________
00913 TH2F* TEveCaloDataHist::GetHist(Int_t slice) const
00914 {
00915    // Get histogram in given slice.
00916    
00917    return (TH2F*) fHStack->GetHists()->At(slice);
00918 }
00919    
00920 //______________________________________________________________________________
00921 void TEveCaloDataHist::GetEtaLimits(Double_t &min, Double_t &max) const
00922 {
00923    // Get eta limits.
00924 
00925    min = fEtaAxis->GetXmin();
00926    max = fEtaAxis->GetXmax();
00927 }
00928 
00929 //______________________________________________________________________________
00930 void TEveCaloDataHist::GetPhiLimits(Double_t &min, Double_t &max) const
00931 {
00932    // Get phi limits.
00933 
00934    min = fPhiAxis->GetXmin();
00935    max = fPhiAxis->GetXmax();
00936 }

Generated on Tue Jul 5 14:16:10 2011 for ROOT_528-00b_version by  doxygen 1.5.1