text:
////////////////////////////////////////////////////////////////////////
// fast cache
//
// Manuel Martinez (manuel.martinez@kit.edu)
//
// license: LGPLv3

#pragma once
#include <uSnippets/object.hpp>
#include <uSnippets/serializer.hpp>

#include <boost/noncopyable.hpp>

#include <fstream>
#include <list>
#include <map>
#include <unordered_map>

#include <mutex>
#include <limits>

namespace uSnippets {
class GenericCache : private boost::noncopyable {

	typedef std::lock_guard<std::recursive_mutex> Lock;
	std::recursive_mutex m;
	std::string filename;
	std::fstream file;

	struct Chunk {

		std::string key;
		uint64_t count;
		size_t dataSize;

		size_t size;
		size_t pos;
		size_t dataPos;
		std::multimap<size_t, std::list<Chunk>::iterator>::iterator holeIt; // Hole BEFORE the actual chunk

		template<class Archive> void serialize(Archive &ar, const uint) { ar & key & count & dataSize; }
	};

	std::list<Chunk> chunks; //All chunks sorted by disk state
	std::unordered_map<std::string, std::list<Chunk>::iterator> index; //Dictionary from the name to the valid chunk
	std::multimap<size_t, std::list<Chunk>::iterator> holes; //All holes and its related chunk (the hole is before the chunk)

	void updateHole(std::list<Chunk>::iterator it) { // Update the hole between this chunk and the previous one.

		Lock lock(m);
		if (it==chunks.end()) return;

		if (it->holeIt != holes.end()) holes.erase(it->holeIt);

		int64_t holeSize = it->pos; //may be temporally negative when resizing the index
		if (it != chunks.begin()) holeSize -= std::prev(it)->pos + std::prev(it)->size;

		it->holeIt = (holeSize>0?holes.insert({holeSize, it}):holes.end());
	}

	uint64_t freeAndGetCount(const std::string &key) {

		Lock lock(m);
		auto count = 0;
		auto indexIt = index.find(key);
		if (indexIt != index.end()) {

			if (indexIt->second->holeIt != holes.end())  holes.erase(indexIt->second->holeIt);

			count = indexIt->second->count;
			updateHole(chunks.erase(indexIt->second));
			index.erase(indexIt);
		}
		return count;
	}

	bool getRAW(const std::string &key, std::string &sdata) {

		if (not file.is_open()) return false;

		auto indexIt = index.find(key);
		if (indexIt == index.end()) return false;
		Chunk &chunk = *indexIt->second;

		sdata.resize(chunk.dataSize);
//		file.sync();
		Lock lock(m);
		file.seekg(chunk.dataPos);
		file.read(&sdata[0], sdata.size());
		return true;
	}

	void setRAW(const std::string &key, const std::string &sdata) {

		Lock lock(m);
		if (not file.is_open()) return;

		invalidateIndex();

		uint64_t count = freeAndGetCount(key);

		Chunk chunk;
		chunk.key = key;
		chunk.count = count+1;
		chunk.dataSize = sdata.size();
		chunk.holeIt = holes.end();

		std::string sheader = Serializer::serialize(chunk);
		chunk.size = sheader.size() + chunk.dataSize + 1;

		auto holeIt = holes.upper_bound(chunk.size);
		auto chunkIt = chunks.end();
		if (holeIt != holes.end()) {

			chunk.pos = holeIt->second->pos - holeIt->first; //store this chunk next to the previous one
			chunkIt = chunks.insert(holeIt->second, chunk);
			updateHole(std::next(chunkIt));
		} else if (not chunks.empty()) {
			chunk.pos = chunks.rbegin()->pos + chunks.rbegin()->size; //store this chunk next to the last one
			chunkIt = chunks.insert(chunks.end(), chunk);

		} else {
			chunk.pos = 0; //store this chunk first
			chunkIt = chunks.insert(chunks.end(), chunk);
		}

		chunkIt->dataPos = chunkIt->pos + sheader.size();

		if (chunk.pos) { file.seekp(chunk.pos-1); file.put('\n'); }
		file.seekp(chunk.pos);
		file << sheader << sdata;
		if (std::next(chunkIt) != chunks.end())
			file << std::string(std::next(chunkIt)->pos-file.tellp()-1,'-') << '\n';
		else
			file << '\n' << Serializer::serialize(Chunk()) << '\n';
		file << std::flush;

		index.emplace(key, chunkIt);
	}

	bool indexed = false;
	void invalidateIndex() {

		Lock lock(m);
		if (not indexed) return;
		file.seekp(-1,file.end); file.put('!');
		indexed = false;
	}

	bool getIndex() {

		Lock lock(m);
		try {

			file.seekg (-1, file.end);
			if (file.get()!='#') return false;
			file.seekg (-20, file.end);
			size_t pos=0;
			for (int i=0; i<19; i++) pos = pos*10+file.get()-'0';
			file.sync();
			file.seekg(pos);

			uint64_t nChunks=0;
			Serializer::unserialize(file, nChunks);
			for (uint64_t i=0; i<nChunks; i++) {
				Chunk chunk;
				Serializer::unserialize(file, chunk);
				Serializer::unserialize(file, chunk.pos);
				Serializer::unserialize(file, chunk.size);
				chunk.holeIt = holes.end();
				chunk.dataPos = chunk.pos + (chunk.size - chunk.dataSize - 1);
				index.emplace(chunk.key, chunks.insert(chunks.end(), chunk));
			}
			for (auto it = chunks.begin(); it!=chunks.end(); it++) updateHole(it);
		} catch (std::istream::failure) { file.clear(); return false; }
		return true;
	}

	bool writeIndex() {

		Lock lock(m);
		if (chunks.empty()) return false;
		try {

			std::string sindex;
			sindex += Serializer::serialize(index.size());
			for (auto &chunk : chunks) {
				sindex += Serializer::serialize(chunk);
				sindex += Serializer::serialize(chunk.pos);
				sindex += Serializer::serialize(chunk.size);
			}
			setRAW("__index", sindex);

			size_t pos = index["__index"]->dataPos;

			std::string spos = "0000000000000000000#";
			for (int i=18; i>=0; i--) { spos[i]+= pos%10; pos /= 10; }

			// Do not blindly write it at the end. Filesize would increase strongly.
			file.seekp(0,file.end);
			file.seekp (std::max(int64_t(chunks.back().pos+chunks.back().size+4), int64_t(file.tellp())-20));
			file << spos << std::flush;

			freeAndGetCount("__index");
		} catch (std::istream::failure) { file.clear(); return false; }
		return true;
	}

public:

	GenericCache(      GenericCache &&) = default; GenericCache& operator=(      GenericCache &&) = default;

	GenericCache(std::string filename) : filename(filename) {

		Lock lock(m);

		if (filename.empty()) return;

		// Create file if needed
		std::fstream(filename, std::ios_base::out | std::ios_base::app);

		file.open(filename, file.in | file.out | file.binary);
		if (not file.is_open()) return;

		indexed = getIndex();
		if (indexed) return;

		// Rebuild Index
		file.seekg(0);
		while (true) {
			size_t pos = file.tellg();
			Chunk chunk;
			if (not Serializer::unserialize(file, chunk) or chunk.count==0) break;

			chunk.pos = pos;
			chunk.dataPos = file.tellg();
			chunk.size = (chunk.dataPos-chunk.pos) + chunk.dataSize + 1;
			chunk.holeIt = holes.end();

			file.seekg(chunk.pos+chunk.size-1);
			file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');

			auto found = index.find(chunk.key);
			if (found==index.end()) {
				index.emplace(chunk.key, chunks.insert(chunks.end(), chunk));
			} else if (found->second->count<chunk.count) {
				chunks.erase(found->second);
				found->second = chunks.insert(chunks.end(), chunk);
			}
		}
		file.clear();
		for (auto it = chunks.begin(); it!=chunks.end(); it++) updateHole(it);

		indexed = writeIndex();
	}

	virtual ~GenericCache() {
		if (not indexed)
			indexed = writeIndex();
	}

	template<class T>
	bool get(const std::string &key, T &t) { std::string str; return getRAW(key, str) and Serializer::unserialize<T>(str,t);}

	bool get(const std::string &key, std::string &str) { return getRAW(key, str); }

	template<class T>
	void set(const std::string &key, const T &t) { setRAW(key, Serializer::serialize(t)); }

	void set(const std::string &key, const std::string  &t) { setRAW(key, t); }

	void purge() {

		Lock lock(m);
		chunks.clear();
		index.clear();
		holes.clear();
		indexed = false;

		file.close();
		file.open(filename, file.in | file.out | file.binary | file.trunc);

		file << Serializer::serialize(Chunk()) << std::flush;
	}

	std::vector<std::string> getKeys() {

		Lock lock(m);
		std::vector<std::string> keys;
		for (auto &c : chunks) keys.push_back(c.key);
		//std::sort(keys.begin(), keys.end());
		return keys;
	}

	void free(const std::string &key) { Lock lock(m); freeAndGetCount(key); }

	size_t usage() {

		Lock lock(m);
		size_t ret = 0;
		for (auto &chunk : chunks)
			ret += chunk.size;
		return ret;
	}
};
}

max_stars_repo_name: MartinezTorres/uSnippets

max_issues_repo_name: MartinezTorres/uSnippets

max_forks_repo_name: MartinezTorres/uSnippets


text:
#include "shift/network/tcp_socket_client.hpp"
#include "shift/network/tcp_socket_client_impl.hpp"
#include "shift/network/network_host.hpp"
#include <shift/log/log.hpp>
#include <shift/platform/fpexceptions.hpp>
#include <shift/core/boost_disable_warnings.hpp>
#include <boost/bind.hpp>
#include <shift/core/boost_restore_warnings.hpp>

namespace shift::network
{
tcp_socket_client::tcp_socket_client(network::options options)
: _impl(std::make_unique<impl>(options))
{
}

tcp_socket_client::~tcp_socket_client()
{
  // If the following assertion fails you did a bad job in making sure that
  // all socket instances are being destroyed before the network host.
  BOOST_ASSERT(network_host::singleton_instantiated());

  if (_impl->underlying_socket.is_open())
    close();
  if (_impl->host.debug_socket_lifetime)
    network_log() << "Deleting Tcp client socket.";
}

std::shared_ptr<tcp_socket_listener> tcp_socket_client::parent() const
{
  return _impl->parent;
}

void tcp_socket_client::close()
{
  _impl->close(*this);
}

bool tcp_socket_client::connect(const boost::asio::ip::address& remote_address,
                                std::uint16_t remote_port)
{
  return _impl->connect(*this, remote_address, remote_port);
}

void tcp_socket_client::post(std::vector<char> buffer)
{
  // Serialize posting of new buffers with the coroutine.
  _impl->read_write_strand.post(
    boost::bind(&tcp_socket_client::impl::post_routine, _impl.get(),
                shared_from_this(), std::move(buffer)));
}

void tcp_socket_client::queue(std::vector<char> buffer)
{
  network_host::singleton_instance().queue_packet(shared_from_this(),
                                                  std::move(buffer));
}

boost::asio::ip::tcp::endpoint tcp_socket_client::local_endpoint() const
{
  return _impl->underlying_socket.local_endpoint();
}

boost::asio::ip::tcp::endpoint tcp_socket_client::remote_endpoint() const
{
  return _impl->underlying_socket.remote_endpoint();
}

void tcp_socket_client::parent(std::shared_ptr<tcp_socket_listener> other)
{
  _impl->parent = std::move(other);
}

void tcp_socket_client::adopt()
{
  _impl->adopt(*this);
}
}

ext: cpp

max_stars_repo_name: cspanier/shift

max_issues_repo_name: cspanier/shift

max_forks_repo_name: cspanier/shift


text:
//               Copyright Marek Dalewski 2017
// Distributed under the Boost Software License, Version 1.0.
//        (See accompanying file LICENSE.md or copy at
//           http://www.boost.org/LICENSE_1_0.txt)

#include <commander/algorithm.hpp>

#include <boost/test/unit_test.hpp>

#include "arithmetic_helpers.hpp"

#include <tuple>
#include <type_traits>

