<commit_before>/**
 * \file arpbnf_search.cc
 *
 *
 *
 * \author Ethan Burns
 * \date 2008-10-29
 */

#include <assert.h>
#include <math.h>

#include <limits>
#include <vector>
#include <algorithm>

#include "arpbnf_search.h"
#include "search.h"
#include "state.h"
#include "util/timer.h"
#include "util/sync_solution_stream.h"

using namespace std;
using namespace ARPBNF;

ARPBNFSearch::ARPBNFThread::ARPBNFThread(NBlockGraph *graph, ARPBNFSearch *search)
	: graph(graph), search(search), set_hot(false)
{
}

ARPBNFSearch::ARPBNFThread::~ARPBNFThread(void) {}

/**
 * Run the search thread.
 */
void ARPBNFSearch::ARPBNFThread::run(void)
{
	vector<State *> *path;
	NBlock *n = NULL;

	do {
	next:
		if (graph->is_done())
			break;
		n = graph->next_nblock(n, !set_hot);
		set_hot = false;
		if (n) {
			expansions = 0;
			path = search_nblock(n);

			if (path) {
				if (search->set_path(path) && !search->final_weight) {
					graph->free_nblock(n);
					n = NULL;
					graph->call_for_resort(search->final_weight, search);
					goto next;
				}
			}
		} else if (!search->final_weight) {
			graph->call_for_resort(search->final_weight, search);
#if !defined(NDEBUG)
			cout << "No solution found at weight "
			     << search->weights->at(search->next_weight - 1)
			     << endl;
#endif	// !NDEBUG
			goto next;
		} else {
#if !defined(NDEBUG)
			cout << "Done" << endl;
#endif	// !NDEBUG
		}
	} while (n && !graph->is_done());

	graph->set_done();
}

/**
 * Search a single NBlock.
 */
vector<State *> *ARPBNFSearch::ARPBNFThread::search_nblock(NBlock *n)
{
	vector<State *> *path = NULL;
	OpenList *open = &n->open;

	while (!open->empty() && !should_switch(n) && !graph->needs_resort()) {

		if (n->open.peek()->get_f_prime() > search->bound.read())
			return NULL;

		State *s = open->take();

#if !defined(NDEBUG)
		State *dup = n->closed.lookup(s);
		assert (!dup || dup == s);
#endif	// !NDEBUG

		if (s->get_f() >= search->bound.read())
			continue;

		if (s->is_goal()) {
			path = s->get_path();
			break;
		}

		expansions += 1;

		vector<State *> *children = search->expand(s);
		vector<State *>::iterator iter;

 		for (iter = children->begin(); iter != children->end(); iter++) {
			State *ch = *iter;
			if (ch->get_f() >= search->bound.read()) {
				delete ch;
				continue;
			}
			vector<State *> *path = process_child(ch);
			if (path) {
				delete children;
				return path;
			}
		}
		delete children;
	}

	return path;
}

/**
 * Process a child state.
 *
 * \return A path if the child was a goal state... maybe we can prune
 *         more on this.
 */
vector<State *> *ARPBNFSearch::ARPBNFThread::process_child(State *ch)
{
	unsigned int block = search->project->project(ch);
	NBlock *cblock = graph->get_nblock(block);
	PQOpenList<State::PQOpsFPrime> *copen = &cblock->open;
	ClosedList *cclosed = &cblock->closed;
	InconsList *cincons = &cblock->incons;
	State *dup = cclosed->lookup(ch);

	if (dup) {
		if (dup->get_g() > ch->get_g()) {
			dup->update(ch->get_parent(), ch->get_c(), ch->get_g());
			assert(!dup->is_incons() || !dup->is_open());
			if (dup->is_open()) {
				copen->see_update(dup);
			} else {
				// Since we aren't searching in
				// strict-f' order, when the weight is
				// 1.0 we must re-open these
				// inconsistent states.
				if (search->final_weight)
					copen->add(dup);
				else if (!dup->is_incons())
					cincons->add(dup);
#if !defined(NDEBUG)
				else
					assert(cincons->lookup(dup) == dup);
#endif // !NDEBUG
			}
		}
		delete ch;
	} else {
		cclosed->add(ch);
		if (ch->is_goal())
			return ch->get_path();
		copen->add(ch);
	}

	return NULL;
}

/**
 * Test the graph to see if we should switch to a new NBlock.
 * \param n The current NBlock.
 *
 * \note We should make this more complex... we should also check our
 *       successor NBlocks.
 */
bool ARPBNFSearch::ARPBNFThread::should_switch(NBlock *n)
{
	bool ret;

	if (expansions < search->min_expansions)
		return false;

	expansions = 0;

	fp_type free = graph->best_val();
	fp_type cur = n->open.get_best_val();
	NBlock *best_scope = graph->best_in_scope(n);

	if (best_scope) {
		fp_type scope = best_scope->open.get_best_val();

		ret = free < cur || scope < cur;
		if (!ret) {
			graph->wont_release(n);
		} else if (scope < free) {
			graph->set_hot(best_scope);
			set_hot = true;
		}
	} else {
		ret = free < cur;
	}

	return ret;
}

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

ARPBNFSearch::ARPBNFSearch(unsigned int n_threads,
			   unsigned int min_e,
			   vector<double> *w)
	: n_threads(n_threads),
	  project(NULL),
	  bound(fp_infinity),
	  graph(NULL),
	  min_expansions(min_e),
	  weights(w),
	  next_weight(1),
	  domain(NULL),
	  final_weight(false)
{
	pthread_mutex_init(&wmutex, NULL);
}

ARPBNFSearch::~ARPBNFSearch(void)
{
	if (graph)
		delete graph;
}

vector<State *> *ARPBNFSearch::search(Timer *timer, State *initial)
{
	solutions = new SyncSolutionStream(timer, 0.0001);
	domain = initial->get_domain();
	project = domain->get_projection();

	vector<ARPBNFSearch::ARPBNFThread*> threads;
	vector<ARPBNFSearch::ARPBNFThread*>::iterator iter;

	graph = new NBlockGraph(project, initial, &bound);

	if (domain->get_heuristic()->get_weight() == fp_one)
		final_weight = true;
	final_sol_weight = domain->get_heuristic()->get_weight();

	for (unsigned int i = 0; i < n_threads; i += 1) {
		ARPBNFThread *t = new ARPBNFThread(graph, this);
		threads.push_back(t);
		t->start();
	}

	for (iter = threads.begin(); iter != threads.end(); iter++) {
		(*iter)->join();
		delete *iter;
	}

	return solutions->get_best_path();
}

void ARPBNFSearch::move_to_next_weight(void)
{
	if (next_weight < weights->size())
		final_sol_weight = weights->at(next_weight);

	if (weights->at(next_weight - 1) != 1.0) {
		double nw = 1.0;
		if (next_weight < weights->size()) {
			nw = weights->at(next_weight);
			next_weight += 1;
		} else {
			cerr << "Final weight is not 1.0, using 1.0" << endl;
		}

		domain->get_heuristic()->set_weight(nw);
		if (nw == 1.0 || next_weight == weights->size())
			final_weight = true;
	}
}

/**
 * Set an incumbant solution.
 *
 * If this function returns true than the calling thread must call for
 * a resort.
 */
bool ARPBNFSearch::set_path(vector<State *> *p)
{
	assert(solutions);

	pthread_mutex_lock(&wmutex);

	if (bound.read() <= p->at(0)->get_g()) {
		pthread_mutex_unlock(&wmutex);
		return false;
	}

	solutions->see_solution(p, get_generated(), get_expanded());
	bound.set(p->at(0)->get_g());
	graph->new_bound();

#if !defined(NDEBUG)
	cout << "Solution of cost " << p->at(0)->get_g() / fp_one
	     << " found at weight " << weights->at(next_weight - 1)
	     << endl;
#endif	// !NDEBUG

	pthread_mutex_unlock(&wmutex);

	return true;
}

/**
 * Output extra "key: value" pairs.
 * keys should not have spaces in their names!
 */
void ARPBNFSearch::output_stats(void)
{
	cout << "total-nblocks: " << project->get_num_nblocks() << endl;
	cout << "created-nblocks: " << graph->get_ncreated_nblocks() << endl;
	cout << "final-sol-weight: " << final_sol_weight << endl;

	if (solutions)
		solutions->output(cout);
}
<commit_msg>Turn off some debug output.<commit_after>/**
 * \file arpbnf_search.cc
 *
 *
 *
 * \author Ethan Burns
 * \date 2008-10-29
 */

#include <assert.h>
#include <math.h>

#include <limits>
#include <vector>
#include <algorithm>

#include "arpbnf_search.h"
#include "search.h"
#include "state.h"
#include "util/timer.h"
#include "util/sync_solution_stream.h"

using namespace std;
using namespace ARPBNF;

ARPBNFSearch::ARPBNFThread::ARPBNFThread(NBlockGraph *graph, ARPBNFSearch *search)
	: graph(graph), search(search), set_hot(false)
{
}

ARPBNFSearch::ARPBNFThread::~ARPBNFThread(void) {}

/**
 * Run the search thread.
 */
void ARPBNFSearch::ARPBNFThread::run(void)
{
	vector<State *> *path;
	NBlock *n = NULL;

	do {
	next:
		if (graph->is_done())
			break;
		n = graph->next_nblock(n, !set_hot);
		set_hot = false;
		if (n) {
			expansions = 0;
			path = search_nblock(n);

			if (path) {
				if (search->set_path(path) && !search->final_weight) {
					graph->free_nblock(n);
					n = NULL;
					graph->call_for_resort(search->final_weight, search);
					goto next;
				}
			}
		} else if (!search->final_weight) {
			graph->call_for_resort(search->final_weight, search);
#if !defined(NDEBUG) && 0
			cout << "No solution found at weight "
			     << search->weights->at(search->next_weight - 1)
			     << endl;
#endif	// !NDEBUG
			goto next;
		} else {
#if !defined(NDEBUG) && 0
			cout << "Done" << endl;
#endif	// !NDEBUG
		}
	} while (n && !graph->is_done());

	graph->set_done();
}

