text:
/*************************************************************************
 * odil - Copyright (C) Universite de Strasbourg
 * Distributed under the terms of the CeCILL-B license, as published by
 * the CEA-CNRS-INRIA. Refer to the LICENSE file or to
 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
 * for details.
 ************************************************************************/

#include "odil/webservices/QIDORSRequest.h"

#include <boost/lexical_cast.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <string>
#include <sstream>

#include "odil/webservices/ItemWithParameters.h"
#include "odil/VR.h"
#include "odil/json_converter.h"
namespace odil
{

namespace webservices
{

QIDORSRequest
::QIDORSRequest(const URL &base_url)
    : _base_url(base_url), _media_type(), _representation(Representation::DICOM_JSON),
      _url(), _selector(), _query_data_set(),
      _fuzzymatching(false), _limit(-1), _offset(0)
{
    // Nothing else
}

QIDORSRequest
::QIDORSRequest(HTTPRequest const & request)
{
    // Build tmp URL from target and "Host" header
    URL tmp_url = URL::parse(request.get_target());
    if(request.has_header("Host"))
    {
        this->_url.authority = request.get_header("Host");
    }

    // Find the media type.
    if(!request.has_header("Accept"))
    {
        throw Exception("Cannot parse request: Accept header missing");
    }
    auto const header_accept = boost::lexical_cast<ItemWithParameters>(
        request.get_header("Accept"));

    // if we have multipart/related, we will have then have application/dicom+xml
    // otherwise we will have application/dicom+json
    if(header_accept.name == "multipart/related")
    {
        auto const it = header_accept.name_parameters.find("type");
        // check if the type is not found
        if(it == header_accept.name_parameters.end())
        {
            std::ostringstream message;
            message
                << "Missing type in Accept header: "
                << request.get_header("Accept");
            throw Exception(message.str());
        }
        // check if type is different from the only available type
        if (it->second != "application/dicom+xml")
        {
            throw Exception("The only available type with multipart option is dicom+xml");
        }
        this->_media_type = it->second;
        this->_representation = Representation::DICOM_XML;
    }
    else
    {
        if (header_accept.name != "application/dicom+json")
        {
            throw Exception("The type cannot be different from dicom+json");
        }
        this->_media_type = header_accept.name;
        this->_representation = Representation::DICOM_JSON;
    }

    std::tie(this->_base_url, this->_url, this->_selector, this->_query_data_set,
             this->_fuzzymatching, this->_limit, this->_offset) =
        QIDORSRequest::_split_full_url(tmp_url);
}

bool
QIDORSRequest
::operator ==(QIDORSRequest const & other) const
{
    return(
        this->_base_url == other._base_url
        && this->_media_type == other._media_type
        && this->_representation == other._representation
        && this->_url == other._url
        && this->_selector == other._selector
        && this->_query_data_set == other._query_data_set
        && this->_fuzzymatching == other._fuzzymatching
        && this->_limit == other._limit
        && this->_offset == other._offset
    );
}

bool
QIDORSRequest
::operator !=(QIDORSRequest const & other) const
{
    return !(*this == other);
}

URL const &
QIDORSRequest
::get_base_url() const
{
    return this->_base_url;
}

void
QIDORSRequest
::set_base_url(const URL &url)
{
    this->_base_url = url;
}

std::string const &
QIDORSRequest
::get_media_type() const
{
    return this->_media_type;
}

Representation const &
QIDORSRequest
::get_representation() const
{
    return this->_representation;
}

URL const &
QIDORSRequest
::get_url() const
{
    return this->_url;
}

Selector const &
QIDORSRequest
::get_selector() const
{
    return this->_selector;
}

DataSet const &
QIDORSRequest
::get_query_data_set() const
{
    return this->_query_data_set;
}

bool
QIDORSRequest
::get_fuzzymatching() const
{
    return this->_fuzzymatching;
}

int
QIDORSRequest
::get_limit() const
{
    return this->_limit;
}

int
QIDORSRequest
::get_offset() const
{
    return this->_offset;
}

std::tuple<URL, URL, Selector, DataSet, bool /*fuzzymatching*/, int /*offset*/, int /*limit*/>
QIDORSRequest
::_split_full_url(const URL &url)
{
    Selector selector;
    URL base_url;

    typedef std::string::const_iterator Iterator;

    namespace qi = boost::spirit::qi;
    namespace p = boost::phoenix; // boost::phoenix::ref clashes with std::ref

    typedef std::vector <std::pair <std::string, std::string> >  KeyVal;

    auto const positions = {url.path.rfind("/instances"),
                            url.path.rfind("/series"),
                            url.path.rfind("/studies")};

    auto const position = std::min(positions);

    if(position != std::string::npos)
    {
        base_url = {
            url.scheme, url.authority, url.path.substr(0, position), "", "" };
        auto const resource = url.path.substr(position+1);

        using boost::spirit::qi::char_;
        using boost::spirit::qi::int_;
        using boost::spirit::qi::lit;
        using boost::spirit::qi::omit;
        using boost::spirit::qi::string;
        using boost::spirit::qi::_1;

        qi::rule<Iterator, std::string()> selec =
                -string("studies")
                >> -string("series")
                >> -string("instances");

        qi::rule<Iterator, std::string()> value = +(~char_("/"));

        qi::rule<Iterator, KeyVal()> retrieve_selector =
                (selec >> -(omit["/"] >> value))% "/";

        KeyVal selector_vector;
        auto iterator = resource.begin();
        qi::phrase_parse(
            iterator, resource.end(),
            retrieve_selector,
            boost::spirit::qi::ascii::space, selector_vector
        );
        for (auto const it : selector_vector)
        {
            if(it.first == "studies")
            {
                selector.set_study(it.second);
            }
            else if(it.first == "series")
            {
                selector.set_series(it.second);
            }
            else if(it.first == "instances")
            {
                selector.set_instance(it.second);
            }
            else
            {
                throw Exception("Unrecognize option (" + it.first + ")");
            }
        }
    }

    if (!QIDORSRequest::_is_selector_valid(selector))
    {
        throw Exception("Selector not correctly constructed (" +
                        selector.get_path(false) + ")");
    }

    using boost::spirit::qi::char_;
    using boost::spirit::qi::omit;

    KeyVal key_val;

    // everything but = and &
    qi::rule<Iterator, std::string()> elem = +~char_("=&");

    qi::rule<Iterator, KeyVal()> retrieve_key_val =
            (elem  >> omit["="] >> elem) % "&";

    auto iterator = url.query.begin();
    qi::phrase_parse(
        iterator, url.query.end(),
            (
               retrieve_key_val
            ),
        boost::spirit::qi::ascii::space, key_val
    );

    bool fuzzy = false;
    int limit = -1, offset = 0;
    std::set< std::vector<odil::Tag> > includefields;
    bool include_all = true;
    odil::DataSet data_set;
    for (auto const pair : key_val)
    {
        if (pair.first == "fuzzymatching")
        {
            if (pair.second == "true")
            {
                fuzzy = true;
            }
            else if (pair.second == "false")
            {
                fuzzy = false;
            }
            else
            {
                throw Exception("Fuzzymatching is not a bool (" + pair.second + ")\n");
            }
        }
        else if (pair.first == "limit")
        {
            try
            {
                limit = boost::lexical_cast<int>(pair.second);
            }
            catch (boost::bad_lexical_cast& e)
            {
                std::cerr << "Limit value is not an integer (" << pair.second << ")\n";
            }
        }
        else if (pair.first == "offset")
        {
            try
            {
                offset = boost::lexical_cast<int>(pair.second);
            }
            catch (boost::bad_lexical_cast& e)
            {
                std::cerr << "Offset value is not an integer (" << pair.second << ")\n";
            }
        }
        else
        {
            std::vector< std::string > dicom_tag_vec;
            qi::rule<Iterator, std::string()> dicom_tags = +~char_("."); // simplified
            qi::rule<Iterator, std::vector<std::string>() > retrieve_attribute_id =
                    (dicom_tags) % ".";
            if (pair.first == "includefield")
            {
                if (pair.second == "all")
                {
                    include_all = true;
                }
                else
                {
                    // retrive AttributeId
                    qi::phrase_parse(
                        pair.second.begin(), pair.second.end(),
                                retrieve_attribute_id,
                        boost::spirit::qi::ascii::space, dicom_tag_vec
                    );
                    odil::DataSet* current_ds = &data_set;
                    bool last = false;
                    odil::Tag last_tag = dicom_tag_vec.back();
                    if (dicom_tag_vec.size() >= 1)
                    {
                        dicom_tag_vec.pop_back();
                        last = true;
                    }
                    for (auto const dicom_tag : dicom_tag_vec)
                    {
                        if (!current_ds->has(dicom_tag))
                        {
                            current_ds->add(dicom_tag, {odil::DataSet()});
                        }
                        current_ds = &current_ds->as_data_set(dicom_tag)[0];
                    }
                    if (last)
                    {
                        current_ds->add(last_tag);
                    }
                }
            }
            else
            {// {AttributeID} = {value}
                // retrive AttributeId
                qi::phrase_parse(
                    pair.first.begin(), pair.first.end(),
                            retrieve_attribute_id,
                    boost::spirit::qi::ascii::space, dicom_tag_vec
                );
                DataSet* top_seq = &data_set;
                Tag current_tag;
                size_t dicom_tag_vec_size = dicom_tag_vec.size();
                for (int i = 0; i < dicom_tag_vec_size; ++i)
                {
                    current_tag = odil::Tag(dicom_tag_vec[i]);

                    if (i < dicom_tag_vec_size - 1)
                    {
                        if (!top_seq->has(current_tag))
                        {
                            top_seq->add(current_tag, {odil::DataSet()}, VR::SQ);
                        }
                        top_seq = &top_seq->as_data_set(current_tag)[0];
                    }
                    else
                    {
                        VR current_vr;
                        try
                        {
                            current_vr = odil::as_vr(current_tag);
                        }
                        catch (Exception const &)
                        {
                            current_vr = VR::UN;
                        }
                        if (is_int(current_vr))
                        {
                            try
                            {
                                top_seq->add(current_tag, {boost::lexical_cast<int>(pair.second)});
                            }
                            catch (boost::bad_lexical_cast& e)
                            {
                                throw Exception(current_tag.get_name() + "Should be an integer (" + pair.second + ")");
                            }
                        }
                        else if (is_real(current_vr))
                        {
                            try
                            {
                                top_seq->add(current_tag, {boost::lexical_cast<double>(pair.second)});
                            }
                            catch (boost::bad_lexical_cast& e)
                            {
                                throw Exception(current_tag.get_name() + "Should be a real (" + pair.second + ")");
                            }
                        }
                        else if (is_string(current_vr))
                        {
                            top_seq->add(current_tag, {pair.second});
                        }
                        else
                        {
                            throw Exception("unrecognize VR for " + _tag_to_string(current_tag, true));
                        }
                    }
                }
            }
        }
    }

    // TODO : Fix includefields = all -> need to look for all includefields in the query_dataset (query[tag] = empty
    // with tag that can be a sequence
//    if (include_all)
//    {
//        includefields.clear();
//    }

    URL full_url = QIDORSRequest::_generate_url(base_url, selector, data_set,
                                           fuzzy, limit, offset, false);

    return std::make_tuple(base_url, full_url, selector, data_set,
                           fuzzy, limit, offset
                           );
}

HTTPRequest
QIDORSRequest
::get_http_request() const
{
    ItemWithParameters accept;
    if (this->_representation == Representation::DICOM_JSON)
    {
        accept.name = "application/dicom+json";
    }
    else
    {
        accept.name = "multipart/related";
        accept.name_parameters["type"] = "application/dicom+xml";
    }

    HTTPRequest::Headers const headers{
        {"Accept", boost::lexical_cast<std::string>(accept) }
    };

    return HTTPRequest("GET", this->_url, "HTTP/1.0", headers);
}

bool
QIDORSRequest
::_is_selector_valid(Selector const & selector)
{
    if (!selector.get_frames().empty() || !selector.get_instance().empty())
    {
        return false;
    }
    else
    {
        return(
            // /studies
            (selector.is_study_present() && selector.get_study().empty() && !selector.is_series_present() && !selector.is_instance_present())
            // /studies/1.2/series
            ||(selector.is_study_present() && !selector.get_study().empty() && selector.is_series_present() && selector.get_series().empty() && !selector.is_instance_present())
            // /series
            ||(!selector.is_study_present() && selector.is_series_present() && selector.get_series().empty() && !selector.is_instance_present())
            // /studies/1.2/series/3.4/instances
            ||(selector.is_study_present() && !selector.get_study().empty() && selector.is_series_present() && !selector.get_series().empty() && selector.is_instance_present())
            // /studies/1.2/instances
            ||(selector.is_study_present() && !selector.get_study().empty() && !selector.is_series_present() && selector.is_instance_present())
            // /instances
            || (!selector.is_study_present() && !selector.is_series_present() && selector.is_instance_present())
        );
    }
}

std::string
QIDORSRequest
::_tag_to_string(Tag const & tag, bool numerical_tag)
{
    if(numerical_tag)
    {
        return std::string(tag);
    }
    else
    {
        try
        {
            return tag.get_name();
        }
        catch (Exception const &)
        {
            return std::string(tag);
        }
    }
}

URL
QIDORSRequest
::_generate_url(URL const & base_url, Selector const & selector, DataSet const & query_data_set,
                  bool fuzzymatching, int limit, int offset, bool numerical_tags)
{
    auto path = base_url.path + selector.get_path(false);
    std::stringstream ss_query, includefield_ss_query;

    // ----- QUERY + INCLUDEFIELD

    typedef std::tuple<odil::Element const *, odil::Tag const *, std::string> leaf;

        // loop vars
    odil::Tag const * current_tag;
    odil::Element const * current_element;
    odil::DataSet const * current_ds;

    std::vector<leaf> leaves;
    std::list< std::pair < odil::DataSet const * , std::string > > data_sets; // str for the root and pointer to the root element
    data_sets.push_back(std::make_pair(&query_data_set, std::string("")));
    std::list< std::pair < odil::DataSet const *, std::string > >::iterator it;

        // loop
    while (!data_sets.empty())
    {
        it = data_sets.begin();
        current_ds = (*it).first;
        std::stringstream current_ds_sstr;
        current_ds_sstr << (*it).second;

        for (auto const & tag_elem : * current_ds)
        {
            std::stringstream current_sstr; // copy of the root string where the leaf element will be append
            current_sstr << current_ds_sstr.str();
            current_tag = &tag_elem.first;
            current_element = &tag_elem.second;
            if (current_element->is_data_set())
            {
                if (current_sstr.str().size() > 0)
                {
                    current_sstr << ".";
                }
                current_sstr << QIDORSRequest::_tag_to_string(*current_tag, numerical_tags);
                data_sets.push_back(std::make_pair(&current_element->as_data_set()[0],
                                    current_sstr.str()));
            }
            else
            {
                if (current_sstr.str().size() > 0)
                {
                    current_sstr << ".";
                }
                current_sstr << QIDORSRequest::_tag_to_string(*current_tag, numerical_tags);
                leaves.push_back(std::make_tuple(current_element, current_tag, current_sstr.str()));
            }
        }
        data_sets.pop_front();
    }

        // query writing
    unsigned int leaves_size = leaves.size(), leaves_count = 0;
    std::stringstream* current_ss;

    for (auto const it : leaves)
    {
        odil::Element const * elem;
        odil::Tag const * tag;
        std::string elem_str;
        std::tie(elem, tag, elem_str) = it;

        if (elem->empty()) // includefield
        {
             includefield_ss_query << "includefield=" << elem_str;
             current_ss = &includefield_ss_query;
        }
        else if (elem->size() == 1)
        {
            ss_query << elem_str << "=";
            if (elem->is_int())
            {
                ss_query << boost::lexical_cast<std::string>(elem->as_int()[0]);
            }
            else if (elem->is_real())
            {
                ss_query << boost::lexical_cast<std::string>(elem->as_real()[0]);
            }
            else if (elem->is_string())
            {
                ss_query << elem->as_string()[0];
            }
            else
            {
                throw Exception("Invalid query tag (" +
                                QIDORSRequest::_tag_to_string(*tag, numerical_tags) +")");
            }
            current_ss = &ss_query;
        }
        else
        {
            throw Exception("Query doesn't allow the use of multidimensional element ("+
                            QIDORSRequest::_tag_to_string(*tag, numerical_tags) +")");
        }
        if (leaves_count ++ < leaves_size -1)
        {
            *current_ss << "&";
        }
    }

        // append includefield at the end of the query string
    ss_query << includefield_ss_query.str() ;

    // ----- FUZZYMATCHING

    ss_query << "&fuzzymatching=";
    if(fuzzymatching)
    {
        ss_query << "true";
    }
    else
    {
        ss_query << "false";
    }

    // ----- LIMIT & OFFSET

    if (limit != -1)
    {
        ss_query << "&limit=" << limit;
        if (offset != 0)
        {
            ss_query << "&offset=" << offset;
        }
    }

    std::string query = ss_query.str();

    return {
        base_url.scheme, base_url.authority, path, query, ""
    };
}

void
QIDORSRequest
::request_datasets(
    Representation representation, Selector const & selector,
    DataSet const & query_data_set, bool fuzzymatching,
    int limit, int offset, bool numerical_tags)
{
    if (representation != Representation::DICOM_JSON &&
            representation != Representation::DICOM_XML)
    {
        throw Exception("Given representation is not available for QIDO-RS");
    }
    this->_representation = representation;
    this->_selector = selector;
    this->_query_data_set = query_data_set;
    this->_fuzzymatching = fuzzymatching;
    this->_limit = limit;
    this->_offset = offset;

    if (!QIDORSRequest::_is_selector_valid(selector))
    {
        throw Exception("Selector not correctly constructed (" +
                        selector.get_path(false) + ")");
    }

    this->_url = QIDORSRequest::_generate_url(this->_base_url, selector,
                                              query_data_set, fuzzymatching,
                                              limit, offset, numerical_tags);
}

}

}

