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()); }