BOOST_AUTO_TEST_CASE( arithmetic_compare )
{
    namespace com  = commander;
    namespace comd = commander::detail;

    using schar8  = std::make_signed_t<char>;     using uchar8  = std::make_unsigned_t<char>;
    using schar16 = std::make_signed_t<char16_t>; using uchar16 = std::make_unsigned_t<char16_t>;
    using schar32 = std::make_signed_t<char32_t>; using uchar32 = std::make_unsigned_t<char32_t>;
    using swchar  = std::make_signed_t<wchar_t>;  using uwchar  = std::make_unsigned_t<wchar_t>;

    const auto non_arithmetic_tuple = std::make_tuple(non_arithmetic_true(), non_arithmetic_false());
    const auto int_tuple = std::make_tuple(int(-5), int(-1), int(0), int(1), int(5));
    const auto float_tuple = std::make_tuple(float(-5), float(-1), float(0), float(1), float(5));
    const auto char_tuple = std::make_tuple(
        sc<schar8>(sc<char>('a')),      sc<uchar8>(sc<char>('a')),
        sc<schar16>(sc<char16_t>('a')), sc<uchar16>(sc<char16_t>('a')),
        sc<schar32>(sc<char32_t>('a')), sc<uchar32>(sc<char32_t>('a')),
        sc<swchar>(sc<wchar_t>('a')),   sc<uwchar>(sc<wchar_t>('a'))
    );

    const auto bool_limits_tuple = std::make_tuple(true, false);
    const auto signed_integral_limits_tuple = std::make_tuple(
        nl<int8_t>::max(),  nl<int8_t>::lowest(),
        nl<int16_t>::max(), nl<int16_t>::lowest(),
        nl<int32_t>::max(), nl<int32_t>::lowest(),
        nl<int64_t>::max(), nl<int64_t>::lowest()
    );
    const auto unsigned_integral_limits_tuple = std::make_tuple(
        nl<uint8_t>::max(),  nl<uint8_t>::lowest(),
        nl<uint16_t>::max(), nl<uint16_t>::lowest(),
        nl<uint32_t>::max(), nl<uint32_t>::lowest(),
        nl<uint64_t>::max(), nl<uint64_t>::lowest()
    );
    const auto floating_point_limits_tuple = std::make_tuple(
        nl<float>::max(),       nl<float>::lowest(),
        nl<double>::max(),      nl<double>::lowest(),
        nl<long double>::max(), nl<long double>::lowest()
    );

    {
        com::tuple_visit(
            [&](const auto& non_arithmetic) {
                size_t count = 0;
                com::tuple_visit(
                    [&](const auto& v) { count += comd::arithmetic_compare(non_arithmetic, v) ? 1 : 0; },
                    non_arithmetic_tuple, int_tuple, float_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
                );
                BOOST_CHECK(count == 0);
            },
            non_arithmetic_tuple
        );
    }

    {
        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 0>(int_tuple), std::get< 0>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 0>(int_tuple), std::get< 0>(float_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 0>(int_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 2);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(int_tuple), std::get< 1>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(int_tuple), std::get< 1>(float_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 1>(int_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 2);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(int_tuple), std::get< 2>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(int_tuple), std::get< 2>(float_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(int_tuple), std::get< 1>(bool_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(int_tuple), std::get< 1>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(int_tuple), std::get< 3>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(int_tuple), std::get< 5>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(int_tuple), std::get< 7>(unsigned_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 2>(int_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 7);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(int_tuple), std::get< 3>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(int_tuple), std::get< 3>(float_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(int_tuple), std::get< 0>(bool_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 3>(int_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 3);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 4>(int_tuple), std::get< 4>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 4>(int_tuple), std::get< 4>(float_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 4>(int_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 2);
        }
    }

    {
        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 0>(float_tuple), std::get< 0>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 0>(float_tuple), std::get< 0>(float_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 0>(float_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 2);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(float_tuple), std::get< 1>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(float_tuple), std::get< 1>(float_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 1>(float_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 2);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(float_tuple), std::get< 2>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(float_tuple), std::get< 2>(float_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(float_tuple), std::get< 1>(bool_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(float_tuple), std::get< 1>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(float_tuple), std::get< 3>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(float_tuple), std::get< 5>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(float_tuple), std::get< 7>(unsigned_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 2>(float_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 7);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(float_tuple), std::get< 3>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(float_tuple), std::get< 3>(float_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(float_tuple), std::get< 0>(bool_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 3>(float_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 3);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 4>(float_tuple), std::get< 4>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 4>(float_tuple), std::get< 4>(float_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 4>(float_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 2);
        }
    }

    {
        com::tuple_visit(
            [&](const auto& character) {
                BOOST_CHECK(com::tuple_visit_conjunction(
                    [&](const auto& v) -> bool { return comd::arithmetic_compare(character, v); },
                    char_tuple
                ) == true);

                size_t count = 0;
                com::tuple_visit(
                    [&](const auto& v) { count += comd::arithmetic_compare(character, v) ? 1 : 0; },
                    non_arithmetic_tuple, int_tuple, float_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
                );
                BOOST_CHECK(count == 0);
            },
            char_tuple
        );
    }

    {
        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 0>(bool_limits_tuple), std::get< 3>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 0>(bool_limits_tuple), std::get< 3>(float_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 0>(bool_limits_tuple), std::get< 0>(bool_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 0>(bool_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 3);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(bool_limits_tuple), std::get< 2>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(bool_limits_tuple), std::get< 2>(float_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(bool_limits_tuple), std::get< 1>(bool_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(bool_limits_tuple), std::get< 1>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(bool_limits_tuple), std::get< 3>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(bool_limits_tuple), std::get< 5>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(bool_limits_tuple), std::get< 7>(unsigned_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 1>(bool_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 7);
        }
    }

    {
        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 0>(signed_integral_limits_tuple), std::get< 0>(signed_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 0>(signed_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(signed_integral_limits_tuple), std::get< 1>(signed_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 1>(signed_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(signed_integral_limits_tuple), std::get< 2>(signed_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 2>(signed_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(signed_integral_limits_tuple), std::get< 3>(signed_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 3>(signed_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 4>(signed_integral_limits_tuple), std::get< 4>(signed_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 4>(signed_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 5>(signed_integral_limits_tuple), std::get< 5>(signed_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 5>(signed_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 6>(signed_integral_limits_tuple), std::get< 6>(signed_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 6>(signed_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 7>(signed_integral_limits_tuple), std::get< 7>(signed_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 7>(signed_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }
    }

    {
        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 0>(unsigned_integral_limits_tuple), std::get< 0>(unsigned_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 0>(unsigned_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(unsigned_integral_limits_tuple), std::get< 2>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(unsigned_integral_limits_tuple), std::get< 2>(float_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(unsigned_integral_limits_tuple), std::get< 1>(bool_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(unsigned_integral_limits_tuple), std::get< 1>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(unsigned_integral_limits_tuple), std::get< 3>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(unsigned_integral_limits_tuple), std::get< 5>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(unsigned_integral_limits_tuple), std::get< 7>(unsigned_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 1>(unsigned_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 7);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(unsigned_integral_limits_tuple), std::get< 2>(unsigned_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 2>(unsigned_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(unsigned_integral_limits_tuple), std::get< 2>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(unsigned_integral_limits_tuple), std::get< 2>(float_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(unsigned_integral_limits_tuple), std::get< 1>(bool_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(unsigned_integral_limits_tuple), std::get< 1>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(unsigned_integral_limits_tuple), std::get< 3>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(unsigned_integral_limits_tuple), std::get< 5>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(unsigned_integral_limits_tuple), std::get< 7>(unsigned_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 3>(unsigned_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 7);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 4>(unsigned_integral_limits_tuple), std::get< 4>(unsigned_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 4>(unsigned_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 5>(unsigned_integral_limits_tuple), std::get< 2>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 5>(unsigned_integral_limits_tuple), std::get< 2>(float_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 5>(unsigned_integral_limits_tuple), std::get< 1>(bool_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 5>(unsigned_integral_limits_tuple), std::get< 1>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 5>(unsigned_integral_limits_tuple), std::get< 3>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 5>(unsigned_integral_limits_tuple), std::get< 5>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 5>(unsigned_integral_limits_tuple), std::get< 7>(unsigned_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 5>(unsigned_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 7);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 6>(unsigned_integral_limits_tuple), std::get< 6>(unsigned_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 6>(unsigned_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 7>(unsigned_integral_limits_tuple), std::get< 2>(int_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 7>(unsigned_integral_limits_tuple), std::get< 2>(float_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 7>(unsigned_integral_limits_tuple), std::get< 1>(bool_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 7>(unsigned_integral_limits_tuple), std::get< 1>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 7>(unsigned_integral_limits_tuple), std::get< 3>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 7>(unsigned_integral_limits_tuple), std::get< 5>(unsigned_integral_limits_tuple)) == true);
            BOOST_CHECK(comd::arithmetic_compare(std::get< 7>(unsigned_integral_limits_tuple), std::get< 7>(unsigned_integral_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 7>(unsigned_integral_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 7);
        }
    }

    {
        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 0>(floating_point_limits_tuple), std::get< 0>(floating_point_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 0>(floating_point_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 1>(floating_point_limits_tuple), std::get< 1>(floating_point_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 1>(floating_point_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 2>(floating_point_limits_tuple), std::get< 2>(floating_point_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 2>(floating_point_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 3>(floating_point_limits_tuple), std::get< 3>(floating_point_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 3>(floating_point_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 4>(floating_point_limits_tuple), std::get< 4>(floating_point_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 4>(floating_point_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }

        {
            BOOST_CHECK(comd::arithmetic_compare(std::get< 5>(floating_point_limits_tuple), std::get< 5>(floating_point_limits_tuple)) == true);

            size_t count = 0;
            com::tuple_visit(
                [&](const auto& v) { count += comd::arithmetic_compare(std::get< 5>(floating_point_limits_tuple), v) ? 1 : 0; },
                non_arithmetic_tuple, int_tuple, float_tuple, char_tuple, bool_limits_tuple, signed_integral_limits_tuple, unsigned_integral_limits_tuple, floating_point_limits_tuple
            );
            BOOST_CHECK(count == 1);
        }
    }
}

max_stars_repo_name: daishe/commander

max_issues_repo_name: daishe/commander

max_forks_repo_name: daishe/commander


text:
/*******************************************************************************
*
*  Filename    : RooFit_SimFit.cc
*  Description : Making simultaneous fit objects
*  Author      : Yi-Mu "Enoch" Chen [ ensc@hep1.phys.ntu.edu.tw ]
*
*******************************************************************************/
#include "TstarAnalysis/LimitCalc/interface/Common.hpp"
#include "TstarAnalysis/LimitCalc/interface/MakeKeysPdf.hpp"
#include "TstarAnalysis/LimitCalc/interface/SampleRooFitMgr.hpp"
#include "TstarAnalysis/LimitCalc/interface/SimFit.hpp"
#include "TstarAnalysis/LimitCalc/interface/SimFitVal.hpp"
#include "TstarAnalysis/LimitCalc/interface/Template.hpp"

#include "ManagerUtils/Maths/interface/RooFitExt.hpp"
#include "ManagerUtils/PlotUtils/interface/Common.hpp"
#include "ManagerUtils/PlotUtils/interface/RooFitUtils.hpp"
#include "TstarAnalysis/Common/interface/PlotStyle.hpp"

#include <boost/format.hpp>
#include <fstream>
#include <stdio.h>

#include "RooAddPdf.h"
#include "RooFitResult.h"
#include "RooGenericPdf.h"
#include "RooMinimizer.h"
#include "RooNLLVar.h"
#include "RooProdPdf.h"
#include "RooRealVar.h"
#include "RooWorkspace.h"
#include "TFile.h"

using namespace std;
using namespace mgr;

/*******************************************************************************
*   Object naming convetions functions
*******************************************************************************/
string
SimFitBGPdfName( const string& datasetname, const string& signalname )
{
  return datasetname + signalname + "simfitbg";
}

string
SimFitCombinePdfName( const string& datasetname, const string& signalname )
{
  return datasetname + signalname  + "simfitcomb";
}

string
StitchSimFitBgPdfname( const std::string& signalname )
{
  return signalname + "simfitbgmaster";
}

/*******************************************************************************
*   Main control function
*******************************************************************************/
void
MakeSimFit(
  SampleRooFitMgr*          data,
  SampleRooFitMgr*          mc,
  vector<SampleRooFitMgr*>& signal_list
  )
{
  vector<RooAbsPdf*> pdflist;
  vector<RooAbsReal*> funclist;

  // Getting fit result from default MC dataset ;
  // RooFitResult* bgconstrain = FitBackgroundTemplate( mc, "" );

  for( auto& sig : signal_list ){
    MakeFullKeysPdf( sig );

    auto fiterr = SimFitSingle( data, sig, "", nullptr );

    MakeSimFitPlot( data, sig, fiterr, "" );

    const double zoomcen   = GetInt( sig->Name() );
    const double zoomwidth = 200;
    MakeSimFitPlot( data, sig, fiterr, "", "zoom", zoomcen-zoomwidth, zoomcen+zoomwidth, 40  );

    // pdflist.push_back( data->Pdf( SimFitBGPdfName( "", sig->Name() ) ) );
    pdflist.push_back( data->Pdf( StitchSimFitBgPdfname( sig->Name() ) ) );
    pdflist.push_back( sig->Pdf( StitchKeyPdfName ) );
    funclist.push_back( sig->Func( StitchKeyNormName ) );
  }

  // Smoothing the efficiency
  if( limnamer.CheckInput( "smootheff" ) ){
    SmoothEfficiency( signal_list );
  }

  for( auto& sig : signal_list ){
    MakeSimFitCardFile( data, sig );
  }

  SaveRooWorkSpace(
    data->DataSet( "" ),
    pdflist,
    {}
    );

  MakeVarValPlot( data );
}

/*******************************************************************************
*   Fitting control flow
*******************************************************************************/
RooFitResult*
SimFitSingle(
  SampleRooFitMgr* data,
  SampleRooFitMgr* sig,
  const string&    datasetname,
  RooFitResult*    bgconstrain
  )
{
  const string bgfuncname   = SimFitBGPdfName( datasetname, sig->Name() );
  const string combfuncname = SimFitCombinePdfName( datasetname, sig->Name() );
  const string fitfunc      = limnamer.GetInput<string>( "fitfunc" );

  RooAbsData* fitdataset = data->DataSet( datasetname );
  RooAbsPdf* bgpdf       = data->NewPdf( bgfuncname, fitfunc );
  RooAbsPdf* sigpdf      = sig->Pdf( StitchKeyPdfName );   // attempting simfit will default signal regardless
  //  sig->SetConstant(kFALSE);
  const double numdata = fitdataset->sumEntries();

  RooRealVar* nb = data->NewVar( combfuncname+"nb", numdata, 0, 1000000 );
  RooRealVar* ns = data->NewVar( combfuncname+"ns", 0, 0, 1000 );

  RooAddPdf* model = new RooAddPdf(
    combfuncname.c_str(),
    combfuncname.c_str(),
    RooArgList( *bgpdf, *sigpdf ),
    RooArgList( *nb,    *ns     )
    );
  data->AddPdf( model );

  cout << "\n>>>>>> Running the fitting! " << endl;
  cout << ">>>>>> " << nb->getVal() << endl;
  cout << ">>>>>> " << ns->getVal() << endl;

  const unsigned maxiter = ( datasetname.find( "pseudo" ) == string::npos ) ? 1000 : 1000;

  //// FitTo Call
  RooCmdArg min    = RooFit::Minimizer( "Minuit", "Migrad" );
  RooCmdArg minos  = RooFit::Minos( kTRUE );
  RooCmdArg strat  = RooFit::Strategy( RooMinimizer::Balance );
  RooCmdArg ext    = RooFit::Extended( kTRUE );
  RooCmdArg offset = RooFit::Offset( kTRUE );
  RooCmdArg ncpu   = RooFit::NumCPU( 8 );
  RooCmdArg clone  = RooFit::CloneData( kFALSE );
  RooCmdArg save   = RooFit::Save();
  RooCmdArg verb   = RooFit::Verbose( kFALSE );
  RooCmdArg printl = RooFit::PrintLevel( -1 );
  RooCmdArg printe = RooFit::PrintEvalErrors( -1 );
  RooCmdArg printw = RooFit::Warnings( kFALSE );

  RooLinkedList fitopt;
  fitopt.Add( &min    );
  fitopt.Add( &ext    );
  fitopt.Add( &strat  );
  fitopt.Add( &minos  );
  fitopt.Add( &save   );
  fitopt.Add( &offset );
  fitopt.Add( &ncpu   );
  fitopt.Add( &clone  );
  fitopt.Add( &verb   );
  fitopt.Add( &printl );
  fitopt.Add( &printe );
  fitopt.Add( &printw );

  RooFitResult* err = NULL;
  unsigned iter     = 0;

  while( !err  ){
    err = model->fitTo( *( fitdataset ), fitopt );
    ++iter;
    if( err->status() ){// Not properly converged
      if( iter > maxiter ){
        break;
      } else {
        delete err;
        err = NULL;
      }
    }
  }

  cout << ">>>>>> Finish running simultaneous fit for " << sig->Name() << endl;
  cout << ">>>>>> Number of iterations:" << iter << endl;
  cout << ">>>>>> Fitted bkg:" << nb->getVal() << endl;
  cout << ">>>>>> Fitted sig:" << ns->getVal() << endl;

  if( datasetname.find( "pseudo" ) != string::npos ){// Early exit for psuedo data set
    return err;
  }

  // Adding external term
  RooRealVar* c = data->NewVar( bgfuncname + "sys", 0, -1, 1 );// Item for adding background shape systematic
  RooRealVar* a = data->Var( bgfuncname + "a" );

  char formula[1024];
  sprintf(
    formula,
    "TMath::Exp( -(%s)*TMath::Power(TMath::Log(x) - (%s),3) )",
    c->GetName(),
    a->GetName()
    );
  c->setError( 0.07 );// A magic number for now
  c->setConstant( kTRUE );

  RooGenericPdf* bkgsys = new RooGenericPdf(
    ( bgfuncname + "sys" ).c_str(),
    ( bgfuncname + "sys" ).c_str(),
    formula,
    RooArgSet( SampleRooFitMgr::x(), *a, *c )
    );

  RooProdPdf* bkgtot = new RooProdPdf(
    StitchSimFitBgPdfname( sig->Name() ).c_str(),
    StitchSimFitBgPdfname( sig->Name() ).c_str(),
    RooArgSet( *bgpdf, *bkgsys )
    );

  data->AddPdf( bkgsys );
  data->AddPdf( bkgtot );
  data->SetConstant( kTRUE );
  sig->SetConstant( kTRUE );
  return err;
}

/*******************************************************************************
*   Making Data cards
*******************************************************************************/
void
MakeSimFitCardFile(
  SampleRooFitMgr* data,
  SampleRooFitMgr* sig
  )
{
  const string sigpdfname = StitchKeyPdfName;
  // const string bgpdfname  = SimFitBGPdfName( "", sig->Name() );
  const string bgpdfname = StitchSimFitBgPdfname( sig->Name() );
  RooAbsData* dataset    = data->DataSet();
  RooAbsPdf* bgpdf       = data->Pdf( bgpdfname );
  RooAbsPdf* sigpdf      = sig->Pdf( sigpdfname );
  const Parameter bgunc  = GetBgNormError( data, "", "", sig->Name() );

  // Writting the common parts
  ofstream cardfile( limnamer.TextFileName( "card", sig->Name() ) );

  MakeCardCommon( cardfile, dataset, bgpdf, sigpdf );
  cardfile << boost::format( "%12s %15lf %15lf" )
    % "rate"
    % sig->ExpectedYield()
    % bgunc.CentralValue() // Using norm RooRealVar
           << endl;

  // Printing list of normalization errors
  const Parameter lumi   = limnamer.MasterConfig().GetStaticParameter( "Lumi Error" );
  const Parameter lepunc = data->Name().find( "Muon" ) == string::npos ?
                           limnamer.MasterConfig().GetStaticParameter( "Electron Systematic" ) :
                           limnamer.MasterConfig().GetStaticParameter( "Muon Systematic" );
  const Parameter sigunc = sig->Sample().SelectionEfficiency();
  const Parameter null( 0, 0, 0 );
  cardfile << "----------------------------------------" << endl;

  // Normalization nuisance parameter
  for( const auto& source : uncsource ){
    if( source == "pdf" || source == "scale" || source == "model" ){ continue; }
    const Parameter unc = GetMCNormError( sig, source + "Up", source + "Down" );
    PrintNuisanceFloats( cardfile, source, "lnN", unc, null  );
  }

  PrintNuisanceFloats( cardfile, "lumi",    "lnN", lumi,   null  );
  PrintNuisanceFloats( cardfile, "statunc", "lnN", sigunc, null  );
  PrintNuisanceFloats( cardfile, "lepsys",  "lnN", lepunc, null  );
  PrintNuisanceUniformFloats( cardfile, "simfitbg", "lnU", null, bgunc );

  // Getting a list of fitting parameters to permutate.
  for( const auto& datasetname : data->SetNameList() ){
    const string bgfuncname = SimFitBGPdfName( datasetname, sig->Name() );

    for( auto var : data->VarContains( bgfuncname ) ){
      const string varname = var->GetName();
      if( varname.find( "sys" ) == string::npos ){
        PrintFloatParam( cardfile, var );
      }
    }
  }

  // Getting stitching variables
  vector<RooRealVar*> stitchvarlist;

  for( auto var : sig->VarContains( "coeff" ) ){
    stitchvarlist.push_back( var );
  }

  for( const auto& var : stitchvarlist ){
    var->setConstant( kTRUE );
    PrintFlatParam( cardfile, var );
  }

  // Closing file
  cardfile.close();
}

/*******************************************************************************
*   Error getting.
*******************************************************************************/
Parameter
GetBgNormError(
  SampleRooFitMgr* data,
  const string&    uperror,
  const string&    downerror,
  const string&    signalname
  )
{
  const string centralpdfname   = SimFitCombinePdfName( "", signalname );
  const string uperrorpdfname   = SimFitCombinePdfName( uperror, signalname );
  const string downerrorpdfname = SimFitCombinePdfName( downerror, signalname );

  RooAddPdf* centralpdf   = (RooAddPdf*)( data->Pdf( centralpdfname ) );
  RooAddPdf* uperrorpdf   = (RooAddPdf*)( data->Pdf( uperrorpdfname ) );
  RooAddPdf* downerrorpdf = (RooAddPdf*)( data->Pdf( downerrorpdfname ) );

  if( uperror == "" || downerror == "" ){// fitting error for main pdf
    return Parameter(
      ( (RooRealVar*)( centralpdf->coefList().at( 0 ) ) )->getVal(),
      ( (RooRealVar*)( centralpdf->coefList().at( 0 ) ) )->getErrorHi(),
      ( (RooRealVar*)( centralpdf->coefList().at( 0 ) ) )->getErrorLo()
      );
  } else {
    const double centralnorm   = ( (RooRealVar*)( centralpdf->coefList().at( 0 ) ) )->getVal();
    const double uperrornorm   = ( (RooRealVar*)( uperrorpdf->coefList().at( 0 ) ) )->getVal();
    const double downerrornorm = ( (RooRealVar*)( downerrorpdf->coefList().at( 0 ) ) )->getVal();
    return Parameter(
      centralnorm,
      uperrornorm - centralnorm,
      centralnorm - downerrornorm
      );
  }
}

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

Parameter
GetMCNormError(
  SampleRooFitMgr* sig,
  const string&    uperrorset,
  const string&    downerrorset
  )
{
  const double centralsetyield = sig->DataSet( "" )->sumEntries();
  const double uperroryield    = sig->DataSet( uperrorset )->sumEntries();
  const double downerroryield  = sig->DataSet( downerrorset )->sumEntries();

  cout << sig->Name() << " | " << uperrorset << " | ";
  cout << centralsetyield << " " << uperroryield << " " << downerroryield << endl;

  return Parameter(
    centralsetyield,
    uperroryield - centralsetyield,
    centralsetyield - downerroryield
    );
}

/*******************************************************************************
*   Plotting fnuctions
*******************************************************************************/
void
MakeSimFitPlot(
  SampleRooFitMgr* data,
  SampleRooFitMgr* sig,
  RooFitResult*    fitres,
  const string&    datasetname,
  const string&    exttag,
  const double     massmin,
  const double     massmax,
  const int        nbins
  )
{
  TCanvas* c          = mgr::NewCanvas();
  TPad* toppad        = mgr::NewTopPad();
  TPad* botpad        = mgr::NewBottomPad();
  const double varmin = SampleRooFitMgr::x().getMin();
  const double varmax = SampleRooFitMgr::x().getMax();
  const double xmin   = massmin >  varmin &&  massmin < varmax && massmin < massmax ? massmin : varmin;
  const double xmax   = massmax >  varmin &&  massmax < varmax && massmin < massmax ? massmax : varmax;
  RooPlot* frame      = nbins > 10 ? SampleRooFitMgr::x().frame( xmin, xmax, nbins ) :  SampleRooFitMgr::x().frame( xmin, xmax );

  const string combpdfname = SimFitCombinePdfName( datasetname, sig->Name() );
  const string bgpdfname   = SimFitBGPdfName( datasetname, sig->Name() );

  RooAbsData* dataset = data->DataSet( datasetname );
  RooAddPdf* model    = (RooAddPdf*)data->Pdf( combpdfname );
  RooAbsPdf* bgpdf    = data->Pdf( bgpdfname );
  RooAbsPdf* sigpdf   = sig->Pdf( KeyPdfName( "" ) );

  cout << bgpdfname << endl;

  for( const auto& pdfname : data->PdfNameList() ){
    cout << pdfname << endl;
  }

  const RooRealVar* bgvar     = data->Var( combpdfname + "nb" );
  const RooRealVar* sigvar    = data->Var( combpdfname + "ns" );
  const double bgstrength     = bgvar->getVal();
  const double sigfitstrength = sigvar->getVal();
  const double sigexpstrength = sig->DataSet()->sumEntries();
  const double ksbkg          = KSTest( *dataset, *bgpdf, SampleRooFitMgr::x() );
  const double ksall          = KSTest( *dataset, *model, SampleRooFitMgr::x() );
  const double multipler      =
    GetInt( sig->Name() ) == 700 ? 1.0 :
    GetInt( sig->Name() ) == 800 ? 2.0 :
    GetInt( sig->Name() ) == 900 ? 15.0 :
    GetInt( sig->Name() ) == 1000 ? 80.0 :
    GetInt( sig->Name() ) == 1100 ? 100.0 :
    GetInt( sig->Name() ) == 1200 ? 200.0 :
    GetInt( sig->Name() ) == 1300 ? 800.0 :
    GetInt( sig->Name() ) == 1400 ? 6000.0 :
    GetInt( sig->Name() ) == 1500 ? 10000.0 :
    GetInt( sig->Name() ) == 1600 ? 30000.0 :
    1.0;

  /*******************************************************************************
  *   Drawing top pad
  *******************************************************************************/
  toppad->Draw();
  toppad->cd();

  TGraph* dataplot = mgr::PlotOn(
    frame, dataset,
    RooFit::DrawOption( PGS_DATA )
    );// Must plot data first to set y axis title

  TGraph* sigplot = mgr::PlotOn(
    frame, sigpdf,
    RooFit::Normalization( sigexpstrength * multipler, RooAbsReal::NumEvent ),
    RooFit::DrawOption( PGS_SIGNAL )
    );

  TGraph* bgplot = mgr::PlotFitErrorOn(
    frame, bgpdf, fitres,
    RooFit::Normalization( bgstrength, RooAbsReal::NumEvent )
    );

  TGraph* modelplot = mgr::PlotOn(
    frame, model,
    RooFit::Normalization( bgstrength + sigfitstrength, RooAbsReal::NumEvent )
    );

  tstar::RemoveDataXBar( (TGraphAsymmErrors*)dataplot );

  frame->Draw();
  frame->SetMinimum( 0.3 );
  frame->SetTitle( "" );
  mgr::SetTopPlotAxis( frame );
  c->cd();

  /*******************************************************************************
  *   Drawing bottom pad
  *******************************************************************************/
  botpad->Draw();
  botpad->cd();

  TGraphAsymmErrors* bgrelplot = mgr::DividedGraph(
    (TGraphAsymmErrors*)bgplot,
    bgplot
    );
  TGraphAsymmErrors* datarelplot = mgr::DividedGraph(
    (TGraphAsymmErrors*)dataplot,
    bgplot
    );
  TGraphAsymmErrors* fitrelplot = mgr::DividedGraph(
    (TGraphAsymmErrors*)modelplot,
    bgplot
  );
  tstar::RemoveDataXBar( datarelplot );

  TLine cen( xmin, 1,   xmax, 1 );
  TLine lineup( xmin, 1.5, xmax, 1.5 );
  TLine linedown( xmin, 0.5, xmax, 0.5 );

  bgrelplot->Draw( "AL3" );
  datarelplot->Draw( PGS_DATA );
  fitrelplot->Draw("L");
  cen.Draw();
  cen.SetLineColor( KBLUE );
  cen.SetLineWidth( 2 );
  lineup.Draw();
  lineup.SetLineColor( kBlack );
  lineup.SetLineStyle( 3 );
  linedown.Draw();
  linedown.SetLineColor( kBlack );
  linedown.SetLineStyle( 3 );

  // Title setting
  bgrelplot->GetXaxis()->SetTitle( frame->GetXaxis()->GetTitle() );
  bgrelplot->GetXaxis()->SetRangeUser( xmin, xmax );
  bgrelplot->GetYaxis()->SetTitle( "Data/Bkg.fit" );
  bgrelplot->SetMaximum( 1.6 );
  bgrelplot->SetMinimum( 0.4 );
  mgr::SetBottomPlotAxis( bgrelplot );

  c->cd();

  /*******************************************************************************
  *   Styling options
  *******************************************************************************/
  // Stripping unwanted points to fix plots
  for( int i = 0; i < bgplot->GetN(); ++i ){
    const double x = bgplot->GetX()[i];
    const double y = bgplot->GetY()[i];
    if( x < frame->GetXaxis()->GetXmin()
        || x > frame->GetXaxis()->GetXmax()
        || y < frame->GetMinimum()/2
        ){
      bgplot->RemovePoint( i );
      --i;
    }
  }

  tstar::SetFitCombStyle( modelplot );
  tstar::SetFitBGStyle( bgplot );
  tstar::SetSignalStyle( sigplot );

  tstar::SetFitCombStyle( fitrelplot );
  tstar::SetFitBGStyle( bgrelplot );
  tstar::SetDataStyle( datarelplot );
  tstar::SetDataStyle( dataplot );

  // Creating legend
  const double legend_x_min = 0.53;
  const double legend_y_min = 0.7;
  TLegend* leg              = mgr::NewLegend( legend_x_min, legend_y_min );

  boost::format sigfmt( "%s(#times%.0lf)" );
  const string sigentry  = str( sigfmt % sig->RootName() % multipler );
  const string dataentry = datasetname.find( "pseudo" ) != string::npos ? "Pseudo data" : "Data";
  const string bgentry   = "Fitted bkg. comp.";
  const string mdlentry  = "Fitted sig.+bkg.";

  leg->AddEntry( dataplot,  dataentry.c_str(), "pe" );
  leg->AddEntry( modelplot, mdlentry.c_str(),  "l"  );
  leg->AddEntry( bgplot,    bgentry.c_str(),   "lf" );
  leg->AddEntry( sigplot,   sigentry.c_str(),  "l"  );
  leg->Draw();

  // Additional information
  mgr::DrawCMSLabel();
  mgr::DrawLuminosity( mgr::SampleMgr::TotalLuminosity() );
  LatexMgr latex;
  latex.SetOrigin( PLOT_X_MIN, PLOT_Y_MAX+TEXT_MARGIN/2, BOTTOM_LEFT )
  .WriteLine( limnamer.GetChannelEXT( "Root Name" ) );
  // .WriteLine( limnamer.ExtQuery<string>( "fitmethod", "SimFit", "Full Name" ) )
  // .WriteLine( limnamer.GetExt<string>( "fitfunc", "Full Name" ) );

  // boost::format obsfmt( "Observed Yield: %d" );
  // boost::format fitfmt( "Fitted bkg.: %.0lf #pm %.0lf" );
  boost::format detfmt( "K_{bkg} = %.3lf,  K_{all} = %.3lf" );

  // const string obsentry = str( obsfmt % obs );
  // const string expentry = str( fitfmt % bgstrength % bgerr );
  const string detentry = str( detfmt % ksbkg % ksall );

  latex.SetOrigin( PLOT_X_TEXT_MAX, legend_y_min - TEXT_MARGIN, TOP_RIGHT )
  // .WriteLine( obsentry )
  // .WriteLine( expentry )
  .WriteLine( detentry );

  // Saving and cleaning up
  vector<string> taglist = ( datasetname.find( "pseudo" ) == string::npos )
                           ? vector<string>( {datasetname, sig->Name(), exttag} )
                           : vector<string>( {"pseudo",    sig->Name(), exttag, SigStrengthTag() } );

  const string prefix   = ( datasetname.find( "pseudo" ) == string::npos ) ? "fitplot" : "valsimfitplot";
  const string mainname = limnamer.PlotFileName( prefix, taglist );
  taglist.push_back( "log" );
  const string logname = limnamer.PlotFileName( prefix, taglist );
  taglist.back() = "zoom";
  const string zoomname = limnamer.PlotFileName( prefix, taglist );
  taglist.push_back( "log" );
  const string zoomlog = limnamer.PlotFileName( prefix, taglist );

  // Unzoomed plot
  const vector<TGraph*> graphlist = {dataplot, modelplot, sigplot, bgplot};
  const double ymax               = mgr::GetYmax( graphlist );
  toppad->SetLogy( kTRUE );
  frame->SetMaximum( ymax * 3000 );
  mgr::SaveToPDF( c, logname.c_str() );
  mgr::SaveToROOT( c, limnamer.PlotRootFile(), limnamer.OptFileName( "", prefix, taglist ) );
  toppad->SetLogy( kFALSE );
  frame->SetMaximum( ymax * 1.5 );
  mgr::SaveToPDF( c, mainname );

  delete frame;
  delete leg;
  delete c;
}

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

void
MakeVarValPlot( SampleRooFitMgr* data )
{
  const vector<string> siglist = limnamer.MasterConfig().GetStaticStringList( "Signal List" );
  TGraphAsymmErrors* nsplot    = new TGraphAsymmErrors( siglist.size() );
  TGraphAsymmErrors* nbplot    = new TGraphAsymmErrors( siglist.size() );
  TGraphAsymmErrors* aplot     = new TGraphAsymmErrors( siglist.size() );
  TGraphAsymmErrors* bplot     = new TGraphAsymmErrors( siglist.size() );

  // Filling the plots
  for( size_t i = 0; i < siglist.size(); ++i  ){
    const auto& signame      = siglist.at( i );
    const string combpdfname = SimFitCombinePdfName( "", signame );
    const RooRealVar* nb     = data->Var( combpdfname + "nb" );
    const RooRealVar* ns     = data->Var( combpdfname + "ns" );

    const string bgpdfname = SimFitBGPdfName( "", signame );
    const RooRealVar* avar = data->Var( bgpdfname + "a" );
    const RooRealVar* bvar = data->Var( bgpdfname + "b" );

    // Special case for NS which is very close to boundary
    nsplot->SetPoint( i, GetInt( signame ), ns->getVal() );
    if( ns->getErrorHi() > 0 ){
      const double low = fabs( ns->getErrorLo() ) > 0 ?
                         std::min( fabs( ns->getErrorLo() ), ns->getVal() ) :
                         ns->getVal();
      const double hi = ns->getErrorHi();
      cout << GetInt( signame ) << " " << low << " " << hi << endl;
      nsplot->SetPointError( i, 50, 50, low, hi );
    } else {
      nsplot->SetPointError( i, 50, 50, ns->getVal(), ns->getError() );
    }

    nbplot->SetPoint( i, GetInt( signame ), nb->getVal() );
    if( nb->getErrorLo() != 0 && nb->getErrorHi() != 0 ){
      nbplot->SetPointError( i, 50, 50, -( nb->getErrorLo() ), nb->getErrorHi() );
    } else {
      nbplot->SetPointError( i, 50, 50, nb->getError(), nb->getError() );
    }

    aplot->SetPoint( i, GetInt( signame ), avar->getVal() );
    if( avar->getErrorLo() != 0 && avar->getErrorHi() != 0 ){
      aplot->SetPointError( i, 50, 50, -avar->getErrorLo(), avar->getErrorHi() );
    } else {
      aplot->SetPointError( i, 50, 50, avar->getError(), avar->getError() );
    }

    bplot->SetPoint( i, GetInt( signame ), bvar->getVal() );
    if( bvar->getErrorLo() != 0 && bvar->getErrorHi() != 0 ){
      bplot->SetPointError( i, 50, 50, -bvar->getErrorLo(), bvar->getErrorHi() );
    } else {
      bplot->SetPointError( i, 50, 50, bvar->getError(), bvar->getError() );
    }
  }

  // Creating the plots
  for( const auto plot : {nsplot, nbplot, aplot, bplot} ){
    const string plottag =
      ( plot == nsplot ) ?  "ns" :
      ( plot == nbplot ) ?  "nb" :
      ( plot == aplot  ) ?  "m0" :
      ( plot == bplot  ) ?  "a2" :
      "";
    const string yaxis = "fit value (" + std::string(
      ( plot == nsplot ) ?  "n_{s}" :
      ( plot == nbplot ) ?  "n_{b}" :
      ( plot == aplot  ) ?  "log(m_{0})" :
      ( plot == bplot  ) ?  "#sqrt{1/2a_{2}}" :
      "" ) + ")" + std::string(
      ( plot == nbplot ) ? " #times10^{3}" : ""
      );

    TCanvas* c = mgr::NewCanvas();
    mgr::SetSinglePad( c );

    plot->Draw( "APZ" );
    tstar::SetDataStyle( plot );
    mgr::SetAxis( plot );

    plot->GetXaxis()->SetTitle( "Signal mass (GeV/c^{2})" );
    plot->GetYaxis()->SetTitle( yaxis.c_str() );
    plot->SetTitle( "" );

    const double ymax = GetYmax( plot );
    const double ymin = GetYmin( plot );

    plot->SetMaximum( ymax + ( ymax-ymin ) * 0.33 );
    plot->SetMinimum( ymin - ( ymax-ymin ) * 0.33 );

    mgr::DrawCMSLabel();
    mgr::DrawLuminosity( mgr::SampleMgr::TotalLuminosity() );

    mgr::LatexMgr latex;
    latex.SetOrigin( PLOT_X_MIN, PLOT_Y_MAX + TEXT_MARGIN/2, BOTTOM_LEFT )
    .WriteLine( limnamer.GetChannelEXT( "Root Name" ) );

    mgr::SaveToPDF( c, limnamer.PlotFileName( "varfitval", plottag ) );
    mgr::SaveToROOT(
      c,
      limnamer.PlotRootFile(),
      limnamer.OptFileName( "", "varfitval", plottag )
      );
    delete c;
  }

  delete nsplot;
  delete nbplot;
  delete aplot;
  delete bplot;
}

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

void
SmoothEfficiency( std::vector<SampleRooFitMgr*>& siglist )
{
  double selecevtmean = 0;
  double origevtmean  = 0;

  for( const auto& sig : siglist ){
    selecevtmean += sig->Sample().SelectedEventCount();
    origevtmean  += sig->Sample().OriginalEventCount();
  }

  selecevtmean /= siglist.size();
  origevtmean  /= siglist.size();

  for( const auto& sig : siglist ){
    sig->Sample().SetSelectedEventCount( selecevtmean );
    sig->Sample().SetOriginalEventCount( origevtmean  );
  }
}

ext: cc

max_stars_repo_name: NTUHEP-Tstar/TstarAnalysis

max_issues_repo_name: NTUHEP-Tstar/TstarAnalysis

max_forks_repo_name: NTUHEP-Tstar/TstarAnalysis


text:
#pragma once
#ifndef BE_PERF_TIMER_STAT_HPP_
#define BE_PERF_TIMER_STAT_HPP_

#include "stat_base.hpp"
#include <boost/iterator/indirect_iterator.hpp>
#include <vector>

namespace be::perf {

class Stats;
class TimerStat;

namespace detail {

///////////////////////////////////////////////////////////////////////////////
class TimerStatChildren final : Immovable {
   friend class TimerStat;
   using child_container = std::vector<TimerStat*>;
public:
   using iterator = boost::indirect_iterator<child_container::iterator>;
   using const_iterator = boost::indirect_iterator<child_container::const_iterator>;

   iterator begin();
   const_iterator begin() const;
   iterator end();
   const_iterator end() const;

   size_t size() const;
   bool empty() const;

   TimerStat& front();
   const TimerStat& front() const;
   TimerStat& back();
   const TimerStat& back() const;

   TimerStat& operator[](size_t index);
   const TimerStat& operator[](size_t index) const;

   void capacity(size_t record_capacity);
   void clear_records();

   void next_record();
   void next_record(U64 sample_id);

   U64 total_elapsed() const;
   U64 total_elapsed(size_t record_index) const;

private:
   child_container children_;
};

///////////////////////////////////////////////////////////////////////////////
struct TimerStatRec {
   U64 sample_id;
   U64 elapsed;
   U64 n_reports;
};

} // be::perf::detail

///////////////////////////////////////////////////////////////////////////////
class TimerStat final : public StatBase<detail::TimerStatRec> {
   friend class TimerStats;
public:
   using child_container = detail::TimerStatChildren;

   TimerStat(TimerStat&& other);

   void clear_parent();
   void parent(TimerStat& stat);
   TimerStat* parent() const;

   child_container children;

   void capacity(std::size_t capacity);
   std::size_t capacity();

   U64 sample_id(std::size_t index) const;
   U64 elapsed(std::size_t index) const;
   I64 exclusive_elapsed(std::size_t index) const;
   U64 report_count(std::size_t index) const;

   void clear();

   void next_record();
   void next_record(U64 sample_id);
   void report(U64 duration);
   U64 sample_id() const;
   U64 elapsed() const;
   I64 exclusive_elapsed() const;
   U64 report_count() const;

private:
   TimerStat(Stats& owner, Id id, S name);

   TimerStat* parent_;
   bool use_active_;
   record active_;
};

} // be::perf

#endif

ext: hpp

max_stars_repo_name: magicmoremagic/bengine-perf

max_issues_repo_name: magicmoremagic/bengine-perf

max_forks_repo_name: magicmoremagic/bengine-perf


text:
// JAGLAVAK CHESS ENGINE (c) 2019 Stuart Riffle

#include "Jaglavak.h"
#include "Generated/DefaultSettings.json.h"

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using namespace boost;
namespace pt = property_tree;

void GlobalSettings::Initialize( const vector< string >& configFiles )
{
    // Start with the embedded defaults

    this->LoadJsonValues( Embedded_DefaultSettings );

    // Overlay the normal settings file

    vector< string > filesToLoad = configFiles;
    filesToLoad.insert( filesToLoad.begin(), "Settings.json" );

    // Then any config files specified on the command line

    for( const string& filename : filesToLoad )
    {
        FILE* f = fopen( filename.c_str(), "r" );
        if( !f )
            continue;

        fseek( f, 0, SEEK_END );
        size_t size = ftell( f );
        fseek( f, 0, SEEK_SET );

        string json;
        json.resize( size );

        size_t loaded = fread( (void*) json.data(), size, 1, f );
        fclose( f );

        if( loaded == size )
            this->LoadJsonValues( json );
    }
}

void GlobalSettings::LoadJsonValues( const string& json )
{
    pt::ptree tree;

    try
    {
        pt::read_json( stringstream( json ), tree );

    } catch( ... ) {}

    for( auto& option : tree )
    {
        const string& name = option.first;
        double value = option.second.get_value< double >();

        _Value[name] = value;
    }
}

void GlobalSettings::PrintListForUci() const
{
    for( auto& pair : _Value )
    {
        const string& name = pair.first;
        int val = (int) pair.second;

        cout << "option type spin name " << name << " default " << val << endl;
    }
}

max_stars_repo_name: StuartRiffle/corvid

max_issues_repo_name: StuartRiffle/corvid

max_forks_repo_name: StuartRiffle/corvid


text:
#ifndef NANA_STD_THREAD_HPP
#define NANA_STD_THREAD_HPP
#include <nana/config.hpp>

#if defined(STD_THREAD_NOT_SUPPORTED)

#if defined(NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ)

#include <mingw.thread.h>
#else
#include <boost/thread.hpp>
namespace std
{
    typedef boost::thread thread;
}
#endif  // (NANA_ENABLE_MINGW_STD_THREADS_WITH_MEGANZ)

#else

#include <thread>

#endif // (STD_THREAD_NOT_SUPPORTED)

#endif // NANA_STD_THREAD_HPP

max_stars_repo_name: bacusters/nana

max_issues_repo_name: bacusters/nana

max_forks_repo_name: bacusters/nana


text:
// Copyright (C) 2017 Andrzej Krzemienski.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/optional for documentation.
//
// You are welcome to contact the author at:
//  akrzemi1@gmail.com

#ifndef BOOST_OPTIONAL_DETAIL_EXPERIMENTAL_TRAITS_04NOV2017_HPP
#define BOOST_OPTIONAL_DETAIL_EXPERIMENTAL_TRAITS_04NOV2017_HPP

#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/type_traits.hpp>

namespace boost { namespace optional_detail {

// The condition to use POD implementation

#ifdef BOOST_OPTIONAL_CONFIG_NO_POD_SPEC
# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
#elif defined BOOST_OPTIONAL_CONFIG_NO_SPEC_FOR_TRIVIAL_TYPES
# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
#elif !defined BOOST_HAS_TRIVIAL_CONSTRUCTOR
# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
#elif !defined BOOST_HAS_TRIVIAL_MOVE_ASSIGN
# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
#elif !defined BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR
# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
#elif !defined BOOST_HAS_TRIVIAL_COPY
# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
#elif !defined BOOST_HAS_TRIVIAL_ASSIGN
# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
#elif !defined BOOST_HAS_TRIVIAL_DESTRUCTOR
# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
#elif BOOST_WORKAROUND(BOOST_GCC, < 50000)
# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
#endif

#if __cplusplus >= 201103L
#  if BOOST_WORKAROUND(BOOST_GCC, >= 50000)
#    define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS
#  elif (defined BOOST_CLANG)
#    define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS
#  endif
#endif

#ifndef BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS
#  define BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T) BOOST_HAS_TRIVIAL_CONSTRUCTOR(T)
#else
#  define BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T) std::is_trivially_default_constructible<T>::value
#endif

#ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
template <typename T>
struct is_type_trivially_copyable
  : boost::conditional<(boost::has_trivial_copy_constructor<T>::value &&
                        boost::has_trivial_move_constructor<T>::value &&
                        boost::has_trivial_destructor<T>::value &&
                        boost::has_trivial_move_assign<T>::value &&
                        boost::has_trivial_assign<T>::value),
                        boost::true_type, boost::false_type>::type
{};
#else
template <typename T>
struct is_type_trivially_copyable
: boost::conditional<(boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value),
                     boost::true_type, boost::false_type>::type
{};
#endif

#ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES
template <typename T>
struct optional_uses_direct_storage_for_
  : boost::conditional< (is_type_trivially_copyable<T>::value && BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T)) ||
                        (boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value)
                      , boost::true_type, boost::false_type>::type
{};
#else
template <typename T>
struct optional_uses_direct_storage_for_
  : boost::conditional<(boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value)
                      , boost::true_type, boost::false_type>::type
{};
#endif

}} // boost::optional_detail

#endif

max_stars_repo_name: chubbymaggie/gtirb


text:
#include "AccessLogger.h"
#include "Convenience.h"
#include <boost/filesystem.hpp>
#include <macgyver/Exception.h>
#include <macgyver/StringConversion.h>

namespace
{
std::string makeAccessLogFileName(const std::string& resource, const std::string& accessLogDir)
{
  try
  {
    // Build access log full path

    // Resource must be at least 1 character long
    std::string resourceId = resource.substr(1);

    boost::filesystem::path filepath(accessLogDir);
    if (resourceId.size() > 0)
    {
      boost::algorithm::replace_all(resourceId, "/", "-");  // this in case there are subhandlers
      filepath /= resourceId + "-access-log";
    }
    else
      filepath /= "default-handler-access-log";

    return filepath.string();
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

std::unique_ptr<std::ofstream> makeAccessLogFile(const std::string& resource,
                                                 const std::string& accessLogDir)
{
  try
  {
    // Create the log directory if it is missing
    if (!boost::filesystem::exists(accessLogDir))
    {
      std::cout << SmartMet::Spine::log_time_str() << " creating access log directory "
                << accessLogDir << std::endl;
      boost::filesystem::create_directories(accessLogDir);
    }

    // Error if the path is not a directory
    if (!boost::filesystem::is_directory(accessLogDir))
      throw std::runtime_error("Access log path '" + accessLogDir + "' is not a directory");

    // Otherwise create a log file in the directory
    std::string path = ::makeAccessLogFileName(resource, accessLogDir);

    std::unique_ptr<std::ofstream> file(new std::ofstream());
    file->open(path, std::ofstream::out | std::ofstream::app);
    if (!file->is_open())
    {
      throw Fmi::Exception(BCP, "Could not open access log file: " + path);
    }

    return file;
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}
}  // namespace

namespace SmartMet
{
namespace Spine
{
AccessLogger::AccessLogger(const std::string& resource, const std::string& accessLogDir)
    : itsResource(resource), itsLoggingDir(accessLogDir), itsIsRunning(false)
{
}

void AccessLogger::start()
{
  try
  {
    itsFileHandle = ::makeAccessLogFile(itsResource, itsLoggingDir);

    itsIsRunning = true;
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

void AccessLogger::stop()
{
  try
  {
    if (itsFileHandle && itsFileHandle->is_open())
      itsFileHandle->close();

    itsIsRunning = false;
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

AccessLogger::~AccessLogger()
{
  try
  {
    this->stop();
  }
  catch (...)
  {
    std::cout << Fmi::Exception::Trace(BCP, "Operation failed!").getStackTrace() << std::endl;
  }
}

void AccessLogger::log(const LoggedRequest& theRequest)
{
  try
  {
    if (!itsIsRunning || !itsFileHandle)
    {
      // Trying to log into a stopped logger
      return;
    }

    *itsFileHandle << theRequest.getIP() << " - - ["
                   << Fmi::to_iso_extended_string(theRequest.getRequestEndTime()) << "] \""
                   << theRequest.getMethod() << ' ' << theRequest.getRequestString() << " HTTP/"
                   << theRequest.getVersion() << "\" " << theRequest.getStatus() << " ["
                   << Fmi::to_iso_extended_string(theRequest.getRequestStartTime()) << "] "
                   << theRequest.getAccessDuration().total_milliseconds() << ' '
                   << theRequest.getContentLength() << ' ' << theRequest.getETag() << "\n";
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

}  // namespace Spine
}  // namespace SmartMet

max_stars_repo_name: fmidev/smartmet-library-spine

max_issues_repo_name: fmidev/smartmet-library-spine

max_forks_repo_name: fmidev/smartmet-library-spine