/* * HistoPlot.cc * * Created on: 29 oct. 2013 * Author: CS */ #include #include #include #include #include "HistoPlot.hh" #include "ParamsNode.hh" #include "AxesNode.hh" #include "Axis.hh" #include "PlotLogger.hh" #include "PlotOutput.hh" #include "TimeUtil.hh" #include "ParamMgr.hh" #include "AxisLegendManager.hh" using namespace AMDA::Parameters; using namespace AMDA::Info; namespace plot { HistoPlot::HistoPlot(AMDA::Parameters::ParameterManager& manager, boost::shared_ptr panel) : PanelPlotOutput(manager, panel){ } /** * @overload PanelPlotOutput::preparePlotArea() */ void HistoPlot::preparePlotArea(double startTime, double stopTime, int intervalIndex, std::vector* ttNames) { // for test, dump plot properties const char* lBuildType=getenv("BUILD_TYPE"); if(lBuildType && std::string(lBuildType) == "Debug") { std::ofstream out("HistoPlot.txt"); dump(out); out.close(); } // Configure range of series and color. configureSeriesAxis(startTime,stopTime); configureAxisLegend(); // Configure params legend configureParamsLegend(startTime,stopTime,intervalIndex); // If panel title is empty, replace it with start and end date. if (_panel->getTitle()->_text.empty() || _panel->_updateTitleOnNextInterval) { //Title must be updated during the next interval plot _panel->_updateTitleOnNextInterval = true; // Set start date and end date. std::string lTimeFormat("%Y/%m/%d %H:%M:%S"); long int lStartTime = static_cast(startTime); tm * lStartTimeTm = gmtime(&lStartTime); char lStartTimeChr[80]; // Format date. strftime(lStartTimeChr, 80, lTimeFormat.c_str(), lStartTimeTm); std::string lStartTimeStr= lStartTimeChr; lStartTimeStr += '.'+std::to_string(startTime -lStartTime ).substr(2,3); long int lStopTime = static_cast(stopTime); tm * lStopTimeTm = gmtime(&lStopTime); char lStopTimeChr[80]; // Format date. strftime(lStopTimeChr, 80, lTimeFormat.c_str(), lStopTimeTm); std::string lStopTimeStr= lStopTimeChr; lStopTimeStr += '.'+std::to_string(stopTime -lStopTime ).substr(2,3); std::string titleText = lStartTimeStr + " - " + lStopTimeStr; if(_panel->_page->_superposeMode){ std::string superposedModeText = "Events from "; if (ttNames != nullptr) { // Iterate through the vector's elements using the pointer for (const std::string& name : *ttNames) { if (name == ttNames->back() && ttNames->size()>1) superposedModeText +=" and '"+name+"' in "+titleText; else if (ttNames->size()==1) superposedModeText +=" '"+name+"' in "+titleText; else if (name == ttNames->at(ttNames->size()-2) && ttNames->size()>1) superposedModeText += "'"+name+"'"; else superposedModeText += "'"+name+"',"; } } _panel->setTitleText(superposedModeText.c_str()); } else{ _panel->setTitleText(titleText.c_str()); } } PanelPlotOutput::preparePlotArea(startTime,stopTime,intervalIndex, ttNames); } void HistoPlot::createParameters(std::list& usedParametersId_) { for (ParameterAxesList::iterator it = _parameterAxesList.begin(); it != _parameterAxesList.end(); ++it) { AMDA::Parameters::ParameterSPtr usedXParam; AMDA::Parameters::ParameterSPtr usedYParam; AMDA::Parameters::ParameterSPtr usedColorParam; for (auto pHistogramProperties : it->getHistogramSeriesPropertiesList()) { if(pHistogramProperties != nullptr){ if(pHistogramProperties->getHistogramType() == "histogram1d"){ AMDA::Parameters::ParameterSPtr originalXParam = _parameterManager.getParameter(it->_originalParamId); if(!pHistogramProperties->getHistotypeProperties().getParamId().empty()) { AMDA::Parameters::ParameterSPtr originalYParam =_parameterManager.getParameter(pHistogramProperties->getHistotypeProperties().getParamId()); usedYParam = createSampledParameterUnderReferenceParameter(originalYParam, originalXParam); if (std::find (usedParametersId_.begin(),usedParametersId_.end(),usedYParam->getId()) == usedParametersId_.end()) usedParametersId_.push_back(usedYParam->getId()); pHistogramProperties->getHistotypeProperties().setParamId(usedYParam->getId()); } if (std::find (usedParametersId_.begin(),usedParametersId_.end(),originalXParam->getId()) == usedParametersId_.end()) usedParametersId_.push_back(originalXParam->getId()); pHistogramProperties->setParamId(originalXParam->getId()); pHistogramProperties->setZAxis(false); } else if(pHistogramProperties->getHistogramType() == "histogram2d"){ AMDA::Parameters::ParameterSPtr originalYParam = _parameterManager.getParameter(it->_originalParamId); ParameterAxes* xSerieParameterAxes = getParameterAxesByXSerieId(pHistogramProperties->getXId()); XSeriesProperties& xSerie = xSerieParameterAxes->getXSeriePropertiesById(pHistogramProperties->getXId()); AMDA::Parameters::ParameterSPtr originalXSerieParam = _parameterManager.getParameter(xSerieParameterAxes->_originalParamId); AMDA::Parameters::ParameterSPtr originalColorParam; if(pHistogramProperties->getHistotypeProperties().getParamId() != ""){ originalColorParam = _parameterManager.getParameter(pHistogramProperties->getHistotypeProperties().getParamId()); } getUsedParameters(originalXSerieParam,originalYParam,originalColorParam,pHistogramProperties->getResamplingProperties(),-1, usedXParam,usedYParam,usedColorParam ); if (std::find (usedParametersId_.begin(),usedParametersId_.end(),usedXParam->getId()) == usedParametersId_.end()) usedParametersId_.push_back(usedXParam->getId()); if (std::find (usedParametersId_.begin(),usedParametersId_.end(),usedYParam->getId()) == usedParametersId_.end()) usedParametersId_.push_back(usedYParam->getId()); if (originalColorParam != nullptr) { if (std::find (usedParametersId_.begin(),usedParametersId_.end(),usedColorParam->getId()) == usedParametersId_.end()) usedParametersId_.push_back(usedColorParam->getId()); pHistogramProperties->getHistotypeProperties().setParamId(usedColorParam->getId()); } pHistogramProperties->setZAxis(true); //link serie to this resampled parameter pHistogramProperties->setParamId(usedYParam->getId()); xSerie.setParamId(usedXParam->getId()); } } } } } void HistoPlot::getUsedParameters(AMDA::Parameters::ParameterSPtr originalXParam_,AMDA::Parameters::ParameterSPtr originalYParam_, AMDA::Parameters::ParameterSPtr originalZParam_, ResamplingProperties &resamplingProperties_, int /*maxResolution_*/,AMDA::Parameters::ParameterSPtr &usedXParam_, AMDA::Parameters::ParameterSPtr &usedYParam_,AMDA::Parameters::ParameterSPtr &usedZParam_) { switch (resamplingProperties_.getType()) { case ResamplingType::MANUAL : { LOG4CXX_ERROR(gLogger, "HistoPlot::getUsedParameters - ResamplingType::MANUAL not available"); } break; case ResamplingType::AUTO : case ResamplingType::XPARAM : LOG4CXX_DEBUG(gLogger, "HistoPlot::getUsedParameters - ResamplingType::XPARAM"); //get original parameter for xparam usedXParam_ = originalXParam_; if (originalXParam_ == originalYParam_) { //same original parameter => re-use xparam usedYParam_ = usedXParam_; } else { //create resampled parameter under times of xparam for yparam usedYParam_ = createSampledParameterUnderReferenceParameter(originalYParam_, originalXParam_); } break; case ResamplingType::YPARAM : LOG4CXX_DEBUG(gLogger, "HistoPlot::getUsedParameters - ResamplingType::YPARAM"); //get original parameter for yparam usedYParam_ = originalYParam_; if (originalXParam_ == originalYParam_) { //same original parameter => re-use yparam usedXParam_ = usedYParam_; } else { //create resampled parameter under times of yparam for cparam usedXParam_ = createSampledParameterUnderReferenceParameter(originalXParam_, originalYParam_); } break; } if (originalZParam_ != nullptr) { usedZParam_ = createSampledParameterUnderReferenceParameter(originalZParam_, usedYParam_); } } void HistoPlot::configureSeriesAxis(double startDate, double stopDate) { // map Range lColorAxeRange; boost::shared_ptr lZAxis = _panel->getColorAxis(); SeriesProperties lSeriesProperties; // Parse each parameter to define on which axis to draw series. for (auto param: _parameterAxesList) { for (auto pHistogramProperties : param.getHistogramSeriesPropertiesList()) { if(pHistogramProperties != nullptr){ boost::shared_ptr lXAxis = _panel->getAxis(pHistogramProperties->getXAxisId()); boost::shared_ptr lYAxis = _panel->getAxis(pHistogramProperties->getYAxisId()); lXAxis->_used = true; lYAxis->_used = true; if(pHistogramProperties->getHistogramType() == "histogram1d"){ std::vector> grid; double xBinSize = 0; // Call histo1DUtils to get yMin/yMax and send these to PanelPlotOutput::drawHistogram to draw the y axis histo1DUtils(startDate, stopDate,*pHistogramProperties.get(), grid, xBinSize); } else if(pHistogramProperties->getHistogramType() == "histogram2d"){ lZAxis->_used = true; if(_panel->_page->_superposeMode){ _globalStartTime = startDate; _globalStopTime = stopDate; } } } } } if (lZAxis != nullptr && lColorAxeRange.isSet()) lZAxis->setRange(lColorAxeRange); } void HistoPlot::configureAxisLegend () { // Y axis AxisLegendManager::configureYAxisLegendForSeries(this); // X axis AxisLegendManager::configureXAxisLegendForSeries(this); // Z axis AxisLegendManager::configureColorAxisLegendForSeries(this); } void HistoPlot::histo1DUtils(double startDate, double stopDate, HistogramSeriesProperties &pHistogramProperties, std::vector> &grid, double &xBinSize){ // Get X, Y axis. boost::shared_ptr lXAxis(_panel->getAxis(pHistogramProperties.getXAxisId())); boost::shared_ptr lYAxis(_panel->getAxis(pHistogramProperties.getYAxisId())); Range lXRange = lXAxis->getRange(); if(std::isnan(lXRange.getMin()) || std::isnan(lXRange.getMax())) return; Range lYRange = lYAxis->Axis::getRange(); double yMin = lYRange.getMin() ; double yMax = lYRange.getMax() ; unsigned int xBinNumber = pHistogramProperties.getManualProperties().getXBinNumber(); xBinSize = (lXRange.getMax() - lXRange.getMin())/ xBinNumber; ParameterData &xData = (*_pParameterValues)[pHistogramProperties.getParamId()]; int xStartIndex = 0; int xNbValues = 0; xData.getIntervalBounds(startDate, stopDate, xStartIndex, xNbValues); double* xValues =nullptr; double* yValues =nullptr; if(lXAxis->_scale==Axis::Scale::LOGARITHMIC) xValues = lXAxis->getComputedValues(xData.getValues(pHistogramProperties.getIndex(), xStartIndex),xNbValues,exp10(lXRange.getMin()), exp10(lXRange.getMax())); else xValues = xData.getValues(pHistogramProperties.getIndex(), xStartIndex); if(!pHistogramProperties.getHistotypeProperties().getParamId().empty()){ ParameterData &yData = (*_pParameterValues)[pHistogramProperties.getHistotypeProperties().getParamId()]; int yStartIndex = 0; int yNbValues = 0; xData.getIntervalBounds(startDate, stopDate, yStartIndex, yNbValues); yValues = yData.getValues(pHistogramProperties.getHistotypeProperties().getIndex(), yStartIndex); } pHistogramProperties.getHistotypeProperties().getHisto1DFunction()->apply(pHistogramProperties.getHistotypeProperties().getHisto1DFunction(),grid,xValues,yValues,xNbValues,lXRange, xBinSize, (lYAxis->_scale==Axis::Scale::LOGARITHMIC) ,yMin, yMax); if(lXAxis->_scale==Axis::Scale::LOGARITHMIC) free(xValues); if(!std::isnan(yMin)) lYRange.setMin(yMin); if(!std::isnan(yMax)) lYRange.setMax(yMax); lYRange._extend = lYAxis->isExtended(); lYAxis->setRange(lYRange); } void HistoPlot::drawHistogram(double startDate, double stopDate, std::string pParamId, HistogramSeriesProperties &pHistogramProperties){ if(pHistogramProperties.getHistogramType() == "histogram1d"){ if(_panel->_page->_superposeMode && pHistogramProperties.isPlotted()) return; std::vector> grid; Color color = pHistogramProperties.getColor(); double xBinSize = 0; boost::shared_ptr lYAxis(_panel->getAxis(pHistogramProperties.getYAxisId())); Range lYRange = lYAxis->getRange(); histo1DUtils(startDate, stopDate,pHistogramProperties, grid, xBinSize); PanelPlotOutput::drawHistogram(startDate,stopDate,pParamId, pHistogramProperties); PanelPlotOutput::drawHistogramBoxes(grid,color,xBinSize, lYRange.getMin(), pHistogramProperties.getManualProperties().hasStairs()); pHistogramProperties.setPlotted(true); } else { if(_panel->_page->_superposeMode && pHistogramProperties.isPlotted()) return; if(_panel->_page->_superposeMode){ startDate= _globalStartTime; stopDate = _globalStopTime; } // Get X, Y and Z axis. boost::shared_ptr lXAxis(_panel->getAxis(pHistogramProperties.getXAxisId())); boost::shared_ptr lYAxis(_panel->getAxis(pHistogramProperties.getYAxisId())); //boost::shared_ptr lZAxis(_panel->getAxis(pHistogramProperties.getZAxisId())); boost::shared_ptr lZAxis = _panel->getColorAxis(); Range lXRange = lXAxis->getRange(); Range lYRange = lYAxis->getRange(); Range lZRange = lZAxis->getRequestedRange(); Color minValColor = lZAxis->getMinValColor(); Color maxValColor = lZAxis->getMaxValColor(); GridPart grid; MatrixGrid matrixGrid; int smoothFactor = pHistogramProperties.getHistotypeProperties().getSmoothFactor(); unsigned int xBinNumber = pHistogramProperties.getManualProperties().getXBinNumber(); unsigned int yBinNumber = pHistogramProperties.getManualProperties().getYBinNumber(); double xBinSize = (lXRange.getMax() - lXRange.getMin())/ xBinNumber; double yBinSize = (lYRange.getMax() - lYRange.getMin())/ yBinNumber; //get parameter x data for this serie ParameterAxes* xSerieParameterAxes = getParameterAxesByXSerieId(pHistogramProperties.getXId()); XSeriesProperties& xSerie = xSerieParameterAxes->getXSeriePropertiesById(pHistogramProperties.getXId()); ParameterData &xData = (*_pParameterValues)[xSerie.getParamId()]; ParameterData &yData = (*_pParameterValues)[pHistogramProperties.getParamId()]; ParameterData &zData = (*_pParameterValues)[pHistogramProperties.getHistotypeProperties().getParamId()]; int xStartIndex; int yStartIndex; int zStartIndex; int xNbValues; int yNbValues; int zNbValues; double zMin = NAN ; double zMax = NAN ; xData.getIntervalBounds(startDate, stopDate, xStartIndex, xNbValues); yData.getIntervalBounds(startDate, stopDate, yStartIndex, yNbValues); zData.getIntervalBounds(startDate, stopDate, zStartIndex, zNbValues); double* xValues; double* yValues; double* zValues; if(lXAxis->_scale==Axis::Scale::LOGARITHMIC) xValues = lXAxis->getComputedValues(xData.getValues(xSerie.getIndex(), xStartIndex),xNbValues,exp10(lXRange.getMin()), exp10(lXRange.getMax())); else xValues = xData.getValues(xSerie.getIndex(), xStartIndex); if(lYAxis->_scale==Axis::Scale::LOGARITHMIC) yValues = lYAxis->getComputedValues(yData.getValues(pHistogramProperties.getIndex(), yStartIndex),yNbValues,exp10(lYRange.getMin()), exp10(lYRange.getMax())); else yValues = yData.getValues(pHistogramProperties.getIndex(), yStartIndex); zValues = zData.getValues(pHistogramProperties.getHistotypeProperties().getIndex(), zStartIndex); for (unsigned int i(0); i < xBinNumber; ++i) { for (unsigned int j(0); j < yBinNumber; ++j) { grid.x[0] = lXRange.getMin()+xBinSize*i; grid.x[1] = grid.x[0]+xBinSize; grid.y[0] = lYRange.getMin() + yBinSize*j; grid.y[1] = grid.y[0]+yBinSize; grid.value = NAN; grid.isColorIndex= false; matrixGrid.push_back(grid); } } pHistogramProperties.getHistotypeProperties().getHisto2DFunction()->apply(matrixGrid, xValues, yValues, zValues, xNbValues,lXRange,lYRange, xBinNumber, yBinNumber, zMin, zMax, smoothFactor); if(lXAxis->_scale==Axis::Scale::LOGARITHMIC) free(xValues); if(lYAxis->_scale==Axis::Scale::LOGARITHMIC) free(yValues); if(std::isnan(lZRange.getMin())) lZRange.setMin(zMin); if(std::isnan(lZRange.getMax())) lZRange.setMax(zMax); lZRange._extend = lZAxis->isExtended(); lZAxis->setRange(lZRange); PanelPlotOutput::drawHistogram(startDate,stopDate,pParamId, pHistogramProperties); PanelPlotOutput::drawMatrix(matrixGrid, zMin, zMax, minValColor,maxValColor, lZAxis->_color._colorMapIndex, false); pHistogramProperties.setPlotted(true); } } void HistoPlot::resetPlot() { for (auto param: _parameterAxesList) { for (auto pHistogramProperties : param.getHistogramSeriesPropertiesList()) { if(pHistogramProperties != nullptr){ if(pHistogramProperties->getHistogramType() == "histogram1d"){ pHistogramProperties->getHistotypeProperties().getHisto1DFunction()->resetCache(); } pHistogramProperties->setPlotted(false); } } } PanelPlotOutput::resetPlot(); } } // Events from 'tt' in TIMEMIN - TIMEMAX