<commit_before>/*
 * Convert an input and an output pipe to a duplex socket.
 *
 * This code is used in the test cases to convert stdin/stdout to a
 * single socket.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "duplex.hxx"
#include "system/fd-util.h"
#include "system/fd_util.h"
#include "event/event2.h"
#include "buffered_io.hxx"
#include "pool.hxx"
#include "fb_pool.hxx"
#include "SliceFifoBuffer.hxx"

#include <inline/compiler.h>
#include <daemon/log.h>

#include <sys/socket.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>

struct duplex {
    int read_fd;
    int write_fd;
    int sock_fd;
    bool sock_eof;

    SliceFifoBuffer from_read, to_write;

    struct event2 read_event, write_event, sock_event;
};

static void
duplex_close(struct duplex *duplex)
{
    if (duplex->read_fd >= 0) {
        event2_set(&duplex->read_event, 0);

        if (duplex->read_fd > 2)
            close(duplex->read_fd);

        duplex->read_fd = -1;
    }

    if (duplex->write_fd >= 0) {
        event2_set(&duplex->write_event, 0);

        if (duplex->write_fd > 2)
            close(duplex->write_fd);

        duplex->write_fd = -1;
    }

    if (duplex->sock_fd >= 0) {
        event2_set(&duplex->sock_event, 0);
        event2_commit(&duplex->sock_event);

        close(duplex->sock_fd);
        duplex->sock_fd = -1;
    }

    duplex->from_read.Free(fb_pool_get());
    duplex->to_write.Free(fb_pool_get());
}

static bool
duplex_check_close(struct duplex *duplex)
{
    if (duplex->read_fd < 0 && duplex->sock_eof &&
        duplex->from_read.IsEmpty() &&
        duplex->to_write.IsEmpty()) {
        duplex_close(duplex);
        return true;
    } else
        return false;
}

static void
read_event_callback(int fd, short event gcc_unused, void *ctx)
{
    struct duplex *duplex = (struct duplex *)ctx;

    assert((event & EV_READ) != 0);

    event2_reset(&duplex->read_event);

    ssize_t nbytes = read_to_buffer(fd, duplex->from_read, INT_MAX);
    if (nbytes == -1) {
        daemon_log(1, "failed to read: %s\n", strerror(errno));
        duplex_close(duplex);
        return;
    }

    if (nbytes == 0) {
        close(fd);
        duplex->read_fd = -1;
        if (duplex_check_close(duplex))
            return;
    }

    if (nbytes > 0)
        event2_or(&duplex->sock_event, EV_WRITE);

    if (duplex->read_fd >= 0 && !duplex->from_read.IsFull())
        event2_or(&duplex->read_event, EV_READ);
}

static void
write_event_callback(int fd, short event gcc_unused, void *ctx)
{
    struct duplex *duplex = (struct duplex *)ctx;

    assert((event & EV_WRITE) != 0);

    event2_reset(&duplex->write_event);

    ssize_t nbytes = write_from_buffer(fd, duplex->to_write);
    if (nbytes == -1) {
        duplex_close(duplex);
        return;
    }

    if (nbytes > 0 && !duplex->sock_eof)
        event2_or(&duplex->sock_event, EV_READ);

    if (!duplex->to_write.IsEmpty())
        event2_or(&duplex->write_event, EV_WRITE);
}

static void
sock_event_callback(int fd, short event, void *ctx)
{
    struct duplex *duplex = (struct duplex *)ctx;

    event2_lock(&duplex->sock_event);
    event2_occurred_persist(&duplex->sock_event, event);

    if ((event & EV_READ) != 0) {
        ssize_t nbytes = recv_to_buffer(fd, duplex->to_write, INT_MAX);
        if (nbytes == -1) {
            daemon_log(1, "failed to read: %s\n", strerror(errno));
            duplex_close(duplex);
            return;
        }

        if (nbytes == 0) {
            duplex->sock_eof = true;
            if (duplex_check_close(duplex))
                return;
        }

        if (likely(nbytes > 0))
            event2_or(&duplex->write_event, EV_WRITE);

        if (!duplex->to_write.IsFull())
            event2_or(&duplex->sock_event, EV_READ);
    }

    if ((event & EV_WRITE) != 0) {
        ssize_t nbytes = send_from_buffer(fd, duplex->from_read);
        if (nbytes == -1) {
            duplex_close(duplex);
            return;
        }

        if (nbytes > 0 && duplex->read_fd >= 0)
            event2_or(&duplex->read_event, EV_READ);

        if (!duplex->from_read.IsEmpty())
            event2_or(&duplex->sock_event, EV_WRITE);
    }

    event2_unlock(&duplex->sock_event);
}

int
duplex_new(struct pool *pool, int read_fd, int write_fd)
{
    assert(pool != nullptr);
    assert(read_fd >= 0);
    assert(write_fd >= 0);

    int fds[2];
    if (socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, fds) < 0)
        return -1;

    if (fd_set_nonblock(fds[1], 1) < 0) {
        int save_errno = errno;
        close(fds[0]);
        close(fds[1]);
        errno = save_errno;
        return -1;
    }

    auto duplex = NewFromPool<struct duplex>(*pool);
    duplex->read_fd = read_fd;
    duplex->write_fd = write_fd;
    duplex->sock_fd = fds[0];
    duplex->sock_eof = false;

    duplex->from_read.Allocate(fb_pool_get());
    duplex->to_write.Allocate(fb_pool_get());

    event2_init(&duplex->read_event, read_fd,
                read_event_callback, duplex, nullptr);
    event2_set(&duplex->read_event, EV_READ);

    event2_init(&duplex->write_event, write_fd,
                write_event_callback, duplex, nullptr);

    event2_init(&duplex->sock_event, duplex->sock_fd,
                sock_event_callback, duplex, nullptr);
    event2_persist(&duplex->sock_event);
    event2_set(&duplex->sock_event, EV_READ);

    return fds[1];
}
<commit_msg>duplex: upper case struct name<commit_after>/*
 * Convert an input and an output pipe to a duplex socket.
 *
 * This code is used in the test cases to convert stdin/stdout to a
 * single socket.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "duplex.hxx"
#include "system/fd-util.h"
#include "system/fd_util.h"
#include "event/event2.h"
#include "buffered_io.hxx"
#include "pool.hxx"
#include "fb_pool.hxx"
#include "SliceFifoBuffer.hxx"

#include <inline/compiler.h>
#include <daemon/log.h>

#include <sys/socket.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>

struct Duplex {
    int read_fd;
    int write_fd;
    int sock_fd;
    bool sock_eof;

    SliceFifoBuffer from_read, to_write;

    struct event2 read_event, write_event, sock_event;
};

static void
duplex_close(Duplex *duplex)
{
    if (duplex->read_fd >= 0) {
        event2_set(&duplex->read_event, 0);

        if (duplex->read_fd > 2)
            close(duplex->read_fd);

        duplex->read_fd = -1;
    }

    if (duplex->write_fd >= 0) {
        event2_set(&duplex->write_event, 0);

        if (duplex->write_fd > 2)
            close(duplex->write_fd);

        duplex->write_fd = -1;
    }

    if (duplex->sock_fd >= 0) {
        event2_set(&duplex->sock_event, 0);
        event2_commit(&duplex->sock_event);

        close(duplex->sock_fd);
        duplex->sock_fd = -1;
    }

    duplex->from_read.Free(fb_pool_get());
    duplex->to_write.Free(fb_pool_get());
}

static bool
duplex_check_close(Duplex *duplex)
{
    if (duplex->read_fd < 0 && duplex->sock_eof &&
        duplex->from_read.IsEmpty() &&
        duplex->to_write.IsEmpty()) {
        duplex_close(duplex);
        return true;
    } else
        return false;
}

static void
read_event_callback(int fd, short event gcc_unused, void *ctx)
{
    Duplex *duplex = (Duplex *)ctx;

    assert((event & EV_READ) != 0);

    event2_reset(&duplex->read_event);

    ssize_t nbytes = read_to_buffer(fd, duplex->from_read, INT_MAX);
    if (nbytes == -1) {
        daemon_log(1, "failed to read: %s\n", strerror(errno));
        duplex_close(duplex);
        return;
    }

    if (nbytes == 0) {
        close(fd);
        duplex->read_fd = -1;
        if (duplex_check_close(duplex))
            return;
    }

    if (nbytes > 0)
        event2_or(&duplex->sock_event, EV_WRITE);

    if (duplex->read_fd >= 0 && !duplex->from_read.IsFull())
        event2_or(&duplex->read_event, EV_READ);
}

static void
write_event_callback(int fd, short event gcc_unused, void *ctx)
{
    Duplex *duplex = (Duplex *)ctx;

    assert((event & EV_WRITE) != 0);

    event2_reset(&duplex->write_event);

    ssize_t nbytes = write_from_buffer(fd, duplex->to_write);
    if (nbytes == -1) {
        duplex_close(duplex);
        return;
    }

    if (nbytes > 0 && !duplex->sock_eof)
        event2_or(&duplex->sock_event, EV_READ);

    if (!duplex->to_write.IsEmpty())
        event2_or(&duplex->write_event, EV_WRITE);
}

static void
sock_event_callback(int fd, short event, void *ctx)
{
    Duplex *duplex = (Duplex *)ctx;

    event2_lock(&duplex->sock_event);
    event2_occurred_persist(&duplex->sock_event, event);

    if ((event & EV_READ) != 0) {
        ssize_t nbytes = recv_to_buffer(fd, duplex->to_write, INT_MAX);
        if (nbytes == -1) {
            daemon_log(1, "failed to read: %s\n", strerror(errno));
            duplex_close(duplex);
            return;
        }

        if (nbytes == 0) {
            duplex->sock_eof = true;
            if (duplex_check_close(duplex))
                return;
        }

        if (likely(nbytes > 0))
            event2_or(&duplex->write_event, EV_WRITE);

        if (!duplex->to_write.IsFull())
            event2_or(&duplex->sock_event, EV_READ);
    }

    if ((event & EV_WRITE) != 0) {
        ssize_t nbytes = send_from_buffer(fd, duplex->from_read);
        if (nbytes == -1) {
            duplex_close(duplex);
            return;
        }

        if (nbytes > 0 && duplex->read_fd >= 0)
            event2_or(&duplex->read_event, EV_READ);

        if (!duplex->from_read.IsEmpty())
            event2_or(&duplex->sock_event, EV_WRITE);
    }

    event2_unlock(&duplex->sock_event);
}

int
duplex_new(struct pool *pool, int read_fd, int write_fd)
{
    assert(pool != nullptr);
    assert(read_fd >= 0);
    assert(write_fd >= 0);

    int fds[2];
    if (socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, fds) < 0)
        return -1;

    if (fd_set_nonblock(fds[1], 1) < 0) {
        int save_errno = errno;
        close(fds[0]);
        close(fds[1]);
        errno = save_errno;
        return -1;
    }

    auto duplex = NewFromPool<Duplex>(*pool);
    duplex->read_fd = read_fd;
    duplex->write_fd = write_fd;
    duplex->sock_fd = fds[0];
    duplex->sock_eof = false;

    duplex->from_read.Allocate(fb_pool_get());
    duplex->to_write.Allocate(fb_pool_get());

    event2_init(&duplex->read_event, read_fd,
                read_event_callback, duplex, nullptr);
    event2_set(&duplex->read_event, EV_READ);

    event2_init(&duplex->write_event, write_fd,
                write_event_callback, duplex, nullptr);

    event2_init(&duplex->sock_event, duplex->sock_fd,
                sock_event_callback, duplex, nullptr);
    event2_persist(&duplex->sock_event);
    event2_set(&duplex->sock_event, EV_READ);

    return fds[1];
}
<|endoftext|>


<commit_before>#include "fast++.hpp"
#include <vif/core/main.hpp>

const char* fastpp_version = "1.2";

const constexpr uint_t grid_id::z;
const constexpr uint_t grid_id::av;
const constexpr uint_t grid_id::age;
const constexpr uint_t grid_id::metal;
const constexpr uint_t grid_id::custom;

const constexpr uint_t prop_id::scale;
const constexpr uint_t prop_id::spec_scale;
const constexpr uint_t prop_id::mass;
const constexpr uint_t prop_id::sfr;
const constexpr uint_t prop_id::ssfr;
const constexpr uint_t prop_id::ldust;
const constexpr uint_t prop_id::lion;
const constexpr uint_t prop_id::mform;
const constexpr uint_t prop_id::custom;

const constexpr uint_t log_style::none;
const constexpr uint_t log_style::decimal;
const constexpr uint_t log_style::abmag;

int vif_main(int argc, char* argv[]) {
    std::string param_file = (argc >= 2 ? argv[1] : "fast.param");

    // Read input data
    options_t opts;
    input_state_t input;
    if (!read_input(opts, input, param_file)) {
        return 1;
    }

    // Initialize the grid
    output_state_t output;
    gridder_t gridder(opts, input, output);
    if (!gridder.check_options()) {
        return 1;
    }

    if (!opts.make_seds.empty()) {
        // Write SEDs if asked, then terminate
        gridder.write_seds();
        return 0;
    }

    if (gridder.read_from_cache && opts.parallel == parallel_choice::generators &&
        opts.n_thread > 0) {
        if (opts.verbose) {
            note("using cache, switched parallel execution from 'generators' to 'models'");
        }

        opts.parallel = parallel_choice::models;
    }

    // Initizalize the fitter
    fitter_t fitter(opts, input, gridder, output);

    // Build/read the grid and fit galaxies
    if (!gridder.build_and_send(fitter)) {
        return 1;
    }

    // Compile results
    fitter.find_best_fits();

    // Write output to disk
    write_output(opts, input, gridder, fitter, output);

    return 0;
}
<commit_msg>Increased version number<commit_after>#include "fast++.hpp"
#include <vif/core/main.hpp>

const char* fastpp_version = "1.3-git";

const constexpr uint_t grid_id::z;
const constexpr uint_t grid_id::av;
const constexpr uint_t grid_id::age;
const constexpr uint_t grid_id::metal;
const constexpr uint_t grid_id::custom;

const constexpr uint_t prop_id::scale;
const constexpr uint_t prop_id::spec_scale;
const constexpr uint_t prop_id::mass;
const constexpr uint_t prop_id::sfr;
const constexpr uint_t prop_id::ssfr;
const constexpr uint_t prop_id::ldust;
const constexpr uint_t prop_id::lion;
const constexpr uint_t prop_id::mform;
const constexpr uint_t prop_id::custom;

const constexpr uint_t log_style::none;
const constexpr uint_t log_style::decimal;
const constexpr uint_t log_style::abmag;

int vif_main(int argc, char* argv[]) {
    std::string param_file = (argc >= 2 ? argv[1] : "fast.param");

    // Read input data
    options_t opts;
    input_state_t input;
    if (!read_input(opts, input, param_file)) {
        return 1;
    }

    // Initialize the grid
    output_state_t output;
    gridder_t gridder(opts, input, output);
    if (!gridder.check_options()) {
        return 1;
    }

    if (!opts.make_seds.empty()) {
        // Write SEDs if asked, then terminate
        gridder.write_seds();
        return 0;
    }

    if (gridder.read_from_cache && opts.parallel == parallel_choice::generators &&
        opts.n_thread > 0) {
        if (opts.verbose) {
            note("using cache, switched parallel execution from 'generators' to 'models'");
        }

        opts.parallel = parallel_choice::models;
    }

    // Initizalize the fitter
    fitter_t fitter(opts, input, gridder, output);

    // Build/read the grid and fit galaxies
    if (!gridder.build_and_send(fitter)) {
        return 1;
    }

    // Compile results
    fitter.find_best_fits();

    // Write output to disk
    write_output(opts, input, gridder, fitter, output);

    return 0;
}
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

#include "mitkPASpectralUnmixingFilterBase.h"

// Includes for AddEnmemberMatrix
#include "mitkPAPropertyCalculator.h"
#include <eigen3/Eigen/Dense>

// ImageAccessor
#include <mitkImageReadAccessor.h>
#include <mitkImageWriteAccessor.h>

mitk::pa::SpectralUnmixingFilterBase::SpectralUnmixingFilterBase()
{
  this->SetNumberOfIndexedOutputs(4);// find solution

  for (unsigned int i = 0; i<GetNumberOfIndexedOutputs(); i++)
  {
    this->SetNthOutput(i, mitk::Image::New());
  }

  m_PropertyCalculatorEigen = mitk::pa::PropertyCalculator::New();
}

mitk::pa::SpectralUnmixingFilterBase::~SpectralUnmixingFilterBase()
{

}

void mitk::pa::SpectralUnmixingFilterBase::AddWavelength(int wavelength)
{
  m_Wavelength.push_back(wavelength);
}

void mitk::pa::SpectralUnmixingFilterBase::AddChromophore(mitk::pa::PropertyCalculator::ChromophoreType chromophore)
{
  m_Chromophore.push_back(chromophore);
}

void mitk::pa::SpectralUnmixingFilterBase::GenerateData()
{
  MITK_INFO << "GENERATING DATA..";

  // Get input image
  mitk::Image::Pointer input = GetInput(0);

  unsigned int xDim = input->GetDimensions()[0];
  unsigned int yDim = input->GetDimensions()[1];
  unsigned int zDim = input->GetDimensions()[2];
  unsigned int size = xDim * yDim * zDim;

  MITK_INFO << "x dimension: " << xDim;
  MITK_INFO << "y dimension: " << yDim;
  MITK_INFO << "z dimension: " << zDim;

  InitializeOutputs();

  auto EndmemberMatrix = CalculateEndmemberMatrix(m_Chromophore, m_Wavelength); //Eigen Endmember Matrix

  // Copy input image into array
  mitk::ImageReadAccessor readAccess(input);

  const float* inputDataArray = ((const float*)readAccess.GetData());

  CheckPreConditions(size, zDim, inputDataArray);

  /* READ OUT INPUTARRAY
  MITK_INFO << "Info Array:";
  int numberOfPixels= 6;
  for (int i=0; i< numberOfPixels; ++i)
    MITK_INFO << inputDataArray[i];/**/

  // test to see pixel values @ txt file
  ofstream myfile;
  myfile.open("PASpectralUnmixingPixelValues.txt");

  //loop over every pixel @ x,y plane
  for (unsigned int x = 0; x < xDim; x++)
  {
    for (unsigned int y = 0; y < yDim; y++)
    {
      Eigen::VectorXf inputVector(zDim);
      for (unsigned int z = 0; z < zDim; z++)
      {
        // Get pixel value of pixel x,y @ wavelength z
        unsigned int pixelNumber = (xDim*yDim*z) + x * yDim + y;
        auto pixel = inputDataArray[pixelNumber];

        //MITK_INFO << "Pixel_values: " << pixel;

        // dummy values for pixel for testing purposes
        //float pixel = rand();

        //write all wavelength absorbtion values for one(!) pixel to a vector
        inputVector[z] = pixel;
      }
      Eigen::VectorXf resultVector = SpectralUnmixingAlgorithm(EndmemberMatrix, inputVector);
      //Eigen::VectorXf resultVector = SpectralUnmixingAlgorithm(m_Chromophore, inputVector);

      // write output
      for (int outputIdx = 0; outputIdx < GetNumberOfIndexedOutputs(); ++outputIdx)
      {
        auto output = GetOutput(outputIdx);
        mitk::ImageWriteAccessor writeOutput(output);
        float* writeBuffer = (float *)writeOutput.GetData();
        writeBuffer[x*yDim + y] = resultVector[outputIdx];
      }
      myfile << "Input Pixel(x,y): " << x << "," << y << "\n" << inputVector << "\n";
      myfile << "Result: "  << "\n HbO2: " << resultVector[0] << "\n Hb: " << resultVector[1] << "\n Mel: "
        << resultVector[2] << "Result vector size" << resultVector.size() << "\n";
    }
  }
  MITK_INFO << "GENERATING DATA...[DONE]";
  myfile.close();
}

