예제 #1
0
파일: display.py 프로젝트: imcf/cecog
    def __init__(self, parent, plugin_manager, settings):
        super(QFrame, self).__init__(parent)
        self.plugin_manager = plugin_manager
        self.plugin_manager.register_observer(self)

        self.settings = settings
        self._plugins = OrderedDict()

        self.setStyleSheet(
            "PluginItem { border: 1px solid black; background: white; }")

        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        frame1 = QFrame(self)
        self._frame2 = QFrame(self)
        layout.addWidget(frame1)
        layout.addSpacing(10)
        layout.addWidget(self._frame2)

        label = QLabel('%s plugins' % plugin_manager.display_name, frame1)
        label.setStyleSheet("font-weight: bold;")
        btn = QPushButton('Add', frame1)
        btn.clicked.connect(self._on_add_plugin)
        self._cb = QComboBox(frame1)
        self._set_plugin_labels()

        layout = QHBoxLayout(frame1)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(label)
        layout.addWidget(self._cb, 1)
        layout.addWidget(btn)

        layout = QVBoxLayout(self._frame2)
        layout.setContentsMargins(0, 0, 0, 0)
예제 #2
0
파일: config.py 프로젝트: cmci/cecog
class SectionRegistry(object):

    def __init__(self):
        self._registry = OrderedDict()

    def register_section(self, section):
        self._registry[section.SECTION_NAME] = section

    def unregister_section(self, name):
        del self._registry[name]

    def get_section(self, name):
        return self._registry[name]

    def get_section_names(self):
        return self._registry.keys()

    def get_path_settings(self):
        result = []
        for section_name, section in self._registry.iteritems():
            for trait_name in section.get_trait_names():
                trait = section.get_trait(trait_name)
                if (isinstance(trait, StringTrait) and
                    trait.widget_info in [StringTrait.STRING_FILE,
                                          StringTrait.STRING_PATH]):
                    result.append((section_name, trait_name, trait))
        return result
예제 #3
0
    def getSamples(self, className):
        self._loadInfos()
        strPathSamples = os.path.join(self._oLearner.dctEnvPaths['samples'],
                                      className)
        lstResults = []
        if os.path.isdir(strPathSamples):
            #print len(self._oLearner.lstFeatureNames), len()
            dctImagePairs = OrderedDict()
            for strName, oMatch in collect_files_by_regex(strPathSamples, '(?P<prefix>.+?)__(?P<type>(img)|(msk)).+?', ['.png', '.jpg']):
                strPrefix = oMatch.group('prefix')
                strType = oMatch.group('type')
                if not strPrefix in dctImagePairs:
                    dctImagePairs[strPrefix] = {}
                dctImagePairs[strPrefix][strType] = strName

            iIdx = 0
            for dctPair in dctImagePairs.values():
                #oContainer = ccore.SingleObjectContainer(dctPair['img'], dctPair['msk'])
                #strCoords = ",".join(map(str,flatten(oContainer.getCrackCoordinates(1))))
                #print dctPair['img'], dctPair['msk']
                #dctFeatures = {}
                #for iF, strFeatureName in enumerate(self._oLearner.lstFeatureNames):
                #    dctFeatures[strFeatureName] = self._oLearner.dctFeatureData[className][iIdx][iF]
                oSample = Sample(dctPair['img'])
                lstResults.append(oSample)
                iIdx += 1
                #break
        return lstResults
예제 #4
0
    def __init__(self, name=None, path=None):
        #super(Classifier, self).__init__()
        self.name = name
        self.path = path

        self.dctClassInfos = OrderedDict()
        self.dctFeatureInfos = OrderedDict()
        self.isInitialized = False
예제 #5
0
파일: __init__.py 프로젝트: imcf/cecog
 def __init__(self, display_name, name, section):
     super(PluginManager, self).__init__()
     self.display_name = display_name
     self.name = name
     self.section = section
     self._plugins = OrderedDict()
     self._instances = OrderedDict()
     self._observer = []
예제 #6
0
파일: learning.py 프로젝트: cmci/cecog
    def __init__(self, **options):
        self.dctFeatureData = OrderedDict()
        self.dctClassNames = {}
        self.dctClassLabels = {}
        self.lstFeatureNames = None
        self.dctHexColors = {}
        self.dctSampleNames = {}
        self.dctEnvPaths = {}
        self.hasZeroInsert = False
        self.dctImageObjects = OrderedDict()

        super(BaseLearner, self).__init__(**options)
예제 #7
0
 def _updateClassifiers(self):
     self._dctClassifiers = OrderedDict()
     for strName in os.listdir(self.strPath):
         strPathClassifier = os.path.join(self.strPath, strName)
         if os.path.isdir(strPathClassifier) and strName[0] not in ['.', '_']:
             oClassifier = Classifier(strName, strPathClassifier)
             self._dctClassifiers[strName] = oClassifier
예제 #8
0
파일: phenes.py 프로젝트: cmci/cecog
def get_pheno_type_phenes(cls):
    """
    Returns a map containing all phenes of the given (L{PhenoType}) class.

    @param cls: class to query
    @type cls: L{PhenoType}
    @return: phene name (L{str}) to L{Phene} instance map
    @rtype: L{dict}
    """
    phene_map = OrderedDict()
    for base in get_bases(cls) + [cls]:
        for name, value in base.__dict__.iteritems():
            if isinstance(value, Phene):
                phene_map[name] = value
    phene_map.sort(key = lambda name: phene_map[name].rank, reverse=True)
    return phene_map
예제 #9
0
파일: display.py 프로젝트: imcf/cecog
    def __init__(self, parent, plugin_manager, settings):
        super(QFrame, self).__init__(parent)
        self.plugin_manager = plugin_manager
        self.plugin_manager.register_observer(self)

        self.settings = settings
        self._plugins = OrderedDict()

        self.setStyleSheet("PluginItem { border: 1px solid black; background: white; }")

        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        frame1 = QFrame(self)
        self._frame2 = QFrame(self)
        layout.addWidget(frame1)
        layout.addSpacing(10)
        layout.addWidget(self._frame2)

        label = QLabel('%s plugins' % plugin_manager.display_name, frame1)
        label.setStyleSheet("font-weight: bold;")
        btn = QPushButton('Add', frame1)
        btn.clicked.connect(self._on_add_plugin)
        self._cb = QComboBox(frame1)
        self._set_plugin_labels()

        layout = QHBoxLayout(frame1)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(label)
        layout.addWidget(self._cb, 1)
        layout.addWidget(btn)

        layout = QVBoxLayout(self._frame2)
        layout.setContentsMargins(0, 0, 0, 0)
예제 #10
0
def get_pheno_type_phenes(cls):
    """
    Returns a map containing all phenes of the given (L{PhenoType}) class.

    @param cls: class to query
    @type cls: L{PhenoType}
    @return: phene name (L{str}) to L{Phene} instance map
    @rtype: L{dict}
    """
    phene_map = OrderedDict()
    for base in get_bases(cls) + [cls]:
        for name, value in base.__dict__.iteritems():
            if isinstance(value, Phene):
                phene_map[name] = value
    phene_map.sort(key=lambda name: phene_map[name].rank, reverse=True)
    return phene_map
예제 #11
0
파일: config.py 프로젝트: cmci/cecog
    def __init__(self):
        self._registry = OrderedDict()
        self._traitname_grpname = OrderedDict()

        for grp_name, grp_items in self.OPTIONS:
            grp = TraitGroup(grp_name)
            self._registry[grp_name] = grp
            for trait_name, trait in grp_items:
                trait_name = trait_name.lower()
                grp.register_trait(trait_name, trait)
                self._traitname_grpname[trait_name] = grp_name
예제 #12
0
파일: tabcontrol.py 프로젝트: imcf/cecog
    def __init__(self, parent, hide_one=True):
        QFrame.__init__(self, parent)

        self.setStyleSheet(TAB_STYLE)

        self._hide_one = hide_one
        self._tabs = OrderedDict()
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        self._btn_frame = QFrame(self)
        self._btn_grp = QButtonGroup(self._btn_frame)
        self._btn_grp.setExclusive(True)
        self._btn_layout = QHBoxLayout(self._btn_frame)
        self._btn_layout.insertStretch(0, 1)
        self._btn_layout.insertStretch(1, 1)
        self._stacked_frame = QStackedWidget(self)
        self._stacked_frame.setObjectName('stacked')
        layout.addWidget(self._btn_frame)
        layout.addWidget(self._stacked_frame)
        self._btn_frame.hide()
        self._current_name = None
예제 #13
0
파일: analyzer.py 프로젝트: cmci/cecog
    def __init__(self, P, channels, filename, filename_hdf5, meta_data, settings,
                 create_nc=True, reuse_nc=True,
                 hdf5_create=True, hdf5_include_raw_images=True,
                 hdf5_include_label_images=True, hdf5_include_features=True):
        super(TimeHolder, self).__init__()
        self.P = P
        self._iCurrentT = None
        self.channels = channels
        self._meta_data = meta_data
        self._settings = settings

        self._create_nc = create_nc
        self._reuse_nc = reuse_nc

        self._nc4_filename = filename
        self._dataset = None

        self._hdf5_create = hdf5_create
        self._hdf5_include_raw_images = hdf5_include_raw_images
        self._hdf5_include_label_images = hdf5_include_label_images
        self._hdf5_include_features = hdf5_include_features

        self._logger = logging.getLogger(self.__class__.__name__)
        # frames get an index representation with the NC file, starting at 0
        frames = sorted(list(meta_data.times))
        self._frames_to_idx = dict([(f,i) for i, f in enumerate(frames)])
        self._idx_to_frames = dict([(i,f) for i, f in enumerate(frames)])

        channels = sorted(list(meta_data.channels))
        region_names = REGION_NAMES_PRIMARY + REGION_NAMES_SECONDARY
        region_channels = ['primary']*len(REGION_NAMES_PRIMARY) + \
                          ['secondary']*len(REGION_NAMES_SECONDARY)

        region_names2 = [('Primary', 'primary')]
        #channel_names2 = [('Primary']
        settings.set_section('ObjectDetection')
        for prefix in ['secondary', 'tertiary']:
            if settings.get('Processing', '%s_processchannel' % prefix):
                for name in REGION_NAMES_SECONDARY:
                    if settings.get2('%s_regions_%s' % (prefix, name)):
                        region_names2.append((prefix.capitalize(), name))



        self._channels_to_idx = dict([(f,i) for i, f in enumerate(channels)])
        self._idx_to_channels = dict([(i,f) for i, f in enumerate(channels)])

        self._regions_to_idx = dict([(n,i) for i, n in enumerate(region_names)])
        self._regions_to_idx2 = OrderedDict([(n,i) for i, n in enumerate(region_names2)])

        if self._hdf5_create:
            f = h5py.File(filename_hdf5, 'w')
            self._hdf5_file = f
예제 #14
0
파일: config.py 프로젝트: cmci/cecog
class TraitGroup(object):

    def __init__(self, name):
        self.name = name
        self._registry = OrderedDict()

    def register_trait(self, name, trait):
        self._registry[name] = trait

    def get_trait(self, name):
        return self._registry[name]

    def get_trait_names(self):
        return self._registry.keys()
예제 #15
0
파일: config.py 프로젝트: cmci/cecog
class _Section(object):

    SECTION_NAME = None
    OPTIONS = None

    def __init__(self):
        self._registry = OrderedDict()
        self._traitname_grpname = OrderedDict()

        for grp_name, grp_items in self.OPTIONS:
            grp = TraitGroup(grp_name)
            self._registry[grp_name] = grp
            for trait_name, trait in grp_items:
                trait_name = trait_name.lower()
                grp.register_trait(trait_name, trait)
                self._traitname_grpname[trait_name] = grp_name

    def get_group(self, name):
        return self._registry[name]

    def get_group_names(self):
        return self._registry.keys()

    def get_trait(self, trait_name):
        grp_name = self._traitname_grpname[trait_name]
        grp = self._registry[grp_name]
        return grp.get_trait(trait_name)

    def get_trait_names(self):
        names = []
        for grp in self._registry.values():
            names += grp.get_trait_names()
        return set(names)

    def get_trait_names_for_group(self, name):
        grp = self.get_group(name)
        return grp.get_trait_names()
예제 #16
0
파일: __init__.py 프로젝트: imcf/cecog
 def run(self, *args, **options):
     results = OrderedDict()
     for instance in self._instances.itervalues():
         inst_args = list(args)
         if not instance.REQUIRES is None:
             if not 'requirements' in options:
                 raise ValueError((
                     "PluginManager(%s).run needs 'requirements' options, "
                     "because Plugin instances '%s' defines requirements." %
                     (self.name, instance.name)))
             requirements = options['requirements']
             for idx in range(len(instance.REQUIRES)):
                 value = instance.get_requirement_info(idx)[1]
                 data = requirements[idx].get_requirement(value)
                 inst_args.append(data)
         results[instance.name] = instance.run(*inst_args)
     return results
예제 #17
0
class ClassifierService(object):

    def __init__(self, path):
        self.strPath = path
        self._dctClassifiers = None
        self._updateClassifiers()

    def _updateClassifiers(self):
        self._dctClassifiers = OrderedDict()
        for strName in os.listdir(self.strPath):
            strPathClassifier = os.path.join(self.strPath, strName)
            if os.path.isdir(strPathClassifier) and strName[0] not in ['.', '_']:
                oClassifier = Classifier(strName, strPathClassifier)
                self._dctClassifiers[strName] = oClassifier

    def getAll(self, update):
        logging.info("getAll, update: %s" % update)
        if update:
            self._updateClassifiers()
        return self._dctClassifiers.values()

    def getClassInfos(self, name):
        logging.info("getClassInfos")
        oClassifier = self._dctClassifiers[name]
        return oClassifier.classInfos

    def getFeatureInfos(self, name):
        logging.info("getFeatureInfos")
        oClassifier = self._dctClassifiers[name]
        return oClassifier.featureInfos

    def getSampleInfos(self, classifierName, className):
        logging.info("getClassSamples %s %s" % (classifierName, className))
        oClassifier = self._dctClassifiers[classifierName]
        return oClassifier.getSamples(className)

    def getFeatureData(self, classifierName, featureNames):
        logging.info("getFeatureData %s %s" % (classifierName, featureNames))
        oClassifier = self._dctClassifiers[classifierName]
        return oClassifier.getFeatureData(featureNames)
