<commit_before>#include "tmath.hpp"
#include <sstream>

/* ================================ SINE ======================================== */
TMath::DOUBLE TMath::sin(DOUBLE x)
{
	x = mod(x + PI, 2 * PI) - PI;
	DOUBLE r = 0;
	for (LONG n = 0; n <= 8L; n++) {
		r += pow(DOUBLE(-1), n) * pow(x, 2 * n + 1) / fac(2 * n + 1);
	}
	return r;
}
TMath::DOUBLE TMath::asin(DOUBLE x)
{
	DOUBLE r = 0;
	DOUBLE delta = 1;
	for (LONG n = 1; delta > 1e-6; n++)
	{
		LONG odd = 2 * n - 1;
		DOUBLE oddf = oddfacd(odd - 2);
		DOUBLE f = facd(odd);
		DOUBLE p = pow(x, odd);
		DOUBLE d = p / f * oddf * oddf;
		delta = abs(d);
		r += p / f * oddf * oddf;
	}
	return r;
}
TMath::DOUBLE TMath::sinh(DOUBLE x)
{
	return 0.5 * (exp(x) - exp(-x));
}
/* ================================ COSINE ======================================== */
TMath::DOUBLE TMath::cos(DOUBLE x)
{
	x = mod(x + PI, 2 * PI) - PI;
	DOUBLE r = 0;
	for (LONG n = 0; n <= 8L; n++) {
		r += pow(DOUBLE(-1.0), n) * pow(x, 2 * n) / fac(2 * n);
	}
	return r;
}
TMath::DOUBLE TMath::acos(DOUBLE x)
{
	return PI / 2 - asin(x);
}
TMath::DOUBLE TMath::cosh(DOUBLE x)
{
	return 0.5 * (exp(x) + exp(-x));
}
/* ================================ TANGENT ======================================== */
TMath::DOUBLE TMath::tan(DOUBLE x)
{
	return sin(x) / cos(x);
}
TMath::DOUBLE TMath::atan(DOUBLE x)
{
	DOUBLE r = 0;
	DOUBLE delta = 1;
	for (LONG n = 0; delta > 1e-4; n++)
	{
		LONG odd = 2 * n + 1;
		DOUBLE d = DOUBLE(pow(-1LL, n)) * pow(x, odd) / DOUBLE(odd);
		delta = abs(d);
		r += d;
	}
	return r;
}
TMath::DOUBLE TMath::tanh(DOUBLE x)
{
	return sinh(x) / cosh(x);
}
/* ================================ COTANGENT ======================================== */
TMath::DOUBLE TMath::cot(DOUBLE x)
{
	return cos(x) / sin(x);
}
TMath::DOUBLE TMath::acot(DOUBLE x)
{
	return PI / 2 - atan(x);
}
TMath::DOUBLE TMath::coth(DOUBLE x)
{
	return cosh(x) / sinh(x);
}
/* ================================ SECANT ======================================== */
TMath::DOUBLE TMath::sec(DOUBLE x)
{
	return 1 / cos(x);
}
TMath::DOUBLE TMath::asec(DOUBLE x)
{
	return acos(1 / x);
}
TMath::DOUBLE TMath::sech(DOUBLE x)
{
	return 1 / cosh(x);
}
/* ================================ COSECANT ======================================== */
TMath::DOUBLE TMath::csc(DOUBLE x)
{
	return 1 / sin(x);
}
TMath::DOUBLE TMath::acsc(DOUBLE x)
{
	return asin(1 / x);
}
TMath::DOUBLE TMath::csch(DOUBLE x)
{
	return 1 / sinh(x);
}
/* ================================= FLOOR, CEIL AND MODULO ======================================== */
TMath::LONG TMath::floor(DOUBLE x)
{
	LONG truncated = LONG(x);
	if (x < 0) {
		if (truncated > x) {
			return truncated - 1;
		} else {
			return truncated;
		}
	}
	else {
		return truncated;
	}
}
TMath::LONG TMath::ceil(DOUBLE x)
{
	LONG truncated = LONG(x);
	if (x < 0) {
		return truncated;
	} else {
		return truncated + 1;
	}
}
TMath::DOUBLE TMath::mod(DOUBLE x, DOUBLE y)
{
	return y * ((x / y) - floor(x / y));
}
/* =============================== EXPONENTIAL FUNCTION, SQRT, LOGARITHM ======================= */
TMath::DOUBLE TMath::exp(DOUBLE x)
{
	DOUBLE r = 0;
	for (LONG n = 0; n <= 15L; n++)
	{
		r += pow(x, n) / facd(n);
	}
	return r;
}
TMath::DOUBLE TMath::sqrt(DOUBLE x)
{
	return root(x, 2);
}
TMath::DOUBLE TMath::root(DOUBLE x, DOUBLE n)
{
	return pow(x, 1 / n);
}
TMath::DOUBLE TMath::ln(DOUBLE x)
{
	x = (x - 1) / (x + 1);
	DOUBLE r = 0;
	for (LONG n = 0; n <= 100L; n++)
	{
		r += 2 * pow(x, 2 * n + 1) / (2 * n + 1);
	}
	return r;
}
TMath::DOUBLE TMath::lg(DOUBLE x)
{
	return ln(x) / ln(10);
}
TMath::DOUBLE TMath::lb(DOUBLE x)
{
	return ln(x) / ln(2);
}
TMath::DOUBLE TMath::log(DOUBLE x, DOUBLE n)
{
	return ln(x) / ln(n);
}
/* =================================== POWER FUNCTIONS =====================================================*/
TMath::DOUBLE TMath::pow(DOUBLE x, LONG n)
{
	if (n < 0) {
		return 1 / pow(x, -n);
	}

	DOUBLE r = 1;
	for (LONG i = 1; i <= n; i++)
	{
		r *= x;
	}
	return r;
}

TMath::LONG TMath::pow(LONG x, LONG n)
{
	if (n < 0) {
		return 1 / pow(x, -n);
	}

	LONG r = 1;
	for (LONG i = 1; i <= n; i++)
	{
		r *= x;
	}
	return r;
}
TMath::DOUBLE TMath::pow(DOUBLE x, DOUBLE n)
{
	return exp(n * ln(x));
}
/* ========================================== FACULTY ============================================*/
TMath::LONG TMath::fac(LONG n) {
	LONG r = 1;
	for (LONG i = 2; i <= n; i++)
	{
		r *= i;
	}
	return r;
}
TMath::DOUBLE TMath::facd(LONG n) {
	DOUBLE r = 1;
	for (LONG i = 2; i <= n; i++) {
		r *= DOUBLE(i);
	}
	return r;
}
TMath::LONG TMath::oddfac(LONG n) {
	LONG r = 1;
	for (LONG i = 3; i <= n; i += 2) {
		r *= i;
	}
	return r;
}
TMath::DOUBLE TMath::oddfacd(LONG n) {
	DOUBLE r = 1;
	for (LONG i = 3; i <= n; i += 2) {
		r *= DOUBLE(i);
	}
	return r;
}
TMath::DOUBLE TMath::abs(DOUBLE x) {
	if (x < 0) return -x;
	else return x;
}

/* ====================================== COMPARISONS ==========*/
TMath::DOUBLE TMath::equal(DOUBLE x, DOUBLE y) {
	return equal(x, y, EQUAL_EPSILON);
}
TMath::DOUBLE TMath::equal(DOUBLE x, DOUBLE y, DOUBLE eps) {
	return abs(x - y) < eps;
}

/* ========================================== DEGREE / RADIANT CONVERSION ================================*/
TMath::DOUBLE TMath::rad(DOUBLE deg)
{
	return PI / 180 * deg;
}
TMath::DOUBLE TMath::deg(DOUBLE rad)
{
	return 180 / PI * rad;
}
/* ======================================== VECTOR IMPLEMENTATIONS =====================================*/

// checkDimensions check if the dimensions of the vectors are equal.
int TMath::Vector::checkDimensions(const Vector &a) const {
	int mdim = dim();
	if (mdim != a.dim()) throw TMath::DIMENSION_ERROR;
	return mdim;
}

// [n] operator accesses the n-th element of the vector
TMath::DOUBLE& TMath::Vector::operator[](const int &i) {
	return elements.at(i);
};

// + operator sums up two vectors.
// result = this + a
TMath::Vector TMath::Vector::operator+(const Vector &a) const {
	int d = checkDimensions(a);
	Vector b(d);
	for (unsigned int i = 0; i < d; i++) {
		b[i] = elements.at(i) + a.elements.at(i);
	}
	return b;
};

// - operator calculates the difference vector of the two vectors.
// result = this - a
TMath::Vector TMath::Vector::operator-(const Vector &a) const {
	int d = checkDimensions(a);
	Vector b(d);
	for (unsigned int i = 0; i < d; i++) {
		b[i] = elements.at(i) - a.elements.at(i);
	}
	return b;
};

// - operator calculates the inversion of the vector.
TMath::Vector TMath::Vector::operator-() const {
	int d = dim();
	Vector b(d);
	for (unsigned int i = 0; i < d; i++) {
		b[i] = -elements.at(i);
	}
	return b;
}

// * operator scales the vector by the scalar.
TMath::Vector TMath::Vector::operator*(const DOUBLE &scalar) const {
	int d = dim();
	Vector b(d);
	for (unsigned int i = 0; i < d; i++) {
		b[i] = elements.at(i) * scalar;
	}
	return b;
};

// / operator scales the vector by the inverse value of the scalar.
TMath::Vector TMath::Vector::operator/(const DOUBLE &scalar) const {
	int d = dim();
	Vector b(d);
	for (unsigned int i = 0; i < d; i++) {
		b[i] = elements.at(i) / scalar;
	}
	return b;
};

// equal checks for equality of both vectors.
bool TMath::Vector::equal(const Vector &a, const DOUBLE &eps) const {
	int d = checkDimensions(a);
	for (unsigned int i = 0; i < d; i++) {
		if (!TMath::equal(elements.at(i), a.elements.at(i), eps)) return false;
	}
	return true;
};

// == operator checks for equality with a constant accuracy of EQUAL_EPSILON.
bool TMath::Vector::operator==(const Vector &a) const {
	int d = checkDimensions(a);
	return this->equal(a, EQUAL_EPSILON);
};

// != operator checks for inequality.
bool TMath::Vector::operator!=(const Vector &a) const {
	int d = checkDimensions(a);
	return !this->equal(a, EQUAL_EPSILON);
};

// dot operator calculates the dot product of the two vectors.
TMath::DOUBLE TMath::Vector::dot(const Vector &a) const {
	int d = checkDimensions(a);
	Vector b(d);
	DOUBLE sum = 0;
	for (unsigned int i = 0; i < d; i++) sum += elements.at(i) * a.elements.at(i);
	return sum;
};

// cross operator calculates the cross product of the two vectors.
TMath::Vector TMath::Vector::cross(const Vector &a) const {
	int d = checkDimensions(a);
	if (d != 3) throw BAD_OPERATION;
	Vector b(3);
	for (unsigned int i = 0; i < 3; i++) {
		unsigned int p = (i+1) % 3, q = (i+2) % 3;
		b[i] = elements.at(i) * a.elements.at(q) - elements.at(q) * a.elements.at(p);
	}
	return b;
};

// sum operator calculates the element sum of the vector.
TMath::DOUBLE TMath::Vector::sum() const {
	int d = dim();
	DOUBLE sum = 0;
	for (unsigned int i = 0; i < d; i++) sum += elements[i];
	return sum;
};