void mitk::pa::SpectralUnmixingFilterBase::CheckPreConditions(unsigned int size, unsigned int NumberOfInputImages, const float* inputDataArray)
{
  // Checking if number of Inputs == added wavelengths
  if (m_Wavelength.size() != NumberOfInputImages)
    mitkThrow() << "CHECK INPUTS! WAVELENGTHERROR";

  // Checking if number of wavelengths >= number of chromophores
  if (m_Chromophore.size() > m_Wavelength.size())
    mitkThrow() << "PRESS 'IGNORE' AND ADD MORE WAVELENGTHS!";

  // Checking if pixel type is float
  int maxPixel = size;
  for (int i = 0; i < maxPixel; ++i)
  {
    if (typeid(inputDataArray[i]).name() != typeid(float).name())
    {
      mitkThrow() << "PIXELTYPE ERROR! FLOAT 32 REQUIRED";
    }
    else continue;
  }

  MITK_INFO << "CHECK PRECONDITIONS ...[DONE]";
}

void mitk::pa::SpectralUnmixingFilterBase::InitializeOutputs()
{
  unsigned int numberOfInputs = GetNumberOfIndexedInputs();
  unsigned int numberOfOutputs = GetNumberOfIndexedOutputs();
  //MITK_INFO << "Inputs: " << numberOfInputs << " Outputs: " << numberOfOutputs;

  //  Set dimensions (2) and pixel type (float) for output
  mitk::PixelType pixelType = mitk::MakeScalarPixelType<float>();
  const int NUMBER_OF_SPATIAL_DIMENSIONS = 2;
  auto* dimensions = new unsigned int[NUMBER_OF_SPATIAL_DIMENSIONS];
  for(unsigned int dimIdx=0; dimIdx<NUMBER_OF_SPATIAL_DIMENSIONS; dimIdx++)
  {
    dimensions[dimIdx] = GetInput()->GetDimensions()[dimIdx];
  }

  // Initialize numberOfOutput pictures with pixel type and dimensions
  for (unsigned int outputIdx = 0; outputIdx < numberOfOutputs; outputIdx++)
  {
    GetOutput(outputIdx)->Initialize(pixelType, NUMBER_OF_SPATIAL_DIMENSIONS, dimensions);
  }
}

//Matrix with #chromophores colums and #wavelengths rows
//so Matrix Element (i,j) contains the Absorbtion of chromophore j @ wavelength i
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> mitk::pa::SpectralUnmixingFilterBase::CalculateEndmemberMatrix(
  std::vector<mitk::pa::PropertyCalculator::ChromophoreType> m_Chromophore, std::vector<int> m_Wavelength)
{
  unsigned int numberOfChromophores = m_Chromophore.size(); //columns
  unsigned int numberOfWavelengths = m_Wavelength.size(); //rows
  Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> EndmemberMatrixEigen(numberOfWavelengths, numberOfChromophores);

  for (unsigned int j = 0; j < numberOfChromophores; ++j)
  {
    if (m_Chromophore[j] == mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED)
    {
      for (unsigned int i = 0; i < numberOfWavelengths; ++i)
        EndmemberMatrixEigen(i, j) = propertyElement(m_Chromophore[j], m_Wavelength[i]);
    }
    else if (m_Chromophore[j] == mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED)
    {
      for (unsigned int i = 0; i < numberOfWavelengths; ++i)
        EndmemberMatrixEigen(i, j) = propertyElement(m_Chromophore[j], m_Wavelength[i]);
    }
    else if (m_Chromophore[j] == mitk::pa::PropertyCalculator::ChromophoreType::MELANIN)
    {
      for (unsigned int i = 0; i < numberOfWavelengths; ++i)
      {
        EndmemberMatrixEigen(i, j) = propertyElement(m_Chromophore[j], m_Wavelength[i]);
        MITK_INFO << "MELANIN " << EndmemberMatrixEigen(i, j);
      }
    }
    else if (m_Chromophore[j] == mitk::pa::PropertyCalculator::ChromophoreType::ONEENDMEMBER)
    {
      for (unsigned int i = 0; i < numberOfWavelengths; ++i)
        EndmemberMatrixEigen(i, j) = 1;
    }
    else
      mitkThrow() << "404 CHROMOPHORE NOT FOUND!";
  }
  MITK_INFO << "GENERATING ENMEMBERMATRIX [DONE]!";
  MITK_INFO << "endmember matrix: " << EndmemberMatrixEigen;
  return EndmemberMatrixEigen;
}

float mitk::pa::SpectralUnmixingFilterBase::propertyElement(mitk::pa::PropertyCalculator::ChromophoreType Chromophore, int Wavelength)
{
  float value = m_PropertyCalculatorEigen->GetAbsorptionForWavelength(Chromophore, Wavelength);
  if (value == 0)
    mitkThrow() << "WAVELENGTH " << Wavelength << "nm NOT SUPPORTED!";
  return value;
}
<commit_msg>add chrono.<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

#include "mitkPASpectralUnmixingFilterBase.h"

// Includes for AddEnmemberMatrix
#include "mitkPAPropertyCalculator.h"
#include <eigen3/Eigen/Dense>

// ImageAccessor
#include <mitkImageReadAccessor.h>
#include <mitkImageWriteAccessor.h>

#include <chrono>

