001/** 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 * Author: Andreas Prlic 021 * 022 * 023 */ 024 025package org.biojava.nbio.structure.scop; 026 027import java.io.BufferedReader; 028import java.io.File; 029import java.io.FileNotFoundException; 030import java.io.IOException; 031import java.io.InputStreamReader; 032import java.net.URL; 033import java.util.ArrayList; 034import java.util.Arrays; 035import java.util.Collections; 036import java.util.HashMap; 037import java.util.List; 038import java.util.Map; 039import java.util.TreeMap; 040import java.util.concurrent.atomic.AtomicBoolean; 041 042import org.biojava.nbio.core.util.FileDownloadUtils; 043import org.biojava.nbio.core.util.InputStreamProvider; 044import org.biojava.nbio.structure.PdbId; 045import org.biojava.nbio.structure.Structure; 046import org.biojava.nbio.structure.StructureTools; 047import org.biojava.nbio.structure.align.util.UserConfiguration; 048import org.slf4j.Logger; 049import org.slf4j.LoggerFactory; 050 051 052/** 053 * This class provides access to the SCOP protein structure classification. 054 * 055 * For more information about SCOP see here: 056 * <ul> 057 * <li>SCOP: <a href="http://scop.mrc-lmb.cam.ac.uk/scop/">http://scop.mrc-lmb.cam.ac.uk/scop/</a></li> 058 059 * <li> Introduction: <a href="http://scop.mrc-lmb.cam.ac.uk/scop/intro.html">http://scop.mrc-lmb.cam.ac.uk/scop/intro.html</a> </li> 060 061 * <li> SCOP parsable files: <a href="http://scop.mrc-lmb.cam.ac.uk/scop/parse/">http://scop.mrc-lmb.cam.ac.uk/scop/parse/</a> </li> 062 * </ul> 063 064 * 065 * This class can automatically download missing files from the SCOP classification. 066 * 067 * @author Andreas Prlic 068 * 069 */ 070public class ScopInstallation implements LocalScopDatabase { 071 072 public static final String DEFAULT_VERSION = ScopFactory.LATEST_VERSION; 073 074 private static final Logger logger = LoggerFactory.getLogger(ScopInstallation.class); 075 076 private String scopVersion; 077 078 // Stores URLs for cla, des, hie, and com files 079 private final List<ScopMirror> mirrors; 080 081 // Cache filenames (with version appended) 082 public static final String claFileName = "dir.cla.scop.txt_"; 083 public static final String desFileName = "dir.des.scop.txt_"; 084 public static final String hieFileName = "dir.hie.scop.txt_"; 085 public static final String comFileName = "dir.com.scop.txt_"; 086 087 // Download locations 088 public static final String SCOP_DOWNLOAD = "https://scop.berkeley.edu/downloads/parse/"; 089 public static final String SCOP_DOWNLOAD_ALTERNATE = "https://scop.berkeley.edu/downloads/parse/"; 090 091 //public static final String NEWLINE = System.getProperty("line.separator"); 092 public static final String FILESPLIT = System.getProperty("file.separator"); 093 094 private String cacheLocation ; 095 096 private AtomicBoolean installedCla; 097 private AtomicBoolean installedDes; 098 private AtomicBoolean installedHie; 099 private AtomicBoolean installedCom; 100 101 private Map<Integer, List<String>> commentsMap; 102 private Map<String, List<ScopDomain>> domainMap; 103 private Map<Integer, ScopDescription> sunidMap; 104 private Map<Integer, ScopNode> scopTree; 105 106 107 /** 108 * Create a new SCOP installation. 109 * 110 * @param cacheLocation where the SCOP files are stored. If they can't be found at that location they will get automatically downloaded and installed there. 111 */ 112 public ScopInstallation(String cacheLocation){ 113 114 setCacheLocation(cacheLocation); 115 116 installedCla = new AtomicBoolean(); 117 installedCla.set(false); 118 installedDes = new AtomicBoolean(); 119 installedDes.set(false); 120 installedHie = new AtomicBoolean(); 121 installedHie.set(false); 122 installedCom = new AtomicBoolean(); 123 installedCom.set(false); 124 125 scopVersion = DEFAULT_VERSION; 126 mirrors = new ArrayList<>(1); 127 128 domainMap = new HashMap<>(); 129 130 sunidMap = new HashMap<>(); 131 scopTree = new TreeMap<>(); 132 133 } 134 135 /** 136 * Removes all of the comments (dir.com file) in order to free memory. The file will need to be reloaded if {@link #getComments(int)} is called subsequently. 137 */ 138 public void nullifyComments() { 139 commentsMap = null; 140 installedCom.set(false); 141 } 142 143 /** 144 * Create a new SCOP installation, downloading the file to "the right place". 145 * This will first check for system properties or environmental variables 146 * called {@link UserConfiguration#PDB_CACHE_DIR}, or else will use a temporary directory 147 */ 148 public ScopInstallation() { 149 this((new UserConfiguration()).getCacheFilePath()); 150 } 151 152 public void ensureClaInstalled() throws IOException { 153 if (installedCla.get()) return; 154 if (!claFileAvailable()) downloadClaFile(); 155 parseClassification(); 156 installedCla.set(true); 157 } 158 159 public void ensureDesInstalled() throws IOException { 160 if (installedDes.get()) return; 161 if (!desFileAvailable()) downloadDesFile(); 162 parseDescriptions(); 163 installedDes.set(true); 164 } 165 166 public void ensureComInstalled() throws IOException { 167 if (installedCom.get()) return; 168 if (!comFileAvailable()) downloadComFile(); 169 parseComments(); 170 installedCom.set(true); 171 } 172 173 public void ensureHieInstalled() throws IOException { 174 if ( installedHie.get()) return; 175 if ( ! hieFileAvailable()) downloadHieFile(); 176 parseHierarchy(); 177 installedHie.set(true); 178 } 179 180 /* (non-Javadoc) 181 * @see org.biojava.nbio.structure.scop.ScopDatabase#getByCategory(org.biojava.nbio.structure.scop.ScopCategory) 182 */ 183 @Override 184 public List<ScopDescription> getByCategory(ScopCategory category){ 185 186 try { 187 ensureDesInstalled(); 188 } catch (IOException e) { 189 throw new ScopIOException(e); 190 } 191 192 List<ScopDescription> matches = new ArrayList<>(); 193 for (Integer i : sunidMap.keySet()){ 194 ScopDescription sc = sunidMap.get(i); 195 if ( sc.getCategory().equals(category)) 196 197 try { 198 matches.add((ScopDescription)sc.clone()); 199 } catch (CloneNotSupportedException e) { 200 throw new RuntimeException("Could not clone " + ScopDescription.class + " subclass", e); 201 } 202 203 } 204 return matches; 205 } 206 207 /* (non-Javadoc) 208 * @see org.biojava.nbio.structure.scop.ScopDatabase#filterByClassificationId(java.lang.String) 209 */ 210 @Override 211 public List<ScopDescription> filterByClassificationId(String query){ 212 213 try { 214 ensureDesInstalled(); 215 } catch (IOException e) { 216 throw new ScopIOException(e); 217 } 218 219 List<ScopDescription> matches = new ArrayList<>(); 220 for (Integer i : sunidMap.keySet()){ 221 ScopDescription sc = sunidMap.get(i); 222 223 224 if( sc.getClassificationId().startsWith(query)){ 225 matches.add(sc); 226 } 227 } 228 229 return matches; 230 } 231 232 233 /* (non-Javadoc) 234 * @see org.biojava.nbio.structure.scop.ScopDatabase#getTree(org.biojava.nbio.structure.scop.ScopDomain) 235 */ 236 @Override 237 public List<ScopNode> getTree(ScopDomain domain){ 238 ScopNode node = getScopNode(domain.getSunid()); 239 240 241 List<ScopNode> tree = new ArrayList<>(); 242 while (node != null){ 243 244 //System.out.println("This node: sunid:" + node.getSunid() ); 245 //System.out.println(getScopDescriptionBySunid(node.getSunid())); 246 node = getScopNode(node.getParentSunid()); 247 if ( node != null) 248 tree.add(node); 249 } 250 Collections.reverse(tree); 251 return tree; 252 } 253 254 /* (non-Javadoc) 255 * @see org.biojava.nbio.structure.scop.ScopDatabase#filterByDomainName(java.lang.String) 256 */ 257 @Override 258 public List<ScopDomain> filterByDomainName(String query) { 259 260 List<ScopDomain > domains = new ArrayList<>(); 261 if (query.length() <5){ 262 return domains; 263 } 264 265 String pdbId = query.substring(1,5); 266 267 List<ScopDomain> doms = getDomainsForPDB(pdbId); 268 269 270 if ( doms == null) 271 return domains; 272 273 query = query.toLowerCase(); 274 for ( ScopDomain d: doms){ 275 if ( d.getScopId().toLowerCase().contains(query)){ 276 domains.add(d); 277 } 278 } 279 280 return domains; 281 } 282 283 /* (non-Javadoc) 284 * @see org.biojava.nbio.structure.scop.ScopDatabase#filterByDescription(java.lang.String) 285 */ 286 @Override 287 public List<ScopDescription> filterByDescription(String query) { 288 try { 289 ensureDesInstalled(); 290 } catch (IOException e) { 291 throw new ScopIOException(e); 292 } 293 294 query = query.toLowerCase(); 295 List<ScopDescription> matches = new ArrayList<>(); 296 for (Integer i : sunidMap.keySet()){ 297 ScopDescription sc = sunidMap.get(i); 298 299 if( sc.getDescription().toLowerCase().startsWith(query)){ 300 matches.add(sc); 301 } 302 } 303 304 return matches; 305 } 306 307 308 /* (non-Javadoc) 309 * @see org.biojava.nbio.structure.scop.ScopDatabase#getScopDescriptionBySunid(int) 310 */ 311 @Override 312 public ScopDescription getScopDescriptionBySunid(int sunid) { 313 try { 314 ensureDesInstalled(); 315 } catch (IOException e) { 316 throw new ScopIOException(e); 317 } 318 return sunidMap.get(sunid); 319 } 320 321 /* (non-Javadoc) 322 * @see org.biojava.nbio.structure.scop.ScopDatabase#getDomainsForPDB(java.lang.String) 323 */ 324 @Override 325 public List<ScopDomain> getDomainsForPDB(String pdbId) { 326 327 try { 328 ensureClaInstalled(); 329 } catch (IOException e) { 330 throw new ScopIOException(e); 331 } 332 333 List<ScopDomain> doms = domainMap.get(pdbId.toLowerCase()); 334 335 List<ScopDomain> retdoms = new ArrayList<>(); 336 337 if ( doms == null) 338 return retdoms; 339 340 for ( ScopDomain d : doms){ 341 try { 342 ScopDomain n = (ScopDomain) d.clone(); 343 retdoms.add(n); 344 } catch (CloneNotSupportedException e){ 345 throw new RuntimeException(ScopDomain.class + " subclass does not support clone()", e); 346 } 347 348 349 } 350 return retdoms; 351 } 352 353 /* (non-Javadoc) 354 * @see org.biojava.nbio.structure.scop.ScopDatabase#getDomainByScopID(java.lang.String) 355 */ 356 @Override 357 public ScopDomain getDomainByScopID(String scopId) { 358 359 try { 360 ensureClaInstalled(); 361 } catch (IOException e) { 362 throw new ScopIOException(e); 363 } 364 365 if ( scopId.length() < 6) { 366 throw new ScopIOException("Does not look like a scop ID! " + scopId); 367 } 368 String pdbId = scopId.substring(1,5); //TODO handle this when you handle extended PdbId (PDB ID) 369 List<ScopDomain> doms = getDomainsForPDB(pdbId); 370 if ( doms == null) 371 return null; 372 for ( ScopDomain d : doms){ 373 if ( d.getScopId().equalsIgnoreCase(scopId)) 374 return d; 375 } 376 377 return null; 378 } 379 380 /* (non-Javadoc) 381 * @see org.biojava.nbio.structure.scop.ScopDatabase#getScopNode(int) 382 */ 383 @Override 384 public ScopNode getScopNode(int sunid){ 385 386 try { 387 ensureHieInstalled(); 388 } catch (IOException e) { 389 throw new ScopIOException(e); 390 } 391 392 return scopTree.get(sunid); 393 } 394 395 396 private void parseClassification() throws IOException { 397 398 File file = new File(getClaFilename()); 399 400 InputStreamProvider ips = new InputStreamProvider(); 401 BufferedReader buffer = new BufferedReader (new InputStreamReader(ips.getInputStream(file))); 402 403 parseClassification(buffer); 404 405 } 406 407 private void parseHierarchy() throws IOException { 408 409 File file = new File(getHieFilename()); 410 411 412 InputStreamProvider ips = new InputStreamProvider(); 413 BufferedReader buffer = new BufferedReader (new InputStreamReader(ips.getInputStream(file))); 414 415 parseHierarchy(buffer); 416 417 } 418 419 private void parseHierarchy(BufferedReader buffer) throws IOException { 420 String line; 421 422 int counter =0; 423 while ((line = buffer.readLine ()) != null) { 424 if ( line.startsWith("#")) 425 continue; 426 427 String[] spl = line.split("\t"); 428 429 if ( spl.length != 3 ) { 430 throw new IOException("parseHierarchy: Can't parse line " + line +" (length: " + spl.length+")"); 431 } 432 counter++; 433 int sunid = Integer.parseInt(spl[0]); 434 int parentSunid = -1; 435 436 if ( sunid != 0) 437 parentSunid = Integer.parseInt(spl[1]); 438 439 String children = spl[2]; 440 String[] childIds = children.split(","); 441 442 List<Integer> chis = new ArrayList<>(); 443 444 for ( String id : childIds){ 445 if ( "-".equals(id)) 446 continue; 447 chis.add(Integer.parseInt(id)); 448 } 449 450 ScopNode node = new ScopNode(); 451 452 node.setSunid(sunid); 453 node.setParentSunid(parentSunid); 454 node.setChildren(chis); 455 456 scopTree.put(sunid, node); 457 } 458 logger.info("Parsed {} SCOP sunid nodes.", counter); 459 } 460 461 462 private void parseDescriptions() throws IOException{ 463 464 File file = new File(getDesFilename()); 465 466 InputStreamProvider ips = new InputStreamProvider(); 467 BufferedReader buffer = new BufferedReader (new InputStreamReader(ips.getInputStream(file))); 468 469 parseDescriptions(buffer); 470 471 } 472 473 private void parseComments() throws IOException{ 474 475 File file = new File(getComFilename()); 476 477 InputStreamProvider ips = new InputStreamProvider(); 478 BufferedReader buffer = new BufferedReader (new InputStreamReader(ips.getInputStream(file))); 479 480 parseComments(buffer); 481 482 } 483 484 private void parseComments(BufferedReader buffer) throws IOException { 485 486 commentsMap = new HashMap<>(); 487 488 int counter = 0; 489 String line; 490 while ((line = buffer.readLine ()) != null) { 491 if (line.startsWith("#")) continue; 492 String[] parts = line.split("!"); 493 int sunId = Integer.parseInt(parts[0].trim()); 494 if (parts.length == 1) { 495 commentsMap.put(sunId, new ArrayList<String>(1)); 496 continue; 497 } 498 List<String> comments = new ArrayList<>(parts.length - 1); 499 for (int i = 1; i < parts.length; i++) { 500 String trimmed = parts[i].trim(); 501 if( !trimmed.isEmpty() ) { 502 comments.add(trimmed); 503 } 504 } 505 commentsMap.put(sunId, comments); 506 counter++; 507 } 508 logger.info("Parsed {} SCOP comments.", counter); 509 510 } 511 512 private void parseDescriptions(BufferedReader buffer) throws IOException { 513 String line = null; 514 515 int counter = 0; 516 while ((line = buffer.readLine ()) != null) { 517 if ( line.startsWith("#")) 518 continue; 519 520 String[] spl = line.split("\t"); 521 522 if ( spl.length != 5 ) { 523 throw new IOException("parseDescriptions: Can't parse line " + line +" (length: " + spl.length+")"); 524 } 525 counter++; 526 527 //46464 dm a.1.1.2 - Hemoglobin I 528 int sunID = Integer.parseInt(spl[0]); 529 ScopCategory category = ScopCategory.fromString(spl[1]); 530 String classificationId = spl[2]; 531 String name = spl[3]; 532 String desc = spl[4]; 533 534 ScopDescription c = new ScopDescription(); 535 c.setSunID(sunID); 536 c.setCategory(category); 537 c.setClassificationId(classificationId); 538 c.setName(name); 539 c.setDescription(desc); 540 541 sunidMap.put(sunID, c); 542 543 } 544 logger.info("Parsed {} SCOP sunid descriptions.", counter); 545 } 546 547 548 549 private void parseClassification(BufferedReader buffer) throws IOException { 550 String line = null; 551 552 int counter = 0; 553 while ((line = buffer.readLine ()) != null) { 554 if ( line.startsWith("#")) 555 continue; 556 557 String[] spl = line.split("\t"); 558 559 if ( spl.length != 6){ 560 throw new IOException("Can't parse line " + line); 561 } 562 counter++; 563 564 String scopId = spl[0]; 565 String pdbId = spl[1]; 566 String range = spl[2]; 567 String classificationId = spl[3]; 568 Integer sunid = Integer.parseInt(spl[4]); 569 String tree = spl[5]; 570 571 572 573 ScopDomain d = new ScopDomain(); 574 d.setScopId(scopId); 575 PdbId tempPdbId = null; 576 try { 577 tempPdbId = new PdbId(pdbId); 578 } catch (NullPointerException | IllegalArgumentException e) { 579 logger.warn("could not parse line >>{}<<. Error Message: {}", line, e.getMessage()); 580 } 581 d.setPdbId(tempPdbId); 582 583 d.setRanges(extractRanges(range)); 584 585 d.setClassificationId(classificationId); 586 d.setSunid(sunid); 587 588 String[] treeSplit = tree.split(","); 589 590 if ( treeSplit.length != 7 ) { 591 throw new IOException("Can't process: " + line ); 592 } 593 594 int classId =Integer.parseInt(treeSplit[0].substring(3)); 595 int foldId = Integer.parseInt(treeSplit[1].substring(3)); 596 int superfamilyId = Integer.parseInt(treeSplit[2].substring(3)); 597 int familyId = Integer.parseInt(treeSplit[3].substring(3)); 598 int domainId = Integer.parseInt(treeSplit[4].substring(3)); 599 int speciesId = Integer.parseInt(treeSplit[5].substring(3)); 600 int px = Integer.parseInt(treeSplit[6].substring(3)); 601 602 d.setClassId(classId); 603 d.setFoldId(foldId); 604 d.setSuperfamilyId(superfamilyId); 605 d.setFamilyId(familyId); 606 d.setDomainId(domainId); 607 d.setSpeciesId(speciesId); 608 d.setPx(px); 609 610 List<ScopDomain> domainList; 611 if ( domainMap.containsKey(pdbId)){ 612 domainList = domainMap.get(pdbId); 613 } else { 614 domainList = new ArrayList<>(); 615 domainMap.put(pdbId,domainList); 616 } 617 618 domainList.add(d); 619 } 620 logger.info("Parsed {} SCOP sunid domains.", counter); 621 622 } 623 624 /** 625 * Converts the SCOP range field into a list of subranges suitable for 626 * storage in a ScopDomain object. Each range should be of a format 627 * compatible with {@link StructureTools#getSubRanges(Structure,String)}. 628 * @param range 629 * @return 630 */ 631 private List<String> extractRanges(String range) { 632 List<String> ranges; 633 String[] rangeSpl = range.split(","); 634 635 // Recent versions of scop always specify a chain, so no processing is needed 636 if(scopVersion.compareTo("1.73") < 0 ) { 637 for(int i=0; i<rangeSpl.length;i++) { 638 String subRange = rangeSpl[i]; 639 640 // Allow single-chains, as well as the '-' special case 641 if(subRange.length()<2) { 642 continue; 643 } 644 645 // Allow explicit chain syntax 646 if(subRange.charAt(1) != ':') { 647 // Early versions sometimes skip the chain identifier for single-chain domains 648 // Indicate this with a chain "_" 649 rangeSpl[i] = "_:"+subRange; 650 } 651 } 652 } 653 ranges = Arrays.asList(rangeSpl); 654 return ranges; 655 } 656 657 protected void downloadClaFile() throws IOException{ 658 if(mirrors.size()<1) { 659 initScopURLs(); 660 } 661 IOException exception = null; 662 for(ScopMirror mirror:mirrors) { 663 try { 664 URL url = new URL(mirror.getClaURL(scopVersion)); 665 666 String localFileName = getClaFilename(); 667 File localFile = new File(localFileName); 668 669 downloadFileFromRemote(url, localFile); 670 return; 671 } catch(IOException e ) { 672 exception = e; 673 } 674 } 675 throw new IOException("Unable to download SCOP .cla file",exception); 676 } 677 678 protected void downloadDesFile() throws IOException{ 679 if(mirrors.size()<1) { 680 initScopURLs(); 681 } 682 IOException exception = null; 683 for(ScopMirror mirror:mirrors) { 684 try { 685 URL url = new URL(mirror.getDesURL( scopVersion)); 686 687 String localFileName = getDesFilename(); 688 File localFile = new File(localFileName); 689 690 downloadFileFromRemote(url, localFile); 691 return; 692 } catch(IOException e ) { 693 exception = e; 694 } 695 } 696 throw new IOException("Unable to download SCOP .des file",exception); 697 } 698 699 protected void downloadHieFile() throws IOException{ 700 if(mirrors.size()<1) { 701 initScopURLs(); 702 } 703 IOException exception = null; 704 for(ScopMirror mirror:mirrors) { 705 try { 706 URL url = new URL(mirror.getHieURL( scopVersion)); 707 708 String localFileName = getHieFilename(); 709 File localFile = new File(localFileName); 710 711 downloadFileFromRemote(url, localFile); 712 return; 713 } catch(IOException e ) { 714 exception = e; 715 } 716 } 717 throw new IOException("Unable to download SCOP .hie file",exception); 718 719 } 720 721 protected void downloadComFile() throws IOException{ 722 if(mirrors.size()<1) { 723 initScopURLs(); 724 } 725 IOException exception = null; 726 for(ScopMirror mirror:mirrors) { 727 try { 728 URL url = new URL(mirror.getComURL(scopVersion)); 729 730 String localFileName = getComFilename(); 731 File localFile = new File(localFileName); 732 733 downloadFileFromRemote(url, localFile); 734 return; 735 } catch (IOException e ) { 736 exception = e; 737 } 738 } 739 throw new IOException("Unable to download SCOP .com file",exception); 740 } 741 742 /** 743 * Downloads the SCOP installation file +/- its validation metadata files. 744 * @param remoteURL The remote file to download 745 * @param localFile the local file to download to 746 * @throws IOException in cases of file I/O, including failure to download a healthy (non-corrupted) file. 747 */ 748 protected void downloadFileFromRemote(URL remoteURL, File localFile) throws IOException{ 749 logger.info("Downloading " + remoteURL + " to: " + localFile); 750 FileDownloadUtils.createValidationFiles(remoteURL, localFile, null, FileDownloadUtils.Hash.UNKNOWN); 751 FileDownloadUtils.downloadFile(remoteURL, localFile); 752 if(! FileDownloadUtils.validateFile(localFile)) 753 throw new IOException("Downloaded file invalid: "+localFile); 754 } 755 756 private boolean claFileAvailable(){ 757 String fileName = getClaFilename(); 758 759 File f = new File(fileName); 760 761 return f.exists() && FileDownloadUtils.validateFile(f); 762 } 763 764 private boolean desFileAvailable(){ 765 String fileName = getDesFilename(); 766 767 File f = new File(fileName); 768 return f.exists() && FileDownloadUtils.validateFile(f); 769 } 770 771 private boolean hieFileAvailable(){ 772 String fileName = getHieFilename(); 773 774 File f = new File(fileName); 775 776 return f.exists() && FileDownloadUtils.validateFile(f); 777 } 778 779 private boolean comFileAvailable(){ 780 String fileName = getComFilename(); 781 782 File f = new File(fileName); 783 784 return f.exists() && FileDownloadUtils.validateFile(f); 785 } 786 787 protected String getClaFilename(){ 788 return cacheLocation + claFileName + scopVersion; 789 } 790 791 protected String getDesFilename(){ 792 return cacheLocation + desFileName + scopVersion; 793 794 } 795 796 protected String getHieFilename(){ 797 return cacheLocation + hieFileName + scopVersion; 798 799 } 800 801 protected String getComFilename(){ 802 return cacheLocation + comFileName + scopVersion; 803 } 804 805 public String getCacheLocation() { 806 return cacheLocation; 807 } 808 809 public void setCacheLocation(String cacheLocation) { 810 811 if (! cacheLocation.endsWith(FILESPLIT)) 812 cacheLocation += FILESPLIT; 813 this.cacheLocation = cacheLocation; 814 815 816 } 817 /* (non-Javadoc) 818 * @see org.biojava.nbio.structure.scop.ScopDatabase#getScopVersion() 819 */ 820 @Override 821 public String getScopVersion() { 822 return scopVersion; 823 } 824 @Override 825 public void setScopVersion(String scopVersion) { 826 if(scopVersion == null) 827 throw new NullPointerException("Null scop version"); 828 if(this.scopVersion.equals(scopVersion)) 829 return; 830 this.scopVersion = scopVersion; 831 // reset installation flags 832 installedCla.set(false); 833 installedDes.set(false); 834 installedHie.set(false); 835 installedCom.set(false); 836 837 } 838 839 public void addMirror(String scopDownloadURL) { 840 mirrors.add(new ScopMirror(scopDownloadURL)); 841 } 842 void addMirror(ScopMirror scopURLs) { 843 mirrors.add(scopURLs); 844 } 845 public List<ScopMirror> getMirrors() { 846 if(mirrors.isEmpty()) { 847 this.initScopURLs(); 848 } 849 return mirrors; 850 } 851 852 /* (non-Javadoc) 853 * @see org.biojava.nbio.structure.scop.ScopDatabase#getScopDomainsBySunid(java.lang.Integer) 854 */ 855 @Override 856 public List<ScopDomain> getScopDomainsBySunid(Integer sunid) 857 { 858 859 try { 860 ensureClaInstalled(); 861 } catch (IOException e) { 862 throw new ScopIOException(e); 863 } 864 865 List<ScopDomain> domains = new ArrayList<>(); 866 867 for (String pdbId: domainMap.keySet()){ 868 for (ScopDomain d : domainMap.get(pdbId)){ 869 try { 870 if ( d.getPx() == sunid) { 871 domains.add((ScopDomain)d.clone()); 872 } else if ( d.getSpeciesId() == sunid ){ 873 domains.add((ScopDomain)d.clone()); 874 }else if ( d.getDomainId() == sunid ){ 875 domains.add((ScopDomain)d.clone()); 876 }else if ( d.getFamilyId() == sunid ){ 877 domains.add((ScopDomain)d.clone()); 878 }else if ( d.getSuperfamilyId() == sunid ){ 879 domains.add((ScopDomain)d.clone()); 880 }else if ( d.getFoldId() == sunid ){ 881 domains.add((ScopDomain)d.clone()); 882 }else if ( d.getClassId() == sunid ){ 883 domains.add((ScopDomain)d.clone()); 884 } else { 885 throw new RuntimeException("Type " + d + " not recognized"); // only possible if SCOP changes 886 } 887 } catch (CloneNotSupportedException e){ 888 throw new RuntimeException(ScopDomain.class + " subclass does not support clone()", e); 889 } 890 } 891 } 892 return domains; 893 894 } 895 896 @Override 897 public List<String> getComments(int sunid) { 898 try { 899 ensureComInstalled(); 900 } catch (IOException e) { 901 throw new ScopIOException(e); 902 } 903 if (!commentsMap.containsKey(sunid)) return new ArrayList<>(1); 904 return commentsMap.get(sunid); 905 } 906 907 908 private void initScopURLs() { 909 if(!this.mirrors.isEmpty()) { 910 return; 911 } 912 913 // first, try default scop 914 ScopMirror primary = new ScopMirror(); 915 // If unreachable, try alternate Berkeley location 916 ScopMirror alt; 917 if (scopVersion.startsWith("2.")) { 918 alt = new ScopMirror( 919 SCOP_DOWNLOAD_ALTERNATE, 920 "dir.cla.scope.%s.txt","dir.des.scope.%s.txt", 921 "dir.hie.scope.%s.txt","dir.com.scope.%s.txt"); 922 } 923 else { 924 alt = new ScopMirror( 925 SCOP_DOWNLOAD_ALTERNATE, 926 "dir.cla.scop.%s.txt","dir.des.scop.%s.txt", 927 "dir.hie.scop.%s.txt","dir.com.scop.%s.txt"); 928 } 929 mirrors.add(primary); 930 mirrors.add(alt); 931 } 932}