ext: cpp

max_stars_repo_name: icryrainix/odil

max_issues_repo_name: icryrainix/odil

max_forks_repo_name: icryrainix/odil


text:
// Copyright (c) 2009-2016 Satoshi Nakamoto
// Copyright (c) 2009-2016 The Bitcoin Developers
// Copyright (c) 2015-2016 Silk Network
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp>

#include <assert.h>

#include "chainparams.h"
#include "chainparamsseeds.h"
#include "main.h"
#include "net.h"
#include "random.h"
#include "utilstrencodings.h"

using namespace boost::assign;

struct SeedSpec6 {
    uint8_t addr[16];
    uint16_t port;
};

//
// Main network
//

// Convert the pnSeeds array into usable address objects.
static void convertSeeds(std::vector<CAddress> &vSeedsOut, const unsigned int *data, unsigned int count, int port)
{
    // It'll only connect to one or two seed nodes because once it connects,
    // it'll get a pile of addresses with newer timestamps.
    // Seed nodes are given a random 'last seen time' of between one and two
    // weeks ago.
    const int64_t nOneWeek = 7*24*60*60;
    for (unsigned int k = 0; k < count; ++k)
    {
        struct in_addr ip;
        unsigned int i = data[k], t;

        // -- convert to big endian
        t =   (i & 0x000000ff) << 24u
            | (i & 0x0000ff00) << 8u
            | (i & 0x00ff0000) >> 8u
            | (i & 0xff000000) >> 24u;

        memcpy(&ip, &t, sizeof(ip));

        CAddress addr(CService(ip, port));
        addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
        vSeedsOut.push_back(addr);
    }
}

class CMainParams : public CChainParams {
public:
    CMainParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0x1f;
        pchMessageStart[1] = 0x22;
        pchMessageStart[2] = 0x05;
        pchMessageStart[3] = 0x31;
        vAlertPubKey = ParseHex("0450e0acc669231cfe2d0a8f0d164c341547487adff89f09e1e78a5299d204bd1c9f05897cb916365c56a31377d872abddb551a12d8d8163149abfc851be7f88ba");
        nDefaultPort = 31000;
        nRPCPort = 31500;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20); // PoW starting difficulty = 0.0002441

        // Build the genesis block. Note that the output of the genesis coinbase cannot
        // be spent as it did not originally exist in the database.

        const char* pszTimestamp = "2015 DarkSilk is Born";
        std::vector<CTxIn> vin;
        vin.resize(1);
        vin[0].scriptSig = CScript() << 0 << CBigNum(42) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
        std::vector<CTxOut> vout;
        vout.resize(1);
        vout[0].SetEmpty();
        CMutableTransaction txNew(1, 1444948732, vin, vout, 0);
        genesis.vtx.push_back(txNew);
        genesis.hashPrevBlock = 0;
        genesis.hashMerkleRoot = genesis.BuildMerkleTree();
        genesis.nVersion = 1;
        genesis.nTime    = 1444948732; //Change to current UNIX Time of generated genesis
        genesis.nBits    = 0x1e0ffff0;
        genesis.nNonce   = 763220;

        hashGenesisBlock = genesis.GetHash();

        //// debug print
        /*
        printf("Gensis Hash: %s\n", genesis.GetHash().ToString().c_str());
        printf("Gensis Hash Merkle: %s\n", genesis.hashMerkleRoot.ToString().c_str());
        printf("Gensis nTime: %u\n", genesis.nTime);
        printf("Gensis nBits: %08x\n", genesis.nBits);
        printf("Gensis Nonce: %u\n\n\n", genesis.nNonce);
        */

        assert(hashGenesisBlock == uint256("0xdcc5e22e275eff273799a4c06493f8364316d032813c22845602f05ff13d7ec7"));
        assert(genesis.hashMerkleRoot == uint256("0xfed7550a453e532c460fac58d438740235c380f9908cae2d602b705ca2c2f0a6"));

        vSeeds.push_back(CDNSSeedData("darksilk.org", "ds1.darksilk.org"));
        vSeeds.push_back(CDNSSeedData("", ""));

        base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1, 30);                     //DarkSilk addresses start with 'D'
        base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1, 10);                     //DarkSilk script addresses start with '5'
        base58Prefixes[SECRET_KEY] =     std::vector<unsigned char>(1, 140);                    //DarkSilk private keys start with 'y'
        base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x02)(0xFE)(0x52)(0x7D).convert_to_container<std::vector<unsigned char> >(); //DarkSilk BIP32 pubkeys start with 'drks'
        base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x02)(0xFE)(0x52)(0x8C).convert_to_container<std::vector<unsigned char> >(); //DarkSilk BIP32 prvkeys start with 'drky'

        convertSeeds(vFixedSeeds, pnSeed, ARRAYLEN(pnSeed), nDefaultPort);

        //TODO(AA)
        nPoolMaxTransactions = 3;
        strSandstormPoolDummyAddress = "DDCxTmWLPytjnEAMd3TCGaryJStEx5caSm"; //private key = MpBeYuuA7c47bqa6ubmBnP8P7hkpmJTSUgwejC8AehSPwsXmkZHD
        strStormnodePaymentsPubKey = "";
        nFirstPOSBlock = 101;

		nStormnodeCollateral = 10000;
		nStormnodeStartBlock = 420;
        nStartStormnodePayments = 1446335999; //Wed, 31 Oct 2015 23:59:59 GMT

		nSandstormCollateral = (0.01*COIN);
		nSandstormPoolMax = (9999.99*COIN);

		nPoWBlockSpacing = 60;
		nPoSBlockSpacing = 64;
    }

    virtual const CBlock& GenesisBlock() const { return genesis; }
    virtual Network NetworkID() const { return CChainParams::MAIN; }

    virtual const vector<CAddress>& FixedSeeds() const {
        return vFixedSeeds;
    }
