extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/plugins/CaliperPlateImporter.java

Code
Comments
Other
Rev Date Author Line
1546 02 Mar 12 nicklas 1 package net.sf.basedb.reggie.plugins;
1546 02 Mar 12 nicklas 2
1546 02 Mar 12 nicklas 3 import java.io.IOException;
1546 02 Mar 12 nicklas 4 import java.io.InputStream;
1546 02 Mar 12 nicklas 5 import java.util.HashMap;
1546 02 Mar 12 nicklas 6 import java.util.List;
1546 02 Mar 12 nicklas 7 import java.util.Map;
1546 02 Mar 12 nicklas 8 import java.util.regex.Matcher;
1546 02 Mar 12 nicklas 9 import java.util.regex.Pattern;
1546 02 Mar 12 nicklas 10
1546 02 Mar 12 nicklas 11 import net.sf.basedb.core.AnnotationSet;
1546 02 Mar 12 nicklas 12 import net.sf.basedb.core.AnnotationType;
1546 02 Mar 12 nicklas 13 import net.sf.basedb.core.BioPlate;
1546 02 Mar 12 nicklas 14 import net.sf.basedb.core.DbControl;
1546 02 Mar 12 nicklas 15 import net.sf.basedb.core.Extract;
1546 02 Mar 12 nicklas 16 import net.sf.basedb.core.ItemQuery;
1904 13 Mar 13 nicklas 17 import net.sf.basedb.core.Type;
1546 02 Mar 12 nicklas 18 import net.sf.basedb.core.query.Expressions;
1546 02 Mar 12 nicklas 19 import net.sf.basedb.core.query.Hql;
1546 02 Mar 12 nicklas 20 import net.sf.basedb.core.query.Restrictions;
1904 13 Mar 13 nicklas 21 import net.sf.basedb.reggie.converter.ValueConverter;
1546 02 Mar 12 nicklas 22 import net.sf.basedb.util.parser.FlatFileParser;
1546 02 Mar 12 nicklas 23 import net.sf.basedb.util.parser.FlatFileParser.LineType;
1546 02 Mar 12 nicklas 24 import net.sf.basedb.util.parser.Mapper;
1546 02 Mar 12 nicklas 25
1546 02 Mar 12 nicklas 26 /**
1546 02 Mar 12 nicklas 27   Plug-in for importing annotations to biomaterial on
1546 02 Mar 12 nicklas 28   bioplates that has been proccessed with the Caliper
1546 02 Mar 12 nicklas 29   machine.
1546 02 Mar 12 nicklas 30   @author nicklas
1546 02 Mar 12 nicklas 31   @since 2.4
1546 02 Mar 12 nicklas 32 */
1546 02 Mar 12 nicklas 33 public class CaliperPlateImporter
3835 11 Apr 16 nicklas 34   extends AbstractPlateImporter
1546 02 Mar 12 nicklas 35 {
1546 02 Mar 12 nicklas 36
1904 13 Mar 13 nicklas 37   private final String plateNamePrefix;
1904 13 Mar 13 nicklas 38   private final Pattern plateNamePattern;
1904 13 Mar 13 nicklas 39
1546 02 Mar 12 nicklas 40   
1904 13 Mar 13 nicklas 41   public CaliperPlateImporter(String plateNamePrefix)
1546 02 Mar 12 nicklas 42   {
1904 13 Mar 13 nicklas 43     this.plateNamePrefix = plateNamePrefix;
1904 13 Mar 13 nicklas 44     this.plateNamePattern = Pattern.compile(plateNamePrefix+"\\d+");
1546 02 Mar 12 nicklas 45   }
1546 02 Mar 12 nicklas 46   
1546 02 Mar 12 nicklas 47   
1546 02 Mar 12 nicklas 48   /**
1546 02 Mar 12 nicklas 49     Import data from the input stream.
1546 02 Mar 12 nicklas 50     @param in
1546 02 Mar 12 nicklas 51   */
2675 17 Sep 14 nicklas 52   public boolean doImport(DbControl dc, InputStream in, boolean validateOnly, String fileName)
1546 02 Mar 12 nicklas 53     throws IOException
1546 02 Mar 12 nicklas 54   {
3835 11 Apr 16 nicklas 55     reset();
1561 15 Mar 12 nicklas 56     Map<String,Integer> locations = new HashMap<String, Integer>();
1546 02 Mar 12 nicklas 57
1546 02 Mar 12 nicklas 58     FlatFileParser ffp = getFlatFileParser();
1546 02 Mar 12 nicklas 59     ffp.setInputStream(in, "UTF-8");
2675 17 Sep 14 nicklas 60     LineType headerLine = ffp.parseHeaders();
2675 17 Sep 14 nicklas 61     int lineNo = ffp.getParsedLines();
2675 17 Sep 14 nicklas 62     if (headerLine != LineType.DATA_HEADER)
1546 02 Mar 12 nicklas 63     {
2675 17 Sep 14 nicklas 64       addErrorMessage("File '" + fileName + "' line " + lineNo + ": Could not find header line starting with 'Plate Name,Well Label,Sample Name...'");
1546 02 Mar 12 nicklas 65       return false; // Can't continue if no data is found in the file
1546 02 Mar 12 nicklas 66     }
1546 02 Mar 12 nicklas 67     
2536 01 Jul 14 nicklas 68     boolean useComma = ffp.getLine(ffp.getLineCount()-1).line().startsWith("Plate Name,");
2536 01 Jul 14 nicklas 69     ffp.setDataSplitterRegexp(Pattern.compile(useComma ? "," : "\t"));
2536 01 Jul 14 nicklas 70     
1546 02 Mar 12 nicklas 71     Mapper plateMapper = ffp.getMapper("\\Plate Name\\");
1546 02 Mar 12 nicklas 72     Mapper wellMapper = ffp.getMapper("\\Well Label\\");
1546 02 Mar 12 nicklas 73     Mapper nameMapper = ffp.getMapper("\\Sample Name\\");
1546 02 Mar 12 nicklas 74     
1546 02 Mar 12 nicklas 75     Map<String, Mapper> amap = new HashMap<String, Mapper>();
1546 02 Mar 12 nicklas 76     ffp.setIgnoreNonExistingColumns(true);
1546 02 Mar 12 nicklas 77     
3835 11 Apr 16 nicklas 78     for (String col : getAnnotationMappings().keySet())
1546 02 Mar 12 nicklas 79     {
1546 02 Mar 12 nicklas 80       if (ffp.getColumnHeaderIndex(col) != null)
1546 02 Mar 12 nicklas 81       {
1546 02 Mar 12 nicklas 82         Mapper m = ffp.getMapper("\\" + col + "\\");
1546 02 Mar 12 nicklas 83         amap.put(col, m);
1546 02 Mar 12 nicklas 84       }
1546 02 Mar 12 nicklas 85       else
1546 02 Mar 12 nicklas 86       {
2675 17 Sep 14 nicklas 87         addErrorMessage("File '" + fileName + "' line " + lineNo + ": Column '" + col + "' not found in column headers.");
1546 02 Mar 12 nicklas 88       }
1546 02 Mar 12 nicklas 89     }
1546 02 Mar 12 nicklas 90     
1546 02 Mar 12 nicklas 91     // Return if there are any errors so far
1546 02 Mar 12 nicklas 92     if (hasError()) return false;
1546 02 Mar 12 nicklas 93     
1963 07 May 13 nicklas 94     int numExtractsByName = 0;
1963 07 May 13 nicklas 95     int numExtractsByLocation = 0;
2836 20 Oct 14 nicklas 96     boolean hasLoadedPlateExtracts = false;
1963 07 May 13 nicklas 97     
3835 11 Apr 16 nicklas 98     BioPlate plate = getBioPlate();
3835 11 Apr 16 nicklas 99     
1546 02 Mar 12 nicklas 100     while (ffp.hasMoreData())
1546 02 Mar 12 nicklas 101     {
1546 02 Mar 12 nicklas 102       FlatFileParser.Data data = ffp.nextData();
2675 17 Sep 14 nicklas 103       lineNo = ffp.getParsedLines();
2675 17 Sep 14 nicklas 104       String fileAndLine = "File '" + fileName + "' line " + lineNo + ": ";
1546 02 Mar 12 nicklas 105       boolean errorOnThisLine = false;
1546 02 Mar 12 nicklas 106       
1546 02 Mar 12 nicklas 107       // Check that the "Plate Name" is a valid entry
5364 16 Apr 19 nicklas 108       String plateName = plateMapper.getString(data);
1546 02 Mar 12 nicklas 109       if (plate == null)
1546 02 Mar 12 nicklas 110       {
2675 17 Sep 14 nicklas 111         plate = findBioPlate(dc, plateName, fileAndLine);
1546 02 Mar 12 nicklas 112         if (plate == null) errorOnThisLine = true;
3835 11 Apr 16 nicklas 113         setBioPlate(plate);
1546 02 Mar 12 nicklas 114       }
1546 02 Mar 12 nicklas 115       else
1546 02 Mar 12 nicklas 116       {
2675 17 Sep 14 nicklas 117         if (!checkBioPlate(dc, plateName, plate, fileAndLine))
1546 02 Mar 12 nicklas 118         {
1546 02 Mar 12 nicklas 119           errorOnThisLine = true;
1546 02 Mar 12 nicklas 120         }
1546 02 Mar 12 nicklas 121       }
1546 02 Mar 12 nicklas 122       
1546 02 Mar 12 nicklas 123       if (errorOnThisLine) continue; // with the next line
1546 02 Mar 12 nicklas 124       
2836 20 Oct 14 nicklas 125       if (!hasLoadedPlateExtracts)
2836 20 Oct 14 nicklas 126       {
3835 11 Apr 16 nicklas 127         if (plate != null)
2836 20 Oct 14 nicklas 128         {
3835 11 Apr 16 nicklas 129           getMissingExtracts().addAll(loadExtractsOnPlate(dc, plate));
2836 20 Oct 14 nicklas 130         }
2836 20 Oct 14 nicklas 131         hasLoadedPlateExtracts = true;
2836 20 Oct 14 nicklas 132       }
2836 20 Oct 14 nicklas 133       
1546 02 Mar 12 nicklas 134       // Check that the "Sample Name" column maps to a valid extract
5364 16 Apr 19 nicklas 135       String extractName = nameMapper.getString(data);
5364 16 Apr 19 nicklas 136       String location = wellMapper.getString(data);
1546 02 Mar 12 nicklas 137       
1963 07 May 13 nicklas 138       Extract extract = null;
3835 11 Apr 16 nicklas 139       if (allowMatchAgainstLocation() && extractName.matches("\\w\\d\\d?"))
1963 07 May 13 nicklas 140       {
2675 17 Sep 14 nicklas 141         extract = findExtractByLocation(dc, plate, extractName, fileAndLine);
1963 07 May 13 nicklas 142         if (extract != null) 
1963 07 May 13 nicklas 143         {
1963 07 May 13 nicklas 144           numExtractsByLocation++;
2675 17 Sep 14 nicklas 145           addWarningMessage(fileAndLine + "No sample name, extract '" + extract.getName() + "' found using location '" + extractName + "'");
1963 07 May 13 nicklas 146           extractName = extract.getName();
1963 07 May 13 nicklas 147         }
1963 07 May 13 nicklas 148       }
1963 07 May 13 nicklas 149       else
1963 07 May 13 nicklas 150       {
2675 17 Sep 14 nicklas 151         extract = findExtractByName(dc, plate, extractName, location, fileAndLine);
1963 07 May 13 nicklas 152         if (extract != null) numExtractsByName++;
1963 07 May 13 nicklas 153       }
1963 07 May 13 nicklas 154
1963 07 May 13 nicklas 155       
1546 02 Mar 12 nicklas 156       if (extract == null) continue; // with the next line
3835 11 Apr 16 nicklas 157       getExtracts().add(extract);
3835 11 Apr 16 nicklas 158       getMissingExtracts().remove(extract);
1906 14 Mar 13 nicklas 159       
1546 02 Mar 12 nicklas 160       // Validate that the location is the same in BASE and the CSV
2675 17 Sep 14 nicklas 161       if (!checkLocation(dc, extract, location, fileAndLine)) continue; // with the next line
1561 15 Mar 12 nicklas 162       
1561 15 Mar 12 nicklas 163       // Check that the same location has not been seen before in this file
1561 15 Mar 12 nicklas 164       if (locations.containsKey(location))
1561 15 Mar 12 nicklas 165       {
2675 17 Sep 14 nicklas 166         addErrorMessage(fileAndLine + "Duplicate well '" + location + "' with extract '" + extractName + "'. Also found on line " + locations.get(location) + ".");
1561 15 Mar 12 nicklas 167         continue; // with the next line
1561 15 Mar 12 nicklas 168       }
1561 15 Mar 12 nicklas 169       locations.put(location, lineNo);
1561 15 Mar 12 nicklas 170       
1546 02 Mar 12 nicklas 171       // Load annotations
1546 02 Mar 12 nicklas 172       AnnotationSet as = extract.getAnnotationSet();
3835 11 Apr 16 nicklas 173       for (String col : getAnnotationMappings().keySet())
1546 02 Mar 12 nicklas 174       {
1561 15 Mar 12 nicklas 175         try
1561 15 Mar 12 nicklas 176         {
1561 15 Mar 12 nicklas 177           Mapper m = amap.get(col);
3835 11 Apr 16 nicklas 178           AnnotationType at = getAnnotationMappings().get(col);
3835 11 Apr 16 nicklas 179           ValueConverter<String, ?> vc = getColumnConverters().get(col);
1561 15 Mar 12 nicklas 180           
5364 16 Apr 19 nicklas 181           String sval = m.getString(data);
1563 16 Mar 12 nicklas 182           if (at.getValueType().isNumerical())
1563 16 Mar 12 nicklas 183           {
1707 14 Jun 12 nicklas 184             if (sval != null)
1707 14 Jun 12 nicklas 185             {  
1707 14 Jun 12 nicklas 186               if (sval.startsWith("[") && sval.endsWith("]"))
1707 14 Jun 12 nicklas 187               {
1707 14 Jun 12 nicklas 188                 // Replace numbers in [] with a negative value
1707 14 Jun 12 nicklas 189                 // Eg. [8.0] --> -8.0
2675 17 Sep 14 nicklas 190                 addWarningMessage(fileAndLine + "Location '" + location + "' with extract '" + 
1707 14 Jun 12 nicklas 191                     extractName + "' has flagged '" + col + "': " + sval);
1707 14 Jun 12 nicklas 192                 sval = "-"+sval.substring(1, sval.length()-1);
1707 14 Jun 12 nicklas 193               }
1707 14 Jun 12 nicklas 194               else if (sval.equalsIgnoreCase("NA"))
1707 14 Jun 12 nicklas 195               {
1707 14 Jun 12 nicklas 196                 // Replace "NA" values with -100
2675 17 Sep 14 nicklas 197                 addWarningMessage(fileAndLine + "Location '" + location + "' with extract '" + 
1707 14 Jun 12 nicklas 198                     extractName + "' has '" + col + "'=" + sval + "; using -100 instead");
1707 14 Jun 12 nicklas 199                 sval = "-100";
1707 14 Jun 12 nicklas 200               }
1563 16 Mar 12 nicklas 201             }
1563 16 Mar 12 nicklas 202           }
1563 16 Mar 12 nicklas 203           
2454 23 May 14 nicklas 204           Object val = vc == null ? sval : vc.convert(sval);
2454 23 May 14 nicklas 205           Type valueType = at.getValueType();
2454 23 May 14 nicklas 206           if (!valueType.isCorrectType(val) && val != null)
2454 23 May 14 nicklas 207           {
2454 23 May 14 nicklas 208             // Parse string values into the correct type
2454 23 May 14 nicklas 209             val = valueType.parseString(val.toString());
2454 23 May 14 nicklas 210           }
2454 23 May 14 nicklas 211
1966 08 May 13 nicklas 212           if (!validateOnly)
1966 08 May 13 nicklas 213           {
3861 22 Apr 16 nicklas 214             if (val != null) as.getAnnotation(at).setValueIfDifferent(val, null);
1966 08 May 13 nicklas 215           }
1906 14 Mar 13 nicklas 216           
1906 14 Mar 13 nicklas 217           // For debugging
1906 14 Mar 13 nicklas 218           //addWarningMessage(extractName + ": " + at.getName() + "=" + sval);
1906 14 Mar 13 nicklas 219           
1561 15 Mar 12 nicklas 220         }
1561 15 Mar 12 nicklas 221         catch (RuntimeException ex)
1561 15 Mar 12 nicklas 222         {
2960 19 Nov 14 nicklas 223           addErrorMessage(fileAndLine + "Location '" + location + "' with extract '" + 
2960 19 Nov 14 nicklas 224               extractName + "' " + ex.getMessage());
1561 15 Mar 12 nicklas 225           errorOnThisLine = true;
1561 15 Mar 12 nicklas 226         }
1546 02 Mar 12 nicklas 227       }
1904 13 Mar 13 nicklas 228       
1904 13 Mar 13 nicklas 229       // External lookup
3835 11 Apr 16 nicklas 230       for (Map.Entry<ValueConverter<String, ?>, AnnotationType> entry : getExternalLookups().entrySet())
1904 13 Mar 13 nicklas 231       {
1904 13 Mar 13 nicklas 232         try
1904 13 Mar 13 nicklas 233         {
1906 14 Mar 13 nicklas 234           ValueConverter<String, ?> lookup = entry.getKey();
1904 13 Mar 13 nicklas 235           AnnotationType at = entry.getValue();
1904 13 Mar 13 nicklas 236           // Do not need to apply Caliper-specific parsing for external data!
1904 13 Mar 13 nicklas 237           Object val = lookup.convert(extractName);
1904 13 Mar 13 nicklas 238           Type valueType = at.getValueType();
1904 13 Mar 13 nicklas 239           if (!valueType.isCorrectType(val) && val != null)
1904 13 Mar 13 nicklas 240           {
1925 11 Apr 13 nicklas 241             // Parse string values into the correct type
1904 13 Mar 13 nicklas 242             val = valueType.parseString(val.toString());
1925 11 Apr 13 nicklas 243           }
1925 11 Apr 13 nicklas 244           
1966 08 May 13 nicklas 245           if (!validateOnly)
1966 08 May 13 nicklas 246           {
3861 22 Apr 16 nicklas 247             if (val != null) as.getAnnotation(at).setValueIfDifferent(val, null);
1966 08 May 13 nicklas 248           }
1906 14 Mar 13 nicklas 249
1906 14 Mar 13 nicklas 250           // For debugging
1906 14 Mar 13 nicklas 251           // addWarningMessage(extractName + ": " + at.getName() + "=" + val);
1904 13 Mar 13 nicklas 252         }
1904 13 Mar 13 nicklas 253         catch (RuntimeException ex)
1904 13 Mar 13 nicklas 254         {
2825 16 Oct 14 nicklas 255           addExternalErrorMessage(ex.getMessage());
1904 13 Mar 13 nicklas 256           errorOnThisLine = true;
1904 13 Mar 13 nicklas 257         }
1904 13 Mar 13 nicklas 258       }
1904 13 Mar 13 nicklas 259       
1561 15 Mar 12 nicklas 260       if (errorOnThisLine) continue; // with the next line
3835 11 Apr 16 nicklas 261       addImported();
1546 02 Mar 12 nicklas 262     }
1546 02 Mar 12 nicklas 263     
1963 07 May 13 nicklas 264     if (numExtractsByLocation > numExtractsByName)
1963 07 May 13 nicklas 265     {
1966 08 May 13 nicklas 266       addErrorMessage("Too many lines have location instead of 'Sample name': " + numExtractsByLocation + " of " + (numExtractsByLocation+numExtractsByName));
1963 07 May 13 nicklas 267     }
1963 07 May 13 nicklas 268
2825 16 Oct 14 nicklas 269     return !hasError() && !hasExternalError();
1546 02 Mar 12 nicklas 270   }
1546 02 Mar 12 nicklas 271   
3835 11 Apr 16 nicklas 272
1546 02 Mar 12 nicklas 273   protected FlatFileParser getFlatFileParser()
1546 02 Mar 12 nicklas 274   {
1546 02 Mar 12 nicklas 275     FlatFileParser ffp = new FlatFileParser();
1546 02 Mar 12 nicklas 276     
2536 01 Jul 14 nicklas 277     ffp.setDataHeaderRegexp(Pattern.compile("Plate Name(,|\t)Well Label(,|\t)Sample Name(,|\t).*"));
2536 01 Jul 14 nicklas 278     ffp.setDataSplitterRegexp(Pattern.compile(",|\t")); // Split on comma or tab to begin with
1546 02 Mar 12 nicklas 279     
1546 02 Mar 12 nicklas 280     ffp.setIgnoreRegexp(Pattern.compile(".*Ladder.*")); // Ignore all lines that contain 'Ladder'
1546 02 Mar 12 nicklas 281     
1546 02 Mar 12 nicklas 282     return ffp;
1546 02 Mar 12 nicklas 283   }
1546 02 Mar 12 nicklas 284   
1546 02 Mar 12 nicklas 285   /**
1546 02 Mar 12 nicklas 286     Convert the bioplate name found in the Caliper output file
1546 02 Mar 12 nicklas 287     to a plate name that is used in BASE. The default implementation
1904 13 Mar 13 nicklas 288     will look for {platePrefix}NNNN in the Caliper plate name and
1546 02 Mar 12 nicklas 289     use only that part.
1546 02 Mar 12 nicklas 290     @return The BASE plate name, or null if the expected pattern could
1546 02 Mar 12 nicklas 291       not be found
1546 02 Mar 12 nicklas 292   */
1546 02 Mar 12 nicklas 293   protected String getBasePlateName(String caliperPlateName)
1546 02 Mar 12 nicklas 294   {
1888 27 Feb 13 nicklas 295     String matched = null;
1888 27 Feb 13 nicklas 296     if (caliperPlateName != null)
1888 27 Feb 13 nicklas 297     {
1904 13 Mar 13 nicklas 298       Matcher m = plateNamePattern.matcher(caliperPlateName);
1888 27 Feb 13 nicklas 299       if (m.find()) matched = m.group();
1888 27 Feb 13 nicklas 300     }
1888 27 Feb 13 nicklas 301     return matched;
1546 02 Mar 12 nicklas 302   }
1546 02 Mar 12 nicklas 303   
1546 02 Mar 12 nicklas 304   /**
1546 02 Mar 12 nicklas 305     Find a bioplate given the name as it appears in the Caliper output
1546 02 Mar 12 nicklas 306     file. This name may include prefix and/or suffix to the name the
1546 02 Mar 12 nicklas 307     plate has in BASE.
1546 02 Mar 12 nicklas 308     @return The bioplate, or null if no bioplate can be loaded (error condition)
1546 02 Mar 12 nicklas 309   */
2675 17 Sep 14 nicklas 310   protected BioPlate findBioPlate(DbControl dc, String caliperPlateName, String fileAndLine)
1546 02 Mar 12 nicklas 311   {
1546 02 Mar 12 nicklas 312     String basePlateName = getBasePlateName(caliperPlateName);
1546 02 Mar 12 nicklas 313     
1546 02 Mar 12 nicklas 314     if (basePlateName == null)
1546 02 Mar 12 nicklas 315     {
2675 17 Sep 14 nicklas 316       addErrorMessage(fileAndLine + "Plate name doesn't match expected pattern (" + plateNamePrefix + "NNNN): " + caliperPlateName);
1546 02 Mar 12 nicklas 317       return null;
1546 02 Mar 12 nicklas 318     }
1546 02 Mar 12 nicklas 319     
1546 02 Mar 12 nicklas 320     ItemQuery<BioPlate> query = BioPlate.getQuery();
1546 02 Mar 12 nicklas 321     query.restrict(Restrictions.eq(Hql.property("name"), Expressions.string(basePlateName)));
1546 02 Mar 12 nicklas 322     List<BioPlate> list = query.list(dc);
1546 02 Mar 12 nicklas 323     
1546 02 Mar 12 nicklas 324     BioPlate plate = null;
1546 02 Mar 12 nicklas 325     if (list.size() == 0)
1546 02 Mar 12 nicklas 326     {
2675 17 Sep 14 nicklas 327       addErrorMessage(fileAndLine + "Could not find any registered bioplate with name: " + basePlateName);
1546 02 Mar 12 nicklas 328     }
1546 02 Mar 12 nicklas 329     else if (list.size() > 1)
1546 02 Mar 12 nicklas 330     {
2675 17 Sep 14 nicklas 331       addErrorMessage(fileAndLine + ": Found " + list.size() + " registered bioplates with the same name: " + basePlateName);
1546 02 Mar 12 nicklas 332     }
1546 02 Mar 12 nicklas 333     else
1546 02 Mar 12 nicklas 334     {
1546 02 Mar 12 nicklas 335       plate = list.get(0);
1546 02 Mar 12 nicklas 336     }
1546 02 Mar 12 nicklas 337     return plate;
1546 02 Mar 12 nicklas 338   }
1546 02 Mar 12 nicklas 339   
1546 02 Mar 12 nicklas 340   /**
1546 02 Mar 12 nicklas 341     Check the the given caliper plate name matches the BASE bioplate name.
1546 02 Mar 12 nicklas 342   */
2675 17 Sep 14 nicklas 343   protected boolean checkBioPlate(DbControl dc, String caliperPlateName, BioPlate plate, String fileAndLine)
1546 02 Mar 12 nicklas 344   {
1546 02 Mar 12 nicklas 345     String basePlateName = getBasePlateName(caliperPlateName);
1546 02 Mar 12 nicklas 346     if (basePlateName == null)
1546 02 Mar 12 nicklas 347     {
2675 17 Sep 14 nicklas 348       addErrorMessage(fileAndLine + "Plate name doesn't match expected pattern (" + plateNamePrefix + "NNNN): " + caliperPlateName);
1546 02 Mar 12 nicklas 349       return false;
1546 02 Mar 12 nicklas 350     }
1546 02 Mar 12 nicklas 351     
1546 02 Mar 12 nicklas 352     if (!basePlateName.equals(plate.getName()))
1546 02 Mar 12 nicklas 353     {
2675 17 Sep 14 nicklas 354       addErrorMessage(fileAndLine + "Plate name in CSV doesn't match the actual plate name (" + plate.getName() + "): " + caliperPlateName);
1546 02 Mar 12 nicklas 355       return false;
1546 02 Mar 12 nicklas 356     }
1546 02 Mar 12 nicklas 357     
1546 02 Mar 12 nicklas 358     return true;
1546 02 Mar 12 nicklas 359   }
1546 02 Mar 12 nicklas 360
1546 02 Mar 12 nicklas 361 }