<commit_before>/****************************************************************************
 *
 *   Copyright (c) 2019 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

#include "logged_topics.h"
#include "messages.h"

#include <px4_platform_common/log.h>
#include <px4_platform_common/px4_config.h>
#include <uORB/uORBTopics.h>

#include <string.h>

using namespace px4::logger;

void LoggedTopics::add_default_topics()
{
	add_topic("actuator_controls_0", 100);
	add_topic("actuator_controls_1", 100);
	add_topic("airspeed", 200);
	add_topic("airspeed_validated", 200);
	add_topic("camera_capture");
	add_topic("camera_trigger");
	add_topic("camera_trigger_secondary");
	add_topic("cellular_status", 200);
	add_topic("cpuload");
	add_topic("estimator_innovations", 200);
	add_topic("estimator_innovation_variances", 200);
	add_topic("estimator_innovation_test_ratios", 200);
	add_topic("ekf_gps_drift");
	add_topic("esc_status", 250);
	add_topic("estimator_status", 200);
	add_topic("home_position");
	add_topic("input_rc", 200);
	add_topic("manual_control_setpoint", 200);
	add_topic("mission");
	add_topic("mission_result");
	add_topic("optical_flow", 50);
	add_topic("position_controller_status", 500);
	add_topic("position_setpoint_triplet", 200);
	add_topic("radio_status");
	add_topic("rate_ctrl_status", 200);
	add_topic("sensor_combined", 100);
	add_topic("sensor_preflight", 200);
	add_topic("system_power", 500);
	add_topic("tecs_status", 200);
	add_topic("trajectory_setpoint", 200);
	add_topic("vehicle_air_data", 200);
	add_topic("vehicle_angular_velocity", 20);
	add_topic("vehicle_attitude", 50);
	add_topic("vehicle_attitude_setpoint", 100);
	add_topic("vehicle_command");
	add_topic("vehicle_global_position", 200);
	add_topic("vehicle_land_detected");
	add_topic("vehicle_local_position", 100);
	add_topic("vehicle_local_position_setpoint", 100);
	add_topic("vehicle_magnetometer", 200);
	add_topic("vehicle_rates_setpoint", 20);
	add_topic("vehicle_status", 200);
	add_topic("vehicle_status_flags");
	add_topic("vtol_vehicle_status", 200);

	add_topic_multi("actuator_outputs", 100);
	add_topic_multi("battery_status", 500);
	add_topic_multi("distance_sensor", 100);
	add_topic_multi("sensor_accel_status", 1000);
	add_topic_multi("sensor_gyro_status", 1000);
	add_topic_multi("telemetry_status");
	add_topic_multi("vehicle_gps_position");
	add_topic_multi("wind_estimate", 200);

#ifdef CONFIG_ARCH_BOARD_PX4_SITL

	add_topic("actuator_controls_virtual_fw");
	add_topic("actuator_controls_virtual_mc");
	add_topic("fw_virtual_attitude_setpoint");
	add_topic("mc_virtual_attitude_setpoint");
	add_topic("offboard_control_mode");
	add_topic("position_controller_status");
	add_topic("time_offset");
	add_topic("vehicle_angular_velocity", 10);
	add_topic("vehicle_attitude_groundtruth", 10);
	add_topic("vehicle_global_position_groundtruth", 100);
	add_topic("vehicle_local_position_groundtruth", 100);
	add_topic("vehicle_roi");

	add_topic_multi("multirotor_motor_limits");

#endif /* CONFIG_ARCH_BOARD_PX4_SITL */
}

void LoggedTopics::add_high_rate_topics()
{
	// maximum rate to analyze fast maneuvers (e.g. for racing)
	add_topic("actuator_controls_0");
	add_topic("actuator_outputs");
	add_topic("manual_control_setpoint");
	add_topic("rate_ctrl_status");
	add_topic("sensor_combined");
	add_topic("vehicle_angular_velocity");
	add_topic("vehicle_attitude");
	add_topic("vehicle_attitude_setpoint");
	add_topic("vehicle_rates_setpoint");
}

void LoggedTopics::add_debug_topics()
{
	add_topic("debug_array");
	add_topic("debug_key_value");
	add_topic("debug_value");
	add_topic("debug_vect");
}

void LoggedTopics::add_estimator_replay_topics()
{
	// for estimator replay (need to be at full rate)
	add_topic("ekf2_timestamps");
	add_topic("ekf_gps_position");

	// current EKF2 subscriptions
	add_topic("airspeed");
	add_topic("optical_flow");
	add_topic("sensor_combined");
	add_topic("sensor_selection");
	add_topic("vehicle_air_data");
	add_topic("vehicle_land_detected");
	add_topic("vehicle_magnetometer");
	add_topic("vehicle_status");
	add_topic("vehicle_visual_odometry");
	add_topic("vehicle_visual_odometry_aligned");
	add_topic_multi("distance_sensor");
	add_topic_multi("vehicle_gps_position");
}

void LoggedTopics::add_thermal_calibration_topics()
{
	add_topic_multi("sensor_accel", 100);
	add_topic_multi("sensor_baro", 100);
	add_topic_multi("sensor_gyro", 100);
}

void LoggedTopics::add_sensor_comparison_topics()
{
	add_topic_multi("sensor_accel", 100);
	add_topic_multi("sensor_baro", 100);
	add_topic_multi("sensor_gyro", 100);
	add_topic_multi("sensor_mag", 100);
}

void LoggedTopics::add_vision_and_avoidance_topics()
{
	add_topic("collision_constraints");
	add_topic("obstacle_distance_fused");
	add_topic("onboard_computer_status", 200);
	add_topic("vehicle_mocap_odometry", 30);
	add_topic("vehicle_trajectory_waypoint", 200);
	add_topic("vehicle_trajectory_waypoint_desired", 200);
	add_topic("vehicle_visual_odometry", 30);
}

void LoggedTopics::add_system_identification_topics()
{
	// for system id need to log imu and controls at full rate
	add_topic("actuator_controls_0");
	add_topic("actuator_controls_1");
	add_topic("sensor_combined");
}

int LoggedTopics::add_topics_from_file(const char *fname)
{
	int ntopics = 0;

	/* open the topic list file */
	FILE *fp = fopen(fname, "r");

	if (fp == nullptr) {
		return -1;
	}

	/* call add_topic for each topic line in the file */
	for (;;) {
		/* get a line, bail on error/EOF */
		char line[80];
		line[0] = '\0';

		if (fgets(line, sizeof(line), fp) == nullptr) {
			break;
		}

		/* skip comment lines */
		if ((strlen(line) < 2) || (line[0] == '#')) {
			continue;
		}

		// read line with format: <topic_name>[, <interval>]
		char topic_name[80];
		uint32_t interval_ms = 0;
		int nfields = sscanf(line, "%s %u", topic_name, &interval_ms);

		if (nfields > 0) {
			int name_len = strlen(topic_name);

			if (name_len > 0 && topic_name[name_len - 1] == ',') {
				topic_name[name_len - 1] = '\0';
			}

			/* add topic with specified interval_ms */
			if (add_topic(topic_name, interval_ms)) {
				ntopics++;

			} else {
				PX4_ERR("Failed to add topic %s", topic_name);
			}
		}
	}

	fclose(fp);
	return ntopics;
}

void LoggedTopics::initialize_mission_topics(MissionLogType mission_log_type)
{
	if (mission_log_type == MissionLogType::Complete) {
		add_mission_topic("camera_capture");
		add_mission_topic("mission_result");
		add_mission_topic("vehicle_global_position", 1000);
		add_mission_topic("vehicle_status", 1000);

	} else if (mission_log_type == MissionLogType::Geotagging) {
		add_mission_topic("camera_capture");
	}
}

void LoggedTopics::add_mission_topic(const char *name, uint16_t interval_ms)
{
	if (add_topic(name, interval_ms)) {
		++_num_mission_subs;
	}
}

bool LoggedTopics::add_topic(const orb_metadata *topic, uint16_t interval_ms, uint8_t instance)
{
	size_t fields_len = strlen(topic->o_fields) + strlen(topic->o_name) + 1; //1 for ':'

	if (fields_len > sizeof(ulog_message_format_s::format)) {
		PX4_WARN("skip topic %s, format string is too large: %zu (max is %zu)", topic->o_name, fields_len,
			 sizeof(ulog_message_format_s::format));

		return false;
	}

	if (_subscriptions.count >= MAX_TOPICS_NUM) {
		PX4_WARN("Too many subscriptions, failed to add: %s %d", topic->o_name, instance);
		return false;
	}

	RequestedSubscription &sub = _subscriptions.sub[_subscriptions.count++];
	sub.topic = topic;
	sub.interval_ms = interval_ms;
	sub.instance = instance;
	return true;
}

bool LoggedTopics::add_topic(const char *name, uint16_t interval_ms, uint8_t instance)
{
	const orb_metadata *const *topics = orb_get_topics();
	bool success = false;

	for (size_t i = 0; i < orb_topics_count(); i++) {
		if (strcmp(name, topics[i]->o_name) == 0) {
			bool already_added = false;

			// check if already added: if so, only update the interval
			for (int j = 0; j < _subscriptions.count; ++j) {
				if (_subscriptions.sub[j].topic == topics[i] &&
				    _subscriptions.sub[j].instance == instance) {

					PX4_DEBUG("logging topic %s(%d), interval: %i, already added, only setting interval",
						  topics[i]->o_name, instance, interval_ms);

					_subscriptions.sub[j].interval_ms = interval_ms;
					success = true;
					already_added = true;
					break;
				}
			}

			if (!already_added) {
				success = add_topic(topics[i], interval_ms, instance);
				PX4_DEBUG("logging topic: %s(%d), interval: %i", topics[i]->o_name, instance, interval_ms);
				break;
			}
		}
	}

	return success;
}

bool LoggedTopics::add_topic_multi(const char *name, uint16_t interval_ms)
{
	// add all possible instances
	for (uint8_t instance = 0; instance < ORB_MULTI_MAX_INSTANCES; instance++) {
		add_topic(name, interval_ms, instance);
	}

	return true;
}

bool LoggedTopics::initialize_logged_topics(SDLogProfileMask profile)
{
	int ntopics = add_topics_from_file(PX4_STORAGEDIR "/etc/logging/logger_topics.txt");

	if (ntopics > 0) {
		PX4_INFO("logging %d topics from logger_topics.txt", ntopics);

	} else {
		initialize_configured_topics(profile);
	}

	return true;
}

void LoggedTopics::initialize_configured_topics(SDLogProfileMask profile)
{
	// load appropriate topics for profile
	// the order matters: if several profiles add the same topic, the logging rate of the last one will be used
	if (profile & SDLogProfileMask::DEFAULT) {
		add_default_topics();
	}

	if (profile & SDLogProfileMask::ESTIMATOR_REPLAY) {
		add_estimator_replay_topics();
	}

	if (profile & SDLogProfileMask::THERMAL_CALIBRATION) {
		add_thermal_calibration_topics();
	}

	if (profile & SDLogProfileMask::SYSTEM_IDENTIFICATION) {
		add_system_identification_topics();
	}

	if (profile & SDLogProfileMask::HIGH_RATE) {
		add_high_rate_topics();
	}

	if (profile & SDLogProfileMask::DEBUG_TOPICS) {
		add_debug_topics();
	}

	if (profile & SDLogProfileMask::SENSOR_COMPARISON) {
		add_sensor_comparison_topics();
	}

	if (profile & SDLogProfileMask::VISION_AND_AVOIDANCE) {
		add_vision_and_avoidance_topics();
	}
}