mitk::pa::SpectralUnmixingFilterBase::SpectralUnmixingFilterBase()
{
  this->SetNumberOfIndexedOutputs(4);// find solution

  for (unsigned int i = 0; i<GetNumberOfIndexedOutputs(); i++)
  {
    this->SetNthOutput(i, mitk::Image::New());
  }

  m_PropertyCalculatorEigen = mitk::pa::PropertyCalculator::New();
}

mitk::pa::SpectralUnmixingFilterBase::~SpectralUnmixingFilterBase()
{

}

void mitk::pa::SpectralUnmixingFilterBase::AddWavelength(int wavelength)
{
  m_Wavelength.push_back(wavelength);
}

void mitk::pa::SpectralUnmixingFilterBase::AddChromophore(mitk::pa::PropertyCalculator::ChromophoreType chromophore)
{
  m_Chromophore.push_back(chromophore);
}

void mitk::pa::SpectralUnmixingFilterBase::GenerateData()
{
  MITK_INFO << "GENERATING DATA..";

  // Get input image
  mitk::Image::Pointer input = GetInput(0);

  unsigned int xDim = input->GetDimensions()[0];
  unsigned int yDim = input->GetDimensions()[1];
  unsigned int zDim = input->GetDimensions()[2];
  unsigned int size = xDim * yDim * zDim;

  MITK_INFO << "x dimension: " << xDim;
  MITK_INFO << "y dimension: " << yDim;
  MITK_INFO << "z dimension: " << zDim;

  InitializeOutputs();

  auto EndmemberMatrix = CalculateEndmemberMatrix(m_Chromophore, m_Wavelength); //Eigen Endmember Matrix

  // Copy input image into array
  mitk::ImageReadAccessor readAccess(input);

  const float* inputDataArray = ((const float*)readAccess.GetData());

  CheckPreConditions(size, zDim, inputDataArray);

  /* READ OUT INPUTARRAY
  MITK_INFO << "Info Array:";
  int numberOfPixels= 6;
  for (int i=0; i< numberOfPixels; ++i)
    MITK_INFO << inputDataArray[i];/**/

  // test to see pixel values @ txt file
  ofstream myfile;
  myfile.open("PASpectralUnmixingPixelValues.txt");

  std::chrono::steady_clock::time_point _start(std::chrono::steady_clock::now());

  //loop over every pixel @ x,y plane
  for (unsigned int x = 0; x < xDim; x++)
  {
    for (unsigned int y = 0; y < yDim; y++)
    {
      Eigen::VectorXf inputVector(zDim);
      for (unsigned int z = 0; z < zDim; z++)
      {
        // Get pixel value of pixel x,y @ wavelength z
        unsigned int pixelNumber = (xDim*yDim*z) + x * yDim + y;
        auto pixel = inputDataArray[pixelNumber];

        //MITK_INFO << "Pixel_values: " << pixel;

        // dummy values for pixel for testing purposes
        //float pixel = rand();

        //write all wavelength absorbtion values for one(!) pixel to a vector
        inputVector[z] = pixel;
      }
      Eigen::VectorXf resultVector = SpectralUnmixingAlgorithm(EndmemberMatrix, inputVector);
      //Eigen::VectorXf resultVector = SpectralUnmixingAlgorithm(m_Chromophore, inputVector);

      // write output
      for (int outputIdx = 0; outputIdx < GetNumberOfIndexedOutputs(); ++outputIdx)
      {
        auto output = GetOutput(outputIdx);
        mitk::ImageWriteAccessor writeOutput(output);
        float* writeBuffer = (float *)writeOutput.GetData();
        writeBuffer[x*yDim + y] = resultVector[outputIdx];
      }
      myfile << "Input Pixel(x,y): " << x << "," << y << "\n" << inputVector << "\n";
      myfile << "Result: "  << "\n HbO2: " << resultVector[0] << "\n Hb: " << resultVector[1] << "\n Mel: "
        << resultVector[2] << "Result vector size" << resultVector.size() << "\n";
    }
  }
  std::chrono::steady_clock::time_point _end(std::chrono::steady_clock::now());
  MITK_INFO << "GENERATING DATA...[DONE]";
  myfile.close();
  MITK_INFO << "Chrono: " << std::chrono::duration_cast<std::chrono::duration<double>>(    _end - _start).count() << "s";
}

void mitk::pa::SpectralUnmixingFilterBase::CheckPreConditions(unsigned int size, unsigned int NumberOfInputImages, const float* inputDataArray)
{
  // Checking if number of Inputs == added wavelengths
  if (m_Wavelength.size() != NumberOfInputImages)
    mitkThrow() << "CHECK INPUTS! WAVELENGTHERROR";

  // Checking if number of wavelengths >= number of chromophores
  if (m_Chromophore.size() > m_Wavelength.size())
    mitkThrow() << "PRESS 'IGNORE' AND ADD MORE WAVELENGTHS!";

  // Checking if pixel type is float
  int maxPixel = size;
  for (int i = 0; i < maxPixel; ++i)
  {
    if (typeid(inputDataArray[i]).name() != typeid(float).name())
    {
      mitkThrow() << "PIXELTYPE ERROR! FLOAT 32 REQUIRED";
    }
    else continue;
  }

  MITK_INFO << "CHECK PRECONDITIONS ...[DONE]";
}

void mitk::pa::SpectralUnmixingFilterBase::InitializeOutputs()
{
  unsigned int numberOfInputs = GetNumberOfIndexedInputs();
  unsigned int numberOfOutputs = GetNumberOfIndexedOutputs();
  //MITK_INFO << "Inputs: " << numberOfInputs << " Outputs: " << numberOfOutputs;

  //  Set dimensions (2) and pixel type (float) for output
  mitk::PixelType pixelType = mitk::MakeScalarPixelType<float>();
  const int NUMBER_OF_SPATIAL_DIMENSIONS = 2;
  auto* dimensions = new unsigned int[NUMBER_OF_SPATIAL_DIMENSIONS];
  for(unsigned int dimIdx=0; dimIdx<NUMBER_OF_SPATIAL_DIMENSIONS; dimIdx++)
  {
    dimensions[dimIdx] = GetInput()->GetDimensions()[dimIdx];
  }

  // Initialize numberOfOutput pictures with pixel type and dimensions
  for (unsigned int outputIdx = 0; outputIdx < numberOfOutputs; outputIdx++)
  {
    GetOutput(outputIdx)->Initialize(pixelType, NUMBER_OF_SPATIAL_DIMENSIONS, dimensions);
  }
}

//Matrix with #chromophores colums and #wavelengths rows
//so Matrix Element (i,j) contains the Absorbtion of chromophore j @ wavelength i
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> mitk::pa::SpectralUnmixingFilterBase::CalculateEndmemberMatrix(
  std::vector<mitk::pa::PropertyCalculator::ChromophoreType> m_Chromophore, std::vector<int> m_Wavelength)
{
  unsigned int numberOfChromophores = m_Chromophore.size(); //columns
  unsigned int numberOfWavelengths = m_Wavelength.size(); //rows
  Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> EndmemberMatrixEigen(numberOfWavelengths, numberOfChromophores);

  for (unsigned int j = 0; j < numberOfChromophores; ++j)
  {
    if (m_Chromophore[j] == mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED)
    {
      for (unsigned int i = 0; i < numberOfWavelengths; ++i)
        EndmemberMatrixEigen(i, j) = propertyElement(m_Chromophore[j], m_Wavelength[i]);
    }
    else if (m_Chromophore[j] == mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED)
    {
      for (unsigned int i = 0; i < numberOfWavelengths; ++i)
        EndmemberMatrixEigen(i, j) = propertyElement(m_Chromophore[j], m_Wavelength[i]);
    }
    else if (m_Chromophore[j] == mitk::pa::PropertyCalculator::ChromophoreType::MELANIN)
    {
      for (unsigned int i = 0; i < numberOfWavelengths; ++i)
      {
        EndmemberMatrixEigen(i, j) = propertyElement(m_Chromophore[j], m_Wavelength[i]);
        MITK_INFO << "MELANIN " << EndmemberMatrixEigen(i, j);
      }
    }
    else if (m_Chromophore[j] == mitk::pa::PropertyCalculator::ChromophoreType::ONEENDMEMBER)
    {
      for (unsigned int i = 0; i < numberOfWavelengths; ++i)
        EndmemberMatrixEigen(i, j) = 1;
    }
    else
      mitkThrow() << "404 CHROMOPHORE NOT FOUND!";
  }
  MITK_INFO << "GENERATING ENMEMBERMATRIX [DONE]!";
  MITK_INFO << "endmember matrix: " << EndmemberMatrixEigen;
  return EndmemberMatrixEigen;
}

float mitk::pa::SpectralUnmixingFilterBase::propertyElement(mitk::pa::PropertyCalculator::ChromophoreType Chromophore, int Wavelength)
{
  float value = m_PropertyCalculatorEigen->GetAbsorptionForWavelength(Chromophore, Wavelength);
  if (value == 0)
    mitkThrow() << "WAVELENGTH " << Wavelength << "nm NOT SUPPORTED!";
  return value;
}
<|endoftext|>


<commit_before>// Time:  O(nlogn)
// Space: O(n)

// BST solution.
class Solution {
public:
    /**
     * @param buildings: A list of lists of integers
     * @return: Find the outline of those buildings
     */
    vector<vector<int> > buildingOutline(vector<vector<int> > &buildings) {
        unordered_map<int, vector<int>> start_point_to_heights;
        unordered_map<int, vector<int>> end_point_to_heights;
        set<int> points;

        for (int i = 0; i < buildings.size(); ++i) {
            start_point_to_heights[buildings[i][0]].emplace_back(buildings[i][2]);
            end_point_to_heights[buildings[i][1]].emplace_back(buildings[i][2]);
            points.emplace(buildings[i][0]);
            points.emplace(buildings[i][1]);
        }

        vector<vector<int>> res;
        map<int, int> height_to_count;
        int curr_start = -1;
        int curr_max = 0;
        // Enumerate each point in increasing order.
        for (auto it = points.begin(); it != points.end(); ++it) {
            vector<int> start_point_heights = start_point_to_heights[*it];
            vector<int> end_point_heights = end_point_to_heights[*it];

            for (int i = 0; i < start_point_heights.size(); ++i) {
                ++height_to_count[start_point_heights[i]];
            }

            for (int i = 0; i < end_point_heights.size(); ++i) {
                --height_to_count[end_point_heights[i]];
                if (height_to_count[end_point_heights[i]] == 0) {
                    height_to_count.erase(end_point_heights[i]);
                }
            }

            if (height_to_count.empty() || curr_max != height_to_count.rbegin()->first) {
                if (curr_max > 0) {
                    res.emplace_back(move(vector<int>{curr_start, *it, curr_max}));
                }
                curr_start = *it;
                curr_max = height_to_count.empty() ? 0 : height_to_count.rbegin()->first;
            }
        }
        return res;
    }
};

// Time:  O(nlogn)
// Space: O(n)
// Divide and conquer solution.
class Solution2 {
public:
    enum {start, end, height};
    /**
     * @param buildings: A list of lists of integers
     * @return: Find the outline of those buildings
     */
    vector<vector<int> > buildingOutline(vector<vector<int> > &buildings) {
        return ComputeSkylineInInterval(buildings, 0, buildings.size());
    }

    // Divide and Conquer.
    vector<vector<int>> ComputeSkylineInInterval(const vector<vector<int>>& buildings,
                                                 int left_endpoint, int right_endpoint) {
        if (right_endpoint - left_endpoint <= 1) {  // 0 or 1 skyline, just copy it.
            return {buildings.cbegin() + left_endpoint,
                    buildings.cbegin() + right_endpoint};
        }
        int mid = left_endpoint + ((right_endpoint - left_endpoint) / 2);
        auto left_skyline = move(ComputeSkylineInInterval(buildings, left_endpoint, mid));
        auto right_skyline = move(ComputeSkylineInInterval(buildings, mid, right_endpoint));
        return MergeSkylines(left_skyline, right_skyline);
    }

    // Merge Sort
    vector<vector<int>> MergeSkylines(vector<vector<int>>& left_skyline, vector<vector<int>>& right_skyline) {
        int i = 0, j = 0;
        vector<vector<int>> merged;

        while (i < left_skyline.size() && j < right_skyline.size()) {
            if (left_skyline[i][end] < right_skyline[j][start]) {
                merged.emplace_back(move(left_skyline[i++]));
            } else if (right_skyline[j][end] < left_skyline[i][start]) {
                merged.emplace_back(move(right_skyline[j++]));
            } else if (left_skyline[i][start] <= right_skyline[j][start]) {
                MergeIntersectSkylines(merged, left_skyline[i], i,
                                       right_skyline[j], j);
            } else {  // left_skyline[i][start] > right_skyline[j][start].
                MergeIntersectSkylines(merged, right_skyline[j], j,
                                       left_skyline[i], i);
            }
        }

        // Insert the remaining skylines.
        merged.insert(merged.end(), left_skyline.begin() + i, left_skyline.end());
        merged.insert(merged.end(), right_skyline.begin() + j, right_skyline.end());
        return merged;
    }

    // a[start] <= b[start]
    void MergeIntersectSkylines(vector<vector<int>>& merged, vector<int>& a, int& a_idx,
                                vector<int>& b, int& b_idx) {
        if (a[end] <= b[end]) {
            if (a[height] > b[height]) {  // |aaa|
                if (b[end] != a[end]) {   // |abb|b
                    b[start] = a[end];
                    merged.emplace_back(move(a)), ++a_idx;
                } else {        // aaa
                    ++b_idx;    // abb
                }
            } else if (a[height] == b[height]) { // abb
                b[start] = a[start], ++a_idx;    // abb
            } else {  // a[height] < b[height].
                if (a[start] != b[start]) {                                           //    bb
                    merged.emplace_back(move(vector<int>{a[start], b[start], a[height]}));  // |a|bb
                }
                ++a_idx;
            }
        } else {  // a[end] > b[end].
            if (a[height] >= b[height]) {  // aaaa
                ++b_idx;                   // abba
            } else {
                //    |bb|
                // |a||bb|a
                if (a[start] != b[start]) {
                    merged.emplace_back(move(vector<int>{a[start], b[start], a[height]}));
                }
                a[start] = b[end];
                merged.emplace_back(move(b)), ++b_idx;
            }
        }
    }
};
<commit_msg>Update building-outline.cpp<commit_after>// Time:  O(nlogn)
// Space: O(n)

// BST solution.
class Solution {
public:
    /**
     * @param buildings: A list of lists of integers
     * @return: Find the outline of those buildings
     */
    vector<vector<int> > buildingOutline(vector<vector<int> > &buildings) {
        unordered_map<int, vector<int>> start_point_to_heights;
        unordered_map<int, vector<int>> end_point_to_heights;
        set<int> points;

        for (int i = 0; i < buildings.size(); ++i) {
            start_point_to_heights[buildings[i][0]].emplace_back(buildings[i][2]);
            end_point_to_heights[buildings[i][1]].emplace_back(buildings[i][2]);
            points.emplace(buildings[i][0]);
            points.emplace(buildings[i][1]);
        }

        vector<vector<int>> res;
        map<int, int> height_to_count;
        int curr_start = -1;
        int curr_max = 0;
        // Enumerate each point in increasing order.
        for (auto it = points.begin(); it != points.end(); ++it) {
            vector<int> start_point_heights = start_point_to_heights[*it];
            vector<int> end_point_heights = end_point_to_heights[*it];

            for (int i = 0; i < start_point_heights.size(); ++i) {
                ++height_to_count[start_point_heights[i]];
            }

            for (int i = 0; i < end_point_heights.size(); ++i) {
                --height_to_count[end_point_heights[i]];
                if (height_to_count[end_point_heights[i]] == 0) {
                    height_to_count.erase(end_point_heights[i]);
                }
            }

            if (height_to_count.empty() || curr_max != height_to_count.rbegin()->first) {
                if (curr_max > 0) {
                    res.emplace_back(move(vector<int>{curr_start, *it, curr_max}));
                }
                curr_start = *it;
                curr_max = height_to_count.empty() ? 0 : height_to_count.rbegin()->first;
            }
        }
        return res;
    }
};

// Time:  O(nlogn)
// Space: O(n)
// Divide and conquer solution.
class Solution2 {
public:
    enum {start, end, height};
    /**
     * @param buildings: A list of lists of integers
     * @return: Find the outline of those buildings
     */
    vector<vector<int> > buildingOutline(vector<vector<int> > &buildings) {
        return ComputeSkylineInInterval(buildings, 0, buildings.size());
    }

    // Divide and Conquer.
    vector<vector<int>> ComputeSkylineInInterval(const vector<vector<int>>& buildings,
                                                 int left_endpoint, int right_endpoint) {
        if (right_endpoint - left_endpoint <= 1) {  // 0 or 1 skyline, just copy it.
            return {buildings.cbegin() + left_endpoint,
                    buildings.cbegin() + right_endpoint};
        }
        int mid = left_endpoint + ((right_endpoint - left_endpoint) / 2);
        auto left_skyline = move(ComputeSkylineInInterval(buildings, left_endpoint, mid));
        auto right_skyline = move(ComputeSkylineInInterval(buildings, mid, right_endpoint));
        return MergeSkylines(left_skyline, right_skyline);
    }

    // Merge Sort
    vector<vector<int>> MergeSkylines(vector<vector<int>>& left_skyline, vector<vector<int>>& right_skyline) {
        int i = 0, j = 0;
        vector<vector<int>> merged;

        while (i < left_skyline.size() && j < right_skyline.size()) {
            if (left_skyline[i][end] < right_skyline[j][start]) {
                merged.emplace_back(move(left_skyline[i++]));
            } else if (right_skyline[j][end] < left_skyline[i][start]) {
                merged.emplace_back(move(right_skyline[j++]));
            } else if (left_skyline[i][start] <= right_skyline[j][start]) {
                MergeIntersectSkylines(merged, left_skyline[i], i,
                                       right_skyline[j], j);
            } else {  // left_skyline[i][start] > right_skyline[j][start].
                MergeIntersectSkylines(merged, right_skyline[j], j,
                                       left_skyline[i], i);
            }
        }

        // Insert the remaining skylines.
        merged.insert(merged.end(), left_skyline.begin() + i, left_skyline.end());
        merged.insert(merged.end(), right_skyline.begin() + j, right_skyline.end());
        return merged;
    }

    // a[start] <= b[start]
    void MergeIntersectSkylines(vector<vector<int>>& merged, vector<int>& a, int& a_idx,
                                vector<int>& b, int& b_idx) {
        if (a[end] <= b[end]) {
            if (a[height] > b[height]) {  // |aaa|
                if (b[end] != a[end]) {   // |abb|b
                    b[start] = a[end];
                    merged.emplace_back(move(a)), ++a_idx;
                } else {        // aaa
                    ++b_idx;    // abb
                }
            } else if (a[height] == b[height]) { // abb
                b[start] = a[start], ++a_idx;    // abb
            } else {  // a[height] < b[height].
                if (a[start] != b[start]) {                                                 //    bb
                    merged.emplace_back(move(vector<int>{a[start], b[start], a[height]}));  // |a|bb
                }
                ++a_idx;
            }
        } else {  // a[end] > b[end].
            if (a[height] >= b[height]) {  // aaaa
                ++b_idx;                   // abba
            } else {
                //    |bb|
                // |a||bb|a
                if (a[start] != b[start]) {
                    merged.emplace_back(move(vector<int>{a[start], b[start], a[height]}));
                }
                a[start] = b[end];
                merged.emplace_back(move(b)), ++b_idx;
            }
        }
    }
};
<|endoftext|>


<commit_before>// Time:  O(|V| + |E|)
// Space: O(|V| + |E|)

class Solution {
public:
    struct node {
        int parent;
        vector<int>neighbors;
    };

    bool validTree(int n, vector<pair<int, int>>& edges) {
        if (edges.size() != n - 1) {
            return false;
        } else if (n == 1) {
            return true;
        }

        unordered_map<int, node> nodes;
        for (const auto& edge : edges) {
            nodes[edge.first].neighbors.emplace_back(edge.second);
            nodes[edge.second].neighbors.emplace_back(edge.first);
        }
        if (nodes.size() != n) {
            return false;
        }

        for (int i = 0; i < n; ++i) {
            nodes[i].parent = -1;
        }

        unordered_set<int> visited;
        queue<int> q;
        q.emplace(0);
        while (!q.empty()) {
            const int i = q.front();
            q.pop();
            visited.emplace(i);
            for (const auto& n : nodes[i].neighbors) {
                if (n != nodes[i].parent) {
                    if (visited.find(n) != visited.end()) {
                        return false;
                    } else {
                        visited.emplace(n);
                        nodes[n].parent = i;
                        q.emplace(n);
                    }
                }
            }
        }
        return true;
    }
};
<commit_msg>Update graph-valid-tree.cpp<commit_after>
// Time:  O(|V| + |E|)
// Space: O(|V| + |E|)

class Solution {
public:
    struct node {
        int parent = -1;
        vector<int>neighbors;
    };

    bool validTree(int n, vector<pair<int, int>>& edges) {
        if (edges.size() != n - 1) {
            return false;
        } else if (n == 1) {
            return true;
        }

        unordered_map<int, node> nodes;
        for (const auto& edge : edges) {
            nodes[edge.first].neighbors.emplace_back(edge.second);
            nodes[edge.second].neighbors.emplace_back(edge.first);
        }

        if (nodes.size() != n) {
            return false;
        }

        unordered_set<int> visited;
        queue<int> q;
        q.emplace(0);
        while (!q.empty()) {
            const int i = q.front();
            q.pop();
            visited.emplace(i);
            for (const auto& n : nodes[i].neighbors) {
                if (n != nodes[i].parent) {
                    if (visited.find(n) != visited.end()) {
                        return false;
                    } else {
                        visited.emplace(n);
                        nodes[n].parent = i;
                        q.emplace(n);
                    }
                }
            }
        }
        return true;
    }
};
<|endoftext|>


<commit_before>#include <rm.hpp>

#include <kdb.hpp>
#include <cmdline.hpp>
#include <print.hpp>

#include <iostream>

using namespace std;
using namespace kdb;

RemoveCommand::RemoveCommand()
{}

int RemoveCommand::execute(Cmdline const& cl)
{
	if (cl.arguments.size() != 1) throw invalid_argument("1 argument required");

	KeySet conf;
	Key x(cl.arguments[0], KEY_END);
	if (!x)
	{
		throw invalid_argument(cl.arguments[0] + " is not a valid keyname");
	}
	kdb.get(conf, x);

	if (!cl.recursive)
	{
		/* TODO crash?
		Key f = conf.lookup(x, KDB_O_POP);
		*/
		KeySet ks = conf.cut (x);

		// if (!f)
		if (ks.size() == 0)
		{
			cerr << "Did not find the key" << endl;
			return 1;
		}
	} else {
		// do recursive removing
		KeySet ks = conf.cut (x);

		if (ks.size() == 0)
		{
			cerr << "Did not find any key" << endl;
			return 1;
		}
	}

	Key n;
	kdb.set(conf, n);

	return 0;
}

RemoveCommand::~RemoveCommand()
{}
<commit_msg>fix removing of single items<commit_after>#include <rm.hpp>

#include <kdb.hpp>
#include <cmdline.hpp>
#include <print.hpp>

#include <iostream>

using namespace std;
using namespace kdb;

RemoveCommand::RemoveCommand()
{}

int RemoveCommand::execute(Cmdline const& cl)
{
	if (cl.arguments.size() != 1) throw invalid_argument("1 argument required");

	KeySet conf;
	Key x(cl.arguments[0], KEY_END);
	if (!x)
	{
		throw invalid_argument(cl.arguments[0] + " is not a valid keyname");
	}
	kdb.get(conf, x);

	if (!cl.recursive)
	{
		Key f = conf.lookup(x, KDB_O_POP);

		if (!f)
		{
			cerr << "Did not find the key" << endl;
			return 1;
		}
	} else {
		// do recursive removing
		KeySet ks = conf.cut (x);

		if (ks.size() == 0)
		{
			cerr << "Did not find any key" << endl;
			return 1;
		}
	}

	Key n;
	kdb.set(conf, n);

	return 0;
}

RemoveCommand::~RemoveCommand()
{}
<|endoftext|>


<commit_before>void k_print_line(const char* string);
void k_print(const char* string);

extern "C"
void  __attribute__ ((section ("main_section"))) kernel_main(){
    k_print("thor> ");

    return;
}

typedef unsigned int uint8_t __attribute__((__mode__(__QI__)));
typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__)));

enum vga_color {
    BLACK = 0,
    BLUE = 1,
    GREEN = 2,
    CYAN = 3,
    RED = 4,
    MAGENTA = 5,
    BROWN = 6,
    LIGHT_GREY = 7,
    DARK_GREY = 8,
    LIGHT_BLUE = 9,
    LIGHT_GREEN = 10,
    LIGHT_CYAN = 11,
    LIGHT_RED = 12,
    LIGHT_MAGENTA = 13,
    LIGHT_BROWN = 14,
    WHITE = 15,
};

long current_line = 0;
long current_column = 0;

uint8_t make_color(vga_color fg, vga_color bg){
    return fg | bg << 4;
}

uint16_t make_vga_entry(char c, uint8_t color){
    uint16_t c16 = c;
    uint16_t color16 = color;
    return c16 | color16 << 8;
}

void k_print_line(const char* string){
    k_print(string);

    current_column = 0;
    ++current_line;
}

void k_print(const char* string){
    uint16_t* vga_buffer = (uint16_t*) 0x0B8000;

    for(int i = 0; string[i] != 0; ++i){
        vga_buffer[current_line * 80 + current_column] = make_vga_entry(string[i], make_color(WHITE, BLACK));

        ++current_column;
    }

    return;
}
<commit_msg>Clean<commit_after>void k_print_line(const char* string);
void k_print(const char* string);

extern "C"
void  __attribute__ ((section ("main_section"))) kernel_main(){
    k_print("thor> ");

    //TODO Register keyword handler

    return;
}

typedef unsigned int uint8_t __attribute__((__mode__(__QI__)));
typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__)));

enum vga_color {
    BLACK = 0,
    BLUE = 1,
    GREEN = 2,
    CYAN = 3,
    RED = 4,
    MAGENTA = 5,
    BROWN = 6,
    LIGHT_GREY = 7,
    DARK_GREY = 8,
    LIGHT_BLUE = 9,
    LIGHT_GREEN = 10,
    LIGHT_CYAN = 11,
    LIGHT_RED = 12,
    LIGHT_MAGENTA = 13,
    LIGHT_BROWN = 14,
    WHITE = 15,
};

long current_line = 0;
long current_column = 0;

uint8_t make_color(vga_color fg, vga_color bg){
    return fg | bg << 4;
}

uint16_t make_vga_entry(char c, uint8_t color){
    uint16_t c16 = c;
    uint16_t color16 = color;
    return c16 | color16 << 8;
}

void k_print_line(const char* string){
    k_print(string);

    current_column = 0;
    ++current_line;
}

void k_print(const char* string){
    uint16_t* vga_buffer = (uint16_t*) 0x0B8000;

    for(int i = 0; string[i] != 0; ++i){
        vga_buffer[current_line * 80 + current_column] = make_vga_entry(string[i], make_color(WHITE, BLACK));

        ++current_column;
    }

    return;
}
<|endoftext|>


<commit_before>#include <jni.h>
#include <string>

static ln::Application* g_app = nullptr;

