name: filter_with_scrublet
namespace: "filter"
scope: "public"
description: |
  Doublet detection using the Scrublet method (Wolock, Lopez and Klein, 2019).
  The method tests for potential doublets by using the expression profiles of
  cells to generate synthetic potential doubles which are tested against cells. 
  The method returns a "doublet score" on which it calls for potential doublets.
  
  For the source code please visit https://github.com/AllonKleinLab/scrublet.
  
  For 10x we expect the doublet rates to be:
    Multiplet Rate (%) - # of Cells Loaded - # of Cells Recovered
    ~0.4% ~800 ~500
    ~0.8% ~1,600 ~1,000
    ~1.6% ~3,200 ~2,000
    ~2.3% ~4,800 ~3,000
    ~3.1% ~6,400 ~4,000
    ~3.9% ~8,000 ~5,000
    ~4.6% ~9,600 ~6,000
    ~5.4% ~11,200 ~7,000
    ~6.1% ~12,800 ~8,000
    ~6.9% ~14,400 ~9,000
    ~7.6% ~16,000 ~10,000
authors:
  - __merge__: /src/authors/dries_de_maeyer.yaml
    roles: [ contributor ]
  - __merge__: /src/authors/robrecht_cannoodt.yaml
    roles: [ maintainer, contributor ]
arguments:
  # input
  - name: "--input"
    type: file
    description: Input h5mu file
    direction: input
    required: true
    example: input.h5mu

  - name: "--modality"
    description: |
      Which modality from the input MuData file to process.
    type: string
    default: "rna"
    required: false

  - name: "--layer"
    description: "Input layer to use as data for calculating doublets. .X is used not specified."
    type: string
    required: false

  # output
  - name: "--output"
    type: file
    description: Output h5mu file.
    direction: output
    example: output.h5mu

  - name: "--obs_name_filter"
    type: string
    default: "filter_with_scrublet"
    description: In which .obs slot to store a boolean array corresponding to which observations should be filtered out.

  - name: "--do_subset"
    type: boolean_true
    description: Whether to subset before storing the output.

  - name: "--obs_name_doublet_score"
    type: string
    default: "scrublet_doublet_score"
    description: Name of the doublet scores column in the obs slot of the returned object.
  
  - name: "--expected_doublet_rate"
    type: double
    required: false
    min: 0
    max: 1
    description: |
      The estimated fraction of doublets as from the experimental setup.

  - name: "--stdev_doublet_rate"
    type: double
    min: 0
    required: false
    description: Uncertainty in the expected doublet rate.

  - name: "--n_neighbors"
    type: integer
    required: false
    min: 0
    description: |
      Number of neighbors used to construct the KNN classifier of observed transcriptomes
      and simulated doublets.
  
  - name: "--sim_doublet_ratio"
    type: double
    min: 0
    description: |
      Number of doublets to simulate relative to the number of observed
      transcriptomes.

  - name: "--min_counts"
    type: integer
    default: 2
    description: The number of minimal UMI counts per cell that have to be present for initial cell detection.

  - name: "--min_cells"
    type: integer
    default: 3
    description: The number of cells in which UMIs for a gene were detected.

  - name: "--min_gene_variablity_percent"
    type: double
    default: 85
    description: Used for gene filtering prior to PCA. Keep the most highly variable genes (in the top min_gene_variability_pctl percentile), as measured by the v-statistic [Klein et al., Cell 2015].

  - name: "--num_pca_components"
    type: integer
    default: 30
    description: Number of principal components to use during PCA dimensionality reduction.

  - name: "--distance_metric"
    type: string
    default: "euclidean"
    description: The distance metric used for computing similarities.

  - name: "--scrublet_score_threshold"
    type: double
    required: false
    min: 0
    max: 1
    description: |
      Manual doublet score threshold. Cells with a doublet score above this value
      are classified as doublets. If not provided, the threshold is determined
      automatically by Scrublet.

  - name: "--allow_automatic_threshold_detection_fail"
    type: "boolean_true"
    description: |
      When scrublet fails to automatically determine the double score threshold, 
      allow the component to continue and set the output columns to NA.
__merge__: [., /src/base/h5_compression_argument.yaml]

resources:
  - type: python_script
    path: script.py
  - path: /src/utils/setup_logger.py
  - path: /src/utils/compress_h5mu.py
test_resources:
  - type: python_script
    path: test.py
  - path: /resources_test/pbmc_1k_protein_v3

engines:
- type: docker
  image: python:3.13-slim
  setup:
    - type: apt
      packages: 
        - procps
        - build-essential
    - type: python
      __merge__: [/src/base/requirements/anndata_mudata.yaml, /src/base/requirements/scanpy.yaml, .]
      packages:
        - scrublet
        - annoy==1.17.3
  __merge__: [/src/base/requirements/python_test_setup.yaml, .]

runners:
- type: executable
  docker_run_args: [--env NUMBA_CACHE_DIR=/tmp]
- type: nextflow
  directives:
    label: [highcpu, midmem]
