<commit_before>//---------------------------------------------------------
// Copyright 2016 Ontario Institute for Cancer Research
// Written by Matei David (matei.david@oicr.on.ca)
//---------------------------------------------------------
//

//
// Getopt
//
#define SUBPROGRAM "extract"
#define LOG_FACILITY SUBPROGRAM

#include <iostream>
#include <sstream>
#include <getopt.h>

#include "nanopolish_read_db.h"
#include "nanopolish_extract.h"
#include "nanopolish_common.h"
#include "fs_support.hpp"
#include "logger.hpp"
#include "alg.hpp"

static const char *EXTRACT_VERSION_MESSAGE =
SUBPROGRAM " Version " PACKAGE_VERSION "\n"
"Written by Jared Simpson.\n"
"\n"
"Copyright 2015 Ontario Institute for Cancer Research\n";

static const char *EXTRACT_USAGE_MESSAGE =
"Usage: " PACKAGE_NAME " " SUBPROGRAM " [OPTIONS] <fast5|dir>...\n"
"Extract reads in fasta format\n"
"\n"
"      --help                           display this help and exit\n"
"      --version                        display version\n"
"  -v, --verbose                        display verbose output\n"
"  -r, --recurse                        recurse into subdirectories\n"
"  -q, --fastq                          extract fastq (default: fasta)\n"
"  -t, --type=TYPE                      read type: template, complement, 2d, 2d-or-template, any\n"
"                                         (default: 2d-or-template)\n"
"  -b, --basecaller=NAME[:VERSION]      consider only data produced by basecaller NAME,\n"
"                                         optionally with given exact VERSION\n"
"  -o, --output=FILE                    write output to FILE (default: stdout)\n"
"\nReport bugs to " PACKAGE_BUGREPORT "\n\n";

namespace opt
{
    static unsigned int verbose = 0;
    static bool recurse = false;
    static std::string read_type = "2d-or-template";
    static std::string basecaller_name;
    static std::string basecaller_version;
    static bool fastq = false;
    static std::string output_file;
    static std::deque< std::string > paths;
    static unsigned total_files_count = 0;
    static unsigned total_files_used_count = 0;
}
static std::ostream* os_p;

std::vector< std::pair< unsigned, std::string > >
get_preferred_basecall_groups(const fast5::File& f)
{
    bool have_2d = false;
    std::vector< std::pair< unsigned, std::string > > res;
    // check 2d
    if (opt::read_type == "any"
        or opt::read_type == "2d"
        or opt::read_type == "2d-or-template")
    {
        const auto& gr_l = f.get_basecall_strand_group_list(2);
        for (const auto& gr : gr_l)
        {
            auto bcd = f.get_basecall_group_description(gr);
            // Never use minknow basecalls
            if(bcd.name == "minknow") {
                continue;
            }

            if (not opt::basecaller_name.empty())
            {
                if ((bcd.name != opt::basecaller_name) or
                    (not opt::basecaller_version.empty() and
                     bcd.version != opt::basecaller_version))
                {
                    continue;
                }
            }

            if (f.have_basecall_fastq(2, gr)
                and f.have_basecall_events(0, gr)
                and f.have_basecall_events(1, gr))
            {
                have_2d = true;
                res.push_back(std::make_pair(2, gr));
                if (opt::read_type != "any")
                {
                    break;
                }
            }
        }
    }
    // check 1d
    for (unsigned st = 0; st < 2; ++st)
    {
        if (opt::read_type == "any"
            or (st == 0
                and (opt::read_type == "template"
                     or (not have_2d and opt::read_type == "2d-or-template")))
            or (st == 1
                and opt::read_type == "complement"))
        {
            const auto& gr_l = f.get_basecall_strand_group_list(st);
            for (const auto& gr : gr_l)
            {
                auto bcd = f.get_basecall_group_description(gr);
                // Never use minknow basecalls
                if(bcd.name == "minknow") {
                    continue;
                }

                if (not opt::basecaller_name.empty())
                {
                    if ((bcd.name != opt::basecaller_name) or
                        (not opt::basecaller_version.empty() and
                         bcd.version != opt::basecaller_version))
                    {
                        continue;
                    }
                }
                if (f.have_basecall_fastq(st, gr)
                    and f.have_basecall_events(st, gr))
                {
                    res.push_back(std::make_pair(st, gr));
                    if (opt::read_type != "any")
                    {
                        break;
                    }
                }
            }
        }
    }
    LOG(debug)
        << "preferred_groups: "
        << alg::os_join(res, ", ", [] (const decltype(res)::value_type& p) {
                std::ostringstream oss;
                oss << "(" << p.first << ":" << p.second << ")";
                return oss.str();
            })
        << "\n";
    return res;
} // get_preferred_basecall_groups

void process_file(const std::string& fn)
{
    LOG(debug) << fn << "\n";
    auto pos = fn.find_last_of('/');
    std::string base_fn = (pos != std::string::npos? fn.substr(pos + 1) : fn);
    if (base_fn.substr(base_fn.size() - 6) == ".fast5")
    {
        base_fn.resize(base_fn.size() - 6);
    }
    fast5::File f;
    do
    {
        try
        {
            // open file
            f.open(fn);
            ++opt::total_files_count;
            // get preferred basecall groups
            auto l = get_preferred_basecall_groups(f);
            if (l.empty())
            {
                LOG(info) << "file [" << fn << "]: no basecalling data suitable for nanoplish\n";
                return;
            }
            ++opt::total_files_used_count;
            const auto& p = l.front();
            // get and parse fastq
            auto fq = f.get_basecall_fastq(p.first, p.second);
            auto fq_a = f.split_fq(fq);
            // construct name
            std::string name;
            std::istringstream(fq_a[0]) >> name;
            std::replace(name.begin(), name.end(), ':', '_');
            name += ":" + p.second + ":";
            if (p.first == 0)
            {
                name += "template";
            }
            else if (p.first == 1)
            {
                name += "complement";
            }
            else
            {
                name += "2d";
            }
            if (not opt::fastq)
            {
                (*os_p)
                    << ">" << name << " " << base_fn << " " << fn << "\n"
                    << fq_a[1] << "\n";
            }
            else
            {
                (*os_p)
                    << "@" << name << " " << base_fn << " " << fn << "\n"
                    << fq_a[1] << "\n"
                    << "+" << fq_a[2] << "\n"
                    << fq_a[3] << "\n";
            }
        }
        catch (hdf5_tools::Exception& e)
        {
            LOG(warning) << fn << ": HDF5 error: " << e.what() << "\n";
        }
    } while (false);
} // process_file

void process_path(const std::string& path)
{
    LOG(info) << path << "\n";
    if (is_directory(path))
    {
        auto dir_list = list_directory(path);
        for (const auto& fn : dir_list)
        {
            if (fn == "." or fn == "..") continue;
            std::string full_fn = path + "/" + fn;
            if (is_directory(full_fn))
            {
                if (opt::recurse)
                {
                    opt::paths.push_back(full_fn);
                }
                else
                {
                    LOG(info) << "ignoring_subdir: " << full_fn << "\n";
                }
            }
            else if (fast5::File::is_valid_file(full_fn))
            {
                process_file(full_fn);
            }
            else
            {
                LOG(info) << "ignoring_file: " << full_fn << "\n";
            }
        }
    }
    else // not is_directory; must be a fast5 file
    {
        if (fast5::File::is_valid_file(path))
        {
            process_file(path);
        }
        else
        {
            LOG(error) << "path [" << path << "] is neither a fast5 file nor a directory\n";
            exit(EXIT_FAILURE);
        }
    }
} // process_path

static const char* shortopts = "vrqt:o:b:";

enum {
    OPT_HELP = 1,
    OPT_VERSION,
    OPT_LOG_LEVEL,
};

static const struct option longopts[] = {
    { "help",               no_argument,       NULL, OPT_HELP },
    { "version",            no_argument,       NULL, OPT_VERSION },
    { "log-level",          required_argument, NULL, OPT_LOG_LEVEL },
    { "verbose",            no_argument,       NULL, 'v' },
    { "recurse",            no_argument,       NULL, 'r' },
    { "fastq",              no_argument,       NULL, 'q' },
    { "type",               required_argument, NULL, 't' },
    { "output",             required_argument, NULL, 'o' },
    { "basecaller",         required_argument, NULL, 'b' },
    { NULL, 0, NULL, 0 }
};

