Skip to content

variantplaner

VariantPlaner, a tool kit to manage many variants without many cpu and ram resource.

Convert a vcf in parquet, convert annotations in parquet, convert parquet in vcf.

But also build a file struct to get a fast variant database interrogations time.

Modules:

  • cli

    Module contains command line entry point function.

  • exception

    Exception could be generate by VariantPlanner.

  • extract

    Extract information of polars.LazyFrame produce from raw vcf file parsing.

  • generate

    Function to generate information.

  • io

    Module manage input parsing and output serializing.

  • normalization

    Function use to normalize data.

  • objects

    Module to store variantplaner object.

  • struct

    Generated data structures for easy integration.

Classes:

  • Annotations

    Object to manage lazyframe as Annotations.

  • ContigsLength

    Store contigs -> length information.

  • Genotypes

    Object to manage lazyframe as Genotypes.

  • Pedigree

    Object to manage lazyframe as Variants.

  • Variants

    Object to manage lazyframe as Variants.

  • Vcf

    Object to manage lazyframe as Vcf.

  • VcfHeader

    Object that parse and store vcf information.

  • VcfParsingBehavior

    Enumeration use to control behavior of IntoLazyFrame.

Annotations

Annotations()

Bases: LazyFrame

Object to manage lazyframe as Annotations.

Methods:

  • minimal_schema

    Get minimal schema of genotypes polars.LazyFrame.

Source code in src/variantplaner/objects/annotations.py
15
16
17
def __init__(self):
    """Initialize a Annotations object."""
    self.lf = polars.LazyFrame(schema=Annotations.minimal_schema())

minimal_schema classmethod

minimal_schema() -> dict[str, type]

Get minimal schema of genotypes polars.LazyFrame.

Source code in src/variantplaner/objects/annotations.py
19
20
21
22
23
24
@classmethod
def minimal_schema(cls) -> dict[str, type]:
    """Get minimal schema of genotypes polars.LazyFrame."""
    return {
        "id": polars.UInt64,
    }

ContigsLength

ContigsLength()

Store contigs -> length information.

Methods:

Source code in src/variantplaner/objects/contigs_length.py
31
32
33
34
35
36
37
38
39
def __init__(self):
    """Initialise a contigs length."""
    self.lf = polars.LazyFrame(
        schema={
            "contig": polars.String,
            "length": polars.UInt64,
            "offset": polars.UInt64,
        }
    )

from_path

from_path(
    path: Path, /, **scan_csv_args: Unpack[ScanCsv]
) -> int

Fill object with file point by pathlib.Path.

Argument: path: path of input file

Returns: Number of contigs line view

Source code in src/variantplaner/objects/contigs_length.py
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
def from_path(self, path: pathlib.Path, /, **scan_csv_args: Unpack[ScanCsv]) -> int:
    """Fill object with file point by pathlib.Path.

    Argument:
    path: path of input file

    Returns: Number of contigs line view
    """
    csv = Csv()
    csv.from_path(path, **scan_csv_args)
    self.lf = csv.lf

    self.__compute_offset()

    return self.lf.collect(engine="cpu").shape[0]

from_vcf_header

from_vcf_header(header: VcfHeader) -> int

Fill a object with VcfHeader.

Argument

header: VcfHeader

Returns: Number of contigs line view

Source code in src/variantplaner/objects/contigs_length.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
def from_vcf_header(self, header: VcfHeader) -> int:
    """Fill a object with VcfHeader.

    Argument:
       header: VcfHeader

    Returns: Number of contigs line view
    """
    contigs_id = re.compile(r"ID=(?P<id>[^,]+)")
    contigs_len = re.compile(r"length=(?P<length>[^,>]+)")

    count = 0
    contigs2len: dict[str, list] = {"contig": [], "length": []}
    for contig_line in header.contigs:
        if (len_match := contigs_len.search(contig_line)) and (id_match := contigs_id.search(contig_line)):
            contigs2len["contig"].append(id_match.groupdict()["id"])
            contigs2len["length"].append(int(len_match.groupdict()["length"]))
        count += 1

    self.lf = polars.LazyFrame(contigs2len, schema={"contig": polars.String, "length": polars.UInt64})

    self.__compute_offset()

    return count

Genotypes

Genotypes(data: LazyFrame | None = None)

Bases: LazyFrame

Object to manage lazyframe as Genotypes.

Methods:

Source code in src/variantplaner/objects/genotypes.py
15
16
17
18
19
20
def __init__(self, data: polars.LazyFrame | None = None):
    """Initialize a Genotypes object."""
    if data is None:
        self.lf = polars.LazyFrame(schema=Genotypes.minimal_schema())
    else:
        self.lf = data

minimal_schema classmethod

minimal_schema() -> dict[str, type]

Get minimal schema of genotypes polars.LazyFrame.

Source code in src/variantplaner/objects/genotypes.py
26
27
28
29
30
31
32
@classmethod
def minimal_schema(cls) -> dict[str, type]:
    """Get minimal schema of genotypes polars.LazyFrame."""
    return {
        "id": polars.UInt64,
        "sample": polars.String,
    }

samples_names

samples_names() -> list[str]

Get list of sample name.

Source code in src/variantplaner/objects/genotypes.py
22
23
24
def samples_names(self) -> list[str]:
    """Get list of sample name."""
    return self.lf.select("sample").unique("sample").collect(engine="cpu").get_column("sample").to_list()

Pedigree

Pedigree()

Bases: LazyFrame

Object to manage lazyframe as Variants.

Methods:

Source code in src/variantplaner/objects/pedigree.py
19
20
21
def __init__(self):
    """Initialize a Variants object."""
    self.lf = polars.LazyFrame(schema=Pedigree.minimal_schema())

from_path

from_path(input_path: Path) -> None

Read a pedigree file in polars.LazyFrame.

Parameters:

  • input_path (Path) –

    Path to pedigree file.

Returns:

  • None

    A polars.LazyFrame that contains ped information ('family_id', 'personal_id', 'father_id', 'mother_id', 'sex', 'affected')

Source code in src/variantplaner/objects/pedigree.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
def from_path(self, input_path: pathlib.Path) -> None:
    """Read a pedigree file in [polars.LazyFrame](https://pola-rs.github.io/polars/py-polars/html/reference/lazyframe/index.html).

    Args:
        input_path: Path to pedigree file.

    Returns:
        A [polars.LazyFrame](https://pola-rs.github.io/polars/py-polars/html/reference/lazyframe/index.html) that contains ped information ('family_id', 'personal_id', 'father_id', 'mother_id', 'sex', 'affected')
    """
    self.lf = polars.scan_csv(
        input_path,
        separator="\t",
        has_header=False,
        null_values=["None", "unknown"],
        new_columns=[
            "family_id",
            "personal_id",
            "father_id",
            "mother_id",
            "sex",
            "affected",
        ],
        schema_overrides=Pedigree.minimal_schema(),
    )

minimal_schema classmethod

minimal_schema() -> Mapping[str, PolarsDataType]

Get schema of variants polars.LazyFrame.

Source code in src/variantplaner/objects/pedigree.py
62
63
64
65
66
67
68
69
70
71
72
73
74
@classmethod
def minimal_schema(
    cls,
) -> collections.abc.Mapping[str, polars._typing.PolarsDataType]:
    """Get schema of variants polars.LazyFrame."""
    return {
        "family_id": polars.String,
        "personal_id": polars.String,
        "father_id": polars.String,
        "mother_id": polars.String,
        "sex": polars.String,
        "affected": polars.Boolean,
    }

to_path

to_path(output_path: Path) -> None

Write pedigree polars.LazyFrame in ped format.

Warning: This function performs polars.LazyFrame.collect before write csv, this can have a significant impact on memory usage

Parameters:

  • lf

    LazyFrame contains pedigree information.

  • output_path (Path) –

    Path where write pedigree information.

Returns:

  • None

    None