// norm operator calculates a normalized vector.
TMath::Vector TMath::Vector::norm() const {
	int d = dim();
	if (d == 0) throw BAD_OPERATION;
	DOUBLE l = length();
	Vector b(d);
	for (unsigned int i = 0; i < d; i++) b[i] = elements[i] / l;
	return b;
}

// length operator calculates the length of the vector.
TMath::DOUBLE TMath::Vector::length() const {
	int d = dim();
	if (d == 0) throw BAD_OPERATION;
	DOUBLE sum = 0;
	for (unsigned int i = 0; i < d; i++) sum += elements[i] * elements[i];
	return TMath::sqrt(sum);
}

// dim returns the vector tuple size.
int TMath::Vector::dim() const {
	return elements.size();
}

// to_string returns a string representation of the vector.
std::string TMath::Vector::to_string() const {
	std::stringstream stream;
	stream << "{";
	int d = dim();
	for (unsigned int i = 0; i < d - 1; i++) stream << elements[i] << ", ";
	if (d > 0) stream << elements[d-1];
	stream << "}";
	return stream.str();
}
<commit_msg>fix: minimize function overhead<commit_after>#include "tmath.hpp"
#include <sstream>

/* ================================ SINE ======================================== */
TMath::DOUBLE TMath::sin(DOUBLE x)
{
	x = mod(x + PI, 2 * PI) - PI;
	DOUBLE r = 0;
	for (LONG n = 0; n <= 8L; n++) {
		r += pow(DOUBLE(-1), n) * pow(x, 2 * n + 1) / fac(2 * n + 1);
	}
	return r;
}
TMath::DOUBLE TMath::asin(DOUBLE x)
{
	DOUBLE r = 0;
	DOUBLE delta = 1;
	for (LONG n = 1; delta > 1e-6; n++)
	{
		LONG odd = 2 * n - 1;
		DOUBLE oddf = oddfacd(odd - 2);
		DOUBLE f = facd(odd);
		DOUBLE p = pow(x, odd);
		DOUBLE d = p / f * oddf * oddf;
		delta = abs(d);
		r += p / f * oddf * oddf;
	}
	return r;
}
TMath::DOUBLE TMath::sinh(DOUBLE x)
{
	return 0.5 * (exp(x) - exp(-x));
}
/* ================================ COSINE ======================================== */
TMath::DOUBLE TMath::cos(DOUBLE x)
{
	x = mod(x + PI, 2 * PI) - PI;
	DOUBLE r = 0;
	for (LONG n = 0; n <= 8L; n++) {
		r += pow(DOUBLE(-1.0), n) * pow(x, 2 * n) / fac(2 * n);
	}
	return r;
}
TMath::DOUBLE TMath::acos(DOUBLE x)
{
	return PI / 2 - asin(x);
}
TMath::DOUBLE TMath::cosh(DOUBLE x)
{
	return 0.5 * (exp(x) + exp(-x));
}
/* ================================ TANGENT ======================================== */
TMath::DOUBLE TMath::tan(DOUBLE x)
{
	return sin(x) / cos(x);
}
TMath::DOUBLE TMath::atan(DOUBLE x)
{
	DOUBLE r = 0;
	DOUBLE delta = 1;
	for (LONG n = 0; delta > 1e-4; n++)
	{
		LONG odd = 2 * n + 1;
		DOUBLE d = DOUBLE(pow(-1LL, n)) * pow(x, odd) / DOUBLE(odd);
		delta = abs(d);
		r += d;
	}
	return r;
}
TMath::DOUBLE TMath::tanh(DOUBLE x)
{
	return sinh(x) / cosh(x);
}
/* ================================ COTANGENT ======================================== */
TMath::DOUBLE TMath::cot(DOUBLE x)
{
	return cos(x) / sin(x);
}
TMath::DOUBLE TMath::acot(DOUBLE x)
{
	return PI / 2 - atan(x);
}
TMath::DOUBLE TMath::coth(DOUBLE x)
{
	return cosh(x) / sinh(x);
}
/* ================================ SECANT ======================================== */
TMath::DOUBLE TMath::sec(DOUBLE x)
{
	return 1 / cos(x);
}
TMath::DOUBLE TMath::asec(DOUBLE x)
{
	return acos(1 / x);
}
TMath::DOUBLE TMath::sech(DOUBLE x)
{
	return 1 / cosh(x);
}
/* ================================ COSECANT ======================================== */
TMath::DOUBLE TMath::csc(DOUBLE x)
{
	return 1 / sin(x);
}
TMath::DOUBLE TMath::acsc(DOUBLE x)
{
	return asin(1 / x);
}
TMath::DOUBLE TMath::csch(DOUBLE x)
{
	return 1 / sinh(x);
}
/* ================================= FLOOR, CEIL AND MODULO ======================================== */
TMath::LONG TMath::floor(DOUBLE x)
{
	LONG truncated = LONG(x);
	if (x < 0) {
		if (truncated > x) {
			return truncated - 1;
		} else {
			return truncated;
		}
	}
	else {
		return truncated;
	}
}
TMath::LONG TMath::ceil(DOUBLE x)
{
	LONG truncated = LONG(x);
	if (x < 0) {
		return truncated;
	} else {
		return truncated + 1;
	}
}
TMath::DOUBLE TMath::mod(DOUBLE x, DOUBLE y)
{
	return y * ((x / y) - floor(x / y));
}
/* =============================== EXPONENTIAL FUNCTION, SQRT, LOGARITHM ======================= */
TMath::DOUBLE TMath::exp(DOUBLE x)
{
	DOUBLE r = 0;
	for (LONG n = 0; n <= 15L; n++)
	{
		r += pow(x, n) / facd(n);
	}
	return r;
}
TMath::DOUBLE TMath::sqrt(DOUBLE x)
{
	return root(x, 2);
}
TMath::DOUBLE TMath::root(DOUBLE x, DOUBLE n)
{
	return pow(x, 1 / n);
}
TMath::DOUBLE TMath::ln(DOUBLE x)
{
	x = (x - 1) / (x + 1);
	DOUBLE r = 0;
	for (LONG n = 0; n <= 100L; n++)
	{
		r += 2 * pow(x, 2 * n + 1) / (2 * n + 1);
	}
	return r;
}
TMath::DOUBLE TMath::lg(DOUBLE x)
{
	return ln(x) / ln(10);
}
TMath::DOUBLE TMath::lb(DOUBLE x)
{
	return ln(x) / ln(2);
}
TMath::DOUBLE TMath::log(DOUBLE x, DOUBLE n)
{
	return ln(x) / ln(n);
}
/* =================================== POWER FUNCTIONS =====================================================*/
TMath::DOUBLE TMath::pow(DOUBLE x, LONG n)
{
	if (n < 0) {
		return 1 / pow(x, -n);
	}

	DOUBLE r = 1;
	for (LONG i = 1; i <= n; i++)
	{
		r *= x;
	}
	return r;
}

TMath::LONG TMath::pow(LONG x, LONG n)
{
	if (n < 0) {
		return 1 / pow(x, -n);
	}

	LONG r = 1;
	for (LONG i = 1; i <= n; i++)
	{
		r *= x;
	}
	return r;
}
TMath::DOUBLE TMath::pow(DOUBLE x, DOUBLE n)
{
	return exp(n * ln(x));
}
/* ========================================== FACULTY ============================================*/
TMath::LONG TMath::fac(LONG n) {
	LONG r = 1;
	for (LONG i = 2; i <= n; i++)
	{
		r *= i;
	}
	return r;
}
TMath::DOUBLE TMath::facd(LONG n) {
	DOUBLE r = 1;
	for (LONG i = 2; i <= n; i++) {
		r *= DOUBLE(i);
	}
	return r;
}
TMath::LONG TMath::oddfac(LONG n) {
	LONG r = 1;
	for (LONG i = 3; i <= n; i += 2) {
		r *= i;
	}
	return r;
}
TMath::DOUBLE TMath::oddfacd(LONG n) {
	DOUBLE r = 1;
	for (LONG i = 3; i <= n; i += 2) {
		r *= DOUBLE(i);
	}
	return r;
}
TMath::DOUBLE TMath::abs(DOUBLE x) {
	if (x < 0) return -x;
	else return x;
}

/* ====================================== COMPARISONS ==========*/
TMath::DOUBLE TMath::equal(DOUBLE x, DOUBLE y) {
	return equal(x, y, EQUAL_EPSILON);
}
TMath::DOUBLE TMath::equal(DOUBLE x, DOUBLE y, DOUBLE eps) {
	return abs(x - y) < eps;
}

/* ========================================== DEGREE / RADIANT CONVERSION ================================*/
TMath::DOUBLE TMath::rad(DOUBLE deg)
{
	return PI / 180 * deg;
}
TMath::DOUBLE TMath::deg(DOUBLE rad)
{
	return 180 / PI * rad;
}
/* ======================================== VECTOR IMPLEMENTATIONS =====================================*/

// checkDimensions check if the dimensions of the vectors are equal.
int TMath::Vector::checkDimensions(const Vector &a) const {
	int mdim = dim();
	if (mdim != a.dim()) throw TMath::DIMENSION_ERROR;
	return mdim;
}

// [n] operator accesses the n-th element of the vector
TMath::DOUBLE& TMath::Vector::operator[](const int &i) {
	return elements.at(i);
};

// + operator sums up two vectors.
// result = this + a
TMath::Vector TMath::Vector::operator+(const Vector &a) const {
	int d = checkDimensions(a);
	Vector b(d);
	for (unsigned int i = 0; i < d; i++) {
		b[i] = elements.at(i) + a.elements.at(i);
	}
	return b;
};

// - operator calculates the difference vector of the two vectors.
// result = this - a
TMath::Vector TMath::Vector::operator-(const Vector &a) const {
	int d = checkDimensions(a);
	Vector b(d);
	for (unsigned int i = 0; i < d; i++) {
		b[i] = elements.at(i) - a.elements.at(i);
	}
	return b;
};

// - operator calculates the inversion of the vector.
TMath::Vector TMath::Vector::operator-() const {
	int d = dim();
	Vector b(d);
	for (unsigned int i = 0; i < d; i++) {
		b[i] = -elements.at(i);
	}
	return b;
}

// * operator scales the vector by the scalar.
TMath::Vector TMath::Vector::operator*(const DOUBLE &scalar) const {
	int d = dim();
	Vector b(d);
	for (unsigned int i = 0; i < d; i++) {
		b[i] = elements.at(i) * scalar;
	}
	return b;
};

// / operator scales the vector by the inverse value of the scalar.
TMath::Vector TMath::Vector::operator/(const DOUBLE &scalar) const {
	int d = dim();
	Vector b(d);
	for (unsigned int i = 0; i < d; i++) {
		b[i] = elements.at(i) / scalar;
	}
	return b;
};

// equal checks for equality of both vectors.
bool TMath::Vector::equal(const Vector &a, const DOUBLE &eps) const {
	int d = checkDimensions(a);
	for (unsigned int i = 0; i < d; i++) {
		if (!TMath::equal(elements.at(i), a.elements.at(i), eps)) return false;
	}
	return true;
};

// == operator checks for equality with a constant accuracy of EQUAL_EPSILON.
bool TMath::Vector::operator==(const Vector &a) const {
	int d = checkDimensions(a);
	return this->equal(a, EQUAL_EPSILON);
};

// != operator checks for inequality.
bool TMath::Vector::operator!=(const Vector &a) const {
	int d = checkDimensions(a);
	return !this->equal(a, EQUAL_EPSILON);
};

// dot operator calculates the dot product of the two vectors.
TMath::DOUBLE TMath::Vector::dot(const Vector &a) const {
	int d = checkDimensions(a);
	Vector b(d);
	DOUBLE sum = 0;
	for (unsigned int i = 0; i < d; i++) sum += elements.at(i) * a.elements.at(i);
	return sum;
};

// cross operator calculates the cross product of the two vectors.
TMath::Vector TMath::Vector::cross(const Vector &a) const {
	int d = checkDimensions(a);
	if (d != 3) throw BAD_OPERATION;
	Vector b(3);
	for (unsigned int i = 0; i < 3; i++) {
		unsigned int p = (i+1) % 3, q = (i+2) % 3;
		b[i] = elements.at(i) * a.elements.at(q) - elements.at(q) * a.elements.at(p);
	}
	return b;
};

// sum operator calculates the element sum of the vector.
TMath::DOUBLE TMath::Vector::sum() const {
	int d = dim();
	DOUBLE sum = 0;
	for (unsigned int i = 0; i < d; i++) sum += elements[i];
	return sum;
};

// norm operator calculates a normalized vector.
TMath::Vector TMath::Vector::norm() const {
	int d = dim();
	if (d == 0) throw BAD_OPERATION;
	return *this / length();
}

// length operator calculates the length of the vector.
TMath::DOUBLE TMath::Vector::length() const {
	int d = dim();
	if (d == 0) throw BAD_OPERATION;
	DOUBLE sum = 0;
	for (unsigned int i = 0; i < d; i++) sum += elements[i] * elements[i];
	return TMath::sqrt(sum);
}

// dim returns the vector tuple size.
int TMath::Vector::dim() const {
	return elements.size();
}

// to_string returns a string representation of the vector.
std::string TMath::Vector::to_string() const {
	std::stringstream stream;
	stream << "{";
	int d = dim();
	for (unsigned int i = 0; i < d - 1; i++) stream << elements[i] << ", ";
	if (d > 0) stream << elements[d-1];
	stream << "}";
	return stream.str();
}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "AliAnalysisManager.h"
#include "AliAnalysisTaskSE.h"
#include "AliAnalysisTaskPHOSTriggerQA.h"
#include "AliESDCaloCluster.h"
#include "AliPHOSGeometry.h"
#include "AliESDEvent.h"
#include "AliESDCaloCells.h"
#include "AliLog.h"
#include "TObjArray.h"
#include "TList.h"
#include "TH1.h"
#include "TH2.h"

// QA of PHOS Trigger data.
//...
// Author: Boris Polishchuk
// Date  : 06.02.2012

ClassImp(AliAnalysisTaskPHOSTriggerQA)

//________________________________________________________________________
AliAnalysisTaskPHOSTriggerQA::AliAnalysisTaskPHOSTriggerQA() : AliAnalysisTaskSE(),
  fOutputContainer(0),fPHOSGeo(0),fEventCounter(0),fL1Threshold(-1)
{
  //Default constructor.
  // Initialize the PHOS geometry
  fPHOSGeo = AliPHOSGeometry::GetInstance("IHEP") ;

}

//________________________________________________________________________
AliAnalysisTaskPHOSTriggerQA::AliAnalysisTaskPHOSTriggerQA(const char *name, Int_t L1_threshold)
: AliAnalysisTaskSE(name),
  fOutputContainer(0),fPHOSGeo(0),fEventCounter(0),fL1Threshold(L1_threshold)
{

  // Output slots #0 write into a TH1 container
  DefineOutput(1,TList::Class());

  // Initialize the PHOS geometry
  fPHOSGeo = AliPHOSGeometry::GetInstance("IHEP") ;

}

//________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::UserCreateOutputObjects()
{
  // Create histograms
  // Called once

  // ESD histograms
  if(fOutputContainer != NULL){
    delete fOutputContainer;
  }

  fOutputContainer = new TList();
  fOutputContainer->SetOwner(kTRUE);

  //Bin 1: total number of processed events.
  //Bin 2: number of events contained PHOS trigger digits.
  fOutputContainer->Add(new TH1F("hNev","Number of events",10,0.,10.));

  char key[55],titl[55];
  Int_t nCols = 56, nRows = 64;

  Int_t    nPtPhot  = 1000 ;
  Double_t ptPhotMax =  100. ;

  Int_t nTrMax = 1200;
  Float_t trMax = 600.;

  fOutputContainer->Add(new TH1F("hNtr","Number of fired 4x4 regions per event",nTrMax,0.,trMax));

  for(Int_t sm=1; sm<5; sm++) {

    snprintf(key,55,"hNtrSM%d",sm);
    snprintf(titl,55,"Number of fired 4x4 regions in SM%d",5-sm);
    fOutputContainer->Add(new TH1F(key,titl,nTrMax/3,0.,trMax/3));

    snprintf(key,55,"h4x4SM%d",sm);
    snprintf(titl,55,"SM%d 4x4 occupancy",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"h4x4CluSM%d",sm);
    snprintf(titl,55,"SM%d 4x4 occupancy associated with clusters (E>2GeV)",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"hCluSM%d",sm);
    snprintf(titl,55,"SM%d cluster occupancy",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"hCluTSM%d",sm);
    snprintf(titl,55,"SM%d triggered cluster occupancy",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"hPhotAllSM%d",sm);
    snprintf(titl,55,"SM%d cluster energy",5-sm);
    fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));

    for(Int_t iTRU=1; iTRU<=8; iTRU++) {
      snprintf(key,55,"hPhotAllSM%dTRU%d",sm,iTRU);
      snprintf(titl,55,"SM%d: clusters energy in TRU%d",5-sm,iTRU);
      fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));
    }

    snprintf(key,55,"hPhotTrigSM%d",sm);
    snprintf(titl,55,"SM%d triggered cluster energy",5-sm);
    fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));

    for(Int_t iTRU=1; iTRU<=8; iTRU++) {
      snprintf(key,55,"hPhotTrigSM%dTRU%d",sm,iTRU);
      snprintf(titl,55,"SM%d: triggered clusters energy in TRU%d",5-sm,iTRU);
      fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));
    }

  }

  PostData(1, fOutputContainer);

}

//________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::UserExec(Option_t *)
{
  // Main loop, called for each event
  // Analyze ESD/AOD

  AliESDEvent *event = dynamic_cast<AliESDEvent*>(InputEvent());

  if (!event) {
    Printf("ERROR: Could not retrieve event");
    PostData(1, fOutputContainer);
    return;
  }

  FillHistogram("hNev",0.); // all events
  fEventCounter++;

  AliESDCaloTrigger* trgESD = event->GetCaloTrigger("PHOS");
  trgESD->Reset();

  if(trgESD->GetEntries())
    FillHistogram("hNev",1.); // triggered events

  TString trigClasses = event->GetFiredTriggerClasses();
  printf("\nEvent %d: %d non-zero trigger digits %s\n",
	 fEventCounter,trgESD->GetEntries(),trigClasses.Data());

  // Get PHOS rotation matrices from ESD and set them to the PHOS geometry
  char key[55] ;

  if(fEventCounter == 0) {
    for(Int_t mod=0; mod<5; mod++) {
      if(!event->GetPHOSMatrix(mod)) continue;
      fPHOSGeo->SetMisalMatrix(event->GetPHOSMatrix(mod),mod) ;
    }
  }

  Int_t multClu = event->GetNumberOfCaloClusters();
  AliESDCaloCells *phsCells = event->GetPHOSCells();

  Int_t inPHOS[3] = {};
  Int_t ntr = 0;

  Int_t kUsedCluster[] = {multClu*0};

  //Loop over 4x4 fired regions
  while(trgESD->Next()) {

    // L1 threshold: -1-L0, 0-high, 1-medium, 2-low
    if(trgESD->GetL1TimeSum() != fL1Threshold) continue;
    ntr++;

    Int_t tmod,tabsId; // "Online" module number, bottom-left 4x4 edge cell absId
    trgESD->GetPosition(tmod,tabsId);

    Int_t trelid[4] ;
    fPHOSGeo->AbsToRelNumbering(tabsId,trelid);

    snprintf(key,55,"h4x4SM%d",trelid[0]);
    FillHistogram(key,trelid[2]-1,trelid[3]-1);

    inPHOS[trelid[0]-1]++;

    for (Int_t i=0; i<multClu; i++) {

      AliESDCaloCluster *c1 = event->GetCaloCluster(i);
      if(kUsedCluster[i]) continue; // already matched to some trigger patch

      if(!c1->IsPHOS()) continue;
      if(c1->GetType() == AliESDCaloCluster::kPHOSCharged) continue; // reject CPV cluster

      if(c1->E()<0.3) continue;
      if(c1->GetNCells()<3) continue ;

      Int_t maxId, relid[4];
      MaxEnergyCellPos(phsCells,c1,maxId);

      fPHOSGeo->AbsToRelNumbering(maxId, relid);
      snprintf(key,55,"hPhotAllSM%d",relid[0]);
      FillHistogram(key,c1->E());

      snprintf(key,55,"hPhotAllSM%dTRU%d",relid[0],GetTRUNum(relid[2]-1,relid[3]-1));
      FillHistogram(key,c1->E());

      snprintf(key,55,"hCluSM%d",relid[0]);
      FillHistogram(key,relid[2]-1,relid[3]-1);

      if( Matched(trelid,relid) ) {

	kUsedCluster[i] = 1;

	snprintf(key,55,"hPhotTrigSM%d",relid[0]);
	FillHistogram(key,c1->E());

	snprintf(key,55,"hPhotTrigSM%dTRU%d",relid[0],GetTRUNum(relid[2]-1,relid[3]-1));
	FillHistogram(key,c1->E());

	snprintf(key,55,"hCluTSM%d",relid[0]);
	FillHistogram(key,relid[2]-1,relid[3]-1);

	if(c1->E()>2.) { // Eclu > 2 GeV
	  snprintf(key,55,"h4x4CluSM%d",trelid[0]);
	  FillHistogram(key,trelid[2]-1,trelid[3]-1);
	}
	continue;
      }

    }
  } //while(trgESD->Next())

  FillHistogram("hNtr",ntr); // number of selected triggers per event

  for(Int_t sm=1; sm<4; sm++) {
    snprintf(key,55,"hNtrSM%d",sm);
    if(inPHOS[sm-1]) FillHistogram(key,inPHOS[sm-1]);
  }

  // Post output data.
  PostData(1, fOutputContainer);

}

//_____________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::FillHistogram(const char * key,Double_t x)const{
  //FillHistogram
  TH1I * tmpI = dynamic_cast<TH1I*>(fOutputContainer->FindObject(key)) ;
  if(tmpI){
    tmpI->Fill(x) ;
    return ;
  }
  TH1F * tmpF = dynamic_cast<TH1F*>(fOutputContainer->FindObject(key)) ;
  if(tmpF){
    tmpF->Fill(x) ;
    return ;
  }
  TH1D * tmpD = dynamic_cast<TH1D*>(fOutputContainer->FindObject(key)) ;
  if(tmpD){
    tmpD->Fill(x) ;
    return ;
  }
  AliInfo(Form("can not find histogram <%s> ",key)) ;
}
//_____________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::FillHistogram(const char * key,Double_t x,Double_t y)const{
  //FillHistogram
  TObject * tmp = fOutputContainer->FindObject(key) ;
  if(!tmp){
    AliInfo(Form("can not find histogram <%s> ",key)) ;
    return ;
  }
  if(tmp->IsA() == TClass::GetClass("TH1F")){
    ((TH1F*)tmp)->Fill(x,y) ;
    return ;
  }
  if(tmp->IsA() == TClass::GetClass("TH2F")){
    ((TH2F*)tmp)->Fill(x,y) ;
    return ;
  }
  AliError(Form("Calling FillHistogram with 2 parameters for histo <%s> of type %s",key,tmp->IsA()->GetName())) ;
}

//_____________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::MaxEnergyCellPos(AliESDCaloCells *cells, AliESDCaloCluster* clu, Int_t& maxId)
{
  Double_t eMax = -111;

  for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
    Int_t cellAbsId = clu->GetCellAbsId(iDig);
    Double_t eCell = cells->GetCellAmplitude(cellAbsId)*clu->GetCellAmplitudeFraction(iDig);
    if(eCell>eMax)  {
      eMax = eCell;
      maxId = cellAbsId;
    }
  }

}

//_____________________________________________________________________________
Bool_t AliAnalysisTaskPHOSTriggerQA::Matched(Int_t *trig_relid, Int_t *cluster_relid)
{
  //Returns kTRUE if cluster position coincides with 4x4 position.

  if( trig_relid[0] != cluster_relid[0] )            return kFALSE; // different modules!
  if( TMath::Abs(trig_relid[2]-cluster_relid[2])>3 ) return kFALSE; // X-distance too large!
  if( TMath::Abs(trig_relid[3]-cluster_relid[3])>3 ) return kFALSE; // Z-distance too large!

  return kTRUE;
}

//_______________________________________________________________________________
Int_t AliAnalysisTaskPHOSTriggerQA::GetTRUNum(Int_t cellX, Int_t cellZ)
{
  //Return TRU region number for given cell.
  //cellX: [0-63], cellZ: [0-55]

  Int_t iTRU=-111;

  //RCU0: TRU 1,2
  if(0<=cellX&&cellX<16) {

    if(0<=cellZ&&cellZ<28) iTRU=2;
    else iTRU=1;
  }

  //RCU1: TRU 3,4
  if(16<=cellX&&cellX<32) {

    if(0<=cellZ&&cellZ<28) iTRU=4;
    else iTRU=3;
  }

  //RCU2: TRU 5,6
  if(32<=cellX&&cellX<48) {

    if(0<=cellZ&&cellZ<28) iTRU=6;
    else iTRU=5;
  }

  //RCU3: TRU 7,8
  if(48<=cellX&&cellX<64) {

    if(0<=cellZ&&cellZ<28) iTRU=8;
    else iTRU=7;
  }

  return iTRU;
}
<commit_msg>Selected triggers per event counter fixed; taken into account an increased number of PHOS modules in Run 2 (4 instead of 3).<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "AliAnalysisManager.h"
#include "AliAnalysisTaskSE.h"
#include "AliAnalysisTaskPHOSTriggerQA.h"
#include "AliESDCaloCluster.h"
#include "AliPHOSGeometry.h"
#include "AliESDEvent.h"
#include "AliESDCaloCells.h"
#include "AliLog.h"
#include "TObjArray.h"
#include "TList.h"
#include "TH1.h"
#include "TH2.h"

// QA of PHOS Trigger data.
//...
// Author: Boris Polishchuk
// Date  : 06.02.2012

ClassImp(AliAnalysisTaskPHOSTriggerQA)

//________________________________________________________________________
AliAnalysisTaskPHOSTriggerQA::AliAnalysisTaskPHOSTriggerQA() : AliAnalysisTaskSE(),
  fOutputContainer(0),fPHOSGeo(0),fEventCounter(0),fL1Threshold(-1)
{
  //Default constructor.
  // Initialize the PHOS geometry
  fPHOSGeo = AliPHOSGeometry::GetInstance("IHEP") ;

}

//________________________________________________________________________
AliAnalysisTaskPHOSTriggerQA::AliAnalysisTaskPHOSTriggerQA(const char *name, Int_t L1_threshold)
: AliAnalysisTaskSE(name),
  fOutputContainer(0),fPHOSGeo(0),fEventCounter(0),fL1Threshold(L1_threshold)
{

  // Output slots #0 write into a TH1 container
  DefineOutput(1,TList::Class());

  // Initialize the PHOS geometry
  fPHOSGeo = AliPHOSGeometry::GetInstance("IHEP") ;

}

//________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::UserCreateOutputObjects()
{
  // Create histograms
  // Called once

  // ESD histograms
  if(fOutputContainer != NULL){
    delete fOutputContainer;
  }

  fOutputContainer = new TList();
  fOutputContainer->SetOwner(kTRUE);

  //Bin 1: total number of processed events.
  //Bin 2: number of events contained PHOS trigger digits.
  fOutputContainer->Add(new TH1F("hNev","Number of events",10,0.,10.));

  char key[55],titl[55];
  Int_t nCols = 56, nRows = 64;

  Int_t    nPtPhot  = 1000 ;
  Double_t ptPhotMax =  100. ;

  Int_t nTrMax = 1200;
  Float_t trMax = 600.;

  fOutputContainer->Add(new TH1F("hNtr","Number of fired 4x4 regions per event",nTrMax,0.,trMax));

  for(Int_t sm=1; sm<5; sm++) {

    snprintf(key,55,"hNtrSM%d",sm);
    snprintf(titl,55,"Number of fired 4x4 regions in SM%d",5-sm);
    fOutputContainer->Add(new TH1F(key,titl,nTrMax/3,0.,trMax/3));

    snprintf(key,55,"h4x4SM%d",sm);
    snprintf(titl,55,"SM%d 4x4 occupancy",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"h4x4CluSM%d",sm);
    snprintf(titl,55,"SM%d 4x4 occupancy associated with clusters (E>2GeV)",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"hCluSM%d",sm);
    snprintf(titl,55,"SM%d cluster occupancy",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"hCluTSM%d",sm);
    snprintf(titl,55,"SM%d triggered cluster occupancy",5-sm);
    fOutputContainer->Add(new TH2F(key,titl,nRows,0.,nRows,nCols,0.,nCols));

    snprintf(key,55,"hPhotAllSM%d",sm);
    snprintf(titl,55,"SM%d cluster energy",5-sm);
    fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));

    for(Int_t iTRU=1; iTRU<=8; iTRU++) {
      snprintf(key,55,"hPhotAllSM%dTRU%d",sm,iTRU);
      snprintf(titl,55,"SM%d: clusters energy in TRU%d",5-sm,iTRU);
      fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));
    }

    snprintf(key,55,"hPhotTrigSM%d",sm);
    snprintf(titl,55,"SM%d triggered cluster energy",5-sm);
    fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));

    for(Int_t iTRU=1; iTRU<=8; iTRU++) {
      snprintf(key,55,"hPhotTrigSM%dTRU%d",sm,iTRU);
      snprintf(titl,55,"SM%d: triggered clusters energy in TRU%d",5-sm,iTRU);
      fOutputContainer->Add(new TH1F(key,titl,nPtPhot,0.,ptPhotMax));
    }

  }

  PostData(1, fOutputContainer);

}

//________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::UserExec(Option_t *)
{
  // Main loop, called for each event
  // Analyze ESD/AOD

  AliESDEvent *event = dynamic_cast<AliESDEvent*>(InputEvent());

  if (!event) {
    Printf("ERROR: Could not retrieve event");
    PostData(1, fOutputContainer);
    return;
  }

  FillHistogram("hNev",0.); // all events
  fEventCounter++;

  AliESDCaloTrigger* trgESD = event->GetCaloTrigger("PHOS");
  trgESD->Reset();

  if(trgESD->GetEntries())
    FillHistogram("hNev",1.); // triggered events

  TString trigClasses = event->GetFiredTriggerClasses();
  printf("\nEvent %d: %d non-zero trigger digits %s\n",
	 fEventCounter,trgESD->GetEntries(),trigClasses.Data());

  // Get PHOS rotation matrices from ESD and set them to the PHOS geometry
  char key[55] ;

  if(fEventCounter == 0) {
    for(Int_t mod=0; mod<5; mod++) {
      if(!event->GetPHOSMatrix(mod)) continue;
      fPHOSGeo->SetMisalMatrix(event->GetPHOSMatrix(mod),mod) ;
    }
  }

  Int_t multClu = event->GetNumberOfCaloClusters();
  AliESDCaloCells *phsCells = event->GetPHOSCells();

  Int_t inPHOS[4] = {};
  Int_t ntr = 0;

  Int_t kUsedCluster[] = {multClu*0};

  //Loop over 4x4 fired regions
  while(trgESD->Next()) {

    // L1 threshold: -1-L0, 0-high, 1-medium, 2-low
    if(trgESD->GetL1TimeSum() != fL1Threshold) continue;
    ntr++;

    Int_t tmod,tabsId; // "Online" module number, bottom-left 4x4 edge cell absId
    trgESD->GetPosition(tmod,tabsId);

    Int_t trelid[4] ;
    fPHOSGeo->AbsToRelNumbering(tabsId,trelid);

    snprintf(key,55,"h4x4SM%d",trelid[0]);
    FillHistogram(key,trelid[2]-1,trelid[3]-1);

    inPHOS[trelid[0]-1]++;

    for (Int_t i=0; i<multClu; i++) {

      AliESDCaloCluster *c1 = event->GetCaloCluster(i);
      if(kUsedCluster[i]) continue; // already matched to some trigger patch

      if(!c1->IsPHOS()) continue;
      if(c1->GetType() == AliESDCaloCluster::kPHOSCharged) continue; // reject CPV cluster

      if(c1->E()<0.3) continue;
      if(c1->GetNCells()<3) continue ;

      Int_t maxId, relid[4];
      MaxEnergyCellPos(phsCells,c1,maxId);

      fPHOSGeo->AbsToRelNumbering(maxId, relid);
      snprintf(key,55,"hPhotAllSM%d",relid[0]);
      FillHistogram(key,c1->E());

      snprintf(key,55,"hPhotAllSM%dTRU%d",relid[0],GetTRUNum(relid[2]-1,relid[3]-1));
      FillHistogram(key,c1->E());

      snprintf(key,55,"hCluSM%d",relid[0]);
      FillHistogram(key,relid[2]-1,relid[3]-1);

      if( Matched(trelid,relid) ) {

	kUsedCluster[i] = 1;

	snprintf(key,55,"hPhotTrigSM%d",relid[0]);
	FillHistogram(key,c1->E());

	snprintf(key,55,"hPhotTrigSM%dTRU%d",relid[0],GetTRUNum(relid[2]-1,relid[3]-1));
	FillHistogram(key,c1->E());

	snprintf(key,55,"hCluTSM%d",relid[0]);
	FillHistogram(key,relid[2]-1,relid[3]-1);

	if(c1->E()>2.) { // Eclu > 2 GeV
	  snprintf(key,55,"h4x4CluSM%d",trelid[0]);
	  FillHistogram(key,trelid[2]-1,trelid[3]-1);
	}
	continue;
      }

    }
  } //while(trgESD->Next())

  FillHistogram("hNtr",ntr); // number of selected triggers per event

  for(Int_t sm=1; sm<5; sm++) {
    snprintf(key,55,"hNtrSM%d",sm);
    if(inPHOS[sm-1]) FillHistogram(key,inPHOS[sm-1]);
  }

  // Post output data.
  PostData(1, fOutputContainer);

}

