#!/usr/bin/env ruby require 'open3' require 'tempfile' module Qu module Cmdwrapper BIN_ROOT = File.join(__dir__, 'ext_bin') BIN_PATH = File.join(BIN_ROOT, Utils::platform_os, Utils::platform_bit.to_s) THERMO_PATH = File.join(__dir__, 'primer3_config') + '/' module_function def primer3_core(p3_input_file) begin cmd = File.join(BIN_PATH, 'primer3_core') begin return system_quietly("#{cmd} #{File.realpath(p3_input_file)}") rescue ShellError return '' end rescue IOError $stderr.puts "Primer3 input file not exists: #{p3_input_file}" exit end end def ntthal(s1, s2=nil, mv=50, dv=1.5, d=50, n=0.25, mode='ANY') cmd = File.join(BIN_PATH, 'ntthal') if s2 tm = `#{cmd} -mv #{mv} -dv #{dv} -d #{d} -n #{n} -s1 #{s1} -s2 #{s2} -r -path #{THERMO_PATH} -a #{mode}` else tm = `#{cmd} -mv #{mv} -dv #{dv} -d #{d} -n #{n} -s1 #{s1} -r -path #{THERMO_PATH} -a HAIRPIN` end return tm.to_f end def faToTwoBit(fasta, twobit) cmd = File.join(BIN_PATH, 'faToTwoBit') `#{cmd} #{fasta} #{twobit}` end def twoBitToFa(seq_list_file, twobit_file) cmd = File.join(BIN_PATH, 'twoBitToFa') records = [] begin out_file = Tempfile.new('twobit') `#{cmd} -seqList=#{seq_list_file} #{twobit_file} #{out_file.path}` out_file.rewind Bio::FlatFile.new(Bio::FastaFormat, out_file).each do |record| records << record.naseq.seq end ensure out_file.close out_file.unlink end return records end def get_binding_seq_list(binding_range_list, twobit_file) amp_seq_list = [] return amp_seq_list if binding_range_list.empty? begin fh = Tempfile.new('binding_range_list') fh.write(binding_range_list.join("\n")) fh.close amp_seq_list = twoBitToFa(fh.path, twobit_file) ensure fh.unlink end return amp_seq_list end class ShellError < StandardError; end def system_quietly(*cmd) exit_status=nil err=nil out=nil Open3.popen3(*cmd) do |stdin, stdout, stderr, wait_thread| err = stderr.gets(nil) out = stdout.gets(nil) [stdin, stdout, stderr].each{|stream| stream.send('close')} exit_status = wait_thread.value end if exit_status.to_i > 0 err = err.chomp if err raise ShellError, err elsif out return out.chomp else return true end end end end if $0 == __FILE__ puts Qu::Cmdwrapper::BIN_PATH end