text:
//---------------------------------Spheral++----------------------------------//
// IvanoviSALEDamageModel
//
// The Ivanov damage model, hopefully close to how it's implemented in iSALE.
// This damage model is most appropriate for rocky materials.
//
// Refs:
//
// Collins, G. S., Melosh, H. J., & Ivanov, B. A. (2004). Modeling damage and deformation in impact simulations.
//   Meteoritics & Planetary Science, 39(2), 217–231. http://doi.wiley.com/10.1111/j.1945-5100.2004.tb00337.x
//
// Raducan, S. D., Davison, T. M., Luther, R., & Collins, G. S. (2019). The role of asteroid strength, porosity and
//   internal friction in impact momentum transfer. Icarus. https://doi.org/10.1016/J.ICARUS.2019.03.040
//
// Lundborg, N. (1967). The strength-size relation of granite. International Journal of Rock Mechanics and
//   Mining Sciences & Geomechanics Abstracts, 4(3):269–272.f
//
// Created by JMO, Sat Jun 26 11:35:44 PDT 2021
//----------------------------------------------------------------------------//
#include "FileIO/FileIO.hh"
#include "IvanoviSALEDamageModel.hh"
#include "TensorStrainPolicy.hh"
#include "IvanoviSALEDamagePolicy.hh"
#include "YoungsModulusPolicy.hh"
#include "LongitudinalSoundSpeedPolicy.hh"
#include "DamageGradientPolicy.hh"
#include "Strength/SolidFieldNames.hh"
#include "NodeList/SolidNodeList.hh"
#include "DataBase/DataBase.hh"
#include "DataBase/State.hh"
#include "DataBase/StateDerivatives.hh"
#include "DataBase/ReplaceState.hh"
#include "Hydro/HydroFieldNames.hh"
#include "Field/FieldList.hh"
#include "Boundary/Boundary.hh"
#include "Neighbor/Neighbor.hh"
#include "Utilities/mortonOrderIndices.hh"
#include "Utilities/allReduce.hh"
#include "Utilities/uniform_random.hh"

#include <boost/functional/hash.hpp>  // hash_combine

#include <string>
#include <vector>
#include <algorithm>
#include <limits>
using std::vector;
using std::string;
using std::pair;
using std::make_pair;
using std::cout;
using std::cerr;
using std::endl;
using std::min;
using std::max;
using std::abs;

namespace Spheral {

//------------------------------------------------------------------------------
// Constructor.
//------------------------------------------------------------------------------
template<typename Dimension>
IvanoviSALEDamageModel<Dimension>::
IvanoviSALEDamageModel(SolidNodeList<Dimension>& nodeList,
                       const TableKernel<Dimension>& W,
                       const double minPlasticFailure,
                       const double plasticFailurePressureSlope,
                       const double plasticFailurePressureOffset,
                       const double tensileFailureStress,
                       const double crackGrowthMultiplier,
                       const DamageCouplingAlgorithm damageCouplingAlgorithm,
                       const double criticalDamageThreshold,
                       const Field<Dimension, int>& mask):
  DamageModel<Dimension>(nodeList, W, crackGrowthMultiplier, damageCouplingAlgorithm),
  mEpsPfb(minPlasticFailure),
  mB(plasticFailurePressureSlope),
  mPc(plasticFailurePressureOffset),
  mTensileFailureStress(tensileFailureStress),
  mCriticalDamageThreshold(criticalDamageThreshold),
  mMask(mask),
  mYoungsModulus(SolidFieldNames::YoungsModulus, nodeList),
  mLongitudinalSoundSpeed(SolidFieldNames::longitudinalSoundSpeed, nodeList),
  mDdamageDt(IvanoviSALEDamagePolicy<Dimension>::prefix() + SolidFieldNames::scalarDamage, nodeList),
  mStrain(SolidFieldNames::strainTensor, nodeList),
  mEffectiveStrain(SolidFieldNames::effectiveStrainTensor, nodeList) {
}

//------------------------------------------------------------------------------
// Destructor.
//------------------------------------------------------------------------------
template<typename Dimension>
IvanoviSALEDamageModel<Dimension>::
~IvanoviSALEDamageModel() {
}

//------------------------------------------------------------------------------
// Evaluate derivatives.
//
// In this model we compute the scalar damage derivative assuming unresolved
// crack growth for every point. However, that is not applied in the tensor
// damage update policy unless the flaws are actually activated.
//------------------------------------------------------------------------------
template<typename Dimension>
void
IvanoviSALEDamageModel<Dimension>::
evaluateDerivatives(const Scalar time,
                    const Scalar dt,
                    const DataBase<Dimension>& dataBase,
                    const State<Dimension>& state,
                    StateDerivatives<Dimension>& derivs) const {

  // Set the scalar magnitude of the damage evolution.
  const auto* nodeListPtr = &(this->nodeList());
  auto&       DDDt = derivs.field(state.buildFieldKey(IvanoviSALEDamagePolicy<Dimension>::prefix() + SolidFieldNames::scalarDamage, nodeListPtr->name()), 0.0);
  this->computeScalarDDDt(dataBase,
                          state,
                          time,
                          dt,
                          DDDt);
}

//------------------------------------------------------------------------------
// Vote on a time step.
//------------------------------------------------------------------------------
template<typename Dimension>
typename IvanoviSALEDamageModel<Dimension>::TimeStepType
IvanoviSALEDamageModel<Dimension>::
dt(const DataBase<Dimension>& /*dataBase*/,
   const State<Dimension>& /*state*/,
   const StateDerivatives<Dimension>& /*derivs*/,
   const Scalar /*currentTime*/) const {

  // // Look at how quickly we're trying to change the damage.
  // double dt = DBL_MAX;
  // const Field<Dimension, SymTensor>& damage = this->nodeList().damage();
  // const ConnectivityMap<Dimension>& connectivityMap = dataBase.connectivityMap();
  // const vector<const NodeList<Dimension>*>& nodeLists = connectivityMap.nodeLists();
  // const size_t nodeListi = distance(nodeLists.begin(), find(nodeLists.begin(), nodeLists.end(), &(this->nodeList())));
  // for (typename ConnectivityMap<Dimension>::const_iterator iItr = connectivityMap.begin(nodeListi);
  //      iItr != connectivityMap.end(nodeListi);
  //      ++iItr) {
  //   const int i = *iItr;
  //   const double D0 = damage(i).Trace() / Dimension::nDim;
  //   dt = min(dt, 0.8*max(D0, 1.0 - D0)/
  //            std::sqrt(mDdamageDt(i)*mDdamageDt(i) + 1.0e-20));
  // }
  // return TimeStepType(dt, "Rate of damage change");

  return TimeStepType(1.0e100, "Rate of damage change -- NO VOTE.");
}

//------------------------------------------------------------------------------
// Register our state.
//------------------------------------------------------------------------------
template<typename Dimension>
void
IvanoviSALEDamageModel<Dimension>::
registerState(DataBase<Dimension>& dataBase,
              State<Dimension>& state) {

  typedef typename State<Dimension>::PolicyPointer PolicyPointer;

  // Register Youngs modulus and the longitudinal sound speed.
  PolicyPointer EPolicy(new YoungsModulusPolicy<Dimension>());
  PolicyPointer clPolicy(new LongitudinalSoundSpeedPolicy<Dimension>());
  state.enroll(mYoungsModulus, EPolicy);
  state.enroll(mLongitudinalSoundSpeed, clPolicy);

  // Set the initial values
  typename StateDerivatives<Dimension>::PackageList dummyPackages;
  StateDerivatives<Dimension> derivs(dataBase, dummyPackages);
  EPolicy->update(state.key(mYoungsModulus), state, derivs, 1.0, 0.0, 0.0);
  clPolicy->update(state.key(mLongitudinalSoundSpeed), state, derivs, 1.0, 0.0, 0.0);

  // Register the strain and effective strain.
  PolicyPointer effectiveStrainPolicy(new TensorStrainPolicy<Dimension>(TensorStrainAlgorithm::PseudoPlasticStrain));
  state.enroll(mStrain);
  state.enroll(mEffectiveStrain, effectiveStrainPolicy);

  // Register the damage and state it requires.
  // Note we are overriding the default no-op policy for the damage
  // as originally registered by the SolidSPHHydroBase class.
  auto& damage = this->nodeList().damage();
  PolicyPointer damagePolicy(new IvanoviSALEDamagePolicy<Dimension>(mEpsPfb,
                                                                    mB,
                                                                    mPc,
                                                                    mTensileFailureStress));
  state.enroll(damage, damagePolicy);

  // Mask out nodes beyond the critical damage threshold from setting the timestep.
  auto maskKey = state.buildFieldKey(HydroFieldNames::timeStepMask, this->nodeList().name());
  auto& mask = state.field(maskKey, 0);
  const auto nlocal = this->nodeList().numInternalNodes();
#pragma omp parallel for
  for (auto i = 0u; i < nlocal; ++i) {
    if (damage(i).Trace() > mCriticalDamageThreshold) mask(i) = 0;
  }
}

//------------------------------------------------------------------------------
// Register the derivatives.
//------------------------------------------------------------------------------
template<typename Dimension>
void
IvanoviSALEDamageModel<Dimension>::
registerDerivatives(DataBase<Dimension>& /*dataBase*/,
                    StateDerivatives<Dimension>& derivs) {
  derivs.enroll(mDdamageDt);
}

//------------------------------------------------------------------------------
// Apply the boundary conditions to the ghost nodes.
//------------------------------------------------------------------------------
template<typename Dimension>
void
IvanoviSALEDamageModel<Dimension>::
applyGhostBoundaries(State<Dimension>& state,
                     StateDerivatives<Dimension>& /*derivs*/) {

  // Grab this models damage field from the state.
  typedef typename State<Dimension>::KeyType Key;
  const Key nodeListName = this->nodeList().name();
  const Key DKey = state.buildFieldKey(SolidFieldNames::tensorDamage, nodeListName);
  CHECK(state.registered(DKey));
  auto& D = state.field(DKey, SymTensor::zero);

  // Apply ghost boundaries to the damage.
  for (auto boundaryItr = this->boundaryBegin();
       boundaryItr < this->boundaryEnd();
       ++boundaryItr) {
    (*boundaryItr)->applyGhostBoundary(D);
  }
}

//------------------------------------------------------------------------------
// Enforce boundary conditions for the physics specific fields.
//------------------------------------------------------------------------------
template<typename Dimension>
void
IvanoviSALEDamageModel<Dimension>::
enforceBoundaries(State<Dimension>& state,
                  StateDerivatives<Dimension>& /*derivs*/) {

  // Grab this models damage field from the state.
  typedef typename State<Dimension>::KeyType Key;
  const Key nodeListName = this->nodeList().name();
  const Key DKey = state.buildFieldKey(SolidFieldNames::tensorDamage, nodeListName);
  CHECK(state.registered(DKey));
  auto& D = state.field(DKey, SymTensor::zero);

  // Enforce!
  for (auto boundaryItr = this->boundaryBegin();
       boundaryItr < this->boundaryEnd();
       ++boundaryItr) {
    (*boundaryItr)->enforceBoundary(D);
  }
}

//------------------------------------------------------------------------------
// Dump the current state to the given file.
//------------------------------------------------------------------------------
template<typename Dimension>
void
IvanoviSALEDamageModel<Dimension>::
dumpState(FileIO& file, const string& pathName) const {
  DamageModel<Dimension>::dumpState(file, pathName);
  file.write(mStrain, pathName + "/strain");
  file.write(mEffectiveStrain, pathName + "/effectiveStrain");
  file.write(mDdamageDt, pathName + "/DdamageDt");
  file.write(mMask, pathName + "/mask");
}

//------------------------------------------------------------------------------
// Restore the state from the given file.
//------------------------------------------------------------------------------
template<typename Dimension>
void
IvanoviSALEDamageModel<Dimension>::
restoreState(const FileIO& file, const string& pathName) {
  DamageModel<Dimension>::restoreState(file, pathName);
  file.read(mStrain, pathName + "/strain");
  file.read(mEffectiveStrain, pathName + "/effectiveStrain");
  file.read(mDdamageDt, pathName + "/DdamageDt");
  file.read(mMask, pathName + "/mask");
}

}

ext: cc

max_stars_repo_name: jmikeowen/Spheral

max_stars_repo_licenses: BSD-Source-Code BSD-3-Clause-LBNL FSFAP

max_issues_repo_name: jmikeowen/Spheral