//_____________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::FillHistogram(const char * key,Double_t x)const{
  //FillHistogram
  TH1I * tmpI = dynamic_cast<TH1I*>(fOutputContainer->FindObject(key)) ;
  if(tmpI){
    tmpI->Fill(x) ;
    return ;
  }
  TH1F * tmpF = dynamic_cast<TH1F*>(fOutputContainer->FindObject(key)) ;
  if(tmpF){
    tmpF->Fill(x) ;
    return ;
  }
  TH1D * tmpD = dynamic_cast<TH1D*>(fOutputContainer->FindObject(key)) ;
  if(tmpD){
    tmpD->Fill(x) ;
    return ;
  }
  AliInfo(Form("can not find histogram <%s> ",key)) ;
}
//_____________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::FillHistogram(const char * key,Double_t x,Double_t y)const{
  //FillHistogram
  TObject * tmp = fOutputContainer->FindObject(key) ;
  if(!tmp){
    AliInfo(Form("can not find histogram <%s> ",key)) ;
    return ;
  }
  if(tmp->IsA() == TClass::GetClass("TH1F")){
    ((TH1F*)tmp)->Fill(x,y) ;
    return ;
  }
  if(tmp->IsA() == TClass::GetClass("TH2F")){
    ((TH2F*)tmp)->Fill(x,y) ;
    return ;
  }
  AliError(Form("Calling FillHistogram with 2 parameters for histo <%s> of type %s",key,tmp->IsA()->GetName())) ;
}

//_____________________________________________________________________________
void AliAnalysisTaskPHOSTriggerQA::MaxEnergyCellPos(AliESDCaloCells *cells, AliESDCaloCluster* clu, Int_t& maxId)
{
  Double_t eMax = -111;

  for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
    Int_t cellAbsId = clu->GetCellAbsId(iDig);
    Double_t eCell = cells->GetCellAmplitude(cellAbsId)*clu->GetCellAmplitudeFraction(iDig);
    if(eCell>eMax)  {
      eMax = eCell;
      maxId = cellAbsId;
    }
  }

}

//_____________________________________________________________________________
Bool_t AliAnalysisTaskPHOSTriggerQA::Matched(Int_t *trig_relid, Int_t *cluster_relid)
{
  //Returns kTRUE if cluster position coincides with 4x4 position.

  if( trig_relid[0] != cluster_relid[0] )            return kFALSE; // different modules!
  if( TMath::Abs(trig_relid[2]-cluster_relid[2])>3 ) return kFALSE; // X-distance too large!
  if( TMath::Abs(trig_relid[3]-cluster_relid[3])>3 ) return kFALSE; // Z-distance too large!

  return kTRUE;
}

//_______________________________________________________________________________
Int_t AliAnalysisTaskPHOSTriggerQA::GetTRUNum(Int_t cellX, Int_t cellZ)
{
  //Return TRU region number for given cell.
  //cellX: [0-63], cellZ: [0-55]

  Int_t iTRU=-111;

  //RCU0: TRU 1,2
  if(0<=cellX&&cellX<16) {

    if(0<=cellZ&&cellZ<28) iTRU=2;
    else iTRU=1;
  }

  //RCU1: TRU 3,4
  if(16<=cellX&&cellX<32) {

    if(0<=cellZ&&cellZ<28) iTRU=4;
    else iTRU=3;
  }

  //RCU2: TRU 5,6
  if(32<=cellX&&cellX<48) {

    if(0<=cellZ&&cellZ<28) iTRU=6;
    else iTRU=5;
  }

  //RCU3: TRU 7,8
  if(48<=cellX&&cellX<64) {

    if(0<=cellZ&&cellZ<28) iTRU=8;
    else iTRU=7;
  }

  return iTRU;
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/

#include "cppfilesettingspage.h"
#include "cpptoolsconstants.h"
#include "ui_cppfilesettingspage.h"

#include <coreplugin/icore.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/mimedatabase.h>
#include <cppeditor/cppeditorconstants.h>

#include <extensionsystem/pluginmanager.h>

#include <QtCore/QSettings>
#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QCoreApplication>
#include <QtCore/QDate>
#include <QtCore/QLocale>

#include <QtGui/QFileDialog>
#include <QtGui/QMessageBox>

static const char *headerSuffixKeyC = "HeaderSuffix";
static const char *sourceSuffixKeyC = "SourceSuffix";
static const char *licenseTemplatePathKeyC = "LicenseTemplate";

const char *licenseTemplateTemplate = QT_TRANSLATE_NOOP("CppTools::Internal::CppFileSettingsWidget",
"/**************************************************************************\n"
"** Qt Creator license header template\n"
"**   Special keywords: %USER% %DATE% %YEAR%\n"
"**   Environment variables: %$VARIABLE%\n"
"**   To protect a percent sign, use '%%'.\n"
"**************************************************************************/\n");

namespace CppTools {
namespace Internal {

CppFileSettings::CppFileSettings() :
    lowerCaseFiles(false)
{
}

void CppFileSettings::toSettings(QSettings *s) const
{
    s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
    s->setValue(QLatin1String(headerSuffixKeyC), headerSuffix);
    s->setValue(QLatin1String(sourceSuffixKeyC), sourceSuffix);
    s->setValue(QLatin1String(Constants::LOWERCASE_CPPFILES_KEY), lowerCaseFiles);
    s->setValue(QLatin1String(licenseTemplatePathKeyC), licenseTemplatePath);
    s->endGroup();
}

void CppFileSettings::fromSettings(QSettings *s)
{
    s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
    headerSuffix= s->value(QLatin1String(headerSuffixKeyC), QLatin1String("h")).toString();
    sourceSuffix = s->value(QLatin1String(sourceSuffixKeyC), QLatin1String("cpp")).toString();
    const bool lowerCaseDefault = Constants::lowerCaseFilesDefault;
    lowerCaseFiles = s->value(QLatin1String(Constants::LOWERCASE_CPPFILES_KEY), QVariant(lowerCaseDefault)).toBool();
    licenseTemplatePath = s->value(QLatin1String(licenseTemplatePathKeyC), QString()).toString();
    s->endGroup();
}

bool CppFileSettings::applySuffixesToMimeDB()
{
    Core::MimeDatabase *mdb = Core::ICore::instance()->mimeDatabase();
    return mdb->setPreferredSuffix(QLatin1String(CppTools::Constants::CPP_SOURCE_MIMETYPE), sourceSuffix)
            && mdb->setPreferredSuffix(QLatin1String(CppTools::Constants::CPP_HEADER_MIMETYPE), headerSuffix);
}

bool CppFileSettings::equals(const CppFileSettings &rhs) const
{
    return lowerCaseFiles == rhs.lowerCaseFiles
           && headerSuffix == rhs.headerSuffix
           && sourceSuffix == rhs.sourceSuffix
           && licenseTemplatePath == rhs.licenseTemplatePath;
}

// Replacements of special license template keywords.
static QString keyWordReplacement(const QString &keyWord)
{
    if (keyWord == QLatin1String("%YEAR%")) {
        return QString::number(QDate::currentDate().year());
    }
    if (keyWord == QLatin1String("%DATE%")) {
        static QString format;
        // ensure a format with 4 year digits. Some have locales have 2.
        if (format.isEmpty()) {
            QLocale loc;
            format = loc.dateFormat(QLocale::ShortFormat);
            const QChar ypsilon = QLatin1Char('y');
            if (format.count(ypsilon) == 2)
                format.insert(format.indexOf(ypsilon), QString(2, ypsilon));
        }
        return QDate::currentDate().toString(format);
    }
    if (keyWord == QLatin1String("%USER%")) {
#ifdef Q_OS_WIN
        return QString::fromLocal8Bit(qgetenv("USERNAME"));
#else
        return QString::fromLocal8Bit(qgetenv("USER"));
#endif
    }
    // Environment variables (for example '%$EMAIL%').
    if (keyWord.startsWith(QLatin1String("%$"))) {
        const QString varName = keyWord.mid(2, keyWord.size() - 3);
        return QString::fromLocal8Bit(qgetenv(varName.toLocal8Bit()));
    }
    return QString();
}

// Parse a license template, scan for %KEYWORD% and replace if known.
// Replace '%%' by '%'.
static void parseLicenseTemplatePlaceholders(QString *t)
{
    int pos = 0;
    const QChar placeHolder = QLatin1Char('%');
    do {
        const int placeHolderPos = t->indexOf(placeHolder, pos);
        if (placeHolderPos == -1)
            break;
        const int endPlaceHolderPos = t->indexOf(placeHolder, placeHolderPos + 1);
        if (endPlaceHolderPos == -1)
            break;
        if (endPlaceHolderPos == placeHolderPos + 1) { // '%%' -> '%'
            t->remove(placeHolderPos, 1);
            pos = placeHolderPos + 1;
        } else {
            const QString keyWord = t->mid(placeHolderPos, endPlaceHolderPos + 1 - placeHolderPos);
            const QString replacement = keyWordReplacement(keyWord);
            if (replacement.isEmpty()) {
                pos = endPlaceHolderPos + 1;
            } else {
                t->replace(placeHolderPos, keyWord.size(), replacement);
                pos = placeHolderPos + replacement.size();
            }
        }
    } while (pos < t->size());
}

// Convenience that returns the formatted license template.
QString CppFileSettings::licenseTemplate()
{

    const QSettings *s = Core::ICore::instance()->settings();
    QString key = QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP);
    key += QLatin1Char('/');
    key += QLatin1String(licenseTemplatePathKeyC);
    const QString path = s->value(key, QString()).toString();
    if (path.isEmpty())
        return QString();
    QFile file(path);
    if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) {
        qWarning("Unable to open the license template %s: %s", qPrintable(path), qPrintable(file.errorString()));
        return QString();
    }
    QString license = QString::fromUtf8(file.readAll());
    parseLicenseTemplatePlaceholders(&license);
    // Ensure exactly one additional new line separating stuff
    const QChar newLine = QLatin1Char('\n');
    if (!license.endsWith(newLine))
        license += newLine;
    license += newLine;
    return license;
}

// ------------------ CppFileSettingsWidget

CppFileSettingsWidget::CppFileSettingsWidget(QWidget *parent) :
    QWidget(parent),
    m_ui(new Ui::CppFileSettingsPage)
{
    m_ui->setupUi(this);
    const Core::MimeDatabase *mdb = Core::ICore::instance()->mimeDatabase();
    // populate suffix combos
    if (const Core::MimeType sourceMt = mdb->findByType(QLatin1String(CppTools::Constants::CPP_SOURCE_MIMETYPE)))
        foreach (const QString &suffix, sourceMt.suffixes())
            m_ui->sourceSuffixComboBox->addItem(suffix);

    if (const Core::MimeType headerMt = mdb->findByType(QLatin1String(CppTools::Constants::CPP_HEADER_MIMETYPE)))
        foreach (const QString &suffix, headerMt.suffixes())
            m_ui->headerSuffixComboBox->addItem(suffix);
    m_ui->licenseTemplatePathChooser->setExpectedKind(Core::Utils::PathChooser::File);
    m_ui->licenseTemplatePathChooser->addButton(tr("Edit..."), this, SLOT(slotEdit()));
}

CppFileSettingsWidget::~CppFileSettingsWidget()
{
    delete m_ui;
}

QString CppFileSettingsWidget::licenseTemplatePath() const
{
    return m_ui->licenseTemplatePathChooser->path();
}

void CppFileSettingsWidget::setLicenseTemplatePath(const QString &lp)
{
    m_ui->licenseTemplatePathChooser->setPath(lp);
}

CppFileSettings CppFileSettingsWidget::settings() const
{
    CppFileSettings rc;
    rc.lowerCaseFiles = m_ui->lowerCaseFileNamesCheckBox->isChecked();
    rc.headerSuffix = m_ui->headerSuffixComboBox->currentText();
    rc.sourceSuffix = m_ui->sourceSuffixComboBox->currentText();
    rc.licenseTemplatePath = licenseTemplatePath();
    return rc;
}

static inline void setComboText(QComboBox *cb, const QString &text, int defaultIndex = 0)
{
    const int index = cb->findText(text);
    cb->setCurrentIndex(index == -1 ? defaultIndex: index);
}

void CppFileSettingsWidget::setSettings(const CppFileSettings &s)
{
    m_ui->lowerCaseFileNamesCheckBox->setChecked(s.lowerCaseFiles);
    setComboText(m_ui->headerSuffixComboBox, s.headerSuffix);
    setComboText(m_ui->sourceSuffixComboBox, s.sourceSuffix);
    setLicenseTemplatePath(s.licenseTemplatePath);
}

void CppFileSettingsWidget::slotEdit()
{
    QString path = licenseTemplatePath();
    // Edit existing file with C++
    if (!path.isEmpty()) {
        Core::EditorManager::instance()->openEditor(path, QLatin1String(CppEditor::Constants::CPPEDITOR_KIND));
        return;
    }
    // Pick a file name and write new template, edit with C++
    path = QFileDialog::getSaveFileName(this, tr("Choose a new license template file"));
    if (path.isEmpty())
        return;
    QFile file(path);
    if (!file.open(QIODevice::WriteOnly|QIODevice::Text|QIODevice::Truncate)) {
        QMessageBox::warning(this, tr("Template write error"),
                             tr("Cannot write to %1: %2").arg(path, file.errorString()));
        return;
    }
    file.write(tr(licenseTemplateTemplate).toUtf8());
    file.close();
    setLicenseTemplatePath(path);
    Core::EditorManager::instance()->openEditor(path, QLatin1String(CppEditor::Constants::CPPEDITOR_KIND));
}

// --------------- CppFileSettingsPage
CppFileSettingsPage::CppFileSettingsPage(QSharedPointer<CppFileSettings> &settings,
                                         QObject *parent) :
    Core::IOptionsPage(parent),
    m_settings(settings)
{
}

CppFileSettingsPage::~CppFileSettingsPage()
{
}

QString CppFileSettingsPage::id() const
{
    return QLatin1String(Constants::CPP_SETTINGS_ID);
}

QString CppFileSettingsPage::trName() const
{
    return QCoreApplication::translate("CppTools", Constants::CPP_SETTINGS_ID);
}

QString CppFileSettingsPage::category() const
{
    return QLatin1String(Constants::CPP_SETTINGS_CATEGORY);
}

QString CppFileSettingsPage::trCategory() const
{
    return QCoreApplication::translate("CppTools", Constants::CPP_SETTINGS_CATEGORY);
}

QWidget *CppFileSettingsPage::createPage(QWidget *parent)
{

    m_widget = new CppFileSettingsWidget(parent);
    m_widget->setSettings(*m_settings);
    return m_widget;
}

void CppFileSettingsPage::apply()
{
    if (m_widget) {
        const CppFileSettings newSettings = m_widget->settings();
        if (newSettings != *m_settings) {
            *m_settings = newSettings;
            m_settings->toSettings(Core::ICore::instance()->settings());
            m_settings->applySuffixesToMimeDB();
        }
    }
}

}
}

<commit_msg>Clarify what the dialog in CppFileSettingsWidget::slotEdit() actually does<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/

#include "cppfilesettingspage.h"
#include "cpptoolsconstants.h"
#include "ui_cppfilesettingspage.h"

#include <coreplugin/icore.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/mimedatabase.h>
#include <cppeditor/cppeditorconstants.h>

#include <extensionsystem/pluginmanager.h>

#include <QtCore/QSettings>
#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QCoreApplication>
#include <QtCore/QDate>
#include <QtCore/QLocale>

#include <QtGui/QFileDialog>
#include <QtGui/QMessageBox>

static const char *headerSuffixKeyC = "HeaderSuffix";
static const char *sourceSuffixKeyC = "SourceSuffix";
static const char *licenseTemplatePathKeyC = "LicenseTemplate";

const char *licenseTemplateTemplate = QT_TRANSLATE_NOOP("CppTools::Internal::CppFileSettingsWidget",
"/**************************************************************************\n"
"** Qt Creator license header template\n"
"**   Special keywords: %USER% %DATE% %YEAR%\n"
"**   Environment variables: %$VARIABLE%\n"
"**   To protect a percent sign, use '%%'.\n"
"**************************************************************************/\n");

namespace CppTools {
namespace Internal {

CppFileSettings::CppFileSettings() :
    lowerCaseFiles(false)
{
}

void CppFileSettings::toSettings(QSettings *s) const
{
    s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
    s->setValue(QLatin1String(headerSuffixKeyC), headerSuffix);
    s->setValue(QLatin1String(sourceSuffixKeyC), sourceSuffix);
    s->setValue(QLatin1String(Constants::LOWERCASE_CPPFILES_KEY), lowerCaseFiles);
    s->setValue(QLatin1String(licenseTemplatePathKeyC), licenseTemplatePath);
    s->endGroup();
}

void CppFileSettings::fromSettings(QSettings *s)
{
    s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
    headerSuffix= s->value(QLatin1String(headerSuffixKeyC), QLatin1String("h")).toString();
    sourceSuffix = s->value(QLatin1String(sourceSuffixKeyC), QLatin1String("cpp")).toString();
    const bool lowerCaseDefault = Constants::lowerCaseFilesDefault;
    lowerCaseFiles = s->value(QLatin1String(Constants::LOWERCASE_CPPFILES_KEY), QVariant(lowerCaseDefault)).toBool();
    licenseTemplatePath = s->value(QLatin1String(licenseTemplatePathKeyC), QString()).toString();
    s->endGroup();
}

bool CppFileSettings::applySuffixesToMimeDB()
{
    Core::MimeDatabase *mdb = Core::ICore::instance()->mimeDatabase();
    return mdb->setPreferredSuffix(QLatin1String(CppTools::Constants::CPP_SOURCE_MIMETYPE), sourceSuffix)
            && mdb->setPreferredSuffix(QLatin1String(CppTools::Constants::CPP_HEADER_MIMETYPE), headerSuffix);
}

bool CppFileSettings::equals(const CppFileSettings &rhs) const
{
    return lowerCaseFiles == rhs.lowerCaseFiles
           && headerSuffix == rhs.headerSuffix
           && sourceSuffix == rhs.sourceSuffix
           && licenseTemplatePath == rhs.licenseTemplatePath;
}

// Replacements of special license template keywords.
static QString keyWordReplacement(const QString &keyWord)
{
    if (keyWord == QLatin1String("%YEAR%")) {
        return QString::number(QDate::currentDate().year());
    }
    if (keyWord == QLatin1String("%DATE%")) {
        static QString format;
        // ensure a format with 4 year digits. Some have locales have 2.
        if (format.isEmpty()) {
            QLocale loc;
            format = loc.dateFormat(QLocale::ShortFormat);
            const QChar ypsilon = QLatin1Char('y');
            if (format.count(ypsilon) == 2)
                format.insert(format.indexOf(ypsilon), QString(2, ypsilon));
        }
        return QDate::currentDate().toString(format);
    }
    if (keyWord == QLatin1String("%USER%")) {
#ifdef Q_OS_WIN
        return QString::fromLocal8Bit(qgetenv("USERNAME"));
#else
        return QString::fromLocal8Bit(qgetenv("USER"));
#endif
    }
    // Environment variables (for example '%$EMAIL%').
    if (keyWord.startsWith(QLatin1String("%$"))) {
        const QString varName = keyWord.mid(2, keyWord.size() - 3);
        return QString::fromLocal8Bit(qgetenv(varName.toLocal8Bit()));
    }
    return QString();
}

// Parse a license template, scan for %KEYWORD% and replace if known.
// Replace '%%' by '%'.
static void parseLicenseTemplatePlaceholders(QString *t)
{
    int pos = 0;
    const QChar placeHolder = QLatin1Char('%');
    do {
        const int placeHolderPos = t->indexOf(placeHolder, pos);
        if (placeHolderPos == -1)
            break;
        const int endPlaceHolderPos = t->indexOf(placeHolder, placeHolderPos + 1);
        if (endPlaceHolderPos == -1)
            break;
        if (endPlaceHolderPos == placeHolderPos + 1) { // '%%' -> '%'
            t->remove(placeHolderPos, 1);
            pos = placeHolderPos + 1;
        } else {
            const QString keyWord = t->mid(placeHolderPos, endPlaceHolderPos + 1 - placeHolderPos);
            const QString replacement = keyWordReplacement(keyWord);
            if (replacement.isEmpty()) {
                pos = endPlaceHolderPos + 1;
            } else {
                t->replace(placeHolderPos, keyWord.size(), replacement);
                pos = placeHolderPos + replacement.size();
            }
        }
    } while (pos < t->size());
}

// Convenience that returns the formatted license template.
QString CppFileSettings::licenseTemplate()
{

    const QSettings *s = Core::ICore::instance()->settings();
    QString key = QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP);
    key += QLatin1Char('/');
    key += QLatin1String(licenseTemplatePathKeyC);
    const QString path = s->value(key, QString()).toString();
    if (path.isEmpty())
        return QString();
    QFile file(path);
    if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) {
        qWarning("Unable to open the license template %s: %s", qPrintable(path), qPrintable(file.errorString()));
        return QString();
    }
    QString license = QString::fromUtf8(file.readAll());
    parseLicenseTemplatePlaceholders(&license);
    // Ensure exactly one additional new line separating stuff
    const QChar newLine = QLatin1Char('\n');
    if (!license.endsWith(newLine))
        license += newLine;
    license += newLine;
    return license;
}

// ------------------ CppFileSettingsWidget

CppFileSettingsWidget::CppFileSettingsWidget(QWidget *parent) :
    QWidget(parent),
    m_ui(new Ui::CppFileSettingsPage)
{
    m_ui->setupUi(this);
    const Core::MimeDatabase *mdb = Core::ICore::instance()->mimeDatabase();
    // populate suffix combos
    if (const Core::MimeType sourceMt = mdb->findByType(QLatin1String(CppTools::Constants::CPP_SOURCE_MIMETYPE)))
        foreach (const QString &suffix, sourceMt.suffixes())
            m_ui->sourceSuffixComboBox->addItem(suffix);

    if (const Core::MimeType headerMt = mdb->findByType(QLatin1String(CppTools::Constants::CPP_HEADER_MIMETYPE)))
        foreach (const QString &suffix, headerMt.suffixes())
            m_ui->headerSuffixComboBox->addItem(suffix);
    m_ui->licenseTemplatePathChooser->setExpectedKind(Core::Utils::PathChooser::File);
    m_ui->licenseTemplatePathChooser->addButton(tr("Edit..."), this, SLOT(slotEdit()));
}

CppFileSettingsWidget::~CppFileSettingsWidget()
{
    delete m_ui;
}

QString CppFileSettingsWidget::licenseTemplatePath() const
{
    return m_ui->licenseTemplatePathChooser->path();
}

void CppFileSettingsWidget::setLicenseTemplatePath(const QString &lp)
{
    m_ui->licenseTemplatePathChooser->setPath(lp);
}

CppFileSettings CppFileSettingsWidget::settings() const
{
    CppFileSettings rc;
    rc.lowerCaseFiles = m_ui->lowerCaseFileNamesCheckBox->isChecked();
    rc.headerSuffix = m_ui->headerSuffixComboBox->currentText();
    rc.sourceSuffix = m_ui->sourceSuffixComboBox->currentText();
    rc.licenseTemplatePath = licenseTemplatePath();
    return rc;
}

static inline void setComboText(QComboBox *cb, const QString &text, int defaultIndex = 0)
{
    const int index = cb->findText(text);
    cb->setCurrentIndex(index == -1 ? defaultIndex: index);
}

void CppFileSettingsWidget::setSettings(const CppFileSettings &s)
{
    m_ui->lowerCaseFileNamesCheckBox->setChecked(s.lowerCaseFiles);
    setComboText(m_ui->headerSuffixComboBox, s.headerSuffix);
    setComboText(m_ui->sourceSuffixComboBox, s.sourceSuffix);
    setLicenseTemplatePath(s.licenseTemplatePath);
}

void CppFileSettingsWidget::slotEdit()
{
    QString path = licenseTemplatePath();
    // Edit existing file with C++
    if (!path.isEmpty()) {
        Core::EditorManager::instance()->openEditor(path, QLatin1String(CppEditor::Constants::CPPEDITOR_KIND));
        return;
    }
    // Pick a file name and write new template, edit with C++
    path = QFileDialog::getSaveFileName(this, tr("Choose a location for the new license template file"));
    if (path.isEmpty())
        return;
    QFile file(path);
    if (!file.open(QIODevice::WriteOnly|QIODevice::Text|QIODevice::Truncate)) {
        QMessageBox::warning(this, tr("Template write error"),
                             tr("Cannot write to %1: %2").arg(path, file.errorString()));
        return;
    }
    file.write(tr(licenseTemplateTemplate).toUtf8());
    file.close();
    setLicenseTemplatePath(path);
    Core::EditorManager::instance()->openEditor(path, QLatin1String(CppEditor::Constants::CPPEDITOR_KIND));
}

// --------------- CppFileSettingsPage
CppFileSettingsPage::CppFileSettingsPage(QSharedPointer<CppFileSettings> &settings,
                                         QObject *parent) :
    Core::IOptionsPage(parent),
    m_settings(settings)
{
}

CppFileSettingsPage::~CppFileSettingsPage()
{
}

QString CppFileSettingsPage::id() const
{
    return QLatin1String(Constants::CPP_SETTINGS_ID);
}

QString CppFileSettingsPage::trName() const
{
    return QCoreApplication::translate("CppTools", Constants::CPP_SETTINGS_ID);
}

QString CppFileSettingsPage::category() const
{
    return QLatin1String(Constants::CPP_SETTINGS_CATEGORY);
}

QString CppFileSettingsPage::trCategory() const
{
    return QCoreApplication::translate("CppTools", Constants::CPP_SETTINGS_CATEGORY);
}

QWidget *CppFileSettingsPage::createPage(QWidget *parent)
{

    m_widget = new CppFileSettingsWidget(parent);
    m_widget->setSettings(*m_settings);
    return m_widget;
}

void CppFileSettingsPage::apply()
{
    if (m_widget) {
        const CppFileSettings newSettings = m_widget->settings();
        if (newSettings != *m_settings) {
            *m_settings = newSettings;
            m_settings->toSettings(Core::ICore::instance()->settings());
            m_settings->applySuffixesToMimeDB();
        }
    }
}

}
}

<|endoftext|>


<commit_before>#ifndef SOLAIRE_STL_OSTREAM_HPP
#define SOLAIRE_STL_OSTREAM_HPP

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

// Contact :
// Email             : solairelibrary@mail.com
// GitHub repository : https://github.com/SolaireLibrary/SolaireCPP

/*!
	\file STLOStream.hpp
	\brief
	\author
	Created			: Adam Smith
	Last modified	: Adam Smith
	\date
	Created			: 12th January 2016
	Last Modified	: 12th January 2016
*/

#include <ostream>
#include "Solaire/Core/OStream.hpp"

namespace Solaire {

	class STLOStream : public OStream {
    private:
        std::ostream& mStream;
    private:
        // Inherited from OStream

        void SOLAIRE_EXPORT_CALL writeU8(const uint8_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeU16(const uint16_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeU32(const uint32_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeU64(const uint64_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeI8(const int8_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeI16(const int16_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeI32(const int32_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeI64(const int64_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeF(const float aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeD(const double aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeC(const char aValue) throw() override {
            mStream << aValue;
        }

    public:
        STLOStream(std::ostream& aStream) :
            mStream(aStream)
        {}

        SOLAIRE_EXPORT_CALL ~STLOStream() {

        }

        // Inherited from OStream

        void SOLAIRE_EXPORT_CALL write(const void* const aPtr, const uint32_t aBytes) throw() override {
            mStream.write(static_cast<const char*>(aPtr), aBytes);
        }

        bool SOLAIRE_EXPORT_CALL isOffsetable() const throw() override {
            //! \todo Check if mStream is offsetable
            return true;
        }

        int32_t SOLAIRE_EXPORT_CALL getOffset() const throw() override {
            return mStream.tellp();
        }

        bool SOLAIRE_EXPORT_CALL setOffset(const int32_t aOffset) throw() override {
            mStream.seekp(aOffset, std::ios::beg);
            return true;
        }

    };

    static STLOStream STD_OUT(std::cout);
    static STLOStream STD_ERR(std::cerr);
    static constexpr char END_LINE = '\n';

}

#endif
<commit_msg>Fixed STD_OUT<commit_after>#ifndef SOLAIRE_STL_OSTREAM_HPP
#define SOLAIRE_STL_OSTREAM_HPP

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

// Contact :
// Email             : solairelibrary@mail.com
// GitHub repository : https://github.com/SolaireLibrary/SolaireCPP

/*!
	\file STLOStream.hpp
	\brief
	\author
	Created			: Adam Smith
	Last modified	: Adam Smith
	\date
	Created			: 12th January 2016
	Last Modified	: 12th January 2016
*/

#include <iostream>
#include "Solaire/Core/OStream.hpp"

namespace Solaire {

	class STLOStream : public OStream {
    private:
        std::ostream& mStream;
    private:
        // Inherited from OStream

        void SOLAIRE_EXPORT_CALL writeU8(const uint8_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeU16(const uint16_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeU32(const uint32_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeU64(const uint64_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeI8(const int8_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeI16(const int16_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeI32(const int32_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeI64(const int64_t aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeF(const float aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeD(const double aValue) throw() override {
            mStream << aValue;
        }

        void SOLAIRE_EXPORT_CALL writeC(const char aValue) throw() override {
            mStream << aValue;
        }

    public:
        STLOStream(std::ostream& aStream) :
            mStream(aStream)
        {}

        SOLAIRE_EXPORT_CALL ~STLOStream() {

        }

        // Inherited from OStream

        void SOLAIRE_EXPORT_CALL write(const void* const aPtr, const uint32_t aBytes) throw() override {
            mStream.write(static_cast<const char*>(aPtr), aBytes);
        }

        bool SOLAIRE_EXPORT_CALL isOffsetable() const throw() override {
            //! \todo Check if mStream is offsetable
            return true;
        }

        int32_t SOLAIRE_EXPORT_CALL getOffset() const throw() override {
            return mStream.tellp();
        }

        bool SOLAIRE_EXPORT_CALL setOffset(const int32_t aOffset) throw() override {
            mStream.seekp(aOffset, std::ios::beg);
            return true;
        }

    };

    static STLOStream STD_OUT(std::cout);
    static STLOStream STD_ERR(std::cerr);
    static constexpr char END_LINE = '\n';

}

#endif
<|endoftext|>


<commit_before>/**
 * @file save_restore_utility.hpp
 * @author Neil Slagle
 *
 * The SaveRestoreUtility provides helper functions in saving and
 *   restoring models.  The current output file type is XML.
 *
 * @experimental
 */
#ifndef __MLPACK_CORE_UTIL_SAVE_RESTORE_UTILITY_HPP
#define __MLPACK_CORE_UTIL_SAVE_RESTORE_UTILITY_HPP

#include <mlpack/prereqs.hpp>
#include <list>
#include <map>
#include <sstream>
#include <string>

#include <libxml/parser.h>
#include <libxml/tree.h>

#include <boost/tokenizer.hpp>

namespace mlpack {
namespace util {

class SaveRestoreUtility
{
 private:
  /**
   * parameters contains a list of names and parameters in string form.
   */
  std::map<std::string, std::string> parameters;

  /**
   * children contains a list of names in string format and child
   * models in the model hierarchy in SaveRestoreUtility format
   */
  std::map<std::string, SaveRestoreUtility> children;

  /**
   * RecurseOnNodes performs a depth first search of the XML tree.
   */
  void RecurseOnNodes(xmlNode* n);

 public:

  SaveRestoreUtility() {}
  ~SaveRestoreUtility() { parameters.clear(); }

  /**
   * ReadFile reads an XML tree from a file.
   */
  bool ReadFile(const std::string& filename);

  /**
   * WriteFile writes the XML tree to a file.
   */
  bool WriteFile(const std::string& filename);

  /**
   * LoadParameter loads a parameter from the parameters map.
   */
  template<typename T>
  T& LoadParameter(T& t, const std::string& name) const;

  /**
   * LoadParameter loads a parameter from the parameters map.
   */
  template<typename T>
  std::vector<T>& LoadParameter(std::vector<T>& v, const std::string& name)
      const;

  /**
   * LoadParameter loads a character from the parameters map.
   */
  char LoadParameter(char c, const std::string& name) const;

  /**
   * LoadParameter loads a string from the parameters map.
   */
  std::string LoadParameter(std::string& str, const std::string& name) const;

  /**
   * LoadParameter loads an arma::mat from the parameters map.
   */
  arma::mat& LoadParameter(arma::mat& matrix, const std::string& name) const;

  /**
   * SaveParameter saves a parameter to the parameters map.
   */
  template<typename T>
  void SaveParameter(const T& t, const std::string& name);

  /**
   * SaveParameter saves a parameter to the parameters map.
   */
  template<typename T>
  void SaveParameter(const std::vector<T>& v, const std::string& name);

  /**
   * SaveParameter saves a character to the parameters map.
   */
  void SaveParameter(const char c, const std::string& name);

  /**
   * SaveParameter saves an arma::mat to the parameters map.
   */
  void SaveParameter(const arma::mat& mat, const std::string& name);

  /**
   * SaveSubModel saves a SaveRestoreUtility to the children map.
   */
  void AddChild(SaveRestoreUtility& mn, const std::string& name);

  /**
   * Return the children.
   */
  const std::map<std::string, SaveRestoreUtility> Children() const { return
    children; }

  /**
   * Return modifiable copy of the children.
   */
  std::map<std::string, SaveRestoreUtility> Children() { return children; }

 private:
  /**
  * WriteFile creates XML tree recursively.
  */
  void WriteFile(xmlNode* n);

  /**
   * ReadFile reads an XML tree recursively.
   */
  void ReadFile(xmlNode* n);

};

//! Specialization for arma::vec.
template<>
arma::vec& SaveRestoreUtility::LoadParameter(arma::vec& t,
                                             const std::string& name) const;

//! Specialization for arma::vec.
template<>
void SaveRestoreUtility::SaveParameter(const arma::vec& t,
                                       const std::string& name);

}; /* namespace util */
}; /* namespace mlpack */

// Include implementation.
#include "save_restore_utility_impl.hpp"

#endif
<commit_msg>Simple spacing fix.<commit_after>/**
 * @file save_restore_utility.hpp
 * @author Neil Slagle
 *
 * The SaveRestoreUtility provides helper functions in saving and
 *   restoring models.  The current output file type is XML.
 *
 * @experimental
 */
#ifndef __MLPACK_CORE_UTIL_SAVE_RESTORE_UTILITY_HPP
#define __MLPACK_CORE_UTIL_SAVE_RESTORE_UTILITY_HPP

#include <mlpack/prereqs.hpp>
#include <list>
#include <map>
#include <sstream>
#include <string>

#include <libxml/parser.h>
#include <libxml/tree.h>

#include <boost/tokenizer.hpp>

namespace mlpack {
namespace util {

class SaveRestoreUtility
{
 private:
  /**
   * parameters contains a list of names and parameters in string form.
   */
  std::map<std::string, std::string> parameters;

  /**
   * children contains a list of names in string format and child
   * models in the model hierarchy in SaveRestoreUtility format
   */
  std::map<std::string, SaveRestoreUtility> children;

  /**
   * RecurseOnNodes performs a depth first search of the XML tree.
   */
  void RecurseOnNodes(xmlNode* n);

 public:

  SaveRestoreUtility() {}
  ~SaveRestoreUtility() { parameters.clear(); }

  /**
   * ReadFile reads an XML tree from a file.
   */
  bool ReadFile(const std::string& filename);

  /**
   * WriteFile writes the XML tree to a file.
   */
  bool WriteFile(const std::string& filename);

  /**
   * LoadParameter loads a parameter from the parameters map.
   */
  template<typename T>
  T& LoadParameter(T& t, const std::string& name) const;

  /**
   * LoadParameter loads a parameter from the parameters map.
   */
  template<typename T>
  std::vector<T>& LoadParameter(std::vector<T>& v, const std::string& name)
      const;

  /**
   * LoadParameter loads a character from the parameters map.
   */
  char LoadParameter(char c, const std::string& name) const;

  /**
   * LoadParameter loads a string from the parameters map.
   */
  std::string LoadParameter(std::string& str, const std::string& name) const;

  /**
   * LoadParameter loads an arma::mat from the parameters map.
   */
  arma::mat& LoadParameter(arma::mat& matrix, const std::string& name) const;

  /**
   * SaveParameter saves a parameter to the parameters map.
   */
  template<typename T>
  void SaveParameter(const T& t, const std::string& name);

  /**
   * SaveParameter saves a parameter to the parameters map.
   */
  template<typename T>
  void SaveParameter(const std::vector<T>& v, const std::string& name);

  /**
   * SaveParameter saves a character to the parameters map.
   */
  void SaveParameter(const char c, const std::string& name);

  /**
   * SaveParameter saves an arma::mat to the parameters map.
   */
  void SaveParameter(const arma::mat& mat, const std::string& name);

  /**
   * SaveSubModel saves a SaveRestoreUtility to the children map.
   */
  void AddChild(SaveRestoreUtility& mn, const std::string& name);

  /**
   * Return the children.
   */
  const std::map<std::string, SaveRestoreUtility> Children() const { return
    children; }

  /**
   * Return modifiable copy of the children.
   */
  std::map<std::string, SaveRestoreUtility> Children() { return children; }

 private:
  /**
   * WriteFile creates XML tree recursively.
   */
  void WriteFile(xmlNode* n);

  /**
   * ReadFile reads an XML tree recursively.
   */
  void ReadFile(xmlNode* n);
};

//! Specialization for arma::vec.
template<>
arma::vec& SaveRestoreUtility::LoadParameter(arma::vec& t,
                                             const std::string& name) const;

//! Specialization for arma::vec.
template<>
void SaveRestoreUtility::SaveParameter(const arma::vec& t,
                                       const std::string& name);

}; /* namespace util */
}; /* namespace mlpack */

// Include implementation.
#include "save_restore_utility_impl.hpp"

#endif
<|endoftext|>


<commit_before>#include "writeback.h"

#include <cassert>
#include <sstream>

template <typename ISA>
Writeback<ISA>::Writeback(bool log) : Log( log)
{
    rp_mem_datapath = make_read_port<Instr>("MEMORY_2_WRITEBACK", PORT_LATENCY);
    rp_execute_datapath = make_read_port<Instr>("EXECUTE_2_WRITEBACK", PORT_LATENCY);
    rp_branch_datapath = make_read_port<Instr>("BRANCH_2_WRITEBACK", PORT_LATENCY);

    wp_bypass = make_write_port<std::pair<RegisterUInt, RegisterUInt>>("WRITEBACK_2_EXECUTE_BYPASS", PORT_BW, SRC_REGISTERS_NUM);
    wp_halt = make_write_port<bool>("WRITEBACK_2_CORE_HALT", PORT_BW, PORT_FANOUT);
}

template <typename ISA>
void Writeback<ISA>::Checker::init( const FuncMemory& outer_mem)
{
    auto memory = FuncMemory::create_hierarchied_memory();
    sim = std::make_shared<FuncSim<ISA>>();
    outer_mem.duplicate_to( memory);
    sim->set_memory( std::move( memory));
    active = true;
}

template <typename ISA>
void Writeback<ISA>::Checker::set_target( const Target& value)
{
    if ( active)
        sim->set_target( value);
}

template<typename ISA>
void Writeback<ISA>::set_target( const Target& value)
{
    checker.set_target( value);
    next_PC = value.address;
}

template <typename ISA>
auto Writeback<ISA>::read_instructions( Cycle cycle)
{
    std::vector<Instr> result;
    for ( auto& port : { rp_branch_datapath.get(), rp_mem_datapath.get(), rp_execute_datapath.get()})
        if ( port->is_ready( cycle))
            result.emplace_back( port->read( cycle));

    return result;
}

template <typename ISA>
void Writeback<ISA>::clock( Cycle cycle)
{
    sout << "wb      cycle " << std::dec << cycle << ": ";

    auto instrs = read_instructions( cycle);

    if ( instrs.empty())
        writeback_bubble( cycle);
    else
        writeback_instruction( instrs.front(), cycle);
}

template <typename ISA>
void Writeback<ISA>::writeback_bubble( Cycle cycle)
{
    sout << "bubble\n";
    if ( cycle >= last_writeback_cycle + 100_lt)
        throw Deadlock( "");
}

template <typename ISA>
void Writeback<ISA>::writeback_instruction( const Writeback<ISA>::Instr& instr, Cycle cycle)
{
    rf->write_dst( instr);
    wp_bypass->write( std::make_pair(instr.get_v_dst(), instr.get_v_dst2()), cycle);

    sout << instr << std::endl;

    checker.check( instr);
    ++executed_instrs;
    last_writeback_cycle = cycle;
    next_PC = instr.get_actual_target().address;
    if ( executed_instrs >= instrs_to_run || instr.is_halt())
        wp_halt->write( true, cycle);

    sout << "Executed instructions: " << executed_instrs
         << std::endl << std::endl;
}

template <typename ISA>
void Writeback<ISA>::Checker::check( const FuncInstr& instr)
{
    if (!active)
        return;

    const auto func_dump = sim->step();

    if ( func_dump.is_same_checker(instr))
        return;

    std::ostringstream oss;
    oss << "Checker output: " << func_dump << std::endl
        << "PerfSim output: " << instr     << std::endl;

    throw CheckerMismatch(oss.str());
}

#include <mips/mips.h>
#include <risc_v/risc_v.h>

template class Writeback<MIPSI>;
template class Writeback<MIPSII>;
template class Writeback<MIPSIII>;
template class Writeback<MIPSIV>;
template class Writeback<MIPS32>;
template class Writeback<MIPS64>;
template class Writeback<RISCV32>;
template class Writeback<RISCV64>;
template class Writeback<RISCV128>;
<commit_msg>Optimize instruction writeback<commit_after>#include "writeback.h"

#include <cassert>
#include <sstream>

template <typename ISA>
Writeback<ISA>::Writeback(bool log) : Log( log)
{
    rp_mem_datapath = make_read_port<Instr>("MEMORY_2_WRITEBACK", PORT_LATENCY);
    rp_execute_datapath = make_read_port<Instr>("EXECUTE_2_WRITEBACK", PORT_LATENCY);
    rp_branch_datapath = make_read_port<Instr>("BRANCH_2_WRITEBACK", PORT_LATENCY);

    wp_bypass = make_write_port<std::pair<RegisterUInt, RegisterUInt>>("WRITEBACK_2_EXECUTE_BYPASS", PORT_BW, SRC_REGISTERS_NUM);
    wp_halt = make_write_port<bool>("WRITEBACK_2_CORE_HALT", PORT_BW, PORT_FANOUT);
}

template <typename ISA>
void Writeback<ISA>::Checker::init( const FuncMemory& outer_mem)
{
    auto memory = FuncMemory::create_hierarchied_memory();
    sim = std::make_shared<FuncSim<ISA>>();
    outer_mem.duplicate_to( memory);
    sim->set_memory( std::move( memory));
    active = true;
}

template <typename ISA>
void Writeback<ISA>::Checker::set_target( const Target& value)
{
    if ( active)
        sim->set_target( value);
}

template<typename ISA>
void Writeback<ISA>::set_target( const Target& value)
{
    checker.set_target( value);
    next_PC = value.address;
}

template <typename ISA>
auto Writeback<ISA>::read_instructions( Cycle cycle)
{
    auto ports = { rp_branch_datapath.get(), rp_mem_datapath.get(), rp_execute_datapath.get() };
    std::vector<Instr> result;
    result.reserve( ports.size());

    for ( auto& port : ports)
        if ( port->is_ready( cycle))
            result.emplace_back( port->read( cycle));

    return result;
}

template <typename ISA>
void Writeback<ISA>::clock( Cycle cycle)
{
    sout << "wb      cycle " << std::dec << cycle << ": ";

    auto instrs = read_instructions( cycle);

    if ( instrs.empty())
        writeback_bubble( cycle);
    else
        writeback_instruction( instrs.front(), cycle);
}

template <typename ISA>
void Writeback<ISA>::writeback_bubble( Cycle cycle)
{
    sout << "bubble\n";
    if ( cycle >= last_writeback_cycle + 100_lt)
        throw Deadlock( "");
}

template <typename ISA>
void Writeback<ISA>::writeback_instruction( const Writeback<ISA>::Instr& instr, Cycle cycle)
{
    rf->write_dst( instr);
    wp_bypass->write( std::make_pair(instr.get_v_dst(), instr.get_v_dst2()), cycle);

    sout << instr << std::endl;

    checker.check( instr);
    ++executed_instrs;
    last_writeback_cycle = cycle;
    next_PC = instr.get_actual_target().address;
    if ( executed_instrs >= instrs_to_run || instr.is_halt())
        wp_halt->write( true, cycle);

    sout << "Executed instructions: " << executed_instrs
         << std::endl << std::endl;
}

template <typename ISA>
void Writeback<ISA>::Checker::check( const FuncInstr& instr)
{
    if (!active)
        return;

    const auto func_dump = sim->step();

    if ( func_dump.is_same_checker(instr))
        return;

    std::ostringstream oss;
    oss << "Checker output: " << func_dump << std::endl
        << "PerfSim output: " << instr     << std::endl;

    throw CheckerMismatch(oss.str());
}

#include <mips/mips.h>
#include <risc_v/risc_v.h>

template class Writeback<MIPSI>;
template class Writeback<MIPSII>;
template class Writeback<MIPSIII>;
template class Writeback<MIPSIV>;
template class Writeback<MIPS32>;
template class Writeback<MIPS64>;
template class Writeback<RISCV32>;
template class Writeback<RISCV64>;
template class Writeback<RISCV128>;
<|endoftext|>