Abstract method subclassing filter base
Use when when you need to apply domain-specific filtering logic to compounds during Pickaxe expansion—for example, retaining only compounds within a Tanimoto similarity threshold to known targets, or compounds matching experimentally detected masses.From its SKILL.md
npx -y skills add HolobiomicsLab/asb-skill-collections --skill abstract-method-subclassing-filter-baseAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 15 stars15 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as CC-BY-4.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
7.4 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it
abstract-method-subclassing-filter-base
Summary
Implement a custom compound filter for Pickaxe by subclassing the Filter base class and defining _choose_cpds_to_filter, _pre_print, and _post_print methods. This skill enables selective compound retention during iterative reaction network expansion based on user-defined criteria.
When to use
When you need to apply domain-specific filtering logic to compounds during Pickaxe expansion—for example, retaining only compounds within a Tanimoto similarity threshold to known targets, or compounds matching experimentally detected masses. Use this when the built-in filters (Tanimoto threshold, Tanimoto sampling, metabolomics, target) do not capture your filtering requirement.
When NOT to use
- Filter logic requires real-time compound property calculations (e.g., thermodynamic stability via eQuilibrator) not pre-computed in the store—consider pre-computing or refactoring.
- You need to filter based on reaction rule properties or cofactor availability rather than compound properties—use reaction-level filtering logic instead.
- Input compound set is empty or None—the filter will receive an empty set and should gracefully return an empty removal set.
Inputs
- candidate compound set (list or iterator of compound IDs) at each generation
- compound data store (access to SMILES, fingerprints, metadata)
- filter parameters (threshold value, target compound list as SMILES or file path, etc.)
Outputs
- set of compound IDs to remove (compounds that failed filter criterion)
- optionally, logging output from _pre_print and _post_print (stdout)
How to apply
Create a new Filter subclass in minedatabase/filters.py with three core methods: init to accept filter parameters (e.g., threshold values, target compound lists), _choose_cpds_to_filter to iterate through candidate compounds, compute your filtering metric (e.g., maximum Tanimoto similarity using RDKit fingerprints), and return the set of compound IDs to remove, and optionally _pre_print and _post_print to log filtering status and removal statistics. The filtering decision is invoked before each generation, so your _choose_cpds_to_filter method receives the candidate compound set and must return those compounds that fail the filter criterion. Expose your filter subclass in pickaxe_run.py and write unit tests in tests/test_unit/test_filters.py using pytest fixtures to verify threshold enforcement and edge cases.
Related tools
- RDKit (compute molecular fingerprints and similarity scores (e.g., Tanimoto) for filtering logic) — https://rdkit.org/docs/api-docs.html
- pytest (write and execute unit tests for filter subclass with predefined fixtures) — https://docs.pytest.org/en/stable/
- Python (implement Filter subclass with required methods)
Examples
class MyTanimotoFilter(Filter):
def __init__(self, targets_smiles, threshold):
self.targets = targets_smiles
self.threshold = threshold
def _choose_cpds_to_filter(self, cpds):
return {cid for cid in cpds if max_tanimoto_similarity(cid, self.targets) < self.threshold}
Evaluation signals
- Subclass properly inherits from Filter base class and implements all required methods (init, filter_name, _choose_cpds_to_filter) without errors.
- Unit tests in tests/test_unit/test_filters.py pass, including edge cases (empty compound set, all compounds pass/fail, threshold boundary conditions).
- Filtered compound set size decreases predictably (or as expected) at each generation when integrated into a Pickaxe run; removal statistics logged by _post_print align with filter criterion.
- Filter is exposed and configurable in pickaxe_run.py; a full Pickaxe run completes without exception when the custom filter is active.
- Output compound set schema is preserved (compound IDs match those in the input candidate set); no spurious or duplicate removals occur.
Limitations
- Filter execution occurs serially before each generation; computationally expensive metrics (e.g., full-graph similarity to all targets for large sets) may slow expansion.
- Filter has access only to compounds stored in the database; pre-computed or external data (e.g., experimental metadata) must be provided at init time or stored in advance.
- Filter decisions are independent at each generation; no inter-generational memory or dynamic threshold adjustment is built into the base pattern.
- Filter method must return a set of IDs to remove, not retain; inverted logic may cause confusion if the filtering criterion is naturally expressed as 'keep compounds where X > threshold'.
Evidence
- [other] Create a Filter subclass in minedatabase/filters.py with init, filter_name, and _choose_cpds_to_filter methods.: "Create a Filter subclass in minedatabase/filters.py with init, filter_name, and _choose_cpds_to_filter methods."
- [other] _choose_cpds_to_filter - This is the main method you need to implement, where you can loop through the compounds at each generation and decide which ones to keep: "_choose_cpds_to_filter - This is the main method you need to implement, where you can loop through the compounds at each generation and decide which ones to keep"
- [other] _pre_print - This method prints to stdout just before the filter is applied.: "_pre_print - This method prints to stdout just before the filter is applied."
- [other] _post_print - This method prints to stdout just after the filter is applied. Useful for printing a summary of filtering results.: "_post_print - This method prints to stdout just after the filter is applied. Useful for printing a summary of filtering results."
- [other] Write unit test(s) for this custom filter in tests/test_unit/test_filters.py: "Write unit test(s) for this custom filter in tests/test_unit/test_filters.py"
- [intro] Specified filters are applied before each generation (and at the end of the run if specified) to reduce the number of compounds to be expanded: "Specified filters are applied before each generation (and at the end of the run if specified) to reduce the number of compounds to be expanded"
- [other] Creating a custom filter requires a working knowledge of python.: "Creating a custom filter requires a working knowledge of python."
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.