<commit_before>// -*- c-style: gnu -*-

#include "act-types.h"

#include "act-config.h"
#include "act-format.h"
#include "act-util.h"

#include <xlocale.h>

namespace act {

field_id
lookup_field_id(const char *str)
{
  switch (tolower_l(str[0], nullptr))
    {
    case 'a':
      if (strcasecmp(str, "activity") == 0)
	return field_activity;
      else if (strcasecmp(str, "average_hr") == 0)
	return field_average_hr;
      break;

    case 'c':
      if (strcasecmp(str, "calories") == 0)
	return field_calories;
      else if (strcasecmp(str, "course") == 0)
	return field_course;
      break;

    case 'd':
      if (strcasecmp(str, "date") == 0)
	return field_date;
      else if (strcasecmp(str, "dew-point") == 0)
	return field_dew_point;
      else if (strcasecmp(str, "distance") == 0)
	return field_distance;
      else if (strcasecmp(str, "duration") == 0)
	return field_duration;
      break;

    case 'e':
      if (strcasecmp(str, "effort") == 0)
	return field_effort;
      else if (strcasecmp(str, "equipment") == 0)
	return field_equipment;
      break;

    case 'g':
      if (strcasecmp(str, "gps-file") == 0)
	return field_gps_file;
      break;

    case 'k':
      if (strcasecmp(str, "keywords") == 0)
	return field_keywords;
      break;

    case 'm':
      if (strcasecmp(str, "max-hr") == 0)
	return field_max_hr;
      else if (strcasecmp(str, "max-pace") == 0)
	return field_max_pace;
      else if (strcasecmp(str, "max-speed") == 0)
	return field_max_speed;
      break;

    case 'p':
      if (strcasecmp(str, "pace") == 0)
	return field_pace;
      break;

    case 'q':
      if (strcasecmp(str, "quality") == 0)
	return field_quality;
      break;

    case 'r':
      if (strcasecmp(str, "resting-hr") == 0)
	return field_resting_hr;
      break;

    case 't':
      if (strcasecmp(str, "temperature") == 0)
	return field_temperature;
      else if (strcasecmp(str, "type") == 0)
	return field_type;
      break;

    case 'w':
      if (strcasecmp(str, "weather") == 0)
	return field_weather;
      else if (strcasecmp(str, "weight") == 0)
	return field_weight;
      break;
    }

  return field_custom;
}

const char *
canonical_field_name(field_id id)
{
  switch (id)
    {
    case field_activity:
      return "Activity";
    case field_average_hr:
      return "Average-HR";
    case field_calories:
      return "Calories";
    case field_course:
      return "Course";
    case field_custom:
      return 0;
    case field_date:
      return "Date";
    case field_dew_point:
      return "Dew-Point";
    case field_distance:
      return "Distance";
    case field_duration:
      return "Duration";
    case field_effort:
      return "Effort";
    case field_equipment:
      return "Equipment";
    case field_gps_file:
      return "GPS-File";
    case field_keywords:
      return "Keywords";
    case field_max_hr:
      return "Max-HR";
    case field_max_pace:
      return "Max-Pace";
    case field_max_speed:
      return "Max-Speed";
    case field_pace:
      return "Pace";
    case field_quality:
      return "Quality";
    case field_resting_hr:
      return "Resting-HR";
    case field_speed:
      return "Speed";
    case field_temperature:
      return "Temperature";
    case field_type:
      return "Type";
    case field_weather:
      return "Weather";
    case field_weight:
      return "Weight";
    }
}

field_data_type
lookup_field_data_type(const field_id id)
{
  switch (id)
    {
    case field_activity:
    case field_course:
    case field_gps_file:
    case field_type:
    case field_custom:
      return type_string;
    case field_average_hr:
    case field_calories:
    case field_max_hr:
    case field_resting_hr:
      return type_number;
    case field_date:
      return type_date;
    case field_distance:
      return type_distance;
    case field_duration:
      return type_duration;
    case field_effort:
    case field_quality:
      return type_fraction;
    case field_equipment:
    case field_keywords:
    case field_weather:
      return type_keywords;
    case field_max_pace:
    case field_pace:
      return type_pace;
    case field_max_speed:
    case field_speed:
      return type_speed;
    case field_dew_point:
    case field_temperature:
      return type_temperature;
    case field_weight:
      return type_weight;
    }
}

bool
canonicalize_field_string(field_data_type type, std::string &str)
{
  switch (type)
    {
    case type_string:
      return true;

    case type_number: {
      double value;
      if (parse_number(str, &value))
	{
	  str.clear();
	  format_number(str, value);
	  return true;
	}
      break; }

    case type_date: {
      time_t date;
      if (parse_date_time(str, &date, nullptr))
	{
	  str.clear();
	  format_date_time(str, date);
	  return true;
	}
      break; }

    case type_duration: {
      double dur;
      if (parse_duration(str, &dur))
	{
	  str.clear();
	  format_duration(str, dur);
	  return true;
	}
      break; }

    case type_distance: {
      double dist;
      unit_type unit;
      if (parse_distance(str, &dist, &unit))
	{
	  str.clear();
	  format_distance(str, dist, unit);
	  return true;
	}
      break; }

    case type_pace: {
      double pace;
      unit_type unit;
      if (parse_pace(str, &pace, &unit))
	{
	  str.clear();
	  format_pace(str, pace, unit);
	  return true;
	}
      break; }

    case type_speed: {
      double speed;
      unit_type unit;
      if (parse_speed(str, &speed, &unit))
	{
	  str.clear();
	  format_speed(str, speed, unit);
	  return true;
	}
      break; }

    case type_temperature: {
      double temp;
      unit_type unit;
      if (parse_temperature(str, &temp, &unit))
	{
	  str.clear();
	  format_temperature(str, temp, unit);
	  return true;
	}
      break; }

    case type_weight: {
      double temp;
      unit_type unit;
      if (parse_weight(str, &temp, &unit))
	{
	  str.clear();
	  format_weight(str, temp, unit);
	  return true;
	}
      break; }

    case type_fraction: {
      double value;
      if (parse_fraction(str, &value))
	{
	  str.clear();
	  format_fraction(str, value);
	  return true;
	}
      break; }

    case type_keywords: {
      std::vector<std::string> keys;
      if (parse_keywords(str, &keys))
	{
	  str.clear();
	  format_keywords(str, keys);
	  return true;
	}
      break; }
    }

  return false;
}

namespace {

int
days_since_1970(const struct tm &tm)
{
  /* Adapted from Linux kernel's mktime(). */

  int year = tm.tm_year + 1900;
  int month = tm.tm_mon - 1;	/* 0..11 -> 11,12,1..10 */
  if (month < 0)
    month += 12, year -= 1;
  int day = tm.tm_mday;

  return ((year/4 - year/100 + year/400 + 367*month/12 + day)
	  + year*365 - 719499);
}

void
append_days_date(std::string &str, int days)
{
  time_t date = days * (time_t) (24*60*60);
  struct tm tm = {0};
  localtime_r(&date, &tm);

  char buf[128];
  strftime_l(buf, sizeof(buf), "%F", &tm, nullptr);
  str.append(buf);
}

} // anonymous namespace

int
date_interval::date_index(time_t date) const
{
  struct tm tm = {0};
  localtime_r(&date, &tm);

  switch (unit)
    {
    case days:
      return days_since_1970(tm);

    case weeks: {
      // 1970-01-01 was a thursday.
      static int week_offset = 4 - shared_config().start_of_week();
      return (days_since_1970(tm) - week_offset) / 7; }

    case months:
      return (tm.tm_year - 70) * 12 + tm.tm_mon;

    case years:
      return tm.tm_year - 70;
    }
}

void
date_interval::append_date(std::string &str, int x) const
{
  switch (unit)
    {
    case days:
      append_days_date(str, x);
      break;

    case weeks: {
      static int week_offset = 4 - shared_config().start_of_week();
      int days = x * 7 + week_offset;
      append_days_date(str, days);
      break; }

    case months: {
      int month = x % 12;
      int year = 1970 + x / 12;
      char buf[128];
      static const char *names[] = {"January", "February", "March",
	"April", "May", "June", "July", "August", "September",
	"October", "November", "December"};
      snprintf_l(buf, sizeof(buf), nullptr, "%s %04d", names[month], year);
      str.append(buf);
      break; }

    case years: {
      char buf[64];
      snprintf_l(buf, sizeof(buf), nullptr, "%d", 1970 + x);
      str.append(buf);
      break; }
    }
}

} // namespace act
<commit_msg>fix weekly date intervals<commit_after>// -*- c-style: gnu -*-

#include "act-types.h"

#include "act-config.h"
#include "act-format.h"
#include "act-util.h"

#include <xlocale.h>

