diff options
Diffstat (limited to 'src/ufo-roof-config.c')
-rw-r--r-- | src/ufo-roof-config.c | 143 |
1 files changed, 104 insertions, 39 deletions
diff --git a/src/ufo-roof-config.c b/src/ufo-roof-config.c index 812d4a2..4788a2a 100644 --- a/src/ufo-roof-config.c +++ b/src/ufo-roof-config.c @@ -5,6 +5,7 @@ #include <ufo/ufo.h> +#include "ufo-roof.h" #include "ufo-roof-error.h" #include "ufo-roof-config.h" @@ -59,10 +60,13 @@ UfoRoofConfig *ufo_roof_config_new(const char *config, GError **error) { // JsonNode *node; JsonObject *root = NULL; JsonObject *hardware = NULL; + JsonObject *geometry = NULL; + JsonObject *optics = NULL; JsonObject *network = NULL; JsonObject *performance = NULL; JsonObject *simulation = NULL; - + JsonObject *reconstruction = NULL; + GError *gerr = NULL; priv = (UfoRoofConfigPrivate*)malloc(sizeof(UfoRoofConfigPrivate)); @@ -73,11 +77,20 @@ UfoRoofConfig *ufo_roof_config_new(const char *config, GError **error) { // Set defaults cfg = &priv->cfg; - cfg->port = 4000; + cfg->roof_mode = FALSE; + cfg->n_planes = 2; + cfg->n_modules = 16; + cfg->channels_per_module = 16; + cfg->bit_depth = 16; + cfg->samples_per_rotation = 1000; + cfg->sample_rate = 0; + cfg->imaging_rate = 0; + + cfg->port = 52067; cfg->n_streams = 1; cfg->protocol = "udp"; cfg->network_timeout = 10000000; - cfg->header_size = 0; + cfg->header_size = sizeof(UfoRoofPacketHeader); cfg->payload_size = 0; cfg->max_packet_size = 0; cfg->max_packets = 100; @@ -86,11 +99,12 @@ UfoRoofConfig *ufo_roof_config_new(const char *config, GError **error) { cfg->drop_buffers = 0; cfg->path = NULL; + // Read configuration priv->parser = json_parser_new_immutable (); json_parser_load_from_file (priv->parser, config, &gerr); - if (gerr != NULL) { + if (gerr != NULL) { g_propagate_prefixed_error(error, gerr, "Error parsing JSON file (%s) with ROOF configuration: ", config); ufo_roof_config_free(cfg); return NULL; @@ -100,75 +114,124 @@ UfoRoofConfig *ufo_roof_config_new(const char *config, GError **error) { if (root) { roof_config_node_get(hardware, root, object, "hardware"); + roof_config_node_get(geometry, root, object, "geometry"); + roof_config_node_get(optics, root, object, "optics"); roof_config_node_get(network, root, object, "network"); + roof_config_node_get(reconstruction, root, object, "reconstruction"); roof_config_node_get(simulation, root, object, "simulation"); roof_config_node_get(performance, root, object, "performance"); } if (hardware) { - // FIXME: Compute dataset size based on roof hardware + roof_config_node_get(cfg->n_planes, hardware, int, "planes"); + roof_config_node_get(cfg->n_modules, hardware, int, "modules"); + roof_config_node_get(cfg->channels_per_module, hardware, int, "channels_per_module"); + roof_config_node_get(cfg->bit_depth, hardware, int, "bit_depth"); + + roof_config_node_get(cfg->samples_per_rotation, hardware, int, "samples_per_rotation"); + roof_config_node_get(cfg->sample_rate, hardware, int, "sample_rate"); + roof_config_node_get(cfg->imaging_rate, hardware, int, "imaging_rate"); + + if ((cfg->sample_rate)||(cfg->imaging_rate)) { + if ((!cfg->sample_rate)||(!cfg->imaging_rate)||(cfg->sample_rate%cfg->imaging_rate)) { + ufo_roof_config_free(cfg); + roof_new_error(error, "Invalid sample (%u) and imaging (%u) rates are specified", cfg->sample_rate, cfg->imaging_rate); + } + + if ((json_object_get_member(hardware, "samples_per_rotation"))&&(cfg->samples_per_rotation != (cfg->sample_rate / cfg->imaging_rate))) { + ufo_roof_config_free(cfg); + roof_new_error(error, "The specified samples-per-rotation (%u) doesn't match sample/imaging rates (%u / %u)", cfg->samples_per_rotation, cfg->sample_rate, cfg->imaging_rate); + } + + cfg->samples_per_rotation = cfg->sample_rate / cfg->imaging_rate; + } + + if ((cfg->bit_depth%8)||(cfg->bit_depth > 32)) { + ufo_roof_config_free(cfg); + roof_new_error(error, "Invalid bit-depth (%u) is configured, only 8, 16, 24, 32 is currently supported", cfg->bit_depth); + } + + cfg->fan_projections = cfg->samples_per_rotation; + cfg->fan_bins = cfg->n_modules * cfg->channels_per_module; + + cfg->dataset_size = cfg->fan_projections * cfg->fan_bins * (cfg->bit_depth / 8); + cfg->n_streams = cfg->n_modules; + cfg->roof_mode = TRUE; } if (network) { -// int max_packet_size = 0; - roof_config_node_get(cfg->port, network, int, "port"); roof_config_node_get(cfg->n_streams, network, int, "streams"); - roof_config_node_get(cfg->max_packet_size, network, int, "max_packet_size"); - // FIXME: compute payload_size based on sample_size roof_config_node_get(cfg->payload_size, network, int, "payload_size"); roof_config_node_get(cfg->header_size, network, int, "header_size"); - roof_config_node_get(cfg->dataset_size, network, int, "dataset_size"); - } - - if (performance) { - roof_config_node_get(cfg->max_packets, performance, int, "packets_at_once"); - roof_config_node_get(cfg->buffer_size, performance, int, "buffer_size"); - roof_config_node_get(cfg->drop_buffers, performance, int, "drop_buffers"); + roof_config_node_get(cfg->max_packet_size, network, int, "max_packet_size"); + roof_config_node_get(cfg->dataset_size, network, int, "dataset_size"); + + if (!cfg->payload_size) { + ufo_roof_config_free(cfg); + roof_new_error(error, "Packet payload and header size must be set"); + } + + if ((cfg->header_size < sizeof(UfoRoofPacketHeader))&&(!strncmp(cfg->protocol, "udp", 3))) { + ufo_roof_config_free(cfg); + roof_new_error(error, "The header with packet id (%lu bytes) is expected for un-ordered protocols", sizeof(UfoRoofPacketHeader)); + } + + if (!cfg->dataset_size) + cfg->dataset_size = cfg->payload_size; } if (simulation) { roof_config_node_get_string(cfg->path, simulation, "path"); roof_config_node_get(cfg->first_file_number, simulation, int, "first_file_number"); + roof_config_node_get(cfg->header_size, simulation, int, "header_size"); + + if (!cfg->payload_size) + cfg->payload_size = cfg->dataset_size; } - // Check configuration consistency - if (!cfg->payload_size) { - ufo_roof_config_free(cfg); - roof_new_error(error, "Packet size is not set"); - } - - if ((!cfg->header_size)&&(!cfg->path)) { - if (!strncmp(cfg->protocol, "udp", 3)) { - // Error if 0 implicitely set, use default value otherwise - if ((network)&&(json_object_get_member(network, "header_size"))) { - ufo_roof_config_free(cfg); - roof_new_error(error, "The header with packet ids is required for un-ordered protocols"); - } else { - cfg->header_size = sizeof(uint32_t); - } - } + if (performance) { + roof_config_node_get(cfg->max_packets, performance, int, "packets_at_once"); + roof_config_node_get(cfg->buffer_size, performance, int, "buffer_size"); + roof_config_node_get(cfg->drop_buffers, performance, int, "drop_buffers"); } + + // Check configuration consistency guint fragments_per_dataset = cfg->dataset_size / cfg->payload_size; guint fragments_per_stream = fragments_per_dataset / cfg->n_streams; + // Dataset should be split in an integer number of network packets (we don't expect data from different datasets in one packet at the moment) if ((cfg->dataset_size % cfg->payload_size)||(fragments_per_dataset%cfg->n_streams)) { ufo_roof_config_free(cfg); roof_new_error(error, "Inconsistent ROOF configuration: dataset_size=%u, packet_size=%u, data_streams=%u", cfg->dataset_size, cfg->payload_size, cfg->n_streams); } - if (cfg->buffer_size * fragments_per_stream < cfg->max_packets) { - cfg->max_packets = cfg->buffer_size * fragments_per_stream / 2; + // Packet should contain an integer number of complete projections (their parts provided by a single module) + if ((cfg->roof_mode)&&(cfg->payload_size % (cfg->channels_per_module * (cfg->bit_depth / 8)))) { + ufo_roof_config_free(cfg); + roof_new_error(error, "Inconsistent ROOF configuration: packet_size=%u, projection_size=%u (%u channels x %u bits)", cfg->payload_size, cfg->channels_per_module * (cfg->bit_depth / 8), cfg->channels_per_module, cfg->bit_depth); } - - // Finalize configuration + if (!cfg->max_packet_size) - cfg->max_packet_size = cfg->header_size + cfg->payload_size; + cfg->max_packet_size = cfg->header_size + cfg->payload_size; + + if (hardware) { + if (cfg->n_modules != cfg->n_streams) { + ufo_roof_config_free(cfg); + roof_new_error(error, "Currently, number of ROOF modules (%u) is exepcted to be equal to number of independent data streams (%u)", cfg->n_modules, cfg->n_streams); + } + + if (cfg->dataset_size != (cfg->fan_projections * cfg->fan_bins * cfg->bit_depth / 8)) { + ufo_roof_config_free(cfg); + roof_new_error(error, "Specified dataset size (%u) does not match ROOF configuration (modules: %u, channels-per-module: %u, bit-depth: %u, samples-per-rotation: %u)", cfg->dataset_size, cfg->n_modules, cfg->channels_per_module, cfg->bit_depth, cfg->samples_per_rotation); + } + } - if (!cfg->dataset_size) - cfg->dataset_size = cfg->payload_size; + if ((cfg->buffer_size * fragments_per_stream) < cfg->max_packets) { + cfg->max_packets = cfg->buffer_size * fragments_per_stream / 2; + } if (cfg->buffer_size < 4) { cfg->drop_buffers = 0; @@ -176,5 +239,7 @@ UfoRoofConfig *ufo_roof_config_new(const char *config, GError **error) { cfg->drop_buffers = cfg->buffer_size / 2; } + printf("dataset size: %i\n", cfg->dataset_size); + return cfg; } |