<commit_before>#include "vehicle.h"
#include "game/resources/vehiclefactory.h"
#include <cfloat>
#include <random>

std::default_random_engine rng;

namespace OpenApoc {

Vehicle::Vehicle(VehicleDefinition &def)
	: def(def)
{

}

Vehicle::~Vehicle()
{

}

class VehicleRandomWalk : public VehicleMission
{
public:
	std::uniform_int_distribution<int> distribution;
	VehicleRandomWalk(Vehicle &vehicle)
		: VehicleMission(vehicle), distribution(-1,1)
			{};
	virtual Vec3<float> getNextDestination()
	{
		FlyingVehicle &v = dynamic_cast<FlyingVehicle&>(*this->vehicle.tileObject);
		TileMap &map = v.owningTile->map;
		Vec3<int> nextPosition;
		int tries = 0;
		do {
			nextPosition = {v.position.x, v.position.y, v.position.z};
			Vec3<int> diff {distribution(rng), distribution(rng), distribution(rng)};
			nextPosition += diff;
			//FIXME HACK - abort after some attempts (e.g. if we're completely trapped)
			//and just phase through whatever obstruction is there
			tries++;
			//Keep looping until we find an empty tile within the map
		} while (nextPosition.x >= map.size.x || nextPosition.x < 0 ||
			nextPosition.y >= map.size.y || nextPosition.y < 0 ||
			nextPosition.z >= map.size.z || nextPosition.z < 0
			//FIXME: Proper routing/obstruction handling
			//(This below could cause an infinite loop if a vehicle gets 'trapped'
			|| (tries < 50 && !map.tiles[nextPosition.z][nextPosition.y][nextPosition.z].objects.empty()));
		return Vec3<float>{nextPosition.x, nextPosition.y, nextPosition.z};
	}
};

class FlyingVehicleMover : public VehicleMover
{
public:
	Vec3<float> goalPosition;
	float speed;
	FlyingVehicleMover(Vehicle &v)
		: VehicleMover(v)
	{
		std::uniform_real_distribution<float> distribution(-0.02, 0.02);
		goalPosition.x = -1.0f;
		//Tweak the speed slightly, makes everything a little less synchronised
		speed = 0.05 + distribution(rng);
	}
	virtual void update(unsigned int ticks)
	{
		FlyingVehicle &v = dynamic_cast<FlyingVehicle&>(*this->vehicle.tileObject);
		if (goalPosition.x == -1.0f)
			goalPosition = v.mission->getNextDestination();
		float distanceLeft = speed * ticks;
		while (distanceLeft > 0)
		{
			Vec3<float> vectorToGoal = goalPosition -
				v.position;
			float distanceToGoal = glm::length(vectorToGoal);
			if (distanceToGoal <= distanceLeft)
			{
				distanceLeft -= distanceToGoal;
				v.position = goalPosition;
				goalPosition = v.mission->getNextDestination();
			}
			else
			{
				v.direction = vectorToGoal;
				v.position += distanceLeft * glm::normalize(vectorToGoal);
				distanceLeft = -1;
			}
		}
		Vec3<int> currentTile{v.position.x, v.position.y, v.position.z};
		if (currentTile != v.owningTile->position)
		{
			for (auto o : v.owningTile->objects)
			{
				if (o.get() == &v)
				{
					auto &map = v.owningTile->map;
					v.owningTile->objects.remove(o);
					v.owningTile = &map.tiles[currentTile.z][currentTile.y][currentTile.x];
					v.owningTile->objects.push_back(o);
					break;
				}
			}
		}

		//FIXME: change owning tile?
		//I've possibly backed myself into a corner here, how I can 'change' the owning tile
		//when the update loop is current iterating over said list? Removing it causes the
		//parent iterator to become invalid (crashing), and adding it to a new tile
		//could cause it to be updated again when /that/ tile is processed.
	}
};

VehicleMission::VehicleMission(Vehicle &v)
	: vehicle(v)
{

}

VehicleMission::~VehicleMission()
{

}

VehicleMover::VehicleMover(Vehicle &v)
: vehicle(v)
{

}

VehicleMover::~VehicleMover()
{

}
FlyingVehicle::FlyingVehicle(Vehicle &vehicle, Tile *owningTile)
	: TileObject(owningTile, Vec3<float>(owningTile->position), vehicle.def.size, true, true, std::shared_ptr<Image>(nullptr)), vehicle(vehicle), direction(0, 1, 0)
{
	assert(!vehicle.tileObject);
	this->mission.reset(new VehicleRandomWalk(vehicle));
	this->mover.reset(new FlyingVehicleMover(vehicle));

}

FlyingVehicle::~FlyingVehicle()
{

}

void
FlyingVehicle::update(unsigned int ticks)
{
	if (this->mover)
		mover->update(ticks);
}

const std::vector<std::pair<Vec3<float>, Vehicle::Direction>> directions =
{
	{{ 0, 1, 0}, Vehicle::Direction::N},
	{{ 1, 1, 0}, Vehicle::Direction::NE},
	{{ 1, 0, 0}, Vehicle::Direction::E},
	{{ 1,-1, 0}, Vehicle::Direction::SE},
	{{ 0,-1, 0}, Vehicle::Direction::S},
	{{-1,-1, 0}, Vehicle::Direction::SW},
	{{-1, 0, 0}, Vehicle::Direction::W},
	{{-1, 1, 0}, Vehicle::Direction::NW},
};

static Vehicle::Direction findClosestDirection(Vec3<float> v)
{
	Vehicle::Direction d = Vehicle::Direction::N;
	//Reset Z (We don't care about ascending/decending)
	v.z = 0;
	float a = FLT_MAX;
	for (auto &p : directions)
	{
		float angle = fabs(glm::angle(glm::normalize(p.first), glm::normalize(v)));
		if (angle < a)
		{
			a = angle;
			d = p.second;
		}
	}
	return d;
}

Image&
FlyingVehicle::getSprite()
{
	//TODO: Banking selection logic
	Vehicle::Direction d = findClosestDirection(this->direction);
	return *this->vehicle.def.sprites[Vehicle::Banking::Flat][d];
}

void
FlyingVehicle::processCollision(TileObject &otherObject)
{
	//TODO: Vehicle collision
}

}; //namespace OpenApoc
<commit_msg>Fix vehicle direction spritest (N/S was inverted)<commit_after>#include "vehicle.h"
#include "game/resources/vehiclefactory.h"
#include <cfloat>
#include <random>

std::default_random_engine rng;

namespace OpenApoc {

Vehicle::Vehicle(VehicleDefinition &def)
	: def(def)
{

}

Vehicle::~Vehicle()
{

}

class VehicleRandomWalk : public VehicleMission
{
public:
	std::uniform_int_distribution<int> distribution;
	VehicleRandomWalk(Vehicle &vehicle)
		: VehicleMission(vehicle), distribution(-1,1)
			{};
	virtual Vec3<float> getNextDestination()
	{
		FlyingVehicle &v = dynamic_cast<FlyingVehicle&>(*this->vehicle.tileObject);
		TileMap &map = v.owningTile->map;
		Vec3<int> nextPosition;
		int tries = 0;
		do {
			nextPosition = {v.position.x, v.position.y, v.position.z};
			Vec3<int> diff {distribution(rng), distribution(rng), distribution(rng)};
			nextPosition += diff;
			//FIXME HACK - abort after some attempts (e.g. if we're completely trapped)
			//and just phase through whatever obstruction is there
			tries++;
			//Keep looping until we find an empty tile within the map
		} while (nextPosition.x >= map.size.x || nextPosition.x < 0 ||
			nextPosition.y >= map.size.y || nextPosition.y < 0 ||
			nextPosition.z >= map.size.z || nextPosition.z < 0
			//FIXME: Proper routing/obstruction handling
			//(This below could cause an infinite loop if a vehicle gets 'trapped'
			|| (tries < 50 && !map.tiles[nextPosition.z][nextPosition.y][nextPosition.z].objects.empty()));
		return Vec3<float>{nextPosition.x, nextPosition.y, nextPosition.z};
	}
};

class FlyingVehicleMover : public VehicleMover
{
public:
	Vec3<float> goalPosition;
	float speed;
	FlyingVehicleMover(Vehicle &v)
		: VehicleMover(v)
	{
		std::uniform_real_distribution<float> distribution(-0.02, 0.02);
		goalPosition.x = -1.0f;
		//Tweak the speed slightly, makes everything a little less synchronised
		speed = 0.05 + distribution(rng);
	}
	virtual void update(unsigned int ticks)
	{
		FlyingVehicle &v = dynamic_cast<FlyingVehicle&>(*this->vehicle.tileObject);
		if (goalPosition.x == -1.0f)
			goalPosition = v.mission->getNextDestination();
		float distanceLeft = speed * ticks;
		while (distanceLeft > 0)
		{
			Vec3<float> vectorToGoal = goalPosition -
				v.position;
			float distanceToGoal = glm::length(vectorToGoal);
			if (distanceToGoal <= distanceLeft)
			{
				distanceLeft -= distanceToGoal;
				v.position = goalPosition;
				goalPosition = v.mission->getNextDestination();
			}
			else
			{
				v.direction = vectorToGoal;
				v.position += distanceLeft * glm::normalize(vectorToGoal);
				distanceLeft = -1;
			}
		}
		Vec3<int> currentTile{v.position.x, v.position.y, v.position.z};
		if (currentTile != v.owningTile->position)
		{
			for (auto o : v.owningTile->objects)
			{
				if (o.get() == &v)
				{
					auto &map = v.owningTile->map;
					v.owningTile->objects.remove(o);
					v.owningTile = &map.tiles[currentTile.z][currentTile.y][currentTile.x];
					v.owningTile->objects.push_back(o);
					break;
				}
			}
		}

		//FIXME: change owning tile?
		//I've possibly backed myself into a corner here, how I can 'change' the owning tile
		//when the update loop is current iterating over said list? Removing it causes the
		//parent iterator to become invalid (crashing), and adding it to a new tile
		//could cause it to be updated again when /that/ tile is processed.
	}
};

VehicleMission::VehicleMission(Vehicle &v)
	: vehicle(v)
{

}

VehicleMission::~VehicleMission()
{

}

VehicleMover::VehicleMover(Vehicle &v)
: vehicle(v)
{

}

VehicleMover::~VehicleMover()
{

}
FlyingVehicle::FlyingVehicle(Vehicle &vehicle, Tile *owningTile)
	: TileObject(owningTile, Vec3<float>(owningTile->position), vehicle.def.size, true, true, std::shared_ptr<Image>(nullptr)), vehicle(vehicle), direction(0, 1, 0)
{
	assert(!vehicle.tileObject);
	this->mission.reset(new VehicleRandomWalk(vehicle));
	this->mover.reset(new FlyingVehicleMover(vehicle));

}

FlyingVehicle::~FlyingVehicle()
{

}

void
FlyingVehicle::update(unsigned int ticks)
{
	if (this->mover)
		mover->update(ticks);
}

const std::vector<std::pair<Vec3<float>, Vehicle::Direction>> directions =
{
	{{ 0,-1, 0}, Vehicle::Direction::N},
	{{ 1,-1, 0}, Vehicle::Direction::NE},
	{{ 1, 0, 0}, Vehicle::Direction::E},
	{{ 1, 1, 0}, Vehicle::Direction::SE},
	{{ 0, 1, 0}, Vehicle::Direction::S},
	{{-1, 1, 0}, Vehicle::Direction::SW},
	{{-1, 0, 0}, Vehicle::Direction::W},
	{{-1,-1, 0}, Vehicle::Direction::NW},
};

static Vehicle::Direction findClosestDirection(Vec3<float> v)
{
	Vehicle::Direction d = Vehicle::Direction::N;
	//Reset Z (We don't care about ascending/decending)
	v.z = 0;
	float a = FLT_MAX;
	for (auto &p : directions)
	{
		float angle = fabs(glm::angle(glm::normalize(p.first), glm::normalize(v)));
		if (angle < a)
		{
			a = angle;
			d = p.second;
		}
	}
	return d;
}

Image&
FlyingVehicle::getSprite()
{
	//TODO: Banking selection logic
	Vehicle::Direction d = findClosestDirection(this->direction);
	return *this->vehicle.def.sprites[Vehicle::Banking::Flat][d];
}

void
FlyingVehicle::processCollision(TileObject &otherObject)
{
	//TODO: Vehicle collision
}

}; //namespace OpenApoc
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 deipi.com LLC and contributors. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "exception.h"

#include "log.h"

#include <string.h>
#include <execinfo.h>
#include <cxxabi.h>
#include <stdarg.h>

#define BUFFER_SIZE 1024

const char* Error::init_traceback()
{
	void* callstack[128];

	// retrieve current stack addresses
	int frames = backtrace(callstack, sizeof(callstack) / sizeof(void*));

	traceback = "Traceback:";

	if (frames == 0) {
		traceback += "\n    <empty, possibly corrupt>";
		return traceback.c_str();
	}

	// resolve addresses into strings containing "filename(function+address)"
	char** strs = backtrace_symbols(callstack, frames);

	// iterate over the returned symbol lines. skip the first, it is the
	// address of this function.
	for (int i = 0; i < frames; i++) {
		int status = 0;
		const char *sep = "\t ()+";
		char *mangled, *lasts;
		std::string result;
		for (mangled = strtok_r(strs[i], sep, &lasts); mangled; mangled = strtok_r(nullptr, sep, &lasts)) {
			char* unmangled = abi::__cxa_demangle(mangled, NULL, 0, &status);
			if (!result.empty()) {
				result += " ";
			}
			if (status == 0) {
				result += unmangled;
			} else {
				result += mangled;
			}
			free(unmangled);
		}
		traceback += "\n    " + result;
	}

	free(strs);

	return traceback.c_str();
}

Error::Error(const char *filename, int line, const char *format, ...)
	: std::runtime_error("")
{
	char buffer[BUFFER_SIZE];

	va_list argptr;
	va_start(argptr, format);
	vsnprintf(buffer, BUFFER_SIZE, format, argptr);
	va_end(argptr);
	msg.assign(buffer);

	snprintf(buffer, BUFFER_SIZE, "%s:%d", filename, line);
	context.assign(std::string(buffer) + ": " + msg);

	L_TRACEBACK("%s\n", init_traceback());
}
<commit_msg>Tweaks<commit_after>/*
 * Copyright (C) 2015 deipi.com LLC and contributors. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "exception.h"

#include "log.h"

#include <string.h>
#include <execinfo.h>
#include <cxxabi.h>
#include <stdarg.h>

#define BUFFER_SIZE 1024

const char*
Error::init_traceback()
{
	void* callstack[128];

	// retrieve current stack addresses
	int frames = backtrace(callstack, sizeof(callstack) / sizeof(void*));

	traceback = "Traceback:";

	if (frames == 0) {
		traceback += "\n    <empty, possibly corrupt>";
		return traceback.c_str();
	}

	// resolve addresses into strings containing "filename(function+address)"
	char** strs = backtrace_symbols(callstack, frames);

	// iterate over the returned symbol lines. skip the first, it is the
	// address of this function.
	for (int i = 0; i < frames; ++i) {
		int status = 0;
		const char *sep = "\t ()+";
		char *mangled, *lasts;
		std::string result;
		for (mangled = strtok_r(strs[i], sep, &lasts); mangled; mangled = strtok_r(nullptr, sep, &lasts)) {
			char* unmangled = abi::__cxa_demangle(mangled, nullptr, 0, &status);
			if (!result.empty()) {
				result += " ";
			}
			if (status == 0) {
				result += unmangled;
			} else {
				result += mangled;
			}
			free(unmangled);
		}
		traceback += "\n    " + result;
	}

	free(strs);

	return traceback.c_str();
}

Error::Error(const char *filename, int line, const char *format, ...)
	: std::runtime_error("")
{
	char buffer[BUFFER_SIZE];

	va_list argptr;
	va_start(argptr, format);
	vsnprintf(buffer, BUFFER_SIZE, format, argptr);
	va_end(argptr);
	msg.assign(buffer);

	snprintf(buffer, BUFFER_SIZE, "%s:%d", filename, line);
	context.assign(std::string(buffer) + ": " + msg);

	L_TRACEBACK("%s\n", init_traceback());
}
<|endoftext|>


<commit_before>//@+leo-ver=5-thin
//@+node:gcross.20110520211700.1400: * @file error.cpp
//@@language cplusplus

//@+<< License >>
//@+node:gcross.20110520211700.1401: ** << License >>
//@+at
// Copyright (c) 2011, Gregory Crosswhite
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//@@c
//@-<< License >>

//@+<< Includes >>
//@+node:gcross.20110520211700.1402: ** << Includes >>
#include "error.hpp"

#include <boost/foreach.hpp>
#include <boost/scoped_array.hpp>
#include <iomanip>
#include <sstream>
//@-<< Includes >>

namespace HDF {

//@+<< Usings >>
//@+node:gcross.20110520211700.1403: ** << Usings >>
using boost::scoped_array;

using std::endl;
using std::ostringstream;
using std::setw;
using std::string;
using std::vector;
//@-<< Usings >>

//@+others
//@+node:gcross.20110520211700.1407: ** Classes
//@+node:gcross.20110520211700.1409: *3* Error
Error::Error(string const& description) {
    H5Ewalk(H5E_DEFAULT,H5E_WALK_UPWARD,&ErrorStackFrame::constructAndPush,&error_stack);

    ostringstream buffer;
    buffer << "Error occurred while " << description << ":\n";

    unsigned int n;
    BOOST_FOREACH(ErrorStackFrame const& frame, error_stack) {
        buffer << "    " << setw(3) << (++n) << ": " << frame.source_filename << " line " << frame.source_line << " in " << frame.source_function << "()" << endl;
        buffer << "    " << " - class:  " << frame.class_name << endl;
        buffer << "    " << " - major: " << frame.major_message << endl;
        buffer << "    " << " - minor: " << frame.minor_message << endl;
    }

    message = buffer.str();
}

Error::~Error() throw() {}

H5E_auto_t Error::hdf_func = NULL;
void* Error::hdf_client_data = NULL;

void Error::disableHDFErrorReporting() {
    H5Eset_auto(H5E_DEFAULT,NULL,NULL);
}

void Error::enableHDFErrorReporting() {
    H5Eset_auto(H5E_DEFAULT,hdf_func,hdf_client_data);
}

Error::AutomaticDisabler::AutomaticDisabler() {
    H5Eget_auto(H5E_DEFAULT,&hdf_func,&hdf_client_data);
    disableHDFErrorReporting();
}

Error::AutomaticDisabler Error::automatic_disabler;
//@+node:gcross.20110520211700.1408: *3* ErrorStackFrame
ErrorStackFrame::ErrorStackFrame(H5E_error2_t const& error_descriptor)
  : source_filename(error_descriptor.file_name)
  , source_line(error_descriptor.line)
  , source_function(error_descriptor.func_name)
{
    {
        size_t size = H5Eget_class_name(error_descriptor.cls_id,NULL,0);
        scoped_array<char> data(new char[size+1]);
        H5Eget_class_name(error_descriptor.cls_id,data.get(),size+1);
        class_name = data.get();
    }
    {
        size_t size = H5Eget_msg(error_descriptor.maj_num,NULL,NULL,0);
        scoped_array<char> data(new char[size+1]);
        H5Eget_msg(error_descriptor.maj_num,NULL,data.get(),size+1);
        major_message = data.get();
    }
    {
        size_t size = H5Eget_msg(error_descriptor.min_num,NULL,NULL,0);
        scoped_array<char> data(new char[size+1]);
        H5Eget_msg(error_descriptor.min_num,NULL,data.get(),size+1);
        minor_message = data.get();
    }
}

herr_t ErrorStackFrame::constructAndPush(unsigned int n, H5E_error2_t const *err_desc, vector<ErrorStackFrame>* stack) {
    stack->push_back(ErrorStackFrame(*err_desc));
    return 0;
}

herr_t ErrorStackFrame::constructAndPush(unsigned int n, H5E_error2_t const *err_desc, void* stack) {
    return constructAndPush(n,err_desc,static_cast<vector<ErrorStackFrame>*>(stack));
}
//@+node:gcross.20110521115623.2762: *3* Exception
Exception::Exception() {}

Exception::Exception(string const& message) : message(message) { }

const char* Exception::what() const throw() { return message.c_str(); }

Exception::~Exception() throw() { }
//@-others

}
//@-leo
<commit_msg>Fixed a bug where I forgot to initialize a counter to zero.<commit_after>//@+leo-ver=5-thin
//@+node:gcross.20110520211700.1400: * @file error.cpp
//@@language cplusplus

//@+<< License >>
//@+node:gcross.20110520211700.1401: ** << License >>
//@+at
// Copyright (c) 2011, Gregory Crosswhite
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//@@c
//@-<< License >>

//@+<< Includes >>
//@+node:gcross.20110520211700.1402: ** << Includes >>
#include "error.hpp"

#include <boost/foreach.hpp>
#include <boost/scoped_array.hpp>
#include <iomanip>
#include <sstream>
//@-<< Includes >>

namespace HDF {

//@+<< Usings >>
//@+node:gcross.20110520211700.1403: ** << Usings >>
using boost::scoped_array;

using std::endl;
using std::ostringstream;
using std::setw;
using std::string;
using std::vector;
//@-<< Usings >>

//@+others
//@+node:gcross.20110520211700.1407: ** Classes
//@+node:gcross.20110520211700.1409: *3* Error
Error::Error(string const& description) {
    H5Ewalk(H5E_DEFAULT,H5E_WALK_UPWARD,&ErrorStackFrame::constructAndPush,&error_stack);

    ostringstream buffer;
    buffer << "Error occurred while " << description << ":\n";

    unsigned int n = 0;
    BOOST_FOREACH(ErrorStackFrame const& frame, error_stack) {
        buffer << "    " << setw(3) << (++n) << ": " << frame.source_filename << " line " << frame.source_line << " in " << frame.source_function << "()" << endl;
        buffer << "    " << " - class:  " << frame.class_name << endl;
        buffer << "    " << " - major: " << frame.major_message << endl;
        buffer << "    " << " - minor: " << frame.minor_message << endl;
    }

    message = buffer.str();
}

Error::~Error() throw() {}

H5E_auto_t Error::hdf_func = NULL;
void* Error::hdf_client_data = NULL;

void Error::disableHDFErrorReporting() {
    H5Eset_auto(H5E_DEFAULT,NULL,NULL);
}

void Error::enableHDFErrorReporting() {
    H5Eset_auto(H5E_DEFAULT,hdf_func,hdf_client_data);
}

Error::AutomaticDisabler::AutomaticDisabler() {
    H5Eget_auto(H5E_DEFAULT,&hdf_func,&hdf_client_data);
    disableHDFErrorReporting();
}

Error::AutomaticDisabler Error::automatic_disabler;
//@+node:gcross.20110520211700.1408: *3* ErrorStackFrame
ErrorStackFrame::ErrorStackFrame(H5E_error2_t const& error_descriptor)
  : source_filename(error_descriptor.file_name)
  , source_line(error_descriptor.line)
  , source_function(error_descriptor.func_name)
{
    {
        size_t size = H5Eget_class_name(error_descriptor.cls_id,NULL,0);
        scoped_array<char> data(new char[size+1]);
        H5Eget_class_name(error_descriptor.cls_id,data.get(),size+1);
        class_name = data.get();
    }
    {
        size_t size = H5Eget_msg(error_descriptor.maj_num,NULL,NULL,0);
        scoped_array<char> data(new char[size+1]);
        H5Eget_msg(error_descriptor.maj_num,NULL,data.get(),size+1);
        major_message = data.get();
    }
    {
        size_t size = H5Eget_msg(error_descriptor.min_num,NULL,NULL,0);
        scoped_array<char> data(new char[size+1]);
        H5Eget_msg(error_descriptor.min_num,NULL,data.get(),size+1);
        minor_message = data.get();
    }
}

herr_t ErrorStackFrame::constructAndPush(unsigned int n, H5E_error2_t const *err_desc, vector<ErrorStackFrame>* stack) {
    stack->push_back(ErrorStackFrame(*err_desc));
    return 0;
}

herr_t ErrorStackFrame::constructAndPush(unsigned int n, H5E_error2_t const *err_desc, void* stack) {
    return constructAndPush(n,err_desc,static_cast<vector<ErrorStackFrame>*>(stack));
}
//@+node:gcross.20110521115623.2762: *3* Exception
Exception::Exception() {}

Exception::Exception(string const& message) : message(message) { }

const char* Exception::what() const throw() { return message.c_str(); }

Exception::~Exception() throw() { }
//@-others

}
//@-leo
<|endoftext|>


<commit_before>/*********************************************************************
 *
 * Copyright (C) 2007,  Simon Kagstrom
 *
 * Filename:      instruction.hh
 * Author:        Simon Kagstrom <simon.kagstrom@gmail.com>
 * Description:   Instruction class
 *
 * $Id:$
 *
 ********************************************************************/
