src/core/net/sf/basedb/util/importer/spotdata/BaseFileInfo.java

Code
Comments
Other
Rev Date Author Line
5093 10 Sep 09 nicklas 1 /**
5093 10 Sep 09 nicklas 2   $Id$
5093 10 Sep 09 nicklas 3
5093 10 Sep 09 nicklas 4   Copyright (C) 2009 Nicklas Nordborg
5093 10 Sep 09 nicklas 5
5093 10 Sep 09 nicklas 6   This file is part of BASE - BioArray Software Environment.
5093 10 Sep 09 nicklas 7   Available at http://base.thep.lu.se/
5093 10 Sep 09 nicklas 8
5093 10 Sep 09 nicklas 9   BASE is free software; you can redistribute it and/or
5093 10 Sep 09 nicklas 10   modify it under the terms of the GNU General Public License
5093 10 Sep 09 nicklas 11   as published by the Free Software Foundation; either version 3
5093 10 Sep 09 nicklas 12   of the License, or (at your option) any later version.
5093 10 Sep 09 nicklas 13
5093 10 Sep 09 nicklas 14   BASE is distributed in the hope that it will be useful,
5093 10 Sep 09 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
5093 10 Sep 09 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5093 10 Sep 09 nicklas 17   GNU General Public License for more details.
5093 10 Sep 09 nicklas 18
5093 10 Sep 09 nicklas 19   You should have received a copy of the GNU General Public License
5093 10 Sep 09 nicklas 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
5093 10 Sep 09 nicklas 21 */
5093 10 Sep 09 nicklas 22 package net.sf.basedb.util.importer.spotdata;
5093 10 Sep 09 nicklas 23
5093 10 Sep 09 nicklas 24 import java.sql.SQLException;
5093 10 Sep 09 nicklas 25 import java.util.ArrayList;
5093 10 Sep 09 nicklas 26 import java.util.Collection;
5093 10 Sep 09 nicklas 27 import java.util.HashMap;
5093 10 Sep 09 nicklas 28 import java.util.LinkedList;
5093 10 Sep 09 nicklas 29 import java.util.List;
5093 10 Sep 09 nicklas 30 import java.util.Map;
5093 10 Sep 09 nicklas 31 import java.util.Set;
5093 10 Sep 09 nicklas 32
5093 10 Sep 09 nicklas 33 import net.sf.basedb.core.BioAssay;
5093 10 Sep 09 nicklas 34 import net.sf.basedb.core.BioAssaySet;
5093 10 Sep 09 nicklas 35 import net.sf.basedb.core.DatabaseException;
5093 10 Sep 09 nicklas 36 import net.sf.basedb.core.DbControl;
5093 10 Sep 09 nicklas 37 import net.sf.basedb.core.DynamicQuery;
5093 10 Sep 09 nicklas 38 import net.sf.basedb.core.DynamicResultIterator;
5093 10 Sep 09 nicklas 39 import net.sf.basedb.core.ExtraValueType;
5093 10 Sep 09 nicklas 40 import net.sf.basedb.core.ItemNotFoundException;
5093 10 Sep 09 nicklas 41 import net.sf.basedb.core.Type;
5093 10 Sep 09 nicklas 42 import net.sf.basedb.core.VirtualColumn;
5093 10 Sep 09 nicklas 43 import net.sf.basedb.core.query.Dynamic;
5093 10 Sep 09 nicklas 44 import net.sf.basedb.core.query.SqlResult;
5093 10 Sep 09 nicklas 45 import net.sf.basedb.util.Diff3;
5374 03 Aug 10 nicklas 46 import net.sf.basedb.util.importer.FileWrapper;
5093 10 Sep 09 nicklas 47
5093 10 Sep 09 nicklas 48 /**
5093 10 Sep 09 nicklas 49   Collects information about a BASEfile as it gets parsed
5093 10 Sep 09 nicklas 50   by a {@link BaseFileImporter}. Information in one section is
5093 10 Sep 09 nicklas 51   often needed when parsing other sections or after the parsing 
5093 10 Sep 09 nicklas 52   has been completed.
5093 10 Sep 09 nicklas 53
5093 10 Sep 09 nicklas 54   @author Nicklas
5093 10 Sep 09 nicklas 55   @version 2.14
5093 10 Sep 09 nicklas 56   @base.modified $Date$
5093 10 Sep 09 nicklas 57 */
5093 10 Sep 09 nicklas 58 public class BaseFileInfo
5093 10 Sep 09 nicklas 59 {
5374 03 Aug 10 nicklas 60   private final FileWrapper file;
5093 10 Sep 09 nicklas 61   
5093 10 Sep 09 nicklas 62   // Information about child assays
5093 10 Sep 09 nicklas 63   private boolean assaysHaveParentAssaysMapping;
5093 10 Sep 09 nicklas 64   private Map<Integer, ChildBioAssay> childAssays;
5093 10 Sep 09 nicklas 65   
5093 10 Sep 09 nicklas 66   // Information about parent bioassay set
5093 10 Sep 09 nicklas 67   private boolean parentHasNullReporter;
5093 10 Sep 09 nicklas 68   private boolean parentHasZeroReporter;
5689 11 Aug 11 nicklas 69   // Position/reporter mapping: key = position, value=reporter id
5093 10 Sep 09 nicklas 70   private Map<Integer, Integer> parentReporterPositions;
5093 10 Sep 09 nicklas 71   private Map<Short, List<Short>> parentChildColumnMapping;
5093 10 Sep 09 nicklas 72   
5093 10 Sep 09 nicklas 73   // Information about spot sections
5093 10 Sep 09 nicklas 74   private Map<Integer, SpotSectionInfo> spotSectionInfo;
5093 10 Sep 09 nicklas 75   private Map<String, ExtraValueType> extraFloats;
5093 10 Sep 09 nicklas 76   
5093 10 Sep 09 nicklas 77   // Information about child spotdata
5093 10 Sep 09 nicklas 78   private boolean childHasDifferentReporterPositionMapping;
5689 11 Aug 11 nicklas 79   // Position/reporter mapping: key = position, value=reporter id
5093 10 Sep 09 nicklas 80   private Map<Integer, Integer> childReporterPositions;
5093 10 Sep 09 nicklas 81   
5093 10 Sep 09 nicklas 82   
5093 10 Sep 09 nicklas 83   /**
5093 10 Sep 09 nicklas 84     The source file which should be a BASEfile.
5374 03 Aug 10 nicklas 85     @since 2.16
5374 03 Aug 10 nicklas 86   */
5374 03 Aug 10 nicklas 87   public BaseFileInfo(FileWrapper file)
5374 03 Aug 10 nicklas 88   {
5093 10 Sep 09 nicklas 89     this.file = file;
5093 10 Sep 09 nicklas 90   }
5093 10 Sep 09 nicklas 91   
5093 10 Sep 09 nicklas 92   /**
5093 10 Sep 09 nicklas 93     Get the name of the file.
5093 10 Sep 09 nicklas 94   */
5093 10 Sep 09 nicklas 95   public String getName()
5093 10 Sep 09 nicklas 96   {
5093 10 Sep 09 nicklas 97     return file.getName();
5093 10 Sep 09 nicklas 98   }
5093 10 Sep 09 nicklas 99   
5093 10 Sep 09 nicklas 100   /**
5093 10 Sep 09 nicklas 101     Get the character set used by the file, or null if not known.
5093 10 Sep 09 nicklas 102   */
5093 10 Sep 09 nicklas 103   public String getCharacterSet()
5093 10 Sep 09 nicklas 104   {
5093 10 Sep 09 nicklas 105     return file.getCharacterSet();
5093 10 Sep 09 nicklas 106   }
5093 10 Sep 09 nicklas 107   
5093 10 Sep 09 nicklas 108   /**
5093 10 Sep 09 nicklas 109     Get the file size.
5093 10 Sep 09 nicklas 110    */
5093 10 Sep 09 nicklas 111   public long getSize()
5093 10 Sep 09 nicklas 112   {
5093 10 Sep 09 nicklas 113     return file.getSize();
5093 10 Sep 09 nicklas 114   }
5093 10 Sep 09 nicklas 115   
5093 10 Sep 09 nicklas 116   /**
5093 10 Sep 09 nicklas 117     Set a flag that indicates if the BASEfile includes a mapping
5093 10 Sep 09 nicklas 118     from child to parent assays.
5093 10 Sep 09 nicklas 119   */
5093 10 Sep 09 nicklas 120   public void setAssaysHaveParentAssaysMapping(boolean haveMapping)
5093 10 Sep 09 nicklas 121   {
5093 10 Sep 09 nicklas 122     this.assaysHaveParentAssaysMapping = haveMapping;
5093 10 Sep 09 nicklas 123   }
5093 10 Sep 09 nicklas 124
5093 10 Sep 09 nicklas 125   /**
5093 10 Sep 09 nicklas 126     A flag that indicates if the BASEfile includes a mapping
5093 10 Sep 09 nicklas 127     from child to parent assays.
5093 10 Sep 09 nicklas 128   */
5093 10 Sep 09 nicklas 129   public boolean getAssaysHaveParentAssaysMapping()
5093 10 Sep 09 nicklas 130   {
5093 10 Sep 09 nicklas 131     return assaysHaveParentAssaysMapping;
5093 10 Sep 09 nicklas 132   }
5093 10 Sep 09 nicklas 133
5093 10 Sep 09 nicklas 134   /**
5093 10 Sep 09 nicklas 135     Add information about a child assay.
5093 10 Sep 09 nicklas 136     @param child Information about the child assay
5093 10 Sep 09 nicklas 137     @return TRUE if the child was added, FALSE if a child with 
5093 10 Sep 09 nicklas 138       the same ID already exists
5093 10 Sep 09 nicklas 139   */
5093 10 Sep 09 nicklas 140   public boolean addChildAssay(ChildBioAssay child)
5093 10 Sep 09 nicklas 141   {
5093 10 Sep 09 nicklas 142     if (childAssays == null) childAssays = new HashMap<Integer, ChildBioAssay>();
5093 10 Sep 09 nicklas 143     if (childAssays.containsKey(child.getFileId())) return false;
5093 10 Sep 09 nicklas 144     childAssays.put(child.getFileId(), child);
5093 10 Sep 09 nicklas 145     return true;
5093 10 Sep 09 nicklas 146   }
5093 10 Sep 09 nicklas 147   
5093 10 Sep 09 nicklas 148   /**
5093 10 Sep 09 nicklas 149     Get information about all child bioassays referenced in the file.
5093 10 Sep 09 nicklas 150   */
5093 10 Sep 09 nicklas 151   public Collection<ChildBioAssay> getChildAssays()
5093 10 Sep 09 nicklas 152   {
5093 10 Sep 09 nicklas 153     return childAssays == null ? null : childAssays.values();
5093 10 Sep 09 nicklas 154   }
5093 10 Sep 09 nicklas 155   
5093 10 Sep 09 nicklas 156   /**
5093 10 Sep 09 nicklas 157      Get the child bioassay with the given id (from the BASEfile).
5093 10 Sep 09 nicklas 158     @param id The ID in the BASEfile
5093 10 Sep 09 nicklas 159     @return A ChildBioAssay or null
5093 10 Sep 09 nicklas 160   */
5093 10 Sep 09 nicklas 161   public ChildBioAssay getChildAssay(int id)
5093 10 Sep 09 nicklas 162   {
5093 10 Sep 09 nicklas 163     return childAssays == null ? null : childAssays.get(id);
5093 10 Sep 09 nicklas 164   }
5093 10 Sep 09 nicklas 165   
5093 10 Sep 09 nicklas 166   
5093 10 Sep 09 nicklas 167   /**
5093 10 Sep 09 nicklas 168     Checks that the bioassay with the given id exists in the database. 
5093 10 Sep 09 nicklas 169     If not, an exception is thrown.
5093 10 Sep 09 nicklas 170     @param dc The DbControl to use
5093 10 Sep 09 nicklas 171     @param id The id of the bioassay
5093 10 Sep 09 nicklas 172     @param line The current line
5093 10 Sep 09 nicklas 173     @throws ItemNotFoundException If the bioassay doesn't exists in the
5093 10 Sep 09 nicklas 174       database
5093 10 Sep 09 nicklas 175   */
5093 10 Sep 09 nicklas 176   public void checkBioAssay(DbControl dc, int id, int line)
5093 10 Sep 09 nicklas 177   {
5093 10 Sep 09 nicklas 178     try
5093 10 Sep 09 nicklas 179     {
5093 10 Sep 09 nicklas 180       BioAssay.getById(dc, id);
5093 10 Sep 09 nicklas 181     }
5093 10 Sep 09 nicklas 182     catch (ItemNotFoundException ex)
5093 10 Sep 09 nicklas 183     {
5093 10 Sep 09 nicklas 184       throw new ItemNotFoundException("Can't find bioassay '" + id +
5093 10 Sep 09 nicklas 185         "' in section 'assays' at line " + line + " in file '" + getName() + "'");
5093 10 Sep 09 nicklas 186     }
5093 10 Sep 09 nicklas 187   }
5093 10 Sep 09 nicklas 188   
5093 10 Sep 09 nicklas 189   /**
5093 10 Sep 09 nicklas 190     Set a flag indicating that at least one position in the parent bioassay 
5093 10 Sep 09 nicklas 191     set has a null reporter.
5093 10 Sep 09 nicklas 192     @param parentHasNullReporter TRUE if there is a position with a null reporter,
5093 10 Sep 09 nicklas 193       FALSE otherwise
5093 10 Sep 09 nicklas 194     @see #loadParentReporterPositions(DbControl, BioAssaySet)
5093 10 Sep 09 nicklas 195   */
5093 10 Sep 09 nicklas 196   public void setParentHasNullReporter(boolean parentHasNullReporter)
5093 10 Sep 09 nicklas 197   {
5093 10 Sep 09 nicklas 198     this.parentHasNullReporter = parentHasNullReporter;
5093 10 Sep 09 nicklas 199   }
5093 10 Sep 09 nicklas 200   
5093 10 Sep 09 nicklas 201   /**
5093 10 Sep 09 nicklas 202     A flag that indicates if at least one position in the parent bioassay
5093 10 Sep 09 nicklas 203     set has a null reporter or not. We need to know this because some BASE 1
5093 10 Sep 09 nicklas 204     plug-ins convert a null reporter to 0 and in most cases it is safe
5093 10 Sep 09 nicklas 205     to convert it back, but only if the parent had a null reporter but not
5093 10 Sep 09 nicklas 206     a '0' reporter to begin with.
5093 10 Sep 09 nicklas 207     @see #getParentHasZeroReporter()
5093 10 Sep 09 nicklas 208   */
5093 10 Sep 09 nicklas 209   public boolean getParentHasNullReporter()
5093 10 Sep 09 nicklas 210   {
5093 10 Sep 09 nicklas 211     return parentHasNullReporter;
5093 10 Sep 09 nicklas 212   }
5093 10 Sep 09 nicklas 213   
5093 10 Sep 09 nicklas 214   /**
5093 10 Sep 09 nicklas 215     Set a flag indicating that at least one position in the parent bioassay
5093 10 Sep 09 nicklas 216     set has a reporter with ID=0.
5093 10 Sep 09 nicklas 217   */
5093 10 Sep 09 nicklas 218   public void setParentHasZeroReporter(boolean parentHasZeroReporter)
5093 10 Sep 09 nicklas 219   {
5093 10 Sep 09 nicklas 220     this.parentHasZeroReporter = parentHasZeroReporter;
5093 10 Sep 09 nicklas 221   }
5093 10 Sep 09 nicklas 222   
5093 10 Sep 09 nicklas 223   /**
5093 10 Sep 09 nicklas 224     A flag that indicates if at least one position in the parent bioassay
5093 10 Sep 09 nicklas 225     set has a reporter with ID=0.
5093 10 Sep 09 nicklas 226     @see #getParentHasNullReporter()
5093 10 Sep 09 nicklas 227   */
5093 10 Sep 09 nicklas 228   public boolean getParentHasZeroReporter()
5093 10 Sep 09 nicklas 229   {
5093 10 Sep 09 nicklas 230     return parentHasZeroReporter;
5093 10 Sep 09 nicklas 231   }
5093 10 Sep 09 nicklas 232   
5093 10 Sep 09 nicklas 233   /**
5093 10 Sep 09 nicklas 234     Load position/reporter mapping from the parent bioassay set. This
5093 10 Sep 09 nicklas 235     will also set the {@link #getParentHasNullReporter()}/{@link #getParentHasZeroReporter()}
5093 10 Sep 09 nicklas 236     flags.
5093 10 Sep 09 nicklas 237     
5093 10 Sep 09 nicklas 238     @param dc A DbControl to use
5093 10 Sep 09 nicklas 239     @param parent The parent bioassay set
5093 10 Sep 09 nicklas 240   */
5093 10 Sep 09 nicklas 241   public void loadParentReporterPositions(DbControl dc, BioAssaySet parent)
5093 10 Sep 09 nicklas 242   {
5093 10 Sep 09 nicklas 243     if (parentReporterPositions != null) return;
5093 10 Sep 09 nicklas 244     
5093 10 Sep 09 nicklas 245     parentReporterPositions = new HashMap<Integer, Integer>();
5093 10 Sep 09 nicklas 246     DynamicQuery positionQuery = parent.getPositionData();
5093 10 Sep 09 nicklas 247     positionQuery.select(Dynamic.select(VirtualColumn.POSITION));
5093 10 Sep 09 nicklas 248     positionQuery.select(Dynamic.select(VirtualColumn.REPORTER_ID));
5093 10 Sep 09 nicklas 249     DynamicResultIterator positionQueryIterator = positionQuery.iterate(dc);
5093 10 Sep 09 nicklas 250     try
5093 10 Sep 09 nicklas 251     {
5093 10 Sep 09 nicklas 252       while (positionQueryIterator.hasNext())
5093 10 Sep 09 nicklas 253       {
5093 10 Sep 09 nicklas 254         SqlResult result = positionQueryIterator.next();
5093 10 Sep 09 nicklas 255         Integer reporterId = (Integer)result.getObject(2);
5093 10 Sep 09 nicklas 256         if (reporterId == null) 
5093 10 Sep 09 nicklas 257         {
5093 10 Sep 09 nicklas 258           setParentHasNullReporter(true);
5093 10 Sep 09 nicklas 259         }
5093 10 Sep 09 nicklas 260         else if (reporterId.intValue() == 0)
5093 10 Sep 09 nicklas 261         {
5093 10 Sep 09 nicklas 262           setParentHasZeroReporter(true);
5093 10 Sep 09 nicklas 263         }
5093 10 Sep 09 nicklas 264         parentReporterPositions.put(result.getInt(1), reporterId);
5093 10 Sep 09 nicklas 265       }
5093 10 Sep 09 nicklas 266     }
5093 10 Sep 09 nicklas 267     catch (SQLException ex)
5093 10 Sep 09 nicklas 268     {
5093 10 Sep 09 nicklas 269       throw new DatabaseException(ex);
5093 10 Sep 09 nicklas 270     }
5093 10 Sep 09 nicklas 271   }
5093 10 Sep 09 nicklas 272   
5093 10 Sep 09 nicklas 273   /**
5093 10 Sep 09 nicklas 274     Set a flag that indicates if the child data has a different position/reporter
5093 10 Sep 09 nicklas 275     mapping than the parent bioassay set.
5093 10 Sep 09 nicklas 276     @see #addChildReporter(Integer, Integer)
5093 10 Sep 09 nicklas 277   */
5093 10 Sep 09 nicklas 278   public void setChildHasDifferentReporterPositionMapping(boolean flag)
5093 10 Sep 09 nicklas 279   {
5093 10 Sep 09 nicklas 280     this.childHasDifferentReporterPositionMapping = flag;
5093 10 Sep 09 nicklas 281   }
5093 10 Sep 09 nicklas 282   
5093 10 Sep 09 nicklas 283   /**
5093 10 Sep 09 nicklas 284     A flag that indicates if the child data has a different position/reporter
5093 10 Sep 09 nicklas 285     mapping than the parent bioassay set.
5093 10 Sep 09 nicklas 286   */
5093 10 Sep 09 nicklas 287   public boolean getChildHasDifferentReporterPositionMapping()
5093 10 Sep 09 nicklas 288   {
5093 10 Sep 09 nicklas 289     return childHasDifferentReporterPositionMapping;
5093 10 Sep 09 nicklas 290   }
5093 10 Sep 09 nicklas 291   
5093 10 Sep 09 nicklas 292   /**
5093 10 Sep 09 nicklas 293     Add a child position/reporter mapping from the parsed BASEfile.
5093 10 Sep 09 nicklas 294     The added mapping will be checked against the parent position/reporter
5093 10 Sep 09 nicklas 295     mapping and the {@link #getChildHasDifferentReporterPositionMapping()}
5093 10 Sep 09 nicklas 296     flag is set if the mapping has changed.
5093 10 Sep 09 nicklas 297     <p>
5093 10 Sep 09 nicklas 298     If a mapping for the given position already exists, a check is made
5093 10 Sep 09 nicklas 299     if the mapping is identical or different. If the mapping is different
5093 10 Sep 09 nicklas 300     the reporter id of the already existing mapping is returned. It is
5093 10 Sep 09 nicklas 301     up to the called to take any appropriate action in this case (usually;
5093 10 Sep 09 nicklas 302     throw an exception). If the mapping doesn't exist or if the mapping
5093 10 Sep 09 nicklas 303     is identical the 'reporterId' value is returned. Thus, it is easy to
5093 10 Sep 09 nicklas 304     check for success by simply comparing:
5093 10 Sep 09 nicklas 305 <pre class="code">    
5093 10 Sep 09 nicklas 306 if (reporterId != addChildReporter(position, reporterId))
5093 10 Sep 09 nicklas 307 {
5093 10 Sep 09 nicklas 308    // ... throw exception
5093 10 Sep 09 nicklas 309 }
5093 10 Sep 09 nicklas 310 </pre>    
5093 10 Sep 09 nicklas 311     @param position The position value
5093 10 Sep 09 nicklas 312     @param reporterId The ID of the reporter
5093 10 Sep 09 nicklas 313     @return The reporterId (same instance) if the mapping is new or
5093 10 Sep 09 nicklas 314       if an identical mapping already exists. The reporer ID of an
5093 10 Sep 09 nicklas 315       existing mapping if it is different. 
5093 10 Sep 09 nicklas 316   */
5093 10 Sep 09 nicklas 317   public Integer addChildReporter(Integer position, Integer reporterId)
5093 10 Sep 09 nicklas 318   {
5093 10 Sep 09 nicklas 319   
5093 10 Sep 09 nicklas 320     // First we check if the position reporter is the same as for the parent
5093 10 Sep 09 nicklas 321     if (!childHasDifferentReporterPositionMapping)
5093 10 Sep 09 nicklas 322     {      
5093 10 Sep 09 nicklas 323       Integer parentReporterId = parentReporterPositions.get(position);
5093 10 Sep 09 nicklas 324       if (!Diff3.isEqualOrNull(reporterId, parentReporterId))
5093 10 Sep 09 nicklas 325       {
5093 10 Sep 09 nicklas 326         setChildHasDifferentReporterPositionMapping(true);
5093 10 Sep 09 nicklas 327         parentReporterPositions.clear();
5093 10 Sep 09 nicklas 328       }
5093 10 Sep 09 nicklas 329     }
5093 10 Sep 09 nicklas 330     
5093 10 Sep 09 nicklas 331     Integer returnValue = reporterId;
5093 10 Sep 09 nicklas 332     
5093 10 Sep 09 nicklas 333     // Then, we check if the position has already been assigned a 
5093 10 Sep 09 nicklas 334     // reporter or not
5093 10 Sep 09 nicklas 335     if (childReporterPositions == null) childReporterPositions = new HashMap<Integer, Integer>();
5093 10 Sep 09 nicklas 336     if (!childReporterPositions.containsKey(position))
5093 10 Sep 09 nicklas 337     {
5093 10 Sep 09 nicklas 338       // ... new position
5093 10 Sep 09 nicklas 339       childReporterPositions.put(position, reporterId);
5093 10 Sep 09 nicklas 340     }
5093 10 Sep 09 nicklas 341     else
5093 10 Sep 09 nicklas 342     {
5093 10 Sep 09 nicklas 343       // Error if same position has already been assigned a different reporter
5093 10 Sep 09 nicklas 344       Integer registeredReporterId = childReporterPositions.get(position);
5093 10 Sep 09 nicklas 345       if (!Diff3.isEqualOrNull(reporterId, registeredReporterId))
5093 10 Sep 09 nicklas 346       {
5093 10 Sep 09 nicklas 347         returnValue = registeredReporterId;
5093 10 Sep 09 nicklas 348       }
5093 10 Sep 09 nicklas 349     }
5093 10 Sep 09 nicklas 350     return returnValue;
5093 10 Sep 09 nicklas 351   }
5093 10 Sep 09 nicklas 352
5093 10 Sep 09 nicklas 353   /**
5093 10 Sep 09 nicklas 354     Get a map with all added child position/reporter mappings. 
5093 10 Sep 09 nicklas 355     The key is the position value and the value is the reporter id.
5093 10 Sep 09 nicklas 356   */
5093 10 Sep 09 nicklas 357   public Map<Integer, Integer> getChildReporterPositions()
5093 10 Sep 09 nicklas 358   {
5093 10 Sep 09 nicklas 359     return childReporterPositions;
5093 10 Sep 09 nicklas 360   }
5093 10 Sep 09 nicklas 361   
5093 10 Sep 09 nicklas 362   /**
5093 10 Sep 09 nicklas 363     Maps a parent data cube column to a child cube column.
5093 10 Sep 09 nicklas 364     Note! A parent may map to multiple childs, and a child may 
5093 10 Sep 09 nicklas 365     have multiple parents.
5093 10 Sep 09 nicklas 366     
5093 10 Sep 09 nicklas 367     @param parentColumn The parent data cube column
5093 10 Sep 09 nicklas 368     @param childColumn The child data cube column
5093 10 Sep 09 nicklas 369   */
5093 10 Sep 09 nicklas 370   public void mapParentChildColumns(short parentColumn, short childColumn)
5093 10 Sep 09 nicklas 371   {
5093 10 Sep 09 nicklas 372     if (parentChildColumnMapping == null) 
5093 10 Sep 09 nicklas 373     {
5093 10 Sep 09 nicklas 374       parentChildColumnMapping = new HashMap<Short, List<Short>>();
5093 10 Sep 09 nicklas 375     }
5093 10 Sep 09 nicklas 376     List<Short> childColumns = parentChildColumnMapping.get(parentColumn);
5093 10 Sep 09 nicklas 377     if (childColumns == null) childColumns = new ArrayList<Short>();
5093 10 Sep 09 nicklas 378     childColumns.add(childColumn);
5093 10 Sep 09 nicklas 379     parentChildColumnMapping.put(parentColumn, childColumns);
5093 10 Sep 09 nicklas 380   }
5093 10 Sep 09 nicklas 381   
5093 10 Sep 09 nicklas 382   /**
5093 10 Sep 09 nicklas 383     Get all child columns that have been mapped to the specified parent
5093 10 Sep 09 nicklas 384     column.
5093 10 Sep 09 nicklas 385     @return A list or null if no mapping exists
5093 10 Sep 09 nicklas 386   */
5093 10 Sep 09 nicklas 387   public List<Short> getChildColumns(short parentColumn)
5093 10 Sep 09 nicklas 388   {
5093 10 Sep 09 nicklas 389     return parentChildColumnMapping == null ? 
5093 10 Sep 09 nicklas 390       null : parentChildColumnMapping.get(parentColumn);
5093 10 Sep 09 nicklas 391   }
5093 10 Sep 09 nicklas 392   
5093 10 Sep 09 nicklas 393   /**
5093 10 Sep 09 nicklas 394     Adds information about a 'spot' section.
5093 10 Sep 09 nicklas 395     @param spotSection The ordinal number of the spot section as it
5093 10 Sep 09 nicklas 396       appears in the BASEfile, starting with 1
5093 10 Sep 09 nicklas 397     @param info The information
5093 10 Sep 09 nicklas 398   */
5093 10 Sep 09 nicklas 399   public void addSpotSectionInfo(int spotSection, SpotSectionInfo info)
5093 10 Sep 09 nicklas 400   {
5093 10 Sep 09 nicklas 401     if (spotSectionInfo == null) spotSectionInfo = new HashMap<Integer, SpotSectionInfo>();
5093 10 Sep 09 nicklas 402     spotSectionInfo.put(spotSection, info);
5093 10 Sep 09 nicklas 403   }
5093 10 Sep 09 nicklas 404   
5093 10 Sep 09 nicklas 405   /**
5093 10 Sep 09 nicklas 406     Get information about a spot section.
5093 10 Sep 09 nicklas 407     @param spotSection The ordinal number of the spot section as it
5093 10 Sep 09 nicklas 408       appears in the BASEfile, starting with 1
5093 10 Sep 09 nicklas 409   */
5093 10 Sep 09 nicklas 410   public SpotSectionInfo getSpotSectionInfo(int spotSection)
5093 10 Sep 09 nicklas 411   {
5093 10 Sep 09 nicklas 412     return spotSectionInfo.get(spotSection);
5093 10 Sep 09 nicklas 413   }
5093 10 Sep 09 nicklas 414   
5093 10 Sep 09 nicklas 415   /**
5093 10 Sep 09 nicklas 416     Add information about an extra float value that appears in the
5093 10 Sep 09 nicklas 417     BASEfile. This method will check if the an {@link ExtraValueType}
5093 10 Sep 09 nicklas 418     with the given external id exists. If not, a new float-type extra
5093 10 Sep 09 nicklas 419     value type is created.
5093 10 Sep 09 nicklas 420     @param dc A DbControl object to use for database access
5093 10 Sep 09 nicklas 421     @param extraFloatId The external id of an extra value type
5093 10 Sep 09 nicklas 422   */
5093 10 Sep 09 nicklas 423   public ExtraValueType addExtraFloat(DbControl dc, String extraFloatId)
5093 10 Sep 09 nicklas 424   {
5093 10 Sep 09 nicklas 425     if (extraFloats == null) extraFloats = new HashMap<String, ExtraValueType>();
5093 10 Sep 09 nicklas 426     ExtraValueType extra = extraFloats.get(extraFloatId);
5093 10 Sep 09 nicklas 427     if (extra == null)
5093 10 Sep 09 nicklas 428     {
5093 10 Sep 09 nicklas 429       try
5093 10 Sep 09 nicklas 430       {
5093 10 Sep 09 nicklas 431         extra = ExtraValueType.getByExternalId(dc, extraFloatId);
5093 10 Sep 09 nicklas 432       }
5093 10 Sep 09 nicklas 433       catch (ItemNotFoundException e)
5093 10 Sep 09 nicklas 434       {
5093 10 Sep 09 nicklas 435         extra = ExtraValueType.getNew(dc, extraFloatId, Type.FLOAT);
5093 10 Sep 09 nicklas 436         extra.setName(extraFloatId);
5093 10 Sep 09 nicklas 437         dc.saveItem(extra);
5093 10 Sep 09 nicklas 438       }
5093 10 Sep 09 nicklas 439       extraFloats.put(extraFloatId, extra);
5093 10 Sep 09 nicklas 440     }
5093 10 Sep 09 nicklas 441     return extra;
5093 10 Sep 09 nicklas 442   }
5093 10 Sep 09 nicklas 443   
5093 10 Sep 09 nicklas 444   /**
5093 10 Sep 09 nicklas 445     Get the extra value type that has the given external id. 
5093 10 Sep 09 nicklas 446     The extra float must have been added with {@link #addExtraFloat(DbControl, String)}
5093 10 Sep 09 nicklas 447     before.
5093 10 Sep 09 nicklas 448     
5093 10 Sep 09 nicklas 449     @param extraFloatId The external id of an extra value type
5093 10 Sep 09 nicklas 450     @return The extra value type, or null
5093 10 Sep 09 nicklas 451   */
5093 10 Sep 09 nicklas 452   public ExtraValueType getExtraFloat(String extraFloatId)
5093 10 Sep 09 nicklas 453   {
5093 10 Sep 09 nicklas 454     return extraFloats == null ? null : extraFloats.get(extraFloatId);
5093 10 Sep 09 nicklas 455   }
5093 10 Sep 09 nicklas 456   
5093 10 Sep 09 nicklas 457   /**
5093 10 Sep 09 nicklas 458     Keeps information about a new child bioassay from
5093 10 Sep 09 nicklas 459     the 'assays' section or 'spot' sections.
5093 10 Sep 09 nicklas 460   */
5093 10 Sep 09 nicklas 461   public static class ChildBioAssay
5093 10 Sep 09 nicklas 462   {
5093 10 Sep 09 nicklas 463     private int fileId;
5093 10 Sep 09 nicklas 464     private String name;
5093 10 Sep 09 nicklas 465     private Set<Integer> parents;
5093 10 Sep 09 nicklas 466     private BioAssay child;
5093 10 Sep 09 nicklas 467     
5093 10 Sep 09 nicklas 468     /**
5093 10 Sep 09 nicklas 469       Create a new object.
5093 10 Sep 09 nicklas 470     */
5093 10 Sep 09 nicklas 471     public ChildBioAssay()
5093 10 Sep 09 nicklas 472     {}
5093 10 Sep 09 nicklas 473     
5093 10 Sep 09 nicklas 474     /**
5093 10 Sep 09 nicklas 475       Create a new object
5093 10 Sep 09 nicklas 476     */
5093 10 Sep 09 nicklas 477     public ChildBioAssay(int fileId)
5093 10 Sep 09 nicklas 478     {
5093 10 Sep 09 nicklas 479       this.fileId = fileId;
5093 10 Sep 09 nicklas 480     }
5093 10 Sep 09 nicklas 481     
5093 10 Sep 09 nicklas 482     /**
5093 10 Sep 09 nicklas 483       Get the id of the child bioassay as it appears in the 
5093 10 Sep 09 nicklas 484       BASEfile. This is either the same as the id of a parent bioassay
5093 10 Sep 09 nicklas 485       or an internal id only.
5093 10 Sep 09 nicklas 486     */
5093 10 Sep 09 nicklas 487     public int getFileId()
5093 10 Sep 09 nicklas 488     {
5093 10 Sep 09 nicklas 489       return fileId;
5093 10 Sep 09 nicklas 490     }
5093 10 Sep 09 nicklas 491     
5093 10 Sep 09 nicklas 492     /**
5093 10 Sep 09 nicklas 493       Set the id of the child bioassay as it appears in the BASEfile.
5093 10 Sep 09 nicklas 494     */
5093 10 Sep 09 nicklas 495     public void setFileId(int fileId)
5093 10 Sep 09 nicklas 496     {
5093 10 Sep 09 nicklas 497       this.fileId = fileId;
5093 10 Sep 09 nicklas 498     }
5093 10 Sep 09 nicklas 499     
5093 10 Sep 09 nicklas 500     /**
5093 10 Sep 09 nicklas 501       Get the name of the child bioassay. May return null if the
5093 10 Sep 09 nicklas 502       BASEfile doesn't specify a name in which case the child will
5093 10 Sep 09 nicklas 503       get the same name as it's parent.
5093 10 Sep 09 nicklas 504     */
5093 10 Sep 09 nicklas 505     public String getName()
5093 10 Sep 09 nicklas 506     {
5093 10 Sep 09 nicklas 507       return name;
5093 10 Sep 09 nicklas 508     }
5093 10 Sep 09 nicklas 509     
5093 10 Sep 09 nicklas 510     /**
5093 10 Sep 09 nicklas 511       Set the name of the child bioassay. If null, the child
5093 10 Sep 09 nicklas 512       will be given the same name as it's parent.
5093 10 Sep 09 nicklas 513     */
5093 10 Sep 09 nicklas 514     public void setName(String name)
5093 10 Sep 09 nicklas 515     {
5093 10 Sep 09 nicklas 516       this.name = name;
5093 10 Sep 09 nicklas 517     }
5093 10 Sep 09 nicklas 518     
5093 10 Sep 09 nicklas 519     /**
5093 10 Sep 09 nicklas 520       Get the parent assays of this child. If no parents has been 
5093 10 Sep 09 nicklas 521       specified, the parent assay is the one that has the same id
5093 10 Sep 09 nicklas 522       as the file id.
5093 10 Sep 09 nicklas 523     */
5093 10 Sep 09 nicklas 524     public Set<Integer> getParents()
5093 10 Sep 09 nicklas 525     {
5093 10 Sep 09 nicklas 526       return parents;
5093 10 Sep 09 nicklas 527     }
5093 10 Sep 09 nicklas 528     
5093 10 Sep 09 nicklas 529     /**
5093 10 Sep 09 nicklas 530       Set the parents for this child.
5093 10 Sep 09 nicklas 531     */
5093 10 Sep 09 nicklas 532     public void setParents(Set<Integer> parents)
5093 10 Sep 09 nicklas 533     {
5093 10 Sep 09 nicklas 534       this.parents = parents;
5093 10 Sep 09 nicklas 535     }
5093 10 Sep 09 nicklas 536     
5093 10 Sep 09 nicklas 537     /**
5093 10 Sep 09 nicklas 538       Get the real child bioassay object once it has been created
5093 10 Sep 09 nicklas 539       and scheduled for saving into the database.
5093 10 Sep 09 nicklas 540       @see BaseFileImporter#createChildBioAssays(DbControl, BioAssaySet, BaseFileInfo, boolean)
5093 10 Sep 09 nicklas 541     */
5093 10 Sep 09 nicklas 542     public BioAssay getChild()
5093 10 Sep 09 nicklas 543     {
5093 10 Sep 09 nicklas 544       return child;
5093 10 Sep 09 nicklas 545     }
5093 10 Sep 09 nicklas 546     
5093 10 Sep 09 nicklas 547     /**
5093 10 Sep 09 nicklas 548       Set the real child bioassay object.
5093 10 Sep 09 nicklas 549     */
5093 10 Sep 09 nicklas 550     public void setChild(BioAssay child)
5093 10 Sep 09 nicklas 551     {
5093 10 Sep 09 nicklas 552       this.child = child;
5093 10 Sep 09 nicklas 553     }
5093 10 Sep 09 nicklas 554     
5093 10 Sep 09 nicklas 555   }
5093 10 Sep 09 nicklas 556
5093 10 Sep 09 nicklas 557   /**
5093 10 Sep 09 nicklas 558     Keeps information about headers and more in a 'spot' section.
5093 10 Sep 09 nicklas 559   */
5093 10 Sep 09 nicklas 560   public static class SpotSectionInfo
5093 10 Sep 09 nicklas 561   {
5093 10 Sep 09 nicklas 562     private int positionIndex;
5093 10 Sep 09 nicklas 563     private int firstAssayFieldIndex;
5093 10 Sep 09 nicklas 564     private List<Integer> assays;
5093 10 Sep 09 nicklas 565     private List<String> assayFields;
5093 10 Sep 09 nicklas 566     private List<ExtraFloatParser> extraFloats;
5093 10 Sep 09 nicklas 567   
5093 10 Sep 09 nicklas 568     private SpotIntensityParser spiParser;
5093 10 Sep 09 nicklas 569   
5093 10 Sep 09 nicklas 570     /**
5093 10 Sep 09 nicklas 571       Creates a new object.
5093 10 Sep 09 nicklas 572     */
5093 10 Sep 09 nicklas 573     public SpotSectionInfo()
5093 10 Sep 09 nicklas 574     {}
5093 10 Sep 09 nicklas 575     
5093 10 Sep 09 nicklas 576     /**
5093 10 Sep 09 nicklas 577       The index of the 'position' data column.
5093 10 Sep 09 nicklas 578     */
5093 10 Sep 09 nicklas 579     public int getPositionIndex()
5093 10 Sep 09 nicklas 580     {
5093 10 Sep 09 nicklas 581       return positionIndex;
5093 10 Sep 09 nicklas 582     }
5093 10 Sep 09 nicklas 583     
5093 10 Sep 09 nicklas 584     /**
5093 10 Sep 09 nicklas 585       Set the column index of the 'position' data column.
5093 10 Sep 09 nicklas 586     */
5093 10 Sep 09 nicklas 587     public void setPositionIndex(int positionIndex)
5093 10 Sep 09 nicklas 588     {
5093 10 Sep 09 nicklas 589       this.positionIndex = positionIndex;
5093 10 Sep 09 nicklas 590     }
5093 10 Sep 09 nicklas 591     
5093 10 Sep 09 nicklas 592     /**
5093 10 Sep 09 nicklas 593       The index of the first data column that contains assay data.
5093 10 Sep 09 nicklas 594     */
5093 10 Sep 09 nicklas 595     public int getFirstAssayFieldIndex()
5093 10 Sep 09 nicklas 596     {
5093 10 Sep 09 nicklas 597       return firstAssayFieldIndex;
5093 10 Sep 09 nicklas 598     }
5093 10 Sep 09 nicklas 599     
5093 10 Sep 09 nicklas 600     /**
5093 10 Sep 09 nicklas 601       Set the index of the first data column that contains assay data.
5093 10 Sep 09 nicklas 602     */
5093 10 Sep 09 nicklas 603     public void setFirstAssayFieldIndex(int firstAssayFieldIndex)
5093 10 Sep 09 nicklas 604     {
5093 10 Sep 09 nicklas 605       this.firstAssayFieldIndex = firstAssayFieldIndex;
5093 10 Sep 09 nicklas 606     }
5093 10 Sep 09 nicklas 607
5093 10 Sep 09 nicklas 608     /**
5093 10 Sep 09 nicklas 609       Get a list with all assay data fields, in the order they
5093 10 Sep 09 nicklas 610       appear in the file.
5093 10 Sep 09 nicklas 611     */
5093 10 Sep 09 nicklas 612     public List<String> getAssayFields()
5093 10 Sep 09 nicklas 613     {
5093 10 Sep 09 nicklas 614       return assayFields;
5093 10 Sep 09 nicklas 615     }
5093 10 Sep 09 nicklas 616     
5093 10 Sep 09 nicklas 617     /**
5093 10 Sep 09 nicklas 618       Set the list of all assay data fields, in the order
5093 10 Sep 09 nicklas 619       the appear in the file.
5093 10 Sep 09 nicklas 620     */
5093 10 Sep 09 nicklas 621     public void setAssayFields(List<String> assayFields)
5093 10 Sep 09 nicklas 622     {
5093 10 Sep 09 nicklas 623       this.assayFields = assayFields;
5093 10 Sep 09 nicklas 624     }
5093 10 Sep 09 nicklas 625
5093 10 Sep 09 nicklas 626     /**
5093 10 Sep 09 nicklas 627       Get a list with the ID:s of all assays in the section,
5093 10 Sep 09 nicklas 628       in the order they appear in the data columns.
5093 10 Sep 09 nicklas 629     */
5093 10 Sep 09 nicklas 630     public List<Integer> getAssays()
5093 10 Sep 09 nicklas 631     {
5093 10 Sep 09 nicklas 632       return assays;
5093 10 Sep 09 nicklas 633     }
5093 10 Sep 09 nicklas 634     
5093 10 Sep 09 nicklas 635     /**
5093 10 Sep 09 nicklas 636       Set a list with the ID:s of all assays, in the
5093 10 Sep 09 nicklas 637       order the appearu in the data columns.
5093 10 Sep 09 nicklas 638     */
5093 10 Sep 09 nicklas 639     public void setAssays(List<Integer> assays)
5093 10 Sep 09 nicklas 640     {
5093 10 Sep 09 nicklas 641       this.assays = assays;
5093 10 Sep 09 nicklas 642     }
5093 10 Sep 09 nicklas 643     
5093 10 Sep 09 nicklas 644     /**
5093 10 Sep 09 nicklas 645       Get the spot intensity parser that should be used for
5093 10 Sep 09 nicklas 646       parsing spot intensities in this section.
5093 10 Sep 09 nicklas 647     */
5093 10 Sep 09 nicklas 648     public SpotIntensityParser getSpotIntensityParser()
5093 10 Sep 09 nicklas 649     {
5093 10 Sep 09 nicklas 650       return spiParser;
5093 10 Sep 09 nicklas 651     }
5093 10 Sep 09 nicklas 652     
5093 10 Sep 09 nicklas 653     /**
5093 10 Sep 09 nicklas 654       Set the spot intensity parser for the section.
5093 10 Sep 09 nicklas 655     */
5093 10 Sep 09 nicklas 656     public void setSpotIntensityParser(SpotIntensityParser spiParser)
5093 10 Sep 09 nicklas 657     {
5093 10 Sep 09 nicklas 658       this.spiParser = spiParser;
5093 10 Sep 09 nicklas 659     }
5093 10 Sep 09 nicklas 660
5093 10 Sep 09 nicklas 661     /**
5093 10 Sep 09 nicklas 662       Get the list of extra value parsers that exists for
5093 10 Sep 09 nicklas 663       this section.
5093 10 Sep 09 nicklas 664     */
5093 10 Sep 09 nicklas 665     public List<ExtraFloatParser> getExtraFloatParsers()
5093 10 Sep 09 nicklas 666     {
5093 10 Sep 09 nicklas 667       return extraFloats;
5093 10 Sep 09 nicklas 668     }
5093 10 Sep 09 nicklas 669   
5093 10 Sep 09 nicklas 670     /**
5093 10 Sep 09 nicklas 671       Add an extra value parser to this section.
5093 10 Sep 09 nicklas 672     */
5093 10 Sep 09 nicklas 673     public void addExtraFloatParser(ExtraFloatParser extraFloatParser)
5093 10 Sep 09 nicklas 674     {
5093 10 Sep 09 nicklas 675       if (extraFloats == null) extraFloats = new LinkedList<ExtraFloatParser>();
5093 10 Sep 09 nicklas 676       extraFloats.add(extraFloatParser);
5093 10 Sep 09 nicklas 677     }
5093 10 Sep 09 nicklas 678   
5093 10 Sep 09 nicklas 679   }
5093 10 Sep 09 nicklas 680 }