Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

axonio.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. # -*- coding: utf-8 -*-
  2. from neo.io.basefromrawio import BaseFromRaw
  3. from neo.rawio.axonrawio import AxonRawIO
  4. from neo.core import Block, Segment, AnalogSignal, Event
  5. import quantities as pq
  6. class AxonIO(AxonRawIO, BaseFromRaw):
  7. """
  8. Class for reading data from pCLAMP and AxoScope
  9. files (.abf version 1 and 2), developed by Molecular device/Axon technologies.
  10. - abf = Axon binary file
  11. - atf is a text file based format from axon that could be
  12. read by AsciiIO (but this file is less efficient.)
  13. Here an important note from erikli@github for user who want to get the :
  14. With Axon ABF2 files, the information that you need to recapitulate the original stimulus waveform (both digital and analog) is contained in multiple places.
  15. - `AxonIO._axon_info['protocol']` -- things like number of samples in episode
  16. - `AxonIO.axon_info['section']['ADCSection']` | `AxonIO.axon_info['section']['DACSection']` -- things about the number of channels and channel properties
  17. - `AxonIO._axon_info['protocol']['nActiveDACChannel']` -- bitmask specifying which DACs are actually active
  18. - `AxonIO._axon_info['protocol']['nDigitalEnable']` -- bitmask specifying which set of Epoch timings should be used to specify the duration of digital outputs
  19. - `AxonIO._axon_info['dictEpochInfoPerDAC']` -- dict of dict. First index is DAC channel and second index is Epoch number (i.e. information about Epoch A in Channel 2 would be in `AxonIO._axon_info['dictEpochInfoPerDAC'][2][0]`)
  20. - `AxonIO._axon_info['EpochInfo']` -- list of dicts containing information about each Epoch's digital out pattern. Digital out is a bitmask with least significant bit corresponding to Digital Out 0
  21. - `AxonIO._axon_info['listDACInfo']` -- information about DAC name, scale factor, holding level, etc
  22. - `AxonIO._t_starts` -- start time of each sweep in a unified time basis
  23. - `AxonIO._sampling_rate`
  24. The current AxonIO.read_protocol() method utilizes a subset of these.
  25. In particular I know it doesn't consider `nDigitalEnable`, `EpochInfo`, or `nActiveDACChannel` and it doesn't account
  26. for different types of Epochs offered by Clampex/pClamp other than discrete steps (such as ramp, pulse train, etc and
  27. encoded by `nEpochType` in the EpochInfoPerDAC section). I'm currently parsing a superset of the properties used
  28. by read_protocol() in my analysis scripts, but that code still doesn't parse the full information and isn't in a state
  29. where it could be committed and I can't currently prioritize putting together all the code that would parse the full
  30. set of data. The `AxonIO._axon_info['EpochInfo']` section doesn't currently exist.
  31. """
  32. _prefered_signal_group_mode = 'split-all'
  33. def __init__(self, filename):
  34. AxonRawIO.__init__(self, filename=filename)
  35. BaseFromRaw.__init__(self, filename)
  36. def read_protocol(self):
  37. """
  38. Read the protocol waveform of the file, if present;
  39. function works with ABF2 only. Protocols can be reconstructed
  40. from the ABF1 header.
  41. Returns: list of segments (one for every episode)
  42. with list of analog signls (one for every DAC).
  43. """
  44. sigs_by_segments, sig_names, sig_units = self.read_raw_protocol()
  45. segments = []
  46. for seg_index, sigs in enumerate(sigs_by_segments):
  47. seg = Segment(index=seg_index)
  48. t_start = self._t_starts[seg_index] * pq.s
  49. for c, sig in enumerate(sigs):
  50. ana_sig = AnalogSignal(sig, sampling_rate=self._sampling_rate * pq.Hz,
  51. t_start=t_start, name=sig_names[c], units=sig_units[c])
  52. seg.analogsignals.append(ana_sig)
  53. segments.append(seg)
  54. return segments