protected:
    CBlock genesis;
    vector<CAddress> vFixedSeeds;
};
static CMainParams mainParams;

//
// Testnet
//

class CTestNetParams : public CMainParams {
public:
    CTestNetParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0x1f;
        pchMessageStart[1] = 0x22;
        pchMessageStart[2] = 0x05;
        pchMessageStart[3] = 0x30;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20); // PoW starting difficulty = 0.0002441
        vAlertPubKey = ParseHex("");
        nDefaultPort = 31750;
        nRPCPort = 31800;
        strDataDir = "testnet";

        // Modify the testnet genesis block so the timestamp is valid for a later start.
        genesis.nTime = 1438578972;
        genesis.nBits  = 0;
        genesis.nNonce = 0;
        hashGenesisBlock = genesis.GetHash();

        //printf("Test Genesis Hash: %s\n", genesis.GetHash().ToString().c_str());
        assert(hashGenesisBlock == uint256("0xf788ac4ae46429468897b4b9758651cb8a642a6e01f16968134a75078905e24d"));

        vFixedSeeds.clear();
        vSeeds.clear();

        base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1, 30);                     //DarkSilk addresses start with 'D'
        base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1, 10);                     //DarkSilk script addresses start with '5'
        base58Prefixes[SECRET_KEY] =     std::vector<unsigned char>(1, 140);                    //DarkSilk private keys start with 'y'
        base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x02)(0xFE)(0x52)(0x7D).convert_to_container<std::vector<unsigned char> >(); //DarkSilk BIP32 pubkeys start with 'drks'
        base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x02)(0xFE)(0x52)(0x8C).convert_to_container<std::vector<unsigned char> >(); //DarkSilk BIP32 prvkeys start with 'drky'

        convertSeeds(vFixedSeeds, pnTestnetSeed, ARRAYLEN(pnTestnetSeed), nDefaultPort);

        //TODO(Amir): Change pub key and dummy address
        nPoolMaxTransactions = 3;
        strStormnodePaymentsPubKey = "";
        strSandstormPoolDummyAddress = "DDCxTmWLPytjnEAMd3TCGaryJStEx5caSm"; //private key = MpBeYuuA7c47bqa6ubmBnP8P7hkpmJTSUgwejC8AehSPwsXmkZHD
        nFirstPOSBlock = 101;

		nStormnodeCollateral = 10000;
		nStormnodeStartBlock = 100;
        nStartStormnodePayments = 1446335999; //Wed, 31 Oct 2015 23:59:59 GMT

		nSandstormCollateral = (0.01*COIN);
		nSandstormPoolMax = (9999.99*COIN);

		nPoWBlockSpacing = 60;
		nPoSBlockSpacing = 64;    }

    virtual Network NetworkID() const { return CChainParams::TESTNET; }
};
static CTestNetParams testNetParams;

