<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: lennardJones.C,v 1.18 2005/02/18 12:50:51 amoll Exp $
//

#include <BALL/MOLMEC/PARAMETER/lennardJones.h>
#include <BALL/MOLMEC/PARAMETER/forceFieldParameters.h>

using namespace std;

namespace BALL
{

	LennardJones::LennardJones() throw()
		:	ParameterSection(),
			A_(0),
			B_(0),
			N_(0),
			Aij_(0),
			Bij_(0),
			is_defined_(0),
			format_(EPSILON_R_FORMAT),
			names_()
	{
	}

	LennardJones::LennardJones(const LennardJones& lj) throw()
		:	ParameterSection(lj),
			A_(lj.A_),
			B_(lj.B_),
			N_(lj.N_),
			Aij_(lj.Aij_),
			Bij_(lj.Bij_),
			is_defined_(lj.is_defined_),
			format_(lj.format_),
			names_(lj.names_)
	{
	}

	LennardJones::~LennardJones() throw()
	{
		clear();
	}

	void LennardJones::clear() throw()
	{
		// clear allocated parameter fields
		A_.clear();
		B_.clear();
		N_.clear();
		Aij_.clear();
		Bij_.clear();
		is_defined_.clear();
		format_ = EPSILON_R_FORMAT;
		names_.clear();

		ParameterSection::clear();
	}

	const LennardJones& LennardJones::operator = (const LennardJones& lj)
		throw()
	{
		ParameterSection::operator = (lj);
		A_ = lj.A_;
		B_ = lj.B_;
		N_ = lj.N_;
		Aij_ = lj.Aij_;
		Bij_ = lj.Bij_;
		is_defined_ = lj.is_defined_;
		format_ = lj.format_;
		names_ = lj.names_;

		return *this;
	}

	bool LennardJones::extractSection
		(Parameters& parameters, const String& section_name) throw()
	{
		return ParameterSection::extractSection(parameters, section_name);
	}

	bool LennardJones::extractSection
		(ForceFieldParameters& parameters, const String& section_name) throw()
	{
		// check whether the parameters are valid
		if (!parameters.isValid())
		{
			return false;
		}

		// extract the basis information
		ParameterSection::extractSection(parameters, section_name);
		bool use_geometric_mean = false;

		// check whether all variables we need are defined, terminate otherwise
		if ((!hasVariable("A") || !hasVariable("B"))
				&& (!hasVariable("epsilon") || !hasVariable("R")))
		{
			Log.error() << "LennardJones::extractSection: Lennard Jones parameter section requires two variable columns:"
				<< "A/B or epsilon/R" << endl;

			return false;

		}
		else
		{
			// format_ == A_B_FORMAT:				parameters are in A/B format
			// format_ == EPSILON_R_FORMAT:	parameters are in epsilon/R format
			// format_ == SLATER_KIRKWOOD_FORMAT:	parameters are in epsilon/R format
			if (hasVariable("epsilon") && hasVariable("R"))
			{
				format_ = EPSILON_R_FORMAT;
				if (options.has("radius_averaging"))
				{
					if (options["radius_averaging"] == "arithmetic")
					{
						use_geometric_mean = false;
					}
					else if (options["radius_averaging"] == "geometric")
					{
						use_geometric_mean = true;
					}
					else
					{
						Log.warn() << "AmberNonBonded: unknown method for averaging LJ radii: '"
								<< options["radius_averaging"] << "'. Using arithmetic mean." << std::endl;
					}
				}
			}
			else if (hasVariable("A") && hasVariable("B"))
			{
				format_ = A_B_FORMAT;
			}
			else if (hasVariable("alpha") && hasVariable("N") && hasVariable("R"))
			{
				// ?????
				format_ = SLATER_KIRKWOOD_FORMAT;
				Log.error() << "LennardJones::extractSection: Slater Kirkwood format not yet supported!" << endl;

				return false;
			}

		}

		// build a two dimensional array of the atom types
		// loop variable
		Size	i;
		const AtomTypes&	atom_types = parameters.getAtomTypes();
		number_of_atom_types_ = atom_types.getNumberOfTypes();

		// allocate two onedimensional fields for the two parameters
		A_.resize(number_of_atom_types_);
		B_.resize(number_of_atom_types_);
		Aij_.resize(number_of_atom_types_ * number_of_atom_types_);
		Bij_.resize(number_of_atom_types_ * number_of_atom_types_);
		is_defined_.resize(number_of_atom_types_);

		for (i = 0; i < number_of_atom_types_; i++)
		{
			is_defined_[i] = false;
		}

		// the indices of the columns containing the values
		Size index_A = 0;
		Size index_B = 0;
		if (format_ == A_B_FORMAT)
		{
			index_A = getColumnIndex("A");
			index_B = getColumnIndex("B");
		}
		else if (format_ == EPSILON_R_FORMAT)
		{
			index_A = getColumnIndex("epsilon");
			index_B = getColumnIndex("R");
		}
		else if (format_ == SLATER_KIRKWOOD_FORMAT)
		{
			index_A = getColumnIndex("epsilon");
			index_B = getColumnIndex("R");
		}

		// try to identify the units of A and B
		// and set the two conversion factors
		double factor_A = 1.0;
		double factor_B = 1.0;

		if (format_ == A_B_FORMAT)
		{
			if (options.has("unit_A"))
			{ //?????
			}
		}
		// in EPSILON_R_FORMAT epsilon is in A and R is in B
		if (format_ == EPSILON_R_FORMAT)
		{
			if (options.has("unit_epsilon"))
			{
				if (options["unit_epsilon"] == "kcal/mol")
				{
					factor_A = Constants::JOULE_PER_CAL;
				}
				if (options["unit_epsilon"] == "cal/mol")
				{
					factor_A = Constants::JOULE_PER_CAL * 0.001;
				}
				if (options["unit_epsilon"] == "J/mol")
				{
					factor_A = 0.001;
				}
			}

			if (options.has("unit_R"))
			{
				if (options["unit_R"] == "pm")
				{
					factor_B = 0.1;
				}
			}
		}

		Atom::Type		atom_type;
		String				key;
		for (i = 0; i < getNumberOfKeys(); ++i)
		{
			// get the key
			key = getKey(i);
			if (atom_types.hasType(key))
			{
				// get the two parameters
				atom_type = atom_types.getType(key);

				// retrieve the two values
				float A = getValue(i, index_A).toFloat() * factor_A;
				float B = getValue(i, index_B).toFloat() * factor_B;

				// store the values
				is_defined_[atom_type] = true;
				A_[atom_type] = A;
				B_[atom_type] = B;

				// check for the sign of the parameters: they have to be positive!
				if ((A < 0) || (B < 0))
				{
					if (format_ == EPSILON_R_FORMAT)
					{
						Log.warn() << "LennardJones::extractSection: VdW parameter may not be negative: type = " << atom_type << " (" << key << "), eps = " << A
											 << ", r = " << B << endl;
					}
					else
					{
						Log.warn() << "LennardJones::extractSection: VdW parameter may not be negative: type = " << atom_type << " (" << key << "), A = " << A
											 << ", B = " << B << endl;
					}
				}

			}
			else
			{
				Log.warn() << "LennardJones::extractSection: unknown atom type in Lennard Jones parameters: " << key << "   i = " << i << endl;
			}
		}

		// now assemble all Lennard Jones parameter for all known atom types

		for (i = 0; i < number_of_atom_types_; i++)
		{
			for (Size j = i; j < number_of_atom_types_; j++)
			{
				// calculate the two indices for the Aij/Bij fields
				Index index = (Index)(i + number_of_atom_types_ * j);
				Index sym_index = (Index)(j + number_of_atom_types_ * i);

				if ((is_defined_[j] == true) && (is_defined_[i]))
				{
					// calculate the values for A and B if in eps/R format
					if (format_ == EPSILON_R_FORMAT)
					{
						double R;
						if (!use_geometric_mean)
						{
							R = B_[i] + B_[j];
						}
						else
						{
							R = 2.0 * sqrt(B_[i] * B_[j]);
						}
						double R3 = R * R * R;
						double R6 = R3 * R3;
						double epsilon = sqrt(A_[i] * A_[j]);
						Aij_[index] = epsilon * R6 * R6;
						Bij_[index] = 2.0 * epsilon * R6;
					}
					else
					{
						// compute and assign Aij/Bij:
						// Aij = Ai * Aj, Aji = Aij
						// Bij = Bi * Bj, Bji = Bij
						Aij_[index] = A_[i] * A_[j];
						Bij_[index] = B_[i] * B_[j];
					}
					Aij_[sym_index] = Aij_[index];
					Bij_[sym_index] = Bij_[index];
				}
				else
				{
					Aij_[index] = 0.0;
					Bij_[index] = 0.0;
					Aij_[sym_index] = 0.0;
					Bij_[sym_index] = 0.0;
				}
			}
		}

		return true;
	}

	bool LennardJones::hasParameters(Atom::Type I, Atom::Type J) const
		throw()
	{
		if (I < 0 || I >= (Index)number_of_atom_types_)
		{
			return false;
		}

		if (J < 0 || J >= (Index)number_of_atom_types_)
		{
			return false;
		}

		return (is_defined_[I] && is_defined_[J]);
	}

	LennardJones::Values LennardJones::getParameters(Atom::Type I, Atom::Type J) const throw()
	{
		LennardJones::Values parameters;
		assignParameters(parameters, I, J);
		return parameters;
	}

	bool LennardJones::assignParameters
		(LennardJones::Values& parameters,
		 Atom::Type I, Atom::Type J) const throw()
	{
		if (hasParameters(I, J))
		{
			parameters.A = Aij_[I * number_of_atom_types_ + J];
			parameters.B = Bij_[I * number_of_atom_types_ + J];

			return true;
		}

		return false;
	}

	bool LennardJones::operator == (const LennardJones& lj) const throw()
	{
		return (ParameterSection::operator == (lj)
						&& (A_ == lj.A_) && (B_ == lj.B_)
						&& (Aij_ == lj.Aij_) && (Bij_ == lj.Bij_));
	}

} // namespace BALL
<commit_msg>fixed index overflow in hasParameters() and cosmetic changes<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: lennardJones.C,v 1.19 2005/02/18 13:06:53 amoll Exp $
//

#include <BALL/MOLMEC/PARAMETER/lennardJones.h>
#include <BALL/MOLMEC/PARAMETER/forceFieldParameters.h>

using namespace std;

namespace BALL
{

	LennardJones::LennardJones() throw()
		:	ParameterSection(),
			A_(0),
			B_(0),
			N_(0),
			Aij_(0),
			Bij_(0),
			is_defined_(0),
			format_(EPSILON_R_FORMAT),
			names_()
	{
	}

	LennardJones::LennardJones(const LennardJones& lj) throw()
		:	ParameterSection(lj),
			A_(lj.A_),
			B_(lj.B_),
			N_(lj.N_),
			Aij_(lj.Aij_),
			Bij_(lj.Bij_),
			is_defined_(lj.is_defined_),
			format_(lj.format_),
			names_(lj.names_)
	{
	}

	LennardJones::~LennardJones() throw()
	{
		clear();
	}

	void LennardJones::clear() throw()
	{
		// clear allocated parameter fields
		A_.clear();
		B_.clear();
		N_.clear();
		Aij_.clear();
		Bij_.clear();
		is_defined_.clear();
		format_ = EPSILON_R_FORMAT;
		names_.clear();

		ParameterSection::clear();
	}

	const LennardJones& LennardJones::operator = (const LennardJones& lj)
		throw()
	{
		ParameterSection::operator = (lj);
		A_ = lj.A_;
		B_ = lj.B_;
		N_ = lj.N_;
		Aij_ = lj.Aij_;
		Bij_ = lj.Bij_;
		is_defined_ = lj.is_defined_;
		format_ = lj.format_;
		names_ = lj.names_;

		return *this;
	}

	bool LennardJones::extractSection
		(Parameters& parameters, const String& section_name) throw()
	{
		return ParameterSection::extractSection(parameters, section_name);
	}