#ifndef __INSTRUCTION_HH__
#define __INSTRUCTION_HH__

#include <mips.hh>
#include <registerallocator.hh>
#include <syscall.hh>
#include <entity.hh>

class JavaClass;
class BasicBlock;
class Function;

class Instruction : public Entity
{
public:
  Instruction(uint32_t address, int opcode,
	      MIPS_register_t rs, MIPS_register_t rt, MIPS_register_t rd, int32_t extra);

  virtual ~Instruction();

  virtual bool isBranch()
  {
    return false;
  }

  virtual bool isReturnJump()
  {
    return false;
  }

  virtual bool isRegisterIndirectJump()
  {
    return false;
  }

  mips_opcode_t getOpcode()
  {
    return (mips_opcode_t)this->opcode;
  }

  bool isBranchTarget()
  {
    return this->branchTarget;
  }

  void setBranchTarget();

  virtual bool isNop()
  {
    return false;
  }

  virtual bool pass1() = 0;

  virtual bool pass2() = 0;

  virtual int getMaxStackHeight()
  {
    return 2;
  }

  virtual bool hasDelaySlot()
  {
    return this->isBranch();
  }

  int addToRegisterUsage(MIPS_register_t reg, int *p)
  {
    if (reg == 0)
      return 0;
    p[reg]++;

    return 1;
  }

  /**
   * Fill in the register destinations
   *
   * @param p the destinations to fill in
   *
   * @return the number of destinations filled
   */
  virtual int fillDestinations(int *p) { return 0; };

  virtual int fillSources(int *p) { return 0; };

  void setDelayed(Instruction *delayed)
  {
    this->delayed = delayed;
  }

  Instruction *getDelayed()
  {
    return this->delayed;
  }

  void setPrefix(Instruction *prefix)
  {
    this->prefix = prefix;
  }

  Instruction *getPrefix()
  {
    return this->prefix;
  }

  MIPS_register_t getRs() { return this->rs; }

  MIPS_register_t getRt() { return this->rt; }

  MIPS_register_t getRd() { return this->rd; }

  int32_t getExtra() { return this->extra; }

  BasicBlock *parent;
protected:
  int opcode;
  MIPS_register_t rs, rt, rd;
  int32_t extra;
  Instruction *delayed;
  Instruction *prefix;

  bool branchTarget;
};

class Nop : public Instruction
{
public:
  Nop(uint32_t address) : Instruction(address, 0, R_ZERO, R_ZERO, R_ZERO, 0)
  {
  }

  virtual bool isNop()
  {
    return true;
  }

  bool pass1()
  {
    return true;
  }

  bool pass2()
  {
    return true;
  }

  int toString(char *dst, size_t n = 255)
  {
    return snprintf(dst, n, " ");
  }
};

class InstructionFactory
{
public:
  static InstructionFactory *getInstance();

  Instruction *create(uint32_t address, uint32_t encoding);

  Instruction *createNop();

private:
  static InstructionFactory *instance;
};

int instruction_to_string(Instruction *insn, char *buf, int buf_len);

#endif /* !__INSTRUCTION_HH__ */
<commit_msg>Moved to entity.hh<commit_after>/*********************************************************************
 *
 * Copyright (C) 2007,  Simon Kagstrom
 *
 * Filename:      instruction.hh
 * Author:        Simon Kagstrom <simon.kagstrom@gmail.com>
 * Description:   Instruction class
 *
 * $Id:$
 *
 ********************************************************************/
#ifndef __INSTRUCTION_HH__
#define __INSTRUCTION_HH__

#include <mips.hh>
#include <registerallocator.hh>
#include <syscall.hh>
#include <entity.hh>

class JavaClass;
class BasicBlock;
class Function;

class Instruction : public Entity
{
public:
  Instruction(uint32_t address, int opcode,
	      MIPS_register_t rs, MIPS_register_t rt, MIPS_register_t rd, int32_t extra);

  virtual ~Instruction();

  virtual bool isBranch()
  {
    return false;
  }

  virtual bool isReturnJump()
  {
    return false;
  }

  virtual bool isRegisterIndirectJump()
  {
    return false;
  }

  mips_opcode_t getOpcode()
  {
    return (mips_opcode_t)this->opcode;
  }

  bool isBranchTarget()
  {
    return this->branchTarget;
  }

  void setBranchTarget();

  virtual bool isNop()
  {
    return false;
  }

  virtual bool pass1() = 0;

  virtual bool pass2() = 0;

  virtual int getMaxStackHeight()
  {
    return 2;
  }

  virtual bool hasDelaySlot()
  {
    return this->isBranch();
  }

  /**
   * Fill in the register destinations
   *
   * @param p the destinations to fill in
   *
   * @return the number of destinations filled
   */
  virtual int fillDestinations(int *p) { return 0; };

  virtual int fillSources(int *p) { return 0; };

  void setDelayed(Instruction *delayed)
  {
    this->delayed = delayed;
  }

  Instruction *getDelayed()
  {
    return this->delayed;
  }

  void setPrefix(Instruction *prefix)
  {
    this->prefix = prefix;
  }

  Instruction *getPrefix()
  {
    return this->prefix;
  }

  MIPS_register_t getRs() { return this->rs; }

  MIPS_register_t getRt() { return this->rt; }

  MIPS_register_t getRd() { return this->rd; }

  int32_t getExtra() { return this->extra; }

  BasicBlock *parent;
protected:
  int opcode;
  MIPS_register_t rs, rt, rd;
  int32_t extra;
  Instruction *delayed;
  Instruction *prefix;

  bool branchTarget;
};

class Nop : public Instruction
{
public:
  Nop(uint32_t address) : Instruction(address, 0, R_ZERO, R_ZERO, R_ZERO, 0)
  {
  }

  virtual bool isNop()
  {
    return true;
  }

  bool pass1()
  {
    return true;
  }

  bool pass2()
  {
    return true;
  }

  int toString(char *dst, size_t n = 255)
  {
    return snprintf(dst, n, " ");
  }
};

class InstructionFactory
{
public:
  static InstructionFactory *getInstance();

  Instruction *create(uint32_t address, uint32_t encoding);

  Instruction *createNop();

private:
  static InstructionFactory *instance;
};

int instruction_to_string(Instruction *insn, char *buf, int buf_len);

#endif /* !__INSTRUCTION_HH__ */
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 2004, 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.                  *
 **************************************************************************/
/* $Id$ */
/** @file    AliFMDPreprocessor.cxx
    @author  Hans Hjersing Dalsgaard <canute@nbi.dk>
    @date    Mon Mar 27 12:39:09 2006
    @brief   Shuttle "preprocessor" for the FMD
*/
//___________________________________________________________________
//
// The class processes data points from DCS (via Amanada), and DAQ DA
// files (via FXS) to make calibration data for the FMD.
//
// Data points:
//    *  Nothing yet.
//
// DAQ FXS file:
//    * pedestals - a (ASCII) Comma Separated Values files with the
//                  fields
//                       rcu	 DDL number
//                       board   FEC board number
//                       chip    ALTRO chip number on FEC
//                       channel ALTRO channel number
//                       strip   VA1 strip number
//                       sample  Sample number
//                       ped     Mean of ADC spectra
//                       noise   Spread of ADC spectra
//                       mu      Mean of Gaussian fit to ADC spectra
//                       sigma   Variance of Gaussian fit to ADC spectra
//                       chi2    Chi^2 per degrees of freedom of fit
//    * Gains     - a (ASCII) Comma Separated Values files with the
//                  fields
//                       rcu	 DDL number
//                       board   FEC board number
//                       chip    ALTRO chip number on FEC
//                       channel ALTRO channel number
//                       strip   VA1 strip number
//                       gain    Slope of gain
//                       error   Error on gain
//                       chi2    Chi^2 per degrees of freedom of fit
//
// See also
//
//   http://aliceinfo.cern.ch/Offline/Activities/Shuttle.html
//
// Latest changes by Christian Holm Christensen
//