<commit_msg>logger: log all raw sensor data at a minimal rate<commit_after>/****************************************************************************
 *
 *   Copyright (c) 2019 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

#include "logged_topics.h"
#include "messages.h"

#include <px4_platform_common/log.h>
#include <px4_platform_common/px4_config.h>
#include <uORB/uORBTopics.h>

#include <string.h>

using namespace px4::logger;

void LoggedTopics::add_default_topics()
{
	add_topic("actuator_controls_0", 100);
	add_topic("actuator_controls_1", 100);
	add_topic("airspeed", 1000);
	add_topic("airspeed_validated", 1000);
	add_topic("camera_capture");
	add_topic("camera_trigger");
	add_topic("camera_trigger_secondary");
	add_topic("cellular_status", 200);
	add_topic("cpuload");
	add_topic("ekf_gps_drift");
	add_topic("esc_status", 250);
	add_topic("estimator_innovation_test_ratios", 200);
	add_topic("estimator_innovation_variances", 200);
	add_topic("estimator_innovations", 200);
	add_topic("estimator_status", 200);
	add_topic("home_position");
	add_topic("input_rc", 200);
	add_topic("manual_control_setpoint", 200);
	add_topic("mission");
	add_topic("mission_result");
	add_topic("offboard_control_mode", 1000);
	add_topic("position_controller_status", 500);
	add_topic("position_setpoint_triplet", 200);
	add_topic("radio_status");
	add_topic("rate_ctrl_status", 200);
	add_topic("sensor_combined", 100);
	add_topic("sensor_correction", 1000);
	add_topic("sensor_preflight", 200);
	add_topic("sensor_selection");
	add_topic("system_power", 500);
	add_topic("tecs_status", 200);
	add_topic("trajectory_setpoint", 200);
	add_topic("vehicle_air_data", 200);
	add_topic("vehicle_angular_velocity", 20);
	add_topic("vehicle_attitude", 50);
	add_topic("vehicle_attitude_setpoint", 100);
	add_topic("vehicle_command");
	add_topic("vehicle_global_position", 200);
	add_topic("vehicle_land_detected");
	add_topic("vehicle_local_position", 100);
	add_topic("vehicle_local_position_setpoint", 100);
	add_topic("vehicle_magnetometer", 200);
	add_topic("vehicle_rates_setpoint", 20);
	add_topic("vehicle_roi", 1000);
	add_topic("vehicle_status", 200);
	add_topic("vehicle_status_flags");
	add_topic("vtol_vehicle_status", 200);

	// multi topics
	add_topic_multi("actuator_outputs", 100);
	add_topic_multi("multirotor_motor_limits", 1000);
	add_topic_multi("telemetry_status", 1000);
	add_topic_multi("wind_estimate", 1000);

	// log all raw sensors at minimal rate (1 Hz)
	add_topic_multi("battery_status", 1000);
	add_topic_multi("differential_pressure", 1000);
	add_topic_multi("distance_sensor", 1000);
	add_topic_multi("optical_flow", 1000);
	add_topic_multi("sensor_accel", 1000);
	add_topic_multi("sensor_accel_status", 1000);
	add_topic_multi("sensor_baro", 1000);
	add_topic_multi("sensor_gyro", 1000);
	add_topic_multi("sensor_gyro_status", 1000);
	add_topic_multi("sensor_mag", 1000);
	add_topic_multi("vehicle_gps_position", 1000);

#ifdef CONFIG_ARCH_BOARD_PX4_SITL
	add_topic("actuator_controls_virtual_fw");
	add_topic("actuator_controls_virtual_mc");
	add_topic("fw_virtual_attitude_setpoint");
	add_topic("mc_virtual_attitude_setpoint");
	add_topic("time_offset");
	add_topic("vehicle_angular_velocity", 10);
	add_topic("vehicle_attitude_groundtruth", 10);
	add_topic("vehicle_global_position_groundtruth", 100);
	add_topic("vehicle_local_position_groundtruth", 100);
#endif /* CONFIG_ARCH_BOARD_PX4_SITL */
}

void LoggedTopics::add_high_rate_topics()
{
	// maximum rate to analyze fast maneuvers (e.g. for racing)
	add_topic("actuator_controls_0");
	add_topic("actuator_outputs");
	add_topic("manual_control_setpoint");
	add_topic("rate_ctrl_status");
	add_topic("sensor_combined");
	add_topic("vehicle_angular_velocity");
	add_topic("vehicle_attitude");
	add_topic("vehicle_attitude_setpoint");
	add_topic("vehicle_rates_setpoint");
}

void LoggedTopics::add_debug_topics()
{
	add_topic("debug_array");
	add_topic("debug_key_value");
	add_topic("debug_value");
	add_topic("debug_vect");
}

void LoggedTopics::add_estimator_replay_topics()
{
	// for estimator replay (need to be at full rate)
	add_topic("ekf2_timestamps");
	add_topic("ekf_gps_position");

	// current EKF2 subscriptions
	add_topic("airspeed");
	add_topic("optical_flow");
	add_topic("sensor_combined");
	add_topic("sensor_selection");
	add_topic("vehicle_air_data");
	add_topic("vehicle_land_detected");
	add_topic("vehicle_magnetometer");
	add_topic("vehicle_status");
	add_topic("vehicle_visual_odometry");
	add_topic("vehicle_visual_odometry_aligned");
	add_topic_multi("distance_sensor");
	add_topic_multi("vehicle_gps_position");
}

void LoggedTopics::add_thermal_calibration_topics()
{
	add_topic_multi("sensor_accel", 100);
	add_topic_multi("sensor_baro", 100);
	add_topic_multi("sensor_gyro", 100);
}

void LoggedTopics::add_sensor_comparison_topics()
{
	add_topic_multi("sensor_accel", 100);
	add_topic_multi("sensor_baro", 100);
	add_topic_multi("sensor_gyro", 100);
	add_topic_multi("sensor_mag", 100);
}

void LoggedTopics::add_vision_and_avoidance_topics()
{
	add_topic("collision_constraints");
	add_topic("obstacle_distance_fused");
	add_topic("onboard_computer_status", 200);
	add_topic("vehicle_mocap_odometry", 30);
	add_topic("vehicle_trajectory_waypoint", 200);
	add_topic("vehicle_trajectory_waypoint_desired", 200);
	add_topic("vehicle_visual_odometry", 30);
}

void LoggedTopics::add_system_identification_topics()
{
	// for system id need to log imu and controls at full rate
	add_topic("actuator_controls_0");
	add_topic("actuator_controls_1");
	add_topic("sensor_combined");
}

int LoggedTopics::add_topics_from_file(const char *fname)
{
	int ntopics = 0;

	/* open the topic list file */
	FILE *fp = fopen(fname, "r");

	if (fp == nullptr) {
		return -1;
	}

	/* call add_topic for each topic line in the file */
	for (;;) {
		/* get a line, bail on error/EOF */
		char line[80];
		line[0] = '\0';

		if (fgets(line, sizeof(line), fp) == nullptr) {
			break;
		}

		/* skip comment lines */
		if ((strlen(line) < 2) || (line[0] == '#')) {
			continue;
		}

		// read line with format: <topic_name>[, <interval>]
		char topic_name[80];
		uint32_t interval_ms = 0;
		int nfields = sscanf(line, "%s %u", topic_name, &interval_ms);

		if (nfields > 0) {
			int name_len = strlen(topic_name);

			if (name_len > 0 && topic_name[name_len - 1] == ',') {
				topic_name[name_len - 1] = '\0';
			}

			/* add topic with specified interval_ms */
			if (add_topic(topic_name, interval_ms)) {
				ntopics++;

			} else {
				PX4_ERR("Failed to add topic %s", topic_name);
			}
		}
	}

	fclose(fp);
	return ntopics;
}

void LoggedTopics::initialize_mission_topics(MissionLogType mission_log_type)
{
	if (mission_log_type == MissionLogType::Complete) {
		add_mission_topic("camera_capture");
		add_mission_topic("mission_result");
		add_mission_topic("vehicle_global_position", 1000);
		add_mission_topic("vehicle_status", 1000);

	} else if (mission_log_type == MissionLogType::Geotagging) {
		add_mission_topic("camera_capture");
	}
}

void LoggedTopics::add_mission_topic(const char *name, uint16_t interval_ms)
{
	if (add_topic(name, interval_ms)) {
		++_num_mission_subs;
	}
}

bool LoggedTopics::add_topic(const orb_metadata *topic, uint16_t interval_ms, uint8_t instance)
{
	size_t fields_len = strlen(topic->o_fields) + strlen(topic->o_name) + 1; //1 for ':'

	if (fields_len > sizeof(ulog_message_format_s::format)) {
		PX4_WARN("skip topic %s, format string is too large: %zu (max is %zu)", topic->o_name, fields_len,
			 sizeof(ulog_message_format_s::format));

		return false;
	}

	if (_subscriptions.count >= MAX_TOPICS_NUM) {
		PX4_WARN("Too many subscriptions, failed to add: %s %d", topic->o_name, instance);
		return false;
	}

	RequestedSubscription &sub = _subscriptions.sub[_subscriptions.count++];
	sub.topic = topic;
	sub.interval_ms = interval_ms;
	sub.instance = instance;
	return true;
}

bool LoggedTopics::add_topic(const char *name, uint16_t interval_ms, uint8_t instance)
{
	const orb_metadata *const *topics = orb_get_topics();
	bool success = false;

	for (size_t i = 0; i < orb_topics_count(); i++) {
		if (strcmp(name, topics[i]->o_name) == 0) {
			bool already_added = false;

			// check if already added: if so, only update the interval
			for (int j = 0; j < _subscriptions.count; ++j) {
				if (_subscriptions.sub[j].topic == topics[i] &&
				    _subscriptions.sub[j].instance == instance) {

					PX4_DEBUG("logging topic %s(%d), interval: %i, already added, only setting interval",
						  topics[i]->o_name, instance, interval_ms);

					_subscriptions.sub[j].interval_ms = interval_ms;
					success = true;
					already_added = true;
					break;
				}
			}

			if (!already_added) {
				success = add_topic(topics[i], interval_ms, instance);
				PX4_DEBUG("logging topic: %s(%d), interval: %i", topics[i]->o_name, instance, interval_ms);
				break;
			}
		}
	}

	return success;
}

bool LoggedTopics::add_topic_multi(const char *name, uint16_t interval_ms)
{
	// add all possible instances
	for (uint8_t instance = 0; instance < ORB_MULTI_MAX_INSTANCES; instance++) {
		add_topic(name, interval_ms, instance);
	}

	return true;
}

bool LoggedTopics::initialize_logged_topics(SDLogProfileMask profile)
{
	int ntopics = add_topics_from_file(PX4_STORAGEDIR "/etc/logging/logger_topics.txt");

	if (ntopics > 0) {
		PX4_INFO("logging %d topics from logger_topics.txt", ntopics);

	} else {
		initialize_configured_topics(profile);
	}

	return true;
}

void LoggedTopics::initialize_configured_topics(SDLogProfileMask profile)
{
	// load appropriate topics for profile
	// the order matters: if several profiles add the same topic, the logging rate of the last one will be used
	if (profile & SDLogProfileMask::DEFAULT) {
		add_default_topics();
	}

	if (profile & SDLogProfileMask::ESTIMATOR_REPLAY) {
		add_estimator_replay_topics();
	}

	if (profile & SDLogProfileMask::THERMAL_CALIBRATION) {
		add_thermal_calibration_topics();
	}

	if (profile & SDLogProfileMask::SYSTEM_IDENTIFICATION) {
		add_system_identification_topics();
	}

	if (profile & SDLogProfileMask::HIGH_RATE) {
		add_high_rate_topics();
	}

	if (profile & SDLogProfileMask::DEBUG_TOPICS) {
		add_debug_topics();
	}

	if (profile & SDLogProfileMask::SENSOR_COMPARISON) {
		add_sensor_comparison_topics();
	}

	if (profile & SDLogProfileMask::VISION_AND_AVOIDANCE) {
		add_vision_and_avoidance_topics();
	}
}