/**
 * Search a single NBlock.
 */
vector<State *> *ARPBNFSearch::ARPBNFThread::search_nblock(NBlock *n)
{
	vector<State *> *path = NULL;
	OpenList *open = &n->open;

	while (!open->empty() && !should_switch(n) && !graph->needs_resort()) {

		if (n->open.peek()->get_f_prime() > search->bound.read())
			return NULL;

		State *s = open->take();

#if !defined(NDEBUG)
		State *dup = n->closed.lookup(s);
		assert (!dup || dup == s);
#endif	// !NDEBUG

		if (s->get_f() >= search->bound.read())
			continue;

		if (s->is_goal()) {
			path = s->get_path();
			break;
		}

		expansions += 1;

		vector<State *> *children = search->expand(s);
		vector<State *>::iterator iter;

 		for (iter = children->begin(); iter != children->end(); iter++) {
			State *ch = *iter;
			if (ch->get_f() >= search->bound.read()) {
				delete ch;
				continue;
			}
			vector<State *> *path = process_child(ch);
			if (path) {
				delete children;
				return path;
			}
		}
		delete children;
	}

	return path;
}

/**
 * Process a child state.
 *
 * \return A path if the child was a goal state... maybe we can prune
 *         more on this.
 */
vector<State *> *ARPBNFSearch::ARPBNFThread::process_child(State *ch)
{
	unsigned int block = search->project->project(ch);
	NBlock *cblock = graph->get_nblock(block);
	PQOpenList<State::PQOpsFPrime> *copen = &cblock->open;
	ClosedList *cclosed = &cblock->closed;
	InconsList *cincons = &cblock->incons;
	State *dup = cclosed->lookup(ch);

	if (dup) {
		if (dup->get_g() > ch->get_g()) {
			dup->update(ch->get_parent(), ch->get_c(), ch->get_g());
			assert(!dup->is_incons() || !dup->is_open());
			if (dup->is_open()) {
				copen->see_update(dup);
			} else {
				// Since we aren't searching in
				// strict-f' order, when the weight is
				// 1.0 we must re-open these
				// inconsistent states.
				if (search->final_weight)
					copen->add(dup);
				else if (!dup->is_incons())
					cincons->add(dup);
#if !defined(NDEBUG)
				else
					assert(cincons->lookup(dup) == dup);
#endif // !NDEBUG
			}
		}
		delete ch;
	} else {
		cclosed->add(ch);
		if (ch->is_goal())
			return ch->get_path();
		copen->add(ch);
	}

	return NULL;
}

/**
 * Test the graph to see if we should switch to a new NBlock.
 * \param n The current NBlock.
 *
 * \note We should make this more complex... we should also check our
 *       successor NBlocks.
 */
bool ARPBNFSearch::ARPBNFThread::should_switch(NBlock *n)
{
	bool ret;

	if (expansions < search->min_expansions)
		return false;

	expansions = 0;

	fp_type free = graph->best_val();
	fp_type cur = n->open.get_best_val();
	NBlock *best_scope = graph->best_in_scope(n);

	if (best_scope) {
		fp_type scope = best_scope->open.get_best_val();

		ret = free < cur || scope < cur;
		if (!ret) {
			graph->wont_release(n);
		} else if (scope < free) {
			graph->set_hot(best_scope);
			set_hot = true;
		}
	} else {
		ret = free < cur;
	}

	return ret;
}

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

ARPBNFSearch::ARPBNFSearch(unsigned int n_threads,
			   unsigned int min_e,
			   vector<double> *w)
	: n_threads(n_threads),
	  project(NULL),
	  bound(fp_infinity),
	  graph(NULL),
	  min_expansions(min_e),
	  weights(w),
	  next_weight(1),
	  domain(NULL),
	  final_weight(false)
{
	pthread_mutex_init(&wmutex, NULL);
}

ARPBNFSearch::~ARPBNFSearch(void)
{
	if (graph)
		delete graph;
}

vector<State *> *ARPBNFSearch::search(Timer *timer, State *initial)
{
	solutions = new SyncSolutionStream(timer, 0.0001);
	domain = initial->get_domain();
	project = domain->get_projection();

	vector<ARPBNFSearch::ARPBNFThread*> threads;
	vector<ARPBNFSearch::ARPBNFThread*>::iterator iter;

	graph = new NBlockGraph(project, initial, &bound);

	if (domain->get_heuristic()->get_weight() == fp_one)
		final_weight = true;
	final_sol_weight = domain->get_heuristic()->get_weight();

	for (unsigned int i = 0; i < n_threads; i += 1) {
		ARPBNFThread *t = new ARPBNFThread(graph, this);
		threads.push_back(t);
		t->start();
	}

	for (iter = threads.begin(); iter != threads.end(); iter++) {
		(*iter)->join();
		delete *iter;
	}

	return solutions->get_best_path();
}

void ARPBNFSearch::move_to_next_weight(void)
{
	if (next_weight < weights->size())
		final_sol_weight = weights->at(next_weight);

	if (weights->at(next_weight - 1) != 1.0) {
		double nw = 1.0;
		if (next_weight < weights->size()) {
			nw = weights->at(next_weight);
			next_weight += 1;
		} else {
			cerr << "Final weight is not 1.0, using 1.0" << endl;
		}

		domain->get_heuristic()->set_weight(nw);
		if (nw == 1.0 || next_weight == weights->size())
			final_weight = true;
	}
}

/**
 * Set an incumbant solution.
 *
 * If this function returns true than the calling thread must call for
 * a resort.
 */
bool ARPBNFSearch::set_path(vector<State *> *p)
{
	assert(solutions);

	pthread_mutex_lock(&wmutex);

	if (bound.read() <= p->at(0)->get_g()) {
		pthread_mutex_unlock(&wmutex);
		return false;
	}

	solutions->see_solution(p, get_generated(), get_expanded());
	bound.set(p->at(0)->get_g());
	graph->new_bound();

#if !defined(NDEBUG) && 0
	cout << "Solution of cost " << p->at(0)->get_g() / fp_one
	     << " found at weight " << weights->at(next_weight - 1)
	     << endl;
#endif	// !NDEBUG

	pthread_mutex_unlock(&wmutex);

	return true;
}

/**
 * Output extra "key: value" pairs.
 * keys should not have spaces in their names!
 */
void ARPBNFSearch::output_stats(void)
{
	cout << "total-nblocks: " << project->get_num_nblocks() << endl;
	cout << "created-nblocks: " << graph->get_ncreated_nblocks() << endl;
	cout << "final-sol-weight: " << final_sol_weight << endl;

	if (solutions)
		solutions->output(cout);
}
<|endoftext|>


<commit_before>#include "./framework.h"
#include <sys/stat.h>
#include <string>
#include <memory>
#include <csignal>
#include <sys/types.h>
#include <unistd.h>
#include "backtrace_formatter.h"

namespace lms {
namespace internal {

Framework::Framework(const std::string &mainConfigFilePath)
    : m_executionManager(*this), logger("lms.Framework"),
      mainConfigFilePath(mainConfigFilePath), m_running(false), is_debug(false) {

    // start();
}

void Framework::addSearchPath(const std::string &path) {
    m_loader.addSearchPath(path);
}

void Framework::start() {
    bool firstRun = true;
    m_running = true;

    while (m_running) {
        // config monitor stuff
        if (firstRun || configMonitor.hasChangedFiles()) {
            logger.info() << "Reload configs";
            configMonitor.unwatchAll();
            RuntimeInfo runtime;
            for(const auto &f: flags) {
                logger.info("flag") << f;
            }
            XmlParser parser(runtime, flags);
            parser.parseFile(mainConfigFilePath);

            for (auto error : parser.errors()) {
                logger.error("XML") << error;
            }

            try {
                logger.time("updateSystem");
                if(! updateSystem(runtime)) {
                    m_running = false;
                }
                logger.timeEnd("updateSystem");
            } catch(std::exception const &ex) {
                logger.error() << lms::typeName(ex) << ": " <<  ex.what();
                m_running = false;
            }

            if(isDebug()) {
                printOverview();
            }

            for (auto file : parser.files()) {
                configMonitor.watch(file);
            }
        }

        if(!cycle()) {
            m_running = false;
        }
        firstRun = false;
    }

    logger.info() << "Stopped";
}

bool Framework::updateSystem(const RuntimeInfo &info) {
    if(isDebug()) {
        logger.debug() << "updateSystem()";
    }

    // Update or load services
    for (const ServiceInfo &serviceInfo : info.services) {
        if(isDebug()) {
            logger.debug() << "Loading service " << serviceInfo.name;
        }
        auto it = services.find(serviceInfo.name);
        if (it == services.end()) {
            // Not loaded yet
            std::shared_ptr<Service> service(m_loader.loadService(serviceInfo));

            service->initBase(serviceInfo);

            try {
                if (!service->init()) {
                    logger.error() << "Service " << serviceInfo.name
                                   << " failed to init()";
                    return false;
                }
            } catch (std::exception const &ex) {
                logger.error() << serviceInfo.name << " throws "
                               << lms::typeName(ex) << " : " << ex.what();
                return false;
            }

            services[serviceInfo.name] = service;
        } else {
            // already loaded
            it->second->initBase(serviceInfo);
            it->second->configsChanged();
        }
    }

    // Update or load modules
    for (const ModuleInfo &moduleInfo : info.modules) {
        if(isDebug()) {
            logger.debug() << "Loading module " << moduleInfo.name;
        }
        auto it = modules.find(moduleInfo.name);
        if (it == modules.end()) {
            // Not yet loaded
            std::shared_ptr<Module> module(m_loader.loadModule(moduleInfo));
            module->initBase(moduleInfo, this);

            try {
                if (!module->init()) {
                    logger.error() << "Module " << moduleInfo.name
                                   << " failed to init()";
                    return false;
                }
            } catch (std::exception const &ex) {
                logger.error() << moduleInfo.name << " throws "
                               << lms::typeName(ex) << " : " << ex.what();
                return false;
            }

            modules[moduleInfo.name] = module;
        } else {
            it->second->initBase(moduleInfo, this);
            it->second->configsChanged();
        }
    }

    if(isDebug()) {
        logger.debug() << "updated system";
    }

    return true;
}

Framework::~Framework() {
    // Shutdown services
    for (auto &service : services) {
        try {
            service.second->destroy();
        } catch (std::exception const &ex) {
            logger.error() << service.first << " throws " << lms::typeName(ex)
                           << " : " << ex.what();
        }
    }

    // Shutdown modules
    for (auto &module : modules) {
        try {
            module.second->destroy();
        } catch (std::exception const &ex) {
            logger.error() << module.first << " throws " << lms::typeName(ex)
                           << " : " << ex.what();
        }
    }
}

bool Framework::cycle() {
    if(modules.size() == 0) {
        logger.error() << "No modules enabled. Check your config file. Shutting down ...";
        return false;
    }

    m_clock.beforeLoopIteration();
    executionManager().validate(modules);
    m_executionManager.loop();
    return true;
}

std::shared_ptr<Service> Framework::getService(std::string const &name) {
    return services[name];
}

bool Framework::isDebug() const {
    return is_debug; /* TODO make this configurable */
}

void Framework::setDebug(bool debug) {
    this->is_debug = debug;
}

DataManager &Framework::dataManager() { return m_dataManager; }

ExecutionManager &Framework::executionManager() { return m_executionManager; }

std::string Framework::loadPath() const { return m_loadLogPath; }

std::string Framework::loadLogObject(std::string const &name, bool isDir) {
    if (!isEnableLoad()) {
        throw std::runtime_error(
            "Command line option --enable-load was not specified");
    }

    std::string logobj = m_loadLogPath + "/" + name;

    return isDir ? logobj + "/" : logobj;
}

std::string Framework::saveLogObject(std::string const &name, bool isDir) {
    if (!isEnableSave()) {
        throw std::runtime_error(
            "Command line option --enable-save was not specified");
    }

    std::string logobj = m_saveLogPath + "/" + name;

    if (isDir) {
        mkdir(logobj.c_str(), MODE);
    }

    return isDir ? logobj + "/" : logobj;
}

bool Framework::isEnableLoad() const { return false; /* TODO */ }

bool Framework::isEnableSave() const { return false; /* TODO */ }

void Framework::addFlag(const std::string &flag) {
    flags.push_back(flag);
}

void Framework::signal(int signal) {
    switch(signal) {
    case SIGSEGV:
        {
        std::ofstream of(std::string("/tmp/lms-segfault-") +
                         std::to_string(getpid()) + "-" + std::to_string(std::time(NULL)) + ".txt");
        printStacktrace(of);
        of.close();
        _exit(1);
        }
        break;
    case SIGINT:
        m_running = false;
        break;
    }
}

void Framework::printOverview() {
    logger.info("overview") << "Modules (" << modules.size() << ")";
    for(const auto &module : modules) {
        logger.info("overview") << "  " << module.first;
    }
    logger.info("overview") << "Services (" << services.size() << ")";
    for(const auto &service : services) {
        logger.info("overview") << "  " << service.first;
    }
}

}  // namespace internal
}  // namespace lms
<commit_msg>Configure clock from configs<commit_after>#include "./framework.h"
#include <sys/stat.h>
#include <string>
#include <memory>
#include <csignal>
#include <sys/types.h>
#include <unistd.h>
#include "backtrace_formatter.h"

namespace lms {
namespace internal {

Framework::Framework(const std::string &mainConfigFilePath)
    : m_executionManager(*this), logger("lms.Framework"),
      mainConfigFilePath(mainConfigFilePath), m_running(false), is_debug(false) {

    // start();
}

void Framework::addSearchPath(const std::string &path) {
    m_loader.addSearchPath(path);
}

void Framework::start() {
    bool firstRun = true;
    m_running = true;

    while (m_running) {
        // config monitor stuff
        if (firstRun || configMonitor.hasChangedFiles()) {
            logger.info() << "Reload configs";
            configMonitor.unwatchAll();
            RuntimeInfo runtime;
            for(const auto &f: flags) {
                logger.info("flag") << f;
            }
            XmlParser parser(runtime, flags);
            parser.parseFile(mainConfigFilePath);

            for (auto error : parser.errors()) {
                logger.error("XML") << error;
            }

            try {
                logger.time("updateSystem");
                if(! updateSystem(runtime)) {
                    m_running = false;
                }
                logger.timeEnd("updateSystem");
            } catch(std::exception const &ex) {
                logger.error() << lms::typeName(ex) << ": " <<  ex.what();
                m_running = false;
            }

            if(isDebug()) {
                printOverview();
            }

            for (auto file : parser.files()) {
                configMonitor.watch(file);
            }
        }

        if(!cycle()) {
            m_running = false;
        }
        firstRun = false;
    }

    logger.info() << "Stopped";
}

bool Framework::updateSystem(const RuntimeInfo &info) {
    if(isDebug()) {
        logger.debug() << "updateSystem()";
    }

    // Update clock
    m_clock.cycleTime(info.clock.cycle);
    m_clock.enabledSleep(info.clock.sleep);
    m_clock.enabledSlowWarning(info.clock.slowWarnings);
    m_clock.enabledCompensate(info.clock.sleepCompensate);

    // Update or load services
    for (const ServiceInfo &serviceInfo : info.services) {
        if(isDebug()) {
            logger.debug() << "Loading service " << serviceInfo.name;
        }
        auto it = services.find(serviceInfo.name);
        if (it == services.end()) {
            // Not loaded yet
            std::shared_ptr<Service> service(m_loader.loadService(serviceInfo));

            service->initBase(serviceInfo);

            try {
                if (!service->init()) {
                    logger.error() << "Service " << serviceInfo.name
                                   << " failed to init()";
                    return false;
                }
            } catch (std::exception const &ex) {
                logger.error() << serviceInfo.name << " throws "
                               << lms::typeName(ex) << " : " << ex.what();
                return false;
            }

            services[serviceInfo.name] = service;
        } else {
            // already loaded
            it->second->initBase(serviceInfo);
            it->second->configsChanged();
        }
    }

    // Update or load modules
    for (const ModuleInfo &moduleInfo : info.modules) {
        if(isDebug()) {
            logger.debug() << "Loading module " << moduleInfo.name;
        }
        auto it = modules.find(moduleInfo.name);
        if (it == modules.end()) {
            // Not yet loaded
            std::shared_ptr<Module> module(m_loader.loadModule(moduleInfo));
            module->initBase(moduleInfo, this);

            try {
                if (!module->init()) {
                    logger.error() << "Module " << moduleInfo.name
                                   << " failed to init()";
                    return false;
                }
            } catch (std::exception const &ex) {
                logger.error() << moduleInfo.name << " throws "
                               << lms::typeName(ex) << " : " << ex.what();
                return false;
            }

            modules[moduleInfo.name] = module;
        } else {
            it->second->initBase(moduleInfo, this);
            it->second->configsChanged();
        }
    }

    if(isDebug()) {
        logger.debug() << "updated system";
    }

    return true;
}

Framework::~Framework() {
    // Shutdown services
    for (auto &service : services) {
        try {
            service.second->destroy();
        } catch (std::exception const &ex) {
            logger.error() << service.first << " throws " << lms::typeName(ex)
                           << " : " << ex.what();
        }
    }

    // Shutdown modules
    for (auto &module : modules) {
        try {
            module.second->destroy();
        } catch (std::exception const &ex) {
            logger.error() << module.first << " throws " << lms::typeName(ex)
                           << " : " << ex.what();
        }
    }
}

bool Framework::cycle() {
    if(modules.size() == 0) {
        logger.error() << "No modules enabled. Check your config file. Shutting down ...";
        return false;
    }

    m_clock.beforeLoopIteration();
    executionManager().validate(modules);
    m_executionManager.loop();
    return true;
}

std::shared_ptr<Service> Framework::getService(std::string const &name) {
    return services[name];
}

bool Framework::isDebug() const {
    return is_debug; /* TODO make this configurable */
}

void Framework::setDebug(bool debug) {
    this->is_debug = debug;
}

DataManager &Framework::dataManager() { return m_dataManager; }

ExecutionManager &Framework::executionManager() { return m_executionManager; }

std::string Framework::loadPath() const { return m_loadLogPath; }

std::string Framework::loadLogObject(std::string const &name, bool isDir) {
    if (!isEnableLoad()) {
        throw std::runtime_error(
            "Command line option --enable-load was not specified");
    }

    std::string logobj = m_loadLogPath + "/" + name;

    return isDir ? logobj + "/" : logobj;
}

std::string Framework::saveLogObject(std::string const &name, bool isDir) {
    if (!isEnableSave()) {
        throw std::runtime_error(
            "Command line option --enable-save was not specified");
    }

    std::string logobj = m_saveLogPath + "/" + name;

    if (isDir) {
        mkdir(logobj.c_str(), MODE);
    }

    return isDir ? logobj + "/" : logobj;
}

bool Framework::isEnableLoad() const { return false; /* TODO */ }

bool Framework::isEnableSave() const { return false; /* TODO */ }

void Framework::addFlag(const std::string &flag) {
    flags.push_back(flag);
}

void Framework::signal(int signal) {
    switch(signal) {
    case SIGSEGV:
        {
        std::ofstream of(std::string("/tmp/lms-segfault-") +
                         std::to_string(getpid()) + "-" + std::to_string(std::time(NULL)) + ".txt");
        printStacktrace(of);
        of.close();
        _exit(1);
        }
        break;
    case SIGINT:
        m_running = false;
        break;
    }
}

void Framework::printOverview() {
    logger.info("overview") << "Modules (" << modules.size() << ")";
    for(const auto &module : modules) {
        logger.info("overview") << "  " << module.first;
    }
    logger.info("overview") << "Services (" << services.size() << ")";
    for(const auto &service : services) {
        logger.info("overview") << "  " << service.first;
    }
}

}  // namespace internal
}  // namespace lms
<|endoftext|>


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

/* Author: Wim Meeussen */

#include <urdf/model.h>
#include <kdl/tree.hpp>
#include <ros/ros.h>
#include "robot_state_publisher/robot_state_publisher.h"
#include "robot_state_publisher/joint_state_listener.h"
#include <kdl_parser/kdl_parser.hpp>

using namespace std;
using namespace ros;
using namespace KDL;
using namespace robot_state_publisher;

JointStateListener::JointStateListener(const KDL::Tree& tree, const MimicMap& m)
  : state_publisher_(tree), mimic_(m)
{
  ros::NodeHandle n_tilde("~");
  ros::NodeHandle n;

  // set publish frequency
  double publish_freq;
  n_tilde.param("publish_frequency", publish_freq, 50.0);
  // get the tf_prefix parameter from the closest namespace
  std::string tf_prefix_key;
  n_tilde.searchParam("tf_prefix", tf_prefix_key);
  n_tilde.param(tf_prefix_key, tf_prefix_, std::string(""));
  publish_interval_ = ros::Duration(1.0/max(publish_freq,1.0));

  // subscribe to joint state
  joint_state_sub_ = n.subscribe("joint_states", 1, &JointStateListener::callbackJointState, this);

  // trigger to publish fixed joints
  timer_ = n_tilde.createTimer(publish_interval_, &JointStateListener::callbackFixedJoint, this);

};

JointStateListener::~JointStateListener()
{};

void JointStateListener::callbackFixedJoint(const ros::TimerEvent& e)
{
  state_publisher_.publishFixedTransforms(tf_prefix_);
}

void JointStateListener::callbackJointState(const JointStateConstPtr& state)
{
  if (state->name.size() != state->position.size()){
    ROS_ERROR("Robot state publisher received an invalid joint state vector");
    return;
  }

  // check if we moved backwards in time (e.g. when playing a bag file)
  ros::Time now = ros::Time::now();
  if(last_callback_time_ > now) {
    // force re-publish of joint transforms
    ROS_WARN("Moved backwards in time (probably because ROS clock was reset), re-publishing joint transforms!");
    last_publish_time_.clear();
  }
  last_callback_time_ = now;

  // determine least recently published joint
  ros::Time last_published = now;
  for (unsigned int i=0; i<state->name.size(); i++)
  {
    ros::Time t = last_publish_time_[state->name[i]];
    last_published = (t < last_published) ? t : last_published;
  }
  // note: if a joint was seen for the first time,
  //       then last_published is zero.

  // check if we need to publish
  if (state->header.stamp >= last_published + publish_interval_){
    // get joint positions from state message
    map<string, double> joint_positions;
    for (unsigned int i=0; i<state->name.size(); i++)
      joint_positions.insert(make_pair(state->name[i], state->position[i]));

    for(MimicMap::iterator i = mimic_.begin(); i != mimic_.end(); i++){
      if(joint_positions.find(i->second->joint_name) != joint_positions.end()){
        double pos = joint_positions[i->second->joint_name] * i->second->multiplier + i->second->offset;
        joint_positions.insert(make_pair(i->first, pos));
      }
    }

    state_publisher_.publishTransforms(joint_positions, state->header.stamp, tf_prefix_);

    // store publish time in joint map
    for (unsigned int i=0; i<state->name.size(); i++)
      last_publish_time_[state->name[i]] = state->header.stamp;
  }
}