	bool LennardJones::extractSection
		(ForceFieldParameters& parameters, const String& section_name) throw()
	{
		// check whether the parameters are valid
		if (!parameters.isValid())
		{
			return false;
		}

		// extract the basis information
		ParameterSection::extractSection(parameters, section_name);
		bool use_geometric_mean = false;

		// check whether all variables we need are defined, terminate otherwise
		if ((!hasVariable("A") || !hasVariable("B"))
				&& (!hasVariable("epsilon") || !hasVariable("R")))
		{
			Log.error() << "LennardJones::extractSection: Lennard Jones parameter section requires two variable columns:"
				<< "A/B or epsilon/R" << endl;

			return false;

		}
		else
		{
			// format_ == A_B_FORMAT:				parameters are in A/B format
			// format_ == EPSILON_R_FORMAT:	parameters are in epsilon/R format
			// format_ == SLATER_KIRKWOOD_FORMAT:	parameters are in epsilon/R format
			if (hasVariable("epsilon") && hasVariable("R"))
			{
				format_ = EPSILON_R_FORMAT;
				if (options.has("radius_averaging"))
				{
					if (options["radius_averaging"] == "arithmetic")
					{
						use_geometric_mean = false;
					}
					else if (options["radius_averaging"] == "geometric")
					{
						use_geometric_mean = true;
					}
					else
					{
						Log.warn() << "AmberNonBonded: unknown method for averaging LJ radii: '"
								<< options["radius_averaging"] << "'. Using arithmetic mean." << std::endl;
					}
				}
			}
			else if (hasVariable("A") && hasVariable("B"))
			{
				format_ = A_B_FORMAT;
			}
			else if (hasVariable("alpha") && hasVariable("N") && hasVariable("R"))
			{
				// ?????
				format_ = SLATER_KIRKWOOD_FORMAT;
				Log.error() << "LennardJones::extractSection: Slater Kirkwood format not yet supported!" << endl;

				return false;
			}

		}

		// build a two dimensional array of the atom types
		// loop variable
		Size	i;
		const AtomTypes&	atom_types = parameters.getAtomTypes();
		number_of_atom_types_ = atom_types.getNumberOfTypes();

		// allocate two onedimensional fields for the two parameters
		A_.resize(number_of_atom_types_);
		B_.resize(number_of_atom_types_);
		Aij_.resize(number_of_atom_types_ * number_of_atom_types_);
		Bij_.resize(number_of_atom_types_ * number_of_atom_types_);
		is_defined_.resize(number_of_atom_types_);

		for (i = 0; i < number_of_atom_types_; i++)
		{
			is_defined_[i] = false;
		}

		// the indices of the columns containing the values
		Size index_A = 0;
		Size index_B = 0;
		if (format_ == A_B_FORMAT)
		{
			index_A = getColumnIndex("A");
			index_B = getColumnIndex("B");
		}
		else if (format_ == EPSILON_R_FORMAT)
		{
			index_A = getColumnIndex("epsilon");
			index_B = getColumnIndex("R");
		}
		else if (format_ == SLATER_KIRKWOOD_FORMAT)
		{
			index_A = getColumnIndex("epsilon");
			index_B = getColumnIndex("R");
		}

		// try to identify the units of A and B
		// and set the two conversion factors
		double factor_A = 1.0;
		double factor_B = 1.0;

		if (format_ == A_B_FORMAT)
		{
			if (options.has("unit_A"))
			{ //?????
			}
		}
		// in EPSILON_R_FORMAT epsilon is in A and R is in B
		if (format_ == EPSILON_R_FORMAT)
		{
			if (options.has("unit_epsilon"))
			{
				if (options["unit_epsilon"] == "kcal/mol")
				{
					factor_A = Constants::JOULE_PER_CAL;
				}
				if (options["unit_epsilon"] == "cal/mol")
				{
					factor_A = Constants::JOULE_PER_CAL * 0.001;
				}
				if (options["unit_epsilon"] == "J/mol")
				{
					factor_A = 0.001;
				}
			}

			if (options.has("unit_R"))
			{
				if (options["unit_R"] == "pm")
				{
					factor_B = 0.1;
				}
			}
		}

		Atom::Type		atom_type;
		String				key;
		for (i = 0; i < getNumberOfKeys(); ++i)
		{
			// get the key
			key = getKey(i);
			if (atom_types.hasType(key))
			{
				// get the two parameters
				atom_type = atom_types.getType(key);

				// retrieve the two values
				float A = getValue(i, index_A).toFloat() * factor_A;
				float B = getValue(i, index_B).toFloat() * factor_B;

				// store the values
				is_defined_[atom_type] = true;
				A_[atom_type] = A;
				B_[atom_type] = B;

				// check for the sign of the parameters: they have to be positive!
				if ((A < 0) || (B < 0))
				{
					if (format_ == EPSILON_R_FORMAT)
					{
						Log.warn() << "LennardJones::extractSection: VdW parameter may not be negative: type = " << atom_type << " (" << key << "), eps = " << A
											 << ", r = " << B << endl;
					}
					else
					{
						Log.warn() << "LennardJones::extractSection: VdW parameter may not be negative: type = " << atom_type << " (" << key << "), A = " << A
											 << ", B = " << B << endl;
					}
				}

			}
			else
			{
				Log.warn() << "LennardJones::extractSection: unknown atom type in Lennard Jones parameters: " << key << "   i = " << i << endl;
			}
		}

		// now assemble all Lennard Jones parameter for all known atom types

		for (i = 0; i < number_of_atom_types_; i++)
		{
			for (Size j = i; j < number_of_atom_types_; j++)
			{
				// calculate the two indices for the Aij/Bij fields
				Index index = (Index)(i + number_of_atom_types_ * j);
				Index sym_index = (Index)(j + number_of_atom_types_ * i);

				if (is_defined_[j] && is_defined_[i])
				{
					// calculate the values for A and B if in eps/R format
					if (format_ == EPSILON_R_FORMAT)
					{
						double R;
						if (!use_geometric_mean)
						{
							R = B_[i] + B_[j];
						}
						else
						{
							R = 2.0 * sqrt(B_[i] * B_[j]);
						}
						double R3 = R * R * R;
						double R6 = R3 * R3;
						double epsilon = sqrt(A_[i] * A_[j]);
						Aij_[index] = epsilon * R6 * R6;
						Bij_[index] = 2.0 * epsilon * R6;
					}
					else
					{
						// compute and assign Aij/Bij:
						// Aij = Ai * Aj, Aji = Aij
						// Bij = Bi * Bj, Bji = Bij
						Aij_[index] = A_[i] * A_[j];
						Bij_[index] = B_[i] * B_[j];
					}
					Aij_[sym_index] = Aij_[index];
					Bij_[sym_index] = Bij_[index];
				}
				else
				{
					Aij_[index] = 0.0;
					Bij_[index] = 0.0;
					Aij_[sym_index] = 0.0;
					Bij_[sym_index] = 0.0;
				}
			}
		}

		return true;
	}

	bool LennardJones::hasParameters(Atom::Type I, Atom::Type J) const
		throw()
	{
		if (I < 0 || I >= (Index)number_of_atom_types_)
		{
			return false;
		}

		if (J < 0 || J >= (Index)number_of_atom_types_)
		{
			return false;
		}

		return (is_defined_[I] && is_defined_[J]);
	}

	LennardJones::Values LennardJones::getParameters(Atom::Type I, Atom::Type J) const throw()
	{
		LennardJones::Values parameters;
		assignParameters(parameters, I, J);
		return parameters;
	}

	bool LennardJones::assignParameters(LennardJones::Values& parameters, Atom::Type I, Atom::Type J) const
		throw()
	{
		if (hasParameters(I, J))
		{
			parameters.A = Aij_[I * number_of_atom_types_ + J];
			parameters.B = Bij_[I * number_of_atom_types_ + J];

			return true;
		}

		return false;
	}

	bool LennardJones::operator == (const LennardJones& lj) const throw()
	{
		return (ParameterSection::operator == (lj)
						&& (A_ 		== lj.A_)
						&& (B_ 		== lj.B_)
						&& (Aij_ 	== lj.Aij_)
						&& (Bij_ 	== lj.Bij_));
	}

} // namespace BALL
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "dht/i_partitioner.hh"
#include "schema.hh"
#include "sstables/index_reader.hh"

class index_reader_assertions {
    std::unique_ptr<sstables::index_reader> _r;
public:
    index_reader_assertions(std::unique_ptr<sstables::index_reader> r)
        : _r(std::move(r))
    { }

    index_reader_assertions& has_monotonic_positions(const schema& s) {
        auto pos_cmp = position_in_partition::composite_less_compare(s);
        auto rp_cmp = dht::ring_position_comparator(s);
        auto prev = dht::ring_position::min();
        _r->read_partition_data().get();
        while (!_r->eof()) {
            auto k = _r->current_partition_entry().get_decorated_key();
            auto rp = dht::ring_position(k.token(), k.key().to_partition_key(s));

            if (!rp_cmp(prev, rp)) {
                BOOST_FAIL(sprint("Partitions have invalid order: %s >= %s", prev, rp));
            }

            prev = rp;

            auto* pi = _r->current_partition_entry().get_promoted_index(s);
            if (!pi->entries.empty()) {
                auto& prev = pi->entries[0];
                for (size_t i = 1; i < pi->entries.size(); ++i) {
                    auto& cur = pi->entries[i];
                    if (pos_cmp(cur.start, prev.end)) {
                        std::cout << "promoted index:\n";
                        for (auto& e : pi->entries) {
                            std::cout << "  " << e.start << "-" << e.end << ": +" << e.offset << " len=" << e.width << std::endl;
                        }
                        BOOST_FAIL(sprint("Index blocks are not monotonic: %s >= %s", prev.end, cur.start));
                    }
                    cur = prev;
                }
            }
            _r->advance_to_next_partition().get();
        }
        return *this;
    }
};