예제 #18
0
    def export_to_xml(self, path, names_to_labels, imagecontainer):
        impl = minidom.getDOMImplementation()
        ann = self._annotations
        for plateid in ann:

            # load plate specific meta data
            imagecontainer.set_plate(plateid)
            meta_data = imagecontainer.get_meta_data()
            time_points = meta_data.times
            # the reference time on which this file is based on
            min_time = time_points[0]

            for position in ann[plateid]:
                ann2 = ann[plateid][position]
                bycn = OrderedDict()
                for time in ann2:
                    for cn in ann2[time]:
                        if not cn in bycn:
                            bycn[cn] = OrderedDict()
                        bycn[cn][time] = ann2[time][cn]

                doc = impl.createDocument(None, 'CellCounter_Marker_File', None)
                top = doc.documentElement
                element = doc.createElement('Marker_Data')
                top.appendChild(element)

                idx_base = time_points.index(min_time)

                for cn in bycn:
                    element2 = doc.createElement('Marker_Type')
                    element.appendChild(element2)
                    element3 = doc.createElement('Type')
                    class_label = names_to_labels[cn]
                    text = doc.createTextNode(str(class_label))
                    element3.appendChild(text)
                    element2.appendChild(element3)
                    for time in bycn[cn]:
                        idx = time_points.index(time) + 1 - idx_base

                        for item in bycn[cn][time]:
                            element3 = doc.createElement('Marker')

                            element4 = doc.createElement('MarkerX')
                            text = doc.createTextNode(str(item[0]))
                            element4.appendChild(text)
                            element3.appendChild(element4)
                            element4 = doc.createElement('MarkerY')
                            text = doc.createTextNode(str(item[1]))
                            element4.appendChild(text)
                            element3.appendChild(element4)
                            element4 = doc.createElement('MarkerZ')
                            text = doc.createTextNode(str(idx))
                            element4.appendChild(text)
                            element3.appendChild(element4)

                            element2.appendChild(element3)

                filename = 'PL%s___P%s___T%05d.xml' % \
                           (plateid, position, min_time)
                f = file(os.path.join(path, filename), 'w')
                doc.writexml(f, indent='  ', addindent='  ', encoding='utf8',
                             newl='\n')
                f.close()
예제 #19
0
파일: display.py 프로젝트: imcf/cecog
class PluginBay(QFrame):

    def __init__(self, parent, plugin_manager, settings):
        super(QFrame, self).__init__(parent)
        self.plugin_manager = plugin_manager
        self.plugin_manager.register_observer(self)

        self.settings = settings
        self._plugins = OrderedDict()

        self.setStyleSheet("PluginItem { border: 1px solid black; background: white; }")

        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        frame1 = QFrame(self)
        self._frame2 = QFrame(self)
        layout.addWidget(frame1)
        layout.addSpacing(10)
        layout.addWidget(self._frame2)

        label = QLabel('%s plugins' % plugin_manager.display_name, frame1)
        label.setStyleSheet("font-weight: bold;")
        btn = QPushButton('Add', frame1)
        btn.clicked.connect(self._on_add_plugin)
        self._cb = QComboBox(frame1)
        self._set_plugin_labels()

        layout = QHBoxLayout(frame1)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(label)
        layout.addWidget(self._cb, 1)
        layout.addWidget(btn)

        layout = QVBoxLayout(self._frame2)
        layout.setContentsMargins(0, 0, 0, 0)

    def init(self):
        self.reset()
        for plugin_name in self.plugin_manager.get_plugin_names():
            self.add_plugin(plugin_name)

    def notify(self, plugin_name, removed):
        pass

    def _set_plugin_labels(self):
        self._cb.clear()
        for name, label in self.plugin_manager.get_plugin_labels():
            self._cb.addItem(label, name)

    def reset(self):
        self._set_plugin_labels()
        for plugin_name in self._plugins.keys()[:]:
            self.remove_plugin(plugin_name)

    def add_plugin(self, plugin_name):
        plugin = self.plugin_manager.get_plugin_instance(plugin_name)
        item = PluginItem(self._frame2, plugin, self.settings)
        item.remove_item.connect(functools.partial(self._on_remove_plugin, plugin_name))
        layout = self._frame2.layout()
        layout.insertWidget(0, item)
        self._plugins[plugin_name] = item

    def remove_plugin(self, plugin_name):
        layout = self._frame2.layout()
        item = self._plugins[plugin_name]
        item.close()
        layout.removeWidget(item)
        del self._plugins[plugin_name]

    def _on_add_plugin(self):
        name_cls = self._cb.itemData(self._cb.currentIndex())
        plugin_name = self.plugin_manager.add_instance(name_cls, self.settings)
        self.add_plugin(plugin_name)

    def _on_remove_plugin(self, plugin_name):
        instance = self.plugin_manager.get_plugin_instance(plugin_name)
        result = False
        n = len(instance.referees)
        if n == 0:
            result = question(None, 'Removing the plugin "%s"' % plugin_name, "Are you sure to remove this plugin?")
        elif n > 0:
            detail = '\n'.join(['%s (%s)' % x[:2] for x in instance.referees])
            result = question(None, 'Removing the plugin "%s"' % plugin_name,
                             '%d other plugin%s require%s this plugin.\n\nAre you sure to remove this plugin?' %
                             (n, 's' if n > 1 else '', 's' if n == 1 else ''),
                             detail=detail, icon=QMessageBox.Warning)
        if result:
            self.remove_plugin(plugin_name)
            self.plugin_manager.remove_instance(plugin_name, self.settings)
예제 #20
0
파일: __init__.py 프로젝트: imcf/cecog
class PluginManager(object):

    PREFIX = 'plugin'
    LABEL = ''

    def __init__(self, display_name, name, section):
        super(PluginManager, self).__init__()
        self.display_name = display_name
        self.name = name
        self.section = section
        self._plugins = OrderedDict()
        self._instances = OrderedDict()
        self._observer = []

    def init_from_settings(self, settings):
        plugin_params = {}
        plugin_cls_names = {}

        for option_name in settings.options(self.section):
            items = option_name.split('__')
            if len(items
                   ) > 4 and items[0] == self.PREFIX and items[1] == self.name:
                plugin_cls_name = items[2]
                plugin_name = items[3]
                params = items[4]
                if not plugin_name in plugin_cls_names:
                    plugin_cls_names[plugin_name] = plugin_cls_name
                else:
                    assert plugin_cls_names[plugin_name] == plugin_cls_name
                plugin_params.setdefault(plugin_name, []).append(
                    (option_name, params))

        for plugin_name in plugin_params:
            plugin_cls_name = plugin_cls_names[plugin_name]
            plugin_cls = self._plugins[plugin_cls_name]
            param_manager = \
                ParamManager.from_settings(plugin_cls, plugin_name, settings, self, plugin_params[plugin_name])
            instance = plugin_cls(plugin_name, param_manager)
            self._instances[plugin_name] = instance
            self.notify_instance_modified(plugin_name)

        for observer in self._observer:
            observer.init()

    def clear(self):
        for plugin_name, instance in self._instances.iteritems():
            instance.close()
            self.notify_instance_modified(plugin_name, True)
        self._instances.clear()

    def add_instance(self, plugin_cls_name, settings):
        if not plugin_cls_name in self._plugins:
            raise ValueError("Plugin '%s' not registered for '%s'." %
                             (plugin_cls_name, self.name))

        plugin_cls = self._plugins[plugin_cls_name]
        plugin_name = self._get_plugin_name(plugin_cls)
        param_manager = ParamManager(plugin_cls, plugin_name, settings, self)
        instance = plugin_cls(plugin_name, param_manager)
        self._instances[plugin_name] = instance
        self.notify_instance_modified(plugin_name)
        return plugin_name

    def remove_instance(self, plugin_name, settings):
        if not plugin_name in self._instances:
            raise ValueError("Plugin instance '%s' not found for '%s'." %
                             (plugin_name, self.name))

        plugin = self._instances[plugin_name]
        plugin.close()
        del self._instances[plugin_name]
        self.notify_instance_modified(plugin_name, True)

    def notify_instance_modified(self, plugin_name, removed=False):
        for observer in self._observer:
            observer.notify(plugin_name, removed)

    def _get_plugin_name(self, plugin_cls):
        """
        generate new plugin name which is not used yet. starting at the plugin class NAME and appending numbers from
        2 to n, like 'primary', 'primary2', 'primary3'
        """
        cnt = 2
        result = plugin_cls.NAME
        while result in self._instances:
            result = plugin_cls.NAME + str(cnt)
            cnt += 1
        return result

    def get_trait_name_template(self, plugin_cls_name, plugin_name):
        return '__'.join(
            [self.PREFIX, self.name, plugin_cls_name, plugin_name, '%s'])

    def register_plugin(self, plugin_cls):
        self._plugins[plugin_cls.NAME] = plugin_cls

    def register_observer(self, observer):
        self._observer.append(observer)

    def unregister_observer(self, observer):
        self._observer.remove(observer)

    def add_referee_to_instance(self, plugin_name, referee):
        instance = self.get_plugin_instance(plugin_name)
        instance.add_referee(referee)

    def remove_referee_from_instance(self, plugin_name, referee):
        instance = self.get_plugin_instance(plugin_name)
        instance.remove_referee(referee)

    def handle_referee(self, plugin_name_new, plugin_name_old, referee):
        # remove old and add new referee to instance
        #print self.name, plugin_name_new, plugin_name_old, referee
        if plugin_name_old in self._instances:
            self.remove_referee_from_instance(plugin_name_old, referee)
        if plugin_name_new in self._instances:
            self.add_referee_to_instance(plugin_name_new, referee)

    def get_referees_for_instance(self, plugin_name):
        instance = self.get_plugin_instance(plugin_name)
        return instance.referees

    def get_plugin_cls_names(self):
        return self._plugins.keys()

    def get_plugin_labels(self):
        return [(name, cls.LABEL) for name, cls in self._plugins.iteritems()]

    def get_plugin_names(self):
        return sorted(self._instances.keys())

    def get_plugin_cls(self, name):
        return self._plugins[name]

    def get_plugin_instance(self, name):
        return self._instances[name]

    def number_loaded_plugins(self):
        """Return the number of plugins that are invoked if run is executed."""
        return len(self._instances)

    # FIXME **option is dangerous, what if one calls run(foo=bar)
    @stopwatch(level=logging.INFO)
    def run(self, *args, **options):
        results = OrderedDict()
        for instance in self._instances.itervalues():
            inst_args = list(args)
            if not instance.REQUIRES is None:
                if not 'requirements' in options:
                    raise ValueError((
                        "PluginManager(%s).run needs 'requirements' options, "
                        "because Plugin instances '%s' defines requirements." %
                        (self.name, instance.name)))
                requirements = options['requirements']
                for idx in range(len(instance.REQUIRES)):
                    value = instance.get_requirement_info(idx)[1]
                    data = requirements[idx].get_requirement(value)
                    inst_args.append(data)
            results[instance.name] = instance.run(*inst_args)
        return results
예제 #21
0
파일: analyzer.py 프로젝트: cmci/cecog
class TimeHolder(OrderedDict):

    NC_GROUP_RAW = 'raw'
    NC_GROUP_LABEL = 'label'
    NC_GROUP_FEATURE = 'feature'
    NC_ZLIB = True
    NC_SHUFFLE = True

    def __init__(self, P, channels, filename, filename_hdf5, meta_data, settings,
                 create_nc=True, reuse_nc=True,
                 hdf5_create=True, hdf5_include_raw_images=True,
                 hdf5_include_label_images=True, hdf5_include_features=True):
        super(TimeHolder, self).__init__()
        self.P = P
        self._iCurrentT = None
        self.channels = channels
        self._meta_data = meta_data
        self._settings = settings

        self._create_nc = create_nc
        self._reuse_nc = reuse_nc

        self._nc4_filename = filename
        self._dataset = None

        self._hdf5_create = hdf5_create
        self._hdf5_include_raw_images = hdf5_include_raw_images
        self._hdf5_include_label_images = hdf5_include_label_images
        self._hdf5_include_features = hdf5_include_features

        self._logger = logging.getLogger(self.__class__.__name__)
        # frames get an index representation with the NC file, starting at 0
        frames = sorted(list(meta_data.times))
        self._frames_to_idx = dict([(f,i) for i, f in enumerate(frames)])
        self._idx_to_frames = dict([(i,f) for i, f in enumerate(frames)])

        channels = sorted(list(meta_data.channels))
        region_names = REGION_NAMES_PRIMARY + REGION_NAMES_SECONDARY
        region_channels = ['primary']*len(REGION_NAMES_PRIMARY) + \
                          ['secondary']*len(REGION_NAMES_SECONDARY)

        region_names2 = [('Primary', 'primary')]
        #channel_names2 = [('Primary']
        settings.set_section('ObjectDetection')
        for prefix in ['secondary', 'tertiary']:
            if settings.get('Processing', '%s_processchannel' % prefix):
                for name in REGION_NAMES_SECONDARY:
                    if settings.get2('%s_regions_%s' % (prefix, name)):
                        region_names2.append((prefix.capitalize(), name))



        self._channels_to_idx = dict([(f,i) for i, f in enumerate(channels)])
        self._idx_to_channels = dict([(i,f) for i, f in enumerate(channels)])

        self._regions_to_idx = dict([(n,i) for i, n in enumerate(region_names)])
        self._regions_to_idx2 = OrderedDict([(n,i) for i, n in enumerate(region_names2)])

        if self._hdf5_create:
            f = h5py.File(filename_hdf5, 'w')
            self._hdf5_file = f

    def create_nc4(self):
        settings = self._settings
        if (self._create_nc and self._reuse_nc and self._dataset is None and
            os.path.isfile(self._nc4_filename)):
            dataset = netCDF4.Dataset(self._nc4_filename, 'a')

            # decide which parts need to be reprocessed based on changes
            # between the saved (from nc4) and the current settings

            # load settings from nc4 file
            #var = str(dataset.variables['settings'][:][0])
            #settings2 = settings.copy()
            #settings2.from_string(var)

            # compare current and saved settings and decide which data is to
            # process again by setting the *_finished variables to zero

