plugins/base2/se.lu.thep.affymetrix/trunk/Plier.java

Code
Comments
Other
Rev Date Author Line
123 12 Jul 06 jari 1 /*
123 12 Jul 06 jari 2   $Id$
123 12 Jul 06 jari 3
348 27 Jun 07 jari 4   Copyright (C) 2006 Jari Häkkinen
348 27 Jun 07 jari 5   Copyright (C) 2007 Jari Häkkinen, Peter Johansson
123 12 Jul 06 jari 6   
123 12 Jul 06 jari 7   This file is part of BASEPlugIns - Non-core plug-ins for BASE,
123 12 Jul 06 jari 8   BioArray Software Environment.
123 12 Jul 06 jari 9   BASEPlugIns is available at http://baseplugins.thep.lu.se/
123 12 Jul 06 jari 10   BASE is available at http://base.thep.lu.se/
123 12 Jul 06 jari 11
123 12 Jul 06 jari 12   BASEPlugIns is free software; you can redistribute it and/or modify
123 12 Jul 06 jari 13   it under the terms of the GNU General Public License as published by
123 12 Jul 06 jari 14   the Free Software Foundation; either version 2 of the License, or
123 12 Jul 06 jari 15   (at your option) any later version.
123 12 Jul 06 jari 16
123 12 Jul 06 jari 17   BASEPlugIns is distributed in the hope that it will be useful, but
123 12 Jul 06 jari 18   WITHOUT ANY WARRANTY; without even the implied warranty of
123 12 Jul 06 jari 19   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
123 12 Jul 06 jari 20   General Public License for more details.
123 12 Jul 06 jari 21
123 12 Jul 06 jari 22   You should have received a copy of the GNU General Public License
123 12 Jul 06 jari 23   along with this program; if not, write to the Free Software
123 12 Jul 06 jari 24   Foundation, Inc., 59 Temple Place - Suite 330,
123 12 Jul 06 jari 25   Boston, MA  02111-1307, USA.
123 12 Jul 06 jari 26 */
123 12 Jul 06 jari 27
123 12 Jul 06 jari 28 package se.lu.thep.affymetrix;
123 12 Jul 06 jari 29
311 28 May 07 peter 30 import se.lu.thep.affymetrix.AbstractExternalBinaryPlugin;
311 28 May 07 peter 31
312 28 May 07 peter 32
123 12 Jul 06 jari 33 import net.sf.basedb.core.Affymetrix;
123 12 Jul 06 jari 34 import net.sf.basedb.core.ArrayDesign;
123 12 Jul 06 jari 35 import net.sf.basedb.core.BaseException;
123 12 Jul 06 jari 36 import net.sf.basedb.core.BioAssay;
123 12 Jul 06 jari 37 import net.sf.basedb.core.BioAssaySet;
123 12 Jul 06 jari 38 import net.sf.basedb.core.DbControl;
123 12 Jul 06 jari 39 import net.sf.basedb.core.Experiment;
123 12 Jul 06 jari 40 import net.sf.basedb.core.File;
123 12 Jul 06 jari 41 import net.sf.basedb.core.Item;
123 12 Jul 06 jari 42 import net.sf.basedb.core.ItemParameterType;
123 12 Jul 06 jari 43 import net.sf.basedb.core.Job;
153 10 Aug 06 jari 44 import net.sf.basedb.core.PluginDefinition;
123 12 Jul 06 jari 45 import net.sf.basedb.core.PluginParameter;
123 12 Jul 06 jari 46 import net.sf.basedb.core.PositionBatcher;
123 12 Jul 06 jari 47 import net.sf.basedb.core.ProgressReporter;
123 12 Jul 06 jari 48 import net.sf.basedb.core.RawBioAssay;
129 08 Aug 06 jari 49 import net.sf.basedb.core.ReporterBatcher;
123 12 Jul 06 jari 50 import net.sf.basedb.core.RequestInformation;
123 12 Jul 06 jari 51 import net.sf.basedb.core.SpotBatcher;
123 12 Jul 06 jari 52 import net.sf.basedb.core.StringParameterType;
123 12 Jul 06 jari 53 import net.sf.basedb.core.Transformation;
123 12 Jul 06 jari 54
123 12 Jul 06 jari 55 import net.sf.basedb.core.plugin.About;
123 12 Jul 06 jari 56 import net.sf.basedb.core.plugin.AboutImpl;
123 12 Jul 06 jari 57 import net.sf.basedb.core.plugin.GuiContext;
123 12 Jul 06 jari 58
123 12 Jul 06 jari 59 import net.sf.basedb.util.parser.FlatFileParser;
123 12 Jul 06 jari 60
123 12 Jul 06 jari 61 import java.io.IOException;
123 12 Jul 06 jari 62
300 24 May 07 peter 63 import java.lang.Double;
300 24 May 07 peter 64 import java.lang.Float;
300 24 May 07 peter 65 import java.lang.Math;
300 24 May 07 peter 66
123 12 Jul 06 jari 67 import java.util.Collections;
123 12 Jul 06 jari 68 import java.util.HashMap;
123 12 Jul 06 jari 69 import java.util.List;
129 08 Aug 06 jari 70 import java.util.Map;
123 12 Jul 06 jari 71 import java.util.Set;
123 12 Jul 06 jari 72
123 12 Jul 06 jari 73 import java.util.regex.Pattern;
123 12 Jul 06 jari 74
123 12 Jul 06 jari 75 /**
123 12 Jul 06 jari 76    This plugin provides means to calculate the fold changes for a root bioassayset 
266 07 May 07 peter 77    using PLIER. It needs the following parameters:
123 12 Jul 06 jari 78
123 12 Jul 06 jari 79    <pre>
123 12 Jul 06 jari 80    String              : name; The name of the new bioassayset.
123 12 Jul 06 jari 81    Experiment          : experiment; The experiment we are working on.
123 12 Jul 06 jari 82    List&gt;RawBioAssay&lt;   : rawBioAssays; The raw bioassays to create bioassays for
123 12 Jul 06 jari 83                          (must be part of the experiment).
123 12 Jul 06 jari 84    </pre>
123 12 Jul 06 jari 85
266 07 May 07 peter 86    @author Peter Johansson
287 22 May 07 jari 87    @version MAKESUBSTOFVERSIONNUMBER
126 20 Jul 06 jari 88    @base.modified $Date$
123 12 Jul 06 jari 89 */
123 12 Jul 06 jari 90
266 07 May 07 peter 91 public class Plier
311 28 May 07 peter 92   extends AbstractExternalBinaryPlugin
123 12 Jul 06 jari 93 {
123 12 Jul 06 jari 94
266 07 May 07 peter 95   public Plier() {}
123 12 Jul 06 jari 96
123 12 Jul 06 jari 97   public About getAbout() { return about; }
123 12 Jul 06 jari 98
123 12 Jul 06 jari 99
266 07 May 07 peter 100   public String getAPTPath()
153 10 Aug 06 jari 101   {
266 07 May 07 peter 102     if (APTPath == null) {
153 10 Aug 06 jari 103       DbControl dc = sc.newDbControl();
343 25 Jun 07 jari 104       try {
343 25 Jun 07 jari 105         String jarpath=PluginDefinition.getByClassName(dc,
343 25 Jun 07 jari 106                                      "se.lu.thep.affymetrix.Plier").getJarPath();
343 25 Jun 07 jari 107         int pos = jarpath.length();
343 25 Jun 07 jari 108         while ((pos>0) && (jarpath.charAt(pos-1)!=java.io.File.separatorChar))
343 25 Jun 07 jari 109           --pos;
343 25 Jun 07 jari 110         APTPath=jarpath.substring(0,pos);
343 25 Jun 07 jari 111       }
343 25 Jun 07 jari 112       finally {
343 25 Jun 07 jari 113         if (dc != null)
343 25 Jun 07 jari 114           dc.close();
343 25 Jun 07 jari 115       }
153 10 Aug 06 jari 116       // Hard coded file name and the binary must reside in the same
153 10 Aug 06 jari 117       // directory as the plug-in jar. The idea behind this is that
153 10 Aug 06 jari 118       // only the BASE administrator is allowed to change files in the
342 23 Jun 07 jari 119       // BASE application directory structure.
266 07 May 07 peter 120       APTPath+="apt-probeset-summarize";
153 10 Aug 06 jari 121     }
266 07 May 07 peter 122     return APTPath;
153 10 Aug 06 jari 123   }
153 10 Aug 06 jari 124
153 10 Aug 06 jari 125
311 28 May 07 peter 126    protected void runBinary(List<RawBioAssay> sources,
311 28 May 07 peter 127                          ProgressReporter progress)
123 12 Jul 06 jari 128     throws InterruptedException, IOException
123 12 Jul 06 jari 129   {
123 12 Jul 06 jari 130     // Are filenames used here unique? There are many possible
123 12 Jul 06 jari 131     // clashes, maybe the implementation should use system generated
123 12 Jul 06 jari 132     // unique filenames?
123 12 Jul 06 jari 133     String filelistname="inputfiles.txt";
123 12 Jul 06 jari 134     java.io.PrintWriter filelist =
266 07 May 07 peter 135       new java.io.PrintWriter(new java.io.File(getExecDirectory(),
266 07 May 07 peter 136                                                filelistname));
266 07 May 07 peter 137     filelist.println("cel_files");
123 12 Jul 06 jari 138     File cdf=Affymetrix.getCdfFile(sources.get(0).getArrayDesign());
133 09 Aug 06 jari 139     progress.display(percentDone,"Downloading CDF file '" +cdf.getName()+ "'.");
123 12 Jul 06 jari 140     download(cdf);
123 12 Jul 06 jari 141     for (RawBioAssay rba : sources) {
123 12 Jul 06 jari 142       File cel=Affymetrix.getCelFile(rba);
133 09 Aug 06 jari 143       progress.display(percentDone,"Downloading CEL file '"+cel.getName()+"'.");
123 12 Jul 06 jari 144       filelist.println(cel.getName());
123 12 Jul 06 jari 145       download(cel);
123 12 Jul 06 jari 146     }
123 12 Jul 06 jari 147     filelist.close();
133 09 Aug 06 jari 148     percentDone+=1;
266 07 May 07 peter 149     progress.display(percentDone,"Running PLIER.");
266 07 May 07 peter 150     String[] cmd = { getAPTPath() , "--cdf-file", cdf.getName(), "--cel-files", 
266 07 May 07 peter 151                      filelistname, "-o", getExecDirectory().toString(), 
266 07 May 07 peter 152                      "--analysis", "plier-mm" };
266 07 May 07 peter 153     Process p = Runtime.getRuntime().exec(cmd, null, getExecDirectory());
123 12 Jul 06 jari 154     p.waitFor();
123 12 Jul 06 jari 155     int status=p.exitValue();
123 12 Jul 06 jari 156     if (status>0)
266 07 May 07 peter 157       throw new IOException("Unexpected exit of PLIER sub-process. " +
123 12 Jul 06 jari 158                             "Return value: " + status);
123 12 Jul 06 jari 159   }
123 12 Jul 06 jari 160
123 12 Jul 06 jari 161
311 28 May 07 peter 162   protected void storeResult(DbControl dc, Experiment experiment,
133 09 Aug 06 jari 163                            List<RawBioAssay> sources, String name,
133 09 Aug 06 jari 164                            ProgressReporter progress)
123 12 Jul 06 jari 165   {
123 12 Jul 06 jari 166     try {
123 12 Jul 06 jari 167       FlatFileParser ffp=new FlatFileParser();
123 12 Jul 06 jari 168       ffp.setInputStream(new java.io.FileInputStream
266 07 May 07 peter 169                          (getExecDirectory()+java.io.File.separator+
290 23 May 07 jari 170                           "plier-mm.summary.txt"), null);
266 07 May 07 peter 171
271 16 May 07 peter 172       ffp.setDataHeaderRegexp(Pattern.compile("probeset_id\\t.*"));
123 12 Jul 06 jari 173       ffp.setDataSplitterRegexp(Pattern.compile("\\t"));
123 12 Jul 06 jari 174       ffp.setMinDataColumns(sources.size()+1);
123 12 Jul 06 jari 175       ffp.setMaxDataColumns(sources.size()+1);
123 12 Jul 06 jari 176       ffp.parseHeaders();
123 12 Jul 06 jari 177
133 09 Aug 06 jari 178       Transformation t=experiment.newTransformation(Job.getById(dc,job.getId()),
133 09 Aug 06 jari 179                                                     sources);
266 07 May 07 peter 180       t.setName("PLIER");
129 08 Aug 06 jari 181       BioAssaySet root = t.newProduct("new", "new", false);
123 12 Jul 06 jari 182       root.setName(name);
123 12 Jul 06 jari 183       dc.saveItem(t);
123 12 Jul 06 jari 184       dc.saveItem(root);
123 12 Jul 06 jari 185
129 08 Aug 06 jari 186       HashMap<Integer,Short> cubecolumn=new HashMap<Integer,Short>();
123 12 Jul 06 jari 187       for (RawBioAssay rba : sources) {
123 12 Jul 06 jari 188         BioAssay ba = root.newRootBioAssay(Collections.singleton(rba));
123 12 Jul 06 jari 189         ba.setName(rba.getName());
123 12 Jul 06 jari 190         dc.saveItem(ba);
123 12 Jul 06 jari 191         cubecolumn.put
123 12 Jul 06 jari 192           (ffp.getColumnHeaderIndex(Affymetrix.getCelFile(rba).getName()),
129 08 Aug 06 jari 193            ba.getDataCubeColumnNo());
123 12 Jul 06 jari 194       }
123 12 Jul 06 jari 195
191 31 Oct 06 jari 196       int position=1;  // Use 1 for consistency with BASE usage if position
129 08 Aug 06 jari 197       ReporterBatcher rbatcher = ReporterBatcher.getNew(dc);
129 08 Aug 06 jari 198       PositionBatcher pbatcher = root.getPositionBatcher();
129 08 Aug 06 jari 199       SpotBatcher sbatcher = root.getSpotBatcher();
133 09 Aug 06 jari 200       // The progress should be inside the loop, but for now we do not
133 09 Aug 06 jari 201       // know how many data entries there is to store (currently the
133 09 Aug 06 jari 202       // number of "spots" is not stored in the database for
133 09 Aug 06 jari 203       // Affymetrix).
133 09 Aug 06 jari 204       percentDone=95;
133 09 Aug 06 jari 205       progress.display(percentDone,"Importing result.");
303 24 May 07 jari 206       double log2=Math.log(2);
123 12 Jul 06 jari 207       while (ffp.hasMoreData()) {
123 12 Jul 06 jari 208         FlatFileParser.Data data = ffp.nextData();
300 24 May 07 peter 209         for (Map.Entry<Integer,Short> entry : cubecolumn.entrySet()){
300 24 May 07 peter 210           Double x = 
302 24 May 07 peter 211             new Double(Math.log(Double.parseDouble(data.get(entry.getKey())))/
303 24 May 07 jari 212                        log2);
300 24 May 07 peter 213           sbatcher.insert(entry.getValue().shortValue(), position, 
300 24 May 07 peter 214                           x.floatValue());
300 24 May 07 peter 215         }
123 12 Jul 06 jari 216         // The reporter id is assumed to be the first column
129 08 Aug 06 jari 217         pbatcher.insert(position,rbatcher.getByExternalId(data.get(0)));
123 12 Jul 06 jari 218         ++position;
123 12 Jul 06 jari 219       }
133 09 Aug 06 jari 220       rbatcher.close();
133 09 Aug 06 jari 221       pbatcher.close();
123 12 Jul 06 jari 222       sbatcher.close();
123 12 Jul 06 jari 223     }
123 12 Jul 06 jari 224     catch(Throwable e) {
218 13 Dec 06 jari 225       throw new BaseException("Unable to import root bioassay.",e);
123 12 Jul 06 jari 226     }
123 12 Jul 06 jari 227   }
123 12 Jul 06 jari 228
123 12 Jul 06 jari 229
153 10 Aug 06 jari 230
153 10 Aug 06 jari 231
311 28 May 07 peter 232
123 12 Jul 06 jari 233   private static final About about = new AboutImpl
266 07 May 07 peter 234     ("PLIER plug-in", "Computes gene expression summary values for " +
266 07 May 07 peter 235      "Affymetrix Genechip data using the Probe Logarithm Intensity " +
302 24 May 07 peter 236      "ERror algorithm. Results are expressed in log2 scale.",
134 09 Aug 06 jari 237      "Version: MAKESUBSTOFVERSIONNUMBER $Revision$ " +
134 09 Aug 06 jari 238      "$Date$",
266 07 May 07 peter 239      "2007 Peter Johansson, " +
125 20 Jul 06 jari 240      "Department of Theoretical Physics, Lund University",
165 29 Aug 06 jari 241      null, null,
300 24 May 07 peter 242      "http://baseplugins.thep.lu.se/wiki/se.lu.thep.affymetrix" );
123 12 Jul 06 jari 243   private RequestInformation configureJob = null;
123 12 Jul 06 jari 244   private RequestInformation configurePlugin = null;
123 12 Jul 06 jari 245   private ItemParameterType<Experiment> experimentType;
123 12 Jul 06 jari 246   /**
123 12 Jul 06 jari 247      This is the directory where the plug-in will generate its output.
123 12 Jul 06 jari 248   */
123 12 Jul 06 jari 249   private java.io.File execDirectory;
123 12 Jul 06 jari 250   private PluginParameter<Experiment> experimentParameter;
123 12 Jul 06 jari 251   private static final Set<GuiContext> guiContexts = Collections.singleton
123 12 Jul 06 jari 252     (new GuiContext(Item.BIOASSAYSET,GuiContext.Type.LIST));
123 12 Jul 06 jari 253   private static final StringParameterType nameType = 
123 12 Jul 06 jari 254     new StringParameterType(BioAssaySet.MAX_NAME_LENGTH, "New bioassayset",
123 12 Jul 06 jari 255                             true);
123 12 Jul 06 jari 256   private static final PluginParameter<String> nameParameter =
123 12 Jul 06 jari 257     new PluginParameter<String>("name", "Bioassay set name",
123 12 Jul 06 jari 258                                 "The name of the root bioassayset", nameType);
133 09 Aug 06 jari 259   private int percentDone=0;
123 12 Jul 06 jari 260   private ItemParameterType<RawBioAssay> rawBioAssaysType;
123 12 Jul 06 jari 261   private PluginParameter<RawBioAssay> rawBioAssaysParameter;
266 07 May 07 peter 262   private String APTPath;
123 12 Jul 06 jari 263 }