Browse Source

Allow monitoring multiple datasets

Matthias Vogelgesang 7 years ago
parent
commit
51857e68a6
1 changed files with 89 additions and 30 deletions
  1. 89 30
      cockpit

+ 89 - 30
cockpit

@@ -133,6 +133,7 @@ class StatusBar(object):
         self.c = colors
 
     def update(self, s):
+        self.window.clear()
         self.window.bkgd(' ', self.c.get(Colors.STATUS_BAR))
         self.window.addstr(s, self.c.get(Colors.STATUS_BAR))
 
@@ -255,10 +256,38 @@ class Parameters(object):
         self.angle = angle
 
 
+class Dataset(object):
+
+    def __init__(self, path):
+        self.path = path
+        self.prefix = os.path.basename(path)
+
+    def __repr__(self):
+        return '<Dataset(prefix={})>'.format(self.prefix)
+
+
 class Application(object):
     def __init__(self, config):
         self.config = config
         self.running = True
+        self.datasets = []
+        self.known = set()
+        self.current = None
+        self.index = -1
+
+    def scan(self):
+        new = []
+
+        for p in os.listdir(self.config.destination):
+            path = os.path.join(self.config.destination, p)
+            if os.path.isdir(path) and p not in self.known:
+                new.append(Dataset(path))
+                self.known.add(p)
+
+        if new:
+            for d in new:
+                self.log.highlight("Found new dataset {}".format(d.prefix))
+                self.datasets.append(d)
 
     def run_command(self, cmd):
         try:
@@ -284,16 +313,12 @@ class Application(object):
             self.log.error("{}".format(e))
             return False
 
-    @property
-    def prefix(self):
-        return os.path.basename(self.config.destination)
-
     @property
     def params_name(self):
-        return '{}params.json'.format(self.prefix)
+        return '{}params.json'.format(self.current.prefix)
 
     def read_info(self):
-        info_file = os.path.join(self.config.destination, '{}.info'.format(self.prefix))
+        info_file = os.path.join(self.current.path, '{}.info'.format(self.current.prefix))
         return read_info_file(info_file)
 
     def read_optimal_params(self, scale=1.0):
@@ -309,7 +334,7 @@ class Application(object):
         axis = (float(info['Col_end']) + 1) / 2.0
         axis_step = 0.25
 
-        fname = os.path.join(self.config.destination, '{}0000.edf'.format(self.prefix))
+        fname = os.path.join(self.current.path, '{}0000.edf'.format(self.current.prefix))
         header = read_edf_id19_header(fname)
         motor_pos = extract_motor_positions(header)
 
@@ -321,14 +346,14 @@ class Application(object):
 
         x_region = 960
         y_region = 960
-        fc_path = '{prefix}/fc'.format(prefix=self.prefix)
+        fc_path = '{path}/fc'.format(path=self.current.path)
 
         if resize:
             x_region /= 2
             y_region /= 2
             axis /= 2
             axis_step /= 2
-            fc_path = '{prefix}/fc-small'.format(prefix=self.prefix)
+            fc_path = '{path}/fc-small'.format(path=self.current.path)
 
         axis_start = axis - slices_per_device * axis_step
         axis_stop = axis + slices_per_device * axis_step
@@ -341,10 +366,10 @@ class Application(object):
                       ' --axis-range={ax_start},{ax_stop},{ax_step}'
                       ' --lamino-angle-range={an_start},{an_stop},{an_step}'
                       ' --metric kurtosis --z-metric kurtosis'
-                      ' --tmp-output {prefix}/tmp'
+                      ' --tmp-output {path}/tmp'
                       .format(ax_start=axis_start, ax_stop=axis_stop, ax_step=axis_step,
                               an_start=angle_start, an_stop=angle_stop, an_step=angle_step,
-                              prefix=self.prefix))
+                              path=self.current.path))
 
         params = ('--x-region="-{x_region},{x_region},1"'
                   ' --y-region="-{y_region},{y_region},1"'
@@ -359,11 +384,16 @@ class Application(object):
                ' {opt_params}'
                ' --reco-params "{params}"'
                ' --params-filename {params_name}'
-               .format(opt_params=opt_params, params=params, params_name=self.params_name,
-                       fc_path=fc_path, prefix=self.prefix))
+               .format(opt_params=opt_params, params=params, params_name=self.params_name, fc_path=fc_path))
 
         return self.run_command(cmd)
 
+    def update_statusbar(self):
+        self.log.info("Current dataset: {}".format(self.current.prefix))
+
+        if self.current:
+            self.status_bar.update("Current: {} [{}/{}]".format(self.current.prefix, self.index + 1, len(self.datasets)))
+
     def on_reconstruct(self):
         self.log.highlight("Reconstructing ...")
 
@@ -412,8 +442,8 @@ class Application(object):
     def on_flat_correct(self):
         self.log.highlight("Flat field correction ...")
         info = self.read_info()
