diff --git a/PMR/resources/etls/pmr-datasets.xml b/PMR/resources/etls/pmr-datasets.xml
index 19e981726..1186b27a4 100644
--- a/PMR/resources/etls/pmr-datasets.xml
+++ b/PMR/resources/etls/pmr-datasets.xml
@@ -141,6 +141,8 @@
relationship
method
objectid
+ created
+ modified
@@ -171,6 +173,8 @@
conception
conceptualDay
objectid
+ created
+ modified
diff --git a/PMR/resources/etls/pmr-demographics.xml b/PMR/resources/etls/pmr-demographics.xml
index 9c06b7b3c..03b2bf94e 100644
--- a/PMR/resources/etls/pmr-demographics.xml
+++ b/PMR/resources/etls/pmr-demographics.xml
@@ -17,6 +17,8 @@
calculated_status
QCState/Label
objectid
+ created
+ modified
diff --git a/mGAP/resources/data/species.tsv b/mGAP/resources/data/species.tsv
new file mode 100644
index 000000000..2472af328
--- /dev/null
+++ b/mGAP/resources/data/species.tsv
@@ -0,0 +1,10 @@
+common_name scientific_name mhc_prefix
+Cotton-top Tamarin Saguinus oedipus Saoe
+Cynomolgus macaque Macaca fascicularis Mafa
+Marmoset Callithrix jacchus Caja
+Pigtail macaque Macaca nemestrina Mane
+Rhesus macaque Macaca mulatta Mamu
+Sooty Mangabey Cercocebus atys Ceat
+Stump Tailed Macaca Arctoides Maar
+Vervet Chlorocebus sabaeus Chsa
+Japanese macaque Macaca fuscata Mafu
diff --git a/mGAP/resources/etls/prime-seq.xml b/mGAP/resources/etls/prime-seq.xml
index 8b2bcecc9..312f0d033 100644
--- a/mGAP/resources/etls/prime-seq.xml
+++ b/mGAP/resources/etls/prime-seq.xml
@@ -53,12 +53,16 @@
releaseId
trackName
label
+ species
totalSamples
category
url
source
description
isprimarytrack
+ shouldindex
+ vcfIndexId/dataid/DataFileUrl
+ vcfIndexId/library_id/name
vcfId/dataid/DataFileUrl
vcfId/library_id/name
@@ -66,6 +70,7 @@
+
@@ -101,6 +106,7 @@
releaseDate
vcfId/dataid/DataFileUrl
genomeId/name
+ species
totalSubjects
totalVariants
dbSnpId
diff --git a/mGAP/resources/queries/mGAP/combinedPedigree.sql b/mGAP/resources/queries/mGAP/combinedPedigree.sql
index 55512965a..4725d8998 100644
--- a/mGAP/resources/queries/mGAP/combinedPedigree.sql
+++ b/mGAP/resources/queries/mGAP/combinedPedigree.sql
@@ -1,12 +1,12 @@
SELECT
- s.subjectname,
+ s.Id as subjectname,
s.gender,
- s.mother as dam,
- s.father as sire,
+ s.Id.parents.dam as dam,
+ s.Id.parents.sire as sire,
s.species,
- s.geographic_origin,
+ s.geographic_origin
-FROM laboratory.subjects s
+FROM "/Internal/PMR/".study.demographics s
UNION ALL
@@ -19,4 +19,4 @@ SELECT
null as geographic_origin
FROM mgap.demographics d
-WHERE d.subjectname NOT IN (SELECT DISTINCT s.subjectname FROM laboratory.subjects s)
\ No newline at end of file
+WHERE d.subjectname NOT IN (SELECT DISTINCT s.Id FROM "/Internal/PMR/".study.demographics s)
\ No newline at end of file
diff --git a/mGAP/resources/queries/mGAP/releaseTracks/.qview.xml b/mGAP/resources/queries/mGAP/releaseTracks/.qview.xml
index 08488c2ec..7de86c8ae 100644
--- a/mGAP/resources/queries/mGAP/releaseTracks/.qview.xml
+++ b/mGAP/resources/queries/mGAP/releaseTracks/.qview.xml
@@ -3,6 +3,7 @@
+
@@ -10,7 +11,6 @@
-
diff --git a/mGAP/resources/queries/mGAP/sampleSummary.query.xml b/mGAP/resources/queries/mGAP/sampleSummary.query.xml
index 4d9e68f7c..86a7a599e 100644
--- a/mGAP/resources/queries/mGAP/sampleSummary.query.xml
+++ b/mGAP/resources/queries/mGAP/sampleSummary.query.xml
@@ -2,8 +2,15 @@
+
subjectName
mGAP Subject/gVCF Summary
+
+
+ SubjectId Listed In Alias Table
+ true
+
+
diff --git a/mGAP/resources/queries/mGAP/sampleSummary.sql b/mGAP/resources/queries/mGAP/sampleSummary.sql
index 385533ddf..d45c1c4bb 100644
--- a/mGAP/resources/queries/mGAP/sampleSummary.sql
+++ b/mGAP/resources/queries/mGAP/sampleSummary.sql
@@ -8,7 +8,8 @@ SELECT
ss.center,
t.tracks,
t.total,
- CASE WHEN ss.originalId IS NULL OR ss.gender IS NULL or ss.species IS NULL or ss.center IS NULL THEN true ELSE false END as missingDemographics
+ CASE WHEN ss.originalId IS NULL OR ss.gender IS NULL or ss.species IS NULL or ss.center IS NULL THEN true ELSE false END as missingDemographics,
+ am.subjectname as aliasSubjectName
FROM (SELECT
COALESCE(o.readset.subjectId, rt.subjectId) as subjectId,
diff --git a/mGAP/resources/queries/mGAP/sampleSummary/.qview.xml b/mGAP/resources/queries/mGAP/sampleSummary/.qview.xml
new file mode 100644
index 000000000..48de68347
--- /dev/null
+++ b/mGAP/resources/queries/mGAP/sampleSummary/.qview.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/mGAP/resources/queries/mGAP/variantCatalogReleases/.qview.xml b/mGAP/resources/queries/mGAP/variantCatalogReleases/.qview.xml
index f8b614ee2..425728879 100644
--- a/mGAP/resources/queries/mGAP/variantCatalogReleases/.qview.xml
+++ b/mGAP/resources/queries/mGAP/variantCatalogReleases/.qview.xml
@@ -1,6 +1,7 @@
+
diff --git a/mGAP/resources/r/UpdateTracks.r b/mGAP/resources/r/UpdateTracks.r
new file mode 100644
index 000000000..8646b5cb0
--- /dev/null
+++ b/mGAP/resources/r/UpdateTracks.r
@@ -0,0 +1,115 @@
+library(Rlabkey)
+library(dplyr)
+
+# This script is designed to be run externally per release, to identify subject that need to be added to the releaseTrackSubsets table:
+
+testByCenter <- function(centerName, trackName) {
+ dat <- suppressWarnings(labkey.selectRows(
+ baseUrl="https://prime-seq.ohsu.edu",
+ folderPath="/Internal/ColonyData",
+ schemaName="mgap",
+ queryName="sampleSummary",
+ viewName="",
+ colSelect="subjectId,externalAlias",
+ colFilter=makeFilter(
+ c("tracks", "DOES_NOT_CONTAIN", trackName),
+ c("center", "EQUAL", centerName)),
+ containerFilter=NULL,
+ colNameOpt="rname"
+ ))
+
+ print(paste0(trackName, ': ', nrow(dat)))
+
+ if (nrow(dat) == 0) {
+ return(NULL)
+ }
+
+ return(data.frame(trackName = trackName, subjectId = dat$subjectid))
+}
+
+testBySpecies <- function(speciesList, trackName) {
+ dat <- suppressWarnings(labkey.selectRows(
+ baseUrl="https://prime-seq.ohsu.edu",
+ folderPath="/Internal/ColonyData",
+ schemaName="mgap",
+ queryName="sampleSummary",
+ viewName="",
+ colSelect="subjectId,externalAlias",
+ colFilter=makeFilter(
+ c("tracks", "DOES_NOT_CONTAIN", trackName),
+ c("species", "IN", paste0(speciesList, collapse = ';'))),
+ containerFilter=NULL,
+ colNameOpt="rname"
+ ))
+
+ print(paste0(trackName, ': ', nrow(dat)))
+
+ if (nrow(dat) == 0) {
+ return(NULL)
+ }
+
+ return(data.frame(trackName = trackName, subjectId = dat$subjectid))
+}
+
+toInsert <- rbind(
+ testByCenter('CNPRC', 'CNPRC Animals'),
+ testByCenter('TNPRC', 'TNPRC Animals'),
+ testByCenter('ENPRC', 'ENPRC Animals'),
+ testByCenter('NEPRC', 'NEPRC Animals'),
+ testByCenter('SNPRC', 'SNPRC Animals'),
+ testByCenter('ONPRC', 'ONPRC Animals'),
+ testByCenter('MDA', 'MDA Animals'),
+ testByCenter('WFU', 'WFU Animals'),
+ testByCenter('CPRC', 'CPRC Animals'),
+ testBySpecies(c('RHESUS MACAQUE', 'Rhesus', 'Macaca mulatta'), 'Rhesus Macaques'),
+ testBySpecies(c('JAPANESE MACAQUE', 'Macaca fuscata'), 'Japanese Macaques')
+)
+
+
+if (FALSE) {
+ added <- labkey.insertRows(
+ baseUrl="https://prime-seq.ohsu.edu",
+ folderPath="/Internal/ColonyData",
+ schemaName="mgap",
+ queryName="releaseTrackSubsets",
+ toInsert = toInsert
+ )
+}
+
+
+# Now ensure all tracks exist:
+existingTracks <- labkey.selectRows(
+ baseUrl="https://prime-seq.ohsu.edu",
+ folderPath="/Internal/ColonyData",
+ schemaName="mgap",
+ queryName="releaseTracks",
+ colNameOpt="rname"
+)
+
+missingTrackNames <- labkey.selectRows(
+ baseUrl="https://prime-seq.ohsu.edu",
+ folderPath="/Internal/ColonyData",
+ schemaName="mgap",
+ queryName="releaseTrackSubsets",
+ colSelect="trackName",
+ colNameOpt="rname"
+) %>%
+ filter(!trackname %in% existingTracks$trackname) %>%
+ select(trackname) %>% unique()
+
+if (nrow(missingTrackNames) > 0) {
+ toAdd <- data.frame(trackName = missingTrackNames$trackname, label = missingTrackNames$trackname, isprimarytrack = FALSE)
+ toAdd$Category <- 'Species Dataset'
+ # Add anything else desired, like species, source, url, description, category
+
+ if (FALSE) {
+ added <- labkey.insertRows(
+ baseUrl="https://prime-seq.ohsu.edu",
+ folderPath="/Internal/ColonyData",
+ schemaName="mgap",
+ queryName="releaseTracks",
+ toInsert = toAdd
+ )
+ }
+}
+
diff --git a/mGAP/resources/schemas/dbscripts/postgresql/mgap-16.73-16.74.sql b/mGAP/resources/schemas/dbscripts/postgresql/mgap-16.73-16.74.sql
new file mode 100644
index 000000000..e4f4faba8
--- /dev/null
+++ b/mGAP/resources/schemas/dbscripts/postgresql/mgap-16.73-16.74.sql
@@ -0,0 +1,3 @@
+ALTER TABLE mGAP.variantCatalogReleases ADD species varchar(1000);
+ALTER TABLE mGAP.releaseTracks ADD species varchar(1000);
+ALTER TABLE mGAP.releaseTracks DROP COLUMN mergepriority;
\ No newline at end of file
diff --git a/mGAP/resources/schemas/dbscripts/postgresql/mgap-16.74-16.75.sql b/mGAP/resources/schemas/dbscripts/postgresql/mgap-16.74-16.75.sql
new file mode 100644
index 000000000..7080ea1bc
--- /dev/null
+++ b/mGAP/resources/schemas/dbscripts/postgresql/mgap-16.74-16.75.sql
@@ -0,0 +1,5 @@
+ALTER TABLE mGAP.releaseTracks ADD shouldindex boolean default false;
+ALTER TABLE mGAP.releaseTracks ADD vcfIndexId int;
+
+ALTER TABLE mGAP.tracksPerRelease ADD shouldindex boolean default false;
+ALTER TABLE mGAP.tracksPerRelease ADD vcfIndexId int;
\ No newline at end of file
diff --git a/mGAP/resources/schemas/dbscripts/sqlserver/mgap-16.73-16.74.sql b/mGAP/resources/schemas/dbscripts/sqlserver/mgap-16.73-16.74.sql
new file mode 100644
index 000000000..e4f4faba8
--- /dev/null
+++ b/mGAP/resources/schemas/dbscripts/sqlserver/mgap-16.73-16.74.sql
@@ -0,0 +1,3 @@
+ALTER TABLE mGAP.variantCatalogReleases ADD species varchar(1000);
+ALTER TABLE mGAP.releaseTracks ADD species varchar(1000);
+ALTER TABLE mGAP.releaseTracks DROP COLUMN mergepriority;
\ No newline at end of file
diff --git a/mGAP/resources/schemas/dbscripts/sqlserver/mgap-16.74-16.75.sql b/mGAP/resources/schemas/dbscripts/sqlserver/mgap-16.74-16.75.sql
new file mode 100644
index 000000000..39631f183
--- /dev/null
+++ b/mGAP/resources/schemas/dbscripts/sqlserver/mgap-16.74-16.75.sql
@@ -0,0 +1,5 @@
+ALTER TABLE mGAP.releaseTracks ADD shouldindex bit default 0;
+ALTER TABLE mGAP.releaseTracks ADD vcfIndexId int;
+
+ALTER TABLE mGAP.tracksPerRelease ADD shouldindex bit default 0;
+ALTER TABLE mGAP.tracksPerRelease ADD vcfIndexId int;
\ No newline at end of file
diff --git a/mGAP/resources/schemas/mgap.xml b/mGAP/resources/schemas/mgap.xml
index 24bfd6332..caed3fa92 100644
--- a/mGAP/resources/schemas/mgap.xml
+++ b/mGAP/resources/schemas/mgap.xml
@@ -95,6 +95,15 @@
false
Row Id
+
+ Species
+
+ laboratory
+ species
+ common_name
+
+
+
Version
false
@@ -644,13 +653,22 @@
Label
false
+
+ Species
+
+ laboratory
+ species
+ common_name
+
+
+
Source
${url}
Category
- false
+ true
URL
@@ -669,14 +687,21 @@
textarea
- Is Primary Track?
-
-
- Merge Priority Order
- This order will be used for genotype priority order when merging to create the primary release VCF. Lower numbers have higher priority. Set to -1 to exclude this track when merging.
+ Is Primary Track For Species?
- Skip Validation?
+ Skip Annotation Checks?
+
+
+ Should Include Lucene Index?
+
+
+ Lucene Index Id
+
+ sequenceanalysis
+ outputfiles
+ rowid
+
true
@@ -812,7 +837,7 @@
Category
- false
+ true
URL
@@ -831,9 +856,20 @@
textarea
- Is Primary Track?
+ Is Primary Track For Species?
false
+
+ Should Include Lucene Index?
+
+
+ Lucene Index Id
+
+ sequenceanalysis
+ outputfiles
+ rowid
+
+
true
diff --git a/mGAP/resources/views/mgapDataDashboard.html b/mGAP/resources/views/mgapDataDashboard.html
index fc6ce214d..1b0fd9138 100644
--- a/mGAP/resources/views/mgapDataDashboard.html
+++ b/mGAP/resources/views/mgapDataDashboard.html
@@ -76,6 +76,13 @@
queryName: 'sampleSummary',
'query.externalAlias~isblank': ''
})
+ },{
+ name: 'gVCFs With SubjectId / Case-sensitive Difference',
+ url: LABKEY.ActionURL.buildURL('query', 'executeQuery.view', null, {
+ schemaName: 'mgap',
+ queryName: 'subjectCaseMismatch',
+ 'query.externalAlias~isnonblank': ''
+ })
}]
},{
header: 'Prior Releases',
diff --git a/mGAP/resources/web/mGAP/window/ReleaseWindow.js b/mGAP/resources/web/mGAP/window/ReleaseWindow.js
index 9921c9746..51fe467b0 100644
--- a/mGAP/resources/web/mGAP/window/ReleaseWindow.js
+++ b/mGAP/resources/web/mGAP/window/ReleaseWindow.js
@@ -12,22 +12,28 @@ Ext4.define('mGAP.window.ReleaseWindow', {
schemaName: 'mgap',
queryName: 'releaseTracks',
scope: this,
- columns: 'vcfId,trackName,vcfId/library_id,isprimarytrack',
+ columns: 'vcfId,species,trackName,vcfId/library_id,isprimarytrack',
failure: LDK.Utils.getErrorCallback(),
success: function (results) {
Ext4.Msg.hide();
var outputFiles = [];
- var distinctGenomes = [];
+ var distinctGenomesBySpecies = {};
Ext4.Array.forEach(results.rows, function(r){
- if (r.vcfId) {
- outputFiles.push(r.vcfId);
+ if (!r.vcfId) {
+ Ext4.Msg.alert('Error', 'Track lacks VCF ID: ' + r.trackName);
+ return false;
+ }
- if (r['vcfId/library_id']) {
- distinctGenomes.push(r['vcfId/library_id']);
- }
+ if (!r.species) {
+ Ext4.Msg.alert('Error', 'Track lacks species: ' + r.trackName);
+ return false;
}
- else if (!r['isprimarytrack']) {
- console.error('Track lacks VCF ID: ' + r.trackName);
+
+ outputFiles.push(r.vcfId);
+
+ distinctGenomesBySpecies[r.species] = distinctGenomesBySpecies[r.species] || [];
+ if (r['vcfId/library_id']) {
+ distinctGenomesBySpecies[r.species].push(r['vcfId/library_id']);
}
}, this);
@@ -36,9 +42,12 @@ Ext4.define('mGAP.window.ReleaseWindow', {
return;
}
- distinctGenomes = Ext4.Array.unique(distinctGenomes);
- if (distinctGenomes.length !== 1){
- Ext4.Msg.alert('Error', 'All files must use the same genome. Genomes found: ' + distinctGenomes.length);
+ for (sn in Ext4.Object.getKeys(distinctGenomesBySpecies)) {
+ var genomes = Ext4.Array.unique(distinctGenomesBySpecies[sn]);
+ if (genomes.length !== 1){
+ Ext4.Msg.alert('Error', 'All files must use the same genome. Genomes found for species ' + sn + ': ' + genomes.length);
+ return;
+ }
}
LABKEY.Ajax.request({
@@ -68,7 +77,7 @@ Ext4.define('mGAP.window.ReleaseWindow', {
title: results.name,
handlerConfig: results,
toolParameters: results.toolParameters,
- libraryId: distinctGenomes.length == 1 ? distinctGenomes[0] : null
+ libraryId: distinctGenomes.length === 1 ? distinctGenomes[0] : null
}).show();
}
}
diff --git a/mGAP/src/org/labkey/mgap/mGAPController.java b/mGAP/src/org/labkey/mgap/mGAPController.java
index e8f0ebbc4..52991080b 100644
--- a/mGAP/src/org/labkey/mgap/mGAPController.java
+++ b/mGAP/src/org/labkey/mgap/mGAPController.java
@@ -58,6 +58,7 @@
import org.labkey.api.query.QueryUpdateService;
import org.labkey.api.query.UserSchema;
import org.labkey.api.reader.Readers;
+import org.labkey.api.resource.Resource;
import org.labkey.api.security.AuthenticationManager;
import org.labkey.api.security.Group;
import org.labkey.api.security.GroupManager;
@@ -224,7 +225,7 @@ public Object execute(RequestUserForm form, BindException errors) throws Excepti
}
DetailsURL url = DetailsURL.fromString("/query/executeQuery.view?schemaName=mgap&query.queryName=userRequests&query.viewName=Pending Requests", c);
- mail.setEncodedHtmlContent("A user requested an account on mGap. Click here to view/approve this request");
+ mail.setEncodedHtmlContent("A user requested an account on mGap. Click here to view/approve this request");
mail.setFrom(getReplyEmail(getContainer()));
mail.setSubject("mGap Account Request");
mail.addRecipients(Message.RecipientType.TO, emails.toArray(new Address[emails.size()]));
@@ -412,13 +413,13 @@ public Object execute(ApproveUserRequestsForm form, BindException errors) throws
User u;
if (map.get("userId") != null)
{
- Integer userId = (Integer)map.get("userId");
+ Integer userId = (Integer) map.get("userId");
u = UserManager.getUser(userId);
existingUsersGivenAccess.add(u);
}
else
{
- ValidEmail ve = new ValidEmail((String)map.get("email"));
+ ValidEmail ve = new ValidEmail((String) map.get("email"));
u = UserManager.getUser(ve);
if (u != null)
{
@@ -428,8 +429,8 @@ public Object execute(ApproveUserRequestsForm form, BindException errors) throws
{
SecurityManager.NewUserStatus st = SecurityManager.addUser(ve, getUser());
u = st.getUser();
- u.setFirstName((String)map.get("firstName"));
- u.setLastName((String)map.get("lastName"));
+ u.setFirstName((String) map.get("firstName"));
+ u.setLastName((String) map.get("lastName"));
UserManager.updateUser(getUser(), u);
if (st.isLdapOrSsoEmail())
@@ -539,7 +540,7 @@ private static Map getReleaseRow(User u, ReleaseForm form, Error
return null;
}
- Container rowContainer = ContainerManager.getForId((String)row.get("container"));
+ Container rowContainer = ContainerManager.getForId((String) row.get("container"));
if (rowContainer == null)
{
errors.reject(ERROR_MSG, "Unknown row container: " + form.getReleaseId());
@@ -555,7 +556,7 @@ else if (!rowContainer.hasPermission(u, ReadPermission.class))
private static SequenceOutputFile getOutputFile(Map row, ReleaseForm form, Errors errors)
{
- SequenceOutputFile so = SequenceOutputFile.getForId((Integer)row.get("vcfId"));
+ SequenceOutputFile so = SequenceOutputFile.getForId((Integer) row.get("vcfId"));
if (so == null)
{
errors.reject(ERROR_MSG, "Unknown VCF file ID: " + form.getReleaseId());
@@ -590,7 +591,7 @@ public void export(DownloadBundleForm form, HttpServletResponse response, BindEx
}
Set toZip = new HashSet<>();
- String zipName = "mGap_VariantCatalog_v" + FileUtil.makeLegalName((String)row.get("version"));
+ String zipName = "mGap_VariantCatalog_v" + FileUtil.makeLegalName((String) row.get("version"));
zipName = zipName.replaceAll(" ", "_");
toZip.add(so.getFile());
@@ -598,7 +599,7 @@ public void export(DownloadBundleForm form, HttpServletResponse response, BindEx
if (form.getIncludeGenome())
{
- ReferenceGenome genome = SequenceAnalysisService.get().getReferenceGenome((Integer)row.get("genomeId"), getUser());
+ ReferenceGenome genome = SequenceAnalysisService.get().getReferenceGenome((Integer) row.get("genomeId"), getUser());
if (genome == null)
{
errors.reject(ERROR_MSG, "Unknown genome: " + row.get("genomeId"));
@@ -969,7 +970,7 @@ public URLHelper getRedirectURL(GenomeBrowserForm form)
String species = StringUtils.trimToNull(form.getSpecies());
if (jbrowseDatabaseId == null)
{
- jbrowseDatabaseId = ctx.getString("human".equals(species) ? "mgapJBrowseHuman": "mgapJBrowse");
+ jbrowseDatabaseId = ctx.getString("human".equals(species) ? "mgapJBrowseHuman" : "mgapJBrowse");
}
if (jbrowseDatabaseId == null)
@@ -1283,4 +1284,71 @@ public URLHelper getSuccessURL(Object o)
return PageFlowUtil.urlProvider(PipelineUrls.class).urlBegin(getContainer());
}
}
+
+ @RequiresPermission(AdminPermission.class)
+ public static class ImportDataAction extends ConfirmAction