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

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you under
the Apache License, Version 2.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

*******************************************************************************/

//==============================================================================
// Standard file manager
//==============================================================================

#include "corecliutils.h"
#include "filemanager.h"
#include "standardfilemanager.h"
#include "standardsupportplugin.h"

//==============================================================================

namespace OpenCOR {
namespace StandardSupport {

//==============================================================================

StandardFileManager::StandardFileManager() :
    mFiles(Files())
{
    // Create some connections to keep track of some events related to our
    // 'global' file manager

    Core::FileManager *fileManagerInstance = Core::FileManager::instance();

    connect(fileManagerInstance, SIGNAL(fileManaged(const QString &)),
            this, SLOT(manageFile(const QString &)));
    connect(fileManagerInstance, SIGNAL(fileUnmanaged(const QString &)),
            this, SLOT(unmanageFile(const QString &)));

    connect(fileManagerInstance, SIGNAL(fileReloaded(const QString &)),
            this, SLOT(reloadFile(const QString &)));

    connect(fileManagerInstance, SIGNAL(fileRenamed(const QString &, const QString &)),
            this, SLOT(renameFile(const QString &, const QString &)));
}

//==============================================================================

StandardFileManager::~StandardFileManager()
{
    // Remove all the managed files

    foreach (QObject *file, mFiles)
        delete file;
}

//==============================================================================

bool StandardFileManager::isFile(const QString &pFileName)
{
    // If the given file is already managed, then we consider that it's of the
    // right type (e.g. CellML file), even though it may not be of the right
    // anymore after having been edited and saved, but in this case it's good to
    // keep considering the file as of the right type, so that the user can
    // continue editing it without any problem, for example

    QString nativeFileName = Core::nativeCanonicalFileName(pFileName);

    if (file(nativeFileName))
        return true;

    // The given file is not managed, so check whether it's a new file and, if
    // so, consider it as of the right type

    if (Core::FileManager::instance()->isNew(nativeFileName))
        return true;

    // Check whether we are dealing with an empty file or a file that contains
    // spaces of sorts and, if not, whether we can load the file contents using
    // the standard and thus determine whether it is of the right type

    QString fileContents;

    if (Core::readTextFromFile(nativeFileName, fileContents)) {
        if (fileContents.trimmed().isEmpty())
            return true;

        return canLoadFileContents(fileContents);
    } else {
        return false;
    }
}

//==============================================================================

QObject * StandardFileManager::file(const QString &pFileName)
{
    // Return the File object, if any, associated with the given file

    return mFiles.value(Core::nativeCanonicalFileName(pFileName));
}

//==============================================================================

void StandardFileManager::manageFile(const QString &pFileName)
{
    QString nativeFileName = Core::nativeCanonicalFileName(pFileName);

    if (!file(nativeFileName) && isFile(nativeFileName)) {
        // We are dealing with a file, which is not already managed, so we can
        // add it to our list of managed files

        mFiles.insert(nativeFileName, newFile(nativeFileName));
    }
}

//==============================================================================

void StandardFileManager::unmanageFile(const QString &pFileName)
{
    QObject *crtFile = file(pFileName);

    if (crtFile) {
        // We are dealing with a file, so we can remove it from our list of
        // managed files after having deleted it

        delete crtFile;

        mFiles.remove(Core::nativeCanonicalFileName(pFileName));
    }
}

//==============================================================================

void StandardFileManager::reloadFile(const QString &pFileName)
{
    // The file is to be reloaded, so reload it
    // Note: to reload a file here ensures that our different standard-based
    //       views won't each do it, thus saving time and ensuring that a
    //       standard-based view doesn't forget to do it...

    QObject *crtFile = file(pFileName);

    if (crtFile) {
        // The file is managed, but should it still be (i.e. can it still be
        // considered as being a file)?

        if (isFile(pFileName))
            qobject_cast<StandardFile *>(crtFile)->reload();
        else
            unmanageFile(pFileName);
    } else {
        // The file is not managed, which means that previously it wasn't
        // considered as being a file, but things may be different now, so try
        // to remanage it and load it, if possible

        manageFile(pFileName);

        crtFile = file(pFileName);

        if (crtFile)
            qobject_cast<StandardFile *>(crtFile)->load();
    }
}

//==============================================================================

void StandardFileManager::renameFile(const QString &pOldFileName,
                                     const QString &pNewFileName)
{
    // The file has been renamed, so we need to update our files mapping, if
    // needed

    QObject *crtFile = file(pOldFileName);

    if (!crtFile)
        return;

    mFiles.insert(pNewFileName, crtFile);
    mFiles.remove(pOldFileName);

    // We also need to ensure that our file object has its file name updated

    qobject_cast<StandardFile *>(crtFile)->setFileName(pNewFileName);
}

//==============================================================================

}   // namespace StandardSupport
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Some minor cleaning up related to issue #721 [ci skip].<commit_after>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you under
the Apache License, Version 2.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

*******************************************************************************/

//==============================================================================
// Standard file manager
//==============================================================================

#include "corecliutils.h"
#include "filemanager.h"
#include "standardfilemanager.h"
#include "standardsupportplugin.h"

//==============================================================================

namespace OpenCOR {
namespace StandardSupport {

//==============================================================================

StandardFileManager::StandardFileManager() :
    mFiles(Files())
{
    // Create some connections to keep track of some events related to our
    // 'global' file manager

    Core::FileManager *fileManagerInstance = Core::FileManager::instance();

    connect(fileManagerInstance, SIGNAL(fileManaged(const QString &)),
            this, SLOT(manageFile(const QString &)));
    connect(fileManagerInstance, SIGNAL(fileUnmanaged(const QString &)),
            this, SLOT(unmanageFile(const QString &)));

    connect(fileManagerInstance, SIGNAL(fileReloaded(const QString &)),
            this, SLOT(reloadFile(const QString &)));

    connect(fileManagerInstance, SIGNAL(fileRenamed(const QString &, const QString &)),
            this, SLOT(renameFile(const QString &, const QString &)));
}

//==============================================================================

StandardFileManager::~StandardFileManager()
{
    // Remove all the managed files

    foreach (QObject *file, mFiles)
        delete file;
}

//==============================================================================

bool StandardFileManager::isFile(const QString &pFileName)
{
    // If the given file is already managed, then we consider that it's of the
    // right type (e.g. CellML file), even though it may not be of the right
    // anymore after having been edited and saved, but in this case it's good to
    // keep considering the file as of the right type, so that the user can
    // continue editing it without any problem, for example

    QString nativeFileName = Core::nativeCanonicalFileName(pFileName);

    if (file(nativeFileName))
        return true;

    // The given file is not managed, so check whether it's a new file and, if
    // so, consider it as of the right type

    if (Core::FileManager::instance()->isNew(nativeFileName))
        return true;

    // Check whether we are dealing with an empty file or a file that contains
    // spaces of sorts and, if not, whether we can load the file contents using
    // the standard and thus determine whether it is of the right type

    QString fileContents;

    if (Core::readTextFromFile(nativeFileName, fileContents)) {
        if (fileContents.trimmed().isEmpty())
            return true;

        return canLoadFileContents(fileContents);
    } else {
        return false;
    }
}

//==============================================================================

QObject * StandardFileManager::file(const QString &pFileName)
{
    // Return the File object, if any, associated with the given file

    return mFiles.value(Core::nativeCanonicalFileName(pFileName));
}

//==============================================================================

void StandardFileManager::manageFile(const QString &pFileName)
{
    QString nativeFileName = Core::nativeCanonicalFileName(pFileName);

    if (!file(nativeFileName) && isFile(nativeFileName)) {
        // We are dealing with a file, which is not already managed, so we can
        // add it to our list of managed files

        mFiles.insert(nativeFileName, newFile(nativeFileName));
    }
}

//==============================================================================

void StandardFileManager::unmanageFile(const QString &pFileName)
{
    QObject *crtFile = file(pFileName);

    if (crtFile) {
        // We are dealing with a file, so we can remove it from our list of
        // managed files after having deleted it

        delete crtFile;

        mFiles.remove(Core::nativeCanonicalFileName(pFileName));
    }
}

//==============================================================================

void StandardFileManager::reloadFile(const QString &pFileName)
{
    // The file is to be reloaded, so reload it
    // Note: to reload a file here ensures that our different standard-based
    //       views won't each do it, thus saving time and ensuring that a
    //       standard-based view doesn't forget to do it...

    QObject *crtFile = file(pFileName);

    if (crtFile) {
        // The file is managed, but should it still be (i.e. can it still be
        // considered as being a file)?

        if (isFile(pFileName))
            static_cast<StandardFile *>(crtFile)->reload();
        else
            unmanageFile(pFileName);
    } else {
        // The file is not managed, which means that previously it wasn't
        // considered as being a file, but things may be different now, so try
        // to remanage it and load it, if possible

        manageFile(pFileName);

        crtFile = file(pFileName);

        if (crtFile)
            static_cast<StandardFile *>(crtFile)->load();
    }
}

//==============================================================================

void StandardFileManager::renameFile(const QString &pOldFileName,
                                     const QString &pNewFileName)
{
    // The file has been renamed, so we need to update our files mapping, if
    // needed

    QObject *crtFile = file(pOldFileName);

    if (!crtFile)
        return;

    mFiles.insert(pNewFileName, crtFile);
    mFiles.remove(pOldFileName);

    // We also need to ensure that our file object has its file name updated

    static_cast<StandardFile *>(crtFile)->setFileName(pNewFileName);
}

//==============================================================================

}   // namespace StandardSupport
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


<commit_before>/*
 * String hash map.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "strmap.hxx"
#include "pool.h"

#include <boost/intrusive/set.hpp>

#include <assert.h>
#include <string.h>

struct strmap {
    struct Item : strmap_pair {
        typedef boost::intrusive::set_member_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> Hook;
        Hook hook;

        Item(const char *_key, const char *_value)
            :strmap_pair(_key, _value) {}

        struct Compare {
            gcc_pure
            bool operator()(const char *a, const Item &b) const {
                return strcmp(a, b.key) < 0;
            }

            gcc_pure
            bool operator()(const Item &a, const char *b) const {
                return strcmp(a.key, b) < 0;
            }

            gcc_pure
            bool operator()(const Item &a, const Item &b) const {
                return strcmp(a.key, b.key) < 0;
            }
        };
    };

    struct pool &pool;

    typedef boost::intrusive::multiset<Item,
                                       boost::intrusive::member_hook<Item, Item::Hook, &Item::hook>,
                                       boost::intrusive::compare<Item::Compare>,
                                       boost::intrusive::constant_time_size<false>> Map;
    Map map;

    mutable Map::const_iterator cursor;

    explicit strmap(struct pool &_pool):pool(_pool) {}

    strmap(const strmap &) = delete;

    void Add(const char *key, const char *value) {
        Item *item = NewFromPool<Item>(&pool, key, value);
        map.insert(*item);
    }

    const char *Set(const char *key, const char *value) {
        const Item item(key, value);
        auto i = map.find(item);
        if (i != map.end()) {
            const char *old_value = i->value;
            i->value = value;
            return old_value;
        } else {
            map.insert(*NewFromPool<Item>(&pool, item));
            return nullptr;
        }
    }

    const char *Remove(const char *key) {
        auto i = map.find(key, Item::Compare());
        if (i == map.end())
            return nullptr;

        Item *found = &*i;
        map.erase(i);

        const char *value = found->value;
        DeleteFromPool(&pool, found);
        return value;
    }

    const char *Get(const char *key) const {
        auto i = map.find(key, Item::Compare());
        if (i == map.end())
            return nullptr;

        return i->value;
    }

    const struct strmap_pair *LookupFirst(const char *key) const {
        auto i = map.find(key, Item::Compare());
        if (i == map.end())
            return nullptr;

        return &*i;
    }

    const struct strmap_pair *LookupNext(const struct strmap_pair *pair) const {
        const Item &item = *(const Item *)pair;
        const auto i = std::next(map.iterator_to(item));
        return i != map.end() && strcmp(i->key, pair->key) == 0
            ? &*i
            : nullptr;
    }
};

struct strmap *
strmap_new(struct pool *pool, gcc_unused unsigned capacity)
{
    return NewFromPool<struct strmap>(pool, *pool);
}

struct strmap *gcc_malloc
strmap_dup(struct pool *pool, struct strmap *src, unsigned capacity)
{
    struct strmap *dest = strmap_new(pool, capacity);
    const struct strmap_pair *pair;

    strmap_rewind(src);
    while ((pair = strmap_next(src)) != nullptr)
        strmap_add(dest, p_strdup(pool, pair->key),
                   p_strdup(pool, pair->value));

    return dest;
}

void
strmap_add(struct strmap *map, const char *key, const char *value)
{
    map->Add(key, value);
}

const char *
strmap_set(struct strmap *map, const char *key, const char *value)
{
    return map->Set(key, value);
}

const char *
strmap_remove(struct strmap *map, const char *key)
{
    return map->Remove(key);
}

const char *
strmap_get(const struct strmap *map, const char *key)
{
    return map->Get(key);
}

const struct strmap_pair *
strmap_lookup_first(const struct strmap *map, const char *key)
{
    return map->LookupFirst(key);
}

const struct strmap_pair *
strmap_lookup_next(const struct strmap *map, const struct strmap_pair *pair)
{
    return map->LookupNext(pair);
}

void
strmap_rewind(struct strmap *map)
{
    assert(map != nullptr);

    map->cursor = map->map.begin();
}

const struct strmap_pair *
strmap_next(struct strmap *map)
{
    assert(map != nullptr);

    if (map->cursor == map->map.end())
        return nullptr;

    return &*map->cursor++;
}
<commit_msg>strmap: add copy constructor<commit_after>/*
 * String hash map.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "strmap.hxx"
#include "pool.h"

#include <boost/intrusive/set.hpp>

#include <assert.h>
#include <string.h>

struct strmap {
    struct Item : strmap_pair {
        typedef boost::intrusive::set_member_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> Hook;
        Hook hook;

        Item(const char *_key, const char *_value)
            :strmap_pair(_key, _value) {}

        struct Compare {
            gcc_pure
            bool operator()(const char *a, const Item &b) const {
                return strcmp(a, b.key) < 0;
            }

            gcc_pure
            bool operator()(const Item &a, const char *b) const {
                return strcmp(a.key, b) < 0;
            }

            gcc_pure
            bool operator()(const Item &a, const Item &b) const {
                return strcmp(a.key, b.key) < 0;
            }
        };
    };

    struct pool &pool;

    typedef boost::intrusive::multiset<Item,
                                       boost::intrusive::member_hook<Item, Item::Hook, &Item::hook>,
                                       boost::intrusive::compare<Item::Compare>,
                                       boost::intrusive::constant_time_size<false>> Map;
    Map map;

    mutable Map::const_iterator cursor;

    explicit strmap(struct pool &_pool):pool(_pool) {}

    strmap(struct pool &_pool, const strmap &src):pool(_pool) {
        const auto hint = map.end();
        for (auto &i : src.map) {
            Item *item = NewFromPool<Item>(&pool,
                                           p_strdup(&pool, i.key),
                                           p_strdup(&pool, i.value));
            map.insert(hint, *item);
        }
    }

    strmap(const strmap &) = delete;

    void Add(const char *key, const char *value) {
        Item *item = NewFromPool<Item>(&pool, key, value);
        map.insert(*item);
    }

    const char *Set(const char *key, const char *value) {
        const Item item(key, value);
        auto i = map.find(item);
        if (i != map.end()) {
            const char *old_value = i->value;
            i->value = value;
            return old_value;
        } else {
            map.insert(*NewFromPool<Item>(&pool, item));
            return nullptr;
        }
    }

    const char *Remove(const char *key) {
        auto i = map.find(key, Item::Compare());
        if (i == map.end())
            return nullptr;

        Item *found = &*i;
        map.erase(i);

        const char *value = found->value;
        DeleteFromPool(&pool, found);
        return value;
    }

    const char *Get(const char *key) const {
        auto i = map.find(key, Item::Compare());
        if (i == map.end())
            return nullptr;

        return i->value;
    }

    const struct strmap_pair *LookupFirst(const char *key) const {
        auto i = map.find(key, Item::Compare());
        if (i == map.end())
            return nullptr;

        return &*i;
    }

    const struct strmap_pair *LookupNext(const struct strmap_pair *pair) const {
        const Item &item = *(const Item *)pair;
        const auto i = std::next(map.iterator_to(item));
        return i != map.end() && strcmp(i->key, pair->key) == 0
            ? &*i
            : nullptr;
    }
};

struct strmap *
strmap_new(struct pool *pool, gcc_unused unsigned capacity)
{
    return NewFromPool<struct strmap>(pool, *pool);
}

struct strmap *gcc_malloc
strmap_dup(struct pool *pool, struct strmap *src, gcc_unused unsigned capacity)
{
    return NewFromPool<struct strmap>(pool, *pool, *src);
}

void
strmap_add(struct strmap *map, const char *key, const char *value)
{
    map->Add(key, value);
}

const char *
strmap_set(struct strmap *map, const char *key, const char *value)
{
    return map->Set(key, value);
}

const char *
strmap_remove(struct strmap *map, const char *key)
{
    return map->Remove(key);
}

const char *
strmap_get(const struct strmap *map, const char *key)
{
    return map->Get(key);
}

const struct strmap_pair *
strmap_lookup_first(const struct strmap *map, const char *key)
{
    return map->LookupFirst(key);
}

const struct strmap_pair *
strmap_lookup_next(const struct strmap *map, const struct strmap_pair *pair)
{
    return map->LookupNext(pair);
}

void
strmap_rewind(struct strmap *map)
{
    assert(map != nullptr);

    map->cursor = map->map.begin();
}

const struct strmap_pair *
strmap_next(struct strmap *map)
{
    assert(map != nullptr);

    if (map->cursor == map->map.end())
        return nullptr;

    return &*map->cursor++;
}
<|endoftext|>


<commit_before>#include "Kontroller/Client.h"

int main(int argc, char* argv[])
{
   Kontroller::Client client;

   client.setButtonCallback([](Kontroller::Button button, bool pressed)
   {
      printf("%s %s\n", Kontroller::getName(button), pressed ? "pressed" : "released");
   });

   client.setDialCallback([](Kontroller::Dial dial, float value)
   {
      printf("%s dial value: %f\n", Kontroller::getName(dial), value);
   });

   client.setSliderCallback([](Kontroller::Slider slider, float value)
   {
      printf("%s slider value: %f\n", Kontroller::getName(slider), value);
   });

   while (!client.getState().stop)
   {
      std::this_thread::sleep_for(std::chrono::milliseconds(100));
   }

   return 0;
}
<commit_msg>Use command line args for client endpoint<commit_after>#include "Kontroller/Client.h"

int main(int argc, char* argv[])
{
   const char* endpoint = argc > 1 ? argv[1] : "127.0.0.1";
   Kontroller::Client client(endpoint);

   client.setButtonCallback([](Kontroller::Button button, bool pressed)
   {
      printf("%s %s\n", Kontroller::getName(button), pressed ? "pressed" : "released");
   });

   client.setDialCallback([](Kontroller::Dial dial, float value)
   {
      printf("%s dial value: %f\n", Kontroller::getName(dial), value);
   });

   client.setSliderCallback([](Kontroller::Slider slider, float value)
   {
      printf("%s slider value: %f\n", Kontroller::getName(slider), value);
   });

   while (!client.getState().stop)
   {
      std::this_thread::sleep_for(std::chrono::milliseconds(100));
   }

   return 0;
}
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:    itkBasicArchitectureTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include <iostream>
#include "itkImage.h"
#include "itkVector.h"
#include "itkRandomImageSource.h"
#include "itkShrinkImageFilter.h"
#include "itkVTKImageWriter.h"
#include "itkRawImageWriter.h"
#include "itkVTKImageReader.h"
#include "itkCommand.h"
#include "itkOutputWindow.h"

// this class is used to send output to stdout and not the itk window
class TextOutput : public itk::OutputWindow
{
public:
  virtual void DisplayText(const char* s)
    {
      std::cout << s << std::endl;
    }
};

// The following three classes are used to support callbacks
// on the shrink filter in the pipeline that follows later
class ShowProgressObject
{
public:
  ShowProgressObject(itk::ProcessObject* o)
    {m_Process = o;}
  void ShowProgress()
    {std::cout << "Progress " << m_Process->GetProgress() << std::endl;}
  itk::ProcessObject::Pointer m_Process;
};

class StartEndEvent
{
public:
  void Start()
    {std::cout << "start event" << std::endl;}
  void End()
    {std::cout << "end event " << std::endl;}
};

class AllEvents
{
public:
  void WatchEvents(itk::LightObject *caller, unsigned long event)
    {
      const char* eventName = 0;
      switch(event)
        {
        case itk::Command::DeleteEvent:
          eventName = "DeleteEvent";
          break;
        case itk::Command::StartEvent:
          eventName = "StartEvent";
          break;
        case itk::Command::EndEvent:
          eventName = "EndEvent";
          break;
        case itk::Command::ProgressEvent:
          {
          itk::ProcessObject* obj = dynamic_cast<itk::ProcessObject*>(caller);
          std::cout << "AnyEvent Progress " << obj->GetProgress() << std::endl;
          eventName = "ProgressEvent";
          break;
          }
        case itk::Command::PickEvent:
          eventName = "PickEvent";
          break;
        case itk::Command::StartPickEvent:
          eventName = "StartPickEvent";
          break;
        case itk::Command::AbortCheckEvent:
          eventName = "AbortCheckEvent";
          break;
        case itk::Command::ExitEvent:
          eventName = "ExitEvent";
          break;
        default:
          eventName = "UserEvent";
        }
      std::cout << "Event name: " << eventName << " Id: " << event << std::endl;
    }
};

int main()
{
  // Comment the following if you want to use the itk text output window
  TextOutput::Pointer textWindPtr = TextOutput::New();
  itk::OutputWindow::SetInstance(textWindPtr);
  // Uncomment the following if you want to see each message independently
  // itk::OutputWindow::GetInstance()->PromptUserOn();

  // Test the creation of an image with native type
  //
  itk::Image<float,2>::Pointer if2 = itk::Image<float,2>::New();

  std::cout << std::endl
            << "Image dimension is " << itk::Image<float,5>::ImageDimension
            << std::endl;
  std::cout << "Image dimension is " << itk::Image<short,1>::ImageDimension
            << std::endl;

  // Begin by creating a simple pipeline. Use a scalar ss a pixel.
  //
  // Create a typedef to make the code more digestable
  typedef itk::Image<float,2> FloatImage2DType;

  // Create a source object (in this case a reader)
  itk::VTKImageReader<FloatImage2DType>::Pointer reader;
  reader = itk::VTKImageReader<FloatImage2DType>::New();
  reader->SetFileName("junkInput.vtk");

  // Create another source object (in this case a random image generator).
  // The source object is templated on the output type.
  //
  itk::RandomImageSource<FloatImage2DType>::Pointer random;
  random = itk::RandomImageSource<FloatImage2DType>::New();
  random->SetMin(0.0);
  random->SetMax(1.0);

  // Create a filter...shrink the image by an integral amount. We also
  // add some callbacks to the start, progress, and end filter execution
  // methods. The filter is templated on the input and output data types.
  //
  itk::ShrinkImageFilter<FloatImage2DType,FloatImage2DType>::Pointer shrink;
  shrink = itk::ShrinkImageFilter<FloatImage2DType,FloatImage2DType>::New();
  shrink->SetInput(random->GetOutput());
  shrink->SetShrinkFactors(2);

  // Create a command to call ShowProgress when progress event is triggered
  ShowProgressObject progressWatch(shrink);
  itk::SimpleMemberCommand<ShowProgressObject>::Pointer command;
  command = itk::SimpleMemberCommand<ShowProgressObject>::New();
  command->SetCallbackFunction(&progressWatch,
                               &ShowProgressObject::ShowProgress);
  shrink->AddObserver(itk::Command::ProgressEvent, command);

  // Create a command to call StartEndEvent when start event is triggered
  StartEndEvent startEndWatch;
  itk::SimpleMemberCommand<StartEndEvent>::Pointer start;
  start = itk::SimpleMemberCommand<StartEndEvent>::New();
  start->SetCallbackFunction(&startEndWatch, &StartEndEvent::Start);
  shrink->AddObserver(itk::Command::StartEvent, start);

  // Create a command to call StartEndEvent when end event is triggered
  itk::SimpleMemberCommand<StartEndEvent>::Pointer end;
  end = itk::SimpleMemberCommand<StartEndEvent>::New();
  end->SetCallbackFunction(&startEndWatch, &StartEndEvent::End);
  shrink->AddObserver(itk::Command::EndEvent, end);

  // Create a command that to call AnyEvent when event is fired
  AllEvents allWatch;
  itk::MemberCommand<AllEvents>::Pointer allEvents;
  allEvents = itk::MemberCommand<AllEvents>::New();
  allEvents->SetCallbackFunction(&allWatch,
                                 &AllEvents::WatchEvents);
  shrink->AddObserver(itk::Command::AnyEvent, allEvents);

  // Create a mapper (in this case a writer). A mapper
  // is templated on the input type.
  //
  itk::VTKImageWriter<FloatImage2DType>::Pointer writer;
  writer = itk::VTKImageWriter<FloatImage2DType>::New();
  writer->SetInput(shrink->GetOutput());
  writer->SetFileName("BasicArchitectureImage.vtk");
  writer->SetFileTypeToASCII();
  writer->Write();

  itk::RawImageWriter<FloatImage2DType>::Pointer rawWriter;
  rawWriter = itk::RawImageWriter<FloatImage2DType>::New();
  rawWriter->SetInput(shrink->GetOutput());
  rawWriter->SetFileName("BasicArchitectureImage.dat");
  rawWriter->SetFileTypeToBinary();
  rawWriter->SetByteOrderToBigEndian();
  rawWriter->Write();

  return EXIT_SUCCESS;
}

<commit_msg><commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:    itkBasicArchitectureTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include <iostream>
#include "itkImage.h"
#include "itkVector.h"
#include "itkRandomImageSource.h"
#include "itkShrinkImageFilter.h"
#include "itkVTKImageWriter.h"
#include "itkRawImageWriter.h"
#include "itkVTKImageReader.h"
#include "itkCommand.h"
#include "itkOutputWindow.h"

// this class is used to send output to stdout and not the itk window
class TextOutput : public itk::OutputWindow
{
public:
  virtual void DisplayText(const char* s)
    {
      std::cout << s << std::endl;
    }
};

// The following three classes are used to support callbacks
// on the shrink filter in the pipeline that follows later
class ShowProgressObject
{
public:
  ShowProgressObject(itk::ProcessObject* o)
    {m_Process = o;}
  void ShowProgress()
    {std::cout << "Progress " << m_Process->GetProgress() << std::endl;}
  itk::ProcessObject::Pointer m_Process;
};

class StartEndEvent
{
public:
  void Start()
    {std::cout << "start event" << std::endl;}
  void End()
    {std::cout << "end event " << std::endl;}
};

class AllEvents
{
public:
  void WatchEvents(itk::LightObject *caller, unsigned long event)
    {
      const char* eventName = 0;
      switch(event)
        {
        case itk::Command::DeleteEvent:
          eventName = "DeleteEvent";
          break;
        case itk::Command::StartEvent:
          eventName = "StartEvent";
          break;
        case itk::Command::EndEvent:
          eventName = "EndEvent";
          break;
        case itk::Command::ProgressEvent:
          {
          itk::ProcessObject* obj = dynamic_cast<itk::ProcessObject*>(caller);
          std::cout << "AnyEvent Progress " << obj->GetProgress() << std::endl;
          eventName = "ProgressEvent";
          break;
          }
        case itk::Command::PickEvent:
          eventName = "PickEvent";
          break;
        case itk::Command::StartPickEvent:
          eventName = "StartPickEvent";
          break;
        case itk::Command::AbortCheckEvent:
          eventName = "AbortCheckEvent";
          break;
        case itk::Command::ExitEvent:
          eventName = "ExitEvent";
          break;
        default:
          eventName = "UserEvent";
        }
      std::cout << "Event name: " << eventName << " Id: " << event << std::endl;
    }
};

int main()
{
  // Comment the following if you want to use the itk text output window
  TextOutput::Pointer textWindPtr = TextOutput::New();
  itk::OutputWindow::SetInstance(textWindPtr);
  // Uncomment the following if you want to see each message independently
  // itk::OutputWindow::GetInstance()->PromptUserOn();

  // Test the creation of an image with native type
  //
  itk::Image<float,2>::Pointer if2 = itk::Image<float,2>::New();

  std::cout << std::endl
            << "Image dimension is " << itk::Image<float,5>::ImageDimension
            << std::endl;
  std::cout << "Image dimension is " << itk::Image<short,1>::ImageDimension
            << std::endl;

  // Begin by creating a simple pipeline. Use a scalar ss a pixel.
  //
  // Create a typedef to make the code more digestable
  typedef itk::Image<float,2> FloatImage2DType;

  // Create a source object (in this case a reader)
  itk::VTKImageReader<FloatImage2DType>::Pointer reader;
  reader = itk::VTKImageReader<FloatImage2DType>::New();
  reader->SetFileName("junkInput.vtk");

  // Create another source object (in this case a random image generator).
  // The source object is templated on the output type.
  //
  itk::RandomImageSource<FloatImage2DType>::Pointer random;
  random = itk::RandomImageSource<FloatImage2DType>::New();
  random->SetMin(0.0);
  random->SetMax(1.0);

  // Create a filter...shrink the image by an integral amount. We also
  // add some callbacks to the start, progress, and end filter execution
  // methods. The filter is templated on the input and output data types.
  //
  itk::ShrinkImageFilter<FloatImage2DType,FloatImage2DType>::Pointer shrink;
  shrink = itk::ShrinkImageFilter<FloatImage2DType,FloatImage2DType>::New();
  shrink->SetInput(random->GetOutput());
  shrink->SetShrinkFactors(2);

  // Create a command to call ShowProgress when progress event is triggered
  ShowProgressObject progressWatch(shrink);
  itk::SimpleMemberCommand<ShowProgressObject>::Pointer command;
  command = itk::SimpleMemberCommand<ShowProgressObject>::New();
  command->SetCallbackFunction(&progressWatch,
                               &ShowProgressObject::ShowProgress);
  shrink->AddObserver(itk::Command::ProgressEvent, command);

  // Create a command to call StartEndEvent when start event is triggered
  StartEndEvent startEndWatch;
  itk::SimpleMemberCommand<StartEndEvent>::Pointer start;
  start = itk::SimpleMemberCommand<StartEndEvent>::New();
  start->SetCallbackFunction(&startEndWatch, &StartEndEvent::Start);
  shrink->AddObserver(itk::Command::StartEvent, start);

  // Create a command to call StartEndEvent when end event is triggered
  itk::SimpleMemberCommand<StartEndEvent>::Pointer end;
  end = itk::SimpleMemberCommand<StartEndEvent>::New();
  end->SetCallbackFunction(&startEndWatch, &StartEndEvent::End);
  shrink->AddObserver(itk::Command::EndEvent, end);

  // Create a command that to call AnyEvent when event is fired
  AllEvents allWatch;
  itk::MemberCommand<AllEvents>::Pointer allEvents;
  allEvents = itk::MemberCommand<AllEvents>::New();
  allEvents->SetCallbackFunction(&allWatch,
                                 &AllEvents::WatchEvents);
  unsigned long tag = shrink->AddObserver(itk::Command::AnyEvent, allEvents);

  // Create a mapper (in this case a writer). A mapper
  // is templated on the input type.
  //
  itk::VTKImageWriter<FloatImage2DType>::Pointer writer;
  writer = itk::VTKImageWriter<FloatImage2DType>::New();
  writer->SetInput(shrink->GetOutput());
  writer->SetFileName("BasicArchitectureImage.vtk");
  writer->SetFileTypeToASCII();
  writer->Write();

  itk::RawImageWriter<FloatImage2DType>::Pointer rawWriter;
  rawWriter = itk::RawImageWriter<FloatImage2DType>::New();
  rawWriter->SetInput(shrink->GetOutput());
  rawWriter->SetFileName("BasicArchitectureImage.dat");
  rawWriter->SetFileTypeToBinary();
  rawWriter->SetByteOrderToBigEndian();
  rawWriter->Write();

  // test RemoveObserver code
  shrink->RemoveObserver( tag );

  return EXIT_SUCCESS;
}

<|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.

  Some parts of this code are derived from ITK. See ITKCopyright.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.

=========================================================================*/

#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

//  Software Guide : BeginCommandLineArgs
//    INPUTS: {IMAGERY_SSECH.tif}
//    OUTPUTS: {ROI_IMAGERY_RGB.png}, {ROI_IMAGERY_MIR.png}
//    0 0 100 100
//  Software Guide : EndCommandLineArgs

//  Software Guide : BeginLatex
//
//  This example shows the use of the
//  \doxygen{otb}{MultiChannelExtractROI} and
//  \doxygen{otb}{MultiToMonoChannelExtractROI} which allow the
//  extraction of ROIs from multiband images stored into
//  \doxygen{otb}{VectorImage}s. The first one povides a Vector Image
//  as output, while the second one provides a classical
//  \doxygen{otb}{Image} with a scalar pixel type. The present example
//  shows how to extract a ROI from a 4-band SPOT 5 image and to
//  produce a first multi-band 3-channel image and a second
//  mono-channel one for the SWIR band.

//  We start by including the needed header files.
//  \index{otb::ExtractROI!header}
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbMultiChannelExtractROI.h"
#include "otbMultiToMonoChannelExtractROI.h"
// Software Guide : EndCodeSnippet

#include "otbImage.h"

int main( int argc, char * argv[] )
{

  // R\'ecuperation de arguments
  if ( argc < 7 )
  {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << "  inputImageFile outputImageFileRGB outputImageFileLastBand startX startY sizeX sizeY" << std::endl;
    return EXIT_FAILURE;
  }

//  Software Guide : BeginLatex
//
//  The program arguments define the image file names as well as the
//  rectangular area to be extracted.
//
//  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  const char * inputFilename  = argv[1];
  const char * outputFilenameRGB = argv[2];
  const char * outputFilenameMIR = argv[3];

  unsigned int  startX((unsigned int)::atoi(argv[4]));
  unsigned int  startY((unsigned int)::atoi(argv[5]));
  unsigned int  sizeX((unsigned int)::atoi(argv[6]));
  unsigned int  sizeY((unsigned int)::atoi(argv[7]));
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  As usual, we define the input and output pixel types.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef   unsigned char  InputPixelType;
  typedef   unsigned char  OutputPixelType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  First of all, we extract the multiband part by using the
  //  \doxygen{otb}{MultiChannelExtractROI} class, which is templated
  //  over the input and output pixel types. This class in not
  //  templated over the images types in order to force these images
  //  to be of \doxygen{otb}{VectorImage} type.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::MultiChannelExtractROI< InputPixelType,
  OutputPixelType >  ExtractROIFilterType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We create the extractor filter by using the \code{New} method of
  //  the class and we set its parameters.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  ExtractROIFilterType::Pointer extractROIFilter = ExtractROIFilterType::New();

  extractROIFilter->SetStartX( startX );
  extractROIFilter->SetStartY( startY );
  extractROIFilter->SetSizeX( sizeX );
  extractROIFilter->SetSizeY( sizeY );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We must tell the filter which are the channels to be used. When
  //  selecting contiguous bands, we can use the
  //  \code{SetFirstChannel} and the \code{SetLastChannel}. Otherwise,
  //  we select individual channels by using the \code{SetChannel} method.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  extractROIFilter->SetFirstChannel( 1 );
  extractROIFilter->SetLastChannel( 3 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We will use the OTB readers and writers for file access.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::ImageFileReader< ExtractROIFilterType::InputImageType >       ReaderType;
  typedef otb::ImageFileWriter< ExtractROIFilterType::InputImageType >      WriterType;

  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Since the number of bands of the input image is dynamically set
  //  at runtime, the \code{Update} method of the reader must be
  //  called before using the extractor filter.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  reader->SetFileName( inputFilename  );
  reader->Update();
  writer->SetFileName( outputFilenameRGB );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We can then build the pipeline as usual.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  extractROIFilter->SetInput( reader->GetOutput() );

  writer->SetInput( extractROIFilter->GetOutput() );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  And execute the pipeline by calling the \code{Update} method of
  //  the writer.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  writer->Update();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The usage of the \doxygen{otb}{MultiToMonoChannelExtractROI} is
  //  similar to the one of the \doxygen{otb}{MultiChannelExtractROI}
  //  described above.
  //
  //  The goal now is to extract an ROI from a multi-band image and
  //  generate a mono-channel image as output.
  //
  //  We could use the \doxygen{otb}{MultiChannelExtractROI} and
  //  select a single channel, but using the
  //  \doxygen{otb}{MultiToMonoChannelExtractROI} we generate a
  //  \doxygen{otb}{Image} instead of an
  //  \doxygen{otb}{VectorImage}. This is useful from a computing and
  //  memory usage point of view.
  //  This class is also templated over the pixel types.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::MultiToMonoChannelExtractROI< InputPixelType,
  OutputPixelType >  ExtractROIMonoFilterType;
  // Software Guide : EndCodeSnippet

  ExtractROIMonoFilterType::Pointer extractROIMonoFilter = ExtractROIMonoFilterType::New();

  extractROIMonoFilter->SetStartX( startX );
  extractROIMonoFilter->SetStartY( startY );
  extractROIMonoFilter->SetSizeX( sizeX );
  extractROIMonoFilter->SetSizeY( sizeY );

  //  Software Guide : BeginLatex
  //
  // For this filter, only one output channel has to be selected.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  extractROIMonoFilter->SetChannel( 4 );
  // Software Guide : EndCodeSnippet

  typedef otb::ImageFileReader< ExtractROIMonoFilterType::InputImageType >       monoReaderType;
  typedef otb::ImageFileWriter< ExtractROIMonoFilterType::OutputImageType >      monoWriterType;
  monoReaderType::Pointer monoReader = monoReaderType::New();
  monoWriterType::Pointer monoWriter = monoWriterType::New();

  monoReader->SetFileName( inputFilename  );
  monoReader->Update(); //Necessaire pour connaitre le nombre de canaux dans l'image
  monoWriter->SetFileName( outputFilenameMIR );
  extractROIMonoFilter->SetInput( monoReader->GetOutput() );

  monoWriter->SetInput( extractROIMonoFilter->GetOutput() );
  monoWriter->Update();

  //  Software Guide : BeginLatex
  //
  // \begin{figure}
  // \center
  // \includegraphics[width=0.44\textwidth]{IMAGERY_SSECH.eps}
  // \itkcaption[Initial SPOT 5 image]{Quicklook of the original SPOT
  // 5 image.}
  // \label{fig:IMAGERY_SSECH}
  // \end{figure}
  //
  // \begin{figure}
  // \center
  // \includegraphics[width=0.44\textwidth]{ROI_IMAGERY_RGB.eps}
  // \includegraphics[width=0.44\textwidth]{ROI_IMAGERY_MIR.eps}
  // \itkcaption[ROI of a SPOT5 image]{Result of the
  // extraction. Left: 3-channel image. Right: mono-band image.}
  // \label{fig:ROI_IMAGERY}
  // \end{figure}
  //
  //  Figure \ref{fig:ROI_IMAGERY} illustrates the result of the
  //  application of both extraction filters on the image presented in
  //  figure \ref{fig:IMAGERY_SSECH}.
  //
  //  Software Guide : EndLatex

  return EXIT_SUCCESS;

}

<commit_msg>DOC: fix the call to Update() after mail at otb-users<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.

  Some parts of this code are derived from ITK. See ITKCopyright.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.

=========================================================================*/

#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

//  Software Guide : BeginCommandLineArgs
//    INPUTS: {IMAGERY_SSECH.tif}
//    OUTPUTS: {ROI_IMAGERY_RGB.png}, {ROI_IMAGERY_MIR.png}
//    0 0 100 100
//  Software Guide : EndCommandLineArgs

//  Software Guide : BeginLatex
//
//  This example shows the use of the
//  \doxygen{otb}{MultiChannelExtractROI} and
//  \doxygen{otb}{MultiToMonoChannelExtractROI} which allow the
//  extraction of ROIs from multiband images stored into
//  \doxygen{otb}{VectorImage}s. The first one povides a Vector Image
//  as output, while the second one provides a classical
//  \doxygen{otb}{Image} with a scalar pixel type. The present example
//  shows how to extract a ROI from a 4-band SPOT 5 image and to
//  produce a first multi-band 3-channel image and a second
//  mono-channel one for the SWIR band.

//  We start by including the needed header files.
//  \index{otb::ExtractROI!header}
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbMultiChannelExtractROI.h"
#include "otbMultiToMonoChannelExtractROI.h"
// Software Guide : EndCodeSnippet

#include "otbImage.h"

int main( int argc, char * argv[] )
{

  // R\'ecuperation de arguments
  if ( argc < 7 )
  {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << "  inputImageFile outputImageFileRGB outputImageFileLastBand startX startY sizeX sizeY" << std::endl;
    return EXIT_FAILURE;
  }

//  Software Guide : BeginLatex
//
//  The program arguments define the image file names as well as the
//  rectangular area to be extracted.
//
//  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  const char * inputFilename  = argv[1];
  const char * outputFilenameRGB = argv[2];
  const char * outputFilenameMIR = argv[3];

  unsigned int  startX((unsigned int)::atoi(argv[4]));
  unsigned int  startY((unsigned int)::atoi(argv[5]));
  unsigned int  sizeX((unsigned int)::atoi(argv[6]));
  unsigned int  sizeY((unsigned int)::atoi(argv[7]));
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  As usual, we define the input and output pixel types.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef   unsigned char  InputPixelType;
  typedef   unsigned char  OutputPixelType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  First of all, we extract the multiband part by using the
  //  \doxygen{otb}{MultiChannelExtractROI} class, which is templated
  //  over the input and output pixel types. This class in not
  //  templated over the images types in order to force these images
  //  to be of \doxygen{otb}{VectorImage} type.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::MultiChannelExtractROI< InputPixelType,
  OutputPixelType >  ExtractROIFilterType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We create the extractor filter by using the \code{New} method of
  //  the class and we set its parameters.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  ExtractROIFilterType::Pointer extractROIFilter = ExtractROIFilterType::New();

  extractROIFilter->SetStartX( startX );
  extractROIFilter->SetStartY( startY );
  extractROIFilter->SetSizeX( sizeX );
  extractROIFilter->SetSizeY( sizeY );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We must tell the filter which are the channels to be used. When
  //  selecting contiguous bands, we can use the
  //  \code{SetFirstChannel} and the \code{SetLastChannel}. Otherwise,
  //  we select individual channels by using the \code{SetChannel} method.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  extractROIFilter->SetFirstChannel( 1 );
  extractROIFilter->SetLastChannel( 3 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We will use the OTB readers and writers for file access.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::ImageFileReader< ExtractROIFilterType::InputImageType >       ReaderType;
  typedef otb::ImageFileWriter< ExtractROIFilterType::InputImageType >      WriterType;

  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Since the number of bands of the input image is dynamically set
  //  at runtime, the \code{UpdateOutputInformation} method of the reader must be
  //  called before using the extractor filter.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  reader->SetFileName( inputFilename  );
  reader->UpdateOutputInformation();
  writer->SetFileName( outputFilenameRGB );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We can then build the pipeline as usual.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  extractROIFilter->SetInput( reader->GetOutput() );

  writer->SetInput( extractROIFilter->GetOutput() );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  And execute the pipeline by calling the \code{Update} method of
  //  the writer.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  writer->Update();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The usage of the \doxygen{otb}{MultiToMonoChannelExtractROI} is
  //  similar to the one of the \doxygen{otb}{MultiChannelExtractROI}
  //  described above.
  //
  //  The goal now is to extract an ROI from a multi-band image and
  //  generate a mono-channel image as output.
  //
  //  We could use the \doxygen{otb}{MultiChannelExtractROI} and
  //  select a single channel, but using the
  //  \doxygen{otb}{MultiToMonoChannelExtractROI} we generate a
  //  \doxygen{otb}{Image} instead of an
  //  \doxygen{otb}{VectorImage}. This is useful from a computing and
  //  memory usage point of view.
  //  This class is also templated over the pixel types.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::MultiToMonoChannelExtractROI< InputPixelType,
  OutputPixelType >  ExtractROIMonoFilterType;
  // Software Guide : EndCodeSnippet

  ExtractROIMonoFilterType::Pointer extractROIMonoFilter = ExtractROIMonoFilterType::New();

  extractROIMonoFilter->SetStartX( startX );
  extractROIMonoFilter->SetStartY( startY );
  extractROIMonoFilter->SetSizeX( sizeX );
  extractROIMonoFilter->SetSizeY( sizeY );

  //  Software Guide : BeginLatex
  //
  // For this filter, only one output channel has to be selected.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  extractROIMonoFilter->SetChannel( 4 );
  // Software Guide : EndCodeSnippet

  typedef otb::ImageFileReader< ExtractROIMonoFilterType::InputImageType >       monoReaderType;
  typedef otb::ImageFileWriter< ExtractROIMonoFilterType::OutputImageType >      monoWriterType;
  monoReaderType::Pointer monoReader = monoReaderType::New();
  monoWriterType::Pointer monoWriter = monoWriterType::New();

  monoReader->SetFileName( inputFilename  );
  monoReader->Update(); //Necessaire pour connaitre le nombre de canaux dans l'image
  monoWriter->SetFileName( outputFilenameMIR );
  extractROIMonoFilter->SetInput( monoReader->GetOutput() );

  monoWriter->SetInput( extractROIMonoFilter->GetOutput() );
  monoWriter->Update();

  //  Software Guide : BeginLatex
  //
  // \begin{figure}
  // \center
  // \includegraphics[width=0.44\textwidth]{IMAGERY_SSECH.eps}
  // \itkcaption[Initial SPOT 5 image]{Quicklook of the original SPOT
  // 5 image.}
  // \label{fig:IMAGERY_SSECH}
  // \end{figure}
  //
  // \begin{figure}
  // \center
  // \includegraphics[width=0.44\textwidth]{ROI_IMAGERY_RGB.eps}
  // \includegraphics[width=0.44\textwidth]{ROI_IMAGERY_MIR.eps}
  // \itkcaption[ROI of a SPOT5 image]{Result of the
  // extraction. Left: 3-channel image. Right: mono-band image.}
  // \label{fig:ROI_IMAGERY}
  // \end{figure}
  //
  //  Figure \ref{fig:ROI_IMAGERY} illustrates the result of the
  //  application of both extraction filters on the image presented in
  //  figure \ref{fig:IMAGERY_SSECH}.
  //
  //  Software Guide : EndLatex

  return EXIT_SUCCESS;

}

<|endoftext|>


<commit_before>#ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__VON_MISES_HPP__
#define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__VON_MISES_HPP__

#include <stan/agrad/partials_vari.hpp>
#include <stan/math/error_handling.hpp>
#include <stan/math.hpp>
#include <stan/meta/traits.hpp>
#include <stan/prob/constants.hpp>
#include <stan/prob/traits.hpp>
#include <stan/prob/distributions/univariate/continuous/uniform.hpp>

namespace stan {

  namespace prob {

    template<bool propto,
             typename T_y, typename T_loc, typename T_scale>
    typename return_type<T_y,T_loc,T_scale>::type
    von_mises_log(T_y const& y, T_loc const& mu, T_scale const& kappa) {
      static char const* const function = "stan::prob::von_mises_log(%1%)";

      // check if any vectors are zero length
      if (!(stan::length(y)
            && stan::length(mu)
            && stan::length(kappa)))
        return 0.0;

      using stan::is_constant_struct;
      using stan::math::check_finite;
      using stan::math::check_positive;
      using stan::math::check_greater;
      using stan::math::check_nonnegative;
      using stan::math::check_consistent_sizes;
      using stan::math::value_of;

      // Result accumulator.
      double logp = 0.0;

      // Validate arguments.
      check_finite(function, y, "Random variable", &logp);
      check_finite(function, mu, "Location paramter", &logp);
      check_finite(function, kappa, "Scale parameter", &logp);
      check_positive(function, kappa, "Scale parameter", &logp);
      check_consistent_sizes(function, y, mu, kappa, "Random variable",
                             "Location parameter", "Scale parameter",
                             &logp);

      // check if no variables are involved and prop-to
      if (!include_summand<propto,T_y,T_loc,T_scale>::value)
        return logp;

      // Determine constants.
      const bool y_const = is_constant_struct<T_y>::value;
      const bool mu_const = is_constant_struct<T_loc>::value;
      const bool kappa_const = is_constant_struct<T_scale>::value;

      // Determine which expensive computations to perform.
      const bool compute_bessel0 = include_summand<propto,T_scale>::value;
      const bool compute_bessel1 = !kappa_const;
      const double TWO_PI = 2.0 * stan::math::pi();

      // Wrap scalars into vector views.
      VectorView<const T_y> y_vec(y);
      VectorView<const T_loc> mu_vec(mu);
      VectorView<const T_scale> kappa_vec(kappa);

      DoubleVectorView<true,is_vector<T_scale>::value> kappa_dbl(length(kappa));
      DoubleVectorView<include_summand<propto,T_scale>::value,is_vector<T_scale>::value> log_bessel0(length(kappa));
      for (size_t i = 0; i < length(kappa); i++) {
        kappa_dbl[i] = value_of(kappa_vec[i]);
        if (include_summand<propto,T_scale>::value)
          log_bessel0[i] = log(boost::math::cyl_bessel_i(0, value_of(kappa_vec[i])));
      }
      agrad::OperandsAndPartials<T_y, T_loc, T_scale> oap(y, mu, kappa);

      size_t N = max_size(y, mu, kappa);

      for (size_t n = 0; n < N; n++) {
        // Extract argument values.
        const double y_ = value_of(y_vec[n]);
        const double y_dbl =  y_ - std::floor(y_ / TWO_PI) * TWO_PI;
        const double mu_dbl = value_of(mu_vec[n]);

        // Reusable values.
        double bessel0 = 0;
        if (compute_bessel0)
          bessel0 = boost::math::cyl_bessel_i(0, kappa_dbl[n]);
        double bessel1 = 0;
        if (compute_bessel1)
          bessel1 = boost::math::cyl_bessel_i(-1, kappa_dbl[n]);
        const double kappa_sin = kappa_dbl[n] * std::sin(mu_dbl - y_dbl);
        const double kappa_cos = kappa_dbl[n] * std::cos(mu_dbl - y_dbl);

        // Log probability.
        if (include_summand<propto>::value)
          logp -= LOG_TWO_PI;
        if (include_summand<propto,T_scale>::value)
          logp -= log_bessel0[n];
        if (include_summand<propto,T_y,T_loc,T_scale>::value)
          logp += kappa_cos;

        // Gradient.
        if (!y_const)
          oap.d_x1[n] += kappa_sin;
        if (!mu_const)
          oap.d_x2[n] -= kappa_sin;
        if (!kappa_const)
          oap.d_x3[n] += kappa_cos / kappa_dbl[n] - bessel1 / bessel0;
      }

      return oap.to_var(logp);
    }

    template<typename T_y, typename T_loc, typename T_scale>
    inline typename return_type<T_y,T_loc,T_scale>::type
    von_mises_log(T_y const& y, T_loc const& mu, T_scale const& kappa) {
      return von_mises_log<false>(y, mu, kappa);
    }

    // The algorithm used in von_mises_rng is a modified version of the
    // algorithm in:
    //
    // Efficient Simulation of the von Mises Distribution
    // D. J. Best and N. I. Fisher
    // Journal of the Royal Statistical Society. Series C (Applied Statistics), Vol. 28, No. 2 (1979), pp. 152-157
    //
    // See licenses/stan-license.txt for Stan license.

    template <class RNG>
    inline double
    von_mises_rng(const double mu,
                  const double kappa,
                  RNG& rng) {
      using boost::variate_generator;
      using stan::prob::uniform_rng;

      static const char* function = "stan::prob::von_mises_rng(%1%)";

      stan::math::check_finite(function,kappa,"inverse of variance",(double*)0);
      stan::math::check_finite(function,mu,"mean",(double*)0);
      stan::math::check_positive(function,kappa,"inverse of variance",
                                 (double*)0);

      double r = 1 + pow((1 + 4 * kappa * kappa), 0.5);
      double rho = 0.5 * (r - pow(2 * r, 0.5)) / kappa;
      double s = 0.5 * (1 + rho * rho) / rho;

      bool done = 0;
      double W;
      while (!done) {
        double Z = std::cos(stan::math::pi() * uniform_rng(0.0, 1.0, rng));
        W = (1 + s * Z) / (s + Z);
        double Y = kappa * (s - W);
        double U2 = uniform_rng(0.0, 1.0, rng);
        done = Y * (2 - Y) - U2 > 0;

        if(!done)
          done = log(Y / U2) + 1 - Y >= 0;
      }

      double U3 = uniform_rng(0.0, 1.0, rng) - 0.5;
      double sign = ((U3 >= 0) - (U3 <= 0));
      double PI = stan::math::pi();

      return sign * std::acos(W) + fmod(fmod(mu,2*PI)+2*PI,2*PI);
    }

  }
}
#endif
<commit_msg>fixes #743. Instead of PI, multiplied by 2 and called it TWO_PI<commit_after>#ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__VON_MISES_HPP__
#define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__VON_MISES_HPP__

#include <stan/agrad/partials_vari.hpp>
#include <stan/math/error_handling.hpp>
#include <stan/math.hpp>
#include <stan/meta/traits.hpp>
#include <stan/prob/constants.hpp>
#include <stan/prob/traits.hpp>
#include <stan/prob/distributions/univariate/continuous/uniform.hpp>

namespace stan {

  namespace prob {

    template<bool propto,
             typename T_y, typename T_loc, typename T_scale>
    typename return_type<T_y,T_loc,T_scale>::type
    von_mises_log(T_y const& y, T_loc const& mu, T_scale const& kappa) {
      static char const* const function = "stan::prob::von_mises_log(%1%)";

      // check if any vectors are zero length
      if (!(stan::length(y)
            && stan::length(mu)
            && stan::length(kappa)))
        return 0.0;

      using stan::is_constant_struct;
      using stan::math::check_finite;
      using stan::math::check_positive;
      using stan::math::check_greater;
      using stan::math::check_nonnegative;
      using stan::math::check_consistent_sizes;
      using stan::math::value_of;

      // Result accumulator.
      double logp = 0.0;

      // Validate arguments.
      check_finite(function, y, "Random variable", &logp);
      check_finite(function, mu, "Location paramter", &logp);
      check_finite(function, kappa, "Scale parameter", &logp);
      check_positive(function, kappa, "Scale parameter", &logp);
      check_consistent_sizes(function, y, mu, kappa, "Random variable",
                             "Location parameter", "Scale parameter",
                             &logp);

      // check if no variables are involved and prop-to
      if (!include_summand<propto,T_y,T_loc,T_scale>::value)
        return logp;

      // Determine constants.
      const bool y_const = is_constant_struct<T_y>::value;
      const bool mu_const = is_constant_struct<T_loc>::value;
      const bool kappa_const = is_constant_struct<T_scale>::value;

      // Determine which expensive computations to perform.
      const bool compute_bessel0 = include_summand<propto,T_scale>::value;
      const bool compute_bessel1 = !kappa_const;
      const double TWO_PI = 2.0 * stan::math::pi();

      // Wrap scalars into vector views.
      VectorView<const T_y> y_vec(y);
      VectorView<const T_loc> mu_vec(mu);
      VectorView<const T_scale> kappa_vec(kappa);

      DoubleVectorView<true,is_vector<T_scale>::value> kappa_dbl(length(kappa));
      DoubleVectorView<include_summand<propto,T_scale>::value,is_vector<T_scale>::value> log_bessel0(length(kappa));
      for (size_t i = 0; i < length(kappa); i++) {
        kappa_dbl[i] = value_of(kappa_vec[i]);
        if (include_summand<propto,T_scale>::value)
          log_bessel0[i] = log(boost::math::cyl_bessel_i(0, value_of(kappa_vec[i])));
      }
      agrad::OperandsAndPartials<T_y, T_loc, T_scale> oap(y, mu, kappa);

      size_t N = max_size(y, mu, kappa);

      for (size_t n = 0; n < N; n++) {
        // Extract argument values.
        const double y_ = value_of(y_vec[n]);
        const double y_dbl =  y_ - std::floor(y_ / TWO_PI) * TWO_PI;
        const double mu_dbl = value_of(mu_vec[n]);

        // Reusable values.
        double bessel0 = 0;
        if (compute_bessel0)
          bessel0 = boost::math::cyl_bessel_i(0, kappa_dbl[n]);
        double bessel1 = 0;
        if (compute_bessel1)
          bessel1 = boost::math::cyl_bessel_i(-1, kappa_dbl[n]);
        const double kappa_sin = kappa_dbl[n] * std::sin(mu_dbl - y_dbl);
        const double kappa_cos = kappa_dbl[n] * std::cos(mu_dbl - y_dbl);

        // Log probability.
        if (include_summand<propto>::value)
          logp -= LOG_TWO_PI;
        if (include_summand<propto,T_scale>::value)
          logp -= log_bessel0[n];
        if (include_summand<propto,T_y,T_loc,T_scale>::value)
          logp += kappa_cos;

        // Gradient.
        if (!y_const)
          oap.d_x1[n] += kappa_sin;
        if (!mu_const)
          oap.d_x2[n] -= kappa_sin;
        if (!kappa_const)
          oap.d_x3[n] += kappa_cos / kappa_dbl[n] - bessel1 / bessel0;
      }

      return oap.to_var(logp);
    }

    template<typename T_y, typename T_loc, typename T_scale>
    inline typename return_type<T_y,T_loc,T_scale>::type
    von_mises_log(T_y const& y, T_loc const& mu, T_scale const& kappa) {
      return von_mises_log<false>(y, mu, kappa);
    }

    // The algorithm used in von_mises_rng is a modified version of the
    // algorithm in:
    //
    // Efficient Simulation of the von Mises Distribution
    // D. J. Best and N. I. Fisher
    // Journal of the Royal Statistical Society. Series C (Applied Statistics), Vol. 28, No. 2 (1979), pp. 152-157
    //
    // See licenses/stan-license.txt for Stan license.

    template <class RNG>
    inline double
    von_mises_rng(const double mu,
                  const double kappa,
                  RNG& rng) {
      using boost::variate_generator;
      using stan::prob::uniform_rng;

      static const char* function = "stan::prob::von_mises_rng(%1%)";

      stan::math::check_finite(function,kappa,"inverse of variance",(double*)0);
      stan::math::check_finite(function,mu,"mean",(double*)0);
      stan::math::check_positive(function,kappa,"inverse of variance",
                                 (double*)0);

      double r = 1 + pow((1 + 4 * kappa * kappa), 0.5);
      double rho = 0.5 * (r - pow(2 * r, 0.5)) / kappa;
      double s = 0.5 * (1 + rho * rho) / rho;

      bool done = 0;
      double W;
      while (!done) {
        double Z = std::cos(stan::math::pi() * uniform_rng(0.0, 1.0, rng));
        W = (1 + s * Z) / (s + Z);
        double Y = kappa * (s - W);
        double U2 = uniform_rng(0.0, 1.0, rng);
        done = Y * (2 - Y) - U2 > 0;

        if(!done)
          done = log(Y / U2) + 1 - Y >= 0;
      }

      double U3 = uniform_rng(0.0, 1.0, rng) - 0.5;
      double sign = ((U3 >= 0) - (U3 <= 0));
      const double TWO_PI = 2 * stan::math::pi();

      return sign * std::acos(W) + fmod(fmod(mu,TWO_PI)+TWO_PI,TWO_PI);
    }

  }
}
#endif
<|endoftext|>


<commit_before>#include "testsettings.hpp"
#ifdef TEST_COLUMN_FLOAT

#include <iostream>
#include <UnitTest++.h>
#include <tightdb/column_basic.hpp>

using namespace tightdb;

template <typename T, size_t N> inline
size_t SizeOfArray( const T(&)[ N ] )
{
  return N;
}

namespace {
float floatVal[] = {0.0f,
                   1.0f,
                   2.12345f,
                   12345.12f,
                   -12345.12f
                  };
const size_t floatValLen = SizeOfArray(floatVal);

double doubleVal[] = {0.0,
                      1.0,
                      2.12345,
                      12345.12,
                      -12345.12
                     };
const size_t doubleValLen = SizeOfArray(doubleVal);

} //namespace

template <class C>
void BasicColumn_IsEmpty()
{
    C c;
    CHECK(c.is_empty());
    CHECK_EQUAL(0U, c.size());
    c.destroy();
}
TEST(ColumnFloat_IsEmpty) { BasicColumn_IsEmpty<ColumnFloat>(); }
TEST(ColumnDouble_IsEmpty){ BasicColumn_IsEmpty<ColumnDouble>(); }

template <class C, typename T>
void BasicColumn_AddGet(T val[], size_t valLen)
{
    C c;
    for (size_t i=0; i<valLen; ++i) {
        c.add(val[i]);

        CHECK_EQUAL(i+1, c.size());

        for (size_t j=0; j<i; ++j) {
            CHECK_EQUAL(val[j], c.get(j));
        }
    }

    c.destroy();
}
TEST(ColumnFloat_AddGet) { BasicColumn_AddGet<ColumnFloat, float>(floatVal, floatValLen); }
TEST(ColumnDouble_AddGet){ BasicColumn_AddGet<ColumnDouble, double>(doubleVal, doubleValLen); }

template <class C, typename T>
void BasicColumn_Clear()
{
    C c;
    CHECK(c.is_empty());

    for (size_t i=0; i<100; ++i)
        c.add();
    CHECK(!c.is_empty());

    c.clear();
    CHECK(c.is_empty());

    c.destroy();
}
TEST(ColumnFloat_Clear) { BasicColumn_Clear<ColumnFloat, float>(); }
TEST(ColumnDouble_Clear){ BasicColumn_Clear<ColumnDouble, double>(); }

template <class C, typename T>
void BasicColumn_Set(T val[], size_t valLen)
{
    C c;
    for (size_t i=0; i<valLen; ++i)
        c.add(val[i]);
    CHECK_EQUAL(valLen, c.size());

    T v0 = T(1.6);
    T v3 = T(-987.23);
    c.set(0, v0);
    CHECK_EQUAL(v0, c.get(0));
    c.set(3, v3);
    CHECK_EQUAL(v3, c.get(3));

    CHECK_EQUAL(val[1], c.get(1));
    CHECK_EQUAL(val[2], c.get(2));
    CHECK_EQUAL(val[4], c.get(4));

    c.destroy();
}
TEST(ColumnFloat_Set) { BasicColumn_Set<ColumnFloat, float>(floatVal, floatValLen); }
TEST(ColumnDouble_Set){ BasicColumn_Set<ColumnDouble, double>(doubleVal, doubleValLen); }

template <class C, typename T>
void BasicColumn_Insert(T val[], size_t valLen)
{
    (void)valLen;

    C c;

    // Insert in empty column
    c.insert(0, val[0]);
    CHECK_EQUAL(val[0], c.get(0));
    CHECK_EQUAL(1, c.size());

    // Insert in top
    c.insert(0, val[1]);
    CHECK_EQUAL(val[1], c.get(0));
    CHECK_EQUAL(val[0], c.get(1));
    CHECK_EQUAL(2, c.size());

    // Insert in middle
    c.insert(1, val[2]);
    CHECK_EQUAL(val[1], c.get(0));
    CHECK_EQUAL(val[2], c.get(1));
    CHECK_EQUAL(val[0], c.get(2));
    CHECK_EQUAL(3, c.size());

    // Insert at buttom
    c.insert(3, val[3]);
    CHECK_EQUAL(val[1], c.get(0));
    CHECK_EQUAL(val[2], c.get(1));
    CHECK_EQUAL(val[0], c.get(2));
    CHECK_EQUAL(val[3], c.get(3));
    CHECK_EQUAL(4, c.size());

    // Insert at top
    c.insert(0, val[4]);
    CHECK_EQUAL(val[4], c.get(0));
    CHECK_EQUAL(val[1], c.get(1));
    CHECK_EQUAL(val[2], c.get(2));
    CHECK_EQUAL(val[0], c.get(3));
    CHECK_EQUAL(val[3], c.get(4));
    CHECK_EQUAL(5, c.size());

    c.destroy();
}
TEST(ColumnFloat_Insert) { BasicColumn_Insert<ColumnFloat, float>(floatVal, floatValLen); }
TEST(ColumnDouble_Insert){ BasicColumn_Insert<ColumnDouble, double>(doubleVal, doubleValLen); }

template <class C, typename T>
void BasicColumn_Aggregates(T val[], size_t valLen)
{
    (void)valLen;
    (void)val;

    C c;

//    double sum = c.sum();
//    CHECK_EQUAL(0, sum);

    // todo: add tests for minimum, maximum,
    // todo !!!

   c.destroy();
}
TEST(ColumnFloat_Aggregates) { BasicColumn_Aggregates<ColumnFloat, float>(floatVal, floatValLen); }
TEST(ColumnDouble_Aggregates){ BasicColumn_Aggregates<ColumnDouble, double>(doubleVal, doubleValLen); }

template <class C, typename T>
void BasicColumn_Delete(T val[], size_t valLen)
{
    C c;
    for (size_t i=0; i<valLen; ++i)
        c.add(val[i]);
    CHECK_EQUAL(5, c.size());
    CHECK_EQUAL(val[0], c.get(0));
    CHECK_EQUAL(val[1], c.get(1));
    CHECK_EQUAL(val[2], c.get(2));
    CHECK_EQUAL(val[3], c.get(3));
    CHECK_EQUAL(val[4], c.get(4));

    // Delete first
    c.erase(0, 0 == c.size()-1);
    CHECK_EQUAL(4, c.size());
    CHECK_EQUAL(val[1], c.get(0));
    CHECK_EQUAL(val[2], c.get(1));
    CHECK_EQUAL(val[3], c.get(2));
    CHECK_EQUAL(val[4], c.get(3));

    // Delete middle
    c.erase(2, 2 == c.size()-1);
    CHECK_EQUAL(3, c.size());
    CHECK_EQUAL(val[1], c.get(0));
    CHECK_EQUAL(val[2], c.get(1));
    CHECK_EQUAL(val[4], c.get(2));

    // Delete last
    c.erase(2, 2 == c.size()-1);
    CHECK_EQUAL(2, c.size());
    CHECK_EQUAL(val[1], c.get(0));
    CHECK_EQUAL(val[2], c.get(1));

    // Delete single
    c.erase(0, 0 == c.size()-1);
    CHECK_EQUAL(1, c.size());
    CHECK_EQUAL(val[2], c.get(0));

    // Delete all
    c.erase(0, 0 == c.size()-1);
    CHECK_EQUAL(0, c.size());

    c.destroy();
}
TEST(ColumnFloat_Delete) { BasicColumn_Delete<ColumnFloat, float>(floatVal, floatValLen); }
TEST(ColumnDouble_Delete){ BasicColumn_Delete<ColumnDouble, double>(doubleVal, doubleValLen); }

TEST(ColumnDouble_InitOfEmptyColumn)
{
    Table t;
    t.add_column(type_Double, "works");
    t.add_column(type_Double, "works also");
    t.add_empty_row();
    t.set_double(0,0,1.1);
    t.set_double(1,0,2.2);
    t.remove_column(1);
    t.add_empty_row();
    t.add_column(type_Double, "doesn't work");
    CHECK_EQUAL(0.0, t.get_double(1,0));
}

TEST(ColumnFloat_InitOfEmptyColumn)
{
    Table t;
    t.add_column(type_Float, "works");
    t.add_column(type_Float, "works also");
    t.add_empty_row();
    t.set_float(0,0,1.1);
    t.set_float(1,0,2.2);
    t.remove_column(1);
    t.add_empty_row();
    t.add_column(type_Float, "doesn't work");
    CHECK_EQUAL(0.0, t.get_float(1,0));
}

TEST(ColumnInt_InitOfEmptyColumn)
{
    Table t;
    t.add_column(type_Int, "works");
    t.add_column(type_Int, "works also");
    t.add_empty_row();
    t.set_int(0,0,1);
    t.set_int(1,0,2);
    t.remove_column(1);
    t.add_empty_row();
    t.add_column(type_Int, "doesn't work");
    CHECK_EQUAL(0, t.get_int(1,0));
}

TEST(ColumnString_InitOfEmptyColumn)
{
    Table t;
    t.add_column(type_String, "works");
    t.add_column(type_String, "works also");
    t.add_empty_row();
    t.set_string(0,0, "yellow");
    t.set_string(1,0, "very bright");
    t.remove_column(1);
    t.add_empty_row();
    t.add_column(type_String, "doesn't work");
    CHECK_EQUAL("", t.get_string(1,0));
}

TEST(ColumnBinary_InitOfEmptyColumn)
{
    Table t;
    t.add_column(type_Binary, "works");
    t.add_column(type_Binary, "works also");
    t.add_empty_row();
    t.set_binary(0,0, BinaryData("yellow",10));
    t.set_binary(1,0, BinaryData("very bright", 15));
    t.remove_column(1);
    t.add_empty_row();
    t.add_column(type_Binary, "doesn't work");
    CHECK_EQUAL(BinaryData("",0), t.get_binary(1,0));
}

TEST(ColumnBool_InitOfEmptyColumn)
{
    Table t;
    t.add_column(type_Bool, "works");
    t.add_column(type_Bool, "works also");
    t.add_empty_row();
    t.set_bool(0,0, true);
    t.set_bool(1,0, true);
    t.remove_column(1);
    t.add_empty_row();
    t.add_column(type_Bool, "doesn't work");
    CHECK_EQUAL(false, t.get_bool(1,0));
}

TEST(ColumnMixed_InitOfEmptyColumn)
{
    Table t;
    t.add_column(type_Mixed, "works");
    t.add_column(type_Mixed, "works also");
    t.add_empty_row();
    t.set_mixed(0,0, new Mixed(1.1));
    t.set_mixed(1,0, new Mixed(2.2));
    t.remove_column(1);
    t.add_empty_row();
    t.add_column(type_Mixed, "doesn't work");
    CHECK_EQUAL(NULL, t.get_mixed(1,0));
}

#endif // TEST_COLUMN_FLOAT
<commit_msg>fixed NULL conversion warning<commit_after>#include "testsettings.hpp"
#ifdef TEST_COLUMN_FLOAT

#include <iostream>
#include <UnitTest++.h>
#include <tightdb/column_basic.hpp>

using namespace tightdb;

template <typename T, size_t N> inline
size_t SizeOfArray( const T(&)[ N ] )
{
  return N;
}

namespace {
float floatVal[] = {0.0f,
                   1.0f,
                   2.12345f,
                   12345.12f,
                   -12345.12f
                  };
const size_t floatValLen = SizeOfArray(floatVal);

double doubleVal[] = {0.0,
                      1.0,
                      2.12345,
                      12345.12,
                      -12345.12
                     };
const size_t doubleValLen = SizeOfArray(doubleVal);

} //namespace

template <class C>
void BasicColumn_IsEmpty()
{
    C c;
    CHECK(c.is_empty());
    CHECK_EQUAL(0U, c.size());
    c.destroy();
}
TEST(ColumnFloat_IsEmpty) { BasicColumn_IsEmpty<ColumnFloat>(); }
TEST(ColumnDouble_IsEmpty){ BasicColumn_IsEmpty<ColumnDouble>(); }

template <class C, typename T>
void BasicColumn_AddGet(T val[], size_t valLen)
{
    C c;
    for (size_t i=0; i<valLen; ++i) {
        c.add(val[i]);

        CHECK_EQUAL(i+1, c.size());

        for (size_t j=0; j<i; ++j) {
            CHECK_EQUAL(val[j], c.get(j));
        }
    }

    c.destroy();
}
TEST(ColumnFloat_AddGet) { BasicColumn_AddGet<ColumnFloat, float>(floatVal, floatValLen); }
TEST(ColumnDouble_AddGet){ BasicColumn_AddGet<ColumnDouble, double>(doubleVal, doubleValLen); }

template <class C, typename T>
void BasicColumn_Clear()
{
    C c;
    CHECK(c.is_empty());

    for (size_t i=0; i<100; ++i)
        c.add();
    CHECK(!c.is_empty());

    c.clear();
    CHECK(c.is_empty());

    c.destroy();
}
TEST(ColumnFloat_Clear) { BasicColumn_Clear<ColumnFloat, float>(); }
TEST(ColumnDouble_Clear){ BasicColumn_Clear<ColumnDouble, double>(); }

template <class C, typename T>
void BasicColumn_Set(T val[], size_t valLen)
{
    C c;
    for (size_t i=0; i<valLen; ++i)
        c.add(val[i]);
    CHECK_EQUAL(valLen, c.size());

    T v0 = T(1.6);
    T v3 = T(-987.23);
    c.set(0, v0);
    CHECK_EQUAL(v0, c.get(0));
    c.set(3, v3);
    CHECK_EQUAL(v3, c.get(3));

    CHECK_EQUAL(val[1], c.get(1));
    CHECK_EQUAL(val[2], c.get(2));
    CHECK_EQUAL(val[4], c.get(4));

    c.destroy();
}
TEST(ColumnFloat_Set) { BasicColumn_Set<ColumnFloat, float>(floatVal, floatValLen); }
TEST(ColumnDouble_Set){ BasicColumn_Set<ColumnDouble, double>(doubleVal, doubleValLen); }

template <class C, typename T>
void BasicColumn_Insert(T val[], size_t valLen)
{
    (void)valLen;

    C c;

    // Insert in empty column
    c.insert(0, val[0]);
    CHECK_EQUAL(val[0], c.get(0));
    CHECK_EQUAL(1, c.size());

    // Insert in top
    c.insert(0, val[1]);
    CHECK_EQUAL(val[1], c.get(0));
    CHECK_EQUAL(val[0], c.get(1));
    CHECK_EQUAL(2, c.size());

    // Insert in middle
    c.insert(1, val[2]);
    CHECK_EQUAL(val[1], c.get(0));
    CHECK_EQUAL(val[2], c.get(1));
    CHECK_EQUAL(val[0], c.get(2));
    CHECK_EQUAL(3, c.size());

    // Insert at buttom
    c.insert(3, val[3]);
    CHECK_EQUAL(val[1], c.get(0));
    CHECK_EQUAL(val[2], c.get(1));
    CHECK_EQUAL(val[0], c.get(2));
    CHECK_EQUAL(val[3], c.get(3));
    CHECK_EQUAL(4, c.size());

    // Insert at top
    c.insert(0, val[4]);
    CHECK_EQUAL(val[4], c.get(0));
    CHECK_EQUAL(val[1], c.get(1));
    CHECK_EQUAL(val[2], c.get(2));
    CHECK_EQUAL(val[0], c.get(3));
    CHECK_EQUAL(val[3], c.get(4));
    CHECK_EQUAL(5, c.size());

    c.destroy();
}
TEST(ColumnFloat_Insert) { BasicColumn_Insert<ColumnFloat, float>(floatVal, floatValLen); }
TEST(ColumnDouble_Insert){ BasicColumn_Insert<ColumnDouble, double>(doubleVal, doubleValLen); }

template <class C, typename T>
void BasicColumn_Aggregates(T val[], size_t valLen)
{
    (void)valLen;
    (void)val;

    C c;

//    double sum = c.sum();
//    CHECK_EQUAL(0, sum);

    // todo: add tests for minimum, maximum,
    // todo !!!

   c.destroy();
}
TEST(ColumnFloat_Aggregates) { BasicColumn_Aggregates<ColumnFloat, float>(floatVal, floatValLen); }
TEST(ColumnDouble_Aggregates){ BasicColumn_Aggregates<ColumnDouble, double>(doubleVal, doubleValLen); }

template <class C, typename T>
void BasicColumn_Delete(T val[], size_t valLen)
{
    C c;
    for (size_t i=0; i<valLen; ++i)
        c.add(val[i]);
    CHECK_EQUAL(5, c.size());
    CHECK_EQUAL(val[0], c.get(0));
    CHECK_EQUAL(val[1], c.get(1));
    CHECK_EQUAL(val[2], c.get(2));
    CHECK_EQUAL(val[3], c.get(3));
    CHECK_EQUAL(val[4], c.get(4));

    // Delete first
    c.erase(0, 0 == c.size()-1);
    CHECK_EQUAL(4, c.size());
    CHECK_EQUAL(val[1], c.get(0));
    CHECK_EQUAL(val[2], c.get(1));
    CHECK_EQUAL(val[3], c.get(2));
    CHECK_EQUAL(val[4], c.get(3));

    // Delete middle
    c.erase(2, 2 == c.size()-1);
    CHECK_EQUAL(3, c.size());
    CHECK_EQUAL(val[1], c.get(0));
    CHECK_EQUAL(val[2], c.get(1));
    CHECK_EQUAL(val[4], c.get(2));

    // Delete last
    c.erase(2, 2 == c.size()-1);
    CHECK_EQUAL(2, c.size());
    CHECK_EQUAL(val[1], c.get(0));
    CHECK_EQUAL(val[2], c.get(1));

    // Delete single
    c.erase(0, 0 == c.size()-1);
    CHECK_EQUAL(1, c.size());
    CHECK_EQUAL(val[2], c.get(0));

    // Delete all
    c.erase(0, 0 == c.size()-1);
    CHECK_EQUAL(0, c.size());

    c.destroy();
}
TEST(ColumnFloat_Delete) { BasicColumn_Delete<ColumnFloat, float>(floatVal, floatValLen); }
TEST(ColumnDouble_Delete){ BasicColumn_Delete<ColumnDouble, double>(doubleVal, doubleValLen); }

TEST(ColumnDouble_InitOfEmptyColumn)
{
    Table t;
    t.add_column(type_Double, "works");
    t.add_column(type_Double, "works also");
    t.add_empty_row();
    t.set_double(0,0,1.1);
    t.set_double(1,0,2.2);
    t.remove_column(1);
    t.add_empty_row();
    t.add_column(type_Double, "doesn't work");
    CHECK_EQUAL(0.0, t.get_double(1,0));
}

TEST(ColumnFloat_InitOfEmptyColumn)
{
    Table t;
    t.add_column(type_Float, "works");
    t.add_column(type_Float, "works also");
    t.add_empty_row();
    t.set_float(0,0,1.1);
    t.set_float(1,0,2.2);
    t.remove_column(1);
    t.add_empty_row();
    t.add_column(type_Float, "doesn't work");
    CHECK_EQUAL(0.0, t.get_float(1,0));
}

TEST(ColumnInt_InitOfEmptyColumn)
{
    Table t;
    t.add_column(type_Int, "works");
    t.add_column(type_Int, "works also");
    t.add_empty_row();
    t.set_int(0,0,1);
    t.set_int(1,0,2);
    t.remove_column(1);
    t.add_empty_row();
    t.add_column(type_Int, "doesn't work");
    CHECK_EQUAL(0, t.get_int(1,0));
}

TEST(ColumnString_InitOfEmptyColumn)
{
    Table t;
    t.add_column(type_String, "works");
    t.add_column(type_String, "works also");
    t.add_empty_row();
    t.set_string(0,0, "yellow");
    t.set_string(1,0, "very bright");
    t.remove_column(1);
    t.add_empty_row();
    t.add_column(type_String, "doesn't work");
    CHECK_EQUAL("", t.get_string(1,0));
}

TEST(ColumnBinary_InitOfEmptyColumn)
{
    Table t;
    t.add_column(type_Binary, "works");
    t.add_column(type_Binary, "works also");
    t.add_empty_row();
    t.set_binary(0,0, BinaryData("yellow",10));
    t.set_binary(1,0, BinaryData("very bright", 15));
    t.remove_column(1);
    t.add_empty_row();
    t.add_column(type_Binary, "doesn't work");
    CHECK_EQUAL(BinaryData("",0), t.get_binary(1,0));
}

TEST(ColumnBool_InitOfEmptyColumn)
{
    Table t;
    t.add_column(type_Bool, "works");
    t.add_column(type_Bool, "works also");
    t.add_empty_row();
    t.set_bool(0,0, true);
    t.set_bool(1,0, true);
    t.remove_column(1);
    t.add_empty_row();
    t.add_column(type_Bool, "doesn't work");
    CHECK_EQUAL(false, t.get_bool(1,0));
}

TEST(ColumnMixed_InitOfEmptyColumn)
{
    Table t;
    t.add_column(type_Mixed, "works");
    t.add_column(type_Mixed, "works also");
    t.add_empty_row();
    t.set_mixed(0,0, new Mixed(1.1));
    t.set_mixed(1,0, new Mixed(2.2));
    t.remove_column(1);
    t.add_empty_row();
    t.add_column(type_Mixed, "doesn't work");
    CHECK_EQUAL(0, t.get_mixed(1,0));
}

#endif // TEST_COLUMN_FLOAT
<|endoftext|>


<commit_before>/*
 * Copyright 2009 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <votca/tools/cubicspline.h>
#include <votca/tools/table.h>
#include <votca/tools/tokenizer.h>
#include <boost/program_options.hpp>
#include <iostream>
#include "version.h"

using namespace std;
namespace po = boost::program_options;

void help_text()
{
    votca::csg::HelpTextHeader("csg_resample");
    cout << "Change grid + interval of any sort of table files.\n"
            "Mainly called internally by inverse script, can also be\n"
            "used to manually prepare input files for coarse-grained\n"
            "simulations.\n\n";
}

void check_option(po::options_description &desc, po::variables_map &vm, const string &option)
{
    if(!vm.count(option)) {
        cout << "csg_resample \n\n";
        cout << desc << endl << "parameter " << option << " is not specified\n";
        exit(1);
    }
}

int main(int argc, char** argv)
{
    string in_file, out_file, grid, spfit;
    CubicSpline spline;
    Table in, out;

    // program options
    po::options_description desc("Allowed options");

    desc.add_options()
      ("in", po::value<string>(&in_file), "table to read")
      ("out", po::value<string>(&out_file), "table to write")
      ("grid", po::value<string>(&grid), "new grid spacing (min:step:max)")
      ("spfit", po::value<string>(&spfit), "specify spline fit grid. if option is not specified, normal spline interpolation is performed")
      //("bc", po::)
      ("help", "options file for coarse graining");

    po::variables_map vm;
    try {
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);
    }
    catch(po::error err) {
        cout << "error parsing command line: " << err.what() << endl;
        return -1;
    }

    // does the user want help?
    if (vm.count("help")) {
        help_text();
        cout << desc << endl;
        return 0;
    }

    check_option(desc, vm, "in");
    check_option(desc, vm, "out");
    check_option(desc, vm, "grid");

    double min, max, step;
    {
        Tokenizer tok(grid, ":");
        vector<string> toks;
        tok.ToVector(toks);
        if(toks.size()!=3) {
            cout << "wrong range format, use min:step:max\n";
            return 1;
        }
        min = boost::lexical_cast<double>(toks[0]);
        step = boost::lexical_cast<double>(toks[1]);
        max = boost::lexical_cast<double>(toks[2]);
    }

    in.Load(in_file);
    spline.setBC(CubicSpline::splineNormal);

    if (vm.count("spfit")) {
        Tokenizer tok(spfit, ":");
        vector<string> toks;
        tok.ToVector(toks);
        if(toks.size()!=3) {
            cout << "wrong range format in spfit, use min:step:max\n";
            return 1;
        }
        double sp_min, sp_max, sp_step;
        sp_min = boost::lexical_cast<double>(toks[0]);
        sp_step = boost::lexical_cast<double>(toks[1]);
        sp_max = boost::lexical_cast<double>(toks[2]);
        cout << "doing spline fit " << sp_min << ":" << sp_step << ":" << sp_max << endl;
        spline.GenerateGrid(sp_min, sp_max, sp_step);

        spline.Fit(in.x(), in.y());
    } else {
        spline.Interpolate(in.x(), in.y());
    }

    out.GenerateGridSpacing(min, max, step);
    spline.Calculate(out.x(), out.y());

    out.y() = out.y();
    out.flags() = ub::scalar_vector<double>(out.flags().size(), 'o');

    int i=0;
    for(i=0; out.x(i) < in.x(0) && i<out.size(); ++i);

    int j=0;
    for(;i < out.size(); ++i) {
        for(; j < in.size(); ++j)
            if(in.x(j) >= out.x(i))
                break;
        if(in.size() == j) break;
        out.flags(i) = in.flags(j);
    }

    out.Save(out_file);

    return 0;
}

<commit_msg>csg_resample added derivative option<commit_after>/*
 * Copyright 2009 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <votca/tools/cubicspline.h>
#include <votca/tools/table.h>
#include <votca/tools/tokenizer.h>
#include <boost/program_options.hpp>
#include <iostream>
#include "version.h"

using namespace std;
namespace po = boost::program_options;

void help_text()
{
    votca::csg::HelpTextHeader("csg_resample");
    cout << "Change grid + interval of any sort of table files.\n"
            "Mainly called internally by inverse script, can also be\n"
            "used to manually prepare input files for coarse-grained\n"
            "simulations.\n\n";
}

void check_option(po::options_description &desc, po::variables_map &vm, const string &option)
{
    if(!vm.count(option)) {
        cout << "csg_resample \n\n";
        cout << desc << endl << "parameter " << option << " is not specified\n";
        exit(1);
    }
}

int main(int argc, char** argv)
{
    string in_file, out_file, grid, spfit;
    CubicSpline spline;
    Table in, out, der;

    // program options
    po::options_description desc("Allowed options");

    desc.add_options()
      ("in", po::value<string>(&in_file), "table to read")
      ("out", po::value<string>(&out_file), "table to write")
      ("derivative", po::value<string>(), "table to write")
      ("grid", po::value<string>(&grid), "new grid spacing (min:step:max)")
      ("spfit", po::value<string>(&spfit), "specify spline fit grid. if option is not specified, normal spline interpolation is performed")
      //("bc", po::)
      ("help", "options file for coarse graining");

    po::variables_map vm;
    try {
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);
    }
    catch(po::error err) {
        cout << "error parsing command line: " << err.what() << endl;
        return -1;
    }

    // does the user want help?
    if (vm.count("help")) {
        help_text();
        cout << desc << endl;
        return 0;
    }

    check_option(desc, vm, "in");
    check_option(desc, vm, "out");
    check_option(desc, vm, "grid");

    double min, max, step;
    {
        Tokenizer tok(grid, ":");
        vector<string> toks;
        tok.ToVector(toks);
        if(toks.size()!=3) {
            cout << "wrong range format, use min:step:max\n";
            return 1;
        }
        min = boost::lexical_cast<double>(toks[0]);
        step = boost::lexical_cast<double>(toks[1]);
        max = boost::lexical_cast<double>(toks[2]);
    }

    in.Load(in_file);
    spline.setBC(CubicSpline::splineNormal);

    if (vm.count("spfit")) {
        Tokenizer tok(spfit, ":");
        vector<string> toks;
        tok.ToVector(toks);
        if(toks.size()!=3) {
            cout << "wrong range format in spfit, use min:step:max\n";
            return 1;
        }
        double sp_min, sp_max, sp_step;
        sp_min = boost::lexical_cast<double>(toks[0]);
        sp_step = boost::lexical_cast<double>(toks[1]);
        sp_max = boost::lexical_cast<double>(toks[2]);
        cout << "doing spline fit " << sp_min << ":" << sp_step << ":" << sp_max << endl;
        spline.GenerateGrid(sp_min, sp_max, sp_step);

        spline.Fit(in.x(), in.y());
    } else {
        spline.Interpolate(in.x(), in.y());
    }

    out.GenerateGridSpacing(min, max, step);
    spline.Calculate(out.x(), out.y());

    out.y() = out.y();
    out.flags() = ub::scalar_vector<double>(out.flags().size(), 'o');

    int i=0;
    for(i=0; out.x(i) < in.x(0) && i<out.size(); ++i);

    int j=0;
    for(;i < out.size(); ++i) {
        for(; j < in.size(); ++j)
            if(in.x(j) >= out.x(i))
                break;
        if(in.size() == j) break;
        out.flags(i) = in.flags(j);
    }

    out.Save(out_file);

    if (vm.count("derivative")) {
        der.GenerateGridSpacing(min, max, step);
        der.flags() = ub::scalar_vector<double>(der.flags().size(), 'o');
        spline.CalculateDerivative(der.x(), der.y());
        der.Save(vm["derivative"].as<string>());
    }
    return 0;
}

<|endoftext|>