-        path = self.config.destination
-        data = dict(path=path, prefix=self.prefix, num=info['TOMO_N'], step=1)
+        path = self.current.path
+        data = dict(path=path, prefix=self.current.prefix, num=info['TOMO_N'], step=1)
 
         cmd = ('tofu flatcorrect --verbose'
                ' --reduction-mode median'
@@ -464,6 +494,16 @@ class Application(object):
 
         return False
 
+    def on_next_dataset(self):
+        self.index = (self.index + 1) % len(self.datasets)
+        self.current = self.datasets[self.index]
+        self.update_statusbar()
+
+    def on_previous_dataset(self):
+        self.index = (self.index - 1) % len(self.datasets)
+        self.current = self.datasets[self.index]
+        self.update_statusbar()
+
     def do_nothing(self):
         return True
 
@@ -477,10 +517,10 @@ class Application(object):
         bottom_pane = screen.subwin(height - 1, width, 1, 0)
 
         left_pane = bottom_pane.subwin(height - 1, width / 4, 1, 0)
-        right_pane = bottom_pane.subwin(height - 1, 2 * width / 4, 1, width / 4)
+        right_pane = bottom_pane.subwin(height - 1, 3 * width / 4, 1, width / 4)
 
-        status_bar = StatusBar(top_pane, colors)
-        status_bar.update('Cockpit')
+        self.status_bar = StatusBar(top_pane, colors)
+        self.status_bar.update('Cockpit')
 
         cmd_window = CommandList(left_pane, colors)
 
@@ -492,41 +532,59 @@ class Application(object):
         quick_optimize = Action('q', 'Quick optimization', self.on_quick_optimize, machine.QUICK_OPTIMIZE)
         optimize = Action('o', 'Optimization', self.on_optimize, machine.OPTIMIZE)
         reconstruct = Action('r', 'Reconstruct', self.on_reconstruct, machine.RECONSTRUCT)
+        flatcorrect = Action('f', 'Flat correct', self.on_flat_correct, machine.FLATCORRECT)
+        next_dataset = Action('n', 'Next dataset', self.on_next_dataset, machine.START)
+        previous_dataset = Action('p', 'Previous dataset', self.on_previous_dataset, machine.START)
 
         machine.add_action(machine.START, sync)
         machine.add_action(machine.START, quick_optimize)
         machine.add_action(machine.START, optimize)
+        machine.add_action(machine.START, next_dataset)
+        machine.add_action(machine.START, previous_dataset)
         machine.add_action(machine.START, quit)
 
         machine.add_action(machine.SYNC, quit)
 
         machine.add_action(machine.QUICK_OPTIMIZE, reconstruct)
         machine.add_action(machine.QUICK_OPTIMIZE, optimize)
+        machine.add_action(machine.QUICK_OPTIMIZE, next_dataset)
+        machine.add_action(machine.QUICK_OPTIMIZE, previous_dataset)
         machine.add_action(machine.QUICK_OPTIMIZE, quit)
 
-        machine.add_action(machine.OPTIMIZE, reconstruct)
         machine.add_action(machine.OPTIMIZE, quick_optimize)
+        machine.add_action(machine.OPTIMIZE, reconstruct)
+        machine.add_action(machine.OPTIMIZE, next_dataset)
+        machine.add_action(machine.OPTIMIZE, previous_dataset)
         machine.add_action(machine.OPTIMIZE, quit)
 
         machine.add_action(machine.CLEAN, sync)
         machine.add_action(machine.CLEAN, quit)
 
-        if os.path.exists(self.params_name):
-            machine.add_action(machine.START, reconstruct)
+        machine.add_action(machine.FLATCORRECT, quick_optimize)
+        machine.add_action(machine.FLATCORRECT, optimize)
+        machine.add_action(machine.FLATCORRECT, next_dataset)
+        machine.add_action(machine.FLATCORRECT, previous_dataset)
+        machine.add_action(machine.FLATCORRECT, quit)
+
+        self.log = LogList(right_pane, colors)
+        self.log.info('Source dir set to {}'.format(self.config.source))
+        self.log.info('Destination dir set to {}'.format(self.config.destination))
+
+        self.scan()
 
-        if not have_flats(self.config.destination):
-            flatcorrect = Action('f', 'Flat correct', self.on_flat_correct, machine.FLATCORRECT)
+        if self.datasets:
+            self.index = 0
+            self.current = self.datasets[0]
+
+        if not have_flats(self.current.path):
             machine.add_action(machine.START, flatcorrect)
             machine.add_action(machine.SYNC, flatcorrect)
-            machine.add_action(machine.FLATCORRECT, quick_optimize)
-            machine.add_action(machine.FLATCORRECT, optimize)
-            machine.add_action(machine.FLATCORRECT, quit)
 
-        cmd_window.set_actions(machine.actions)
+        if os.path.exists(self.params_name):
+            machine.add_action(machine.START, reconstruct)
 
-        self.log = LogList(right_pane, colors)
-        self.log.info('Source dir set to {}'.format(self.config.source))
-        self.log.info('Destination dir set to {}'.format(self.config.destination))
+        self.update_statusbar()
+        cmd_window.set_actions(machine.actions)
 
         while self.running:
             ci = screen.getch()
@@ -543,6 +601,7 @@ class Application(object):
             elif ci == curses.KEY_BACKSPACE:
                 cmd_window.backspace()
 
+            self.scan()
             screen.refresh()
 
     def run(self):