#            valid = {'primary'   : [True, True],
#                     'secondary' : [True, True],
#                     }
#            for name in ['primary', 'secondary']:
#                channel_id = settings2.get(SECTION_NAME_OBJECTDETECTION,
#                                           '%s_channelid' % name)
#                idx = dataset.variables['channels_idx'][:] == channel_id
#                if (not settings.compare(settings2, SECTION_NAME_OBJECTDETECTION,
#                                         '%s_image' % name) or
#                    not settings.compare(settings2, SECTION_NAME_OBJECTDETECTION,
#                                         'secondary_registration') or
#                    not valid[name][0]):
#                    dataset.variables['raw_images_finished'][:,idx] = 0
#                    valid['primary'] = [False, False]
#                    valid['secondary'] = [False, False]
#                idx = dataset.variables['region_channels'][:] == name
#                if (not settings.compare(settings2, SECTION_NAME_OBJECTDETECTION,
#                                        '%s_segmentation' % name) or
#                    not valid[name][1]):
#                    dataset.variables['label_images_finished'][:,idx] = 0
#                    valid['primary'] = [False, False]
#                    valid['secondary'] = [False, False]

        elif self._create_nc and self._dataset is None:
            meta = self._meta_data
            dim_t = meta.dim_t
            dim_c = meta.dim_c
            w = meta.real_image_width
            h = meta.real_image_height

            channels = sorted(list(meta.channels))
            region_names = REGION_NAMES_PRIMARY + REGION_NAMES_SECONDARY
            region_channels = ['primary']*len(REGION_NAMES_PRIMARY) + \
                              ['secondary']*len(REGION_NAMES_SECONDARY)

            dataset = netCDF4.Dataset(self._nc4_filename, 'w', format='NETCDF4')
            dataset.createDimension('frames', dim_t)
            dataset.createDimension('channels', dim_c)
            dataset.createDimension('height', h)
            dataset.createDimension('width', w)
            dataset.createDimension('regions', len(region_names))
            dataset.createDimension('one', 1)

            frames = sorted(list(meta.times))
            var = dataset.createVariable('frames_idx', 'u4', 'frames')
            var.description = 'Mapping from indices to frames.'
            var[:] = frames

            var = dataset.createVariable('settings', str, 'one')
            var.description = 'Cecog settings used for the generation of this '\
                              'netCDF file. Current cecog and this settings '\
                              'are compared hierarchically leading to a '\
                              'stepwise invalidation of preprocessed values.'

            raw_g = dataset.createGroup(self.NC_GROUP_RAW)
            raw_g.description = 'Converted raw images as processed by cecog '\
                                'after 8bit conversion, registration, and '\
                                'z-projection/selection.'
            label_g = dataset.createGroup(self.NC_GROUP_LABEL)
            label_g.description = 'Label images as a result of object '\
                                  'detection.'

            object_g = dataset.createGroup('object')
            object_g.description = 'General object values and mapping'
            feature_g = dataset.createGroup(self.NC_GROUP_FEATURE)
            feature_g.description = 'Feature values'

            for channel_id in meta.channels:
                var = raw_g.createVariable(channel_id, 'u1',
                                           ('frames', 'height', 'width'),
                                           zlib=self.NC_ZLIB,
                                           shuffle=self.NC_SHUFFLE,
                                           chunksizes=(1, h, w))
                # FIXME: not working for dim_t == 1 (no timelapse data)
                var.valid = [0] * dim_t
                #print channel_id, dim_t, var.valid

            for channel_name in REGION_NAMES.keys():
                channel_g = label_g.createGroup(channel_name)
                grp1 = object_g.createGroup(channel_name)
                grp2 = feature_g.createGroup(channel_name)
                for region_name in REGION_NAMES[channel_name]:
                    var = channel_g.createVariable(region_name, 'i2',
                                                   ('frames', 'height',
                                                    'width'),
                                                   zlib=self.NC_ZLIB,
                                                   shuffle=self.NC_SHUFFLE,
                                                   chunksizes=(1, h, w))
                    var.valid = [0] * dim_t
                    grp1.createGroup(region_name)
                    grp2.createGroup(region_name)

            var = dataset.createVariable('channels_idx', str, 'channels')
            var[:] = numpy.asarray(channels, 'O')

            var = dataset.createVariable('region_names', str, 'regions')
            var[:] = numpy.asarray(region_names, 'O')

            var = dataset.createVariable('region_channels', str, 'regions')
            var[:] = numpy.asarray(region_channels, 'O')

            dataset.createVariable('raw_images', 'u1',
                                   ('frames', 'channels', 'height', 'width'),
                                   zlib='True',
                                   shuffle=False,
                                   chunksizes=(1, 1, h, w)
                                   )
            finished = dataset.createVariable('raw_images_finished', 'i1',
                                              ('frames', 'channels'))
            finished[:] = 0

            dataset.createVariable('label_images', 'i2',
                                   ('frames', 'regions', 'height', 'width'),
                                   zlib='True',
                                   shuffle=False,
                                   chunksizes=(1, 1, h, w)
                                   )
            finished = dataset.createVariable('label_images_finished', 'i1',
                                              ('frames', 'regions'))

            finished[:] = 0
        else:
            dataset = None

        if not dataset is None:
            # update the settings to the current version
            var = dataset.variables['settings']
            var[:] = numpy.asarray(settings.to_string(), 'O')
            self._dataset = dataset

    @staticmethod
    def nc_valid_set(var, idx, value):
        helper = var.valid
        if len(helper.shape) == 0:
            helper = value
        else:
            helper[idx] = value
        var.valid = helper

    def close_all(self):
        if not self._dataset is None:
            self._dataset.close()
            self._dataset = None
            self._create_nc = False
        if self._hdf5_create:
            self._hdf5_file.close()
            self._hdf5_create = False

    def __del__(self):
        self.close_all()

    def initTimePoint(self, iT):
        self._iCurrentT = iT

    def getCurrentTimePoint(self):
        return self._iCurrentT

    def getCurrentChannels(self):
        return self[self._iCurrentT]

    def purge_features(self):
        for channels in self.itervalues():
            for channel in channels.itervalues():
                channel.purge(features={})

    def apply_channel(self, oChannel):
        iT = self._iCurrentT
        if not iT in self:
            self[iT] = OrderedDict()
        self[iT][oChannel.NAME] = oChannel
        self[iT].sort(key = lambda x: self[iT][x])

    def apply_segmentation(self, channel, primary_channel=None):
        self.create_nc4()
        valid = False
        desc = '[P %s, T %05d, C %s]' % (self.P, self._iCurrentT,
                                         channel.strChannelId)
        name = channel.NAME.lower()
        if self._create_nc or self._reuse_nc:
            grp = self._dataset.groups[self.NC_GROUP_LABEL]
            grp = grp.groups[name]
            frame_idx = self._frames_to_idx[self._iCurrentT]
        if self._reuse_nc:
            for region_name in channel.lstAreaSelection:
                var = grp.variables[region_name]
                if len(var.valid.shape) == 0:
                    frame_valid = var.valid
                else:
                    frame_valid = var.valid[frame_idx]
                if frame_valid:
                    img_label = ccore.numpy_to_image(var[frame_idx],
                                                     copy=True)
                    img_xy = channel.meta_image.image
                    container = ccore.ImageMaskContainer(img_xy, img_label,
                                                         False, True, True)
                    channel.dctContainers[region_name] = container
                    valid = True
                else:
                    valid = False
                    break
        if not valid:
            channel.apply_segmentation(primary_channel)
            if self._create_nc:
                for region_name in channel.lstAreaSelection:
                    var = grp.variables[region_name]
                    container = channel.dctContainers[region_name]
                    var[frame_idx] = \
                        container.img_labels.toArray(copy=False)
                    self.nc_valid_set(var, frame_idx, 1)
                self._logger.debug('Label images %s written to nc4 file.' %\
                                   desc)
        else:
            self._logger.debug('Label images %s loaded from nc4 file.' %\
                   desc)

        if self._hdf5_create and self._hdf5_include_label_images:
            meta = self._meta_data
            w = meta.real_image_width
            h = meta.real_image_height
            f = self._hdf5_file
            if 'labeled_images' in f:
                labeled_images = f['labeled_images']
            else:
                nr_labels = len(self._regions_to_idx2)
                dt = h5py.special_dtype(vlen=str)
                names = f.create_dataset('label_names', (nr_labels, 2), dt)
                for tpl, idx in self._regions_to_idx2.iteritems():
                    names[idx] = tpl
                labeled_images = f.create_dataset('label_images', (nr_labels, meta.dim_t, meta.dim_z, w, h),
                                                  'int32', compression='szip', chunks=(1,1,meta.dim_z,w,h))

            frame_idx = self._frames_to_idx[self._iCurrentT]
            for region_name in channel.lstAreaSelection:
                idx = self._regions_to_idx2[(channel.NAME, region_name)]
                container = channel.dctContainers[region_name]
                array = container.img_labels.toArray(copy=False)
                labeled_images[idx, frame_idx, 0] = numpy.require(array, 'int32')


    def prepare_raw_image(self, channel):
        self.create_nc4()

        desc = '[P %s, T %05d, C %s]' % (self.P, self._iCurrentT,
                                         channel.strChannelId)
        if self._create_nc or self._reuse_nc:
            grp = self._dataset.groups[self.NC_GROUP_RAW]
            var = grp.variables[channel.strChannelId]
            frame_idx = self._frames_to_idx[self._iCurrentT]
            
            if len(var.valid.shape) == 0:
                frame_valid = var.valid
            else:
                frame_valid = var.valid[frame_idx]
                    
        if self._reuse_nc and frame_valid:
            coordinate = Coordinate(position=self.P, time=self._iCurrentT,
                                    channel=channel.strChannelId, zslice=1)
            meta_image = MetaImage(image_container=None, coordinate=coordinate)

            img = ccore.numpy_to_image(var[frame_idx], copy=True)
            meta_image.set_image(img)
            meta_image.set_raw_image(img)
            channel.meta_image = meta_image
            self._logger.debug('Raw image %s loaded from nc4 file.' % desc)
        else:
            channel.apply_zselection()
            channel.normalize_image()
            channel.apply_registration()
            if self._create_nc:
                img = channel.meta_image.image
                grp = self._dataset.groups[self.NC_GROUP_RAW]
                var = grp.variables[channel.strChannelId]
                var[frame_idx] = img.toArray(copy=False)
                self.nc_valid_set(var, frame_idx, 1)
                self._logger.debug('Raw image %s written to nc4 file.' % desc)

        if self._hdf5_create and self._hdf5_include_raw_images:
            meta = self._meta_data
            w = meta.real_image_width
            h = meta.real_image_height
            f = self._hdf5_file
            if 'images' in f:
                images = f['images']
            else:
                images = f.create_dataset('pre_images', (meta.dim_c, meta.dim_t, meta.dim_z, w, h),
                                          'uint8', compression='szip', chunks=(1,1,meta.dim_z,w,h))
                dt = h5py.special_dtype(vlen=str)
                channels = f.create_dataset('channel_names', (meta.dim_c,), dt)
                for idx in range(meta.dim_c):
                    channels[idx] = self._idx_to_channels[idx]

            frame_idx = self._frames_to_idx[self._iCurrentT]
            channel_idx = self._channels_to_idx[channel.strChannelId]
            img = channel.meta_image.image
            array = img.toArray(copy=False)
            print array.shape, (meta.dim_c, meta.dim_t, meta.dim_z, w, h), frame_idx, channel_idx
            images[channel_idx, frame_idx, 0] = array

    def apply_features(self, channel):
        self.create_nc4()
        valid = False
        desc = '[P %s, T %05d, C %s]' % (self.P, self._iCurrentT,
                                         channel.strChannelId)

        name = channel.NAME.lower()
        channel.apply_features()

        if self._hdf5_create and self._hdf5_include_features:
            meta = self._meta_data
            w = meta.real_image_width
            h = meta.real_image_height
            f = self._hdf5_file
            if 'features' in f:
                features = f['features']
            else:
                features = f.create_group('features')

            if 'objects' in f:
                objects = f['objects']
            else:
                objects = f.create_group('objects')

#        #nr_objects
#
#        data_f = features.create_dataset(str(self._iCurrentT), (), 'float32',
#                                         compression='szip', chunks=())
#        data_o = objects.create_dataset(str(self._iCurrentT), (), 'float32',
#                                         compression='szip', chunks=())
#
#            nr_labels = len(self._regions_to_idx2)
#            dt = h5py.special_dtype(vlen=str)
#            names = f.create_dataset('label_names', (nr_labels, 2), dt)
#            for tpl, idx in self._regions_to_idx2.iteritems():
#                names[idx] = tpl
#            labeled_images = f.create_dataset('labeled_images', (nr_labels, meta.dim_t, meta.dim_z, w, h),
#                                              'int32', compression='szip', chunks=(1,1,meta.dim_z,w,h))
#
#        frame_idx = self._frames_to_idx[self._iCurrentT]
#        for region_name in channel.lstAreaSelection:
#            idx = self._regions_to_idx2[(channel.NAME, region_name)]
#            container = channel.dctContainers[region_name]
#            array = container.img_labels.toArray(copy=False)
#            labeled_images[idx, frame_idx, 0] = numpy.require(array, 'int32')



    def extportObjectCounts(self, filename, P, meta_data, prim_info=None,
                            sec_info=None, sep='\t'):
        f = file(filename, 'w')
        has_header = False

        for frame, channels in self.iteritems():
            #channels.sort(key = lambda x: channels[x])

            line1 = []
            line2 = []
            line3 = []
            line4 = []
            items = []
            coordinate = Coordinate(position=P, time=frame)
            prefix = [frame, meta_data.get_timestamp_relative(coordinate)]
            prefix_names = ['frame', 'time']

            for channel in channels.values():
                if channel.NAME == 'Primary' and not prim_info is None:
                    region_info = prim_info
                elif channel.NAME == 'Secondary' and not sec_info is None:
                    region_info = sec_info
                else:
                    region_info = None

                if not region_info is None:
                    region_name, class_names = region_info
                    if not has_header:
                        keys = ['total'] + class_names
                        line4 += keys
                        line3 += ['total'] + ['class']*len(class_names)
                        line1 += [channel.NAME.upper()] * len(keys)
                        line2 += [region_name] * len(keys)

                    if channel.has_region(region_name):
                        region = channel.get_region(region_name)
                        total = len(region)
                        count = dict([(x, 0) for x in class_names])
                        # in case just total counts are needed
                        if len(class_names) > 0:
                            for obj in region.values():
                                count[obj.strClassName] += 1
                        items += [total] + [count[x] for x in class_names]
                    else:
                        items += [numpy.NAN] * (len(class_names) + 1)

            if not has_header:
                has_header = True
                prefix_str = [''] * len(prefix)
                f.write('%s\n' % sep.join(prefix_str + line1))
                f.write('%s\n' % sep.join(prefix_str + line2))
                f.write('%s\n' % sep.join(prefix_str + line3))
                f.write('%s\n' % sep.join(prefix_names + line4))

            f.write('%s\n' % sep.join(map(str, prefix + items)))

        f.close()


    def extportObjectDetails(self, filename, sep='\t', excel_style=False):
        f = file(filename, 'w')

        feature_lookup = OrderedDict()
        feature_lookup['mean'] = 'n2_avg'
        feature_lookup['sd'] = 'n2_stddev'
        feature_lookup['size'] = 'roisize'

        has_header = False
        line1 = []
        line2 = []
        line3 = []

        for frame, channels in self.iteritems():

            items = []
            prim_region = channels.values()[0].get_region('primary')

            for obj_id in prim_region:

                prefix = [frame, obj_id]
                prefix_names = ['frame', 'objID']
                items = []

                for channel in channels.values():

                    for region_id in channel.region_names():

                        region = channel.get_region(region_id)
                        if obj_id in region:
                            #FIXME:
                            feature_lookup2 = feature_lookup.copy()
                            for k,v in feature_lookup2.items():
                                if not region.hasFeatureName(v):
                                    del feature_lookup2[k]

                            if not has_header:
                                keys = ['classLabel', 'className']
                                if channel.NAME == 'Primary':
                                    keys += ['centerX', 'centerY']
                                keys += feature_lookup2.keys()
                                if excel_style:
                                    line1 += [channel.NAME.upper()] * len(keys)
                                    line2 += [region_id] * len(keys)
                                    line3 += keys
                                else:
                                    line1 += ['%s_%s_%s' % (channel.NAME.upper(),
                                                            region_id, key)
                                              for key in keys]

                            obj = region[obj_id]
                            #print feature_lookup2.keys(), feature_lookup2.values()
                            #fn = region.getFeatureNames()
                            #print zip(fn, obj.aFeatures)
                            features = region.getFeaturesByNames(obj_id, feature_lookup2.values())
                            values = [x if not x is None else '' for x in [obj.iLabel, obj.strClassName]]
                            if channel.NAME == 'Primary':
                                values += [obj.oCenterAbs[0], obj.oCenterAbs[1]]
                            values += list(features)
                            items.extend(values)

                if not has_header:
                    has_header = True
                    prefix_str = [''] * len(prefix)
                    if excel_style:
                        line1 = prefix_str + line1
                        line2 = prefix_str + line2
                        line3 = prefix_names + line3
                        f.write('%s\n' % sep.join(line1))
                        f.write('%s\n' % sep.join(line2))
                        f.write('%s\n' % sep.join(line3))
                    else:
                        line1 = prefix_names + line1
                        f.write('%s\n' % sep.join(line1))

                f.write('%s\n' % sep.join(map(str, prefix + items)))

        f.close()
        
    def extportImageFileNames(self, output_path, position_str, imagecontainer, channel_mapping):
        channel_mapping_reversed = dict([(v,k) for k,v in channel_mapping.iteritems()])
        filename = os.path.join(output_path, 'P%s__image_files.txt' % self.P)
        importer = imagecontainer._importer
        table = {}
        for c in channel_mapping:
            table[c] = []
        for t in self.keys():
            for c in channel_mapping.values():
                for z in importer.dimension_lookup[position_str][t][c]:
                    c_name = channel_mapping_reversed[c]
                    table[c_name].append(os.path.join(importer.path, importer.dimension_lookup[position_str][t][c][z]))
                    
        f = open(filename, 'w')
        f.write("\t".join(table.keys()) + "\n")
        for image_file_names in zip(*table.values()):
            f.write("\t".join(image_file_names) + "\n")
        f.close()
예제 #22
0
파일: display.py 프로젝트: imcf/cecog
class PluginBay(QFrame):
    def __init__(self, parent, plugin_manager, settings):
        super(QFrame, self).__init__(parent)
        self.plugin_manager = plugin_manager
        self.plugin_manager.register_observer(self)

        self.settings = settings
        self._plugins = OrderedDict()

        self.setStyleSheet(
            "PluginItem { border: 1px solid black; background: white; }")

        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        frame1 = QFrame(self)
        self._frame2 = QFrame(self)
        layout.addWidget(frame1)
        layout.addSpacing(10)
        layout.addWidget(self._frame2)

        label = QLabel('%s plugins' % plugin_manager.display_name, frame1)
        label.setStyleSheet("font-weight: bold;")
        btn = QPushButton('Add', frame1)
        btn.clicked.connect(self._on_add_plugin)
        self._cb = QComboBox(frame1)
        self._set_plugin_labels()

        layout = QHBoxLayout(frame1)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(label)
        layout.addWidget(self._cb, 1)
        layout.addWidget(btn)

        layout = QVBoxLayout(self._frame2)
        layout.setContentsMargins(0, 0, 0, 0)

    def init(self):
        self.reset()
        for plugin_name in self.plugin_manager.get_plugin_names():
            self.add_plugin(plugin_name)

    def notify(self, plugin_name, removed):
        pass

    def _set_plugin_labels(self):
        self._cb.clear()
        for name, label in self.plugin_manager.get_plugin_labels():
            self._cb.addItem(label, name)

    def reset(self):
        self._set_plugin_labels()
        for plugin_name in self._plugins.keys()[:]:
            self.remove_plugin(plugin_name)

    def add_plugin(self, plugin_name):
        plugin = self.plugin_manager.get_plugin_instance(plugin_name)
        item = PluginItem(self._frame2, plugin, self.settings)
        item.remove_item.connect(
            functools.partial(self._on_remove_plugin, plugin_name))
        layout = self._frame2.layout()
        layout.insertWidget(0, item)
        self._plugins[plugin_name] = item

    def remove_plugin(self, plugin_name):
        layout = self._frame2.layout()
        item = self._plugins[plugin_name]
        item.close()
        layout.removeWidget(item)
        del self._plugins[plugin_name]

    def _on_add_plugin(self):
        name_cls = self._cb.itemData(self._cb.currentIndex())
        plugin_name = self.plugin_manager.add_instance(name_cls, self.settings)
        self.add_plugin(plugin_name)

    def _on_remove_plugin(self, plugin_name):
        instance = self.plugin_manager.get_plugin_instance(plugin_name)
        result = False
        n = len(instance.referees)
        if n == 0:
            result = question(None, 'Removing the plugin "%s"' % plugin_name,
                              "Are you sure to remove this plugin?")
        elif n > 0:
            detail = '\n'.join(['%s (%s)' % x[:2] for x in instance.referees])
            result = question(
                None,
                'Removing the plugin "%s"' % plugin_name,
                '%d other plugin%s require%s this plugin.\n\nAre you sure to remove this plugin?'
                % (n, 's' if n > 1 else '', 's' if n == 1 else ''),
                detail=detail,
                icon=QMessageBox.Warning)
        if result:
            self.remove_plugin(plugin_name)
            self.plugin_manager.remove_instance(plugin_name, self.settings)
예제 #23
0
파일: CecogAnalyzer.py 프로젝트: cmci/cecog
    def __init__(self):
        QMainWindow.__init__(self)
        qApp._main_window = self

        self._is_initialized = False
        self._debug = False
        self._imagecontainer = None
        self._meta_data = None
        self._browser = None

        self.setWindowTitle(self.TITLE + '[*]')

        central_widget = QFrame(self)
        self.setCentralWidget(central_widget)


        action_about = self.create_action('&About', slot=self._on_about)
        action_quit = self.create_action('&Quit', slot=self._on_quit)
        action_pref = self.create_action('&Preferences',
                                         slot=self._on_preferences)

        #action_new = self.create_action('&New...', shortcut=QKeySequence.New,
        #                                  icon='filenew')
        action_open = self.create_action('&Open Settings...',
                                         shortcut=QKeySequence.Open,
                                         slot=self._on_file_open
                                         )
        action_save = self.create_action('&Save Settings',
                                         shortcut=QKeySequence.Save,
                                         slot=self._on_file_save
                                         )
        self.action_save = action_save
        action_save_as = self.create_action('&Save Settings As...',
                                            shortcut=QKeySequence.SaveAs,
                                            slot=self._on_file_save_as
                                            )
        menu_file = self.menuBar().addMenu('&File')
        self.add_actions(menu_file, (action_about, action_pref,
                                     None, action_open,
                                     None, action_save, action_save_as,
                                     None, action_quit))

        action_open = self.create_action('&Open Browser...',
                                         shortcut=QKeySequence('CTRL+B'),
                                         slot=self._on_browser_open
                                         )
        menu_browser = self.menuBar().addMenu('&Browser')
        self.add_actions(menu_browser, (action_open,
                                     #None, action_save, action_save_as,
                                     #None, action_quit
                                     ))

        action_log = self.create_action('&Show Log Window...',
                                        shortcut=QKeySequence(Qt.CTRL + Qt.Key_L),
                                        slot=self._on_show_log_window
                                        )
        menu_window = self.menuBar().addMenu('&Window')
        self.add_actions(menu_window, (action_log,
                                       ))

        action_help_startup = self.create_action('&Startup Help...',
                                                 shortcut=QKeySequence.HelpContents,
                                                 slot=self._on_help_startup
                                                )
        menu_help = self.menuBar().addMenu('&Help')
        self.add_actions(menu_help, (action_help_startup,))

        qApp._statusbar = QStatusBar(self)
        self.setStatusBar(qApp._statusbar)


        self._selection = QListWidget(central_widget)
        self._selection.setViewMode(QListView.IconMode)
        #self._selection.setUniformItemSizes(True)
        self._selection.setIconSize(QSize(35, 35))
        self._selection.setGridSize(QSize(140, 60))
        #self._selection.setWrapping(False)
        self._selection.setMovement(QListView.Static)
        #self._selection.setFlow(QListView.TopToBottom)
        #self._selection.setSpacing(12)
        self._selection.setMaximumWidth(self._selection.gridSize().width() + 5)
        self._selection.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self._selection.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,
                                                  QSizePolicy.Expanding))

        self._pages = QStackedWidget(central_widget)
        self._pages.main_window = self

        self._settings_filename = None
        self._settings = GuiConfigSettings(self, SECTION_REGISTRY)

        self._tab_lookup = OrderedDict()
        self._tabs = [GeneralFrame(self._settings, self._pages),
                      ObjectDetectionFrame(self._settings, self._pages),
                      FeatureExtractionFrame(self._settings, self._pages),
                      ClassificationFrame(self._settings, self._pages),
                      TrackingFrame(self._settings, self._pages),
                      ErrorCorrectionFrame(self._settings, self._pages),
                      OutputFrame(self._settings, self._pages),
                      ProcessingFrame(self._settings, self._pages),
                      ]
        if ANALYZER_CONFIG.get('Analyzer', 'cluster_support'):
            self._tabs.append(ClusterFrame(self._settings, self._pages))

        widths = []
        for tab in self._tabs:
            size = self._add_page(tab)
            widths.append(size.width())
        self.set_modules_active(state=False)
        self._pages.setMinimumWidth(max(widths) + 45)

        self._selection.currentItemChanged.connect(self._on_change_page)

        self._selection.setCurrentRow(0)

        w_logo = QLabel(central_widget)
        w_logo.setPixmap(QPixmap(':cecog_logo_w145'))

        layout = QGridLayout(central_widget)
        layout.addWidget(self._selection, 0, 0)
        layout.addWidget(w_logo, 1, 0, Qt.AlignBottom | Qt.AlignHCenter)
        layout.addWidget(self._pages, 0, 1, 2, 1)

        qApp._log_handler = GuiLogHandler(self)
        qApp._log_window = LogWindow(qApp._log_handler)
        qApp._log_window.setGeometry(50, 50, 600, 300)

        logger = logging.getLogger()
        qApp._log_handler.setLevel(logging.NOTSET)
        formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s')
        qApp._log_handler.setFormatter(formatter)
        #logger.addHandler(self._handler)
        logger.setLevel(logging.NOTSET)

        qApp._image_dialog = None
        qApp._graphics = None

        self.setGeometry(0, 0, 1100, 750)
        self.setMinimumSize(QSize(700, 600))
        self.show()
        self.center()
        self.raise_()
        self._is_initialized = True
예제 #24
0
파일: analyzer.py 프로젝트: cmci/cecog
class CellAnalyzer(PropertyManager):

    PROPERTIES = \
        dict(P =
                 StringProperty(True, doc=''),
             bCreateImages =
                 BooleanProperty(True, doc="Create output images"),
             iBinningFactor =
                 IntProperty(None,
                             is_mandatory=True,
                             doc=''),
             detect_objects =
                 BooleanProperty(True),


             time_holder =
                 InstanceProperty(None,
                                  TimeHolder,
                                  doc="Instance of TimeHolder.",
                                  is_mandatory=True),
            )

    __attributes__ = [Attribute('_channel_registry'),
                      Attribute('_iT'),
                      Attribute('_oLogger'),
                      ]

    def __init__(self, **dctOptions):
        super(CellAnalyzer, self).__init__(**dctOptions)
        self._oLogger = logging.getLogger(self.__class__.__name__)

    def initTimepoint(self, iT):
        self._channel_registry = OrderedDict()
        self._iT = iT
        self.time_holder.initTimePoint(iT)

    def register_channel(self, channel):
        self._channel_registry[channel.NAME] = channel

    def get_channel_names(self):
        return self._channel_registry.keys()

    def get_channel(self, name):
        return self._channel_registry[name]

    def process(self, apply=True, extract_features=True):
        # sort by Channel `RANK`
        channels = sorted(self._channel_registry.values())
        primary_channel = None
        for channel in channels:

            self.time_holder.prepare_raw_image(channel)

            if self.detect_objects:
                self.time_holder.apply_segmentation(channel, primary_channel)
                if extract_features:
                    self.time_holder.apply_features(channel)

                if primary_channel is None:
                    assert channel.RANK == 1
                    primary_channel = channel

        if apply:
            for channel in channels:
                self.time_holder.apply_channel(channel)

    def purge(self, features=None):
        for oChannel in self._channel_registry.values():
            if not features is None and oChannel.strChannelId in features:
                channelFeatures = features[oChannel.strChannelId]
            else:
                channelFeatures = None
            oChannel.purge(features=channelFeatures)

    def exportLabelImages(self, pathOut, compression='LZW'):
        for name, channel in self._channel_registry.iteritems():
            channel_id = channel.strChannelId
            for strRegion, oContainer in channel.dctContainers.iteritems():
                strPathOutImage = os.path.join(pathOut,
                                               channel_id,
                                               strRegion)
                safe_mkdirs(strPathOutImage)
                oContainer.exportLabelImage(os.path.join(strPathOutImage,
                                                         'P%s_T%05d.tif' % (self.P, self._iT)),
                                            compression)

    def getImageSize(self, name):
        oChannel = self._channel_registry[name]
        w = oChannel.meta_image.width
        h = oChannel.meta_image.height
        return (w,h)

    def render(self, strPathOut, dctRenderInfo=None,
               strFileSuffix='.jpg', strCompression='98', writeToDisc=True,
               images=None):
        lstImages = []
        if not images is None:
            lstImages += images

        if dctRenderInfo is None:
            for name, oChannel in self._channel_registry.iteritems():
                for strRegion, oContainer in oChannel.dctContainers.iteritems():
                    strHexColor, fAlpha = oChannel.dctAreaRendering[strRegion]
                    imgRaw = oChannel.meta_image.image
                    imgCon = ccore.Image(imgRaw.width, imgRaw.height)
                    ccore.drawContour(oContainer.getBinary(), imgCon, 255, False)
                    lstImages.append((imgRaw, strHexColor, 1.0))
                    lstImages.append((imgCon, strHexColor, fAlpha))
        else:
            for channel_name, dctChannelInfo in dctRenderInfo.iteritems():
                if channel_name in self._channel_registry:
                    oChannel = self._channel_registry[channel_name]
                    if 'raw' in dctChannelInfo:
                        strHexColor, fAlpha = dctChannelInfo['raw']
                        lstImages.append((oChannel.meta_image.image, strHexColor, fAlpha))

                    if 'contours' in dctChannelInfo:
                        # transform the old dict-style to the new tuple-style,
                        # which allows multiple definitions for one region
                        if type(dctChannelInfo['contours']) == types.DictType:
                            lstContourInfos = [(k,)+v
                                               for k,v in dctChannelInfo['contours'].iteritems()]
                        else:
                            lstContourInfos = dctChannelInfo['contours']

                        for tplData in lstContourInfos:
                            strRegion, strNameOrColor, fAlpha, bShowLabels = tplData[:4]

                            # draw contours only if region is present
                            if oChannel.has_region(strRegion):
                                if len(tplData) > 4:
                                    bThickContours = tplData[4]
                                else:
                                    bThickContours = False
                                if strNameOrColor == 'class_label':
                                    oContainer = oChannel.dctContainers[strRegion]
                                    oRegion = oChannel.get_region(strRegion)
                                    dctLabels = {}
                                    dctColors = {}
                                    for iObjId, oObj in oRegion.iteritems():
                                        iLabel = oObj.iLabel
                                        if not iLabel is None:
                                            if not iLabel in dctLabels:
                                                dctLabels[iLabel] = []
                                            dctLabels[iLabel].append(iObjId)
                                            dctColors[iLabel] = oObj.strHexColor
                                    #print dctLabels
                                    imgRaw = oChannel.meta_image.image
                                    imgCon2 = ccore.Image(imgRaw.width, imgRaw.height)
                                    for iLabel, lstObjIds in dctLabels.iteritems():
                                        imgCon = ccore.Image(imgRaw.width, imgRaw.height)
                                        oContainer.drawContoursByIds(lstObjIds, 255, imgCon, bThickContours, False)
                                        lstImages.append((imgCon, dctColors[iLabel], fAlpha))

                                        if type(bShowLabels) == types.BooleanType and bShowLabels:
                                        #    oContainer.drawTextsByIds(lstObjIds, lstObjIds, imgCon2)
                                        #else:
                                            oContainer.drawTextsByIds(lstObjIds, [str(iLabel)]*len(lstObjIds), imgCon2)
                                    lstImages.append((imgCon2, '#FFFFFF', 1.0))

                                else:
                                    oContainer = oChannel.dctContainers[strRegion]
                                    oRegion = oChannel.get_region(strRegion)
                                    lstObjIds = oRegion.keys()
                                    imgRaw = oChannel.meta_image.image
                                    imgCon = ccore.Image(imgRaw.width, imgRaw.height)
                                    if not strNameOrColor is None:
                                        oContainer.drawContoursByIds(lstObjIds, 255, imgCon, bThickContours, False)
                                    else:
                                        strNameOrColor = '#FFFFFF'
                                    lstImages.append((imgCon, strNameOrColor, fAlpha))
                                    if bShowLabels:
                                        imgCon2 = ccore.Image(imgRaw.width, imgRaw.height)
                                        oContainer.drawLabelsByIds(lstObjIds, imgCon2)
                                        lstImages.append((imgCon2, '#FFFFFF', 1.0))


        if len(lstImages) > 0:
            imgRgb = ccore.makeRGBImage([x[0].getView() for x in lstImages],
                                        [ccore.RGBValue(*hexToRgb(x[1])) for x in lstImages],
                                        [x[2] for x in lstImages])

            if writeToDisc:
                strFilePath = os.path.join(strPathOut, "P%s_T%05d%s" % (self.P, self._iT, strFileSuffix))
                safe_mkdirs(strPathOut)
                ccore.writeImage(imgRgb, strFilePath, strCompression)
                self._oLogger.debug("* rendered image written '%s'" % strFilePath)
            else:
                strFilePath = ''
            return imgRgb, strFilePath


    def collectObjects(self, plate_id, P, lstReader, oLearner, byTime=True):

        #channel_name = oLearner.strChannelId
        strRegionId = oLearner.strRegionId
        img_rgb = None

        self._oLogger.debug('* collecting samples...')

#        bSuccess = True
#        channels = sorted(self._channel_registry.values())
#        primary_cChannel = None
#        for channel2 in lstChannels:
#
#            self.time_holder.prepare_raw_image(channel)
#            self.time_holder.apply_segmentation(oChannel2, oPrimaryChannel)
#
#            if oPrimaryChannel is None:
#                assert oChannel2.RANK == 1
#                oPrimaryChannel = oChannel2
        self.process(apply = False, extract_features = False)

        # self._channel_registry
        oChannel = self._channel_registry[oLearner.channel_name]
        oContainer = oChannel.get_container(strRegionId)
        objects = oContainer.getObjects()

        object_lookup = {}
        for oReader in lstReader:
            lstCoordinates = None
            if (byTime and P == oReader.getPosition() and self._iT in oReader):
                lstCoordinates = oReader[self._iT]
            elif (not byTime and P in oReader):
                lstCoordinates = oReader[P]
            #print "moo", P, oReader.getPosition(), byTime, self._iT in oReader
            #print lstCoordinates, byTime, self.P, oReader.keys()

            if not lstCoordinates is None:
                #print self.iP, self._iT, lstCoordinates
                for dctData in lstCoordinates:
                    label = dctData['iClassLabel']
                    if (label in oLearner.dctClassNames and
                        dctData['iPosX'] >= 0 and
                        dctData['iPosX'] < oContainer.width and
                        dctData['iPosY'] >= 0 and
                        dctData['iPosY'] < oContainer.height):

                        center1 = ccore.Diff2D(dctData['iPosX'],
                                               dctData['iPosY'])

                        # test for obj_id "under" annotated pixel first
                        obj_id = oContainer.img_labels[center1]

                        # if not background: valid obj_id found
                        if obj_id > 0:
                            dict_append_list(object_lookup, label, obj_id)

                        # otherwise try to find nearest object in a search
                        # radius of 30 pixel (compatibility with CellCounter)
                        else:
                            dists = []
                            for obj_id, obj in objects.iteritems():
                                diff = obj.oCenterAbs - center1
                                dist_sq = diff.squaredMagnitude()
                                # limit to 30 pixel radius
                                if dist_sq < 900:
                                    dists.append((obj_id, dist_sq))
                            if len(dists) > 0:
                                dists.sort(lambda a,b: cmp(a[1], b[1]))
                                obj_id = dists[0][0]
                                dict_append_list(object_lookup, label, obj_id)

        object_ids = set(flatten(object_lookup.values()))
        objects_del = set(objects.keys()) - object_ids
        for obj_id in objects_del:
            oContainer.delObject(obj_id)

        self.time_holder.apply_features(oChannel)
        region = oChannel.get_region(strRegionId)

        learner_objects = []
        for label, object_ids in object_lookup.iteritems():
            class_name = oLearner.dctClassNames[label]
            hex_color = oLearner.dctHexColors[class_name]
            rgb_value = ccore.RGBValue(*hexToRgb(hex_color))
            for obj_id in object_ids:
                obj = region[obj_id]
                obj.iLabel = label
                obj.strClassName = class_name
                obj.strHexColor = hex_color

                if (obj.oRoi.upperLeft[0] >= 0 and
                    obj.oRoi.upperLeft[1] >= 0 and
                    obj.oRoi.lowerRight[0] < oContainer.width and
                    obj.oRoi.lowerRight[1] < oContainer.height):
                    iCenterX, iCenterY = obj.oCenterAbs

                    strPathOutLabel = os.path.join(oLearner.dctEnvPaths['samples'],
                                                   oLearner.dctClassNames[label])
                    safe_mkdirs(strPathOutLabel)

                    strFilenameBase = 'PL%s___P%s___T%05d___X%04d___Y%04d' % (plate_id, self.P, self._iT, iCenterX, iCenterY)

                    obj.sample_id = strFilenameBase
                    learner_objects.append(obj)

                    strFilenameImg = os.path.join(strPathOutLabel, '%s___img.png' % strFilenameBase)
                    strFilenameMsk = os.path.join(strPathOutLabel, '%s___msk.png' % strFilenameBase)
                    # FIXME: export Objects is segfaulting for objects
                    #        where its bounding box is touching the border
                    #        i.e. one corner point equals zero!
                    oContainer.exportObject(obj_id,
                                            strFilenameImg,
                                            strFilenameMsk)

                    oContainer.markObjects([obj_id], rgb_value, False, True)

                    #print obj_id, obj.oCenterAbs, iCenterX, iCenterY
                    print '*** CSdebug: drawFilledCircle', iCenterX, iCenterY
                    ccore.drawFilledCircle(ccore.Diff2D(iCenterX, iCenterY),
                                           3, oContainer.img_rgb, rgb_value)


        if len(learner_objects) > 0:
            oLearner.applyObjects(learner_objects)
            # we don't want to apply None for feature names
            oLearner.setFeatureNames(oChannel.lstFeatureNames)

        strPathOut = os.path.join(oLearner.dctEnvPaths['controls'])
        safe_mkdirs(strPathOut)
        oContainer.exportRGB(os.path.join(strPathOut,
                                          "P%s_T%05d_C%s_R%s.jpg" %\
                                           (self.P, self._iT, oLearner.strChannelId, oLearner.strRegionId)),
                            '90')
        img_rgb = oContainer.img_rgb
        return img_rgb


    def classifyObjects(self, oPredictor):
        channel_name = oPredictor.strChannelId
        strRegionId = oPredictor.strRegionId
        oChannel = self._channel_registry[channel_name]
        oRegion = oChannel.get_region(strRegionId)
        for iObjId, oObj in oRegion.iteritems():
            iLabel, dctProb = oPredictor.predict(oObj.aFeatures.copy(), oRegion.getFeatureNames())
            oObj.iLabel = iLabel
            oObj.dctProb = dctProb
            oObj.strClassName = oPredictor.dctClassNames[iLabel]
            oObj.strHexColor = oPredictor.dctHexColors[oObj.strClassName]
예제 #25
0
class Classifier(object):

    def __init__(self, name=None, path=None):
        #super(Classifier, self).__init__()
        self.name = name
        self.path = path

        self.dctClassInfos = OrderedDict()
        self.dctFeatureInfos = OrderedDict()
        self.isInitialized = False
        #self._loadInfos()

    def _loadInfos(self):
        print "LOAD"
        if not self.isInitialized:
            self._oLearner = BaseLearner(strEnvPath=self.path)
            try:
                self._oLearner.importFromArff()
                try:
                    self._oLearner.importSampleNames()
                except IOError:
                    has_samples = False
                else:
                    has_samples = True
                #print has_samples
            except IOError:
                pass
            else:
                print "import %s" % self.name

                for iLabel in self._oLearner.lstClassLabels:
                    strName = self._oLearner.dctClassNames[iLabel]
                    strHexColor = self._oLearner.dctHexColors[strName]
                    if strName in self._oLearner.dctFeatureData:
                        oClass = Class(strName, iLabel,
                                       len(self._oLearner.dctFeatureData[strName]),
                                       hexToFlexColor(strHexColor))
                        oClass.oClassifier = self
                        dctFeatures = {}
                        for iIdx, strFeatureName in enumerate(self._oLearner.lstFeatureNames):
                            dctFeatures[strFeatureName] = list(self._oLearner.dctFeatureData[strName][:,iIdx])
                        oClass.features = dctFeatures
                        if has_samples:
                            oClass.sample_names = [Sample(os.path.join(self._oLearner.dctEnvPaths['samples'], strName, filename))
                                                   for filename in self._oLearner.dctSampleNames[strName]]
                            #print strName,self._oLearner.dctSampleNames[strName]
                        self.dctClassInfos[strName] = oClass
                self.isInitialized = True

                for strFeatureName in self._oLearner.lstFeatureNames:
                    self.dctFeatureInfos[strFeatureName] = Feature(strFeatureName)

    @property
    def classes(self):
        self._loadInfos()
        return self.dctClassInfos.values()

    @property
    def classInfos(self):
        self._loadInfos()
        logging.debug("classes: %s" % len(self.dctClassInfos.values()))
        return self.dctClassInfos.values()

    @property
    def featureInfos(self):
        self._loadInfos()
        logging.debug("features: %s" % len(self.dctFeatureInfos.values()))
        return self.dctFeatureInfos.values()

    def getSamples(self, className):
        self._loadInfos()
        strPathSamples = os.path.join(self._oLearner.dctEnvPaths['samples'],
                                      className)
        lstResults = []
        if os.path.isdir(strPathSamples):
            #print len(self._oLearner.lstFeatureNames), len()
            dctImagePairs = OrderedDict()
            for strName, oMatch in collect_files_by_regex(strPathSamples, '(?P<prefix>.+?)__(?P<type>(img)|(msk)).+?', ['.png', '.jpg']):
                strPrefix = oMatch.group('prefix')
                strType = oMatch.group('type')
                if not strPrefix in dctImagePairs:
                    dctImagePairs[strPrefix] = {}
                dctImagePairs[strPrefix][strType] = strName

            iIdx = 0
            for dctPair in dctImagePairs.values():
                #oContainer = ccore.SingleObjectContainer(dctPair['img'], dctPair['msk'])
                #strCoords = ",".join(map(str,flatten(oContainer.getCrackCoordinates(1))))
                #print dctPair['img'], dctPair['msk']
                #dctFeatures = {}
                #for iF, strFeatureName in enumerate(self._oLearner.lstFeatureNames):
                #    dctFeatures[strFeatureName] = self._oLearner.dctFeatureData[className][iIdx][iF]
                oSample = Sample(dctPair['img'])
                lstResults.append(oSample)
                iIdx += 1
                #break
        return lstResults

    def getFeatureData(self, featureNames):
        self._loadInfos()
        lstFeatureData = []
        if len(featureNames) == 1:
            strFeatureName = featureNames[0]
            for strClassName, oClass in self.dctClassInfos.iteritems():
                aY, aX = numpy.histogram(oClass.features[strFeatureName], normed=True)
                lstData = [dict(x=fX, y=fY) for fX,fY in zip(aX, aY)]
                lstFeatureData.append(lstData)
        elif len(featureNames) == 2:
            for strClassName, oClass in self.dctClassInfos.iteritems():
                iSize = len(oClass.features.values()[0])
                lstData = [dict([(strFeatureName, oClass.features[strFeatureName][iIdx])
                                 for strFeatureName in featureNames])
                           for iIdx in range(iSize)]
                lstFeatureData.append(lstData)
        #print lstFeatureData
        return lstFeatureData