extern "C" ::ln::Application* LuminoCreateApplicationInstance();

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeInitialize(
    JNIEnv *env,
    jobject /* this */,
    jint width,
    jint height)
{
    ln::GlobalLogger::addLogcatAdapter();
	g_app = ::LuminoCreateApplicationInstance();
	ln::detail::ApplicationHelper::initialize(g_app);
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeUpdateFrame(
    JNIEnv *env,
    jobject /* this */)
{
	ln::detail::ApplicationHelper::processTick(g_app);
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeFinalize(
    JNIEnv *env,
    jobject /* this */)
{
	ln::detail::ApplicationHelper::finalize(g_app);
	ln::RefObjectHelper::release(g_app);
    g_app = nullptr;
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeOnSurfaceChanged(
    JNIEnv *env,
    jobject /* this */,
    jint width,
    jint height)
{
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeOnPause(
    JNIEnv *env,
    jobject /* this */)
{
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeOnResume(
    JNIEnv *env,
    jobject /* this */)
{
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeTouchesBegin(
    JNIEnv *env,
    jobject /* this */,
    jint id,
    jfloat x,
    jfloat y)
{
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeTouchesEnd(
    JNIEnv *env,
    jobject /* this */,
    jint id,
    jfloat x,
    jfloat y)
{
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeTouchesMove(
    JNIEnv *env,
    jobject /* this */,
    jintArray ids,
    jfloatArray xs,
    jfloatArray ys)
{
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeTouchesCancel(
    JNIEnv *env,
    jobject /* this */,
    jintArray ids,
    jfloatArray xs,
    jfloatArray ys)
{
}

extern "C" JNIEXPORT jboolean JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeKeyEvent(
    JNIEnv *env,
    jobject /* this */,
    jint keyCode,
    jboolean isPressed)
{
    return JNI_FALSE;
}
<commit_msg>Update tools/LuminoCLI/Templates/NativeProject/Projects/LuminoApp.Android/app/src/main/cpp/native-lib.cpp<commit_after>#include <jni.h>
#include <string>

static ln::Application* g_app = nullptr;

extern "C" ::ln::Application* LuminoCreateApplicationInstance();

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeInitialize(
    JNIEnv *env,
    jobject /* this */,
    jint width,
    jint height)
{
    ln::GlobalLogger::addLogcatAdapter();
	g_app = ::LuminoCreateApplicationInstance();
	ln::detail::ApplicationHelper::initialize(g_app);
	ln::detail::SwapChainHelper::setBackendBufferSize(ln::Engine::mainWindow()->swapChain(), width, height);
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeUpdateFrame(
    JNIEnv *env,
    jobject /* this */)
{
	ln::detail::ApplicationHelper::processTick(g_app);
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeFinalize(
    JNIEnv *env,
    jobject /* this */)
{
	ln::detail::ApplicationHelper::finalize(g_app);
	ln::RefObjectHelper::release(g_app);
    g_app = nullptr;
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeOnSurfaceChanged(
    JNIEnv *env,
    jobject /* this */,
    jint width,
    jint height)
{
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeOnPause(
    JNIEnv *env,
    jobject /* this */)
{
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeOnResume(
    JNIEnv *env,
    jobject /* this */)
{
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeTouchesBegin(
    JNIEnv *env,
    jobject /* this */,
    jint id,
    jfloat x,
    jfloat y)
{
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeTouchesEnd(
    JNIEnv *env,
    jobject /* this */,
    jint id,
    jfloat x,
    jfloat y)
{
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeTouchesMove(
    JNIEnv *env,
    jobject /* this */,
    jintArray ids,
    jfloatArray xs,
    jfloatArray ys)
{
}

extern "C" JNIEXPORT void JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeTouchesCancel(
    JNIEnv *env,
    jobject /* this */,
    jintArray ids,
    jfloatArray xs,
    jfloatArray ys)
{
}

extern "C" JNIEXPORT jboolean JNICALL
Java_org_lumino_lib_luminoapp_LuminoRenderer_nativeKeyEvent(
    JNIEnv *env,
    jobject /* this */,
    jint keyCode,
    jboolean isPressed)
{
    return JNI_FALSE;
}
<|endoftext|>


<commit_before>#ifndef _macros_hpp_INCLUDED
#define _macros_hpp_INCLUDED

// Central file for keeping (most) macros.

/*------------------------------------------------------------------------*/

// Profiling support.

#define START(P,ARGS...) \
do { \
  if (internal->profiles.P.level > internal->opts.profile) break; \
  internal->start_profiling (&internal->profiles.P, ##ARGS); \
} while (0)

#define STOP(P,ARGS...) \
do { \
  if (internal->profiles.P.level > internal->opts.profile) break; \
  internal->stop_profiling (&internal->profiles.P, ##ARGS); \
} while (0)

#define SWITCH_AND_START(F,T,P) \
do { \
  const double N = seconds (); \
  const int L = internal->opts.profile; \
  if (internal->profiles.F.level > L)  STOP (F, N); \
  if (internal->profiles.T.level > L) START (T, N); \
  if (internal->profiles.P.level > L) START (P, N); \
} while (0)

#define STOP_AND_SWITCH(P,F,T) \
do { \
  const double N = seconds (); \
  const int L = internal->opts.profile; \
  if (internal->profiles.P.level > L)  STOP (P, N); \
  if (internal->profiles.F.level > L)  STOP (F, N); \
  if (internal->profiles.T.level > L) START (T, N); \
} while (0)

/*------------------------------------------------------------------------*/

// Memory allocation with implicit memory usage updates.

#define NEW(P,T,N) \
do { (P) = new T[N], internal->inc_bytes ((N) * sizeof (T)); } while (0)

#define DEL(P,T,N) \
do { delete [] (P), internal->dec_bytes ((N) * sizeof (T)); } while (0)

#define ENLARGE(P,T,O,N) \
do { \
  T * TMP = (P); \
  NEW (P, T, N); \
  for (size_t I = 0; I < (O); I++) (P)[I] = (TMP)[I]; \
  internal->dec_bytes ((O) * sizeof (T)); \
  delete [] TMP; \
} while (0)

#define VECTOR_BYTES(V) ((V).capacity () * sizeof ((V)[0]))

/*------------------------------------------------------------------------*/

// Compact message code.

#define MSG(ARGS...) Message::print (internal, 0, ##ARGS)
#define VRB(ARGS...) Message::print (internal, 1, ##ARGS)
#define SECTION(ARGS...) Message::section (internal, ##ARGS)

/*------------------------------------------------------------------------*/

// Compact average update and initialization code for better logging.

#define UPDATE_AVG(EMA_OR_AVG,Y) \
do { EMA_OR_AVG.update (internal, (Y), #EMA_OR_AVG); } while (0)

#define INIT_EMA(E,V) \
  E = EMA (V); \
  LOG ("init " #E " EMA target alpha %g", (double) V)

#endif
<commit_msg>fixed<commit_after>#ifndef _macros_hpp_INCLUDED
#define _macros_hpp_INCLUDED

// Central file for keeping (most) macros.

/*------------------------------------------------------------------------*/

// Profiling support.

#define START(P,ARGS...) \
do { \
  if (internal->profiles.P.level > internal->opts.profile) break; \
  internal->start_profiling (&internal->profiles.P, ##ARGS); \
} while (0)

#define STOP(P,ARGS...) \
do { \
  if (internal->profiles.P.level > internal->opts.profile) break; \
  internal->stop_profiling (&internal->profiles.P, ##ARGS); \
} while (0)

#define SWITCH_AND_START(F,T,P) \
do { \
  const double N = seconds (); \
  const int L = internal->opts.profile; \
  if (internal->profiles.F.level <= L)  STOP (F, N); \
  if (internal->profiles.T.level <= L) START (T, N); \
  if (internal->profiles.P.level <= L) START (P, N); \
} while (0)

#define STOP_AND_SWITCH(P,F,T) \
do { \
  const double N = seconds (); \
  const int L = internal->opts.profile; \
  if (internal->profiles.P.level <= L)  STOP (P, N); \
  if (internal->profiles.F.level <= L)  STOP (F, N); \
  if (internal->profiles.T.level <= L) START (T, N); \
} while (0)

/*------------------------------------------------------------------------*/

// Memory allocation with implicit memory usage updates.

#define NEW(P,T,N) \
do { (P) = new T[N], internal->inc_bytes ((N) * sizeof (T)); } while (0)

#define DEL(P,T,N) \
do { delete [] (P), internal->dec_bytes ((N) * sizeof (T)); } while (0)

#define ENLARGE(P,T,O,N) \
do { \
  T * TMP = (P); \
  NEW (P, T, N); \
  for (size_t I = 0; I < (O); I++) (P)[I] = (TMP)[I]; \
  internal->dec_bytes ((O) * sizeof (T)); \
  delete [] TMP; \
} while (0)

#define VECTOR_BYTES(V) ((V).capacity () * sizeof ((V)[0]))

/*------------------------------------------------------------------------*/

// Compact message code.

#define MSG(ARGS...) Message::print (internal, 0, ##ARGS)
#define VRB(ARGS...) Message::print (internal, 1, ##ARGS)
#define SECTION(ARGS...) Message::section (internal, ##ARGS)

/*------------------------------------------------------------------------*/

// Compact average update and initialization code for better logging.

#define UPDATE_AVG(EMA_OR_AVG,Y) \
do { EMA_OR_AVG.update (internal, (Y), #EMA_OR_AVG); } while (0)

#define INIT_EMA(E,V) \
  E = EMA (V); \
  LOG ("init " #E " EMA target alpha %g", (double) V)

#endif
<|endoftext|>


<commit_before>#include <iostream>

#include <vw/Image/ImageMath.h>
#include <vw/Image/UtilityViews.h>
#include <vw/Plate/PlateFile.h>
#include <vw/Image/MaskViews.h>
#include <vw/Octave/Main.h>

#include <mvp/Config.h>
#include <mvp/MVPWorkspace.h>
#include <mvp/MVPJob.h>

#include <boost/program_options.hpp>

using namespace vw;
using namespace vw::cartography;
using namespace vw::platefile;
using namespace vw::octave;
using namespace std;
using namespace mvp;

namespace po = boost::program_options;

template <class BBoxT, class RealT, size_t DimN>
void print_bbox_helper(math::BBoxBase<BBoxT, RealT, DimN> const& bbox) {
  cout << "BBox = " << bbox << endl;
  cout << "width, height = " << bbox.width() << ", " << bbox.height() << endl;
}

int main(int argc, char* argv[])
{
  #if MVP_ENABLE_OCTAVE_SUPPORT
  start_octave_interpreter();
  #endif

  po::options_description cmd_opts("Command line options");
  cmd_opts.add_options()
    ("help,h", "Print this message")
    ("silent", "Run without outputting status")
    ("config-file,f", po::value<string>()->default_value("mvp.conf"), "Specify a pipeline configuration file")
    ("print-workspace,p", "Print information about the workspace and exit")
    ("dump-job", "Dump a jobfile")
    ("col,c", po::value<int>(), "When dumping a jobfile, column of tile to dump")
    ("row,r", po::value<int>(), "When dumping a jobfile, row of tile to dump")
    ("level,l", po::value<int>(), "When dumping a jobfile or printing the workspace, level to operate at")
    ("job", po::value<string>(), "Render a jobfile")
    ;

  po::options_description render_opts("Render Options");
  render_opts.add_options()
    ("col-start", po::value<int>(), "Col to start rendering at")
    ("col-end", po::value<int>(), "One past last col to render")
    ("row-start", po::value<int>(), "Row to start rendering at")
    ("row-end", po::value<int>(), "One past last row to render")
    ("render-level", po::value<int>(), "Level to render at")
    ;

  po::options_description mvp_opts;
  mvp_opts.add(MVPWorkspace::program_options()).add(render_opts);

  po::options_description all_opts;
  all_opts.add(cmd_opts).add(mvp_opts);

  po::variables_map vm;
  store(po::command_line_parser(argc, argv).options(all_opts).run(), vm);

  if (vm.count("help")) {
    cout << all_opts << endl;
    return 0;
  }

  ifstream ifs(vm["config-file"].as<string>().c_str());
  if (ifs) {
    store(parse_config_file(ifs, mvp_opts), vm);
  }

  notify(vm);

  MVPWorkspace work(MVPWorkspace::construct_from_program_options(vm));

  if (!vm.count("silent")) {
    cout << boolalpha << endl;
    cout << "-------------------------------------" << endl;
    cout << "Welcome to the Multiple View Pipeline" << endl;
    cout << "-------------------------------------" << endl;
    cout << endl;
    cout << "Number of images loaded = " << work.num_images() << endl;
    cout << " Equal resolution level = " << work.equal_resolution_level() << endl;
    cout << "    Equal density level = " << work.equal_density_level() << endl;
    cout << endl;
    cout << "# Workspace lonlat BBox #" << endl;
    print_bbox_helper(work.lonlat_work_area());
    cout << endl;
    cout << "# Workspace tile BBox (@ equal density level) #" << endl;
    print_bbox_helper(work.tile_work_area(work.equal_density_level()));
    if (vm.count("level")) {
      int print_level = vm["level"].as<int>();
      cout << endl;
      cout << "# Workspace tile BBox (@ level " << print_level << ") #" << endl;
      print_bbox_helper(work.tile_work_area(print_level));
    }
    cout << endl;
  }

  if (vm.count("print-workspace")) {
    return 0;
  }

  if (vm.count("dump-job")) {
    if (!vm.count("col") || !vm.count("row") || !vm.count("level")) {
      cerr << "Error: Must specify a col, row, and level to dump" << endl;
      return 1;
    }
    save_job_file(work.assemble_job(vm["col"].as<int>(), vm["row"].as<int>(), vm["level"].as<int>()));
    return 0;
  }

  int render_level = work.equal_density_level();
  if (vm.count("render-level")) {
    render_level = vm["render-level"].as<int>();
  }

  BBox2i tile_bbox(work.tile_work_area(render_level));

  if (vm.count("col-start")) {
    VW_ASSERT(vm.count("col-end"), ArgumentErr() << "col-start specified, but col-end not");
    tile_bbox.min()[0] = vm["col-start"].as<int>();
    tile_bbox.max()[0] = vm["col-end"].as<int>();
  }

  if (vm.count("row-start")) {
    VW_ASSERT(vm.count("row-end"), ArgumentErr() << "row-start specified, but col-end not");
    tile_bbox.min()[1] = vm["row-start"].as<int>();
    tile_bbox.max()[1] = vm["row-end"].as<int>();
  }

  if (!vm.count("silent")) {
    cout << "-------------------------------------" << endl;
    cout << "        Rendering Information" << endl;
    cout << "-------------------------------------" << endl;
    cout << endl;
    cout << "Render level = " << render_level << endl;
    cout << "  Use octave = " << vm["use-octave"].as<bool>() << endl;
    cout << endl;
    cout << "# Render tile BBox #" << endl;
    print_bbox_helper(tile_bbox);
    cout << endl;
    cout << "-------------------------------------" << endl;
    cout << "              Status" << endl;
    cout << "-------------------------------------" << endl;
    cout << endl;
  }

  if (vm.count("job")) {
    MVPTileResult result = mvpjob_process_tile(vm["job"].as<string>(), TerminalProgressCallback("mvp", "Processing job: "));
    write_georeferenced_image(vm["job"].as<string>() + ".tif", result.alt, result.georef);
  } else {
    boost::shared_ptr<PlateFile> pf(new PlateFile(work.result_platefile(),
                                                  work.plate_georef().map_proj(),
                                                  "MVP Result Plate",
                                                  work.plate_georef().tile_size(),
                                                  "tif", VW_PIXEL_GRAYA, VW_CHANNEL_FLOAT32));

    Transaction tid = pf->transaction_request("Post Heights", -1);

    int curr_tile = 0;
    int num_tiles = tile_bbox.width() * tile_bbox.height();
    float32 plate_min_val = numeric_limits<float32>::max(), plate_max_val = numeric_limits<float32>::min();
    for (int col = tile_bbox.min().x(); col < tile_bbox.max().x(); col++) {
      for (int row = tile_bbox.min().y(); row < tile_bbox.max().y(); row++) {
        boost::shared_ptr<ProgressCallback> progress;

        if (!vm.count("silent")) {
          ostringstream status;
          status << "Tile: " << ++curr_tile << "/" << num_tiles << " Location: [" << col << ", " << row << "] @" << render_level << " ";
          progress.reset(new TerminalProgressCallback("mvp", status.str()));
        } else {
          progress.reset(new ProgressCallback);
        }

        MVPTileResult result = mvpjob_process_tile(work.assemble_job(col, row, render_level), *progress);

        ImageView<PixelGrayA<float32> > rendered_tile = mask_to_alpha(pixel_cast<PixelMask<PixelGray<float32> > >(result.alt));

        float32 tile_min_val, tile_max_val;
        try {
          min_max_channel_values(result.alt, tile_min_val, tile_max_val);
        } catch (ArgumentErr& e) {
          tile_min_val = numeric_limits<float32>::max();
          tile_max_val = numeric_limits<float32>::min();
        }

        plate_min_val = min(plate_min_val, tile_min_val);
        plate_max_val = max(plate_max_val, tile_max_val);

        pf->write_request();
        pf->write_update(rendered_tile, col, row, render_level, tid);
        pf->sync();
        pf->write_complete();
      }
    }

    // This way that tile is easy to find...
    for (int level = 2; level < render_level; level++) {
      int divisor = render_level - level;
      for (int col = tile_bbox.min().x() >> divisor; col <= tile_bbox.max().x() >> divisor; col++) {
        for (int row = tile_bbox.min().y() >> divisor; row <= tile_bbox.max().y() >> divisor; row++) {
          ImageView<PixelGrayA<float32> > rendered_tile(constant_view(PixelGrayA<float32>(),
                                                                      work.plate_georef().tile_size(), work.plate_georef().tile_size()));
          pf->write_request();
          pf->write_update(rendered_tile, col, row, level, tid);
          pf->sync();
          pf->write_complete();
        }
      }
    }

    if (!vm.count("silent")) {
      cout << "Plate (min, max): (" << plate_min_val << ", " << plate_max_val << ")" << endl;
      cout << endl;
    }
  }

  #if MVP_ENABLE_OCTAVE_SUPPORT
  do_octave_atexit();
  #endif

  return 0;
}
<commit_msg>updated mvp.cc for new platefile api<commit_after>#include <iostream>

#include <vw/Image/ImageMath.h>
#include <vw/Image/UtilityViews.h>
#include <vw/Plate/PlateFile.h>
#include <vw/Image/MaskViews.h>
#include <vw/Octave/Main.h>

#include <mvp/Config.h>
#include <mvp/MVPWorkspace.h>
#include <mvp/MVPJob.h>

#include <boost/program_options.hpp>

using namespace vw;
using namespace vw::cartography;
using namespace vw::platefile;
using namespace vw::octave;
using namespace std;
using namespace mvp;

namespace po = boost::program_options;

template <class BBoxT, class RealT, size_t DimN>
void print_bbox_helper(math::BBoxBase<BBoxT, RealT, DimN> const& bbox) {
  cout << "BBox = " << bbox << endl;
  cout << "width, height = " << bbox.width() << ", " << bbox.height() << endl;
}

int main(int argc, char* argv[])
{
  #if MVP_ENABLE_OCTAVE_SUPPORT
  start_octave_interpreter();
  #endif

  po::options_description cmd_opts("Command line options");
  cmd_opts.add_options()
    ("help,h", "Print this message")
    ("silent", "Run without outputting status")
    ("config-file,f", po::value<string>()->default_value("mvp.conf"), "Specify a pipeline configuration file")
    ("print-workspace,p", "Print information about the workspace and exit")
    ("dump-job", "Dump a jobfile")
    ("col,c", po::value<int>(), "When dumping a jobfile, column of tile to dump")
    ("row,r", po::value<int>(), "When dumping a jobfile, row of tile to dump")
    ("level,l", po::value<int>(), "When dumping a jobfile or printing the workspace, level to operate at")
    ("job", po::value<string>(), "Render a jobfile")
    ;

  po::options_description render_opts("Render Options");
  render_opts.add_options()
    ("col-start", po::value<int>(), "Col to start rendering at")
    ("col-end", po::value<int>(), "One past last col to render")
    ("row-start", po::value<int>(), "Row to start rendering at")
    ("row-end", po::value<int>(), "One past last row to render")
    ("render-level", po::value<int>(), "Level to render at")
    ;

  po::options_description mvp_opts;
  mvp_opts.add(MVPWorkspace::program_options()).add(render_opts);

  po::options_description all_opts;
  all_opts.add(cmd_opts).add(mvp_opts);

  po::variables_map vm;
  store(po::command_line_parser(argc, argv).options(all_opts).run(), vm);

  if (vm.count("help")) {
    cout << all_opts << endl;
    return 0;
  }

  ifstream ifs(vm["config-file"].as<string>().c_str());
  if (ifs) {
    store(parse_config_file(ifs, mvp_opts), vm);
  }

  notify(vm);

  MVPWorkspace work(MVPWorkspace::construct_from_program_options(vm));

  if (!vm.count("silent")) {
    cout << boolalpha << endl;
    cout << "-------------------------------------" << endl;
    cout << "Welcome to the Multiple View Pipeline" << endl;
    cout << "-------------------------------------" << endl;
    cout << endl;
    cout << "Number of images loaded = " << work.num_images() << endl;
    cout << " Equal resolution level = " << work.equal_resolution_level() << endl;
    cout << "    Equal density level = " << work.equal_density_level() << endl;
    cout << endl;
    cout << "# Workspace lonlat BBox #" << endl;
    print_bbox_helper(work.lonlat_work_area());
    cout << endl;
    cout << "# Workspace tile BBox (@ equal density level) #" << endl;
    print_bbox_helper(work.tile_work_area(work.equal_density_level()));
    if (vm.count("level")) {
      int print_level = vm["level"].as<int>();
      cout << endl;
      cout << "# Workspace tile BBox (@ level " << print_level << ") #" << endl;
      print_bbox_helper(work.tile_work_area(print_level));
    }
    cout << endl;
  }

  if (vm.count("print-workspace")) {
    return 0;
  }

  if (vm.count("dump-job")) {
    if (!vm.count("col") || !vm.count("row") || !vm.count("level")) {
      cerr << "Error: Must specify a col, row, and level to dump" << endl;
      return 1;
    }
    save_job_file(work.assemble_job(vm["col"].as<int>(), vm["row"].as<int>(), vm["level"].as<int>()));
    return 0;
  }

  int render_level = work.equal_density_level();
  if (vm.count("render-level")) {
    render_level = vm["render-level"].as<int>();
  }

  BBox2i tile_bbox(work.tile_work_area(render_level));

  if (vm.count("col-start")) {
    VW_ASSERT(vm.count("col-end"), ArgumentErr() << "col-start specified, but col-end not");
    tile_bbox.min()[0] = vm["col-start"].as<int>();
    tile_bbox.max()[0] = vm["col-end"].as<int>();
  }

  if (vm.count("row-start")) {
    VW_ASSERT(vm.count("row-end"), ArgumentErr() << "row-start specified, but col-end not");
    tile_bbox.min()[1] = vm["row-start"].as<int>();
    tile_bbox.max()[1] = vm["row-end"].as<int>();
  }

  if (!vm.count("silent")) {
    cout << "-------------------------------------" << endl;
    cout << "        Rendering Information" << endl;
    cout << "-------------------------------------" << endl;
    cout << endl;
    cout << "Render level = " << render_level << endl;
    cout << "  Use octave = " << vm["use-octave"].as<bool>() << endl;
    cout << endl;
    cout << "# Render tile BBox #" << endl;
    print_bbox_helper(tile_bbox);
    cout << endl;
    cout << "-------------------------------------" << endl;
    cout << "              Status" << endl;
    cout << "-------------------------------------" << endl;
    cout << endl;
  }

  if (vm.count("job")) {
    MVPTileResult result = mvpjob_process_tile(vm["job"].as<string>(), TerminalProgressCallback("mvp", "Processing job: "));
    write_georeferenced_image(vm["job"].as<string>() + ".tif", result.alt, result.georef);
  } else {
    boost::shared_ptr<PlateFile> pf(new PlateFile(work.result_platefile(),
                                                  work.plate_georef().map_proj(),
                                                  "MVP Result Plate",
                                                  work.plate_georef().tile_size(),
                                                  "tif", VW_PIXEL_GRAYA, VW_CHANNEL_FLOAT32));

    pf->transaction_begin("Post Heights", -1);
    pf->write_request();

    int curr_tile = 0;
    int num_tiles = tile_bbox.width() * tile_bbox.height();
    float32 plate_min_val = numeric_limits<float32>::max(), plate_max_val = numeric_limits<float32>::min();

    for (int col = tile_bbox.min().x(); col < tile_bbox.max().x(); col++) {
      for (int row = tile_bbox.min().y(); row < tile_bbox.max().y(); row++) {
        boost::shared_ptr<ProgressCallback> progress;

        if (!vm.count("silent")) {
          ostringstream status;
          status << "Tile: " << ++curr_tile << "/" << num_tiles << " Location: [" << col << ", " << row << "] @" << render_level << " ";
          progress.reset(new TerminalProgressCallback("mvp", status.str()));
        } else {
          progress.reset(new ProgressCallback);
        }

        MVPTileResult result = mvpjob_process_tile(work.assemble_job(col, row, render_level), *progress);

        ImageView<PixelGrayA<float32> > rendered_tile = mask_to_alpha(pixel_cast<PixelMask<PixelGray<float32> > >(result.alt));

        float32 tile_min_val, tile_max_val;
        try {
          min_max_channel_values(result.alt, tile_min_val, tile_max_val);
        } catch (ArgumentErr& e) {
          tile_min_val = numeric_limits<float32>::max();
          tile_max_val = numeric_limits<float32>::min();
        }

        plate_min_val = min(plate_min_val, tile_min_val);
        plate_max_val = max(plate_max_val, tile_max_val);

        pf->write_update(rendered_tile, col, row, render_level);
        pf->sync();
      }
    }

    // This way that tile is easy to find...
    for (int level = 2; level < render_level; level++) {
      int divisor = render_level - level;
      for (int col = tile_bbox.min().x() >> divisor; col <= tile_bbox.max().x() >> divisor; col++) {
        for (int row = tile_bbox.min().y() >> divisor; row <= tile_bbox.max().y() >> divisor; row++) {
          ImageView<PixelGrayA<float32> > rendered_tile(constant_view(PixelGrayA<float32>(),
                                                                      work.plate_georef().tile_size(), work.plate_georef().tile_size()));
          pf->write_update(rendered_tile, col, row, level);
        }
      }
    }

    pf->sync();
    pf->write_complete();
    pf->transaction_end(true);

    if (!vm.count("silent")) {
      cout << "Plate (min, max): (" << plate_min_val << ", " << plate_max_val << ")" << endl;
      cout << endl;
    }
  }

  #if MVP_ENABLE_OCTAVE_SUPPORT
  do_octave_atexit();
  #endif

  return 0;
}
<|endoftext|>


<commit_before>#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/common/common.h>
#include <pcl/common/transforms.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/parse.h>
#include <pcl/console/print.h>
#include <pcl/io/pcd_io.h>
#include <iostream>
#include <flann/flann.h>
#include <flann/io/hdf5.h>
#include <boost/filesystem.hpp>

typedef std::pair<std::string, std::vector<float> > vfh_model;

/** \brief Loads an n-D histogram file as a VFH signature
  * \param path the input file name
  * \param vfh the resultant VFH model
  */
bool
loadHist (const boost::filesystem::path &path, vfh_model &vfh)
{
  int vfh_idx;
  // Load the file as a PCD
  try
  {
    sensor_msgs::PointCloud2 cloud;
    int version;
    Eigen::Vector4f origin;
    Eigen::Quaternionf orientation;
    pcl::PCDReader r;
    unsigned int type; int idx;
    r.readHeader (path.string (), cloud, origin, orientation, version, type, idx);

    vfh_idx = pcl::getFieldIndex (cloud, "vfh");
    if (vfh_idx == -1)
      return (false);
    if ((int)cloud.width * cloud.height != 1)
      return (false);
  }
  catch (pcl::InvalidConversionException e)
  {
    return (false);
  }

  // Treat the VFH signature as a single Point Cloud
  pcl::PointCloud <pcl::VFHSignature308> point;
  pcl::io::loadPCDFile (path.string (), point);
  vfh.second.resize (308);

  std::vector <sensor_msgs::PointField> fields;
  getFieldIndex (point, "vfh", fields);

  for (size_t i = 0; i < fields[vfh_idx].count; ++i)
  {
    vfh.second[i] = point.points[0].histogram[i];
  }
  vfh.first = path.string ();
  return (true);
}

/** \brief Search for the closest k neighbors
  * \param index the tree
  * \param model the query model
  * \param k the number of neighbors to search for
  * \param indices the resultant neighbor indices
  * \param distances the resultant neighbor distances
  */
inline void
nearestKSearch (flann::Index<flann::ChiSquareDistance<float> > &index, const vfh_model &model,
                int k, flann::Matrix<int> &indices, flann::Matrix<float> &distances)
{
  // Query point
  flann::Matrix<float> p = flann::Matrix<float>(new float[model.second.size ()], 1, model.second.size ());
  memcpy (&p.ptr ()[0], &model.second[0], p.cols * p.rows * sizeof (float));

  indices = flann::Matrix<int>(new int[k], 1, k);
  distances = flann::Matrix<float>(new float[k], 1, k);
  index.knnSearch (p, indices, distances, k, flann::SearchParams (512));
  delete[] p.ptr ();
}

/** \brief Load the list of file model names from an ASCII file
  * \param models the resultant list of model name
  * \param filename the input file name
  */
bool
loadFileList (std::vector<vfh_model> &models, const std::string &filename)
{
  ifstream fs;
  fs.open (filename.c_str ());
  if (!fs.is_open () || fs.fail ())
    return (false);

  std::string line;
  while (!fs.eof ())
  {
    getline (fs, line);
    if (line.empty ())
      continue;
    vfh_model m;
    m.first = line;
    models.push_back (m);
  }
  fs.close ();
  return (true);
}

int
main (int argc, char** argv)
{
  int k = 6;

  double thresh = DBL_MAX;     // No threshold, disabled by default

  if (argc < 2)
  {
    pcl::console::print_error
      ("Need at least three parameters! Syntax is: %s <query_vfh_model.pcd> [options] {kdtree.idx} {training_data.h5} {training_data.list}\n", argv[0]);
    pcl::console::print_info ("    where [options] are:  -k      = number of nearest neighbors to search for in the tree (default: ");
    pcl::console::print_value ("%d", k); pcl::console::print_info (")\n");
    pcl::console::print_info ("                          -thresh = maximum distance threshold for a model to be considered VALID (default: ");
    pcl::console::print_value ("%f", thresh); pcl::console::print_info (")\n\n");
    return (-1);
  }

  std::string extension (".pcd");
  transform (extension.begin (), extension.end (), extension.begin (), (int(*)(int))tolower);

  // Load the test histogram
  std::vector<int> pcd_indices = pcl::console::parse_file_extension_argument (argc, argv, ".pcd");
  vfh_model histogram;
  if (!loadHist (argv[pcd_indices.at (0)], histogram))
  {
    pcl::console::print_error ("Cannot load test file %s\n", argv[pcd_indices.at (0)]);
    return (-1);
  }

  pcl::console::parse_argument (argc, argv, "-thresh", thresh);
  // Search for the k closest matches
  pcl::console::parse_argument (argc, argv, "-k", k);
  pcl::console::print_highlight ("Using "); pcl::console::print_value ("%d", k); pcl::console::print_info (" nearest neighbors.\n");

  std::string kdtree_idx_file_name = "kdtree.idx";
  std::string training_data_h5_file_name = "training_data.h5";
  std::string training_data_list_file_name = "training_data.list";

  std::vector<vfh_model> models;
  flann::Matrix<int> k_indices;
  flann::Matrix<float> k_distances;
  flann::Matrix<float> data;
  // Check if the data has already been saved to disk
  if (!boost::filesystem::exists ("training_data.h5") || !boost::filesystem::exists ("training_data.list"))
  {
    pcl::console::print_error ("Could not find training data models files %s and %s!\n",
        training_data_h5_file_name.c_str (), training_data_list_file_name.c_str ());
    return (-1);
  }
  else
  {
    loadFileList (models, training_data_list_file_name);
    flann::load_from_file (data, training_data_h5_file_name, "training_data");
    pcl::console::print_highlight ("Training data found. Loaded %d VFH models from %s/%s.\n",
        (int)data.rows, training_data_h5_file_name.c_str (), training_data_list_file_name.c_str ());
  }

  // Check if the tree index has already been saved to disk
  if (!boost::filesystem::exists (kdtree_idx_file_name))
  {
    pcl::console::print_error ("Could not find kd-tree index in file %s!", kdtree_idx_file_name.c_str ());
    return (-1);
  }
  else
  {
    flann::Index<flann::ChiSquareDistance<float> > index (data, flann::SavedIndexParams ("kdtree.idx"));
    index.buildIndex ();
    nearestKSearch (index, histogram, k, k_indices, k_distances);
  }

  // Output the results on screen
  pcl::console::print_highlight ("The closest %d neighbors for %s are:\n", k, argv[pcd_indices[0]]);
  for (int i = 0; i < k; ++i)
    pcl::console::print_info ("    %d - %s (%d) with a distance of: %f\n",
        i, models.at (k_indices[0][i]).first.c_str (), k_indices[0][i], k_distances[0][i]);

  // Load the results
  pcl::visualization::PCLVisualizer p (argc, argv, "VFH Cluster Classifier");
  int y_s = (int)floor (sqrt ((double)k));
  int x_s = y_s + (int)ceil ((k / (double)y_s) - y_s);
  double x_step = (double)(1 / (double)x_s);
  double y_step = (double)(1 / (double)y_s);
  pcl::console::print_highlight ("Preparing to load ");
  pcl::console::print_value ("%d", k);
  pcl::console::print_info (" files (");
  pcl::console::print_value ("%d", x_s);
  pcl::console::print_info ("x");
  pcl::console::print_value ("%d", y_s);
  pcl::console::print_info (" / ");
  pcl::console::print_value ("%f", x_step);
  pcl::console::print_info ("x");
  pcl::console::print_value ("%f", y_step);
  pcl::console::print_info (")\n");

  int viewport = 0, l = 0, m = 0;
  for (int i = 0; i < k; ++i)
  {
    std::string cloud_name = models.at (k_indices[0][i]).first;
    boost::replace_last (cloud_name, "_vfh", "");

    p.createViewPort (l * x_step, m * y_step, (l + 1) * x_step, (m + 1) * y_step, viewport);
    l++;
    if (l >= x_s)
    {
      l = 0;
      m++;
    }

    sensor_msgs::PointCloud2 cloud;
    pcl::console::print_highlight (stderr, "Loading "); pcl::console::print_value (stderr, "%s ", cloud_name.c_str ());
    if (pcl::io::loadPCDFile (cloud_name, cloud) == -1)
      break;

    // Convert from blob to PointCloud
    pcl::PointCloud<pcl::PointXYZ> cloud_xyz;
    pcl::fromROSMsg (cloud, cloud_xyz);

    if (cloud_xyz.points.size () == 0)
      break;

    pcl::console::print_info ("[done, ");
    pcl::console::print_value ("%d", (int)cloud_xyz.points.size ());
    pcl::console::print_info (" points]\n");
    pcl::console::print_info ("Available dimensions: ");
    pcl::console::print_value ("%s\n", pcl::getFieldsList (cloud).c_str ());

    // Demean the cloud
    Eigen::Vector4f centroid;
    pcl::compute3DCentroid (cloud_xyz, centroid);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xyz_demean (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::demeanPointCloud<pcl::PointXYZ> (cloud_xyz, centroid, *cloud_xyz_demean);
    // Add to renderer*
    p.addPointCloud (cloud_xyz_demean, cloud_name, viewport);

    // Check if the model found is within our inlier tolerance
    std::stringstream ss;
    ss << k_distances[0][i];
    if (k_distances[0][i] > thresh)
    {
      p.addText (ss.str (), 20, 30, 1, 0, 0, ss.str (), viewport);  // display the text with red

      // Create a red line
      pcl::PointXYZ min_p, max_p;
      pcl::getMinMax3D (*cloud_xyz_demean, min_p, max_p);
      std::stringstream line_name;
      line_name << "line_" << i;
      p.addLine (min_p, max_p, 1, 0, 0, line_name.str (), viewport);
      p.setShapeRenderingProperties (pcl::visualization::PCL_VISUALIZER_LINE_WIDTH, 5, line_name.str (), viewport);
    }
    else
      p.addText (ss.str (), 20, 30, 0, 1, 0, ss.str (), viewport);

    // Increase the font size for the score*
    p.setShapeRenderingProperties (pcl::visualization::PCL_VISUALIZER_FONT_SIZE, 18, ss.str (), viewport);

    // Add the cluster name
    p.addText (cloud_name, 20, 10, cloud_name, viewport);
  }
  // Add coordianate systems to all viewports
  p.addCoordinateSystem (0.1, 0);

  p.spin ();
  return (0);
}
<commit_msg>second attenmpt to fix the build of vfh_recognition tutorial on mac os<commit_after>#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/common/common.h>
#include <pcl/common/transforms.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/parse.h>
#include <pcl/console/print.h>
#include <pcl/io/pcd_io.h>
#include <iostream>
#include <flann/flann.h>
#include <flann/io/hdf5.h>
#include <boost/filesystem.hpp>

typedef std::pair<std::string, std::vector<float> > vfh_model;

/** \brief Loads an n-D histogram file as a VFH signature
  * \param path the input file name
  * \param vfh the resultant VFH model
  */
bool
loadHist (const boost::filesystem::path &path, vfh_model &vfh)
{
  int vfh_idx;
  // Load the file as a PCD
  try
  {
    sensor_msgs::PointCloud2 cloud;
    int version;
    Eigen::Vector4f origin;
    Eigen::Quaternionf orientation;
    pcl::PCDReader r;
    int type; unsigned int idx;
    r.readHeader (path.string (), cloud, origin, orientation, version, type, idx);

    vfh_idx = pcl::getFieldIndex (cloud, "vfh");
    if (vfh_idx == -1)
      return (false);
    if ((int)cloud.width * cloud.height != 1)
      return (false);
  }
  catch (pcl::InvalidConversionException e)
  {
    return (false);
  }

  // Treat the VFH signature as a single Point Cloud
  pcl::PointCloud <pcl::VFHSignature308> point;
  pcl::io::loadPCDFile (path.string (), point);
  vfh.second.resize (308);

  std::vector <sensor_msgs::PointField> fields;
  getFieldIndex (point, "vfh", fields);

  for (size_t i = 0; i < fields[vfh_idx].count; ++i)
  {
    vfh.second[i] = point.points[0].histogram[i];
  }
  vfh.first = path.string ();
  return (true);
}

/** \brief Search for the closest k neighbors
  * \param index the tree
  * \param model the query model
  * \param k the number of neighbors to search for
  * \param indices the resultant neighbor indices
  * \param distances the resultant neighbor distances
  */
inline void
nearestKSearch (flann::Index<flann::ChiSquareDistance<float> > &index, const vfh_model &model,
                int k, flann::Matrix<int> &indices, flann::Matrix<float> &distances)
{
  // Query point
  flann::Matrix<float> p = flann::Matrix<float>(new float[model.second.size ()], 1, model.second.size ());
  memcpy (&p.ptr ()[0], &model.second[0], p.cols * p.rows * sizeof (float));

  indices = flann::Matrix<int>(new int[k], 1, k);
  distances = flann::Matrix<float>(new float[k], 1, k);
  index.knnSearch (p, indices, distances, k, flann::SearchParams (512));
  delete[] p.ptr ();
}

/** \brief Load the list of file model names from an ASCII file
  * \param models the resultant list of model name
  * \param filename the input file name
  */
bool
loadFileList (std::vector<vfh_model> &models, const std::string &filename)
{
  ifstream fs;
  fs.open (filename.c_str ());
  if (!fs.is_open () || fs.fail ())
    return (false);

  std::string line;
  while (!fs.eof ())
  {
    getline (fs, line);
    if (line.empty ())
      continue;
    vfh_model m;
    m.first = line;
    models.push_back (m);
  }
  fs.close ();
  return (true);
}

int
main (int argc, char** argv)
{
  int k = 6;

  double thresh = DBL_MAX;     // No threshold, disabled by default

  if (argc < 2)
  {
    pcl::console::print_error
      ("Need at least three parameters! Syntax is: %s <query_vfh_model.pcd> [options] {kdtree.idx} {training_data.h5} {training_data.list}\n", argv[0]);
    pcl::console::print_info ("    where [options] are:  -k      = number of nearest neighbors to search for in the tree (default: ");
    pcl::console::print_value ("%d", k); pcl::console::print_info (")\n");
    pcl::console::print_info ("                          -thresh = maximum distance threshold for a model to be considered VALID (default: ");
    pcl::console::print_value ("%f", thresh); pcl::console::print_info (")\n\n");
    return (-1);
  }

  std::string extension (".pcd");
  transform (extension.begin (), extension.end (), extension.begin (), (int(*)(int))tolower);

  // Load the test histogram
  std::vector<int> pcd_indices = pcl::console::parse_file_extension_argument (argc, argv, ".pcd");
  vfh_model histogram;
  if (!loadHist (argv[pcd_indices.at (0)], histogram))
  {
    pcl::console::print_error ("Cannot load test file %s\n", argv[pcd_indices.at (0)]);
    return (-1);
  }

  pcl::console::parse_argument (argc, argv, "-thresh", thresh);
  // Search for the k closest matches
  pcl::console::parse_argument (argc, argv, "-k", k);
  pcl::console::print_highlight ("Using "); pcl::console::print_value ("%d", k); pcl::console::print_info (" nearest neighbors.\n");

  std::string kdtree_idx_file_name = "kdtree.idx";
  std::string training_data_h5_file_name = "training_data.h5";
  std::string training_data_list_file_name = "training_data.list";

  std::vector<vfh_model> models;
  flann::Matrix<int> k_indices;
  flann::Matrix<float> k_distances;
  flann::Matrix<float> data;
  // Check if the data has already been saved to disk
  if (!boost::filesystem::exists ("training_data.h5") || !boost::filesystem::exists ("training_data.list"))
  {
    pcl::console::print_error ("Could not find training data models files %s and %s!\n",
        training_data_h5_file_name.c_str (), training_data_list_file_name.c_str ());
    return (-1);
  }
  else
  {
    loadFileList (models, training_data_list_file_name);
    flann::load_from_file (data, training_data_h5_file_name, "training_data");
    pcl::console::print_highlight ("Training data found. Loaded %d VFH models from %s/%s.\n",
        (int)data.rows, training_data_h5_file_name.c_str (), training_data_list_file_name.c_str ());
  }

  // Check if the tree index has already been saved to disk
  if (!boost::filesystem::exists (kdtree_idx_file_name))
  {
    pcl::console::print_error ("Could not find kd-tree index in file %s!", kdtree_idx_file_name.c_str ());
    return (-1);
  }
  else
  {
    flann::Index<flann::ChiSquareDistance<float> > index (data, flann::SavedIndexParams ("kdtree.idx"));
    index.buildIndex ();
    nearestKSearch (index, histogram, k, k_indices, k_distances);
  }

  // Output the results on screen
  pcl::console::print_highlight ("The closest %d neighbors for %s are:\n", k, argv[pcd_indices[0]]);
  for (int i = 0; i < k; ++i)
    pcl::console::print_info ("    %d - %s (%d) with a distance of: %f\n",
        i, models.at (k_indices[0][i]).first.c_str (), k_indices[0][i], k_distances[0][i]);

  // Load the results
  pcl::visualization::PCLVisualizer p (argc, argv, "VFH Cluster Classifier");
  int y_s = (int)floor (sqrt ((double)k));
  int x_s = y_s + (int)ceil ((k / (double)y_s) - y_s);
  double x_step = (double)(1 / (double)x_s);
  double y_step = (double)(1 / (double)y_s);
  pcl::console::print_highlight ("Preparing to load ");
  pcl::console::print_value ("%d", k);
  pcl::console::print_info (" files (");
  pcl::console::print_value ("%d", x_s);
  pcl::console::print_info ("x");
  pcl::console::print_value ("%d", y_s);
  pcl::console::print_info (" / ");
  pcl::console::print_value ("%f", x_step);
  pcl::console::print_info ("x");
  pcl::console::print_value ("%f", y_step);
  pcl::console::print_info (")\n");

  int viewport = 0, l = 0, m = 0;
  for (int i = 0; i < k; ++i)
  {
    std::string cloud_name = models.at (k_indices[0][i]).first;
    boost::replace_last (cloud_name, "_vfh", "");

    p.createViewPort (l * x_step, m * y_step, (l + 1) * x_step, (m + 1) * y_step, viewport);
    l++;
    if (l >= x_s)
    {
      l = 0;
      m++;
    }

    sensor_msgs::PointCloud2 cloud;
    pcl::console::print_highlight (stderr, "Loading "); pcl::console::print_value (stderr, "%s ", cloud_name.c_str ());
    if (pcl::io::loadPCDFile (cloud_name, cloud) == -1)
      break;

    // Convert from blob to PointCloud
    pcl::PointCloud<pcl::PointXYZ> cloud_xyz;
    pcl::fromROSMsg (cloud, cloud_xyz);

    if (cloud_xyz.points.size () == 0)
      break;

    pcl::console::print_info ("[done, ");
    pcl::console::print_value ("%d", (int)cloud_xyz.points.size ());
    pcl::console::print_info (" points]\n");
    pcl::console::print_info ("Available dimensions: ");
    pcl::console::print_value ("%s\n", pcl::getFieldsList (cloud).c_str ());

    // Demean the cloud
    Eigen::Vector4f centroid;
    pcl::compute3DCentroid (cloud_xyz, centroid);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xyz_demean (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::demeanPointCloud<pcl::PointXYZ> (cloud_xyz, centroid, *cloud_xyz_demean);
    // Add to renderer*
    p.addPointCloud (cloud_xyz_demean, cloud_name, viewport);

    // Check if the model found is within our inlier tolerance
    std::stringstream ss;
    ss << k_distances[0][i];
    if (k_distances[0][i] > thresh)
    {
      p.addText (ss.str (), 20, 30, 1, 0, 0, ss.str (), viewport);  // display the text with red

      // Create a red line
      pcl::PointXYZ min_p, max_p;
      pcl::getMinMax3D (*cloud_xyz_demean, min_p, max_p);
      std::stringstream line_name;
      line_name << "line_" << i;
      p.addLine (min_p, max_p, 1, 0, 0, line_name.str (), viewport);
      p.setShapeRenderingProperties (pcl::visualization::PCL_VISUALIZER_LINE_WIDTH, 5, line_name.str (), viewport);
    }
    else
      p.addText (ss.str (), 20, 30, 0, 1, 0, ss.str (), viewport);

    // Increase the font size for the score*
    p.setShapeRenderingProperties (pcl::visualization::PCL_VISUALIZER_FONT_SIZE, 18, ss.str (), viewport);

    // Add the cluster name
    p.addText (cloud_name, 20, 10, cloud_name, viewport);
  }
  // Add coordianate systems to all viewports
  p.addCoordinateSystem (0.1, 0);

  p.spin ();
  return (0);
}
<|endoftext|>