1 /* 2 * Copyright (C) 2008 Genome Research Limited 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 * 18 * @author: Tim Carver 19 */ 20 21 package uk.ac.sanger.artemis.circular; 22 23 24 import java.awt.BorderLayout; 25 import java.awt.Color; 26 import java.awt.Dimension; 27 import java.io.BufferedReader; 28 import java.io.File; 29 import java.io.FileInputStream; 30 import java.io.FileNotFoundException; 31 import java.io.FileReader; 32 import java.io.IOException; 33 import java.io.InputStreamReader; 34 import java.net.MalformedURLException; 35 import java.net.URL; 36 import java.util.Vector; 37 import java.util.Hashtable; 38 39 import javax.swing.Box; 40 import javax.swing.ButtonGroup; 41 import javax.swing.JLabel; 42 import javax.swing.JOptionPane; 43 import javax.swing.JPanel; 44 import javax.swing.JRadioButton; 45 import javax.swing.JScrollPane; 46 import javax.swing.JSeparator; 47 48 import uk.ac.sanger.artemis.Entry; 49 import uk.ac.sanger.artemis.EntryGroup; 50 import uk.ac.sanger.artemis.EntryVector; 51 import uk.ac.sanger.artemis.Feature; 52 import uk.ac.sanger.artemis.FeatureVector; 53 import uk.ac.sanger.artemis.Options; 54 import uk.ac.sanger.artemis.SimpleEntryGroup; 55 import uk.ac.sanger.artemis.components.EntryFileDialog; 56 import uk.ac.sanger.artemis.components.MessageDialog; 57 import uk.ac.sanger.artemis.components.StickyFileChooser; 58 import uk.ac.sanger.artemis.components.SwingWorker; 59 import uk.ac.sanger.artemis.io.EntryInformation; 60 import uk.ac.sanger.artemis.io.EntryInformationException; 61 import uk.ac.sanger.artemis.io.Key; 62 import uk.ac.sanger.artemis.io.Location; 63 import uk.ac.sanger.artemis.io.MSPcrunchDocumentEntry; 64 import uk.ac.sanger.artemis.io.Range; 65 import uk.ac.sanger.artemis.io.RangeVector; 66 import uk.ac.sanger.artemis.sequence.Bases; 67 import uk.ac.sanger.artemis.sequence.NoSequenceException; 68 import uk.ac.sanger.artemis.util.Document; 69 import uk.ac.sanger.artemis.util.DocumentFactory; 70 import uk.ac.sanger.artemis.util.OutOfRangeException; 71 import uk.ac.sanger.artemis.util.ReadOnlyException; 72 import uk.ac.sanger.artemis.util.WorkingGZIPInputStream; 73 74 75 /** 76 * DNA draw wizard 77 */ 78 public class Wizard 79 { 80 private DNADraw dna = null; 81 82 public static Track TRACK_1 = new Track(0.95d, "CDS", "pseudo", false, true, false, null); 83 public static Track TRACK_2 = new Track(0.9d, "CDS", "pseudo", false, false, true, null); 84 public static Track TRACK_3 = new Track(0.85d, "CDS", "pseudo", true, true, true, null); 85 public static Track TRACK_4 = new Track(0.8d, "misc_feature", true, true, null); 86 public static Track TRACK_5 = new Track(0.75d, null, true, true, null); 87 88 private SwingWorker workerGraph; 89 public static Track[] tracks = { TRACK_1, TRACK_2, TRACK_3, TRACK_4, TRACK_5 }; 90 Wizard(DNADraw dna_current)91 public Wizard(DNADraw dna_current) 92 { 93 int n = getOption(dna_current); // option 0 - read data file 94 // option 1 - edit existing dna 95 // option 2 - read template 96 if(n == 0) 97 dna = getDNADrawFromFile(dna_current); 98 else if(n == 2) 99 { 100 StickyFileChooser chooser = new StickyFileChooser(); 101 chooser.showOpenDialog(null); 102 103 File fileTemplate = chooser.getSelectedFile(); 104 if(!fileTemplate.exists()) 105 JOptionPane.showMessageDialog(null, 106 fileTemplate.getName()+" cannot be found!", 107 "Missing File", JOptionPane.WARNING_MESSAGE); 108 loadTemplate(chooser.getSelectedFile()); 109 } 110 else if(n == 1) 111 { 112 Vector block = new Vector(); 113 Vector restrictionEnzyme = new Vector(); 114 if(dna_current == null) 115 dna = new DNADraw(); 116 else 117 { 118 dna = dna_current; 119 block = dna_current.getGeneticMarker(); 120 restrictionEnzyme = dna_current.getRestrictionEnzyme(); 121 } 122 123 LineAttribute la = new LineAttribute(dna); 124 125 GeneticMarker gm; 126 if(dna_current != null) 127 gm = new GeneticMarker(dna_current,block); 128 else 129 gm = new GeneticMarker(dna,block); 130 131 RestrictionEnzyme re; 132 if(dna_current != null) 133 re = new RestrictionEnzyme(dna_current,restrictionEnzyme); 134 else 135 re = new RestrictionEnzyme(dna,restrictionEnzyme); 136 137 Ticks tk = new Ticks(dna_current,false); 138 139 la.setMinimumSize(la.getPreferredSize()); 140 la.setMaximumSize(la.getPreferredSize()); 141 142 re.setMinimumSize(re.getPreferredSize()); 143 re.setMaximumSize(re.getPreferredSize()); 144 145 ScrollPanel pane = new ScrollPanel(new BorderLayout()); 146 Box bdown = Box.createVerticalBox(); 147 bdown.add(new JLabel("Properties")); 148 Box bacross = Box.createHorizontalBox(); 149 bacross.add(la); 150 bacross.add(tk); 151 bacross.add(Box.createHorizontalGlue()); 152 bdown.add(bacross); 153 154 bdown.add(new JSeparator()); 155 bdown.add(Box.createVerticalStrut(10)); 156 bdown.add(new JLabel("Features")); 157 bacross = Box.createHorizontalBox(); 158 bacross.add(gm); 159 bacross.add(Box.createHorizontalGlue()); 160 bdown.add(bacross); 161 162 bdown.add(new JSeparator()); 163 bdown.add(Box.createVerticalStrut(10)); 164 bdown.add(new JLabel("Restriction Enzymes")); 165 bacross = Box.createHorizontalBox(); 166 bacross.add(re); 167 bacross.add(Box.createHorizontalGlue()); 168 bdown.add(bacross); 169 pane.add(bdown,BorderLayout.CENTER); 170 171 JScrollPane createWizScroll = new JScrollPane(pane); 172 173 Dimension dscreen = createWizScroll.getToolkit().getScreenSize(); 174 int wid = (int)dscreen.getWidth(); 175 if(wid > 700) 176 wid = 700; 177 178 int hgt = (int)dscreen.getHeight(); 179 if(hgt > 750) 180 hgt = 700; 181 hgt-=50; 182 183 Dimension d = new Dimension(wid,hgt); 184 createWizScroll.setPreferredSize(d); 185 186 JOptionPane.showMessageDialog(null, 187 createWizScroll, "DNA Wizard", 188 JOptionPane.PLAIN_MESSAGE); 189 190 dna.setGeneticMarker(block); 191 dna.setRestrictionEnzyme(restrictionEnzyme); 192 dna.setLineAttributes(la.getLineAttr()); 193 dna.setStartTick(tk.getStartTick()); 194 dna.setMinorTickInterval(tk.getMinorTickInterval()); 195 dna.setTickInterval(tk.getTickInterval()); 196 197 int s = la.getStart(); 198 dna.setStart(s); 199 200 s = la.getEnd(); 201 dna.setEnd(s); 202 } 203 } 204 205 /** 206 * Open a DNA plot based on a template file 207 * @param template 208 */ Wizard(final String templateName)209 public Wizard(final String templateName) 210 { 211 loadTemplate(templateName); 212 } 213 214 /** 215 * Load from a template file 216 * @param template 217 */ loadTemplate(final String templateName)218 private void loadTemplate(final String templateName) 219 { 220 final ProgressFrame progress = new ProgressFrame(); 221 progress.setString("Reading from "+templateName+" "); 222 progress.setValue(2); 223 224 if(dna == null) 225 dna = new DNADraw(); 226 Options.getOptions(); 227 final BufferedReader inputStream = getReader(templateName); 228 loadTemplate(inputStream, templateName, progress); 229 } 230 231 /** 232 * Load from a template file 233 * @param template 234 */ loadTemplate(final File templateFile)235 private void loadTemplate(final File templateFile) 236 { 237 final ProgressFrame progress = new ProgressFrame(); 238 progress.setString("Reading from "+templateFile.getName()+" "); 239 progress.setValue(2); 240 241 if(dna == null) 242 dna = new DNADraw(); 243 Options.getOptions(); 244 FileReader reader; 245 try 246 { 247 reader = new FileReader(templateFile); 248 final BufferedReader inputStream = new BufferedReader(reader); 249 loadTemplate(inputStream, templateFile.getName(), progress); 250 } 251 catch(FileNotFoundException e) 252 { 253 e.printStackTrace(); 254 } 255 } 256 loadTemplate(final BufferedReader inputStream, final String templateName, final ProgressFrame progress)257 private void loadTemplate(final BufferedReader inputStream, 258 final String templateName, 259 final ProgressFrame progress) 260 { 261 try 262 { 263 final EntryGroup entryGroup = new SimpleEntryGroup(); 264 final Hashtable fileEntrys = new Hashtable(); 265 Vector v_tracks = new Vector(); 266 String inLine = null; 267 String lineAttrStr[] = null; 268 String tickMarksStr[] = null; 269 String gcGraphStr[] = null; 270 String gcSkewGraphStr[] = null; 271 String userGraphStr[] = null; 272 273 String lineAttrStart = "# line attributes:"; 274 String tickMarksStart = "# tick marks:"; 275 String gcGraphStart = "# GC Graph:"; 276 String gcSkewGraphStart = "# GC Skew Graph:"; 277 String userGraphStart = "# User Graph:"; 278 String mergeBlastFeatures = "# merge.blast"; 279 280 while((inLine = inputStream.readLine()) != null) 281 { 282 if(inLine.startsWith("#") || inLine.trim().equals("")) 283 { 284 if(inLine.startsWith(lineAttrStart)) 285 lineAttrStr = inLine.substring(lineAttrStart.length()).trim().split("[=\\s]"); 286 else if(inLine.startsWith(tickMarksStart)) 287 tickMarksStr = inLine.substring(tickMarksStart.length()).trim().split("[=\\s]"); 288 else if(inLine.startsWith(gcGraphStart)) 289 gcGraphStr = inLine.substring(gcGraphStart.length()).trim().split("[=\\s]"); 290 else if(inLine.startsWith(gcSkewGraphStart)) 291 gcSkewGraphStr = inLine.substring(gcSkewGraphStart.length()).trim().split("[=\\s]"); 292 else if(inLine.startsWith(userGraphStart)) 293 userGraphStr = inLine.substring(userGraphStart.length()).trim().split("[=\\s]"); 294 else if(inLine.startsWith(mergeBlastFeatures)) 295 System.setProperty("merge.blast", "true"); 296 continue; 297 } 298 299 String properties[] = inLine.split("\t"); 300 301 final String separator; 302 if (properties[11].indexOf ("://") != -1) 303 separator = "/"; 304 else 305 separator = File.separator; 306 String fileName = properties[11] + separator + properties[10]; 307 Entry entry; 308 if(!fileEntrys.containsKey(fileName)) 309 { 310 progress.setString("Reading "+properties[10]); 311 progress.setValue(4); 312 entry = getEntry(fileName, entryGroup); 313 if(entry == null) 314 continue; 315 fileEntrys.put(fileName, entry); 316 } 317 else 318 { 319 entry = (Entry)fileEntrys.get(fileName); 320 } 321 322 Track track = new Track(.9,entry); 323 track.setPropertiesFromTemplate(inLine); 324 v_tracks.add(track); 325 } 326 inputStream.close(); 327 328 progress.setString("Read template "+templateName); 329 progress.setValue(7); 330 Track[] newTracks = new Track[v_tracks.size()]; 331 for(int i=0; i<v_tracks.size(); i++) 332 newTracks[i] = (Track) v_tracks.get(i); 333 334 Wizard.tracks = newTracks; 335 336 dna.setArtemisEntryGroup(entryGroup); 337 338 int sequenceLength = entryGroup.getSequenceEntry().getBases().getLength(); 339 340 Hashtable lineAttr = new Hashtable(); 341 lineAttr.put("lsize", new Integer(1)); 342 lineAttr.put("circular", new Boolean(true)); 343 lineAttr.put("start", new Integer(0)); 344 lineAttr.put("end", new Integer(sequenceLength)); 345 if(lineAttrStr != null) 346 { 347 for(int i=0; i<lineAttrStr.length; i++) 348 { 349 if(lineAttrStr[i].startsWith("line_size")) 350 lineAttr.put("lsize", new Integer(lineAttrStr[i+1])); 351 else if(lineAttrStr[i].startsWith("circular")) 352 lineAttr.put("circular", new Boolean(lineAttrStr[i+1])); 353 else if(lineAttrStr[i].startsWith("line_height")) 354 dna.setLineHeight(Float.parseFloat(lineAttrStr[i+1])); 355 else if(lineAttrStr[i].startsWith("bases_per_line")) 356 dna.setBasesPerLine(Integer.parseInt(lineAttrStr[i+1])); 357 } 358 } 359 dna.setLineAttributes(lineAttr); 360 361 final int div; 362 if(sequenceLength < 1000) 363 div = 100; 364 else if(sequenceLength < 10000) 365 div = 1000; 366 else if(sequenceLength < 100000) 367 div = 10000; 368 else 369 div = 100000; 370 int tick = sequenceLength / div; 371 tick = tick * (div / 10); 372 int tick2 = tick / 2; 373 tick = tick2 * 2; 374 375 if(tickMarksStr != null) 376 { 377 for(int i=0; i<tickMarksStr.length; i++) 378 { 379 if(tickMarksStr[i].startsWith("major")) 380 tick = Integer.parseInt(tickMarksStr[i+1]); 381 else if(tickMarksStr[i].startsWith("minor")) 382 tick2 = Integer.parseInt(tickMarksStr[i+1]); 383 } 384 } 385 386 dna.setGeneticMarker(new Vector()); 387 dna.setRestrictionEnzyme(new Vector()); 388 dna.setMinorTickInterval(tick2); 389 dna.setTickInterval(tick); 390 391 TrackManager trackManager = dna.getTrackManager(); 392 if(trackManager == null) 393 { 394 trackManager = new TrackManager(dna); 395 dna.setTrackManager(trackManager); 396 } 397 trackManager.update(tracks); 398 399 final String[] this_gcGraphStr = gcGraphStr; 400 final String[] this_gcSkewGraphStr = gcSkewGraphStr; 401 final String[] this_userGraphStr = userGraphStr; 402 workerGraph = new SwingWorker() 403 { 404 public Object construct() 405 { 406 loadGraphs(this_gcGraphStr, this_gcSkewGraphStr, this_userGraphStr, dna, progress); 407 return null; 408 } 409 }; 410 } 411 catch(FileNotFoundException e) 412 { 413 e.printStackTrace(); 414 } 415 catch(IOException e) 416 { 417 e.printStackTrace(); 418 } 419 catch(NoSequenceException e) 420 { 421 e.printStackTrace(); 422 } 423 } 424 425 /** 426 * Load graphs using template file details 427 * @param gcGraphStr 428 * @param gcSkewGraphStr 429 * @param userGraphStr 430 * @param dna 431 */ loadGraphs(final String gcGraphStr[], final String gcSkewGraphStr[], final String userGraphStr[], final DNADraw dna, final ProgressFrame progress)432 private void loadGraphs(final String gcGraphStr[], 433 final String gcSkewGraphStr[], 434 final String userGraphStr[], 435 final DNADraw dna, 436 final ProgressFrame progress) 437 { 438 439 if(gcGraphStr != null) 440 { 441 if(progress != null) 442 { 443 progress.setString("Calculating GC graph points"); 444 } 445 GCGraph gcGraph = new GCGraph(dna); 446 gcGraph.setOptionsStr(gcGraphStr); 447 dna.setGcGraph(gcGraph); 448 gcGraph.calcGraphValues(); 449 dna.add(gcGraph); 450 dna.repaint(); 451 dna.revalidate(); 452 } 453 if(gcSkewGraphStr != null) 454 { 455 if(progress != null) 456 { 457 progress.setString("Calculating GC Skew graph points"); 458 progress.setValue(8); 459 } 460 GCSkewGraph gcSkewGraph = new GCSkewGraph(dna); 461 gcSkewGraph.setOptionsStr(gcSkewGraphStr); 462 dna.setGcSkewGraph(gcSkewGraph); 463 gcSkewGraph.calcGraphValues(); 464 dna.add(gcSkewGraph); 465 dna.repaint(); 466 dna.revalidate(); 467 } 468 if(userGraphStr != null) 469 { 470 String fileName = null; 471 for(int i=0;i<userGraphStr.length; i++) 472 { 473 if(userGraphStr[i].startsWith("file_name")) 474 fileName = userGraphStr[i+1]; 475 } 476 //final uk.ac.sanger.artemis.util.Document document = 477 // new uk.ac.sanger.artemis.util.FileDocument(new File(fileName)); 478 try 479 { 480 if(progress != null) 481 { 482 progress.setString("Calculating user graph points"); 483 progress.setValue(9); 484 } 485 UserGraph userGraph = new UserGraph(dna, fileName); 486 userGraph.setOptionsStr(userGraphStr); 487 dna.setUserGraph(userGraph); 488 userGraph.calcGraphValues(); 489 dna.add(userGraph); 490 dna.repaint(); 491 dna.revalidate(); 492 } 493 catch(IOException e) 494 { 495 e.printStackTrace(); 496 return; 497 } 498 } 499 progress.dispose(); 500 } 501 502 /** 503 * Return an Artemis entry from a file 504 * @param entryFileName 505 * @param entryGroup 506 * @return 507 * @throws NoSequenceException 508 */ getEntry(final String entryFileName, final EntryGroup entryGroup)509 private Entry getEntry(final String entryFileName, final EntryGroup entryGroup) 510 throws NoSequenceException 511 { 512 final Document entry_document = DocumentFactory.makeDocument(entryFileName); 513 final EntryInformation artemis_entry_information = 514 Options.getArtemisEntryInformation(); 515 516 uk.ac.sanger.artemis.io.Entry new_embl_entry = 517 EntryFileDialog.getEntryFromFile(null, entry_document, 518 artemis_entry_information, 519 false); 520 521 if(new_embl_entry == null) // the read failed 522 return null; 523 524 new_embl_entry = mergeOption(new_embl_entry); 525 526 Entry entry = null; 527 try 528 { 529 Bases bases = null; 530 if(entryGroup.getSequenceEntry() != null) 531 bases = entryGroup.getSequenceEntry().getBases(); 532 if(bases == null) 533 entry = new Entry(new_embl_entry); 534 else 535 entry = new Entry(bases,new_embl_entry); 536 537 entryGroup.add(entry); 538 } 539 catch(OutOfRangeException e) 540 { 541 new MessageDialog(null, "read failed: one of the features in " + 542 entryFileName + " has an out of range " + 543 "location: " + e.getMessage()); 544 } 545 return entry; 546 } 547 548 mergeOption(uk.ac.sanger.artemis.io.Entry embl_entry)549 private static uk.ac.sanger.artemis.io.Entry mergeOption(uk.ac.sanger.artemis.io.Entry embl_entry) 550 { 551 if(embl_entry instanceof uk.ac.sanger.artemis.io.MSPcrunchDocumentEntry && 552 System.getProperty("merge.blast") == null) 553 { 554 int status = JOptionPane.showConfirmDialog(null, 555 "This looks like a BLAST file. Do you want to merge\n"+ 556 "overlapping BLAST hits to improve performance?", "Read BLAST", 557 JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); 558 if(status == JOptionPane.OK_OPTION) 559 System.setProperty("merge.blast", ""); 560 else 561 System.setProperty("merge.blast", "false"); 562 } 563 564 if( embl_entry instanceof uk.ac.sanger.artemis.io.MSPcrunchDocumentEntry && 565 System.getProperty("merge.blast") != null && 566 !System.getProperty("merge.blast").equals("false") ) 567 embl_entry = mergeOverlappingFeatures(embl_entry); 568 return embl_entry; 569 } 570 571 /** 572 * Merge overlapping BLAST hit features to improve the performance of 573 * DNAPlotter. 574 * @param embl_entry 575 * @return 576 */ mergeOverlappingFeatures(uk.ac.sanger.artemis.io.Entry embl_entry)577 private static uk.ac.sanger.artemis.io.Entry mergeOverlappingFeatures(uk.ac.sanger.artemis.io.Entry embl_entry) 578 { 579 final String name = embl_entry.getName(); 580 final RangeVector ranges = new RangeVector(); 581 uk.ac.sanger.artemis.io.FeatureVector features = embl_entry.getAllFeatures(); 582 System.out.print("Number of features: before merge = "+features.size()); 583 584 for(int i=0; i<features.size(); i++) 585 { 586 Range ri = ((uk.ac.sanger.artemis.io.Feature) features.elementAt(i)). 587 getLocation().getTotalRange(); 588 boolean overlaps = false; 589 Range rjOld = null; 590 Range rj = null; 591 int j; 592 for(j=0; j<ranges.size(); j++) 593 { 594 rjOld = (Range) ranges.get(j); 595 if(ri.overlaps(rjOld)) 596 { 597 int start = rjOld.getStart(); 598 int end = rjOld.getEnd(); 599 if(start > ri.getStart()) 600 start = ri.getStart(); 601 if(end < ri.getEnd()) 602 end = ri.getEnd(); 603 604 try 605 { 606 rj = new Range(start, end); 607 overlaps = true; 608 break; 609 } 610 catch (OutOfRangeException e){} 611 } 612 } 613 if(!overlaps) 614 ranges.add(ri); 615 else 616 { 617 ranges.remove(rjOld); 618 ranges.add(rj); 619 } 620 } 621 622 embl_entry.dispose(); 623 embl_entry = new MSPcrunchDocumentEntry( 624 Options.getOptions().getArtemisEntryInformation()) 625 { 626 public boolean isReadOnly () { 627 return false; 628 } 629 }; 630 embl_entry.setName(name); 631 632 final Key key = new Key("CRUNCH_D"); 633 for(int i=0; i<ranges.size(); i++) 634 { 635 Range r = (Range)ranges.get(i); 636 try 637 { 638 Feature f = new uk.ac.sanger.artemis.Feature( 639 new uk.ac.sanger.artemis.io.EmblStreamFeature(key, new Location(r), null)); 640 embl_entry.add(f.getEmblFeature()); 641 } 642 catch (ReadOnlyException e){} 643 catch (EntryInformationException e){} 644 catch (OutOfRangeException e) 645 { 646 e.printStackTrace(); 647 } 648 } 649 650 System.out.println(" after merge = "+ranges.size()); 651 return embl_entry; 652 } 653 654 /** 655 * Create a DNADraw panel from a file 656 * @param dna_current 657 * @return 658 */ getDNADrawFromFile(DNADraw dna_current)659 protected static DNADraw getDNADrawFromFile(DNADraw dna_current) 660 { 661 Options.getOptions(); 662 uk.ac.sanger.artemis.components.FileDialogEntrySource entrySource = 663 new uk.ac.sanger.artemis.components.FileDialogEntrySource(null, null); 664 665 final EntryGroup entryGroup = new SimpleEntryGroup(); 666 Entry entry; 667 try 668 { 669 entry = entrySource.getEntry(true); 670 entryGroup.add(entry); 671 return getDNADrawFromArtemisEntry(dna_current, entryGroup, entry); 672 } 673 catch(OutOfRangeException e) 674 { 675 e.printStackTrace(); 676 } 677 catch(NoSequenceException e) 678 { 679 JOptionPane.showMessageDialog(null, "No sequence found!", 680 "Sequence Missing", JOptionPane.WARNING_MESSAGE); 681 } 682 return null; 683 } 684 685 /** 686 * Create a DNADraw panel from an entry 687 * @param dna_current 688 * @param entryGroup 689 * @param entry 690 * @return 691 */ getDNADrawFromArtemisEntry(DNADraw dna_current, final EntryGroup entryGroup, final Entry entry)692 public static DNADraw getDNADrawFromArtemisEntry(DNADraw dna_current, 693 final EntryGroup entryGroup, 694 final Entry entry) 695 { 696 for(int i=0; i<tracks.length; i++) 697 tracks[i].setEntry(entry); 698 699 FeatureVector features = entry.getAllFeatures(); 700 Vector block = new Vector(); 701 702 if(dna_current == null) 703 dna_current = new DNADraw(); 704 705 dna_current.setArtemisEntryGroup(entryGroup); 706 707 Hashtable lineAttr = new Hashtable(); 708 lineAttr.put("lsize", new Integer(1)); 709 lineAttr.put("circular", new Boolean(true)); 710 lineAttr.put("start", new Integer(0)); 711 lineAttr.put("end", new Integer(entry.getBases().getLength())); 712 713 dna_current.setLineAttributes(lineAttr); 714 715 for(int i = 0; i < features.size(); i++) 716 { 717 Feature f = features.elementAt(i); 718 719 RangeVector ranges = f.getLocation().getRanges(); 720 721 for(int j = 0; j < ranges.size(); j++) 722 { 723 Range range = (Range) ranges.get(j); 724 725 Color col = f.getColour(); 726 if(col == null || col.equals(Color.white)) 727 col = Color.lightGray; 728 729 Track track; 730 731 if(TRACK_1.isOnTrack(f)) 732 track = TRACK_1; 733 else if(TRACK_2.isOnTrack(f)) 734 track = TRACK_2; 735 else if(TRACK_3.isOnTrack(f)) 736 track = TRACK_3; 737 else if(TRACK_4.isOnTrack(f)) 738 track = TRACK_4; 739 else 740 track = TRACK_5; 741 742 Block drawBlock = new Block(f.getIDString(), range.getStart(), range 743 .getEnd(), col, 10.f, track, dna_current); 744 745 drawBlock.setFeature(f); 746 block.add(drawBlock); 747 } 748 } 749 750 int div; 751 if(entry.getBases().getLength() < 1000) 752 div = 100; 753 else if(entry.getBases().getLength() < 10000) 754 div = 1000; 755 else if(entry.getBases().getLength() < 100000) 756 div = 10000; 757 else 758 div = 100000; 759 int tick = entry.getBases().getLength() / div; 760 tick = tick * (div / 10); 761 int tick2 = tick / 2; 762 tick = tick2 * 2; 763 764 dna_current.setGeneticMarker(block); 765 dna_current.setRestrictionEnzyme(new Vector()); 766 dna_current.setMinorTickInterval(tick2); 767 dna_current.setTickInterval(tick); 768 769 EntryVector entries = entryGroup.getActiveEntries(); 770 for(int i=0; i<entries.size(); i++) 771 { 772 Entry this_entry = entries.elementAt(i); 773 if(!this_entry.getName().equals(entry.getName())) 774 addFeaturesFromEntry(this_entry, dna_current); 775 } 776 return dna_current; 777 } 778 779 /** 780 * Read a new entry from a file 781 * @param dna_current 782 * @param bases 783 * @return 784 */ readEntry(final DNADraw dna_current, final Bases bases)785 public static DNADraw readEntry(final DNADraw dna_current, 786 final Bases bases) 787 { 788 Options.getOptions(); 789 uk.ac.sanger.artemis.components.FileDialogEntrySource entrySource = 790 new uk.ac.sanger.artemis.components.FileDialogEntrySource(null, null); 791 792 try 793 { 794 Entry entry = entrySource.getEntry(bases,true); 795 796 if(entry.getEMBLEntry() instanceof uk.ac.sanger.artemis.io.MSPcrunchDocumentEntry) 797 { 798 uk.ac.sanger.artemis.io.Entry new_embl_entry = 799 mergeOption(entry.getEMBLEntry()); 800 entry = new Entry(bases, new_embl_entry); 801 } 802 803 dna_current.getArtemisEntryGroup().add(entry); 804 805 addFeaturesFromEntry(entry, dna_current); 806 } 807 catch(OutOfRangeException e) 808 { 809 JOptionPane.showMessageDialog(null, 810 "Feature found out of range:\n"+ 811 e.getMessage(),"Out of Range", 812 JOptionPane.WARNING_MESSAGE); 813 } 814 815 return dna_current; 816 } 817 818 /** 819 * Add features from an entry to a new track 820 * @param entry 821 * @param dna_current 822 */ addFeaturesFromEntry(final Entry entry, final DNADraw dna_current)823 private static void addFeaturesFromEntry(final Entry entry, 824 final DNADraw dna_current) 825 { 826 FeatureVector features = entry.getAllFeatures(); 827 828 Track track = addTrack(entry); 829 track.setAny(true); 830 for(int i=0; i<features.size(); i++) 831 { 832 Feature f = features.elementAt(i); 833 RangeVector ranges = f.getLocation().getRanges(); 834 835 for(int j=0; j<ranges.size(); j++) 836 { 837 Range range = (Range) ranges.get(j); 838 839 Color col = f.getColour(); 840 if(col == null || col.equals(Color.white)) 841 col = Color.lightGray; 842 843 Block drawBlock = new Block(f.getIDString(), 844 range.getStart(), 845 range.getEnd(), 846 col, 847 10.f, 848 track, dna_current); 849 850 drawBlock.setFeature(f); 851 dna_current.getGeneticMarker().add(drawBlock); 852 } 853 } 854 } 855 856 857 getDNADraw()858 public DNADraw getDNADraw() 859 { 860 return dna; 861 } 862 863 getOption(DNADraw dna_current)864 private int getOption(DNADraw dna_current) 865 { 866 Box bdown = Box.createVerticalBox(); 867 868 JRadioButton[] radioButtons; 869 870 radioButtons = new JRadioButton[2]; 871 872 final ButtonGroup group = new ButtonGroup(); 873 radioButtons[0] = new JRadioButton("Read in sequence file"); 874 group.add(radioButtons[0]); 875 876 radioButtons[0].setSelected(true); 877 bdown.add(radioButtons[0]); 878 879 880 radioButtons[0].setSelected(true); 881 if(dna_current != null) 882 { 883 radioButtons[1] = new JRadioButton("Edit current dna display"); 884 group.add(radioButtons[1]); 885 radioButtons[1].setSelected(true); 886 } 887 else 888 { 889 radioButtons[1] = new JRadioButton("Read template file"); 890 group.add(radioButtons[1]); 891 } 892 bdown.add(radioButtons[1]); 893 894 JPanel pane = new JPanel(new BorderLayout()); 895 pane.add(bdown); 896 JOptionPane.showMessageDialog(null, 897 pane, "DNA Viewer Wizard", 898 JOptionPane.QUESTION_MESSAGE); 899 900 if(radioButtons[0].isSelected()) 901 return 0; 902 else if(radioButtons[1].isSelected() && dna_current != null) 903 return 1; 904 else if(radioButtons[1].isSelected()) 905 return 2; 906 907 return 1; 908 } 909 getTracks()910 protected static Track[] getTracks() 911 { 912 return tracks; 913 } 914 915 addTrack(Entry entry)916 protected static Track addTrack(Entry entry) 917 { 918 Track[] tracks = getTracks(); 919 Track[] newTracks = new Track[tracks.length+1]; 920 for(int i=0; i<tracks.length; i++) 921 newTracks[i] = tracks[i]; 922 923 final double position; 924 if(tracks.length > 1) 925 position = tracks[tracks.length-1].getPosition()-0.05; 926 else 927 position = 0.95; 928 Track newTrack = new Track(position, entry); 929 newTracks[tracks.length] = newTrack; 930 Wizard.tracks = newTracks; 931 return newTrack; 932 } 933 deleteTrack(int trackIndex)934 protected static void deleteTrack(int trackIndex) 935 { 936 Track[] tracks = getTracks(); 937 Track[] newTracks = new Track[tracks.length-1]; 938 int count = 0; 939 for(int i=0; i<tracks.length; i++) 940 { 941 if(i == trackIndex) 942 continue; 943 944 newTracks[count] = tracks[i]; 945 count++; 946 } 947 948 Wizard.tracks = newTracks; 949 } 950 951 /** 952 * Return reader for a file or a URL 953 * @param templateName 954 * @return 955 */ getReader(final String templateName)956 protected static BufferedReader getReader(final String templateName) 957 { 958 final File fileTemplate = new File(templateName); 959 BufferedReader inputStream = null; 960 if(!fileTemplate.exists()) 961 { 962 if (templateName.indexOf ("://") != -1) 963 { 964 URL template; 965 try 966 { 967 template = new URL(templateName); 968 inputStream = new BufferedReader( 969 new InputStreamReader(template.openStream())); 970 } 971 catch(MalformedURLException e) 972 { 973 e.printStackTrace(); 974 } 975 catch(IOException e) 976 { 977 e.printStackTrace(); 978 } 979 } 980 } 981 else 982 { 983 try 984 { 985 if(templateName.endsWith(".gz")) 986 inputStream = new BufferedReader( 987 new InputStreamReader(new WorkingGZIPInputStream( 988 new FileInputStream(fileTemplate) ))); 989 else 990 inputStream = new BufferedReader(new FileReader(fileTemplate)); 991 } 992 catch(FileNotFoundException e) 993 { 994 e.printStackTrace(); 995 } 996 catch (IOException e) 997 { 998 e.printStackTrace(); 999 } 1000 } 1001 return inputStream; 1002 } 1003 getWorkerGraph()1004 public SwingWorker getWorkerGraph() 1005 { 1006 return workerGraph; 1007 } 1008 } 1009 1010