예제 #26
0
파일: analyzer.py 프로젝트: cmci/cecog
 def initTimepoint(self, iT):
     self._channel_registry = OrderedDict()
     self._iT = iT
     self.time_holder.initTimePoint(iT)
예제 #27
0
파일: tabcontrol.py 프로젝트: imcf/cecog
class TabControl(QFrame):
    """General tab control: list of buttons at the top and stacked widget below"""

    current_changed = pyqtSignal(int)

    def __init__(self, parent, hide_one=True):
        QFrame.__init__(self, parent)

        self.setStyleSheet(TAB_STYLE)

        self._hide_one = hide_one
        self._tabs = OrderedDict()
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        self._btn_frame = QFrame(self)
        self._btn_grp = QButtonGroup(self._btn_frame)
        self._btn_grp.setExclusive(True)
        self._btn_layout = QHBoxLayout(self._btn_frame)
        self._btn_layout.insertStretch(0, 1)
        self._btn_layout.insertStretch(1, 1)
        self._stacked_frame = QStackedWidget(self)
        self._stacked_frame.setObjectName('stacked')
        layout.addWidget(self._btn_frame)
        layout.addWidget(self._stacked_frame)
        self._btn_frame.hide()
        self._current_name = None

    def add_tab(self, name, frame):
        scroll_area = QScrollArea(self)
        scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll_area.setWidgetResizable(True)
        scroll_area.setFrameShape(QFrame.NoFrame)
        scroll_area.setWidget(frame)

        btn = QPushButton(name, self._btn_frame)
        btn.setObjectName('tab')
        btn.setFlat(True)
        btn.setCheckable(True)
        btn.toggled.connect(functools.partial(self._on_btn_toggled, name))
        self._btn_grp.addButton(btn)
        self._tabs[name] = (scroll_area, frame, btn)
        self._stacked_frame.addWidget(scroll_area)
        self._btn_layout.insertWidget(len(self._tabs), btn)
        if not self._hide_one or len(self._tabs) > 1:
            self._btn_frame.show()

        self._current_name = name

    def remove_tab(self, name):
        scroll_area = self._tabs[name][0]
        btn = self._tabs[name][1]
        self._btn_layout.removeWidget(btn)
        self._stacked_frame.removeWidget(scroll_area)
        if (self._hide_one and len(self._tabs) <= 1) or (not self._hide_one and len(self._tabs) == 0):
            self._btn_frame.hide()

    def set_active(self, name, toggle=True):
        scroll_area = self._tabs[name][0]
        if toggle:
            btn = self._tabs[name][2]
            btn.setChecked(True)
        self._stacked_frame.setCurrentWidget(scroll_area)
        self._current_name = name
        self.current_changed.emit(self._tabs.index(name))

    def set_active_index(self, index):
        name = self._tabs.keys()[index]
        self.set_active(name)

    def _on_btn_toggled(self, name):
        self.set_active(name, toggle=False)

    def enable_non_active(self, state=True):
        for name in self._tabs:
            frame, btn = self._tabs[name][1:]
            if frame != self._stacked_frame.currentWidget():
                btn.setEnabled(state)

    def get_frame(self, name):
        return self._tabs[name][1]

    @property
    def current_name(self):
        return self._current_name

    @property
    def current_index(self):
        return self._tabs.index(self._current_name)
예제 #28
0
파일: config.py 프로젝트: cmci/cecog
 def __init__(self):
     self._registry = OrderedDict()
예제 #29
0
파일: learning.py 프로젝트: cmci/cecog
class BaseLearner(LoggerMixin, OptionManager):

    ANNOTATIONS = 'annotations'

    OPTIONS = {"strEnvPath" :          Option(".", callback="_onEnvPath"),
               "lstClassDefinitions" : Option([], callback="_onDefineClasses"),
               "strArffFileName" :     Option("features.arff"),
               "strSparseFileName" :   Option("features.sparse"),
               "strDefinitionFileName" :   Option("class_definition.txt"),
               "filename_pickle" :     Option("learner.pkl"),
              }

    __attributes__ = ['dctFeatureData',
                      'dctSampleData',
                      'dctClassNames',
                      'dctClassLabels',
                      'lstFeatureNames',
                      'dctHexColors',
                      'dctEnvPaths',
                      'dctImageObjects']

    def __init__(self, **options):
        self.dctFeatureData = OrderedDict()
        self.dctClassNames = {}
        self.dctClassLabels = {}
        self.lstFeatureNames = None
        self.dctHexColors = {}
        self.dctSampleNames = {}
        self.dctEnvPaths = {}
        self.hasZeroInsert = False
        self.dctImageObjects = OrderedDict()

        super(BaseLearner, self).__init__(**options)

    def __getstate__(self):
        dctState = get_attribute_values(self)
        return dctState

    def __setstate__(self, state):
        set_attribute_values(self, state)

    def clear(self):
        self.dctFeatureData.clear()
        self.dctClassNames.clear()
        self.dctClassLabels.clear()
        self.lstFeatureNames = None
        self.dctHexColors.clear()
        self.dctSampleNames.clear()
        self.dctImageObjects.clear()

    def mergeClasses(self, info, mapping):
        newl = copy.deepcopy(self)

        newl.dctClassNames = {}
        newl.dctClassLabels = {}
        newl.dctHexColors = {}
        for label, name, color in info:
            newl.dctClassNames[label] = name
            newl.dctClassLabels[name] = label
            newl.dctHexColors[name] = color
        data = OrderedDict()
        for new_label, label_list in mapping.iteritems():
            new_name = newl.dctClassNames[new_label]
            if not new_name in data:
                data[new_name] = []
            for old_label in label_list:
                old_name = self.dctClassNames[old_label]
                data[new_name].extend(self.dctFeatureData[old_name])
        for name in data:
            data[name] = numpy.asarray(data[name])
        newl.dctFeatureData = data
        return newl

    @property
    def lstClassNames(self):
        return [self.dctClassNames[x] for x in self.lstClassLabels]

    @property
    def lstClassLabels(self):
        return sorted(self.dctClassNames.keys())

    @property
    def iClassNumber(self):
        return len(self.dctClassNames)

    @property
    def lstHexColors(self):
        return [self.dctHexColors[x] for x in self.lstClassNames]

    @property
    def names2samples(self):
        return dict([(n, len(self.dctFeatureData.get(n, [])))
                     for n in self.lstClassNames])


    @property
    def l2nl(self):
        '''
        convert a label into a new label
        (new labels are continuous from 0..number of classes
        '''
        return dict([(l,i) for i,l in enumerate(self.lstClassLabels)])

    @property
    def nl2l(self):
        '''
        convert a new label into the original label
        '''
        return dict([(i,l) for i,l in enumerate(self.lstClassLabels)])


    #def getFeaturesByName(self, featureName):


    def initEnv(self):
        env_path = self.getOption('strEnvPath')
        if not os.path.isdir(env_path):
            raise IOError("Classifier environment path '%s' does not exist." %
                          env_path)
        for strName, strPath in self.dctEnvPaths.iteritems():
            safe_mkdirs(strPath)

    def _onDefineClasses(self, lstClassDefinitions):
        for dctClassDescription in lstClassDefinitions:
            strClassName = dctClassDescription['name']
            iClassLabel  = dctClassDescription['label']
            tplColor     = dctClassDescription['color']

            # FIXME: folders not supported yet!!!
            if ('folders' not in dctClassDescription or
                dctClassDescription['folders'] is None or
                len(dctClassDescription['folders']) == 0):
                lstFolders = [strClassName]
            else:
                lstFolders = dctClassDescription['folders']

            self.dctClassNames[iClassLabel] = strClassName
            self.dctClassLabels[strClassName] = iClassLabel
            self.dctHexColors[strClassName] = rgbToHex(*tplColor)


    def _onEnvPath(self, strEnvPath):
        self.dctEnvPaths = {'samples' :    os.path.join(strEnvPath, "samples"),
                            self.ANNOTATIONS : os.path.join(strEnvPath, self.ANNOTATIONS),
                            'data':        os.path.join(strEnvPath, "data"),
                            'controls':    os.path.join(strEnvPath, "controls"),
                       }

    def getPath(self, strName):
        path = self.dctEnvPaths[strName]
        if not os.path.exists(path):
            os.mkdir(path)
        return path

    def get_env_path(self):
        return self.getOption('strEnvPath')

    def set_env_path(self, path):
        self.setOption('strEnvPath', path)
        self._onEnvPath(path)

    def loadDefinition(self, path=None, filename=None):
        if filename is None:
            filename = self.getOption('strDefinitionFileName')
        if path is None:
            path = self.getOption('strEnvPath')
        f = open(os.path.join(path, filename), "rb")
        reader = csv.reader(f, delimiter='\t', quoting=csv.QUOTE_NONE)
        self.dctClassNames.clear()
        self.dctClassLabels.clear()
        self.dctHexColors.clear()
        for row in reader:
            label = int(row[0])
            name = row[1]
            color = row[2]
            self.dctClassNames[label] = name
            self.dctClassLabels[name] = label
            self.dctHexColors[name] = color
        f.close()

    def saveDefinition(self, path=None, filename=None):
        if filename is None:
            filename = self.getOption('strDefinitionFileName')
        if path is None:
            path = self.getOption('strEnvPath')
        f = open(os.path.join(path, filename), "wb")
        writer = csv.writer(f, delimiter='\t', quoting=csv.QUOTE_NONE)
        for class_name in self.lstClassNames:
            class_label = self.dctClassLabels[class_name]
            color = self.dctHexColors[class_name]
            writer.writerow([class_label, class_name, color])
        f.close()

    def exportRanges(self, strFilePath=None, strFileName=None):
        if strFileName is None:
            strFileName = os.path.splitext(self.getOption('strArffFileName'))[0]
            strFileName += '.range'
        if strFilePath is None:
            strFilePath = self.dctEnvPaths['data']

        all_features = numpy.asarray(flatten(self.dctFeatureData.values()))
        features_min = numpy.min(all_features, 0)
        features_max = numpy.max(all_features, 0)

        f = file(os.path.join(strFilePath, strFileName), 'w')
        f.write('x\n')
        f.write('-1 1\n')
        for idx, (m1, m2) in enumerate(zip(features_min, features_max)):
            f.write('%d %.10e %.10e\n' % (idx+1, m1, m2))
        f.close()

    def importFromArff(self, strFilePath=None, strFileName=None):
        if strFileName is None:
            strFileName = self.getOption('strArffFileName')
        if strFilePath is None:
            strFilePath = self.dctEnvPaths['data']

        oReader = ArffReader(os.path.join(strFilePath, strFileName))
        self.dctFeatureData = oReader.dctFeatureData
        self.dctClassNames = oReader.dctClassNames
        self.dctClassLabels = oReader.dctClassLabels
        self.lstFeatureNames = oReader.lstFeatureNames
        self.dctHexColors = oReader.dctHexColors
        self.hasZeroInsert = oReader.hasZeroInsert
        #print self.dctClassLabels
        #print self.dctClassNames
        #print self.dctFeatureData.keys()

    def check(self):
        filename = os.path.splitext(self.getOption('strArffFileName'))[0]
        result = {'path_env' : self.getOption('strEnvPath'),
                  'path_data' : self.dctEnvPaths['data'],
                  'path_samples' : self.dctEnvPaths['samples'],
                  'path_annotations' : self.dctEnvPaths['annotations'],
                  'model' : os.path.join(self.dctEnvPaths['data'], '%s.model' % filename),
                  'range' : os.path.join(self.dctEnvPaths['data'], '%s.range' % filename),
                  'conf' : os.path.join(self.dctEnvPaths['data'], '%s.confusion.txt' % filename),
                  'arff' : os.path.join(self.dctEnvPaths['data'], self.getOption('strArffFileName')),
                  'definition' : os.path.join(self.getOption('strEnvPath'), self.getOption('strDefinitionFileName')),
                  }
        result.update({'has_path_data' : os.path.isdir(self.dctEnvPaths['data']),
                       'has_path_samples' : os.path.isdir(self.dctEnvPaths['samples']),
                       'has_path_annotations' : os.path.isdir(self.dctEnvPaths['annotations']),
                       'has_model' : os.path.isfile(os.path.join(self.dctEnvPaths['data'], '%s.model' % filename)),
                       'has_range' : os.path.isfile(os.path.join(self.dctEnvPaths['data'], '%s.range' % filename)),
                       'has_conf' : os.path.isfile(os.path.join(self.dctEnvPaths['data'], '%s.confusion.txt' % filename)),
                       'has_arff' : os.path.isfile(os.path.join(self.dctEnvPaths['data'], self.getOption('strArffFileName'))),
                       'has_definition' : os.path.isfile(os.path.join(self.getOption('strEnvPath'), self.getOption('strDefinitionFileName'))),
                       }
                      )
        return result


    def exportToArff(self, strFilePath=None, strFileName=None):
        if strFileName is None:
            strFileName = self.getOption('strArffFileName')
        if strFilePath is None:
            strFilePath = self.dctEnvPaths['data']

        #print self.hasZeroInsert
        oWriter = ArffWriter(os.path.join(strFilePath, strFileName),
                             self.lstFeatureNames,
                             self.dctClassLabels,
                             dctHexColors=self.dctHexColors,
                             hasZeroInsert=self.hasZeroInsert)
        oWriter.writeAllFeatureData(self.dctFeatureData)
        oWriter.close()

    def exportToSparse(self, strFilePath=None, strFileName=None):
        if strFileName is None:
            strFileName = self.getOption('strSparseFileName')
        if strFilePath is None:
            strFilePath = self.dctEnvPaths['data']

        oWriter = SparseWriter(os.path.join(strFilePath, strFileName),
                               self.lstFeatureNames,
                               self.dctClassLabels)
        oWriter.writeAllFeatureData(self.dctFeatureData)
        oWriter.close()

    def importSampleNames(self, strFilePath=None, strFileName=None):
        if strFileName is None:
            strFileName = os.path.splitext(self.getOption('strArffFileName'))[0]
            strFileName = '%s.samples.txt' % strFileName
        if strFilePath is None:
            strFilePath = self.dctEnvPaths['data']
        f = file(os.path.join(strFilePath, strFileName), 'r')
        self.dctSampleNames = {}
        for line in f:
            class_name, file_name = line.strip().split('\t')
            if class_name in self.dctClassLabels:
                if not class_name in self.dctSampleNames:
                    self.dctSampleNames[class_name] = []
            self.dctSampleNames[class_name].append(file_name)
        f.close()

    def exportSampleNames(self, strFilePath=None, strFileName=None):
        if strFileName is None:
            strFileName = os.path.splitext(self.getOption('strArffFileName'))[0]
            strFileName = '%s.samples.txt' % strFileName
        if strFilePath is None:
            strFilePath = self.dctEnvPaths['data']
        f = file(os.path.join(strFilePath, strFileName), 'w')
        for class_name, samples in self.dctSampleNames.iteritems():
            for sample_name in samples:
                f.write('%s\t%s\n' % (class_name, sample_name))
        f.close()

    def export(self):
        self.exportToArff()
        self.exportToSparse()
        self.exportSampleNames()