void parse_extract_options(int argc, char** argv)
{
    bool die = false;
    std::vector< std::string> log_level;
    for (char c; (c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1;) {
        std::istringstream arg(optarg != NULL ? optarg : "");
        switch (c) {
            case OPT_HELP:
                std::cout << EXTRACT_USAGE_MESSAGE;
                exit(EXIT_SUCCESS);
            case OPT_VERSION:
                std::cout << EXTRACT_VERSION_MESSAGE;
                exit(EXIT_SUCCESS);
            case OPT_LOG_LEVEL:
                log_level.push_back(arg.str());
                break;
            case 'v': opt::verbose++; break;
            case 'r': opt::recurse = true; break;
            case 'q': opt::fastq = true; break;
            case 't': arg >> opt::read_type; break;
            case 'o': arg >> opt::output_file; break;
        case 'b':
            arg >> opt::basecaller_name;
            auto i = opt::basecaller_name.find(':');
            if (i != std::string::npos)
            {
                opt::basecaller_version = opt::basecaller_name.substr(i + 1);
                opt::basecaller_name.resize(i);
            }
            break;
        }
    }
    // set log levels
    auto default_level = (int)logger::warning + opt::verbose;
    logger::Logger::set_default_level(default_level);
    logger::Logger::set_levels_from_options(log_level, &std::clog);
    // parse paths to process
    while (optind < argc)
    {
        std::string path = argv[optind++];
        while (path.size() > 1 and path[path.size() - 1] == '/')
        {
            path.resize(path.size() - 1);
        }
        opt::paths.push_back(path);
    }
    if (opt::paths.empty())
    {
        std::cerr << SUBPROGRAM ": no paths to process\n";
        die = true;
    }
    // check read type
    if (not (opt::read_type == "template"
             or opt::read_type == "complement"
             or opt::read_type == "2d"
             or opt::read_type == "2d-or-template"
             or opt::read_type == "any"))
    {
        std::cerr << SUBPROGRAM ": invalid read type: " << opt::read_type << "\n";
        die = true;
    }
    // die if errors
    if (die)
    {
        std::cerr << "\n" << EXTRACT_USAGE_MESSAGE;
        exit(EXIT_FAILURE);
    }
    LOG(info) << "paths: " << alg::os_join(opt::paths, " ") << "\n";
    LOG(info) << "recurse: " << (opt::recurse? "yes" : "no") << "\n";
    LOG(info) << "read_type: " << opt::read_type << "\n";
    LOG(info) << "basecaller_name: " << opt::basecaller_name << "\n";
    LOG(info) << "basecaller_version: " << opt::basecaller_version << "\n";
}

int extract_main(int argc, char** argv)
{
    parse_extract_options(argc, argv);

    // Iterate over fast5 collection extracting the sequence reads
    // We do this in a block so the file is automatically closed
    // when ofs goes out of scope.
    {
        std::ofstream ofs;
        if (not opt::output_file.empty())
        {
            ofs.open(opt::output_file);
            os_p = &ofs;
        }
        else
        {
            os_p = &std::cout;
        }
        for (unsigned i = 0; i < opt::paths.size(); ++i)
        {
            process_path(opt::paths[i]);
        }
    }

    // Build the ReadDB from the output file
    ReadDB read_db;
    read_db.build(opt::output_file);

    std::clog << "[extract] found " << opt::total_files_count
              << " files, extracted " << opt::total_files_used_count
              << " reads\n";
    return 0;
}
<commit_msg>make the -o option to extract mandatory<commit_after>//---------------------------------------------------------
// Copyright 2016 Ontario Institute for Cancer Research
// Written by Matei David (matei.david@oicr.on.ca)
//---------------------------------------------------------
//

//
// Getopt
//
#define SUBPROGRAM "extract"
#define LOG_FACILITY SUBPROGRAM

#include <iostream>
#include <sstream>
#include <getopt.h>

#include "nanopolish_read_db.h"
#include "nanopolish_extract.h"
#include "nanopolish_common.h"
#include "fs_support.hpp"
#include "logger.hpp"
#include "alg.hpp"

static const char *EXTRACT_VERSION_MESSAGE =
SUBPROGRAM " Version " PACKAGE_VERSION "\n"
"Written by Jared Simpson.\n"
"\n"
"Copyright 2015 Ontario Institute for Cancer Research\n";

static const char *EXTRACT_USAGE_MESSAGE =
"Usage: " PACKAGE_NAME " " SUBPROGRAM " [OPTIONS] <fast5|dir>...\n"
"Extract reads in fasta format\n"
"\n"
"      --help                           display this help and exit\n"
"      --version                        display version\n"
"  -v, --verbose                        display verbose output\n"
"  -r, --recurse                        recurse into subdirectories\n"
"  -q, --fastq                          extract fastq (default: fasta)\n"
"  -t, --type=TYPE                      read type: template, complement, 2d, 2d-or-template, any\n"
"                                         (default: 2d-or-template)\n"
"  -b, --basecaller=NAME[:VERSION]      consider only data produced by basecaller NAME,\n"
"                                         optionally with given exact VERSION\n"
"  -o, --output=FILE                    write output to FILE\n"
"\nReport bugs to " PACKAGE_BUGREPORT "\n\n";

namespace opt
{
    static unsigned int verbose = 0;
    static bool recurse = false;
    static std::string read_type = "2d-or-template";
    static std::string basecaller_name;
    static std::string basecaller_version;
    static bool fastq = false;
    static std::string output_file;
    static std::deque< std::string > paths;
    static unsigned total_files_count = 0;
    static unsigned total_files_used_count = 0;
}
static std::ostream* os_p;

std::vector< std::pair< unsigned, std::string > >
get_preferred_basecall_groups(const fast5::File& f)
{
    bool have_2d = false;
    std::vector< std::pair< unsigned, std::string > > res;
    // check 2d
    if (opt::read_type == "any"
        or opt::read_type == "2d"
        or opt::read_type == "2d-or-template")
    {
        const auto& gr_l = f.get_basecall_strand_group_list(2);
        for (const auto& gr : gr_l)
        {
            auto bcd = f.get_basecall_group_description(gr);
            // Never use minknow basecalls
            if(bcd.name == "minknow") {
                continue;
            }

            if (not opt::basecaller_name.empty())
            {
                if ((bcd.name != opt::basecaller_name) or
                    (not opt::basecaller_version.empty() and
                     bcd.version != opt::basecaller_version))
                {
                    continue;
                }
            }

            if (f.have_basecall_fastq(2, gr)
                and f.have_basecall_events(0, gr)
                and f.have_basecall_events(1, gr))
            {
                have_2d = true;
                res.push_back(std::make_pair(2, gr));
                if (opt::read_type != "any")
                {
                    break;
                }
            }
        }
    }
    // check 1d
    for (unsigned st = 0; st < 2; ++st)
    {
        if (opt::read_type == "any"
            or (st == 0
                and (opt::read_type == "template"
                     or (not have_2d and opt::read_type == "2d-or-template")))
            or (st == 1
                and opt::read_type == "complement"))
        {
            const auto& gr_l = f.get_basecall_strand_group_list(st);
            for (const auto& gr : gr_l)
            {
                auto bcd = f.get_basecall_group_description(gr);
                // Never use minknow basecalls
                if(bcd.name == "minknow") {
                    continue;
                }

                if (not opt::basecaller_name.empty())
                {
                    if ((bcd.name != opt::basecaller_name) or
                        (not opt::basecaller_version.empty() and
                         bcd.version != opt::basecaller_version))
                    {
                        continue;
                    }
                }
                if (f.have_basecall_fastq(st, gr)
                    and f.have_basecall_events(st, gr))
                {
                    res.push_back(std::make_pair(st, gr));
                    if (opt::read_type != "any")
                    {
                        break;
                    }
                }
            }
        }
    }
    LOG(debug)
        << "preferred_groups: "
        << alg::os_join(res, ", ", [] (const decltype(res)::value_type& p) {
                std::ostringstream oss;
                oss << "(" << p.first << ":" << p.second << ")";
                return oss.str();
            })
        << "\n";
    return res;
} // get_preferred_basecall_groups

void process_file(const std::string& fn)
{
    LOG(debug) << fn << "\n";
    auto pos = fn.find_last_of('/');
    std::string base_fn = (pos != std::string::npos? fn.substr(pos + 1) : fn);
    if (base_fn.substr(base_fn.size() - 6) == ".fast5")
    {
        base_fn.resize(base_fn.size() - 6);
    }
    fast5::File f;
    do
    {
        try
        {
            // open file
            f.open(fn);
            ++opt::total_files_count;
            // get preferred basecall groups
            auto l = get_preferred_basecall_groups(f);
            if (l.empty())
            {
                LOG(info) << "file [" << fn << "]: no basecalling data suitable for nanoplish\n";
                return;
            }
            ++opt::total_files_used_count;
            const auto& p = l.front();
            // get and parse fastq
            auto fq = f.get_basecall_fastq(p.first, p.second);
            auto fq_a = f.split_fq(fq);
            // construct name
            std::string name;
            std::istringstream(fq_a[0]) >> name;
            std::replace(name.begin(), name.end(), ':', '_');
            name += ":" + p.second + ":";
            if (p.first == 0)
            {
                name += "template";
            }
            else if (p.first == 1)
            {
                name += "complement";
            }
            else
            {
                name += "2d";
            }
            if (not opt::fastq)
            {
                (*os_p)
                    << ">" << name << " " << base_fn << " " << fn << "\n"
                    << fq_a[1] << "\n";
            }
            else
            {
                (*os_p)
                    << "@" << name << " " << base_fn << " " << fn << "\n"
                    << fq_a[1] << "\n"
                    << "+" << fq_a[2] << "\n"
                    << fq_a[3] << "\n";
            }
        }
        catch (hdf5_tools::Exception& e)
        {
            LOG(warning) << fn << ": HDF5 error: " << e.what() << "\n";
        }
    } while (false);
} // process_file

void process_path(const std::string& path)
{
    LOG(info) << path << "\n";
    if (is_directory(path))
    {
        auto dir_list = list_directory(path);
        for (const auto& fn : dir_list)
        {
            if (fn == "." or fn == "..") continue;
            std::string full_fn = path + "/" + fn;
            if (is_directory(full_fn))
            {
                if (opt::recurse)
                {
                    opt::paths.push_back(full_fn);
                }
                else
                {
                    LOG(info) << "ignoring_subdir: " << full_fn << "\n";
                }
            }
            else if (fast5::File::is_valid_file(full_fn))
            {
                process_file(full_fn);
            }
            else
            {
                LOG(info) << "ignoring_file: " << full_fn << "\n";
            }
        }
    }
    else // not is_directory; must be a fast5 file
    {
        if (fast5::File::is_valid_file(path))
        {
            process_file(path);
        }
        else
        {
            LOG(error) << "path [" << path << "] is neither a fast5 file nor a directory\n";
            exit(EXIT_FAILURE);
        }
    }
} // process_path

static const char* shortopts = "vrqt:o:b:";

enum {
    OPT_HELP = 1,
    OPT_VERSION,
    OPT_LOG_LEVEL,
};

static const struct option longopts[] = {
    { "help",               no_argument,       NULL, OPT_HELP },
    { "version",            no_argument,       NULL, OPT_VERSION },
    { "log-level",          required_argument, NULL, OPT_LOG_LEVEL },
    { "verbose",            no_argument,       NULL, 'v' },
    { "recurse",            no_argument,       NULL, 'r' },
    { "fastq",              no_argument,       NULL, 'q' },
    { "type",               required_argument, NULL, 't' },
    { "output",             required_argument, NULL, 'o' },
    { "basecaller",         required_argument, NULL, 'b' },
    { NULL, 0, NULL, 0 }
};

void parse_extract_options(int argc, char** argv)
{
    bool die = false;
    std::vector< std::string> log_level;
    for (char c; (c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1;) {
        std::istringstream arg(optarg != NULL ? optarg : "");
        switch (c) {
            case OPT_HELP:
                std::cout << EXTRACT_USAGE_MESSAGE;
                exit(EXIT_SUCCESS);
            case OPT_VERSION:
                std::cout << EXTRACT_VERSION_MESSAGE;
                exit(EXIT_SUCCESS);
            case OPT_LOG_LEVEL:
                log_level.push_back(arg.str());
                break;
            case 'v': opt::verbose++; break;
            case 'r': opt::recurse = true; break;
            case 'q': opt::fastq = true; break;
            case 't': arg >> opt::read_type; break;
            case 'o': arg >> opt::output_file; break;
        case 'b':
            arg >> opt::basecaller_name;
            auto i = opt::basecaller_name.find(':');
            if (i != std::string::npos)
            {
                opt::basecaller_version = opt::basecaller_name.substr(i + 1);
                opt::basecaller_name.resize(i);
            }
            break;
        }
    }
    // set log levels
    auto default_level = (int)logger::warning + opt::verbose;
    logger::Logger::set_default_level(default_level);
    logger::Logger::set_levels_from_options(log_level, &std::clog);

    if(opt::output_file.empty()) {
        std::cerr << SUBPROGRAM ": an output file (-o) is required\n";
        die = true;
    }

    // parse paths to process
    while (optind < argc)
    {
        std::string path = argv[optind++];
        while (path.size() > 1 and path[path.size() - 1] == '/')
        {
            path.resize(path.size() - 1);
        }
        opt::paths.push_back(path);
    }

    if (opt::paths.empty())
    {
        std::cerr << SUBPROGRAM ": no paths to process\n";
        die = true;
    }

    // check read type
    if (not (opt::read_type == "template"
             or opt::read_type == "complement"
             or opt::read_type == "2d"
             or opt::read_type == "2d-or-template"
             or opt::read_type == "any"))
    {
        std::cerr << SUBPROGRAM ": invalid read type: " << opt::read_type << "\n";
        die = true;
    }

    // die if errors
    if (die)
    {
        std::cerr << "\n" << EXTRACT_USAGE_MESSAGE;
        exit(EXIT_FAILURE);
    }

    LOG(info) << "paths: " << alg::os_join(opt::paths, " ") << "\n";
    LOG(info) << "recurse: " << (opt::recurse? "yes" : "no") << "\n";
    LOG(info) << "read_type: " << opt::read_type << "\n";
    LOG(info) << "basecaller_name: " << opt::basecaller_name << "\n";
    LOG(info) << "basecaller_version: " << opt::basecaller_version << "\n";
}

int extract_main(int argc, char** argv)
{
    parse_extract_options(argc, argv);

    // Iterate over fast5 collection extracting the sequence reads
    // We do this in a block so the file is automatically closed
    // when ofs goes out of scope.
    {
        std::ofstream ofs;
        ofs.open(opt::output_file);
        os_p = &ofs;

        for (unsigned i = 0; i < opt::paths.size(); ++i)
        {
            process_path(opt::paths[i]);
        }
    }

    // Build the ReadDB from the output file
    ReadDB read_db;
    read_db.build(opt::output_file);
    read_db.save();

    std::clog << "[extract] found " << opt::total_files_count
              << " files, extracted " << opt::total_files_used_count
              << " reads\n";
    return 0;
}
<|endoftext|>


<commit_before>//
//  main.cpp
//  dixon
//
//  Created by Tobias Wood on 25/03/2014.
//
//

#include <time.h>
#include <getopt.h>
#include <iostream>
#include <atomic>
#include "Eigen/Dense"

#include "Nifti/Nifti.h"
#include "QUIT/Volume.h"
#include "QUIT/ThreadPool.h"

using namespace std;
using namespace Eigen;

//******************************************************************************
// Arguments / Usage
//******************************************************************************
const string usage {
"Usage is: dixon [options] magnitude phase \n\
\
Options:\n\
	--help, -h        : Print this message\n\
	--verbose, -v     : Print more information\n\
	--out, -o path    : Add a prefix to the output filenames\n"
};

static bool verbose = false;
static string outPrefix;
static struct option long_options[] =
{
	{"help", no_argument, 0, 'h'},
	{"verbose", no_argument, 0, 'v'},
	{"mask", required_argument, 0, 'm'},
	{"out", required_argument, 0, 'o'},
	{0, 0, 0, 0}
};
//******************************************************************************
// Main
//******************************************************************************
int main(int argc, char **argv)
{
	//**************************************************************************
	// Argument Processing
	//**************************************************************************
	Nifti maskFile;
	MultiArray<int8_t, 3> maskVol;
	int indexptr = 0, c;
	while ((c = getopt_long(argc, argv, "hvm:o:", long_options, &indexptr)) != -1) {
		switch (c) {
			case 'v': verbose = true; break;
			case 'm':
				cout << "Reading mask file " << optarg << endl;
				maskFile.open(optarg, Nifti::Mode::Read);
				maskVol.resize(maskFile.dims());
				maskFile.readVolumes(maskVol.begin(), maskVol.end(), 0, 1);
				break;
			case 'o':
				outPrefix = optarg;
				cout << "Output prefix will be: " << outPrefix << endl;
				break;
			case 'h':
			case '?': // getopt will print an error message
				exit(EXIT_FAILURE);
		}
	}
	//**************************************************************************
	#pragma mark Gather data
	//**************************************************************************
	if ((argc - optind) != 2) {
		cout << "Requires 1 magnitude file and 1 phase file with 3 echos each as input." << endl << usage << endl;
		exit(EXIT_FAILURE);
	}

	cout << "Opening magnitude file: " << argv[optind] << endl;
	Nifti inputFile;
	inputFile.open(argv[optind++], Nifti::Mode::Read);
	Nifti templateFile(inputFile, 1);
	MultiArray<float, 4> mag{inputFile.dims()};
	inputFile.readVolumes(mag.begin(), mag.end());
	inputFile.close();

	cout << "Opening phase file: " << argv[optind] << endl;
	inputFile.open(argv[optind++], Nifti::Mode::Read);
	MultiArray<float, 4> phase{inputFile.dims()};
	inputFile.readVolumes(phase.begin(), phase.end());
	if (!templateFile.matchesSpace(inputFile) || (maskFile.isOpen() && !templateFile.matchesSpace(maskFile))) {
		cerr << "Input file dimensions or orientations do not match." << endl;
		exit(EXIT_FAILURE);
	}
	inputFile.close();

	Nifti::ArrayXs dims = templateFile.dims().head(3);
	MultiArray<float, 3> Wv(dims), Fv(dims), Av(dims);
	//**************************************************************************
	// Do the fitting
	//**************************************************************************
	ThreadPool pool;
	cout << "Starting processing..." << endl;
	auto S0 = mag.slice<3>({0,0,0,0},{-1,-1,-1,0});
	auto S1 = mag.slice<3>({0,0,0,1},{-1,-1,-1,0});
	auto S2 = mag.slice<3>({0,0,0,2},{-1,-1,-1,0});
	auto phi0 = phase.slice<3>({0,0,0,0},{-1,-1,-1,0});
	auto phi1 = phase.slice<3>({0,0,0,1},{-1,-1,-1,0});
	auto phi2 = phase.slice<3>({0,0,0,2},{-1,-1,-1,0});
	for (size_t k = 0; k < S0.dims()[2]; k++) {
		clock_t loopStart;
		// Read in data
		if (verbose)
			cout << "Starting slice " << k << "..." << flush;
		loopStart = clock();
		atomic<int> voxCount{0};
		//cout << endl << I0s << endl << I1s << endl << I2s << endl;
		//cout << Ws << endl << Fs << endl << As << endl;
		function<void (const size_t)> processVox = [&] (const size_t j) {
			for (size_t i = 0; i < S0.dims()[0]; i++)
				if (!maskFile.isOpen() || maskVol[{i,j,k}]) {
					// From Ma et al JMR 1997
					Av[{i,j,k}] = sqrt(S2[{i,j,k}] / S0[{i,j,k}]);
					float phi = (phi2[{i,j,k}] - phi0[{i,j,k}]) / 2.;
					float psi = cos((phi1[{i,j,k}] - phi0[{i,j,k}]) - phi);
					float frac = S1[{i,j,k}] / sqrt(S0[{i,j,k}]*S2[{i,j,k}]);
					Wv[{i,j,k}] = (1 + psi * frac) * S0[{i,j,k}] / 2.;
					Fv[{i,j,k}] = (1 - psi * frac) * S0[{i,j,k}] / 2.;
				}
		};
		pool.for_loop(processVox, S0.dims()[1]);

		if (verbose) {
			clock_t loopEnd = clock();
			if (voxCount > 0)
				cout << voxCount << " unmasked voxels, CPU time per voxel was "
				          << ((loopEnd - loopStart) / ((float)voxCount * CLOCKS_PER_SEC)) << " s, ";
			cout << "finished." << endl;
		}
	}

	if (verbose)
		cout << "Writing results." << endl;
	templateFile.open(outPrefix + "W.nii.gz", Nifti::Mode::Write);
	templateFile.writeVolumes(Wv.begin(), Wv.end());
	templateFile.close();
	templateFile.open(outPrefix + "F.nii.gz", Nifti::Mode::Write);
	templateFile.writeVolumes(Fv.begin(), Fv.end());
	templateFile.close();
	templateFile.open(outPrefix + "A.nii.gz", Nifti::Mode::Write);
	templateFile.writeVolumes(Av.begin(), Av.end());
	templateFile.close();
	cout << "All done." << endl;
	exit(EXIT_SUCCESS);
}

<commit_msg>Updated to use complex division instead of phase subtraction, improves artefact suppresion.<commit_after>//
//  main.cpp
//  dixon
//
//  Created by Tobias Wood on 25/03/2014.
//
//

#include <time.h>
#include <getopt.h>
#include <iostream>
#include <atomic>
#include "Eigen/Dense"

#include "Nifti/Nifti.h"
#include "QUIT/Volume.h"
#include "QUIT/ThreadPool.h"

using namespace std;
using namespace Eigen;

//******************************************************************************
// Arguments / Usage
//******************************************************************************
const string usage {
"Usage is: dixon [options] input \n\
\
Input must be complex valued.\n\
Options:\n\
	--help, -h        : Print this message\n\
	--verbose, -v     : Print more information\n\
	--out, -o path    : Add a prefix to the output filenames\n"
};

static bool verbose = false;
static string outPrefix;
static struct option long_options[] =
{
	{"help", no_argument, 0, 'h'},
	{"verbose", no_argument, 0, 'v'},
	{"mask", required_argument, 0, 'm'},
	{"out", required_argument, 0, 'o'},
	{0, 0, 0, 0}
};
//******************************************************************************
// Main
//******************************************************************************
int main(int argc, char **argv)
{
	//**************************************************************************
	// Argument Processing
	//**************************************************************************
	Nifti maskFile;
	MultiArray<int8_t, 3> maskVol;
	int indexptr = 0, c;
	while ((c = getopt_long(argc, argv, "hvm:o:", long_options, &indexptr)) != -1) {
		switch (c) {
			case 'v': verbose = true; break;
			case 'm':
				cout << "Reading mask file " << optarg << endl;
				maskFile.open(optarg, Nifti::Mode::Read);
				maskVol.resize(maskFile.dims());
				maskFile.readVolumes(maskVol.begin(), maskVol.end(), 0, 1);
				break;
			case 'o':
				outPrefix = optarg;
				cout << "Output prefix will be: " << outPrefix << endl;
				break;
			case 'h':
			case '?': // getopt will print an error message
				exit(EXIT_FAILURE);
		}
	}
	//**************************************************************************
	#pragma mark Gather data
	//**************************************************************************
	if ((argc - optind) != 1) {
		cout << "Requires 1 complex-valued file with 3 echos each as input." << endl << usage << endl;
		exit(EXIT_FAILURE);
	}

	cout << "Opening magnitude file: " << argv[optind] << endl;
	Nifti inputFile;
	inputFile.open(argv[optind++], Nifti::Mode::Read);
	Nifti templateFile(inputFile, 1);
	MultiArray<complex<float>, 4> data{inputFile.dims()};
	inputFile.readVolumes(data.begin(), data.end());
	inputFile.close();
	if (maskFile.isOpen() && !templateFile.matchesSpace(maskFile)) {
		cerr << "Mask file dimensions or orientations do not match input." << endl;
		exit(EXIT_FAILURE);
	}

	Nifti::ArrayXs dims = templateFile.dims().head(3);
	MultiArray<float, 3> Wv(dims), Fv(dims), Av(dims);
	//**************************************************************************
	// Do the fitting
	//**************************************************************************
	ThreadPool pool;
	cout << "Starting processing..." << endl;
	auto S0 = data.slice<3>({0,0,0,0},{-1,-1,-1,0});
	auto S1 = data.slice<3>({0,0,0,1},{-1,-1,-1,0});
	auto S2 = data.slice<3>({0,0,0,2},{-1,-1,-1,0});
	//auto phi0 = phase.slice<3>({0,0,0,0},{-1,-1,-1,0});
	//auto phi1 = phase.slice<3>({0,0,0,1},{-1,-1,-1,0});
	//auto phi2 = phase.slice<3>({0,0,0,2},{-1,-1,-1,0});
	for (size_t k = 0; k < dims[2]; k++) {
		clock_t loopStart;
		// Read in data
		if (verbose)
			cout << "Starting slice " << k << "..." << flush;
		loopStart = clock();
		atomic<int> voxCount{0};
		//cout << endl << I0s << endl << I1s << endl << I2s << endl;
		//cout << Ws << endl << Fs << endl << As << endl;
		function<void (const size_t)> processVox = [&] (const size_t j) {
			for (size_t i = 0; i < dims[0]; i++)
				if (!maskFile.isOpen() || maskVol[{i,j,k}]) {
					// From Ma et al JMR 1997
					Av[{i,j,k}] = sqrt(abs(S2[{i,j,k}]) / abs(S0[{i,j,k}]));
					float phi = arg(S2[{i,j,k}] / S0[{i,j,k}]) / 2.;
					float psi = cos(arg(S1[{i,j,k}] / S0[{i,j,k}]) - phi);
					float frac = abs(S1[{i,j,k}]) / sqrt(abs(S0[{i,j,k}])*abs(S2[{i,j,k}]));
					Wv[{i,j,k}] = (1 + psi * frac) * abs(S0[{i,j,k}]) / 2.;
					Fv[{i,j,k}] = (1 - psi * frac) * abs(S0[{i,j,k}]) / 2.;
				}
		};
		pool.for_loop(processVox, dims[1]);

		if (verbose) {
			clock_t loopEnd = clock();
			if (voxCount > 0)
				cout << voxCount << " unmasked voxels, CPU time per voxel was "
				          << ((loopEnd - loopStart) / ((float)voxCount * CLOCKS_PER_SEC)) << " s, ";
			cout << "finished." << endl;
		}
	}

	if (verbose)
		cout << "Writing results." << endl;
	templateFile.setDatatype(Nifti::DataType::FLOAT32);
	templateFile.open(outPrefix + "W.nii.gz", Nifti::Mode::Write);
	templateFile.writeVolumes(Wv.begin(), Wv.end());
	templateFile.close();
	templateFile.open(outPrefix + "F.nii.gz", Nifti::Mode::Write);
	templateFile.writeVolumes(Fv.begin(), Fv.end());
	templateFile.close();
	templateFile.open(outPrefix + "A.nii.gz", Nifti::Mode::Write);
	templateFile.writeVolumes(Av.begin(), Av.end());
	templateFile.close();
	cout << "All done." << endl;
	exit(EXIT_SUCCESS);
}

<|endoftext|>


<commit_before>#include <QtCore/QCoreApplication>
#include <iostream>
#include <string>

bool isUniqueChar1(const std::string &str);
bool isUniqueChar2(const std::string &str);
bool isUniqueChar3(const std::string &str);

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    std::string str1 = "just one.";
    if ( isUniqueChar1(str1) )
    {
        std::cout << str1 << " has all unique characters." << std::endl;
    }
    else
    {
        std::cout << str1 << " hasn't all unique characters." << std::endl;
    }

    std::string str2 = "I am hahaya.";
    if ( isUniqueChar2(str2) )
    {
        std::cout << str2 << " has all unique characters." << std::endl;
    }
    else
    {
        std::cout << str2 << " hasn't all unique characters." << std::endl;
    }

    std::string str3 = "abcdefg";
    if ( isUniqueChar3(str3) )
    {
        std::cout << str3 << " has all unique characters." << std::endl;
    }
    else
    {
        std::cout << str3 << " hasn't all unique characters." << std::endl;
    }

    return a.exec();
}

//stringеַȫΪASCIIʱ(ⷨһ)
bool isUniqueChar1(const std::string &str)
{
    bool char_set[256];
    memset( char_set, 0, sizeof(char_set) ); //뽫λófalse

    for ( unsigned int i = 0; i < str.length(); ++i )
    {
        int value = (int)str.at(i);
        if ( char_set[value] )
        {
            return false;
        }
        char_set[value] = true;
    }
    return true;
}

//stringеַȫΪASCIIʱ(ⷨ)
bool isUniqueChar2(const std::string &str)
{
    int checker[8];
    memset(checker, 0, sizeof(checker)); //뽫λó0

    for ( unsigned int i = 0; i < str.length(); ++i )
    {
        int value = (int)str.at(i);
        int row = value/32;
        int colunm = value%32;
        if ( checker[row] & (1<<colunm) )
        {
            return false;
        }
        checker[row] |= (1<<colunm);
    }
    return true;
}

//stringеַȫΪĸʱ(ֻ'a' - 'z')
bool isUniqueChar3(const std::string &str)
{
    int checker = 0;    //뽫λó0

    for ( unsigned int i = 0; i < str.length(); ++i )
    {
        int value = (int)(str.at(i) - 'a' );
        if ( checker & (1<<value) )
        {
            return false;
        }
        checker |= (1<<value);
    }
    return true;
}
<commit_msg>add solution for qution 1.1<commit_after>#include <iostream>
#include <string>

bool isUniqueChar1(const std::string &str);
bool isUniqueChar2(const std::string &str);
bool isUniqueChar3(const std::string &str);

int main(int argc, char *argv[])
{
    std::string str1 = "just one.";
    if ( isUniqueChar1(str1) )
    {
        std::cout << str1 << " has all unique characters." << std::endl;
    }
    else
    {
        std::cout << str1 << " hasn't all unique characters." << std::endl;
    }

    std::string str2 = "I am hahaya.";
    if ( isUniqueChar2(str2) )
    {
        std::cout << str2 << " has all unique characters." << std::endl;
    }
    else
    {
        std::cout << str2 << " hasn't all unique characters." << std::endl;
    }

    std::string str3 = "abcdefg";
    if ( isUniqueChar3(str3) )
    {
        std::cout << str3 << " has all unique characters." << std::endl;
    }
    else
    {
        std::cout << str3 << " hasn't all unique characters." << std::endl;
    }

    return 0;
}

//stringеַȫΪASCIIʱ(ⷨһ)
bool isUniqueChar1(const std::string &str)
{
    bool char_set[256];
    memset( char_set, 0, sizeof(char_set) ); //뽫λófalse

    for ( unsigned int i = 0; i < str.length(); ++i )
    {
        int value = (int)str.at(i);
        if ( char_set[value] )
        {
            return false;
        }
        char_set[value] = true;
    }
    return true;
}

//stringеַȫΪASCIIʱ(ⷨ)
bool isUniqueChar2(const std::string &str)
{
    int checker[8];
    memset(checker, 0, sizeof(checker)); //뽫λó0

    for ( unsigned int i = 0; i < str.length(); ++i )
    {
        int value = (int)str.at(i);
        int row = value/32;
        int colunm = value%32;
        if ( checker[row] & (1<<colunm) )
        {
            return false;
        }
        checker[row] |= (1<<colunm);
    }
    return true;
}

//stringеַȫΪĸʱ(ֻ'a' - 'z')
bool isUniqueChar3(const std::string &str)
{
    int checker = 0;    //뽫λó0

    for ( unsigned int i = 0; i < str.length(); ++i )
    {
        int value = (int)(str.at(i) - 'a' );
        if ( checker & (1<<value) )
        {
            return false;
        }
        checker |= (1<<value);
    }
    return true;
}
<|endoftext|>


<commit_before>/*
 * Arm.cpp
 *
 *  Created on: Jan 13, 2011
 *      Author: Nick Alberts
 */

#include "Arm.h"
#include "diag/diagnostics_center.h"
#include "Math.h"
/**
 * This function runs in the control thread, and continually sets the motors to the correct speed.
 * The speed is determined by the difference in angle divided by a constant.
 */
void Arm::control_arm_motor( void *object )
{
	Arm *instance = (Arm *) object;
	instance->upperArmAngle = instance->GetTilt();

	// Runs when the difference in angles is large enough
	//TODO: fix kCloseEnough with real value
	while ( fabs( instance->upperArmAngle - instance->arm_control_angle ) < kCloseEnough )
	{
		// Conversion factor is from clicks to angles and k is to fix the angle
		instance->upperArmAngle = instance->GetTilt();
		instance->armMotor.Set( ( instance->arm_control_angle - instance->upperArmAngle ) / 500.0 );
	}

	instance->armMotor.Set( 0.0 );
}

// TODO: needs actual arguments and ports
/**
 * constructor for arm class
 */
Arm::Arm():
	armMotor( 4 ),
	armSolenoidRaise( 1 ),
	armSolenoidLower( 2 ),
	armEncoder( 4,5 ),
	arm_control_thread(new nr::conc::thread::function_entry( Arm::control_arm_motor ) )

{
	lowerArm = false;

	nr::diag::diagnostics_center& diag = nr::diag::diagnostics_center::get_shared_instance();
	diag.register_device( new nr::diag::observable_speed_controller( armMotor ), "Arm Motor" );
	diag.register_device( new nr::diag::observable_encoder( armEncoder ), "Arm Encoder" );
}
/**
 * THis function sets the lower arm to a boolean position value:true corresponds to raised and false corresponds to lower
 */
void Arm::SetLowerArm( bool position )
{

	if ( (! lowerArm && position) )
	{
		//fires the arm solenoid
		armSolenoidRaise.Set( true );
		armSolenoidLower.Set( false );
		lowerArm=true;
	}

	else if ( lowerArm && ! position )
	{
		armSolenoidLower.Set( true );
		armSolenoidRaise.Set( false );
		lowerArm=false;
	}
}

void Arm::SetUpperArm( double angle )
{
	// TODO: Constants and real angle factors
	if ( ! arm_control_mutex.trylock() )
	{
		arm_control_thread.Stop();
	}
	arm_control_thread.Start( (void *) this );
	arm_control_angle = angle;
}

// TODO: fix this for real values with actual correction value
double Arm::GetTilt()
{
	return armEncoder.Get();
}
<commit_msg>Case-sensitivity in includes\!<commit_after>/*
 * Arm.cpp
 *
 *  Created on: Jan 13, 2011
 *      Author: Nick Alberts
 */

#include "Arm.h"
#include "diag/diagnostics_center.h"
#include <math.h>
/**
 * This function runs in the control thread, and continually sets the motors to the correct speed.
 * The speed is determined by the difference in angle divided by a constant.
 */
void Arm::control_arm_motor( void *object )
{
	Arm *instance = (Arm *) object;
	instance->upperArmAngle = instance->GetTilt();

	// Runs when the difference in angles is large enough
	//TODO: fix kCloseEnough with real value
	while ( fabs( instance->upperArmAngle - instance->arm_control_angle ) < kCloseEnough )
	{
		// Conversion factor is from clicks to angles and k is to fix the angle
		instance->upperArmAngle = instance->GetTilt();
		instance->armMotor.Set( ( instance->arm_control_angle - instance->upperArmAngle ) / 500.0 );
	}

	instance->armMotor.Set( 0.0 );
}

// TODO: needs actual arguments and ports
/**
 * constructor for arm class
 */
Arm::Arm():
	armMotor( 4 ),
	armSolenoidRaise( 1 ),
	armSolenoidLower( 2 ),
	armEncoder( 4,5 ),
	arm_control_thread(new nr::conc::thread::function_entry( Arm::control_arm_motor ) )

{
	lowerArm = false;

	nr::diag::diagnostics_center& diag = nr::diag::diagnostics_center::get_shared_instance();
	diag.register_device( new nr::diag::observable_speed_controller( armMotor ), "Arm Motor" );
	diag.register_device( new nr::diag::observable_encoder( armEncoder ), "Arm Encoder" );
}
/**
 * THis function sets the lower arm to a boolean position value:true corresponds to raised and false corresponds to lower
 */
void Arm::SetLowerArm( bool position )
{

	if ( (! lowerArm && position) )
	{
		//fires the arm solenoid
		armSolenoidRaise.Set( true );
		armSolenoidLower.Set( false );
		lowerArm=true;
	}

	else if ( lowerArm && ! position )
	{
		armSolenoidLower.Set( true );
		armSolenoidRaise.Set( false );
		lowerArm=false;
	}
}

void Arm::SetUpperArm( double angle )
{
	// TODO: Constants and real angle factors
	if ( ! arm_control_mutex.trylock() )
	{
		arm_control_thread.Stop();
	}
	arm_control_thread.Start( (void *) this );
	arm_control_angle = angle;
}

// TODO: fix this for real values with actual correction value
double Arm::GetTilt()
{
	return armEncoder.Get();
}
<|endoftext|>


<commit_before>//*****************************************************************************
// Copyright 2017-2019 Intel Corporation
//
// 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 "ngraph/distributed.hpp"
#include "ngraph/distributed/mlsl.hpp"
#include "ngraph/distributed/null.hpp"
#include "ngraph/distributed/open_mpi.hpp"
#include "ngraph/log.hpp"

using namespace ngraph;

std::ostream& reduction::operator<<(std::ostream& out, const reduction::Type& obj)
{
#if !(defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ == 8))
#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Wswitch"
#pragma GCC diagnostic error "-Wswitch-enum"
#endif
    switch (obj)
    {
    case reduction::Type::SUM: out << "SUM"; break;
    case reduction::Type::PROD: out << "PROD"; break;
    case reduction::Type::MIN: out << "MIN"; break;
    case reduction::Type::MAX: out << "MAX"; break;
    }
#if !(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 8)
#pragma GCC diagnostic pop
#endif
    return out;
};

static std::unique_ptr<DistributedInterface> s_distributed_interface;

void ngraph::set_distributed_interface(std::unique_ptr<DistributedInterface> distributed_interface)
{
    NGRAPH_DEBUG << "Setting distributed interfsce to: " << distributed_interface->get_name();
    s_distributed_interface = std::move(distributed_interface);
}

DistributedInterface* ngraph::get_distributed_interface()
{
    if (0 == s_distributed_interface)
    {
#ifdef NGRAPH_DISTRIBUTED_OMPI_ENABLE
        set_distributed_interface(std::unique_ptr<DistributedInterface>(
            new ngraph::distributed::OpenMPIDistributedInterface()));
#elif defined(NGRAPH_DISTRIBUTED_MLSL_ENABLE)
        set_distributed_interface(std::unique_ptr<DistributedInterface>(
            new ngraph::distributed::MLSLDistributedInterface()));
#else
        set_distributed_interface(std::unique_ptr<DistributedInterface>(
            new ngraph::distributed::NullDistributedInterface()));
#endif
    }
    return s_distributed_interface.get();
}
<commit_msg>fix spelling error<commit_after>//*****************************************************************************
// Copyright 2017-2019 Intel Corporation
//
// 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 "ngraph/distributed.hpp"
#include "ngraph/distributed/mlsl.hpp"
#include "ngraph/distributed/null.hpp"
#include "ngraph/distributed/open_mpi.hpp"
#include "ngraph/log.hpp"

using namespace ngraph;

std::ostream& reduction::operator<<(std::ostream& out, const reduction::Type& obj)
{
#if !(defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ == 8))
#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Wswitch"
#pragma GCC diagnostic error "-Wswitch-enum"
#endif
    switch (obj)
    {
    case reduction::Type::SUM: out << "SUM"; break;
    case reduction::Type::PROD: out << "PROD"; break;
    case reduction::Type::MIN: out << "MIN"; break;
    case reduction::Type::MAX: out << "MAX"; break;
    }
#if !(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 8)
#pragma GCC diagnostic pop
#endif
    return out;
};

static std::unique_ptr<DistributedInterface> s_distributed_interface;

void ngraph::set_distributed_interface(std::unique_ptr<DistributedInterface> distributed_interface)
{
    NGRAPH_DEBUG << "Setting distributed interface to: " << distributed_interface->get_name();
    s_distributed_interface = std::move(distributed_interface);
}

DistributedInterface* ngraph::get_distributed_interface()
{
    if (0 == s_distributed_interface)
    {
#ifdef NGRAPH_DISTRIBUTED_OMPI_ENABLE
        set_distributed_interface(std::unique_ptr<DistributedInterface>(
            new ngraph::distributed::OpenMPIDistributedInterface()));
#elif defined(NGRAPH_DISTRIBUTED_MLSL_ENABLE)
        set_distributed_interface(std::unique_ptr<DistributedInterface>(
            new ngraph::distributed::MLSLDistributedInterface()));
#else
        set_distributed_interface(std::unique_ptr<DistributedInterface>(
            new ngraph::distributed::NullDistributedInterface()));
#endif
    }
    return s_distributed_interface.get();
}
<|endoftext|>


<commit_before>#include "LED.h"

#define NUM_OF_LED 2
#define NUM_OF_PINS 2

Adafruit_NeoPixel AN_LED = Adafruit_NeoPixel(NUM_OF_LED, NUM_OF_PINS, NEO_RGB + NEO_KHZ800);

// must initialize with begin() and show()

// void Dot::debug_show() {
//   printf("(%d, %d)\n", this->x, this->y);
// };

bool LEDClass::on(){
  AN_LED.setPixelColor(led_num_, red_, green_, blue_);
  AN_LED.show();

  status_ = true;

  return status_;
}

bool LEDClass::off(){
  AN_LED.setPixelColor(led_num_, 0x000000);
  status_ = false;

  return status_;
}

// bool LEDClass::getStatus(){
//   return status_;
// }
//
// void LEDClass::color(float hue){
//   color(led_num_, hue);
//
//
// }
//
// void LEDClass::color(uint8_t r, uint8_t g, uint8_t b){
//   red_ = r;
//   green_ = g;
//   blue_ = b;
//
//   SetHLSFromRGB();
// }
//
// void brightness(double brightness){
//   brightness_ = brightness;
//
//   SetRGBFromHLS();
// }
//
// void saturation(double saturation){
//
// }
//
// void LEDClass::randomcolor(){
//
// }
//
// void LEDClass::SetHLSFromRGB(){
//
// }
//
// void LEDClass::SetRGBFromHLS(){
//   double max, min;
//   if (brightness_ < 0.5) {
//     max = 255 * l * (saturation_ + 1);
//     min = 255 * l * (s - 1);
//   } else {
//     max = 255 * (l + (1 - l) * s);
//     min = 255 * (l - (1 - l) * s);
//   }
//
//   if (h < 60) {
//     red_ = max;
//     green_ = (h / 60) * (max - min) + min;
//     blue_ = min;
//   } else if (h < 120) {
//     red_ = ((120 - h) / 60) * (max - min) + min;
//     green_ = max;
//     blue_ = min;
//   } else if (h < 180) {
//     red_ = min;
//     green_ = max;
//     blue_ = ((h - 120) / 60) * (max - min) + min;
//   } else if (h < 240) {
//     red_ = min;
//     green_ = ((240 - h) / 60) * (max - min) + min;
//     blue_ = max;
//   } else if (h < 300) {
//     red_ = ((h - 240) / 60) * (max - min) + min;
//     green_ = min;
//     blue_ = max;
//   } else {
//     red_ = max;
//     green_ = min;
//     blue_ = ((360-h) / 60) * (max - min) + min;
//   }
// }
//
//
//
//
//
// void color_update_hsl(int led) {
//   double s = led_saturation[led-1];
//   double l = led_brightness[led-1];
//   double h = led_hue[led-1] * 360; // 0 - 360
//
//   double max, min;
//   if (l < 0.5) {
//     max = 255 * l * (s + 1);
//     min = 255 * l * (s - 1);
//   } else {
//     max = 255 * (l + (1 - l) * s);
//     min = 255 * (l - (1 - l) * s);
//   }
//
//   uint8_t r, g, b;
//
//   if (h < 60) {
//     r = max;
//     g = (h / 60) * (max - min) + min;
//     b = min;
//   } else if (h < 120) {
//     r = ((120 - h) / 60) * (max - min) + min;
//     g = max;
//     b = min;
//   } else if (h < 180) {
//     r = min;
//     g = max;
//     b = ((h - 120) / 60) * (max - min) + min;
//   } else if (h < 240) {
//     r = min;
//     g = ((240 - h) / 60) * (max - min) + min;
//     b = max;
//   } else if (h < 300) {
//     r = ((h - 240) / 60) * (max - min) + min;
//     g = min;
//     b = max;
//   } else {
//     r = max;
//     g = min;
//     b = ((360-h) / 60) * (max - min) + min;
//   }
//
//   uint32_t rgb = Adafruit_NeoPixel::Color(r, g, b);
//   // Serial.println(rgb, HEX);
//   led_colors[led-1] = rgb;
//
// }<commit_msg>remove old function<commit_after>#include "LED.h"

#define NUM_OF_LED 2
#define NUM_OF_PINS 2

Adafruit_NeoPixel AN_LED = Adafruit_NeoPixel(NUM_OF_LED, NUM_OF_PINS, NEO_RGB + NEO_KHZ800);

// must initialize with begin() and show()

// void Dot::debug_show() {
//   printf("(%d, %d)\n", this->x, this->y);
// };

bool LEDClass::on(){
  AN_LED.setPixelColor(led_num_, red_, green_, blue_);
  AN_LED.show();

  status_ = true;

  return status_;
}

bool LEDClass::off(){
  AN_LED.setPixelColor(led_num_, 0x000000);
  status_ = false;

  return status_;
}

// bool LEDClass::getStatus(){
//   return status_;
// }
//
// void LEDClass::color(float hue){
//   color(led_num_, hue);
//
//
// }
//
// void LEDClass::color(uint8_t r, uint8_t g, uint8_t b){
//   red_ = r;
//   green_ = g;
//   blue_ = b;
//
//   SetHLSFromRGB();
// }
//
// void brightness(double brightness){
//   brightness_ = brightness;
//
//   SetRGBFromHLS();
// }
//
// void saturation(double saturation){
//
// }
//
// void LEDClass::randomcolor(){
//
// }
//
// void LEDClass::SetHLSFromRGB(){
//
// }
//
// void LEDClass::SetRGBFromHLS(){
//   double max, min;
//   if (brightness_ < 0.5) {
//     max = 255 * l * (saturation_ + 1);
//     min = 255 * l * (s - 1);
//   } else {
//     max = 255 * (l + (1 - l) * s);
//     min = 255 * (l - (1 - l) * s);
//   }
//
//   if (h < 60) {
//     red_ = max;
//     green_ = (h / 60) * (max - min) + min;
//     blue_ = min;
//   } else if (h < 120) {
//     red_ = ((120 - h) / 60) * (max - min) + min;
//     green_ = max;
//     blue_ = min;
//   } else if (h < 180) {
//     red_ = min;
//     green_ = max;
//     blue_ = ((h - 120) / 60) * (max - min) + min;
//   } else if (h < 240) {
//     red_ = min;
//     green_ = ((240 - h) / 60) * (max - min) + min;
//     blue_ = max;
//   } else if (h < 300) {
//     red_ = ((h - 240) / 60) * (max - min) + min;
//     green_ = min;
//     blue_ = max;
//   } else {
//     red_ = max;
//     green_ = min;
//     blue_ = ((360-h) / 60) * (max - min) + min;
//   }
// }
//
<|endoftext|>


<commit_before>/**
 ** \file object/object-class.cc
 ** \brief Creation of the URBI object object.
 */

//#define ENABLE_DEBUG_TRACES

#include <boost/bind.hpp>
#include <boost/format.hpp>

#include <libport/compiler.hh>
#include <libport/containers.hh>
#include <libport/escape.hh>
#include <libport/foreach.hh>
#include <libport/tokenizer.hh>

#include <kernel/uconnection.hh>
#include <kernel/userver.hh>
#include <object/cxx-primitive.hh>
#include <object/float.hh>
#include <object/global.hh>
#include <object/list.hh>
#include <object/object.hh>
#include <object/string.hh>
#include <object/symbols.hh>
#include <runner/raise.hh>
#include <runner/runner.hh>

namespace object
{
  /*--------------------.
  | Object primitives.  |
  `--------------------*/

  static rObject
  object_class_clone (const objects_type& args)
  {
    check_arg_count(args.size() - 1, 0);

    return args[0]->clone();
  }

  static rObject
  object_class_init (const objects_type& args)
  {
    check_arg_count(args.size() - 1, 0);
    return args[0];
  }

  /// Send dumped self on the connection.
  /// args[1], if present, can be the tag to use.
  static rObject
  object_class_dump (const objects_type& args)
  {
    runner::Runner& r = ::kernel::urbiserver->getCurrentRunner();

    check_arg_count(args.size() - 1, 1, 2);

    // Second argument is max depth.
    int depth_max = 0;
    if (args.size() >= 2)
    {
      type_check<Float>(args[1]);
      const rFloat& arg1 = args[1]->as<Float>();
      try
      {
	depth_max = libport::numeric_cast<int>(arg1->value_get());
      }
      catch (libport::bad_numeric_cast& ue)
      {
	runner::raise_bad_integer_error(arg1->value_get());
      }
    }

    // Third argument is the tag name.
    std::string tag;
    if (args.size() >= 3)
    {
      type_check<String>(args[2]);
      const rString& arg2 = args[2].unsafe_cast<String>();
      assert(arg2);
      tag = arg2->value_get();
    }

    std::ostringstream os;
    args[0]->dump(os, depth_max);
    //for now our best choice is to dump line by line in "system" messages.
    const std::string stream = os.str();
    boost::tokenizer< boost::char_separator<char> > tok =
      libport::make_tokenizer(stream, "\n");
    const std::string system_header("*** ");
    foreach(const std::string& line, tok)
      r.send_message(tag, system_header+line);
    return void_class;
  }

  /// Return the address of an object as a number, mostly
  /// for debugging purpose.
  static rObject
  object_class_uid (const objects_type& args)
  {
    static boost::format uid("0x%x");
    check_arg_count(args.size() - 1, 0);
    return
      new String(str(uid % reinterpret_cast<long long>(args[0].get())));
  }

  /// Structural equality
  static rObject
  object_class_EQ_EQ(const objects_type& args)
  {
    // Unless overridden, structural equality is physical equality.
    check_arg_count(args.size() - 1, 1);
    return args[0]->call(SYMBOL(EQ_EQ_EQ), args[1]);
  }

  /// Physical equality
  static rObject
  object_class_EQ_EQ_EQ(const objects_type& args)
  {
    check_arg_count(args.size() - 1, 1);
    return to_boolean(args[0] == args[1]);
  }

  static rObject
  object_class_apply(const objects_type& args)
  {
    check_arg_count(args.size() - 1, 1);
    type_check<List>(args[1]);
    const rList& arg1 = args[1]->as<List>();
    if (arg1->value_get ().size () != 1
        || arg1->value_get().front() != args[0])
      RAISE("first argument must be `[this]'");
    return arg1->value_get().front();
  }

  static rObject
  object_class_callMessage (const objects_type& args)
  {
    runner::Runner& r = ::kernel::urbiserver->getCurrentRunner();

    check_arg_count(args.size() - 1, 1);
    // We need to set the 'code' slot: make a copy of the call message.
    rObject call_message = args[1]->clone();
    const rObject& message = call_message->slot_get(SYMBOL(message));
    type_check<String>(message);
    const libport::Symbol msg(message->as<String>()->value_get());
    const rObject& target = args[0];
    const rObject& code = target->slot_get(msg);
    call_message->slot_update(SYMBOL(code), code);
    call_message->slot_update(SYMBOL(target), target);
    // FIXME: Sanity checks on the call message are probably required
    return r.apply_call_message(code, msg, call_message);
  }

  /*---------.
  | Protos.  |
  `---------*/

  /// Adding or removing protos. \a Verb is "add" or "remove".
#define CHANGE_PARENTS(Verb)                                            \
  static rObject                                                        \
  object_class_ ## Verb ## Proto (                     \
                                  const objects_type& args)                   \
  {									\
    check_arg_count(args.size() - 1, 1);                                \
    args[0]->proto_ ## Verb (args[1]);					\
    return args[0];							\
  }

  /// Add a proto.
  CHANGE_PARENTS(add);
  /// Remove a proto.
  CHANGE_PARENTS(remove);
#undef CHANGE_PARENTS

  /// Get protos' list.
  static rObject
  object_class_protos (const objects_type& args)
  {
    check_arg_count(args.size() - 1, 0);
    return args[0]->urbi_protos_get ();
  }

  /// Add a prototype
  static bool
  proto_add(List::value_type& protos, const rObject& proto)
  {
    protos.push_back(proto);
    return false;
  }

  /// Recursively get protos list
  static rObject
  object_class_allProtos(const objects_type& args)
  {
    check_arg_count(args.size() - 1, 0);
    List::value_type res;
    for_all_protos(args[0], boost::bind(&proto_add, boost::ref(res), _1));
    return new List(res);
  }

  /*--------.
  | Slots.  |
  `--------*/

  template <typename F>
  static inline void for_all_slot_names(const rObject& o, F f)
  {
    for (Object::slots_implem::iterator slot = o->slots_get().begin(o.get());
         slot != o->slots_get().end(o.get());
         ++slot)
      f(slot->first.second);
  }

  static void
  add_as_rString(List::value_type& l, libport::Symbol slot_name)
  {
    l.push_back(new String(slot_name));
  }

  /// List of slot names.
  static rObject
  object_class_slotNames (const objects_type& args)
  {
    check_arg_count(args.size() - 1, 0);
    const rObject& obj = args[0];

    List::value_type l;
    for_all_slot_names(obj, boost::bind(&add_as_rString, boost::ref(l), _1));
    return new List(l);
  }

  /// Recursive list of slot names.

  static void
  maybe_add(std::vector<libport::Symbol>& control, List::value_type& l,
	    libport::Symbol slot_name)
  {
    if (!libport::has(control, slot_name))
    {
      control.push_back(slot_name);
      l.push_back(new String(slot_name));
    }
  }

  static rObject
  object_class_allSlotNames(const objects_type& args)
  {
    check_arg_count(args.size() - 1, 0);
    std::vector<libport::Symbol> slot_names;
    List::value_type res;
    objects_type protos =
      object_class_allProtos(args)->as<List>()->value_get();
    foreach (const rObject& proto, protos)
    {
      for_all_slot_names(proto, boost::bind(&maybe_add,
					    boost::ref(slot_names),
					    boost::ref(res),
					    _1));
    }
    return new List(res);
  }

  static bool
  object_class_isA(rObject self, rObject proto)
  {
    return is_a(self, proto);
  }

  static bool
  object_class_hasLocalSlot(rObject self, const libport::Symbol& slot)
  {
    return self->local_slot_get(slot);
  }

  void
  object_class_initialize ()
  {
    Object::proto->slot_set(SYMBOL(isA),
                           make_primitive(object_class_isA));
    Object::proto->slot_set(SYMBOL(hasLocalSlot),
                            make_primitive(&object_class_hasLocalSlot));
    /// \a Call gives the name of the C++ function, and \a Name that in Urbi.
#define DECLARE(Name)                                                   \
    Object::proto->slot_set(SYMBOL(Name), new Primitive(object_class_##Name), true)

    DECLARE(addProto);
    DECLARE(allProtos);
    DECLARE(allSlotNames);
    DECLARE(apply);
    DECLARE(callMessage);
    DECLARE(clone);
    DECLARE(dump);
    DECLARE(init);
    DECLARE(EQ_EQ_EQ);
    DECLARE(protos);
    DECLARE(removeProto);
    DECLARE(EQ_EQ);
    DECLARE(slotNames);
    DECLARE(uid);
#undef DECLARE

#define DECLARE(Name, Code)                                     \
    Object::proto->slot_set(SYMBOL(Name), make_primitive(Code))

    DECLARE(createSlot, &Object::urbi_createSlot);
    DECLARE(getProperty, &Object::property_get);
    DECLARE(getSlot, &Object::urbi_getSlot);
    DECLARE(hasProperty, &Object::property_has);
    DECLARE(hasSlot, &Object::slot_has);
    DECLARE(locateSlot, &Object::urbi_locateSlot);
    DECLARE(setProperty, &Object::property_set);
    DECLARE(setSlot, &Object::urbi_setSlot);
    DECLARE(setConstSlot, &Object::urbi_setConstSlot);
    DECLARE(removeProperty, &Object::property_remove);
    DECLARE(removeSlot, &Object::urbi_removeSlot);
    DECLARE(updateSlot, &Object::urbi_updateSlot);
#undef DECLARE
  }

}; // namespace object
<commit_msg>style changes.<commit_after>/**
 ** \file object/object-class.cc
 ** \brief Creation of the URBI object object.
 */

//#define ENABLE_DEBUG_TRACES

#include <boost/bind.hpp>
#include <boost/format.hpp>

#include <libport/compiler.hh>
#include <libport/containers.hh>
#include <libport/escape.hh>
#include <libport/foreach.hh>
#include <libport/tokenizer.hh>

#include <kernel/uconnection.hh>
#include <kernel/userver.hh>
#include <object/cxx-primitive.hh>
#include <object/float.hh>
#include <object/global.hh>
#include <object/list.hh>
#include <object/object.hh>
#include <object/string.hh>
#include <object/symbols.hh>
#include <runner/raise.hh>
#include <runner/runner.hh>

namespace object
{
  /*--------------------.
  | Object primitives.  |
  `--------------------*/

  static rObject
  object_class_clone (const objects_type& args)
  {
    check_arg_count(args.size() - 1, 0);

    return args[0]->clone();
  }

  static rObject
  object_class_init (const objects_type& args)
  {
    check_arg_count(args.size() - 1, 0);
    return args[0];
  }

  /// Send dumped self on the connection.
  /// args[1], if present, can be the tag to use.
  static rObject
  object_class_dump (const objects_type& args)
  {
    runner::Runner& r = ::kernel::urbiserver->getCurrentRunner();

    check_arg_count(args.size() - 1, 1, 2);

    // Second argument is max depth.
    int depth_max = 0;
    if (args.size() >= 2)
    {
      type_check<Float>(args[1]);
      const rFloat& arg1 = args[1]->as<Float>();
      try
      {
	depth_max = libport::numeric_cast<int>(arg1->value_get());
      }
      catch (libport::bad_numeric_cast& ue)
      {
	runner::raise_bad_integer_error(arg1->value_get());
      }
    }

    // Third argument is the tag name.
    std::string tag;
    if (args.size() >= 3)
    {
      type_check<String>(args[2]);
      const rString& arg2 = args[2].unsafe_cast<String>();
      assert(arg2);
      tag = arg2->value_get();
    }

    std::ostringstream os;
    args[0]->dump(os, depth_max);
    //for now our best choice is to dump line by line in "system" messages.
    const std::string stream = os.str();
    boost::tokenizer< boost::char_separator<char> > tok =
      libport::make_tokenizer(stream, "\n");
    const std::string system_header("*** ");
    foreach(const std::string& line, tok)
      r.send_message(tag, system_header+line);
    return void_class;
  }

  /// Return the address of an object as a number, mostly
  /// for debugging purpose.
  static rObject
  object_class_uid (const objects_type& args)
  {
    static boost::format uid("0x%x");
    check_arg_count(args.size() - 1, 0);
    return
      new String(str(uid % reinterpret_cast<long long>(args[0].get())));
  }

  /// Structural equality
  static rObject
  object_class_EQ_EQ(const objects_type& args)
  {
    // Unless overridden, structural equality is physical equality.
    check_arg_count(args.size() - 1, 1);
    return args[0]->call(SYMBOL(EQ_EQ_EQ), args[1]);
  }

  /// Physical equality
  static rObject
  object_class_EQ_EQ_EQ(const objects_type& args)
  {
    check_arg_count(args.size() - 1, 1);
    return to_boolean(args[0] == args[1]);
  }

  static rObject
  object_class_apply(const objects_type& args)
  {
    check_arg_count(args.size() - 1, 1);
    type_check<List>(args[1]);
    const rList& arg1 = args[1]->as<List>();
    if (arg1->value_get ().size () != 1
        || arg1->value_get().front() != args[0])
      RAISE("first argument must be `[this]'");
    return arg1->value_get().front();
  }

  static rObject
  object_class_callMessage (const objects_type& args)
  {
    runner::Runner& r = ::kernel::urbiserver->getCurrentRunner();

    check_arg_count(args.size() - 1, 1);
    // We need to set the 'code' slot: make a copy of the call message.
    rObject call_message = args[1]->clone();
    const rObject& message = call_message->slot_get(SYMBOL(message));
    type_check<String>(message);
    const libport::Symbol msg(message->as<String>()->value_get());
    const rObject& target = args[0];
    const rObject& code = target->slot_get(msg);
    call_message->slot_update(SYMBOL(code), code);
    call_message->slot_update(SYMBOL(target), target);
    // FIXME: Sanity checks on the call message are probably required
    return r.apply_call_message(code, msg, call_message);
  }

  /*---------.
  | Protos.  |
  `---------*/

  /// Adding or removing protos. \a Verb is "add" or "remove".
#define CHANGE_PARENTS(Verb)                                            \
  static rObject                                                        \
  object_class_ ## Verb ## Proto (                     \
                                  const objects_type& args)                   \
  {									\
    check_arg_count(args.size() - 1, 1);                                \
    args[0]->proto_ ## Verb (args[1]);					\
    return args[0];							\
  }

  /// Add a proto.
  CHANGE_PARENTS(add);
  /// Remove a proto.
  CHANGE_PARENTS(remove);
#undef CHANGE_PARENTS

  /// Get protos' list.
  static rObject
  object_class_protos (const objects_type& args)
  {
    check_arg_count(args.size() - 1, 0);
    return args[0]->urbi_protos_get ();
  }

  /// Add a prototype
  static bool
  proto_add(List::value_type& protos, const rObject& proto)
  {
    protos.push_back(proto);
    return false;
  }

  /// Recursively get protos list
  static rObject
  object_class_allProtos(const objects_type& args)
  {
    check_arg_count(args.size() - 1, 0);
    List::value_type res;
    for_all_protos(args[0], boost::bind(&proto_add, boost::ref(res), _1));
    return new List(res);
  }

  /*--------.
  | Slots.  |
  `--------*/

  template <typename F>
  static inline void for_all_slot_names(const rObject& o, F f)
  {
    for (Object::slots_implem::iterator slot = o->slots_get().begin(o.get());
         slot != o->slots_get().end(o.get());
         ++slot)
      f(slot->first.second);
  }

  static void
  add_as_rString(List::value_type& l, libport::Symbol slot_name)
  {
    l.push_back(new String(slot_name));
  }

  /// List of slot names.
  static rObject
  object_class_slotNames (const objects_type& args)
  {
    check_arg_count(args.size() - 1, 0);
    const rObject& obj = args[0];

    List::value_type l;
    for_all_slot_names(obj, boost::bind(&add_as_rString, boost::ref(l), _1));
    return new List(l);
  }

  /// Recursive list of slot names.
  static void
  maybe_add(std::vector<libport::Symbol>& control, List::value_type& l,
	    libport::Symbol slot_name)
  {
    if (!libport::has(control, slot_name))
    {
      control.push_back(slot_name);
      l.push_back(new String(slot_name));
    }
  }

  static rObject
  object_class_allSlotNames(const objects_type& args)
  {
    check_arg_count(args.size() - 1, 0);
    std::vector<libport::Symbol> slot_names;
    List::value_type res;
    objects_type protos =
      object_class_allProtos(args)->as<List>()->value_get();
    foreach (const rObject& proto, protos)
    {
      for_all_slot_names(proto, boost::bind(&maybe_add,
					    boost::ref(slot_names),
					    boost::ref(res),
					    _1));
    }
    return new List(res);
  }

  static bool
  object_class_isA(rObject self, rObject proto)
  {
    return is_a(self, proto);
  }

  static bool
  object_class_hasLocalSlot(rObject self, const libport::Symbol& slot)
  {
    return self->local_slot_get(slot);
  }

  void
  object_class_initialize()
  {
    Object::proto->slot_set(SYMBOL(isA),
                           make_primitive(object_class_isA));
    Object::proto->slot_set(SYMBOL(hasLocalSlot),
                            make_primitive(&object_class_hasLocalSlot));
    /// \a Call gives the name of the C++ function, and \a Name that in Urbi.
#define DECLARE(Name)                                                   \
    Object::proto->slot_set(SYMBOL(Name), new Primitive(object_class_##Name), true)

    DECLARE(addProto);
    DECLARE(allProtos);
    DECLARE(allSlotNames);
    DECLARE(apply);
    DECLARE(callMessage);
    DECLARE(clone);
    DECLARE(dump);
    DECLARE(init);
    DECLARE(EQ_EQ_EQ);
    DECLARE(protos);
    DECLARE(removeProto);
    DECLARE(EQ_EQ);
    DECLARE(slotNames);
    DECLARE(uid);
#undef DECLARE

#define DECLARE(Name, Code)                                     \
    Object::proto->slot_set(SYMBOL(Name), make_primitive(&Object::Code))

    DECLARE(createSlot     , urbi_createSlot);
    DECLARE(getProperty    , property_get);
    DECLARE(getSlot        , urbi_getSlot);
    DECLARE(hasProperty    , property_has);
    DECLARE(hasSlot        , slot_has);
    DECLARE(locateSlot     , urbi_locateSlot);
    DECLARE(removeProperty , property_remove);
    DECLARE(removeSlot     , urbi_removeSlot);
    DECLARE(setConstSlot   , urbi_setConstSlot);
    DECLARE(setProperty    , property_set);
    DECLARE(setSlot        , urbi_setSlot);
    DECLARE(updateSlot     , urbi_updateSlot);
#undef DECLARE
  }

}; // namespace object
<|endoftext|>


<commit_before>/**
 ** \file object/object-class.cc
 ** \brief Creation of the URBI object object.
 */

//#define ENABLE_DEBUG_TRACES
#include <libport/compiler.hh>
#include <libport/escape.hh>
#include <libport/foreach.hh>
#include <libport/tokenizer.hh>

#include <kernel/uconnection.hh>

#include <object/cxx-primitive.hh>
#include <object/float-class.hh>
#include <object/global-class.hh>
#include <object/list-class.hh>
#include <object/object-class.hh>
#include <object/object.hh>
#include <object/string-class.hh>

#include <runner/call.hh>
#include <runner/runner.hh>

namespace object
{
  rObject object_class;

  /*--------------------.
  | Object primitives.  |
  `--------------------*/

  static rObject
  object_class_clone (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    return args[0]->clone();
  }

  static rObject
  object_class_init (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (1);
    return args[0];
  }

  /// Send dumped self on the connection.
  /// args[1], if present, can be the tag to use.
  static rObject
  object_class_dump (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT_RANGE(1, 3);

    // Second argument is max depth.
    int depth_max = 0;
    if (args.size() >= 2)
    {
      type_check<Float>(args[1], SYMBOL(dump));
      rFloat arg1 = args[1]->as<Float>();
      try
      {
	depth_max = libport::ufloat_to_int(arg1->value_get());
      }
      catch (libport::bad_numeric_cast& ue)
      {
	throw BadInteger(arg1->value_get(), SYMBOL(dump));
      }
    }

    // Third argument is the tag name.
    std::string tag;
    if (args.size() >= 3)
    {
      rString arg2 = args[2].unsafe_cast<String>();
      assert(arg2);
      tag = arg2->value_get().name_get();
    }

    std::ostringstream os;
    args[0]->dump(os, r, depth_max);
    //for now our best choice is to dump line by line in "system" messages.
    const std::string stream = os.str();
    boost::tokenizer< boost::char_separator<char> > tok =
      libport::make_tokenizer(stream, "\n");
    std::string system_header("*** ");
    foreach(const std::string& line, tok)
      r.send_message(tag, system_header+line);
    return void_class;
  }

  /// Return the address of an object as a number, mostly
  /// for debugging purpose.
  static rObject
  object_class_uid (runner::Runner&, objects_type args)
  {
    static boost::format uid("0x%x");
    CHECK_ARG_COUNT(1);
    return
      new String(libport::Symbol
                 (str(uid % reinterpret_cast<long long>(args[0].get()))));
  }

  /// Structural equality
  static rObject
  object_class_sameAs(runner::Runner& r, objects_type args)
  {
    // Unless overridden, structural equality is physical equality.
    CHECK_ARG_COUNT (2);
    return urbi_call(r, args[0], SYMBOL(memSameAs), args[1]);
  }

  /// Physical equality
  static rObject
  object_class_memSameAs(runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    return to_boolean(args[0] == args[1]);
  }

  static rObject
  object_class_apply(runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(2);
    type_check<List>(args[1], SYMBOL(apply));
    rList arg1 = args[1]->as<List>();
    if (arg1->value_get ().size () != 1 || arg1->value_get().front() != args[0])
      throw PrimitiveError(SYMBOL(apply), "first argument must be [this]");
    return arg1->value_get().front();
  }

  static rObject
  object_class_callMessage (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    // We need to set the 'code' slot: make a copy of the call message.
    rObject call_message = args[1]->clone();
    rObject message = call_message->slot_get(SYMBOL(message));
    type_check<String>(message, SYMBOL(callMessage));
    libport::Symbol msg = message->as<String>()->value_get();
    rObject code = args[0]->slot_get(msg);
    call_message->slot_update(r, SYMBOL(code), code);
    // FIXME: Sanity checks on the call message are probably required
    objects_type self;
    self.push_back(args[0]);
    return r.apply(code, msg, self, call_message);
  }

  /*---------.
  | Protos.  |
  `---------*/

  /// Adding or removing protos. \a Verb is "add" or "remove".
#define CHANGE_PARENTS(Verb)						\
  static rObject							\
  object_class_ ## Verb ## Proto (runner::Runner&, objects_type args)	\
  {									\
    CHECK_ARG_COUNT(2);							\
    args[0]->proto_ ## Verb (args[1]);					\
    return args[0];							\
  }

  /// Add a proto.
  CHANGE_PARENTS(add);
  /// Remove a proto.
  CHANGE_PARENTS(remove);
#undef CHANGE_PARENTS

  /// Get protos' list.
  static rObject
  object_class_protos (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(1);
    return args[0]->urbi_protos_get ();
  }

  /*--------.
  | Slots.  |
  `--------*/

  /// List of slot names.
  static rObject
  object_class_slotNames (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(1);
    rObject obj = args[0];

    List::value_type l;
    for (Object::slots_implem::iterator slot = obj->slots_get().begin(obj.get());
         slot != obj->slots_get().end(obj.get());
         ++slot)
      l.push_back (new String(slot->first.second));

    return new List(l);
  }

  /// Get a slot content.
  static rObject
  object_class_getSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(2);
    rObject obj = args[0];
    rString arg1 = args[1].unsafe_cast<String>();
    assert(arg1);
    return obj->slot_get(arg1->value_get());
  }

  // self.getLazyLocalSlot(SLOT-NAME, DEFAULT-VALUE, CREATE?).
  static rObject
  object_class_getLazyLocalSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (4);

    rString arg1 = args[1].unsafe_cast<String>();
    assert(arg1);
    Object::key_type slot_name = arg1->value_get ();

    // If the slot already exists, return its content.
    if (rObject slot = args[0]->own_slot_get (slot_name))
      return slot;

    // The slot doesn't exist. Should we create it?
    if (is_true (args[3], SYMBOL(getLazyLocalSlot)))
      args[0]->slot_set (slot_name, args[2]);

    // Return the default value for this slot.
    return args[2];
  }

  /// Remove a slot.
  static rObject
  object_class_removeSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(2);
    rObject obj = args[0];
    rString arg1 = args[1].unsafe_cast<String>();
    assert(arg1);
    obj->slot_remove(arg1->value_get());
    return obj;
  }

   /// Locate a slot.
  static rObject
  object_class_locateSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(2);
    rString arg1 = args[1].unsafe_cast<String>();
    assert(arg1);

    rObject o = args[0]->slot_locate(arg1->value_get());
    return o ? o : nil_class;
  }

  static rObject
  object_class_setSlot (runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT(3);
    rString arg1 = args[1].unsafe_cast<String>();
    assert(arg1);
    args[0]->slot_set(arg1->value_get (), args[2]);
    return args[2];
  }

  static rObject
  object_class_updateSlot (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT(3);
    rString arg1 = args[1].unsafe_cast<String>();
    assert(arg1);
    return args[0]->slot_update(r, arg1->value_get (), args[2]);
  }

  static rObject
  object_class_changeSlot (runner::Runner& r, objects_type args)
  {
    CHECK_ARG_COUNT(3);
    rString arg1 = args[1].unsafe_cast<String>();
    assert(arg1);
    args[0]->slot_update(r, arg1->value_get (), args[2], false);
    return args[2];
  }

  static rObject
  object_class_isA(runner::Runner&, objects_type args)
  {
    CHECK_ARG_COUNT (2);
    return new Float(is_a(args[0], args[1])? 1.0:0.0);
  }

  void
  object_class_initialize ()
  {
    /// \a Call gives the name of the C++ function, and \a Name that in Urbi.
#define DECLARE(Name)				\
    DECLARE_PRIMITIVE(object, Name)

    DECLARE(addProto);
    DECLARE(apply);
    DECLARE(callMessage);
    DECLARE(changeSlot);
    DECLARE(clone);
    DECLARE(dump);
    DECLARE(getLazyLocalSlot);
    DECLARE(getSlot);
    DECLARE(init);
    DECLARE(isA);
    DECLARE(locateSlot);
    DECLARE(memSameAs);
    DECLARE(protos);
    DECLARE(removeProto);
    DECLARE(removeSlot);
    DECLARE(sameAs);
    DECLARE(setSlot);
    DECLARE(slotNames);
    DECLARE(uid);
    DECLARE(updateSlot);
#undef DECLARE

#define DECLARE(Name, Code)                     \
    object_class->slot_set(SYMBOL(Name), make_primitive(Code, SYMBOL(Name)))

    DECLARE(getProperty, &Object::property_get);
    DECLARE(hasProperty, &Object::property_has);
    DECLARE(hasSlot, &Object::slot_has);
    DECLARE(setProperty, &Object::property_set);
    DECLARE(removeProperty, &Object::property_remove);
#undef DECLARE
  }

}; // namespace object
<commit_msg>Take arguments by ref in object primitives.<commit_after>/**
 ** \file object/object-class.cc
 ** \brief Creation of the URBI object object.
 */

//#define ENABLE_DEBUG_TRACES
#include <libport/compiler.hh>
#include <libport/escape.hh>
#include <libport/foreach.hh>
#include <libport/tokenizer.hh>

#include <kernel/uconnection.hh>

#include <object/cxx-primitive.hh>
#include <object/float-class.hh>
#include <object/global-class.hh>
#include <object/list-class.hh>
#include <object/object-class.hh>
#include <object/object.hh>
#include <object/string-class.hh>

#include <runner/call.hh>
#include <runner/runner.hh>

namespace object
{
  rObject object_class;

  /*--------------------.
  | Object primitives.  |
  `--------------------*/

  static rObject
  object_class_clone (runner::Runner&, objects_type& args)
  {
    CHECK_ARG_COUNT (1);
    return args[0]->clone();
  }

  static rObject
  object_class_init (runner::Runner&, objects_type& args)
  {
    CHECK_ARG_COUNT (1);
    return args[0];
  }

  /// Send dumped self on the connection.
  /// args[1], if present, can be the tag to use.
  static rObject
  object_class_dump (runner::Runner& r, objects_type& args)
  {
    CHECK_ARG_COUNT_RANGE(1, 3);

    // Second argument is max depth.
    int depth_max = 0;
    if (args.size() >= 2)
    {
      type_check<Float>(args[1], SYMBOL(dump));
      rFloat arg1 = args[1]->as<Float>();
      try
      {
	depth_max = libport::ufloat_to_int(arg1->value_get());
      }
      catch (libport::bad_numeric_cast& ue)
      {
	throw BadInteger(arg1->value_get(), SYMBOL(dump));
      }
    }

    // Third argument is the tag name.
    std::string tag;
    if (args.size() >= 3)
    {
      rString arg2 = args[2].unsafe_cast<String>();
      assert(arg2);
      tag = arg2->value_get().name_get();
    }

    std::ostringstream os;
    args[0]->dump(os, r, depth_max);
    //for now our best choice is to dump line by line in "system" messages.
    const std::string stream = os.str();
    boost::tokenizer< boost::char_separator<char> > tok =
      libport::make_tokenizer(stream, "\n");
    std::string system_header("*** ");
    foreach(const std::string& line, tok)
      r.send_message(tag, system_header+line);
    return void_class;
  }

  /// Return the address of an object as a number, mostly
  /// for debugging purpose.
  static rObject
  object_class_uid (runner::Runner&, objects_type& args)
  {
    static boost::format uid("0x%x");
    CHECK_ARG_COUNT(1);
    return
      new String(libport::Symbol
                 (str(uid % reinterpret_cast<long long>(args[0].get()))));
  }

  /// Structural equality
  static rObject
  object_class_sameAs(runner::Runner& r, objects_type& args)
  {
    // Unless overridden, structural equality is physical equality.
    CHECK_ARG_COUNT (2);
    return urbi_call(r, args[0], SYMBOL(memSameAs), args[1]);
  }

  /// Physical equality
  static rObject
  object_class_memSameAs(runner::Runner&, objects_type& args)
  {
    CHECK_ARG_COUNT (2);
    return to_boolean(args[0] == args[1]);
  }

  static rObject
  object_class_apply(runner::Runner&, objects_type& args)
  {
    CHECK_ARG_COUNT(2);
    type_check<List>(args[1], SYMBOL(apply));
    rList arg1 = args[1]->as<List>();
    if (arg1->value_get ().size () != 1 || arg1->value_get().front() != args[0])
      throw PrimitiveError(SYMBOL(apply), "first argument must be [this]");
    return arg1->value_get().front();
  }

