def import_xdi(name): if name[-3:] == 'txt': data_raw = np.loadtxt(name) data = Group() data.energy = data_raw[:,2] data.mu = data_raw[:,8]/data_raw[:,5] else: data_raw = np.loadtxt(name) data = Group() data.energy = data_raw[:,0] data.mu = data_raw[:,1] data.i0 = data_raw[:,2] return data
def gsexdi_deadtime_correct(fname, channelname, subdir='DT_Corrected', bad=None, _larch=None): """convert GSE XDI fluorescence XAFS scans to dead time corrected files""" if not is_GSEXDI(fname): print("'%s' is not a GSE XDI scan file\n" % fname) return out = Group() out.orig_filename = fname try: xdi = read_gsexdi(fname, bad=bad, _larch=_larch) except: print('Could not read XDI file ', fname) return for attr in ('energy', 'i0', 'i1', 'i2', 'tscaler', 'counttime', 'scan_start_time', 'scan_end_time'): if hasattr(xdi, attr): setattr(out, attr, getattr(xdi, attr)) # some scans may not record separate counttime, but TSCALER # is clock ticks for a 50MHz clock if not hasattr(out, 'counttime'): out.counttime = xdi.tscaler * 2.e-8 if hasattr(xdi, 'energy_readback'): out.energy = xdi.energy_readback arrname = None channelname = channelname.lower().replace(' ', '_') for arr in xdi.array_labels: if arr.lower().startswith(channelname): arrname = arr break if arrname is None: print('Cannot find Channel %s in file %s '% (channelname, fname)) return out.ifluor = getattr(xdi, arrname) out.ifluor_raw = getattr(xdi, arrname) arrname_raw = arrname + '_nodtc' if arrname_raw in xdi.array_labels: out.ifluor_raw = getattr(xdi, arrname_raw) out.mufluor = out.ifluor / out.i0 if hasattr(out, 'i1') or hasattr(out, 'itrans'): i1 = getattr(out, 'i1', None) if i1 is None: i1 = getattr(out, 'itrans', None) if i1 is not None: i1 = i1 / out.i0 i1[np.where(i1<2.0e-20)] = 2.0e-20 out.mutrans = -np.log(i1) npts = len(out.energy) buff = ['# XDI/1.0 GSE/1.0'] header = OrderedDict() hgroups = ['beamline', 'facility', 'mono', 'undulator', 'detectors', 'scaler', 'detectorstage', 'samplestage', 'scan', 'scanparameters'] hskip = ['scanparameters.end', 'scanparameters.start'] for agroup in hgroups: attrs = xdi._xdi.attrs.get(agroup, {}) if agroup == 'mono': agroup = 'monochromator' header[agroup] = OrderedDict() for sname in sorted(attrs.keys()): if "%s.%s" %( agroup, sname) not in hskip: header[agroup][sname] = attrs[sname] header['facility']['name'] = 'APS' header['facility']['xray_source'] = '3.6 cm undulator' header['beamline']['name'] = '13-ID-E, GSECARS' header['detectors']['i0'] = '20cm ion chamber, He' header['detectors']['ifluor'] = 'Si SDD Vortex ME-4, 4 elements' header['detectors']['ifluor_electronics'] = 'Quantum Xspress3 3.1.10' mono_cut = 'Si(111)' if xdi.mono_dspacing < 2: mono_cut = 'Si(311)' header['monochromator']['name'] = "%s, LN2 cooled" % mono_cut out_arrays = OrderedDict() out_arrays['energy'] = ('energy', 'eV') out_arrays['mufluor'] = ('mufluor', None) if hasattr(out, 'i1'): out_arrays['mutrans'] = ('mutrans', None) out_arrays['ifluor'] = ('ifluor', '# deadtime-corrected') out_arrays['ifluor_raw'] = ('ifluor_raw', '# not deadtime-corrected') out_arrays['i0'] = ('i0', None) if hasattr(out, 'i1'): out_arrays['itrans'] = ('i1', None) if hasattr(out, 'i2'): out_arrays['irefer'] = ('i2', None) if hasattr(out, 'counttime'): out_arrays['counttime'] = ('counttime', 'sec') arrlabel = [] for iarr, aname in enumerate(out_arrays): lab = "%12s " % aname if iarr == 0: lab = "%11s " % aname arrlabel.append(lab) extra = out_arrays[aname][1] if extra is None: extra = '' buff.append("# Column.%i: %s %s" % (iarr+1, aname, extra)) arrlabel = '#%s' % (' '.join(arrlabel)) ncol = len(out_arrays) for family, fval in header.items(): for attr, val in fval.items(): buff.append("# %s.%s: %s" % (family.title(), attr, val)) buff.append("# ///") for comment in xdi._xdi.comments.split('\n'): c = comment.strip() if len(c) > 0: buff.append('# %s' % c) buff.extend(["# summed %s fluorescence data from %s" % (channelname, fname), "# Dead-time correction applied", "#"+ "-"*78, arrlabel]) efmt = "%11.4f" ffmt = "%13.7f" gfmt = "%13.7g" for i in range(npts): dline = ["", efmt % out.energy[i], ffmt % out.mufluor[i]] if hasattr(out, 'i1'): dline.append(ffmt % out.mutrans[i]) dline.extend([gfmt % out.ifluor[i], gfmt % out.ifluor_raw[i], gfmt % out.i0[i]]) if hasattr(out, 'i1'): dline.append(gfmt % out.i1[i]) if hasattr(out, 'i2'): dline.append(gfmt % out.i2[i]) if hasattr(out, 'counttime'): dline.append(gfmt % out.counttime[i]) buff.append(" ".join(dline)) ofile = fname[:] if ofile.startswith('..'): ofile = ofile[3:] ofile = ofile.replace('.', '_') + '.dat' ofile = os.path.join(subdir, ofile) if not os.path.exists(subdir): os.mkdir(subdir) try: fout = open(ofile, 'w') fout.write("\n".join(buff)) fout.close() print("wrote %s, npts=%i, channel='%s'" % (ofile, npts, channelname)) except: print("could not open / write to output file %s" % ofile) return out
def gsexdi_deadtime_correct(fname, channelname, subdir='DT_Corrected', bad=None, _larch=None): """convert GSE XDI fluorescence XAFS scans to dead time corrected files""" if not is_GSEXDI(fname): print("'%s' is not a GSE XDI scan file\n" % fname) return out = Group() out.orig_filename = fname try: xdi = read_gsexdi(fname, bad=bad, _larch=_larch) except: print('Could not read XDI file ', fname) return for attr in ('energy', 'i0', 'i1', 'i2', 'tscaler', 'counttime', 'scan_start_time', 'scan_end_time'): if hasattr(xdi, attr): setattr(out, attr, getattr(xdi, attr)) # some scans may not record separate counttime, but TSCALER # is clock ticks for a 50MHz clock if not hasattr(out, 'counttime'): out.counttime = xdi.tscaler * 2.e-8 if hasattr(xdi, 'energy_readback'): out.energy = xdi.energy_readback mono_cut = 'Si(111)' if xdi.mono_dspacing < 2: mono_cut = 'Si(311)' header_args = {'mono_dspace': xdi.mono_dspacing, 'mono_cut': mono_cut} arrname = None channelname = channelname.lower().replace(' ', '_') for arr in xdi.array_labels: if arr.lower().startswith(channelname): arrname = arr break if arrname is None: print('Cannot find Channel %s in file %s '% (channelname, fname)) return out.fl_corr = getattr(xdi, arrname) out.fl_raw = getattr(xdi, arrname) arrname_raw = arrname + '_nodtc' if arrname_raw in xdi.array_labels: out.fl_raw = getattr(xdi, arrname_raw) out.mufluor = out.fl_corr / out.i0 npts = len(out.energy) ncol = 6 arrlabel = ['#', ' energy ', ' mufluor ', ' i0 ', ' fluor_dtc', ' fluor_raw', ' counttime'] header = DTC_header % header_args buff = [l.strip() for l in header.split('\n')] has_i1, has_i2 = False, False if hasattr(out, 'i1'): ncol += 1 buff.append('# Column.%i: itrans ' % ncol) arrlabel.append(' itrans ') has_i1 = True if hasattr(out, 'i2'): ncol += 1 buff.append('# Column.%i: irefer ' % ncol) arrlabel.append(' irefer ') has_i2 = True arrlabel = ' '.join(arrlabel) buff.extend(["# Scan.start_time: %s" % out.scan_start_time, "# ///", "# summed %s fluorescence data from %s" % (channelname, fname), "# Dead-time correction applied", "#---------------------------------", arrlabel]) fmt = " %11.3f %15.8f %14.3f %16.5f %14.2f %14.3f" for i in range(npts): dline = fmt % (out.energy[i], out.mufluor[i], out.i0[i], out.fl_corr[i], out.fl_raw[i], out.counttime[i]) if has_i1: dline = "%s %14.3f" % (dline, out.i1[i]) if has_i2: dline = "%s %14.3f" % (dline, out.i2[i]) buff.append(dline) ofile = fname[:] if ofile.startswith('..'): ofile = ofile[3:] ofile = ofile.replace('.', '_') + '.dat' ofile = os.path.join(subdir, ofile) if not os.path.exists(subdir): os.mkdir(subdir) try: fout = open(ofile, 'w') fout.write("\n".join(buff)) fout.close() print("wrote %s, npts=%i, channel='%s'" % (ofile, npts, channelname)) except: print("could not open / write to output file %s" % ofile) return out
from larch import Interpreter, Group # now import larch-specific Python code from larch_plugins.xafs import autobk, xftf # create a larch interpreter, passed to most functions my_larch = Interpreter(with_plugins=False) # create an empty Group xafsdat = Group() # read data (here using np.loadtxt), stick into Group # using "expected names" for XAFS data rawdata = np.loadtxt('../xafsdata/fe2o3_rt1.xmu') xafsdat.energy = rawdata[:, 0] xafsdat.mu = rawdata[:, 1] xafsdat.i0 = rawdata[:, 1] # run autobk on the xafsdat Group, including a larch Interpreter.... # note that this expects 'energy' and 'mu' to be in xafsdat, and will # write data for 'k', 'chi', 'kwin', 'e0', ... into xafsdat autobk(xafsdat, rbkg=1.0, kweight=2, _larch=my_larch) # Fourier transform to R space, again passing in a Group (here, # 'k' and 'chi' are expected, and writitng out 'r', 'chir_mag', # and so on xftf(xafsdat, kmin=2, kmax=15, dk=3, kweight=2, _larch=my_larch) # # plot grid of results: