diff --git a/MccColony/resources/queries/study/demographics/.qview.xml b/MccColony/resources/queries/study/demographics/.qview.xml index a35d07baa..3bb77e21b 100644 --- a/MccColony/resources/queries/study/demographics/.qview.xml +++ b/MccColony/resources/queries/study/demographics/.qview.xml @@ -26,6 +26,7 @@ + diff --git a/mGAP/src/org/labkey/mgap/columnTransforms/LuceneIndexTransform.java b/mGAP/src/org/labkey/mgap/columnTransforms/LuceneIndexTransform.java index 35e9787db..55fb8c77e 100644 --- a/mGAP/src/org/labkey/mgap/columnTransforms/LuceneIndexTransform.java +++ b/mGAP/src/org/labkey/mgap/columnTransforms/LuceneIndexTransform.java @@ -1,14 +1,11 @@ package org.labkey.mgap.columnTransforms; -import org.apache.commons.io.FileUtils; import org.jetbrains.annotations.Nullable; +import org.labkey.api.jbrowse.JBrowseService; import org.labkey.api.pipeline.PipelineJobException; -import org.labkey.api.sequenceanalysis.run.SimpleScriptWrapper; import org.labkey.mgap.etl.EtlQueueManager; import java.io.File; -import java.io.IOException; -import java.util.Arrays; public class LuceneIndexTransform extends OutputFileTransform { @@ -27,6 +24,7 @@ protected File doFileCopy(File f, File subdir, @Nullable String name) throws Pip // NOTE: lucene is a special case since the DB tracks one file, but we need this whole folder: File sourceDir = f.getParentFile(); File targetDir = new File(subdir, "LuceneIndex"); + JBrowseService.get().clearLuceneCacheEntry(targetDir); EtlQueueManager.get().queueRsyncCopy(getContainerUser().getContainer(), sourceDir, targetDir); return new File(targetDir, sourceDir.getName() + "/" + f.getName()); diff --git a/mGAP/src/org/labkey/mgap/pipeline/mGapSummarizer.java b/mGAP/src/org/labkey/mgap/pipeline/mGapSummarizer.java index c27fc0794..ced520a20 100644 --- a/mGAP/src/org/labkey/mgap/pipeline/mGapSummarizer.java +++ b/mGAP/src/org/labkey/mgap/pipeline/mGapSummarizer.java @@ -174,7 +174,7 @@ private static class FieldData public static void filterCodingPotential(Set codingPotential) { //due to overlapping transcripts, this is often added. remove these less-specific terms in order - for (String type : Arrays.asList("intragenic_variant", "non_coding_transcript_variant", "intron_variant")) + for (String type : Arrays.asList("custom", "intergenic_variant", "intragenic_variant")) { if (codingPotential.size() > 1) { @@ -184,9 +184,8 @@ public static void filterCodingPotential(Set codingPotential) if (codingPotential.contains("synonymous_variant") || codingPotential.contains("missense_variant")) { + codingPotential.remove("intergenic_variant"); codingPotential.remove("intragenic_variant"); - codingPotential.remove("non_coding_transcript_variant"); - codingPotential.remove("intron_variant"); } } diff --git a/mcc/package-lock.json b/mcc/package-lock.json index fa19fb024..6303d5198 100644 --- a/mcc/package-lock.json +++ b/mcc/package-lock.json @@ -4839,12 +4839,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -6509,9 +6509,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" diff --git a/mcc/resources/etls/mcc.xml b/mcc/resources/etls/mcc.xml index b4f41a9c4..70da9b5f3 100644 --- a/mcc/resources/etls/mcc.xml +++ b/mcc/resources/etls/mcc.xml @@ -38,7 +38,7 @@ objectid - + @@ -56,7 +56,7 @@ objectid - + @@ -72,7 +72,7 @@ objectid - + @@ -89,7 +89,7 @@ objectid - + @@ -106,7 +106,7 @@ objectid - + @@ -127,7 +127,7 @@ marmosetsShipped - + diff --git a/mcc/resources/queries/mcc/aggregatedDemographics.sql b/mcc/resources/queries/mcc/aggregatedDemographics.sql index 4f481572f..39586b680 100644 --- a/mcc/resources/queries/mcc/aggregatedDemographics.sql +++ b/mcc/resources/queries/mcc/aggregatedDemographics.sql @@ -19,6 +19,7 @@ SELECT WHEN d.calculated_status = 'Alive' AND (SELECT COUNT(f.flag.value) as total FROM "/data/Colonies/SNPRC/".study.flags f WHERE f.Id = d.Id AND f.isActive = true) > 0 THEN true ELSE false END as u24_status, + d.litterId, d.Id.mostRecentDeparture.mostRecentDeparture, o.availability, o.current_housing_status, @@ -67,6 +68,7 @@ SELECT WHEN d.calculated_status = 'Alive' AND (SELECT COUNT(f.flag.value) as total FROM "/data/Colonies/WNPRC/".study.flags f WHERE f.Id = d.Id AND f.isActive = true) > 0 THEN true ELSE false END as u24_status, + d.litterId, d.Id.mostRecentDeparture.mostRecentDeparture, o.availability, o.current_housing_status, @@ -112,6 +114,7 @@ SELECT d.objectid, d.calculated_status, d.u24_status, + d.litterId, d.Id.mostRecentDeparture.mostRecentDeparture, o.availability, o.current_housing_status, @@ -160,6 +163,7 @@ SELECT d.objectid, d.calculated_status, d.u24_status, + d.litterId, d.Id.mostRecentDeparture.mostRecentDeparture, o.availability, o.current_housing_status, diff --git a/mcc/resources/queries/study/demographics.js b/mcc/resources/queries/study/demographics.js index 1b0016228..4ce83cf7a 100644 --- a/mcc/resources/queries/study/demographics.js +++ b/mcc/resources/queries/study/demographics.js @@ -111,6 +111,13 @@ function onUpsert(helper, scriptErrors, row, oldRow){ } } + if (oldRow && oldRow.Id) { + var existingId = triggerHelper.getMccAlias(oldRow.Id); + if (existingId) { + idToMccAlias[row.Id] = existingId; + } + } + if (!row.date) { row.date = new Date(); } diff --git a/mcc/resources/queries/study/demographics.query.xml b/mcc/resources/queries/study/demographics.query.xml index 3de9b0e1a..b0ce71b6e 100644 --- a/mcc/resources/queries/study/demographics.query.xml +++ b/mcc/resources/queries/study/demographics.query.xml @@ -9,7 +9,7 @@ - + true @@ -121,6 +121,13 @@ Alternate IDs + + Litter ID + /query/executeQuery.view?schemaName=study& + query.queryName=Demographics& + query.litterId~eq=${litterId} + + diff --git a/mcc/resources/queries/study/demographics/.qview.xml b/mcc/resources/queries/study/demographics/.qview.xml index 8950e4cd5..a5c82e8f7 100644 --- a/mcc/resources/queries/study/demographics/.qview.xml +++ b/mcc/resources/queries/study/demographics/.qview.xml @@ -36,6 +36,7 @@ + diff --git a/mcc/resources/queries/study/demographicsLittermates.query.xml b/mcc/resources/queries/study/demographicsLittermates.query.xml new file mode 100644 index 000000000..acc292687 --- /dev/null +++ b/mcc/resources/queries/study/demographicsLittermates.query.xml @@ -0,0 +1,23 @@ + + Littermates of Any Animal + + + + Littermates of Any Animal + + + true + true + + + + + + Littermate(s) + + + Relationship +
+
+
+
diff --git a/mcc/resources/queries/study/demographicsLittermates.sql b/mcc/resources/queries/study/demographicsLittermates.sql new file mode 100644 index 000000000..10ddc5d29 --- /dev/null +++ b/mcc/resources/queries/study/demographicsLittermates.sql @@ -0,0 +1,16 @@ +SELECT + +d1.Id, +d1.litterId, + +GROUP_CONCAT(d2.Id, ',') as litterMates, + +FROM study.Demographics d1 + +JOIN study.Demographics d2 ON (d1.litterId = d2.litterId AND d1.id != d2.id) + +WHERE + d1.qcstate.publicdata = true AND + d2.qcstate.publicdata = true + +GROUP BY d1.Id, d1.litterId \ No newline at end of file diff --git a/mcc/resources/referenceStudy/study/datasets/datasets_metadata.xml b/mcc/resources/referenceStudy/study/datasets/datasets_metadata.xml index 912def432..202636ca8 100644 --- a/mcc/resources/referenceStudy/study/datasets/datasets_metadata.xml +++ b/mcc/resources/referenceStudy/study/datasets/datasets_metadata.xml @@ -685,6 +685,9 @@ boolean + + varchar + Demographics diff --git a/mcc/resources/web/mcc/window/MarkShippedWindow.js b/mcc/resources/web/mcc/window/MarkShippedWindow.js index dd369edb7..9d38932c4 100644 --- a/mcc/resources/web/mcc/window/MarkShippedWindow.js +++ b/mcc/resources/web/mcc/window/MarkShippedWindow.js @@ -10,11 +10,6 @@ Ext4.define('MCC.window.MarkShippedWindow', { return; } - if (checked.length !== 1) { - Ext4.Msg.alert('Error', 'Currently only one ID is supported as a time'); - return; - } - Ext4.create('MCC.window.MarkShippedWindow', { dataRegionName: dataRegionName, rowIds: checked @@ -37,23 +32,6 @@ Ext4.define('MCC.window.MarkShippedWindow', { html: 'This will:
1) Mark the selected animals as shipped from this center
2) Enter a new demographics record in the selected study
3) Preserve the MCC ID for each animal.', border: false, style: 'padding-bottom: 10px;' - },{ - xtype: 'checkbox', - fieldLabel: 'Animal Will Use Previous Id', - itemId: 'usePreviousId', - listeners: { - scope: this, - change: function (field, val) { - var target = field.up('panel').down('#newId'); - target.allowBlank = !!val; - target.setVisible(!val); - } - }, - },{ - xtype: 'textfield', - fieldLabel: 'New ID (blank if unchanged)', - itemId: 'newId', - allowBlank: false },{ xtype: 'datefield', fieldLabel: 'Effective Date', @@ -105,7 +83,7 @@ Ext4.define('MCC.window.MarkShippedWindow', { } } } - }], + }, this.getAnimalIdFields()], buttons: [{ text: 'Submit', handler: this.onSubmit, @@ -121,11 +99,72 @@ Ext4.define('MCC.window.MarkShippedWindow', { this.callParent(arguments); }, + getAnimalIdFields: function(){ + var fields = [{ + xtype: 'displayfield', + value: 'Animal ID', + width: 150 + },{ + xtype: 'displayfield', + value: 'Keep Existing ID?', + width: 150 + },{ + xtype: 'displayfield', + value: 'New ID (blank if unchanged)', + }]; + + Ext4.Array.forEach(this.rowIds, function(rowId){ + const animalId = this.lsidToAnimalId(rowId); + fields = fields.concat([{ + xtype: 'displayfield', + value: animalId, + },{ + xtype: 'checkbox', + itemId: 'usePreviousId-' + animalId, + checked: false, + listeners: { + scope: this, + change: function (field, val) { + var target = field.up('panel').down('#newId-' + animalId); + target.allowBlank = !!val; + target.setDisabled(val); + } + } + },{ + xtype: 'textfield', + itemId: 'newId-' + animalId, + disabled: false, + allowBlank: true + }]); + }, this); + + return { + layout: { + type: 'table', + columns: 3 + }, + border: false, + defaults: { + style: 'padding:5px;', + border: false + }, + items: fields + }; + }, + + lsidToAnimalId: function(lsid){ + lsid = lsid.split(':')[4]; + lsid = lsid.split('.'); + lsid.shift(); + + return lsid.join('.'); + }, + onSubmit: function(btn){ Ext4.Msg.wait('Loading...'); var win = btn.up('window'); - var lsid = win.rowIds[0]; + var lsids = win.rowIds; var effectiveDate = win.down('#effectiveDate').getValue(); var centerName = win.down('#centerName').getValue(); var targetFolder = win.down('#targetFolder').getValue(); @@ -134,9 +173,19 @@ Ext4.define('MCC.window.MarkShippedWindow', { return; } - if (!win.down('#usePreviousId').getValue() && !win.down('#newId').getValue()) { - Ext4.Msg.hide(); - Ext4.Msg.alert('Error', 'Must enter the new ID'); + var hasError = false; + Ext4.Array.forEach(this.rowIds, function(rowId) { + var animalId = this.lsidToAnimalId(rowId); + var useExisting = win.down('#usePreviousId-' + animalId).getValue(); + if (!useExisting && !win.down('#newId-' + animalId).getValue()) { + Ext4.Msg.hide(); + Ext4.Msg.alert('Error', 'Must enter the new ID for: ' + animalId); + hasError = true; + return false; + } + }, this); + + if (hasError) { return; } @@ -145,122 +194,125 @@ Ext4.define('MCC.window.MarkShippedWindow', { LABKEY.Query.selectRows({ schemaName: 'study', queryName: 'Demographics', - filterArray: [LABKEY.Filter.create('lsid', lsid)], + filterArray: [LABKEY.Filter.create('lsid', lsids.join(';'), LABKEY.Filter.Types.IN)], columns: 'Id,gender,colony,species,birth,death,center,Id/MostRecentDeparture/MostRecentDeparture,Id/mccAlias/externalAlias,calculated_status,dam,sire,damMccAlias/externalAlias,sireMccAlias/externalAlias', scope: this, failure: LDK.Utils.getErrorCallback(), success: function(results) { if (!results || !results.rows || !results.rows.length) { Ext4.Msg.hide(); - Ext4.Msg.alert('Error', 'No row round for LSID: ' + lsid + '. This is not expected'); - return; + Ext4.Msg.alert('Error', 'No rows found for, this is not expected'); + return false; } - var row = results.rows[0]; - var newId = win.down('#newId').getValue() || row.Id; var commands = []; + Ext4.Array.forEach(results.rows, function(row){ + var effectiveId = win.down('#usePreviousId-' + row.Id).getValue() ? row.Id : win.down('#newId-' + row.Id).getValue(); + // This should be checked above, although perhaps case sensitivity could get involved: + LDK.Assert.assertNotEmpty('Missing effective ID after query', effectiveId); - var shouldAddDeparture = !row['Id/MostRecentDeparture/MostRecentDeparture'] || row['Id/MostRecentDeparture/MostRecentDeparture'] !== Ext4.Date.format(row.effectiveDate, 'Y-m-d') || row.Id !== newId; - if (shouldAddDeparture) { - commands.push({ - command: 'insert', - schemaName: 'study', - queryName: 'Departure', - rows: [{ - Id: row.Id, - date: effectiveDate, - destination: centerName, - description: row.colony ? 'Original center: ' + row.colony : null, - qcstate: null, - objectId: null, - QCStateLabel: 'Completed' - }] - }); - } + var shouldAddDeparture = !row['Id/MostRecentDeparture/MostRecentDeparture'] || row['Id/MostRecentDeparture/MostRecentDeparture'] !== Ext4.Date.format(row.effectiveDate, 'Y-m-d') || row.Id !== effectiveId; + if (shouldAddDeparture) { + commands.push({ + command: 'insert', + schemaName: 'study', + queryName: 'Departure', + rows: [{ + Id: row.Id, + date: effectiveDate, + destination: centerName, + description: row.colony ? 'Original center: ' + row.colony : null, + qcstate: null, + objectId: null, + QCStateLabel: 'Completed' + }] + }); + } - // If going to a new LK folder, we're creating a whole new record: - if (targetFolderId.toUpperCase() !== LABKEY.Security.currentContainer.id.toUpperCase() || newId !== row.Id) { - commands.push({ - command: 'insert', - containerPath: targetFolder, - schemaName: 'study', - queryName: 'Demographics', - rows: [{ - Id: newId, - date: effectiveDate, - alternateIds: row.Id !== newId ? row.Id : null, - gender: row.gender, - species: row.species, - birth: row.birth, - death: row.death, - dam: row.dam, - sire: row.sire, - damMccAlias: row['damMccAlias/externalAlias'], - sireMccAlias: row['sireMccAlias/externalAlias'], - colony: centerName, - source: row.colony, - calculated_status: 'Alive', - mccAlias: row['Id/mccAlias/externalAlias'], - QCState: null, - QCStateLabel: 'Completed', - objectId: null - }] - }); + // If going to a new LK folder, we're creating a whole new record: + if (targetFolderId.toUpperCase() !== LABKEY.Security.currentContainer.id.toUpperCase() || effectiveId !== row.Id) { + commands.push({ + command: 'insert', + containerPath: targetFolder, + schemaName: 'study', + queryName: 'Demographics', + rows: [{ + Id: effectiveId, + date: effectiveDate, + alternateIds: row.Id !== effectiveId ? row.Id : null, + gender: row.gender, + species: row.species, + birth: row.birth, + death: row.death, + dam: row.dam, + sire: row.sire, + damMccAlias: row['damMccAlias/externalAlias'], + sireMccAlias: row['sireMccAlias/externalAlias'], + colony: centerName, + source: row.colony, + calculated_status: 'Alive', + mccAlias: row['Id/mccAlias/externalAlias'], + QCState: null, + QCStateLabel: 'Completed', + objectId: null + }] + }); - commands.push({ - command: 'update', - containerPath: null, //Use current folder - schemaName: 'study', - queryName: 'Demographics', - rows: [{ - Id: row.Id, // NOTE: always change the original record - excludeFromCensus: true - }] - }); - } - else { - // Otherwise update the existing: - commands.push({ - command: 'update', - containerPath: targetFolder, - schemaName: 'study', - queryName: 'Demographics', - rows: [{ - Id: row.Id, - date: effectiveDate, - alternateIds: null, - gender: row.gender, - species: row.species, - birth: row.birth, - death: row.death, - dam: row.dam, - sire: row.sire, - colony: centerName, - source: row.colony, - calculated_status: 'Alive', - QCState: null, - QCStateLabel: 'Completed', - objectId: null - }] - }); + commands.push({ + command: 'update', + containerPath: null, //Use current folder + schemaName: 'study', + queryName: 'Demographics', + rows: [{ + Id: row.Id, // NOTE: always change the original record + excludeFromCensus: true + }] + }); + } + else { + // Otherwise update the existing: + commands.push({ + command: 'update', + containerPath: targetFolder, + schemaName: 'study', + queryName: 'Demographics', + rows: [{ + Id: row.Id, + date: effectiveDate, + alternateIds: null, + gender: row.gender, + species: row.species, + birth: row.birth, + death: row.death, + dam: row.dam, + sire: row.sire, + colony: centerName, + source: row.colony, + calculated_status: 'Alive', + QCState: null, + QCStateLabel: 'Completed', + objectId: null + }] + }); - // And also add an arrival record. NOTE: set the date after the departure to get status to update properly - var arrivalDate = new Date(effectiveDate).setMinutes(effectiveDate.getMinutes() + 1); - commands.push({ - command: 'insert', - containerPath: targetFolder, - schemaName: 'study', - queryName: 'Arrival', - rows: [{ - Id: newId, - date: arrivalDate, - source: centerName, - QCState: null, - QCStateLabel: 'Completed', - objectId: null - }] - }); - } + // And also add an arrival record. NOTE: set the date after the departure to get status to update properly + var arrivalDate = new Date(effectiveDate).setMinutes(effectiveDate.getMinutes() + 1); + commands.push({ + command: 'insert', + containerPath: targetFolder, + schemaName: 'study', + queryName: 'Arrival', + rows: [{ + Id: effectiveId, + date: arrivalDate, + source: centerName, + QCState: null, + QCStateLabel: 'Completed', + objectId: null + }] + }); + } + }, this); LABKEY.Query.saveRows({ commands: commands, diff --git a/mcc/src/org/labkey/mcc/query/MccEhrCustomizer.java b/mcc/src/org/labkey/mcc/query/MccEhrCustomizer.java index ff6a0d31c..12373e56e 100644 --- a/mcc/src/org/labkey/mcc/query/MccEhrCustomizer.java +++ b/mcc/src/org/labkey/mcc/query/MccEhrCustomizer.java @@ -96,6 +96,13 @@ private void customizeAnimalTable(AbstractTableInfo ti) ti.addColumn(col); } + if (ti.getColumn("littermates") == null) + { + var col = getWrappedIdCol(ti.getUserSchema(), ti, "littermates", "demographicsLittermates"); + col.setLabel("Littermates"); + col.setDescription("The IDs of "); + ti.addColumn(col); + } } private BaseColumnInfo getWrappedIdCol(UserSchema us, AbstractTableInfo ds, String name, String queryName) diff --git a/mcc/src/org/labkey/mcc/query/TriggerHelper.java b/mcc/src/org/labkey/mcc/query/TriggerHelper.java index 02aed50cb..f36e999e6 100644 --- a/mcc/src/org/labkey/mcc/query/TriggerHelper.java +++ b/mcc/src/org/labkey/mcc/query/TriggerHelper.java @@ -260,6 +260,22 @@ public void possiblySendRabNotification(int reviewerId) } } + private TableInfo _mappingTable = null; + + private TableInfo getMappingTable() + { + if (_mappingTable == null) + { + _mappingTable = QueryService.get().getUserSchema(_user, _container, MccSchema.NAME).getTable(MccSchema.TABLE_ANIMAL_MAPPING); + } + + return _mappingTable; + } + + public @Nullable String getMccAlias(String id) { + return new TableSelector(getMappingTable(), PageFlowUtil.set("externalAlias"), new SimpleFilter(FieldKey.fromString("subjectname"), id, CompareType.EQUAL), null).getObject(String.class); + } + public int ensureMccAliasExists(Collection rawIds, Map existingAliases) { // NOTE: The incoming object can convert numeric IDs from strings to int, so manually convert: @@ -273,7 +289,7 @@ public int ensureMccAliasExists(Collection rawIds, Map e SimpleFilter filter = new SimpleFilter(FieldKey.fromString("subjectname"), idMap.values(), CompareType.IN); final Set aliasesFound = new HashSet<>(); - TableInfo ti = QueryService.get().getUserSchema(_user, _container, MccSchema.NAME).getTable(MccSchema.TABLE_ANIMAL_MAPPING); + TableInfo ti = getMappingTable(); new TableSelector(ti, PageFlowUtil.set("subjectname", "externalAlias"), filter, null).forEachResults(rs -> { aliasesFound.add(rs.getString(FieldKey.fromString("subjectname"))); if (ciExistingAliases.containsKey(rs.getString(FieldKey.fromString("subjectname")))) { diff --git a/mcc/test/src/org/labkey/test/tests/mcc/MccTest.java b/mcc/test/src/org/labkey/test/tests/mcc/MccTest.java index 89d94101c..c4a2f2739 100644 --- a/mcc/test/src/org/labkey/test/tests/mcc/MccTest.java +++ b/mcc/test/src/org/labkey/test/tests/mcc/MccTest.java @@ -40,6 +40,7 @@ import org.labkey.test.util.DataRegionTable; import org.labkey.test.util.Ext4Helper; import org.labkey.test.util.PermissionsHelper; +import org.labkey.test.util.ext4cmp.Ext4CmpRef; import org.labkey.test.util.ext4cmp.Ext4ComboRef; import org.labkey.test.util.ext4cmp.Ext4FieldRef; @@ -128,7 +129,7 @@ private void testAnimalImportAndTransfer() throws Exception new Window.WindowFinder(getDriver()).withTitle("Error").waitFor(); waitAndClick(Ext4Helper.Locators.ext4Button("OK")); - Ext4FieldRef.getForLabel(this, "Animal Will Use Previous Id").setChecked(true); + _ext4Helper.queryOne("#usePreviousId-Animal2", Ext4FieldRef.class).setChecked(true); waitAndClick(Ext4Helper.Locators.ext4Button("Submit")); new Window.WindowFinder(getDriver()).withTitle("Success").waitFor(); @@ -181,7 +182,7 @@ private void testAnimalImportAndTransfer() throws Exception sleep(100); Ext4ComboRef.getForLabel(this, "Target Folder").setComboByDisplayValue("Other"); - Ext4FieldRef.getForLabel(this, "Animal Will Use Previous Id").setChecked(true); + _ext4Helper.queryOne("#usePreviousId-Animal2", Ext4FieldRef.class).setChecked(true); waitAndClick(Ext4Helper.Locators.ext4Button("Submit")); new Window.WindowFinder(getDriver()).withTitle("Success").waitFor(); @@ -238,7 +239,7 @@ private void testAnimalImportAndTransfer() throws Exception sleep(100); Ext4ComboRef.getForLabel(this, "Target Folder").setComboByDisplayValue("Other"); - Ext4FieldRef.getForLabel(this, "New ID (blank if unchanged)").setValue("TheNewId"); + _ext4Helper.queryOne("#newId-12345", Ext4FieldRef.class).setValue("TheNewId"); waitAndClick(Ext4Helper.Locators.ext4Button("Submit")); new Window.WindowFinder(getDriver()).withTitle("Success").waitFor(); diff --git a/primeseq/resources/etls/mcc.xml b/primeseq/resources/etls/mcc.xml index 2277dbbc5..0d027d146 100644 --- a/primeseq/resources/etls/mcc.xml +++ b/primeseq/resources/etls/mcc.xml @@ -12,6 +12,9 @@ sire gender + + + diff --git a/primeseq/src/org/labkey/primeseq/PrimeseqModule.java b/primeseq/src/org/labkey/primeseq/PrimeseqModule.java index c8c3539ae..a50f4f915 100644 --- a/primeseq/src/org/labkey/primeseq/PrimeseqModule.java +++ b/primeseq/src/org/labkey/primeseq/PrimeseqModule.java @@ -32,8 +32,6 @@ import org.labkey.api.view.WebPartFactory; import org.labkey.primeseq.analysis.CombineMethylationRatesHandler; import org.labkey.primeseq.analysis.MethylationRateComparisonHandler; -import org.labkey.primeseq.pipeline.BisSnpGenotyperAnalysis; -import org.labkey.primeseq.pipeline.BisSnpIndelRealignerStep; import org.labkey.primeseq.pipeline.BismarkWrapper; import org.labkey.primeseq.pipeline.BlastPipelineJobResourceAllocator; import org.labkey.primeseq.pipeline.ClusterMaintenanceTask; @@ -114,9 +112,6 @@ public PipelineStartup() SequencePipelineService.get().registerPipelineStep(new BismarkWrapper.Provider()); SequencePipelineService.get().registerPipelineStep(new BismarkWrapper.MethylationExtractorProvider()); - SequencePipelineService.get().registerPipelineStep(new BisSnpIndelRealignerStep.Provider()); - SequencePipelineService.get().registerPipelineStep(new BisSnpGenotyperAnalysis.Provider()); - SequenceAnalysisService.get().registerFileHandler(new MethylationRateComparisonHandler()); SequenceAnalysisService.get().registerFileHandler(new CombineMethylationRatesHandler()); diff --git a/primeseq/src/org/labkey/primeseq/pipeline/AbstractBisSnpWrapper.java b/primeseq/src/org/labkey/primeseq/pipeline/AbstractBisSnpWrapper.java deleted file mode 100644 index a2e7c12d5..000000000 --- a/primeseq/src/org/labkey/primeseq/pipeline/AbstractBisSnpWrapper.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.labkey.primeseq.pipeline; - -import org.apache.logging.log4j.Logger; -import org.labkey.api.pipeline.PipelineJobException; -import org.labkey.api.pipeline.PipelineJobService; -import org.labkey.api.sequenceanalysis.pipeline.SequencePipelineService; -import org.labkey.api.sequenceanalysis.run.AbstractCommandWrapper; -import org.labkey.api.sequenceanalysis.run.CreateSequenceDictionaryWrapper; - -import java.io.File; - -/** - * Created by bimber on 8/14/2016. - */ -public class AbstractBisSnpWrapper extends AbstractCommandWrapper -{ - public AbstractBisSnpWrapper(Logger log) - { - super(log); - } - - protected File getJAR() - { - String path = PipelineJobService.get().getConfigProperties().getSoftwarePackagePath("BISSNPPATH"); - if (path != null) - { - return new File(path); - } - - path = PipelineJobService.get().getConfigProperties().getSoftwarePackagePath(SequencePipelineService.SEQUENCE_TOOLS_PARAM); - if (path == null) - { - path = PipelineJobService.get().getAppProperties().getToolsDirectory(); - } - - return path == null ? new File("BisSNP.jar") : new File(path, "BisSNP.jar"); - } - - public boolean jarExists() - { - return getJAR() == null || !getJAR().exists(); - } - - protected void ensureDictionary(File referenceFasta) throws PipelineJobException - { - getLogger().info("\tensure dictionary exists"); - new CreateSequenceDictionaryWrapper(getLogger()).execute(referenceFasta, false); - } - - protected String getJava6Filepath() - { - String javaDir = PipelineJobService.get().getConfigProperties().getSoftwarePackagePath("JAVA_HOME_6"); - if (javaDir != null) - { - File ret = new File(javaDir, "bin"); - ret = new File(ret, "java"); - return ret.getPath(); - } - - //if not explicitly found, try the default - javaDir = PipelineJobService.get().getConfigProperties().getSoftwarePackagePath("JAVA_HOME"); - if (javaDir != null) - { - File ret = new File(javaDir, "bin"); - ret = new File(ret, "java"); - return ret.getPath(); - } - - return "java"; - } -} diff --git a/primeseq/src/org/labkey/primeseq/pipeline/BisSnpGenotyperAnalysis.java b/primeseq/src/org/labkey/primeseq/pipeline/BisSnpGenotyperAnalysis.java deleted file mode 100644 index 1f700a1d0..000000000 --- a/primeseq/src/org/labkey/primeseq/pipeline/BisSnpGenotyperAnalysis.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.labkey.primeseq.pipeline; - -import org.labkey.api.pipeline.PipelineJobException; -import org.labkey.api.sequenceanalysis.model.AnalysisModel; -import org.labkey.api.sequenceanalysis.model.Readset; -import org.labkey.api.sequenceanalysis.pipeline.AbstractAnalysisStepProvider; -import org.labkey.api.sequenceanalysis.pipeline.AnalysisOutputImpl; -import org.labkey.api.sequenceanalysis.pipeline.AnalysisStep; -import org.labkey.api.sequenceanalysis.pipeline.CommandLineParam; -import org.labkey.api.sequenceanalysis.pipeline.PipelineContext; -import org.labkey.api.sequenceanalysis.pipeline.PipelineStepProvider; -import org.labkey.api.sequenceanalysis.pipeline.ReferenceGenome; -import org.labkey.api.sequenceanalysis.pipeline.SequencePipelineService; -import org.labkey.api.sequenceanalysis.pipeline.ToolParameterDescriptor; -import org.labkey.api.sequenceanalysis.run.AbstractCommandPipelineStep; -import org.labkey.api.util.FileUtil; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * User: bimber - * Date: 7/3/2014 - * Time: 11:29 AM - */ -public class BisSnpGenotyperAnalysis extends AbstractCommandPipelineStep implements AnalysisStep -{ - public BisSnpGenotyperAnalysis(PipelineStepProvider provider, PipelineContext ctx) - { - super(provider, ctx, new BisulfiteGenotyperWrapper(ctx.getLogger())); - } - - public static class Provider extends AbstractAnalysisStepProvider - { - public Provider() - { - super("BisulfiteGenotyperAnalysis", "BisSNP BisulfiteGenotyper", "BisSNP", "This will run BisSNP's BisulfiteGenotyper on the selected data.", getToolDescriptors(), null, null); - } - - @Override - public BisSnpGenotyperAnalysis create(PipelineContext ctx) - { - return new BisSnpGenotyperAnalysis(this, ctx); - } - } - - public static List getToolDescriptors() - { - return Arrays.asList( - ToolParameterDescriptor.createCommandLineParam(CommandLineParam.create("-stand_call_conf"), "stand_call_conf", "Threshold For Calling Variants", "The minimum phred-scaled confidence threshold at which variants should be called", "ldk-numberfield", null, 20), - ToolParameterDescriptor.createCommandLineParam(CommandLineParam.create("-stand_emit_conf"), "stand_emit_conf", "Threshold For Emitting Variants", "The minimum phred-scaled confidence threshold at which variants should be emitted (and filtered with LowQual if less than the calling threshold)", "ldk-numberfield", null, 20) - ); - } - - @Override - public Output performAnalysisPerSampleRemote(Readset rs, File inputBam, ReferenceGenome referenceGenome, File outputDir) throws PipelineJobException - { - AnalysisOutputImpl output = new AnalysisOutputImpl(); - output.addInput(inputBam, "Input BAM File"); - - File snpOutputFile = new File(outputDir, FileUtil.getBaseName(inputBam) + ".snp.vcf"); - File cpgOutputFile = new File(outputDir, FileUtil.getBaseName(inputBam) + ".cpg.vcf"); - - getWrapper().setOutputDir(outputDir); - - List args = new ArrayList<>(); - args.addAll(getClientCommandArgs()); - - Integer maxThreads = SequencePipelineService.get().getMaxThreads(getPipelineCtx().getJob().getLogger()); - getWrapper().execute(inputBam, referenceGenome.getWorkingFastaFile(), cpgOutputFile, snpOutputFile, maxThreads, args); - - //sort, which will also create indexes - File dict = new File(referenceGenome.getWorkingFastaFile().getParent(), FileUtil.getBaseName(referenceGenome.getWorkingFastaFile()) + ".dict"); - cpgOutputFile = SequencePipelineService.get().sortVcf(cpgOutputFile, new File(cpgOutputFile.getPath() + ".gz"), dict, getPipelineCtx().getLogger()); - snpOutputFile = SequencePipelineService.get().sortVcf(snpOutputFile, new File(snpOutputFile.getPath() + ".gz"), dict, getPipelineCtx().getLogger()); - - (new File(outputDir, FileUtil.getBaseName(inputBam) + ".snp.vcf")).delete(); - (new File(outputDir, FileUtil.getBaseName(inputBam) + ".cpg.vcf")).delete(); - (new File(outputDir, FileUtil.getBaseName(inputBam) + ".snp.vcf.idx")).delete(); - (new File(outputDir, FileUtil.getBaseName(inputBam) + ".cpg.vcf.idx")).delete(); - - File snpIdxFile = new File(outputDir, FileUtil.getBaseName(inputBam) + ".snp.vcf.gz.tbi"); - File cpgIdxFile = new File(outputDir, FileUtil.getBaseName(inputBam) + ".cpg.vcf.gz.tbi"); - - output.addOutput(cpgOutputFile, "Bisulfite VCF File"); - output.addSequenceOutput(cpgOutputFile, cpgOutputFile.getName(), "Bisulfite VCF File", rs.getReadsetId(), null, referenceGenome.getGenomeId(), null); - if (cpgIdxFile.exists()) - { - output.addOutput(cpgIdxFile, "Bisulfite VCF Index"); - } - else - { - getPipelineCtx().getLogger().warn("expected index not found: " + cpgIdxFile.getName()); - } - output.addOutput(getWrapper().getFilterSummary(cpgOutputFile), "Bisulfite Filter Summary"); - - output.addOutput(snpOutputFile, "VCF File"); - output.addSequenceOutput(snpOutputFile, snpOutputFile.getName(), "VCF File", rs.getReadsetId(), null, referenceGenome.getGenomeId(), null); - if (snpIdxFile.exists()) - { - output.addOutput(snpIdxFile, "Bisulfite VCF Index"); - } - else - { - getPipelineCtx().getLogger().warn("expected index not found: " + snpIdxFile.getName()); - } - output.addOutput(getWrapper().getFilterSummary(snpOutputFile), "Bisulfite Filter Summary"); - - return output; - } - - @Override - public Output performAnalysisPerSampleLocal(AnalysisModel model, File inputBam, File referenceFasta, File outDir) throws PipelineJobException - { - return null; - } -} diff --git a/primeseq/src/org/labkey/primeseq/pipeline/BisSnpIndelRealignerStep.java b/primeseq/src/org/labkey/primeseq/pipeline/BisSnpIndelRealignerStep.java deleted file mode 100644 index 424459262..000000000 --- a/primeseq/src/org/labkey/primeseq/pipeline/BisSnpIndelRealignerStep.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.labkey.primeseq.pipeline; - -import org.labkey.api.pipeline.PipelineJobException; -import org.labkey.api.sequenceanalysis.model.Readset; -import org.labkey.api.sequenceanalysis.pipeline.AbstractPipelineStepProvider; -import org.labkey.api.sequenceanalysis.pipeline.BamProcessingOutputImpl; -import org.labkey.api.sequenceanalysis.pipeline.BamProcessingStep; -import org.labkey.api.sequenceanalysis.pipeline.PipelineContext; -import org.labkey.api.sequenceanalysis.pipeline.PipelineStepProvider; -import org.labkey.api.sequenceanalysis.pipeline.ReferenceGenome; -import org.labkey.api.sequenceanalysis.pipeline.SequencePipelineService; -import org.labkey.api.sequenceanalysis.run.AbstractCommandPipelineStep; -import org.labkey.api.util.FileUtil; - -import java.io.File; -import java.util.List; - -/** - * User: bimber - * Date: 6/15/2014 - * Time: 4:59 PM - */ -public class BisSnpIndelRealignerStep extends AbstractCommandPipelineStep implements BamProcessingStep -{ - public BisSnpIndelRealignerStep(PipelineStepProvider provider, PipelineContext ctx) - { - super(provider, ctx, new BisSnpIndelRealignerWrapper(ctx.getLogger())); - } - - public static class Provider extends AbstractPipelineStepProvider - { - public Provider() - { - super("BisSnpIndelRealigner", "BisSNP Indel Realigner", "BisSNP", "The step runs BisSNP's IndelRealigner tool. It is similar to GATK's, except adapted for bisulfite data.", List.of(), null, "https://sourceforge.net/projects/bissnp/"); - } - - @Override - public BisSnpIndelRealignerStep create(PipelineContext ctx) - { - return new BisSnpIndelRealignerStep(this, ctx); - } - } - - @Override - public Output processBam(Readset rs, File inputBam, ReferenceGenome referenceGenome, File outputDirectory) throws PipelineJobException - { - BamProcessingOutputImpl output = new BamProcessingOutputImpl(); - getWrapper().setOutputDir(outputDirectory); - - File dictionary = new File(referenceGenome.getWorkingFastaFile().getParentFile(), FileUtil.getBaseName(referenceGenome.getWorkingFastaFile().getName()) + ".dict"); - boolean dictionaryExists = dictionary.exists(); - getPipelineCtx().getLogger().debug("dict exists: " + dictionaryExists + ", " + dictionary.getPath()); - - File outputBam = new File(outputDirectory, FileUtil.getBaseName(inputBam) + ".bissnp-realigned.bam"); - Integer maxThreads = SequencePipelineService.get().getMaxThreads(getPipelineCtx().getJob().getLogger()); - output.setBAM(getWrapper().execute(inputBam, outputBam, referenceGenome.getWorkingFastaFile(), null, maxThreads)); - - output.addIntermediateFile(outputBam); - output.addIntermediateFile(getWrapper().getExpectedIntervalsFile(inputBam), "Realigner Intervals File"); - - if (!dictionaryExists) - { - if (dictionary.exists()) - { - output.addIntermediateFile(dictionary); - } - else - { - getPipelineCtx().getLogger().debug("dict file not found: " + dictionary.getPath()); - } - } - - //note: we might sort the input - File sortedBam = new File(inputBam.getParentFile(), FileUtil.getBaseName(inputBam) + ".sorted.bam"); - if (sortedBam.exists()) - { - getPipelineCtx().getLogger().debug("sorted file exists: " + sortedBam.getPath()); - output.addIntermediateFile(sortedBam); - output.addIntermediateFile(new File(outputDirectory, FileUtil.getBaseName(inputBam) + ".bissnp-realigned.bai")); - } - else - { - getPipelineCtx().getLogger().debug("sorted file does not exist: " + sortedBam.getPath()); - output.addIntermediateFile(new File(outputDirectory, FileUtil.getBaseName(inputBam) + ".bissnp-realigned.bai")); - } - - return output; - } -} diff --git a/primeseq/src/org/labkey/primeseq/pipeline/BisSnpIndelRealignerWrapper.java b/primeseq/src/org/labkey/primeseq/pipeline/BisSnpIndelRealignerWrapper.java deleted file mode 100644 index 0390442d6..000000000 --- a/primeseq/src/org/labkey/primeseq/pipeline/BisSnpIndelRealignerWrapper.java +++ /dev/null @@ -1,199 +0,0 @@ -package org.labkey.primeseq.pipeline; - -import htsjdk.samtools.SAMFileHeader; -import org.apache.commons.io.FileUtils; -import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.Nullable; -import org.labkey.api.pipeline.PipelineJobException; -import org.labkey.api.sequenceanalysis.pipeline.SamSorter; -import org.labkey.api.sequenceanalysis.pipeline.SequencePipelineService; -import org.labkey.api.util.FileUtil; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * User: bimber - * Date: 7/1/2014 - * Time: 2:40 PM - */ -public class BisSnpIndelRealignerWrapper extends AbstractBisSnpWrapper -{ - public BisSnpIndelRealignerWrapper(Logger log) - { - super(log); - } - - public File execute(File inputBam, @Nullable File outputBam, File referenceFasta, @Nullable File knownIndelsVcf, @Nullable Integer maxThreads) throws PipelineJobException - { - getLogger().info("Running BisSNP IndelRealigner for: " + inputBam.getName()); - - List tempFiles = new ArrayList<>(); - File workingBam = performSharedWork(inputBam, outputBam, referenceFasta, tempFiles); - if (!workingBam.equals(inputBam)) - { - tempFiles.add(workingBam); - } - - List extraArgs = new ArrayList<>(); - if (maxThreads != null) - { - extraArgs.add("-nt"); - extraArgs.add(maxThreads.toString()); - } - - File intervalsFile = buildTargetIntervals(referenceFasta, workingBam, knownIndelsVcf, getExpectedIntervalsFile(inputBam), extraArgs); - - //then run realigner - getLogger().info("\trunning BisSNP IndelRealigner"); - List realignerArgs = new ArrayList<>(); - realignerArgs.add(getJava6Filepath()); - realignerArgs.addAll(SequencePipelineService.get().getJavaOpts()); - realignerArgs.add("-jar"); - realignerArgs.add(getJAR().getPath()); - realignerArgs.add("-T"); - realignerArgs.add("IndelRealigner"); - realignerArgs.add("-R"); - realignerArgs.add(referenceFasta.getPath()); - realignerArgs.add("-I"); - realignerArgs.add(workingBam.getPath()); - realignerArgs.add("-o"); - - File realignedBam = outputBam == null ? new File(getOutputDir(inputBam), FileUtil.getBaseName(inputBam) + ".realigned.bam") : outputBam; - realignerArgs.add(realignedBam.getPath()); - realignerArgs.add("-targetIntervals"); - realignerArgs.add(intervalsFile.getPath()); - realignerArgs.add("--bam_compression"); - realignerArgs.add("9"); - if (knownIndelsVcf != null) - { - realignerArgs.add("--known"); - realignerArgs.add(knownIndelsVcf.getPath()); - } - - execute(realignerArgs); - if (!realignedBam.exists()) - { - throw new PipelineJobException("Expected BAM not found: " + realignedBam.getPath()); - } - - return processOutput(tempFiles, inputBam, outputBam, realignedBam); - } - - private File processOutput(List tempFiles, File inputBam, File outputBam, File realignedBam) throws PipelineJobException - { - if (!tempFiles.isEmpty()) - { - for (File f : tempFiles) - { - getLogger().debug("\tdeleting temp file: " + f.getPath()); - f.delete(); - } - } - - try - { - if (outputBam == null) - { - getLogger().debug("replacing input BAM with realigned"); - inputBam.delete(); - FileUtils.moveFile(realignedBam, inputBam); - - return inputBam; - } - else - { - return realignedBam; - } - } - catch (IOException e) - { - throw new PipelineJobException(e); - } - } - - private File buildTargetIntervals(File referenceFasta, File inputBam, File knownIndelsVcf, File intervalsFile, @Nullable List extraArgs) throws PipelineJobException - { - getLogger().info("building target intervals"); - List args = new ArrayList<>(); - args.add(getJava6Filepath()); - args.addAll(SequencePipelineService.get().getJavaOpts()); - args.add("-jar"); - args.add(getJAR().getPath()); - args.add("-T"); - args.add("BisulfiteRealignerTargetCreator"); - args.add("-R"); - args.add(referenceFasta.getPath()); - args.add("-I"); - args.add(inputBam.getPath()); - args.add("-o"); - - args.add(intervalsFile.getPath()); - - if (knownIndelsVcf != null) - { - args.add("--known"); - args.add(knownIndelsVcf.getPath()); - } - - if (extraArgs != null) - { - args.addAll(extraArgs); - } - - execute(args); - - //log the intervals - long lineCount = SequencePipelineService.get().getLineCount(intervalsFile); - getLogger().info("\ttarget intervals to realign: " + lineCount); - - return intervalsFile; - } - - private File performSharedWork(File inputBam, File outputBam, File referenceFasta, List tempFiles) throws PipelineJobException - { - //ensure BAM sorted - try - { - SAMFileHeader.SortOrder order = SequencePipelineService.get().getBamSortOrder(inputBam); - - if (SAMFileHeader.SortOrder.coordinate != order) - { - getLogger().info("coordinate sorting BAM, order was: " + (order == null ? "not provided" : order.name())); - File sorted = new File(inputBam.getParentFile(), FileUtil.getBaseName(inputBam) + ".sorted.bam"); - new SamSorter(getLogger()).execute(inputBam, sorted, SAMFileHeader.SortOrder.coordinate); - - //this indicates we expect to replace the original in place, in which case we should delete the unsorted BAM - if (outputBam == null) - { - tempFiles.add(inputBam); - } - - inputBam = sorted; - } - else - { - getLogger().info("bam is already in coordinate sort order"); - } - } - catch (IOException e) - { - throw new PipelineJobException(e); - } - - ensureDictionary(referenceFasta); - - File idx = SequencePipelineService.get().ensureBamIndex(inputBam, getLogger(), true); - if (idx != null) - tempFiles.add(idx); - - return inputBam; - } - - public File getExpectedIntervalsFile(File inputBam) - { - return new File(getOutputDir(inputBam), FileUtil.getBaseName(inputBam) + ".intervals"); - } -} diff --git a/primeseq/src/org/labkey/primeseq/pipeline/BisulfiteGenotyperWrapper.java b/primeseq/src/org/labkey/primeseq/pipeline/BisulfiteGenotyperWrapper.java deleted file mode 100644 index 85f4627cf..000000000 --- a/primeseq/src/org/labkey/primeseq/pipeline/BisulfiteGenotyperWrapper.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.labkey.primeseq.pipeline; - -import org.apache.logging.log4j.Logger; -import org.labkey.api.pipeline.PipelineJobException; -import org.labkey.api.sequenceanalysis.pipeline.SequencePipelineService; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by bimber on 8/8/2014. - */ -public class BisulfiteGenotyperWrapper extends AbstractBisSnpWrapper -{ - public BisulfiteGenotyperWrapper(Logger log) - { - super(log); - } - - public void execute(File inputBam, File referenceFasta, File cpgOutputFile, File snpOutputFile, Integer maxThreads, List options) throws PipelineJobException - { - getLogger().info("Running BisSNP BisulfiteGenotyper for: " + inputBam.getName()); - - if (cpgOutputFile.getName().toLowerCase().endsWith(".gz") || snpOutputFile.getName().toLowerCase().endsWith(".gz")) - { - throw new PipelineJobException("BisulfiteGenotyper is built using an old GATK version and does not work properly with gzipped files"); - } - - ensureDictionary(referenceFasta); - - File createdIndex = SequencePipelineService.get().ensureBamIndex(inputBam, getLogger(), false); - if (createdIndex == null) - { - getLogger().debug("\tusing existing BAM index"); - } - - File rawCpgOutput = new File(getOutputDir(cpgOutputFile), SequencePipelineService.get().getUnzippedBaseName(cpgOutputFile.getName()) + ".cpg-raw.vcf"); - File rawSnpOutput = new File(getOutputDir(snpOutputFile), SequencePipelineService.get().getUnzippedBaseName(snpOutputFile.getName()) + ".snp-raw.vcf"); - - List args = new ArrayList<>(); - args.add(getJava6Filepath()); - args.addAll(SequencePipelineService.get().getJavaOpts()); - args.add("-jar"); - args.add(getJAR().getPath()); - args.add("-T"); - args.add("BisulfiteGenotyper"); - args.add("-R"); - args.add(referenceFasta.getPath()); - args.add("-I"); - args.add(inputBam.getPath()); - args.add("-vfn1"); - args.add(rawCpgOutput.getPath()); - args.add("-vfn2"); - args.add(rawSnpOutput.getPath()); - - if (options != null) - { - args.addAll(options); - } - - if (maxThreads != null) - { - args.add("-nt"); - args.add(maxThreads.toString()); - } - else - { - getLogger().debug("max threads not set"); - } - - execute(args); - if (!rawCpgOutput.exists()) - { - throw new PipelineJobException("Expected output not found: " + rawCpgOutput.getPath()); - } - - try - { - SequencePipelineService.get().sortROD(rawCpgOutput, getLogger(), 2); - SequencePipelineService.get().sortROD(rawSnpOutput, getLogger(), 2); - } - catch (IOException e) - { - throw new PipelineJobException(e); - } - - //then filter - getLogger().info("filtering CpG VCF"); - List filterArgs1 = new ArrayList<>(); - filterArgs1.add(getJava6Filepath()); - filterArgs1.addAll(SequencePipelineService.get().getJavaOpts()); - filterArgs1.add("-jar"); - filterArgs1.add(getJAR().getPath()); - filterArgs1.add("-T"); - filterArgs1.add("VCFpostprocess"); - filterArgs1.add("-R"); - filterArgs1.add(referenceFasta.getPath()); - filterArgs1.add("-oldVcf"); - filterArgs1.add(rawCpgOutput.getPath()); - filterArgs1.add("-newVcf"); - filterArgs1.add(cpgOutputFile.getPath()); - filterArgs1.add("-snpVcf"); - filterArgs1.add(rawCpgOutput.getPath()); - filterArgs1.add("-o"); - filterArgs1.add(getFilterSummary(cpgOutputFile).getPath()); - execute(filterArgs1); - - (new File(rawCpgOutput.getPath() + ".idx")).delete(); - rawCpgOutput.delete(); - - getLogger().info("filtering CpG VCF"); - List filterArgs2 = new ArrayList<>(); - filterArgs2.add(getJava6Filepath()); - filterArgs2.addAll(SequencePipelineService.get().getJavaOpts()); - filterArgs2.add("-jar"); - filterArgs2.add(getJAR().getPath()); - filterArgs2.add("-T"); - filterArgs2.add("VCFpostprocess"); - filterArgs2.add("-R"); - filterArgs2.add(referenceFasta.getPath()); - filterArgs2.add("-oldVcf"); - filterArgs2.add(rawSnpOutput.getPath()); - filterArgs2.add("-newVcf"); - filterArgs2.add(snpOutputFile.getPath()); - filterArgs2.add("-snpVcf"); - filterArgs2.add(rawSnpOutput.getPath()); - filterArgs2.add("-o"); - filterArgs2.add(getFilterSummary(snpOutputFile).getPath()); - execute(filterArgs2); - - (new File(rawSnpOutput.getPath() + ".idx")).delete(); - rawSnpOutput.delete(); - - if (createdIndex != null) - { - getLogger().debug("\tdeleting temp BAM index: " + createdIndex.getPath()); - createdIndex.delete(); - } - } - - public File getFilterSummary(File vcf) - { - return new File(getOutputDir(vcf), SequencePipelineService.get().getUnzippedBaseName(vcf.getName()) + ".summary.txt"); - } -}