<commit_before>/**
 * This file is part of the CernVM File System.
 *
 * This command processes a repository's catalog structure to detect and remove
 * outdated and/or unneeded data objects.
 */

#include "cvmfs_config.h"
#include "swissknife_gc.h"

#include <string>

#include "garbage_collection/garbage_collector.h"
#include "garbage_collection/hash_filter.h"
#include "manifest.h"
#include "upload_facility.h"

namespace swissknife {

typedef HttpObjectFetcher<> ObjectFetcher;
typedef CatalogTraversal<ObjectFetcher> ReadonlyCatalogTraversal;
typedef GarbageCollector<ReadonlyCatalogTraversal, SimpleHashFilter> GC;
typedef GC::Configuration GcConfig;

ParameterList CommandGc::GetParams() {
  ParameterList r;
  r.push_back(Parameter::Mandatory('r', "repository url"));
  r.push_back(Parameter::Mandatory('u', "spooler definition string"));
  r.push_back(Parameter::Mandatory('n', "fully qualified repository name"));
  r.push_back(Parameter::Optional('h', "conserve <h> revisions"));
  r.push_back(Parameter::Optional('z', "conserve revisions younger than <z>"));
  r.push_back(Parameter::Optional('k', "repository master key(s)"));
  r.push_back(Parameter::Optional('t', "temporary directory"));
  r.push_back(Parameter::Optional('L', "path to deletion log file"));
  r.push_back(Parameter::Switch('d', "dry run"));
  r.push_back(Parameter::Switch('l', "list objects to be removed"));
  return r;
}

int CommandGc::Main(const ArgumentList &args) {
  const std::string &repo_url = *args.find('r')->second;
  const std::string &spooler = *args.find('u')->second;
  const std::string &repo_name = *args.find('n')->second;
  const int64_t revisions = (args.count('h') > 0) ?
    String2Int64(*args.find('h')->second) : GcConfig::kFullHistory;
  const time_t timestamp  = (args.count('z') > 0)
    ? static_cast<time_t>(String2Int64(*args.find('z')->second))
    : GcConfig::kNoTimestamp;
  const std::string &repo_keys = (args.count('k') > 0) ?
    *args.find('k')->second : "";
  const bool dry_run = (args.count('d') > 0);
  const bool list_condemned_objects = (args.count('l') > 0);
  const std::string temp_directory = (args.count('t') > 0) ?
    *args.find('t')->second : "/tmp";
  const std::string deletion_log_path = (args.count('L') > 0) ?
    *args.find('L')->second : "";

  if (revisions < 0) {
    LogCvmfs(kLogCvmfs, kLogStderr,
             "at least one revision needs to be preserved");
    return 1;
  }

  if (timestamp == GcConfig::kNoTimestamp &&
      revisions == GcConfig::kFullHistory) {
    LogCvmfs(kLogCvmfs, kLogStderr,
             "neither a timestamp nor history threshold given");
    return 1;
  }

  FILE *deletion_log_file = NULL;
  if (!deletion_log_path.empty()) {
    deletion_log_file = fopen(deletion_log_path.c_str(), "a+");
    if (NULL == deletion_log_file) {
      LogCvmfs(kLogCvmfs, kLogStderr, "failed to open deletion log file "
                                      "(errno: %d)", errno);
      return 1;
    }
  }

  download::DownloadManager   download_manager;
  signature::SignatureManager signature_manager;
  download_manager.Init(1, true, g_statistics);
  signature_manager.Init();
  if (!signature_manager.LoadPublicRsaKeys(repo_keys)) {
    LogCvmfs(kLogCatalog, kLogStderr, "failed to load public key(s)");
    return 1;
  }

  ObjectFetcher object_fetcher(repo_name,
                               repo_url,
                               temp_directory,
                               &download_manager,
                               &signature_manager);

  UniquePtr<manifest::Manifest> manifest;
  ObjectFetcher::Failures retval = object_fetcher.FetchManifest(&manifest);
  if (retval != ObjectFetcher::kFailOk) {
    LogCvmfs(kLogCvmfs, kLogStderr, "failed to load repository manifest "
                                    "(%d - %s)",
                                    retval, Code2Ascii(retval));
    return 1;
  }

  if (!manifest->garbage_collectable()) {
    LogCvmfs(kLogCvmfs, kLogStderr,
             "repository does not allow garbage collection");
    return 1;
  }

  GcConfig config;
  const upload::SpoolerDefinition spooler_definition(spooler, shash::kAny);
  config.uploader = upload::AbstractUploader::Construct(spooler_definition);
  config.keep_history_depth = revisions;
  config.keep_history_timestamp = timestamp;
  config.dry_run = dry_run;
  config.verbose = list_condemned_objects;
  config.object_fetcher = &object_fetcher;
  config.deleted_objects_logfile = deletion_log_file;

  if (config.uploader == NULL) {
    LogCvmfs(kLogCvmfs, kLogStderr, "failed to initialize spooler for '%s'",
             spooler.c_str());
    return 1;
  }

  if (deletion_log_file != NULL) {
    const int bytes_written = fprintf(deletion_log_file,
                                      "# Garbage Collection started at %s\n",
                                      StringifyTime(time(NULL), true).c_str());
    if (bytes_written < 0) {
      LogCvmfs(kLogCvmfs, kLogStderr, "failed to write to deletion log '%s' "
                                      "(errno: %d)",
                                      deletion_log_path.c_str(), errno);
      return 1;
    }
  }

  GC collector(config);
  const bool success = collector.Collect();

  download_manager.Fini();
  signature_manager.Fini();

  if (deletion_log_file != NULL) {
    const int bytes_written = fprintf(deletion_log_file,
                                      "# Garbage Collection finished at %s\n\n",
                                      StringifyTime(time(NULL), true).c_str());
    assert(bytes_written >= 0);
    fclose(deletion_log_file);
  }

  return success ? 0 : 1;
}

}  // namespace swissknife
<commit_msg>Refactor: use centralised manifest fetching in gc<commit_after>/**
 * This file is part of the CernVM File System.
 *
 * This command processes a repository's catalog structure to detect and remove
 * outdated and/or unneeded data objects.
 */

#include "cvmfs_config.h"
#include "swissknife_gc.h"

#include <string>

#include "garbage_collection/garbage_collector.h"
#include "garbage_collection/hash_filter.h"
#include "manifest.h"
#include "upload_facility.h"

namespace swissknife {

typedef HttpObjectFetcher<> ObjectFetcher;
typedef CatalogTraversal<ObjectFetcher> ReadonlyCatalogTraversal;
typedef GarbageCollector<ReadonlyCatalogTraversal, SimpleHashFilter> GC;
typedef GC::Configuration GcConfig;

ParameterList CommandGc::GetParams() {
  ParameterList r;
  r.push_back(Parameter::Mandatory('r', "repository url"));
  r.push_back(Parameter::Mandatory('u', "spooler definition string"));
  r.push_back(Parameter::Mandatory('n', "fully qualified repository name"));
  r.push_back(Parameter::Optional('h', "conserve <h> revisions"));
  r.push_back(Parameter::Optional('z', "conserve revisions younger than <z>"));
  r.push_back(Parameter::Optional('k', "repository master key(s)"));
  r.push_back(Parameter::Optional('t', "temporary directory"));
  r.push_back(Parameter::Optional('L', "path to deletion log file"));
  r.push_back(Parameter::Switch('d', "dry run"));
  r.push_back(Parameter::Switch('l', "list objects to be removed"));
  return r;
}

int CommandGc::Main(const ArgumentList &args) {
  const std::string &repo_url = *args.find('r')->second;
  const std::string &spooler = *args.find('u')->second;
  const std::string &repo_name = *args.find('n')->second;
  const int64_t revisions = (args.count('h') > 0) ?
    String2Int64(*args.find('h')->second) : GcConfig::kFullHistory;
  const time_t timestamp  = (args.count('z') > 0)
    ? static_cast<time_t>(String2Int64(*args.find('z')->second))
    : GcConfig::kNoTimestamp;
  const std::string &repo_keys = (args.count('k') > 0) ?
    *args.find('k')->second : "";
  const bool dry_run = (args.count('d') > 0);
  const bool list_condemned_objects = (args.count('l') > 0);
  const std::string temp_directory = (args.count('t') > 0) ?
    *args.find('t')->second : "/tmp";
  const std::string deletion_log_path = (args.count('L') > 0) ?
    *args.find('L')->second : "";

  if (revisions < 0) {
    LogCvmfs(kLogCvmfs, kLogStderr,
             "at least one revision needs to be preserved");
    return 1;
  }

  if (timestamp == GcConfig::kNoTimestamp &&
      revisions == GcConfig::kFullHistory) {
    LogCvmfs(kLogCvmfs, kLogStderr,
             "neither a timestamp nor history threshold given");
    return 1;
  }

  FILE *deletion_log_file = NULL;
  if (!deletion_log_path.empty()) {
    deletion_log_file = fopen(deletion_log_path.c_str(), "a+");
    if (NULL == deletion_log_file) {
      LogCvmfs(kLogCvmfs, kLogStderr, "failed to open deletion log file "
                                      "(errno: %d)", errno);
      return 1;
    }
  }

  const bool follow_redirects = false;
  if (!this->InitDownloadManager(follow_redirects) ||
      !this->InitSignatureManager(repo_keys)) {
    LogCvmfs(kLogCatalog, kLogStderr, "failed to init repo connection");
    return 1;
  }

  ObjectFetcher object_fetcher(repo_name,
                               repo_url,
                               temp_directory,
                               download_manager(),
                               signature_manager());

  UniquePtr<manifest::Manifest> manifest;
  ObjectFetcher::Failures retval = object_fetcher.FetchManifest(&manifest);
  if (retval != ObjectFetcher::kFailOk) {
    LogCvmfs(kLogCvmfs, kLogStderr, "failed to load repository manifest "
                                    "(%d - %s)",
                                    retval, Code2Ascii(retval));
    return 1;
  }

  if (!manifest->garbage_collectable()) {
    LogCvmfs(kLogCvmfs, kLogStderr,
             "repository does not allow garbage collection");
    return 1;
  }

  GcConfig config;
  const upload::SpoolerDefinition spooler_definition(spooler, shash::kAny);
  config.uploader = upload::AbstractUploader::Construct(spooler_definition);
  config.keep_history_depth = revisions;
  config.keep_history_timestamp = timestamp;
  config.dry_run = dry_run;
  config.verbose = list_condemned_objects;
  config.object_fetcher = &object_fetcher;
  config.deleted_objects_logfile = deletion_log_file;

  if (config.uploader == NULL) {
    LogCvmfs(kLogCvmfs, kLogStderr, "failed to initialize spooler for '%s'",
             spooler.c_str());
    return 1;
  }

  if (deletion_log_file != NULL) {
    const int bytes_written = fprintf(deletion_log_file,
                                      "# Garbage Collection started at %s\n",
                                      StringifyTime(time(NULL), true).c_str());
    if (bytes_written < 0) {
      LogCvmfs(kLogCvmfs, kLogStderr, "failed to write to deletion log '%s' "
                                      "(errno: %d)",
                                      deletion_log_path.c_str(), errno);
      return 1;
    }
  }

  GC collector(config);
  const bool success = collector.Collect();

  if (deletion_log_file != NULL) {
    const int bytes_written = fprintf(deletion_log_file,
                                      "# Garbage Collection finished at %s\n\n",
                                      StringifyTime(time(NULL), true).c_str());
    assert(bytes_written >= 0);
    fclose(deletion_log_file);
  }

  return success ? 0 : 1;
}

}  // namespace swissknife
<|endoftext|>


<commit_before>/* Jim Viebke
Feb 14, 2015 */

#include <fstream>
#include <thread>

#include "craft.h"
#include "game.h"

using namespace std;

int main()
{
	// ensure game directories exist
	R::create_path_if_not_exists(C::game_directory);
	R::create_path_if_not_exists(C::room_directory);
	R::create_path_if_not_exists(C::user_data_directory);

	// ensure .bat utilites are on the disk
	R::to_file(C::game_directory + "\\" + "move room data to delete folder.bat.txt",
		string("move C:\\IslandMUD\\rooms C:\\IslandMUD\\delete"));
	R::to_file(C::game_directory + "\\" + "wipe delete folder.bat",
		string("del /f/s/q C:\\IslandMUD\\delete > nul") + "\n" + "rmdir /s/q C:\\IslandMUD\\delete");

	// create game object
	Game game;

	// initialize and load everything
	game.load();

	// For playing using the server as the sole client (development), call main_test_loop().
	// Execution stays here until the game ends.
	game.main_test_loop();

}
<commit_msg>spelling<commit_after>/* Jim Viebke
Feb 14, 2015 */

#include <fstream>
#include <thread>

#include "craft.h"
#include "game.h"

using namespace std;

int main()
{
	// ensure game directories exist
	R::create_path_if_not_exists(C::game_directory);
	R::create_path_if_not_exists(C::room_directory);
	R::create_path_if_not_exists(C::user_data_directory);

	// ensure .bat utilities are on the disk
	R::to_file(C::game_directory + "\\" + "move room data to delete folder.bat.txt",
		string("move C:\\IslandMUD\\rooms C:\\IslandMUD\\delete"));
	R::to_file(C::game_directory + "\\" + "wipe delete folder.bat",
		string("del /f/s/q C:\\IslandMUD\\delete > nul") + "\n" + "rmdir /s/q C:\\IslandMUD\\delete");

	// create game object
	Game game;

	// initialize and load everything
	game.load();

	// For playing using the server as the sole client (development), call main_test_loop().
	// Execution stays here until the game ends.
	game.main_test_loop();

}
<|endoftext|>


<commit_before>/*
* Dataset_opencvTest.cpp
* Tests Dataset_opencv
*
Copyright 2017 Wojciech Wilgierz

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

#include <gtest/gtest.h>
#include <span.h>
#include "Spectre.libClassifier/Dataset_opencv.h"
#include "Spectre.libException/InconsistentArgumentSizesException.h"
#include "Spectre.libException/OutOfRangeException.h"

namespace
{
using namespace Spectre::libClassifier;
using namespace Spectre::libException;

class Dataset_opencvInitializationTest : public ::testing::Test
{
public:
protected:
	const std::vector<DataType> data_long{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
	const std::vector<DataType> data_short{ 0.5f, 0.4f, 0.6f };
	const std::vector<Label> labels{ 3, 7, 14 };
	const std::vector<Label> labels_too_long{ 3, 7, 14, 5 };
};

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization_col_size_one)
{
	EXPECT_NO_THROW(Dataset_opencv(data_short, labels));
}

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization)
{
	EXPECT_NO_THROW(Dataset_opencv(data_long, labels));
}

TEST_F(Dataset_opencvInitializationTest, throws_for_inconsistent_size)
{
	EXPECT_THROW(Dataset_opencv(data_short, labels_too_long), InconsistentArgumentSizesException);
}

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization_from_mat_col_size_one)
{
	std::vector<DataType> tmp_data(data_short);
	std::vector<Label> tmp_labels(labels);
	cv::Mat mat_data(3, 1, CV_TYPE, tmp_data.data());
	cv::Mat mat_labels(3, 1, CV_LABEL_TYPE, tmp_labels.data());
	EXPECT_NO_THROW(Dataset_opencv(mat_data, mat_labels));
}

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization_from_mat)
{
	std::vector<DataType> tmp_data(data_long);
	std::vector<Label> tmp_labels(labels);
	cv::Mat mat_data(3, 3, CV_TYPE, tmp_data.data());
	cv::Mat mat_labels(3, 1, CV_LABEL_TYPE, tmp_labels.data());
	EXPECT_NO_THROW(Dataset_opencv(mat_data, mat_labels));
}

class Dataset_opencvTest : public ::testing::Test
{
public:
	Dataset_opencvTest()
	{

	}
protected:
	const std::vector<DataType> data{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
	const std::vector<Label> labels{ 3, 7, 14 };
	std::unique_ptr<Dataset_opencv> dataset;

	void SetUp() override
	{
		dataset = std::make_unique<Dataset_opencv>(data, labels);
	}
};

TEST_F(Dataset_opencvTest, get_out_of_range_data)
{
	EXPECT_THROW((*dataset)[4], OutOfRangeException);
}

TEST_F(Dataset_opencvTest, get_in_range_data)
{
	auto test = (*dataset)[1];
	std::vector<DataType> check({ 1.1f, 1.6f, 0.7f });
	for (auto i = 0u; i < check.size(); i++)
	{
		EXPECT_EQ(test[i], check[i]);
	}
}

TEST_F(Dataset_opencvTest, get_out_of_range_label)
{
	EXPECT_THROW(dataset->GetSampleMetadata(4), OutOfRangeException);
}

TEST_F(Dataset_opencvTest, get_in_range_label)
{
	auto test = dataset->GetSampleMetadata(1);
	Label check = 7;
	EXPECT_EQ(test, check);
}

TEST_F(Dataset_opencvTest, get_dataset_metadata)
{
	const Empty check = Empty::instance();
	EXPECT_EQ(&(*dataset).GetDatasetMetadata(), &check);
}

TEST_F(Dataset_opencvTest, get_data)
{
	gsl::span<const Observation> result = dataset->GetData();
	EXPECT_EQ(result.size(), data.size());
	for (auto i = 0u; i < data.size(); i++)
	{
		EXPECT_EQ(result[i], data[i]);
	}
}

TEST_F(Dataset_opencvTest, get_labels)
{
	gsl::span<const Label> result = dataset->GetSampleMetadata();
	EXPECT_EQ(result.size(), labels.size());
	for (auto i = 0u; i < labels.size(); i++)
	{
		EXPECT_EQ(result[i], labels[i]);
	}
}

TEST_F(Dataset_opencvTest, get_size)
{
	EXPECT_EQ(dataset->size(), labels.size());
}

TEST_F(Dataset_opencvTest, get_data_mat)
{
	std::vector<DataType> mat_data{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
	cv::Mat check(3, 3, CV_TYPE, mat_data.data());
	cv::Mat result = dataset->getMatData();
	EXPECT_EQ(check, result);
}

TEST_F(Dataset_opencvTest, get_labels_mat)
{
	std::vector<Label> mat_labels{ 3, 7, 14 };
	cv::Mat check(3, 1, CV_LABEL_TYPE, mat_labels.data());
	cv::Mat result = dataset->getMatLabels();
	EXPECT_EQ(check.size, result.size);
}

//advanced tests

TEST_F(Dataset_opencvTest, check_if_creating_copy)
{
	std::unique_ptr<Dataset_opencv> testDataset = std::make_unique<Dataset_opencv>(data, labels);
	gsl::span<const Observation> result = dataset->GetData();
	delete &testDataset;
	EXPECT_EQ(data.size(), result.size());
}

}<commit_msg>fixed few errors regarding comparison and test naming<commit_after>/*
* Dataset_opencvTest.cpp
* Tests Dataset_opencv
*
Copyright 2017 Wojciech Wilgierz

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

#include <gtest/gtest.h>
#include <span.h>
#include "Spectre.libClassifier/Dataset_opencv.h"
#include "Spectre.libException/InconsistentArgumentSizesException.h"
#include "Spectre.libException/OutOfRangeException.h"

namespace
{
using namespace Spectre::libClassifier;
using namespace Spectre::libException;

class Dataset_opencvInitializationTest : public ::testing::Test
{
public:
protected:
	const std::vector<DataType> data_long{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
	const std::vector<DataType> data_short{ 0.5f, 0.4f, 0.6f };
	const std::vector<Label> labels{ 3, 7, 14 };
	const std::vector<Label> labels_too_long{ 3, 7, 14, 5 };
};

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization_col_size_one)
{
	EXPECT_NO_THROW(Dataset_opencv(data_short, labels));
}

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization)
{
	EXPECT_NO_THROW(Dataset_opencv(data_long, labels));
}

TEST_F(Dataset_opencvInitializationTest, throws_for_inconsistent_size)
{
	EXPECT_THROW(Dataset_opencv(data_short, labels_too_long), InconsistentArgumentSizesException);
}

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization_from_mat_col_size_one)
{
	std::vector<DataType> tmp_data(data_short);
	std::vector<Label> tmp_labels(labels);
	cv::Mat mat_data(3, 1, CV_TYPE, tmp_data.data());
	cv::Mat mat_labels(3, 1, CV_LABEL_TYPE, tmp_labels.data());
	EXPECT_NO_THROW(Dataset_opencv(mat_data, mat_labels));
}

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization_from_mat)
{
	std::vector<DataType> tmp_data(data_long);
	std::vector<Label> tmp_labels(labels);
	cv::Mat mat_data(3, 3, CV_TYPE, tmp_data.data());
	cv::Mat mat_labels(3, 1, CV_LABEL_TYPE, tmp_labels.data());
	EXPECT_NO_THROW(Dataset_opencv(mat_data, mat_labels));
}

TEST_F(Dataset_opencvInitializationTest, throws_for_inconsistent_size_from_mat)
{
	std::vector<DataType> tmp_data(data_long);
	std::vector<Label> tmp_labels(labels_too_long);
	cv::Mat mat_data(3, 3, CV_TYPE, tmp_data.data());
	cv::Mat mat_labels(4, 1, CV_LABEL_TYPE, tmp_labels.data());
	EXPECT_THROW(Dataset_opencv(mat_data, mat_labels), InconsistentArgumentSizesException);
}

class Dataset_opencvTest : public ::testing::Test
{
public:
	Dataset_opencvTest()
	{

	}

	bool compareCVMats(cv::Mat mat1, cv::Mat mat2)
	{
		if (mat1.rows != mat2.rows || mat1.cols != mat2.cols) return false;
		for (auto i = 0; i<(mat1.rows*mat1.cols); i++)
		{
			if (mat1.data[i] != mat2.data[i]) return false;
		}
		return true;
	}

protected:
	const std::vector<DataType> data{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
	const std::vector<Label> labels{ 3, 7, 14 };
	std::unique_ptr<Dataset_opencv> dataset;

	void SetUp() override
	{
		dataset = std::make_unique<Dataset_opencv>(data, labels);
	}
};

TEST_F(Dataset_opencvTest, throws_on_access_to_data_out_of_range)
{
	EXPECT_THROW((*dataset)[4], OutOfRangeException);
}

TEST_F(Dataset_opencvTest, check_getting_in_range_data)
{
	auto test = (*dataset)[1];
	std::vector<DataType> check({ 1.1f, 1.6f, 0.7f });
	for (auto i = 0u; i < check.size(); i++)
	{
		EXPECT_EQ(test[i], check[i]);
	}
}

TEST_F(Dataset_opencvTest, throws_on_access_to_label_out_of_range)
{
	EXPECT_THROW(dataset->GetSampleMetadata(4), OutOfRangeException);
}

TEST_F(Dataset_opencvTest, check_getting_in_range_label)
{
	auto test = dataset->GetSampleMetadata(1);
	Label check = 7;
	EXPECT_EQ(test, check);
}

TEST_F(Dataset_opencvTest, get_dataset_metadata)
{
	const Empty check = Empty::instance();
	EXPECT_EQ(&dataset->GetDatasetMetadata(), &check);
}

TEST_F(Dataset_opencvTest, get_data)
{
	gsl::span<const Observation> result = dataset->GetData();
	EXPECT_EQ(result.size(), data.size());
	for (auto i = 0u; i < data.size(); i++)
	{
		EXPECT_EQ(result[i].data(), &data[i]);
	}
}

TEST_F(Dataset_opencvTest, get_labels)
{
	gsl::span<const Label> result = dataset->GetSampleMetadata();
	EXPECT_EQ(result.size(), labels.size());
	for (auto i = 0u; i < labels.size(); i++)
	{
		EXPECT_EQ(result[i], labels[i]);
	}
}

TEST_F(Dataset_opencvTest, check_correct_dataset_size)
{
	EXPECT_EQ(dataset->size(), labels.size());
}

TEST_F(Dataset_opencvTest, check_getting_data_to_mat)
{
	std::vector<DataType> mat_data{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
	cv::Mat check(3, 3, CV_TYPE, mat_data.data());
	cv::Mat result = dataset->getMatData();
	EXPECT_TRUE(compareCVMats(check, result));
}

TEST_F(Dataset_opencvTest, check_getting_labels_to_mat)
{
	std::vector<Label> mat_labels{ 3, 7, 14 };
	cv::Mat check(3, 1, CV_LABEL_TYPE, mat_labels.data());
	cv::Mat result = dataset->getMatLabels();
	EXPECT_TRUE(compareCVMats(check, result));
}

//advanced tests

TEST_F(Dataset_opencvTest, check_if_creating_copy)
{
	std::unique_ptr<Dataset_opencv> result = nullptr;
	// @gmrukwa: Opening new scope, so variables will get destroyed.
	{
		const std::vector<DataType> tmpData{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
		const std::vector<Label> tmpLabels{ 3, 7, 14 };

		result = std::make_unique<Dataset_opencv>(tmpData, tmpLabels);
	}

	EXPECT_EQ(data.size(), result->size());
}

}<|endoftext|>


<commit_before>/****************************************************************************
 *
 *   Copyright (C) 2012 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/**
 * @file spi.cpp
 *
 * Base class for devices connected via SPI.
 *
 * @todo Work out if caching the mode/frequency would save any time.
 *
 * @todo A separate bus/device abstraction would allow for mixed interrupt-mode
 * and non-interrupt-mode clients to arbitrate for the bus.  As things stand,
 * a bus shared between clients of both kinds is vulnerable to races between
 * the two, where an interrupt-mode client will ignore the lock held by the
 * non-interrupt-mode client.
 */

#include <px4_config.h>
#include <nuttx/arch.h>
#include "spi.h"

#ifndef CONFIG_SPI_EXCHANGE
# error This driver requires CONFIG_SPI_EXCHANGE
#endif

namespace device
{

SPI::SPI(const char *name,
	 const char *devname,
	 int bus,
	 uint32_t device,
	 enum spi_mode_e mode,
	 uint32_t frequency,
	 int irq) :
	// base class
	CDev(name, devname, irq),
	// public
	// protected
	locking_mode(LOCK_PREEMPTION),
	// private
	_device(device),
	_mode(mode),
	_frequency(frequency),
	_dev(nullptr),
	_bus(bus)
{
	// fill in _device_id fields for a SPI device
	_device_id.devid_s.bus_type = DeviceBusType_SPI;
	_device_id.devid_s.bus = bus;
	_device_id.devid_s.address = (uint8_t)device;
	// devtype needs to be filled in by the driver
	_device_id.devid_s.devtype = 0;
}

SPI::~SPI()
{
	// XXX no way to let go of the bus...
}

int
SPI::init()
{
	int ret = OK;

	/* attach to the spi bus */
	if (_dev == nullptr) {
		_dev = px4_spibus_initialize(_bus);
	}

	if (_dev == nullptr) {
		DEVICE_DEBUG("failed to init SPI");
		ret = -ENOENT;
		goto out;
	}

	/* deselect device to ensure high to low transition of pin select */
	SPI_SELECT(_dev, _device, false);

	/* call the probe function to check whether the device is present */
	ret = probe();

	if (ret != OK) {
		DEVICE_DEBUG("probe failed");
		goto out;
	}

	/* do base class init, which will create the device node, etc. */
	ret = CDev::init();

	if (ret != OK) {
		DEVICE_DEBUG("cdev init failed");
		goto out;
	}

	/* tell the workd where we are */
	DEVICE_LOG("on SPI bus %d at %d (%u KHz)", _bus, _device, _frequency / 1000);

out:
	return ret;
}

int
SPI::probe()
{
	// assume the device is too stupid to be discoverable
	return OK;
}

int
SPI::transfer(uint8_t *send, uint8_t *recv, unsigned len)
{
	int result;

	if ((send == nullptr) && (recv == nullptr)) {
		return -EINVAL;
	}

	LockMode mode = up_interrupt_context() ? LOCK_NONE : locking_mode;

	/* lock the bus as required */
	switch (mode) {
	default:
	case LOCK_PREEMPTION: {
			irqstate_t state = px4_enter_critical_section();
			result = _transfer(send, recv, len);
			px4_leave_critical_section(state);
		}
		break;

	case LOCK_THREADS:
		SPI_LOCK(_dev, true);
		result = _transfer(send, recv, len);
		SPI_LOCK(_dev, false);
		break;

	case LOCK_NONE:
		result = _transfer(send, recv, len);
		break;
	}

	return result;
}

void
SPI::set_frequency(uint32_t frequency)
{
	_frequency = frequency;
}

int
SPI::_transfer(uint8_t *send, uint8_t *recv, unsigned len)
{
	SPI_SETFREQUENCY(_dev, _frequency);
	SPI_SETMODE(_dev, _mode);
	SPI_SETBITS(_dev, 8);
	SPI_SELECT(_dev, _device, true);

	/* do the transfer */
	SPI_EXCHANGE(_dev, send, recv, len);

	/* and clean up */
	SPI_SELECT(_dev, _device, false);

	return OK;
}

} // namespace device
<commit_msg>spi:Print only device index (mask bus in _device<commit_after>/****************************************************************************
 *
 *   Copyright (C) 2012 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/**
 * @file spi.cpp
 *
 * Base class for devices connected via SPI.
 *
 * @todo Work out if caching the mode/frequency would save any time.
 *
 * @todo A separate bus/device abstraction would allow for mixed interrupt-mode
 * and non-interrupt-mode clients to arbitrate for the bus.  As things stand,
 * a bus shared between clients of both kinds is vulnerable to races between
 * the two, where an interrupt-mode client will ignore the lock held by the
 * non-interrupt-mode client.
 */

#include <px4_config.h>
#include <nuttx/arch.h>
#include "spi.h"

#ifndef CONFIG_SPI_EXCHANGE
# error This driver requires CONFIG_SPI_EXCHANGE
#endif

namespace device
{

SPI::SPI(const char *name,
	 const char *devname,
	 int bus,
	 uint32_t device,
	 enum spi_mode_e mode,
	 uint32_t frequency,
	 int irq) :
	// base class
	CDev(name, devname, irq),
	// public
	// protected
	locking_mode(LOCK_PREEMPTION),
	// private
	_device(device),
	_mode(mode),
	_frequency(frequency),
	_dev(nullptr),
	_bus(bus)
{
	// fill in _device_id fields for a SPI device
	_device_id.devid_s.bus_type = DeviceBusType_SPI;
	_device_id.devid_s.bus = bus;
	_device_id.devid_s.address = (uint8_t)device;
	// devtype needs to be filled in by the driver
	_device_id.devid_s.devtype = 0;
}

SPI::~SPI()
{
	// XXX no way to let go of the bus...
}

int
SPI::init()
{
	int ret = OK;

	/* attach to the spi bus */
	if (_dev == nullptr) {
		_dev = px4_spibus_initialize(_bus);
	}

	if (_dev == nullptr) {
		DEVICE_DEBUG("failed to init SPI");
		ret = -ENOENT;
		goto out;
	}

	/* deselect device to ensure high to low transition of pin select */
	SPI_SELECT(_dev, _device, false);

	/* call the probe function to check whether the device is present */
	ret = probe();

	if (ret != OK) {
		DEVICE_DEBUG("probe failed");
		goto out;
	}

	/* do base class init, which will create the device node, etc. */
	ret = CDev::init();

	if (ret != OK) {
		DEVICE_DEBUG("cdev init failed");
		goto out;
	}

	/* tell the workd where we are */
	DEVICE_LOG("on SPI bus %d at %d (%u KHz)", _bus, PX4_SPI_DEV_ID(_device), _frequency / 1000);

out:
	return ret;
}

int
SPI::probe()
{
	// assume the device is too stupid to be discoverable
	return OK;
}

int
SPI::transfer(uint8_t *send, uint8_t *recv, unsigned len)
{
	int result;

	if ((send == nullptr) && (recv == nullptr)) {
		return -EINVAL;
	}

	LockMode mode = up_interrupt_context() ? LOCK_NONE : locking_mode;

	/* lock the bus as required */
	switch (mode) {
	default:
	case LOCK_PREEMPTION: {
			irqstate_t state = px4_enter_critical_section();
			result = _transfer(send, recv, len);
			px4_leave_critical_section(state);
		}
		break;

	case LOCK_THREADS:
		SPI_LOCK(_dev, true);
		result = _transfer(send, recv, len);
		SPI_LOCK(_dev, false);
		break;

	case LOCK_NONE:
		result = _transfer(send, recv, len);
		break;
	}

	return result;
}

void
SPI::set_frequency(uint32_t frequency)
{
	_frequency = frequency;
}

int
SPI::_transfer(uint8_t *send, uint8_t *recv, unsigned len)
{
	SPI_SETFREQUENCY(_dev, _frequency);
	SPI_SETMODE(_dev, _mode);
	SPI_SETBITS(_dev, 8);
	SPI_SELECT(_dev, _device, true);

	/* do the transfer */
	SPI_EXCHANGE(_dev, send, recv, len);

	/* and clean up */
	SPI_SELECT(_dev, _device, false);

	return OK;
}

} // namespace device
<|endoftext|>


<commit_before>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  @file JPetTaskIO.cpp
 */

#include "JPetTaskIO.h"
#include <memory>
#include <cassert>
#include "../JPetReader/JPetReader.h"
#include "../JPetTreeHeader/JPetTreeHeader.h"
#include "../JPetTask/JPetTask.h"
#include "../JPetCommonTools/JPetCommonTools.h"

#include "../JPetLoggerInclude.h"

JPetTaskIO::JPetTaskIO():
  fEventNb(-1),
  fWriter(0),
  fReader(0),
  fHeader(0),
  fStatistics(0),
  fAuxilliaryData(0),
  fParamManager(0)
{
}

void JPetTaskIO::init(const JPetOptions::Options& opts)
{
  setOptions(JPetOptions(opts));
  std::string inputFilename(fOptions.getInputFile());
  std::string outputPath(fOptions.getOutputPath());
  auto outputFilename = outputPath + std::string(fOptions.getOutputFile());
  createInputObjects(inputFilename.c_str());
  createOutputObjects(outputFilename.c_str());
}

void JPetTaskIO::exec()
{
  assert(fTask);
  assert(fReader);
  assert(fParamManager);
  fTask->setParamManager(fParamManager);
  JPetTaskInterface::Options emptyOpts;
  fTask->init(emptyOpts); //prepare current task for file
  auto totalEvents = 0ll;
  if (fReader) {
    totalEvents = fReader->getNbOfAllEvents();
  } else {
    WARNING("no JPETReader set totalEvents set to -1");
    totalEvents = -1;
  }
  auto firstEvent = 0ll;
  auto lastEvent = 0ll;
  setUserLimits(fOptions, totalEvents,  firstEvent, lastEvent);
  assert(lastEvent >= 0);
  for (auto i = firstEvent; i <= lastEvent; i++) {

    //(std::dynamic_pointer_cast<JPetTask>(fTask))->setEvent(&(static_cast<TNamed&>(fReader->getCurrentEvent())));
    (dynamic_cast<JPetTask*>(fTask))->setEvent(&(static_cast<TNamed&>(fReader->getCurrentEvent())));
    if (fOptions.isProgressBar()) {
      displayProgressBar(i, lastEvent);
    }
    fTask->exec();
    fReader->nextEvent();
  }
  fTask->terminate();
}

void JPetTaskIO::terminate()
{
  assert(fReader);
  assert(fWriter);
  assert(fHeader);
  assert(fStatistics);
  assert(fAuxilliaryData);

  fWriter->writeHeader(fHeader);

  fWriter->writeObject(fStatistics->getHistogramsTable(), "Stats");

  fWriter->writeObject(fAuxilliaryData, "Auxilliary Data");

  // store the parametric objects in the ouptut ROOT file
  getParamManager().saveParametersToFile(
    fWriter);
  getParamManager().clearParameters();

  fWriter->closeFile();
  fReader->closeFile();

}

void JPetTaskIO::setOptions(const JPetOptions& opts)
{
  fOptions = opts;
}
void JPetTaskIO::setParamManager(JPetParamManager* paramManager)
{
  DEBUG("JPetTaskIO");
  fParamManager = paramManager;
}

JPetParamManager& JPetTaskIO::getParamManager()
{
  DEBUG("JPetTaskIO");
  static JPetParamManager NullManager(true);
  if (fParamManager) {
    DEBUG("JPetParamManger returning normal parammanager");
    return *fParamManager;
  } else {
    DEBUG("JPetParamManger returning NullManager ");
    return NullManager;
  }
}

void JPetTaskIO::createInputObjects(const char* inputFilename)
{
  auto treeName = "";
  fReader = new JPetReader;
  if (fOptions.getInputFileType() == JPetOptions::kHld ) {
    treeName = "T";
  } else {
    treeName = "tree";
  }
  if ( fReader->openFileAndLoadData( inputFilename, treeName )) {
    if (fOptions.getInputFileType() == JPetOptions::kHld ) {
      // create a header to be stored along with the output tree
      fHeader = new JPetTreeHeader(fOptions.getRunNumber());

      // add general info to the Tree header
      fHeader->setBaseFileName(fOptions.getInputFile());

    } else {
      assert(fParamManager);
      fParamManager->readParametersFromFile(dynamic_cast<JPetReader*> (fReader));
      // read the header from the previous analysis stage
      //
      fHeader = dynamic_cast<JPetReader*>(fReader)->getHeaderClone();
      //fParamManager.readParametersFromFile( fReader );
    }
    // create an object for storing histograms and counters during processing
    fStatistics = new JPetStatistics();

    // read the Auxilliary data from input file
    // or create it if it was non-existent
    fAuxilliaryData = dynamic_cast<JPetAuxilliaryData*>(fReader->getObjectFromFile("Auxilliary Data"));

    // add info about this module to the processing stages' history in Tree header
    //auto task = std::dynamic_pointer_cast<JPetTask>(fTask);
    auto task = dynamic_cast<JPetTask*>(fTask);
    fHeader->addStageInfo(task->GetName(), task->GetTitle(), 0,
                          JPetCommonTools::getTimeString());

  } else {
    ERROR(inputFilename + std::string(": Unable to open the input file or load the tree"));
    exit(-1);
  }
}

void JPetTaskIO::createOutputObjects(const char* outputFilename)
{
  fWriter = new JPetWriter( outputFilename );
  assert(fWriter);
  if (fTask) {
    //auto task = std::dynamic_pointer_cast<JPetTask>(fTask);
    auto task = dynamic_cast<JPetTask*>(fTask);
    task->setWriter(fWriter);
    if (!fAuxilliaryData) {
      fAuxilliaryData = new JPetAuxilliaryData();
    }
    task->setStatistics(fStatistics);
    task->setAuxilliaryData(fAuxilliaryData);
  } else {
    WARNING("the subTask does not exist, so Write was not passed to it");
  }
}

void JPetTaskIO::displayProgressBar(int currentEventNumber, int numberOfEvents) const
{
  return fProgressBar.display(currentEventNumber, numberOfEvents);
}

const JPetParamBank& JPetTaskIO::getParamBank()
{
  DEBUG("from JPetTaskIO");
  assert(fParamManager);
  return fParamManager->getParamBank();
}

JPetTaskIO::~JPetTaskIO()
{
  if (fWriter) {
    delete fWriter;
    fWriter = 0;
  }
  if (fReader) {
    delete fReader;
    fReader = 0;
  }
  if (fStatistics) {
    delete fStatistics;
    fStatistics = 0;
  }
  if (fAuxilliaryData) {
    delete fAuxilliaryData;
    fAuxilliaryData = 0;
  }

}

/// Sets values of firstEvent and lastEvent based on user options opts and total number of events from JPetReader
// if the totEventsFromReader is less than 0, than first and last are set to -1.
void JPetTaskIO::setUserLimits(const JPetOptions& opts, const long long kTotEventsFromReader, long long& first, long long& last) const
{
  const auto kLastEvent = opts.getLastEvent();
  const auto kFirstEvent = opts.getFirstEvent();
  if ( kTotEventsFromReader < 1) {
    WARNING("kTotEvetnsFromReader < 1, first and last set to -1");
    first = last = -1;
  } else {
    if ( kFirstEvent < 0) {
      first = 0;
    } else {
      first = kFirstEvent < kTotEventsFromReader ? kFirstEvent : kTotEventsFromReader - 1;
    }
    if (kLastEvent < 0)  {
      last = kTotEventsFromReader - 1;
    } else {
      last = kLastEvent < kTotEventsFromReader ? kLastEvent : kTotEventsFromReader - 1;
    }
  }
  assert(first >= 0);
  assert(last >= 0);
  assert(first <= last);
}
<commit_msg>Update JPetTaskIO code to pass JPetOptions to the JPetTask it executes.<commit_after>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  @file JPetTaskIO.cpp
 */

#include "JPetTaskIO.h"
#include <memory>
#include <cassert>
#include "../JPetReader/JPetReader.h"
#include "../JPetTreeHeader/JPetTreeHeader.h"
#include "../JPetTask/JPetTask.h"
#include "../JPetCommonTools/JPetCommonTools.h"

#include "../JPetLoggerInclude.h"

JPetTaskIO::JPetTaskIO():
  fEventNb(-1),
  fWriter(0),
  fReader(0),
  fHeader(0),
  fStatistics(0),
  fAuxilliaryData(0),
  fParamManager(0)
{
}

void JPetTaskIO::init(const JPetOptions::Options& opts)
{
  setOptions(JPetOptions(opts));
  std::string inputFilename(fOptions.getInputFile());
  std::string outputPath(fOptions.getOutputPath());
  auto outputFilename = outputPath + std::string(fOptions.getOutputFile());
  createInputObjects(inputFilename.c_str());
  createOutputObjects(outputFilename.c_str());
}

void JPetTaskIO::exec()
{
  assert(fTask);
  assert(fReader);
  assert(fParamManager);
  fTask->setParamManager(fParamManager);
  fTask->init(fOptions.getOptions()); //prepare current task for file
  auto totalEvents = 0ll;
  if (fReader) {
    totalEvents = fReader->getNbOfAllEvents();
  } else {
    WARNING("no JPETReader set totalEvents set to -1");
    totalEvents = -1;
  }
  auto firstEvent = 0ll;
  auto lastEvent = 0ll;
  setUserLimits(fOptions, totalEvents,  firstEvent, lastEvent);
  assert(lastEvent >= 0);
  for (auto i = firstEvent; i <= lastEvent; i++) {

    //(std::dynamic_pointer_cast<JPetTask>(fTask))->setEvent(&(static_cast<TNamed&>(fReader->getCurrentEvent())));
    (dynamic_cast<JPetTask*>(fTask))->setEvent(&(static_cast<TNamed&>(fReader->getCurrentEvent())));
    if (fOptions.isProgressBar()) {
      displayProgressBar(i, lastEvent);
    }
    fTask->exec();
    fReader->nextEvent();
  }
  fTask->terminate();
}

void JPetTaskIO::terminate()
{
  assert(fReader);
  assert(fWriter);
  assert(fHeader);
  assert(fStatistics);
  assert(fAuxilliaryData);

  fWriter->writeHeader(fHeader);

  fWriter->writeObject(fStatistics->getHistogramsTable(), "Stats");

  fWriter->writeObject(fAuxilliaryData, "Auxilliary Data");

  // store the parametric objects in the ouptut ROOT file
  getParamManager().saveParametersToFile(
    fWriter);
  getParamManager().clearParameters();

  fWriter->closeFile();
  fReader->closeFile();

}

void JPetTaskIO::setOptions(const JPetOptions& opts)
{
  fOptions = opts;
}
void JPetTaskIO::setParamManager(JPetParamManager* paramManager)
{
  DEBUG("JPetTaskIO");
  fParamManager = paramManager;
}

JPetParamManager& JPetTaskIO::getParamManager()
{
  DEBUG("JPetTaskIO");
  static JPetParamManager NullManager(true);
  if (fParamManager) {
    DEBUG("JPetParamManger returning normal parammanager");
    return *fParamManager;
  } else {
    DEBUG("JPetParamManger returning NullManager ");
    return NullManager;
  }
}

void JPetTaskIO::createInputObjects(const char* inputFilename)
{
  auto treeName = "";
  fReader = new JPetReader;
  if (fOptions.getInputFileType() == JPetOptions::kHld ) {
    treeName = "T";
  } else {
    treeName = "tree";
  }
  if ( fReader->openFileAndLoadData( inputFilename, treeName )) {
    if (fOptions.getInputFileType() == JPetOptions::kHld ) {
      // create a header to be stored along with the output tree
      fHeader = new JPetTreeHeader(fOptions.getRunNumber());

      // add general info to the Tree header
      fHeader->setBaseFileName(fOptions.getInputFile());

    } else {
      assert(fParamManager);
      fParamManager->readParametersFromFile(dynamic_cast<JPetReader*> (fReader));
      // read the header from the previous analysis stage
      //
      fHeader = dynamic_cast<JPetReader*>(fReader)->getHeaderClone();
      //fParamManager.readParametersFromFile( fReader );
    }
    // create an object for storing histograms and counters during processing
    fStatistics = new JPetStatistics();

    // read the Auxilliary data from input file
    // or create it if it was non-existent
    fAuxilliaryData = dynamic_cast<JPetAuxilliaryData*>(fReader->getObjectFromFile("Auxilliary Data"));

    // add info about this module to the processing stages' history in Tree header
    //auto task = std::dynamic_pointer_cast<JPetTask>(fTask);
    auto task = dynamic_cast<JPetTask*>(fTask);
    fHeader->addStageInfo(task->GetName(), task->GetTitle(), 0,
                          JPetCommonTools::getTimeString());

  } else {
    ERROR(inputFilename + std::string(": Unable to open the input file or load the tree"));
    exit(-1);
  }
}

void JPetTaskIO::createOutputObjects(const char* outputFilename)
{
  fWriter = new JPetWriter( outputFilename );
  assert(fWriter);
  if (fTask) {
    //auto task = std::dynamic_pointer_cast<JPetTask>(fTask);
    auto task = dynamic_cast<JPetTask*>(fTask);
    task->setWriter(fWriter);
    if (!fAuxilliaryData) {
      fAuxilliaryData = new JPetAuxilliaryData();
    }
    task->setStatistics(fStatistics);
    task->setAuxilliaryData(fAuxilliaryData);
  } else {
    WARNING("the subTask does not exist, so Write was not passed to it");
  }
}

void JPetTaskIO::displayProgressBar(int currentEventNumber, int numberOfEvents) const
{
  return fProgressBar.display(currentEventNumber, numberOfEvents);
}

const JPetParamBank& JPetTaskIO::getParamBank()
{
  DEBUG("from JPetTaskIO");
  assert(fParamManager);
  return fParamManager->getParamBank();
}

JPetTaskIO::~JPetTaskIO()
{
  if (fWriter) {
    delete fWriter;
    fWriter = 0;
  }
  if (fReader) {
    delete fReader;
    fReader = 0;
  }
  if (fStatistics) {
    delete fStatistics;
    fStatistics = 0;
  }
  if (fAuxilliaryData) {
    delete fAuxilliaryData;
    fAuxilliaryData = 0;
  }

}

/// Sets values of firstEvent and lastEvent based on user options opts and total number of events from JPetReader
// if the totEventsFromReader is less than 0, than first and last are set to -1.
void JPetTaskIO::setUserLimits(const JPetOptions& opts, const long long kTotEventsFromReader, long long& first, long long& last) const
{
  const auto kLastEvent = opts.getLastEvent();
  const auto kFirstEvent = opts.getFirstEvent();
  if ( kTotEventsFromReader < 1) {
    WARNING("kTotEvetnsFromReader < 1, first and last set to -1");
    first = last = -1;
  } else {
    if ( kFirstEvent < 0) {
      first = 0;
    } else {
      first = kFirstEvent < kTotEventsFromReader ? kFirstEvent : kTotEventsFromReader - 1;
    }
    if (kLastEvent < 0)  {
      last = kTotEventsFromReader - 1;
    } else {
      last = kLastEvent < kTotEventsFromReader ? kLastEvent : kTotEventsFromReader - 1;
    }
  }
  assert(first >= 0);
  assert(last >= 0);
  assert(first <= last);
}
<|endoftext|>


<commit_before>#include <fstream>
#include <string>
#include <sstream>

#include <Eigen/Dense>

#include <VirtualRobot/VirtualRobot.h>
#include <VirtualRobot/Robot.h>
#include <VirtualRobot/RobotNodeSet.h>
#include <VirtualRobot/Nodes/RobotNode.h>

#include <MMM/Motion/Motion.h>
#include <MMM/XMLTools.h>

#include <boost/filesystem.hpp>
#include <boost/make_shared.hpp>

#include "utils/mmm/TrajectoryExporter.h"
#include "utils/mmm/ControlPoint.h"
#include "utils/mmm/ControlMatrix.h"
#include "utils/mmm/ControlValue.h"
#include "utils/VelocityEstimation.h"

void TrajectoryExporter::exportToMMM(const std::string& path)
{
    boost::filesystem::path targetPath(path);
    boost::filesystem::path baseDir = targetPath.parent_path();
    std::string relRobotPath = MMM::XML::make_relative(baseDir.string(), pathToRobot);

    MMM::MotionPtr motion(new MMM::Motion("Walking pattern"));

    motion->setJointOrder(jointNames);

    int size = bodyTrajectory.cols();
    int ndof = bodyTrajectory.rows();

    Eigen::MatrixXf bodyVelocity = VelocityEstimation::simpleDiff(bodyTrajectory, timestep);

    for (int i = 0; i < size; i++)
    {
        // we need rootPos in mm
        MMM::MotionFramePtr frame(new MMM::MotionFrame(ndof));
        Eigen::Matrix4f rootPose = leftFootTrajectory[i];
        frame->setRootPose(rootPose);
        frame->setRootPos((Eigen::Vector3f) (1000 * rootPose.block(0, 3, 3, 1)));
        frame->joint = bodyTrajectory.col(i);
        frame->joint_vel = bodyVelocity.col(i);
        frame->timestep = timestep * i;
        frame->addEntry("CoM",
                        boost::make_shared<ControlPointEntry3f>("CoM",
                                comTrajectory.col(i),
                                comVelocity.col(i),
                                comAcceleration.col(i)
                                                               )
                       );
        frame->addEntry("ZMP",
                        boost::make_shared<ControlPointEntry2f>("ZMP",
                                computedZMPTrajectory.col(i)
                                                               )
                       );
        frame->addEntry("ReferenceZMP",
                        boost::make_shared<ControlPointEntry2f>("ReferenceZMP",
                                referenceZMPTrajectory.col(i)
                                                               )
                       );
        frame->addEntry("LeftFoot",
                        boost::make_shared<ControlMatrixEntry4f>("LeftFoot",
                                leftFootTrajectory[i]
                                                                )
                       );
        frame->addEntry("RightFoot",
                        boost::make_shared<ControlMatrixEntry4f>("RightFoot",
                                rightFootTrajectory[i]
                                                                )
                       );
        frame->addEntry("Chest",
                        boost::make_shared<ControlMatrixEntry4f>("Chest",
                                chestTrajectory[i]
                                                                )
                       );
        frame->addEntry("Pelvis",
                        boost::make_shared<ControlMatrixEntry4f>("Pelvis",
                                pelvisTrajectory[i]
                                                                )
                       );
        frame->addEntry("SupportPhase",
                        boost::make_shared<ControlValueEntry<int>>("SupportPhase",
                                phase[i]
                                                                  )
                       );

        motion->addMotionFrame(frame);
    }

    MMM::ModelPtr model(new MMM::Model());
    model->filename = relRobotPath;
    motion->setModel(model);

    std::ofstream out(path.c_str());
    out << "<MMM>"
        << motion->toXML()
        << "</MMM>";
}

<commit_msg>Fix root position unit<commit_after>#include <fstream>
#include <string>
#include <sstream>

#include <Eigen/Dense>

#include <VirtualRobot/VirtualRobot.h>
#include <VirtualRobot/Robot.h>
#include <VirtualRobot/RobotNodeSet.h>
#include <VirtualRobot/Nodes/RobotNode.h>

#include <MMM/Motion/Motion.h>
#include <MMM/XMLTools.h>

#include <boost/filesystem.hpp>
#include <boost/make_shared.hpp>

#include "utils/mmm/TrajectoryExporter.h"
#include "utils/mmm/ControlPoint.h"
#include "utils/mmm/ControlMatrix.h"
#include "utils/mmm/ControlValue.h"
#include "utils/VelocityEstimation.h"

void TrajectoryExporter::exportToMMM(const std::string& path)
{
    boost::filesystem::path targetPath(path);
    boost::filesystem::path baseDir = targetPath.parent_path();
    std::string relRobotPath = MMM::XML::make_relative(baseDir.string(), pathToRobot);

    MMM::MotionPtr motion(new MMM::Motion("Walking pattern"));

    motion->setJointOrder(jointNames);

    int size = bodyTrajectory.cols();
    int ndof = bodyTrajectory.rows();

    Eigen::MatrixXf bodyVelocity = VelocityEstimation::simpleDiff(bodyTrajectory, timestep);

    for (int i = 0; i < size; i++)
    {
        // we need rootPos in mm
        MMM::MotionFramePtr frame(new MMM::MotionFrame(ndof));
        Eigen::Matrix4f rootPose = leftFootTrajectory[i];
        frame->setRootPose(rootPose);
        frame->setRootPos(rootPose.block(0, 3, 3, 1));
        frame->joint = bodyTrajectory.col(i);
        frame->joint_vel = bodyVelocity.col(i);
        frame->timestep = timestep * i;
        frame->addEntry("CoM",
                        boost::make_shared<ControlPointEntry3f>("CoM",
                                comTrajectory.col(i),
                                comVelocity.col(i),
                                comAcceleration.col(i)
                                                               )
                       );
        frame->addEntry("ZMP",
                        boost::make_shared<ControlPointEntry2f>("ZMP",
                                computedZMPTrajectory.col(i)
                                                               )
                       );
        frame->addEntry("ReferenceZMP",
                        boost::make_shared<ControlPointEntry2f>("ReferenceZMP",
                                referenceZMPTrajectory.col(i)
                                                               )
                       );
        frame->addEntry("LeftFoot",
                        boost::make_shared<ControlMatrixEntry4f>("LeftFoot",
                                leftFootTrajectory[i]
                                                                )
                       );
        frame->addEntry("RightFoot",
                        boost::make_shared<ControlMatrixEntry4f>("RightFoot",
                                rightFootTrajectory[i]
                                                                )
                       );
        frame->addEntry("Chest",
                        boost::make_shared<ControlMatrixEntry4f>("Chest",
                                chestTrajectory[i]
                                                                )
                       );
        frame->addEntry("Pelvis",
                        boost::make_shared<ControlMatrixEntry4f>("Pelvis",
                                pelvisTrajectory[i]
                                                                )
                       );
        frame->addEntry("SupportPhase",
                        boost::make_shared<ControlValueEntry<int>>("SupportPhase",
                                phase[i]
                                                                  )
                       );

        motion->addMotionFrame(frame);
    }

    MMM::ModelPtr model(new MMM::Model());
    model->filename = relRobotPath;
    motion->setModel(model);

    std::ofstream out(path.c_str());
    out << "<MMM>"
        << motion->toXML()
        << "</MMM>";
}

<|endoftext|>


<commit_before>#ifndef __MAPNIK_VECTOR_TILE_GEOMETRY_ENCODER_H__
#define __MAPNIK_VECTOR_TILE_GEOMETRY_ENCODER_H__

// vector tile
#include "vector_tile.pb.h"
#include <mapnik/geometry.hpp>
#include "vector_tile_config.hpp"
#include <boost/range/adaptor/sliced.hpp>
#include <cstdlib>
#include <cmath>
#include <sstream>
#include <iostream>

namespace mapnik { namespace vector_tile_impl {

inline unsigned encode_geometry(mapnik::geometry::point<std::int64_t> const& pt,
                        vector_tile::Tile_Feature & current_feature,
                        int32_t & start_x,
                        int32_t & start_y)
{
    current_feature.add_geometry(9); // 1 | (move_to << 3)
    int32_t dx = pt.x - start_x;
    int32_t dy = pt.y - start_y;
    // Manual zigzag encoding.
    current_feature.add_geometry((dx << 1) ^ (dx >> 31));
    current_feature.add_geometry((dy << 1) ^ (dy >> 31));
    start_x = pt.x;
    start_y = pt.y;
    return 1;
}

inline unsigned encode_geometry(mapnik::geometry::line_string<std::int64_t> const& line,
                        vector_tile::Tile_Feature & current_feature,
                        int32_t & start_x,
                        int32_t & start_y)
{
    const int cmd_bits = 3;
    int32_t line_to_length = static_cast<int32_t>(line.size()) - 1;

    enum {
        move_to = 1,
        line_to = 2,
        coords = 3
    } status = move_to;

    for (auto const& pt : line)
    {
        if (status == move_to)
        {
            status = line_to;
            current_feature.add_geometry(9); // 1 | (move_to << 3)
        }
        else if (status == line_to)
        {
            status = coords;
            current_feature.add_geometry((line_to_length << cmd_bits) | 2); // len | (line_to << 3)
        }
        int32_t dx = pt.x - start_x;
        int32_t dy = pt.y - start_y;
        // Manual zigzag encoding.
        current_feature.add_geometry((dx << 1) ^ (dx >> 31));
        current_feature.add_geometry((dy << 1) ^ (dy >> 31));
        start_x = pt.x;
        start_y = pt.y;
    }
    return line.size();
}

inline unsigned encode_geometry(mapnik::geometry::linear_ring<std::int64_t> const& ring,
                        vector_tile::Tile_Feature & current_feature,
                        int32_t & start_x,
                        int32_t & start_y)
{
    if (ring.size() < 3) return 0;
    const int cmd_bits = 3;
    int32_t line_to_length = static_cast<int32_t>(ring.size()) - 1;
    int count = 0;
    enum {
        move_to = 1,
        line_to = 2,
        coords = 3
    } status = move_to;
    bool drop_last = false;
    if (ring.size() > 2 && ring.front() == ring.back())
    {
        drop_last = true;
        line_to_length -= 1;
        if (line_to_length < 2)
        {
            return 0;
        }
    }

    for (auto const& pt : ring)
    {
        if (status == move_to)
        {
            status = line_to;
            current_feature.add_geometry(9); // 1 | (move_to << 3)
        }
        else if (status == line_to)
        {
            status = coords;
            current_feature.add_geometry((line_to_length<< cmd_bits) | 2); // len | (line_to << 3)
        }
        else if (drop_last && count == line_to_length + 1)
        {
            continue;
        }
        int32_t dx = pt.x - start_x;
        int32_t dy = pt.y - start_y;
        // Manual zigzag encoding.
        current_feature.add_geometry((dx << 1) ^ (dx >> 31));
        current_feature.add_geometry((dy << 1) ^ (dy >> 31));
        start_x = pt.x;
        start_y = pt.y;
        ++count;
    }
    current_feature.add_geometry(15); // close_path
    return line_to_length;
}

inline unsigned encode_geometry(mapnik::geometry::polygon<std::int64_t> const& poly,
                                vector_tile::Tile_Feature & current_feature,
                                int32_t & x_,
                                int32_t & y_)
{
    unsigned count = 0;
    count += encode_geometry(poly.exterior_ring, current_feature, x_, y_);
    if (count == 0)
    {
        return count;
    }
    for (auto const& ring : poly.interior_rings)
    {
        count += encode_geometry(ring, current_feature, x_, y_);
    }
    return count;
}

}} // end ns

#endif // __MAPNIK_VECTOR_TILE_GEOMETRY_ENCODER_H__
<commit_msg>remove unused header<commit_after>#ifndef __MAPNIK_VECTOR_TILE_GEOMETRY_ENCODER_H__
#define __MAPNIK_VECTOR_TILE_GEOMETRY_ENCODER_H__

// vector tile
#include "vector_tile.pb.h"
#include <mapnik/geometry.hpp>
#include "vector_tile_config.hpp"
#include <cstdlib>
#include <cmath>
#include <sstream>
#include <iostream>

namespace mapnik { namespace vector_tile_impl {

inline unsigned encode_geometry(mapnik::geometry::point<std::int64_t> const& pt,
                        vector_tile::Tile_Feature & current_feature,
                        int32_t & start_x,
                        int32_t & start_y)
{
    current_feature.add_geometry(9); // 1 | (move_to << 3)
    int32_t dx = pt.x - start_x;
    int32_t dy = pt.y - start_y;
    // Manual zigzag encoding.
    current_feature.add_geometry((dx << 1) ^ (dx >> 31));
    current_feature.add_geometry((dy << 1) ^ (dy >> 31));
    start_x = pt.x;
    start_y = pt.y;
    return 1;
}

inline unsigned encode_geometry(mapnik::geometry::line_string<std::int64_t> const& line,
                        vector_tile::Tile_Feature & current_feature,
                        int32_t & start_x,
                        int32_t & start_y)
{
    const int cmd_bits = 3;
    int32_t line_to_length = static_cast<int32_t>(line.size()) - 1;

    enum {
        move_to = 1,
        line_to = 2,
        coords = 3
    } status = move_to;

    for (auto const& pt : line)
    {
        if (status == move_to)
        {
            status = line_to;
            current_feature.add_geometry(9); // 1 | (move_to << 3)
        }
        else if (status == line_to)
        {
            status = coords;
            current_feature.add_geometry((line_to_length << cmd_bits) | 2); // len | (line_to << 3)
        }
        int32_t dx = pt.x - start_x;
        int32_t dy = pt.y - start_y;
        // Manual zigzag encoding.
        current_feature.add_geometry((dx << 1) ^ (dx >> 31));
        current_feature.add_geometry((dy << 1) ^ (dy >> 31));
        start_x = pt.x;
        start_y = pt.y;
    }
    return line.size();
}

inline unsigned encode_geometry(mapnik::geometry::linear_ring<std::int64_t> const& ring,
                        vector_tile::Tile_Feature & current_feature,
                        int32_t & start_x,
                        int32_t & start_y)
{
    if (ring.size() < 3) return 0;
    const int cmd_bits = 3;
    int32_t line_to_length = static_cast<int32_t>(ring.size()) - 1;
    int count = 0;
    enum {
        move_to = 1,
        line_to = 2,
        coords = 3
    } status = move_to;
    bool drop_last = false;
    if (ring.size() > 2 && ring.front() == ring.back())
    {
        drop_last = true;
        line_to_length -= 1;
        if (line_to_length < 2)
        {
            return 0;
        }
    }

    for (auto const& pt : ring)
    {
        if (status == move_to)
        {
            status = line_to;
            current_feature.add_geometry(9); // 1 | (move_to << 3)
        }
        else if (status == line_to)
        {
            status = coords;
            current_feature.add_geometry((line_to_length<< cmd_bits) | 2); // len | (line_to << 3)
        }
        else if (drop_last && count == line_to_length + 1)
        {
            continue;
        }
        int32_t dx = pt.x - start_x;
        int32_t dy = pt.y - start_y;
        // Manual zigzag encoding.
        current_feature.add_geometry((dx << 1) ^ (dx >> 31));
        current_feature.add_geometry((dy << 1) ^ (dy >> 31));
        start_x = pt.x;
        start_y = pt.y;
        ++count;
    }
    current_feature.add_geometry(15); // close_path
    return line_to_length;
}

inline unsigned encode_geometry(mapnik::geometry::polygon<std::int64_t> const& poly,
                                vector_tile::Tile_Feature & current_feature,
                                int32_t & x_,
                                int32_t & y_)
{
    unsigned count = 0;
    count += encode_geometry(poly.exterior_ring, current_feature, x_, y_);
    if (count == 0)
    {
        return count;
    }
    for (auto const& ring : poly.interior_rings)
    {
        count += encode_geometry(ring, current_feature, x_, y_);
    }
    return count;
}

}} // end ns

#endif // __MAPNIK_VECTOR_TILE_GEOMETRY_ENCODER_H__
<|endoftext|>


<commit_before>// Copyright (c) 2012-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "bloom.h"

#include "primitives/transaction.h"
#include "hash.h"
#include "script/script.h"
#include "script/standard.h"
#include "streams.h"

#include <math.h>
#include <stdlib.h>

#include <boost/foreach.hpp>

#define LN2SQUARED 0.4804530139182014246671025263266649717305529515945455
#define LN2 0.6931471805599453094172321214581765680755001343602552

using namespace std;

CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweakIn, unsigned char nFlagsIn) :
    /**
     * The ideal size for a bloom filter with a given number of elements and false positive rate is:
     * - nElements * log(fp rate) / ln(2)^2
     * We ignore filter parameters which will create a bloom filter larger than the protocol limits
     */
    vData(min((unsigned int)(-1  / LN2SQUARED * nElements * log(nFPRate)), MAX_BLOOM_FILTER_SIZE * 8) / 8),
    /**
     * The ideal number of hash functions is filter size * ln(2) / number of elements
     * Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits
     * See https://en.wikipedia.org/wiki/Bloom_filter for an explanation of these formulas
     */
    isFull(false),
    isEmpty(false),
    nHashFuncs(min((unsigned int)(vData.size() * 8 / nElements * LN2), MAX_HASH_FUNCS)),
    nTweak(nTweakIn),
    nFlags(nFlagsIn)
{
}

// Private constructor used by CRollingBloomFilter
CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweakIn) :
    vData((unsigned int)(-1  / LN2SQUARED * nElements * log(nFPRate)) / 8),
    isFull(false),
    isEmpty(true),
    nHashFuncs((unsigned int)(vData.size() * 8 / nElements * LN2)),
    nTweak(nTweakIn),
    nFlags(BLOOM_UPDATE_NONE)
{
}

inline unsigned int CBloomFilter::Hash(unsigned int nHashNum, const std::vector<unsigned char>& vDataToHash) const
{
    // 0xFBA4C795 chosen as it guarantees a reasonable bit difference between nHashNum values.
    return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) % (vData.size() * 8);
}

void CBloomFilter::insert(const vector<unsigned char>& vKey)
{
    if (isFull)
        return;
    for (unsigned int i = 0; i < nHashFuncs; i++)
    {
        unsigned int nIndex = Hash(i, vKey);
        // Sets bit nIndex of vData
        vData[nIndex >> 3] |= (1 << (7 & nIndex));
    }
    isEmpty = false;
}

void CBloomFilter::insert(const COutPoint& outpoint)
{
    CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
    stream << outpoint;
    vector<unsigned char> data(stream.begin(), stream.end());
    insert(data);
}

void CBloomFilter::insert(const uint256& hash)
{
    vector<unsigned char> data(hash.begin(), hash.end());
    insert(data);
}

