diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..1c8c2fa2 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +# Set update schedule for GitHub Actions +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every week + interval: "monthly" diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 594cd6b7..56bb1feb 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -14,12 +14,12 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.12' - name: Install build dependencies run: | @@ -31,13 +31,13 @@ jobs: python -m build --wheel . - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Login to the GitHub Container Registry - uses: docker/login-action@v1 + uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} @@ -45,12 +45,12 @@ jobs: - name: Extract metadata for Docker id: meta - uses: docker/metadata-action@v3 + uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - name: Push the Docker image to the GHCR - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v6 with: context: . push: true diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0e958526..c912c250 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -10,11 +10,11 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Setup Python 3.10 - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - name: Setup Python 3.12 + uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install Ruff run: | @@ -24,3 +24,7 @@ jobs: - name: Lint/Check format with Ruff run: | ruff check . --output-format=github + + - name: Check formatting with Ruff + run: | + ruff format --check . diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 508669c3..fdceb7f1 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -9,11 +9,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.12' - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9dd98123..a2d5fb7a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -17,33 +17,27 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.9', '3.10', '3.11', '3.12'] + python-version: ['3.10', '3.11', '3.12'] os: [ubuntu-latest, windows-latest, macos-latest] experimental: [false,] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip - pip install flake8 pytest pytest-cov wheel + pip install pytest pytest-cov wheel pip install -e . - - name: Lint with flake8 - run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Run unit and system tests run: | pytest -v --cov=mokapot tests/ - name: Upload coverage to codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: true diff --git a/mokapot/confidence.py b/mokapot/confidence.py index 7fc9f848..8a3e30a2 100644 --- a/mokapot/confidence.py +++ b/mokapot/confidence.py @@ -488,7 +488,7 @@ def assign_confidence( psms: list[OnDiskPsmDataset], max_workers, scores=None, - descs: list[bool] | None=None, + descs: list[bool] | None = None, eval_fdr=0.01, dest_dir: Path | None = None, file_root: str = "", diff --git a/mokapot/config.py b/mokapot/config.py index cecfe5b2..07890773 100644 --- a/mokapot/config.py +++ b/mokapot/config.py @@ -76,7 +76,9 @@ def _parser(): "--verify_pin", type=bool, default=True, - help="Verify that PIN input files are valid TSVs. If not convert them.", + help=( + "Verify that PIN input files are valid TSVs. If not convert them." + ), ) parser.add_argument( @@ -399,8 +401,8 @@ def _parser(): default=None, type=Path, help="Optionally, sets a path to an MSAID sqlite result database " - "for writing outputs to. If not set (None), results are " - "written in the standard TSV format.", + "for writing outputs to. If not set (None), results are " + "written in the standard TSV format.", ) return parser diff --git a/mokapot/mokapot.py b/mokapot/mokapot.py index c7647a64..db0fff9f 100644 --- a/mokapot/mokapot.py +++ b/mokapot/mokapot.py @@ -62,13 +62,13 @@ def main(main_args=None): logging.info("=================") if config.verify_pin: for path_pin in config.psm_files: - with open(path_pin, 'r') as f_pin: + with open(path_pin, "r") as f_pin: valid_tsv = is_valid_tsv(f_pin) if not valid_tsv: logging.info(f"{path_pin} invalid tsv, converting") path_tsv = f"{path_pin}.tsv" - with open(path_pin, 'r') as f_pin: - with open(path_tsv, 'a') as f_tsv: + with open(path_pin, "r") as f_pin: + with open(path_tsv, "a") as f_tsv: pin_to_valid_tsv(f_in=f_pin, f_out=f_tsv) shutil.move(path_tsv, path_pin) diff --git a/mokapot/parsers/pin_to_tsv.py b/mokapot/parsers/pin_to_tsv.py index cdf14a29..7d8d18ad 100644 --- a/mokapot/parsers/pin_to_tsv.py +++ b/mokapot/parsers/pin_to_tsv.py @@ -1,39 +1,27 @@ +"""Parse PIN files.""" + from pathlib import Path -from io import StringIO from typing import TextIO -from unittest.mock import Mock import argparse + # PIN file specification from # https://github.com/percolator/percolator/wiki/Interface#tab-delimited-file-format -""" -PSMId Label ScanNr feature1name ... featureNname Peptide Proteins -DefaultDirection - - feature1weight ... featureNweight [optional] -""" - -EXAMPLE_PIN = """SpecId\tLabel\tScanNr\tExpMass\tPeptide\tProteins -target_0_16619_2_-1\t1\t16619\t750.4149\tK.SEFLVR.E\tsp|Q96QR8|PURB_HUMAN\tsp|Q00577|PURA_HUMAN -target_0_2025_2_-1\t1\t2025\t751.4212\tR.HTALGPR.S\tsp|Q9Y4H4|GPSM3_HUMAN""" -EXAMPLE_HEADER, EXAMPLE_LINE_1, EXAMPLE_LINE_2 = EXAMPLE_PIN.split('\n') - -PIN_SEP = '\t' - - def parse_pin_header_columns( - header: str, - sep_column: str = PIN_SEP, - + header: str, + sep_column: str = "\t", ) -> (int, int): - """ - Parse the header of a PIN file to get the number of columns and the index of the - Proteins column. + """Parse the PIN file header. + + Parse the header of a PIN file to get the number of columns and the + index of the Proteins column. Parameters ---------- header : str The header line from the PIN file. sep_column : str, optional - Column separator (default is PIN_SEP). + Column separator. Returns ------- @@ -42,11 +30,6 @@ def parse_pin_header_columns( idx_protein_col : int The index of the 'Proteins' column. - Examples - -------- - >>> n_col, idx_protein_col = parse_pin_header_columns(EXAMPLE_HEADER) - >>> n_col, idx_protein_col - (6, 5) """ columns = header.strip().split(sep_column) assert "Proteins" in columns @@ -56,11 +39,11 @@ def parse_pin_header_columns( def convert_line_pin_to_tsv( - line: str, - idx_protein_col: int, - n_col: int, - sep_column: str = "\t", - sep_protein: str = ":" + line: str, + idx_protein_col: int, + n_col: int, + sep_column: str = "\t", + sep_protein: str = ":", ): """ Convert a single line from a PIN file format to a TSV format. @@ -72,7 +55,8 @@ def convert_line_pin_to_tsv( idx_protein_col : int The index of the first protein column. n_col : int - The total number of columns in the PIN file (excluding additional protein columns). + The total number of columns in the PIN file (excluding additional + protein columns). sep_column : str, optional The separator used between columns (default is "\t"). sep_protein : str, optional @@ -82,33 +66,25 @@ def convert_line_pin_to_tsv( ------- str The converted line in TSV format. - - Examples - -------- - >>> header = EXAMPLE_HEADER - >>> n_col, idx_protein_col = parse_pin_header_columns(header) - >>> tsv_line = convert_line_pin_to_tsv(EXAMPLE_LINE_1, n_col=n_col, idx_protein_col=idx_protein_col) - >>> tsv_line.expandtabs(4) # needed for docstring to work - 'target_0_16619_2_-1 1 16619 750.4149 K.SEFLVR.E sp|Q96QR8|PURB_HUMAN:sp|Q00577|PURA_HUMAN' - >>> tsv_line = convert_line_pin_to_tsv(EXAMPLE_LINE_2, n_col=n_col, idx_protein_col=idx_protein_col) - >>> tsv_line.expandtabs(4) # needed for docstring to work - 'target_0_2025_2_-1 1 2025 751.4212 R.HTALGPR.S sp|Q9Y4H4|GPSM3_HUMAN' """ elements = line.split(sep=sep_column) # this contains columns and proteins n_proteins = len(elements) - n_col idx_prot_start = idx_protein_col idx_prot_end = idx_protein_col + n_proteins + 1 proteins: str = sep_protein.join(elements[idx_prot_start:idx_prot_end]) - columns: list = elements[:idx_prot_start] + [proteins] + elements[idx_prot_end:] + columns: list = ( + elements[:idx_prot_start] + [proteins] + elements[idx_prot_end:] + ) tsv_line: str = sep_column.join(columns) return tsv_line def is_valid_tsv( - f_in: TextIO, - sep_column: str = PIN_SEP + f_in: TextIO, + sep_column: str = "\t", ) -> bool: - """ + """Verify that a file is a valid TSV. + This function verifies that: 1. All rows have the same number of columns as the header row. 2. The file does not contain a "DefaultDirection" line as the second line. @@ -116,10 +92,10 @@ def is_valid_tsv( Parameters ---------- f_in : TextIO - Input file object to read from. This should be an opened file or file-like - object that supports iteration. + Input file object to read from. This should be an opened file or + file-like bject that supports iteration. sep_column : str, optional - Column separator (default is PIN_SEP, which is assumed to be a tab character). + Column separator Returns ------- @@ -127,11 +103,6 @@ def is_valid_tsv( True if the file is a valid TSV according to the specified criteria, False otherwise. - Examples - -------- - >>> input = StringIO(EXAMPLE_PIN) - >>> is_valid_tsv(input) - False """ n_col_header = len(next(f_in).split(sep_column)) line_2 = next(f_in) @@ -152,17 +123,13 @@ def is_valid_tsv( def pin_to_valid_tsv( - f_in: TextIO, - f_out: TextIO, - sep_column: str = PIN_SEP, - sep_protein: str = ":" + f_in: TextIO, f_out: TextIO, sep_column: str = "\t", sep_protein: str = ":" ) -> None: - """ - Convert a PIN file to a valid TSV file. + """Convert a PIN file to a valid TSV file. This assumes that the input file is in PIN format and that the first line - is a header. It preserves the header in the output file and ignores the second line - if it starts with "DefaultDirection". + is a header. It preserves the header in the output file and ignores the + second line if it starts with "DefaultDirection". Parameters ---------- @@ -178,16 +145,6 @@ def pin_to_valid_tsv( Returns ------- None - - Examples - -------- - >>> mock_input = StringIO(EXAMPLE_PIN) - >>> mock_output = Mock() - >>> mock_output.write = Mock() - >>> pin_to_valid_tsv(mock_input, mock_output) - >>> mock_output.write.call_count - 3 - >>> mock_output.write.assert_any_call(EXAMPLE_HEADER + "\\n") """ header: str = next(f_in).strip() f_out.write(header + "\n") @@ -204,7 +161,7 @@ def pin_to_valid_tsv( n_col=n_col, idx_protein_col=idx_protein_col, sep_column=sep_column, - sep_protein=sep_protein + sep_protein=sep_protein, ) f_out.write(tsv_line + "\n") @@ -215,27 +172,37 @@ def pin_to_valid_tsv( n_col=n_col, idx_protein_col=idx_protein_col, sep_column=sep_column, - sep_protein=sep_protein + sep_protein=sep_protein, ) f_out.write(tsv_line + "\n") def main(): - parser = argparse.ArgumentParser(description="Convert PIN file to valid TSV") + parser = argparse.ArgumentParser( + description="Convert PIN file to valid TSV" + ) parser.add_argument("path_in", type=Path, help="Input PIN file path") parser.add_argument("path_out", type=Path, help="Output TSV file path") - parser.add_argument("--sep_column", type=str, default="\t", - help="Column separator (default: '\\t')") - parser.add_argument("--sep_protein", type=str, default=":", - help="Protein separator (default: ':')") + parser.add_argument( + "--sep_column", + type=str, + default="\t", + help="Column separator (default: '\\t')", + ) + parser.add_argument( + "--sep_protein", + type=str, + default=":", + help="Protein separator (default: ':')", + ) args = parser.parse_args() - with open(args.path_in, 'r') as f_in: - with open(args.path_out, 'a') as f_out: + with open(args.path_in, "r") as f_in: + with open(args.path_out, "a") as f_out: pin_to_valid_tsv( f_in=f_in, f_out=f_out, sep_column=args.sep_column, - sep_protein=args.sep_protein + sep_protein=args.sep_protein, ) diff --git a/mokapot/streaming.py b/mokapot/streaming.py index b2fdcae8..1b64cada 100644 --- a/mokapot/streaming.py +++ b/mokapot/streaming.py @@ -2,7 +2,6 @@ Helper classes and methods used for streaming of tabular data. """ - from __future__ import annotations from typing import Generator, Callable, Iterator @@ -26,6 +25,7 @@ class JoinedTabularDataReader(TabularDataReader): A list of 'TabularDataReader' objects representing the individual data sources. """ + readers: list[TabularDataReader] def __init__(self, readers: list[TabularDataReader]): @@ -173,6 +173,7 @@ class MergedTabularDataReader(TabularDataReader): column_types : list List of column types for the merged data. """ + def __init__( self, readers: list[TabularDataReader], diff --git a/mokapot/tabular_data.py b/mokapot/tabular_data.py index 5ced7452..287baeb2 100644 --- a/mokapot/tabular_data.py +++ b/mokapot/tabular_data.py @@ -60,6 +60,7 @@ class TabularDataReader(ABC): (e.g. data frames), combine or modify other readers or represent computed tabular results. """ + @abstractmethod def get_column_names(self) -> list[str]: raise NotImplementedError @@ -121,6 +122,7 @@ class ColumnMappedReader(TabularDataReader): A dictionary that maps the original column names to the new column names. """ + def __init__(self, reader: TabularDataReader, column_map: dict[str, str]): self.reader = reader self.column_map = column_map @@ -186,6 +188,7 @@ class CSVFileReader(TabularDataReader): Arguments for reading CSV file passed on to the pandas `read_csv` function. """ + def __init__(self, file_name: Path, sep: str = "\t"): self.file_name = file_name self.stdargs = {"sep": sep, "index_col": False} @@ -231,6 +234,7 @@ class DataFrameReader(TabularDataReader): df : pd.DataFrame The DataFrame being read from. """ + df: pd.DataFrame def __init__(self, df: pd.DataFrame): @@ -328,6 +332,7 @@ class TabularDataWriter(ABC): column_types : list | None List of column types (optional) """ + def __init__( self, columns: list[str], @@ -455,6 +460,7 @@ class BufferedWriter(TabularDataWriter): The buffer containing the tabular data to be written. The buffer type depends on the buffer_type attribute. """ + writer: TabularDataWriter buffer_size: int buffer_type: TableType @@ -561,6 +567,7 @@ class CSVFileWriter(TabularDataWriter): The separator string used to separate fields in the CSV file. Default is tab character ("\t"). """ + file_name: Path def __init__( @@ -616,6 +623,7 @@ class ParquetFileWriter(TabularDataWriter): file_name : Path The path to the Parquet file being written. """ + file_name: Path def __init__( @@ -667,6 +675,7 @@ class SqliteWriter(TabularDataWriter, ABC): """ SqliteWriter class for writing tabular data to SQLite database. """ + connection: sqlite3.Connection def __init__( diff --git a/tests/conftest.py b/tests/conftest.py index de74f4ce..1247d618 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -125,14 +125,18 @@ def psm_df_1000(tmp_path): "expmass": rng.uniform(500, 2000, size=500), "peptide": [_random_peptide(5, rng) for _ in range(500)], "proteins": ["_dummy" for _ in range(500)], - "score": np.concatenate([ - rng.normal(3, size=200), - rng.normal(size=300), - ]), - "score2": np.concatenate([ - rng.normal(3, size=200), - rng.normal(size=300), - ]), + "score": np.concatenate( + [ + rng.normal(3, size=200), + rng.normal(size=300), + ] + ), + "score2": np.concatenate( + [ + rng.normal(3, size=200), + rng.normal(size=300), + ] + ), "filename": "test.mzML", "ret_time": rng.uniform(0, 60 * 120, size=500), "charge": rng.choice([2, 3, 4], size=500), @@ -180,14 +184,18 @@ def psm_df_1000_parquet(tmp_path): "expmass": rng.uniform(500, 2000, size=500), "peptide": [_random_peptide(5, rng) for _ in range(500)], "proteins": ["_dummy" for _ in range(500)], - "score": np.concatenate([ - rng.normal(3, size=200), - rng.normal(size=300), - ]), - "score2": np.concatenate([ - rng.normal(3, size=200), - rng.normal(size=300), - ]), + "score": np.concatenate( + [ + rng.normal(3, size=200), + rng.normal(size=300), + ] + ), + "score2": np.concatenate( + [ + rng.normal(3, size=200), + rng.normal(size=300), + ] + ), "filename": "test.mzML", "ret_time": rng.uniform(0, 60 * 120, size=500), "charge": rng.choice([2, 3, 4], size=500), @@ -369,36 +377,44 @@ def psm_files_4000(tmp_path): decoy_scores2 = np.random.normal(size=n, loc=4, scale=3) decoy_scores3 = np.random.normal(size=n, loc=12, scale=4) targets = pd.DataFrame( - np.array([ - np.ones(n), - target_scores1, - target_scores2, - target_scores3, - ]).transpose(), + np.array( + [ + np.ones(n), + target_scores1, + target_scores2, + target_scores3, + ] + ).transpose(), columns=["Label", "feature1", "feature2", "feature3"], ) decoys = pd.DataFrame( - np.array([ - -np.ones(n), - decoy_scores1, - decoy_scores2, - decoy_scores3, - ]).transpose(), + np.array( + [ + -np.ones(n), + decoy_scores1, + decoy_scores2, + decoy_scores3, + ] + ).transpose(), columns=["Label", "feature1", "feature2", "feature3"], ) psms_df = pd.concat([targets, decoys]).reset_index(drop=True) NC = len(psms_df) psms_df["ScanNr"] = np.random.randint(1, NC // 2 + 1, NC) - expmass = np.hstack([ - np.random.uniform(50, 500, NC // 2), - np.random.uniform(50, 500, NC // 2), - ]) + expmass = np.hstack( + [ + np.random.uniform(50, 500, NC // 2), + np.random.uniform(50, 500, NC // 2), + ] + ) expmass.sort() psms_df["ExpMass"] = expmass - peptides = np.hstack([ - np.arange(1, NC // 2 + 1), - np.arange(1, NC // 2 + 1), - ]) + peptides = np.hstack( + [ + np.arange(1, NC // 2 + 1), + np.arange(1, NC // 2 + 1), + ] + ) peptides.sort() psms_df["Peptide"] = peptides psms_df["Proteins"] = "dummy" @@ -542,15 +558,17 @@ def __init__(self): self._proteins = None self._has_proteins = False - self.peptides = pd.DataFrame({ - "filename": "a/b/c.mzML", - "calcmass": [1, 2], - "ret_time": [60, 120], - "charge": [2, 3], - "peptide": ["B.ABCD[+2.817]XYZ.A", "ABCDE(shcah8)FG"], - "mokapot q-value": [0.001, 0.1], - "protein": ["A|B|C\tB|C|A", "A|B|C"], - }) + self.peptides = pd.DataFrame( + { + "filename": "a/b/c.mzML", + "calcmass": [1, 2], + "ret_time": [60, 120], + "charge": [2, 3], + "peptide": ["B.ABCD[+2.817]XYZ.A", "ABCDE(shcah8)FG"], + "mokapot q-value": [0.001, 0.1], + "protein": ["A|B|C\tB|C|A", "A|B|C"], + } + ) self.confidence_estimates = {"peptides": self.peptides} self.decoy_confidence_estimates = {"peptides": self.peptides} diff --git a/tests/system_tests/test_cli.py b/tests/system_tests/test_cli.py index 9be78681..c0a852cc 100644 --- a/tests/system_tests/test_cli.py +++ b/tests/system_tests/test_cli.py @@ -69,7 +69,6 @@ def test_basic_cli(tmp_path, scope_files): assert targets_psms_df.iloc[0, 5] == "sp|P10809|CH60_HUMAN" - def test_cli_options(tmp_path, scope_files): """Test non-defaults""" params = [ diff --git a/tests/unit_tests/test_confidence.py b/tests/unit_tests/test_confidence.py index df3ef7c9..48651eb7 100644 --- a/tests/unit_tests/test_confidence.py +++ b/tests/unit_tests/test_confidence.py @@ -178,7 +178,7 @@ def test_assign_confidence_parquet(psm_df_1000_parquet, tmp_path): assign_confidence( [copy.copy(psms_disk)], prefixes=[None], - descs=None, # should default to [True] as in the first case + descs=None, # should default to [True] as in the first case dest_dir=tmp_path, max_workers=4, eval_fdr=0.02, diff --git a/tests/unit_tests/test_parser_parquet.py b/tests/unit_tests/test_parser_parquet.py index 98bbcd14..2b1d1ea8 100644 --- a/tests/unit_tests/test_parser_parquet.py +++ b/tests/unit_tests/test_parser_parquet.py @@ -10,32 +10,34 @@ def std_parquet(tmp_path): """Create a standard pin file""" out_file = tmp_path / "std_pin.parquet" - df = pd.DataFrame([ - { - "sPeCid": "DefaultDirection", - "LaBel": "0", - "pepTide": "-", - "sCore": "-", - "scanNR": "1", - "pRoteins": "-", - }, - { - "sPeCid": "a", - "LaBel": "1", - "pepTide": "ABC", - "sCore": "5", - "scanNR": "2", - "pRoteins": "protein1", - }, - { - "sPeCid": "b", - "LaBel": "-1", - "pepTide": "CBA", - "sCore": "10", - "scanNR": "3", - "pRoteins": "decoy_protein1", - }, - ]) + df = pd.DataFrame( + [ + { + "sPeCid": "DefaultDirection", + "LaBel": "0", + "pepTide": "-", + "sCore": "-", + "scanNR": "1", + "pRoteins": "-", + }, + { + "sPeCid": "a", + "LaBel": "1", + "pepTide": "ABC", + "sCore": "5", + "scanNR": "2", + "pRoteins": "protein1", + }, + { + "sPeCid": "b", + "LaBel": "-1", + "pepTide": "CBA", + "sCore": "10", + "scanNR": "3", + "pRoteins": "decoy_protein1", + }, + ] + ) df.to_parquet(out_file, index=False) return out_file diff --git a/tests/unit_tests/test_streaming.py b/tests/unit_tests/test_streaming.py index 21bebe04..bf5cc1f8 100644 --- a/tests/unit_tests/test_streaming.py +++ b/tests/unit_tests/test_streaming.py @@ -15,14 +15,18 @@ @pytest.fixture def readers_to_merge(): # Prepare two dataframe readers - df1 = pd.DataFrame({ - "foo": [1, 3, 4, 5, 8, 10], - "bar": [20, 6, 3, 2, 1, 0], - }) - df2 = pd.DataFrame({ - "foo": [2, 2, 6, 9, 11, 13, 15], - "bar": [18, 16, 13, 6, 5, 5, 0], - }) + df1 = pd.DataFrame( + { + "foo": [1, 3, 4, 5, 8, 10], + "bar": [20, 6, 3, 2, 1, 0], + } + ) + df2 = pd.DataFrame( + { + "foo": [2, 2, 6, 9, 11, 13, 15], + "bar": [18, 16, 13, 6, 5, 5, 0], + } + ) reader1 = DataFrameReader(df1) reader2 = DataFrameReader(df2) return [reader1, reader2] @@ -31,14 +35,18 @@ def readers_to_merge(): @pytest.fixture def readers_to_join(): # Prepare two dataframe readers - df1 = pd.DataFrame({ - "foo": [1, 3, 4, 5, 8, 10], - "bar": [20, 6, 3, 2, 1, 0], - }) - df2 = pd.DataFrame({ - "baz": [11, 13, 14, 15, 18, 110], - "quux": [220, 26, 23, 22, 21, 20], - }) + df1 = pd.DataFrame( + { + "foo": [1, 3, 4, 5, 8, 10], + "bar": [20, 6, 3, 2, 1, 0], + } + ) + df2 = pd.DataFrame( + { + "baz": [11, 13, 14, 15, 18, 110], + "quux": [220, 26, 23, 22, 21, 20], + } + ) reader1 = DataFrameReader(df1) reader2 = DataFrameReader(df2) return [reader1, reader2] @@ -51,10 +59,12 @@ def test_merged_tabular_data_reader(readers_to_merge): ) pd.testing.assert_frame_equal( reader.read(), - pd.DataFrame({ - "foo": [1, 2, 2, 3, 4, 5, 6, 8, 9, 10, 11, 13, 15], - "bar": [20, 18, 16, 6, 3, 2, 13, 1, 6, 0, 5, 5, 0], - }), + pd.DataFrame( + { + "foo": [1, 2, 2, 3, 4, 5, 6, 8, 9, 10, 11, 13, 15], + "bar": [20, 18, 16, 6, 3, 2, 13, 1, 6, 0, 5, 5, 0], + } + ), ) # Check that chunked read works diff --git a/tests/unit_tests/test_tabular_data.py b/tests/unit_tests/test_tabular_data.py index c8b806ab..f134d941 100644 --- a/tests/unit_tests/test_tabular_data.py +++ b/tests/unit_tests/test_tabular_data.py @@ -187,12 +187,10 @@ def test_dataframe_reader(psm_df_6): ) reader = DataFrameReader.from_array( - np.array([1, 2, 3], - dtype=np.int32), name="test" + np.array([1, 2, 3], dtype=np.int32), name="test" ) pd.testing.assert_frame_equal( - reader.read(), - pd.DataFrame({"test": [1, 2, 3]}, dtype=np.int32) + reader.read(), pd.DataFrame({"test": [1, 2, 3]}, dtype=np.int32) ) @@ -219,13 +217,15 @@ def test_column_renaming(psm_df_6): assert (reader.read().values == orig_reader.read().values).all() assert ( - reader.read(["Pep", "protein", "T", "feature_1"]).values - == orig_reader.read([ - "peptide", - "protein", - "target", - "feature_1", - ]).values + reader.read(["Pep", "protein", "T", "feature_1"]).values + == orig_reader.read( + [ + "peptide", + "protein", + "target", + "feature_1", + ] + ).values ).all() renamed_chunk = next( diff --git a/tests/unit_tests/test_writer_flashlfq.py b/tests/unit_tests/test_writer_flashlfq.py index 37663005..420e8b68 100644 --- a/tests/unit_tests/test_writer_flashlfq.py +++ b/tests/unit_tests/test_writer_flashlfq.py @@ -29,15 +29,17 @@ def test_basic(mock_conf, tmp_path): """Test that the basic output works""" conf = mock_conf df = pd.read_table(mokapot.to_flashlfq(conf, tmp_path / "test.txt")) - expected = pd.DataFrame({ - "File Name": ["c.mzML"] * 2, - "Base Sequence": ["ABCDXYZ", "ABCDEFG"], - "Full Sequence": ["B.ABCD[+2.817]XYZ.A", "ABCDE(shcah8)FG"], - "Peptide Monoisotopic Mass": [1, 2], - "Scan Retention Time": [1.0, 2.0], - "Precursor Charge": [2, 3], - "Protein Accession": ["A|B|C; B|C|A", "A|B|C"], - }) + expected = pd.DataFrame( + { + "File Name": ["c.mzML"] * 2, + "Base Sequence": ["ABCDXYZ", "ABCDEFG"], + "Full Sequence": ["B.ABCD[+2.817]XYZ.A", "ABCDE(shcah8)FG"], + "Peptide Monoisotopic Mass": [1, 2], + "Scan Retention Time": [1.0, 2.0], + "Precursor Charge": [2, 3], + "Protein Accession": ["A|B|C; B|C|A", "A|B|C"], + } + ) pd.testing.assert_frame_equal(df, expected)