<commit_before>    /**
 * @file   strategy_node.cpp
 * @author Matheus Vieira Portela
 * @date   21/03/2014
 * @author Izabella Thaís Oliveira Gomes
 * @date   19/02/2017
 *
 * @attention Copyright (C) 2014 UnBall Robot Soccer Team
 *
 * @brief Run strategy for robots
 *
 * This node subscribes to the vision topic, applies strategy to decide robots linear and angular velocities, and
 * publishes to the strategy topic.
 */

#include <vector>

#include <ros/ros.h>

#include <strategy/MeasurementSystemMessage.h>
#include <strategy/KeyboardMessage.h>
#include <strategy/target_positions_msg.h>
//#include <strategy.hpp> // Strategy strategy;
#include <goals.hpp>
#include <robot.hpp> // Robot robot[6];
#include <ball.hpp> // Ball ball;

void initRobotsPoses();
void publishRobotsTargetPositions(ros::Publisher &publisher);
void receiveMeasurementSystemMessage(const strategy::MeasurementSystemMessage::ConstPtr &msg);
//void receiveKeyboardMessage(const strategy::KeyboardMessage::ConstPtr &msg);

int main(int argc, char **argv)
{
    ros::init(argc, argv, "strategy_node");

    ros::NodeHandle n;
    ros::Rate loop_rate(30); // Hz

    ros::Subscriber sub = n.subscribe("measurement_system_topic", 1, receiveMeasurementSystemMessage);
    //ros::Subscriber sub2 = n.subscribe("keyboard_topic", 1, receiveKeyboardMessage);
    ros::Publisher publisher = n.advertise<strategy::target_positions_msg>("target_positions_msg", 1);

    //initRobotsPoses();

    while (ros::ok())
    {
        //strategy.run();
        publishRobotsTargetPositions(publisher);
        ros::spinOnce();
        loop_rate.sleep();
    }

    return 0;
}

/**
 * Initialize robots poses with the simulation hardcoded poses.
 *
 * This is done in order to prevent errors in the first evaluated action, which may calculate travelled distance from
 * the last iteration.
 *
 * For example: if a robot is set to move for 0.20 m, its initial position is (0, 0) and it is spawn at (0.3, 0), the
 * method will calculate a travelled distance of 0.30 m and return, even though its real travelled distance so far is 0!
 */
/*void initRobotsPoses()
{
    float x[6] = {0.37, 0.37, 0.60, -0.37, -0.37, -0.60};
    float y[6] = {0.40, -0.40, 0.0, 0.40, -0.40, 0.0};

    for (int i = 0; i < 6; ++i)
        robot[i].setPose(x[i], y[i], 0.0); // Initial theta is 0
}*/

/**
 * Publishes the robots target positions to the strategy topic.
 * @param publisher a ROS node publisher.
 */
void publishRobotsTargetPositions(ros::Publisher &publisher)
{
    strategy:: target_positions_msg msg;

    ROS_DEBUG("Publishing target_positions_msg message");

    robot[0].setTargetX(0.5);
    robot[0].setTargetY(0.5);

    msg.x[0] = robot[0].getTargetX();
    msg.y[0] = robot[0].getTargetY();

    for (int i = 1; i < 6; i++)
    {
        robot[i].setTargetX(0);
        robot[i].setTargetY(0);

        msg.x[i] = robot[i].getTargetX();
        msg.y[i] = robot[i].getTargetY();

        ROS_DEBUG("target_x: %f\t target_y: %f", msg.x[i], msg.y[i]);
    }

    publisher.publish(msg);
}

/*float getAngularVel(int i) {
    float K = 1;
    float distance_x = Ball::getInstance().getX() - robot[i].getX();
    float distance_y = Ball::getInstance().getY() - robot[i].getY();
    float angle_to_ball = atan2(distance_y,distance_x);
    return K*(robot[i].getTh() - angle_to_ball);
}*/

/**
 * Receives the robots locations from the vision topic.
 * @param msg an UnBall vision message pointer.
 */
void receiveMeasurementSystemMessage(const strategy::MeasurementSystemMessage::ConstPtr &msg)
{
    //ROS_INF)O("\n\n[StrategyNode]:ReceiveMeasuermentSystemMessage - Receiving measurement system message");

    for (int i = 0; i < 6; i++)
    {
        //ROS_INFO("Robots: %d x: %f\t y: %f\t th: %f", i, msg->x[i], msg->y[i], msg->th[i]);
        robot[i].setPose(msg->x[i], msg->y[i], msg->th[i]);
    }

    //ROS_INFO("Ball: x: %f, y: %f", msg->ball_x, msg->ball_y);
    if (msg->y[2] < -0.75 or msg->y[2] > 0.75 or msg->x[2] < -0.65 or msg->x[2] > 0.65)
    {
        //HACK: in case we do not find our goakeeper, we set our goal by:
        //finding the opponent goalkeeper
        //sending the negative of its x position to the function setGoalkeeperSide
        //this way we find which is our goal, and therefore which goal we should target
        //only meant to happen on a penalty
        int opponent_goalkeeper_number = Goals::getInstance().findOpponentGoalkeeper();
        Goals::getInstance().setGoalkeeperSide(-robot[opponent_goalkeeper_number].getY());
    }
    else
    {
        Goals::getInstance().setGoalkeeperSide(robot[2].getY());
    }
    Ball::getInstance().update(msg->ball_y, -msg->ball_x);
}

/**
 * Receives a key from the keyboard topic.
 * @param msg a keyboard message pointer.
 */
/*void receiveKeyboardMessage(const strategy::KeyboardMessage::ConstPtr &msg)
{
    ROS_ERROR("Received key: %c", msg->key);

    Strategy::getInstance().receiveKeyboardInput(msg->key);
    strategy.receiveKeyboardInput(msg->key);
}*/
<commit_msg>Now the strategy node is publish the target position message for one robot.<commit_after>    /**
 * @file   strategy_node.cpp
 * @author Matheus Vieira Portela
 * @date   21/03/2014
 * @author Izabella Thaís Oliveira Gomes
 * @date   19/02/2017
 *
 * @attention Copyright (C) 2014 UnBall Robot Soccer Team
 *
 * @brief Run strategy for robots
 *
 * This node subscribes to the vision topic, applies strategy to decide robots linear and angular velocities, and
 * publishes to the strategy topic.
 */

#include <vector>

#include <ros/ros.h>

#include <strategy/MeasurementSystemMessage.h>
#include <strategy/KeyboardMessage.h>
#include <strategy/target_positions_msg.h>
//#include <strategy.hpp> // Strategy strategy;
#include <goals.hpp>
#include <robot.hpp> // Robot robot[6];
#include <ball.hpp> // Ball ball;

//void initRobotsPoses();
void publishRobotsTargetPositions(ros::Publisher &publisher);
void receiveMeasurementSystemMessage(const strategy::MeasurementSystemMessage::ConstPtr &msg);
//void receiveKeyboardMessage(const strategy::KeyboardMessage::ConstPtr &msg);

int main(int argc, char **argv)
{
    ros::init(argc, argv, "strategy_node");

    ros::NodeHandle n;
    ros::Rate loop_rate(30); // Hz

    ros::Subscriber sub = n.subscribe("measurement_system_topic", 1, receiveMeasurementSystemMessage);
    //ros::Subscriber sub2 = n.subscribe("keyboard_topic", 1, receiveKeyboardMessage);
    ros::Publisher publisher = n.advertise<strategy::target_positions_msg>("target_positions_topic", 1);

    //initRobotsPoses();

    while (ros::ok())
    {
        ROS_INFO("[Strategy] Measurement System Message: Receiving");
        //strategy.run();
        publishRobotsTargetPositions(publisher);
        ros::spinOnce();
        loop_rate.sleep();
    }

    return 0;
}

/**
 * Initialize robots poses with the simulation hardcoded poses.
 *
 * This is done in order to prevent errors in the first evaluated action, which may calculate travelled distance from
 * the last iteration.
 *
 * For example: if a robot is set to move for 0.20 m, its initial position is (0, 0) and it is spawn at (0.3, 0), the
 * method will calculate a travelled distance of 0.30 m and return, even though its real travelled distance so far is 0!
 */
/*void initRobotsPoses()
{
    float x[6] = {0.37, 0.37, 0.60, -0.37, -0.37, -0.60};
    float y[6] = {0.40, -0.40, 0.0, 0.40, -0.40, 0.0};

    for (int i = 0; i < 6; ++i)
        robot[i].setPose(x[i], y[i], 0.0); // Initial theta is 0
}*/

/**
 * Publishes the robots target positions to the strategy topic.
 * @param publisher a ROS node publisher.
 */
void publishRobotsTargetPositions(ros::Publisher &publisher)
{
    strategy::target_positions_msg msg;

    ROS_INFO("Publishing target_positions_msg message");

    robot[0].setTargetX(0.5);
    robot[0].setTargetY(0.5);

    ROS_INFO("Robots: %d x: %f\t y: %f\t\n", 0, robot[0].getTargetX(), robot[0].getTargetX());

    msg.x[0] = robot[0].getTargetX();
    msg.y[0] = robot[0].getTargetY();

    for (int i = 1; i < 2; i++)
    {

        robot[i].setTargetX(0);
        robot[i].setTargetY(0);

        ROS_INFO("Robots: %d x: %f\t y: %f\t\n", i, robot[i].getTargetX(), robot[i].getTargetX());

        msg.x[i] = robot[i].getTargetX();
        msg.y[i] = robot[i].getTargetY();

        ROS_DEBUG("target_x: %f\t target_y: %f", msg.x[i], msg.y[i]);
    }

    publisher.publish(msg);
}

/*float getAngularVel(int i) {
    float K = 1;
    float distance_x = Ball::getInstance().getX() - robot[i].getX();
    float distance_y = Ball::getInstance().getY() - robot[i].getY();
    float angle_to_ball = atan2(distance_y,distance_x);
    return K*(robot[i].getTh() - angle_to_ball);
}*/

/**
 * Receives the robots locations from the vision topic.
 * @param msg an UnBall vision message pointer.
 */
void receiveMeasurementSystemMessage(const strategy::MeasurementSystemMessage::ConstPtr &msg)
{
    ROS_INFO("\n\n[StrategyNode]:ReceiveMeasurementSystemMessage - Receiving measurement system message");

    for (int i = 0; i < 6; i++)
    {
        ROS_INFO("Robots: %d x: %f\t y: %f\t th: %f", i, msg->x[i], msg->y[i], msg->th[i]);
        robot[i].setPose(msg->x[i], msg->y[i], msg->th[i]);
    }

    ROS_INFO("Ball: x: %f, y: %f", msg->ball_x, msg->ball_y);
    if (msg->y[2] < -0.75 or msg->y[2] > 0.75 or msg->x[2] < -0.65 or msg->x[2] > 0.65)
    {
        //HACK: in case we do not find our goakeeper, we set our goal by:
        //finding the opponent goalkeeper
        //sending the negative of its x position to the function setGoalkeeperSide
        //this way we find which is our goal, and therefore which goal we should target
        //only meant to happen on a penalty
        int opponent_goalkeeper_number = Goals::getInstance().findOpponentGoalkeeper();
        Goals::getInstance().setGoalkeeperSide(-robot[opponent_goalkeeper_number].getY());
    }
    else
    {
        Goals::getInstance().setGoalkeeperSide(robot[2].getY());
    }
    Ball::getInstance().update(msg->ball_y, -msg->ball_x);
}