static CChainParams *pCurrentParams = &mainParams;

const CChainParams &Params() {
    return *pCurrentParams;
}

void SelectParams(CChainParams::Network network) {
    switch (network) {
        case CChainParams::MAIN:
            pCurrentParams = &mainParams;
            break;
        case CChainParams::TESTNET:
            pCurrentParams = &testNetParams;
            break;
        default:
            assert(false && "Unimplemented network");
            return;
    }
}

bool SelectParamsFromCommandLine() {

    bool fTestNet = GetBoolArg("-testnet", false);

    if (fTestNet) {
        SelectParams(CChainParams::TESTNET);
    } else {
        SelectParams(CChainParams::MAIN);
    }
    return true;
}

max_stars_repo_name: GregoryBetz/DarkSilk-RC

max_issues_repo_name: GregoryBetz/DarkSilk-RC

max_forks_repo_name: GregoryBetz/DarkSilk-RC


text:
/*
	[Vc,Fc] = cut_mesh_mex(V,F);
    V, F: vertices/faces of input mesh (any topology, with/without boundary)
    Vc, Fc: vertices/faces of cut mesh
*/

#include <iostream>
#include <stdlib.h>     /* srand, rand */

#include "mex.h"
#include <Eigen/Core>
#include <Eigen/Sparse>

#include <igl/matlab_format.h>
#include <igl/adjacency_matrix.h>
#include <igl/boundary_loop.h>
#include "polyvector_field_cut_mesh_with_singularities_randomized.h"
#include <igl/cut_mesh.h>
#include <igl/euler_characteristic.h>

using namespace std;

void mexFunction(	int nlhs, mxArray *plhs[],
				 int nrhs, const mxArray*prhs[] )
{
	/* retrieve arguments */
	if( nrhs!=2 )
		mexErrMsgTxt("2 input arguments are required - faces and vertices.");
	if( nlhs<2 )
		mexErrMsgTxt("2 output arguments are required - faces and vertices.");

	// first argument : vertices
    double *V_mex = mxGetPr(prhs[0]);
    int nV = (int)mxGetM(prhs[0]);
    int cV = (int)mxGetN(prhs[0]);
	if( cV!=3 )
		mexErrMsgTxt("Vertices should be an #V x 3 matrix.");
    Eigen::MatrixXd V = Eigen::Map<Eigen::MatrixXd>(V_mex,nV,3);

	// second argument : faces
    double *F_mex = mxGetPr(prhs[1]);
    int nF = (int)mxGetM(prhs[1]);
    int cF = (int)mxGetN(prhs[1]);
	if( cF!=3 )
		mexErrMsgTxt("Faces should be an #F x 3 matrix.");
    Eigen::MatrixXd Fd = Eigen::Map<Eigen::MatrixXd>(F_mex,nF,3);
    Eigen::MatrixXi F = Fd.cast<int> ();
    // C-based indexing
    F = F.array() -1;

    // compute Euler characteristic of input mesh
    int e_in = igl::euler_characteristic(V, F);
    // compute number of boundaries in input mesh
    std::vector<std::vector<int> > L;
    igl::boundary_loop(F,L);
    int b_in = L.size();
    // compute genus of input mesh
    int g_in =(2-b_in-e_in)/2;
    cerr<<" -> Input mesh: e = "<<e_in<<", b = "<<b_in<<", g= "<<g_in<<endl;

    // for genus zero we need to add two non-adjacent singularities
    Eigen::VectorXi singularities;
    if (g_in ==0)
    {
        // generate two random singularities between 0 and nV-1:
        int s0 = rand() % nV ;
        // make sure singus aren't adjacent
        Eigen::SparseMatrix<int> A;
        igl::adjacency_matrix(F,A);
        int s1 = s0;
        while (s1==s0 || A.coeff(s0,s1) == 1)
            s1 = rand() % nV ;

        singularities.setZero(2,1);
        singularities<<s0,s1;
    }

    // generate cuts using tree traversal: a boolean per face edge
    Eigen::MatrixXi cuts;
    polyvector_field_cut_mesh_with_singularities_randomized(V, F, singularities, cuts);

    // duplicate vertices along cut to produce cut mesh
    Eigen::MatrixXd Vc;
    Eigen::MatrixXi Fc;
    igl::cut_mesh(V, F, cuts, Vc, Fc);

    // compute Euler characteristic of output mesh
    // this should be 1 ALWAYS (disk topology)
    int e_out = igl::euler_characteristic(Vc, Fc);
    // compute number of boundaries in input mesh
    std::vector<std::vector<int> > Lc;
    igl::boundary_loop(Fc,Lc);
    int b_out = Lc.size();
    // compute genus of input mesh
    int g_out =(2-b_out-e_out)/2;
    cerr<<" -> Output mesh: e = "<<e_out<<", b = "<<b_out<<", g= "<<g_out<<endl;

    if( e_out!=1 )
		mexErrMsgTxt("Output mesh does not have disk topology.");

	// first output : vertices of cut mesh
	plhs[0] = mxCreateDoubleMatrix(Vc.rows(), 3, mxREAL);
    Eigen::Map<Eigen::MatrixXd>( mxGetPr(plhs[0]), Vc.rows(), Vc.cols() ) = Vc;

	// second output : faces of cut mesh
    Eigen::MatrixXd Fc_d = Fc.cast<double>();
    // matlab-based indexing
    Fc_d = Fc_d.array() + 1;
	plhs[1] = mxCreateDoubleMatrix(Fc.rows(), 3, mxREAL);
    Eigen::Map<Eigen::MatrixXd>( mxGetPr(plhs[1]), Fc_d.rows(), Fc_d.cols() ) = Fc_d;

	return;
}


text:
/*
 * @Description:
 * @Author: Ren Qian
 * @Date: 2020-03-01 18:35:19
 */

#ifndef LIDAR_LOCALIZATION_MODELS_GRAPH_OPTIMIZER_INTERFACE_GRAPH_OPTIMIZER_HPP_
#define LIDAR_LOCALIZATION_MODELS_GRAPH_OPTIMIZER_INTERFACE_GRAPH_OPTIMIZER_HPP_

#include <string>
#include <deque>
#include <Eigen/Dense>

namespace lidar_localization {
class InterfaceGraphOptimizer {
  public:
    virtual ~InterfaceGraphOptimizer() {}
    // 优化
    virtual bool Optimize() = 0;
    // 输入、输出数据
    virtual bool GetOptimizedPose(std::deque<Eigen::Matrix4f>& optimized_pose) = 0;
    virtual int GetNodeNum() = 0;
    // 添加节点、边、鲁棒核
    virtual void SetEdgeRobustKernel(std::string robust_kernel_name, double robust_kernel_size) = 0;
    virtual void AddSe3Node(const Eigen::Isometry3d &pose, bool need_fix) = 0;
    virtual void AddSe3Edge(int vertex_index1,
                            int vertex_index2,
                            const Eigen::Isometry3d &relative_pose,
                            const Eigen::VectorXd noise) = 0;
    virtual void AddSe3PriorXYZEdge(int se3_vertex_index,
                                    const Eigen::Vector3d &xyz,
                                    Eigen::VectorXd noise) = 0;
    virtual void AddSe3PriorQuaternionEdge(int se3_vertex_index,
                                           const Eigen::Quaterniond &quat,
                                           Eigen::VectorXd noise) = 0;
    // 设置优化参数
    void SetMaxIterationsNum(int max_iterations_num);

  protected:
    int max_iterations_num_ = 512;
};
} // namespace lidar_localization
#endif

ext: hpp


text:
//
// Copyright 2016 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
//    names, trademarks, service marks, or product names of the Licensor
//    and its affiliates, except as required to comply with Section 4(c) of
//    the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "pxr/usd/usdSkel/cache.h"

#include "pxr/usd/usd/pyConversions.h"
#include "pxr/base/tf/pyContainerConversions.h"
#include "pxr/base/tf/pyResultConversions.h"
#include "pxr/base/tf/pyUtils.h"
#include "pxr/base/tf/wrapTypeHelpers.h"

#include "pxr/usd/usd/prim.h"

#include "pxr/usd/usdSkel/animation.h"
#include "pxr/usd/usdSkel/root.h"
#include "pxr/usd/usdSkel/skeleton.h"
#include "pxr/usd/usdSkel/skeletonQuery.h"
#include "pxr/usd/usdSkel/skinningQuery.h"

#include <boost/python.hpp>
#include <boost/python/extract.hpp>

using namespace boost::python;

PXR_NAMESPACE_USING_DIRECTIVE

namespace {

std::vector<UsdSkelBinding>
_ComputeSkelBindings(const UsdSkelCache& self,
                     const UsdSkelRoot& skelRoot,
                     const Usd_PrimFlagsPredicate predicate)
{
    std::vector<UsdSkelBinding> bindings;
    self.ComputeSkelBindings(skelRoot, &bindings, predicate);
    return bindings;
}

UsdSkelBinding
_ComputeSkelBinding(const UsdSkelCache& self,
                    const UsdSkelRoot& skelRoot,
                    const UsdSkelSkeleton& skel,
                    const Usd_PrimFlagsPredicate predicate)
{
    UsdSkelBinding binding;
    self.ComputeSkelBinding(skelRoot, skel, &binding, predicate);
    return binding;
}

} // namespace

void wrapUsdSkelCache()
{
    using This = UsdSkelCache;

    class_<This>("Cache", init<>())

        .def("Clear", &This::Clear)

        .def("Populate", &This::Populate,
             (arg("skelRoot"), arg("predicate")))

        .def("GetSkelQuery", &This::GetSkelQuery)

        .def("GetSkinningQuery", &This::GetSkinningQuery)

        .def("GetAnimQuery",
             (UsdSkelAnimQuery (UsdSkelCache::*)(const UsdPrim&) const)
             &This::GetAnimQuery,
             (arg("prim")))

        .def("GetAnimQuery",
             (UsdSkelAnimQuery (UsdSkelCache::*)(const UsdSkelAnimation&) const)
             &This::GetAnimQuery,
             (arg("anim")))

        .def("ComputeSkelBindings", &_ComputeSkelBindings,
             return_value_policy<TfPySequenceToList>(),
             (arg("skelRoot"), arg("predicate")))

        .def("ComputeSkelBinding", &_ComputeSkelBinding,
             (arg("skelRoot"), arg("skel"), arg("predicate")))
        ;
}

max_stars_repo_name: DougRogers-DigitalFish/USD

max_issues_repo_name: DougRogers-DigitalFish/USD

max_forks_repo_name: DougRogers-DigitalFish/USD


text:
//==================================================================================================
/*!

  Copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#include <boost/simd/function/scalar/sin.hpp>
#include <boost/simd/function/restricted.hpp>
#include <scalar_test.hpp>
#include <boost/simd/constant/inf.hpp>
#include <boost/simd/constant/minf.hpp>
#include <boost/simd/constant/nan.hpp>
#include <boost/simd/constant/one.hpp>
#include <boost/simd/constant/mone.hpp>
#include <boost/simd/constant/zero.hpp>
#include <boost/simd/constant/mzero.hpp>
#include <boost/simd/constant/pio_2.hpp>
#include <boost/simd/constant/pio_4.hpp>
#include <boost/simd/constant/sqrt_2o_2.hpp>
#include <boost/simd/function/is_negative.hpp>
#include <boost/simd/function/is_positive.hpp>

STF_CASE_TPL (" sin",  STF_IEEE_TYPES)
{
  namespace bs = boost::simd;
  namespace bd = boost::dispatch;
  using bs::sin;

  using r_t = decltype(sin(T()));

  // return type conformity test
  STF_TYPE_IS(r_t, T);

  // specific values tests
#ifndef BOOST_SIMD_NO_INVALIDS
  STF_ULP_EQUAL(sin(bs::Inf<T>()), bs::Nan<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Minf<T>()), bs::Nan<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Nan<T>()), bs::Nan<r_t>(), 0.5);
#endif
  STF_ULP_EQUAL(sin(-bs::Pio_2<T>()), bs::Mone<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(-bs::Pio_4<T>()), -bs::Sqrt_2o_2<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Pio_2<T>()), bs::One<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Pio_4<T>()), bs::Sqrt_2o_2<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Zero<T>()), bs::Zero<r_t>(), 0.5);
  STF_EXPECT(bs::is_negative(sin(bs::Mzero<T>())));
  STF_EXPECT(bs::is_positive(sin(bs::Zero<T>())));
}

STF_CASE_TPL (" sin restricted ",  STF_IEEE_TYPES)
{
  namespace bs = boost::simd;
  namespace bd = boost::dispatch;
  using bs::sin;
  using r_t = decltype(sin(T()));

  // specific values tests
#ifndef BOOST_SIMD_NO_INVALIDS
  STF_ULP_EQUAL(bs::restricted_(sin)(bs::Inf<T>()), bs::Nan<r_t>(), 0.5);
  STF_ULP_EQUAL(bs::restricted_(sin)(bs::Minf<T>()), bs::Nan<r_t>(), 0.5);
  STF_ULP_EQUAL(bs::restricted_(sin)(bs::Nan<T>()), bs::Nan<r_t>(), 0.5);
#endif
  STF_ULP_EQUAL(bs::restricted_(sin)(-bs::Pio_2<T>()), bs::Nan<r_t>(), 0.5);
  STF_ULP_EQUAL(bs::restricted_(sin)(-bs::Pio_4<T>()), -bs::Sqrt_2o_2<r_t>(), 0.5);
  STF_ULP_EQUAL(bs::restricted_(sin)(bs::Pio_2<T>()), bs::Nan<r_t>(), 0.5);
  STF_ULP_EQUAL(bs::restricted_(sin)(bs::Pio_4<T>()), bs::Sqrt_2o_2<r_t>(), 0.5);
  STF_ULP_EQUAL(bs::restricted_(sin)(bs::Zero<T>()), bs::Zero<r_t>(), 0.5);
  STF_EXPECT(bs::is_negative(bs::restricted_(sin)(bs::Mzero<T>())));
  STF_EXPECT(bs::is_positive(bs::restricted_(sin)(bs::Zero<T>())));
}

STF_CASE_TPL (" sin",  STF_IEEE_TYPES)
{
  namespace bs = boost::simd;
  namespace bst = bs::tag;
  namespace bd = boost::dispatch;
  using bs::sin;

  using r_t = decltype(sin(T()));

  // return type conformity test
  STF_TYPE_IS(r_t, T);

  // specific values tests
#ifndef BOOST_SIMD_NO_INVALIDS
  STF_ULP_EQUAL(sin(bs::Inf<T>(), bst::clipped_small_), bs::Nan<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Minf<T>(), bst::clipped_small_), bs::Nan<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Nan<T>(), bst::clipped_small_), bs::Nan<r_t>(), 0.5);
#endif
  STF_ULP_EQUAL(sin(-bs::Pio_2<T>(), bst::clipped_small_), bs::Mone<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(-bs::Pio_4<T>(), bst::clipped_small_), -bs::Sqrt_2o_2<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Pio_2<T>(), bst::clipped_small_), bs::One<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Pio_4<T>(), bst::clipped_small_), bs::Sqrt_2o_2<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Zero<T>(), bst::clipped_small_), bs::Zero<r_t>(), 0.5);
  STF_EXPECT(bs::is_negative(sin(bs::Mzero<T>(), bst::clipped_small_)));
  STF_EXPECT(bs::is_positive(sin(bs::Zero<T>(), bst::clipped_small_)));
}
STF_CASE_TPL (" sin",  STF_IEEE_TYPES)
{
  namespace bs = boost::simd;
  namespace bst = bs::tag;
  namespace bd = boost::dispatch;
  using bs::sin;

  using r_t = decltype(sin(T()));

  // return type conformity test
  STF_TYPE_IS(r_t, T);

  // specific values tests
#ifndef BOOST_SIMD_NO_INVALIDS
  STF_ULP_EQUAL(sin(bs::Inf<T>(), bst::clipped_medium_), bs::Nan<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Minf<T>(), bst::clipped_medium_), bs::Nan<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Nan<T>(), bst::clipped_medium_), bs::Nan<r_t>(), 0.5);
#endif
  STF_ULP_EQUAL(sin(-bs::Pio_2<T>(), bst::clipped_medium_), bs::Mone<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(-bs::Pio_4<T>(), bst::clipped_medium_), -bs::Sqrt_2o_2<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Pio_2<T>(), bst::clipped_medium_), bs::One<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Pio_4<T>(), bst::clipped_medium_), bs::Sqrt_2o_2<r_t>(), 0.5);
  STF_ULP_EQUAL(sin(bs::Zero<T>(), bst::clipped_medium_), bs::Zero<r_t>(), 0.5);
  STF_EXPECT(bs::is_negative(sin(bs::Mzero<T>(), bst::clipped_medium_)));
  STF_EXPECT(bs::is_positive(sin(bs::Zero<T>(), bst::clipped_medium_)));
}