<commit_before>// Copyright 2013-2015, Durachenko Aleksey V. <durachenko.aleksey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
#include "qsesppsyncsignallinearplot.h"
#include <QPainter>
#include "qseabstractsppsyncdatasource.h"
#include "qsehelper.h"

QseSppSyncSignalLinearPlot::QseSppSyncSignalLinearPlot(QObject *parent) :
    QseAbstractSppSyncSignalPlot(parent)
{
    setZeroPoint(Middle);
}

void QseSppSyncSignalLinearPlot::draw(QPainter *painter, const QRect &rect,
        const QseSppGeometry &geometry)
{
    if (isVisible(rect, geometry))
    {
        QsePeakArray peaks = dataSource()->read(geometry, rect.width());
        if (!peaks.isEmpty())
        {
            int offset = 0;
            if (geometry.x() < 0)
                offset = geometry.x();

            painter->save();
            painter->setPen(pen());
            painter->setOpacity(opacity());
            if (peaks.hasMaximums())
                drawAsPeaks(painter, peaks, rect, geometry, offset);
            else
                drawAsLines(painter, peaks, rect, geometry, offset);
            painter->restore();
        }
    }

    QseAbstractSppSyncSignalPlot::draw(painter, rect, geometry);
}

void QseSppSyncSignalLinearPlot::drawAsLines(QPainter *painter,
        const QsePeakArray &peaks, const QRect &rect,
        const QseSppGeometry &geometry, int offset)
{
    const qint64 pps = -geometry.samplesPerPixel();
    const QVector<double> &points = peaks.minimums();

    double zero;
    switch (zeroPoint())
    {
    case Top:
        zero = 0;
        break;
    case Middle:
        zero = rect.height()/2.0;
        break;
    case Bottom:
        zero = rect.height();
        break;
    }

    int space = 0; // skip pixel from left bound
    int first = 0; // index of first visible points
    if (offset < 0)
        space = pps * -offset;
    else
        first = offset;

    for (int i = first+1; i < points.count(); ++i)
    {
        double x1 = space + (i-1-first)*pps;
        double x2 = x1 + pps;
        double y1 = zero-(geometry.y()+points[i-1])*rect.height()/geometry.height();
        double y2 = zero-(geometry.y()+points[i])*rect.height()/geometry.height();

        if (x1 >= rect.width())
            break;

        if ((y1 < 0 && y2 < 0) || (y1 >= rect.height() && y2 >= rect.height()))
            continue;

        double yy1 = y1;
        double yy2 = y2;
        double xx1 = x1;
        double xx2 = x2;

        if (y1 >= rect.height())
            Qse::calcIntersection(x1, y1, x2, y2, x1, rect.height()-1, x2, rect.height()-1, xx1, yy1);
        if (y2 >= rect.height())
            Qse::calcIntersection(x1, y1, x2, y2, x1, rect.height()-1, x2, rect.height()-1, xx2, yy2);
        if (y1 < 0)
            Qse::calcIntersection(x1, y1, x2, y2, x1, 0, x2, 0, xx1, yy1);
        if (y2 < 0)
            Qse::calcIntersection(x1, y1, x2, y2, x1, 0, x2, 0, xx2, yy2);

        painter->drawLine(QPointF(xx1, yy1), QPointF(xx2, yy2));
    }
}

void QseSppSyncSignalLinearPlot::drawAsPeaks(QPainter *painter,
        const QsePeakArray &peaks, const QRect &rect,
        const QseSppGeometry &geometry, int offset)
{
    const QVector<double> &minimums = peaks.minimums();
    const QVector<double> &maximums = peaks.maximums();

    double zero;
    switch (zeroPoint())
    {
    case Top:
        zero = 0;
        break;
    case Middle:
        zero = rect.height()/2.0;
        break;
    case Bottom:
        zero = rect.height();
        break;
    }

    int space = 0; // skip pixel from left bound
    int first = 0; // index of first visible minimum(maximum)
    if (offset < 0)
        space = -offset / geometry.samplesPerPixel();
    else
        first = offset;

    if (first >= maximums.count())
        return;

    double prevMin = zero-(geometry.y()+minimums[first])*rect.height()/geometry.height();
    double prevMax = zero-(geometry.y()+maximums[first])*rect.height()/geometry.height();
    double x1 = space;
    double x2 = space;
    if (x1 >= rect.width())
        return;
    if (prevMin < 0.0) prevMin = 0.0;
    if (prevMax < 0.0) prevMax = 0.0;
    if (prevMin >= rect.height()) prevMin = rect.height()-1;
    if (prevMax >= rect.height()) prevMax = rect.height()-1;
    if (prevMin == prevMax)
        painter->drawPoint(QPointF(x1, prevMin));
    else
        painter->drawLine(QPointF(x1, prevMin), QPointF(x2, prevMax));

    for (int i = first+1; i < minimums.count(); ++i)
    {
        x1 = space + i - first;
        x2 = space + i - first;
        if (x1 >= rect.width())
            break;
        double curMin = zero-(geometry.y()+minimums[i])*rect.height()/geometry.height();
        double curMax = zero-(geometry.y()+maximums[i])*rect.height()/geometry.height();
        if (! ((curMin < 0.0 && curMax < 0.0)
              || (curMin >= rect.height() && curMax >= rect.height())))
        {
            if (curMin < 0.0) curMin = 0.0;
            if (curMax < 0.0) curMax = 0.0;
            if (curMin >= rect.height()) curMin = rect.height()-1;
            if (curMax >= rect.height()) curMax = rect.height()-1;

            // fill the gap between the two lines, if exists
            if (curMin < prevMax) curMin = prevMax-1;
            if (curMax > prevMin) curMax = prevMin+1;

            //
            prevMin = curMin;
            prevMax = curMax;

            if (curMin == curMax)
                painter->drawPoint(QPointF(x1, curMin));
            else
                painter->drawLine(QPointF(x1, curMin), QPointF(x2, curMax));
        }
    }
}
<commit_msg>fix warning<commit_after>// Copyright 2013-2015, Durachenko Aleksey V. <durachenko.aleksey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
#include "qsesppsyncsignallinearplot.h"
#include <QPainter>
#include "qseabstractsppsyncdatasource.h"
#include "qsehelper.h"

QseSppSyncSignalLinearPlot::QseSppSyncSignalLinearPlot(QObject *parent) :
    QseAbstractSppSyncSignalPlot(parent)
{
    setZeroPoint(Middle);
}

void QseSppSyncSignalLinearPlot::draw(QPainter *painter, const QRect &rect,
        const QseSppGeometry &geometry)
{
    if (isVisible(rect, geometry))
    {
        QsePeakArray peaks = dataSource()->read(geometry, rect.width());
        if (!peaks.isEmpty())
        {
            int offset = 0;
            if (geometry.x() < 0)
                offset = geometry.x();

            painter->save();
            painter->setPen(pen());
            painter->setOpacity(opacity());
            if (peaks.hasMaximums())
                drawAsPeaks(painter, peaks, rect, geometry, offset);
            else
                drawAsLines(painter, peaks, rect, geometry, offset);
            painter->restore();
        }
    }

    QseAbstractSppSyncSignalPlot::draw(painter, rect, geometry);
}

void QseSppSyncSignalLinearPlot::drawAsLines(QPainter *painter,
        const QsePeakArray &peaks, const QRect &rect,
        const QseSppGeometry &geometry, int offset)
{
    const qint64 pps = -geometry.samplesPerPixel();
    const QVector<double> &points = peaks.minimums();

    double zero = 0;
    switch (zeroPoint())
    {
    case Top:
        zero = 0;
        break;
    case Middle:
        zero = rect.height()/2.0;
        break;
    case Bottom:
        zero = rect.height();
        break;
    }

    int space = 0; // skip pixel from left bound
    int first = 0; // index of first visible points
    if (offset < 0)
        space = pps * -offset;
    else
        first = offset;

    for (int i = first+1; i < points.count(); ++i)
    {
        double x1 = space + (i-1-first)*pps;
        double x2 = x1 + pps;
        double y1 = zero-(geometry.y()+points[i-1])*rect.height()/geometry.height();
        double y2 = zero-(geometry.y()+points[i])*rect.height()/geometry.height();

        if (x1 >= rect.width())
            break;

        if ((y1 < 0 && y2 < 0) || (y1 >= rect.height() && y2 >= rect.height()))
            continue;

        double yy1 = y1;
        double yy2 = y2;
        double xx1 = x1;
        double xx2 = x2;

        if (y1 >= rect.height())
            Qse::calcIntersection(x1, y1, x2, y2, x1, rect.height()-1, x2, rect.height()-1, xx1, yy1);
        if (y2 >= rect.height())
            Qse::calcIntersection(x1, y1, x2, y2, x1, rect.height()-1, x2, rect.height()-1, xx2, yy2);
        if (y1 < 0)
            Qse::calcIntersection(x1, y1, x2, y2, x1, 0, x2, 0, xx1, yy1);
        if (y2 < 0)
            Qse::calcIntersection(x1, y1, x2, y2, x1, 0, x2, 0, xx2, yy2);

        painter->drawLine(QPointF(xx1, yy1), QPointF(xx2, yy2));
    }
}

