Skip to content
Snippets Groups Projects
Commit 470d19f3 authored by Flissi Areski's avatar Flissi Areski
Browse files

Merge branch 'add-craft' into 'master'

Add craft

See merge request !7
parents 4c463ef1 2063f186
No related branches found
No related tags found
1 merge request!7Add craft
Showing
with 1644 additions and 200 deletions
...@@ -84,6 +84,7 @@ RUN chown -R www-data:www-data /var/www ...@@ -84,6 +84,7 @@ RUN chown -R www-data:www-data /var/www
# ajustement pour version web : pas de print sur sdtout mais envoie d'une réponse CGI de type content-type/html # ajustement pour version web : pas de print sur sdtout mais envoie d'une réponse CGI de type content-type/html
COPY ./pampa /var/www/cgi-bin/pampa/pampa COPY ./pampa /var/www/cgi-bin/pampa/pampa
COPY ./main_taxonomy_filtering.py /var/www/cgi-bin/pampa/pampa/ COPY ./main_taxonomy_filtering.py /var/www/cgi-bin/pampa/pampa/
COPY ./table_maker.py /var/www/cgi-bin/pampa/pampa
# Ajustage des droits # Ajustage des droits
RUN chmod +x /var/www/cgi-bin/pampa/* RUN chmod +x /var/www/cgi-bin/pampa/*
......
version: '3.8'
services:
pampa:
build:
context: .
args:
- DEBIAN_FRONTEND=noninteractive
- SERVER_NAME=localhost
ports:
- "80:80"
volumes:
- postgres_data:/var/lib/postgresql/12/main
environment:
- SERVER_NAME=localhost
restart: unless-stopped
volumes:
postgres_data:
\ No newline at end of file
...@@ -43,11 +43,11 @@ def main(): ...@@ -43,11 +43,11 @@ def main():
# parsing models for peptide tables, sequences or limits # parsing models for peptide tables, sequences or limits
set_of_taxid=set() set_of_taxid=set()
if args.peptide_table : if args.peptide_table :
set_of_markers = pt.parse_peptide_tables(args.peptide_table, args.limit, primary_taxonomy) set_of_markers, _ = pt.parse_peptide_tables(args.peptide_table, args.limit, primary_taxonomy)
set_of_taxid.update({m.taxid for m in set_of_markers}) set_of_taxid.update({m.taxid() for m in set_of_markers})
if args.fasta or args.directory: if args.fasta or args.directory:
set_of_sequences = fa.build_set_of_sequences(args.fasta, args.directory, None, primary_taxonomy) set_of_sequences = fa.build_set_of_sequences(args.fasta, args.directory, None, primary_taxonomy)
set_of_taxid.update({s.taxid for s in set_of_sequences}) set_of_taxid.update({s.taxid() for s in set_of_sequences})
if args.limit: if args.limit:
list_of_constraints=limit.parse_limits(args.limit) list_of_constraints=limit.parse_limits(args.limit)
set_of_taxid.update({t for dict in list_of_constraints for t in dict["OX"]}) set_of_taxid.update({t for dict in list_of_constraints for t in dict["OX"]})
......
import argparse
import json
import csv
from src import markers
from src import peptide_table as pt
from src import config
from src import utils
from functools import cmp_to_key, partial
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-g", dest="or_data")
parser.add_argument("-r", dest="out_data")
parser.add_argument("-o", dest="output")
parser.add_argument("-m", dest="method")
args = parser.parse_args()
table_maker(args.out_data, args.or_data, args.output, args.method)
def compare_file(or_markers, out_markers):
group = {}
for or_marker in or_markers:
group[or_marker] = []
or_data = or_marker.field
keys = or_data.keys()
for out_marker in out_markers:
out_data = out_marker.field
results = {}
for key in keys:
if or_data[key] == out_data[key]:
results[key] = True
elif key == "Mass":
if round(float(or_data[key]),1) == round(float(out_data[key]),1):
results[key] = True
else:
results[key] = False
else:
results[key] = False
if all(results.values()):
group[or_marker].append(out_marker)
return group
def generate_json_result(original_path, output_path, outfile_name):
JSON_file = open(outfile_name, "w")
or_markers, _ = pt.parse_peptide_tables(original_path, None, None, False)
out_markers, list_of_headers = pt.parse_peptide_tables(output_path, None, None, False)
#pt.build_peptide_table_from_set_of_markers(out_markers, "test.tsv")
group = compare_file(or_markers, out_markers)
if not list_of_headers:
headers={pt.restitute_field(key) for m in out_markers for key in m.field}
list_of_headers=(config.sort_headers(headers))
else:
list_of_headers=list(map(pt.restitute_field, list_of_headers))
list_of_headers.append('__modifiedCells')
reverse_map = {}
for orig_marker, out_list in group.items():
for out_m in out_list:
reverse_map[out_m] = orig_marker
dicts = []
for out_m in out_markers:
orig_m = reverse_map.get(out_m, None)
status = {}
for field, value in out_m.field.items():
if orig_m is None:
status[field] = 'new'
else:
if field in orig_m.field:
orig_val = orig_m.field[field]
if field == "Mass":
if orig_val != value:
status[field] = 'modified'
else:
status[field] = 'original'
else:
status[field] = 'modified' if value != orig_val else 'original'
else:
status[field] = 'added'
out_m.field['__modifiedCells'] = dict(zip(list_of_headers, status.values()))
dicts.append(out_m)
set_of_codes=[m.code() for m in dicts]
list_of_codes=config.sort_headers(set_of_codes)
dicts.sort(key=cmp_to_key(partial(pt.marker_order, list_of_codes=list_of_codes)))
result = []
for m in dicts:
result.append(dict(zip(list_of_headers, m.field.values())))
json.dump(result, JSON_file)
JSON_file.close()
return result, list_of_headers
def read_tsv(file_path):
data = []
with open(file_path, "r", newline="") as file:
reader = csv.DictReader(file, delimiter="\t")
headers = reader.fieldnames
for row in reader:
data.append(row)
return data, headers
def table_maker(peptide_out, peptide_or, output_file, method):
if method == "fillin":
dicts, header = generate_json_result([peptide_or], [peptide_out], "test.json")
header.pop()
else :
dicts, header = read_tsv(peptide_out)
html = '''
<div id="results" style="height: 500px; margin-bottom: 20px;" class="ag-theme-alpine"></div>
<div style="margin-top: 10px;">
<button onclick="exportData()">Download Results (.TSV)</button>
<button onclick="deleteSelectedRows()" style="margin-left: 10px;">Delete Selected Rows</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/ag-grid-community/dist/ag-grid-community.min.js"></script>
<script type="text/javascript">
function initGrid() {
let gridApi;
const outData = ''' + json.dumps(dicts) + ''';
const columnDefs = ''' + json.dumps([{"field": h, "headerName": h, "editable": True} for h in header]) + ''';
const gridOptions = {
theme: agGrid.themeBalham,
rowData: outData,
columnDefs: columnDefs.map(col => ({
...col,
cellStyle: params => {
const status = params.data.__modifiedCells?.[col.field];
if (status === 'modified') return { backgroundColor: '#ffff00'};
if (status === 'added') return { backgroundColor: '#00ff00'};
if (status === 'new') return { backgroundColor: '#0000ff'};
return null;
}
})),
pagination: true,
paginationPageSize: 20,
defaultColDef: {
sortable: true,
filter: true,
resizable: true,
editable: true
},
autoSizeStrategy: {
type: "fitCellContents",
},
rowSelection: 'multiple',
onCellValueChanged: function(event) {
console.log('Cell modified:', event);
},
};
function autoSizeAll(skipHeader) {
const allColumnIds = [];
gridApi.getColumns().forEach((column) => {
allColumnIds.push(column.getId());
});
gridApi.autoSizeColumns(allColumnIds, skipHeader);
gridApi.sizeColumnsToFit();
}
gridApi = agGrid.createGrid(document.querySelector("#results"), gridOptions);
window.gridApi = gridApi;
autoSizeAll(true);
window.exportData = function() {
gridApi.exportDataAsCsv({
fileName: "result.tsv",
columnSeparator: '\\t',
suppressQuotes: true,
skipBOM: true
});
};
window.deleteSelectedRows = function() {
const selectedNodes = gridApi.getSelectedNodes();
const selectedData = selectedNodes.map(node => node.data);
gridApi.applyTransaction({ remove: selectedData });
};
}
if(document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initGrid);
} else {
initGrid();
}
</script>
<div id="status" style="margin-top: 10px; color: #666;"></div>
'''
with open(output_file, 'w') as f:
f.write(html)
if __name__ == '__main__':
main()
\ No newline at end of file
...@@ -24,6 +24,16 @@ TAXONOMY_REDUCED_FILE = DATA_PAMPA_DIR + "taxonomy_reduced.tsv" ...@@ -24,6 +24,16 @@ TAXONOMY_REDUCED_FILE = DATA_PAMPA_DIR + "taxonomy_reduced.tsv"
SPECTRA_EXAMPLE_1 = DATA_PAMPA_DIR + "example_1.zip" SPECTRA_EXAMPLE_1 = DATA_PAMPA_DIR + "example_1.zip"
# ---- CRAFT ----
HOMOLOGY_PEPTIDE = DATA_PAMPA_DIR + "homology_peptides.tsv"
HOMOLOGY_SEQUENCES = DATA_PAMPA_DIR + "homology_sequences.fasta"
FILLIN_PEPTIDE = DATA_PAMPA_DIR + "fillin_peptides.tsv"
FILLIN_SEQUENCES = DATA_PAMPA_DIR + "fillin_sequences.fasta"
ALLPEPTIDES_SEQUENCES = DATA_PAMPA_DIR + "allpeptides_sequences.fasta"
#Renvoie le pwd pour le dossier tmp/ #Renvoie le pwd pour le dossier tmp/
def tmp_dir(run_id): def tmp_dir(run_id):
......
import cgitb; cgitb.enable()
import json
import os, sys
from html_utils import *
import common
import zipfile
import operator
#import table_maker
from tools import *
"""
NOTES
- en ajoutant de nouvelles tables de peptides par défaut autres que mammals dans nos données, il faut adapter dans la partie de génération de l'arbre taxonomique section 'reduction by taxonomic groups' la vérification que toutes les tables (groupes taxonomiques) ont été inclues.
"""
def results_output(run_id, job_name=None):
"""
Produit la liste des fichiers téléchargeables par l'utilisateur.
"""
output_files_title = {
"out_"+run_id+".tsv": "Assignments: ",
"detail_out_"+run_id+".tsv": "More details: ",
"report_out_"+run_id+".txt": "Report on the run: ",
"table_out_"+run_id+".tsv": "Peptides table built: ",
"data_result_"+run_id+".zip": "Downloads all results and data: "
}
head_out = "All results are available in the following files."
html = head_out
html += "<ul>"
listdir = os.listdir(path=common.RESULT_DIR+run_id)
for fn in output_files_title:
if fn in listdir:
if job_name is not None:
parts = os.path.splitext(fn)
dwl_name = parts[0] + "_" + job_name + parts[1]
else:
dwl_name = fn
html += li(output_files_title[fn] + href_dl(fn, dwl_name))
html += "</ul>"
return html
def write_main_page(run_id, taxo_used, or_data, method, job_name=None):
"""Write a- HTML page. The result page shown first when the PAMPA analysis is done."""
html = ""
# Insert HTML header and page head
html += open(f"{common.HTML_PATH}/header.php", "r").read()
html += '''
<div class="frametitle"><h1 id="title">Pampa-Craft</h1></div>
<div id="center_sup">
<div class="theme-border" style="display:none"></div>
<div id="link_home" style="display:inline-block">
<a href="/" class="text_onglet">
<img src="/Style/icon/home_w.png" alt="home_general"/>
</a>
</div>
<div class="tabs" id="menu_central" style="display:inline-block">'''
html += open(f"{common.HTML_PATH}/menu_central.txt", "r").read()
html += '''</div></div><div id="main"><div id="center">'''
table_dir = common.RESULT_DIR + run_id + "/table.php"
command = f"/usr/bin/python {common.PAMPA_DIR}table_maker.py -g {or_data} -r {taxo_used} -o {table_dir} -m {method}"
os.chdir(format(os.getcwd()) + "/pampa/")
os.system(command)
if os.path.exists(table_dir):
html += f'<h2>Results for job {run_id}{f" ({job_name})" if job_name else ""}</h2>'
# Show warnings if they exist
warning_file = common.RESULT_DIR + run_id + "/warning.log"
if os.path.exists(warning_file):
with open(warning_file) as fileOut:
content = fileOut.read().strip()
if content:
html += '''
<div id="warnings_hidden" style="display: block;">
<p>Warning(s) were raised during the execution. <a id="show_warnings">View report</a></p>
</div>
<div id="warnings_shown" style="display: none;">
<p>Warning(s) were raised during the execution. <a id="hide_warnings">Hide</a></p>
<table class="vide">'''
for line in content.split('\n'):
if line:
html += f'<tr><td>{line}</td></tr>'
html += '''</table></div><br>'''
html+= '''
<h3>Peptide Table</h3>
<p>editable preview of the results file. <b>Use the bouton bellow to download edited result.</b></p>'''
html += '<iframe id="results" src="table.php" style="border: none; width: 100%; height: 575px;"></iframe>'
# Download section
html += '''
<h3>Download</h3>''' + results_output(run_id, job_name=job_name) + '<br>'
# Retrieve results
html += f'''
<h3>Retrieve results with an ID</h3>
<p>Your result remains available for at least one month.</p>
<p>To access it, you can either save the URL or <a id="copy" data-copy="{run_id}">copy the ID</a> {run_id}.</p>
<br>'''
else:
html += f'''<div id="error">
<h2>something went wrong in job ({run_id}).</h2>
<p>The problem might be related to one of the input files.</p>
<p>For more details, Please contact <a href="mailto:areski.flissi@univ-lille.fr?Subject=[Pampa ERROR - JOB: {run_id}]">PAMPA</a>.</p>
</div>'''
# Insert page footer
html += '</div></div>'
html += open(f"{common.HTML_PATH}/footer.php", "r").read()
html += '</body></html>'
# Save the HTML file
open(common.RESULT_DIR + run_id + "/results.php", "w").write(html)
def write_no_results_page(run_id, job_name=None):
"""Write a HTML page. The result page shown first when the PAMPA analysis is done."""
html = ""
# Insert HTML header and page head
html += (open(f"{common.HTML_PATH}/header.php", "r").read())
html += '<div class="frametitle"><h1 id="title">Pampa</h1></div><div id="center_sup"><div class="theme-border" style="display:none"></div><div id="link_home" style="display:inline-block"><a href="/" class="text_onglet"><img src="/Style/icon/home_w.png" alt="home_general"/></a></div><div class="tabs" id="menu_central" style="display:inline-block">'
html += open(f"{common.HTML_PATH}/menu_central.txt", 'r').read()
html += '</div></div><div id="main"><div id="center">'
html += (f'<h2>Results for job {run_id}{f" ({job_name})" if job_name else ""}</h2>')
html += '<h4><font color="red">No results</font></h4>'
open(common.RESULT_DIR + run_id + "/results.php", "w").write(html)
# Main program
def main():
# Ce script est lancé avec un paramètre : le nom d'un fichier json
# ce fichier contient diverses informations qui vont guider la construction de la page de résultats.
json_params_file = sys.argv[1]
params = json.load(open(json_params_file, "r"))
run_id = params["run_id"]
if "job_name" in params:
job_name = params['job_name']
else:
job_name = None
if "peptides_path" in params:
table_files = params["peptides_path"]
else:
table_files = None
if "sequences_files" in params:
fasta_file = params["sequences_files"]
method = params["method"]
zip_results(["out_"+run_id+".tsv", "report_out_"+run_id+".txt", ], run_id, job_name=job_name)
write_main_page(run_id, common.RESULT_DIR+ run_id + "/out_"+run_id+".tsv", table_files, method, job_name=job_name)
main()
#!/usr/bin/python
# -*- coding: utf-8 -*-
import cgitb;cgitb.enable()
import os
import cgi
import json
import re
import sys
import common
import shutil
import zipfile
from tools import *
# Fonction permettant de vérifier les données soumises dans le formulaire, retour dans un dictionnaire (req)
# Fonction qui sera modifiée pour le traitement de vos données
def extract_request(form):
""" check the validity of the different fields of form
Cette section vérifie la validité des argument soumis et les conditionne afin de lancer PAMPA comme souhaité.
"""
error_found = False
error_messages = []
req = {}
# fichier de log où les points importants du traitement de la requête seront incris
log = open('log.txt', 'w')
log.write(f'Starting log file\n') # log
resdir = common.RESULT_DIR + form['run_id'].value
log.write(f"Result directory : {resdir}\n")
req['files_uploaded'] = []
extract_job(form, log, req, error_messages)
if 'method' in form:
req["method"] = form['method'].value
method = form['method'].value
else:
method = None
error_messages.append(f"Method is required")
if 'craft-example' in form:
if method == "homology":
extract_files_from_list([common.HOMOLOGY_PEPTIDE], resdir)
req["peptides_path"] = resdir + '/' + "homology_peptides.tsv"
elif method == "fillin":
extract_files_from_list([common.FILLIN_PEPTIDE], resdir)
req["peptides_path"] = resdir + '/' + "fillin_peptides.tsv"
elif 'peptides_file' in form and form['peptides_file'].filename != "":
f = form['peptides_file'].filename
fn = os.path.basename(f)
uploaded, not_uploaded = extract_files_from_fileitems([form['peptides_file']], resdir, extensions_list=[".tsv", ".csv"],
unzip=False)
req["peptides_path"] = resdir + '/' + fn
req['files_uploaded'].extend(uploaded)
for fn in uploaded:
log.write(f"file {fn}\n")
for fn in not_uploaded:
error_messages.append(f"{fn} : The peptide table file must be in TSV format.")
rel_sequences_dir = "sequences"
rel_spectra_dir = "spectra"
abs_sequences_dir = os.path.join(resdir, rel_sequences_dir)
abs_spectra_dir = os.path.join(resdir, rel_spectra_dir)
if 'craft-example' in form:
req['sequences_dir'] = abs_sequences_dir
if method == "homology":
extract_files_from_list([common.HOMOLOGY_SEQUENCES], abs_sequences_dir)
elif method == "fillin":
extract_files_from_list([common.FILLIN_SEQUENCES], abs_sequences_dir)
elif method == "allpeptides":
extract_files_from_list([common.ALLPEPTIDES_SEQUENCES], abs_sequences_dir)
elif 'sequences_files' in form:
req['sequences_dir'] = abs_sequences_dir
fileitems = form['sequences_files']
if not isinstance(fileitems, list):
fileitems = [fileitems]
if fileitems[0].filename == "":
if method != "fillin" and method != "deamidation" and method != "selection":
error_messages.append("At least one FASTA file is required.")
else:
uploaded, not_uploaded = extract_files_from_fileitems(fileitems, abs_sequences_dir,
extensions_list=[".txt", ".fasta"], unzip=True)
req['files_uploaded'].extend(uploaded)
for fn in uploaded:
log.write(f"file {fn}\n")
req['sequences_file'] = fn
for fn in not_uploaded:
if fn in uploaded:
error_messages.append(
f'The File {fn} appears to be present several times in the data supplied.')
else:
error_messages.append(f"{fn} : Sequences must be in FASTA or in a ZIP archive.")
else:
if method != "fillin" and method != "deamidation" and method != "selection":
error_messages.append("At least one sequence is required.")
if 'limit_file' in form and form['limit_file'].filename != "":
f = form['limit_file'].filename
fn = os.path.basename(f)
uploaded, not_uploaded = extract_files_from_fileitems([form['limit_file']], resdir, extensions_list=[".txt"],
unzip=False)
req["limit_path"] = resdir + '/' + fn
req['files_uploaded'].extend(uploaded)
for fn in uploaded:
log.write(f"file {fn}\n")
for fn in not_uploaded:
error_messages.append(f"{fn} : The taxonomy file must be in TSV format.")
if method == "fillin":
if 'error' in form:
error_value = form['error'].value.strip()
if error_value:
req['error_margin'] = error_value
else:
req['error_margin'] = "0.1"
if method == "allpeptides" or method == "selection":
extract_error_margin(form, log, req, error_messages)
if method == "selection" or method == "allpeptides":
if 'spectra_files' in form:
# spectres utilisateurs
fileitems = form['spectra_files']
if not isinstance(fileitems, list):
fileitems = [fileitems]
if fileitems[0].filename == "":
if method != "allpeptides":
error_messages.append("At least one spectrum is required.")
else:
req['spectra_dir'] = abs_spectra_dir
uploaded, not_uploaded = extract_files_from_fileitems(fileitems, abs_spectra_dir, extensions_list=[".csv", ".mgd", ".mzml"], unzip=True)
req['files_uploaded'].extend(uploaded)
for fn in uploaded:
log.write(f"file {fn}\n")
for fn in not_uploaded:
if fn in uploaded :
error_messages.append(f'The mass spectrum {fn} appears to be present several times in the data supplied.')
else:
error_messages.append(f"{fn} : Spectra must be in CSV, MGD or mzML format or in a ZIP archive.")
else:
if method != "allpeptides":
error_messages.append("At least one spectrum is required.")
if method == "fillin" or method == "homology":
extract_taxonomy_selection(form, log, req, error_messages, resdir)
log.write("Recap downloads :\n")
for fn in req['files_uploaded']:
log.write(f"dwl {fn}\n")
req["error_messages"] = error_messages
log.write("Error messages :\n")
for e in error_messages:
log.write(f"error: {e}\n")
log.close()
return req
# Lance le programme en fonction des données contenant dans req
# Fonction à modifier pour l'adapter à votre programme
def launch_software(run_id, req):
# Build the command line for PAMPA
output_arg = "out_" + run_id + ".tsv"
method = req['method']
command = "python pampa_craft.py --" + method + " -o " + common.RESULT_DIR + run_id + "/" + output_arg
if 'peptides_path' in req:
peptides_arg = req['peptides_path']
command += " -p " + peptides_arg
if 'sequences_dir' in req:
sequences_arg = req['sequences_dir']
command += " -d " + sequences_arg
if 'spectra_dir' in req:
spectra_arg = req['spectra_dir']
command += " -s " + spectra_arg
if 'limit_path' in req:
limit_arg = req["limit_path"]
command += " -l " + limit_arg
if 'error_margin' in req:
error_arg = req["error_margin"]
command += " -e " + str(error_arg)
if 'taxo_file' in req:
taxo_file_arg = req["taxo_file"]
command += " -t " + taxo_file_arg
command += " --web"
open("acommand.txt", "w").write(f"{command}") # log
# Launch the analysis
cwd = format(os.getcwd())
os.chdir(format(os.getcwd()) + "/pampa/")
os.system(command)
os.chdir(cwd)
# Écrit un fichier de résultats d'erreurs si PAMPA a planté, sinon affiche les résultats
if open(common.RESULT_DIR + run_id + "/error.log", "r").read() != "":
# Manage PAMPA errors (error.log)
json_file = common.RESULT_DIR + run_id + "/render_error_pampa.json"
os.system(f"python render_error_pampa.py {run_id}")
else:
# Params in json for render_result.py -> le json est écrit dans le dossier result/{run_id}
json_file = common.RESULT_DIR + run_id + "/render_result_params.json"
render_result_dict = {"run_id": run_id}
if "job_name" in req:
render_result_dict["job_name"] = req['job_name'] # nom du job
if "peptides_path" in req:
render_result_dict["peptides_path"] = req['peptides_path']
if "sequences_dir" in req:
render_result_dict["sequences_files"] = req['sequences_dir'] # tables de peptides utilisées
if "method" in req:
render_result_dict["method"] = req['method']
json.dump(render_result_dict, open(json_file, "w"))
os.system(f"python craft_render_result.py {json_file}")
# Vérifie si il n'y a pas d'erreur au retour des données soumises par le formulaire
def process_request(form):
run_id = form['run_id'].value
error = 0
error_page = []
req = extract_request(form)
if len(req['error_messages']) > 0:
error_page = req['error_messages']
error = 1
json_file = common.RESULT_DIR + run_id + "/render_error_params.json"
render_error_dict = {"result_path": common.RESULT_DIR, "run_id": run_id, "error_list": req['error_messages']}
json.dump(render_error_dict, open(json_file, "w"))
os.system(f"python render_error.py {json_file}")
else:
launch_software(run_id, req)
return (error, error_page)
def main():
fs = cgi.FieldStorage()
error, error_page = process_request(fs)
sys.stdout.write("Content-Type: application/json")
sys.stdout.write("\n")
sys.stdout.write("\n")
result = {}
if error == 0 or error == 1:
result['success'] = True
result['run_id'] = fs['run_id'].value
result['path_result'] = common.RESULT_DIR + fs['run_id'].value + "/results.php"
else:
result['success'] = False
sys.stdout.write(json.dumps(result, indent=1))
sys.stdout.write("\n")
main()
...@@ -7,102 +7,7 @@ import json ...@@ -7,102 +7,7 @@ import json
import re import re
import sys import sys
import common import common
import shutil from tools import *
import zipfile
#Vérification du mail
def verif_mail(mail):
""" check the validity of email address """
res = mail.strip()
if res.find(' ') > 0:
return False
a = res.find('@')
if a <= 0:
return False
if res.find('@', a+1) > 0:
return False
return True
def extract_files_from_fileitems(fileitems, final_dir, extensions_list=None, unzip=False):
"""
Gère les fichiers uploadés (dont ZIP) et les copie dans le dossier cible.
Args:
fileitems (list): Liste de fichiers type Werkzeug FileStorage
final_dir (str): Dossier de destination
extensions_list (list): Extensions autorisées (ex: ['.txt', '.csv'])
unzip (bool): Auto-extraction des ZIP si True
Returns:
tuple: (fichiers transférés, fichiers rejetés)
"""
files_moved = []
files_not_moved = []
final_dir = final_dir.rstrip('/')
if not os.path.exists(final_dir):
os.makedirs(final_dir, exist_ok=True)
if extensions_list:
extensions = "|".join(extensions_list)
for f in fileitems:
fn = os.path.basename(f.filename)
re_extension = re.compile(os.path.splitext(fn)[1], re.IGNORECASE)
if unzip and re_extension.search(".zip"):
with zipfile.ZipFile(f.file, "r") as myzip:
for element in myzip.infolist():
fname = os.path.basename(element.filename)
if element.is_dir():
continue
re_extension = re.compile(os.path.splitext(fname)[1], re.IGNORECASE)
if (extensions_list is None or re_extension.search(extensions)) and not os.path.exists(
os.path.join(final_dir, fname)):
with myzip.open(element.filename, "r") as src, open(os.path.join(final_dir, fname),
'wb') as dst:
dst.write(src.read())
files_moved.append(fname)
else:
files_not_moved.append(fname)
elif (extensions_list is None or re_extension.search(extensions)) and not os.path.exists(
os.path.join(final_dir, fn)):
with open(os.path.join(final_dir, fn), 'wb') as dst:
dst.write(f.file.read())
files_moved.append(fn)
else:
files_not_moved.append(fn)
return files_moved, files_not_moved
def extract_files_from_list(filename_list, final_dir):
"""
Déplacement de fichiers internes.
l'unzip est systématique
"""
final_dir = final_dir.rstrip('/')
if not os.path.exists(final_dir):
os.mkdir(final_dir)
for fn in filename_list:
if os.path.exists(fn):
re_extension = re.compile(os.path.splitext(fn)[1], re.IGNORECASE) # to detect ZIP archive
if re_extension.search(".zip"):
with zipfile.ZipFile(fn, "r") as myzip:
for element in myzip.filelist:
fname = element.filename
if fname[-1] != "/": # not a directory
open(final_dir + '/' + fname, 'wb').write(myzip.open(fname, "r").read()) # cp file
else:
open(final_dir + '/' + os.path.basename(fn), 'w').write(open(fn, "r").read()) # cp file
return None
#Fonction permettant de vérifier les données soumises dans le formulaire, retour dans un dictionnaire (req) #Fonction permettant de vérifier les données soumises dans le formulaire, retour dans un dictionnaire (req)
#Fonction qui sera modifiée pour le traitement de vos données #Fonction qui sera modifiée pour le traitement de vos données
...@@ -142,17 +47,7 @@ def extract_request(form): ...@@ -142,17 +47,7 @@ def extract_request(form):
#req['pampa_version'] = form['pampa_version'] #req['pampa_version'] = form['pampa_version']
# Job name parsing (optionnal) # Job name parsing (optionnal)
if "job_name" in form: extract_job(form, log, req, error_messages)
job_name = form["job_name"].value.strip().replace(' ', '_')
if job_name == "":
log.write("Job name: None\n") # log
elif len(job_name) <= 30:
req['job_name'] = job_name
log.write(f"Job name: {job_name}\n") # log
else:
error_messages.append(f"The job name cannot exceed 30 characters. Current size: {len(job_name)}.")
else:
log.write("Job name: None\n")
# Spectra files parsing # Spectra files parsing
rel_spectra_dir = "spectra" rel_spectra_dir = "spectra"
...@@ -184,35 +79,7 @@ def extract_request(form): ...@@ -184,35 +79,7 @@ def extract_request(form):
error_messages.append("At least one spectrum is required.") error_messages.append("At least one spectrum is required.")
# Mass error parsing # Mass error parsing
if "error_margin_selection" in form: extract_error_margin(form, log, req, error_messages)
error_margin_selection = form['error_margin_selection'].value
error_margin = 0
if error_margin_selection == "MALDI_TOF":
# valeur par défaut
error_margin = 50
elif error_margin_selection == "MALDI_FTICR":
# valeur par défaut
error_margin = 5
elif error_margin_selection == "ppm":
if "error_margin_ppm" in form:
error_margin = int(form['error_margin_ppm'].value)
if error_margin < 1 or error_margin > 1000:
error_messages.append(f"The mass error in ppm must be within the range 1-1000. Input value: {error_margin}.")
else:
error_messages.append(f"With the custom value in ppm option, a mass error value is required.")
elif error_margin_selection == "daltons":
if "error_margin_daltons" in form:
error_margin = float(form['error_margin_daltons'].value)
if not (error_margin > 0 and error_margin < 1):
error_messages.append(f"The mass error in daltons must be within the range 0.002-0.998. Input value: {error_margin}.")
else:
error_messages.append(f"With the custom value in Daltons option, a mass error value is required.")
else:
error_messages.append(f"Internal error. An unknow value have been entered in the 'error_margin_selection' input: {error_margin_selection}")
log.write(f"Error margin: {error_margin}\n")
req['error_margin'] = error_margin
else:
error_messages.append("A mass error selection is necessary for the analysis.")
# 'Choice of the markers and organisms' parsing (default data or upload custom data) # 'Choice of the markers and organisms' parsing (default data or upload custom data)
if "reference_source" not in form : if "reference_source" not in form :
...@@ -329,38 +196,7 @@ def extract_request(form): ...@@ -329,38 +196,7 @@ def extract_request(form):
error_messages.append("Internal error. Issue in the formular structure ('peptides_files' or 'sequences_files' input).") error_messages.append("Internal error. Issue in the formular structure ('peptides_files' or 'sequences_files' input).")
# Taxonomy parsing # Taxonomy parsing
if "taxonomy_selection" in form: extract_taxonomy_selection(form, log, req, error_messages, resdir)
taxonomy_selection = form["taxonomy_selection"].value
if taxonomy_selection == "default":
# sur les données (table/sequences) utilisateurs, on utilise la taxonomy_all.tsv qui est plus générale.
f = common.TAXONOMY_ALL_FILE
fn = os.path.basename(f)
extract_files_from_list([f], resdir)
req["taxo_file"] = resdir + '/' + fn # for the command
req["taxo_source"] = "default_all"
log.write(f"file {fn}\n") # log
elif taxonomy_selection == "no":
# pas d'information taxonomique -> pas de fichier taxo.tsv
log.write("No taxonomy\n")
elif taxonomy_selection == "custom":
# upload de la taxonomie utilisateur si possible, sinon erreur
if 'taxo_file' in form and not isinstance(form['taxo_file'], list) and form['taxo_file'].filename != "":
f = form['taxo_file'].filename
fn = os.path.basename(f)
uploaded, not_uploaded = extract_files_from_fileitems([form['taxo_file']], resdir, extensions_list=[".tsv"], unzip=False)
req["taxo_file"] = resdir + '/' + fn # for the command
req["taxo_source"] = "user"
req['files_uploaded'].extend(uploaded) # for the render_result
for fn in uploaded:
log.write(f"file {fn}\n")
for fn in not_uploaded:
error_messages.append(f"{fn} : The taxonomy file must be in TSV format.")
else:
error_messages.append("If you choose to upload your own taxonomy, a taxonomy file is required.")
else:
error_messages.append(f"Internal error. An unexpected value has been submitted in the 'taxonomy_selection' input : {taxonomy_selection}")
else:
error_messages.append("A choice is required in the 'Taxonomy' section.")
# option -n nombre et/ou -a (solution suboptimales) # option -n nombre et/ou -a (solution suboptimales)
if 'nearoptimal_selection' in form: if 'nearoptimal_selection' in form:
......
...@@ -6,6 +6,7 @@ import common ...@@ -6,6 +6,7 @@ import common
import zipfile import zipfile
import operator import operator
from render_sub_assignment import * from render_sub_assignment import *
from tools import *
""" """
NOTES NOTES
...@@ -14,15 +15,6 @@ NOTES ...@@ -14,15 +15,6 @@ NOTES
""" """
def href_dl(link, name):
"""
Construit une balise <a> ouvrant la page sur un nouvel onglet.
"""
result = f'<a href="{link}" download="{name}" target="_blank">{name}</a>'
return result
def command_builder_taxoreducer(taxonomy, output, reroot=False, peptides_tables=None, sequence_dir=None, limit_file=None): def command_builder_taxoreducer(taxonomy, output, reroot=False, peptides_tables=None, sequence_dir=None, limit_file=None):
""" """
Construit la ligne de commande adaptée à l'utilisation du script 'main_taxonomy_reduced'. Ce script produit une taxonomie réduite sur la base de l'ensemble des espèces sur lesquelles des données sont renseignées (sous la forme de tables de peptides ou d'un dossier de fichiers fasta de séquences de collagène) ou d'un limit_file (au format employé par PAMPA). Construit la ligne de commande adaptée à l'utilisation du script 'main_taxonomy_reduced'. Ce script produit une taxonomie réduite sur la base de l'ensemble des espèces sur lesquelles des données sont renseignées (sous la forme de tables de peptides ou d'un dossier de fichiers fasta de séquences de collagène) ou d'un limit_file (au format employé par PAMPA).
...@@ -41,25 +33,6 @@ def command_builder_taxoreducer(taxonomy, output, reroot=False, peptides_tables= ...@@ -41,25 +33,6 @@ def command_builder_taxoreducer(taxonomy, output, reroot=False, peptides_tables=
command += " -r" command += " -r"
return command return command
def zip_results(file_names, run_id, job_name=None):
"""
Produit un fichier ZIP contenant tous les fichiers de résultat :
- out.tsv
- detail_out.tsv
- report_out.txt
Ce fichier ZIP pourra être téléchargé par l'utilisateur.
"""
with zipfile.ZipFile(f"{common.RESULT_DIR}{run_id}/data_result_{run_id}.zip", "a", compression=zipfile.ZIP_DEFLATED) as dwl_zip:
for fn in file_names:
abs_path = common.RESULT_DIR + run_id + '/' + fn
if os.path.exists(abs_path):
if job_name is not None:
parts = os.path.splitext(fn)
dwl_name = parts[0] + "_" + job_name + parts[1]
else:
dwl_name = fn
dwl_zip.write(abs_path, arcname=dwl_name)
def results_output(run_id, job_name=None): def results_output(run_id, job_name=None):
""" """
Produit la liste des fichiers téléchargeables par l'utilisateur. Produit la liste des fichiers téléchargeables par l'utilisateur.
......
import os
import zipfile
import cgi
import re
import common
# -------------------------------------
# Form
def verif_mail(mail):
"""
Vérification d'une adresse email.
Args:
mail (str): Email à valider
Returns:
bool: True/False
"""
res = mail.strip()
if res.find(' ') > 0:
return False
a = res.find('@')
if a <= 0:
return False
if res.find('@', a + 1) > 0:
return False
return True
def extract_files_from_fileitems(fileitems, final_dir, extensions_list=None, unzip=False):
"""
Gère les fichiers uploadés (dont ZIP) et les copie dans le dossier cible.
Args:
fileitems (list): Liste de fichiers type Werkzeug FileStorage
final_dir (str): Dossier de destination
extensions_list (list): Extensions autorisées (ex: ['.txt', '.csv'])
unzip (bool): Auto-extraction des ZIP si True
Returns:
tuple: (fichiers transférés, fichiers rejetés)
"""
files_moved = []
files_not_moved = []
final_dir = final_dir.rstrip('/')
if not os.path.exists(final_dir):
os.makedirs(final_dir, exist_ok=True)
if extensions_list:
extensions = "|".join(extensions_list)
for f in fileitems:
fn = os.path.basename(f.filename)
re_extension = re.compile(os.path.splitext(fn)[1], re.IGNORECASE)
if unzip and re_extension.search(".zip"):
with zipfile.ZipFile(f.file, "r") as myzip:
for element in myzip.infolist():
fname = os.path.basename(element.filename)
if element.is_dir():
continue
re_extension = re.compile(os.path.splitext(fname)[1], re.IGNORECASE)
if (extensions_list is None or re_extension.search(extensions)) and not os.path.exists(os.path.join(final_dir, fname)):
with myzip.open(element.filename, "r") as src, open(os.path.join(final_dir, fname), 'wb') as dst:
dst.write(src.read())
files_moved.append(fname)
else:
files_not_moved.append(fname)
elif (extensions_list is None or re_extension.search(extensions)) and not os.path.exists(
os.path.join(final_dir, fn)):
with open(os.path.join(final_dir, fn), 'wb') as dst:
dst.write(f.file.read())
files_moved.append(fn)
else:
files_not_moved.append(fn)
return files_moved, files_not_moved
def extract_files_from_list(filename_list, final_dir):
"""
Copie des fichiers locaux vers un dossier cible avec extraction automatique des ZIP.
Args:
filename_list (list): Liste de chemins de fichiers locaux
final_dir (str): Dossier de destination
"""
final_dir = final_dir.rstrip('/')
if not os.path.exists(final_dir):
os.mkdir(final_dir)
for fn in filename_list:
if os.path.exists(fn):
re_extension = re.compile(os.path.splitext(fn)[1], re.IGNORECASE) # to detect ZIP archive
if re_extension.search(".zip"):
with zipfile.ZipFile(fn, "r") as myzip:
for element in myzip.filelist:
fname = element.filename
if fname[-1] != "/": # not a directory
open(final_dir + '/' + fname, 'wb').write(myzip.open(fname, "r").read()) # cp file
else:
open(final_dir + '/' + os.path.basename(fn), 'w').write(open(fn, "r").read()) # cp file
return None
# -------------------------------------
# Extract form data
def extract_job(form, log, req, error_messages):
if "job_name" in form:
job_name = form["job_name"].value.strip().replace(' ', '_')
if job_name == "":
log.write("Job name: None\n")
elif len(job_name) <= 30:
req['job_name'] = job_name
log.write(f"Job name: {job_name}\n")
else:
error_messages.append(f"The job name cannot exceed 30 characters. Current size: {len(job_name)}.")
else:
log.write("Job name: None\n")
def extract_error_margin(form, log, req, error_messages):
if "error_margin_selection" in form:
error_margin_selection = form['error_margin_selection'].value
error_margin = 0
if error_margin_selection == "MALDI_TOF":
# valeur par défaut
error_margin = 50
elif error_margin_selection == "MALDI_FTICR":
# valeur par défaut
error_margin = 5
elif error_margin_selection == "ppm":
if "error_margin_ppm" in form and form["error_margin_ppm"].value != '':
error_margin = int(form['error_margin_ppm'].value)
if error_margin < 1 or error_margin > 1000:
error_messages.append(
f"The mass error in ppm must be within the range 1-1000. Input value: {error_margin}.")
else:
error_messages.append(f"With the custom value in ppm option, a mass error value is required.")
elif error_margin_selection == "daltons":
if "error_margin_daltons" in form and form["error_margin_daltons"].value != '':
error_margin = float(form['error_margin_daltons'].value)
if not (error_margin > 0 and error_margin < 1):
error_messages.append(
f"The mass error in daltons must be within the range 0.002-0.998. Input value: {error_margin}.")
else:
error_messages.append(f"With the custom value in Daltons option, a mass error value is required.")
else:
error_messages.append(
f"Internal error. An unknow value have been entered in the 'error_margin_selection' input: {error_margin_selection}")
log.write(f"Error margin: {error_margin}\n")
req['error_margin'] = error_margin
else:
error_messages.append("A mass error selection is necessary for the analysis.")
def extract_taxonomy_selection(form, log, req, error_messages, resdir):
if "taxonomy_selection" in form:
taxonomy_selection = form["taxonomy_selection"].value
if taxonomy_selection == "default":
# sur les données (table/sequences) utilisateurs, on utilise la taxonomy_all.tsv qui est plus générale.
f = common.TAXONOMY_ALL_FILE
fn = os.path.basename(f)
extract_files_from_list([f], resdir)
req["taxo_file"] = resdir + '/' + fn # for the command
req["taxo_source"] = "default_all"
log.write(f"file {fn}\n") # log
elif taxonomy_selection == "no":
# pas d'information taxonomique -> pas de fichier taxo.tsv
log.write("No taxonomy\n")
elif taxonomy_selection == "custom":
# upload de la taxonomie utilisateur si possible, sinon erreur
if 'taxo_file' in form and not isinstance(form['taxo_file'], list) and form['taxo_file'].filename != "":
f = form['taxo_file'].filename
fn = os.path.basename(f)
uploaded, not_uploaded = extract_files_from_fileitems([form['taxo_file']], resdir,
extensions_list=[".tsv"], unzip=False)
req["taxo_file"] = resdir + '/' + fn # for the command
req["taxo_source"] = "user"
req['files_uploaded'].extend(uploaded) # for the render_result
for fn in uploaded:
log.write(f"file {fn}\n")
for fn in not_uploaded:
error_messages.append(f"{fn} : The taxonomy file must be in TSV format.")
else:
error_messages.append("If you choose to upload your own taxonomy, a taxonomy file is required.")
else:
error_messages.append(
f"Internal error. An unexpected value has been submitted in the 'taxonomy_selection' input : {taxonomy_selection}")
else:
error_messages.append("A choice is required in the 'Taxonomy' section.")
# -------------------------------------
# Result
def href_dl(link, name):
"""
Génère un lien HTML de téléchargement.
Args:
link (str): URL du fichier
name (str): Nom affiché du fichier
Returns:
str: Balise HTML <a> formatée
"""
result = f'<a href="{link}" download="{name}" target="_blank">{name}</a>'
return result
def zip_results(file_names, run_id, job_name=None):
"""
Crée une archive ZIP des résultats d'analyse.
Args:
file_names (list): Noms des fichiers à archiver
run_id (str): Identifiant unique de l'analyse
job_name (str): Optionnel - suffixe pour les noms de fichiers
"""
with zipfile.ZipFile(f"{common.RESULT_DIR}{run_id}/data_result_{run_id}.zip", "a",
compression=zipfile.ZIP_DEFLATED) as dwl_zip:
for fn in file_names:
abs_path = common.RESULT_DIR + run_id + '/' + fn
if os.path.exists(abs_path):
if job_name is not None:
parts = os.path.splitext(fn)
dwl_name = parts[0] + "_" + job_name + parts[1]
else:
dwl_name = fn
dwl_zip.write(abs_path, arcname=dwl_name)
\ No newline at end of file
<?php include('header.php') ?>
<body>
<div class="frametitle">
<h1 id="title">Pampa-Craft</h1>
</div>
<div id="center_sup">
<div class="theme-border" style="display:none"></div>
<div id="link_home" style="display:inline-block"><a href="/" class="text_onglet"><img src="/Style/icon/home_w.png" alt="home_general"/></a></div>
<div class="tabs" id="menu_central" style="display:inline-block"><?php include("menu_central.txt")?></div>
</div>
<div id="main">
<div id="center">
<form id="formulaire-craft-f" method="post" enctype="multipart/form-data">
<input type="hidden" name="pampa_version" value="assign"/>
<input type="hidden" name="method" value="allpeptides"/>
<div class="formulaire">
<table class="vide pampa_choice">
<tr>
<td class="label">
<h2>Name of the job <span style="font-weight: normal">(optional) :</span></h2>
</td>
<td>
<input type="text" name="job_name" maxlength="30"/>
</td>
</tr>
</table>
</div>
<div class="formulaire">
<h2>Target sequences</h2>
<table class="vide">
<tr>
<td class="label">
<B>Upload</B> The fasta files that you will use to complete your table.
</td>
</tr>
<tr id="sequences_input">
<td>
<input type="file" name="sequences_files" value="file" accept=".fasta,.zip" multiple required/>
</td>
</tr>
<tr id="sequences_example" style="display: none;">
<td>
<input class="file_input" id="back_to_normal" type="button" value="Parcourir..."/>
craft-example.zip
<input type="checkbox" style="display: none;" name="craft-example"/>
</td>
</tr>
</table>
<br>
<table class="vide">
<tr>
<td class="label">
<B>Upload</B> The limit file (optional, doc : https://github.com/touzet/pampa/wiki/Limiting-searches).
</td>
</tr>
<tr id="limit_input">
<td>
<input type="file" name="limit_file" value="file" accept=".txt"/>
</td>
</tr>
</table>
</div>
<div class="formulaire">
<h2>Mass spectra</h2>
<table class="vide">
<tr>
<td class="label">
<B>Upload</B> your MS spectra files in CSV, MGF or mzML format (or in a .ZIP archive)
</td>
</tr>
<tr id="spectra_input">
<td>
<input type="file" name="spectra_files" value="file" accept=".csv,.mgf,.mzml,.zip" multiple/>
</td>
</tr>
<tr id="spectra_example" style="display: none;">
<td>
<input class="file_input" id="back_to_normal" type="button" value="Parcourir..."/>
craft_example.zip
<input type="checkbox" style="display: none;" name="spectra_example_1"/>
</td>
</tr>
</table>
<br>
<b>Mass error</b>
<table class="vide pampa_choice">
<tr>
<td>
<input type="radio" name="error_margin_selection" value="MALDI_TOF" checked/>
Optimize for MALDI-TOF spectra
</td>
</tr>
<tr>
<td>
<input type="radio" name="error_margin_selection" value="MALDI_FTICR"/>
Optimize for MALDI-FTICR spectra
</td>
</tr>
<tr>
<td>
<input type="radio" name="error_margin_selection" value="ppm"/>
Custom value in ppm
</td>
<td>
<input type="number" name="error_margin_ppm" step="1" min="1" max="1000" placeholder="between 1 and 1000"/>
</td>
</tr>
<tr>
<td>
<input type="radio" name="error_margin_selection" value="daltons">
Custom value in Daltons
</td>
<td>
<input type="number" name="error_margin_daltons" step="0.002" min="0.002" max="0.998" placeholder="between 0.002 and 0.998"/>
</td>
</tr>
</table>
</div>
<div class="center">
<input type="button" id="example-allpeptides" name="example-allpeptides" value="Example">
</div>
<div class="center">
<input type="submit" id="reset-craft-a" name="reset" value="Reset" />
<input type="submit" id="run" name="button" value="Run" />
<input type="hidden" name="command" value="request" />
</div>
</form>
</div><!--bloc -->
</div><!-- main-->
<!-- chargement de la librairie php lib.inc -->
<?php require("../lib.inc")?>
<!-- appel de la fonction footer qui permet d'afficher au bas de la page (nom du logiciel, un lien vers le mail, la date de modif -->
<!-- A modifier en fonction de votre logiciel -->
<?php footer("Pampa","Pampa", "areski.flissi@univ-lille.fr","2025"); ?>
</body>
</html>
<?php include('header.php') ?>
<body>
<div class="frametitle">
<h1 id="title">Pampa-Craft</h1>
</div>
<div id="center_sup">
<div class="theme-border" style="display:none"></div>
<div id="link_home" style="display:inline-block"><a href="/" class="text_onglet"><img src="/Style/icon/home_w.png" alt="home_general"/></a></div>
<div class="tabs" id="menu_central" style="display:inline-block"><?php include("menu_central.txt")?></div>
</div>
<div id="main">
<div id="center">
<form id="formulaire-craft-f" method="post" enctype="multipart/form-data">
<input type="hidden" name="pampa_version" value="assign"/>
<input type="hidden" name="method" value="deamidation"/>
<div class="formulaire">
<table class="vide pampa_choice">
<tr>
<td class="label">
<h2>Name of the job <span style="font-weight: normal">(optional) :</span></h2>
</td>
<td>
<input type="text" name="job_name" maxlength="30"/>
</td>
</tr>
</table>
</div>
<div class="formulaire">
<h2>Peptides Table</h2>
<table class="vide">
<tr>
<td class="label">
<B>Upload</B> the peptides table that you want to complete in (.csv or .tsv)
</td>
</tr>
<tr id="peptide_input">
<td>
<input type="file" name="peptides_file" value="file" accept=".tsv,.csv" required/>
</td>
</tr>
<tr id="peptide_example" style="display: none;">
<td>
<input class="file_input" id="back_to_normal" type="button" value="Parcourir..."/>
craft-example.tsv
<input type="checkbox" style="display: none;" name="craft-example"/>
</td>
</tr>
</table>
<br>
</div>
<div class="formulaire">
<h2>Limit File</h2>
<table class="vide">
<tr>
<td class="label">
<B>Upload</B> The limit file (optional, doc : https://github.com/touzet/pampa/wiki/Limiting-searches).
</td>
</tr>
<tr id="limit_input">
<td>
<input type="file" name="limit_file" value="file" accept=".txt"/>
</td>
</tr>
</table>
</div>
<div class="center">
<input type="submit" id="run" name="button" value="Run" />
<input type="hidden" name="command" value="request" />
</div>
</form>
</div><!--bloc -->
</div><!-- main-->
<!-- chargement de la librairie php lib.inc -->
<?php require("../lib.inc")?>
<!-- appel de la fonction footer qui permet d'afficher au bas de la page (nom du logiciel, un lien vers le mail, la date de modif -->
<!-- A modifier en fonction de votre logiciel -->
<?php footer("Pampa","Pampa", "areski.flissi@univ-lille.fr","2025"); ?>
</body>
</html>
<?php include('header.php') ?>
<body>
<div class="frametitle">
<h1 id="title">Pampa-Craft</h1>
</div>
<div id="center_sup">
<div class="theme-border" style="display:none"></div>
<div id="link_home" style="display:inline-block"><a href="/" class="text_onglet"><img src="/Style/icon/home_w.png" alt="home_general"/></a></div>
<div class="tabs" id="menu_central" style="display:inline-block"><?php include("menu_central.txt")?></div>
</div>
<div id="main">
<div id="center">
<form id="formulaire-craft-f" method="post" enctype="multipart/form-data">
<input type="hidden" name="pampa_version" value="assign"/>
<input type="hidden" name="method" value="fillin"/>
<div class="formulaire">
<table class="vide pampa_choice">
<tr>
<td class="label">
<h2>Name of the job <span style="font-weight: normal">(optional) :</span></h2>
</td>
<td>
<input type="text" name="job_name" maxlength="30"/>
</td>
</tr>
</table>
</div>
<div class="formulaire">
<h2>Peptide table</h2>
<table class="vide">
<tr>
<td class="label">
<B>Upload</B> the peptide table that you want to complete in (.csv or .tsv)
</td>
</tr>
<tr id="peptide_input">
<td>
<input type="file" name="peptides_file" value="file" accept=".tsv,.csv" required/>
</td>
</tr>
<tr id="peptide_example" style="display: none;">
<td>
<input class="file_input" id="back_to_normal" type="button" value="Parcourir..."/>
craft-example.tsv
<input type="checkbox" style="display: none;" name="craft-example"/>
</td>
</tr>
</table>
<br>
</div>
<div class="formulaire">
<h2>Target sequences</h2>
<table class="vide">
<tr>
<td class="label">
<B>Upload</B> The fasta files that you will use to complete your table.
</td>
</tr>
<tr id="sequences_input">
<td>
<input type="file" name="sequences_files" value="file" accept=".fasta,.zip" multiple/>
</td>
</tr>
<tr id="sequences_example" style="display: none;">
<td>
<input class="file_input" id="back_to_normal" type="button" value="Parcourir..."/>
craft-example.zip
<input type="checkbox" style="display: none;" name="craft-example"/>
</td>
</tr>
</table>
<br>
<table class="vide">
<tr>
<td class="label">
<B>Upload</B> The limit file (optional, doc : https://github.com/touzet/pampa/wiki/Limiting-searches).
</td>
</tr>
<tr id="limit_input">
<td>
<input type="file" name="limit_file" value="file" accept=".txt"/>
</td>
</tr>
</table>
<br>
<table>
<tr>
<td class="label">
<B>Enter</B> The margin error
</td>
</tr>
<tr id="error_input">
<td>
<input type="number" name="error" step="0.0001" min="0.0001" max="1" placeholder="between 0.0001 and 1"/>
</td>
</tr>
</table>
</div>
<div class="formulaire">
<h2>Taxonomy</h2>
<table class="vide">
<tr>
<td colspan="2">
<input type="radio" name="taxonomy_selection" value="default"/>
Use NCBI taxonomy
</td>
</tr>
<tr>
<td colspan="2">
<input type="radio" name="taxonomy_selection" value="no" checked/>
Provide no taxonomy
</td>
</tr>
<tr>
<td>
<input type="radio" name="taxonomy_selection" value="custom"/>
Upload your own taxonomy
</td>
<td>
<input type="file" name="taxo_file" value="file" accept=".tsv"/>
</td>
</tr>
</table>
</div>
<div class="center">
<input type="button" id="example-fillin" name="example-fillin" value="Example">
</div>
<div class="center">
<input type="submit" id="reset-craft-f" name="reset" value="Reset" />
<input type="submit" id="run" name="button" value="Run" />
<input type="hidden" name="command" value="request" />
</div>
</form>
</div><!--bloc -->
</div><!-- main-->
<!-- chargement de la librairie php lib.inc -->
<?php require("../lib.inc")?>
<!-- appel de la fonction footer qui permet d'afficher au bas de la page (nom du logiciel, un lien vers le mail, la date de modif -->
<!-- A modifier en fonction de votre logiciel -->
<?php footer("Pampa","Pampa", "areski.flissi@univ-lille.fr","2025"); ?>
</body>
</html>
<?php include('header.php') ?>
<body>
<div class="frametitle">
<h1 id="title">Pampa-Craft</h1>
</div>
<div id="center_sup">
<div class="theme-border" style="display:none"></div>
<div id="link_home" style="display:inline-block"><a href="/" class="text_onglet"><img src="/Style/icon/home_w.png" alt="home_general"/></a></div>
<div class="tabs" id="menu_central" style="display:inline-block"><?php include("menu_central.txt")?></div>
</div>
<div id="main">
<div id="center">
<form id="formulaire-craft-h" method="post" enctype="multipart/form-data">
<input type="hidden" name="pampa_version" value="assign"/>
<input type="hidden" name="method" value="homology"/>
<div class="formulaire">
<table class="vide pampa_choice">
<tr>
<td class="label">
<h2>Name of the job <span style="font-weight: normal">(optional) :</span></h2>
</td>
<td>
<input type="text" name="job_name" maxlength="30"/>
</td>
</tr>
</table>
</div>
<div class="formulaire">
<h2>Peptide Table</h2>
<table class="vide">
<tr>
<td class="label">
<B>Upload</B> the peptide table that you want to complete in (.csv or .tsv)
</td>
</tr>
<tr id="peptide_input">
<td>
<input type="file" name="peptides_file" value="file" accept=".tsv,.csv" required/>
</td>
</tr>
<tr id="peptide_example" style="display: none;">
<td>
<input class="file_input" id="back_to_normal" type="button" value="Parcourir..."/>
craft-example.tsv
<input type="checkbox" style="display: none;" name="craft-example"/>
</td>
</tr>
</table>
<br>
</div>
<div class="formulaire">
<h2>Target sequences</h2>
<table class="vide">
<tr>
<td class="label">
<B>Upload</B> The fasta files that you will use to complete your table.
</td>
</tr>
<tr id="sequences_input">
<td>
<input type="file" name="sequences_files" value="file" accept=".fasta,.zip" multiple required/>
</td>
</tr>
<tr id="sequences_example" style="display: none;">
<td>
<input class="file_input" id="back_to_normal" type="button" value="Parcourir..."/>
craft-example.zip
<input type="checkbox" style="display: none;" name="craft-example"/>
</td>
</tr>
</table>
<br>
<table class="vide">
<tr>
<td class="label">
<B>Upload</B> The limit file (optional, doc : https://github.com/touzet/pampa/wiki/Limiting-searches).
</td>
</tr>
<tr id="limit_input">
<td>
<input type="file" name="limit_file" value="file" accept=".txt"/>
</td>
</tr>
</table>
</div>
<div class="formulaire">
<h2>Taxonomy</h2>
<table class="vide">
<tr>
<td colspan="2">
<input type="radio" name="taxonomy_selection" value="default"/>
Use NCBI taxonomy
</td>
</tr>
<tr>
<td colspan="2">
<input type="radio" name="taxonomy_selection" value="no" checked/>
Provide no taxonomy
</td>
</tr>
<tr>
<td>
<input type="radio" name="taxonomy_selection" value="custom"/>
Upload your own taxonomy
</td>
<td>
<input type="file" name="taxo_file" value="file" accept=".tsv"/>
</td>
</tr>
</table>
</div>
<div class="center">
<input type="button" id="example-homology" name="example-homology" value="Example">
</div>
<div class="center">
<input type="submit" id="reset-craft-h" name="reset" value="Reset" />
<input type="submit" id="run" name="button" value="Run" />
<input type="hidden" name="command" value="request" />
</div>
</form>
</div><!--bloc -->
</div><!-- main-->
<!-- chargement de la librairie php lib.inc -->
<?php require("../lib.inc")?>
<!-- appel de la fonction footer qui permet d'afficher au bas de la page (nom du logiciel, un lien vers le mail, la date de modif -->
<!-- A modifier en fonction de votre logiciel -->
<?php footer("Pampa","Pampa", "areski.flissi@univ-lille.fr","2025"); ?>
</body>
</html>
<?php include('header.php') ?>
<body>
<div class="frametitle">
<h1 id="title">Pampa-Craft</h1>
</div>
<div id="center_sup">
<div class="theme-border" style="display:none"></div>
<div id="link_home" style="display:inline-block"><a href="/" class="text_onglet"><img src="/Style/icon/home_w.png" alt="home_general"/></a></div>
<div class="tabs" id="menu_central" style="display:inline-block"><?php include("menu_central.txt")?></div>
</div>
<div id="main">
<div id="center">
<form id="formulaire-craft-f" method="post" enctype="multipart/form-data">
<input type="hidden" name="pampa_version" value="assign"/>
<input type="hidden" name="method" value="selection"/>
<div class="formulaire">
<table class="vide pampa_choice">
<tr>
<td class="label">
<h2>Name of the job <span style="font-weight: normal">(optional) :</span></h2>
</td>
<td>
<input type="text" name="job_name" maxlength="30"/>
</td>
</tr>
</table>
</div>
<div class="formulaire">
<h2>Peptide Table</h2>
<table class="vide">
<tr>
<td class="label">
<B>Upload</B> the peptide table that you want to complete in (.csv or .tsv)
</td>
</tr>
<tr id="peptide_input">
<td>
<input type="file" name="peptides_file" value="file" accept=".tsv,.csv" required/>
</td>
</tr>
<tr id="peptide_example" style="display: none;">
<td>
<input class="file_input" id="back_to_normal" type="button" value="Parcourir..."/>
craft-example.tsv
<input type="checkbox" style="display: none;" name="craft-example"/>
</td>
</tr>
</table>
<br>
</div>
<div class="formulaire">
<h2>Mass spectra</h2>
<table class="vide">
<tr>
<td class="label">
<B>Upload</B> your MS spectra files in CSV, MGF or mzML format (or in a .ZIP archive)
</td>
</tr>
<tr id="spectra_input">
<td>
<input type="file" name="spectra_files" value="file" accept=".csv,.mgf,.mzml,.zip" multiple required/>
</td>
</tr>
<tr id="spectra_example" style="display: none;">
<td>
<input class="file_input" id="back_to_normal" type="button" value="Parcourir..."/>
pampa_example_1.zip
<input type="checkbox" style="display: none;" name="spectra_example_1"/>
</td>
</tr>
</table>
<br>
<b>Mass error</b>
<table class="vide pampa_choice">
<tr>
<td>
<input type="radio" name="error_margin_selection" value="MALDI_TOF" checked/>
Optimize for MALDI-TOF spectra
</td>
</tr>
<tr>
<td>
<input type="radio" name="error_margin_selection" value="MALDI_FTICR"/>
Optimize for MALDI-FTICR spectra
</td>
</tr>
<tr>
<td>
<input type="radio" name="error_margin_selection" value="ppm"/>
Custom value in ppm
</td>
<td>
<input type="number" name="error_margin_ppm" step="1" min="1" max="1000" placeholder="between 1 and 1000"/>
</td>
</tr>
<tr>
<td>
<input type="radio" name="error_margin_selection" value="daltons">
Custom value in Daltons
</td>
<td>
<input type="number" name="error_margin_daltons" step="0.002" min="0.002" max="0.998" placeholder="between 0.002 and 0.998"/>
</td>
</tr>
</table>
</div>
<div class="center">
<input type="submit" id="run" name="button" value="Run" />
<input type="hidden" name="command" value="request" />
</div>
</form>
</div><!--bloc -->
</div><!-- main-->
<!-- chargement de la librairie php lib.inc -->
<?php require("../lib.inc")?>
<!-- appel de la fonction footer qui permet d'afficher au bas de la page (nom du logiciel, un lien vers le mail, la date de modif -->
<!-- A modifier en fonction de votre logiciel -->
<?php footer("Pampa","Pampa", "areski.flissi@univ-lille.fr","2025"); ?>
</body>
</html>
...@@ -11,7 +11,7 @@ blockquote { ...@@ -11,7 +11,7 @@ blockquote {
padding-left: 8px; padding-left: 8px;
} }
.formulaire { .formulaire, .formulaire-craft-h, .formulaire-craft-f {
border: 1px solid #CCCCCC; border: 1px solid #CCCCCC;
color: #000000; color: #000000;
margin: auto auto 10pt; margin: auto auto 10pt;
......
>XP_027830506.1 OS=Ovis aries OX=9940 GN=COL1A1 A
MFSFVDLRLLLLLAATALLTHGQEEGQEEGQEEDIPPVTCVQNGLRYHDRDVWKPVPCQICVCDNGNVLCDDVICDELKDCPNAKVPTDECCPVCPEGQESTTDQETTGVEGPKGDTGPRGPRGPAGPPGRDGIPGQPGLPGPPGPPGPPGPPGLGGNFAPQLSYGYDEKSTGISVPGPMGPSGPRGLPGPPGAPGPQGFQGPPGEPGEPGASGPMGPRGPPGPPGKNGDDGEAGKPGRPGERGPPGPQGARGLPGTAGLPGMKGHRGFSGLDGAKGDAGPAGPKGEPGSPGENGAPGQMGPRGLPGERGRPGAPGPAGARGNDGATGAAGPPGPTGPAGPPGFPGAVGAKGEAGPQGPRGSEGPQGVRGEPGPPGPAGAAGPAGNPGADGQPGAKGANGAPGIAGAPGFPGARGPSGPQGPSGPPGPKGNSGEPGAPGSKGDTGAKGEPGPTGIQGPPGPAGEEGKRGARGEPGPAGLPGPPGERGGPGSRGFPGSDGVAGPKGPAGERGAPGPAGPKGSPGEAGRPGEAGLPGAKGLTGSPGSPGPDGKTGPPGPAGQDGRPGPPGPPGARGQAGVMGFPGPKGAAGEPGKAGERGVPGPPGAVGPAGKDGEAGAQGPPGPAGPAGERGEQGPAGSPGFQGLPGPAGPPGEAGKPGEQGVPGDLGAPGPSGARGERGFPGERGVQGPPGPAGPRGANGAPGNDGAKGDAGAPGAPGSQGAPGLQGMPGERGAAGLPGPKGDRGDAGPKGADGAPGKDGVRGLTGPIGPPGPAGAPGDKGETGPSGPAGPTGARGAPGDRGEPGPPGPAGFAGPPGADGQPGAKGEPGDAGAKGDAGPPGPAGPAGPPGPIGNVGAPGPKGARGSAGPPGATGFPGAAGRVGPPGPSGNAGPPGPPGPAGKEGSKGPRGETGPAGRAGEVGPPGPPGPAGEKGAPGADGPAGAPGTPGPQGIAGQRGVVGLPGQRGERGFPGLPGPSGEPGKQGPSGASGERGPPGPMGPPGLAGPPGESGREGAPGAEGSPGRDGAPGAKGDRGETGPAGPPGAPGAPGAPGPVGPAGKSGDRGETGPAGPAGPIGPVGARGPAGPQGPRGDKGETGEQGDRGIKGHRGFSGLQGPPGPPGSPGEQGPSGASGPAGPRGPPGSAGTPGKDGLNGLPGPIGPPGPRGRTGDAGPAGPPGPPGPPGPPGPPSGGYDLSFLPQPPQEKAHDGGRYYRADDANVVRDRDLEVDTTLKSLSQQIENIRSPEGSRKNPARTCRDLKMCHPDWKSGEYWIDPNQGCNLDAIKVFCNMETGETCVYPTQPSVPQKNWYISKNPKDKRHVWYGESMTGGFQFEYGGQGSDPADVAIQLTFLRLMSTEASQNITYHCKNSVAYMDQQTGSLKKALLLQGSNEIEIRAEGNSRFTYSVTYDGCTSHTGAWGKTVIEYKTTKTSRLPIIDVAPLDVGAPDQEFGFDIGSVCFL
>XP_004007775.1 OS=Ovis aries OX=9940 GN=COL1A2 A
MLSFVDTRTLLLLAVTSCLATCQSLQEATARKGPSGDRGPRGERGPPGPPGRDGDDGIPGPPGPPGPPGPPGLGGNFAAQFDGKGGGPGPMGLMGPRGPPGASGAPGPQGFQGPPGEPGEPGQTGPAGARGPPGPPGKAGEDGHPGKPGRPGERGVVGPQGARGFPGTPGLPGFKGIRGHNGLDGLKGQPGAPGVKGEPGAPGENGTPGQTGARGLPGERGRVGAPGPAGARGSDGSVGPVGPAGPIGSAGPPGFPGAPGPKGELGPVGNPGPAGPAGPRGEVGLPGLSGPVGPPGNPGANGLPGAKGAAGLPGVAGAPGLPGPRGIPGPVGAAGATGARGLVGEPGPAGSKGESGNKGEPGAVGQPGPPGPSGEEGKRGSTGEIGPAGPPGPPGLRGNPGSRGLPGADGRAGVMGPAGSRGATGPAGVRGPNGDSGRPGEPGLMGPRGFPGSPGNIGPAGKEGPAGLPGIDGRPGPIGPAGARGEPGNIGFPGPKGPTGDPGKAGEKGHAGLAGPRGAPGPDGNNGAQGPPGLQGVQGGKGEQGPAGPPGFQGLPGPAGTAGEAGKPGERGIPGEFGLPGPAGARGERGPPGESGAAGPTGPIGSRGPSGPPGPDGNKGEPGVVGAPGTAGPSGPSGLPGERGAAGIPGGKGEKGETGLRGDVGSPGRDGARGAPGAVGAPGPAGANGDRGEAGPAGPAGPAGPRGSPGERGEVGPAGPNGFAGPAGAAGQPGAKGERGTKGPKGENGPVGPTGPVGAAGPSGPNGPPGPAGSRGDGGPPGATGFPGAAGRTGPPGPAGISGPPGPPGPAGKEGLRGPRGDQGPVGRTGEPGAAGPPGFVGEKGPSGEPGTAGPPGTPGPQGLLGAPGFLGLPGSRGERGLPGVAGSVGEPGPLGIAGPPGARGPPGNVGNPGVNGAPGEAGRDGNPGNDGPPGRDGQPGHKGERGYPGNAGPVGAAGAPGPQGPVGPTGKHGSRGEPGPVGAVGPAGAVGPRGPSGPQGIRGDKGEPGDKGPRGLPGLKGHNGLQGLPGLAGHHGDQGAPGAVGPAGPRGPAGPTGPAGKDGRTGQPGAVGPAGIRGSQGSQGPAGPPGPPGPPGPPGPSGGGYDFGFDGDFYRADQPRSPASLRPKDYEVDATLKSLNNQIETLLTPEGSRKNPARTCRDLRLSHPEWSSGYYWIDPNQGCTMDAIKVYCDFSTGETCIRAQPEDIPVKNWYRNSKAKKHVWVGETINGGTQFEYNVEGVTTKEMATQLAFMRLLANHASQNITYHCKNSIAYMDEETGNLKKAVILQGSNDVELVAEGNSRFTYTVLVDGCSKKTNEWKKTIIEYKTNKPSRLPILDIAPLDIGGADQEIRLNIGPVCFK
Taxon Marker Sequence Mass PTM Hel Gene SeqID Begin End
Mus musculus A 1178.6 COL1A2
Mus musculus A 1194.6 COL1A2
Mus musculus B 1453.7 COL1A2
Mus musculus C 1592.8 COL1A2
>NP_031768.2 OS=Mus musculus OX=10090 GN=COL1A1
MFSFVDLRLLLLLGATALLTHGQEDIPEVSCIHNGLRVPNGETWKPEVCLICICHNGTAVCDDVQCNEELDCPNPQRREGECCAFCPEEYVSPNSEDVGVEGPKGDPGPQGPRGPVGPPGRDGIPGQPGLPGPPGPPGPPGPPGLGGNFASQMSYGYDEKSAGVSVPGPMGPSGPRGLPGPPGAPGPQGFQGPPGEPGEPGGSGPMGPRGPPGPPGKNGDDGEAGKPGRPGERGPPGPQGARGLPGTAGLPGMKGHRGFSGLDGAKGDAGPAGPKGEPGSPGENGAPGQMGPRGLPGERGRPGPPGTAGARGNDGAVGAAGPPGPTGPTGPPGFPGAVGAKGEAGPQGARGSEGPQGVRGEPGPPGPAGAAGPAGNPGADGQPGAKGANGAPGIAGAPGFPGARGPSGPQGPSGPPGPKGNSGEPGAPGNKGDTGAKGEPGATGVQGPPGPAGEEGKRGARGEPGPSGLPGPPGERGGPGSRGFPGADGVAGPKGPSGERGAPGPAGPKGSPGEAGRPGEAGLPGAKGLTGSPGSPGPDGKTGPPGPAGQDGRPGPAGPPGARGQAGVMGFPGPKGTAGEPGKAGERGLPGPPGAVGPAGKDGEAGAQGAPGPAGPAGERGEQGPAGSPGFQGLPGPAGPPGEAGKPGEQGVPGDLGAPGPSGARGERGFPGERGVQGPPGPAGPRGNNGAPGNDGAKGDTGAPGAPGSQGAPGLQGMPGERGAAGLPGPKGDRGDAGPKGADGSPGKDGARGLTGPIGPPGPAGAPGDKGEAGPSGPPGPTGARGAPGDRGEAGPPGPAGFAGPPGADGQPGAKGEPGDTGVKGDAGPPGPAGPAGPPGPIGNVGAPGPKGPRGAAGPPGATGFPGAAGRVGPPGPSGNAGPPGPPGPVGKEGGKGPRGETGPAGRPGEVGPPGPPGPAGEKGSPGADGPAGSPGTPGPQGIAGQRGVVGLPGQRGERGFPGLPGPSGEPGKQGPSGSSGERGPPGPMGPPGLAGPPGESGREGSPGAEGSPGRDGAPGAKGDRGETGPAGPPGAPGAPGAPGPVGPAGKNGDRGETGPAGPAGPIGPAGARGPAGPQGPRGDKGETGEQGDRGIKGHRGFSGLQGPPGSPGSPGEQGPSGASGPAGPRGPPGSAGSPGKDGLNGLPGPIGPPGPRGRTGDSGPAGPPGPPGPPGPPGPPSGGYDFSFLPQPPQEKSQDGGRYYRADDANVVRDRDLEVDTTLKSLSQQIENIRSPEGSRKNPARTCRDLKMCHSDWKSGEYWIDPNQGCNLDAIKVYCNMETGQTCVFPTQPSVPQKNWYISPNPKEKKHVWFGESMTDGFPFEYGSEGSDPADVAIQLTFLRLMSTEASQNITYHCKNSVAYMDQQTGNLKKALLLQGSNEIELRGEGNSRFTYSTLVDGCTSHTGTWGKTVIEYKTTKTSRLPIIDVAPLDIGAPDQEFGLDIGPACFV
>NP_031769.2 OS=Mus musculus OX=10090 GN=COL1A2
MLSFVDTRTLLLLAVTSCLATCQYLQSGSVRKGPTGDRGPRGQRGPAGPRGRDGVDGPMGPPGPPGSPGPPGSPAPPGLTGNFAAQYSDKGVSSGPGPMGLMGPRGPPGAVGAPGPQGFQGPAGEPGEPGQTGPAGPRGPAGSPGKAGEDGHPGKPGRPGERGVVGPQGARGFPGTPGLPGFKGVKGHSGMDGLKGQPGAQGVKGEPGAPGENGTPGQAGARGLPGERGRVGAPGPAGARGSDGSVGPVGPAGPIGSAGPPGFPGAPGPKGELGPVGNPGPAGPAGPRGEVGLPGLSGPVGPPGNPGTNGLTGAKGATGLPGVAGAPGLPGPRGIPGPAGAAGATGARGLVGEPGPAGSKGESGNKGEPGSVGAQGPPGPSGEEGKRGSPGEAGSAGPAGPPGLRGSPGSRGLPGADGRAGVMGPPGNRGSTGPAGIRGPNGDAGRPGEPGLMGPRGLPGSPGNVGPSGKEGPVGLPGIDGRPGPIGPAGPRGEAGNIGFPGPKGPSGDPGKPGERGHPGLAGARGAPGPDGNNGAQGPPGPQGVQGGKGEQGPAGPPGFQGLPGPSGTTGEVGKPGERGLPGEFGLPGPAGPRGERGTPGESGAAGPSGPIGSRGPSGAPGPDGNKGEAGAVGAPGSAGASGPGGLPGERGAAGIPGGKGEKGETGLRGDTGNTGRDGARGIPGAVGAPGPAGASGDRGEAGAAGPSGPAGPRGSPGERGEVGPAGPNGFAGPAGAAGQPGAKGEKGTKGPKGENGIVGPTGSVGAAGPSGPNGPPGPVGSRGDGGPPGMTGFPGAAGRTGPPGPSGIAGPPGPPGAAGKEGIRGPRGDQGPVGRTGETGASGPPGFVGEKGPSGEPGTAGAPGTAGPQGLLGAPGILGLPGSRGERGLPGIAGALGEPGPLGISGPPGARGPPGAVGSPGVNGAPGEAGRDGNPGSDGPPGRDGQPGHKGERGYPGSIGPTGAAGAPGPHGSVGPAGKHGNRGEPGPAGSVGPVGAVGPRGPSGPQGIRGDKGEPGDKGHRGLPGLKGYSGLQGLPGLAGLHGDQGAPGPVGPAGPRGPAGPSGPVGKDGRSGQPGPVGPAGVRGSQGSQGPAGPPGPPGPPGPPGVSGGGYDFGFEGDFYRADQPRSQPSLRPKDYEVDATLKSLNNQIETLLTPEGSRKNPARTCRDLRLSHPEWNSDYYWIDPNQGCTMDAIKVYCDFSTGETCIQAQPVNTPAKNSYSRAQANKHVWLGETINGGSQFEYNVEGVSSKEMATQLAFMRLLANRASQNITYHCKNSIAYLDEETGSLNKAVLLQGSNDVELVAEGNSRFTYSVLVDGCSKKTNEWGKTIIEYKTNKPSRLPFLDIAPLDIGGADQEFRVEVGPVCFK
>XP_032768589.1 OS=Rattus rattus OX=10117 GN=COL1A1
MFSFVDLRLLLLLGATALLTHGQEDIPEVSCIHNGLRVPNGETWKPDVCLICICHNGTAVCDGVLCKEDLDCPNPQRREGECCPFCPEEYVSPDAEVIGVEGPKGDPGPQGPRGPVGPPGQDGIPGQPGLPGPPGPPGPPGPPGLGGNFASQMSYGYDEKSAGVSVPGPMGPSGPRGLPGPPGAPGPQGFQGPPGEPGEPGASGPMGPRGPPGPPGKNGDDGEAGKPGRPGERGPPGPQGARGLPGTAGLPGMKGHRGFSGLDGAKGDTGPAGPKGEPGSPGENGAPGQMGPRGLPGERGRPGPPGSAGARGNDGAVGAAGPPGPTGPTGPPGFPGAAGAKGEAGPQGARGSEGPQGVRGEPGPPGPAGAAGPAGNPGADGQPGAKGANGAPGIAGAPGFPGARGPSGPQGPSGAPGPKGNSGEPGAPGNKGDTGAKGEPGPAGVQGPPGPAGEEGKRGARGEPGPSGLPGPPGERGGPGSRGFPGADGVAGPKGPAGERGSPGPAGPKGSPGEAGRPGEAGLPGAKGLTGSPGSPGPDGKTGPPGPAGQDGRPGPAGPPGARGQAGVMGFPGPKGTAGEPGKAGERGVPGPPGAVGPAGKDGEAGAQGAPGPAGPAGERGEQGPAGSPGFQGLPGPAGPPGEAGKPGEQGVPGDLGAPGPSGARGERGFPGERGVQGPPGPAGPRGNNGAPGNDGAKGDTGAPGAPGSQGAPGLQGMPGERGAAGLPGPKGDRGDAGPKGADGSPGKDGVRGLTGPIGPPGPAGAPGDKGETGPSGPAGPTGARGAPGDRGEPGPPGPAGFAGPPGADGQPGAKGEPGDTGVKGDAGPPGPAGPAGPPGPIGNVGAPGPKGTRGAAGPPGATGFPGAAGRVGPPGPSGNAGPPGPPGPVGKEGGKGPRGETGPAGRPGEVGPPGPPGPAGEKGSPGADGPAGSPGTPGPQGIAGQRGVVGLPGQRGERGFPGLPGPSGEPGKQGPSGASGERGPPGPMGPPGLAGPPGESGREGSPGAEGSPGRDGAPGAKGDRGETGPAGPPGAPGAPGAPGPVGPAGKNGDRGETGPAGPAGPIGPAGARGPAGPQGPRGDKGETGEQGDRGIKGHRGFSGLQGPPGSPGSPGEQGPSGASGPAGPRGPPGSAGSPGKDGLNGLPGPIGPPGPRGRTGDSGPAGPPGPPGPPGPPGPPSGGYDFSFLPQPPQEKSQDGGRYYRADDANVVRDRDLEVDTTLKSLSQQIENIRSPEGSRKNPARTCRDLKMCHSDWKSGEYWIDPNQGCNLDAIKVYCNMETGQTCVFPTQPSVPQKNWYISPNPKEKTHIWFGESMSGGFQFEYGSEGSDPADVAIQLTFLRLMSTEASQNITYHCKNSVAYMDQQTGNLKKSLLLQGSNEIELRGEGNSRFTYSTLVDGCTSHTGTWGKTVIEYKTTKTSRLPIIDVAPLDIGAPDQEFGMDVGPACFV
>XP_032762867.1 OS=Rattus rattus OX=10117 GN=COL1A2
MLSFVDTRTLLLLAVTSCLATCQSLQMGSVRKGPTGDRGPRGQRGPAGPRGRDGVDGPVGPPGPAGAPGPPGPPGPPGLTGNFAAQYSDKGVSAGPGPMGLMGPRGPPGAVGAPGPQGFQGPAGEPGEPGQTGPAGSRGPAGPPGKAGEDGHPGKPGRPGERGVVGPQGARGFPGTPGLPGFKGIRGHNGLDGLKGQPGAQGVKGEPGAPGENGTPGQAGARGLPGERGRVGAPGPAGARGSDGSVGPVGPAGPIGSAGPPGFPGAPGPKGELGPVGNPGPAGPAGPRGEAGLPGLSGPVGPPGNPGANGLTGAKGATGLPGVAGAPGLPGPRGIPGPVGAAGATGPRGLVGEPGPAGSKGETGNKGEPGSAGAQGPPGPSGEEGKRGSPGEPGSAGPAGPPGLRGSPGSRGLPGADGRAGVMGPPGNRGSTGPAGVRGPNGDAGRPGEPGLMGPRGLPGSPGNVGPAGKEGPVGLPGIDGRPGPIGPAGPRGEAGNIGFPGPKGPSGDPGKPGEKGHPGLAGARGAPGPDGNNGAQGPPGPQGVQGGKGEQGPAGPPGFQGLPGPSGTAGEVGKPGERGLPGEFGLPGPAGPRGERGPPGESGAAGPSGPIGSRGPSGAAGPDGNKGEAGAVGAPGSAGASGPGGLPGERGAAGIPGGKGEKGETGLRGEIGNPGRDGARGAPGAIGAPGPAGASGDRGEAGAAGPSGPAGPRGSPGERGEVGPAGPNGFAGPAGSAGQPGAKGEKGTKGPKGENGIVGPTGPVGAAGPSGPNGPPGPAGTRGDGGPPGMTGFPGAAGRTGPPGPSGITGPPGPPGAAGKEGIRGPRGDQGPVGRTGEIGASGPPGFAGEKGPSGEPGTAGPPGTAGPQGLLGAPGILGLPGSRGERGLPGIAGALGEPGPLGIAGPPGARGPPGAVGSPGVNGAPGEAGRDGNPGSDGPPGRDGQPGHKGERGYPGNIGPTGAAGAPGPHGSVGPAGKHGNRGEPGPAGSVGPVGAVGPRGPSGPQGIRGDKGEPGDKGARGLPGLKGHNGLQGLPGLAGLHGDQGAPGPVGPAGPRGPAGPSGPVGKDGRSGHPGPVGPAGVRGSQGSQGPAGPPGPPGPPGPPGVSGGGYDFGFEGDFYRADQPRSQPSLRPKDYEVDATLKSLNNQIETLLTPEGSKKNPARTCRDLRLSHPEWKSDYYWIDPNQGCTMDAIKVYCDFSTGETCIQAQPVNTPAKNAYSRAQANKHVWLGETINGGSQFEYNAEGVSSKEMATQLAFMRLLANRASQNITYHCKNSIAYLDEETGRLNKAVILQGSNDVELVAEGNSRFTYTVLVDGCSKKTNEWDKTIIEYKTNKPSRLPFLDIAPLDIGGANQEFRVEVGPVCFK
>NP_445756.1 OS=Rattus norvegicus OX=10116 GN=COL1A1
MFSFVDLRLLLLLGATALLTHGQEDIPEVSCIHNGLRVPNGETWKPDVCLICICHNGTAVCDGVLCKEDLDCPNPQKREGECCPFCPEEYVSPDAEVIGVEGPKGDPGPQGPRGPVGPPGQDGIPGQPGLPGPPGPPGPPGPPGLGGNFASQMSYGYDEKSAGVSVPGPMGPSGPRGLPGPPGAPGPQGFQGPPGEPGEPGASGPMGPRGPPGPPGKNGDDGEAGKPGRPGERGPPGPQGARGLPGTAGLPGMKGHRGFSGLDGAKGDTGPAGPKGEPGSPGENGAPGQMGPRGLPGERGRPGPPGSAGARGNDGAVGAAGPPGPTGPTGPPGFPGAAGAKGEAGPQGARGSEGPQGVRGEPGPPGPAGAAGPAGNPGADGQPGAKGANGAPGIAGAPGFPGARGPSGPQGPSGAPGPKGNSGEPGAPGNKGDTGAKGEPGPAGVQGPPGPAGEEGKRGARGEPGPSGLPGPPGERGGPGSRGFPGADGVAGPKGPAGERGSPGPAGPKGSPGEAGRPGEAGLPGAKGLTGSPGSPGPDGKTGPPGPAGQDGRPGPAGPPGARGQAGVMGFPGPKGTAGEPGKAGERGVPGPPGAVGPAGKDGEAGAQGAPGPAGPAGERGEQGPAGSPGFQGLPGPAGPPGEAGKPGEQGVPGDLGAPGPSGARGERGFPGERGVQGPPGPAGPRGNNGAPGNDGAKGDTGAPGAPGSQGAPGLQGMPGERGAAGLPGPKGDRGDAGPKGADGSPGKDGVRGLTGPIGPPGPAGAPGDKGETGPSGPAGPTGARGAPGDRGEPGPPGPAGFAGPPGADGQPGAKGEPGDTGVKGDAGPPGPAGPAGPPGPIGNVGAPGPKGSRGAAGPPGATGFPGAAGRVGPPGPSGNAGPPGPPGPVGKEGGKGPRGETGPAGRPGEVGPPGPPGPAGEKGSPGADGPAGSPGTPGPQGIAGQRGVVGLPGQRGERGFPGLPGPSGEPGKQGPSGASGERGPPGPMGPPGLAGPPGESGREGSPGAEGSPGRDGAPGAKGDRGETGPAGPPGAPGAPGAPGPVGPAGKNGDRGETGPAGPAGPIGPAGARGPAGPQGPRGDKGETGEQGDRGIKGHRGFSGLQGPPGSPGSPGEQGPSGASGPAGPRGPPGSAGSPGKDGLNGLPGPIGPPGPRGRTGDSGPAGPPGPPGPPGPPGPPSGGYDFSFLPQPPQEKSQDGGRYYRADDANVVRDRDLEVDTTLKSLSQQIENIRSPEGSRKNPARTCRDLKMCHSDWKSGEYWIDPNQGCNLDAIKVYCNMETGQTCVFPTQPSVPQKNWYISPNPKEKKHVWFGESMTDGFQFEYGSEGSDPADVAIQLTFLRLMSTEASQNITYHCKNSVAYMDQQTGNLKKSLLLQGSNEIELRGEGNSRFTYSTLVDGCTSHTGTWGKTVIEYKTTKTSRLPIIDVAPLDIGAPDQEFGMDIGPACFV
>NP_445808.2 OS=Rattus norvegicus OX=10116 GN=COL1A2
MLSFVDTRTLLLLAVTSCLATCQSLQMGSVRKGPTGDRGPRGQRGPAGPRGRDGVDGPVGPPGPPGAPGPPGPPGPPGLTGNFAAQYSDKGVSAGPGPMGLMGPRGPPGAVGAPGPQGFQGPAGEPGEPGQTGPAGSRGPAGPPGKAGEDGHPGKPGRPGERGVVGPQGARGFPGTPGLPGFKGIRGHNGLDGLKGQPGAQGVKGEPGAPGENGTPGQAGARGLPGERGRVGAPGPAGARGSDGSVGPVGPAGPIGSAGPPGFPGAPGPKGELGPVGNPGPAGPAGPRGEAGLPGLSGPVGPPGNPGANGLTGAKGATGLPGVAGAPGLPGPRGIPGPVGAAGATGPRGLVGEPGPAGSKGETGNKGEPGSAGAQGPPGPSGEEGKRGSPGEPGSAGPAGPPGLRGSPGSRGLPGADGRAGVMGPPGNRGSTGPAGVRGPNGDAGRPGEPGLMGPRGLPGSPGNVGPAGKEGPVGLPGIDGRPGPIGPAGPRGEAGNIGFPGPKGPSGDPGKPGEKGHPGLAGARGAPGPDGNNGAQGPPGPQGVQGGKGEQGPAGPPGFQGLPGPSGTAGEVGKPGERGLPGEFGLPGPAGPRGERGPPGESGAAGPSGPIGSRGPSGAPGPDGNKGEAGAVGAPGSAGASGPGGLPGERGAAGIPGGKGEKGETGLRGEIGNPGRDGARGAPGAIGAPGPAGASGDRGEAGAAGPSGPAGPRGSPGERGEVGPAGPNGFAGPAGSAGQPGAKGEKGTKGPKGENGIVGPTGPVGAAGPSGPNGPPGPAGSRGDGGPPGMTGFPGAAGRTGPPGPSGITGPPGPPGAAGKEGIRGPRGDQGPVGRTGEIGASGPPGFAGEKGPSGEPGTTGPPGTAGPQGLLGAPGILGLPGSRGERGLPGIAGALGEPGPLGIAGPPGARGPPGAVGSPGVNGAPGEAGRDGNPGSDGPPGRDGQPGHKGERGYPGNIGPTGAAGAPGPHGSVGPAGKHGNRGEPGPAGSVGPVGAVGPRGPSGPQGIRGDKGEPGDKGARGLPGLKGHNGLQGLPGLAGLHGDQGAPGPVGPAGPRGPAGPSGPIGKDGRSGHPGPVGPAGVRGSQGSQGPAGPPGPPGPPGPPGVSGGGYDFGFEGDFYRADQPRSQPSLRPKDYEVDATLKSLNNQIETLLTPEGSRKNPARTCRDLRLSHPEWKSDYYWIDPNQGCTMDAIKVYCDFSTGETCIQAQPVNTPAKNAYSRAQANKHVWLGETINGGSQFEYNAEGVSSKEMATQLAFMRLLANRASQNITYHCKNSIAYLDEETGRLNKAVILQGSNDVELVAEGNSRFTYTVLVDGCSKKTNEWDKTIIEYKTNKPSRLPFLDIAPLDIGGTNQEFRVEVGPVCFK
Taxon name Sequence PTM Marker Gene
Meles meles GLPGEFGLPGPAGPR 2H COL1A2-484/B COL1A2
Meles meles GLPGVSGSVGEPGPLGIAGPPGAR 3H COL1A2-793/D COL1A2
Meles meles GLTGPIGPPGPAGAPGDKGEAGPSGPAGPTGAR 2H COL1A1-586/F COL1A1
Meles meles GLTGPIGPPGPAGAPGDKGEAGPSGPAGPTGAR 3H COL1A1-586/F COL1A1
Meles meles GPNGEAGSTGPSGPPGLR 2H COL1A2-292/P2 COL1A2
Meles meles GPPGESGAAGPSGPIGSR 1H COL1A2-502/C COL1A2
Meles meles GPSGEAGTAGPPGTPGPQGLLGAPGILGLPGSR 4H COL1A2-757/G COL1A2
Meles meles GPSGEAGTAGPPGTPGPQGLLGAPGILGLPGSR 5H COL1A2-757/G COL1A2
Meles meles GVQGPPGPAGPR 1H COL1A1-508/P1 COL1A1
Meles meles TGHPGTVGPAGIR 0H COL1A2-978/A COL1A2
Meles meles TGHPGTVGPAGIR 1H COL1A2-978/A COL1A2
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment