コード例 #1
0
ファイル: main.py プロジェクト: olfa-lab/olfactometry
 def __init__(self, parent=None, config_obj=None):
     super(Olfactometers, self).__init__()  # not sure if this will work.
     if not config_obj:
         self.config_fn, self.config_obj = get_olfa_config()
     elif isinstance(config_obj, dict):
         self.config_obj = config_obj
     elif isinstance(config_obj, str):
         self.config_fn, self.config_obj = get_olfa_config(config_obj)
     else:
         raise OlfaException(
             "Passed config_obj is of unknown type. Can be a dict, path to JSON or None."
         )
     menubar = self.menuBar()
     self._buildmenubar(menubar)
     self.olfa_specs = self.config_obj['Olfactometers']
     self.olfas = self._config_olfas(self.olfa_specs)
     try:
         self.dilutor_specs = self.config_obj[
             'Dilutors']  # configure *global* dilutors.
         self.dilutors = self._config_dilutors(self.dilutor_specs)
     except (TypeError,
             KeyError):  # no global Dilutors are specified, which is OK!
         self.dilutors = []
     self.setWindowTitle("Olfactometry")
     layout = QtGui.QVBoxLayout()
     for olfa in self.olfas:
         layout.addWidget(olfa)
     for dilutor in self.dilutors:
         layout.addWidget(dilutor)
     central_widget = QtGui.QWidget()
     self.setCentralWidget(central_widget)
     central_widget.setLayout(layout)
     self.statusBar()
     QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('CleanLooks'))
コード例 #2
0
ファイル: main.py プロジェクト: olfa-lab/olfactometry
    def set_odors(self, odors, concs=None, valvestates=None):
        """
        Sets odors on all olfactometers based on list of odor strings provided. Empty string or None will open no odor.

        :param odors: list or tuple of strings specifying odors by olfactometer (one string per olfactometer).
        :param valvestates: (optional) list of valvestates (True opens, False closes)
        :return: True if all setting appears successful.
        :rtype: bool
        """

        successes = []
        if not hasattr(odors, '__iter__'):
            if len(self.olfas) < 2:
                odors = (odors, )  # make into tuple
        if not hasattr(concs, '__iter__'):
            if len(self.olfas) < 2:
                concs = (concs, )  # make into tuple
        if not len(odors) == len(self.olfas):
            raise OlfaException(
                'Number of odors specified must be equal to the number of olfactometers.'
            )
        if not valvestates:
            valvestates = [None] * len(
                odors
            )  #just allows us to zip through this. Olfactometer will deal with Nones.
        if not concs:
            concs = [None] * len(
                odors
            )  # just allows us to zip through this. Olfactometer will deal with Nones.
        for odor, conc, olfa, valvestate in zip(odors, concs, self.olfas,
                                                valvestates):
            if odor:
                success = olfa.set_odor(odor, conc, valvestate)
                successes.append(success)
        return all(successes)
コード例 #3
0
ファイル: main.py プロジェクト: olfa-lab/olfactometry
    def set_dilution_flows(self,
                           olfa_dilution_flows=(),
                           global_dilution_flows=()):
        """
        This sets dilution flows for dilutors attached to olfactometers or global dilutors attached to all olfactometers.
        Each flow spec is specified by a list of flowrates: [vac, air].

        :param olfa_dilution_flows: list of lists of lists specifying dilution flows for dilutors attached to
        olfactometers: [[[olfa1_vac1, olfa1_air1], [olfa1_vac2, olfa1_air2], ...], [[olfa2_vac1, olfa2_vac2],... ], ...]
        :param global_dilution_flows: sets flow for global dilutor (ie those attached to all olfactometers):
        [[global1_vac, global1_air], [global2_vac,...], ...]
        :return: True if all setting appears successful.
        :rtype: bool
        """

        olfa_succeses = []
        global_successes = []
        if not len(olfa_dilution_flows) == len(self.olfas):
            raise OlfaException(
                'Number of flowrate pairs for olfa_dilution_flows parameter '
                'must be consistent with number of olfactometers.\n\n'
                '\t\t( i.e. "[(olfa1_vac, olfa1_air), (olfa2_vac, olfa2_air), ...]" )'
            )
        if olfa_dilution_flows:
            for olfa, flows in zip(self.olfas, olfa_dilution_flows):
                success = olfa.set_dilution(flows=flows)
                olfa_succeses.append(success)
        olfa_success = all(olfa_succeses)
        if not len(global_dilution_flows) == len(self.dilutors):
            raise OlfaException(
                'Number of flowrate pairs for global_dilution_flows parameter must be consistent with '
                'number of global dilutors present in configuration. \n\n'
                '\t\tThis does not include dilutors embedded in olfactometer objects!!!'
            )
        if global_dilution_flows:
            for dilutor, flows in zip(self.dilutors, global_dilution_flows):
                success = dilutor.set_flows(flows)
                global_successes.append(success)
        global_success = all(global_successes)
        return all((olfa_success, global_success))