namespace act {

field_id
lookup_field_id(const char *str)
{
  switch (tolower_l(str[0], nullptr))
    {
    case 'a':
      if (strcasecmp(str, "activity") == 0)
	return field_activity;
      else if (strcasecmp(str, "average_hr") == 0)
	return field_average_hr;
      break;

    case 'c':
      if (strcasecmp(str, "calories") == 0)
	return field_calories;
      else if (strcasecmp(str, "course") == 0)
	return field_course;
      break;

    case 'd':
      if (strcasecmp(str, "date") == 0)
	return field_date;
      else if (strcasecmp(str, "dew-point") == 0)
	return field_dew_point;
      else if (strcasecmp(str, "distance") == 0)
	return field_distance;
      else if (strcasecmp(str, "duration") == 0)
	return field_duration;
      break;

    case 'e':
      if (strcasecmp(str, "effort") == 0)
	return field_effort;
      else if (strcasecmp(str, "equipment") == 0)
	return field_equipment;
      break;

    case 'g':
      if (strcasecmp(str, "gps-file") == 0)
	return field_gps_file;
      break;

    case 'k':
      if (strcasecmp(str, "keywords") == 0)
	return field_keywords;
      break;

    case 'm':
      if (strcasecmp(str, "max-hr") == 0)
	return field_max_hr;
      else if (strcasecmp(str, "max-pace") == 0)
	return field_max_pace;
      else if (strcasecmp(str, "max-speed") == 0)
	return field_max_speed;
      break;

    case 'p':
      if (strcasecmp(str, "pace") == 0)
	return field_pace;
      break;

    case 'q':
      if (strcasecmp(str, "quality") == 0)
	return field_quality;
      break;

    case 'r':
      if (strcasecmp(str, "resting-hr") == 0)
	return field_resting_hr;
      break;

    case 't':
      if (strcasecmp(str, "temperature") == 0)
	return field_temperature;
      else if (strcasecmp(str, "type") == 0)
	return field_type;
      break;

    case 'w':
      if (strcasecmp(str, "weather") == 0)
	return field_weather;
      else if (strcasecmp(str, "weight") == 0)
	return field_weight;
      break;
    }

  return field_custom;
}

const char *
canonical_field_name(field_id id)
{
  switch (id)
    {
    case field_activity:
      return "Activity";
    case field_average_hr:
      return "Average-HR";
    case field_calories:
      return "Calories";
    case field_course:
      return "Course";
    case field_custom:
      return 0;
    case field_date:
      return "Date";
    case field_dew_point:
      return "Dew-Point";
    case field_distance:
      return "Distance";
    case field_duration:
      return "Duration";
    case field_effort:
      return "Effort";
    case field_equipment:
      return "Equipment";
    case field_gps_file:
      return "GPS-File";
    case field_keywords:
      return "Keywords";
    case field_max_hr:
      return "Max-HR";
    case field_max_pace:
      return "Max-Pace";
    case field_max_speed:
      return "Max-Speed";
    case field_pace:
      return "Pace";
    case field_quality:
      return "Quality";
    case field_resting_hr:
      return "Resting-HR";
    case field_speed:
      return "Speed";
    case field_temperature:
      return "Temperature";
    case field_type:
      return "Type";
    case field_weather:
      return "Weather";
    case field_weight:
      return "Weight";
    }
}

field_data_type
lookup_field_data_type(const field_id id)
{
  switch (id)
    {
    case field_activity:
    case field_course:
    case field_gps_file:
    case field_type:
    case field_custom:
      return type_string;
    case field_average_hr:
    case field_calories:
    case field_max_hr:
    case field_resting_hr:
      return type_number;
    case field_date:
      return type_date;
    case field_distance:
      return type_distance;
    case field_duration:
      return type_duration;
    case field_effort:
    case field_quality:
      return type_fraction;
    case field_equipment:
    case field_keywords:
    case field_weather:
      return type_keywords;
    case field_max_pace:
    case field_pace:
      return type_pace;
    case field_max_speed:
    case field_speed:
      return type_speed;
    case field_dew_point:
    case field_temperature:
      return type_temperature;
    case field_weight:
      return type_weight;
    }
}

bool
canonicalize_field_string(field_data_type type, std::string &str)
{
  switch (type)
    {
    case type_string:
      return true;

    case type_number: {
      double value;
      if (parse_number(str, &value))
	{
	  str.clear();
	  format_number(str, value);
	  return true;
	}
      break; }

    case type_date: {
      time_t date;
      if (parse_date_time(str, &date, nullptr))
	{
	  str.clear();
	  format_date_time(str, date);
	  return true;
	}
      break; }

    case type_duration: {
      double dur;
      if (parse_duration(str, &dur))
	{
	  str.clear();
	  format_duration(str, dur);
	  return true;
	}
      break; }

    case type_distance: {
      double dist;
      unit_type unit;
      if (parse_distance(str, &dist, &unit))
	{
	  str.clear();
	  format_distance(str, dist, unit);
	  return true;
	}
      break; }

    case type_pace: {
      double pace;
      unit_type unit;
      if (parse_pace(str, &pace, &unit))
	{
	  str.clear();
	  format_pace(str, pace, unit);
	  return true;
	}
      break; }

    case type_speed: {
      double speed;
      unit_type unit;
      if (parse_speed(str, &speed, &unit))
	{
	  str.clear();
	  format_speed(str, speed, unit);
	  return true;
	}
      break; }

    case type_temperature: {
      double temp;
      unit_type unit;
      if (parse_temperature(str, &temp, &unit))
	{
	  str.clear();
	  format_temperature(str, temp, unit);
	  return true;
	}
      break; }

    case type_weight: {
      double temp;
      unit_type unit;
      if (parse_weight(str, &temp, &unit))
	{
	  str.clear();
	  format_weight(str, temp, unit);
	  return true;
	}
      break; }

    case type_fraction: {
      double value;
      if (parse_fraction(str, &value))
	{
	  str.clear();
	  format_fraction(str, value);
	  return true;
	}
      break; }

    case type_keywords: {
      std::vector<std::string> keys;
      if (parse_keywords(str, &keys))
	{
	  str.clear();
	  format_keywords(str, keys);
	  return true;
	}
      break; }
    }

  return false;
}

namespace {

int
days_since_1970(const struct tm &tm)
{
  /* Adapted from Linux kernel's mktime(). */

  int year = tm.tm_year + 1900;
  int month = tm.tm_mon - 1;	/* 0..11 -> 11,12,1..10 */
  if (month < 0)
    month += 12, year -= 1;
  int day = tm.tm_mday;

  return ((year/4 - year/100 + year/400 + 367*month/12 + day)
	  + year*365 - 719499);
}

void
append_days_date(std::string &str, int days)
{
  time_t date = days * (time_t) (24*60*60);
  struct tm tm = {0};
  localtime_r(&date, &tm);

  char buf[128];
  strftime_l(buf, sizeof(buf), "%F", &tm, nullptr);
  str.append(buf);
}

} // anonymous namespace

int
date_interval::date_index(time_t date) const
{
  struct tm tm = {0};
  localtime_r(&date, &tm);

  switch (unit)
    {
    case days:
      return days_since_1970(tm);

    case weeks: {
      // 1970-01-01 was a thursday.
      static int week_offset = 4 - shared_config().start_of_week();
      return (days_since_1970(tm) + week_offset) / 7; }

    case months:
      return (tm.tm_year - 70) * 12 + tm.tm_mon;

    case years:
      return tm.tm_year - 70;
    }
}

void
date_interval::append_date(std::string &str, int x) const
{
  switch (unit)
    {
    case days:
      append_days_date(str, x);
      break;

    case weeks: {
      static int week_offset = 4 - shared_config().start_of_week();
      int days = x * 7 - week_offset;
      append_days_date(str, days);
      break; }

    case months: {
      int month = x % 12;
      int year = 1970 + x / 12;
      char buf[128];
      static const char *names[] = {"January", "February", "March",
	"April", "May", "June", "July", "August", "September",
	"October", "November", "December"};
      snprintf_l(buf, sizeof(buf), nullptr, "%s %04d", names[month], year);
      str.append(buf);
      break; }

    case years: {
      char buf[64];
      snprintf_l(buf, sizeof(buf), nullptr, "%d", 1970 + x);
      str.append(buf);
      break; }
    }
}

} // namespace act
<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl_ros/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include "mongodb_store/SetParam.h"

#include <actionlib/server/simple_action_server.h>
#include <calibrate_chest/CalibrateCameraAction.h>

#include <sensor_msgs/JointState.h>

class CalibrateCameraServer {
private:

    ros::NodeHandle n;
    actionlib::SimpleActionServer<calibrate_chest::CalibrateCameraAction> server;
    std::string action_name;
    ros::ServiceClient client;
    std::string camera_name;
    std::string camera_topic;
    calibrate_chest::CalibrateCameraFeedback feedback;
    calibrate_chest::CalibrateCameraResult result;

public:

    CalibrateCameraServer(const std::string& name, const std::string& camera_name) :
        server(n, name, boost::bind(&CalibrateCameraServer::execute_cb, this, _1), false),
        action_name(name),
        client(n.serviceClient<mongodb_store::SetParam>("/config_manager/set_param")),
        camera_name(camera_name),
        camera_topic(camera_name + "/depth/points")
    {
        server.start();
    }

private:

    bool is_inlier(const Eigen::Vector3f& point, const Eigen::Vector4f plane, double threshold) const
    {
        return fabs(point.dot(plane.segment<3>(0)) + plane(3)) < threshold;
    }

    void plot_best_plane(const pcl::PointCloud<pcl::PointXYZ>& points, const Eigen::Vector4f plane, double threshold) const
    {
        pcl::PointCloud<pcl::PointXYZ>::Ptr inlier_cloud(new pcl::PointCloud<pcl::PointXYZ>());
        pcl::PointCloud<pcl::PointXYZ>::Ptr outlier_cloud(new pcl::PointCloud<pcl::PointXYZ>());

        for (int i = 0; i < points.size(); ++i) {
            if (is_inlier(points[i].getVector3fMap(), plane, threshold)) {
                inlier_cloud->push_back(points[i]);
            }
            else {
                outlier_cloud->push_back(points[i]);
            }
        }

        pcl::visualization::PCLVisualizer viewer("3D Viewer");
        viewer.setBackgroundColor(0, 0, 0);
        viewer.addCoordinateSystem(1.0);
        viewer.initCameraParameters();

        pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> inlier_color_handler(inlier_cloud, 255, 0, 0);
        viewer.addPointCloud(inlier_cloud, inlier_color_handler, "inliers");

        pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> outlier_color_handler(outlier_cloud, 0, 0, 255);
        viewer.addPointCloud(outlier_cloud, outlier_color_handler, "outliers");

        while (!viewer.wasStopped())
        {
            viewer.spinOnce(100);
            boost::this_thread::sleep(boost::posix_time::microseconds(100000));
        }

    }

    void compute_plane(Eigen::Vector4f& plane, const pcl::PointCloud<pcl::PointXYZ>& points, int* inds) const
    {
        Eigen::Vector3f first = points[inds[1]].getVector3fMap() - points[inds[0]].getVector3fMap();
        Eigen::Vector3f second = points[inds[2]].getVector3fMap() - points[inds[0]].getVector3fMap();
        Eigen::Vector3f normal = first.cross(second);
        normal.normalize();
        plane.segment<3>(0) = normal;
        plane(3) = -normal.dot(points[inds[0]].getVector3fMap());
    }

