INM-6 / python-neo

Neo is a package for representing electrophysiology data in Python, together with support for reading a wide range of neurophysiology file formats
http://packages.python.org/neo/
BSD 3-Clause "New" or "Revised" License
3 stars 10 forks source link

Annotation filtering based on multiple allowed values #11

Open mdenker opened 9 years ago

mdenker commented 9 years ago

Currently, the filter function in neo accepts inputs of the form

targdict=[{cond1,cond2},{cond3,cond4},..]

where cond1 and cond2 are OR, whereas the individual dictionaries {cond1,cond2} and {cond3,cond4} are AND connected.

One drawback is that it is not possible to filter for multiple values. For example, filtering for units 0 and 1 on electrode 7 is not possible via the following statement, which returns only unit 1 (the last filtering condition specified):

bl.filter(targdict=[{"unit_id":0,"unit_id":1},{"electrode_id":7}], objects=neo.core.SpikeTrain)

Output:

[SpikeTrain
 name: 'Segment 0, Channel 7, Unit 1'
 annotations: {'channel_id': 7,
   'electrode_id': 7,
   'mua': False,
   'sua': False,
   'unit_id': 1}]

To achive the desired behavior, you need to use complex list comprehensions:

z=[item for sublist in [bl.filter(targdict=[{"unit_id":z},{"electrode_id":7}],objects=neo.core.SpikeTrain) for z in [0,1]] for item in sublist]
lphan commented 9 years ago

The problem is : python does not take data in type dict with the same key but different values. Example:

targdict=[{'unit_id':0, 'unit_id':1, 'd':4},{'electrode_id':7}, {'a':1, 'b':2, 'c':3}]
# return: [{'d': 4, 'unit_id': 1}, {'electrode_id': 7}, {'a': 1, 'b': 2, 'c': 3}]
# unit_id = 0 and unit_id = 1 does NOT work. 
lphan commented 9 years ago

For the above example, I suggest the following input:

targdict=[{'unit_id': 0, 'electrode_id': 7}, {'unit_id': 1, 'electrode_id': 7}]
#  it means: (unit_id =0 AND electrode_id = 7) OR (unit_id = 1 AND electrode_id = 7)
targdict[0]  # return {'electrode_id' = 7, 'unit_id' =0}
targdict[1]  # return {'electrode_id' = 7, 'unit_id' =1}

In this case, it might be controversial with the above statement. But if we understand that targdict in this case is a list and for every element is an filter_combi_condition. It's easier to access to the filter_condition of every element with

targdict[0]['electrode_id']  # return 7
targdict[1]['unit_id']  # return 1

The filter function of neo can be reimplemented follow this way.