void QseSppSyncSignalLinearPlot::drawAsPeaks(QPainter *painter,
        const QsePeakArray &peaks, const QRect &rect,
        const QseSppGeometry &geometry, int offset)
{
    const QVector<double> &minimums = peaks.minimums();
    const QVector<double> &maximums = peaks.maximums();

    double zero = 0;
    switch (zeroPoint())
    {
    case Top:
        zero = 0;
        break;
    case Middle:
        zero = rect.height()/2.0;
        break;
    case Bottom:
        zero = rect.height();
        break;
    }

    int space = 0; // skip pixel from left bound
    int first = 0; // index of first visible minimum(maximum)
    if (offset < 0)
        space = -offset / geometry.samplesPerPixel();
    else
        first = offset;

    if (first >= maximums.count())
        return;

    double prevMin = zero-(geometry.y()+minimums[first])*rect.height()/geometry.height();
    double prevMax = zero-(geometry.y()+maximums[first])*rect.height()/geometry.height();
    double x1 = space;
    double x2 = space;
    if (x1 >= rect.width())
        return;
    if (prevMin < 0.0) prevMin = 0.0;
    if (prevMax < 0.0) prevMax = 0.0;
    if (prevMin >= rect.height()) prevMin = rect.height()-1;
    if (prevMax >= rect.height()) prevMax = rect.height()-1;
    if (prevMin == prevMax)
        painter->drawPoint(QPointF(x1, prevMin));
    else
        painter->drawLine(QPointF(x1, prevMin), QPointF(x2, prevMax));

    for (int i = first+1; i < minimums.count(); ++i)
    {
        x1 = space + i - first;
        x2 = space + i - first;
        if (x1 >= rect.width())
            break;
        double curMin = zero-(geometry.y()+minimums[i])*rect.height()/geometry.height();
        double curMax = zero-(geometry.y()+maximums[i])*rect.height()/geometry.height();
        if (! ((curMin < 0.0 && curMax < 0.0)
              || (curMin >= rect.height() && curMax >= rect.height())))
        {
            if (curMin < 0.0) curMin = 0.0;
            if (curMax < 0.0) curMax = 0.0;
            if (curMin >= rect.height()) curMin = rect.height()-1;
            if (curMax >= rect.height()) curMax = rect.height()-1;

            // fill the gap between the two lines, if exists
            if (curMin < prevMax) curMin = prevMax-1;
            if (curMax > prevMin) curMax = prevMin+1;

            //
            prevMin = curMin;
            prevMax = curMax;

            if (curMin == curMax)
                painter->drawPoint(QPointF(x1, curMin));
            else
                painter->drawLine(QPointF(x1, curMin), QPointF(x2, curMax));
        }
    }
}
<|endoftext|>


<commit_before>// @(#)root/roostats:$Id$
// Author: Kyle Cranmer, George Lewis
/*************************************************************************
 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//_________________________________________________
/*
BEGIN_HTML

END_HTML
*/
//

#include "RooStats/HistFactory/Systematics.h"
#include "RooStats/HistFactory/HistFactoryException.h"

// Constraints
std::string RooStats::HistFactory::Constraint::Name( Constraint::Type type ) {

  if( type == Constraint::Gaussian ) return "Gaussian";
  if( type == Constraint::Poisson )  return "Poisson";
  return "";
}

RooStats::HistFactory::Constraint::Type RooStats::HistFactory::Constraint::GetType( const std::string& Name ) {

  if( Name == "" ) {
    std::cout << "Error: Given empty name for ConstraintType" << std::endl;
    throw hf_exc();
  }

  else if ( Name == "Gaussian" || Name == "Gauss" ) {
    return Constraint::Gaussian;
  }

  else if ( Name == "Poisson" || Name == "Pois" ) {
    return Constraint::Poisson;
  }

  else {
    std::cout << "Error: Unknown name given for Constraint Type: " << Name << std::endl;
    throw hf_exc();
  }

}

// Norm Factor
RooStats::HistFactory::NormFactor::NormFactor() : fName(""), fVal(1.0),
						  fLow(1.0), fHigh(1.0),
						  fConst(true) {;}

void RooStats::HistFactory::NormFactor::Print( std::ostream& stream ) {
  stream << "\t \t Name: " << fName
	 << "\t Val: " << fVal
	 << "\t Low: " << fLow
	 << "\t High: " << fHigh
	 << "\t Const: " << fConst
	 << std::endl;
}

void RooStats::HistFactory::NormFactor::PrintXML( std::ostream& xml ) {
  xml << "      <NormFactor Name=\"" << GetName() << "\" "
      << " Val=\""   << GetVal()   << "\" "
      << " High=\""  << GetHigh()  << "\" "
      << " Low=\""   << GetLow()   << "\" "
      << " Const=\"" << (GetConst() ? std::string("True") : std::string("False")) << "\" "
      << "  /> " << std::endl;
}

// Overall Sys
void RooStats::HistFactory::OverallSys::Print( std::ostream& stream ) {
  stream << "\t \t Name: " << fName
	 << "\t Low: " << fLow
	 << "\t High: " << fHigh
	 << std::endl;
}

void RooStats::HistFactory::OverallSys::PrintXML( std::ostream& xml ) {
  xml << "      <OverallSys Name=\"" << GetName() << "\" "
      << " High=\"" << GetHigh() << "\" "
      << " Low=\""  << GetLow()  << "\" "
      << "  /> " << std::endl;
}

// HistoSys
TH1* RooStats::HistFactory::HistoSys::GetHistoLow() {
  TH1* histo_low = (TH1*) fhLow.GetObject();
  return histo_low;
}

TH1* RooStats::HistFactory::HistoSys::GetHistoHigh() {
  TH1* histo_high = (TH1*) fhHigh.GetObject();
  return histo_high;
}

void RooStats::HistFactory::HistoSys::Print( std::ostream& stream ) {
  stream << "\t \t Name: " << fName
	 << "\t InputFileLow: " << fInputFileLow
	 << "\t HistoNameLow: " << fHistoNameLow
	 << "\t HistoPathLow: " << fHistoPathLow
	 << "\t InputFileHigh: " << fInputFileHigh
	 << "\t HistoNameHigh: " << fHistoNameHigh
	 << "\t HistoPathHigh: " << fHistoPathHigh
	 << std::endl;
}

void RooStats::HistFactory::HistoSys::PrintXML( std::ostream& xml ) {
  xml << "      <HistoSys Name=\"" << GetName() << "\" "
      << " InputFileLow=\""  << GetInputFileLow()  << "\" "
      << " HistoNameLow=\""  << GetHistoNameLow()  << "\" "
      << " HistoPathLow=\""  << GetHistoPathLow()  << "\" "

      << " InputFileHigh=\""  << GetInputFileHigh()  << "\" "
      << " HistoNameHigh=\""  << GetHistoNameHigh()  << "\" "
      << " HistoPathHigh=\""  << GetHistoPathHigh()  << "\" "
      << "  /> " << std::endl;
}

void RooStats::HistFactory::HistoSys::writeToFile( const std::string& FileName,
						   const std::string& DirName ) {

  // This saves the histograms to a file and
  // changes the name of the local file and histograms

  TH1* histLow = GetHistoLow();
  if( histLow==NULL ) {
    std::cout << "Error: Cannot write " << GetName()
	      << " to file: " << FileName
	      << " HistoLow is NULL"
	      << std::endl;
    throw hf_exc();
  }
  histLow->Write();
  fInputFileLow = FileName;
  fHistoPathLow = DirName;
  fHistoNameLow = histLow->GetName();

  TH1* histHigh = GetHistoHigh();
  if( histHigh==NULL ) {
    std::cout << "Error: Cannot write " << GetName()
	      << " to file: " << FileName
	      << " HistoHigh is NULL"
	      << std::endl;
    throw hf_exc();
  }
  histHigh->Write();
  fInputFileHigh = FileName;
  fHistoPathHigh = DirName;
  fHistoNameHigh = histHigh->GetName();

  return;

}

// Shape Sys

TH1* RooStats::HistFactory::ShapeSys::GetErrorHist() {
  TH1* error_hist = (TH1*) fhError.GetObject();
  return error_hist;
}

void RooStats::HistFactory::ShapeSys::Print( std::ostream& stream ) {
  stream << "\t \t Name: " << fName
	 << "\t InputFile: " << fInputFile
	 << "\t HistoName: " << fHistoName
	 << "\t HistoPath: " << fHistoPath
	 << std::endl;
}

void RooStats::HistFactory::ShapeSys::PrintXML( std::ostream& xml ) {
  xml << "      <ShapeSys Name=\"" << GetName() << "\" "
      << " InputFile=\""  << GetInputFile()  << "\" "
      << " HistoName=\""  << GetHistoName()  << "\" "
      << " HistoPath=\""  << GetHistoPath()  << "\" "
      << " ConstraintType=\"" << std::string(Constraint::Name(GetConstraintType())) << "\" "
      << "  /> " << std::endl;
}

void RooStats::HistFactory::ShapeSys::writeToFile( const std::string& FileName,
						   const std::string& DirName ) {

  TH1* histError = GetErrorHist();
  if( histError==NULL ) {
    std::cout << "Error: Cannot write " << GetName()
	      << " to file: " << FileName
	      << " ErrorHist is NULL"
	      << std::endl;
    throw hf_exc();
  }
  histError->Write();
  fInputFile = FileName;
  fHistoPath = DirName;
  fHistoName = histError->GetName();

  return;

}

// HistoFactor

void RooStats::HistFactory::HistoFactor::Print( std::ostream& stream ) {
  stream << "\t \t Name: " << fName
	 << "\t InputFileLow: " << fInputFileLow
	 << "\t HistoNameLow: " << fHistoNameLow
	 << "\t HistoPathLow: " << fHistoPathLow
	 << "\t InputFileHigh: " << fInputFileHigh
	 << "\t HistoNameHigh: " << fHistoNameHigh
	 << "\t HistoPathHigh: " << fHistoPathHigh
	 << std::endl;
}

TH1* RooStats::HistFactory::HistoFactor::GetHistoLow() {
  TH1* histo_low = (TH1*) fhLow.GetObject();
  return histo_low;
}

TH1* RooStats::HistFactory::HistoFactor::GetHistoHigh() {
  TH1* histo_high = (TH1*) fhHigh.GetObject();
  return histo_high;
}

void RooStats::HistFactory::HistoFactor::writeToFile( const std::string& FileName,
						      const std::string& DirName ) {

  // This saves the histograms to a file and
  // changes the name of the local file and histograms

  TH1* histLow = GetHistoLow();
  if( histLow==NULL ) {
    std::cout << "Error: Cannot write " << GetName()
	      << " to file: " << FileName
	      << " HistoLow is NULL"
	      << std::endl;
    throw hf_exc();
  }
  histLow->Write();
  fInputFileLow = FileName;
  fHistoPathLow = DirName;
  fHistoNameLow = histLow->GetName();

  TH1* histHigh = GetHistoHigh();
  if( histHigh==NULL ) {
    std::cout << "Error: Cannot write " << GetName()
	      << " to file: " << FileName
	      << " HistoHigh is NULL"
	      << std::endl;
    throw hf_exc();
  }
  histHigh->Write();
  fInputFileHigh = FileName;
  fHistoPathHigh = DirName;
  fHistoNameHigh = histHigh->GetName();

  return;

}

