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

Code
Comments
Other
Rev Date Author Line
7268 22 Jun 23 nicklas 1 package net.sf.basedb.reggie.grid;
7268 22 Jun 23 nicklas 2
7268 22 Jun 23 nicklas 3 import java.util.ArrayList;
7268 22 Jun 23 nicklas 4 import java.util.List;
7268 22 Jun 23 nicklas 5
7268 22 Jun 23 nicklas 6 import org.slf4j.LoggerFactory;
7268 22 Jun 23 nicklas 7
7287 15 Aug 23 nicklas 8 import net.sf.basedb.core.AnyToAny;
7279 11 Aug 23 nicklas 9 import net.sf.basedb.core.BioSource;
7287 15 Aug 23 nicklas 10 import net.sf.basedb.core.DataFileType;
7268 22 Jun 23 nicklas 11 import net.sf.basedb.core.DbControl;
7268 22 Jun 23 nicklas 12 import net.sf.basedb.core.DerivedBioAssay;
7287 15 Aug 23 nicklas 13 import net.sf.basedb.core.Directory;
7268 22 Jun 23 nicklas 14 import net.sf.basedb.core.File;
7287 15 Aug 23 nicklas 15 import net.sf.basedb.core.FileServer;
7268 22 Jun 23 nicklas 16 import net.sf.basedb.core.ItemList;
7268 22 Jun 23 nicklas 17 import net.sf.basedb.core.ItemNotFoundException;
7268 22 Jun 23 nicklas 18 import net.sf.basedb.core.ItemSubtype;
7268 22 Jun 23 nicklas 19 import net.sf.basedb.core.Job;
7287 15 Aug 23 nicklas 20 import net.sf.basedb.core.Path;
7270 28 Jun 23 nicklas 21 import net.sf.basedb.core.Sample;
7268 22 Jun 23 nicklas 22 import net.sf.basedb.core.SessionControl;
7268 22 Jun 23 nicklas 23 import net.sf.basedb.core.Software;
7268 22 Jun 23 nicklas 24 import net.sf.basedb.core.StringParameterType;
7268 22 Jun 23 nicklas 25 import net.sf.basedb.opengrid.JobDefinition;
7268 22 Jun 23 nicklas 26 import net.sf.basedb.opengrid.JobStatus;
7268 22 Jun 23 nicklas 27 import net.sf.basedb.opengrid.OpenGridCluster;
7268 22 Jun 23 nicklas 28 import net.sf.basedb.opengrid.OpenGridSession;
7268 22 Jun 23 nicklas 29 import net.sf.basedb.opengrid.ScriptBuilder;
7268 22 Jun 23 nicklas 30 import net.sf.basedb.opengrid.config.ClusterConfig;
7268 22 Jun 23 nicklas 31 import net.sf.basedb.opengrid.config.JobConfig;
7268 22 Jun 23 nicklas 32 import net.sf.basedb.opengrid.service.JobCompletionHandler;
7268 22 Jun 23 nicklas 33 import net.sf.basedb.reggie.Reggie;
7268 22 Jun 23 nicklas 34 import net.sf.basedb.reggie.XmlConfig;
7268 22 Jun 23 nicklas 35 import net.sf.basedb.reggie.dao.Annotationtype;
7268 22 Jun 23 nicklas 36 import net.sf.basedb.reggie.dao.BiomaterialList;
7287 15 Aug 23 nicklas 37 import net.sf.basedb.reggie.dao.CopyNumber;
7268 22 Jun 23 nicklas 38 import net.sf.basedb.reggie.dao.Datafiletype;
7268 22 Jun 23 nicklas 39 import net.sf.basedb.reggie.dao.DoNotUse;
7287 15 Aug 23 nicklas 40 import net.sf.basedb.reggie.dao.Fileserver;
7279 11 Aug 23 nicklas 41 import net.sf.basedb.reggie.dao.Patient;
7269 26 Jun 23 nicklas 42 import net.sf.basedb.reggie.dao.Pipeline;
7268 22 Jun 23 nicklas 43 import net.sf.basedb.reggie.dao.Subtype;
7406 08 Nov 23 nicklas 44 import net.sf.basedb.reggie.dao.TumorNormalPair;
7268 22 Jun 23 nicklas 45 import net.sf.basedb.util.Values;
7268 22 Jun 23 nicklas 46 import net.sf.basedb.util.extensions.logging.ExtensionsLog;
7268 22 Jun 23 nicklas 47 import net.sf.basedb.util.extensions.logging.ExtensionsLogger;
7268 22 Jun 23 nicklas 48
7268 22 Jun 23 nicklas 49 /**
7268 22 Jun 23 nicklas 50   Helper class for creating items needed for generating ASCAT analysis 
7268 22 Jun 23 nicklas 51   script and send it to the cluster for execution.
7268 22 Jun 23 nicklas 52   
7268 22 Jun 23 nicklas 53   @author nicklas
7268 22 Jun 23 nicklas 54   @since 4.49
7268 22 Jun 23 nicklas 55 */
7268 22 Jun 23 nicklas 56 public class AscatJobCreator 
7268 22 Jun 23 nicklas 57   extends AbstractJobCreator
7268 22 Jun 23 nicklas 58 {
7268 22 Jun 23 nicklas 59   private Software software;
7268 22 Jun 23 nicklas 60   
7341 11 Sep 23 nicklas 61   private AllelicImbalanceTest imbalaceTest;
7341 11 Sep 23 nicklas 62   private Integer penalty;
7341 11 Sep 23 nicklas 63   private Integer minDepth;
7279 11 Aug 23 nicklas 64   private Float tau;
7279 11 Aug 23 nicklas 65   private Float rho;
7279 11 Aug 23 nicklas 66   private Float psi;  
7279 11 Aug 23 nicklas 67   
7268 22 Jun 23 nicklas 68   public AscatJobCreator()
7268 22 Jun 23 nicklas 69   {}
7268 22 Jun 23 nicklas 70
7268 22 Jun 23 nicklas 71   /**
7268 22 Jun 23 nicklas 72     Set the software item to set on created dervied bioassays.
7268 22 Jun 23 nicklas 73   */
7268 22 Jun 23 nicklas 74   public void setSoftware(Software software)
7268 22 Jun 23 nicklas 75   {
7268 22 Jun 23 nicklas 76     this.software = software;
7268 22 Jun 23 nicklas 77   }
7268 22 Jun 23 nicklas 78
7268 22 Jun 23 nicklas 79   /**
7341 11 Sep 23 nicklas 80     Set the test that should be used for allelic imbalance.
7279 11 Aug 23 nicklas 81   */
7341 11 Sep 23 nicklas 82   public void setAllelicImbalanceTest(AllelicImbalanceTest imbalaceTest)
7279 11 Aug 23 nicklas 83   {
7341 11 Sep 23 nicklas 84     this.imbalaceTest = imbalaceTest;
7279 11 Aug 23 nicklas 85   }
7279 11 Aug 23 nicklas 86   
7279 11 Aug 23 nicklas 87   /**
7279 11 Aug 23 nicklas 88     Set a value for the 'tau' parameter that is used in the allelic imbalance test.
7279 11 Aug 23 nicklas 89   */
7279 11 Aug 23 nicklas 90   public void setTau(Float tau)
7279 11 Aug 23 nicklas 91   {
7279 11 Aug 23 nicklas 92     this.tau = tau;
7279 11 Aug 23 nicklas 93   }
7279 11 Aug 23 nicklas 94   /**
7279 11 Aug 23 nicklas 95     Set a manual value for the 'rho' parameter used in the ASCAT optimization
7279 11 Aug 23 nicklas 96    */
7279 11 Aug 23 nicklas 97   public void setRho(Float rho)
7279 11 Aug 23 nicklas 98   {
7279 11 Aug 23 nicklas 99     this.rho = rho;
7279 11 Aug 23 nicklas 100   }
7279 11 Aug 23 nicklas 101   /**
7279 11 Aug 23 nicklas 102     Set a manual value for the 'psi' parameter used in the ASCAT optimization
7279 11 Aug 23 nicklas 103    */
7279 11 Aug 23 nicklas 104   public void setPsi(Float psi)
7279 11 Aug 23 nicklas 105   {
7279 11 Aug 23 nicklas 106     this.psi = psi;
7279 11 Aug 23 nicklas 107   }
7279 11 Aug 23 nicklas 108   
7279 11 Aug 23 nicklas 109   /**
7341 11 Sep 23 nicklas 110     Set a manual value for the 'penalty' parameter used in the ASCAT segmentation
7341 11 Sep 23 nicklas 111     @since 4.49.1
7341 11 Sep 23 nicklas 112   */
7341 11 Sep 23 nicklas 113   public void setPenalty(Integer penalty)
7341 11 Sep 23 nicklas 114   {
7341 11 Sep 23 nicklas 115     this.penalty = penalty;
7341 11 Sep 23 nicklas 116   }
7341 11 Sep 23 nicklas 117
7341 11 Sep 23 nicklas 118   /**
7341 11 Sep 23 nicklas 119     Set a manual value for the 'minCounts' parameter used by allelecounter.
7341 11 Sep 23 nicklas 120     @since 4.49.1
7341 11 Sep 23 nicklas 121   */
7341 11 Sep 23 nicklas 122   public void setMinDepth(Integer minDepth)
7341 11 Sep 23 nicklas 123   {
7341 11 Sep 23 nicklas 124     this.minDepth = minDepth;
7341 11 Sep 23 nicklas 125   }
7341 11 Sep 23 nicklas 126
7341 11 Sep 23 nicklas 127   
7341 11 Sep 23 nicklas 128   /**
7268 22 Jun 23 nicklas 129     Schedule jobs on the given cluster for running ASCAT analysis.
7268 22 Jun 23 nicklas 130     @return A list with the corresponding jobs in BASE
7268 22 Jun 23 nicklas 131   */
7268 22 Jun 23 nicklas 132   public List<JobDefinition> createAscatJobs(DbControl dc, OpenGridCluster cluster, List<TumorNormalPair> alignedSequences)
7268 22 Jun 23 nicklas 133   {
7268 22 Jun 23 nicklas 134     SessionControl sc = dc.getSessionControl();
7268 22 Jun 23 nicklas 135     
7268 22 Jun 23 nicklas 136     ClusterConfig clusterCfg = cluster.getConfig();
7268 22 Jun 23 nicklas 137     XmlConfig cfg = Reggie.getConfig(cluster.getId());
7268 22 Jun 23 nicklas 138     if (cfg == null)
7268 22 Jun 23 nicklas 139     {
7268 22 Jun 23 nicklas 140       throw new ItemNotFoundException("No configuration in reggie-config.xml for cluster: " + cluster.getId());
7268 22 Jun 23 nicklas 141     }
7268 22 Jun 23 nicklas 142     String parameterSet = (String)Annotationtype.PARAMETER_SET.getAnnotationValue(dc, software);
7268 22 Jun 23 nicklas 143
7268 22 Jun 23 nicklas 144     // Get global options
7268 22 Jun 23 nicklas 145     String global_env = ScriptUtil.multilineIndent(cfg.getConfig("global-env"));
7268 22 Jun 23 nicklas 146     String projectArchiveDNA = cfg.getRequiredConfig("project-archive-dna", null);
7268 22 Jun 23 nicklas 147
7372 06 Oct 23 nicklas 148     // ASCAT
7372 06 Oct 23 nicklas 149     String ascat_submit = cfg.getConfig("ascat/submit", parameterSet, null);
7372 06 Oct 23 nicklas 150     String ascat_submit_debug = cfg.getConfig("ascat/submit-debug", parameterSet, null);
7268 22 Jun 23 nicklas 151     String ascat_env = ScriptUtil.multilineIndent(cfg.getRequiredConfig("ascat/env", parameterSet));
7268 22 Jun 23 nicklas 152     String ascat_envdebug = ScriptUtil.multilineIndent(cfg.getConfig("ascat/env-debug", parameterSet, null));
7268 22 Jun 23 nicklas 153     String ascat_execute = ScriptUtil.multilineIndent(cfg.getConfig("ascat/execute", parameterSet, "./ascat.sh"));
7372 06 Oct 23 nicklas 154     
7268 22 Jun 23 nicklas 155     // Load common items
7268 22 Jun 23 nicklas 156     ItemSubtype ascatType = Subtype.COPY_NUMBER.get(dc);
7268 22 Jun 23 nicklas 157     ItemSubtype ascatJobType = Subtype.ASCAT_JOB.get(dc);
7268 22 Jun 23 nicklas 158
7268 22 Jun 23 nicklas 159     // Selected items must be removed from this list
7268 22 Jun 23 nicklas 160     ItemList ascatPipeline = BiomaterialList.ASCAT_PIPELINE.load(dc);
7268 22 Jun 23 nicklas 161
7268 22 Jun 23 nicklas 162     // Options common for all jobs
7268 22 Jun 23 nicklas 163     JobConfig jobConfig = new JobConfig();
7268 22 Jun 23 nicklas 164     if (priority != null) jobConfig.setPriority(priority);
7372 06 Oct 23 nicklas 165     if (partition != null) jobConfig.setSbatchOption("partition", ScriptUtil.checkValidScriptParameter(partition));
7372 06 Oct 23 nicklas 166     jobConfig.convertOptionsTo(clusterCfg.getType());
7372 06 Oct 23 nicklas 167     if (submitOptionsOverride != null)
7372 06 Oct 23 nicklas 168     {
7372 06 Oct 23 nicklas 169       ScriptUtil.addSubmitOptions(jobConfig, submitOptionsOverride, clusterCfg.getType());
7372 06 Oct 23 nicklas 170     }
7372 06 Oct 23 nicklas 171     else
7372 06 Oct 23 nicklas 172     {
7372 06 Oct 23 nicklas 173       ScriptUtil.addSubmitOptions(jobConfig, ascat_submit, clusterCfg.getType());
7372 06 Oct 23 nicklas 174       if (debug) ScriptUtil.addSubmitOptions(jobConfig, ascat_submit_debug, clusterCfg.getType());
7372 06 Oct 23 nicklas 175     }
7268 22 Jun 23 nicklas 176     
7268 22 Jun 23 nicklas 177     // We submit one job for each raw bioassay to the cluster
7268 22 Jun 23 nicklas 178     List<JobDefinition> jobDefs = new ArrayList<JobDefinition>(alignedSequences.size());
7268 22 Jun 23 nicklas 179
7268 22 Jun 23 nicklas 180     for (TumorNormalPair pair : alignedSequences)
7268 22 Jun 23 nicklas 181     {
7268 22 Jun 23 nicklas 182       // Ensure items are loaded in this transaction
7268 22 Jun 23 nicklas 183       pair = pair.reload(dc);
7268 22 Jun 23 nicklas 184
7268 22 Jun 23 nicklas 185       // Get some information about the aligned data that we need
7268 22 Jun 23 nicklas 186       DerivedBioAssay tumor = pair.tumor.getDerivedBioAssay();
7268 22 Jun 23 nicklas 187       DerivedBioAssay normal = pair.normal.getDerivedBioAssay();
7268 22 Jun 23 nicklas 188       ascatPipeline.removeItem(tumor);
7268 22 Jun 23 nicklas 189       
7268 22 Jun 23 nicklas 190       String tumorFolder = (String)Annotationtype.DATA_FILES_FOLDER.getAnnotationValue(dc, tumor);
7268 22 Jun 23 nicklas 191       File tumorBam = Datafiletype.BAM.getFile(dc, tumor);
7268 22 Jun 23 nicklas 192       String normalFolder = (String)Annotationtype.DATA_FILES_FOLDER.getAnnotationValue(dc, normal);
7268 22 Jun 23 nicklas 193       File normalBam = Datafiletype.BAM.getFile(dc, normal);
7269 26 Jun 23 nicklas 194       Pipeline pipeline = Pipeline.getByName((String)Annotationtype.PIPELINE.getAnnotationValue(dc, tumor));
7268 22 Jun 23 nicklas 195       
7268 22 Jun 23 nicklas 196       // Create job 
7268 22 Jun 23 nicklas 197       Job ascatJob = Job.getNew(dc, null, null, null);
7268 22 Jun 23 nicklas 198       ascatJob.setItemSubtype(ascatJobType);
7268 22 Jun 23 nicklas 199       ascatJob.setPluginVersion("reggie-"+Reggie.VERSION);
7268 22 Jun 23 nicklas 200       ascatJob.setSendMessage(Values.getBoolean(sc.getUserClientSetting("plugins.sendmessage"), false));
7268 22 Jun 23 nicklas 201       ascatJob.setName("Run ASCAT analysis: " + tumor.getName()+"/"+normal.getName());
7268 22 Jun 23 nicklas 202       if (debug) ascatJob.setName(ascatJob.getName() + " (debug)");
7268 22 Jun 23 nicklas 203       if (partition != null) ascatJob.setParameterValue("partition", new StringParameterType(), partition);
7372 06 Oct 23 nicklas 204       if (submitOptionsOverride != null) ascatJob.setParameterValue("jobOptions", new StringParameterType(), submitOptionsOverride);
7268 22 Jun 23 nicklas 205       dc.saveItem(ascatJob);
7268 22 Jun 23 nicklas 206       
7268 22 Jun 23 nicklas 207       // Create ASCAT derived bioassay
7268 22 Jun 23 nicklas 208       String ascatName = ScriptUtil.checkValidScriptParameter(pair.tumor.getNextDerivedBioAssayName(dc, Subtype.COPY_NUMBER));
7268 22 Jun 23 nicklas 209       DerivedBioAssay ascat = DerivedBioAssay.getNew(dc, tumor, ascatJob);
7268 22 Jun 23 nicklas 210       ascat.addParent(normal);
7268 22 Jun 23 nicklas 211       ascat.setItemSubtype(ascatType);
7269 26 Jun 23 nicklas 212       pipeline.setAnnotation(dc, ascat);
7268 22 Jun 23 nicklas 213       ascat.setName(ascatName);
7268 22 Jun 23 nicklas 214       ascat.setExtract(tumor.getExtract());
7268 22 Jun 23 nicklas 215       ascat.setSoftware(software);
7268 22 Jun 23 nicklas 216       ascat.setProtocol(null);
7268 22 Jun 23 nicklas 217       DoNotUse.copyDoNotUseAnnotations(dc, tumor, ascat, false);
7268 22 Jun 23 nicklas 218       dc.saveItem(ascat);
7268 22 Jun 23 nicklas 219
7270 28 Jun 23 nicklas 220       Sample specimen =  (Sample)pair.tumor.findSingleParent(dc, Subtype.SPECIMEN);
7270 28 Jun 23 nicklas 221       String externalTumorName = tumor.getName();
7270 28 Jun 23 nicklas 222       if (specimen != null && specimen.getExternalId() != null)
7270 28 Jun 23 nicklas 223       {
7270 28 Jun 23 nicklas 224         // Replace SCANB-ID with Sample.externalId
7270 28 Jun 23 nicklas 225         externalTumorName = externalTumorName.replace(specimen.getName(), specimen.getExternalId());
7270 28 Jun 23 nicklas 226       }
7270 28 Jun 23 nicklas 227       Sample blood =  (Sample)pair.normal.findSingleParent(dc, Subtype.BLOOD);
7270 28 Jun 23 nicklas 228       String externalNormalName = normal.getName();
7270 28 Jun 23 nicklas 229       if (blood != null && blood.getExternalId() != null)
7270 28 Jun 23 nicklas 230       {
7270 28 Jun 23 nicklas 231         // Replace SCANB-ID with Sample.externalId
7270 28 Jun 23 nicklas 232         externalNormalName = externalNormalName.replace(blood.getName(), blood.getExternalId());
7270 28 Jun 23 nicklas 233       }
7270 28 Jun 23 nicklas 234       
7268 22 Jun 23 nicklas 235       String ascatFolder = tumorFolder + "/"+ascat.getName().substring(tumor.getName().length()+1);
7268 22 Jun 23 nicklas 236       if (debug && !ascatFolder.startsWith("/debug"))
7268 22 Jun 23 nicklas 237       {
7268 22 Jun 23 nicklas 238         ascatFolder = "/debug" + ascatFolder;
7268 22 Jun 23 nicklas 239       }
7268 22 Jun 23 nicklas 240       Annotationtype.DATA_FILES_FOLDER.setAnnotationValue(dc, ascat, ascatFolder);
7290 18 Aug 23 nicklas 241       /*
7268 22 Jun 23 nicklas 242       if (autoConfirm)
7268 22 Jun 23 nicklas 243       {
7268 22 Jun 23 nicklas 244         Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, ascat, "AutoConfirm");
7268 22 Jun 23 nicklas 245       }
7290 18 Aug 23 nicklas 246       */
7287 15 Aug 23 nicklas 247       // Record manual parameters as annotations
7287 15 Aug 23 nicklas 248       if (tau != null) Annotationtype.TAU_MANUAL.setAnnotationValue(dc, ascat, tau);
7287 15 Aug 23 nicklas 249       if (rho != null) Annotationtype.RHO_MANUAL.setAnnotationValue(dc, ascat, rho);
7287 15 Aug 23 nicklas 250       if (psi != null) Annotationtype.PSI_MANUAL.setAnnotationValue(dc, ascat, psi);
7341 11 Sep 23 nicklas 251       if (penalty != null) Annotationtype.PENALTY.setAnnotationValue(dc, ascat, penalty);
7341 11 Sep 23 nicklas 252       if (minDepth != null) Annotationtype.MIN_DEPTH.setAnnotationValue(dc, ascat, minDepth);
7341 11 Sep 23 nicklas 253       if (imbalaceTest != null) Annotationtype.IMBALANCE_TEST.setAnnotationValue(dc, ascat, imbalaceTest.getTitle());
7268 22 Jun 23 nicklas 254       
7268 22 Jun 23 nicklas 255       // Checks to make sure no bad things are included in script file
7268 22 Jun 23 nicklas 256       ScriptUtil.checkValidPath(ascatFolder, true, true);
7268 22 Jun 23 nicklas 257       ScriptUtil.checkValidScriptParameter(tumorBam.getName());
7268 22 Jun 23 nicklas 258       ScriptUtil.checkValidScriptParameter(normalBam.getName());
7268 22 Jun 23 nicklas 259
7268 22 Jun 23 nicklas 260       ScriptBuilder script = new ScriptBuilder();
7268 22 Jun 23 nicklas 261       script.cmd(debug ? "set -ex" : "set -e");
7268 22 Jun 23 nicklas 262       // Set file permissions based on consent or external group!
7268 22 Jun 23 nicklas 263       ScriptUtil.setUmaskForItem(dc, pair.tumor, null, script);
7268 22 Jun 23 nicklas 264       script.newLine();
7268 22 Jun 23 nicklas 265       script.cmd(global_env);
7268 22 Jun 23 nicklas 266       script.export("ArchiveFolder", projectArchiveDNA);
7270 28 Jun 23 nicklas 267       script.export("TumorName", ScriptUtil.checkValidScriptParameter(externalTumorName));
7268 22 Jun 23 nicklas 268       script.export("TumorFolder", "${ArchiveFolder}"+tumorFolder);
7270 28 Jun 23 nicklas 269       script.export("TumorBam", tumorBam.getName().replace(".bam", ""));
7270 28 Jun 23 nicklas 270       script.export("NormalName", ScriptUtil.checkValidScriptParameter(externalNormalName));
7268 22 Jun 23 nicklas 271       script.export("NormalFolder", "${ArchiveFolder}"+normalFolder);
7270 28 Jun 23 nicklas 272       script.export("NormalBam", normalBam.getName().replace(".bam", ""));
7270 28 Jun 23 nicklas 273       script.export("AscatFolder", "${ArchiveFolder}"+ascatFolder);
7270 28 Jun 23 nicklas 274       
7278 10 Aug 23 nicklas 275       String gender = "XX";
7279 11 Aug 23 nicklas 276       Patient patient = Patient.get((BioSource)pair.tumor.findSingleParent(dc, Subtype.PATIENT));
7279 11 Aug 23 nicklas 277       if (patient != null)
7279 11 Aug 23 nicklas 278       {
7279 11 Aug 23 nicklas 279         if ("M".equals(Annotationtype.GENDER.getAnnotationValue(dc, patient.getItem()))) 
7279 11 Aug 23 nicklas 280         {
7279 11 Aug 23 nicklas 281           gender = "XY";
7279 11 Aug 23 nicklas 282         }
7279 11 Aug 23 nicklas 283       }
7279 11 Aug 23 nicklas 284       
7278 10 Aug 23 nicklas 285       String ascatParameters = "";
7278 10 Aug 23 nicklas 286       String alleleCounterParameters = "";
7278 10 Aug 23 nicklas 287       if (gender != null) 
7278 10 Aug 23 nicklas 288       {
7278 10 Aug 23 nicklas 289         ascatParameters += " --gender "+gender;
7278 10 Aug 23 nicklas 290         alleleCounterParameters += " --gender "+gender;
7278 10 Aug 23 nicklas 291       }
7341 11 Sep 23 nicklas 292       if (minDepth != null) alleleCounterParameters += " --minCounts "+minDepth;
7341 11 Sep 23 nicklas 293       
7341 11 Sep 23 nicklas 294       if (imbalaceTest != null) ascatParameters += " --imbalanceTest "+imbalaceTest.name().toLowerCase();
7279 11 Aug 23 nicklas 295       if (tau != null) ascatParameters += " --tau "+tau;
7279 11 Aug 23 nicklas 296       if (rho != null) ascatParameters += " --rho "+rho;
7279 11 Aug 23 nicklas 297       if (psi != null) ascatParameters += " --psi "+psi;
7341 11 Sep 23 nicklas 298       if (penalty != null) ascatParameters += " --penalty "+penalty;
7278 10 Aug 23 nicklas 299       
7278 10 Aug 23 nicklas 300       script.export("AlleleCounterParameters", alleleCounterParameters);
7278 10 Aug 23 nicklas 301       script.export("AscatParameters", ascatParameters);
7278 10 Aug 23 nicklas 302       
7268 22 Jun 23 nicklas 303       script.newLine();
7268 22 Jun 23 nicklas 304       script.cmd(ascat_env);
7268 22 Jun 23 nicklas 305       if (debug) script.cmd(ascat_envdebug);
7268 22 Jun 23 nicklas 306       script.cmd(ascat_execute);
7268 22 Jun 23 nicklas 307
7268 22 Jun 23 nicklas 308       JobDefinition jobDef = new JobDefinition("ASCAT", jobConfig, batchConfig, ascatJob);
7268 22 Jun 23 nicklas 309       jobDef.addFile(ScriptUtil.upload("ascat.sh"));
7270 28 Jun 23 nicklas 310       jobDef.addFile(ScriptUtil.upload("allele_counter.R"));
7271 29 Jun 23 nicklas 311       jobDef.addFile(ScriptUtil.upload("run_ascat.R"));
7268 22 Jun 23 nicklas 312       jobDef.addFile(ScriptUtil.upload("reggie-utils.sh"));
7268 22 Jun 23 nicklas 313       jobDef.addFile(ScriptUtil.upload("stdwrap.sh"));
7270 28 Jun 23 nicklas 314       jobDef.addFile(ScriptUtil.upload("stderrwrap.sh"));
7268 22 Jun 23 nicklas 315       jobDef.setDebug(debug);
7268 22 Jun 23 nicklas 316       jobDef.setCmd(script.toString());
7268 22 Jun 23 nicklas 317       jobDefs.add(jobDef);
7268 22 Jun 23 nicklas 318     }
7268 22 Jun 23 nicklas 319     
7268 22 Jun 23 nicklas 320     return jobDefs;
7268 22 Jun 23 nicklas 321   }
7268 22 Jun 23 nicklas 322
7268 22 Jun 23 nicklas 323   /**
7268 22 Jun 23 nicklas 324     Job completion handler for ASCAT jobs. The handler downloads the
7268 22 Jun 23 nicklas 325     'files.out' file and create links to the files and import some
7268 22 Jun 23 nicklas 326     annotations.
7268 22 Jun 23 nicklas 327   */
7268 22 Jun 23 nicklas 328   public static class AscatJobCompletionHandler
7268 22 Jun 23 nicklas 329     implements JobCompletionHandler
7268 22 Jun 23 nicklas 330   {
7268 22 Jun 23 nicklas 331     private static final ExtensionsLogger logger = 
7268 22 Jun 23 nicklas 332       ExtensionsLog.getLogger(JobCompletionHandlerFactory.ID, true).wrap(LoggerFactory.getLogger(AscatJobCompletionHandler.class));
7268 22 Jun 23 nicklas 333     
7268 22 Jun 23 nicklas 334     public AscatJobCompletionHandler()
7268 22 Jun 23 nicklas 335     {}
7268 22 Jun 23 nicklas 336   
7268 22 Jun 23 nicklas 337     @Override
7268 22 Jun 23 nicklas 338     public String jobCompleted(SessionControl sc, OpenGridSession session, Job job, JobStatus status)
7268 22 Jun 23 nicklas 339     {
7268 22 Jun 23 nicklas 340       String jobName = status.getName();
7287 15 Aug 23 nicklas 341       String ascatStats = session.getJobFileAsString(jobName, "stats.txt", "UTF-8");
7268 22 Jun 23 nicklas 342       String files = session.getJobFileAsString(jobName, "files.out", "UTF-8");
7287 15 Aug 23 nicklas 343       Metrics metrics = parseFiles(sc, job, ascatStats, files);
7421 14 Nov 23 nicklas 344       String msg = "ASCAT analysis completed.";
7421 14 Nov 23 nicklas 345       if (metrics.ploidy != null && metrics.purity != null)
7421 14 Nov 23 nicklas 346       {
7421 14 Nov 23 nicklas 347         msg += " Purity: "+Values.formatNumber(metrics.purity*100, 0, "%")+
7421 14 Nov 23 nicklas 348           "; Ploidy: "+Values.formatNumber(metrics.ploidy, 2)+
7421 14 Nov 23 nicklas 349           "; Goodness of fit: "+Values.formatNumber(metrics.goodnessOfFit, 1, "%")+
7421 14 Nov 23 nicklas 350           (metrics.nonAberrant ? "; Non-aberrant" : "");
7421 14 Nov 23 nicklas 351       }
7421 14 Nov 23 nicklas 352       else
7421 14 Nov 23 nicklas 353       {
7421 14 Nov 23 nicklas 354         msg += " ASCAT could not find an optimal ploidy and purity value.";
7421 14 Nov 23 nicklas 355       }
7287 15 Aug 23 nicklas 356       return msg;
7268 22 Jun 23 nicklas 357     }
7268 22 Jun 23 nicklas 358     
7287 15 Aug 23 nicklas 359     private Metrics parseFiles(SessionControl sc, Job job, String ascatStats, String filesOut)
7268 22 Jun 23 nicklas 360     {
7287 15 Aug 23 nicklas 361       // Import statistics
7287 15 Aug 23 nicklas 362       Metrics metrics = new Metrics();
7287 15 Aug 23 nicklas 363       for (String line : ascatStats.split("\n"))
7287 15 Aug 23 nicklas 364       {
7287 15 Aug 23 nicklas 365         String[] keyVal = line.split("\\s+", 2);
7287 15 Aug 23 nicklas 366         if (keyVal.length == 2)
7287 15 Aug 23 nicklas 367         {
7287 15 Aug 23 nicklas 368           String key = keyVal[0];
7405 08 Nov 23 nicklas 369           String val = keyVal[1];
7432 15 Nov 23 nicklas 370           Float valf = Values.getFloat(val, null);
7287 15 Aug 23 nicklas 371           
7405 08 Nov 23 nicklas 372           if ("normal_contamination".equals(key))
7287 15 Aug 23 nicklas 373           {
7405 08 Nov 23 nicklas 374             metrics.normalContamination = valf;
7287 15 Aug 23 nicklas 375           }
7405 08 Nov 23 nicklas 376           else if ("ploidy".equals(key))
7287 15 Aug 23 nicklas 377           {
7405 08 Nov 23 nicklas 378             metrics.ploidy = valf;
7287 15 Aug 23 nicklas 379           }
7405 08 Nov 23 nicklas 380           else if ("purity".equals(key))
7287 15 Aug 23 nicklas 381           {
7405 08 Nov 23 nicklas 382             metrics.purity = valf;
7287 15 Aug 23 nicklas 383           }
7405 08 Nov 23 nicklas 384           else if ("goodness_of_fit".equals(key))
7287 15 Aug 23 nicklas 385           {
7405 08 Nov 23 nicklas 386             metrics.goodnessOfFit = valf;
7287 15 Aug 23 nicklas 387           }
7405 08 Nov 23 nicklas 388           else if ("non_aberrant".equals(key))
7341 11 Sep 23 nicklas 389           {
7405 08 Nov 23 nicklas 390             metrics.nonAberrant = Values.getBoolean(val);
7341 11 Sep 23 nicklas 391           }
7405 08 Nov 23 nicklas 392           else if ("n_segs".equals(key))
7405 08 Nov 23 nicklas 393           {
7405 08 Nov 23 nicklas 394             metrics.nSegs = Values.getInt(val);
7405 08 Nov 23 nicklas 395           }
7405 08 Nov 23 nicklas 396           else if ("LOH".equals(key))
7405 08 Nov 23 nicklas 397           {
7405 08 Nov 23 nicklas 398             metrics.loh = valf;
7405 08 Nov 23 nicklas 399           }
7405 08 Nov 23 nicklas 400           else if ("GI".equals(key))
7405 08 Nov 23 nicklas 401           {
7405 08 Nov 23 nicklas 402             metrics.gi_score = valf;
7405 08 Nov 23 nicklas 403           }
7287 15 Aug 23 nicklas 404         }
7287 15 Aug 23 nicklas 405       }
7287 15 Aug 23 nicklas 406             
7268 22 Jun 23 nicklas 407       DbControl dc = null;
7268 22 Jun 23 nicklas 408       String msg = null;
7268 22 Jun 23 nicklas 409       try
7268 22 Jun 23 nicklas 410       {
7268 22 Jun 23 nicklas 411         dc = sc.newDbControl("Reggie: ASCAT analysis completed handler");
7268 22 Jun 23 nicklas 412         
7287 15 Aug 23 nicklas 413         CopyNumber ascat = CopyNumber.getByJob(dc, job);
7287 15 Aug 23 nicklas 414         DerivedBioAssay dba = ascat.getItem();
7268 22 Jun 23 nicklas 415
7287 15 Aug 23 nicklas 416         Annotationtype.NORMAL_CONTAMINATION.setAnnotationValue(dc, dba, metrics.normalContamination);
7287 15 Aug 23 nicklas 417         Annotationtype.PLOIDY.setAnnotationValue(dc, dba, metrics.ploidy);
7287 15 Aug 23 nicklas 418         Annotationtype.GOODNESS_OF_FIT.setAnnotationValue(dc, dba, metrics.goodnessOfFit);
7287 15 Aug 23 nicklas 419         Annotationtype.PURITY.setAnnotationValue(dc, dba, metrics.purity);
7405 08 Nov 23 nicklas 420         Annotationtype.NUMBER_OF_SEGMENTS.setAnnotationValue(dc, dba, metrics.nSegs);
7405 08 Nov 23 nicklas 421         Annotationtype.LOH_FRACTION.setAnnotationValue(dc, dba, metrics.loh);
7405 08 Nov 23 nicklas 422         Annotationtype.GI_SCORE.setAnnotationValue(dc, dba, metrics.gi_score);
7341 11 Sep 23 nicklas 423         if (metrics.nonAberrant) Annotationtype.NON_ABERRANT.setAnnotationValue(dc, dba, "Yes");
7287 15 Aug 23 nicklas 424         
7287 15 Aug 23 nicklas 425         // Create file links
7287 15 Aug 23 nicklas 426         FileServer fileArchive = Fileserver.PROJECT_ARCHIVE_DNA.load(dc);
7287 15 Aug 23 nicklas 427         String analysisDir = Reggie.SECONDARY_ANALYSIS_DIR;
7287 15 Aug 23 nicklas 428
7287 15 Aug 23 nicklas 429         String dataFilesFolder = (String)Annotationtype.DATA_FILES_FOLDER.getAnnotationValue(dc, dba);
7287 15 Aug 23 nicklas 430         String baseFolder = Reggie.convertDataFilesFolderToBaseFolder(dataFilesFolder);
7287 15 Aug 23 nicklas 431         Directory localDataDir = Directory.getNew(dc, new Path(analysisDir+baseFolder, Path.Type.DIRECTORY));
7287 15 Aug 23 nicklas 432   
7287 15 Aug 23 nicklas 433         DataFileType rawData = Datafiletype.GENERIC_RAWDATA.load(dc);
7287 15 Aug 23 nicklas 434         ItemSubtype rawType = rawData.getGenericType();
7287 15 Aug 23 nicklas 435
7287 15 Aug 23 nicklas 436         int lineNo = 0;
7287 15 Aug 23 nicklas 437         for (String line : filesOut.split("\n"))
7287 15 Aug 23 nicklas 438         {
7287 15 Aug 23 nicklas 439           lineNo++;
7287 15 Aug 23 nicklas 440           
7287 15 Aug 23 nicklas 441           File f = File.getFile(dc, localDataDir, line.substring(line.lastIndexOf("/")+1), true);
7287 15 Aug 23 nicklas 442           f.setFileServer(fileArchive);
7287 15 Aug 23 nicklas 443           String fileUrl = "sftp://" + fileArchive.getHost() + dataFilesFolder + "/" + f.getName();
7287 15 Aug 23 nicklas 444           try
7287 15 Aug 23 nicklas 445           {
7287 15 Aug 23 nicklas 446             f.setUrl(fileUrl, true);
7287 15 Aug 23 nicklas 447           }
7287 15 Aug 23 nicklas 448           catch (RuntimeException ex)
7287 15 Aug 23 nicklas 449           {
7287 15 Aug 23 nicklas 450             f.setUrl(fileUrl, false);
7287 15 Aug 23 nicklas 451           }
7287 15 Aug 23 nicklas 452           
7287 15 Aug 23 nicklas 453           if (!f.isInDatabase())
7287 15 Aug 23 nicklas 454           {
7287 15 Aug 23 nicklas 455             dc.saveItem(f);
7287 15 Aug 23 nicklas 456           }
7287 15 Aug 23 nicklas 457           
7287 15 Aug 23 nicklas 458           AnyToAny link = AnyToAny.getNewOrExisting(dc, dba, f.getName(), f, true);
7287 15 Aug 23 nicklas 459           if (!link.isInDatabase()) dc.saveItem(link);
7287 15 Aug 23 nicklas 460         }
7287 15 Aug 23 nicklas 461
7268 22 Jun 23 nicklas 462         dc.commit();
7268 22 Jun 23 nicklas 463       }
7268 22 Jun 23 nicklas 464       finally
7268 22 Jun 23 nicklas 465       {
7268 22 Jun 23 nicklas 466         if (dc != null) dc.close();
7268 22 Jun 23 nicklas 467       }
7287 15 Aug 23 nicklas 468       return metrics;
7268 22 Jun 23 nicklas 469     }
7268 22 Jun 23 nicklas 470     
7268 22 Jun 23 nicklas 471   }
7287 15 Aug 23 nicklas 472     
7287 15 Aug 23 nicklas 473   static class Metrics
7287 15 Aug 23 nicklas 474   {
7287 15 Aug 23 nicklas 475     Float normalContamination = null;
7287 15 Aug 23 nicklas 476     Float ploidy = null;
7287 15 Aug 23 nicklas 477     Float purity = null;
7287 15 Aug 23 nicklas 478     Float goodnessOfFit = null;
7405 08 Nov 23 nicklas 479     Integer nSegs = null;
7405 08 Nov 23 nicklas 480     Float loh = null;
7405 08 Nov 23 nicklas 481     Float gi_score = null;
7341 11 Sep 23 nicklas 482     boolean nonAberrant = false;
7287 15 Aug 23 nicklas 483   }
7287 15 Aug 23 nicklas 484
7341 11 Sep 23 nicklas 485   
7341 11 Sep 23 nicklas 486   public enum AllelicImbalanceTest
7341 11 Sep 23 nicklas 487   {
7341 11 Sep 23 nicklas 488     LEGACY("Legacy"), 
7341 11 Sep 23 nicklas 489     MAD_SEGMENT("MadSegment"),
7341 11 Sep 23 nicklas 490     BIMODALITY_COEFFICIENT("BimodalityCoefficient");
7341 11 Sep 23 nicklas 491   
7341 11 Sep 23 nicklas 492     public static AllelicImbalanceTest fromTitle(String title)
7341 11 Sep 23 nicklas 493     {
7341 11 Sep 23 nicklas 494       for (AllelicImbalanceTest test : AllelicImbalanceTest.values())
7341 11 Sep 23 nicklas 495       {
7341 11 Sep 23 nicklas 496         if (test.getTitle().equals(title)) return test;
7341 11 Sep 23 nicklas 497       }
7341 11 Sep 23 nicklas 498       return null;
7341 11 Sep 23 nicklas 499     }
7341 11 Sep 23 nicklas 500     
7341 11 Sep 23 nicklas 501     private final String title;
7341 11 Sep 23 nicklas 502     private AllelicImbalanceTest(String title)
7341 11 Sep 23 nicklas 503     {
7341 11 Sep 23 nicklas 504       this.title = title;
7341 11 Sep 23 nicklas 505     }
7341 11 Sep 23 nicklas 506     
7341 11 Sep 23 nicklas 507     public String getTitle()
7341 11 Sep 23 nicklas 508     {
7341 11 Sep 23 nicklas 509       return title;
7341 11 Sep 23 nicklas 510     }
7341 11 Sep 23 nicklas 511     
7341 11 Sep 23 nicklas 512   }
7268 22 Jun 23 nicklas 513 }