Repository: Sage-Bionetworks/Genie

Issue:
Add validation check for SAMPLE_ID
cBioPortal file imports have an undocumented character limit of 50 for SAMPLE_IDs.  This caused issues with the 12.2-consortium release with one site's IDs.  

Discussion:
thomasyu888: @hhunterzinck This can be reviewed, but do not merge yet.  We will wait until after the public release to merge
thomasyu888: @hhunterzinck make sure to set the correct --project_id. It defaults to main genie project id, but if you provide the test genie project id, sage will be included
thomasyu888: Thanks for the review. This is another PR that should be merged after the public release
thomasyu888: Use _validate_genie function for structural variants

Patch:
diff --git a/genie/process_functions.py b/genie/process_functions.py
index 033e1ec..fed9e3b 100644
--- a/genie/process_functions.py
+++ b/genie/process_functions.py
@@ -174,6 +174,32 @@ def checkColExist(DF, key):
     return result
 
 
+def validate_genie_identifier(
+    identifiers: pd.Series, center: str, filename: str, col: str
+) -> str:
+    """Validate GENIE sample and patient ids.
+
+    Args:
+        identifiers (pd.Series): Array of GENIE identifiers
+        center (str): GENIE center name
+        filename (str): name of file
+        col (str): Column with identifiers
+
+    return:
+        str: Errors
+    """
+    total_error = ""
+    if not all(identifiers.str.startswith(f"GENIE-{center}")):
+        total_error = total_error + (
+            f"{filename}: {col} must start with GENIE-{center}\n"
+        )
+    if any(identifiers.str.len() >= 50):
+        total_error = total_error + (
+            f"{filename}: {col} must have less than 50 characters.\n"
+        )
+    return total_error
+
+
 # def get_oncotree_codes(oncotree_url):
 #     '''
 #     Deprecated
diff --git a/genie/process_mutation.py b/genie/process_mutation.py
index 6bb209f..047f229 100644
--- a/genie/process_mutation.py
+++ b/genie/process_mutation.py
@@ -326,10 +326,10 @@ def format_maf(mafdf: pd.DataFrame, center: str) -> pd.DataFrame:
     Returns:
         Formatted mutation dataframe"""
     mafdf["Center"] = center
+    # Leaving here for safe guarding.
     mafdf["Tumor_Sample_Barcode"] = [
         process_functions.checkGenieId(i, center) for i in mafdf["Tumor_Sample_Barcode"]
     ]
-
     mafdf["Sequence_Source"] = float("nan")
     mafdf["Sequencer"] = float("nan")
     mafdf["Validation_Status"][
diff --git a/genie_registry/clinical.py b/genie_registry/clinical.py
index 3268ecd..64c36d7 100644
--- a/genie_registry/clinical.py
+++ b/genie_registry/clinical.py
@@ -262,11 +262,6 @@ class Clinical(FileTypeFormat):
         """Transform the values of each row of the clinical file"""
         # Must create copy or else it will overwrite the original row
         x = row.copy()
-        # # PATIENT ID
-        if x.get("PATIENT_ID") is not None:
-            x["PATIENT_ID"] = process_functions.checkGenieId(
-                x["PATIENT_ID"], self.center
-            )
 
         # BIRTH YEAR
         if x.get("BIRTH_YEAR") is not None:
@@ -274,10 +269,6 @@ class Clinical(FileTypeFormat):
             if process_functions.checkInt(x["BIRTH_YEAR"]):
                 x["BIRTH_YEAR"] = int(x["BIRTH_YEAR"])
 
-        # SAMPLE ID
-        if x.get("SAMPLE_ID") is not None:
-            x["SAMPLE_ID"] = process_functions.checkGenieId(x["SAMPLE_ID"], self.center)
-
         # AGE AT SEQ REPORT
         if x.get("AGE_AT_SEQ_REPORT") is not None:
             if process_functions.checkInt(x["AGE_AT_SEQ_REPORT"]):
@@ -531,6 +522,14 @@ class Clinical(FileTypeFormat):
                     "uploaded, then please check to make sure no duplicated "
                     "PATIENT_IDs exist in the patient clinical file.\n"
                 )
+            error = process_functions.validate_genie_identifier(
+                identifiers=clinicaldf[sample_id],
+                center=self.center,
+                filename="Sample Clinical File",
+                col="SAMPLE_ID",
+            )
+            total_error.write(error)
+
         # CHECK: PATIENT_ID
         patientId = "PATIENT_ID"
         # #CHECK: PATIENT_ID IN SAMPLE FILE
@@ -538,7 +537,17 @@ class Clinical(FileTypeFormat):
 
         if not havePatientColumn:
             total_error.write("Patient Clinical File: Must have PATIENT_ID column.\n")
-
+        else:
+            if not all(clinicaldf[patientId].str.startswith(f"GENIE-{self.center}")):
+                total_error.write(
+                    "Patient Clinical File: "
+                    f"PATIENT_ID must start with GENIE-{self.center}\n"
+                )
+            if any(clinicaldf[patientId].str.len() >= 50):
+                total_error.write(
+                    "Patient Clinical File: PATIENT_ID must have less than "
+                    "50 characters.\n"
+                )
         # CHECK: within the sample file that the sample ids match
         # the patient ids
         if haveSampleColumn and havePatientColumn:
diff --git a/genie_registry/cna.py b/genie_registry/cna.py
index 39347e6..82777f8 100644
--- a/genie_registry/cna.py
+++ b/genie_registry/cna.py
@@ -136,11 +136,6 @@ class cna(FileTypeFormat):
         cnaDf.drop_duplicates("Hugo_Symbol", keep=False, inplace=True)
         cnaDf = pd.concat([cnaDf, duplicatedGenes], sort=False)
         cnaDf = cnaDf[order]
-        cnaDf.columns = [
-            process_functions.checkGenieId(i, self.center) if i != "Hugo_Symbol" else i
-            for i in cnaDf.columns
-        ]
-
         return cnaDf
 
     def process_steps(self, cnaDf, newPath):
@@ -177,7 +172,10 @@ class cna(FileTypeFormat):
 
         if process_functions.checkColExist(cnvDF, "ENTREZ_GENE_ID"):
             del cnvDF["ENTREZ_GENE_ID"]
-
+        error = process_functions.validate_genie_identifier(
+            identifiers=cnvDF.columns, center=self.center, filename="cnv", col="samples"
+        )
+        total_error += error
         # cnvDF = cnvDF.fillna('')
         allowed_values = [
             "-2.0",
diff --git a/genie_registry/fusions.py b/genie_registry/fusions.py
index abcb258..5ec30a8 100644
--- a/genie_registry/fusions.py
+++ b/genie_registry/fusions.py
@@ -64,11 +64,6 @@ class fusions(FileTypeFormat):
     def _process(self, fusion):
         fusion.columns = [col.upper() for col in fusion.columns]
         fusion["CENTER"] = self.center
-        newsamples = [
-            process_functions.checkGenieId(i, self.center)
-            for i in fusion["TUMOR_SAMPLE_BARCODE"]
-        ]
-        fusion["TUMOR_SAMPLE_BARCODE"] = newsamples
 
         # This is temporary, because comments column will be removed
         # if fusion.get("COMMENTS") is None:
@@ -157,6 +152,14 @@ class fusions(FileTypeFormat):
                 )
             # fusionDF = fusionDF.drop_duplicates("HUGO_SYMBOL").apply(lambda x: validateSymbol(x, bedDf), axis=1)
 
+        if process_functions.checkColExist(fusionDF, "TUMOR_SAMPLE_BARCODE"):
+            error = process_functions.validate_genie_identifier(
+                identifiers=fusionDF["TUMOR_SAMPLE_BARCODE"],
+                center=self.center,
+                filename="fusion",
+                col="TUMOR_SAMPLE_BARCODE",
+            )
+            total_error += error
         # if process_functions.checkColExist(fusionDF, "DNA_SUPPORT"):
         #     if not fusionDF.DNA_SUPPORT.isin(["yes","no","unknown"]).all():
         #         total_error += "Your fusion file's DNA_SUPPORT column must be 'yes', 'no', or 'unknown'"
diff --git a/genie_registry/maf.py b/genie_registry/maf.py
index 714233a..a25cc36 100644
--- a/genie_registry/maf.py
+++ b/genie_registry/maf.py
@@ -261,6 +261,15 @@ class maf(FileTypeFormat):
         error = _check_tsa1_tsa2(mutationDF)
         total_error.write(error)
 
+        if process_functions.checkColExist(mutationDF, "TUMOR_SAMPLE_BARCODE"):
+            error = process_functions.validate_genie_identifier(
+                identifiers=mutationDF["TUMOR_SAMPLE_BARCODE"],
+                center=self.center,
+                filename="maf",
+                col="TUMOR_SAMPLE_BARCODE",
+            )
+            total_error.write(error)
+
         return total_error.getvalue(), warning.getvalue()
 
     def _get_dataframe(self, filePathList):
diff --git a/genie_registry/mutationsInCis.py b/genie_registry/mutationsInCis.py
index a7ef110..313b3aa 100644
--- a/genie_registry/mutationsInCis.py
+++ b/genie_registry/mutationsInCis.py
@@ -101,4 +101,14 @@ class mutationsInCis(FileTypeFormat):
                     "mutationInCis_filtered_samples.csv file in "
                     "each institution's staging folder.\n"
                 )
+
+        if process_functions.checkColExist(mutationInCisDf, "Tumor_Sample_Barcode"):
+            error = process_functions.validate_genie_identifier(
+                identifiers=mutationInCisDf["Tumor_Sample_Barcode"],
+                center=self.center,
+                filename="Mutations In Cis Filter File",
+                col="TUMOR_SAMPLE_BARCODE",
+            )
+            total_error += error
+
         return total_error, warning
diff --git a/genie_registry/sampleRetraction.py b/genie_registry/sampleRetraction.py
index a3ec940..60f42af 100644
--- a/genie_registry/sampleRetraction.py
+++ b/genie_registry/sampleRetraction.py
@@ -36,11 +36,6 @@ class sampleRetraction(FileTypeFormat):
             else "geniePatientId"
         )
         deleteSamplesDf.rename(columns={0: col}, inplace=True)
-        samples = [
-            process_functions.checkGenieId(sample, self.center)
-            for sample in deleteSamplesDf[col]
-        ]
-        deleteSamplesDf[col] = samples
         modifiedOn = to_unix_epoch_time(
             datetime.datetime.strptime(modifiedOn, "%Y-%m-%dT%H:%M:%S")
         )
diff --git a/genie_registry/seg.py b/genie_registry/seg.py
index 65d7ac5..363764a 100644
--- a/genie_registry/seg.py
+++ b/genie_registry/seg.py
@@ -23,8 +23,6 @@ class seg(FileTypeFormat):
 
     def _process(self, seg):
         seg.columns = [col.upper() for col in seg.columns]
-        newsamples = [process_functions.checkGenieId(i, self.center) for i in seg["ID"]]
-        seg["ID"] = newsamples
         seg = seg.drop_duplicates()
         seg = seg.rename(
             columns={
@@ -81,4 +79,10 @@ class seg(FileTypeFormat):
                 % ", ".join(sorted(nullCols))
             )
 
+        if process_functions.checkColExist(segDF, "ID"):
+            error = process_functions.validate_genie_identifier(
+                identifiers=segDF["ID"], center=self.center, filename="Seg", col="ID"
+            )
+            total_error += error
+
         return (total_error, warning)


Test patch:
diff --git a/tests/test_clinical.py b/tests/test_clinical.py
index 81ea546..0a904ac 100644
--- a/tests/test_clinical.py
+++ b/tests/test_clinical.py
@@ -134,7 +134,13 @@ def test_patient_fillvs__process(clin_class):
 
     patientdf = pd.DataFrame(
         dict(
-            PATIENT_Id=["ID1", "ID2", "ID3", "ID4", "ID5"],
+            PATIENT_Id=[
+                "GENIE-SAGE-ID1",
+                "GENIE-SAGE-ID2",
+                "GENIE-SAGE-ID3",
+                "GENIE-SAGE-ID4",
+                "GENIE-SAGE-ID5",
+            ],
             sex=[1, 2, 1, 2, 99],
             PRIMARY_RACE=[1, 2, 3, 4, 99],
             Secondary_RACE=[1, 2, 3, 4, 99],
@@ -191,7 +197,13 @@ def test_patient_lesscoltemplate__process(clin_class):
     # TEST patient processing
     patientdf = pd.DataFrame(
         dict(
-            PATIENT_Id=["ID1", "ID2", "ID3", "ID4", "ID5"],
+            PATIENT_Id=[
+                "GENIE-SAGE-ID1",
+                "GENIE-SAGE-ID2",
+                "GENIE-SAGE-ID3",
+                "GENIE-SAGE-ID4",
+                "GENIE-SAGE-ID5",
+            ],
             sex=[1, 2, 1, 2, 99],
             PRIMARY_RACE=[1, 2, 3, 4, 99],
             Secondary_RACE=[1, 2, 3, 4, 99],
@@ -253,7 +265,13 @@ def test_patient_vs__process(clin_class):
     # Clinical file headers are capitalized prior to processing
     patientdf = pd.DataFrame(
         dict(
-            PATIENT_Id=["ID1", "ID2", "ID3", "ID4", "ID5"],
+            PATIENT_Id=[
+                "GENIE-SAGE-ID1",
+                "GENIE-SAGE-ID2",
+                "GENIE-SAGE-ID3",
+                "GENIE-SAGE-ID4",
+                "GENIE-SAGE-ID5",
+            ],
             sex=[1, 2, 1, 2, 99],
             PRIMARY_RACE=[1, 2, 3, 4, 99],
             Secondary_RACE=[1, 2, 3, 4, 99],
@@ -341,8 +359,20 @@ def test_sample__process(clin_class):
     # patient = False
     sampledf = pd.DataFrame(
         dict(
-            SAMPLE_ID=["ID1-1", "ID2-1", "ID3-1", "ID4-1", "ID5-1"],
-            PATIENT_ID=["ID1", "ID2", "ID3", "ID4", "ID5"],
+            SAMPLE_ID=[
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID2-1",
+                "GENIE-SAGE-ID3-1",
+                "GENIE-SAGE-ID4-1",
+                "GENIE-SAGE-ID5-1",
+            ],
+            PATIENT_ID=[
+                "GENIE-SAGE-ID1",
+                "GENIE-SAGE-ID2",
+                "GENIE-SAGE-ID3",
+                "GENIE-SAGE-ID4",
+                "GENIE-SAGE-ID5",
+            ],
             Age_AT_SEQ_REPORT=[100000, 100000, 100000, 100000, 100000],
             ONCOTree_CODE=["AMPCA", " UNKNOWN", "AMPCA", "AMPCA", "AMPCA"],
             SAMPLE_TYPE=[1, 2, 3, 4, 4],
@@ -362,7 +392,13 @@ def test_perfect__validate(clin_class):
     """
     patientdf = pd.DataFrame(
         dict(
-            PATIENT_ID=["ID1", "ID2", "ID3", "ID4", "ID5"],
+            PATIENT_ID=[
+                "GENIE-SAGE-ID1",
+                "GENIE-SAGE-ID2",
+                "GENIE-SAGE-ID3",
+                "GENIE-SAGE-ID4",
+                "GENIE-SAGE-ID5",
+            ],
             SEX=[1, 2, 1, 2, 99],
             PRIMARY_RACE=[1, 2, 3, 4, 99],
             SECONDARY_RACE=[1, 2, 3, 4, 99],
@@ -380,8 +416,20 @@ def test_perfect__validate(clin_class):
 
     sampledf = pd.DataFrame(
         dict(
-            SAMPLE_ID=["ID1-1", "ID2-1", "ID3-1", "ID4-1", "ID5-1"],
-            PATIENT_ID=["ID1", "ID2", "ID3", "ID4", "ID5"],
+            SAMPLE_ID=[
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID2-1",
+                "GENIE-SAGE-ID3-1",
+                "GENIE-SAGE-ID4-1",
+                "GENIE-SAGE-ID5-1",
+            ],
+            PATIENT_ID=[
+                "GENIE-SAGE-ID1",
+                "GENIE-SAGE-ID2",
+                "GENIE-SAGE-ID3",
+                "GENIE-SAGE-ID4",
+                "GENIE-SAGE-ID5",
+            ],
             AGE_AT_SEQ_REPORT=[">32485", "Unknown", "<6570", 20000, 100000],
             ONCOTREE_CODE=["AMPCA", "AMPCA", "Unknown", "AMPCA", "AMPCA"],
             SAMPLE_TYPE=[1, 2, 3, 4, 4],
@@ -407,7 +455,13 @@ def test_nonull__validate(clin_class):
     """
     patientdf = pd.DataFrame(
         dict(
-            PATIENT_ID=["ID1", "ID2", "ID3", "ID4", "ID5"],
+            PATIENT_ID=[
+                "GENIE-SAGE-ID1",
+                "GENIE-SAGE-ID2",
+                "GENIE-SAGE-ID3",
+                "GENIE-SAGE-ID4",
+                "GENIE-SAGE-ID5",
+            ],
             SEX=[1, 2, 1, 2, float("nan")],
             PRIMARY_RACE=[1, 2, 3, 4, float("nan")],
             SECONDARY_RACE=[1, 2, 3, 4, float("nan")],
@@ -431,8 +485,20 @@ def test_nonull__validate(clin_class):
 
     sampledf = pd.DataFrame(
         dict(
-            SAMPLE_ID=["ID1-1", "ID2-1", "ID3-1", "ID4-1", "ID5-1"],
-            PATIENT_ID=["ID1", "ID2", "ID3", "ID4", "ID5"],
+            SAMPLE_ID=[
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID2-1",
+                "GENIE-SAGE-ID3-1",
+                "GENIE-SAGE-ID4-1",
+                "GENIE-SAGE-ID5-1",
+            ],
+            PATIENT_ID=[
+                "GENIE-SAGE-ID1",
+                "GENIE-SAGE-ID2",
+                "GENIE-SAGE-ID3",
+                "GENIE-SAGE-ID4",
+                "GENIE-SAGE-ID5",
+            ],
             AGE_AT_SEQ_REPORT=[100000, "Unknown", 20000, float("nan"), 100000],
             ONCOTREE_CODE=["AMPCA", "AMPCA", "Unknown", "AMPCA", "AMPCA"],
             SAMPLE_TYPE=[1, 2, 3, 4, float("nan")],
@@ -540,8 +606,20 @@ def test_errors__validate(clin_class):
     """
     sampleDf = pd.DataFrame(
         dict(
-            SAMPLE_ID=[float("nan"), "ID2-1", "ID3-1", "ID4-1", "ID5-1"],
-            PATIENT_ID=["ID6", "ID2", "ID3", float("nan"), "ID5"],
+            SAMPLE_ID=[
+                float("nan"),
+                "GENIE-SAGE-ID2-1",
+                "GENIE-SAGE-ID3-1",
+                "GENIE-SAGE-ID4-1",
+                "GENIE-SAGE-ID5-1",
+            ],
+            PATIENT_ID=[
+                "GENIE-SAGE-ID6",
+                "GENIE-SAGE-ID2",
+                "GENIE-SAGE-ID3",
+                float("nan"),
+                "GENIE-SAGE-ID5",
+            ],
             AGE_AT_SEQ_REPORT=[10, 100000, ">doo", 100000, 100000],
             ONCOTREE_CODE=["AMPCAD", "TESTIS", "AMPCA", "AMPCA", "UCEC"],
             SAMPLE_TYPE=[1, 2, 3, 4, 6],
@@ -557,7 +635,13 @@ def test_errors__validate(clin_class):
 
     patientDf = pd.DataFrame(
         dict(
-            PATIENT_ID=["ID6", "ID2", "ID3", float("nan"), "ID5"],
+            PATIENT_ID=[
+                "GENIE-SAGE-ID6",
+                "GENIE-SAGE-ID2",
+                "GENIE-SAGE-ID3",
+                float("nan"),
+                "GENIE-SAGE-ID5",
+            ],
             SEX=[1, 2, 1, 5, float("nan")],
             PRIMARY_RACE=[1, 2, 3, 6, float("nan")],
             SECONDARY_RACE=[1, 2, 3, 6, float("nan")],
@@ -575,11 +659,13 @@ def test_errors__validate(clin_class):
         mock_get_onco_map.called_once_with(json_oncotreeurl)
 
         expectedErrors = (
+            "Sample Clinical File: SAMPLE_ID must start with GENIE-SAGE\n"
+            "Patient Clinical File: PATIENT_ID must start with GENIE-SAGE\n"
             "Sample Clinical File: PATIENT_ID's much be contained in the "
             "SAMPLE_ID's (ex. SAGE-1 <-> SAGE-1-2)\n"
             "Patient Clinical File: All samples must have associated patient "
             "information and no null patient ids allowed. "
-            "These samples are missing patient data: ID4-1\n"
+            "These samples are missing patient data: GENIE-SAGE-ID4-1\n"
             "Sample Clinical File: Please double check your "
             "AGE_AT_SEQ_REPORT. It must be an integer, 'Unknown', "
             "'>32485', '<6570'.\n"
@@ -637,9 +723,9 @@ def test_errors__validate(clin_class):
         )
         expectedWarnings = (
             "Sample Clinical File: All patients must have associated sample "
-            "information. These patients are missing sample data: ID6\n"
+            "information. These patients are missing sample data: GENIE-SAGE-ID6\n"
             "Sample Clinical File: Some SAMPLE_IDs have conflicting SEX and "
-            "ONCOTREE_CODES: ID2-1,ID5-1\n"
+            "ONCOTREE_CODES: GENIE-SAGE-ID2-1,GENIE-SAGE-ID5-1\n"
         )
         assert error == expectedErrors.format(year=datetime.datetime.utcnow().year)
         assert warning == expectedWarnings
@@ -653,7 +739,13 @@ def test_duplicated__validate(clin_class):
     """
     patientDf = pd.DataFrame(
         dict(
-            PATIENT_ID=["ID1", "ID1", "ID3", "ID4", float("nan")],
+            PATIENT_ID=[
+                "GENIE-SAGE-ID1",
+                "GENIE-SAGE-ID1",
+                "GENIE-SAGE-ID3",
+                "GENIE-SAGE-ID4",
+                float("nan"),
+            ],
             SEX=[1, 2, 1, 2, float("nan")],
             PRIMARY_RACE=[1, 2, 3, 4, float("nan")],
             SECONDARY_RACE=[1, 2, 3, 4, float("nan")],
@@ -683,8 +775,18 @@ def test_duplicated__validate(clin_class):
 
     sampleDf = pd.DataFrame(
         dict(
-            SAMPLE_ID=["ID1-1", "ID3-1", "ID4-1", float("nan")],
-            PATIENT_ID=["ID1", "ID3", "ID4", float("nan")],
+            SAMPLE_ID=[
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID3-1",
+                "GENIE-SAGE-ID4-1",
+                float("nan"),
+            ],
+            PATIENT_ID=[
+                "GENIE-SAGE-ID1",
+                "GENIE-SAGE-ID3",
+                "GENIE-SAGE-ID4",
+                float("nan"),
+            ],
             AGE_AT_SEQ_REPORT=[100000, 100000, 100000, float("nan")],
             ONCOTREE_CODE=["AMPCA", "UNKNOWN", "AMPCA", float("nan")],
             SAMPLE_TYPE=[1, 3, 4, float("nan")],
diff --git a/tests/test_cna.py b/tests/test_cna.py
index 5b50365..25fc9b4 100644
--- a/tests/test_cna.py
+++ b/tests/test_cna.py
@@ -45,7 +45,7 @@ def cna_class(genie_config):
 
 def test_processing(cna_class):
 
-    order = ["Hugo_Symbol", "Entrez_gene_id", "Id1-1", "Id2-1"]
+    order = ["Hugo_Symbol", "Entrez_gene_id", "GENIE-SAGE-Id1-1", "GENIE-SAGE-Id2-1"]
 
     expected_cnadf = pd.DataFrame(
         {
@@ -59,8 +59,8 @@ def test_processing(cna_class):
         {
             "Hugo_Symbol": ["AAED", "AAK1", "AAAS"],
             "Entrez_gene_id": [0, 0, 0],
-            "Id1-1": [-0.5, 2, 0.5],
-            "Id2-1": [1, 1.5, -1.5],
+            "GENIE-SAGE-Id1-1": [-0.5, 2, 0.5],
+            "GENIE-SAGE-Id2-1": [1, 1.5, -1.5],
         }
     )
     cnadf = cnadf[order]
diff --git a/tests/test_fusions.py b/tests/test_fusions.py
index df3a4f6..d0ea8bb 100644
--- a/tests/test_fusions.py
+++ b/tests/test_fusions.py
@@ -64,7 +64,11 @@ def test_processing(fusionClass):
             "HUGO_SYMBOL": ["AAED", "AAK1", "AAAS5"],
             "ENTREZ_GENE_ID": [0, 0, float("nan")],
             "CENTER": ["SAGE", "SAGE", "SAGE"],
-            "TUMOR_SAMPLE_BARCODE": ["ID1-1", "ID2-1", "ID1-3"],
+            "TUMOR_SAMPLE_BARCODE": [
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID2-1",
+                "GENIE-SAGE-ID1-3",
+            ],
             "FUSION": ["AAED-AAK1", "AAAS-AAK1", "AAAS-AAK1"],
             "DNA_SUPPORT": ["foo", "foo", "foo"],
             "RNA_SUPPORT": ["foo", "foo", "foo"],
@@ -77,17 +81,23 @@ def test_processing(fusionClass):
     assert expectedFusionDf.equals(newFusionDf[expectedFusionDf.columns])
 
 
-def test_validation(fusionClass):
+def test_validation__fail_name(fusionClass):
     with pytest.raises(AssertionError):
         fusionClass.validateFilename(["foo"])
     assert fusionClass.validateFilename(["data_fusions_SAGE.txt"]) == "fusions"
 
+
+def test_validation_perfect(fusionClass):
     fusionDf = pd.DataFrame(
         {
             "HUGO_SYMBOL": ["AAED", "AAK1", "AAAS"],
             "ENTREZ_GENE_ID": [0, 0, 0],
             "CENTER": ["SAGE", "SAGE", "SAGE"],
-            "TUMOR_SAMPLE_BARCODE": ["ID1-1", "ID2-1", "ID1-3"],
+            "TUMOR_SAMPLE_BARCODE": [
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID2-1",
+                "GENIE-SAGE-ID1-3",
+            ],
             "FUSION": ["AAED-AAK1", "AAAS-AAK1", "AAAS-AAK1"],
             "DNA_SUPPORT": ["foo", "foo", "foo"],
             "RNA_SUPPORT": ["foo", "foo", "foo"],
@@ -100,6 +110,8 @@ def test_validation(fusionClass):
         assert error == ""
         assert warning == ""
 
+
+def test_validation_perfect_invalid(fusionClass):
     fusionDf = pd.DataFrame(
         {
             "HUGO_SYMBOL": [float("nan"), "AAK1", "AAAS"],
@@ -117,6 +129,7 @@ def test_validation(fusionClass):
         expectedErrors = (
             "Your fusion file must at least have these headers: ENTREZ_GENE_ID.\n"
             "Your fusion file should not have any NA/blank Hugo Symbols.\n"
+            "fusion: TUMOR_SAMPLE_BARCODE must start with GENIE-SAGE\n"
         )
 
         assert error == expectedErrors
@@ -126,6 +139,7 @@ def test_validation(fusionClass):
         error, warning = fusionClass._validate(fusionDf, True)
         expectedErrors = (
             "Your fusion file must at least have these headers: ENTREZ_GENE_ID.\n"
+            "fusion: TUMOR_SAMPLE_BARCODE must start with GENIE-SAGE\n"
         )
         assert error == expectedErrors
         assert warning == ""
diff --git a/tests/test_maf.py b/tests/test_maf.py
index 5d40ae2..155d66c 100644
--- a/tests/test_maf.py
+++ b/tests/test_maf.py
@@ -30,7 +30,13 @@ def test_perfect_validation():
             CHROMOSOME=[1, 2, 3, 4, 5],
             START_POSITION=[1, 2, 3, 4, 2],
             REFERENCE_ALLELE=["A", "A", "A", "A", "A"],
-            TUMOR_SAMPLE_BARCODE=["ID1-1", "ID1-1", "ID1-1", "ID1-1", "ID1-1"],
+            TUMOR_SAMPLE_BARCODE=[
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID1-1",
+            ],
             T_ALT_COUNT=[1, 2, 3, 4, 3],
             T_DEPTH=[1, 2, 3, 4, 3],
             T_REF_COUNT=[1, 2, 3, 4, 3],
@@ -56,7 +62,13 @@ def test_firstcolumn_validation():
             "REFERENCE_ALLELE": ["A", "B", "C", "D", "E"],
             "START_POSITION": [1, 2, 3, 4, 2],
             "CHROMOSOME": ["A", "A", "A", "A", "A"],
-            "TUMOR_SAMPLE_BARCODE": ["ID1-1", "ID1-1", "ID1-1", "ID1-1", "ID1-1"],
+            "TUMOR_SAMPLE_BARCODE": [
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID1-1",
+            ],
             "T_ALT_COUNT": [1, 2, 3, 4, 3],
             "T_DEPTH": [1, 2, 3, 4, 3],
             "T_REF_COUNT": [1, 2, 3, 4, 3],
@@ -135,6 +147,7 @@ def test_errors_validation():
         "maf: "
         "CHROMOSOME column cannot have any values that start "
         "with 'chr' or any 'WT' values.\n"
+        "maf: TUMOR_SAMPLE_BARCODE must start with GENIE-SAGE\n"
     )
     expectedWarnings = (
         "maf: "
@@ -179,6 +192,7 @@ def test_invalid_validation():
         "maf: N_REF_COUNT must be a numerical column.\n"
         "maf: "
         "TUMOR_SEQ_ALLELE2 can't have any blank or null values.\n"
+        "maf: TUMOR_SAMPLE_BARCODE must start with GENIE-SAGE\n"
     )
     expectedWarnings = (
         "maf: TUMOR_SEQ_ALLELE2 column contains 'NA' values, "
diff --git a/tests/test_mutationsInCis.py b/tests/test_mutationsInCis.py
index 281338f..ea5e319 100644
--- a/tests/test_mutationsInCis.py
+++ b/tests/test_mutationsInCis.py
@@ -54,7 +54,7 @@ def mutCis(genie_config):
 ENTITY = synapseclient.Project("testing", annotations={"dbMapping": ["syn10967259"]})
 
 
-def test_validation(mutCis):
+def test_validation__perfect(mutCis):
     with pytest.raises(AssertionError):
         mutCis.validateFilename(["foo"])
     assert (
@@ -82,6 +82,9 @@ def test_validation(mutCis):
         error, warning = mutCis._validate(mutCisDf)
         assert error == ""
         assert warning == ""
+
+
+def test_validation__missing_col(mutCis):
     mutCisDf = pd.DataFrame(
         dict(
             Flag=["mutationsInCis"],
@@ -104,11 +107,13 @@ def test_validation(mutCis):
         )
         assert error == expectedErrors
 
+
+def test_validation__invalid(mutCis):
     mutCisDf = pd.DataFrame(
         dict(
             Flag=["mutationsInCis"],
             Center=["SAGE"],
-            Tumor_Sample_Barcode=["GENIE-SAGE-ID1-1"],
+            Tumor_Sample_Barcode=["ID1-1"],
             Variant_Classification=["Nonsense_Mutation"],
             Hugo_Symbol=["AKT1"],
             HGVSp_Short=["foo"],
@@ -126,5 +131,7 @@ def test_validation(mutCis):
             "Mutations In Cis Filter File: All variants must come from "
             "the original mutationInCis_filtered_samples.csv file in each "
             "institution's staging folder.\n"
+            "Mutations In Cis Filter File: TUMOR_SAMPLE_BARCODE must "
+            "start with GENIE-SAGE\n"
         )
         assert error == expectedErrors
diff --git a/tests/test_retraction.py b/tests/test_retraction.py
index d0c1b01..6334c71 100644
--- a/tests/test_retraction.py
+++ b/tests/test_retraction.py
@@ -35,7 +35,17 @@ def test_processing():
         )
     )
 
-    srDf = pd.DataFrame({0: ["ID1-1", "ID2-1", "ID3-1", "ID4-1", "ID5-1"]})
+    srDf = pd.DataFrame(
+        {
+            0: [
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID2-1",
+                "GENIE-SAGE-ID3-1",
+                "GENIE-SAGE-ID4-1",
+                "GENIE-SAGE-ID5-1",
+            ]
+        }
+    )
 
     newsrDf = sr._process(srDf, "2018-04-06T18:30:00")
     assert expectedsrDf.equals(newsrDf[expectedsrDf.columns])
@@ -60,7 +70,17 @@ def test_processing():
         )
     )
 
-    prDf = pd.DataFrame({0: ["ID1", "ID2", "ID3", "ID4", "ID5"]})
+    prDf = pd.DataFrame(
+        {
+            0: [
+                "GENIE-SAGE-ID1",
+                "GENIE-SAGE-ID2",
+                "GENIE-SAGE-ID3",
+                "GENIE-SAGE-ID4",
+                "GENIE-SAGE-ID5",
+            ]
+        }
+    )
 
     newprDf = pr._process(prDf, "2018-04-07T18:30:00")
     assert expectedprDf.equals(newprDf[expectedprDf.columns])
diff --git a/tests/test_seg.py b/tests/test_seg.py
index f442e88..bd91149 100644
--- a/tests/test_seg.py
+++ b/tests/test_seg.py
@@ -34,7 +34,13 @@ def test_processing():
 
     segDf = pd.DataFrame(
         {
-            "ID": ["ID1-1", "ID2-1", "ID3-1", "ID4-1", "ID5-1"],
+            "ID": [
+                "GENIE-SAGE-ID1-1",
+                "GENIE-SAGE-ID2-1",
+                "GENIE-SAGE-ID3-1",
+                "GENIE-SAGE-ID4-1",
+                "GENIE-SAGE-ID5-1",
+            ],
             "CHROM": ["chr1", 2, 3, 4, 5],
             "LOC.START": [1, 2, 3, 4, 3],
             "LOC.END": [1, 2, 3, 4, 2],
@@ -50,15 +56,23 @@ def test_processing():
     assert expectedSegDf.equals(newSegDf[expectedSegDf.columns])
 
 
-def test_validation():
+def test_validation_filename():
     with pytest.raises(AssertionError):
         segClass.validateFilename(["foo"])
     assert segClass.validateFilename(["genie_data_cna_hg19_SAGE.seg"]) == "seg"
     assert cbsClass.validateFilename(["genie_data_cna_hg19_SAGE.cbs"]) == "cbs"
 
+
+def test_validation_perfect():
     segDf = pd.DataFrame(
         {
-            "ID": ["ID1", "ID2", "ID3", "ID4", "ID5"],
+            "ID": [
+                "GENIE-SAGE-ID1",
+                "GENIE-SAGE-ID2",
+                "GENIE-SAGE-ID3",
+                "GENIE-SAGE-ID4",
+                "GENIE-SAGE-ID5",
+            ],
             "CHROM": [1, 2, 3, 4, 5],
             "LOC.START": [1, 2, 3, 4, 3],
             "LOC.END": [1, 2, 3, 4, 3],
@@ -71,6 +85,8 @@ def test_validation():
     assert error == ""
     assert warning == ""
 
+
+def test_valdation_invalid():
     segDf = pd.DataFrame(
         {
             "ID": ["ID1", "ID2", "ID3", "ID4", "ID5"],
@@ -84,6 +100,7 @@ def test_validation():
         "Your seg file is missing these headers: SEG.MEAN.\n"
         "Seg: No null or empty values allowed in column(s): "
         "CHROM, LOC.END, LOC.START.\n"
+        "Seg: ID must start with GENIE-SAGE\n"
     )
     error, warning = segClass._validate(segDf)
     assert error == expectedErrors
@@ -108,6 +125,7 @@ def test_validation():
         "Seg: Only integars allowed in these column(s): "
         "LOC.END, LOC.START, NUM.MARK.\n"
         "Seg: Only numerical values allowed in SEG.MEAN.\n"
+        "Seg: ID must start with GENIE-SAGE\n"
     )
     assert error == expectedErrors
     assert warning == ""