{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":116062,"databundleVersionId":14084779,"sourceType":"competition"}],"dockerImageVersionId":31153,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"The most common reasons a **CAFA (or CAFA-Kaggle)** submission fails are:\n\n| Problem | Description | Symptom |\n|----------|--------------|----------|\n| **Incorrect columns** | Must be exactly **3 columns**, tab-separated: `UniProt_ID`, `GO_term`, `Score` | Any space, extra column, or comma breaks it |\n| **Header line included** | The competition expects **no header** | “Header line detected” error |\n| **Invalid GO IDs** | Must match `GO:\\d{7}` pattern | Error about “invalid GO term” |\n| **Invalid protein IDs** | Must match list in the provided targets | “Unknown protein” error |\n| **Score format** | Must be a valid float between `0` and `1`, using `.` as decimal | “Invalid score” or “parsing error” |\n| **Duplicate (Protein, GO) pairs** | Each combination should appear **once** | Error about duplicates |\n| **File encoding / line endings** | Should be **UTF-8**, UNIX (`\\n`) line endings | “Could not parse submission” after long wait |\n\nThis scripts attempts to find the errors and correct them.","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport sys\nimport os\nimport re\n\n\nCURRENT_DIR = os.path.dirname(os.path.abspath(__file__))\nos.chdir(CURRENT_DIR)\nif CURRENT_DIR not in sys.path:\n    sys.path.insert(0, CURRENT_DIR)\nSUBMISSION_FILE = '../data/submission.tsv'\nSAMPLE_SUBMISSION = '../data/sample_submission.tsv'\nFASTA_FILE = '../data/testsuperset.fasta'\n\n\ndef validate_submission(path):\n    df = pd.read_csv(path, sep='\\t', header=None, dtype=str)\n    print(f\"Loaded {len(df):,} lines\")\n\n    # --- Structure ---\n    if df.shape[1] != 3:\n        print(f\"❌ Invalid number of columns ({df.shape[1]}). Expected 3.\")\n        return\n\n    df.columns = [\"UniProt_ID\", \"GO_term\", \"Score\"]\n\n    # --- GO term format ---\n    invalid_go = ~df[\"GO_term\"].str.match(r\"^GO:\\d{7}$\")\n    if invalid_go.any():\n        print(f\"❌ Invalid GO IDs found (examples: {df[invalid_go].head(5).to_dict('records')})\")\n    else:\n        print(\"✅ All GO terms valid.\")\n\n    # --- Score validity ---\n    try:\n        df[\"Score\"] = df[\"Score\"].astype(float)\n    except Exception as e:\n        print(f\"❌ Could not parse some scores as floats: {e}\")\n        return\n\n    out_of_range = (df[\"Score\"] < 0) | (df[\"Score\"] > 1)\n    if out_of_range.any():\n        print(f\"❌ Found {out_of_range.sum()} scores outside [0,1].\")\n    else:\n        print(\"✅ All scores in [0,1].\")\n\n    # --- Duplicates ---\n    subset=[\"UniProt_ID\", \"GO_term\"]\n    dups = df.duplicated(subset=subset)\n    if dups.any():\n        print(f\"❌ Found {dups.sum()} duplicate (UniProt, GO) pairs.\")\n        df_new = df.drop_duplicates(subset=subset, keep=\"first\")\n        df_new.to_csv(\"submission_nodup.tsv\", sep=\"\\t\", header=False, index=False)\n        print(f\"Removed duplicates. New file has {len(df_new):,} lines.\")\n        exit(0)\n    else:\n        print(\"✅ No duplicate pairs.\")\n\n    # --- Reference protein IDs ---\n    ref_ids = set()\n    with open(FASTA_FILE) as f:\n        for line in f:\n            if line.startswith(\">\"):\n                ref_ids.add(re.match(r\">(\\S+)\", line).group(1))\n    #ref = pd.read_csv(SAMPLE_SUBMISSION, sep='\\t', header=None, usecols=[0], names=['UniProt_ID'])\n    #ref_ids = set(ref['UniProt_ID'])\n    missing = df.loc[~df['UniProt_ID'].isin(ref_ids)] #Find rows where the UniProt_ID is are not in ref_ids.\n    if not missing.empty:\n        print(f\"⚠️ {len(missing)} proteins not in reference list (example: {missing['UniProt_ID'].iloc[0]})\")\n        df = df[df[\"UniProt_ID\"].isin(ref_ids)]\n        df.to_csv(\"submission_filtered.tsv\", sep=\"\\t\", header=False, index=False)\n        print(f\"Filtered submission now has {len(df):,} lines (valid proteins only).\")\n    else:\n        print(\"✅ All protein IDs match reference list.\")\n\n    print(\"✅ Validation complete — format looks correct if no ❌ shown.\")\n\nif __name__ == \"__main__\":\n    validate_submission(SUBMISSION_FILE)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null}]}