Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ValueError on non-spy table for _get_exp_summary() #1031

Closed
MichaelCoulter opened this issue Jul 12, 2024 · 2 comments · Fixed by #1035
Closed

ValueError on non-spy table for _get_exp_summary() #1031

MichaelCoulter opened this issue Jul 12, 2024 · 2 comments · Fixed by #1035
Assignees

Comments

@MichaelCoulter
Copy link
Collaborator

im trying to run this delete command, which returns 1 entry from the IntervalLinearizedPosition table.

(IntervalLinearizedPosition & {'nwb_file_name':'CH85_20220713_.nwb'} 
                 & {'track_graph_name':'CH101 auto track 6 arm v2'}).delete()

but, i get this error. im not sure why it is looking for a downstream table that i'm pretty sure does not use this nwb_file.

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In [230], line 3
      1 from spyglass.common import IntervalLinearizedPosition
      2 #(IntervalLinearizedPosition & {'nwb_file_name LIKE "CH85%"'} & {'track_graph_name LIKE "%101%"'})
----> 3 (IntervalLinearizedPosition & {'nwb_file_name':'CH85_20220713_.nwb'} 
      4                  & {'track_graph_name':'CH101 auto track 6 arm v2'}).delete()

File ~/spyglass/src/spyglass/utils/dj_mixin.py:691, in SpyglassMixin.delete(self, *args, **kwargs)
    689 def delete(self, *args, **kwargs):
    690     """Alias for cautious_delete, overwrites datajoint.table.Table.delete"""
--> 691     self.cautious_delete(*args, **kwargs)

File ~/spyglass/src/spyglass/utils/dj_mixin.py:656, in SpyglassMixin.cautious_delete(self, force_permission, dry_run, *args, **kwargs)
    653 external, IntervalList = self._delete_deps[3], self._delete_deps[4]
    655 if not force_permission or dry_run:
--> 656     self._check_delete_permission()
    658 down_fts = self.delete_downstream_parts(
    659     dry_run=True,
    660     disable_warning=True,
    661 )
    663 if dry_run:

File ~/spyglass/src/spyglass/utils/dj_mixin.py:571, in SpyglassMixin._check_delete_permission(self)
    564     logger.warn(  # Permit delete if no session connection
    565         "Could not find lab team associated with "
    566         + f"{self.__class__.__name__}."
    567         + "\nBe careful not to delete others' data."
    568     )
    569     return
--> 571 sess_summary = self._get_exp_summary()
    572 experimenters = sess_summary.fetch(self._member_pk)
    573 if None in experimenters:

File ~/spyglass/src/spyglass/utils/dj_mixin.py:516, in SpyglassMixin._get_exp_summary(self)
    513 format = dj.U(self._session_pk, self._member_pk)
    515 restr = self.restriction or True
--> 516 sess_link = self._session_connection.cascade(restr, direction="up")
    518 exp_missing = format & (sess_link - SesExp).proj(**empty_pk)
    519 exp_present = format & (sess_link * SesExp - exp_missing).proj()

File ~/spyglass/src/spyglass/utils/dj_graph.py:1146, in TableChain.cascade(self, restriction, direction, **kwargs)
   1144     for table in non_numeric:
   1145         if table is not start:
-> 1146             self._set_restr(table, False, replace=True)
   1148 return self._get_ft(end, with_restr=True)

File ~/spyglass/src/spyglass/utils/dj_graph.py:228, in AbstractGraph._set_restr(self, table, restriction, replace)
    226 def _set_restr(self, table, restriction, replace=False):
    227     """Add restriction to graph node. If one exists, merge with new."""
--> 228     ft = self._get_ft(table)
    229     restriction = (  # Convert to condition if list or dict
    230         make_condition(ft, restriction, set())
    231         if not isinstance(restriction, str)
    232         else restriction
    233     )
    234     existing = self._get_restr(table)

File ~/spyglass/src/spyglass/utils/dj_graph.py:258, in AbstractGraph._get_ft(self, table, with_restr, warn)
    255 else:
    256     restr = True
--> 258 if not (ft := self._get_node(table).get("ft")):
    259     ft = FreeTable(self.connection, table)
    260     self._set_node(table, "ft", ft)

File ~/spyglass/src/spyglass/utils/dj_graph.py:179, in AbstractGraph._get_node(self, table)
    177 table = self._ensure_names(table)
    178 if not (node := self.graph.nodes.get(table)):
--> 179     raise ValueError(
    180         f"Table {table} not found in graph."
    181         + "\n\tPlease import this table and rerun"
    182     )
    183 return node

ValueError: Table `alison_decoding`.`clusterless_aligned_interval_selection` not found in graph.
	Please import this table and rerun

any help is appreciated, thanks!

@MichaelCoulter
Copy link
Collaborator Author

this error is also triggered by automatic deletes, such as this command for populating SortGroup

SortGroup().set_group_by_electrode_group(nwb_file_name)

@CBroz1 CBroz1 changed the title problem with delete ValueError on non-spy table for _get_exp_summary() Jul 14, 2024
@CBroz1 CBroz1 self-assigned this Jul 14, 2024
@MichaelCoulter
Copy link
Collaborator Author

MichaelCoulter commented Jul 14, 2024

the command i tried:

(SortGroup & {'nwb_file_name' : 'CH73_20211209_.nwb'}).delete(force_permission=True)
---------------------------------------------------------------------------
NetworkXError                             Traceback (most recent call last)
File ~/spyglass/src/spyglass/utils/dj_mixin.py:334, in SpyglassMixin._part_masters(self)
    333 try:
--> 334     _ = search_descendants(self)
    335 except NetworkXError:

File ~/spyglass/src/spyglass/utils/dj_mixin.py:331, in SpyglassMixin._part_masters.<locals>.search_descendants(parent)
    330 part_masters.add(master)
--> 331 search_descendants(dj.FreeTable(self.connection, master))

File ~/spyglass/src/spyglass/utils/dj_mixin.py:331, in SpyglassMixin._part_masters.<locals>.search_descendants(parent)
    330 part_masters.add(master)
--> 331 search_descendants(dj.FreeTable(self.connection, master))

File ~/spyglass/src/spyglass/utils/dj_mixin.py:321, in SpyglassMixin._part_masters.<locals>.search_descendants(parent)
    320 def search_descendants(parent):
--> 321     for desc in parent.descendants(as_objects=True):
    322         if (  # Check if has master, is part
    323             not (master := get_master(desc.full_table_name))
    324             # has other non-master parent
    325             or not set(desc.parents()) - set([master])
    326             or master in part_masters  # already in cache
    327         ):

File ~/anaconda3/envs/spyglass2/lib/python3.9/site-packages/datajoint/table.py:212, in Table.descendants(self, as_objects)
    205 """
    206 
    207 :param as_objects: False - a list of table names; True - a list of table objects.
    208 :return: list of tables descendants in topological order.
    209 """
    210 return [
    211     FreeTable(self.connection, node) if as_objects else node
--> 212     for node in self.connection.dependencies.descendants(self.full_table_name)
    213     if not node.isdigit()
    214 ]

File ~/anaconda3/envs/spyglass2/lib/python3.9/site-packages/datajoint/dependencies.py:170, in Dependencies.descendants(self, full_table_name)
    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 ~/anaconda3/envs/spyglass2/lib/python3.9/site-packages/networkx/algorithms/dag.py:53, in descendants(G, source)
     52 if not G.has_node(source):
---> 53     raise nx.NetworkXError(f"The node {source} is not in the graph.")
     54 des = {n for n, d in nx.shortest_path_length(G, source=source).items()}

NetworkXError: The node `jguidera_spikesorting`.`__spike_sorting_recording_cohort` is not in the graph.

During handling of the above exception, another exception occurred:

NetworkXError                             Traceback (most recent call last)
File ~/spyglass/src/spyglass/utils/dj_mixin.py:338, in SpyglassMixin._part_masters(self)
    337     self._import_part_masters()
--> 338     _ = search_descendants(self)
    339 except NetworkXError as e:

File ~/spyglass/src/spyglass/utils/dj_mixin.py:331, in SpyglassMixin._part_masters.<locals>.search_descendants(parent)
    330 part_masters.add(master)
--> 331 search_descendants(dj.FreeTable(self.connection, master))