max_issues_repo_licenses: BSD-Source-Code BSD-3-Clause-LBNL FSFAP

max_forks_repo_name: jmikeowen/Spheral

max_forks_repo_licenses: BSD-Source-Code BSD-3-Clause-LBNL FSFAP


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

#ifndef NAVI_SIM__SCENARIO_TEST_COMPONENT_HPP_
#define NAVI_SIM__SCENARIO_TEST_COMPONENT_HPP_

#if __cplusplus
extern "C" {
#endif

// The below macros are taken from https://gcc.gnu.org/wiki/Visibility and from
// demos/composition/include/composition/visibility_control.h at https://github.com/ros2/demos
#if defined _WIN32 || defined __CYGWIN__
#ifdef __GNUC__
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_EXPORT __attribute__((dllexport))
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_IMPORT __attribute__((dllimport))
#else
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_EXPORT __declspec(dllexport)
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_IMPORT __declspec(dllimport)
#endif
#ifdef NAVI_SIM_SCENARIO_TEST_COMPONENT_BUILDING_DLL
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_PUBLIC NAVI_SIM_SCENARIO_TEST_COMPONENT_EXPORT
#else
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_PUBLIC NAVI_SIM_SCENARIO_TEST_COMPONENT_IMPORT
#endif
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_PUBLIC_TYPE NAVI_SIM_SCENARIO_TEST_COMPONENT_PUBLIC
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_LOCAL
#else
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_EXPORT __attribute__((visibility("default")))
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_IMPORT
#if __GNUC__ >= 4
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_PUBLIC __attribute__((visibility("default")))
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_LOCAL __attribute__((visibility("hidden")))
#else
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_PUBLIC
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_LOCAL
#endif
#define NAVI_SIM_SCENARIO_TEST_COMPONENT_PUBLIC_TYPE
#endif
#if __cplusplus
}  // extern "C"
#endif

#include <tf2_geometry_msgs/tf2_geometry_msgs.h>
#include <tf2_ros/buffer.h>
#include <tf2_ros/transform_broadcaster.h>
#include <tf2_ros/transform_listener.h>

#include <boost/optional.hpp>
#include <fstream>
#include <memory>
#include <navi_sim/interpreter/interpreter.hpp>
#include <navi_sim/raycaster.hpp>
#include <rclcpp/rclcpp.hpp>
#include <sensor_msgs/msg/point_cloud2.hpp>
#include <std_msgs/msg/string.hpp>
#include <string>
#include <utility>
#include <vector>
#include <visualization_msgs/msg/marker_array.hpp>

namespace navi_sim
{
class ScenarioTestComponent : public rclcpp::Node
{
public:
  NAVI_SIM_SCENARIO_TEST_COMPONENT_PUBLIC
  explicit ScenarioTestComponent(const rclcpp::NodeOptions & options);
  NAVI_SIM_SCENARIO_TEST_COMPONENT_PUBLIC
  explicit ScenarioTestComponent(std::string name, const rclcpp::NodeOptions & options);
  template <typename T, typename... Ts>
  void addPrimitive(Ts &&... xs)
  {
    raycaster_ptr_->addPrimitive<T>(std::forward<Ts>(xs)...);
  }

private:
  bool checkCollision();
  bool checkCollision(
    const std::vector<geometry_msgs::msg::Point> & poly0,
    const std::vector<geometry_msgs::msg::Point> & poly1);
  void initialize();
  std::unique_ptr<navi_sim::Raycaster> raycaster_ptr_;
  double bbox_center_x_;
  double bbox_center_y_;
  double bbox_center_z_;
  double bbox_length_;
  double bbox_width_;
  double update_rate_;
  std::string map_frame_;
  tf2_ros::Buffer buffer_;
  tf2_ros::TransformListener listener_;
  const std::vector<geometry_msgs::msg::Point> getBboxPolygon();
  const geometry_msgs::msg::Point getCornerPoint(bool x_dir, bool y_dir) const;
  std::vector<geometry_msgs::msg::Point> transformPoints(
    const geometry_msgs::msg::TransformStamped & pose,
    const std::vector<geometry_msgs::msg::Point> & points);
  rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr collision_marker_pub_;
  rclcpp::Publisher<geometry_msgs::msg::PoseStamped>::SharedPtr goal_pub_;
  rclcpp::TimerBase::SharedPtr timer_;
  void update();
  const visualization_msgs::msg::MarkerArray getCollisionMarker(bool collision);
  std::unique_ptr<navi_sim::Interpreter> interpreter_;
  std::string scenario_filename_;
  const boost::optional<geometry_msgs::msg::Pose> getEgoPose();
  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr context_pub_;
  rclcpp::Time start_time_;
};
}  // namespace navi_sim

#endif  // NAVI_SIM__SCENARIO_TEST_COMPONENT_HPP_

ext: hpp


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

#include "gbdxm.h"

#include <gbdxmVersion.h>

#include <boost/algorithm/string.hpp>
#include <boost/date_time.hpp>
#include <boost/filesystem.hpp>
#include <boost/make_shared.hpp>
#include <boost/make_unique.hpp>
#include <boost/program_options.hpp>
#include <boost/range/adaptor/map.hpp>
#include <geometry/cv_program_options.hpp>
#include <json/json.h>
#include <DeepCoreVersion.h>
#include <classification/Classification.h>
#include <classification/GbdxmCommon.h>
#include <classification/ModelMetadataJson.h>
#include <sstream>
#include <utility/File.h>
#include <utility/Error.h>
#include <utility/Logging.h>

namespace po = boost::program_options;

using namespace dg::deepcore;

using boost::adaptors::keys;
using boost::algorithm::join;
using boost::algorithm::to_lower;
using boost::algorithm::to_lower_copy;
using boost::filesystem::exists;
using boost::filesystem::is_directory;
using boost::make_unique;
using boost::posix_time::from_iso_string;
using boost::posix_time::to_time_t;
using std::cout;
using std::endl;
using std::find;
using std::find_if;
using std::ifstream;
using std::map;
using std::move;
using std::remove_if;
using std::string;
using std::stringstream;
using std::unique_ptr;
using std::vector;

namespace dg { namespace gbdxm {

// Forward declarations

po::detail::cmdline::style_parser buildExtraStyleParser();
po::options_description buildHelpOptions();
po::options_description buildParseOptions();
void addShowOptions(po::options_description& desc);
void addPackOptions(po::options_description& desc, bool helpOptions);
boost::shared_ptr<po::option_description> createFrameworkOption(classification::ItemDescription item, const char* type, const char* name, const char* ending);
void addPackFrameworkOptions(po::options_description& desc, bool includeCategory);
void addUnpackOptions(po::options_description& desc);

void setupLogging(const po::variables_map& vm);
unique_ptr<GbdxmArgs> readArgs(const po::variables_map& vm, const string& action);
unique_ptr<GbdxmArgs> readShowArgs(const po::variables_map& vm);
unique_ptr<GbdxmArgs> readPackArgs(const po::variables_map& vm);
vector<string> readJsonMetadata(const string& fileName, GbdxmPackArgs& args);
void readModelMetadata(GbdxmPackArgs& args, vector<string>& missingFields);
unique_ptr<GbdxmArgs> readUnpackArgs(const po::variables_map& vm);
void tryErase(vector<string>& names, const string& name);

} } // namespace dg { namespace gbdxm {

int main (int argc, const char* const* argv)
{
    using namespace dg::gbdxm;

    try {
        // Setup initial logging environment
        log::init();
        log::addCerrSink(level_t::warning, level_t::fatal, log::dg_log_format::dg_short_log);

        classification::init();

        // First argument is action, which we parse out ourselves
        if(argc < 2) {
            cout << buildHelpOptions() << endl;
            DG_ERROR_THROW("Must have at least 1 argument.");
        }

        string action = argv[1];
        to_lower(action);

        // Add gbdxm-file as a positional argument for convenience
        po::positional_options_description p;
        p.add("gbdxm-file", -1);

        // Parse the arguments
        po::variables_map vm;

        try {
            // Build arguments
            auto desc = buildParseOptions();

            po::store(po::command_line_parser(argc - 1, &argv[1])
                          .extra_style_parser(buildExtraStyleParser())
                          .options(desc)
                          .positional(p)
                          .run(), vm);
            po::notify(vm);
        } catch(...) {
            cout << buildHelpOptions() << endl;
            DG_ERROR_RETHROW("");
        }

        setupLogging(vm);

        // Read arguments, if invalid action or "help", print the usage details
        auto args = readArgs(vm, action);
        if(!args) {
            cout << buildHelpOptions() << endl;
            DG_CHECK(action == "help", "Invalid action. The correct actions are help, show, and pack");

            exit(0);
        }

        doAction(*args);
    } catch (...) {
        DG_ERROR_LOG(gbdxm, DG_ERROR_FROM_CURRENT(""));
        return 1;
    }

    return 0;
}

namespace dg { namespace gbdxm {

po::detail::cmdline::style_parser buildExtraStyleParser()
{
    vector<po::detail::cmdline::style_parser> parsers;

    parsers.emplace_back(&po::ignore_numbers);

    for(const auto& type : classification::ModelIdentifier::types()) {
        parsers.emplace_back(po::prefix_argument(type));
    }

    return po::combine_style_parsers(parsers);
}

po::options_description buildHelpOptions()
{
    stringstream ss;
    ss <<
        "GDBX Model Packaging Tool\n"
        "Version: " GBDXM_VERSION_STRING "\n"
        "Built on DeepCore version: " DEEPCORE_VERSION_STRING "\n"
        "GBDXM Metadata Version: " << classification::gbdxm::METADATA_VERSION << "\n\n"
        "Usage: gbdxm <action> [options] [gbdxm file]\n\n"
        "Actions:\n"
        "  help  \t\t Show this help message.\n"
        "  show  \t\t Show package metadata.\n"
        "  pack  \t\t Pack a model into a GBDX package.\n\n"
        "General Options";

    po::options_description desc(
        ss.str()
    );

    desc.add_options()
        ("verbose,v", "Verbose output.")
        ("gbdxm-file,f", po::value<string>()->value_name("PATH"), "Input or output GBDXM file.");

    addShowOptions(desc);
    addPackOptions(desc, true);

    return desc;
}

po::options_description buildParseOptions()
{
    po::options_description desc;
    desc.add_options()
        ("verbose,v", "Verbose output.")
        ("gbdxm-file,f", po::value<string>(), "Input or output GBDXM file.")
        ("plaintext", "Don't encrypt the model.")
        ("image-type,i", po::value<string>(), "Image type. e.g. jpg (deprecated).")
        ("category,C", po::value<string>(), "Model category");

    addShowOptions(desc);
    addPackOptions(desc, false);
    addUnpackOptions(desc); // Hidden activity, options not in help

    return desc;
}

void addShowOptions(po::options_description& desc)
{
    // No options here, left for future expansion
}

void addPackOptions(po::options_description& desc, bool helpOptions)
{
    po::options_description pack("Pack Options");
    string supportedTypes = "Type of the input model. Currently supported types:";
    for(const auto& type : classification::ModelIdentifier::types()) {
        supportedTypes += "\n \t - " + type;
    }

    pack.add_options()
        ("type,t", po::value<string>()->value_name("TYPE"), supportedTypes.c_str())
        ("json,j", po::value<string>()->value_name("PATH"),
            "Model metadata in JSON format. Command line parameters will override "
            "entries in this file if present.")
        ("name,n", po::value<string>()->value_name("NAME"), "Model name.")
        ("version,V", po::value<string>()->value_name("VERSION"), "Model version.")
        ("description,d", po::value<string>()->value_name("DESCRIPTION"), "Model description.")
        ("labels,l", po::value<string>()->value_name("PATH"), "Labels file name.")
        ("label-names", po::value<vector<string>>()->multitoken()->value_name("LABEL1 [LABEL2 ...]"),
            "A list of label names.")
        ("date-time", po::value<string>()->value_name("DATE_TIME"),
            "Date/time the model was created (optional). Default is the current date and time. Must be in the following "
            "ISO format: YYYYMMDDTHHMMSS[.ffffff], where 'T' is the literal date-time separator. e.g. 20020131T100001.123456")
        ("model-size,w", po::cvSize_value()->value_name("WIDTH [HEIGHT]"), "Classifier model size. Model parameters will "
            "override this if present.")
        ("bounding-box,b", po::cvRect2d_value()->value_name("W S E N"),
            "Training area bounding box (optional). Must specify four "
            "coordinates: west longitude, south latitude, east longitude, and north latitude. e.g. "
            "--bounding-box -180 -90 180 90")
        ("color-mode,c", po::value<string>()->value_name("MODE"),
            "Color mode. Model parameters will override this if present. Must be one of the following: grayscale, rgb, multiband")
        ("resolution,r", po::cvSize2d_value()->value_name("WIDTH [HEIGHT]"),
            "Model pixel resolution (optional).")
        ;

    addPackFrameworkOptions(pack, helpOptions);

    desc.add(pack);
}

void addPackFrameworkOptions(po::options_description& desc, bool includeCategory)
{
    for(const auto& type : classification::ModelIdentifier::types()) {
        const auto& identifier = *classification::ModelIdentifier::find(type);

        string title("Pack ");
        title += identifier.prettyType();
        title += " Options";

        po::options_description framework(title);

        if(includeCategory) {
            string categoryDesc = "Model category";
            if(identifier.canDetectCategory()) {
                categoryDesc += " (optional). ";
            } else {
                categoryDesc += ". ";
            }

            categoryDesc += "The supported categories are: " + join(identifier.categories(), ", ") + ".";

            framework.add(boost::make_shared<po::option_description>(
                "category,C", po::value<string>()->value_name("CATEGORY"), categoryDesc.c_str()));
        }

        auto multiDesc = string("Set multiple ") + identifier.prettyType() + " options.";

        framework.add(boost::make_shared<po::option_description>(
            type.c_str(),
            po::value<vector<string>>()
                ->value_name("NAME VALUE [NAME VALUE ...]")
                ->multitoken(),
            multiDesc.c_str()));

        // Add descriptions for model items
        for(const auto& item : identifier.itemDescriptions()) {
            framework.add(createFrameworkOption(item, identifier.type(), "PATH", " file name"));
        }

        // Add descriptions for model options
        for(const auto& item : identifier.optionDescriptions()) {
            framework.add(createFrameworkOption(item, identifier.type(), "VALUE", ""));
        }

        desc.add(framework);
    }
}

boost::shared_ptr<po::option_description> createFrameworkOption(classification::ItemDescription item, const char* type, const char* name, const char* ending)
{
    string option(type);
    option += "-";
    option += item.name;

    auto description = item.description + ending;
    if(item.optional) {
        description += " (optional)";
    }

    description += ".";

    if(!item.allowedValues.empty()) {
        description += " Allowed values are: " + join(item.allowedValues, ", ") + ".";
    }

    auto value = po::value<string>()->value_name(name);
    if(!item.defaultValue.empty()) {
        value->default_value("\"" + item.defaultValue + "\"");
    }

    return boost::make_shared<po::option_description>(option.c_str(), value, description.c_str());
}

void addUnpackOptions(po::options_description& desc)
{
    po::options_description unpack("Unpack Options");
    unpack.add_options()
        ("output-dir,o", po::value<string>()->value_name("PATH")->default_value("."),
            "Directory for the output model files. Default is current directory.");

    desc.add(unpack);
}

void setupLogging(const po::variables_map& vm)
{
    // --verbose
    if(vm.count("verbose")) {
        log::addCoutSink(level_t::info, level_t::info, log::dg_log_format::dg_short_log);
    }
}

unique_ptr<GbdxmArgs> readArgs(const boost::program_options::variables_map& vm, const string& action)
{
    unique_ptr<GbdxmArgs> args;

    if(action == "show") {
        args = readShowArgs(vm);
    } else if(action == "pack") {
        args = readPackArgs(vm);
    } else if(action == "unpack") {
        args = readUnpackArgs(vm);
    }

    // If action is not in "show", "pack", or "unpack", just return nullptr
    if(!args) {
        return nullptr;
    }

    // --gbdxm-file
    DG_CHECK(vm.count("gbdxm-file") > 0, "No GBDXM file specified.");
    args->gbdxFile = vm["gbdxm-file"].as<string>();

    return args;
}

unique_ptr<GbdxmArgs> readShowArgs(const po::variables_map& vm)
{
    unique_ptr<GbdxmArgs> args(new GbdxmArgs);
    args->action = Action::SHOW;

    return args;
}

void readFrameworkPackItems(map<string, string>& items,
                            map<string, string>& options,
                            vector<string>& missingArgs,
                            const classification::ItemDescriptions& descriptions,
                            const string& prefix)
{
    for(const auto& item : descriptions) {
        auto it = options.find(item.name);
        if(it != options.end()) {
            if(!item.allowedValues.empty()) {
                auto valueIt = find(item.allowedValues.begin(), item.allowedValues.end(), it->second);
                DG_CHECK(valueIt != item.allowedValues.end(),
                         "Invalid --%s-%s option: allowed values are: %s",
                        item.name.c_str(), prefix.c_str(), join(item.allowedValues, ", ").c_str());
            }

            items[it->first] = it->second;
            options.erase(it);
        } else if(!item.optional && items.find(item.name) == items.end()) {
            missingArgs.push_back(prefix + item.name);
        }
    }
}

vector<string> readFrameworkPackArgs(const po::variables_map& vm, GbdxmPackArgs& args)
{
    auto type = args.package->type();
    map<string, string> cliOptions;
    if(vm.count(type) > 0) {
        const auto& argList = vm[args.package->type()].as<vector<string>>();
        DG_CHECK(argList.size() % 2 == 0, "--%s must have an even number of arguments", type);

        for(auto it = argList.begin(); it != argList.end(); ++it) {
            const auto& key = *it++;
            const auto& value = *it;
            cliOptions[key] = value;
        }
    }

    auto prefix = string(type) + "-";
    vector<string> missingArgs;

    readFrameworkPackItems(args.modelFiles, cliOptions, missingArgs, args.identifier->itemDescriptions(), prefix);

    map<string, string> options;
    readFrameworkPackItems(options, cliOptions, missingArgs, args.identifier->optionDescriptions(), prefix);
    args.package->metadata().setOptions(options);

    DG_CHECK(cliOptions.empty(), "Invalid %s options: %s",
            args.identifier->type(), join(keys(cliOptions), ", ").c_str());

    return missingArgs;
}

unique_ptr<GbdxmArgs> readPackArgs(const po::variables_map& vm)
{
    auto args = make_unique<GbdxmPackArgs>();
    args->action = Action::PACK;
    vector<string> missingFields;
    vector<string> errors;

    // --type
    if(vm.count("type")) {
        args->type = vm["type"].as<string>();
        to_lower(args->type);

        args->package = classification::ModelPackage::create(args->type.c_str());
        missingFields = classification::ModelMetadataJson::fieldNames(args->type);
        tryErase(missingFields, "type");
    }

    // --json
    if(vm.count("json")) {
        missingFields = readJsonMetadata(vm["json"].as<string>(), *args);
    }

    DG_CHECK(!args->type.empty() && args->package, "Missing model type")
    tryErase(missingFields, "version");
    tryErase(missingFields, "size");
    args->identifier = &args->package->identifier();
    auto& metadata = args->package->metadata();

    // --version
    if(vm.count("version")) {
        metadata.setVersion(vm["version"].as<string>());
        tryErase(missingFields, "modelVersion");
    }

    // --name
    if(vm.count("name")) {
        metadata.setName(vm["name"].as<string>());
        tryErase(missingFields, "name");
    }

    // --category
    if(vm.count("category")) {
        metadata.setCategory(to_lower_copy(vm["category"].as<string>()));
        tryErase(missingFields, "category");
    }

    // --description
    if(vm.count("description")) {
        metadata.setDescription(vm["description"].as<string>());
        tryErase(missingFields, "description");
    }

    // --label-names
    if(vm.count("label-names")) {
        metadata.setLabels(vm["label-names"].as<vector<string>>());
        if(!metadata.labels().empty()) {
            tryErase(missingFields, "labels");
        }
    }

    // --labels
    if(vm.count("labels")) {
        DG_CHECK(vm.count("label-names") == 0, "Please specify either --labels or --label-names, not both");
        args->labelsFile = vm["labels"].as<string>();
        if (!args->labelsFile.empty()) {
            tryErase(missingFields, "labels");
        }
    }

    // --date-time
    if(vm.count("date-time")) {
        time_t timeCreated;
        try {
            timeCreated = to_time_t(from_iso_string(vm["date-time"].as<string>()));
        } catch (...) {
            DG_ERROR_THROW("Invalid date/time format in --date-time argument");
        }
        metadata.setTimeCreated(timeCreated);
    } else if(find(missingFields.begin(), missingFields.end(), "timeCreated" ) != missingFields.end()) {
        metadata.setTimeCreated(time(nullptr));
    }

    tryErase(missingFields, "timeCreated");

    // --model-size
    if(vm.count("model-size")) {
        metadata.setModelSize(vm["model-size"].as<cv::Size>());
        tryErase(missingFields, "modelSize");
    }

    // --bounding-box
    if(vm.count("bounding-box")) {
        metadata.setBoundingBox(vm["bounding-box"].as<cv::Rect2d>());
        tryErase(missingFields, "boundingBox");
    }

    // --image-type
    if(vm.count("image-type")) {
        DG_LOG(gbdxm, warning) << "--image-type argument is deprecated and ignored";
    }

    // --color-mode
    if(vm.count("color-mode")) {
        auto colorMode = classification::colorModeFromString(vm["color-mode"].as<string>());
        if(colorMode != classification::ColorMode::UNKNOWN) {
            metadata.setColorMode(colorMode);
            tryErase(missingFields, "colorMode");
        } else {
            errors.emplace_back("Unsupported option for --color-mode '" + vm["color-mode"].as<string>() + "'");
        }
    }

    // --resolution
    if(vm.count("resolution")) {
        metadata.setResolution(vm["resolution"].as<cv::Size2d>());
        tryErase(missingFields, "resolution");
    }

    // "--<type>-<option>" arguments, e.g. "--caffe-model"
    auto missingArgs = readFrameworkPackArgs(vm, *args);

    if(!missingArgs.empty()) {
        errors.push_back(string("Missing ") + metadata.type() + " model arguments: --" + join(missingArgs, ", --"));
    } else {
        // Try to retrieve fields from the model
        readModelMetadata(*args, missingFields);
    }

    // --plaintext
    if(vm.count("plaintext")) {
        args->encrypt = false;
    }

    // Create an error message for missingFields
    if(!missingFields.empty()) {
        auto cliMap = classification::ModelMetadataJson::fieldToOption(metadata.type());
        vector<string> cliFields;

        for(const auto& missingField : missingFields){
            auto it = cliMap.find(missingField);
            if(it != end(cliMap)) {
                cliFields.push_back(it->second);
            }
            else{
                cliFields.push_back(missingField);
            }
        }
        errors.push_back("Missing required metadata arguments: --" + join(cliFields, ", --"));
    }

    // Create an error if category is invalid or cannot be inferred
    vector<string> categories;
    if (args->identifier->canDetectCategory()) {
        categories = args->identifier->detectCategory(*args->package);
        DG_CHECK(!categories.empty(), "Category could not be detected for type '%s'", args->type.c_str());
    } else {
        categories = args->identifier->categories();
        DG_CHECK(!categories.empty(), "No categories for invalid or unsupported type '%s'", args->type.c_str());
    }

    if(metadata.category().empty()) {
        if(categories.size() == 1) {
            metadata.setCategory(categories[0]);
        } else {
            errors.push_back("Please specify a category, possible categories "
                             "for this model are: " + join(categories, ", "));
        }
    } else if(find(categories.begin(), categories.end(), metadata.category()) == categories.end()) {
        errors.push_back("Category '" + metadata.category()  + "' is invalid,"
                         " possible categories for this model are: " + join(categories, ", "));
    }

    DG_CHECK(errors.empty(), "%s", join(errors, "\n").c_str());
    return std::move(args);
}

vector<string> readJsonMetadata(const string& fileName, GbdxmPackArgs& args)
{
    DG_CHECK(exists(fileName), "%s does not exist", fileName.c_str());
    DG_CHECK(!is_directory(fileName), "%s is a directory", fileName.c_str());

    vector<string> missingFields;
    ifstream ifs(fileName);
    DG_CHECK(ifs.good(), "Error opening %s: %s", fileName.c_str(), strerror(errno));

    Json::Reader reader;
    Json::Value root;
    DG_CHECK(reader.parse(ifs, root), "Error parsing metadata: %s",
             reader.getFormattedErrorMessages().c_str());

    auto metadata = classification::ModelMetadataJson::fromJsonPartial(root, missingFields, args.type);
    args.package = classification::ModelPackage::create(move(metadata));
    args.type = args.package->type();

    if(root.isMember("content")) {
        DG_CHECK(root["content"].type() == Json::objectValue,
                 "Invalid metadata \"content\" field: must be a JSON object.");

        for(const auto& name : root["content"].getMemberNames()) {
            args.modelFiles[name] = root["content"][name].asString();
        }
    }

    return missingFields;
}

void readModelMetadata(GbdxmPackArgs& args, vector<string>& missingFields)
{
    // Load the files with metadata into the ModelPackage
    for(const auto& itemName : args.identifier->metadataItems()) {
        const auto& fileName = args.modelFiles[itemName];

        const auto& descriptions = args.identifier->itemDescriptions();
        auto it = find_if(descriptions.begin(), descriptions.end(), [&itemName](const classification::ItemDescription& desc) {
            return desc.name == itemName;
        });

        // Sanity check, should never happen unless the ModelPackage
        // and ModelIdentifier are set up wrong.
        DG_CHECK(it != descriptions.end(), "'%s' is not registered as valid model package item", itemName.c_str());

        if(fileName.empty()) {
            DG_CHECK(it->optional, "--%s-%s argument is missing", args.identifier->type(), itemName.c_str());
            continue;
        }

        if(!exists(fileName)) {
            if(it->optional) {
                DG_LOG(gbdxm, warning) << "Invalid --" << args.identifier->type() << "-" << itemName
                                       << " argument: "<< fileName << " does not exist";
                continue;
            } else {
                // Again, this shouldn't happen, but we'll handle it here anyway.
                DG_ERROR_THROW("Invalid --%s-%s argument: %s does not exist",
                               args.identifier->type(), itemName.c_str(), fileName.c_str());
            }
        }

        DG_LOG(gbdxm, info) << "Reading model metadata from " << fileName;

        args.package->setItem(itemName, readBinaryFile(fileName));
    }

    // Read the metadata
    auto itemsRead = args.identifier->readMetadata(*args.package);

    // Remove items retrieved from the missingFields list
    missingFields.erase(remove_if(missingFields.begin(), missingFields.end(), [&itemsRead](const string& item) {
        return find(itemsRead.begin(), itemsRead.end(), item) != itemsRead.end();
    }), missingFields.end());
}

unique_ptr<GbdxmArgs> readUnpackArgs(const po::variables_map& vm)
{
    unique_ptr<GbdxmUnpackArgs> args(new GbdxmUnpackArgs);
    args->action = Action::UNPACK;

    // --output-dir
    args->outputDir = vm["output-dir"].as<string>();

    return std::move(args);
}

void tryErase(vector<string>& names, const string& name)
{
    auto it = find(names.begin(), names.end(), name);
    if(it != names.end()) {
        names.erase(it);
    }
}

} } // namespace dg { namespace gbdxm {