bool CBloomFilter::contains(const vector<unsigned char>& vKey) const
{
    if (isFull)
        return true;
    if (isEmpty)
        return false;
    for (unsigned int i = 0; i < nHashFuncs; i++)
    {
        unsigned int nIndex = Hash(i, vKey);
        // Checks bit nIndex of vData
        if (!(vData[nIndex >> 3] & (1 << (7 & nIndex))))
            return false;
    }
    return true;
}

bool CBloomFilter::contains(const COutPoint& outpoint) const
{
    CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
    stream << outpoint;
    vector<unsigned char> data(stream.begin(), stream.end());
    return contains(data);
}

bool CBloomFilter::contains(const uint256& hash) const
{
    vector<unsigned char> data(hash.begin(), hash.end());
    return contains(data);
}

void CBloomFilter::clear()
{
    vData.assign(vData.size(),0);
    isFull = false;
    isEmpty = true;
}

bool CBloomFilter::IsWithinSizeConstraints() const
{
    return vData.size() <= MAX_BLOOM_FILTER_SIZE && nHashFuncs <= MAX_HASH_FUNCS;
}

bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx)
{
    bool fFound = false;
    // Match if the filter contains the hash of tx
    //  for finding tx when they appear in a block
    if (isFull)
        return true;
    if (isEmpty)
        return false;
    const uint256& hash = tx.GetHash();
    if (contains(hash))
        fFound = true;

    for (unsigned int i = 0; i < tx.vout.size(); i++)
    {
        const CTxOut& txout = tx.vout[i];
        // Match if the filter contains any arbitrary script data element in any scriptPubKey in tx
        // If this matches, also add the specific output that was matched.
        // This means clients don't have to update the filter themselves when a new relevant tx
        // is discovered in order to find spending transactions, which avoids round-tripping and race conditions.
        CScript::const_iterator pc = txout.scriptPubKey.begin();
        vector<unsigned char> data;
        while (pc < txout.scriptPubKey.end())
        {
            opcodetype opcode;
            if (!txout.scriptPubKey.GetOp(pc, opcode, data))
                break;
            if (data.size() != 0 && contains(data))
            {
                fFound = true;
                if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_ALL)
                    insert(COutPoint(hash, i));
                else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY)
                {
                    txnouttype type;
                    vector<vector<unsigned char> > vSolutions;
                    if (Solver(txout.scriptPubKey, type, vSolutions) &&
                            (type == TX_PUBKEY || type == TX_MULTISIG))
                        insert(COutPoint(hash, i));
                }
                break;
            }
        }
    }

    if (fFound)
        return true;

    BOOST_FOREACH(const CTxIn& txin, tx.vin)
    {
        // Match if the filter contains an outpoint tx spends
        if (contains(txin.prevout))
            return true;

        // Match if the filter contains any arbitrary script data element in any scriptSig in tx
        CScript::const_iterator pc = txin.scriptSig.begin();
        vector<unsigned char> data;
        while (pc < txin.scriptSig.end())
        {
            opcodetype opcode;
            if (!txin.scriptSig.GetOp(pc, opcode, data))
                break;
            if (data.size() != 0 && contains(data))
                return true;
        }
    }

    return false;
}

void CBloomFilter::UpdateEmptyFull()
{
    bool full = true;
    bool empty = true;
    for (unsigned int i = 0; i < vData.size(); i++)
    {
        full &= vData[i] == 0xff;
        empty &= vData[i] == 0;
    }
    isFull = full;
    isEmpty = empty;
}

CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate, unsigned int nTweak) :
    b1(nElements * 2, fpRate, nTweak), b2(nElements * 2, fpRate, nTweak)
{
    // Implemented using two bloom filters of 2 * nElements each.
    // We fill them up, and clear them, staggered, every nElements
    // inserted, so at least one always contains the last nElements
    // inserted.
    nBloomSize = nElements * 2;
    nInsertions = 0;
}

void CRollingBloomFilter::insert(const std::vector<unsigned char>& vKey)
{
    if (nInsertions == 0) {
        b1.clear();
    } else if (nInsertions == nBloomSize / 2) {
        b2.clear();
    }
    b1.insert(vKey);
    b2.insert(vKey);
    if (++nInsertions == nBloomSize) {
        nInsertions = 0;
    }
}

void CRollingBloomFilter::insert(const uint256& hash)
{
    if (nInsertions == 0) {
        b1.clear();
    } else if (nInsertions == nBloomSize / 2) {
        b2.clear();
    }
    b1.insert(hash);
    b2.insert(hash);
    if (++nInsertions == nBloomSize) {
        nInsertions = 0;
    }
}

bool CRollingBloomFilter::contains(const std::vector<unsigned char>& vKey) const
{
    if (nInsertions < nBloomSize / 2) {
        return b2.contains(vKey);
    }
    return b1.contains(vKey);
}

bool CRollingBloomFilter::contains(const uint256& hash) const
{
    if (nInsertions < nBloomSize / 2) {
        return b2.contains(hash);
    }
    return b1.contains(hash);
}

void CRollingBloomFilter::clear()
{
    b1.clear();
    b2.clear();
    nInsertions = 0;
}
<commit_msg>Reuse vector hashing code for uint256<commit_after>// Copyright (c) 2012-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "bloom.h"

#include "primitives/transaction.h"
#include "hash.h"
#include "script/script.h"
#include "script/standard.h"
#include "streams.h"

#include <math.h>
#include <stdlib.h>

#include <boost/foreach.hpp>

#define LN2SQUARED 0.4804530139182014246671025263266649717305529515945455
#define LN2 0.6931471805599453094172321214581765680755001343602552

using namespace std;

CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweakIn, unsigned char nFlagsIn) :
    /**
     * The ideal size for a bloom filter with a given number of elements and false positive rate is:
     * - nElements * log(fp rate) / ln(2)^2
     * We ignore filter parameters which will create a bloom filter larger than the protocol limits
     */
    vData(min((unsigned int)(-1  / LN2SQUARED * nElements * log(nFPRate)), MAX_BLOOM_FILTER_SIZE * 8) / 8),
    /**
     * The ideal number of hash functions is filter size * ln(2) / number of elements
     * Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits
     * See https://en.wikipedia.org/wiki/Bloom_filter for an explanation of these formulas
     */
    isFull(false),
    isEmpty(false),
    nHashFuncs(min((unsigned int)(vData.size() * 8 / nElements * LN2), MAX_HASH_FUNCS)),
    nTweak(nTweakIn),
    nFlags(nFlagsIn)
{
}

// Private constructor used by CRollingBloomFilter
CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweakIn) :
    vData((unsigned int)(-1  / LN2SQUARED * nElements * log(nFPRate)) / 8),
    isFull(false),
    isEmpty(true),
    nHashFuncs((unsigned int)(vData.size() * 8 / nElements * LN2)),
    nTweak(nTweakIn),
    nFlags(BLOOM_UPDATE_NONE)
{
}

inline unsigned int CBloomFilter::Hash(unsigned int nHashNum, const std::vector<unsigned char>& vDataToHash) const
{
    // 0xFBA4C795 chosen as it guarantees a reasonable bit difference between nHashNum values.
    return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) % (vData.size() * 8);
}

void CBloomFilter::insert(const vector<unsigned char>& vKey)
{
    if (isFull)
        return;
    for (unsigned int i = 0; i < nHashFuncs; i++)
    {
        unsigned int nIndex = Hash(i, vKey);
        // Sets bit nIndex of vData
        vData[nIndex >> 3] |= (1 << (7 & nIndex));
    }
    isEmpty = false;
}

void CBloomFilter::insert(const COutPoint& outpoint)
{
    CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
    stream << outpoint;
    vector<unsigned char> data(stream.begin(), stream.end());
    insert(data);
}

void CBloomFilter::insert(const uint256& hash)
{
    vector<unsigned char> data(hash.begin(), hash.end());
    insert(data);
}

bool CBloomFilter::contains(const vector<unsigned char>& vKey) const
{
    if (isFull)
        return true;
    if (isEmpty)
        return false;
    for (unsigned int i = 0; i < nHashFuncs; i++)
    {
        unsigned int nIndex = Hash(i, vKey);
        // Checks bit nIndex of vData
        if (!(vData[nIndex >> 3] & (1 << (7 & nIndex))))
            return false;
    }
    return true;
}

bool CBloomFilter::contains(const COutPoint& outpoint) const
{
    CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
    stream << outpoint;
    vector<unsigned char> data(stream.begin(), stream.end());
    return contains(data);
}

bool CBloomFilter::contains(const uint256& hash) const
{
    vector<unsigned char> data(hash.begin(), hash.end());
    return contains(data);
}

void CBloomFilter::clear()
{
    vData.assign(vData.size(),0);
    isFull = false;
    isEmpty = true;
}

bool CBloomFilter::IsWithinSizeConstraints() const
{
    return vData.size() <= MAX_BLOOM_FILTER_SIZE && nHashFuncs <= MAX_HASH_FUNCS;
}

bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx)
{
    bool fFound = false;
    // Match if the filter contains the hash of tx
    //  for finding tx when they appear in a block
    if (isFull)
        return true;
    if (isEmpty)
        return false;
    const uint256& hash = tx.GetHash();
    if (contains(hash))
        fFound = true;

    for (unsigned int i = 0; i < tx.vout.size(); i++)
    {
        const CTxOut& txout = tx.vout[i];
        // Match if the filter contains any arbitrary script data element in any scriptPubKey in tx
        // If this matches, also add the specific output that was matched.
        // This means clients don't have to update the filter themselves when a new relevant tx
        // is discovered in order to find spending transactions, which avoids round-tripping and race conditions.
        CScript::const_iterator pc = txout.scriptPubKey.begin();
        vector<unsigned char> data;
        while (pc < txout.scriptPubKey.end())
        {
            opcodetype opcode;
            if (!txout.scriptPubKey.GetOp(pc, opcode, data))
                break;
            if (data.size() != 0 && contains(data))
            {
                fFound = true;
                if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_ALL)
                    insert(COutPoint(hash, i));
                else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY)
                {
                    txnouttype type;
                    vector<vector<unsigned char> > vSolutions;
                    if (Solver(txout.scriptPubKey, type, vSolutions) &&
                            (type == TX_PUBKEY || type == TX_MULTISIG))
                        insert(COutPoint(hash, i));
                }
                break;
            }
        }
    }

    if (fFound)
        return true;

    BOOST_FOREACH(const CTxIn& txin, tx.vin)
    {
        // Match if the filter contains an outpoint tx spends
        if (contains(txin.prevout))
            return true;

        // Match if the filter contains any arbitrary script data element in any scriptSig in tx
        CScript::const_iterator pc = txin.scriptSig.begin();
        vector<unsigned char> data;
        while (pc < txin.scriptSig.end())
        {
            opcodetype opcode;
            if (!txin.scriptSig.GetOp(pc, opcode, data))
                break;
            if (data.size() != 0 && contains(data))
                return true;
        }
    }

    return false;
}

void CBloomFilter::UpdateEmptyFull()
{
    bool full = true;
    bool empty = true;
    for (unsigned int i = 0; i < vData.size(); i++)
    {
        full &= vData[i] == 0xff;
        empty &= vData[i] == 0;
    }
    isFull = full;
    isEmpty = empty;
}

CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate, unsigned int nTweak) :
    b1(nElements * 2, fpRate, nTweak), b2(nElements * 2, fpRate, nTweak)
{
    // Implemented using two bloom filters of 2 * nElements each.
    // We fill them up, and clear them, staggered, every nElements
    // inserted, so at least one always contains the last nElements
    // inserted.
    nBloomSize = nElements * 2;
    nInsertions = 0;
}

void CRollingBloomFilter::insert(const std::vector<unsigned char>& vKey)
{
    if (nInsertions == 0) {
        b1.clear();
    } else if (nInsertions == nBloomSize / 2) {
        b2.clear();
    }
    b1.insert(vKey);
    b2.insert(vKey);
    if (++nInsertions == nBloomSize) {
        nInsertions = 0;
    }
}

void CRollingBloomFilter::insert(const uint256& hash)
{
    vector<unsigned char> data(hash.begin(), hash.end());
    insert(data);
}

bool CRollingBloomFilter::contains(const std::vector<unsigned char>& vKey) const
{
    if (nInsertions < nBloomSize / 2) {
        return b2.contains(vKey);
    }
    return b1.contains(vKey);
}

bool CRollingBloomFilter::contains(const uint256& hash) const
{
    vector<unsigned char> data(hash.begin(), hash.end());
    return contains(data);
}

void CRollingBloomFilter::clear()
{
    b1.clear();
    b2.clear();
    nInsertions = 0;
}
<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
// Copyright (C) 2006-2010 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

#include <vw/Stereo/OptimizedCorrelator.h>

using namespace vw;
using namespace stereo;

template <class ScoreT>
struct DisparityScore {
  ScoreT best, worst;
  int32 hdisp, vdisp;

  DisparityScore() {
    best = ScalarTypeLimits<ScoreT>::highest();
    worst = ScalarTypeLimits<ScoreT>::lowest();
    hdisp = vdisp = 0;
  }
};

struct AbsDifferenceFunctor : BinaryReturnTemplateType<DifferenceType> {
  template <class Arg1T, class Arg2T>
  typename result<AbsDifferenceFunctor(Arg1T, Arg2T)>::type
  inline operator()(Arg1T const& arg1, Arg2T const& arg2) const { return fabs(arg1-arg2); }
};

template <class Image1T, class Image2T>
inline BinaryPerPixelView<Image1T, Image2T, AbsDifferenceFunctor> abs_difference(ImageViewBase<Image1T> const& image1, ImageViewBase<Image2T> const& image2) {
  return BinaryPerPixelView<Image1T, Image2T, AbsDifferenceFunctor>(image1.impl(), image2.impl(), AbsDifferenceFunctor());
}

struct SqDifferenceFunctor : BinaryReturnTemplateType<DifferenceType> {
  template <class Arg1T, class Arg2T>
  typename result<SqDifferenceFunctor(Arg1T, Arg2T)>::type
  inline operator()(Arg1T const& arg1, Arg2T const& arg2) const {
    typename result<SqDifferenceFunctor(Arg1T, Arg2T)>::type diff = arg1 - arg2;
    return diff * diff;
  }
};

template <class Image1T, class Image2T>
inline BinaryPerPixelView<Image1T, Image2T, SqDifferenceFunctor> sq_difference(ImageViewBase<Image1T> const& image1, ImageViewBase<Image2T> const& image2) {
  return BinaryPerPixelView<Image1T, Image2T, SqDifferenceFunctor>(image1.impl(), image2.impl(), SqDifferenceFunctor());
}

// ---------------------------------------------------------------------------
//                           COST FUNCTIONS
// ---------------------------------------------------------------------------

ImageView<float> AbsDifferenceCost::calculate(int32 dx, int32 dy) {
  BBox2i right_bbox = this->bbox() + Vector2i(dx, dy);
  CropView<EdgeExtensionView<ImageView<float>, ZeroEdgeExtension> > left_window(edge_extend(m_left,ZeroEdgeExtension()), this->bbox());
  CropView<EdgeExtensionView<ImageView<float>, ZeroEdgeExtension> > right_window(edge_extend(m_right,ZeroEdgeExtension()), right_bbox);
  return this->box_filter(abs_difference(left_window, right_window));
}

ImageView<float> SqDifferenceCost::calculate(int32 dx, int32 dy) {
  BBox2i right_bbox = this->bbox() + Vector2i(dx, dy);
  CropView<EdgeExtensionView<ImageView<float>, ZeroEdgeExtension> > left_window(edge_extend(m_left,ZeroEdgeExtension()), this->bbox());
  CropView<EdgeExtensionView<ImageView<float>, ZeroEdgeExtension> > right_window(edge_extend(m_right,ZeroEdgeExtension()), right_bbox);
  return this->box_filter(sq_difference(left_window, right_window));
}

