lamino.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #include <stdlib.h>
  2. #include <readline/readline.h>
  3. #include <readline/history.h>
  4. #include <glib-object.h>
  5. #include "reco.h"
  6. #include "io.h"
  7. typedef void (*CommandFunction)(Params *, gchar **argv);
  8. typedef struct {
  9. const gchar *command;
  10. CommandFunction func;
  11. } CommandMap;
  12. static void
  13. print (Params *params, gchar **argv)
  14. {
  15. for (gint i = 0; params->entries[i].long_name != NULL; i++) {
  16. GOptionEntry *entry;
  17. entry = &params->entries[i];
  18. if (argv[0] == NULL || g_strcmp0 (entry->long_name, argv[0]) == 0) {
  19. switch (entry->arg) {
  20. case G_OPTION_ARG_STRING:
  21. info ("%-15s%s\n", entry->long_name, *((gchar **) entry->arg_data));
  22. break;
  23. case G_OPTION_ARG_INT:
  24. info ("%-15s%i\n", entry->long_name, *((gint *) entry->arg_data));
  25. break;
  26. case G_OPTION_ARG_DOUBLE:
  27. info ("%-15s%f\n", entry->long_name, *((gdouble *) entry->arg_data));
  28. break;
  29. default:
  30. break;
  31. }
  32. }
  33. }
  34. }
  35. static void
  36. set (Params *params, gchar **argv)
  37. {
  38. if (argv[0] == NULL) {
  39. warn ("No parameter given\n");
  40. return;
  41. }
  42. if (argv[1] == NULL) {
  43. warn ("No value given\n");
  44. return;
  45. }
  46. for (gint i = 0; params->entries[i].long_name != NULL; i++) {
  47. GOptionEntry *entry;
  48. entry = &params->entries[i];
  49. if (g_strcmp0 (entry->long_name, argv[0]) == 0) {
  50. switch (entry->arg) {
  51. case G_OPTION_ARG_STRING:
  52. {
  53. gchar *s;
  54. s = *((gchar **) entry->arg_data);
  55. g_free (s);
  56. *(gchar **) entry->arg_data = g_strjoinv (" ", &argv[1]);
  57. }
  58. break;
  59. case G_OPTION_ARG_INT:
  60. *(gint *) entry->arg_data = atoi (argv[1]);
  61. break;
  62. case G_OPTION_ARG_DOUBLE:
  63. *(gdouble *) entry->arg_data = atof (argv[1]);
  64. break;
  65. default:
  66. break;
  67. }
  68. print (params, argv);
  69. break;
  70. }
  71. }
  72. }
  73. static void
  74. quit (Params *params, gchar **argv)
  75. {
  76. exit (0);
  77. }
  78. static void
  79. start_shell (Params *params)
  80. {
  81. static CommandMap map[] = {
  82. { "run", run_cached_reconstruction },
  83. { "print", print },
  84. { "set", set },
  85. { "quit", quit },
  86. { NULL },
  87. };
  88. while (1) {
  89. gchar *line;
  90. gint i;
  91. gchar **split = NULL;
  92. line = readline ("> ");
  93. if (line && *line && (g_strchomp (line) == g_strchug (line))) {
  94. add_history (line);
  95. }
  96. else {
  97. goto cleanup_line;
  98. }
  99. split = g_strsplit (line, " ", 0);
  100. for (i = 0; map[i].command != NULL; i++) {
  101. /* Run command even if only partially written out */
  102. if (g_str_has_prefix (map[i].command, split[0])) {
  103. map[i].func (params, &split[1]);
  104. break;
  105. }
  106. }
  107. if (map[i].command == NULL)
  108. warn ("Unknown command `%s'\n", split[0]);
  109. cleanup_line:
  110. g_free (line);
  111. g_strfreev (split);
  112. }
  113. }
  114. static void
  115. parse_params (Params *params, int argc, char **argv)
  116. {
  117. GOptionContext *context;
  118. GError *error = NULL;
  119. GOptionEntry entries[] = {
  120. { "width", 0, 0, G_OPTION_ARG_INT, &params->width, "Width", "[int]" },
  121. { "height", 0, 0, G_OPTION_ARG_INT, &params->height, "Height", "[int]" },
  122. { "num-radios", 0, 0, G_OPTION_ARG_INT, &params->num_radios, "Number of radios", "[int]" },
  123. { "num-darks", 0, 0, G_OPTION_ARG_INT, &params->num_darks, "Number of darks", "[int]" },
  124. { "num-flats", 0, 0, G_OPTION_ARG_INT, &params->num_flats, "Number of flats", "[int]" },
  125. { "radios", 0, 0, G_OPTION_ARG_STRING, &params->radios, "Radios", "[path|glob]" },
  126. { "darks", 0, 0, G_OPTION_ARG_STRING, &params->darks, "Darks", "[path|glob]" },
  127. { "flats", 0, 0, G_OPTION_ARG_STRING, &params->flats, "Flats", "[path|glob]" },
  128. { "flats-after", 0, 0, G_OPTION_ARG_STRING, &params->flats_after, "Flats", "[path|glob]" },
  129. { "radio-step", 0, 0, G_OPTION_ARG_INT, &params->radio_step, "Radio step", "[int]" },
  130. { "dark-scale", 0, 0, G_OPTION_ARG_DOUBLE, &params->dark_scale, "Dark scale", "[float]" },
  131. { "output", 0, 0, G_OPTION_ARG_STRING, &params->output, "Output", "[path]" },
  132. { "theta", 0, 0, G_OPTION_ARG_DOUBLE, &params->theta, "Tilt (theta)", "[float]" },
  133. { "tau", 0, 0, G_OPTION_ARG_DOUBLE, &params->tau, "Pixel size (theta)", "[float]" },
  134. { "psi", 0, 0, G_OPTION_ARG_DOUBLE, &params->psi, "Misalignment (psi)", "[float]" },
  135. { "px", 0, 0, G_OPTION_ARG_DOUBLE, &params->px, "X coordinate of axis", "[float]" },
  136. { "py", 0, 0, G_OPTION_ARG_DOUBLE, &params->py, "Y coordinate of axis", "[float]" },
  137. { "px-variation", 0, 0, G_OPTION_ARG_DOUBLE, &params->px_variation, "X axis variation", "[float]" },
  138. { "vx", 0, 0, G_OPTION_ARG_DOUBLE, &params->v_origin[0], "X coordinate of box origin", "[float]" },
  139. { "vy", 0, 0, G_OPTION_ARG_DOUBLE, &params->v_origin[1], "Y coordinate of box origin", "[float]" },
  140. { "vz", 0, 0, G_OPTION_ARG_DOUBLE, &params->v_origin[2], "Z coordinate of box origin", "[float]" },
  141. { "vw", 0, 0, G_OPTION_ARG_INT, &params->v_size[0], "Width of box", "[int]" },
  142. { "vh", 0, 0, G_OPTION_ARG_INT, &params->v_size[1], "Height of box", "[int]" },
  143. { "vd", 0, 0, G_OPTION_ARG_INT, &params->v_size[2], "Depth of box", "[int]" },
  144. { "z-spacing", 0, 0, G_OPTION_ARG_DOUBLE, &params->z_spacing, "Z-spacing", "[int]" },
  145. { "interactive", 0, 0, G_OPTION_ARG_NONE, &params->interactive, "Start interactive mode", "" },
  146. { "write-summed", 0, 0, G_OPTION_ARG_NONE, &params->write_summed, "Write summed flat-field-corrected projections", "" },
  147. { NULL }
  148. };
  149. context = g_option_context_new ("- laminographic reconstruction");
  150. g_option_context_add_main_entries (context, entries, NULL);
  151. if (!g_option_context_parse (context, &argc, &argv, &error)) {
  152. g_print ("option parsing failed: %s\n", error->message);
  153. exit (1);
  154. }
  155. /* Copy entry information for later reference */
  156. params->entries = g_memdup (entries, sizeof (entries));
  157. if (params->interactive)
  158. goto parse_params_cleanup;
  159. if (!params_okay (params)) {
  160. err ("Parameters missing.\n\n");
  161. g_print ("%s\n", g_option_context_get_help (context, TRUE, NULL));
  162. exit (1);
  163. }
  164. parse_params_cleanup:
  165. g_option_context_free (context);
  166. }
  167. int
  168. main (int argc, char **argv)
  169. {
  170. Params params = {
  171. .interactive = FALSE,
  172. .radios = NULL,
  173. .darks = NULL,
  174. .flats = NULL,
  175. .flats_after = NULL,
  176. .output = "volume-%i.tif",
  177. .width = 0,
  178. .height = 0,
  179. .num_radios = 0,
  180. .num_darks = 1,
  181. .num_flats = 1,
  182. .radio_step = 1,
  183. .theta = G_MAXDOUBLE,
  184. .dark_scale = 1.0,
  185. .tau = 1.0,
  186. .psi = 0.0,
  187. .px = G_MAXDOUBLE,
  188. .py = G_MAXDOUBLE,
  189. .px_variation = 0.0,
  190. .v_size = {256, 256, 256},
  191. .v_origin = {0.0, 0.0, 0.0},
  192. .z_spacing = 1.0,
  193. .cache = NULL,
  194. };
  195. #if !(GLIB_CHECK_VERSION (2, 36, 0))
  196. g_type_init ();
  197. #endif
  198. parse_params (&params, argc, argv);
  199. if (params.interactive)
  200. start_shell (&params);
  201. else
  202. run_simple_reconstruction (&params, NULL);
  203. return 0;
  204. }