Exemplo n.º 1
0
def profile_main():
  DEFAULT_CACHE = ".radialx/cache"
  header()
  parser = doopts()
  (options, args) = parser.parse_args()

  try:
    config_file = args[0]
  except IndexError:
    usage(parser, 'No config file specified.')

  tk = TK.Tk()
  tk.title('profilex')
  tk.protocol("WM_DELETE_WINDOW", sys.exit)
  plot_f = TK.Frame(tk, relief=TK.RIDGE, border=2)
  plot_f.pack(side=TK.TOP, fill=TK.BOTH, expand=TK.YES)
  qb = TK.Button(tk, fg="#aa0000",
                     text="Quit", cursor="hand2",
                     command=sys.exit)
  qb.pack()
  task_pane = TK.Frame(tk)
  task_pane.pack(expand=TK.NO, fill=TK.X)
  statusvar = TK.StringVar()
  status = TK.Label(task_pane, textvariable=statusvar,
                               justify=TK.LEFT)
  status.pack(expand=TK.NO, fill=TK.BOTH, side=TK.LEFT)
  pb_f = TK.Frame(tk, relief=TK.RIDGE, border=2)
  pb_f.pack(side=TK.TOP, fill=TK.BOTH, expand=TK.NO)
  task_svar = TK.StringVar()
  TK.Label(tk, width=70, textvariable=task_svar).pack(side=TK.TOP)
  task_pb = PB(tk, svar=task_svar, height=8)
  task_pb.pack(side=TK.TOP, expand=TK.NO, fill=TK.BOTH)
  job_svar = TK.StringVar()
  TK.Label(tk, width=70, textvariable=job_svar).pack(side=TK.TOP)
  job_pb = PB(tk, job_svar, height=8)
  job_pb.pack(side=TK.TOP, expand=TK.NO, fill=TK.BOTH)
  # TK.Button(tk, text='Quit', command=tk.destroy).pack(side=TK.TOP)
  tk.update_idletasks()

  cfg = _radialx.load_config(config_file)
  general = cfg['general']
  spectradb = _radialx.load_config(general['spec_db'])

  # interpolate fields for spectra (e.g. %latest%)
  spec_dir = general['spec_dir']
  suffix = ("yml", "yaml", "spec", "json")
  field = "%latest%"
  latest = None
  for key, spec in spectradb.items():
    if spec['filename'] == field:
      if latest is None:
        latest = last_made(dirpath=spec_dir, suffix=suffix)
      spec['filename'] = latest

  imagesdb = _radialx.load_config(general['img_db'])

  if general['cache'] is None:
    cache = DEFAULT_CACHE
  else:
    cache = general['cache']
  cache = pyfscache.FSCache(cache)

  if general['mode'] == "averaging":
    config = cfg['averaging']
    groups_img = _radialx.load_config(general['img_groups'])
    groups_img = groups_img['images']
    groups_spec = _radialx.load_config(general['spec_groups'])
    groups_spec = groups_spec['spectra']
    cfg['groups'] = {'images' : groups_img, 'spectra' : groups_spec}
    spectra = _radialx.get_spectra(cfg, spectradb, "averaging")
    images = _radialx.get_images(cfg, imagesdb, "averaging")
    pltcfg = _radialx.load_config(config['plot_config'])
    plt = MyXYPlot(master=plot_f,
                   figsize=pltcfg['plot_size'],
                   dpi=pltcfg['dpi'])
    sp = _radialx.load_spectra(config, spectra)
    sp_values = sp.values()
    ms = _radialx.averages(config, images,
                                  pltcfg=pltcfg,
                                  plt=plt,
                                  job=job_pb.update,
                                  task=task_pb.update,
                                  cache=cache)
    ms_values = ms.values()
    TCs = sp_values + ms_values
    _radialx.sharpnesses(config, TCs)
    # if ((config['scaled_to'] is not None) and
    #     (len(images) + len(spectra) == 2)):
    if config['scaled_to'] is not None:
      if len(images) + len(spectra) == 2:
        db = SQLite.Database(general['score_db'])
        title = "Model Name"
        table = db.create("scores",
                          # pdb model that produced spectrum
                          ("model", TEXT),
                          # key from image database
                          ("image_key", TEXT),
                          # Ro score for the scaling
                          ("score", REAL),
                          # R**2 statistic
                          ("Rsq", REAL),
                          # fitted alpha scaling parameter
                          ("alpha", REAL),
                          # fitted m scaling parameter
                          ("m", REAL),
                          # fitted b scaling parameter
                          ("b", REAL),
                          # fitted B scaling parameter
                          ("Bfac", REAL),
                          # json of the image entry from the images db
                          ("image", TEXT),
                          # base64 of bz2 of model pdb file
                          ("pdb", TEXT),
                          # base64 of numpy serialized spectrum array
                          # in [ 2-theta, intensity ] pairs
                          ("spectrum", TEXT),
                          # json of the profilex averaging config section
                          ("config", TEXT),
                          # json of the profilex general config section
                          ("general", TEXT),
                          mode="open")

        if options.model is not None:
          if os.path.exists(options.model):
            options.model = None
          elif table(model=options.model):
            options.model = None
        title = "Unique Model Name"
        latest_pdb = last_made(dirpath=general['model_dir'],
                               suffix=".pdb")
        while options.model is None:
          options.model = askopenfilename(
                                    title=title,
                                    parent=tk,
                                    filetypes=[("PDB", "*.pdb")],
                                    initialdir=general['model_dir'],
                                    initialfile=latest_pdb)
          if not options.model:
            msg = "Must proceed with a\nunique model name.\n\nContinue?"
            if askyesno("Continue", msg, parent=tk):
              options.model = None
            else:
              sys.exit()
          else:
            rows = table(model=options.model)
            if rows:
              bn = os.path.basename(options.model)
              tplt = ("Model name '%s'\nis not unique.\n\n" +
                      "Overwrite score?")
              msg = tplt % bn
              overwrite = askyesnocancel("Overwrite Score", msg)
              if overwrite is None:
                options.model = None
              elif overwrite:
                if len(rows) > 1:
                  msg = ("%s Records with model\nnamed '%s'.\n\n" +
                         "Erase all?") % (len(rows), bn)
                  if askyesno("Erase Records", msg, parent=tk):
                    for row in rows:
                      del table[row['__id__']]
                  else:
                    config['save_score'] = False
              else:
                config['save_score'] = False
      else:
        table = None
        options.model = None
      config['pdb_model'] = options.model
      T = None
      Cs = []
      for TC in TCs:
        if TC['image_key'] == config['scaled_to']:
          T = TC
        else:
          Cs.append(TC)
      std_outlet = StdOutlet(tk)
      if T is None:
        tplt = "Unrecognized value for scaled_to: %s"
        msg = tplt % config['scaled_to']
        raise _radialx.ConfigError(msg)
      _radialx.scale_several(config, Cs, T, general, std_outlet, table)
    msc = ms.copy()
    msc.update(sp)
    spmsc = msc.reversed()
    nimgs = _radialx.plot_images(plt, spmsc, config, pltcfg, 0)
    statusvar.set("%s Images Processed and Plotted" % nimgs)
    task_pb.deactivate()
    job_pb.deactivate()
  elif general['mode'] == "difference":
    config = cfg['difference']
    if config['scaling_target'] in ("NONE", "None", "none", None):
      config['scaling_target'] = None
    config['images'] = [config['negative'], config['positive']]
    # adapting difference config to averaging config
    # maybe just change the settings file format?
    config['scaled_to'] = config['negative']
    config['roi'] = config['limits']
    config['roi_bins'] = config['bins']
    config['img_bins'] = config['bins']
    config['norm_type'] = None
    config['stretch'] = False
    config['do_norm'] = False
    config['smooth_spectra'] = False
    images = _radialx.get_images(cfg, imagesdb, "difference")
    keys = [k for (k, d) in images]
    pltcfg = _radialx.load_config(config['plot_config'])
    plt = MyXYPlot(master=plot_f,
                   figsize=pltcfg['plot_size'],
                   dpi=pltcfg['dpi'])
    plt2 = MyXYPlot(master=plot_f,
                   figsize=pltcfg['plot_size'],
                   dpi=pltcfg['dpi'],
                   sibling=plt)
    # _radialx.plot_spectra(config, spectra, pltcfg, plt, cache=cache)
    ms = _radialx.averages(config, images,
                                   pltcfg=pltcfg,
                                   plt=plt,
                                   job=job_pb.update,
                                   task=task_pb.update,
                                   cache=cache)
    TCs = ms.values()
    if TCs[0]['image_key'] == config['scaled_to']:
      T = TCs[0]
      C = TCs[1]
    else:
      T = TCs[1]
      C = TCs[0]
    if config['scaling_target'] is None:
      T['scaled'] = T['sum Is']
      C['scaled'] = C['sum Is']
      _radialx.bin_equivalent(T)
      _radialx.bin_equivalent(C)
    else:
      Cs = [C]
      std_outlet = StdOutlet(tk)
      table = None
      _radialx.scale_several(config, Cs, T, general, std_outlet, table)
    msc = ms.copy()
    nimgs = _radialx.plot_images(plt, msc, config, pltcfg, 0)
    statusvar.set("%s Images Processed and Plotted" % nimgs)
    twoths = T['bin middles two-theta']
    avis = C['scaled'] - T['scaled']
    if avis.min() < 0:
      avis = avis - avis.min()
    spectrum_file = config['output'] + ".yml"
    _radialx.write_spectrum(spectrum_file,
                            config['output'], twoths, avis, False)

    # manually build a spec record for load_spectra()
    twoths_degs = T['bin middles two-theta degs']
    record = OrderedDict()
    record["filename"] = spectrum_file
    for k in ["descr", "nickname", "wavelength"]:
      record[k] = config[k]
    record['__filepath__'] = spectrum_file
    pattern = numpy.array([twoths_degs, avis]).T
    record['__data__'] = OrderedDict()
    record['__data__']['model'] = config['output']
    record['__data__']['pattern'] = pattern
    spectra = [(config['key'], record)]
    sp = _radialx.load_spectra(config, spectra)
    nimgs = _radialx.plot_images(plt, sp, config, pltcfg, 0) 
    task_pb.deactivate()
    job_pb.deactivate()
    output = ["\n[%s]" % config['key']]
    for (k, v)  in record.items():
      if not k.startswith("__"):
        try:
          output.append("%s = %f" % (k, float(v)))
        except (ValueError, TypeError):
          output.append("%s = \"%s\"" % (k, v))
    output = "\n".join(output) + "\n"
    std_outlet = StdOutlet(tk)
    std_outlet(output)
  elif general['mode'] == "recentering":
    config = cfg['recentering']
    image = imagesdb[config['recenter_image']]
    plt = MyXYPlot(master=plot_f, figsize=config['plot_size'])

    # result = {"coords" : coords,
    #           "vals" : vals,
    #           "exes" : exes,
    #           "whys" : whys,
    #           "max_xy" : max_xy}

    result = _radialx.recenter(general, config, image,
                                                plt=plt,
                                                job=job_pb.update,
                                                task=task_pb.update,
                                                cache=cache)
    # flip x and y for image space
    # title = "%s\n%s to %s %s (%s px grid)" % params
    title = "%s : %s" % (image['filename'], result['max_xy'])
    factor = (config['bin_factor'], config['bin_factor'])
    # flip exes and whys for image space
    xy_heat(result['coords'], result['vals'],
                              heat_up=1.0/3.0,
                              xlabs=result['exes'],
                              ylabs=result['whys'],
                              title=title)
  else:
    job_pb.update("The mode for the run is not recognized.", 1)

  tk.mainloop()