// ----------------------------------
// ----- MAIN -----------------------
// ----------------------------------
int main(int argc, char** argv)
{
  // Initialize ros
  ros::init(argc, argv, "robot_state_publisher");
  NodeHandle node;
  std::cout <<argv[0] << std::endl;

  ///////////////////////////////////////// begin deprecation warning
  std::string exe_name = argv[0];
  std::size_t slash = exe_name.find_last_of("/");
  if (slash != std::string::npos)
    exe_name = exe_name.substr(slash + 1);
  if (exe_name == "state_publisher")
    ROS_WARN("The 'state_publisher' executable is deprecated. Please use 'robot_state_publisher' instead");
  ///////////////////////////////////////// end deprecation warning

  // gets the location of the robot description on the parameter server
  urdf::Model model;
  model.initParam("robot_description");
  KDL::Tree tree;
  if (!kdl_parser::treeFromUrdfModel(model, tree)){
    ROS_ERROR("Failed to extract kdl tree from xml robot description");
    return -1;
  }

  MimicMap mimic;

  for(std::map< std::string, boost::shared_ptr< urdf::Joint > >::iterator i = model.joints_.begin(); i != model.joints_.end(); i++){
    if(i->second->mimic){
      mimic.insert(make_pair(i->first, i->second->mimic));
    }
  }

  JointStateListener state_publisher(tree, mimic);
  ros::spin();

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

/* Author: Wim Meeussen */

#include <urdf/model.h>
#include <kdl/tree.hpp>
#include <ros/ros.h>
#include "robot_state_publisher/robot_state_publisher.h"
#include "robot_state_publisher/joint_state_listener.h"
#include <kdl_parser/kdl_parser.hpp>

using namespace std;
using namespace ros;
using namespace KDL;
using namespace robot_state_publisher;

JointStateListener::JointStateListener(const KDL::Tree& tree, const MimicMap& m)
  : state_publisher_(tree), mimic_(m)
{
  ros::NodeHandle n_tilde("~");
  ros::NodeHandle n;

  // set publish frequency
  double publish_freq;
  n_tilde.param("publish_frequency", publish_freq, 50.0);
  // get the tf_prefix parameter from the closest namespace
  std::string tf_prefix_key;
  n_tilde.searchParam("tf_prefix", tf_prefix_key);
  n_tilde.param(tf_prefix_key, tf_prefix_, std::string(""));
  publish_interval_ = ros::Duration(1.0/max(publish_freq,1.0));

  // subscribe to joint state
  joint_state_sub_ = n.subscribe("joint_states", 1, &JointStateListener::callbackJointState, this);

  // trigger to publish fixed joints
  timer_ = n_tilde.createTimer(publish_interval_, &JointStateListener::callbackFixedJoint, this);

};

JointStateListener::~JointStateListener()
{};

void JointStateListener::callbackFixedJoint(const ros::TimerEvent& e)
{
  state_publisher_.publishFixedTransforms(tf_prefix_);
}

void JointStateListener::callbackJointState(const JointStateConstPtr& state)
{
  if (state->name.size() != state->position.size()){
    ROS_ERROR("Robot state publisher received an invalid joint state vector");
    return;
  }

  // check if we moved backwards in time (e.g. when playing a bag file)
  ros::Time now = ros::Time::now();
  if(last_callback_time_ > now) {
    // force re-publish of joint transforms
    ROS_WARN("Moved backwards in time (probably because ROS clock was reset), re-publishing joint transforms!");
    last_publish_time_.clear();
  }
  last_callback_time_ = now;

  // determine least recently published joint
  ros::Time last_published = now;
  for (unsigned int i=0; i<state->name.size(); i++)
  {
    ros::Time t = last_publish_time_[state->name[i]];
    last_published = (t < last_published) ? t : last_published;
  }
  // note: if a joint was seen for the first time,
  //       then last_published is zero.

  // check if we need to publish
  if (state->header.stamp >= last_published + publish_interval_){
    // get joint positions from state message
    map<string, double> joint_positions;
    for (unsigned int i=0; i<state->name.size(); i++)
      joint_positions.insert(make_pair(state->name[i], state->position[i]));

    for(MimicMap::iterator i = mimic_.begin(); i != mimic_.end(); i++){
      if(joint_positions.find(i->second->joint_name) != joint_positions.end()){
        double pos = joint_positions[i->second->joint_name] * i->second->multiplier + i->second->offset;
        joint_positions.insert(make_pair(i->first, pos));
      }
    }

    state_publisher_.publishTransforms(joint_positions, state->header.stamp, tf_prefix_);

    // store publish time in joint map
    for (unsigned int i=0; i<state->name.size(); i++)
      last_publish_time_[state->name[i]] = state->header.stamp;
  }
}

// ----------------------------------
// ----- MAIN -----------------------
// ----------------------------------
int main(int argc, char** argv)
{
  // Initialize ros
  ros::init(argc, argv, "robot_state_publisher");
  NodeHandle node;

  ///////////////////////////////////////// begin deprecation warning
  std::string exe_name = argv[0];
  std::size_t slash = exe_name.find_last_of("/");
  if (slash != std::string::npos)
    exe_name = exe_name.substr(slash + 1);
  if (exe_name == "state_publisher")
    ROS_WARN("The 'state_publisher' executable is deprecated. Please use 'robot_state_publisher' instead");
  ///////////////////////////////////////// end deprecation warning

  // gets the location of the robot description on the parameter server
  urdf::Model model;
  model.initParam("robot_description");
  KDL::Tree tree;
  if (!kdl_parser::treeFromUrdfModel(model, tree)){
    ROS_ERROR("Failed to extract kdl tree from xml robot description");
    return -1;
  }

  MimicMap mimic;

  for(std::map< std::string, boost::shared_ptr< urdf::Joint > >::iterator i = model.joints_.begin(); i != model.joints_.end(); i++){
    if(i->second->mimic){
      mimic.insert(make_pair(i->first, i->second->mimic));
    }
  }

  JointStateListener state_publisher(tree, mimic);
  ros::spin();

  return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fieldwnd.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 21:24:46 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_FIELDWND_HXX
#define SC_FIELDWND_HXX

#include <vector>

#ifndef SC_ADDRESS_HXX
#include "address.hxx"
#endif

#ifndef _SV_CTRL_HXX
#include <vcl/ctrl.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif

#ifndef _CPPUHELPER_WEAKREF_HXX_
#include <cppuhelper/weakref.hxx>
#endif

#define MAX_LABELS  256
#define PAGE_SIZE   16      // count of visible fields for scrollbar
#define LINE_SIZE   8       // count of fields per column for scrollbar
#define MAX_FIELDS  8       // maximum count of fields for row/col/data area
#define MAX_PAGEFIELDS 10   // maximum count of fields for page area

#define OWIDTH  PivotGlobal::nObjWidth
#define OHEIGHT PivotGlobal::nObjHeight
#define SSPACE  PivotGlobal::nSelSpace

class ScDPLayoutDlg;
class ScAccessibleDataPilotControl;

//===================================================================

/** Type of content area. */
enum ScDPFieldType
{
    TYPE_PAGE,              /// Area for all page fields.
    TYPE_ROW,               /// Area for all row fields.
    TYPE_COL,               /// Area for all column fields.
    TYPE_DATA,              /// Area for all data fields.
    TYPE_SELECT             /// Selection area with all fields.
};

//-------------------------------------------------------------------

/** Represents a field area in the DataPilot layout dialog. */
class ScDPFieldWindow : public Control
{
private:
    String                  aName;          /// name of the control, used in Accessibility
    ScDPLayoutDlg*          pDlg;           /// Parent dialog.
    Rectangle               aWndRect;       /// Area rectangle in pixels.
    FixedText*              pFtCaption;     /// FixedText containing the name of the control.
    Point                   aTextPos;       /// Position of the caption text.
    std::vector< String >   aFieldArr;      /// Pointer to string array of the field names.
    ScDPFieldType           eType;          /// Type of this area.
    Color                   aFaceColor;     /// Color for dialog background.
    Color                   aWinColor;      /// Color for window background.
    Color                   aTextColor;     /// Color for text in buttons.
    Color                   aWinTextColor;  /// Color for text in field windows.
    size_t                  nFieldSize;     /// Maximum count of fields.
    size_t                  nFieldSelected; /// Currently selected field.

    com::sun::star::uno::WeakReference< ::com::sun::star::accessibility::XAccessible > xAccessible;
    ScAccessibleDataPilotControl* pAccessible;

    /** Initilize the object. */
    void                    Init();

    /** Reads all needed style settings. */
    void                    GetStyleSettings();

    /** Draws the background. */
    void                    DrawBackground( OutputDevice& rDev );
    /** Draws a field into the specified rectangle. */
    void                    DrawField(
                                OutputDevice& rDev,
                                const Rectangle& rRect,
                                const String& rText,
                                bool bFocus );

    /** @return  TRUE, if the field index is inside of the control area. */
    bool                    IsValidIndex( size_t nIndex ) const;
    /** @return  TRUE, if the field with the given index exists. */
    bool                    IsExistingIndex( size_t nIndex ) const;
    /** @return  The new selection index after moving to the given direction. */
    size_t                  CalcNewFieldIndex( SCsCOL nDX, SCsROW nDY ) const;

    /** Sets selection to the field with index nIndex. */
    void                    SetSelection( size_t nIndex );
    /** Sets selection to first field. */
    void                    SetSelectionHome();
    /** Sets selection to last field. */
    void                    SetSelectionEnd();
    /** Sets selection to new position relative to current. */
    void                    MoveSelection( USHORT nKeyCode, SCsCOL nDX, SCsROW nDY );

    /** Moves the selected field to nDestIndex. */
    void                    MoveField( size_t nDestIndex );
    /** Moves the selected field to the given direction. */
    void                    MoveFieldRel( SCsCOL nDX, SCsROW nDY );

protected:
    virtual void            Paint( const Rectangle& rRect );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );
    virtual void            MouseButtonDown( const MouseEvent& rMEvt );
    virtual void            MouseButtonUp( const MouseEvent& rMEvt );
    virtual void            MouseMove( const MouseEvent& rMEvt );
    virtual void            KeyInput( const KeyEvent& rKEvt );
    virtual void            GetFocus();
    virtual void            LoseFocus();
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();

public:
                            ScDPFieldWindow(
                                ScDPLayoutDlg* pDialog,
                                const ResId& rResId,
                                ScDPFieldType eFieldType,
                                FixedText* pFtFieldCaption );
                            ScDPFieldWindow(
                                ScDPLayoutDlg* pDialog,
                                const ResId& rResId,
                                ScDPFieldType eFieldType,
                                const String& aName );
    virtual                 ~ScDPFieldWindow();

    /** Draws the complete control. */
    void                    Redraw();

    /** @return  The pixel position of a field (without bound check). */
    Point                   GetFieldPosition( size_t nIndex ) const;
    /** @return  The pixel size of a field. */
    Size                    GetFieldSize() const;

    /** @return  The index of the selected field. */
    inline bool             IsEmpty() const { return aFieldArr.empty(); }
    /** @return  The index of the selected field. */
    inline size_t           GetSelectedField() const { return nFieldSelected; }
    /** @return  The pixel position of the last possible field. */
    Point                   GetLastPosition() const;

    /** @return  The count of existing fields. */
    inline size_t           GetFieldCount() const { return aFieldArr.size(); }
    /** Inserts a field to the specified index. */
    void                    AddField( const String& rText, size_t nNewIndex );
    /** Removes a field from the specified index. */
    void                    DelField( size_t nDelIndex );
    /** Removes all fields. */
    void                    ClearFields();
    /** Changes the text on an existing field. */
    void                    SetFieldText( const String& rText, size_t nIndex );
    /** Returns the text of an existing field. */
    const String&           GetFieldText( size_t nIndex ) const;

    /** Inserts a field using the specified pixel position.
        @param rPos  The coordinates to insert the field.
        @param rnIndex  The new index of the field is returned here.
        @return  TRUE, if the field has been created. */
    bool                    AddField( const String& rText, const Point& rPos, size_t& rnIndex );
    /** Calculates the field index at a specific pixel position.
        @param rnIndex  The index of the field is returned here.
        @return  TRUE, if the index value is valid. */
    bool                    GetFieldIndex( const Point& rPos, size_t& rnIndex ) const;
    /** Calculates a field index at a specific pixel position. Returns in every
        case the index of an existing field.
        @param rnIndex  The index of the field is returned here.
        @return  TRUE, if the index value is valid. */
    void                    GetExistingIndex( const Point& rPos, size_t& rnIndex );

    /** Notifies this control that the offset of the first field has been changed.
        The control has to adjust the selection to keep the same field selected
        on scrolling with scrollbar. */
    void                    ModifySelectionOffset( long nOffsetDiff );
    /** Selects the next field. Called i.e. after moving a field from SELECT area. */
    void                    SelectNext();

    /** @return The name of the control without shortcut. */
    inline String           GetName() const { return aName; }

    /** @return The description of the control which is used for the accessibility objects. */
    String                  GetDescription() const;

    /** Grabs focus and sets new selection. */
    void                    GrabFocusWithSel( size_t nIndex );

    /** @return The type of the FieldWindow. */
    inline ScDPFieldType    GetType() const { return eType; }
};

//===================================================================

#endif // SC_FIELDWND_HXX
<commit_msg>INTEGRATION: CWS dr41 (1.11.440); FILE MERGED 2005/10/05 00:19:56 dr 1.11.440.2: RESYNC: (1.11-1.12); FILE MERGED 2005/09/13 18:40:43 nn 1.11.440.1: #124828# update mnemonics and tab stop style bits in StateChanged/INITSHOW<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fieldwnd.hxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: rt $ $Date: 2005-10-21 12:04:07 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_FIELDWND_HXX
#define SC_FIELDWND_HXX

#include <vector>

#ifndef SC_ADDRESS_HXX
#include "address.hxx"
#endif

#ifndef _SV_CTRL_HXX
#include <vcl/ctrl.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif

#ifndef _CPPUHELPER_WEAKREF_HXX_
#include <cppuhelper/weakref.hxx>
#endif

#define MAX_LABELS  256
#define PAGE_SIZE   16      // count of visible fields for scrollbar
#define LINE_SIZE   8       // count of fields per column for scrollbar
#define MAX_FIELDS  8       // maximum count of fields for row/col/data area
#define MAX_PAGEFIELDS 10   // maximum count of fields for page area

#define OWIDTH  PivotGlobal::nObjWidth
#define OHEIGHT PivotGlobal::nObjHeight
#define SSPACE  PivotGlobal::nSelSpace

class ScDPLayoutDlg;
class ScAccessibleDataPilotControl;

//===================================================================

/** Type of content area. */
enum ScDPFieldType
{
    TYPE_PAGE,              /// Area for all page fields.
    TYPE_ROW,               /// Area for all row fields.
    TYPE_COL,               /// Area for all column fields.
    TYPE_DATA,              /// Area for all data fields.
    TYPE_SELECT             /// Selection area with all fields.
};

//-------------------------------------------------------------------

/** Represents a field area in the DataPilot layout dialog. */
class ScDPFieldWindow : public Control
{
private:
    String                  aName;          /// name of the control, used in Accessibility
    ScDPLayoutDlg*          pDlg;           /// Parent dialog.
    Rectangle               aWndRect;       /// Area rectangle in pixels.
    FixedText*              pFtCaption;     /// FixedText containing the name of the control.
    Point                   aTextPos;       /// Position of the caption text.
    std::vector< String >   aFieldArr;      /// Pointer to string array of the field names.
    ScDPFieldType           eType;          /// Type of this area.
    Color                   aFaceColor;     /// Color for dialog background.
    Color                   aWinColor;      /// Color for window background.
    Color                   aTextColor;     /// Color for text in buttons.
    Color                   aWinTextColor;  /// Color for text in field windows.
    size_t                  nFieldSize;     /// Maximum count of fields.
    size_t                  nFieldSelected; /// Currently selected field.

    com::sun::star::uno::WeakReference< ::com::sun::star::accessibility::XAccessible > xAccessible;
    ScAccessibleDataPilotControl* pAccessible;

    /** Initilize the object. */
    void                    Init();

    /** Reads all needed style settings. */
    void                    GetStyleSettings();

    /** Draws the background. */
    void                    DrawBackground( OutputDevice& rDev );
    /** Draws a field into the specified rectangle. */
    void                    DrawField(
                                OutputDevice& rDev,
                                const Rectangle& rRect,
                                const String& rText,
                                bool bFocus );

    /** @return  TRUE, if the field index is inside of the control area. */
    bool                    IsValidIndex( size_t nIndex ) const;
    /** @return  TRUE, if the field with the given index exists. */
    bool                    IsExistingIndex( size_t nIndex ) const;
    /** @return  The new selection index after moving to the given direction. */
    size_t                  CalcNewFieldIndex( SCsCOL nDX, SCsROW nDY ) const;

    /** Sets selection to the field with index nIndex. */
    void                    SetSelection( size_t nIndex );
    /** Sets selection to first field. */
    void                    SetSelectionHome();
    /** Sets selection to last field. */
    void                    SetSelectionEnd();
    /** Sets selection to new position relative to current. */
    void                    MoveSelection( USHORT nKeyCode, SCsCOL nDX, SCsROW nDY );

    /** Moves the selected field to nDestIndex. */
    void                    MoveField( size_t nDestIndex );
    /** Moves the selected field to the given direction. */
    void                    MoveFieldRel( SCsCOL nDX, SCsROW nDY );

    /** Updates the tab stop style bits. */
    void                    UpdateStyle();

protected:
    virtual void            Paint( const Rectangle& rRect );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );
    virtual void            MouseButtonDown( const MouseEvent& rMEvt );
    virtual void            MouseButtonUp( const MouseEvent& rMEvt );
    virtual void            MouseMove( const MouseEvent& rMEvt );
    virtual void            KeyInput( const KeyEvent& rKEvt );
    virtual void            GetFocus();
    virtual void            LoseFocus();
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();

public:
                            ScDPFieldWindow(
                                ScDPLayoutDlg* pDialog,
                                const ResId& rResId,
                                ScDPFieldType eFieldType,
                                FixedText* pFtFieldCaption );
                            ScDPFieldWindow(
                                ScDPLayoutDlg* pDialog,
                                const ResId& rResId,
                                ScDPFieldType eFieldType,
                                const String& aName );
    virtual                 ~ScDPFieldWindow();

    /** Reads the FixedText's text with mnemonic and hides the FixedText. */
    void                    UseMnemonic();

    /** Draws the complete control. */
    void                    Redraw();

    /** @return  The pixel position of a field (without bound check). */
    Point                   GetFieldPosition( size_t nIndex ) const;
    /** @return  The pixel size of a field. */
    Size                    GetFieldSize() const;

    /** @return  The index of the selected field. */
    inline bool             IsEmpty() const { return aFieldArr.empty(); }
    /** @return  The index of the selected field. */
    inline size_t           GetSelectedField() const { return nFieldSelected; }
    /** @return  The pixel position of the last possible field. */
    Point                   GetLastPosition() const;

    /** @return  The count of existing fields. */
    inline size_t           GetFieldCount() const { return aFieldArr.size(); }
    /** Inserts a field to the specified index. */
    void                    AddField( const String& rText, size_t nNewIndex );
    /** Removes a field from the specified index. */
    void                    DelField( size_t nDelIndex );
    /** Removes all fields. */
    void                    ClearFields();
    /** Changes the text on an existing field. */
    void                    SetFieldText( const String& rText, size_t nIndex );
    /** Returns the text of an existing field. */
    const String&           GetFieldText( size_t nIndex ) const;

    /** Inserts a field using the specified pixel position.
        @param rPos  The coordinates to insert the field.
        @param rnIndex  The new index of the field is returned here.
        @return  TRUE, if the field has been created. */
    bool                    AddField( const String& rText, const Point& rPos, size_t& rnIndex );
    /** Calculates the field index at a specific pixel position.
        @param rnIndex  The index of the field is returned here.
        @return  TRUE, if the index value is valid. */
    bool                    GetFieldIndex( const Point& rPos, size_t& rnIndex ) const;
    /** Calculates a field index at a specific pixel position. Returns in every
        case the index of an existing field.
        @param rnIndex  The index of the field is returned here.
        @return  TRUE, if the index value is valid. */
    void                    GetExistingIndex( const Point& rPos, size_t& rnIndex );

    /** Notifies this control that the offset of the first field has been changed.
        The control has to adjust the selection to keep the same field selected
        on scrolling with scrollbar. */
    void                    ModifySelectionOffset( long nOffsetDiff );
    /** Selects the next field. Called i.e. after moving a field from SELECT area. */
    void                    SelectNext();

    /** @return The name of the control without shortcut. */
    inline String           GetName() const { return aName; }

    /** @return The description of the control which is used for the accessibility objects. */
    String                  GetDescription() const;

    /** Grabs focus and sets new selection. */
    void                    GrabFocusWithSel( size_t nIndex );

    /** @return The type of the FieldWindow. */
    inline ScDPFieldType    GetType() const { return eType; }
};

//===================================================================

#endif // SC_FIELDWND_HXX
<|endoftext|>


<commit_before>
#include <iostream>

#include "../../network/network.h"
#include "../../network/util.h"

int main(int argc, char *argv[])
{
	/* create Data */
	int ret;
	FILE *fp;
	const int trainingDataNum = 4;
	float *trainingData[trainingDataNum];
	float *labelData[trainingDataNum];
	float d[4][2];
	float l[4][2];
	int value;

	bool re;
	trainingData[0] = d[0];
	trainingData[1] = d[1];
	trainingData[2] = d[2];
	trainingData[3] = d[3];
	re = loadTrainingData(trainingData, "dataset/logic/train-exor.txt", trainingDataNum, 2);
	if(re == false) return 0;

	labelData[0] = l[0];
	labelData[1] = l[1];
	labelData[2] = l[2];
	labelData[3] = l[3];
	re = loadTrainingLabel(labelData, "dataset/logic/train-exor-label.txt", trainingDataNum, 2);
	if(re == false) return 0;

	for(int i = 0; i < 4; i++) {
		std::cout << trainingData[i][0] << trainingData[i][1] << " | ";
		std::cout << labelData[i][0] << labelData[i][1] << std::endl;
	}

	/* parameters */
	int epoch = 20000;
	float lr = 0.1;

	/* Create Network */
	Network *net;
	net = new Network();

	FullyConnectedLayer *full1, *full2;
	act_T *act1t, *act2t;

	act1t = new act_T;
	act1t->apply = logistic_apply;
	act1t->diff  = logistic_diff;
	act2t = new act_T;
	act2t->apply = logistic_apply;
	act2t->diff  = logistic_diff;
	full1 = new FullyConnectedLayer(2, 3, act1t, lr);
	full2 = new FullyConnectedLayer(3, 2, act2t, lr);

	net->appendLayer(full1);
	net->appendLayer(full2);

	net->setTest(trainingData, labelData, trainingDataNum, 1000);
	net->train(trainingData, labelData, trainingDataNum, epoch);
	net->saveParameters((char *)"parameters/logic/exor_20000.param");

	delete net;
	delete act1t;
	delete act2t;
	delete full1;
	delete full2;

	return 0;
}
<commit_msg>Delete unnecessary code<commit_after>
#include <iostream>

#include "../../network/network.h"
#include "../../network/util.h"

int main(int argc, char *argv[])
{
	/* create Data */
	bool re;
	const int trainingDataNum = 4;
	const int dataDim = 2;
	float *trainingData[trainingDataNum];
	float *labelData[trainingDataNum];

	for(int i = 0; i < trainingDataNum; i++) {
		trainingData[i] = new float(dataDim);
	}
	re = loadTrainingData(trainingData, "dataset/logic/train-exor.txt", trainingDataNum, dataDim);
	if(re == false) return 0;

	for(int i = 0; i < trainingDataNum; i++) {
		labelData[i] = new float(dataDim);
	}
	re = loadTrainingLabel(labelData, "dataset/logic/train-exor-label.txt", trainingDataNum, dataDim);
	if(re == false) return 0;

	for(int i = 0; i < 4; i++) {
		std::cout << trainingData[i][0] << trainingData[i][1] << " | ";
		std::cout << labelData[i][0] << labelData[i][1] << std::endl;
	}

	/* parameters */
	int epoch = 20000;
	float lr = 0.1;

	/* Create Network */
	Network *net;
	net = new Network();

	FullyConnectedLayer *full1, *full2;
	act_T *act1t, *act2t;

	act1t = new act_T;
	act1t->apply = logistic_apply;
	act1t->diff  = logistic_diff;
	act2t = new act_T;
	act2t->apply = logistic_apply;
	act2t->diff  = logistic_diff;
	full1 = new FullyConnectedLayer(2, 3, act1t, lr);
	full2 = new FullyConnectedLayer(3, 2, act2t, lr);

	net->appendLayer(full1);
	net->appendLayer(full2);

	net->setTest(trainingData, labelData, trainingDataNum, 1000);
	net->train(trainingData, labelData, trainingDataNum, epoch);
	net->saveParameters((char *)"parameters/logic/exor_20000.param");

	delete net;
	delete act1t;
	delete act2t;
	delete full1;
	delete full2;

	for(int i = 0; i < trainingDataNum; i++)
		delete trainingData[i];
	for(int i = 0; i < trainingDataNum; i++)
		delete labelData[i];

	return 0;
}
<|endoftext|>


<commit_before>/**
 * @file dewpoint.cpp
 *
 * @date Jan 21, 2012
 * @author partio
 */

#include "dewpoint.h"
#include <iostream>
#include "plugin_factory.h"
#include "logger_factory.h"
#include <boost/lexical_cast.hpp>

#define HIMAN_AUXILIARY_INCLUDE

#include "fetcher.h"
#include "writer.h"
#include "neons.h"
#include "pcuda.h"

#undef HIMAN_AUXILIARY_INCLUDE

#ifdef DEBUG
#include "timer_factory.h"
#endif

using namespace std;
using namespace himan::plugin;

#undef HAVE_CUDA

#ifdef HAVE_CUDA
namespace himan
{
namespace plugin
{
namespace dewpoint_cuda
{
void doCuda(const float* Tin, float TBase, const float* Pin, float PScale, const float* VVin, float* VVout, size_t N, float PConst, unsigned short deviceIndex);
}
}
}
#endif

const double RW = 461.5; // Vesihoyryn kaasuvakio (J / K kg)
const double L = 2.5e6; // Veden hoyrystymislampo (J / kg)
const double RW_div_L = RW / L;