  static rObject
  object_class_callMessage (runner::Runner& r, objects_type& args)
  {
    CHECK_ARG_COUNT (2);
    // We need to set the 'code' slot: make a copy of the call message.
    rObject call_message = args[1]->clone();
    rObject message = call_message->slot_get(SYMBOL(message));
    type_check<String>(message, SYMBOL(callMessage));
    libport::Symbol msg = message->as<String>()->value_get();
    rObject code = args[0]->slot_get(msg);
    call_message->slot_update(r, SYMBOL(code), code);
    // FIXME: Sanity checks on the call message are probably required
    objects_type self;
    self.push_back(args[0]);
    return r.apply(code, msg, self, call_message);
  }

  /*---------.
  | Protos.  |
  `---------*/

  /// Adding or removing protos. \a Verb is "add" or "remove".
#define CHANGE_PARENTS(Verb)						\
  static rObject							\
  object_class_ ## Verb ## Proto (runner::Runner&, objects_type& args)	\
  {									\
    CHECK_ARG_COUNT(2);							\
    args[0]->proto_ ## Verb (args[1]);					\
    return args[0];							\
  }

  /// Add a proto.
  CHANGE_PARENTS(add);
  /// Remove a proto.
  CHANGE_PARENTS(remove);
#undef CHANGE_PARENTS

