Beispiel #1
0
    # BART configuration file:
    shutil.copy2(cfile, date_dir)
    # TEP file:
    if not os.path.isfile(tep_name):
        mu.error("Tepfile ('{:s}') Not found.".format(tep_name))
    else:
        shutil.copy2(tep_name, date_dir + os.path.basename(tep_name))

    # Check if files already exist:
    runMCMC = 0  # Flag that indicate which steps to run
    # Atmospheric file:
    if os.path.isfile(atmfile):
        atmfile = os.path.realpath(atmfile)
        shutil.copy2(atmfile, date_dir + os.path.basename(atmfile))
        mu.msg(1,
               "Atmospheric file copied from: '{:s}'.".format(atmfile),
               indent=2)
        runMCMC |= 8
    # Pre-atmospheric file:
    if os.path.isfile(preatm_file):
        preatm_file = os.path.realpath(preatm_file)
        shutil.copy2(preatm_file, date_dir + os.path.basename(preatm_file))
        mu.msg(1,
               "Pre-atmospheric file copied from: '{:s}'.".format(preatm_file),
               indent=2)
        runMCMC |= 4
    # Elemental-abundances file:
    if abun_file is not None and os.path.isfile(abun_file):
        shutil.copy2(abun_file, date_dir + os.path.basename(abun_file))
        mu.msg(
            1,
Beispiel #2
0
def main():
    """
  One function to run them all.
  """

    mu.msg(
        1,
        "\n======= Bayesian Atmospheric Radiative Transfer (BART) ==============="
        "\nA code to infer planetary atmospheric properties based on observed  "
        "\nspectroscopic information."
        "\n\nCopyright (C) 2015-2016 University of Central Florida."
        "\nAll rights reserved."
        "\n\nContact:  Patricio Cubillos  patricio.cubillos[at]oeaw.ac.at"
        "\n          Jasmina Blecic     jasmina[at]physics.ucf.edu"
        "\n          Joseph Harrington  jh[at]physics.ucf.edu"
        "\n======================================================================"
    )

    mu.msg(1, "\nInitialization:")

    # Parse the config file from the command line:
    cparser = argparse.ArgumentParser(
        description=__doc__,
        add_help=False,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    # Add config file option:
    cparser.add_argument("-c",
                         "--config_file",
                         help="Configuration file",
                         metavar="FILE")

    # Parser for the MCMC arguments:
    parser = argparse.ArgumentParser(parents=[cparser])
    parser.add_argument("--justTEA", action='store_true', help="Run only TEA.")
    parser.add_argument("--justOpacity",
                        action='store_true',
                        help="Run only Transit to generate the Opacity table.")
    parser.add_argument("--resume",
                        action='store_true',
                        help="Resume a previous run.")
    # Directories and files options:
    group = parser.add_argument_group("Directories and files")
    group.add_argument(
        "--loc_dir",
        dest="loc_dir",
        help="Output directory to store results [default: %(default)s]",
        type=str,
        action="store",
        default="outdir")
    group.add_argument("--tep_name",
                       dest="tep_name",
                       help="Transiting exoplanet file name.",
                       type=str,
                       action="store",
                       default=None)
    group.add_argument("--logfile",
                       dest="logfile",
                       help="MCMC log file [default: %(default)s]",
                       type=str,
                       action="store",
                       default="MCMC.log")
    # Pressure layers options:
    group = parser.add_argument_group("Layers pressure sampling")
    group.add_argument(
        "--n_layers",
        dest="n_layers",
        help="Number of atmospheric layers [default: %(default)s]",
        type=int,
        action="store",
        default=100)
    group.add_argument("--p_top",
                       dest="p_top",
                       help="Pressure at the top of the atmosphere (bars) "
                       "[default: %(default)s]",
                       type=np.double,
                       action="store",
                       default=1.0e-5)
    group.add_argument("--p_bottom",
                       dest="p_bottom",
                       help="Pressure at the botom of the atmosphere (bars) "
                       "[default: %(default)s]",
                       type=np.double,
                       action="store",
                       default=100.0)
    group.add_argument("--log",
                       dest="log",
                       help="Use log (True) or linear (False) scale sampling "
                       "[default: %(default)s]",
                       type=eval,
                       action="store",
                       default=True)
    group.add_argument("--press_file",
                       dest="press_file",
                       help="Input/Output file with pressure array.",
                       type=str,
                       action="store",
                       default=None)

    # Elemental abundance options:
    group = parser.add_argument_group("Elemental abundances")
    group.add_argument(
        "--abun_basic",
        dest="abun_basic",
        help="Input elemental abundances file [default: %(default)s]",
        type=str,
        action="store",
        default="../BART/inputs/abundances_Asplund2009.txt")
    group.add_argument("--abun_file",
                       dest="abun_file",
                       help="Input/Output modified elemental abundances file",
                       type=str,
                       action="store",
                       default=None)
    group.add_argument(
        "--solar_times",
        dest="solar_times",
        help="Multiplication factor for metal-element abundances",
        type=int,
        action="store",
        default=1.0)
    group.add_argument(
        "--COswap",
        dest="COswap",
        help="Swap C and O abundances if True [default: %(default)s]",
        type=eval,
        action="store",
        default=False)

    # Temperature profile options:
    group = parser.add_argument_group("Temperature profile")
    group.add_argument("--PTtype",
                       dest="PTtype",
                       help="Temperature profile model [default: %(default)s]",
                       type=str,
                       action="store",
                       default="line",
                       choices=("line", "madhu"))
    group.add_argument("--PTinit",
                       dest="PTinit",
                       help="Temperature profile model parameters",
                       type=mu.parray,
                       action="store",
                       default=None)

    # Atmospheric model options:
    group = parser.add_argument_group("Atmospheric model")
    group.add_argument(
        "--in_elem",
        dest="in_elem",
        help="Input elements to consider in TEA [default: %(default)s]",
        type=str,
        action="store",
        default='H He C N O')
    group.add_argument(
        "--out_spec",
        dest="out_spec",
        help="Output species to include in the atmospheric model "
        "[default: %(default)s]",
        type=str,
        action="store",
        default='H_g He_ref C_g N_g O_g H2_ref CO_g CO2_g CH4_g H2O_g')
    group.add_argument(
        "--preatm_file",
        dest="preatm_file",
        help="Pre-atmospheric file with elemental abundances per layer "
        "[default: %(default)s]",
        type=str,
        action="store",
        default="elem.atm")
    group.add_argument("--atmfile",
                       dest="atmfile",
                       help="Atmospheric model file [default: %(default)s]",
                       type=str,
                       action="store",
                       default="")
    group.add_argument(
        "--uniform",
        dest="uniform",
        help="If not None, set uniform abundances with the specified "
        "values for each species in out_spec [default: %(default)s]",
        type=mu.parray,
        action="store",
        default=None)
    group.add_argument(
        "--refpress",
        dest="refpress",
        help="Reference pressure level (bar) corresponding to the pressure"
        "at the planet radius [default: %(default)s]",
        type=float,
        action="store",
        default=0.1)

    # MCMC options:
    group = parser.add_argument_group("MCMC")
    group.add_argument("--params",
                       dest="params",
                       help="Model-fitting parameters [default: %(default)s]",
                       type=mu.parray,
                       action="store",
                       default=None)
    group.add_argument("--molfit",
                       dest="molfit",
                       help="Molecules fit [default: %(default)s]",
                       type=mu.parray,
                       action="store",
                       default=None)
    group.add_argument(
        "--Tmin",
        dest="Tmin",
        help="Lower Temperature boundary [default: %(default)s]",
        type=float,
        action="store",
        default=400.0)
    group.add_argument(
        "--Tmax",
        dest="Tmax",
        help="Higher Temperature boundary [default: %(default)s]",
        type=float,
        action="store",
        default=3000.0)
    group.add_argument("--quiet",
                       dest="quiet",
                       help="Set verbosity level to minimum",
                       action="store_true")
    group.add_argument("--stepsize",
                       dest="stepsize",
                       help="Parameters stepsize",
                       type=mu.parray,
                       action="store",
                       default=None)
    group.add_argument("--burnin",
                       dest="burnin",
                       help="Number of burn-in iterations per chain",
                       type=mu.parray,
                       action="store",
                       default=None)
    group.add_argument("--data",
                       dest="data",
                       help="Transit or eclipse depths",
                       type=mu.parray,
                       action="store",
                       default=None)
    group.add_argument("--uncert",
                       dest="uncert",
                       help="Uncertanties on transit or eclipse depths",
                       type=mu.parray,
                       action="store",
                       default=None)

    # Input converter options:
    group = parser.add_argument_group("Input Converter Options")
    group.add_argument(
        "--tint",
        dest="tint",
        help="Internal temperature of the planet [default: %(default)s].",
        type=float,
        action="store",
        default=100.0)

    # Output-Converter Options:
    group = parser.add_argument_group("Output Converter Options")
    group.add_argument("--filter",
                       action="store",
                       help="Waveband filter name [default: %(default)s]",
                       dest="filter",
                       type=mu.parray,
                       default=None)
    group.add_argument("--kurucz_file",
                       action="store",
                       help="Stellar Kurucz file [default: %(default)s]",
                       dest="kurucz",
                       type=str,
                       default=None)
    group.add_argument("--solution",
                       action="store",
                       help="Solution geometry [default: %(default)s]",
                       dest="solution",
                       type=str,
                       default="None",
                       choices=('transit', 'eclipse'))

    # Transit options:
    group = parser.add_argument_group("Transit variables")
    group.add_argument(
        "--tconfig",
        dest="tconfig",
        help="Transit configuration file [default: %(default)s]",
        type=str,
        action="store",
        default="transit.cfg")
    group.add_argument("--opacityfile",
                       dest="opacityfile",
                       help="Opacity table file [default: %(default)s]",
                       type=str,
                       action="store",
                       default=None)
    group.add_argument("--outspec",
                       dest="outspec",
                       help="Output spectrum filename [default: %(default)s]",
                       type=str,
                       action="store",
                       default="outspec.dat")
    group.add_argument(
        "--shareOpacity",
        dest="shareOpacity",
        help="If True, use shared memory for the Transit opacity file "
        "[default: %(default)s]",
        type=eval,
        action="store",
        default=True)

    # Remaining_argv contains all other command-line-arguments:
    cargs, remaining_argv = cparser.parse_known_args()
    # Get only the arguments defined above:
    known, unknown = parser.parse_known_args(remaining_argv)

    # Get configuration file from command-line:
    cfile = cargs.config_file
    # Default:
    if cfile is None:
        cfile = "./BART.cfg"
    # Always require a configuration file:
    if not os.path.isfile(cfile):
        mu.error("Configuration file: '{:s}' not found.".format(cfile))

    # Read values from configuration file:
    config = ConfigParser.SafeConfigParser()
    config.optionxform = str  # This one enable Uppercase in arguments
    config.read([cfile])
    defaults = dict(config.items("MCMC"))
    mu.msg(1, "The configuration file is: '{:s}'.".format(cfile), indent=2)

    # Set the defaults from the configuration file:
    parser.set_defaults(**defaults)
    # Set values from command line:
    args, unknown = parser.parse_known_args(remaining_argv)

    # Unpack the variables from args:
    variables = dir(args)
    for var in dir(known):
        if not var.startswith("_"):
            exec("{:s} = args.{:s}".format(var, var))

    # Make output directory:
    # Make a subdirectory with the date and time
    dirfmt = loc_dir + "%4d-%02d-%02d_%02d:%02d:%02d"
    date_dir = dirfmt % time.localtime()[0:6]
    # FINDME: Temporary hack (temporary?):
    date_dir = os.path.normpath(loc_dir) + "/"
    if not os.path.isabs(date_dir):
        date_dir = os.getcwd() + "/" + date_dir
    mu.msg(1, "Output folder: '{:s}'".format(date_dir), indent=2)
    try:
        os.mkdir(date_dir)
    except OSError, e:
        if e.errno == 17:  # Allow overwritting while we debug
            pass
        else:
            mu.error("Cannot create folder '{:s}'. {:s}.".format(
                date_dir, os.strerror(e.errno)))
Beispiel #3
0
def main():
  """
  One function to run them all.
  """

  mu.msg(1,
     "\n======= Bayesian Atmospheric Radiative Transfer (BART) ==============="
     "\nA code to infer planetary atmospheric properties based on observed  "
     "\nspectroscopic information."
   "\n\nCopyright (C) 2015-2016 University of Central Florida."
     "\nAll rights reserved."
   "\n\nContact:  Patricio Cubillos  patricio.cubillos[at]oeaw.ac.at"
     "\n          Jasmina Blecic     jasmina[at]physics.ucf.edu"
     "\n          Joseph Harrington  jh[at]physics.ucf.edu"
     "\n======================================================================")

  mu.msg(1, "\nInitialization:")

  # Parse the config file from the command line:
  cparser = argparse.ArgumentParser(description=__doc__, add_help=False,
                         formatter_class=argparse.RawDescriptionHelpFormatter)
  # Add config file option:
  cparser.add_argument("-c", "--config_file",
                       help="Configuration file", metavar="FILE")

  # Parser for the MCMC arguments:
  parser = argparse.ArgumentParser(parents=[cparser])
  parser.add_argument("--justTEA",               action='store_true',
                       help="Run only TEA.")
  parser.add_argument("--justOpacity",           action='store_true',
                       help="Run only Transit to generate the Opacity table.")
  parser.add_argument("--justPlots",             action='store_true',
                       help="Remakes plots of BART output.")
  parser.add_argument("--resume",                action='store_true',
                       help="Resume a previous run.")
  # Directories and files options:
  group = parser.add_argument_group("Directories and files")
  group.add_argument("--loc_dir", dest="loc_dir",
           help="Output directory to store results [default: %(default)s]",
           type=str, action="store", default="outdir")
  group.add_argument("--tep_name", dest="tep_name",
           help="Transiting exoplanet file name.",
           type=str, action="store", default=None)
  group.add_argument("--logfile", dest="logfile",
           help="MCMC log file [default: %(default)s]",
           type=str, action="store", default="MCMC.log")
  # Pressure layers options:
  group = parser.add_argument_group("Layers pressure sampling")
  group.add_argument("--n_layers", dest="n_layers",
           help="Number of atmospheric layers [default: %(default)s]",
           type=int, action="store", default=100)
  group.add_argument("--p_top", dest="p_top",
           help="Pressure at the top of the atmosphere (bars) "
                "[default: %(default)s]",
           type=np.double, action="store", default=1.0e-5)
  group.add_argument("--p_bottom", dest="p_bottom",
           help="Pressure at the botom of the atmosphere (bars) "
                "[default: %(default)s]",
           type=np.double, action="store", default=100.0)
  group.add_argument("--log", dest="log",
           help="Use log (True) or linear (False) scale sampling "
                "[default: %(default)s]",
           type=eval, action="store", default=True)
  group.add_argument("--press_file", dest="press_file",
           help="Input/Output file with pressure array.",
           type=str, action="store", default=None)

  # Elemental abundance options:
  group = parser.add_argument_group("Elemental abundances")
  group.add_argument("--abun_basic", dest="abun_basic",
           help="Input elemental abundances file [default: %(default)s]",
           type=str, action="store", default="../BART/inputs/abundances_Asplund2009.txt")
  group.add_argument("--abun_file", dest="abun_file",
           help="Input/Output modified elemental abundances file",
           type=str, action="store", default=None)
  group.add_argument("--solar_times", dest="solar_times",
           help="Multiplication factor for metal-element abundances",
           type=int, action="store", default=1.0)
  group.add_argument("--COswap", dest="COswap",
           help="Swap C and O abundances if True [default: %(default)s]",
           type=eval, action="store", default=False)

  # Temperature profile options:
  group = parser.add_argument_group("Temperature profile")
  group.add_argument("--PTtype", dest="PTtype",
           help="Temperature profile model [default: %(default)s]",
           type=str, action="store", default="line", 
           choices=("line","madhu_noinv","madhu_inv","iso"))
  group.add_argument("--PTinit", dest="PTinit",
           help="Temperature profile model parameters",
           type=mu.parray, action="store", default=None)

  # Atmospheric model options:
  group = parser.add_argument_group("Atmospheric model")
  group.add_argument("--in_elem", dest="in_elem",
           help="Input elements to consider in TEA [default: %(default)s]",
           type=str, action="store", default='H He C N O')
  group.add_argument("--out_spec", dest="out_spec",
           help="Output species to include in the atmospheric model "
                "[default: %(default)s]",
           type=str, action="store",
           default='H_g He_ref C_g N_g O_g H2_ref CO_g CO2_g CH4_g H2O_g')
  group.add_argument("--preatm_file", dest="preatm_file",
           help="Pre-atmospheric file with elemental abundances per layer "
                "[default: %(default)s]",
           type=str, action="store", default="elem.atm")
  group.add_argument("--atmfile", dest="atmfile",
           help="Atmospheric model file [default: %(default)s]",
           type=str, action="store", default="")
  group.add_argument("--uniform", dest="uniform",
           help="If not None, set uniform abundances with the specified "
                "values for each species in out_spec [default: %(default)s]",
           type=mu.parray, action="store", default=None)
  group.add_argument("--refpress", dest="refpress",
           help="Reference pressure level (bar) corresponding to the pressure"
                " at the planet radius [default: %(default)s]",
           type=float, action="store", default=0.1)

  # MCMC options:
  group = parser.add_argument_group("MCMC")
  group.add_argument("--params",  dest="params",
           help="Model-fitting parameters [default: %(default)s]",
           type=mu.parray, action="store", default=None)
  group.add_argument("--parnames", dest="parnames", 
           help="Labels for model-fitting parameters [default: %(default)s]", 
           type=mu.parray, action="store", default=None)
  group.add_argument("--molfit",  dest="molfit", 
           help="Molecules fit [default: %(default)s]",
           type=mu.parray, action="store", default=None)
  group.add_argument("--Tmin",    dest="Tmin", 
           help="Lower Temperature boundary [default: %(default)s]",
           type=float,     action="store", default=400.0)
  group.add_argument("--Tmax",    dest="Tmax",
           help="Higher Temperature boundary [default: %(default)s]",
           type=float,     action="store", default=3000.0)
  group.add_argument("--quiet",   dest="quiet",
           help="Set verbosity level to minimum",
           action="store_true")
  group.add_argument("--nchains",  dest="nchains", 
           help="Number of parallel chains for MCMC", 
           type=int,       action="store", default=10)
  group.add_argument("--stepsize", dest="stepsize",
           help="Parameters stepsize",
           type=mu.parray, action="store", default=None)
  group.add_argument("--burnin", dest="burnin",
           help="Number of burn-in iterations per chain",
           type=int,       action="store", default=None)
  group.add_argument("--thinning", dest="thinning",
           help="Thinning factor of the chains (use every thinning-th "
                 "iteration) used in the GR test and plots", 
           type=int,       action="store", default=1)
  group.add_argument("--data", dest="data",
           help="Transit or eclipse depths",
           type=mu.parray, action="store", default=None)
  group.add_argument("--uncert", dest="uncert",
           help="Uncertanties on transit or eclipse depths",
           type=mu.parray, action="store", default=None)

  # Input converter options:
  group = parser.add_argument_group("Input Converter Options")
  group.add_argument("--tint", dest="tint",
           help="Internal temperature of the planet [default: %(default)s].",
           type=float, action="store", default=100.0)

  # Output-Converter Options:
  group = parser.add_argument_group("Output Converter Options")
  group.add_argument("--filters",                action="store",
           help="Waveband filter names [default: %(default)s]",
           dest="filters",   type=mu.parray, default=None)
  group.add_argument("--kurucz_file",           action="store",
           help="Stellar Kurucz file [default: %(default)s]",
           dest="kurucz",   type=str,       default=None)
  group.add_argument("--solution",                    action="store",
           help="Solution geometry [default: %(default)s]",
           dest="solution", type=str,       default="None",
           choices=('transit', 'eclipse'))

  # Transit options:
  group = parser.add_argument_group("Transit variables")
  group.add_argument("--tconfig", dest="tconfig",
           help="Transit configuration file [default: %(default)s]",
           type=str, action="store", default="transit.cfg")
  group.add_argument("--opacityfile", dest="opacityfile",
           help="Opacity table file [default: %(default)s]",
           type=str, action="store", default=None)
  group.add_argument("--outspec", dest="outspec",
           help="Output spectrum filename [default: %(default)s]",
           type=str, action="store", default="outspec.dat")
  group.add_argument("--shareOpacity", dest="shareOpacity",
           help="If True, use shared memory for the Transit opacity file "
                "[default: %(default)s]",
           type=eval, action="store", default=True)


  # Remaining_argv contains all other command-line-arguments:
  cargs, remaining_argv = cparser.parse_known_args()
  # Get only the arguments defined above:
  known, unknown = parser.parse_known_args(remaining_argv)


  # Get configuration file from command-line:
  cfile = cargs.config_file
  # Default:
  if cfile is None:
    cfile = "./BART.cfg"
  # Always require a configuration file:
  if not os.path.isfile(cfile):
    mu.error("Configuration file: '{:s}' not found.".format(cfile))

  # Read values from configuration file:
  config = ConfigParser.SafeConfigParser()
  config.optionxform = str  # This one enable Uppercase in arguments
  config.read([cfile])
  defaults = dict(config.items("MCMC"))
  mu.msg(1, "The configuration file is: '{:s}'.".format(cfile), indent=2)

  # Set the defaults from the configuration file:
  parser.set_defaults(**defaults)
  # Set values from command line:
  args, unknown = parser.parse_known_args(remaining_argv)

  # Unpack the variables from args:
  variables = dir(args)
  for var in dir(known):
    if not var.startswith("_"):
      exec("{:s} = args.{:s}".format(var, var))

  # Dictionary of functions to calculate temperature for PTtype
  PTfunc = {'iso'         : pt.PT_iso,
            'line'        : pt.PT_line, 
            'madhu_noinv' : pt.PT_NoInversion,
            'madhu_inv'   : pt.PT_Inversion}

  # Check that the user gave a valid PTtype:
  if PTtype not in PTfunc.keys():
    print("The specified 'PTtype' is not valid. Options are 'line', " + \
          "'madhu_noinv', 'madhu_inv', or 'iso'. Please try again.")
    sys.exit()

  # Check that out_spec and uniform are valid specifications
  if uniform is not None and len(uniform) != len(out_spec.split(' ')):
    print('The inputs for out_spec and uniform are not compatible.')
    diffuniout = len(uniform) - len(out_spec.split(' '))
    if diffuniout > 0:
      if diffuniout == 1:
        print('uniform has ' + str(diffuniout) + 'extra entry.')
      else:
        print('uniform has ' + str(diffuniout) + 'extra entries.')
    else:
      if diffuniout == -1:
        print('out_spec has ' + str(-1*diffuniout) + 'extra entry.')
      else:
        print('out_spec has ' + str(-1*diffuniout) + 'extra entries.')
    print('Please correct this and run again.')
    sys.exit()

  # Make output directory:
  # Make a subdirectory with the date and time
  dirfmt = loc_dir + "%4d-%02d-%02d_%02d:%02d:%02d"
  date_dir = dirfmt % time.localtime()[0:6]
  # FINDME: Temporary hack (temporary?):
  date_dir = os.path.normpath(loc_dir) + "/"
  if not os.path.isabs(date_dir):
    date_dir = os.getcwd() + "/" + date_dir
  mu.msg(1, "Output folder: '{:s}'".format(date_dir), indent=2)
  try:
    os.mkdir(date_dir)
  except OSError, e:
    if e.errno == 17: # Allow overwritting while we debug
      pass
    else:
      mu.error("Cannot create folder '{:s}'. {:s}.".format(date_dir,
                                                     os.strerror(e.errno)))
Beispiel #4
0
    else:
      mu.error("Cannot create folder '{:s}'. {:s}.".format(date_dir,
                                                     os.strerror(e.errno)))
  # Copy files to date dir:
  # BART configuration file:
  shutil.copy2(cfile, date_dir)
  # TEP file:
  if not os.path.isfile(tep_name):
    mu.error("Tepfile ('{:s}') Not found.".format(tep_name))
  else:
    shutil.copy2(tep_name, date_dir + os.path.basename(tep_name))

  # Check if files already exist:
  runMCMC = 0  # Flag that indicate which steps to run
  if justPlots:
    mu.msg(1, "\nRe-making output plots.", indent=0)
    runMCMC |= 16
  # Atmospheric file:
  if os.path.isfile(atmfile):
    atmfile = os.path.realpath(atmfile)
    shutil.copy2(atmfile, date_dir + os.path.basename(atmfile))
    mu.msg(1, "Atmospheric file copied from: '{:s}'.".format(atmfile),indent=2)
    runMCMC |= 8
  # Pre-atmospheric file:
  if os.path.isfile(preatm_file):
    preatm_file = os.path.realpath(preatm_file)
    shutil.copy2(preatm_file, date_dir + os.path.basename(preatm_file))
    mu.msg(1, "Pre-atmospheric file copied from: '{:s}'.".format(preatm_file),
           indent=2)
    runMCMC |= 4
  # Elemental-abundances file:
Beispiel #5
0
def main(comm):
    """
  This is a hacked version of MC3's func.py.
  This function directly call's the modeling function for the BART project.
  """
    # Parse arguments:
    cparser = argparse.ArgumentParser(
        description=__doc__,
        add_help=False,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    # Add config file option:
    cparser.add_argument("-c",
                         "--config_file",
                         help="Configuration file",
                         metavar="FILE")
    # Remaining_argv contains all other command-line-arguments:
    args, remaining_argv = cparser.parse_known_args()

    # Get parameters from configuration file:
    cfile = args.config_file
    if cfile:
        config = ConfigParser.SafeConfigParser()
        config.optionxform = str
        config.read([cfile])
        defaults = dict(config.items("MCMC"))
    else:
        defaults = {}
    parser = argparse.ArgumentParser(parents=[cparser])
    parser.add_argument("--func",
                        dest="func",
                        type=mu.parray,
                        action="store",
                        default=None)
    parser.add_argument("--indparams",
                        dest="indparams",
                        type=mu.parray,
                        action="store",
                        default=[])
    parser.add_argument("--params",
                        dest="params",
                        type=mu.parray,
                        action="store",
                        default=None,
                        help="Model-fitting parameters [default: %(default)s]")
    parser.add_argument("--molfit",
                        dest="molfit",
                        type=mu.parray,
                        action="store",
                        default=None,
                        help="Molecules fit [default: %(default)s]")
    parser.add_argument(
        "--Tmin",
        dest="Tmin",
        type=float,
        action="store",
        default=400.0,
        help="Lower Temperature boundary [default: %(default)s]")
    parser.add_argument(
        "--Tmax",
        dest="Tmax",
        type=float,
        action="store",
        default=3000.0,
        help="Higher Temperature boundary [default: %(default)s]")
    parser.add_argument("--quiet",
                        action="store_true",
                        help="Set verbosity level to minimum",
                        dest="quiet")
    # Input-Converter Options:
    group = parser.add_argument_group("Input Converter Options")
    group.add_argument("--atmospheric_file",
                       action="store",
                       help="Atmospheric file [default: %(default)s]",
                       dest="atmfile",
                       type=str,
                       default=None)
    group.add_argument("--PTtype",
                       action="store",
                       help="PT profile type.",
                       dest="PTtype",
                       type=str,
                       default="none")
    group.add_argument("--tint",
                       action="store",
                       help="Internal temperature of the planet [default: "
                       "%(default)s].",
                       dest="tint",
                       type=float,
                       default=100.0)
    # transit Options:
    group = parser.add_argument_group("transit Options")
    group.add_argument(
        "--config",
        action="store",
        help="transit configuration file [default: %(default)s]",
        dest="config",
        type=str,
        default=None)
    # Output-Converter Options:
    group = parser.add_argument_group("Output Converter Options")
    group.add_argument("--filters",
                       action="store",
                       help="Waveband filter name [default: %(default)s]",
                       dest="filters",
                       type=mu.parray,
                       default=None)
    group.add_argument("--tep_name",
                       action="store",
                       help="A TEP file [default: %(default)s]",
                       dest="tep_name",
                       type=str,
                       default=None)
    group.add_argument("--kurucz_file",
                       action="store",
                       help="Stellar Kurucz file [default: %(default)s]",
                       dest="kurucz",
                       type=str,
                       default=None)
    group.add_argument("--solution",
                       action="store",
                       help="Solution geometry [default: %(default)s]",
                       dest="solution",
                       type=str,
                       default="None",
                       choices=('transit', 'eclipse'))

    parser.set_defaults(**defaults)
    args2, unknown = parser.parse_known_args(remaining_argv)

    # Quiet all threads except rank 0:
    rank = comm.Get_rank()
    verb = rank == 0

    # Get (Broadcast) the number of parameters and iterations from MPI:
    array1 = np.zeros(2, np.int)
    mu.comm_bcast(comm, array1)
    npars, niter = array1

    # :::::::  Initialize the Input converter ::::::::::::::::::::::::::
    atmfile = args2.atmfile
    molfit = args2.molfit
    PTtype = args2.PTtype
    params = args2.params
    tepfile = args2.tep_name
    tint = args2.tint
    Tmin = args2.Tmin
    Tmax = args2.Tmax
    solution = args2.solution  # Solution type

    # Dictionary of functions to calculate temperature for PTtype
    PTfunc = {
        'iso': pt.PT_iso,
        'line': pt.PT_line,
        'madhu_noinv': pt.PT_NoInversion,
        'madhu_inv': pt.PT_Inversion
    }

    # Extract necessary values from the TEP file:
    tep = rd.File(tepfile)
    # Stellar temperature in K:
    tstar = float(tep.getvalue('Ts')[0])
    # Stellar radius (in meters):
    rstar = float(tep.getvalue('Rs')[0]) * c.Rsun
    # Semi-major axis (in meters):
    sma = float(tep.getvalue('a')[0]) * sc.au
    # Planetary radius (in meters):
    rplanet = float(tep.getvalue('Rp')[0]) * c.Rjup
    # Planetary mass (in kg):
    mplanet = float(tep.getvalue('Mp')[0]) * c.Mjup

    # Number of fitting parameters:
    nfree = len(params)  # Total number of free parameters
    nmolfit = len(molfit)  # Number of molecular free parameters
    nradfit = int(solution == 'transit')  # 1 for transit, 0 for eclipse
    nPT = nfree - nmolfit - nradfit  # Number of PT free parameters

    # Read atmospheric file to get data arrays:
    species, pressure, temp, abundances = mat.readatm(atmfile)
    # Reverse pressure order (for PT to work):
    pressure = pressure[::-1]
    nlayers = len(pressure)  # Number of atmospheric layers
    nspecies = len(species)  # Number of species in the atmosphere
    mu.msg(verb,
           "There are {:d} layers and {:d} species.".format(nlayers, nspecies))
    # Find index for Hydrogen and Helium:
    species = np.asarray(species)
    iH2 = np.where(species == "H2")[0]
    iHe = np.where(species == "He")[0]
    # Get H2/He abundance ratio:
    ratio = (abundances[:, iH2] / abundances[:, iHe]).squeeze()
    # Find indices for the metals:
    imetals = np.where((species != "He") & (species != "H2") & \
                       (species != "H-") & (species != 'e-'))[0]
    # Index of molecular abundances being modified:
    imol = np.zeros(nmolfit, dtype='i')
    for i in np.arange(nmolfit):
        imol[i] = np.where(np.asarray(species) == molfit[i])[0]

    # Pressure-Temperature profile:
    if PTtype == "line":
        # Planetary surface gravity (in cm s-2):
        gplanet = 100.0 * sc.G * mplanet / rplanet**2
        # Additional PT arguments:
        PTargs = [rstar, tstar, tint, sma, gplanet]
    else:
        PTargs = None

    # Allocate arrays for receiving and sending data to master:
    freepars = np.zeros(nfree, dtype='d')
    profiles = np.zeros((nspecies + 1, nlayers), dtype='d')
    # This are sub-sections of profiles, containing just the temperature and
    # the abundance profiles, respectively:
    tprofile = profiles[0, :]
    aprofiles = profiles[1:, :]

    # Store abundance profiles:
    for i in np.arange(nspecies):
        aprofiles[i] = abundances[:, i]

    # :::::::  Spawn transit code  :::::::::::::::::::::::::::::::::::::
    # # transit configuration file:
    transitcfile = args2.tconfig

    # Initialize the transit python module:
    transit_args = ["transit", "-c", transitcfile]
    trm.transit_init(len(transit_args), transit_args)

    # Get wavenumber array from transit:
    nwave = trm.get_no_samples()
    specwn = trm.get_waveno_arr(nwave)

    # :::::::  Output Converter  :::::::::::::::::::::::::::::::::::::::
    ffile = args2.filters  # Filter files
    kurucz = args2.kurucz  # Kurucz file

    # Log10(stellar gravity)
    gstar = float(tep.getvalue('loggstar')[0])
    # Planet-to-star radius ratio:
    rprs = rplanet / rstar

    nfilters = len(ffile)  # Number of filters:

    # FINDME: Separate filter/stellar interpolation?
    # Get stellar model:
    starfl, starwn, tmodel, gmodel = w.readkurucz(kurucz, tstar, gstar)
    # Read and resample the filters:
    nifilter = []  # Normalized interpolated filter
    istarfl = []  # interpolated stellar flux
    wnindices = []  # wavenumber indices used in interpolation
    for i in np.arange(nfilters):
        # Read filter:
        filtwaven, filttransm = w.readfilter(ffile[i])
        # Check that filter boundaries lie within the spectrum wn range:
        if filtwaven[0] < specwn[0] or filtwaven[-1] > specwn[-1]:
            mu.exit(message="Wavenumber array ({:.2f} - {:.2f} cm-1) does not "
                    "cover the filter[{:d}] wavenumber range ({:.2f} - {:.2f} "
                    "cm-1).".format(specwn[0], specwn[-1], i, filtwaven[0],
                                    filtwaven[-1]))

        # Resample filter and stellar spectrum:
        nifilt, strfl, wnind = w.resample(specwn, filtwaven, filttransm,
                                          starwn, starfl)
        nifilter.append(nifilt)
        istarfl.append(strfl)
        wnindices.append(wnind)

    # Allocate arrays for receiving and sending data to master:
    spectrum = np.zeros(nwave, dtype='d')
    bandflux = np.zeros(nfilters, dtype='d')

    # Allocate array to receive parameters from MPI:
    params = np.zeros(npars, np.double)

    # ::::::  Main MCMC Loop  ::::::::::::::::::::::::::::::::::::::::::
    # ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    while niter >= 0:
        niter -= 1
        # Receive parameters from MCMC:
        mu.comm_scatter(comm, params)

        # Check for the MCMC-end flag:
        if params[0] == np.inf:
            break

        # Input converter calculate the profiles:
        try:
            tprofile[:] = pt.PT_generator(pressure, params[0:nPT],
                                          PTfunc[PTtype], PTargs)[::-1]
        except ValueError:
            mu.msg(verb, 'Input parameters give non-physical profile.')
            # FINDME: what to do here?

        # If the temperature goes out of bounds:
        if np.any(tprofile < Tmin) or np.any(tprofile > Tmax):
            mu.comm_gather(comm, -np.ones(nfilters), MPI.DOUBLE)
            continue
        # Scale abundance profiles:
        for i in np.arange(nmolfit):
            m = imol[i]
            # Use variable as the log10:
            aprofiles[m] = abundances[:, m] * 10.0**params[nPT + nradfit + i]

        # Update H2, He abundances so sum(abundances) = 1.0 in each layer:
        q = 1.0 - np.sum(aprofiles[imetals], axis=0)
        if np.any(q < 0.0):
            mu.comm_gather(comm, -np.ones(nfilters), MPI.DOUBLE)
            continue
        aprofiles[iH2] = ratio * q / (1.0 + ratio)
        aprofiles[iHe] = q / (1.0 + ratio)

        # Set the 'surface' level:
        if solution == "transit":
            trm.set_radius(params[nPT])

        # Let transit calculate the model spectrum:
        spectrum = trm.run_transit(profiles.flatten(), nwave)

        # Calculate the band-integrated intensity per filter:
        for i in np.arange(nfilters):
            if solution == "eclipse":
                fluxrat = (spectrum[wnindices[i]] / istarfl[i]) * rprs * rprs
                bandflux[i] = w.bandintegrate(fluxrat, specwn, nifilter[i],
                                              wnindices[i])
            elif solution == "transit":
                bandflux[i] = w.bandintegrate(spectrum[wnindices[i]], specwn,
                                              nifilter[i], wnindices[i])

        # Send resutls back to MCMC:
        mu.comm_gather(comm, bandflux, MPI.DOUBLE)

    # ::::::  End main Loop  :::::::::::::::::::::::::::::::::::::::::::
    # ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    # Close communications and disconnect:
    mu.comm_disconnect(comm)
    trm.free_memory()
Beispiel #6
0
def main(comm):
  """
  This is a hacked version of MC3's func.py.
  This function directly call's the modeling function for the BART project.
  """
  # Parse arguments:
  cparser = argparse.ArgumentParser(description=__doc__, add_help=False,
                         formatter_class=argparse.RawDescriptionHelpFormatter)
  # Add config file option:
  cparser.add_argument("-c", "--config_file", 
                       help="Configuration file", metavar="FILE")
  # Remaining_argv contains all other command-line-arguments:
  args, remaining_argv = cparser.parse_known_args()

  # Get parameters from configuration file:
  cfile = args.config_file
  if cfile:
    config = ConfigParser.SafeConfigParser()
    config.optionxform = str
    config.read([cfile])
    defaults = dict(config.items("MCMC"))
  else:
    defaults = {}
  parser = argparse.ArgumentParser(parents=[cparser])
  parser.add_argument("--func",      dest="func",      type=mu.parray, 
                                     action="store",  default=None)
  parser.add_argument("--indparams", dest="indparams", type=mu.parray, 
                                     action="store",   default=[])
  parser.add_argument("--params",    dest="params",    type=mu.parray,
                                     action="store",   default=None,
                      help="Model-fitting parameters [default: %(default)s]")
  parser.add_argument("--molfit",    dest="molfit",    type=mu.parray,
                                     action="store",   default=None,
                      help="Molecules fit [default: %(default)s]")
  parser.add_argument("--Tmin",      dest="Tmin",      type=float,
                      action="store",  default=400.0,
                      help="Lower Temperature boundary [default: %(default)s]")
  parser.add_argument("--Tmax",      dest="Tmax",      type=float,
                      action="store",  default=3000.0,
                      help="Higher Temperature boundary [default: %(default)s]")
  parser.add_argument("--quiet",             action="store_true",
                      help="Set verbosity level to minimum",
                      dest="quiet")
  # Input-Converter Options:
  group = parser.add_argument_group("Input Converter Options")
  group.add_argument("--atmospheric_file",  action="store",
                     help="Atmospheric file [default: %(default)s]",
                     dest="atmfile", type=str,    default=None)
  group.add_argument("--PTtype",            action="store",
                     help="PT profile type.",
                     dest="PTtype",  type=str,    default="none")
                     #choices=('line', 'madhu'))
  group.add_argument("--tint",              action="store",
                     help="Internal temperature of the planet [default: "
                     "%(default)s].",
                     dest="tint",    type=float,  default=100.0)
  # transit Options:
  group = parser.add_argument_group("transit Options")
  group.add_argument("--config",  action="store",
                     help="transit configuration file [default: %(default)s]",
                     dest="config", type=str,    default=None)
  # Output-Converter Options:
  group = parser.add_argument_group("Output Converter Options")
  group.add_argument("--filter",                 action="store",
                     help="Waveband filter name [default: %(default)s]",
                     dest="filter",   type=mu.parray, default=None)
  group.add_argument("--tep_name",          action="store",
                     help="A TEP file [default: %(default)s]",
                     dest="tep_name", type=str,    default=None)
  group.add_argument("--kurucz_file",           action="store",
                     help="Stellar Kurucz file [default: %(default)s]",
                     dest="kurucz",   type=str,       default=None)
  group.add_argument("--solution",                    action="store",
                     help="Solution geometry [default: %(default)s]",
                     dest="solution", type=str,       default="None",
                     choices=('transit', 'eclipse'))

  parser.set_defaults(**defaults)
  args2, unknown = parser.parse_known_args(remaining_argv)

  # Quiet all threads except rank 0:
  rank = comm.Get_rank()
  verb = rank == 0

  # Get (Broadcast) the number of parameters and iterations from MPI:
  array1 = np.zeros(2, np.int)
  mu.comm_bcast(comm, array1)
  npars, niter = array1

  # :::::::  Initialize the Input converter ::::::::::::::::::::::::::
  atmfile  = args2.atmfile
  molfit   = args2.molfit
  PTtype   = args2.PTtype
  params   = args2.params
  tepfile  = args2.tep_name
  tint     = args2.tint
  Tmin     = args2.Tmin
  Tmax     = args2.Tmax
  solution = args2.solution  # Solution type

  # Extract necessary values from the TEP file:
  tep = rd.File(tepfile)
  # Stellar temperature in K:
  tstar = float(tep.getvalue('Ts')[0])
  # Stellar radius (in meters):
  rstar = float(tep.getvalue('Rs')[0]) * c.Rsun
  # Semi-major axis (in meters):
  sma   = float(tep.getvalue( 'a')[0]) * sc.au
  # Planetary radius (in meters):
  rplanet = float(tep.getvalue('Rp')[0]) * c.Rjup
  # Planetary mass (in kg):
  mplanet = float(tep.getvalue('Mp')[0]) * c.Mjup

  # Number of fitting parameters:
  nfree   = len(params)                 # Total number of free parameters
  nmolfit = len(molfit)                 # Number of molecular free parameters
  nradfit = int(solution == 'transit')  # 1 for transit, 0 for eclipse
  nPT     = nfree - nmolfit - nradfit   # Number of PT free parameters

  # Read atmospheric file to get data arrays:
  species, pressure, temp, abundances = mat.readatm(atmfile)
  # Reverse pressure order (for PT to work):
  pressure = pressure[::-1]
  nlayers  = len(pressure)   # Number of atmospheric layers
  nspecies = len(species)    # Number of species in the atmosphere
  mu.msg(verb, "There are {:d} layers and {:d} species.".format(nlayers,
                                                                nspecies))
  # Find index for Hydrogen and Helium:
  species = np.asarray(species)
  iH2     = np.where(species=="H2")[0]
  iHe     = np.where(species=="He")[0]
  # Get H2/He abundance ratio:
  ratio = (abundances[:,iH2] / abundances[:,iHe]).squeeze()
  # Find indices for the metals:
  imetals = np.where((species != "He") & (species != "H2"))[0]
  # Index of molecular abundances being modified:
  imol = np.zeros(nmolfit, dtype='i')
  for i in np.arange(nmolfit):
    imol[i] = np.where(np.asarray(species) == molfit[i])[0]

  # Pressure-Temperature profile:
  PTargs = [PTtype]
  if PTtype == "line":
    # Planetary surface gravity (in cm s-2):
    gplanet = 100.0 * sc.G * mplanet / rplanet**2
    # Additional PT arguments:
    PTargs += [rstar, tstar, tint, sma, gplanet]

  # Allocate arrays for receiving and sending data to master:
  freepars = np.zeros(nfree,                 dtype='d')
  profiles = np.zeros((nspecies+1, nlayers), dtype='d')
  # This are sub-sections of profiles, containing just the temperature and
  # the abundance profiles, respectively:
  tprofile  = profiles[0, :]
  aprofiles = profiles[1:,:]

  # Store abundance profiles:
  for i in np.arange(nspecies):
    aprofiles[i] = abundances[:, i]

  # :::::::  Spawn transit code  :::::::::::::::::::::::::::::::::::::
  # # transit configuration file:
  transitcfile = args2.tconfig
 
  # FINDME: Find a way to set verb to the transit subprocesses.
  # Silence all threads except rank 0:
  # if verb == 0:
  #   rargs = ["--quiet"]
  # else:
  #   rargs = []

  # Initialize the transit python module:
  transit_args = ["transit", "-c", transitcfile]
  trm.transit_init(len(transit_args), transit_args)

  # Get wavenumber array from transit:
  nwave  = trm.get_no_samples()
  specwn = trm.get_waveno_arr(nwave)

  # :::::::  Output Converter  :::::::::::::::::::::::::::::::::::::::
  ffile    = args2.filter    # Filter files
  kurucz   = args2.kurucz    # Kurucz file

  # Log10(stellar gravity)
  gstar = float(tep.getvalue('loggstar')[0])
  # Planet-to-star radius ratio:
  rprs  = rplanet / rstar

  nfilters = len(ffile)  # Number of filters:

  # FINDME: Separate filter/stellar interpolation?
  # Get stellar model:
  starfl, starwn, tmodel, gmodel = w.readkurucz(kurucz, tstar, gstar)
  # Read and resample the filters:
  nifilter  = [] # Normalized interpolated filter
  istarfl   = [] # interpolated stellar flux
  wnindices = [] # wavenumber indices used in interpolation
  for i in np.arange(nfilters):
    # Read filter:
    filtwaven, filttransm = w.readfilter(ffile[i])
    # Check that filter boundaries lie within the spectrum wn range:
    if filtwaven[0] < specwn[0] or filtwaven[-1] > specwn[-1]:
      mu.exit(message="Wavenumber array ({:.2f} - {:.2f} cm-1) does not "
              "cover the filter[{:d}] wavenumber range ({:.2f} - {:.2f} "
              "cm-1).".format(specwn[0], specwn[-1], i, filtwaven[0],
                                                        filtwaven[-1]))

    # Resample filter and stellar spectrum:
    nifilt, strfl, wnind = w.resample(specwn, filtwaven, filttransm,
                                              starwn,    starfl)
    nifilter.append(nifilt)
    istarfl.append(strfl)
    wnindices.append(wnind)

  # Allocate arrays for receiving and sending data to master:
  spectrum = np.zeros(nwave,    dtype='d')
  bandflux = np.zeros(nfilters, dtype='d')

  # Allocate array to receive parameters from MPI:
  params = np.zeros(npars, np.double)

  # ::::::  Main MCMC Loop  ::::::::::::::::::::::::::::::::::::::::::
  # ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  while niter >= 0:
    niter -= 1
    # Receive parameters from MCMC:
    mu.comm_scatter(comm, params)

    # Check for the MCMC-end flag:
    if params[0] == np.inf:
      break

    # Input converter calculate the profiles:
    try:
      tprofile[:] = pt.PT_generator(pressure, params[0:nPT], PTargs)[::-1]
    except ValueError:
      mu.msg(verb, 'Input parameters give non-physical profile.')
      # FINDME: what to do here?

    # If the temperature goes out of bounds:
    if np.any(tprofile < Tmin) or np.any(tprofile > Tmax):
      #print("Out of bounds")
      mu.comm_gather(comm, -np.ones(nfilters), MPI.DOUBLE)
      continue

    # Scale abundance profiles:
    for i in np.arange(nmolfit):
      m = imol[i]
      # Use variable as the log10:
      aprofiles[m] = abundances[:, m] * 10.0**params[nPT+nradfit+i]
    # Update H2, He abundances so sum(abundances) = 1.0 in each layer:
    q = 1.0 - np.sum(aprofiles[imetals], axis=0)
    aprofiles[iH2] = ratio * q / (1.0 + ratio)
    aprofiles[iHe] =         q / (1.0 + ratio)

    # Set the 'surface' level:
    if solution == "transit":
      trm.set_radius(params[nPT])

    if rank == 1:
      print("Iteration: {:05}".format(niter))
    # Let transit calculate the model spectrum:
    spectrum = trm.run_transit(profiles.flatten(), nwave)

    # Output converter band-integrate the spectrum:
    # Calculate the band-integrated intensity per filter:
    for i in np.arange(nfilters):
      if   solution == "eclipse":
        fluxrat = (spectrum[wnindices[i]]/istarfl[i]) * rprs*rprs
        bandflux[i] = w.bandintegrate(fluxrat, specwn,
                                      nifilter[i], wnindices[i])
      elif solution == "transit":
        bandflux[i] = w.bandintegrate(spectrum[wnindices[i]], specwn,
                                      nifilter[i], wnindices[i])

    # Send resutls back to MCMC:
    #mu.msg(verb, "OCON FLAG 95: Flux band integrated ({})".format(bandflux))
    #mu.msg(verb, "{}".format(params[nPT:]))
    mu.comm_gather(comm, bandflux, MPI.DOUBLE)
    #mu.msg(verb, "OCON FLAG 97: Sent results back to MCMC")

  # ::::::  End main Loop  :::::::::::::::::::::::::::::::::::::::::::
  # ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # Close communications and disconnect:
  mu.comm_disconnect(comm)
  mu.msg(verb, "FUNC FLAG 99: func out")

  # Close the transit communicators:
  trm.free_memory()
  mu.msg(verb, "FUNC FLAG OUT ~~ 100 ~~")
Beispiel #7
0
def main():
    """
  One function to run them all.
  """

    mu.msg(
        1,
        "\n======= Bayesian Atmospheric Radiative Transfer (BART) ==============="
        "\nA code to infer planetary atmospheric properties based on observed  "
        "\nspectroscopic information."
        "\n\nCopyright (C) 2015-2016 University of Central Florida."
        "\nAll rights reserved."
        "\n\nContact:  Patricio Cubillos  patricio.cubillos[at]oeaw.ac.at"
        "\n          Jasmina Blecic     jasmina[at]physics.ucf.edu"
        "\n          Joseph Harrington  jh[at]physics.ucf.edu"
        "\n======================================================================"
    )

    mu.msg(1, "\nInitialization:")

    # Parse the config file from the command line:
    cparser = argparse.ArgumentParser(
        description=__doc__,
        add_help=False,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    # Add config file option:
    cparser.add_argument("-c",
                         "--config_file",
                         help="Configuration file",
                         metavar="FILE")

    # Parser for the MCMC arguments:
    parser = argparse.ArgumentParser(parents=[cparser])
    parser.add_argument("--justTEA",
                        dest="justTEA",
                        action='store_true',
                        help="Run only TEA.",
                        default=False)
    parser.add_argument("--justOpacity",
                        dest="justOpacity",
                        action='store_true',
                        help="Run only Transit to generate the Opacity table.",
                        default=False)
    parser.add_argument("--justPlots",
                        dest="justPlots",
                        action='store_true',
                        help="Remakes plots of BART output.",
                        default=False)
    parser.add_argument("--resume",
                        dest="resume",
                        action='store_true',
                        help="Resume a previous run.",
                        default=False)
    # Directories and files options:
    group = parser.add_argument_group("Directories and files")
    group.add_argument("--fext",
                       dest="fext",
                       help="File extension for plots [default: %(default)s]",
                       type=str,
                       action="store",
                       default=".png")
    group.add_argument(
        "--loc_dir",
        dest="loc_dir",
        help="Output directory to store results [default: %(default)s]",
        type=str,
        action="store",
        default="outdir")
    group.add_argument("--tep_name",
                       dest="tep_name",
                       help="Transiting exoplanet file name.",
                       type=str,
                       action="store",
                       default=None)
    group.add_argument("--logfile",
                       dest="logfile",
                       help="MCMC log file [default: %(default)s]",
                       type=str,
                       action="store",
                       default="MCMC.log")
    # Pressure layers options:
    group = parser.add_argument_group("Layers pressure sampling")
    group.add_argument(
        "--n_layers",
        dest="n_layers",
        help="Number of atmospheric layers [default: %(default)s]",
        type=int,
        action="store",
        default=100)
    group.add_argument("--p_top",
                       dest="p_top",
                       help="Pressure at the top of the atmosphere (bars) "
                       "[default: %(default)s]",
                       type=np.double,
                       action="store",
                       default=1.0e-5)
    group.add_argument("--p_bottom",
                       dest="p_bottom",
                       help="Pressure at the botom of the atmosphere (bars) "
                       "[default: %(default)s]",
                       type=np.double,
                       action="store",
                       default=100.0)
    group.add_argument("--log",
                       dest="log",
                       help="Use log (True) or linear (False) scale sampling "
                       "[default: %(default)s]",
                       type=eval,
                       action="store",
                       default=True)
    group.add_argument("--press_file",
                       dest="press_file",
                       help="Input/Output file with pressure array.",
                       type=str,
                       action="store",
                       default=None)

    # Elemental abundance options:
    group = parser.add_argument_group("Elemental abundances")
    group.add_argument(
        "--abun_basic",
        dest="abun_basic",
        help="Input elemental abundances file [default: %(default)s]",
        type=str,
        action="store",
        default="../BART/inputs/abundances_Asplund2009.txt")
    group.add_argument("--abun_file",
                       dest="abun_file",
                       help="Input/Output modified elemental abundances file",
                       type=str,
                       action="store",
                       default=None)
    group.add_argument(
        "--solar_times",
        dest="solar_times",
        help="Multiplication factor for metal-element abundances",
        type=int,
        action="store",
        default=1.0)
    group.add_argument(
        "--COswap",
        dest="COswap",
        help="Swap C and O abundances if True [default: %(default)s]",
        type=eval,
        action="store",
        default=False)

    # Temperature profile options:
    group = parser.add_argument_group("Temperature profile")
    group.add_argument("--PTtype",
                       dest="PTtype",
                       help="Temperature profile model [default: %(default)s]",
                       type=str,
                       action="store",
                       default="line",
                       choices=("line", "madhu_noinv", "madhu_inv", "iso"))
    group.add_argument("--PTinit",
                       dest="PTinit",
                       help="Temperature profile model parameters",
                       type=mu.parray,
                       action="store",
                       default=None)

    # Atmospheric model options:
    group = parser.add_argument_group("Atmospheric model")
    group.add_argument(
        "--in_elem",
        dest="in_elem",
        help="Input elements to consider in TEA [default: %(default)s]",
        type=str,
        action="store",
        default='H He C N O')
    group.add_argument(
        "--out_spec",
        dest="out_spec",
        help="Output species to include in the atmospheric model "
        "[default: %(default)s]",
        type=str,
        action="store",
        default='H_g He_ref C_g N_g O_g H2_ref CO_g CO2_g CH4_g H2O_g')
    group.add_argument(
        "--preatm_file",
        dest="preatm_file",
        help="Pre-atmospheric file with elemental abundances per layer "
        "[default: %(default)s]",
        type=str,
        action="store",
        default="elem.atm")
    group.add_argument("--atmfile",
                       dest="atmfile",
                       help="Atmospheric model file [default: %(default)s]",
                       type=str,
                       action="store",
                       default="")
    group.add_argument(
        "--uniform",
        dest="uniform",
        help="If not None, set uniform abundances with the specified "
        "values for each species in out_spec [default: %(default)s]",
        type=mu.parray,
        action="store",
        default=None)
    group.add_argument(
        "--refpress",
        dest="refpress",
        help="Reference pressure level (bar) corresponding to the pressure"
        " at the planet radius [default: %(default)s]",
        type=float,
        action="store",
        default=0.1)
    group.add_argument("--cloudtop",
                       action="store",
                       help="Cloud deck top pressure [default: %(default)s]",
                       dest="cloudtop",
                       type=float,
                       default=None)
    group.add_argument("--scattering",
                       action="store",
                       help="Rayleigh scattering [default: %(default)s]",
                       dest="scattering",
                       type=float,
                       default=None)

    # MCMC options:
    group = parser.add_argument_group("MCMC")
    group.add_argument("--params",
                       dest="params",
                       help="Model-fitting parameters [default: %(default)s]",
                       type=mu.parray,
                       action="store",
                       default=None)
    group.add_argument(
        "--parnames",
        dest="parnames",
        help="Labels for model-fitting parameters [default: %(default)s]",
        type=mu.parray,
        action="store",
        default=None)
    group.add_argument("--molfit",
                       dest="molfit",
                       help="Molecules fit [default: %(default)s]",
                       type=mu.parray,
                       action="store",
                       default=None)
    group.add_argument(
        "--Tmin",
        dest="Tmin",
        help="Lower Temperature boundary [default: %(default)s]",
        type=float,
        action="store",
        default=400.0)
    group.add_argument(
        "--Tmax",
        dest="Tmax",
        help="Higher Temperature boundary [default: %(default)s]",
        type=float,
        action="store",
        default=3000.0)
    group.add_argument("--quiet",
                       dest="quiet",
                       help="Set verbosity level to minimum",
                       action="store_true")
    group.add_argument("--nchains",
                       dest="nchains",
                       help="Number of parallel chains for MCMC",
                       type=int,
                       action="store",
                       default=10)
    group.add_argument("--walk",
                       dest="walk",
                       help="MCMC algorithm",
                       type=str,
                       action="store",
                       default="snooker",
                       choices=('snooker', 'mrw', 'demc', 'unif'))
    group.add_argument("--stepsize",
                       dest="stepsize",
                       help="Parameters stepsize",
                       type=mu.parray,
                       action="store",
                       default=None)
    group.add_argument("--burnin",
                       dest="burnin",
                       help="Number of burn-in iterations per chain",
                       type=int,
                       action="store",
                       default=None)
    group.add_argument(
        "--thinning",
        dest="thinning",
        help="Thinning factor of the chains (use every thinning-th "
        "iteration) used in the GR test and plots",
        type=int,
        action="store",
        default=1)
    group.add_argument("--data",
                       dest="data",
                       help="Transit or eclipse depths",
                       type=mu.parray,
                       action="store",
                       default=None)
    group.add_argument("--uncert",
                       dest="uncert",
                       help="Uncertanties on transit or eclipse depths",
                       type=mu.parray,
                       action="store",
                       default=None)
    group.add_argument("--savemodel",
                       dest="savemodel",
                       help="Filename to save out models.",
                       type=str,
                       action="store",
                       default=None)
    group.add_argument("--modelper", dest="modelper",
             help="Determines how to split MC3's `savemodel`. " + \
                  "0 makes no split, >0 sets the # of iterations per split. " + \
                  "If nchains=10 and modelper=5, it will save every 50 " + \
                  "models to a new .NPY file.",
             type=int,       action="store", default=0)
    group.add_argument("--plots",
                       dest="plots",
                       help="Determines whether to produce plots.",
                       type=bool,
                       action="store",
                       default=True)

    # Input converter options:
    group = parser.add_argument_group("Input Converter Options")
    group.add_argument(
        "--tint",
        dest="tint",
        help="Internal temperature of the planet [default: %(default)s].",
        type=float,
        action="store",
        default=100.0)
    group.add_argument("--tint_type", dest="tint_type",
             help="Method to evaluate `tint`. Options: const or thorngren. " + \
                  "[default: %(default)s].",
             type=str,   action="store", default='const',
             choices=("const","thorngren"))

    # Output-Converter Options:
    group = parser.add_argument_group("Output Converter Options")
    group.add_argument("--filters",
                       action="store",
                       help="Waveband filter names [default: %(default)s]",
                       dest="filters",
                       type=mu.parray,
                       default=None)
    group.add_argument("--kurucz_file",
                       action="store",
                       help="Stellar Kurucz file [default: %(default)s]",
                       dest="kurucz",
                       type=str,
                       default=None)
    group.add_argument("--solution",
                       action="store",
                       help="Solution geometry [default: %(default)s]",
                       dest="solution",
                       type=str,
                       default="None",
                       choices=('transit', 'eclipse'))

    # Transit options:
    group = parser.add_argument_group("Transit variables")
    group.add_argument(
        "--tconfig",
        dest="tconfig",
        help="Transit configuration file [default: %(default)s]",
        type=str,
        action="store",
        default="transit.cfg")
    group.add_argument("--opacityfile",
                       dest="opacityfile",
                       help="Opacity table file [default: %(default)s]",
                       type=str,
                       action="store",
                       default=None)
    group.add_argument("--outspec",
                       dest="outspec",
                       help="Output spectrum filename [default: %(default)s]",
                       type=str,
                       action="store",
                       default="outspec.dat")
    group.add_argument(
        "--shareOpacity",
        dest="shareOpacity",
        help="If True, use shared memory for the Transit opacity file "
        "[default: %(default)s]",
        type=eval,
        action="store",
        default=True)

    # Remaining_argv contains all other command-line-arguments:
    cargs, remaining_argv = cparser.parse_known_args()
    # Get only the arguments defined above:
    known, unknown = parser.parse_known_args(remaining_argv)

    # Get configuration file from command-line:
    cfile = cargs.config_file
    # Default:
    if cfile is None:
        cfile = os.path.join(os.getcwd(), "BART.cfg")
    # Always require a configuration file:
    if not os.path.isfile(cfile):
        mu.error("Configuration file: '{:s}' not found.".format(cfile))

    # Read values from configuration file:
    config = ConfigParser()
    config.optionxform = str  # This one enable Uppercase in arguments
    config.read([cfile])
    defaults = dict(config.items("MCMC"))
    mu.msg(1, "The configuration file is: '{:s}'.".format(cfile), indent=2)

    # Set the defaults from the configuration file:
    parser.set_defaults(**defaults)
    # Set values from command line:
    args, unknown = parser.parse_known_args(remaining_argv)

    # Unpack configuration-file/command-line arguments:
    justTEA = args.justTEA
    justOpacity = args.justOpacity
    justPlots = args.justPlots
    resume = args.resume

    loc_dir = args.loc_dir
    fext = args.fext
    tep_name = args.tep_name
    logfile = args.logfile

    n_layers = args.n_layers
    p_top = args.p_top
    p_bottom = args.p_bottom
    log = args.log
    press_file = args.press_file

    abun_basic = args.abun_basic
    abun_file = args.abun_file
    solar_times = args.solar_times
    COswap = args.COswap
    cloud = args.cloudtop
    rayleigh = args.scattering

    PTtype = args.PTtype
    PTinit = args.PTinit

    in_elem = args.in_elem
    out_spec = args.out_spec
    preatm_file = args.preatm_file
    atmfile = args.atmfile
    uniform = args.uniform
    refpress = args.refpress

    params = args.params
    parnames = args.parnames
    molfit = args.molfit
    Tmin = args.Tmin
    Tmax = args.Tmax
    quiet = args.quiet
    nchains = args.nchains
    walk = args.walk
    stepsize = args.stepsize
    burnin = args.burnin
    thinning = args.thinning
    data = args.data
    uncert = args.uncert
    savemodel = args.savemodel
    modelper = args.modelper
    plots = args.plots

    tint = args.tint
    tint_type = args.tint_type

    filters = args.filters
    kurucz = args.kurucz
    solution = args.solution

    tconfig = args.tconfig
    opacityfile = args.opacityfile
    outspec = args.outspec
    shareOpacity = args.shareOpacity

    # Unpack the variables from args:
    '''
  argd = {}
  for key, val in vars(args).items():
    if type(val) == str and val in ['True', 'False', 'None']:
      if val == 'True':
        argd.update({key:True})
      elif val == 'False':
        argd.update({key:False})
      elif val == 'None':
        argd.update({key:None})
    else:
      argd.update({key:val})
  vars(sys.modules[__name__]).update(argd)
  '''

    # Dictionary of functions to calculate temperature for PTtype
    PTfunc = {
        'iso': pt.PT_iso,
        'line': pt.PT_line,
        'madhu_noinv': pt.PT_NoInversion,
        'madhu_inv': pt.PT_Inversion
    }

    # Check that the user gave a valid PTtype:
    if PTtype not in PTfunc.keys():
        print("The specified 'PTtype' is not valid. Options are 'line', " + \
              "'madhu_noinv', 'madhu_inv', or 'iso'. Please try again.")
        sys.exit()

    # Check that out_spec and uniform are valid specifications
    if uniform is not None and len(uniform) != len(out_spec.split(' ')):
        print('The inputs for out_spec and uniform are not compatible.')
        diffuniout = len(uniform) - len(out_spec.split(' '))
        if diffuniout > 0:
            if diffuniout == 1:
                print('uniform has ' + str(diffuniout) + 'extra entry.')
            else:
                print('uniform has ' + str(diffuniout) + 'extra entries.')
        else:
            if diffuniout == -1:
                print('out_spec has ' + str(-1 * diffuniout) + 'extra entry.')
            else:
                print('out_spec has ' + str(-1 * diffuniout) +
                      'extra entries.')
        print('Please correct this and run again.')
        sys.exit()

    # Make output directory:
    # Make a subdirectory with the date and time
    dirfmt = loc_dir + "%4d-%02d-%02d_%02d:%02d:%02d"
    date_dir = dirfmt % time.localtime()[0:6]
    # FINDME: Temporary hack (temporary?):
    date_dir = os.path.join(os.path.normpath(loc_dir), "")
    if not os.path.isabs(date_dir):
        date_dir = os.path.join(os.getcwd(), date_dir)
    mu.msg(1, "Output folder: '{:s}'".format(date_dir), indent=2)
    try:
        os.mkdir(date_dir)
    except OSError as e:
        if e.errno == 17:  # Allow overwritting while we debug
            pass
        else:
            mu.error("Cannot create folder '{:s}'. {:s}.".format(
                date_dir, os.strerror(e.errno)))
    # Copy files to date dir:
    # BART configuration file:
    shutil.copy2(cfile, date_dir)
    # TEP file:
    if not os.path.isfile(tep_name):
        mu.error("Tepfile ('{:s}') Not found.".format(tep_name))
    else:
        shutil.copy2(tep_name, date_dir + os.path.basename(tep_name))

    # Check if files already exist:
    runMCMC = 0  # Flag that indicate which steps to run
    if justPlots:
        mu.msg(1, "\nRe-making output plots.", indent=0)
        runMCMC |= 16
    # Atmospheric file:
    if os.path.isfile(atmfile):
        fatmfile = os.path.realpath(atmfile)
        shutil.copy2(fatmfile, date_dir + os.path.basename(fatmfile))
        mu.msg(1,
               "Atmospheric file copied from: '{:s}'.".format(fatmfile),
               indent=2)
        runMCMC |= 8
    atmfile = date_dir + os.path.basename(atmfile)
    # Pre-atmospheric file:
    if os.path.isfile(preatm_file):
        fpreatm_file = os.path.realpath(preatm_file)
        shutil.copy2(fpreatm_file, date_dir + os.path.basename(fpreatm_file))
        mu.msg(
            1,
            "Pre-atmospheric file copied from: '{:s}'.".format(fpreatm_file),
            indent=2)
        runMCMC |= 4
    # Elemental-abundances file:
    if abun_file is not None and os.path.isfile(abun_file):
        shutil.copy2(abun_file, date_dir + os.path.basename(abun_file))
        mu.msg(
            1,
            "Elemental abundances file copied from: '{:s}'.".format(abun_file),
            indent=2)
        runMCMC |= 2
    # Pressure file:
    if press_file is not None and os.path.isfile(press_file):
        shutil.copy2(press_file, date_dir + os.path.basename(press_file))
        mu.msg(1,
               "Pressure file copied from: '{:s}'.".format(press_file),
               indent=2)
        runMCMC |= 1

    press_file = date_dir + os.path.basename(press_file)
    # Generate files as needed:
    if runMCMC < 1:  # Pressure file
        mp.makeP(n_layers, p_top, p_bottom, press_file, log)
        mu.msg(1, "Created new pressure file.", indent=2)

    # Make uniform-abundance profiles if requested:
    if uniform is not None and runMCMC < 8:
        # Calculate the temperature profile:
        temp = ipt.initialPT2(date_dir, PTinit, press_file, PTtype,
                              PTfunc[PTtype], tep_name)
        # Generate the uniform-abundance profiles file:
        mat.uniform(atmfile, press_file, abun_basic, tep_name, out_spec,
                    uniform, temp, refpress)
        # Update the runMCMC flag to skip upcoming steps:
        runMCMC |= 8

    if runMCMC < 2:  # Elemental-abundances file
        mu.msg(1, "CO swap: {}".format(COswap), indent=2)
        mat.makeAbun(abun_basic, date_dir + abun_file, solar_times, COswap)
        mu.msg(1, "Created new elemental abundances file.", indent=2)

    abun_file = date_dir + abun_file

    if runMCMC < 4:  # Pre-atmospheric file
        # Calculate the temperature profile:
        temp = ipt.initialPT2(date_dir,
                              PTinit,
                              press_file,
                              PTtype,
                              PTfunc[PTtype],
                              tep_name,
                              tint_type=tint_type)
        # Choose a pressure-temperature profile
        mu.msg(1, "\nChoose temperature and pressure profile:", indent=2)
        raw_input("  open Initial PT profile figure and\n"
                  "  press enter to continue or quit and choose other initial "
                  "PT parameters.")
        mat.make_preatm(tep_name, press_file, abun_file, in_elem, out_spec,
                        preatm_file, temp)
        mu.msg(1, "Created new pre-atmospheric file.", indent=2)

    if runMCMC < 8:  # Atmospheric file
        # Generate the TEA configuration file:
        mc.makeTEA(cfile, TEAdir)
        # Call TEA to calculate the atmospheric file:
        TEAcall = os.path.join(TEAdir, "tea", "runatm.py")
        TEAout = os.path.splitext(atmfile)[0]  # Remove extension
        # Execute TEA:
        mu.msg(1, "\nExecute TEA:")
        proc = subprocess.Popen([TEAcall, preatm_file, 'TEA'])
        proc.communicate()

        TEAres = os.path.join("TEA", "results", "TEA.tea")
        shutil.copy2(os.path.join(date_dir, TEAres), atmfile)
        # Add radius array:
        mat.makeRadius(out_spec, atmfile, abun_file, tep_name, refpress)
        mu.msg(1, "Added radius column to TEA atmospheric file.", indent=2)
        # Re-format file for use with transit:
        mat.reformat(atmfile)
        mu.msg(1, "Atmospheric file reformatted for Transit.", indent=2)

    if justTEA:
        mu.msg(1, "~~ BART End (after TEA) ~~")
        return

    # Make the MC3 configuration file:
    if runMCMC < 16:  # MCMC
        MCMC_cfile = os.path.join(os.path.realpath(loc_dir),
                                  "MCMC_" + os.path.basename(cfile))
        mc.makeMCMC(cfile, MCMC_cfile, logfile)
        # Make transit configuration file:
        mc.makeTransit(MCMC_cfile, tep_name, shareOpacity)

        # Generate the opacity file if it doesn't exist:
        if not os.path.isfile(opacityfile):
            mu.msg(1, "Transit call to generate the Opacity grid table.")
            Tcall = os.path.join(Transitdir, "transit", "transit")
            subprocess.call(
                ["{:s} -c {:s} --justOpacity".format(Tcall, tconfig)],
                shell=True,
                cwd=date_dir)
        else:
            mu.msg(
                1,
                "\nTransit copies the existing opacity file from:\n '{:s}'.".
                format(opacityfile),
                indent=2)
            shutil.copy2(opacityfile, date_dir + os.path.basename(opacityfile))

    if justOpacity:
        mu.msg(1, "~~ BART End (after Transit opacity calculation) ~~")
        return

    # Run the MCMC:
    if runMCMC < 16:
        MC3call = os.path.join(MC3dir, "MCcubed", "mccubed.py")
        subprocess.call(["mpiexec {:s} -c {:s}".format(MC3call, MCMC_cfile)],
                        shell=True,
                        cwd=date_dir)

    if walk == 'unif' and modelper > 0:
        # Clean up the output directory
        model_dir = os.path.join(date_dir, savemodel.replace('.npy', ''), '')
        # Make directory
        try:
            os.mkdir(model_dir)
        except OSError as e:
            if e.errno == 17:  # Already exists
                pass
            else:
                mu.error("Cannot create folder '{:s}'. {:s}.".format(
                    model_dir, os.strerror(e.errno)))
        # Move model files to subdirectory
        subprocess.call(
            ['mv {:s} {:s}'.format('*'.join(savemodel.split('.')), model_dir)],
            shell=True,
            cwd=date_dir)

    if plots and walk != 'unif':
        # Re-plot MCMC results in prettier format
        mcp.mc3plots('output.npy', burnin, thinning, nchains, uniform, molfit,
                     out_spec, parnames, stepsize, date_dir,
                     ["output_trace", "output_pairwise", "output_posterior"],
                     fext)

        # Run best-fit Transit call
        mu.msg(1, "\nTransit call with the best-fitting values.")

        # MCcubed output file
        MCfile = date_dir + logfile

        # Call bestFit submodule: make new bestFit_tconfig.cfg, run best-fit Transit
        bf.callTransit(atmfile,
                       tep_name,
                       MCfile,
                       stepsize,
                       molfit,
                       cloud,
                       rayleigh,
                       solution,
                       refpress,
                       tconfig,
                       date_dir,
                       burnin,
                       abun_basic,
                       PTtype,
                       PTfunc[PTtype],
                       tint,
                       tint_type,
                       filters,
                       fext=fext)
        # Plot best-fit eclipse or modulation spectrum, depending on solution:
        bf.plot_bestFit_Spectrum(filters, kurucz, tep_name, solution, outspec,
                                 data, uncert, date_dir, fext)

        bestFit_atmfile = 'bestFit.atm'

        # Plot abundance profiles
        bf.plotabun(date_dir, bestFit_atmfile, molfit, fext)

        mu.msg(1, "\nTransit call for contribution functions/transmittance.")
        # Run Transit with unlimited 'toomuch' argument:
        cf.cf_tconfig(date_dir)
        # Call Transit with the cf_tconfig
        cf_tconfig = date_dir + 'cf_tconfig.cfg'
        Tcall = os.path.join(Transitdir, "transit", "transit")
        subprocess.call(["{:s} -c {:s}".format(Tcall, cf_tconfig)],
                        shell=True,
                        cwd=date_dir)

        # Calculate and plot contribution functions:
        if solution == "eclipse":
            # Compute contribution fucntions if this is a eclipse run:
            mu.msg(1, "Calculating contribution functions.", indent=2)
            ctfraw, ctf = cf.cf(date_dir, bestFit_atmfile, filters, fext)
        else:
            # Compute transmittance if this is a transmission run:
            mu.msg(1, "Calculating transmittance.", indent=2)
            ctf = cf.transmittance(date_dir, bestFit_atmfile, filters, fext)

        # Make a plot of MCMC profiles with contribution functions/transmittance
        bf.callTransit(atmfile,
                       tep_name,
                       MCfile,
                       stepsize,
                       molfit,
                       cloud,
                       rayleigh,
                       solution,
                       refpress,
                       tconfig,
                       date_dir,
                       burnin,
                       abun_basic,
                       PTtype,
                       PTfunc[PTtype],
                       tint,
                       tint_type,
                       filters,
                       ctf,
                       fext=fext)

    mu.msg(1, "~~ BART End ~~")