dewpoint::dewpoint() : itsUseCuda(false)
{
    itsClearTextFormula = "Td = T / (1 - (T * ln(RH)*(Rw/L)))";

    itsLogger = std::unique_ptr<logger> (logger_factory::Instance()->GetLog("dewpoint"));

}

void dewpoint::Process(shared_ptr<configuration> conf)
{

    shared_ptr<plugin::pcuda> c = dynamic_pointer_cast<plugin::pcuda> (plugin_factory::Instance()->Plugin("pcuda"));

    if (c->HaveCuda())
    {
        string msg = "I possess the powers of CUDA";

        if (!conf->UseCuda())
        {
            msg += ", but I won't use them";
        }
        else
        {
            msg += ", and I'm not afraid to use them";
            itsUseCuda = true;
        }

        itsLogger->Info(msg);

    }

    // Get number of threads to use

    unsigned short threadCount = ThreadCount(conf->ThreadCount());

    boost::thread_group g;

    /*
     * The target information is parsed from the configuration file.
     */

    shared_ptr<info> targetInfo = conf->Info();

    /*
     * Get producer information from neons if whole_file_write is false.
     */

    if (!conf->WholeFileWrite())
    {
        shared_ptr<neons> n = dynamic_pointer_cast<neons> (plugin_factory::Instance()->Plugin("neons"));

        map<string,string> prodInfo = n->ProducerInfo(targetInfo->Producer().Id());

        if (prodInfo.size())
        {
            producer prod(targetInfo->Producer().Id());

            prod.Process(boost::lexical_cast<long> (prodInfo["process"]));
            prod.Centre(boost::lexical_cast<long> (prodInfo["centre"]));
            prod.Name(prodInfo["name"]);

            targetInfo->Producer(prod);
        }

    }

    /*
     * Set target parameter to potential temperature
     *
     * We need to specify grib and querydata parameter information
     * since we don't know which one will be the output format.
     *
     */

    vector<param> params;

    param requestedParam ("TD-K", 10);

    requestedParam.GribDiscipline(0);
    requestedParam.GribCategory(0);
    requestedParam.GribParameter(6);

    params.push_back(requestedParam);

    targetInfo->Params(params);

    /*
     * Create data structures.
     */

    targetInfo->Create(conf->ScanningMode(), false);

    /*
     * Initialize parent class functions for dimension handling
     */

    Dimension(conf->LeadingDimension());
    FeederInfo(targetInfo->Clone());
    FeederInfo()->Param(requestedParam);

    /*
     * Each thread will have a copy of the target info.
     */

    vector<shared_ptr<info> > targetInfos;

    targetInfos.resize(threadCount);

    for (size_t i = 0; i < threadCount; i++)
    {

        itsLogger->Info("Thread " + boost::lexical_cast<string> (i + 1) + " starting");

        targetInfos[i] = targetInfo->Clone();

        boost::thread* t = new boost::thread(&dewpoint::Run,
                                             this,
                                             targetInfos[i],
                                             conf,
                                             i + 1);

        g.add_thread(t);

    }

    g.join_all();

    if (conf->WholeFileWrite())
    {

        shared_ptr<writer> theWriter = dynamic_pointer_cast <writer> (plugin_factory::Instance()->Plugin("writer"));

        targetInfo->FirstTime();

        string theOutputFile = "himan_" + targetInfo->Param().Name() + "_" + targetInfo->Time().OriginDateTime()->String("%Y%m%d%H");
        theWriter->ToFile(targetInfo, conf->OutputFileType(), false, theOutputFile);

    }
}

void dewpoint::Run(shared_ptr<info> myTargetInfo,
               shared_ptr<const configuration> conf,
               unsigned short threadIndex)
{

    while (AdjustLeadingDimension(myTargetInfo))
    {
        Calculate(myTargetInfo, conf, threadIndex);
    }

}

/*
 * Calculate()
 *
 * This function does the actual calculation.
 */

