text: import os
  import time
  import multiprocessing as mp
  from PIL import Image, ImageDraw, ImageColor, ImageOps, ImageFont
  from pyfaidx import Fasta
  from zipfile import ZipFile
  from .drawreadset import DrawReadSet, CoveragePlot, CoverageHeatmap
  from .coordinates import COORDINATES
  from .geneplot import GenePlot
  from .basetrack import BaseTrack
  from .scale import Xscale
  from .bam import BAM
  from .util import get_url, getTemplatePath, fileOpen, fileSave, check_dir, getrgb, get_scale, is_exist, renderTemplate
  from .conf import COLOR, IMAGE_MARGIN_BOTTOM
  
  
  class BamSnap():
  
      def __init__(self, opt):
          self.opt = opt
          self.bamlist = []
          self.has_opt_error = False
          self.split_poslist = self.get_split_poslist(self.opt['poslist'], self.opt['process'])
          self.process = {}
          self.is_single_image_out = False
          self.set_is_single_image_out()
  
      def set_is_single_image_out(self):
          flag = False
          if len(self.opt['poslist']) == 1:
              if not self.opt['separated_bam']:
                  flag = True
              else:
                  fnameuppper = self.opt['out'].upper()
                  if fnameuppper.endswith('.PNG') or fnameuppper.endswith('.JPG'):
                      flag = True
          self.is_single_image_out = flag
  
      def get_split_poslist(self, poslist, no_process):
          split_poslist = {}
          icore = 0
          for pos1 in poslist:
              try:
                  split_poslist[icore].append(pos1)
              except KeyError:
                  split_poslist[icore] = [pos1]
              icore += 1
              if icore >= no_process:
                  icore = 0
          return split_poslist
  
      def load_bamlist(self):
          ks = self.opt.keys()
          if 'bamlist' in ks and self.opt['bamlist'] is not None:
              for line in open(self.opt['bamlist']):
                  line = line.strip()
                  if len(line) > 0 and line[0] != '#':
                      arr = line.split('\t')
                      if len(arr) == 2:
                          bamObj = BAM(arr[0], arr[1])
                          if 'ref' in self.opt:
                              bamObj.setReference(self.opt['ref'])
                          self.bamlist.append(bamObj)
                      else:
                          bamObj = BAM(arr[0])
                          if 'ref' in self.opt:
                              bamObj.setReference(self.opt['ref'])
                          self.bamlist.append(bamObj)
          elif 'bam' in ks and len(self.opt['bam']) > 0:
              for idx, bamfile in enumerate(self.opt['bam']):
                  try:
                      title = self.opt['title'][idx]
                  except IndexError:
                      title = ""
                  bamObj = BAM(bamfile, title)
                  if 'ref' in self.opt:
                      bamObj.setReference(self.opt['ref'])
                  self.bamlist.append(bamObj)
  
      def start_process_drawplot(self, image_w, bamlist):
          for tno in range(self.opt['process']):
              self.process[tno] = mp.Process(target=run_process_drawplot_bamlist, args=(
                  image_w, bamlist, self.split_poslist[tno], self.opt, self.is_single_image_out), name='proc ' + str(tno+1))
              self.process[tno].start()
  
      def save_html(self):
  
          check_dir(os.path.join(self.opt['out'], 'css', 'aa'))
          check_dir(os.path.join(self.opt['out'], 'js', 'aa'))
          check_dir(os.path.join(self.opt['out'], 'sample_list', 'aa'))
          check_dir(os.path.join(self.opt['out'], 'variant_list', 'aa'))
          renderTemplate('bootstrap.min.css', os.path.join(self.opt['out'], 'css', 'bootstrap.min.css'), {})
          renderTemplate('bootstrap.min.css.map', os.path.join(self.opt['out'], 'css', 'bootstrap.min.css.map'), {})
          renderTemplate('bootstrap.bundle.min.js', os.path.join(self.opt['out'], 'css', 'bootstrap.bundle.min.js'), {})
          renderTemplate('bootstrap.bundle.min.js.map', os.path.join(
              self.opt['out'], 'css', 'bootstrap.bundle.min.js.map'), {})
          renderTemplate('bamsnap_index.html', os.path.join(self.opt['out'], 'index.html'), {})
  
          self.save_sample_list()
          self.save_variant_list()
          self.opt['log'].info('Saved '+os.path.join(self.opt['out'], 'index.html'))
  
      def save_sample_list(self):
          d = {}
  
          # d['COLHEADER'] = "<th>SID</th><th>Het</th><th>Hom</th><th>All</th>"
          d['COLHEADER'] = "<th>SID</th>"
          h = ""
          for bam in self.bamlist:
              htmlfile = './sample_list/' + bam.title2 + '.html'
  
              d2 = {'SID': bam.title}
              all_tab = ""
              img_list = ""
              for pos1 in self.opt['poslist']:
                  vid = pos1['chrom'] + ':' + str(pos1['t_pos'])
                  vid2 = pos1['chrom'] + '_' + str(pos1['t_pos'])
                  all_tab += '<li class="nav-item"><a class="nav-link cl" mid="' + vid2 + '" href="#' + vid2 + \
                      '"><span data-feather="file-text"></span>'+pos1['chrom']+':'+str(pos1['t_pos'])+'</a></li>'
                  # h3 += '<a name="'+t1+'"></a><div class="ic" id="s20_63231_T_G"><div class="text-block"><span class="it">'+t1+'</span><span class="badge badge-secondary gt">GT 0|0</span><span class="badge badge-secondary gt">DP 3</span></div><img src="./HG01468/20:63231.png" alt="'+t1+'" style="width:100%;"></div>'
                  img_list += '<a name="'+vid2+'"></a><div class="ic" id="s'+vid2+'"><div class="text-block"><span class="it">'+vid + \
                      '</span></div><img src="../bamsnap_images/' + \
                      bam.title.replace(' ', '_')+'_'+vid+'.png" alt="'+vid+'" style="width:100%;"></div>'
              d2['ALL'] = all_tab
              d2['IMGLIST'] = img_list
              d2['ALL_TOTAL'] = str(len(self.opt['poslist']))
              renderTemplate('sample_temp.html', os.path.join(self.opt['out'], 'sample_list', bam.title2 + '.html'), d2)
  
              h += '<tr class=cl>'
              h += '<td><a href="' + htmlfile + '" target="body">' + bam.title + '</a></td>'
              # h += '<td><a href="' + htmlfile + '" target="body">' + str(pos1['t_pos']) + '</a></td>'
              h += '</tr>'
          d['SAMPLE_LIST'] = h
          renderTemplate('sample_list.html', os.path.join(self.opt['out'], 'sample_list.html'), d)
  
      def save_variant_list(self):
  
          h = ""
          for pos1 in self.opt['poslist']:
              htmlfile = './variant_list/' + pos1['chrom'] + '_' + str(pos1['t_pos']) + '.html'
              vid = pos1['chrom'] + ':' + str(pos1['t_pos'])
              d2 = {'VID': vid}
  
              all_tab = ""
              img_list = ""
              for bam in self.bamlist:
                  sid = bam.title
                  sid2 = bam.title.replace(' ', '_')
                  # all_tab += '<li class="nav-item"><a class="nav-link cl" mid="'+sid+'" href="#'+sid+'"><span data-feather="file-text"></span>'+sid+' 0|1 53</a></li>'
                  all_tab += '<li class="nav-item"><a class="nav-link cl" mid="'+sid + '" href="#'+sid+'">'
                  all_tab += '<span data-feather="file-text"></span>'+sid+'</a></li>'
                  # img_list += '<a name="'+sid+'"></a><div class="ic" id="s'+sid+'"><div class="text-block"><span class="it">'+sid+'</span><span class="badge badge-warning gt">GT 0|1</span><span class="badge badge-warning gt">DP 53</span></div><img src="../bamsnap_images/'+sid2+'_'+vid+'.png" alt="'+sid+'" style="width:100%;"></div>'
                  img_list += '<a name="'+sid+'"></a><div class="ic" id="s'+sid+'"><div class="text-block"><span class="it">' + \
                      sid+'</span></div><img src="../bamsnap_images/'+sid2+'_'+vid+'.png" alt="'+sid+'" style="width:100%;"></div>'
  
              d2['ALL'] = all_tab
              d2['IMGLIST'] = img_list
              d2['ALL_TOTAL'] = str(len(self.bamlist))
              renderTemplate('variant_temp.html', os.path.join(
                  self.opt['out'], 'variant_list', pos1['chrom'] + '_' + str(pos1['t_pos']) + '.html'), d2)
  
              h += '<tr class=cl>'
              h += '<td><a href="' + htmlfile + '" target="body">' + pos1['chrom'] + '</a></td>'
              h += '<td><a href="' + htmlfile + '" target="body">' + str(pos1['t_pos']) + '</a></td>'
              h += '</tr>'
  
          d = {}
          # d['COLHEADER'] = "<th>CHROM</th><th>POS</th><th>ID</th><th>REF</th><th>ALT</th>"
          d['COLHEADER'] = "<th>CHROM</th><th>POS</th>"
          d['VARIANT_LIST'] = h
          renderTemplate('variant_list.html', os.path.join(self.opt['out'], 'variant_list.html'), d)
  
      def get_outfnamelist(self):
          outfnamelist = []
          for pos1 in self.opt['poslist']:
              if self.opt['separated_bam']:
                  for bam in self.bamlist:
                      metainfo = get_out_file_metainfo(bam, pos1, self.opt, self.is_single_image_out)
                      outfnamelist.append(metainfo)
              else:
                  metainfo = get_out_file_metainfo(self.bamlist, pos1, self.opt, self.is_single_image_out)
                  outfnamelist.append(metainfo)
          return outfnamelist
  
      def generate_zipfile(self):
          outzip = self.opt['out'] + '.zip'
          zo = ZipFile(outzip, 'w')
          for folderName, subfolders, filenames in os.walk(self.opt['out']):
              for filename in filenames:
                  filePath = os.path.join(folderName, filename)
                  zo.write(filePath, filePath)
          zo.close()
          self.opt['log'].info("(" + mp.current_process().name + ") Saved " + outzip)
  
      def run(self):
          t0 = time.time()
          timemap = {'set_refseq': 0}
          self.load_bamlist()
  
          if not self.has_opt_error and len(self.opt['poslist']) > 0:
              image_w = self.opt['width'] - self.opt['plot_margin_left'] - self.opt['plot_margin_right']
  
              if self.opt['separated_bam']:
                  for bam in self.bamlist:
                      self.start_process_drawplot(image_w, [bam])
              else:
                  self.start_process_drawplot(image_w, self.bamlist)
  
          t2 = time.time()
          if not self.is_single_image_out:
              if not self.opt['save_image_only']:
                  self.save_html()
              if self.opt['zipout']:
                  self.generate_zipfile()
  
          self.opt['log'].debug('Total running time for getting reference sequence (set_refseq): ' +
                                str(round(timemap['set_refseq'], 3))+' sec')
          self.opt['log'].info('Total running time: ' + str(round(t2-t0, 1))+' sec')
  
  
  def run_process_drawplot_bamlist(image_w, bamlist, poslist, opt, is_single_image_out):
      rseq = ReferenceSequence(opt)
      bsplot = BamSnapPlot(opt)
      bsplot.set_is_single_image_out(is_single_image_out)
      for pos1 in poslist:
          t11 = time.time()
          refseq = rseq.get_refseq(pos1)
          xscale = Xscale(pos1['g_spos'], pos1['g_epos'], image_w)
          imagefname = bsplot.drawplot_bamlist(pos1, image_w, bamlist, xscale, refseq)
          t12 = time.time()
          opt['log'].info("(" + mp.current_process().name + ") Saved " +
                          imagefname + " : " + str(round(t12-t11, 5)) + " sec")
  
  
  def get_out_file_metainfo(bam, pos1, opt, is_single_image_out):
      meta = {'imgtitle': "", 'outfname': ""}
      imgtitle = ""
      if is_single_image_out:
          outfname = opt['out']
          imgtitle = outfname
          u = outfname.upper()
          if not (u.endswith('.JPG') or u.endswith('.JPEG') or u.endswith('.PNG')):
              outfname += '.' + opt['imagetype']
      else:
          if opt['save_image_only']:
              path = os.path.join(opt['out'])
          else:
              path = os.path.join(opt['out'], opt['image_dir_name'])
  
          bamtitle = bam.title.replace(' ', '_').replace('#', '_')
  
          if opt['separated_bam']:
              imgtitle = bamtitle + '_'
  
          if 't_pos' in pos1:
              imgtitle += pos1['chrom'] + ':' + str(pos1['t_pos'])
          else:
              imgtitle += pos1['chrom'] + ':' + str(pos1['t_spos']) + '-' + str(pos1['t_epos'])
  
          outfname = os.path.join(path, imgtitle) + '.' + opt['imagetype']
  
      meta['imgtitle'] = imgtitle
      meta['outfname'] = outfname
      return meta
  
  
  class BamSnapPlot():
      def __init__(self, opt):
          self.opt = opt
          self.font = {}
          self.drawplot = self.opt['draw']
          self.bamplot = self.opt['bamplot']
          self.is_single_image_out = False
  
      def set_is_single_image_out(self, is_single_image_out):
          self.is_single_image_out = is_single_image_out
  
      def init_image(self, image_w, bgcolor="FFFFFF"):
          ia = Image.new('RGB', (image_w, 0), getrgb(bgcolor))
          return ia
  
      def get_font(self, font_size, font_type='regular'):
          try:
              font = self.font[font_size]
          except KeyError:
              if font_type == 'bold':
                  font = ImageFont.truetype(getTemplatePath('VeraMono-Bold.ttf'), font_size)
              else:
                  font = ImageFont.truetype(getTemplatePath('VeraMono.ttf'), font_size)
              self.font[font_size] = font
          return font
  
      def add_margin_to_image(self, ia, margin_left=0, margin_top=0, margin_right=0, margin_bottom=0):
          if max(margin_left, margin_top, margin_right, margin_bottom) > 0:
              ia = ImageOps.expand(ia, (margin_left, margin_top, margin_right,
                                        margin_bottom), fill=getrgb(self.opt['bgcolor']))
          return ia
  
      def save_image(self, ia, bam, pos1):
          outfile_metainfo = get_out_file_metainfo(bam, pos1, self.opt, self.is_single_image_out)
          check_dir(outfile_metainfo['outfname'])
  
          if self.opt['imagetype'] == "jpg":
              ia = ia.convert("RGB")
              ia.save(outfile_metainfo['outfname'], "JPEG", quality=100, optimize=True)
          else:
              ia.save(outfile_metainfo['outfname'], "PNG", quality=1, optimize=True)
  
          self.opt['log'].info("(" + mp.current_process().name + ") Saved " + outfile_metainfo['outfname'])
          return outfile_metainfo['outfname']
  
      def get_title_image(self, title, w, fontsize):
          margin = 10
          font = self.get_font(fontsize, 'bold')
          fontsize = font.getsize(title)
          h = fontsize[1] + 3 + margin * 2
          im = Image.new('RGB', (w, h), getrgb(self.opt['bgcolor']))
          dr = ImageDraw.Draw(im)
  
          if self.opt['border']:
              h1 = int(h/2)
              dr.line([(0, h1), (w, h1)], fill=getrgb('000000'), width=1)
  
          # dr.rectangle([(margin, margin - 1 ),(margin * 3 + fontsize[0], margin + fontsize[1] + 1)], fill=(255,255,255,255), outline=(120,120,120,255))
          dr.rectangle([(margin, margin - 1), (margin * 3 + fontsize[0], margin + fontsize[1] + 1)],
                       fill=(255, 255, 255, 255), outline=(255, 255, 255, 255))
          dr.text((margin * 2, margin), title, font=font, fill=COLOR['LABEL'])
          return im, h
  
      def append_image(self, ia, ia_sub):
          offset_top = ia.height
          ia = ImageOps.expand(ia, (0, 0, 0, ia_sub.height), fill=getrgb(self.opt['bgcolor']))
          ia.paste(ia_sub, (0, offset_top))
          return ia
  
      def get_image_seperator(self, w, h):
          im = Image.new('RGB', (w, h), getrgb(self.opt['bgcolor']))
          dr = ImageDraw.Draw(im)
          h1 = int(h/2)
          dr.line([(0, h1), (w, h1)], fill=getrgb('000000'), width=1)
          return im
  
      def get_bamplot_image(self, bam, pos1, image_w, xscale, refseq):
          rset = DrawReadSet(bam, pos1['chrom'], pos1['g_spos'], pos1['g_epos'], xscale, refseq)
          rset.read_gap_w = self.opt['read_gap_width']
          rset.read_gap_h = self.opt['read_gap_height']
          rset.read_thickness = self.opt['read_thickness']
          rset.coverage_vaf = self.opt['coverage_vaf']
          rset.opt = self.opt
          rset.xscale = xscale
          rset.calculate_readmap(is_strand_group=True)
  
          im = self.init_image(image_w, self.opt['bgcolor'])
          border_top = 0
          if not self.opt['no_title']:
              ia_sub, title_height = self.get_title_image(bam.title, image_w, self.opt['title_fontsize'])
              border_top = im.height + int(title_height/2)
              im = self.append_image(im, ia_sub)
  
          for pidx, plot1 in enumerate(self.bamplot):
              if plot1 == "heatmap":
                  covhmplot = CoverageHeatmap(rset, xscale)
                  covhmplot.font = self.get_font(self.opt['coverage_fontsize'])
                  ia_sub = covhmplot.get_image(image_w, self.opt['heatmap_height'], self.opt['heatmap_bgcolor'])
                  im = self.append_image(im, ia_sub)
  
              if plot1 == "coverage":
                  covplot = CoveragePlot(rset, xscale, self.opt['coverage_vaf'])
                  covplot.coverage_color = self.opt['coverage_color']
                  covplot.font = self.get_font(self.opt['coverage_fontsize'])
                  ia_sub = covplot.get_image(image_w, self.opt['coverage_height'], self.opt['coverage_bgcolor'])
                  im = self.append_image(im, ia_sub)
  
              if plot1 == "read":
                  if self.opt['read_group'] == "":
                      h_all = rset.get_estimated_height('all')
                      ia_sub = rset.get_image(
                          image_w, h_all, 'all', self.opt['read_color'], self.opt['read_bgcolor'], self.opt['read_color_by'])
                      im = self.append_image(im, ia_sub)
  
                  elif self.opt['read_group'] == "strand":
                      # self.opt['read_bgcolor'] = "F0F000"
                      h_pos = rset.get_estimated_height('pos_strand')
                      ia_sub = rset.get_image(image_w, h_pos, 'pos_strand',
                                              self.opt['read_pos_color'], self.opt['read_bgcolor'], self.opt['read_color_by'])
                      im = self.append_image(im, ia_sub)
  
                      # self.opt['read_bgcolor'] = "00F0F0"
                      h_neg = rset.get_estimated_height('neg_strand')
                      ia_sub = rset.get_image(image_w, h_neg, 'neg_strand',
                                              self.opt['read_neg_color'], self.opt['read_bgcolor'], self.opt['read_color_by'])
                      im = self.append_image(im, ia_sub)
  
              if plot1 == "coordinates":
                  im = self.append_coordinates_image(im, pos1, image_w, xscale)
  
              if plot1 == "gene":
                  im = self.append_geneplot_image(im, pos1, image_w, xscale)
  
              if plot1 == "base":
                  im = self.append_baseplot_image(im, pos1, image_w, xscale, refseq)
  
          if self.opt['border']:
              padding_bottom = 15
              margin_top = 25
              margin_bottom = 10
              im = self.add_margin_to_image(im, 0, margin_top, 0, margin_bottom+padding_bottom)
  
              dr = ImageDraw.Draw(im)
              dr.line([(0, border_top + margin_top), (0, im.height-1-margin_bottom)], fill=getrgb('000000'), width=1)
              dr.line([(im.width-1, border_top + margin_top), (im.width-1,
                                                               im.height-1-margin_bottom)], fill=getrgb('000000'), width=1)
              dr.line([(0, im.height-1-margin_bottom), (im.width-1, im.height-1-margin_bottom)], fill=getrgb('000000'), width=1)
  
          return im
  
      def append_coordinates_image(self, ia, pos1, image_w, xscale):
          coord = COORDINATES(pos1['chrom'], pos1['g_spos'], pos1['g_epos'], xscale,
                              image_w, self.opt['coordinates_height'], self.opt['debug'])
          coord.font = self.get_font(self.opt['coordinates_fontsize'])
          coord.axisloc = self.opt['coordinates_axisloc']
          coord.bgcolor = self.opt['coordinates_bgcolor']
          coord.labelcolor = self.opt['coordinates_labelcolor']
          ia_sub = coord.get_image()
          ia = self.append_image(ia, ia_sub)
          return ia
  
      def append_geneplot_image(self, ia, pos1, image_w, xscale):
          geneplot = GenePlot(pos1['chrom'], pos1['g_spos'], pos1['g_epos'], xscale,
                              image_w, self.opt['refversion'], show_transcript=True)
          geneplot.font = self.get_font(self.opt['gene_fontsize'])
          geneplot.gene_pos_color = self.opt['gene_pos_color']
          geneplot.gene_neg_color = self.opt['gene_neg_color']
          ia_sub = geneplot.get_image()
          ia = self.append_image(ia, ia_sub)
          return ia
  
      def append_baseplot_image(self, ia, pos1, image_w, xscale, refseq):
          baseplot = BaseTrack(pos1['chrom'], pos1['g_spos'], pos1['g_epos'], refseq, xscale, image_w)
          baseplot.font = self.get_font(self.opt['base_fontsize'])
          ia_sub = baseplot.get_image(self.opt['base_margin_top'], self.opt['base_margin_bottom'])
          ia = self.append_image(ia, ia_sub)
          return ia
  
      # def generate_zipfile(self):
      #     outzip = self.opt['out'] + '.zip'
      #     zo = ZipFile(outzip, 'w')
      #     for folderName, subfolders, filenames in os.walk(self.opt['out']):
      #         for filename in filenames:
      #             filePath = os.path.join(folderName, filename)
      #             zo.write(filePath, filePath)
      #     zo.close()
      #     self.opt['log'].info("(" + mp.current_process().name + ") Saved " + outzip)
  
      def drawplot_bamlist(self, pos1, image_w, bamlist, xscale, refseq):
          ia = self.init_image(image_w, self.opt['bgcolor'])
          drawA = None
  
          for pidx, plot1 in enumerate(self.drawplot):
              if plot1 == "coordinates":
                  ia = self.append_coordinates_image(ia, pos1, image_w, xscale)
  
              if plot1 == "bamplot":
                  for bidx, bam in enumerate(bamlist):
                      if (bidx + 1) % 10 == 0:
                          self.opt['log'].info("..processing " + bam.filename + " (" + str(bidx + 1) + ")")
                      ia_sub = self.get_bamplot_image(bam, pos1, image_w, xscale, refseq)
                      ia = self.append_image(ia, ia_sub)
  
                      if not self.opt['border'] and self.opt['separator_height'] > 0:
                          ia_sub = self.get_image_seperator(image_w, self.opt['separator_height'])
                          ia = self.append_image(ia, ia_sub)
  
              if plot1 == "gene":
                  ia = self.append_geneplot_image(ia, pos1, image_w, xscale)
  
              if plot1 == "base":
                  ia = self.append_baseplot_image(ia, pos1, image_w, xscale, refseq)
  
          if self.opt['grid'] > 0:
              drawA = ImageDraw.Draw(ia)
              for posi in range(pos1['g_spos'], pos1['g_epos'] + 1, self.opt['grid']):
                  x1 = xscale.xmap[posi]['spos'] - 1
                  drawA.line([(x1, 0), (x1, ia.height)], fill=COLOR['GRID_COLOR'], width=1)
  
          if self.opt['center_line']:
              drawA = ImageDraw.Draw(ia)
              x1 = ((self.opt['g_epos']-self.opt['g_spos'])/2)*self.scale_x
              for h1 in range(0, ia.height, 7):
                  drawA.line([(x1, h1), (x1, h1+2)], fill=COLOR['CENTER_LINE'], width=1)
  
          if not self.opt['no_target_line']:
              drawA = ImageDraw.Draw(ia)
              x1 = xscale.xmap[pos1['t_spos']]['spos']
              x2 = xscale.xmap[pos1['t_epos']]['spos']
              for h1 in range(0, ia.height, 7):
                  drawA.line([(x1, h1), (x1, h1+2)], fill=COLOR['CENTER_LINE'], width=1)
                  drawA.line([(x2, h1), (x2, h1+2)], fill=COLOR['CENTER_LINE'], width=1)
  
              if self.opt['debug']:
                  for xi in range(pos1['g_spos'], pos1['g_epos']+1):
                      x1 = xscale.xmap[xi]['spos']
                      drawA.line([(x1, 20), (x1, ia.height)], fill=(0, 0, 0, 255), width=1)
                  drawA.line([(int(image_w/2), 0), (int(image_w/2), ia.height)], fill=(255, 0, 0, 255), width=1)
  
          if 'highlight' in self.opt.keys():
              drawA = ImageDraw.Draw(ia)
              for h1 in self.opt['highlight'].split(','):
                  arr = h1.split(':')
                  arr2 = arr[1].split('-')
                  t_spos = int(arr2[0])
                  t_epos = int(arr2[1])
                  x1 = (t_spos-self.opt['g_spos'])*self.scale_x - 4
                  x2 = (t_epos-self.opt['g_spos'])*self.scale_x - 2
                  for h1 in range(0, ia.height, 7):
                      drawA.line([(x1, h1), (x1, h1+2)], fill=COLOR['CENTER_LINE'], width=1)
                      drawA.line([(x2, h1), (x2, h1+2)], fill=COLOR['CENTER_LINE'], width=1)
  
          ia = self.add_margin_to_image(ia, self.opt['plot_margin_left'], self.opt['plot_margin_top'],
                                        self.opt['plot_margin_right'], self.opt['plot_margin_bottom'])
          imagefname = self.save_image(ia, bamlist[0], pos1)
          return imagefname
  
  
  class ReferenceSequence():
      def __init__(self, opt):
          self.opt = opt
          self.fasta = None
          if is_exist(self.opt['ref']):
              self.fasta = Fasta(self.opt['ref'], rebuild=False)
  
      def get_refseq(self, pos1):
          refseq = {}
          if self.opt['ref'] == "":
              refseq = self.get_refseq_from_ucsc(pos1)
          else:
              refseq = self.get_refseq_from_localfasta(pos1)
          return refseq
  
      # def set_refseq_from_ncbiapi(self):
      #     url = "http://www.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide"
      #     url += "&id=NC_000001&seq_start=97533596&seq_stop=97533606&rettype=fasta&retmode=text"
      #     cont = get_url(url)
      #     seq = ""
      #     for line in cont.strip().split('\n'):
      #         if line[0] != '>':
      #             seq += line.strip()
      #     print ('seq:',seq)
      #     i = 0
      #     for gpos in range(self.opt['g_spos']-1000,self.opt['g_epos']+1000+1):
      #         self.refseq[gpos] = seq[i]
      #         i += 1
  
      def get_refseq_from_ucsc(self, pos1):
          spos = pos1['g_spos']-self.opt['margin'] - 500
          epos = pos1['g_epos']+self.opt['margin'] + 1 + 500
          # seqver = "hg38"
          seqver = self.opt['refversion']
          if not pos1['chrom'].startswith('chr'):
              chrom = 'chr' + pos1['chrom']
          else:
              chrom = pos1['chrom']
          url = "http://genome.ucsc.edu/cgi-bin/das/" + seqver + \
              "/dna?segment=" + chrom + ":" + str(spos) + "," + str(epos)
          # url = "http://genome.ucsc.edu/cgi-bin/das/" + seqver + \
          #     "/dna?segment=chr"+pos1['chrom']+":"+str(spos+1)+","+str(epos+1)
          cont = get_url(url)
          seq = ""
          for line in cont.strip().split('\n'):
              if line[0] != '<':
                  seq += line.strip().upper()
          i = 0
          refseq = {}
          for gpos in range(spos, epos):
              refseq[gpos] = seq[i]
              i += 1
          return refseq
  
      def get_refseq_from_localfasta(self, pos1):
          spos = pos1['g_spos']-self.opt['margin'] - 500
          epos = pos1['g_epos']+self.opt['margin'] + 1 + 500
          seq = self.get_refseq_from_fasta(pos1['chrom'], spos, epos, self.opt['ref_index_rebuild'])
          i = 0
          refseq = {}
          for gpos in range(spos, epos):
              if i >= len(seq) or gpos < 0:
                  refseq[gpos+1] = "_"
              else:
                  refseq[gpos+1] = seq[i]
                  i += 1
          return refseq
  
      def get_refseq_from_fasta(self, chrom, spos, epos, rebuild_index=False):
          f = self.fasta
          fastachrommap = {}
          for c1 in list(f.keys()):
              arr = c1.split(' ')
              tchrom = arr[0]
              fastachrommap[tchrom] = c1
          refseq = f[fastachrommap[chrom]][max(0,spos):epos+1]
          return str(refseq)
  