#include #include #include #include #include "reco.h" #include "io.h" typedef void (*CommandFunction)(Params *, gchar **argv); typedef struct { const gchar *command; CommandFunction func; } CommandMap; static void print (Params *params, gchar **argv) { for (gint i = 0; params->entries[i].long_name != NULL; i++) { GOptionEntry *entry; entry = ¶ms->entries[i]; if (argv[0] == NULL || g_strcmp0 (entry->long_name, argv[0]) == 0) { switch (entry->arg) { case G_OPTION_ARG_STRING: info ("%-15s%s\n", entry->long_name, *((gchar **) entry->arg_data)); break; case G_OPTION_ARG_INT: info ("%-15s%i\n", entry->long_name, *((gint *) entry->arg_data)); break; case G_OPTION_ARG_DOUBLE: info ("%-15s%f\n", entry->long_name, *((gdouble *) entry->arg_data)); break; default: break; } } } } static void set (Params *params, gchar **argv) { if (argv[0] == NULL) { warn ("No parameter given\n"); return; } if (argv[1] == NULL) { warn ("No value given\n"); return; } for (gint i = 0; params->entries[i].long_name != NULL; i++) { GOptionEntry *entry; entry = ¶ms->entries[i]; if (g_strcmp0 (entry->long_name, argv[0]) == 0) { switch (entry->arg) { case G_OPTION_ARG_STRING: { gchar *s; s = *((gchar **) entry->arg_data); g_free (s); *(gchar **) entry->arg_data = g_strjoinv (" ", &argv[1]); } break; case G_OPTION_ARG_INT: *(gint *) entry->arg_data = atoi (argv[1]); break; case G_OPTION_ARG_DOUBLE: *(gdouble *) entry->arg_data = atof (argv[1]); break; default: break; } print (params, argv); break; } } } static void quit (Params *params, gchar **argv) { exit (0); } static void start_shell (Params *params) { static CommandMap map[] = { { "run", run_cached_reconstruction }, { "print", print }, { "set", set }, { "quit", quit }, { NULL }, }; while (1) { gchar *line; gint i; gchar **split = NULL; line = readline ("> "); if (line && *line && (g_strchomp (line) == g_strchug (line))) { add_history (line); } else { goto cleanup_line; } split = g_strsplit (line, " ", 0); for (i = 0; map[i].command != NULL; i++) { /* Run command even if only partially written out */ if (g_str_has_prefix (map[i].command, split[0])) { map[i].func (params, &split[1]); break; } } if (map[i].command == NULL) warn ("Unknown command `%s'\n", split[0]); cleanup_line: g_free (line); g_strfreev (split); } } static void parse_params (Params *params, int argc, char **argv) { GOptionContext *context; GError *error = NULL; GOptionEntry entries[] = { { "width", 0, 0, G_OPTION_ARG_INT, ¶ms->width, "Width", "[int]" }, { "height", 0, 0, G_OPTION_ARG_INT, ¶ms->height, "Height", "[int]" }, { "num-radios", 0, 0, G_OPTION_ARG_INT, ¶ms->num_radios, "Number of radios", "[int]" }, { "num-darks", 0, 0, G_OPTION_ARG_INT, ¶ms->num_darks, "Number of darks", "[int]" }, { "num-flats", 0, 0, G_OPTION_ARG_INT, ¶ms->num_flats, "Number of flats", "[int]" }, { "radios", 0, 0, G_OPTION_ARG_STRING, ¶ms->radios, "Radios", "[path|glob]" }, { "darks", 0, 0, G_OPTION_ARG_STRING, ¶ms->darks, "Darks", "[path|glob]" }, { "flats", 0, 0, G_OPTION_ARG_STRING, ¶ms->flats, "Flats", "[path|glob]" }, { "flats-after", 0, 0, G_OPTION_ARG_STRING, ¶ms->flats_after, "Flats", "[path|glob]" }, { "radio-step", 0, 0, G_OPTION_ARG_INT, ¶ms->radio_step, "Radio step", "[int]" }, { "dark-scale", 0, 0, G_OPTION_ARG_DOUBLE, ¶ms->dark_scale, "Dark scale", "[float]" }, { "output", 0, 0, G_OPTION_ARG_STRING, ¶ms->output, "Output", "[path]" }, { "theta", 0, 0, G_OPTION_ARG_DOUBLE, ¶ms->theta, "Tilt (theta)", "[float]" }, { "tau", 0, 0, G_OPTION_ARG_DOUBLE, ¶ms->tau, "Pixel size (theta)", "[float]" }, { "psi", 0, 0, G_OPTION_ARG_DOUBLE, ¶ms->psi, "Misalignment (psi)", "[float]" }, { "px", 0, 0, G_OPTION_ARG_DOUBLE, ¶ms->px, "X coordinate of axis", "[float]" }, { "py", 0, 0, G_OPTION_ARG_DOUBLE, ¶ms->py, "Y coordinate of axis", "[float]" }, { "px-variation", 0, 0, G_OPTION_ARG_DOUBLE, ¶ms->px_variation, "X axis variation", "[float]" }, { "vx", 0, 0, G_OPTION_ARG_DOUBLE, ¶ms->v_origin[0], "X coordinate of box origin", "[float]" }, { "vy", 0, 0, G_OPTION_ARG_DOUBLE, ¶ms->v_origin[1], "Y coordinate of box origin", "[float]" }, { "vz", 0, 0, G_OPTION_ARG_DOUBLE, ¶ms->v_origin[2], "Z coordinate of box origin", "[float]" }, { "vw", 0, 0, G_OPTION_ARG_INT, ¶ms->v_size[0], "Width of box", "[int]" }, { "vh", 0, 0, G_OPTION_ARG_INT, ¶ms->v_size[1], "Height of box", "[int]" }, { "vd", 0, 0, G_OPTION_ARG_INT, ¶ms->v_size[2], "Depth of box", "[int]" }, { "z-spacing", 0, 0, G_OPTION_ARG_DOUBLE, ¶ms->z_spacing, "Z-spacing", "[int]" }, { "interactive", 0, 0, G_OPTION_ARG_NONE, ¶ms->interactive, "Start interactive mode", "" }, { "write-summed", 0, 0, G_OPTION_ARG_NONE, ¶ms->write_summed, "Write summed flat-field-corrected projections", "" }, { NULL } }; context = g_option_context_new ("- laminographic reconstruction"); g_option_context_add_main_entries (context, entries, NULL); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_print ("option parsing failed: %s\n", error->message); exit (1); } /* Copy entry information for later reference */ params->entries = g_memdup (entries, sizeof (entries)); if (params->interactive) goto parse_params_cleanup; if (!params_okay (params)) { err ("Parameters missing.\n\n"); g_print ("%s\n", g_option_context_get_help (context, TRUE, NULL)); exit (1); } parse_params_cleanup: g_option_context_free (context); } int main (int argc, char **argv) { Params params = { .interactive = FALSE, .radios = NULL, .darks = NULL, .flats = NULL, .flats_after = NULL, .output = "volume-%i.tif", .width = 0, .height = 0, .num_radios = 0, .num_darks = 1, .num_flats = 1, .radio_step = 1, .theta = G_MAXDOUBLE, .dark_scale = 1.0, .tau = 1.0, .psi = 0.0, .px = G_MAXDOUBLE, .py = G_MAXDOUBLE, .px_variation = 0.0, .v_size = {256, 256, 256}, .v_origin = {0.0, 0.0, 0.0}, .z_spacing = 1.0, .cache = NULL, }; #if !(GLIB_CHECK_VERSION (2, 36, 0)) g_type_init (); #endif parse_params (¶ms, argc, argv); if (params.interactive) start_shell (¶ms); else run_simple_reconstruction (¶ms, NULL); return 0; }