reco.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #include <stdlib.h>
  2. #include <ufo/ufo.h>
  3. #include "reco.h"
  4. #include "io.h"
  5. static void
  6. print_dots (gpointer user)
  7. {
  8. static int n = 0;
  9. if ((n++ % 10) == 0)
  10. g_print (".");
  11. }
  12. static void
  13. check (GError *error)
  14. {
  15. if (error != NULL) {
  16. if (error->message != NULL)
  17. g_printerr ("%s", error->message);
  18. exit (1);
  19. }
  20. }
  21. static UfoTaskNode *
  22. make_task (UfoPluginManager *pm, const gchar *name)
  23. {
  24. GError *error = NULL;
  25. UfoTaskNode *task;
  26. task = ufo_plugin_manager_get_task (pm, name, &error);
  27. check (error);
  28. return task;
  29. }
  30. static guint
  31. next_power_of_two (guint32 x)
  32. {
  33. --x;
  34. x |= x >> 1;
  35. x |= x >> 2;
  36. x |= x >> 4;
  37. x |= x >> 8;
  38. x |= x >> 16;
  39. return x + 1;
  40. }
  41. gboolean
  42. params_okay (Params *params)
  43. {
  44. return params->width != 0 &&
  45. params->height != 0 &&
  46. params->num_radios != 0 &&
  47. params->radios != NULL &&
  48. params->theta < G_MAXDOUBLE &&
  49. params->px < G_MAXDOUBLE &&
  50. params->py < G_MAXDOUBLE;
  51. }
  52. void
  53. run_simple_reconstruction (Params *params, gchar **argv)
  54. {
  55. guint xl, xr, yt, yb;
  56. guint padded_width;
  57. guint padded_height;
  58. gdouble theta_rad;
  59. gdouble angle_step;
  60. guint fwidth;
  61. gdouble time = 0.0;
  62. UfoPluginManager *pm = NULL;
  63. UfoTaskGraph *graph = NULL;
  64. UfoBaseScheduler *sched = NULL;
  65. UfoTaskNode *radio_reader = NULL;
  66. UfoTaskNode *dark_reader = NULL;
  67. UfoTaskNode *flat_reader = NULL;
  68. UfoTaskNode *ffc = NULL;
  69. UfoTaskNode *pad = NULL;
  70. UfoTaskNode *ramp = NULL;
  71. UfoTaskNode *fft1 = NULL;
  72. UfoTaskNode *fft2 = NULL;
  73. UfoTaskNode *ifft = NULL;
  74. UfoTaskNode *conv = NULL;
  75. UfoTaskNode *reco = NULL;
  76. UfoTaskNode *writer = NULL;
  77. GError *error = NULL;
  78. if (!params_okay (params)) {
  79. err ("Parameters missing.\n");
  80. return;
  81. }
  82. pm = ufo_plugin_manager_new (NULL);
  83. graph = UFO_TASK_GRAPH (ufo_task_graph_new ());
  84. radio_reader = make_task (pm, "reader");
  85. pad = make_task (pm, "padding-2d");
  86. ramp = make_task (pm, "lamino-ramp");
  87. fft1 = make_task (pm, "fft");
  88. fft2 = make_task (pm, "fft");
  89. ifft = make_task (pm, "ifft");
  90. conv = make_task (pm, "lamino-conv");
  91. reco = make_task (pm, "lamino-bp");
  92. writer = make_task (pm, "writer");
  93. g_object_set (radio_reader,
  94. "path", params->radios,
  95. "end", params->num_radios - 1,
  96. NULL);
  97. g_object_set (fft1, "dimensions", 2, NULL);
  98. g_object_set (fft2, "dimensions", 2, NULL);
  99. g_object_set (ifft, "dimensions", 2, NULL);
  100. fwidth = ((guint) params->px) * 2;
  101. padded_width = next_power_of_two (fwidth) * 2;
  102. padded_height = next_power_of_two ((guint32) params->height + 1);
  103. xl = params->px - params->width / 2;
  104. xr = padded_width - params->width - xl;
  105. yt = params->py - params->height / 2;
  106. yb = padded_height - params->height - yt;
  107. angle_step = (G_PI * 2.0) / params->num_radios;
  108. theta_rad = params->theta / 360. * G_PI * 2;
  109. info ("Axis: x=%.1f y=%.1f variation=%.1f\n",
  110. params->px, params->py, params->px_variation);
  111. info ("Lamino: theta=%.3f tau=%.3f step=%.5f fwidth=%d\n",
  112. theta_rad, params->tau, angle_step, fwidth);
  113. info ("Padding: size=[%d %d] (xl=%d xr=%d yt=%d yb=%d)\n",
  114. padded_width, padded_height, xl, xr, yt, yb);
  115. info ("Volume: origin=[%.1f %.1f %.1f] size=[%d %d %d]\n",
  116. params->v_origin[0], params->v_origin[1], params->v_origin[2],
  117. params->v_size[0], params->v_size[1], params->v_size[2]);
  118. g_object_set (pad,
  119. "xl", xl, "xr", xr,
  120. "yt", yt, "yb", yb,
  121. "mode", "brep",
  122. NULL);
  123. g_object_set (ramp,
  124. "width", padded_width,
  125. "height", padded_height,
  126. "theta", theta_rad,
  127. "tau", params->tau,
  128. "fwidth", fwidth,
  129. NULL);
  130. g_object_set (reco,
  131. "angle-step", angle_step,
  132. "theta", theta_rad,
  133. "psi", params->psi,
  134. "proj-ox", params->px,
  135. "proj-oy", params->py,
  136. "proj-ox-variation", params->px_variation,
  137. "vol-ox", params->v_size[0] / 2 + params->v_origin[0],
  138. "vol-oy", params->v_size[1] / 2 + params->v_origin[1],
  139. "vol-oz", params->v_size[2] / 2 + params->v_origin[2],
  140. "vol-sx", params->v_size[0],
  141. "vol-sy", params->v_size[1],
  142. "vol-sz", params->v_size[2],
  143. NULL);
  144. g_object_set (writer,
  145. "filename", params->output,
  146. NULL);
  147. if (params->darks != NULL && params->flats != NULL) {
  148. flat_reader = make_task (pm, "reader");
  149. dark_reader = make_task (pm, "reader");
  150. ffc = make_task (pm, "flat-field-correction");
  151. g_object_set (ffc, "dark-scale", params->dark_scale, NULL);
  152. g_object_set (flat_reader, "path", params->flats, NULL);
  153. g_object_set (dark_reader, "path", params->darks, NULL);
  154. ufo_task_graph_connect_nodes_full (graph, radio_reader, ffc, 0);
  155. ufo_task_graph_connect_nodes_full (graph, dark_reader, ffc, 1);
  156. ufo_task_graph_connect_nodes_full (graph, flat_reader, ffc, 2);
  157. ufo_task_graph_connect_nodes (graph, ffc, pad);
  158. }
  159. else {
  160. warn ("> No flat/dark field correction\n");
  161. ufo_task_graph_connect_nodes (graph, radio_reader, pad);
  162. }
  163. ufo_task_graph_connect_nodes (graph, pad, fft1);
  164. ufo_task_graph_connect_nodes (graph, ramp, fft2);
  165. ufo_task_graph_connect_nodes_full (graph, fft1, conv, 0);
  166. ufo_task_graph_connect_nodes_full (graph, fft2, conv, 1);
  167. ufo_task_graph_connect_nodes (graph, conv, ifft);
  168. ufo_task_graph_connect_nodes (graph, ifft, reco);
  169. ufo_task_graph_connect_nodes (graph, reco, writer);
  170. g_signal_connect (reco, "processed", G_CALLBACK (print_dots), NULL);
  171. sched = UFO_BASE_SCHEDULER (ufo_scheduler_new (NULL, NULL));
  172. ufo_base_scheduler_run (sched, graph, &error);
  173. check (error);
  174. g_object_get (sched, "time", &time, NULL);
  175. g_print ("\n");
  176. info("Finished in %3.3fs\n", time);
  177. g_object_unref (pm);
  178. g_object_unref (graph);
  179. g_object_unref (sched);
  180. g_object_unref (radio_reader);
  181. g_object_unref (pad);
  182. g_object_unref (fft1);
  183. g_object_unref (fft2);
  184. /* g_object_unref (conv); */
  185. g_object_unref (reco);
  186. g_object_unref (writer);
  187. if (params->darks != NULL && params->flats != NULL) {
  188. g_object_unref (ffc);
  189. g_object_unref (flat_reader);
  190. g_object_unref (dark_reader);
  191. }
  192. }