Source code for mosaic.trajio.chimeraTrajIO
# -*- coding: utf-8 -*-
"""
Chimera VC100 concatenated file format implementation of metaTrajIO. Read concatenated chimera files with specified amplifier settings.
:Created: 7/11/2016
:Author: Kyle Briggs <kbrig035@uottawa.ca>
:License: See LICENSE.TXT
:ChangeLog:
.. line-block::
5/12/21 AB Update Chimera settings from MAT files generated during data collection.
7/29/16 KB Miscelleneous bugfixes
7/11/16 KB Initial version
"""
import struct
import glob
import mosaic.trajio.metaTrajIO as metaTrajIO
import mosaic.utilities.mosaicLogging as mlog
from mosaic.utilities.util import eval_
from mosaic.trajio.ChimeraSettingsDict import ChimeraSettingsDict as ChimeraSettingsDict
import numpy as np
__all__ = ["chimeraTrajIO", "InvalidDataColumnError"]
[docs]class InvalidDataColumnError(Exception):
pass
[docs]class chimeraTrajIO(metaTrajIO.metaTrajIO):
"""
Read a file generated by the Chimera VC100. The current in pA
is returned after scaling by the amplifier scale factors.
:Usage and Assumptions:
Binary data is in a single column of unsigned 16 bit integers:
The column layout is specified with the ``ColumnTypes`` parameter, which accepts a list of tuples.
[('curr_pA', '<u2')]
The option is left in in case of future changes to the platform, but can be left alone in the settings file for now.
The first element of each tuple is an arbitrary text label and the second element is
a valid `Numpy type <http://docs.scipy.org/doc/numpy/user/basics.types.html>`_.
Chimera gain settings are used to convert the integers stored by the ADC to current values.
These values are automatically read in from matched MAT files generated by the Chimera software.
.. code-block:: javascript
"chimeraTrajIO": {
"filter": "*.log",
"start": "0.0",
"HeaderOffset": "0"
}
:Parameters:
In addition to :class:`~mosaic.metaTrajIO.metaTrajIO` args,
- `HeaderOffset` : Ignore first *n* bytes of the file for header (currently fixed at: 0 bytes).
:Returns:
None
:Errors:
None
"""
def _init(self, **kwargs):
self.chimeraLogger=mlog.mosaicLogging().getLogger(name=__name__)
self.HeaderOffset=0
# Check if a MAT or txt file exists in the data directory and override any settings with values from the file
self._updateChimeraSettings()
# additional meta data
self.fileFormat='bin'
# set the sampling frequency in Hz.
if not hasattr(self, 'Fs'):
self.Fs=self.SamplingFrequency
[docs] def readdata(self, fname):
"""
Return raw data from a single data file. Set a class
attribute Fs with the sampling frequency in Hz.
:Parameters:
- `fname` : fileame to read
:Returns:
- An array object that holds raw (unscaled) data from `fname`
:Errors:
None
"""
self._updateChimeraSettings()
data=np.memmap(fname, dtype=self.ColumnTypes, mode='r', offset=self.HeaderOffset)[self.IonicCurrentColumn]
gain = self.TIAgain * self.preADCgain
bitmask = int((2**16 - 1) - (2**(16-self.ADCbits) - 1))
data = data & bitmask
data = self.ADCvref - 2*self.ADCvref*data.astype(float)/float(2**16)
data = -data/gain + self.pAoffset
return np.array(data*1.0e12, dtype=np.float64)
def _formatsettings(self):
"""
Populate `logObject` with settings strings for display
:Parameters:
- `logObject` : a object that holds logging text (see :class:`~mosaic.utilities.mosaicLog.mosaicLog`)
"""
self.chimeraLogger.info( '\t\tTIAgain = {0} Ohms'.format(self.TIAgain) )
self.chimeraLogger.info( '\t\tpreADCgain = {0} '.format(self.preADCgain) )
self.chimeraLogger.info( '\t\tmVoffset = \'{0}\''.format(self.mVoffset) )
self.chimeraLogger.info( '\t\tADCvref = \'{0}\''.format(self.ADCvref) )
self.chimeraLogger.info( '\t\tADCbits = \'{0}\''.format(self.ADCbits) )
self.chimeraLogger.info( '\t\tpAoffset = \'{0}\''.format(self.pAoffset) )
def _updateChimeraSettings(self):
settFile=self.currentFilename[:-3]+"mat"
chimeraSettings=ChimeraSettingsDict(settFile)
if len(chimeraSettings)>0:
self.chimeraLogger.info("Valid Chimera settings file found. Overriding values in MOSAIC settings file.")
# set the sampling frequency in Hz.
# If the Fs attribute doesn't exist set it
if hasattr(self, 'Fs'):
if self.Fs!=chimeraSettings["SamplingFrequency"]:
raise metaTrajIO.SamplingRateChangedError("The sampling rate in the data file '{0}' has changed.".format(fname))
else:
for k,v in chimeraSettings.items():
setattr(self, k, v)
else:
raise metaTrajIO.InsufficientArgumentsError("A valid Chimera settings file was not found in the data directory.")
if __name__ == '__main__':
print("Main funcion not implemented for chimeraTrajIO")