newick-ruby 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. data/README +2 -0
  2. data/bin/newickDist +22 -5
  3. data/lib/Newick.rb +332 -326
  4. metadata +4 -4
data/README CHANGED
@@ -14,6 +14,8 @@ Jonathan Badger
14
14
  J. Craig Venter Institute
15
15
  jhbadger@gmail.com
16
16
 
17
+ UPDATES:
18
+ 1.0.2 -- faster distance matrix calculation
17
19
 
18
20
  License
19
21
  (The MIT License)
data/bin/newickDist CHANGED
@@ -1,16 +1,33 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'Newick'
4
+ require 'optparse'
5
+ require 'ostruct'
6
+
7
+ opt = OpenStruct.new
8
+ opt.verbose = false
9
+
10
+ ARGV.options {|opts|
11
+ opts.banner << " tree-file"
12
+ opts.on("-v", "--verbose", "show progress") {|t| opt.verbose = t}
13
+ begin
14
+ opts.parse!
15
+ rescue
16
+ STDERR.puts $!.message
17
+ STDERR.puts opts
18
+ exit(1)
19
+ end
20
+ if (ARGV.size < 1)
21
+ STDERR.puts opts
22
+ exit(1)
23
+ end
24
+ }
4
25
 
5
- if (ARGV.size != 1)
6
- STDERR.printf("usage: %s tree-file\n", $0)
7
- exit(1)
8
- end
9
26
 
10
27
  file = ARGV.pop
11
28
 
12
29
  tree = NewickTree.fromFile(file)
13
- dMatrix = tree.distanceMatrix
30
+ dMatrix = tree.distanceMatrix(opt.verbose)
14
31
 
15
32
  printf(" %d\n", dMatrix.keys.size)
16
33
  dMatrix.keys.each {|key1|
data/lib/Newick.rb CHANGED
@@ -8,7 +8,7 @@ class NewickToken
8
8
  attr_reader :type
9
9
  # string value of token
10
10
  attr_reader :value
11
-
11
+
12
12
  def initialize(type, value)
13
13
  @type = type
14
14
  @value = value
@@ -19,7 +19,7 @@ end
19
19
 
20
20
  # Splits a Newick tree string into tokens that NewickTree uses
21
21
  class NewickTokenizer
22
-
22
+
23
23
  def initialize(str)
24
24
  @str = str
25
25
  @pos = 0
@@ -45,17 +45,17 @@ class NewickTokenizer
45
45
  return NewickToken.new("SYMBOL", c)
46
46
  elsif (c == ":")
47
47
  if (@str.index((/([0-9|\.|\-|e|E]+)/), @pos) == @pos)
48
- @pos += $1.length
49
- return NewickToken.new("WEIGHT", $1)
48
+ @pos += $1.length
49
+ return NewickToken.new("WEIGHT", $1)
50
50
  else
51
- raise NewickParseError, "Illegal weight at pos #{@pos} of #{@str}"
51
+ raise NewickParseError, "Illegal weight at pos #{@pos} of #{@str}"
52
52
  end
53
53
  elsif (c == "'")
54
54
  if (@str.index(/(\'[^\']*\')/, @pos - 1) == @pos - 1)
55
- @pos += $1.length - 1
56
- return NewickToken.new("LABEL", $1)
55
+ @pos += $1.length - 1
56
+ return NewickToken.new("LABEL", $1)
57
57
  else
58
- raise NewickParseError, "Illegal label at pos #{@pos} of #{@str}"
58
+ raise NewickParseError, "Illegal label at pos #{@pos} of #{@str}"
59
59
  end
60
60
  elsif (@str.index(/([^,():]+)/, @pos - 1) == @pos - 1)
61
61
  @pos += $1.length - 1
@@ -112,10 +112,10 @@ class NewickNode
112
112
  s = ""
113
113
  if (!leaf?)
114
114
  s += "("
115
- @children.each {|child|
116
- s += child.to_s(showLen, bootStrap)
117
- s += "," if (child != @children.last)
118
- }
115
+ @children.each do |child|
116
+ s += child.to_s(showLen, bootStrap)
117
+ s += "," if (child != @children.last)
118
+ end
119
119
  s += ")"
120
120
  end
121
121
  if (leaf? || bootStrap == "node")
@@ -133,32 +133,32 @@ class NewickNode
133
133
  taxa = []
134
134
  if (!leaf?)
135
135
  taxa.push(@name) if (bootstrap)
136
- @children.each {|child|
137
- child.taxa.each {|taxon|
138
- taxa.push(taxon)
139
- }
140
- }
136
+ @children.each do |child|
137
+ child.taxa.each do |taxon|
138
+ taxa.push(taxon)
139
+ end
140
+ end
141
141
  else
142
142
  taxa.push(name)
143
143
  end
144
144
  return taxa.sort
145
145
  end
146
-
146
+
147
147
  # returns array of leaves (taxa) are contained in the node
148
148
  def leaves
149
149
  nodes = []
150
- descendants.each {|node|
150
+ descendants.each do |node|
151
151
  nodes.push(node) if (node.leaf?)
152
- }
152
+ end
153
153
  return nodes
154
154
  end
155
155
 
156
156
  # returns array of non leaves (taxa) that are contained in the node
157
157
  def intNodes
158
158
  nodes = []
159
- descendants.each {|child|
159
+ descendants.each do |child|
160
160
  nodes.push(child) if (!child.leaf?)
161
- }
161
+ end
162
162
  return nodes
163
163
  end
164
164
 
@@ -168,10 +168,10 @@ class NewickNode
168
168
  if (@name =~/#{name}/)
169
169
  found = self
170
170
  else
171
- @children.each {|child|
172
- found = child.findNode(name)
173
- break if found
174
- }
171
+ @children.each do |child|
172
+ found = child.findNode(name)
173
+ break if found
174
+ end
175
175
  end
176
176
  return found
177
177
  end
@@ -188,7 +188,7 @@ class NewickNode
188
188
  oldParent.edgeLen = @edgeLen
189
189
  @edgeLen = 0
190
190
  end
191
-
191
+
192
192
  # True if given node is child (or grandchild, etc.) of self. False otherwise
193
193
  def include?(node)
194
194
  while(node.parent != nil)
@@ -210,12 +210,12 @@ class NewickNode
210
210
  # returns array of all descendant nodes
211
211
  def descendants
212
212
  descendants = []
213
- @children.each {|child|
213
+ @children.each do |child|
214
214
  descendants.push(child)
215
- child.descendants.each {|grandchild|
216
- descendants.push(grandchild)
217
- }
218
- }
215
+ child.descendants.each do |grandchild|
216
+ descendants.push(grandchild)
217
+ end
218
+ end
219
219
  return descendants
220
220
  end
221
221
 
@@ -225,24 +225,24 @@ class NewickNode
225
225
  if (parent.nil?)
226
226
  return siblings
227
227
  else
228
- @parent.children.each {|child|
228
+ @parent.children.each do |child|
229
229
  siblings.push(child) if (child!=self)
230
- }
230
+ end
231
231
  return siblings
232
232
  end
233
233
  end
234
234
 
235
- # reorders descendant nodes alphabetically and by size
235
+ # reorders descendant nodes alphabetically and by size
236
236
  def reorder
237
237
  return if (@children.empty?)
238
238
  @children.sort! {|x, y| x.name <=> y.name}
239
- @children.each {|child|
239
+ @children.each do |child|
240
240
  child.reorder
241
- }
241
+ end
242
242
  return self
243
243
  end
244
244
 
245
-
245
+
246
246
 
247
247
  # returns the last common ancestor node of self and given node
248
248
  def lca(node)
@@ -265,7 +265,7 @@ class NewickNode
265
265
  end
266
266
  return dist
267
267
  end
268
-
268
+
269
269
 
270
270
  # returns number of nodes to the ancestor node
271
271
  def nodesToAncestor(ancestor)
@@ -280,7 +280,7 @@ class NewickNode
280
280
  end
281
281
  end
282
282
 
283
-
283
+
284
284
  # returns number of nodes to other node
285
285
  def nodesToNode(node)
286
286
  lca = lca(node)
@@ -296,9 +296,9 @@ class NewickNode
296
296
  # calculates node Y positions
297
297
  def calcYPos
298
298
  ySum = 0
299
- @children.each {|child|
299
+ @children.each do |child|
300
300
  ySum += child.y
301
- }
301
+ end
302
302
  @y = ySum / @children.size
303
303
  end
304
304
 
@@ -311,36 +311,36 @@ class NewickNode
311
311
  @x = parent.x + @edgeLen
312
312
  end
313
313
  if (!leaf?)
314
- @children.each {|child|
314
+ @children.each do |child|
315
315
  child.calcXPos
316
- }
316
+ end
317
317
  end
318
318
  end
319
319
 
320
320
  # returns the maximum X value in node
321
321
  def xMax
322
322
  xMax = 0
323
- children.each {|child|
323
+ children.each do |child|
324
324
  xMax = child.edgeLen if (child.x > xMax)
325
- }
325
+ end
326
326
  return xMax
327
327
  end
328
328
 
329
329
  # returns the maximum Y value in node
330
330
  def yMax
331
331
  yMax = 0
332
- children.each {|child|
332
+ children.each do |child|
333
333
  yMax = child.y if (child.y > yMax)
334
- }
334
+ end
335
335
  return yMax
336
336
  end
337
337
 
338
338
  # returns the minimum Y value in node
339
339
  def yMin
340
340
  yMin = 1e6
341
- children.each {|child|
341
+ children.each do |child|
342
342
  yMin = child.y if (child.y < yMin)
343
- }
343
+ end
344
344
  return yMin
345
345
  end
346
346
 
@@ -357,9 +357,9 @@ class NewickTree
357
357
  def NewickTree.fromFile(fileName)
358
358
  treeString = ""
359
359
  inFile = File.new(fileName)
360
- inFile.each {|line|
360
+ inFile.each do |line|
361
361
  treeString += line.chomp
362
- }
362
+ end
363
363
  inFile.close
364
364
  treeString.gsub!(/\[[^\]]*\]/,"") # remove comments before parsing
365
365
  return NewickTree.new(treeString)
@@ -369,43 +369,43 @@ class NewickTree
369
369
  def buildTree(parent, tokenizer)
370
370
  while (!(token = tokenizer.nextToken).nil?)
371
371
  if (token.type == "LABEL")
372
- name = token.value
373
- edgeLen = 0
374
- if (tokenizer.peekToken.type == "WEIGHT")
375
- edgeLen = tokenizer.nextToken.value.to_f
376
- end
377
- node = NewickNode.new(name, edgeLen)
378
- return node
372
+ name = token.value
373
+ edgeLen = 0
374
+ if (tokenizer.peekToken.type == "WEIGHT")
375
+ edgeLen = tokenizer.nextToken.value.to_f
376
+ end
377
+ node = NewickNode.new(name, edgeLen)
378
+ return node
379
379
  elsif (token.value == "(")
380
- node = NewickNode.new("", 0)
381
- forever = true
382
- while (forever)
383
- child = buildTree(node, tokenizer)
384
- node.addChild(child)
385
- break if tokenizer.peekToken.value != ","
386
- tokenizer.nextToken
387
- end
388
- if (tokenizer.nextToken.value != ")")
389
- raise NewickParseError, "Expected ')' but found: #{token.value}"
390
- else
391
- peek = tokenizer.peekToken
392
- if (peek.value == ")" || peek.value == "," || peek.value == ";")
393
- return node
394
- elsif (peek.type == "WEIGHT")
395
- node.edgeLen = tokenizer.nextToken.value.to_f
396
- return node
397
- elsif (peek.type == "LABEL")
398
- token = tokenizer.nextToken
399
- node.name = token.value
400
- if (tokenizer.peekToken.type == "WEIGHT")
401
- node.edgeLen = tokenizer.nextToken.value.to_f
402
- end
403
- return node
404
- end
405
- end
380
+ node = NewickNode.new("", 0)
381
+ forever = true
382
+ while (forever)
383
+ child = buildTree(node, tokenizer)
384
+ node.addChild(child)
385
+ break if tokenizer.peekToken.value != ","
386
+ tokenizer.nextToken
387
+ end
388
+ if (tokenizer.nextToken.value != ")")
389
+ raise NewickParseError, "Expected ')' but found: #{token.value}"
390
+ else
391
+ peek = tokenizer.peekToken
392
+ if (peek.value == ")" || peek.value == "," || peek.value == ";")
393
+ return node
394
+ elsif (peek.type == "WEIGHT")
395
+ node.edgeLen = tokenizer.nextToken.value.to_f
396
+ return node
397
+ elsif (peek.type == "LABEL")
398
+ token = tokenizer.nextToken
399
+ node.name = token.value
400
+ if (tokenizer.peekToken.type == "WEIGHT")
401
+ node.edgeLen = tokenizer.nextToken.value.to_f
402
+ end
403
+ return node
404
+ end
405
+ end
406
406
  else
407
- raise NewickParseError,
408
- "Expected '(' or label but found: #{token.value}"
407
+ raise NewickParseError,
408
+ "Expected '(' or label but found: #{token.value}"
409
409
  end
410
410
  end
411
411
  end
@@ -437,33 +437,33 @@ class NewickTree
437
437
  else
438
438
  taxon = "SEQ0000001"
439
439
  end
440
- @root.descendants.each {|node|
440
+ @root.descendants.each do |node|
441
441
  if (node.name != "" && node.name.to_i == 0)
442
- ali[taxon] = node.name
443
- aliF.printf("%s\t%s\n", taxon, node.name) if (!aliasFile.nil?)
444
- node.name = taxon.dup
445
- taxon.succ!
442
+ ali[taxon] = node.name
443
+ aliF.printf("%s\t%s\n", taxon, node.name) if (!aliasFile.nil?)
444
+ node.name = taxon.dup
445
+ taxon.succ!
446
446
  end
447
- }
447
+ end
448
448
  aliF.close if (!aliasFile.nil?)
449
449
  return self, ali
450
450
  end
451
451
 
452
452
  # renames nodes according to alias hash
453
453
  def unAlias(aliasNames)
454
- @root.descendants.each {|node|
454
+ @root.descendants.each do |node|
455
455
  node.name = aliasNames[node.name] if (!aliasNames[node.name].nil?)
456
- }
456
+ end
457
457
  return self
458
458
  end
459
459
 
460
460
  # renames nodes according to inverse alias hash
461
461
  def reAlias(aliasNames)
462
- @root.descendants.each {|node|
463
- aliasNames.keys.each {|key|
462
+ @root.descendants.each do |node|
463
+ aliasNames.keys.each do |key|
464
464
  node.name = key if (aliasNames[key] == node.name)
465
- }
466
- }
465
+ end
466
+ end
467
467
  return self
468
468
  end
469
469
 
@@ -473,22 +473,28 @@ class NewickTree
473
473
  end
474
474
 
475
475
  # returns a 2D hash of pairwise distances on tree
476
- def distanceMatrix
476
+ def distanceMatrix(verbose = nil)
477
477
  dMatrix = Hash.new
478
- @root.taxa.each {|taxon1|
479
- dMatrix[taxon1] = Hash.new
480
- taxon1Node = @root.findNode(taxon1)
481
- @root.taxa.each {|taxon2|
482
- if (taxon1 == taxon2)
483
- dMatrix[taxon1][taxon2] = 0.0
484
- else
485
- taxon2Node = @root.findNode(taxon2)
486
- lca = taxon1Node.lca(taxon2Node)
487
- dMatrix[taxon1][taxon2] = taxon1Node.distToAncestor(lca) +
488
- taxon2Node.distToAncestor(lca)
489
- end
490
- }
491
- }
478
+ leaves = root.leaves
479
+ num = (leaves.size)**2
480
+ numpercent = num/100
481
+ count = 0
482
+
483
+ leaves.each do |leaf1|
484
+ dMatrix[leaf1.name] = Hash.new
485
+ leaves.each do |leaf2|
486
+ count += 1
487
+ if (verbose && count % numpercent == 0)
488
+ STDERR.printf("Processing %s %s (%d of %d)\n", leaf1.name, leaf2.name, count, num)
489
+ end
490
+ if (leaf1 == leaf2)
491
+ dMatrix[leaf1.name][leaf2.name] = 0.0
492
+ else
493
+ lca = leaf1.lca(leaf2)
494
+ dMatrix[leaf1.name][leaf2.name] = leaf1.distToAncestor(lca) + leaf2.distToAncestor(lca)
495
+ end
496
+ end
497
+ end
492
498
  return dMatrix
493
499
  end
494
500
 
@@ -496,22 +502,22 @@ class NewickTree
496
502
  def compare(tree)
497
503
  tree1 = self.dup.unroot
498
504
  tree2 = tree.dup.unroot
499
-
505
+
500
506
  diff1 = []
501
507
  diff2 = []
502
508
  if (tree1.taxa == tree2.taxa)
503
509
  clades1 = tree1.clades
504
510
  clades2 = tree2.clades
505
- clades1.each {|clade|
506
- if (!clades2.include?(clade))
507
- diff1.push(clade)
508
- end
509
- }
510
- clades2.each {|clade|
511
- if (!clades1.include?(clade))
512
- diff2.push(clade)
513
- end
514
- }
511
+ clades1.each do |clade|
512
+ if (!clades2.include?(clade))
513
+ diff1.push(clade)
514
+ end
515
+ end
516
+ clades2.each do |clade|
517
+ if (!clades1.include?(clade))
518
+ diff2.push(clade)
519
+ end
520
+ end
515
521
  else
516
522
  raise NewickParseError, "The trees have different taxa!"
517
523
  end
@@ -531,9 +537,9 @@ class NewickTree
531
537
  left, right = @root.children
532
538
  left, right = right, left if (right.leaf?) # don't uproot leaf side
533
539
  left.edgeLen += right.edgeLen
534
- right.children.each {|child|
540
+ right.children.each do |child|
535
541
  @root.addChild(child)
536
- }
542
+ end
537
543
  @root.removeChild(right)
538
544
  return self
539
545
  end
@@ -560,37 +566,37 @@ class NewickTree
560
566
  greatestDist = 0
561
567
  dist = Hash.new
562
568
  org1, org2 = nil, nil
563
- @root.leaves.each {|node1|
564
- @root.leaves.each {|node2|
569
+ @root.leaves.each do |node1|
570
+ @root.leaves.each do |node2|
565
571
  dist[node1] = Hash.new if dist[node1].nil?
566
572
  dist[node2] = Hash.new if dist[node2].nil?
567
573
  next if (!dist[node1][node2].nil?)
568
574
  lca = node1.lca(node2)
569
575
  dist[node1][node2] = node1.distToAncestor(lca) +
570
- node2.distToAncestor(lca)
576
+ node2.distToAncestor(lca)
571
577
  dist[node2][node1] = dist[node1][node2]
572
578
  if (dist[node1][node2] > greatestDist)
573
579
  org1 = node1
574
580
  org2 = node2
575
581
  greatestDist = dist[node1][node2]
576
- end
577
- }
578
- }
582
+ end
583
+ end
584
+ end
579
585
  return org1, org2, greatestDist
580
586
  end
581
587
 
582
588
  # add EC numbers from alignment
583
589
  def addECnums(alignFile)
584
590
  ec = Hash.new
585
- File.new(alignFile).each {|line|
591
+ File.new(alignFile).each do |line|
586
592
  if (line =~ /^>/)
587
- definition = line.chomp[1..line.length]
588
- name = definition.split(" ").first
589
- if (definition =~ /\[EC:([0-9|\.]*)/)
590
- ec[name] = name + "_" + $1
591
- end
593
+ definition = line.chomp[1..line.length]
594
+ name = definition.split(" ").first
595
+ if (definition =~ /\[EC:([0-9|\.]*)/)
596
+ ec[name] = name + "_" + $1
597
+ end
592
598
  end
593
- }
599
+ end
594
600
  unAlias(ec)
595
601
  end
596
602
 
@@ -626,23 +632,23 @@ class NewickTree
626
632
  # returns array of arrays representing the tree clades
627
633
  def clades(bootstrap = false)
628
634
  clades = []
629
- @root.descendants.each {|clade|
635
+ @root.descendants.each do |clade|
630
636
  clades.push(clade.taxa(bootstrap)) if (!clade.children.empty?)
631
- }
637
+ end
632
638
  return clades
633
639
  end
634
640
 
635
641
  # add bootstrap values (given in clade arrays) to a tree
636
642
  def addBootStrap(bootClades)
637
- @root.descendants.each {|clade|
643
+ @root.descendants.each do |clade|
638
644
  next if clade.leaf?
639
- bootClades.each {|bClade|
640
- boot, rest = bClade.first, bClade[1..bClade.size - 1]
641
- if (rest == clade.taxa ) # same clade found
642
- clade.name = boot
643
- end
644
- }
645
- }
645
+ bootClades.each do |bClade|
646
+ boot, rest = bClade.first, bClade[1..bClade.size - 1]
647
+ if (rest == clade.taxa ) # same clade found
648
+ clade.name = boot
649
+ end
650
+ end
651
+ end
646
652
  end
647
653
 
648
654
  # return array of arrays of taxa representing relatives at each level
@@ -653,23 +659,23 @@ class NewickTree
653
659
  else
654
660
  relatives = []
655
661
  while(!node.parent.nil?)
656
- relatives.push(node.parent.taxa - node.taxa)
657
- node = node.parent
662
+ relatives.push(node.parent.taxa - node.taxa)
663
+ node = node.parent
658
664
  end
659
665
  return relatives
660
666
  end
661
667
  end
662
668
 
663
-
669
+
664
670
  # Fixes PHYLIP's mistake of using branch lengths and not node values
665
671
  def fixPhylip
666
- @root.descendants.each {|child|
672
+ @root.descendants.each do |child|
667
673
  br = child.edgeLen.to_i
668
674
  child.edgeLen = 0
669
675
  if (br > 0 && !child.leaf?)
670
676
  child.name = br.to_s
671
677
  end
672
- }
678
+ end
673
679
  end
674
680
 
675
681
 
@@ -678,189 +684,189 @@ class NewickTree
678
684
  yPos = 0.25
679
685
  @root.reorder
680
686
  leaves = @root.leaves.sort {|x, y| x.nodesToNode(y) <=> y.nodesToNode(x)}
681
- leaves.each {|leaf|
687
+ leaves.each do |leaf|
682
688
  leaf.y = yPos
683
689
  yPos += yUnit
684
- }
685
- nodes = @root.intNodes.sort{|x, y| y.nodesToAncestor(@root) <=>
686
- x.nodesToAncestor(@root)}
687
- nodes.each {|node|
688
- node.calcYPos
689
- }
690
- @root.calcYPos
691
- @root.calcXPos
692
- nodes = @root.intNodes.sort{|x, y| x.nodesToAncestor(@root) <=>
693
- y.nodesToAncestor(@root)}
694
- nodes.each {|node|
695
- @root.calcXPos # (forwards from root)
696
- }
697
- end
698
-
699
- # function to generate gi link to ncbi for draw, below
700
- def giLink(entry)
701
- ncbiLink = "http://www.ncbi.nlm.nih.gov/entrez/"
702
- protLink = "viewer.fcgi?db=protein&val="
703
- if (entry =~ /^gi[\_]*([0-9]*)/ || entry =~ /(^[A-Z|0-9]*)\|/)
704
- return ncbiLink + protLink + $1
705
- else
706
- return nil
707
690
  end
708
- end
709
-
710
- # returns PDF representation of branching structure of tree
711
- def draw(pdfFile, boot="width", linker = :giLink, labelName = false,
712
- highlights = Hash.new, brackets = nil, rawNames = false)
713
- colors = {"goldenrod4"=>[139, 105, 20], "lightcyan"=>[224, 255, 255], "rosybrown1"=>[255, 193, 193], "sienna1"=>[255, 130, 71], "lavender"=>[230, 230, 250], "rosybrown2"=>[238, 180, 180], "wheat1"=>[255, 231, 186], "linen"=>[250, 240, 230], "beige"=>[245, 245, 220], "sienna2"=>[238, 121, 66], "paleturquoise1"=>[187, 255, 255], "pink1"=>[255, 181, 197], "wheat2"=>[238, 216, 174], "violetred"=>[208, 32, 144], "palegreen"=>[152, 251, 152], "gray50"=>[127, 127, 127], "rosybrown3"=>[205, 155, 155], "sienna3"=>[205, 104, 57], "paleturquoise2"=>[174, 238, 238], "green1"=>[0, 255, 0], "pink2"=>[238, 169, 184], "wheat3"=>[205, 186, 150], "lightskyblue1"=>[176, 226, 255], "gray51"=>[130, 130, 130], "rosybrown4"=>[139, 105, 105], "sienna4"=>[139, 71, 38], "paleturquoise3"=>[150, 205, 205], "green2"=>[0, 238, 0], "pink3"=>[205, 145, 158], "wheat4"=>[139, 126, 102], "lightskyblue2"=>[164, 211, 238], "yellow1"=>[255, 255, 0], "sgilightgray"=>[170, 170, 170], "paleturquoise4"=>[102, 139, 139], "green3"=>[0, 205, 0], "pink4"=>[139, 99, 108], "lightskyblue3"=>[141, 182, 205], "yellow2"=>[238, 238, 0], "gray52"=>[133, 133, 133], "mediumorchid"=>[186, 85, 211], "green4"=>[0, 139, 0], "lightskyblue4"=>[96, 123, 139], "ivory1"=>[255, 255, 240], "yellow3"=>[205, 205, 0], "plum1"=>[255, 187, 255], "lightblue1"=>[191, 239, 255], "seashell1"=>[255, 245, 238], "gray53"=>[135, 135, 135], "ivory2"=>[238, 238, 224], "violetred1"=>[255, 62, 150], "plum2"=>[238, 174, 238], "lightblue2"=>[178, 223, 238], "seashell2"=>[238, 229, 222], "gray54"=>[138, 138, 138], "white"=>[255, 255, 255], "mediumslateblue"=>[123, 104, 238], "ivory3"=>[205, 205, 193], "yellow4"=>[139, 139, 0], "lightcyan1"=>[224, 255, 255], "plum3"=>[205, 150, 205], "lightslateblue"=>[132, 112, 255], "lightblue3"=>[154, 192, 205], "seashell3"=>[205, 197, 191], "gray55"=>[140, 140, 140], "ivory4"=>[139, 139, 131], "lightcyan2"=>[209, 238, 238], "violetred2"=>[238, 58, 140], "peru"=>[205, 133, 63], "lightblue4"=>[104, 131, 139], "seashell4"=>[139, 134, 130], "gray56"=>[143, 143, 143], "flesh"=>[255, 125, 64], "lightcyan3"=>[180, 205, 205], "violetred3"=>[205, 50, 120], "plum4"=>[139, 102, 139], "lightblue"=>[173, 216, 230], "gray57"=>[145, 145, 145], "coral"=>[255, 127, 80], "cadmiumorange"=>[255, 97, 3], "khaki1"=>[255, 246, 143], "lightcyan4"=>[122, 139, 139], "violetred4"=>[139, 34, 82], "lightslategray"=>[119, 136, 153], "gray58"=>[148, 148, 148], "sgigray32"=>[81, 81, 81], "khaki2"=>[238, 230, 133], "dodgerblue1"=>[30, 144, 255], "lavenderblush1"=>[255, 240, 245], "gray59"=>[150, 150, 150], "khaki3"=>[205, 198, 115], "dodgerblue2"=>[28, 134, 238], "lavenderblush2"=>[238, 224, 229], "banana"=>[227, 207, 87], "khaki4"=>[139, 134, 78], "dodgerblue3"=>[24, 116, 205], "lavenderblush3"=>[205, 193, 197], "cyan2"=>[0, 238, 238], "cadetblue"=>[95, 158, 160], "cadmiumyellow"=>[255, 153, 18], "mediumpurple"=>[147, 112, 219], "dodgerblue4"=>[16, 78, 139], "lavenderblush4"=>[139, 131, 134], "cyan3"=>[0, 205, 205], "silver"=>[192, 192, 192], "sgigray36"=>[91, 91, 91], "cyan4"=>[0, 139, 139], "deeppink1"=>[255, 20, 147], "burntumber"=>[138, 51, 36], "deeppink2"=>[238, 18, 137], "aliceblue"=>[240, 248, 255], "rosybrown"=>[188, 143, 143], "aquamarine"=>[127, 255, 212], "plum"=>[221, 160, 221], "deeppink3"=>[205, 16, 118], "darkgoldenrod"=>[184, 134, 11], "darkslategray1"=>[151, 255, 255], "chartreuse1"=>[127, 255, 0], "deeppink4"=>[139, 10, 80], "antiquewhite"=>[250, 235, 215], "darkslategray2"=>[141, 238, 238], "chartreuse2"=>[118, 238, 0], "darkslategray3"=>[121, 205, 205], "raspberry"=>[135, 38, 87], "chartreuse3"=>[102, 205, 0], "darkslategray4"=>[82, 139, 139], "chartreuse4"=>[69, 139, 0], "lightsalmon"=>[255, 160, 122], "warmgrey"=>[128, 128, 105], "cobalt"=>[61, 89, 171], "pink"=>[255, 192, 203], "orangered"=>[255, 69, 0], "indianred"=>[205, 92, 92], "palegreen1"=>[154, 255, 154], "red1"=>[255, 0, 0], "darkorange1"=>[255, 127, 0], "palegreen2"=>[144, 238, 144], "darkorchid"=>[153, 50, 204], "red2"=>[238, 0, 0], "darkorange2"=>[238, 118, 0], "palegreen3"=>[124, 205, 124], "goldenrod"=>[218, 165, 32], "red3"=>[205, 0, 0], "tomato1"=>[255, 99, 71], "yellowgreen"=>[154, 205, 50], "darkorange3"=>[205, 102, 0], "palegreen4"=>[84, 139, 84], "gray30"=>[77, 77, 77], "red4"=>[139, 0, 0], "tomato2"=>[238, 92, 66], "darkorange4"=>[139, 69, 0], "antiquewhite1"=>[255, 239, 219], "gray31"=>[79, 79, 79], "brown"=>[165, 42, 42], "tomato3"=>[205, 79, 57], "thistle1"=>[255, 225, 255], "antiquewhite2"=>[238, 223, 204], "darkolivegreen1"=>[202, 255, 112], "gray32"=>[82, 82, 82], "gray80"=>[204, 204, 204], "tomato4"=>[139, 54, 38], "sepia"=>[94, 38, 18], "thistle2"=>[238, 210, 238], "deepskyblue"=>[0, 191, 255], "antiquewhite3"=>[205, 192, 176], "darkolivegreen2"=>[188, 238, 104], "cornflowerblue"=>[100, 149, 237], "gray33"=>[84, 84, 84], "gray81"=>[207, 207, 207], "thistle3"=>[205, 181, 205], "peachpuff"=>[255, 218, 185], "steelblue1"=>[99, 184, 255], "antiquewhite4"=>[139, 131, 120], "darkolivegreen3"=>[162, 205, 90], "gray34"=>[87, 87, 87], "gray82"=>[209, 209, 209], "maroon"=>[128, 0, 0], "thistle4"=>[139, 123, 139], "springgreen1"=>[0, 238, 118], "steelblue2"=>[92, 172, 238], "darkolivegreen4"=>[110, 139, 61], "gray35"=>[89, 89, 89], "gray83"=>[212, 212, 212], "springgreen2"=>[0, 205, 102], "steelblue3"=>[79, 148, 205], "steelblue"=>[70, 130, 180], "gray36"=>[92, 92, 92], "gray84"=>[214, 214, 214], "springgreen3"=>[0, 139, 69], "steelblue4"=>[54, 100, 139], "gray37"=>[94, 94, 94], "blue2"=>[0, 0, 238], "darkturquoise"=>[0, 206, 209], "gray38"=>[97, 97, 97], "gray85"=>[217, 217, 217], "sgigray12"=>[30, 30, 30], "blanchedalmond"=>[255, 235, 205], "violet"=>[238, 130, 238], "blue3"=>[0, 0, 205], "gray39"=>[99, 99, 99], "gray86"=>[219, 219, 219], "burlywood1"=>[255, 211, 155], "navy"=>[0, 0, 128], "darkviolet"=>[148, 0, 211], "blue4"=>[0, 0, 139], "gray87"=>[222, 222, 222], "burlywood2"=>[238, 197, 145], "floralwhite"=>[255, 250, 240], "turquoise"=>[64, 224, 208], "darkorange"=>[255, 140, 0], "gray88"=>[224, 224, 224], "burlywood3"=>[205, 170, 125], "gray89"=>[227, 227, 227], "dimgray"=>[105, 105, 105], "sgigray16"=>[40, 40, 40], "snow"=>[255, 250, 250], "burlywood4"=>[139, 115, 85], "mediumvioletred"=>[199, 21, 133], "seagreen"=>[46, 139, 87], "purple1"=>[155, 48, 255], "lightsteelblue1"=>[202, 225, 255], "purple2"=>[145, 44, 238], "orangered1"=>[255, 69, 0], "lightsteelblue2"=>[188, 210, 238], "purple3"=>[125, 38, 205], "cyan/aqua"=>[0, 255, 255], "orangered2"=>[238, 64, 0], "lightsteelblue3"=>[162, 181, 205], "purple4"=>[85, 26, 139], "orangered3"=>[205, 55, 0], "fuchsia"=>[255, 0, 255], "lightsteelblue4"=>[110, 123, 139], "mistyrose1"=>[255, 228, 225], "orangered4"=>[139, 37, 0], "darkorchid1"=>[191, 62, 255], "lemonchiffon1"=>[255, 250, 205], "mistyrose2"=>[238, 213, 210], "darkorchid2"=>[178, 58, 238], "lemonchiffon2"=>[238, 233, 191], "mistyrose3"=>[205, 183, 181], "royalblue"=>[65, 105, 225], "darkorchid3"=>[154, 50, 205], "lemonchiffon3"=>[205, 201, 165], "sgiolivedrab"=>[142, 142, 56], "mistyrose4"=>[139, 125, 123], "darkorchid4"=>[104, 34, 139], "peachpuff1"=>[255, 218, 185], "mediumseagreen"=>[60, 179, 113], "lemonchiffon4"=>[139, 137, 112], "lightgreen"=>[144, 238, 144], "peachpuff2"=>[238, 203, 173], "peachpuff3"=>[205, 175, 149], "peachpuff4"=>[139, 119, 101], "lightsteelblue"=>[176, 196, 222], "skyblue"=>[135, 206, 235], "gray10"=>[26, 26, 26], "magenta"=>[255, 0, 255], "turquoise1"=>[0, 245, 255], "gray11"=>[28, 28, 28], "turquoise2"=>[0, 229, 238], "chartreuse"=>[127, 255, 0], "navajowhite"=>[255, 222, 173], "ghostwhite"=>[248, 248, 255], "gray12"=>[31, 31, 31], "gray60"=>[153, 153, 153], "melon"=>[227, 168, 105], "turquoise3"=>[0, 197, 205], "gray13"=>[33, 33, 33], "gray61"=>[156, 156, 156], "coral1"=>[255, 114, 86], "turquoise4"=>[0, 134, 139], "gray14"=>[36, 36, 36], "gray62"=>[158, 158, 158], "sgiteal"=>[56, 142, 142], "coral2"=>[238, 106, 80], "honeydew"=>[240, 255, 240], "gray1"=>[3, 3, 3], "gray15"=>[38, 38, 38], "firebrick"=>[178, 34, 34], "coral3"=>[205, 91, 69], "lightpink"=>[255, 182, 193], "gray2"=>[5, 5, 5], "gray16"=>[41, 41, 41], "gray63"=>[161, 161, 161], "coral4"=>[139, 62, 47], "mediumblue"=>[0, 0, 205], "gray3"=>[8, 8, 8], "gray17"=>[43, 43, 43], "gray64"=>[163, 163, 163], "blueviolet"=>[138, 43, 226], "darkgreen"=>[0, 100, 0], "gray4"=>[10, 10, 10], "gray18"=>[46, 46, 46], "gray65"=>[166, 166, 166], "deepskyblue1"=>[0, 191, 255], "gray5"=>[13, 13, 13], "gray19"=>[48, 48, 48], "gray66"=>[168, 168, 168], "mediumspringgreen"=>[0, 250, 154], "darkkhaki"=>[189, 183, 107], "lightgoldenrodyellow"=>[250, 250, 210], "orange"=>[255, 128, 0], "deepskyblue2"=>[0, 178, 238], "gray6"=>[15, 15, 15], "gray67"=>[171, 171, 171], "mediumturquoise"=>[72, 209, 204], "deepskyblue3"=>[0, 154, 205], "turquoiseblue"=>[0, 199, 140], "gray7"=>[18, 18, 18], "gray68"=>[173, 173, 173], "orchid"=>[218, 112, 214], "burlywood"=>[222, 184, 135], "thistle"=>[216, 191, 216], "mediumpurple1"=>[171, 130, 255], "deepskyblue4"=>[0, 104, 139], "gray8"=>[20, 20, 20], "gray69"=>[176, 176, 176], "palevioletred"=>[219, 112, 147], "sandybrown"=>[244, 164, 96], "mediumpurple2"=>[159, 121, 238], "yellow"=>[255, 255, 0], "darkgoldenrod1"=>[255, 185, 15], "gray9"=>[23, 23, 23], "darkseagreen"=>[143, 188, 143], "mediumpurple3"=>[137, 104, 205], "darkgoldenrod2"=>[238, 173, 14], "sgigray92"=>[234, 234, 234], "mediumpurple4"=>[93, 71, 139], "darkgoldenrod3"=>[205, 149, 12], "mediumaquamarine"=>[102, 205, 170], "firebrick1"=>[255, 48, 48], "tomato"=>[255, 99, 71], "darkgoldenrod4"=>[139, 101, 8], "gray"=>[128, 128, 128], "firebrick2"=>[238, 44, 44], "palegoldenrod"=>[238, 232, 170], "moccasin"=>[255, 228, 181], "firebrick3"=>[205, 38, 38], "snow1"=>[255, 250, 250], "sgigray96"=>[244, 244, 244], "firebrick4"=>[139, 26, 26], "snow2"=>[238, 233, 233], "papayawhip"=>[255, 239, 213], "snow3"=>[205, 201, 201], "eggshell"=>[252, 230, 201], "snow4"=>[139, 137, 137], "tan"=>[210, 180, 140], "peacock"=>[51, 161, 201], "gold1"=>[255, 215, 0], "slateblue1"=>[131, 111, 255], "springgreen"=>[0, 255, 127], "ivoryblack"=>[41, 36, 33], "gold2"=>[238, 201, 0], "honeydew1"=>[240, 255, 240], "greenyellow"=>[173, 255, 47], "slateblue2"=>[122, 103, 238], "gainsboro"=>[220, 220, 220], "azure"=>[240, 255, 255], "gold3"=>[205, 173, 0], "oldlace"=>[253, 245, 230], "honeydew2"=>[224, 238, 224], "gold4"=>[139, 117, 0], "honeydew3"=>[193, 205, 193], "slateblue3"=>[105, 89, 205], "green"=>[0, 128, 0], "skyblue1"=>[135, 206, 255], "honeydew4"=>[131, 139, 131], "cadetblue1"=>[152, 245, 255], "slateblue4"=>[71, 60, 139], "sienna"=>[160, 82, 45], "darksalmon"=>[233, 150, 122], "skyblue2"=>[126, 192, 238], "cadetblue2"=>[142, 229, 238], "sapgreen"=>[48, 128, 20], "gray40"=>[102, 102, 102], "skyblue3"=>[108, 166, 205], "midnightblue"=>[25, 25, 112], "blue"=>[0, 0, 255], "cadetblue3"=>[122, 197, 205], "sgichartreuse"=>[113, 198, 113], "skyblue4"=>[74, 112, 139], "cadetblue4"=>[83, 134, 139], "lime"=>[0, 255, 0], "gray90"=>[229, 229, 229], "gray42"=>[105, 105, 105], "mistyrose"=>[255, 228, 225], "burntsienna"=>[138, 54, 15], "ivory"=>[255, 255, 240], "gray43"=>[110, 110, 110], "gray91"=>[232, 232, 232], "darkcyan"=>[0, 139, 139], "gray44"=>[112, 112, 112], "gray92"=>[235, 235, 235], "lawngreen"=>[124, 252, 0], "gray45"=>[115, 115, 115], "gray93"=>[237, 237, 237], "palevioletred1"=>[255, 130, 171], "saddlebrown"=>[139, 69, 19], "lavenderblush"=>[255, 240, 245], "gray46"=>[117, 117, 117], "gray94"=>[240, 240, 240], "palevioletred2"=>[238, 121, 159], "khaki"=>[240, 230, 140], "paleturquoise"=>[174, 238, 238], "gray47"=>[120, 120, 120], "gray95"=>[242, 242, 242], "carrot"=>[237, 145, 33], "palevioletred3"=>[205, 104, 137], "lightsalmon1"=>[255, 160, 122], "olivedrab"=>[107, 142, 35], "gray48"=>[122, 122, 122], "palevioletred4"=>[139, 71, 93], "wheat"=>[245, 222, 179], "lightsalmon2"=>[238, 149, 114], "powderblue"=>[176, 224, 230], "gray49"=>[125, 125, 125], "gray96"=>[245, 245, 245], "red"=>[255, 0, 0], "brown1"=>[255, 64, 64], "lightsalmon3"=>[205, 129, 98], "manganeseblue"=>[3, 168, 158], "gray97"=>[247, 247, 247], "brown2"=>[238, 59, 59], "lightsalmon4"=>[139, 87, 66], "olive"=>[128, 128, 0], "gray98"=>[250, 250, 250], "lightgrey"=>[211, 211, 211], "sgigray72"=>[183, 183, 183], "brown3"=>[205, 51, 51], "gold"=>[255, 215, 0], "mintcream"=>[245, 255, 250], "gray99"=>[252, 252, 252], "brown4"=>[139, 35, 35], "sgidarkgray"=>[85, 85, 85], "magenta2"=>[238, 0, 238], "sgigray76"=>[193, 193, 193], "magenta3"=>[205, 0, 205], "dodgerblue"=>[30, 144, 255], "magenta4"=>[139, 0, 139], "cobaltgreen"=>[61, 145, 64], "sgisalmon"=>[198, 113, 113], "emeraldgreen"=>[0, 201, 87], "sgibrightgray"=>[197, 193, 170], "darkred"=>[139, 0, 0], "rawsienna"=>[199, 97, 20], "seagreen1"=>[84, 255, 159], "lightyellow"=>[255, 255, 224], "olivedrab1"=>[192, 255, 62], "orchid1"=>[255, 131, 250], "seashell"=>[255, 245, 238], "seagreen2"=>[78, 238, 148], "bisque1"=>[255, 228, 196], "olivedrab2"=>[179, 238, 58], "orchid2"=>[238, 122, 233], "azure1"=>[240, 255, 255], "seagreen3"=>[67, 205, 128], "bisque2"=>[238, 213, 183], "whitesmoke"=>[245, 245, 245], "olivedrab3"=>[154, 205, 50], "orchid3"=>[205, 105, 201], "azure2"=>[224, 238, 238], "lightpink1"=>[255, 174, 185], "lightgoldenrod1"=>[255, 236, 139], "bisque3"=>[205, 183, 158], "olivedrab4"=>[105, 139, 34], "orchid4"=>[139, 71, 137], "purple"=>[128, 0, 128], "lemonchiffon"=>[255, 250, 205], "azure3"=>[193, 205, 205], "lightpink2"=>[238, 162, 173], "seagreen4"=>[46, 139, 87], "forestgreen"=>[34, 139, 34], "lightgoldenrod2"=>[238, 220, 130], "bisque4"=>[139, 125, 107], "sgislateblue"=>[113, 113, 198], "azure4"=>[131, 139, 139], "lightpink3"=>[205, 140, 149], "lightgoldenrod3"=>[205, 190, 112], "gray20"=>[51, 51, 51], "sgibeet"=>[142, 56, 142], "limegreen"=>[50, 205, 50], "orange1"=>[255, 165, 0], "lightpink4"=>[139, 95, 101], "lightgoldenrod4"=>[139, 129, 76], "gray21"=>[54, 54, 54], "orange2"=>[238, 154, 0], "gray22"=>[56, 56, 56], "gray70"=>[179, 179, 179], "orange3"=>[205, 133, 0], "gray23"=>[59, 59, 59], "gray71"=>[181, 181, 181], "orange4"=>[139, 90, 0], "lightseagreen"=>[32, 178, 170], "bisque"=>[255, 228, 196], "gray24"=>[61, 61, 61], "gray72"=>[184, 184, 184], "darkslateblue"=>[72, 61, 139], "gray25"=>[64, 64, 64], "gray73"=>[186, 186, 186], "lightcoral"=>[240, 128, 128], "tan1"=>[255, 165, 79], "gray26"=>[66, 66, 66], "black"=>[0, 0, 0], "tan2"=>[238, 154, 73], "gray27"=>[69, 69, 69], "gray74"=>[189, 189, 189], "teal"=>[0, 128, 128], "tan3"=>[205, 133, 63], "aquamarine1"=>[127, 255, 212], "gray28"=>[71, 71, 71], "gray75"=>[191, 191, 191], "tan4"=>[139, 90, 43], "darkmagenta"=>[139, 0, 139], "aquamarine2"=>[118, 238, 198], "gray29"=>[74, 74, 74], "gray76"=>[194, 194, 194], "indianred1"=>[255, 106, 106], "chocolate"=>[210, 105, 30], "aquamarine3"=>[102, 205, 170], "gray77"=>[196, 196, 196], "indianred2"=>[238, 99, 99], "slategray1"=>[198, 226, 255], "chocolate1"=>[255, 127, 36], "aquamarine4"=>[69, 139, 116], "gray78"=>[199, 199, 199], "sgigray52"=>[132, 132, 132], "indianred3"=>[205, 85, 85], "salmon"=>[250, 128, 114], "darkblue"=>[0, 0, 139], "lightyellow1"=>[255, 255, 224], "slategray2"=>[185, 211, 238], "chocolate2"=>[238, 118, 33], "gray79"=>[201, 201, 201], "indianred4"=>[139, 58, 58], "hotpink"=>[255, 105, 180], "brick"=>[156, 102, 31], "lightyellow2"=>[238, 238, 209], "slategray3"=>[159, 182, 205], "chocolate3"=>[205, 102, 29], "darkgray"=>[169, 169, 169], "lightyellow3"=>[205, 205, 180], "darkolivegreen"=>[85, 107, 47], "slategray4"=>[108, 123, 139], "chocolate4"=>[139, 69, 19], "salmon1"=>[255, 140, 105], "deeppink"=>[255, 20, 147], "indigo"=>[75, 0, 130], "darkslategray"=>[47, 79, 79], "navajowhite1"=>[255, 222, 173], "lightyellow4"=>[139, 139, 122], "royalblue1"=>[72, 118, 255], "slateblue"=>[106, 90, 205], "maroon1"=>[255, 52, 179], "sgigray56"=>[142, 142, 142], "salmon2"=>[238, 130, 98], "navajowhite2"=>[238, 207, 161], "coldgrey"=>[128, 138, 135], "royalblue2"=>[67, 110, 238], "cornsilk1"=>[255, 248, 220], "maroon2"=>[238, 48, 167], "salmon3"=>[205, 112, 84], "navajowhite3"=>[205, 179, 139], "royalblue3"=>[58, 95, 205], "cornsilk2"=>[238, 232, 205], "maroon3"=>[205, 41, 144], "slategray"=>[112, 128, 144], "salmon4"=>[139, 76, 57], "navajowhite4"=>[139, 121, 94], "royalblue4"=>[39, 64, 139], "darkseagreen1"=>[193, 255, 193], "cornsilk3"=>[205, 200, 177], "maroon4"=>[139, 28, 98], "hotpink1"=>[255, 110, 180], "mediumorchid1"=>[224, 102, 255], "darkseagreen2"=>[180, 238, 180], "cornsilk4"=>[139, 136, 120], "mint"=>[189, 252, 201], "hotpink2"=>[238, 106, 167], "sgilightblue"=>[125, 158, 192], "goldenrod1"=>[255, 193, 37], "mediumorchid2"=>[209, 95, 238], "darkseagreen3"=>[155, 205, 155], "hotpink3"=>[205, 96, 144], "goldenrod2"=>[238, 180, 34], "mediumorchid3"=>[180, 82, 205], "darkseagreen4"=>[105, 139, 105], "hotpink4"=>[139, 58, 98], "crimson"=>[220, 20, 60], "lightskyblue"=>[135, 206, 250], "goldenrod3"=>[205, 155, 29], "mediumorchid4"=>[122, 55, 139], "cornsilk"=>[255, 248, 220]}
714
- pdf=FPDF.new('P', "cm")
715
- pdf.SetTitle(pdfFile)
716
- pdf.SetCreator("newickDraw")
717
- pdf.SetAuthor(ENV["USER"]) if (!ENV["USER"].nil?)
718
- pdf.AddPage
719
- yUnit = nil
720
- lineWidth = nil
721
- fontSize = nil
722
- bootScale = 0.6
723
- if (taxa.size < 30)
724
- fontSize = 10
725
- yUnit = 0.5
726
- lineWidth = 0.02
727
- elsif (taxa.size < 60)
728
- fontSize = 8
729
- yUnit = 0.25
730
- lineWidth = 0.01
731
- elsif (taxa.size < 150)
732
- fontSize = 8
733
- yUnit = 0.197
734
- lineWidth = 0.01
735
- elsif (taxa.size < 300)
736
- fontSize = 2
737
- yUnit = 0.09
738
- lineWidth = 0.005
739
- elsif (taxa.size < 400)
740
- fontSize = 2
741
- yUnit = 0.055
742
- lineWidth = 0.002
743
- elsif (taxa.size < 800)
744
- fontSize = 1
745
- yUnit = 0.030
746
- lineWidth = 0.0015
747
- else
748
- fontSize = 0.5
749
- yUnit = 0.020
750
- lineWidth = 0.0010
751
- end
752
- bootScale = 0.5 * fontSize
753
- pdf.SetFont('Times','B', fontSize)
754
- calcPos(yUnit) # calculate node pos before drawing
755
- max = 0
756
- @root.leaves.each {|leaf|
757
- d = leaf.distToAncestor(@root)
758
- max = d if (max < d)
759
- }
760
- xScale = 10.0/max
761
- xOffSet = 0.25
762
- pdf.SetLineWidth(lineWidth)
763
- pdf.SetTextColor(0, 0, 0)
764
- pdf.Line(0, @root.y, xOffSet, @root.y)
765
- pdf.Line(xOffSet, @root.yMin, xOffSet, @root.yMax)
766
- @root.descendants.each {|child|
767
- if (!child.leaf?)
768
- if (child.name.to_i > 75 && boot == "width") # good bootstrap
769
- pdf.SetLineWidth(lineWidth * 5)
770
- else
771
- pdf.SetLineWidth(lineWidth)
691
+ nodes = @root.intNodes.sort{|x, y| y.nodesToAncestor(@root) <=>
692
+ x.nodesToAncestor(@root)}
693
+ nodes.each do |node|
694
+ node.calcYPos
695
+ end
696
+ @root.calcYPos
697
+ @root.calcXPos
698
+ nodes = @root.intNodes.sort{|x, y| x.nodesToAncestor(@root) <=>
699
+ y.nodesToAncestor(@root)}
700
+ nodes.each do |node|
701
+ @root.calcXPos # (forwards from root)
772
702
  end
773
- bootX = xOffSet + child.x*xScale
774
- bootY = ((child.yMin + child.yMax) / 2.0)
775
- pdf.SetXY(bootX, bootY)
776
- pdf.SetFont('Times','B', bootScale)
777
- pdf.Write(0, child.name.to_s)
778
- pdf.SetFont('Times','B', fontSize)
779
- pdf.Line(xOffSet + child.x*xScale, child.yMin,
780
- xOffSet + child.x*xScale, child.yMax)
781
- else
782
- if (child.parent.name.to_i > 75 && boot == "width") # good bootstrap
783
- pdf.SetLineWidth(lineWidth * 5)
703
+ end
704
+
705
+ # function to generate gi link to ncbi for draw, below
706
+ def giLink(entry)
707
+ ncbiLink = "http://www.ncbi.nlm.nih.gov/entrez/"
708
+ protLink = "viewer.fcgi?db=protein&val="
709
+ if (entry =~ /^gi[\_]*([0-9]*)/ || entry =~ /(^[A-Z|0-9]*)\|/)
710
+ return ncbiLink + protLink + $1
784
711
  else
785
- pdf.SetLineWidth(lineWidth)
712
+ return nil
786
713
  end
787
- pdf.SetXY(xOffSet + child.x*xScale, child.y)
788
- efields = child.name.split("__")
789
- entry, species = efields.first, efields.last
790
- if (entry =~/\{([^\}]*)\}/)
791
- species = $1
792
- end
793
- species = entry if species.nil? && !rawNames
794
- species = child.name if rawNames
795
- hl = false
796
- highlights.keys.each{|highlight|
797
- hl = highlights[highlight] if (entry.index(highlight))
798
- }
799
- if (pdfFile.index(entry)) # name of query taxon
800
- pdf.SetTextColor(colors["red"][0], colors["red"][1], colors["red"][2])
801
- pdf.Write(0, entry)
802
- pdf.SetTextColor(colors["black"][0], colors["black"][1], colors["black"][2])
803
- elsif (linker && link = send(linker, entry))
804
- pdf.SetTextColor(colors["black"][0], colors["black"][1], colors["black"][2]) if hl
805
- pdf.Write(0, species, link)
806
- pdf.SetTextColor(colors["black"][0], colors["black"][1], colors["black"][2]) if hl
807
- elsif (!species.nil?)
808
- pdf.SetTextColor(colors[hl][0], colors[hl][1], colors[hl][2]) if hl
809
- pdf.Write(0, species)
810
- pdf.SetTextColor(colors["black"][0], colors["black"][1], colors["black"][2]) if hl
714
+ end
715
+
716
+ # returns PDF representation of branching structure of tree
717
+ def draw(pdfFile, boot="width", linker = :giLink, labelName = false,
718
+ highlights = Hash.new, brackets = nil, rawNames = false)
719
+ colors = {"goldenrod4"=>[139, 105, 20], "lightcyan"=>[224, 255, 255], "rosybrown1"=>[255, 193, 193], "sienna1"=>[255, 130, 71], "lavender"=>[230, 230, 250], "rosybrown2"=>[238, 180, 180], "wheat1"=>[255, 231, 186], "linen"=>[250, 240, 230], "beige"=>[245, 245, 220], "sienna2"=>[238, 121, 66], "paleturquoise1"=>[187, 255, 255], "pink1"=>[255, 181, 197], "wheat2"=>[238, 216, 174], "violetred"=>[208, 32, 144], "palegreen"=>[152, 251, 152], "gray50"=>[127, 127, 127], "rosybrown3"=>[205, 155, 155], "sienna3"=>[205, 104, 57], "paleturquoise2"=>[174, 238, 238], "green1"=>[0, 255, 0], "pink2"=>[238, 169, 184], "wheat3"=>[205, 186, 150], "lightskyblue1"=>[176, 226, 255], "gray51"=>[130, 130, 130], "rosybrown4"=>[139, 105, 105], "sienna4"=>[139, 71, 38], "paleturquoise3"=>[150, 205, 205], "green2"=>[0, 238, 0], "pink3"=>[205, 145, 158], "wheat4"=>[139, 126, 102], "lightskyblue2"=>[164, 211, 238], "yellow1"=>[255, 255, 0], "sgilightgray"=>[170, 170, 170], "paleturquoise4"=>[102, 139, 139], "green3"=>[0, 205, 0], "pink4"=>[139, 99, 108], "lightskyblue3"=>[141, 182, 205], "yellow2"=>[238, 238, 0], "gray52"=>[133, 133, 133], "mediumorchid"=>[186, 85, 211], "green4"=>[0, 139, 0], "lightskyblue4"=>[96, 123, 139], "ivory1"=>[255, 255, 240], "yellow3"=>[205, 205, 0], "plum1"=>[255, 187, 255], "lightblue1"=>[191, 239, 255], "seashell1"=>[255, 245, 238], "gray53"=>[135, 135, 135], "ivory2"=>[238, 238, 224], "violetred1"=>[255, 62, 150], "plum2"=>[238, 174, 238], "lightblue2"=>[178, 223, 238], "seashell2"=>[238, 229, 222], "gray54"=>[138, 138, 138], "white"=>[255, 255, 255], "mediumslateblue"=>[123, 104, 238], "ivory3"=>[205, 205, 193], "yellow4"=>[139, 139, 0], "lightcyan1"=>[224, 255, 255], "plum3"=>[205, 150, 205], "lightslateblue"=>[132, 112, 255], "lightblue3"=>[154, 192, 205], "seashell3"=>[205, 197, 191], "gray55"=>[140, 140, 140], "ivory4"=>[139, 139, 131], "lightcyan2"=>[209, 238, 238], "violetred2"=>[238, 58, 140], "peru"=>[205, 133, 63], "lightblue4"=>[104, 131, 139], "seashell4"=>[139, 134, 130], "gray56"=>[143, 143, 143], "flesh"=>[255, 125, 64], "lightcyan3"=>[180, 205, 205], "violetred3"=>[205, 50, 120], "plum4"=>[139, 102, 139], "lightblue"=>[173, 216, 230], "gray57"=>[145, 145, 145], "coral"=>[255, 127, 80], "cadmiumorange"=>[255, 97, 3], "khaki1"=>[255, 246, 143], "lightcyan4"=>[122, 139, 139], "violetred4"=>[139, 34, 82], "lightslategray"=>[119, 136, 153], "gray58"=>[148, 148, 148], "sgigray32"=>[81, 81, 81], "khaki2"=>[238, 230, 133], "dodgerblue1"=>[30, 144, 255], "lavenderblush1"=>[255, 240, 245], "gray59"=>[150, 150, 150], "khaki3"=>[205, 198, 115], "dodgerblue2"=>[28, 134, 238], "lavenderblush2"=>[238, 224, 229], "banana"=>[227, 207, 87], "khaki4"=>[139, 134, 78], "dodgerblue3"=>[24, 116, 205], "lavenderblush3"=>[205, 193, 197], "cyan2"=>[0, 238, 238], "cadetblue"=>[95, 158, 160], "cadmiumyellow"=>[255, 153, 18], "mediumpurple"=>[147, 112, 219], "dodgerblue4"=>[16, 78, 139], "lavenderblush4"=>[139, 131, 134], "cyan3"=>[0, 205, 205], "silver"=>[192, 192, 192], "sgigray36"=>[91, 91, 91], "cyan4"=>[0, 139, 139], "deeppink1"=>[255, 20, 147], "burntumber"=>[138, 51, 36], "deeppink2"=>[238, 18, 137], "aliceblue"=>[240, 248, 255], "rosybrown"=>[188, 143, 143], "aquamarine"=>[127, 255, 212], "plum"=>[221, 160, 221], "deeppink3"=>[205, 16, 118], "darkgoldenrod"=>[184, 134, 11], "darkslategray1"=>[151, 255, 255], "chartreuse1"=>[127, 255, 0], "deeppink4"=>[139, 10, 80], "antiquewhite"=>[250, 235, 215], "darkslategray2"=>[141, 238, 238], "chartreuse2"=>[118, 238, 0], "darkslategray3"=>[121, 205, 205], "raspberry"=>[135, 38, 87], "chartreuse3"=>[102, 205, 0], "darkslategray4"=>[82, 139, 139], "chartreuse4"=>[69, 139, 0], "lightsalmon"=>[255, 160, 122], "warmgrey"=>[128, 128, 105], "cobalt"=>[61, 89, 171], "pink"=>[255, 192, 203], "orangered"=>[255, 69, 0], "indianred"=>[205, 92, 92], "palegreen1"=>[154, 255, 154], "red1"=>[255, 0, 0], "darkorange1"=>[255, 127, 0], "palegreen2"=>[144, 238, 144], "darkorchid"=>[153, 50, 204], "red2"=>[238, 0, 0], "darkorange2"=>[238, 118, 0], "palegreen3"=>[124, 205, 124], "goldenrod"=>[218, 165, 32], "red3"=>[205, 0, 0], "tomato1"=>[255, 99, 71], "yellowgreen"=>[154, 205, 50], "darkorange3"=>[205, 102, 0], "palegreen4"=>[84, 139, 84], "gray30"=>[77, 77, 77], "red4"=>[139, 0, 0], "tomato2"=>[238, 92, 66], "darkorange4"=>[139, 69, 0], "antiquewhite1"=>[255, 239, 219], "gray31"=>[79, 79, 79], "brown"=>[165, 42, 42], "tomato3"=>[205, 79, 57], "thistle1"=>[255, 225, 255], "antiquewhite2"=>[238, 223, 204], "darkolivegreen1"=>[202, 255, 112], "gray32"=>[82, 82, 82], "gray80"=>[204, 204, 204], "tomato4"=>[139, 54, 38], "sepia"=>[94, 38, 18], "thistle2"=>[238, 210, 238], "deepskyblue"=>[0, 191, 255], "antiquewhite3"=>[205, 192, 176], "darkolivegreen2"=>[188, 238, 104], "cornflowerblue"=>[100, 149, 237], "gray33"=>[84, 84, 84], "gray81"=>[207, 207, 207], "thistle3"=>[205, 181, 205], "peachpuff"=>[255, 218, 185], "steelblue1"=>[99, 184, 255], "antiquewhite4"=>[139, 131, 120], "darkolivegreen3"=>[162, 205, 90], "gray34"=>[87, 87, 87], "gray82"=>[209, 209, 209], "maroon"=>[128, 0, 0], "thistle4"=>[139, 123, 139], "springgreen1"=>[0, 238, 118], "steelblue2"=>[92, 172, 238], "darkolivegreen4"=>[110, 139, 61], "gray35"=>[89, 89, 89], "gray83"=>[212, 212, 212], "springgreen2"=>[0, 205, 102], "steelblue3"=>[79, 148, 205], "steelblue"=>[70, 130, 180], "gray36"=>[92, 92, 92], "gray84"=>[214, 214, 214], "springgreen3"=>[0, 139, 69], "steelblue4"=>[54, 100, 139], "gray37"=>[94, 94, 94], "blue2"=>[0, 0, 238], "darkturquoise"=>[0, 206, 209], "gray38"=>[97, 97, 97], "gray85"=>[217, 217, 217], "sgigray12"=>[30, 30, 30], "blanchedalmond"=>[255, 235, 205], "violet"=>[238, 130, 238], "blue3"=>[0, 0, 205], "gray39"=>[99, 99, 99], "gray86"=>[219, 219, 219], "burlywood1"=>[255, 211, 155], "navy"=>[0, 0, 128], "darkviolet"=>[148, 0, 211], "blue4"=>[0, 0, 139], "gray87"=>[222, 222, 222], "burlywood2"=>[238, 197, 145], "floralwhite"=>[255, 250, 240], "turquoise"=>[64, 224, 208], "darkorange"=>[255, 140, 0], "gray88"=>[224, 224, 224], "burlywood3"=>[205, 170, 125], "gray89"=>[227, 227, 227], "dimgray"=>[105, 105, 105], "sgigray16"=>[40, 40, 40], "snow"=>[255, 250, 250], "burlywood4"=>[139, 115, 85], "mediumvioletred"=>[199, 21, 133], "seagreen"=>[46, 139, 87], "purple1"=>[155, 48, 255], "lightsteelblue1"=>[202, 225, 255], "purple2"=>[145, 44, 238], "orangered1"=>[255, 69, 0], "lightsteelblue2"=>[188, 210, 238], "purple3"=>[125, 38, 205], "cyan/aqua"=>[0, 255, 255], "orangered2"=>[238, 64, 0], "lightsteelblue3"=>[162, 181, 205], "purple4"=>[85, 26, 139], "orangered3"=>[205, 55, 0], "fuchsia"=>[255, 0, 255], "lightsteelblue4"=>[110, 123, 139], "mistyrose1"=>[255, 228, 225], "orangered4"=>[139, 37, 0], "darkorchid1"=>[191, 62, 255], "lemonchiffon1"=>[255, 250, 205], "mistyrose2"=>[238, 213, 210], "darkorchid2"=>[178, 58, 238], "lemonchiffon2"=>[238, 233, 191], "mistyrose3"=>[205, 183, 181], "royalblue"=>[65, 105, 225], "darkorchid3"=>[154, 50, 205], "lemonchiffon3"=>[205, 201, 165], "sgiolivedrab"=>[142, 142, 56], "mistyrose4"=>[139, 125, 123], "darkorchid4"=>[104, 34, 139], "peachpuff1"=>[255, 218, 185], "mediumseagreen"=>[60, 179, 113], "lemonchiffon4"=>[139, 137, 112], "lightgreen"=>[144, 238, 144], "peachpuff2"=>[238, 203, 173], "peachpuff3"=>[205, 175, 149], "peachpuff4"=>[139, 119, 101], "lightsteelblue"=>[176, 196, 222], "skyblue"=>[135, 206, 235], "gray10"=>[26, 26, 26], "magenta"=>[255, 0, 255], "turquoise1"=>[0, 245, 255], "gray11"=>[28, 28, 28], "turquoise2"=>[0, 229, 238], "chartreuse"=>[127, 255, 0], "navajowhite"=>[255, 222, 173], "ghostwhite"=>[248, 248, 255], "gray12"=>[31, 31, 31], "gray60"=>[153, 153, 153], "melon"=>[227, 168, 105], "turquoise3"=>[0, 197, 205], "gray13"=>[33, 33, 33], "gray61"=>[156, 156, 156], "coral1"=>[255, 114, 86], "turquoise4"=>[0, 134, 139], "gray14"=>[36, 36, 36], "gray62"=>[158, 158, 158], "sgiteal"=>[56, 142, 142], "coral2"=>[238, 106, 80], "honeydew"=>[240, 255, 240], "gray1"=>[3, 3, 3], "gray15"=>[38, 38, 38], "firebrick"=>[178, 34, 34], "coral3"=>[205, 91, 69], "lightpink"=>[255, 182, 193], "gray2"=>[5, 5, 5], "gray16"=>[41, 41, 41], "gray63"=>[161, 161, 161], "coral4"=>[139, 62, 47], "mediumblue"=>[0, 0, 205], "gray3"=>[8, 8, 8], "gray17"=>[43, 43, 43], "gray64"=>[163, 163, 163], "blueviolet"=>[138, 43, 226], "darkgreen"=>[0, 100, 0], "gray4"=>[10, 10, 10], "gray18"=>[46, 46, 46], "gray65"=>[166, 166, 166], "deepskyblue1"=>[0, 191, 255], "gray5"=>[13, 13, 13], "gray19"=>[48, 48, 48], "gray66"=>[168, 168, 168], "mediumspringgreen"=>[0, 250, 154], "darkkhaki"=>[189, 183, 107], "lightgoldenrodyellow"=>[250, 250, 210], "orange"=>[255, 128, 0], "deepskyblue2"=>[0, 178, 238], "gray6"=>[15, 15, 15], "gray67"=>[171, 171, 171], "mediumturquoise"=>[72, 209, 204], "deepskyblue3"=>[0, 154, 205], "turquoiseblue"=>[0, 199, 140], "gray7"=>[18, 18, 18], "gray68"=>[173, 173, 173], "orchid"=>[218, 112, 214], "burlywood"=>[222, 184, 135], "thistle"=>[216, 191, 216], "mediumpurple1"=>[171, 130, 255], "deepskyblue4"=>[0, 104, 139], "gray8"=>[20, 20, 20], "gray69"=>[176, 176, 176], "palevioletred"=>[219, 112, 147], "sandybrown"=>[244, 164, 96], "mediumpurple2"=>[159, 121, 238], "yellow"=>[255, 255, 0], "darkgoldenrod1"=>[255, 185, 15], "gray9"=>[23, 23, 23], "darkseagreen"=>[143, 188, 143], "mediumpurple3"=>[137, 104, 205], "darkgoldenrod2"=>[238, 173, 14], "sgigray92"=>[234, 234, 234], "mediumpurple4"=>[93, 71, 139], "darkgoldenrod3"=>[205, 149, 12], "mediumaquamarine"=>[102, 205, 170], "firebrick1"=>[255, 48, 48], "tomato"=>[255, 99, 71], "darkgoldenrod4"=>[139, 101, 8], "gray"=>[128, 128, 128], "firebrick2"=>[238, 44, 44], "palegoldenrod"=>[238, 232, 170], "moccasin"=>[255, 228, 181], "firebrick3"=>[205, 38, 38], "snow1"=>[255, 250, 250], "sgigray96"=>[244, 244, 244], "firebrick4"=>[139, 26, 26], "snow2"=>[238, 233, 233], "papayawhip"=>[255, 239, 213], "snow3"=>[205, 201, 201], "eggshell"=>[252, 230, 201], "snow4"=>[139, 137, 137], "tan"=>[210, 180, 140], "peacock"=>[51, 161, 201], "gold1"=>[255, 215, 0], "slateblue1"=>[131, 111, 255], "springgreen"=>[0, 255, 127], "ivoryblack"=>[41, 36, 33], "gold2"=>[238, 201, 0], "honeydew1"=>[240, 255, 240], "greenyellow"=>[173, 255, 47], "slateblue2"=>[122, 103, 238], "gainsboro"=>[220, 220, 220], "azure"=>[240, 255, 255], "gold3"=>[205, 173, 0], "oldlace"=>[253, 245, 230], "honeydew2"=>[224, 238, 224], "gold4"=>[139, 117, 0], "honeydew3"=>[193, 205, 193], "slateblue3"=>[105, 89, 205], "green"=>[0, 128, 0], "skyblue1"=>[135, 206, 255], "honeydew4"=>[131, 139, 131], "cadetblue1"=>[152, 245, 255], "slateblue4"=>[71, 60, 139], "sienna"=>[160, 82, 45], "darksalmon"=>[233, 150, 122], "skyblue2"=>[126, 192, 238], "cadetblue2"=>[142, 229, 238], "sapgreen"=>[48, 128, 20], "gray40"=>[102, 102, 102], "skyblue3"=>[108, 166, 205], "midnightblue"=>[25, 25, 112], "blue"=>[0, 0, 255], "cadetblue3"=>[122, 197, 205], "sgichartreuse"=>[113, 198, 113], "skyblue4"=>[74, 112, 139], "cadetblue4"=>[83, 134, 139], "lime"=>[0, 255, 0], "gray90"=>[229, 229, 229], "gray42"=>[105, 105, 105], "mistyrose"=>[255, 228, 225], "burntsienna"=>[138, 54, 15], "ivory"=>[255, 255, 240], "gray43"=>[110, 110, 110], "gray91"=>[232, 232, 232], "darkcyan"=>[0, 139, 139], "gray44"=>[112, 112, 112], "gray92"=>[235, 235, 235], "lawngreen"=>[124, 252, 0], "gray45"=>[115, 115, 115], "gray93"=>[237, 237, 237], "palevioletred1"=>[255, 130, 171], "saddlebrown"=>[139, 69, 19], "lavenderblush"=>[255, 240, 245], "gray46"=>[117, 117, 117], "gray94"=>[240, 240, 240], "palevioletred2"=>[238, 121, 159], "khaki"=>[240, 230, 140], "paleturquoise"=>[174, 238, 238], "gray47"=>[120, 120, 120], "gray95"=>[242, 242, 242], "carrot"=>[237, 145, 33], "palevioletred3"=>[205, 104, 137], "lightsalmon1"=>[255, 160, 122], "olivedrab"=>[107, 142, 35], "gray48"=>[122, 122, 122], "palevioletred4"=>[139, 71, 93], "wheat"=>[245, 222, 179], "lightsalmon2"=>[238, 149, 114], "powderblue"=>[176, 224, 230], "gray49"=>[125, 125, 125], "gray96"=>[245, 245, 245], "red"=>[255, 0, 0], "brown1"=>[255, 64, 64], "lightsalmon3"=>[205, 129, 98], "manganeseblue"=>[3, 168, 158], "gray97"=>[247, 247, 247], "brown2"=>[238, 59, 59], "lightsalmon4"=>[139, 87, 66], "olive"=>[128, 128, 0], "gray98"=>[250, 250, 250], "lightgrey"=>[211, 211, 211], "sgigray72"=>[183, 183, 183], "brown3"=>[205, 51, 51], "gold"=>[255, 215, 0], "mintcream"=>[245, 255, 250], "gray99"=>[252, 252, 252], "brown4"=>[139, 35, 35], "sgidarkgray"=>[85, 85, 85], "magenta2"=>[238, 0, 238], "sgigray76"=>[193, 193, 193], "magenta3"=>[205, 0, 205], "dodgerblue"=>[30, 144, 255], "magenta4"=>[139, 0, 139], "cobaltgreen"=>[61, 145, 64], "sgisalmon"=>[198, 113, 113], "emeraldgreen"=>[0, 201, 87], "sgibrightgray"=>[197, 193, 170], "darkred"=>[139, 0, 0], "rawsienna"=>[199, 97, 20], "seagreen1"=>[84, 255, 159], "lightyellow"=>[255, 255, 224], "olivedrab1"=>[192, 255, 62], "orchid1"=>[255, 131, 250], "seashell"=>[255, 245, 238], "seagreen2"=>[78, 238, 148], "bisque1"=>[255, 228, 196], "olivedrab2"=>[179, 238, 58], "orchid2"=>[238, 122, 233], "azure1"=>[240, 255, 255], "seagreen3"=>[67, 205, 128], "bisque2"=>[238, 213, 183], "whitesmoke"=>[245, 245, 245], "olivedrab3"=>[154, 205, 50], "orchid3"=>[205, 105, 201], "azure2"=>[224, 238, 238], "lightpink1"=>[255, 174, 185], "lightgoldenrod1"=>[255, 236, 139], "bisque3"=>[205, 183, 158], "olivedrab4"=>[105, 139, 34], "orchid4"=>[139, 71, 137], "purple"=>[128, 0, 128], "lemonchiffon"=>[255, 250, 205], "azure3"=>[193, 205, 205], "lightpink2"=>[238, 162, 173], "seagreen4"=>[46, 139, 87], "forestgreen"=>[34, 139, 34], "lightgoldenrod2"=>[238, 220, 130], "bisque4"=>[139, 125, 107], "sgislateblue"=>[113, 113, 198], "azure4"=>[131, 139, 139], "lightpink3"=>[205, 140, 149], "lightgoldenrod3"=>[205, 190, 112], "gray20"=>[51, 51, 51], "sgibeet"=>[142, 56, 142], "limegreen"=>[50, 205, 50], "orange1"=>[255, 165, 0], "lightpink4"=>[139, 95, 101], "lightgoldenrod4"=>[139, 129, 76], "gray21"=>[54, 54, 54], "orange2"=>[238, 154, 0], "gray22"=>[56, 56, 56], "gray70"=>[179, 179, 179], "orange3"=>[205, 133, 0], "gray23"=>[59, 59, 59], "gray71"=>[181, 181, 181], "orange4"=>[139, 90, 0], "lightseagreen"=>[32, 178, 170], "bisque"=>[255, 228, 196], "gray24"=>[61, 61, 61], "gray72"=>[184, 184, 184], "darkslateblue"=>[72, 61, 139], "gray25"=>[64, 64, 64], "gray73"=>[186, 186, 186], "lightcoral"=>[240, 128, 128], "tan1"=>[255, 165, 79], "gray26"=>[66, 66, 66], "black"=>[0, 0, 0], "tan2"=>[238, 154, 73], "gray27"=>[69, 69, 69], "gray74"=>[189, 189, 189], "teal"=>[0, 128, 128], "tan3"=>[205, 133, 63], "aquamarine1"=>[127, 255, 212], "gray28"=>[71, 71, 71], "gray75"=>[191, 191, 191], "tan4"=>[139, 90, 43], "darkmagenta"=>[139, 0, 139], "aquamarine2"=>[118, 238, 198], "gray29"=>[74, 74, 74], "gray76"=>[194, 194, 194], "indianred1"=>[255, 106, 106], "chocolate"=>[210, 105, 30], "aquamarine3"=>[102, 205, 170], "gray77"=>[196, 196, 196], "indianred2"=>[238, 99, 99], "slategray1"=>[198, 226, 255], "chocolate1"=>[255, 127, 36], "aquamarine4"=>[69, 139, 116], "gray78"=>[199, 199, 199], "sgigray52"=>[132, 132, 132], "indianred3"=>[205, 85, 85], "salmon"=>[250, 128, 114], "darkblue"=>[0, 0, 139], "lightyellow1"=>[255, 255, 224], "slategray2"=>[185, 211, 238], "chocolate2"=>[238, 118, 33], "gray79"=>[201, 201, 201], "indianred4"=>[139, 58, 58], "hotpink"=>[255, 105, 180], "brick"=>[156, 102, 31], "lightyellow2"=>[238, 238, 209], "slategray3"=>[159, 182, 205], "chocolate3"=>[205, 102, 29], "darkgray"=>[169, 169, 169], "lightyellow3"=>[205, 205, 180], "darkolivegreen"=>[85, 107, 47], "slategray4"=>[108, 123, 139], "chocolate4"=>[139, 69, 19], "salmon1"=>[255, 140, 105], "deeppink"=>[255, 20, 147], "indigo"=>[75, 0, 130], "darkslategray"=>[47, 79, 79], "navajowhite1"=>[255, 222, 173], "lightyellow4"=>[139, 139, 122], "royalblue1"=>[72, 118, 255], "slateblue"=>[106, 90, 205], "maroon1"=>[255, 52, 179], "sgigray56"=>[142, 142, 142], "salmon2"=>[238, 130, 98], "navajowhite2"=>[238, 207, 161], "coldgrey"=>[128, 138, 135], "royalblue2"=>[67, 110, 238], "cornsilk1"=>[255, 248, 220], "maroon2"=>[238, 48, 167], "salmon3"=>[205, 112, 84], "navajowhite3"=>[205, 179, 139], "royalblue3"=>[58, 95, 205], "cornsilk2"=>[238, 232, 205], "maroon3"=>[205, 41, 144], "slategray"=>[112, 128, 144], "salmon4"=>[139, 76, 57], "navajowhite4"=>[139, 121, 94], "royalblue4"=>[39, 64, 139], "darkseagreen1"=>[193, 255, 193], "cornsilk3"=>[205, 200, 177], "maroon4"=>[139, 28, 98], "hotpink1"=>[255, 110, 180], "mediumorchid1"=>[224, 102, 255], "darkseagreen2"=>[180, 238, 180], "cornsilk4"=>[139, 136, 120], "mint"=>[189, 252, 201], "hotpink2"=>[238, 106, 167], "sgilightblue"=>[125, 158, 192], "goldenrod1"=>[255, 193, 37], "mediumorchid2"=>[209, 95, 238], "darkseagreen3"=>[155, 205, 155], "hotpink3"=>[205, 96, 144], "goldenrod2"=>[238, 180, 34], "mediumorchid3"=>[180, 82, 205], "darkseagreen4"=>[105, 139, 105], "hotpink4"=>[139, 58, 98], "crimson"=>[220, 20, 60], "lightskyblue"=>[135, 206, 250], "goldenrod3"=>[205, 155, 29], "mediumorchid4"=>[122, 55, 139], "cornsilk"=>[255, 248, 220]}
720
+ pdf=FPDF.new('P', "cm")
721
+ pdf.SetTitle(pdfFile)
722
+ pdf.SetCreator("newickDraw")
723
+ pdf.SetAuthor(ENV["USER"]) if (!ENV["USER"].nil?)
724
+ pdf.AddPage
725
+ yUnit = nil
726
+ lineWidth = nil
727
+ fontSize = nil
728
+ bootScale = 0.6
729
+ if (taxa.size < 30)
730
+ fontSize = 10
731
+ yUnit = 0.5
732
+ lineWidth = 0.02
733
+ elsif (taxa.size < 60)
734
+ fontSize = 8
735
+ yUnit = 0.25
736
+ lineWidth = 0.01
737
+ elsif (taxa.size < 150)
738
+ fontSize = 8
739
+ yUnit = 0.197
740
+ lineWidth = 0.01
741
+ elsif (taxa.size < 300)
742
+ fontSize = 2
743
+ yUnit = 0.09
744
+ lineWidth = 0.005
745
+ elsif (taxa.size < 400)
746
+ fontSize = 2
747
+ yUnit = 0.055
748
+ lineWidth = 0.002
749
+ elsif (taxa.size < 800)
750
+ fontSize = 1
751
+ yUnit = 0.030
752
+ lineWidth = 0.0015
811
753
  else
812
- pdf.SetTextColor(colors[hl][0], colors[hl][1], colors[hl][2]) if hl
813
- pdf.Write(0, entry)
814
- pdf.SetTextColor(colors["black"][0], colors["black"][1], colors["black"][2]) if hl
754
+ fontSize = 0.5
755
+ yUnit = 0.020
756
+ lineWidth = 0.0010
815
757
  end
816
- end
817
- pdf.Line(xOffSet + child.parent.x*xScale, child.y,
818
- xOffSet + child.x*xScale, child.y)
819
- }
820
- if (labelName)
821
- pdf.SetFont('Times','B', 24)
822
- pdf.SetXY(0, pdf.GetY + 1)
823
- pdf.Write(0, labelName)
824
- end
825
- if (brackets)
826
- brackets.each {|bracket|
827
- x, y1, y2, label, r, p = bracket
828
- next if label.nil?
829
- pdf.SetLineWidth(lineWidth * 5)
830
- pdf.SetFont('Times','B', fontSize*1.5)
831
- pdf.Line(x, y1, x, y2)
832
- pdf.Line(x, y1, x - 0.3, y1)
833
- pdf.Line(x, y2, x - 0.3, y2)
834
- pdf.SetXY(x, (y1+y2)/2)
835
- pdf.Write(0, label)
836
- if (r == "r")
837
- pdf.SetTextColor(255, 0, 0)
838
- pdf.SetXY(x + 1.8, -0.65+(y1+y2)/2)
839
- pdf.SetFont('Times','B', fontSize*10)
840
- pdf.Write(0, " .")
841
- pdf.SetTextColor(0, 0, 0)
758
+ bootScale = 0.5 * fontSize
759
+ pdf.SetFont('Times','B', fontSize)
760
+ calcPos(yUnit) # calculate node pos before drawing
761
+ max = 0
762
+ @root.leaves.each do |leaf|
763
+ d = leaf.distToAncestor(@root)
764
+ max = d if (max < d)
765
+ end
766
+ xScale = 10.0/max
767
+ xOffSet = 0.25
768
+ pdf.SetLineWidth(lineWidth)
769
+ pdf.SetTextColor(0, 0, 0)
770
+ pdf.Line(0, @root.y, xOffSet, @root.y)
771
+ pdf.Line(xOffSet, @root.yMin, xOffSet, @root.yMax)
772
+ @root.descendants.each do |child|
773
+ if (!child.leaf?)
774
+ if (child.name.to_i > 75 && boot == "width") # good bootstrap
775
+ pdf.SetLineWidth(lineWidth * 5)
776
+ else
777
+ pdf.SetLineWidth(lineWidth)
778
+ end
779
+ bootX = xOffSet + child.x*xScale
780
+ bootY = ((child.yMin + child.yMax) / 2.0)
781
+ pdf.SetXY(bootX, bootY)
782
+ pdf.SetFont('Times','B', bootScale)
783
+ pdf.Write(0, child.name.to_s)
784
+ pdf.SetFont('Times','B', fontSize)
785
+ pdf.Line(xOffSet + child.x*xScale, child.yMin,
786
+ xOffSet + child.x*xScale, child.yMax)
787
+ else
788
+ if (child.parent.name.to_i > 75 && boot == "width") # good bootstrap
789
+ pdf.SetLineWidth(lineWidth * 5)
790
+ else
791
+ pdf.SetLineWidth(lineWidth)
792
+ end
793
+ pdf.SetXY(xOffSet + child.x*xScale, child.y)
794
+ efields = child.name.split("__")
795
+ entry, species = efields.first, efields.last
796
+ if (entry =~/\{([^\}]*)\}/)
797
+ species = $1
798
+ end
799
+ species = entry if species.nil? && !rawNames
800
+ species = child.name if rawNames
801
+ hl = false
802
+ highlights.keys.each do |highlight|
803
+ hl = highlights[highlight] if (entry.index(highlight))
804
+ end
805
+ if (pdfFile.index(entry)) # name of query taxon
806
+ pdf.SetTextColor(colors["red"][0], colors["red"][1], colors["red"][2])
807
+ pdf.Write(0, entry)
808
+ pdf.SetTextColor(colors["black"][0], colors["black"][1], colors["black"][2])
809
+ elsif (linker && link = send(linker, entry))
810
+ pdf.SetTextColor(colors["black"][0], colors["black"][1], colors["black"][2]) if hl
811
+ pdf.Write(0, species, link)
812
+ pdf.SetTextColor(colors["black"][0], colors["black"][1], colors["black"][2]) if hl
813
+ elsif (!species.nil?)
814
+ pdf.SetTextColor(colors[hl][0], colors[hl][1], colors[hl][2]) if hl
815
+ pdf.Write(0, species)
816
+ pdf.SetTextColor(colors["black"][0], colors["black"][1], colors["black"][2]) if hl
817
+ else
818
+ pdf.SetTextColor(colors[hl][0], colors[hl][1], colors[hl][2]) if hl
819
+ pdf.Write(0, entry)
820
+ pdf.SetTextColor(colors["black"][0], colors["black"][1], colors["black"][2]) if hl
821
+ end
842
822
  end
843
- if (p == "p" || r == "p")
844
- pdf.SetTextColor(255, 0, 255)
845
- pdf.SetXY(x + 2.3, -0.65+(y1+y2)/2)
846
- pdf.SetFont('Times','B', fontSize*10)
847
- pdf.Write(0, " .")
848
- pdf.SetTextColor(0, 0, 0)
823
+ pdf.Line(xOffSet + child.parent.x*xScale, child.y,
824
+ xOffSet + child.x*xScale, child.y)
825
+ end
826
+ if (labelName)
827
+ pdf.SetFont('Times','B', 24)
828
+ pdf.SetXY(0, pdf.GetY + 1)
829
+ pdf.Write(0, labelName)
830
+ end
831
+ if (brackets)
832
+ brackets.each do |bracket|
833
+ x, y1, y2, label, r, p = bracket
834
+ next if label.nil?
835
+ pdf.SetLineWidth(lineWidth * 5)
836
+ pdf.SetFont('Times','B', fontSize*1.5)
837
+ pdf.Line(x, y1, x, y2)
838
+ pdf.Line(x, y1, x - 0.3, y1)
839
+ pdf.Line(x, y2, x - 0.3, y2)
840
+ pdf.SetXY(x, (y1+y2)/2)
841
+ pdf.Write(0, label)
842
+ if (r == "r")
843
+ pdf.SetTextColor(255, 0, 0)
844
+ pdf.SetXY(x + 1.8, -0.65+(y1+y2)/2)
845
+ pdf.SetFont('Times','B', fontSize*10)
846
+ pdf.Write(0, " .")
847
+ pdf.SetTextColor(0, 0, 0)
848
+ end
849
+ if (p == "p" || r == "p")
850
+ pdf.SetTextColor(255, 0, 255)
851
+ pdf.SetXY(x + 2.3, -0.65+(y1+y2)/2)
852
+ pdf.SetFont('Times','B', fontSize*10)
853
+ pdf.Write(0, " .")
854
+ pdf.SetTextColor(0, 0, 0)
855
+ end
849
856
  end
850
- }
857
+ end
858
+ pdf.SetLineWidth(lineWidth * 5)
859
+ pdf.Line(1, pdf.GetY + 1, 1 + 0.1*xScale, pdf.GetY + 1)
860
+ pdf.SetFont('Times','B', fontSize)
861
+ pdf.SetXY(1 + 0.1*xScale, pdf.GetY + 1)
862
+ pdf.Write(0, "0.1")
863
+ if (pdfFile =~/^--/)
864
+ return pdf.Output
865
+ else
866
+ pdf.Output(pdfFile)
867
+ end
851
868
  end
852
- pdf.SetLineWidth(lineWidth * 5)
853
- pdf.Line(1, pdf.GetY + 1, 1 + 0.1*xScale, pdf.GetY + 1)
854
- pdf.SetFont('Times','B', fontSize)
855
- pdf.SetXY(1 + 0.1*xScale, pdf.GetY + 1)
856
- pdf.Write(0, "0.1")
857
- if (pdfFile =~/^--/)
858
- return pdf.Output
859
- else
860
- pdf.Output(pdfFile)
861
869
  end
862
- end
863
- end
864
870
 
865
871
 
866
872
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newick-ruby
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 1
10
- version: 1.0.1
9
+ - 2
10
+ version: 1.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jonathan Badger
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-02 00:00:00 -07:00
18
+ date: 2010-11-08 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency