aboutsummaryrefslogtreecommitdiff
path: root/uploader/templates/populations
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2024-09-23 14:30:15 -0500
committerFrederick Muriuki Muriithi2024-09-23 16:35:39 -0500
commit4285cc10e24d6410206329ba079406e9aa21cc30 (patch)
tree70f785460b14731634d0a4bd93ad5bbb9c5ba833 /uploader/templates/populations
parent0b37b9b3fa4fead86787a705713645fa14530a54 (diff)
downloadgn-uploader-4285cc10e24d6410206329ba079406e9aa21cc30.tar.gz
Move R/qtl2 upload code under the populations package.
Diffstat (limited to 'uploader/templates/populations')
-rw-r--r--uploader/templates/populations/rqtl2/create-tissue-success.html106
-rw-r--r--uploader/templates/populations/rqtl2/index.html54
-rw-r--r--uploader/templates/populations/rqtl2/no-such-job.html13
-rw-r--r--uploader/templates/populations/rqtl2/rqtl2-job-error.html39
-rw-r--r--uploader/templates/populations/rqtl2/rqtl2-job-results.html24
-rw-r--r--uploader/templates/populations/rqtl2/rqtl2-job-status.html20
-rw-r--r--uploader/templates/populations/rqtl2/rqtl2-qc-job-error.html120
-rw-r--r--uploader/templates/populations/rqtl2/rqtl2-qc-job-results.html66
-rw-r--r--uploader/templates/populations/rqtl2/rqtl2-qc-job-status.html41
-rw-r--r--uploader/templates/populations/rqtl2/rqtl2-qc-job-success.html37
-rw-r--r--uploader/templates/populations/rqtl2/select-geno-dataset.html69
-rw-r--r--uploader/templates/populations/rqtl2/select-population.html57
-rw-r--r--uploader/templates/populations/rqtl2/select-probeset-dataset.html191
-rw-r--r--uploader/templates/populations/rqtl2/select-probeset-study-id.html143
-rw-r--r--uploader/templates/populations/rqtl2/select-tissue.html115
-rw-r--r--uploader/templates/populations/rqtl2/summary-info.html65
-rw-r--r--uploader/templates/populations/rqtl2/upload-rqtl2-bundle-step-01.html276
-rw-r--r--uploader/templates/populations/rqtl2/upload-rqtl2-bundle-step-02.html33
18 files changed, 1469 insertions, 0 deletions
diff --git a/uploader/templates/populations/rqtl2/create-tissue-success.html b/uploader/templates/populations/rqtl2/create-tissue-success.html
new file mode 100644
index 0000000..d6fe154
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/create-tissue-success.html
@@ -0,0 +1,106 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+
+{%block title%}Upload R/qtl2 Bundle{%endblock%}
+
+{%block contents%}
+<h2 class="heading">Select Tissue</h2>
+
+<div class="row">
+ <p>You have successfully added a new tissue, organ or biological material with
+ the following details:</p>
+</div>
+
+<div class="row">
+ {{flash_all_messages()}}
+
+ <form id="frm-create-tissue-display"
+ method="POST"
+ action="#">
+ <legend class="heading">Create Tissue</legend>
+
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id"
+ value="{{population.InbredSetId}}" />
+ <input type="hidden" name="rqtl2_bundle_file" value="{{rqtl2_bundle_file}}" />
+ <input type="hidden" name="geno-dataset-id" value="{{geno_dataset.Id}}" />
+ <input type="hidden" name="tissueid" value="{{tissue.Id}}" />
+
+ <div class="form-group">
+ <label>Name</label>
+ <label>{{tissue.TissueName}}</label>
+ </div>
+
+ <div class="form-group">
+ <label>Short Name</label>
+ <label>{{tissue.Short_Name}}</label>
+ </div>
+
+ {%if tissue.BIRN_lex_ID%}
+ <div class="form-group">
+ <label>BIRN Lex ID</label>
+ <label>{{tissue.BIRN_lex_ID}}</label>
+ </div>
+ {%endif%}
+
+ {%if tissue.BIRN_lex_Name%}
+ <div class="form-group">
+ <label>BIRN Lex Name</label>
+ <label>{{tissue.BIRN_lex_Name}}</label>
+ </div>
+ {%endif%}
+ </form>
+
+ <div id="action-buttons"
+ style="width:65ch;display:inline-grid;column-gap:5px;">
+
+ <form id="frm-create-tissue-success-continue"
+ method="POST"
+ action="{{url_for('expression-data.rqtl2.select_dataset_info',
+ species_id=species.SpeciesId,
+ population_id=population.InbredSetId)}}"
+ style="display: inline; width: 100%; grid-column: 1 / 2;
+ padding-top: 0.5em; text-align: center; border: none;
+ background-color: inherit;">
+
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id"
+ value="{{population.InbredSetId}}" />
+ <input type="hidden" name="rqtl2_bundle_file" value="{{rqtl2_bundle_file}}" />
+ <input type="hidden" name="geno-dataset-id" value="{{geno_dataset.Id}}" />
+ <input type="hidden" name="tissueid" value="{{tissue.Id}}" />
+
+ <button type="submit" class="btn btn-primary">continue</button>
+ </form>
+ </div>
+</div>
+
+<div class="row">
+ <p style="display:inline;width:100%;grid-column:2/3;text-align:center;
+ color:#336699;font-weight:bold;">
+ OR
+ </p>
+</div>
+
+<div class="row">
+ <form id="frm-create-tissue-success-select-existing"
+ method="POST"
+ action="{{url_for('expression-data.rqtl2.select_tissue',
+ species_id=species.SpeciesId,
+ population_id=population.InbredSetId)}}"
+ style="display: inline; width: 100%; grid-column: 3 / 4;
+ padding-top: 0.5em; text-align: center; border: none;
+ background-color: inherit;">
+
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id"
+ value="{{population.InbredSetId}}" />
+ <input type="hidden" name="rqtl2_bundle_file" value="{{rqtl2_bundle_file}}" />
+ <input type="hidden" name="geno-dataset-id" value="{{geno_dataset.Id}}" />
+
+ <button type="submit" class="btn btn-primary">
+ select from existing tissues</button>
+ </form>
+</div>
+
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/index.html b/uploader/templates/populations/rqtl2/index.html
new file mode 100644
index 0000000..ec6ffb8
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/index.html
@@ -0,0 +1,54 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_messages%}
+
+{%block title%}Data Upload{%endblock%}
+
+{%block contents%}
+<h1 class="heading">R/qtl2 data upload</h1>
+
+<h2>R/qtl2 Upload</h2>
+
+<div class="row">
+ <form method="POST" action="{{url_for('expression-data.rqtl2.select_species')}}"
+ id="frm-rqtl2-upload">
+ <legend class="heading">upload R/qtl2 bundle</legend>
+ {{flash_messages("error-rqtl2")}}
+
+ <div class="form-group">
+ <label for="select:species" class="form-label">Species</label>
+ <select id="select:species"
+ name="species_id"
+ required="required"
+ class="form-control">
+ <option value="">Select species</option>
+ {%for spec in species%}
+ <option value="{{spec.SpeciesId}}">{{spec.MenuName}}</option>
+ {%endfor%}
+ </select>
+ <small class="form-text text-muted">
+ Data that you upload to the system should belong to a know species.
+ Here you can select the species that you wish to upload data for.
+ </small>
+ </div>
+
+ <input type="submit" class="btn btn-primary" value="submit" />
+ </form>
+</div>
+
+<div class="row">
+ <h2 class="heading">R/qtl2 Bundles</h2>
+
+ <div class="explainer">
+ <p>This feature combines and extends the two upload methods below. Instead of
+ uploading one item at a time, the R/qtl2 bundle you upload can contain both
+ the genotypes data (samples/individuals/cases and their data) and the
+ expression data.</p>
+ <p>The R/qtl2 bundle, additionally, can contain extra metadata, that neither
+ of the methods below can handle.</p>
+
+ <a href="{{url_for('expression-data.rqtl2.select_species')}}"
+ title="Upload a zip bundle of R/qtl2 files">
+ <button class="btn btn-primary">upload R/qtl2 bundle</button></a>
+ </div>
+</div>
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/no-such-job.html b/uploader/templates/populations/rqtl2/no-such-job.html
new file mode 100644
index 0000000..b17004f
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/no-such-job.html
@@ -0,0 +1,13 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_messages%}
+
+{%block title%}Job Status{%endblock%}
+
+{%block contents%}
+<h1 class="heading">R/qtl2 job status</h1>
+
+<h2>R/qtl2 Upload: No Such Job</h2>
+
+<p class="alert-danger">No job with ID {{jobid}} was found.</p>
+
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/rqtl2-job-error.html b/uploader/templates/populations/rqtl2/rqtl2-job-error.html
new file mode 100644
index 0000000..9817518
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/rqtl2-job-error.html
@@ -0,0 +1,39 @@
+{%extends "base.html"%}
+{%from "cli-output.html" import cli_output%}
+
+{%block title%}Job Status{%endblock%}
+
+{%block contents%}
+<h1 class="heading">R/qtl2 job status</h1>
+
+<h2>R/qtl2 Upload: Job Status</h2>
+
+<div class="explainer">
+ <p>The processing of the R/qtl2 bundle you uploaded has failed. We have
+ provided some information below to help you figure out what the problem
+ could be.</p>
+ <p>If you find that you cannot figure out what the problem is on your own,
+ please contact the team running the system for assistance, providing the
+ following details:
+ <ul>
+ <li>R/qtl2 bundle you uploaded</li>
+ <li>This URL: <strong>{{request_url()}}</strong></li>
+ <li>(maybe) a screenshot of this page</li>
+ </ul>
+ </p>
+</div>
+
+<h4>stdout</h4>
+{{cli_output(job, "stdout")}}
+
+<h4>stderr</h4>
+{{cli_output(job, "stderr")}}
+
+<h4>Log</h4>
+<div class="cli-output">
+ {%for msg in messages%}
+ {{msg}}<br />
+ {%endfor%}
+</div>
+
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/rqtl2-job-results.html b/uploader/templates/populations/rqtl2/rqtl2-job-results.html
new file mode 100644
index 0000000..4ecd415
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/rqtl2-job-results.html
@@ -0,0 +1,24 @@
+{%extends "base.html"%}
+{%from "cli-output.html" import cli_output%}
+
+{%block title%}Job Status{%endblock%}
+
+{%block contents%}
+<h1 class="heading">R/qtl2 job status</h1>
+
+<h2>R/qtl2 Upload: Job Status</h2>
+
+<div class="explainer">
+ <p>The processing of the R/qtl2 bundle you uploaded has completed
+ successfully.</p>
+ <p>You should now be able to use GeneNetwork to run analyses on your data.</p>
+</div>
+
+<h4>Log</h4>
+<div class="cli-output">
+ {%for msg in messages%}
+ {{msg}}<br />
+ {%endfor%}
+</div>
+
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/rqtl2-job-status.html b/uploader/templates/populations/rqtl2/rqtl2-job-status.html
new file mode 100644
index 0000000..e896f88
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/rqtl2-job-status.html
@@ -0,0 +1,20 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_messages%}
+
+{%block title%}Job Status{%endblock%}
+
+{%block extrameta%}
+<meta http-equiv="refresh" content="3">
+{%endblock%}
+
+{%block contents%}
+<h1 class="heading">R/qtl2 job status</h1>
+
+<h2>R/qtl2 Upload: Job Status</h2>
+
+<h4>Log</h4>
+<div class="cli-output">
+ <pre>{{"\n".join(messages)}}</pre>
+</div>
+
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/rqtl2-qc-job-error.html b/uploader/templates/populations/rqtl2/rqtl2-qc-job-error.html
new file mode 100644
index 0000000..90e8887
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/rqtl2-qc-job-error.html
@@ -0,0 +1,120 @@
+{%extends "base.html"%}
+{%from "cli-output.html" import cli_output%}
+
+{%block title%}R/qtl2 bundle: QC Job Error{%endblock%}
+
+{%macro errors_table(tableid, errors)%}
+<table id="{{tableid}}" class="table error-table">
+ <caption>{{caption}}</caption>
+ <thead>
+ <tr>
+ <th>Line</th>
+ <th>Column</th>
+ <th>Value</th>
+ <th>Message</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for error in errors%}
+ <tr>
+ <td>{{error.line}}</td>
+ <td>{{error.column}}</td>
+ <td>{{error.value}}</td>
+ <td>{{error.message}}</td>
+ </tr>
+ {%else%}
+ <tr>
+ <td colspan="4">No errors to display here.</td>
+ </tr>
+ {%endfor%}
+ </tbody>
+</table>
+{%endmacro%}
+
+{%block contents%}
+<h1 class="heading">R/qtl2 bundle: QC job Error</h1>
+
+<div class="explainer">
+ <p>The R/qtl2 bundle has failed some <emph>Quality Control</emph> checks.</p>
+ <p>We list below some of the errors that need to be fixed before the data can
+ be uploaded onto GeneNetwork.</p>
+</div>
+
+{%if errorsgeneric | length > 0%}
+<h2 class="heading">Generic Errors ({{errorsgeneric | length}})</h3>
+<div class="explainer">
+ We found the following generic errors in your R/qtl2 bundle:
+</div>
+
+<h3>Missing Files</h3>
+<div class="explainer">
+ <p>These files are listed in the bundle's control file, but do not actually
+ exist in the bundle</p>
+</div>
+<table id="tbl-errors-missing-files" class="table error-table">
+ <thead>
+ <tr>
+ <th>Control File Key</th>
+ <th>Bundle File Name</th>
+ <th>Message</th>
+ </tr>
+ </thead>
+ <tbody>
+ {%for error in (errorsgeneric | selectattr("type", "equalto", "MissingFile"))%}
+ <tr>
+ <td>{{error.controlfilekey}}</td>
+ <td>{{error.filename}}</td>
+ <td>{{error.message}}</td>
+ </tr>
+ {%endfor%}
+ </tbody>
+</table>
+
+<h3>Other Generic Errors</h3>
+{{errors_table("tbl-errors-generic", errorsgeneric| selectattr("type", "ne", "MissingFile"))}}
+{%endif%}
+
+{%if errorsgeno | length > 0%}
+<h2 class="heading">Geno Errors ({{errorsgeno | length}})</h3>
+<div class="explainer">
+ We found the following errors in the 'geno' file in your R/qtl2 bundle:
+</div>
+{{errors_table("tbl-errors-geno", errorsgeno[0:50])}}
+{%endif%}
+
+{%if errorspheno | length > 0%}
+<h2 class="heading">Pheno Errors ({{errorspheno | length}})</h3>
+<div class="explainer">
+ We found the following errors in the 'pheno' file in your R/qtl2 bundle:
+</div>
+{{errors_table("tbl-errors-pheno", errorspheno[0:50])}}
+{%endif%}
+
+{%if errorsphenose | length > 0%}
+<h2 class="heading">Phenose Errors ({{errorsphenose | length}})</h3>
+<div class="explainer">
+ We found the following errors in the 'phenose' file in your R/qtl2 bundle:
+</div>
+{{errors_table("tbl-errors-phenose", errorsphenose[0:50])}}
+{%endif%}
+
+{%if errorsphenocovar | length > 0%}
+<h2 class="heading">Phenocovar Errors ({{errorsphenocovar | length}})</h3>
+<div class="explainer">
+ We found the following errors in the 'phenocovar' file in your R/qtl2 bundle:
+</div>
+{{errorsphenocovar}}
+{%endif%}
+
+<h4>stdout</h4>
+{{cli_output(job, "stdout")}}
+
+<h4>stderr</h4>
+{{cli_output(job, "stderr")}}
+
+<h4>Log</h4>
+<div class="cli-output">
+ <pre>{{"\n".join(messages)}}</pre>
+</div>
+
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/rqtl2-qc-job-results.html b/uploader/templates/populations/rqtl2/rqtl2-qc-job-results.html
new file mode 100644
index 0000000..b3c3a8f
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/rqtl2-qc-job-results.html
@@ -0,0 +1,66 @@
+{%extends "base.html"%}
+{%from "cli-output.html" import cli_output%}
+
+{%block title%}R/qtl2 bundle: QC job results{%endblock%}
+
+{%block contents%}
+<h1 class="heading">R/qtl2 bundle: QC job results</h1>
+
+<div class="row">
+ <p>The R/qtl2 bundle you uploaded has passed all automated quality-control
+ checks successfully.</p>
+ <p>You may now continue to load the data into GeneNetwork for the bundle, with
+ the following details:</p>
+</div>
+
+<div class="row">
+ <form id="form-qc-job-results"
+ action="{{url_for('expression-data.rqtl2.select_dataset_info',
+ species_id=species.SpeciesId,
+ population_id=population.Id)}}"
+ method="POST">
+ <div class="form-group">
+ <legend>Species</legend>
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+
+ <span class="form-label">Name</span>
+ <span class="form-text">{{species.Name | capitalize}}</span>
+
+ <span class="form-label">Scientific</span>
+ <span class="form-text">{{species.FullName | capitalize}}</span>
+ </div>
+
+ <div class="form-group">
+ <legend>population</legend>
+ <input type="hidden" name="population_id" value="{{population.Id}}" />
+
+ <span class="form-label">Name</span>
+ <span class="form-text">{{population.InbredSetName}}</span>
+
+ <span class="form-label">Full Name</span>
+ <span class="form-text">{{population.FullName}}</span>
+
+ <span class="form-label">Genetic Type</span>
+ <span class="form-text">{{population.GeneticType}}</span>
+
+ <span class="form-label">Description</span>
+ <span class="form-text">{{population.Description or "-"}}</span>
+ </div>
+
+ <div class="form-group">
+ <legend>R/qtl2 Bundle File</legend>
+ <input type="hidden" name="rqtl2_bundle_file" value="{{rqtl2bundle}}" />
+ <input type="hidden" name="original-filename" value="{{rqtl2bundleorig}}" />
+
+ <span class="form-label">Original Name</span>
+ <span class="form-text">{{rqtl2bundleorig}}</span>
+
+ <span class="form-label">Internal Name</span>
+ <span class="form-text">{{rqtl2bundle[0:25]}}&hellip;</span>
+ </div>
+
+ <button type="submit" class="btn btn-primary">continue</button>
+ </form>
+</div>
+
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/rqtl2-qc-job-status.html b/uploader/templates/populations/rqtl2/rqtl2-qc-job-status.html
new file mode 100644
index 0000000..f4a6266
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/rqtl2-qc-job-status.html
@@ -0,0 +1,41 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_messages%}
+
+{%block title%}Job Status{%endblock%}
+
+{%block extrameta%}
+<meta http-equiv="refresh" content="3">
+{%endblock%}
+
+{%block contents%}
+<h1 class="heading">R/qtl2 bundle: QC job status</h1>
+
+{%if geno_percent%}
+<p>
+ <h2>Checking 'geno' file:</h2>
+ <progress id="prg-geno-checking" value="{{geno_percent}}" max="100">
+ {{geno_percent}}%</progress>
+ {{geno_percent}}%</p>
+{%endif%}
+
+{%if pheno_percent%}
+<p>
+ <h2>Checking 'pheno' file:</h2>
+ <progress id="prg-pheno-checking" value="{{pheno_percent}}" max="100">
+ {{pheno_percent}}%</progress>
+ {{pheno_percent}}%</p>
+{%endif%}
+
+{%if phenose_percent%}
+<p>
+ <h2>Checking 'phenose' file:</h2>
+ <progress id="prg-phenose-checking" value="{{phenose_percent}}" max="100">
+ {{phenose_percent}}%</progress>
+ {{phenose_percent}}%</p>
+{%endif%}
+
+<h4>Log</h4>
+<div class="cli-output">
+ <pre>{{"\n".join(messages)}}</pre>
+</div>
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/rqtl2-qc-job-success.html b/uploader/templates/populations/rqtl2/rqtl2-qc-job-success.html
new file mode 100644
index 0000000..f126835
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/rqtl2-qc-job-success.html
@@ -0,0 +1,37 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+
+{%block title%}R/qtl2 Bundle: Quality Control Successful{%endblock%}
+
+{%block contents%}
+<h2 class="heading">R/qtl2 Bundle: Quality Control Successful</h2>
+
+<div class="row">
+ <p>The R/qtl2 bundle you uploaded has passed <emph>all</emph> quality control
+ checks successfully, and is now ready for uploading into the database.</p>
+ <p>Click "Continue" below to proceed.</p>
+</div>
+
+<!--
+ The "action" on this form takes us to the next step, where we can
+ select all the other data necessary to enter the data into the database.
+ -->
+<div class="row">
+ <form id="frm-upload-rqtl2-bundle"
+ action="{{url_for('expression-data.rqtl2.select_dataset_info',
+ species_id=species.SpeciesId,
+ population_id=population.InbredSetId)}}"
+ method="POST"
+ enctype="multipart/form-data">
+ {{flash_all_messages()}}
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id"
+ value="{{population.InbredSetId}}" />
+ <input type="hidden" name="rqtl2_bundle_file"
+ value="{{rqtl2_bundle_file}}" />
+
+ <button type="submit" class="btn btn-primary">continue</button>
+ </form>
+</div>
+
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/select-geno-dataset.html b/uploader/templates/populations/rqtl2/select-geno-dataset.html
new file mode 100644
index 0000000..3233abc
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/select-geno-dataset.html
@@ -0,0 +1,69 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_messages%}
+
+{%block title%}Upload R/qtl2 Bundle{%endblock%}
+
+{%block contents%}
+<h2 class="heading">Select Genotypes Dataset</h2>
+
+<div class="row">
+ <p>Your R/qtl2 files bundle could contain a "geno" specification. You will
+ therefore need to select from one of the existing Genotype datasets or
+ create a new one.</p>
+ <p>This is the dataset where your data will be organised under.</p>
+</div>
+
+<div class="row">
+ <form id="frm-upload-rqtl2-bundle"
+ action="{{url_for('expression-data.rqtl2.select_geno_dataset',
+ species_id=species.SpeciesId,
+ population_id=population.InbredSetId)}}"
+ method="POST"
+ enctype="multipart/form-data">
+ <legend class="heading">select from existing genotype datasets</legend>
+
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id"
+ value="{{population.InbredSetId}}" />
+ <input type="hidden" name="rqtl2_bundle_file"
+ value="{{rqtl2_bundle_file}}" />
+
+ {{flash_messages("error-rqtl2-select-geno-dataset")}}
+
+ <div class="form-group">
+ <legend>Datasets</legend>
+ <label for="select:geno-datasets" class="form-label">Dataset</label>
+ <select id="select:geno-datasets"
+ name="geno-dataset-id"
+ required="required"
+ {%if datasets | length == 0%}
+ disabled="disabled"
+ {%endif%}
+ class="form-control"
+ aria-describedby="help-geno-dataset-select-dataset">
+ <option value="">Select dataset</option>
+ {%for dset in datasets%}
+ <option value="{{dset['Id']}}">{{dset["Name"]}} ({{dset["FullName"]}})</option>
+ {%endfor%}
+ </select>
+ <span id="help-geno-dataset-select-dataset" class="form-text text-muted">
+ Select from the existing genotype datasets for species
+ {{species.SpeciesName}} ({{species.FullName}}).
+ </span>
+ </div>
+
+ <button type="submit" class="btn btn-primary">select dataset</button>
+ </form>
+</div>
+
+<div class="row">
+ <p>If the genotype dataset you need does not currently exist for your dataset,
+ go the <a href="{{url_for(
+ 'species.populations.genotypes.create_dataset',
+ species_id=species.SpeciesId,
+ population_id=population.Id)}}"
+ title="Create a new genotypes dataset for {{species.FullName}}">
+ genotypes page to create the genotype dataset</a></p>
+</div>
+
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/select-population.html b/uploader/templates/populations/rqtl2/select-population.html
new file mode 100644
index 0000000..ded425f
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/select-population.html
@@ -0,0 +1,57 @@
+{%extends "expression-data/index.html"%}
+{%from "flash_messages.html" import flash_messages%}
+{%from "species/macro-display-species-card.html" import display_species_card%}
+
+{%block title%}Select Grouping/Population{%endblock%}
+
+{%block contents%}
+<h1 class="heading">Select grouping/population</h1>
+
+<div class="row">
+ <p>The data is organised in a hierarchical form, beginning with
+ <em>species</em> at the very top. Under <em>species</em> the data is
+ organised by <em>population</em>, sometimes referred to as <em>grouping</em>.
+ (In some really old documents/systems, you might see this referred to as
+ <em>InbredSet</em>.)</p>
+ <p>In this section, you get to define what population your data is to be
+ organised by.</p>
+</div>
+
+<div class="row">
+ <form method="POST"
+ action="{{url_for('expression-data.rqtl2.select_population',
+ species_id=species.SpeciesId)}}">
+ <legend class="heading">select grouping/population</legend>
+ {{flash_messages("error-select-population")}}
+
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+
+ <div class="form-group">
+ <label for="select:inbredset" class="form-label">population</label>
+ <select id="select:inbredset"
+ name="inbredset_id"
+ required="required"
+ class="form-control">
+ <option value="">Select a grouping/population</option>
+ {%for pop in populations%}
+ <option value="{{pop.InbredSetId}}">
+ {{pop.InbredSetName}} ({{pop.FullName}})</option>
+ {%endfor%}
+ </select>
+ <span class="form-text text-muted">Select the population for your data from
+ the list below.</span>
+ </div>
+
+ <button type="submit" class="btn btn-primary" />select population</button>
+</form>
+</div>
+
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_species_card(species)}}
+{%endblock%}
+
+
+{%block javascript%}
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/select-probeset-dataset.html b/uploader/templates/populations/rqtl2/select-probeset-dataset.html
new file mode 100644
index 0000000..74f8f69
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/select-probeset-dataset.html
@@ -0,0 +1,191 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_messages%}
+
+{%block title%}Upload R/qtl2 Bundle{%endblock%}
+
+{%block contents%}
+<h2 class="heading">Phenotype(ProbeSet) Dataset</h2>
+
+<div class="row">
+ <p>The R/qtl2 bundle you uploaded contains (a) "<strong>pheno</strong>"
+ file(s). This data needs to be organised under a dataset.</p>
+ <p>This page gives you the ability to do that.</p>
+</div>
+
+{%if datasets | length > 0%}
+<div class="row">
+ <form method="POST"
+ action="{{url_for('expression-data.rqtl2.select_probeset_dataset',
+ species_id=species.SpeciesId, population_id=population.Id)}}"
+ id="frm:select-probeset-dataset">
+ <legend class="heading">Select from existing ProbeSet datasets</legend>
+ {{flash_messages("error-rqtl2")}}
+
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id"
+ value="{{population.InbredSetId}}" />
+ <input type="hidden" name="rqtl2_bundle_file"
+ value="{{rqtl2_bundle_file}}" />
+ <input type="hidden" name="geno-dataset-id" value="{{geno_dataset.Id}}" />
+ <input type="hidden" name="tissueid" value="{{tissue.Id}}" />
+ <input type="hidden" name="probe-study-id" value="{{probe_study.Id}}" />
+
+ <div class="form-group">
+ <label class="form-label" for="select:probe-dataset">Dataset</label>
+ <select id="select:probe-dataset"
+ name="probe-dataset-id"
+ required="required"
+ {%if datasets | length == 0%}disabled="disabled"{%endif%}
+ class="form-control"
+ aria-describedby="help-probe-dataset">
+ <option value="">Select a dataset</option>
+ {%for dataset in datasets%}
+ <option value={{dataset.Id}}>
+ {{dataset.Name}}
+ {%if dataset.FullName%}
+ -- ({{dataset.FullName}})
+ {%endif%}
+ </option>
+ {%endfor%}
+ </select>
+
+ <span id="help-probe-dataset" class="form-text text-muted">
+ Select from existing ProbeSet datasets.</span>
+ </div>
+
+ <button type="submit" class="btn btn-primary" />select dataset</button>
+</form>
+</div>
+
+<div class="row">
+ <p style="color:#FE3535; padding-left:20em; font-weight:bolder;">OR</p>
+</div>
+{%endif%}
+
+<div class="row">
+ <p>Create an entirely new ProbeSet dataset for your data.</p>
+</div>
+
+<div class="row">
+ <form method="POST"
+ action="{{url_for('expression-data.rqtl2.create_probeset_dataset',
+ species_id=species.SpeciesId, population_id=population.Id)}}"
+ id="frm:create-probeset-dataset">
+ <legend class="heading">Create a new ProbeSet dataset</legend>
+ {{flash_messages("error-rqtl2-create-probeset-dataset")}}
+
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id"
+ value="{{population.InbredSetId}}" />
+ <input type="hidden" name="rqtl2_bundle_file"
+ value="{{rqtl2_bundle_file}}" />
+ <input type="hidden" name="geno-dataset-id" value="{{geno_dataset.Id}}" />
+ <input type="hidden" name="tissueid" value="{{tissue.Id}}" />
+ <input type="hidden" name="probe-study-id" value="{{probe_study.Id}}" />
+
+ <div class="form-group">
+ <label class="form-label" for="select:average">averaging method</label>
+ <select id="select:average"
+ name="averageid"
+ required="required"
+ class="form-control"
+ aria-describedby="help-average">
+ <option value="">Select averaging method</option>
+ {%for avgmethod in avgmethods%}
+ <option value="{{avgmethod.Id}}">
+ {{avgmethod.Name}}
+ {%if avgmethod.Normalization%}
+ ({{avgmethod.Normalization}})
+ {%endif%}
+ </option>
+ {%endfor%}
+ </select>
+
+ <span id="help-average" class="form-text text-muted">
+ Select the averaging method used for your data.
+ </span>
+ </div>
+
+ <div class="form-group">
+ <label class="form-label" for="txt:datasetname">Name</label>
+ <input type="text" id="txt:datasetname" name="datasetname"
+ required="required"
+ maxlength="40"
+ title="Name of the dataset, e.g 'BXDMicroArray_ProbeSet_June03'. (Required)"
+ class="form-control"
+ aria-describedby="help-dataset-name" />
+
+ <span id="help-dataset-name" class="form-text text-muted">
+ Provide a name for the dataset e.g. "BXDMicroArray_ProbeSet_June03". This
+ is mandatory <strong>MUST</strong> be provided.
+ </span>
+ </div>
+
+ <div class="form-group">
+ <label class="form-label" for="txt:datasetfullname">Full Name</label>
+ <input type="text" id="txt:datasetfullname" name="datasetfullname"
+ required="required"
+ maxlength="100"
+ title="A longer name for the dataset, e.g. 'UTHSC Brain mRNA U74Av2 (Jun03) MAS5'. (Required)"
+ class="form-control"
+ aria-describedby="help-dataset-fullname" />
+
+ <span id="help-dataset-fullname" class="form-text text-muted">
+ Provide a longer, more descriptive name for the dataset e.g.
+ "UTHSC Brain mRNA U74Av2 (Jun03) MAS5". This is mandatory and
+ <strong>MUST</strong> be provided.
+ </span>
+ </div>
+
+ <div class="form-group">
+ <label class="form-label" for="txt:datasetshortname">Short Name</label>
+ <input type="text" id="txt:datasetshortname" name="datasetshortname"
+ maxlength="100"
+ title="An abbreviated name for the dataset, e.g 'Br_U_0603_M'. (Optional)"
+ class="form-control"
+ aria-describedby="help-dataset-shortname" />
+
+ <span id="help-dataset-shortname" class="form-text text-muted">
+ Provide a longer, more descriptive name for the dataset e.g. "Br_U_0603_M".
+ This is optional.
+ </span>
+ </div>
+
+ <div class="form-check">
+ <input type="checkbox" id="chk:public" name="datasetpublic"
+ checked="checked"
+ title="Whether or not the dataset is accessible by the general public."
+ class="form-check-input"
+ aria-describedby="help-public" />
+ <label class="form-check-label" for="chk:datasetpublic">Public?</label>
+
+ <span id="help-public" class="form-text text-muted">
+ Check to specify that the dataset will be publicly available. Uncheck to
+ limit access to the dataset.
+ </span>
+ </div>
+
+ <div class="form-group">
+ <label class="form-label" for="select:datasetdatascale">Data Scale</label>
+ <select id="select:datasetdatascale"
+ name="datasetdatascale"
+ required="required"
+ class="form-control"
+ aria-describedby="help-dataset-datascale">
+ <option value="log2" selected="selected">log2</option>
+ <option value="z_score">z_score</option>
+ <option value="log2_ratio">log2_ratio</option>
+ <option value="linear">linear</option>
+ <option value="linear_positive">linear_positive</option>
+ </select>
+
+ <span id="help-dataset-datascale" class="form-text text-muted">
+ Select from a list of scaling methods.
+ </span>
+ </div>
+
+ <button type="submit" class="btn btn-primary">create dataset</button>
+ </form>
+</div>
+
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/select-probeset-study-id.html b/uploader/templates/populations/rqtl2/select-probeset-study-id.html
new file mode 100644
index 0000000..e3fd9cc
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/select-probeset-study-id.html
@@ -0,0 +1,143 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_messages %}
+
+{%block title%}Upload R/qtl2 Bundle{%endblock%}
+
+{%block contents%}
+<h2 class="heading">Phenotype(ProbeSet) Study</h2>
+
+<div class="row">
+ <p>The R/qtl2 bundle you uploaded contains (a) "<strong>pheno</strong>"
+ file(s). This data needs to be organised under a study.</p>
+ <p>In this page, you can either select from a existing dataset:</p>
+
+ <form method="POST"
+ action="{{url_for('expression-data.rqtl2.select_probeset_study',
+ species_id=species.SpeciesId, population_id=population.Id)}}"
+ id="frm:select-probeset-study">
+ <legend class="heading">Select from existing ProbeSet studies</legend>
+ {{flash_messages("error-rqtl2-select-probeset-study")}}
+
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id"
+ value="{{population.InbredSetId}}" />
+ <input type="hidden" name="rqtl2_bundle_file"
+ value="{{rqtl2_bundle_file}}" />
+ <input type="hidden" name="geno-dataset-id" value="{{geno_dataset.Id}}" />
+ <input type="hidden" name="tissueid" value="{{tissue.Id}}" />
+
+ <div>
+ <label for="select:probe-study" class="form-label">Study</label>
+ <select id="select:probe-study"
+ name="probe-study-id"
+ required="required"
+ aria-describedby="help-select-probeset-study"
+ {%if studies | length == 0%}disabled="disabled"{%endif%}
+ class="form-control">
+ <option value="">Select a study</option>
+ {%for study in studies%}
+ <option value={{study.Id}}>
+ {{study.Name}}
+ {%if study.FullName%}
+ -- ({{study.FullName}})
+ {%endif%}
+ </option>
+ {%endfor%}
+ </select>
+ <small id="help-select-probeset-study" class="form-text text-muted">
+ Select from existing ProbeSet studies.
+ </small>
+ </div>
+
+ <button type="submit" class="btn btn-primary">select study</button>
+ </form>
+</div>
+
+<div class="row">
+ <p style="color:#FE3535; padding-left:20em; font-weight:bolder;">OR</p>
+</div>
+
+<div class="row">
+
+ <p>Create a new ProbeSet dataset below:</p>
+
+ <form method="POST"
+ action="{{url_for('expression-data.rqtl2.create_probeset_study',
+ species_id=species.SpeciesId, population_id=population.Id)}}"
+ id="frm:create-probeset-study">
+ <legend class="heading">Create new ProbeSet study</legend>
+
+ {{flash_messages("error-rqtl2-create-probeset-study")}}
+
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id"
+ value="{{population.InbredSetId}}" />
+ <input type="hidden" name="rqtl2_bundle_file"
+ value="{{rqtl2_bundle_file}}" />
+ <input type="hidden" name="geno-dataset-id" value="{{geno_dataset.Id}}" />
+ <input type="hidden" name="tissueid" value="{{tissue.Id}}" />
+
+ <div>
+ <label for="select:platform" class="form-label">Platform</label>
+ <select id="select:platform"
+ name="platformid"
+ required="required"
+ aria-describedby="help-select-platform"
+ {%if platforms | length == 0%}disabled="disabled"{%endif%}
+ class="form-control">
+ <option value="">Select a platform</option>
+ {%for platform in platforms%}
+ <option value="{{platform.GeneChipId}}">
+ {{platform.GeneChipName}} ({{platform.Name}})
+ </option>
+ {%endfor%}
+ </select>
+ <small id="help-select-platform" class="form-text text-muted">
+ Select from a list of known genomics platforms.
+ </small>
+ </div>
+
+ <div class="form-group">
+ <label for="txt:studyname" class="form-label">Study name</label>
+ <input type="text" id="txt:studyname" name="studyname"
+ placeholder="Name of the study. (Required)"
+ required="required"
+ maxlength="100"
+ class="form-control" />
+ <span class="form-text text-muted" id="help-study-name">
+ Provide a name for the study.</span>
+ </div>
+
+ <div class="form-group">
+ <label for="txt:studyfullname" class="form-label">Full Study Name</label>
+ <input type="text"
+ id="txt:studyfullname"
+ name="studyfullname"
+ placeholder="Longer name of the study. (Optional)"
+ maxlength="100"
+ class="form-control" />
+ <span class="form-text text-muted" id="help-study-full-name">
+ Provide a longer, more descriptive name for the study. This is optional
+ and you can leave it blank.
+ </span>
+ </div>
+
+ <div class="form-group">
+ <label for="txt:studyshortname" class="form-label">Short Study Name</label>
+ <input type="text"
+ id="txt:studyshortname"
+ name="studyshortname"
+ placeholder="Shorter name of the study. (Optional)"
+ maxlength="100"
+ class="form-control" />
+ <span class="form-text text-muted" id="help-study-short-name">
+ Provide a shorter name for the study. This is optional and you can leave
+ it blank.
+ </span>
+ </div>
+
+ <button type="submit" class="btn btn-primary">create study</button>
+ </form>
+</div>
+
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/select-tissue.html b/uploader/templates/populations/rqtl2/select-tissue.html
new file mode 100644
index 0000000..fe3080a
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/select-tissue.html
@@ -0,0 +1,115 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_messages%}
+
+{%block title%}Upload R/qtl2 Bundle{%endblock%}
+
+{%block contents%}
+<h2 class="heading">Tissue</h2>
+
+<div class="row">
+ <p>The data you are uploading concerns a tissue, cell, organ, or other
+ biological material used in an experiment.</p>
+ <p>Select the appropriate biological material below</p>
+</div>
+
+{%if tissues | length > 0%}
+<div class="row">
+ <form method="POST"
+ action="{{url_for('expression-data.rqtl2.select_tissue',
+ species_id=species.SpeciesId, population_id=population.Id)}}"
+ id="frm:select-probeset-dataset">
+ <legend class="heading">Select from existing ProbeSet datasets</legend>
+ {{flash_messages("error-select-tissue")}}
+
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id"
+ value="{{population.InbredSetId}}" />
+ <input type="hidden" name="rqtl2_bundle_file"
+ value="{{rqtl2_bundle_file}}" />
+ <input type="hidden" name="geno-dataset-id" value="{{geno_dataset.Id}}" />
+
+ <div class="form-group">
+ <label class="form-label" for="select-tissue">Tissue</label>
+ <select id="select-tissue"
+ name="tissueid"
+ required="required"
+ {%if tissues | length == 0%}disabled="disabled"{%endif%}
+ class="form-control"
+ aria-describedby="help-select-tissue">
+ <option value="">Select a tissue</option>
+ {%for tissue in tissues%}
+ <option value={{tissue.Id}}>
+ {{tissue.Name}}
+ {%if tissue.Short_Name%}
+ -- ({{tissue.Short_Name}})
+ {%endif%}
+ </option>
+ {%endfor%}
+ </select>
+
+ <span id="help-select-tissue" class="form-text text-muted">
+ Select from existing biological material.</span>
+ </div>
+
+ <button type="submit" class="btn btn-primary">use selected</button>
+ </form>
+</div>
+
+<div class="row">
+ <p style="color:#FE3535; padding-left:20em; font-weight:bolder;">OR</p>
+</div>
+{%endif%}
+
+<div class="row">
+ <p>If you cannot find the biological material in the drop-down above, add it
+ to the system below.</p>
+
+ <form method="POST"
+ action="{{url_for('expression-data.rqtl2.create_tissue',
+ species_id=species.SpeciesId, population_id=population.Id)}}"
+ id="frm:create-probeset-dataset">
+ <legend class="heading">Add new tissue, organ or biological material</legend>
+ {{flash_messages("error-create-tissue")}}
+
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id"
+ value="{{population.InbredSetId}}" />
+ <input type="hidden" name="rqtl2_bundle_file"
+ value="{{rqtl2_bundle_file}}" />
+ <input type="hidden" name="geno-dataset-id" value="{{geno_dataset.Id}}" />
+
+ <div class="form-group">
+ <label class="form-label" for="tissue-name">name</label>
+ <input type="text"
+ id="txt-tissuename"
+ name="tissuename"
+ required="required"
+ title = "A name to identify the tissue, organ or biological material."
+ class="form-control"
+ aria-describedby="help-tissue-name" />
+
+ <span class="form-text text-muted" id="help-tissue-name">
+ A name to identify the tissue, organ or biological material.
+ </span>
+ </div>
+
+ <div class="form-group">
+ <label for="txt-shortname" class="form-label">short name</label>
+ <input type="text" id="txt-tissueshortname" name="tissueshortname"
+ required="required"
+ maxlength="7"
+ title="A short name (e.g. 'Mam') for the biological material."
+ class="form-control"
+ aria-describedby="help-tissue-short-name" />
+
+ <span class="form-text text-muted" id="help-tissue-short-name">
+ Provide a short name for the tissue, organ or biological material used in
+ the experiment.
+ </span>
+ </div>
+
+ <button type="submit" class="btn btn-primary" />add new material</button>
+</form>
+</div>
+
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/summary-info.html b/uploader/templates/populations/rqtl2/summary-info.html
new file mode 100644
index 0000000..0adba2e
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/summary-info.html
@@ -0,0 +1,65 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_messages%}
+
+{%block title%}Upload R/qtl2 Bundle{%endblock%}
+
+{%block contents%}
+<h2 class="heading">Summary</h2>
+
+<div class="row">
+ <p>This is the information you have provided to accompany the R/qtl2 bundle
+ you have uploaded. Please verify the information is correct before
+ proceeding.</p>
+</div>
+
+<div class="row">
+ <dl>
+ <dt>Species</dt>
+ <dd>{{species.SpeciesName}} ({{species.FullName}})</dd>
+
+ <dt>Population</dt>
+ <dd>{{population.InbredSetName}}</dd>
+
+ {%if geno_dataset%}
+ <dt>Genotype Dataset</dt>
+ <dd>{{geno_dataset.Name}} ({{geno_dataset.FullName}})</dd>
+ {%endif%}
+
+ {%if tissue%}
+ <dt>Tissue</dt>
+ <dd>{{tissue.TissueName}} ({{tissue.Name}}, {{tissue.Short_Name}})</dd>
+ {%endif%}
+
+ {%if probe_study%}
+ <dt>ProbeSet Study</dt>
+ <dd>{{probe_study.Name}} ({{probe_study.FullName}})</dd>
+ {%endif%}
+
+ {%if probe_dataset%}
+ <dt>ProbeSet Dataset</dt>
+ <dd>{{probe_dataset.Name2}} ({{probe_dataset.FullName}})</dd>
+ {%endif%}
+ </dl>
+</div>
+
+<div class="row">
+ <form id="frm:confirm-rqtl2bundle-details"
+ action="{{url_for('expression-data.rqtl2.confirm_bundle_details',
+ species_id=species.SpeciesId,
+ population_id=population.InbredSetId)}}"
+ method="POST"
+ enctype="multipart/form-data">
+ <legend class="heading">Create ProbeSet dataset</legend>
+
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id"
+ value="{{population.InbredSetId}}" />
+ <input type="hidden" name="rqtl2_bundle_file" value="{{rqtl2_bundle_file}}" />
+ <input type="hidden" name="geno-dataset-id" value="{{geno_dataset.Id}}" />
+ <input type="hidden" name="probe-study-id" value="{{probe_study.Id}}" />
+ <input type="hidden" name="probe-dataset-id" value="{{probe_dataset.Id}}" />
+
+ <button type="submit" class="btn btn-primary">continue</button>
+ </form>
+</div>
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/upload-rqtl2-bundle-step-01.html b/uploader/templates/populations/rqtl2/upload-rqtl2-bundle-step-01.html
new file mode 100644
index 0000000..9d45c5f
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/upload-rqtl2-bundle-step-01.html
@@ -0,0 +1,276 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "upload_progress_indicator.html" import upload_progress_indicator%}
+
+{%block title%}Upload R/qtl2 Bundle{%endblock%}
+
+{%block contents%}
+{%macro rqtl2_file_help()%}
+<span class="form-text text-muted">
+ <p>
+ Provide a valid R/qtl2 zip file here. In particular, ensure your zip bundle
+ contains exactly one control file and the corresponding files mentioned in
+ the control file.
+ </p>
+ <p>
+ The control file can be either a YAML or JSON file. <em>ALL</em> other data
+ files in the zip bundle should be CSV files.
+ </p>
+ <p>See the
+ <a href="https://kbroman.org/qtl2/assets/vignettes/input_files.html"
+ target="_blank">
+ R/qtl2 file format specifications
+ </a>
+ for more details.
+ </p>
+</span>
+{%endmacro%}
+{{upload_progress_indicator()}}
+
+<div id="resumable-file-display-template"
+ class="panel panel-info"
+ style="display: none">
+ <div class="panel-heading"></div>
+ <div class="panel-body"></div>
+</div>
+
+
+<h2 class="heading">Upload R/qtl2 Bundle</h2>
+
+<div id="resumable-drop-area"
+ style="display:none;background:#eeeeee;min-height:12em;border-radius:0.5em;padding:1em;">
+ <p>
+ <a id="resumable-browse-button" href="#"
+ class="btn btn-info">Browse</a>
+ </p>
+ <p class="form-text text-muted">
+ You can drag and drop your file here, or click the browse button.
+ Click on the file to remove it.
+ </p>
+ {{rqtl2_file_help()}}
+ <div id="resumable-selected-files"
+ style="display:flex;flex-direction:row;flex-wrap: wrap;justify-content:space-around;gap:10px 20px;"></div>
+ <div id="resumable-class-buttons" style="text-align: right;">
+ <button id="resumable-upload-button"
+ class="btn btn-primary"
+ style="display: none">start upload</button>
+ <button id="resumable-cancel-upload-button"
+ class="btn btn-danger"
+ style="display: none">cancel upload</button>
+ </div>
+ <div id="resumable-progress-bar" class="progress" style="display: none">
+ <div class="progress-bar"
+ role="progress-bar"
+ aria-valuenow="60"
+ aria-valuemin="0"
+ aria-valuemax="100"
+ style="width: 0%;">
+ Uploading: 60%
+ </div>
+ </div>
+</div>
+
+<form id="frm-upload-rqtl2-bundle"
+ action="{{url_for('expression-data.rqtl2.upload_rqtl2_bundle',
+ species_id=species.SpeciesId,
+ population_id=population.InbredSetId)}}"
+ method="POST"
+ enctype="multipart/form-data"
+ data-resumable-target="{{url_for(
+ 'expression-data.rqtl2.upload_rqtl2_bundle_chunked_post',
+ species_id=species.SpeciesId,
+ population_id=population.InbredSetId)}}">
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id"
+ value="{{population.InbredSetId}}" />
+
+ {{flash_all_messages()}}
+
+ <div class="form-group">
+ <legend class="heading">file upload</legend>
+ <label for="file-rqtl2-bundle" class="form-label">R/qtl2 bundle</label>
+ <input type="file" id="file-rqtl2-bundle" name="rqtl2_bundle_file"
+ accept="application/zip, .zip"
+ required="required"
+ class="form-control" />
+ {{rqtl2_file_help()}}
+ </div>
+
+ <button type="submit"
+ class="btn btn-primary"
+ data-toggle="modal"
+ data-target="#upload-progress-indicator">upload R/qtl2 bundle</button>
+</form>
+
+{%endblock%}
+
+{%block javascript%}
+<script src="{{url_for('base.node_modules',
+ filename='resumablejs/resumable.js')}}"></script>
+<script type="text/javascript" src="/static/js/upload_progress.js"></script>
+<script type="text/javascript">
+ function readBinaryFile(file) {
+ return new Promise((resolve, reject) => {
+ var _reader = new FileReader();
+ _reader.onload = (event) => {resolve(_reader.result);};
+ _reader.readAsArrayBuffer(file);
+ });
+ }
+
+ function computeFileChecksum(file) {
+ return readBinaryFile(file)
+ .then((content) => {
+ return window.crypto.subtle.digest(
+ "SHA-256", new Uint8Array(content));
+ }).then((digest) => {
+ return Uint8ArrayToHex(new Uint8Array(digest))
+ });
+ }
+
+ function Uint8ArrayToHex(arr) {
+ var toHex = (val) => {
+ _hex = val.toString(16);
+ if(_hex.length < 2) {
+ return "0" + val;
+ }
+ return _hex;
+ };
+ _hexstr = ""
+ arr.forEach((val) => {_hexstr += toHex(val)});
+ return _hexstr
+ }
+
+ var r = Resumable({
+ target: $("#frm-upload-rqtl2-bundle").attr("data-resumable-target"),
+ fileType: ["zip"],
+ maxFiles: 1,
+ forceChunkSize: true,
+ generateUniqueIdentifier: (file, event) => {
+ return computeFileChecksum(file).then((checksum) => {
+ var _relativePath = (file.webkitRelativePath
+ || file.relativePath
+ || file.fileName
+ || file.name);
+ return checksum + "-" + _relativePath.replace(
+ /[^a-zA-Z0-9_-]/img, "");
+ });
+ }
+ });
+
+ if(r.support) {
+ //Hide form and display drag&drop UI
+ $("#frm-upload-rqtl2-bundle").css("display", "none");
+ $("#resumable-drop-area").css("display", "block");
+
+ // Define UI elements for browse and drag&drop
+ r.assignDrop(document.getElementById("resumable-drop-area"));
+ r.assignBrowse(document.getElementById("resumable-browse-button"));
+
+ // Event handlers
+
+ function display_files(files) {
+ displayArea = $("#resumable-selected-files")
+ displayArea.empty();
+ files.forEach((file) => {
+ var displayElement = $(
+ "#resumable-file-display-template").clone();
+ displayElement.removeAttr("id");
+ displayElement.css("display", "");
+ displayElement.find(".panel-heading").text(file.fileName);
+ list = $("<ul></ul>");
+ list.append($("<li><strong>Name</strong>: "
+ + (file.name
+ || file.fileName
+ || file.relativePath
+ || file.webkitRelativePath)
+ + "</li>"));
+ list.append($("<li><strong>Size</strong>: "
+ + (file.size / (1024*1024)).toFixed(2)
+ + " MB</li>"));
+ list.append($("<li><strong>Unique Identifier</strong>: "
+ + file.uniqueIdentifier + "</li>"));
+ list.append($("<li><strong>Mime</strong>: "
+ + file.file.type
+ + "</li>"));
+ displayElement.find(".panel-body").append(list);
+ displayElement.appendTo("#resumable-selected-files");
+ });
+ }
+
+ r.on("filesAdded", function(files) {
+ display_files(files);
+ $("#resumable-upload-button").css("display", "");
+ $("#resumable-upload-button").on("click", (event) => {
+ r.upload();
+ });
+ });
+
+ r.on("uploadStart", (event) => {
+ $("#resumable-upload-button").css("display", "none");
+ $("#resumable-cancel-upload-button").css("display", "");
+ $("#resumable-cancel-upload-button").on("click", (event) => {
+ r.files.forEach((file) => {
+ if(file.isUploading()) {
+ file.abort();
+ }
+ });
+ $("#resumable-cancel-upload-button").css("display", "none");
+ $("#resumable-upload-button").on("click", (event) => {
+ r.files.forEach((file) => {file.retry();});
+ });
+ $("#resumable-upload-button").css("display", "");
+ });
+ });
+
+ r.on("progress", () => {
+ var progress = (r.progress() * 100).toFixed(2);
+ var pbar = $("#resumable-progress-bar > .progress-bar");
+ $("#resumable-progress-bar").css("display", "");
+ pbar.css("width", progress+"%");
+ pbar.attr("aria-valuenow", progress);
+ pbar.text("Uploading: " + progress + "%");
+ })
+
+ r.on("fileSuccess", (file, message) => {
+ if(message != "OK") {
+ var uri = (window.location.protocol
+ + "//"
+ + window.location.host
+ + message);
+ window.location.replace(uri);
+ }
+ });
+
+ r.on("error", (message, file) => {
+ filename = (file.webkitRelativePath
+ || file.relativePath
+ || file.fileName
+ || file.name);
+ jsonmsg = JSON.parse(message);
+ alert("There was an error while uploading your file '"
+ + filename
+ + "'. The error message was:\n\n\t"
+ + jsonmsg.error
+ + " ("
+ + jsonmsg.statuscode
+ + "): " + jsonmsg.message);
+ })
+ } else {
+ setup_upload_handlers(
+ "frm-upload-rqtl2-bundle", make_data_uploader(
+ function (form) {
+ var formdata = new FormData();
+ formdata.append(
+ "species_id",
+ form.querySelector('input[name="species_id"]').value);
+ formdata.append(
+ "population_id",
+ form.querySelector('input[name="population_id"]').value);
+ formdata.append(
+ "rqtl2_bundle_file",
+ form.querySelector("#file-rqtl2-bundle").files[0]);
+ return formdata;
+ }));
+ }
+</script>
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/upload-rqtl2-bundle-step-02.html b/uploader/templates/populations/rqtl2/upload-rqtl2-bundle-step-02.html
new file mode 100644
index 0000000..8210ed0
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/upload-rqtl2-bundle-step-02.html
@@ -0,0 +1,33 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+
+{%block title%}Upload R/qtl2 Bundle{%endblock%}
+
+{%block contents%}
+<h2 class="heading">Upload R/qtl2 Bundle</h2>
+
+<div class="row">
+ <p>You have successfully uploaded the zipped bundle of R/qtl2 files.</p>
+ <p>The next step is to select the various extra information we need to figure
+ out what to do with the data. You will select/create the relevant studies
+ and/or datasets to organise the data in the steps that follow.</p>
+ <p>Click "Continue" below to proceed.</p>
+
+ <form id="frm-upload-rqtl2-bundle"
+ action="{{url_for('expression-data.rqtl2.select_dataset_info',
+ species_id=species.SpeciesId,
+ population_id=population.InbredSetId)}}"
+ method="POST"
+ enctype="multipart/form-data">
+ {{flash_all_messages()}}
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id"
+ value="{{population.InbredSetId}}" />
+ <input type="hidden" name="rqtl2_bundle_file"
+ value="{{rqtl2_bundle_file}}" />
+
+ <button type="submit" class="btn btn-primary">continue</button>
+ </form>
+</div>
+
+{%endblock%}