/**
 * Receives a key from the keyboard topic.
 * @param msg a keyboard message pointer.
 */
/*void receiveKeyboardMessage(const strategy::KeyboardMessage::ConstPtr &msg)
{
    ROS_ERROR("Received key: %c", msg->key);

    Strategy::getInstance().receiveKeyboardInput(msg->key);
    strategy.receiveKeyboardInput(msg->key);
}*/
<|endoftext|>


<commit_before>// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/assert.h"
#include "platform/utils.h"
#include "vm/globals.h"
#include "vm/os.h"
#include "vm/unit_test.h"

namespace dart {

UNIT_TEST_CASE(Sleep) {
  int64_t start_time = OS::GetCurrentTimeMillis();
  int64_t sleep_time = 702;
  OS::Sleep(sleep_time);
  int64_t delta = OS::GetCurrentTimeMillis() - start_time;
  const int kAcceptableSleepWakeupJitter = 100;  // Measured in milliseconds.
  EXPECT_GE(delta, sleep_time - kAcceptableSleepWakeupJitter);
  EXPECT_LE(delta, sleep_time + kAcceptableSleepWakeupJitter);
}

UNIT_TEST_CASE(SNPrint) {
  char buffer[256];
  int length;
  length = OS::SNPrint(buffer, 10, "%s", "foo");
  EXPECT_EQ(3, length);
  EXPECT_STREQ("foo", buffer);
  length = OS::SNPrint(buffer, 3, "%s", "foo");
  EXPECT_EQ(3, length);
  EXPECT_STREQ("fo", buffer);
  length = OS::SNPrint(buffer, 256, "%s%c%d", "foo", 'Z', 42);
  EXPECT_EQ(6, length);
  EXPECT_STREQ("fooZ42", buffer);
  length = OS::SNPrint(NULL, 0, "foo");
  EXPECT_EQ(3, length);
}

// This test is expected to crash when it runs.
UNIT_TEST_CASE(SNPrint_BadArgs) {
  int width = kMaxInt32;
  int num = 7;
  OS::SNPrint(NULL, 0, "%*d%*d", width, num, width, num);
}

UNIT_TEST_CASE(OsFuncs) {
  EXPECT(Utils::IsPowerOfTwo(OS::ActivationFrameAlignment()));
  EXPECT(Utils::IsPowerOfTwo(OS::PreferredCodeAlignment()));
  int procs = OS::NumberOfAvailableProcessors();
  EXPECT_LE(1, procs);
  EXPECT_LT(0U, OS::GetStackSizeLimit());
}

UNIT_TEST_CASE(OSAlignedAllocate) {
  // TODO(johnmccutchan): Test other alignments, once we support
  // alignments != 16 on Mac.
  void* p1 = OS::AlignedAllocate(1023, 16);
  void* p2 = OS::AlignedAllocate(1025, 16);
  void* p3 = OS::AlignedAllocate(1025, 16);
  void* p4 = OS::AlignedAllocate(1, 16);
  void* p5 = OS::AlignedAllocate(2, 16);
  void* p6 = OS::AlignedAllocate(4, 16);
  EXPECT((reinterpret_cast<intptr_t>(p1) & 15) == 0);
  EXPECT((reinterpret_cast<intptr_t>(p2) & 15) == 0);
  EXPECT((reinterpret_cast<intptr_t>(p3) & 15) == 0);
  EXPECT((reinterpret_cast<intptr_t>(p4) & 15) == 0);
  EXPECT((reinterpret_cast<intptr_t>(p5) & 15) == 0);
  EXPECT((reinterpret_cast<intptr_t>(p6) & 15) == 0);
  OS::AlignedFree(p1);
  OS::AlignedFree(p2);
  OS::AlignedFree(p3);
  OS::AlignedFree(p4);
  OS::AlignedFree(p5);
  OS::AlignedFree(p6);
}

}  // namespace dart
<commit_msg>Increase timeout jitter<commit_after>// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/assert.h"
#include "platform/utils.h"
#include "vm/globals.h"
#include "vm/os.h"
#include "vm/unit_test.h"

namespace dart {

UNIT_TEST_CASE(Sleep) {
  int64_t start_time = OS::GetCurrentTimeMillis();
  int64_t sleep_time = 702;
  OS::Sleep(sleep_time);
  int64_t delta = OS::GetCurrentTimeMillis() - start_time;
  const int kAcceptableSleepWakeupJitter = 200;  // Measured in milliseconds.
  EXPECT_GE(delta, sleep_time - kAcceptableSleepWakeupJitter);
  EXPECT_LE(delta, sleep_time + kAcceptableSleepWakeupJitter);
}

UNIT_TEST_CASE(SNPrint) {
  char buffer[256];
  int length;
  length = OS::SNPrint(buffer, 10, "%s", "foo");
  EXPECT_EQ(3, length);
  EXPECT_STREQ("foo", buffer);
  length = OS::SNPrint(buffer, 3, "%s", "foo");
  EXPECT_EQ(3, length);
  EXPECT_STREQ("fo", buffer);
  length = OS::SNPrint(buffer, 256, "%s%c%d", "foo", 'Z', 42);
  EXPECT_EQ(6, length);
  EXPECT_STREQ("fooZ42", buffer);
  length = OS::SNPrint(NULL, 0, "foo");
  EXPECT_EQ(3, length);
}

// This test is expected to crash when it runs.
UNIT_TEST_CASE(SNPrint_BadArgs) {
  int width = kMaxInt32;
  int num = 7;
  OS::SNPrint(NULL, 0, "%*d%*d", width, num, width, num);
}

UNIT_TEST_CASE(OsFuncs) {
  EXPECT(Utils::IsPowerOfTwo(OS::ActivationFrameAlignment()));
  EXPECT(Utils::IsPowerOfTwo(OS::PreferredCodeAlignment()));
  int procs = OS::NumberOfAvailableProcessors();
  EXPECT_LE(1, procs);
  EXPECT_LT(0U, OS::GetStackSizeLimit());
}

UNIT_TEST_CASE(OSAlignedAllocate) {
  // TODO(johnmccutchan): Test other alignments, once we support
  // alignments != 16 on Mac.
  void* p1 = OS::AlignedAllocate(1023, 16);
  void* p2 = OS::AlignedAllocate(1025, 16);
  void* p3 = OS::AlignedAllocate(1025, 16);
  void* p4 = OS::AlignedAllocate(1, 16);
  void* p5 = OS::AlignedAllocate(2, 16);
  void* p6 = OS::AlignedAllocate(4, 16);
  EXPECT((reinterpret_cast<intptr_t>(p1) & 15) == 0);
  EXPECT((reinterpret_cast<intptr_t>(p2) & 15) == 0);
  EXPECT((reinterpret_cast<intptr_t>(p3) & 15) == 0);
  EXPECT((reinterpret_cast<intptr_t>(p4) & 15) == 0);
  EXPECT((reinterpret_cast<intptr_t>(p5) & 15) == 0);
  EXPECT((reinterpret_cast<intptr_t>(p6) & 15) == 0);
  OS::AlignedFree(p1);
  OS::AlignedFree(p2);
  OS::AlignedFree(p3);
  OS::AlignedFree(p4);
  OS::AlignedFree(p5);
  OS::AlignedFree(p6);
}

}  // namespace dart
<|endoftext|>


<commit_before>/*
 * File:   render.cpp
 * Author: ivan
 *
 * Created on October 12, 2015, 11:04 PM
 */

#include "render.hpp"

#include <cmath>

#include <cairo/cairo.h>

#include <utki/util.hpp>

using namespace svgren;

namespace{

class CairoMatrixPush{
	cairo_matrix_t m;
	cairo_t* cr;
public:
	CairoMatrixPush(cairo_t* cr) :
			cr(cr)
	{
		ASSERT(this->cr)
		cairo_get_matrix(this->cr, &this->m);
	}
	~CairoMatrixPush()noexcept{
		cairo_set_matrix(this->cr, &this->m);
	}
};

class Renderer : public svgdom::Renderer{
	cairo_t* curCr;

	cairo_t* cr;

	void applyTransformations(const svgdom::Transformable& transformable)const{
		for(auto& t : transformable.transformations){
			switch(t.type){
				case svgdom::Transformable::Transformation::EType::TRANSLATE:
					cairo_translate(this->curCr, t.x, t.y);
					break;
				case svgdom::Transformable::Transformation::EType::MATRIX:
					{
						cairo_matrix_t matrix;
						matrix.xx = t.a;
						matrix.yx = t.b;
						matrix.xy = t.c;
						matrix.yy = t.d;
						matrix.x0 = t.e;
						matrix.y0 = t.f;
						cairo_transform(this->curCr, &matrix);
					}
					break;
				case svgdom::Transformable::Transformation::EType::SCALE:
					cairo_scale(this->curCr, t.x, t.y);
					break;
				case svgdom::Transformable::Transformation::EType::ROTATE:
					cairo_translate(this->curCr, t.x, t.y);
					cairo_rotate(this->curCr, t.angle);
					cairo_translate(this->curCr, -t.x, -t.y);
					break;
				case svgdom::Transformable::Transformation::EType::SKEWX:
					{
						cairo_matrix_t matrix;
						matrix.xx = 1;
						matrix.yx = 0;
						matrix.xy = std::tan(t.angle);
						matrix.yy = 1;
						matrix.x0 = 0;
						matrix.y0 = 0;
						cairo_transform(this->curCr, &matrix);
					}
					break;
				case svgdom::Transformable::Transformation::EType::SKEWY:
					{
						cairo_matrix_t matrix;
						matrix.xx = 1;
						matrix.yx = std::tan(t.angle);
						matrix.xy = 0;
						matrix.yy = 1;
						matrix.x0 = 0;
						matrix.y0 = 0;
						cairo_transform(this->curCr, &matrix);
					}
					break;
				default:
					ASSERT(false)
					break;
			}
		}
	}

	void renderCurrentShape(const svgdom::Shape& e){
		auto fill = e.getStyleProperty(svgdom::EStyleProperty::FILL);
		auto stroke = e.getStyleProperty(svgdom::EStyleProperty::STROKE);

		if(fill && !fill->isNone()){
			svgdom::real opacity;
			if(auto p = e.getStyleProperty(svgdom::EStyleProperty::FILL_OPACITY)){
				opacity = p->opacity;
			}else{
				opacity = 1;
			}

			if(fill->rule == svgdom::StylePropertyValue::ERule::URL){
				//TODO:
			}else{
				auto fillRgb = fill->getRgb();
				cairo_set_source_rgba(this->curCr, fillRgb.r, fillRgb.g, fillRgb.b, opacity);
			}

			if(stroke && !stroke->isNone()){
				cairo_fill_preserve(this->curCr);
			}else{
				cairo_fill(this->curCr);
			}
		}

		if(stroke && !stroke->isNone()){
			if(auto p = e.getStyleProperty(svgdom::EStyleProperty::STROKE_WIDTH)){
				cairo_set_line_width(curCr, p->length.value);
			}else{
				cairo_set_line_width(curCr, 1);
			}

			svgdom::real opacity;
			if(auto p = e.getStyleProperty(svgdom::EStyleProperty::STROKE_OPACITY)){
				opacity = p->opacity;
			}else{
				opacity = 1;
			}

			auto rgb = stroke->getRgb();

			cairo_set_source_rgba(this->curCr, rgb.r, rgb.g, rgb.b, opacity);
			cairo_stroke(this->curCr);
		}
	}

public:
	Renderer(cairo_t* cr) :
			cr(cr)
	{
		this->curCr = this->cr;
	}

	void render(const svgdom::GElement& e)override{
		CairoMatrixPush cairoMatrixPush(this->curCr);

		this->applyTransformations(e);

		e.Container::render(*this);
	}

	void render(const svgdom::SvgElement& e)override{
		e.Container::render(*this);
	}

	void render(const svgdom::PathElement& e)override{
		CairoMatrixPush cairoMatrixPush(this->curCr);

		this->applyTransformations(e);

//		const svgdom::PathElement::Step* prev = nullptr;
		for(auto& s : e.path){
			switch(s.type){
				case svgdom::PathElement::Step::EType::MOVE_ABS:
					cairo_move_to(this->curCr, s.x, s.y);
					break;
				case svgdom::PathElement::Step::EType::MOVE_REL:
					cairo_rel_move_to(this->curCr, s.x, s.y);
					break;
				case svgdom::PathElement::Step::EType::LINE_ABS:
					cairo_line_to(this->curCr, s.x, s.y);
					break;
				case svgdom::PathElement::Step::EType::LINE_REL:
					cairo_rel_line_to(this->curCr, s.x, s.y);
					break;
				case svgdom::PathElement::Step::EType::HORIZONTAL_LINE_ABS:
					{
						double x, y;
						if(cairo_has_current_point(this->curCr)){
							cairo_get_current_point(this->curCr, &x, &y);
						}else{
							y = 0;
						}
						cairo_line_to(this->curCr, s.x, y);
					}
					break;
				case svgdom::PathElement::Step::EType::HORIZONTAL_LINE_REL:
					{
						double x, y;
						if(cairo_has_current_point(this->curCr)){
							cairo_get_current_point(this->curCr, &x, &y);
						}else{
							y = 0;
						}
						cairo_rel_line_to(this->curCr, s.x, y);
					}
					break;
				case svgdom::PathElement::Step::EType::VERTICAL_LINE_ABS:
					{
						double x, y;
						if(cairo_has_current_point(this->curCr)){
							cairo_get_current_point(this->curCr, &x, &y);
						}else{
							x = 0;
						}
						cairo_line_to(this->curCr, x, s.y);
					}
					break;
				case svgdom::PathElement::Step::EType::VERTICAL_LINE_REL:
					{
						double x, y;
						if(cairo_has_current_point(this->curCr)){
							cairo_get_current_point(this->curCr, &x, &y);
						}else{
							x = 0;
						}
						cairo_rel_line_to(this->curCr, x, s.y);
					}
					break;
				case svgdom::PathElement::Step::EType::CLOSE:
					cairo_close_path(this->curCr);
					break;
				case svgdom::PathElement::Step::EType::CUBIC_ABS:
					cairo_curve_to(this->curCr, s.x1, s.y1, s.x2, s.y2, s.x, s.y);
					break;
				case svgdom::PathElement::Step::EType::CUBIC_REL:
					cairo_rel_curve_to(this->curCr, s.x1, s.y1, s.x2, s.y2, s.x, s.y);
					break;
//				case svgdom::PathElement::Step::EType::CUBIC_SMOOTH_ABS:
//					{
//						double x, y;
//						if(cairo_has_current_point(this->cr)){
//							cairo_get_current_point(this->cr, &x, &y);
//						}else{
//							x = 0;
//							y = 0;
//						}
//						double x1, y1;
//						if(prev){
//							x1 = -(prev->x2 - x) + x;
//							y1 = -(prev->y2 - y) + y;
//						}else{
//							x1 = x;
//							y1 = y;
//						}
//						cairo_curve_to(this->cr, x1, y1, s.x2, s.y2, s.x, s.y);
//					}
//					break;
				default:
					ASSERT(false)
					break;
			}
//			prev = &s;
		}

		this->renderCurrentShape(e);
	}

	void render(const svgdom::RectElement& e) override{
		CairoMatrixPush cairoMatrixPush(this->curCr);

		this->applyTransformations(e);

		if((e.rx.value == 0 || e.rx.unit == svgdom::Length::EUnit::UNKNOWN)
				&& (e.ry.value == 0 || e.ry.unit == svgdom::Length::EUnit::UNKNOWN))
		{
			cairo_rectangle(this->curCr, e.x.value, e.y.value, e.width.value, e.height.value);
		}else{
			//compute real rx and ry
			auto rx = e.rx;
			auto ry = e.ry;

			if(ry.unit == svgdom::Length::EUnit::UNKNOWN && rx.unit != svgdom::Length::EUnit::UNKNOWN){
				ry = rx;
			}else if(rx.unit == svgdom::Length::EUnit::UNKNOWN && ry.unit != svgdom::Length::EUnit::UNKNOWN){
				rx = ry;
			}
			ASSERT(rx.unit != svgdom::Length::EUnit::UNKNOWN && ry.unit != svgdom::Length::EUnit::UNKNOWN)

			if(rx.value > e.width.value / 2){
				rx.value = e.width.value / 2;
			}
			if(ry.value > e.height.value / 2){
				ry.value = e.height.value / 2;
			}

			cairo_move_to(this->curCr, e.x.value + rx.value, e.y.value);
			cairo_line_to(this->curCr, e.x.value + e.width.value - rx.value, e.y.value);

			cairo_save (this->curCr);
			cairo_translate (this->curCr, e.x.value + e.width.value - rx.value, e.y.value + ry.value);
			cairo_scale (this->curCr, rx.value, ry.value);
			cairo_arc (this->curCr, 0, 0, 1, -M_PI / 2, 0);
			cairo_restore (this->curCr);

			cairo_line_to(this->curCr, e.x.value + e.width.value, e.y.value + e.height.value - ry.value);

			cairo_save (this->curCr);
			cairo_translate (this->curCr, e.x.value + e.width.value - rx.value, e.y.value + e.height.value - ry.value);
			cairo_scale (this->curCr, rx.value, ry.value);
			cairo_arc (this->curCr, 0, 0, 1, 0, M_PI / 2);
			cairo_restore (this->curCr);

			cairo_line_to(this->curCr, e.x.value + rx.value, e.y.value + e.height.value);

			cairo_save (this->curCr);
			cairo_translate (this->curCr, e.x.value + rx.value, e.y.value + e.height.value - ry.value);
			cairo_scale (this->curCr, rx.value, ry.value);
			cairo_arc (this->curCr, 0, 0, 1, M_PI / 2, M_PI);
			cairo_restore (this->curCr);

			cairo_line_to(this->curCr, e.x.value, e.y.value + ry.value);

			cairo_save (this->curCr);
			cairo_translate (this->curCr, e.x.value + rx.value, e.y.value + ry.value);
			cairo_scale (this->curCr, rx.value, ry.value);
			cairo_arc (this->curCr, 0, 0, 1, M_PI, M_PI * 3 / 2);
			cairo_restore (this->curCr);

			cairo_close_path(this->curCr);
		}

		this->renderCurrentShape(e);
	}
};

}//~namespace

std::vector<std::uint32_t> svgren::render(const svgdom::SvgElement& svg, unsigned width, unsigned height){
//	int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
	int stride = width * 4;

	TRACE(<< "width = " << width << " stride = " << stride / 4 << std::endl)

	std::vector<std::uint32_t> ret((stride / sizeof(std::uint32_t)) * height);

	for(auto& c : ret){
		c = 0xffffffff;//TODO: fill 0
	}

	cairo_surface_t* surface = cairo_image_surface_create_for_data(
			reinterpret_cast<unsigned char*>(&*ret.begin()),
			CAIRO_FORMAT_ARGB32,
			width,
			height,
			stride
		);
	if(!surface){
		ret.clear();
		return ret;
	}
	utki::ScopeExit scopeExitSurface([&surface](){
		cairo_surface_destroy(surface);
	});

	cairo_t* cr = cairo_create(surface);
	if(!cr){
		ret.clear();
		return ret;
	}
	utki::ScopeExit scopeExitContext([&cr](){
		cairo_destroy(cr);
	});

	Renderer r(cr);

	svg.render(r);

	return ret;
}
<commit_msg>stuff<commit_after>/*
 * File:   render.cpp
 * Author: ivan
 *
 * Created on October 12, 2015, 11:04 PM
 */

#include "render.hpp"

#include <cmath>

#include <cairo/cairo.h>

#include <utki/util.hpp>

using namespace svgren;

namespace{

class CairoMatrixPush{
	cairo_matrix_t m;
	cairo_t* cr;
public:
	CairoMatrixPush(cairo_t* cr) :
			cr(cr)
	{
		ASSERT(this->cr)
		cairo_get_matrix(this->cr, &this->m);
	}
	~CairoMatrixPush()noexcept{
		cairo_set_matrix(this->cr, &this->m);
	}
};

class Renderer : public svgdom::Renderer{
	cairo_t* curCr;

	cairo_t* cr;

	void applyTransformations(const svgdom::Transformable& transformable)const{
		for(auto& t : transformable.transformations){
			switch(t.type){
				case svgdom::Transformable::Transformation::EType::TRANSLATE:
					cairo_translate(this->curCr, t.x, t.y);
					break;
				case svgdom::Transformable::Transformation::EType::MATRIX:
					{
						cairo_matrix_t matrix;
						matrix.xx = t.a;
						matrix.yx = t.b;
						matrix.xy = t.c;
						matrix.yy = t.d;
						matrix.x0 = t.e;
						matrix.y0 = t.f;
						cairo_transform(this->curCr, &matrix);
					}
					break;
				case svgdom::Transformable::Transformation::EType::SCALE:
					cairo_scale(this->curCr, t.x, t.y);
					break;
				case svgdom::Transformable::Transformation::EType::ROTATE:
					cairo_translate(this->curCr, t.x, t.y);
					cairo_rotate(this->curCr, t.angle);
					cairo_translate(this->curCr, -t.x, -t.y);
					break;
				case svgdom::Transformable::Transformation::EType::SKEWX:
					{
						cairo_matrix_t matrix;
						matrix.xx = 1;
						matrix.yx = 0;
						matrix.xy = std::tan(t.angle);
						matrix.yy = 1;
						matrix.x0 = 0;
						matrix.y0 = 0;
						cairo_transform(this->curCr, &matrix);
					}
					break;
				case svgdom::Transformable::Transformation::EType::SKEWY:
					{
						cairo_matrix_t matrix;
						matrix.xx = 1;
						matrix.yx = std::tan(t.angle);
						matrix.xy = 0;
						matrix.yy = 1;
						matrix.x0 = 0;
						matrix.y0 = 0;
						cairo_transform(this->curCr, &matrix);
					}
					break;
				default:
					ASSERT(false)
					break;
			}
		}
	}

	void renderCurrentShape(const svgdom::Shape& e){
		auto fill = e.getStyleProperty(svgdom::EStyleProperty::FILL);
		auto stroke = e.getStyleProperty(svgdom::EStyleProperty::STROKE);

		if(fill && !fill->isNone()){
			svgdom::real opacity;
			if(auto p = e.getStyleProperty(svgdom::EStyleProperty::FILL_OPACITY)){
				opacity = p->opacity;
			}else{
				opacity = 1;
			}

			if(fill->isUrl()){
				if(fill->url){
					//TODO:
				}else{
					cairo_set_source_rgba(this->curCr, 0, 0, 0, 0);
				}
			}else{
				auto fillRgb = fill->getRgb();
				cairo_set_source_rgba(this->curCr, fillRgb.r, fillRgb.g, fillRgb.b, opacity);
			}

			if(stroke && !stroke->isNone()){
				cairo_fill_preserve(this->curCr);
			}else{
				cairo_fill(this->curCr);
			}
		}

		if(stroke && !stroke->isNone()){
			if(auto p = e.getStyleProperty(svgdom::EStyleProperty::STROKE_WIDTH)){
				cairo_set_line_width(curCr, p->length.value);
			}else{
				cairo_set_line_width(curCr, 1);
			}

			svgdom::real opacity;
			if(auto p = e.getStyleProperty(svgdom::EStyleProperty::STROKE_OPACITY)){
				opacity = p->opacity;
			}else{
				opacity = 1;
			}

			auto rgb = stroke->getRgb();
			cairo_set_source_rgba(this->curCr, rgb.r, rgb.g, rgb.b, opacity);

			cairo_stroke(this->curCr);
		}
	}

public:
	Renderer(cairo_t* cr) :
			cr(cr)
	{
		this->curCr = this->cr;
	}

	void render(const svgdom::GElement& e)override{
		CairoMatrixPush cairoMatrixPush(this->curCr);

		this->applyTransformations(e);

		e.Container::render(*this);
	}

	void render(const svgdom::SvgElement& e)override{
		e.Container::render(*this);
	}

	void render(const svgdom::PathElement& e)override{
		CairoMatrixPush cairoMatrixPush(this->curCr);

		this->applyTransformations(e);

//		const svgdom::PathElement::Step* prev = nullptr;
		for(auto& s : e.path){
			switch(s.type){
				case svgdom::PathElement::Step::EType::MOVE_ABS:
					cairo_move_to(this->curCr, s.x, s.y);
					break;
				case svgdom::PathElement::Step::EType::MOVE_REL:
					cairo_rel_move_to(this->curCr, s.x, s.y);
					break;
				case svgdom::PathElement::Step::EType::LINE_ABS:
					cairo_line_to(this->curCr, s.x, s.y);
					break;
				case svgdom::PathElement::Step::EType::LINE_REL:
					cairo_rel_line_to(this->curCr, s.x, s.y);
					break;
				case svgdom::PathElement::Step::EType::HORIZONTAL_LINE_ABS:
					{
						double x, y;
						if(cairo_has_current_point(this->curCr)){
							cairo_get_current_point(this->curCr, &x, &y);
						}else{
							y = 0;
						}
						cairo_line_to(this->curCr, s.x, y);
					}
					break;
				case svgdom::PathElement::Step::EType::HORIZONTAL_LINE_REL:
					{
						double x, y;
						if(cairo_has_current_point(this->curCr)){
							cairo_get_current_point(this->curCr, &x, &y);
						}else{
							y = 0;
						}
						cairo_rel_line_to(this->curCr, s.x, y);
					}
					break;
				case svgdom::PathElement::Step::EType::VERTICAL_LINE_ABS:
					{
						double x, y;
						if(cairo_has_current_point(this->curCr)){
							cairo_get_current_point(this->curCr, &x, &y);
						}else{
							x = 0;
						}
						cairo_line_to(this->curCr, x, s.y);
					}
					break;
				case svgdom::PathElement::Step::EType::VERTICAL_LINE_REL:
					{
						double x, y;
						if(cairo_has_current_point(this->curCr)){
							cairo_get_current_point(this->curCr, &x, &y);
						}else{
							x = 0;
						}
						cairo_rel_line_to(this->curCr, x, s.y);
					}
					break;
				case svgdom::PathElement::Step::EType::CLOSE:
					cairo_close_path(this->curCr);
					break;
				case svgdom::PathElement::Step::EType::CUBIC_ABS:
					cairo_curve_to(this->curCr, s.x1, s.y1, s.x2, s.y2, s.x, s.y);
					break;
				case svgdom::PathElement::Step::EType::CUBIC_REL:
					cairo_rel_curve_to(this->curCr, s.x1, s.y1, s.x2, s.y2, s.x, s.y);
					break;
//				case svgdom::PathElement::Step::EType::CUBIC_SMOOTH_ABS:
//					{
//						double x, y;
//						if(cairo_has_current_point(this->cr)){
//							cairo_get_current_point(this->cr, &x, &y);
//						}else{
//							x = 0;
//							y = 0;
//						}
//						double x1, y1;
//						if(prev){
//							x1 = -(prev->x2 - x) + x;
//							y1 = -(prev->y2 - y) + y;
//						}else{
//							x1 = x;
//							y1 = y;
//						}
//						cairo_curve_to(this->cr, x1, y1, s.x2, s.y2, s.x, s.y);
//					}
//					break;
				default:
					ASSERT(false)
					break;
			}
//			prev = &s;
		}

		this->renderCurrentShape(e);
	}

	void render(const svgdom::RectElement& e) override{
		CairoMatrixPush cairoMatrixPush(this->curCr);

		this->applyTransformations(e);

		if((e.rx.value == 0 || e.rx.unit == svgdom::Length::EUnit::UNKNOWN)
				&& (e.ry.value == 0 || e.ry.unit == svgdom::Length::EUnit::UNKNOWN))
		{
			cairo_rectangle(this->curCr, e.x.value, e.y.value, e.width.value, e.height.value);
		}else{
			//compute real rx and ry
			auto rx = e.rx;
			auto ry = e.ry;

			if(ry.unit == svgdom::Length::EUnit::UNKNOWN && rx.unit != svgdom::Length::EUnit::UNKNOWN){
				ry = rx;
			}else if(rx.unit == svgdom::Length::EUnit::UNKNOWN && ry.unit != svgdom::Length::EUnit::UNKNOWN){
				rx = ry;
			}
			ASSERT(rx.unit != svgdom::Length::EUnit::UNKNOWN && ry.unit != svgdom::Length::EUnit::UNKNOWN)

			if(rx.value > e.width.value / 2){
				rx.value = e.width.value / 2;
			}
			if(ry.value > e.height.value / 2){
				ry.value = e.height.value / 2;
			}

			cairo_move_to(this->curCr, e.x.value + rx.value, e.y.value);
			cairo_line_to(this->curCr, e.x.value + e.width.value - rx.value, e.y.value);

			cairo_save (this->curCr);
			cairo_translate (this->curCr, e.x.value + e.width.value - rx.value, e.y.value + ry.value);
			cairo_scale (this->curCr, rx.value, ry.value);
			cairo_arc (this->curCr, 0, 0, 1, -M_PI / 2, 0);
			cairo_restore (this->curCr);

			cairo_line_to(this->curCr, e.x.value + e.width.value, e.y.value + e.height.value - ry.value);

			cairo_save (this->curCr);
			cairo_translate (this->curCr, e.x.value + e.width.value - rx.value, e.y.value + e.height.value - ry.value);
			cairo_scale (this->curCr, rx.value, ry.value);
			cairo_arc (this->curCr, 0, 0, 1, 0, M_PI / 2);
			cairo_restore (this->curCr);

			cairo_line_to(this->curCr, e.x.value + rx.value, e.y.value + e.height.value);

			cairo_save (this->curCr);
			cairo_translate (this->curCr, e.x.value + rx.value, e.y.value + e.height.value - ry.value);
			cairo_scale (this->curCr, rx.value, ry.value);
			cairo_arc (this->curCr, 0, 0, 1, M_PI / 2, M_PI);
			cairo_restore (this->curCr);

			cairo_line_to(this->curCr, e.x.value, e.y.value + ry.value);

			cairo_save (this->curCr);
			cairo_translate (this->curCr, e.x.value + rx.value, e.y.value + ry.value);
			cairo_scale (this->curCr, rx.value, ry.value);
			cairo_arc (this->curCr, 0, 0, 1, M_PI, M_PI * 3 / 2);
			cairo_restore (this->curCr);

			cairo_close_path(this->curCr);
		}

		this->renderCurrentShape(e);
	}
};

}//~namespace

std::vector<std::uint32_t> svgren::render(const svgdom::SvgElement& svg, unsigned width, unsigned height){
//	int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
	int stride = width * 4;

	TRACE(<< "width = " << width << " stride = " << stride / 4 << std::endl)

	std::vector<std::uint32_t> ret((stride / sizeof(std::uint32_t)) * height);

	for(auto& c : ret){
		c = 0xffffffff;//TODO: fill 0
	}

	cairo_surface_t* surface = cairo_image_surface_create_for_data(
			reinterpret_cast<unsigned char*>(&*ret.begin()),
			CAIRO_FORMAT_ARGB32,
			width,
			height,
			stride
		);
	if(!surface){
		ret.clear();
		return ret;
	}
	utki::ScopeExit scopeExitSurface([&surface](){
		cairo_surface_destroy(surface);
	});

	cairo_t* cr = cairo_create(surface);
	if(!cr){
		ret.clear();
		return ret;
	}
	utki::ScopeExit scopeExitContext([&cr](){
		cairo_destroy(cr);
	});

	Renderer r(cr);

	svg.render(r);

	return ret;
}
<|endoftext|>


<commit_before>#include <sal/lockable.hpp>
#include <sal/common.test.hpp>

namespace {

struct locked_ptr
  : public sal_test::fixture
{
  int data{};
  std::mutex mutex{};
  using ptr = sal::locked_ptr<int, std::mutex>;
};

TEST_F(locked_ptr, ctor_lock)
{
  ptr p(&data, mutex);
  EXPECT_FALSE(mutex.try_lock());
}

TEST_F(locked_ptr, ctor_adopt_lock)
{
  mutex.lock();
  {
    ptr p(&data, mutex, std::adopt_lock);
    EXPECT_TRUE(bool(p));
  }
  EXPECT_TRUE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, ctor_try_lock)
{
  {
    ptr p(&data, mutex, std::try_to_lock);
    EXPECT_TRUE(bool(p));
  }
  EXPECT_TRUE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, ctor_try_lock_fail)
{
  mutex.lock();
  {
    ptr p(&data, mutex, std::try_to_lock);
    EXPECT_FALSE(bool(p));
  }
  EXPECT_FALSE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, ctor_defer_lock)
{
  mutex.lock();
  {
    ptr p(&data, mutex, std::defer_lock);
    EXPECT_TRUE(bool(p));
  }
  EXPECT_FALSE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, dtor_unlock)
{
  {
    ptr p(&data, mutex);
    EXPECT_FALSE(mutex.try_lock());
  }
  EXPECT_TRUE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, dtor_no_unlock_unlocked)
{
  {
    ptr p(&data, mutex);
    p.unlock();
    EXPECT_TRUE(mutex.try_lock());
  }
  EXPECT_FALSE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, move_ctor)
{
  {
    ptr src(&data, mutex);
    EXPECT_TRUE(bool(src));
    EXPECT_EQ(&data, src.get());
    EXPECT_FALSE(mutex.try_lock());

    auto dest = std::move(src);
    EXPECT_TRUE(bool(dest));
    EXPECT_EQ(&data, dest.get());
    EXPECT_FALSE(mutex.try_lock());

    EXPECT_FALSE(bool(src));
    EXPECT_EQ(nullptr, src.get());
    EXPECT_FALSE(mutex.try_lock());
  }
  EXPECT_TRUE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, move_assign)
{
  {
    ptr src(&data, mutex);
    EXPECT_TRUE(bool(src));
    EXPECT_EQ(&data, src.get());
    EXPECT_FALSE(mutex.try_lock());

    int other_data{};
    std::mutex other_mutex{};
    ptr dest(&other_data, other_mutex);
    EXPECT_FALSE(other_mutex.try_lock());

    dest = std::move(src);
    EXPECT_TRUE(other_mutex.try_lock());
    other_mutex.unlock();

    EXPECT_TRUE(bool(dest));
    EXPECT_EQ(&data, dest.get());
    EXPECT_FALSE(mutex.try_lock());

    EXPECT_FALSE(bool(src));
    EXPECT_EQ(nullptr, src.get());
    EXPECT_FALSE(mutex.try_lock());
  }
  EXPECT_TRUE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, move_assign_no_unlock_unlocked)
{
  int other_data{};
  std::mutex other_mutex{};
  {
    ptr src(&data, mutex);
    ptr dest(&other_data, other_mutex);

    dest.unlock();
    EXPECT_TRUE(other_mutex.try_lock());

    dest = std::move(src);
    EXPECT_EQ(&data, dest.get());
  }
  EXPECT_FALSE(other_mutex.try_lock());
  other_mutex.unlock();
}

TEST_F(locked_ptr, swap)
{
  int other_data{};
  std::mutex other_mutex{};
  {
    ptr a(&data, mutex);
    EXPECT_EQ(&data, a.get());
    EXPECT_FALSE(mutex.try_lock());

    ptr b(&other_data, other_mutex);
    EXPECT_EQ(&other_data, b.get());
    EXPECT_FALSE(other_mutex.try_lock());

    swap(a, b);
    EXPECT_EQ(&data, b.get());
    EXPECT_FALSE(mutex.try_lock());
    EXPECT_EQ(&other_data, a.get());
    EXPECT_FALSE(other_mutex.try_lock());
  }
  EXPECT_TRUE(mutex.try_lock());
  mutex.unlock();
  EXPECT_TRUE(other_mutex.try_lock());
  other_mutex.unlock();
}

TEST_F(locked_ptr, explicit_unlock)
{
  ptr p(&data, mutex);
  EXPECT_FALSE(mutex.try_lock());

  p.unlock();
  EXPECT_TRUE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, bool)
{
  ptr p(&data, mutex);
  EXPECT_TRUE(bool(p));

  p.unlock();
  EXPECT_FALSE(bool(p));
}

TEST_F(locked_ptr, operator_arrow)
{
  EXPECT_EQ(0, data);

  sal::locked_ptr<locked_ptr, std::mutex> p(this, mutex);
  EXPECT_EQ(0, p->data);

  p->data = 1;
  EXPECT_EQ(1, data);
}

TEST_F(locked_ptr, operator_deref)
{
  EXPECT_EQ(0, data);

  sal::locked_ptr<int, std::mutex> p(&data, mutex);
  EXPECT_EQ(0, data);

  *p = 1;
  EXPECT_EQ(1, data);
}

} // namespace

namespace {

struct lockable
  : public sal_test::fixture
{
  int data{};
  sal::lockable_t<int> l{data};
};

TEST_F(lockable, lock)
{
  EXPECT_EQ(0, data);

  auto p = l.lock();
  EXPECT_FALSE(bool(l.try_lock()));

  *p = 1;
  EXPECT_EQ(1, data);
}

void lock (const sal::lockable_t<int> &l)
{
  auto p = l.lock();
  EXPECT_FALSE(bool(l.try_lock()));
  EXPECT_EQ(1, *p);
  //COMPILER ERROR: *p = 2;
}

TEST_F(lockable, const_lock)
{
  data = 1;
  lock(l);
  EXPECT_EQ(1, data);
}

TEST_F(lockable, try_lock)
{
  EXPECT_EQ(0, data);

  auto p = l.try_lock();
  EXPECT_FALSE(bool(l.try_lock()));

  *p = 1;
  EXPECT_EQ(1, data);
}

void try_lock (const sal::lockable_t<int> &l)
{
  auto p = l.try_lock();
  EXPECT_FALSE(bool(l.try_lock()));
  EXPECT_EQ(1, *p);
  //COMPILER ERROR: *p = 2;
}

TEST_F(lockable, const_try_lock)
{
  data = 1;
  try_lock(l);
  EXPECT_EQ(1, data);
}

TEST_F(lockable, unlocked)
{
  EXPECT_EQ(0, data);

  auto p = l.unlocked();
  EXPECT_TRUE(bool(l.try_lock()));

  *p = 1;
  EXPECT_EQ(1, data);
}

void unlocked (const sal::lockable_t<int> &l)
{
  auto p = l.unlocked();
  EXPECT_TRUE(bool(l.try_lock()));
  EXPECT_EQ(1, *p);
  //COMPILER ERROR: *p = 2;
}

TEST_F(lockable, const_unlocked)
{
  data = 1;
  unlocked(l);
  EXPECT_EQ(1, data);
}

TEST_F(lockable, devel)
{
  int data = 1;

  using lockable_int = sal::lockable_t<int>;
  using locked_int_ptr = lockable_int::ptr;

  lockable_int i{data};
  if (locked_int_ptr ip = i.lock())
  {
    *ip = 2;
  }

  EXPECT_EQ(2, data);
}

} // namespace
<commit_msg>Remove missed temporary unittest<commit_after>#include <sal/lockable.hpp>
#include <sal/common.test.hpp>

namespace {

struct locked_ptr
  : public sal_test::fixture
{
  int data{};
  std::mutex mutex{};
  using ptr = sal::locked_ptr<int, std::mutex>;
};

TEST_F(locked_ptr, ctor_lock)
{
  ptr p(&data, mutex);
  EXPECT_FALSE(mutex.try_lock());
}

TEST_F(locked_ptr, ctor_adopt_lock)
{
  mutex.lock();
  {
    ptr p(&data, mutex, std::adopt_lock);
    EXPECT_TRUE(bool(p));
  }
  EXPECT_TRUE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, ctor_try_lock)
{
  {
    ptr p(&data, mutex, std::try_to_lock);
    EXPECT_TRUE(bool(p));
  }
  EXPECT_TRUE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, ctor_try_lock_fail)
{
  mutex.lock();
  {
    ptr p(&data, mutex, std::try_to_lock);
    EXPECT_FALSE(bool(p));
  }
  EXPECT_FALSE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, ctor_defer_lock)
{
  mutex.lock();
  {
    ptr p(&data, mutex, std::defer_lock);
    EXPECT_TRUE(bool(p));
  }
  EXPECT_FALSE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, dtor_unlock)
{
  {
    ptr p(&data, mutex);
    EXPECT_FALSE(mutex.try_lock());
  }
  EXPECT_TRUE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, dtor_no_unlock_unlocked)
{
  {
    ptr p(&data, mutex);
    p.unlock();
    EXPECT_TRUE(mutex.try_lock());
  }
  EXPECT_FALSE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, move_ctor)
{
  {
    ptr src(&data, mutex);
    EXPECT_TRUE(bool(src));
    EXPECT_EQ(&data, src.get());
    EXPECT_FALSE(mutex.try_lock());

    auto dest = std::move(src);
    EXPECT_TRUE(bool(dest));
    EXPECT_EQ(&data, dest.get());
    EXPECT_FALSE(mutex.try_lock());

    EXPECT_FALSE(bool(src));
    EXPECT_EQ(nullptr, src.get());
    EXPECT_FALSE(mutex.try_lock());
  }
  EXPECT_TRUE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, move_assign)
{
  {
    ptr src(&data, mutex);
    EXPECT_TRUE(bool(src));
    EXPECT_EQ(&data, src.get());
    EXPECT_FALSE(mutex.try_lock());

    int other_data{};
    std::mutex other_mutex{};
    ptr dest(&other_data, other_mutex);
    EXPECT_FALSE(other_mutex.try_lock());

    dest = std::move(src);
    EXPECT_TRUE(other_mutex.try_lock());
    other_mutex.unlock();

    EXPECT_TRUE(bool(dest));
    EXPECT_EQ(&data, dest.get());
    EXPECT_FALSE(mutex.try_lock());

    EXPECT_FALSE(bool(src));
    EXPECT_EQ(nullptr, src.get());
    EXPECT_FALSE(mutex.try_lock());
  }
  EXPECT_TRUE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, move_assign_no_unlock_unlocked)
{
  int other_data{};
  std::mutex other_mutex{};
  {
    ptr src(&data, mutex);
    ptr dest(&other_data, other_mutex);

    dest.unlock();
    EXPECT_TRUE(other_mutex.try_lock());

    dest = std::move(src);
    EXPECT_EQ(&data, dest.get());
  }
  EXPECT_FALSE(other_mutex.try_lock());
  other_mutex.unlock();
}

TEST_F(locked_ptr, swap)
{
  int other_data{};
  std::mutex other_mutex{};
  {
    ptr a(&data, mutex);
    EXPECT_EQ(&data, a.get());
    EXPECT_FALSE(mutex.try_lock());

    ptr b(&other_data, other_mutex);
    EXPECT_EQ(&other_data, b.get());
    EXPECT_FALSE(other_mutex.try_lock());

    swap(a, b);
    EXPECT_EQ(&data, b.get());
    EXPECT_FALSE(mutex.try_lock());
    EXPECT_EQ(&other_data, a.get());
    EXPECT_FALSE(other_mutex.try_lock());
  }
  EXPECT_TRUE(mutex.try_lock());
  mutex.unlock();
  EXPECT_TRUE(other_mutex.try_lock());
  other_mutex.unlock();
}

TEST_F(locked_ptr, explicit_unlock)
{
  ptr p(&data, mutex);
  EXPECT_FALSE(mutex.try_lock());

  p.unlock();
  EXPECT_TRUE(mutex.try_lock());
  mutex.unlock();
}

TEST_F(locked_ptr, bool)
{
  ptr p(&data, mutex);
  EXPECT_TRUE(bool(p));

  p.unlock();
  EXPECT_FALSE(bool(p));
}

TEST_F(locked_ptr, operator_arrow)
{
  EXPECT_EQ(0, data);

  sal::locked_ptr<locked_ptr, std::mutex> p(this, mutex);
  EXPECT_EQ(0, p->data);

  p->data = 1;
  EXPECT_EQ(1, data);
}

TEST_F(locked_ptr, operator_deref)
{
  EXPECT_EQ(0, data);

  sal::locked_ptr<int, std::mutex> p(&data, mutex);
  EXPECT_EQ(0, data);

  *p = 1;
  EXPECT_EQ(1, data);
}

} // namespace

namespace {

struct lockable
  : public sal_test::fixture
{
  int data{};
  sal::lockable_t<int> l{data};
};

TEST_F(lockable, lock)
{
  EXPECT_EQ(0, data);

  auto p = l.lock();
  EXPECT_FALSE(bool(l.try_lock()));

  *p = 1;
  EXPECT_EQ(1, data);
}

void lock (const sal::lockable_t<int> &l)
{
  auto p = l.lock();
  EXPECT_FALSE(bool(l.try_lock()));
  EXPECT_EQ(1, *p);
  //COMPILER ERROR: *p = 2;
}

TEST_F(lockable, const_lock)
{
  data = 1;
  lock(l);
  EXPECT_EQ(1, data);
}

TEST_F(lockable, try_lock)
{
  EXPECT_EQ(0, data);

  auto p = l.try_lock();
  EXPECT_FALSE(bool(l.try_lock()));

  *p = 1;
  EXPECT_EQ(1, data);
}

void try_lock (const sal::lockable_t<int> &l)
{
  auto p = l.try_lock();
  EXPECT_FALSE(bool(l.try_lock()));
  EXPECT_EQ(1, *p);
  //COMPILER ERROR: *p = 2;
}

TEST_F(lockable, const_try_lock)
{
  data = 1;
  try_lock(l);
  EXPECT_EQ(1, data);
}

TEST_F(lockable, unlocked)
{
  EXPECT_EQ(0, data);

  auto p = l.unlocked();
  EXPECT_TRUE(bool(l.try_lock()));

  *p = 1;
  EXPECT_EQ(1, data);
}

void unlocked (const sal::lockable_t<int> &l)
{
  auto p = l.unlocked();
  EXPECT_TRUE(bool(l.try_lock()));
  EXPECT_EQ(1, *p);
  //COMPILER ERROR: *p = 2;
}

TEST_F(lockable, const_unlocked)
{
  data = 1;
  unlocked(l);
  EXPECT_EQ(1, data);
}

} // namespace
<|endoftext|>


<commit_before><commit_msg>BCLD-3422 Fixed leaks in BCClient<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed bug in sample sheet dialog (dialog for wrong sample shown).<commit_after><|endoftext|>


<commit_before>//----------------------------------------------------------------------------
// copyright 2012, 2013, 2014 Keean Schupke
// compile with c++ -std=c++11
// profile.h

#include <ctime>

extern "C" {
    #include <sys/resource.h>
}

inline uint64_t rtime() {
    struct rusage rusage;
    getrusage(RUSAGE_SELF, &rusage);
    return 1000000 * static_cast<uint64_t>(rusage.ru_utime.tv_sec)
        + static_cast<uint64_t>(rusage.ru_utime.tv_usec);
}

template <typename T> class profile {
    static uint64_t t;
    static uint64_t s;

public:
    profile() {
        start();
    }

    ~profile() {
        finish();
    }

    static void start() {
        s = rtime();
    }

    static void finish() {
        uint64_t const u = rtime();
        t += u - s;
        s = u;
    }

    static void reset() {
        t = 0;
    }

    static uint64_t report() {
        return t;
    }
};

template<typename T> uint64_t profile<T>::t {0};
template<typename T> uint64_t profile<T>::s;

<commit_msg>prevent division by ero with very short runtimes<commit_after>//----------------------------------------------------------------------------
// copyright 2012, 2013, 2014 Keean Schupke
// compile with c++ -std=c++11
// profile.h

#include <ctime>

extern "C" {
    #include <sys/resource.h>
}

inline uint64_t rtime() {
    struct rusage rusage;
    getrusage(RUSAGE_SELF, &rusage);
    return 1000000 * static_cast<uint64_t>(rusage.ru_utime.tv_sec)
        + static_cast<uint64_t>(rusage.ru_utime.tv_usec);
}

template <typename T> class profile {
    static uint64_t t;
    static uint64_t s;

public:
    profile() {
        start();
    }

    ~profile() {
        finish();
    }

    static void start() {
        s = rtime();
    }

    static void finish() {
        uint64_t const u = rtime();
        t += u - s;
        s = u;
    }

    static void reset() {
        t = 1;
    }

    static uint64_t report() {
        return t;
    }
};

template<typename T> uint64_t profile<T>::t {1};
template<typename T> uint64_t profile<T>::s;

<|endoftext|>


<commit_before><commit_msg>or i can if i set the pubMsg as the msg<commit_after><|endoftext|>


<commit_before>//
//  automaton.cpp
//  lut-lang
//
//  Created by Kevin Antoine on 06/03/2015.
//  Copyright (c) 2015 H4314. All rights reserved.

#include "E0.h"
#include "E1.h"
#include "../state.h"
#include "TokenType.h"

E0::E0 () : State() { };

bool E0::transition (Automaton *automaton, ASTTokenNode *t) {

  ASTTokenNode token = ASTTokenNode(TokenType::D);

  switch ( t->getTokenType() ) {
    case TokenType::D:
      automaton->decalage(t, new E1());
      return true;
      break;
    case TokenType::WRITE:
    case TokenType::READ :
    case TokenType::VAR:
    case TokenType::CONST:
    case TokenType::ID:
    case TokenType::ENDOFFILE :
      //Reduction
      token = ASTTokenNode(TokenType::D);
      automaton->stackStates.top()->transition(automaton, &token);
      return true;
      break;
    default:
      return false;
      break;
  }

  return false;
}<commit_msg>break removed<commit_after>//
//  automaton.cpp
//  lut-lang
//
//  Created by Kevin Antoine on 06/03/2015.
//  Copyright (c) 2015 H4314. All rights reserved.

#include "E0.h"
#include "E1.h"
#include "../state.h"
#include "TokenType.h"

E0::E0 () : State() { };

bool E0::transition (Automaton *automaton, ASTTokenNode *t) {

  ASTTokenNode token = ASTTokenNode(TokenType::D);

  switch ( t->getTokenType() ) {
    case TokenType::D:
      automaton->decalage(t, new E1());
      return true;
    case TokenType::WRITE:
    case TokenType::READ :
    case TokenType::VAR:
    case TokenType::CONST:
    case TokenType::ID:
    case TokenType::ENDOFFILE :
      //Reduction
      token = ASTTokenNode(TokenType::D);
      automaton->stackStates.top()->transition(automaton, &token);
      return true;
    default:
      return false;
  }

  return false;
}<|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.                  *
 **************************************************************************/

/* $Id$ */
/* History of cvs commits:
 *
 * $Log$
 *
*/
///////////////////////////////////////////////////////////////////////////////
// Class AliEMCALCalibHistoProducer accumulating histograms
// with amplitudes per EMCAL channel
// It is intended to run at DAQ computers (LDC, GDC, HLT or MOOD)
// and it fills the histograms with amplitudes per channel.
// Usage example see in EMCAL/macros/Shuttle/AliEMCALCalibHistoProducer.C
//
// Author: Boris Polichtchouk, 4 October 2006
// Adapted for EMCAL by Gustavo Conesa Balbastre, October 2006
///////////////////////////////////////////////////////////////////////////////

#include "AliLog.h"
#include "AliEMCALCalibHistoProducer.h"
#include "TH1.h"
#include "TFile.h"
#include "TProfile.h"
#include "AliRawReader.h"
#include "AliCaloRawStream.h"

ClassImp(AliEMCALCalibHistoProducer)

//-----------------------------------------------------------------------------
AliEMCALCalibHistoProducer::AliEMCALCalibHistoProducer(AliRawReader* rawReader) :
  fRawReader(rawReader),fHistoFile(0),fHistoFileName("calibHisto.root"),
  fUpdatingRate(100),fIsOldRCUFormat(kFALSE), fNSuperModules(12),  fNCellsEta (48),
  fNCellsPhi(24),  fNCellsPhiHalfSM(12)
{
  // Constructor

  for(Int_t ism=0; ism<fNSuperModules; ism++) {
    fAmpProf[ism] = 0;
    fSMInstalled[ism]=kTRUE;
    for(Int_t icol=0; icol<fNCellsEta; icol++)
      for(Int_t irow=0; irow<fNCellsPhi; irow++)
	  fAmpHisto[ism][icol][irow]=0;
  }

}

//-----------------------------------------------------------------------------
AliEMCALCalibHistoProducer::AliEMCALCalibHistoProducer() :
  fRawReader(0),fHistoFile(0),fUpdatingRate(0),fIsOldRCUFormat(kFALSE),
  fNSuperModules(12), fNCellsEta (48), fNCellsPhi(24), fNCellsPhiHalfSM(12)
{
  // Default constructor
}

//-----------------------------------------------------------------------------
AliEMCALCalibHistoProducer::~AliEMCALCalibHistoProducer()
{
  // Destructor
  if(fHistoFile) {
    fHistoFile->Close();
    delete fHistoFile;
  }
}
//-----------------------------------------------------------------------------
void AliEMCALCalibHistoProducer::Init()
{
  // initializes input data stream supplied by rawReader
  // Checks existence of histograms which might have been left
  // from the previous runs to continue their filling
  fHistoFile =  new TFile(fHistoFileName,"update");
  char hname[128];
  Int_t nRow =  fNCellsPhi ;

  for(Int_t supermodule=0; supermodule<fNSuperModules; supermodule++) {
    //Check installed supermodules
    if(fSMInstalled[supermodule]==kFALSE) continue;
    //Check created profiles
    sprintf(hname,"mod%d",supermodule);
    TProfile* prof = (TProfile*)fHistoFile->Get(hname);
    if(prof)
      fAmpProf[supermodule]=prof;

    //Check created histograms
    if(supermodule > 10) nRow = fNCellsPhiHalfSM ; //Supermodules 11 and 12 are half supermodules
    for(Int_t column=0; column<fNCellsEta; column++) {
      for(Int_t row=0; row<nRow; row++) {
	sprintf(hname,"mod%dcol%drow%d",supermodule,column,row);
	TH1F* hist = (TH1F*)fHistoFile->Get(hname);
	if(hist)
	  fAmpHisto[supermodule][column][row]=hist;
      }
    }
  }

}
//-----------------------------------------------------------------------------
void AliEMCALCalibHistoProducer::Run()
{
  // Reads raw data stream and fills amplitude histograms
  // The histograms are written to file every fUpdatingRate events
  //Also fills profiles to study the stability of supermodules during runs.

  Init();

//   TH1F* gHighGain = 0;
//   TH1F* gLowGain = 0;
  Int_t iBin = 0;
  Int_t iEvent = 0;
  Int_t runNum = 0;
  Int_t nProfFreq = 1000; //Number of events with which a bin of the TProfile if filled
  Int_t nEvtBins = 1000; //Total number of the profile survey bins.

  AliCaloRawStream in(fRawReader,"EMCAL");
  if(fIsOldRCUFormat)
    in.SetOldRCUFormat(kTRUE);

  // Read raw data event by event

  while (fRawReader->NextEvent()) {
    runNum = fRawReader->GetRunNumber();
    Float_t energy = 0;
     while ( in.Next() ) {

      if(fSMInstalled[in.GetModule()]==kFALSE) continue;

      if (in.GetSignal() > energy) {
	energy = (Double_t) in.GetSignal();
      }

      iBin++;

      if(iBin==in.GetTimeLength()) {
	iBin=0;

	Int_t mod = in.GetModule();
	Int_t col = in.GetColumn();
	Int_t row = in.GetRow();
	Int_t evtbin = iEvent/nProfFreq;
	char hname[128];

	//Check if histogram/profile already exist, if not create it.
	if(!fAmpHisto[mod][col][row]) {
	  sprintf(hname,"mod%dcol%drow%d",mod,col,row);
	  fAmpHisto[mod][col][row] = new TH1F(hname,hname,1024,-0.5,1023.);
	}
	if(!fAmpProf[mod]) {
	  sprintf(hname,"mod%d",mod);
	  fAmpProf[mod] = new TProfile(hname,hname,nEvtBins,0.,nEvtBins);
	}
	//Fill histogram/profile
	Bool_t lowGainFlag = in.IsLowGain();
	if(!lowGainFlag) {
	  fAmpHisto[mod][col][row]->Fill(energy);
	  fAmpProf[mod]->Fill(evtbin, energy);
	}
      }
    }

    // update histograms in local file every 100th event
    if(iEvent%fUpdatingRate == 0) {
      AliInfo(Form("Updating histo file, event %d, run %d\n",iEvent,runNum));
      UpdateHistoFile();
    }
    iEvent++;
  }

  UpdateHistoFile();
  AliInfo(Form("%d events of run %d processed.",iEvent,runNum));
}

//-----------------------------------------------------------------------------
void AliEMCALCalibHistoProducer::UpdateHistoFile()
{
  // Write histograms to file

  if(!fHistoFile) return;
  if(!fHistoFile->IsOpen()) return;

  TH1F* hist=0;
  TProfile* prof =0;

  Int_t nRow =  fNCellsPhi ;
  for(Int_t supermodule=0; supermodule<fNSuperModules; supermodule++) {

    prof = fAmpProf[supermodule];
    if(prof) prof->Write(prof->GetName(),TObject::kWriteDelete);

    if(supermodule > 10)  nRow = fNCellsPhiHalfSM ; //Supermodules 11 and 12 are half supermodules
    for(Int_t column=0; column<fNCellsEta; column++) {
      for(Int_t row=0; row<nRow; row++) {
	hist = fAmpHisto[supermodule][column][row];
	if(hist) hist->Write(hist->GetName(),TObject::kWriteDelete);
      }
    }
  }

}
<commit_msg>Add copy constructor and assignment operator to cxx, change default name of histograms file to avoid confusion with PHOS histograms file<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.                  *
 **************************************************************************/

/* $Id$ */
/* History of cvs commits:
 *
 * $Log$
 * Revision 1.1  2006/12/07 16:32:16  gustavo
 * First shuttle code, online calibration histograms producer, EMCAL preprocessor
 *
 *
*/
///////////////////////////////////////////////////////////////////////////////
// Class AliEMCALCalibHistoProducer accumulating histograms
// with amplitudes per EMCAL channel
// It is intended to run at DAQ computers (LDC, GDC, HLT or MOOD)
// and it fills the histograms with amplitudes per channel.
// Usage example see in EMCAL/macros/Shuttle/AliEMCALCalibHistoProducer.C
//
// Author: Boris Polichtchouk, 4 October 2006
// Adapted for EMCAL by Gustavo Conesa Balbastre, October 2006
///////////////////////////////////////////////////////////////////////////////

#include "TH1.h"
#include "TFile.h"
#include "TProfile.h"

#include "AliLog.h"
#include "AliRawReader.h"
#include "AliCaloRawStream.h"
#include "AliEMCALCalibHistoProducer.h"

ClassImp(AliEMCALCalibHistoProducer)

//-----------------------------------------------------------------------------
AliEMCALCalibHistoProducer::AliEMCALCalibHistoProducer(AliRawReader* rawReader) :
  TObject(),fRawReader(rawReader),fHistoFile(0),fHistoFileName("calibEmcHisto.root"),
  fUpdatingRate(100),fIsOldRCUFormat(kFALSE), fNSuperModules(12),  fNCellsEta (48),
  fNCellsPhi(24),  fNCellsPhiHalfSM(12)
{
  // Constructor

  for(Int_t ism=0; ism<fNSuperModules; ism++) {
    fAmpProf[ism] = 0;
    fSMInstalled[ism]=kTRUE;
    for(Int_t icol=0; icol<fNCellsEta; icol++)
      for(Int_t irow=0; irow<fNCellsPhi; irow++)
	  fAmpHisto[ism][icol][irow]=0;
  }

}
//-----------------------------------------------------------------------------
AliEMCALCalibHistoProducer::AliEMCALCalibHistoProducer() :
  fRawReader(0x0),fHistoFile(0),fHistoFileName(""),
  fUpdatingRate(0),fIsOldRCUFormat(kFALSE), fNSuperModules(12),  fNCellsEta (48),
  fNCellsPhi(24),  fNCellsPhiHalfSM(12)
{
  // default Constructor

  for(Int_t ism=0; ism<fNSuperModules; ism++) {
    fAmpProf[ism] = 0;
    fSMInstalled[ism]=kTRUE;
    for(Int_t icol=0; icol<fNCellsEta; icol++)
      for(Int_t irow=0; irow<fNCellsPhi; irow++)
	  fAmpHisto[ism][icol][irow]=0;
  }

}

//-----------------------------------------------------------------------------
AliEMCALCalibHistoProducer::AliEMCALCalibHistoProducer(const AliEMCALCalibHistoProducer & copy) :
  TObject(copy),fRawReader((AliRawReader*)copy. fRawReader->Clone()),
  fHistoFile((TFile*)copy.fHistoFile->Clone()),fHistoFileName(copy.fHistoFileName),
  fUpdatingRate(copy.fUpdatingRate),fIsOldRCUFormat(copy.fIsOldRCUFormat),
  fNSuperModules(copy.fNSuperModules), fNCellsEta (copy.fNCellsEta),
  fNCellsPhi(copy.fNCellsPhi), fNCellsPhiHalfSM(copy.fNCellsPhiHalfSM)
{
  //copy constructor

 for(Int_t ism=0; ism<fNSuperModules; ism++) {
    fAmpProf[ism] = copy. fAmpProf[ism];
    fSMInstalled[ism]= copy.fSMInstalled[ism];
    for(Int_t icol=0; icol<fNCellsEta; icol++)
      for(Int_t irow=0; irow<fNCellsPhi; irow++)
	  fAmpHisto[ism][icol][irow]= copy.fAmpHisto[ism][icol][irow];
  }

}

//-----------------------------------------------------------------------------
AliEMCALCalibHistoProducer::~AliEMCALCalibHistoProducer()
{
  // Destructor
  if(fHistoFile) {
    fHistoFile->Close();
    delete fHistoFile;
  }
}

//------------------------------------------------------------------------------
//
AliEMCALCalibHistoProducer& AliEMCALCalibHistoProducer::operator=(const AliEMCALCalibHistoProducer& copy)
{
	//
	// Assignment operator.
	// Besides copying all parameters, duplicates all collections.
	//
                if (&copy == this) return *this;
	TObject::operator=(copy);
	fHistoFileName = copy.fHistoFileName;
	fUpdatingRate = copy.fUpdatingRate;
	fIsOldRCUFormat = copy.fIsOldRCUFormat;
	fNSuperModules = copy.fNSuperModules;
	fNCellsEta = copy.fNCellsEta;
	fNCellsPhi = copy.fNCellsPhi;
	fNCellsPhiHalfSM = copy.fNCellsPhiHalfSM;

	fRawReader  = (AliRawReader*)copy. fRawReader->Clone();
	fHistoFile      = (TFile*)copy.fHistoFile->Clone();

	for(Int_t ism=0; ism<fNSuperModules; ism++) {
	  fAmpProf[ism] = copy. fAmpProf[ism];
	  fSMInstalled[ism]= copy.fSMInstalled[ism];
	  for(Int_t icol=0; icol<fNCellsEta; icol++)
	    for(Int_t irow=0; irow<fNCellsPhi; irow++)
	      fAmpHisto[ism][icol][irow]= copy.fAmpHisto[ism][icol][irow];
	}

	return (*this);
}
//-----------------------------------------------------------------------------
void AliEMCALCalibHistoProducer::Init()
{
  // initializes input data stream supplied by rawReader
  // Checks existence of histograms which might have been left
  // from the previous runs to continue their filling
  fHistoFile =  new TFile(fHistoFileName,"update");
  char hname[128];
  Int_t nRow =  fNCellsPhi ;

  for(Int_t supermodule=0; supermodule<fNSuperModules; supermodule++) {
    //Check installed supermodules
    if(fSMInstalled[supermodule]==kFALSE) continue;
    //Check created profiles
    sprintf(hname,"mod%d",supermodule);
    TProfile* prof = (TProfile*)fHistoFile->Get(hname);
    if(prof)
      fAmpProf[supermodule]=prof;

    //Check created histograms
    if(supermodule > 10) nRow = fNCellsPhiHalfSM ; //Supermodules 11 and 12 are half supermodules
    for(Int_t column=0; column<fNCellsEta; column++) {
      for(Int_t row=0; row<nRow; row++) {
	sprintf(hname,"mod%dcol%drow%d",supermodule,column,row);
	TH1F* hist = (TH1F*)fHistoFile->Get(hname);
	if(hist)
	  fAmpHisto[supermodule][column][row]=hist;
      }
    }
  }

}
//-----------------------------------------------------------------------------
void AliEMCALCalibHistoProducer::Run()
{
  // Reads raw data stream and fills amplitude histograms
  // The histograms are written to file every fUpdatingRate events
  //Also fills profiles to study the stability of supermodules during runs.

  Init();

//   TH1F* gHighGain = 0;
//   TH1F* gLowGain = 0;
  Int_t iBin = 0;
  Int_t iEvent = 0;
  Int_t runNum = 0;
  Int_t nProfFreq = 1000; //Number of events with which a bin of the TProfile if filled
  Int_t nEvtBins = 1000; //Total number of the profile survey bins.

  AliCaloRawStream in(fRawReader,"EMCAL");
  if(fIsOldRCUFormat)
    in.SetOldRCUFormat(kTRUE);

  // Read raw data event by event

  while (fRawReader->NextEvent()) {
    runNum = fRawReader->GetRunNumber();
    Float_t energy = 0;
     while ( in.Next() ) {

      if(fSMInstalled[in.GetModule()]==kFALSE) continue;

      if (in.GetSignal() > energy) {
	energy = (Double_t) in.GetSignal();
      }

      iBin++;

      if(iBin==in.GetTimeLength()) {
	iBin=0;

	Int_t mod = in.GetModule();
	Int_t col = in.GetColumn();
	Int_t row = in.GetRow();
	Int_t evtbin = iEvent/nProfFreq;
	char hname[128];

	//Check if histogram/profile already exist, if not create it.
	if(!fAmpHisto[mod][col][row]) {
	  sprintf(hname,"mod%dcol%drow%d",mod,col,row);
	  fAmpHisto[mod][col][row] = new TH1F(hname,hname,1024,-0.5,1023.);
	}
	if(!fAmpProf[mod]) {
	  sprintf(hname,"mod%d",mod);
	  fAmpProf[mod] = new TProfile(hname,hname,nEvtBins,0.,nEvtBins);
	}
	//Fill histogram/profile
	Bool_t lowGainFlag = in.IsLowGain();
	if(!lowGainFlag) {
	  fAmpHisto[mod][col][row]->Fill(energy);
	  fAmpProf[mod]->Fill(evtbin, energy);
	}
      }
    }

    // update histograms in local file every 100th event
    if(iEvent%fUpdatingRate == 0) {
      AliInfo(Form("Updating histo file, event %d, run %d\n",iEvent,runNum));
      UpdateHistoFile();
    }
    iEvent++;
  }

  UpdateHistoFile();
  AliInfo(Form("%d events of run %d processed.",iEvent,runNum));
}

//-----------------------------------------------------------------------------
void AliEMCALCalibHistoProducer::UpdateHistoFile()
{
  // Write histograms to file

  if(!fHistoFile) return;
  if(!fHistoFile->IsOpen()) return;

  TH1F* hist=0;
  TProfile* prof =0;

  Int_t nRow =  fNCellsPhi ;
  for(Int_t supermodule=0; supermodule<fNSuperModules; supermodule++) {

    prof = fAmpProf[supermodule];
    if(prof) prof->Write(prof->GetName(),TObject::kWriteDelete);

    if(supermodule > 10)  nRow = fNCellsPhiHalfSM ; //Supermodules 11 and 12 are half supermodules
    for(Int_t column=0; column<fNCellsEta; column++) {
      for(Int_t row=0; row<nRow; row++) {
	hist = fAmpHisto[supermodule][column][row];
	if(hist) hist->Write(hist->GetName(),TObject::kWriteDelete);
      }
    }
  }

}
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkMahalanobisDistanceThresholdImageFunctionTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <stdio.h>

#include "itkMahalanobisDistanceThresholdImageFunction.h"
#include "itkImage.h"
#include "itkRGBPixel.h"

int itkMahalanobisDistanceThresholdImageFunctionTest(int, char* [] )
{

  const unsigned int          Dimension = 3;
  typedef unsigned char       PixelComponentType;
  typedef itk::RGBPixel<PixelComponentType>  PixelType;

  typedef itk::Image< PixelType, Dimension > ImageType;
  typedef itk::MahalanobisDistanceThresholdImageFunction< ImageType > FunctionType;

  // Create and allocate the image
  ImageType::Pointer      image = ImageType::New();
  ImageType::SizeType     size;
  ImageType::IndexType    start;
  ImageType::RegionType   region;

  size[0] = 50;
  size[1] = 50;
  size[2] = 50;

  start.Fill( 0 );

  region.SetIndex( start );
  region.SetSize( size );

  image->SetRegions( region );
  image->Allocate();

  ImageType::PixelType initialValue;

  initialValue[0] = 11;
  initialValue[1] = 22;
  initialValue[2] = 33;

  image->FillBuffer( initialValue );

  FunctionType::Pointer function = FunctionType::New();

  function->SetInputImage( image );

  const double threshold = 5.0;
  function->SetThreshold( threshold );

  vnl_matrix<double> Covariance( Dimension, Dimension );
  vnl_vector<double> Mean( Dimension );

  Mean[0] = 10.0;
  Mean[1] = 20.0;
  Mean[2] = 30.0;

  Covariance.fill( 0.0 );
  Covariance[0][0] = 100.0;
  Covariance[1][1] = 200.0;
  Covariance[2][2] = 300.0;

  function->SetCovariance( Covariance );
  function->SetMean( Mean );

  ImageType::IndexType    index;

  index[0] = 25;
  index[1] = 25;
  index[2] = 25;

  FunctionType::OutputType  belongs;

  belongs = function->EvaluateAtIndex( index );
  std::cout << "function->EvaluateAtIndex( index ): " << belongs << std::endl;

  // Test Evaluate
  FunctionType::PointType point;
  point[0] = 25;
  point[1] = 25;
  point[2] = 25;
  FunctionType::OutputType belongs2;
  belongs2 = function->Evaluate(point);
  std::cout << "function->Evaluate(point): " << belongs2 << std::endl;

  // Test EvaluateAtContinuousIndex
  FunctionType::ContinuousIndexType cindex;
  cindex[0] = 25;
  cindex[1] = 25;
  cindex[2] = 25;
  FunctionType::OutputType belongs3;
  belongs3 = function->EvaluateAtContinuousIndex(cindex);
  std::cout << "function->EvaluateAtContinuousIndex(cindex): " << belongs3 << std::endl;

  // Test GetConstReferenceMacro
  const double & getThreshold = function->GetThreshold();
  std::cout << "function->GetThreshold(): " << getThreshold << std::endl;
  if( fabs( threshold - getThreshold ) > 1e-9 )
    {
    std::cerr << "Error: Set/Get Threshold do not match" << std::endl;
    return EXIT_FAILURE;
    }

  // Exercise GetMean() and GetCovariance()
  Mean       = function->GetMean();
  Covariance = function->GetCovariance();

  std::cout << "Test PASSED ! " << std::endl;
  return EXIT_SUCCESS;

}

<commit_msg>FIX: Bug#417. Added tests for new methods EvaluateDistance() and      EvaluateDistanceAtIndex(). The test was also improved by adding      checks for the values returned by Evaluate*() methods.      The new methods added were needed for fixing the itkVectorConfidence      ConnectedImage filter.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkMahalanobisDistanceThresholdImageFunctionTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <stdio.h>

#include "itkMahalanobisDistanceThresholdImageFunction.h"
#include "itkImage.h"
#include "itkRGBPixel.h"

int itkMahalanobisDistanceThresholdImageFunctionTest(int, char* [] )
{

  const unsigned int          Dimension = 3;
  typedef unsigned char       PixelComponentType;
  typedef itk::RGBPixel<PixelComponentType>  PixelType;

  typedef itk::Image< PixelType, Dimension > ImageType;
  typedef itk::MahalanobisDistanceThresholdImageFunction< ImageType > FunctionType;

  // Create and allocate the image
  ImageType::Pointer      image = ImageType::New();
  ImageType::SizeType     size;
  ImageType::IndexType    start;
  ImageType::RegionType   region;

  size[0] = 50;
  size[1] = 50;
  size[2] = 50;

  start.Fill( 0 );

  region.SetIndex( start );
  region.SetSize( size );

  image->SetRegions( region );
  image->Allocate();

  ImageType::PixelType initialValue;

  initialValue[0] = 11;
  initialValue[1] = 22;
  initialValue[2] = 33;

  image->FillBuffer( initialValue );

  FunctionType::Pointer function = FunctionType::New();

  function->SetInputImage( image );

  const double threshold = 5.0;
  function->SetThreshold( threshold );

  typedef vnl_matrix<double> CovarianceType;
  typedef vnl_vector<double> MeanType;

  CovarianceType Covariance( Dimension, Dimension );
  MeanType  Mean( Dimension );

  Mean[0] = 10.0;
  Mean[1] = 20.0;
  Mean[2] = 30.0;

  Covariance.fill( 0.0 );
  Covariance[0][0] = 100.0;
  Covariance[1][1] = 200.0;
  Covariance[2][2] = 300.0;

  function->SetCovariance( Covariance );
  function->SetMean( Mean );

  ImageType::IndexType    index;

  index[0] = 25;
  index[1] = 25;
  index[2] = 25;

  FunctionType::OutputType  belongs;

  belongs = function->EvaluateAtIndex( index );
  std::cout << "function->EvaluateAtIndex( index ): " << belongs << std::endl;
  if( !belongs )
    {
    std::cerr << "Error in EvaluateAtIndex() we were expecting true and got false" << std::endl;
    return EXIT_FAILURE;
    }

  const double distance = function->EvaluateDistanceAtIndex( index );
  std::cout << "function->EvaluateDistanceAtIndex( index ): " << distance << std::endl;

  const double expectedDistance = 0.244949;
  if( fabs(distance - expectedDistance) > 1e-5 )
    {
    std::cerr << "Error in distance computation in EvaluateDistanceAtIndex() !!" << std::endl;
    std::cerr << "Expected distance value = " << expectedDistance << std::endl;
    std::cerr << "Distance obtained value = " << distance << std::endl;
    return EXIT_FAILURE;
    }

  // Test Evaluate
  FunctionType::PointType point;
  point[0] = 25;
  point[1] = 25;
  point[2] = 25;
  FunctionType::OutputType belongs2;
  belongs2 = function->Evaluate(point);
  std::cout << "function->Evaluate(point): " << belongs2 << std::endl;

  if( !belongs2 )
    {
    std::cerr << "Error in Evaluate() we were expecting true and got false" << std::endl;
    return EXIT_FAILURE;
    }

  const double distance2 = function->EvaluateDistance(point);
  std::cout << "function->EvaluateDistance(point): " << distance2 << std::endl;

  if( fabs(distance2 - expectedDistance) > 1e-5 )
    {
    std::cerr << "Error in distance computation in EvaluateDistance() !!" << std::endl;
    std::cerr << "Expected distance value = " << expectedDistance << std::endl;
    std::cerr << "Distance obtained value = " << distance2 << std::endl;
    return EXIT_FAILURE;
    }

  // Test EvaluateAtContinuousIndex
  FunctionType::ContinuousIndexType cindex;
  cindex[0] = 25;
  cindex[1] = 25;
  cindex[2] = 25;
  FunctionType::OutputType belongs3;
  belongs3 = function->EvaluateAtContinuousIndex(cindex);
  std::cout << "function->EvaluateAtContinuousIndex(cindex): " << belongs3 << std::endl;

  if( !belongs3 )
    {
    std::cerr << "Error in EvaluateAtContinuousIndex() we were expecting true and got false" << std::endl;
    return EXIT_FAILURE;
    }

  // Test GetConstReferenceMacro
  const double & getThreshold = function->GetThreshold();
  std::cout << "function->GetThreshold(): " << getThreshold << std::endl;
  if( fabs( threshold - getThreshold ) > 1e-9 )
    {
    std::cerr << "Error: Set/Get Threshold do not match" << std::endl;
    return EXIT_FAILURE;
    }

  // Exercise GetMean() and GetCovariance()
  Mean       = function->GetMean();
  Covariance = function->GetCovariance();

  std::cout << "Test PASSED ! " << std::endl;
  return EXIT_SUCCESS;

}

<|endoftext|>