ext: cpp

max_stars_repo_name: DigitalGlobe/gbdxm

max_issues_repo_name: DigitalGlobe/GGD-gbdxm

max_forks_repo_name: DigitalGlobe/GGD-gbdxm


text:
#ifndef BOOST_CORE_NO_EXCEPTIONS_SUPPORT_HPP
#define BOOST_CORE_NO_EXCEPTIONS_SUPPORT_HPP

#if defined(_MSC_VER)
#  pragma once
#endif

//----------------------------------------------------------------------
// (C) Copyright 2004 Pavel Vozenilek.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
//
//
// This file contains helper macros used when exception support may be
// disabled (as indicated by macro BOOST_NO_EXCEPTIONS).
//
// Before picking up these macros you may consider using RAII techniques
// to deal with exceptions - their syntax can be always the same with
// or without exception support enabled.
//----------------------------------------------------------------------

#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>

#if !(defined BOOST_NO_EXCEPTIONS)
#    define BOOST_TRY { try
#    define BOOST_CATCH(x) catch(x)
#    define BOOST_RETHROW throw;
#    define BOOST_CATCH_END }
#else
#    if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
#        define BOOST_TRY { if ("")
#        define BOOST_CATCH(x) else if (!"")
#    else
#        define BOOST_TRY { if (true)
#        define BOOST_CATCH(x) else if (false)
#    endif
#    define BOOST_RETHROW
#    define BOOST_CATCH_END }
#endif

#endif

max_stars_repo_name: xarvey/Yuuuuuge

max_issues_repo_name: xarvey/Yuuuuuge

max_forks_repo_name: xarvey/Yuuuuuge


text:
// Copyright (c) 2018 Graphcore Ltd. All rights reserved.

// Legacy code to test some BroadcastVectorInner vertices.
// This code is no longer used.

#define BOOST_TEST_MODULE ChannelMul

#include "../lib/popops/ExprOpUtil.hpp"
#include <boost/multi_array.hpp>
#include <functional>
#include <iostream>
#include <limits>
#include <poplar/Engine.hpp>
#include <poplibs_support/TestDevice.hpp>
#include <poplibs_test/Util.hpp>
#include <popops/codelets.hpp>
#include <poputil/TileMapping.hpp>
#include <poputil/VertexTemplates.hpp>

// Tolerances used in tests
#define FLOAT_REL_TOL 0.01
#define HALF_REL_TOL 0.1
#define FLOAT_ABS_TOL 1e-6
#define HALF_ABS_TOL 1e-3

using namespace poplar;
using namespace poplar::program;
using namespace poputil;
using namespace poplibs_test::util;
using namespace poplibs_support;

const OptionFlags options;

struct TestCase {
  poplar::Type type;
  std::size_t scaleLen;
  std::size_t actsLen;
};

struct TestCaseData {
  std::vector<double> scale;
  std::vector<double> actsIn;

  std::unique_ptr<char[]> rawScale;
  std::unique_ptr<char[]> rawActsIn;
  std::unique_ptr<char[]> rawActsOut;
};

static bool channelMulTests(const std::vector<TestCase> &cases) {

  const std::size_t overwriteLen = 32;

  auto device = createTestDevice(TEST_TARGET, 1, 1);
  const auto &target = device.getTarget();
  Graph graph(target);
  popops::addCodelets(graph);

  // One compute set, with a vertex for each test case.
  auto cs = graph.addComputeSet("cs");

  Sequence uploadProg;
  Sequence downloadProg;
  std::vector<std::pair<std::string, char *>> tmap;
  std::vector<TestCaseData> tcData(cases.size());

  for (std::size_t i = 0; i < cases.size(); ++i) {
    const auto &tc = cases[i];
    if (tc.actsLen % tc.scaleLen != 0) {
      return false;
    }

    std::cout << "Test case [" << i << "]: "
              << " scaleLen: " << tc.scaleLen << " actsLen: " << tc.actsLen
              << " type: " << tc.type.toString() << "\n";

    std::string suffix = "_" + std::to_string(i);

    auto scale = graph.addVariable(tc.type, {tc.scaleLen}, "scale" + suffix);
    auto actsIn = graph.addVariable(tc.type, {tc.actsLen}, "actsIn" + suffix);
    auto actsOut = graph.addVariable(tc.type, {tc.actsLen + overwriteLen},
                                     "actsOut" + suffix);
    graph.setTileMapping(scale, 0);
    graph.setTileMapping(actsIn, 0);
    graph.setTileMapping(actsOut, 0);

    std::string templateVertexName =
        templateVertex("popops::BroadcastVectorInnerSupervisor",
                       popops::expr::BinaryOpType::MULTIPLY, tc.type);

    auto v =
        graph.addVertex(cs, templateVertexName,
                        {{"data", actsIn}, {"out", actsOut}, {"B", scale}});

    auto actsBlockCount = tc.actsLen / tc.scaleLen;
    auto actsBlockCountPacked =
        ((actsBlockCount / 6) << 3) | (actsBlockCount % 6);
    uint16_t actsBlockCountPacked16 = actsBlockCountPacked;

    if (actsBlockCountPacked16 != actsBlockCountPacked)
      return false;

    graph.setInitialValue(v["dataBlockCountPacked"], actsBlockCountPacked16);

    graph.setTileMapping(v, 0);

    tcData[i].rawScale = allocateHostMemoryForTensor(
        scale, "scale" + suffix, graph, uploadProg, downloadProg, tmap);
    tcData[i].rawActsIn = allocateHostMemoryForTensor(
        actsIn, "acts" + suffix, graph, uploadProg, downloadProg, tmap);
    tcData[i].rawActsOut = allocateHostMemoryForTensor(
        actsOut, "out" + suffix, graph, uploadProg, downloadProg, tmap);

    tcData[i].scale.resize(tc.scaleLen);
    tcData[i].actsIn.resize(tc.actsLen);

    std::mt19937 randomEngine;
    writeRandomValues(target, scale.elementType(), tcData[i].scale.data(),
                      tcData[i].scale.data() + tcData[i].scale.size(), -2., 2.,
                      randomEngine);
    writeRandomValues(target, actsIn.elementType(), tcData[i].actsIn.data(),
                      tcData[i].actsIn.data() + tcData[i].actsIn.size(), -2.,
                      2., randomEngine);

    copy(target, tcData[i].scale.data(), tcData[i].scale.size(),
         scale.elementType(), tcData[i].rawScale.get());
    copy(target, tcData[i].actsIn.data(), tcData[i].actsIn.size(),
         actsIn.elementType(), tcData[i].rawActsIn.get());
    // Set actsOut to 1, to verify there are no overwrites.
    std::vector<double> ones(actsOut.numElements(), 1.0);
    copy(target, ones.data(), ones.size(), actsOut.elementType(),
         tcData[i].rawActsOut.get());
  }

  std::cout << "Executing engine\n";

  auto prog = Execute(cs);
  Engine engine(graph, Sequence(uploadProg, prog, downloadProg), options);

  attachStreams(engine, tmap);

  device.bind([&](const Device &d) {
    engine.load(d);
    engine.run(0);
  });

  std::cout << "Checking results\n";

  // Check the results for each test case.

  for (std::size_t i = 0; i < tcData.size(); ++i) {
    const auto &tc = cases[i];

    std::cout << "Checking case [" << i << "]\n";

    // Convert back to double.
    std::vector<double> actsOut(tcData[i].actsIn.size() + overwriteLen, 0.0);

    copy(target, tc.type, tcData[i].rawActsOut.get(), actsOut.data(),
         actsOut.size());

    // Check the answer.
    std::vector<double> actsOutRef(actsOut.size(), 1.0);
    for (std::size_t k = 0; k < tc.actsLen; ++k)
      actsOutRef[k] = tcData[i].actsIn[k] * tcData[i].scale[k % tc.scaleLen];

    const double absoluteTolerance =
        tc.type == FLOAT ? FLOAT_ABS_TOL : HALF_ABS_TOL;
    const double relativeTolerance =
        tc.type == FLOAT ? FLOAT_REL_TOL : HALF_REL_TOL;

    auto matchesModel =
        checkIsClose("out", actsOut.data(), {actsOut.size()}, actsOutRef.data(),
                     actsOut.size(), relativeTolerance, absoluteTolerance);
    if (!matchesModel)
      return false;
  }

  return true;
}

const bool isNotSim = !isSimulator(TEST_TARGET);

BOOST_AUTO_TEST_CASE(ChannelMulTiny) {
  std::vector<TestCase> cases = {
      {HALF, 1, 8},  {HALF, 4, 16},  {HALF, 8, 32},  {HALF, 5, 15},
      {FLOAT, 1, 8}, {FLOAT, 4, 16}, {FLOAT, 8, 32}, {FLOAT, 5, 15},
  };
  BOOST_TEST(channelMulTests(cases));
}

BOOST_AUTO_TEST_CASE(ChannelMulSmall,
                     *boost::unit_test::precondition(enableIfNotSim())) {
  std::vector<TestCase> cases = {
      {HALF, 1, 480},   {HALF, 4, 480},  {HALF, 8, 480},  {HALF, 12, 480},
      {HALF, 16, 480},  {HALF, 1, 15},   {HALF, 4, 12},   {HALF, 8, 40},
      {HALF, 5, 15},    {HALF, 8, 168},

      {FLOAT, 1, 480},  {FLOAT, 4, 480}, {FLOAT, 8, 480}, {FLOAT, 12, 480},
      {FLOAT, 16, 480}, {FLOAT, 1, 15},  {FLOAT, 4, 12},  {FLOAT, 8, 40},
      {FLOAT, 5, 15},   {FLOAT, 8, 168},
  };
  BOOST_TEST(channelMulTests(cases));
}

BOOST_AUTO_TEST_CASE(ChannelMulLarge1_half,
                     *boost::unit_test::precondition(enableIfNotSim())) {
  std::vector<TestCase> cases = {
      {HALF, 1, 8000},
  };
  BOOST_TEST(channelMulTests(cases));
}

BOOST_AUTO_TEST_CASE(ChannelMulLarge8_half,
                     *boost::unit_test::precondition(enableIfNotSim())) {
  std::vector<TestCase> cases = {
      {HALF, 8, 8000},
  };
  BOOST_TEST(channelMulTests(cases));
}

BOOST_AUTO_TEST_CASE(ChannelMulLarge1_float,
                     *boost::unit_test::precondition(enableIfNotSim())) {
  std::vector<TestCase> cases = {
      {FLOAT, 1, 8000},
  };
  BOOST_TEST(channelMulTests(cases));
}

BOOST_AUTO_TEST_CASE(ChannelMulLarge8_float,
                     *boost::unit_test::precondition(enableIfNotSim())) {
  std::vector<TestCase> cases = {
      {FLOAT, 8, 8000},
  };
  BOOST_TEST(channelMulTests(cases));
}

// Above an addend length over 2044, we switch to scalar code. Check that works.
BOOST_AUTO_TEST_CASE(ChannelMul_MaxChannels_MultipleOfFour_half,
                     *boost::unit_test::precondition(enableIfNotSim())) {
  for (std::size_t scaleLen = 2040; scaleLen <= 2052; scaleLen += 4) {
    std::vector<TestCase> cases = {
        {HALF, scaleLen, scaleLen * 4},
    };
    BOOST_TEST(channelMulTests(cases));
  }
}

max_stars_repo_name: graphcore/poplibs

max_issues_repo_name: graphcore/poplibs

max_forks_repo_name: graphcore/poplibs


text:
#include <iostream>
#include <fstream>

#include <boost/program_options.hpp>

#include "mp/following_detection.hpp"
#include "mp/following_graph.hpp"

#include "../common/util.hpp"
#include "../common/follower_file.hpp"

using namespace mp;
using namespace std;

void parse_options(int argc, char *argv[]);
void validate_options();

// Path to input feature file.
string in_file;

// The timestamp for graph generation.
bool absolute_timestamp = false;
i64  at_timestamp = 0;

// Path to output file and its type.
string out_file;
string out_type;

int main(int argc, char *argv[]) {
    setlocale(LC_ALL, "C");
    parse_options(argc, argv);
    validate_options();

    // Load follower data from file
    following_data followers;
    feature_parameters params;
    {
        fstream in_stream;
        try {
            try_open(in_stream, in_file, ios_base::in);
        } catch (const std::exception &e) {
            cerr << "failed to open input file \""
                 << in_file << "\": "
                 << e.what() << endl;
            exit(1);
        }

        cereal::JSONInputArchive ar(in_stream);
        load_follower_file(ar, followers, params);
    }

    cout << "Using follower data:\n"
         << "  Source:      " << in_file << "\n"
         << "  Data source: " << params.data_source << "\n"
         << "  Algorithm:   " << params.algorithm << "\n"
         << "  Window size: " << params.window_size << " seconds\n"
         << "  Time lag:    " << params.time_lag << " seconds\n"
         << "  Devices:     " << followers.devices.size() << "\n"
         << "  Begin:       " << followers.begin_timestamp << "\n"
         << "  End:         " << followers.end_timestamp << "\n"
         << "  Duration:    " << followers.duration << " seconds\n";

    i64 abs_ts = absolute_timestamp ? at_timestamp
                                    : followers.begin_timestamp + at_timestamp;
    i64 rel_ts = abs_ts - followers.begin_timestamp;

    cout << "Computation parameters:\n"
         << "  Output:           " << out_file << "\n"
         << "  Timestamp (abs.): " << abs_ts << "\n"
         << "  Timestamp (rel.): " << rel_ts << "\n"
         << flush;

    if (abs_ts < followers.begin_timestamp || abs_ts > followers.end_timestamp) {
        cerr << "Timestamp " << abs_ts << " is out of range. Exiting." << endl;
        exit(1);
    }

    following_graph graph = following_graph_at(followers, abs_ts);

    // Save graph to file
    {
        fstream out_stream;
        try {
            try_open(out_stream, out_file, ios_base::out | ios_base::trunc);
        } catch (const std::exception &e) {
            cerr << "failed to open output file \""
                 << out_file << "\": "
                 << e.what() << endl;
            exit(1);
        }

        if (out_type == "json") {
            cereal::JSONOutputArchive ar(out_stream);
            ar(cereal::make_nvp("params", params));
            ar(cereal::make_nvp("timestamp", abs_ts));
            ar(cereal::make_nvp("graph", graph));
        } else if (out_type == "graphml") {
            to_graphml(graph, out_stream);
        } else {
            throw std::logic_error("unsupported output type: " + out_type);
        }
    }

    return 0;
}

void parse_options(int argc, char *argv[])
{
    namespace po = boost::program_options;

    po::options_description opts("Options");
    opts.add_options()
            ("help,h",
             "Print this help message")
            ("input",
             po::value<string>(&in_file)->value_name("PATH")->required(),
             "The path to a file generated by the detect-followers program.")
            ("at",
              po::value<i64>(&at_timestamp)->value_name("TIMESTAMP")->required(),
             "Use the follower data at TIMESTAMP to generate the follower graph. "
             "By default, the timestamp is interpreted as relative from the beginning "
             "of the follower data (i.e. 0 -> first second).")
            ("absolute",
             po::bool_switch(&absolute_timestamp)->default_value(false),
             "Interpret the timestamp given for --at as absolute instead of relative.")
            ("output",
             po::value<string>(&out_file)->value_name("PATH")->required(),
             "The output path. The generated graph will be written to this file.")
            ("output-type",
             po::value<string>(&out_type)->value_name("TYPE")->required(),
             "The output format.\n"
             "Supported formats are:\n"
             "  json:    \tWrites a human-readable JSON file that contains the graph and some meta information\n"
             "  graphml: \tOutput a GraphML document. GraphML files can be read by many graph-visualization tools.")
            ;

    po::variables_map vm;
    try {
        auto parser = po::command_line_parser(argc, argv);
        parser.options(opts);
        po::store(parser.run(), vm);

        if (vm.count("help")) {
            cerr << "Usage: " << argv[0] << " [options]" << "\n";
            cerr << "\n";
            cerr << "This program takes a file previously created by the detect-followers\n"
                 << "program and extracts a following graph at some user-defined timestamp.\n"
                 << "The graph will contain an edge between two vertices \"a\" and \"b\"\n"
                 << "if \"a\" is classified as following \"b\".\n"
                 << "Multiple output formats are supported.\n\n"
                 << flush;
            cerr << opts << flush;
            exit(1);
        }

        po::notify(vm);
    } catch (const po::error &e) {
        cerr << e.what() << endl;
        exit(1);
    }
}

void validate_options()
{
    auto contains = [](const vector<string> &v, const string &s) {
        return std::find(v.begin(), v.end(), s) != v.end();
    };

    static const vector<string> allowed_output_types{"json", "graphml"};

    bool ok = true;
    if (!contains(allowed_output_types, out_type)) {
        cerr << "output type is invalid (" << out_type << ")" << endl;
        ok = false;
    }

    if (!ok) {
        exit(1);
    }
}

max_stars_repo_name: mbeckem/mp

max_issues_repo_name: mbeckem/mp

max_forks_repo_name: mbeckem/mp


text: #include <boost/filesystem/path.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#include "external_task.h"
#include "sandbox/isolate_sandbox.h"
#include "helpers/string_utils.h"
#include "helpers/filesystem.h"
#include <fstream>
#include <algorithm>
#include <memory>
#include <string>
#define BOOST_FILESYSTEM_NO_DEPRECATED
#define BOOST_NO_CXX11_SCOPED_ENUMS
#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;

external_task::external_task(const create_params &data)
	: task_base(data.id, data.task_meta), worker_config_(data.worker_conf), sandbox_(nullptr),
	  sandbox_config_(data.task_meta->sandbox), limits_(data.limits), logger_(data.logger), temp_dir_(data.temp_dir),
	  evaluation_dir_(data.source_path), sandbox_working_dir_(data.sandbox_working_path)
{
	if (worker_config_ == nullptr) { throw task_exception("No worker configuration provided."); }

	if (limits_ == nullptr) { throw task_exception("No limits provided."); }

	if (sandbox_config_ == nullptr) { throw task_exception("No sandbox configuration provided."); }

	if (!sandbox_config_->working_directory.empty()) {
		if (!helpers::check_relative(sandbox_config_->working_directory)) {
			throw task_exception("Given working directory in sandbox config is not relative or contains '..'");
		}

		evaluation_dir_ = fs::path(data.source_path) / sandbox_config_->working_directory;
	}

	sandbox_check();
}

void external_task::sandbox_check()
{
	bool found = false;

#ifndef _WIN32
	if (task_meta_->sandbox->name == "isolate") { found = true; }
#endif

	if (found == false) { throw task_exception("Unknown sandbox type: " + task_meta_->sandbox->name); }
}

void external_task::sandbox_init()
{
#ifndef _WIN32
	if (task_meta_->sandbox->name == "isolate") {
		sandbox_limits limits(*limits_);
		if (this->get_type() == task_type::INITIATION) {
			limits.share_net = true; // initiation (compilation) tasks may use internet to download stuff

			// TODO: a better way would be to make this optional (a job will define, whether it requires net or not)
		}
		sandbox_ = std::make_shared<isolate_sandbox>(
			sandbox_config_, limits, worker_config_->get_worker_id(), temp_dir_, evaluation_dir_.string(), logger_);
	}
#endif
}

void external_task::sandbox_fini()
{
	sandbox_ = nullptr;
}

std::shared_ptr<task_results> external_task::run()
{
	sandbox_init();

	if (sandbox_ == nullptr) {
		// should never happen, unless we are doomed
		return nullptr;
	}

	// initialize output from stdout and stderr
	results_output_init();

	// check if evaluation directory exists
	if (!fs::exists(evaluation_dir_)) {
		throw task_exception("Evaluation directory '" + evaluation_dir_.string() + "' of sandbox does not exists");
	}

	// check if binary is executable and set it otherwise
	make_binary_executable(task_meta_->binary);

	auto res = std::make_shared<task_results>();
	res->sandbox_status =
		std::unique_ptr<sandbox_results>(new sandbox_results(sandbox_->run(task_meta_->binary, task_meta_->cmd_args)));

	// get output from stdout and stderr
	get_results_output(res);

	sandbox_fini();

	// Check if sandbox ran successfully, else report error
	if (res->sandbox_status->status != isolate_status::OK) {
		res->status = task_status::FAILED;
		res->error_message = "Sandboxed program failed: " + res->sandbox_status->message;
	}

	return res;
}

std::shared_ptr<sandbox_limits> external_task::get_limits()
{
	return limits_;
}

void external_task::results_output_init()
{
	std::string random = helpers::random_alphanum_string(10);

	if (sandbox_config_->output || !sandbox_config_->carboncopy_stdout.empty()) {
		// output from stdout/stderr or carboncopy of stdout was requested
		if (sandbox_config_->std_output == "") {
			remove_stdout_ = true;
			std::string stdout_file = task_meta_->task_id + "." + random + ".output.stdout";
			sandbox_config_->std_output = (sandbox_working_dir_ / fs::path(stdout_file)).string();
		}
	}

	if (sandbox_config_->output || !sandbox_config_->carboncopy_stderr.empty()) {
		// output from stdout/stderr or carboncopy of stderr was requested
		if (sandbox_config_->std_error == "") {
			remove_stderr_ = true;
			std::string stderr_file = task_meta_->task_id + "." + random + ".output.stderr";
			sandbox_config_->std_error = (sandbox_working_dir_ / fs::path(stderr_file)).string();
		}
	}
}

fs::path external_task::find_path_outside_sandbox(const std::string &file)
{
	return helpers::find_path_outside_sandbox(
		file, sandbox_config_->chdir, limits_->bound_dirs, evaluation_dir_.string());
}

void external_task::get_results_output(std::shared_ptr<task_results> result)
{
	// files were outputted inside sandbox, so we have to find path outside sandbox
	fs::path stdout_file_path = find_path_outside_sandbox(sandbox_config_->std_output);
	fs::path stderr_file_path = find_path_outside_sandbox(sandbox_config_->std_error);
	process_results_output(result, stdout_file_path, stderr_file_path);
	process_carboncopy_output(stdout_file_path, stderr_file_path);

	// delete produced files if requested
	try {
		if (remove_stdout_) { fs::remove(stdout_file_path); }
		if (remove_stderr_) { fs::remove(stderr_file_path); }
	} catch (fs::filesystem_error &e) {
		logger_->warn("Temporary sandbox output files not cleaned properly: {}", e.what());
	}
}

void external_task::process_results_output(
	const std::shared_ptr<task_results> &result, const fs::path &stdout_path, const fs::path &stderr_path)
{
	if (sandbox_config_->output) {
		std::size_t max_length = worker_config_->get_max_output_length();
		std::string result_stdout(max_length, 0);
		std::string result_stderr(max_length, 0);

		// open and read files
		std::ifstream std_out(stdout_path.string());
		std::ifstream std_err(stderr_path.string());
		std_out.read(&result_stdout[0], max_length);
		std_err.read(&result_stderr[0], max_length);

		// if there was something in stdout, write it to result
		if (std_out.gcount() != 0) {
			result_stdout = result_stdout.substr(0, std_out.gcount());
			// filter non printable result
			helpers::filter_non_printable_chars(result_stdout);
			// write to result structure
			result->output_stdout = result_stdout;
		}

		// if there was something in stderr, write it to result
		if (std_err.gcount() != 0) {
			result_stderr = result_stderr.substr(0, std_err.gcount());
			// filter non printable result
			helpers::filter_non_printable_chars(result_stderr);
			// write to result structure
			result->output_stderr = result_stderr;
		}

		// be nice and close streams
		std_out.close();
		std_err.close();
	}
}

void external_task::process_carboncopy_output(const fs::path &stdout_path, const fs::path &stderr_path)
{
	std::size_t max_length = worker_config_->get_max_carboncopy_length();
	if (!sandbox_config_->carboncopy_stdout.empty()) {
		std::ifstream infile(stdout_path.string(), std::ios::binary);
		std::ofstream copy_file(sandbox_config_->carboncopy_stdout, std::ios::binary);

		// make the copying, by reading the file in memory and writing it to the copy
		std::string inmemory(max_length, 0);
		infile.read(&inmemory[0], max_length);
		copy_file.write(&inmemory[0], infile.gcount());

		// some day we do not close streams... but it is not this day
		infile.close();
		copy_file.close();
	}

	if (!sandbox_config_->carboncopy_stderr.empty()) {
		std::ifstream infile(stderr_path.string(), std::ios::binary);
		std::ofstream copy_file(sandbox_config_->carboncopy_stderr, std::ios::binary);

		// make the copying, by reading the file in memory and writing it to the copy
		std::string inmemory(max_length, 0);
		infile.read(&inmemory[0], max_length);
		copy_file.write(&inmemory[0], infile.gcount());

		// close streams, you fools
		infile.close();
		copy_file.close();
	}
}

void external_task::make_binary_executable(const std::string &binary)
{
	fs::path binary_path;
	try {
		binary_path = find_path_outside_sandbox(binary);
		if (binary_path.empty()) {
			logger_->info("Sandbox path {} not found in local filesystem, executable bit not set", binary);
			return;
		}

		// determine if file has executable bits set
		fs::file_status stat = status(binary_path);
		if (stat.permissions() & (fs::perms::owner_exe | fs::perms::group_exe | fs::perms::others_exe)) { return; }

		fs::permissions(
			binary_path, fs::perms::add_perms | fs::perms::owner_exe | fs::perms::group_exe | fs::others_exe);
	} catch (fs::filesystem_error &e) {
		log_and_throw(logger_,
			"Failed to set executable bits for path inside '",
			binary,
			"' and outside '",
			binary_path.string(),
			"'. Error: ",
			e.what());
	}
}

max_stars_repo_name: rqu/worker

max_issues_repo_name: rqu/worker

max_forks_repo_name: rqu/worker


text:
#ifndef TRIUMF_SUPERCONDUCTIVITY_PIPPARD_HPP
#define TRIUMF_SUPERCONDUCTIVITY_PIPPARD_HPP

#include <cmath>

// #include <boost/multiprecision/cpp_dec_float.hpp>

#include <triumf/constants/codata_2018.hpp>
#include <triumf/superconductivity/bcs.hpp>
#include <triumf/superconductivity/phenomenology.hpp>

// TRIUMF: Canada's particle accelerator centre
namespace triumf {

//
namespace superconductivity {

// Pippard's phenomenological theory of superconductivity
namespace pippard {

///
template <typename T = double>
T J_0(T temperature, T critical_temperature, T gap_meV, T exponent) {
  // Boltzmann constant (meV / K)
  constexpr T k_B_meV_per_K =
      1e3 *
      triumf::constants::codata_2018::Boltzmann_constant_in_eV_K<T>::value();
  //
  // T reduced_temperature = temperature / critical_temperature;
  //
  return std::pow(phenomenology::reduced_penetration_depth<T>(
                      temperature, critical_temperature, exponent),
                  2) *
         bcs::reduced_gap<T>(temperature, critical_temperature) *
         std::tanh(bcs::gap<T>(temperature, critical_temperature, gap_meV) /
                   (2.0 * k_B_meV_per_K * temperature));
}

/// temperature dependence of the Pippard coherence length,
/// "borrowed" from BCS theory
template <typename T = double>
T coherence_length(T temperature, T critical_temperature, T gap_meV, T exponent,
                   T xi_0, T mean_free_path) {
  T fraction_1 =
      J_0<T>(temperature, critical_temperature, gap_meV, exponent) / xi_0;
  T fraction_2 = 1.0 / mean_free_path;
  T fraction = fraction_1 + fraction_2;
  // handle a some edge cases for very big/small args
  if (std::isinf(fraction)) {
    return 0.0;
  } else if (fraction == 0.0) {
    return std::numeric_limits<T>::infinity();
  } else {
    return 1.0 / fraction;
  }
}

/// temperature dependence of the (reduced) Pippard coherence length,
/// "borrowed" from BCS theory
template <typename T = double>
T reduced_coherence_length(T temperature, T critical_temperature, T gap_meV,
                           T exponent, T xi_0, T mean_free_path) {
  return coherence_length<T>(temperature, critical_temperature, gap_meV,
                             exponent, xi_0, mean_free_path) /
         coherence_length<T>(0.0, critical_temperature, gap_meV, exponent, xi_0,
                             mean_free_path);
}

/// helper function for the Pippard Kernel
template <typename T = double> T g(T x) {
  /*
  boost::multiprecision::cpp_dec_float_100 value =
      (3.0 / 2.0) * ((1.0 + x * x) * std::atan(x) - x) / (x * x * x);
  return value;
  */
  // return correct result when x ~ 0.
  if (x < 1.0e-4) {
    return 1.0;
  } else {
    return (3.0 / 2.0) * ((1.0 + x * x) * std::atan(x) - x) / (x * x * x);
  }
}

/// Pippard Kernel
template <typename T = double>
T kernel(T q, T temperature, T critical_temperature, T gap_meV, T xi_0,
         T mean_free_path, T lambda_0, T exponent) {
  T x = q * coherence_length<T>(temperature, critical_temperature, gap_meV,
                                exponent, xi_0, mean_free_path);
  return std::pow(phenomenology::penetration_depth<T>(
                      temperature, critical_temperature, exponent, lambda_0),
                  -2) *
         reduced_coherence_length<T>(temperature, critical_temperature, gap_meV,
                                     exponent, xi_0, mean_free_path) *
         g<T>(x);
}

/// (reduced) Pippard Kernel
template <typename T = double>
T reduced_kernel(T q, T temperature, T critical_temperature, T gap_meV, T xi_0,
                 T mean_free_path, T lambda_0, T exponent) {
  return kernel<T>(q, temperature, critical_temperature, gap_meV, xi_0,
                   mean_free_path, lambda_0, exponent) /
         kernel<T>(0.0, temperature, critical_temperature, gap_meV, xi_0,
                   mean_free_path, lambda_0, exponent);
}

/// (reduced) magnetic field penetration proifile
template <typename T = double>
T reduced_field_penetration(T z, T temperature, T critical_temperature,
                            T gap_meV, T xi_0, T mean_free_path, T lambda_0,
                            T exponent) {
  //
  if (z <= 0.0) {
    return 1.0;
  } else {
    //
    auto pippard_integrand = [&](T q) -> T {
      T K = kernel<T>(q, temperature, critical_temperature, gap_meV, xi_0,
                      mean_free_path, lambda_0, exponent);
      return q / (q * q + K);
    };
    // create the integrator w/ specific tolerance and evaluation levels
    // (defaults: root_epsilon and eight levels for type double).
    // static T tolerance = std::sqrt(std::numeric_limits<T>::epsilon());
    static T tolerance = std::cbrt(std::numeric_limits<T>::epsilon());
    std::size_t levels = sizeof(T);
    static boost::math::quadrature::ooura_fourier_sin<T> pippard_integrator =
        boost::math::quadrature::ooura_fourier_sin<T>(tolerance, levels);
    // evaluate the integral, which returns a pair
    // (first = integral, second = relative error)
    std::pair<T, T> result = pippard_integrator.integrate(pippard_integrand, z);
    // return the integral multiplied by the prefactors to get B vs. z
    return boost::math::constants::two_div_pi<T>() * result.first;
  }
}

/// magnetic field penetration proifile
template <typename T = double>
T field_penetration(T z, T temperature, T critical_temperature, T gap_meV,
                    T xi_0, T mean_free_path, T lambda_0, T exponent,
                    T applied_field) {
  return applied_field * reduced_field_penetration<T>(
                             z, temperature, critical_temperature, gap_meV,
                             xi_0, mean_free_path, lambda_0, exponent);
}

} // namespace pippard

} // namespace superconductivity

} // namespace triumf

#endif // TRIUMF_SUPERCONDUCTIVITY_PIPPARD_HPP

max_stars_repo_name: rmlmcfadden/triumfpp

max_issues_repo_name: rmlmcfadden/triumfpp

max_forks_repo_name: rmlmcfadden/triumfpp


text:
/*
	Copyright 2005-2007 Adobe Systems Incorporated
	Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
	or a copy at http://stlab.adobe.com/licenses.html)
*/

/*************************************************************************************************/

#include <adobe/config.hpp>

#define BOOST_TEST_MAIN

#include <boost/test/unit_test.hpp>

#include <adobe/name.hpp>
#include <adobe/utility/ignore_unused.hpp>

BOOST_AUTO_TEST_CASE(name_int) {
    adobe::name_t not_an_int("not_an_int");
    int i = not_an_int;
    adobe::ignore_unused(i);
}

max_stars_repo_name: brycelelbach/asl

max_issues_repo_name: brycelelbach/asl

max_forks_repo_name: brycelelbach/asl


text:
//  (C) Copyright John Maddock 2006.
//  Use, modification and distribution are subject to the
//  Boost Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_MATH_SPECIAL_HERMITE_HPP
#define BOOST_MATH_SPECIAL_HERMITE_HPP

#ifdef _MSC_VER
#pragma once
#endif

#include <boost/math/special_functions/math_fwd.hpp>
#include <boost/math/tools/config.hpp>
#include <boost/math/policies/error_handling.hpp>

namespace boost{
namespace math{

// Recurrence relation for Hermite polynomials:
template <class T1, class T2, class T3>
inline typename tools::promote_args<T1, T2, T3>::type
   hermite_next(unsigned n, T1 x, T2 Hn, T3 Hnm1)
{
   return (2 * x * Hn - 2 * n * Hnm1);
}

namespace detail{

// Implement Hermite polynomials via recurrence:
template <class T>
T hermite_imp(unsigned n, T x)
{
   T p0 = 1;
   T p1 = 2 * x;

   if(n == 0)
      return p0;

   unsigned c = 1;

   while(c < n)
   {
      std::swap(p0, p1);
      p1 = hermite_next(c, x, p0, p1);
      ++c;
   }
   return p1;
}

} // namespace detail

template <class T, class Policy>
inline typename tools::promote_args<T>::type
   hermite(unsigned n, T x, const Policy&)
{
   typedef typename tools::promote_args<T>::type result_type;
   typedef typename policies::evaluation<result_type, Policy>::type value_type;
   return policies::checked_narrowing_cast<result_type, Policy>(detail::hermite_imp(n, static_cast<value_type>(x)), "boost::math::hermite<%1%>(unsigned, %1%)");
}

template <class T>
inline typename tools::promote_args<T>::type
   hermite(unsigned n, T x)
{
   return boost::math::hermite(n, x, policies::policy<>());
}

} // namespace math
} // namespace boost

#endif // BOOST_MATH_SPECIAL_HERMITE_HPP


text:
//Copyright (c) 2013 Singapore-MIT Alliance for Research and Technology
//Licensed under the terms of the MIT License, as described in the file:
//   license.txt   (http://opensource.org/licenses/MIT)

#pragma once

#include <boost/noncopyable.hpp>
#include "MT_Config.hpp"
#include "conf/ConfigParams.hpp"
#include "conf/ParseConfigXmlBase.hpp"
#include "conf/RawConfigParams.hpp"

using namespace sim_mob;
using namespace sim_mob::medium;
using namespace xercesc;

namespace sim_mob
{

namespace medium
{
/**
 * Parser for the mid-term config file
 *
 * \author Harish Loganathan
 * \author Zhang Huai Peng
 */
class ParseMidTermConfigFile: public ParseConfigXmlBase, private boost::noncopyable
{
public:
	/**
	 * Parse a config file into MT_Config, performing all XML parsing and some trivial semantic processing
	 *
	 * @param configFileName - Config file to be processed
	 *
	 * @param result - Configuration values extracted from config file
	 */
	ParseMidTermConfigFile(const std::string& configFileName, MT_Config& result, ConfigParams& cfg);

private:
	/**
	 * Code for processing the xml
	 *
	 * @param configFileName is the filename of configuration
	 */
	virtual void processXmlFile(xercesc::XercesDOMParser& parser);

	/**
	 * processes mid term run mode - supply or preday
	 * sets the run mode in configParams
     *
	 * @param node node corresponding to the mid-term run mode element in xml file
	 */
	void processMidTermRunMode(xercesc::DOMElement* node);

	/**
     * processes the supply element in config file
     *
	 * @param node node corresponding to the supply element in xml file
	 */
	void processSupplyNode(xercesc::DOMElement* node);

	/**
	 * processes the preday element in config file
     *
	 * @param node node corresponding to the preday element in xml file
	 */
	void processPredayNode(xercesc::DOMElement* node);

	/**
	 * processes the stored procedure mappings under supply node
     *
	 * @param node node corresponding to the procedure mappings for supply in xml file
	 */
	void processProcMapNode(xercesc::DOMElement* node);
	 /**
	 * processes the energy model node
     *
	 * @param node node specifying the usage flag and output file of energy model
	 */
	void processEnergyModelNode(xercesc::DOMElement* node);

	/**
	 * processes the activity load interval node
     *
	 * @param node node specifying the value and unit for activity load interval
	 */

	void processActivityLoadIntervalElement(xercesc::DOMElement* node);
	/**
	 * processes update interval node
     *
	 * @param node node corresponding to update interval element
	 */
	void processUpdateIntervalElement(xercesc::DOMElement* node);

	/**
	 * processes dwell time element included in xml file.
     *
	 * @param node node corresponding to the dwell time element inside xml file
	 */
	void processDwellTimeElement(xercesc::DOMElement* node);

	/**
	 * processes default capacity bust included in xml file.
     *
	 * @param node node corresponding to the bus capacity element inside xml file
	 */
	void processBusCapactiyElement(xercesc::DOMElement* node);

	/**
	 * processes pedestrian walk speed included in xml file.
     *
	 * @param node node corresponding to pedestrian walk speed element inside xml file
	 */
	void processWalkSpeedElement(xercesc::DOMElement* node);

	/**
	 * processes threads number in person loader included in xml file.
	 *
	 * @param node corresponding to the element of threads number in person loader inside xml file
	 */
	void processThreadsNumInPersonLoaderElement(xercesc::DOMElement* node);

	/**
     * processes model scripts element in config xml
     *
	 * @param node node corresponding to model_scripts element inside xml file
	 */
	ModelScriptsMap processModelScriptsNode(xercesc::DOMElement* node);

	/**
	 * processes statistics output file element in config xml
     *
	 * @param node node corresponding to statistics output file element inside xml file
	 */
	void processStatisticsOutputNode(xercesc::DOMElement* node);

	/**
	 * processes node for speed-density function params
	 */
	void processSpeedDensityParamsNode(xercesc::DOMElement* node);

	/**
	 * processes calibration element in config xml
     *
	 * @param node node corresponding to calibration element inside xml file
	 */
	void processCalibrationNode(xercesc::DOMElement* node);

	/**
	 * Processes the system element in the config file
	 *
	 * @param node node corresponding to the system element inside xml file
	 */
	void processSystemNode(xercesc::DOMElement* node);

	/**
	 * Processes the generic_props element in the config file
	 *
	 * @param node node corresponding to the generic_props element inside xml file
	 */
	void processGenericPropsNode(xercesc::DOMElement* node);

	/**
	 * processes network_database element in config xml
	 *
	 * @param node node corresponding to network_database element inside xml file
	 */
	void processDatabaseNode(xercesc::DOMElement* node, DatabaseDetails& dbDetails);

	/**
	 * processes the workers element in config xml
	 *
	 * @param node node corresponding to workers element inside xml file
	 */
	void processWorkersNode(xercesc::DOMElement* node);

	/**
	 * processes the person element in config xml
	 *
	 * @param node node corresponding to person element inside xml file
	 */
	void processWorkerPersonNode(xercesc::DOMElement* node);

	/**
	 * processes the ScreenLine element in config xml
	 *
	 * @param node node corresponding to screenline element inside xml file
	 */
	void processScreenLineNode(xercesc::DOMElement* node);

	/**
	 * processes the region_restriction element in config xml
	 *
	 * @param node node corresponding to cbd element inside xml file
	 */
	void processRegionRestrictionNode(xercesc::DOMElement* node);

    /**
	 * processes the generateBusRoutes element in config xml
	 *
	 * @param node node corresponding to generateBusRoutes element inside xml file
	 */
	void processGenerateBusRoutesNode(xercesc::DOMElement* node);

	/**
	 * processes the subtrip_travel_metrics_output element in config xml
	 *
	 * @param node node corresponding to generateBusRoutes element inside xml file
	 */
	void processSubtripTravelMetricsOutputNode(xercesc::DOMElement* node);

	/**
	 * processes the bus stop schedule times element in config xml
	 *
	 * @param node node correspoding to scheduledTimes element inside xml file
	 */
	void processBusStopScheduledTimesNode(xercesc::DOMElement* node);

	/**
	 * processes the travel time element the config xml
	 *
	 * @param node node corresponding to trave_time element inside xml file
	 */
	void processTT_Update(xercesc::DOMElement* node);

	/**
	 * Processes the publicTransit element in config xml
	 *
	 * @param node node corresponding to the publicTransit element inside xml file
	 */
	void processPublicTransit(xercesc::DOMElement* node);

	/**
	 * Processes the incidents element in config xml
	 *
	 * @param node node corresponding to the incidents element inside xml file
	 */
	void processIncidentsNode(xercesc::DOMElement* node);

	/**
	 * Processes the busController element in config xml
	 * @param node node corresponding to the busController element inside xml file
	 */
	void processBusControllerNode(xercesc::DOMElement *node);

	/**
	 * Processes the trainController element in config xml
	 * @param node is the node corresponding to the trainController element inside simrun_Midterm.xml file
	 */
	void processTrainControllerNode(xercesc::DOMElement *node);

	void processPathSetFileName(xercesc::DOMElement* node);

	/**
  * Process the trip chain output node in simrun_MidTerm.xml
  * @param node is the node corresponding to the trip_chain_output element inside simrun_Midterm.xml file
  */
	void processTripChainOutputNode(xercesc::DOMElement* node);

    /**
     * Processes the travel modes element in config xml
     *
     * @param node node corresponding to the travel modes element inside xml file
     */
    void processTravelModesNode(xercesc::DOMElement* node);

    /**
     * Processes the activity types element in config xml
     *
     * @param node node corresponding to the activity types element inside xml file
     */
    void processActivityTypesNode(xercesc::DOMElement* node);

	/**
 	* Processes the OnHail and OnCall Taxi Trajectory  element in config xml
 	*
 	* @param node node corresponding to respectively Taxi Trajectory  types element inside xml file
 	*/
	void processOnCallTaxiTrajectoryNode(xercesc::DOMElement* node);
	void processOnHailTaxiTrajectoryNode(xercesc::DOMElement* node);

	/// The config we are currently loading
	MT_Config& mtCfg;

	/// Shared configuration
	ConfigParams& cfg;
};
} // namespace medium
} // namespace sim_mob


text:
//#############################################################################
                                 /*-:::--.`
                            -+shmMMNmmddmmNMNmho/.
                 `yyo++osddMms:                  `/yNNy-
              yo    +mMy:                       `./dMMdyssssso-
              oy  -dMy.                     `-+ssso:.`:mMy`   .ys
                ho+MN:                  `:osso/.         oMm-   +h
                +Mmd-           `/syo-                     :MNhs`
                `NM-.hs`      :syo:                          sMh
                oMh   :ho``/yy+.                             `MM.
                hM+    `yNN/`                                 dM+
                dM/  -sy/`/ho`                                hMo
                hMo/ho.     :yy-                             dM/
            :dNM/             :yy:                         yMy
            sy`:MN.              `+ys-                     +Mm`
            oy`   :NM+                  .+ys/`           `hMd.ys
            /sssssyNMm:                   `:sys:`     `oNN+   m-
                        .sNMh+.                   `:sNMdyysssssy:
                        -odMNhs+:-.`    `.-/oydMNh+.
                            `-+shdNMMMMMMMNmdyo/.
                                    `````*/
//#############################################################################
// Imgui for the visualizer
//#############################################################################

#include <boost/thread.hpp>
#include <boost/chrono.hpp>
#include <boost/thread/lockable_adapter.hpp>
#include <mutex>
#include <iostream>
#include <random>

#include <igl/readOFF.h>
#include <igl/opengl/glfw/Viewer.h>
#include <igl/opengl/glfw/imgui/ImGuiMenu.h>
#include <igl/opengl/glfw/imgui/ImGuiHelpers.h>

#include <igl/jet.h>

// PCL
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/common/io.h>

#include "er-pipeline.h"

#include "application_state.h"
#include "helpers_ui.h"

igl::opengl::glfw::imgui::ImGuiMenu menu;

using namespace er;

void flush_settings(igl::opengl::glfw::Viewer &viewer)
{
#ifdef USE_IMGUI
	// Save camera position
	app_state::get().save_vec3f("camera_translation", viewer.core.camera_translation);
	Eigen::Vector4f v4 = { viewer.core.trackball_angle.x(), viewer.core.trackball_angle.y(), viewer.core.trackball_angle.z(), viewer.core.trackball_angle.w() };
	app_state::get().save_vec4f("trackball_angle", v4);

	app_state::get().config["camera_zoom"] = viewer.core.camera_zoom;

	er::app_state::get().save_configuration();
#endif
}

void initialize_visualizer_ui(igl::opengl::glfw::Viewer &viewer)
{
#ifdef USE_IMGUI
	// Attach a menu plugin
	viewer.plugins.push_back(&menu);

	// Add content to the default menu window
	menu.callback_draw_viewer_window = [&] () {
		if (app_state::get().show_igl_viewer_menu)
			menu.draw_viewer_menu();
	};

	menu.callback_draw_custom_window = [&] () {
		std::string open_file;

		if (ImGui::BeginMainMenuBar()) {
			if (ImGui::BeginMenu("File")) {
				if (ImGui::MenuItem("Open", "Ctrl+O")) {
					std::string fname = igl::file_dialog_open();

					if (fname.length() != 0) {
						std::cout << "Load file " << fname << std::endl;
						open_file = fname;
					}
				}

				if (ImGui::MenuItem("Save", "Ctrl+S")) {
					flush_settings(viewer);
				}

				if (ImGui::BeginMenu("Open Recent")) {
					json j_object = app_state::get().config["recent_files"];

					if (j_object != nullptr) {
						for (auto& x : json::iterator_wrapper(j_object)) {

							std::string key = x.key();
							if (ImGui::MenuItem(key.c_str())) {
								std::cout << "---------- Open ---------------\n";
								std::cout << "key: " << x.key() << ", value: " << x.value() << '\n';
								open_file = key.c_str();
							}
						}
					}

					ImGui::EndMenu();
				}

				ImGui::Separator();
				if (ImGui::BeginMenu("Open by description")) {
					json j_object = app_state::get().json_dataset["datasets"];

					if (j_object != nullptr) {
						for (auto& x : json::iterator_wrapper(j_object)) {
							json j_data = x.value();

							std::string bag_file = app_state::get().get_bagfile_from_id(x.key());
							try {
								std::string description = j_data["short_description"];
								std::string text = x.key() + std::string(" :: ") + description;

								if (ImGui::MenuItem(text.c_str())) {
									std::cout << "---------- Open ---------------\n";
									std::cout << "key: " << x.key() << ", value: " << x.value() << '\n';

									open_file = bag_file;
								}
							} catch (const std::exception &e) {
#ifdef DEBUG
								printf("! No description yet\n");
#endif
							}
						}
					}

					ImGui::EndMenu();
				}

				ImGui::EndMenu();
			}

			if (ImGui::BeginMenu("Edit")) {
				if (ImGui::MenuItem("Undo", "CTRL+Z")) {}
				if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {}  // Disabled item
				ImGui::Separator();
				if (ImGui::MenuItem("Cut", "CTRL+X")) {}
				if (ImGui::MenuItem("Copy", "CTRL+C")) {}
				if (ImGui::MenuItem("Paste", "CTRL+V")) {}
				ImGui::EndMenu();
			}

			if (ImGui::BeginMenu("View")) {
				ImGui::MenuItem("Console", NULL, &app_state::get().show_app_console);
				ImGui::MenuItem("Log", NULL, &app_state::get().show_app_log);
				ImGui::Separator();
				ImGui::MenuItem("Camera", NULL, &app_state::get().show_camera_window);
				ImGui::MenuItem("Ground", NULL, &app_state::get().show_debug_ground);
				ImGui::MenuItem("Raw Rgbd", NULL, &app_state::get().show_raw_rgbd);
				ImGui::MenuItem("System", NULL, &app_state::get().show_system_view);
				ImGui::MenuItem("Plants", NULL, &app_state::get().show_plants_view);
				ImGui::MenuItem("Plant Analsys", NULL, &app_state::get().show_analysis);

				ImGui::EndMenu();
			}

			ImGui::EndMainMenuBar();
		}

		ShowAppConsole(&app_state::get().show_app_console);
		ShowAppLog(&app_state::get().show_app_log);

		static const int flags = ImGuiWindowFlags_AlwaysAutoResize;

		ImGuiIO& io = ImGui::GetIO();

		if (app_state::get().show_system_view) {
			ImGui::Begin("System", &app_state::get().show_system_view, flags);

			if (ImGui::CollapsingHeader("Capture", ImGuiTreeNodeFlags_DefaultOpen)) {
				ImGui::Text("Data Path");
				ImGui::SameLine(60); ImGui::Text("%s",
					app_state::get().capture_folder.c_str());

				float w = ImGui::GetContentRegionAvailWidth();
				float p = ImGui::GetStyle().FramePadding.x;

				static char buf[256] = "Short Description";
				try {
					std::string description = app_state::get().json_data["short_description"];
					if (description.size() > 0) {
						memset(buf, 0, sizeof(buf));
						strncpy(buf, description.c_str(), description.size());
					}
				} catch (const std::exception &e) {
#ifdef DEBUG
					printf("No description yet!\n");
#endif
				}

				if (ImGui::InputText("Short Description", buf, IM_ARRAYSIZE(buf))) {
					printf("TODO: Save description - Renamed file data\n");
					app_state::get().save_description(buf);
				}

				if (ImGui::Button("Load##Analysis", ImVec2((w - p) / 2.f, 0))) {
					std::string fname = igl::file_dialog_open();

					if (fname.length() != 0) {
						std::cout << "Load file " << fname << std::endl;
						open_file = fname;
					}
				}
				ImGui::SameLine(0, p);
				if (ImGui::Button("Save##Analysis", ImVec2((w - p) / 2.f, 0))) {
					flush_settings(viewer);
				}

				ImGui::Separator();

				float seek = app_state::get().playback_position;
				if (ImGui::SliderFloat("Seek", &seek, 0,
					app_state::get().playback_duration)) {
					printf(" Seek %2.2f ", seek);
				}
			}

			ImGui::End();
		}

		//ImGui::GetIO().IniFilename = "interface.ini";

		if (app_state::get().show_raw_rgbd) {
			ImGui::Begin("Raw RGBD View", &app_state::get().show_raw_rgbd, flags);

			ImGui::Text("Color Spaces");

			if (ImGui::Checkbox("Show ground Raw", &app_state::get().show_ground_raw)) {
				printf(" Show ground Raw\n"); app_state::get().invalidate_ui = true;
			}

			if (ImGui::Checkbox("Show plants Raw", &app_state::get().show_plants_raw)) {
				printf(" Show plants Raw\n"); app_state::get().invalidate_ui = true;
			}

			ImGui::Checkbox("Show nvdi", &app_state::get().bool_tint_nvdi);
			ImGui::SliderFloat("NVDI", &app_state::get().cur_nvdi,
				app_state::get().min_nvdi,
				app_state::get().max_nvdi);

			ImGui::Checkbox("Show ir", &app_state::get().bool_tint_ir);
			ImGui::SliderFloat("IR", &app_state::get().cur_ir, app_state::get().min_ir, app_state::get().max_ir);
			//ImGui::SliderFloat("HSV", &cur_nvdi, min_nvdi, max_nvdi);

			ImGui::Text("Clipping Z");
			ImGui::SliderFloat("Min Z", &app_state::get().cur_min_clip[2], app_state::get().min_clip[2], app_state::get().max_clip[2]);
			ImGui::SliderFloat("Max Z", &app_state::get().cur_max_clip[2], app_state::get().min_clip[2], app_state::get().max_clip[2]);

			ImGui::Text("Clipping Y");
			ImGui::SliderFloat("clipping Y", &app_state::get().cur_max_clip[1], app_state::get().min_clip[1], app_state::get().max_clip[1]);

			ImGui::Text("Point Scale");
			ImGui::SliderFloat("scale", &app_state::get().point_scale, 0.001f, 0.02f);

			if (ImGui::Checkbox("Show IR data", &app_state::get().show_ir_only_data)) {
				app_state::get().invalidate_ui = true;
				printf(" Show IR data \n");
			};

			ImGui::Separator();
			if (app_state::get().playing)
				ImGui::Checkbox("Playing", &app_state::get().playing);
			else
				ImGui::Checkbox("Pause", &app_state::get().playing);

			ImGui::Checkbox("Debug", &app_state::get().bool_debug_verbose);
			ImGui::End();
		}

		if (app_state::get().show_debug_ground) {
			ImGui::Begin("Debug Ground", &app_state::get().show_debug_ground, flags);
			ImGui::Text("Rotation");
			ImGui::Checkbox("Override", &app_state::get().bool_override_rotation);
			ImGui::SliderFloat("RotX", &app_state::get().rot_x, -2 * M_PI, 2 * M_PI);
			ImGui::SliderFloat("RotY", &app_state::get().rot_y, -2 * M_PI, 2 * M_PI);
			ImGui::SliderFloat("RotZ", &app_state::get().rot_z, -2 * M_PI, 2 * M_PI);

			ImGui::Text("Degree");
			ImGui::SameLine(100); ImGui::Text("%2.2f", app_state::get().rot_x * 360 / (2 * M_PI));
			ImGui::SameLine(150); ImGui::Text("%2.2f", app_state::get().rot_y * 360 / (2 * M_PI));
			ImGui::SameLine(200); ImGui::Text("%2.2f", app_state::get().rot_z * 360 / (2 * M_PI));

			ImGui::Checkbox("Traslate", &app_state::get().bool_traslate);
			ImGui::End();
		}

		if (app_state::get().show_camera_window) {
			ImGui::Begin("Camera", &app_state::get().show_camera_window, flags);

			float eye3f[3] = { viewer.core.camera_eye.x(), viewer.core.camera_eye.y(), viewer.core.camera_eye.z() };
			ImGui::DragFloat3("camera_eye", eye3f, 0.01f, -10.0f, 10.0f);

			float cent3f[3] = { viewer.core.camera_center.x(), viewer.core.camera_center.y(), viewer.core.camera_center.z() };
			ImGui::DragFloat3("camera_center", cent3f, 0.01f, -10.0f, 10.0f);

			float tran3f[3] = { viewer.core.camera_translation.x(), viewer.core.camera_translation.y(), viewer.core.camera_translation.z() };
			ImGui::DragFloat3("camera_translation", tran3f, 0.01f, -10.0f, 10.0f);

			float quat4f[4] = { viewer.core.trackball_angle.vec()[0], viewer.core.trackball_angle.vec()[1],
				viewer.core.trackball_angle.vec()[2], viewer.core.trackball_angle.w() };

			ImGui::DragFloat4("trackball", quat4f, 0.01f, -2 * M_PI, 2 * M_PI);

			ImGui::SliderFloat("zoom", &viewer.core.camera_zoom, -0.1f, 10);

			ImGui::End();
		}

		if (app_state::get().show_plants_view) {
			ImGui::Begin("Plants View", &app_state::get().show_plants_view, flags);

			ImGui::Text("Clipping Z");
			ImGui::SliderFloat("Min Z", &app_state::get().plant_min_Z, -0.1f, 3);
			ImGui::SliderFloat("Max Z", &app_state::get().plant_max_Z, -0.1f, 3);

			ImGui::Text("Clipping Y");
			ImGui::SliderFloat("Min Y", &app_state::get().plant_min_Y, -0.1f, 1);
			ImGui::SliderFloat("Max Y", &app_state::get().plant_max_Y, -0.1f, 1);

			ImGui::End();
		}

		if (app_state::get().show_analysis) {
			ImGui::Begin("Analysis", &app_state::get().show_analysis, flags);

			if (ImGui::Checkbox("Show ground", &app_state::get().show_ground)) {
				printf(" Show ground\n"); app_state::get().invalidate_ui = true;
			}

			if (ImGui::Checkbox("Show plants", &app_state::get().show_plants)) {
				printf(" Show plants\n"); app_state::get().invalidate_ui = true;
			}

			if (ImGui::Checkbox("Extract plants", &app_state::get().bool_extract_plants)) {
				printf(" Extract plants\n"); app_state::get().invalidate_ui = true;
			};

			ImGui::Separator();

			if (ImGui::Checkbox("BBX", &app_state::get().show_bbx)) {
				printf(" Color cluster \n"); app_state::get().invalidate_ui = true;
			};

			if (ImGui::Checkbox("Raw Cloud", &app_state::get().bool_cloud_raw)) {
				app_state::get().invalidate_ui = true;
				printf(" Color cluster \n");
			};

			if (ImGui::Checkbox("Color cluster", &app_state::get().bool_color_cluster)) {
				app_state::get().invalidate_ui = true;
				printf(" Color cluster \n");
			};

			if (ImGui::Checkbox("Voxel Process", &app_state::get().bool_voxel_process)) {
				app_state::get().invalidate_ui = true;
				printf(" Voxel Process \n");
			};

			if (ImGui::Checkbox("Distance Filter", &app_state::get().bool_distance_filter)) {
				app_state::get().invalidate_ui = true;
				printf(" Distance filter \n");
			};

			if (ImGui::Checkbox("Ground plane", &app_state::get().show_ground_plane)) {
				app_state::get().invalidate_ui = true;
				printf(" Show ground plane \n");
			};

			if (ImGui::Checkbox("Ground alignment", &app_state::get().ground_alignment)) {
				app_state::get().invalidate_ui = true;
				printf(" Align ground \n");
			};

			/*
			if (ImGui::Checkbox("Ground alignment X", &app_state::get().ground_alignment_x)) {
				app_state::get().invalidate_ui = true;
				printf(" Align ground X \n");
			};

			if (ImGui::Checkbox("Ground alignment Y", &app_state::get().ground_alignment_y)) {
				app_state::get().invalidate_ui = true;
				printf(" Align ground Y \n");
			};
			*/

			if (ImGui::Checkbox("Show floor", &app_state::get().show_floor)) {
				app_state::get().invalidate_ui = true;
				printf(" Show floor \n");
			};

			ImGui::Separator();
			ImGui::Text("-- Cloud --");
			//ImGui::Text("Raw %d", cloud_raw->points.size());
			//ImGui::Text("Process %d", cloud->points.size());

			ImGui::End();
		}

		er::pipeline er_pipe = er::pipeline::get();
		er_pipe.render_ui();

		// We defer the file opening since we might break the interface by changing
		// state.

		if (open_file.size() > 0)
			app_state::get().set_current_file(open_file);
	};
#endif
}