extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/grid/WgsVariantCallJobCreator.java

Code
Comments
Other
Rev Date Author Line
7388 31 Oct 23 nicklas 1 package net.sf.basedb.reggie.grid;
7388 31 Oct 23 nicklas 2
7395 06 Nov 23 nicklas 3 import java.io.StringWriter;
7388 31 Oct 23 nicklas 4 import java.util.ArrayList;
7395 06 Nov 23 nicklas 5 import java.util.Arrays;
7388 31 Oct 23 nicklas 6 import java.util.List;
7388 31 Oct 23 nicklas 7
7439 16 Nov 23 nicklas 8 import net.sf.basedb.core.AnnotationType;
7410 10 Nov 23 nicklas 9 import net.sf.basedb.core.AnyToAny;
7410 10 Nov 23 nicklas 10 import net.sf.basedb.core.DataFileType;
7388 31 Oct 23 nicklas 11 import net.sf.basedb.core.DbControl;
7388 31 Oct 23 nicklas 12 import net.sf.basedb.core.DerivedBioAssay;
7410 10 Nov 23 nicklas 13 import net.sf.basedb.core.Directory;
7439 16 Nov 23 nicklas 14 import net.sf.basedb.core.Extract;
7388 31 Oct 23 nicklas 15 import net.sf.basedb.core.File;
7410 10 Nov 23 nicklas 16 import net.sf.basedb.core.FileServer;
7410 10 Nov 23 nicklas 17 import net.sf.basedb.core.FileSetMember;
7439 16 Nov 23 nicklas 18 import net.sf.basedb.core.InvalidDataException;
7395 06 Nov 23 nicklas 19 import net.sf.basedb.core.ItemList;
7388 31 Oct 23 nicklas 20 import net.sf.basedb.core.ItemNotFoundException;
7395 06 Nov 23 nicklas 21 import net.sf.basedb.core.ItemParameterType;
7395 06 Nov 23 nicklas 22 import net.sf.basedb.core.ItemQuery;
7388 31 Oct 23 nicklas 23 import net.sf.basedb.core.ItemSubtype;
7388 31 Oct 23 nicklas 24 import net.sf.basedb.core.Job;
7410 10 Nov 23 nicklas 25 import net.sf.basedb.core.Path;
7406 08 Nov 23 nicklas 26 import net.sf.basedb.core.RawBioAssay;
7406 08 Nov 23 nicklas 27 import net.sf.basedb.core.Sample;
7388 31 Oct 23 nicklas 28 import net.sf.basedb.core.SessionControl;
7388 31 Oct 23 nicklas 29 import net.sf.basedb.core.Software;
7388 31 Oct 23 nicklas 30 import net.sf.basedb.core.StringParameterType;
7388 31 Oct 23 nicklas 31 import net.sf.basedb.opengrid.JobDefinition;
7388 31 Oct 23 nicklas 32 import net.sf.basedb.opengrid.JobStatus;
7388 31 Oct 23 nicklas 33 import net.sf.basedb.opengrid.OpenGridCluster;
7388 31 Oct 23 nicklas 34 import net.sf.basedb.opengrid.OpenGridSession;
7388 31 Oct 23 nicklas 35 import net.sf.basedb.opengrid.ScriptBuilder;
7388 31 Oct 23 nicklas 36 import net.sf.basedb.opengrid.config.ClusterConfig;
7388 31 Oct 23 nicklas 37 import net.sf.basedb.opengrid.config.JobConfig;
7395 06 Nov 23 nicklas 38 import net.sf.basedb.opengrid.filetransfer.StringUploadSource;
7388 31 Oct 23 nicklas 39 import net.sf.basedb.opengrid.service.JobCompletionHandler;
7388 31 Oct 23 nicklas 40 import net.sf.basedb.reggie.Reggie;
7388 31 Oct 23 nicklas 41 import net.sf.basedb.reggie.XmlConfig;
7388 31 Oct 23 nicklas 42 import net.sf.basedb.reggie.dao.AlignedSequences;
7388 31 Oct 23 nicklas 43 import net.sf.basedb.reggie.dao.Annotationtype;
7406 08 Nov 23 nicklas 44 import net.sf.basedb.reggie.dao.BiomaterialList;
7388 31 Oct 23 nicklas 45 import net.sf.basedb.reggie.dao.Datafiletype;
7388 31 Oct 23 nicklas 46 import net.sf.basedb.reggie.dao.DoNotUse;
7410 10 Nov 23 nicklas 47 import net.sf.basedb.reggie.dao.Fileserver;
7389 01 Nov 23 nicklas 48 import net.sf.basedb.reggie.dao.PanelOfNormal;
7388 31 Oct 23 nicklas 49 import net.sf.basedb.reggie.dao.Pipeline;
7410 10 Nov 23 nicklas 50 import net.sf.basedb.reggie.dao.Rawbioassay;
7406 08 Nov 23 nicklas 51 import net.sf.basedb.reggie.dao.Rawdatatype;
7388 31 Oct 23 nicklas 52 import net.sf.basedb.reggie.dao.Subtype;
7406 08 Nov 23 nicklas 53 import net.sf.basedb.reggie.dao.TumorNormalPair;
7388 31 Oct 23 nicklas 54 import net.sf.basedb.util.Values;
7395 06 Nov 23 nicklas 55 import net.sf.basedb.util.export.TableWriter;
7388 31 Oct 23 nicklas 56
7388 31 Oct 23 nicklas 57 /**
7388 31 Oct 23 nicklas 58   Helper class for creating items needed for executing WGS variant calling
7388 31 Oct 23 nicklas 59   and submitting jobs to the cluster.
7388 31 Oct 23 nicklas 60   
7388 31 Oct 23 nicklas 61   @author nicklas
7388 31 Oct 23 nicklas 62   @since 4.50
7388 31 Oct 23 nicklas 63 */
7388 31 Oct 23 nicklas 64 public class WgsVariantCallJobCreator 
7388 31 Oct 23 nicklas 65   extends AbstractJobCreator
7388 31 Oct 23 nicklas 66 {
7388 31 Oct 23 nicklas 67   private Software software;
7439 16 Nov 23 nicklas 68   private String panelOfNormals;
7388 31 Oct 23 nicklas 69
7388 31 Oct 23 nicklas 70   public WgsVariantCallJobCreator()
7388 31 Oct 23 nicklas 71   {}
7388 31 Oct 23 nicklas 72
7388 31 Oct 23 nicklas 73   /**
7388 31 Oct 23 nicklas 74     Set the software item to set on created PanelOfNormals.
7388 31 Oct 23 nicklas 75     @see DerivedBioAssay#setSoftware(Software)
7388 31 Oct 23 nicklas 76   */
7388 31 Oct 23 nicklas 77   public void setSoftware(Software software)
7388 31 Oct 23 nicklas 78   {
7388 31 Oct 23 nicklas 79     this.software = software;
7388 31 Oct 23 nicklas 80   }
7388 31 Oct 23 nicklas 81
7439 16 Nov 23 nicklas 82   /**
7439 16 Nov 23 nicklas 83     Set the panel-of-normals that should be used in the paired variant calling.
7439 16 Nov 23 nicklas 84   */
7439 16 Nov 23 nicklas 85   public void setPanelOfNormals(String panelOfNormals)
7439 16 Nov 23 nicklas 86   {
7439 16 Nov 23 nicklas 87     this.panelOfNormals = panelOfNormals;
7439 16 Nov 23 nicklas 88   }
7388 31 Oct 23 nicklas 89   
7388 31 Oct 23 nicklas 90   /**
7388 31 Oct 23 nicklas 91     Create a child items for all given aligneded sequences and schedule
7388 31 Oct 23 nicklas 92     jobs on the given cluster for running StringTie.
7388 31 Oct 23 nicklas 93     @return A list with the corresponding jobs in BASE
7388 31 Oct 23 nicklas 94   */
7388 31 Oct 23 nicklas 95   public List<JobDefinition> createPonVariantCallingJobs(DbControl dc, OpenGridCluster cluster, List<AlignedSequences> alignedSequences)
7388 31 Oct 23 nicklas 96   {
7388 31 Oct 23 nicklas 97     SessionControl sc = dc.getSessionControl();
7388 31 Oct 23 nicklas 98     
7388 31 Oct 23 nicklas 99     ClusterConfig clusterCfg = cluster.getConfig();
7388 31 Oct 23 nicklas 100     XmlConfig cfg = Reggie.getConfig(cluster.getId());
7388 31 Oct 23 nicklas 101     if (cfg == null)
7388 31 Oct 23 nicklas 102     {
7388 31 Oct 23 nicklas 103       throw new ItemNotFoundException("No configuration in reggie-config.xml for cluster: " + cluster.getId());
7388 31 Oct 23 nicklas 104     }
7416 13 Nov 23 nicklas 105     String parameterSet = (String)Annotationtype.PARAMETER_SET.getAnnotationValue(dc, software);
7388 31 Oct 23 nicklas 106   
7388 31 Oct 23 nicklas 107     // Get global options
7388 31 Oct 23 nicklas 108     String global_env = ScriptUtil.multilineIndent(cfg.getConfig("global-env"));
7388 31 Oct 23 nicklas 109     String projectArchive = cfg.getRequiredConfig("project-archive-dna", null);
7388 31 Oct 23 nicklas 110
7388 31 Oct 23 nicklas 111     // Options for the programs
7416 13 Nov 23 nicklas 112     String vcall_submit = cfg.getConfig("wgs-variant-call/submit", parameterSet, null);
7416 13 Nov 23 nicklas 113     String vcall_submit_debug = cfg.getConfig("wgs-variant-call/submit-debug", parameterSet, null);
7416 13 Nov 23 nicklas 114     String vcall_env = ScriptUtil.multilineIndent(cfg.getRequiredConfig("wgs-variant-call/env", parameterSet));
7416 13 Nov 23 nicklas 115     String vcall_envpon = ScriptUtil.multilineIndent(cfg.getConfig("wgs-variant-call/env-pon-vcall", parameterSet, null));
7416 13 Nov 23 nicklas 116     String vcall_envdebug = ScriptUtil.multilineIndent(cfg.getConfig("wgs-variant-call/env-debug", parameterSet, null));
7416 13 Nov 23 nicklas 117     String vcall_execute = ScriptUtil.multilineIndent(cfg.getConfig("wgs-variant-call/execute-pon-vcall", parameterSet, "./wgs_pon_vcall.sh"));
7388 31 Oct 23 nicklas 118     
7388 31 Oct 23 nicklas 119     // Options common for all jobs
7388 31 Oct 23 nicklas 120     JobConfig jobConfig = new JobConfig();
7388 31 Oct 23 nicklas 121     if (priority != null) jobConfig.setPriority(priority);
7388 31 Oct 23 nicklas 122     if (partition != null) jobConfig.setSbatchOption("partition", ScriptUtil.checkValidScriptParameter(partition));
7388 31 Oct 23 nicklas 123     jobConfig.convertOptionsTo(clusterCfg.getType());
7388 31 Oct 23 nicklas 124     if (submitOptionsOverride != null)
7388 31 Oct 23 nicklas 125     {
7388 31 Oct 23 nicklas 126       ScriptUtil.addSubmitOptions(jobConfig, submitOptionsOverride, clusterCfg.getType());
7388 31 Oct 23 nicklas 127     }
7388 31 Oct 23 nicklas 128     else
7388 31 Oct 23 nicklas 129     {
7388 31 Oct 23 nicklas 130       ScriptUtil.addSubmitOptions(jobConfig, vcall_submit, clusterCfg.getType());
7388 31 Oct 23 nicklas 131       if (debug) ScriptUtil.addSubmitOptions(jobConfig, vcall_submit_debug, clusterCfg.getType());
7388 31 Oct 23 nicklas 132     }
7388 31 Oct 23 nicklas 133     
7388 31 Oct 23 nicklas 134     ItemSubtype ponType = Subtype.PANEL_OF_NORMAL.get(dc);
7388 31 Oct 23 nicklas 135     
7388 31 Oct 23 nicklas 136     // We submit one job for each raw bioassay to the cluster
7388 31 Oct 23 nicklas 137     List<JobDefinition> jobDefs = new ArrayList<JobDefinition>(alignedSequences.size());
7388 31 Oct 23 nicklas 138
7388 31 Oct 23 nicklas 139     for (AlignedSequences as : alignedSequences)
7388 31 Oct 23 nicklas 140     {
7388 31 Oct 23 nicklas 141       as = AlignedSequences.getById(dc, as.getId()); // Ensure item is loaded in this transaction
7388 31 Oct 23 nicklas 142
7388 31 Oct 23 nicklas 143       // Get some information about the aligned data that we need
7388 31 Oct 23 nicklas 144       DerivedBioAssay aligned = as.getDerivedBioAssay();
7388 31 Oct 23 nicklas 145       
7388 31 Oct 23 nicklas 146       String bamFolder = (String)Annotationtype.DATA_FILES_FOLDER.getAnnotationValue(dc, aligned);
7388 31 Oct 23 nicklas 147       File bamFile = Datafiletype.BAM.getFile(dc, aligned);
7388 31 Oct 23 nicklas 148       String bamName = ScriptUtil.checkValidScriptParameter(bamFile.getName());
7388 31 Oct 23 nicklas 149       
7388 31 Oct 23 nicklas 150       // Create job 
7388 31 Oct 23 nicklas 151       Job vcallJob = Job.getNew(dc, null, null, null);
7388 31 Oct 23 nicklas 152       vcallJob.setItemSubtype(Subtype.VARIANT_CALLING_JOB.get(dc));
7388 31 Oct 23 nicklas 153       vcallJob.setPluginVersion("reggie-"+Reggie.VERSION);
7388 31 Oct 23 nicklas 154       vcallJob.setSendMessage(Values.getBoolean(sc.getUserClientSetting("plugins.sendmessage"), false));
7388 31 Oct 23 nicklas 155       vcallJob.setName("Panel-of-normal variant calling " + aligned.getName());
7388 31 Oct 23 nicklas 156       vcallJob.setParameterValue("pipeline", new StringParameterType(), Pipeline.DNA_NORMAL_WGS.getId());
7388 31 Oct 23 nicklas 157       if (debug) vcallJob.setName(vcallJob.getName() + " (debug)");
7388 31 Oct 23 nicklas 158       if (partition != null) vcallJob.setParameterValue("partition", new StringParameterType(), partition);
7388 31 Oct 23 nicklas 159       if (submitOptionsOverride != null) vcallJob.setParameterValue("jobOptions", new StringParameterType(), submitOptionsOverride);
7388 31 Oct 23 nicklas 160       dc.saveItem(vcallJob);
7388 31 Oct 23 nicklas 161
7389 01 Nov 23 nicklas 162       // Create panel-of-normal bioassay
7388 31 Oct 23 nicklas 163       String ponName = ScriptUtil.checkValidScriptParameter(as.getNextDerivedBioAssayName(dc, Subtype.PANEL_OF_NORMAL));
7388 31 Oct 23 nicklas 164       DerivedBioAssay pon = DerivedBioAssay.getNew(dc, aligned, vcallJob);
7388 31 Oct 23 nicklas 165       Pipeline.DNA_NORMAL_WGS.setAnnotation(dc, pon);
7388 31 Oct 23 nicklas 166       pon.setItemSubtype(ponType);
7388 31 Oct 23 nicklas 167       pon.setName(ponName);
7388 31 Oct 23 nicklas 168       pon.setExtract(aligned.getExtract());
7388 31 Oct 23 nicklas 169       pon.setSoftware(software);
7388 31 Oct 23 nicklas 170       DoNotUse.copyDoNotUseAnnotations(dc, aligned, pon, false);
7388 31 Oct 23 nicklas 171       dc.saveItem(pon);
7388 31 Oct 23 nicklas 172
7389 01 Nov 23 nicklas 173       String ponFolder = (debug ? "/debug/":"/")+pon.getName();
7389 01 Nov 23 nicklas 174       Annotationtype.DATA_FILES_FOLDER.setAnnotationValue(dc, pon, ponFolder);
7388 31 Oct 23 nicklas 175       if (autoConfirm)
7388 31 Oct 23 nicklas 176       {
7388 31 Oct 23 nicklas 177         Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, pon, "AutoConfirm");
7388 31 Oct 23 nicklas 178       }
7389 01 Nov 23 nicklas 179       
7388 31 Oct 23 nicklas 180       // Checks to make sure no bad things are included in script file
7388 31 Oct 23 nicklas 181       ScriptUtil.checkValidScriptParameter(pon.getName());
7388 31 Oct 23 nicklas 182       ScriptUtil.checkValidScriptParameter(bamFile.getName());
7388 31 Oct 23 nicklas 183
7388 31 Oct 23 nicklas 184       ScriptBuilder script = new ScriptBuilder();
7388 31 Oct 23 nicklas 185       script.cmd(debug ? "set -ex" : "set -e");
7388 31 Oct 23 nicklas 186       script.cmd("umask -S u=rwx,g=,o="); // Results are private to scanb user
7388 31 Oct 23 nicklas 187       script.newLine();
7388 31 Oct 23 nicklas 188       script.cmd(global_env);
7388 31 Oct 23 nicklas 189       script.export("ArchiveFolder", projectArchive);
7388 31 Oct 23 nicklas 190       script.export("BamFolder", "${ArchiveFolder}"+bamFolder);
7388 31 Oct 23 nicklas 191       script.export("BamName", bamName.replace(".bam", ""));
7388 31 Oct 23 nicklas 192       script.newLine();
7388 31 Oct 23 nicklas 193       script.cmd(vcall_env);
7406 08 Nov 23 nicklas 194       script.cmd(vcall_envpon);
7388 31 Oct 23 nicklas 195       if (debug) script.cmd(vcall_envdebug);
7389 01 Nov 23 nicklas 196       script.export("PonFolder", "${PonArchive}"+ponFolder);
7389 01 Nov 23 nicklas 197       script.newLine();
7388 31 Oct 23 nicklas 198       script.cmd(vcall_execute);
7388 31 Oct 23 nicklas 199
7388 31 Oct 23 nicklas 200       JobDefinition jobDef = new JobDefinition("PonCall", jobConfig, batchConfig, vcallJob);
7388 31 Oct 23 nicklas 201       jobDef.addFile(ScriptUtil.upload("wgs_pon_vcall.sh"));
7388 31 Oct 23 nicklas 202       jobDef.addFile(ScriptUtil.upload("reggie-utils.sh"));
7388 31 Oct 23 nicklas 203       jobDef.addFile(ScriptUtil.upload("stdwrap.sh"));
7388 31 Oct 23 nicklas 204       jobDef.setDebug(debug);
7388 31 Oct 23 nicklas 205       jobDef.setCmd(script.toString());
7388 31 Oct 23 nicklas 206       jobDefs.add(jobDef);
7388 31 Oct 23 nicklas 207     }
7388 31 Oct 23 nicklas 208     
7388 31 Oct 23 nicklas 209     return jobDefs;
7388 31 Oct 23 nicklas 210   }
7388 31 Oct 23 nicklas 211   
7388 31 Oct 23 nicklas 212   
7388 31 Oct 23 nicklas 213   /**
7395 06 Nov 23 nicklas 214     Create a child items for all given aligneded sequences and schedule
7395 06 Nov 23 nicklas 215     jobs on the given cluster for running StringTie.
7395 06 Nov 23 nicklas 216     @return A list with the corresponding jobs in BASE
7395 06 Nov 23 nicklas 217   */
7395 06 Nov 23 nicklas 218   public Job buildPanelOfNormals(DbControl dc, OpenGridCluster cluster, ItemList list)
7395 06 Nov 23 nicklas 219   {
7395 06 Nov 23 nicklas 220     SessionControl sc = dc.getSessionControl();
7395 06 Nov 23 nicklas 221     
7395 06 Nov 23 nicklas 222     ClusterConfig clusterCfg = cluster.getConfig();
7395 06 Nov 23 nicklas 223     XmlConfig cfg = Reggie.getConfig(cluster.getId());
7395 06 Nov 23 nicklas 224     if (cfg == null)
7395 06 Nov 23 nicklas 225     {
7395 06 Nov 23 nicklas 226       throw new ItemNotFoundException("No configuration in reggie-config.xml for cluster: " + cluster.getId());
7395 06 Nov 23 nicklas 227     }
7395 06 Nov 23 nicklas 228   
7395 06 Nov 23 nicklas 229     // Get global options
7395 06 Nov 23 nicklas 230     String global_env = ScriptUtil.multilineIndent(cfg.getConfig("global-env"));
7395 06 Nov 23 nicklas 231   
7395 06 Nov 23 nicklas 232     // Options for the programs
7395 06 Nov 23 nicklas 233     String build_submit = cfg.getConfig("wgs-variant-call/submit", null, null);
7395 06 Nov 23 nicklas 234     String build_submit_debug = cfg.getConfig("wgs-variant-call/submit-debug", null, null);
7395 06 Nov 23 nicklas 235     String build_env = ScriptUtil.multilineIndent(cfg.getRequiredConfig("wgs-variant-call/env", null));
7416 13 Nov 23 nicklas 236     String build_envpon = ScriptUtil.multilineIndent(cfg.getConfig("wgs-variant-call/env-pon-build", null, null));
7395 06 Nov 23 nicklas 237     String build_envdebug = ScriptUtil.multilineIndent(cfg.getConfig("wgs-variant-call/env-debug", null, null));
7395 06 Nov 23 nicklas 238     String build_execute = ScriptUtil.multilineIndent(cfg.getConfig("wgs-variant-call/execute-pon-build", null, "./wgs_pon_build.sh"));
7395 06 Nov 23 nicklas 239     
7395 06 Nov 23 nicklas 240     // Options common for all jobs
7395 06 Nov 23 nicklas 241     JobConfig jobConfig = new JobConfig();
7395 06 Nov 23 nicklas 242     if (priority != null) jobConfig.setPriority(priority);
7395 06 Nov 23 nicklas 243     if (partition != null) jobConfig.setSbatchOption("partition", ScriptUtil.checkValidScriptParameter(partition));
7395 06 Nov 23 nicklas 244     jobConfig.convertOptionsTo(clusterCfg.getType());
7395 06 Nov 23 nicklas 245     if (submitOptionsOverride != null)
7395 06 Nov 23 nicklas 246     {
7395 06 Nov 23 nicklas 247       ScriptUtil.addSubmitOptions(jobConfig, submitOptionsOverride, clusterCfg.getType());
7395 06 Nov 23 nicklas 248     }
7395 06 Nov 23 nicklas 249     else
7395 06 Nov 23 nicklas 250     {
7395 06 Nov 23 nicklas 251       ScriptUtil.addSubmitOptions(jobConfig, build_submit, clusterCfg.getType());
7395 06 Nov 23 nicklas 252       if (debug) ScriptUtil.addSubmitOptions(jobConfig, build_submit_debug, clusterCfg.getType());
7395 06 Nov 23 nicklas 253     }
7395 06 Nov 23 nicklas 254     
7395 06 Nov 23 nicklas 255     // Create job 
7395 06 Nov 23 nicklas 256     Job buildJob = Job.getNew(dc, null, null, null);
7395 06 Nov 23 nicklas 257     buildJob.setItemSubtype(Subtype.VARIANT_STATISTICS_JOB.get(dc));
7395 06 Nov 23 nicklas 258     buildJob.setPluginVersion("reggie-"+Reggie.VERSION);
7395 06 Nov 23 nicklas 259     buildJob.setSendMessage(Values.getBoolean(sc.getUserClientSetting("plugins.sendmessage"), false));
7395 06 Nov 23 nicklas 260     buildJob.setName("Build panel-of-normals: " + list.getName());
7395 06 Nov 23 nicklas 261     buildJob.setParameterValue("pipeline", new StringParameterType(), Pipeline.DNA_NORMAL_WGS.getId());
7395 06 Nov 23 nicklas 262     buildJob.setParameterValue("list", new ItemParameterType<ItemList>(ItemList.class, null), list);
7395 06 Nov 23 nicklas 263     if (debug) buildJob.setName(buildJob.getName() + " (debug)");
7395 06 Nov 23 nicklas 264     if (partition != null) buildJob.setParameterValue("partition", new StringParameterType(), partition);
7395 06 Nov 23 nicklas 265     if (submitOptionsOverride != null) buildJob.setParameterValue("jobOptions", new StringParameterType(), submitOptionsOverride);
7395 06 Nov 23 nicklas 266     dc.saveItem(buildJob);
7395 06 Nov 23 nicklas 267     
7395 06 Nov 23 nicklas 268     ScriptBuilder script = new ScriptBuilder();
7395 06 Nov 23 nicklas 269     script.cmd(debug ? "set -ex" : "set -e");
7395 06 Nov 23 nicklas 270     script.cmd("umask -S u=rwx,g=,o="); // Results are private to scanb user
7395 06 Nov 23 nicklas 271     script.newLine();
7395 06 Nov 23 nicklas 272     script.cmd(global_env);
7395 06 Nov 23 nicklas 273     script.newLine();
7395 06 Nov 23 nicklas 274     script.cmd(build_env);
7406 08 Nov 23 nicklas 275     script.cmd(build_envpon);
7395 06 Nov 23 nicklas 276     if (debug) script.cmd(build_envdebug);
7395 06 Nov 23 nicklas 277     script.newLine();
7395 06 Nov 23 nicklas 278     script.cmd(build_execute);
7395 06 Nov 23 nicklas 279     
7395 06 Nov 23 nicklas 280     // Export a list with PanelOfNormal names and DataFilesFolder annotations
7395 06 Nov 23 nicklas 281     StringWriter ponList = new StringWriter(list.getSize()*80);
7395 06 Nov 23 nicklas 282     TableWriter tw = new TableWriter(ponList);
7395 06 Nov 23 nicklas 283     ItemQuery<DerivedBioAssay> query = list.getMembers();
7395 06 Nov 23 nicklas 284     query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
7395 06 Nov 23 nicklas 285     for (DerivedBioAssay pon : query.list(dc))
7395 06 Nov 23 nicklas 286     {
7395 06 Nov 23 nicklas 287       String dataFolder = ScriptUtil.checkValidPath((String)Annotationtype.DATA_FILES_FOLDER.getAnnotationValue(dc, pon), true, false);
7395 06 Nov 23 nicklas 288       tw.tablePrintData(pon.getName(), dataFolder);
7395 06 Nov 23 nicklas 289     }
7395 06 Nov 23 nicklas 290     tw.flush();
7395 06 Nov 23 nicklas 291     tw.close();
7395 06 Nov 23 nicklas 292     
7395 06 Nov 23 nicklas 293     JobDefinition jobDef = new JobDefinition("PonBuild", jobConfig, batchConfig, buildJob);
7395 06 Nov 23 nicklas 294     jobDef.addFile(ScriptUtil.upload("wgs_pon_build.sh"));
7395 06 Nov 23 nicklas 295     jobDef.addFile(ScriptUtil.upload("reggie-utils.sh"));
7395 06 Nov 23 nicklas 296     jobDef.addFile(ScriptUtil.upload("stdwrap.sh"));
7395 06 Nov 23 nicklas 297     jobDef.addFile(new StringUploadSource("ponlist.txt", ponList.toString()));
7395 06 Nov 23 nicklas 298     jobDef.setDebug(debug);
7395 06 Nov 23 nicklas 299     jobDef.setCmd(script.toString());
7395 06 Nov 23 nicklas 300     ScriptUtil.submitJobs(dc, cluster, Arrays.asList(jobDef));
7395 06 Nov 23 nicklas 301     
7395 06 Nov 23 nicklas 302     return buildJob;
7395 06 Nov 23 nicklas 303   }
7395 06 Nov 23 nicklas 304
7411 10 Nov 23 nicklas 305   public List<JobDefinition> createPairedVariantCallingJobs(DbControl dc, OpenGridCluster cluster, List<TumorNormalPair> alignedSequences)
7406 08 Nov 23 nicklas 306   {
7406 08 Nov 23 nicklas 307     SessionControl sc = dc.getSessionControl();
7406 08 Nov 23 nicklas 308     
7406 08 Nov 23 nicklas 309     ClusterConfig clusterCfg = cluster.getConfig();
7406 08 Nov 23 nicklas 310     XmlConfig cfg = Reggie.getConfig(cluster.getId());
7406 08 Nov 23 nicklas 311     if (cfg == null)
7406 08 Nov 23 nicklas 312     {
7406 08 Nov 23 nicklas 313       throw new ItemNotFoundException("No configuration in reggie-config.xml for cluster: " + cluster.getId());
7406 08 Nov 23 nicklas 314     }
7406 08 Nov 23 nicklas 315     String parameterSet = (String)Annotationtype.PARAMETER_SET.getAnnotationValue(dc, software);
7406 08 Nov 23 nicklas 316
7406 08 Nov 23 nicklas 317     // Get global options
7406 08 Nov 23 nicklas 318     String global_env = ScriptUtil.multilineIndent(cfg.getConfig("global-env"));
7406 08 Nov 23 nicklas 319     String projectArchiveDNA = cfg.getRequiredConfig("project-archive-dna", null);
7406 08 Nov 23 nicklas 320     
7406 08 Nov 23 nicklas 321     // Options for the programs
7406 08 Nov 23 nicklas 322     String vcall_submit = cfg.getConfig("wgs-variant-call/submit", parameterSet, null);
7406 08 Nov 23 nicklas 323     String vcall_submit_debug = cfg.getConfig("wgs-variant-call/submit-debug", parameterSet, null);
7406 08 Nov 23 nicklas 324     String vcall_env = ScriptUtil.multilineIndent(cfg.getRequiredConfig("wgs-variant-call/env", parameterSet));
7416 13 Nov 23 nicklas 325     String vcall_envpaired = ScriptUtil.multilineIndent(cfg.getConfig("wgs-variant-call/env-paired-vcall", parameterSet, null));
7406 08 Nov 23 nicklas 326     String vcall_envdebug = ScriptUtil.multilineIndent(cfg.getConfig("wgs-variant-call/env-debug", parameterSet, null));
7406 08 Nov 23 nicklas 327     String vcall_execute = ScriptUtil.multilineIndent(cfg.getConfig("wgs-variant-call/execute-paired-vcall", parameterSet, "./variantcall.sh"));
7406 08 Nov 23 nicklas 328     
7406 08 Nov 23 nicklas 329     // Selected items must be removed from this list
7406 08 Nov 23 nicklas 330     ItemList vcallPipeline = BiomaterialList.WGS_VARIANT_CALLING_PIPELINE.load(dc);
7406 08 Nov 23 nicklas 331     // Create VariantCall raw bioassays
7406 08 Nov 23 nicklas 332     Rawdatatype variantCallType = Rawdatatype.VARIANT_CALL;
7406 08 Nov 23 nicklas 333
7406 08 Nov 23 nicklas 334     // Options common for all jobs
7406 08 Nov 23 nicklas 335     JobConfig jobConfig = new JobConfig();
7406 08 Nov 23 nicklas 336     if (priority != null) jobConfig.setPriority(priority);
7406 08 Nov 23 nicklas 337     if (partition != null) jobConfig.setSbatchOption("partition", ScriptUtil.checkValidScriptParameter(partition));
7406 08 Nov 23 nicklas 338     jobConfig.convertOptionsTo(clusterCfg.getType());
7406 08 Nov 23 nicklas 339     if (submitOptionsOverride != null)
7406 08 Nov 23 nicklas 340     {
7406 08 Nov 23 nicklas 341       ScriptUtil.addSubmitOptions(jobConfig, submitOptionsOverride, clusterCfg.getType());
7406 08 Nov 23 nicklas 342     }
7406 08 Nov 23 nicklas 343     else
7406 08 Nov 23 nicklas 344     {
7406 08 Nov 23 nicklas 345       ScriptUtil.addSubmitOptions(jobConfig, vcall_submit, clusterCfg.getType());
7406 08 Nov 23 nicklas 346       if (debug) ScriptUtil.addSubmitOptions(jobConfig, vcall_submit_debug, clusterCfg.getType());
7406 08 Nov 23 nicklas 347     }
7406 08 Nov 23 nicklas 348     
7439 16 Nov 23 nicklas 349     AnnotationType ponType = Annotationtype.PANEL_OF_NORMALS.get(dc);
7406 08 Nov 23 nicklas 350     // We submit one job for each raw bioassay to the cluster
7406 08 Nov 23 nicklas 351     List<JobDefinition> jobDefs = new ArrayList<JobDefinition>(alignedSequences.size());
7406 08 Nov 23 nicklas 352     for (TumorNormalPair pair : alignedSequences)
7406 08 Nov 23 nicklas 353     {
7406 08 Nov 23 nicklas 354       // Ensure items are loaded in this transaction
7406 08 Nov 23 nicklas 355       pair = pair.reload(dc);
7406 08 Nov 23 nicklas 356       
7406 08 Nov 23 nicklas 357       // Get some information about the aligned data that we need
7406 08 Nov 23 nicklas 358       DerivedBioAssay tumor = pair.tumor.getDerivedBioAssay();
7406 08 Nov 23 nicklas 359       DerivedBioAssay normal = pair.normal.getDerivedBioAssay();
7439 16 Nov 23 nicklas 360       Extract library = tumor.getExtract();
7406 08 Nov 23 nicklas 361       vcallPipeline.removeItem(tumor);
7406 08 Nov 23 nicklas 362       
7406 08 Nov 23 nicklas 363       String tumorFolder = (String)Annotationtype.DATA_FILES_FOLDER.getAnnotationValue(dc, tumor);
7406 08 Nov 23 nicklas 364       File tumorBam = Datafiletype.BAM.getFile(dc, tumor);
7406 08 Nov 23 nicklas 365       String normalFolder = (String)Annotationtype.DATA_FILES_FOLDER.getAnnotationValue(dc, normal);
7406 08 Nov 23 nicklas 366       File normalBam = Datafiletype.BAM.getFile(dc, normal);
7411 10 Nov 23 nicklas 367       Pipeline pipeline = Pipeline.DNA_PAIRED_VARIANTCALL;
7406 08 Nov 23 nicklas 368
7439 16 Nov 23 nicklas 369       // Find which panel-of-normals to use
7439 16 Nov 23 nicklas 370       String panelOfNormalsToUse = panelOfNormals;
7439 16 Nov 23 nicklas 371       if (panelOfNormalsToUse == null)
7439 16 Nov 23 nicklas 372       {
7439 16 Nov 23 nicklas 373         if (library == null)
7439 16 Nov 23 nicklas 374         {
7439 16 Nov 23 nicklas 375           throw new ItemNotFoundException("Expected to find a parent Library for "+tumor.getName());
7439 16 Nov 23 nicklas 376         }
7439 16 Nov 23 nicklas 377         // Use the value from the Library.ExternalOperator annotation
7439 16 Nov 23 nicklas 378         String tmp = (String)Annotationtype.EXTERNAL_OPERATOR.getAnnotationValue(dc, library);
7439 16 Nov 23 nicklas 379         panelOfNormalsToUse = ponType.findValue(tmp, true, true);
7439 16 Nov 23 nicklas 380         if (panelOfNormalsToUse == null)
7439 16 Nov 23 nicklas 381         {
7439 16 Nov 23 nicklas 382           if (tmp != null)
7439 16 Nov 23 nicklas 383           {
7439 16 Nov 23 nicklas 384             throw new InvalidDataException(library.getName()+": Operator '"+tmp+"' has not matching panel-of-normals");
7439 16 Nov 23 nicklas 385           }
7439 16 Nov 23 nicklas 386           else
7439 16 Nov 23 nicklas 387           {
7439 16 Nov 23 nicklas 388             throw new ItemNotFoundException(library.getName()+": Missing ExternalOperator annotation");
7439 16 Nov 23 nicklas 389           }
7439 16 Nov 23 nicklas 390         }
7439 16 Nov 23 nicklas 391       }
7439 16 Nov 23 nicklas 392       panelOfNormalsToUse = ScriptUtil.checkValidScriptParameter(panelOfNormalsToUse);
7439 16 Nov 23 nicklas 393       String vcall_envpon = cfg.getRequiredConfig("wgs-variant-call/panel-of-normals[@operator='"+panelOfNormalsToUse+"']", parameterSet);
7439 16 Nov 23 nicklas 394       
7406 08 Nov 23 nicklas 395       // Create job 
7406 08 Nov 23 nicklas 396       Job vcallJob = Job.getNew(dc, null, null, null);
7406 08 Nov 23 nicklas 397       vcallJob.setItemSubtype(Subtype.VARIANT_CALLING_JOB.get(dc));
7406 08 Nov 23 nicklas 398       vcallJob.setPluginVersion("reggie-"+Reggie.VERSION);
7406 08 Nov 23 nicklas 399       vcallJob.setSendMessage(Values.getBoolean(sc.getUserClientSetting("plugins.sendmessage"), false));
7406 08 Nov 23 nicklas 400       vcallJob.setName("Run WGS variant calling: " + tumor.getName()+"/"+normal.getName());
7411 10 Nov 23 nicklas 401       vcallJob.setParameterValue("pipeline", new StringParameterType(), pipeline.getId());
7406 08 Nov 23 nicklas 402       if (debug) vcallJob.setName(vcallJob.getName() + " (debug)");
7406 08 Nov 23 nicklas 403       if (partition != null) vcallJob.setParameterValue("partition", new StringParameterType(), partition);
7406 08 Nov 23 nicklas 404       if (submitOptionsOverride != null) vcallJob.setParameterValue("jobOptions", new StringParameterType(), submitOptionsOverride);
7406 08 Nov 23 nicklas 405       dc.saveItem(vcallJob);
7406 08 Nov 23 nicklas 406
7406 08 Nov 23 nicklas 407       // Create VariantCall raw bioassay
7406 08 Nov 23 nicklas 408       String rawName = ScriptUtil.checkValidScriptParameter(pair.tumor.getNextRawBioAssayName(dc, Rawdatatype.VARIANT_CALL));
7406 08 Nov 23 nicklas 409       RawBioAssay raw = variantCallType.createRawBioAssay(dc);
7406 08 Nov 23 nicklas 410       pipeline.setAnnotation(dc, raw);
7406 08 Nov 23 nicklas 411       raw.setJob(vcallJob);
7406 08 Nov 23 nicklas 412       raw.setName(rawName);
7439 16 Nov 23 nicklas 413       raw.setParentExtract(library);
7406 08 Nov 23 nicklas 414       raw.setSoftware(software);
7406 08 Nov 23 nicklas 415       raw.setProtocol(null); // To prevent a default value
7406 08 Nov 23 nicklas 416       raw.setArrayDesign(null); // To prevent the default hg38
7406 08 Nov 23 nicklas 417       raw.setParentBioAssay(tumor);
7406 08 Nov 23 nicklas 418       DoNotUse.copyDoNotUseAnnotations(dc, tumor, raw, false);
7406 08 Nov 23 nicklas 419       dc.saveItem(raw);
7436 15 Nov 23 nicklas 420       // Link the normal alignment
7436 15 Nov 23 nicklas 421       AnyToAny linkedNormal = AnyToAny.getNew(dc, raw, normal, "Normal", false);
7436 15 Nov 23 nicklas 422       linkedNormal.setDescription("The paired normal used in the variant calling.");
7436 15 Nov 23 nicklas 423       dc.saveItem(linkedNormal);
7406 08 Nov 23 nicklas 424
7406 08 Nov 23 nicklas 425       Sample specimen =  (Sample)pair.tumor.findSingleParent(dc, Subtype.SPECIMEN);
7406 08 Nov 23 nicklas 426       if (specimen == null)
7406 08 Nov 23 nicklas 427       {
7439 16 Nov 23 nicklas 428         throw new ItemNotFoundException("Expected to find a parent Specimen for "+tumor.getName());
7406 08 Nov 23 nicklas 429       }
7406 08 Nov 23 nicklas 430       String externalTumorName = specimen.getExternalId(); // This is expected in the RG:SM field in the tumor.bam
7406 08 Nov 23 nicklas 431       Sample blood =  (Sample)pair.normal.findSingleParent(dc, Subtype.BLOOD);
7406 08 Nov 23 nicklas 432       if (blood == null)
7406 08 Nov 23 nicklas 433       {
7406 08 Nov 23 nicklas 434         throw new ItemNotFoundException("Expected to find a parent Blood for "+normal.getName());
7406 08 Nov 23 nicklas 435       }
7406 08 Nov 23 nicklas 436       String externalNormalName = blood.getExternalId();
7406 08 Nov 23 nicklas 437       String vcallFolder = tumorFolder + "/"+raw.getName().substring(tumor.getName().length()+1);
7406 08 Nov 23 nicklas 438       if (debug && !vcallFolder.startsWith("/debug"))
7406 08 Nov 23 nicklas 439       {
7406 08 Nov 23 nicklas 440         vcallFolder = "/debug" + vcallFolder;
7406 08 Nov 23 nicklas 441       }
7406 08 Nov 23 nicklas 442       Annotationtype.DATA_FILES_FOLDER.setAnnotationValue(dc, raw, vcallFolder);
7439 16 Nov 23 nicklas 443       Annotationtype.PANEL_OF_NORMALS.setAnnotationValue(dc, raw, panelOfNormalsToUse);
7438 16 Nov 23 nicklas 444       if (autoConfirm)
7438 16 Nov 23 nicklas 445       {
7438 16 Nov 23 nicklas 446         Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, raw, "AutoConfirm");
7438 16 Nov 23 nicklas 447       }
7406 08 Nov 23 nicklas 448
7406 08 Nov 23 nicklas 449       // Checks to make sure no bad things are included in script file
7406 08 Nov 23 nicklas 450       ScriptUtil.checkValidPath(vcallFolder, true, true);
7406 08 Nov 23 nicklas 451       ScriptUtil.checkValidScriptParameter(tumorBam.getName());
7406 08 Nov 23 nicklas 452       ScriptUtil.checkValidScriptParameter(normalBam.getName());
7406 08 Nov 23 nicklas 453
7406 08 Nov 23 nicklas 454       ScriptBuilder script = new ScriptBuilder();
7406 08 Nov 23 nicklas 455       script.cmd(debug ? "set -ex" : "set -e");
7406 08 Nov 23 nicklas 456       // Set file permissions based on consent or external group!
7406 08 Nov 23 nicklas 457       ScriptUtil.setUmaskForItem(dc, pair.tumor, null, script);
7406 08 Nov 23 nicklas 458       script.newLine();
7406 08 Nov 23 nicklas 459       script.cmd(global_env);
7406 08 Nov 23 nicklas 460       script.export("ArchiveFolder", projectArchiveDNA);
7406 08 Nov 23 nicklas 461       script.export("TumorSampleName", ScriptUtil.checkValidScriptParameter(externalTumorName));
7406 08 Nov 23 nicklas 462       script.export("TumorFolder", "${ArchiveFolder}"+tumorFolder);
7406 08 Nov 23 nicklas 463       script.export("TumorBam", tumorBam.getName().replace(".bam", ""));
7406 08 Nov 23 nicklas 464       script.export("NormalSampleName", ScriptUtil.checkValidScriptParameter(externalNormalName));
7406 08 Nov 23 nicklas 465       script.export("NormalFolder", "${ArchiveFolder}"+normalFolder);
7406 08 Nov 23 nicklas 466       script.export("NormalBam", normalBam.getName().replace(".bam", ""));
7406 08 Nov 23 nicklas 467       script.export("VcallFolder", "${ArchiveFolder}"+vcallFolder);
7439 16 Nov 23 nicklas 468       
7406 08 Nov 23 nicklas 469       script.newLine();
7406 08 Nov 23 nicklas 470       script.cmd(vcall_env);
7439 16 Nov 23 nicklas 471       script.cmd(vcall_envpon);
7406 08 Nov 23 nicklas 472       script.cmd(vcall_envpaired);
7406 08 Nov 23 nicklas 473       if (debug) script.cmd(vcall_envdebug);
7406 08 Nov 23 nicklas 474       script.cmd(vcall_execute);
7406 08 Nov 23 nicklas 475
7406 08 Nov 23 nicklas 476       JobDefinition jobDef = new JobDefinition("WGSVariantCall", jobConfig, batchConfig, vcallJob);
7406 08 Nov 23 nicklas 477       jobDef.addFile(ScriptUtil.upload("wgs_paired_vcall.sh"));
7406 08 Nov 23 nicklas 478       jobDef.addFile(ScriptUtil.upload("reggie-utils.sh"));
7406 08 Nov 23 nicklas 479       jobDef.addFile(ScriptUtil.upload("stdwrap.sh"));
7425 14 Nov 23 nicklas 480       jobDef.addFile(ScriptUtil.upload("stderrwrap.sh"));
7406 08 Nov 23 nicklas 481       jobDef.setDebug(debug);
7406 08 Nov 23 nicklas 482       jobDef.setCmd(script.toString());
7406 08 Nov 23 nicklas 483       jobDefs.add(jobDef);
7406 08 Nov 23 nicklas 484
7406 08 Nov 23 nicklas 485     }
7406 08 Nov 23 nicklas 486     
7406 08 Nov 23 nicklas 487     return jobDefs;
7406 08 Nov 23 nicklas 488   }
7395 06 Nov 23 nicklas 489   
7395 06 Nov 23 nicklas 490   /**
7410 10 Nov 23 nicklas 491     Job completion handler for paired variant call jobs.
7410 10 Nov 23 nicklas 492   */
7410 10 Nov 23 nicklas 493   public static class PairedVariantCallJobCompletionHandler
7410 10 Nov 23 nicklas 494     implements JobCompletionHandler
7410 10 Nov 23 nicklas 495   {
7410 10 Nov 23 nicklas 496     
7410 10 Nov 23 nicklas 497     public PairedVariantCallJobCompletionHandler()
7410 10 Nov 23 nicklas 498     {}
7410 10 Nov 23 nicklas 499   
7410 10 Nov 23 nicklas 500     @Override
7410 10 Nov 23 nicklas 501     public String jobCompleted(SessionControl sc, OpenGridSession session, Job job, JobStatus status)
7410 10 Nov 23 nicklas 502     {
7410 10 Nov 23 nicklas 503       String jobName = status.getName();
7410 10 Nov 23 nicklas 504       String files = session.getJobFileAsString(jobName, "files.out", "UTF-8");
7410 10 Nov 23 nicklas 505       String stats = session.getJobFileAsString(jobName, "stats.out", "UTF-8");
7410 10 Nov 23 nicklas 506       Metrics metrics = parseFiles(sc, job, files, stats);
7410 10 Nov 23 nicklas 507       String msg = "Variant calling completed. Found ";
7410 10 Nov 23 nicklas 508       msg += Reggie.formatCount(metrics.numVariants, 1) + " raw variants; ";
7410 10 Nov 23 nicklas 509       msg += Reggie.formatCount(metrics.filteredVariants, 1) + " passed filter; ";
7410 10 Nov 23 nicklas 510       msg += Reggie.formatCount(metrics.numCallable, 2) + " callable bases.";
7410 10 Nov 23 nicklas 511       return msg;
7410 10 Nov 23 nicklas 512     }
7410 10 Nov 23 nicklas 513     
7410 10 Nov 23 nicklas 514     private Metrics parseFiles(SessionControl sc, Job job, String filesOut, String statsOut)
7410 10 Nov 23 nicklas 515     {
7410 10 Nov 23 nicklas 516       DbControl dc = null;
7410 10 Nov 23 nicklas 517       Metrics metrics = new Metrics();
7410 10 Nov 23 nicklas 518       try
7410 10 Nov 23 nicklas 519       {
7410 10 Nov 23 nicklas 520         // Summarize number of variants 
7410 10 Nov 23 nicklas 521         for (String line : statsOut.split("\n"))
7410 10 Nov 23 nicklas 522         {
7410 10 Nov 23 nicklas 523           String[] stat = line.split(":", 2);
7410 10 Nov 23 nicklas 524           String key = stat[0].strip();
7410 10 Nov 23 nicklas 525           int val = Values.getInt(stat[1].strip());
7410 10 Nov 23 nicklas 526           if (key.endsWith(".variants"))
7410 10 Nov 23 nicklas 527           {
7410 10 Nov 23 nicklas 528             metrics.numVariants += val;
7410 10 Nov 23 nicklas 529           }
7410 10 Nov 23 nicklas 530           else if (key.endsWith(".callable"))
7410 10 Nov 23 nicklas 531           {
7410 10 Nov 23 nicklas 532             metrics.numCallable += val;
7410 10 Nov 23 nicklas 533           }
7410 10 Nov 23 nicklas 534           else if ("Filtered variants".equals(key))
7410 10 Nov 23 nicklas 535           {
7410 10 Nov 23 nicklas 536             metrics.filteredVariants = val;
7410 10 Nov 23 nicklas 537           }
7410 10 Nov 23 nicklas 538         }
7410 10 Nov 23 nicklas 539         
7410 10 Nov 23 nicklas 540         dc = sc.newDbControl("Reggie: WGS variant calling completed handler");
7410 10 Nov 23 nicklas 541         Rawbioassay vcall = Rawbioassay.getByJob(dc, job);
7410 10 Nov 23 nicklas 542         RawBioAssay raw = vcall.getItem();
7410 10 Nov 23 nicklas 543         
7410 10 Nov 23 nicklas 544         Annotationtype.VARIANTS_RAW.setAnnotationValue(dc, raw, metrics.numVariants);
7410 10 Nov 23 nicklas 545         Annotationtype.VARIANTS_PASSED_FILTER.setAnnotationValue(dc, raw, metrics.filteredVariants);
7410 10 Nov 23 nicklas 546         Annotationtype.CALLABLE_BASES.setAnnotationValue(dc, raw, metrics.numCallable);
7410 10 Nov 23 nicklas 547         
7410 10 Nov 23 nicklas 548         // Create file links
7410 10 Nov 23 nicklas 549         FileServer fileArchive = Fileserver.PROJECT_ARCHIVE_DNA.load(dc);
7410 10 Nov 23 nicklas 550         String analysisDir = Reggie.SECONDARY_ANALYSIS_DIR;
7410 10 Nov 23 nicklas 551
7410 10 Nov 23 nicklas 552         String dataFilesFolder = (String)Annotationtype.DATA_FILES_FOLDER.getAnnotationValue(dc, raw);
7410 10 Nov 23 nicklas 553         String baseFolder = Reggie.convertDataFilesFolderToBaseFolder(dataFilesFolder);
7410 10 Nov 23 nicklas 554         Directory localDataDir = Directory.getNew(dc, new Path(analysisDir+baseFolder, Path.Type.DIRECTORY));
7410 10 Nov 23 nicklas 555   
7410 10 Nov 23 nicklas 556         ItemSubtype vcfType = Subtype.VARIANT_CALL_FORMAT.load(dc);
7410 10 Nov 23 nicklas 557         DataFileType vcfData = Datafiletype.VCF.load(dc);
7410 10 Nov 23 nicklas 558
7410 10 Nov 23 nicklas 559         for (String line : filesOut.split("\n"))
7410 10 Nov 23 nicklas 560         {
7416 13 Nov 23 nicklas 561           String filename = line.substring(line.lastIndexOf("/")+1);
7410 10 Nov 23 nicklas 562           
7416 13 Nov 23 nicklas 563           File f = File.getFile(dc, localDataDir, filename, true);
7410 10 Nov 23 nicklas 564           f.setFileServer(fileArchive);
7410 10 Nov 23 nicklas 565           String fileUrl = "sftp://" + fileArchive.getHost() + dataFilesFolder + "/" + f.getName();
7410 10 Nov 23 nicklas 566           try
7410 10 Nov 23 nicklas 567           {
7410 10 Nov 23 nicklas 568             f.setUrl(fileUrl, true);
7410 10 Nov 23 nicklas 569           }
7410 10 Nov 23 nicklas 570           catch (RuntimeException ex)
7410 10 Nov 23 nicklas 571           {
7410 10 Nov 23 nicklas 572             f.setUrl(fileUrl, false);
7410 10 Nov 23 nicklas 573           }
7416 13 Nov 23 nicklas 574           if (filename.endsWith(".table")) f.setMimeType("text/plain");
7416 13 Nov 23 nicklas 575           if (filename.endsWith(".vcf.gz")) f.setMimeTypeAuto("application/x-gzip", vcfType);
7416 13 Nov 23 nicklas 576           if (filename.endsWith(".vcf")) f.setMimeTypeAuto("text/plain", vcfType);
7410 10 Nov 23 nicklas 577           
7410 10 Nov 23 nicklas 578           if (!f.isInDatabase())
7410 10 Nov 23 nicklas 579           {
7410 10 Nov 23 nicklas 580             dc.saveItem(f);
7410 10 Nov 23 nicklas 581           }
7410 10 Nov 23 nicklas 582           
7416 13 Nov 23 nicklas 583           if (filename.equals("variants-somatic.vcf.gz"))
7410 10 Nov 23 nicklas 584           {
7410 10 Nov 23 nicklas 585             f.setDescription(metrics.filteredVariants + " variants passed filter");
7410 10 Nov 23 nicklas 586             f.setItemSubtype(vcfType);
7410 10 Nov 23 nicklas 587             FileSetMember member = raw.getFileSet().addMember(f, vcfData);
7410 10 Nov 23 nicklas 588           }
7410 10 Nov 23 nicklas 589           else
7410 10 Nov 23 nicklas 590           {
7416 13 Nov 23 nicklas 591             AnyToAny link = AnyToAny.getNewOrExisting(dc, raw, filename, f, true);
7410 10 Nov 23 nicklas 592             if (!link.isInDatabase()) dc.saveItem(link);
7416 13 Nov 23 nicklas 593             if (filename.equals("variants-raw.vcf.gz"))
7416 13 Nov 23 nicklas 594             {
7416 13 Nov 23 nicklas 595               f.setDescription(metrics.numVariants + " variants.");
7416 13 Nov 23 nicklas 596             }
7410 10 Nov 23 nicklas 597           }
7410 10 Nov 23 nicklas 598         }
7410 10 Nov 23 nicklas 599         dc.commit();
7410 10 Nov 23 nicklas 600       }
7410 10 Nov 23 nicklas 601       finally
7410 10 Nov 23 nicklas 602       {
7410 10 Nov 23 nicklas 603         if (dc != null) dc.close();
7410 10 Nov 23 nicklas 604       }
7410 10 Nov 23 nicklas 605       return metrics;
7410 10 Nov 23 nicklas 606     }
7410 10 Nov 23 nicklas 607   }
7410 10 Nov 23 nicklas 608
7410 10 Nov 23 nicklas 609   
7410 10 Nov 23 nicklas 610   /**
7388 31 Oct 23 nicklas 611     Job completion handler for Panel-of-normal variant call jobs.
7388 31 Oct 23 nicklas 612   */
7388 31 Oct 23 nicklas 613   public static class PanelOfNormalVariantCallJobCompletionHandler
7388 31 Oct 23 nicklas 614     implements JobCompletionHandler
7388 31 Oct 23 nicklas 615   {
7388 31 Oct 23 nicklas 616     
7388 31 Oct 23 nicklas 617     public PanelOfNormalVariantCallJobCompletionHandler()
7388 31 Oct 23 nicklas 618     {}
7388 31 Oct 23 nicklas 619   
7388 31 Oct 23 nicklas 620     @Override
7388 31 Oct 23 nicklas 621     public String jobCompleted(SessionControl sc, OpenGridSession session, Job job, JobStatus status)
7388 31 Oct 23 nicklas 622     {
7389 01 Nov 23 nicklas 623       String jobName = status.getName();
7389 01 Nov 23 nicklas 624       String stats = session.getJobFileAsString(jobName, "stats.out", "UTF-8");
7389 01 Nov 23 nicklas 625       Metrics metrics = parseFiles(sc, job, stats);
7390 02 Nov 23 nicklas 626       String msg = "Variant calling completed. Found ";
7390 02 Nov 23 nicklas 627       msg += Reggie.formatCount(metrics.numVariants, 1) + " variants; ";
7390 02 Nov 23 nicklas 628       msg += Reggie.formatCount(metrics.numCallable, 2) + " callable bases.";
7390 02 Nov 23 nicklas 629       return msg;
7388 31 Oct 23 nicklas 630     }
7389 01 Nov 23 nicklas 631     
7389 01 Nov 23 nicklas 632     private Metrics parseFiles(SessionControl sc, Job job, String statsOut)
7389 01 Nov 23 nicklas 633     {
7389 01 Nov 23 nicklas 634       DbControl dc = null;
7389 01 Nov 23 nicklas 635       Metrics metrics = new Metrics();
7389 01 Nov 23 nicklas 636       try
7389 01 Nov 23 nicklas 637       {
7389 01 Nov 23 nicklas 638         dc = sc.newDbControl("Reggie: Panel-of-normals variant calling completed handler");
7389 01 Nov 23 nicklas 639         
7389 01 Nov 23 nicklas 640         // Summarize number of variants 
7389 01 Nov 23 nicklas 641         for (String line : statsOut.split("\n"))
7389 01 Nov 23 nicklas 642         {
7389 01 Nov 23 nicklas 643           String[] stat = line.split(":", 2);
7390 02 Nov 23 nicklas 644           String key = stat[0].strip();
7390 02 Nov 23 nicklas 645           int val = Values.getInt(stat[1].strip());
7390 02 Nov 23 nicklas 646           if (key.endsWith(".variants"))
7390 02 Nov 23 nicklas 647           {
7390 02 Nov 23 nicklas 648             metrics.numVariants += val;
7390 02 Nov 23 nicklas 649           }
7390 02 Nov 23 nicklas 650           else if (key.endsWith(".callable"))
7390 02 Nov 23 nicklas 651           {
7390 02 Nov 23 nicklas 652             metrics.numCallable += val;
7390 02 Nov 23 nicklas 653           }
7389 01 Nov 23 nicklas 654         }
7389 01 Nov 23 nicklas 655         PanelOfNormal pon = PanelOfNormal.getByJob(dc, job);
7389 01 Nov 23 nicklas 656         Annotationtype.VARIANTS_RAW.setAnnotationValue(dc, pon.getItem(), metrics.numVariants);
7397 06 Nov 23 nicklas 657         Annotationtype.CALLABLE_BASES.setAnnotationValue(dc, pon.getItem(), metrics.numCallable);
7389 01 Nov 23 nicklas 658         dc.commit();
7389 01 Nov 23 nicklas 659       }
7389 01 Nov 23 nicklas 660       finally
7389 01 Nov 23 nicklas 661       {
7389 01 Nov 23 nicklas 662         if (dc != null) dc.close();
7389 01 Nov 23 nicklas 663       }
7395 06 Nov 23 nicklas 664       return metrics;
7395 06 Nov 23 nicklas 665     }
7395 06 Nov 23 nicklas 666   }
7389 01 Nov 23 nicklas 667   
7395 06 Nov 23 nicklas 668   /**
7395 06 Nov 23 nicklas 669     Job completion handler for building panel-of-normal.
7395 06 Nov 23 nicklas 670   */
7395 06 Nov 23 nicklas 671   public static class BuildPanelOfNormalsJobCompletionHandler
7395 06 Nov 23 nicklas 672     implements JobCompletionHandler
7395 06 Nov 23 nicklas 673   {
7395 06 Nov 23 nicklas 674     public BuildPanelOfNormalsJobCompletionHandler()
7395 06 Nov 23 nicklas 675     {}
7395 06 Nov 23 nicklas 676
7395 06 Nov 23 nicklas 677     @Override
7395 06 Nov 23 nicklas 678     public String jobCompleted(SessionControl sc, OpenGridSession session, Job job, JobStatus status) 
7395 06 Nov 23 nicklas 679     {
7395 06 Nov 23 nicklas 680       String jobName = status.getName();
7395 06 Nov 23 nicklas 681       String stats = session.getJobFileAsString(jobName, "stats.out", "UTF-8");
7395 06 Nov 23 nicklas 682       Metrics metrics = parseFiles(sc, job, stats);
7395 06 Nov 23 nicklas 683       String msg = "Panel-or-normals built with ";
7395 06 Nov 23 nicklas 684       msg += Reggie.formatCount(metrics.numVariants, 1) + " variants.";
7395 06 Nov 23 nicklas 685       msg += " Result files can be found at: " + session.getHost().getWorkFolder(jobName);
7395 06 Nov 23 nicklas 686       return msg;
7395 06 Nov 23 nicklas 687     }
7395 06 Nov 23 nicklas 688     
7395 06 Nov 23 nicklas 689     private Metrics parseFiles(SessionControl sc, Job job, String statsOut)
7395 06 Nov 23 nicklas 690     {
7395 06 Nov 23 nicklas 691       Metrics metrics = new Metrics();
7395 06 Nov 23 nicklas 692         
7395 06 Nov 23 nicklas 693       // Summarize number of variants 
7395 06 Nov 23 nicklas 694       for (String line : statsOut.split("\n"))
7395 06 Nov 23 nicklas 695       {
7395 06 Nov 23 nicklas 696         String[] stat = line.split(":", 2);
7395 06 Nov 23 nicklas 697         String key = stat[0].strip();
7395 06 Nov 23 nicklas 698         int val = Values.getInt(stat[1].strip());
7395 06 Nov 23 nicklas 699         if (key.endsWith(".variants"))
7395 06 Nov 23 nicklas 700         {
7395 06 Nov 23 nicklas 701           metrics.numVariants += val;
7395 06 Nov 23 nicklas 702         }
7395 06 Nov 23 nicklas 703       }
7389 01 Nov 23 nicklas 704       return metrics;
7389 01 Nov 23 nicklas 705     }
7388 31 Oct 23 nicklas 706   }
7389 01 Nov 23 nicklas 707   
7389 01 Nov 23 nicklas 708   static class Metrics
7389 01 Nov 23 nicklas 709   {
7389 01 Nov 23 nicklas 710     int numVariants = 0;
7410 10 Nov 23 nicklas 711     int filteredVariants = 0;
7390 02 Nov 23 nicklas 712     long numCallable = 0;
7389 01 Nov 23 nicklas 713   }
7388 31 Oct 23 nicklas 714
7388 31 Oct 23 nicklas 715 }