def upload_odml_tree(session, doc_or_section): """ Upload a whole odml tree. :param session: :type session: Session :param doc_or_section: :type doc_or_section: odml.Document or odml.Section :return: The root of the uploaded odml tree. :rtype: BaseSection """ created_objects = [] # closure that is used for recursive upload def upload_section_recursive(section): sec_uploaded = session.set(section) created_objects.append(sec_uploaded) for prop in section.properties: prop = copy.deepcopy(prop) sec_uploaded.append(prop) prop_uploaded = session.set(prop) created_objects.append(prop_uploaded) for value in prop.values: value = copy.deepcopy(value) prop_uploaded.append(value) val_uploaded = session.set(value) created_objects.append(val_uploaded) for child_section in section.sections: child_section._parent = sec_uploaded upload_section_recursive(child_section) return sec_uploaded if not (isinstance(doc_or_section, odml.doc.BaseDocument) or isinstance(doc_or_section, odml.section.BaseSection)): raise TypeError("Provide odML Document or Section") try: if isinstance(doc_or_section, odml.doc.BaseDocument): head = session.set(doc_or_section) created_objects.append(head) for sec in doc_or_section.sections: sec._parent = head upload_section_recursive(sec) else: head = upload_section_recursive(doc_or_section) return session.get(head.location, refresh=True) except RuntimeError as e: delete_all(session, created_objects) raise e
def upload_neo_structure(session, neo_object): """ Upload a whole neo structure recursively. :param session: :type session: Session :param neo_object: :type neo_object: object :return: The uploaded neo object :rtype: object """ processed = {} # define simple closures that upload a specific neo object def upload_block(block): if block not in processed: block_uploaded = session.set(block) processed[block] = block_uploaded for segment in block.segments: upload_segment(segment, block_uploaded) for channel_group in block.recordingchannelgroups: upload_recording_channel_group(channel_group, block_uploaded) return block_uploaded else: return processed[block] def upload_segment(segment, block=None): if segment not in processed: seg_uploaded = session.set(segment) processed[segment] = seg_uploaded signals = (segment.analogsignals or []) + (segment.irregularlysampledsignals or []) for signal in signals: upload_signal(signal, seg_uploaded) for signal_array in segment.analogsignalarrays: upload_signal_array(signal_array, seg_uploaded) spikes = (segment.spikes or []) + (segment.spiketrains or []) for spike in spikes: upload_spike(spike, seg_uploaded) events_and_epochs = (segment.events or []) + (segment.eventarrays or []) events_and_epochs += (segment.epochs or []) + (segment.epocharrays or []) for obj in events_and_epochs: upload_event_or_epoch(obj, seg_uploaded) else: seg_uploaded = processed[segment] if block is not None: seg_uploaded.block = block seg_uploaded = session.set(seg_uploaded) processed[segment] = seg_uploaded return seg_uploaded def upload_recording_channel_group(channel_group, block=None): if channel_group not in processed: group_uploaded = session.set(channel_group) processed[channel_group] = group_uploaded for channel in channel_group.recordingchannels: upload_recording_channel(channel, group_uploaded) for unit in channel_group.units: upload_unit(unit, group_uploaded) else: group_uploaded = processed[channel_group] if block is not None: group_uploaded.block = block group_uploaded = session.set(group_uploaded) processed[channel_group] = group_uploaded return group_uploaded def upload_recording_channel(recording_channel, channel_group=None): if recording_channel not in processed: channel_uploaded = session.set(recording_channel) processed[recording_channel] = channel_uploaded signals = (recording_channel.analogsignals or []) + (recording_channel.irregularlysampledsignals or []) for signal in signals: upload_signal(signal, None, channel_uploaded) else: channel_uploaded = processed[recording_channel] if channel_group is not None: channel_uploaded.recordingchannelgroups.append(channel_group) channel_uploaded = session.set(channel_uploaded) processed[recording_channel] = channel_uploaded return channel_uploaded def upload_unit(unit, channel_group=None): if unit not in processed: unit_uploaded = session.set(unit) processed[unit] = unit_uploaded spikes = (unit.spikes or []) + (unit.spiketrains or []) for spike in spikes: upload_spike(spike, None, unit_uploaded) else: unit_uploaded = processed[unit] if channel_group is not None: unit_uploaded.recordingchannelgroup = channel_group unit_uploaded = session.set(unit_uploaded) processed[unit] = unit_uploaded return unit_uploaded def upload_spike(spike, segment=None, unit=None): if spike not in processed: spike_uploaded = session.set(spike) processed[spike] = spike_uploaded else: spike_uploaded = processed[spike] if segment is not None: spike_uploaded.segment = segment spike_uploaded = session.set(spike_uploaded) processed[spike] = spike_uploaded if unit is not None: spike_uploaded.unit = unit spike_uploaded = session.set(spike_uploaded) processed[spike] = spike_uploaded return spike_uploaded def upload_signal_array(signal_array, segment=None, channel_group=None): if signal_array not in processed: array_uploaded = session.set(signal_array) processed[signal_array] = array_uploaded else: array_uploaded = processed[signal_array] if segment is not None: array_uploaded.segment = segment array_uploaded = session.set(array_uploaded) processed[signal_array] = array_uploaded if channel_group is not None: array_uploaded.recordingchannelgroup = channel_group array_uploaded = session.set(array_uploaded) processed[signal_array] = array_uploaded return array_uploaded def upload_signal(signal, segment=None, channel=None): if signal not in processed: signal_uploaded = session.set(signal) processed[signal] = signal_uploaded else: signal_uploaded = processed[signal] if segment is not None: signal_uploaded.segment = segment signal_uploaded = session.set(signal_uploaded) processed[signal] = signal_uploaded if channel is not None: signal_uploaded.recordingchannel = channel signal_uploaded = session.set(signal_uploaded) processed[signal] = signal_uploaded return signal_uploaded def upload_event_or_epoch(obj, segment=None): if obj not in processed: uploaded = session.set(obj) processed[obj] = uploaded else: uploaded = processed[obj] if segment is not None: uploaded.segment = segment uploaded = session.set(uploaded) processed[obj] = uploaded return uploaded # select a matching upload function and start upload try: if isinstance(neo_object, neo.Block): uploaded = upload_block(neo_object) elif isinstance(neo_object, neo.Segment): uploaded = upload_segment(neo_object) elif isinstance(neo_object, neo.EventArray): uploaded = upload_event_or_epoch(neo_object) elif isinstance(neo_object, neo.Event): uploaded = upload_event_or_epoch(neo_object) elif isinstance(neo_object, neo.EpochArray): uploaded = upload_event_or_epoch(neo_object) elif isinstance(neo_object, neo.Epoch): uploaded = upload_event_or_epoch(neo_object) elif isinstance(neo_object, neo.RecordingChannelGroup): uploaded = upload_recording_channel_group(neo_object) elif isinstance(neo_object, neo.RecordingChannel): uploaded = upload_recording_channel(neo_object) elif isinstance(neo_object, neo.Unit): uploaded = upload_unit(neo_object) elif isinstance(neo_object, neo.SpikeTrain): uploaded = upload_spike(neo_object) elif isinstance(neo_object, neo.Spike): uploaded = upload_spike(neo_object) elif isinstance(neo_object, neo.AnalogSignalArray): uploaded = upload_signal_array(neo_object) elif isinstance(neo_object, neo.AnalogSignal): uploaded = upload_signal(neo_object) elif isinstance(neo_object, neo.IrregularlySampledSignal): uploaded = upload_signal(neo_object) else: raise RuntimeError("Not compatible type: " + str(type(neo_object))) return session.get(uploaded.location, recursive=True, refresh=True) except RuntimeError as e: if len(processed) > 0: delete_all(session, processed.keys()) raise e