inline
index_reader_assertions assert_that(std::unique_ptr<sstables::index_reader> r) {
    return { std::move(r) };
}
<commit_msg>tests/sstable_assertions: Assert a promoted index is empty<commit_after>/*
 * Copyright (C) 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "dht/i_partitioner.hh"
#include "schema.hh"
#include "sstables/index_reader.hh"

class index_reader_assertions {
    std::unique_ptr<sstables::index_reader> _r;
public:
    index_reader_assertions(std::unique_ptr<sstables::index_reader> r)
        : _r(std::move(r))
    { }

    index_reader_assertions& has_monotonic_positions(const schema& s) {
        auto pos_cmp = position_in_partition::composite_less_compare(s);
        auto rp_cmp = dht::ring_position_comparator(s);
        auto prev = dht::ring_position::min();
        _r->read_partition_data().get();
        while (!_r->eof()) {
            auto k = _r->current_partition_entry().get_decorated_key();
            auto rp = dht::ring_position(k.token(), k.key().to_partition_key(s));

            if (!rp_cmp(prev, rp)) {
                BOOST_FAIL(sprint("Partitions have invalid order: %s >= %s", prev, rp));
            }

            prev = rp;

            auto* pi = _r->current_partition_entry().get_promoted_index(s);
            if (!pi->entries.empty()) {
                auto& prev = pi->entries[0];
                for (size_t i = 1; i < pi->entries.size(); ++i) {
                    auto& cur = pi->entries[i];
                    if (pos_cmp(cur.start, prev.end)) {
                        std::cout << "promoted index:\n";
                        for (auto& e : pi->entries) {
                            std::cout << "  " << e.start << "-" << e.end << ": +" << e.offset << " len=" << e.width << std::endl;
                        }
                        BOOST_FAIL(sprint("Index blocks are not monotonic: %s >= %s", prev.end, cur.start));
                    }
                    cur = prev;
                }
            }
            _r->advance_to_next_partition().get();
        }
        return *this;
    }

    index_reader_assertions& is_empty(const schema& s) {
        _r->read_partition_data().get();
        while (!_r->eof()) {
            auto* pi = _r->current_partition_entry().get_promoted_index(s);
            BOOST_REQUIRE(pi == nullptr);
            _r->advance_to_next_partition().get();
        }
        return *this;
    }
};

inline
index_reader_assertions assert_that(std::unique_ptr<sstables::index_reader> r) {
    return { std::move(r) };
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: expm.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: ihi $ $Date: 2007-11-26 17:05:36 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_goodies.hxx"

#include <vcl/graph.hxx>
#include <vcl/bmpacc.hxx>
#include <svtools/fltcall.hxx>

//============================ XPMWriter ==================================

class XPMWriter {

private:

    SvStream*           mpOStm;             // Die auszugebende XPM-Datei
    USHORT              mpOStmOldModus;

    BOOL                mbStatus;
    BOOL                mbTrans;
    BitmapReadAccess*   mpAcc;
    ULONG               mnWidth, mnHeight;  // Bildausmass in Pixeln
    USHORT              mnColors;

    com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;

    void                ImplCallback( USHORT nPercent );
    BOOL                ImplWriteHeader();
    void                ImplWritePalette();
    void                ImplWriteColor( USHORT );
    void                ImplWriteBody();
    void                ImplWriteNumber( sal_Int32 );
    void                ImplWritePixel( ULONG );

public:
                        XPMWriter();
                        ~XPMWriter();

    BOOL                WriteXPM( const Graphic& rGraphic, SvStream& rXPM, FilterConfigItem* pFilterConfigItem );
};

//=================== Methoden von XPMWriter ==============================

XPMWriter::XPMWriter() :
    mbStatus    ( TRUE ),
    mbTrans     ( FALSE ),
    mpAcc       ( NULL )
{
}

// ------------------------------------------------------------------------

XPMWriter::~XPMWriter()
{
}

// ------------------------------------------------------------------------

void XPMWriter::ImplCallback( USHORT nPercent )
{
    if ( xStatusIndicator.is() )
    {
        if ( nPercent <= 100 )
            xStatusIndicator->setValue( nPercent );
    }
}

//  ------------------------------------------------------------------------

BOOL XPMWriter::WriteXPM( const Graphic& rGraphic, SvStream& rXPM, FilterConfigItem* pFilterConfigItem)
{
    Bitmap  aBmp;

    mpOStm = &rXPM;

    if ( pFilterConfigItem )
    {
        xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
        if ( xStatusIndicator.is() )
        {
            rtl::OUString aMsg;
            xStatusIndicator->start( aMsg, 100 );
        }
    }

    BitmapEx    aBmpEx( rGraphic.GetBitmapEx() );
    aBmp = aBmpEx.GetBitmap();

    if ( rGraphic.IsTransparent() )                 // event. transparente Farbe erzeugen
    {
        mbTrans = TRUE;
        if ( aBmp.GetBitCount() >= 8 )              // wenn noetig Bild auf 8 bit konvertieren
            aBmp.Convert( BMP_CONVERSION_8BIT_TRANS );
        else
            aBmp.Convert( BMP_CONVERSION_4BIT_TRANS );
        aBmp.Replace( aBmpEx.GetMask(), BMP_COL_TRANS );
    }
    else
    {
        if ( aBmp.GetBitCount() > 8 )               // wenn noetig Bild auf 8 bit konvertieren
            aBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
    }
    mpAcc = aBmp.AcquireReadAccess();
    if ( mpAcc )
    {
        mnColors = mpAcc->GetPaletteEntryCount();
        mpOStmOldModus = mpOStm->GetNumberFormatInt();
        mpOStm->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );

        if ( ImplWriteHeader() )
        {
            ImplWritePalette();
            ImplWriteBody();
            *mpOStm << "\x22XPMENDEXT\x22\x0a};";
        }
        aBmp.ReleaseAccess( mpAcc );
    }
    else
        mbStatus = FALSE;

    mpOStm->SetNumberFormatInt( mpOStmOldModus );

    if ( xStatusIndicator.is() )
        xStatusIndicator->end();

    return mbStatus;
}

// ------------------------------------------------------------------------

BOOL XPMWriter::ImplWriteHeader()
{
    mnWidth = mpAcc->Width();
    mnHeight = mpAcc->Height();
    if ( mnWidth && mnHeight && mnColors )
    {
        *mpOStm << "/* XPM */\x0astatic char * image[] = \x0a{\x0a\x22";
        ImplWriteNumber( mnWidth );
        *mpOStm << (BYTE)32;
        ImplWriteNumber( mnHeight );
        *mpOStm << (BYTE)32;
        ImplWriteNumber( mnColors );
        *mpOStm << (BYTE)32;
        ImplWriteNumber( ( mnColors > 26 ) ? 2 : 1 );
        *mpOStm << "\x22,\x0a";
    }
    else mbStatus = FALSE;
    return mbStatus;
}

// ------------------------------------------------------------------------

void XPMWriter::ImplWritePalette()
{
    USHORT nTransIndex = 0xffff;

    if ( mbTrans )
        nTransIndex = mpAcc->GetBestMatchingColor( BMP_COL_TRANS );
    for ( USHORT i = 0; i < mnColors; i++ )
    {
        *mpOStm << "\x22";
        ImplWritePixel( i );
        *mpOStm << (BYTE)32;
        if ( nTransIndex != i )
        {
            ImplWriteColor( i );
            *mpOStm << "\x22,\x0a";
        }
        else
            *mpOStm << "c none\x22,\x0a";
    }
}

// ------------------------------------------------------------------------

void XPMWriter::ImplWriteBody()
{
    for ( ULONG y = 0; y < mnHeight; y++ )
    {
        ImplCallback( (USHORT)( ( 100 * y ) / mnHeight ) );         // processing output in percent
        *mpOStm << (BYTE)0x22;
        for ( ULONG x = 0; x < mnWidth; x++ )
        {
            ImplWritePixel( (BYTE)(mpAcc->GetPixel( y, x ) ) );
        }
        *mpOStm << "\x22,\x0a";
    }
}

// ------------------------------------------------------------------------
// eine Dezimalzahl im ASCII format wird in den Stream geschrieben

void XPMWriter::ImplWriteNumber( sal_Int32 nNumber )
{
    const ByteString aNum( ByteString::CreateFromInt32( nNumber ) );

    for( sal_Int16 n = 0UL, nLen = aNum.Len(); n < nLen; n++  )
        *mpOStm << aNum.GetChar( n );

}

// ------------------------------------------------------------------------

void XPMWriter::ImplWritePixel( ULONG nCol )
{
    if ( mnColors > 26 )
    {
        BYTE nDiff = (BYTE) ( nCol / 26 );
        *mpOStm << (BYTE)( nDiff + 'A' );
        *mpOStm << (BYTE)( nCol - ( nDiff*26 ) + 'A' );
    }
    else
        *mpOStm << (BYTE)( nCol + 'A' );
}

// ------------------------------------------------------------------------
// ein Farbwert wird im Hexadezimalzahlformat in den Stream geschrieben
void XPMWriter::ImplWriteColor( USHORT nNumber )
{
    ULONG   nTmp;
    BYTE    j;

    *mpOStm << "c #";   // # zeigt einen folgenden Hexwert an
    const BitmapColor& rColor = mpAcc->GetPaletteColor( nNumber );
    nTmp = ( rColor.GetRed() << 16 ) | ( rColor.GetGreen() << 8 ) | rColor.GetBlue();
    for ( signed char i = 20; i >= 0 ; i-=4 )
    {
        if ( ( j = (BYTE)( nTmp >> i ) & 0xf ) > 9 )
            j += 'A' - 10;
        else
            j += '0';
        *mpOStm << j;
    }
}

// ------------------------------------------------------------------------

// ---------------------
// - exported function -
// ---------------------

extern "C" BOOL __LOADONCALLAPI GraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pFilterConfigItem, BOOL )
{
    XPMWriter aXPMWriter;

    return aXPMWriter.WriteXPM( rGraphic, rStream, pFilterConfigItem );
}

#ifndef GCC
#endif

// ---------------
// - Win16 trash -
// ---------------

#ifdef WIN

static HINSTANCE hDLLInst = 0;

extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
{
    if ( nHeap )
        UnlockData( 0 );

    hDLLInst = hDLL;

    return TRUE;
}

// ------------------------------------------------------------------------

extern "C" int CALLBACK WEP( int )
{
    return 1;
}

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.9.40); FILE MERGED 2008/03/31 13:39:38 rt 1.9.40.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: expm.cxx,v $
 * $Revision: 1.10 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_goodies.hxx"

#include <vcl/graph.hxx>
#include <vcl/bmpacc.hxx>
#include <svtools/fltcall.hxx>

//============================ XPMWriter ==================================

class XPMWriter {

private:

    SvStream*           mpOStm;             // Die auszugebende XPM-Datei
    USHORT              mpOStmOldModus;

    BOOL                mbStatus;
    BOOL                mbTrans;
    BitmapReadAccess*   mpAcc;
    ULONG               mnWidth, mnHeight;  // Bildausmass in Pixeln
    USHORT              mnColors;

    com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;

    void                ImplCallback( USHORT nPercent );
    BOOL                ImplWriteHeader();
    void                ImplWritePalette();
    void                ImplWriteColor( USHORT );
    void                ImplWriteBody();
    void                ImplWriteNumber( sal_Int32 );
    void                ImplWritePixel( ULONG );

public:
                        XPMWriter();
                        ~XPMWriter();

    BOOL                WriteXPM( const Graphic& rGraphic, SvStream& rXPM, FilterConfigItem* pFilterConfigItem );
};

//=================== Methoden von XPMWriter ==============================

XPMWriter::XPMWriter() :
    mbStatus    ( TRUE ),
    mbTrans     ( FALSE ),
    mpAcc       ( NULL )
{
}

// ------------------------------------------------------------------------

XPMWriter::~XPMWriter()
{
}

// ------------------------------------------------------------------------

void XPMWriter::ImplCallback( USHORT nPercent )
{
    if ( xStatusIndicator.is() )
    {
        if ( nPercent <= 100 )
            xStatusIndicator->setValue( nPercent );
    }
}

//  ------------------------------------------------------------------------

BOOL XPMWriter::WriteXPM( const Graphic& rGraphic, SvStream& rXPM, FilterConfigItem* pFilterConfigItem)
{
    Bitmap  aBmp;

    mpOStm = &rXPM;

    if ( pFilterConfigItem )
    {
        xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
        if ( xStatusIndicator.is() )
        {
            rtl::OUString aMsg;
            xStatusIndicator->start( aMsg, 100 );
        }
    }

    BitmapEx    aBmpEx( rGraphic.GetBitmapEx() );
    aBmp = aBmpEx.GetBitmap();

    if ( rGraphic.IsTransparent() )                 // event. transparente Farbe erzeugen
    {
        mbTrans = TRUE;
        if ( aBmp.GetBitCount() >= 8 )              // wenn noetig Bild auf 8 bit konvertieren
            aBmp.Convert( BMP_CONVERSION_8BIT_TRANS );
        else
            aBmp.Convert( BMP_CONVERSION_4BIT_TRANS );
        aBmp.Replace( aBmpEx.GetMask(), BMP_COL_TRANS );
    }
    else
    {
        if ( aBmp.GetBitCount() > 8 )               // wenn noetig Bild auf 8 bit konvertieren
            aBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
    }
    mpAcc = aBmp.AcquireReadAccess();
    if ( mpAcc )
    {
        mnColors = mpAcc->GetPaletteEntryCount();
        mpOStmOldModus = mpOStm->GetNumberFormatInt();
        mpOStm->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );

        if ( ImplWriteHeader() )
        {
            ImplWritePalette();
            ImplWriteBody();
            *mpOStm << "\x22XPMENDEXT\x22\x0a};";
        }
        aBmp.ReleaseAccess( mpAcc );
    }
    else
        mbStatus = FALSE;

    mpOStm->SetNumberFormatInt( mpOStmOldModus );

    if ( xStatusIndicator.is() )
        xStatusIndicator->end();

    return mbStatus;
}

// ------------------------------------------------------------------------

BOOL XPMWriter::ImplWriteHeader()
{
    mnWidth = mpAcc->Width();
    mnHeight = mpAcc->Height();
    if ( mnWidth && mnHeight && mnColors )
    {
        *mpOStm << "/* XPM */\x0astatic char * image[] = \x0a{\x0a\x22";
        ImplWriteNumber( mnWidth );
        *mpOStm << (BYTE)32;
        ImplWriteNumber( mnHeight );
        *mpOStm << (BYTE)32;
        ImplWriteNumber( mnColors );
        *mpOStm << (BYTE)32;
        ImplWriteNumber( ( mnColors > 26 ) ? 2 : 1 );
        *mpOStm << "\x22,\x0a";
    }
    else mbStatus = FALSE;
    return mbStatus;
}

// ------------------------------------------------------------------------