Source code in src/variantplaner/objects/pedigree.py
48
49
50
51
52
53
54
55
56
57
58
59
60
def to_path(self, output_path: pathlib.Path) -> None:
    """Write pedigree [polars.LazyFrame](https://pola-rs.github.io/polars/py-polars/html/reference/lazyframe/index.html) in ped format.

    Warning: This function performs [polars.LazyFrame.collect][] before write csv, this can have a significant impact on memory usage

    Args:
        lf: LazyFrame contains pedigree information.
        output_path: Path where write pedigree information.

    Returns:
        None
    """
    self.lf.collect(engine="cpu").write_csv(output_path, include_header=False, separator="\t")

Variants

Variants(data: LazyFrame | None = None)

Bases: LazyFrame

Object to manage lazyframe as Variants.

Methods:

Source code in src/variantplaner/objects/variants.py
15
16
17
18
19
20
def __init__(self, data: polars.LazyFrame | None = None):
    """Initialize a Variants object."""
    if data is None:
        self.lf = polars.LazyFrame(schema=Variants.minimal_schema())
    else:
        self.lf = data

minimal_schema classmethod

minimal_schema() -> dict[str, type]

Get schema of variants polars.LazyFrame.

Source code in src/variantplaner/objects/variants.py
22
23
24
25
26
27
28
29
30
31
@classmethod
def minimal_schema(cls) -> dict[str, type]:
    """Get schema of variants polars.LazyFrame."""
    return {
        "id": polars.UInt64,
        "chr": polars.String,
        "pos": polars.UInt64,
        "ref": polars.String,
        "alt": polars.String,
    }

Vcf

Vcf()

Object to manage lazyframe as Vcf.

Methods:

Source code in src/variantplaner/objects/vcf.py
50
51
52
53
54
def __init__(self):
    """Initialize a Vcf object."""
    self.lf = polars.LazyFrame(schema=Variants.minimal_schema())

    self.header = VcfHeader()

add_genotypes

add_genotypes(genotypes_lf: Genotypes) -> None

Add genotypes information in vcf.

Source code in src/variantplaner/objects/vcf.py
157
158
159
160
161
162
163
164
165
166
167
def add_genotypes(self, genotypes_lf: Genotypes) -> None:
    """Add genotypes information in vcf."""
    for sample in genotypes_lf.samples_names():
        geno2sample = (
            genotypes_lf.lf.filter(polars.col("sample") == sample)
            .rename(
                {col: f"{sample}_{col}" for col in genotypes_lf.lf.collect_schema().names()[2:]},
            )
            .drop("sample")
        )
        self.lf = self.lf.join(geno2sample, on="id", how="full", coalesce=True)

annotations

annotations(
    select_info: set[str] | None = None,
) -> Annotations

Get annotations of vcf.

Source code in src/variantplaner/objects/vcf.py
169
170
171
172
173
def annotations(self, select_info: set[str] | None = None) -> Annotations:
    """Get annotations of vcf."""
    lf = self.lf.with_columns(self.lf.header.info_parser(select_info))

    return lf.drop("chr", "pos", "ref", "alt", "format", "info")

from_path

from_path(
    path: Path,
    chr2len_path: Path | None,
    behavior: VcfParsingBehavior = NOTHING,
) -> None

Populate Vcf object with vcf file.

Source code in src/variantplaner/objects/vcf.py
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
def from_path(
    self,
    path: pathlib.Path,
    chr2len_path: pathlib.Path | None,
    behavior: VcfParsingBehavior = VcfParsingBehavior.NOTHING,
) -> None:
    """Populate Vcf object with vcf file."""
    with xopen.xopen(path) as fh:
        try:
            self.header.from_lines(fh)
        except NotVcfHeaderError as e:
            raise NotAVCFError(path) from e

    chr2len = ContigsLength()
    if chr2len_path is not None:
        if chr2len.from_path(chr2len_path) == 0 and chr2len.from_vcf_header(self.header) == 0:
            raise NoContigsLengthInformationError
    elif chr2len.from_vcf_header(self.header) == 0:
        raise NoContigsLengthInformationError

    self.lf = polars.scan_csv(
        path,
        separator="\t",
        comment_prefix="#",
        has_header=False,
        schema_overrides=Vcf.schema(),
        new_columns=list(Vcf.schema().keys()),
    )

    schema = self.lf.collect_schema()
    self.lf = self.lf.rename(dict(zip(schema.names(), self.header.column_name(schema.len()))))
    self.lf = self.lf.cast(Vcf.schema())  # type: ignore # noqa: PGH003  polars 1.0 typing stuff

    if behavior & VcfParsingBehavior.MANAGE_SV:
        self.lf = self.lf.with_columns(self.header.info_parser({"SVTYPE", "SVLEN"}))

    if behavior & VcfParsingBehavior.KEEP_STAR:
        self.lf = self.lf.filter(polars.col("alt") != "*")

    self.lf = normalization.add_variant_id(self.lf, chr2len.lf)

    if behavior & VcfParsingBehavior.MANAGE_SV:
        self.lf = self.lf.drop("SVTYPE", "SVLEN", strict=False)

genotypes

genotypes(format_str: str = 'GT:AD:DP:GQ') -> Genotypes

Get genotype of vcf.

Source code in src/variantplaner/objects/vcf.py
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
def genotypes(self, format_str: str = "GT:AD:DP:GQ") -> Genotypes:
    """Get genotype of vcf."""
    schema = self.lf.collect_schema()

    if "format" not in schema.names():
        raise NoGenotypeError

    lf = self.lf.select([*schema.names()[schema.names().index("format") :]])
    schema = lf.collect_schema()

    # Clean bad variant
    lf = lf.filter(polars.col("format").str.starts_with(format_str)).select(*schema.names()[1:])

    # Found index of genotype value
    col_index = {
        key: index
        for (index, key) in enumerate(
            format_str.split(":"),
        )
    }

    # Pivot value
    genotypes = Genotypes()
    genotypes.lf = lf.unpivot(index=["id"]).with_columns(
        [
            polars.col("id"),
            polars.col("variable").alias("sample"),
            polars.col("value").str.split(":"),
        ],
    )

    # Split genotype column in sub value
    col2expr = self.header.format_parser()

    genotypes.lf = genotypes.lf.with_columns(
        [
            polars.col("value").list.get(index).pipe(function=col2expr[col], col_name=col)
            for col, index in col_index.items()
        ],
    )

    # Select intrusting column
    genotypes.lf = genotypes.lf.select(["id", "sample", *[col.lower() for col in col_index]])

    if "gt".upper() in col2expr:
        genotypes.lf = genotypes.lf.filter(polars.col("gt") != 0)

    return genotypes

schema classmethod

schema() -> Mapping[str, PolarsDataType]

Get schema of Vcf polars.LazyFrame.

Source code in src/variantplaner/objects/vcf.py
175
176
177
178
179
180
181
182
183
184
185
186
187
@classmethod
def schema(cls) -> collections.abc.Mapping[str, polars._typing.PolarsDataType]:
    """Get schema of Vcf polars.LazyFrame."""
    return {
        "chr": polars.String,
        "pos": polars.UInt64,
        "vid": polars.String,
        "ref": polars.String,
        "alt": polars.String,
        "qual": polars.String,
        "filter": polars.String,
        "info": polars.String,
    }

set_variants

set_variants(variants: Variants) -> None

Set variants of vcf.

Source code in src/variantplaner/objects/vcf.py
104
105
106
def set_variants(self, variants: Variants) -> None:
    """Set variants of vcf."""
    self.lf = variants.lf

variants

variants() -> Variants

Get variants of vcf.

Source code in src/variantplaner/objects/vcf.py
100
101
102
def variants(self) -> Variants:
    """Get variants of vcf."""
    return self.lf.select(Variants.minimal_schema())

VcfHeader

VcfHeader()

Object that parse and store vcf information.

Methods:

Attributes:

  • contigs (Iterator[str]) –

    Get an iterator of line contains chromosomes information.

  • samples_index (dict[str, int] | None) –

    Read vcf header to generate an association map between sample name and index.

Source code in src/variantplaner/objects/vcf_header.py
27
28
29
def __init__(self):
    """Initialise VcfHeader."""
    self._header = []

contigs cached property

contigs: Iterator[str]

Get an iterator of line contains chromosomes information.

Returns: String iterator

samples_index cached property

samples_index: dict[str, int] | None

Read vcf header to generate an association map between sample name and index.

Args: header: Header string.

Returns: Map that associate a sample name to is sample index.

Raises: NotVcfHeaderError: If all line not start by '#CHR'

column_name

column_name(
    number_of_column: int = MINIMAL_COL_NUMBER,
) -> Iterator[str]

Get an iterator of correct column name.

Returns: String iterator

Source code in src/variantplaner/objects/vcf_header.py
225
226
227
228
229
230
231
232
233
234
235
236
def column_name(self, number_of_column: int = MINIMAL_COL_NUMBER) -> typing.Iterator[str]:
    """Get an iterator of correct column name.

    Returns: String iterator
    """
    base_col_name = ["chr", "pos", "vid", "ref", "alt", "qual", "filter", "info"]

    yield from base_col_name

    if number_of_column > MINIMAL_COL_NUMBER and (samples := self.samples_index):
        yield "format"
        yield from (sample for (sample, _) in samples.items())

format_parser

format_parser(
    select_format: set[str] | None = None,
) -> dict[str, Callable[[Expr, str], Expr]]

Generate a list of polars.Expr to extract genotypes information.

Warning: Float values can't be converted for the moment they are stored as String to keep information

Args: header: Line of vcf header. input_path: Path to vcf file. select_format: List of target format field.

Returns: A dict to link format id to pipeable function with Polars.Expr

Raises: NotVcfHeaderError: If all line not start by '#CHR'

Source code in src/variantplaner/objects/vcf_header.py
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
def format_parser(
    self,
    select_format: set[str] | None = None,
) -> dict[str, typing.Callable[[polars.Expr, str], polars.Expr]]:
    """Generate a list of [polars.Expr](https://pola-rs.github.io/polars/py-polars/html/reference/expressions/index.html) to extract genotypes information.

    **Warning**: Float values can't be converted for the moment they are stored as String to keep information

    Args:
    header: Line of vcf header.
    input_path: Path to vcf file.
    select_format: List of target format field.

    Returns:
    A dict to link format id to pipeable function with Polars.Expr

    Raises:
    NotVcfHeaderError: If all line not start by '#CHR'
    """
    format_re = re.compile(
        "ID=(?P<id>[A-Za-z_][0-9A-Za-z_.]*),Number=(?P<number>[ARG0-9\\.]+),Type=(?P<type>Integer|Float|String|Character)",
    )

    expressions: dict[str, typing.Callable[[polars.Expr, str], polars.Expr]] = {}

    for line in self._header:
        if line.startswith("#CHROM"):
            return expressions

        if not line.startswith("##FORMAT"):
            continue

        if (search := format_re.search(line)) and (not select_format or search["id"] in select_format):
            name = search["id"]
            number = search["number"]
            format_type = search["type"]

            if name == "GT":
                expressions["GT"] = VcfHeader.__format_gt
                continue

            if number == "1":
                if format_type == "Integer":
                    expressions[name] = VcfHeader.__format_one_int
                elif format_type == "Float":  # noqa: SIM114 Float isn't already support but in future
                    expressions[name] = VcfHeader.__format_one_str
                elif format_type in {"String", "Character"}:
                    expressions[name] = VcfHeader.__format_one_str
                else:
                    pass  # Not reachable

            elif format_type == "Integer":
                expressions[name] = VcfHeader.__format_list_int
            elif format_type == "Float":  # noqa: SIM114 Float isn't already support but in future
                expressions[name] = VcfHeader.__format_list_str
            elif format_type in {"String", "Character"}:
                expressions[name] = VcfHeader.__format_list_str
            else:
                pass  # Not reachable

    raise NotVcfHeaderError

from_files

from_files(path: Path) -> None

Populate VcfHeader object with content of only header file.

Args: path: Path of file

Returns: None

Source code in src/variantplaner/objects/vcf_header.py
31
32
33
34
35
36
37
38
39
40
41
42
43
def from_files(self, path: pathlib.Path) -> None:
    """Populate VcfHeader object with content of only header file.

    Args:
    path: Path of file

    Returns:
    None
    """
    with open(path) as fh:
        for full_line in fh:
            line = full_line.strip()
            self._header.append(line)

from_lines

from_lines(lines: Iterator[str]) -> None

