diff options
-rw-r--r-- | doc/guix_profile_setup.org | 39 | ||||
-rw-r--r-- | wqflask/wqflask/correlation_matrix/show_corr_matrix.py | 124 | ||||
-rw-r--r-- | wqflask/wqflask/marker_regression/display_mapping_results.py | 43 | ||||
-rw-r--r-- | wqflask/wqflask/marker_regression/run_mapping.py | 6 | ||||
-rw-r--r-- | wqflask/wqflask/show_trait/show_trait.py | 23 | ||||
-rw-r--r-- | wqflask/wqflask/static/new/css/show_trait.css | 8 | ||||
-rw-r--r-- | wqflask/wqflask/static/new/javascript/show_trait.js | 8 | ||||
-rw-r--r-- | wqflask/wqflask/templates/base.html | 4 | ||||
-rw-r--r-- | wqflask/wqflask/templates/mapping_results.html | 15 | ||||
-rw-r--r-- | wqflask/wqflask/templates/show_trait_calculate_correlations.html | 2 | ||||
-rw-r--r-- | wqflask/wqflask/templates/show_trait_transform_and_filter.html | 12 |
11 files changed, 168 insertions, 116 deletions
diff --git a/doc/guix_profile_setup.org b/doc/guix_profile_setup.org new file mode 100644 index 00000000..c397377c --- /dev/null +++ b/doc/guix_profile_setup.org @@ -0,0 +1,39 @@ +* Setting up GUIX profile for GN
+
+First create a guix profile with the latest packages:
+
+: ~/opt/guix/bin/guix pull
+
+This will create a profile with the latest packages under`~/.config/guix/current`
+
+Now you have the latest guix. Check: `$HOME/.config/guix/current/bin/guix --version`
+
+At this point, it's worth mentioning that installing
+python3-genenetwork using `$HOME/.config/guix/current/bin/guix` should
+work; but let's use the dev version(since that may come handy in
+time), and it's a nice thing to know.
+
+Next, we ensure that the appropriate GUILE<sub>PATHS</sub> are set:
+
+: export GUILE_LOAD_PATH=$HOME/.config/guix/current/share/guile/site/3.0/
+: export GUILE_LOAD_COMPILED_PATH=$HOME/.config/guix/current/lib/guile/3.0/site-ccache/
+
+Get into the container:
+
+: $HOME/.config/guix/current/bin/guix environment -C guix --ad-hoc bash gcc-toolchain
+: ./bootstrap
+: ./configure --localstatedir=/var --sysconfdir=/etc
+
+Check that everything works:
+
+: make check
+
+Clean up and build:
+
+: make clean-go
+: make -j 4
+: exit
+
+Install Python3 (substitute paths when necessary):
+
+: env GUIX_PACKAGE_PATH='/home/zas1024/guix-bioinformatics:/home/zas1024/guix-past/modules' $HOME/.config/guix/current/bin/guix install python3-genenetwork2 -p ~/opt/python3-genenetwork2 --substitute-urls="http://guix.genenetwork.org https://berlin.guixsd.org https://ci.guix.gnu.org https://mirror.hydra.gnu.org"
diff --git a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py index 9ac02ac5..e7b16e77 100644 --- a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py +++ b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py @@ -23,6 +23,9 @@ import math import random import string +import rpy2.robjects as ro +from rpy2.robjects.packages import importr + import numpy as np import scipy @@ -160,23 +163,22 @@ class CorrelationMatrix: for sample in self.all_sample_list: groups.append(1) - # Not doing PCA until rpy2 is excised self.pca_works = "False" - # try: - # corr_result_eigen = np.linalg.eig(np.array(self.pca_corr_results)) - # corr_eigen_value, corr_eigen_vectors = sortEigenVectors( - # corr_result_eigen) - - # if self.do_PCA == True: - # self.pca_works = "True" - # self.pca_trait_ids = [] - # pca = self.calculate_pca( - # list(range(len(self.traits))), corr_eigen_value, corr_eigen_vectors) - # self.loadings_array = self.process_loadings() - # else: - # self.pca_works = "False" - # except: - # self.pca_works = "False" + try: + corr_result_eigen = np.linalg.eig(np.array(self.pca_corr_results)) + corr_eigen_value, corr_eigen_vectors = sortEigenVectors( + corr_result_eigen) + + if self.do_PCA == True: + self.pca_works = "True" + self.pca_trait_ids = [] + pca = self.calculate_pca( + list(range(len(self.traits))), corr_eigen_value, corr_eigen_vectors) + self.loadings_array = self.process_loadings() + else: + self.pca_works = "False" + except: + self.pca_works = "False" self.js_data = dict(traits=[trait.name for trait in self.traits], groups=groups, @@ -185,51 +187,51 @@ class CorrelationMatrix: samples=self.all_sample_list, sample_data=self.sample_data,) - # def calculate_pca(self, cols, corr_eigen_value, corr_eigen_vectors): - # base = importr('base') - # stats = importr('stats') - - # corr_results_to_list = robjects.FloatVector( - # [item for sublist in self.pca_corr_results for item in sublist]) - - # m = robjects.r.matrix(corr_results_to_list, nrow=len(cols)) - # eigen = base.eigen(m) - # pca = stats.princomp(m, cor="TRUE") - # self.loadings = pca.rx('loadings') - # self.scores = pca.rx('scores') - # self.scale = pca.rx('scale') - - # trait_array = zScore(self.trait_data_array) - # trait_array_vectors = np.dot(corr_eigen_vectors, trait_array) - - # pca_traits = [] - # for i, vector in enumerate(trait_array_vectors): - # # ZS: Check if below check is necessary - # # if corr_eigen_value[i-1] > 100.0/len(self.trait_list): - # pca_traits.append((vector * -1.0).tolist()) - - # this_group_name = self.trait_list[0][1].group.name - # temp_dataset = data_set.create_dataset( - # dataset_name="Temp", dataset_type="Temp", group_name=this_group_name) - # temp_dataset.group.get_samplelist() - # for i, pca_trait in enumerate(pca_traits): - # trait_id = "PCA" + str(i + 1) + "_" + temp_dataset.group.species + "_" + \ - # this_group_name + "_" + datetime.datetime.now().strftime("%m%d%H%M%S") - # this_vals_string = "" - # position = 0 - # for sample in temp_dataset.group.all_samples_ordered(): - # if sample in self.shared_samples_list: - # this_vals_string += str(pca_trait[position]) - # this_vals_string += " " - # position += 1 - # else: - # this_vals_string += "x " - # this_vals_string = this_vals_string[:-1] - - # Redis.set(trait_id, this_vals_string, ex=THIRTY_DAYS) - # self.pca_trait_ids.append(trait_id) - - # return pca + def calculate_pca(self, cols, corr_eigen_value, corr_eigen_vectors): + base = importr('base') + stats = importr('stats') + + corr_results_to_list = ro.FloatVector( + [item for sublist in self.pca_corr_results for item in sublist]) + + m = ro.r.matrix(corr_results_to_list, nrow=len(cols)) + eigen = base.eigen(m) + pca = stats.princomp(m, cor="TRUE") + self.loadings = pca.rx('loadings') + self.scores = pca.rx('scores') + self.scale = pca.rx('scale') + + trait_array = zScore(self.trait_data_array) + trait_array_vectors = np.dot(corr_eigen_vectors, trait_array) + + pca_traits = [] + for i, vector in enumerate(trait_array_vectors): + # ZS: Check if below check is necessary + # if corr_eigen_value[i-1] > 100.0/len(self.trait_list): + pca_traits.append((vector * -1.0).tolist()) + + this_group_name = self.trait_list[0][1].group.name + temp_dataset = data_set.create_dataset( + dataset_name="Temp", dataset_type="Temp", group_name=this_group_name) + temp_dataset.group.get_samplelist() + for i, pca_trait in enumerate(pca_traits): + trait_id = "PCA" + str(i + 1) + "_" + temp_dataset.group.species + "_" + \ + this_group_name + "_" + datetime.datetime.now().strftime("%m%d%H%M%S") + this_vals_string = "" + position = 0 + for sample in temp_dataset.group.all_samples_ordered(): + if sample in self.shared_samples_list: + this_vals_string += str(pca_trait[position]) + this_vals_string += " " + position += 1 + else: + this_vals_string += "x " + this_vals_string = this_vals_string[:-1] + + Redis.set(trait_id, this_vals_string, ex=THIRTY_DAYS) + self.pca_trait_ids.append(trait_id) + + return pca def process_loadings(self): loadings_array = [] diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index ec17d3b0..f941267e 100644 --- a/wqflask/wqflask/marker_regression/display_mapping_results.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -861,6 +861,9 @@ class DisplayMappingResults: (item[1], yZero - item[2] * bootHeightThresh / maxBootCount)), fill=self.BOOTSTRAP_BOX_COLOR, outline=BLACK) + if maxBootCount == 0: + return + # draw boot scale highestPercent = (maxBootCount * 100.0) / nboot bootScale = Plot.detScale(0, highestPercent) @@ -2286,20 +2289,9 @@ class DisplayMappingResults: font=VERDANA_FILE, size=int(18 * zoom * 1.5)) yZero = yTopOffset + plotHeight - # LRSHeightThresh = drawAreaHeight - # AdditiveHeightThresh = drawAreaHeight/2 - # DominanceHeightThresh = drawAreaHeight/2 - if self.selectedChr == 1: - LRSHeightThresh = drawAreaHeight - yTopOffset + 30 * (zoom - 1) - AdditiveHeightThresh = LRSHeightThresh / 2 - DominanceHeightThresh = LRSHeightThresh / 2 - else: - LRSHeightThresh = drawAreaHeight - AdditiveHeightThresh = drawAreaHeight / 2 - DominanceHeightThresh = drawAreaHeight / 2 - # LRSHeightThresh = (yZero - yTopOffset + 30*(zoom - 1)) - # AdditiveHeightThresh = LRSHeightThresh/2 - # DominanceHeightThresh = LRSHeightThresh/2 + LRSHeightThresh = drawAreaHeight + AdditiveHeightThresh = drawAreaHeight / 2 + DominanceHeightThresh = drawAreaHeight / 2 if LRS_LOD_Max > 100: LRSScale = 20.0 @@ -2380,8 +2372,7 @@ class DisplayMappingResults: # ZS: I don't know if what I did here with this inner function is clever or overly complicated, but it's the only way I could think of to avoid duplicating the code inside this function def add_suggestive_significant_lines_and_legend(start_pos_x, chr_length_dist): - rightEdge = int(start_pos_x + chr_length_dist * \ - plotXScale - self.SUGGESTIVE_WIDTH / 1.5) + rightEdge = xLeftOffset + plotWidth im_drawer.line( xy=((start_pos_x + self.SUGGESTIVE_WIDTH / 1.5, suggestiveY), (rightEdge, suggestiveY)), @@ -2569,7 +2560,10 @@ class DisplayMappingResults: Xc = startPosX + ((qtlresult['Mb'] - start_cm - startMb) * plotXScale) * ( ((qtlresult['Mb'] - start_cm - startMb) * plotXScale) / ((qtlresult['Mb'] - start_cm - startMb + self.GraphInterval) * plotXScale)) else: - Xc = startPosX + (qtlresult['Mb'] - startMb) * plotXScale + if self.selectedChr != -1 and qtlresult['Mb'] > endMb: + Xc = startPosX + endMb * plotXScale + else: + Xc = startPosX + (qtlresult['Mb'] - startMb) * plotXScale # updated by NL 06-18-2011: # fix the over limit LRS graph issue since genotype trait may give infinite LRS; @@ -2580,36 +2574,29 @@ class DisplayMappingResults: if 'lrs_value' in qtlresult: if self.LRS_LOD == "LOD" or self.LRS_LOD == "-logP": if qtlresult['lrs_value'] > 460 or qtlresult['lrs_value'] == 'inf': - #Yc = yZero - webqtlConfig.MAXLRS*LRSHeightThresh/(LRSAxisList[-1]*self.LODFACTOR) Yc = yZero - webqtlConfig.MAXLRS * \ LRSHeightThresh / \ (LRS_LOD_Max * self.LODFACTOR) else: - #Yc = yZero - qtlresult['lrs_value']*LRSHeightThresh/(LRSAxisList[-1]*self.LODFACTOR) Yc = yZero - \ qtlresult['lrs_value'] * LRSHeightThresh / \ (LRS_LOD_Max * self.LODFACTOR) else: if qtlresult['lrs_value'] > 460 or qtlresult['lrs_value'] == 'inf': - #Yc = yZero - webqtlConfig.MAXLRS*LRSHeightThresh/LRSAxisList[-1] Yc = yZero - webqtlConfig.MAXLRS * LRSHeightThresh / LRS_LOD_Max else: - #Yc = yZero - qtlresult['lrs_value']*LRSHeightThresh/LRSAxisList[-1] Yc = yZero - \ qtlresult['lrs_value'] * \ LRSHeightThresh / LRS_LOD_Max else: if qtlresult['lod_score'] > 100 or qtlresult['lod_score'] == 'inf': - #Yc = yZero - webqtlConfig.MAXLRS*LRSHeightThresh/LRSAxisList[-1] Yc = yZero - webqtlConfig.MAXLRS * LRSHeightThresh / LRS_LOD_Max else: if self.LRS_LOD == "LRS": - #Yc = yZero - qtlresult['lod_score']*self.LODFACTOR*LRSHeightThresh/LRSAxisList[-1] Yc = yZero - \ qtlresult['lod_score'] * self.LODFACTOR * \ LRSHeightThresh / LRS_LOD_Max else: - #Yc = yZero - qtlresult['lod_score']*LRSHeightThresh/LRSAxisList[-1] Yc = yZero - \ qtlresult['lod_score'] * \ LRSHeightThresh / LRS_LOD_Max @@ -2642,14 +2629,12 @@ class DisplayMappingResults: AdditiveHeightThresh / additiveMax AdditiveCoordXY.append((Xc, Yc)) + if self.selectedChr != -1 and qtlresult['Mb'] > endMb: + break + m += 1 if self.manhattan_plot != True: - # im_drawer.polygon( - # xy=LRSCoordXY, - # outline=thisLRSColor - # #, closed=0, edgeWidth=lrsEdgeWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth) - # ) draw_open_polygon(canvas, xy=LRSCoordXY, outline=thisLRSColor, width=lrsEdgeWidth) diff --git a/wqflask/wqflask/marker_regression/run_mapping.py b/wqflask/wqflask/marker_regression/run_mapping.py index c5b980a7..f601201b 100644 --- a/wqflask/wqflask/marker_regression/run_mapping.py +++ b/wqflask/wqflask/marker_regression/run_mapping.py @@ -673,9 +673,9 @@ def trim_markers_for_table(markers): sorted_markers = sorted( markers, key=lambda k: k['lrs_value'], reverse=True) - # ZS: So we end up with a list of just 2000 markers - if len(sorted_markers) >= 2000: - trimmed_sorted_markers = sorted_markers[:2000] + #ZS: So we end up with a list of just 2000 markers + if len(sorted_markers) >= 10000: + trimmed_sorted_markers = sorted_markers[:10000] return trimmed_sorted_markers else: return sorted_markers diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 9ee6a16d..c07430dd 100644 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -177,10 +177,13 @@ class ShowTrait: sample_lists = [group.sample_list for group in self.sample_groups] categorical_var_list = [] + self.numerical_var_list = [] if not self.temp_trait: # ZS: Only using first samplelist, since I think mapping only uses those samples categorical_var_list = get_categorical_variables( self.this_trait, self.sample_groups[0]) + self.numerical_var_list = get_numerical_variables( + self.this_trait, self.sample_groups[0]) # ZS: Get list of chromosomes to select for mapping self.chr_list = [["All", -1]] @@ -694,6 +697,26 @@ def get_categorical_variables(this_trait, sample_list) -> list: return categorical_var_list +def get_numerical_variables(this_trait, sample_list) -> list: + numerical_var_list = [] + + if len(sample_list.attributes) > 0: + for attribute in sample_list.attributes: + all_numeric = True + all_none = True + for attr_val in sample_list.attributes[attribute].distinct_values: + if not attr_val: + continue + try: + val_as_float = float(attr_val) + all_none = False + except: + all_numeric = False + break + if all_numeric and not all_none: + numerical_var_list.append(sample_list.attributes[attribute].name) + + return numerical_var_list def get_genotype_scales(genofiles): geno_scales = {} diff --git a/wqflask/wqflask/static/new/css/show_trait.css b/wqflask/wqflask/static/new/css/show_trait.css index 27404801..782dabc2 100644 --- a/wqflask/wqflask/static/new/css/show_trait.css +++ b/wqflask/wqflask/static/new/css/show_trait.css @@ -159,10 +159,10 @@ div.normalize-div { } div.mapping-main { - min-width: 1200px; + min-width: 1400px; } div.mapping-options { - min-width: 500px; + min-width: 700px; } div.covar-options { @@ -194,7 +194,7 @@ div.select-covar-div { .selected-covariates { overflow-y: scroll; resize: none; - width: 200px; + width: 400px; } .cofactor-input { @@ -259,4 +259,4 @@ input.trait-value-input { div.inline-div { display: inline; -}
\ No newline at end of file +} diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 569046d3..77ef1720 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -747,7 +747,11 @@ filter_by_value = function() { if (filter_column == "value" || filter_column == "stderr"){ var this_col_value = filter_val_nodes[i].childNodes[0].value; } else { - var this_col_value = filter_val_nodes[i].childNodes[0].data; + if (filter_val_nodes[i].childNodes[0] !== undefined){ + var this_col_value = filter_val_nodes[i].childNodes[0].data; + } else { + continue + } } let this_val_node = val_nodes[i].childNodes[0]; @@ -1700,4 +1704,4 @@ $('#normalize').click(edit_data_change); Number.prototype.countDecimals = function () { if(Math.floor(this.valueOf()) === this.valueOf()) return 0; return this.toString().split(".")[1].length || 0; -}
\ No newline at end of file +} diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index ddb1d272..12dddf89 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -85,7 +85,7 @@ <li><a href="/snp_browser">Variant Browser</a></li> <li><a href="http://bnw.genenetwork.org/sourcecodes/home.php">Bayesian Network Webserver</a></li> <li><a href="https://systems-genetics.org/">Systems Genetics PheWAS</a></li> - <li><span class="broken_link" href="http://ucscbrowser.genenetwork.org/">Genome Browser</span></li> + <li><a href="http://ucscbrowser.genenetwork.org/">Genome Browser</a></li> <li><a href="http://power.genenetwork.org">BXD Power Calculator</a></li> <li><a href="http://datafiles.genenetwork.org">Interplanetary File System</a></li> </ul> @@ -208,7 +208,7 @@ <a href="http://joss.theoj.org/papers/10.21105/joss.00025"><img src="https://camo.githubusercontent.com/846b750f582ae8f1d0b4f7e8fee78bed705c88ba/687474703a2f2f6a6f73732e7468656f6a2e6f72672f7061706572732f31302e32313130352f6a6f73732e30303032352f7374617475732e737667" alt="JOSS" data-canonical-src="http://joss.theoj.org/papers/10.21105/joss.00025/status.svg" style="max-width:100%;"></a> </p> <p> - Development and source code on <a href="https://github.com/genenetwork/">github</a> with <a href="https://github.com/genenetwork/genenetwork2/issues">issue tracker</a> and <a href="https://github.com/genenetwork/genenetwork2/blob/master/README.md">documentation</a>. Join the <span class="broken_link" href="http://listserv.uthsc.edu/mailman/listinfo/genenetwork-dev">mailing list</span> and find us on <a href="https://webchat.freenode.net/">IRC</a> (#genenetwork channel). + Development and source code on <a href="https://github.com/genenetwork/">github</a> with <a href="https://github.com/genenetwork/genenetwork2/issues">issue tracker</a> and <a href="https://github.com/genenetwork/genenetwork2/blob/master/README.md">documentation</a>. Join the <a href="http://listserv.uthsc.edu/mailman/listinfo/genenetwork-dev">mailing list</a> and find us on <span class="broken_link" href="https://webchat.freenode.net/">IRC</span> (#genenetwork channel). {% if version: %} <p><small>GeneNetwork {{ version }}</small></p> {% endif %} diff --git a/wqflask/wqflask/templates/mapping_results.html b/wqflask/wqflask/templates/mapping_results.html index d6fc6e37..35d8a157 100644 --- a/wqflask/wqflask/templates/mapping_results.html +++ b/wqflask/wqflask/templates/mapping_results.html @@ -357,7 +357,9 @@ {% endif %} <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/scientific.js') }}"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script> <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='purescript-genome-browser/js/purescript-genetics-browser.js') }}"></script> @@ -409,13 +411,12 @@ "info": "Showing from _START_ to _END_ of " + js_data.total_markers + " records", }, "order": [[1, "asc" ]], - "sDom": "iRZtir", - "iDisplayLength": -1, - "autoWidth": false, - "deferRender": true, + "sDom": "itir", + "autoWidth": true, "bSortClasses": false, - "scrollCollapse": false, - "paging": false + "scrollY": "100vh", + "scroller": true, + "scrollCollapse": true } ); {% elif selectedChr != -1 and plotScale =="physic" and (dataset.group.species == 'mouse' or dataset.group.species == 'rat') %} $('#trait_table').dataTable( { diff --git a/wqflask/wqflask/templates/show_trait_calculate_correlations.html b/wqflask/wqflask/templates/show_trait_calculate_correlations.html index ffbe313c..16a819fa 100644 --- a/wqflask/wqflask/templates/show_trait_calculate_correlations.html +++ b/wqflask/wqflask/templates/show_trait_calculate_correlations.html @@ -72,7 +72,7 @@ <select name="corr_sample_method" class="form-control"> <option value="pearson">Pearson</option> <option value="spearman">Spearman Rank</option> - <!-- <option value="bicor">Biweight Midcorrelation</option> --> + <option value="bicor">Biweight Midcorrelation</option> </select> </div> </div> diff --git a/wqflask/wqflask/templates/show_trait_transform_and_filter.html b/wqflask/wqflask/templates/show_trait_transform_and_filter.html index e3f5ef81..20f78b48 100644 --- a/wqflask/wqflask/templates/show_trait_transform_and_filter.html +++ b/wqflask/wqflask/templates/show_trait_transform_and_filter.html @@ -46,19 +46,17 @@ </div> {% endif %} <div id="filterMenuSpan" class="input-append block-div-2"> - <label for="filter_samples_field">Filter samples by {% if not sample_groups[0].attributes %}value{% endif %} </label> - {% if sample_groups[0].attributes %} + <label for="filter_samples_field">Filter samples by {% if (numerical_var_list|length == 0) and (not js_data.se_exists) %}value{% endif %} </label> + {% if (numerical_var_list|length > 0) or js_data.se_exists %} <select id="filter_column"> <option value="value">Value</option> {% if js_data.se_exists %} <option value="stderr">SE</option> {% endif %} - {% for attribute in sample_groups[0].attributes %} - + {% for attribute in numerical_var_list %} <option value="{{ loop.index }}"> - {{ sample_groups[0].attributes[attribute].name }} + {{ attribute }} </option> - {% endfor %} </select> {% endif %} @@ -116,4 +114,4 @@ <p>Samples with no value (x) can be hidden by clicking<strong>Hide No Value</strong> button.</p> </div> -</div>
\ No newline at end of file +</div> |