<commit_before>// Copyright 2010-2013 RethinkDB, all rights reserved.
#include "rdb_protocol/terms/terms.hpp"

#include <string>

#include "rdb_protocol/error.hpp"
#include "rdb_protocol/func.hpp"
#include "rdb_protocol/op.hpp"
#include "rdb_protocol/pathspec.hpp"
#include "rdb_protocol/pb_utils.hpp"
#include "rdb_protocol/pseudo_literal.hpp"
#include "rdb_protocol/minidriver.hpp"

#pragma GCC diagnostic ignored "-Wshadow"

namespace ql {

// This term is used for functions that are polymorphic on objects and
// sequences, like `pluck`.  It will handle the polymorphism; terms inheriting
// from it just need to implement evaluation on objects (`obj_eval`).
class obj_or_seq_op_term_t : public op_term_t {
public:
    enum poly_type_t {
        MAP = 0,
        FILTER = 1,
        SKIP_MAP = 2
    };
    obj_or_seq_op_term_t(compile_env_t *env, protob_t<const Term> term,
                         poly_type_t _poly_type, argspec_t argspec)
        : op_term_t(env, term, argspec, optargspec_t({"_NO_RECURSE_"})),
          poly_type(_poly_type), func(make_counted_term()) {

        auto varnum = pb::dummy_var_t::OBJORSEQ_VARNUM;

        // body is a new reql expression similar to term except that the first argument
        // is replaced by a new variable.
        // For example, foo.pluck('a') becomes varnum.pluck('a')
        r::reql_t body = r::var(varnum).call(term->type());
        body.copy_args_from_term(*term, 1);
        body.add_arg(r::optarg("_NO_RECURSE_", r::boolean(true)));

        switch (poly_type) {
        case MAP: {
            func->Swap(&r::fun(varnum, std::move(body)).get());
        } break;
        case FILTER: {
            func->Swap(&r::fun(varnum, std::move(body)).get());
        } break;
        case SKIP_MAP: {
            func->Swap(&r::fun(varnum, r::array(std::move(body)).default_(r::array())).get());
        } break;
        default: unreachable();
        }

        prop_bt(func.get());
    }
private:
    virtual counted_t<val_t> obj_eval(scope_env_t *env, counted_t<val_t> v0) = 0;

    virtual counted_t<val_t> eval_impl(scope_env_t *env, UNUSED eval_flags_t flags) {
        counted_t<val_t> v0 = arg(env, 0);
        counted_t<const datum_t> d;

        if (v0->get_type().is_convertible(val_t::type_t::DATUM)) {
            d = v0->as_datum();
        }

        if (d.has() && d->get_type() == datum_t::R_OBJECT) {
            return obj_eval(env, v0);
        } else if ((d.has() && d->get_type() == datum_t::R_ARRAY) ||
                   (!d.has() && v0->get_type().is_convertible(val_t::type_t::SEQUENCE))) {
            // The above if statement is complicated because it produces better
            // error messages on e.g. strings.
            if (counted_t<val_t> no_recurse = optarg(env, "_NO_RECURSE_")) {
                rcheck(no_recurse->as_bool() == false, base_exc_t::GENERIC,
                       strprintf("Cannot perform %s on a sequence of sequences.", name()));
            }

            compile_env_t compile_env(env->scope.compute_visibility());
            counted_t<func_term_t> func_term = make_counted<func_term_t>(&compile_env, func);
            counted_t<func_t> func = func_term->eval_to_func(env->scope);

            switch (poly_type) {
            case MAP:
                return new_val(env->env, v0->as_seq(env->env)->map(func));
            case FILTER:
                return new_val(env->env,
                               v0->as_seq(env->env)->filter(func, counted_t<func_t>()));
            case SKIP_MAP:
                return new_val(env->env, v0->as_seq(env->env)->concatmap(func));
            default: unreachable();
            }
        }

        rfail_typed_target(
            v0, "Cannot perform %s on a non-object non-sequence `%s`.",
            name(), v0->trunc_print().c_str());
    }

    poly_type_t poly_type;
    protob_t<Term> func;
};

class pluck_term_t : public obj_or_seq_op_term_t {
public:
    pluck_term_t(compile_env_t *env, const protob_t<const Term> &term) :
        obj_or_seq_op_term_t(env, term, MAP, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval(scope_env_t *env, counted_t<val_t> v0) {
        counted_t<const datum_t> obj = v0->as_datum();
        r_sanity_check(obj->get_type() == datum_t::R_OBJECT);

        const size_t n = num_args();
        std::vector<counted_t<const datum_t> > paths;
        paths.reserve(n - 1);
        for (size_t i = 1; i < n; ++i) {
            paths.push_back(arg(env, i)->as_datum());
        }
        pathspec_t pathspec(make_counted<const datum_t>(std::move(paths)), this);
        return new_val(project(obj, pathspec, DONT_RECURSE));
    }
    virtual const char *name() const { return "pluck"; }
};

class without_term_t : public obj_or_seq_op_term_t {
public:
    without_term_t(compile_env_t *env, const protob_t<const Term> &term) :
        obj_or_seq_op_term_t(env, term, MAP, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval(scope_env_t *env, counted_t<val_t> v0) {
        counted_t<const datum_t> obj = v0->as_datum();
        r_sanity_check(obj->get_type() == datum_t::R_OBJECT);

        std::vector<counted_t<const datum_t> > paths;
        const size_t n = num_args();
        paths.reserve(n - 1);
        for (size_t i = 1; i < n; ++i) {
            paths.push_back(arg(env, i)->as_datum());
        }
        pathspec_t pathspec(make_counted<const datum_t>(std::move(paths)), this);
        return new_val(unproject(obj, pathspec, DONT_RECURSE));
    }
    virtual const char *name() const { return "without"; }
};

class literal_term_t : public op_term_t {
public:
    literal_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : op_term_t(env, term, argspec_t(0, 1)) { }
private:
    virtual counted_t<val_t> eval_impl(scope_env_t *env, eval_flags_t flags) {
        rcheck(flags & LITERAL_OK, base_exc_t::GENERIC,
               "Stray literal keyword found, literal can only be present inside merge "
               "and cannot nest inside other literals.");
        datum_ptr_t res(datum_t::R_OBJECT);
        bool clobber = res.add(datum_t::reql_type_string,
                               make_counted<const datum_t>(pseudo::literal_string));
        if (num_args() == 1) {
            clobber |= res.add(pseudo::value_key, arg(env, 0)->as_datum());
        }

        r_sanity_check(!clobber);
        std::set<std::string> permissible_ptypes;
        permissible_ptypes.insert(pseudo::literal_string);
        return new_val(res.to_counted(permissible_ptypes));
    }
    virtual const char *name() const { return "literal"; }
};

class merge_term_t : public obj_or_seq_op_term_t {
public:
    merge_term_t(compile_env_t *env, const protob_t<const Term> &term) :
        obj_or_seq_op_term_t(env, term, MAP, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval(scope_env_t *env, counted_t<val_t> v0) {
        counted_t<const datum_t> d = v0->as_datum();
        for (size_t i = 1; i < num_args(); ++i) {
            counted_t<val_t> v = arg(env, i, LITERAL_OK);

            // We branch here because compiling functions is expensive, and
            // `obj_eval` may be called many many times.
            if (v->get_type().is_convertible(val_t::type_t::DATUM)) {
                d = d->merge(v->as_datum());
            } else {
                auto f = arg(env, i, LITERAL_OK)->as_func(CONSTANT_SHORTCUT);
                d = d->merge(f->call(env->env, d, LITERAL_OK)->as_datum());
            }
        }
        return new_val(d);
    }
    virtual const char *name() const { return "merge"; }
};

class has_fields_term_t : public obj_or_seq_op_term_t {
public:
    has_fields_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : obj_or_seq_op_term_t(env, term, FILTER, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval(scope_env_t *env, counted_t<val_t> v0) {
        counted_t<const datum_t> obj = v0->as_datum();
        r_sanity_check(obj->get_type() == datum_t::R_OBJECT);

        std::vector<counted_t<const datum_t> > paths;
        const size_t n = num_args();
        paths.reserve(n - 1);
        for (size_t i = 1; i < n; ++i) {
            paths.push_back(arg(env, i)->as_datum());
        }
        pathspec_t pathspec(make_counted<const datum_t>(std::move(paths)), this);
        return new_val_bool(contains(obj, pathspec));
    }
    virtual const char *name() const { return "has_fields"; }
};

class get_field_term_t : public obj_or_seq_op_term_t {
public:
    get_field_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : obj_or_seq_op_term_t(env, term, SKIP_MAP, argspec_t(2)) { }
private:
    virtual counted_t<val_t> obj_eval(scope_env_t *env, counted_t<val_t> v0) {
        return new_val(v0->as_datum()->get(arg(env, 1)->as_str()));
    }
    virtual const char *name() const { return "get_field"; }
};

counted_t<term_t> make_get_field_term(compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<get_field_term_t>(env, term);
}

counted_t<term_t> make_has_fields_term(compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<has_fields_term_t>(env, term);
}

counted_t<term_t> make_pluck_term(compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<pluck_term_t>(env, term);
}
counted_t<term_t> make_without_term(compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<without_term_t>(env, term);
}
counted_t<term_t> make_literal_term(compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<literal_term_t>(env, term);
}
counted_t<term_t> make_merge_term(compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<merge_term_t>(env, term);
}

} // namespace ql
<commit_msg>fixed double-arg evaluation<commit_after>// Copyright 2010-2013 RethinkDB, all rights reserved.
#include "rdb_protocol/terms/terms.hpp"

#include <string>

#include "rdb_protocol/error.hpp"
#include "rdb_protocol/func.hpp"
#include "rdb_protocol/op.hpp"
#include "rdb_protocol/pathspec.hpp"
#include "rdb_protocol/pb_utils.hpp"
#include "rdb_protocol/pseudo_literal.hpp"
#include "rdb_protocol/minidriver.hpp"

#pragma GCC diagnostic ignored "-Wshadow"

namespace ql {

// This term is used for functions that are polymorphic on objects and
// sequences, like `pluck`.  It will handle the polymorphism; terms inheriting
// from it just need to implement evaluation on objects (`obj_eval`).
class obj_or_seq_op_term_t : public op_term_t {
public:
    enum poly_type_t {
        MAP = 0,
        FILTER = 1,
        SKIP_MAP = 2
    };
    obj_or_seq_op_term_t(compile_env_t *env, protob_t<const Term> term,
                         poly_type_t _poly_type, argspec_t argspec)
        : op_term_t(env, term, argspec, optargspec_t({"_NO_RECURSE_"})),
          poly_type(_poly_type), func(make_counted_term()) {

        auto varnum = pb::dummy_var_t::OBJORSEQ_VARNUM;

        // body is a new reql expression similar to term except that the first argument
        // is replaced by a new variable.
        // For example, foo.pluck('a') becomes varnum.pluck('a')
        r::reql_t body = r::var(varnum).call(term->type());
        body.copy_args_from_term(*term, 1);
        body.add_arg(r::optarg("_NO_RECURSE_", r::boolean(true)));

        switch (poly_type) {
        case MAP: {
            func->Swap(&r::fun(varnum, std::move(body)).get());
        } break;
        case FILTER: {
            func->Swap(&r::fun(varnum, std::move(body)).get());
        } break;
        case SKIP_MAP: {
            func->Swap(&r::fun(varnum, r::array(std::move(body)).default_(r::array())).get());
        } break;
        default: unreachable();
        }

        prop_bt(func.get());
    }
private:
    virtual counted_t<val_t> obj_eval(scope_env_t *env, counted_t<val_t> v0) = 0;