void dewpoint::Calculate(shared_ptr<info> myTargetInfo,
                     shared_ptr<const configuration> conf,
                     unsigned short threadIndex)
{

    shared_ptr<fetcher> f = dynamic_pointer_cast <fetcher> (plugin_factory::Instance()->Plugin("fetcher"));

    // Required source parameters

    param TParam("T-K");
    param RHParam("RH-PRCNT");

    unique_ptr<logger> myThreadedLogger = std::unique_ptr<logger> (logger_factory::Instance()->GetLog("dewpointThread #" + boost::lexical_cast<string> (threadIndex)));

    ResetNonLeadingDimension(myTargetInfo);

    myTargetInfo->FirstParam();

    while (AdjustNonLeadingDimension(myTargetInfo))
    {

        myThreadedLogger->Debug("Calculating time " + myTargetInfo->Time().ValidDateTime()->String("%Y%m%d%H") +
                                " level " + boost::lexical_cast<string> (myTargetInfo->Level().Value()));

        myTargetInfo->Data()->Resize(conf->Ni(), conf->Nj());

        double TBase = 0;

        shared_ptr<info> TInfo;
        shared_ptr<info> RHInfo;

        try
        {
        	TInfo = f->Fetch(conf,
        						myTargetInfo->Time(),
        	                    myTargetInfo->Level(),
        	                    TParam);

        	RHInfo = f->Fetch(conf,
        						myTargetInfo->Time(),
        	        			myTargetInfo->Level(),
        	        			RHParam);

        }
        catch (HPExceptionType e)
        {
        	switch (e)
        	{
				case kFileDataNotFound:
					itsLogger->Info("Skipping step " + boost::lexical_cast<string> (myTargetInfo->Time().Step()) + ", level " + boost::lexical_cast<string> (myTargetInfo->Level().Value()));
					myTargetInfo->Data()->Fill(kFloatMissing); // Fill data with missing value
					continue;
					break;

				default:
					throw runtime_error(ClassName() + ": Unable to proceed");
					break;
			}
        }

        assert(RHInfo->Param().Unit() == kPrcnt);

    	if (TInfo->Param().Unit() == kC)
    	{
    		TBase = 273.15;
    	}

        shared_ptr<NFmiGrid> targetGrid(myTargetInfo->Grid()->ToNewbaseGrid());
        shared_ptr<NFmiGrid> TGrid(TInfo->Grid()->ToNewbaseGrid());
        shared_ptr<NFmiGrid> RHGrid(RHInfo->Grid()->ToNewbaseGrid());

        int missingCount = 0;
        int count = 0;

        bool equalGrids = (*myTargetInfo->Grid() == *TInfo->Grid() && *myTargetInfo->Grid() == *RHInfo->Grid());

#ifdef HAVE_CUDA

        if (itsUseCuda && equalGrids)
        {
            size_t N = TGrid->Size();

            float* VVout = new float[N];

            if (!isPressureLevel)
            {
                dewpoint_cuda::doCuda(TGrid->DataPool()->Data(), TBase, PGrid->DataPool()->Data(), PScale, VVGrid->DataPool()->Data(), VVout, N, 0, theThreadIndex-1);
            }
            else
            {
                dewpoint_cuda::doCuda(TGrid->DataPool()->Data(), TBase, 0, 0, VVGrid->DataPool()->Data(), VVout, N, 100 * myTargetInfo->Level().Value(), theThreadIndex-1);
            }

            double *data = new double[N];

            for (size_t i = 0; i < N; i++)
            {
                data[i] = static_cast<float> (VVout[i]);

                if (data[i] == kFloatMissing)
                {
                    missingCount++;
                }

                count++;
            }

            myTargetInfo->Data()->Set(data, N);

            delete [] data;
            delete [] VVout;

        }
        else
        {

#else
        if (true)
        {
#endif

            assert(targetGrid->Size() == myTargetInfo->Data()->Size());

            myTargetInfo->ResetLocation();

            targetGrid->Reset();

#ifdef DEBUG
            unique_ptr<timer> t = unique_ptr<timer> (timer_factory::Instance()->GetTimer());
            t->Start();
#endif

            while (myTargetInfo->NextLocation() && targetGrid->Next())
            {
                count++;

                double T = kFloatMissing;
                double RH = kFloatMissing;

                InterpolateToPoint(targetGrid, TGrid, equalGrids, T);
                InterpolateToPoint(targetGrid, RHGrid, equalGrids, RH);

                if (T == kFloatMissing || RH == kFloatMissing)
                {
                    missingCount++;

                    myTargetInfo->Value(kFloatMissing);
                    continue;
                }

                double TD = ((T+TBase) / (1 - ((T+TBase) * log(RH) * (RW_div_L)))) - 273.15 + TBase;

                if (!myTargetInfo->Value(TD))
                {
                    throw runtime_error(ClassName() + ": Failed to set value to matrix");
                }

            }
#ifdef DEBUG
            t->Stop();
            itsLogger->Debug("Calculation took " + boost::lexical_cast<string> (t->GetTime()) + " microseconds on CPU");
#endif
        }

        /*
         * Now we are done for this level
         *
         * Clone info-instance to writer since it might change our descriptor places
         */

        myThreadedLogger->Info("Missing values: " + boost::lexical_cast<string> (missingCount) + "/" + boost::lexical_cast<string> (count));

        if (!conf->WholeFileWrite())
        {
            shared_ptr<writer> w = dynamic_pointer_cast <writer> (plugin_factory::Instance()->Plugin("writer"));

            w->ToFile(myTargetInfo->Clone(), conf->OutputFileType(), true);
        }
    }
}
<commit_msg>Parameter unit change<commit_after>/**
 * @file dewpoint.cpp
 *
 * @date Jan 21, 2012
 * @author partio
 */

#include "dewpoint.h"
#include <iostream>
#include "plugin_factory.h"
#include "logger_factory.h"
#include <boost/lexical_cast.hpp>

#define HIMAN_AUXILIARY_INCLUDE

#include "fetcher.h"
#include "writer.h"
#include "neons.h"
#include "pcuda.h"

#undef HIMAN_AUXILIARY_INCLUDE

#ifdef DEBUG
#include "timer_factory.h"
#endif

using namespace std;
using namespace himan::plugin;

#undef HAVE_CUDA

#ifdef HAVE_CUDA
namespace himan
{
namespace plugin
{
namespace dewpoint_cuda
{
void doCuda(const float* Tin, float TBase, const float* Pin, float PScale, const float* VVin, float* VVout, size_t N, float PConst, unsigned short deviceIndex);
}
}
}
#endif

const double RW = 461.5; // Vesihoyryn kaasuvakio (J / K kg)
const double L = 2.5e6; // Veden hoyrystymislampo (J / kg)
const double RW_div_L = RW / L;

dewpoint::dewpoint() : itsUseCuda(false)
{
    itsClearTextFormula = "Td = T / (1 - (T * ln(RH)*(Rw/L)))";

    itsLogger = std::unique_ptr<logger> (logger_factory::Instance()->GetLog("dewpoint"));

}

void dewpoint::Process(shared_ptr<configuration> conf)
{

    shared_ptr<plugin::pcuda> c = dynamic_pointer_cast<plugin::pcuda> (plugin_factory::Instance()->Plugin("pcuda"));

    if (c->HaveCuda())
    {
        string msg = "I possess the powers of CUDA";

        if (!conf->UseCuda())
        {
            msg += ", but I won't use them";
        }
        else
        {
            msg += ", and I'm not afraid to use them";
            itsUseCuda = true;
        }

        itsLogger->Info(msg);

    }

    // Get number of threads to use

    unsigned short threadCount = ThreadCount(conf->ThreadCount());

    boost::thread_group g;

    /*
     * The target information is parsed from the configuration file.
     */

    shared_ptr<info> targetInfo = conf->Info();

    /*
     * Get producer information from neons if whole_file_write is false.
     */

    if (!conf->WholeFileWrite())
    {
        shared_ptr<neons> n = dynamic_pointer_cast<neons> (plugin_factory::Instance()->Plugin("neons"));

        map<string,string> prodInfo = n->ProducerInfo(targetInfo->Producer().Id());

        if (prodInfo.size())
        {
            producer prod(targetInfo->Producer().Id());

            prod.Process(boost::lexical_cast<long> (prodInfo["process"]));
            prod.Centre(boost::lexical_cast<long> (prodInfo["centre"]));
            prod.Name(prodInfo["name"]);

            targetInfo->Producer(prod);
        }

    }

    /*
     * Set target parameter to potential temperature
     *
     * We need to specify grib and querydata parameter information
     * since we don't know which one will be the output format.
     *
     */

    vector<param> params;

    param requestedParam ("TD-C", 10);

    requestedParam.GribDiscipline(0);
    requestedParam.GribCategory(0);
    requestedParam.GribParameter(6);

    params.push_back(requestedParam);

    targetInfo->Params(params);

    /*
     * Create data structures.
     */

    targetInfo->Create(conf->ScanningMode(), false);

    /*
     * Initialize parent class functions for dimension handling
     */

    Dimension(conf->LeadingDimension());
    FeederInfo(targetInfo->Clone());
    FeederInfo()->Param(requestedParam);

    /*
     * Each thread will have a copy of the target info.
     */

    vector<shared_ptr<info> > targetInfos;

    targetInfos.resize(threadCount);

    for (size_t i = 0; i < threadCount; i++)
    {

        itsLogger->Info("Thread " + boost::lexical_cast<string> (i + 1) + " starting");

        targetInfos[i] = targetInfo->Clone();

        boost::thread* t = new boost::thread(&dewpoint::Run,
                                             this,
                                             targetInfos[i],
                                             conf,
                                             i + 1);

        g.add_thread(t);

    }

    g.join_all();

    if (conf->WholeFileWrite())
    {

        shared_ptr<writer> theWriter = dynamic_pointer_cast <writer> (plugin_factory::Instance()->Plugin("writer"));

        targetInfo->FirstTime();

        string theOutputFile = "himan_" + targetInfo->Param().Name() + "_" + targetInfo->Time().OriginDateTime()->String("%Y%m%d%H");
        theWriter->ToFile(targetInfo, conf->OutputFileType(), false, theOutputFile);

    }
}

void dewpoint::Run(shared_ptr<info> myTargetInfo,
               shared_ptr<const configuration> conf,
               unsigned short threadIndex)
{

    while (AdjustLeadingDimension(myTargetInfo))
    {
        Calculate(myTargetInfo, conf, threadIndex);
    }

}

/*
 * Calculate()
 *
 * This function does the actual calculation.
 */

void dewpoint::Calculate(shared_ptr<info> myTargetInfo,
                     shared_ptr<const configuration> conf,
                     unsigned short threadIndex)
{

    shared_ptr<fetcher> f = dynamic_pointer_cast <fetcher> (plugin_factory::Instance()->Plugin("fetcher"));

    // Required source parameters

    param TParam("T-K");
    param RHParam("RH-PRCNT");

    unique_ptr<logger> myThreadedLogger = std::unique_ptr<logger> (logger_factory::Instance()->GetLog("dewpointThread #" + boost::lexical_cast<string> (threadIndex)));

    ResetNonLeadingDimension(myTargetInfo);

    myTargetInfo->FirstParam();

    while (AdjustNonLeadingDimension(myTargetInfo))
    {

        myThreadedLogger->Debug("Calculating time " + myTargetInfo->Time().ValidDateTime()->String("%Y%m%d%H") +
                                " level " + boost::lexical_cast<string> (myTargetInfo->Level().Value()));

        myTargetInfo->Data()->Resize(conf->Ni(), conf->Nj());

        double TBase = 0;

        shared_ptr<info> TInfo;
        shared_ptr<info> RHInfo;

        try
        {
        	TInfo = f->Fetch(conf,
        						myTargetInfo->Time(),
        	                    myTargetInfo->Level(),
        	                    TParam);

        	RHInfo = f->Fetch(conf,
        						myTargetInfo->Time(),
        	        			myTargetInfo->Level(),
        	        			RHParam);

        }
        catch (HPExceptionType e)
        {
        	switch (e)
        	{
				case kFileDataNotFound:
					itsLogger->Info("Skipping step " + boost::lexical_cast<string> (myTargetInfo->Time().Step()) + ", level " + boost::lexical_cast<string> (myTargetInfo->Level().Value()));
					myTargetInfo->Data()->Fill(kFloatMissing); // Fill data with missing value
					continue;
					break;

				default:
					throw runtime_error(ClassName() + ": Unable to proceed");
					break;
			}
        }

        assert(RHInfo->Param().Unit() == kPrcnt);

    	if (TInfo->Param().Unit() == kC)
    	{
    		TBase = 273.15;
    	}

        shared_ptr<NFmiGrid> targetGrid(myTargetInfo->Grid()->ToNewbaseGrid());
        shared_ptr<NFmiGrid> TGrid(TInfo->Grid()->ToNewbaseGrid());
        shared_ptr<NFmiGrid> RHGrid(RHInfo->Grid()->ToNewbaseGrid());

        int missingCount = 0;
        int count = 0;

        bool equalGrids = (*myTargetInfo->Grid() == *TInfo->Grid() && *myTargetInfo->Grid() == *RHInfo->Grid());

#ifdef HAVE_CUDA

        if (itsUseCuda && equalGrids)
        {
            size_t N = TGrid->Size();

            float* VVout = new float[N];

            if (!isPressureLevel)
            {
                dewpoint_cuda::doCuda(TGrid->DataPool()->Data(), TBase, PGrid->DataPool()->Data(), PScale, VVGrid->DataPool()->Data(), VVout, N, 0, theThreadIndex-1);
            }
            else
            {
                dewpoint_cuda::doCuda(TGrid->DataPool()->Data(), TBase, 0, 0, VVGrid->DataPool()->Data(), VVout, N, 100 * myTargetInfo->Level().Value(), theThreadIndex-1);
            }

            double *data = new double[N];

            for (size_t i = 0; i < N; i++)
            {
                data[i] = static_cast<float> (VVout[i]);

                if (data[i] == kFloatMissing)
                {
                    missingCount++;
                }

                count++;
            }

            myTargetInfo->Data()->Set(data, N);

            delete [] data;
            delete [] VVout;

        }
        else
        {

#else
        if (true)
        {
#endif

            assert(targetGrid->Size() == myTargetInfo->Data()->Size());

            myTargetInfo->ResetLocation();

            targetGrid->Reset();

#ifdef DEBUG
            unique_ptr<timer> t = unique_ptr<timer> (timer_factory::Instance()->GetTimer());
            t->Start();
#endif

            while (myTargetInfo->NextLocation() && targetGrid->Next())
            {
                count++;

                double T = kFloatMissing;
                double RH = kFloatMissing;

                InterpolateToPoint(targetGrid, TGrid, equalGrids, T);
                InterpolateToPoint(targetGrid, RHGrid, equalGrids, RH);

                if (T == kFloatMissing || RH == kFloatMissing)
                {
                    missingCount++;

                    myTargetInfo->Value(kFloatMissing);
                    continue;
                }

                double TD = ((T+TBase) / (1 - ((T+TBase) * log(RH) * (RW_div_L)))) - 273.15 + TBase;

                if (!myTargetInfo->Value(TD))
                {
                    throw runtime_error(ClassName() + ": Failed to set value to matrix");
                }

            }
#ifdef DEBUG
            t->Stop();
            itsLogger->Debug("Calculation took " + boost::lexical_cast<string> (t->GetTime()) + " microseconds on CPU");
#endif
        }

        /*
         * Now we are done for this level
         *
         * Clone info-instance to writer since it might change our descriptor places
         */

        myThreadedLogger->Info("Missing values: " + boost::lexical_cast<string> (missingCount) + "/" + boost::lexical_cast<string> (count));

        if (!conf->WholeFileWrite())
        {
            shared_ptr<writer> w = dynamic_pointer_cast <writer> (plugin_factory::Instance()->Plugin("writer"));

            w->ToFile(myTargetInfo->Clone(), conf->OutputFileType(), true);
        }
    }
}
<|endoftext|>