<commit_before>//
// Copyright (c) 2008-2014 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include "Precompiled.h"
#include "Context.h"
#include "Sprite2D.h"
#include "StaticSprite2D.h"
#include "Texture2D.h"

#include "DebugNew.h"

namespace Urho3D
{

extern const char* URHO2D_CATEGORY;

StaticSprite2D::StaticSprite2D(Context* context) :
    Drawable2D(context),
    flipX_(false),
    flipY_(false),
    color_(Color::WHITE)
{
    vertices_.Reserve(6);
}

StaticSprite2D::~StaticSprite2D()
{
}

void StaticSprite2D::RegisterObject(Context* context)
{
    context->RegisterFactory<StaticSprite2D>(URHO2D_CATEGORY);
    ACCESSOR_ATTRIBUTE(StaticSprite2D, VAR_BOOL, "Flip X", GetFlipX, SetFlipX, bool, false, AM_DEFAULT);
    ACCESSOR_ATTRIBUTE(StaticSprite2D, VAR_BOOL, "Flip Y", GetFlipY, SetFlipY, bool, false, AM_DEFAULT);
    REF_ACCESSOR_ATTRIBUTE(StaticSprite2D, VAR_COLOR, "Color", GetColor, SetColor, Color, Color::WHITE, AM_DEFAULT);
    COPY_BASE_ATTRIBUTES(StaticSprite2D, Drawable2D);
}

void StaticSprite2D::SetFlip(bool flipX, bool flipY)
{
    if (flipX_ == flipX && flipY_ == flipY)
        return;

    flipX_ = flipX;
    flipY_ = flipY;
    // Assume flipping does not invalidate bounding rectangle
    verticesDirty_ = true;
    geometryDirty_ = true;
    MarkNetworkUpdate();
}

void StaticSprite2D::SetFlipX(bool flipX)
{
    SetFlip(flipX, flipY_);
}

void StaticSprite2D::SetFlipY(bool flipY)
{
    SetFlip(flipX_, flipY);
}

void StaticSprite2D::SetColor(const Color& color)
{
    if (color == color_)
        return;

    color_ = color;
    verticesDirty_ = true;
    geometryDirty_ = true;
    MarkNetworkUpdate();
}

void StaticSprite2D::UpdateVertices()
{
    if (!verticesDirty_)
        return;

    vertices_.Clear();

    if (!sprite_)
        return;

    Texture2D* texture = sprite_->GetTexture();
    if (!texture)
        return;

    const IntRect& rectangle_ = sprite_->GetRectangle();
    if (rectangle_.Width() == 0 || rectangle_.Height() == 0)
        return;

    /*
    V1 --------V2
    |         / |
    |       /   |
    |     /     |
    |   /       |
    | /         |
    V0 --------V3
    */
    Vertex2D vertex0;
    Vertex2D vertex1;
    Vertex2D vertex2;
    Vertex2D vertex3;

    float unitsPerPixel = 1.0f / pixelsPerUnit_;
    float width = (float)rectangle_.Width() * unitsPerPixel;
    float height = (float)rectangle_.Height() * unitsPerPixel;

    const Vector2& hotSpot = sprite_->GetHotSpot();
    float hotSpotX = flipX_ ? (1.0f - hotSpot.x_) : hotSpot.x_;
    float hotSpotY = flipY_ ? (1.0f - hotSpot.y_) : hotSpot.y_;

    float leftX = -width * hotSpotX;
    float rightX = width * (1.0f - hotSpotX);
    float bottomY = -height * hotSpotY;
    float topY = height * (1.0f - hotSpotY);
    vertex0.position_ = Vector3(leftX, bottomY, zValue_);
    vertex1.position_ = Vector3(leftX, topY, zValue_);
    vertex2.position_ = Vector3(rightX, topY, zValue_);
    vertex3.position_ = Vector3(rightX, bottomY, zValue_);

    float invTexW = 1.0f / (float)texture->GetWidth();
    float invTexH = 1.0f / (float)texture->GetHeight();

    float leftU = rectangle_.left_ * invTexW;
    float rightU = rectangle_.right_ * invTexW;
    float topV = rectangle_.top_ * invTexH;
    float bottomV = rectangle_.bottom_ * invTexH;
    vertex0.uv_ = Vector2(leftU, bottomV);
    vertex1.uv_ = Vector2(leftU, topV);
    vertex2.uv_ = Vector2(rightU, topV);
    vertex3.uv_ = Vector2(rightU, bottomV);

    if (flipX_)
    {
        Swap(vertex0.uv_.x_, vertex3.uv_.x_);
        Swap(vertex1.uv_.x_, vertex2.uv_.x_);
    }

    if (flipY_)
    {
        Swap(vertex0.uv_.y_, vertex1.uv_.y_);
        Swap(vertex2.uv_.y_, vertex3.uv_.y_);
    }

    vertex0.color_ = vertex1.color_ = vertex2.color_  = vertex3.color_ = color_.ToUInt();

    vertices_.Push(vertex0);
    vertices_.Push(vertex1);
    vertices_.Push(vertex2);
    vertices_.Push(vertex3);

    geometryDirty_ = true;
    verticesDirty_ = false;
}

}
<commit_msg>Minor change for comment.<commit_after>//
// Copyright (c) 2008-2014 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#include "Precompiled.h"
#include "Context.h"
#include "Sprite2D.h"
#include "StaticSprite2D.h"
#include "Texture2D.h"

#include "DebugNew.h"

namespace Urho3D
{

extern const char* URHO2D_CATEGORY;

StaticSprite2D::StaticSprite2D(Context* context) :
    Drawable2D(context),
    flipX_(false),
    flipY_(false),
    color_(Color::WHITE)
{
    vertices_.Reserve(6);
}

StaticSprite2D::~StaticSprite2D()
{
}

void StaticSprite2D::RegisterObject(Context* context)
{
    context->RegisterFactory<StaticSprite2D>(URHO2D_CATEGORY);
    ACCESSOR_ATTRIBUTE(StaticSprite2D, VAR_BOOL, "Flip X", GetFlipX, SetFlipX, bool, false, AM_DEFAULT);
    ACCESSOR_ATTRIBUTE(StaticSprite2D, VAR_BOOL, "Flip Y", GetFlipY, SetFlipY, bool, false, AM_DEFAULT);
    REF_ACCESSOR_ATTRIBUTE(StaticSprite2D, VAR_COLOR, "Color", GetColor, SetColor, Color, Color::WHITE, AM_DEFAULT);
    COPY_BASE_ATTRIBUTES(StaticSprite2D, Drawable2D);
}

void StaticSprite2D::SetFlip(bool flipX, bool flipY)
{
    if (flipX_ == flipX && flipY_ == flipY)
        return;

    flipX_ = flipX;
    flipY_ = flipY;
    // Assume flipping does not invalidate bounding rectangle
    verticesDirty_ = true;
    geometryDirty_ = true;
    MarkNetworkUpdate();
}

void StaticSprite2D::SetFlipX(bool flipX)
{
    SetFlip(flipX, flipY_);
}

void StaticSprite2D::SetFlipY(bool flipY)
{
    SetFlip(flipX_, flipY);
}

void StaticSprite2D::SetColor(const Color& color)
{
    if (color == color_)
        return;

    color_ = color;
    verticesDirty_ = true;
    geometryDirty_ = true;
    MarkNetworkUpdate();
}

void StaticSprite2D::UpdateVertices()
{
    if (!verticesDirty_)
        return;

    vertices_.Clear();

    if (!sprite_)
        return;

    Texture2D* texture = sprite_->GetTexture();
    if (!texture)
        return;

    const IntRect& rectangle_ = sprite_->GetRectangle();
    if (rectangle_.Width() == 0 || rectangle_.Height() == 0)
        return;

    /*
    V1---------V2
    |         / |
    |       /   |
    |     /     |
    |   /       |
    | /         |
    V0---------V3
    */
    Vertex2D vertex0;
    Vertex2D vertex1;
    Vertex2D vertex2;
    Vertex2D vertex3;

    float unitsPerPixel = 1.0f / pixelsPerUnit_;
    float width = (float)rectangle_.Width() * unitsPerPixel;
    float height = (float)rectangle_.Height() * unitsPerPixel;

    const Vector2& hotSpot = sprite_->GetHotSpot();
    float hotSpotX = flipX_ ? (1.0f - hotSpot.x_) : hotSpot.x_;
    float hotSpotY = flipY_ ? (1.0f - hotSpot.y_) : hotSpot.y_;

    float leftX = -width * hotSpotX;
    float rightX = width * (1.0f - hotSpotX);
    float bottomY = -height * hotSpotY;
    float topY = height * (1.0f - hotSpotY);
    vertex0.position_ = Vector3(leftX, bottomY, zValue_);
    vertex1.position_ = Vector3(leftX, topY, zValue_);
    vertex2.position_ = Vector3(rightX, topY, zValue_);
    vertex3.position_ = Vector3(rightX, bottomY, zValue_);

    float invTexW = 1.0f / (float)texture->GetWidth();
    float invTexH = 1.0f / (float)texture->GetHeight();

    float leftU = rectangle_.left_ * invTexW;
    float rightU = rectangle_.right_ * invTexW;
    float topV = rectangle_.top_ * invTexH;
    float bottomV = rectangle_.bottom_ * invTexH;
    vertex0.uv_ = Vector2(leftU, bottomV);
    vertex1.uv_ = Vector2(leftU, topV);
    vertex2.uv_ = Vector2(rightU, topV);
    vertex3.uv_ = Vector2(rightU, bottomV);

    if (flipX_)
    {
        Swap(vertex0.uv_.x_, vertex3.uv_.x_);
        Swap(vertex1.uv_.x_, vertex2.uv_.x_);
    }

    if (flipY_)
    {
        Swap(vertex0.uv_.y_, vertex1.uv_.y_);
        Swap(vertex2.uv_.y_, vertex3.uv_.y_);
    }

    vertex0.color_ = vertex1.color_ = vertex2.color_  = vertex3.color_ = color_.ToUInt();

    vertices_.Push(vertex0);
    vertices_.Push(vertex1);
    vertices_.Push(vertex2);
    vertices_.Push(vertex3);

    geometryDirty_ = true;
    verticesDirty_ = false;
}

}
<|endoftext|>


<commit_before>/*
    Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>

    This file is part of the KDE project

    This library is free software you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation either
    version 2 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    aint with this library see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "KmlDocumentTagHandler.h"

#include "MarbleDebug.h"

#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataDocument.h"
#include "GeoDataFolder.h"
#include "GeoDataParser.h"

namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER(Document)

GeoNode* KmlDocumentTagHandler::parse(GeoParser& parser) const
{
    Q_ASSERT(parser.isStartElement() && parser.isValidElement(kmlTag_Document));

    GeoStackItem parentItem = parser.parentElement();
    if( !(parentItem.qualifiedName().first.isNull() && parentItem.qualifiedName().second.isNull()) ) {
        // this happens if there is a parent element to the Document tag. We can work around that and simply expect that
        // the new Document tag works like a Folder
        if( parentItem.represents( kmlTag_Folder ) || parentItem.represents( kmlTag_Document ) ) {
            GeoDataDocument *document = new GeoDataDocument;
            KmlObjectTagHandler::parseIdentifiers( parser, document );
            parentItem.nodeAs<GeoDataContainer>()->append( document );

            return document;
        }
        else if ( parentItem.qualifiedName().first == kmlTag_kml)
        {
            GeoDataDocument* doc = geoDataDoc( parser );
            return doc;
        }
    }
    return 0;
}

}
}
<commit_msg>Root document tags can have ids as well<commit_after>/*
    Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>

    This file is part of the KDE project

    This library is free software you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation either
    version 2 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    aint with this library see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "KmlDocumentTagHandler.h"

#include "MarbleDebug.h"

#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataDocument.h"
#include "GeoDataFolder.h"
#include "GeoDataParser.h"

namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER(Document)

GeoNode* KmlDocumentTagHandler::parse(GeoParser& parser) const
{
    Q_ASSERT(parser.isStartElement() && parser.isValidElement(kmlTag_Document));

    GeoStackItem parentItem = parser.parentElement();
    if( !(parentItem.qualifiedName().first.isNull() && parentItem.qualifiedName().second.isNull()) ) {
        // this happens if there is a parent element to the Document tag. We can work around that and simply expect that
        // the new Document tag works like a Folder
        if( parentItem.represents( kmlTag_Folder ) || parentItem.represents( kmlTag_Document ) ) {
            GeoDataDocument *document = new GeoDataDocument;
            KmlObjectTagHandler::parseIdentifiers( parser, document );
            parentItem.nodeAs<GeoDataContainer>()->append( document );

            return document;
        }
        else if ( parentItem.qualifiedName().first == kmlTag_kml)
        {
            GeoDataDocument* doc = geoDataDoc( parser );
            KmlObjectTagHandler::parseIdentifiers( parser, doc );
            return doc;
        }
    }
    return 0;
}

}
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "itkVariableLengthVector.h"
#include "otbChangeLabelImageFilter.h"
#include "otbStandardWriterWatcher.h"
#include "otbStatisticsXMLFileReader.h"
#include "otbShiftScaleVectorImageFilter.h"
#include "otbImageClassificationFilter.h"
#include "otbMultiToMonoChannelExtractROI.h"
#include "otbImageToVectorImageCastFilter.h"
#include "otbMachineLearningModelFactory.h"

namespace otb
{
namespace Wrapper
{

class ImageClassifier : public Application
{
public:
  /** Standard class typedefs. */
  typedef ImageClassifier            Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(ImageClassifier, otb::Application);

  /** Filters typedef */
  typedef itk::VariableLengthVector<FloatVectorImageType::InternalPixelType>            MeasurementType;
  typedef otb::StatisticsXMLFileReader<MeasurementType>                                 StatisticsReader;
  typedef otb::ShiftScaleVectorImageFilter<FloatVectorImageType, FloatVectorImageType>  RescalerType;
  typedef otb::ImageClassificationFilter<FloatVectorImageType, UInt32ImageType>         ClassificationFilterType;
  typedef ClassificationFilterType::Pointer                                             ClassificationFilterPointerType;
  typedef ClassificationFilterType::ModelType                                           ModelType;
  typedef ModelType::Pointer                                                            ModelPointerType;
  typedef ClassificationFilterType::ValueType ValueType;
  typedef ClassificationFilterType::LabelType LabelType;
  typedef otb::MachineLearningModelFactory<ValueType, LabelType> MachineLearningModelFactoryType;

private:
  void DoInit()
  {
    SetName("ImageClassifier");
    SetDescription("Performs a classification of the input image according to a model file.");

    // Documentation
    SetDocName("Image Classification");
    SetDocLongDescription("This application performs an image classification based on a model file (*.txt extension) produced by the TrainImagesClassifier application. Pixels of the output image will contain the class label decided by the classifier. The input pixels can be optionnaly centered and reduced according to the statistics file produced by the ComputeImagesStatistics application. An optional input mask can be provided, in which case only input image pixels whose corresponding mask value is greater than 0 will be classified. The remaining of pixels will be given the label 0 in the output image.");

    SetDocLimitations("The input image must have the same type, order and number of bands than the images used to produce the statistics file and the SVM model file. If a statistics file was used during training by the TrainImagesClassifier, it is mandatory to use the same statistics file for classification. If an input mask is used, its size must match the input image size.");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("TrainImagesClassifier, ValidateImagesClassifier, ComputeImagesStatistics");

    AddDocTag(Tags::Learning);

    AddParameter(ParameterType_InputImage, "in",  "Input Image");
    SetParameterDescription( "in", "The input image to classify.");

    AddParameter(ParameterType_InputImage,  "mask",   "Input Mask");
    SetParameterDescription( "mask", "The mask allows to restrict classification of the input image to the area where mask pixel values are greater than 0.");
    MandatoryOff("mask");

    AddParameter(ParameterType_InputFilename, "model", "Model file");
    SetParameterDescription("model", "A model file (*.txt extension, produced by TrainImagesClassifier application).");

    AddParameter(ParameterType_InputFilename, "imstat", "Statistics file");
    SetParameterDescription("imstat", "A XML file containing mean and standard deviation to center and reduce samples before classification (produced by ComputeImagesStatistics application).");
    MandatoryOff("imstat");

    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
    SetParameterDescription( "out", "Output image containing class labels");
    SetParameterOutputImagePixelType( "out", ImagePixelType_uint8);

    AddRAMParameter();

   // Doc example parameter settings
    SetDocExampleParameterValue("in", "QB_1_ortho.tif");
    SetDocExampleParameterValue("imstat", "EstimateImageStatisticsQB1.xml");
    SetDocExampleParameterValue("model", "clsvmModelQB1.svm");
    SetDocExampleParameterValue("out", "clLabeledImageQB1.tif");
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {
    // Load input image
    FloatVectorImageType::Pointer inImage = GetParameterImage("in");
    inImage->UpdateOutputInformation();

    // Load svm model
    otbAppLogINFO("Loading model");
    m_Model = MachineLearningModelFactoryType::CreateMachineLearningModel(GetParameterString("model"),
                                                                          MachineLearningModelFactoryType::ReadMode);
    m_Model->Load(GetParameterString("model"));
    otbAppLogINFO("Model loaded");

    // Normalize input image (optional)
    StatisticsReader::Pointer  statisticsReader = StatisticsReader::New();
    MeasurementType  meanMeasurementVector;
    MeasurementType  stddevMeasurementVector;
    m_Rescaler = RescalerType::New();

    // Classify
    m_ClassificationFilter = ClassificationFilterType::New();
    m_ClassificationFilter->SetModel(m_Model);

    // Normalize input image if asked
    if(IsParameterEnabled("imstat")  )
      {
      otbAppLogINFO("Input image normalization activated.");
      // Load input image statistics
      statisticsReader->SetFileName(GetParameterString("imstat"));
      meanMeasurementVector   = statisticsReader->GetStatisticVectorByName("mean");
      stddevMeasurementVector = statisticsReader->GetStatisticVectorByName("stddev");
      otbAppLogINFO( "mean used: " << meanMeasurementVector );
      otbAppLogINFO( "standard deviation used: " << stddevMeasurementVector );
      // Rescale vector image
      m_Rescaler->SetScale(stddevMeasurementVector);
      m_Rescaler->SetShift(meanMeasurementVector);
      m_Rescaler->SetInput(inImage);

      m_ClassificationFilter->SetInput(m_Rescaler->GetOutput());
      }
    else
      {
      otbAppLogINFO("Input image normalization deactivated.");
      m_ClassificationFilter->SetInput(inImage);
      }

    if(IsParameterEnabled("mask"))
      {
      otbAppLogINFO("Using input mask");
      // Load mask image and cast into LabeledImageType
      UInt32ImageType::Pointer inMask = GetParameterUInt32Image("mask");

      m_ClassificationFilter->SetInputMask(inMask);
      }

    SetParameterOutputImage<UInt32ImageType>("out", m_ClassificationFilter->GetOutput());
  }

  ClassificationFilterType::Pointer m_ClassificationFilter;
  ModelPointerType m_Model;
  RescalerType::Pointer m_Rescaler;
};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::ImageClassifier)
<commit_msg>ENH: ImageClassifier application: generation of classification maps with maximal labels equal to 65535<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "itkVariableLengthVector.h"
#include "otbChangeLabelImageFilter.h"
#include "otbStandardWriterWatcher.h"
#include "otbStatisticsXMLFileReader.h"
#include "otbShiftScaleVectorImageFilter.h"
#include "otbImageClassificationFilter.h"
#include "otbMultiToMonoChannelExtractROI.h"
#include "otbImageToVectorImageCastFilter.h"
#include "otbMachineLearningModelFactory.h"

namespace otb
{
namespace Wrapper
{

class ImageClassifier : public Application
{
public:
  /** Standard class typedefs. */
  typedef ImageClassifier            Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(ImageClassifier, otb::Application);

  /** Filters typedef */
  typedef UInt16ImageType                                                                      OutputImageType;
  typedef UInt8ImageType                                                                       MaskImageType;
  typedef itk::VariableLengthVector<FloatVectorImageType::InternalPixelType>                   MeasurementType;
  typedef otb::StatisticsXMLFileReader<MeasurementType>                                        StatisticsReader;
  typedef otb::ShiftScaleVectorImageFilter<FloatVectorImageType, FloatVectorImageType>         RescalerType;
  typedef otb::ImageClassificationFilter<FloatVectorImageType, OutputImageType, MaskImageType> ClassificationFilterType;
  typedef ClassificationFilterType::Pointer                                                    ClassificationFilterPointerType;
  typedef ClassificationFilterType::ModelType                                                  ModelType;
  typedef ModelType::Pointer                                                                   ModelPointerType;
  typedef ClassificationFilterType::ValueType                                                  ValueType;
  typedef ClassificationFilterType::LabelType                                                  LabelType;
  typedef otb::MachineLearningModelFactory<ValueType, LabelType>                               MachineLearningModelFactoryType;

private:
  void DoInit()
  {
    SetName("ImageClassifier");
    SetDescription("Performs a classification of the input image according to a model file.");

    // Documentation
    SetDocName("Image Classification");
    SetDocLongDescription("This application performs an image classification based on a model file produced by the TrainImagesClassifier application. Pixels of the output image will contain the class labels decided by the classifier (maximal class label = 65535). The input pixels can be optionally centered and reduced according to the statistics file produced by the ComputeImagesStatistics application. An optional input mask can be provided, in which case only input image pixels whose corresponding mask value is greater than 0 will be classified. The remaining of pixels will be given the label 0 in the output image.");

    SetDocLimitations("The input image must have the same type, order and number of bands than the images used to produce the statistics file and the SVM model file. If a statistics file was used during training by the TrainImagesClassifier, it is mandatory to use the same statistics file for classification. If an input mask is used, its size must match the input image size.");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("TrainImagesClassifier, ValidateImagesClassifier, ComputeImagesStatistics");

    AddDocTag(Tags::Learning);

    AddParameter(ParameterType_InputImage, "in",  "Input Image");
    SetParameterDescription( "in", "The input image to classify.");

    AddParameter(ParameterType_InputImage,  "mask",   "Input Mask");
    SetParameterDescription( "mask", "The mask allows to restrict classification of the input image to the area where mask pixel values are greater than 0.");
    MandatoryOff("mask");

    AddParameter(ParameterType_InputFilename, "model", "Model file");
    SetParameterDescription("model", "A model file (produced by TrainImagesClassifier application, maximal class label = 65535).");

    AddParameter(ParameterType_InputFilename, "imstat", "Statistics file");
    SetParameterDescription("imstat", "A XML file containing mean and standard deviation to center and reduce samples before classification (produced by ComputeImagesStatistics application).");
    MandatoryOff("imstat");

    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
    SetParameterDescription( "out", "Output image containing class labels");
    SetParameterOutputImagePixelType( "out", ImagePixelType_uint8);

    AddRAMParameter();

   // Doc example parameter settings
    SetDocExampleParameterValue("in", "QB_1_ortho.tif");
    SetDocExampleParameterValue("imstat", "EstimateImageStatisticsQB1.xml");
    SetDocExampleParameterValue("model", "clsvmModelQB1.svm");
    SetDocExampleParameterValue("out", "clLabeledImageQB1.tif");
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {
    // Load input image
    FloatVectorImageType::Pointer inImage = GetParameterImage("in");
    inImage->UpdateOutputInformation();

    // Load svm model
    otbAppLogINFO("Loading model");
    m_Model = MachineLearningModelFactoryType::CreateMachineLearningModel(GetParameterString("model"),
                                                                          MachineLearningModelFactoryType::ReadMode);
    m_Model->Load(GetParameterString("model"));
    otbAppLogINFO("Model loaded");

    // Normalize input image (optional)
    StatisticsReader::Pointer  statisticsReader = StatisticsReader::New();
    MeasurementType  meanMeasurementVector;
    MeasurementType  stddevMeasurementVector;
    m_Rescaler = RescalerType::New();

    // Classify
    m_ClassificationFilter = ClassificationFilterType::New();
    m_ClassificationFilter->SetModel(m_Model);

    // Normalize input image if asked
    if(IsParameterEnabled("imstat")  )
      {
      otbAppLogINFO("Input image normalization activated.");
      // Load input image statistics
      statisticsReader->SetFileName(GetParameterString("imstat"));
      meanMeasurementVector   = statisticsReader->GetStatisticVectorByName("mean");
      stddevMeasurementVector = statisticsReader->GetStatisticVectorByName("stddev");
      otbAppLogINFO( "mean used: " << meanMeasurementVector );
      otbAppLogINFO( "standard deviation used: " << stddevMeasurementVector );
      // Rescale vector image
      m_Rescaler->SetScale(stddevMeasurementVector);
      m_Rescaler->SetShift(meanMeasurementVector);
      m_Rescaler->SetInput(inImage);

      m_ClassificationFilter->SetInput(m_Rescaler->GetOutput());
      }
    else
      {
      otbAppLogINFO("Input image normalization deactivated.");
      m_ClassificationFilter->SetInput(inImage);
      }

    if(IsParameterEnabled("mask"))
      {
      otbAppLogINFO("Using input mask");
      // Load mask image and cast into LabeledImageType
      MaskImageType::Pointer inMask = GetParameterUInt8Image("mask");

      m_ClassificationFilter->SetInputMask(inMask);
      }

    SetParameterOutputImage<OutputImageType>("out", m_ClassificationFilter->GetOutput());
  }

  ClassificationFilterType::Pointer m_ClassificationFilter;
  ModelPointerType m_Model;
  RescalerType::Pointer m_Rescaler;
};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::ImageClassifier)
<|endoftext|>


<commit_before>// Copyright (c) 2014, Baidu.com, Inc. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Author: yanshiguang02@baidu.com

#include <gflags/gflags.h>

// global
DEFINE_bool(bfs_bug_tolerant, true, "Tolerate minor bug");
DEFINE_string(bfs_log, "", "BFS log");
DEFINE_int32(bfs_log_size, 1024, "BFS log size");
// nameserver
DEFINE_string(namedb_path, "./db", "Namespace database");
DEFINE_int64(namedb_cache_size, 1024L, "Namespace datebase memery cache size");
DEFINE_string(nameserver, "127.0.0.1", "Nameserver host");
DEFINE_string(nameserver_port, "8828", "Nameserver port");
DEFINE_int32(keepalive_timeout, 10, "Chunkserver keepalive timeout");
DEFINE_int32(default_replica_num, 3, "Default replica num of data block");
DEFINE_int32(nameserver_log_level, 4, "Nameserver log level");
DEFINE_string(nameserver_logfile, "./nlog", "Nameserver log file");
DEFINE_string(nameserver_warninglog, "./wflog", "Warning log file");
DEFINE_int32(nameserver_safemode_time, 120, "Nameserver leave safemode time in ms");
DEFINE_int32(recover_speed, 100, "max num of block to recover for one chunkserver");
DEFINE_int32(recover_timeout, 180, "Recover timeout for one chunkserver");
DEFINE_bool(clean_redundancy, false, "Clean redundant replica");
DEFINE_int32(nameserver_report_thread_num, 20, "Threads to handle block report");
DEFINE_int32(nameserver_work_thread_num, 20, "Work threads num");
DEFINE_bool(select_chunkserver_by_zone, false, "Select chunkserver by zone");

// chunkserver
DEFINE_string(block_store_path, "./data", "Data path");
DEFINE_string(chunkserver_port, "8825", "Chunkserver port");
DEFINE_int32(heartbeat_interval, 1, "Heartbeat interval");
DEFINE_int32(blockreport_interval, 10, "blockreport_interval");
DEFINE_int32(blockreport_size, 2000, "blockreport_size");
DEFINE_int32(chunkserver_log_level, 4, "Chunkserver log level");
DEFINE_string(chunkserver_warninglog, "./wflog", "Warning log file");
DEFINE_int32(write_buf_size, 1024*1024, "Block write buffer size, bytes");
DEFINE_int32(chunkserver_max_pending_buffers, 10240, "Buffer num wait flush to disk");
DEFINE_int32(chunkserver_work_thread_num, 10, "Chunkserver work thread num");
DEFINE_int32(chunkserver_read_thread_num, 20, "Chunkserver work thread num");
DEFINE_int32(chunkserver_write_thread_num, 10, "Chunkserver work thread num");
DEFINE_int32(chunkserver_io_thread_num, 10, "Chunkserver io thread num");
DEFINE_int32(chunkserver_recover_thread_num, 10, "Chunkserver work thread num");
DEFINE_int32(chunkserver_file_cache_size, 1000, "Chunkserver file cache size");
DEFINE_int32(chunkserver_use_root_partition, 1, "Should chunkserver use root partition, 0: forbidden");
DEFINE_bool(chunkserver_auto_clean, true, "If namespace version mismatch, chunkserver clean itself");
// SDK
DEFINE_int32(sdk_thread_num, 10, "Sdk thread num");
DEFINE_int32(sdk_file_reada_len, 1024*1024, "Read ahead buffer len");
DEFINE_string(sdk_write_mode, "chains", "Sdk write mode: chains/fan-out");
DEFINE_int32(sdk_createblock_retry, 5, "Create block retry times before fail");

/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
<commit_msg>Remove unused flag<commit_after>// Copyright (c) 2014, Baidu.com, Inc. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Author: yanshiguang02@baidu.com

#include <gflags/gflags.h>

// global
DEFINE_bool(bfs_bug_tolerant, true, "Tolerate minor bug");
DEFINE_string(bfs_log, "", "BFS log");
DEFINE_int32(bfs_log_size, 1024, "BFS log size");
// nameserver
DEFINE_string(namedb_path, "./db", "Namespace database");
DEFINE_int64(namedb_cache_size, 1024L, "Namespace datebase memery cache size");
DEFINE_string(nameserver, "127.0.0.1", "Nameserver host");
DEFINE_string(nameserver_port, "8828", "Nameserver port");
DEFINE_int32(keepalive_timeout, 10, "Chunkserver keepalive timeout");
DEFINE_int32(default_replica_num, 3, "Default replica num of data block");
DEFINE_int32(nameserver_log_level, 4, "Nameserver log level");
DEFINE_string(nameserver_warninglog, "./wflog", "Warning log file");
DEFINE_int32(nameserver_safemode_time, 120, "Nameserver leave safemode time in ms");
DEFINE_int32(recover_speed, 100, "max num of block to recover for one chunkserver");
DEFINE_int32(recover_timeout, 180, "Recover timeout for one chunkserver");
DEFINE_bool(clean_redundancy, false, "Clean redundant replica");
DEFINE_int32(nameserver_report_thread_num, 20, "Threads to handle block report");
DEFINE_int32(nameserver_work_thread_num, 20, "Work threads num");
DEFINE_bool(select_chunkserver_by_zone, false, "Select chunkserver by zone");

// chunkserver
DEFINE_string(block_store_path, "./data", "Data path");
DEFINE_string(chunkserver_port, "8825", "Chunkserver port");
DEFINE_int32(heartbeat_interval, 1, "Heartbeat interval");
DEFINE_int32(blockreport_interval, 10, "blockreport_interval");
DEFINE_int32(blockreport_size, 2000, "blockreport_size");
DEFINE_int32(chunkserver_log_level, 4, "Chunkserver log level");
DEFINE_string(chunkserver_warninglog, "./wflog", "Warning log file");
DEFINE_int32(write_buf_size, 1024*1024, "Block write buffer size, bytes");
DEFINE_int32(chunkserver_max_pending_buffers, 10240, "Buffer num wait flush to disk");
DEFINE_int32(chunkserver_work_thread_num, 10, "Chunkserver work thread num");
DEFINE_int32(chunkserver_read_thread_num, 20, "Chunkserver work thread num");
DEFINE_int32(chunkserver_write_thread_num, 10, "Chunkserver work thread num");
DEFINE_int32(chunkserver_io_thread_num, 10, "Chunkserver io thread num");
DEFINE_int32(chunkserver_recover_thread_num, 10, "Chunkserver work thread num");
DEFINE_int32(chunkserver_file_cache_size, 1000, "Chunkserver file cache size");
DEFINE_int32(chunkserver_use_root_partition, 1, "Should chunkserver use root partition, 0: forbidden");
DEFINE_bool(chunkserver_auto_clean, true, "If namespace version mismatch, chunkserver clean itself");
// SDK
DEFINE_int32(sdk_thread_num, 10, "Sdk thread num");
DEFINE_int32(sdk_file_reada_len, 1024*1024, "Read ahead buffer len");
DEFINE_string(sdk_write_mode, "chains", "Sdk write mode: chains/fan-out");
DEFINE_int32(sdk_createblock_retry, 5, "Create block retry times before fail");

/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
<|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2012 Francois Beaune, Jupiter Jazz Limited
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// appleseed.foundation headers.
#include "foundation/utility/containers/dictionary.h"
#include "foundation/utility/test.h"

// Standard headers.
#include <string>

using namespace foundation;
using namespace std;

TEST_SUITE(Foundation_Utility_StringDictionary)
{
    TEST_CASE(EqualityOperator_GivenTwoEmptyDictionaries_ReturnsTrue)
    {
        StringDictionary sd1;
        StringDictionary sd2;

        ASSERT_TRUE(sd1 == sd2);
        ASSERT_FALSE(sd1 != sd2);
    }

    TEST_CASE(EqualityOperator_GivenDictionariesOfDifferentSize_ReturnsFalse)
    {
        StringDictionary sd1;
        sd1.insert("key", "value");

        StringDictionary sd2;

        ASSERT_FALSE(sd1 == sd2);
        ASSERT_TRUE(sd1 != sd2);
    }

    TEST_CASE(EqualityOperator_GivenDictionariesWithSingleItemWithSameKeyButDifferentValues_ReturnsFalse)
    {
        StringDictionary sd1;
        sd1.insert("key", "value1");

        StringDictionary sd2;
        sd2.insert("key", "value2");

        ASSERT_FALSE(sd1 == sd2);
        ASSERT_TRUE(sd1 != sd2);
    }

    TEST_CASE(EqualityOperator_GivenDictionariesWithSingleItemWithDifferentKeysButSameValue_ReturnsFalse)
    {
        StringDictionary sd1;
        sd1.insert("key1", "value");

        StringDictionary sd2;
        sd2.insert("key2", "value");

        ASSERT_FALSE(sd1 == sd2);
        ASSERT_TRUE(sd1 != sd2);
    }

    TEST_CASE(EqualityOperator_GivenDictionariesWithSingleIdenticalItem_ReturnsTrue)
    {
        StringDictionary sd1;
        sd1.insert("key", "value");

        StringDictionary sd2;
        sd2.insert("key", "value");

        ASSERT_TRUE(sd1 == sd2);
        ASSERT_FALSE(sd1 != sd2);
    }

    TEST_CASE(Insert_ReturnsThisPointer)
    {
        StringDictionary sd;

        const StringDictionary* result = &sd.insert("key", "value");

        EXPECT_EQ(&sd, result);
    }

    TEST_CASE(Get_GivenCStringKeyOfNonExistingItem_ThrowsExceptionDictionaryItemNotFound)
    {
        StringDictionary sd;

        EXPECT_EXCEPTION(ExceptionDictionaryItemNotFound,
        {
            const char* item = sd.get("key");
        });
    }

    TEST_CASE(GetAsInt_GivenCStringKeyOfNonExistingItem_ThrowsExceptionDictionaryItemNotFound)
    {
        StringDictionary sd;

        EXPECT_EXCEPTION(ExceptionDictionaryItemNotFound,
        {
            const int item = sd.get<int>("key");
        });
    }

    TEST_CASE(GetAsInt_GivenStdStringKeyOfNonExistingItem_ThrowsExceptionDictionaryItemNotFound)
    {
        StringDictionary sd;

        EXPECT_EXCEPTION(ExceptionDictionaryItemNotFound,
        {
            const int item = sd.get<int>(string("key"));
        });
    }

    TEST_CASE(Remove_GivenCStringKeyOfExistingItem_RemovesItem)
    {
        StringDictionary sd;
        sd.insert("key", "value");

        sd.remove("key");

        EXPECT_FALSE(sd.exist("key"));
    }

    TEST_CASE(Remove_GivenStdStringKeyOfExistingItem_RemovesItem)
    {
        StringDictionary sd;
        sd.insert("key", "value");

        sd.remove(string("key"));

        EXPECT_FALSE(sd.exist("key"));
    }

    TEST_CASE(Remove_GivenCStringKeyOfNonExistingItem_DoesNothing)
    {
        StringDictionary sd;

        sd.remove("key");
    }

    TEST_CASE(Remove_ReturnsThisPointer)
    {
        StringDictionary sd;

        const StringDictionary* result = &sd.remove("key");

        EXPECT_EQ(&sd, result);
    }
}

TEST_SUITE(Foundation_Utility_DictionaryDictionary)
{
    TEST_CASE(Insert_ReturnsThisPointer)
    {
        DictionaryDictionary dd;

        const DictionaryDictionary* result = &dd.insert("key", Dictionary());

        EXPECT_EQ(&dd, result);
    }

    TEST_CASE(Remove_GivenCStringKeyOfNonExistingItem_DoesNothing)
    {
        DictionaryDictionary dd;

        dd.remove("key");
    }

    TEST_CASE(Remove_ReturnsThisPointer)
    {
        DictionaryDictionary dd;

        const DictionaryDictionary* result = &dd.remove("key");

        EXPECT_EQ(&dd, result);
    }
}

TEST_SUITE(Foundation_Utility_Dictionary)
{
    TEST_CASE(Constructor_ConstructsEmptyDictionary)
    {
        Dictionary dic;

        EXPECT_EQ(0, dic.size());
        EXPECT_TRUE(dic.empty());
    }

    TEST_CASE(CopyConstructor_GivenSourceDictionaryWithOneStringItem_CopiesStringItem)
    {
        Dictionary dic;
        dic.insert("key", "value");

        Dictionary copy(dic);

        EXPECT_EQ("value", copy.get<string>("key"));
    }

    TEST_CASE(CopyConstructor_GivenSourceDictionaryWithOneDictionaryItem_CopiesDictionaryItem)
    {
        Dictionary child;
        child.insert("key", "value");

        Dictionary dic;
        dic.insert("child", child);

        Dictionary copy(dic);

        EXPECT_EQ("value", copy.dictionary("child").get<string>("key"));
    }

    TEST_CASE(AssignmentOperator_GivenSourceDictionaryWithOneStringItem_CopiesStringItem)
    {
        Dictionary dic;
        dic.insert("key", "value");

        Dictionary other;
        other = dic;

        EXPECT_EQ("value", other.get<string>("key"));
    }

    TEST_CASE(AssignmentOperator_GivenSourceDictionaryWithOneDictionaryItem_CopiesDictionaryItem)
    {
        Dictionary child;
        child.insert("key", "value");

        Dictionary dic;
        dic.insert("child", child);

        Dictionary other;
        other = dic;

        EXPECT_EQ("value", other.dictionary("child").get<string>("key"));
    }

    TEST_CASE(Clear_GivenDictionaryWithOneStringItem_RemovesItem)
    {
        Dictionary dic;
        dic.insert("key", "value");

        dic.clear();

        EXPECT_EQ(0, dic.size());
        EXPECT_TRUE(dic.empty());
    }

    TEST_CASE(Clear_GivenDictionaryWithOneDictionaryItem_RemovesItem)
    {
        Dictionary dic;
        dic.insert("key", Dictionary());

        dic.clear();

        EXPECT_EQ(0, dic.size());
        EXPECT_TRUE(dic.empty());
    }

    TEST_CASE(Insert_GivenCStringKeyAndCStringValue_InsertsValue)
    {
        Dictionary dic;

        dic.insert("key", "value");

        EXPECT_EQ(1, dic.size());
        EXPECT_FALSE(dic.empty());
        EXPECT_EQ("value", dic.get<string>("key"));
    }

    TEST_CASE(Insert_GivenCStringKeyAndStdStringValue_InsertsValue)
    {
        Dictionary dic;

        dic.insert("key", string("value"));

        EXPECT_EQ(1, dic.size());
        EXPECT_FALSE(dic.empty());
        EXPECT_EQ("value", dic.get<string>("key"));
    }

    TEST_CASE(Insert_GivenCStringKeyAndIntegerValue_InsertsValue)
    {
        Dictionary dic;

        dic.insert("key", 42);

        EXPECT_EQ(1, dic.size());
        EXPECT_FALSE(dic.empty());
        EXPECT_EQ(42, dic.get<int>("key"));
    }

    TEST_CASE(Insert_GivenStdStringKeyAndCStringValue_InsertsValue)
    {
        Dictionary dic;

        dic.insert(string("key"), "value");

        EXPECT_EQ(1, dic.size());
        EXPECT_FALSE(dic.empty());
        EXPECT_EQ("value", dic.get<string>("key"));
    }

    TEST_CASE(Insert_GivenStdStringKeyAndIntegerValue_InsertsValue)
    {
        Dictionary dic;

        dic.insert(string("key"), 42);

        EXPECT_EQ(1, dic.size());
        EXPECT_FALSE(dic.empty());
        EXPECT_EQ(42, dic.get<int>("key"));
    }

    TEST_CASE(Insert_GivenDictionary_ReturnsThisPointer)
    {
        Dictionary dic;

        const Dictionary* result = &dic.insert("key", Dictionary());

        EXPECT_EQ(&dic, result);
    }

    TEST_CASE(Insert_GivenCString_ReturnsThisPointer)
    {
        Dictionary dic;

        const Dictionary* result = &dic.insert("key", "value");

        EXPECT_EQ(&dic, result);
    }

    TEST_CASE(GetAsInt_GivenCStringKeyOfNonExistingItem_ThrowsExceptionDictionaryItemNotFound)
    {
        Dictionary dic;

        EXPECT_EXCEPTION(ExceptionDictionaryItemNotFound,
        {
            const int item = dic.get<int>("key");
        });
    }

    TEST_CASE(GetAsInt_GivenStdStringKeyOfNonExistingItem_ThrowsExceptionDictionaryItemNotFound)
    {
        Dictionary dic;

        EXPECT_EXCEPTION(ExceptionDictionaryItemNotFound,
        {
            const int item = dic.get<int>(string("key"));
        });
    }
}
<commit_msg>replaced ASSERTs by EXPECTs.<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2012 Francois Beaune, Jupiter Jazz Limited
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// appleseed.foundation headers.
#include "foundation/utility/containers/dictionary.h"
#include "foundation/utility/test.h"

// Standard headers.
#include <string>

using namespace foundation;
using namespace std;

TEST_SUITE(Foundation_Utility_StringDictionary)
{
    TEST_CASE(EqualityOperator_GivenTwoEmptyDictionaries_ReturnsTrue)
    {
        StringDictionary sd1;
        StringDictionary sd2;

        EXPECT_TRUE(sd1 == sd2);
        EXPECT_FALSE(sd1 != sd2);
    }

    TEST_CASE(EqualityOperator_GivenDictionariesOfDifferentSize_ReturnsFalse)
    {
        StringDictionary sd1;
        sd1.insert("key", "value");

        StringDictionary sd2;

        EXPECT_FALSE(sd1 == sd2);
        EXPECT_TRUE(sd1 != sd2);
    }

    TEST_CASE(EqualityOperator_GivenDictionariesWithSingleItemWithSameKeyButDifferentValues_ReturnsFalse)
    {
        StringDictionary sd1;
        sd1.insert("key", "value1");

        StringDictionary sd2;
        sd2.insert("key", "value2");

        EXPECT_FALSE(sd1 == sd2);
        EXPECT_TRUE(sd1 != sd2);
    }

    TEST_CASE(EqualityOperator_GivenDictionariesWithSingleItemWithDifferentKeysButSameValue_ReturnsFalse)
    {
        StringDictionary sd1;
        sd1.insert("key1", "value");

        StringDictionary sd2;
        sd2.insert("key2", "value");

        EXPECT_FALSE(sd1 == sd2);
        EXPECT_TRUE(sd1 != sd2);
    }

    TEST_CASE(EqualityOperator_GivenDictionariesWithSingleIdenticalItem_ReturnsTrue)
    {
        StringDictionary sd1;
        sd1.insert("key", "value");

        StringDictionary sd2;
        sd2.insert("key", "value");

        EXPECT_TRUE(sd1 == sd2);
        EXPECT_FALSE(sd1 != sd2);
    }

    TEST_CASE(Insert_ReturnsThisPointer)
    {
        StringDictionary sd;

        const StringDictionary* result = &sd.insert("key", "value");

        EXPECT_EQ(&sd, result);
    }

    TEST_CASE(Get_GivenCStringKeyOfNonExistingItem_ThrowsExceptionDictionaryItemNotFound)
    {
        StringDictionary sd;

        EXPECT_EXCEPTION(ExceptionDictionaryItemNotFound,
        {
            const char* item = sd.get("key");
        });
    }

    TEST_CASE(GetAsInt_GivenCStringKeyOfNonExistingItem_ThrowsExceptionDictionaryItemNotFound)
    {
        StringDictionary sd;

        EXPECT_EXCEPTION(ExceptionDictionaryItemNotFound,
        {
            const int item = sd.get<int>("key");
        });
    }

    TEST_CASE(GetAsInt_GivenStdStringKeyOfNonExistingItem_ThrowsExceptionDictionaryItemNotFound)
    {
        StringDictionary sd;

        EXPECT_EXCEPTION(ExceptionDictionaryItemNotFound,
        {
            const int item = sd.get<int>(string("key"));
        });
    }

    TEST_CASE(Remove_GivenCStringKeyOfExistingItem_RemovesItem)
    {
        StringDictionary sd;
        sd.insert("key", "value");

        sd.remove("key");

        EXPECT_FALSE(sd.exist("key"));
    }

    TEST_CASE(Remove_GivenStdStringKeyOfExistingItem_RemovesItem)
    {
        StringDictionary sd;
        sd.insert("key", "value");

        sd.remove(string("key"));

        EXPECT_FALSE(sd.exist("key"));
    }

    TEST_CASE(Remove_GivenCStringKeyOfNonExistingItem_DoesNothing)
    {
        StringDictionary sd;

        sd.remove("key");
    }

    TEST_CASE(Remove_ReturnsThisPointer)
    {
        StringDictionary sd;

        const StringDictionary* result = &sd.remove("key");

        EXPECT_EQ(&sd, result);
    }
}

TEST_SUITE(Foundation_Utility_DictionaryDictionary)
{
    TEST_CASE(Insert_ReturnsThisPointer)
    {
        DictionaryDictionary dd;

        const DictionaryDictionary* result = &dd.insert("key", Dictionary());

        EXPECT_EQ(&dd, result);
    }

    TEST_CASE(Remove_GivenCStringKeyOfNonExistingItem_DoesNothing)
    {
        DictionaryDictionary dd;

        dd.remove("key");
    }

    TEST_CASE(Remove_ReturnsThisPointer)
    {
        DictionaryDictionary dd;

        const DictionaryDictionary* result = &dd.remove("key");

        EXPECT_EQ(&dd, result);
    }
}

TEST_SUITE(Foundation_Utility_Dictionary)
{
    TEST_CASE(Constructor_ConstructsEmptyDictionary)
    {
        Dictionary dic;

        EXPECT_EQ(0, dic.size());
        EXPECT_TRUE(dic.empty());
    }

    TEST_CASE(CopyConstructor_GivenSourceDictionaryWithOneStringItem_CopiesStringItem)
    {
        Dictionary dic;
        dic.insert("key", "value");

        Dictionary copy(dic);

        EXPECT_EQ("value", copy.get<string>("key"));
    }

    TEST_CASE(CopyConstructor_GivenSourceDictionaryWithOneDictionaryItem_CopiesDictionaryItem)
    {
        Dictionary child;
        child.insert("key", "value");

        Dictionary dic;
        dic.insert("child", child);

        Dictionary copy(dic);

        EXPECT_EQ("value", copy.dictionary("child").get<string>("key"));
    }

    TEST_CASE(AssignmentOperator_GivenSourceDictionaryWithOneStringItem_CopiesStringItem)
    {
        Dictionary dic;
        dic.insert("key", "value");

        Dictionary other;
        other = dic;

        EXPECT_EQ("value", other.get<string>("key"));
    }

    TEST_CASE(AssignmentOperator_GivenSourceDictionaryWithOneDictionaryItem_CopiesDictionaryItem)
    {
        Dictionary child;
        child.insert("key", "value");

        Dictionary dic;
        dic.insert("child", child);

        Dictionary other;
        other = dic;

        EXPECT_EQ("value", other.dictionary("child").get<string>("key"));
    }

    TEST_CASE(Clear_GivenDictionaryWithOneStringItem_RemovesItem)
    {
        Dictionary dic;
        dic.insert("key", "value");

        dic.clear();

        EXPECT_EQ(0, dic.size());
        EXPECT_TRUE(dic.empty());
    }

    TEST_CASE(Clear_GivenDictionaryWithOneDictionaryItem_RemovesItem)
    {
        Dictionary dic;
        dic.insert("key", Dictionary());

        dic.clear();

        EXPECT_EQ(0, dic.size());
        EXPECT_TRUE(dic.empty());
    }

    TEST_CASE(Insert_GivenCStringKeyAndCStringValue_InsertsValue)
    {
        Dictionary dic;

        dic.insert("key", "value");

        EXPECT_EQ(1, dic.size());
        EXPECT_FALSE(dic.empty());
        EXPECT_EQ("value", dic.get<string>("key"));
    }

    TEST_CASE(Insert_GivenCStringKeyAndStdStringValue_InsertsValue)
    {
        Dictionary dic;

        dic.insert("key", string("value"));

        EXPECT_EQ(1, dic.size());
        EXPECT_FALSE(dic.empty());
        EXPECT_EQ("value", dic.get<string>("key"));
    }

    TEST_CASE(Insert_GivenCStringKeyAndIntegerValue_InsertsValue)
    {
        Dictionary dic;

        dic.insert("key", 42);

        EXPECT_EQ(1, dic.size());
        EXPECT_FALSE(dic.empty());
        EXPECT_EQ(42, dic.get<int>("key"));
    }

    TEST_CASE(Insert_GivenStdStringKeyAndCStringValue_InsertsValue)
    {
        Dictionary dic;

        dic.insert(string("key"), "value");

        EXPECT_EQ(1, dic.size());
        EXPECT_FALSE(dic.empty());
        EXPECT_EQ("value", dic.get<string>("key"));
    }

    TEST_CASE(Insert_GivenStdStringKeyAndIntegerValue_InsertsValue)
    {
        Dictionary dic;

        dic.insert(string("key"), 42);

        EXPECT_EQ(1, dic.size());
        EXPECT_FALSE(dic.empty());
        EXPECT_EQ(42, dic.get<int>("key"));
    }

    TEST_CASE(Insert_GivenDictionary_ReturnsThisPointer)
    {
        Dictionary dic;

        const Dictionary* result = &dic.insert("key", Dictionary());

        EXPECT_EQ(&dic, result);
    }

    TEST_CASE(Insert_GivenCString_ReturnsThisPointer)
    {
        Dictionary dic;

        const Dictionary* result = &dic.insert("key", "value");

        EXPECT_EQ(&dic, result);
    }

    TEST_CASE(GetAsInt_GivenCStringKeyOfNonExistingItem_ThrowsExceptionDictionaryItemNotFound)
    {
        Dictionary dic;

        EXPECT_EXCEPTION(ExceptionDictionaryItemNotFound,
        {
            const int item = dic.get<int>("key");
        });
    }

    TEST_CASE(GetAsInt_GivenStdStringKeyOfNonExistingItem_ThrowsExceptionDictionaryItemNotFound)
    {
        Dictionary dic;

        EXPECT_EXCEPTION(ExceptionDictionaryItemNotFound,
        {
            const int item = dic.get<int>(string("key"));
        });
    }
}
<|endoftext|>


<commit_before>#ifndef ALGORITHM_HUFFMAN_H_
#define ALGORITHM_HUFFMAN_H_ 1

#include <vector>
#include <string>
#include <functional>

namespace algorithm
{

class Huffman
{
public:
    typedef unsigned char   SymbolType;
    typedef size_t          SizeType;
    typedef unsigned int    CodewordType;
    typedef std::string     StringType;
    typedef std::ifstream   FileInputType;
    typedef std::ofstream   FileOutputType;
    typedef uint32_t        EncodeBufferType;

    typedef std::pair<SymbolType, SizeType> MetaSymbolType;

    struct Run
    {
        SymbolType      symbol;
        SizeType        run_len;
        SizeType        freq;

        Run *           left;
        Run *           right;

        CodewordType    codeword;
        SizeType        codeword_len;

        Run *           next;

        Run(const SymbolType & symbol, const SizeType & run_len, const SizeType & freq = 0)
        : symbol        (symbol)
        , run_len       (run_len)
        , freq          (freq)
        , left          (nullptr)
        , right         (nullptr)
        , codeword      (0)
        , codeword_len  (0)
        , next          (nullptr)
        { }

        Run(const MetaSymbolType & meta_symbol, const SizeType & freq = 0)
        : symbol        (meta_symbol.first)
        , run_len       (meta_symbol.second)
        , freq          (freq)
        , left          (nullptr)
        , right         (nullptr)
        , codeword      (0)
        , codeword_len  (0)
        , next          (nullptr)
        { }

        Run(const Run & run)
        : symbol        (run.symbol)
        , run_len       (run.run_len)
        , freq          (run.freq)
        , left          (run.left)
        , right         (run.right)
        , codeword      (run.codeword)
        , codeword_len  (run.codeword_len)
        , next          (run.next)
        { }

        Run(Run * left, Run * right)
        : symbol        (0)
        , run_len       (0)
        , freq          (left->freq + right->freq)
        , left          (left)
        , right         (right)
        , codeword      (0)
        , codeword_len  (0)
        , next          (nullptr)
        { }

        inline
        Run &
        operator=(Run run)
        {
            this->symbol        = run.symbol;
            this->run_len       = run.run_len;
            this->freq          = run.freq;
            this->left          = run.left;
            this->right         = run.right;
            this->codeword      = run.codeword;
            this->codeword_len  = run.codeword_len;
            this->next          = run.next;

            return *this;
        }

        inline
        bool
        operator==(const Run & rhs)
        const
        { return symbol == rhs.symbol && run_len == rhs.run_len; }

        inline
        bool
        operator!=(const Run & rhs)
        const
        { return ! (*this == rhs); }

        inline
        Run &
        operator++(void)
        {
            ++freq;
            return *this;
        }

        inline
        Run
        operator++(int)
        {
            Run temp(*this);
            operator++();
            return temp;
        }

        inline
        Run &
        operator--(void)
        {
            --freq;
            return *this;
        }

        inline
        Run
        operator--(int)
        {
            Run temp(*this);
            operator--();
            return temp;
        }

        inline
        bool
        operator<(const Run & rhs)
        const
        { return (this->freq < rhs.freq); }

        inline
        bool
        operator>(const Run & rhs)
        const
        { return (this->freq > rhs.freq); }

        inline
        bool
        operator<=(const Run & rhs)
        const
        { return ! operator>(rhs); }

        inline
        bool
        operator>=(const Run & rhs)
        const
        { return ! operator<(rhs); }
    };

    typedef Run     RunType;

    typedef std::vector<RunType>                        RunArrayType;
    typedef std::array<RunType *, sizeof(SymbolType)>   RunListType;
    typedef RunType *                                   HuffmanTreeType;

private:
    RunArrayType        runs_;
    RunListType         list_;
    HuffmanTreeType     root_;

    void CollectRuns(FileInputType &);
    void CreateHuffmanTree(void);
    void AssignCodeword(RunType *, const CodewordType & = 0, const SizeType & = 0);
    void CreateRunList(RunType *);
    RunType * GetRunFromList(const SymbolType &, const SizeType &);
    void WriteHeader(FileInputType &, FileOutputType &);
    void WriteEncode(FileInputType &, FileOutputType &);

    void PrintHuffmanTree(FILE *, const RunType *, const SizeType &);

public:
    void CompressFile(FileInputType &, const StringType &, const StringType &);

    void PrintAllRuns(FILE * = stdout);
    void PrintHuffmanTree(FILE * = stdout);
};

} /** ns: algorithm */

#endif /** ! ALGORITHM_HUFFMAN_H_ */
<commit_msg>Change type unsigned char to uint8_t<commit_after>#ifndef ALGORITHM_HUFFMAN_H_
#define ALGORITHM_HUFFMAN_H_ 1

#include <vector>
#include <string>
#include <functional>

namespace algorithm
{

class Huffman
{
public:
    typedef uint8_t         SymbolType;
    typedef size_t          SizeType;
    typedef unsigned int    CodewordType;
    typedef std::string     StringType;
    typedef std::ifstream   FileInputType;
    typedef std::ofstream   FileOutputType;
    typedef uint32_t        EncodeBufferType;

    typedef std::pair<SymbolType, SizeType> MetaSymbolType;

    struct Run
    {
        SymbolType      symbol;
        SizeType        run_len;
        SizeType        freq;

        Run *           left;
        Run *           right;

        CodewordType    codeword;
        SizeType        codeword_len;

        Run *           next;

        Run(const SymbolType & symbol, const SizeType & run_len, const SizeType & freq = 0)
        : symbol        (symbol)
        , run_len       (run_len)
        , freq          (freq)
        , left          (nullptr)
        , right         (nullptr)
        , codeword      (0)
        , codeword_len  (0)
        , next          (nullptr)
        { }

        Run(const MetaSymbolType & meta_symbol, const SizeType & freq = 0)
        : symbol        (meta_symbol.first)
        , run_len       (meta_symbol.second)
        , freq          (freq)
        , left          (nullptr)
        , right         (nullptr)
        , codeword      (0)
        , codeword_len  (0)
        , next          (nullptr)
        { }

        Run(const Run & run)
        : symbol        (run.symbol)
        , run_len       (run.run_len)
        , freq          (run.freq)
        , left          (run.left)
        , right         (run.right)
        , codeword      (run.codeword)
        , codeword_len  (run.codeword_len)
        , next          (run.next)
        { }

        Run(Run * left, Run * right)
        : symbol        (0)
        , run_len       (0)
        , freq          (left->freq + right->freq)
        , left          (left)
        , right         (right)
        , codeword      (0)
        , codeword_len  (0)
        , next          (nullptr)
        { }

        inline
        Run &
        operator=(Run run)
        {
            this->symbol        = run.symbol;
            this->run_len       = run.run_len;
            this->freq          = run.freq;
            this->left          = run.left;
            this->right         = run.right;
            this->codeword      = run.codeword;
            this->codeword_len  = run.codeword_len;
            this->next          = run.next;

            return *this;
        }

        inline
        bool
        operator==(const Run & rhs)
        const
        { return symbol == rhs.symbol && run_len == rhs.run_len; }

        inline
        bool
        operator!=(const Run & rhs)
        const
        { return ! (*this == rhs); }

        inline
        Run &
        operator++(void)
        {
            ++freq;
            return *this;
        }

        inline
        Run
        operator++(int)
        {
            Run temp(*this);
            operator++();
            return temp;
        }

        inline
        Run &
        operator--(void)
        {
            --freq;
            return *this;
        }

        inline
        Run
        operator--(int)
        {
            Run temp(*this);
            operator--();
            return temp;
        }

        inline
        bool
        operator<(const Run & rhs)
        const
        { return (this->freq < rhs.freq); }

        inline
        bool
        operator>(const Run & rhs)
        const
        { return (this->freq > rhs.freq); }

        inline
        bool
        operator<=(const Run & rhs)
        const
        { return ! operator>(rhs); }

        inline
        bool
        operator>=(const Run & rhs)
        const
        { return ! operator<(rhs); }
    };

    typedef Run     RunType;

    typedef std::vector<RunType>                        RunArrayType;
    typedef std::array<RunType *, sizeof(SymbolType)>   RunListType;
    typedef RunType *                                   HuffmanTreeType;

private:
    RunArrayType        runs_;
    RunListType         list_;
    HuffmanTreeType     root_;

    void CollectRuns(FileInputType &);
    void CreateHuffmanTree(void);
    void AssignCodeword(RunType *, const CodewordType & = 0, const SizeType & = 0);
    void CreateRunList(RunType *);
    RunType * GetRunFromList(const SymbolType &, const SizeType &);
    void WriteHeader(FileInputType &, FileOutputType &);
    void WriteEncode(FileInputType &, FileOutputType &);

    void PrintHuffmanTree(FILE *, const RunType *, const SizeType &);

public:
    void CompressFile(FileInputType &, const StringType &, const StringType &);

    void PrintAllRuns(FILE * = stdout);
    void PrintHuffmanTree(FILE * = stdout);
};

} /** ns: algorithm */

#endif /** ! ALGORITHM_HUFFMAN_H_ */
<|endoftext|>


<commit_before>/*
 *  Empar.cpp
 *
 *  Created by Ania M. Kedzierska on 11/11/11.
 *  Copyright 2011 Politecnic University of Catalonia, Center for Genomic Regulation.  This is program can be redistributed, modified or else as given by the terms of the GNU General Public License.
 *
 */

#include <iostream>
#include <cstdlib>
#include <fstream>
#include <ctime>
#include <cmath>
#include <list>
#include <string>
#include <stdexcept>

#include "Empar.h"
#include "em.h"
#include "tree.h"
#include "parameters.h"
#include "alignment.h"
#include "model.h"
#include "sampling.h"
#include "miscelania.h"
#include "random.h"
#include "fisher.h"
#include "permutation.h"

// Prints an informative warning if the tree is nonidentifiable.
bool nonident_warning(Tree &T) {
  std::list<long> Lnon;
  std::list<long>::iterator it;
  std::list<long>::iterator itlast;

  for(long i = 0; i < T.nnodes; i++) {
    // Any node (root or not) with valence 2 leads to nonident.
    if(valence(T, i) == 2) {
      Lnon.push_back(i);
    }

    // A root of valence 1 leads to nonident.
    if(valence(T, i) == 1 && i == T.nleaves) {
      Lnon.push_back(i);
    }
  }

  if (Lnon.size() > 0) {
    std::cout << "WARNING: The following nodes lead to non-identifiability of the parameters: ";
    itlast = Lnon.end();
    --itlast;
    for(it=Lnon.begin(); it != Lnon.end(); it++) {
      std::cout << *it;
      if (it != itlast) {     // if not the last element
        std::cout << ", ";
      }
    }
    std::cout << "." << std::endl << std::endl;

    std::cout << "This may happen for two reasons:" << std::endl;
    std::cout << " 1) The root has valence 1. If the model has non-uniform distribution, the length of the outgoing edge cannot be recovered reliably." << std::endl;
    std::cout << " 2) There is a node (typically thought of as the root) with exactly two incident edges. In this case only the sum of lengths of the two incident edges can be recovered reliably." << std::endl << std::endl;
  }

  return Lnon.size() > 0;
}

void run(std::string tree_filename, std::string fasta_filename, std::string model_name) {
  Model Mod;                 // The model
  Counts data;               // the counts
  Parameters Par;            // the parameters
  std::vector<double> br;    // branch lengths
  double eps = 1e-8;         // The threshold for the EM algorithm.

  Parameters Parsim;         // used for simulating data.
  std::vector<double> brsim; // branch lengths of simulated data.

  std::vector<std::vector<double> > Cov;  // Covariance matrix
  std::vector<double> variances;          // The variances

  bool simulate;
  bool nonident;
  std::string parameters_filename;
  std::string covariances_filename;

  // initialize random number generator with time(0).
  random_initialize();

  parameters_filename = strip_extension(fasta_filename) + ".dat";
  covariances_filename = strip_extension(fasta_filename) + ".cov";

  // Creates the pointers to the model-specific functions.
  Mod = create_model(model_name);
  std::cout << "Model: " << Mod.name << std::endl;

  // Reads the tree.
  Tree T = read_tree(tree_filename);

  // Prints the Tree
  std::cout << "Tree:" << std::endl;
  print_tree(T);

  // Check for possible nonidentifiability issues.
  nonident = nonident_warning(T);

  // Initialize the parameters for simulation of K81 data for testing
  Parsim = create_parameters(T);

  if (fasta_filename == ":test") {      // if fasta file is :test generate random data.
    simulate = true;

    // Warn
    std::cout << "WARNING: Using simulated data " << std::endl << std::endl;

    // Generate random parameters
    random_parameters_length(T, Mod, Parsim);

    // Simulate the data
    random_fake_counts(T, 1000, data, Parsim);

    // Prints branch-lengths for future check.
    branch_lengths(Parsim, brsim);
    std::cout << "Simulated branch lengths:" << std::endl;
    print_vector(brsim);

  } else {                                  // otherwise read the data
    simulate = false;

    // Read the counts.
    std::cout << "Reading fasta file:" << std::endl;
    read_counts(T, data, fasta_filename);
    add_pseudocounts(0.01, data);
    std::cout << std::endl;
  }

  // Check whether the data and the tree match.
  if (T.nalpha != data.nalpha || T.nleaves != data.nspecies) {
    throw std::invalid_argument("The order of the sequences or their number and the phylogenetic tree do not match.");
  }

  Par = create_parameters(T);

  clock_t start_time, end_time;
  start_time = clock();
  std::cout << "Starting the EM algorithm" << std::endl;

  // Runs the EM algorithm. Par is used as initial parameters.
  // After execution, Par contains the MLE computed by the algorithm.
  EMalgorithm(T, Mod, Par, data, eps);

  // Choses the best permutation.
  guess_permutation(T, Mod, Par);

  end_time = clock();

  branch_lengths(Par, br);

  // If parameters are not identifiable, the computation of the covariance matrix will
  // fail as the Fisher info matrix will not be invertible.
  if (!nonident) {
    // Compute the covariance matrix using observed Fisher.
    full_MLE_observed_covariance_matrix(T, Mod, Par, data, Cov);
    variances.resize(Cov.size());
    for(unsigned int i=0; i < Cov.size(); i++) {
      variances[i] = Cov[i][i];
    }

    // Save the sigmas into a file
    std::fstream fcov;
    fcov.precision(15);
    fcov.open(covariances_filename.c_str(), std::ios::out);
    if (!fcov.is_open()) {
      std::cout << "Could not open file: covariances.dat" << std::endl;
    }
    for(unsigned int i=0; i < Cov.size(); i++) {
      for(unsigned int j=0; j < Cov.size(); j++) {
        fcov << Cov[i][j] << " ";
      }
      fcov << std::endl;
    }
    fcov << std::endl;
    fcov.close();
  }

  std::cout << std::endl;
  std::cout << "Finished." << std::endl;
  std::cout << "Elapsed time: " << ((double)(end_time - start_time)) / CLOCKS_PER_SEC << " s" << std::endl;
  std::cout << std::endl;
  std::cout << "Likelihood: " << log_likelihood(T, Par, data) << std::endl << std::endl;
  std::cout << "Branch lengths: " << std::endl;
  print_vector(br);

  if (!nonident) {
    std::cout << "Parameter variances: " << std::endl;
    print_vector(variances);
  }

  std::cout << "Newick Tree:" << std::endl;
  print_newick_tree(T, br);

  // if is a simulation, print the L2 distance !
  if (simulate) {
    std::cout << "L2 distance:   " << parameters_distance(Par, Parsim) << std::endl;
    std::cout << "KL divergence: " << KL_divergence(T, Par, Parsim) << std::endl;
    std::cout << std::endl;
  }

  // if it is not a simulation, store the parameters in a file !
  if (!simulate) {
    std::fstream st;
    st.precision(15);
    st.setf(std::ios::fixed,std::ios::floatfield);
    st.open(parameters_filename.c_str(), std::ios::out);
    print_parameters(Par, st);
  }
}
<commit_msg>Extract some code to separate function<commit_after>/*
 *  Empar.cpp
 *
 *  Created by Ania M. Kedzierska on 11/11/11.
 *  Copyright 2011 Politecnic University of Catalonia, Center for Genomic Regulation.  This is program can be redistributed, modified or else as given by the terms of the GNU General Public License.
 *
 */

#include <iostream>
#include <cstdlib>
#include <fstream>
#include <ctime>
#include <cmath>
#include <list>
#include <string>
#include <stdexcept>

#include "Empar.h"
#include "em.h"
#include "tree.h"
#include "parameters.h"
#include "alignment.h"
#include "model.h"
#include "sampling.h"
#include "miscelania.h"
#include "random.h"
#include "fisher.h"
#include "permutation.h"

// Prints an informative warning if the tree is nonidentifiable.
bool nonident_warning(Tree &T) {
  std::list<long> Lnon;
  std::list<long>::iterator it;
  std::list<long>::iterator itlast;

  for(long i = 0; i < T.nnodes; i++) {
    // Any node (root or not) with valence 2 leads to nonident.
    if(valence(T, i) == 2) {
      Lnon.push_back(i);
    }

    // A root of valence 1 leads to nonident.
    if(valence(T, i) == 1 && i == T.nleaves) {
      Lnon.push_back(i);
    }
  }

  if (Lnon.size() > 0) {
    std::cout << "WARNING: The following nodes lead to non-identifiability of the parameters: ";
    itlast = Lnon.end();
    --itlast;
    for(it=Lnon.begin(); it != Lnon.end(); it++) {
      std::cout << *it;
      if (it != itlast) {     // if not the last element
        std::cout << ", ";
      }
    }
    std::cout << "." << std::endl << std::endl;

    std::cout << "This may happen for two reasons:" << std::endl;
    std::cout << " 1) The root has valence 1. If the model has non-uniform distribution, the length of the outgoing edge cannot be recovered reliably." << std::endl;
    std::cout << " 2) There is a node (typically thought of as the root) with exactly two incident edges. In this case only the sum of lengths of the two incident edges can be recovered reliably." << std::endl << std::endl;
  }

  return Lnon.size() > 0;
}

void save_sigmas_to(const std::string& fname,
	const std::vector<std::vector<double> >& cov_matrix)
{
    std::fstream fcov;
    fcov.precision(15);
    fcov.open(fname.c_str(), std::ios::out);
    if (!fcov.is_open()) {
      std::cout << "Could not open file: covariances.dat" << std::endl;
      // TODO: exit
    }

    for(unsigned int i=0; i < cov_matrix.size(); i++) {
      for(unsigned int j=0; j < cov_matrix.size(); j++) {
        fcov << cov_matrix[i][j] << " ";
      }
      fcov << std::endl;
    }
    fcov << std::endl;

    fcov.close();
}

void run(std::string tree_filename, std::string fasta_filename, std::string model_name) {
  Model Mod;                 // The model
  Counts data;               // the counts
  Parameters Par;            // the parameters
  std::vector<double> br;    // branch lengths
  double eps = 1e-8;         // The threshold for the EM algorithm.

  Parameters Parsim;         // used for simulating data.
  std::vector<double> brsim; // branch lengths of simulated data.

  std::vector<std::vector<double> > Cov;  // Covariance matrix
  std::vector<double> variances;          // The variances

  bool simulate;
  bool nonident;
  std::string parameters_filename;
  std::string covariances_filename;

  // initialize random number generator with time(0).
  random_initialize();

  parameters_filename = strip_extension(fasta_filename) + ".dat";
  covariances_filename = strip_extension(fasta_filename) + ".cov";

  // Creates the pointers to the model-specific functions.
  Mod = create_model(model_name);
  std::cout << "Model: " << Mod.name << std::endl;

  // Reads the tree.
  Tree T = read_tree(tree_filename);

  // Prints the Tree
  std::cout << "Tree:" << std::endl;
  print_tree(T);

  // Check for possible nonidentifiability issues.
  nonident = nonident_warning(T);

  // Initialize the parameters for simulation of K81 data for testing
  Parsim = create_parameters(T);

  if (fasta_filename == ":test") {      // if fasta file is :test generate random data.
    simulate = true;

    // Warn
    std::cout << "WARNING: Using simulated data " << std::endl << std::endl;

    // Generate random parameters
    random_parameters_length(T, Mod, Parsim);

    // Simulate the data
    random_fake_counts(T, 1000, data, Parsim);

    // Prints branch-lengths for future check.
    branch_lengths(Parsim, brsim);
    std::cout << "Simulated branch lengths:" << std::endl;
    print_vector(brsim);

  } else {                                  // otherwise read the data
    simulate = false;

    // Read the counts.
    std::cout << "Reading fasta file:" << std::endl;
    read_counts(T, data, fasta_filename);
    add_pseudocounts(0.01, data);
    std::cout << std::endl;
  }

  // Check whether the data and the tree match.
  if (T.nalpha != data.nalpha || T.nleaves != data.nspecies) {
    throw std::invalid_argument("The order of the sequences or their number and the phylogenetic tree do not match.");
  }

  Par = create_parameters(T);

  clock_t start_time, end_time;
  start_time = clock();
  std::cout << "Starting the EM algorithm" << std::endl;

  // Runs the EM algorithm. Par is used as initial parameters.
  // After execution, Par contains the MLE computed by the algorithm.
  EMalgorithm(T, Mod, Par, data, eps);

  // Choses the best permutation.
  guess_permutation(T, Mod, Par);

  end_time = clock();

  branch_lengths(Par, br);

  // If parameters are not identifiable, the computation of the covariance matrix will
  // fail as the Fisher info matrix will not be invertible.
  if (!nonident) {
    // Compute the covariance matrix using observed Fisher.
    full_MLE_observed_covariance_matrix(T, Mod, Par, data, Cov);
    variances.resize(Cov.size());
    for(unsigned int i=0; i < Cov.size(); i++) {
      variances[i] = Cov[i][i];
    }

    // Save the sigmas into a file
    save_sigmas_to(covariances_filename, Cov);
  }

  std::cout << std::endl;
  std::cout << "Finished." << std::endl;
  std::cout << "Elapsed time: " << ((double)(end_time - start_time)) / CLOCKS_PER_SEC << " s" << std::endl;
  std::cout << std::endl;
  std::cout << "Likelihood: " << log_likelihood(T, Par, data) << std::endl << std::endl;
  std::cout << "Branch lengths: " << std::endl;
  print_vector(br);

  if (!nonident) {
    std::cout << "Parameter variances: " << std::endl;
    print_vector(variances);
  }

  std::cout << "Newick Tree:" << std::endl;
  print_newick_tree(T, br);

  // if is a simulation, print the L2 distance !
  if (simulate) {
    std::cout << "L2 distance:   " << parameters_distance(Par, Parsim) << std::endl;
    std::cout << "KL divergence: " << KL_divergence(T, Par, Parsim) << std::endl;
    std::cout << std::endl;
  }

  // if it is not a simulation, store the parameters in a file !
  if (!simulate) {
    std::fstream st;
    st.precision(15);
    st.setf(std::ios::fixed,std::ios::floatfield);
    st.open(parameters_filename.c_str(), std::ios::out);
    print_parameters(Par, st);
  }
}
<|endoftext|>


<commit_before>//
// Copyright (C) 2014
// Alessio Sclocco <a.sclocco@vu.nl>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#include <iostream>
using std::cout;
using std::cerr;
using std::endl;
using std::fixed;
#include <iomanip>
using std::setprecision;
#include <ctime>

#include <ArgumentList.hpp>
using isa::utils::ArgumentList;
#include <InitializeOpenCL.hpp>
using isa::OpenCL::initializeOpenCL;
#include <CLData.hpp>
using isa::OpenCL::CLData;
#include <Exceptions.hpp>
using isa::Exceptions::OpenCLError;
#include <Flops.hpp>
using isa::Benchmarks::Flops;
#include <utils.hpp>
using isa::utils::same;

const unsigned int nrIterations = 10;

int main(int argc, char * argv[]) {
	unsigned int oclPlatform = 0;
	unsigned int oclDevice = 0;
	unsigned int arrayDim = 0;
	unsigned int nrLoops = 0;
	unsigned int minThreads = 0;
	unsigned int maxThreads = 0;

	// Parse command line
	if ( argc != 11 ) {
		cerr << "Usage: " << argv[0] << " -opencl_platform <opencl_platform> -opencl_device <opencl_device> -loops <nr_loops> -min <min_threads> -max <max_threads>" << endl;
		return 1;
	}

	ArgumentList commandLine(argc, argv);
	try {
		oclPlatform = commandLine.getSwitchArgument< unsigned int >("-opencl_platform");
		oclDevice = commandLine.getSwitchArgument< unsigned int >("-opencl_device");
		nrLoops = commandLine.getSwitchArgument< unsigned int >("-loops");
		minThreads = commandLine.getSwitchArgument< unsigned int >("-min");
		maxThreads = commandLine.getSwitchArgument< unsigned int >("-max");
	} catch ( exception & err ) {
		cerr << err.what() << endl;
		return 1;
	}

	// Initialize OpenCL
	vector< cl::Platform > * oclPlatforms = new vector< cl::Platform >();
	cl::Context * oclContext = new cl::Context();
	vector< cl::Device > * oclDevices = new vector< cl::Device >();
	vector< vector< cl::CommandQueue > > * oclQueues = new vector< vector< cl::CommandQueue > >();
	try {
		initializeOpenCL(oclPlatform, 1, oclPlatforms, oclContext, oclDevices, oclQueues);
	} catch ( OpenCLError &err ) {
		cerr << err.what() << endl;
		return 1;
	}
	arrayDim = (oclDevices->at(oclDevice)).getInfo< CL_DEVICE_MAX_MEM_ALLOC_SIZE >();
	arrayDim /= sizeof(float);

	CLData< float > * A = new CLData< float >("A", true);
	CLData< float > * C = new CLData< float >("C", true);

	A->setCLContext(oclContext);
	A->setCLQueue(&(oclQueues->at(oclDevice)[0]));
	A->allocateHostData(arrayDim);
	srand(time(NULL));
	for ( unsigned int i = 0; i < arrayDim; i++ ) {
		A->setHostDataItem(i, 1.0f / static_cast< float >(rand() % 15));
	}
	C->setCLContext(oclContext);
	C->setCLQueue(&(oclQueues->at(oclDevice)[0]));
	C->allocateHostData(arrayDim);
	try {
		A->setDeviceReadOnly();
		A->allocateDeviceData();
		A->copyHostToDevice();
		C->setDeviceWriteOnly();
		C->allocateDeviceData();
	} catch ( OpenCLError &err ) {
		cerr << err.what() << endl;
		return 1;
	}

	cout << fixed;
	cout << arrayDim << endl;
	for (unsigned int threads0 = minThreads; threads0 <= maxThreads; threads0 *= 2 ) {
		for (unsigned int threads1 = 1; threads1 <= 32; threads1++ ) {
			if ( (arrayDim % (threads0 * threads1) != 0) || ((threads0 * threads1) > maxThreads) ) {
				continue;
			}

			Flops< float > flops = Flops< float >("float");
			try {
				flops.bindOpenCL(oclContext, &(oclDevices->at(oclDevice)), &(oclQueues->at(oclDevice)[0]));
				flops.setNrThreads(arrayDim);
				flops.setNrThreadsPerBlock(threads0);
				flops.setNrRows(threads1);
				flops.setNrIterations(nrLoops);
				flops.generateCode();

				flops(A, C);
				flops.reset();
				for ( unsigned int iter = 0; iter < nrIterations; iter++ ) {
					flops(A, C);
				}
			} catch ( OpenCLError &err ) {
				cerr << err.what() << endl;
				return 1;
			}

			cout << threads0 << " " << threads1 << " " << setprecision(3) << flops.getGFLOPs() << " " << setprecision(6) << flops.getTimer().getAverageTime() << endl;

		}
	}
	cout << endl;

	return 0;
}
<commit_msg>There was a spurious print.<commit_after>//
// Copyright (C) 2014
// Alessio Sclocco <a.sclocco@vu.nl>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#include <iostream>
using std::cout;
using std::cerr;
using std::endl;
using std::fixed;
#include <iomanip>
using std::setprecision;
#include <ctime>

#include <ArgumentList.hpp>
using isa::utils::ArgumentList;
#include <InitializeOpenCL.hpp>
using isa::OpenCL::initializeOpenCL;
#include <CLData.hpp>
using isa::OpenCL::CLData;
#include <Exceptions.hpp>
using isa::Exceptions::OpenCLError;
#include <Flops.hpp>
using isa::Benchmarks::Flops;
#include <utils.hpp>
using isa::utils::same;

const unsigned int nrIterations = 10;

int main(int argc, char * argv[]) {
	unsigned int oclPlatform = 0;
	unsigned int oclDevice = 0;
	unsigned int arrayDim = 0;
	unsigned int nrLoops = 0;
	unsigned int minThreads = 0;
	unsigned int maxThreads = 0;

	// Parse command line
	if ( argc != 11 ) {
		cerr << "Usage: " << argv[0] << " -opencl_platform <opencl_platform> -opencl_device <opencl_device> -loops <nr_loops> -min <min_threads> -max <max_threads>" << endl;
		return 1;
	}

	ArgumentList commandLine(argc, argv);
	try {
		oclPlatform = commandLine.getSwitchArgument< unsigned int >("-opencl_platform");
		oclDevice = commandLine.getSwitchArgument< unsigned int >("-opencl_device");
		nrLoops = commandLine.getSwitchArgument< unsigned int >("-loops");
		minThreads = commandLine.getSwitchArgument< unsigned int >("-min");
		maxThreads = commandLine.getSwitchArgument< unsigned int >("-max");
	} catch ( exception & err ) {
		cerr << err.what() << endl;
		return 1;
	}

	// Initialize OpenCL
	vector< cl::Platform > * oclPlatforms = new vector< cl::Platform >();
	cl::Context * oclContext = new cl::Context();
	vector< cl::Device > * oclDevices = new vector< cl::Device >();
	vector< vector< cl::CommandQueue > > * oclQueues = new vector< vector< cl::CommandQueue > >();
	try {
		initializeOpenCL(oclPlatform, 1, oclPlatforms, oclContext, oclDevices, oclQueues);
	} catch ( OpenCLError &err ) {
		cerr << err.what() << endl;
		return 1;
	}
	arrayDim = (oclDevices->at(oclDevice)).getInfo< CL_DEVICE_MAX_MEM_ALLOC_SIZE >();
	arrayDim /= sizeof(float);

	CLData< float > * A = new CLData< float >("A", true);
	CLData< float > * C = new CLData< float >("C", true);

	A->setCLContext(oclContext);
	A->setCLQueue(&(oclQueues->at(oclDevice)[0]));
	A->allocateHostData(arrayDim);
	srand(time(NULL));
	for ( unsigned int i = 0; i < arrayDim; i++ ) {
		A->setHostDataItem(i, 1.0f / static_cast< float >(rand() % 15));
	}
	C->setCLContext(oclContext);
	C->setCLQueue(&(oclQueues->at(oclDevice)[0]));
	C->allocateHostData(arrayDim);
	try {
		A->setDeviceReadOnly();
		A->allocateDeviceData();
		A->copyHostToDevice();
		C->setDeviceWriteOnly();
		C->allocateDeviceData();
	} catch ( OpenCLError &err ) {
		cerr << err.what() << endl;
		return 1;
	}

	cout << fixed;
	for (unsigned int threads0 = minThreads; threads0 <= maxThreads; threads0 *= 2 ) {
		for (unsigned int threads1 = 1; threads1 <= 32; threads1++ ) {
			if ( (arrayDim % (threads0 * threads1) != 0) || ((threads0 * threads1) > maxThreads) ) {
				continue;
			}

			Flops< float > flops = Flops< float >("float");
			try {
				flops.bindOpenCL(oclContext, &(oclDevices->at(oclDevice)), &(oclQueues->at(oclDevice)[0]));
				flops.setNrThreads(arrayDim);
				flops.setNrThreadsPerBlock(threads0);
				flops.setNrRows(threads1);
				flops.setNrIterations(nrLoops);
				flops.generateCode();

				flops(A, C);
				flops.reset();
				for ( unsigned int iter = 0; iter < nrIterations; iter++ ) {
					flops(A, C);
				}
			} catch ( OpenCLError &err ) {
				cerr << err.what() << endl;
				return 1;
			}

			cout << threads0 << " " << threads1 << " " << setprecision(3) << flops.getGFLOPs() << " " << setprecision(6) << flops.getTimer().getAverageTime() << endl;

		}
	}
	cout << endl;

	return 0;
}
<|endoftext|>


<commit_before>#include <reversed.hpp>

#include <vector>
#include <array>
#include <string>
#include <utility>

#include "helpers.hpp"
#include "catch.hpp"

using iter::reversed;
using Vec = const std::vector<int>;

TEST_CASE("reversed: can reverse a vector", "[reversed]") {
    Vec ns = {10, 20, 30, 40};
    auto r = reversed(ns);

    Vec v(std::begin(r), std::end(r));
    Vec vc = {40, 30, 20, 10};

    REQUIRE( v == vc );
}

TEST_CASE("reversed: can reverse an array", "[reversed]") {
    int ns[] = {10, 20, 30, 40};
    auto r = reversed(ns);

    Vec v(std::begin(r), std::end(r));
    Vec vc = {40, 30, 20, 10};

    REQUIRE( v == vc );
}

TEST_CASE("reversed: empty when iterable is empty", "[reversed]") {
    Vec emp{};
    auto r = reversed(emp);
    REQUIRE( std::begin(r) == std::end(r) );
}

TEST_CASE("reversed: moves rvalues and binds to lvalues", "[reversed]") {
    itertest::BasicIterable<int> bi{1, 2};
    itertest::BasicIterable<int> bi2{1, 2};
    reversed(bi);
    REQUIRE_FALSE( bi.was_moved_from() );

    reversed(std::move(bi2));
    REQUIRE( bi2.was_moved_from() );
}

TEST_CASE("reversed: doesn't move or copy elements of array", "[reversed]") {
    constexpr itertest::SolidInt arr[] = {{6}, {7}, {8}};
    for (auto&& i : reversed(arr)) {
        (void)i;
    }
}

TEST_CASE("reversed: with iterable doesn't move or copy elems", "[reversed]") {
    constexpr std::array<itertest::SolidInt, 3> arr{{{6}, {7}, {8}}};
    for (auto&& i : reversed(arr)) {
        (void)i;
    }
}

TEST_CASE("reversed: iterator meets requirements", "[reversed]") {
    Vec v;
    auto r = reversed(v);
    REQUIRE( itertest::IsIterator<decltype(std::begin(r))>::value );
}
<commit_msg>tests reversed iterator with array<commit_after>#include <reversed.hpp>

#include <vector>
#include <array>
#include <string>
#include <utility>

#include "helpers.hpp"
#include "catch.hpp"

using iter::reversed;
using Vec = const std::vector<int>;

TEST_CASE("reversed: can reverse a vector", "[reversed]") {
    Vec ns = {10, 20, 30, 40};
    auto r = reversed(ns);

    Vec v(std::begin(r), std::end(r));
    Vec vc = {40, 30, 20, 10};

    REQUIRE( v == vc );
}

TEST_CASE("reversed: can reverse an array", "[reversed]") {
    int ns[] = {10, 20, 30, 40};
    auto r = reversed(ns);

    Vec v(std::begin(r), std::end(r));
    Vec vc = {40, 30, 20, 10};

    REQUIRE( v == vc );
}

TEST_CASE("reversed: empty when iterable is empty", "[reversed]") {
    Vec emp{};
    auto r = reversed(emp);
    REQUIRE( std::begin(r) == std::end(r) );
}

TEST_CASE("reversed: moves rvalues and binds to lvalues", "[reversed]") {
    itertest::BasicIterable<int> bi{1, 2};
    itertest::BasicIterable<int> bi2{1, 2};
    reversed(bi);
    REQUIRE_FALSE( bi.was_moved_from() );

    reversed(std::move(bi2));
    REQUIRE( bi2.was_moved_from() );
}

TEST_CASE("reversed: doesn't move or copy elements of array", "[reversed]") {
    constexpr itertest::SolidInt arr[] = {{6}, {7}, {8}};
    for (auto&& i : reversed(arr)) {
        (void)i;
    }
}

TEST_CASE("reversed: with iterable doesn't move or copy elems", "[reversed]") {
    constexpr std::array<itertest::SolidInt, 3> arr{{{6}, {7}, {8}}};
    for (auto&& i : reversed(arr)) {
        (void)i;
    }
}

TEST_CASE("reversed: iterator meets requirements", "[reversed]") {
    Vec v;
    auto r = reversed(v);
    REQUIRE( itertest::IsIterator<decltype(std::begin(r))>::value );

    int a[1];
    auto ra = reversed(a);
    REQUIRE( itertest::IsIterator<decltype(std::begin(ra))>::value );
}
<|endoftext|>