Exemplo n.º 2
0
def chemfigit(config):
  program = "chemfigit"

  cfg = config.copy()

  # setup logger
  logger = logging.getLogger(program)
  log_level = getattr(logging, cfg['log_level'].upper())
  logger.setLevel(log_level)
  ch = logging.StreamHandler()
  ch.setLevel(log_level)
  formatter = logging.Formatter("%(name)s [%(levelname)s] %(message)s")
  ch.setFormatter(formatter)
  logger.addHandler(ch)

  # setup paths
  cfg['cwd'] = os.getcwd()
  cfg['start_time'] = time.time()
  cfg['temp_base'] = "%014.2f" % cfg['start_time']
  cfg['temp_dir'] = os.path.join(tempfile.gettempdir(),
                                 program,
                                 cfg['temp_base'])
  if cfg['tex_file']:
    cfg['tex_file'] = os.path.abspath(cfg['tex_file'])
    if cfg['dest_dir'] is None:
      cfg['dest_dir'] = os.path.dirname(cfg['tex_file'])
      cfg['abs_dest_dir'] = cfg['dest_dir']
    else:
      cfg['abs_dest_dir'] = os.path.abspath(cfg['dest_dir'])
    logger.info('Using tex file: %(tex_file)s', cfg)
  else:
    if cfg['dest_dir'] is None:
      curdir = os.path.abspath('.')
      cfg['tex_file'] = phyles.last_made(curdir, suffix=".tex",
                                                  depth=cfg['tex_depth'])
      if cfg['tex_file'] is None:
        raise ChemFigitError('No tex file found.')
      cfg['abs_dest_dir'] = os.path.dirname(cfg['tex_file'])
    else:
      cfg['abs_dest_dir'] = os.path.abspath(cfg['dest_dir'])
      cfg['tex_file'] = phyles.last_made(cfg['abs_dest_dir'],
                                               suffix=".tex",
                                               depth=cfg['tex_depth'])
    logger.info('Using newest tex file: %(tex_file)s', cfg)
  cfg['tex_base'] = os.path.basename(cfg['tex_file'])
  cfg['abs_tex_file'] = os.path.abspath(cfg['tex_file'])
  cfg['prefix'] = cfg['tex_base'].rsplit(".", 1)[0]
  cfg['full_pdf_file'] = cfg['prefix'] + ".pdf"

  # create temp dir
  if os.path.exists(cfg['temp_dir']):
    logger.info('Had md5 collision (%s)!', cfg['temp_base'])
    shutil.rmtree(cfg['temp_dir']) # had md5 collision!
  logger.info('Making directory: %s', cfg['temp_dir'])
  os.makedirs(cfg['temp_dir'])

  # create dest dir
  if not os.path.exists(cfg['abs_dest_dir']):
    logger.info('Making directory: %s', cfg['abs_dest_dir'])
    os.makedirs(cfg['abs_dest_dir'])

  # insert tex_includes into TEXINPUTS

  if cfg['tex_includes'] is not None:
    inputs = cfg['tex_includes'].split(":")
    inputs = [os.path.abspath(p) for p in inputs]
    s_inputs = ":".join(inputs)
    os.environ['TEXINPUTS'] = ":".join([s_inputs, os.environ['TEXINPUTS']])
    os.system('echo $TEXINPUTS')
    # raise SystemExit
  
  # do preamble
  if cfg['preamble'] is not None:
    found_preamble = False
    for p in inputs:
      preamble_path = os.path.join(p, cfg['preamble'])
      if os.path.exists(preamble_path):
        cfg['preamble_path'] = preamble_path
        found_preamble = True
        break
    if not found_preamble:
      tplt = "Could not find preamble '%s'."
      msg = tplt % (cfg['preamble'],)
      raise ChemFigitError(msg)
    with open(preamble_path) as f:
      preamble_text = f.read()
    cfg['preamble_base'] = os.path.basename(cfg['preamble'])
    new_preamble_file = os.path.join(cfg['temp_dir'],
                                     cfg['preamble_base'])
    with open(new_preamble_file, "w") as f:
      f.write(preamble_text)


  # copy the tex file
  logger.info("copying %s to %s", cfg['abs_tex_file'],
                                  cfg['temp_dir'])
  shutil.copy(cfg['abs_tex_file'], cfg['temp_dir'])

  # change to the temp dir
  logger.info("Changing dir to %s", cfg['temp_dir'])
  os.chdir(cfg['temp_dir'])

  # create the document file
  cfg['geometry'] = ",".join(["paperwidth=%(paperwidth)s",
                              "paperheight=%(paperheight)s",
                              "margin=%(papermargin)s"]) % cfg
  doc_setup = r"""
               \documentclass[letter,%(font_size)spt]{article}
               \usepackage[%(geometry)s]{geometry}
               \pagestyle{empty}

               \input{%(preamble_base)s}

               \begin{document}
               \input{%(tex_base)s}
               \end{document}
               """
  cfg['doc_setup'] = textwrap.dedent(doc_setup)[1:] % cfg

  cfg['document_prefix'] = cfg['prefix'] + "-document"
  cfg['tex_document'] = cfg['document_prefix'] + ".tex"

  with open(cfg['tex_document'], "w") as f:
    f.write(cfg['doc_setup'])

  # open log files
  cfg['out_log_file'] = open("stdout.log", "w")
  cfg['err_log_file'] = open("stderr.log", "w")

  # run pdflatex
  pdflatex_command = "%(pdflatex)s %(tex_document)s" % cfg
  logger.info('running 1st time: %s', pdflatex_command)
  subprocess.call(pdflatex_command.split(),
                  stdout=cfg['out_log_file'],
                  stderr=cfg['err_log_file'])
  logger.info('running 2nd time: %s', pdflatex_command)
  subprocess.call(pdflatex_command.split(),
                  stdout=cfg['out_log_file'],
                  stderr=cfg['err_log_file'])

  # crop the pdf
  cfg['pdf_file'] = "%(prefix)s.pdf" % cfg
  cfg['document_pdf'] = cfg['document_prefix'] + ".pdf"
  cfg['cropped_pdf_file'] = "%(prefix)s-crop.pdf" % cfg
  pdfcrop_command = ("%(pdfcrop)s --margins %(crop_margin)s " +
                     "%(document_pdf)s %(cropped_pdf_file)s")
  pdfcrop_command = pdfcrop_command % cfg
  logger.info('running: %s', pdfcrop_command)
  subprocess.call(pdfcrop_command.split(),
                  stdout=cfg['out_log_file'],
                  stderr=cfg['err_log_file'])

  # do the outputs
  for output in cfg['output_formats']:
    OUTPUTS[output](cfg, logger)

  # close log files
  cfg['out_log_file'].close()
  cfg['err_log_file'].close()

  # return to cwd
  os.chdir(cfg['cwd'])

  return cfg