src/core/net/sf/basedb/util/IncludeExcludeFilter.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
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.BaseException;
2738 17 Oct 06 nicklas 25 import net.sf.basedb.core.BioAssay;
2183 24 Apr 06 nicklas 26 import net.sf.basedb.core.BioAssaySet;
2183 24 Apr 06 nicklas 27 import net.sf.basedb.core.DbControl;
2183 24 Apr 06 nicklas 28 import net.sf.basedb.core.DynamicResultIterator;
2183 24 Apr 06 nicklas 29 import net.sf.basedb.core.DynamicSpotQuery;
2183 24 Apr 06 nicklas 30 import net.sf.basedb.core.VirtualColumn;
2183 24 Apr 06 nicklas 31 import net.sf.basedb.core.query.Aggregations;
2183 24 Apr 06 nicklas 32 import net.sf.basedb.core.query.Dynamic;
2738 17 Oct 06 nicklas 33 import net.sf.basedb.core.query.Expression;
2183 24 Apr 06 nicklas 34 import net.sf.basedb.core.query.Expressions;
2183 24 Apr 06 nicklas 35 import net.sf.basedb.core.query.Restriction;
2183 24 Apr 06 nicklas 36 import net.sf.basedb.core.query.Restrictions;
2183 24 Apr 06 nicklas 37 import net.sf.basedb.core.query.Select;
2183 24 Apr 06 nicklas 38 import net.sf.basedb.core.query.Selects;
2183 24 Apr 06 nicklas 39 import net.sf.basedb.core.query.SqlQuery;
2183 24 Apr 06 nicklas 40 import net.sf.basedb.core.query.SqlResult;
2778 24 Oct 06 nicklas 41 import net.sf.basedb.core.query.WhenStatement;
2183 24 Apr 06 nicklas 42
2183 24 Apr 06 nicklas 43 import java.sql.SQLException;
2183 24 Apr 06 nicklas 44 import java.util.HashMap;
2738 17 Oct 06 nicklas 45 import java.util.List;
2183 24 Apr 06 nicklas 46 import java.util.Map;
2183 24 Apr 06 nicklas 47
2183 24 Apr 06 nicklas 48 /**
2183 24 Apr 06 nicklas 49
2183 24 Apr 06 nicklas 50   
2183 24 Apr 06 nicklas 51   @author Nicklas
2183 24 Apr 06 nicklas 52   @version 2.0
2183 24 Apr 06 nicklas 53   @base.modified $Date$
2183 24 Apr 06 nicklas 54 */
2183 24 Apr 06 nicklas 55 public class IncludeExcludeFilter
2183 24 Apr 06 nicklas 56   implements DynamicFilter
2183 24 Apr 06 nicklas 57 {
2778 24 Oct 06 nicklas 58   private final Restriction filter;
2183 24 Apr 06 nicklas 59   private final int includeLimit;
2183 24 Apr 06 nicklas 60   private final int excludeLimit;
2183 24 Apr 06 nicklas 61   private final Map<Integer, Integer> positionCount; 
2183 24 Apr 06 nicklas 62   
2738 17 Oct 06 nicklas 63   public IncludeExcludeFilter(DbControl dc, BioAssaySet bas, List<BioAssay> bioAssays,
2738 17 Oct 06 nicklas 64     Restriction filter, Integer includeLimit, Integer excludeLimit)
2183 24 Apr 06 nicklas 65   {
2778 24 Oct 06 nicklas 66     this.filter = filter;
2778 24 Oct 06 nicklas 67     this.includeLimit = includeLimit == null ? Integer.MAX_VALUE : includeLimit.intValue();
2185 25 Apr 06 nicklas 68     this.excludeLimit = excludeLimit== null ? 0 : excludeLimit.intValue();
2183 24 Apr 06 nicklas 69     this.positionCount = new HashMap<Integer, Integer>();
2183 24 Apr 06 nicklas 70     
2183 24 Apr 06 nicklas 71     // Select position and count of columns for that position
2183 24 Apr 06 nicklas 72     Select cnt = Selects.expression(
2183 24 Apr 06 nicklas 73       Aggregations.count(Dynamic.column(VirtualColumn.COLUMN), true), 
2183 24 Apr 06 nicklas 74       "cnt"
2183 24 Apr 06 nicklas 75     );
2183 24 Apr 06 nicklas 76     
2183 24 Apr 06 nicklas 77     DynamicSpotQuery query = bas.getSpotData();
2183 24 Apr 06 nicklas 78     query.select(Dynamic.select(VirtualColumn.POSITION));
2183 24 Apr 06 nicklas 79     query.select(cnt);
2183 24 Apr 06 nicklas 80     
2738 17 Oct 06 nicklas 81     // Restrict on selected bioassays
2738 17 Oct 06 nicklas 82     // Create child bioassays and filter
2738 17 Oct 06 nicklas 83     if (bioAssays != null && bioAssays.size() > 0)
2738 17 Oct 06 nicklas 84     {
2738 17 Oct 06 nicklas 85       Expression[] selectedColumns = new Expression[bioAssays.size()];
2738 17 Oct 06 nicklas 86       for (int i = 0; i < selectedColumns.length; ++i)
2738 17 Oct 06 nicklas 87       {
2738 17 Oct 06 nicklas 88         BioAssay ba = bioAssays.get(i);
2738 17 Oct 06 nicklas 89         selectedColumns[i] = Expressions.integer(ba.getDataCubeColumnNo());
2738 17 Oct 06 nicklas 90       }
2738 17 Oct 06 nicklas 91       Expression column = Dynamic.column(VirtualColumn.COLUMN);
2738 17 Oct 06 nicklas 92       query.restrict(Restrictions.in(column, selectedColumns));
2738 17 Oct 06 nicklas 93     }
2738 17 Oct 06 nicklas 94     
2183 24 Apr 06 nicklas 95     // Add restrictions and grouping
2183 24 Apr 06 nicklas 96     query.restrict(filter);
2183 24 Apr 06 nicklas 97     query.group(Dynamic.column(VirtualColumn.POSITION));
2185 25 Apr 06 nicklas 98     if (this.excludeLimit > 0)
2183 24 Apr 06 nicklas 99     {
2183 24 Apr 06 nicklas 100       query.having(
2183 24 Apr 06 nicklas 101         Restrictions.gteq(
2183 24 Apr 06 nicklas 102             Expressions.selected(cnt),
2185 25 Apr 06 nicklas 103             Expressions.integer(this.excludeLimit)
2183 24 Apr 06 nicklas 104         )
2183 24 Apr 06 nicklas 105       );
2183 24 Apr 06 nicklas 106     }
2183 24 Apr 06 nicklas 107
2183 24 Apr 06 nicklas 108     // Execure query and fill hashmap
2183 24 Apr 06 nicklas 109     DynamicResultIterator result = query.iterate(dc);
2183 24 Apr 06 nicklas 110     try
2183 24 Apr 06 nicklas 111     {
2183 24 Apr 06 nicklas 112       while (result.hasNext())
2183 24 Apr 06 nicklas 113       {
2183 24 Apr 06 nicklas 114         SqlResult data = result.next();
2183 24 Apr 06 nicklas 115         int position = data.getInt(1);
2183 24 Apr 06 nicklas 116         int count = data.getInt(2);
2183 24 Apr 06 nicklas 117         positionCount.put(position, count);
2183 24 Apr 06 nicklas 118       }
2183 24 Apr 06 nicklas 119     }
2183 24 Apr 06 nicklas 120     catch (SQLException ex)
2183 24 Apr 06 nicklas 121     {
2183 24 Apr 06 nicklas 122       throw new BaseException(ex);
2183 24 Apr 06 nicklas 123     }
2183 24 Apr 06 nicklas 124   }
2183 24 Apr 06 nicklas 125   
2183 24 Apr 06 nicklas 126   /**
2778 24 Oct 06 nicklas 127     We need the position which is in column 2 (already selected). If the limits
2778 24 Oct 06 nicklas 128     leave a gap we also need to know if a spot matches the filter or not.
2183 24 Apr 06 nicklas 129   */
6127 14 Sep 12 nicklas 130   @Override
2183 24 Apr 06 nicklas 131   public void configureQuery(SqlQuery query)
2778 24 Oct 06 nicklas 132   {
2778 24 Oct 06 nicklas 133     if (includeLimit > excludeLimit)
2778 24 Oct 06 nicklas 134     {
2778 24 Oct 06 nicklas 135       // Case statment that returns 1 if spot matches filter, 0 otherwise
2778 24 Oct 06 nicklas 136       WhenStatement matches = new WhenStatement(filter, Expressions.integer(1));
2778 24 Oct 06 nicklas 137       query.select(
2778 24 Oct 06 nicklas 138         Selects.expression(
2778 24 Oct 06 nicklas 139           Expressions.caseWhen(
2778 24 Oct 06 nicklas 140             Expressions.integer(0), 
2778 24 Oct 06 nicklas 141             new WhenStatement[] { matches } 
2778 24 Oct 06 nicklas 142           )
2778 24 Oct 06 nicklas 143         , "matches")
2778 24 Oct 06 nicklas 144       );
2778 24 Oct 06 nicklas 145     }
2778 24 Oct 06 nicklas 146   }
2183 24 Apr 06 nicklas 147   
2183 24 Apr 06 nicklas 148   /**
2222 09 May 06 nicklas 149     Always true.
2222 09 May 06 nicklas 150   */
6127 14 Sep 12 nicklas 151   @Override
2222 09 May 06 nicklas 152   public boolean useIncludeSpot()
2222 09 May 06 nicklas 153   {
2222 09 May 06 nicklas 154     return true;
2222 09 May 06 nicklas 155   }
2222 09 May 06 nicklas 156   
2222 09 May 06 nicklas 157   /**
2183 24 Apr 06 nicklas 158     Check if a spot should be included in the filtered output or not.
2183 24 Apr 06 nicklas 159     
2183 24 Apr 06 nicklas 160     @param data The current data row to check
2183 24 Apr 06 nicklas 161     @return TRUE if the spot passed the filter, FALSE otherwise
2183 24 Apr 06 nicklas 162   */
6127 14 Sep 12 nicklas 163   @Override
2183 24 Apr 06 nicklas 164   public boolean includeSpot(SqlResult data)
2183 24 Apr 06 nicklas 165     throws SQLException
2183 24 Apr 06 nicklas 166   {
2183 24 Apr 06 nicklas 167     int position = data.getInt(2);
2183 24 Apr 06 nicklas 168     Integer count = positionCount.get(position);
2778 24 Oct 06 nicklas 169     boolean match = false;
2778 24 Oct 06 nicklas 170     if (count != null)
2778 24 Oct 06 nicklas 171     {
2778 24 Oct 06 nicklas 172       if (count < excludeLimit)
2778 24 Oct 06 nicklas 173       {
2778 24 Oct 06 nicklas 174         match = false;
2778 24 Oct 06 nicklas 175       }
2778 24 Oct 06 nicklas 176       else if (count >= includeLimit)
2778 24 Oct 06 nicklas 177       {
2778 24 Oct 06 nicklas 178         match = true;
2778 24 Oct 06 nicklas 179       }
2778 24 Oct 06 nicklas 180       else // excludeLimit <= count < includeLimit
2778 24 Oct 06 nicklas 181       {
2778 24 Oct 06 nicklas 182         match = data.getInt(3) == 1;
2778 24 Oct 06 nicklas 183       }
2778 24 Oct 06 nicklas 184     }
2778 24 Oct 06 nicklas 185     return match;
2183 24 Apr 06 nicklas 186   }
2183 24 Apr 06 nicklas 187 }