diff --git a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage.query.xml b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage.query.xml
index f4f2e91b2..d78f3a033 100644
--- a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage.query.xml
+++ b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage.query.xml
@@ -9,6 +9,14 @@
true
true
+
+ Analysis Id
+
+ sequenceanalysis
+ sequence_analyses
+ rowid
+
+
150
diff --git a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage.sql b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage.sql
index 7ab8394a5..544b2d361 100644
--- a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage.sql
+++ b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage.sql
@@ -1,51 +1,45 @@
-PARAMETERS(AnalysisId INTEGER)
-
-select
- (CAST(AnalysisId as varchar) || '<>' || a.lineages) as key,
- a.analysis_id,
- a.lineages,
- max(a.totalLineages) as totalLineages,
- a.loci,
-
- sum(a.total) as total,
- max(a.total_reads) as total_reads,
- round(100 * (cast(sum(a.total) as float) / cast(max(a.total_reads) as float)), 2) as percent,
- group_concat(distinct a.haplotypesWithAllele) as haplotypesWithAllele,
-
- CAST((select sum(s.total) as total FROM sequenceanalysis.alignment_summary s WHERE s.analysis_id = AnalysisId AND s.rowid IN (
- SELECT distinct asj.alignment_id from sequenceanalysis.alignment_summary_junction asj WHERE asj.analysis_id = AnalysisId AND asj.ref_nt_id.locus = a.loci and asj.status = true
- )
- ) as integer) as total_reads_from_locus,
-
- round(100 * (cast(sum(a.total) as float) / cast((select sum(s.total) as total FROM sequenceanalysis.alignment_summary s WHERE s.analysis_id = AnalysisId AND s.rowid IN (
- SELECT distinct asj.alignment_id from sequenceanalysis.alignment_summary_junction asj WHERE asj.analysis_id = AnalysisId AND asj.ref_nt_id.locus = a.loci and asj.status = true
- )
- ) as float)), 2) as percent_from_locus,
- group_concat(distinct a.rowid, ',') as rowids
+SELECT
+ t.*,
+ CASE WHEN t.total_reads_from_locus = 0 THEN 0 ELSE round(100 * (cast(t.total_reads as float) / cast(t.total_reads_from_locus as float)), 2) END as percent_from_locus,
FROM (
-
- select
- a.analysis_id,
- a.rowid,
-
- group_concat(distinct coalesce(j.ref_nt_id.lineage, j.ref_nt_id.name), chr(10)) as lineages,
- count(distinct j.ref_nt_id.lineage) as totalLineages,
- group_concat(distinct coalesce(j.ref_nt_id.locus, j.ref_nt_id.name), chr(10)) as loci,
-
- total,
- cast((select sum(total) as total FROM sequenceanalysis.alignment_summary s WHERE s.analysis_id = AnalysisId) as integer) as total_reads,
- group_concat(distinct hs.haplotype, chr(10)) as haplotypesWithAllele
-
- from sequenceanalysis.alignment_summary a
- join sequenceanalysis.alignment_summary_junction j ON (j.analysis_id = AnalysisId AND j.alignment_id = a.rowid and j.status = true)
- left join sequenceanalysis.haplotype_sequences hs ON ((
- (hs.name = j.ref_nt_id.lineage AND hs.type = 'Lineage') OR
- (hs.name = j.ref_nt_id.name AND hs.type = 'Allele')
- ) AND hs.haplotype.datedisabled IS NULL)
- WHERE a.analysis_id = AnalysisId
- group by a.analysis_id, a.rowid, a.total
-
-) a
-
-GROUP BY a.analysis_id, a.lineages, a.loci
+ SELECT
+ (CAST(a.analysis_id as varchar) || '<>' || a.lineages) as key,
+ a.analysis_id,
+ max(a.lineages) as lineages,
+ coalesce(max(a.totalLineages), 0) as totalLineages,
+ a.loci,
+
+ sum(a.total) as total_reads,
+ max(a.total_reads_in_analysis) as total_reads_in_analysis,
+ CASE WHEN max(a.total_reads_in_analysis) = 0 THEN 0 ELSE round(100 * (cast(sum(a.total) as float) / cast(max(a.total_reads_in_analysis) as float)), 2) END as percent,
+
+ group_concat(a.rowid, ',') as rowids,
+ group_concat(distinct a.haplotypesWithAllele) as haplotypesWithAllele,
+
+ max(a.total_reads_from_locus) as total_reads_from_locus,
+ max(a.lastModified) as lastModified,
+ count(distinct a.rowid) as nAlignments
+
+ FROM (
+
+ select
+ ac.analysis_id,
+ ac.rowid,
+
+ group_concat(distinct coalesce(ac.lineage, ac.ntName), chr(10)) as lineages,
+ count(distinct ac.lineage) as totalLineages,
+ group_concat(distinct coalesce(ac.locus, ac.ntName), chr(10)) as loci,
+
+ group_concat(distinct haplotypesWithAllele, chr(10)) as haplotypesWithAllele,
+
+ max(ac.total) as total,
+ max(ac.total_reads_in_analysis) as total_reads_in_analysis,
+ max(ac.total_reads_from_locus) as total_reads_from_locus,
+ max(ac.modified) as lastModified
+ from sequenceanalysis.alignment_summary_combined ac
+ group by ac.analysis_id, ac.rowid, ac.total
+ ) a
+
+ GROUP BY a.analysis_id, a.lineages, a.loci
+) t
\ No newline at end of file
diff --git a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage/.qview.xml b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage/.qview.xml
index 7b6dac64b..9c03eeb42 100644
--- a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage/.qview.xml
+++ b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage/.qview.xml
@@ -19,8 +19,8 @@
-
+
diff --git a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage/With Haplotype Matches.qview.xml b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage/With Haplotype Matches.qview.xml
index 1b4726c31..185a76068 100644
--- a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage/With Haplotype Matches.qview.xml
+++ b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage/With Haplotype Matches.qview.xml
@@ -19,8 +19,8 @@
-
+
diff --git a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage_orig.sql b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage_orig.sql
new file mode 100644
index 000000000..7ab8394a5
--- /dev/null
+++ b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_by_lineage_orig.sql
@@ -0,0 +1,51 @@
+PARAMETERS(AnalysisId INTEGER)
+
+select
+ (CAST(AnalysisId as varchar) || '<>' || a.lineages) as key,
+ a.analysis_id,
+ a.lineages,
+ max(a.totalLineages) as totalLineages,
+ a.loci,
+
+ sum(a.total) as total,
+ max(a.total_reads) as total_reads,
+ round(100 * (cast(sum(a.total) as float) / cast(max(a.total_reads) as float)), 2) as percent,
+ group_concat(distinct a.haplotypesWithAllele) as haplotypesWithAllele,
+
+ CAST((select sum(s.total) as total FROM sequenceanalysis.alignment_summary s WHERE s.analysis_id = AnalysisId AND s.rowid IN (
+ SELECT distinct asj.alignment_id from sequenceanalysis.alignment_summary_junction asj WHERE asj.analysis_id = AnalysisId AND asj.ref_nt_id.locus = a.loci and asj.status = true
+ )
+ ) as integer) as total_reads_from_locus,
+
+ round(100 * (cast(sum(a.total) as float) / cast((select sum(s.total) as total FROM sequenceanalysis.alignment_summary s WHERE s.analysis_id = AnalysisId AND s.rowid IN (
+ SELECT distinct asj.alignment_id from sequenceanalysis.alignment_summary_junction asj WHERE asj.analysis_id = AnalysisId AND asj.ref_nt_id.locus = a.loci and asj.status = true
+ )
+ ) as float)), 2) as percent_from_locus,
+ group_concat(distinct a.rowid, ',') as rowids
+
+FROM (
+
+ select
+ a.analysis_id,
+ a.rowid,
+
+ group_concat(distinct coalesce(j.ref_nt_id.lineage, j.ref_nt_id.name), chr(10)) as lineages,
+ count(distinct j.ref_nt_id.lineage) as totalLineages,
+ group_concat(distinct coalesce(j.ref_nt_id.locus, j.ref_nt_id.name), chr(10)) as loci,
+
+ total,
+ cast((select sum(total) as total FROM sequenceanalysis.alignment_summary s WHERE s.analysis_id = AnalysisId) as integer) as total_reads,
+ group_concat(distinct hs.haplotype, chr(10)) as haplotypesWithAllele
+
+ from sequenceanalysis.alignment_summary a
+ join sequenceanalysis.alignment_summary_junction j ON (j.analysis_id = AnalysisId AND j.alignment_id = a.rowid and j.status = true)
+ left join sequenceanalysis.haplotype_sequences hs ON ((
+ (hs.name = j.ref_nt_id.lineage AND hs.type = 'Lineage') OR
+ (hs.name = j.ref_nt_id.name AND hs.type = 'Allele')
+ ) AND hs.haplotype.datedisabled IS NULL)
+ WHERE a.analysis_id = AnalysisId
+ group by a.analysis_id, a.rowid, a.total
+
+) a
+
+GROUP BY a.analysis_id, a.lineages, a.loci
diff --git a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_combined.query.xml b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_combined.query.xml
new file mode 100644
index 000000000..b96e6d860
--- /dev/null
+++ b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_combined.query.xml
@@ -0,0 +1,23 @@
+
+
+
+
+ Alignment Summary, Combined
+
+
+ Total First-Mate Reads
+ The column shows the number of alignments that contain a first-mate or singleton read
+
+
+ Total Second-Mate Reads
+ The column shows the number of alignments that contain a second-mate read
+
+
+ Total Valid Pairs
+ The column shows the number of alignments that contain valid paired reads (both forward and reverse)
+
+
+
+
+
+
diff --git a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_grouped.query.xml b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_grouped.query.xml
index 4f755a30e..9eb153f0d 100644
--- a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_grouped.query.xml
+++ b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_grouped.query.xml
@@ -6,6 +6,14 @@
Alignment Summary
rowids
+
+ Analysis Id
+
+ sequenceanalysis
+ sequence_analyses
+ rowid
+
+
RowIds
true
diff --git a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_grouped.sql b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_grouped.sql
index ee61c695e..62f16b6e4 100644
--- a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_grouped.sql
+++ b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_grouped.sql
@@ -1,70 +1,55 @@
-PARAMETERS(AnalysisId INTEGER)
-
-select
- a.analysis_id,
- a.alleles,
- a.alleleIds,
- max(a.lineages) as lineages,
- coalesce(max(a.totalLineages), 0) as totalLineages,
- a.loci,
-
- sum(a.total) as total_reads,
- sum(a.total_forward) as total_forward,
- sum(a.total_reverse) as total_reverse,
- sum(a.valid_pairs) as valid_pairs,
- max(cast(a.total_reads as integer)) as total_reads_in_analysis,
- --max(a.loci_total_reads) as total_reads_in_analysis_from_locus,
- CASE WHEN max(a.total_reads) = 0 THEN 0 ELSE round(100 * (cast(sum(a.total) as float) / cast(max(a.total_reads) as float)), 2) END as percent,
--- case
--- when (cast(sum(a.total) as float) / cast(max(a.total_reads) as float)) >= .04 THEN 'Major'
--- else 'Minor'
--- end as category,
-
- group_concat(a.rowid, ',') as rowids,
- group_concat(distinct a.haplotypesWithAllele) as haplotypesWithAllele,
-
- CAST((select sum(s.total) as total FROM sequenceanalysis.alignment_summary s WHERE s.analysis_id = AnalysisId AND s.rowid IN (
- SELECT distinct asj.alignment_id from sequenceanalysis.alignment_summary_junction asj WHERE asj.analysis_id = AnalysisId AND asj.ref_nt_id.locus = a.loci and asj.status = true
- )
- ) as INTEGER) as total_reads_from_locus,
-
- round(100 * (cast(sum(a.total) as float) / CASE WHEN count(a.lineages) = 0 THEN max(a.total_reads) ELSE cast((select sum(s.total) as total FROM sequenceanalysis.alignment_summary s WHERE s.analysis_id = AnalysisId AND s.rowid IN (
- SELECT distinct asj.alignment_id from sequenceanalysis.alignment_summary_junction asj WHERE asj.analysis_id = AnalysisId AND asj.ref_nt_id.locus = a.loci and asj.status = true
- )
- ) as float) END), 2) as percent_from_locus,
- max(lastModified) as lastModified,
- count(distinct a.rowid) as nAlignments,
- max(a.nloci) as nLoci
+SELECT
+ t.*,
+ CASE WHEN t.total_reads_from_locus = 0 THEN 0 ELSE round(100 * (cast(t.total_reads as float) / cast(t.total_reads_from_locus as float)), 2) END as percent_from_locus,
FROM (
-
- select
- a.analysis_id,
- a.rowid,
-
- group_concat(distinct j.ref_nt_id) as alleleIds,
- group_concat(distinct j.ref_nt_id.name, chr(10)) as alleles,
- group_concat(distinct j.ref_nt_id.lineage, chr(10)) as lineages,
- count(distinct j.ref_nt_id.lineage) as totalLineages,
- group_concat(distinct j.ref_nt_id.locus, chr(10)) as loci,
- count(distinct j.ref_nt_id.locus) as nloci,
- group_concat(distinct hs.haplotype, chr(10)) as haplotypesWithAllele,
-
- total,
- total_forward,
- total_reverse,
- valid_pairs,
- (select sum(total) as total FROM sequenceanalysis.alignment_summary s WHERE s.analysis_id = AnalysisId) as total_reads,
- max(j.modified) as lastModified
- from sequenceanalysis.alignment_summary a
- left join sequenceanalysis.alignment_summary_junction j ON (j.analysis_id = AnalysisId AND j.alignment_id = a.rowid and j.status = true)
- left join sequenceanalysis.haplotype_sequences hs ON ((
- (hs.name = j.ref_nt_id.lineage AND hs.type = 'Lineage') OR
- (hs.name = j.ref_nt_id.name AND hs.type = 'Allele')
- ) AND hs.haplotype.datedisabled IS NULL)
- WHERE a.analysis_id = AnalysisId
- group by a.analysis_id, a.rowid, a.total, total_forward, total_reverse, valid_pairs
-
-) a
-
-GROUP BY a.analysis_id, a.alleles, a.alleleIds, a.loci
+ SELECT
+ a.analysis_id,
+ a.alleles,
+ a.alleleIds,
+ max(a.lineages) as lineages,
+ coalesce(max(a.totalLineages), 0) as totalLineages,
+ a.loci,
+
+ sum(a.total) as total_reads,
+ sum(a.total_forward) as total_forward,
+ sum(a.total_reverse) as total_reverse,
+ sum(a.valid_pairs) as valid_pairs,
+ max(a.total_reads_in_analysis) as total_reads_in_analysis,
+ CASE WHEN max(a.total_reads_in_analysis) = 0 THEN 0 ELSE round(100 * (cast(sum(a.total) as float) / cast(max(a.total_reads_in_analysis) as float)), 2) END as percent,
+
+ group_concat(a.rowid, ',') as rowids,
+ group_concat(distinct a.haplotypesWithAllele) as haplotypesWithAllele,
+
+ max(a.total_reads_from_locus) as total_reads_from_locus,
+ max(a.lastModified) as lastModified,
+ count(distinct a.rowid) as nAlignments,
+ max(a.nloci) as nLoci
+
+ FROM (
+
+ select
+ ac.analysis_id,
+ ac.rowid,
+
+ group_concat(distinct ac.ref_nt_id) as alleleIds,
+ group_concat(distinct ac.ntName, chr(10)) as alleles,
+ group_concat(distinct ac.lineage, chr(10)) as lineages,
+ count(distinct ac.lineage) as totalLineages,
+ group_concat(distinct ac.locus, chr(10)) as loci,
+ count(distinct ac.locus) as nloci,
+ group_concat(distinct haplotypesWithAllele, chr(10)) as haplotypesWithAllele,
+
+ max(ac.total) as total,
+ max(ac.total_forward) as total_forward,
+ max(ac.total_reverse) as total_reverse,
+ max(ac.valid_pairs) as valid_pairs,
+ max(ac.total_reads_in_analysis) as total_reads_in_analysis,
+ max(ac.total_reads_from_locus) as total_reads_from_locus,
+ max(ac.modified) as lastModified
+ from sequenceanalysis.alignment_summary_combined ac
+ group by ac.analysis_id, ac.rowid
+ ) a
+
+ GROUP BY a.analysis_id, a.alleles, a.alleleIds, a.loci
+) t
\ No newline at end of file
diff --git a/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_grouped_orig.sql b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_grouped_orig.sql
new file mode 100644
index 000000000..ee61c695e
--- /dev/null
+++ b/SequenceAnalysis/resources/queries/sequenceanalysis/alignment_summary_grouped_orig.sql
@@ -0,0 +1,70 @@
+PARAMETERS(AnalysisId INTEGER)
+
+select
+ a.analysis_id,
+ a.alleles,
+ a.alleleIds,
+ max(a.lineages) as lineages,
+ coalesce(max(a.totalLineages), 0) as totalLineages,
+ a.loci,
+
+ sum(a.total) as total_reads,
+ sum(a.total_forward) as total_forward,
+ sum(a.total_reverse) as total_reverse,
+ sum(a.valid_pairs) as valid_pairs,
+ max(cast(a.total_reads as integer)) as total_reads_in_analysis,
+ --max(a.loci_total_reads) as total_reads_in_analysis_from_locus,
+ CASE WHEN max(a.total_reads) = 0 THEN 0 ELSE round(100 * (cast(sum(a.total) as float) / cast(max(a.total_reads) as float)), 2) END as percent,
+-- case
+-- when (cast(sum(a.total) as float) / cast(max(a.total_reads) as float)) >= .04 THEN 'Major'
+-- else 'Minor'
+-- end as category,
+
+ group_concat(a.rowid, ',') as rowids,
+ group_concat(distinct a.haplotypesWithAllele) as haplotypesWithAllele,
+
+ CAST((select sum(s.total) as total FROM sequenceanalysis.alignment_summary s WHERE s.analysis_id = AnalysisId AND s.rowid IN (
+ SELECT distinct asj.alignment_id from sequenceanalysis.alignment_summary_junction asj WHERE asj.analysis_id = AnalysisId AND asj.ref_nt_id.locus = a.loci and asj.status = true
+ )
+ ) as INTEGER) as total_reads_from_locus,
+
+ round(100 * (cast(sum(a.total) as float) / CASE WHEN count(a.lineages) = 0 THEN max(a.total_reads) ELSE cast((select sum(s.total) as total FROM sequenceanalysis.alignment_summary s WHERE s.analysis_id = AnalysisId AND s.rowid IN (
+ SELECT distinct asj.alignment_id from sequenceanalysis.alignment_summary_junction asj WHERE asj.analysis_id = AnalysisId AND asj.ref_nt_id.locus = a.loci and asj.status = true
+ )
+ ) as float) END), 2) as percent_from_locus,
+ max(lastModified) as lastModified,
+ count(distinct a.rowid) as nAlignments,
+ max(a.nloci) as nLoci
+
+FROM (
+
+ select
+ a.analysis_id,
+ a.rowid,
+
+ group_concat(distinct j.ref_nt_id) as alleleIds,
+ group_concat(distinct j.ref_nt_id.name, chr(10)) as alleles,
+ group_concat(distinct j.ref_nt_id.lineage, chr(10)) as lineages,
+ count(distinct j.ref_nt_id.lineage) as totalLineages,
+ group_concat(distinct j.ref_nt_id.locus, chr(10)) as loci,
+ count(distinct j.ref_nt_id.locus) as nloci,
+ group_concat(distinct hs.haplotype, chr(10)) as haplotypesWithAllele,
+
+ total,
+ total_forward,
+ total_reverse,
+ valid_pairs,
+ (select sum(total) as total FROM sequenceanalysis.alignment_summary s WHERE s.analysis_id = AnalysisId) as total_reads,
+ max(j.modified) as lastModified
+ from sequenceanalysis.alignment_summary a
+ left join sequenceanalysis.alignment_summary_junction j ON (j.analysis_id = AnalysisId AND j.alignment_id = a.rowid and j.status = true)
+ left join sequenceanalysis.haplotype_sequences hs ON ((
+ (hs.name = j.ref_nt_id.lineage AND hs.type = 'Lineage') OR
+ (hs.name = j.ref_nt_id.name AND hs.type = 'Allele')
+ ) AND hs.haplotype.datedisabled IS NULL)
+ WHERE a.analysis_id = AnalysisId
+ group by a.analysis_id, a.rowid, a.total, total_forward, total_reverse, valid_pairs
+
+) a
+
+GROUP BY a.analysis_id, a.alleles, a.alleleIds, a.loci
diff --git a/SequenceAnalysis/src/org/labkey/sequenceanalysis/SequenceAnalysisSchema.java b/SequenceAnalysis/src/org/labkey/sequenceanalysis/SequenceAnalysisSchema.java
index 452be9a16..3f1c4421f 100644
--- a/SequenceAnalysis/src/org/labkey/sequenceanalysis/SequenceAnalysisSchema.java
+++ b/SequenceAnalysis/src/org/labkey/sequenceanalysis/SequenceAnalysisSchema.java
@@ -53,6 +53,7 @@ public class SequenceAnalysisSchema
public static final String TABLE_ANALYSIS_SETS = "analysisSets";
public static final String TABLE_ANALYSIS_SET_MEMBERS = "analysisSetMembers";
public static final String TABLE_READ_DATA = "readData";
+ public static final String TABLE_ALIGNMENT_SUMMARY_COMBINED = "alignment_summary_combined";
public static SequenceAnalysisSchema getInstance()
{
diff --git a/SequenceAnalysis/src/org/labkey/sequenceanalysis/query/AlignmentSummaryGroupedTableInfo.java b/SequenceAnalysis/src/org/labkey/sequenceanalysis/query/AlignmentSummaryGroupedTableInfo.java
new file mode 100644
index 000000000..7fdd87800
--- /dev/null
+++ b/SequenceAnalysis/src/org/labkey/sequenceanalysis/query/AlignmentSummaryGroupedTableInfo.java
@@ -0,0 +1,163 @@
+package org.labkey.sequenceanalysis.query;
+
+import org.jetbrains.annotations.NotNull;
+import org.labkey.api.data.AbstractTableInfo;
+import org.labkey.api.data.BaseColumnInfo;
+import org.labkey.api.data.JdbcType;
+import org.labkey.api.data.MutableColumnInfo;
+import org.labkey.api.data.SQLFragment;
+import org.labkey.api.data.dialect.SqlDialect;
+import org.labkey.api.query.ExprColumn;
+import org.labkey.api.query.QueryForeignKey;
+import org.labkey.api.query.UserSchema;
+import org.labkey.sequenceanalysis.SequenceAnalysisSchema;
+
+/**
+ * The purpose of this table is to perform several important joins without the LK overhead of containers, providing a simpler pre-joined view of the data.
+ */
+public class AlignmentSummaryGroupedTableInfo extends AbstractTableInfo
+{
+ private final UserSchema _userSchema;
+
+ public AlignmentSummaryGroupedTableInfo(UserSchema schema)
+ {
+ super(schema.getDbSchema(), SequenceAnalysisSchema.TABLE_ALIGNMENT_SUMMARY_COMBINED);
+ _userSchema = schema;
+
+ setTitle("Alignment Summary Data Combined");
+ setupColumns();
+ }
+
+ private void setupColumns()
+ {
+ MutableColumnInfo analysisIdCol = new BaseColumnInfo("analysis_id", this, JdbcType.BIGINT);
+ analysisIdCol.setLabel("Analysis Id");
+ //analysisIdCol.setFk(new QueryForeignKey.Builder(getUserSchema(), getContainerFilter()).schema(SequenceAnalysisSchema.SCHEMA_NAME).table(SequenceAnalysisSchema.TABLE_ANALYSES).key("rowid").display("rowid"));
+ addColumn(analysisIdCol);
+
+ MutableColumnInfo rowIdCol = new BaseColumnInfo("rowid", this, JdbcType.BIGINT);
+ rowIdCol.setLabel("Alignment Id");
+ //analysisIdCol.setFk(new QueryForeignKey.Builder(getUserSchema(), getContainerFilter()).schema(SequenceAnalysisSchema.SCHEMA_NAME).table(SequenceAnalysisSchema.TABLE_ANALYSES).key("rowid").display("rowid"));
+ addColumn(rowIdCol);
+
+ MutableColumnInfo readsetCol = new BaseColumnInfo("readset", this, JdbcType.BIGINT);
+ readsetCol.setLabel("Readset");
+ //readsetCol.setFk(new QueryForeignKey.Builder(getUserSchema(), getContainerFilter()).schema(SequenceAnalysisSchema.SCHEMA_NAME).table(SequenceAnalysisSchema.TABLE_READSETS).key("rowid").display("name"));
+ addColumn(readsetCol);
+
+ MutableColumnInfo ntId = new BaseColumnInfo("ref_nt_id", this, JdbcType.BIGINT);
+ ntId.setLabel("NT Sequence");
+ //ntId.setFk(new QueryForeignKey.Builder(getUserSchema(), getContainerFilter()).schema(SequenceAnalysisSchema.SCHEMA_NAME).table(SequenceAnalysisSchema.TABLE_REF_NT_SEQUENCES).key("rowid").display("name"));
+ addColumn(ntId);
+
+ MutableColumnInfo ntName = new BaseColumnInfo("ntName", this, JdbcType.VARCHAR);
+ ntName.setLabel("NT Sequence Name");
+ addColumn(ntName);
+
+ MutableColumnInfo ntLineage = new BaseColumnInfo("lineage", this, JdbcType.VARCHAR);
+ ntLineage.setLabel("NT Lineage");
+ addColumn(ntLineage);
+
+ MutableColumnInfo ntLocus = new BaseColumnInfo("locus", this, JdbcType.VARCHAR);
+ ntLocus.setLabel("NT Locus");
+ addColumn(ntLocus);
+
+ MutableColumnInfo totalCol = new BaseColumnInfo("total", this, JdbcType.BIGINT);
+ totalCol.setLabel("Total Reads");
+ addColumn(totalCol);
+
+ MutableColumnInfo totalForwardCol = new BaseColumnInfo("total_forward", this, JdbcType.BIGINT);
+ totalForwardCol.setLabel("Total Forward Reads");
+ addColumn(totalForwardCol);
+
+ MutableColumnInfo totalReverseCol = new BaseColumnInfo("total_reverse", this, JdbcType.BIGINT);
+ totalReverseCol.setLabel("Total Reverse Reads");
+ addColumn(totalReverseCol);
+
+ MutableColumnInfo validPairsCol = new BaseColumnInfo("valid_pairs", this, JdbcType.BIGINT);
+ validPairsCol.setLabel("Total Valid Pairs");
+ addColumn(validPairsCol);
+
+ MutableColumnInfo totalReadsInAnalysis = new BaseColumnInfo("total_reads_in_analysis", this, JdbcType.BIGINT);
+ totalReadsInAnalysis.setLabel("Total Reads In Analysis");
+ addColumn(totalReadsInAnalysis);
+
+ SQLFragment sql = new SQLFragment("(SELECT sum(xs.total) as expr FROM (SELECT xs.total \n" +
+ "FROM sequenceanalysis.sequence_analyses xa\n" +
+ "JOIN sequenceanalysis.alignment_summary xs ON (xa.rowid = xs.analysis_id) \n" +
+ "JOIN sequenceanalysis.alignment_summary_junction xasj ON (xasj.status = " + getSqlDialect().getBooleanTRUE() + " AND xs.rowid = xasj.alignment_id)\n" +
+ "JOIN sequenceanalysis.ref_nt_sequences xnt ON (xnt.rowid = xasj.ref_nt_id)\n" +
+ "WHERE xa.rowid = " + ExprColumn.STR_TABLE_ALIAS + ".analysis_id AND xnt.locus = " + ExprColumn.STR_TABLE_ALIAS + ".locus\n" +
+ "GROUP BY xs.rowid, xs.total) xs)");
+
+ ExprColumn totalReadsFromLocus = new ExprColumn(this, "total_reads_from_locus", sql, JdbcType.BIGINT, getColumn("analysis_id"), getColumn("locus"));
+ totalReadsFromLocus.setLabel("Total Reads From Locus");
+ addColumn(totalReadsFromLocus);
+
+ MutableColumnInfo haplotypesWithAlleleCol = new BaseColumnInfo("haplotypesWithAllele", this, JdbcType.VARCHAR);
+ haplotypesWithAlleleCol.setLabel("Haplotypes With Allele");
+ addColumn(haplotypesWithAlleleCol);
+
+ MutableColumnInfo containerCol = new BaseColumnInfo("container", this, JdbcType.GUID);
+ containerCol.setLabel("Folder");
+ containerCol.setFk(new QueryForeignKey.Builder(getUserSchema(), getContainerFilter()).schema("core").table("containers"));
+ addColumn(containerCol);
+
+ MutableColumnInfo createdCol = new BaseColumnInfo("created", this, JdbcType.TIMESTAMP);
+ createdCol.setLabel("Created");
+ addColumn(createdCol);
+
+ MutableColumnInfo createdByCol = new BaseColumnInfo("createdby", this, JdbcType.BIGINT);
+ createdByCol.setLabel("Created By");
+ createdByCol.setFk(new QueryForeignKey.Builder(getUserSchema(), getContainerFilter()).schema("core").table("users").key("rowid"));
+ addColumn(createdByCol);
+
+ MutableColumnInfo modifiedCol = new BaseColumnInfo("modified", this, JdbcType.TIMESTAMP);
+ modifiedCol.setLabel("Modified");
+ addColumn(modifiedCol);
+
+ MutableColumnInfo modifiedByCol = new BaseColumnInfo("modifiedby", this, JdbcType.BIGINT);
+ modifiedByCol.setLabel("Modified By");
+ modifiedByCol.setFk(new QueryForeignKey.Builder(getUserSchema(), getContainerFilter()).schema("core").table("users").key("rowid"));
+ addColumn(modifiedByCol);
+ }
+
+ @Override
+ protected SQLFragment getFromSQL()
+ {
+ final SqlDialect sd = getUserSchema().getDbSchema().getSqlDialect();
+ final String chr = sd.isPostgreSQL() ? "chr" : "char";
+
+ return new SQLFragment("SELECT\n" +
+ "a.rowid as analysis_id,\n" +
+ "al.rowid,\n" +
+ "a.readset,\n" +
+ "nt.rowid as ref_nt_id,\n" +
+ "nt.name as ntName,\n" +
+ "nt.lineage as lineage,\n" +
+ "nt.locus as locus,\n" +
+ "a.container,\n" +
+ "a.created,\n" +
+ "a.createdBy,\n" +
+ "a.modified,\n" +
+ "a.modifiedBy,\n" +
+ "al.total,\n" +
+ "al.total_forward,\n" +
+ "al.total_reverse,\n" +
+ "al.valid_pairs,\n" +
+ "(SELECT sum(s.total) as expr FROM " + SequenceAnalysisSchema.SCHEMA_NAME + "." + SequenceAnalysisSchema.TABLE_ALIGNMENT_SUMMARY + " s WHERE s.analysis_id = a.rowId) as total_reads_in_analysis,\n" +
+ "(SELECT ").append(sd.getGroupConcat(new SQLFragment("hs.haplotype"), true, true, new SQLFragment(chr + "(10)"))).
+ append(" as expr FROM sequenceanalysis.haplotype_sequences hs JOIN sequenceanalysis.haplotypes ht ON (hs.haplotype = ht.name) WHERE ht.datedisabled IS NULL AND ((hs.type = 'Lineage' AND hs.name = nt.lineage) OR (hs.type = 'Allele' AND hs.name = nt.name))) as haplotypesWithAllele\n" + "\n" +
+ "FROM " + SequenceAnalysisSchema.SCHEMA_NAME + "." + SequenceAnalysisSchema.TABLE_ANALYSES + " a\n" +
+ "JOIN " + SequenceAnalysisSchema.SCHEMA_NAME + "." + SequenceAnalysisSchema.TABLE_ALIGNMENT_SUMMARY + " al ON (a.RowId = al.analysis_id)\n" +
+ "LEFT JOIN " + SequenceAnalysisSchema.SCHEMA_NAME + "." + SequenceAnalysisSchema.TABLE_ALIGNMENT_SUMMARY_JUNCTION + " asj ON (al.rowid = asj.alignment_id)\n" +
+ "LEFT JOIN " + SequenceAnalysisSchema.SCHEMA_NAME + "." + SequenceAnalysisSchema.TABLE_REF_NT_SEQUENCES + " nt ON (nt.rowid = asj.ref_nt_id)\n" +
+ "WHERE asj.status = ").append(sd.getBooleanTRUE());
+ }
+
+ @Override
+ public @NotNull UserSchema getUserSchema()
+ {
+ return _userSchema;
+ }
+}
diff --git a/SequenceAnalysis/src/org/labkey/sequenceanalysis/query/SequenceAnalysisUserSchema.java b/SequenceAnalysis/src/org/labkey/sequenceanalysis/query/SequenceAnalysisUserSchema.java
index 9757cfc34..162a93f6e 100644
--- a/SequenceAnalysis/src/org/labkey/sequenceanalysis/query/SequenceAnalysisUserSchema.java
+++ b/SequenceAnalysis/src/org/labkey/sequenceanalysis/query/SequenceAnalysisUserSchema.java
@@ -1,8 +1,10 @@
package org.labkey.sequenceanalysis.query;
import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.labkey.api.collections.CaseInsensitiveTreeSet;
import org.labkey.api.data.AbstractTableInfo;
import org.labkey.api.data.ColumnInfo;
import org.labkey.api.data.CompareType;
@@ -15,6 +17,7 @@
import org.labkey.api.data.JdbcType;
import org.labkey.api.data.RenderContext;
import org.labkey.api.data.SQLFragment;
+import org.labkey.api.data.SchemaTableInfo;
import org.labkey.api.data.TableInfo;
import org.labkey.api.data.WrappedColumn;
import org.labkey.api.ldk.LDKService;
@@ -25,6 +28,7 @@
import org.labkey.api.query.DetailsURL;
import org.labkey.api.query.ExprColumn;
import org.labkey.api.query.FieldKey;
+import org.labkey.api.query.FilteredTable;
import org.labkey.api.query.QueryAction;
import org.labkey.api.query.QuerySchema;
import org.labkey.api.query.QueryService;
@@ -34,13 +38,17 @@
import org.labkey.api.util.HtmlString;
import org.labkey.api.util.LinkBuilder;
import org.labkey.api.util.PageFlowUtil;
+import org.labkey.api.util.logging.LogHelper;
import org.labkey.api.view.ActionURL;
import org.labkey.api.writer.HtmlWriter;
import org.labkey.sequenceanalysis.SequenceAnalysisSchema;
import org.labkey.sequenceanalysis.SequenceAnalysisServiceImpl;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.LinkedHashSet;
+import java.util.Set;
/**
* User: bimber
@@ -49,25 +57,48 @@
*/
public class SequenceAnalysisUserSchema extends SimpleUserSchema
{
- private SequenceAnalysisUserSchema(User user, Container container, DbSchema schema)
+ private static final Logger _log = LogHelper.getLogger(SequenceAnalysisUserSchema.class, "Messages related to SequenceAnalysisUserSchema");
+
+ private SequenceAnalysisUserSchema(User user, Container container, DbSchema schema, Set available)
{
- super(SequenceAnalysisSchema.SCHEMA_NAME, null, user, container, schema);
+ super(SequenceAnalysisSchema.SCHEMA_NAME, null, user, container, schema, null, available, null);
}
public static void register(final Module m)
{
final DbSchema dbSchema = SequenceAnalysisSchema.getInstance().getSchema();
+ final Set available = new CaseInsensitiveTreeSet();
+ for (String tableName : dbSchema.getTableNames())
+ {
+ SchemaTableInfo table = dbSchema.getTable(tableName);
+ if (null != table)
+ available.add(table.getName());
+ else
+ _log.error("Schema '" + dbSchema.getName() + "' provided tableName '" + tableName + "', but not actual table.");
+ }
+ available.add(SequenceAnalysisSchema.TABLE_ALIGNMENT_SUMMARY_COMBINED);
DefaultSchema.registerProvider(SequenceAnalysisSchema.SCHEMA_NAME, new DefaultSchema.SchemaProvider(m)
{
@Override
public QuerySchema createSchema(final DefaultSchema schema, Module module)
{
- return new SequenceAnalysisUserSchema(schema.getUser(), schema.getContainer(), dbSchema);
+ return new SequenceAnalysisUserSchema(schema.getUser(), schema.getContainer(), dbSchema, available);
}
});
}
+ @Override
+ public TableInfo createTable(String name, ContainerFilter cf)
+ {
+ if (SequenceAnalysisSchema.TABLE_ALIGNMENT_SUMMARY_COMBINED.equalsIgnoreCase(name))
+ {
+ return createAlignmentSummaryCombined(cf);
+ }
+
+ return super.createTable(name, cf);
+ }
+
@Override
@Nullable
protected TableInfo createWrappedTable(String name, @NotNull TableInfo sourceTable, ContainerFilter cf)
@@ -131,7 +162,29 @@ else if (SequenceAnalysisSchema.TABLE_ANALYSES.equalsIgnoreCase(name))
return createAnalysesTable(sourceTable, cf);
}
else
+ {
return super.createWrappedTable(name, sourceTable, cf);
+ }
+ }
+
+ @Override
+ public Set getTableNames()
+ {
+ Set ret = new HashSet<>(super.getTableNames());
+ ret.add(SequenceAnalysisSchema.TABLE_ALIGNMENT_SUMMARY_COMBINED);
+
+ return Collections.unmodifiableSet(ret);
+ }
+
+ @Override
+ public synchronized Set getVisibleTableNames()
+ {
+ return getTableNames();
+ }
+
+ private TableInfo createAlignmentSummaryCombined(ContainerFilter cf)
+ {
+ return new SimpleTable<>(this, new AlignmentSummaryGroupedTableInfo(this), cf).init();
}
private TableInfo createAnalysesTable(TableInfo sourceTable, ContainerFilter cf)
diff --git a/jbrowse/src/org/labkey/jbrowse/JBrowseModule.java b/jbrowse/src/org/labkey/jbrowse/JBrowseModule.java
index 15feab9e5..945d451aa 100644
--- a/jbrowse/src/org/labkey/jbrowse/JBrowseModule.java
+++ b/jbrowse/src/org/labkey/jbrowse/JBrowseModule.java
@@ -117,6 +117,7 @@ public void doStartupAfterSpringConfig(ModuleContext moduleContext)
// These are all part of the JBrowse demo data:
ContentSecurityPolicyFilter.registerAllowedSources(this.getClass().getName(), Directive.Connection, "https://jbrowse.org", "https://s3.amazonaws.com", "https://ftp.ncbi.nlm.nih.gov");
ContentSecurityPolicyFilter.registerAllowedSources(this.getClass().getName(), Directive.Style, "https://www.gstatic.com");
+ ContentSecurityPolicyFilter.registerAllowedSources(this.getClass().getName(), Directive.Font, "https://www.gstatic.com", "https://fonts.googleapis.com");
ContextListener.addShutdownListener(new JBrowseLuceneSearch.ShutdownHandler());
}