<|endoftext|>


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

namespace {

// Returns true if a camera path is currently running, and false otherwise.
[[codegen::luawrap]] bool isFlying() {
    using namespace openspace;
    bool hasFinished = global::navigationHandler->pathNavigator().hasFinished();
    return hasFinished;
}

// Continue playing a paused camera path.
[[codegen::luawrap]] void continuePath() {
    openspace::global::navigationHandler->pathNavigator().continuePath();
}

// Pause a playing camera path.
[[codegen::luawrap]] void pausePath() {
    openspace::global::navigationHandler->pathNavigator().pausePath();
}

// Stops a path, if one is being played.
[[codegen::luawrap]] void stopPath() {
    openspace::global::navigationHandler->pathNavigator().abortPath();
}

/**
 * Move the camera to the node with the specified identifier. The optional double
 * specifies the duration of the motion, in seconds. If the optional bool is set to true
 * the target up vector for camera is set based on the target node. Either of the optional
 * parameters can be left out.
 */
[[codegen::luawrap]] void flyTo(std::string nodeIdentifier,
                      std::optional<std::variant<bool, double>> useUpFromTargetOrDuration,
                                                           std::optional<double> duration)
{
    using namespace openspace;
    if (useUpFromTargetOrDuration.has_value() &&
        std::holds_alternative<double>(*useUpFromTargetOrDuration) &&
        duration.has_value())
    {
        throw ghoul::lua::LuaError("Duration cannot be specified twice");
    }

    if (!sceneGraphNode(nodeIdentifier)) {
        throw ghoul::lua::LuaError("Unknown node name: " + nodeIdentifier);
    }

    ghoul::Dictionary insDict;
    insDict.setValue("TargetType", std::string("Node"));
    insDict.setValue("Target", nodeIdentifier);
    if (useUpFromTargetOrDuration.has_value()) {
        if (std::holds_alternative<bool>(*useUpFromTargetOrDuration)) {
            insDict.setValue(
                "UseTargetUpDirection",
                std::get<bool>(*useUpFromTargetOrDuration)
            );
        }
        else {
            double d = std::get<double>(*useUpFromTargetOrDuration);
            if (d <= 0.0) {
                throw ghoul::lua::LuaError("Duration must be larger than zero");
            }
            insDict.setValue("Duration", d);
        }
    }
    if (duration.has_value()) {
        double d = *duration;
        if (d <= 0.0) {
            throw ghoul::lua::LuaError("Duration must be larger than zero");
        }
        insDict.setValue("Duration", d);
    }

    global::navigationHandler->pathNavigator().createPath(insDict);

    if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
        global::navigationHandler->pathNavigator().startPath();
    }
}

/**
 * Move the camera to the node with the specified identifier. The second argument is the
 * desired target height above the target node's bounding sphere, in meters. The optional
 * double specifies the duration of the motion, in seconds. If the optional bool is set to
 * true, the target up vector for camera is set based on the target node. Either of the
 * optional parameters can be left out.
 */
[[codegen::luawrap]] void flyToHeight(std::string nodeIdentifier, double height,
                      std::optional<std::variant<bool, double>> useUpFromTargetOrDuration,
                                                           std::optional<double> duration)
{
    using namespace openspace;
    if (!sceneGraphNode(nodeIdentifier)) {
        throw ghoul::lua::LuaError("Unknown node name: " + nodeIdentifier);
    }

    ghoul::Dictionary insDict;
    insDict.setValue("TargetType", std::string("Node"));
    insDict.setValue("Target", nodeIdentifier);
    insDict.setValue("Height", height);
    if (useUpFromTargetOrDuration.has_value()) {
        if (std::holds_alternative<bool>(*useUpFromTargetOrDuration)) {
            insDict.setValue(
                "UseTargetUpDirection",
                std::get<bool>(*useUpFromTargetOrDuration)
            );
        }
        else {
            double d = std::get<double>(*useUpFromTargetOrDuration);
            if (d <= 0.0) {
                throw ghoul::lua::LuaError("Duration must be larger than zero");
            }
            insDict.setValue("Duration", d);
        }
    }
    if (duration.has_value()) {
        double d = *duration;
        if (d <= 0.0) {
            throw ghoul::lua::LuaError("Duration must be larger than zero");
        }
        insDict.setValue("Duration", d);
    }

    global::navigationHandler->pathNavigator().createPath(insDict);

    if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
        global::navigationHandler->pathNavigator().startPath();
    }
}

/**
 * Create a path to the navigation state described by the input table. The optional
 * double specifies the target duration of the motion, in seconds. Note that roll must be
 * included for the target up direction to be taken into account.
 */
[[codegen::luawrap]] void flyToNavigationState(ghoul::Dictionary navigationState,
                                               std::optional<double> duration)
{
    using namespace openspace;
    try {
        documentation::testSpecificationAndThrow(
            interaction::NavigationState::Documentation(),
            navigationState,
            "NavigationState"
        );
    }
    catch (const documentation::SpecificationError& e) {
        LERRORC("flyToNavigationState", ghoul::to_string(e.result));
        throw ghoul::lua::LuaError(fmt::format("Unable to create a path: {}", e.what()));
    }

    ghoul::Dictionary instruction;
    instruction.setValue("TargetType", std::string("NavigationState"));
    instruction.setValue("NavigationState", navigationState);

    if (duration.has_value()) {
        double d = *duration;
        if (d <= 0.0) {
            throw ghoul::lua::LuaError("Duration must be larger than zero");
        }
        instruction.setValue("Duration", d);
    }

    global::navigationHandler->pathNavigator().createPath(instruction);

    if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
        global::navigationHandler->pathNavigator().startPath();
    }
}

/**
 * Zoom linearly to the current focus node, using the default distance. The optional input
 * parameter specifies the duration for the motion, in seconds.
 */
[[codegen::luawrap]] void zoomToFocus(std::optional<double> duration) {
    using namespace openspace;
    const SceneGraphNode* node = global::navigationHandler->anchorNode();
    if (!node) {
        throw ghoul::lua::LuaError("Could not determine current focus node");
    }

    ghoul::Dictionary insDict;
    insDict.setValue("TargetType", std::string("Node"));
    insDict.setValue("Target", node->identifier());
    insDict.setValue("PathType", std::string("Linear"));

    if (duration.has_value()) {
        double d = *duration;
        if (d <= 0.0) {
            throw ghoul::lua::LuaError("Duration must be larger than zero");
        }
        insDict.setValue("Duration", d);
    }

    global::navigationHandler->pathNavigator().createPath(insDict);

    if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
        global::navigationHandler->pathNavigator().startPath();
    }
}

/**
 * Fly linearly to a specific distance in relation to the focus node. The distance is
 * given in meters above the bounding sphere of the current focus node. The optional input
 * parameter specifies the duration for the motion, in seconds.
 */
[[codegen::luawrap]] void zoomToDistance(double distance, std::optional<double> duration)
{
    using namespace openspace;
    if (distance <= 0.0) {
        throw ghoul::lua::LuaError("The distance must be larger than zero");
    }

    const SceneGraphNode* node = global::navigationHandler->anchorNode();
    if (!node) {
        throw ghoul::lua::LuaError("Could not determine current focus node");
    }

    ghoul::Dictionary insDict;
    insDict.setValue("TargetType", std::string("Node"));
    insDict.setValue("Target", node->identifier());
    insDict.setValue("Height", distance);
    insDict.setValue("PathType", std::string("Linear"));

    if (duration.has_value()) {
        double d = *duration;
        if (d <= 0.0) {
            throw ghoul::lua::LuaError("Duration must be larger than zero");
        }
        insDict.setValue("Duration", d);
    }

    global::navigationHandler->pathNavigator().createPath(insDict);

    if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
        global::navigationHandler->pathNavigator().startPath();
    }
}

/**
 * Fly linearly to a specific distance in relation to the focus node. The distance is
 * given as a multiple of the bounding sphere of the current focus node. That is, a value
 * of 1 will result in a position at a distance of one times the size of the bounding
 * sphere away from the object. The optional input parameter specifies the duration for
 * the motion, in seconds.
 */
[[codegen::luawrap]] void zoomToDistanceRelative(double distance,
                                                 std::optional<double> duration)
{
    using namespace openspace;
    if (distance <= 0.0) {
        throw ghoul::lua::LuaError("The distance must be larger than zero");
    }

    const SceneGraphNode* node = global::navigationHandler->anchorNode();
    if (!node) {
        throw ghoul::lua::LuaError("Could not determine current focus node");
    }

    distance *= node->boundingSphere();

    ghoul::Dictionary insDict;
    insDict.setValue("TargetType", std::string("Node"));
    insDict.setValue("Target", node->identifier());
    insDict.setValue("Height", distance);
    insDict.setValue("PathType", std::string("Linear"));

    if (duration.has_value()) {
        double d = *duration;
        if (d <= 0.0) {
            throw ghoul::lua::LuaError("Duration must be larger than zero");
        }
        insDict.setValue("Duration", d);
    }

    global::navigationHandler->pathNavigator().createPath(insDict);

    if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
        global::navigationHandler->pathNavigator().startPath();
    }
}

// Create a camera path as described by the lua table input argument.
[[codegen::luawrap]] void createPath(ghoul::Dictionary path) {
    using namespace openspace;
    global::navigationHandler->pathNavigator().createPath(path);
    if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
        global::navigationHandler->pathNavigator().startPath();
    }
}

#include "pathnavigator_lua_codegen.cpp"

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

namespace {

// Returns true if a camera path is currently running, and false otherwise.
[[codegen::luawrap]] bool isFlying() {
    using namespace openspace;
    bool hasFinished = global::navigationHandler->pathNavigator().hasFinished();
    return !hasFinished;
}

// Continue playing a paused camera path.
[[codegen::luawrap]] void continuePath() {
    openspace::global::navigationHandler->pathNavigator().continuePath();
}

// Pause a playing camera path.
[[codegen::luawrap]] void pausePath() {
    openspace::global::navigationHandler->pathNavigator().pausePath();
}

// Stops a path, if one is being played.
[[codegen::luawrap]] void stopPath() {
    openspace::global::navigationHandler->pathNavigator().abortPath();
}

/**
 * Move the camera to the node with the specified identifier. The optional double
 * specifies the duration of the motion, in seconds. If the optional bool is set to true
 * the target up vector for camera is set based on the target node. Either of the optional
 * parameters can be left out.
 */
[[codegen::luawrap]] void flyTo(std::string nodeIdentifier,
                      std::optional<std::variant<bool, double>> useUpFromTargetOrDuration,
                                                           std::optional<double> duration)
{
    using namespace openspace;
    if (useUpFromTargetOrDuration.has_value() &&
        std::holds_alternative<double>(*useUpFromTargetOrDuration) &&
        duration.has_value())
    {
        throw ghoul::lua::LuaError("Duration cannot be specified twice");
    }

    if (!sceneGraphNode(nodeIdentifier)) {
        throw ghoul::lua::LuaError("Unknown node name: " + nodeIdentifier);
    }

    ghoul::Dictionary insDict;
    insDict.setValue("TargetType", std::string("Node"));
    insDict.setValue("Target", nodeIdentifier);
    if (useUpFromTargetOrDuration.has_value()) {
        if (std::holds_alternative<bool>(*useUpFromTargetOrDuration)) {
            insDict.setValue(
                "UseTargetUpDirection",
                std::get<bool>(*useUpFromTargetOrDuration)
            );
        }
        else {
            double d = std::get<double>(*useUpFromTargetOrDuration);
            if (d <= 0.0) {
                throw ghoul::lua::LuaError("Duration must be larger than zero");
            }
            insDict.setValue("Duration", d);
        }
    }
    if (duration.has_value()) {
        double d = *duration;
        if (d <= 0.0) {
            throw ghoul::lua::LuaError("Duration must be larger than zero");
        }
        insDict.setValue("Duration", d);
    }

    global::navigationHandler->pathNavigator().createPath(insDict);

    if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
        global::navigationHandler->pathNavigator().startPath();
    }
}

/**
 * Move the camera to the node with the specified identifier. The second argument is the
 * desired target height above the target node's bounding sphere, in meters. The optional
 * double specifies the duration of the motion, in seconds. If the optional bool is set to
 * true, the target up vector for camera is set based on the target node. Either of the
 * optional parameters can be left out.
 */
[[codegen::luawrap]] void flyToHeight(std::string nodeIdentifier, double height,
                      std::optional<std::variant<bool, double>> useUpFromTargetOrDuration,
                                                           std::optional<double> duration)
{
    using namespace openspace;
    if (!sceneGraphNode(nodeIdentifier)) {
        throw ghoul::lua::LuaError("Unknown node name: " + nodeIdentifier);
    }

    ghoul::Dictionary insDict;
    insDict.setValue("TargetType", std::string("Node"));
    insDict.setValue("Target", nodeIdentifier);
    insDict.setValue("Height", height);
    if (useUpFromTargetOrDuration.has_value()) {
        if (std::holds_alternative<bool>(*useUpFromTargetOrDuration)) {
            insDict.setValue(
                "UseTargetUpDirection",
                std::get<bool>(*useUpFromTargetOrDuration)
            );
        }
        else {
            double d = std::get<double>(*useUpFromTargetOrDuration);
            if (d <= 0.0) {
                throw ghoul::lua::LuaError("Duration must be larger than zero");
            }
            insDict.setValue("Duration", d);
        }
    }
    if (duration.has_value()) {
        double d = *duration;
        if (d <= 0.0) {
            throw ghoul::lua::LuaError("Duration must be larger than zero");
        }
        insDict.setValue("Duration", d);
    }

    global::navigationHandler->pathNavigator().createPath(insDict);

    if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
        global::navigationHandler->pathNavigator().startPath();
    }
}

/**
 * Create a path to the navigation state described by the input table. The optional
 * double specifies the target duration of the motion, in seconds. Note that roll must be
 * included for the target up direction to be taken into account.
 */
[[codegen::luawrap]] void flyToNavigationState(ghoul::Dictionary navigationState,
                                               std::optional<double> duration)
{
    using namespace openspace;
    try {
        documentation::testSpecificationAndThrow(
            interaction::NavigationState::Documentation(),
            navigationState,
            "NavigationState"
        );
    }
    catch (const documentation::SpecificationError& e) {
        LERRORC("flyToNavigationState", ghoul::to_string(e.result));
        throw ghoul::lua::LuaError(fmt::format("Unable to create a path: {}", e.what()));
    }

    ghoul::Dictionary instruction;
    instruction.setValue("TargetType", std::string("NavigationState"));
    instruction.setValue("NavigationState", navigationState);

    if (duration.has_value()) {
        double d = *duration;
        if (d <= 0.0) {
            throw ghoul::lua::LuaError("Duration must be larger than zero");
        }
        instruction.setValue("Duration", d);
    }

    global::navigationHandler->pathNavigator().createPath(instruction);

    if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
        global::navigationHandler->pathNavigator().startPath();
    }
}

/**
 * Zoom linearly to the current focus node, using the default distance. The optional input
 * parameter specifies the duration for the motion, in seconds.
 */
[[codegen::luawrap]] void zoomToFocus(std::optional<double> duration) {
    using namespace openspace;
    const SceneGraphNode* node = global::navigationHandler->anchorNode();
    if (!node) {
        throw ghoul::lua::LuaError("Could not determine current focus node");
    }

    ghoul::Dictionary insDict;
    insDict.setValue("TargetType", std::string("Node"));
    insDict.setValue("Target", node->identifier());
    insDict.setValue("PathType", std::string("Linear"));

    if (duration.has_value()) {
        double d = *duration;
        if (d <= 0.0) {
            throw ghoul::lua::LuaError("Duration must be larger than zero");
        }
        insDict.setValue("Duration", d);
    }

    global::navigationHandler->pathNavigator().createPath(insDict);

    if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
        global::navigationHandler->pathNavigator().startPath();
    }
}

/**
 * Fly linearly to a specific distance in relation to the focus node. The distance is
 * given in meters above the bounding sphere of the current focus node. The optional input
 * parameter specifies the duration for the motion, in seconds.
 */
[[codegen::luawrap]] void zoomToDistance(double distance, std::optional<double> duration)
{
    using namespace openspace;
    if (distance <= 0.0) {
        throw ghoul::lua::LuaError("The distance must be larger than zero");
    }

    const SceneGraphNode* node = global::navigationHandler->anchorNode();
    if (!node) {
        throw ghoul::lua::LuaError("Could not determine current focus node");
    }

    ghoul::Dictionary insDict;
    insDict.setValue("TargetType", std::string("Node"));
    insDict.setValue("Target", node->identifier());
    insDict.setValue("Height", distance);
    insDict.setValue("PathType", std::string("Linear"));

    if (duration.has_value()) {
        double d = *duration;
        if (d <= 0.0) {
            throw ghoul::lua::LuaError("Duration must be larger than zero");
        }
        insDict.setValue("Duration", d);
    }

    global::navigationHandler->pathNavigator().createPath(insDict);

    if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
        global::navigationHandler->pathNavigator().startPath();
    }
}

/**
 * Fly linearly to a specific distance in relation to the focus node. The distance is
 * given as a multiple of the bounding sphere of the current focus node. That is, a value
 * of 1 will result in a position at a distance of one times the size of the bounding
 * sphere away from the object. The optional input parameter specifies the duration for
 * the motion, in seconds.
 */
[[codegen::luawrap]] void zoomToDistanceRelative(double distance,
                                                 std::optional<double> duration)
{
    using namespace openspace;
    if (distance <= 0.0) {
        throw ghoul::lua::LuaError("The distance must be larger than zero");
    }

    const SceneGraphNode* node = global::navigationHandler->anchorNode();
    if (!node) {
        throw ghoul::lua::LuaError("Could not determine current focus node");
    }

    distance *= node->boundingSphere();

    ghoul::Dictionary insDict;
    insDict.setValue("TargetType", std::string("Node"));
    insDict.setValue("Target", node->identifier());
    insDict.setValue("Height", distance);
    insDict.setValue("PathType", std::string("Linear"));

    if (duration.has_value()) {
        double d = *duration;
        if (d <= 0.0) {
            throw ghoul::lua::LuaError("Duration must be larger than zero");
        }
        insDict.setValue("Duration", d);
    }

    global::navigationHandler->pathNavigator().createPath(insDict);

    if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
        global::navigationHandler->pathNavigator().startPath();
    }
}

// Create a camera path as described by the lua table input argument.
[[codegen::luawrap]] void createPath(ghoul::Dictionary path) {
    using namespace openspace;
    global::navigationHandler->pathNavigator().createPath(path);
    if (global::navigationHandler->pathNavigator().hasCurrentPath()) {
        global::navigationHandler->pathNavigator().startPath();
    }
}

#include "pathnavigator_lua_codegen.cpp"

} // namespace
<|endoftext|>


<commit_before>#include "aquila/global.h"
#include "aquila/transform/FftFactory.h"
#include "aquila/tools/TextPlot.h"
#include <algorithm>
#include <functional>
#include <memory>