예제 #30
0
파일: analyzer.py 프로젝트: cmci/cecog
    def extportObjectDetails(self, filename, sep='\t', excel_style=False):
        f = file(filename, 'w')

        feature_lookup = OrderedDict()
        feature_lookup['mean'] = 'n2_avg'
        feature_lookup['sd'] = 'n2_stddev'
        feature_lookup['size'] = 'roisize'

        has_header = False
        line1 = []
        line2 = []
        line3 = []

        for frame, channels in self.iteritems():

            items = []
            prim_region = channels.values()[0].get_region('primary')

            for obj_id in prim_region:

                prefix = [frame, obj_id]
                prefix_names = ['frame', 'objID']
                items = []

                for channel in channels.values():

                    for region_id in channel.region_names():

                        region = channel.get_region(region_id)
                        if obj_id in region:
                            #FIXME:
                            feature_lookup2 = feature_lookup.copy()
                            for k,v in feature_lookup2.items():
                                if not region.hasFeatureName(v):
                                    del feature_lookup2[k]

                            if not has_header:
                                keys = ['classLabel', 'className']
                                if channel.NAME == 'Primary':
                                    keys += ['centerX', 'centerY']
                                keys += feature_lookup2.keys()
                                if excel_style:
                                    line1 += [channel.NAME.upper()] * len(keys)
                                    line2 += [region_id] * len(keys)
                                    line3 += keys
                                else:
                                    line1 += ['%s_%s_%s' % (channel.NAME.upper(),
                                                            region_id, key)
                                              for key in keys]

                            obj = region[obj_id]
                            #print feature_lookup2.keys(), feature_lookup2.values()
                            #fn = region.getFeatureNames()
                            #print zip(fn, obj.aFeatures)
                            features = region.getFeaturesByNames(obj_id, feature_lookup2.values())
                            values = [x if not x is None else '' for x in [obj.iLabel, obj.strClassName]]
                            if channel.NAME == 'Primary':
                                values += [obj.oCenterAbs[0], obj.oCenterAbs[1]]
                            values += list(features)
                            items.extend(values)

                if not has_header:
                    has_header = True
                    prefix_str = [''] * len(prefix)
                    if excel_style:
                        line1 = prefix_str + line1
                        line2 = prefix_str + line2
                        line3 = prefix_names + line3
                        f.write('%s\n' % sep.join(line1))
                        f.write('%s\n' % sep.join(line2))
                        f.write('%s\n' % sep.join(line3))
                    else:
                        line1 = prefix_names + line1
                        f.write('%s\n' % sep.join(line1))

                f.write('%s\n' % sep.join(map(str, prefix + items)))

        f.close()
예제 #31
0
파일: CecogAnalyzer.py 프로젝트: cmci/cecog
class AnalyzerMainWindow(QMainWindow):

    TITLE = 'CecogAnalyzer'

    NAME_FILTERS = ['Settings files (*.conf)',
                    'All files (*.*)']

    modified = pyqtSignal('bool')

    def __init__(self):
        QMainWindow.__init__(self)
        qApp._main_window = self

        self._is_initialized = False
        self._debug = False
        self._imagecontainer = None
        self._meta_data = None
        self._browser = None

        self.setWindowTitle(self.TITLE + '[*]')

        central_widget = QFrame(self)
        self.setCentralWidget(central_widget)


        action_about = self.create_action('&About', slot=self._on_about)
        action_quit = self.create_action('&Quit', slot=self._on_quit)
        action_pref = self.create_action('&Preferences',
                                         slot=self._on_preferences)

        #action_new = self.create_action('&New...', shortcut=QKeySequence.New,
        #                                  icon='filenew')
        action_open = self.create_action('&Open Settings...',
                                         shortcut=QKeySequence.Open,
                                         slot=self._on_file_open
                                         )
        action_save = self.create_action('&Save Settings',
                                         shortcut=QKeySequence.Save,
                                         slot=self._on_file_save
                                         )
        self.action_save = action_save
        action_save_as = self.create_action('&Save Settings As...',
                                            shortcut=QKeySequence.SaveAs,
                                            slot=self._on_file_save_as
                                            )
        menu_file = self.menuBar().addMenu('&File')
        self.add_actions(menu_file, (action_about, action_pref,
                                     None, action_open,
                                     None, action_save, action_save_as,
                                     None, action_quit))

        action_open = self.create_action('&Open Browser...',
                                         shortcut=QKeySequence('CTRL+B'),
                                         slot=self._on_browser_open
                                         )
        menu_browser = self.menuBar().addMenu('&Browser')
        self.add_actions(menu_browser, (action_open,
                                     #None, action_save, action_save_as,
                                     #None, action_quit
                                     ))

        action_log = self.create_action('&Show Log Window...',
                                        shortcut=QKeySequence(Qt.CTRL + Qt.Key_L),
                                        slot=self._on_show_log_window
                                        )
        menu_window = self.menuBar().addMenu('&Window')
        self.add_actions(menu_window, (action_log,
                                       ))

        action_help_startup = self.create_action('&Startup Help...',
                                                 shortcut=QKeySequence.HelpContents,
                                                 slot=self._on_help_startup
                                                )
        menu_help = self.menuBar().addMenu('&Help')
        self.add_actions(menu_help, (action_help_startup,))

        qApp._statusbar = QStatusBar(self)
        self.setStatusBar(qApp._statusbar)


        self._selection = QListWidget(central_widget)
        self._selection.setViewMode(QListView.IconMode)
        #self._selection.setUniformItemSizes(True)
        self._selection.setIconSize(QSize(35, 35))
        self._selection.setGridSize(QSize(140, 60))
        #self._selection.setWrapping(False)
        self._selection.setMovement(QListView.Static)
        #self._selection.setFlow(QListView.TopToBottom)
        #self._selection.setSpacing(12)
        self._selection.setMaximumWidth(self._selection.gridSize().width() + 5)
        self._selection.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self._selection.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,
                                                  QSizePolicy.Expanding))

        self._pages = QStackedWidget(central_widget)
        self._pages.main_window = self

        self._settings_filename = None
        self._settings = GuiConfigSettings(self, SECTION_REGISTRY)

        self._tab_lookup = OrderedDict()
        self._tabs = [GeneralFrame(self._settings, self._pages),
                      ObjectDetectionFrame(self._settings, self._pages),
                      FeatureExtractionFrame(self._settings, self._pages),
                      ClassificationFrame(self._settings, self._pages),
                      TrackingFrame(self._settings, self._pages),
                      ErrorCorrectionFrame(self._settings, self._pages),
                      OutputFrame(self._settings, self._pages),
                      ProcessingFrame(self._settings, self._pages),
                      ]
        if ANALYZER_CONFIG.get('Analyzer', 'cluster_support'):
            self._tabs.append(ClusterFrame(self._settings, self._pages))

        widths = []
        for tab in self._tabs:
            size = self._add_page(tab)
            widths.append(size.width())
        self.set_modules_active(state=False)
        self._pages.setMinimumWidth(max(widths) + 45)

        self._selection.currentItemChanged.connect(self._on_change_page)

        self._selection.setCurrentRow(0)

        w_logo = QLabel(central_widget)
        w_logo.setPixmap(QPixmap(':cecog_logo_w145'))

        layout = QGridLayout(central_widget)
        layout.addWidget(self._selection, 0, 0)
        layout.addWidget(w_logo, 1, 0, Qt.AlignBottom | Qt.AlignHCenter)
        layout.addWidget(self._pages, 0, 1, 2, 1)

        qApp._log_handler = GuiLogHandler(self)
        qApp._log_window = LogWindow(qApp._log_handler)
        qApp._log_window.setGeometry(50, 50, 600, 300)

        logger = logging.getLogger()
        qApp._log_handler.setLevel(logging.NOTSET)
        formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s')
        qApp._log_handler.setFormatter(formatter)
        #logger.addHandler(self._handler)
        logger.setLevel(logging.NOTSET)

        qApp._image_dialog = None
        qApp._graphics = None

        self.setGeometry(0, 0, 1100, 750)
        self.setMinimumSize(QSize(700, 600))
        self.show()
        self.center()
        self.raise_()
        self._is_initialized = True

    def closeEvent(self, event):
        '''
        The app should quit when the main window is closed.
        '''
        if not self._exit_app():
            event.ignore()

    def test_r_import(self):
        try:
            import rpy2.robjects as robjects
            import rpy2.rinterface as rinterface
            import rpy2.robjects.numpy2ri

            # some tests
            x = robjects.r['pi']
            v = robjects.FloatVector([1.1, 2.2, 3.3, 4.4, 5.5, 6.6])
            m = robjects.r['matrix'](v, nrow=2)
            has_R_version = True
            version = '%s.%s' % (robjects.r['version'][5][0],
                                 robjects.r['version'][6][0])
        except:
            has_R_version = False
            msg = 'R installation not found.\n\n'\
                  'To use HMM error correction or plotting functions '\
                  'R >= Version 2.9 must be installed together with these.'\
                  'packages:\n'
            msg += ', '.join(R_LIBRARIES)
            msg += '\n\nSee http://www.r-project.org\n\n'
            critical(self, 'R installation not found', info=msg, detail_tb=True)


        if has_R_version:
            missing_libs = []
            buffer = []
            rinterface.setWriteConsole(lambda x: buffer.append(x))
            for lib_name in R_LIBRARIES:
                try:
                    robjects.r['library'](lib_name)
                except:
                    missing_libs.append(lib_name)
            rinterface.setWriteConsole(None)
            if len(missing_libs) > 0:
                msg = 'Missing R package(s)\n\n'
                msg += ', '.join(missing_libs)
                msg += '\n\nSee http://www.r-project.org\n\n'
                msg += '\n'.join(buffer)

                critical(self, 'Missing R libraries', info=msg, detail_tb=True)
                qApp.valid_R_version = False
            else:
                qApp.valid_R_version = True

    def settings_changed(self, changed):
        if self._is_initialized:
            self.setWindowModified(changed)
            self.action_save.setEnabled(changed)
            self.modified.emit(changed)

    def _add_page(self, widget):
        button = QListWidgetItem(self._selection)
        button.setIcon(QIcon(widget.ICON))
        button.setText(widget.get_name())
        button.setTextAlignment(Qt.AlignHCenter)
        #button.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)

        #self.connect(button, )