    void extract_height_and_angle(const Eigen::Vector4f& plane)
    {
        feedback.status = "Checking and saving calibration...";
        server.publishFeedback(feedback);

        ROS_INFO("Ground plane: %f, %f, %f, %f", plane(0), plane(1), plane(2), plane(3));
        double dist = fabs(plane(3)/plane(2)); // distance along z axis
        double height = fabs(plane(3)/plane.segment<3>(0).squaredNorm()); // height
        ROS_INFO("Distance to plane along camera axis: %f", dist);
        ROS_INFO("Height above ground: %f", height);
        double angle = asin(height/dist);
        double angle_deg = 180.0f*angle/M_PI;
        ROS_INFO("Angle radians: %f", angle);
        ROS_INFO("Angle degrees: %f", angle_deg);

        result.angle = angle_deg;
        result.height = height;

        if (fabs(45.0f - angle_deg) > 3.0f) {
            result.status = "Angle not close enough to 45 degrees.";
            server.setAborted(result);
            return;
        }

        mongodb_store::SetParam srv;
        char buffer[250];

        // store height above ground in datacentre
        ros::param::set(std::string("/") + camera_name + "_height", height);
        sprintf(buffer, "{\"path\":\"/%s_height\",\"value\":%f}", camera_name.c_str(), height);
        srv.request.param = buffer;
        if (!client.call(srv)) {
            ROS_ERROR("Failed to call set height, is config manager running?");
        }

        // store angle between camera and horizontal plane
        ros::param::set(std::string("/") + camera_name + "_angle", angle);
        sprintf(buffer, "{\"path\":\"/%s_angle\",\"value\":%f}", camera_name.c_str(), angle);
        srv.request.param = buffer;
        if (!client.call(srv)) {
            ROS_ERROR("Failed to call set angle, is config manager running?");
        }

        result.status = "Successfully computed and saved calibration.";
        server.setSucceeded(result);
    }

    void publish_calibration()
    {
        feedback.status = "Publishing calibration...";
        feedback.progress = 0.0f;

        // get calibration with respect to ground plane from the calibrate_chest node
        double height, angle;
        n.param<double>(std::string("/") + camera_name + "_height", height, 1.10f); // get the height calibration
        n.param<double>(std::string("/") + camera_name + "_angle", angle, 0.72f); // get the angle calibration

        ros::Rate rate(1.0f);
        ros::Publisher pub = n.advertise<sensor_msgs::JointState>("/chest_calibration_publisher/state", 1);

        int counter = 0; // only publish for the first 10 secs, transforms will stay in tf
        while (n.ok() && counter < 5) {
            sensor_msgs::JointState joint_state;
            joint_state.header.stamp = ros::Time::now();
            joint_state.name.resize(2);
            joint_state.position.resize(2);
            joint_state.velocity.resize(2);
            joint_state.name[0] = camera_name + "_height_joint";
            joint_state.name[1] = camera_name + "_tilt_joint";
            joint_state.position[0] = height;
            joint_state.position[1] = angle;
            joint_state.velocity[0] = 0;
            joint_state.velocity[1] = 0;
            pub.publish(joint_state);

            feedback.progress = float(counter+1)/5.0f;
            server.publishFeedback(feedback);

            rate.sleep();
            ++counter;
        }

        ROS_INFO("Stopping to publish chest transform after 5 seconds, quitting...");

        result.status = "Published calibration.";
        result.angle = 180.0f/M_PI*angle;
        result.height = height;
        server.setSucceeded(result);
    }

public:

    void msg_callback(const sensor_msgs::PointCloud2::ConstPtr& msg)
    {
        //if (!do_calibrate) {
        //    return;
        //}
        //do_calibrate = false;

        feedback.status = "Calibrating...";
        feedback.progress = 0.0f;
        server.publishFeedback(feedback);

        ROS_INFO("Got a pointcloud, calibrating...");
        pcl::PointCloud<pcl::PointXYZ> cloud;
        pcl::fromROSMsg(*msg, cloud);

        int nbr = cloud.size();

        int max = 1000; // ransac iterations
        double threshold = 0.02; // threshold for plane inliers

        Eigen::Vector4f best_plane; // best plane parameters found
        int best_inliers = -1; // best number of inliers

        int inds[3];

        Eigen::Vector4f plane;
        int inliers;
        for (int i = 0; i < max; ++i) {

            for (int j = 0; j < 3; ++j) {
                inds[j] = rand() % nbr; // get a random point
            }

            // check that the points aren't the same
            if (inds[0] == inds[1] || inds[0] == inds[2] || inds[1] == inds[2]) {
                continue;
            }

            compute_plane(plane, cloud, inds);
            inliers = 0;
            for (int j = 0; j < nbr; j += 30) { // count number of inliers
                if (is_inlier(cloud[j].getVector3fMap(), plane, threshold)) {
                    ++inliers;
                }
            }

            if (inliers > best_inliers) {
                best_plane = plane;
                best_inliers = inliers;
            }

            if (i % 10 == 0 || i == max - 1) {
                feedback.progress = float(i+1)/float(max);
                server.publishFeedback(feedback);
            }
        }

        extract_height_and_angle(best_plane); // find parameters and feed them to datacentre
        //plot_best_plane(cloud, best_plane, threshold); // visually evaluate plane fit
    }

    void execute_cb(const calibrate_chest::CalibrateCameraGoalConstPtr& goal)
    {
        if (goal->command == "calibrate") {
            sensor_msgs::PointCloud2::ConstPtr msg = ros::topic::waitForMessage<sensor_msgs::PointCloud2>(camera_topic, n);
            if (msg) {
                msg_callback(msg);
            }
            else {
                result.status = "Did not receive any point cloud.";
                server.setAborted(result);
            }
        }
        else if (goal->command == "publish") {
            publish_calibration();
        }
        else {
            result.status = "Enter command \"calibrate\" or \"publish\".";
            server.setAborted(result);
        }
    }
};

int main(int argc, char** argv)
{
    ros::init(argc, argv, "calibrate_chest");
    CalibrateCameraServer calibrate(ros::this_node::getName(), "chest_xtion");
    ros::spin();

	return 0;
}
<commit_msg>Made desired angle configurable<commit_after>#include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl_ros/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include "mongodb_store/SetParam.h"
#include <sstream>

#include <actionlib/server/simple_action_server.h>
#include <calibrate_chest/CalibrateCameraAction.h>

#include <sensor_msgs/JointState.h>

class CalibrateCameraServer {
private:

    ros::NodeHandle n;
    actionlib::SimpleActionServer<calibrate_chest::CalibrateCameraAction> server;
    std::string action_name;
    ros::ServiceClient client;
    std::string camera_name;
    std::string camera_topic;
    double desired_angle;
    calibrate_chest::CalibrateCameraFeedback feedback;
    calibrate_chest::CalibrateCameraResult result;

public:

    CalibrateCameraServer(const std::string& name, const std::string& camera_name, double angle) :
        server(n, name, boost::bind(&CalibrateCameraServer::execute_cb, this, _1), false),
        action_name(name),
        client(n.serviceClient<mongodb_store::SetParam>("/config_manager/set_param")),
        camera_name(camera_name),
        camera_topic(camera_name + "/depth/points"),
        desired_angle(angle)
    {
        server.start();
    }

private:

    bool is_inlier(const Eigen::Vector3f& point, const Eigen::Vector4f plane, double threshold) const
    {
        return fabs(point.dot(plane.segment<3>(0)) + plane(3)) < threshold;
    }

    void plot_best_plane(const pcl::PointCloud<pcl::PointXYZ>& points, const Eigen::Vector4f plane, double threshold) const
    {
        pcl::PointCloud<pcl::PointXYZ>::Ptr inlier_cloud(new pcl::PointCloud<pcl::PointXYZ>());
        pcl::PointCloud<pcl::PointXYZ>::Ptr outlier_cloud(new pcl::PointCloud<pcl::PointXYZ>());

        for (int i = 0; i < points.size(); ++i) {
            if (is_inlier(points[i].getVector3fMap(), plane, threshold)) {
                inlier_cloud->push_back(points[i]);
            }
            else {
                outlier_cloud->push_back(points[i]);
            }
        }

        pcl::visualization::PCLVisualizer viewer("3D Viewer");
        viewer.setBackgroundColor(0, 0, 0);
        viewer.addCoordinateSystem(1.0);
        viewer.initCameraParameters();

        pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> inlier_color_handler(inlier_cloud, 255, 0, 0);
        viewer.addPointCloud(inlier_cloud, inlier_color_handler, "inliers");

        pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> outlier_color_handler(outlier_cloud, 0, 0, 255);
        viewer.addPointCloud(outlier_cloud, outlier_color_handler, "outliers");

        while (!viewer.wasStopped())
        {
            viewer.spinOnce(100);
            boost::this_thread::sleep(boost::posix_time::microseconds(100000));
        }

    }

    void compute_plane(Eigen::Vector4f& plane, const pcl::PointCloud<pcl::PointXYZ>& points, int* inds) const
    {
        Eigen::Vector3f first = points[inds[1]].getVector3fMap() - points[inds[0]].getVector3fMap();
        Eigen::Vector3f second = points[inds[2]].getVector3fMap() - points[inds[0]].getVector3fMap();
        Eigen::Vector3f normal = first.cross(second);
        normal.normalize();
        plane.segment<3>(0) = normal;
        plane(3) = -normal.dot(points[inds[0]].getVector3fMap());
    }

    void extract_height_and_angle(const Eigen::Vector4f& plane)
    {
        feedback.status = "Checking and saving calibration...";
        server.publishFeedback(feedback);

        ROS_INFO("Ground plane: %f, %f, %f, %f", plane(0), plane(1), plane(2), plane(3));
        double dist = fabs(plane(3)/plane(2)); // distance along z axis
        double height = fabs(plane(3)/plane.segment<3>(0).squaredNorm()); // height
        ROS_INFO("Distance to plane along camera axis: %f", dist);
        ROS_INFO("Height above ground: %f", height);
        double angle = asin(height/dist);
        double angle_deg = 180.0f*angle/M_PI;
        ROS_INFO("Angle radians: %f", angle);
        ROS_INFO("Angle degrees: %f", angle_deg);

        result.angle = angle_deg;
        result.height = height;

        if (fabs(desired_angle - angle_deg) > 3.0f) {
            std::stringstream ss;
            ss << desired_angle;
            result.status = std::string("Angle not close enough to ") + ss.str() + " degrees.";
            server.setAborted(result);
            return;
        }

        mongodb_store::SetParam srv;
        char buffer[250];

        // store height above ground in datacentre
        ros::param::set(std::string("/") + camera_name + "_height", height);
        sprintf(buffer, "{\"path\":\"/%s_height\",\"value\":%f}", camera_name.c_str(), height);
        srv.request.param = buffer;
        if (!client.call(srv)) {
            ROS_ERROR("Failed to call set height, is config manager running?");
        }

        // store angle between camera and horizontal plane
        ros::param::set(std::string("/") + camera_name + "_angle", angle);
        sprintf(buffer, "{\"path\":\"/%s_angle\",\"value\":%f}", camera_name.c_str(), angle);
        srv.request.param = buffer;
        if (!client.call(srv)) {
            ROS_ERROR("Failed to call set angle, is config manager running?");
        }

        result.status = "Successfully computed and saved calibration.";
        server.setSucceeded(result);
    }

    void publish_calibration()
    {
        feedback.status = "Publishing calibration...";
        feedback.progress = 0.0f;

        // get calibration with respect to ground plane from the calibrate_chest node
        double height, angle;
        n.param<double>(std::string("/") + camera_name + "_height", height, 1.10f); // get the height calibration
        n.param<double>(std::string("/") + camera_name + "_angle", angle, 0.72f); // get the angle calibration

        ros::Rate rate(1.0f);
        ros::Publisher pub = n.advertise<sensor_msgs::JointState>("/chest_calibration_publisher/state", 1);

        int counter = 0; // only publish for the first 10 secs, transforms will stay in tf
        while (n.ok() && counter < 5) {
            sensor_msgs::JointState joint_state;
            joint_state.header.stamp = ros::Time::now();
            joint_state.name.resize(2);
            joint_state.position.resize(2);
            joint_state.velocity.resize(2);
            joint_state.name[0] = camera_name + "_height_joint";
            joint_state.name[1] = camera_name + "_tilt_joint";
            joint_state.position[0] = height;
            joint_state.position[1] = angle;
            joint_state.velocity[0] = 0;
            joint_state.velocity[1] = 0;
            pub.publish(joint_state);

            feedback.progress = float(counter+1)/5.0f;
            server.publishFeedback(feedback);

            rate.sleep();
            ++counter;
        }

        ROS_INFO("Stopping to publish chest transform after 5 seconds, quitting...");

        result.status = "Published calibration.";
        result.angle = 180.0f/M_PI*angle;
        result.height = height;
        server.setSucceeded(result);
    }

public:

    void msg_callback(const sensor_msgs::PointCloud2::ConstPtr& msg)
    {
        //if (!do_calibrate) {
        //    return;
        //}
        //do_calibrate = false;

        feedback.status = "Calibrating...";
        feedback.progress = 0.0f;
        server.publishFeedback(feedback);

        ROS_INFO("Got a pointcloud, calibrating...");
        pcl::PointCloud<pcl::PointXYZ> cloud;
        pcl::fromROSMsg(*msg, cloud);

        int nbr = cloud.size();

        int max = 1000; // ransac iterations
        double threshold = 0.02; // threshold for plane inliers

        Eigen::Vector4f best_plane; // best plane parameters found
        int best_inliers = -1; // best number of inliers

        int inds[3];

        Eigen::Vector4f plane;
        int inliers;
        for (int i = 0; i < max; ++i) {

            for (int j = 0; j < 3; ++j) {
                inds[j] = rand() % nbr; // get a random point
            }

            // check that the points aren't the same
            if (inds[0] == inds[1] || inds[0] == inds[2] || inds[1] == inds[2]) {
                continue;
            }

            compute_plane(plane, cloud, inds);
            inliers = 0;
            for (int j = 0; j < nbr; j += 30) { // count number of inliers
                if (is_inlier(cloud[j].getVector3fMap(), plane, threshold)) {
                    ++inliers;
                }
            }

            if (inliers > best_inliers) {
                best_plane = plane;
                best_inliers = inliers;
            }

            if (i % 10 == 0 || i == max - 1) {
                feedback.progress = float(i+1)/float(max);
                server.publishFeedback(feedback);
            }
        }

        extract_height_and_angle(best_plane); // find parameters and feed them to datacentre
        //plot_best_plane(cloud, best_plane, threshold); // visually evaluate plane fit
    }

    void execute_cb(const calibrate_chest::CalibrateCameraGoalConstPtr& goal)
    {
        if (goal->command == "calibrate") {
            sensor_msgs::PointCloud2::ConstPtr msg = ros::topic::waitForMessage<sensor_msgs::PointCloud2>(camera_topic, n);
            if (msg) {
                msg_callback(msg);
            }
            else {
                result.status = "Did not receive any point cloud.";
                server.setAborted(result);
            }
        }
        else if (goal->command == "publish") {
            publish_calibration();
        }
        else {
            result.status = "Enter command \"calibrate\" or \"publish\".";
            server.setAborted(result);
        }
    }
};

int main(int argc, char** argv)
{
    ros::init(argc, argv, "calibrate_chest");
    CalibrateCameraServer calibrate(ros::this_node::getName(), "chest_xtion", 46.0);
    ros::spin();

	return 0;
}
<|endoftext|>


<commit_before>#ifndef __REPLICASET_HPP_INCLUDED__
#define __REPLICASET_HPP_INCLUDED__

#include <iterator>
#include <memory>
#include <set>
#include <string>

struct Replica
{
    std::string hostname;

    short port;

    Replica()
        : hostname(),
          port()
    {
    }

    Replica(std::string h, short p=8081)
        : hostname(h),
          port(p)
    {
    }
};

struct compare_replica
{
    bool operator()(const Replica& lhs, const Replica& rhs) const
    {
        return lhs.hostname < rhs.hostname;
    }
};

class ReplicaSet
{
public:

    ReplicaSet();

    ~ReplicaSet();

    void Add(Replica replica);

    void Remove(Replica replica);

    bool Contains(Replica replica);

    int GetSize();

    void Clear();

    std::shared_ptr<ReplicaSet> Intersection(std::shared_ptr<ReplicaSet> other);

    using iterator = std::set<Replica, compare_replica>::iterator;

    using const_iterator = std::set<Replica, compare_replica>::const_iterator;

    ReplicaSet::iterator begin() const;

    ReplicaSet::iterator end() const;

private:

    std::set<Replica, compare_replica> replicaset;
};

#endif
<commit_msg>Update replicaset iterator definition syntax<commit_after>#ifndef __REPLICASET_HPP_INCLUDED__
#define __REPLICASET_HPP_INCLUDED__

#include <iterator>
#include <memory>
#include <set>
#include <string>

struct Replica
{
    std::string hostname;

    short port;

    Replica()
        : hostname(),
          port()
    {
    }

    Replica(std::string h, short p=8081)
        : hostname(h),
          port(p)
    {
    }
};

struct compare_replica
{
    bool operator()(const Replica& lhs, const Replica& rhs) const
    {
        return lhs.hostname < rhs.hostname;
    }
};

class ReplicaSet
{
public:

    ReplicaSet();

    ~ReplicaSet();

    void Add(Replica replica);

    void Remove(Replica replica);

    bool Contains(Replica replica);

    int GetSize();

    void Clear();

    std::shared_ptr<ReplicaSet> Intersection(std::shared_ptr<ReplicaSet> other);

    typedef typename std::set<Replica, compare_replica>::iterator iterator;

    typedef typename std::set<Replica, compare_replica>::const_iterator const_iterator;

    ReplicaSet::iterator begin() const;

    ReplicaSet::iterator end() const;

private:

    std::set<Replica, compare_replica> replicaset;
};

#endif
<|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: AliTRDtrackingEfficiencyCombined.cxx 27496 2008-07-22 08:35:45Z cblume $ */

////////////////////////////////////////////////////////////////////////////
//                                                                        //
//  Reconstruction QA                                                     //
//                                                                        //
//  Authors:                                                              //
//    Markus Fasel <M.Fasel@gsi.de>                                       //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

#include <TObjArray.h>
#include <TProfile.h>
#include <TMath.h>
#include <TCanvas.h>
#include "TTreeStream.h"

#include "AliMagFMaps.h"
#include "AliTracker.h"
#include "AliTrackReference.h"
#include "AliAnalysisManager.h"

#include "AliTRDseedV1.h"
#include "AliTRDtrackV1.h"
#include "AliTRDtrackInfo/AliTRDtrackInfo.h"
#include "AliTRDtrackingEfficiencyCombined.h"

ClassImp(AliTRDtrackingEfficiencyCombined)

//_____________________________________________________________________________
AliTRDtrackingEfficiencyCombined::AliTRDtrackingEfficiencyCombined()
  :AliTRDrecoTask("TrackingEffMC", "Combined Tracking Efficiency")
{
  //
  // Default constructor
  //
}

//_____________________________________________________________________________
void AliTRDtrackingEfficiencyCombined::CreateOutputObjects(){
  //
  // Create output objects
  //

  OpenFile(0, "RECREATE");

  const Int_t nbins = 11;
  Float_t xbins[nbins+1] = {.5, .7, .9, 1.3, 1.7, 2.4, 3.5, 4.5, 5.5, 7., 9., 11.};

  fContainer = new TObjArray();
  fContainer->Add(new TProfile("trEffComb", "Combined Tracking Efficiency", nbins, xbins));
  fContainer->Add(new TProfile("trContComb", "Combined Tracking Contamination", nbins, xbins));
}

//_____________________________________________________________________________
void AliTRDtrackingEfficiencyCombined::Exec(Option_t *){
  //
  // Do it
  //

	const Float_t kAlpha = 0.349065850;
	Int_t naccepted = 0, nrejected = 0, ndoublecounted = 0;
	Int_t labelsacc[10000];
	Int_t labelsrej[10000];
	Float_t momacc[10000];
	Float_t momrej[10000];
	if(!AliTracker::GetFieldMap()){
		AliMagFMaps* field = new AliMagFMaps("Maps","Maps", 2, 1., 10., AliMagFMaps::k5kG);
		AliTracker::SetFieldMap(field, kTRUE);
	}
	TProfile *efficiency = (TProfile *)fContainer->At(0);
	TProfile *contamination = (TProfile *)fContainer->At(1);

	Int_t nTrackInfos = fTracks->GetEntriesFast();
	Double_t mom = 0;
	AliTRDtrackV1 *TRDtrack = 0x0;
	AliTRDtrackInfo *trkInf = 0x0;
	AliTrackReference *trackRef = 0x0;
	for(Int_t itinf = 0; itinf < nTrackInfos; itinf++){
		mom = 0.;
		trkInf = dynamic_cast<AliTRDtrackInfo *>(fTracks->UncheckedAt(itinf));
		if(!trkInf) continue;
		if((TRDtrack = trkInf->GetTRDtrack()) || trkInf->GetNumberOfClustersRefit()){
			// check if allready found by the tracker
			Bool_t found = kFALSE;
			for(Int_t il = 0; il < naccepted; il++){
				if(labelsacc[il] == trkInf->GetLabel()) found = kTRUE;
			}
			if(found){
				mom =  trackRef ? trackRef->P() : TRDtrack->P();
				contamination->Fill(mom, 1);
				ndoublecounted++;
				continue;
			}
			if(trkInf->GetNTrackRefs()){
				Int_t iref = 0;
				while(!(trackRef = trkInf->GetTrackRef(iref++)));
			}
			if(!trackRef) printf("Error: Track Reference missing for Track %d\n", TRDtrack->GetLabel());
			mom =  trackRef ? trackRef->P() : TRDtrack->P();
//           Accept track
			if(fDebugLevel > 3)printf("Accept track\n");
			momacc[naccepted] = mom;
			labelsacc[naccepted++] = trkInf->GetLabel();
/*			printf("Reconstructed: event %3d Tracks: MC[%d] ESD[%d] NRefs[%d]\n", (Int_t)AliAnalysisManager::GetAnalysisManager()->GetCurrentEntry(), trkInf->GetLabel(),  trkInf->GetTrackId(), trkInf->GetNTrackRefs());*/
    } else{
			if(fDebugLevel>10) printf("Analysing Track References\n");
      // Check if track is findable
			Float_t xmin = 10000.0, xmax = 0.0;
			Float_t ymin = 0.0, ymax = 0.0;
			Float_t zmin = 0.0, zmax = 0.0;
			Float_t lastx = 0.0, x = 0.0;
			Int_t nLayers = 0;
/*			trackRef = trkInf->GetTrackRef(0);*/
/*			xmin = trackRef->LocalX(); xmax = trackRef->LocalX();
      ymin = trackRef->LocalY(); ymax = trackRef->LocalY();
      mom = trackRef->P();*/
      Int_t *sector = new Int_t[trkInf->GetNTrackRefs()];
      for(Int_t itr = 0; itr < trkInf->GetNTrackRefs(); itr++){
        trackRef = trkInf->GetTrackRef(itr);
				if(fDebugLevel>10) printf("%d. x[%f], y[%f], z[%f]\n", itr, trackRef->LocalX(), trackRef->LocalY(), trackRef->Z());
				x = trackRef->LocalX();
				if(x < 250. || x > 370.) continue;	// Be Sure that we are inside TRD
        sector[itr] = Int_t(trackRef->Alpha()/kAlpha);
        if(x < xmin){
          xmin = trackRef->LocalX();
          ymin = trackRef->LocalY();
          zmin = trackRef->Z();
          mom = trackRef->P();
        }
        if(x > xmax){
          xmax = trackRef->LocalX();
          ymax = trackRef->LocalY();
          zmax = trackRef->Z();
        }
				if(itr > 0){
					Float_t dist = TMath::Abs(x - lastx);
					if(fDebugLevel>10) printf("x = %f, lastx = %f, dist = %f\n", x, lastx, dist);
					if(TMath::Abs(dist - 3.7) < 0.1) nLayers++; 	// ref(i+1) has to be larger than ref(i)
				}
				lastx = x;
      }
      // Apply cuts
      Bool_t findable = kTRUE;
      if(trkInf->GetNTrackRefs() > 2 && xmax > xmin){
        if(mom < 0.55) findable = kFALSE;									// momentum cut at 0.6
 				Double_t yangle = (ymax -ymin)/(xmax - xmin);
				Double_t zangle = (zmax -zmin)/(xmax - xmin);
				if(fDebugLevel>10) printf("track: y-Angle = %f, z-Angle = %f\n", yangle, zangle);
				if(fDebugLevel>10) printf("nLayers = %d\n", nLayers);
				if(TMath::ATan(TMath::Abs(yangle)) > 45.) findable = kFALSE;
				if(TMath::ATan(TMath::Abs(zangle)) > 45.) findable = kFALSE;
				if(nLayers < 4) findable = kFALSE;
        if(!trkInf->IsPrimary()) findable = kFALSE;
        Bool_t samesec = kTRUE;
        for(Int_t iref = 1; iref < trkInf->GetNTrackRefs(); iref++)
          if(sector[iref] != sector[0]) samesec = kFALSE;
        if(!samesec) findable = kFALSE;		// Discard all tracks which are passing more than one sector
        if(fDebugLevel){
          Double_t trackAngle = TMath::ATan(yangle);
          Bool_t primary = trkInf->IsPrimary();
          (*fDebugStream) << "NotFoundTrack"
            << "Momentum=" 	<< mom
            << "trackAngle="<< trackAngle
            << "NLayers="	<< nLayers
            << "Primary="	<< primary
            << "\n";
        }
      }
      else
        findable = kFALSE;
      delete[] sector;
      if(findable){
				momrej[nrejected] = mom;
				labelsrej[nrejected++] = trkInf->GetLabel();
/*			  printf("Not Reconstructed: event %3d Tracks: MC[%d] ESD[%d] NRefs[%d]\n", (Int_t)AliAnalysisManager::GetAnalysisManager()->GetCurrentEntry(), trkInf->GetLabel(),  trkInf->GetTrackId(), trkInf->GetNTrackRefs());*/
      }
    }
  }
	for(Int_t itk = 0; itk < naccepted; itk++){
		if(fDebugLevel > 2)printf("Accepted MC track: %d\n", labelsacc[itk]);
		efficiency->Fill(momacc[itk], 1);
		contamination->Fill(momacc[itk], 0);
	}
	Int_t nall = naccepted;
	for(Int_t imis = 0; imis < nrejected; imis++){
		Bool_t found = kFALSE;
		for(Int_t ifound = 0; ifound < naccepted; ifound++){
			if(labelsacc[ifound] == labelsrej[imis]){
				found = kTRUE;
				break;
			}
		}
		if(!found){
			efficiency->Fill(momrej[imis], 0);
			contamination->Fill(momrej[imis], 0);
			if(fDebugLevel > 2)printf("Rejected MC track: %d\n", labelsrej[imis]);
			nall++;
		}
	}
  //if(fDebugLevel>=1)
  printf("%3d Tracks: MC[%3d] TRD[%3d | %5.2f%%] \n", (Int_t)AliAnalysisManager::GetAnalysisManager()->GetCurrentEntry(), nall, naccepted, 1.E2*Float_t(naccepted)/Float_t(nall));
  printf("%3d Tracks: ALL[%3d] DoubleCounted[%3d | %5.2f%%] \n", (Int_t)AliAnalysisManager::GetAnalysisManager()->GetCurrentEntry(), nall + ndoublecounted, ndoublecounted, 1.E2*Float_t(ndoublecounted)/Float_t(nall + ndoublecounted));

  PostData(0, fContainer);
}

//_____________________________________________________________________________
void AliTRDtrackingEfficiencyCombined::Terminate(Option_t *)
{
  //
  // Termination
  //

  if(fDebugStream){
    delete fDebugStream;
    fDebugStream = 0x0;
    fDebugLevel = 0;
  }

  fContainer = dynamic_cast<TObjArray*>(GetOutputData(0));
  if (!fContainer) {
    Printf("ERROR: list not available");
    return;
  }

  /*TProfile *hEff = (TProfile*)fContainer->At(0);
  TProfile *hEffCont = (TProfile*)fContainer->At(1);
  Printf("Eff[%p] EffCont[%p]\n", (void*)hEff, (void*)hEffCont);

  TCanvas *c2 = new TCanvas("c2","",800,400);
  c2->Divide(2,1);

  c2->cd(1);
  hEff->DrawCopy("e1");
  c2->cd(2);
  hEffCont->DrawCopy("e1");*/
}
<commit_msg>insert protection against kink candidates from TPC<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: AliTRDtrackingEfficiencyCombined.cxx 27496 2008-07-22 08:35:45Z cblume $ */

////////////////////////////////////////////////////////////////////////////
//                                                                        //
//  Reconstruction QA                                                     //
//                                                                        //
//  Authors:                                                              //
//    Markus Fasel <M.Fasel@gsi.de>                                       //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

#include <TObjArray.h>
#include <TProfile.h>
#include <TMath.h>
#include <TCanvas.h>
#include "TTreeStream.h"

#include "AliMagFMaps.h"
#include "AliTracker.h"
#include "AliTrackReference.h"
#include "AliAnalysisManager.h"

#include "AliTRDseedV1.h"
#include "AliTRDtrackV1.h"
#include "AliTRDtrackInfo/AliTRDtrackInfo.h"
#include "AliTRDtrackingEfficiencyCombined.h"

ClassImp(AliTRDtrackingEfficiencyCombined)

//_____________________________________________________________________________
AliTRDtrackingEfficiencyCombined::AliTRDtrackingEfficiencyCombined()
  :AliTRDrecoTask("TrackingEffMC", "Combined Tracking Efficiency")
{
  //
  // Default constructor
  //
}

//_____________________________________________________________________________
void AliTRDtrackingEfficiencyCombined::CreateOutputObjects(){
  //
  // Create output objects
  //

  OpenFile(0, "RECREATE");

  const Int_t nbins = 11;
  Float_t xbins[nbins+1] = {.5, .7, .9, 1.3, 1.7, 2.4, 3.5, 4.5, 5.5, 7., 9., 11.};

  fContainer = new TObjArray();
  fContainer->Add(new TProfile("trEffComb", "Combined Tracking Efficiency", nbins, xbins));
  fContainer->Add(new TProfile("trContComb", "Combined Tracking Contamination", nbins, xbins));
}

//_____________________________________________________________________________
void AliTRDtrackingEfficiencyCombined::Exec(Option_t *){
  //
  // Do it
  //

	const Float_t kAlpha = 0.349065850;
	Int_t naccepted = 0, nrejected = 0, ndoublecounted = 0;
	Int_t labelsacc[10000];
	Int_t labelsrej[10000];
	Float_t momacc[10000];
	Float_t momrej[10000];
	TProfile *efficiency = (TProfile *)fContainer->At(0);
	TProfile *contamination = (TProfile *)fContainer->At(1);

	Int_t nTrackInfos = fTracks->GetEntriesFast();
	Double_t mom = 0;
	AliTRDtrackV1 *TRDtrack = 0x0;
	AliTRDtrackInfo *trkInf = 0x0;
	AliTrackReference *trackRef = 0x0;
	for(Int_t itinf = 0; itinf < nTrackInfos; itinf++){
		mom = 0.;
		trkInf = dynamic_cast<AliTRDtrackInfo *>(fTracks->UncheckedAt(itinf));
		if(!trkInf) continue;
		if((TRDtrack = trkInf->GetTRDtrack()) || trkInf->GetNumberOfClustersRefit()){
			// check if allready found by the tracker
			Bool_t found = kFALSE;
			for(Int_t il = 0; il < naccepted; il++){
				if(labelsacc[il] == trkInf->GetLabel()) found = kTRUE;
			}
			if(found){
				mom =  trackRef ? trackRef->P() : TRDtrack->P();
				contamination->Fill(mom, 1);
				ndoublecounted++;
				continue;
			}
			if(trkInf->GetNTrackRefs()){
				Int_t iref = 0;
				while(!(trackRef = trkInf->GetTrackRef(iref++)));
			}
			if(!trackRef) printf("Error: Track Reference missing for Track %d\n", trkInf->GetLabel());
			mom =  trackRef ? trackRef->P() : TRDtrack->P();
//           Accept track
			if(fDebugLevel > 3)printf("Accept track\n");
			momacc[naccepted] = mom;
			labelsacc[naccepted++] = trkInf->GetLabel();
/*			printf("Reconstructed: event %3d Tracks: MC[%d] ESD[%d] NRefs[%d]\n", (Int_t)AliAnalysisManager::GetAnalysisManager()->GetCurrentEntry(), trkInf->GetLabel(),  trkInf->GetTrackId(), trkInf->GetNTrackRefs());*/
    } else{
			if(fDebugLevel>10) printf("Analysing Track References\n");
      // Check if track is findable
			Float_t xmin = 10000.0, xmax = 0.0;
			Float_t ymin = 0.0, ymax = 0.0;
			Float_t zmin = 0.0, zmax = 0.0;
			Float_t lastx = 0.0, x = 0.0;
			Int_t nLayers = 0;
/*			trackRef = trkInf->GetTrackRef(0);*/
/*			xmin = trackRef->LocalX(); xmax = trackRef->LocalX();
      ymin = trackRef->LocalY(); ymax = trackRef->LocalY();
      mom = trackRef->P();*/
      Int_t *sector = new Int_t[trkInf->GetNTrackRefs()];
      for(Int_t itr = 0; itr < trkInf->GetNTrackRefs(); itr++){
        trackRef = trkInf->GetTrackRef(itr);
				if(fDebugLevel>10) printf("%d. x[%f], y[%f], z[%f]\n", itr, trackRef->LocalX(), trackRef->LocalY(), trackRef->Z());
				x = trackRef->LocalX();
				if(x < 250. || x > 370.) continue;	// Be Sure that we are inside TRD
        sector[itr] = Int_t(trackRef->Alpha()/kAlpha);
        if(x < xmin){
          xmin = trackRef->LocalX();
          ymin = trackRef->LocalY();
          zmin = trackRef->Z();
          mom = trackRef->P();
        }
        if(x > xmax){
          xmax = trackRef->LocalX();
          ymax = trackRef->LocalY();
          zmax = trackRef->Z();
        }
				if(itr > 0){
					Float_t dist = TMath::Abs(x - lastx);
					if(fDebugLevel>10) printf("x = %f, lastx = %f, dist = %f\n", x, lastx, dist);
					if(TMath::Abs(dist - 3.7) < 0.1) nLayers++; 	// ref(i+1) has to be larger than ref(i)
				}
				lastx = x;
      }
      // Apply cuts
      Bool_t findable = kTRUE;
      if(trkInf->GetNTrackRefs() > 2 && xmax > xmin){
        if(mom < 0.55) findable = kFALSE;									// momentum cut at 0.6
 				Double_t yangle = (ymax -ymin)/(xmax - xmin);
				Double_t zangle = (zmax -zmin)/(xmax - xmin);
				if(fDebugLevel>10) printf("track: y-Angle = %f, z-Angle = %f\n", yangle, zangle);
				if(fDebugLevel>10) printf("nLayers = %d\n", nLayers);
				if(TMath::ATan(TMath::Abs(yangle)) > 45.) findable = kFALSE;
				if(TMath::ATan(TMath::Abs(zangle)) > 45.) findable = kFALSE;
				if(nLayers < 4) findable = kFALSE;
        if(!trkInf->IsPrimary()) findable = kFALSE;
        Bool_t samesec = kTRUE;
        for(Int_t iref = 1; iref < trkInf->GetNTrackRefs(); iref++)
          if(sector[iref] != sector[0]) samesec = kFALSE;
        if(!samesec) findable = kFALSE;		// Discard all tracks which are passing more than one sector
        if(fDebugLevel){
          Double_t trackAngle = TMath::ATan(yangle);
          Bool_t primary = trkInf->IsPrimary();
          (*fDebugStream) << "NotFoundTrack"
            << "Momentum=" 	<< mom
            << "trackAngle="<< trackAngle
            << "NLayers="	<< nLayers
            << "Primary="	<< primary
            << "\n";
        }
      }
      else
        findable = kFALSE;
      delete[] sector;
      if(findable){
				momrej[nrejected] = mom;
				labelsrej[nrejected++] = trkInf->GetLabel();
/*			  printf("Not Reconstructed: event %3d Tracks: MC[%d] ESD[%d] NRefs[%d]\n", (Int_t)AliAnalysisManager::GetAnalysisManager()->GetCurrentEntry(), trkInf->GetLabel(),  trkInf->GetTrackId(), trkInf->GetNTrackRefs());*/
      }
    }
  }
	for(Int_t itk = 0; itk < naccepted; itk++){
		if(fDebugLevel > 2)printf("Accepted MC track: %d\n", labelsacc[itk]);
		efficiency->Fill(momacc[itk], 1);
		contamination->Fill(momacc[itk], 0);
	}
	Int_t nall = naccepted;
	for(Int_t imis = 0; imis < nrejected; imis++){
		Bool_t found = kFALSE;
		for(Int_t ifound = 0; ifound < naccepted; ifound++){
			if(labelsacc[ifound] == labelsrej[imis]){
				found = kTRUE;
				break;
			}
		}
		if(!found){
			efficiency->Fill(momrej[imis], 0);
			contamination->Fill(momrej[imis], 0);
			if(fDebugLevel > 2)printf("Rejected MC track: %d\n", labelsrej[imis]);
			nall++;
		}
	}
  //if(fDebugLevel>=1)
  printf("%3d Tracks: MC[%3d] TRD[%3d | %5.2f%%] \n", (Int_t)AliAnalysisManager::GetAnalysisManager()->GetCurrentEntry(), nall, naccepted, 1.E2*Float_t(naccepted)/Float_t(nall));
  printf("%3d Tracks: ALL[%3d] DoubleCounted[%3d | %5.2f%%] \n", (Int_t)AliAnalysisManager::GetAnalysisManager()->GetCurrentEntry(), nall + ndoublecounted, ndoublecounted, 1.E2*Float_t(ndoublecounted)/Float_t(nall + ndoublecounted));

  PostData(0, fContainer);
}

//_____________________________________________________________________________
void AliTRDtrackingEfficiencyCombined::Terminate(Option_t *)
{
  //
  // Termination
  //

  if(fDebugStream){
    delete fDebugStream;
    fDebugStream = 0x0;
    fDebugLevel = 0;
  }

  fContainer = dynamic_cast<TObjArray*>(GetOutputData(0));
  if (!fContainer) {
    Printf("ERROR: list not available");
    return;
  }

  /*TProfile *hEff = (TProfile*)fContainer->At(0);
  TProfile *hEffCont = (TProfile*)fContainer->At(1);
  Printf("Eff[%p] EffCont[%p]\n", (void*)hEff, (void*)hEffCont);

  TCanvas *c2 = new TCanvas("c2","",800,400);
  c2->Divide(2,1);

  c2->cd(1);
  hEff->DrawCopy("e1");
  c2->cd(2);
  hEffCont->DrawCopy("e1");*/
}
<|endoftext|>


<commit_before>#include "YMain.h"

/** YDA **/
#include "YSpriteSheetManager.h"
#include "YPoint.h"
#include "YVector.h"
#include "YFileSystem.h"

/** Penguin **/
#include "Penguin.h"
#include "Fish.h"
#include "Crab.h"

/** C++ **/
#include <functional>
#include <vector>
#undef main

YSpriteSheetManager::kError loadResources(YSpriteSheetManager* a_manager)
{
    typedef struct Sprites
    {
        std::string key;
        std::string value;
    } Sprite;

    Sprite sprites[] = {
        {"background", "tropical_island_day.png"},
        {"penguin", "penguin.png"},
        {"fish_blue", "fish_blue.png"},
		{"fish_green", "fish_green.png"},
		{"fish_red", "fish_red.png"},
		{"crab_pink", "crab_pink.png"},
        {"scuma", "scuma.png"}
    };

    int size = sizeof(sprites) / sizeof(Sprite);
    bool success = true;
    YSpriteSheetManager::kError result;

    for (int i = 0; i < size; ++i)
    {
        std::string key = sprites[i].key;
        std::string value = YFileSystem::getCurrentDir() + "\\" + sprites[i].value;

        result = a_manager->add(key, value);

        if (result != YSpriteSheetManager::NONE)
        {
            printf("Error on loading %s\n",
                   value.c_str());
            success &= false;
        }
    }

    return success == true ? YSpriteSheetManager::NONE : YSpriteSheetManager::LOADING_ERROR;
}

int main(int argc, char* argv[])
{
	/** creates window **/
    YMain* game = new YMain("Penguins - sergiosvieira@gmail.com",
                            640,
                            480);

	/** loads resources **/
	YSpriteSheetManager* spriteManager = new YSpriteSheetManager(game->renderer());

    if (loadResources(spriteManager) != YSpriteSheetManager::NONE)
    {
    	printf("Error on loading resources!\n");

    	return 1;
    }

	/** creates penguin **/
	Penguin* penguin = new Penguin(spriteManager->findByName("penguin"),
								   YPoint(160.f, -10.f),
								   YFrame(0, 0, 8, 10, 10, 5));
	penguin->firstFrame(0);
	penguin->lastFrame(3);

    /** creates fishes **/
    std::vector<Fish*> fishes;

    for (int i = 0; i < 5; ++i)
    {
		Fish *fish = NULL;

		fish = new Fish(spriteManager->findByName("fish_blue"),
						YPoint(100.f, 100.f),
                        YFrame(0, 0, 2, 10, 10, 15));

        if (fish != NULL)
        {
        	fish->pause(false);
            fishes.push_back(fish);
        }
    }

	YVector gravity(0, 15.0);
	float ground = 410.f;
	SDL_Rect islandRect;

	islandRect.x = 150;
	islandRect.y = ground;
	islandRect.w = 230;
	islandRect.h = 70;

	/** creates crab **/
    SDL_Texture* scuma = spriteManager->findByName("scuma");
	Crab* crab = new Crab(spriteManager->findByName("crab_pink"),
						  YPoint(50.f, ground),
						  YFrame(0, 0, 2, 10, 11, 8),
						  ground,
                          scuma);
	crab->pause(false);
	crab->visible(false);

	bool falling = true;

    YMain::FunctionUpdate update = [&](SDL_Event* a_event)
    {
		if (falling == true)
		{
			YPoint position = penguin->position() + gravity;

			if (position.y() < ground)
			{
				penguin->position(position);
				penguin->currentFrame(8);
				penguin->pause(true);
			}
			else
			{
				YPoint position(penguin->position().x(), ground);

				penguin->position(position);
				falling = false;
				crab->start(islandRect);
			}
		}
		else
		{
			penguin->pause(false);

			if( a_event->type == SDL_MOUSEBUTTONDOWN )
			{
				penguin->startJump();
			}
			else if (a_event->type == SDL_MOUSEBUTTONUP)
			{
				penguin->endJump();
			}

			penguin->update();
			crab->update();
		}
    };

    YMain::FunctionRender render = [&](SDL_Renderer* a_renderer)
    {
		SDL_RenderCopy(a_renderer,
					   spriteManager->findByName("background"),
					   NULL,
					   NULL);

        /** draw penguin **/
        SDL_Rect nextFrameRect = penguin->nextFrame();
        SDL_Rect dstRect = penguin->rect(4);
        SDL_RenderCopy(a_renderer,
                       penguin->texture(),
                       &nextFrameRect,
                       &dstRect);

        /** draw fish **/
        Fish* fish = fishes.at(0);

        if (fish != NULL)
        {
            SDL_Rect nextFishFrameRect = fish->nextFrame();
            SDL_Rect dstFishRect = fish->rect(3);
            SDL_RenderCopy(a_renderer,
                           fish->texture(),
                           &nextFishFrameRect,
                           &dstFishRect);
        }

		/** draw crab **/
        nextFrameRect = crab->nextFrame();
        dstRect = crab->rect(3);
        SDL_RenderCopy(a_renderer,
                       crab->texture(),
                       &nextFrameRect,
                       &dstRect);
        nextFrameRect = crab->scuma()->nextFrame();
        dstRect = crab->scuma()->rect(3);
        SDL_RenderCopy(a_renderer,
                       scuma,
                       &nextFrameRect,
                       &dstRect);
    };

    game->start(&update,
                &render,
                25,
                5);

    /** dealloc resources **/
    for (Fish* fish: fishes)
    {
        if (fish != NULL)
        {
            delete fish;
        }
    }

    delete game;

	return 0;
}
<commit_msg>Choose separator based on OS Change updates of penguin position<commit_after>#include "YMain.h"

/** YDA **/
#include "YSpriteSheetManager.h"
#include "YPoint.h"
#include "YVector.h"
#include "YFileSystem.h"

/** Penguin **/
#include "Penguin.h"
#include "Fish.h"
#include "Crab.h"

/** C++ **/
#include <functional>
#include <vector>
#undef main

YSpriteSheetManager::kError loadResources(YSpriteSheetManager* a_manager)
{
    typedef struct Sprites
    {
        std::string key;
        std::string value;
    } Sprite;

    Sprite sprites[] = {
        {"background", "tropical_island_day.png"},
        {"penguin", "penguin.png"},
        {"fish_blue", "fish_blue.png"},
		{"fish_green", "fish_green.png"},
		{"fish_red", "fish_red.png"},
		{"crab_pink", "crab_pink.png"},
        {"scuma", "scuma.png"}
    };

    int size = sizeof(sprites) / sizeof(Sprite);
    bool success = true;
    YSpriteSheetManager::kError result;

    std::string kSeparator =
#ifdef _WIN32
    "\\";
#else
    "/";
#endif

    for (int i = 0; i < size; ++i)
    {
        std::string key = sprites[i].key;
        std::string value = YFileSystem::getCurrentDir() + kSeparator + sprites[i].value;

        result = a_manager->add(key, value);

        if (result != YSpriteSheetManager::NONE)
        {
            printf("Error on loading %s\n",
                   value.c_str());
            success &= false;
        }
    }

    return success == true ? YSpriteSheetManager::NONE : YSpriteSheetManager::LOADING_ERROR;
}

int main(int argc, char* argv[])
{
	/** creates window **/
    YMain* game = new YMain("Penguins - sergiosvieira@gmail.com",
                            640,
                            480);

	/** loads resources **/
	YSpriteSheetManager* spriteManager = new YSpriteSheetManager(game->renderer());

    if (loadResources(spriteManager) != YSpriteSheetManager::NONE)
    {
    	printf("Error on loading resources!\n");

    	return 1;
    }

	/** creates penguin **/
	Penguin* penguin = new Penguin(spriteManager->findByName("penguin"),
								   YPoint(160.f, -10.f),
								   YFrame(0, 0, 8, 10, 10, 5));
	penguin->firstFrame(0);
	penguin->lastFrame(3);

    /** creates fishes **/
    std::vector<Fish*> fishes;

    for (int i = 0; i < 5; ++i)
    {
		Fish *fish = NULL;

		fish = new Fish(spriteManager->findByName("fish_blue"),
						YPoint(100.f, 100.f),
                        YFrame(0, 0, 2, 10, 10, 15));

        if (fish != NULL)
        {
        	fish->pause(false);
            fishes.push_back(fish);
        }
    }

	YVector gravity(0, 15.0);
	float ground = 410.f;
	SDL_Rect islandRect;

	islandRect.x = 150;
	islandRect.y = ground;
	islandRect.w = 230;
	islandRect.h = 70;

	/** creates crab **/
    SDL_Texture* scuma = spriteManager->findByName("scuma");
	Crab* crab = new Crab(spriteManager->findByName("crab_pink"),
						  YPoint(50.f, ground),
						  YFrame(0, 0, 2, 10, 11, 8),
						  ground,
                          scuma);
	crab->pause(false);
	crab->visible(false);

	bool falling = true;

    YMain::FunctionUpdate update = [&](SDL_Event* a_event)
    {
		if (falling == true)
		{
			YPoint position = penguin->position().add(gravity);

			if (position.y() < ground)
			{
				penguin->position(position);
				penguin->currentFrame(8);
				penguin->pause(true);
			}
			else
			{
				YPoint position(penguin->position().x(), ground);

				penguin->position(position);
				crab->start(islandRect);
				falling = false;
			}
		}
		else
		{
			penguin->pause(false);

			if( a_event->type == SDL_MOUSEBUTTONDOWN )
			{
				penguin->startJump();
			}
			else if (a_event->type == SDL_MOUSEBUTTONUP)
			{
				penguin->endJump();
			}

			penguin->update();
			crab->update();
		}
    };

    YMain::FunctionRender render = [&](SDL_Renderer* a_renderer)
    {
		SDL_RenderCopy(a_renderer,
					   spriteManager->findByName("background"),
					   NULL,
					   NULL);

        /** draw penguin **/
        SDL_Rect nextFrameRect = penguin->nextFrame();
        SDL_Rect dstRect = penguin->rect(4);
        SDL_RenderCopy(a_renderer,
                       penguin->texture(),
                       &nextFrameRect,
                       &dstRect);

        /** draw fish **/
        Fish* fish = fishes.at(0);

        if (fish != NULL)
        {
            SDL_Rect nextFishFrameRect = fish->nextFrame();
            SDL_Rect dstFishRect = fish->rect(3);
            SDL_RenderCopy(a_renderer,
                           fish->texture(),
                           &nextFishFrameRect,
                           &dstFishRect);
        }

		/** draw crab **/
        nextFrameRect = crab->nextFrame();
        dstRect = crab->rect(3);
        SDL_RenderCopy(a_renderer,
                       crab->texture(),
                       &nextFrameRect,
                       &dstRect);
        nextFrameRect = crab->scuma()->nextFrame();
        dstRect = crab->scuma()->rect(3);
        SDL_RenderCopy(a_renderer,
                       scuma,
                       &nextFrameRect,
                       &dstRect);
    };

    game->start(&update,
                &render,
                25,
                5);

    /** dealloc resources **/
    for (Fish* fish: fishes)
    {
        if (fish != NULL)
        {
            delete fish;
        }
    }

    delete game;

	return 0;
}
<|endoftext|>


<commit_before>#include <bits/stdc++.h>

using namespace std;

class Node {
    public:
        int data;
        Node *left;
        Node *right;
        Node(int d) {
            data = d;
            left = NULL;
            right = NULL;
        }
};

class Solution {
    public:
  		Node* insert(Node* root, int data) {
            if(root == NULL) {
                return new Node(data);
            } else {
                Node* cur;
                if(data <= root->data) {
                    cur = insert(root->left, data);
                    root->left = cur;
                } else {
                    cur = insert(root->right, data);
                    root->right = cur;
               }

               return root;
           }
        }
        /*The tree node has data, left child and right child
class Node {
    int data;
    Node* left;
    Node* right;
};

*/

    /*Node *lca(Node *root, int v1,int v2) {
      if(root==NULL)                                              // Corner case and base condition to check whether the root node is empty or not, if it returns NULL then it means that either the root node is empty or the nodes for which Lowest Common Ancestor are asked for are not there in the tree
        return NULL;

       if(v1<root->data && v2<root->data)                         // Recursive function to calculate the value of LCA of two nodes //
      {
        return lca(root->left,v1,v2);                             // Recursive call to the left subtree //
      }
      if(v1>root->data && v2>root->data)
      {
        return lca(root->right,v1,v2);                            // Recursive call to the right subtree//
      }

      return root;

    }*/
/* Alternate way is to store the nodes encountered and check for node common in both path*/

Node *lca(Node *root, int v1, int v2){
  	if(!root){
  		return NULL;
  	}
	auto copy = root;
	vector<Node*> p1;
	vector<Node*> p2;
	while (v1 != copy->data) {
		if (v1 > copy->data) {
			p1.push_back(copy);
			copy = copy->right;
		}else {
			p1.push_back(copy);
			copy = copy->left;
		}
	}
	p1.push_back(copy);
	while (v2 != root->data) {
		if (v2 > root->data) {
			p2.push_back(root);
			root = root->right;
		}else {
			p2.push_back(root);
			root = root->left;
		}
	}
	p2.push_back(root);
	Node *low = NULL;

	for (int i = 0; i < min((int)p1.size(), (int)p2.size()); i++) {
		if(p1[i] == p2[i]){
			low = p1[i];
		}
	}
	return low;
  }

  void topView(Node*root){
    if(!root){
      return;
    }
    map<int, pair<int, int>> m;
    fillMap(root, 0, 0, m);
    for (auto i = m.begin(); i != i.end(); i++){
      cout << i->second.first << " ";
    }
  }

  void fillMap(Node *root, int lvl, int horizontalDistance, map<int, pair<int, int>> &m){
    if(!root){
      return;
    }
    if(!m.count(horizontalDistance)){
      m[horizontalDistance] = make_pair(root->data, lvl);
    }else if(m[d].second > lvl){
      m[horizontalDistance] = make_pair(root->data, lvl);
    }
    fillMap(root->left, lvl+1, horizontalDistance-1, m);
    fillMap(root->right, lvl+1, horizontalDistance+1, m);
  }

};

/*    int main() {

    Solution myTree;
    Node* root = NULL;

    int t;
    int data;

    std::cin >> t;

    while(t-- > 0) {
        std::cin >> data;
        root = myTree.insert(root, data);
    }

  	int v1, v2;
  	std::cin >> v1 >> v2;

    Node *ans = myTree.lca(root, v1, v2);

  	std::cout << ans->data;

    return 0;
}*/

// To run a test comment out the above main function and uncomment the following one//

	int main() {
	Solution myTree;
	Node* root = NULL;
	root = myTree.insert(root,4);
	root = myTree.insert(root,2);
	root = myTree.insert(root,3);
	root = myTree.insert(root,1);
	root = myTree.insert(root,7);
	root = myTree.insert(root,6);
  topView(root);
	Node*ans = myTree.lca(root,1,7);

	std::cout << ans->data;

	return 0;
}

<commit_msg>Top view of binary tree<commit_after>#include <bits/stdc++.h>

using namespace std;

class Node {
    public:
        int data;
        Node *left;
        Node *right;
        Node(int d) {
            data = d;
            left = NULL;
            right = NULL;
        }
};

class Solution {
    public:
  		Node* insert(Node* root, int data) {
            if(root == NULL) {
                return new Node(data);
            } else {
                Node* cur;
                if(data <= root->data) {
                    cur = insert(root->left, data);
                    root->left = cur;
                } else {
                    cur = insert(root->right, data);
                    root->right = cur;
               }

               return root;
           }
        }
        /*The tree node has data, left child and right child
class Node {
    int data;
    Node* left;
    Node* right;
};

*/

    /*Node *lca(Node *root, int v1,int v2) {
      if(root==NULL)                                              // Corner case and base condition to check whether the root node is empty or not, if it returns NULL then it means that either the root node is empty or the nodes for which Lowest Common Ancestor are asked for are not there in the tree
        return NULL;

       if(v1<root->data && v2<root->data)                         // Recursive function to calculate the value of LCA of two nodes //
      {
        return lca(root->left,v1,v2);                             // Recursive call to the left subtree //
      }
      if(v1>root->data && v2>root->data)
      {
        return lca(root->right,v1,v2);                            // Recursive call to the right subtree//
      }

      return root;

    }*/
/* Alternate way is to store the nodes encountered and check for node common in both path*/

Node *lca(Node *root, int v1, int v2){
  	if(!root){
  		return NULL;
  	}
	auto copy = root;
	vector<Node*> p1;
	vector<Node*> p2;
	while (v1 != copy->data) {
		if (v1 > copy->data) {
			p1.push_back(copy);
			copy = copy->right;
		}else {
			p1.push_back(copy);
			copy = copy->left;
		}
	}
	p1.push_back(copy);
	while (v2 != root->data) {
		if (v2 > root->data) {
			p2.push_back(root);
			root = root->right;
		}else {
			p2.push_back(root);
			root = root->left;
		}
	}
	p2.push_back(root);
	Node *low = NULL;

	for (int i = 0; i < min((int)p1.size(), (int)p2.size()); i++) {
		if(p1[i] == p2[i]){
			low = p1[i];
		}
	}
	return low;
  }

};
    void fillMap(Node *root, int lvl, int horizontalDistance, map<int, pair<int, int>> &m){
    if(!root){
      return;
    }
    if(!m.count(horizontalDistance)){
      m[horizontalDistance] = make_pair(root->data, lvl);
    }else if(m[horizontalDistance].second > lvl){
      m[horizontalDistance] = make_pair(root->data, lvl);
    }
    fillMap(root->left, lvl+1, horizontalDistance-1, m);
    fillMap(root->right, lvl+1, horizontalDistance+1, m);
  }

  void topView(Node*root){
    if(!root){
      return;
    }
    map<int, pair<int, int>> m;
    fillMap(root, 0, 0, m);
    for (auto i = m.begin(); i != m.end(); i++){
      cout << i->second.first << " ";
    }
  }
/*
            4
           /  \
          /    \
        2       7
      /   \    /
      1   3   6

Nodes which are visible from top of the root node are considered for top view. In this 1 2 4 7 are visible
from top of root node.(Consider this as 3d model and nodes which are visible from top is our ans.)

 */
/*    int main() {

    Solution myTree;
    Node* root = NULL;

    int t;
    int data;

    std::cin >> t;

    while(t-- > 0) {
        std::cin >> data;
        root = myTree.insert(root, data);
    }

  	int v1, v2;
  	std::cin >> v1 >> v2;

    Node *ans = myTree.lca(root, v1, v2);

  	std::cout << ans->data;

    return 0;
}*/

// To run a test comment out the above main function and uncomment the following one//

	int main() {
	Solution myTree;
	Node* root = NULL;
	root = myTree.insert(root,4);
	root = myTree.insert(root,2);
	root = myTree.insert(root,3);
	root = myTree.insert(root,1);
	root = myTree.insert(root,7);
	root = myTree.insert(root,6);
  topView(root);
	// Node*ans = myTree.lca(root,1,7);

	// std::cout << ans->data;

	return 0;
}

<|endoftext|>


<commit_before>// MenuTools.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "MenuTools.h"
#include "Startup.h"

#include "MenuCommon/Defines.h"

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name

// Forward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	// Single instance
	Startup startup;
	if(!startup.CreateJob())
	{
		return FALSE;
	}

	// Initialize global strings
	LoadString(hInstance, BUILD(IDS_APP_TITLE), szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_MENUTOOLS, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	HACCEL hAccelTable;
	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MENUTOOLS));

	// Main message loop:
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}

//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MENUTOOLS));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_MENUTOOLS);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: Add any drawing code here...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}
<commit_msg>Hide the main application window and removed unnecessary code.<commit_after>// MenuTools.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "MenuTools.h"
#include "Startup.h"

#include "MenuCommon/Defines.h"

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;								// current instance
HWND hWnd;										// current window handle
TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name

// Forward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	// Single instance
	Startup startup;
	if(!startup.CreateJob())
	{
		return FALSE;
	}

	// Initialize global strings
	LoadString(hInstance, BUILD(IDS_APP_TITLE), szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_MENUTOOLS, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, SW_HIDE))
	{
		return FALSE;
	}

	// Main message loop:
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int) msg.wParam;
}

//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MENUTOOLS));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, 0, 0, NULL, NULL, NULL, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_DESTROY	- post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;

	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}
<|endoftext|>