int main() {

	FILE *fp;

	const std::size_t = 64;
	// etc.

	Aquila::SignalSource cmic; // control
	Aquila::SignalSource mic0, mic1, mic2, mic3;

	// GET FILE STUFF
	cmic.SignalSource(/*double vector*/, /*sample frequency rate -- check Arduino */);
			//  ^ fp needed here.
	//

	auto fft = Aquila::FftFactory::getFft(SIZE);
		// scope resolution w/ Function? ^

	//int inverse(double amp) {
	//	return amp * -1;
	//}

	Aquila::SpectrumType cspec = fft->fft(cmic.toArray());

	// TWO WAYS (PICK ONE!)
	//std::for_each(cspec.begin(), cspec.end(), &inverse); // inverse noise spectrum.
	// ^ way 1: "for_each"
	for (double amp : cspec) {
		amp *= -1; } // <Michael-approved.
	// ^ way 2: range-based for loop
	// (does this work?)

	// SpectrumType is a vector of double-vectors.
	// why?
	// run example and print contents of an ex
	// frequency spectrum.
	// is *= -1 the best way to apply an operation
	// to all elements of a vector?

<commit_msg>updatito!<commit_after>#include "aquila/global.h"
#include "aquila/transform/FftFactory.h"
#include "aquila/tools/TextPlot.h" // probably not for the Whole thing.
#include <algorithm>
#include <functional>
#include <memory>

int main() {

	FILE *fp;

	const std::size_t = 64;
	// etc.

	Aquila::SignalSource cmic; // control
	Aquila::SignalSource mic0, mic1, mic2, mic3;

	// ASSIGN ALL READINGS TO VARS
	//this will require a review of file-io C++

	cmic.SignalSource(/*double vector*/, /*sample frequency rate -- check Arduino */);
			//  ^ fp needed here.

	auto fft = Aquila::FftFactory::getFft(SIZE);

	Aquila::SpectrumType cspec = fft->fft(cmic.toArray());

	for (/*ComplexType syntax*/ amp : cspec) {
		amp *= -1; } // except it ain't double, it's ComplexType.

	// SpectrumType is a vector of double-vectors.
	// why?
	// run example and print contents of an ex
	// frequency spectrum.
	// is *= -1 the best way to apply an operation
	// to all elements of a vector?

<|endoftext|>


<commit_before>void P010_GSLIntegrator()
{
   gPluginMgr->AddHandler("ROOT::Math::VirtualIntegrator", "GSLIntegrator", "ROOT::Math::GSLIntegrator",
      "MathMore", "GSLIntegrator(const char *, double, double, unsigned int)");
}
<commit_msg>From Lorenzo: fix for a change in GSLIntegrator constructor to use Gauss integration rule<commit_after>void P010_GSLIntegrator()
{
   gPluginMgr->AddHandler("ROOT::Math::VirtualIntegrator", "GSLIntegrator", "ROOT::Math::GSLIntegrator",
      "MathMore", "GSLIntegrator(const char *, int, double, double, unsigned int)");
}
<|endoftext|>


<commit_before>#include "Entity.h"
#include "EntityManager.h"
#include "EntityType.h"

#include "components/debug/Debug.h"

const int EntityManager::NO_ID = -1;

int EntityManager::entityComparer(const std::unique_ptr<Entity> &a, const std::unique_ptr<Entity> &b)
{
	return a->getID() < b->getID();
}

EntityManager::EntityList &EntityManager::getEntityList(EntityType entityType)
{
	const int index = static_cast<int>(entityType);
	DebugAssertIndex(this->entityLists, index);
	return this->entityLists[index];
}

const EntityManager::EntityList &EntityManager::getEntityList(EntityType entityType) const
{
	const int index = static_cast<int>(entityType);
	DebugAssertIndex(this->entityLists, index);
	return this->entityLists[index];
}

int EntityManager::getEntityInsertIndex(int id, const EntityList &entityList)
{
	DebugAssert(id != EntityManager::NO_ID);

	// Increase index until given entity ID is greater.
	int index = 0;
	for (const auto &entity : entityList)
	{
		const int currentID = entity->getID();
		DebugAssert(currentID != id);

		if (currentID < id)
		{
			index++;
		}
		else
		{
			break;
		}
	}

	return index;
}

bool EntityManager::tryGetEntityIndex(int id, const EntityList &entityList, int *outIndex)
{
	// @todo: maybe make this function a function of a new EntityGroup class, and
	// make the EntityGroup have a vector of IDs that can be binary-searched here, so
	// we can get the entity index in log(n) time.

	// Assume the list is sorted by ID, to allow for early-out.
	DebugAssert(std::is_sorted(entityList.begin(), entityList.end(),
		EntityManager::entityComparer));

	const int entityCount = static_cast<int>(entityList.size());
	for (int i = 0; i < entityCount; i++)
	{
		const std::unique_ptr<Entity> &entity = entityList[i];
		const int entityID = entity->getID();

		if (entityID == id)
		{
			*outIndex = i;
			return true;
		}
		else if (entityID > id)
		{
			break;
		}
	}

	return false;
}

bool EntityManager::tryGetEntityListIndex(int id, int *outIndex) const
{
	const int entityListCount = static_cast<int>(this->entityLists.size());

	for (int i = 0; i < entityListCount; i++)
	{
		const auto &entityList = this->entityLists[i];

		int dummy;
		if (EntityManager::tryGetEntityIndex(id, entityList, &dummy))
		{
			*outIndex = i;
			return true;
		}
	}

	return false;
}

int EntityManager::getFreeID() const
{
	// Iterate through IDs from 0 to infinity until one is available.
	int id = 0;
	while (this->get(id) == nullptr)
	{
		id++;
	}

	return id;
}

Entity *EntityManager::get(int id) const
{
	// See if the entity exists in any entity list.
	int entityListIndex;
	if (this->tryGetEntityListIndex(id, &entityListIndex))
	{
		const auto &entityList = this->entityLists[entityListIndex];

		// Get the entity's index in the entity list.
		int entityIndex;
		if (EntityManager::tryGetEntityIndex(id, entityList, &entityIndex))
		{
			return entityList[entityIndex].get();
		}
		else
		{
			// Entity not found.
			return nullptr;
		}
	}
	else
	{
		// Entity list not found.
		return nullptr;
	}
}

int EntityManager::getCount(EntityType entityType) const
{
	const EntityList &entityList = this->getEntityList(entityType);
	return static_cast<int>(entityList.size());
}

int EntityManager::getTotalCount() const
{
	int count = 0;
	for (const auto &entityList : this->entityLists)
	{
		count += static_cast<int>(entityList.size());
	}

	return count;
}

int EntityManager::getEntities(EntityType entityType, Entity **outEntities, int outSize)
{
	DebugAssert(outEntities != nullptr);
	DebugAssert(outSize >= 0);

	// Get entity list for the given entity type.
	const auto &entityList = this->getEntityList(entityType);
	const int writeCount = std::min(static_cast<int>(entityList.size()), outSize);
	for (int i = 0; i < writeCount; i++)
	{
		const std::unique_ptr<Entity> &entity = entityList[i];
		outEntities[i] = entity.get();
	}

	return writeCount;
}

int EntityManager::getTotalEntities(Entity **outEntities, int outSize)
{
	DebugAssert(outEntities != nullptr);
	DebugAssert(outSize >= 0);

	int writeIndex = 0;
	for (const auto &entityList : this->entityLists)
	{
		for (const std::unique_ptr<Entity> &entity : entityList)
		{
			if (writeIndex == outSize)
			{
				return writeIndex;
			}

			outEntities[writeIndex] = entity.get();
			writeIndex++;
		}
	}

	return writeIndex;
}

Entity *EntityManager::add(std::unique_ptr<Entity> entity)
{
	DebugAssert(entity.get() != nullptr);
	DebugAssert(entity->getID() == EntityManager::NO_ID);

	// Assign entity ID.
	entity->setID(this->getFreeID());

	// Get entity list for the entity.
	EntityList &entityList = this->getEntityList(entity->getEntityType());
	DebugAssert(std::is_sorted(entityList.begin(), entityList.end(),
		EntityManager::entityComparer));

	Entity *entityPtr = entity.get();

	// Insert the entity into the sorted list.
	const int insertIndex = EntityManager::getEntityInsertIndex(entity->getID(), entityList);
	entityList.insert(entityList.begin() + insertIndex, std::move(entity));

	return entityPtr;
}

void EntityManager::remove(int id)
{
	int entityListIndex;
	if (this->tryGetEntityListIndex(id, &entityListIndex))
	{
		auto &entityList = this->entityLists[entityListIndex];

		int entityIndex;
		if (EntityManager::tryGetEntityIndex(id, entityList, &entityIndex))
		{
			entityList.erase(entityList.begin() + entityIndex);
		}
	}
}
<commit_msg>Fixed GCC compile error.<commit_after>#include <algorithm>

#include "Entity.h"
#include "EntityManager.h"
#include "EntityType.h"

#include "components/debug/Debug.h"

const int EntityManager::NO_ID = -1;

int EntityManager::entityComparer(const std::unique_ptr<Entity> &a, const std::unique_ptr<Entity> &b)
{
	return a->getID() < b->getID();
}

EntityManager::EntityList &EntityManager::getEntityList(EntityType entityType)
{
	const int index = static_cast<int>(entityType);
	DebugAssertIndex(this->entityLists, index);
	return this->entityLists[index];
}

const EntityManager::EntityList &EntityManager::getEntityList(EntityType entityType) const
{
	const int index = static_cast<int>(entityType);
	DebugAssertIndex(this->entityLists, index);
	return this->entityLists[index];
}

int EntityManager::getEntityInsertIndex(int id, const EntityList &entityList)
{
	DebugAssert(id != EntityManager::NO_ID);

	// Increase index until given entity ID is greater.
	int index = 0;
	for (const auto &entity : entityList)
	{
		const int currentID = entity->getID();
		DebugAssert(currentID != id);

		if (currentID < id)
		{
			index++;
		}
		else
		{
			break;
		}
	}

	return index;
}

bool EntityManager::tryGetEntityIndex(int id, const EntityList &entityList, int *outIndex)
{
	// @todo: maybe make this function a function of a new EntityGroup class, and
	// make the EntityGroup have a vector of IDs that can be binary-searched here, so
	// we can get the entity index in log(n) time.

	// Assume the list is sorted by ID, to allow for early-out.
	DebugAssert(std::is_sorted(entityList.begin(), entityList.end(),
		EntityManager::entityComparer));

	const int entityCount = static_cast<int>(entityList.size());
	for (int i = 0; i < entityCount; i++)
	{
		const std::unique_ptr<Entity> &entity = entityList[i];
		const int entityID = entity->getID();

		if (entityID == id)
		{
			*outIndex = i;
			return true;
		}
		else if (entityID > id)
		{
			break;
		}
	}

	return false;
}

bool EntityManager::tryGetEntityListIndex(int id, int *outIndex) const
{
	const int entityListCount = static_cast<int>(this->entityLists.size());

	for (int i = 0; i < entityListCount; i++)
	{
		const auto &entityList = this->entityLists[i];

		int dummy;
		if (EntityManager::tryGetEntityIndex(id, entityList, &dummy))
		{
			*outIndex = i;
			return true;
		}
	}

	return false;
}

int EntityManager::getFreeID() const
{
	// Iterate through IDs from 0 to infinity until one is available.
	int id = 0;
	while (this->get(id) == nullptr)
	{
		id++;
	}

	return id;
}

Entity *EntityManager::get(int id) const
{
	// See if the entity exists in any entity list.
	int entityListIndex;
	if (this->tryGetEntityListIndex(id, &entityListIndex))
	{
		const auto &entityList = this->entityLists[entityListIndex];

		// Get the entity's index in the entity list.
		int entityIndex;
		if (EntityManager::tryGetEntityIndex(id, entityList, &entityIndex))
		{
			return entityList[entityIndex].get();
		}
		else
		{
			// Entity not found.
			return nullptr;
		}
	}
	else
	{
		// Entity list not found.
		return nullptr;
	}
}

int EntityManager::getCount(EntityType entityType) const
{
	const EntityList &entityList = this->getEntityList(entityType);
	return static_cast<int>(entityList.size());
}

int EntityManager::getTotalCount() const
{
	int count = 0;
	for (const auto &entityList : this->entityLists)
	{
		count += static_cast<int>(entityList.size());
	}

	return count;
}

int EntityManager::getEntities(EntityType entityType, Entity **outEntities, int outSize)
{
	DebugAssert(outEntities != nullptr);
	DebugAssert(outSize >= 0);

	// Get entity list for the given entity type.
	const auto &entityList = this->getEntityList(entityType);
	const int writeCount = std::min(static_cast<int>(entityList.size()), outSize);
	for (int i = 0; i < writeCount; i++)
	{
		const std::unique_ptr<Entity> &entity = entityList[i];
		outEntities[i] = entity.get();
	}

	return writeCount;
}

int EntityManager::getTotalEntities(Entity **outEntities, int outSize)
{
	DebugAssert(outEntities != nullptr);
	DebugAssert(outSize >= 0);

	int writeIndex = 0;
	for (const auto &entityList : this->entityLists)
	{
		for (const std::unique_ptr<Entity> &entity : entityList)
		{
			if (writeIndex == outSize)
			{
				return writeIndex;
			}

			outEntities[writeIndex] = entity.get();
			writeIndex++;
		}
	}

	return writeIndex;
}

Entity *EntityManager::add(std::unique_ptr<Entity> entity)
{
	DebugAssert(entity.get() != nullptr);
	DebugAssert(entity->getID() == EntityManager::NO_ID);

	// Assign entity ID.
	entity->setID(this->getFreeID());

	// Get entity list for the entity.
	EntityList &entityList = this->getEntityList(entity->getEntityType());
	DebugAssert(std::is_sorted(entityList.begin(), entityList.end(),
		EntityManager::entityComparer));

	Entity *entityPtr = entity.get();

	// Insert the entity into the sorted list.
	const int insertIndex = EntityManager::getEntityInsertIndex(entity->getID(), entityList);
	entityList.insert(entityList.begin() + insertIndex, std::move(entity));

	return entityPtr;
}

void EntityManager::remove(int id)
{
	int entityListIndex;
	if (this->tryGetEntityListIndex(id, &entityListIndex))
	{
		auto &entityList = this->entityLists[entityListIndex];

		int entityIndex;
		if (EntityManager::tryGetEntityIndex(id, entityList, &entityIndex))
		{
			entityList.erase(entityList.begin() + entityIndex);
		}
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quic/core/crypto/tls_server_connection.h"

#include "absl/strings/string_view.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"
#include "quic/core/crypto/proof_source.h"
#include "quic/platform/api/quic_flag_utils.h"
#include "quic/platform/api/quic_flags.h"

namespace quic {

TlsServerConnection::TlsServerConnection(SSL_CTX* ssl_ctx, Delegate* delegate)
    : TlsConnection(ssl_ctx, delegate->ConnectionDelegate()),
      delegate_(delegate) {}

// static
bssl::UniquePtr<SSL_CTX> TlsServerConnection::CreateSslCtx(
    ProofSource* proof_source) {
  bssl::UniquePtr<SSL_CTX> ssl_ctx =
      TlsConnection::CreateSslCtx(SSL_VERIFY_NONE);
  SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(),
                                         &TlsExtServernameCallback);
  SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), &SelectAlpnCallback, nullptr);
  // We don't actually need the TicketCrypter here, but we need to know
  // whether it's set.
  if (proof_source->GetTicketCrypter()) {
    QUIC_RESTART_FLAG_COUNT_N(quic_session_tickets_always_enabled, 1, 3);
    SSL_CTX_set_ticket_aead_method(ssl_ctx.get(),
                                   &TlsServerConnection::kSessionTicketMethod);
  } else if (!GetQuicRestartFlag(quic_session_tickets_always_enabled)) {
    QUIC_RESTART_FLAG_COUNT_N(quic_session_tickets_always_enabled, 2, 3);
    SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_NO_TICKET);
  } else {
    QUIC_RESTART_FLAG_COUNT_N(quic_session_tickets_always_enabled, 3, 3);
  }
  if (GetQuicRestartFlag(quic_enable_zero_rtt_for_tls_v2) &&
      (proof_source->GetTicketCrypter() ||
       GetQuicRestartFlag(quic_session_tickets_always_enabled))) {
    SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1);
  }
  SSL_CTX_set_select_certificate_cb(
      ssl_ctx.get(), &TlsServerConnection::EarlySelectCertCallback);
  if (GetQuicRestartFlag(quic_tls_prefer_server_cipher_and_curve_list)) {
    SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);
  }
  return ssl_ctx;
}

