aboutsummaryrefslogtreecommitdiff
path: root/uploader/templates/phenotypes
diff options
context:
space:
mode:
Diffstat (limited to 'uploader/templates/phenotypes')
-rw-r--r--uploader/templates/phenotypes/add-phenotypes.html231
-rw-r--r--uploader/templates/phenotypes/create-dataset.html106
-rw-r--r--uploader/templates/phenotypes/list-datasets.html6
-rw-r--r--uploader/templates/phenotypes/macro-display-pheno-dataset-card.html31
-rw-r--r--uploader/templates/phenotypes/view-dataset.html20
-rw-r--r--uploader/templates/phenotypes/view-phenotype.html34
6 files changed, 419 insertions, 9 deletions
diff --git a/uploader/templates/phenotypes/add-phenotypes.html b/uploader/templates/phenotypes/add-phenotypes.html
new file mode 100644
index 0000000..196bc69
--- /dev/null
+++ b/uploader/templates/phenotypes/add-phenotypes.html
@@ -0,0 +1,231 @@
+{%extends "phenotypes/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-table-pagination.html" import table_pagination%}
+{%from "phenotypes/macro-display-pheno-dataset-card.html" import display_pheno_dataset_card%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="add-phenotypes"%}
+ class="breadcrumb-item active"
+ {%else%}
+ class="breadcrumb-item"
+ {%endif%}>
+ <a href="{{url_for('species.populations.phenotypes.add_phenotypes',
+ species_id=species.SpeciesId,
+ population_id=population.Id,
+ dataset_id=dataset.Id)}}">View Datasets</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+ <form id="frm-add-phenotypes"
+ method="POST"
+ enctype="multipart/form-data"
+ action="{{url_for('species.populations.phenotypes.add_phenotypes',
+ species_id=species.SpeciesId,
+ population_id=population.Id,
+ dataset_id=dataset.Id)}}">
+ <legend>Add New Phenotypes</legend>
+
+ <div class="form-text help-block">
+ <p>Select the zip file bundle containing information on the phenotypes you
+ wish to upload, then click the "Upload Phenotypes" button below to
+ upload the data.</p>
+ <p>See the <a href="#section-file-formats">File Formats</a> section below
+ to get an understanding of what is expected of the bundle files you
+ upload.</p>
+ <p><strong>This will not update any existing phenotypes!</strong></p>
+ </div>
+
+ <div class="form-group">
+ <label for="finput-phenotypes-bundle" class="form-label">
+ Phenotypes Bundle</label>
+ <input type="file"
+ id="finput-phenotypes-bundle"
+ name="phenotypes-bundle"
+ accept="application/zip, .zip"
+ required="required"
+ class="form-control" />
+ </div>
+
+ <div class="form-group">
+ <input type="submit"
+ value="upload phenotypes"
+ class="btn btn-primary" />
+ </div>
+ </form>
+</div>
+
+<div class="row">
+ <h2 class="heading" id="section-file-formats">File Formats</h2>
+ <p>We accept an extended form of the
+ <a href="https://kbroman.org/qtl2/assets/vignettes/input_files.html#format-of-the-data-files"
+ title="R/qtl2 software input file format documentation">
+ input files' format used with the R/qtl2 software</a> as a single ZIP
+ file</p>
+ <p>The files that are used for this feature are:
+ <ul>
+ <li>the <em>control</em> file</li>
+ <li><em>pheno</em> file(s)</li>
+ <li><em>phenocovar</em> file(s)</li>
+ <li><em>phenose</em> files(s)</li>
+ </ul>
+ </p>
+ <p>Other files within the bundle will be ignored, for this feature.</p>
+ <p>The following section will detail the expectations for each of the
+ different file types within the uploaded ZIP file bundle for phenotypes:</p>
+
+ <h3 class="subheading">Control File</h3>
+ <p>There <strong>MUST be <em>one, and only one</em></strong> file that acts
+ as the control file. This file can be:
+ <ul>
+ <li>a <em>JSON</em> file, or</li>
+ <li>a <em>YAML</em> file.</li>
+ </ul>
+ </p>
+
+ <p>The control file is useful for defining things about the bundle such as:</p>
+ <ul>
+ <li>The field separator value (default: <code>sep: ','</code>). There can
+ only ever be one field separator and it <strong>MUST</strong> be the same
+ one for <strong>ALL</strong> files in the bundle.</li>
+ <li>The comment character (default: <code>comment.char: '#'</code>). Any
+ line that starts with this character will be considered a comment line and
+ be ignored in its entirety.</li>
+ <li>Code for missing values (default: <code>na.strings: 'NA'</code>). You
+ can specify more than one code to indicate missing values, e.g.
+ <code>{…, "na.strings": ["NA", "N/A", "-"], …}</code></li>
+ </ul>
+
+ <h3 class="subheading"><em>pheno</em> File(s)</h3>
+ <p>These files are the main data files. You must have at least one of these
+ files in your bundle for it to be valid for this step.</p>
+ <p>The data is a matrix of <em>individuals × phenotypes</em> by default, as
+ below:<br />
+ <code>
+ id,10001,10002,10003,10004,…<br />
+ BXD1,61.400002,54.099998,483,49.799999,…<br />
+ BXD2,49,50.099998,403,45.5,…<br />
+ BXD5,62.5,53.299999,501,62.900002,…<br />
+ BXD6,53.099998,55.099998,403,NA,…<br />
+ ⋮<br /></code>
+ </p>
+ <p>If the <code>pheno_transposed</code> value is set to <code>True</code>,
+ then the data will be a <em>phenotypes × individuals</em> matrix as in the
+ example below:<br />
+ <code>
+ id,BXD1,BXD2,BXD5,BXD6,…<br />
+ 10001,61.400002,49,62.5,53.099998,…<br />
+ 10002,54.099998,50.099998,53.299999,55.099998,…<br />
+ 10003,483,403,501,403,…<br />
+ 10004,49.799999,45.5,62.900002,NA,…<br />
+ ⋮
+ </code>
+ </p>
+
+
+ <h3 class="subheading"><em>phenocovar</em> File(s)</h3>
+ <p>At least one phenotypes metadata file with the metadata values such as
+ descriptions, PubMed Identifier, publication titles (if present), etc.</p>
+ <p>The data in this/these file(s) is a matrix of
+ <em>phenotypes × phenotypes-covariates</em>. The first column is always the
+ phenotype names/identifiers — same as in the R/qtl2 format.</p>
+ <p><em>phenocovar</em> files <strong>should never be transposed</strong>!</p>
+ <p>This file <strong>MUST</strong> be present in the bundle, and have data for
+ the bundle to be considered valid by our system for this step.<br />
+ In addition to that, the following are the fields that <strong>must be
+ present</strong>, and
+ have values, in the file before the file is considered valid:
+ <ul>
+ <li><em>description</em>: A description for each phenotype. Useful
+ for users to know what the phenotype is about.</li>
+ <li><em>units</em>: The units of measurement for the phenotype,
+ e.g. milligrams for brain weight, centimetres/millimetres for
+ tail-length, etc.</li>
+ </ul></p>
+
+ <p>The following <em>optional</em> fields can also be provided:
+ <ul>
+ <li><em>pubmedid</em>: A PubMed Identifier for the publication where
+ the phenotype is published. If this field is not provided, the system will
+ assume your phenotype is not published.</li>
+ </ul>
+ </p>
+ <p>These files will be marked up in the control file with the
+ <code>phenocovar</code> key, as in the examples below:
+ <ol>
+ <li>JSON: single file<br />
+ <code>{<br />
+ &nbsp;&nbsp;⋮,<br />
+ &nbsp;&nbsp;"phenocovar": "your_covariates_file.csv",<br />
+ &nbsp;&nbsp;⋮<br />
+ }
+ </code>
+ </li>
+ <li>JSON: multiple files<br />
+ <code>{<br />
+ &nbsp;&nbsp;⋮,<br />
+ &nbsp;&nbsp;"phenocovar": [<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;"covariates_file_01.csv",<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;"covariates_file_01.csv",<br />
+ &nbsp;&nbsp;&nbsp;&nbsp;⋮<br />
+ &nbsp;&nbsp;],<br />
+ &nbsp;&nbsp;⋮<br />
+ }
+ </code>
+ </li>
+ <li>YAML: single file or<br />
+ <code>
+ ⋮<br />
+ phenocovar: your_covariates_file.csv<br />
+ ⋮
+ </code>
+ </li>
+ <li>YAML: multiple files<br />
+ <code>
+ ⋮<br />
+ phenocovar:<br />
+ - covariates_file_01.csv<br />
+ - covariates_file_02.csv<br />
+ - covariates_file_03.csv<br />
+ …<br />
+ ⋮
+ </code>
+ </li>
+ </ol>
+ </p>
+
+ <h3 class="subheading"><em>phenose</em> and <em>phenonum</em> File(s)</h3>
+ <p>These are extensions to the R/qtl2 standard, i.e. these types ofs file are
+ not supported by the original R/qtl2 file format</p>
+ <p>We use these files to upload the standard errors (<em>phenose</em>) when
+ the data file (<em>pheno</em>) is average data. In that case, the
+ <em>phenonum</em> file(s) contains the number of individuals that were
+ involved when computing the averages.</p>
+ <p>Both types of files are matrices of <em>individuals × phenotypes</em> by
+ default. Like the related <em>pheno</em> files, if
+ <code>pheno_transposed: True</code>, then the file will be a matrix of
+ <em>phenotypes × individuals</em>.</p>
+</div>
+
+<div class="row text-warning">
+ <h3 class="subheading">Notes for Devs (well… Fred, really.)</h3>
+ <p>Use the following resources for automated retrieval of certain data</p>
+ <ul>
+ <li><a href="https://www.ncbi.nlm.nih.gov/pmc/tools/developers/"
+ title="NCBI APIs: Retrieve articles' metadata etc.">
+ NCBI APIS</a></li>
+ </ul>
+</div>
+
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_pheno_dataset_card(species, population, dataset)}}
+{%endblock%}
diff --git a/uploader/templates/phenotypes/create-dataset.html b/uploader/templates/phenotypes/create-dataset.html
new file mode 100644
index 0000000..93de92f
--- /dev/null
+++ b/uploader/templates/phenotypes/create-dataset.html
@@ -0,0 +1,106 @@
+{%extends "phenotypes/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-table-pagination.html" import table_pagination%}
+{%from "populations/macro-display-population-card.html" import display_population_card%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="create-dataset"%}
+ class="breadcrumb-item active"
+ {%else%}
+ class="breadcrumb-item"
+ {%endif%}>
+ <a href="{{url_for('species.populations.phenotypes.create_dataset',
+ species_id=species.SpeciesId,
+ population_id=population.Id)}}">Create Datasets</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+ <p>Create a new phenotype dataset.</p>
+</div>
+
+<div class="row">
+ <form id="frm-create-pheno-dataset"
+ action="{{url_for('species.populations.phenotypes.create_dataset',
+ species_id=species.SpeciesId,
+ population_id=population.Id)}}"
+ method="POST">
+
+ <div class="form-group">
+ <label class="form-label" for="txt-dataset-name">Name</label>
+ {%if errors["dataset-name"] is defined%}
+ <small class="form-text text-muted danger">
+ <p>{{errors["dataset-name"]}}</p></small>
+ {%endif%}
+ <input type="text"
+ name="dataset-name"
+ id="txt-dataset-name"
+ value="{{original_formdata.get('dataset-name') or (population.InbredSetCode + 'Publish')}}"
+ {%if errors["dataset-name"] is defined%}
+ class="form-control danger"
+ {%else%}
+ class="form-control"
+ {%endif%}
+ required="required" />
+ <small class="form-text text-muted">
+ <p>A short representative name for the dataset.</p>
+ <p>Recommended: Use the population code and append "Publish" at the end.
+ <br />This field will only accept names composed of
+ letters ('A-Za-z'), numbers (0-9), hyphens and underscores.</p>
+ </small>
+ </div>
+
+ <div class="form-group">
+ <label class="form-label" for="txt-dataset-fullname">Full Name</label>
+ {%if errors["dataset-fullname"] is defined%}
+ <small class="form-text text-muted danger">
+ <p>{{errors["dataset-fullname"]}}</p></small>
+ {%endif%}
+ <input id="txt-dataset-fullname"
+ name="dataset-fullname"
+ type="text"
+ value="{{original_formdata.get('dataset-fullname', '')}}"
+ {%if errors["dataset-fullname"] is defined%}
+ class="form-control danger"
+ {%else%}
+ class="form-control"
+ {%endif%}
+ required="required" />
+ <small class="form-text text-muted">
+ <p>A longer, descriptive name for the dataset &mdash; useful for humans.
+ </p></small>
+ </div>
+
+ <div class="form-group">
+ <label class="form-label" for="txt-dataset-shortname">Short Name</label>
+ <input id="txt-dataset-shortname"
+ name="dataset-shortname"
+ type="text"
+ class="form-control"
+ value="{{original_formdata.get('dataset-shortname') or (population.InbredSetCode + ' Publish')}}" />
+ <small class="form-text text-muted">
+ <p>An optional, short name for the dataset. <br />
+ If this is not provided, it will default to the value provided for the
+ <strong>Name</strong> field above.</p></small>
+ </div>
+
+ <div class="form-group">
+ <input type="submit"
+ class="btn btn-primary"
+ value="create phenotype dataset" />
+ </div>
+
+ </form>
+</div>
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_population_card(species, population)}}
+{%endblock%}
diff --git a/uploader/templates/phenotypes/list-datasets.html b/uploader/templates/phenotypes/list-datasets.html
index 360fd2c..2eaf43a 100644
--- a/uploader/templates/phenotypes/list-datasets.html
+++ b/uploader/templates/phenotypes/list-datasets.html
@@ -51,8 +51,10 @@
<p class="text-warning">
<span class="glyphicon glyphicon-exclamation-sign"></span>
There is no dataset for this population!</p>
- <p><a href="#"
- class="not-implemented btn btn-primary"
+ <p><a href="{{url_for('species.populations.phenotypes.create_dataset',
+ species_id=species.SpeciesId,
+ population_id=population.Id)}}"
+ class="btn btn-primary"
title="Create a new phenotype dataset.">create dataset</a></p>
{%endif%}
</div>
diff --git a/uploader/templates/phenotypes/macro-display-pheno-dataset-card.html b/uploader/templates/phenotypes/macro-display-pheno-dataset-card.html
new file mode 100644
index 0000000..11b108b
--- /dev/null
+++ b/uploader/templates/phenotypes/macro-display-pheno-dataset-card.html
@@ -0,0 +1,31 @@
+{%from "populations/macro-display-population-card.html" import display_population_card%}
+
+{%macro display_pheno_dataset_card(species, population, dataset)%}
+{{display_population_card(species, population)}}
+
+<div class="card">
+ <div class="card-body">
+ <h5 class="card-title">Phenotypes' Dataset</h5>
+ <div class="card-text">
+ <table class="table">
+ <tbody>
+ <tr>
+ <td>Name</td>
+ <td>{{dataset.Name}}</td>
+ </tr>
+
+ <tr>
+ <td>Full Name</td>
+ <td>{{dataset.FullName}}</td>
+ </tr>
+
+ <tr>
+ <td>Short Name</td>
+ <td>{{dataset.ShortName}}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+</div>
+{%endmacro%}
diff --git a/uploader/templates/phenotypes/view-dataset.html b/uploader/templates/phenotypes/view-dataset.html
index e2ccb60..b136bb6 100644
--- a/uploader/templates/phenotypes/view-dataset.html
+++ b/uploader/templates/phenotypes/view-dataset.html
@@ -1,5 +1,6 @@
{%extends "phenotypes/base.html"%}
{%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-table-pagination.html" import table_pagination%}
{%from "populations/macro-display-population-card.html" import display_population_card%}
{%block title%}Phenotypes{%endblock%}
@@ -36,10 +37,7 @@
<tbody>
<tr>
- <td><a href="{{url_for('species.populations.phenotypes.view_dataset',
- species_id=species.SpeciesId,
- population_id=population.Id,
- dataset_id=dataset.Id)}}">{{dataset.Name}}</a></td>
+ <td>{{dataset.Name}}</td>
<td>{{dataset.FullName}}</td>
<td>{{dataset.ShortName}}</td>
</tr>
@@ -48,12 +46,20 @@
</div>
<div class="row">
+ <p><a href="{{url_for('species.populations.phenotypes.add_phenotypes',
+ species_id=species.SpeciesId,
+ population_id=population.Id,
+ dataset_id=dataset.Id)}}"
+ title="Add a bunch of phenotypes"
+ class="btn btn-primary">Add phenotypes</a></p>
+</div>
+
+<div class="row">
<h2>Phenotype Data</h2>
<p>This dataset has a total of {{phenotype_count}} phenotypes.</p>
- <p class="text-warning">
- <span class="glyphicon glyphicon-exclamation-sign"></span>
- Display pagination controls here &hellip;</p>
+
+ {{table_pagination(start_from, count, phenotype_count, url_for('species.populations.phenotypes.view_dataset', species_id=species.SpeciesId, population_id=population.Id, dataset_id=dataset.Id), "phenotypes")}}
<table class="table">
<thead>
diff --git a/uploader/templates/phenotypes/view-phenotype.html b/uploader/templates/phenotypes/view-phenotype.html
index 03935f5..99bb8e5 100644
--- a/uploader/templates/phenotypes/view-phenotype.html
+++ b/uploader/templates/phenotypes/view-phenotype.html
@@ -41,8 +41,42 @@
<td><strong>Collation</strong></td>
<td>{{dataset.FullName}}</td>
</tr>
+ <tr>
+ <td><strong>Units</strong></td>
+ <td>{{phenotype.Units}}</td>
+ </tr>
</tbody>
</table>
+
+ <form action="#edit-delete-phenotype"
+ method="POST"
+ id="frm-delete-phenotype">
+
+ <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+ <input type="hidden" name="population_id" value="{{population.Id}}" />
+ <input type="hidden" name="dataset_id" value="{{dataset.Id}}" />
+ <input type="hidden" name="phenotype_id" value="{{phenotype.Id}}" />
+
+ <div class="btn-group btn-group-justified">
+ <div class="btn-group">
+ {%if "group:resource:edit-resource" in privileges%}
+ <input type="submit"
+ title="Edit the values for the phenotype. This is meant to be used when you need to update only a few values."
+ class="btn btn-primary not-implemented"
+ value="edit" />
+ {%endif%}
+ </div>
+ <div class="btn-group"></div>
+ <div class="btn-group">
+ {%if "group:resource:delete-resource" in privileges%}
+ <input type="submit"
+ title="Delete the entire phenotype. This is useful when you need to change data for most or all of the fields for this phenotype."
+ class="btn btn-danger not-implemented"
+ value="delete" />
+ {%endif%}
+ </div>
+ </div>
+ </form>
</div>
</div>