src/core/net/sf/basedb/util/BioAssaySetFilterUtil.java

Code
Comments
Other
Rev Date Author Line
2183 24 Apr 06 nicklas 1 /*
2183 24 Apr 06 nicklas 2   $Id$
2183 24 Apr 06 nicklas 3
4889 06 Apr 09 nicklas 4   Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg, Martin Svensson
2183 24 Apr 06 nicklas 5   
2304 22 May 06 jari 6   This file is part of BASE - BioArray Software Environment.
2304 22 May 06 jari 7   Available at http://base.thep.lu.se/
2183 24 Apr 06 nicklas 8
2183 24 Apr 06 nicklas 9   BASE is free software; you can redistribute it and/or
2183 24 Apr 06 nicklas 10   modify it under the terms of the GNU General Public License
4479 05 Sep 08 jari 11   as published by the Free Software Foundation; either version 3
2183 24 Apr 06 nicklas 12   of the License, or (at your option) any later version.
2183 24 Apr 06 nicklas 13
2183 24 Apr 06 nicklas 14   BASE is distributed in the hope that it will be useful,
2183 24 Apr 06 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
2183 24 Apr 06 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2183 24 Apr 06 nicklas 17   GNU General Public License for more details.
2183 24 Apr 06 nicklas 18
2183 24 Apr 06 nicklas 19   You should have received a copy of the GNU General Public License
4515 11 Sep 08 jari 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
2183 24 Apr 06 nicklas 21 */
2183 24 Apr 06 nicklas 22 package net.sf.basedb.util;
2183 24 Apr 06 nicklas 23
2183 24 Apr 06 nicklas 24 import net.sf.basedb.core.DbControl;
2183 24 Apr 06 nicklas 25 import net.sf.basedb.core.DynamicSpotQuery;
2183 24 Apr 06 nicklas 26 import net.sf.basedb.core.FilterBatcher;
2183 24 Apr 06 nicklas 27 import net.sf.basedb.core.Job;
2183 24 Apr 06 nicklas 28 import net.sf.basedb.core.Transformation;
2183 24 Apr 06 nicklas 29 import net.sf.basedb.core.BioAssaySet;
2183 24 Apr 06 nicklas 30 import net.sf.basedb.core.BioAssay;
2185 25 Apr 06 nicklas 31 import net.sf.basedb.core.Type;
2183 24 Apr 06 nicklas 32 import net.sf.basedb.core.VirtualColumn;
2183 24 Apr 06 nicklas 33 import net.sf.basedb.core.DynamicResultIterator;
2183 24 Apr 06 nicklas 34 import net.sf.basedb.core.ProgressReporter;
2183 24 Apr 06 nicklas 35 import net.sf.basedb.core.BaseException;
2183 24 Apr 06 nicklas 36 import net.sf.basedb.core.InvalidDataException;
2183 24 Apr 06 nicklas 37 import net.sf.basedb.core.InvalidUseOfNullException;
2738 17 Oct 06 nicklas 38 import net.sf.basedb.core.query.Expression;
2185 25 Apr 06 nicklas 39 import net.sf.basedb.core.query.Expressions;
2183 24 Apr 06 nicklas 40 import net.sf.basedb.core.query.Restriction;
2183 24 Apr 06 nicklas 41 import net.sf.basedb.core.query.Dynamic;
2185 25 Apr 06 nicklas 42 import net.sf.basedb.core.query.Restrictions;
2183 24 Apr 06 nicklas 43 import net.sf.basedb.core.query.SqlResult;
4118 01 Feb 08 nicklas 44 import net.sf.basedb.core.signal.ThreadSignalHandler;
2183 24 Apr 06 nicklas 45
2183 24 Apr 06 nicklas 46 import java.sql.SQLException;
2738 17 Oct 06 nicklas 47 import java.util.List;
2183 24 Apr 06 nicklas 48
2183 24 Apr 06 nicklas 49
2183 24 Apr 06 nicklas 50 /**
2778 24 Oct 06 nicklas 51   This is a utility class for plugins that filters bioassay set data.
2183 24 Apr 06 nicklas 52   
2183 24 Apr 06 nicklas 53   @base.modified $Date$
2183 24 Apr 06 nicklas 54   @author Nicklas
2183 24 Apr 06 nicklas 55   @version 2.0
2183 24 Apr 06 nicklas 56 */
2183 24 Apr 06 nicklas 57 public class BioAssaySetFilterUtil
2183 24 Apr 06 nicklas 58 {
2183 24 Apr 06 nicklas 59
2183 24 Apr 06 nicklas 60   /**
2183 24 Apr 06 nicklas 61     Create a filtered bioassay set from a parent bioassay set using
2183 24 Apr 06 nicklas 62     a simple restriction. The filtering is done by the 
2981 30 Nov 06 nicklas 63     {@link FilterBatcher#insert(net.sf.basedb.core.AbstractSqlQuery)} which is 
2981 30 Nov 06 nicklas 64     very fast since most of the work is done by the database.
2183 24 Apr 06 nicklas 65     <p>
2183 24 Apr 06 nicklas 66     The calling code mustn't forget to commit the transaction.
2183 24 Apr 06 nicklas 67     
2183 24 Apr 06 nicklas 68     @param dc The <code>DbControl</code> object to use for database acecss
2183 24 Apr 06 nicklas 69     @param parent The parent bioassay set to start from
2738 17 Oct 06 nicklas 70     @param bioAssays Only filter on the specified bio assays, if the list
2738 17 Oct 06 nicklas 71       is null or empty all bioassays will be filtered
2183 24 Apr 06 nicklas 72     @param job The job that the transformation should be linked to, or
2183 24 Apr 06 nicklas 73       null if this method isn't called by a job
2183 24 Apr 06 nicklas 74     @param filter A filter expression
2183 24 Apr 06 nicklas 75     @param progress A <code>ProgressReporter</code> object (optional, current not used)
4017 28 Nov 07 martin 76      @return A filtered bioassay set. 
2183 24 Apr 06 nicklas 77     @throws InvalidDataException If any of the required parameters is null
4017 28 Nov 07 martin 78     @throws BaseException If creating a filtered bioassay set fails in some way.
2183 24 Apr 06 nicklas 79   */
2183 24 Apr 06 nicklas 80   public static BioAssaySet createFilteredBioAssaySet(DbControl dc, BioAssaySet parent, 
2738 17 Oct 06 nicklas 81     List<BioAssay> bioAssays, Job job, Restriction filter, ProgressReporter progress)
2183 24 Apr 06 nicklas 82     throws InvalidDataException, BaseException
2183 24 Apr 06 nicklas 83   {
2183 24 Apr 06 nicklas 84     if (parent == null) throw new InvalidUseOfNullException("parent");
2183 24 Apr 06 nicklas 85     if (filter == null) throw new InvalidUseOfNullException("filter");
2183 24 Apr 06 nicklas 86   
2185 25 Apr 06 nicklas 87     if (progress != null) progress.display(5, "Initialising spot filter...");
4118 01 Feb 08 nicklas 88     ThreadSignalHandler.checkInterrupted();
2185 25 Apr 06 nicklas 89
2183 24 Apr 06 nicklas 90     // Create Transformation
2183 24 Apr 06 nicklas 91     Transformation t = parent.newTransformation(job);
2492 08 Aug 06 nicklas 92     dc.saveItem(t);
2183 24 Apr 06 nicklas 93
2183 24 Apr 06 nicklas 94     // Create the filtered BioAssaySet in the same datacube and layer
2750 20 Oct 06 nicklas 95     BioAssaySet child = t.newProduct(null, null, false);
2738 17 Oct 06 nicklas 96     child.setName(parent.getName());
2183 24 Apr 06 nicklas 97     dc.saveItem(child);
2183 24 Apr 06 nicklas 98
2183 24 Apr 06 nicklas 99     // Create the batchers we need
2183 24 Apr 06 nicklas 100     FilterBatcher filterBatcher = child.getFilterBatcher();
2183 24 Apr 06 nicklas 101
2183 24 Apr 06 nicklas 102     // Create the query
2183 24 Apr 06 nicklas 103     DynamicSpotQuery query = parent.getSpotData();
5319 20 Apr 10 nicklas 104     query.setDisableRawJoinOnMergedData(true);
2183 24 Apr 06 nicklas 105     query.select(Dynamic.select(VirtualColumn.COLUMN));
2183 24 Apr 06 nicklas 106     query.select(Dynamic.select(VirtualColumn.POSITION));
2183 24 Apr 06 nicklas 107     query.restrict(filter);
2185 25 Apr 06 nicklas 108     query.restrict(
2185 25 Apr 06 nicklas 109       Restrictions.eq(
2185 25 Apr 06 nicklas 110         Dynamic.column(VirtualColumn.COLUMN),
2185 25 Apr 06 nicklas 111         Expressions.parameter("column")
2185 25 Apr 06 nicklas 112       )
2185 25 Apr 06 nicklas 113     );
2222 09 May 06 nicklas 114
2185 25 Apr 06 nicklas 115     //   Prepare progress reporting
2185 25 Apr 06 nicklas 116     int spotsTotal = parent.getNumSpots();
2738 17 Oct 06 nicklas 117     if (bioAssays != null && bioAssays.size() > 0)
2738 17 Oct 06 nicklas 118     {
2738 17 Oct 06 nicklas 119       spotsTotal = 0;
2738 17 Oct 06 nicklas 120       for (BioAssay ba : bioAssays)
2738 17 Oct 06 nicklas 121       {
2738 17 Oct 06 nicklas 122         spotsTotal += ba.getNumSpots();
2738 17 Oct 06 nicklas 123       }
2738 17 Oct 06 nicklas 124     }
2738 17 Oct 06 nicklas 125     
4095 21 Jan 08 enell 126     long spotsDone = 0;
2185 25 Apr 06 nicklas 127     int spotsAfter = 0;
2185 25 Apr 06 nicklas 128     if (progress != null) progress.display(10, "Filtering spots (0 done; "+spotsTotal+" total)...");
4118 01 Feb 08 nicklas 129
2492 08 Aug 06 nicklas 130     // Create filter
2738 17 Oct 06 nicklas 131     if (bioAssays == null || bioAssays.size() == 0) bioAssays =  parent.getBioAssays().list(dc);
2738 17 Oct 06 nicklas 132     for (BioAssay parentBa : bioAssays)
2185 25 Apr 06 nicklas 133     {
4118 01 Feb 08 nicklas 134       ThreadSignalHandler.checkInterrupted();
2738 17 Oct 06 nicklas 135       BioAssay childBa = child.newBioAssay(parentBa);
2998 04 Dec 06 nicklas 136       dc.saveItemIf(child, childBa, false);
2185 25 Apr 06 nicklas 137       spotsDone += parentBa.getNumSpots();
2492 08 Aug 06 nicklas 138       query.setParameter("column", (int)parentBa.getDataCubeColumnNo(), Type.INT);
2185 25 Apr 06 nicklas 139       spotsAfter += filterBatcher.insert(query);
2185 25 Apr 06 nicklas 140
2185 25 Apr 06 nicklas 141       if (progress != null) 
2185 25 Apr 06 nicklas 142       {
4095 21 Jan 08 enell 143         int percent = 10 + (int)(90L * spotsDone / spotsTotal);
2185 25 Apr 06 nicklas 144         progress.display(percent, 
2185 25 Apr 06 nicklas 145           "Filtering spot intensities ("+spotsDone+" done; "+spotsTotal+" total)...");
2185 25 Apr 06 nicklas 146       }
2185 25 Apr 06 nicklas 147     }
2185 25 Apr 06 nicklas 148     
2183 24 Apr 06 nicklas 149     // Close and clean up, calling code must commit
2183 24 Apr 06 nicklas 150     filterBatcher.close();
2183 24 Apr 06 nicklas 151
2185 25 Apr 06 nicklas 152     if (progress != null)
2185 25 Apr 06 nicklas 153     {
2285 18 May 06 nicklas 154       progress.display(100, "Filtering spot intensities ("+spotsTotal+" done; "+spotsTotal+" total)...\n");
2185 25 Apr 06 nicklas 155     }
2185 25 Apr 06 nicklas 156
2183 24 Apr 06 nicklas 157     // Return  
2183 24 Apr 06 nicklas 158     return child;
2183 24 Apr 06 nicklas 159   }
2183 24 Apr 06 nicklas 160   
2183 24 Apr 06 nicklas 161   public static BioAssaySet createFilteredBioAssaySet(DbControl dc, BioAssaySet parent, 
2738 17 Oct 06 nicklas 162     List<BioAssay> bioAssays, Job job, DynamicFilter filter, ProgressReporter progress)
2399 20 Jun 06 nicklas 163     throws InvalidDataException, BaseException
2399 20 Jun 06 nicklas 164   {
2399 20 Jun 06 nicklas 165     if (parent == null) throw new InvalidUseOfNullException("parent");
2399 20 Jun 06 nicklas 166     if (filter == null) throw new InvalidUseOfNullException("filter");
2399 20 Jun 06 nicklas 167   
2399 20 Jun 06 nicklas 168     if (progress != null) progress.display(5, "Initialising spot filter...");
4118 01 Feb 08 nicklas 169     ThreadSignalHandler.checkInterrupted();
2399 20 Jun 06 nicklas 170
2399 20 Jun 06 nicklas 171     // Create Transformation
2399 20 Jun 06 nicklas 172     Transformation t = parent.newTransformation(job);
2492 08 Aug 06 nicklas 173     dc.saveItem(t);
2399 20 Jun 06 nicklas 174
2399 20 Jun 06 nicklas 175     // Create the filtered BioAssaySet in the same datacube and layer
2738 17 Oct 06 nicklas 176     BioAssaySet child = t.newProduct(null, null, bioAssays == null || bioAssays.size() == 0);
2738 17 Oct 06 nicklas 177     child.setName(parent.getName());
2399 20 Jun 06 nicklas 178     dc.saveItem(child);
2183 24 Apr 06 nicklas 179     
2399 20 Jun 06 nicklas 180     // Create the batchers we need
2399 20 Jun 06 nicklas 181     FilterBatcher filterBatcher = child.getFilterBatcher();
2183 24 Apr 06 nicklas 182
2399 20 Jun 06 nicklas 183     // Create the query
2399 20 Jun 06 nicklas 184     DynamicSpotQuery query = parent.getSpotData();
5319 20 Apr 10 nicklas 185     query.setDisableRawJoinOnMergedData(true);
2399 20 Jun 06 nicklas 186     query.select(Dynamic.select(VirtualColumn.COLUMN));
2399 20 Jun 06 nicklas 187     query.select(Dynamic.select(VirtualColumn.POSITION));
2399 20 Jun 06 nicklas 188     filter.configureQuery(query);
2738 17 Oct 06 nicklas 189     
2738 17 Oct 06 nicklas 190     int spotsTotal = parent.getNumSpots(); // Total number of spots
2183 24 Apr 06 nicklas 191
2738 17 Oct 06 nicklas 192     // Create child bioassays and filter
2738 17 Oct 06 nicklas 193     if (bioAssays != null && bioAssays.size() > 0)
2738 17 Oct 06 nicklas 194     {
2738 17 Oct 06 nicklas 195       spotsTotal = 0;
2738 17 Oct 06 nicklas 196       Expression[] selectedColumns = new Expression[bioAssays.size()];
2738 17 Oct 06 nicklas 197       for (int i = 0; i < selectedColumns.length; ++i)
2738 17 Oct 06 nicklas 198       {
2738 17 Oct 06 nicklas 199         BioAssay ba = bioAssays.get(i);
2738 17 Oct 06 nicklas 200         BioAssay childBa = child.newBioAssay(ba);
2998 04 Dec 06 nicklas 201         dc.saveItemIf(child, childBa, false);
2738 17 Oct 06 nicklas 202         selectedColumns[i] = Expressions.integer(ba.getDataCubeColumnNo());
2738 17 Oct 06 nicklas 203         spotsTotal += ba.getNumSpots();
2738 17 Oct 06 nicklas 204       }
2738 17 Oct 06 nicklas 205       Expression column = Dynamic.column(VirtualColumn.COLUMN);
2738 17 Oct 06 nicklas 206       query.restrict(Restrictions.in(column, selectedColumns));
2738 17 Oct 06 nicklas 207     }
4118 01 Feb 08 nicklas 208     
2399 20 Jun 06 nicklas 209     // Prepare progress reporting
2399 20 Jun 06 nicklas 210     int interval = 10;  // Update progress after this many spots >= 10
4095 21 Jan 08 enell 211     long spotsDone = 0;
2399 20 Jun 06 nicklas 212     int spotsAfter = 0;
2399 20 Jun 06 nicklas 213     if (progress != null)
2399 20 Jun 06 nicklas 214     {
2399 20 Jun 06 nicklas 215       interval = spotsTotal / 20;
2399 20 Jun 06 nicklas 216       if (interval < 10) interval = 10;
2399 20 Jun 06 nicklas 217       progress.display(10, "Filtering spots (0 done; "+spotsTotal+" total)...");
2399 20 Jun 06 nicklas 218     }
4118 01 Feb 08 nicklas 219
2399 20 Jun 06 nicklas 220     // Do the filtering
2399 20 Jun 06 nicklas 221     if (filter.useIncludeSpot())
2399 20 Jun 06 nicklas 222     {
2399 20 Jun 06 nicklas 223       DynamicResultIterator result = query.iterate(dc);
2399 20 Jun 06 nicklas 224       try
2183 24 Apr 06 nicklas 225       {
2399 20 Jun 06 nicklas 226         while (result.hasNext())
2183 24 Apr 06 nicklas 227         {
4118 01 Feb 08 nicklas 228           ThreadSignalHandler.checkInterrupted();
2399 20 Jun 06 nicklas 229           SqlResult data = result.next();
2399 20 Jun 06 nicklas 230           if (filter.includeSpot(data))
2183 24 Apr 06 nicklas 231           {
2399 20 Jun 06 nicklas 232             short column = data.getShort(1);
2399 20 Jun 06 nicklas 233             int position = data.getInt(2);
2399 20 Jun 06 nicklas 234             filterBatcher.insert(column, position);
2399 20 Jun 06 nicklas 235             spotsAfter++;
2399 20 Jun 06 nicklas 236           }
2399 20 Jun 06 nicklas 237           
2399 20 Jun 06 nicklas 238           if (progress != null)
2399 20 Jun 06 nicklas 239           {
2399 20 Jun 06 nicklas 240             spotsDone++;
2399 20 Jun 06 nicklas 241             if (spotsDone % interval == 0)
2183 24 Apr 06 nicklas 242             {
4095 21 Jan 08 enell 243               int percent = 10 + (int)(90L * spotsDone / spotsTotal);
2399 20 Jun 06 nicklas 244               progress.display(percent, 
2399 20 Jun 06 nicklas 245                 "Filtering spot intensities ("+spotsDone+" done; "+spotsTotal+" total)...");
2183 24 Apr 06 nicklas 246             }
2183 24 Apr 06 nicklas 247           }
2183 24 Apr 06 nicklas 248         }
2183 24 Apr 06 nicklas 249       }
2399 20 Jun 06 nicklas 250       catch (SQLException ex)
2183 24 Apr 06 nicklas 251       {
2399 20 Jun 06 nicklas 252         throw new BaseException(ex);
2183 24 Apr 06 nicklas 253       }
2399 20 Jun 06 nicklas 254     }
2399 20 Jun 06 nicklas 255     else
2399 20 Jun 06 nicklas 256     {
2399 20 Jun 06 nicklas 257       filterBatcher.insert(query);
2399 20 Jun 06 nicklas 258     }
2183 24 Apr 06 nicklas 259
2399 20 Jun 06 nicklas 260     // Close and clean up, calling code must commit
2399 20 Jun 06 nicklas 261     filterBatcher.close();
2399 20 Jun 06 nicklas 262     if (progress != null)
2399 20 Jun 06 nicklas 263     {
2399 20 Jun 06 nicklas 264       progress.display(100, "Filtering spot intensities ("+spotsTotal+" done; "+spotsTotal+" total)...\n");
2183 24 Apr 06 nicklas 265     }
2183 24 Apr 06 nicklas 266
2399 20 Jun 06 nicklas 267     // Return  
2399 20 Jun 06 nicklas 268     return child;
2399 20 Jun 06 nicklas 269   }
2399 20 Jun 06 nicklas 270
2222 09 May 06 nicklas 271
2183 24 Apr 06 nicklas 272 }