src/core/net/sf/basedb/util/export/spotdata/AbstractFieldConverter.java

Code
Comments
Other
Rev Date Author Line
5277 22 Mar 10 nicklas 1 /**
5277 22 Mar 10 nicklas 2   $Id $
5277 22 Mar 10 nicklas 3
5277 22 Mar 10 nicklas 4   Copyright (C) 2010 Nicklas Nordborg
5277 22 Mar 10 nicklas 5
5277 22 Mar 10 nicklas 6   This file is part of BASE - BioArray Software Environment.
5277 22 Mar 10 nicklas 7   Available at http://base.thep.lu.se/
5277 22 Mar 10 nicklas 8
5277 22 Mar 10 nicklas 9   BASE is free software; you can redistribute it and/or
5277 22 Mar 10 nicklas 10   modify it under the terms of the GNU General Public License
5277 22 Mar 10 nicklas 11   as published by the Free Software Foundation; either version 3
5277 22 Mar 10 nicklas 12   of the License, or (at your option) any later version.
5277 22 Mar 10 nicklas 13
5277 22 Mar 10 nicklas 14   BASE is distributed in the hope that it will be useful,
5277 22 Mar 10 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
5277 22 Mar 10 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5277 22 Mar 10 nicklas 17   GNU General Public License for more details.
5277 22 Mar 10 nicklas 18
5277 22 Mar 10 nicklas 19   You should have received a copy of the GNU General Public License
5277 22 Mar 10 nicklas 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
5277 22 Mar 10 nicklas 21 */
5277 22 Mar 10 nicklas 22 package net.sf.basedb.util.export.spotdata;
5277 22 Mar 10 nicklas 23
5302 31 Mar 10 nicklas 24 import java.util.ArrayList;
5277 22 Mar 10 nicklas 25 import java.util.List;
5277 22 Mar 10 nicklas 26
5277 22 Mar 10 nicklas 27 import net.sf.basedb.core.AnnotationType;
5277 22 Mar 10 nicklas 28 import net.sf.basedb.core.BaseException;
5300 31 Mar 10 nicklas 29 import net.sf.basedb.core.BioAssay;
5277 22 Mar 10 nicklas 30 import net.sf.basedb.core.BioAssaySet;
5277 22 Mar 10 nicklas 31 import net.sf.basedb.core.DbControl;
5277 22 Mar 10 nicklas 32 import net.sf.basedb.core.ExtendedProperties;
5277 22 Mar 10 nicklas 33 import net.sf.basedb.core.ExtendedProperty;
5277 22 Mar 10 nicklas 34 import net.sf.basedb.core.ExtraValue;
5277 22 Mar 10 nicklas 35 import net.sf.basedb.core.ExtraValueType;
5277 22 Mar 10 nicklas 36 import net.sf.basedb.core.Formula;
5277 22 Mar 10 nicklas 37 import net.sf.basedb.core.Include;
5277 22 Mar 10 nicklas 38 import net.sf.basedb.core.IntensityTransform;
5277 22 Mar 10 nicklas 39 import net.sf.basedb.core.ItemQuery;
5300 31 Mar 10 nicklas 40 import net.sf.basedb.core.Metadata;
5292 26 Mar 10 nicklas 41 import net.sf.basedb.core.RawDataProperty;
5277 22 Mar 10 nicklas 42 import net.sf.basedb.core.RawDataType;
5277 22 Mar 10 nicklas 43 import net.sf.basedb.core.Type;
5277 22 Mar 10 nicklas 44 import net.sf.basedb.core.ExtraValue.CoordinateType;
5300 31 Mar 10 nicklas 45 import net.sf.basedb.core.Metadata.PropertyPath;
5300 31 Mar 10 nicklas 46 import net.sf.basedb.core.data.RawData;
5300 31 Mar 10 nicklas 47 import net.sf.basedb.core.data.ReporterData;
5277 22 Mar 10 nicklas 48 import net.sf.basedb.core.query.Expression;
5277 22 Mar 10 nicklas 49 import net.sf.basedb.core.query.Expressions;
5277 22 Mar 10 nicklas 50 import net.sf.basedb.core.query.Hql;
5277 22 Mar 10 nicklas 51 import net.sf.basedb.core.query.Restrictions;
5277 22 Mar 10 nicklas 52 import net.sf.basedb.core.snapshot.SnapshotManager;
5277 22 Mar 10 nicklas 53
5277 22 Mar 10 nicklas 54 /**
5277 22 Mar 10 nicklas 55   Abstract helper class for implementing {@link ExportableFieldConverter}.
5277 22 Mar 10 nicklas 56   It contains a lot of helper method for locating formulas, extra values,
5277 22 Mar 10 nicklas 57   experimental factors, etc.
5277 22 Mar 10 nicklas 58   
5277 22 Mar 10 nicklas 59   @author nicklas
5277 22 Mar 10 nicklas 60   @since 2.15
5277 22 Mar 10 nicklas 61 */
5277 22 Mar 10 nicklas 62 public abstract class AbstractFieldConverter
5277 22 Mar 10 nicklas 63   implements ExportableFieldConverter
5277 22 Mar 10 nicklas 64 {
5277 22 Mar 10 nicklas 65   private final DbControl dc;
5277 22 Mar 10 nicklas 66   private final BioAssaySet source;
5277 22 Mar 10 nicklas 67
5277 22 Mar 10 nicklas 68   private SnapshotManager snapshotManager;
5277 22 Mar 10 nicklas 69   private ItemQuery<AnnotationType> factorQuery;
5300 31 Mar 10 nicklas 70   private ItemQuery<AnnotationType> assayAnnotationQuery;
5277 22 Mar 10 nicklas 71   private ItemQuery<ExtraValue> extraQuery;
5277 22 Mar 10 nicklas 72   private ItemQuery<Formula> formulaQuery;
5277 22 Mar 10 nicklas 73
5277 22 Mar 10 nicklas 74   /**
5277 22 Mar 10 nicklas 75     Creates a new field converter to be used with a specific 
5277 22 Mar 10 nicklas 76     bioassay set source.
5277 22 Mar 10 nicklas 77     @param dc A DbControl to use for database access
5277 22 Mar 10 nicklas 78     @param source The source bioassay set
5277 22 Mar 10 nicklas 79   */
5277 22 Mar 10 nicklas 80   protected AbstractFieldConverter(DbControl dc, BioAssaySet source)
5277 22 Mar 10 nicklas 81   {
5277 22 Mar 10 nicklas 82     if (dc == null) throw new NullPointerException("dc");
5277 22 Mar 10 nicklas 83     if (source == null) throw new NullPointerException("source");
5277 22 Mar 10 nicklas 84     this.dc = dc;
5277 22 Mar 10 nicklas 85     this.source = source;
5277 22 Mar 10 nicklas 86   }
5277 22 Mar 10 nicklas 87   
5277 22 Mar 10 nicklas 88   /**
5292 26 Mar 10 nicklas 89     Get the DbControl to use for database access.
5292 26 Mar 10 nicklas 90   */
5292 26 Mar 10 nicklas 91   protected DbControl getDbControl()
5292 26 Mar 10 nicklas 92   {
5292 26 Mar 10 nicklas 93     return dc;
5292 26 Mar 10 nicklas 94   }
5292 26 Mar 10 nicklas 95   /**
5292 26 Mar 10 nicklas 96     Get the source bioassay set.
5292 26 Mar 10 nicklas 97   */
5292 26 Mar 10 nicklas 98   protected BioAssaySet getSource()
5292 26 Mar 10 nicklas 99   {
5292 26 Mar 10 nicklas 100     return source;
5292 26 Mar 10 nicklas 101   }
5292 26 Mar 10 nicklas 102   
5292 26 Mar 10 nicklas 103   /**
5277 22 Mar 10 nicklas 104     Set a snapshot manager that should be used with annotation-based
5277 22 Mar 10 nicklas 105     fields. If no snapshot manager is provided, a new manager will 
5277 22 Mar 10 nicklas 106     automatically be created if needed.
5277 22 Mar 10 nicklas 107     @param snapshotManager The snapshot manager to use
5277 22 Mar 10 nicklas 108   */
5277 22 Mar 10 nicklas 109   public void setSnapshotManager(SnapshotManager snapshotManager)
5277 22 Mar 10 nicklas 110   {
5277 22 Mar 10 nicklas 111     this.snapshotManager = snapshotManager;
5277 22 Mar 10 nicklas 112   }
5277 22 Mar 10 nicklas 113   
5277 22 Mar 10 nicklas 114   /**
5277 22 Mar 10 nicklas 115     Get the snapshot manager to use with annotation-based fields.
5277 22 Mar 10 nicklas 116     If no snapshot manager has been configured a new one is automatically
5277 22 Mar 10 nicklas 117     created.
5277 22 Mar 10 nicklas 118     @return A snapshot manager object
5277 22 Mar 10 nicklas 119   */
5277 22 Mar 10 nicklas 120   public SnapshotManager getSnapshotManager()
5277 22 Mar 10 nicklas 121   {
5277 22 Mar 10 nicklas 122     if (snapshotManager == null) snapshotManager = new SnapshotManager();
5277 22 Mar 10 nicklas 123     return snapshotManager;
5277 22 Mar 10 nicklas 124   }
5277 22 Mar 10 nicklas 125   
5277 22 Mar 10 nicklas 126   /**
5277 22 Mar 10 nicklas 127     Get a static assay property field, such as name, description or id.
5277 22 Mar 10 nicklas 128     Property lookup is not case-sensitive. Eg. both 'name' and 'Name' will
5277 22 Mar 10 nicklas 129     match.
5277 22 Mar 10 nicklas 130     
5277 22 Mar 10 nicklas 131     @param name The property name
5277 22 Mar 10 nicklas 132     @param exportTitle The title as it should be in the exported file
5277 22 Mar 10 nicklas 133     @return An AssayPropertyField or null if not found
5277 22 Mar 10 nicklas 134   */
5277 22 Mar 10 nicklas 135   protected AssayPropertyField getAssayPropertyField(String name, String exportTitle)
5277 22 Mar 10 nicklas 136   {
5277 22 Mar 10 nicklas 137     AssayPropertyField fld = null;
5300 31 Mar 10 nicklas 138     Metadata<BioAssay> metadata = Metadata.getInstance(BioAssay.class);
5300 31 Mar 10 nicklas 139     try
5277 22 Mar 10 nicklas 140     {
5300 31 Mar 10 nicklas 141       PropertyPath<BioAssay, ?> path = metadata.getPropertyPath(name, true);
5300 31 Mar 10 nicklas 142       Type type = Type.fromHibernateType(path.getHibernateType());
5300 31 Mar 10 nicklas 143       if (type == null) 
5300 31 Mar 10 nicklas 144       {
5300 31 Mar 10 nicklas 145         // The output is written to a text file, so if we don't know 
5300 31 Mar 10 nicklas 146         // what it is, it will always end up as a string
5300 31 Mar 10 nicklas 147         type = Type.STRING;
5300 31 Mar 10 nicklas 148       }
5300 31 Mar 10 nicklas 149       fld = ExportableFieldFactory.assayProperty(path.getPath(), exportTitle, type, null);
5277 22 Mar 10 nicklas 150     }
5300 31 Mar 10 nicklas 151     catch (RuntimeException ex)
5300 31 Mar 10 nicklas 152     {}
5277 22 Mar 10 nicklas 153     return fld;
5277 22 Mar 10 nicklas 154   }
5277 22 Mar 10 nicklas 155   
5277 22 Mar 10 nicklas 156   /**
5277 22 Mar 10 nicklas 157     Get an experimental factor assay field. A database query is used to 
5277 22 Mar 10 nicklas 158     locate an experimental factor for the experiment that has the
5277 22 Mar 10 nicklas 159     given name or external id. Depending on the underlying database, 
5277 22 Mar 10 nicklas 160     the lookup may be case-sensitive or case-insensitive. If more than 
5277 22 Mar 10 nicklas 161     one experimental factor is found an exception is thrown.
5277 22 Mar 10 nicklas 162     
5277 22 Mar 10 nicklas 163     @param name The name or external id of the experimental factor to find
5277 22 Mar 10 nicklas 164     @param exportTitle The title as it should be in the exported file or null
5277 22 Mar 10 nicklas 165       to use the name of the experimental factor
5277 22 Mar 10 nicklas 166     @return An AnnotationAssayField or null if no experimental factor is found
5277 22 Mar 10 nicklas 167   */
5277 22 Mar 10 nicklas 168   protected AnnotationAssayField getExperimentalFactorField(String name, String exportTitle)
5277 22 Mar 10 nicklas 169   {
5277 22 Mar 10 nicklas 170     if (factorQuery == null)
5277 22 Mar 10 nicklas 171     {
5292 26 Mar 10 nicklas 172       factorQuery = getSource().getExperiment().getExperimentalFactors();
5277 22 Mar 10 nicklas 173       factorQuery.include(Include.MINE, Include.SHARED, Include.IN_PROJECT, Include.OTHERS);
5302 31 Mar 10 nicklas 174       //WHERE name = :name OR externalId = :name
5277 22 Mar 10 nicklas 175       Expression nameParameter = Expressions.parameter("name");
5302 31 Mar 10 nicklas 176       factorQuery.restrictPermanent(
5277 22 Mar 10 nicklas 177           Restrictions.or(
5277 22 Mar 10 nicklas 178             Restrictions.eq(Hql.property("name"), nameParameter),
5277 22 Mar 10 nicklas 179             Restrictions.eq(Hql.property("externalId"), nameParameter)
5277 22 Mar 10 nicklas 180           )
5277 22 Mar 10 nicklas 181       );
5277 22 Mar 10 nicklas 182     }
5277 22 Mar 10 nicklas 183     factorQuery.setParameter("name", name, Type.STRING);
5277 22 Mar 10 nicklas 184     List<AnnotationType> result = factorQuery.list(dc);
5277 22 Mar 10 nicklas 185     int size = result.size();
5277 22 Mar 10 nicklas 186     AnnotationAssayField fld = null;
5277 22 Mar 10 nicklas 187     if (size > 1)
5277 22 Mar 10 nicklas 188     {
5277 22 Mar 10 nicklas 189       throw new BaseException("Found " + result.size() + 
5277 22 Mar 10 nicklas 190         " experimental factors for name/external id: " + name);
5277 22 Mar 10 nicklas 191     }
5277 22 Mar 10 nicklas 192     else if (size == 1)
5277 22 Mar 10 nicklas 193     {
5277 22 Mar 10 nicklas 194       AnnotationType at = result.get(0);
5277 22 Mar 10 nicklas 195       if (exportTitle == null) exportTitle = at.getName();
5277 22 Mar 10 nicklas 196       fld = ExportableFieldFactory.annotation(at, exportTitle, null);
5277 22 Mar 10 nicklas 197       fld.setSnapshotManager(getSnapshotManager());
5277 22 Mar 10 nicklas 198     }
5277 22 Mar 10 nicklas 199     return fld;
5277 22 Mar 10 nicklas 200   }
5277 22 Mar 10 nicklas 201   
5277 22 Mar 10 nicklas 202   /**
5300 31 Mar 10 nicklas 203     Get an assay annotation field. A database query is used to locate an annotation 
5300 31 Mar 10 nicklas 204     type that has been used on at least one assay in the bioassay set.
5300 31 Mar 10 nicklas 205     Depending on the underlying database, the lookup may be case-sensitive or 
5300 31 Mar 10 nicklas 206     case-insensitive. If more than one annotation type is found an exception is thrown.
5300 31 Mar 10 nicklas 207     
5300 31 Mar 10 nicklas 208     @param name The name or external id of the annotation type to find
5300 31 Mar 10 nicklas 209     @param exportTitle The title as it should be in the exported file or null
5300 31 Mar 10 nicklas 210       to use the name of the annotation type
5300 31 Mar 10 nicklas 211     @return An AnnotationAssayField or null if no annotation type is found
5300 31 Mar 10 nicklas 212   */
5300 31 Mar 10 nicklas 213   protected AnnotationAssayField getAssayAnnotationField(String name, String exportTitle)
5300 31 Mar 10 nicklas 214   {
5300 31 Mar 10 nicklas 215     if (assayAnnotationQuery == null)
5300 31 Mar 10 nicklas 216     {
5302 31 Mar 10 nicklas 217       assayAnnotationQuery = AnnotationType.getQuery(null);
5302 31 Mar 10 nicklas 218       assayAnnotationQuery.setDistinct(true);
5300 31 Mar 10 nicklas 219       assayAnnotationQuery.include(Include.MINE, Include.SHARED, Include.IN_PROJECT, Include.OTHERS);
5302 31 Mar 10 nicklas 220       // WHERE name = :name or externalId = :name
5300 31 Mar 10 nicklas 221       Expression nameParameter = Expressions.parameter("name");
5302 31 Mar 10 nicklas 222       assayAnnotationQuery.restrictPermanent(
5302 31 Mar 10 nicklas 223         Restrictions.or(
5302 31 Mar 10 nicklas 224           Restrictions.eq(Hql.property("name"), nameParameter),
5302 31 Mar 10 nicklas 225           Restrictions.eq(Hql.property("externalId"), nameParameter)
5302 31 Mar 10 nicklas 226         )
5300 31 Mar 10 nicklas 227       );
5302 31 Mar 10 nicklas 228       // INNER JOIN annotations a WHERE a.annotationSet.id IN (:ids)
5302 31 Mar 10 nicklas 229       assayAnnotationQuery.join(Hql.innerJoin("annotations", "a"));
5302 31 Mar 10 nicklas 230       assayAnnotationQuery.restrictPermanent(
5302 31 Mar 10 nicklas 231         Restrictions.in(
5302 31 Mar 10 nicklas 232           Hql.property("a", "annotationSet.id"), 
5302 31 Mar 10 nicklas 233           Expressions.parameter("assayAnnotationSets")
5302 31 Mar 10 nicklas 234         )
5302 31 Mar 10 nicklas 235       );
5302 31 Mar 10 nicklas 236       List<BioAssay> assays = getSource().getBioAssays().list(dc);
5302 31 Mar 10 nicklas 237       List<Integer> ids = new ArrayList<Integer>(assays.size());
5302 31 Mar 10 nicklas 238       for (BioAssay ba : assays)
5302 31 Mar 10 nicklas 239       {
5302 31 Mar 10 nicklas 240         if (ba.isAnnotated()) ids.add(ba.getAnnotationSet().getId());
5302 31 Mar 10 nicklas 241       }
5302 31 Mar 10 nicklas 242       if (ids.size() == 0) ids.add(0);
5302 31 Mar 10 nicklas 243       assayAnnotationQuery.setPermanentParameter("assayAnnotationSets", ids, Type.INT);
5300 31 Mar 10 nicklas 244     }
5300 31 Mar 10 nicklas 245     assayAnnotationQuery.setParameter("name", name, Type.STRING);
5300 31 Mar 10 nicklas 246     List<AnnotationType> result = assayAnnotationQuery.list(dc);
5300 31 Mar 10 nicklas 247     int size = result.size();
5300 31 Mar 10 nicklas 248     AnnotationAssayField fld = null;
5300 31 Mar 10 nicklas 249     if (size > 1)
5300 31 Mar 10 nicklas 250     {
5300 31 Mar 10 nicklas 251       throw new BaseException("Found " + result.size() + 
5300 31 Mar 10 nicklas 252         " assay annotations for name/external id: " + name);
5300 31 Mar 10 nicklas 253     }
5300 31 Mar 10 nicklas 254     else if (size == 1)
5300 31 Mar 10 nicklas 255     {
5300 31 Mar 10 nicklas 256       AnnotationType at = result.get(0);
5300 31 Mar 10 nicklas 257       if (exportTitle == null) exportTitle = at.getName();
5300 31 Mar 10 nicklas 258       fld = ExportableFieldFactory.annotation(at, exportTitle, null);
5300 31 Mar 10 nicklas 259       fld.setSnapshotManager(getSnapshotManager());
5300 31 Mar 10 nicklas 260     }
5300 31 Mar 10 nicklas 261     return fld;
5300 31 Mar 10 nicklas 262   }
5300 31 Mar 10 nicklas 263   
5300 31 Mar 10 nicklas 264   /**
5277 22 Mar 10 nicklas 265     Get a static or extended reporter property field, such as name, description 
5277 22 Mar 10 nicklas 266     or id. Property lookup is not case-sensitive. Eg. both 'name' and 'Name' will
5277 22 Mar 10 nicklas 267     match.
5277 22 Mar 10 nicklas 268     
5277 22 Mar 10 nicklas 269     @param name The name of the reporter property
5277 22 Mar 10 nicklas 270     @param exportTitle The exported title or null to use the title
5277 22 Mar 10 nicklas 271       of the extended property (which can be different from the name)
5277 22 Mar 10 nicklas 272     @return A dynamic field, or null if no reporter property is found
5277 22 Mar 10 nicklas 273   */
5277 22 Mar 10 nicklas 274   protected DynamicField getReporterProperty(String name, String exportTitle)
5277 22 Mar 10 nicklas 275   {
5277 22 Mar 10 nicklas 276     DynamicField fld = null;
5300 31 Mar 10 nicklas 277     // Check the extended properties first
5300 31 Mar 10 nicklas 278     List<ExtendedProperty> extended = ExtendedProperties.getProperties("ReporterData");
5300 31 Mar 10 nicklas 279     if (extended != null)
5277 22 Mar 10 nicklas 280     {
5300 31 Mar 10 nicklas 281       for (ExtendedProperty ep : extended)
5300 31 Mar 10 nicklas 282       {
5300 31 Mar 10 nicklas 283         if (ep.getName().equalsIgnoreCase(name) || ep.getTitle().equalsIgnoreCase(name))
5300 31 Mar 10 nicklas 284         {
5300 31 Mar 10 nicklas 285           fld = ExportableFieldFactory.reporter(ep, exportTitle, null);
5300 31 Mar 10 nicklas 286           break;
5300 31 Mar 10 nicklas 287         }
5300 31 Mar 10 nicklas 288       }
5277 22 Mar 10 nicklas 289     }
5292 26 Mar 10 nicklas 290     if (fld == null)
5277 22 Mar 10 nicklas 291     {
5300 31 Mar 10 nicklas 292       // If not found, use metadata
5300 31 Mar 10 nicklas 293       Metadata<ReporterData> metadata = Metadata.getInstance(ReporterData.class);
5300 31 Mar 10 nicklas 294       try
5277 22 Mar 10 nicklas 295       {
5300 31 Mar 10 nicklas 296         PropertyPath<ReporterData, ?> path = metadata.getPropertyPath(name, true);
5300 31 Mar 10 nicklas 297         Type type = Type.fromHibernateType(path.getHibernateType());
5300 31 Mar 10 nicklas 298         if (type == null) 
5292 26 Mar 10 nicklas 299         {
5300 31 Mar 10 nicklas 300           // The output is written to a text file, so if we don't know 
5300 31 Mar 10 nicklas 301           // what it is, it will always end up as a string
5300 31 Mar 10 nicklas 302           type = Type.STRING;
5292 26 Mar 10 nicklas 303         }
5300 31 Mar 10 nicklas 304         fld = ExportableFieldFactory.reporter(path.getPath(), exportTitle, type, Formula.AverageMethod.NONE, null);
5292 26 Mar 10 nicklas 305       }
5300 31 Mar 10 nicklas 306       catch (RuntimeException ex)
5300 31 Mar 10 nicklas 307       {}
5292 26 Mar 10 nicklas 308     }
5300 31 Mar 10 nicklas 309     if (fld == null)
5300 31 Mar 10 nicklas 310     {
5300 31 Mar 10 nicklas 311       // Special cases to make everything compatible with the importer which
5300 31 Mar 10 nicklas 312       // requires that either "External ID" or "Internal ID" columns are present
5373 03 Aug 10 nicklas 313       // "Position" is also handled as a special case
5300 31 Mar 10 nicklas 314       if ("External ID".equalsIgnoreCase(name))
5300 31 Mar 10 nicklas 315       {
5373 03 Aug 10 nicklas 316         fld = ExportableFieldFactory.reporter("externalId", name, Type.STRING, null, null);
5300 31 Mar 10 nicklas 317       }
5300 31 Mar 10 nicklas 318       else if ("Internal ID".equalsIgnoreCase(name))
5300 31 Mar 10 nicklas 319       {
5373 03 Aug 10 nicklas 320         fld = ExportableFieldFactory.reporter("id", name, Type.STRING, null, null);
5300 31 Mar 10 nicklas 321       }
5373 03 Aug 10 nicklas 322       else if ("Position".equals(name))
5373 03 Aug 10 nicklas 323       {
5373 03 Aug 10 nicklas 324         fld = ExportableFieldFactory.jep("pos()", name, Type.INT, null, null);
5373 03 Aug 10 nicklas 325       }
5300 31 Mar 10 nicklas 326     }
5292 26 Mar 10 nicklas 327     return fld;
5292 26 Mar 10 nicklas 328   }
5292 26 Mar 10 nicklas 329
5292 26 Mar 10 nicklas 330   /**
5292 26 Mar 10 nicklas 331     Find an extended raw data property with the given name and create
5292 26 Mar 10 nicklas 332     a dynamic field from it using exportTitle as the title.
5292 26 Mar 10 nicklas 333     @param name The name of the extended raw data property
5292 26 Mar 10 nicklas 334     @param exportTitle The exported title or null to use the title
5292 26 Mar 10 nicklas 335       of the extended property (which can be different from the name)
5292 26 Mar 10 nicklas 336     @return A dynamic field, or null if no raw data property is found
5292 26 Mar 10 nicklas 337   */
5300 31 Mar 10 nicklas 338   protected DynamicField getRawDataProperty(String name, String exportTitle)
5292 26 Mar 10 nicklas 339   {
5292 26 Mar 10 nicklas 340     DynamicField fld = null;
5300 31 Mar 10 nicklas 341     // Check the extended properties first
5300 31 Mar 10 nicklas 342     List<RawDataProperty> properties = getSource().getRawDataType().getProperties();
5300 31 Mar 10 nicklas 343     if (properties != null)
5292 26 Mar 10 nicklas 344     {
5300 31 Mar 10 nicklas 345       for (RawDataProperty rp : properties)
5292 26 Mar 10 nicklas 346       {
5300 31 Mar 10 nicklas 347         if (rp.getName().equalsIgnoreCase(name) || rp.getTitle().equalsIgnoreCase(name))
5300 31 Mar 10 nicklas 348         {
5300 31 Mar 10 nicklas 349           fld = ExportableFieldFactory.rawData(rp, exportTitle, null);
5300 31 Mar 10 nicklas 350           break;
5300 31 Mar 10 nicklas 351         }
5277 22 Mar 10 nicklas 352       }
5277 22 Mar 10 nicklas 353     }
5300 31 Mar 10 nicklas 354     if (fld == null)
5300 31 Mar 10 nicklas 355     {
5300 31 Mar 10 nicklas 356       // If not found, use metadata
5300 31 Mar 10 nicklas 357       Metadata<RawData> metadata = Metadata.getInstance(RawData.class, getSource().getRawDataType().getEntityName());
5300 31 Mar 10 nicklas 358       try
5300 31 Mar 10 nicklas 359       {
5300 31 Mar 10 nicklas 360         PropertyPath<RawData, ?> path = metadata.getPropertyPath(name, true);
5300 31 Mar 10 nicklas 361         Type type = Type.fromHibernateType(path.getHibernateType());
5300 31 Mar 10 nicklas 362         if (type == null) 
5300 31 Mar 10 nicklas 363         {
5300 31 Mar 10 nicklas 364           // The output is written to a text file, so if we don't know 
5300 31 Mar 10 nicklas 365           // what it is, it will always end up as a string
5300 31 Mar 10 nicklas 366           type = Type.STRING;
5300 31 Mar 10 nicklas 367         }
5300 31 Mar 10 nicklas 368         fld = ExportableFieldFactory.rawData(path.getPath(), exportTitle, type, Formula.AverageMethod.NONE, null);
5300 31 Mar 10 nicklas 369       }
5300 31 Mar 10 nicklas 370       catch (RuntimeException ex)
5300 31 Mar 10 nicklas 371       {}
5300 31 Mar 10 nicklas 372     }
5300 31 Mar 10 nicklas 373
5277 22 Mar 10 nicklas 374     return fld;
5277 22 Mar 10 nicklas 375   }
5277 22 Mar 10 nicklas 376
5277 22 Mar 10 nicklas 377   
5277 22 Mar 10 nicklas 378   /**
5277 22 Mar 10 nicklas 379     Get an extra value dynamic field. A database query is used to 
5277 22 Mar 10 nicklas 380     locate an extra value for the bioassay set that has the
5277 22 Mar 10 nicklas 381     given name or external id. Depending on the underlying database, 
5277 22 Mar 10 nicklas 382     the lookup may be case-sensitive or case-insensitive. If more than 
5277 22 Mar 10 nicklas 383     one extra value is found an exception is thrown.
5277 22 Mar 10 nicklas 384     
5277 22 Mar 10 nicklas 385     @param name The name or external id of the experimental factor to find
5277 22 Mar 10 nicklas 386     @param type The coordinate type of the extra value (eg. POSITION for reporter
5277 22 Mar 10 nicklas 387       extra values, and SPOT for spot extra values)
5277 22 Mar 10 nicklas 388     @param exportTitle The title as it should be in the exported file or null
5277 22 Mar 10 nicklas 389       to use the name of the extra value
5277 22 Mar 10 nicklas 390     @return A DynamicField or null if no extra value is found
5277 22 Mar 10 nicklas 391   */
5277 22 Mar 10 nicklas 392   protected DynamicField getExtraValueField(String name, CoordinateType type, String exportTitle)
5277 22 Mar 10 nicklas 393   {
5277 22 Mar 10 nicklas 394     if (extraQuery == null)
5277 22 Mar 10 nicklas 395     {
5302 31 Mar 10 nicklas 396       extraQuery = getSource().getExtraValues();
5302 31 Mar 10 nicklas 397       // INNER JOIN extraValueType evt
5302 31 Mar 10 nicklas 398       extraQuery.joinPermanent(Hql.innerJoin("extraValueType", "evt"));
5302 31 Mar 10 nicklas 399       // WHERE evt.name = :name OR evt.externalId = :name
5277 22 Mar 10 nicklas 400       Expression nameParameter = Expressions.parameter("name");
5302 31 Mar 10 nicklas 401       extraQuery.restrictPermanent(
5277 22 Mar 10 nicklas 402         Restrictions.or(
5277 22 Mar 10 nicklas 403           Restrictions.eq(Hql.property("evt", "name"), nameParameter),
5277 22 Mar 10 nicklas 404           Restrictions.eq(Hql.property("evt", "externalId"), nameParameter)
5277 22 Mar 10 nicklas 405         )
5277 22 Mar 10 nicklas 406       );
5302 31 Mar 10 nicklas 407       // WHERE dataCubeExtraValue.coordinateType = :type
5302 31 Mar 10 nicklas 408       extraQuery.restrictPermanent(
5302 31 Mar 10 nicklas 409           Restrictions.eq(
5302 31 Mar 10 nicklas 410             Hql.property("dataCubeExtraValue.coordinateType"), 
5302 31 Mar 10 nicklas 411             Expressions.parameter("type"))
5302 31 Mar 10 nicklas 412         );
5277 22 Mar 10 nicklas 413     }
5277 22 Mar 10 nicklas 414     extraQuery.setParameter("name", name, Type.STRING);
5277 22 Mar 10 nicklas 415     extraQuery.setParameter("type", type.getValue(), Type.INT);
5277 22 Mar 10 nicklas 416     List<ExtraValue> result = extraQuery.list(dc);
5277 22 Mar 10 nicklas 417     int size = result.size();
5277 22 Mar 10 nicklas 418     DynamicField fld = null;
5277 22 Mar 10 nicklas 419     if (size > 1)
5277 22 Mar 10 nicklas 420     {
5277 22 Mar 10 nicklas 421       throw new BaseException("Found " + result.size() + 
5277 22 Mar 10 nicklas 422         " extra values with name/external id: " + name);
5277 22 Mar 10 nicklas 423     }
5277 22 Mar 10 nicklas 424     else if (size == 1)
5277 22 Mar 10 nicklas 425     {
5277 22 Mar 10 nicklas 426       ExtraValueType evt = result.get(0).getExtraValueType();
5277 22 Mar 10 nicklas 427       if (exportTitle == null) exportTitle = evt.getName();
5277 22 Mar 10 nicklas 428       fld = ExportableFieldFactory.extraValue(evt, exportTitle, null);
5277 22 Mar 10 nicklas 429     }
5277 22 Mar 10 nicklas 430     return fld;
5277 22 Mar 10 nicklas 431   }
5277 22 Mar 10 nicklas 432   
5277 22 Mar 10 nicklas 433   /**
5277 22 Mar 10 nicklas 434     Get a formula dynamic field. A database query is used to 
5385 13 Aug 10 nicklas 435     locate the formula which must be a {@link net.sf.basedb.core.Formula.Type#COLUMN_EXPRESSION} 
5277 22 Mar 10 nicklas 436     and be suitable for the  {@link RawDataType} and {@link IntensityTransform} 
5277 22 Mar 10 nicklas 437     used by the source bioassay set. Depending on the underlying database, 
5277 22 Mar 10 nicklas 438     the lookup may be case-sensitive or case-insensitive. If more than 
5277 22 Mar 10 nicklas 439     one formula is found an exception is thrown.
5277 22 Mar 10 nicklas 440     
5277 22 Mar 10 nicklas 441     @param name The name of the formula to find
5277 22 Mar 10 nicklas 442     @param exportTitle The title as it should be in the exported file or null
5277 22 Mar 10 nicklas 443       to use the name of the formula
5277 22 Mar 10 nicklas 444     @return A DynamicField or null if no extra value is found
5277 22 Mar 10 nicklas 445   */
5277 22 Mar 10 nicklas 446   protected DynamicField getFormulaField(String name, String exportTitle)
5277 22 Mar 10 nicklas 447   {
5277 22 Mar 10 nicklas 448     if (formulaQuery == null)
5277 22 Mar 10 nicklas 449     {
5292 26 Mar 10 nicklas 450       BioAssaySet src = getSource();
5292 26 Mar 10 nicklas 451       formulaQuery = Formula.getQuery(Formula.Type.COLUMN_EXPRESSION, src.getRawDataType(), src.getIntensityTransform());
5277 22 Mar 10 nicklas 452       formulaQuery.include(Include.MINE, Include.SHARED, Include.IN_PROJECT, Include.OTHERS);
5302 31 Mar 10 nicklas 453       formulaQuery.restrictPermanent(Restrictions.eq(Hql.property("name"), Expressions.parameter("name")));
5277 22 Mar 10 nicklas 454     }
5277 22 Mar 10 nicklas 455     formulaQuery.setParameter("name", name, Type.STRING);
5277 22 Mar 10 nicklas 456     List<Formula> result = formulaQuery.list(dc);
5277 22 Mar 10 nicklas 457     int size = result.size();
5277 22 Mar 10 nicklas 458     DynamicField fld = null;
5277 22 Mar 10 nicklas 459     if (size > 1)
5277 22 Mar 10 nicklas 460     {
5277 22 Mar 10 nicklas 461       throw new BaseException("Found " + result.size() + 
5277 22 Mar 10 nicklas 462         " formulas with name: " + name);
5277 22 Mar 10 nicklas 463     }
5277 22 Mar 10 nicklas 464     else if (size == 1)
5277 22 Mar 10 nicklas 465     {
5277 22 Mar 10 nicklas 466       Formula f = result.get(0);
5277 22 Mar 10 nicklas 467       if (exportTitle == null) exportTitle = f.getName();
5277 22 Mar 10 nicklas 468       fld = ExportableFieldFactory.formula(f, exportTitle, null);
5277 22 Mar 10 nicklas 469     }
5277 22 Mar 10 nicklas 470     return fld;
5277 22 Mar 10 nicklas 471   }
5277 22 Mar 10 nicklas 472   
5277 22 Mar 10 nicklas 473   /**
5277 22 Mar 10 nicklas 474     Create a dynamic field for spot intensity if the field name has
5292 26 Mar 10 nicklas 475     the pattern 'Ch X' where 'X' is a channel number between 1
5277 22 Mar 10 nicklas 476     and the number of channels in the raw data type used by the 
5277 22 Mar 10 nicklas 477     source bioassay set.
5277 22 Mar 10 nicklas 478     @param fieldName The field name
5277 22 Mar 10 nicklas 479     @return A dynamic field, or null if the name doesn't match the pattern
5277 22 Mar 10 nicklas 480   */
5277 22 Mar 10 nicklas 481   protected DynamicField getIntensityField(String fieldName, String exportTitle)
5277 22 Mar 10 nicklas 482   {
5277 22 Mar 10 nicklas 483     DynamicField df = null;
5292 26 Mar 10 nicklas 484     for (int i = 1; i <= getSource().getRawDataType().getChannels(); ++i)
5277 22 Mar 10 nicklas 485     {
5277 22 Mar 10 nicklas 486       if (fieldName.equalsIgnoreCase("Ch "+i))
5277 22 Mar 10 nicklas 487       {
5277 22 Mar 10 nicklas 488         df = ExportableFieldFactory.channel(i, exportTitle, null);
5277 22 Mar 10 nicklas 489         break;
5277 22 Mar 10 nicklas 490       }
5277 22 Mar 10 nicklas 491     }
5277 22 Mar 10 nicklas 492     return df;
5277 22 Mar 10 nicklas 493   }
5277 22 Mar 10 nicklas 494
5277 22 Mar 10 nicklas 495   
5277 22 Mar 10 nicklas 496 }