// #include <iostream>

#include <fstream>
#include "AliFMDPreprocessor.h"
#include "AliFMDCalibPedestal.h"
#include "AliFMDCalibGain.h"
#include "AliFMDCalibStripRange.h"
#include "AliFMDCalibSampleRate.h"
#include "AliFMDParameters.h"
#include "AliCDBMetaData.h"
#include "AliCDBManager.h"
// #include "AliDCSValue.h"
#include "AliLog.h"
#include <TTimeStamp.h>
// #include <TFile.h>
#include <TObjString.h>
#include <TString.h>
#include <TNamed.h>

ClassImp(AliFMDPreprocessor)
#if 0 // Do not remove - here to make Emacs happy
;
#endif

//____________________________________________________
AliFMDPreprocessor::AliFMDPreprocessor(AliShuttleInterface* shuttle)
  : AliPreprocessor("FMD", shuttle)
{
  AddRunType("PHYSICS");
  AddRunType("STANDALONE");
  AddRunType("PEDESTAL");
  AddRunType("GAIN");
}

//____________________________________________________
Bool_t AliFMDPreprocessor::GetAndCheckFileSources(TList*&     list,
						  Int_t       system,
						  const char* id)
{
  // Convinience function
  // Parameters:
  //   list     On return, list of files.
  //   system   Alice system (DAQ, DCS, ...)
  //   id       File id
  // Return:
  //   kTRUE on success.
  list = GetFileSources(system, id);
  if (!list) {
    TString sys;
    switch (system) {
    case kDAQ: sys = "DAQ";     break;
    case kDCS: sys = "DCS";     break;
    default:   sys = "unknown"; break;
    }
    Log(Form("Failed to get file sources for %s/%s", sys.Data(), system));
    return kFALSE;
  }
  return kTRUE;
}

//____________________________________________________
AliCDBEntry*
AliFMDPreprocessor::GetFromCDB(const char* second, const char* third)
{
  return GetFromOCDB(second, third);
}

//____________________________________________________
UInt_t AliFMDPreprocessor::Process(TMap* /* dcsAliasMap */)
{
  // Main member function.
  // Parameters:
  //    dcsAliassMap   Map of DCS data point aliases.
  // Return
  //    0 on success, >0 otherwise
  Bool_t resultPed   = kTRUE;
  Bool_t resultGain  = kTRUE;
  Bool_t resultRange = kTRUE;
  Bool_t resultRate  = kTRUE;
  Bool_t resultZero  = kTRUE;

  // Do we need this ?
  // if(!dcsAliasMap) return 1;
  //
  // Invoking the cdb manager and the FMD parameters class
  // AliCDBManager* cdb   = AliCDBManager::Instance();
  // cdb->SetDefaultStorage("local://$ALICE_ROOT");
  // cdb->SetRun(0);
  AliFMDParameters* pars = AliFMDParameters::Instance();
  pars->Init(this, false, AliFMDParameters::kAltroMap);

  // This is if the SOR contains Fee parameters, and we run a DA to
  // extract these parameters.   The same code could work if we get
  // the information from DCS via the FXS
  TList* files = 0;
  AliFMDCalibSampleRate*      calibRate  = 0;
  AliFMDCalibStripRange*      calibRange = 0;
  AliFMDCalibZeroSuppression* calibZero  = 0;
  // Disabled for now.
#if 0
  if (GetAndCheckFileSources(files, kDAQ,"info"))
    GetInfoCalibration(files, calibRate, calibRange, calibZero);
  resultRate  = (!calibRate  ? kFALSE : kTRUE);
  resultRange = (!calibRange ? kFALSE : kTRUE);
  resultZero  = (!calibZero  ? kFALSE : kTRUE);
#endif

  // Gt the run type
  TString runType(GetRunType());

  //Creating calibration objects
  AliFMDCalibPedestal* calibPed  = 0;
  AliFMDCalibGain*     calibGain = 0;
  if (runType.Contains("PEDESTAL", TString::kIgnoreCase)) {
    if (GetAndCheckFileSources(files, kDAQ, "pedestals")) {
      if(files->GetSize())
	calibPed = GetPedestalCalibration(files);
    }
    resultPed = (calibPed ? kTRUE : kFALSE);
  }
  if (runType.Contains("GAIN", TString::kIgnoreCase)) {
    if (GetAndCheckFileSources(files, kDAQ, "gains")) {
      if(files->GetSize())
	calibGain = GetGainCalibration(files);
    }
    resultGain = (calibGain ? kTRUE : kFALSE);
  }

  //Storing Calibration objects
  AliCDBMetaData metaData;
  metaData.SetBeamPeriod(0);
  metaData.SetResponsible("Hans H. Dalsgaard");
  metaData.SetComment("Preprocessor stores pedestals and gains for the FMD.");

  if(calibPed)  {
    resultPed  = Store("Calib","Pedestal", calibPed, &metaData, 0, kTRUE);
    delete calibPed;
  }
  if(calibGain) {
    resultGain = Store("Calib","PulseGain", calibGain, &metaData, 0, kTRUE);
    delete calibGain;
  }
  if(calibRange) {
    resultRange = Store("Calib","StripRange", calibRange, &metaData, 0, kTRUE);
    delete calibRange;
  }
  if(calibRate) {
    resultRate = Store("Calib","SampleRate", calibRate, &metaData, 0, kTRUE);
    delete calibRate;
  }
  if(calibZero) {
    resultZero = Store("Calib","ZeroSuppression", calibZero,&metaData,0,kTRUE);
    delete calibZero;
  }

#if 0
  // Disabled until we implement GetInfoCalibration properly
  Bool_t success = (resultPed && resultGain  && resultRange &&
		    resultRate  && resultZero);
#endif
  Bool_t success = resultPed && resultGain;
  Log(Form("FMD preprocessor was %s", (success ? "successful" : "failed")));
  return (success ? 0 : 1);
}

//____________________________________________________________________
Bool_t
AliFMDPreprocessor::GetInfoCalibration(TList* files,
				       AliFMDCalibSampleRate*&      s,
				       AliFMDCalibStripRange*&      r,
				       AliFMDCalibZeroSuppression*& z)
{
  // Get info calibrations.
  // Parameters:
  //     files List of files.
  //     s     On return, newly allocated object
  //     r     On return, newly allocated object
  //     z     On return, newly allocated object
  // Return:
  //     kTRUE on success
  if (!files) return kTRUE; // Should really be false
  if (files->GetEntries() <= 0) return kTRUE;

  s = new AliFMDCalibSampleRate();
  r = new AliFMDCalibStripRange();
  z = new AliFMDCalibZeroSuppression();

  // AliFMDParameters*    pars     = AliFMDParameters::Instance();
  TIter                iter(files);
  TObjString*          fileSource;

  while((fileSource = dynamic_cast<TObjString*>(iter.Next()))) {
    const Char_t* filename = GetFile(kDAQ, "info", fileSource->GetName());
    std::ifstream in(filename);
    if(!in) {
      Log(Form("File %s not found!", filename));
      continue;
    }
  }
  return kTRUE;
}

//____________________________________________________________________
AliFMDCalibPedestal*
AliFMDPreprocessor::GetPedestalCalibration(TList* pedFiles)
{
  // Read DAQ DA produced CSV files of pedestals, and return a
  // calibration object.
  // Parameters:
  //   pedFiles     List of pedestal files
  // Return
  //   A pointer to a newly allocated AliFMDCalibPedestal object, or
  //   null in case of errors.
  if(!pedFiles) return 0;

  AliFMDCalibPedestal* calibPed = new AliFMDCalibPedestal();
  AliFMDParameters*    pars     = AliFMDParameters::Instance();
  TIter                iter(pedFiles);
  TObjString*          fileSource;

  while((fileSource = dynamic_cast<TObjString*>(iter.Next()))) {
    const Char_t* filename = GetFile(kDAQ, "pedestals", fileSource->GetName());
    std::ifstream in(filename);
    if(!in) {
      Log(Form("File %s not found!", filename));
      continue;
    }

    // Get header (how long is it ?)
    TString header;
    header.ReadLine(in);
    header.ToLower();
    if(!header.Contains("pedestal")) {
      Log("File header is not from pedestal!");
      continue;
    }
    Log("File contains data from pedestals");

    // Read columns line
    int lineno = 2;
    header.ReadLine(in);

    // Loop until EOF
    while(in.peek()!=EOF) {
      if(in.bad()) {
	Log(Form("Bad read at line %d in %s", lineno, filename));
	break;
      }
      UInt_t ddl=2, board, chip, channel, strip, sample, tb;
      Float_t ped, noise, mu, sigma, chi2ndf;
      Char_t c[11];

      in >> ddl      >> c[0]
	 >> board    >> c[1]
	 >> chip     >> c[2]
	 >> channel  >> c[3]
	 >> strip    >> c[4]
	 >> sample   >> c[5]
	 >> tb       >> c[6]
	 >> ped      >> c[7]
	 >> noise    >> c[8]
	 >> mu       >> c[9]
	 >> sigma    >> c[10]
	 >> chi2ndf;
      lineno++;

      // Ignore trailing garbage
      if (strip > 127) continue;

      //Setting DDL to comply with the FMD in DAQ
      UInt_t FmdDDLBase = 3072;
      ddl = ddl - FmdDDLBase;
      //Setting the pedestals via the hardware address
      UShort_t det, sec, str;
      Char_t ring;

      pars->Hardware2Detector(ddl,board,chip,channel,det,ring,sec,str);
      strip += str;

      calibPed->Set(det,ring,sec,strip,ped,noise);

    }
  }
  return calibPed;
}

//____________________________________________________________________
AliFMDCalibGain*
AliFMDPreprocessor::GetGainCalibration(TList* gainFiles)
{
  // Read DAQ DA produced CSV files of pedestals, and return a
  // calibration object.
  // Parameters:
  //   pedFiles     List of pedestal files
  // Return
  //   A pointer to a newly allocated AliFMDCalibPedestal object, or
  //   null in case of errors.
  if(!gainFiles) return 0;

  AliFMDCalibGain*  calibGain  = new AliFMDCalibGain();
  AliFMDParameters* pars       = AliFMDParameters::Instance();
  TIter             iter(gainFiles);
  TObjString*       fileSource;
  while((fileSource = dynamic_cast<TObjString *>(iter.Next()))) {
    const Char_t* filename = GetFile(kDAQ, "gains", fileSource->GetName());
    std::ifstream in(filename);
    if(!in) {
      Log(Form("File %s not found!", filename));
      continue;
    }

    //Get header (how long is it ?)
    TString header;
    header.ReadLine(in);
    header.ToLower();
    if(!header.Contains("gain")) {
      Log("File header is not from gain!");
      continue;
    }
    Log("File contains data from pulse gain");

    // Read column headers
    header.ReadLine(in);

    int lineno  = 2;
    // Read until EOF
    while(in.peek()!=EOF) {
      if(in.bad()) {
	Log(Form("Bad read at line %d in %s", lineno, filename));
	break;
      }
      UInt_t ddl=2, board, chip, channel, strip;
      Float_t gain,error,  chi2ndf;
      Char_t c[7];

      in >> ddl      >> c[0]
	 >> board    >> c[1]
	 >> chip     >> c[2]
	 >> channel  >> c[3]
	 >> strip    >> c[4]
	 >> gain     >> c[5]
	 >> error    >> c[6]
	 >> chi2ndf;
      lineno++;
      // Ignore trailing garbage
      if(strip > 127) continue;

      //Setting DDL to comply with the FMD in DAQ
      UInt_t FmdDDLBase = 3072;
      ddl = ddl - FmdDDLBase;
      //Setting the pedestals via the hardware address
      UShort_t det, sec, str;
      Char_t ring;
      pars->Hardware2Detector(ddl,board,chip,channel,det,ring,sec,str);

      strip += str;
      calibGain->Set(det,ring,sec,strip,gain);
    }
  }
  return calibGain;
}

//____________________________________________________________________
//
// EOF
//
<commit_msg>New version to make use of automatic IDs from AliFMDPreprocessor<commit_after>/**************************************************************************
 * Copyright(c) 2004, 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.                  *
 **************************************************************************/
/* $Id$ */
/** @file    AliFMDPreprocessor.cxx
    @author  Hans Hjersing Dalsgaard <canute@nbi.dk>
    @date    Mon Mar 27 12:39:09 2006
    @brief   Shuttle "preprocessor" for the FMD
*/
//___________________________________________________________________
//
// The class processes data points from DCS (via Amanada), and DAQ DA
// files (via FXS) to make calibration data for the FMD.
//
// Data points:
//    *  Nothing yet.
//
// DAQ FXS file:
//    * pedestals - a (ASCII) Comma Separated Values files with the
//                  fields
//                       rcu	 DDL number
//                       board   FEC board number
//                       chip    ALTRO chip number on FEC
//                       channel ALTRO channel number
//                       strip   VA1 strip number
//                       sample  Sample number
//                       ped     Mean of ADC spectra
//                       noise   Spread of ADC spectra
//                       mu      Mean of Gaussian fit to ADC spectra
//                       sigma   Variance of Gaussian fit to ADC spectra
//                       chi2    Chi^2 per degrees of freedom of fit
//    * Gains     - a (ASCII) Comma Separated Values files with the
//                  fields
//                       rcu	 DDL number
//                       board   FEC board number
//                       chip    ALTRO chip number on FEC
//                       channel ALTRO channel number
//                       strip   VA1 strip number
//                       gain    Slope of gain
//                       error   Error on gain
//                       chi2    Chi^2 per degrees of freedom of fit
//
// See also
//
//   http://aliceinfo.cern.ch/Offline/Activities/Shuttle.html
//
// Latest changes by Christian Holm Christensen
//

// #include <iostream>

#include <fstream>
#include "AliFMDPreprocessor.h"
#include "AliFMDCalibPedestal.h"
#include "AliFMDCalibGain.h"
#include "AliFMDCalibStripRange.h"
#include "AliFMDCalibSampleRate.h"
#include "AliFMDParameters.h"
#include "AliCDBMetaData.h"
#include "AliCDBManager.h"
// #include "AliDCSValue.h"
#include "AliLog.h"
#include <TTimeStamp.h>
// #include <TFile.h>
#include <TObjString.h>
#include <TString.h>
#include <TNamed.h>

ClassImp(AliFMDPreprocessor)
#if 0 // Do not remove - here to make Emacs happy
;
#endif

//____________________________________________________
AliFMDPreprocessor::AliFMDPreprocessor(AliShuttleInterface* shuttle)
  : AliPreprocessor("FMD", shuttle)
{
  AddRunType("PHYSICS");
  AddRunType("STANDALONE");
  AddRunType("PEDESTAL");
  AddRunType("GAIN");
}

//____________________________________________________
Bool_t AliFMDPreprocessor::GetAndCheckFileSources(TList*&     list,
						  Int_t       system,
						  const char* id)
{
  // Convinience function
  // Parameters:
  //   list     On return, list of files.
  //   system   Alice system (DAQ, DCS, ...)
  //   id       File id
  // Return:
  //   kTRUE on success.
  list = GetFileSources(system, id);
  if (!list) {
    TString sys;
    switch (system) {
    case kDAQ: sys = "DAQ";     break;
    case kDCS: sys = "DCS";     break;
    default:   sys = "unknown"; break;
    }
    Log(Form("Failed to get file sources for %s/%s", sys.Data(), system));
    return kFALSE;
  }
  return kTRUE;
}

//____________________________________________________
AliCDBEntry*
AliFMDPreprocessor::GetFromCDB(const char* second, const char* third)
{
  return GetFromOCDB(second, third);
}

//____________________________________________________
UInt_t AliFMDPreprocessor::Process(TMap* /* dcsAliasMap */)
{
  // Main member function.
  // Parameters:
  //    dcsAliassMap   Map of DCS data point aliases.
  // Return
  //    0 on success, >0 otherwise
  Bool_t resultPed   = kTRUE;
  Bool_t resultGain  = kTRUE;
  Bool_t resultRange = kTRUE;
  Bool_t resultRate  = kTRUE;
  Bool_t resultZero  = kTRUE;

  // Do we need this ?
  // if(!dcsAliasMap) return 1;
  //
  // Invoking the cdb manager and the FMD parameters class
  // AliCDBManager* cdb   = AliCDBManager::Instance();
  // cdb->SetDefaultStorage("local://$ALICE_ROOT");
  // cdb->SetRun(0);
  AliFMDParameters* pars = AliFMDParameters::Instance();
  pars->Init(this, false, AliFMDParameters::kAltroMap);

  // This is if the SOR contains Fee parameters, and we run a DA to
  // extract these parameters.   The same code could work if we get
  // the information from DCS via the FXS
  TList* files = 0;
  AliFMDCalibSampleRate*      calibRate  = 0;
  AliFMDCalibStripRange*      calibRange = 0;
  AliFMDCalibZeroSuppression* calibZero  = 0;
  // Disabled for now.
#if 0
  if (GetAndCheckFileSources(files, kDAQ,pars->GetConditionsShuttleID()))
    GetInfoCalibration(files, calibRate, calibRange, calibZero);
  resultRate  = (!calibRate  ? kFALSE : kTRUE);
  resultRange = (!calibRange ? kFALSE : kTRUE);
  resultZero  = (!calibZero  ? kFALSE : kTRUE);
#endif

  // Gt the run type
  TString runType(GetRunType());

  //Creating calibration objects
  AliFMDCalibPedestal* calibPed  = 0;
  AliFMDCalibGain*     calibGain = 0;
  if (runType.Contains("PEDESTAL", TString::kIgnoreCase)) {
    if (GetAndCheckFileSources(files, kDAQ, pars->GetPedestalShuttleID())) {
      if(files->GetSize())
	calibPed = GetPedestalCalibration(files);
    }
    resultPed = (calibPed ? kTRUE : kFALSE);
  }
  if (runType.Contains("GAIN", TString::kIgnoreCase)) {
    if (GetAndCheckFileSources(files, kDAQ, pars->GetGainShuttleID())) {
      if(files->GetSize())
	calibGain = GetGainCalibration(files);
    }
    resultGain = (calibGain ? kTRUE : kFALSE);
  }

  //Storing Calibration objects
  AliCDBMetaData metaData;
  metaData.SetBeamPeriod(0);
  metaData.SetResponsible("Hans H. Dalsgaard");
  metaData.SetComment("Preprocessor stores pedestals and gains for the FMD.");

  if(calibPed)  {
    resultPed  = Store("Calib","Pedestal", calibPed, &metaData, 0, kTRUE);
    delete calibPed;
  }
  if(calibGain) {
    resultGain = Store("Calib","PulseGain", calibGain, &metaData, 0, kTRUE);
    delete calibGain;
  }
  if(calibRange) {
    resultRange = Store("Calib","StripRange", calibRange, &metaData, 0, kTRUE);
    delete calibRange;
  }
  if(calibRate) {
    resultRate = Store("Calib","SampleRate", calibRate, &metaData, 0, kTRUE);
    delete calibRate;
  }
  if(calibZero) {
    resultZero = Store("Calib","ZeroSuppression", calibZero,&metaData,0,kTRUE);
    delete calibZero;
  }

#if 0
  // Disabled until we implement GetInfoCalibration properly
  Bool_t success = (resultPed && resultGain  && resultRange &&
		    resultRate  && resultZero);
#endif
  Bool_t success = resultPed && resultGain;
  Log(Form("FMD preprocessor was %s", (success ? "successful" : "failed")));
  return (success ? 0 : 1);
}

//____________________________________________________________________
Bool_t
AliFMDPreprocessor::GetInfoCalibration(TList* files,
				       AliFMDCalibSampleRate*&      s,
				       AliFMDCalibStripRange*&      r,
				       AliFMDCalibZeroSuppression*& z)
{
  // Get info calibrations.
  // Parameters:
  //     files List of files.
  //     s     On return, newly allocated object
  //     r     On return, newly allocated object
  //     z     On return, newly allocated object
  // Return:
  //     kTRUE on success
  if (!files) return kTRUE; // Should really be false
  if (files->GetEntries() <= 0) return kTRUE;

  s = new AliFMDCalibSampleRate();
  r = new AliFMDCalibStripRange();
  z = new AliFMDCalibZeroSuppression();

  AliFMDParameters*    pars     = AliFMDParameters::Instance();
  TIter                iter(files);
  TObjString*          fileSource;

  while((fileSource = dynamic_cast<TObjString*>(iter.Next()))) {
    const Char_t* filename = GetFile(kDAQ, pars->GetConditionsShuttleID(), fileSource->GetName());
    std::ifstream in(filename);
    if(!in) {
      Log(Form("File %s not found!", filename));
      continue;
    }
  }
  return kTRUE;
}

//____________________________________________________________________
AliFMDCalibPedestal*
AliFMDPreprocessor::GetPedestalCalibration(TList* pedFiles)
{
  // Read DAQ DA produced CSV files of pedestals, and return a
  // calibration object.
  // Parameters:
  //   pedFiles     List of pedestal files
  // Return
  //   A pointer to a newly allocated AliFMDCalibPedestal object, or
  //   null in case of errors.
  if(!pedFiles) return 0;

  AliFMDCalibPedestal* calibPed = new AliFMDCalibPedestal();
  AliFMDParameters*    pars     = AliFMDParameters::Instance();
  TIter                iter(pedFiles);
  TObjString*          fileSource;

  while((fileSource = dynamic_cast<TObjString*>(iter.Next()))) {
    const Char_t* filename = GetFile(kDAQ, pars->GetPedestalShuttleID(), fileSource->GetName());
    std::ifstream in(filename);
    if(!in) {
      Log(Form("File %s not found!", filename));
      continue;
    }

    // Get header (how long is it ?)
    TString header;
    header.ReadLine(in);
    header.ToLower();
    if(!header.Contains("pedestal")) {
      Log("File header is not from pedestal!");
      continue;
    }
    Log("File contains data from pedestals");

    // Read columns line
    int lineno = 2;
    header.ReadLine(in);

    // Loop until EOF
    while(in.peek()!=EOF) {
      if(in.bad()) {
	Log(Form("Bad read at line %d in %s", lineno, filename));
	break;
      }
      UInt_t ddl=2, board, chip, channel, strip, sample, tb;
      Float_t ped, noise, mu, sigma, chi2ndf;
      Char_t c[11];

      in >> ddl      >> c[0]
	 >> board    >> c[1]
	 >> chip     >> c[2]
	 >> channel  >> c[3]
	 >> strip    >> c[4]
	 >> sample   >> c[5]
	 >> tb       >> c[6]
	 >> ped      >> c[7]
	 >> noise    >> c[8]
	 >> mu       >> c[9]
	 >> sigma    >> c[10]
	 >> chi2ndf;
      lineno++;

      // Ignore trailing garbage
      if (strip > 127) continue;

      //Setting DDL to comply with the FMD in DAQ
      UInt_t FmdDDLBase = 3072;
      ddl = ddl - FmdDDLBase;
      //Setting the pedestals via the hardware address
      UShort_t det, sec, str;
      Char_t ring;

      pars->Hardware2Detector(ddl,board,chip,channel,det,ring,sec,str);
      strip += str;

      calibPed->Set(det,ring,sec,strip,ped,noise);

    }
  }
  return calibPed;
}

//____________________________________________________________________
AliFMDCalibGain*
AliFMDPreprocessor::GetGainCalibration(TList* gainFiles)
{
  // Read DAQ DA produced CSV files of pedestals, and return a
  // calibration object.
  // Parameters:
  //   pedFiles     List of pedestal files
  // Return
  //   A pointer to a newly allocated AliFMDCalibPedestal object, or
  //   null in case of errors.
  if(!gainFiles) return 0;

  AliFMDCalibGain*  calibGain  = new AliFMDCalibGain();
  AliFMDParameters* pars       = AliFMDParameters::Instance();
  TIter             iter(gainFiles);
  TObjString*       fileSource;
  while((fileSource = dynamic_cast<TObjString *>(iter.Next()))) {
    const Char_t* filename = GetFile(kDAQ, pars->GetGainShuttleID(), fileSource->GetName());
    std::ifstream in(filename);
    if(!in) {
      Log(Form("File %s not found!", filename));
      continue;
    }

    //Get header (how long is it ?)
    TString header;
    header.ReadLine(in);
    header.ToLower();
    if(!header.Contains("gain")) {
      Log("File header is not from gain!");
      continue;
    }
    Log("File contains data from pulse gain");

    // Read column headers
    header.ReadLine(in);

    int lineno  = 2;
    // Read until EOF
    while(in.peek()!=EOF) {
      if(in.bad()) {
	Log(Form("Bad read at line %d in %s", lineno, filename));
	break;
      }
      UInt_t ddl=2, board, chip, channel, strip;
      Float_t gain,error,  chi2ndf;
      Char_t c[7];

      in >> ddl      >> c[0]
	 >> board    >> c[1]
	 >> chip     >> c[2]
	 >> channel  >> c[3]
	 >> strip    >> c[4]
	 >> gain     >> c[5]
	 >> error    >> c[6]
	 >> chi2ndf;
      lineno++;
      // Ignore trailing garbage
      if(strip > 127) continue;

      //Setting DDL to comply with the FMD in DAQ
      UInt_t FmdDDLBase = 3072;
      ddl = ddl - FmdDDLBase;
      //Setting the pedestals via the hardware address
      UShort_t det, sec, str;
      Char_t ring;
      pars->Hardware2Detector(ddl,board,chip,channel,det,ring,sec,str);

      strip += str;
      calibGain->Set(det,ring,sec,strip,gain);
    }
  }
  return calibGain;
}

//____________________________________________________________________
//
// EOF
//
<|endoftext|>


<commit_before><commit_msg>This is never defined.<commit_after><|endoftext|>


<commit_before>// Copyright (C) 2017 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and University of
// of Connecticut School of Medicine.
// All rights reserved.

// Copyright (C) 2010 - 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

/*
 * CAnnotation.cpp
 *
 *  Created on: Aug 12, 2010
 *      Author: shoops
 */

#include <sstream>

#include "copasi.h"

#include "CAnnotation.h"

#include "MIRIAM/CRDFUtilities.h"
#include "utilities/CCopasiMessage.h"
#include "utilities/CVersion.h"
#include "report/CKeyFactory.h"
#include "model/CModelValue.h"
#include "model/CReaction.h"
#include "model/CEvent.h"
#include "model/CModelParameterSet.h"
#include "function/CFunction.h"
#include "utilities/CUnitDefinition.h"
#include "copasi/core/CRootContainer.h"

#include "xml/parser/CXMLParser.h"

// static
CAnnotation * CAnnotation::castObject(CDataObject * pObject)
{
  CModelEntity * pEntity = NULL;
  CEvent * pEvent = NULL;
  CReaction * pReaction = NULL;
  CFunction * pFunction = NULL;
  CUnitDefinition * pUnitDefinition = NULL;
  CModelParameterSet * pParameterSet = NULL;

  if ((pEntity = dynamic_cast< CModelEntity * >(pObject)) != NULL)
    return static_cast< CAnnotation * >(pEntity);

  if ((pEvent = dynamic_cast< CEvent * >(pObject)) != NULL)
    return static_cast< CAnnotation * >(pEvent);

  if ((pReaction = dynamic_cast< CReaction * >(pObject)) != NULL)
    return static_cast< CAnnotation * >(pReaction);

  if ((pParameterSet = dynamic_cast< CModelParameterSet * >(pObject)) != NULL)
    return static_cast< CAnnotation * >(pParameterSet);

  if ((pFunction = dynamic_cast< CFunction * >(pObject)) != NULL)
    return static_cast< CAnnotation * >(pFunction);

  if ((pUnitDefinition = dynamic_cast< CUnitDefinition * >(pObject)) != NULL)
    return static_cast< CAnnotation * >(pUnitDefinition);

  return NULL;
}

// static
const CAnnotation * CAnnotation::castObject(const CDataObject * pObject)
{
  const CModelEntity * pEntity = NULL;
  const CEvent * pEvent = NULL;
  const CReaction * pReaction = NULL;
  const CFunction * pFunction = NULL;
  const CUnitDefinition * pUnitDefinition = NULL;
  const CModelParameterSet * pParameterSet = NULL;

  if ((pEntity = dynamic_cast< const CModelEntity * >(pObject)) != NULL)
    return static_cast< const CAnnotation * >(pEntity);

  if ((pEvent = dynamic_cast< const CEvent * >(pObject)) != NULL)
    return static_cast< const CAnnotation * >(pEvent);

  if ((pReaction = dynamic_cast< const CReaction * >(pObject)) != NULL)
    return static_cast< const CAnnotation * >(pReaction);

  if ((pParameterSet = dynamic_cast< const CModelParameterSet * >(pObject)) != NULL)
    return static_cast< const CAnnotation * >(pParameterSet);

  if ((pFunction = dynamic_cast< const CFunction * >(pObject)) != NULL)
    return static_cast< const CAnnotation * >(pFunction);

  if ((pUnitDefinition = dynamic_cast< const CUnitDefinition * >(pObject)) != NULL)
    return static_cast< const CAnnotation * >(pUnitDefinition);

  return NULL;
}

CAnnotation::CAnnotation():
  mKey(""),
  mNotes(),
  mMiriamAnnotation(),
  mXMLId(),
  mUnsupportedAnnotations()
{}

CAnnotation::CAnnotation(const CAnnotation & src):
  mKey(""),
  mNotes(src.mNotes),
  mMiriamAnnotation(src.mMiriamAnnotation),
  mXMLId(src.mXMLId),
  mUnsupportedAnnotations(src.mUnsupportedAnnotations)
{}

CAnnotation::~CAnnotation()
{
  CRootContainer::getKeyFactory()->remove(mKey);
}

// virtual
const std::string & CAnnotation::getKey() const
{
  return mKey;
}

void CAnnotation::setMiriamAnnotation(const std::string & miriamAnnotation,
                                      const std::string & newId,
                                      const std::string & oldId)
{
  mMiriamAnnotation = miriamAnnotation;
  mXMLId = newId;
  CRDFUtilities::fixLocalFileAboutReference(mMiriamAnnotation, newId, oldId);
}

const std::string & CAnnotation::getMiriamAnnotation() const
{return mMiriamAnnotation;}

void CAnnotation::setNotes(const std::string & notes)
{
  mNotes = notes;
}
const std::string & CAnnotation::getNotes() const
{
  return mNotes;
}

bool CAnnotation::operator == (const CAnnotation & rhs) const
{
  if (mNotes != rhs.mNotes)
    return false;

  std::string Annotation = mMiriamAnnotation;
  CRDFUtilities::fixLocalFileAboutReference(Annotation, rhs.mXMLId, mXMLId);

  // We need to ignore white spaces when comparing.
  std::string::const_iterator it = Annotation.begin();
  std::string::const_iterator end = Annotation.end();
  std::string::const_iterator itRhs = rhs.mMiriamAnnotation.begin();
  std::string::const_iterator endRhs = rhs.mMiriamAnnotation.end();

  while (it != end && itRhs != endRhs)
    {
      if (*it == * itRhs)
        {
          ++it;
          ++itRhs;

          continue;
        }

      // Advance past white spaces
      while (it != end)
        {
          if (*it == '\x20' || *it == '\x09' || *it == '\x0d' || *it == '\x0a')
            {
              ++it;

              continue;
            }

          break;
        }

      // Advance past white spaces
      while (itRhs != endRhs)
        {
          if (*itRhs == '\x20' || *itRhs == '\x09' || *itRhs == '\x0d' || *itRhs == '\x0a')
            {
              ++itRhs;

              continue;
            }

          break;
        }

      if (it == end && itRhs == endRhs)
        {
          return true;
        }

      if (it == end || itRhs == endRhs)
        {
          return false;
        }

      if (*it != *itRhs)
        {
          return false;
        }

      ++it;
      ++itRhs;
    }

  return true;
}

CAnnotation::UnsupportedAnnotation & CAnnotation::getUnsupportedAnnotations()
{
  return mUnsupportedAnnotations;
}

const CAnnotation::UnsupportedAnnotation & CAnnotation::getUnsupportedAnnotations() const
{
  return mUnsupportedAnnotations;
}

bool CAnnotation::addUnsupportedAnnotation(const std::string & name, const std::string & xml)
{
  // The name must not be empty
  if (name == "")
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCAnnotation + 7);
      return false;
    }

  // The name must be unique
  if (mUnsupportedAnnotations.find(name) != mUnsupportedAnnotations.end())
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCAnnotation + 6, name.c_str());
      return false;
    }

  // We need to check whether we have valid XML.
  if (!isValidXML(xml))
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCAnnotation + 5, name.c_str());
      return false;
    }

  mUnsupportedAnnotations[name] = xml;

  return true;
}

bool CAnnotation::replaceUnsupportedAnnotation(const std::string & name, const std::string & xml)
{
  // We need to check whether we have valid XML.
  if (!isValidXML(xml))
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCAnnotation + 5, name.c_str());
      return false;
    }

  // The annotation must exist
  if (mUnsupportedAnnotations.find(name) == mUnsupportedAnnotations.end())
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCAnnotation + 8, name.c_str());
      return false;
    }

  mUnsupportedAnnotations[name] = xml;

  return true;
}

bool CAnnotation::removeUnsupportedAnnotation(const std::string & name)
{
  UnsupportedAnnotation::iterator it = mUnsupportedAnnotations.find(name);

  if (it == mUnsupportedAnnotations.end())
    {
      return false;
    }

  mUnsupportedAnnotations.erase(it);

  return true;
}

// static
bool CAnnotation::isValidXML(const std::string & xml)
{
  std::istringstream XML;
  XML.str(xml);
  XML.imbue(std::locale::classic());
  XML.precision(std::numeric_limits<double>::digits10 + 2);

  bool done = false;

  CVersion Version;
  CXMLParser Parser(Version);

  size_t Size = CCopasiMessage::size();

#define BUFFER_SIZE 0xfffe
  char * pBuffer = new char[BUFFER_SIZE + 1];

  while (!done)
    {
      XML.get(pBuffer, BUFFER_SIZE, 0);

      if (XML.eof()) done = true;

      if (XML.fail() && !done)
        {
          done = true;
          return false;
        }

      if (!Parser.parse(pBuffer, -1, done))
        {
          done = true;
          return false;
        }
    }

  delete [] pBuffer;
#undef BUFFER_SIZE

  // Remove error messages created by setExpression as this may fail
  // due to incomplete model specification at this time.
  while (CCopasiMessage::size() > Size)
    CCopasiMessage::getLastMessage();

  return true;
}
<commit_msg>- issue 2573: import of multiple annotations of the same namespace supported and verified<commit_after>// Copyright (C) 2017 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and University of
// of Connecticut School of Medicine.
// All rights reserved.

// Copyright (C) 2010 - 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

/*
 * CAnnotation.cpp
 *
 *  Created on: Aug 12, 2010
 *      Author: shoops
 */

#include <sstream>

#include "copasi.h"

#include "CAnnotation.h"

#include "MIRIAM/CRDFUtilities.h"
#include "utilities/CCopasiMessage.h"
#include "utilities/CVersion.h"
#include "report/CKeyFactory.h"
#include "model/CModelValue.h"
#include "model/CReaction.h"
#include "model/CEvent.h"
#include "model/CModelParameterSet.h"
#include "function/CFunction.h"
#include "utilities/CUnitDefinition.h"
#include "copasi/core/CRootContainer.h"

#include "xml/parser/CXMLParser.h"

// static
CAnnotation * CAnnotation::castObject(CDataObject * pObject)
{
  CModelEntity * pEntity = NULL;
  CEvent * pEvent = NULL;
  CReaction * pReaction = NULL;
  CFunction * pFunction = NULL;
  CUnitDefinition * pUnitDefinition = NULL;
  CModelParameterSet * pParameterSet = NULL;

  if ((pEntity = dynamic_cast< CModelEntity * >(pObject)) != NULL)
    return static_cast< CAnnotation * >(pEntity);

  if ((pEvent = dynamic_cast< CEvent * >(pObject)) != NULL)
    return static_cast< CAnnotation * >(pEvent);

  if ((pReaction = dynamic_cast< CReaction * >(pObject)) != NULL)
    return static_cast< CAnnotation * >(pReaction);

  if ((pParameterSet = dynamic_cast< CModelParameterSet * >(pObject)) != NULL)
    return static_cast< CAnnotation * >(pParameterSet);

  if ((pFunction = dynamic_cast< CFunction * >(pObject)) != NULL)
    return static_cast< CAnnotation * >(pFunction);

  if ((pUnitDefinition = dynamic_cast< CUnitDefinition * >(pObject)) != NULL)
    return static_cast< CAnnotation * >(pUnitDefinition);

  return NULL;
}

// static
const CAnnotation * CAnnotation::castObject(const CDataObject * pObject)
{
  const CModelEntity * pEntity = NULL;
  const CEvent * pEvent = NULL;
  const CReaction * pReaction = NULL;
  const CFunction * pFunction = NULL;
  const CUnitDefinition * pUnitDefinition = NULL;
  const CModelParameterSet * pParameterSet = NULL;

  if ((pEntity = dynamic_cast< const CModelEntity * >(pObject)) != NULL)
    return static_cast< const CAnnotation * >(pEntity);

  if ((pEvent = dynamic_cast< const CEvent * >(pObject)) != NULL)
    return static_cast< const CAnnotation * >(pEvent);

  if ((pReaction = dynamic_cast< const CReaction * >(pObject)) != NULL)
    return static_cast< const CAnnotation * >(pReaction);

  if ((pParameterSet = dynamic_cast< const CModelParameterSet * >(pObject)) != NULL)
    return static_cast< const CAnnotation * >(pParameterSet);

  if ((pFunction = dynamic_cast< const CFunction * >(pObject)) != NULL)
    return static_cast< const CAnnotation * >(pFunction);

  if ((pUnitDefinition = dynamic_cast< const CUnitDefinition * >(pObject)) != NULL)
    return static_cast< const CAnnotation * >(pUnitDefinition);

  return NULL;
}

CAnnotation::CAnnotation():
  mKey(""),
  mNotes(),
  mMiriamAnnotation(),
  mXMLId(),
  mUnsupportedAnnotations()
{}

CAnnotation::CAnnotation(const CAnnotation & src):
  mKey(""),
  mNotes(src.mNotes),
  mMiriamAnnotation(src.mMiriamAnnotation),
  mXMLId(src.mXMLId),
  mUnsupportedAnnotations(src.mUnsupportedAnnotations)
{}

CAnnotation::~CAnnotation()
{
  CRootContainer::getKeyFactory()->remove(mKey);
}

// virtual
const std::string & CAnnotation::getKey() const
{
  return mKey;
}

void CAnnotation::setMiriamAnnotation(const std::string & miriamAnnotation,
                                      const std::string & newId,
                                      const std::string & oldId)
{
  mMiriamAnnotation = miriamAnnotation;
  mXMLId = newId;
  CRDFUtilities::fixLocalFileAboutReference(mMiriamAnnotation, newId, oldId);
}

const std::string & CAnnotation::getMiriamAnnotation() const
{return mMiriamAnnotation;}

void CAnnotation::setNotes(const std::string & notes)
{
  mNotes = notes;
}
const std::string & CAnnotation::getNotes() const
{
  return mNotes;
}

bool CAnnotation::operator == (const CAnnotation & rhs) const
{
  if (mNotes != rhs.mNotes)
    return false;

  std::string Annotation = mMiriamAnnotation;
  CRDFUtilities::fixLocalFileAboutReference(Annotation, rhs.mXMLId, mXMLId);

  // We need to ignore white spaces when comparing.
  std::string::const_iterator it = Annotation.begin();
  std::string::const_iterator end = Annotation.end();
  std::string::const_iterator itRhs = rhs.mMiriamAnnotation.begin();
  std::string::const_iterator endRhs = rhs.mMiriamAnnotation.end();

  while (it != end && itRhs != endRhs)
    {
      if (*it == * itRhs)
        {
          ++it;
          ++itRhs;

          continue;
        }

      // Advance past white spaces
      while (it != end)
        {
          if (*it == '\x20' || *it == '\x09' || *it == '\x0d' || *it == '\x0a')
            {
              ++it;

              continue;
            }

          break;
        }

      // Advance past white spaces
      while (itRhs != endRhs)
        {
          if (*itRhs == '\x20' || *itRhs == '\x09' || *itRhs == '\x0d' || *itRhs == '\x0a')
            {
              ++itRhs;

              continue;
            }

          break;
        }

      if (it == end && itRhs == endRhs)
        {
          return true;
        }

      if (it == end || itRhs == endRhs)
        {
          return false;
        }

      if (*it != *itRhs)
        {
          return false;
        }

      ++it;
      ++itRhs;
    }

  return true;
}

CAnnotation::UnsupportedAnnotation & CAnnotation::getUnsupportedAnnotations()
{
  return mUnsupportedAnnotations;
}

const CAnnotation::UnsupportedAnnotation & CAnnotation::getUnsupportedAnnotations() const
{
  return mUnsupportedAnnotations;
}

bool CAnnotation::addUnsupportedAnnotation(const std::string & name, const std::string & xml)
{
  // The name must not be empty
  if (name == "")
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCAnnotation + 7);
      return false;
    }

  // We need to check whether we have valid XML.
  if (!isValidXML(xml))
  {
    CCopasiMessage(CCopasiMessage::ERROR, MCAnnotation + 5, name.c_str());
    return false;
  }

  // if we already have an entry, we add it ...
  if (mUnsupportedAnnotations.find(name) != mUnsupportedAnnotations.end())
    {
      mUnsupportedAnnotations[name] += xml;
    }
  else
  {
    mUnsupportedAnnotations[name] = xml;
  }

  return true;
}

bool CAnnotation::replaceUnsupportedAnnotation(const std::string & name, const std::string & xml)
{
  // We need to check whether we have valid XML.
  if (!isValidXML(xml))
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCAnnotation + 5, name.c_str());
      return false;
    }

  // The annotation must exist
  if (mUnsupportedAnnotations.find(name) == mUnsupportedAnnotations.end())
    {
      CCopasiMessage(CCopasiMessage::ERROR, MCAnnotation + 8, name.c_str());
      return false;
    }

  mUnsupportedAnnotations[name] = xml;

  return true;
}

bool CAnnotation::removeUnsupportedAnnotation(const std::string & name)
{
  UnsupportedAnnotation::iterator it = mUnsupportedAnnotations.find(name);

  if (it == mUnsupportedAnnotations.end())
    {
      return false;
    }

  mUnsupportedAnnotations.erase(it);

  return true;
}

// static
bool CAnnotation::isValidXML(const std::string & xml)
{
  std::istringstream XML;
  XML.str(xml);
  XML.imbue(std::locale::classic());
  XML.precision(std::numeric_limits<double>::digits10 + 2);

  bool done = false;

  CVersion Version;
  CXMLParser Parser(Version);

  size_t Size = CCopasiMessage::size();

#define BUFFER_SIZE 0xfffe
  char * pBuffer = new char[BUFFER_SIZE + 1];

  while (!done)
    {
      XML.get(pBuffer, BUFFER_SIZE, 0);

      if (XML.eof()) done = true;

      if (XML.fail() && !done)
        {
          done = true;
          return false;
        }

      if (!Parser.parse(pBuffer, -1, done))
        {
          done = true;
          return false;
        }
    }

  delete [] pBuffer;
#undef BUFFER_SIZE

  // Remove error messages created by setExpression as this may fail
  // due to incomplete model specification at this time.
  while (CCopasiMessage::size() > Size)
    CCopasiMessage::getLastMessage();

  return true;
}
<|endoftext|>


<commit_before>#include <QString>
#include <QUrl>
#include <QFileInfo>
#include <QSqlQuery>
#include <QSqlRecord>
#include "identity.h"
#include "kernel.h"
#include "ilwisdata.h"
#include "resource.h"
#include "catalogview.h"
#include "catalogquery.h"
#include "catalog.h"
#include "ilwiscontext.h"
#include "mastercatalog.h"

using namespace Ilwis;

CatalogView::CatalogView(QObject *parent) :
    QObject(parent)
{
}

CatalogView::CatalogView(const QUrl &loc) : QObject(){
    addLocation(loc);
    QStringList parts = loc.toString().split("/");
    name(parts.back());
    _resource = Resource("ilwis://internalcatalog/" + name(), itCATALOGVIEW);
    QStringList lst;
    lst.append(loc.toString());
    _resource["locations"] = lst;
}

CatalogView::CatalogView(const Resource &resource) : QObject(), Identity(resource.name(),resource.id(),resource.code()){
    filter(resource["filter"].toString());
    QStringList lst = resource["locations"].toStringList();
    for(auto url : lst){
        if ( url != sUNDEF)
            _locations.push_back(QUrl(url));
    }
    _resource = resource;
}

CatalogView::CatalogView(const CatalogView &cat) : QObject(),
    Identity(sUNDEF,i64UNDEF,cat.code(),cat.description()),
     _filter(cat._filter),
     _locations(cat._locations),
     _fixedItems(cat._fixedItems),
     _parent(cat._parent),
     _resource(cat.resource())
 {
     Identity::prepare(); // bit inconveniet but the id must be set. this overrules the name so we set it again
     name(cat.name());
}

void CatalogView::addLocation(const QUrl& loc){
    if ( std::find(_locations.begin(), _locations.end(), loc) == _locations.end()){
        _locations.push_back(loc);
        if ( name() != sUNDEF)
            return;

        QStringList parts = loc.toString().split("/");
        QString cid = parts.back();
        name(cid);
    }
}

std::vector<Resource> CatalogView::items() const
{
    if (!isValid())
        return std::vector<Resource>();

    std::vector<Resource> results;
    for(auto& item : _fixedItems){
        results.push_back(item.second);
    }
    QString filter = _filter;
    for(auto location : _locations) {
        std::vector<Resource> items;
        if ( location == QUrl("ilwis://system")){
            if ( filter != "")
                filter += " and ";
            filter += QString("type<>%1").arg(QString::number(itGEODETICDATUM)); // datums are not visible in the catalogs
        }
        if ( location != MasterCatalog::MASTERCATALOG){
            items =  mastercatalog()->select(location, filter);
        }else
            items =  mastercatalog()->select(filter);

        std::copy(items.begin(), items.end(),std::back_inserter(results));
    }
    std::set<Resource> uniques(results.begin(), results.end());
    results.resize(uniques.size());
    std::copy(uniques.begin(), uniques.end(), results.begin());
    return results;

}

void CatalogView::addFixedItem(quint64 id)
{
    Resource resource = mastercatalog()->id2Resource(id);
    if ( resource.isValid()){
        _fixedItems[id] = resource;
    }
}

void CatalogView::removeFixedItem(quint64 id)
{
    auto iter = _fixedItems.find(id);
    if ( iter != _fixedItems.end())
        _fixedItems.erase(iter);
}

quint32 CatalogView::fixedItemCount() const
{
    return _fixedItems.size();
}

QString CatalogView::filter() const
{
    return _filter;
}

void CatalogView::filter(const QString &filter)
{
    CatalogQuery query;
    _filter = query.transformQuery(filter);
}

Resource CatalogView::resource() const
{
    return _resource;
}

bool CatalogView::hasParent() const
{
    if ( _locations.size() != 1)
        return false;
    return _locations[0].scheme() == "file";
}

bool CatalogView::prepare()
{
    for(auto resource : _locations)
        if(!mastercatalog()->addContainer(resource))
            return false;

    Identity::prepare();

    return true;
}

CatalogView &CatalogView::operator=(const CatalogView &view)
{
    Identity::prepare();
    name(view.name());
    setDescription(view.description());
    code(view.code());
    _filter = view._filter;
    _locations = view._locations;
    _resource = view._resource;
    _fixedItems = view._fixedItems;

    return *this;

}

QString CatalogView::type() const
{
    return "CatalogView";
}

bool CatalogView::isValid() const
{
    return _locations.size() > 0 || _fixedItems.size() > 0 ;
}

QUrl CatalogView::parentCatalogView() const
{
    return _parent;
}

void CatalogView::setParentCatalogView(const QUrl &url)
{
    _parent = url;
}

<commit_msg>No longer forces a scan in prepare. The add container method from mastercatalog is basically the only one who is still doing that and that is only used at the places were a scan is wanted. Doing it here interferes with the multithreading as it cant be recognized if we should start a thread here , or not<commit_after>#include <QString>
#include <QUrl>
#include <QFileInfo>
#include <QSqlQuery>
#include <QSqlRecord>
#include "identity.h"
#include "kernel.h"
#include "ilwisdata.h"
#include "resource.h"
#include "catalogview.h"
#include "catalogquery.h"
#include "catalog.h"
#include "ilwiscontext.h"
#include "mastercatalog.h"

using namespace Ilwis;

CatalogView::CatalogView(QObject *parent) :
    QObject(parent)
{
}

CatalogView::CatalogView(const QUrl &loc) : QObject(){
    addLocation(loc);
    QStringList parts = loc.toString().split("/");
    name(parts.back());
    _resource = Resource("ilwis://internalcatalog/" + name(), itCATALOGVIEW);
    QStringList lst;
    lst.append(loc.toString());
    _resource["locations"] = lst;
}

CatalogView::CatalogView(const Resource &resource) : QObject(), Identity(resource.name(),resource.id(),resource.code()){
    filter(resource["filter"].toString());
    QStringList lst = resource["locations"].toStringList();
    for(auto url : lst){
        if ( url != sUNDEF)
            _locations.push_back(QUrl(url));
    }
    _resource = resource;
}

CatalogView::CatalogView(const CatalogView &cat) : QObject(),
    Identity(sUNDEF,i64UNDEF,cat.code(),cat.description()),
     _filter(cat._filter),
     _locations(cat._locations),
     _fixedItems(cat._fixedItems),
     _parent(cat._parent),
     _resource(cat.resource())
 {
     Identity::prepare(); // bit inconveniet but the id must be set. this overrules the name so we set it again
     name(cat.name());
}

void CatalogView::addLocation(const QUrl& loc){
    if ( std::find(_locations.begin(), _locations.end(), loc) == _locations.end()){
        _locations.push_back(loc);
        if ( name() != sUNDEF)
            return;

        QStringList parts = loc.toString().split("/");
        QString cid = parts.back();
        name(cid);
    }
}

std::vector<Resource> CatalogView::items() const
{
    if (!isValid())
        return std::vector<Resource>();

    std::vector<Resource> results;
    for(auto& item : _fixedItems){
        results.push_back(item.second);
    }
    QString filter = _filter;
    for(auto location : _locations) {
        std::vector<Resource> items;
        if ( location == QUrl("ilwis://system")){
            if ( filter != "")
                filter += " and ";
            filter += QString("type<>%1").arg(QString::number(itGEODETICDATUM)); // datums are not visible in the catalogs
        }
        if ( location != MasterCatalog::MASTERCATALOG){
            items =  mastercatalog()->select(location, filter);
        }else
            items =  mastercatalog()->select(filter);

        std::copy(items.begin(), items.end(),std::back_inserter(results));
    }
    std::set<Resource> uniques(results.begin(), results.end());
    results.resize(uniques.size());
    std::copy(uniques.begin(), uniques.end(), results.begin());
    return results;

}

void CatalogView::addFixedItem(quint64 id)
{
    Resource resource = mastercatalog()->id2Resource(id);
    if ( resource.isValid()){
        _fixedItems[id] = resource;
    }
}

void CatalogView::removeFixedItem(quint64 id)
{
    auto iter = _fixedItems.find(id);
    if ( iter != _fixedItems.end())
        _fixedItems.erase(iter);
}

quint32 CatalogView::fixedItemCount() const
{
    return _fixedItems.size();
}

QString CatalogView::filter() const
{
    return _filter;
}

void CatalogView::filter(const QString &filter)
{
    CatalogQuery query;
    _filter = query.transformQuery(filter);
}

Resource CatalogView::resource() const
{
    return _resource;
}

bool CatalogView::hasParent() const
{
    if ( _locations.size() != 1)
        return false;
    return _locations[0].scheme() == "file";
}

bool CatalogView::prepare()
{
//    for(auto resource : _locations)
//        if(!mastercatalog()->addContainer(resource))
//            return false;

    Identity::prepare();

    return true;
}

CatalogView &CatalogView::operator=(const CatalogView &view)
{
    Identity::prepare();
    name(view.name());
    setDescription(view.description());
    code(view.code());
    _filter = view._filter;
    _locations = view._locations;
    _resource = view._resource;
    _fixedItems = view._fixedItems;

    return *this;

}

QString CatalogView::type() const
{
    return "CatalogView";
}

bool CatalogView::isValid() const
{
    return _locations.size() > 0 || _fixedItems.size() > 0 ;
}

QUrl CatalogView::parentCatalogView() const
{
    return _parent;
}

void CatalogView::setParentCatalogView(const QUrl &url)
{
    _parent = url;
}

<|endoftext|>