spyglass
spyglass copied to clipboard
delete from `SpikeSortingOutput` exceeds max attempts
I get the below error when trying to delete from SortGroup.
Code:
import spyglass.spikesorting.v0.spikesorting_recording as sgss
(sgss.SortGroup & {'nwb_file_name': 'J1620210529_.nwb',
'sort_group_id': 100}).cautious_delete()
Error stack
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
File ~/Documents/anaconda3/envs/spyglass/lib/python3.9/site-packages/networkx/classes/digraph.py:899, in DiGraph.successors(self, n)
898 try:
--> 899 return iter(self._succ[n])
900 except KeyError as err:
KeyError: '`spikesorting_merge`.`spike_sorting_output`'
The above exception was the direct cause of the following exception:
NetworkXError Traceback (most recent call last)
Cell In[8], line 2
1 import spyglass.spikesorting.v0.spikesorting_recording as sgss
----> 2 (sgss.SortGroup & {'nwb_file_name': 'J1620210529_.nwb',
3 'sort_group_id': 100}).cautious_delete()
File ~/src/spyglass/src/spyglass/utils/dj_mixin.py:452, in SpyglassMixin.cautious_delete(self, force_permission, *args, **kwargs)
449 if not force_permission:
450 self._check_delete_permission()
--> 452 merge_deletes = self.delete_downstream_merge(
453 dry_run=True,
454 disable_warning=True,
455 return_parts=False,
456 )
458 safemode = (
459 dj.config.get("safemode", True)
460 if kwargs.get("safemode") is None
461 else kwargs["safemode"]
462 )
464 if merge_deletes:
File ~/src/spyglass/src/spyglass/utils/dj_mixin.py:248, in SpyglassMixin.delete_downstream_merge(self, restriction, dry_run, reload_cache, disable_warning, return_parts, **kwargs)
245 restriction = restriction or self.restriction or True
247 merge_join_dict = {}
--> 248 for name, chain in self._merge_chains.items():
249 join = chain.join(restriction)
250 if join:
File ~/Documents/anaconda3/envs/spyglass/lib/python3.9/functools.py:993, in cached_property.__get__(self, instance, owner)
991 val = cache.get(self.attrname, _NOT_FOUND)
992 if val is _NOT_FOUND:
--> 993 val = self.func(instance)
994 try:
995 cache[self.attrname] = val
File ~/src/spyglass/src/spyglass/utils/dj_mixin.py:172, in SpyglassMixin._merge_chains(self)
161 """Dict of chains to merges downstream of self
162
163 Format: {full_table_name: TableChains}.
(...)
169 delete_downstream_merge call.
170 """
171 merge_chains = {}
--> 172 for name, merge_table in self._merge_tables.items():
173 chains = TableChains(self, merge_table, connection=self.connection)
174 if len(chains):
File ~/Documents/anaconda3/envs/spyglass/lib/python3.9/functools.py:993, in cached_property.__get__(self, instance, owner)
991 val = cache.get(self.attrname, _NOT_FOUND)
992 if val is _NOT_FOUND:
--> 993 val = self.func(instance)
994 try:
995 cache[self.attrname] = val
File ~/src/spyglass/src/spyglass/utils/dj_mixin.py:150, in SpyglassMixin._merge_tables(self)
147 merge_tables[master_name] = master
148 search_descendants(master)
--> 150 _ = search_descendants(self)
152 logger.info(
153 f"Building merge cache for {self.table_name}.\n\t"
154 + f"Found {len(merge_tables)} downstream merge tables"
155 )
157 return merge_tables
File ~/src/spyglass/src/spyglass/utils/dj_mixin.py:148, in SpyglassMixin._merge_tables.<locals>.search_descendants(parent)
146 if MERGE_PK in master.heading.names:
147 merge_tables[master_name] = master
--> 148 search_descendants(master)
File ~/src/spyglass/src/spyglass/utils/dj_mixin.py:138, in SpyglassMixin._merge_tables.<locals>.search_descendants(parent)
137 def search_descendants(parent):
--> 138 for desc in parent.descendants(as_objects=True):
139 if (
140 MERGE_PK not in desc.heading.names
141 or not (master_name := get_master(desc.full_table_name))
142 or master_name in merge_tables
143 ):
144 continue
File ~/src/datajoint-python/datajoint/table.py:215, in Table.descendants(self, as_objects)
207 def descendants(self, as_objects=False):
208 """
209
210 :param as_objects: False - a list of table names; True - a list of table objects.
211 :return: list of tables descendants in topological order.
212 """
213 return [
214 FreeTable(self.connection, node) if as_objects else node
--> 215 for node in self.connection.dependencies.descendants(self.full_table_name)
216 if not node.isdigit()
217 ]
File ~/src/datajoint-python/datajoint/dependencies.py:170, in Dependencies.descendants(self, full_table_name)
165 """
166 :param full_table_name: In form `schema`.`table_name`
167 :return: all dependent tables sorted in topological order. Self is included.
168 """
169 self.load(force=False)
--> 170 nodes = self.subgraph(nx.algorithms.dag.descendants(self, full_table_name))
171 return unite_master_parts(
172 [full_table_name] + list(nx.algorithms.dag.topological_sort(nodes))
173 )
File ~/Documents/anaconda3/envs/spyglass/lib/python3.9/site-packages/networkx/utils/backends.py:412, in _dispatch.__call__(self, backend, *args, **kwargs)
409 def __call__(self, /, *args, backend=None, **kwargs):
410 if not backends:
411 # Fast path if no backends are installed
--> 412 return self.orig_func(*args, **kwargs)
414 # Use `backend_name` in this function instead of `backend`
415 backend_name = backend
File ~/Documents/anaconda3/envs/spyglass/lib/python3.9/site-packages/networkx/algorithms/dag.py:73, in descendants(G, source)
39 @nx._dispatch
40 def descendants(G, source):
41 """Returns all nodes reachable from `source` in `G`.
42
43 Parameters
(...)
71 ancestors
72 """
---> 73 return {child for parent, child in nx.bfs_edges(G, source)}
File ~/Documents/anaconda3/envs/spyglass/lib/python3.9/site-packages/networkx/algorithms/dag.py:73, in <setcomp>(.0)
39 @nx._dispatch
40 def descendants(G, source):
41 """Returns all nodes reachable from `source` in `G`.
42
43 Parameters
(...)
71 ancestors
72 """
---> 73 return {child for parent, child in nx.bfs_edges(G, source)}
File ~/Documents/anaconda3/envs/spyglass/lib/python3.9/site-packages/networkx/algorithms/traversal/breadth_first_search.py:203, in bfs_edges(G, source, reverse, depth_limit, sort_neighbors)
199 yield from generic_bfs_edges(
200 G, source, lambda node: iter(sort_neighbors(successors(node))), depth_limit
201 )
202 else:
--> 203 yield from generic_bfs_edges(G, source, successors, depth_limit)
File ~/Documents/anaconda3/envs/spyglass/lib/python3.9/site-packages/networkx/algorithms/traversal/breadth_first_search.py:103, in generic_bfs_edges(G, source, neighbors, depth_limit, sort_neighbors)
101 n = len(G)
102 depth = 0
--> 103 next_parents_children = [(source, neighbors(source))]
104 while next_parents_children and depth < depth_limit:
105 this_parents_children = next_parents_children
File ~/Documents/anaconda3/envs/spyglass/lib/python3.9/site-packages/networkx/classes/digraph.py:901, in DiGraph.successors(self, n)
899 return iter(self._succ[n])
900 except KeyError as err:
--> 901 raise NetworkXError(f"The node {n} is not in the digraph.") from err
NetworkXError: The node `spikesorting_merge`.`spike_sorting_output` is not in the digraph.
@CBroz1