text: #! /usr/bin/env python3
  # Convert a .model file into a .inl file that can be directly compiled into nanopolish
  
  
  import argparse
  
  def assign(name, value):
      assert(len(name) > 0)
      assert(value is not None)
      print("\ttmp.%s = %s;" % (name, value))
  
  def quote(value):
      assert(len(value) > 0)
      return "\"" + value + "\""
  
  parser = argparse.ArgumentParser( description='Rewrite a .model file into a file that can be directly compiled into nanopolish')
  parser.add_argument('-i', '--input', type=str, required=True)
  parser.add_argument('-f', '--function-name', type=str, required=True)
  args = parser.parse_args()
  
  f = open(args.input)
  K = 0
  model = list()
  header_kv = dict()
  bases = dict()
  
  for line in f:
      line = line.rstrip()
      fields = line.split()
  
      # check if this is a header line
      if line[0] == '#' or line.find("kmer") == 0:
          if fields[0] != "kmer":
              key = fields[0][1:]
              value = fields[1]
              header_kv[key] = value
      else:
          # check if this is the first non-header line seen
          if K == 0:
              K = len(fields[0])
          else:
              assert len(fields[0]) == K
          model.append(tuple(fields))
          for b in fields[0]:
              bases[b] = 1
  
  # Preamble
  print("// Autogenerated by convert_model_to_header.py")
  print("#ifndef NANOPOLISH_%s_INL" % args.function_name.upper())
  print("#define NANOPOLISH_%s_INL" % args.function_name.upper())
  
  data_name = "%s_data" % args.function_name
  print("static std::vector<double> %s = {" % data_name)
  for ki, t in enumerate(model):
  
      is_last = ki == len(model) - 1
      sep = ',' if not is_last else ''
  
      print("\t\t%.5f, %.5f, %.5f, %.5f%s // %s" % (float(t[1]), float(t[2]), float(t[3]), float(t[4]), sep, t[0]))
  print("};")
  
  print("PoreModel %s()\n{" % args.function_name)
  print("\tPoreModel tmp;")
  # Output metadata
  assign("model_filename", quote(args.input))
  assign("k", K)
  
  num_states = len(model)
  
  print("\ttmp.states.resize(%d);" % num_states)
  print("\tfor(size_t i = 0; i < %d; ++i) {" % num_states)
  print("\t\ttmp.states[i].level_mean = %s[4*i + 0];" % data_name)
  print("\t\ttmp.states[i].level_stdv = %s[4*i + 1];" % data_name)
  print("\t\ttmp.states[i].sd_mean = %s[4*i + 2];" % data_name)
  print("\t\ttmp.states[i].sd_stdv = %s[4*i + 3];" % data_name)
  print("\t\ttmp.states[i].update_sd_lambda();")
  print("\t\ttmp.states[i].update_logs();")
  print("\t}")
  
  if "alphabet" in header_kv:
      print("\ttmp.pmalphabet = get_alphabet_by_name(%s);" % (quote(header_kv["alphabet"])))
  else:
      print("\ttmp.pmalphabet = best_alphabet(%s);" % (quote("".join(bases))))
  
  print("\ttmp.set_metadata(%s, %s);" % (quote(header_kv["kit"]), quote(header_kv["strand"])))
  print("\treturn tmp;\n}")
  print("#endif")
  