Histogram2D.h add save/load graphic cuts into/from txt file
This commit is contained in:
parent
839b3d2a58
commit
c8e032390a
299
Histogram2D.h
299
Histogram2D.h
|
@ -19,7 +19,82 @@ const QList<QPair<QColor, QString>> colorCycle = { {QColor(Qt::red), "Red"},
|
|||
class Histogram2D : public QCustomPlot{
|
||||
|
||||
public:
|
||||
Histogram2D(QString title, QString xLabel, QString yLabel, int xbin, double xmin, double xmax, int ybin, double ymin, double ymax, QWidget * parent = nullptr) : QCustomPlot(parent){
|
||||
Histogram2D(QString title, QString xLabel, QString yLabel, int xbin, double xmin, double xmax, int ybin, double ymin, double ymax, QWidget * parent = nullptr);
|
||||
|
||||
void SetXTitle(QString xTitle) { xAxis->setLabel(xTitle);}
|
||||
void SetYTitle(QString yTitle) { yAxis->setLabel(yTitle);}
|
||||
void Rebin(int xbin, double xmin, double xmax, int ybin, double ymin, double ymax);
|
||||
void RebinY(int ybin, double ymin, double ymax);
|
||||
|
||||
void SetChannelMap(bool onOff, int tickStep = 1) { isChannelMap = onOff; this->tickStep = tickStep;}
|
||||
|
||||
void UpdatePlot(){ colorMap->rescaleDataRange(); replot(); }
|
||||
void Clear(); // Clear Data and histrogram
|
||||
|
||||
void Fill(double x, double y);
|
||||
|
||||
void DrawCut();
|
||||
void ClearAllCuts();
|
||||
|
||||
QList<QPolygonF> GetCutList() const{return cutList;} // this list may contain empty element
|
||||
QList<int> GetCutEntryList() const{ return cutEntryList;}
|
||||
QList<QString> GetCutNameList() const { return cutNameList;}
|
||||
void PrintCutEntry() const;
|
||||
|
||||
double GetXNBin() const {return xBin;}
|
||||
double GetXMin() const {return xMin;}
|
||||
double GetXMax() const {return xMax;}
|
||||
double GetYNBin() const {return yBin;}
|
||||
double GetYMin() const {return yMin;}
|
||||
double GetYMax() const {return yMax;}
|
||||
|
||||
void SaveCuts(QString cutFileName);
|
||||
void LoadCuts(QString cutFileName);
|
||||
|
||||
private:
|
||||
double xMin, xMax, yMin, yMax;
|
||||
int xBin, yBin;
|
||||
|
||||
bool isChannelMap;
|
||||
int tickStep;
|
||||
bool isLogZ;
|
||||
|
||||
QCPColorMap * colorMap;
|
||||
QCPColorScale *colorScale;
|
||||
|
||||
bool usingMenu;
|
||||
|
||||
int entry[3][3]; // overflow counter, entrt[1][1] is entry in the plot;
|
||||
|
||||
QCPItemRect * box[3][3];
|
||||
QCPItemText * txt[3][3];
|
||||
|
||||
QPolygonF tempCut;
|
||||
int tempCutID; // only incresing;
|
||||
int numCut;
|
||||
QList<QPolygonF> cutList;
|
||||
QList<QString> cutNameList; // name of the cut
|
||||
QList<int> cutEntryList; // number of entry inside the cut.
|
||||
QList<int> cutIDList; // ID of the cut
|
||||
QList<int> cutTextIDList; //
|
||||
QList<int> plottableIDList;
|
||||
bool isDrawCut;
|
||||
int lastPlottableID;
|
||||
|
||||
QCPItemLine * line;
|
||||
double oldMouseX = 0.0, oldMouseY = 0.0;
|
||||
|
||||
bool isBusy;
|
||||
|
||||
void rightMouseClickMenu(QMouseEvent * event);
|
||||
void rightMouseClickRebin();
|
||||
|
||||
};
|
||||
|
||||
//^###############################################
|
||||
//^###############################################
|
||||
|
||||
inline Histogram2D::Histogram2D(QString title, QString xLabel, QString yLabel, int xbin, double xmin, double xmax, int ybin, double ymin, double ymax, QWidget * parent) : QCustomPlot(parent){
|
||||
// DebugPrint("%s", "Histogram2D");
|
||||
for( int i = 0; i < 3; i ++ ){
|
||||
for( int j = 0; j < 3; j ++ ){
|
||||
|
@ -185,95 +260,7 @@ public:
|
|||
});
|
||||
}
|
||||
|
||||
//^===================================
|
||||
|
||||
void SetXTitle(QString xTitle) { xAxis->setLabel(xTitle);}
|
||||
void SetYTitle(QString yTitle) { yAxis->setLabel(yTitle);}
|
||||
void Rebin(int xbin, double xmin, double xmax, int ybin, double ymin, double ymax);
|
||||
void RebinY(int ybin, double ymin, double ymax);
|
||||
|
||||
void SetChannelMap(bool onOff, int tickStep = 1) { isChannelMap = onOff; this->tickStep = tickStep;}
|
||||
|
||||
void UpdatePlot(){
|
||||
// QCPColorGradient color;
|
||||
// color.clearColorStops();
|
||||
// color.setNanColor(QColor("white"));
|
||||
// // color.setColorStopAt( 0.0, QColor("white" ));
|
||||
// // color.setColorStopAt( 1.0/entry[1][1], QColor("purple" ));
|
||||
// color.setColorStopAt( 0.0, QColor("purple" ));
|
||||
// color.setColorStopAt( 0.2, QColor("blue"));
|
||||
// color.setColorStopAt( 0.4, QColor("cyan"));
|
||||
// color.setColorStopAt( 0.6, QColor("green"));
|
||||
// color.setColorStopAt( 0.8, QColor("yellow"));
|
||||
// color.setColorStopAt( 1.0, QColor("red"));
|
||||
// colorMap->setGradient(color);
|
||||
|
||||
colorMap->rescaleDataRange();
|
||||
|
||||
replot();
|
||||
}
|
||||
|
||||
void Clear(); // Clear Data and histrogram
|
||||
|
||||
void Fill(double x, double y);
|
||||
|
||||
void DrawCut();
|
||||
void ClearAllCuts();
|
||||
|
||||
QList<QPolygonF> GetCutList() const{return cutList;} // this list may contain empty element
|
||||
QList<int> GetCutEntryList() const{ return cutEntryList;}
|
||||
QList<QString> GetCutNameList() const { return cutNameList;}
|
||||
void PrintCutEntry() const;
|
||||
|
||||
double GetXNBin() const {return xBin;}
|
||||
double GetXMin() const {return xMin;}
|
||||
double GetXMax() const {return xMax;}
|
||||
double GetYNBin() const {return yBin;}
|
||||
double GetYMin() const {return yMin;}
|
||||
double GetYMax() const {return yMax;}
|
||||
|
||||
private:
|
||||
double xMin, xMax, yMin, yMax;
|
||||
int xBin, yBin;
|
||||
|
||||
bool isChannelMap;
|
||||
int tickStep;
|
||||
bool isLogZ;
|
||||
|
||||
QCPColorMap * colorMap;
|
||||
QCPColorScale *colorScale;
|
||||
|
||||
bool usingMenu;
|
||||
|
||||
int entry[3][3]; // overflow counter, entrt[1][1] is entry in the plot;
|
||||
|
||||
QCPItemRect * box[3][3];
|
||||
QCPItemText * txt[3][3];
|
||||
|
||||
QPolygonF tempCut;
|
||||
int tempCutID; // only incresing;
|
||||
QList<QPolygonF> cutList;
|
||||
QList<int> cutIDList;
|
||||
int numCut;
|
||||
bool isDrawCut;
|
||||
int lastPlottableID;
|
||||
QList<int> cutTextIDList;
|
||||
QList<int> plottableIDList;
|
||||
QList<QString> cutNameList;
|
||||
QList<int> cutEntryList;
|
||||
|
||||
QCPItemLine * line;
|
||||
double oldMouseX = 0.0, oldMouseY = 0.0;
|
||||
|
||||
bool isBusy;
|
||||
|
||||
void rightMouseClickMenu(QMouseEvent * event);
|
||||
void rightMouseClickRebin();
|
||||
|
||||
};
|
||||
|
||||
//^###############################################
|
||||
//^###############################################
|
||||
|
||||
inline void Histogram2D::Fill(double x, double y){
|
||||
// DebugPrint("%s", "Histogram2D");
|
||||
|
@ -391,7 +378,7 @@ inline void Histogram2D::ClearAllCuts(){
|
|||
inline void Histogram2D::PrintCutEntry() const{
|
||||
DebugPrint("%s", "Histogram2D");
|
||||
if( numCut == 0 ) return;
|
||||
printf("=============== There are %d cuts.\n", numCut);
|
||||
printf("=============== There are %d cuts. (%lld, %lld)\n", numCut, cutList.count(), cutEntryList.count());
|
||||
for( int i = 0; i < cutList.count(); i++){
|
||||
if( cutList[i].isEmpty() ) continue;
|
||||
printf("%10s | %d \n", cutNameList[i].toStdString().c_str(), cutEntryList[i]);
|
||||
|
@ -439,8 +426,11 @@ inline void Histogram2D::rightMouseClickMenu(QMouseEvent * event){
|
|||
QAction * a2 = menu->addAction("Clear hist.");
|
||||
QAction * a3 = menu->addAction("Toggle Stat.");
|
||||
QAction * a4 = menu->addAction("Rebin (clear histogram)");
|
||||
QAction * a8 = menu->addAction("Load Cut(s)");
|
||||
QAction * a5 = menu->addAction("Create a Cut");
|
||||
QAction * a7 = nullptr;
|
||||
if( numCut > 0 ) {
|
||||
a7 = menu->addAction("Save Cut(s)");
|
||||
menu->addSeparator();
|
||||
menu->addAction("Add/Edit names to Cuts");
|
||||
menu->addAction("Clear all Cuts");
|
||||
|
@ -575,6 +565,27 @@ inline void Histogram2D::rightMouseClickMenu(QMouseEvent * event){
|
|||
return;
|
||||
}
|
||||
|
||||
if( selectedAction == a8 ){ // load Cuts
|
||||
QString filePath = QFileDialog::getOpenFileName(this,
|
||||
"Load Cuts from File",
|
||||
QDir::homePath(),
|
||||
"Text file (*.txt)");
|
||||
|
||||
if (!filePath.isEmpty()) LoadCuts(filePath);
|
||||
|
||||
}
|
||||
|
||||
if( selectedAction == a7 ){ // Save Cuts
|
||||
|
||||
QString filePath = QFileDialog::getSaveFileName(this,
|
||||
"Save Cuts to File",
|
||||
QDir::homePath(),
|
||||
"Text file (*.txt)");
|
||||
|
||||
if (!filePath.isEmpty()) SaveCuts(filePath);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -674,5 +685,113 @@ inline void Histogram2D::rightMouseClickRebin(){
|
|||
|
||||
}
|
||||
|
||||
inline void Histogram2D::SaveCuts(QString cutFileName){
|
||||
|
||||
QFile file(cutFileName);
|
||||
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QTextStream out(&file);
|
||||
|
||||
// Define the text to write
|
||||
QStringList lines;
|
||||
|
||||
for( int i = 0; i < cutList.size(); i++){
|
||||
lines << "====== "+ cutNameList[i];
|
||||
for( int pt = 0 ; pt < cutList[i].size(); pt ++){
|
||||
lines << QString::number(cutList[i][pt].rx(), 'g', 5) + "," + QString::number(cutList[i][pt].ry(), 'g', 5);
|
||||
}
|
||||
}
|
||||
|
||||
lines << "#===== End of File";
|
||||
|
||||
// Write each line to the file
|
||||
for (const QString &line : lines) out << line << "\n";
|
||||
|
||||
// Close the file
|
||||
file.close();
|
||||
qDebug() << "File written successfully to" << cutFileName;
|
||||
}else{
|
||||
qWarning() << "Unable to open file" << cutFileName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline void Histogram2D::LoadCuts(QString cutFileName){
|
||||
|
||||
QFile file(cutFileName);
|
||||
QString cutNameTemp;
|
||||
|
||||
// Open the file in read mode
|
||||
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QTextStream in(&file);
|
||||
|
||||
ClearAllCuts();
|
||||
tempCut.clear();
|
||||
|
||||
// Read each line and append to the QStringList
|
||||
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine();
|
||||
|
||||
if( line.contains("======") ){
|
||||
if( !tempCut.isEmpty() ) {
|
||||
DrawCut();
|
||||
plottableIDList.push_back(plottableCount() -1 );
|
||||
cutNameList.push_back(cutNameTemp);
|
||||
cutEntryList.push_back(0);
|
||||
QCPItemText * text = new QCPItemText(this);
|
||||
text->setText(cutNameList.last());
|
||||
text->position->setCoords(tempCut[0].rx(), tempCut[0].ry());
|
||||
int colorID = tempCutID% colorCycle.count();
|
||||
text->setColor(colorCycle[colorID].first);
|
||||
cutTextIDList.push_back(itemCount() - 1);
|
||||
// cutList.push_back(tempCut);
|
||||
cutIDList.push_back(tempCutID);
|
||||
}
|
||||
tempCut.clear();
|
||||
tempCutID ++;
|
||||
numCut ++;
|
||||
|
||||
int spacePos = line.indexOf(' ');
|
||||
cutNameTemp = line.mid(spacePos + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if( line.contains("#==") ) {
|
||||
DrawCut();
|
||||
plottableIDList.push_back(plottableCount() -1 );
|
||||
cutNameList.push_back(cutNameTemp);
|
||||
cutEntryList.push_back(0);
|
||||
QCPItemText * text = new QCPItemText(this);
|
||||
text->setText(cutNameList.last());
|
||||
text->position->setCoords(tempCut[0].rx(), tempCut[0].ry());
|
||||
int colorID = tempCutID% colorCycle.count();
|
||||
text->setColor(colorCycle[colorID].first);
|
||||
cutTextIDList.push_back(itemCount() - 1);
|
||||
cutList.push_back(tempCut);
|
||||
cutIDList.push_back(tempCutID);
|
||||
break;
|
||||
}else{
|
||||
QStringList haha = line.split(",");
|
||||
// qDebug() << haha;
|
||||
tempCut.push_back(QPointF(haha[0].toFloat(), haha[1].toFloat()));
|
||||
DrawCut();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Close the file
|
||||
file.close();
|
||||
qDebug() << "File read successfully from" << cutFileName;
|
||||
|
||||
// PrintCutEntry();
|
||||
// DrawCut();
|
||||
replot();
|
||||
|
||||
} else {
|
||||
qWarning() << "Unable to open file" << cutFileName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user