File ~/spyglass/src/spyglass/utils/dj_mixin.py:321, in SpyglassMixin._part_masters.<locals>.search_descendants(parent)
    320 def search_descendants(parent):
--> 321     for desc in parent.descendants(as_objects=True):
    322         if (  # Check if has master, is part
    323             not (master := get_master(desc.full_table_name))
    324             # has other non-master parent
    325             or not set(desc.parents()) - set([master])
    326             or master in part_masters  # already in cache
    327         ):

File ~/anaconda3/envs/spyglass2/lib/python3.9/site-packages/datajoint/table.py:212, in Table.descendants(self, as_objects)
    205 """
    206 
    207 :param as_objects: False - a list of table names; True - a list of table objects.
    208 :return: list of tables descendants in topological order.
    209 """
    210 return [
    211     FreeTable(self.connection, node) if as_objects else node
--> 212     for node in self.connection.dependencies.descendants(self.full_table_name)
    213     if not node.isdigit()
    214 ]

File ~/anaconda3/envs/spyglass2/lib/python3.9/site-packages/datajoint/dependencies.py:170, in Dependencies.descendants(self, full_table_name)
    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 ~/anaconda3/envs/spyglass2/lib/python3.9/site-packages/networkx/algorithms/dag.py:53, in descendants(G, source)
     52 if not G.has_node(source):
---> 53     raise nx.NetworkXError(f"The node {source} is not in the graph.")
     54 des = {n for n, d in nx.shortest_path_length(G, source=source).items()}

NetworkXError: The node `jguidera_edeno_decoder_run`.`__edeno_decode` is not in the graph.

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
Cell In [5], line 3
      1 SpikeSortingRecording & {'nwb_file_name' : 'CH73_20211209_.nwb'}
      2 #(Nwbfile & {'nwb_file_name LIKE "CH73%"'}).fetch('nwb_file_name')
----> 3 (SortGroup & {'nwb_file_name' : 'CH73_20211209_.nwb'}).delete(force_permission=True)

File ~/spyglass/src/spyglass/utils/dj_mixin.py:691, in SpyglassMixin.delete(self, *args, **kwargs)
    689 def delete(self, *args, **kwargs):
    690     """Alias for cautious_delete, overwrites datajoint.table.Table.delete"""
--> 691     self.cautious_delete(*args, **kwargs)

File ~/spyglass/src/spyglass/utils/dj_mixin.py:658, in SpyglassMixin.cautious_delete(self, force_permission, dry_run, *args, **kwargs)
    655 if not force_permission or dry_run:
    656     self._check_delete_permission()
--> 658 down_fts = self.delete_downstream_parts(
    659     dry_run=True,
    660     disable_warning=True,
    661 )
    663 if dry_run:
    664     return (
    665         down_fts,
    666         IntervalList(),  # cleanup func relies on downstream deletes
    667         external["raw"].unused(),
    668         external["analysis"].unused(),
    669     )

File ~/spyglass/src/spyglass/utils/dj_mixin.py:429, in SpyglassMixin.delete_downstream_parts(self, restriction, dry_run, reload_cache, disable_warning, return_graph, verbose, **kwargs)
    426 if reload_cache:
    427     _ = self.__dict__.pop("_part_masters", None)
--> 429 _ = self._part_masters  # load cache before loading graph
    430 restriction = restriction or self.restriction or True
    432 restr_graph = RestrGraph(
    433     seed_table=self,
    434     leaves={self.full_table_name: restriction},
   (...)
    437     verbose=verbose,
    438 )

File ~/anaconda3/envs/spyglass2/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 ~/spyglass/src/spyglass/utils/dj_mixin.py:341, in SpyglassMixin._part_masters(self)
    339     except NetworkXError as e:
    340         table_name = "".join(e.args[0].split("`")[1:4])
--> 341         raise ValueError(f"Please import {table_name} and try again.")
    343 logger.info(
    344     f"Building part-parent cache for {self.camel_name}.\n\t"
    345     + f"Found {len(part_masters)} downstream part tables"
    346 )
    348 return part_masters

ValueError: Please import jguidera_edeno_decoder_run.__edeno_decode and try again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants