Repository: wfondrie/mokapot

Issue:
ValueError: No decoy PSMs were detected.
I have loaded a file in the required format (these are the first few lines and the names of the columns). 
```
SpecId | Label | ScanNr | Peptide | Proteins
0 | 1 | 38422 | R.AEGSDVANAVLDGADC[Common Fixed:Carbamidomethy... | P14618
1 | 1 | 41542 | R.SNYLLNTTIAGVEEADVVLLVGTNPR.F | P28331
```
I am getting an error saying that there are no decoy PSMs, however, I know there are decoys. My label column has -1's in it. It loads the file in, but is not getting any further than that. I have looked through the documentation and can't seem to see what I could be missing. Any suggestions would be greatly appreciated. Thank you!

Here is the error that I am getting. 
```
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-bc18f4fefa97> in <module>
----> 1 psms = mokapot.read_pin(file)
      2 results, models = mokapot.brew(psms)
      3 results.to_txt()

~/anaconda3/lib/python3.8/site-packages/mokapot/parsers.py in read_pin(pin_files, group_column, to_df, copy_data)
    103         return pin_df
    104 
--> 105     return LinearPsmDataset(
    106         psms=pin_df,
    107         target_column=labels[0],

~/anaconda3/lib/python3.8/site-packages/mokapot/dataset.py in __init__(self, psms, target_column, spectrum_columns, peptide_column, protein_column, group_column, feature_columns, copy_data)
    427             raise ValueError("No target PSMs were detected.")
    428         if not num_decoys:
--> 429             raise ValueError("No decoy PSMs were detected.")
    430         if not self.data.shape[0]:
    431             raise ValueError("No PSMs were detected.")

ValueError: No decoy PSMs were detected.
```





Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 363da49..4bea464 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changelog for mokapot  
 
+## [Unreleased]
+### Fixed
+- Parsing Percolator tab-delimited files with a "DefaultDirection" line.
+- `Label` column is now converted to boolean during PIN file parsing. 
+  Previously, problems occurred if the `Label` column was of dtype `object`.
+
 ## [0.6.0] - 2021-03-03  
 ### Added  
 - Support for parsing PSMs from PepXML input files.
diff --git a/mokapot/parsers/pin.py b/mokapot/parsers/pin.py
index 65e8e30..69567cd 100644
--- a/mokapot/parsers/pin.py
+++ b/mokapot/parsers/pin.py
@@ -87,14 +87,17 @@ def read_pin(pin_files, group_column=None, to_df=False, copy_data=False):
             raise ValueError(f"More than one '{name}' column found.")
 
     if not all([specid, peptides, proteins, labels, spectra]):
+        print([specid, peptides, proteins, labels, spectra])
         raise ValueError(
             "This PIN format is incompatible with mokapot. Please"
             " verify that the required columns are present."
         )
 
     # Convert labels to the correct format.
+    print(pin_df[labels[0]])
+    pin_df[labels[0]] = pin_df[labels[0]].astype(int)
     if any(pin_df[labels[0]] == -1):
-        pin_df[labels[0]] = (pin_df[labels[0]] + 1) / 2
+        pin_df[labels[0]] = ((pin_df[labels[0]] + 1) / 2).astype(bool)
 
     if to_df:
         return pin_df
@@ -138,8 +141,14 @@ def read_percolator(perc_file):
 
     with fopen(perc_file) as perc:
         cols = perc.readline().rstrip().split("\t")
+        dir_line = perc.readline().rstrip().split("\t")[0]
+        if dir_line.lower() != "defaultdirection":
+            perc.seek(0)
+            _ = perc.readline()
+
         psms = pd.concat((c for c in _parse_in_chunks(perc, cols)), copy=False)
 
+    print(psms.head())
     return psms
 
 


Test patch:
diff --git a/tests/unit_tests/test_parser_pin.py b/tests/unit_tests/test_parser_pin.py
index e69de29..bae0fd3 100644
--- a/tests/unit_tests/test_parser_pin.py
+++ b/tests/unit_tests/test_parser_pin.py
@@ -0,0 +1,37 @@
+"""Test that parsing Percolator input files works correctly"""
+import pytest
+import mokapot
+import pandas as pd
+
+
+@pytest.fixture
+def std_pin(tmp_path):
+    """Create a standard pin file"""
+    out_file = tmp_path / "std_pin"
+    with open(str(out_file), "w+") as pin:
+        dat = (
+            "sPeCid\tLaBel\tpepTide\tsCore\tscanNR\tpRoteins\n"
+            "DefaultDirection\t-\t-\t-\t1\t-\t-\n"
+            "a\t1\tABC\t5\t2\tprotein1\tprotein2\n"
+            "b\t-1\tCBA\t10\t3\tdecoy_protein1\tdecoy_protein2"
+        )
+        pin.write(dat)
+
+    return out_file
+
+
+def test_pin_parsing(std_pin):
+    """Test pin parsing"""
+    df = mokapot.read_pin(std_pin, to_df=True)
+    assert df["LaBel"].dtype == "bool"
+    assert len(df) == 2
+    assert len(df[df["LaBel"]]) == 1
+    assert len(df[df["LaBel"]]) == 1
+
+    dat = mokapot.read_pin(std_pin)
+    pd.testing.assert_frame_equal(df.loc[:, ("sCore",)], dat.features)
+
+
+def test_pin_wo_dir():
+    """Test a PIN file without a DefaultDirection line"""
+    dat = mokapot.read_pin("data/scope2_FP97AA.pin")