  /// Get protos' list.
  static rObject
  object_class_protos (runner::Runner&, objects_type& args)
  {
    CHECK_ARG_COUNT(1);
    return args[0]->urbi_protos_get ();
  }

  /*--------.
  | Slots.  |
  `--------*/

  /// List of slot names.
  static rObject
  object_class_slotNames (runner::Runner&, objects_type& args)
  {
    CHECK_ARG_COUNT(1);
    rObject obj = args[0];

    List::value_type l;
    for (Object::slots_implem::iterator slot = obj->slots_get().begin(obj.get());
         slot != obj->slots_get().end(obj.get());
         ++slot)
      l.push_back (new String(slot->first.second));

    return new List(l);
  }

  /// Get a slot content.
  static rObject
  object_class_getSlot (runner::Runner&, objects_type& args)
  {
    CHECK_ARG_COUNT(2);
    rObject obj = args[0];
    rString arg1 = args[1].unsafe_cast<String>();
    assert(arg1);
    return obj->slot_get(arg1->value_get());
  }

  // self.getLazyLocalSlot(SLOT-NAME, DEFAULT-VALUE, CREATE?).
  static rObject
  object_class_getLazyLocalSlot (runner::Runner&, objects_type& args)
  {
    CHECK_ARG_COUNT (4);

    rString arg1 = args[1].unsafe_cast<String>();
    assert(arg1);
    Object::key_type slot_name = arg1->value_get ();

    // If the slot already exists, return its content.
    if (rObject slot = args[0]->own_slot_get (slot_name))
      return slot;

    // The slot doesn't exist. Should we create it?
    if (is_true (args[3], SYMBOL(getLazyLocalSlot)))
      args[0]->slot_set (slot_name, args[2]);

    // Return the default value for this slot.
    return args[2];
  }

  /// Remove a slot.
  static rObject
  object_class_removeSlot (runner::Runner&, objects_type& args)
  {
    CHECK_ARG_COUNT(2);
    rObject obj = args[0];
    rString arg1 = args[1].unsafe_cast<String>();
    assert(arg1);
    obj->slot_remove(arg1->value_get());
    return obj;
  }

   /// Locate a slot.
  static rObject
  object_class_locateSlot (runner::Runner&, objects_type& args)
  {
    CHECK_ARG_COUNT(2);
    rString arg1 = args[1].unsafe_cast<String>();
    assert(arg1);

    rObject o = args[0]->slot_locate(arg1->value_get());
    return o ? o : nil_class;
  }

  static rObject
  object_class_setSlot (runner::Runner&, objects_type& args)
  {
    CHECK_ARG_COUNT(3);
    rString arg1 = args[1].unsafe_cast<String>();
    assert(arg1);
    args[0]->slot_set(arg1->value_get (), args[2]);
    return args[2];
  }

  static rObject
  object_class_updateSlot (runner::Runner& r, objects_type& args)
  {
    CHECK_ARG_COUNT(3);
    rString arg1 = args[1].unsafe_cast<String>();
    assert(arg1);
    return args[0]->slot_update(r, arg1->value_get (), args[2]);
  }

  static rObject
  object_class_changeSlot (runner::Runner& r, objects_type& args)
  {
    CHECK_ARG_COUNT(3);
    rString arg1 = args[1].unsafe_cast<String>();
    assert(arg1);
    args[0]->slot_update(r, arg1->value_get (), args[2], false);
    return args[2];
  }

  static rObject
  object_class_isA(runner::Runner&, objects_type& args)
  {
    CHECK_ARG_COUNT (2);
    return new Float(is_a(args[0], args[1])? 1.0:0.0);
  }

  void
  object_class_initialize ()
  {
    /// \a Call gives the name of the C++ function, and \a Name that in Urbi.
#define DECLARE(Name)				\
    DECLARE_PRIMITIVE(object, Name)

    DECLARE(addProto);
    DECLARE(apply);
    DECLARE(callMessage);
    DECLARE(changeSlot);
    DECLARE(clone);
    DECLARE(dump);
    DECLARE(getLazyLocalSlot);
    DECLARE(getSlot);
    DECLARE(init);
    DECLARE(isA);
    DECLARE(locateSlot);
    DECLARE(memSameAs);
    DECLARE(protos);
    DECLARE(removeProto);
    DECLARE(removeSlot);
    DECLARE(sameAs);
    DECLARE(setSlot);
    DECLARE(slotNames);
    DECLARE(uid);
    DECLARE(updateSlot);
#undef DECLARE

#define DECLARE(Name, Code)                     \
    object_class->slot_set(SYMBOL(Name), make_primitive(Code, SYMBOL(Name)))

    DECLARE(getProperty, &Object::property_get);
    DECLARE(hasProperty, &Object::property_has);
    DECLARE(hasSlot, &Object::slot_has);
    DECLARE(setProperty, &Object::property_set);
    DECLARE(removeProperty, &Object::property_remove);
#undef DECLARE
  }

}; // namespace object
<|endoftext|>