• Facebook
  • Twitter
  • Reddit
  • StumbleUpon
  • Digg
  • email

#!/usr/bin/env python
 
# do_raytrace.py
 
# By Nathan C. Hearn
#    December 12, 2006
#
# Front-end script to raytracer program
 
import math
 
# Constants
 
rad_per_deg = math.pi / float(180.0)
 
mpirun_exec = "mpirun"
executable = "~/code/flash/QuickFlash/examples/raytracer/raytracer"
 
# Set up options
 
cylinder_y = float(0.045)
cylinder_z = float(0.045)
 
cylinder_max_radius = float(0.060)
 
cylinder_min_x = float(0.0)
cylinder_max_x = float(0.2)
 
sample_spacing_default = float(0.0001)     # User-defined
 
detector_x_default = float(0.1)            # User-defined
detector_azimuth_default = float(45.0)     # User-defined (in degrees)
 
source_distance = float(1.2)               # 12 mm
source_diameter = float(0.002)             # 20 micron or 10 micron
 
film_distance = float(22.8)                # 228 mm
 
film_size_x = float(5.0)                   # 50 mm (diameter??)
film_size_y = float(5.0)                   # 50 mm (diameter??)
 
film_pixels_x_default = int(2273)          # 22 microns / pixel (??)
film_pixels_y_default = int(2273)          # 22 microns / pixel (??)
 
rays_per_pixel_default = int(10)           # User-defined
 
mpi_processes_default = int(0)
 
# Set up the command line parser
 
def parse_cli() :
 
    from optparse import OptionParser
 
    usage = str("%prog input_file [options]")
    version = str("%prog 0.1")
 
    argParser = OptionParser(usage, version=version)
 
    # sample_spacing
 
    sample_spacing_str = str("sample_spacing")
 
    argParser.add_option("--" + sample_spacing_str, type="float",
                         dest="sample_spacing",
                         help="Spacing between samples on ray (cm)")
 
    argParser.set_defaults(sample_spacing=sample_spacing_default)
 
    # detector x-coordinate
 
    detector_x_str = str("detector_x")
 
    argParser.add_option("--" + detector_x_str, type="float",
                         dest="detector_x",
                         help="Detector axis x-coordinate (cm)")
 
    argParser.set_defaults(detector_x=detector_x_default)
 
    # detector azimuth
 
    detector_azimuth_str = str("detector_azimuth")
 
    argParser.add_option("--" + detector_azimuth_str, type="float",
                         dest="detector_azimuth",
                         help="Azimuthal angle of detector axis (deg)")
 
    argParser.set_defaults(detector_azimuth=detector_azimuth_default)
 
    # Film pixels along cylinder axis
 
    film_pixels_x_str = str("film_pixels_x")
 
    argParser.add_option("--" + film_pixels_x_str, type="int",
                         dest="film_pixels_x",
                         help="Film pixels along cylinder axis")
 
    argParser.set_defaults(film_pixels_x=film_pixels_x_default)
 
    # Film pixels along transvers axis
 
    film_pixels_y_str = str("film_pixels_y")
 
    argParser.add_option("--" + film_pixels_y_str, type="int",
                         dest="film_pixels_y",
                         help="Film pixels along cylinder axis")
 
    argParser.set_defaults(film_pixels_y=film_pixels_y_default)
 
    # Rays per pixel
 
    rays_per_pixel_str = str("rays_per_pixel")
 
    argParser.add_option("--" + rays_per_pixel_str, type="int",
                         dest="rays_per_pixel",
                         help="Number of rays per pixel")
 
    argParser.set_defaults(rays_per_pixel=rays_per_pixel_default)
 
    # Rays per pixel
 
    mpi_processes_str = str("mpi_processes")
 
    argParser.add_option("--" + mpi_processes_str, type="int",
                         dest="mpi_processes",
                         help="Number of parallel processes (zero if no MPI)")
 
    argParser.set_defaults(mpi_processes=mpi_processes_default)
 
    # Parse the command line
 
    opts, args = argParser.parse_args()
 
    return opts, args
 
 
# Run the program
 
