...
 
Commits (35)
MODULES= display fit mfile-root
SUBDIRS = display fit mfile-root
.PHONY: all clean $(MODULES)
.PHONY: all clean $(SUBDIRS)
all: $(MODULES)
all: $(SUBDIRS)
clean:
$(MAKE) -C display clean
$(MAKE) -C fit clean
$(MAKE) -C mfile-root clean
clean: $(SUBDIRS)
display:
$(MAKE) -C display
fit:
$(MAKE) -C fit
mfile-root:
$(MAKE) -C mfile-root
$(SUBDIRS):
$(MAKE) -C $@ $(MAKECMDGOALS)
.PHONY: all clean
# Add C++14 standard flag if no other C++ standard was selected
ifneq (,$(findstring CXXFLAGS,-std=))
CXXFLAGS += -std=c++14
endif
all: $(TARGET)
clean:
rm -rf *.pcm $(OBJECTS) $(DEPS) $(ROOTDICT) $(ROOTMAP) $(TARGET)
%.o : %.cc
%.o : %.cc %.d
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $(OUTPUT_OPTION) $<
$(POSTCOMPILE)
%.o: %.c
%.o: %.c %.d
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $(OUTPUT_OPTION) $<
$(POSTCOMPILE)
%.d: ;
.PRECIOUS: %.d
-include $(DEPS)
$(MODNAME)_rdict.cc: $(HEADERS) LinkDef.h
$(ROOT_CLING) $(ROOT_CLING_FLAGS) $^
$(TARGET): $(OBJECTS) $(MODNAME)_rdict.o
$(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES) $(LDLIBS) -o $@
SOURCES := $(wildcard *.cc)
HEADERS := $(wildcard *.hh)
OBJECTS := $(patsubst %.cc,%.o,$(SOURCES))
DEPS := $(patsubst %.cc,%.d,$(SOURCES))
LIBMFILE_CFLAGS = # e.g. -I/usr/local/include
LIBMFILE_LDFLAGS = # e.g. -L /opt/lib64
LIBX11_CFLAGS = # e.g. -I/opt/X11/include
LIBX11_LDFLAGS = # e.g. -L/opt/X11/lib
ROOT_CONFIG = root-config
ROOT_CLING = rootcling
ROOT_CLING_FLAGS = -f $@ -noIncludePaths -inlineInputHeader
ROOT_CLING_FLAGS += -s $(TARGET) -rmf $(ROOTMAP)
# Removed as a precaution, failed in fit
# ROOT_CLING_FLAGS += -rml lib$(MODNAME).so
ROOT_CXXFLAGS := $(shell $(ROOT_CONFIG) --cflags)
ROOT_LIBS := $(shell $(ROOT_CONFIG) --libs)
ROOT_GLIBS := $(shell $(ROOT_CONFIG) --glibs)
CFLAGS = -O2 -g -Wall -fPIC $(DEPFLAGS)
CXXFLAGS = $(ROOT_CXXFLAGS) -Wall -g -O2 -fPIC $(DEPFLAGS) -I../util
LDFLAGS = -shared
LDLIBS = -lstdc++
DEPFLAGS = -MT $@ -MMD -MP -MF $*.Td
POSTCOMPILE = mv -f $*.Td $*.d
TARGET = lib$(MODNAME).so
ROOTDICT = $(MODNAME)_rdict.cc
ROOTMAP = lib$(MODNAME).rootmap
......@@ -17,53 +17,51 @@
* You should have received a copy of the GNU General Public License
* along with HDTV; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*
*/
#include "Calibration.h"
#include "Calibration.hh"
#include <cmath>
#include <algorithm>
#include <iostream>
#include <memory>
#include <numeric>
#include <TAxis.h>
#include <TMath.h>
//#include <Riostream.h>
#include "Compat.hh"
namespace HDTV {
void Calibration::SetCal(const std::vector<double>& cal)
{
void Calibration::SetCal(const std::vector<double> &cal) {
fCal = cal;
UpdateDerivative();
}
void Calibration::SetCal(const TArrayD& cal)
{
void Calibration::SetCal(const TArrayD &cal) {
fCal.clear();
for(int i=0; i<cal.GetSize(); i++)
fCal.push_back(cal[i]);
fCal.reserve(cal.GetSize());
std::copy(cal.GetArray(), cal.GetArray() + cal.GetSize(),
std::back_inserter(fCal));
UpdateDerivative();
}
void Calibration::SetCal(double cal0)
{
void Calibration::SetCal(double cal0) {
fCal.clear();
fCal.push_back(cal0);
UpdateDerivative();
}
void Calibration::SetCal(double cal0, double cal1)
{
void Calibration::SetCal(double cal0, double cal1) {
fCal.clear();
fCal.push_back(cal0);
fCal.push_back(cal1);
UpdateDerivative();
}
void Calibration::SetCal(double cal0, double cal1, double cal2)
{
void Calibration::SetCal(double cal0, double cal1, double cal2) {
fCal.clear();
fCal.push_back(cal0);
fCal.push_back(cal1);
......@@ -71,8 +69,7 @@ void Calibration::SetCal(double cal0, double cal1, double cal2)
UpdateDerivative();
}
void Calibration::SetCal(double cal0, double cal1, double cal2, double cal3)
{
void Calibration::SetCal(double cal0, double cal1, double cal2, double cal3) {
fCal.clear();
fCal.push_back(cal0);
fCal.push_back(cal1);
......@@ -81,116 +78,97 @@ void Calibration::SetCal(double cal0, double cal1, double cal2, double cal3)
UpdateDerivative();
}
void Calibration::UpdateDerivative()
{
void Calibration::UpdateDerivative() {
// Update the coefficients of the derivative polynomial.
// (Internal use only.)
std::vector<double>::iterator c = fCal.begin();
double a = 1.0;
fCalDeriv.clear();
if(c != fCal.end())
++c;
while(c != fCal.end()) {
fCalDeriv.push_back(a * *c++);
a += 1.;
if (fCal.empty()) {
return;
}
double a = 1.0;
std::transform(fCal.begin() + 1, fCal.end(), std::back_inserter(fCalDeriv),
[&](double coeff) { return coeff * a++; });
}
double Calibration::Ch2E(double ch) const
{
//! Convert a channel to an energy, using the chosen energy
//! calibration.
//! Convert a channel to an energy, using the chosen energy
//! calibration.
double Calibration::Ch2E(double ch) const {
// Catch special case of a trivial calibration
if(fCal.empty())
if (fCal.empty()) {
return ch;
std::vector<double>::const_reverse_iterator c = fCal.rbegin();
double E = *c++;
while(c != fCal.rend())
E = E * ch + *c++;
return E;
}
}
double Calibration::dEdCh(double ch) const
{
//! Calculate the slope of the calibration function, \frac{dE}{dCh},
//! at position ch .
return std::accumulate(
fCal.rbegin(), fCal.rend(), 0.0,
[ch](double E, double coeff) { return E * ch + coeff; });
}
//! Calculate the slope of the calibration function, \frac{dE}{dCh},
//! at position ch .
double Calibration::dEdCh(double ch) const {
// Catch special case of a trivial calibration
if(fCal.empty())
if (fCal.empty()) {
return 1.0;
std::vector<double>::const_reverse_iterator c = fCalDeriv.rbegin();
double slope = *c++;
while(c != fCalDeriv.rend())
slope = slope * ch + *c++;
return slope;
}
return std::accumulate(
fCalDeriv.rbegin(), fCalDeriv.rend(), 0.0,
[ch](double slope, double coeff) { return slope * ch + coeff; });
}
double Calibration::E2Ch(double e) const
{
double Calibration::E2Ch(double e) const {
//! Convert an energy to a channel, using the chosen energy
//! calibration.
//! TODO: deal with slope == 0.0
// Catch special case of a trivial calibration
if(fCal.empty())
if (fCal.empty()) {
return e;
}
double ch = 1.0;
double de = Ch2E(ch) - e;
double slope;
double _e = TMath::Abs(e);
double _e = std::abs(e);
std::vector<double>::const_reverse_iterator c;
if(_e < 1.0) _e = 1.0;
for(int i=0; i<10 && TMath::Abs(de / _e) > 1e-10; i++) {
if (_e < 1.0) {
_e = 1.0;
}
for (int i = 0; i < 10 && std::abs(de / _e) > 1e-10; i++) {
// Calculate slope
c = fCalDeriv.rbegin();
slope = *c++;
while(c != fCalDeriv.rend()) {
slope = slope * ch + *c++;
}
ch -= de / slope;
de = Ch2E(ch) - e;
slope = std::accumulate(
fCalDeriv.rbegin(), fCalDeriv.rend(), 0.0,
[ch](double slope, double coeff) { return slope * ch + coeff; });
ch -= de / slope;
de = Ch2E(ch) - e;
}
if (std::abs(de / _e) > 1e-10) {
std::cout << "Warning: Solver failed to converge in Calibration::E2Ch()."
<< std::endl;
}
if(TMath::Abs(de / _e) > 1e-10) {
std::cout << "Warning: Solver failed to converge in Calibration::E2Ch()." << std::endl;
}
return ch;
}
void Calibration::Apply(TAxis *axis, int nbins)
{
double *centers = new double[nbins];
for(int i=0; i<nbins; i++) {
centers[i] = Ch2E((double)i);
void Calibration::Apply(TAxis *axis, int nbins) {
auto centers = Util::make_unique<double[]>(nbins);
for (int i = 0; i < nbins; i++) {
centers[i] = Ch2E(i);
}
axis->Set(nbins, centers);
delete[] centers;
axis->Set(nbins, centers.get());
}
void Calibration::Rebin(const unsigned int nBins)
{
void Calibration::Rebin(const unsigned int nBins) {
const unsigned int size = fCal.size();
for(unsigned int i = 0; i < size; i++)
{
for (unsigned int i = 0; i < size; i++) {
fCal[i] *= std::pow(nBins, i);
}
UpdateDerivative();
......
......@@ -30,7 +30,8 @@ class TArrayD;
namespace HDTV {
//! A calibration (channel-energy relationship) with a polynomial of an arbitrary degree
//! A calibration (channel-energy relationship) with a polynomial of an
//! arbitrary degree
/** It should be noted that this class knows nothing about the binning of the
* histogram it might belong to. In hdtv, a Calibration is used to convert an
* energy to a channel, and the ROOT TAxis object of the respective histogram
......@@ -44,83 +45,50 @@ namespace HDTV {
*/
class Calibration {
public:
Calibration() { }
Calibration(double cal0)
{
SetCal(cal0);
}
Calibration(double cal0, double cal1)
{
SetCal(cal0, cal1);
}
Calibration(double cal0, double cal1, double cal2)
{
SetCal(cal0, cal1, cal2);
}
Calibration(double cal0, double cal1, double cal2, double cal3)
{
SetCal(cal0, cal1, cal2, cal3);
}
Calibration(const std::vector<double> &cal)
{
SetCal(cal);
}
Calibration(const TArrayD &cal)
{
SetCal(cal);
}
void SetCal(double cal0);
void SetCal(double cal0, double cal1);
void SetCal(double cal0, double cal1, double cal2);
void SetCal(double cal0, double cal1, double cal2, double cal3);
void SetCal(const std::vector<double> &cal);
void SetCal(const TArrayD &cal);
inline bool operator==(const Calibration &rhs)
{
return this->fCal == rhs.fCal;
}
inline bool operator!=(const Calibration &rhs)
{
return !(*this == rhs);
}
inline operator bool() const
{
return !IsTrivial();
}
inline bool IsTrivial() const
{
return fCal.empty();
}
inline const std::vector<double> &GetCoeffs() const
{
return fCal;
}
inline int GetDegree() const
{
return fCal.size() - 1;
}
double Ch2E(double ch) const;
double dEdCh(double ch) const;
double E2Ch(double e) const;
void Rebin(const unsigned int nBins);
void Apply(TAxis *axis, int nbins);
Calibration() = default;
explicit Calibration(double cal0) { SetCal(cal0); }
Calibration(double cal0, double cal1) { SetCal(cal0, cal1); }
Calibration(double cal0, double cal1, double cal2) {
SetCal(cal0, cal1, cal2);
}
Calibration(double cal0, double cal1, double cal2, double cal3) {
SetCal(cal0, cal1, cal2, cal3);
}
explicit Calibration(const std::vector<double> &cal) { SetCal(cal); }
explicit Calibration(const TArrayD &cal) { SetCal(cal); }
void SetCal(double cal0);
void SetCal(double cal0, double cal1);
void SetCal(double cal0, double cal1, double cal2);
void SetCal(double cal0, double cal1, double cal2, double cal3);
void SetCal(const std::vector<double> &cal);
void SetCal(const TArrayD &cal);
bool operator==(const Calibration &rhs) { return this->fCal == rhs.fCal; }
bool operator!=(const Calibration &rhs) { return !(*this == rhs); }
explicit operator bool() const { return !IsTrivial(); }
bool IsTrivial() const { return fCal.empty(); }
const std::vector<double> &GetCoeffs() const { return fCal; }
int GetDegree() const { return fCal.size() - 1; }
double Ch2E(double ch) const;
double dEdCh(double ch) const;
double E2Ch(double e) const;
void Rebin(const unsigned int nBins);
void Apply(TAxis *axis, int nbins);
private:
std::vector<double> fCal;
std::vector<double> fCalDeriv;
void UpdateDerivative();
std::vector<double> fCal;
std::vector<double> fCalDeriv;
void UpdateDerivative();
};
} // end namespace HDTV
......
......@@ -17,82 +17,64 @@
* You should have received a copy of the GNU General Public License
* along with HDTV; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*
*/
#include "DisplayBlock.h"
#include "DisplayObj.h"
#include "DisplayStack.h"
#include "View1D.h"
#include "DisplayBlock.hh"
#include <cmath>
#include <TMath.h>
#include <TGFrame.h>
#include <TColor.h>
#include <TGFrame.h>
#include <TROOT.h>
#include "DisplayObj.hh"
#include "DisplayStack.hh"
#include "View1D.hh"
namespace HDTV {
namespace Display {
DisplayBlock::DisplayBlock(int col)
: DisplayObj(),
fCal(),
fNorm(1.0)
{
//! Constructor
//! Constructor
DisplayBlock::DisplayBlock(int col) : DisplayObj(), fGC{nullptr}, fNorm{1.0} {
InitGC(col);
}
DisplayBlock::~DisplayBlock()
{
//! Destructor
//! Destructor
DisplayBlock::~DisplayBlock() { gClient->GetGCPool()->FreeGC(fGC); }
gClient->GetGCPool()->FreeGC(fGC);
}
inline void DisplayBlock::InitGC(int col)
{
inline void DisplayBlock::InitGC(int col) {
// Setup GC for requested color
TColor *color = dynamic_cast<TColor*>(gROOT->GetListOfColors()->At(col));
auto color = dynamic_cast<TColor *>(gROOT->GetListOfColors()->At(col));
GCValues_t gval;
gval.fMask = kGCForeground;
gval.fForeground = color->GetPixel();
fGC = gClient->GetGCPool()->GetGC(&gval, true);
}
void DisplayBlock::SetColor(int col)
{
void DisplayBlock::SetColor(int col) {
// Free old GC
gClient->GetGCPool()->FreeGC(fGC);
// Setup GC for color
InitGC(col);
Update();
}
double DisplayBlock::GetMinE()
{
//! Return the spectrums lower endpoint in energy units
return TMath::Min(Ch2E((double) GetMinCh()),
Ch2E((double) GetMaxCh()));
//! Return the spectrums lower endpoint in energy units
double DisplayBlock::GetMinE() {
return std::min(Ch2E(GetMinCh()), Ch2E(GetMaxCh()));
}
double DisplayBlock::GetMaxE()
{
//! Return the spectrums upper endpoint in energy units
return TMath::Max(Ch2E((double) GetMinCh()),
Ch2E((double) GetMaxCh()));
//! Return the spectrums upper endpoint in energy units
double DisplayBlock::GetMaxE() {
return std::max(Ch2E(GetMinCh()), Ch2E(GetMaxCh()));
}
double DisplayBlock::GetERange()
{
//! Returns the width of the spectrum in energy units
return TMath::Abs(Ch2E((double) GetMinCh())
- Ch2E((double) GetMaxCh()));
//! Returns the width of the spectrum in energy units
double DisplayBlock::GetERange() {
return std::abs(Ch2E(GetMinCh()) - Ch2E(GetMaxCh()));
}
} // end namespace Display
......
......@@ -17,14 +17,14 @@
* You should have received a copy of the GNU General Public License
* along with HDTV; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*
*/
#ifndef __DisplayBlock_h__
#define __DisplayBlock_h__
#include "Calibration.h"
#include "DisplayObj.h"
#include "Calibration.hh"
#include "DisplayObj.hh"
class TGGC;
......@@ -33,37 +33,48 @@ namespace Display {
//! DisplayBlock: common baseclass for DisplayFunc and DisplaySpec
// FIXME: think of a better name?
class DisplayBlock: public DisplayObj
{
class DisplayBlock : public DisplayObj {
friend class Painter;
public:
DisplayBlock(int col);
~DisplayBlock();
void SetCal(const Calibration& cal) { fCal = cal; Update(); };
inline double Ch2E(double ch) { return fCal ? fCal.Ch2E(ch) : ch; }
inline double E2Ch(double e) { return fCal ? fCal.E2Ch(e) : e; }
double GetMaxE();
double GetMinE();
double GetERange();
virtual inline double GetMinCh() { return 0.0; }
virtual inline double GetMaxCh() { return 0.0; }
inline double GetCenterCh() { return (GetMinCh() + GetMaxCh()) / 2.0; }
void SetColor(int col);
void SetNorm(double norm) { fNorm = norm; Update(); }
double GetNorm() { return fNorm; }
protected:
inline const TGGC *GetGC() const { return fGC; }
private:
void InitGC(int col);
Calibration fCal;
TGGC *fGC;
double fNorm; // normalization factor
public:
explicit DisplayBlock(int col);
~DisplayBlock() override;
void SetCal(const Calibration &cal) {
fCal = cal;
Update();
};
double Ch2E(double ch) { return fCal ? fCal.Ch2E(ch) : ch; }
double E2Ch(double e) { return fCal ? fCal.E2Ch(e) : e; }
double GetMaxE();
double GetMinE();
double GetERange();
virtual double GetMinCh() { return 0.0; }
virtual double GetMaxCh() { return 0.0; }
double GetCenterCh() { return (GetMinCh() + GetMaxCh()) / 2.0; }
void SetColor(int col);
void SetNorm(double norm) {
fNorm = norm;
Update();
}
double GetNorm() { return fNorm; }
protected:
const TGGC *GetGC() const { return fGC; }
private:
void InitGC(int col);
Calibration fCal;
TGGC *fGC;
double fNorm; // normalization factor
};
} // end namespace Display
......
......@@ -17,42 +17,70 @@
* You should have received a copy of the GNU General Public License
* along with HDTV; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*
*/
#include "DisplayCut.h"
#include "DisplayCut.hh"
#include <cmath>
#include <TCutG.h>
#include <TMath.h>
namespace HDTV {
namespace Display {
DisplayCut::DisplayCut(const TCutG& cut, bool invertAxes)
{
if(invertAxes)
Init(cut.GetN(), cut.GetY(), cut.GetX());
else
Init(cut.GetN(), cut.GetX(), cut.GetY());
}
namespace {
void DisplayCut::Init(int n, const double* x, const double* y)
{
if(n <= 0) return;
fPoints.reserve(n);
fPoints.push_back(CutPoint(x[0], y[0]));
fX1 = fX2 = x[0];
fY1 = fY2 = y[0];
for(int i=1; i<n; ++i) {
fPoints.push_back(CutPoint(x[i], y[i]));
fX1 = TMath::Min(fX1, x[i]);
fX2 = TMath::Max(fX2, x[i]);
fY1 = TMath::Min(fY1, y[i]);
fY2 = TMath::Max(fY2, y[i]);
std::vector<DisplayCut::CutPoint>
make_points(const double *x_begin, const double *x_end, const double *y_begin) {
std::vector<DisplayCut::CutPoint> points;
if (x_end > x_begin) {
points.reserve(std::distance(x_begin, x_end));
while (x_begin != x_end) {
points.emplace_back(*x_begin++, *y_begin++);
}
}
return points;
}
} // namespace
DisplayCut::DisplayCut(int n, const double *x, const double *y)
: fPoints{make_points(x, x + n, y)}, fX1{0.0}, fY1{0.0}, fX2{0.0},
fY2{0.0} {
UpdateBoundingBox();
}
DisplayCut::DisplayCut(const TCutG &cut, bool invertAxes)
: fPoints{invertAxes
? make_points(cut.GetY(), cut.GetY() + cut.GetN(), cut.GetX())
: make_points(cut.GetX(), cut.GetX() + cut.GetN(),
cut.GetY())},
fX1{0.0}, fY1{0.0}, fX2{0.0}, fY2{0.0} {
UpdateBoundingBox();
}
void DisplayCut::UpdateBoundingBox() {
if (fPoints.empty()) {
fX1 = 0.0;
fX2 = 0.0;
fY1 = 0.0;
fY2 = 0.0;
return;
}
fX1 = std::numeric_limits<double>::max();
fX2 = std::numeric_limits<double>::min();
fY1 = std::numeric_limits<double>::max();
fY2 = std::numeric_limits<double>::min();
for (auto &point : fPoints) {
fX1 = std::min(fX1, point.x);
fX2 = std::max(fX2, point.x);
fY1 = std::min(fY1, point.y);
fY2 = std::max(fY2, point.y);
}
}
} // end namespace Display
......
......@@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License
* along with HDTV; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*
*/
#ifndef __DisplayCut_h__
......@@ -31,33 +31,31 @@ namespace HDTV {
namespace Display {
class DisplayCut {
public:
class CutPoint {
public:
class CutPoint {
public:
CutPoint(double _x, double _y) { x = _x; y = _y; }
double x, y;
};
DisplayCut() {}
DisplayCut(int n, const double* x, const double* y)
{ Init(n, x, y); }
DisplayCut(const TCutG& cut, bool invertAxes=false);
const std::vector<CutPoint>& GetPoints() const
{ return fPoints; }
inline double BB_x1() const { return fX1; }
inline double BB_y1() const { return fY1; }
inline double BB_x2() const { return fX2; }
inline double BB_y2() const { return fY2; }
private:
void Init(int n, const double* x, const double* y);
std::vector<CutPoint> fPoints;
double fX1, fY1, fX2, fY2; // bounding box
CutPoint(double _x, double _y) : x(_x), y(_y) {}
double x, y;
};
DisplayCut() : fX1{0.0}, fY1{0.0}, fX2{0.0}, fY2{0.0} {}
DisplayCut(int n, const double *x, const double *y);
explicit DisplayCut(const TCutG &cut, bool invertAxes = false);
const std::vector<CutPoint> &GetPoints() const { return fPoints; }
double BB_x1() const { return fX1; }
double BB_y1() const { return fY1; }
double BB_x2() const { return fX2; }
double BB_y2() const { return fY2; }
private:
void UpdateBoundingBox();
std::vector<CutPoint> fPoints;
double fX1, fY1, fX2, fY2; // bounding box
};
} // end namespace Display
} // end namespace HDTV
#endif
......@@ -17,21 +17,19 @@
* You should have received a copy of the GNU General Public License
* along with HDTV; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*
*/
#include "DisplayFunc.h"
#include "DisplayFunc.hh"
#include <iostream>
#include "DisplayStack.h"
#include "DisplayStack.hh"
namespace HDTV {
namespace Display {
DisplayFunc::DisplayFunc(TF1 *func, int col)
: DisplayBlock(col)
{
DisplayFunc::DisplayFunc(TF1 *func, int col) : DisplayBlock(col) {
fFunc = func;
}
......
......@@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License
* along with HDTV; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*
*/
#ifndef __DisplayFunc_h__
......@@ -25,30 +25,42 @@
#include <TF1.h>
#include "DisplayBlock.h"
#include "Painter.h"
#include "DisplayBlock.hh"
#include "Painter.hh"
namespace HDTV {
namespace Display {
//! Wrapper around a ROOT TF1 object being displayed
class DisplayFunc : public DisplayBlock {
public:
DisplayFunc(TF1 *func, int col = DEFAULT_COLOR);
inline TF1 *GetFunc() { return fFunc; }
inline double Eval(double x) { return fFunc->Eval(x); }
inline double GetMinCh(void) { double min, max; fFunc->GetRange(min, max); return min; }
inline double GetMaxCh(void) { double min, max; fFunc->GetRange(min, max); return max; }
virtual void PaintRegion(UInt_t x1, UInt_t x2, Painter& painter)
{ if(IsVisible()) painter.DrawFunction(this, x1, x2); }
virtual int GetZIndex() { return Z_INDEX_FUNC; }
private:
TF1 *fFunc;
public:
explicit DisplayFunc(TF1 *func, int col = DEFAULT_COLOR);
TF1 *GetFunc() { return fFunc; }
double Eval(double x) { return fFunc->Eval(x); }
double GetMinCh() override {
double min, max;
fFunc->GetRange(min, max);
return min;
}
double GetMaxCh() override {
double min, max;
fFunc->GetRange(min, max);
return max;
}
void PaintRegion(UInt_t x1, UInt_t x2, Painter &painter) override {
if (IsVisible()) {
painter.DrawFunction(this, x1, x2);
}
}
virtual int GetZIndex() { return Z_INDEX_FUNC; }
private:
TF1 *fFunc;
};
} // end namespace Display
......
......@@ -17,48 +17,42 @@
* You should have received a copy of the GNU General Public License
* along with HDTV; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*
*/
#include "DisplayObj.h"
#include "DisplayObj.hh"
#include <Riostream.h>
#include <algorithm>
#include <iostream>
#include "DisplayStack.h"
#include "View1D.h"
#include "DisplayStack.hh"
#include "View1D.hh"
namespace HDTV {
namespace Display {
const int DisplayObj::DEFAULT_COLOR = 3;
DisplayObj::~DisplayObj()
{
//! Destructor
Remove(); // Remove object from all display stacks
//! Destructor
DisplayObj::~DisplayObj() {
// Remove object from all display stacks
Remove();
}
void DisplayObj::Update(bool force)
{
//! Update all display stacks that the object is presently on
if(!IsVisible() && !force)
//! Update all display stacks that the object is presently on
void DisplayObj::Update(bool force) {
if (!IsVisible() && !force) {
return;
for(std::list<DisplayStack*>::iterator stack = fStacks.begin();
stack != fStacks.end();
stack++)
{
(*stack)->Update();
}
}
void DisplayObj::Draw(View1D *view)
{
//! Add the object to view s display stack
for (auto &stack : fStacks) {
stack->Update();
}
}
if(!view) {
//! Add the object to view s display stack
void DisplayObj::Draw(View1D *view) {
if (!view) {
std::cout << "Error: Draw to NULL view: no action taken." << std::endl;
return;
}
......@@ -66,120 +60,94 @@ void DisplayObj::Draw(View1D *view)
Draw(view->GetDisplayStack());
}
void DisplayObj::Remove(View1D *view)
{
//! Remove the object from view s display stack
Remove(view->GetDisplayStack());
}
void DisplayObj::Draw(DisplayStack *stack)
{
//! Add the object to the display stack
DisplayStack::ObjList& list = stack->fObjects;
DisplayStack::ObjList::iterator pos = list.begin();
while(pos != list.end() && (*pos)->GetZIndex() <= GetZIndex()) { ++pos; }
list.insert(pos, this);
//! Remove the object from view s display stack
void DisplayObj::Remove(View1D *view) { Remove(view->GetDisplayStack()); }
//! Add the object to the display stack
void DisplayObj::Draw(DisplayStack *stack) {
auto &objects = stack->fObjects;
auto pos = std::find_if(
objects.begin(),
objects.end(), [zindex = GetZIndex()](const DisplayObj *obj) {
return obj->GetZIndex() > zindex;
});
objects.insert(pos, this);
fStacks.insert(fStacks.begin(), stack);
stack->Update();
}
void DisplayObj::Remove(DisplayStack *stack)
{
//! Remove the object from the display stack
//! Remove the object from the display stack
void DisplayObj::Remove(DisplayStack *stack) {
stack->fObjects.remove(this);
stack->Update();
fStacks.remove(stack);
}
void DisplayObj::Remove()
{
//! Remove the object from all display stacks it appears in
//! Remove the object from all display stacks it appears in
void DisplayObj::Remove() {
// Note that we cannot use an iterator to traverse a changing list
while(!fStacks.empty()) {
while (!fStacks.empty()) {
Remove(*fStacks.begin());
}
}
void DisplayObj::ToTop(View1D *view)
{
//! Move the object to the top of its list in view s display stack
ToTop(view->GetDisplayStack());
}
void DisplayObj::ToBottom(View1D *view)
{
//! Move the object to the bottom of its list in view s display stack
ToBottom(view->GetDisplayStack());
}
void DisplayObj::ToTop(DisplayStack *stack)
{
//! Move the object to the top of all objects with lower or equal z-index in
//! the display stack.
DisplayStack::ObjList& list = stack->fObjects;
DisplayStack::ObjList::iterator pos = list.begin();
while(pos != list.end() && (*pos)->GetZIndex() <= GetZIndex()) { ++pos; }
if(pos != list.end() && *pos == this)
//! Move the object to the top of its list in view s display stack
void DisplayObj::ToTop(View1D *view) { ToTop(view->GetDisplayStack()); }
//! Move the object to the bottom of its list in view s display stack
void DisplayObj::ToBottom(View1D *view) { ToBottom(view->GetDisplayStack()); }
//! Move the object to the top of all objects with lower or equal z-index in the
//! display stack.
void DisplayObj::ToTop(DisplayStack *stack) {
auto &objects = stack->fObjects;
auto pos = std::find_if(
objects.begin(),
objects.end(), [zindex = GetZIndex()](const DisplayObj *obj) {
return obj->GetZIndex() > zindex;
});
if (pos != objects.end() && *pos == this) {
return;
list.remove(this);
list.insert(pos, this);
}
objects.remove(this);
objects.insert(pos, this);
stack->Update();
}
void DisplayObj::ToTop()
{
//! Move the object to the top of all objects with lower or equal z-index in
//! all display stacks it appears in.
for(std::list<DisplayStack*>::iterator stack = fStacks.begin();
stack != fStacks.end();
++stack) {
ToTop(*stack);
//! Move the object to the top of all objects with lower or equal z-index in all
//! display stacks it appears in.
void DisplayObj::ToTop() {
for (auto &stack : fStacks) {
ToTop(stack);
}
}
void DisplayObj::ToBottom(DisplayStack *stack)
{
//! Move the object to the bottom of all objects with higher or equal z-index
//! in the display stack.
DisplayStack::ObjList& list = stack->fObjects;
DisplayStack::ObjList::iterator pos = list.begin();
while(pos != list.end() && (*pos)->GetZIndex() < GetZIndex()) { ++pos; }
if(pos != list.end() && *pos == this)
//! Move the object to the bottom of all objects with higher or equal z-index in
//! the display stack.
void DisplayObj::ToBottom(DisplayStack *stack) {
auto &objects = stack->fObjects;
auto pos = std::find_if(
objects.begin(),
objects.end(), [zindex = GetZIndex()](const DisplayObj *obj) {
return !(obj->GetZIndex() < zindex);
});
if (pos != objects.end() && *pos == this) {
return;
list.remove(this);
list.insert(list.begin(), this);
}
objects.remove(this);
objects.insert(objects.begin(), this);
stack->Update();
}
void DisplayObj::ToBottom()
{
//! Move the object to the bottom of all objects with higher or equal z-index
//! in all display stacks it appears in.
for(std::list<DisplayStack*>::iterator stack = fStacks.begin();
stack != fStacks.end();
++stack) {
ToBottom(*stack);
//! Move the object to the bottom of all objects with higher or equal z-index in
//! all display stacks it appears in.
void DisplayObj::ToBottom() {
for (auto &stack : fStacks) {
ToBottom(stack);
}
}
......
......@@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License
* along with HDTV; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*
*/
#ifndef __DisplayObj_h__
......@@ -25,8 +25,8 @@
#include <list>
#include "DisplayObjZIndex.h"
#include "Painter.h"
#include "DisplayObjZIndex.hh"
#include "Painter.hh"
namespace HDTV {
namespace Display {
......@@ -36,45 +36,54 @@ class View1D;
//! An object being displayed in a View1D widget
class DisplayObj {
public:
DisplayObj() : fVisible(true) { }
virtual ~DisplayObj();
inline bool IsVisible() const { return fVisible; }
inline void Show() { fVisible = true; Update(true); }
inline void Hide() { fVisible = false; Update(true); }
/* Management functions */
void Draw(View1D *view);
void Remove(View1D *view);
void Draw(DisplayStack *stack);
void Remove(DisplayStack *stack);
void Remove();
void ToTop(View1D *view);
void ToBottom(View1D *view);
void ToTop(DisplayStack *stack);
void ToBottom(DisplayStack *stack);
void ToTop();
void ToBottom();
virtual void PaintRegion(UInt_t x1, UInt_t x2, Painter& painter) { }
virtual int GetZIndex() { return Z_INDEX_MISC; }
static const int DEFAULT_COLOR;
protected:
void Update(bool force=false);
std::list<DisplayStack*> fStacks;
int fZIndex;
private:
bool fVisible;
public:
DisplayObj() : fZIndex{0}, fVisible{true} {}
virtual ~DisplayObj();
bool IsVisible() const { return fVisible; }
void Show() {
fVisible = true;
Update(true);
}
void Hide() {
fVisible = false;
Update(true);
}
/* Management functions */
void Draw(View1D *view);
void Remove(View1D *view);
void Draw(DisplayStack *stack);
void Remove(DisplayStack *stack);
void Remove();
void ToTop(View1D *view);
void ToBottom(View1D *view);
void ToTop(DisplayStack *stack);
void ToBottom(DisplayStack *stack);
void ToTop();
void ToBottom();
virtual void PaintRegion(UInt_t /*x1*/, UInt_t /*x2*/,
Painter & /*painter*/) {}
virtual int GetZIndex() const { return Z_INDEX_MISC; }
static const int DEFAULT_COLOR;
protected:
void Update(bool force = false);
std::list<DisplayStack *> fStacks;
int fZIndex;
private:
bool fVisible;
};
} // end namespace Display
......
......@@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License
* along with HDTV; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*
*/
#ifndef __DisplayObjZIndex_h__
......
......@@ -17,49 +17,44 @@
* You should have received a copy of the GNU General Public License
* along with HDTV; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*
*/
#include "DisplaySpec.h"
#include "DisplaySpec.hh"
#include <utility>
#include <Riostream.h>
#include <TH1.h>
#include <TROOT.h>
#include "DisplayStack.h"
#include "DisplayStack.hh"
namespace HDTV {
namespace Display {
DisplaySpec::DisplaySpec(const TH1* hist, int col)
: DisplayBlock(col),
fDrawUnderflowBin(false),
fDrawOverflowBin(false)
{
//! Constructor
//! Constructor
DisplaySpec::DisplaySpec(const TH1 *hist, int col)
: DisplayBlock(col), fCachedMaxBin{0}, fCachedMax{0.0},
fDrawUnderflowBin(false), fDrawOverflowBin(false) {
fHist.reset(dynamic_cast<TH1 *>(hist->Clone()));
fHist.reset(dynamic_cast<TH1*>(hist->Clone()));
//cout << "GSDisplaySpec constructor" << endl;
// cout << "GSDisplaySpec constructor" << endl;
/* Set invalid values to ensure cache is flushed at the
first call to GetMax_Cached() */
/* Set invalid values to ensure cache is flushed at the
first call to GetMax_Cached() */
fCachedB1 = 1;
fCachedB2 = 0;
}
void DisplaySpec::SetHist(const TH1* hist)
{
void DisplaySpec::SetHist(const TH1 *hist) {
//! Set the histogram owned by this object to a copy of hist
fHist.reset(dynamic_cast<TH1*>(hist->Clone()));
fHist.reset(dynamic_cast<TH1 *>(hist->Clone()));
Update();
}
int DisplaySpec::GetRegionMaxBin(int b1, int b2)
{
int DisplaySpec::GetRegionMaxBin(int b1, int b2) {
//! Find the bin number of the bin between b1 and b2 (inclusive) which
//! contains the most events
//! b1 and b2 are raw bin numbers
......@@ -70,96 +65,94 @@ int DisplaySpec::GetRegionMaxBin(int b1, int b2)
b1 = ClipBin(b1);
b2 = ClipBin(b2);
max_y = fHist->GetBinContent(b1);
max_bin = b1;
for(bin = b1; bin <= b2; bin ++) {
y = fHist->GetBinContent(bin);
if(y > max_y) {
max_y = y;
max_bin = bin;
}
for (bin