コード例 #4
0
ファイル: olfactometer.py プロジェクト: c-wilson/olfactometry
    def find_odor(self, odor, conc=None):
        """
        Finds the exact matches for a vial with the specified odor / concentration.  Concentration is optional if only
        one vial with the odor is present in the configuration.

        ** Raises exemption if no matches are found or if multiple matches are found. **

        :param odor: string for odor.
        :param conc: float concentration, optional.
        :return: integer of the vial where odor/concentration found.
        :rtype: int
        """
        odor_matches = []
        for k, v in self.valve_config.iteritems():
            if 'odor' in v.keys() and odor.lower() == v['odor'].lower():
                odor_matches.append(k)

        odor_conc_matches = []
        if conc:
            tol = conc * 1e-6
            for k in odor_matches:
                v = self.valve_config[k]
                if abs(v['conc'] - conc) < tol:
                    odor_conc_matches.append(k)
        else:
            odor_conc_matches = odor_matches

        if not odor_conc_matches:
            print self.valve_config
            raise OlfaException(
                'Cannot find specified odor/concentration in vialset (odor: {0}, conc: {1}).'
                .format(odor, conc))
        elif len(odor_conc_matches) > 1:
            print self.valve_config
            raise OlfaException(
                'Multiple matches for odor/concentration found in vialset (odor: {0}, conc: {1}).'
                .format(odor, conc))
        else:
            return int(odor_conc_matches[0])
コード例 #5
0
ファイル: olfactometer.py プロジェクト: c-wilson/olfactometry
 def _config_dummy(self, valve_config):
     dummys = []
     for k, v in valve_config.iteritems():
         if v.get('odor', '').lower() == 'dummy':
             dummy = int(k)
             dummys.append(dummy)
     if len(dummys) > 1:
         print dummys
         raise OlfaException(
             "Configuration file must specify one dummy vial.")
     elif len(dummys) < 1:
         dummy = 4
         logging.warning('Dummy not specified, using vial 4.')
     return dummy
コード例 #6
0
ファイル: dilutor.py プロジェクト: olfa-lab/olfactometry
    def set_flows(self, flows):
        """
        Sets flowrates of attached MFCs.

        :param flows: iterable of flowrates to set MFCs, ordered as (vac, air).
        :return:
        """
        if not len(flows) == len(self.mfcs):
            ex_str = 'Number of flows specified ({0}) not equal to number of MFCs in Dilutor ({1}).'.format(
                len(flows), len(self.mfcs))
            raise OlfaException(ex_str)
        else:
            successes = []
            for mfc, flow in zip(self.mfcs, flows):
                success = mfc.set_flowrate(flow)
                successes.append(success)
            return all(successes)
コード例 #7
0
ファイル: main.py プロジェクト: olfa-lab/olfactometry
    def set_flows(self, flows):
        """
        Sets MFC flows for all olfactometers.

        :param flows: List of flowrates (ie "[(olfa1_MFCflow1, olfa1_MFCflow2), (olfa2_MFCflow1,...),...]")
        :return: True if sets appear to be successful as reported by olfas.
        :rtype: bool
        """
        successes = []
        if not len(self.olfas) == len(flows):
            raise OlfaException(
                'Number of flowrates specified must equal then number of olfactometers.'
            )
        for olfa, flow in zip(self.olfas, flows):
            if flow:
                success = olfa.set_flows(flow)
                successes.append(success)
        return all(successes)
コード例 #8
0
ファイル: olfactometer.py プロジェクト: c-wilson/olfactometry
    def check_flows(self):
        """
        Checks all MFCs in olfa to see if they are reporting flow. This prevents opening a vial in a no-flow condition.

        :return: True if all MFCs polling correctly and are reporting flow.
        :rtype: bool
        """

        flows_on = True
        if self.check_flows_before_opening:
            for i, mfc in enumerate(self.mfcs):
                time_elapsed = time.time() - mfc.last_poll_time
                if time_elapsed > 2.1 * self.polling_interval:
                    raise OlfaException('MFC polling is not ok.')
                elif mfc.flow <= 0.:
                    logging.warning('MFC {0} reporting no flow.'.format(i))
                    flows_on = False
        else:
            pass
        return flows_on
コード例 #9
0
ファイル: olfactometer.py プロジェクト: c-wilson/olfactometry
    def set_flows(self, flows):
        """
        Sets flow rate for MFCs based on provided tuple. Specified flowrates should be in the units of the MFC.

        i.e. (900, 100) will set the first MFC to 900 SCCM and the second to 100 SCCM.

        :param flows:
        :return: return bool if all sets are complete.
        """

        if not len(flows) == len(self.mfcs):
            ex_str = 'Number of flows specified ({0}) not equal to number of MFCs in olfa ({1}).'.format(
                len(flows), len(self.mfcs))
            raise OlfaException(ex_str)
        else:
            successes = []
            for mfc, flow in zip(self.mfcs, flows):
                success = mfc.set_flowrate(flow)
                successes.append(success)
            return all(successes)
コード例 #10
0
ファイル: main.py プロジェクト: olfa-lab/olfactometry
    def set_vials(self, vials, valvestates=None):
        """
        Sets vials on all olfactometers based on list of vial numbers provided. 0 or None will open no vial for that
        olfa.

        :param vials: list or tuple of vials.
        :param valvestates: (optional) list of valvestates (True opens, False closes)
        :return: True if all setting appears successful.
        :rtype: bool
        """
        successes = []
        if not len(vials) == len(self.olfas):
            raise OlfaException(
                'Number of vials specified must be equal to the number of olfactometers.'
            )
        if not valvestates:
            valvestates = [None] * len(vials)
        for vial, olfa, valvestate in zip(vials, self.olfas, valvestates):
            if vial:
                success = olfa.set_vial(vial, valvestate)
                successes.append(success)
        return all(successes)
コード例 #11
0
ファイル: olfactometer.py プロジェクト: c-wilson/olfactometry
 def stop_mfc_polling(self):
     raise OlfaException(
         'stop_mfc_polling must be defined by olfactometer class')