def main() :
 
    from sys import exit, stdout, stderr
    from os import system
 
    opts, args = parse_cli()
 
    minArgs = int(1)
 
    if (len(args) < minArgs) :
        # argParser.print_help()
        stderr.write("Improper number of arguments (see --help)\n")
        exit()
 
    # Parse required arguments (input_file)
 
    argPtr = int(0)
 
    input_file = str(args[argPtr])
    argPtr += 1
 
    # Parse options
 
    sample_spacing = opts.sample_spacing
 
    detector_x = opts.detector_x
    detector_azimuth_deg = opts.detector_azimuth
 
    detector_azimuth = detector_azimuth_deg * rad_per_deg
 
    film_pixels_x = opts.film_pixels_x
    film_pixels_y = opts.film_pixels_y
 
    rays_per_pixel = opts.rays_per_pixel
 
    mpi_processes = opts.mpi_processes
 
    use_mpi = False
 
    if (mpi_processes > 0) :
        use_mpi = True
 
    # A few other quantities
 
    source_radius = 0.5 * source_diameter
 
    # Collect the input values for logging
 
    parmstr = list()
 
    parmstr.append("Raytracer executable [ " + executable + " ]")
 
    parmstr.append("Input file [ " + input_file + " ]")
 
    parmstr.append("Cylinder axis y-coord [ " + str(cylinder_y) + " cm ]")
    parmstr.append("Cylinder axis z-coord [ " + str(cylinder_z) + " cm ]")
 
    parmstr.append("Cylinder max radius [ " + str(cylinder_max_radius)
                   + " cm ]")
 
    parmstr.append("Cylinder min x-coord [ " + str(cylinder_min_x) + " cm ]");
    parmstr.append("Cylinder max x-coord [ " + str(cylinder_max_x) + " cm ]");
 
    parmstr.append("Sample spacing along ray [ " + str(sample_spacing)
                   + " cm ]")
 
    parmstr.append("Detector axis x-coord [ " + str(detector_x) + " cm ]")
    parmstr.append("Detector axis azimuthal angle [ "
                   + str(detector_azimuth_deg) + " deg ]")
 
    parmstr.append("Source distance [ " + str(source_distance) + " cm ]")
    parmstr.append("Source diameter [ " + str(source_diameter) + " cm ]")
 
    parmstr.append("Film distance [ " + str(film_distance) + " cm ]")
 
    parmstr.append("Film size along cylinder axis [ " + str(film_size_x)
                   + " cm ]")
    parmstr.append("Film size along transverse axis [ " + str(film_size_y)
                   + " cm ]")
 
    parmstr.append("Film pixels along cyilnder axis [ " + str(film_pixels_x)
                   + " ] - " + str(1.0e+4 * film_size_x / float(film_pixels_x))
                   + " microns / pixel")
    parmstr.append("Film pixels along transverse axis [ " + str(film_pixels_y)
                   + " ] - " + str(1.0e+4 * film_size_y / float(film_pixels_x))
                   + " microns / pixel")
 
    parmstr.append("Rays per pixel [ " + str(rays_per_pixel) + " ]")
 
    if (use_mpi) :
        parmstr.append("MPI processes [ " + str(mpi_processes) + " ]")
        parmstr.append("MPI exec [ " + str(mpirun_exec) + " ]")
 
    # Log the parameters
 
    for entry in parmstr :
        stderr.write(entry + "\n")
        stdout.write("# " + entry + "\n")
 
    # Run the program
 
    full_exec = None
 
    if (use_mpi) :
        full_exec = mpirun_exec + " -np " + str(mpi_processes) + " " \
                    + executable
    else :
        full_exec = executable
 
    exec_str = full_exec + " " + input_file + " " + str(cylinder_y) + " " \
               + str(cylinder_z) + " " + str(cylinder_max_radius) + " " \
               + str(cylinder_min_x) + " " + str(cylinder_max_x) + " " \
               + str(sample_spacing) + " " \
               + str(detector_x) + " " + str(detector_azimuth) + " " \
               + str(source_distance) + " " + str(source_radius) + " " \
               + str(film_distance) + " " \
               + str(film_size_x) + " " + str(film_size_y) + " " \
               + str(film_pixels_x) + " " + str(film_pixels_y) + " " \
               + str(rays_per_pixel)
 
    stderr.write("\n")
    stderr.write("Executing command:\n")
    stderr.write("  " + exec_str + "\n")
 
    stdout.write("#\n")
    stdout.write("# Command [ " + exec_str + " ]\n")
 
    system(exec_str)
 
 
if (__name__ == "__main__") :
    main()