def _init_step_ids(self): self._step_ids = OrderedDict() for i, step in enumerate(self._steps): step_id = step.name ##"%d_%s" % (i, step.name) self._step_ids[step_id] = step
class Analysis(six.with_metaclass(AnalysisMetaClass, object)): # XXX the metaclass automatically registers the Analysis class in the # AnalysisFactory and intializes the param_template_map def __init__(self, study): self._init_steps() self._init_step_ids() self.study = study self.pipeline = None self.parameters = None def _init_steps(self): raise NotImplementedError("Analysis is an Abstract class.") def _init_step_ids(self): self._step_ids = OrderedDict() for i, step in enumerate(self._steps): step_id = step.name ##"%d_%s" % (i, step.name) self._step_ids[step_id] = step def step_from_id(self, step_id): return self._step_ids.get(step_id) def import_data(self, subject): raise NotImplementedError("Analysis is an Abstract class. import_data must be redefined.") def set_parameters(self, subject): raise NotImplementedError("Analysis is an Abstract class. set_parameters must be redefined.") def propagate_parameters(self): raise NotImplementedError("Analysis is an Abstract class. propagate_parameter must be redefined.") def list_input_parameters_with_existing_files(self): raise NotImplementedError("Analysis is an Abstract class. list_input_parameters_with_existing_files must be redefined.") def list_output_parameters_with_existing_files(self): raise NotImplementedError("Analysis is an Abstract class. list_output_parameters_with_existing_files must be redefined.") def has_some_results(self, step_ids=None): raise NotImplementedError("Analysis is an Abstract class. has_some_results must be redefined.") def has_all_results(self, step_ids=None): raise NotImplementedError("Analysis is an Abstract class. has_all_results must be redefined.") def existing_results(self, step_ids=None): raise NotImplementedError("Analysis is an Abstract class. existing_results must be redefined.") def clear_results(self, step_ids=None): to_remove = self.existing_results(step_ids) for filename in to_remove: filenames = self._files_for_format(filename) for f in filenames: if os.path.isfile(f): os.remove(f) elif os.path.isdir(f): shutil.rmtree(f) def _files_for_format(self, filename): ext_map = { 'ima': ['ima', 'dim'], 'img': ['img', 'hdr'], 'arg': ['arg', 'data'], } ext_pos = filename.rfind('.') if ext_pos < 0: return [filename, filename + '.minf'] ext = filename[ext_pos + 1:] exts = ext_map.get(ext, [ext]) fname_base = filename[:ext_pos + 1] return [fname_base + ext for ext in exts] + [filename + '.minf'] def convert_from_formats(self, old_volumes_format, old_meshes_format): # TODO: use aims/somaio IO system for formats extensions exts = [['.nii'], ['.nii.gz'], ['.img', '.hdr'], ['.ima', '.dim'], ['.dcm'], ['.mnc'], ['.gii'], ['.mesh'], ['.ply']] vol_formats = ['.nii', '.nii.gz', '.img', '.ima', '.dcm', '.mnc'] mesh_formats = ['.gii', '.mesh', '.ply'] def _convert_data(old_name, new_name): print('converting:', old_name, 'to:', new_name) data = aims.read(old_name) aims.write(data, new_name) def _remove_data(name): for fexts in exts: for ext in fexts: if name.endswith(ext): basename = name[:-len(ext)] real_exts = fexts + [fexts[0] + '.minf'] for cext in real_exts: filename = basename + cext if os.path.isdir(filename): print('rmtree', filename) shutil.rmtree(filename) elif os.path.exists(filename): print('rm', filename) os.unlink(filename) def _look_for_other_formats(value, new_value): old_format = [fext[0] for fext in exts if value.endswith(fext[0])] if len(old_format) == 0: return value old_format = old_format[0] if old_format in vol_formats: dtype = 0 elif old_format in mesh_formats: dtype = 1 else: return value typed_formats = [vol_formats, mesh_formats] old_base = value[:-len(old_format)] for fexts in exts: if not fexts[0] in typed_formats[dtype]: continue if not isinstance(new_value, basestring) \ or not new_value.endswith(fexts[0]): for ext in fexts: new_old_value = old_base + ext if not os.path.exists(new_old_value): # not OK break else: # found matching format return old_base + fexts[0] return value print('convert analysis', self.subject, 'from formats:', old_volumes_format, old_meshes_format, 'to:', self.study.volumes_format, self.study.meshes_format) #if old_volumes_format == self.study.volumes_format \ #and old_meshes_format == self.study.meshes_format: #print(' nothing to do.') #return old_params = self.parameters # force re-running FOM self.set_parameters(self.subject) todo = [(old_params, self.parameters)] while todo: old_dict, new_dict = todo.pop(0) old_state = old_dict.get('state', {}) new_state = new_dict.get('state', {}) for key, value in six.iteritems(old_state): if isinstance(value, basestring): new_value = new_state.get(key) if not os.path.exists(value) \ and (not isinstance(new_value, basestring) or not os.path.exists(new_value)): value = _look_for_other_formats(value, new_value) if os.path.exists(value): if new_value not in ('', None, traits.Undefined) \ and new_value != value: _convert_data(value, new_value) if new_value != value: _remove_data(value) old_nodes = old_dict.get('nodes', {}) new_nodes = new_dict.get('nodes', {}) if old_nodes: todo += [(node, new_nodes.get(key, {})) for key, node in six.iteritems(old_nodes)]