Extract all header information of vcf lines.

Line between start of file and first line start with '#CHROM' or not start with '#'

Args: lines: Iterator of line

Returns: None

Raises: NotAVcfHeader: If a line not starts with '#' NotAVcfHeader: If no line start by '#CHROM'

Source code in src/variantplaner/objects/vcf_header.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
def from_lines(self, lines: typing.Iterator[str]) -> None:
    """Extract all header information of vcf lines.

    Line between start of file and first line start with '#CHROM' or not start with '#'

    Args:
    lines: Iterator of line

    Returns: None

    Raises:
    NotAVcfHeader: If a line not starts with '#'
    NotAVcfHeader: If no line start by '#CHROM'
    """
    for full_line in lines:
        line = full_line.strip()

        if not line.startswith("#"):
            raise NotVcfHeaderError

        if line.startswith("#CHROM"):
            self._header.append(line)
            return

        self._header.append(line)

    raise NotVcfHeaderError

info_parser

info_parser(
    select_info: set[str] | None = None,
) -> list[Expr]

Generate a list of polars.Expr to extract variants information.

Args: header: Line of vcf header input_path: Path to vcf file. select_info: List of target info field

Returns: List of polars.Expr to parse info columns.

Raises: NotVcfHeaderError: If all line not start by '#CHR'

Source code in src/variantplaner/objects/vcf_header.py
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
def info_parser(self, select_info: set[str] | None = None) -> list[polars.Expr]:
    """Generate a list of [polars.Expr](https://pola-rs.github.io/polars/py-polars/html/reference/expressions/index.html) to extract variants information.

    Args:
    header: Line of vcf header
    input_path: Path to vcf file.
    select_info: List of target info field

    Returns:
    List of [polars.Expr](https://pola-rs.github.io/polars/py-polars/html/reference/expressions/index.html) to parse info columns.

    Raises:
    NotVcfHeaderError: If all line not start by '#CHR'
    """
    info_re = re.compile(
        r"ID=(?P<id>([A-Za-z_][0-9A-Za-z_.]*|1000G)),Number=(?P<number>[ARG0-9\.]+),Type=(?P<type>Integer|Float|String|Character)",
    )

    expressions: list[polars.Expr] = []

    for line in self._header:
        if line.startswith("#CHROM"):
            return expressions

        if not line.startswith("##INFO"):
            continue

        if (search := info_re.search(line)) and (not select_info or search["id"] in select_info):
            regex = rf"{search['id']}=([^;]+);?"

            local_expr = polars.col("info").str.extract(regex, 1)

            if search["number"] == "1":
                if search["type"] == "Integer":
                    local_expr = local_expr.cast(polars.Int64)
                elif search["type"] == "Float":
                    local_expr = local_expr.cast(polars.Float64)
                elif search["type"] in {"String", "Character"}:
                    pass  # Not do anything on string or character
                else:
                    pass  # Not reachable

            else:
                local_expr = local_expr.str.split(",")
                if search["type"] == "Integer":
                    local_expr = local_expr.cast(polars.List(polars.Int64))
                elif search["type"] == "Float":
                    local_expr = local_expr.cast(polars.List(polars.Float64))
                elif search["type"] in {"String", "Character"}:
                    pass  # Not do anything on string or character
                else:
                    pass  # Not reachable

            expressions.append(local_expr.alias(search["id"]))

    raise NotVcfHeaderError

VcfParsingBehavior

Bases: IntFlag

Enumeration use to control behavior of IntoLazyFrame.

Attributes:

  • KEEP_STAR

    Keep star variant.

  • MANAGE_SV

    into_lazyframe try to avoid structural variant id collision, SVTYPE/SVLEN info value must be present.

  • NOTHING

    into_lazyframe not have any specific behavior

KEEP_STAR class-attribute instance-attribute

KEEP_STAR = auto()

Keep star variant.

MANAGE_SV class-attribute instance-attribute

MANAGE_SV = auto()

into_lazyframe try to avoid structural variant id collision, SVTYPE/SVLEN info value must be present.

NOTHING class-attribute instance-attribute

NOTHING = auto()

into_lazyframe not have any specific behavior