void XPMWriter::ImplWritePalette()
{
    USHORT nTransIndex = 0xffff;

    if ( mbTrans )
        nTransIndex = mpAcc->GetBestMatchingColor( BMP_COL_TRANS );
    for ( USHORT i = 0; i < mnColors; i++ )
    {
        *mpOStm << "\x22";
        ImplWritePixel( i );
        *mpOStm << (BYTE)32;
        if ( nTransIndex != i )
        {
            ImplWriteColor( i );
            *mpOStm << "\x22,\x0a";
        }
        else
            *mpOStm << "c none\x22,\x0a";
    }
}

// ------------------------------------------------------------------------

void XPMWriter::ImplWriteBody()
{
    for ( ULONG y = 0; y < mnHeight; y++ )
    {
        ImplCallback( (USHORT)( ( 100 * y ) / mnHeight ) );         // processing output in percent
        *mpOStm << (BYTE)0x22;
        for ( ULONG x = 0; x < mnWidth; x++ )
        {
            ImplWritePixel( (BYTE)(mpAcc->GetPixel( y, x ) ) );
        }
        *mpOStm << "\x22,\x0a";
    }
}

// ------------------------------------------------------------------------
// eine Dezimalzahl im ASCII format wird in den Stream geschrieben

void XPMWriter::ImplWriteNumber( sal_Int32 nNumber )
{
    const ByteString aNum( ByteString::CreateFromInt32( nNumber ) );

    for( sal_Int16 n = 0UL, nLen = aNum.Len(); n < nLen; n++  )
        *mpOStm << aNum.GetChar( n );

}

// ------------------------------------------------------------------------

void XPMWriter::ImplWritePixel( ULONG nCol )
{
    if ( mnColors > 26 )
    {
        BYTE nDiff = (BYTE) ( nCol / 26 );
        *mpOStm << (BYTE)( nDiff + 'A' );
        *mpOStm << (BYTE)( nCol - ( nDiff*26 ) + 'A' );
    }
    else
        *mpOStm << (BYTE)( nCol + 'A' );
}

// ------------------------------------------------------------------------
// ein Farbwert wird im Hexadezimalzahlformat in den Stream geschrieben
void XPMWriter::ImplWriteColor( USHORT nNumber )
{
    ULONG   nTmp;
    BYTE    j;

    *mpOStm << "c #";   // # zeigt einen folgenden Hexwert an
    const BitmapColor& rColor = mpAcc->GetPaletteColor( nNumber );
    nTmp = ( rColor.GetRed() << 16 ) | ( rColor.GetGreen() << 8 ) | rColor.GetBlue();
    for ( signed char i = 20; i >= 0 ; i-=4 )
    {
        if ( ( j = (BYTE)( nTmp >> i ) & 0xf ) > 9 )
            j += 'A' - 10;
        else
            j += '0';
        *mpOStm << j;
    }
}

// ------------------------------------------------------------------------

// ---------------------
// - exported function -
// ---------------------

extern "C" BOOL __LOADONCALLAPI GraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pFilterConfigItem, BOOL )
{
    XPMWriter aXPMWriter;

    return aXPMWriter.WriteXPM( rGraphic, rStream, pFilterConfigItem );
}

#ifndef GCC
#endif

// ---------------
// - Win16 trash -
// ---------------

#ifdef WIN

static HINSTANCE hDLLInst = 0;

extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
{
    if ( nHeap )
        UnlockData( 0 );

    hDLLInst = hDLL;

    return TRUE;
}

// ------------------------------------------------------------------------

extern "C" int CALLBACK WEP( int )
{
    return 1;
}

#endif
<|endoftext|>


<commit_before>//===- SimplifyCFG.cpp - Code to perform CFG simplification ---------------===//
//
// SimplifyCFG - This function is used to do simplification of a CFG.  For
// example, it adjusts branches to branches to eliminate the extra hop, it
// eliminates unreachable basic blocks, and does other "peephole" optimization
// of the CFG.  It returns true if a modification was made, and returns an
// iterator that designates the first element remaining after the block that
// was deleted.
//
// WARNING:  The entry node of a function may not be simplified.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constant.h"
#include "llvm/iPHINode.h"
#include "llvm/Support/CFG.h"
#include <algorithm>
#include <functional>

// PropogatePredecessors - This gets "Succ" ready to have the predecessors from
// "BB".  This is a little tricky because "Succ" has PHI nodes, which need to
// have extra slots added to them to hold the merge edges from BB's
// predecessors.  This function returns true (failure) if the Succ BB already
// has a predecessor that is a predecessor of BB.
//
// Assumption: Succ is the single successor for BB.
//
static bool PropogatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {
  assert(*succ_begin(BB) == Succ && "Succ is not successor of BB!");
  assert(isa<PHINode>(Succ->front()) && "Only works on PHId BBs!");

  // If there is more than one predecessor, and there are PHI nodes in
  // the successor, then we need to add incoming edges for the PHI nodes
  //
  const std::vector<BasicBlock*> BBPreds(pred_begin(BB), pred_end(BB));

  // Check to see if one of the predecessors of BB is already a predecessor of
  // Succ.  If so, we cannot do the transformation!
  //
  for (pred_iterator PI = pred_begin(Succ), PE = pred_end(Succ);
       PI != PE; ++PI) {
    if (find(BBPreds.begin(), BBPreds.end(), *PI) != BBPreds.end())
      return true;
  }

  // Loop over all of the PHI nodes in the successor BB
  for (BasicBlock::iterator I = Succ->begin();
       PHINode *PN = dyn_cast<PHINode>(&*I); ++I) {
    Value *OldVal = PN->removeIncomingValue(BB);
    assert(OldVal && "No entry in PHI for Pred BB!");

    for (std::vector<BasicBlock*>::const_iterator PredI = BBPreds.begin(),
	   End = BBPreds.end(); PredI != End; ++PredI) {
      // Add an incoming value for each of the new incoming values...
      PN->addIncoming(OldVal, *PredI);
    }
  }
  return false;
}

// SimplifyCFG - This function is used to do simplification of a CFG.  For
// example, it adjusts branches to branches to eliminate the extra hop, it
// eliminates unreachable basic blocks, and does other "peephole" optimization
// of the CFG.  It returns true if a modification was made, and returns an
// iterator that designates the first element remaining after the block that
// was deleted.
//
// WARNING:  The entry node of a function may not be simplified.
//
bool SimplifyCFG(BasicBlock *BB) {
  Function *M = BB->getParent();

  assert(BB && BB->getParent() && "Block not embedded in function!");
  assert(BB->getTerminator() && "Degenerate basic block encountered!");
  assert(&BB->getParent()->front() != BB && "Can't Simplify entry block!");

  // Remove basic blocks that have no predecessors... which are unreachable.
  if (pred_begin(BB) == pred_end(BB) &&
      !BB->hasConstantReferences()) {
    //cerr << "Removing BB: \n" << BB;

    // Loop through all of our successors and make sure they know that one
    // of their predecessors is going away.
    for_each(succ_begin(BB), succ_end(BB),
	     std::bind2nd(std::mem_fun(&BasicBlock::removePredecessor), BB));

    while (!BB->empty()) {
      Instruction &I = BB->back();
      // If this instruction is used, replace uses with an arbitrary
      // constant value.  Because control flow can't get here, we don't care
      // what we replace the value with.  Note that since this block is
      // unreachable, and all values contained within it must dominate their
      // uses, that all uses will eventually be removed.
      if (!I.use_empty())
        // Make all users of this instruction reference the constant instead
        I.replaceAllUsesWith(Constant::getNullValue(I.getType()));

      // Remove the instruction from the basic block
      BB->getInstList().pop_back();
    }
    M->getBasicBlockList().erase(BB);
    return true;
  }

  // Check to see if this block has no instructions and only a single
  // successor.  If so, replace block references with successor.
  succ_iterator SI(succ_begin(BB));
  if (SI != succ_end(BB) && ++SI == succ_end(BB)) {  // One succ?
    if (BB->front().isTerminator()) {   // Terminator is the only instruction!
      BasicBlock *Succ = *succ_begin(BB); // There is exactly one successor

      if (Succ != BB) {   // Arg, don't hurt infinite loops!
        // If our successor has PHI nodes, then we need to update them to
        // include entries for BB's predecessors, not for BB itself.
        // Be careful though, if this transformation fails (returns true) then
        // we cannot do this transformation!
        //
	if (!isa<PHINode>(Succ->front()) ||
            !PropogatePredecessorsForPHIs(BB, Succ)) {

          //cerr << "Killing Trivial BB: \n" << BB;

          BB->replaceAllUsesWith(Succ);
          std::string OldName = BB->getName();

          // Delete the old basic block...
          M->getBasicBlockList().erase(BB);

          if (!OldName.empty() && !Succ->hasName())  // Transfer name if we can
            Succ->setName(OldName);

          //cerr << "Function after removal: \n" << M;
          return true;
	}
      }
    }
  }

  // Merge basic blocks into their predecessor if there is only one distinct
  // pred, and if there is only one distinct successor of the predecessor, and
  // if there are no PHI nodes.
  //
  if (!BB->hasConstantReferences()) {
    pred_iterator PI(pred_begin(BB)), PE(pred_end(BB));
    BasicBlock *OnlyPred = *PI++;
    for (; PI != PE; ++PI)  // Search all predecessors, see if they are all same
      if (*PI != OnlyPred) {
        OnlyPred = 0;       // There are multiple different predecessors...
        break;
      }

    BasicBlock *OnlySucc = 0;
    if (OnlyPred && OnlyPred != BB) {   // Don't break self loops
      // Check to see if there is only one distinct successor...
      succ_iterator SI(succ_begin(OnlyPred)), SE(succ_end(OnlyPred));
      OnlySucc = BB;
      for (; SI != SE; ++SI)
        if (*SI != OnlySucc) {
          OnlySucc = 0;     // There are multiple distinct successors!
          break;
        }
    }

    if (OnlySucc) {
      //cerr << "Merging: " << BB << "into: " << OnlyPred;
      TerminatorInst *Term = OnlyPred->getTerminator();

      // Resolve any PHI nodes at the start of the block.  They are all
      // guaranteed to have exactly one entry if they exist.
      //
      while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) {
        assert(PN->getNumIncomingValues() == 1 && "Only one pred!");
        PN->replaceAllUsesWith(PN->getIncomingValue(0));
        BB->getInstList().pop_front();  // Delete the phi node...
      }

      // Delete the unconditional branch from the predecessor...
      OnlyPred->getInstList().pop_back();

      // Move all definitions in the succecessor to the predecessor...
      OnlyPred->getInstList().splice(OnlyPred->end(), BB->getInstList());

      // Make all PHI nodes that refered to BB now refer to Pred as their
      // source...
      BB->replaceAllUsesWith(OnlyPred);

      std::string OldName = BB->getName();

      // Erase basic block from the function...
      M->getBasicBlockList().erase(BB);

      // Inherit predecessors name if it exists...
      if (!OldName.empty() && !OnlyPred->hasName())
        OnlyPred->setName(OldName);

      return true;
    }
  }

  return false;
}
<commit_msg>Minor cleanups<commit_after>//===- SimplifyCFG.cpp - Code to perform CFG simplification ---------------===//
//
// SimplifyCFG - This function is used to do simplification of a CFG.  For
// example, it adjusts branches to branches to eliminate the extra hop, it
// eliminates unreachable basic blocks, and does other "peephole" optimization
// of the CFG.  It returns true if a modification was made, and returns an
// iterator that designates the first element remaining after the block that
// was deleted.
//
// WARNING:  The entry node of a function may not be simplified.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constant.h"
#include "llvm/iPHINode.h"
#include "llvm/Support/CFG.h"
#include <algorithm>
#include <functional>

// PropogatePredecessors - This gets "Succ" ready to have the predecessors from
// "BB".  This is a little tricky because "Succ" has PHI nodes, which need to
// have extra slots added to them to hold the merge edges from BB's
// predecessors.  This function returns true (failure) if the Succ BB already
// has a predecessor that is a predecessor of BB.
//
// Assumption: Succ is the single successor for BB.
//
static bool PropogatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {
  assert(*succ_begin(BB) == Succ && "Succ is not successor of BB!");

  if (!isa<PHINode>(Succ->front()))
    return false;  // We can make the transformation, no problem.

  // If there is more than one predecessor, and there are PHI nodes in
  // the successor, then we need to add incoming edges for the PHI nodes
  //
  const std::vector<BasicBlock*> BBPreds(pred_begin(BB), pred_end(BB));

  // Check to see if one of the predecessors of BB is already a predecessor of
  // Succ.  If so, we cannot do the transformation!
  //
  for (pred_iterator PI = pred_begin(Succ), PE = pred_end(Succ);
       PI != PE; ++PI)
    if (find(BBPreds.begin(), BBPreds.end(), *PI) != BBPreds.end())
      return true;

  // Loop over all of the PHI nodes in the successor BB
  for (BasicBlock::iterator I = Succ->begin();
       PHINode *PN = dyn_cast<PHINode>(&*I); ++I) {
    Value *OldVal = PN->removeIncomingValue(BB);
    assert(OldVal && "No entry in PHI for Pred BB!");

    for (std::vector<BasicBlock*>::const_iterator PredI = BBPreds.begin(),
	   End = BBPreds.end(); PredI != End; ++PredI) {
      // Add an incoming value for each of the new incoming values...
      PN->addIncoming(OldVal, *PredI);
    }
  }
  return false;
}

// SimplifyCFG - This function is used to do simplification of a CFG.  For
// example, it adjusts branches to branches to eliminate the extra hop, it
// eliminates unreachable basic blocks, and does other "peephole" optimization
// of the CFG.  It returns true if a modification was made, and returns an
// iterator that designates the first element remaining after the block that
// was deleted.
//
// WARNING:  The entry node of a function may not be simplified.
//
bool SimplifyCFG(BasicBlock *BB) {
  Function *M = BB->getParent();

  assert(BB && BB->getParent() && "Block not embedded in function!");
  assert(BB->getTerminator() && "Degenerate basic block encountered!");
  assert(&BB->getParent()->front() != BB && "Can't Simplify entry block!");

  // Remove basic blocks that have no predecessors... which are unreachable.
  if (pred_begin(BB) == pred_end(BB) &&
      !BB->hasConstantReferences()) {
    //cerr << "Removing BB: \n" << BB;

    // Loop through all of our successors and make sure they know that one
    // of their predecessors is going away.
    for_each(succ_begin(BB), succ_end(BB),
	     std::bind2nd(std::mem_fun(&BasicBlock::removePredecessor), BB));

    while (!BB->empty()) {
      Instruction &I = BB->back();
      // If this instruction is used, replace uses with an arbitrary
      // constant value.  Because control flow can't get here, we don't care
      // what we replace the value with.  Note that since this block is
      // unreachable, and all values contained within it must dominate their
      // uses, that all uses will eventually be removed.
      if (!I.use_empty())
        // Make all users of this instruction reference the constant instead
        I.replaceAllUsesWith(Constant::getNullValue(I.getType()));

      // Remove the instruction from the basic block
      BB->getInstList().pop_back();
    }
    M->getBasicBlockList().erase(BB);
    return true;
  }

  // Check to see if this block has no instructions and only a single
  // successor.  If so, replace block references with successor.
  succ_iterator SI(succ_begin(BB));
  if (SI != succ_end(BB) && ++SI == succ_end(BB)) {  // One succ?
    if (BB->front().isTerminator()) {   // Terminator is the only instruction!
      BasicBlock *Succ = *succ_begin(BB); // There is exactly one successor

      if (Succ != BB) {   // Arg, don't hurt infinite loops!
        // If our successor has PHI nodes, then we need to update them to
        // include entries for BB's predecessors, not for BB itself.
        // Be careful though, if this transformation fails (returns true) then
        // we cannot do this transformation!
        //
	if (!PropogatePredecessorsForPHIs(BB, Succ)) {
          //cerr << "Killing Trivial BB: \n" << BB;
          BB->replaceAllUsesWith(Succ);
          std::string OldName = BB->getName();

          // Delete the old basic block...
          M->getBasicBlockList().erase(BB);

          if (!OldName.empty() && !Succ->hasName())  // Transfer name if we can
            Succ->setName(OldName);

          //cerr << "Function after removal: \n" << M;
          return true;
	}
      }
    }
  }

  // Merge basic blocks into their predecessor if there is only one distinct
  // pred, and if there is only one distinct successor of the predecessor, and
  // if there are no PHI nodes.
  //
  if (!BB->hasConstantReferences()) {
    pred_iterator PI(pred_begin(BB)), PE(pred_end(BB));
    BasicBlock *OnlyPred = *PI++;
    for (; PI != PE; ++PI)  // Search all predecessors, see if they are all same
      if (*PI != OnlyPred) {
        OnlyPred = 0;       // There are multiple different predecessors...
        break;
      }

    BasicBlock *OnlySucc = 0;
    if (OnlyPred && OnlyPred != BB) {   // Don't break self loops
      // Check to see if there is only one distinct successor...
      succ_iterator SI(succ_begin(OnlyPred)), SE(succ_end(OnlyPred));
      OnlySucc = BB;
      for (; SI != SE; ++SI)
        if (*SI != OnlySucc) {
          OnlySucc = 0;     // There are multiple distinct successors!
          break;
        }
    }

    if (OnlySucc) {
      //cerr << "Merging: " << BB << "into: " << OnlyPred;
      TerminatorInst *Term = OnlyPred->getTerminator();

      // Resolve any PHI nodes at the start of the block.  They are all
      // guaranteed to have exactly one entry if they exist.
      //
      while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) {
        assert(PN->getNumIncomingValues() == 1 && "Only one pred!");
        PN->replaceAllUsesWith(PN->getIncomingValue(0));
        BB->getInstList().pop_front();  // Delete the phi node...
      }

      // Delete the unconditional branch from the predecessor...
      OnlyPred->getInstList().pop_back();

      // Move all definitions in the succecessor to the predecessor...
      OnlyPred->getInstList().splice(OnlyPred->end(), BB->getInstList());

      // Make all PHI nodes that refered to BB now refer to Pred as their
      // source...
      BB->replaceAllUsesWith(OnlyPred);

      std::string OldName = BB->getName();

      // Erase basic block from the function...
      M->getBasicBlockList().erase(BB);

      // Inherit predecessors name if it exists...
      if (!OldName.empty() && !OnlyPred->hasName())
        OnlyPred->setName(OldName);

      return true;
    }
  }

  return false;
}
<|endoftext|>


<commit_before>//this tutorial illustrates how to:
//  -create a variable binwidth histogram with a binning such
//   that the population per bin is about the same.
//  -rebin a variable binwidth histogram into another one.
//Author: Rene Brun

#include "TH1.h"
#include "TCanvas.h"
void rebin() {
   //create a fix bin histogram
   TH1F *h = new TH1F("h","test rebin",100,-3,3);
   Int_t nentries = 1000;
   h->FillRandom("gaus",nentries);
   Double_t xbins[1000];
   Int_t k=0;
   TAxis *axis = h->GetXaxis();
   for (Int_t i=1;i<=100;i++) {
      Int_t y = (Int_t)h->GetBinContent(i);
      if (y <=0) continue;
      Double_t dx = axis->GetBinWidth(i)/y;
      Double_t xmin = axis->GetBinLowEdge(i);
      for (Int_t j=0;j<y;j++) {
         xbins[k] = xmin +j*dx;
         k++;
      }
   }
   //create a variable binwidth histogram out of fix bin histogram
   //new rebinned histogram should have about 10 entries per bin
   TH1F *hnew = new TH1F("hnew","rebinned",k-1,xbins);
   hnew->FillRandom("gaus",10*nentries);

   //rebin hnew keeping only 50% of the bins
   Double_t xbins2[500];
   Int_t kk=0;
   for (Int_t j=0;j<k;j+=2) {
      xbins2[kk] = xbins[j];
      kk++;
   }
   xbins2[kk] = xbins[k];
   TH1F *hnew2 = (TH1F*)hnew->Rebin(kk-1,"hnew2",xbins2);

   //draw the 3 histograms
   TCanvas *c1 = new TCanvas("c1","c1",800,1000);
   c1->Divide(1,3);
   c1->cd(1);
   h->Draw();
   c1->cd(2);
   hnew->Draw();
   c1->cd(3);
   hnew2->Draw();
}
<commit_msg>Fix a problem reported by the nighties. The array xbins was dimensioned 500 instead of 501.<commit_after>//this tutorial illustrates how to:
//  -create a variable binwidth histogram with a binning such
//   that the population per bin is about the same.
//  -rebin a variable binwidth histogram into another one.
//Author: Rene Brun

#include "TH1.h"
#include "TCanvas.h"
void rebin() {
   //create a fix bin histogram
   TH1F *h = new TH1F("h","test rebin",100,-3,3);
   Int_t nentries = 1000;
   h->FillRandom("gaus",nentries);
   Double_t xbins[1000];
   Int_t k=0;
   TAxis *axis = h->GetXaxis();
   for (Int_t i=1;i<=100;i++) {
      Int_t y = (Int_t)h->GetBinContent(i);
      if (y <=0) continue;
      Double_t dx = axis->GetBinWidth(i)/y;
      Double_t xmin = axis->GetBinLowEdge(i);
      for (Int_t j=0;j<y;j++) {
         xbins[k] = xmin +j*dx;
         k++;
      }
   }
   //create a variable binwidth histogram out of fix bin histogram
   //new rebinned histogram should have about 10 entries per bin
   TH1F *hnew = new TH1F("hnew","rebinned",k-1,xbins);
   hnew->FillRandom("gaus",10*nentries);

   //rebin hnew keeping only 50% of the bins
   Double_t xbins2[501];
   Int_t kk=0;
   for (Int_t j=0;j<k;j+=2) {
      xbins2[kk] = xbins[j];
      kk++;
   }
   xbins2[kk] = xbins[k];
   TH1F *hnew2 = (TH1F*)hnew->Rebin(kk-1,"hnew2",xbins2);

   //draw the 3 histograms
   TCanvas *c1 = new TCanvas("c1","c1",800,1000);
   c1->Divide(1,3);
   c1->cd(1);
   h->Draw();
   c1->cd(2);
   hnew->Draw();
   c1->cd(3);
   hnew2->Draw();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <boost/program_options.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/filesystem.hpp>
#include <boost/uuid/uuid_io.hpp>

#include "csv_back.h"
#include "cyclus.h"
#include "hdf5_back.h"
#include "sqlite_back.h"
#include "xml_file_loader.h"
#include "xml_flat_loader.h"

#include "sim_init.h"
#include "query_backend.h"
#include <boost/uuid/uuid_generators.hpp>

namespace po = boost::program_options;
namespace fs = boost::filesystem;

using namespace cyclus;

//-----------------------------------------------------------------------
// Main entry point for the test application...
//-----------------------------------------------------------------------
int main(int argc, char* argv[]) {
  // close all dlopen'd modules AFTER everything else destructs
  DynamicModule::Closer cl;

  // verbosity help msg
  std::string vmessage = "output log verbosity. Can be text:\n\n";
  vmessage +=
      "   LEV_ERROR (least verbose, default), LEV_WARN, \n"
      "   LEV_INFO1 (through 5), and LEV_DEBUG1 (through 5).\n\n";
  vmessage +=
      "Or an integer:\n\n   0 (LEV_ERROR equiv) through 11 (LEV_DEBUG5 equiv)\n";

  // parse command line options
  po::options_description desc("Allowed options");
  desc.add_options()
      ("help,h", "produce help message")
      ("include", "print the cyclus include directory")
      ("version", "print cyclus core and dependency versions and quit")
      ("schema",
       "dump the cyclus master schema including all installed module schemas")
      ("module-schema", po::value<std::string>(),
       "dump the schema for the named module")
      ("schema-path", po::value<std::string>(),
       "manually specify the path to the cyclus master schema")
      ("flat-schema", "use the flat master simulation schema")
      ("no-model", "only print log entries from cyclus core code")
      ("no-mem", "exclude memory log statement from logger output")
      ("verb,v", po::value<std::string>(), vmessage.c_str())
      ("output-path,o", po::value<std::string>(), "output path")
      ("input-file", po::value<std::string>(), "input file")
      ;

  po::variables_map vm;
  try {
    po::store(po::parse_command_line(argc, argv, desc), vm);
  } catch(std::exception err) {
    std::cout << "Invalid arguments.\n"
              <<  "Usage:   cyclus [options] [path/to/input/filename]\n"
              << desc << "\n";
    return 1;
  }
  po::notify(vm);

  po::positional_options_description p;
  p.add("input-file", 1);

  // po::variables_map vm;
  po::store(po::command_line_parser(argc, argv).
            options(desc).positional(p).run(), vm);
  po::notify(vm);

  // setup context

  std::string schema_path = Env::GetInstallPath() + "/share/cyclus.rng.in";
  bool flat_schema = false;
  if (vm.count("flat-schema")) {
    schema_path = Env::GetInstallPath() + "/share/cyclus-flat.rng.in";
    flat_schema = true;
  }
  if (vm.count("schema-path")) {
    schema_path = vm["schema-path"].as<std::string>();
  }

  // respond to command line args that don't run a simulation
  if (vm.count("help")) {
    std::string err_msg = "Cyclus usage requires an input file.\n";
    err_msg += "Usage:   cyclus [options] [path/to/input/filename]\n";
    std::cout << err_msg << std::endl;
    std::cout << desc << "\n";
    return 0;
  } else if (vm.count("version")) {
    std::cout << "Cyclus Core " << version::core()
              << " (" << version::describe() << ")"
              << "\n\nDependencies:\n";
    std::cout << "   Boost    " << version::boost() << "\n";
    std::cout << "   Coin-Cbc " << version::coincbc() << "\n";
    std::cout << "   Hdf5     " << version::hdf5() << "\n";
    std::cout << "   Sqlite3  " << version::sqlite3() << "\n";
    std::cout << "   xml2     " << version::xml2() << "\n";
    return 0;
  } else if (vm.count("include")) {
    std::cout << Env::GetInstallPath() << "/include/cyclus/\n";
    return 0;
  } else if (vm.count("schema")) {
    try {
      if (flat_schema) {
        std::cout << "\n" << BuildFlatMasterSchema(schema_path) << "\n";
      } else {
        std::cout << "\n" << BuildMasterSchema(schema_path) << "\n";
      }
    } catch (cyclus::IOError err) {
      std::cout << err.what() << "\n";
      return 1;
    }
    return 0;
  } else if (vm.count("module-schema")) {
    std::string name(vm["module-schema"].as<std::string>());
    try {
      Recorder rec;
      Timer ti;
      Context* ctx = new Context(&ti, &rec);
      Model* m = DynamicModule::Make(ctx, name);
      std::cout << "<element name=\"" << name << "\">\n";
      std::cout << m->schema();
      std::cout << "</element>\n";
      ctx->DelModel(m);
    } catch (cyclus::IOError err) {
      std::cout << err.what() << "\n";
    }
    return 0;
  }

  // announce yourself
  std::cout << "              :                                                               " << std::endl;
  std::cout << "          .CL:CC CC             _Q     _Q  _Q_Q    _Q    _Q              _Q   " << std::endl;
  std::cout << "        CC;CCCCCCCC:C;         /_\\)   /_\\)/_/\\\\)  /_\\)  /_\\)            /_\\)  " << std::endl;
  std::cout << "        CCCCCCCCCCCCCl       __O|/O___O|/O_OO|/O__O|/O__O|/O____________O|/O__" << std::endl;
  std::cout << "     CCCCCCf     iCCCLCC     /////////////////////////////////////////////////" << std::endl;
  std::cout << "     iCCCt  ;;;;;.  CCCC                                                      " << std::endl;
  std::cout << "    CCCC  ;;;;;;;;;. CClL.                          c                         " << std::endl;
  std::cout << "   CCCC ,;;       ;;: CCCC  ;                   : CCCCi                       " << std::endl;
  std::cout << "    CCC ;;         ;;  CC   ;;:                CCC`   `C;                     " << std::endl;
  std::cout << "  lCCC ;;              CCCC  ;;;:             :CC .;;. C;   ;    :   ;  :;;   " << std::endl;
  std::cout << "  CCCC ;.              CCCC    ;;;,           CC ;    ; Ci  ;    :   ;  :  ;  " << std::endl;
  std::cout << "   iCC :;               CC       ;;;,        ;C ;       CC  ;    :   ; .      " << std::endl;
  std::cout << "  CCCi ;;               CCC        ;;;.      .C ;       tf  ;    :   ;  ;.    " << std::endl;
  std::cout << "  CCC  ;;               CCC          ;;;;;;; fC :       lC  ;    :   ;    ;:  " << std::endl;
  std::cout << "   iCf ;;               CC         :;;:      tC ;       CC  ;    :   ;     ;  " << std::endl;
  std::cout << "  fCCC :;              LCCf      ;;;:         LC :.  ,: C   ;    ;   ; ;   ;  " << std::endl;
  std::cout << "  CCCC  ;;             CCCC    ;;;:           CCi `;;` CC.  ;;;; :;.;.  ; ,;  " << std::endl;
  std::cout << "    CCl ;;             CC    ;;;;              CCC    CCL                     " << std::endl;
  std::cout << "   tCCC  ;;        ;; CCCL  ;;;                  tCCCCC.                      " << std::endl;
  std::cout << "    CCCC  ;;     :;; CCCCf  ;                     ,L                          " << std::endl;
  std::cout << "     lCCC   ;;;;;;  CCCL                                                      " << std::endl;
  std::cout << "     CCCCCC  :;;  fCCCCC                                                      " << std::endl;
  std::cout << "      . CCCC     CCCC .                                                       " << std::endl;
  std::cout << "       .CCCCCCCCCCCCCi                                                        " << std::endl;
  std::cout << "          iCCCCCLCf                                                           " << std::endl;
  std::cout << "           .  C. ,                                                            " << std::endl;
  std::cout << "              :                                                               " << std::endl;

  if (vm.count("no-model")) {
    Logger::NoModel() = true;
  }

  if (vm.count("no-mem")) {
    Logger::NoMem() = true;
  }

  if (!vm.count("input-file")) {
    std::string err_msg = "Cyclus usage requires an input file.\n";
    err_msg += "Usage:   cyclus [path/to/input/filename]\n";
    std::cout << err_msg << std::endl;
    std::cout << desc << "\n";
    return 0;
  }

  if (vm.count("verb")) {
    std::string v_level = vm["verb"].as<std::string>();
    if (v_level.length() < 3) {
      Logger::ReportLevel() = (LogLevel)strtol(v_level.c_str(), NULL, 10);
    } else {
      Logger::ReportLevel() = Logger::ToLogLevel(v_level);
    }
  }

  // tell ENV the path between the cwd and the cyclus executable
  std::string path = Env::PathBase(argv[0]);
  Env::SetCyclusRelPath(path);

  // tell pyne about the path to nuc data
  Env::SetNucDataPath();

  // Create the output file
  std::string output_path = "cyclus.sqlite";
  try {
    if (vm.count("output-path")) {
      output_path = vm["output-path"].as<std::string>();
    }
  } catch (Error ge) {
    CLOG(LEV_ERROR) << ge.what();
    return 1;
  }

  // create db backends
  FullBackend* fback = new SqliteBack(output_path);
  RecBackend* rback = NULL;
  std::string ext = fs::path(output_path).extension().generic_string();
  if (ext == ".h5") { // not queryable
    rback = new Hdf5Back(output_path.c_str());
  } else if (ext == ".csv") { // not queryable
    rback = new CsvBack(output_path.c_str());
  }

  // read input file and initialize db from input file
  std::string inputFile = vm["input-file"].as<std::string>();
  boost::uuids::uuid simid;
  try {
    if (flat_schema) {
      XMLFlatLoader l(fback, schema_path, inputFile);
      simid = l.LoadSim();
    } else {
      XMLFileLoader l(fback, schema_path, inputFile);
      simid = l.LoadSim();
    }
  } catch (Error e) {
    CLOG(LEV_ERROR) << e.what();
    return 1;
  }

  // initialize sim from output db
  SimInit si;
  si.Init(fback, simid);
  si.recorder()->RegisterBackend(fback);
  if (rback != NULL) {
    si.recorder()->RegisterBackend(rback);
  }

  // Run the simulation
  si.timer()->RunSim();

  delete fback;
  if (rback != NULL) {
    delete rback;
  }

  std::cout << std::endl;
  std::cout << "Status: Cyclus run successful!" << std::endl;
  std::cout << "Output location: " << output_path << std::endl;
  std::cout << "Simulation ID: " << boost::lexical_cast<std::string>
               (si.context()->sim_id()) << std::endl;

  return 0;
}
<commit_msg>refactored cyclus.cc file into separate functions and cleaned it up<commit_after>#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <boost/program_options.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/filesystem.hpp>
#include <boost/uuid/uuid_io.hpp>

#include "csv_back.h"
#include "cyclus.h"
#include "hdf5_back.h"
#include "sqlite_back.h"
#include "xml_file_loader.h"
#include "xml_flat_loader.h"

#include "sim_init.h"
#include "query_backend.h"
#include <boost/uuid/uuid_generators.hpp>

namespace po = boost::program_options;
namespace fs = boost::filesystem;

using namespace cyclus;

struct ArgInfo {
  po::variables_map vm; // holds parsed/specified cli opts and values
  po::options_description desc; // holds cli opts description;
  bool flat_schema;
  std::string schema_path;
  std::string output_path;
};

// Describes and parses cli arguments.  Returns the error code that main should
// return early OR -1 if main should not return early.
int ParseCliArgs(ArgInfo* ai, int argc, char* argv[]);

// Processes and handles args that don't run a simulation. Returns the error
// code that main should return early OR -1 if main should not return early.
int EarlyExitArgs(const ArgInfo& ai);

// Using cli flags, retrieves and sets global params for the simulation.
void GetSimInfo(ArgInfo* ai);

static std::string usage = "Usage:   cyclus [opts] [input-file]";

//-----------------------------------------------------------------------
// Main entry point for the test application...
//-----------------------------------------------------------------------
int main(int argc, char* argv[]) {
  // close all dlopen'd modules AFTER everything else destructs
  DynamicModule::Closer cl;

  // tell ENV the path between the cwd and the cyclus executable
  std::string path = Env::PathBase(argv[0]);
  Env::SetCyclusRelPath(path);

  // tell pyne about the path to nuc data
  Env::SetNucDataPath();

  // handle cli option flags
  ArgInfo ai;
  int ret = ParseCliArgs(&ai, argc, argv);
  if (ret > -1 ) {
    return ret;
  }
  GetSimInfo(&ai);
  ret = EarlyExitArgs(ai);
  if (ret > -1 ) {
    return ret;
  }

  // process positional args
  if (!ai.vm.count("input-file")) {
    std::cout << "No input file specified.\n"
              << usage << "\n\n"
              << ai.desc << "\n";
    return 1;
  }
  std::string infile = ai.vm["input-file"].as<std::string>();

  // announce yourself
  std::cout << "              :                                                               " << std::endl;
  std::cout << "          .CL:CC CC             _Q     _Q  _Q_Q    _Q    _Q              _Q   " << std::endl;
  std::cout << "        CC;CCCCCCCC:C;         /_\\)   /_\\)/_/\\\\)  /_\\)  /_\\)            /_\\)  " << std::endl;
  std::cout << "        CCCCCCCCCCCCCl       __O|/O___O|/O_OO|/O__O|/O__O|/O____________O|/O__" << std::endl;
  std::cout << "     CCCCCCf     iCCCLCC     /////////////////////////////////////////////////" << std::endl;
  std::cout << "     iCCCt  ;;;;;.  CCCC                                                      " << std::endl;
  std::cout << "    CCCC  ;;;;;;;;;. CClL.                          c                         " << std::endl;
  std::cout << "   CCCC ,;;       ;;: CCCC  ;                   : CCCCi                       " << std::endl;
  std::cout << "    CCC ;;         ;;  CC   ;;:                CCC`   `C;                     " << std::endl;
  std::cout << "  lCCC ;;              CCCC  ;;;:             :CC .;;. C;   ;    :   ;  :;;   " << std::endl;
  std::cout << "  CCCC ;.              CCCC    ;;;,           CC ;    ; Ci  ;    :   ;  :  ;  " << std::endl;
  std::cout << "   iCC :;               CC       ;;;,        ;C ;       CC  ;    :   ; .      " << std::endl;
  std::cout << "  CCCi ;;               CCC        ;;;.      .C ;       tf  ;    :   ;  ;.    " << std::endl;
  std::cout << "  CCC  ;;               CCC          ;;;;;;; fC :       lC  ;    :   ;    ;:  " << std::endl;
  std::cout << "   iCf ;;               CC         :;;:      tC ;       CC  ;    :   ;     ;  " << std::endl;
  std::cout << "  fCCC :;              LCCf      ;;;:         LC :.  ,: C   ;    ;   ; ;   ;  " << std::endl;
  std::cout << "  CCCC  ;;             CCCC    ;;;:           CCi `;;` CC.  ;;;; :;.;.  ; ,;  " << std::endl;
  std::cout << "    CCl ;;             CC    ;;;;              CCC    CCL                     " << std::endl;
  std::cout << "   tCCC  ;;        ;; CCCL  ;;;                  tCCCCC.                      " << std::endl;
  std::cout << "    CCCC  ;;     :;; CCCCf  ;                     ,L                          " << std::endl;
  std::cout << "     lCCC   ;;;;;;  CCCL                                                      " << std::endl;
  std::cout << "     CCCCCC  :;;  fCCCCC                                                      " << std::endl;
  std::cout << "      . CCCC     CCCC .                                                       " << std::endl;
  std::cout << "       .CCCCCCCCCCCCCi                                                        " << std::endl;
  std::cout << "          iCCCCCLCf                                                           " << std::endl;
  std::cout << "           .  C. ,                                                            " << std::endl;
  std::cout << "              :                                                               " << std::endl;

  // create db backends
  FullBackend* fback = new SqliteBack(ai.output_path);
  RecBackend* rback = NULL;
  std::string ext = fs::path(ai.output_path).extension().generic_string();
  if (ext == ".h5") { // not queryable
    rback = new Hdf5Back(ai.output_path.c_str());
  } else if (ext == ".csv") { // not queryable
    rback = new CsvBack(ai.output_path.c_str());
  }

  // read input file and initialize db from input file
  boost::uuids::uuid simid;
  try {
    if (ai.flat_schema) {
      XMLFlatLoader l(fback, ai.schema_path, infile);
      simid = l.LoadSim();
    } else {
      XMLFileLoader l(fback, ai.schema_path, infile);
      simid = l.LoadSim();
    }
  } catch (Error e) {
    CLOG(LEV_ERROR) << e.what();
    return 1;
  }

  // initialize sim from output db
  SimInit si;
  si.Init(fback, simid);
  si.recorder()->RegisterBackend(fback);
  if (rback != NULL) {
    si.recorder()->RegisterBackend(rback);
  }

  // Run the simulation
  si.timer()->RunSim();

  delete fback;
  if (rback != NULL) {
    delete rback;
  }

  std::cout << std::endl;
  std::cout << "Status: Cyclus run successful!" << std::endl;
  std::cout << "Output location: " << ai.output_path << std::endl;
  std::cout << "Simulation ID: " << boost::lexical_cast<std::string>
               (si.context()->sim_id()) << std::endl;

  return 0;
};

int ParseCliArgs(ArgInfo* ai, int argc, char* argv[]) {
  // verbosity help msg
  std::string vmessage = "output log verbosity. Can be text:\n\n";
  vmessage +=
      "   LEV_ERROR (least verbose, default), LEV_WARN, \n"
      "   LEV_INFO1 (through 5), and LEV_DEBUG1 (through 5).\n\n";
  vmessage +=
      "Or an integer:\n\n   0 (LEV_ERROR equiv) through 11 (LEV_DEBUG5 equiv)\n";

  // parse command line options
  ai->desc.add_options()
      ("help,h", "produce help message")
      ("include", "print the cyclus include directory")
      ("version", "print cyclus core and dependency versions and quit")
      ("schema",
       "dump the cyclus master schema including all installed module schemas")
      ("module-schema", po::value<std::string>(),
       "dump the schema for the named module")
      ("schema-path", po::value<std::string>(),
       "manually specify the path to the cyclus master schema")
      ("flat-schema", "use the flat master simulation schema")
      ("no-model", "only print log entries from cyclus core code")
      ("no-mem", "exclude memory log statement from logger output")
      ("verb,v", po::value<std::string>(), vmessage.c_str())
      ("output-path,o", po::value<std::string>(), "output path")
      ("input-file", po::value<std::string>(), "input file")
      ;

  po::variables_map vm;
  try {
    po::store(po::parse_command_line(argc, argv, ai->desc), ai->vm);
  } catch(std::exception err) {
    std::cout << "Invalid arguments.\n"
              <<  usage << "\n\n"
              << ai->desc << "\n";
    return 1;
  }
  po::notify(ai->vm);

  po::positional_options_description p;
  p.add("input-file", 1);

  po::store(po::command_line_parser(argc, argv).
            options(ai->desc).positional(p).run(), ai->vm);
  po::notify(ai->vm);
  return -1;
}

int EarlyExitArgs(const ArgInfo& ai) {
  // respond to command line args that don't run a simulation
  if (ai.vm.count("help")) {
    std::cout << usage << "\n\n"
              << ai.desc << "\n";
    return 0;
  } else if (ai.vm.count("version")) {
    std::cout << "Cyclus Core " << version::core()
              << " (" << version::describe() << ")"
              << "\n\nDependencies:\n";
    std::cout << "   Boost    " << version::boost() << "\n";
    std::cout << "   Coin-Cbc " << version::coincbc() << "\n";
    std::cout << "   Hdf5     " << version::hdf5() << "\n";
    std::cout << "   Sqlite3  " << version::sqlite3() << "\n";
    std::cout << "   xml2     " << version::xml2() << "\n";
    return 0;
  } else if (ai.vm.count("include")) {
    std::cout << Env::GetInstallPath() << "/include/cyclus/\n";
    return 0;
  } else if (ai.vm.count("schema")) {
    try {
      if (ai.flat_schema) {
        std::cout << "\n" << BuildFlatMasterSchema(ai.schema_path) << "\n";
      } else {
        std::cout << "\n" << BuildMasterSchema(ai.schema_path) << "\n";
      }
    } catch (cyclus::IOError err) {
      std::cout << err.what() << "\n";
      return 1;
    }
    return 0;
  } else if (ai.vm.count("module-schema")) {
    std::string name(ai.vm["module-schema"].as<std::string>());
    try {
      Recorder rec;
      Timer ti;
      Context* ctx = new Context(&ti, &rec);
      Model* m = DynamicModule::Make(ctx, name);
      std::cout << "<element name=\"" << name << "\">\n";
      std::cout << m->schema();
      std::cout << "</element>\n";
      ctx->DelModel(m);
    } catch (cyclus::IOError err) {
      std::cout << err.what() << "\n";
    }
    return 0;
  }
  return -1; // main should not return early
};

void GetSimInfo(ArgInfo* ai) {
  // schema info
  ai->schema_path = Env::GetInstallPath() + "/share/cyclus.rng.in";
  ai->flat_schema = false;
  if (ai->vm.count("flat-schema")) {
    ai->schema_path = Env::GetInstallPath() + "/share/cyclus-flat.rng.in";
    ai->flat_schema = true;
  }
  if (ai->vm.count("schema-path")) {
    ai->schema_path = ai->vm["schema-path"].as<std::string>();
  }

  // logging params
  if (ai->vm.count("no-model")) {
    Logger::NoModel() = true;
  }
  if (ai->vm.count("no-mem")) {
    Logger::NoMem() = true;
  }
  if (ai->vm.count("verb")) {
    std::string v_level = ai->vm["verb"].as<std::string>();
    if (v_level.length() < 3) {
      Logger::ReportLevel() = (LogLevel)strtol(v_level.c_str(), NULL, 10);
    } else {
      Logger::ReportLevel() = Logger::ToLogLevel(v_level);
    }
  }

  // output path
  ai->output_path = "cyclus.sqlite";
  if (ai->vm.count("output-path")) {
    ai->output_path = ai->vm["output-path"].as<std::string>();
  }
}

<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

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

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

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

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

// Qmitk
#include "QmitkDicomLocalStorageWidget.h"
//#include <mitkLogMacros.h>

// Qt
#include <QLabel>
#include <QProgressDialog>
#include <QVariant>
#include <QMessageBox>

const std::string QmitkDicomLocalStorageWidget::Widget_ID = "org.mitk.Widgets.QmitkDicomLocalStorageWidget";

QmitkDicomLocalStorageWidget::QmitkDicomLocalStorageWidget(QWidget *parent)
  : QWidget(parent)
  , m_Controls(0)
  , m_LocalIndexer(new ctkDICOMIndexer(parent))
{
    CreateQtPartControl(this);
}

QmitkDicomLocalStorageWidget::~QmitkDicomLocalStorageWidget()
{
    m_LocalDatabase->closeDatabase();
}

void QmitkDicomLocalStorageWidget::CreateQtPartControl( QWidget *parent )
{
    if ( !m_Controls )
    {
        m_Controls = new Ui::QmitkDicomLocalStorageWidgetControls;
        m_Controls->setupUi( parent );

        this->SetupProgressDialog(this);

        connect(m_Controls->deleteButton,SIGNAL(clicked()),this,SLOT(OnDeleteButtonClicked()));
        connect(m_Controls->viewInternalDataButton, SIGNAL(clicked()), this , SLOT(OnViewButtonClicked()));

        connect(m_Controls->ctkDicomBrowser, SIGNAL(seriesSelectionChanged(const QStringList&)),
                this, SLOT(OnSeriesSelectionChanged(const QStringList&)));
        connect(m_Controls->ctkDicomBrowser, SIGNAL(seriesSelectionChanged(const QStringList&)),
                this, SLOT(OnSeriesSelectionChanged(const QStringList&)));
        connect(m_Controls->ctkDicomBrowser, SIGNAL(seriesDoubleClicked(const QModelIndex&)),
                this, SLOT(OnViewButtonClicked()));

        connect(m_LocalIndexer, SIGNAL(indexingComplete()),this, SLOT(OnFinishedImport()));
        connect(m_LocalIndexer, SIGNAL(indexingComplete()),this, SIGNAL(SignalFinishedImport()));
        connect(m_LocalIndexer, SIGNAL(indexingComplete()),this, SLOT(OnFinishedImport()));
        connect(m_LocalIndexer, SIGNAL(indexingFilePath(const QString&)), m_ProgressDialogLabel, SLOT(setText(const QString&)));
        connect(m_LocalIndexer, SIGNAL(progress(int)), m_ProgressDialog, SLOT(setValue(int)));
        connect(m_ProgressDialog, SIGNAL(canceled()), m_LocalIndexer, SLOT(cancel()));

        m_Controls->ctkDicomBrowser->setTableOrientation(Qt::Vertical);
    }
}

void QmitkDicomLocalStorageWidget::OnStartDicomImport(const QString& dicomData)
{
    if(m_LocalDatabase->isOpen())
    {
        m_LocalIndexer->addDirectory(*m_LocalDatabase,dicomData,m_LocalDatabase->databaseDirectory());
    }
}

void QmitkDicomLocalStorageWidget::OnStartDicomImport(const QStringList& dicomData)
{
    if(m_LocalDatabase->isOpen())
    {
        m_ProgressDialog->show();
        m_LocalIndexer->addListOfFiles(*m_LocalDatabase,dicomData,m_LocalDatabase->databaseDirectory());
    }
}

void QmitkDicomLocalStorageWidget::OnFinishedImport()
{
    m_ProgressDialog->setValue(m_ProgressDialog->maximum());
}

void QmitkDicomLocalStorageWidget::OnDeleteButtonClicked()
{
  if (!this->DeletePatients())
  {
    if (!this->DeleteStudies())
    {
      this->DeleteSeries();
    }
  }

  m_Controls->ctkDicomBrowser->updateTableViews();
}

bool QmitkDicomLocalStorageWidget::DeletePatients()
{
  auto selectedPatientUIDs = m_Controls->ctkDicomBrowser->currentPatientsSelection();

  if (!selectedPatientUIDs.empty())
  {
    QStringList studyUIDs;

    for (const auto& patientUID : selectedPatientUIDs)
      studyUIDs.append(m_LocalDatabase->studiesForPatient(patientUID));

    QStringList seriesUIDs;

    for (const auto& studyUID : studyUIDs)
      seriesUIDs.append(m_LocalDatabase->seriesForStudy(studyUID));

    auto answer = QMessageBox::question(nullptr, "Delete Patients",
      QString("Do you really want to delete %1 %2, containing %3 series in %4 %5?")
        .arg(selectedPatientUIDs.count())
        .arg(selectedPatientUIDs.count() != 1 ? "patients" : "patient")
        .arg(seriesUIDs.count())
        .arg(studyUIDs.count())
        .arg(studyUIDs.count() != 1 ? "studies" : "study"));

    if (answer == QMessageBox::Yes)
    {
      for (const auto& patientUID : selectedPatientUIDs)
        m_LocalDatabase->removePatient(patientUID);
    }

    return true;
  }

  return false;
}

bool QmitkDicomLocalStorageWidget::DeleteStudies()
{
  auto selectedStudyUIDs = m_Controls->ctkDicomBrowser->currentStudiesSelection();

  if (!selectedStudyUIDs.empty())
  {
    QStringList seriesUIDs;

    for (const auto& studyUID : selectedStudyUIDs)
      seriesUIDs.append(m_LocalDatabase->seriesForStudy(studyUID));

    auto answer = QMessageBox::question(nullptr, "Delete Studies",
      QString("Do you really want to delete %1 %2, containing %3 series?")
        .arg(selectedStudyUIDs.count())
        .arg(selectedStudyUIDs.count() != 1 ? "studies" : "study")
        .arg(seriesUIDs.count()));

    if (answer == QMessageBox::Yes)
    {
      for (const auto& studyUID : selectedStudyUIDs)
        m_LocalDatabase->removeStudy(studyUID);
    }

    return true;
  }

  return false;
}

bool QmitkDicomLocalStorageWidget::DeleteSeries()
{
  auto selectedSeriesUIDs = m_Controls->ctkDicomBrowser->currentSeriesSelection();

  if (!selectedSeriesUIDs.empty())
  {
    auto answer = QMessageBox::question(nullptr, "Delete Series",
      QString("Do you really want to delete %1 series?")
        .arg(selectedSeriesUIDs.count()));

    if (answer == QMessageBox::Yes)
    {
      for (const auto& seriesUID : selectedSeriesUIDs)
        m_LocalDatabase->removeSeries(seriesUID);
    }

    return true;
  }

  return false;
}

void QmitkDicomLocalStorageWidget::OnViewButtonClicked()
{
  QStringList uids = m_Controls->ctkDicomBrowser->currentSeriesSelection();
  QString uid;
  foreach (uid, uids)
  {
    QStringList filesForSeries = m_LocalDatabase->filesForSeries(uid);
    QHash<QString, QVariant> eventProperty;
    eventProperty.insert("FilesForSeries", filesForSeries);
    emit SignalDicomToDataManager(eventProperty);
  }
}

void QmitkDicomLocalStorageWidget::SetDatabaseDirectory(QString newDatatbaseDirectory)
{
    QDir databaseDirecory = QDir(newDatatbaseDirectory);
    if(!databaseDirecory.exists())
    {
        databaseDirecory.mkpath(databaseDirecory.absolutePath());
    }
    QString newDatatbaseFile = databaseDirecory.absolutePath() + QString("/ctkDICOM.sql");
    this->SetDatabase(newDatatbaseFile);
}

void QmitkDicomLocalStorageWidget::SetDatabase(QString databaseFile)
{
    m_LocalDatabase = new ctkDICOMDatabase(databaseFile);
    m_LocalDatabase->setParent(this);
    m_Controls->ctkDicomBrowser->setDICOMDatabase(m_LocalDatabase);
}

void QmitkDicomLocalStorageWidget::OnSeriesSelectionChanged(const QStringList &s)
{
  m_Controls->viewInternalDataButton->setEnabled((s.size() != 0));
}

void QmitkDicomLocalStorageWidget::SetupProgressDialog(QWidget* parent)
{
    m_ProgressDialog = new QProgressDialog("DICOM Import", "Cancel", 0, 100, parent,Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
    m_ProgressDialogLabel = new QLabel("Initialization...", m_ProgressDialog);
    m_ProgressDialog->setLabel(m_ProgressDialogLabel);
    m_ProgressDialog->setWindowModality(Qt::ApplicationModal);
    m_ProgressDialog->setMinimumDuration(0);
}
<commit_msg>Fixed wrong QMessageBox return type check<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

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

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

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

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

// Qmitk
#include "QmitkDicomLocalStorageWidget.h"
//#include <mitkLogMacros.h>

// Qt
#include <QLabel>
#include <QProgressDialog>
#include <QVariant>
#include <QMessageBox>

const std::string QmitkDicomLocalStorageWidget::Widget_ID = "org.mitk.Widgets.QmitkDicomLocalStorageWidget";

QmitkDicomLocalStorageWidget::QmitkDicomLocalStorageWidget(QWidget *parent)
  : QWidget(parent)
  , m_Controls(0)
  , m_LocalIndexer(new ctkDICOMIndexer(parent))
{
    CreateQtPartControl(this);
}

QmitkDicomLocalStorageWidget::~QmitkDicomLocalStorageWidget()
{
    m_LocalDatabase->closeDatabase();
}

void QmitkDicomLocalStorageWidget::CreateQtPartControl( QWidget *parent )
{
    if ( !m_Controls )
    {
        m_Controls = new Ui::QmitkDicomLocalStorageWidgetControls;
        m_Controls->setupUi( parent );

        this->SetupProgressDialog(this);

        connect(m_Controls->deleteButton,SIGNAL(clicked()),this,SLOT(OnDeleteButtonClicked()));
        connect(m_Controls->viewInternalDataButton, SIGNAL(clicked()), this , SLOT(OnViewButtonClicked()));

        connect(m_Controls->ctkDicomBrowser, SIGNAL(seriesSelectionChanged(const QStringList&)),
                this, SLOT(OnSeriesSelectionChanged(const QStringList&)));
        connect(m_Controls->ctkDicomBrowser, SIGNAL(seriesSelectionChanged(const QStringList&)),
                this, SLOT(OnSeriesSelectionChanged(const QStringList&)));
        connect(m_Controls->ctkDicomBrowser, SIGNAL(seriesDoubleClicked(const QModelIndex&)),
                this, SLOT(OnViewButtonClicked()));

        connect(m_LocalIndexer, SIGNAL(indexingComplete()),this, SLOT(OnFinishedImport()));
        connect(m_LocalIndexer, SIGNAL(indexingComplete()),this, SIGNAL(SignalFinishedImport()));
        connect(m_LocalIndexer, SIGNAL(indexingComplete()),this, SLOT(OnFinishedImport()));
        connect(m_LocalIndexer, SIGNAL(indexingFilePath(const QString&)), m_ProgressDialogLabel, SLOT(setText(const QString&)));
        connect(m_LocalIndexer, SIGNAL(progress(int)), m_ProgressDialog, SLOT(setValue(int)));
        connect(m_ProgressDialog, SIGNAL(canceled()), m_LocalIndexer, SLOT(cancel()));

        m_Controls->ctkDicomBrowser->setTableOrientation(Qt::Vertical);
    }
}

void QmitkDicomLocalStorageWidget::OnStartDicomImport(const QString& dicomData)
{
    if(m_LocalDatabase->isOpen())
    {
        m_LocalIndexer->addDirectory(*m_LocalDatabase,dicomData,m_LocalDatabase->databaseDirectory());
    }
}

void QmitkDicomLocalStorageWidget::OnStartDicomImport(const QStringList& dicomData)
{
    if(m_LocalDatabase->isOpen())
    {
        m_ProgressDialog->show();
        m_LocalIndexer->addListOfFiles(*m_LocalDatabase,dicomData,m_LocalDatabase->databaseDirectory());
    }
}

void QmitkDicomLocalStorageWidget::OnFinishedImport()
{
    m_ProgressDialog->setValue(m_ProgressDialog->maximum());
}

void QmitkDicomLocalStorageWidget::OnDeleteButtonClicked()
{
  if (!this->DeletePatients())
  {
    if (!this->DeleteStudies())
    {
      this->DeleteSeries();
    }
  }

  m_Controls->ctkDicomBrowser->updateTableViews();
}

bool QmitkDicomLocalStorageWidget::DeletePatients()
{
  auto selectedPatientUIDs = m_Controls->ctkDicomBrowser->currentPatientsSelection();

  if (!selectedPatientUIDs.empty())
  {
    QStringList studyUIDs;

    for (const auto& patientUID : selectedPatientUIDs)
      studyUIDs.append(m_LocalDatabase->studiesForPatient(patientUID));

    QStringList seriesUIDs;

    for (const auto& studyUID : studyUIDs)
      seriesUIDs.append(m_LocalDatabase->seriesForStudy(studyUID));

    auto answer = QMessageBox::question(nullptr, "Delete Patients",
      QString("Do you really want to delete %1 %2, containing %3 series in %4 %5?")
        .arg(selectedPatientUIDs.count())
        .arg(selectedPatientUIDs.count() != 1 ? "patients" : "patient")
        .arg(seriesUIDs.count())
        .arg(studyUIDs.count())
        .arg(studyUIDs.count() != 1 ? "studies" : "study"));

    if (answer == QMessageBox::Ok)
    {
      for (const auto& patientUID : selectedPatientUIDs)
        m_LocalDatabase->removePatient(patientUID);
    }

    return true;
  }

  return false;
}

bool QmitkDicomLocalStorageWidget::DeleteStudies()
{
  auto selectedStudyUIDs = m_Controls->ctkDicomBrowser->currentStudiesSelection();

  if (!selectedStudyUIDs.empty())
  {
    QStringList seriesUIDs;

    for (const auto& studyUID : selectedStudyUIDs)
      seriesUIDs.append(m_LocalDatabase->seriesForStudy(studyUID));

    auto answer = QMessageBox::question(nullptr, "Delete Studies",
      QString("Do you really want to delete %1 %2, containing %3 series?")
        .arg(selectedStudyUIDs.count())
        .arg(selectedStudyUIDs.count() != 1 ? "studies" : "study")
        .arg(seriesUIDs.count()));

    if (answer == QMessageBox::Ok)
    {
      for (const auto& studyUID : selectedStudyUIDs)
        m_LocalDatabase->removeStudy(studyUID);
    }

    return true;
  }

  return false;
}

bool QmitkDicomLocalStorageWidget::DeleteSeries()
{
  auto selectedSeriesUIDs = m_Controls->ctkDicomBrowser->currentSeriesSelection();

  if (!selectedSeriesUIDs.empty())
  {
    auto answer = QMessageBox::question(nullptr, "Delete Series",
      QString("Do you really want to delete %1 series?")
        .arg(selectedSeriesUIDs.count()));

    if (answer == QMessageBox::Ok)
    {
      for (const auto& seriesUID : selectedSeriesUIDs)
        m_LocalDatabase->removeSeries(seriesUID);
    }

    return true;
  }

  return false;
}

void QmitkDicomLocalStorageWidget::OnViewButtonClicked()
{
  QStringList uids = m_Controls->ctkDicomBrowser->currentSeriesSelection();
  QString uid;
  foreach (uid, uids)
  {
    QStringList filesForSeries = m_LocalDatabase->filesForSeries(uid);
    QHash<QString, QVariant> eventProperty;
    eventProperty.insert("FilesForSeries", filesForSeries);
    emit SignalDicomToDataManager(eventProperty);
  }
}

void QmitkDicomLocalStorageWidget::SetDatabaseDirectory(QString newDatatbaseDirectory)
{
    QDir databaseDirecory = QDir(newDatatbaseDirectory);
    if(!databaseDirecory.exists())
    {
        databaseDirecory.mkpath(databaseDirecory.absolutePath());
    }
    QString newDatatbaseFile = databaseDirecory.absolutePath() + QString("/ctkDICOM.sql");
    this->SetDatabase(newDatatbaseFile);
}

void QmitkDicomLocalStorageWidget::SetDatabase(QString databaseFile)
{
    m_LocalDatabase = new ctkDICOMDatabase(databaseFile);
    m_LocalDatabase->setParent(this);
    m_Controls->ctkDicomBrowser->setDICOMDatabase(m_LocalDatabase);
}

void QmitkDicomLocalStorageWidget::OnSeriesSelectionChanged(const QStringList &s)
{
  m_Controls->viewInternalDataButton->setEnabled((s.size() != 0));
}

void QmitkDicomLocalStorageWidget::SetupProgressDialog(QWidget* parent)
{
    m_ProgressDialog = new QProgressDialog("DICOM Import", "Cancel", 0, 100, parent,Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
    m_ProgressDialogLabel = new QLabel("Initialization...", m_ProgressDialog);
    m_ProgressDialog->setLabel(m_ProgressDialogLabel);
    m_ProgressDialog->setWindowModality(Qt::ApplicationModal);
    m_ProgressDialog->setMinimumDuration(0);
}
<|endoftext|>