#        scroll_area = QScrollArea(self._pages)
#        scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
#        scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
#        scroll_area.setWidgetResizable(True)
#        scroll_area.setWidget(widget)
#
#        self._pages.addWidget(scroll_area)
        self._pages.addWidget(widget)

        widget.toggle_tabs.connect(self._on_toggle_tabs)
        self._tab_lookup[widget.get_name()] = (button, widget)
        return widget.size()

    def _on_toggle_tabs(self, name):
        '''
        toggle ItemIsEnabled flag for all list items but name
        '''
        for name2 in self._tab_lookup:
            if name2 != name:
                item, widget = self._tab_lookup[name2]
                flags = item.flags()
                # check flag (and)
                if flags & Qt.ItemIsEnabled:
                    # remove flag (nand)
                    item.setFlags(flags & ~Qt.ItemIsEnabled)
                else:
                    # set flag (or)
                    item.setFlags(flags | Qt.ItemIsEnabled)

    def _on_change_page(self, current, previous):
        if not current:
            current = previous
        index = self._selection.row(current)
        self._pages.setCurrentIndex(index);
        widget = self._pages.widget(index)
        widget.page_changed()

    def _check_settings_saved(self):
        if self.isWindowModified():
            result = question(self, 'Settings have been modified.',
                              info='Do you want to save settings?',
                              modal=True, show_cancel=True,
                              default=QMessageBox.Yes,
                              escape=QMessageBox.Cancel)
            if result == QMessageBox.Yes:
                self.save_settings()
        else:
            result = QMessageBox.No
        return result

    def _exit_app(self):
        do_exit = False
        if not self._debug:
            if question(self, 'Do you really want to exit?', modal=True):
                if self._check_settings_saved() != QMessageBox.Cancel:
                    do_exit = True
                    qApp.exit()
        else:
            do_exit = True
            qApp.exit()
        return do_exit


    def center(self):
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2,
        (screen.height() - size.height()) / 2)

    def add_actions(self, target, actions):
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)

    def create_action(self, text, slot=None, shortcut=None, icon=None,
                      tooltip=None, checkable=None, signal='triggered()',
                      checked=False):
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(QIcon(':/%s.png' % icon))
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tooltip is not None:
            action.setToolTip(tooltip)
            action.setStatusTip(tooltip)
        if slot is not None:
            self.connect(action, SIGNAL(signal), slot)
        if checkable is not None:
            action.setCheckable(True)
        action.setChecked(checked)
        return action

    def save_settings(self, save_as=False):
        filename = self._settings_filename
        if filename is None or save_as:
            filename = self.__get_save_as_filename()
        if not filename is None:
            self._write_settings(filename)

    def _read_settings(self, filename):
        try:
            self._settings.read(filename)
        except:
            critical(self,
                     "Error loading settings file",
                     info="Could not load settings file '%s'." % filename,
                     detail_tb=True)
            status('Settings not successfully loaded.')
        else:
            self._settings_filename = filename
            self.setWindowTitle('%s - %s[*]' % (self.TITLE, filename))
            try:
                for widget in self._tabs:
                    widget.update_input()
            except:
                critical(self, "Problem loading settings file.",
                         info="Fix the problem in file '%s' and load the "\
                                "settings file again." % filename,
                         detail_tb=True)
            self.settings_changed(False)
            status('Settings successfully loaded.')

    def _write_settings(self, filename):
        try:
            f = file(filename, 'w')
            # create a new version (copy) of the current settings which add the needed rendering information
            settings_dummy = ProcessingFrame.get_export_settings(self._settings)
            settings_dummy.write(f)
            f.close()
        except:
            critical(self,
                     "Error saving settings file",
                     info="Could not save settings file as '%s'." % filename,
                     detail_tb=True)
            status('Settings not successfully saved.')
        else:
            self._settings_filename = filename
            self.setWindowTitle('%s - %s[*]' % (self.TITLE, filename))
            self.settings_changed(False)
            status('Settings successfully saved.')

    def _on_about(self):
        print "about"
        dialog = QDialog(self)
        #dialog.setBackgroundRole(QPalette.Dark)
        dialog.setStyleSheet('background: #000000; '
                             'background-image: url(:cecog_about)')
        dialog.setWindowTitle('About CecogAnalyzer')
        dialog.setFixedSize(400, 300)
        layout = QGridLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        #image = QImage(':cecog_splash')
        #label1 = QLabel(dialog)
        #label1.setStyleSheet('background-image: url(:cecog_splash)')
        #label1.setPixmap(QPixmap.fromImage(image))
        #layout.addWidget(label1, 0, 0)
        label2 = QLabel(dialog)
        label2.setStyleSheet('background: transparent;')
        label2.setAlignment(Qt.AlignCenter)
        label2.setText('CecogAnalyzer\nVersion %s\n\n'
                       'Copyright (c) 2006 - 2011\n' % VERSION)
        label3 = QLabel(dialog)
        label3.setStyleSheet('background: transparent;')
        label3.setTextFormat(Qt.AutoText)
        label3.setOpenExternalLinks(True)
        label3.setAlignment(Qt.AlignCenter)
        #palette = label2.palette()
        #palette.link = QBrush(QColor(200,200,200))
        #label3.setPalette(palette)
        label3.setText('<style>a { color: green; } a:visited { color: green; }</style>'
                       '<a href="http://cellcognition.org">cellcognition.org</a><br>')
        layout.addWidget(label2, 1, 0)
        layout.addWidget(label3, 2, 0)
        layout.setAlignment(Qt.AlignCenter | 
                            Qt.AlignBottom)
        dialog.setLayout(layout)
        dialog.show()

    def _on_preferences(self):
        print "pref"

    def _on_quit(self):
        self._exit_app()

    def _on_browser_open(self):
        if self._imagecontainer is None:
            warning(self, 'Data structure not loaded',
                    'The input data structure was not loaded.\n'
                    'Please click "Load image data" in General.')
        elif self._browser is None:
            try:
                browser = Browser(self._settings,
                                  self._imagecontainer)
                browser.show()
                browser.raise_()
                browser.setFocus()
                self._browser = browser
            except:
                exception(self, 'Problem opening the browser')
        else:
            self._browser.show()
            self._browser.raise_()

    def _on_load_input(self):
        txt = "Error scanning image structure"
        path_in = self._settings.get(SECTION_NAME_GENERAL, 'pathin')
        if path_in == '':
            critical(self, txt, "Image path must be defined.")
        elif not os.path.isdir(path_in) and \
             not os.path.isdir(os.path.join(get_package_path(), path_in)):
            critical(self, txt, "Image path '%s' not found." % path_in)
        else:
            try:
                infos = list(ImageContainer.iter_check_plates(self._settings))
            except:
                exception(self, txt)
            else:
                found_any = numpy.any([not info[3] is None for info in infos])
                cancel = False
                if found_any:
                    found_plates = [info[0] for info in infos
                                    if not info[3] is None]
                    missing_plates = [info[0] for info in infos
                                      if info[3] is None]
                    has_missing = len(missing_plates) > 0
                    txt = '%s plates were already scanned.\nDo you want ' \
                          'to rescan the file structure(s)? ' \
                          'This can take several minutes.' % \
                          ('Some' if has_missing else 'All')
                    title = 'Rescan input structure?'

                    box = QMessageBox(QMessageBox.Question, title, title,
                                      QMessageBox.Cancel, self, Qt.Sheet)
                    box.setWindowModality(Qt.WindowModal)
                    box.setInformativeText(txt)
                    box.setDetailedText('Plates with scanned structure: \n%s\n'
                                        '\nPlates without scanned structure: '
                                        '\n%s' % 
                                        ('\n'.join(found_plates),
                                         '\n'.join(missing_plates)))
                    if not has_missing:
                        btn1 = QPushButton('No', box)
                        box.addButton(btn1, QMessageBox.NoRole)
                        box.setDefaultButton(btn1)
                    elif len(found_plates) > 0:
                        btn1 = QPushButton('Rescan missing', box)
                        box.addButton(btn1, QMessageBox.YesRole)
                        box.setDefaultButton(btn1)
                    else:
                        btn1 = None

                    btn2 = QPushButton('Rescan all', box)
                    box.addButton(btn2, QMessageBox.YesRole)

                    if box.exec_() == QMessageBox.Cancel:
                        cancel = True
                    else:
                        btn = box.clickedButton()
                        if btn == btn1:
                            if has_missing:
                                scan_plates = dict([(info[0], info[0] in missing_plates) for info in infos])
                            else:
                                scan_plates = dict((info[0], False) for info in infos)
                        else:
                            scan_plates = dict((info[0], True) for info in infos)
                else:
                    has_multiple = self._settings.get(SECTION_NAME_GENERAL,
                                                      "has_multiple_plates")
                    if not question(self, "No structure data found",
                                    "Are you sure to scan %s?\n\nThis can take "
                                    "several minutes depending on the number of"
                                    " images." % 
                                    ("%d plates" % len(infos) if has_multiple
                                     else "one plate")):
                        cancel = True
                    scan_plates = dict((info[0], True) for info in infos)
                if not cancel:
                    self._load_image_container(infos, scan_plates)

    def _load_image_container(self, plate_infos, scan_plates=None, show_dlg=True):

        self._clear_browser()
        imagecontainer = ImageContainer()
        self._imagecontainer = imagecontainer

        if scan_plates is None:
            scan_plates = dict((info[0], False) for info in plate_infos)

        def load(dlg):
            iter = imagecontainer.iter_import_from_settings(self._settings, scan_plates)
            for idx, info in enumerate(iter):
                dlg.targetSetValue.emit(idx + 1)

            if len(imagecontainer.plates) > 0:
                plate = imagecontainer.plates[0]
                imagecontainer.set_plate(plate)

        self.dlg = waitingProgressDialog('Please wait until the input structure is scanned\n'
                                    'or the structure data loaded...', self, load, (0, len(scan_plates)))
        self.dlg.exec_(passDialog=True)

        if len(imagecontainer.plates) > 0:
            imagecontainer.check_dimensions()
            channels = imagecontainer.channels

            # do not report value changes to the main window
            self._settings.set_notify_change(False)
            
            self.set_image_crop_size()

            problems = []
            for prefix in ['primary', 'secondary', 'tertiary']:
                trait = self._settings.get_trait(SECTION_NAME_OBJECTDETECTION,
                                                 '%s_channelid' % prefix)
                if trait.set_list_data(channels) is None:
                    problems.append(prefix)
                self._tabs[1].get_widget('%s_channelid' % prefix).update()

            # report problems about a mismatch between channel IDs found in the data and specified by the user
            if len(problems) > 0:
                critical(self, "Selected channel IDs not valid",
                         "The selected channel IDs for %s are not valid.\nValid IDs are %s." % 
                         (", ".join(["'%s Channel'" % s.capitalize() for s in problems]),
                          ", ".join(["'%s'" % s for s in channels])))
                # a mismatch between settings and data will cause changed settings
                self.settings_changed(True)

            trait = self._settings.get_trait(SECTION_NAME_TRACKING,
                                             'tracking_duration_unit')

            # allow time-base tracking durations only if time-stamp
            # information is present
            meta_data = imagecontainer.get_meta_data()
            if meta_data.has_timestamp_info:
                result = trait.set_list_data(TRACKING_DURATION_UNITS_TIMELAPSE)
            else:
                result = trait.set_list_data(TRACKING_DURATION_UNITS_DEFAULT)
            if result is None:
                critical(self, "Could not set tracking duration units",
                         "The tracking duration units selected to match the load data. Please check your settings.")
                # a mismatch between settings and data will cause changed settings
                self.settings_changed(True)

            # activate change notification again
            self._settings.set_notify_change(True)

            
            self.set_modules_active(state=True)
            if show_dlg:
                information(self, "Plate(s) successfully loaded",
                            "%d plates loaded successfully." % len(imagecontainer.plates))
        else:
            critical(self, "No valid image data found",
                     "The naming schema provided might not fit your image data"
                     "or the coordinate file is not correct.\n\nPlease modify "
                     "the values and scan the structure again.")
            
    def set_image_crop_size(self):
        x0, y0, x1, y1 = self._settings.get('General', 'crop_image_x0'), \
                         self._settings.get('General', 'crop_image_y0'), \
                         self._settings.get('General', 'crop_image_x1'), \
                         self._settings.get('General', 'crop_image_y1')

        x0_, y0_, x1_, y1_ = 0, \
                             0, \
                             self._imagecontainer.get_meta_data().dim_x, \
                             self._imagecontainer.get_meta_data().dim_y
                         
        trait_x0 = self._settings.get_trait(SECTION_NAME_GENERAL, 'crop_image_x0')
        trait_y0 = self._settings.get_trait(SECTION_NAME_GENERAL, 'crop_image_y0')
        trait_x1 = self._settings.get_trait(SECTION_NAME_GENERAL, 'crop_image_x1')
        trait_y1 = self._settings.get_trait(SECTION_NAME_GENERAL, 'crop_image_y1')
        
        # Check if the crop values are valid
        if x0 > 0 and y0 > 0 and x1 <= x1_ and y1 <= y1_ and x0 != x1 and y0 != y1:
            # Set to default values
            trait_x0.set_value(trait_x0.get_widget(), x0)
            trait_y0.set_value(trait_y0.get_widget(), y0)
            trait_x1.set_value(trait_x1.get_widget(), x1)
            trait_y0.set_value(trait_y1.get_widget(), y1)
        else:
            trait_x0.set_value(trait_x0.get_widget(), x0_)
            trait_y0.set_value(trait_y0.get_widget(), y0_)
            trait_x1.set_value(trait_x1.get_widget(), x1_)
            trait_y0.set_value(trait_y1.get_widget(), y1_)
                        
        # Set GUI widget valid ranges
        trait_x0.set_min_value(x0_)
        trait_x0.set_max_value(x1_)
        trait_y0.set_min_value(y0_)
        trait_y0.set_max_value(y1_)
        trait_x1.set_min_value(x0_)
        trait_x1.set_max_value(x1_)
        trait_y1.set_min_value(y0_)
        trait_y1.set_max_value(y1_)

    def set_modules_active(self, state=True):
        for name, (button, widget) in self._tab_lookup.iteritems():
            widget.set_active(state)

    @pyqtSlot()
    def _on_file_open(self):
        if self._check_settings_saved() != QMessageBox.Cancel:
            dir = ''
            if not self._settings_filename is None:
                settings_filename = convert_package_path(self._settings_filename)
                if os.path.isfile(settings_filename):
                    dir = settings_filename
            filename = QFileDialog.getOpenFileName(self, 'Open config file', dir, ';;'.join(self.NAME_FILTERS))
            if filename:
                self._read_settings(filename)
                self._clear_browser()
                self.set_modules_active(state=False)


    @pyqtSlot()
    def _on_file_save(self):
        self.save_settings(False)

    @pyqtSlot()
    def _on_file_save_as(self):
        self.save_settings(True)

    def _clear_browser(self):
        # close and delete the current browser instance
        if not self._browser is None:
            self._browser.close()
            del self._browser
            # FIXME: necessary step to prevent crash after loading of new image container
            gc.collect()
            self._browser = None

    def _on_show_log_window(self):
        logger = logging.getLogger()
        logger.addHandler(qApp._log_handler)
        qApp._log_window.show()
        qApp._log_window.raise_()

    def __get_save_as_filename(self):
        dir = ''
        if not self._settings_filename is None:
            settings_filename = convert_package_path(self._settings_filename)
            if os.path.isfile(settings_filename):
                dir = settings_filename
        filename = QFileDialog.getSaveFileName(self, 'Save config file as', dir, ';;'.join(self.NAME_FILTERS))
        return filename or None

    def _on_help_startup(self):
        show_html('_startup')
예제 #32
0
파일: config.py 프로젝트: cmci/cecog
 def __init__(self, name):
     self.name = name
     self._registry = OrderedDict()