bio-polyploid-tools 0.5.2 → 0.6.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 23c185fa7183010bca4c619fa252ecd2d58e2d13
4
- data.tar.gz: a093ad10be19c610df004bc2b0ad8834dcd7ca00
3
+ metadata.gz: 76d57ca94d667e3aff5324977e57d8b7a5f0d91e
4
+ data.tar.gz: ccd2fad348fbc8a68927b944adc8e13b7d776edf
5
5
  SHA512:
6
- metadata.gz: 7b6838728afb273a71afc44bfe790c947662c0d432229e3d40f7dca34e67928a849a95c9f52c90562b509e3ef1aa9d51147c7c60de49573baf826695cc425365
7
- data.tar.gz: 4941e7ca5027e0fed010dcd6523f82fafc1a8db75a9826f4c14f6fef20a54e79f614d91560cf398174e23ebbe1f2c71b80916ba118ae28ed50fe4a451f3c8410
6
+ metadata.gz: 99edd393245dc13ebf8b10abab165c86a9e808f5cabfe95fccd6607360383d79c277a84e37c831782412817ac35b82dddde717448510dbd5f89b4e5a268640d9
7
+ data.tar.gz: c387e7b9a9b8d5c6bbb8e286a2fa71e4ecd92093578e58d04d260f5d8f7ba66f47d03856486c030f91488f39078129b27f600329596faec2183e0c521eaf6785
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.2
1
+ 0.6.0
data/bin/polymarker.rb CHANGED
@@ -36,6 +36,8 @@ options[:bucket] = 1
36
36
  options[:model] = "est2genome"
37
37
  options[:arm_selection] = arm_selection_functions[:arm_selection_embl] ;
38
38
  options[:flanking_size] = 150;
39
+ options[:variation_free_region] = 0
40
+ options[:extract_found_contigs] = false
39
41
  options[:primer_3_preferences] = {
40
42
  :primer_product_size_range => "50-150" ,
41
43
  :primer_max_size => 25 ,
@@ -60,6 +62,11 @@ OptionParser.new do |opts|
60
62
  opts.on("-s", "--snp_list FILE", "File with the list of snps to search from, requires --reference to get the sequence using a position") do |o|
61
63
  options[:snp_list] = o
62
64
  end
65
+
66
+ opts.on("-t", "--mutant_list FILE", "File with the list of positions with mutation and the mutation line.\n\
67
+ requires --reference to get the sequence using a position") do |o|
68
+ options[:mutant_list] = o
69
+ end
63
70
 
64
71
  opts.on("-r", "--reference FILE", "Fasta file with the sequence for the markers (to complement --snp_list)") do |o|
65
72
  options[:reference] = o
@@ -71,9 +78,9 @@ OptionParser.new do |opts|
71
78
 
72
79
  opts.on("-e", "--exonerate_model MODEL", "Model to be used in exonerate to search for the contigs") do |o|
73
80
  options[:model] = o
74
- end
81
+ end
75
82
 
76
- opts.on("-a", "--arm_selection arm_selection_embl|arm_selection_morex|arm_selection_first_two", "Function to decide the chromome arm") do |o|
83
+ opts.on("-a", "--arm_selection arm_selection_embl|arm_selection_morex|arm_selection_first_two", "Function to decide the chromome arm") do |o|
77
84
  options[:arm_selection] = arm_selection_functions[o.to_sym];
78
85
  end
79
86
 
@@ -81,8 +88,20 @@ OptionParser.new do |opts|
81
88
  options[:primer_3_preferences] = Bio::DB::Primer3.read_primer_preferences(o, options[:primer_3_preferences] )
82
89
  end
83
90
 
91
+ opts.on("-v", "--variation_free_region INT", "If present, avoid generating the common primer if there are homoeologous SNPs within the specified distance") do |o|
92
+ options[:variation_free_region] = o.to_i
93
+ end
94
+
95
+ opts.on("-x", "--extract_found_contigs", "If present, save in a separate file the contigs with matches. Useful to debug.") do |o|
96
+ options[:extract_found_contigs] = true
97
+ end
98
+
99
+ opts.on("-P", "--primers_to_order")do
100
+ #TODO: have a string with the tails, optional.
101
+ options[:primers_to_order] = true
102
+ end
103
+
84
104
 
85
-
86
105
  end.parse!
87
106
 
88
107
  if options[:primer_3_preferences][:primer_product_size_range]
@@ -108,8 +127,9 @@ snp_in="B"
108
127
 
109
128
  fasta_reference = nil
110
129
  #test_file="/Users/ramirezr/Dropbox/JIC/PrimersToTest/test_primers_nick_and_james_1.csv"
111
- test_file=options[:marker_list]
130
+ test_file=options[:marker_list] if options[:marker_list]
112
131
  test_file=options[:snp_list] if options[:snp_list]
132
+ test_file=options[:mutant_list] if options[:mutant_list]
113
133
  fasta_reference = options[:reference]
114
134
  output_folder="#{test_file}_primer_design_#{Time.now.strftime('%Y%m%d-%H%M%S')}"
115
135
  output_folder= options[:output_folder] if options[:output_folder]
@@ -122,12 +142,12 @@ primer_3_input="#{output_folder}/primer_3_input_temp"
122
142
  primer_3_output="#{output_folder}/primer_3_output_temp"
123
143
  exons_filename="#{output_folder}/exons_genes_and_contigs.fa"
124
144
  output_primers="#{output_folder}/primers.csv"
145
+ output_to_order="#{output_folder}/primers_to_order.csv"
125
146
  @status_file="#{output_folder}/status.txt"
126
147
 
127
148
  primer_3_config=File.expand_path(File.dirname(__FILE__) + '/../conf/primer3_config')
128
149
  model=options[:model]
129
150
 
130
-
131
151
  def write_status(status)
132
152
  f=File.open(@status_file, "a")
133
153
  f.puts "#{Time.now.to_s},#{status}"
@@ -148,9 +168,6 @@ if fasta_reference
148
168
  p "Fasta reference: #{fasta_reference}"
149
169
  end
150
170
 
151
-
152
-
153
-
154
171
  #1. Read all the SNP files
155
172
  #chromosome = nil
156
173
  write_status "Reading SNPs"
@@ -167,13 +184,22 @@ File.open(test_file) do | f |
167
184
  region = fasta_reference_db.index.region_for_entry(snp.gene).get_full_region
168
185
  snp.template_sequence = fasta_reference_db.fetch_sequence(region)
169
186
  else
170
- $stderr.puts "ERROR: Unable to find entry for #{snp.gene}"
187
+ write_status "WARN: Unable to find entry for #{snp.gene}"
188
+ end
189
+ elsif options[:mutant_list] and options[:reference] #List and fasta file
190
+ snp = Bio::PolyploidTools::SNPMutant.parse(line)
191
+ entry = fasta_reference_db.index.region_for_entry(snp.contig)
192
+ if entry
193
+ region = fasta_reference_db.index.region_for_entry(snp.contig).get_full_region
194
+ snp.full_sequence = fasta_reference_db.fetch_sequence(region)
195
+ else
196
+ write_status "WARN: Unable to find entry for #{snp.gene}"
171
197
  end
172
-
173
198
  else
174
199
  rise Bio::DB::Exonerate::ExonerateException.new "Wrong number of arguments. "
175
200
  end
176
201
  rise Bio::DB::Exonerate::ExonerateException.new "No SNP for line '#{line}'" if snp == nil
202
+
177
203
  snp.snp_in = snp_in
178
204
  snp.original_name = original_name
179
205
  if snp.position
@@ -206,7 +232,7 @@ file.close
206
232
  #chr_group = chromosome[0]
207
233
  write_status "Searching markers in genome"
208
234
  exo_f = File.open(exonerate_file, "w")
209
- contigs_f = File.open(temp_contigs, "w")
235
+ contigs_f = File.open(temp_contigs, "w") if options[:extract_found_contigs]
210
236
  filename=path_to_contigs
211
237
  puts filename
212
238
  target=filename
@@ -224,13 +250,13 @@ Bio::DB::Exonerate.align({:query=>temp_fasta_query, :target=>target, :model=>mod
224
250
  raise ExonerateException.new, "Entry not found! #{aln.target_id}. Make sure that the #{target_id}.fai was generated properly." if entry == nil
225
251
  region = entry.get_full_region
226
252
  seq = fasta_file.fetch_sequence(region)
227
- contigs_f.puts(">#{aln.target_id}\n#{seq}")
253
+ contigs_f.puts(">#{aln.target_id}\n#{seq}") if options[:extract_found_contigs]
228
254
  end
229
255
  end
230
256
  end
231
257
 
232
- exo_f.close()
233
- contigs_f.close()
258
+ exo_f.close()
259
+ contigs_f.close() if options[:extract_found_contigs]
234
260
 
235
261
  #4. Load all the results from exonerate and get the input filename for primer3
236
262
  #Custom arm selection function that only uses the first two characters. Maybe
@@ -241,12 +267,13 @@ write_status "Reading best alignment on each chromosome"
241
267
  container= Bio::PolyploidTools::ExonContainer.new
242
268
  container.flanking_size=options[:flanking_size]
243
269
  container.gene_models(temp_fasta_query)
244
- container.chromosomes(temp_contigs)
270
+ container.chromosomes(fasta_reference)
245
271
  container.add_parental({:name=>snp_in})
246
272
  container.add_parental({:name=>original_name})
247
273
  snps.each do |snp|
248
274
  snp.container = container
249
275
  snp.flanking_size = container.flanking_size
276
+ snp.variation_free_region = options[:variation_free_region]
250
277
  container.add_snp(snp)
251
278
  end
252
279
  container.add_alignments({:exonerate_file=>exonerate_file, :arm_selection=>options[:arm_selection] , :min_identity=>min_identity})
@@ -281,6 +308,8 @@ kasp_container.add_primers_file(primer_3_output) if added_exons > 0
281
308
  header = "Marker,SNP,RegionSize,chromosome,total_contigs,contig_regions,SNP_type,#{original_name},#{snp_in},common,primer_type,orientation,#{original_name}_TM,#{snp_in}_TM,common_TM,selected_from,product_size,errors"
282
309
  File.open(output_primers, 'w') { |f| f.write("#{header}\n#{kasp_container.print_primers}") }
283
310
 
311
+ File.open(output_to_order, "w") { |io| io.write(kasp_container.print_primers_with_tails()) }
312
+
284
313
  write_status "DONE"
285
314
  rescue StandardError => e
286
315
  write_status "ERROR\t#{e.message}"
@@ -28,7 +28,7 @@ OptionParser.new do |opts|
28
28
 
29
29
  opts.banner = "Usage: snp_postion_to_polymarker.rb [options]"
30
30
 
31
- opts.on("-s", "--sno_file CSV", "CSV file with the following columnns:\nID,Allele_1,position,Allele_1,target_chromosome") do |o|
31
+ opts.on("-s", "--snp_file CSV", "CSV file with the following columnns:\nID,Allele_1,position,Allele_1,target_chromosome") do |o|
32
32
  options[:snp_file] = o
33
33
  end
34
34
  opts.on("-r", "--reference FASTA", "reference with the genes/contings/marker seuqnece") do |o|
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: bio-polyploid-tools 0.5.2 ruby lib
5
+ # stub: bio-polyploid-tools 0.6.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "bio-polyploid-tools"
9
- s.version = "0.5.2"
9
+ s.version = "0.6.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Ricardo H. Ramirez-Gonzalez"]
14
- s.date = "2014-10-28"
14
+ s.date = "2015-02-15"
15
15
  s.description = "Repository of tools developed in TGAC and Crop Genetics in JIC to work with polyploid wheat"
16
16
  s.email = "ricardo.ramirez-gonzalez@tgac.ac.uk"
17
17
  s.executables = ["bfr.rb", "count_variations.rb", "filter_blat_by_target_coverage.rb", "find_best_blat_hit.rb", "find_best_exonerate.rb", "hexaploid_primers.rb", "homokaryot_primers.rb", "map_markers_to_contigs.rb", "markers_in_region.rb", "polymarker.rb", "snp_position_to_polymarker.rb", "snps_between_bams.rb"]
@@ -81,6 +81,7 @@ Gem::Specification.new do |s|
81
81
  "lib/bio/PolyploidTools/Marker.rb",
82
82
  "lib/bio/PolyploidTools/PrimerRegion.rb",
83
83
  "lib/bio/PolyploidTools/SNP.rb",
84
+ "lib/bio/PolyploidTools/SNPMutant.rb",
84
85
  "lib/bio/PolyploidTools/SNPSequence.rb",
85
86
  "lib/bio/db/exonerate.rb",
86
87
  "lib/bio/db/primer3.rb",
@@ -91,6 +92,8 @@ Gem::Specification.new do |s|
91
92
  "test/data/BS00068396_51_contigs.fa",
92
93
  "test/data/BS00068396_51_exonerate.tab",
93
94
  "test/data/BS00068396_51_genes.txt",
95
+ "test/data/IWGSC_CSS_1AL_scaff_1455974.fa",
96
+ "test/data/IWGSC_CSS_1AL_scaff_1455974_aln_contigs.fa",
94
97
  "test/data/LIB1716.bam",
95
98
  "test/data/LIB1716.bam.bai",
96
99
  "test/data/LIB1719.bam",
@@ -111,6 +114,7 @@ Gem::Specification.new do |s|
111
114
  "test/data/patological_cases5D.csv",
112
115
  "test/data/primer_3_input_header_test",
113
116
  "test/data/short_primer_design_test.csv",
117
+ "test/data/test_from_mutant.csv",
114
118
  "test/data/test_iselect.csv",
115
119
  "test/data/test_iselect_reference.fa",
116
120
  "test/data/test_iselect_reference.fa.fai",
@@ -14,6 +14,7 @@ module Bio::PolyploidTools
14
14
  attr_accessor :genomes_count
15
15
  attr_accessor :primer_3_min_seq_length
16
16
  attr_accessor :chromosome
17
+ attr_accessor :variation_free_region
17
18
 
18
19
  #Format:
19
20
  #Gene_name,Original,SNP_Pos,pos,chromosome
@@ -37,6 +38,7 @@ module Bio::PolyploidTools
37
38
  def initialize
38
39
  @genomes_count = 3 #TODO: if we want to use this with other polyploids, me need to set this as a variable in the main script.
39
40
  @primer_3_min_seq_length = 50
41
+ @variation_free_region = 0
40
42
  end
41
43
 
42
44
  def to_polymarker_sequence(flanking_size)
@@ -260,8 +262,14 @@ module Bio::PolyploidTools
260
262
  sequence = reverse_complement_string(sequence)
261
263
  orientation = "reverse"
262
264
  end
265
+ if @variation_free_region > 0
266
+ check_str = sequence[right+1, @variation_free_region]
267
+ return nil if check_str != check_str.downcase
268
+ end
269
+
263
270
  end
264
271
 
272
+
265
273
  str = "SEQUENCE_ID=#{opts[:name]} #{orientation}\n"
266
274
  str << "SEQUENCE_FORCE_LEFT_END=#{left}\n"
267
275
  str << "SEQUENCE_FORCE_RIGHT_END=#{right}\n" if opts[:right_pos]
@@ -279,8 +287,6 @@ module Bio::PolyploidTools
279
287
  str << "SEQUENCE_FORCE_LEFT_END=#{left}\n"
280
288
  str << "SEQUENCE_TEMPLATE=#{sequence}\n"
281
289
  str << "=\n"
282
- else
283
-
284
290
  end
285
291
 
286
292
  str
@@ -0,0 +1,85 @@
1
+
2
+ require_relative "SNPSequence"
3
+ require 'bio-samtools'
4
+ module Bio::PolyploidTools
5
+ class SNPSequenceException < RuntimeError
6
+ end
7
+
8
+ class SNPMutant < SNPSequence
9
+
10
+ attr_accessor :library, :contig, :chr
11
+ #Format:
12
+ #seqid,library,position,wt_base,mut_base
13
+ #IWGSC_CSS_1AL_scaff_1455974,Kronos2281,127,C,T
14
+ def self.parse(reg_str)
15
+ reg_str.chomp!
16
+ snp = SNPMutant.new
17
+
18
+ arr = reg_str.split(",")
19
+
20
+ throw SNPSequenceException.new "Need five fields to parse, and got #{arr.size} in #{reg_str}" unless arr.size == 5
21
+
22
+ snp.contig, snp.library, snp.position, snp.original, snp.snp = reg_str.split(",")
23
+ snp.position = snp.position.to_i
24
+ snp.gene = "EMPTY"
25
+ begin
26
+ toks = snp.contig.split('_')
27
+ #1AL_1455974_Kronos2281_127C
28
+ #snp.chr = contig.split('_')[2][0,2] #This parses the default from the IWGSC. We may want to make this a lambda
29
+ #snp.chr = toks[2][0,2]
30
+ name = toks[2] + "_" + toks[4] + "_" + snp.library + "_" + snp.position.to_s
31
+ snp.gene = name
32
+ snp.chromosome = toks[2][0,2]
33
+ snp.chr = snp.chromosome
34
+
35
+ rescue Exception => e
36
+ $stderr.puts "WARN: snp.chr couldnt be set, the sequence id to parse was #{snp.contig}. We expect something like: IWGSC_CSS_1AL_scaff_1455974"
37
+ snp.gene = "Error"
38
+ $stderr.puts e
39
+ end
40
+
41
+ snp.exon_list = Hash.new()
42
+ snp.flanking_size=100
43
+ snp
44
+ end
45
+
46
+ def full_sequence=(seq)
47
+ self.template_sequence = seq
48
+ self.sequence_original = self.to_polymarker_sequence(self.flanking_size)
49
+ self.parse_sequence_snp
50
+ end
51
+
52
+ def full_sequence()
53
+ self.template_sequence
54
+ end
55
+
56
+ def chromosome_group
57
+ chr[0]
58
+ end
59
+
60
+ def chromosome_genome
61
+ chr[1]
62
+ end
63
+
64
+ def chromosome_genome
65
+ return chr[3] if chr[3]
66
+ return nil
67
+ end
68
+
69
+ def parse_sequence_snp
70
+ pos = 0
71
+ match_data = /(?<pre>\w*)\[(?<org>[ACGT])\/(?<snp>[ACGT])\](?<pos>\w*)/.match(sequence_original.strip)
72
+ if match_data
73
+ @position = Regexp.last_match(:pre).size + 1
74
+ @original = Regexp.last_match(:org)
75
+ @snp = Regexp.last_match(:snp)
76
+ amb_base = Bio::NucleicAcid.to_IUAPC("#{@original}#{@snp}")
77
+ @template_sequence = "#{Regexp.last_match(:pre)}#{amb_base}#{Regexp.last_match(:pos)}"
78
+
79
+ end
80
+ end
81
+
82
+
83
+
84
+ end
85
+ end
@@ -41,14 +41,14 @@ module Bio::PolyploidTools
41
41
  pos = 0
42
42
  match_data = /(?<pre>\w*)\[(?<org>[ACGT])\/(?<snp>[ACGT])\](?<pos>\w*)/.match(sequence_original.strip)
43
43
  if match_data
44
- @position = Regexp.last_match(:pre).size + 1
45
- @original = Regexp.last_match(:org)
46
- @snp = Regexp.last_match(:snp)
47
-
48
- amb_base = Bio::NucleicAcid.to_IUAPC("#{@original}#{@snp}")
49
-
50
- @template_sequence = "#{Regexp.last_match(:pre)}#{amb_base}#{Regexp.last_match(:pos)}"
51
-
44
+ @position = Regexp.last_match(:pre).size + 1
45
+ @original = Regexp.last_match(:org)
46
+ @snp = Regexp.last_match(:snp)
47
+
48
+ amb_base = Bio::NucleicAcid.to_IUAPC("#{@original}#{@snp}")
49
+
50
+ @template_sequence = "#{Regexp.last_match(:pre)}#{amb_base}#{Regexp.last_match(:pos)}"
51
+
52
52
  end
53
53
  end
54
54
 
@@ -17,18 +17,18 @@ module Bio::DB::Primer3
17
17
  end
18
18
 
19
19
  def self.prepare_input_file(file, opts2={})
20
- opts = {
21
- :primer_product_size_range => "50-150" ,
22
- :primer_max_size => 25 ,
23
- :primer_lib_ambiguity_codes_consensus => 1,
24
- :primer_liberal_base => 1,
25
- :primer_num_return => 5,
26
- :primer_explain_flag => 1,
27
- :primer_thermodynamic_parameters_path => File.expand_path(File.dirname(__FILE__) + '../../../../conf/primer3_config/') + '/'
20
+ opts = {
21
+ :primer_product_size_range => "50-150" ,
22
+ :primer_max_size => 25 ,
23
+ :primer_lib_ambiguity_codes_consensus => 1,
24
+ :primer_liberal_base => 1,
25
+ :primer_num_return => 5,
26
+ :primer_explain_flag => 1,
27
+ :primer_thermodynamic_parameters_path => File.expand_path(File.dirname(__FILE__) + '../../../../conf/primer3_config/') + '/'
28
28
  }.merge(opts2)
29
29
 
30
30
  opts.each do |key,value|
31
- file.puts "#{key.to_s.upcase}=#{value}\n"
31
+ file.puts "#{key.to_s.upcase}=#{value}\n"
32
32
  end
33
33
  # file.puts "="
34
34
  end
@@ -68,7 +68,7 @@ module Bio::DB::Primer3
68
68
  @primers_line_1 = SortedSet.new
69
69
  @primers_line_2 = SortedSet.new
70
70
  @regions = SortedSet.new
71
- @primer3_errors = Set.new
71
+ @primer3_errors = Set.new
72
72
  end
73
73
 
74
74
  def line_2_name
@@ -106,24 +106,23 @@ module Bio::DB::Primer3
106
106
  nil
107
107
  end
108
108
 
109
-
110
- def print_primers
111
- #TODO: Retrieve error messages
109
+ def values
110
+ return @values if @values
112
111
  left_start = 0
113
112
  left_end = 0
114
113
  right_start = 0
115
114
  right_end = 0
116
115
  total_columns_before_messages=17
117
- values = Array.new
118
- #values << "#{gene},,#{template_length},"
119
- values << gene
120
- values << "#{original}#{position}#{snp}"
121
- values << template_length
122
- values << snp_from.chromosome
123
- values << regions.size
124
- values << regions.join("|")
116
+ @values = Array.new
117
+ #@values << "#{gene},,#{template_length},"
118
+ @values << gene
119
+ @values << "#{original}#{position}#{snp}"
120
+ @values << template_length
121
+ @values << snp_from.chromosome
122
+ @values << regions.size
123
+ @values << regions.join("|")
125
124
  if primer3_line_1 and primer3_line_2
126
- values << primer3_line_1.polymorphism
125
+ @values << primer3_line_1.polymorphism
127
126
 
128
127
  #Block that searches both if both pairs have a TM
129
128
  primer_2 = primer3_line_2.left_primer_with_coordinates(primer3_line_1.left_coordinates, primer3_line_1.orientation)
@@ -133,27 +132,27 @@ module Bio::DB::Primer3
133
132
  # $stderr.puts primer_1
134
133
  # $stderr.puts primer_2
135
134
  if primer3_line_1 < primer3_line_2 and primer_2_tm != "NA"
136
- values << primer3_line_1.left_primer
137
- values << primer_2
138
- values << primer3_line_1.right_primer
139
- values << primer3_line_1.type.to_s
140
- values << primer3_line_1.orientation.to_s
141
- values << primer3_line_1.best_pair.left.tm
142
- values << primer_2_tm
143
- values << primer3_line_1.best_pair.right.tm
144
- values << "first"
145
- values << primer3_line_1.best_pair.product_size
135
+ @values << primer3_line_1.left_primer
136
+ @values << primer_2
137
+ @values << primer3_line_1.right_primer
138
+ @values << primer3_line_1.type.to_s
139
+ @values << primer3_line_1.orientation.to_s
140
+ @values << primer3_line_1.best_pair.left.tm
141
+ @values << primer_2_tm
142
+ @values << primer3_line_1.best_pair.right.tm
143
+ @values << "first"
144
+ @values << primer3_line_1.best_pair.product_size
146
145
  elsif primer_1_tm != "NA"
147
- values << primer_1
148
- values << primer3_line_2.left_primer
149
- values << primer3_line_2.right_primer
150
- values << primer3_line_2.type.to_s
151
- values << primer3_line_2.orientation.to_s
152
- values << primer_1_tm
153
- values << primer3_line_2.best_pair.left.tm
154
- values << primer3_line_2.best_pair.right.tm
155
- values << "second"
156
- values << primer3_line_2.best_pair.product_size
146
+ @values << primer_1
147
+ @values << primer3_line_2.left_primer
148
+ @values << primer3_line_2.right_primer
149
+ @values << primer3_line_2.type.to_s
150
+ @values << primer3_line_2.orientation.to_s
151
+ @values << primer_1_tm
152
+ @values << primer3_line_2.best_pair.left.tm
153
+ @values << primer3_line_2.best_pair.right.tm
154
+ @values << "second"
155
+ @values << primer3_line_2.best_pair.product_size
157
156
  else
158
157
 
159
158
  first_candidate = find_primer_pair_first
@@ -172,80 +171,99 @@ module Bio::DB::Primer3
172
171
 
173
172
  if first_candidate and second_candidate and first_candidate < second_candidate
174
173
  #puts "A"
175
- values << first_candidate.left_primer
176
- values << primer_2
177
- values << first_candidate.right_primer
178
- values << first_candidate.type.to_s
179
- values << first_candidate.orientation.to_s
180
- values << first_candidate.best_pair.left.tm
181
- values << primer_2_tm
182
- values << first_candidate.best_pair.right.tm
183
- values << "first"
184
- values << first_candidate.best_pair.product_size
174
+ @values << first_candidate.left_primer
175
+ @values << primer_2
176
+ @values << first_candidate.right_primer
177
+ @values << first_candidate.type.to_s
178
+ @values << first_candidate.orientation.to_s
179
+ @values << first_candidate.best_pair.left.tm
180
+ @values << primer_2_tm
181
+ @values << first_candidate.best_pair.right.tm
182
+ @values << "first"
183
+ @values << first_candidate.best_pair.product_size
185
184
  elsif second_candidate
186
185
  #puts "B"
187
- values << primer_1
188
- values << second_candidate.left_primer
189
- values << second_candidate.right_primer
190
- values << second_candidate.type.to_s
191
- values << second_candidate.orientation.to_s
192
- values << primer_1_tm
193
- values << second_candidate.best_pair.left.tm
194
- values << second_candidate.best_pair.right.tm
195
- values << "second"
196
- values << second_candidate.best_pair.product_size
186
+ @values << primer_1
187
+ @values << second_candidate.left_primer
188
+ @values << second_candidate.right_primer
189
+ @values << second_candidate.type.to_s
190
+ @values << second_candidate.orientation.to_s
191
+ @values << primer_1_tm
192
+ @values << second_candidate.best_pair.left.tm
193
+ @values << second_candidate.best_pair.right.tm
194
+ @values << "second"
195
+ @values << second_candidate.best_pair.product_size
197
196
  elsif first_candidate
198
197
  #puts "C"
199
- values << first_candidate.left_primer
200
- values << primer_2
201
- values << first_candidate.right_primer
202
- values << first_candidate.type.to_s
203
- values << first_candidate.orientation.to_s
204
- values << primer_2_tm
205
- values << first_candidate.best_pair.left.tm
206
- values << first_candidate.best_pair.right.tm
207
- values << "first"
208
- values << first_candidate.best_pair.product_size
209
- # else
210
- # values << ""
198
+ @values << first_candidate.left_primer
199
+ @values << primer_2
200
+ @values << first_candidate.right_primer
201
+ @values << first_candidate.type.to_s
202
+ @values << first_candidate.orientation.to_s
203
+ @values << primer_2_tm
204
+ @values << first_candidate.best_pair.left.tm
205
+ @values << first_candidate.best_pair.right.tm
206
+ @values << "first"
207
+ @values << first_candidate.best_pair.product_size
211
208
  end
212
-
213
209
  end
214
210
 
215
211
  elsif primer3_line_1
216
- values << primer3_line_1.polymorphism
217
- values << primer3_line_1.left_primer
218
- values << primer3_line_1.left_primer_snp(self)
219
- values << primer3_line_1.right_primer
220
- values << primer3_line_1.type.to_s
221
- values << primer3_line_1.orientation.to_s
222
- values << primer3_line_1.best_pair.left.tm
223
- values << "NA"
224
- values << primer3_line_1.best_pair.right.tm
225
-
226
- values << "first+"
227
- values << primer3_line_1.best_pair.product_size
212
+ @values << primer3_line_1.polymorphism
213
+ @values << primer3_line_1.left_primer
214
+ @values << primer3_line_1.left_primer_snp(self)
215
+ @values << primer3_line_1.right_primer
216
+ @values << primer3_line_1.type.to_s
217
+ @values << primer3_line_1.orientation.to_s
218
+ @values << primer3_line_1.best_pair.left.tm
219
+ @values << "NA"
220
+ @values << primer3_line_1.best_pair.right.tm
221
+
222
+ @values << "first+"
223
+ @values << primer3_line_1.best_pair.product_size
228
224
  elsif primer3_line_2
229
- values << primer3_line_2.polymorphism
230
- values << primer3_line_2.left_primer_snp(self)
231
- values << primer3_line_2.left_primer
232
- values << primer3_line_2.right_primer
233
- values << primer3_line_2.type.to_s
234
- values << primer3_line_2.orientation.to_s
235
- values << "NA"
236
- values << primer3_line_2.best_pair.left.tm
237
- values << primer3_line_2.best_pair.right.tm
238
- values << "second+"
239
- values << primer3_line_2.best_pair.product_size
225
+ @values << primer3_line_2.polymorphism
226
+ @values << primer3_line_2.left_primer_snp(self)
227
+ @values << primer3_line_2.left_primer
228
+ @values << primer3_line_2.right_primer
229
+ @values << primer3_line_2.type.to_s
230
+ @values << primer3_line_2.orientation.to_s
231
+ @values << "NA"
232
+ @values << primer3_line_2.best_pair.left.tm
233
+ @values << primer3_line_2.best_pair.right.tm
234
+ @values << "second+"
235
+ @values << primer3_line_2.best_pair.product_size
240
236
 
241
237
  end
242
- if values.size < total_columns_before_messages
243
- values[total_columns_before_messages] = primer3_errors.to_a.join("|")
238
+ if @values.size < total_columns_before_messages
239
+ @values[total_columns_before_messages] = primer3_errors.to_a.join("|")
244
240
  else
245
- values << nil
241
+ @values << nil
246
242
  end
243
+ return @values
244
+ end
245
+
246
+ def print_primers
247
+ self.values.join(",")
248
+ end
249
+
250
+ def found_primers?
251
+ return self.values[7] && self.values[7] != nil
252
+ end
253
+
254
+ def first_primer
255
+ return self.values[7] if self.values[7] && self.values[7] != nil
256
+ return ""
257
+ end
258
+
259
+ def second_primer
260
+ return self.values[8] if self.values[8] && self.values[8] != nil
261
+ return ""
262
+ end
247
263
 
248
- values.join(",")
264
+ def common_primer
265
+ return self.values[9] if self.values[9]&& self.values[9] != nil
266
+ return ""
249
267
  end
250
268
 
251
269
  def self.parse(reg_str)
@@ -273,10 +291,10 @@ module Bio::DB::Primer3
273
291
  def add_record(primer3record)
274
292
  @primer3_errors = Set.new unless @primer3_errors
275
293
  @template_length = primer3record.sequence_template.size
276
- if primer3record.primer_error != nil
277
- primer3_errors << primer3record.primer_error
278
- return
279
- end
294
+ if primer3record.primer_error != nil
295
+ primer3_errors << primer3record.primer_error
296
+ return
297
+ end
280
298
  case
281
299
 
282
300
  when primer3record.line == @line_1
@@ -451,7 +469,7 @@ module Bio::DB::Primer3
451
469
  @scores[:chromosome_semispecific] = 100
452
470
  @scores[:chromosome_nonspecific] = 0
453
471
  @scores[:exon] = 50
454
-
472
+
455
473
  end
456
474
 
457
475
  def snp
@@ -654,7 +672,7 @@ module Bio::DB::Primer3
654
672
 
655
673
  attr_accessor :line_1, :line_2
656
674
  attr_accessor :snp_hash
657
-
675
+
658
676
 
659
677
  def add_snp_file(filename)
660
678
  @snp_hash=Hash.new unless @snp_hash
@@ -696,6 +714,19 @@ module Bio::DB::Primer3
696
714
  end
697
715
  return str
698
716
  end
717
+
718
+ def print_primers_with_tails(tail_a: "GAAGGTCGGAGTCAACGGATT", tail_b: "GAAGGTGACCAAGTTCATGCT")
719
+ str = ""
720
+ snp_hash.each do |k, snp|
721
+ if snp.found_primers?
722
+ str << snp.gene << snp.original << "\t" << tail_a << snp.first_primer << "\n"
723
+ str << snp.gene << snp.snp << "\t" << tail_b << snp.second_primer << "\n"
724
+ str << snp.gene << "\t" << snp.common_primer << "\n"
725
+ end
726
+ end
727
+ return str
728
+ end
729
+
699
730
  end
700
731
  end
701
732