diff --git a/.gitmodules b/.gitmodules index a95ffcb74fdd76d4a30d84988b24c056baef1ef7..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +0,0 @@ -[submodule "mr_db"] - path = mr_db - url = /Users/mdryden/src/mr_db -[submodule "dstat-interface/mr_db"] - path = dstat-interface/mr_db - url = http://microfluidics.utoronto.ca/gitlab/mdryden/mr-db.git -[submodule "dstat_interface/mr_db"] - path = dstat_interface/mr_db - url = http://microfluidics.utoronto.ca/gitlab/mdryden/mr-db.git diff --git a/CHANGELOG b/CHANGELOG index f90415d2427dda000d59407b596ba907ea8effa6..0c5a35d10f4a465a4937118f19600b5760e7de8c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,34 +1,35 @@ -Version 1.0.2 - -Improved logging system: Log messages now print showing where they came from. - -Implemented gobject IO callbacks for experiments: - Process will not continuously poll for new data from serial process anymore. - -Stop button works again - -Buttons in Photodiode and Calibration modules remain insensitive until ready. +Version 1.3.3 + -Bugfix #24: Remove ZODB support until it can be fixed for latest ZODB -Version 1.0.2a - -Hotfix #12: Restored measurement ability on Windows - -Minor logging changes - -Automatically enable TCS on DStat when measure light sensor button clicked. +Version 1.3.2 + -Improves initial connection reliability + +Version 1.3.1 + -Fixed electrochem modes broken when database added + -Make metadata keys optional. -Version 1.0.3 - -Fixed #14: Added support for PMT idle mode - -Reduced CPU usage when running OCP by reducing polling frequency +Version 1.3 + -Fixed a bug related to calibration mode + -Added ZODB data storage + -Integrated with zmq_plugin + +Version 1.2 + -Old Microdrop interface depreciated + -New zmq_plugin based interface + -Internal changes to save functionality and plot storage. -Version 1.0.4 - -Adds support for synchronous electromechanical shutter detection (added in dstat/dstat-firmware@29d4c86) - -New version string system +Version 1.1.3 + -Changed internal storage of experiment data + -Added Analysis options: + -FFT integral moved there + -Basic statistics -Version 1.0.5 - -Bugfix for saving error introduced by new logging system - -Version 1.0.6 - -Automatically integrates shutter FFT peak and saves to data file - -Adds option to offset start of FFT to avoid PMT startup delay - -Version 1.0.7 - -Fixed a few bugs for systems without git - -Implements mean crossing detection instead of windowing for shutter FFT +Version 1.1.2 + -Fixed more critical bugs from refactoring +Version 1.1.1 + -Fixed critical bug that made PGA setting change with Gain resistor + Version 1.1 -Plot will be prettier if seaborn is installed -Fixed bug in shutter FFT display @@ -36,32 +37,35 @@ Version 1.1 -Adds requirement for yaml -Parameters automatically saved and loaded from last session -Can manually save and load parameter files + +Version 1.0.7 + -Fixed a few bugs for systems without git + -Implements mean crossing detection instead of windowing for shutter FFT -Version 1.1.1 - -Fixed critical bug that made PGA setting change with Gain resistor - -Version 1.1.2 - -Fixed more critical bugs from refactoring +Version 1.0.6 + -Automatically integrates shutter FFT peak and saves to data file + -Adds option to offset start of FFT to avoid PMT startup delay -Version 1.1.3 - -Changed internal storage of experiment data - -Added Analysis options: - -FFT integral moved there - -Basic statistics -Version 1.2 - -Old Microdrop interface depreciated - -New zmq_plugin based interface - -Internal changes to save functionality and plot storage. +Version 1.0.5 + -Bugfix for saving error introduced by new logging system -Version 1.3 - -Fixed a bug related to calibration mode - -Added ZODB data storage - -Integrated with zmq_plugin +Version 1.0.4 + -Adds support for synchronous electromechanical shutter detection (added in dstat/dstat-firmware@29d4c86) + -New version string system -Version 1.3.1 - -Fixed electrochem modes broken when database added - -Make metadata keys optional. +Version 1.0.3 + -Fixed #14: Added support for PMT idle mode + -Reduced CPU usage when running OCP by reducing polling frequency + +Version 1.0.2a + -Hotfix #12: Restored measurement ability on Windows + -Minor logging changes + -Automatically enable TCS on DStat when measure light sensor button clicked. -Version 1.3.2 - -Improves initial connection reliability \ No newline at end of file +Version 1.0.2 + -Improved logging system: Log messages now print showing where they came from. + -Implemented gobject IO callbacks for experiments: + Process will not continuously poll for new data from serial process anymore. + -Stop button works again + -Buttons in Photodiode and Calibration modules remain insensitive until ready. diff --git a/README.markdown b/README.markdown index a0157f9408016dfd92d805ff8d3bfc7dc5a73567..c4283474369e404adc878a738d2a9ff272ba8b4b 100644 --- a/README.markdown +++ b/README.markdown @@ -38,9 +38,6 @@ Python and related packages needed: (versions listed are tested, older versions * XQuartz (2.7.7) * zeromq (4.0.5) and pyzmq (14.6.0) * pyyaml (3.11) -* zodb -* zeo -* psutil Optional: @@ -168,4 +165,4 @@ If the connection failed, unplug the DStat and try again. 3. Set an appropriate potentiostat gain. 4. Click Execute. - \ No newline at end of file + diff --git a/dstat_interface/db.py b/dstat_interface/db.py deleted file mode 100644 index 3e1fda80e3c69ec7b85a85162fa412c663ad97b4..0000000000000000000000000000000000000000 --- a/dstat_interface/db.py +++ /dev/null @@ -1,194 +0,0 @@ -import logging -from time import sleep, time -from os.path import expanduser -from uuid import uuid4 - -from BTrees.OOBTree import OOBTree - -import mr_db.mr_db as db - -logger = logging.getLogger("dstat.db") - -current_db = None - -def start_db(path=None): - global current_db - current_db = Database(data_dir=path) - -def restart_db(object, path): - logger.info("Restarting database") - global current_db - if current_db is None: - logger.info("No database running") - start_db(path=path) - else: - stop_db() - start_db(path=path) - -def stop_db(): - global current_db - if not current_db is None: - logger.info("Stopping ZEO") - current_db.disconnect() - current_db = None - db.stop_server() - else: - logger.warning("Tried to disconnect ZEO when not connected") - -class Database(object): - def __init__(self, name='dstat', data_dir=None): - if data_dir is None: - data_dir = expanduser('~/.mr_db') - self.connected = False - self.name = name - - self.db_connect(data_dir) - - self.db = self.connection.databases - - # Make sure database exists - if not self.db.has_key(name): - self.db[name] = OOBTree() - db.transaction.commit() - - def disconnect(self): - if self.connected is True: - self.connection.db.close() - else: - logger.war("Tried to disconnect ZEO when not connected") - - def db_connect(self, root_dir): - """Connects to ZEO process. Starts ZEO if not running. Returns - connection object. - """ - if root_dir == '': - root_dir = None - - while self.connected is False: - try: - self.connection = db.DbConnection(root_dir=root_dir) - self.connected = True - logger.info("Connected to ZEO server") - except db.ClientStorage.ClientDisconnected: - db.stop_server() - logger.info("Starting ZEO server -- root_dir = %s", root_dir) - db_proc = db.start_server(root_dir=root_dir) - sleep(3) - - def add_results(self, measurement_uuid=None, measurement_name=None, - experiment_uuid=None, experiment_metadata=None, - patient_id=None, - timestamp=None, - data=None): - - """Add a measurement""" - - if experiment_metadata is None: - experiment_metadata = {} - - try: - logger.info("Starting DB transaction") - db.transaction.begin() - - logger.info("Creating Experiment with id: %s", experiment_uuid) - exp_db, exp_id = self.add_experiment( - experiment_uuid=experiment_uuid, - timestamp=timestamp, - **experiment_metadata) - - logger.info("Adding Measurement with id: %s", measurement_uuid) - name = self.add_dstat_measurement(experiment=exp_db[exp_id], - measurement_uuid=measurement_uuid, - name=measurement_name, - timestamp=timestamp, - data=data) - - if patient_id is not None: - if not patient_id in self.db['patients']: - logger.info("Creating patient with id: %s", patient_id) - patient = db.Patient(pid=patient_id) - self.db['patients'][patient_id] = patient - - if not exp_id in self.db['patients'][patient_id].experiments: - logger.info("Linking experiment into patient with id: %s", - patient_id) - self.db['patients'][patient_id].link_experiment(exp_db, - exp_id) - - logger.info("Committing DB transaction") - db.transaction.commit() - - return name - - except: - logger.error("Aborting DB transaction") - db.transaction.abort() - raise - - def add_experiment(self, experiment_uuid=None, timestamp=None, **kwargs): - """Add a new experiment. Will raise KeyExistsError if id is already - in db to avoid unintended collisions. - ---- - Arguments: - id: experiment id---UUID will be generated if not supplied - timestamp: current time---Will be generated if not supplied - kwargs: additional keyword arguments that will be saved in experiment. - """ - - if experiment_uuid is None: - experiment_uuid = uuid4().hex - if timestamp is None: - timestamp = time() - - kwargs.update({'id':experiment_uuid, 'timestamp':timestamp}) - - if not experiment_uuid in self.db[self.name]: - self.db[self.name][experiment_uuid] = db.PersistentMapping() - else: - logger.info("Experiment already exists, appending") - - self.db[self.name][experiment_uuid].update(kwargs) - - return (self.db[self.name], experiment_uuid) - - def add_dstat_measurement(self, experiment, measurement_uuid=None, - data=None, timestamp=None, name=None): - - if measurement_uuid is None: - measurement_uuid = uuid4().hex - if timestamp is None: - timestamp = time() - if data is None: - data = {} - - if not 'measurements' in experiment: - experiment['measurements'] = db.PersistentMapping() - if not 'measurements_by_name' in experiment: - experiment['measurements_by_name'] = db.PersistentMapping() - - if measurement_uuid in experiment['measurements']: - raise db.KeyExistsError(measurement_uuid, - "Measurement ID already exists. Access directly to update") - - data['timestamp'] = timestamp - data['id'] = measurement_uuid - - if name is not None: - data['name'] = name - - experiment['measurements'][measurement_uuid] = data - - if name is not None: - while name in experiment['measurements_by_name']: - first, sep, last = name.rpartition('-') - - if last.isdigit(): - index = int(last) - index += 1 - name = sep.join((first,str(index))) - else: - name += '-1' - - experiment['measurements_by_name'][name] = data - - return name \ No newline at end of file diff --git a/dstat_interface/interface/dstatinterface.glade b/dstat_interface/interface/dstatinterface.glade index 345ab09706c9af5db2e3a6c58fa6e6add4c47739..02aab91f98344971444470fc676593c4e7e46437 100644 --- a/dstat_interface/interface/dstatinterface.glade +++ b/dstat_interface/interface/dstatinterface.glade @@ -689,11 +689,6 @@ Thanks to Christian Fobel for help with Dropbot Plugin</property> <property name="can_focus">False</property> <property name="stock">gtk-preferences</property> </object> - <object class="GtkImage" id="image7"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="stock">gtk-info</property> - </object> <object class="GtkImage" id="image8"> <property name="visible">True</property> <property name="can_focus">False</property> @@ -841,28 +836,6 @@ Thanks to Christian Fobel for help with Dropbot Plugin</property> </child> </object> </child> - <child> - <object class="GtkMenuItem" id="menu_database"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">Database</property> - <child type="submenu"> - <object class="GtkMenu" id="menu5"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <child> - <object class="GtkImageMenuItem" id="menu_database_options"> - <property name="label" translatable="yes">Database Options</property> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="image">image7</property> - <property name="use_stock">False</property> - </object> - </child> - </object> - </child> - </object> - </child> <child> <object class="GtkMenuItem" id="menuitem4"> <property name="visible">True</property> diff --git a/dstat_interface/main.py b/dstat_interface/main.py index 274d2bbc6acb01b796952b905ef1baf63b394ecc..c4b65beec26ff99f22a9e2a68c52e3ab7f8fb1dc 100755 --- a/dstat_interface/main.py +++ b/dstat_interface/main.py @@ -48,7 +48,6 @@ os.chdir(os.path.dirname(os.path.abspath(sys.argv[0]))) from version import getVersion import interface.save as save -from interface.db import DB_Window import dstat_comm as comm import experiments as exp import interface.exp_window as exp_window @@ -59,7 +58,6 @@ import params import parameter_test import analysis import zmq -import db from errors import InputError from plugin import DstatPlugin, get_hub_uri @@ -101,12 +99,6 @@ class Main(object): self.exp_window = exp_window.Experiments(self.builder) self.analysis_opt_window = analysis.AnalysisOptions(self.builder) - - self.db_window = DB_Window() - self.builder.get_object('menu_database_options').connect_object( - 'activate', DB_Window.show, self.db_window - ) - self.db_window.connect('db_reset', db.restart_db) # Setup Autosave self.autosave_checkbox = self.builder.get_object('autosave_checkbutton') @@ -191,7 +183,6 @@ class Main(object): params.save_params(self, 'last_params.yml') self.on_serial_disconnect_clicked() - db.stop_db() mainloop.quit() def on_gtk_about_activate(self, menuitem, data=None): @@ -412,13 +403,7 @@ class Main(object): self.metadata = metadata if self.metadata is not None: - logger.info("Loading external metadata") - self.db_window.update_from_metadata(self.metadata) - elif self.db_window.params['exp_id_entry'] is None: - logger.info("DB exp_id field blank, autogenerating") - self.db_window.on_exp_id_autogen_button_clicked() - - self.db_window.params = {'measure_id_entry':experiment_id.hex} + logger.info("Loading external metadata") def exceptions(): """ Cleans up after errors """ @@ -704,33 +689,6 @@ class Main(object): self.autosavedir_button.get_filename(), self.autosavename.get_text() ) - # Database output - if self.current_exp.parameters['db_enable_checkbutton']: - meta = {} - - if self.current_exp.parameters['metadata'] is not None: - metadata = self.current_exp.parameters['metadata'] - exp_metakeys = ['experiment_uuid', 'patient_id', 'name'] - meta.update( - {k: metadata[k] - for k in metadata - if k not in exp_metakeys - } - ) - - name = self.current_exp.parameters['measure_name_entry'] - - newname = db.current_db.add_results( - measurement_uuid=self.active_experiment_id.hex, - measurement_name=name, - experiment_uuid=self.current_exp.parameters['exp_id_entry'], - experiment_metadata=meta, - patient_id=self.current_exp.parameters['patient_id_entry'], - timestamp=None, - data=self.current_exp.export() - ) - - self.db_window.params = {'measure_name_entry':newname} # uDrop # UI stuff diff --git a/dstat_interface/params.py b/dstat_interface/params.py index 1bf6db84b2cf76a539b17f766b6bf330105078c2..6d384e6c806a47526d100377e3cac627a050e202 100755 --- a/dstat_interface/params.py +++ b/dstat_interface/params.py @@ -43,8 +43,7 @@ def get_params(window): logger.info("No gain selected.") parameters.update(window.exp_window.get_params(selection)) parameters.update(window.analysis_opt_window.params) - parameters.update(window.db_window.persistent_params) - + return parameters def save_params(window, path): @@ -74,6 +73,5 @@ def set_params(window, params): window.exp_window.set_params(params['experiment_index'], params) window.analysis_opt_window.params = params - window.db_window.params = params window.params_loaded = True diff --git a/pavement.py b/pavement.py index bf1f907e0cfac6ff06845920459077722865df40..0aea7f58afe84674e34958f65404241569de2066 100644 --- a/pavement.py +++ b/pavement.py @@ -18,8 +18,7 @@ setup(name='dstat_interface', license='GPLv3', packages=['dstat_interface', ], install_requires=['matplotlib', 'numpy', 'pyserial', 'pyzmq', - 'pyyaml','seaborn', 'zmq-plugin>=0.2.post2', 'zodb', - 'zeo', 'psutil'], + 'pyyaml','seaborn', 'zmq-plugin>=0.2.post2'], # Install data listed in `MANIFEST.in` include_package_data=True)