    virtual counted_t<val_t> eval_impl(scope_env_t *env, UNUSED eval_flags_t flags) {
        counted_t<val_t> v0 = arg(env, 0);
        counted_t<const datum_t> d;

        if (v0->get_type().is_convertible(val_t::type_t::DATUM)) {
            d = v0->as_datum();
        }

        if (d.has() && d->get_type() == datum_t::R_OBJECT) {
            return obj_eval(env, v0);
        } else if ((d.has() && d->get_type() == datum_t::R_ARRAY) ||
                   (!d.has() && v0->get_type().is_convertible(val_t::type_t::SEQUENCE))) {
            // The above if statement is complicated because it produces better
            // error messages on e.g. strings.
            if (counted_t<val_t> no_recurse = optarg(env, "_NO_RECURSE_")) {
                rcheck(no_recurse->as_bool() == false, base_exc_t::GENERIC,
                       strprintf("Cannot perform %s on a sequence of sequences.", name()));
            }

            compile_env_t compile_env(env->scope.compute_visibility());
            counted_t<func_term_t> func_term = make_counted<func_term_t>(&compile_env, func);
            counted_t<func_t> func = func_term->eval_to_func(env->scope);

            switch (poly_type) {
            case MAP:
                return new_val(env->env, v0->as_seq(env->env)->map(func));
            case FILTER:
                return new_val(env->env,
                               v0->as_seq(env->env)->filter(func, counted_t<func_t>()));
            case SKIP_MAP:
                return new_val(env->env, v0->as_seq(env->env)->concatmap(func));
            default: unreachable();
            }
        }

        rfail_typed_target(
            v0, "Cannot perform %s on a non-object non-sequence `%s`.",
            name(), v0->trunc_print().c_str());
    }

    poly_type_t poly_type;
    protob_t<Term> func;
};

class pluck_term_t : public obj_or_seq_op_term_t {
public:
    pluck_term_t(compile_env_t *env, const protob_t<const Term> &term) :
        obj_or_seq_op_term_t(env, term, MAP, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval(scope_env_t *env, counted_t<val_t> v0) {
        counted_t<const datum_t> obj = v0->as_datum();
        r_sanity_check(obj->get_type() == datum_t::R_OBJECT);

        const size_t n = num_args();
        std::vector<counted_t<const datum_t> > paths;
        paths.reserve(n - 1);
        for (size_t i = 1; i < n; ++i) {
            paths.push_back(arg(env, i)->as_datum());
        }
        pathspec_t pathspec(make_counted<const datum_t>(std::move(paths)), this);
        return new_val(project(obj, pathspec, DONT_RECURSE));
    }
    virtual const char *name() const { return "pluck"; }
};

class without_term_t : public obj_or_seq_op_term_t {
public:
    without_term_t(compile_env_t *env, const protob_t<const Term> &term) :
        obj_or_seq_op_term_t(env, term, MAP, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval(scope_env_t *env, counted_t<val_t> v0) {
        counted_t<const datum_t> obj = v0->as_datum();
        r_sanity_check(obj->get_type() == datum_t::R_OBJECT);

        std::vector<counted_t<const datum_t> > paths;
        const size_t n = num_args();
        paths.reserve(n - 1);
        for (size_t i = 1; i < n; ++i) {
            paths.push_back(arg(env, i)->as_datum());
        }
        pathspec_t pathspec(make_counted<const datum_t>(std::move(paths)), this);
        return new_val(unproject(obj, pathspec, DONT_RECURSE));
    }
    virtual const char *name() const { return "without"; }
};

class literal_term_t : public op_term_t {
public:
    literal_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : op_term_t(env, term, argspec_t(0, 1)) { }
private:
    virtual counted_t<val_t> eval_impl(scope_env_t *env, eval_flags_t flags) {
        rcheck(flags & LITERAL_OK, base_exc_t::GENERIC,
               "Stray literal keyword found, literal can only be present inside merge "
               "and cannot nest inside other literals.");
        datum_ptr_t res(datum_t::R_OBJECT);
        bool clobber = res.add(datum_t::reql_type_string,
                               make_counted<const datum_t>(pseudo::literal_string));
        if (num_args() == 1) {
            clobber |= res.add(pseudo::value_key, arg(env, 0)->as_datum());
        }

        r_sanity_check(!clobber);
        std::set<std::string> permissible_ptypes;
        permissible_ptypes.insert(pseudo::literal_string);
        return new_val(res.to_counted(permissible_ptypes));
    }
    virtual const char *name() const { return "literal"; }
};

class merge_term_t : public obj_or_seq_op_term_t {
public:
    merge_term_t(compile_env_t *env, const protob_t<const Term> &term) :
        obj_or_seq_op_term_t(env, term, MAP, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval(scope_env_t *env, counted_t<val_t> v0) {
        counted_t<const datum_t> d = v0->as_datum();
        for (size_t i = 1; i < num_args(); ++i) {
            counted_t<val_t> v = arg(env, i, LITERAL_OK);

            // We branch here because compiling functions is expensive, and
            // `obj_eval` may be called many many times.
            if (v->get_type().is_convertible(val_t::type_t::DATUM)) {
                d = d->merge(v->as_datum());
            } else {
                auto f = v->as_func(CONSTANT_SHORTCUT);
                d = d->merge(f->call(env->env, d, LITERAL_OK)->as_datum());
            }
        }
        return new_val(d);
    }
    virtual const char *name() const { return "merge"; }
};

class has_fields_term_t : public obj_or_seq_op_term_t {
public:
    has_fields_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : obj_or_seq_op_term_t(env, term, FILTER, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval(scope_env_t *env, counted_t<val_t> v0) {
        counted_t<const datum_t> obj = v0->as_datum();
        r_sanity_check(obj->get_type() == datum_t::R_OBJECT);

        std::vector<counted_t<const datum_t> > paths;
        const size_t n = num_args();
        paths.reserve(n - 1);
        for (size_t i = 1; i < n; ++i) {
            paths.push_back(arg(env, i)->as_datum());
        }
        pathspec_t pathspec(make_counted<const datum_t>(std::move(paths)), this);
        return new_val_bool(contains(obj, pathspec));
    }
    virtual const char *name() const { return "has_fields"; }
};

class get_field_term_t : public obj_or_seq_op_term_t {
public:
    get_field_term_t(compile_env_t *env, const protob_t<const Term> &term)
        : obj_or_seq_op_term_t(env, term, SKIP_MAP, argspec_t(2)) { }
private:
    virtual counted_t<val_t> obj_eval(scope_env_t *env, counted_t<val_t> v0) {
        return new_val(v0->as_datum()->get(arg(env, 1)->as_str()));
    }
    virtual const char *name() const { return "get_field"; }
};

counted_t<term_t> make_get_field_term(compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<get_field_term_t>(env, term);
}

counted_t<term_t> make_has_fields_term(compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<has_fields_term_t>(env, term);
}

counted_t<term_t> make_pluck_term(compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<pluck_term_t>(env, term);
}
counted_t<term_t> make_without_term(compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<without_term_t>(env, term);
}
counted_t<term_t> make_literal_term(compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<literal_term_t>(env, term);
}
counted_t<term_t> make_merge_term(compile_env_t *env, const protob_t<const Term> &term) {
    return make_counted<merge_term_t>(env, term);
}

} // namespace ql
<|endoftext|>


<commit_before>#include <iostream> //cout
#include <string>
#include "general.h"
#include <gmd.h> 	//LaGenMatDouble
#include <laslv.h>  //LUFactorizeIP, LaLUInverseIP, etc.
#include <blas3pp.h>
#include <random>   //random_device, mt19937
#include <cstdlib>	//rand, srand
#include <math.h>

using namespace std;
						/* ------ NOTES ------ */
// be careful with row ordering
	// true = row ordered + DOES NOT link to the array it was made with
	// false = column ordered + LINKS to the array it was made with
// check that everything is reset to 0 or I where needed

						/* ------ WORKING ------ */

/* -- Output -- */
void print_initial_parameters(double U, double beta, double lambda, double delta_tau, int time_size, int lattice_size){
	cout << "no of lattice points = " << lattice_size << endl;
	cout << "no of time slices = " << time_size << endl;
	cout << "U = " << U << endl;
	cout << "beta = " << beta << endl;
	cout << "lambda = " << lambda << endl;
	cout << "delta tau = " << delta_tau << endl;
}

/* -- Generation -- */
// Random Numbers
// Structure

/* -- Calculation -- */
// Initial Parameters
void initial_parameter_calculation(const double U, const double beta, double& lambda, double& delta_tau, int& time_size){
    lambda = acoshf(exp(sqrt(0.125*U)/2));  // by definition
    time_size = ceil(beta / lambda);        // by definition
    delta_tau = beta / time_size;           // = sqrt(0.125 / U) by convension
}
// Matrix Operations
// Weights
// Testing
void test_initial_parameters(){
    double U = 1, beta = 10, lambda, delta_tau;
    int lattice_size = 5, time_size;
    initial_parameter_calculation(U, beta, lambda, delta_tau, time_size);
    print_initial_parameters(U, beta, lambda, delta_tau, time_size, lattice_size);
}

						/* ------ TO TEST ------ */
//...

void print_matrix(const LaGenMatComplex& matrix){
	cout << matrix << endl;
}
void print_matrix(const LaGenMatComplex& matrix, const string name){
	cout << name << ":" << endl << matrix << endl;
}
void print_vector(const LaVectorComplex& vector, const string name){
    cout << name << ":" << endl << vector << endl;
}
int generate_spins(){
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dist(0, 1);
    return (dist(gen) % 2)*2 - 1;
}
void generate_lattice(const int lattice_size, const int time_size, LaGenMatComplex& lattice){
    int matrix_volume = lattice_size * time_size;
    COMPLEX elements[matrix_volume];
    for(int row = 0; row < time_size; row++){
        for(int column = 0; column < lattice_size; column++){
            int i = row * lattice_size + column;
            cout << "element = " << i << endl;
            // elements[i].r = generate_spins();
            // elements[i].i = 0;
        }
    }
    // lattice = LaGenMatComplex(elements, lattice_size, time_size, false);
}
void test_generate_lattice(){
    int lattice_size = 5, time_size = 17;
    LaGenMatComplex lattice;
    generate_lattice(lattice_size, time_size, lattice);
    print_matrix(lattice, "lattice");
}
void generate_H(const int lattice_size, LaGenMatComplex& H){
    /* initialise everything */
    int matrix_volume = lattice_size * lattice_size, n;
    COMPLEX elements[matrix_volume];

    /* generate the matrix */
    for(int i = 0; i < lattice_size; i++){
        for (int j = 0; j < lattice_size; j++) {
            n = (lattice_size * i) + j;
            //cout.width(3);
            //cout << abs(i-j);
            if(abs(i-j) == 1 || abs(i-j) == lattice_size - 1){
                elements[n].r = -1;
            }else{
                elements[n].r = 0;
            }
            elements[n].i = 0;
        }
    }

    H = LaGenMatComplex(elements, lattice_size, lattice_size, false);
}
void test_H(const int matrix_size){
    /* initialise everything */
    LaGenMatComplex H;
    LaVectorComplex eigenvalues = LaVectorComplex(matrix_size);
    LaGenMatComplex eigenvectors = LaGenMatComplex::zeros(matrix_size, matrix_size);
    /* generate matrix */
    generate_H(matrix_size, H);
    print_matrix(H);
    /* calculate eigenstuff */
    LaEigSolve(H, eigenvalues, eigenvectors);
    print_vector(eigenvalues, "eigenvalues");
    // eigenvalues are 2 cos(n pi / q), where q = the matrix size
}

						/* ------ TO CONVERT ------ */
// matrix_size          -> lattice_size or time_size
// len                  -> array_size
// matrix_eigenvstuff   -> LaEigSolve
// float                -> double

/* ------ Main QMC Program ------ */
int main(){
    test_generate_lattice();
}
<commit_msg>generate lattice - testing<commit_after>#include <iostream> //cout
#include <string>
#include "general.h"
#include <gmd.h> 	//LaGenMatDouble
#include <laslv.h>  //LUFactorizeIP, LaLUInverseIP, etc.
#include <blas3pp.h>
#include <random>   //random_device, mt19937
#include <cstdlib>	//rand, srand
#include <math.h>

using namespace std;
						/* ------ NOTES ------ */
// be careful with row ordering
	// true = row ordered + DOES NOT link to the array it was made with
	// false = column ordered + LINKS to the array it was made with
// check that everything is reset to 0 or I where needed

						/* ------ WORKING ------ */

/* -- Output -- */
void print_initial_parameters(double U, double beta, double lambda, double delta_tau, int time_size, int lattice_size){
	cout << "no of lattice points = " << lattice_size << endl;
	cout << "no of time slices = " << time_size << endl;
	cout << "U = " << U << endl;
	cout << "beta = " << beta << endl;
	cout << "lambda = " << lambda << endl;
	cout << "delta tau = " << delta_tau << endl;
}

/* -- Generation -- */
// Random Numbers
// Structure

/* -- Calculation -- */
// Initial Parameters
void initial_parameter_calculation(const double U, const double beta, double& lambda, double& delta_tau, int& time_size){
    lambda = acoshf(exp(sqrt(0.125*U)/2));  // by definition
    time_size = ceil(beta / lambda);        // by definition
    delta_tau = beta / time_size;           // = sqrt(0.125 / U) by convension
}
// Matrix Operations
// Weights
// Testing
void test_initial_parameters(){
    double U = 1, beta = 10, lambda, delta_tau;
    int lattice_size = 5, time_size;
    initial_parameter_calculation(U, beta, lambda, delta_tau, time_size);
    print_initial_parameters(U, beta, lambda, delta_tau, time_size, lattice_size);
}

						/* ------ TO TEST ------ */
//...

void print_matrix(const LaGenMatComplex& matrix){
	cout << matrix << endl;
}
void print_matrix(const LaGenMatComplex& matrix, const string name){
	cout << name << ":" << endl << matrix << endl;
}
void print_vector(const LaVectorComplex& vector, const string name){
    cout << name << ":" << endl << vector << endl;
}
int generate_spins(){
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dist(0, 1);
    return (dist(gen) % 2)*2 - 1;
}
void generate_lattice(const int lattice_size, const int time_size, LaGenMatComplex& lattice){
    int matrix_volume = lattice_size * time_size;
    COMPLEX elements[matrix_volume];
    for(int row = 0; row < time_size; row++){
        for(int column = 0; column < lattice_size; column++){
            int i = row * lattice_size + column;
            // cout << "element = " << i << endl;
            elements[i].r = generate_spins();
            elements[i].i = 0;
        }
    }
    // lattice = LaGenMatComplex(elements, lattice_size, time_size, false);
}
void test_generate_lattice(){
    int lattice_size = 5, time_size = 17;
    LaGenMatComplex lattice;
    generate_lattice(lattice_size, time_size, lattice);
    print_matrix(lattice, "lattice");
}
void generate_H(const int lattice_size, LaGenMatComplex& H){
    /* initialise everything */
    int matrix_volume = lattice_size * lattice_size, n;
    COMPLEX elements[matrix_volume];

    /* generate the matrix */
    for(int i = 0; i < lattice_size; i++){
        for (int j = 0; j < lattice_size; j++) {
            n = (lattice_size * i) + j;
            //cout.width(3);
            //cout << abs(i-j);
            if(abs(i-j) == 1 || abs(i-j) == lattice_size - 1){
                elements[n].r = -1;
            }else{
                elements[n].r = 0;
            }
            elements[n].i = 0;
        }
    }

    H = LaGenMatComplex(elements, lattice_size, lattice_size, false);
}
void test_H(const int matrix_size){
    /* initialise everything */
    LaGenMatComplex H;
    LaVectorComplex eigenvalues = LaVectorComplex(matrix_size);
    LaGenMatComplex eigenvectors = LaGenMatComplex::zeros(matrix_size, matrix_size);
    /* generate matrix */
    generate_H(matrix_size, H);
    print_matrix(H);
    /* calculate eigenstuff */
    LaEigSolve(H, eigenvalues, eigenvectors);
    print_vector(eigenvalues, "eigenvalues");
    // eigenvalues are 2 cos(n pi / q), where q = the matrix size
}

