From 475b1746c133b0286871b7414918704557f1abcc Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Mon, 9 Mar 2015 15:53:07 +0100 Subject: Remove old Logging code (only used in fft.cu) --- include/astra/Logger.h | 72 -------------------------------------------------- 1 file changed, 72 deletions(-) delete mode 100644 include/astra/Logger.h (limited to 'include') diff --git a/include/astra/Logger.h b/include/astra/Logger.h deleted file mode 100644 index 34fd364..0000000 --- a/include/astra/Logger.h +++ /dev/null @@ -1,72 +0,0 @@ -/* ------------------------------------------------------------------------ -Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp - 2014-2015, CWI, Amsterdam - -Contact: astra@uantwerpen.be -Website: http://sf.net/projects/astra-toolbox - -This file is part of the ASTRA Toolbox. - - -The ASTRA Toolbox is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -The ASTRA Toolbox 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 General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the ASTRA Toolbox. If not, see . - ------------------------------------------------------------------------ -$Id$ -*/ - -#ifndef _INC_ASTRA_LOGGER -#define _INC_ASTRA_LOGGER - -#include - -namespace astra -{ - -/** - * This is the first stab at a decent logger. If the file "astra_logger.txt", it will be replaced - * with the text sent to this logger. If the file doesn't exist when the app starts, nothing is written. - */ -class CLogger -{ - static std::FILE * m_pOutFile; - static bool m_bInitialized; - - static void _assureIsInitialized(); - - CLogger(); - -public: - - /** - * Writes a line to the log file (newline is added). Ignored if logging is turned off. - * - * @param _text char pointer to text in line - */ - static void writeLine(const char * _text); - - /** - * Formats and writes a CUDA error to the log file. Ignored if logging is turned off. - * - * @param _fileName filename where error occurred (typically __FILE__) - * @param _line line in file (typically __LINE__) - * @param _errString string describing the error, can be output of cudaGetErrorString - */ - static void writeTerminalCUDAError(const char * _fileName, int _iLine, const char * _errString); -}; - -} - -#endif /* _INC_ASTRA_LOGGER */ - -- cgit v1.2.3 From a1dff91d7d8db49ecd79dfbcc6a6a663b114f9fd Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Mon, 9 Mar 2015 17:51:42 +0100 Subject: Adds new logging capabilities (based on clog.h) --- build/linux/Makefile.in | 1 + include/astra/Logging.h | 147 ++++++++++++ include/astra/clog.h | 622 ++++++++++++++++++++++++++++++++++++++++++++++++ src/Logging.cpp | 175 ++++++++++++++ 4 files changed, 945 insertions(+) create mode 100644 include/astra/Logging.h create mode 100644 include/astra/clog.h create mode 100644 src/Logging.cpp (limited to 'include') diff --git a/build/linux/Makefile.in b/build/linux/Makefile.in index d9ff045..c2b9994 100644 --- a/build/linux/Makefile.in +++ b/build/linux/Makefile.in @@ -118,6 +118,7 @@ BASE_OBJECTS=\ src/Fourier.lo \ src/GeometryUtil3D.lo \ src/Globals.lo \ + src/Logging.lo \ src/ParallelBeamBlobKernelProjector2D.lo \ src/ParallelBeamLinearKernelProjector2D.lo \ src/ParallelBeamLineKernelProjector2D.lo \ diff --git a/include/astra/Logging.h b/include/astra/Logging.h new file mode 100644 index 0000000..ce777ae --- /dev/null +++ b/include/astra/Logging.h @@ -0,0 +1,147 @@ +/* +----------------------------------------------------------------------- +Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp + 2014-2015, CWI, Amsterdam + +Contact: astra@uantwerpen.be +Website: http://sf.net/projects/astra-toolbox + +This file is part of the ASTRA Toolbox. + + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see . + +----------------------------------------------------------------------- +$Id$ +*/ + +#ifndef _INC_ASTRA_LOGGING +#define _INC_ASTRA_LOGGING + +#define ASTRA_LOG(id) __FILE__, __LINE__, id + +namespace astra +{ + +enum log_level { + LOG_DEBUG, + LOG_INFO, + LOG_WARN, + LOG_ERROR +}; + +class CLogger +{ + CLogger(); + ~CLogger(); + static bool m_bEnabledFile; + static bool m_bEnabledScreen; + static bool m_bFileProvided; + static bool m_bInitialized; + static void _assureIsInitialized(); + static void _setLevel(int id, log_level m_eLevel); + +public: + + /** + * Writes a line to the log file (newline is added). Ignored if logging is turned off. + * + * @param sfile + * The name of the source file making this log call (e.g. __FILE__). + * + * @param sline + * The line number of the call in the source code (e.g. __LINE__). + * + * @param id + * The id of the logger to write to. + * + * @param fmt + * The format string for the message (printf formatting). + * + * @param ... + * Any additional format arguments. + */ + static void debug(const char *sfile, int sline, const char *fmt, ...); + static void info(const char *sfile, int sline, const char *fmt, ...); + static void warn(const char *sfile, int sline, const char *fmt, ...); + static void error(const char *sfile, int sline, const char *fmt, ...); + + /** + * Sets the file to log to, with logging level. + * + * @param filename + * File to log to. + * + * @param m_eLevel + * Logging level (LOG_DEBUG, LOG_WARN, LOG_INFO, LOG_ERROR). + * + */ + static void setOutputFile(const char *filename, log_level m_eLevel); + + /** + * Sets the screen to log to, with logging level. + * + * @param screen_fd + * Screen file descriptor (1 for stdout, 2 for stderr) + * + * @param m_eLevel + * Logging level (LOG_DEBUG, LOG_WARN, LOG_INFO, LOG_ERROR). + * + */ + static void setOutputScreen(int fd, log_level m_eLevel); + + /** + * Set the format string for log messages. Here are the substitutions you may + * use: + * + * %f: Source file name generating the log call. + * %n: Source line number where the log call was made. + * %m: The message text sent to the logger (after printf formatting). + * %d: The current date, formatted using the logger's date format. + * %t: The current time, formatted using the logger's time format. + * %l: The log level (one of "DEBUG", "INFO", "WARN", or "ERROR"). + * %%: A literal percent sign. + * + * The default format string is "%d %t %f(%n): %l: %m\n". + * + * @param fmt + * The new format string, which must be less than 256 bytes. + * You probably will want to end this with a newline (\n). + * + */ + static void setFormatFile(const char *fmt); + static void setFormatScreen(const char *fmt); + + + /** + * Enable logging. + * + */ + static void enable(); + static void enableScreen(); + static void enableFile(); + + /** + * Disable logging. + * + */ + static void disable(); + static void disableScreen(); + static void disableFile(); + +}; + +} + +#endif /* _INC_ASTRA_LOGGING */ diff --git a/include/astra/clog.h b/include/astra/clog.h new file mode 100644 index 0000000..4d8e39d --- /dev/null +++ b/include/astra/clog.h @@ -0,0 +1,622 @@ +/* clog: Extremely simple logger for C. + * + * Features: + * - Implemented purely as a single header file. + * - Create multiple loggers. + * - Four log levels (debug, info, warn, error). + * - Custom formats. + * - Fast. + * + * Dependencies: + * - Should conform to C89, C++98 (but requires vsnprintf, unfortunately). + * - POSIX environment. + * + * USAGE: + * + * Include this header in any file that wishes to write to logger(s). In + * exactly one file (per executable), define CLOG_MAIN first (e.g. in your + * main .c file). + * + * #define CLOG_MAIN + * #include "clog.h" + * + * This will define the actual objects that all the other units will use. + * + * Loggers are identified by integers (0 - 15). It's expected that you'll + * create meaningful constants and then refer to the loggers as such. + * + * Example: + * + * const int MY_LOGGER = 0; + * + * int main() { + * int r; + * r = clog_init_path(MY_LOGGER, "my_log.txt"); + * if (r != 0) { + * fprintf(stderr, "Logger initialization failed.\n"); + * return 1; + * } + * clog_info(CLOG(MY_LOGGER), "Hello, world!"); + * clog_free(MY_LOGGER); + * return 0; + * } + * + * The CLOG macro used in the call to clog_info is a helper that passes the + * __FILE__ and __LINE__ parameters for you, so you don't have to type them + * every time. (It could be prettier with variadic macros, but that requires + * C99 or C++11 to be standards compliant.) + * + * Errors encountered by clog will be printed to stderr. You can suppress + * these by defining a macro called CLOG_SILENT before including clog.h. + * + * License: Do whatever you want. It would be nice if you contribute + * improvements as pull requests here: + * + * https://github.com/mmueller/clog + * + * Copyright 2013 Mike Mueller . + * + * As is; no warranty is provided; use at your own risk. + */ + +#ifndef __CLOG_H__ +#define __CLOG_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Number of loggers that can be defined. */ +#define CLOG_MAX_LOGGERS 16 + +/* Format strings cannot be longer than this. */ +#define CLOG_FORMAT_LENGTH 256 + +/* Formatted times and dates should be less than this length. If they are not, + * they will not appear in the log. */ +#define CLOG_DATETIME_LENGTH 256 + +/* Default format strings. */ +#define CLOG_DEFAULT_FORMAT "%d %t %f(%n): %l: %m\n" +#define CLOG_DEFAULT_DATE_FORMAT "%Y-%m-%d" +#define CLOG_DEFAULT_TIME_FORMAT "%H:%M:%S" + +#ifdef __cplusplus +extern "C" { +#endif + +enum clog_level { + CLOG_DEBUG, + CLOG_INFO, + CLOG_WARN, + CLOG_ERROR +}; + +struct clog; + +/** + * Create a new logger writing to the given file path. The file will always + * be opened in append mode. + * + * @param id + * A constant integer between 0 and 15 that uniquely identifies this logger. + * + * @param path + * Path to the file where log messages will be written. + * + * @return + * Zero on success, non-zero on failure. + */ +int clog_init_path(int id, const char *const path); + +/** + * Create a new logger writing to a file descriptor. + * + * @param id + * A constant integer between 0 and 15 that uniquely identifies this logger. + * + * @param fd + * The file descriptor where log messages will be written. + * + * @return + * Zero on success, non-zero on failure. + */ +int clog_init_fd(int id, int fd); + +/** + * Destroy (clean up) a logger. You should do this at the end of execution, + * or when you are done using the logger. + * + * @param id + * The id of the logger to destroy. + */ +void clog_free(int id); + +#define CLOG(id) __FILE__, __LINE__, id + +/** + * Log functions (one per level). Call these to write messages to the log + * file. The first three arguments can be replaced with a call to the CLOG + * macro defined above, e.g.: + * + * clog_debug(CLOG(MY_LOGGER_ID), "This is a log message."); + * + * @param sfile + * The name of the source file making this log call (e.g. __FILE__). + * + * @param sline + * The line number of the call in the source code (e.g. __LINE__). + * + * @param id + * The id of the logger to write to. + * + * @param fmt + * The format string for the message (printf formatting). + * + * @param ... + * Any additional format arguments. + */ +void clog_debug(const char *sfile, int sline, int id, const char *fmt, va_list ap); +void clog_info(const char *sfile, int sline, int id, const char *fmt, va_list ap); +void clog_warn(const char *sfile, int sline, int id, const char *fmt, va_list ap); +void clog_error(const char *sfile, int sline, int id, const char *fmt, va_list ap); + +/** + * Set the minimum level of messages that should be written to the log. + * Messages below this level will not be written. By default, loggers are + * created with level == CLOG_DEBUG. + * + * @param id + * The identifier of the logger. + * + * @param level + * The new minimum log level. + * + * @return + * Zero on success, non-zero on failure. + */ +int clog_set_level(int id, enum clog_level level); + +/** + * Set the format string used for times. See strftime(3) for how this string + * should be defined. The default format string is CLOG_DEFAULT_TIME_FORMAT. + * + * @param fmt + * The new format string, which must be less than CLOG_FORMAT_LENGTH bytes. + * + * @return + * Zero on success, non-zero on failure. + */ +int clog_set_time_fmt(int id, const char *fmt); + +/** + * Set the format string used for dates. See strftime(3) for how this string + * should be defined. The default format string is CLOG_DEFAULT_DATE_FORMAT. + * + * @param fmt + * The new format string, which must be less than CLOG_FORMAT_LENGTH bytes. + * + * @return + * Zero on success, non-zero on failure. + */ +int clog_set_date_fmt(int id, const char *fmt); + +/** + * Set the format string for log messages. Here are the substitutions you may + * use: + * + * %f: Source file name generating the log call. + * %n: Source line number where the log call was made. + * %m: The message text sent to the logger (after printf formatting). + * %d: The current date, formatted using the logger's date format. + * %t: The current time, formatted using the logger's time format. + * %l: The log level (one of "DEBUG", "INFO", "WARN", or "ERROR"). + * %%: A literal percent sign. + * + * The default format string is CLOG_DEFAULT_FORMAT. + * + * @param fmt + * The new format string, which must be less than CLOG_FORMAT_LENGTH bytes. + * You probably will want to end this with a newline (\n). + * + * @return + * Zero on success, non-zero on failure. + */ +int clog_set_fmt(int id, const char *fmt); + +/* + * No need to read below this point. + */ + +/** + * The C logger structure. + */ +struct clog { + + /* The current level of this logger. Messages below it will be dropped. */ + enum clog_level level; + + /* The file being written. */ + int fd; + + /* The format specifier. */ + char fmt[CLOG_FORMAT_LENGTH]; + + /* Date format */ + char date_fmt[CLOG_FORMAT_LENGTH]; + + /* Time format */ + char time_fmt[CLOG_FORMAT_LENGTH]; + + /* Tracks whether the fd needs to be closed eventually. */ + int opened; +}; + +void _clog_err(const char *fmt, ...); + +#ifdef CLOG_MAIN +struct clog *_clog_loggers[CLOG_MAX_LOGGERS] = { 0 }; +#else +extern struct clog *_clog_loggers[CLOG_MAX_LOGGERS]; +#endif + +#ifdef CLOG_MAIN + +const char *const CLOG_LEVEL_NAMES[] = { + "DEBUG", + "INFO", + "WARN", + "ERROR", +}; + +int +clog_init_path(int id, const char *const path) +{ + int fd = open(path, O_CREAT | O_WRONLY | O_APPEND, 0666); + if (fd == -1) { + _clog_err("Unable to open %s: %s\n", path, strerror(errno)); + return 1; + } + if (clog_init_fd(id, fd)) { + close(fd); + return 1; + } + _clog_loggers[id]->opened = 1; + return 0; +} + +int +clog_init_fd(int id, int fd) +{ + struct clog *logger; + + if (_clog_loggers[id] != NULL) { + _clog_err("Logger %d already initialized.\n", id); + return 1; + } + + logger = (struct clog *) malloc(sizeof(struct clog)); + if (logger == NULL) { + _clog_err("Failed to allocate logger: %s\n", strerror(errno)); + return 1; + } + + logger->level = CLOG_DEBUG; + logger->fd = fd; + logger->opened = 0; + strcpy(logger->fmt, CLOG_DEFAULT_FORMAT); + strcpy(logger->date_fmt, CLOG_DEFAULT_DATE_FORMAT); + strcpy(logger->time_fmt, CLOG_DEFAULT_TIME_FORMAT); + + _clog_loggers[id] = logger; + return 0; +} + +void +clog_free(int id) +{ + if (_clog_loggers[id]) { + if (_clog_loggers[id]->opened) { + close(_clog_loggers[id]->fd); + } + free(_clog_loggers[id]); + _clog_loggers[id]=NULL; + } +} + +int +clog_set_level(int id, enum clog_level level) +{ + if (_clog_loggers[id] == NULL) { + return 1; + } + if ((unsigned) level > CLOG_ERROR) { + return 1; + } + _clog_loggers[id]->level = level; + return 0; +} + +int +clog_set_time_fmt(int id, const char *fmt) +{ + struct clog *logger = _clog_loggers[id]; + if (logger == NULL) { + _clog_err("clog_set_time_fmt: No such logger: %d\n", id); + return 1; + } + if (strlen(fmt) >= CLOG_FORMAT_LENGTH) { + _clog_err("clog_set_time_fmt: Format specifier too long.\n"); + return 1; + } + strcpy(logger->time_fmt, fmt); + return 0; +} + +int +clog_set_date_fmt(int id, const char *fmt) +{ + struct clog *logger = _clog_loggers[id]; + if (logger == NULL) { + _clog_err("clog_set_date_fmt: No such logger: %d\n", id); + return 1; + } + if (strlen(fmt) >= CLOG_FORMAT_LENGTH) { + _clog_err("clog_set_date_fmt: Format specifier too long.\n"); + return 1; + } + strcpy(logger->date_fmt, fmt); + return 0; +} + +int +clog_set_fmt(int id, const char *fmt) +{ + struct clog *logger = _clog_loggers[id]; + if (logger == NULL) { + _clog_err("clog_set_fmt: No such logger: %d\n", id); + return 1; + } + if (strlen(fmt) >= CLOG_FORMAT_LENGTH) { + _clog_err("clog_set_fmt: Format specifier too long.\n"); + return 1; + } + strcpy(logger->fmt, fmt); + return 0; +} + +/* Internal functions */ + +size_t +_clog_append_str(char **dst, char *orig_buf, const char *src, size_t cur_size) +{ + size_t new_size = cur_size; + + while (strlen(*dst) + strlen(src) >= new_size) { + new_size *= 2; + } + if (new_size != cur_size) { + if (*dst == orig_buf) { + *dst = (char *) malloc(new_size); + strcpy(*dst, orig_buf); + } else { + *dst = (char *) realloc(*dst, new_size); + } + } + + strcat(*dst, src); + return new_size; +} + +size_t +_clog_append_int(char **dst, char *orig_buf, long int d, size_t cur_size) +{ + char buf[40]; /* Enough for 128-bit decimal */ + if (snprintf(buf, 40, "%ld", d) >= 40) { + return cur_size; + } + return _clog_append_str(dst, orig_buf, buf, cur_size); +} + +size_t +_clog_append_time(char **dst, char *orig_buf, struct tm *lt, + const char *fmt, size_t cur_size) +{ + char buf[CLOG_DATETIME_LENGTH]; + size_t result = strftime(buf, CLOG_DATETIME_LENGTH, fmt, lt); + + if (result > 0) { + return _clog_append_str(dst, orig_buf, buf, cur_size); + } + + return cur_size; +} + +const char * +_clog_basename(const char *path) +{ + const char *slash = strrchr(path, '/'); + if (slash) { + path = slash + 1; + } +#ifdef _WIN32 + slash = strrchr(path, '\\'); + if (slash) { + path = slash + 1; + } +#endif + return path; +} + +char * +_clog_format(const struct clog *logger, char buf[], size_t buf_size, + const char *sfile, int sline, const char *level, + const char *message) +{ + size_t cur_size = buf_size; + char *result = buf; + enum { NORMAL, SUBST } state = NORMAL; + size_t fmtlen = strlen(logger->fmt); + size_t i; + time_t t = time(NULL); + struct tm *lt = localtime(&t); + + sfile = _clog_basename(sfile); + result[0] = 0; + for (i = 0; i < fmtlen; ++i) { + if (state == NORMAL) { + if (logger->fmt[i] == '%') { + state = SUBST; + } else { + char str[2] = { 0 }; + str[0] = logger->fmt[i]; + cur_size = _clog_append_str(&result, buf, str, cur_size); + } + } else { + switch (logger->fmt[i]) { + case '%': + cur_size = _clog_append_str(&result, buf, "%", cur_size); + break; + case 't': + cur_size = _clog_append_time(&result, buf, lt, + logger->time_fmt, cur_size); + break; + case 'd': + cur_size = _clog_append_time(&result, buf, lt, + logger->date_fmt, cur_size); + break; + case 'l': + cur_size = _clog_append_str(&result, buf, level, cur_size); + break; + case 'n': + cur_size = _clog_append_int(&result, buf, sline, cur_size); + break; + case 'f': + cur_size = _clog_append_str(&result, buf, sfile, cur_size); + break; + case 'm': + cur_size = _clog_append_str(&result, buf, message, + cur_size); + break; + } + state = NORMAL; + } + } + + return result; +} + +void +_clog_log(const char *sfile, int sline, enum clog_level level, + int id, const char *fmt, va_list ap) +{ + /* For speed: Use a stack buffer until message exceeds 4096, then switch + * to dynamically allocated. This should greatly reduce the number of + * memory allocations (and subsequent fragmentation). */ + char buf[4096]; + size_t buf_size = 4096; + char *dynbuf = buf; + char *message; + int result; + struct clog *logger = _clog_loggers[id]; + + if (!logger) { + _clog_err("No such logger: %d\n", id); + return; + } + + if (level < logger->level) { + return; + } + + /* Format the message text with the argument list. */ + result = vsnprintf(dynbuf, buf_size, fmt, ap); + if ((size_t) result >= buf_size) { + buf_size = result + 1; + dynbuf = (char *) malloc(buf_size); + result = vsnprintf(dynbuf, buf_size, fmt, ap); + if ((size_t) result >= buf_size) { + /* Formatting failed -- too large */ + _clog_err("Formatting failed (1).\n"); + free(dynbuf); + return; + } + } + + /* Format according to log format and write to log */ + { + char message_buf[4096]; + message = _clog_format(logger, message_buf, 4096, sfile, sline, + CLOG_LEVEL_NAMES[level], dynbuf); + if (!message) { + _clog_err("Formatting failed (2).\n"); + if (dynbuf != buf) { + free(dynbuf); + } + return; + } + result = write(logger->fd, message, strlen(message)); + if (result == -1) { + _clog_err("Unable to write to log file: %s\n", strerror(errno)); + } + if (message != message_buf) { + free(message); + } + if (dynbuf != buf) { + free(dynbuf); + } + fsync(logger->fd); + } +} + +void +clog_debug(const char *sfile, int sline, int id, const char *fmt, va_list ap) +{ + _clog_log(sfile, sline, CLOG_DEBUG, id, fmt, ap); +} + +void +clog_info(const char *sfile, int sline, int id, const char *fmt, va_list ap) +{ + _clog_log(sfile, sline, CLOG_INFO, id, fmt, ap); +} + +void +clog_warn(const char *sfile, int sline, int id, const char *fmt, va_list ap) +{ + _clog_log(sfile, sline, CLOG_WARN, id, fmt, ap); +} + +void +clog_error(const char *sfile, int sline, int id, const char *fmt, va_list ap) +{ + _clog_log(sfile, sline, CLOG_ERROR, id, fmt, ap); +} + +void +_clog_err(const char *fmt, ...) +{ +#ifdef CLOG_SILENT + (void) fmt; +#else + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); +#endif +} + +#endif /* CLOG_MAIN */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __CLOG_H__ */ diff --git a/src/Logging.cpp b/src/Logging.cpp new file mode 100644 index 0000000..9011d37 --- /dev/null +++ b/src/Logging.cpp @@ -0,0 +1,175 @@ +/* +----------------------------------------------------------------------- +Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp + 2014-2015, CWI, Amsterdam + +Contact: astra@uantwerpen.be +Website: http://sf.net/projects/astra-toolbox + +This file is part of the ASTRA Toolbox. + + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see . + +----------------------------------------------------------------------- +$Id$ +*/ + +#define CLOG_MAIN +#include + +#include + +#include + +using namespace astra; + +void CLogger::enableScreen() +{ + m_bEnabledScreen = true; +} + +void CLogger::enableFile() +{ + m_bEnabledFile = true; +} + +void CLogger::enable() +{ + enableScreen(); + enableFile(); +} + +void CLogger::disableScreen() +{ + m_bEnabledScreen = false; +} + +void CLogger::disableFile() +{ + m_bEnabledFile = false; +} + +void CLogger::disable() +{ + disableScreen(); + disableFile(); +} + +void CLogger::debug(const char *sfile, int sline, const char *fmt, ...) +{ + _assureIsInitialized(); + va_list ap; + va_start(ap, fmt); + if(m_bEnabledScreen) clog_debug(sfile,sline,0,fmt,ap); + if(m_bEnabledFile && m_bFileProvided) clog_debug(sfile,sline,1,fmt,ap); +} + +void CLogger::info(const char *sfile, int sline, const char *fmt, ...) +{ + _assureIsInitialized(); + va_list ap; + va_start(ap, fmt); + if(m_bEnabledScreen) clog_info(sfile,sline,0,fmt,ap); + if(m_bEnabledFile && m_bFileProvided) clog_info(sfile,sline,1,fmt,ap); +} + +void CLogger::warn(const char *sfile, int sline, const char *fmt, ...) +{ + _assureIsInitialized(); + va_list ap; + va_start(ap, fmt); + if(m_bEnabledScreen) clog_warn(sfile,sline,0,fmt,ap); + if(m_bEnabledFile && m_bFileProvided) clog_warn(sfile,sline,1,fmt,ap); +} + +void CLogger::error(const char *sfile, int sline, const char *fmt, ...) +{ + _assureIsInitialized(); + va_list ap; + va_start(ap, fmt); + if(m_bEnabledScreen) clog_error(sfile,sline,0,fmt,ap); + if(m_bEnabledFile && m_bFileProvided) clog_error(sfile,sline,1,fmt,ap); +} + +void CLogger::_setLevel(int id, log_level m_eLevel) +{ + switch(m_eLevel){ + case LOG_DEBUG: + clog_set_level(id,CLOG_DEBUG); + break; + case LOG_INFO: + clog_set_level(id,CLOG_INFO); + break; + case LOG_WARN: + clog_set_level(id,CLOG_WARN); + break; + case LOG_ERROR: + clog_set_level(id,CLOG_ERROR); + break; + } +} + +void CLogger::setOutputScreen(int fd, log_level m_eLevel) +{ + _assureIsInitialized(); + clog_free(0); + clog_init_fd(0, fd); + _setLevel(0,m_eLevel); +} + +void CLogger::setOutputFile(const char *filename, log_level m_eLevel) +{ + if(m_bFileProvided){ + clog_free(1); + m_bFileProvided=false; + } + if(!clog_init_path(1,filename)){ + m_bFileProvided=true; + _setLevel(1,m_eLevel); + } +} + +void CLogger::_assureIsInitialized() +{ + if(!m_bInitialized) + { + clog_init_fd(0, 2); + clog_set_level(0, CLOG_INFO); + m_bInitialized = true; + } +} + +void CLogger::setFormatFile(const char *fmt) +{ + if(m_bFileProvided){ + clog_set_fmt(1,fmt); + }else{ + error(__FILE__,__LINE__,"No log file specified"); + } +} +void CLogger::setFormatScreen(const char *fmt) +{ + clog_set_fmt(0,fmt); +} + +CLogger::CLogger() +{ + ; +} + +bool CLogger::m_bEnabledScreen = true; +bool CLogger::m_bEnabledFile = true; +bool CLogger::m_bFileProvided = false; +bool CLogger::m_bInitialized = false; -- cgit v1.2.3 From c5507b6ef2abfab169150528a374526bb348bf62 Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Fri, 13 Mar 2015 12:18:21 +0100 Subject: Adds ASTRA_*** defines for easier logging, and changes internal calls to these defines --- cuda/2d/astra.cu | 2 +- cuda/2d/fft.cu | 24 ++++++++++++------------ cuda/2d/util.cu | 6 +++--- cuda/3d/util3d.cu | 10 +++++----- include/astra/Logging.h | 5 ++++- src/ConeProjectionGeometry3D.cpp | 2 +- src/Config.cpp | 2 +- src/CudaFilteredBackProjectionAlgorithm.cpp | 2 +- src/CudaForwardProjectionAlgorithm.cpp | 2 +- src/CudaForwardProjectionAlgorithm3D.cpp | 2 +- src/CudaReconstructionAlgorithm2D.cpp | 2 +- src/FilteredBackProjectionAlgorithm.cpp | 2 +- 12 files changed, 32 insertions(+), 29 deletions(-) (limited to 'include') diff --git a/cuda/2d/astra.cu b/cuda/2d/astra.cu index 71fd089..2f72db0 100644 --- a/cuda/2d/astra.cu +++ b/cuda/2d/astra.cu @@ -564,7 +564,7 @@ bool AstraFBP::setFilter(E_FBPFILTER _eFilter, const float * _pfHostFilter /* = } default: { - astra::CLogger::error(__FILE__,__LINE__,"AstraFBP::setFilter: Unknown filter type requested"); + ASTRA_ERROR("AstraFBP::setFilter: Unknown filter type requested"); delete [] pHostFilter; return false; } diff --git a/cuda/2d/fft.cu b/cuda/2d/fft.cu index 468c7c2..49c696c 100644 --- a/cuda/2d/fft.cu +++ b/cuda/2d/fft.cu @@ -43,7 +43,7 @@ using namespace astra; #define CHECK_ERROR(errorMessage) do { \ cudaError_t err = cudaThreadSynchronize(); \ if( cudaSuccess != err) { \ - astra::CLogger::error(__FILE__,__LINE__,"Cuda error %s : %s", \ + ASTRA_ERROR("Cuda error %s : %s", \ errorMessage,cudaGetErrorString( err)); \ exit(EXIT_FAILURE); \ } } while (0) @@ -51,13 +51,13 @@ using namespace astra; #define SAFE_CALL( call) do { \ cudaError err = call; \ if( cudaSuccess != err) { \ - astra::CLogger::error(__FILE__,__LINE__,"Cuda error: %s ", \ + ASTRA_ERROR("Cuda error: %s ", \ cudaGetErrorString( err)); \ exit(EXIT_FAILURE); \ } \ err = cudaThreadSynchronize(); \ if( cudaSuccess != err) { \ - astra::CLogger::error(__FILE__,__LINE__,"Cuda error: %s : ", \ + ASTRA_ERROR("Cuda error: %s : ", \ cudaGetErrorString( err)); \ exit(EXIT_FAILURE); \ } } while (0) @@ -137,7 +137,7 @@ static bool invokeCudaFFT(int _iProjectionCount, int _iDetectorCount, result = cufftPlan1d(&plan, _iDetectorCount, CUFFT_R2C, _iProjectionCount); if(result != CUFFT_SUCCESS) { - astra::CLogger::error(__FILE__,__LINE__,"Failed to plan 1d r2c fft"); + ASTRA_ERROR("Failed to plan 1d r2c fft"); return false; } @@ -146,7 +146,7 @@ static bool invokeCudaFFT(int _iProjectionCount, int _iDetectorCount, if(result != CUFFT_SUCCESS) { - astra::CLogger::error(__FILE__,__LINE__,"Failed to exec 1d r2c fft"); + ASTRA_ERROR("Failed to exec 1d r2c fft"); return false; } @@ -163,7 +163,7 @@ static bool invokeCudaIFFT(int _iProjectionCount, int _iDetectorCount, result = cufftPlan1d(&plan, _iDetectorCount, CUFFT_C2R, _iProjectionCount); if(result != CUFFT_SUCCESS) { - astra::CLogger::error(__FILE__,__LINE__,"Failed to plan 1d c2r fft"); + ASTRA_ERROR("Failed to plan 1d c2r fft"); return false; } @@ -174,7 +174,7 @@ static bool invokeCudaIFFT(int _iProjectionCount, int _iDetectorCount, if(result != CUFFT_SUCCESS) { - astra::CLogger::error(__FILE__,__LINE__,"Failed to exec 1d c2r fft"); + ASTRA_ERROR("Failed to exec 1d c2r fft"); return false; } @@ -630,7 +630,7 @@ void genFilter(E_FBPFILTER _eFilter, float _fD, int _iProjectionCount, } default: { - astra::CLogger::error(__FILE__,__LINE__,"Cannot serve requested filter"); + ASTRA_ERROR("Cannot serve requested filter"); } } @@ -764,13 +764,13 @@ void testCudaFFT() result = cufftPlan1d(&plan, iDetectorCount, CUFFT_R2C, iProjectionCount); if(result != CUFFT_SUCCESS) { - astra::CLogger::error(__FILE__,__LINE__,"Failed to plan 1d r2c fft"); + ASTRA_ERROR("Failed to plan 1d r2c fft"); } result = cufftExecR2C(plan, pfDevProj, pDevFourProj); if(result != CUFFT_SUCCESS) { - astra::CLogger::error(__FILE__,__LINE__,"Failed to exec 1d r2c fft"); + ASTRA_ERROR("Failed to exec 1d r2c fft"); } cufftDestroy(plan); @@ -794,13 +794,13 @@ void testCudaFFT() result = cufftPlan1d(&plan, iDetectorCount, CUFFT_C2R, iProjectionCount); if(result != CUFFT_SUCCESS) { - astra::CLogger::error(__FILE__,__LINE__,"Failed to plan 1d c2r fft"); + ASTRA_ERROR("Failed to plan 1d c2r fft"); } result = cufftExecC2R(plan, pDevFourProj, pfDevInFourProj); if(result != CUFFT_SUCCESS) { - astra::CLogger::error(__FILE__,__LINE__,"Failed to exec 1d c2r fft"); + ASTRA_ERROR("Failed to exec 1d c2r fft"); } cufftDestroy(plan); diff --git a/cuda/2d/util.cu b/cuda/2d/util.cu index 6ced557..a4f8f3e 100644 --- a/cuda/2d/util.cu +++ b/cuda/2d/util.cu @@ -93,7 +93,7 @@ bool allocateVolume(float*& ptr, unsigned int width, unsigned int height, unsign cudaError_t ret = cudaMallocPitch((void**)&ptr, &p, sizeof(float)*width, height); if (ret != cudaSuccess) { reportCudaError(ret); - astra::CLogger::error(__FILE__,__LINE__,"Failed to allocate %dx%d GPU buffer", width, height); + ASTRA_ERROR("Failed to allocate %dx%d GPU buffer", width, height); return false; } @@ -261,7 +261,7 @@ bool cudaTextForceKernelsCompletion() cudaError_t returnedCudaError = cudaThreadSynchronize(); if(returnedCudaError != cudaSuccess) { - astra::CLogger::error(__FILE__,__LINE__,"Failed to force completion of cuda kernels: %d: %s.", returnedCudaError, cudaGetErrorString(returnedCudaError)); + ASTRA_ERROR("Failed to force completion of cuda kernels: %d: %s.", returnedCudaError, cudaGetErrorString(returnedCudaError)); return false; } @@ -271,7 +271,7 @@ bool cudaTextForceKernelsCompletion() void reportCudaError(cudaError_t err) { if(err != cudaSuccess) - astra::CLogger::error(__FILE__,__LINE__,"CUDA error %d: %s.", err, cudaGetErrorString(err)); + ASTRA_ERROR("CUDA error %d: %s.", err, cudaGetErrorString(err)); } diff --git a/cuda/3d/util3d.cu b/cuda/3d/util3d.cu index f2d16b3..537ed69 100644 --- a/cuda/3d/util3d.cu +++ b/cuda/3d/util3d.cu @@ -48,7 +48,7 @@ cudaPitchedPtr allocateVolumeData(const SDimensions3D& dims) cudaError err = cudaMalloc3D(&volData, extentV); if (err != cudaSuccess) { astraCUDA::reportCudaError(err); - astra::CLogger::error(__FILE__,__LINE__,"Failed to allocate %dx%dx%d GPU buffer", dims.iVolX, dims.iVolY, dims.iVolZ); + ASTRA_ERROR("Failed to allocate %dx%dx%d GPU buffer", dims.iVolX, dims.iVolY, dims.iVolZ); volData.ptr = 0; // TODO: return 0 somehow? } @@ -67,7 +67,7 @@ cudaPitchedPtr allocateProjectionData(const SDimensions3D& dims) cudaError err = cudaMalloc3D(&projData, extentP); if (err != cudaSuccess) { astraCUDA::reportCudaError(err); - astra::CLogger::error(__FILE__,__LINE__,"Failed to allocate %dx%dx%d GPU buffer", dims.iProjU, dims.iProjAngles, dims.iProjV); + ASTRA_ERROR("Failed to allocate %dx%dx%d GPU buffer", dims.iProjU, dims.iProjAngles, dims.iProjV); projData.ptr = 0; // TODO: return 0 somehow? } @@ -305,7 +305,7 @@ cudaArray* allocateVolumeArray(const SDimensions3D& dims) cudaError err = cudaMalloc3DArray(&cuArray, &channelDesc, extentA); if (err != cudaSuccess) { astraCUDA::reportCudaError(err); - astra::CLogger::error(__FILE__,__LINE__,"Failed to allocate %dx%dx%d GPU array", dims.iVolX, dims.iVolY, dims.iVolZ); + ASTRA_ERROR("Failed to allocate %dx%dx%d GPU array", dims.iVolX, dims.iVolY, dims.iVolZ); return 0; } @@ -323,7 +323,7 @@ cudaArray* allocateProjectionArray(const SDimensions3D& dims) if (err != cudaSuccess) { astraCUDA::reportCudaError(err); - astra::CLogger::error(__FILE__,__LINE__,"Failed to allocate %dx%dx%d GPU array", dims.iProjU, dims.iProjAngles, dims.iProjV); + ASTRA_ERROR("Failed to allocate %dx%dx%d GPU array", dims.iProjU, dims.iProjAngles, dims.iProjV); return 0; } @@ -399,7 +399,7 @@ bool cudaTextForceKernelsCompletion() cudaError_t returnedCudaError = cudaThreadSynchronize(); if(returnedCudaError != cudaSuccess) { - astra::CLogger::error(__FILE__,__LINE__,"Failed to force completion of cuda kernels: %d: %s.", returnedCudaError, cudaGetErrorString(returnedCudaError)); + ASTRA_ERROR("Failed to force completion of cuda kernels: %d: %s.", returnedCudaError, cudaGetErrorString(returnedCudaError)); return false; } diff --git a/include/astra/Logging.h b/include/astra/Logging.h index ce777ae..5695663 100644 --- a/include/astra/Logging.h +++ b/include/astra/Logging.h @@ -29,7 +29,10 @@ $Id$ #ifndef _INC_ASTRA_LOGGING #define _INC_ASTRA_LOGGING -#define ASTRA_LOG(id) __FILE__, __LINE__, id +#define ASTRA_DEBUG(...) astra::CLogger::debug(__FILE__,__LINE__, __VA_ARGS__) +#define ASTRA_INFO(...) astra::CLogger::info(__FILE__,__LINE__, __VA_ARGS__) +#define ASTRA_WARN(...) astra::CLogger::warn(__FILE__,__LINE__, __VA_ARGS__) +#define ASTRA_ERROR(...) astra::CLogger::error(__FILE__,__LINE__, __VA_ARGS__) namespace astra { diff --git a/src/ConeProjectionGeometry3D.cpp b/src/ConeProjectionGeometry3D.cpp index 13f147b..1976901 100644 --- a/src/ConeProjectionGeometry3D.cpp +++ b/src/ConeProjectionGeometry3D.cpp @@ -259,7 +259,7 @@ void CConeProjectionGeometry3D::projectPoint(float32 fX, float32 fY, float32 fZ, // Scale fS to detector plane fU = detectorOffsetXToColIndexFloat( (fS * (m_fOriginSourceDistance + m_fOriginDetectorDistance)) / fD ); - astra::CLogger::debug(__FILE__,__LINE__,"alpha: %f, D: %f, V: %f, S: %f, U: %f", alpha, fD, fV, fS, fU); + ASTRA_DEBUG("alpha: %f, D: %f, V: %f, S: %f, U: %f", alpha, fD, fV, fS, fU); } diff --git a/src/Config.cpp b/src/Config.cpp index 0a85b3c..388cfdf 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -149,7 +149,7 @@ bool ConfigStackCheck::stopParsing() if (!errors.empty()) { ostringstream os; os << "Warning: " << name << ": unused configuration options: " << errors; - astra::CLogger::warn(__FILE__,__LINE__,os.str().c_str()); + ASTRA_WARN(os.str().c_str()); return false; } diff --git a/src/CudaFilteredBackProjectionAlgorithm.cpp b/src/CudaFilteredBackProjectionAlgorithm.cpp index 26b848e..0badc20 100644 --- a/src/CudaFilteredBackProjectionAlgorithm.cpp +++ b/src/CudaFilteredBackProjectionAlgorithm.cpp @@ -485,7 +485,7 @@ E_FBPFILTER CCudaFilteredBackProjectionAlgorithm::_convertStringToFilter(const c } else { - astra::CLogger::error(__FILE__,__LINE__,"Failed to convert \"%s\" into a filter.",_filterType); + ASTRA_ERROR("Failed to convert \"%s\" into a filter.",_filterType); } return output; diff --git a/src/CudaForwardProjectionAlgorithm.cpp b/src/CudaForwardProjectionAlgorithm.cpp index 1ae6b83..19cadd6 100644 --- a/src/CudaForwardProjectionAlgorithm.cpp +++ b/src/CudaForwardProjectionAlgorithm.cpp @@ -106,7 +106,7 @@ bool CCudaForwardProjectionAlgorithm::initialize(const Config& _cfg) id = boost::lexical_cast(node->getContent()); CProjector2D *projector = CProjector2DManager::getSingleton().get(id); if (!dynamic_cast(projector)) { - astra::CLogger::warn(__FILE__,__LINE__,"Warning: non-CUDA Projector2D passed to FP_CUDA"); + ASTRA_WARN("Warning: non-CUDA Projector2D passed to FP_CUDA"); } delete node; } diff --git a/src/CudaForwardProjectionAlgorithm3D.cpp b/src/CudaForwardProjectionAlgorithm3D.cpp index 57e1094..8e6bab5 100644 --- a/src/CudaForwardProjectionAlgorithm3D.cpp +++ b/src/CudaForwardProjectionAlgorithm3D.cpp @@ -267,7 +267,7 @@ void CCudaForwardProjectionAlgorithm3D::run(int) for (int k = 0; k < 2; ++k) { float fU, fV; projgeom->projectPoint(fX[i], fY[j], fZ[k], a, fU, fV); - astra::CLogger::debug(__FILE__,__LINE__,"%3d %c1,%c1,%c1 -> %12f %12f", a, i ? ' ' : '-', j ? ' ' : '-', k ? ' ' : '-', fU, fV); + ASTRA_DEBUG("%3d %c1,%c1,%c1 -> %12f %12f", a, i ? ' ' : '-', j ? ' ' : '-', k ? ' ' : '-', fU, fV); } } #endif diff --git a/src/CudaReconstructionAlgorithm2D.cpp b/src/CudaReconstructionAlgorithm2D.cpp index b434e8a..929f0f1 100644 --- a/src/CudaReconstructionAlgorithm2D.cpp +++ b/src/CudaReconstructionAlgorithm2D.cpp @@ -178,7 +178,7 @@ bool CCudaReconstructionAlgorithm2D::initialize(const Config& _cfg) id = boost::lexical_cast(node->getContent()); CProjector2D *projector = CProjector2DManager::getSingleton().get(id); if (!dynamic_cast(projector)) { - astra::CLogger::warn(__FILE__,__LINE__,"Warning: non-CUDA Projector2D passed"); + ASTRA_WARN("Warning: non-CUDA Projector2D passed"); } delete node; } diff --git a/src/FilteredBackProjectionAlgorithm.cpp b/src/FilteredBackProjectionAlgorithm.cpp index 47315bb..4a8e5ac 100644 --- a/src/FilteredBackProjectionAlgorithm.cpp +++ b/src/FilteredBackProjectionAlgorithm.cpp @@ -135,7 +135,7 @@ bool CFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) for (int i = 0; i < angleCount; i ++) { if (projectionIndex[i] > m_pProjector->getProjectionGeometry()->getProjectionAngleCount() -1 ) { - astra::CLogger::error(__FILE__,__LINE__,"Invalid Projection Index"); + ASTRA_ERROR("Invalid Projection Index"); return false; } else { int orgIndex = (int)projectionIndex[i]; -- cgit v1.2.3 From f21700e00e81538d5510973a51b8ae97fb4a24dd Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Fri, 13 Mar 2015 17:12:42 +0100 Subject: Enable logging to Matlab window using callback function Also introduces a mex initialize function that is called at the first invocation of any mex method. --- build/linux/Makefile.in | 1 + include/astra/Logging.h | 9 +++++- include/astra/clog.h | 53 ++++++++++++++++++++++++++++++++++ matlab/mex/astra_mex.cpp | 3 ++ matlab/mex/astra_mex_algorithm_c.cpp | 3 ++ matlab/mex/astra_mex_c.cpp | 3 ++ matlab/mex/astra_mex_data2d_c.cpp | 3 ++ matlab/mex/astra_mex_data3d_c.cpp | 3 ++ matlab/mex/astra_mex_log_c.cpp | 3 ++ matlab/mex/astra_mex_matrix_c.cpp | 3 ++ matlab/mex/astra_mex_projector3d_c.cpp | 3 ++ matlab/mex/astra_mex_projector_c.cpp | 3 ++ matlab/mex/mexInitFunctions.cpp | 24 +++++++++++++++ matlab/mex/mexInitFunctions.h | 6 ++++ src/Logging.cpp | 8 +++-- 15 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 matlab/mex/mexInitFunctions.cpp create mode 100644 matlab/mex/mexInitFunctions.h (limited to 'include') diff --git a/build/linux/Makefile.in b/build/linux/Makefile.in index f862114..49220df 100644 --- a/build/linux/Makefile.in +++ b/build/linux/Makefile.in @@ -216,6 +216,7 @@ TEST_OBJECTS=\ MATLAB_CXX_OBJECTS=\ matlab/mex/mexHelpFunctions.o \ matlab/mex/mexCopyDataHelpFunctions.o \ + matlab/mex/mexInitFunctions.o \ matlab/mex/mexDataManagerHelpFunctions.o MATLAB_MEX=\ diff --git a/include/astra/Logging.h b/include/astra/Logging.h index 5695663..e822c24 100644 --- a/include/astra/Logging.h +++ b/include/astra/Logging.h @@ -75,7 +75,7 @@ public: * @param ... * Any additional format arguments. */ - static void debug(const char *sfile, int sline, const char *fmt, ...); + static void debug(const char *sfile, int sline, const char *fmt, ...); static void info(const char *sfile, int sline, const char *fmt, ...); static void warn(const char *sfile, int sline, const char *fmt, ...); static void error(const char *sfile, int sline, const char *fmt, ...); @@ -143,6 +143,13 @@ public: static void disableScreen(); static void disableFile(); + /** + * Set callback function for logging to screen. + * @return whether callback was set succesfully. + * + */ + static bool setCallbackScreen(void (*cb)(const char *msg, size_t len)); + }; } diff --git a/include/astra/clog.h b/include/astra/clog.h index 4d8e39d..3b7e18b 100644 --- a/include/astra/clog.h +++ b/include/astra/clog.h @@ -231,6 +231,32 @@ int clog_set_date_fmt(int id, const char *fmt); */ int clog_set_fmt(int id, const char *fmt); +/** + * Set the callback function. + * + * @param cb + * The new callback function. + * + * @return + * Zero on success, non-zero on failure. + */ +int clog_set_cb(int id, void (*cb)(const char *msg, size_t len)); + +/** + * Set the file descriptor. + * + * @param id + * The identifier of the logger. + * + * @param fd + * The new file descriptor. + * + * @return + * Zero on success, non-zero on failure. + */ +int clog_set_fd(int id, int fd); + + /* * No need to read below this point. */ @@ -257,6 +283,9 @@ struct clog { /* Tracks whether the fd needs to be closed eventually. */ int opened; + + /* Callback function for each log message. */ + void (*cb)(const char *msg, size_t len); }; void _clog_err(const char *fmt, ...); @@ -314,6 +343,7 @@ clog_init_fd(int id, int fd) strcpy(logger->fmt, CLOG_DEFAULT_FORMAT); strcpy(logger->date_fmt, CLOG_DEFAULT_DATE_FORMAT); strcpy(logger->time_fmt, CLOG_DEFAULT_TIME_FORMAT); + logger->cb = NULL; _clog_loggers[id] = logger; return 0; @@ -344,6 +374,16 @@ clog_set_level(int id, enum clog_level level) return 0; } +int +clog_set_fd(int id, int fd) +{ + if (_clog_loggers[id] == NULL) { + return 1; + } + _clog_loggers[id]->fd = fd; + return 0; +} + int clog_set_time_fmt(int id, const char *fmt) { @@ -392,6 +432,18 @@ clog_set_fmt(int id, const char *fmt) return 0; } +int +clog_set_cb(int id, void (*cb)(const char *msg, size_t len)) +{ + struct clog *logger = _clog_loggers[id]; + if (logger == NULL) { + _clog_err("clog_set_cb: No such logger: %d\n", id); + return 1; + } + logger->cb = cb; + return 0; +} + /* Internal functions */ size_t @@ -563,6 +615,7 @@ _clog_log(const char *sfile, int sline, enum clog_level level, return; } result = write(logger->fd, message, strlen(message)); + if (logger->cb) logger->cb(message,strlen(message)); if (result == -1) { _clog_err("Unable to write to log file: %s\n", strerror(errno)); } diff --git a/matlab/mex/astra_mex.cpp b/matlab/mex/astra_mex.cpp index 0eb5662..4bf42dd 100644 --- a/matlab/mex/astra_mex.cpp +++ b/matlab/mex/astra_mex.cpp @@ -28,6 +28,7 @@ $Id$ #include #include "mexHelpFunctions.h" +#include "mexInitFunctions.h" #include "astra/Globals.h" @@ -104,6 +105,8 @@ void mexFunction(int nlhs, mxArray* plhs[], return; } + initASTRAMex(); + // SWITCH (MODE) if (sMode == std::string("version")) { astra_mex_version(nlhs, plhs, nrhs, prhs); diff --git a/matlab/mex/astra_mex_algorithm_c.cpp b/matlab/mex/astra_mex_algorithm_c.cpp index 669af8c..e4afa63 100644 --- a/matlab/mex/astra_mex_algorithm_c.cpp +++ b/matlab/mex/astra_mex_algorithm_c.cpp @@ -32,6 +32,7 @@ $Id$ */ #include #include "mexHelpFunctions.h" +#include "mexInitFunctions.h" #include "astra/Globals.h" #define USE_MATLAB_UNDOCUMENTED @@ -325,6 +326,8 @@ void mexFunction(int nlhs, mxArray* plhs[], return; } + initASTRAMex(); + // SWITCH (MODE) if (sMode == "create") { astra_mex_algorithm_create(nlhs, plhs, nrhs, prhs); diff --git a/matlab/mex/astra_mex_c.cpp b/matlab/mex/astra_mex_c.cpp index 760bd51..4a331f5 100644 --- a/matlab/mex/astra_mex_c.cpp +++ b/matlab/mex/astra_mex_c.cpp @@ -33,6 +33,7 @@ $Id$ #include #include "mexHelpFunctions.h" +#include "mexInitFunctions.h" #include "astra/Globals.h" @@ -128,6 +129,8 @@ void mexFunction(int nlhs, mxArray* plhs[], return; } + initASTRAMex(); + // SWITCH (MODE) if (sMode == std::string("version")) { astra_mex_version(nlhs, plhs, nrhs, prhs); diff --git a/matlab/mex/astra_mex_data2d_c.cpp b/matlab/mex/astra_mex_data2d_c.cpp index 5f79e98..9576896 100644 --- a/matlab/mex/astra_mex_data2d_c.cpp +++ b/matlab/mex/astra_mex_data2d_c.cpp @@ -32,6 +32,7 @@ $Id$ */ #include #include "mexHelpFunctions.h" +#include "mexInitFunctions.h" #include @@ -635,6 +636,8 @@ void mexFunction(int nlhs, mxArray* plhs[], return; } + initASTRAMex(); + // SWITCH (MODE) if (sMode == std::string("get")) { astra_mex_data2d_get(nlhs, plhs, nrhs, prhs); diff --git a/matlab/mex/astra_mex_data3d_c.cpp b/matlab/mex/astra_mex_data3d_c.cpp index 0a3f85d..32b0ba7 100644 --- a/matlab/mex/astra_mex_data3d_c.cpp +++ b/matlab/mex/astra_mex_data3d_c.cpp @@ -32,6 +32,7 @@ $Id$ */ #include #include "mexHelpFunctions.h" +#include "mexInitFunctions.h" #include "mexCopyDataHelpFunctions.h" #include "mexDataManagerHelpFunctions.h" @@ -371,6 +372,8 @@ void mexFunction(int nlhs, mxArray* plhs[], return; } + initASTRAMex(); + // 3D data if (sMode == std::string("create")) { astra_mex_data3d_create(nlhs, plhs, nrhs, prhs); diff --git a/matlab/mex/astra_mex_log_c.cpp b/matlab/mex/astra_mex_log_c.cpp index 14ae391..79fe3d5 100644 --- a/matlab/mex/astra_mex_log_c.cpp +++ b/matlab/mex/astra_mex_log_c.cpp @@ -32,6 +32,7 @@ $Id$ */ #include #include "mexHelpFunctions.h" +#include "mexInitFunctions.h" #include "astra/Logging.h" @@ -278,6 +279,8 @@ void mexFunction(int nlhs, mxArray* plhs[], return; } + initASTRAMex(); + // SWITCH (MODE) if (sMode == "debug") { astra_mex_log_debug(nlhs, plhs, nrhs, prhs); diff --git a/matlab/mex/astra_mex_matrix_c.cpp b/matlab/mex/astra_mex_matrix_c.cpp index 01ad08b..aa31383 100644 --- a/matlab/mex/astra_mex_matrix_c.cpp +++ b/matlab/mex/astra_mex_matrix_c.cpp @@ -32,6 +32,7 @@ $Id$ */ #include #include "mexHelpFunctions.h" +#include "mexInitFunctions.h" #include @@ -412,6 +413,8 @@ void mexFunction(int nlhs, mxArray* plhs[], return; } + initASTRAMex(); + // SWITCH (MODE) if (sMode == std::string("get")) { astra_mex_matrix_get(nlhs, plhs, nrhs, prhs); diff --git a/matlab/mex/astra_mex_projector3d_c.cpp b/matlab/mex/astra_mex_projector3d_c.cpp index 5381cf6..c3b547f 100644 --- a/matlab/mex/astra_mex_projector3d_c.cpp +++ b/matlab/mex/astra_mex_projector3d_c.cpp @@ -33,6 +33,7 @@ $Id$ #include #include "mexHelpFunctions.h" +#include "mexInitFunctions.h" #include "astra/Globals.h" @@ -403,6 +404,8 @@ void mexFunction(int nlhs, mxArray* plhs[], return; } + initASTRAMex(); + // SWITCH (MODE) if (sMode == "create") { astra_mex_projector3d_create(nlhs, plhs, nrhs, prhs); diff --git a/matlab/mex/astra_mex_projector_c.cpp b/matlab/mex/astra_mex_projector_c.cpp index 58cd953..204ba8e 100644 --- a/matlab/mex/astra_mex_projector_c.cpp +++ b/matlab/mex/astra_mex_projector_c.cpp @@ -34,6 +34,7 @@ $Id$ #include #include "mexHelpFunctions.h" +#include "mexInitFunctions.h" #include "astra/AstraObjectManager.h" #include "astra/Projector2D.h" @@ -476,6 +477,8 @@ void mexFunction(int nlhs, mxArray* plhs[], return; } + initASTRAMex(); + // SWITCH (MODE) if (sMode == "create") { astra_mex_projector_create(nlhs, plhs, nrhs, prhs); diff --git a/matlab/mex/mexInitFunctions.cpp b/matlab/mex/mexInitFunctions.cpp new file mode 100644 index 0000000..d8a50d7 --- /dev/null +++ b/matlab/mex/mexInitFunctions.cpp @@ -0,0 +1,24 @@ +#include +#include "astra/Logging.h" + +bool mexIsInitialized=false; + +/** + * Callback to print log message to Matlab window. + * + */ +void logCallBack(const char *msg, size_t len){ + mexPrintf(msg); +} + +/** + * Initialize mex functions. + * + */ +void initASTRAMex(){ + if(mexIsInitialized) return; + if(!astra::CLogger::setCallbackScreen(&logCallBack)){ + mexErrMsgTxt("Error initializing mex functions."); + } + mexIsInitialized=true; +} diff --git a/matlab/mex/mexInitFunctions.h b/matlab/mex/mexInitFunctions.h new file mode 100644 index 0000000..f16e9c9 --- /dev/null +++ b/matlab/mex/mexInitFunctions.h @@ -0,0 +1,6 @@ +#ifndef _INC_ASTRA_MEX_INITFUNCTIONS +#define _INC_ASTRA_MEX_INITFUNCTIONS + +void initASTRAMex(); + +#endif \ No newline at end of file diff --git a/src/Logging.cpp b/src/Logging.cpp index 9011d37..9d7c219 100644 --- a/src/Logging.cpp +++ b/src/Logging.cpp @@ -124,8 +124,7 @@ void CLogger::_setLevel(int id, log_level m_eLevel) void CLogger::setOutputScreen(int fd, log_level m_eLevel) { _assureIsInitialized(); - clog_free(0); - clog_init_fd(0, fd); + clog_set_fd(0, fd); _setLevel(0,m_eLevel); } @@ -169,6 +168,11 @@ CLogger::CLogger() ; } +bool CLogger::setCallbackScreen(void (*cb)(const char *msg, size_t len)){ + _assureIsInitialized(); + return clog_set_cb(0,cb)==0; +} + bool CLogger::m_bEnabledScreen = true; bool CLogger::m_bEnabledFile = true; bool CLogger::m_bFileProvided = false; -- cgit v1.2.3 From 35fadf8641b05d357a37e8098b9a801ba0e815b9 Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Fri, 13 Mar 2015 17:22:41 +0100 Subject: Use a less verbose default fmt for screen logging and cleaner messages --- include/astra/clog.h | 8 ++++---- src/Config.cpp | 2 +- src/CudaForwardProjectionAlgorithm.cpp | 2 +- src/CudaReconstructionAlgorithm2D.cpp | 2 +- src/Logging.cpp | 1 + 5 files changed, 8 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/astra/clog.h b/include/astra/clog.h index 3b7e18b..ce082df 100644 --- a/include/astra/clog.h +++ b/include/astra/clog.h @@ -299,10 +299,10 @@ extern struct clog *_clog_loggers[CLOG_MAX_LOGGERS]; #ifdef CLOG_MAIN const char *const CLOG_LEVEL_NAMES[] = { - "DEBUG", - "INFO", - "WARN", - "ERROR", + "Debug", + "Info", + "Warning", + "Error", }; int diff --git a/src/Config.cpp b/src/Config.cpp index 388cfdf..d860638 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -148,7 +148,7 @@ bool ConfigStackCheck::stopParsing() if (!errors.empty()) { ostringstream os; - os << "Warning: " << name << ": unused configuration options: " << errors; + os << name << ": unused configuration options: " << errors; ASTRA_WARN(os.str().c_str()); return false; } diff --git a/src/CudaForwardProjectionAlgorithm.cpp b/src/CudaForwardProjectionAlgorithm.cpp index 19cadd6..95abb62 100644 --- a/src/CudaForwardProjectionAlgorithm.cpp +++ b/src/CudaForwardProjectionAlgorithm.cpp @@ -106,7 +106,7 @@ bool CCudaForwardProjectionAlgorithm::initialize(const Config& _cfg) id = boost::lexical_cast(node->getContent()); CProjector2D *projector = CProjector2DManager::getSingleton().get(id); if (!dynamic_cast(projector)) { - ASTRA_WARN("Warning: non-CUDA Projector2D passed to FP_CUDA"); + ASTRA_WARN("non-CUDA Projector2D passed to FP_CUDA"); } delete node; } diff --git a/src/CudaReconstructionAlgorithm2D.cpp b/src/CudaReconstructionAlgorithm2D.cpp index 929f0f1..1c6b763 100644 --- a/src/CudaReconstructionAlgorithm2D.cpp +++ b/src/CudaReconstructionAlgorithm2D.cpp @@ -178,7 +178,7 @@ bool CCudaReconstructionAlgorithm2D::initialize(const Config& _cfg) id = boost::lexical_cast(node->getContent()); CProjector2D *projector = CProjector2DManager::getSingleton().get(id); if (!dynamic_cast(projector)) { - ASTRA_WARN("Warning: non-CUDA Projector2D passed"); + ASTRA_WARN("non-CUDA Projector2D passed"); } delete node; } diff --git a/src/Logging.cpp b/src/Logging.cpp index 9d7c219..f95df0e 100644 --- a/src/Logging.cpp +++ b/src/Logging.cpp @@ -146,6 +146,7 @@ void CLogger::_assureIsInitialized() { clog_init_fd(0, 2); clog_set_level(0, CLOG_INFO); + clog_set_fmt(0, "%l: %m\n"); m_bInitialized = true; } } -- cgit v1.2.3 From d1ad446669cea2a76d7146023e4862a1fdbf3e13 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Thu, 19 Mar 2015 16:47:23 +0100 Subject: Fix windows build --- include/astra/Logging.h | 4 +++- include/astra/clog.h | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/astra/Logging.h b/include/astra/Logging.h index e822c24..8e19ea4 100644 --- a/include/astra/Logging.h +++ b/include/astra/Logging.h @@ -29,6 +29,8 @@ $Id$ #ifndef _INC_ASTRA_LOGGING #define _INC_ASTRA_LOGGING +#include "astra/Globals.h" + #define ASTRA_DEBUG(...) astra::CLogger::debug(__FILE__,__LINE__, __VA_ARGS__) #define ASTRA_INFO(...) astra::CLogger::info(__FILE__,__LINE__, __VA_ARGS__) #define ASTRA_WARN(...) astra::CLogger::warn(__FILE__,__LINE__, __VA_ARGS__) @@ -44,7 +46,7 @@ enum log_level { LOG_ERROR }; -class CLogger +class _AstraExport CLogger { CLogger(); ~CLogger(); diff --git a/include/astra/clog.h b/include/astra/clog.h index ce082df..c0cbae4 100644 --- a/include/astra/clog.h +++ b/include/astra/clog.h @@ -71,7 +71,15 @@ #include #include #include +#ifndef _MSC_VER #include +#else +#include +#define open _open +#define close _close +#define write _write +#define snprintf _snprintf +#endif /* Number of loggers that can be defined. */ #define CLOG_MAX_LOGGERS 16 @@ -625,7 +633,10 @@ _clog_log(const char *sfile, int sline, enum clog_level level, if (dynbuf != buf) { free(dynbuf); } +#ifndef _MSC_VER + // FIXME fsync(logger->fd); +#endif } } -- cgit v1.2.3 From 9ba78fcfa3dec88928df33be26821e3fd5a10727 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Fri, 20 Mar 2015 14:57:59 +0100 Subject: Use FlushFileBuffers in Windows --- include/astra/clog.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/astra/clog.h b/include/astra/clog.h index c0cbae4..6ffb660 100644 --- a/include/astra/clog.h +++ b/include/astra/clog.h @@ -74,6 +74,8 @@ #ifndef _MSC_VER #include #else +#define WIN32_LEAN_AND_MEAN +#include #include #define open _open #define close _close @@ -634,8 +636,13 @@ _clog_log(const char *sfile, int sline, enum clog_level level, free(dynbuf); } #ifndef _MSC_VER - // FIXME fsync(logger->fd); +#else + HANDLE h = (HANDLE) _get_osfhandle(logger->fd); + if (h != INVALID_HANDLE_VALUE) { + // This call will fail on a console fd, but that's ok. + FlushFileBuffers(h); + } #endif } } -- cgit v1.2.3 From 1b32573046f33050b9300324e6c74e10abb6caaf Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Thu, 9 Apr 2015 15:44:01 +0200 Subject: Add 'link' feature to Python (for 2D and 3D data) --- include/astra/Float32ProjectionData2D.h | 25 +++++++++++++++++++++++++ include/astra/Float32VolumeData2D.h | 25 +++++++++++++++++++++++++ python/astra/CFloat32CustomPython.h | 17 +++++++++++++++++ python/astra/PyIncludes.pxd | 8 ++++++++ python/astra/data2d.py | 21 +++++++++++++++++++++ python/astra/data2d_c.pyx | 21 +++++++++++++++++---- python/astra/data3d.py | 22 ++++++++++++++++++++++ python/astra/data3d_c.pyx | 27 ++++++++++++++++++++++----- src/Float32ProjectionData2D.cpp | 19 +++++++++++++++++++ src/Float32VolumeData2D.cpp | 20 ++++++++++++++++++++ 10 files changed, 196 insertions(+), 9 deletions(-) create mode 100644 python/astra/CFloat32CustomPython.h (limited to 'include') diff --git a/include/astra/Float32ProjectionData2D.h b/include/astra/Float32ProjectionData2D.h index 7461491..bb99f4b 100644 --- a/include/astra/Float32ProjectionData2D.h +++ b/include/astra/Float32ProjectionData2D.h @@ -101,6 +101,19 @@ public: * Copy constructor */ CFloat32ProjectionData2D(const CFloat32ProjectionData2D& _other); + + /** Constructor. Create an instance of the CFloat32ProjectionData2D class with pre-allocated memory. + * + * Creates an instance of the CFloat32ProjectionData2D class. Memory + * is pre-allocated and passed via the abstract CFloat32CustomMemory handle + * class. The handle will be deleted when the memory can be freed. + * You should override the destructor to provide custom behaviour on free. + * + * @param _pGeometry Projection Geometry object. This object will be HARDCOPIED into this class. + * @param _pCustomMemory custom memory handle + * + */ + CFloat32ProjectionData2D(CProjectionGeometry2D* _pGeometry, CFloat32CustomMemory* _pCustomMemory); /** * Assignment operator @@ -148,6 +161,18 @@ public: * @param _fScalar scalar value to be put at each index. */ bool initialize(CProjectionGeometry2D* _pGeometry, float32 _fScalar); + + /** Initialization. Initializes an instance of the CFloat32ProjectionData2D class with pre-allocated memory. + * + * Memory is pre-allocated and passed via the abstract CFloat32CustomMemory handle + * class. The handle will be deleted when the memory can be freed. + * You should override the destructor to provide custom behaviour on free. + * + * @param _pGeometry Projection Geometry object. This object will be HARDCOPIED into this class. + * @param _pCustomMemory custom memory handle + * + */ + bool initialize(CProjectionGeometry2D* _pGeometry, CFloat32CustomMemory* _pCustomMemory); /** Get the number of detectors. * diff --git a/include/astra/Float32VolumeData2D.h b/include/astra/Float32VolumeData2D.h index 4f44a8c..abecebf 100644 --- a/include/astra/Float32VolumeData2D.h +++ b/include/astra/Float32VolumeData2D.h @@ -92,6 +92,19 @@ public: * Copy constructor */ CFloat32VolumeData2D(const CFloat32VolumeData2D& _other); + + /** Constructor. Create an instance of the CFloat32VolumeData2D class with pre-allocated memory. + * + * Creates an instance of the CFloat32VolumeData2D class. Memory + * is pre-allocated and passed via the abstract CFloat32CustomMemory handle + * class. The handle will be deleted when the memory can be freed. + * You should override the destructor to provide custom behaviour on free. + * + * @param _pGeometry Volume Geometry object. This object will be HARDCOPIED into this class. + * @param _pCustomMemory custom memory handle + * + */ + CFloat32VolumeData2D(CVolumeGeometry2D* _pGeometry, CFloat32CustomMemory* _pCustomMemory); /** * Assignment operator @@ -132,6 +145,18 @@ public: * @param _fScalar scalar value to be put at each index. */ bool initialize(CVolumeGeometry2D* _pGeometry, float32 _fScalar); + + /** Initialization. Initializes an instance of the CFloat32VolumeData2D class with pre-allocated memory. + * + * Memory is pre-allocated and passed via the abstract CFloat32CustomMemory handle + * class. The handle will be deleted when the memory can be freed. + * You should override the destructor to provide custom behaviour on free. + * + * @param _pGeometry Volume Geometry object. This object will be HARDCOPIED into this class. + * @param _pCustomMemory custom memory handle + * + */ + bool initialize(CVolumeGeometry2D* _pGeometry, CFloat32CustomMemory* _pCustomMemory); /** Destructor. */ diff --git a/python/astra/CFloat32CustomPython.h b/python/astra/CFloat32CustomPython.h new file mode 100644 index 0000000..d8593fc --- /dev/null +++ b/python/astra/CFloat32CustomPython.h @@ -0,0 +1,17 @@ +class CFloat32CustomPython : public astra::CFloat32CustomMemory { +public: + CFloat32CustomPython(PyObject * arrIn) + { + arr = arrIn; + // Set pointer to numpy data pointer + m_fPtr = (float *)PyArray_DATA(arr); + // Increase reference count since ASTRA has a reference + Py_INCREF(arr); + } + virtual ~CFloat32CustomPython() { + // Decrease reference count since ASTRA object is destroyed + Py_DECREF(arr); + } +private: + PyObject* arr; +}; \ No newline at end of file diff --git a/python/astra/PyIncludes.pxd b/python/astra/PyIncludes.pxd index 7df02c5..13329d1 100644 --- a/python/astra/PyIncludes.pxd +++ b/python/astra/PyIncludes.pxd @@ -63,10 +63,14 @@ cdef extern from "astra/VolumeGeometry2D.h" namespace "astra": float32 getWindowMaxY() Config* getConfiguration() +cdef extern from "astra/Float32Data2D.h" namespace "astra": + cdef cppclass CFloat32CustomMemory: + pass cdef extern from "astra/Float32VolumeData2D.h" namespace "astra": cdef cppclass CFloat32VolumeData2D: CFloat32VolumeData2D(CVolumeGeometry2D*) + CFloat32VolumeData2D(CVolumeGeometry2D*, CFloat32CustomMemory*) CVolumeGeometry2D * getGeometry() int getWidth() int getHeight() @@ -130,6 +134,7 @@ cdef extern from "astra/ParallelProjectionGeometry2D.h" namespace "astra": cdef extern from "astra/Float32ProjectionData2D.h" namespace "astra": cdef cppclass CFloat32ProjectionData2D: CFloat32ProjectionData2D(CProjectionGeometry2D*) + CFloat32ProjectionData2D(CProjectionGeometry2D*, CFloat32CustomMemory*) CProjectionGeometry2D * getGeometry() void changeGeometry(CProjectionGeometry2D*) int getDetectorCount() @@ -207,6 +212,7 @@ cdef extern from "astra/ProjectionGeometry3D.h" namespace "astra": cdef extern from "astra/Float32VolumeData3DMemory.h" namespace "astra": cdef cppclass CFloat32VolumeData3DMemory: CFloat32VolumeData3DMemory(CVolumeGeometry3D*) + CFloat32VolumeData3DMemory(CVolumeGeometry3D*, CFloat32CustomMemory*) CVolumeGeometry3D* getGeometry() @@ -231,6 +237,8 @@ cdef extern from "astra/Float32ProjectionData3DMemory.h" namespace "astra": cdef cppclass CFloat32ProjectionData3DMemory: CFloat32ProjectionData3DMemory(CProjectionGeometry3D*) CFloat32ProjectionData3DMemory(CConeProjectionGeometry3D*) + CFloat32ProjectionData3DMemory(CProjectionGeometry3D*, CFloat32CustomMemory*) + CFloat32ProjectionData3DMemory(CConeProjectionGeometry3D*, CFloat32CustomMemory*) CProjectionGeometry3D* getGeometry() cdef extern from "astra/Float32Data3D.h" namespace "astra": diff --git a/python/astra/data2d.py b/python/astra/data2d.py index 8c4be03..f119f05 100644 --- a/python/astra/data2d.py +++ b/python/astra/data2d.py @@ -24,6 +24,7 @@ # #----------------------------------------------------------------------- from . import data2d_c as d +import numpy as np def clear(): """Clear all 2D data objects.""" @@ -52,6 +53,26 @@ def create(datatype, geometry, data=None): """ return d.create(datatype,geometry,data) +def link(datatype, geometry, data): + """Link a 2D numpy array with the toolbox. + + :param datatype: Data object type, '-vol' or '-sino'. + :type datatype: :class:`string` + :param geometry: Volume or projection geometry. + :type geometry: :class:`dict` + :param data: Numpy array to link + :type data: :class:`numpy.ndarray` + :returns: :class:`int` -- the ID of the constructed object. + + """ + if not isinstance(data,np.ndarray): + raise ValueError("Input should be a numpy array") + if not data.dtype==np.float32: + raise ValueError("Numpy array should be float32") + if not (data.flags['C_CONTIGUOUS'] and data.flags['ALIGNED']): + raise ValueError("Numpy array should be C_CONTIGUOUS and ALIGNED") + return d.create(datatype,geometry,data,True) + def store(i, data): """Fill existing 2D object with data. diff --git a/python/astra/data2d_c.pyx b/python/astra/data2d_c.pyx index b9c105e..ac54898 100644 --- a/python/astra/data2d_c.pyx +++ b/python/astra/data2d_c.pyx @@ -49,6 +49,10 @@ from .utils import wrap_from_bytes cdef CData2DManager * man2d = PyData2DManager.getSingletonPtr() +cdef extern from "CFloat32CustomPython.h": + cdef cppclass CFloat32CustomPython: + CFloat32CustomPython(arrIn) + def clear(): man2d.clear() @@ -61,11 +65,12 @@ def delete(ids): man2d.remove(ids) -def create(datatype, geometry, data=None): +def create(datatype, geometry, data=None, link=False): cdef Config *cfg cdef CVolumeGeometry2D * pGeometry cdef CProjectionGeometry2D * ppGeometry cdef CFloat32Data2D * pDataObject2D + cdef CFloat32CustomMemory * pCustom if datatype == '-vol': cfg = utils.dictToConfig(six.b('VolumeGeometry'), geometry) pGeometry = new CVolumeGeometry2D() @@ -73,7 +78,11 @@ def create(datatype, geometry, data=None): del cfg del pGeometry raise Exception('Geometry class not initialized.') - pDataObject2D = new CFloat32VolumeData2D(pGeometry) + if link: + pCustom = new CFloat32CustomPython(data) + pDataObject2D = new CFloat32VolumeData2D(pGeometry, pCustom) + else: + pDataObject2D = new CFloat32VolumeData2D(pGeometry) del cfg del pGeometry elif datatype == '-sino': @@ -91,7 +100,11 @@ def create(datatype, geometry, data=None): del cfg del ppGeometry raise Exception('Geometry class not initialized.') - pDataObject2D = new CFloat32ProjectionData2D(ppGeometry) + if link: + pCustom = new CFloat32CustomPython(data) + pDataObject2D = new CFloat32ProjectionData2D(ppGeometry, pCustom) + else: + pDataObject2D = new CFloat32ProjectionData2D(ppGeometry) del ppGeometry del cfg else: @@ -101,7 +114,7 @@ def create(datatype, geometry, data=None): del pDataObject2D raise Exception("Couldn't initialize data object.") - fillDataObject(pDataObject2D, data) + if not link: fillDataObject(pDataObject2D, data) return man2d.store(pDataObject2D) diff --git a/python/astra/data3d.py b/python/astra/data3d.py index a2e9201..4fdf9d7 100644 --- a/python/astra/data3d.py +++ b/python/astra/data3d.py @@ -24,6 +24,7 @@ # #----------------------------------------------------------------------- from . import data3d_c as d +import numpy as np def create(datatype,geometry,data=None): """Create a 3D object. @@ -39,6 +40,27 @@ def create(datatype,geometry,data=None): """ return d.create(datatype,geometry,data) +def link(datatype, geometry, data): + """Link a 3D numpy array with the toolbox. + + :param datatype: Data object type, '-vol' or '-sino'. + :type datatype: :class:`string` + :param geometry: Volume or projection geometry. + :type geometry: :class:`dict` + :param data: Numpy array to link + :type data: :class:`numpy.ndarray` + :returns: :class:`int` -- the ID of the constructed object. + + """ + if not isinstance(data,np.ndarray): + raise ValueError("Input should be a numpy array") + if not data.dtype==np.float32: + raise ValueError("Numpy array should be float32") + if not (data.flags['C_CONTIGUOUS'] and data.flags['ALIGNED']): + raise ValueError("Numpy array should be C_CONTIGUOUS and ALIGNED") + return d.create(datatype,geometry,data,True) + + def get(i): """Get a 3D object. diff --git a/python/astra/data3d_c.pyx b/python/astra/data3d_c.pyx index 4b069f7..f2c6e26 100644 --- a/python/astra/data3d_c.pyx +++ b/python/astra/data3d_c.pyx @@ -50,12 +50,17 @@ cdef CData3DManager * man3d = PyData3DManager.getSingletonPtr cdef extern from *: CFloat32Data3DMemory * dynamic_cast_mem "dynamic_cast" (CFloat32Data3D * ) except NULL -def create(datatype,geometry,data=None): +cdef extern from "CFloat32CustomPython.h": + cdef cppclass CFloat32CustomPython: + CFloat32CustomPython(arrIn) + +def create(datatype,geometry,data=None, link=False): cdef Config *cfg cdef CVolumeGeometry3D * pGeometry cdef CProjectionGeometry3D * ppGeometry cdef CFloat32Data3DMemory * pDataObject3D cdef CConeProjectionGeometry3D* pppGeometry + cdef CFloat32CustomMemory * pCustom if datatype == '-vol': cfg = utils.dictToConfig(six.b('VolumeGeometry'), geometry) pGeometry = new CVolumeGeometry3D() @@ -63,7 +68,11 @@ def create(datatype,geometry,data=None): del cfg del pGeometry raise Exception('Geometry class not initialized.') - pDataObject3D = new CFloat32VolumeData3DMemory(pGeometry) + if link: + pCustom = new CFloat32CustomPython(data) + pDataObject3D = new CFloat32VolumeData3DMemory(pGeometry, pCustom) + else: + pDataObject3D = new CFloat32VolumeData3DMemory(pGeometry) del cfg del pGeometry elif datatype == '-sino' or datatype == '-proj3d': @@ -84,7 +93,11 @@ def create(datatype,geometry,data=None): del cfg del ppGeometry raise Exception('Geometry class not initialized.') - pDataObject3D = new CFloat32ProjectionData3DMemory(ppGeometry) + if link: + pCustom = new CFloat32CustomPython(data) + pDataObject3D = new CFloat32ProjectionData3DMemory(ppGeometry, pCustom) + else: + pDataObject3D = new CFloat32ProjectionData3DMemory(ppGeometry) del ppGeometry del cfg elif datatype == "-sinocone": @@ -94,7 +107,11 @@ def create(datatype,geometry,data=None): del cfg del pppGeometry raise Exception('Geometry class not initialized.') - pDataObject3D = new CFloat32ProjectionData3DMemory(pppGeometry) + if link: + pCustom = new CFloat32CustomPython(data) + pDataObject3D = new CFloat32ProjectionData3DMemory(pppGeometry, pCustom) + else: + pDataObject3D = new CFloat32ProjectionData3DMemory(pppGeometry) else: raise Exception("Invalid datatype. Please specify '-vol' or '-proj3d'.") @@ -102,7 +119,7 @@ def create(datatype,geometry,data=None): del pDataObject3D raise Exception("Couldn't initialize data object.") - fillDataObject(pDataObject3D, data) + if not link: fillDataObject(pDataObject3D, data) pDataObject3D.updateStatistics() diff --git a/src/Float32ProjectionData2D.cpp b/src/Float32ProjectionData2D.cpp index 85e0cdd..f7f83e3 100644 --- a/src/Float32ProjectionData2D.cpp +++ b/src/Float32ProjectionData2D.cpp @@ -75,6 +75,16 @@ CFloat32ProjectionData2D::CFloat32ProjectionData2D(const CFloat32ProjectionData2 m_bInitialized = true; } +//---------------------------------------------------------------------------------------- +// Create an instance of the CFloat32ProjectionData2D class with pre-allocated data +CFloat32ProjectionData2D::CFloat32ProjectionData2D(CProjectionGeometry2D* _pGeometry, CFloat32CustomMemory* _pCustomMemory) +{ + m_bInitialized = false; + m_bInitialized = initialize(_pGeometry, _pCustomMemory); +} + + + // Assignment operator CFloat32ProjectionData2D& CFloat32ProjectionData2D::operator=(const CFloat32ProjectionData2D& _other) @@ -118,6 +128,15 @@ bool CFloat32ProjectionData2D::initialize(CProjectionGeometry2D* _pGeometry, flo return m_bInitialized; } +//---------------------------------------------------------------------------------------- +// Initialization +bool CFloat32ProjectionData2D::initialize(CProjectionGeometry2D* _pGeometry, CFloat32CustomMemory* _pCustomMemory) +{ + m_pGeometry = _pGeometry->clone(); + m_bInitialized = _initialize(m_pGeometry->getDetectorCount(), m_pGeometry->getProjectionAngleCount(), _pCustomMemory); + return m_bInitialized; +} + //---------------------------------------------------------------------------------------- // Destructor CFloat32ProjectionData2D::~CFloat32ProjectionData2D() diff --git a/src/Float32VolumeData2D.cpp b/src/Float32VolumeData2D.cpp index e11c4e4..c903c66 100644 --- a/src/Float32VolumeData2D.cpp +++ b/src/Float32VolumeData2D.cpp @@ -72,6 +72,15 @@ CFloat32VolumeData2D::CFloat32VolumeData2D(const CFloat32VolumeData2D& _other) : m_bInitialized = true; } +//---------------------------------------------------------------------------------------- +// Create an instance of the CFloat32VolumeData2D class with pre-allocated data +CFloat32VolumeData2D::CFloat32VolumeData2D(CVolumeGeometry2D* _pGeometry, CFloat32CustomMemory* _pCustomMemory) +{ + m_bInitialized = false; + m_bInitialized = initialize(_pGeometry, _pCustomMemory); +} + + // Assignment operator CFloat32VolumeData2D& CFloat32VolumeData2D::operator=(const CFloat32VolumeData2D& _other) @@ -122,6 +131,17 @@ bool CFloat32VolumeData2D::initialize(CVolumeGeometry2D* _pGeometry, float32 _fS m_bInitialized = _initialize(m_pGeometry->getGridColCount(), m_pGeometry->getGridRowCount(), _fScalar); return m_bInitialized; } + +//---------------------------------------------------------------------------------------- +// Initialization +bool CFloat32VolumeData2D::initialize(CVolumeGeometry2D* _pGeometry, CFloat32CustomMemory* _pCustomMemory) +{ + m_pGeometry = _pGeometry->clone(); + m_bInitialized = _initialize(m_pGeometry->getGridColCount(), m_pGeometry->getGridRowCount(), _pCustomMemory); + return m_bInitialized; +} + + //---------------------------------------------------------------------------------------- void CFloat32VolumeData2D::changeGeometry(CVolumeGeometry2D* _pGeometry) { -- cgit v1.2.3 From 7b55ee5f60c5f5865726cf48636b642cd9de111d Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Fri, 10 Apr 2015 12:29:22 +0200 Subject: Add changeGeometry function to Data3D classes --- include/astra/Float32ProjectionData3D.h | 5 +++++ include/astra/Float32VolumeData3D.h | 5 +++++ src/Float32ProjectionData3D.cpp | 9 +++++++++ src/Float32VolumeData3D.cpp | 9 +++++++++ 4 files changed, 28 insertions(+) (limited to 'include') diff --git a/include/astra/Float32ProjectionData3D.h b/include/astra/Float32ProjectionData3D.h index 79b762e..329c9a4 100644 --- a/include/astra/Float32ProjectionData3D.h +++ b/include/astra/Float32ProjectionData3D.h @@ -196,6 +196,11 @@ public: * @return pointer to projection geometry. */ virtual CProjectionGeometry3D* getGeometry() const; + + /** Change the projection geometry. + * Note that this can't change the dimensions of the data. + */ + virtual void changeGeometry(CProjectionGeometry3D* pGeometry); }; diff --git a/include/astra/Float32VolumeData3D.h b/include/astra/Float32VolumeData3D.h index d8f0ae9..07df78f 100644 --- a/include/astra/Float32VolumeData3D.h +++ b/include/astra/Float32VolumeData3D.h @@ -214,6 +214,11 @@ public: * @return The geometry describing the data stored in this volume */ virtual CVolumeGeometry3D* getGeometry() const; + + /** Change the projection geometry. + * Note that this can't change the dimensions of the data. + */ + virtual void changeGeometry(CVolumeGeometry3D* pGeometry); }; //---------------------------------------------------------------------------------------- diff --git a/src/Float32ProjectionData3D.cpp b/src/Float32ProjectionData3D.cpp index d039c83..2bd0447 100644 --- a/src/Float32ProjectionData3D.cpp +++ b/src/Float32ProjectionData3D.cpp @@ -270,4 +270,13 @@ CFloat32ProjectionData3D& CFloat32ProjectionData3D::operator-=(const float32& _f return *this; } +void CFloat32ProjectionData3D::changeGeometry(CProjectionGeometry3D* _pGeometry) +{ + if (!m_bInitialized) return; + + delete m_pGeometry; + m_pGeometry = _pGeometry->clone(); +} + + } // end namespace astra diff --git a/src/Float32VolumeData3D.cpp b/src/Float32VolumeData3D.cpp index ce00a10..bd78001 100644 --- a/src/Float32VolumeData3D.cpp +++ b/src/Float32VolumeData3D.cpp @@ -266,4 +266,13 @@ CFloat32VolumeData3D& CFloat32VolumeData3D::operator-=(const float32& _fScalar) return *this; } +void CFloat32VolumeData3D::changeGeometry(CVolumeGeometry3D* _pGeometry) +{ + if (!m_bInitialized) return; + + delete m_pGeometry; + m_pGeometry = _pGeometry->clone(); +} + + } // end namespace astra -- cgit v1.2.3 From bf31003d74f538a9096ef5999b31b0daa58c38c9 Mon Sep 17 00:00:00 2001 From: Jeroen Bédorf Date: Thu, 2 Apr 2015 12:04:31 +0200 Subject: Fix memory leak in the config --- include/astra/Config.h | 2 ++ src/Config.cpp | 5 +++++ 2 files changed, 7 insertions(+) (limited to 'include') diff --git a/include/astra/Config.h b/include/astra/Config.h index 9893c90..0230dbe 100644 --- a/include/astra/Config.h +++ b/include/astra/Config.h @@ -51,6 +51,8 @@ struct _AstraExport Config { XMLNode* self; XMLNode* global; + + XMLDocument *_doc; }; struct ConfigCheckData { diff --git a/src/Config.cpp b/src/Config.cpp index d860638..32e5ed9 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -48,6 +48,7 @@ using namespace std; Config::Config() { self = 0; + _doc = 0; } //----------------------------------------------------------------------------- @@ -55,6 +56,7 @@ Config::Config() Config::Config(XMLNode* _self) { self = _self; + _doc = 0; } //----------------------------------------------------------------------------- @@ -62,6 +64,8 @@ Config::~Config() { delete self; self = 0; + delete _doc; + _doc = 0; } //----------------------------------------------------------------------------- @@ -70,6 +74,7 @@ void Config::initialize(std::string rootname) if (self == 0) { XMLDocument* doc = XMLDocument::createDocument(rootname); self = doc->getRootNode(); + _doc = doc; } } -- cgit v1.2.3 From 47fe3421585302f2101691a685ab99b0e1ad5cfc Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Fri, 1 May 2015 17:48:32 +0200 Subject: Change XMLNode* to XMLNode An XMLNode object is already simply a pointer, so no need to dynamically allocate XMLNodes. --- include/astra/AstraObjectFactory.h | 2 +- include/astra/Config.h | 5 +- include/astra/XMLDocument.h | 2 +- include/astra/XMLNode.h | 59 ++++++----- matlab/mex/astra_mex_algorithm_c.cpp | 2 +- matlab/mex/astra_mex_data2d_c.cpp | 4 +- matlab/mex/astra_mex_data3d_c.cpp | 2 +- matlab/mex/mexDataManagerHelpFunctions.cpp | 2 +- matlab/mex/mexHelpFunctions.cpp | 62 +++++------ matlab/mex/mexHelpFunctions.h | 6 +- python/astra/PyIncludes.pxd | 2 +- python/astra/PyXMLDocument.pxd | 8 +- python/astra/utils.pyx | 29 ++---- src/ArtAlgorithm.cpp | 6 +- src/ConeProjectionGeometry3D.cpp | 26 +++-- src/ConeVecProjectionGeometry3D.cpp | 25 ++--- src/Config.cpp | 19 ++-- src/CudaBackProjectionAlgorithm3D.cpp | 6 +- src/CudaCglsAlgorithm3D.cpp | 6 +- src/CudaDartMaskAlgorithm.cpp | 22 ++-- src/CudaDartMaskAlgorithm3D.cpp | 22 ++-- src/CudaDartSmoothingAlgorithm.cpp | 20 ++-- src/CudaDartSmoothingAlgorithm3D.cpp | 20 ++-- src/CudaDataOperationAlgorithm.cpp | 25 ++--- src/CudaFDKAlgorithm3D.cpp | 6 +- src/CudaFilteredBackProjectionAlgorithm.cpp | 44 ++++---- src/CudaForwardProjectionAlgorithm.cpp | 23 ++--- src/CudaForwardProjectionAlgorithm3D.cpp | 21 ++-- src/CudaProjector2D.cpp | 5 +- src/CudaProjector3D.cpp | 5 +- src/CudaReconstructionAlgorithm2D.cpp | 49 +++++---- src/CudaRoiSelectAlgorithm.cpp | 13 ++- src/CudaSartAlgorithm.cpp | 4 +- src/CudaSirtAlgorithm.cpp | 8 +- src/CudaSirtAlgorithm3D.cpp | 6 +- src/FanFlatProjectionGeometry2D.cpp | 22 ++-- src/FanFlatVecProjectionGeometry2D.cpp | 18 ++-- src/FilteredBackProjectionAlgorithm.cpp | 20 ++-- src/ForwardProjectionAlgorithm.cpp | 23 ++--- src/ParallelBeamBlobKernelProjector2D.cpp | 22 ++-- src/ParallelProjectionGeometry2D.cpp | 8 +- src/ParallelProjectionGeometry3D.cpp | 12 +-- src/ParallelVecProjectionGeometry3D.cpp | 25 ++--- src/ProjectionGeometry2D.cpp | 17 ++- src/ProjectionGeometry3D.cpp | 25 ++--- src/Projector2D.cpp | 6 +- src/Projector3D.cpp | 8 +- src/ReconstructionAlgorithm2D.cpp | 39 ++++--- src/ReconstructionAlgorithm3D.cpp | 36 +++---- src/SartAlgorithm.cpp | 4 +- src/SparseMatrixProjectionGeometry2D.cpp | 15 ++- src/VolumeGeometry2D.cpp | 30 +++--- src/VolumeGeometry3D.cpp | 45 ++++---- src/XMLDocument.cpp | 5 +- src/XMLNode.cpp | 155 ++++++++++++---------------- tests/test_XMLDocument.cpp | 52 ++++------ 56 files changed, 518 insertions(+), 635 deletions(-) (limited to 'include') diff --git a/include/astra/AstraObjectFactory.h b/include/astra/AstraObjectFactory.h index ba4ec11..1ed4955 100644 --- a/include/astra/AstraObjectFactory.h +++ b/include/astra/AstraObjectFactory.h @@ -110,7 +110,7 @@ template T* CAstraObjectFactory::create(const Config& _cfg) { functor_find finder = functor_find(); - finder.tofind = _cfg.self->getAttribute("type"); + finder.tofind = _cfg.self.getAttribute("type"); CreateObject::find(finder); if (finder.res == NULL) return NULL; if (finder.res->initialize(_cfg)) diff --git a/include/astra/Config.h b/include/astra/Config.h index 0230dbe..c10a16e 100644 --- a/include/astra/Config.h +++ b/include/astra/Config.h @@ -44,13 +44,12 @@ namespace astra { struct _AstraExport Config { Config(); - Config(XMLNode* _self); + Config(XMLNode _self); ~Config(); void initialize(std::string rootname); - XMLNode* self; - XMLNode* global; + XMLNode self; XMLDocument *_doc; }; diff --git a/include/astra/XMLDocument.h b/include/astra/XMLDocument.h index 869e1a3..eddd908 100644 --- a/include/astra/XMLDocument.h +++ b/include/astra/XMLDocument.h @@ -78,7 +78,7 @@ public: * * @return first XML node of the document */ - XMLNode* getRootNode(); + XMLNode getRootNode(); /** Save an XML DOM tree to an XML file * diff --git a/include/astra/XMLNode.h b/include/astra/XMLNode.h index eceffe1..f79c1a8 100644 --- a/include/astra/XMLNode.h +++ b/include/astra/XMLNode.h @@ -64,71 +64,74 @@ public: /** Deconstructor */ ~XMLNode(); - + + /** Check validity + */ + operator bool() const { return fDOMElement != 0; } /** Get a single child XML node. If there are more, the first one is returned * * @param _sName tagname of the requested child node * @return first child node with the correct tagname, null pointer if it doesn't exist */ - XMLNode* getSingleNode(string _sName); + XMLNode getSingleNode(string _sName) const; /** Get all child XML nodes that have the tagname name * * @param _sName tagname of the requested child nodes * @return list with all child nodes with the correct tagname */ - std::list getNodes(string _sName); + std::list getNodes(string _sName) const; /** Get all child XML nodes * * @return list with all child nodes */ - std::list getNodes(); + std::list getNodes() const; /** Get the name of this node * * @return name of node */ - std::string getName(); + std::string getName() const; /** Get the content of the XML node as a single string. * * @return node content */ - string getContent(); + string getContent() const; /** Get the content of the XML node as a numerical. * * @return node content */ - float32 getContentNumerical(); + float32 getContentNumerical() const; /** Get the content of the XML node as a boolean. * * @return node content */ - bool getContentBool(); + bool getContentBool() const; /** Get the content of the XML node as a vector of strings. * * @return node content */ - vector getContentArray(); + vector getContentArray() const; /** Get the content of the XML node as a c-array of float32 data. * * @param _pfData data array, shouldn't be initialized already. * @param _iSize number of elements stored in _pfData */ - void getContentNumericalArray(float32*& _pfData, int& _iSize); + void getContentNumericalArray(float32*& _pfData, int& _iSize) const; /** Get the content of the XML node as a stl container of float32 data. * * @return node content */ - vector getContentNumericalArray(); - vector getContentNumericalArrayDouble(); + vector getContentNumericalArray() const; + vector getContentNumericalArrayDouble() const; @@ -137,7 +140,7 @@ public: * @param _sName of the attribute. * @return attribute value, empty string if it doesn't exist. */ - bool hasAttribute(string _sName); + bool hasAttribute(string _sName) const; /** Get the value of an attribute. * @@ -145,7 +148,7 @@ public: * @param _sDefaultValue value to return if the attribute isn't found * @return attribute value, _sDefaultValue if it doesn't exist. */ - string getAttribute(string _sName, string _sDefaultValue = ""); + string getAttribute(string _sName, string _sDefaultValue = "") const; /** Get the value of a numerical attribute. * @@ -153,8 +156,8 @@ public: * @param _fDefaultValue value to return if the attribute isn't found * @return attribute value, _fDefaultValue if it doesn't exist. */ - float32 getAttributeNumerical(string _sName, float32 _fDefaultValue = 0); - double getAttributeNumericalDouble(string _sName, double _fDefaultValue = 0); + float32 getAttributeNumerical(string _sName, float32 _fDefaultValue = 0) const; + double getAttributeNumericalDouble(string _sName, double _fDefaultValue = 0) const; /** Get the value of a boolean attribute. * @@ -162,7 +165,7 @@ public: * @param _bDefaultValue value to return if the attribute isn't found * @return attribute value, _bDefaultValue if it doesn't exist. */ - bool getAttributeBool(string _sName, bool _bDefaultValue = false); + bool getAttributeBool(string _sName, bool _bDefaultValue = false) const; @@ -172,7 +175,7 @@ public: * @param _sKey option key * @return true if option does exist */ - bool hasOption(string _sKey); + bool hasOption(string _sKey) const; /** Get the value of an option within this XML Node * @@ -180,7 +183,7 @@ public: * @param _sDefaultValue value to return if key isn't found * @return option value, _sDefaultValue if the option doesn't exist */ - string getOption(string _sKey, string _sDefaultValue = ""); + string getOption(string _sKey, string _sDefaultValue = "") const; /** Get the value of an option within this XML Node * @@ -188,7 +191,7 @@ public: * @param _fDefaultValue value to return if key isn't found * @return option value, _fDefaultValue if the option doesn't exist */ - float32 getOptionNumerical(string _sKey, float32 _fDefaultValue = 0); + float32 getOptionNumerical(string _sKey, float32 _fDefaultValue = 0) const; /** Get the value of an option within this XML Node * @@ -196,14 +199,14 @@ public: * @param _bDefaultValue value to return if key isn't found * @return option value, _bDefaultValue if the option doesn't exist */ - bool getOptionBool(string _sKey, bool _bDefaultValue = false); + bool getOptionBool(string _sKey, bool _bDefaultValue = false) const; /** Get the value of an option within this XML Node * * @param _sKey option key * @return numerical array */ - vector getOptionNumericalArray(string _sKey); + vector getOptionNumericalArray(string _sKey) const; @@ -214,7 +217,7 @@ public: * @param _sNodeName the name of the new childnode * @return new child node */ - XMLNode* addChildNode(string _sNodeName); + XMLNode addChildNode(string _sNodeName); /** Create a new XML node as a child to this one, also add some content: * <...><_sNodeName>_sValue</_sNodeName></...> @@ -223,7 +226,7 @@ public: * @param _sValue some node content * @return new child node */ - XMLNode* addChildNode(string _sNodeName, string _sValue); + XMLNode addChildNode(string _sNodeName, string _sValue); /** Create a new XML node as a child to this one, also add some numerical content: * <...><_sNodeName>_sValue</_sNodeName></...> @@ -232,7 +235,7 @@ public: * @param _fValue some node content * @return new child node */ - XMLNode* addChildNode(string _sNodeName, float32 _fValue); + XMLNode addChildNode(string _sNodeName, float32 _fValue); /** Create a new XML node as a child to this one, also add a list of numerical content: * <...><_sNodeName>_sValue</_sNodeName></...> @@ -242,7 +245,7 @@ public: * @param _iSize number of elements in _pfList * @return new child node */ - XMLNode* addChildNode(string _sNodeName, float32* _pfList, int _iSize); + XMLNode addChildNode(string _sNodeName, float32* _pfList, int _iSize); /** Add some text to the node: <...>_sText</...> * @@ -294,11 +297,11 @@ public: /** Print to String */ - std::string toString(); + std::string toString() const; /** Print the node */ - void print(); + void print() const; protected: diff --git a/matlab/mex/astra_mex_algorithm_c.cpp b/matlab/mex/astra_mex_algorithm_c.cpp index e4afa63..ec7aa72 100644 --- a/matlab/mex/astra_mex_algorithm_c.cpp +++ b/matlab/mex/astra_mex_algorithm_c.cpp @@ -81,7 +81,7 @@ void astra_mex_algorithm_create(int nlhs, mxArray* plhs[], int nrhs, const mxArr // turn MATLAB struct to an XML-based Config object Config* cfg = structToConfig("Algorithm", prhs[1]); - CAlgorithm* pAlg = CAlgorithmFactory::getSingleton().create(cfg->self->getAttribute("type")); + CAlgorithm* pAlg = CAlgorithmFactory::getSingleton().create(cfg->self.getAttribute("type")); if (!pAlg) { delete cfg; mexErrMsgTxt("Unknown algorithm. \n"); diff --git a/matlab/mex/astra_mex_data2d_c.cpp b/matlab/mex/astra_mex_data2d_c.cpp index 9576896..909d229 100644 --- a/matlab/mex/astra_mex_data2d_c.cpp +++ b/matlab/mex/astra_mex_data2d_c.cpp @@ -149,7 +149,7 @@ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra Config* cfg = structToConfig("ProjectionGeometry", prhs[2]); // FIXME: Change how the base class is created. (This is duplicated // in 'change_geometry' and Projector2D.cpp.) - std::string type = cfg->self->getAttribute("type"); + std::string type = cfg->self.getAttribute("type"); CProjectionGeometry2D* pGeometry; if (type == "sparse_matrix") { pGeometry = new CSparseMatrixProjectionGeometry2D(); @@ -438,7 +438,7 @@ void astra_mex_data2d_change_geometry(int nlhs, mxArray* plhs[], int nrhs, const Config* cfg = structToConfig("ProjectionGeometry2D", prhs[2]); // FIXME: Change how the base class is created. (This is duplicated // in 'create' and Projector2D.cpp.) - std::string type = cfg->self->getAttribute("type"); + std::string type = cfg->self.getAttribute("type"); CProjectionGeometry2D* pGeometry; if (type == "sparse_matrix") { pGeometry = new CSparseMatrixProjectionGeometry2D(); diff --git a/matlab/mex/astra_mex_data3d_c.cpp b/matlab/mex/astra_mex_data3d_c.cpp index 6096adc..fe4ce37 100644 --- a/matlab/mex/astra_mex_data3d_c.cpp +++ b/matlab/mex/astra_mex_data3d_c.cpp @@ -346,7 +346,7 @@ void astra_mex_data3d_change_geometry(int nlhs, mxArray* plhs[], int nrhs, const astra::Config* cfg = structToConfig("ProjectionGeometry3D", geometry); // FIXME: Change how the base class is created. (This is duplicated // in Projector3D.cpp.) - std::string type = cfg->self->getAttribute("type"); + std::string type = cfg->self.getAttribute("type"); astra::CProjectionGeometry3D* pGeometry = 0; if (type == "parallel3d") { pGeometry = new astra::CParallelProjectionGeometry3D(); diff --git a/matlab/mex/mexDataManagerHelpFunctions.cpp b/matlab/mex/mexDataManagerHelpFunctions.cpp index d482428..1794abb 100644 --- a/matlab/mex/mexDataManagerHelpFunctions.cpp +++ b/matlab/mex/mexDataManagerHelpFunctions.cpp @@ -285,7 +285,7 @@ allocateDataObject(const std::string & sDataType, astra::Config* cfg = structToConfig("ProjectionGeometry3D", geometry); // FIXME: Change how the base class is created. (This is duplicated // in Projector3D.cpp.) - std::string type = cfg->self->getAttribute("type"); + std::string type = cfg->self.getAttribute("type"); astra::CProjectionGeometry3D* pGeometry = 0; if (type == "parallel3d") { pGeometry = new astra::CParallelProjectionGeometry3D(); diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp index c0ac711..00d766f 100644 --- a/matlab/mex/mexHelpFunctions.cpp +++ b/matlab/mex/mexHelpFunctions.cpp @@ -185,7 +185,7 @@ Config* structToConfig(string rootname, const mxArray* pStruct) } //----------------------------------------------------------------------------------------- -bool structToXMLNode(XMLNode* node, const mxArray* pStruct) +bool structToXMLNode(XMLNode node, const mxArray* pStruct) { // loop all fields int nfields = mxGetNumberOfFields(pStruct); @@ -199,16 +199,16 @@ bool structToXMLNode(XMLNode* node, const mxArray* pStruct) if (mxIsChar(pField)) { string sValue = mexToString(pField); if (sFieldName == "type") { - node->addAttribute("type", sValue); + node.addAttribute("type", sValue); } else { - delete node->addChildNode(sFieldName, sValue); + node.addChildNode(sFieldName, sValue); } } // scalar else if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) == 1) { string sValue = mexToString(pField); - delete node->addChildNode(sFieldName, sValue); + node.addChildNode(sFieldName, sValue); } // numerical array @@ -217,20 +217,18 @@ bool structToXMLNode(XMLNode* node, const mxArray* pStruct) mexErrMsgTxt("Numeric input must be double."); return false; } - XMLNode* listbase = node->addChildNode(sFieldName); - listbase->addAttribute("listsize", mxGetM(pField)*mxGetN(pField)); + XMLNode listbase = node.addChildNode(sFieldName); + listbase.addAttribute("listsize", mxGetM(pField)*mxGetN(pField)); double* pdValues = mxGetPr(pField); int index = 0; for (unsigned int row = 0; row < mxGetM(pField); row++) { for (unsigned int col = 0; col < mxGetN(pField); col++) { - XMLNode* item = listbase->addChildNode("ListItem"); - item->addAttribute("index", index); - item->addAttribute("value", pdValues[col*mxGetM(pField)+row]); + XMLNode item = listbase.addChildNode("ListItem"); + item.addAttribute("index", index); + item.addAttribute("value", pdValues[col*mxGetM(pField)+row]); index++; - delete item; } } - delete listbase; } // not castable to a single string @@ -240,9 +238,8 @@ bool structToXMLNode(XMLNode* node, const mxArray* pStruct) if (!ret) return false; } else { - XMLNode* newNode = node->addChildNode(sFieldName); + XMLNode newNode = node.addChildNode(sFieldName); bool ret = structToXMLNode(newNode, pField); - delete newNode; if (!ret) return false; } @@ -254,7 +251,7 @@ bool structToXMLNode(XMLNode* node, const mxArray* pStruct) } //----------------------------------------------------------------------------------------- // Options struct to xml node -bool optionsToXMLNode(XMLNode* node, const mxArray* pOptionStruct) +bool optionsToXMLNode(XMLNode node, const mxArray* pOptionStruct) { // loop all fields int nfields = mxGetNumberOfFields(pOptionStruct); @@ -262,7 +259,7 @@ bool optionsToXMLNode(XMLNode* node, const mxArray* pOptionStruct) std::string sFieldName = std::string(mxGetFieldNameByNumber(pOptionStruct, i)); const mxArray* pField = mxGetFieldByNumber(pOptionStruct, 0, i); - if (node->hasOption(sFieldName)) { + if (node.hasOption(sFieldName)) { mexErrMsgTxt("Duplicate option"); return false; } @@ -270,7 +267,7 @@ bool optionsToXMLNode(XMLNode* node, const mxArray* pOptionStruct) // string or scalar if (mxIsChar(pField) || mexIsScalar(pField)) { string sValue = mexToString(pField); - node->addOption(sFieldName, sValue); + node.addOption(sFieldName, sValue); } // numerical array else if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) > 1) { @@ -279,21 +276,19 @@ bool optionsToXMLNode(XMLNode* node, const mxArray* pOptionStruct) return false; } - XMLNode* listbase = node->addChildNode("Option"); - listbase->addAttribute("key", sFieldName); - listbase->addAttribute("listsize", mxGetM(pField)*mxGetN(pField)); + XMLNode listbase = node.addChildNode("Option"); + listbase.addAttribute("key", sFieldName); + listbase.addAttribute("listsize", mxGetM(pField)*mxGetN(pField)); double* pdValues = mxGetPr(pField); int index = 0; for (unsigned int row = 0; row < mxGetM(pField); row++) { for (unsigned int col = 0; col < mxGetN(pField); col++) { - XMLNode* item = listbase->addChildNode("ListItem"); - item->addAttribute("index", index); - item->addAttribute("value", pdValues[col*mxGetM(pField)+row]); + XMLNode item = listbase.addChildNode("ListItem"); + item.addAttribute("index", index); + item.addAttribute("value", pdValues[col*mxGetM(pField)+row]); index++; - delete item; } } - delete listbase; } else { mexErrMsgTxt("Unsupported option type"); return false; @@ -343,30 +338,29 @@ mxArray* configToStruct(astra::Config* cfg) } //----------------------------------------------------------------------------------------- -mxArray* XMLNodeToStruct(astra::XMLNode* node) +mxArray* XMLNodeToStruct(astra::XMLNode node) { std::map mList; std::map mOptions; // type_attribute - if (node->hasAttribute("type")) { - mList["type"] = mxCreateString(node->getAttribute("type").c_str()); + if (node.hasAttribute("type")) { + mList["type"] = mxCreateString(node.getAttribute("type").c_str()); } - list nodes = node->getNodes(); - for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { - XMLNode* subnode = (*it); + list nodes = node.getNodes(); + for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { + XMLNode subnode = (*it); // option - if (subnode->getName() == "Option") { - mOptions[subnode->getAttribute("key")] = stringToMxArray(subnode->getAttribute("value")); + if (subnode.getName() == "Option") { + mOptions[subnode.getAttribute("key")] = stringToMxArray(subnode.getAttribute("value")); } // regular content else { - mList[subnode->getName()] = stringToMxArray(subnode->getContent()); + mList[subnode.getName()] = stringToMxArray(subnode.getContent()); } - delete subnode; } if (mOptions.size() > 0) mList["options"] = buildStruct(mOptions); diff --git a/matlab/mex/mexHelpFunctions.h b/matlab/mex/mexHelpFunctions.h index f9ffcf2..3ac5bd8 100644 --- a/matlab/mex/mexHelpFunctions.h +++ b/matlab/mex/mexHelpFunctions.h @@ -58,13 +58,13 @@ mxArray* anyToMxArray(boost::any _any); // turn a MATLAB struct into a Config object astra::Config* structToConfig(string rootname, const mxArray* pStruct); -bool structToXMLNode(astra::XMLNode* node, const mxArray* pStruct); -bool optionsToXMLNode(astra::XMLNode* node, const mxArray* pOptionStruct); +bool structToXMLNode(astra::XMLNode node, const mxArray* pStruct); +bool optionsToXMLNode(astra::XMLNode node, const mxArray* pOptionStruct); std::map parseStruct(const mxArray* pInput); // turn a Config object into a MATLAB struct mxArray* configToStruct(astra::Config* cfg); -mxArray* XMLNodeToStruct(astra::XMLNode* xml); +mxArray* XMLNodeToStruct(astra::XMLNode xml); mxArray* stringToMxArray(std::string input); mxArray* buildStruct(std::map mInput); diff --git a/python/astra/PyIncludes.pxd b/python/astra/PyIncludes.pxd index 1d8285b..909f58f 100644 --- a/python/astra/PyIncludes.pxd +++ b/python/astra/PyIncludes.pxd @@ -43,7 +43,7 @@ cdef extern from "astra/Config.h" namespace "astra": cdef cppclass Config: Config() void initialize(string rootname) - XMLNode *self + XMLNode self cdef extern from "astra/VolumeGeometry2D.h" namespace "astra": cdef cppclass CVolumeGeometry2D: diff --git a/python/astra/PyXMLDocument.pxd b/python/astra/PyXMLDocument.pxd index 69781f1..57c447e 100644 --- a/python/astra/PyXMLDocument.pxd +++ b/python/astra/PyXMLDocument.pxd @@ -44,14 +44,14 @@ cdef extern from "astra/Globals.h" namespace "astra": cdef extern from "astra/XMLNode.h" namespace "astra": cdef cppclass XMLNode: string getName() - XMLNode *addChildNode(string name) - XMLNode *addChildNode(string, string) + XMLNode addChildNode(string name) + XMLNode addChildNode(string, string) void addAttribute(string, string) void addAttribute(string, float32) void addOption(string, string) bool hasOption(string) string getAttribute(string) - list[XMLNode *] getNodes() + list[XMLNode] getNodes() vector[float32] getContentNumericalArray() string getContent() bool hasAttribute(string) @@ -59,7 +59,7 @@ cdef extern from "astra/XMLNode.h" namespace "astra": cdef extern from "astra/XMLDocument.h" namespace "astra": cdef cppclass XMLDocument: void saveToFile(string sFilename) - XMLNode *getRootNode() + XMLNode getRootNode() cdef extern from "astra/XMLDocument.h" namespace "astra::XMLDocument": cdef XMLDocument *createDocument(string rootname) diff --git a/python/astra/utils.pyx b/python/astra/utils.pyx index 0439f1b..8f1e0b7 100644 --- a/python/astra/utils.pyx +++ b/python/astra/utils.pyx @@ -80,9 +80,9 @@ def wrap_from_bytes(value): return s -cdef void readDict(XMLNode * root, _dc): - cdef XMLNode * listbase - cdef XMLNode * itm +cdef void readDict(XMLNode root, _dc): + cdef XMLNode listbase + cdef XMLNode itm cdef int i cdef int j @@ -102,34 +102,29 @@ cdef void readDict(XMLNode * root, _dc): itm.addAttribute(< string > six.b('index'), < float32 > index) itm.addAttribute( < string > six.b('value'), < float32 > val[i, j]) index += 1 - del itm elif val.ndim == 1: for i in range(val.shape[0]): itm = listbase.addChildNode(six.b('ListItem')) itm.addAttribute(< string > six.b('index'), < float32 > index) itm.addAttribute(< string > six.b('value'), < float32 > val[i]) index += 1 - del itm else: raise Exception("Only 1 or 2 dimensions are allowed") - del listbase elif isinstance(val, dict): if item == six.b('option') or item == six.b('options') or item == six.b('Option') or item == six.b('Options'): readOptions(root, val) else: itm = root.addChildNode(item) readDict(itm, val) - del itm else: if item == six.b('type'): root.addAttribute(< string > six.b('type'), wrap_to_bytes(val)) else: itm = root.addChildNode(item, wrap_to_bytes(val)) - del itm -cdef void readOptions(XMLNode * node, dc): - cdef XMLNode * listbase - cdef XMLNode * itm +cdef void readOptions(XMLNode node, dc): + cdef XMLNode listbase + cdef XMLNode itm cdef int i cdef int j for item in dc: @@ -150,17 +145,14 @@ cdef void readOptions(XMLNode * node, dc): itm.addAttribute(< string > six.b('index'), < float32 > index) itm.addAttribute( < string > six.b('value'), < float32 > val[i, j]) index += 1 - del itm elif val.ndim == 1: for i in range(val.shape[0]): itm = listbase.addChildNode(six.b('ListItem')) itm.addAttribute(< string > six.b('index'), < float32 > index) itm.addAttribute(< string > six.b('value'), < float32 > val[i]) index += 1 - del itm else: raise Exception("Only 1 or 2 dimensions are allowed") - del listbase else: node.addOption(item, wrap_to_bytes(val)) @@ -214,10 +206,10 @@ def stringToPythonValue(inputIn): return str(input) -cdef XMLNode2dict(XMLNode * node): - cdef XMLNode * subnode - cdef list[XMLNode * ] nodes - cdef list[XMLNode * ].iterator it +cdef XMLNode2dict(XMLNode node): + cdef XMLNode subnode + cdef list[XMLNode] nodes + cdef list[XMLNode].iterator it dct = {} opts = {} if node.hasAttribute(six.b('type')): @@ -230,7 +222,6 @@ cdef XMLNode2dict(XMLNode * node): opts[castString(subnode.getAttribute('key'))] = stringToPythonValue(subnode.getAttribute('value')) else: dct[castString(subnode.getName())] = stringToPythonValue(subnode.getContent()) - del subnode inc(it) if len(opts)>0: dct['options'] = opts return dct diff --git a/src/ArtAlgorithm.cpp b/src/ArtAlgorithm.cpp index 8f058a3..6a699ec 100644 --- a/src/ArtAlgorithm.cpp +++ b/src/ArtAlgorithm.cpp @@ -132,7 +132,7 @@ bool CArtAlgorithm::initialize(const Config& _cfg) } // ray order - string projOrder = _cfg.self->getOption("RayOrder", "sequential"); + string projOrder = _cfg.self.getOption("RayOrder", "sequential"); CC.markOptionParsed("RayOrder"); m_iCurrentRay = 0; m_iRayCount = m_pProjector->getProjectionGeometry()->getProjectionAngleCount() * @@ -145,7 +145,7 @@ bool CArtAlgorithm::initialize(const Config& _cfg) m_piDetectorOrder[i] = i % m_pProjector->getProjectionGeometry()->getDetectorCount(); } } else if (projOrder == "custom") { - vector rayOrderList = _cfg.self->getOptionNumericalArray("RayOrderList"); + vector rayOrderList = _cfg.self.getOptionNumericalArray("RayOrderList"); m_iRayCount = rayOrderList.size() / 2; m_piProjectionOrder = new int[m_iRayCount]; m_piDetectorOrder = new int[m_iRayCount]; @@ -158,7 +158,7 @@ bool CArtAlgorithm::initialize(const Config& _cfg) return false; } - m_fLambda = _cfg.self->getOptionNumerical("Lambda", 1.0f); + m_fLambda = _cfg.self.getOptionNumerical("Lambda", 1.0f); CC.markOptionParsed("Lambda"); // success diff --git a/src/ConeProjectionGeometry3D.cpp b/src/ConeProjectionGeometry3D.cpp index 1976901..dd22eba 100644 --- a/src/ConeProjectionGeometry3D.cpp +++ b/src/ConeProjectionGeometry3D.cpp @@ -87,17 +87,15 @@ bool CConeProjectionGeometry3D::initialize(const Config& _cfg) CProjectionGeometry3D::initialize(_cfg); // Required: DistanceOriginDetector - XMLNode* node = _cfg.self->getSingleNode("DistanceOriginDetector"); + XMLNode node = _cfg.self.getSingleNode("DistanceOriginDetector"); ASTRA_CONFIG_CHECK(node, "ConeProjectionGeometry3D", "No DistanceOriginDetector tag specified."); - m_fOriginDetectorDistance = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_fOriginDetectorDistance = boost::lexical_cast(node.getContent()); CC.markNodeParsed("DistanceOriginDetector"); // Required: DetectorOriginSource - node = _cfg.self->getSingleNode("DistanceOriginSource"); + node = _cfg.self.getSingleNode("DistanceOriginSource"); ASTRA_CONFIG_CHECK(node, "ConeProjectionGeometry3D", "No DistanceOriginSource tag specified."); - m_fOriginSourceDistance = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_fOriginSourceDistance = boost::lexical_cast(node.getContent()); CC.markNodeParsed("DistanceOriginSource"); // success @@ -193,14 +191,14 @@ Config* CConeProjectionGeometry3D::getConfiguration() const { Config* cfg = new Config(); cfg->initialize("ProjectionGeometry3D"); - cfg->self->addAttribute("type", "cone"); - cfg->self->addChildNode("DetectorSpacingX", m_fDetectorSpacingX); - cfg->self->addChildNode("DetectorSpacingY", m_fDetectorSpacingY); - cfg->self->addChildNode("DetectorRowCount", m_iDetectorRowCount); - cfg->self->addChildNode("DetectorColCount", m_iDetectorColCount); - cfg->self->addChildNode("DistanceOriginDetector", m_fOriginDetectorDistance); - cfg->self->addChildNode("DistanceOriginSource", m_fOriginSourceDistance); - cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); + cfg->self.addAttribute("type", "cone"); + cfg->self.addChildNode("DetectorSpacingX", m_fDetectorSpacingX); + cfg->self.addChildNode("DetectorSpacingY", m_fDetectorSpacingY); + cfg->self.addChildNode("DetectorRowCount", m_iDetectorRowCount); + cfg->self.addChildNode("DetectorColCount", m_iDetectorColCount); + cfg->self.addChildNode("DistanceOriginDetector", m_fOriginDetectorDistance); + cfg->self.addChildNode("DistanceOriginSource", m_fOriginSourceDistance); + cfg->self.addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); return cfg; } diff --git a/src/ConeVecProjectionGeometry3D.cpp b/src/ConeVecProjectionGeometry3D.cpp index 9dc273d..47ed630 100644 --- a/src/ConeVecProjectionGeometry3D.cpp +++ b/src/ConeVecProjectionGeometry3D.cpp @@ -73,33 +73,30 @@ bool CConeVecProjectionGeometry3D::initialize(const Config& _cfg) ASTRA_ASSERT(_cfg.self); ConfigStackCheck CC("ConeVecProjectionGeometry3D", this, _cfg); - XMLNode* node; + XMLNode node; // TODO: Fix up class hierarchy... this class doesn't fit very well. // initialization of parent class //CProjectionGeometry3D::initialize(_cfg); // Required: DetectorRowCount - node = _cfg.self->getSingleNode("DetectorRowCount"); + node = _cfg.self.getSingleNode("DetectorRowCount"); ASTRA_CONFIG_CHECK(node, "ConeVecProjectionGeometry3D", "No DetectorRowCount tag specified."); - m_iDetectorRowCount = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_iDetectorRowCount = boost::lexical_cast(node.getContent()); CC.markNodeParsed("DetectorRowCount"); // Required: DetectorColCount - node = _cfg.self->getSingleNode("DetectorColCount"); + node = _cfg.self.getSingleNode("DetectorColCount"); ASTRA_CONFIG_CHECK(node, "ConeVecProjectionGeometry3D", "No DetectorColCount tag specified."); - m_iDetectorColCount = boost::lexical_cast(node->getContent()); + m_iDetectorColCount = boost::lexical_cast(node.getContent()); m_iDetectorTotCount = m_iDetectorRowCount * m_iDetectorColCount; - ASTRA_DELETE(node); CC.markNodeParsed("DetectorColCount"); // Required: Vectors - node = _cfg.self->getSingleNode("Vectors"); + node = _cfg.self.getSingleNode("Vectors"); ASTRA_CONFIG_CHECK(node, "ConeVecProjectionGeometry3D", "No Vectors tag specified."); - vector data = node->getContentNumericalArrayDouble(); + vector data = node.getContentNumericalArrayDouble(); CC.markNodeParsed("Vectors"); - ASTRA_DELETE(node); ASTRA_CONFIG_CHECK(data.size() % 12 == 0, "ConeVecProjectionGeometry3D", "Vectors doesn't consist of 12-tuples."); m_iProjectionAngleCount = data.size() / 12; m_pProjectionAngles = new SConeProjection[m_iProjectionAngleCount]; @@ -208,9 +205,9 @@ Config* CConeVecProjectionGeometry3D::getConfiguration() const Config* cfg = new Config(); cfg->initialize("ProjectionGeometry3D"); - cfg->self->addAttribute("type", "cone_vec"); - cfg->self->addChildNode("DetectorRowCount", m_iDetectorRowCount); - cfg->self->addChildNode("DetectorColCount", m_iDetectorColCount); + cfg->self.addAttribute("type", "cone_vec"); + cfg->self.addChildNode("DetectorRowCount", m_iDetectorRowCount); + cfg->self.addChildNode("DetectorColCount", m_iDetectorColCount); std::string vectors = ""; for (int i = 0; i < m_iProjectionAngleCount; ++i) { @@ -229,7 +226,7 @@ Config* CConeVecProjectionGeometry3D::getConfiguration() const vectors += boost::lexical_cast(p.fDetVZ); if (i < m_iProjectionAngleCount-1) vectors += ';'; } - cfg->self->addChildNode("Vectors", vectors); + cfg->self.addChildNode("Vectors", vectors); return cfg; } diff --git a/src/Config.cpp b/src/Config.cpp index 32e5ed9..395080b 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -45,15 +45,14 @@ using namespace std; //----------------------------------------------------------------------------- // default constructor -Config::Config() +Config::Config() : self() { - self = 0; _doc = 0; } //----------------------------------------------------------------------------- // not so default constructor -Config::Config(XMLNode* _self) +Config::Config(XMLNode _self) { self = _self; _doc = 0; @@ -62,8 +61,6 @@ Config::Config(XMLNode* _self) //----------------------------------------------------------------------------- Config::~Config() { - delete self; - self = 0; delete _doc; _doc = 0; } @@ -71,7 +68,7 @@ Config::~Config() //----------------------------------------------------------------------------- void Config::initialize(std::string rootname) { - if (self == 0) { + if (!self) { XMLDocument* doc = XMLDocument::createDocument(rootname); self = doc->getRootNode(); _doc = doc; @@ -129,13 +126,13 @@ bool ConfigStackCheck::stopParsing() std::string errors; - std::list nodes = cfg->self->getNodes(); - for (std::list::iterator i = nodes.begin(); i != nodes.end(); ++i) + std::list nodes = cfg->self.getNodes(); + for (std::list::iterator i = nodes.begin(); i != nodes.end(); ++i) { - std::string nodeName = (*i)->getName(); + std::string nodeName = i->getName(); if (nodeName == "Option") { - nodeName = (*i)->getAttribute("key", ""); + nodeName = i->getAttribute("key", ""); if (object->configCheckData->parsedOptions.find(nodeName) == object->configCheckData->parsedOptions.end()) { if (!errors.empty()) errors += ", "; errors += nodeName; @@ -147,8 +144,6 @@ bool ConfigStackCheck::stopParsing() } } } - for (std::list::iterator i = nodes.begin(); i != nodes.end(); ++i) - delete (*i); nodes.clear(); if (!errors.empty()) { diff --git a/src/CudaBackProjectionAlgorithm3D.cpp b/src/CudaBackProjectionAlgorithm3D.cpp index abcf096..fbb8f28 100644 --- a/src/CudaBackProjectionAlgorithm3D.cpp +++ b/src/CudaBackProjectionAlgorithm3D.cpp @@ -102,9 +102,9 @@ bool CCudaBackProjectionAlgorithm3D::initialize(const Config& _cfg) return false; } - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); CC.markOptionParsed("GPUindex"); - m_iVoxelSuperSampling = (int)_cfg.self->getOptionNumerical("VoxelSuperSampling", 1); + m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", 1); CC.markOptionParsed("VoxelSuperSampling"); CFloat32ProjectionData3DMemory* pSinoMem = dynamic_cast(m_pSinogram); @@ -114,7 +114,7 @@ const CParallelProjectionGeometry3D* par3dgeom = dynamic_cast(projgeom); if (parvec3dgeom || par3dgeom) { // This option is only supported for Par3D currently - m_bSIRTWeighting = _cfg.self->getOptionBool("SIRTWeighting", false); + m_bSIRTWeighting = _cfg.self.getOptionBool("SIRTWeighting", false); CC.markOptionParsed("SIRTWeighting"); } diff --git a/src/CudaCglsAlgorithm3D.cpp b/src/CudaCglsAlgorithm3D.cpp index a5500d6..3457b81 100644 --- a/src/CudaCglsAlgorithm3D.cpp +++ b/src/CudaCglsAlgorithm3D.cpp @@ -106,11 +106,11 @@ bool CCudaCglsAlgorithm3D::initialize(const Config& _cfg) return false; } - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); CC.markOptionParsed("GPUindex"); - m_iDetectorSuperSampling = (int)_cfg.self->getOptionNumerical("DetectorSuperSampling", 1); + m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1); CC.markOptionParsed("DetectorSuperSampling"); - m_iVoxelSuperSampling = (int)_cfg.self->getOptionNumerical("VoxelSuperSampling", 1); + m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", 1); CC.markOptionParsed("VoxelSuperSampling"); m_pCgls = new AstraCGLS3d(); diff --git a/src/CudaDartMaskAlgorithm.cpp b/src/CudaDartMaskAlgorithm.cpp index dcdefcc..950b428 100644 --- a/src/CudaDartMaskAlgorithm.cpp +++ b/src/CudaDartMaskAlgorithm.cpp @@ -65,38 +65,36 @@ bool CCudaDartMaskAlgorithm::initialize(const Config& _cfg) ConfigStackCheck CC("CudaDartMaskAlgorithm", this, _cfg); // reconstruction data - XMLNode* node = _cfg.self->getSingleNode("SegmentationDataId"); + XMLNode node = _cfg.self.getSingleNode("SegmentationDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No SegmentationDataId tag specified."); - int id = boost::lexical_cast(node->getContent()); + int id = boost::lexical_cast(node.getContent()); m_pSegmentation = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("SegmentationDataId"); // reconstruction data - node = _cfg.self->getSingleNode("MaskDataId"); + node = _cfg.self.getSingleNode("MaskDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No MaskDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pMask = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("MaskDataId"); // Option: GPU number - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex); CC.markOptionParsed("GPUindex"); - if (!_cfg.self->hasOption("GPUindex")) + if (!_cfg.self.hasOption("GPUindex")) CC.markOptionParsed("GPUIndex"); // Option: Connectivity - m_iConn = (unsigned int)_cfg.self->getOptionNumerical("Connectivity", 8); + m_iConn = (unsigned int)_cfg.self.getOptionNumerical("Connectivity", 8); CC.markOptionParsed("Connectivity"); // Option: Threshold - m_iThreshold = (unsigned int)_cfg.self->getOptionNumerical("Threshold", 1); + m_iThreshold = (unsigned int)_cfg.self.getOptionNumerical("Threshold", 1); CC.markOptionParsed("Threshold"); // Option: Radius - m_iRadius = (unsigned int)_cfg.self->getOptionNumerical("Radius", 1); + m_iRadius = (unsigned int)_cfg.self.getOptionNumerical("Radius", 1); CC.markOptionParsed("Radius"); _check(); diff --git a/src/CudaDartMaskAlgorithm3D.cpp b/src/CudaDartMaskAlgorithm3D.cpp index f3500b9..b0dfc5b 100644 --- a/src/CudaDartMaskAlgorithm3D.cpp +++ b/src/CudaDartMaskAlgorithm3D.cpp @@ -65,38 +65,36 @@ bool CCudaDartMaskAlgorithm3D::initialize(const Config& _cfg) ConfigStackCheck CC("CudaDartMaskAlgorithm", this, _cfg); // reconstruction data - XMLNode* node = _cfg.self->getSingleNode("SegmentationDataId"); + XMLNode node = _cfg.self.getSingleNode("SegmentationDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No SegmentationDataId tag specified."); - int id = boost::lexical_cast(node->getContent()); + int id = boost::lexical_cast(node.getContent()); m_pSegmentation = dynamic_cast(CData3DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("SegmentationDataId"); // reconstruction data - node = _cfg.self->getSingleNode("MaskDataId"); + node = _cfg.self.getSingleNode("MaskDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No MaskDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pMask = dynamic_cast(CData3DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("MaskDataId"); // Option: GPU number - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex); CC.markOptionParsed("GPUindex"); - if (!_cfg.self->hasOption("GPUindex")) + if (!_cfg.self.hasOption("GPUindex")) CC.markOptionParsed("GPUIndex"); // Option: Connectivity - m_iConn = (unsigned int)_cfg.self->getOptionNumerical("Connectivity", 8); + m_iConn = (unsigned int)_cfg.self.getOptionNumerical("Connectivity", 8); CC.markOptionParsed("Connectivity"); // Option: Threshold - m_iThreshold = (unsigned int)_cfg.self->getOptionNumerical("Threshold", 1); + m_iThreshold = (unsigned int)_cfg.self.getOptionNumerical("Threshold", 1); CC.markOptionParsed("Threshold"); // Option: Radius - m_iRadius = (unsigned int)_cfg.self->getOptionNumerical("Radius", 1); + m_iRadius = (unsigned int)_cfg.self.getOptionNumerical("Radius", 1); CC.markOptionParsed("Radius"); _check(); diff --git a/src/CudaDartSmoothingAlgorithm.cpp b/src/CudaDartSmoothingAlgorithm.cpp index 2f2103f..7e22809 100644 --- a/src/CudaDartSmoothingAlgorithm.cpp +++ b/src/CudaDartSmoothingAlgorithm.cpp @@ -65,34 +65,32 @@ bool CCudaDartSmoothingAlgorithm::initialize(const Config& _cfg) ConfigStackCheck CC("CudaDartSmoothingAlgorithm", this, _cfg); // reconstruction data - XMLNode* node = _cfg.self->getSingleNode("InDataId"); + XMLNode node = _cfg.self.getSingleNode("InDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No InDataId tag specified."); - int id = boost::lexical_cast(node->getContent()); + int id = boost::lexical_cast(node.getContent()); m_pIn = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("InDataId"); // reconstruction data - node = _cfg.self->getSingleNode("OutDataId"); + node = _cfg.self.getSingleNode("OutDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No OutDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pOut = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("OutDataId"); // Option: GPU number - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex); CC.markOptionParsed("GPUindex"); - if (!_cfg.self->hasOption("GPUindex")) + if (!_cfg.self.hasOption("GPUindex")) CC.markOptionParsed("GPUIndex"); // Option: Radius - m_fB = (float)_cfg.self->getOptionNumerical("Intensity", 0.3f); + m_fB = (float)_cfg.self.getOptionNumerical("Intensity", 0.3f); CC.markOptionParsed("Intensity"); // Option: Radius - m_iRadius = (unsigned int)_cfg.self->getOptionNumerical("Radius", 1); + m_iRadius = (unsigned int)_cfg.self.getOptionNumerical("Radius", 1); CC.markOptionParsed("Radius"); diff --git a/src/CudaDartSmoothingAlgorithm3D.cpp b/src/CudaDartSmoothingAlgorithm3D.cpp index f3cf015..9c4437a 100644 --- a/src/CudaDartSmoothingAlgorithm3D.cpp +++ b/src/CudaDartSmoothingAlgorithm3D.cpp @@ -65,34 +65,32 @@ bool CCudaDartSmoothingAlgorithm3D::initialize(const Config& _cfg) ConfigStackCheck CC("CudaDartSmoothingAlgorithm", this, _cfg); // reconstruction data - XMLNode* node = _cfg.self->getSingleNode("InDataId"); + XMLNode node = _cfg.self.getSingleNode("InDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No InDataId tag specified."); - int id = boost::lexical_cast(node->getContent()); + int id = boost::lexical_cast(node.getContent()); m_pIn = dynamic_cast(CData3DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("InDataId"); // reconstruction data - node = _cfg.self->getSingleNode("OutDataId"); + node = _cfg.self.getSingleNode("OutDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No OutDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pOut = dynamic_cast(CData3DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("OutDataId"); // Option: GPU number - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex); CC.markOptionParsed("GPUindex"); - if (!_cfg.self->hasOption("GPUindex")) + if (!_cfg.self.hasOption("GPUindex")) CC.markOptionParsed("GPUIndex"); // Option: Intensity - m_fB = (float)_cfg.self->getOptionNumerical("Intensity", 0.3f); + m_fB = (float)_cfg.self.getOptionNumerical("Intensity", 0.3f); CC.markOptionParsed("Intensity"); // Option: Radius - m_iRadius = (unsigned int)_cfg.self->getOptionNumerical("Radius", 1); + m_iRadius = (unsigned int)_cfg.self.getOptionNumerical("Radius", 1); CC.markOptionParsed("Radius"); _check(); diff --git a/src/CudaDataOperationAlgorithm.cpp b/src/CudaDataOperationAlgorithm.cpp index 79a9d7f..ae133c2 100644 --- a/src/CudaDataOperationAlgorithm.cpp +++ b/src/CudaDataOperationAlgorithm.cpp @@ -67,40 +67,37 @@ bool CCudaDataOperationAlgorithm::initialize(const Config& _cfg) ConfigStackCheck CC("CCudaDataOperationAlgorithm", this, _cfg); // operation - XMLNode* node = _cfg.self->getSingleNode("Operation"); + XMLNode node = _cfg.self.getSingleNode("Operation"); ASTRA_CONFIG_CHECK(node, "CCudaDataOperationAlgorithm", "No Operation tag specified."); - m_sOperation = node->getContent(); + m_sOperation = node.getContent(); m_sOperation.erase(std::remove(m_sOperation.begin(), m_sOperation.end(), ' '), m_sOperation.end()); - ASTRA_DELETE(node); CC.markNodeParsed("Operation"); // data - node = _cfg.self->getSingleNode("DataId"); + node = _cfg.self.getSingleNode("DataId"); ASTRA_CONFIG_CHECK(node, "CCudaDataOperationAlgorithm", "No DataId tag specified."); - vector data = node->getContentArray(); + vector data = node.getContentArray(); for (vector::iterator it = data.begin(); it != data.end(); it++){ int id = boost::lexical_cast(*it); m_pData.push_back(dynamic_cast(CData2DManager::getSingleton().get(id))); } - ASTRA_DELETE(node); CC.markNodeParsed("DataId"); // scalar - node = _cfg.self->getSingleNode("Scalar"); + node = _cfg.self.getSingleNode("Scalar"); ASTRA_CONFIG_CHECK(node, "CCudaDataOperationAlgorithm", "No Scalar tag specified."); - m_fScalar = node->getContentNumericalArray(); - ASTRA_DELETE(node); + m_fScalar = node.getContentNumericalArray(); CC.markNodeParsed("Scalar"); // Option: GPU number - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex); CC.markOptionParsed("GPUindex"); - if (!_cfg.self->hasOption("GPUindex")) + if (!_cfg.self.hasOption("GPUindex")) CC.markOptionParsed("GPUIndex"); - if (_cfg.self->hasOption("MaskId")) { - int id = boost::lexical_cast(_cfg.self->getOption("MaskId")); + if (_cfg.self.hasOption("MaskId")) { + int id = boost::lexical_cast(_cfg.self.getOption("MaskId")); m_pMask = dynamic_cast(CData2DManager::getSingleton().get(id)); } CC.markOptionParsed("MaskId"); diff --git a/src/CudaFDKAlgorithm3D.cpp b/src/CudaFDKAlgorithm3D.cpp index 7638696..467e641 100644 --- a/src/CudaFDKAlgorithm3D.cpp +++ b/src/CudaFDKAlgorithm3D.cpp @@ -100,12 +100,12 @@ bool CCudaFDKAlgorithm3D::initialize(const Config& _cfg) return false; } - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); CC.markOptionParsed("GPUindex"); - m_iVoxelSuperSampling = (int)_cfg.self->getOptionNumerical("VoxelSuperSampling", 1); + m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", 1); CC.markOptionParsed("VoxelSuperSampling"); - m_bShortScan = _cfg.self->getOptionBool("ShortScan", false); + m_bShortScan = _cfg.self.getOptionBool("ShortScan", false); CC.markOptionParsed("ShortScan"); // success diff --git a/src/CudaFilteredBackProjectionAlgorithm.cpp b/src/CudaFilteredBackProjectionAlgorithm.cpp index 0badc20..5d6c166 100644 --- a/src/CudaFilteredBackProjectionAlgorithm.cpp +++ b/src/CudaFilteredBackProjectionAlgorithm.cpp @@ -78,39 +78,36 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) } // sinogram data - XMLNode* node = _cfg.self->getSingleNode("ProjectionDataId"); + XMLNode node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "CudaFBP", "No ProjectionDataId tag specified."); - int id = boost::lexical_cast(node->getContent()); + int id = boost::lexical_cast(node.getContent()); m_pSinogram = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("ProjectionDataId"); // reconstruction data - node = _cfg.self->getSingleNode("ReconstructionDataId"); + node = _cfg.self.getSingleNode("ReconstructionDataId"); ASTRA_CONFIG_CHECK(node, "CudaFBP", "No ReconstructionDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pReconstruction = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("ReconstructionDataId"); // filter type - node = _cfg.self->getSingleNode("FilterType"); - if(node != NULL) + node = _cfg.self.getSingleNode("FilterType"); + if (node) { - m_eFilter = _convertStringToFilter(node->getContent().c_str()); + m_eFilter = _convertStringToFilter(node.getContent().c_str()); } else { m_eFilter = FILTER_RAMLAK; } CC.markNodeParsed("FilterType"); - ASTRA_DELETE(node); // filter - node = _cfg.self->getSingleNode("FilterSinogramId"); - if(node != NULL) + node = _cfg.self.getSingleNode("FilterSinogramId"); + if (node) { - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); const CFloat32ProjectionData2D * pFilterData = dynamic_cast(CData2DManager::getSingleton().get(id)); m_iFilterWidth = pFilterData->getGeometry()->getDetectorCount(); int iFilterProjectionCount = pFilterData->getGeometry()->getProjectionAngleCount(); @@ -124,13 +121,12 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) m_pfFilter = NULL; } CC.markNodeParsed("FilterSinogramId"); // TODO: Only for some types! - ASTRA_DELETE(node); // filter parameter - node = _cfg.self->getSingleNode("FilterParameter"); - if(node != NULL) + node = _cfg.self.getSingleNode("FilterParameter"); + if (node) { - float fParameter = boost::lexical_cast(node->getContent()); + float fParameter = boost::lexical_cast(node.getContent()); m_fFilterParameter = fParameter; } else @@ -138,13 +134,12 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) m_fFilterParameter = -1.0f; } CC.markNodeParsed("FilterParameter"); // TODO: Only for some types! - ASTRA_DELETE(node); // D value - node = _cfg.self->getSingleNode("FilterD"); - if(node != NULL) + node = _cfg.self.getSingleNode("FilterD"); + if (node) { - float fD = boost::lexical_cast(node->getContent()); + float fD = boost::lexical_cast(node.getContent()); m_fFilterD = fD; } else @@ -152,19 +147,18 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) m_fFilterD = 1.0f; } CC.markNodeParsed("FilterD"); // TODO: Only for some types! - ASTRA_DELETE(node); // GPU number - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); CC.markOptionParsed("GPUindex"); // Pixel supersampling factor - m_iPixelSuperSampling = (int)_cfg.self->getOptionNumerical("PixelSuperSampling", 1); + m_iPixelSuperSampling = (int)_cfg.self.getOptionNumerical("PixelSuperSampling", 1); CC.markOptionParsed("PixelSuperSampling"); // Fan beam short scan mode if (m_pSinogram && dynamic_cast(m_pSinogram->getGeometry())) { - m_bShortScan = (int)_cfg.self->getOptionBool("ShortScan", false); + m_bShortScan = (int)_cfg.self.getOptionBool("ShortScan", false); CC.markOptionParsed("ShortScan"); } diff --git a/src/CudaForwardProjectionAlgorithm.cpp b/src/CudaForwardProjectionAlgorithm.cpp index 95abb62..0f97d59 100644 --- a/src/CudaForwardProjectionAlgorithm.cpp +++ b/src/CudaForwardProjectionAlgorithm.cpp @@ -73,42 +73,39 @@ bool CCudaForwardProjectionAlgorithm::initialize(const Config& _cfg) ConfigStackCheck CC("CudaForwardProjectionAlgorithm", this, _cfg); // sinogram data - XMLNode* node = _cfg.self->getSingleNode("ProjectionDataId"); + XMLNode node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "FP_CUDA", "No ProjectionDataId tag specified."); - int id = boost::lexical_cast(node->getContent()); + int id = boost::lexical_cast(node.getContent()); m_pSinogram = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("ProjectionDataId"); // volume data - node = _cfg.self->getSingleNode("VolumeDataId"); + node = _cfg.self.getSingleNode("VolumeDataId"); ASTRA_CONFIG_CHECK(node, "FP_CUDA", "No VolumeDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pVolume = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("VolumeDataId"); // GPU number - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex); CC.markOptionParsed("GPUindex"); - if (!_cfg.self->hasOption("GPUindex")) + if (!_cfg.self.hasOption("GPUindex")) CC.markOptionParsed("GPUIndex"); // Detector supersampling factor - m_iDetectorSuperSampling = (int)_cfg.self->getOptionNumerical("DetectorSuperSampling", 1); + m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1); CC.markOptionParsed("DetectorSuperSampling"); // This isn't used yet, but passing it is not something to warn about - node = _cfg.self->getSingleNode("ProjectorId"); + node = _cfg.self.getSingleNode("ProjectorId"); if (node) { - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); CProjector2D *projector = CProjector2DManager::getSingleton().get(id); if (!dynamic_cast(projector)) { ASTRA_WARN("non-CUDA Projector2D passed to FP_CUDA"); } - delete node; } CC.markNodeParsed("ProjectorId"); diff --git a/src/CudaForwardProjectionAlgorithm3D.cpp b/src/CudaForwardProjectionAlgorithm3D.cpp index 8e6bab5..e29b5a9 100644 --- a/src/CudaForwardProjectionAlgorithm3D.cpp +++ b/src/CudaForwardProjectionAlgorithm3D.cpp @@ -78,40 +78,37 @@ bool CCudaForwardProjectionAlgorithm3D::initialize(const Config& _cfg) ASTRA_ASSERT(_cfg.self); ConfigStackCheck CC("CudaForwardProjectionAlgorithm3D", this, _cfg); - XMLNode* node; + XMLNode node; int id; // sinogram data - node = _cfg.self->getSingleNode("ProjectionDataId"); + node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "CudaForwardProjection3D", "No ProjectionDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pProjections = dynamic_cast(CData3DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("ProjectionDataId"); // reconstruction data - node = _cfg.self->getSingleNode("VolumeDataId"); + node = _cfg.self.getSingleNode("VolumeDataId"); ASTRA_CONFIG_CHECK(node, "CudaForwardProjection3D", "No VolumeDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pVolume = dynamic_cast(CData3DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("VolumeDataId"); // optional: projector - node = _cfg.self->getSingleNode("ProjectorId"); + node = _cfg.self.getSingleNode("ProjectorId"); if (node) { - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pProjector = CProjector3DManager::getSingleton().get(id); - ASTRA_DELETE(node); } else { m_pProjector = 0; // TODO: or manually construct default projector? } CC.markNodeParsed("ProjectorId"); // GPU number - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); CC.markOptionParsed("GPUindex"); - m_iDetectorSuperSampling = (int)_cfg.self->getOptionNumerical("DetectorSuperSampling", 1); + m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1); CC.markOptionParsed("DetectorSuperSampling"); // success diff --git a/src/CudaProjector2D.cpp b/src/CudaProjector2D.cpp index 056ea3b..fa024c8 100644 --- a/src/CudaProjector2D.cpp +++ b/src/CudaProjector2D.cpp @@ -104,10 +104,10 @@ bool CCudaProjector2D::initialize(const Config& _cfg) // TODO: Check the projection geometry is a supported type - XMLNode* node = _cfg.self->getSingleNode("ProjectionKernel"); + XMLNode node = _cfg.self.getSingleNode("ProjectionKernel"); m_projectionKernel = ker2d_default; if (node) { - std::string sProjKernel = node->getContent(); + std::string sProjKernel = node.getContent(); if (sProjKernel == "default") { @@ -115,7 +115,6 @@ bool CCudaProjector2D::initialize(const Config& _cfg) return false; } } - ASTRA_DELETE(node); CC.markNodeParsed("ProjectionKernel"); m_bIsInitialized = _check(); diff --git a/src/CudaProjector3D.cpp b/src/CudaProjector3D.cpp index 2f4c799..41529a5 100644 --- a/src/CudaProjector3D.cpp +++ b/src/CudaProjector3D.cpp @@ -105,10 +105,10 @@ bool CCudaProjector3D::initialize(const Config& _cfg) return false; } - XMLNode* node = _cfg.self->getSingleNode("ProjectionKernel"); + XMLNode node = _cfg.self.getSingleNode("ProjectionKernel"); m_projectionKernel = ker3d_default; if (node) { - std::string sProjKernel = node->getContent(); + std::string sProjKernel = node.getContent(); if (sProjKernel == "default") { @@ -118,7 +118,6 @@ bool CCudaProjector3D::initialize(const Config& _cfg) return false; } } - ASTRA_DELETE(node); CC.markNodeParsed("ProjectionKernel"); m_bIsInitialized = _check(); diff --git a/src/CudaReconstructionAlgorithm2D.cpp b/src/CudaReconstructionAlgorithm2D.cpp index 1c6b763..db99d42 100644 --- a/src/CudaReconstructionAlgorithm2D.cpp +++ b/src/CudaReconstructionAlgorithm2D.cpp @@ -96,91 +96,88 @@ bool CCudaReconstructionAlgorithm2D::initialize(const Config& _cfg) } // sinogram data - XMLNode* node = _cfg.self->getSingleNode("ProjectionDataId"); + XMLNode node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "CudaSirt2", "No ProjectionDataId tag specified."); - int id = boost::lexical_cast(node->getContent()); + int id = boost::lexical_cast(node.getContent()); m_pSinogram = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("ProjectionDataId"); // reconstruction data - node = _cfg.self->getSingleNode("ReconstructionDataId"); + node = _cfg.self.getSingleNode("ReconstructionDataId"); ASTRA_CONFIG_CHECK(node, "CudaSirt2", "No ReconstructionDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pReconstruction = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("ReconstructionDataId"); // fixed mask - if (_cfg.self->hasOption("ReconstructionMaskId")) { + if (_cfg.self.hasOption("ReconstructionMaskId")) { m_bUseReconstructionMask = true; - id = boost::lexical_cast(_cfg.self->getOption("ReconstructionMaskId")); + id = boost::lexical_cast(_cfg.self.getOption("ReconstructionMaskId")); m_pReconstructionMask = dynamic_cast(CData2DManager::getSingleton().get(id)); ASTRA_CONFIG_CHECK(m_pReconstructionMask, "CudaReconstruction2D", "Invalid ReconstructionMaskId."); } CC.markOptionParsed("ReconstructionMaskId"); // fixed mask - if (_cfg.self->hasOption("SinogramMaskId")) { + if (_cfg.self.hasOption("SinogramMaskId")) { m_bUseSinogramMask = true; - id = boost::lexical_cast(_cfg.self->getOption("SinogramMaskId")); + id = boost::lexical_cast(_cfg.self.getOption("SinogramMaskId")); m_pSinogramMask = dynamic_cast(CData2DManager::getSingleton().get(id)); ASTRA_CONFIG_CHECK(m_pSinogramMask, "CudaReconstruction2D", "Invalid SinogramMaskId."); } CC.markOptionParsed("SinogramMaskId"); // Constraints - NEW - if (_cfg.self->hasOption("MinConstraint")) { + if (_cfg.self.hasOption("MinConstraint")) { m_bUseMinConstraint = true; - m_fMinValue = _cfg.self->getOptionNumerical("MinConstraint", 0.0f); + m_fMinValue = _cfg.self.getOptionNumerical("MinConstraint", 0.0f); CC.markOptionParsed("MinConstraint"); } else { // Constraint - OLD - m_bUseMinConstraint = _cfg.self->getOptionBool("UseMinConstraint", false); + m_bUseMinConstraint = _cfg.self.getOptionBool("UseMinConstraint", false); CC.markOptionParsed("UseMinConstraint"); if (m_bUseMinConstraint) { - m_fMinValue = _cfg.self->getOptionNumerical("MinConstraintValue", 0.0f); + m_fMinValue = _cfg.self.getOptionNumerical("MinConstraintValue", 0.0f); CC.markOptionParsed("MinConstraintValue"); } } - if (_cfg.self->hasOption("MaxConstraint")) { + if (_cfg.self.hasOption("MaxConstraint")) { m_bUseMaxConstraint = true; - m_fMaxValue = _cfg.self->getOptionNumerical("MaxConstraint", 255.0f); + m_fMaxValue = _cfg.self.getOptionNumerical("MaxConstraint", 255.0f); CC.markOptionParsed("MaxConstraint"); } else { // Constraint - OLD - m_bUseMaxConstraint = _cfg.self->getOptionBool("UseMaxConstraint", false); + m_bUseMaxConstraint = _cfg.self.getOptionBool("UseMaxConstraint", false); CC.markOptionParsed("UseMaxConstraint"); if (m_bUseMaxConstraint) { - m_fMaxValue = _cfg.self->getOptionNumerical("MaxConstraintValue", 0.0f); + m_fMaxValue = _cfg.self.getOptionNumerical("MaxConstraintValue", 0.0f); CC.markOptionParsed("MaxConstraintValue"); } } // GPU number - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex); CC.markOptionParsed("GPUindex"); - if (!_cfg.self->hasOption("GPUindex")) + if (!_cfg.self.hasOption("GPUindex")) CC.markOptionParsed("GPUIndex"); // Detector supersampling factor - m_iDetectorSuperSampling = (int)_cfg.self->getOptionNumerical("DetectorSuperSampling", 1); + m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1); CC.markOptionParsed("DetectorSuperSampling"); // Pixel supersampling factor - m_iPixelSuperSampling = (int)_cfg.self->getOptionNumerical("PixelSuperSampling", 1); + m_iPixelSuperSampling = (int)_cfg.self.getOptionNumerical("PixelSuperSampling", 1); CC.markOptionParsed("PixelSuperSampling"); // This isn't used yet, but passing it is not something to warn about - node = _cfg.self->getSingleNode("ProjectorId"); + node = _cfg.self.getSingleNode("ProjectorId"); if (node) { - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); CProjector2D *projector = CProjector2DManager::getSingleton().get(id); if (!dynamic_cast(projector)) { ASTRA_WARN("non-CUDA Projector2D passed"); } - delete node; } CC.markNodeParsed("ProjectorId"); diff --git a/src/CudaRoiSelectAlgorithm.cpp b/src/CudaRoiSelectAlgorithm.cpp index bfccb3a..7635c69 100644 --- a/src/CudaRoiSelectAlgorithm.cpp +++ b/src/CudaRoiSelectAlgorithm.cpp @@ -66,22 +66,21 @@ bool CCudaRoiSelectAlgorithm::initialize(const Config& _cfg) ConfigStackCheck CC("CudaDartMaskAlgorithm", this, _cfg); // reconstruction data - XMLNode* node = _cfg.self->getSingleNode("DataId"); + XMLNode node = _cfg.self.getSingleNode("DataId"); ASTRA_CONFIG_CHECK(node, "CudaRoiSelect", "No DataId tag specified."); - int id = boost::lexical_cast(node->getContent()); + int id = boost::lexical_cast(node.getContent()); m_pData = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("DataId"); // Option: GPU number - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex); CC.markOptionParsed("GPUindex"); - if (!_cfg.self->hasOption("GPUindex")) + if (!_cfg.self.hasOption("GPUindex")) CC.markOptionParsed("GPUIndex"); // Option: Radius - m_fRadius = (unsigned int)_cfg.self->getOptionNumerical("Radius", 0.0f); + m_fRadius = (unsigned int)_cfg.self.getOptionNumerical("Radius", 0.0f); CC.markOptionParsed("Radius"); _check(); diff --git a/src/CudaSartAlgorithm.cpp b/src/CudaSartAlgorithm.cpp index 8e22c59..8c0c6d7 100644 --- a/src/CudaSartAlgorithm.cpp +++ b/src/CudaSartAlgorithm.cpp @@ -74,7 +74,7 @@ bool CCudaSartAlgorithm::initialize(const Config& _cfg) // projection order int projectionCount = m_pSinogram->getGeometry()->getProjectionAngleCount(); int* projectionOrder = NULL; - string projOrder = _cfg.self->getOption("ProjectionOrder", "random"); + string projOrder = _cfg.self.getOption("ProjectionOrder", "random"); CC.markOptionParsed("ProjectionOrder"); if (projOrder == "sequential") { projectionOrder = new int[projectionCount]; @@ -97,7 +97,7 @@ bool CCudaSartAlgorithm::initialize(const Config& _cfg) sart->setProjectionOrder(projectionOrder, projectionCount); delete[] projectionOrder; } else if (projOrder == "custom") { - vector projOrderList = _cfg.self->getOptionNumericalArray("ProjectionOrderList"); + vector projOrderList = _cfg.self.getOptionNumericalArray("ProjectionOrderList"); projectionOrder = new int[projOrderList.size()]; for (int i = 0; i < projOrderList.size(); i++) { projectionOrder[i] = static_cast(projOrderList[i]); diff --git a/src/CudaSirtAlgorithm.cpp b/src/CudaSirtAlgorithm.cpp index f6eb79a..d424915 100644 --- a/src/CudaSirtAlgorithm.cpp +++ b/src/CudaSirtAlgorithm.cpp @@ -76,13 +76,13 @@ bool CCudaSirtAlgorithm::initialize(const Config& _cfg) return false; // min/max masks - if (_cfg.self->hasOption("MinMaskId")) { - int id = boost::lexical_cast(_cfg.self->getOption("MinMaskId")); + if (_cfg.self.hasOption("MinMaskId")) { + int id = boost::lexical_cast(_cfg.self.getOption("MinMaskId")); m_pMinMask = dynamic_cast(CData2DManager::getSingleton().get(id)); } CC.markOptionParsed("MinMaskId"); - if (_cfg.self->hasOption("MaxMaskId")) { - int id = boost::lexical_cast(_cfg.self->getOption("MaxMaskId")); + if (_cfg.self.hasOption("MaxMaskId")) { + int id = boost::lexical_cast(_cfg.self.getOption("MaxMaskId")); m_pMaxMask = dynamic_cast(CData2DManager::getSingleton().get(id)); } CC.markOptionParsed("MaxMaskId"); diff --git a/src/CudaSirtAlgorithm3D.cpp b/src/CudaSirtAlgorithm3D.cpp index da83c7e..5ad131b 100644 --- a/src/CudaSirtAlgorithm3D.cpp +++ b/src/CudaSirtAlgorithm3D.cpp @@ -107,11 +107,11 @@ bool CCudaSirtAlgorithm3D::initialize(const Config& _cfg) return false; } - m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); + m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); CC.markOptionParsed("GPUindex"); - m_iDetectorSuperSampling = (int)_cfg.self->getOptionNumerical("DetectorSuperSampling", 1); + m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1); CC.markOptionParsed("DetectorSuperSampling"); - m_iVoxelSuperSampling = (int)_cfg.self->getOptionNumerical("VoxelSuperSampling", 1); + m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", 1); CC.markOptionParsed("VoxelSuperSampling"); m_pSirt = new AstraSIRT3d(); diff --git a/src/FanFlatProjectionGeometry2D.cpp b/src/FanFlatProjectionGeometry2D.cpp index d757f18..32a19bc 100644 --- a/src/FanFlatProjectionGeometry2D.cpp +++ b/src/FanFlatProjectionGeometry2D.cpp @@ -134,17 +134,15 @@ bool CFanFlatProjectionGeometry2D::initialize(const Config& _cfg) CProjectionGeometry2D::initialize(_cfg); // Required: DistanceOriginDetector - XMLNode* node = _cfg.self->getSingleNode("DistanceOriginDetector"); + XMLNode node = _cfg.self.getSingleNode("DistanceOriginDetector"); ASTRA_CONFIG_CHECK(node, "FanFlatProjectionGeometry2D", "No DistanceOriginDetector tag specified."); - m_fOriginDetectorDistance = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_fOriginDetectorDistance = boost::lexical_cast(node.getContent()); CC.markNodeParsed("DistanceOriginDetector"); // Required: DetectorOriginSource - node = _cfg.self->getSingleNode("DistanceOriginSource"); + node = _cfg.self.getSingleNode("DistanceOriginSource"); ASTRA_CONFIG_CHECK(node, "FanFlatProjectionGeometry2D", "No DistanceOriginSource tag specified."); - m_fOriginSourceDistance = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_fOriginSourceDistance = boost::lexical_cast(node.getContent()); CC.markNodeParsed("DistanceOriginSource"); // success @@ -209,12 +207,12 @@ Config* CFanFlatProjectionGeometry2D::getConfiguration() const { Config* cfg = new Config(); cfg->initialize("ProjectionGeometry2D"); - cfg->self->addAttribute("type", "fanflat"); - cfg->self->addChildNode("DetectorCount", getDetectorCount()); - cfg->self->addChildNode("DetectorWidth", getDetectorWidth()); - cfg->self->addChildNode("DistanceOriginSource", getOriginSourceDistance()); - cfg->self->addChildNode("DistanceOriginDetector", getOriginDetectorDistance()); - cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); + cfg->self.addAttribute("type", "fanflat"); + cfg->self.addChildNode("DetectorCount", getDetectorCount()); + cfg->self.addChildNode("DetectorWidth", getDetectorWidth()); + cfg->self.addChildNode("DistanceOriginSource", getOriginSourceDistance()); + cfg->self.addChildNode("DistanceOriginDetector", getOriginDetectorDistance()); + cfg->self.addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); return cfg; } //---------------------------------------------------------------------------------------- diff --git a/src/FanFlatVecProjectionGeometry2D.cpp b/src/FanFlatVecProjectionGeometry2D.cpp index 9c7b596..4104379 100644 --- a/src/FanFlatVecProjectionGeometry2D.cpp +++ b/src/FanFlatVecProjectionGeometry2D.cpp @@ -116,25 +116,23 @@ bool CFanFlatVecProjectionGeometry2D::initialize(const Config& _cfg) ASTRA_ASSERT(_cfg.self); ConfigStackCheck CC("FanFlatVecProjectionGeometry2D", this, _cfg); - XMLNode* node; + XMLNode node; // TODO: Fix up class hierarchy... this class doesn't fit very well. // initialization of parent class //CProjectionGeometry2D::initialize(_cfg); // Required: DetectorCount - node = _cfg.self->getSingleNode("DetectorCount"); + node = _cfg.self.getSingleNode("DetectorCount"); ASTRA_CONFIG_CHECK(node, "FanFlatVecProjectionGeometry3D", "No DetectorRowCount tag specified."); - m_iDetectorCount = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_iDetectorCount = boost::lexical_cast(node.getContent()); CC.markNodeParsed("DetectorCount"); // Required: Vectors - node = _cfg.self->getSingleNode("Vectors"); + node = _cfg.self.getSingleNode("Vectors"); ASTRA_CONFIG_CHECK(node, "FanFlatVecProjectionGeometry3D", "No Vectors tag specified."); - vector data = node->getContentNumericalArray(); + vector data = node.getContentNumericalArray(); CC.markNodeParsed("Vectors"); - ASTRA_DELETE(node); ASTRA_CONFIG_CHECK(data.size() % 6 == 0, "FanFlatVecProjectionGeometry3D", "Vectors doesn't consist of 6-tuples."); m_iProjectionAngleCount = data.size() / 6; m_pProjectionAngles = new SFanProjection[m_iProjectionAngleCount]; @@ -232,8 +230,8 @@ Config* CFanFlatVecProjectionGeometry2D::getConfiguration() const { Config* cfg = new Config(); cfg->initialize("ProjectionGeometry2D"); - cfg->self->addAttribute("type", "fanflat_vec"); - cfg->self->addChildNode("DetectorCount", getDetectorCount()); + cfg->self.addAttribute("type", "fanflat_vec"); + cfg->self.addChildNode("DetectorCount", getDetectorCount()); std::string vectors = ""; for (int i = 0; i < m_iProjectionAngleCount; ++i) { SFanProjection& p = m_pProjectionAngles[i]; @@ -245,7 +243,7 @@ Config* CFanFlatVecProjectionGeometry2D::getConfiguration() const vectors += boost::lexical_cast(p.fDetUY); if (i < m_iProjectionAngleCount-1) vectors += ';'; } - cfg->self->addChildNode("Vectors", vectors); + cfg->self.addChildNode("Vectors", vectors); return cfg; } //---------------------------------------------------------------------------------------- diff --git a/src/FilteredBackProjectionAlgorithm.cpp b/src/FilteredBackProjectionAlgorithm.cpp index 4a8e5ac..f494d22 100644 --- a/src/FilteredBackProjectionAlgorithm.cpp +++ b/src/FilteredBackProjectionAlgorithm.cpp @@ -94,30 +94,27 @@ bool CFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) ASTRA_ASSERT(_cfg.self); // projector - XMLNode* node = _cfg.self->getSingleNode("ProjectorId"); + XMLNode node = _cfg.self.getSingleNode("ProjectorId"); ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ProjectorId tag specified."); - int id = boost::lexical_cast(node->getContent()); + int id = boost::lexical_cast(node.getContent()); m_pProjector = CProjector2DManager::getSingleton().get(id); - ASTRA_DELETE(node); // sinogram data - node = _cfg.self->getSingleNode("ProjectionDataId"); + node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ProjectionDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pSinogram = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); // volume data - node = _cfg.self->getSingleNode("ReconstructionDataId"); + node = _cfg.self.getSingleNode("ReconstructionDataId"); ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ReconstructionDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pReconstruction = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); - node = _cfg.self->getSingleNode("ProjectionIndex"); + node = _cfg.self.getSingleNode("ProjectionIndex"); if (node) { - vector projectionIndex = node->getContentNumericalArray(); + vector projectionIndex = node.getContentNumericalArray(); int angleCount = projectionIndex.size(); int detectorCount = m_pProjector->getProjectionGeometry()->getDetectorCount(); @@ -154,7 +151,6 @@ bool CFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) m_pProjector = new CParallelBeamLineKernelProjector2D(pg,m_pReconstruction->getGeometry()); m_pSinogram = new CFloat32ProjectionData2D(pg, sinogramData2D); } - ASTRA_DELETE(node); // TODO: check that the angles are linearly spaced between 0 and pi diff --git a/src/ForwardProjectionAlgorithm.cpp b/src/ForwardProjectionAlgorithm.cpp index b530491..f356824 100644 --- a/src/ForwardProjectionAlgorithm.cpp +++ b/src/ForwardProjectionAlgorithm.cpp @@ -126,37 +126,34 @@ bool CForwardProjectionAlgorithm::initialize(const Config& _cfg) } // projector - XMLNode* node = _cfg.self->getSingleNode("ProjectorId"); + XMLNode node = _cfg.self.getSingleNode("ProjectorId"); ASTRA_CONFIG_CHECK(node, "ForwardProjection", "No ProjectorId tag specified."); - int id = boost::lexical_cast(node->getContent()); + int id = boost::lexical_cast(node.getContent()); m_pProjector = CProjector2DManager::getSingleton().get(id); - ASTRA_DELETE(node); // sinogram data - node = _cfg.self->getSingleNode("ProjectionDataId"); + node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "ForwardProjection", "No ProjectionDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pSinogram = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); // volume data - node = _cfg.self->getSingleNode("VolumeDataId"); + node = _cfg.self.getSingleNode("VolumeDataId"); ASTRA_CONFIG_CHECK(node, "ForwardProjection", "No VolumeDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pVolume = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); // volume mask - if (_cfg.self->hasOption("VolumeMaskId")) { + if (_cfg.self.hasOption("VolumeMaskId")) { m_bUseVolumeMask = true; - id = boost::lexical_cast(_cfg.self->getOption("VolumeMaskId")); + id = boost::lexical_cast(_cfg.self.getOption("VolumeMaskId")); m_pVolumeMask = dynamic_cast(CData2DManager::getSingleton().get(id)); } // sino mask - if (_cfg.self->hasOption("SinogramMaskId")) { + if (_cfg.self.hasOption("SinogramMaskId")) { m_bUseSinogramMask = true; - id = boost::lexical_cast(_cfg.self->getOption("SinogramMaskId")); + id = boost::lexical_cast(_cfg.self.getOption("SinogramMaskId")); m_pSinogramMask = dynamic_cast(CData2DManager::getSingleton().get(id)); } diff --git a/src/ParallelBeamBlobKernelProjector2D.cpp b/src/ParallelBeamBlobKernelProjector2D.cpp index 3253f88..4559a48 100644 --- a/src/ParallelBeamBlobKernelProjector2D.cpp +++ b/src/ParallelBeamBlobKernelProjector2D.cpp @@ -128,28 +128,28 @@ bool CParallelBeamBlobKernelProjector2D::initialize(const Config& _cfg) } // required: Kernel - XMLNode* node = _cfg.self->getSingleNode("Kernel"); + XMLNode node = _cfg.self.getSingleNode("Kernel"); ASTRA_CONFIG_CHECK(node, "BlobProjector", "No Kernel tag specified."); { // Required: KernelSize - XMLNode* node2 = node->getSingleNode("KernelSize"); + XMLNode node2 = node.getSingleNode("KernelSize"); ASTRA_CONFIG_CHECK(node2, "BlobProjector", "No Kernel/KernelSize tag specified."); - m_fBlobSize = boost::lexical_cast(node2->getContent()); + m_fBlobSize = boost::lexical_cast(node2.getContent()); // Required: SampleRate - node2 = node->getSingleNode("SampleRate"); + node2 = node.getSingleNode("SampleRate"); ASTRA_CONFIG_CHECK(node2, "BlobProjector", "No Kernel/SampleRate tag specified."); - m_fBlobSampleRate = boost::lexical_cast(node2->getContent()); + m_fBlobSampleRate = boost::lexical_cast(node2.getContent()); // Required: SampleCount - node2 = node->getSingleNode("SampleCount"); + node2 = node.getSingleNode("SampleCount"); ASTRA_CONFIG_CHECK(node2, "BlobProjector", "No Kernel/SampleCount tag specified."); - m_iBlobSampleCount = boost::lexical_cast(node2->getContent()); + m_iBlobSampleCount = boost::lexical_cast(node2.getContent()); // Required: KernelValues - node2 = node->getSingleNode("KernelValues"); + node2 = node.getSingleNode("KernelValues"); ASTRA_CONFIG_CHECK(node2, "BlobProjector", "No Kernel/KernelValues tag specified."); - vector values = node2->getContentNumericalArray(); + vector values = node2.getContentNumericalArray(); ASTRA_CONFIG_CHECK(values.size() == (unsigned int)m_iBlobSampleCount, "BlobProjector", "Number of specified values doesn't match SampleCount."); m_pfBlobValues = new float32[m_iBlobSampleCount]; for (int i = 0; i < m_iBlobSampleCount; i++) { @@ -157,9 +157,9 @@ bool CParallelBeamBlobKernelProjector2D::initialize(const Config& _cfg) } // Required: KernelValues - node2 = node->getSingleNode("KernelValuesNeg"); + node2 = node.getSingleNode("KernelValuesNeg"); ASTRA_CONFIG_CHECK(node2, "BlobProjector", "No Kernel/KernelValuesNeg tag specified."); - vector values2 = node2->getContentNumericalArray(); + vector values2 = node2.getContentNumericalArray(); ASTRA_CONFIG_CHECK(values2.size() == (unsigned int)m_iBlobSampleCount, "BlobProjector", "Number of specified values doesn't match SampleCount."); m_pfBlobValuesNeg = new float32[m_iBlobSampleCount]; for (int i = 0; i < m_iBlobSampleCount; i++) { diff --git a/src/ParallelProjectionGeometry2D.cpp b/src/ParallelProjectionGeometry2D.cpp index cac8f30..699e141 100644 --- a/src/ParallelProjectionGeometry2D.cpp +++ b/src/ParallelProjectionGeometry2D.cpp @@ -176,10 +176,10 @@ Config* CParallelProjectionGeometry2D::getConfiguration() const { Config* cfg = new Config(); cfg->initialize("ProjectionGeometry2D"); - cfg->self->addAttribute("type", "parallel"); - cfg->self->addChildNode("DetectorCount", getDetectorCount()); - cfg->self->addChildNode("DetectorWidth", getDetectorWidth()); - cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); + cfg->self.addAttribute("type", "parallel"); + cfg->self.addChildNode("DetectorCount", getDetectorCount()); + cfg->self.addChildNode("DetectorWidth", getDetectorWidth()); + cfg->self.addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); return cfg; } //---------------------------------------------------------------------------------------- diff --git a/src/ParallelProjectionGeometry3D.cpp b/src/ParallelProjectionGeometry3D.cpp index eb200f9..1c87157 100644 --- a/src/ParallelProjectionGeometry3D.cpp +++ b/src/ParallelProjectionGeometry3D.cpp @@ -164,12 +164,12 @@ Config* CParallelProjectionGeometry3D::getConfiguration() const { Config* cfg = new Config(); cfg->initialize("ProjectionGeometry3D"); - cfg->self->addAttribute("type", "parallel3d"); - cfg->self->addChildNode("DetectorRowCount", m_iDetectorRowCount); - cfg->self->addChildNode("DetectorColCount", m_iDetectorColCount); - cfg->self->addChildNode("DetectorSpacingX", m_fDetectorSpacingX); - cfg->self->addChildNode("DetectorSpacingY", m_fDetectorSpacingY); - cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); + cfg->self.addAttribute("type", "parallel3d"); + cfg->self.addChildNode("DetectorRowCount", m_iDetectorRowCount); + cfg->self.addChildNode("DetectorColCount", m_iDetectorColCount); + cfg->self.addChildNode("DetectorSpacingX", m_fDetectorSpacingX); + cfg->self.addChildNode("DetectorSpacingY", m_fDetectorSpacingY); + cfg->self.addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); return cfg; } //---------------------------------------------------------------------------------------- diff --git a/src/ParallelVecProjectionGeometry3D.cpp b/src/ParallelVecProjectionGeometry3D.cpp index dc325e9..ffad6d0 100644 --- a/src/ParallelVecProjectionGeometry3D.cpp +++ b/src/ParallelVecProjectionGeometry3D.cpp @@ -73,33 +73,30 @@ bool CParallelVecProjectionGeometry3D::initialize(const Config& _cfg) ASTRA_ASSERT(_cfg.self); ConfigStackCheck CC("ParallelVecProjectionGeometry3D", this, _cfg); - XMLNode* node; + XMLNode node; // TODO: Fix up class hierarchy... this class doesn't fit very well. // initialization of parent class //CProjectionGeometry3D::initialize(_cfg); // Required: DetectorRowCount - node = _cfg.self->getSingleNode("DetectorRowCount"); + node = _cfg.self.getSingleNode("DetectorRowCount"); ASTRA_CONFIG_CHECK(node, "ParallelVecProjectionGeometry3D", "No DetectorRowCount tag specified."); - m_iDetectorRowCount = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_iDetectorRowCount = boost::lexical_cast(node.getContent()); CC.markNodeParsed("DetectorRowCount"); // Required: DetectorCount - node = _cfg.self->getSingleNode("DetectorColCount"); + node = _cfg.self.getSingleNode("DetectorColCount"); ASTRA_CONFIG_CHECK(node, "", "No DetectorColCount tag specified."); - m_iDetectorColCount = boost::lexical_cast(node->getContent()); + m_iDetectorColCount = boost::lexical_cast(node.getContent()); m_iDetectorTotCount = m_iDetectorRowCount * m_iDetectorColCount; - ASTRA_DELETE(node); CC.markNodeParsed("DetectorColCount"); // Required: Vectors - node = _cfg.self->getSingleNode("Vectors"); + node = _cfg.self.getSingleNode("Vectors"); ASTRA_CONFIG_CHECK(node, "ParallelVecProjectionGeometry3D", "No Vectors tag specified."); - vector data = node->getContentNumericalArrayDouble(); + vector data = node.getContentNumericalArrayDouble(); CC.markNodeParsed("Vectors"); - ASTRA_DELETE(node); ASTRA_CONFIG_CHECK(data.size() % 12 == 0, "ParallelVecProjectionGeometry3D", "Vectors doesn't consist of 12-tuples."); m_iProjectionAngleCount = data.size() / 12; m_pProjectionAngles = new SPar3DProjection[m_iProjectionAngleCount]; @@ -208,9 +205,9 @@ Config* CParallelVecProjectionGeometry3D::getConfiguration() const Config* cfg = new Config(); cfg->initialize("ProjectionGeometry3D"); - cfg->self->addAttribute("type", "parallel3d_vec"); - cfg->self->addChildNode("DetectorRowCount", m_iDetectorRowCount); - cfg->self->addChildNode("DetectorColCount", m_iDetectorColCount); + cfg->self.addAttribute("type", "parallel3d_vec"); + cfg->self.addChildNode("DetectorRowCount", m_iDetectorRowCount); + cfg->self.addChildNode("DetectorColCount", m_iDetectorColCount); std::string vectors = ""; for (int i = 0; i < m_iProjectionAngleCount; ++i) { @@ -229,7 +226,7 @@ Config* CParallelVecProjectionGeometry3D::getConfiguration() const vectors += boost::lexical_cast(p.fDetVZ); if (i < m_iProjectionAngleCount-1) vectors += ';'; } - cfg->self->addChildNode("Vectors", vectors); + cfg->self.addChildNode("Vectors", vectors); return cfg; } diff --git a/src/ProjectionGeometry2D.cpp b/src/ProjectionGeometry2D.cpp index 89b5fe0..b89605b 100644 --- a/src/ProjectionGeometry2D.cpp +++ b/src/ProjectionGeometry2D.cpp @@ -124,24 +124,21 @@ bool CProjectionGeometry2D::initialize(const Config& _cfg) } // Required: DetectorWidth - XMLNode* node = _cfg.self->getSingleNode("DetectorWidth"); + XMLNode node = _cfg.self.getSingleNode("DetectorWidth"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No DetectorWidth tag specified."); - m_fDetectorWidth = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_fDetectorWidth = boost::lexical_cast(node.getContent()); CC.markNodeParsed("DetectorWidth"); // Required: DetectorCount - node = _cfg.self->getSingleNode("DetectorCount"); + node = _cfg.self.getSingleNode("DetectorCount"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No DetectorCount tag specified."); - m_iDetectorCount = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_iDetectorCount = boost::lexical_cast(node.getContent()); CC.markNodeParsed("DetectorCount"); // Required: ProjectionAngles - node = _cfg.self->getSingleNode("ProjectionAngles"); + node = _cfg.self.getSingleNode("ProjectionAngles"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No ProjectionAngles tag specified."); - vector angles = node->getContentNumericalArray(); - delete node; + vector angles = node.getContentNumericalArray(); m_iProjectionAngleCount = angles.size(); ASTRA_CONFIG_CHECK(m_iProjectionAngleCount > 0, "ProjectionGeometry2D", "Not enough ProjectionAngles specified."); m_pfProjectionAngles = new float32[m_iProjectionAngleCount]; @@ -150,7 +147,7 @@ bool CProjectionGeometry2D::initialize(const Config& _cfg) } CC.markNodeParsed("ProjectionAngles"); - vector offset = _cfg.self->getOptionNumericalArray("ExtraDetectorOffset"); + vector offset = _cfg.self.getOptionNumericalArray("ExtraDetectorOffset"); m_pfExtraDetectorOffset = new float32[m_iProjectionAngleCount]; if (offset.size() == (size_t)m_iProjectionAngleCount) { for (int i = 0; i < m_iProjectionAngleCount; i++) { diff --git a/src/ProjectionGeometry3D.cpp b/src/ProjectionGeometry3D.cpp index 5b77767..ef0246c 100644 --- a/src/ProjectionGeometry3D.cpp +++ b/src/ProjectionGeometry3D.cpp @@ -149,38 +149,34 @@ bool CProjectionGeometry3D::initialize(const Config& _cfg) ASTRA_ASSERT(_cfg.self); // Required: DetectorWidth - XMLNode* node = _cfg.self->getSingleNode("DetectorSpacingX"); + XMLNode node = _cfg.self.getSingleNode("DetectorSpacingX"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorSpacingX tag specified."); - m_fDetectorSpacingX = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_fDetectorSpacingX = boost::lexical_cast(node.getContent()); CC.markNodeParsed("DetectorSpacingX"); // Required: DetectorHeight - node = _cfg.self->getSingleNode("DetectorSpacingY"); + node = _cfg.self.getSingleNode("DetectorSpacingY"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorSpacingY tag specified."); - m_fDetectorSpacingY = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_fDetectorSpacingY = boost::lexical_cast(node.getContent()); CC.markNodeParsed("DetectorSpacingY"); // Required: DetectorRowCount - node = _cfg.self->getSingleNode("DetectorRowCount"); + node = _cfg.self.getSingleNode("DetectorRowCount"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorRowCount tag specified."); - m_iDetectorRowCount = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_iDetectorRowCount = boost::lexical_cast(node.getContent()); CC.markNodeParsed("DetectorRowCount"); // Required: DetectorCount - node = _cfg.self->getSingleNode("DetectorColCount"); + node = _cfg.self.getSingleNode("DetectorColCount"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorColCount tag specified."); - m_iDetectorColCount = boost::lexical_cast(node->getContent()); + m_iDetectorColCount = boost::lexical_cast(node.getContent()); m_iDetectorTotCount = m_iDetectorRowCount * m_iDetectorColCount; - ASTRA_DELETE(node); CC.markNodeParsed("DetectorColCount"); // Required: ProjectionAngles - node = _cfg.self->getSingleNode("ProjectionAngles"); + node = _cfg.self.getSingleNode("ProjectionAngles"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No ProjectionAngles tag specified."); - vector angles = node->getContentNumericalArray(); + vector angles = node.getContentNumericalArray(); m_iProjectionAngleCount = angles.size(); ASTRA_CONFIG_CHECK(m_iProjectionAngleCount > 0, "ProjectionGeometry3D", "Not enough ProjectionAngles specified."); m_pfProjectionAngles = new float32[m_iProjectionAngleCount]; @@ -188,7 +184,6 @@ bool CProjectionGeometry3D::initialize(const Config& _cfg) m_pfProjectionAngles[i] = angles[i]; } CC.markNodeParsed("ProjectionAngles"); - ASTRA_DELETE(node); // Interface class, so don't return true return false; diff --git a/src/Projector2D.cpp b/src/Projector2D.cpp index 32a2956..cf233a0 100644 --- a/src/Projector2D.cpp +++ b/src/Projector2D.cpp @@ -114,12 +114,12 @@ bool CProjector2D::initialize(const Config& _cfg) } // required: ProjectionGeometry - XMLNode* node = _cfg.self->getSingleNode("ProjectionGeometry"); + XMLNode node = _cfg.self.getSingleNode("ProjectionGeometry"); ASTRA_CONFIG_CHECK(node, "Projector2D", "No ProjectionGeometry tag specified."); // FIXME: Change how the base class is created. (This is duplicated // in astra_mex_data2d.cpp.) - std::string type = node->getAttribute("type"); + std::string type = node.getAttribute("type"); if (type == "sparse_matrix") { m_pProjectionGeometry = new CSparseMatrixProjectionGeometry2D(); m_pProjectionGeometry->initialize(Config(node)); @@ -141,7 +141,7 @@ bool CProjector2D::initialize(const Config& _cfg) // required: VolumeGeometry - node = _cfg.self->getSingleNode("VolumeGeometry"); + node = _cfg.self.getSingleNode("VolumeGeometry"); ASTRA_CONFIG_CHECK(node, "Projector2D", "No VolumeGeometry tag specified."); m_pVolumeGeometry = new CVolumeGeometry2D(); m_pVolumeGeometry->initialize(Config(node)); diff --git a/src/Projector3D.cpp b/src/Projector3D.cpp index 14cb16a..5e22105 100644 --- a/src/Projector3D.cpp +++ b/src/Projector3D.cpp @@ -92,11 +92,11 @@ bool CProjector3D::initialize(const Config& _cfg) assert(_cfg.self); ConfigStackCheck CC("Projector3D", this, _cfg); - XMLNode* node; + XMLNode node; - node = _cfg.self->getSingleNode("ProjectionGeometry"); + node = _cfg.self.getSingleNode("ProjectionGeometry"); ASTRA_CONFIG_CHECK(node, "Projector3D", "No ProjectionGeometry tag specified."); - std::string type = node->getAttribute("type"); + std::string type = node.getAttribute("type"); CProjectionGeometry3D* pProjGeometry = 0; if (type == "parallel3d") { pProjGeometry = new CParallelProjectionGeometry3D(); @@ -115,7 +115,7 @@ bool CProjector3D::initialize(const Config& _cfg) ASTRA_CONFIG_CHECK(m_pProjectionGeometry->isInitialized(), "Projector3D", "ProjectionGeometry not initialized."); CC.markNodeParsed("ProjectionGeometry"); - node = _cfg.self->getSingleNode("VolumeGeometry"); + node = _cfg.self.getSingleNode("VolumeGeometry"); ASTRA_CONFIG_CHECK(node, "Projector3D", "No VolumeGeometry tag specified."); CVolumeGeometry3D* pVolGeometry = new CVolumeGeometry3D(); pVolGeometry->initialize(Config(node)); // this deletes node diff --git a/src/ReconstructionAlgorithm2D.cpp b/src/ReconstructionAlgorithm2D.cpp index e089fac..767efe6 100644 --- a/src/ReconstructionAlgorithm2D.cpp +++ b/src/ReconstructionAlgorithm2D.cpp @@ -84,71 +84,68 @@ bool CReconstructionAlgorithm2D::initialize(const Config& _cfg) ConfigStackCheck CC("ReconstructionAlgorithm2D", this, _cfg); // projector - XMLNode* node = _cfg.self->getSingleNode("ProjectorId"); + XMLNode node = _cfg.self.getSingleNode("ProjectorId"); ASTRA_CONFIG_CHECK(node, "Reconstruction2D", "No ProjectorId tag specified."); - int id = boost::lexical_cast(node->getContent()); + int id = boost::lexical_cast(node.getContent()); m_pProjector = CProjector2DManager::getSingleton().get(id); - ASTRA_DELETE(node); CC.markNodeParsed("ProjectorId"); // sinogram data - node = _cfg.self->getSingleNode("ProjectionDataId"); + node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "Reconstruction2D", "No ProjectionDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pSinogram = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("ProjectionDataId"); // reconstruction data - node = _cfg.self->getSingleNode("ReconstructionDataId"); + node = _cfg.self.getSingleNode("ReconstructionDataId"); ASTRA_CONFIG_CHECK(node, "Reconstruction2D", "No ReconstructionDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pReconstruction = dynamic_cast(CData2DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("ReconstructionDataId"); // fixed mask - if (_cfg.self->hasOption("ReconstructionMaskId")) { + if (_cfg.self.hasOption("ReconstructionMaskId")) { m_bUseReconstructionMask = true; - id = boost::lexical_cast(_cfg.self->getOption("ReconstructionMaskId")); + id = boost::lexical_cast(_cfg.self.getOption("ReconstructionMaskId")); m_pReconstructionMask = dynamic_cast(CData2DManager::getSingleton().get(id)); ASTRA_CONFIG_CHECK(m_pReconstructionMask, "Reconstruction2D", "Invalid ReconstructionMaskId."); } CC.markOptionParsed("ReconstructionMaskId"); // fixed mask - if (_cfg.self->hasOption("SinogramMaskId")) { + if (_cfg.self.hasOption("SinogramMaskId")) { m_bUseSinogramMask = true; - id = boost::lexical_cast(_cfg.self->getOption("SinogramMaskId")); + id = boost::lexical_cast(_cfg.self.getOption("SinogramMaskId")); m_pSinogramMask = dynamic_cast(CData2DManager::getSingleton().get(id)); ASTRA_CONFIG_CHECK(m_pSinogramMask, "Reconstruction2D", "Invalid SinogramMaskId."); } CC.markOptionParsed("SinogramMaskId"); // Constraints - NEW - if (_cfg.self->hasOption("MinConstraint")) { + if (_cfg.self.hasOption("MinConstraint")) { m_bUseMinConstraint = true; - m_fMinValue = _cfg.self->getOptionNumerical("MinConstraint", 0.0f); + m_fMinValue = _cfg.self.getOptionNumerical("MinConstraint", 0.0f); CC.markOptionParsed("MinConstraint"); } else { // Constraint - OLD - m_bUseMinConstraint = _cfg.self->getOptionBool("UseMinConstraint", false); + m_bUseMinConstraint = _cfg.self.getOptionBool("UseMinConstraint", false); CC.markOptionParsed("UseMinConstraint"); if (m_bUseMinConstraint) { - m_fMinValue = _cfg.self->getOptionNumerical("MinConstraintValue", 0.0f); + m_fMinValue = _cfg.self.getOptionNumerical("MinConstraintValue", 0.0f); CC.markOptionParsed("MinConstraintValue"); } } - if (_cfg.self->hasOption("MaxConstraint")) { + if (_cfg.self.hasOption("MaxConstraint")) { m_bUseMaxConstraint = true; - m_fMaxValue = _cfg.self->getOptionNumerical("MaxConstraint", 255.0f); + m_fMaxValue = _cfg.self.getOptionNumerical("MaxConstraint", 255.0f); CC.markOptionParsed("MaxConstraint"); } else { // Constraint - OLD - m_bUseMaxConstraint = _cfg.self->getOptionBool("UseMaxConstraint", false); + m_bUseMaxConstraint = _cfg.self.getOptionBool("UseMaxConstraint", false); CC.markOptionParsed("UseMaxConstraint"); if (m_bUseMaxConstraint) { - m_fMaxValue = _cfg.self->getOptionNumerical("MaxConstraintValue", 0.0f); + m_fMaxValue = _cfg.self.getOptionNumerical("MaxConstraintValue", 0.0f); CC.markOptionParsed("MaxConstraintValue"); } } diff --git a/src/ReconstructionAlgorithm3D.cpp b/src/ReconstructionAlgorithm3D.cpp index 13d069d..86b8ab2 100644 --- a/src/ReconstructionAlgorithm3D.cpp +++ b/src/ReconstructionAlgorithm3D.cpp @@ -104,7 +104,7 @@ bool CReconstructionAlgorithm3D::initialize(const Config& _cfg) ASTRA_ASSERT(_cfg.self); ConfigStackCheck CC("ReconstructionAlgorithm3D", this, _cfg); - XMLNode* node; + XMLNode node; int id; #if 0 // projector @@ -116,60 +116,58 @@ bool CReconstructionAlgorithm3D::initialize(const Config& _cfg) #endif // sinogram data - node = _cfg.self->getSingleNode("ProjectionDataId"); + node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "Reconstruction3D", "No ProjectionDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pSinogram = dynamic_cast(CData3DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("ProjectionDataId"); // reconstruction data - node = _cfg.self->getSingleNode("ReconstructionDataId"); + node = _cfg.self.getSingleNode("ReconstructionDataId"); ASTRA_CONFIG_CHECK(node, "Reconstruction3D", "No ReconstructionDataId tag specified."); - id = boost::lexical_cast(node->getContent()); + id = boost::lexical_cast(node.getContent()); m_pReconstruction = dynamic_cast(CData3DManager::getSingleton().get(id)); - ASTRA_DELETE(node); CC.markNodeParsed("ReconstructionDataId"); // fixed mask - if (_cfg.self->hasOption("ReconstructionMaskId")) { + if (_cfg.self.hasOption("ReconstructionMaskId")) { m_bUseReconstructionMask = true; - id = boost::lexical_cast(_cfg.self->getOption("ReconstructionMaskId")); + id = boost::lexical_cast(_cfg.self.getOption("ReconstructionMaskId")); m_pReconstructionMask = dynamic_cast(CData3DManager::getSingleton().get(id)); } CC.markOptionParsed("ReconstructionMaskId"); // fixed mask - if (_cfg.self->hasOption("SinogramMaskId")) { + if (_cfg.self.hasOption("SinogramMaskId")) { m_bUseSinogramMask = true; - id = boost::lexical_cast(_cfg.self->getOption("SinogramMaskId")); + id = boost::lexical_cast(_cfg.self.getOption("SinogramMaskId")); m_pSinogramMask = dynamic_cast(CData3DManager::getSingleton().get(id)); } // Constraints - NEW - if (_cfg.self->hasOption("MinConstraint")) { + if (_cfg.self.hasOption("MinConstraint")) { m_bUseMinConstraint = true; - m_fMinValue = _cfg.self->getOptionNumerical("MinConstraint", 0.0f); + m_fMinValue = _cfg.self.getOptionNumerical("MinConstraint", 0.0f); CC.markOptionParsed("MinConstraint"); } else { // Constraint - OLD - m_bUseMinConstraint = _cfg.self->getOptionBool("UseMinConstraint", false); + m_bUseMinConstraint = _cfg.self.getOptionBool("UseMinConstraint", false); CC.markOptionParsed("UseMinConstraint"); if (m_bUseMinConstraint) { - m_fMinValue = _cfg.self->getOptionNumerical("MinConstraintValue", 0.0f); + m_fMinValue = _cfg.self.getOptionNumerical("MinConstraintValue", 0.0f); CC.markOptionParsed("MinConstraintValue"); } } - if (_cfg.self->hasOption("MaxConstraint")) { + if (_cfg.self.hasOption("MaxConstraint")) { m_bUseMaxConstraint = true; - m_fMaxValue = _cfg.self->getOptionNumerical("MaxConstraint", 255.0f); + m_fMaxValue = _cfg.self.getOptionNumerical("MaxConstraint", 255.0f); CC.markOptionParsed("MaxConstraint"); } else { // Constraint - OLD - m_bUseMaxConstraint = _cfg.self->getOptionBool("UseMaxConstraint", false); + m_bUseMaxConstraint = _cfg.self.getOptionBool("UseMaxConstraint", false); CC.markOptionParsed("UseMaxConstraint"); if (m_bUseMaxConstraint) { - m_fMaxValue = _cfg.self->getOptionNumerical("MaxConstraintValue", 0.0f); + m_fMaxValue = _cfg.self.getOptionNumerical("MaxConstraintValue", 0.0f); CC.markOptionParsed("MaxConstraintValue"); } } diff --git a/src/SartAlgorithm.cpp b/src/SartAlgorithm.cpp index f7a1677..e4dc5c7 100644 --- a/src/SartAlgorithm.cpp +++ b/src/SartAlgorithm.cpp @@ -126,7 +126,7 @@ bool CSartAlgorithm::initialize(const Config& _cfg) // projection order m_iCurrentProjection = 0; m_iProjectionCount = m_pProjector->getProjectionGeometry()->getProjectionAngleCount(); - string projOrder = _cfg.self->getOption("ProjectionOrder", "sequential"); + string projOrder = _cfg.self.getOption("ProjectionOrder", "sequential"); CC.markOptionParsed("ProjectionOrder"); if (projOrder == "sequential") { m_piProjectionOrder = new int[m_iProjectionCount]; @@ -145,7 +145,7 @@ bool CSartAlgorithm::initialize(const Config& _cfg) m_piProjectionOrder[i + k] = t; } } else if (projOrder == "custom") { - vector projOrderList = _cfg.self->getOptionNumericalArray("ProjectionOrderList"); + vector projOrderList = _cfg.self.getOptionNumericalArray("ProjectionOrderList"); m_piProjectionOrder = new int[projOrderList.size()]; for (int i = 0; i < m_iProjectionCount; i++) { m_piProjectionOrder[i] = static_cast(projOrderList[i]); diff --git a/src/SparseMatrixProjectionGeometry2D.cpp b/src/SparseMatrixProjectionGeometry2D.cpp index 86357d2..073720f 100644 --- a/src/SparseMatrixProjectionGeometry2D.cpp +++ b/src/SparseMatrixProjectionGeometry2D.cpp @@ -98,11 +98,10 @@ bool CSparseMatrixProjectionGeometry2D::initialize(const Config& _cfg) CProjectionGeometry2D::initialize(_cfg); // get matrix - XMLNode* node = _cfg.self->getSingleNode("MatrixID"); + XMLNode node = _cfg.self.getSingleNode("MatrixID"); ASTRA_CONFIG_CHECK(node, "SparseMatrixProjectionGeometry2D", "No MatrixID tag specified."); - int id = boost::lexical_cast(node->getContent()); + int id = boost::lexical_cast(node.getContent()); m_pMatrix = CMatrixManager::getSingleton().get(id); - ASTRA_DELETE(node); CC.markNodeParsed("MatrixID"); // success @@ -194,11 +193,11 @@ Config* CSparseMatrixProjectionGeometry2D::getConfiguration() const { Config* cfg = new Config(); cfg->initialize("ProjectionGeometry2D"); - cfg->self->addAttribute("type", "sparse matrix"); - cfg->self->addChildNode("DetectorCount", getDetectorCount()); - cfg->self->addChildNode("DetectorWidth", getDetectorWidth()); - cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); - cfg->self->addChildNode("MatrixID", CMatrixManager::getSingleton().getIndex(m_pMatrix)); + cfg->self.addAttribute("type", "sparse matrix"); + cfg->self.addChildNode("DetectorCount", getDetectorCount()); + cfg->self.addChildNode("DetectorWidth", getDetectorWidth()); + cfg->self.addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); + cfg->self.addChildNode("MatrixID", CMatrixManager::getSingleton().getIndex(m_pMatrix)); return cfg; } diff --git a/src/VolumeGeometry2D.cpp b/src/VolumeGeometry2D.cpp index d412914..6eea1b2 100644 --- a/src/VolumeGeometry2D.cpp +++ b/src/VolumeGeometry2D.cpp @@ -164,24 +164,22 @@ bool CVolumeGeometry2D::initialize(const Config& _cfg) } // Required: GridColCount - XMLNode* node = _cfg.self->getSingleNode("GridColCount"); + XMLNode node = _cfg.self.getSingleNode("GridColCount"); ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridColCount tag specified."); - m_iGridColCount = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_iGridColCount = boost::lexical_cast(node.getContent()); CC.markNodeParsed("GridColCount"); // Required: GridRowCount - node = _cfg.self->getSingleNode("GridRowCount"); + node = _cfg.self.getSingleNode("GridRowCount"); ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridRowCount tag specified."); - m_iGridRowCount = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_iGridRowCount = boost::lexical_cast(node.getContent()); CC.markNodeParsed("GridRowCount"); // Optional: Window minima and maxima - m_fWindowMinX = _cfg.self->getOptionNumerical("WindowMinX", -m_iGridColCount/2.0f); - m_fWindowMaxX = _cfg.self->getOptionNumerical("WindowMaxX", m_iGridColCount/2.0f); - m_fWindowMinY = _cfg.self->getOptionNumerical("WindowMinY", -m_iGridRowCount/2.0f); - m_fWindowMaxY = _cfg.self->getOptionNumerical("WindowMaxY", m_iGridRowCount/2.0f); + m_fWindowMinX = _cfg.self.getOptionNumerical("WindowMinX", -m_iGridColCount/2.0f); + m_fWindowMaxX = _cfg.self.getOptionNumerical("WindowMaxX", m_iGridColCount/2.0f); + m_fWindowMinY = _cfg.self.getOptionNumerical("WindowMinY", -m_iGridRowCount/2.0f); + m_fWindowMaxY = _cfg.self.getOptionNumerical("WindowMaxY", m_iGridRowCount/2.0f); CC.markOptionParsed("WindowMinX"); CC.markOptionParsed("WindowMaxX"); CC.markOptionParsed("WindowMinY"); @@ -285,13 +283,13 @@ Config* CVolumeGeometry2D::getConfiguration() const Config* cfg = new Config(); cfg->initialize("VolumeGeometry2D"); - cfg->self->addChildNode("GridColCount", m_iGridColCount); - cfg->self->addChildNode("GridRowCount", m_iGridRowCount); + cfg->self.addChildNode("GridColCount", m_iGridColCount); + cfg->self.addChildNode("GridRowCount", m_iGridRowCount); - cfg->self->addOption("WindowMinX", m_fWindowMinX); - cfg->self->addOption("WindowMaxX", m_fWindowMaxX); - cfg->self->addOption("WindowMinY", m_fWindowMinY); - cfg->self->addOption("WindowMaxY", m_fWindowMaxY); + cfg->self.addOption("WindowMinX", m_fWindowMinX); + cfg->self.addOption("WindowMaxX", m_fWindowMaxX); + cfg->self.addOption("WindowMinY", m_fWindowMinY); + cfg->self.addOption("WindowMaxY", m_fWindowMaxY); return cfg; } diff --git a/src/VolumeGeometry3D.cpp b/src/VolumeGeometry3D.cpp index 66e6f0c..a1cf424 100644 --- a/src/VolumeGeometry3D.cpp +++ b/src/VolumeGeometry3D.cpp @@ -192,33 +192,30 @@ bool CVolumeGeometry3D::initialize(const Config& _cfg) } // Required: GridColCount - XMLNode* node = _cfg.self->getSingleNode("GridColCount"); + XMLNode node = _cfg.self.getSingleNode("GridColCount"); ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridColCount tag specified."); - m_iGridColCount = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_iGridColCount = boost::lexical_cast(node.getContent()); CC.markNodeParsed("GridColCount"); // Required: GridRowCount - node = _cfg.self->getSingleNode("GridRowCount"); + node = _cfg.self.getSingleNode("GridRowCount"); ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridRowCount tag specified."); - m_iGridRowCount = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_iGridRowCount = boost::lexical_cast(node.getContent()); CC.markNodeParsed("GridRowCount"); // Required: GridRowCount - node = _cfg.self->getSingleNode("GridSliceCount"); + node = _cfg.self.getSingleNode("GridSliceCount"); ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridSliceCount tag specified."); - m_iGridSliceCount = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_iGridSliceCount = boost::lexical_cast(node.getContent()); CC.markNodeParsed("GridSliceCount"); // Optional: Window minima and maxima - m_fWindowMinX = _cfg.self->getOptionNumerical("WindowMinX", -m_iGridColCount/2.0f); - m_fWindowMaxX = _cfg.self->getOptionNumerical("WindowMaxX", m_iGridColCount/2.0f); - m_fWindowMinY = _cfg.self->getOptionNumerical("WindowMinY", -m_iGridRowCount/2.0f); - m_fWindowMaxY = _cfg.self->getOptionNumerical("WindowMaxY", m_iGridRowCount/2.0f); - m_fWindowMinZ = _cfg.self->getOptionNumerical("WindowMinZ", -m_iGridSliceCount/2.0f); - m_fWindowMaxZ = _cfg.self->getOptionNumerical("WindowMaxZ", m_iGridSliceCount/2.0f); + m_fWindowMinX = _cfg.self.getOptionNumerical("WindowMinX", -m_iGridColCount/2.0f); + m_fWindowMaxX = _cfg.self.getOptionNumerical("WindowMaxX", m_iGridColCount/2.0f); + m_fWindowMinY = _cfg.self.getOptionNumerical("WindowMinY", -m_iGridRowCount/2.0f); + m_fWindowMaxY = _cfg.self.getOptionNumerical("WindowMaxY", m_iGridRowCount/2.0f); + m_fWindowMinZ = _cfg.self.getOptionNumerical("WindowMinZ", -m_iGridSliceCount/2.0f); + m_fWindowMaxZ = _cfg.self.getOptionNumerical("WindowMaxZ", m_iGridSliceCount/2.0f); CC.markOptionParsed("WindowMinX"); CC.markOptionParsed("WindowMaxX"); CC.markOptionParsed("WindowMinY"); @@ -386,16 +383,16 @@ Config* CVolumeGeometry3D::getConfiguration() const Config* cfg = new Config(); cfg->initialize("VolumeGeometry3D"); - cfg->self->addChildNode("GridColCount", m_iGridColCount); - cfg->self->addChildNode("GridRowCount", m_iGridRowCount); - cfg->self->addChildNode("GridSliceCount", m_iGridSliceCount); + cfg->self.addChildNode("GridColCount", m_iGridColCount); + cfg->self.addChildNode("GridRowCount", m_iGridRowCount); + cfg->self.addChildNode("GridSliceCount", m_iGridSliceCount); - cfg->self->addOption("WindowMinX", m_fWindowMinX); - cfg->self->addOption("WindowMaxX", m_fWindowMaxX); - cfg->self->addOption("WindowMinY", m_fWindowMinY); - cfg->self->addOption("WindowMaxY", m_fWindowMaxY); - cfg->self->addOption("WindowMinZ", m_fWindowMinZ); - cfg->self->addOption("WindowMaxZ", m_fWindowMaxZ); + cfg->self.addOption("WindowMinX", m_fWindowMinX); + cfg->self.addOption("WindowMaxX", m_fWindowMaxX); + cfg->self.addOption("WindowMinY", m_fWindowMinY); + cfg->self.addOption("WindowMaxY", m_fWindowMaxY); + cfg->self.addOption("WindowMinZ", m_fWindowMinZ); + cfg->self.addOption("WindowMaxZ", m_fWindowMaxZ); return cfg; } diff --git a/src/XMLDocument.cpp b/src/XMLDocument.cpp index da843b4..716ed9e 100644 --- a/src/XMLDocument.cpp +++ b/src/XMLDocument.cpp @@ -89,10 +89,9 @@ XMLDocument* XMLDocument::createDocument(string sRootName) } //----------------------------------------------------------------------------- -XMLNode* XMLDocument::getRootNode() +XMLNode XMLDocument::getRootNode() { - // TODO: clean up: this 'new' requires callers to do memory management - return new XMLNode(fDOMDocument->first_node()); + return XMLNode(fDOMDocument->first_node()); } //----------------------------------------------------------------------------- diff --git a/src/XMLNode.cpp b/src/XMLNode.cpp index 5e9d927..75985cc 100644 --- a/src/XMLNode.cpp +++ b/src/XMLNode.cpp @@ -38,22 +38,11 @@ using namespace astra; using namespace std; -//----------------------------------------------------------------------------- -// Utility function to delete a list of nodes -static void deleteNodes(list& nodes) -{ - for (list::iterator i = nodes.begin(); i != nodes.end(); ++i) - delete (*i); - - nodes.clear(); -} - - //----------------------------------------------------------------------------- // default constructor XMLNode::XMLNode() { - + fDOMElement = 0; } //----------------------------------------------------------------------------- @@ -79,14 +68,14 @@ void XMLNode::setDOMNode(xml_node<>* n) //----------------------------------------------------------------------------- // print XML Node -void XMLNode::print() +void XMLNode::print() const { std::cout << fDOMElement; } //----------------------------------------------------------------------------- // print XML Node -std::string XMLNode::toString() +std::string XMLNode::toString() const { std::string s; ::print(std::back_inserter(s), *fDOMElement, 0); @@ -95,64 +84,61 @@ std::string XMLNode::toString() //----------------------------------------------------------------------------- // Get single node -XMLNode* XMLNode::getSingleNode(string name) +XMLNode XMLNode::getSingleNode(string name) const { xml_node<> *node = fDOMElement->first_node(name.c_str()); - if (node) - return new XMLNode(node); - else - return 0; + return XMLNode(node); } //----------------------------------------------------------------------------- // Get list of nodes -list XMLNode::getNodes(string name) +list XMLNode::getNodes(string name) const { - list result; + list result; xml_node<> *iter; for (iter = fDOMElement->first_node(name.c_str()); iter; iter = iter->next_sibling(name.c_str())) { - result.push_back(new XMLNode(iter)); + result.push_back(XMLNode(iter)); } return result; } //----------------------------------------------------------------------------- // Get list of nodes -list XMLNode::getNodes() +list XMLNode::getNodes() const { - list result; + list result; xml_node<> *iter; for (iter = fDOMElement->first_node(); iter; iter = iter->next_sibling()) { - result.push_back(new XMLNode(iter)); + result.push_back(XMLNode(iter)); } return result; } //----------------------------------------------------------------------------- // Get name of this node -std::string XMLNode::getName() +std::string XMLNode::getName() const { return fDOMElement->name(); } //----------------------------------------------------------------------------- // Get node content - STRING -string XMLNode::getContent() +string XMLNode::getContent() const { return fDOMElement->value(); } //----------------------------------------------------------------------------- // Get node content - NUMERICAL -float32 XMLNode::getContentNumerical() +float32 XMLNode::getContentNumerical() const { return boost::lexical_cast(getContent()); } //----------------------------------------------------------------------------- // Get node content - BOOLEAN -bool XMLNode::getContentBool() +bool XMLNode::getContentBool() const { string res = getContent(); return ((res == "1") || (res == "yes") || (res == "true") || (res == "on")); @@ -160,21 +146,20 @@ bool XMLNode::getContentBool() //----------------------------------------------------------------------------- // Get node content - STRING LIST -vector XMLNode::getContentArray() +vector XMLNode::getContentArray() const { // get listsize int iSize = boost::lexical_cast(getAttribute("listsize")); // create result array vector res(iSize); // loop all list item nodes - list nodes = getNodes("ListItem"); - for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { - int iIndex = (*it)->getAttributeNumerical("index"); - string sValue = (*it)->getAttribute("value"); + list nodes = getNodes("ListItem"); + for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { + int iIndex = it->getAttributeNumerical("index"); + string sValue = it->getAttribute("value"); ASTRA_ASSERT(iIndex < iSize); res[iIndex] = sValue; } - deleteNodes(nodes); // return return res; @@ -182,7 +167,7 @@ vector XMLNode::getContentArray() //----------------------------------------------------------------------------- // Get node content - NUMERICAL LIST -vector XMLNode::getContentNumericalArray() +vector XMLNode::getContentNumericalArray() const { // is scalar if (!hasAttribute("listsize")) { @@ -195,19 +180,18 @@ vector XMLNode::getContentNumericalArray() // create result array vector res(iSize); // loop all list item nodes - list nodes = getNodes("ListItem"); - for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { - int iIndex = (*it)->getAttributeNumerical("index"); - float32 fValue = (*it)->getAttributeNumerical("value"); + list nodes = getNodes("ListItem"); + for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { + int iIndex = it->getAttributeNumerical("index"); + float32 fValue = it->getAttributeNumerical("value"); ASTRA_ASSERT(iIndex < iSize); res[iIndex] = fValue; } - deleteNodes(nodes); // return return res; } -vector XMLNode::getContentNumericalArrayDouble() +vector XMLNode::getContentNumericalArrayDouble() const { // is scalar if (!hasAttribute("listsize")) { @@ -220,21 +204,20 @@ vector XMLNode::getContentNumericalArrayDouble() // create result array vector res(iSize); // loop all list item nodes - list nodes = getNodes("ListItem"); - for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { - int iIndex = (*it)->getAttributeNumerical("index"); - double fValue = (*it)->getAttributeNumericalDouble("value"); + list nodes = getNodes("ListItem"); + for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { + int iIndex = it->getAttributeNumerical("index"); + double fValue = it->getAttributeNumericalDouble("value"); ASTRA_ASSERT(iIndex < iSize); res[iIndex] = fValue; } - deleteNodes(nodes); // return return res; } //----------------------------------------------------------------------------- // Get node content - NUMERICAL LIST 2 -void XMLNode::getContentNumericalArray(float32*& _pfData, int& _iSize) +void XMLNode::getContentNumericalArray(float32*& _pfData, int& _iSize) const { // is scalar if (!hasAttribute("listsize")) { @@ -248,19 +231,18 @@ void XMLNode::getContentNumericalArray(float32*& _pfData, int& _iSize) // create result array _pfData = new float32[_iSize]; // loop all list item nodes - list nodes = getNodes("ListItem"); - for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { - int iIndex = (*it)->getAttributeNumerical("index"); - float32 fValue = (*it)->getAttributeNumerical("value"); + list nodes = getNodes("ListItem"); + for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { + int iIndex = it->getAttributeNumerical("index"); + float32 fValue = it->getAttributeNumerical("value"); ASTRA_ASSERT(iIndex < _iSize); _pfData[iIndex] = fValue; } - deleteNodes(nodes); } //----------------------------------------------------------------------------- // Is attribute? -bool XMLNode::hasAttribute(string _sName) +bool XMLNode::hasAttribute(string _sName) const { xml_attribute<> *attr = fDOMElement->first_attribute(_sName.c_str()); return (attr != 0); @@ -268,7 +250,7 @@ bool XMLNode::hasAttribute(string _sName) //----------------------------------------------------------------------------- // Get attribute - STRING -string XMLNode::getAttribute(string _sName, string _sDefaultValue) +string XMLNode::getAttribute(string _sName, string _sDefaultValue) const { xml_attribute<> *attr = fDOMElement->first_attribute(_sName.c_str()); @@ -279,12 +261,12 @@ string XMLNode::getAttribute(string _sName, string _sDefaultValue) //----------------------------------------------------------------------------- // Get attribute - NUMERICAL -float32 XMLNode::getAttributeNumerical(string _sName, float32 _fDefaultValue) +float32 XMLNode::getAttributeNumerical(string _sName, float32 _fDefaultValue) const { if (!hasAttribute(_sName)) return _fDefaultValue; return boost::lexical_cast(getAttribute(_sName)); } -double XMLNode::getAttributeNumericalDouble(string _sName, double _fDefaultValue) +double XMLNode::getAttributeNumericalDouble(string _sName, double _fDefaultValue) const { if (!hasAttribute(_sName)) return _fDefaultValue; return boost::lexical_cast(getAttribute(_sName)); @@ -292,7 +274,7 @@ double XMLNode::getAttributeNumericalDouble(string _sName, double _fDefaultValue //----------------------------------------------------------------------------- // Get attribute - BOOLEAN -bool XMLNode::getAttributeBool(string _sName, bool _bDefaultValue) +bool XMLNode::getAttributeBool(string _sName, bool _bDefaultValue) const { if (!hasAttribute(_sName)) return _bDefaultValue; string res = getAttribute(_sName); @@ -301,7 +283,7 @@ bool XMLNode::getAttributeBool(string _sName, bool _bDefaultValue) //----------------------------------------------------------------------------- // Has option? -bool XMLNode::hasOption(string _sKey) +bool XMLNode::hasOption(string _sKey) const { xml_node<> *iter; for (iter = fDOMElement->first_node("Option"); iter; iter = iter->next_sibling("Option")) { @@ -314,7 +296,7 @@ bool XMLNode::hasOption(string _sKey) //----------------------------------------------------------------------------- // Get option - STRING -string XMLNode::getOption(string _sKey, string _sDefaultValue) +string XMLNode::getOption(string _sKey, string _sDefaultValue) const { xml_node<> *iter; for (iter = fDOMElement->first_node("Option"); iter; iter = iter->next_sibling("Option")) { @@ -331,7 +313,7 @@ string XMLNode::getOption(string _sKey, string _sDefaultValue) //----------------------------------------------------------------------------- // Get option - NUMERICAL -float32 XMLNode::getOptionNumerical(string _sKey, float32 _fDefaultValue) +float32 XMLNode::getOptionNumerical(string _sKey, float32 _fDefaultValue) const { if (!hasOption(_sKey)) return _fDefaultValue; return boost::lexical_cast(getOption(_sKey)); @@ -339,7 +321,7 @@ float32 XMLNode::getOptionNumerical(string _sKey, float32 _fDefaultValue) //----------------------------------------------------------------------------- // Get option - BOOL -bool XMLNode::getOptionBool(string _sKey, bool _bDefaultValue) +bool XMLNode::getOptionBool(string _sKey, bool _bDefaultValue) const { bool bHasOption = hasOption(_sKey); if (!bHasOption) return _bDefaultValue; @@ -349,20 +331,18 @@ bool XMLNode::getOptionBool(string _sKey, bool _bDefaultValue) //----------------------------------------------------------------------------- // Get option - NUMERICAL ARRAY -vector XMLNode::getOptionNumericalArray(string _sKey) +vector XMLNode::getOptionNumericalArray(string _sKey) const { if (!hasOption(_sKey)) return vector(); - list nodes = getNodes("Option"); - for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { - if ((*it)->getAttribute("key") == _sKey) { - vector vals = (*it)->getContentNumericalArray(); - deleteNodes(nodes); + list nodes = getNodes("Option"); + for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { + if (it->getAttribute("key") == _sKey) { + vector vals = it->getContentNumericalArray(); return vals; } } - deleteNodes(nodes); return vector(); } @@ -385,41 +365,40 @@ vector XMLNode::getOptionNumericalArray(string _sKey) //----------------------------------------------------------------------------- // Add child node - EMPTY -XMLNode* XMLNode::addChildNode(string _sNodeName) +XMLNode XMLNode::addChildNode(string _sNodeName) { xml_document<> *doc = fDOMElement->document(); char *node_name = doc->allocate_string(_sNodeName.c_str()); xml_node<> *node = doc->allocate_node(node_element, node_name); fDOMElement->append_node(node); - // TODO: clean up: this 'new' requires callers to do memory management - return new XMLNode(node); + return XMLNode(node); } //----------------------------------------------------------------------------- // Add child node - STRING -XMLNode* XMLNode::addChildNode(string _sNodeName, string _sText) +XMLNode XMLNode::addChildNode(string _sNodeName, string _sText) { - XMLNode* res = addChildNode(_sNodeName); - res->setContent(_sText); + XMLNode res = addChildNode(_sNodeName); + res.setContent(_sText); return res; } //----------------------------------------------------------------------------- // Add child node - FLOAT -XMLNode* XMLNode::addChildNode(string _sNodeName, float32 _fValue) +XMLNode XMLNode::addChildNode(string _sNodeName, float32 _fValue) { - XMLNode* res = addChildNode(_sNodeName); - res->setContent(_fValue); + XMLNode res = addChildNode(_sNodeName); + res.setContent(_fValue); return res; } //----------------------------------------------------------------------------- // Add child node - LIST -XMLNode* XMLNode::addChildNode(string _sNodeName, float32* _pfList, int _iSize) +XMLNode XMLNode::addChildNode(string _sNodeName, float32* _pfList, int _iSize) { - XMLNode* res = addChildNode(_sNodeName); - res->setContent(_pfList, _iSize); + XMLNode res = addChildNode(_sNodeName); + res.setContent(_pfList, _iSize); return res; } @@ -472,20 +451,18 @@ void XMLNode::addAttribute(string _sName, float32 _fValue) // Add option - STRING void XMLNode::addOption(string _sName, string _sText) { - XMLNode* node = addChildNode("Option"); - node->addAttribute("key", _sName); - node->addAttribute("value", _sText); - delete node; + XMLNode node = addChildNode("Option"); + node.addAttribute("key", _sName); + node.addAttribute("value", _sText); } //----------------------------------------------------------------------------- // Add option - FLOAT void XMLNode::addOption(string _sName, float32 _sText) { - XMLNode* node = addChildNode("Option"); - node->addAttribute("key", _sName); - node->addAttribute("value", _sText); - delete node; + XMLNode node = addChildNode("Option"); + node.addAttribute("key", _sName); + node.addAttribute("value", _sText); } //----------------------------------------------------------------------------- diff --git a/tests/test_XMLDocument.cpp b/tests/test_XMLDocument.cpp index adabdd6..07abee3 100644 --- a/tests/test_XMLDocument.cpp +++ b/tests/test_XMLDocument.cpp @@ -38,12 +38,12 @@ BOOST_AUTO_TEST_CASE( testXMLDocument_Constructor1 ) astra::XMLDocument *doc = astra::XMLDocument::createDocument("test"); BOOST_REQUIRE(doc); - astra::XMLNode *root = doc->getRootNode(); + astra::XMLNode root = doc->getRootNode(); BOOST_REQUIRE(root); - BOOST_CHECK(root->getName() == "test"); - BOOST_CHECK(root->getContent().empty()); + BOOST_CHECK(root.getName() == "test"); + BOOST_CHECK(root.getContent().empty()); } BOOST_AUTO_TEST_CASE( testXMLDocument_FileIO ) @@ -53,12 +53,12 @@ BOOST_AUTO_TEST_CASE( testXMLDocument_FileIO ) doc->saveToFile("test.xml"); astra::XMLDocument *doc2 = astra::XMLDocument::readFromFile("test.xml"); - astra::XMLNode *root = doc2->getRootNode(); + astra::XMLNode root = doc2->getRootNode(); BOOST_REQUIRE(root); - BOOST_CHECK(root->getName() == "test"); - BOOST_CHECK(root->getContent().empty()); + BOOST_CHECK(root.getName() == "test"); + BOOST_CHECK(root.getContent().empty()); } @@ -67,32 +67,28 @@ BOOST_AUTO_TEST_CASE( testXMLDocument_CreateNodes ) astra::XMLDocument *doc = astra::XMLDocument::createDocument("test"); BOOST_REQUIRE(doc); - astra::XMLNode *root = doc->getRootNode(); + astra::XMLNode root = doc->getRootNode(); BOOST_REQUIRE(root); - astra::XMLNode *node = root->addChildNode("child"); + astra::XMLNode node = root.addChildNode("child"); BOOST_REQUIRE(node); - node->addAttribute("attr", "val"); + node.addAttribute("attr", "val"); doc->saveToFile("test2.xml"); - delete node; - delete root; delete doc; doc = astra::XMLDocument::readFromFile("test2.xml"); BOOST_REQUIRE(doc); root = doc->getRootNode(); BOOST_REQUIRE(node); - node = root->getSingleNode("child"); + node = root.getSingleNode("child"); BOOST_REQUIRE(node); - BOOST_CHECK(node->hasAttribute("attr")); - BOOST_CHECK(node->getAttribute("attr") == "val"); + BOOST_CHECK(node.hasAttribute("attr")); + BOOST_CHECK(node.getAttribute("attr") == "val"); - delete node; - delete root; delete doc; } @@ -101,16 +97,16 @@ BOOST_AUTO_TEST_CASE( testXMLDocument_Options ) astra::XMLDocument *doc = astra::XMLDocument::createDocument("test"); BOOST_REQUIRE(doc); - astra::XMLNode *root = doc->getRootNode(); + astra::XMLNode root = doc->getRootNode(); BOOST_REQUIRE(root); - BOOST_CHECK(!root->hasOption("opt")); + BOOST_CHECK(!root.hasOption("opt")); - root->addOption("opt", "val"); + root.addOption("opt", "val"); - BOOST_CHECK(root->hasOption("opt")); + BOOST_CHECK(root.hasOption("opt")); - BOOST_CHECK(root->getOption("opt") == "val"); + BOOST_CHECK(root.getOption("opt") == "val"); } @@ -119,39 +115,35 @@ BOOST_AUTO_TEST_CASE( testXMLDocument_List ) astra::XMLDocument *doc = astra::XMLDocument::createDocument("test"); BOOST_REQUIRE(doc); - astra::XMLNode *root = doc->getRootNode(); + astra::XMLNode root = doc->getRootNode(); BOOST_REQUIRE(root); - astra::XMLNode *node = root->addChildNode("child"); + astra::XMLNode node = root.addChildNode("child"); BOOST_REQUIRE(node); float fl[] = { 1.0, 3.5, 2.0, 4.75 }; - node->setContent(fl, sizeof(fl)/sizeof(fl[0])); + node.setContent(fl, sizeof(fl)/sizeof(fl[0])); doc->saveToFile("test3.xml"); - delete node; - delete root; delete doc; doc = astra::XMLDocument::readFromFile("test3.xml"); BOOST_REQUIRE(doc); root = doc->getRootNode(); BOOST_REQUIRE(root); - node = root->getSingleNode("child"); + node = root.getSingleNode("child"); BOOST_REQUIRE(node); - std::vector f = node->getContentNumericalArray(); + std::vector f = node.getContentNumericalArray(); BOOST_CHECK(f[0] == fl[0]); BOOST_CHECK(f[1] == fl[1]); BOOST_CHECK(f[2] == fl[2]); BOOST_CHECK(f[3] == fl[3]); - delete node; - delete root; delete doc; } -- cgit v1.2.3 From fff7470f1d74b0085355130350fa834ea8d37069 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Wed, 6 May 2015 13:50:11 +0200 Subject: Make XML array handling consistent setContent and getContent were using different XML formats previously. --- include/astra/XMLNode.h | 35 +++++++--- matlab/mex/mexHelpFunctions.cpp | 22 +----- python/astra/PyXMLDocument.pxd | 2 + python/astra/utils.pyx | 35 +++------- src/XMLNode.cpp | 150 +++++++++++++++++++++++----------------- 5 files changed, 127 insertions(+), 117 deletions(-) (limited to 'include') diff --git a/include/astra/XMLNode.h b/include/astra/XMLNode.h index f79c1a8..4d29d5c 100644 --- a/include/astra/XMLNode.h +++ b/include/astra/XMLNode.h @@ -119,14 +119,8 @@ public: */ vector getContentArray() const; - /** Get the content of the XML node as a c-array of float32 data. - * - * @param _pfData data array, shouldn't be initialized already. - * @param _iSize number of elements stored in _pfData - */ - void getContentNumericalArray(float32*& _pfData, int& _iSize) const; - /** Get the content of the XML node as a stl container of float32 data. + * NB: A 2D matrix is returned as a linear list * * @return node content */ @@ -259,13 +253,38 @@ public: */ void setContent(float32 _fValue); - /** Add a list of numerical data to the node: <...>_sText</...> + /** Add a list of numerical data to the node * * @param _pfList data * @param _iSize number of elements in the list */ void setContent(float32* _pfList, int _iSize); + /** Add a list of numerical data to the node + * + * @param _pfList data + * @param _iSize number of elements in the list + */ + void setContent(double* _pfList, int _iSize); + + /** Add a (2D) matrix of numerical data to the node + * + * @param _pfMatrix data + * @param _iWidth width of the matrix + * @param _iHeight height of the matrix + * @param transposed true is C order, false is Fortran order + */ + void setContent(float32* _pfMatrix, int _iWidth, int _iHeight, bool transposed); + + /** Add a (2D) matrix of numerical data to the node + * + * @param _pfMatrix data + * @param _iWidth width of the matrix + * @param _iHeight height of the matrix + * @param transposed true is C order, false is Fortran order + */ + void setContent(double* _pfMatrix, int _iWidth, int _iHeight, bool transposed); + /** Add an attribute to this node: <... _sName="_sValue"> * * @param _sName name of the attribute diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp index 00d766f..87a9672 100644 --- a/matlab/mex/mexHelpFunctions.cpp +++ b/matlab/mex/mexHelpFunctions.cpp @@ -218,17 +218,8 @@ bool structToXMLNode(XMLNode node, const mxArray* pStruct) return false; } XMLNode listbase = node.addChildNode(sFieldName); - listbase.addAttribute("listsize", mxGetM(pField)*mxGetN(pField)); double* pdValues = mxGetPr(pField); - int index = 0; - for (unsigned int row = 0; row < mxGetM(pField); row++) { - for (unsigned int col = 0; col < mxGetN(pField); col++) { - XMLNode item = listbase.addChildNode("ListItem"); - item.addAttribute("index", index); - item.addAttribute("value", pdValues[col*mxGetM(pField)+row]); - index++; - } - } + listbase.setContent(pdValues, mxGetN(pField), mxGetM(pField), true); } // not castable to a single string @@ -278,17 +269,8 @@ bool optionsToXMLNode(XMLNode node, const mxArray* pOptionStruct) XMLNode listbase = node.addChildNode("Option"); listbase.addAttribute("key", sFieldName); - listbase.addAttribute("listsize", mxGetM(pField)*mxGetN(pField)); double* pdValues = mxGetPr(pField); - int index = 0; - for (unsigned int row = 0; row < mxGetM(pField); row++) { - for (unsigned int col = 0; col < mxGetN(pField); col++) { - XMLNode item = listbase.addChildNode("ListItem"); - item.addAttribute("index", index); - item.addAttribute("value", pdValues[col*mxGetM(pField)+row]); - index++; - } - } + listbase.setContent(pdValues, mxGetN(pField), mxGetM(pField), true); } else { mexErrMsgTxt("Unsupported option type"); return false; diff --git a/python/astra/PyXMLDocument.pxd b/python/astra/PyXMLDocument.pxd index 57c447e..033b8ef 100644 --- a/python/astra/PyXMLDocument.pxd +++ b/python/astra/PyXMLDocument.pxd @@ -53,6 +53,8 @@ cdef extern from "astra/XMLNode.h" namespace "astra": string getAttribute(string) list[XMLNode] getNodes() vector[float32] getContentNumericalArray() + void setContent(double*, int, int, bool) + void setContent(double*, int) string getContent() bool hasAttribute(string) diff --git a/python/astra/utils.pyx b/python/astra/utils.pyx index 8f1e0b7..ddb37aa 100644 --- a/python/astra/utils.pyx +++ b/python/astra/utils.pyx @@ -26,6 +26,7 @@ # distutils: language = c++ # distutils: libraries = astra +cimport numpy as np import numpy as np import six from libcpp.string cimport string @@ -85,6 +86,7 @@ cdef void readDict(XMLNode root, _dc): cdef XMLNode itm cdef int i cdef int j + cdef double* data dc = convert_item(_dc) for item in dc: @@ -93,21 +95,11 @@ cdef void readDict(XMLNode root, _dc): if val.size == 0: break listbase = root.addChildNode(item) - listbase.addAttribute(< string > six.b('listsize'), < float32 > val.size) - index = 0 + data = np.PyArray_DATA(np.ascontiguousarray(val,dtype=np.float64)) if val.ndim == 2: - for i in range(val.shape[0]): - for j in range(val.shape[1]): - itm = listbase.addChildNode(six.b('ListItem')) - itm.addAttribute(< string > six.b('index'), < float32 > index) - itm.addAttribute( < string > six.b('value'), < float32 > val[i, j]) - index += 1 + listbase.setContent(data, val.shape[1], val.shape[0], False) elif val.ndim == 1: - for i in range(val.shape[0]): - itm = listbase.addChildNode(six.b('ListItem')) - itm.addAttribute(< string > six.b('index'), < float32 > index) - itm.addAttribute(< string > six.b('value'), < float32 > val[i]) - index += 1 + listbase.setContent(data, val.shape[0]) else: raise Exception("Only 1 or 2 dimensions are allowed") elif isinstance(val, dict): @@ -127,6 +119,7 @@ cdef void readOptions(XMLNode node, dc): cdef XMLNode itm cdef int i cdef int j + cdef double* data for item in dc: val = dc[item] if node.hasOption(item): @@ -136,21 +129,11 @@ cdef void readOptions(XMLNode node, dc): break listbase = node.addChildNode(six.b('Option')) listbase.addAttribute(< string > six.b('key'), < string > item) - listbase.addAttribute(< string > six.b('listsize'), < float32 > val.size) - index = 0 + data = np.PyArray_DATA(np.ascontiguousarray(val,dtype=np.float64)) if val.ndim == 2: - for i in range(val.shape[0]): - for j in range(val.shape[1]): - itm = listbase.addChildNode(six.b('ListItem')) - itm.addAttribute(< string > six.b('index'), < float32 > index) - itm.addAttribute( < string > six.b('value'), < float32 > val[i, j]) - index += 1 + listbase.setContent(data, val.shape[1], val.shape[0], False) elif val.ndim == 1: - for i in range(val.shape[0]): - itm = listbase.addChildNode(six.b('ListItem')) - itm.addAttribute(< string > six.b('index'), < float32 > index) - itm.addAttribute(< string > six.b('value'), < float32 > val[i]) - index += 1 + listbase.setContent(data, val.shape[0]) else: raise Exception("Only 1 or 2 dimensions are allowed") else: diff --git a/src/XMLNode.cpp b/src/XMLNode.cpp index 75985cc..0ec701f 100644 --- a/src/XMLNode.cpp +++ b/src/XMLNode.cpp @@ -32,6 +32,11 @@ $Id$ #include "rapidxml/rapidxml_print.hpp" #include +#include +#include +#include + + using namespace rapidxml; using namespace astra; @@ -167,77 +172,43 @@ vector XMLNode::getContentArray() const //----------------------------------------------------------------------------- // Get node content - NUMERICAL LIST +// NB: A 2D matrix is returned as a linear list vector XMLNode::getContentNumericalArray() const { - // is scalar - if (!hasAttribute("listsize")) { - vector res(1); - res[0] = getContentNumerical(); - return res; - } + string input = getContent(); - int iSize = boost::lexical_cast(getAttribute("listsize")); - // create result array - vector res(iSize); - // loop all list item nodes - list nodes = getNodes("ListItem"); - for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { - int iIndex = it->getAttributeNumerical("index"); - float32 fValue = it->getAttributeNumerical("value"); - ASTRA_ASSERT(iIndex < iSize); - res[iIndex] = fValue; + // split + std::vector items; + boost::split(items, input, boost::is_any_of(",;")); + + // init list + vector out; + out.resize(items.size()); + + // loop elements + for (unsigned int i = 0; i < items.size(); i++) { + out[i] = boost::lexical_cast(items[i]); } - // return - return res; + return out; } vector XMLNode::getContentNumericalArrayDouble() const { - // is scalar - if (!hasAttribute("listsize")) { - vector res(1); - res[0] = getContentNumerical(); - return res; - } + string input = getContent(); - int iSize = boost::lexical_cast(getAttribute("listsize")); - // create result array - vector res(iSize); - // loop all list item nodes - list nodes = getNodes("ListItem"); - for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { - int iIndex = it->getAttributeNumerical("index"); - double fValue = it->getAttributeNumericalDouble("value"); - ASTRA_ASSERT(iIndex < iSize); - res[iIndex] = fValue; - } - // return - return res; -} + // split + std::vector items; + boost::split(items, input, boost::is_any_of(",;")); -//----------------------------------------------------------------------------- -// Get node content - NUMERICAL LIST 2 -void XMLNode::getContentNumericalArray(float32*& _pfData, int& _iSize) const -{ - // is scalar - if (!hasAttribute("listsize")) { - _iSize = 1; - _pfData = new float32[_iSize]; - _pfData[0] = getContentNumerical(); - return; - } - // get listsize - _iSize = boost::lexical_cast(getAttribute("listsize")); - // create result array - _pfData = new float32[_iSize]; - // loop all list item nodes - list nodes = getNodes("ListItem"); - for (list::iterator it = nodes.begin(); it != nodes.end(); it++) { - int iIndex = it->getAttributeNumerical("index"); - float32 fValue = it->getAttributeNumerical("value"); - ASTRA_ASSERT(iIndex < _iSize); - _pfData[iIndex] = fValue; + // init list + vector out; + out.resize(items.size()); + + // loop elements + for (unsigned int i = 0; i < items.size(); i++) { + out[i] = boost::lexical_cast(items[i]); } + return out; } //----------------------------------------------------------------------------- @@ -420,15 +391,68 @@ void XMLNode::setContent(float32 _fValue) //----------------------------------------------------------------------------- // Set content - LIST -void XMLNode::setContent(float32* pfList, int _iSize) -{ + +template +static std::string setContentList_internal(T* pfList, int _iSize) { std::string str = (_iSize > 0) ? boost::lexical_cast(pfList[0]) : ""; for (int i = 1; i < _iSize; i++) { str += "," + boost::lexical_cast(pfList[i]); } - setContent(str); + return str; +} + +void XMLNode::setContent(float32* pfList, int _iSize) +{ + setContent(setContentList_internal(pfList, _iSize)); +} + +void XMLNode::setContent(double* pfList, int _iSize) +{ + setContent(setContentList_internal(pfList, _iSize)); } +//----------------------------------------------------------------------------- +// Set content - MATRIX + +template +static std::string setContentMatrix_internal(T* _pfMatrix, int _iWidth, int _iHeight, bool transposed) +{ + std::string str = ""; + + int s1,s2; + + if (!transposed) { + s1 = 1; + s2 = _iWidth; + } else { + s1 = _iHeight; + s2 = 1; + } + + for (int y = 0; y < _iHeight; ++y) { + if (_iWidth > 0) + str += boost::lexical_cast(_pfMatrix[0*s1 + y*s2]); + for (int x = 1; x < _iWidth; x++) + str += "," + boost::lexical_cast(_pfMatrix[x*s1 + y*s2]); + + if (y != _iHeight-1) + str += ";"; + } + + return str; +} + +void XMLNode::setContent(float32* _pfMatrix, int _iWidth, int _iHeight, bool transposed) +{ + setContent(setContentMatrix_internal(_pfMatrix, _iWidth, _iHeight, transposed)); +} + +void XMLNode::setContent(double* _pfMatrix, int _iWidth, int _iHeight, bool transposed) +{ + setContent(setContentMatrix_internal(_pfMatrix, _iWidth, _iHeight, transposed)); +} + + //----------------------------------------------------------------------------- // Add attribute - STRING void XMLNode::addAttribute(string _sName, string _sText) -- cgit v1.2.3