001 /** 002 * Copyright (C) 2010 The Roslin Institute <contact andy.law@roslin.ed.ac.uk> 003 * 004 * This file is part of the Ensembl Java API demonstration project developed by the 005 * Bioinformatics Group at The Roslin Institute, The Royal (Dick) School of 006 * Veterinary Studies, University of Edinburgh. 007 * 008 * This is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (version 3) as published by 010 * the Free Software Foundation. 011 * 012 * This software is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 015 * GNU General Public License for more details. 016 * 017 * You should have received a copy of the GNU General Public License 018 * in this software distribution. If not, see <http://www.gnu.org/licenses/gpl-3.0.html/>. 019 */ 020 021 package uk.ac.roslin.ensembl.datasourceaware.core; 022 023 import java.util.ArrayList; 024 import java.util.HashMap; 025 import java.util.List; 026 import uk.ac.roslin.ensembl.config.EnsemblComparaDivision; 027 import uk.ac.roslin.ensembl.model.Mapping; 028 import uk.ac.roslin.ensembl.model.MappingSet; 029 import uk.ac.roslin.ensembl.model.Coordinate; 030 import uk.ac.roslin.ensembl.model.Coordinate.Strand; 031 import uk.ac.roslin.ensembl.model.Mapping; 032 import uk.ac.roslin.ensembl.model.database.Registry; 033 import uk.ac.roslin.ensembl.model.core.CoordinateSystem; 034 import uk.ac.roslin.ensembl.dao.factory.DAOCoreFactory; 035 import uk.ac.roslin.ensembl.dao.factory.DAOFactory; 036 import uk.ac.roslin.ensembl.exception.DAOException; 037 import uk.ac.roslin.ensembl.model.CoordinateSet; 038 import uk.ac.roslin.ensembl.model.ObjectType; 039 import uk.ac.roslin.ensembl.model.core.CoreObject; 040 import uk.ac.roslin.ensembl.model.core.Species; 041 import uk.ac.roslin.ensembl.config.FeatureType; 042 import uk.ac.roslin.ensembl.dao.factory.DAOComparaFactory; 043 import uk.ac.roslin.ensembl.dao.factory.DAOSpeciesFactory; 044 import uk.ac.roslin.ensembl.model.core.CollectionSpecies; 045 import uk.ac.roslin.ensembl.model.database.CollectionDatabase; 046 import uk.ac.roslin.ensembl.model.database.SingleSpeciesDatabase; 047 048 /** 049 * 050 * @author paterson 051 */ 052 public class DADNASequence extends org.biojava3.core.sequence.DNASequence implements CoreObject, uk.ac.roslin.ensembl.model.core.DNASequence { 053 054 protected DAOFactory daoFactory = null; 055 protected String schemaVersion = null; 056 protected String dbVersion = null; 057 protected Registry registry = null; 058 protected Integer id = null; 059 protected Integer seqRegionID = null; 060 protected String name = null; 061 protected String dbSpeciesName = null; 062 protected Species species = null; 063 protected Integer DBSeqLength = null; 064 protected CoordinateSystem coordSystem = null; 065 protected MappingSet mappings = new MappingSet(); 066 protected HashMap<ObjectType, CoordinateSet> mappedRegions 067 = new HashMap<ObjectType, CoordinateSet>(); 068 protected HashMap<ObjectType, MappingSet> objectTypeMappings 069 = new HashMap<ObjectType, MappingSet>(); 070 protected HashMap<EnsemblComparaDivision, DAOComparaFactory> comparaFactories 071 = new HashMap<EnsemblComparaDivision, DAOComparaFactory>(); 072 073 public DADNASequence() { 074 super(); 075 076 } 077 078 public DADNASequence(DAEnsemblDNASequenceReader proxyLoader) { 079 super(proxyLoader); 080 ((DAEnsemblDNASequenceReader) this.getProxySequenceReader()).setParent(this); 081 this.setId(proxyLoader.getSeqRegionID()); 082 this.setDBSeqLength(proxyLoader.getLengthInteger()); 083 } 084 085 public DADNASequence(String sequence) { 086 super(new DAEnsemblDNASequenceReader()); 087 ((DAEnsemblDNASequenceReader) this.getProxySequenceReader()).setParent(this); 088 ((DAEnsemblDNASequenceReader) this.getProxySequenceReader()).setContents(sequence); 089 } 090 091 public DADNASequence(DAOCoreFactory factory) { 092 this.setDaoFactory(factory); 093 } 094 095 public void setSequenceStorage(DAEnsemblDNASequenceReader proxyLoader) { 096 this.setProxySequenceReader(proxyLoader); 097 ((DAEnsemblDNASequenceReader) this.getProxySequenceReader()).setParent(this); 098 } 099 100 public DAOCoreFactory getDaoFactory() { 101 return (DAOCoreFactory) daoFactory; 102 } 103 104 public void setDaoFactory(DAOFactory daoFactory) { 105 this.daoFactory = daoFactory; 106 if (this.daoFactory!= null) { 107 this.setSchemaVersion(daoFactory.getEnsemblSchemaVersion()); 108 this.setDBVersion(daoFactory.getDBVersion()); 109 this.setRegistry((Registry) daoFactory.getRegistry()); 110 } 111 } 112 113 public String getSchemaVersion() { 114 return schemaVersion; 115 } 116 117 private void setSchemaVersion(String schemaVersion) { 118 this.schemaVersion = schemaVersion; 119 } 120 121 public String getDBVersion() { 122 return dbVersion; 123 } 124 125 private void setDBVersion(String dbversion) { 126 this.dbVersion = dbversion; 127 } 128 129 public Registry getRegistry() { 130 return registry; 131 } 132 133 public void setRegistry(Registry datasource) { 134 this.registry = datasource; 135 } 136 137 public Integer getId() { 138 return id; 139 } 140 141 public void setId(Integer id) { 142 this.id = id; 143 } 144 145 public String getDBName() { 146 return (daoFactory!= null)?daoFactory.getDatabaseName():null; 147 } 148 149 public Species getSpecies() { 150 if (species == null && this.daoFactory != null && this.daoFactory instanceof DAOSpeciesFactory) { 151 species = ((DAOSpeciesFactory) this.daoFactory).getSpecies(); 152 } 153 return species; 154 } 155 156 public void setSpecies(Species species) { 157 this.species = species; 158 } 159 160 public ObjectType getType() { 161 //forces a lazy load so make sure we get CS for all retrieved sequenceIDS in the first query! 162 if (this.getCoordSystem() != null) { 163 return this.getCoordSystem().getType(); 164 } else { 165 return null; 166 } 167 } 168 169 public Integer getDBSeqLength() { 170 if (DBSeqLength == null) { 171 this.lazyLoad(); 172 } 173 if (DBSeqLength != null) { 174 return DBSeqLength; 175 } else { return 0;} 176 } 177 178 public void setDBSeqLength(Integer seqLength) { 179 this.DBSeqLength = seqLength; 180 this.setBioEnd(seqLength); 181 } 182 183 @Override 184 public Integer getBioEnd() { 185 186 try { 187 return (super.getBioEnd() != null) ? super.getBioEnd() : this.getDBSeqLength(); 188 } catch (NullPointerException e) { 189 return this.getDBSeqLength(); 190 } 191 } 192 193 @Override 194 public int getLength() { 195 196 try { 197 return super.getLength(); 198 } catch (NullPointerException e) { 199 return this.getDBSeqLength(); 200 } 201 } 202 203 public String getName() { 204 if (name == null) { 205 this.lazyLoad(); 206 } 207 return name; 208 } 209 210 public void setName(String name) { 211 this.name = name; 212 } 213 214 public CoordinateSystem getCoordSystem() { 215 216 if (coordSystem == null) { 217 this.lazyLoad(); 218 } 219 220 return coordSystem; 221 } 222 223 public void setCoordSystem(CoordinateSystem coordSystem) { 224 this.coordSystem = coordSystem; 225 } 226 227 public MappingSet getMappings() { 228 return this.mappings; 229 } 230 231 //Should Be Private?? 232 public MappingSet getMappings(ObjectType targetType) { 233 234 //need to add lazy load here? 235 236 if (!this.objectTypeMappings.containsKey(targetType)) { 237 return new MappingSet(); 238 } else { 239 return this.objectTypeMappings.get(targetType); 240 } 241 } 242 243 public Boolean addMapping(Mapping mapping) { 244 245 // //check we haven't already added a mapping for an object with this id! 246 // if (mapping.getTarget() != null) { 247 // 248 // for (Mapping m : this.mappings) { 249 // if (m.getTarget() != null && m.getTarget().getId().equals(mapping.getTarget().getId())) { 250 // return; 251 // } 252 // } 253 // } 254 255 //if we fail to add the mapping this will be false 256 if (this.mappings.add((Mapping) mapping)) { 257 258 ObjectType t = mapping.getTargetType(); 259 260 if (t != null) { 261 if (!this.objectTypeMappings.containsKey(t)) { 262 this.objectTypeMappings.put(t, new MappingSet()); 263 } 264 265 this.objectTypeMappings.get(t).add((Mapping) mapping); 266 } 267 return true; 268 } 269 return false; 270 } 271 272 public List<DAGene> getGenesOnRegion(Coordinate coord) throws DAOException { 273 274 List<DAGene> out = new ArrayList<DAGene>(); 275 276 List<? extends Mapping> mappings = null; 277 278 //test if we already have got the genes for this coordinate region 279 if (this.mappedRegions.containsKey(FeatureType.gene) 280 && this.mappedRegions.get(FeatureType.gene).containsCoordinateWithoutGaps(coord)) { 281 282 //we need a temporary pointer here so we can match the signatures 283 ArrayList<Mapping> theseMappings = new ArrayList<Mapping>(); 284 285 //find and return genes in this region 286 for (Mapping m : this.getMappings(FeatureType.gene)) { 287 Coordinate c = m.getSourceCoordinates(); 288 if (c.overlaps(coord)) { 289 theseMappings.add(m); 290 } 291 } 292 mappings = theseMappings; 293 294 if (mappings == null || mappings.isEmpty()) { 295 return out; 296 } else { 297 //these mappings are seq -> gene 298 299 if (coord.getStrand() == null) { 300 for (Mapping m : mappings) { 301 out.add((DAGene) m.getTarget()); 302 //already done in the DAO 303 //this.addMapping(m); 304 305 } 306 } else { 307 for (Mapping m : mappings) { 308 if (m.getSourceCoordinates().getStrand().equals(coord.getStrand())) { 309 out.add((DAGene) m.getTarget()); 310 } 311 //already done in the DAO 312 //this.addMapping(m); 313 } 314 } 315 } 316 return out; 317 318 } else { 319 320 if (this.getDaoFactory() != null && this.getDaoFactory().getGeneDAO() != null) { 321 322 mappings = this.getDaoFactory().getGeneDAO().getGeneMappingsOnRegion(this, coord); 323 } 324 325 if (mappings == null || mappings.isEmpty()) { 326 return out; 327 } else { 328 //these mappings ade gene->seq 329 if (coord.getStrand() == null) { 330 for (Mapping m : mappings) { 331 out.add((DAGene) m.getSource()); 332 //already done in the DAO 333 //this.addMapping(m); 334 335 } 336 } else { 337 for (Mapping m : mappings) { 338 if (m.getTargetCoordinates().getStrand().equals(coord.getStrand())) { 339 out.add((DAGene) m.getSource()); 340 } 341 //already done in the DAO 342 //this.addMapping(m); 343 } 344 } 345 } 346 347 //put this region in the sore of mapped regions 348 if (!mappedRegions.containsKey(FeatureType.gene)) { 349 mappedRegions.put(FeatureType.gene, new CoordinateSet()); 350 } 351 this.mappedRegions.get(FeatureType.gene).add(coord); 352 return out; 353 } 354 } 355 356 public List<DAGene> getGenesOnRegion(Integer start, Integer stop, Strand strand) throws DAOException { 357 358 Strand s = strand; 359 Integer begin = null; 360 Integer end = null; 361 362 // if (s == null) { 363 // s = Strand.FORWARD_STRAND; 364 // } 365 366 if (start != null && stop != null && start.doubleValue() > stop.doubleValue()) { 367 begin = stop; 368 end = start; 369 } else { 370 begin = start; 371 end = stop; 372 } 373 374 Coordinate coord = new Coordinate(start, stop, strand); 375 return this.getGenesOnRegion(coord); 376 377 } 378 379 public List<DAGene> getGenesOnRegion(Integer start, Integer stop) throws DAOException { 380 381 return this.getGenesOnRegion(start, stop, null); 382 } 383 384 private void lazyLoad() { 385 386 if (this.id != null && this.getDaoFactory() != null) { 387 try { 388 DADNASequence fetchedSeq = (DADNASequence) this.getDaoFactory().getSequenceDAO().getSequenceByID(id); 389 this.setName(fetchedSeq.getName()); 390 this.setDBSeqLength(fetchedSeq.getDBSeqLength()); 391 this.setCoordSystem(fetchedSeq.getCoordSystem()); 392 } catch (Exception ex) { 393 } 394 } 395 } 396 397 public String getSequenceAsString(Integer begin, Integer end) { 398 if (this.getLength()==0) { 399 return ""; 400 } 401 return super.getSequenceAsString(begin, end, org.biojava3.core.sequence.Strand.POSITIVE); 402 } 403 404 public String getReverseComplementSequenceAsString(Integer begin, Integer end) { 405 if (this.getLength()==0) { 406 return ""; 407 } 408 DAEnsemblDNASequenceReader ss = (DAEnsemblDNASequenceReader) getProxySequenceReader(); 409 return ss.getReverseComplementSequenceAsString(begin, end); 410 } 411 412 public String getReverseComplementSequenceAsString() { 413 if (this.getLength()==0) { 414 return ""; 415 } 416 return this.getReverseComplementSequenceAsString(this.getBioBegin(), this.getBioEnd()); 417 } 418 419 public HashMap<ObjectType, MappingSet> getObjectTypeMappings() { 420 return objectTypeMappings; 421 } 422 423 public HashMap<ObjectType, CoordinateSet> getMappedRegions() { 424 return mappedRegions; 425 } 426 427 public String getHashID() { 428 return 429 ((this.getDaoFactory()!=null) ? this.getDaoFactory().getDatabaseName() : "NODATABASE") 430 431 +"_" 432 433 +((this.getType()!=null) ? this.getType().toString() : "NOTYPE") 434 435 +"_" 436 437 +((this.getId()!=null) ? this.getId().toString() : "NOID"); 438 } 439 440 @Override 441 public String toString() { 442 return ((this.getId()!=null) ? this.getId().toString() : "NOID"); 443 } 444 445 public void clearAllMappings() { 446 mappings.clear(); 447 mappedRegions.clear(); 448 objectTypeMappings.clear(); 449 } 450 451 public EnsemblComparaDivision getComparaDivision() { 452 if (this.getSpecies()==null) { 453 return null; 454 } 455 return this.getSpecies().getComparaDivision(); 456 } 457 458 public DAOComparaFactory getComparaFactory(EnsemblComparaDivision comparaDivision) { 459 460 if (comparaFactories.containsKey(comparaDivision)) { 461 return comparaFactories.get(comparaDivision); 462 } else if (this.getDaoFactory() != null) { 463 DAOComparaFactory f = this.getDaoFactory().getComparaFactory(comparaDivision); 464 comparaFactories.put(comparaDivision, f); 465 return f; 466 } 467 return null; 468 } 469 470 public DAOComparaFactory getComparaFactory() { 471 472 EnsemblComparaDivision comparaDivision = this.getComparaDivision(); 473 474 if (comparaFactories.containsKey(comparaDivision)) { 475 return comparaFactories.get(comparaDivision); 476 } else if (this.getDaoFactory() != null) { 477 DAOComparaFactory f = this.getDaoFactory().getComparaFactory(comparaDivision); 478 comparaFactories.put(comparaDivision, f); 479 return f; 480 } 481 return null; 482 } 483 484 public String getAssembly() { 485 486 if (this.getSpecies() == null || this.getDaoFactory() == null 487 || this.getDaoFactory().getDatabase() == null) { 488 return null; 489 } 490 491 try { 492 493 if (this.getSpecies() instanceof CollectionSpecies) { 494 return ((CollectionDatabase) this.getDaoFactory().getDatabase()).getAssembly( 495 (CollectionSpecies) this.getSpecies()); 496 497 } else { 498 return ((SingleSpeciesDatabase) this.getDaoFactory().getDatabase()).getAssembly(); 499 500 } 501 } catch (Exception e) { 502 return null; 503 } 504 505 } 506 507 508 }