void TlsServerConnection::SetCertChain(
    const std::vector<CRYPTO_BUFFER*>& cert_chain) {
  SSL_set_chain_and_key(ssl(), cert_chain.data(), cert_chain.size(), nullptr,
                        &TlsServerConnection::kPrivateKeyMethod);
}

const SSL_PRIVATE_KEY_METHOD TlsServerConnection::kPrivateKeyMethod{
    &TlsServerConnection::PrivateKeySign,
    nullptr,  // decrypt
    &TlsServerConnection::PrivateKeyComplete,
};

// static
TlsServerConnection* TlsServerConnection::ConnectionFromSsl(SSL* ssl) {
  return static_cast<TlsServerConnection*>(
      TlsConnection::ConnectionFromSsl(ssl));
}

// static
ssl_select_cert_result_t TlsServerConnection::EarlySelectCertCallback(
    const SSL_CLIENT_HELLO* client_hello) {
  return ConnectionFromSsl(client_hello->ssl)
      ->delegate_->EarlySelectCertCallback(client_hello);
}

// static
int TlsServerConnection::TlsExtServernameCallback(SSL* ssl,
                                                  int* out_alert,
                                                  void* /*arg*/) {
  return ConnectionFromSsl(ssl)->delegate_->TlsExtServernameCallback(out_alert);
}

// static
int TlsServerConnection::SelectAlpnCallback(SSL* ssl,
                                            const uint8_t** out,
                                            uint8_t* out_len,
                                            const uint8_t* in,
                                            unsigned in_len,
                                            void* /*arg*/) {
  return ConnectionFromSsl(ssl)->delegate_->SelectAlpn(out, out_len, in,
                                                       in_len);
}

// static
ssl_private_key_result_t TlsServerConnection::PrivateKeySign(SSL* ssl,
                                                             uint8_t* out,
                                                             size_t* out_len,
                                                             size_t max_out,
                                                             uint16_t sig_alg,
                                                             const uint8_t* in,
                                                             size_t in_len) {
  return ConnectionFromSsl(ssl)->delegate_->PrivateKeySign(
      out, out_len, max_out, sig_alg,
      absl::string_view(reinterpret_cast<const char*>(in), in_len));
}

// static
ssl_private_key_result_t TlsServerConnection::PrivateKeyComplete(
    SSL* ssl,
    uint8_t* out,
    size_t* out_len,
    size_t max_out) {
  return ConnectionFromSsl(ssl)->delegate_->PrivateKeyComplete(out, out_len,
                                                               max_out);
}

// static
const SSL_TICKET_AEAD_METHOD TlsServerConnection::kSessionTicketMethod{
    TlsServerConnection::SessionTicketMaxOverhead,
    TlsServerConnection::SessionTicketSeal,
    TlsServerConnection::SessionTicketOpen,
};

// static
size_t TlsServerConnection::SessionTicketMaxOverhead(SSL* ssl) {
  return ConnectionFromSsl(ssl)->delegate_->SessionTicketMaxOverhead();
}

// static
int TlsServerConnection::SessionTicketSeal(SSL* ssl,
                                           uint8_t* out,
                                           size_t* out_len,
                                           size_t max_out_len,
                                           const uint8_t* in,
                                           size_t in_len) {
  return ConnectionFromSsl(ssl)->delegate_->SessionTicketSeal(
      out, out_len, max_out_len,
      absl::string_view(reinterpret_cast<const char*>(in), in_len));
}

// static
enum ssl_ticket_aead_result_t TlsServerConnection::SessionTicketOpen(
    SSL* ssl,
    uint8_t* out,
    size_t* out_len,
    size_t max_out_len,
    const uint8_t* in,
    size_t in_len) {
  return ConnectionFromSsl(ssl)->delegate_->SessionTicketOpen(
      out, out_len, max_out_len,
      absl::string_view(reinterpret_cast<const char*>(in), in_len));
}

}  // namespace quic
<commit_msg>Add a flag count for --gfe2_restart_flag_quic_tls_prefer_server_cipher_and_curve_list.<commit_after>// Copyright (c) 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quic/core/crypto/tls_server_connection.h"

#include "absl/strings/string_view.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"
#include "quic/core/crypto/proof_source.h"
#include "quic/platform/api/quic_flag_utils.h"
#include "quic/platform/api/quic_flags.h"

namespace quic {

TlsServerConnection::TlsServerConnection(SSL_CTX* ssl_ctx, Delegate* delegate)
    : TlsConnection(ssl_ctx, delegate->ConnectionDelegate()),
      delegate_(delegate) {}

// static
bssl::UniquePtr<SSL_CTX> TlsServerConnection::CreateSslCtx(
    ProofSource* proof_source) {
  bssl::UniquePtr<SSL_CTX> ssl_ctx =
      TlsConnection::CreateSslCtx(SSL_VERIFY_NONE);
  SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(),
                                         &TlsExtServernameCallback);
  SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), &SelectAlpnCallback, nullptr);
  // We don't actually need the TicketCrypter here, but we need to know
  // whether it's set.
  if (proof_source->GetTicketCrypter()) {
    QUIC_RESTART_FLAG_COUNT_N(quic_session_tickets_always_enabled, 1, 3);
    SSL_CTX_set_ticket_aead_method(ssl_ctx.get(),
                                   &TlsServerConnection::kSessionTicketMethod);
  } else if (!GetQuicRestartFlag(quic_session_tickets_always_enabled)) {
    QUIC_RESTART_FLAG_COUNT_N(quic_session_tickets_always_enabled, 2, 3);
    SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_NO_TICKET);
  } else {
    QUIC_RESTART_FLAG_COUNT_N(quic_session_tickets_always_enabled, 3, 3);
  }
  if (GetQuicRestartFlag(quic_enable_zero_rtt_for_tls_v2) &&
      (proof_source->GetTicketCrypter() ||
       GetQuicRestartFlag(quic_session_tickets_always_enabled))) {
    SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1);
  }
  SSL_CTX_set_select_certificate_cb(
      ssl_ctx.get(), &TlsServerConnection::EarlySelectCertCallback);
  if (GetQuicRestartFlag(quic_tls_prefer_server_cipher_and_curve_list)) {
    QUIC_RESTART_FLAG_COUNT(quic_tls_prefer_server_cipher_and_curve_list);
    SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);
  }
  return ssl_ctx;
}

void TlsServerConnection::SetCertChain(
    const std::vector<CRYPTO_BUFFER*>& cert_chain) {
  SSL_set_chain_and_key(ssl(), cert_chain.data(), cert_chain.size(), nullptr,
                        &TlsServerConnection::kPrivateKeyMethod);
}

const SSL_PRIVATE_KEY_METHOD TlsServerConnection::kPrivateKeyMethod{
    &TlsServerConnection::PrivateKeySign,
    nullptr,  // decrypt
    &TlsServerConnection::PrivateKeyComplete,
};

// static
TlsServerConnection* TlsServerConnection::ConnectionFromSsl(SSL* ssl) {
  return static_cast<TlsServerConnection*>(
      TlsConnection::ConnectionFromSsl(ssl));
}

// static
ssl_select_cert_result_t TlsServerConnection::EarlySelectCertCallback(
    const SSL_CLIENT_HELLO* client_hello) {
  return ConnectionFromSsl(client_hello->ssl)
      ->delegate_->EarlySelectCertCallback(client_hello);
}

// static
int TlsServerConnection::TlsExtServernameCallback(SSL* ssl,
                                                  int* out_alert,
                                                  void* /*arg*/) {
  return ConnectionFromSsl(ssl)->delegate_->TlsExtServernameCallback(out_alert);
}

// static
int TlsServerConnection::SelectAlpnCallback(SSL* ssl,
                                            const uint8_t** out,
                                            uint8_t* out_len,
                                            const uint8_t* in,
                                            unsigned in_len,
                                            void* /*arg*/) {
  return ConnectionFromSsl(ssl)->delegate_->SelectAlpn(out, out_len, in,
                                                       in_len);
}

// static
ssl_private_key_result_t TlsServerConnection::PrivateKeySign(SSL* ssl,
                                                             uint8_t* out,
                                                             size_t* out_len,
                                                             size_t max_out,
                                                             uint16_t sig_alg,
                                                             const uint8_t* in,
                                                             size_t in_len) {
  return ConnectionFromSsl(ssl)->delegate_->PrivateKeySign(
      out, out_len, max_out, sig_alg,
      absl::string_view(reinterpret_cast<const char*>(in), in_len));
}

// static
ssl_private_key_result_t TlsServerConnection::PrivateKeyComplete(
    SSL* ssl,
    uint8_t* out,
    size_t* out_len,
    size_t max_out) {
  return ConnectionFromSsl(ssl)->delegate_->PrivateKeyComplete(out, out_len,
                                                               max_out);
}

// static
const SSL_TICKET_AEAD_METHOD TlsServerConnection::kSessionTicketMethod{
    TlsServerConnection::SessionTicketMaxOverhead,
    TlsServerConnection::SessionTicketSeal,
    TlsServerConnection::SessionTicketOpen,
};

// static
size_t TlsServerConnection::SessionTicketMaxOverhead(SSL* ssl) {
  return ConnectionFromSsl(ssl)->delegate_->SessionTicketMaxOverhead();
}

// static
int TlsServerConnection::SessionTicketSeal(SSL* ssl,
                                           uint8_t* out,
                                           size_t* out_len,
                                           size_t max_out_len,
                                           const uint8_t* in,
                                           size_t in_len) {
  return ConnectionFromSsl(ssl)->delegate_->SessionTicketSeal(
      out, out_len, max_out_len,
      absl::string_view(reinterpret_cast<const char*>(in), in_len));
}

// static
enum ssl_ticket_aead_result_t TlsServerConnection::SessionTicketOpen(
    SSL* ssl,
    uint8_t* out,
    size_t* out_len,
    size_t max_out_len,
    const uint8_t* in,
    size_t in_len) {
  return ConnectionFromSsl(ssl)->delegate_->SessionTicketOpen(
      out, out_len, max_out_len,
      absl::string_view(reinterpret_cast<const char*>(in), in_len));
}

}  // namespace quic
<|endoftext|>


<commit_before>void SetupTrackCutsDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD);
void SetupPairCutsDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD);
void InitHistogramsDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD);
void InitCFDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD);

AliESDtrackCuts *SetupESDtrackCutsDieleData(Int_t cutDefinition);

TString namesDieleData=("basicQ+SPDfirst+pt>1+PID; basicQ+SPDany+pt>1+PID");

TObjArray *arrNamesDieleData=namesDieleData.Tokenize("; ");

const Int_t nDie=arrNamesDieleData->GetEntries();

AliDielectron* ConfigJpsi2ee(Int_t cutDefinition, Bool_t isAOD=kFALSE)
{
  //
  // Setup the instance of AliDielectron
  //

  // create the actual framework object
  TString name=Form("%02d",cutDefinition);
  if (cutDefinition<arrNamesDieleData->GetEntriesFast()){
    name=arrNamesDieleData->At(cutDefinition)->GetName();
  }
  AliDielectron *diele = new AliDielectron(Form("%s",name.Data()),
                             Form("Track cuts: %s",name.Data()));

  // cut setup
  SetupTrackCutsDieleData(diele, cutDefinition, isAOD);
  SetupPairCutsDieleData(diele, cutDefinition, isAOD);

  //
  // histogram setup
  // only if an AliDielectronHistos object is attached to the
  // dielelectron framework histograms will be filled
  //
  InitHistogramsDieleData(diele, cutDefinition, isAOD);

  // the last definition uses no cuts and only the QA histograms should be filled!
//   if (cutDefinition<nDie-1)
  InitCFDieleData(diele, cutDefinition, isAOD);

  AliDielectronTrackRotator *rot=new AliDielectronTrackRotator;
  rot->SetConeAnglePhi(TMath::Pi());
  rot->SetIterations(10);
  diele->SetTrackRotator(rot);
  return diele;
}

//______________________________________________________________________________________
void SetupTrackCutsDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD)
{
  //
  // Setup the track cuts
  //

  //ESD quality cuts DielectronTrackCuts
  if (!isAOD) {
    diele->GetTrackFilter().AddCuts(SetupESDtrackCutsDieleData(cutDefinition));
  } else {
    AliDielectronTrackCuts *trackCuts=new AliDielectronTrackCuts("trackCuts","trackCuts");
    if (cutDefinition==0)
      trackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kFirst);
    else if (cutDefinition==1)
      trackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
    trackCuts->SetRequireTPCRefit(kTRUE);
    trackCuts->SetRequireITSRefit(kTRUE);
    diele->GetTrackFilter().AddCuts(trackCuts);
  }

  //Pt cut ----------------------------------------------------------
  AliDielectronVarCuts *pt = new AliDielectronVarCuts("ptCut","pt cut");
  pt->AddCut(AliDielectronVarManager::kPt,1.,1e30);
  pt->AddCut(AliDielectronVarManager::kKinkIndex0,0.);

  //AOD additions since there are no AliESDtrackCuts -----------------
  //
  if (isAOD){
    // TPC #clusteres cut
    pt->AddCut(AliDielectronVarManager::kNclsTPC,70.,160.);
    pt->AddCut(AliDielectronVarManager::kEta,-0.9,0.9);
    //TODO: DCA cuts to be investigated!!!
//       pt->AddCut(AliDielectronVarManager::kImpactParXY,-1.,1.);
//       pt->AddCut(AliDielectronVarManager::kImpactParZ,-3.,3.);
  }
  diele->GetTrackFilter().AddCuts(pt);

  // PID cuts --------------------------------------------------------
  AliDielectronPID *pid = new AliDielectronPID("PID10","TPC nSigma |e|<3 + |Pi|>3 + |P|>3 + TOF nSigma |e|<3");
  pid->AddCut(AliDielectronPID::kTPC,AliPID::kElectron,-3.,3.);
  pid->AddCut(AliDielectronPID::kTPC,AliPID::kPion,-3.,3.,0.,0.,kTRUE);
  pid->AddCut(AliDielectronPID::kTPC,AliPID::kProton,-20.,3.,0.,0.,kTRUE);
  diele->GetTrackFilter().AddCuts(pid);
}

//______________________________________________________________________________________
void SetupPairCutsDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD)
{
  //
  // Setup the pair cuts
  //

  //Invariant mass and rapidity selection
  AliDielectronVarCuts *pairCut=new AliDielectronVarCuts("2<M<4+|Y|<.9","2<M<4 + |Y|<.9");
//   pairCut->AddCut(AliDielectronVarManager::kM,2.,4.);
  pairCut->AddCut(AliDielectronVarManager::kY,-0.9,0.9);
  diele->GetPairFilter().AddCuts(pairCut);
}

//______________________________________________________________________________________
AliESDtrackCuts *SetupESDtrackCutsDieleData(Int_t cutDefinition)
{
  //
  // Setup default AliESDtrackCuts
  //
  AliESDtrackCuts *esdTrackCuts = new AliESDtrackCuts;

  // basic track quality cuts  (basicQ)
  esdTrackCuts->SetMaxDCAToVertexZ(3.0);
  esdTrackCuts->SetMaxDCAToVertexXY(1.0);

  esdTrackCuts->SetEtaRange( -0.9 , 0.9 );

  esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
  esdTrackCuts->SetRequireITSRefit(kTRUE);
  esdTrackCuts->SetRequireTPCRefit(kTRUE);

  esdTrackCuts->SetPtRange(.8,1e30);

  esdTrackCuts->SetMinNClustersTPC(70);
  esdTrackCuts->SetMaxChi2PerClusterTPC(4);

  // default SPD any
  esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);

  if (cutDefinition==0)
    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kFirst);

  return esdTrackCuts;
}

//______________________________________________________________________________________
void InitHistogramsDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD)
{
  //
  // Initialise the histograms
  //

  //Setup histogram Manager
  AliDielectronHistos *histos=new AliDielectronHistos(diele->GetName(),diele->GetTitle());

  //Initialise histogram classes
  histos->SetReservedWords("Track;Pair");

  //Track classes
  //to fill also track info from 2nd event loop until 2
  for (Int_t i=0; i<2; ++i){
    histos->AddClass(Form("Track_%s",AliDielectron::TrackClassName(i)));
  }

  //Pair classes
  // to fill also mixed event histograms loop until 10
  for (Int_t i=0; i<3; ++i){
    histos->AddClass(Form("Pair_%s",AliDielectron::PairClassName(i)));
  }

  //legs from pair
  for (Int_t i=0; i<3; ++i){
    histos->AddClass(Form("Track_Legs_%s",AliDielectron::PairClassName(i)));
  }
  //track rotation
//   histos->AddClass(Form("Pair_%s",PairClassName(AliDielectron::kEv1PMRot)));
//   histos->AddClass(Form("Track_Legs_%s",PairClassName(AliDielectron::kEv1PMRot)));

  //add histograms to event class
  if (cutDefinition==0) {
    histos->AddClass("Event");
    histos->UserHistogram("Event","VtxZ","Vertex Z;Z[cm]",300,-15.,15.,AliDielectronVarManager::kZvPrim);
  }

  //add histograms to Track classes
  histos->UserHistogram("Track","Pt","Pt;Pt [GeV];#tracks",400,0,20.,AliDielectronVarManager::kPt);
  histos->UserHistogram("Track","TPCnCls","Number of Clusters TPC;TPC number clusteres;#tracks",160,-0.5,159.5,AliDielectronVarManager::kNclsTPC);

  histos->UserHistogram("Track","dXY","dXY;dXY [cm];#tracks",500,-1.,1.,AliDielectronVarManager::kImpactParXY);
  histos->UserHistogram("Track","dZ","dZ;dZ [cm];#tracks",600,-3.,3.,AliDielectronVarManager::kImpactParZ);
  histos->UserHistogram("Track","Eta_Phi","Eta Phi Map; Eta; Phi;#tracks",
                        100,-1,1,144,0,6.285,AliDielectronVarManager::kEta,AliDielectronVarManager::kPhi);

  histos->UserHistogram("Track","dEdx_P","dEdx;P [GeV];TPC signal (arb units);#tracks",
                        200,0.2,20.,100,0.,200.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTPCsignal,kTRUE);
  histos->UserHistogram("Track","TPCnSigmaEle_P","TPC number of sigmas Electrons;P [GeV];TPC number of sigmas Electrons;#tracks",
                        200,0.2,20.,100,-10.,10.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTPCnSigmaEle,kTRUE);

  //add histograms to Pair classes
  histos->UserHistogram("Pair","InvMass","Inv.Mass;Inv. Mass [GeV];#pairs",
                        201,-.01,4.01,AliDielectronVarManager::kM);
  histos->UserHistogram("Pair","Rapidity","Rapidity;Rapidity;#pairs",
                        100,-1.,1.,AliDielectronVarManager::kY);
  histos->UserHistogram("Pair","OpeningAngle","Opening angle;angle",
                        100,0.,3.15,AliDielectronVarManager::kOpeningAngle);

  diele->SetHistogramManager(histos);
}

void InitCFDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD)
{
  //
  // Setupd the CF Manager if needed
  //

  AliDielectronCF *cf=new AliDielectronCF(diele->GetName(),diele->GetTitle());

  //pair variables
  cf->AddVariable(AliDielectronVarManager::kPt,"0.0, 1.0, 2.0, 3.0, 5., 7.0, 10.0, 100.0");

  cf->AddVariable(AliDielectronVarManager::kY,"-5,-1,-0.9,-0.8,-0.7,-0.5,-0.3,0.3,0.5,0.7,0.8,0.9,1.0,5");
  cf->AddVariable(AliDielectronVarManager::kM,125,0.,125*.04); //40Mev Steps
  cf->AddVariable(AliDielectronVarManager::kPairType,"-0.5,0.5,1.5,2.5");
  cf->AddVariable(AliDielectronVarManager::kThetaHE, "-2.0, -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0, 2.0");
  cf->AddVariable(AliDielectronVarManager::kThetaCS, "-2.0, -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0, 2.0");
  //leg variables
  cf->AddVariable(AliDielectronVarManager::kPt,"0.0, 0.8, 0.9, 0.95, 1.0, 1.05, 1.1, 1.2, 100.0",kTRUE);
  cf->AddVariable(AliDielectronVarManager::kNclsTPC,"0, 70, 75, 80, 85, 90, 100, 120, 160",kTRUE);
  cf->AddVariable(AliDielectronVarManager::kEta,"-5,-1,-0.9,-0.85,-0.8,-0.75,0.75,0.8,0.85,0.9,1.0,5",kTRUE);

//   cf->AddVariable(AliDielectronVarManager::kTPCnSigmaEle,"-2.5,-2,-1.5,-1,-0.5,4.",kTRUE);
  cf->AddVariable(AliDielectronVarManager::kTPCnSigmaPio,"3.,3.5,4.,100",kTRUE);
  cf->AddVariable(AliDielectronVarManager::kTPCnSigmaPro,"3.,3.5,4.,100",kTRUE);

  //event variables
  cf->AddVariable(AliDielectronVarManager::kNaccTrcklts,"0.0, 9.0, 17.0, 25.0, 36.0, 55.0, 500.0");

  if (!isAOD){
    Bool_t hasMC=(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0);
    if (hasMC){
      cf->AddVariable(AliDielectronVarManager::kPdgCode,10000,-5000.5,4999.5,kTRUE);
      cf->AddVariable(AliDielectronVarManager::kPdgCodeMother,10000,-5000.5,4999.5,kTRUE);
      cf->AddVariable(AliDielectronVarManager::kPdgCodeGrandMother,10000,-5000.5,4999.5,kTRUE);
    }
  }
    //only in this case write MC truth info
  if (cutDefinition==0){
    cf->SetStepForMCtruth();
  }

  diele->SetCFManagerPair(cf);

}

<commit_msg>- test commit<commit_after>void SetupTrackCutsDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD);
void SetupPairCutsDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD);
void InitHistogramsDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD);
void InitCFDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD);

AliESDtrackCuts *SetupESDtrackCutsDieleData(Int_t cutDefinition);

TString namesDieleData=("basicQ+SPDfirst+pt>1+PID; basicQ+SPDany+pt>1+PID");

TObjArray *arrNamesDieleData=namesDieleData.Tokenize("; ");

const Int_t nDie=arrNamesDieleData->GetEntries();

AliDielectron* ConfigJpsi2ee(Int_t cutDefinition, Bool_t isAOD=kFALSE)
{
  //
  // Setup the instance of AliDielectron
  //

  // create the actual framework object
  TString name=Form("%02d",cutDefinition);
  if (cutDefinition<arrNamesDieleData->GetEntriesFast()){
    name=arrNamesDieleData->At(cutDefinition)->GetName();
  }
  AliDielectron *diele = new AliDielectron(Form("%s",name.Data()),
                             Form("Track cuts: %s",name.Data()));

  // cut setup
  SetupTrackCutsDieleData(diele, cutDefinition, isAOD);
  SetupPairCutsDieleData(diele, cutDefinition, isAOD);

  //
  // histogram setup
  // only if an AliDielectronHistos object is attached to the
  // dielelectron framework histograms will be filled
  //
  InitHistogramsDieleData(diele, cutDefinition, isAOD);

  // the last definition uses no cuts and only the QA histograms should be filled!
//   if (cutDefinition<nDie-1)
  InitCFDieleData(diele, cutDefinition, isAOD);

  AliDielectronTrackRotator *rot=new AliDielectronTrackRotator;
  rot->SetConeAnglePhi(TMath::Pi());
  rot->SetIterations(10);
  diele->SetTrackRotator(rot);
  return diele;
}

//______________________________________________________________________________________
void SetupTrackCutsDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD)
{
  //
  // Setup the track cuts
  //

  //ESD quality cuts DielectronTrackCuts
  if (!isAOD) {
    diele->GetTrackFilter().AddCuts(SetupESDtrackCutsDieleData(cutDefinition));
  } else {
    AliDielectronTrackCuts *trackCuts=new AliDielectronTrackCuts("trackCuts","trackCuts");
    if (cutDefinition==0)
      trackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kFirst);
    else if (cutDefinition==1)
      trackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
    trackCuts->SetRequireTPCRefit(kTRUE);
    trackCuts->SetRequireITSRefit(kTRUE);
    diele->GetTrackFilter().AddCuts(trackCuts);
  }

  //Pt cut ----------------------------------------------------------
  AliDielectronVarCuts *pt = new AliDielectronVarCuts("ptCut","pt cut");
  pt->AddCut(AliDielectronVarManager::kPt,1.,1e30);
  pt->AddCut(AliDielectronVarManager::kKinkIndex0,0.);

  //AOD additions since there are no AliESDtrackCuts -----------------
  //
  if (isAOD){
    // TPC #clusteres cut
    pt->AddCut(AliDielectronVarManager::kNclsTPC,70.,160.);
    pt->AddCut(AliDielectronVarManager::kEta,-0.9,0.9);
    //TODO: DCA cuts to be investigated!!!
//       pt->AddCut(AliDielectronVarManager::kImpactParXY,-1.,1.);
//       pt->AddCut(AliDielectronVarManager::kImpactParZ,-3.,3.);
  }
  diele->GetTrackFilter().AddCuts(pt);

  // PID cuts --------------------------------------------------------
  AliDielectronPID *pid = new AliDielectronPID("PID10","TPC nSigma |e|<3 + |Pi|>3 + |P|>3 + TOF nSigma |e|<3");
  pid->AddCut(AliDielectronPID::kTPC,AliPID::kElectron,-3.,3.);
  pid->AddCut(AliDielectronPID::kTPC,AliPID::kPion,-3.,3.,0.,0.,kTRUE);
  pid->AddCut(AliDielectronPID::kTPC,AliPID::kProton,-20.,3.,0.,0.,kTRUE);
  diele->GetTrackFilter().AddCuts(pid);
}

//______________________________________________________________________________________
void SetupPairCutsDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD)
{
  //
  // Setup the pair cuts
  //

  //Invariant mass and rapidity selection
  AliDielectronVarCuts *pairCut=new AliDielectronVarCuts("2<M<4+|Y|<.9","2<M<4 + |Y|<.9");
//   pairCut->AddCut(AliDielectronVarManager::kM,2.,4.);
  pairCut->AddCut(AliDielectronVarManager::kY,-0.9,0.9);
  diele->GetPairFilter().AddCuts(pairCut);
}

//______________________________________________________________________________________
AliESDtrackCuts *SetupESDtrackCutsDieleData(Int_t cutDefinition)
{
  //
  // Setup default AliESDtrackCuts
  //
  AliESDtrackCuts *esdTrackCuts = new AliESDtrackCuts;

  // basic track quality cuts  (basicQ)
  esdTrackCuts->SetMaxDCAToVertexZ(3.0);
  esdTrackCuts->SetMaxDCAToVertexXY(1.0);

  esdTrackCuts->SetEtaRange( -0.9 , 0.9 );

  esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
  esdTrackCuts->SetRequireITSRefit(kTRUE);
  esdTrackCuts->SetRequireTPCRefit(kTRUE);

  esdTrackCuts->SetPtRange(.8,1e30);

  esdTrackCuts->SetMinNClustersTPC(70);
  esdTrackCuts->SetMaxChi2PerClusterTPC(4);

  // default SPD any
  esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);

  if (cutDefinition==0)
    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kFirst);

  return esdTrackCuts;
}

//______________________________________________________________________________________
void InitHistogramsDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD)
{
  //
  // Initialise the histograms
  //

  //Setup histogram Manager
  AliDielectronHistos *histos=new AliDielectronHistos(diele->GetName(),diele->GetTitle());

  //Initialise histogram classes
  histos->SetReservedWords("Track;Pair");

  //Track classes
  //to fill also track info from 2nd event loop until 2
  for (Int_t i=0; i<2; ++i){
    histos->AddClass(Form("Track_%s",AliDielectron::TrackClassName(i)));
  }

  //Pair classes
  // to fill also mixed event histograms loop until 10
  for (Int_t i=0; i<3; ++i){
    histos->AddClass(Form("Pair_%s",AliDielectron::PairClassName(i)));
  }

  //legs from pair
  for (Int_t i=0; i<3; ++i){
    histos->AddClass(Form("Track_Legs_%s",AliDielectron::PairClassName(i)));
  }
  //track rotation
//   histos->AddClass(Form("Pair_%s",PairClassName(AliDielectron::kEv1PMRot)));
//   histos->AddClass(Form("Track_Legs_%s",PairClassName(AliDielectron::kEv1PMRot)));

  //add histograms to event class
  if (cutDefinition==0) {
    histos->AddClass("Event");
    histos->UserHistogram("Event","VtxZ","Vertex Z;Z[cm]",300,-15.,15.,AliDielectronVarManager::kZvPrim);
  }

  //add histograms to Track classes
  histos->UserHistogram("Track","Pt","Pt;Pt [GeV];#tracks",400,0,20.,AliDielectronVarManager::kPt);
  histos->UserHistogram("Track","TPCnCls","Number of Clusters TPC;TPC number clusteres;#tracks",160,-0.5,159.5,AliDielectronVarManager::kNclsTPC);

  histos->UserHistogram("Track","dXY","dXY;dXY [cm];#tracks",500,-1.,1.,AliDielectronVarManager::kImpactParXY);
  histos->UserHistogram("Track","dZ","dZ;dZ [cm];#tracks",600,-3.,3.,AliDielectronVarManager::kImpactParZ);
  histos->UserHistogram("Track","Eta_Phi","Eta Phi Map; Eta; Phi;#tracks",
                        100,-1,1,144,0,6.285,AliDielectronVarManager::kEta,AliDielectronVarManager::kPhi);

  histos->UserHistogram("Track","dEdx_P","dEdx;P [GeV];TPC signal (arb units);#tracks",
                        200,0.2,20.,100,0.,200.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTPCsignal,kTRUE);
  histos->UserHistogram("Track","TPCnSigmaEle_P","TPC number of sigmas Electrons;P [GeV];TPC number of sigmas Electrons;#tracks",
                        200,0.2,20.,100,-10.,10.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTPCnSigmaEle,kTRUE);

  //add histograms to Pair classes
  histos->UserHistogram("Pair","InvMass","Inv.Mass;Inv. Mass [GeV];#pairs",
                        201,-.01,4.01,AliDielectronVarManager::kM);
  histos->UserHistogram("Pair","Rapidity","Rapidity;Rapidity;#pairs",
                        100,-1.,1.,AliDielectronVarManager::kY);
  histos->UserHistogram("Pair","OpeningAngle","Opening angle;angle",
                        100,0.,3.15,AliDielectronVarManager::kOpeningAngle);

  diele->SetHistogramManager(histos);
}

void InitCFDieleData(AliDielectron *diele, Int_t cutDefinition, Bool_t isAOD)
{
  //
  // Setupd the CF Manager if needed
  //

  AliDielectronCF *cf=new AliDielectronCF(diele->GetName(),diele->GetTitle());

  //pair variables
  cf->AddVariable(AliDielectronVarManager::kPt,"0.0, 1.0, 2.0, 3.0, 5., 7.0, 10.0, 100.0");

  cf->AddVariable(AliDielectronVarManager::kY,"-5,-1,-0.9,-0.8,-0.7,-0.5,-0.3,0.3,0.5,0.7,0.8,0.9,1.0,5");
  cf->AddVariable(AliDielectronVarManager::kM,125,0.,125*.04); //40Mev Steps
  cf->AddVariable(AliDielectronVarManager::kPairType,"-0.5,0.5,1.5,2.5");
  cf->AddVariable(AliDielectronVarManager::kThetaHE, "-2.0, -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0, 2.0");
  cf->AddVariable(AliDielectronVarManager::kThetaCS, "-2.0, -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0, 2.0");
  //leg variables
  cf->AddVariable(AliDielectronVarManager::kPt,"0.0, 0.8, 0.9, 0.95, 1.0, 1.05, 1.1, 1.2, 100.0",kTRUE);
  cf->AddVariable(AliDielectronVarManager::kNclsTPC,"0, 70, 75, 80, 85, 90, 100, 120, 160",kTRUE);
  cf->AddVariable(AliDielectronVarManager::kEta,"-5,-1,-0.9,-0.85,-0.8,-0.75,0.75,0.8,0.85,0.9,1.0,5",kTRUE);

//   cf->AddVariable(AliDielectronVarManager::kTPCnSigmaEle,"-2.5,-2,-1.5,-1,-0.5,4.",kTRUE);
  cf->AddVariable(AliDielectronVarManager::kTPCnSigmaPio,"3.,3.5,4.,100",kTRUE);
  cf->AddVariable(AliDielectronVarManager::kTPCnSigmaPro,"3.,3.5,4.,100",kTRUE);

  //event variables
  cf->AddVariable(AliDielectronVarManager::kNaccTrcklts,"0.0, 9.0, 17.0, 25.0, 36.0, 55.0, 500.0");

  if (!isAOD){
    Bool_t hasMC=(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0);
    if (hasMC){
      cf->AddVariable(AliDielectronVarManager::kPdgCode,10000,-5000.5,4999.5,kTRUE);
      cf->AddVariable(AliDielectronVarManager::kPdgCodeMother,10000,-5000.5,4999.5,kTRUE);
      cf->AddVariable(AliDielectronVarManager::kPdgCodeGrandMother,10000,-5000.5,4999.5,kTRUE);
    }
  }
    //only in this case write MC truth info
  if (cutDefinition==0){
    cf->SetStepForMCtruth();
  }

  diele->SetCFManagerPair(cf);

}

<|endoftext|>