void RooStats::HistFactory::HistoFactor::PrintXML( std::ostream& xml ) {
  xml << "      <HistoFactor Name=\"" << GetName() << "\" "

      << " InputFileLow=\""  << GetInputFileLow()  << "\" "
      << " HistoNameLow=\""  << GetHistoNameLow()  << "\" "
      << " HistoPathLow=\""  << GetHistoPathLow()  << "\" "

      << " InputFileHigh=\""  << GetInputFileHigh()  << "\" "
      << " HistoNameHigh=\""  << GetHistoNameHigh()  << "\" "
      << " HistoPathHigh=\""  << GetHistoPathHigh()  << "\" "
      << "  /> " << std::endl;
}

// Shape Factor
RooStats::HistFactory::ShapeFactor::ShapeFactor() : fConstant(false),
						    fHasInitialShape(false),
						    fhInitialShape(NULL) {;}

void RooStats::HistFactory::ShapeFactor::Print( std::ostream& stream ) {

  stream << "\t \t Name: " << fName << std::endl;

  if( fHistoName != "" ) {
    stream << "\t \t "
	   << " Shape Hist Name: " << fHistoName
	   << " Shape Hist Path Name: " << fHistoPath
	   << " Shape Hist FileName: " << fInputFile
	   << std::endl;
  }

  if( fConstant ) { stream << "\t \t ( Constant ): " << std::endl; }

}

void RooStats::HistFactory::ShapeFactor::writeToFile( const std::string& FileName,
						      const std::string& DirName ) {

  if( HasInitialShape() ) {
    TH1* histInitialShape = GetInitialShape();
    if( histInitialShape==NULL ) {
      std::cout << "Error: Cannot write " << GetName()
		<< " to file: " << FileName
		<< " InitialShape is NULL"
		<< std::endl;
      throw hf_exc();
    }
    histInitialShape->Write();
    fInputFile = FileName;
    fHistoPath = DirName;
    fHistoName = histInitialShape->GetName();
  }

  return;

}

void RooStats::HistFactory::ShapeFactor::PrintXML( std::ostream& xml ) {
  xml << "      <ShapeFactor Name=\"" << GetName() << "\" ";
  if( fHasInitialShape ) {
    xml << " InputFile=\""  << GetInputFile()  << "\" "
	<< " HistoName=\""  << GetHistoName()  << "\" "
	<< " HistoPath=\""  << GetHistoPath()  << "\" ";
  }
  xml << "  /> " << std::endl;
}

// Stat Error Config
void RooStats::HistFactory::StatErrorConfig::Print( std::ostream& stream ) {
  stream << "\t \t RelErrorThreshold: " << fRelErrorThreshold
	 << "\t ConstraintType: " << Constraint::Name( fConstraintType )
	 << std::endl;
}

void RooStats::HistFactory::StatErrorConfig::PrintXML( std::ostream& xml ) {
  xml << "    <StatErrorConfig RelErrorThreshold=\"" << GetRelErrorThreshold()
      << "\" "
      << "ConstraintType=\"" << Constraint::Name( GetConstraintType() )
      << "\" "
      << "/> " << std::endl << std::endl;

}

// Stat Error
TH1* RooStats::HistFactory::StatError::GetErrorHist() {
  return (TH1*) fhError.GetObject();
}

void RooStats::HistFactory::StatError::Print( std::ostream& stream ) {
  stream << "\t \t Activate: " << fActivate
	 << "\t InputFile: " << fInputFile
	 << "\t HistoName: " << fHistoName
	 << "\t histoPath: " << fHistoPath
	 << std::endl;
}

void RooStats::HistFactory::StatError::PrintXML( std::ostream& xml ) {

  if( GetActivate() ) {
    xml << "      <StatError Activate=\""
	<< (GetActivate() ? std::string("True") : std::string("False"))
	<< "\" "
	<< " InputFile=\"" << GetInputFile() << "\" "
	<< " HistoName=\"" << GetHistoName() << "\" "
	<< " HistoPath=\"" << GetHistoPath() << "\" "
	<< " /> " << std::endl;
  }

}

void RooStats::HistFactory::StatError::writeToFile( const std::string& OutputFileName,
						    const std::string& DirName ) {

  if( fUseHisto ) {

    std::string statErrorHistName = "statisticalErrors";

    TH1* hStatError = GetErrorHist();
    if( hStatError == NULL ) {
      std::cout << "Error: Stat Error error hist is NULL" << std::endl;
      throw hf_exc();
    }
    hStatError->Write(statErrorHistName.c_str());

    fInputFile = OutputFileName;
    fHistoName = statErrorHistName;
    fHistoPath = DirName;

  }

  return;

}
<commit_msg>Fix the PrintXML according to HistFactory.dtd  (InputFileLow/High -> HistoFileLow/High) This fixes ROOT-5480<commit_after>// @(#)root/roostats:$Id$
// Author: Kyle Cranmer, George Lewis
/*************************************************************************
 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//_________________________________________________
/*
BEGIN_HTML

END_HTML
*/
//

#include "RooStats/HistFactory/Systematics.h"
#include "RooStats/HistFactory/HistFactoryException.h"

// Constraints
std::string RooStats::HistFactory::Constraint::Name( Constraint::Type type ) {

  if( type == Constraint::Gaussian ) return "Gaussian";
  if( type == Constraint::Poisson )  return "Poisson";
  return "";
}

RooStats::HistFactory::Constraint::Type RooStats::HistFactory::Constraint::GetType( const std::string& Name ) {

  if( Name == "" ) {
    std::cout << "Error: Given empty name for ConstraintType" << std::endl;
    throw hf_exc();
  }

  else if ( Name == "Gaussian" || Name == "Gauss" ) {
    return Constraint::Gaussian;
  }

  else if ( Name == "Poisson" || Name == "Pois" ) {
    return Constraint::Poisson;
  }

  else {
    std::cout << "Error: Unknown name given for Constraint Type: " << Name << std::endl;
    throw hf_exc();
  }

}

// Norm Factor
RooStats::HistFactory::NormFactor::NormFactor() : fName(""), fVal(1.0),
						  fLow(1.0), fHigh(1.0),
						  fConst(true) {;}

void RooStats::HistFactory::NormFactor::Print( std::ostream& stream ) {
  stream << "\t \t Name: " << fName
	 << "\t Val: " << fVal
	 << "\t Low: " << fLow
	 << "\t High: " << fHigh
	 << "\t Const: " << fConst
	 << std::endl;
}

void RooStats::HistFactory::NormFactor::PrintXML( std::ostream& xml ) {
  xml << "      <NormFactor Name=\"" << GetName() << "\" "
      << " Val=\""   << GetVal()   << "\" "
      << " High=\""  << GetHigh()  << "\" "
      << " Low=\""   << GetLow()   << "\" "
      << " Const=\"" << (GetConst() ? std::string("True") : std::string("False")) << "\" "
      << "  /> " << std::endl;
}

// Overall Sys
void RooStats::HistFactory::OverallSys::Print( std::ostream& stream ) {
  stream << "\t \t Name: " << fName
	 << "\t Low: " << fLow
	 << "\t High: " << fHigh
	 << std::endl;
}

void RooStats::HistFactory::OverallSys::PrintXML( std::ostream& xml ) {
  xml << "      <OverallSys Name=\"" << GetName() << "\" "
      << " High=\"" << GetHigh() << "\" "
      << " Low=\""  << GetLow()  << "\" "
      << "  /> " << std::endl;
}

// HistoSys
TH1* RooStats::HistFactory::HistoSys::GetHistoLow() {
  TH1* histo_low = (TH1*) fhLow.GetObject();
  return histo_low;
}

TH1* RooStats::HistFactory::HistoSys::GetHistoHigh() {
  TH1* histo_high = (TH1*) fhHigh.GetObject();
  return histo_high;
}

void RooStats::HistFactory::HistoSys::Print( std::ostream& stream ) {
  stream << "\t \t Name: " << fName
	 << "\t HistoFileLow: " << fInputFileLow
	 << "\t HistoNameLow: " << fHistoNameLow
	 << "\t HistoPathLow: " << fHistoPathLow
	 << "\t HistoFileHigh: " << fInputFileHigh
	 << "\t HistoNameHigh: " << fHistoNameHigh
	 << "\t HistoPathHigh: " << fHistoPathHigh
	 << std::endl;
}

void RooStats::HistFactory::HistoSys::PrintXML( std::ostream& xml ) {
  xml << "      <HistoSys Name=\"" << GetName() << "\" "
      << " HistoFileLow=\""  << GetInputFileLow()  << "\" "
      << " HistoNameLow=\""  << GetHistoNameLow()  << "\" "
      << " HistoPathLow=\""  << GetHistoPathLow()  << "\" "

      << " HistoFileHigh=\""  << GetInputFileHigh()  << "\" "
      << " HistoNameHigh=\""  << GetHistoNameHigh()  << "\" "
      << " HistoPathHigh=\""  << GetHistoPathHigh()  << "\" "
      << "  /> " << std::endl;
}

void RooStats::HistFactory::HistoSys::writeToFile( const std::string& FileName,
						   const std::string& DirName ) {

  // This saves the histograms to a file and
  // changes the name of the local file and histograms

  TH1* histLow = GetHistoLow();
  if( histLow==NULL ) {
    std::cout << "Error: Cannot write " << GetName()
	      << " to file: " << FileName
	      << " HistoLow is NULL"
	      << std::endl;
    throw hf_exc();
  }
  histLow->Write();
  fInputFileLow = FileName;
  fHistoPathLow = DirName;
  fHistoNameLow = histLow->GetName();

  TH1* histHigh = GetHistoHigh();
  if( histHigh==NULL ) {
    std::cout << "Error: Cannot write " << GetName()
	      << " to file: " << FileName
	      << " HistoHigh is NULL"
	      << std::endl;
    throw hf_exc();
  }
  histHigh->Write();
  fInputFileHigh = FileName;
  fHistoPathHigh = DirName;
  fHistoNameHigh = histHigh->GetName();

  return;

}

// Shape Sys

TH1* RooStats::HistFactory::ShapeSys::GetErrorHist() {
  TH1* error_hist = (TH1*) fhError.GetObject();
  return error_hist;
}

void RooStats::HistFactory::ShapeSys::Print( std::ostream& stream ) {
  stream << "\t \t Name: " << fName
	 << "\t InputFile: " << fInputFile
	 << "\t HistoName: " << fHistoName
	 << "\t HistoPath: " << fHistoPath
	 << std::endl;
}

void RooStats::HistFactory::ShapeSys::PrintXML( std::ostream& xml ) {
  xml << "      <ShapeSys Name=\"" << GetName() << "\" "
      << " InputFile=\""  << GetInputFile()  << "\" "
      << " HistoName=\""  << GetHistoName()  << "\" "
      << " HistoPath=\""  << GetHistoPath()  << "\" "
      << " ConstraintType=\"" << std::string(Constraint::Name(GetConstraintType())) << "\" "
      << "  /> " << std::endl;
}

void RooStats::HistFactory::ShapeSys::writeToFile( const std::string& FileName,
						   const std::string& DirName ) {

  TH1* histError = GetErrorHist();
  if( histError==NULL ) {
    std::cout << "Error: Cannot write " << GetName()
	      << " to file: " << FileName
	      << " ErrorHist is NULL"
	      << std::endl;
    throw hf_exc();
  }
  histError->Write();
  fInputFile = FileName;
  fHistoPath = DirName;
  fHistoName = histError->GetName();

  return;

}

// HistoFactor

void RooStats::HistFactory::HistoFactor::Print( std::ostream& stream ) {
  stream << "\t \t Name: " << fName
	 << "\t InputFileLow: " << fInputFileLow
	 << "\t HistoNameLow: " << fHistoNameLow
	 << "\t HistoPathLow: " << fHistoPathLow
	 << "\t InputFileHigh: " << fInputFileHigh
	 << "\t HistoNameHigh: " << fHistoNameHigh
	 << "\t HistoPathHigh: " << fHistoPathHigh
	 << std::endl;
}

TH1* RooStats::HistFactory::HistoFactor::GetHistoLow() {
  TH1* histo_low = (TH1*) fhLow.GetObject();
  return histo_low;
}

TH1* RooStats::HistFactory::HistoFactor::GetHistoHigh() {
  TH1* histo_high = (TH1*) fhHigh.GetObject();
  return histo_high;
}

void RooStats::HistFactory::HistoFactor::writeToFile( const std::string& FileName,
						      const std::string& DirName ) {

  // This saves the histograms to a file and
  // changes the name of the local file and histograms

  TH1* histLow = GetHistoLow();
  if( histLow==NULL ) {
    std::cout << "Error: Cannot write " << GetName()
	      << " to file: " << FileName
	      << " HistoLow is NULL"
	      << std::endl;
    throw hf_exc();
  }
  histLow->Write();
  fInputFileLow = FileName;
  fHistoPathLow = DirName;
  fHistoNameLow = histLow->GetName();

  TH1* histHigh = GetHistoHigh();
  if( histHigh==NULL ) {
    std::cout << "Error: Cannot write " << GetName()
	      << " to file: " << FileName
	      << " HistoHigh is NULL"
	      << std::endl;
    throw hf_exc();
  }
  histHigh->Write();
  fInputFileHigh = FileName;
  fHistoPathHigh = DirName;
  fHistoNameHigh = histHigh->GetName();

  return;

}

void RooStats::HistFactory::HistoFactor::PrintXML( std::ostream& xml ) {
  xml << "      <HistoFactor Name=\"" << GetName() << "\" "

      << " InputFileLow=\""  << GetInputFileLow()  << "\" "
      << " HistoNameLow=\""  << GetHistoNameLow()  << "\" "
      << " HistoPathLow=\""  << GetHistoPathLow()  << "\" "

      << " InputFileHigh=\""  << GetInputFileHigh()  << "\" "
      << " HistoNameHigh=\""  << GetHistoNameHigh()  << "\" "
      << " HistoPathHigh=\""  << GetHistoPathHigh()  << "\" "
      << "  /> " << std::endl;
}

// Shape Factor
RooStats::HistFactory::ShapeFactor::ShapeFactor() : fConstant(false),
						    fHasInitialShape(false),
						    fhInitialShape(NULL) {;}

void RooStats::HistFactory::ShapeFactor::Print( std::ostream& stream ) {

  stream << "\t \t Name: " << fName << std::endl;

  if( fHistoName != "" ) {
    stream << "\t \t "
	   << " Shape Hist Name: " << fHistoName
	   << " Shape Hist Path Name: " << fHistoPath
	   << " Shape Hist FileName: " << fInputFile
	   << std::endl;
  }

  if( fConstant ) { stream << "\t \t ( Constant ): " << std::endl; }

}

void RooStats::HistFactory::ShapeFactor::writeToFile( const std::string& FileName,
						      const std::string& DirName ) {

  if( HasInitialShape() ) {
    TH1* histInitialShape = GetInitialShape();
    if( histInitialShape==NULL ) {
      std::cout << "Error: Cannot write " << GetName()
		<< " to file: " << FileName
		<< " InitialShape is NULL"
		<< std::endl;
      throw hf_exc();
    }
    histInitialShape->Write();
    fInputFile = FileName;
    fHistoPath = DirName;
    fHistoName = histInitialShape->GetName();
  }

  return;

}

void RooStats::HistFactory::ShapeFactor::PrintXML( std::ostream& xml ) {
  xml << "      <ShapeFactor Name=\"" << GetName() << "\" ";
  if( fHasInitialShape ) {
    xml << " InputFile=\""  << GetInputFile()  << "\" "
	<< " HistoName=\""  << GetHistoName()  << "\" "
	<< " HistoPath=\""  << GetHistoPath()  << "\" ";
  }
  xml << "  /> " << std::endl;
}

// Stat Error Config
void RooStats::HistFactory::StatErrorConfig::Print( std::ostream& stream ) {
  stream << "\t \t RelErrorThreshold: " << fRelErrorThreshold
	 << "\t ConstraintType: " << Constraint::Name( fConstraintType )
	 << std::endl;
}

void RooStats::HistFactory::StatErrorConfig::PrintXML( std::ostream& xml ) {
  xml << "    <StatErrorConfig RelErrorThreshold=\"" << GetRelErrorThreshold()
      << "\" "
      << "ConstraintType=\"" << Constraint::Name( GetConstraintType() )
      << "\" "
      << "/> " << std::endl << std::endl;

}

// Stat Error
TH1* RooStats::HistFactory::StatError::GetErrorHist() {
  return (TH1*) fhError.GetObject();
}

void RooStats::HistFactory::StatError::Print( std::ostream& stream ) {
  stream << "\t \t Activate: " << fActivate
	 << "\t InputFile: " << fInputFile
	 << "\t HistoName: " << fHistoName
	 << "\t histoPath: " << fHistoPath
	 << std::endl;
}

void RooStats::HistFactory::StatError::PrintXML( std::ostream& xml ) {

  if( GetActivate() ) {
    xml << "      <StatError Activate=\""
	<< (GetActivate() ? std::string("True") : std::string("False"))
	<< "\" "
	<< " InputFile=\"" << GetInputFile() << "\" "
	<< " HistoName=\"" << GetHistoName() << "\" "
	<< " HistoPath=\"" << GetHistoPath() << "\" "
	<< " /> " << std::endl;
  }

}

void RooStats::HistFactory::StatError::writeToFile( const std::string& OutputFileName,
						    const std::string& DirName ) {

  if( fUseHisto ) {

    std::string statErrorHistName = "statisticalErrors";

    TH1* hStatError = GetErrorHist();
    if( hStatError == NULL ) {
      std::cout << "Error: Stat Error error hist is NULL" << std::endl;
      throw hf_exc();
    }
    hStatError->Write(statErrorHistName.c_str());

    fInputFile = OutputFileName;
    fHistoName = statErrorHistName;
    fHistoPath = DirName;

  }

  return;

}
<|endoftext|>


<commit_before>#include "Filter.h"

using namespace std;

Filter::Filter(float length = 0.65) {
	// Saiten-Koeffizienten
	this->l = length;
	this->Ts = 60.97;
	this->rho = 1140;
	this->A = 0.5188e-6;
	this->E = 5.4e9;
	this->I = 0.171e-12;
	this->d1 = 8e-5;
	this->d3 = -1.4e-5;

	// Abtastpunkt
	this->xa = 0.1;

	// Abtastrate und Samplelänge
	this->T = 44100;
	this->seconds = 10;
	this->samples = seconds*T;
	this->filters = 30;

	// Blockverarbeitungs-Länge
	this->blocksize = 100;

	// Ausgangssignal
	// y = zeros(1,samples);

	std::cout << "Hello World!";
}

void Filter::createPoles() {
	vector<float> sigmas(this->filters);
	vector<float> omegas(this->filters);
}
<commit_msg>Sigmas und Omegas mit 1 füllen<commit_after>#include "Filter.h"

using namespace std;

Filter::Filter(float length = 0.65) {
	// Saiten-Koeffizienten
	this->l = length;
	this->Ts = 60.97;
	this->rho = 1140;
	this->A = 0.5188e-6;
	this->E = 5.4e9;
	this->I = 0.171e-12;
	this->d1 = 8e-5;
	this->d3 = -1.4e-5;

	// Abtastpunkt
	this->xa = 0.1;

	// Abtastrate und Samplelänge
	this->T = 44100;
	this->seconds = 10;
	this->samples = seconds*T;
	this->filters = 30;

	// Blockverarbeitungs-Länge
	this->blocksize = 100;

	// Ausgangssignal
	// y = zeros(1,samples);

	this->createPoles();

	std::cout << "Hello World!";
}

void Filter::createPoles() {
	int i;
	vector<float> sigmas(this->filters);
	vector<float> omegas(this->filters);

	for(i = 0; i < this->filters; i++) {
		sigmas.push_back(1);
		omegas.push_back(2);
	}
}
<|endoftext|>


<commit_before>#include <catch.hpp>
#include <rapidcheck-catch.h>

#include "rapidcheck/gen/Transform.h"
#include "rapidcheck/gen/Create.h"

#include "util/GenUtils.h"
#include "util/Predictable.h"
#include "util/Generators.h"
#include "util/ShrinkableUtils.h"

using namespace rc;
using namespace rc::test;

TEST_CASE("gen::map") {
  prop("maps the shrinkable returned by the generator",
       [](const Shrinkable<int> &shrinkable) {
         const auto mapper = [](int x) { return x * x; };
         const auto mapped =
             gen::map(Gen<int>(fn::constant(shrinkable)), mapper)(Random(), 0);
         RC_ASSERT(shrinkable::map(shrinkable, mapper) == mapped);
       });

  prop("forwards the parameter to the generator",
       [](const GenParams &params) {
         const auto gen = gen::map(genPassedParams(),
                                   [](GenParams &&x) { return std::move(x); });
         RC_ASSERT(gen(params.random, params.size).value() == params);
       });

  SECTION("works with non-copyable types") {
    const auto value =
        gen::map(gen::arbitrary<NonCopyable>(),
                 [](NonCopyable &&nc) { return std::move(nc); })(Random(), 0)
            .value();
    REQUIRE(isArbitraryPredictable(value));
  }

  prop("uses gen::arbitrary if no generator is specified",
       [](const GenParams &params) {
         const auto value = gen::map<Predictable>([](Predictable &&x) {
           return std::move(x);
         })(params.random, params.size)
                                .value();
         RC_ASSERT(isArbitraryPredictable(value));
       });

  prop(
      "finds minimum where string represtation of unsigned integer must be"
      " longer than some value",
      [](const Random &random) {
        const auto gen =
            gen::map(gen::arbitrary<unsigned int>(),
                     [](unsigned int x) { return std::to_string(x); });
        const auto n = *gen::inRange(2, 7);
        std::string expected(n, '0');
        expected[0] = '1';
        const auto result =
            searchGen(random,
                      kNominalSize,
                      gen,
                      [=](const std::string &x) { return x.size() >= n; });
        RC_ASSERT(result == expected);
      });
}

TEST_CASE("gen::mapcat") {
  // It would be nice and all to test the monad laws here but since `Gen` is
  // only morally a monad because of random splitting, it's simpler this way
  prop("mapcats the returned shrinkables",
       [](Shrinkable<int> a, Shrinkable<int> b) {
         const auto expected = shrinkable::mapcat(
             a,
             [=](int x) {
               return shrinkable::map(
                   b, [=](int y) { return std::make_pair(x, y); });
             });
         const auto gen = gen::mapcat<int>(
             fn::constant(a),
             [=](int x) -> Gen<std::pair<int, int>> {
               return fn::constant(shrinkable::map(
                   b, [=](int y) { return std::make_pair(x, y); }));
             });
         const auto actual = gen(Random(), 0);

         RC_ASSERT(actual == expected);
       });

  prop("passes correct size",
       [](const GenParams &params) {
         const auto gen = gen::mapcat(
             genSize(),
             [](int x) {
               return gen::map(genSize(),
                               [=](int y) { return std::make_pair(x, y); });
             });

         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value == std::make_pair(params.size, params.size));
       });

  prop("passes unique randoms",
       [](const GenParams &params) {
         const auto gen = gen::mapcat(
             genRandom(),
             [](const Random &x) {
               return gen::map(
                   genRandom(),
                   [=](Random &&y) { return std::make_pair(x, std::move(y)); });
             });

         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value.first != value.second);
         RC_ASSERT(value.first != params.random);
         RC_ASSERT(value.second != params.random);
       });

  SECTION("works with non-copyable types") {
    const auto gen = gen::mapcat(gen::arbitrary<NonCopyable>(),
                                 [](NonCopyable &&x) {
                                   RC_ASSERT(isArbitraryPredictable(x));
                                   return gen::arbitrary<NonCopyable>();
                                 });
    const auto value = gen(Random(), 0).value();
    RC_ASSERT(isArbitraryPredictable(value));
  }
}

TEST_CASE("gen::join") {
  prop("gen::join(gen::map(s, f)) == gen::mapcat(s, f)",
       [](Shrinkable<int> a, Shrinkable<int> b) {
         const auto f = [=](int x) -> Gen<std::pair<int, int>> {
           return fn::constant(
               shrinkable::map(b, [=](int y) { return std::make_pair(x, y); }));
         };
         const auto expected =
             gen::mapcat(Gen<int>(fn::constant(a)), f)(Random(), 0);
         const auto actual =
             gen::join(gen::map(Gen<int>(fn::constant(a)), f))(Random(), 0);

         RC_ASSERT(actual == expected);
       });

  prop("passes correct size",
       [](const GenParams &params) {
         const auto gen = gen::join(gen::map(
             genSize(),
             [=](int x) {
               return gen::map(genSize(),
                               [=](int y) { return std::make_pair(x, y); });
             }));

         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value == std::make_pair(params.size, params.size));
       });

  prop("passes unique random generators",
       [](const GenParams &params) {
         const auto gen =
             gen::join(gen::map(genRandom(),
                                [=](const Random &x) {
                                  return gen::map(genRandom(),
                                                  [=](const Random &y) {
                                                    return std::make_pair(x, y);
                                                  });
                                }));

         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value.first != value.second);
         RC_ASSERT(value.first != params.random);
         RC_ASSERT(value.second != params.random);
       });

  SECTION("works with non-copyable types") {
    const auto gen = gen::join(gen::map(gen::arbitrary<NonCopyable>(),
                                        [](const NonCopyable &x) {
                                          RC_ASSERT(isArbitraryPredictable(x));
                                          return gen::arbitrary<NonCopyable>();
                                        }));

    const auto value = gen(Random(), 0).value();
    RC_ASSERT(isArbitraryPredictable(value));
  }
}

TEST_CASE("gen::cast") {
  prop("casting to a larger type and then back yields original",
       [](const Shrinkable<uint8_t> &shrinkable) {
         const Gen<uint8_t> gen(fn::constant(shrinkable));
         const auto cast = gen::cast<uint8_t>(gen::cast<int>(gen));
         RC_ASSERT(cast(Random(), 0) == shrinkable);
       });
}

TEST_CASE("gen::suchThat") {
  prop("generated value always matches predicate",
       [](const GenParams &params) {
         const auto gen = gen::suchThat(gen::arbitrary<int>(),
                                        [](int x) { return (x % 2) == 0; });
         const auto shrinkable = gen(params.random, params.size);
         onAnyPath(
             shrinkable,
             [](const Shrinkable<int> &value, const Shrinkable<int> &shrink) {
               RC_ASSERT((value.value() % 2) == 0);
             });
       });

  prop(
      "if predicate returns true for every value, returned shrinkable is"
      " unchanged",
      [](const GenParams &params, const Shrinkable<int> &shrinkable) {
        const Gen<int> underlying(fn::constant(shrinkable));
        const auto gen = gen::suchThat(underlying, fn::constant(true));
        RC_ASSERT(underlying(params.random, params.size) ==
                  gen(params.random, params.size));
      });

  prop("throws GenerationFailure if value cannot be generated",
       [](const GenParams &params) {
         const auto gen = gen::suchThat(gen::just<int>(0), fn::constant(false));
         const auto shrinkable = gen(params.random, params.size);
         try {
           shrinkable.value();
         } catch (const GenerationFailure &e) {
           RC_SUCCEED("Threw GenerationFailure");
         }
         RC_FAIL("Didn't throw GenerationFailure");
       });

  prop("passes the passed size to the underlying generator on the first try",
       [] {
         const auto size = *gen::inRange<int>(0, 2000);
         const auto gen = gen::suchThat(genPassedParams(), fn::constant(true));
         const auto params = gen(Random(), size).value();
         RC_ASSERT(params.size == size);
       });

  prop("uses gen::arbitrary if no generator is specified",
       [](const GenParams &params) {
         const auto value = gen::suchThat<Predictable>(fn::constant(true))(
                                params.random, params.size)
                                .value();
         RC_ASSERT(isArbitraryPredictable(value));
       });

  SECTION("works with non-copyable types") {
    const auto value = gen::suchThat(gen::arbitrary<NonCopyable>(),
                                     fn::constant(true))(Random(), 0)
                           .value();
    REQUIRE(isArbitraryPredictable(value));
  }
}

TEST_CASE("gen::resize") {
  prop("always uses the specified size",
       [](const GenParams &params) {
         const auto size = *gen::inRange<int>(0, 2000);
         const auto gen = gen::resize(size, genPassedParams());
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value.size == size);
       });

  prop("passes through random generator unchanged",
       [](const GenParams &params) {
         const auto gen = gen::resize(0, genPassedParams());
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value.random == params.random);
       });
}

TEST_CASE("gen::scale") {
  prop("scales the size by the specified factor",
       [](const GenParams &params) {
         const auto gen = gen::scale(2.0, genPassedParams());
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value.size == params.size * 2);
       });

  prop("passes through random generator unchanged",
       [](const GenParams &params) {
         const auto gen = gen::scale(2.0, genPassedParams());
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value.random == params.random);
       });
}

TEST_CASE("gen::noShrink") {
  prop("returned shrinkable has expected value",
       [](const GenParams &params, int x) {
         const auto gen = gen::noShrink(gen::just(x));
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value == x);
       });

  prop("returned shrinkable has no shrinks",
       [](const GenParams &params) {
         const auto gen = gen::noShrink(gen::arbitrary<int>());
         const auto shrinkable = gen(params.random, params.size);
         RC_ASSERT(!shrinkable.shrinks().next());
       });

  prop("passes generation params unchanged",
       [](const GenParams &params) {
         const auto gen = gen::noShrink(genPassedParams());
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value == params);
       });
}

TEST_CASE("gen::withSize") {
  prop("passes the current size to the callable",
       [](const GenParams &params) {
         const auto gen =
             gen::withSize([](int size) { return gen::just(size); });
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value == params.size);
       });

  prop("generates what the returned generator generates",
       [](const GenParams &params, int x) {
         const auto gen = gen::withSize([=](int size) { return gen::just(x); });
         const auto shrinkable = gen(params.random, params.size);
         RC_ASSERT(shrinkable == shrinkable::just(x));
       });

  prop("passes generation params unchanged",
       [](const GenParams &params) {
         const auto gen =
             gen::withSize([](int size) { return genPassedParams(); });
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value == params);
       });
}
<commit_msg>Change wording in gen::mapcat property<commit_after>#include <catch.hpp>
#include <rapidcheck-catch.h>

#include "rapidcheck/gen/Transform.h"
#include "rapidcheck/gen/Create.h"

#include "util/GenUtils.h"
#include "util/Predictable.h"
#include "util/Generators.h"
#include "util/ShrinkableUtils.h"

using namespace rc;
using namespace rc::test;

TEST_CASE("gen::map") {
  prop("maps the shrinkable returned by the generator",
       [](const Shrinkable<int> &shrinkable) {
         const auto mapper = [](int x) { return x * x; };
         const auto mapped =
             gen::map(Gen<int>(fn::constant(shrinkable)), mapper)(Random(), 0);
         RC_ASSERT(shrinkable::map(shrinkable, mapper) == mapped);
       });

  prop("forwards the parameter to the generator",
       [](const GenParams &params) {
         const auto gen = gen::map(genPassedParams(),
                                   [](GenParams &&x) { return std::move(x); });
         RC_ASSERT(gen(params.random, params.size).value() == params);
       });

  SECTION("works with non-copyable types") {
    const auto value =
        gen::map(gen::arbitrary<NonCopyable>(),
                 [](NonCopyable &&nc) { return std::move(nc); })(Random(), 0)
            .value();
    REQUIRE(isArbitraryPredictable(value));
  }

  prop("uses gen::arbitrary if no generator is specified",
       [](const GenParams &params) {
         const auto value = gen::map<Predictable>([](Predictable &&x) {
           return std::move(x);
         })(params.random, params.size)
                                .value();
         RC_ASSERT(isArbitraryPredictable(value));
       });

  prop(
      "finds minimum where string represtation of unsigned integer must be"
      " longer than some value",
      [](const Random &random) {
        const auto gen =
            gen::map(gen::arbitrary<unsigned int>(),
                     [](unsigned int x) { return std::to_string(x); });
        const auto n = *gen::inRange(2, 7);
        std::string expected(n, '0');
        expected[0] = '1';
        const auto result =
            searchGen(random,
                      kNominalSize,
                      gen,
                      [=](const std::string &x) { return x.size() >= n; });
        RC_ASSERT(result == expected);
      });
}

TEST_CASE("gen::mapcat") {
  // It would be nice and all to test the monad laws here but since `Gen` is
  // only morally a monad because of random splitting, it's simpler this way
  prop("mapcats the returned shrinkables",
       [](Shrinkable<int> a, Shrinkable<int> b) {
         const auto expected = shrinkable::mapcat(
             a,
             [=](int x) {
               return shrinkable::map(
                   b, [=](int y) { return std::make_pair(x, y); });
             });
         const auto gen = gen::mapcat<int>(
             fn::constant(a),
             [=](int x) -> Gen<std::pair<int, int>> {
               return fn::constant(shrinkable::map(
                   b, [=](int y) { return std::make_pair(x, y); }));
             });
         const auto actual = gen(Random(), 0);

         RC_ASSERT(actual == expected);
       });

  prop("passes correct size",
       [](const GenParams &params) {
         const auto gen = gen::mapcat(
             genSize(),
             [](int x) {
               return gen::map(genSize(),
                               [=](int y) { return std::make_pair(x, y); });
             });

         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value == std::make_pair(params.size, params.size));
       });

  prop("passes unique random generators",
       [](const GenParams &params) {
         const auto gen = gen::mapcat(
             genRandom(),
             [](const Random &x) {
               return gen::map(
                   genRandom(),
                   [=](Random &&y) { return std::make_pair(x, std::move(y)); });
             });

         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value.first != value.second);
         RC_ASSERT(value.first != params.random);
         RC_ASSERT(value.second != params.random);
       });

  SECTION("works with non-copyable types") {
    const auto gen = gen::mapcat(gen::arbitrary<NonCopyable>(),
                                 [](NonCopyable &&x) {
                                   RC_ASSERT(isArbitraryPredictable(x));
                                   return gen::arbitrary<NonCopyable>();
                                 });
    const auto value = gen(Random(), 0).value();
    RC_ASSERT(isArbitraryPredictable(value));
  }
}

TEST_CASE("gen::join") {
  prop("gen::join(gen::map(s, f)) == gen::mapcat(s, f)",
       [](Shrinkable<int> a, Shrinkable<int> b) {
         const auto f = [=](int x) -> Gen<std::pair<int, int>> {
           return fn::constant(
               shrinkable::map(b, [=](int y) { return std::make_pair(x, y); }));
         };
         const auto expected =
             gen::mapcat(Gen<int>(fn::constant(a)), f)(Random(), 0);
         const auto actual =
             gen::join(gen::map(Gen<int>(fn::constant(a)), f))(Random(), 0);

         RC_ASSERT(actual == expected);
       });

  prop("passes correct size",
       [](const GenParams &params) {
         const auto gen = gen::join(gen::map(
             genSize(),
             [=](int x) {
               return gen::map(genSize(),
                               [=](int y) { return std::make_pair(x, y); });
             }));

         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value == std::make_pair(params.size, params.size));
       });

  prop("passes unique random generators",
       [](const GenParams &params) {
         const auto gen =
             gen::join(gen::map(genRandom(),
                                [=](const Random &x) {
                                  return gen::map(genRandom(),
                                                  [=](const Random &y) {
                                                    return std::make_pair(x, y);
                                                  });
                                }));

         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value.first != value.second);
         RC_ASSERT(value.first != params.random);
         RC_ASSERT(value.second != params.random);
       });

  SECTION("works with non-copyable types") {
    const auto gen = gen::join(gen::map(gen::arbitrary<NonCopyable>(),
                                        [](const NonCopyable &x) {
                                          RC_ASSERT(isArbitraryPredictable(x));
                                          return gen::arbitrary<NonCopyable>();
                                        }));

    const auto value = gen(Random(), 0).value();
    RC_ASSERT(isArbitraryPredictable(value));
  }
}

TEST_CASE("gen::cast") {
  prop("casting to a larger type and then back yields original",
       [](const Shrinkable<uint8_t> &shrinkable) {
         const Gen<uint8_t> gen(fn::constant(shrinkable));
         const auto cast = gen::cast<uint8_t>(gen::cast<int>(gen));
         RC_ASSERT(cast(Random(), 0) == shrinkable);
       });
}

TEST_CASE("gen::suchThat") {
  prop("generated value always matches predicate",
       [](const GenParams &params) {
         const auto gen = gen::suchThat(gen::arbitrary<int>(),
                                        [](int x) { return (x % 2) == 0; });
         const auto shrinkable = gen(params.random, params.size);
         onAnyPath(
             shrinkable,
             [](const Shrinkable<int> &value, const Shrinkable<int> &shrink) {
               RC_ASSERT((value.value() % 2) == 0);
             });
       });

  prop(
      "if predicate returns true for every value, returned shrinkable is"
      " unchanged",
      [](const GenParams &params, const Shrinkable<int> &shrinkable) {
        const Gen<int> underlying(fn::constant(shrinkable));
        const auto gen = gen::suchThat(underlying, fn::constant(true));
        RC_ASSERT(underlying(params.random, params.size) ==
                  gen(params.random, params.size));
      });

  prop("throws GenerationFailure if value cannot be generated",
       [](const GenParams &params) {
         const auto gen = gen::suchThat(gen::just<int>(0), fn::constant(false));
         const auto shrinkable = gen(params.random, params.size);
         try {
           shrinkable.value();
         } catch (const GenerationFailure &e) {
           RC_SUCCEED("Threw GenerationFailure");
         }
         RC_FAIL("Didn't throw GenerationFailure");
       });

  prop("passes the passed size to the underlying generator on the first try",
       [] {
         const auto size = *gen::inRange<int>(0, 2000);
         const auto gen = gen::suchThat(genPassedParams(), fn::constant(true));
         const auto params = gen(Random(), size).value();
         RC_ASSERT(params.size == size);
       });

  prop("uses gen::arbitrary if no generator is specified",
       [](const GenParams &params) {
         const auto value = gen::suchThat<Predictable>(fn::constant(true))(
                                params.random, params.size)
                                .value();
         RC_ASSERT(isArbitraryPredictable(value));
       });

  SECTION("works with non-copyable types") {
    const auto value = gen::suchThat(gen::arbitrary<NonCopyable>(),
                                     fn::constant(true))(Random(), 0)
                           .value();
    REQUIRE(isArbitraryPredictable(value));
  }
}

TEST_CASE("gen::resize") {
  prop("always uses the specified size",
       [](const GenParams &params) {
         const auto size = *gen::inRange<int>(0, 2000);
         const auto gen = gen::resize(size, genPassedParams());
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value.size == size);
       });

  prop("passes through random generator unchanged",
       [](const GenParams &params) {
         const auto gen = gen::resize(0, genPassedParams());
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value.random == params.random);
       });
}

TEST_CASE("gen::scale") {
  prop("scales the size by the specified factor",
       [](const GenParams &params) {
         const auto gen = gen::scale(2.0, genPassedParams());
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value.size == params.size * 2);
       });

  prop("passes through random generator unchanged",
       [](const GenParams &params) {
         const auto gen = gen::scale(2.0, genPassedParams());
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value.random == params.random);
       });
}

TEST_CASE("gen::noShrink") {
  prop("returned shrinkable has expected value",
       [](const GenParams &params, int x) {
         const auto gen = gen::noShrink(gen::just(x));
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value == x);
       });

  prop("returned shrinkable has no shrinks",
       [](const GenParams &params) {
         const auto gen = gen::noShrink(gen::arbitrary<int>());
         const auto shrinkable = gen(params.random, params.size);
         RC_ASSERT(!shrinkable.shrinks().next());
       });

  prop("passes generation params unchanged",
       [](const GenParams &params) {
         const auto gen = gen::noShrink(genPassedParams());
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value == params);
       });
}

TEST_CASE("gen::withSize") {
  prop("passes the current size to the callable",
       [](const GenParams &params) {
         const auto gen =
             gen::withSize([](int size) { return gen::just(size); });
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value == params.size);
       });

  prop("generates what the returned generator generates",
       [](const GenParams &params, int x) {
         const auto gen = gen::withSize([=](int size) { return gen::just(x); });
         const auto shrinkable = gen(params.random, params.size);
         RC_ASSERT(shrinkable == shrinkable::just(x));
       });

  prop("passes generation params unchanged",
       [](const GenParams &params) {
         const auto gen =
             gen::withSize([](int size) { return genPassedParams(); });
         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value == params);
       });
}
<|endoftext|>


<commit_before>#include "SvgCreator.h"
#include "SvgItemInfo.h"
#include "SvgTextInfo.h"
#include "SvgLineInfo.h"
#include "SvgCurveInfo.h"
#include "MapData.h"
#include "FilledPolygonItem.h"
#include "LineItem.h"
#include "PointItem.h"
#include "ItemLook.h"
#include "Point.h"
#include "BezierInfo.h"
#include "TextInfo.h"

#include <sstream>
#include <fstream>

namespace map_server
{
    SvgCreator::~SvgCreator()
    {
        std::multimap<int, SvgInfo *>::iterator it = _infoMap.begin();
        for (; it != _infoMap.end(); ++it) delete (*it).second;
    }

    void SvgCreator::execute(void)
    {
        std::stringstream content;

        content << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl
                << "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"" << _widthInPixels
                << "\" height=\"" << _heightInPixels << "\">" <<std::endl;

        MapData::lock();

        std::multimap<int, SvgInfo *>::iterator it = _infoMap.begin();
        for (; it != _infoMap.end(); ++it)
        {
            SvgItemInfo *svgItemInfo = dynamic_cast<SvgItemInfo *>((*it).second);
            if (svgItemInfo != 0)
            {
                const MapItem *item = svgItemInfo->getItem();
                const ItemLook *look = svgItemInfo->getLook();
                int resolutionIndex = svgItemInfo->getResolutionIndex();

                const FilledPolygonItem *filledPolygonItem = dynamic_cast<const FilledPolygonItem *>(item);
                if (filledPolygonItem != 0)
                {
                    std::vector<SvgCurveInfo *> curveInfoVector;
                    bool lastIn = false;

                    int i, n = filledPolygonItem->getPointVector(resolutionIndex).size();
                    for (i = 0; i < n; ++i)
                    {
                        const Point *point = filledPolygonItem->getPointVector(resolutionIndex)[i];
                        double x = (point->getX() - _xFocus) * _scale + 0.5 * _widthInPixels;
                        double y = (point->getY() - _yFocus) * _scale + 0.5 * _heightInPixels;
                        bool in = (x > -2.0 && x < _widthInPixels + 2.0 && y > -2.0 && y < _heightInPixels + 2.0);

                        if (!lastIn && x < -2.0) x = -2.0;
                        if (!lastIn && x > _widthInPixels + 2.0) x = _widthInPixels + 2.0;
                        if (!lastIn && y < -2.0) y = -2.0;
                        if (!lastIn && y > _heightInPixels + 2.0) y = _heightInPixels + 2.0;

                        if (i == 0)
                        {
                            curveInfoVector.push_back(new SvgCurveInfo(0.0, 0.0, 0.0, 0.0, x, y));
                        }
                        else
                        {
                            double x1 = x, y1 = y, x2 = x, y2 = y;
                            if (in || lastIn)
                            {
                                x1 = (point->getBezierInfo()->getX1() - _xFocus) * _scale + 0.5 * _widthInPixels;
                                y1 = (point->getBezierInfo()->getY1() - _yFocus) * _scale + 0.5 * _heightInPixels;
                                x2 = (point->getBezierInfo()->getX2() - _xFocus) * _scale + 0.5 * _widthInPixels;
                                y2 = (point->getBezierInfo()->getY2() - _yFocus) * _scale + 0.5 * _heightInPixels;
                            }

                            curveInfoVector.push_back(new SvgCurveInfo(x1, y1, x2, y2, x, y));
                        }

                        lastIn = in;
                    }

                    content << "<path style=\"fill:" << look->getHexColor()
                            << ";fill-opacity:" << static_cast<double>(look->getAlpha()) / 255.0
                            << ";stroke:none\" d=\"";

                    for (i = 0; i < n; ++i)
                    {
                        SvgCurveInfo *curveInfo = curveInfoVector[i];

                        if (i == 0)
                        {
                            content << "M " << curveInfo->getX() << "," << curveInfo->getY() << " ";
                        }
                        else
                        {
                            bool ok = true;
                            double x = curveInfo->getX();
                            double y = curveInfo->getY();

                            if (i != n - 1)
                            {
                                SvgCurveInfo *pCurveInfo = curveInfoVector[i - 1];
                                SvgCurveInfo *nCurveInfo = curveInfoVector[i + 1];

                                if ((y < -1.0 || y > _widthInPixels + 1.0) && pCurveInfo->getX() == x && nCurveInfo->getX() == x) ok = false;
                                if ((x < -1.0 || x > _heightInPixels + 1.0) && pCurveInfo->getY() == y && nCurveInfo->getY() == y) ok = false;
                            }

                            if (ok) content << "C " << curveInfo->getX1() << " " << curveInfo->getY1() << ","
                                            << curveInfo->getX2() << " " << curveInfo->getY2() << "," << x << " " << y << " ";
                        }

                        delete curveInfo;
                    }

                    content << "\"></path>" << std::endl;
                }
                else
                {
                    const LineItem *lineItem = dynamic_cast<const LineItem *>(item);
                    if (lineItem != 0)
                    {
                        content << "<path style=\"fill:none;stroke:" << look->getHexColor()
                                << ";stroke-opacity:" << static_cast<double>(look->getAlpha()) / 255.0
                                << ";stroke-width:" << look->getSize() * _scale * _sizeFactor
                                << ";stroke-linecap:round;stroke-linejoin:round\" d=\"";

                        bool lastIn = false;
                        std::stringstream lastMove;
                        int i, n = lineItem->getPointVector(resolutionIndex).size();
                        for (i = 0; i < n; ++i)
                        {
                            const Point *point = lineItem->getPointVector(resolutionIndex)[i];
                            double x = (point->getX() - _xFocus) * _scale + 0.5 * _widthInPixels;
                            double y = (point->getY() - _yFocus) * _scale + 0.5 * _heightInPixels;
                            bool in = (x > -10.0 && x < _widthInPixels + 10.0 && y > -10.0 && y < _heightInPixels + 10.0);

                            if (i == 0 || (!in && !lastIn))
                            {
                                lastMove.str("");
                                lastMove << "M " << x << "," << y << " ";
                            }
                            else
                            {
                                double x1 = (point->getBezierInfo()->getX1() - _xFocus) * _scale + 0.5 * _widthInPixels;
                                double y1 = (point->getBezierInfo()->getY1() - _yFocus) * _scale + 0.5 * _heightInPixels;
                                double x2 = (point->getBezierInfo()->getX2() - _xFocus) * _scale + 0.5 * _widthInPixels;
                                double y2 = (point->getBezierInfo()->getY2() - _yFocus) * _scale + 0.5 * _heightInPixels;
                                content << lastMove.str() << "C " << x1 << " " << y1 << "," << x2 << " " << y2 << "," << x << " " << y << " ";
                                lastMove.str("");
                            }

                            lastIn = in;
                        }

                        content << "\"></path>" << std::endl;
                    }
                    else
                    {
                        const PointItem *pointItem = dynamic_cast<const PointItem *>(item);
                        if (pointItem != 0)
                        {
                            double x = (pointItem->getPoint()->getX() - _xFocus) * _scale + 0.5 * _widthInPixels;
                            double y = (pointItem->getPoint()->getY() - _yFocus) * _scale + 0.5 * _heightInPixels;

                            if (x > -10.0 && x < _widthInPixels + 10.0 && y > -10.0 && y < _heightInPixels + 10.0)
                            {
                                content << "<circle cx=\"" << x << "\" cy=\"" << y << "\" r=\"" << 0.5 * look->getSize() * _scale * _sizeFactor
                                        << "\" stroke=\"black\" stroke-width=\"" << _scale * _sizeFactor
                                        << "\" fill=\"" << look->getHexColor()
                                        << "\" fill-opacity=\"" << static_cast<double>(look->getAlpha()) / 255.0 << "\"></circle>" << std::endl;
                            }
                        }
                    }
                }
            }
            else
            {
                SvgTextInfo *svgTextInfo = dynamic_cast<SvgTextInfo *>((*it).second);
                if (svgTextInfo != 0)
                {
                    int i, n = svgTextInfo->getLineVector().size();
                    for (i = 0; i < n; ++i)
                    {
                        const SvgLineInfo *lineInfo = svgTextInfo->getLineVector()[i];

                        double x = (lineInfo->getX() - _xFocus) * _scale + 0.5 * _widthInPixels;
                        double y = (lineInfo->getY() - _yFocus) * _scale + 0.5 * _heightInPixels;

                        content << "<text x=\"" << x << "\" y=\"" << y << "\" font-size=\"" << svgTextInfo->getTextInfo()->getFontSize()
                                << "\" font-family=\"arial\" fill=\"" << svgTextInfo->getTextInfo()->getHexColor()
                                << "\" fill-opacity=\"" << static_cast<double>(svgTextInfo->getTextInfo()->getAlpha()) / 255.0
                                << "\">" << lineInfo->getText() << "</text>" << std::endl;
                    }
                }
            }
        }

        MapData::unlock();

        content << "</svg>";

        // Todo: Prevent different threads to write simultaneously the same file
		std::string fileName;
		if (_socketId.size() > 2) fileName = "map_" + _socketId.substr(2, _socketId.size() - 2) + ".svg";
		else fileName = "map_" + _socketId + ".svg";

        std::ofstream file(fileName);
        file << content.str();
    }
}
<commit_msg>C++ map server: Bug correction in SVG creator<commit_after>#include "SvgCreator.h"
#include "SvgItemInfo.h"
#include "SvgTextInfo.h"
#include "SvgLineInfo.h"
#include "SvgCurveInfo.h"
#include "MapData.h"
#include "FilledPolygonItem.h"
#include "LineItem.h"
#include "PointItem.h"
#include "ItemLook.h"
#include "Point.h"
#include "BezierInfo.h"
#include "TextInfo.h"

#include <sstream>
#include <fstream>

namespace map_server
{
    SvgCreator::~SvgCreator()
    {
        std::multimap<int, SvgInfo *>::iterator it = _infoMap.begin();
        for (; it != _infoMap.end(); ++it) delete (*it).second;
    }

    void SvgCreator::execute(void)
    {
        std::stringstream content;

        content << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl
                << "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"" << _widthInPixels
                << "\" height=\"" << _heightInPixels << "\">" << std::endl;

        MapData::lock();

        std::multimap<int, SvgInfo *>::iterator it = _infoMap.begin();
        for (; it != _infoMap.end(); ++it)
        {
            SvgItemInfo *svgItemInfo = dynamic_cast<SvgItemInfo *>((*it).second);
            if (svgItemInfo != 0)
            {
                const MapItem *item = svgItemInfo->getItem();
                const ItemLook *look = svgItemInfo->getLook();
                int resolutionIndex = svgItemInfo->getResolutionIndex();

                const FilledPolygonItem *filledPolygonItem = dynamic_cast<const FilledPolygonItem *>(item);
                if (filledPolygonItem != 0)
                {
                    std::vector<SvgCurveInfo *> curveInfoVector;
                    bool lastIn = false;
                    const double d = 2.0;

                    int i, n = filledPolygonItem->getPointVector(resolutionIndex).size();
                    for (i = 0; i < n; ++i)
                    {
                        const Point *point = filledPolygonItem->getPointVector(resolutionIndex)[i];
                        double x = (point->getX() - _xFocus) * _scale + 0.5 * _widthInPixels;
                        double y = (point->getY() - _yFocus) * _scale + 0.5 * _heightInPixels;
                        bool in = (x > -d && x < _widthInPixels + d && y > -d && y < _heightInPixels + d);

                        bool nextIn = false;
                        if (i < n - 1)
                        {
                            const Point *np = filledPolygonItem->getPointVector(resolutionIndex)[i + 1];
                            double nx = (np->getX() - _xFocus) * _scale + 0.5 * _widthInPixels;
                            double ny = (np->getY() - _yFocus) * _scale + 0.5 * _heightInPixels;
                            nextIn = (nx > -d && nx < _widthInPixels + d && ny > -d && ny < _heightInPixels + d);
                        }

                        if (!lastIn && !nextIn && x < -d) x = -d;
                        if (!lastIn && !nextIn && x > _widthInPixels + d) x = _widthInPixels + d;
                        if (!lastIn && !nextIn && y < -d) y = -d;
                        if (!lastIn && !nextIn && y > _heightInPixels + d) y = _heightInPixels + d;

                        if (i == 0)
                        {
                            curveInfoVector.push_back(new SvgCurveInfo(0.0, 0.0, 0.0, 0.0, x, y));
                        }
                        else
                        {
                            double x1 = x, y1 = y, x2 = x, y2 = y;
                            if (in || lastIn)
                            {
                                x1 = (point->getBezierInfo()->getX1() - _xFocus) * _scale + 0.5 * _widthInPixels;
                                y1 = (point->getBezierInfo()->getY1() - _yFocus) * _scale + 0.5 * _heightInPixels;
                                x2 = (point->getBezierInfo()->getX2() - _xFocus) * _scale + 0.5 * _widthInPixels;
                                y2 = (point->getBezierInfo()->getY2() - _yFocus) * _scale + 0.5 * _heightInPixels;
                            }

                            curveInfoVector.push_back(new SvgCurveInfo(x1, y1, x2, y2, x, y));
                        }

                        lastIn = in;
                    }

                    content << "<path style=\"fill:" << look->getHexColor()
                            << ";fill-opacity:" << static_cast<double>(look->getAlpha()) / 255.0
                            << ";fill-rule:evenodd;stroke:none\" d=\"";

                    for (i = 0; i < n; ++i)
                    {
                        SvgCurveInfo *curveInfo = curveInfoVector[i];

                        if (i == 0)
                        {
                            content << "M " << curveInfo->getX() << "," << curveInfo->getY() << " ";
                        }
                        else
                        {
                            bool ok = true;
                            double x = curveInfo->getX();
                            double y = curveInfo->getY();

                            if (i != n - 1)
                            {
                                SvgCurveInfo *pCurveInfo = curveInfoVector[i - 1];
                                SvgCurveInfo *nCurveInfo = curveInfoVector[i + 1];

                                if ((y < -(d - 1.0) || y > _widthInPixels + (d - 1.0)) && pCurveInfo->getX() == x && nCurveInfo->getX() == x) ok = false;
                                if ((x < -(d - 1.0) || x > _heightInPixels + (d - 1.0)) && pCurveInfo->getY() == y && nCurveInfo->getY() == y) ok = false;
                            }

                            if (ok) content << "C " << curveInfo->getX1() << " " << curveInfo->getY1() << ","
                                            << curveInfo->getX2() << " " << curveInfo->getY2() << "," << x << " " << y << " ";
                        }

                        delete curveInfo;
                    }

                    content << "\"></path>" << std::endl;
                }
                else
                {
                    const LineItem *lineItem = dynamic_cast<const LineItem *>(item);
                    if (lineItem != 0)
                    {
                        content << "<path style=\"fill:none;stroke:" << look->getHexColor()
                                << ";stroke-opacity:" << static_cast<double>(look->getAlpha()) / 255.0
                                << ";stroke-width:" << look->getSize() * _scale * _sizeFactor
                                << ";stroke-linecap:round;stroke-linejoin:round\" d=\"";

                        bool lastIn = false;
                        std::stringstream lastMove;
                        int i, n = lineItem->getPointVector(resolutionIndex).size();
                        for (i = 0; i < n; ++i)
                        {
                            const Point *point = lineItem->getPointVector(resolutionIndex)[i];
                            double x = (point->getX() - _xFocus) * _scale + 0.5 * _widthInPixels;
                            double y = (point->getY() - _yFocus) * _scale + 0.5 * _heightInPixels;
                            bool in = (x > -10.0 && x < _widthInPixels + 10.0 && y > -10.0 && y < _heightInPixels + 10.0);

                            if (i == 0 || (!in && !lastIn))
                            {
                                lastMove.str("");
                                lastMove << "M " << x << "," << y << " ";
                            }
                            else
                            {
                                double x1 = (point->getBezierInfo()->getX1() - _xFocus) * _scale + 0.5 * _widthInPixels;
                                double y1 = (point->getBezierInfo()->getY1() - _yFocus) * _scale + 0.5 * _heightInPixels;
                                double x2 = (point->getBezierInfo()->getX2() - _xFocus) * _scale + 0.5 * _widthInPixels;
                                double y2 = (point->getBezierInfo()->getY2() - _yFocus) * _scale + 0.5 * _heightInPixels;
                                content << lastMove.str() << "C " << x1 << " " << y1 << "," << x2 << " " << y2 << "," << x << " " << y << " ";
                                lastMove.str("");
                            }

                            lastIn = in;
                        }

                        content << "\"></path>" << std::endl;
                    }
                    else
                    {
                        const PointItem *pointItem = dynamic_cast<const PointItem *>(item);
                        if (pointItem != 0)
                        {
                            double x = (pointItem->getPoint()->getX() - _xFocus) * _scale + 0.5 * _widthInPixels;
                            double y = (pointItem->getPoint()->getY() - _yFocus) * _scale + 0.5 * _heightInPixels;

                            if (x > -10.0 && x < _widthInPixels + 10.0 && y > -10.0 && y < _heightInPixels + 10.0)
                            {
                                content << "<circle cx=\"" << x << "\" cy=\"" << y << "\" r=\"" << 0.5 * look->getSize() * _scale * _sizeFactor
                                        << "\" stroke=\"black\" stroke-width=\"" << _scale * _sizeFactor
                                        << "\" fill=\"" << look->getHexColor()
                                        << "\" fill-opacity=\"" << static_cast<double>(look->getAlpha()) / 255.0 << "\"></circle>" << std::endl;
                            }
                        }
                    }
                }
            }
            else
            {
                SvgTextInfo *svgTextInfo = dynamic_cast<SvgTextInfo *>((*it).second);
                if (svgTextInfo != 0)
                {
                    int i, n = svgTextInfo->getLineVector().size();
                    for (i = 0; i < n; ++i)
                    {
                        const SvgLineInfo *lineInfo = svgTextInfo->getLineVector()[i];

                        double x = (lineInfo->getX() - _xFocus) * _scale + 0.5 * _widthInPixels;
                        double y = (lineInfo->getY() - _yFocus) * _scale + 0.5 * _heightInPixels;

                        content << "<text x=\"" << x << "\" y=\"" << y << "\" font-size=\"" << svgTextInfo->getTextInfo()->getFontSize()
                                << "\" font-family=\"arial\" fill=\"" << svgTextInfo->getTextInfo()->getHexColor()
                                << "\" fill-opacity=\"" << static_cast<double>(svgTextInfo->getTextInfo()->getAlpha()) / 255.0
                                << "\">" << lineInfo->getText() << "</text>" << std::endl;
                    }
                }
            }
        }

        MapData::unlock();

        content << "<rect x=\"0.5\" y=\"0.5\" width=\"" << _widthInPixels - 1.0 << "\" height=\"" << _heightInPixels - 1.0
                << "\" style=\"fill:none;stroke-width:1;stroke:black\"/>" << std::endl << "</svg>";

        // Todo: Prevent different threads to write simultaneously the same file
		std::string fileName;
		if (_socketId.size() > 2) fileName = "map_" + _socketId.substr(2, _socketId.size() - 2) + ".svg";
		else fileName = "map_" + _socketId + ".svg";

        std::ofstream file(fileName);
        file << content.str();
    }
}
<|endoftext|>