ImageView<float> NormXCorrCost::calculate(int32 dx, int32 dy) {
  BBox2i right_bbox = this->bbox() + Vector2i(dx, dy);
  CropView<EdgeExtensionView<ImageView<float>, ZeroEdgeExtension> > left_window(edge_extend(m_left, ZeroEdgeExtension()), this->bbox());
  CropView<EdgeExtensionView<ImageView<float>, ZeroEdgeExtension> > left_mean_window(edge_extend(m_left_mean, ZeroEdgeExtension()), this->bbox());
  CropView<EdgeExtensionView<ImageView<float>, ZeroEdgeExtension> > left_variance_window(edge_extend(m_left_variance, ZeroEdgeExtension()), this->bbox());

  CropView<EdgeExtensionView<ImageView<float>, ZeroEdgeExtension> > right_window(edge_extend(m_right, ZeroEdgeExtension()), right_bbox);
  CropView<EdgeExtensionView<ImageView<float>, ZeroEdgeExtension> > right_mean_window(edge_extend(m_right_mean, ZeroEdgeExtension()), right_bbox);
  CropView<EdgeExtensionView<ImageView<float>, ZeroEdgeExtension> > right_variance_window(edge_extend(m_right_variance, ZeroEdgeExtension()), right_bbox);

  ImageView<float> left_right_mean = this->box_filter(left_window * right_window);

  // We take the absolute value and subtract 1 here so that
  // invalid (empty) regions of the image (which would normally
  // evaluate to zero) end up evaluating to 1.0, and areas that
  // are highly correlated are closer to zero.
  //return 1-abs(pow(left_right_mean - left_mean_window * right_mean_window, 2) /
  //             left_variance_window / right_variance_window);
  left_right_mean = left_right_mean -left_mean_window * right_mean_window;
  return 1-abs(left_right_mean*left_right_mean / left_variance_window / right_variance_window);
}

// ---------------------------------------------------------------------------
//                           CORRELATE()
// ---------------------------------------------------------------------------
ImageView<PixelMask<Vector2f> > vw::stereo::correlate(boost::shared_ptr<StereoCostFunction> const& cost_function,
                                                      BBox2i const& search_window,
                                                      ProgressCallback const& progress) {

  int32 width = cost_function->cols();
  int32 height = cost_function->rows();

  ImageView<DisparityScore<float> > result_buf(width, height);
  ImageView<float> cost_buf(width, height);

  int32 current_iteration = 0;
  int32 total_iterations = (search_window.width() + 1) * (search_window.height() + 1);

  BBox2i left_bbox = cost_function->bbox();
  for (int32 dy = search_window.min().y(); dy <= search_window.max().y(); dy++) {
    for (int32 dx = search_window.min().x(); dx <= search_window.max().x(); dx++) {
      BBox2i right_bbox = cost_function->bbox() + Vector2i (dx,dy);

      CropView<ImageView<DisparityScore<float> > > result_buf_window(result_buf, left_bbox);
      CropView<ImageView<float> > cost_buf_window(cost_buf, left_bbox);

      // Calculate cost function
      cost_buf_window = cost_function->calculate(dx,dy);

      CropView<ImageView<DisparityScore<float> > >::pixel_accessor result_row_acc = result_buf_window.origin();
      CropView<ImageView<float> >::pixel_accessor cost_buf_row_acc = cost_buf_window.origin();
      for (int32 y = 0; y < left_bbox.height(); y++) {
        CropView<ImageView<DisparityScore<float> > >::pixel_accessor result_col_acc = result_row_acc;
        CropView<ImageView<float> >::pixel_accessor cost_buf_col_acc = cost_buf_row_acc;
        for (int32 x = 0; x < left_bbox.width(); x++) {
          if (*cost_buf_col_acc < (*result_col_acc).best) {
            (*result_col_acc).best = *cost_buf_col_acc;
            (*result_col_acc).hdisp = dx;
            (*result_col_acc).vdisp = dy;
          }
          if (*cost_buf_col_acc > (*result_col_acc).worst) {
            (*result_col_acc).worst = *cost_buf_col_acc;
          }
          result_col_acc.next_col();
          cost_buf_col_acc.next_col();
        }
        result_row_acc.next_row();
        cost_buf_row_acc.next_row();
      }

      progress.report_fractional_progress(++current_iteration, total_iterations);
      progress.abort_if_requested();
    }
  }

  // convert from the local result buffer to the return format
  ImageView<PixelMask<Vector2f> > result(width, height);

  for (int32 x = 0; x < width; x++) {
    for (int32 y = 0; y < height; y++) {
      if (result_buf(x, y).best == ScalarTypeLimits<float>::highest() ||
          result_buf(x, y).best == result_buf(x, y).worst) {
        invalidate(result(x,y));
      } else {
        result(x, y)[0] = result_buf(x,y).hdisp;
        result(x, y)[1] = result_buf(x,y).vdisp;
        validate( result(x,y) );
      }
    }
  }
  progress.report_finished();
  return result;
}

<commit_msg>Improve readability in optimized correlator<commit_after>// __BEGIN_LICENSE__
// Copyright (C) 2006-2010 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

#include <vw/Stereo/OptimizedCorrelator.h>

using namespace vw;
using namespace stereo;

template <class ScoreT>
struct DisparityScore {
  ScoreT best, worst;
  int32 hdisp, vdisp;

  DisparityScore() {
    best = ScalarTypeLimits<ScoreT>::highest();
    worst = ScalarTypeLimits<ScoreT>::lowest();
    hdisp = vdisp = 0;
  }
};

struct AbsDifferenceFunctor : BinaryReturnTemplateType<DifferenceType> {
  template <class Arg1T, class Arg2T>
  typename result<AbsDifferenceFunctor(Arg1T, Arg2T)>::type
  inline operator()(Arg1T const& arg1, Arg2T const& arg2) const { return fabs(arg1-arg2); }
};

template <class Image1T, class Image2T>
inline BinaryPerPixelView<Image1T, Image2T, AbsDifferenceFunctor>
abs_difference(ImageViewBase<Image1T> const& image1, ImageViewBase<Image2T> const& image2) {
  return BinaryPerPixelView<Image1T, Image2T, AbsDifferenceFunctor>(image1.impl(), image2.impl(), AbsDifferenceFunctor());
}

struct SqDifferenceFunctor : BinaryReturnTemplateType<DifferenceType> {
  template <class Arg1T, class Arg2T>
  typename result<SqDifferenceFunctor(Arg1T, Arg2T)>::type
  inline operator()(Arg1T const& arg1, Arg2T const& arg2) const {
    typename result<SqDifferenceFunctor(Arg1T, Arg2T)>::type diff = arg1 - arg2;
    return diff * diff;
  }
};

template <class Image1T, class Image2T>
inline BinaryPerPixelView<Image1T, Image2T, SqDifferenceFunctor>
sq_difference(ImageViewBase<Image1T> const& image1, ImageViewBase<Image2T> const& image2) {
  return BinaryPerPixelView<Image1T, Image2T, SqDifferenceFunctor>(image1.impl(), image2.impl(), SqDifferenceFunctor());
}

// ---------------------------------------------------------------------------
//                           COST FUNCTIONS
// ---------------------------------------------------------------------------

ImageView<float> AbsDifferenceCost::calculate(int32 dx, int32 dy) {
  typedef ZeroEdgeExtension EdgeT;
  typedef CropView<EdgeExtensionView<ImageView<float>, EdgeT > > OverCropT;

  BBox2i right_bbox = this->bbox() + Vector2i(dx, dy);
  OverCropT left_window(edge_extend(m_left, EdgeT()), this->bbox());
  OverCropT right_window(edge_extend(m_right, EdgeT()), right_bbox);
  return this->box_filter(abs_difference(left_window, right_window));
}

ImageView<float> SqDifferenceCost::calculate(int32 dx, int32 dy) {
  typedef ZeroEdgeExtension EdgeT;
  typedef CropView<EdgeExtensionView<ImageView<float>, EdgeT > > OverCropT;

  BBox2i right_bbox = this->bbox() + Vector2i(dx, dy);
  OverCropT left_window(edge_extend(m_left, EdgeT()), this->bbox());
  OverCropT right_window(edge_extend(m_right, EdgeT()), right_bbox);
  return this->box_filter(sq_difference(left_window, right_window));
}

ImageView<float> NormXCorrCost::calculate(int32 dx, int32 dy) {
  typedef ZeroEdgeExtension EdgeT;
  typedef CropView<EdgeExtensionView<ImageView<float>, EdgeT > > OverCropT;

  BBox2i right_bbox = this->bbox() + Vector2i(dx, dy);
  OverCropT left_window(edge_extend(m_left, EdgeT()), this->bbox());
  OverCropT left_mean_window(edge_extend(m_left_mean, EdgeT()), this->bbox());
  OverCropT left_variance_window(edge_extend(m_left_variance, EdgeT()), this->bbox());

  OverCropT right_window(edge_extend(m_right, EdgeT()), right_bbox);
  OverCropT right_mean_window(edge_extend(m_right_mean, EdgeT()), right_bbox);
  OverCropT right_variance_window(edge_extend(m_right_variance, EdgeT()), right_bbox);

  ImageView<float> left_right_mean = this->box_filter(left_window * right_window);

  // We take the absolute value and subtract 1 here so that
  // invalid (empty) regions of the image (which would normally
  // evaluate to zero) end up evaluating to 1.0, and areas that
  // are highly correlated are closer to zero.
  //return 1-abs(pow(left_right_mean - left_mean_window * right_mean_window, 2) /
  //             left_variance_window / right_variance_window);
  left_right_mean = left_right_mean -left_mean_window * right_mean_window;
  return 1-abs(left_right_mean*left_right_mean / left_variance_window / right_variance_window);
}

// ---------------------------------------------------------------------------
//                           CORRELATE()
// ---------------------------------------------------------------------------
ImageView<PixelMask<Vector2f> > vw::stereo::correlate(boost::shared_ptr<StereoCostFunction> const& cost_function,
                                                      BBox2i const& search_window,
                                                      ProgressCallback const& progress) {

  int32 width = cost_function->cols();
  int32 height = cost_function->rows();

  ImageView<DisparityScore<float> > result_buf(width, height);
  ImageView<float> cost_buf(width, height);

  int32 current_iteration = 0;
  int32 total_iterations = (search_window.width() + 1) * (search_window.height() + 1);

  BBox2i left_bbox = cost_function->bbox();
  for (int32 dy = search_window.min().y(); dy <= search_window.max().y(); dy++) {
    for (int32 dx = search_window.min().x(); dx <= search_window.max().x(); dx++) {
      BBox2i right_bbox = cost_function->bbox() + Vector2i (dx,dy);

      CropView<ImageView<DisparityScore<float> > > result_buf_window(result_buf, left_bbox);
      CropView<ImageView<float> > cost_buf_window(cost_buf, left_bbox);

      // Calculate cost function
      cost_buf_window = cost_function->calculate(dx,dy);

      CropView<ImageView<DisparityScore<float> > >::pixel_accessor result_row_acc = result_buf_window.origin();
      CropView<ImageView<float> >::pixel_accessor cost_buf_row_acc = cost_buf_window.origin();
      for (int32 y = 0; y < left_bbox.height(); y++) {
        CropView<ImageView<DisparityScore<float> > >::pixel_accessor result_col_acc = result_row_acc;
        CropView<ImageView<float> >::pixel_accessor cost_buf_col_acc = cost_buf_row_acc;
        for (int32 x = 0; x < left_bbox.width(); x++) {
          if (*cost_buf_col_acc < (*result_col_acc).best) {
            (*result_col_acc).best = *cost_buf_col_acc;
            (*result_col_acc).hdisp = dx;
            (*result_col_acc).vdisp = dy;
          }
          if (*cost_buf_col_acc > (*result_col_acc).worst) {
            (*result_col_acc).worst = *cost_buf_col_acc;
          }
          result_col_acc.next_col();
          cost_buf_col_acc.next_col();
        }
        result_row_acc.next_row();
        cost_buf_row_acc.next_row();
      }

      progress.report_fractional_progress(++current_iteration, total_iterations);
      progress.abort_if_requested();
    }
  }

  // convert from the local result buffer to the return format
  ImageView<PixelMask<Vector2f> > result(width, height);

  for (int32 x = 0; x < width; x++) {
    for (int32 y = 0; y < height; y++) {
      if (result_buf(x, y).best == ScalarTypeLimits<float>::highest() ||
          result_buf(x, y).best == result_buf(x, y).worst) {
        invalidate(result(x,y));
      } else {
        result(x, y)[0] = result_buf(x,y).hdisp;
        result(x, y)[1] = result_buf(x,y).vdisp;
        validate( result(x,y) );
      }
    }
  }
  progress.report_finished();
  return result;
}

<|endoftext|>