						/* ------ TO CONVERT ------ */
// matrix_size          -> lattice_size or time_size
// len                  -> array_size
// matrix_eigenvstuff   -> LaEigSolve
// float                -> double

/* ------ Main QMC Program ------ */
int main(){
    test_generate_lattice();
}
<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date$
Version:   $Revision: 1.12 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkContourUtils.h"
#include "mitkImageCast.h"
#include "ipSegmentation.h"

// explicitly instantiate the 2D version of this method
InstantiateAccessFunctionForFixedDimension_2( mitk::ContourUtils::ItkCopyFilledContourToSlice, 2, const mitk::Image*, int );

mitk::ContourUtils::ContourUtils()
{
}

mitk::ContourUtils::~ContourUtils()
{
}

mitk::Contour::Pointer mitk::ContourUtils::ProjectContourTo2DSlice(Image* slice, Contour* contourIn3D, bool itkNotUsed( correctionForIpSegmentation ), bool constrainToInside)
{
  if ( !slice || !contourIn3D ) return NULL;

  Contour::Pointer projectedContour = Contour::New();

  const Contour::PathType::VertexListType* pointsIn3D = contourIn3D->GetContourPath()->GetVertexList();
  const Geometry3D* sliceGeometry = slice->GetGeometry();
  for ( Contour::PathType::VertexListType::const_iterator iter = pointsIn3D->begin();
        iter != pointsIn3D->end();
        ++iter )
  {
    Contour::PathType::VertexType currentPointIn3DITK = *iter;
    Point3D currentPointIn3D;
    for (int i = 0; i < 3; ++i) currentPointIn3D[i] = currentPointIn3DITK[i];

    Point3D projectedPointIn2D;
    projectedPointIn2D.Fill(0.0);
    sliceGeometry->WorldToIndex( currentPointIn3D, projectedPointIn2D );
    MITK_INFO << "world point " << currentPointIn3D << " in index is " << projectedPointIn2D;

    if ( !sliceGeometry->IsIndexInside( projectedPointIn2D ) && constrainToInside )
    {
      MITK_INFO << "**" << currentPointIn3D << " is " << projectedPointIn2D << " --> correct it (TODO)" << std::endl;
    }

    projectedContour->AddVertex( projectedPointIn2D );
  }

  return projectedContour;
}

mitk::Contour::Pointer mitk::ContourUtils::BackProjectContourFrom2DSlice(Image* slice, Contour* contourIn2D, bool itkNotUsed( correctionForIpSegmentation ) )
{
  if ( !slice || !contourIn2D ) return NULL;

  Contour::Pointer worldContour = Contour::New();

  const Contour::PathType::VertexListType* pointsIn2D = contourIn2D->GetContourPath()->GetVertexList();
  const Geometry3D* sliceGeometry = slice->GetGeometry();
  for ( Contour::PathType::VertexListType::const_iterator iter = pointsIn2D->begin();
        iter != pointsIn2D->end();
        ++iter )
  {
    Contour::PathType::VertexType currentPointIn3DITK = *iter;
    Point3D currentPointIn2D;
    for (int i = 0; i < 3; ++i) currentPointIn2D[i] = currentPointIn3DITK[i];

    Point3D worldPointIn3D;
    worldPointIn3D.Fill(0.0);
    sliceGeometry->IndexToWorld( currentPointIn2D, worldPointIn3D );
    MITK_INFO << "index " << currentPointIn2D << " world " << worldPointIn3D << std::endl;

    worldContour->AddVertex( worldPointIn3D );
  }

  return worldContour;
}

void mitk::ContourUtils::FillContourInSlice( Contour* projectedContour, Image* sliceImage, int paintingPixelValue )
{
  // 1. Use ipSegmentation to draw a filled(!) contour into a new 8 bit 2D image, which will later be copied back to the slice.
  //    We don't work on the "real" working data, because ipSegmentation would restrict us to 8 bit images

  // convert the projected contour into a ipSegmentation format
  mitkIpInt4_t* picContour = new mitkIpInt4_t[2 * projectedContour->GetNumberOfPoints()];
  const Contour::PathType::VertexListType* pointsIn2D = projectedContour->GetContourPath()->GetVertexList();
  unsigned int index(0);
  for ( Contour::PathType::VertexListType::const_iterator iter = pointsIn2D->begin();
        iter != pointsIn2D->end();
        ++iter, ++index )
  {
    picContour[ 2 * index + 0 ] = static_cast<mitkIpInt4_t>( (*iter)[0] + 1.0 ); // +0.5 wahrscheinlich richtiger
    picContour[ 2 * index + 1 ] = static_cast<mitkIpInt4_t>( (*iter)[1] + 1.0 );
    MITK_INFO << "mitk 2d [" << (*iter)[0] << ", " << (*iter)[1] << "]  pic [" << picContour[ 2*index+0] << ", " << picContour[ 2*index+1] << "]";
  }

  assert( sliceImage->GetSliceData() );
  mitkIpPicDescriptor* originalPicSlice = sliceImage->GetSliceData()->GetPicDescriptor();
  mitkIpPicDescriptor* picSlice = ipMITKSegmentationNew( originalPicSlice );
  ipMITKSegmentationClear( picSlice );

  assert( originalPicSlice && picSlice );

  // here comes the actual contour filling algorithm (from ipSegmentation/Graphics Gems)
  ipMITKSegmentationCombineRegion ( picSlice, picContour, projectedContour->GetNumberOfPoints(), NULL, IPSEGMENTATION_OR,  1); // set to 1

  delete[] picContour;

  // 2. Copy the filled contour to the working data slice
  //    copy all pixels that are non-zero to the original image (not caring for the actual type of the working image). perhaps make the replace value a parameter ( -> general painting tool ).
  //    make the pic slice an mitk/itk image (as little ipPic code as possible), call a templated method with accessbyitk, iterate over the original and the modified slice

  Image::Pointer ipsegmentationModifiedSlice = Image::New();
  ipsegmentationModifiedSlice->Initialize( picSlice );
  ipsegmentationModifiedSlice->SetPicSlice( picSlice );

  AccessFixedDimensionByItk_2( sliceImage, ItkCopyFilledContourToSlice, 2, ipsegmentationModifiedSlice, paintingPixelValue );

  ipsegmentationModifiedSlice = NULL; // free MITK header information
  ipMITKSegmentationFree( picSlice ); // free actual memory
}

template<typename TPixel, unsigned int VImageDimension>
void mitk::ContourUtils::ItkCopyFilledContourToSlice( itk::Image<TPixel,VImageDimension>* originalSlice, const Image* filledContourSlice, int overwritevalue )
{
  typedef itk::Image<TPixel,VImageDimension> SliceType;

  typename SliceType::Pointer filledContourSliceITK;
  CastToItkImage( filledContourSlice, filledContourSliceITK );

  // now the original slice and the ipSegmentation-painted slice are in the same format, and we can just copy all pixels that are non-zero
  typedef itk::ImageRegionIterator< SliceType >       OutputIteratorType;
  typedef itk::ImageRegionConstIterator< SliceType >   InputIteratorType;

  InputIteratorType inputIterator( filledContourSliceITK, filledContourSliceITK->GetLargestPossibleRegion() );
  OutputIteratorType outputIterator( originalSlice, originalSlice->GetLargestPossibleRegion() );

  outputIterator.GoToBegin();
  inputIterator.GoToBegin();

  while ( !outputIterator.IsAtEnd() )
  {
    if ( inputIterator.Get() != 0 )
    {
      outputIterator.Set( overwritevalue );
    }

    ++outputIterator;
    ++inputIterator;
  }
}

<commit_msg>FIX (#6552): remove debug output that slows down execution considerably<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date$
Version:   $Revision: 1.12 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkContourUtils.h"
#include "mitkImageCast.h"
#include "ipSegmentation.h"

// explicitly instantiate the 2D version of this method
InstantiateAccessFunctionForFixedDimension_2( mitk::ContourUtils::ItkCopyFilledContourToSlice, 2, const mitk::Image*, int );

mitk::ContourUtils::ContourUtils()
{
}

mitk::ContourUtils::~ContourUtils()
{
}

mitk::Contour::Pointer mitk::ContourUtils::ProjectContourTo2DSlice(Image* slice, Contour* contourIn3D, bool itkNotUsed( correctionForIpSegmentation ), bool constrainToInside)
{
  if ( !slice || !contourIn3D ) return NULL;

  Contour::Pointer projectedContour = Contour::New();

  const Contour::PathType::VertexListType* pointsIn3D = contourIn3D->GetContourPath()->GetVertexList();
  const Geometry3D* sliceGeometry = slice->GetGeometry();
  for ( Contour::PathType::VertexListType::const_iterator iter = pointsIn3D->begin();
        iter != pointsIn3D->end();
        ++iter )
  {
    Contour::PathType::VertexType currentPointIn3DITK = *iter;
    Point3D currentPointIn3D;
    for (int i = 0; i < 3; ++i) currentPointIn3D[i] = currentPointIn3DITK[i];

    Point3D projectedPointIn2D;
    projectedPointIn2D.Fill(0.0);
    sliceGeometry->WorldToIndex( currentPointIn3D, projectedPointIn2D );
    // MITK_INFO << "world point " << currentPointIn3D << " in index is " << projectedPointIn2D;

    if ( !sliceGeometry->IsIndexInside( projectedPointIn2D ) && constrainToInside )
    {
      MITK_INFO << "**" << currentPointIn3D << " is " << projectedPointIn2D << " --> correct it (TODO)" << std::endl;
    }

    projectedContour->AddVertex( projectedPointIn2D );
  }

  return projectedContour;
}

mitk::Contour::Pointer mitk::ContourUtils::BackProjectContourFrom2DSlice(Image* slice, Contour* contourIn2D, bool itkNotUsed( correctionForIpSegmentation ) )
{
  if ( !slice || !contourIn2D ) return NULL;

  Contour::Pointer worldContour = Contour::New();

  const Contour::PathType::VertexListType* pointsIn2D = contourIn2D->GetContourPath()->GetVertexList();
  const Geometry3D* sliceGeometry = slice->GetGeometry();
  for ( Contour::PathType::VertexListType::const_iterator iter = pointsIn2D->begin();
        iter != pointsIn2D->end();
        ++iter )
  {
    Contour::PathType::VertexType currentPointIn3DITK = *iter;
    Point3D currentPointIn2D;
    for (int i = 0; i < 3; ++i) currentPointIn2D[i] = currentPointIn3DITK[i];

    Point3D worldPointIn3D;
    worldPointIn3D.Fill(0.0);
    sliceGeometry->IndexToWorld( currentPointIn2D, worldPointIn3D );
    //MITK_INFO << "index " << currentPointIn2D << " world " << worldPointIn3D << std::endl;

    worldContour->AddVertex( worldPointIn3D );
  }

  return worldContour;
}

void mitk::ContourUtils::FillContourInSlice( Contour* projectedContour, Image* sliceImage, int paintingPixelValue )
{
  // 1. Use ipSegmentation to draw a filled(!) contour into a new 8 bit 2D image, which will later be copied back to the slice.
  //    We don't work on the "real" working data, because ipSegmentation would restrict us to 8 bit images

  // convert the projected contour into a ipSegmentation format
  mitkIpInt4_t* picContour = new mitkIpInt4_t[2 * projectedContour->GetNumberOfPoints()];
  const Contour::PathType::VertexListType* pointsIn2D = projectedContour->GetContourPath()->GetVertexList();
  unsigned int index(0);
  for ( Contour::PathType::VertexListType::const_iterator iter = pointsIn2D->begin();
        iter != pointsIn2D->end();
        ++iter, ++index )
  {
    picContour[ 2 * index + 0 ] = static_cast<mitkIpInt4_t>( (*iter)[0] + 1.0 ); // +0.5 wahrscheinlich richtiger
    picContour[ 2 * index + 1 ] = static_cast<mitkIpInt4_t>( (*iter)[1] + 1.0 );
    //MITK_INFO << "mitk 2d [" << (*iter)[0] << ", " << (*iter)[1] << "]  pic [" << picContour[ 2*index+0] << ", " << picContour[ 2*index+1] << "]";
  }

  assert( sliceImage->GetSliceData() );
  mitkIpPicDescriptor* originalPicSlice = sliceImage->GetSliceData()->GetPicDescriptor();
  mitkIpPicDescriptor* picSlice = ipMITKSegmentationNew( originalPicSlice );
  ipMITKSegmentationClear( picSlice );

  assert( originalPicSlice && picSlice );

  // here comes the actual contour filling algorithm (from ipSegmentation/Graphics Gems)
  ipMITKSegmentationCombineRegion ( picSlice, picContour, projectedContour->GetNumberOfPoints(), NULL, IPSEGMENTATION_OR,  1); // set to 1

  delete[] picContour;

  // 2. Copy the filled contour to the working data slice
  //    copy all pixels that are non-zero to the original image (not caring for the actual type of the working image). perhaps make the replace value a parameter ( -> general painting tool ).
  //    make the pic slice an mitk/itk image (as little ipPic code as possible), call a templated method with accessbyitk, iterate over the original and the modified slice

  Image::Pointer ipsegmentationModifiedSlice = Image::New();
  ipsegmentationModifiedSlice->Initialize( picSlice );
  ipsegmentationModifiedSlice->SetPicSlice( picSlice );

  AccessFixedDimensionByItk_2( sliceImage, ItkCopyFilledContourToSlice, 2, ipsegmentationModifiedSlice, paintingPixelValue );

  ipsegmentationModifiedSlice = NULL; // free MITK header information
  ipMITKSegmentationFree( picSlice ); // free actual memory
}

template<typename TPixel, unsigned int VImageDimension>
void mitk::ContourUtils::ItkCopyFilledContourToSlice( itk::Image<TPixel,VImageDimension>* originalSlice, const Image* filledContourSlice, int overwritevalue )
{
  typedef itk::Image<TPixel,VImageDimension> SliceType;

  typename SliceType::Pointer filledContourSliceITK;
  CastToItkImage( filledContourSlice, filledContourSliceITK );

  // now the original slice and the ipSegmentation-painted slice are in the same format, and we can just copy all pixels that are non-zero
  typedef itk::ImageRegionIterator< SliceType >       OutputIteratorType;
  typedef itk::ImageRegionConstIterator< SliceType >   InputIteratorType;

  InputIteratorType inputIterator( filledContourSliceITK, filledContourSliceITK->GetLargestPossibleRegion() );
  OutputIteratorType outputIterator( originalSlice, originalSlice->GetLargestPossibleRegion() );

  outputIterator.GoToBegin();
  inputIterator.GoToBegin();

  while ( !outputIterator.IsAtEnd() )
  {
    if ( inputIterator.Get() != 0 )
    {
      outputIterator.Set( overwritevalue );
    }

    ++outputIterator;
    ++inputIterator;
  }
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * 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 "otbWrapperChoiceParameter.h"
#include "otbWrapperListViewParameter.h"
#include "otbWrapperBoolParameter.h"
#include "otbWrapperApplicationRegistry.h"
#include "otbWrapperTypes.h"
#include "otbWrapperApplication.h"

#include <vector>
#include <string>
#include <iostream>
#include <cassert>
#include <fstream>

int main(int argc, char* argv[])
{
  if (argc < 3)
    {
      std::cerr << "Usage : " << argv[0] << " name OTB_APPLICATION_PATH [out_dir]" << std::endl;
      return EXIT_FAILURE;
    }

  using namespace otb::Wrapper;

  const std::string module(argv[1]);

  /* TestApplication is removed in CMakeLists.txt */
#if 0
  if (module == "TestApplication")
    return EXIT_SUCCESS;
#endif

  ApplicationRegistry::AddApplicationPath(argv[2]);
  Application::Pointer appli =  ApplicationRegistry::CreateApplicationFaster(module.c_str());

  assert(!appli.IsNull());

  appli->Init();

  std::map<ParameterType, std::string> parameterTypeToString;

  parameterTypeToString[ParameterType_Empty] = "QgsProcessingParameterBoolean";
  parameterTypeToString[ParameterType_Bool] = "QgsProcessingParameterBoolean";
  parameterTypeToString[ParameterType_Int] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_Float] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_RAM] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_Radius] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_Choice] = "OTBParameterChoice";
  parameterTypeToString[ParameterType_String] = "QgsProcessingParameterString";
  parameterTypeToString[ParameterType_InputImage] = "QgsProcessingParameterRasterLayer";
  parameterTypeToString[ParameterType_InputFilename] = "QgsProcessingParameterFile";
  parameterTypeToString[ParameterType_InputImageList] = "QgsProcessingParameterMultipleLayers";
  parameterTypeToString[ParameterType_InputVectorData] = "QgsProcessingParameterVectorLayer";
  parameterTypeToString[ParameterType_InputFilenameList] = "QgsProcessingParameterMultipleLayers";
  parameterTypeToString[ParameterType_InputVectorDataList] = "QgsProcessingParameterMultipleLayers";
  parameterTypeToString[ParameterType_OutputImage] = "QgsProcessingParameterRasterDestination";
  parameterTypeToString[ParameterType_OutputVectorData] = "QgsProcessingParameterVectorDestination";
  parameterTypeToString[ParameterType_OutputFilename] = "QgsProcessingParameterFileDestination";
  parameterTypeToString[ParameterType_Directory] = "QgsProcessingParameterFile";
  //TODO
  parameterTypeToString[ParameterType_StringList] = "QgsProcessingParameterString";

  const std::vector<std::string> appKeyList = appli->GetParametersKeys(true);
  const unsigned int nbOfParam = appKeyList.size();

  std::string output_file = module + ".txt";
  std::string  algs_txt = "algs.txt";
  if (argc > 3) {
   #if defined(WIN32)
   std::string output_dir = std::string(argv[3]) + "\\";
   #else
   std::string output_dir = std::string(argv[3]) + "/";
   #endif
    output_file = output_dir + module + ".txt";
    algs_txt = output_dir +  "algs.txt";
    }

  #if 0
  std::cout << "output_file: " << output_file << std::endl;
  std::cout << "algs_txt: " << algs_txt << std::endl;
  #endif
  std::ofstream dFile;
  dFile.open (output_file, std::ios::out);
  std::cerr << "Writing " << output_file << std::endl;

  std::string output_parameter_name;
  bool hasRasterOutput = false;
  for (unsigned int i = 0; i < nbOfParam; i++)
    {
      Parameter::Pointer param = appli->GetParameterByKey(appKeyList[i]);
      if (param->GetMandatory())
	{
	  ParameterType type = appli->GetParameterType(appKeyList[i]);
	  if (type == ParameterType_OutputImage )
	    {
	      output_parameter_name = appKeyList[i];
	      hasRasterOutput = true;
	    }
	}
    }

  if(output_parameter_name.empty())
    dFile << module << std::endl;
  else
    dFile << module << "|" <<  output_parameter_name << std::endl;

  dFile << appli->GetDescription() << std::endl;
  const std::string group = appli->GetDocTags().size() > 0 ? appli->GetDocTags()[0] : "UNCLASSIFIED";
  dFile << group << std::endl;

  for (unsigned int i = 0; i < nbOfParam; i++)
    {
      const std::string name = appKeyList[i];

      Parameter::Pointer param = appli->GetParameterByKey(name);
      ParameterType type = appli->GetParameterType(name);
      const std::string description = param->GetName();
      const std::string qgis_type = parameterTypeToString[type];

      //ListView parameters types are added as N number of QgsParameterBoolean where N being
      //number of items in a listview.
      //Example case: RadiometricIndices application
      //For next update of plugin code ListView can use custom widget wrapper and behave
      //exactly like OTB.
      if(type == ParameterType_ListView)
	{
	  ListViewParameter *lparam = dynamic_cast<ListViewParameter*>(param.GetPointer());
	  for( unsigned int c = 0; c < lparam->GetNbChoices(); ++c )
	    dFile << "QgsProcessingParameterBoolean|"
		  << lparam->GetChoiceKey(c)  << "|"
		  << lparam->GetChoiceName(c)
		  << "|False|True" << std::endl;
	}

      if (  type == ParameterType_Group  ||
	    type == ParameterType_OutputProcessXML  ||
	    type == ParameterType_InputProcessXML  ||
	    type == ParameterType_ListView ||
	    type == ParameterType_RAM
	    )
	{
	  // group parameter cannot have any value.
	  //outxml and inxml parameters are not relevant for QGIS and is considered a bit noisy
	  //ram is added by qgis-otb processing provider plugin as an advanced parameter for all apps
	  //listview is a special case. We indeed add them to descriptor file but with different logic.
	  continue;
	}

      assert(!qgis_type.empty());
      if(qgis_type.empty())
	{
	  std::cerr << "No mapping found for parameter '" <<name <<"' type=" << type << std::endl;
	  return EXIT_FAILURE;
	}

      bool isDestination = false;

      dFile << qgis_type << "|" << name << "|" << description;

      std::string default_value = "None";
      if (type == ParameterType_Int)
	{
	  dFile << "|QgsProcessingParameterNumber.Integer";
	  default_value = param->HasValue() ? appli->GetParameterAsString(name): "0";
	}
      else if (type == ParameterType_Float)
	{
	  dFile << "|QgsProcessingParameterNumber.Double";
	  default_value = param->HasValue() ? appli->GetParameterAsString(name): "0";
	}
      else if (type == ParameterType_Radius)
	{
	  dFile << "|QgsProcessingParameterNumber.Integer";
	  default_value = param->HasValue() ? appli->GetParameterAsString(name): "0";
	}
      else if(type == ParameterType_InputFilename)
	{
	  dFile << "|QgsProcessingParameterFile.File|txt";
	}
      else if(type == ParameterType_Directory)
	{
	  dFile << "|QgsProcessingParameterFile.Folder|False";
	}
      else if (type == ParameterType_InputImageList)
	{
	   dFile << "|3";
	}
      else if (type == ParameterType_InputVectorDataList)
	{
	  dFile << "|-1";
	}
      else if (type == ParameterType_InputVectorData)
	{
	  dFile << "|-1";
	}
      else if(type == ParameterType_InputFilenameList)
	{
	  dFile << "|4";
	}
      else if (type == ParameterType_InputImage)
	{
	  //default is None and nothing to add to dFile
	}
      else if(type ==ParameterType_String)
	{
	  //default is None and nothing to add to dFile
	}
      else if(type ==ParameterType_StringList)
	{
	  //default is None and nothing to add to dFile
	}
      else if(type == ParameterType_Bool)
	{
	  //BoolParameter *bparam = dynamic_cast<BoolParameter*>(param.GetPointer());
	  //default_value = bparam->GetValueAsString();
	  default_value =  appli->GetParameterAsString(name);
	}
      else if(type == ParameterType_Choice)
	{
	  std::vector<std::string>  key_list  = appli->GetChoiceKeys(name);
	  std::string values = "";
	  for( auto k : key_list)
	    values += k + ";";

	  values.pop_back();
	  dFile << "|" << values ;
	  ChoiceParameter *cparam = dynamic_cast<ChoiceParameter*>(param.GetPointer());
	  default_value = std::to_string(cparam->GetValue());
	}
      else if(type == ParameterType_OutputVectorData ||
	      type == ParameterType_OutputImage ||
	      type == ParameterType_OutputFilename)
	{
	  //no need for default_value, optional and extra fields in dFile
	  //if parameter is a destination type. qgis_type|name|description is enough.
	  //so we simply set isDestination to true and skip to end to append a new line.
	  isDestination =  true;
	}
      else
	{
     	  std::cout << "ERROR: default_value is empty for '" << name << "' type='" << qgis_type << "'" << std::endl;
	  return EXIT_FAILURE;
	}

      if (!isDestination)
	{
	  //const char*  optional = param->GetMandatory() ? "False" : "True";
	  std::string optional;
	  if (param->GetMandatory())
	    if (param->HasValue())
	      {
		optional = "True";
	      }
	    else{
	      optional = "False";
	    }
	  else {
	    optional = "True";
	  }

	  dFile << "|" << default_value << "|" << optional;
	}
      dFile << std::endl;
   }

  dFile.close();

  std::ofstream indexFile;
  indexFile.open (algs_txt, std::ios::out | std::ios::app );
  indexFile << group << "|" << module << std::endl;
  indexFile.close();
  return EXIT_SUCCESS;
}

<commit_msg>ENH: fallback type for ListView<commit_after>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * 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 "otbWrapperChoiceParameter.h"
#include "otbWrapperListViewParameter.h"
#include "otbWrapperBoolParameter.h"
#include "otbWrapperApplicationRegistry.h"
#include "otbWrapperTypes.h"
#include "otbWrapperApplication.h"

#include <vector>
#include <string>
#include <iostream>
#include <cassert>
#include <fstream>

int main(int argc, char* argv[])
{
  if (argc < 3)
    {
      std::cerr << "Usage : " << argv[0] << " name OTB_APPLICATION_PATH [out_dir]" << std::endl;
      return EXIT_FAILURE;
    }

  using namespace otb::Wrapper;

  const std::string module(argv[1]);

  /* TestApplication is removed in CMakeLists.txt */
#if 0
  if (module == "TestApplication")
    return EXIT_SUCCESS;
#endif

  ApplicationRegistry::AddApplicationPath(argv[2]);
  Application::Pointer appli =  ApplicationRegistry::CreateApplicationFaster(module.c_str());

  assert(!appli.IsNull());

  appli->Init();

  std::map<ParameterType, std::string> parameterTypeToString;

  parameterTypeToString[ParameterType_Empty] = "QgsProcessingParameterBoolean";
  parameterTypeToString[ParameterType_Bool] = "QgsProcessingParameterBoolean";
  parameterTypeToString[ParameterType_Int] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_Float] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_RAM] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_Radius] = "QgsProcessingParameterNumber";
  parameterTypeToString[ParameterType_Choice] = "OTBParameterChoice";
  parameterTypeToString[ParameterType_String] = "QgsProcessingParameterString";
  parameterTypeToString[ParameterType_InputImage] = "QgsProcessingParameterRasterLayer";
  parameterTypeToString[ParameterType_InputFilename] = "QgsProcessingParameterFile";
  parameterTypeToString[ParameterType_InputImageList] = "QgsProcessingParameterMultipleLayers";
  parameterTypeToString[ParameterType_InputVectorData] = "QgsProcessingParameterVectorLayer";
  parameterTypeToString[ParameterType_InputFilenameList] = "QgsProcessingParameterMultipleLayers";
  parameterTypeToString[ParameterType_InputVectorDataList] = "QgsProcessingParameterMultipleLayers";
  parameterTypeToString[ParameterType_OutputImage] = "QgsProcessingParameterRasterDestination";
  parameterTypeToString[ParameterType_OutputVectorData] = "QgsProcessingParameterVectorDestination";
  parameterTypeToString[ParameterType_OutputFilename] = "QgsProcessingParameterFileDestination";
  parameterTypeToString[ParameterType_Directory] = "QgsProcessingParameterFile";
  //TODO
  parameterTypeToString[ParameterType_StringList] = "QgsProcessingParameterString";

  //ListView parameters are treated as plain string (QLineEdit) in qgis processing ui.
  //This seems rather unpleasant when comparing Qgis processing with Monteverdi/Mapla in OTB
  //We tried to push something simple with checkboxes but its too risky for this version
  //and clock is ticking...
  //
  parameterTypeToString[ParameterType_ListView] = "QgsProcessingParameterString";

  //For next update of plugin code ListView should use a custom widget wrapper and behave
  //exactly like OTB Mapla. And this #if 0 block is our TODO remainder.
  #if 0
  parameterTypeToString[ParameterType_ListView] = "OTBParameterListView";
  #endif

  const std::vector<std::string> appKeyList = appli->GetParametersKeys(true);
  const unsigned int nbOfParam = appKeyList.size();

  std::string output_file = module + ".txt";
  std::string  algs_txt = "algs.txt";
  if (argc > 3) {
   #if defined(WIN32)
   std::string output_dir = std::string(argv[3]) + "\\";
   #else
   std::string output_dir = std::string(argv[3]) + "/";
   #endif
    output_file = output_dir + module + ".txt";
    algs_txt = output_dir +  "algs.txt";
    }

  #if 0
  std::cout << "output_file: " << output_file << std::endl;
  std::cout << "algs_txt: " << algs_txt << std::endl;
  #endif
  std::ofstream dFile;
  dFile.open (output_file, std::ios::out);
  std::cerr << "Writing " << output_file << std::endl;

  std::string output_parameter_name;
  bool hasRasterOutput = false;
  for (unsigned int i = 0; i < nbOfParam; i++)
    {
      Parameter::Pointer param = appli->GetParameterByKey(appKeyList[i]);
      if (param->GetMandatory())
	{
	  ParameterType type = appli->GetParameterType(appKeyList[i]);
	  if (type == ParameterType_OutputImage )
	    {
	      output_parameter_name = appKeyList[i];
	      hasRasterOutput = true;
	    }
	}
    }

  if(output_parameter_name.empty())
    dFile << module << std::endl;
  else
    dFile << module << "|" <<  output_parameter_name << std::endl;

  dFile << appli->GetDescription() << std::endl;
  const std::string group = appli->GetDocTags().size() > 0 ? appli->GetDocTags()[0] : "UNCLASSIFIED";
  dFile << group << std::endl;

  for (unsigned int i = 0; i < nbOfParam; i++)
    {
      const std::string name = appKeyList[i];

      Parameter::Pointer param = appli->GetParameterByKey(name);
      ParameterType type = appli->GetParameterType(name);
      const std::string description = param->GetName();
      const std::string qgis_type = parameterTypeToString[type];

      if (  type == ParameterType_Group  ||
	    type == ParameterType_OutputProcessXML  ||
	    type == ParameterType_InputProcessXML  ||
	    type == ParameterType_RAM
	    )
	{
	  // group parameter cannot have any value.
	  //outxml and inxml parameters are not relevant for QGIS and is considered a bit noisy
	  //ram is added by qgis-otb processing provider plugin as an advanced parameter for all apps
	  //listview is a special case. We indeed add them to descriptor file but with different logic.
	  continue;
	}

      assert(!qgis_type.empty());
      if(qgis_type.empty())
	{
	  std::cerr << "No mapping found for parameter '" <<name <<"' type=" << type << std::endl;
	  return EXIT_FAILURE;
	}

      bool isDestination = false;

      dFile << qgis_type << "|" << name << "|" << description;

      std::string default_value = "None";
      if (type == ParameterType_Int)
	{
	  dFile << "|QgsProcessingParameterNumber.Integer";
	  default_value = param->HasValue() ? appli->GetParameterAsString(name): "0";
	}
      else if (type == ParameterType_Float)
	{
	  dFile << "|QgsProcessingParameterNumber.Double";
	  default_value = param->HasValue() ? appli->GetParameterAsString(name): "0";
	}
      else if (type == ParameterType_Radius)
	{
	  dFile << "|QgsProcessingParameterNumber.Integer";
	  default_value = param->HasValue() ? appli->GetParameterAsString(name): "0";
	}
      else if(type == ParameterType_InputFilename)
	{
	  dFile << "|QgsProcessingParameterFile.File|txt";
	}
      else if(type == ParameterType_Directory)
	{
	  dFile << "|QgsProcessingParameterFile.Folder|False";
	}
      else if (type == ParameterType_InputImageList)
	{
	   dFile << "|3";
	}
      else if (type == ParameterType_InputVectorDataList)
	{
	  dFile << "|-1";
	}
      else if (type == ParameterType_InputVectorData)
	{
	  dFile << "|-1";
	}
      else if(type == ParameterType_InputFilenameList)
	{
	  dFile << "|4";
	}
      else if (type == ParameterType_InputImage)
	{
	  //default is None and nothing to add to dFile
	}
      else if(type ==ParameterType_String)
	{
	  //default is None and nothing to add to dFile
	}
      else if(type ==ParameterType_StringList)
	{
	  //default is None and nothing to add to dFile
	}
      else if(type ==ParameterType_ListView)
	{
	  //default is None and nothing to add to dFile
	}
      else if(type == ParameterType_Bool)
	{
	  //BoolParameter *bparam = dynamic_cast<BoolParameter*>(param.GetPointer());
	  //default_value = bparam->GetValueAsString();
	  default_value =  appli->GetParameterAsString(name);
	}
      else if(type == ParameterType_Choice)
	{
	  std::vector<std::string>  key_list  = appli->GetChoiceKeys(name);
	  std::string values = "";
	  for( auto k : key_list)
	    values += k + ";";

	  values.pop_back();
	  dFile << "|" << values ;
	  ChoiceParameter *cparam = dynamic_cast<ChoiceParameter*>(param.GetPointer());
	  default_value = std::to_string(cparam->GetValue());
	}
      else if(type == ParameterType_OutputVectorData ||
	      type == ParameterType_OutputImage ||
	      type == ParameterType_OutputFilename)
	{
	  //no need for default_value, optional and extra fields in dFile
	  //if parameter is a destination type. qgis_type|name|description is enough.
	  //so we simply set isDestination to true and skip to end to append a new line.
	  isDestination =  true;
	}
      else
	{
     	  std::cout << "ERROR: default_value is empty for '" << name << "' type='" << qgis_type << "'" << std::endl;
	  return EXIT_FAILURE;
	}

      if (!isDestination)
	{
	  //const char*  optional = param->GetMandatory() ? "False" : "True";
	  std::string optional;
	  if (param->GetMandatory())
	    if (param->HasValue())
	      {
		optional = "True";
	      }
	    else{
	      optional = "False";
	    }
	  else {
	    optional = "True";
	  }

	  dFile << "|" << default_value << "|" << optional;
	}
      dFile << std::endl;
   }

  dFile.close();

  std::ofstream indexFile;
  indexFile.open (algs_txt, std::ios::out | std::ios::app );
  indexFile << group << "|" << module << std::endl;
  indexFile.close();
  return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkGDCMImageIO.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

  Portions of this code are covered under the VTK copyright.
  See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkGDCMImageIO.h"
#include "gdcmFile.h"
#include "gdcmHeaderHelper.h"
#include <fstream>

namespace itk
{

GDCMImageIO::GDCMImageIO()
{
//  this->SetNumberOfDimensions(2); //default
  m_ByteOrder = LittleEndian; //default
  m_FileType = Binary;  //default...always true
  m_RescaleSlope = 1.0;
  m_RescaleIntercept = 0.0;
}

GDCMImageIO::~GDCMImageIO()
{
}

bool GDCMImageIO::OpenGDCMFileForReading(std::ifstream& os,
                                         const char* filename)

{
  // Make sure that we have a file to
  if ( filename == "" )
    {
    itkExceptionMacro(<<"A FileName must be specified.");
    return false;
    }

  // Close file from any previous image
  if ( os.is_open() )
    {
    os.close();
    }

  // Open the new file for reading
  itkDebugMacro(<< "Initialize: opening file " << filename);

  // Actually open the file
  os.open( filename, std::ios::in | std::ios::binary );

  if ( os.fail() )
    {
    return false;
    }

  return true;
}

bool GDCMImageIO::OpenGDCMFileForWriting(std::ofstream& os,
                                         const char* filename)

{
  // Make sure that we have a file to
  if ( filename == "" )
    {
    itkExceptionMacro(<<"A FileName must be specified.");
    return false;
    }

  // Close file from any previous image
  if ( os.is_open() )
    {
    os.close();
    }

  // Open the new file for writing
  itkDebugMacro(<< "Initialize: opening file " << filename);

#ifdef __sgi
  // Create the file. This is required on some older sgi's
  std::ofstream tFile(filename,std::ios::out);
  tFile.close();
#endif

  // Actually open the file
  os.open( filename, std::ios::out | std::ios::binary );

  if( os.fail() )
    {
    itkExceptionMacro(<< "Could not open file for writing: " << filename);
    return false;
    }

  return true;
}

// This method will only test if the header looks like a
//GDCM image file.
bool GDCMImageIO::CanReadFile(const char* filename)
{
  std::ifstream file;
  char buffer[256];
  std::string fname(filename);

  if(  fname == "" )
    {
    itkDebugMacro(<<"No filename specified.");
    return false;
    }

  bool extensionFound = false;
  std::string::size_type sprPos = fname.rfind(".dcm");  //acr nema ??
  if ((sprPos != std::string::npos)
      && (sprPos == fname.length() - 4))
    {
    extensionFound = true;
    }

  if( !extensionFound )
    {
    itkDebugMacro(<<"The filename extension is not recognized");
    return false;
    }

  //Check for file existence:
  if ( ! this->OpenGDCMFileForReading(file, filename))
    {
    return false;
    }

  // Check to see if its a valid dicom file gdcm is able to parse:
  //We are parsing the header one time here:
  gdcmHeaderHelper GdcmHeader(filename);
  if (!GdcmHeader.IsReadable())
    {
    itkExceptionMacro("Gdcm cannot parse file " << filename );
    return false;
    }

  //For later : For 2d stack dicom:
  //we should not mix insoncistent on pixel type
  //GdcmHeader.GetPixelType();
  //we should not mix insoncistent on image size
  //GdcmHeader.GetXSize(); GdcmHeader.GetYSize(); GdcmHeader.GetZSize();
  //spacing:
  //GdcmHeader.GetXSpacing(); GdcmHeader.GetYSpacing(); ...
  //GdcmHeader.GetXOrigin() ...

  return true;
}

void GDCMImageIO::Read(void* buffer)
{
  std::ifstream file;

  //read header information file:
  this->InternalReadImageInformation(file);

  //Should I handle differently dicom lut ?
  //GdcmHeader.HasLUT()

  if( !this->ReadBufferAsBinary( file, buffer, this->GetImageSizeInBytes()) )
    {
    itkExceptionMacro(<<"Read failed: Wanted "
                      << this->GetImageSizeInBytes()
                      << " bytes, but read "
                      << file.gcount() << " bytes.");
    }

  gdcmFile GdcmFile(m_FileName);
  size_t size = GdcmFile.GetImageDataSize();
  //== this->GetImageSizeInComponents()
  unsigned char *Source = (unsigned char*)GdcmFile.GetImageData();
  memcpy((void*)buffer, (void*)Source, size);

  //closing files:
  file.close();
}

void GDCMImageIO::InternalReadImageInformation(std::ifstream& file)
{
  //read header
  if ( ! this->OpenGDCMFileForReading(file, m_FileName.c_str()) )
    {
    itkExceptionMacro(<< "Cannot read requested file");
    }

  gdcmHeaderHelper GdcmHeader(m_FileName.c_str());

  // We don't need to positionate the Endian related stuff (by using
  // this->SetDataByteOrderToBigEndian() or SetDataByteOrderToLittleEndian()
  // since the reading of the file is done by gdcm.
  // But we do need to set up the data type for downstream filters:

  std::string type = GdcmHeader.GetPixelType();
  if( type == "8U")
    {
    SetPixelType(UCHAR);
    SetComponentType(UCHAR);
    }
  else if( type == "8S")
    {
    SetPixelType(CHAR);
    SetComponentType(CHAR);
    }
  else if( type == "16U")
    {
    SetPixelType(USHORT);
    SetComponentType(USHORT);
    }
  else if( type == "16S")
    {
    SetPixelType(SHORT);
    SetComponentType(SHORT);
    }
  else if( type == "32U")
    {
    SetPixelType(UINT);
    SetComponentType(UINT);
    }
  else if( type == "32S")
    {
    SetPixelType(INT);
    SetComponentType(INT);
    }
  else if ( type == "FD" )
    {
    //64 bits Double image
    SetPixelType(DOUBLE);
    SetComponentType(DOUBLE);
    }
  else
    {
    itkExceptionMacro(<<"Unrecognized type:" << type);
    }

  // set values in case we don't find them
  this->SetNumberOfDimensions(2);
  m_Dimensions[0] = GdcmHeader.GetXSize();
  m_Dimensions[1] = GdcmHeader.GetYSize();
  //m_Dimensions[2] = GdcmHeader.GetZSize();
  m_Dimensions[2] = 0;

  m_Spacing[0] = GdcmHeader.GetXSpacing();
  m_Spacing[1] = GdcmHeader.GetYSpacing();
  //  m_Spacing[2] = GdcmHeader.GetZSpacing();
  m_Spacing[2] = 0;

  m_Origin[0] = GdcmHeader.GetXOrigin();
  m_Origin[1] = GdcmHeader.GetYOrigin();
  m_Origin[2] = GdcmHeader.GetZOrigin();
  m_Origin[2] = 0;

  //For grayscale image :
  m_RescaleSlope = GdcmHeader.GetRescaleSlope();
  m_RescaleIntercept = GdcmHeader.GetRescaleIntercept();

}

void GDCMImageIO::ReadImageInformation()
{
  std::ifstream file;
  this->InternalReadImageInformation(file);
}

bool GDCMImageIO::CanWriteFile( const char* name )
{
  std::string filename = name;

  if(  filename == "" )
    {
    itkDebugMacro(<<"No filename specified.");
    return false;
    }

  bool extensionFound = false;
  std::string::size_type sprPos = filename.rfind(".dcm");
  if ((sprPos != std::string::npos)
      && (sprPos == filename.length() - 4))
    {
    extensionFound = true;
    }

  if( !extensionFound )
    {
    itkDebugMacro(<<"The filename extension is not recognized");
    return false;
    }

  return true;
}

void GDCMImageIO::WriteImageInformation()
{
}

void GDCMImageIO::Write(const void* buffer)
{
  std::ofstream file;
  if ( ! this->OpenGDCMFileForWriting(file, m_FileName.c_str()) )
    {
    return;
    }

  //gdcmFile GdcmFile();
  //GdcmFile.WriteDcmExplVR(m_FileName);
  //GdcmFile.WriteDcmImplVR(m_FileName);
  //GdcmFile.WriteRawData(m_FileName);
  file.close();
}

void GDCMImageIO::PrintSelf(std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);
}

} // end namespace itk
<commit_msg>ENH: PrintSelf defect<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkGDCMImageIO.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

  Portions of this code are covered under the VTK copyright.
  See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkGDCMImageIO.h"
#include "gdcmFile.h"
#include "gdcmHeaderHelper.h"
#include <fstream>

namespace itk
{

GDCMImageIO::GDCMImageIO()
{
//  this->SetNumberOfDimensions(2); //default
  m_ByteOrder = LittleEndian; //default
  m_FileType = Binary;  //default...always true
  m_RescaleSlope = 1.0;
  m_RescaleIntercept = 0.0;
}

GDCMImageIO::~GDCMImageIO()
{
}

bool GDCMImageIO::OpenGDCMFileForReading(std::ifstream& os,
                                         const char* filename)

{
  // Make sure that we have a file to
  if ( filename == "" )
    {
    itkExceptionMacro(<<"A FileName must be specified.");
    return false;
    }

  // Close file from any previous image
  if ( os.is_open() )
    {
    os.close();
    }

  // Open the new file for reading
  itkDebugMacro(<< "Initialize: opening file " << filename);

  // Actually open the file
  os.open( filename, std::ios::in | std::ios::binary );

  if ( os.fail() )
    {
    return false;
    }

  return true;
}

bool GDCMImageIO::OpenGDCMFileForWriting(std::ofstream& os,
                                         const char* filename)

{
  // Make sure that we have a file to
  if ( filename == "" )
    {
    itkExceptionMacro(<<"A FileName must be specified.");
    return false;
    }

  // Close file from any previous image
  if ( os.is_open() )
    {
    os.close();
    }

  // Open the new file for writing
  itkDebugMacro(<< "Initialize: opening file " << filename);

#ifdef __sgi
  // Create the file. This is required on some older sgi's
  std::ofstream tFile(filename,std::ios::out);
  tFile.close();
#endif

  // Actually open the file
  os.open( filename, std::ios::out | std::ios::binary );

  if( os.fail() )
    {
    itkExceptionMacro(<< "Could not open file for writing: " << filename);
    return false;
    }

  return true;
}

// This method will only test if the header looks like a
//GDCM image file.
bool GDCMImageIO::CanReadFile(const char* filename)
{
  std::ifstream file;
  char buffer[256];
  std::string fname(filename);

  if(  fname == "" )
    {
    itkDebugMacro(<<"No filename specified.");
    return false;
    }

  bool extensionFound = false;
  std::string::size_type sprPos = fname.rfind(".dcm");  //acr nema ??
  if ((sprPos != std::string::npos)
      && (sprPos == fname.length() - 4))
    {
    extensionFound = true;
    }

  if( !extensionFound )
    {
    itkDebugMacro(<<"The filename extension is not recognized");
    return false;
    }

  //Check for file existence:
  if ( ! this->OpenGDCMFileForReading(file, filename))
    {
    return false;
    }

  // Check to see if its a valid dicom file gdcm is able to parse:
  //We are parsing the header one time here:
  gdcmHeaderHelper GdcmHeader(filename);
  if (!GdcmHeader.IsReadable())
    {
    itkExceptionMacro("Gdcm cannot parse file " << filename );
    return false;
    }

  //For later : For 2d stack dicom:
  //we should not mix insoncistent on pixel type
  //GdcmHeader.GetPixelType();
  //we should not mix insoncistent on image size
  //GdcmHeader.GetXSize(); GdcmHeader.GetYSize(); GdcmHeader.GetZSize();
  //spacing:
  //GdcmHeader.GetXSpacing(); GdcmHeader.GetYSpacing(); ...
  //GdcmHeader.GetXOrigin() ...

  return true;
}

void GDCMImageIO::Read(void* buffer)
{
  std::ifstream file;

  //read header information file:
  this->InternalReadImageInformation(file);

  //Should I handle differently dicom lut ?
  //GdcmHeader.HasLUT()

  if( !this->ReadBufferAsBinary( file, buffer, this->GetImageSizeInBytes()) )
    {
    itkExceptionMacro(<<"Read failed: Wanted "
                      << this->GetImageSizeInBytes()
                      << " bytes, but read "
                      << file.gcount() << " bytes.");
    }

  gdcmFile GdcmFile(m_FileName);
  size_t size = GdcmFile.GetImageDataSize();
  //== this->GetImageSizeInComponents()
  unsigned char *Source = (unsigned char*)GdcmFile.GetImageData();
  memcpy((void*)buffer, (void*)Source, size);

  //closing files:
  file.close();
}

void GDCMImageIO::InternalReadImageInformation(std::ifstream& file)
{
  //read header
  if ( ! this->OpenGDCMFileForReading(file, m_FileName.c_str()) )
    {
    itkExceptionMacro(<< "Cannot read requested file");
    }

  gdcmHeaderHelper GdcmHeader(m_FileName.c_str());

  // We don't need to positionate the Endian related stuff (by using
  // this->SetDataByteOrderToBigEndian() or SetDataByteOrderToLittleEndian()
  // since the reading of the file is done by gdcm.
  // But we do need to set up the data type for downstream filters:

  std::string type = GdcmHeader.GetPixelType();
  if( type == "8U")
    {
    SetPixelType(UCHAR);
    SetComponentType(UCHAR);
    }
  else if( type == "8S")
    {
    SetPixelType(CHAR);
    SetComponentType(CHAR);
    }
  else if( type == "16U")
    {
    SetPixelType(USHORT);
    SetComponentType(USHORT);
    }
  else if( type == "16S")
    {
    SetPixelType(SHORT);
    SetComponentType(SHORT);
    }
  else if( type == "32U")
    {
    SetPixelType(UINT);
    SetComponentType(UINT);
    }
  else if( type == "32S")
    {
    SetPixelType(INT);
    SetComponentType(INT);
    }
  else if ( type == "FD" )
    {
    //64 bits Double image
    SetPixelType(DOUBLE);
    SetComponentType(DOUBLE);
    }
  else
    {
    itkExceptionMacro(<<"Unrecognized type:" << type);
    }

  // set values in case we don't find them
  this->SetNumberOfDimensions(2);
  m_Dimensions[0] = GdcmHeader.GetXSize();
  m_Dimensions[1] = GdcmHeader.GetYSize();
  //m_Dimensions[2] = GdcmHeader.GetZSize();
  m_Dimensions[2] = 0;

  m_Spacing[0] = GdcmHeader.GetXSpacing();
  m_Spacing[1] = GdcmHeader.GetYSpacing();
  //  m_Spacing[2] = GdcmHeader.GetZSpacing();
  m_Spacing[2] = 0;

  m_Origin[0] = GdcmHeader.GetXOrigin();
  m_Origin[1] = GdcmHeader.GetYOrigin();
  m_Origin[2] = GdcmHeader.GetZOrigin();
  m_Origin[2] = 0;

  //For grayscale image :
  m_RescaleSlope = GdcmHeader.GetRescaleSlope();
  m_RescaleIntercept = GdcmHeader.GetRescaleIntercept();

}

void GDCMImageIO::ReadImageInformation()
{
  std::ifstream file;
  this->InternalReadImageInformation(file);
}

bool GDCMImageIO::CanWriteFile( const char* name )
{
  std::string filename = name;

  if(  filename == "" )
    {
    itkDebugMacro(<<"No filename specified.");
    return false;
    }

  bool extensionFound = false;
  std::string::size_type sprPos = filename.rfind(".dcm");
  if ((sprPos != std::string::npos)
      && (sprPos == filename.length() - 4))
    {
    extensionFound = true;
    }

  if( !extensionFound )
    {
    itkDebugMacro(<<"The filename extension is not recognized");
    return false;
    }

  return true;
}

void GDCMImageIO::WriteImageInformation()
{
}

void GDCMImageIO::Write(const void* buffer)
{
  std::ofstream file;
  if ( ! this->OpenGDCMFileForWriting(file, m_FileName.c_str()) )
    {
    return;
    }

  //gdcmFile GdcmFile();
  //GdcmFile.WriteDcmExplVR(m_FileName);
  //GdcmFile.WriteDcmImplVR(m_FileName);
  //GdcmFile.WriteRawData(m_FileName);
  file.close();
}

void GDCMImageIO::PrintSelf(std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);
  os << indent << "RescaleSlope: " << m_RescaleSlope << "\n";
  os << indent << "RescaleIntercept: " << m_RescaleIntercept << "\n";
}

} // end namespace itk
<|endoftext|>


<commit_before>//
//  SerialPort.cpp
//  Clock Signal
//
//  Created by Thomas Harte on 12/10/2019.
//  Copyright © 2019 Thomas Harte. All rights reserved.
//

#include "Line.hpp"

#include <limits>

using namespace Serial;

template <bool include_clock>
void Line<include_clock>::set_writer_clock_rate(HalfCycles clock_rate) {
	clock_rate_ = clock_rate;
}

template <bool include_clock>
void Line<include_clock>::advance_writer(HalfCycles cycles) {
	if(cycles == HalfCycles(0)) return;

	const auto integral_cycles = cycles.as_integral();
	remaining_delays_ = std::max(remaining_delays_ - integral_cycles, Cycles::IntType(0));
	if(events_.empty()) {
		write_cycles_since_delegate_call_ += integral_cycles;
		if(transmission_extra_) {
			transmission_extra_ -= integral_cycles;
			if(transmission_extra_ <= 0) {
				transmission_extra_ = 0;
				if constexpr (!include_clock) {
					update_delegate(level_);
				}
			}
		}
	} else {
		while(!events_.empty()) {
			if(events_.front().delay <= integral_cycles) {
				cycles -= events_.front().delay;
				write_cycles_since_delegate_call_ += events_.front().delay;
				const auto old_level = level_;

				auto iterator = events_.begin() + 1;
				while(iterator != events_.end() && iterator->type != Event::Delay) {
					level_ = iterator->type == Event::SetHigh;
					if constexpr(include_clock) {
						update_delegate(level_);
					}
					++iterator;
				}
				events_.erase(events_.begin(), iterator);

				if constexpr (!include_clock) {
					if(old_level != level_) {
						update_delegate(old_level);
					}
				}

				// Book enough extra time for the read delegate to be posted
				// the final bit if one is attached.
				if(events_.empty()) {
					transmission_extra_ = minimum_write_cycles_for_read_delegate_bit();
				}
			} else {
				events_.front().delay -= integral_cycles;
				write_cycles_since_delegate_call_ += integral_cycles;
				break;
			}
		}
	}
}

template <bool include_clock>
void Line<include_clock>::write(bool level) {
	if(!events_.empty()) {
		events_.emplace_back();
		events_.back().type = level ? Event::SetHigh : Event::SetLow;
	} else {
		level_ = level;
		transmission_extra_ = minimum_write_cycles_for_read_delegate_bit();
	}
}

template <bool include_clock>
template <bool lsb_first, typename IntT> void Line<include_clock>::write_internal(HalfCycles cycles, int count, IntT levels) {
	remaining_delays_ += count * cycles.as_integral();

	auto event = events_.size();
	events_.resize(events_.size() + size_t(count)*2);
	while(count--) {
		events_[event].type = Event::Delay;
		events_[event].delay = int(cycles.as_integral());
		IntT bit;
		if constexpr (lsb_first) {
			bit = levels & 1;
			levels >>= 1;
		} else {
			constexpr auto top_bit = IntT(0x80) << ((sizeof(IntT) - 1) * 8);
			bit = levels & top_bit;
			levels <<= 1;
		}

		events_[event+1].type = bit ? Event::SetHigh : Event::SetLow;
		event += 2;
	}
}

template <bool include_clock>
void Line<include_clock>::write(HalfCycles cycles, int count, int levels) {
	write_internal<true, int>(cycles, count, levels);
}

template <bool include_clock>
template <bool lsb_first, typename IntT> void Line<include_clock>::write(HalfCycles cycles, IntT value) {
	write_internal<lsb_first, IntT>(cycles, 8 * sizeof(IntT), value);
}

template <bool include_clock>
void Line<include_clock>::reset_writing() {
	remaining_delays_ = 0;
	events_.clear();
}

template <bool include_clock>
bool Line<include_clock>::read() const {
	return level_;
}

template <bool include_clock>
void Line<include_clock>::set_read_delegate(ReadDelegate *delegate, Storage::Time bit_length) {
	read_delegate_ = delegate;
	if constexpr (!include_clock) {
		assert(bit_length > Storage::Time(0));
		read_delegate_bit_length_ = bit_length;
		read_delegate_bit_length_.simplify();
		write_cycles_since_delegate_call_ = 0;
	}
}

template <bool include_clock>
void Line<include_clock>::update_delegate(bool level) {
	// Exit early if there's no delegate, or if the delegate is waiting for
	// zero and this isn't zero.
	if(!read_delegate_) return;

	if constexpr (!include_clock) {
		const int cycles_to_forward = write_cycles_since_delegate_call_;
		write_cycles_since_delegate_call_ = 0;
		if(level && read_delegate_phase_ == ReadDelegatePhase::WaitingForZero) return;

		// Deal with a transition out of waiting-for-zero mode by seeding time left
		// in bit at half a bit.
		if(read_delegate_phase_ == ReadDelegatePhase::WaitingForZero) {
			time_left_in_bit_ = read_delegate_bit_length_;
			time_left_in_bit_.clock_rate <<= 1;
			read_delegate_phase_ = ReadDelegatePhase::Serialising;
		}

		// Forward as many bits as occur.
		Storage::Time time_left(cycles_to_forward, int(clock_rate_.as_integral()));
		const int bit = level ? 1 : 0;
		int bits = 0;
		while(time_left >= time_left_in_bit_) {
			++bits;
			if(!read_delegate_->serial_line_did_produce_bit(this, bit)) {
				read_delegate_phase_ = ReadDelegatePhase::WaitingForZero;
				if(bit) return;
			}

			time_left -= time_left_in_bit_;
			time_left_in_bit_ = read_delegate_bit_length_;
		}
		time_left_in_bit_ -= time_left;
	} else {
		read_delegate_->serial_line_did_produce_bit(this, level);
	}
}

template <bool include_clock>
Cycles::IntType Line<include_clock>::minimum_write_cycles_for_read_delegate_bit() {
	if(!read_delegate_) return 0;
	return 1 + (read_delegate_bit_length_ * unsigned(clock_rate_.as_integral())).template get<int>();
}

//
// Explicitly instantiate the meaningful instances of templates above;
// this class uses templates primarily to keep the interface compact and
// to take advantage of constexpr functionality selection, not so as
// to be generic.
//

template class Serial::Line<true>;
template class Serial::Line<false>;

template void Line<true>::write<true, uint8_t>(HalfCycles, uint8_t);
template void Line<true>::write<false, uint8_t>(HalfCycles, uint8_t);
template void Line<true>::write<true, uint16_t>(HalfCycles, uint16_t);
template void Line<true>::write<false, uint16_t>(HalfCycles, uint16_t);
template void Line<true>::write<true, uint32_t>(HalfCycles, uint32_t);
template void Line<true>::write<false, uint32_t>(HalfCycles, uint32_t);
template void Line<true>::write<true, uint64_t>(HalfCycles, uint64_t);
template void Line<true>::write<false, uint64_t>(HalfCycles, uint64_t);

template void Line<false>::write<true, uint8_t>(HalfCycles, uint8_t);
template void Line<false>::write<false, uint8_t>(HalfCycles, uint8_t);
template void Line<false>::write<true, uint16_t>(HalfCycles, uint16_t);
template void Line<false>::write<false, uint16_t>(HalfCycles, uint16_t);
template void Line<false>::write<true, uint32_t>(HalfCycles, uint32_t);
template void Line<false>::write<false, uint32_t>(HalfCycles, uint32_t);
template void Line<false>::write<true, uint64_t>(HalfCycles, uint64_t);
template void Line<false>::write<false, uint64_t>(HalfCycles, uint64_t);
<commit_msg>Add header for `assert`.<commit_after>//
//  SerialPort.cpp
//  Clock Signal
//
//  Created by Thomas Harte on 12/10/2019.
//  Copyright © 2019 Thomas Harte. All rights reserved.
//

#include "Line.hpp"

#include <cassert>
#include <limits>

using namespace Serial;

template <bool include_clock>
void Line<include_clock>::set_writer_clock_rate(HalfCycles clock_rate) {
	clock_rate_ = clock_rate;
}

template <bool include_clock>
void Line<include_clock>::advance_writer(HalfCycles cycles) {
	if(cycles == HalfCycles(0)) return;

	const auto integral_cycles = cycles.as_integral();
	remaining_delays_ = std::max(remaining_delays_ - integral_cycles, Cycles::IntType(0));
	if(events_.empty()) {
		write_cycles_since_delegate_call_ += integral_cycles;
		if(transmission_extra_) {
			transmission_extra_ -= integral_cycles;
			if(transmission_extra_ <= 0) {
				transmission_extra_ = 0;
				if constexpr (!include_clock) {
					update_delegate(level_);
				}
			}
		}
	} else {
		while(!events_.empty()) {
			if(events_.front().delay <= integral_cycles) {
				cycles -= events_.front().delay;
				write_cycles_since_delegate_call_ += events_.front().delay;
				const auto old_level = level_;

				auto iterator = events_.begin() + 1;
				while(iterator != events_.end() && iterator->type != Event::Delay) {
					level_ = iterator->type == Event::SetHigh;
					if constexpr(include_clock) {
						update_delegate(level_);
					}
					++iterator;
				}
				events_.erase(events_.begin(), iterator);

				if constexpr (!include_clock) {
					if(old_level != level_) {
						update_delegate(old_level);
					}
				}

				// Book enough extra time for the read delegate to be posted
				// the final bit if one is attached.
				if(events_.empty()) {
					transmission_extra_ = minimum_write_cycles_for_read_delegate_bit();
				}
			} else {
				events_.front().delay -= integral_cycles;
				write_cycles_since_delegate_call_ += integral_cycles;
				break;
			}
		}
	}
}

template <bool include_clock>
void Line<include_clock>::write(bool level) {
	if(!events_.empty()) {
		events_.emplace_back();
		events_.back().type = level ? Event::SetHigh : Event::SetLow;
	} else {
		level_ = level;
		transmission_extra_ = minimum_write_cycles_for_read_delegate_bit();
	}
}

template <bool include_clock>
template <bool lsb_first, typename IntT> void Line<include_clock>::write_internal(HalfCycles cycles, int count, IntT levels) {
	remaining_delays_ += count * cycles.as_integral();

	auto event = events_.size();
	events_.resize(events_.size() + size_t(count)*2);
	while(count--) {
		events_[event].type = Event::Delay;
		events_[event].delay = int(cycles.as_integral());
		IntT bit;
		if constexpr (lsb_first) {
			bit = levels & 1;
			levels >>= 1;
		} else {
			constexpr auto top_bit = IntT(0x80) << ((sizeof(IntT) - 1) * 8);
			bit = levels & top_bit;
			levels <<= 1;
		}

		events_[event+1].type = bit ? Event::SetHigh : Event::SetLow;
		event += 2;
	}
}

template <bool include_clock>
void Line<include_clock>::write(HalfCycles cycles, int count, int levels) {
	write_internal<true, int>(cycles, count, levels);
}

template <bool include_clock>
template <bool lsb_first, typename IntT> void Line<include_clock>::write(HalfCycles cycles, IntT value) {
	write_internal<lsb_first, IntT>(cycles, 8 * sizeof(IntT), value);
}

template <bool include_clock>
void Line<include_clock>::reset_writing() {
	remaining_delays_ = 0;
	events_.clear();
}

template <bool include_clock>
bool Line<include_clock>::read() const {
	return level_;
}

template <bool include_clock>
void Line<include_clock>::set_read_delegate(ReadDelegate *delegate, Storage::Time bit_length) {
	read_delegate_ = delegate;
	if constexpr (!include_clock) {
		assert(bit_length > Storage::Time(0));
		read_delegate_bit_length_ = bit_length;
		read_delegate_bit_length_.simplify();
		write_cycles_since_delegate_call_ = 0;
	}
}

template <bool include_clock>
void Line<include_clock>::update_delegate(bool level) {
	// Exit early if there's no delegate, or if the delegate is waiting for
	// zero and this isn't zero.
	if(!read_delegate_) return;

	if constexpr (!include_clock) {
		const int cycles_to_forward = write_cycles_since_delegate_call_;
		write_cycles_since_delegate_call_ = 0;
		if(level && read_delegate_phase_ == ReadDelegatePhase::WaitingForZero) return;

		// Deal with a transition out of waiting-for-zero mode by seeding time left
		// in bit at half a bit.
		if(read_delegate_phase_ == ReadDelegatePhase::WaitingForZero) {
			time_left_in_bit_ = read_delegate_bit_length_;
			time_left_in_bit_.clock_rate <<= 1;
			read_delegate_phase_ = ReadDelegatePhase::Serialising;
		}

		// Forward as many bits as occur.
		Storage::Time time_left(cycles_to_forward, int(clock_rate_.as_integral()));
		const int bit = level ? 1 : 0;
		int bits = 0;
		while(time_left >= time_left_in_bit_) {
			++bits;
			if(!read_delegate_->serial_line_did_produce_bit(this, bit)) {
				read_delegate_phase_ = ReadDelegatePhase::WaitingForZero;
				if(bit) return;
			}

			time_left -= time_left_in_bit_;
			time_left_in_bit_ = read_delegate_bit_length_;
		}
		time_left_in_bit_ -= time_left;
	} else {
		read_delegate_->serial_line_did_produce_bit(this, level);
	}
}

template <bool include_clock>
Cycles::IntType Line<include_clock>::minimum_write_cycles_for_read_delegate_bit() {
	if(!read_delegate_) return 0;
	return 1 + (read_delegate_bit_length_ * unsigned(clock_rate_.as_integral())).template get<int>();
}

//
// Explicitly instantiate the meaningful instances of templates above;
// this class uses templates primarily to keep the interface compact and
// to take advantage of constexpr functionality selection, not so as
// to be generic.
//

template class Serial::Line<true>;
template class Serial::Line<false>;

template void Line<true>::write<true, uint8_t>(HalfCycles, uint8_t);
template void Line<true>::write<false, uint8_t>(HalfCycles, uint8_t);
template void Line<true>::write<true, uint16_t>(HalfCycles, uint16_t);
template void Line<true>::write<false, uint16_t>(HalfCycles, uint16_t);
template void Line<true>::write<true, uint32_t>(HalfCycles, uint32_t);
template void Line<true>::write<false, uint32_t>(HalfCycles, uint32_t);
template void Line<true>::write<true, uint64_t>(HalfCycles, uint64_t);
template void Line<true>::write<false, uint64_t>(HalfCycles, uint64_t);

template void Line<false>::write<true, uint8_t>(HalfCycles, uint8_t);
template void Line<false>::write<false, uint8_t>(HalfCycles, uint8_t);
template void Line<false>::write<true, uint16_t>(HalfCycles, uint16_t);
template void Line<false>::write<false, uint16_t>(HalfCycles, uint16_t);
template void Line<false>::write<true, uint32_t>(HalfCycles, uint32_t);
template void Line<false>::write<false, uint32_t>(HalfCycles, uint32_t);
template void Line<false>::write<true, uint64_t>(HalfCycles, uint64_t);
template void Line<false>::write<false, uint64_t>(HalfCycles, uint64_t);
<|endoftext|>