def subtract_background_from_stacks(scanfile, indir, outdir, scannumber=-1): """Subtract background from SAXS data in MAT-file stacks. """ scans = read_yaml(scanfile) if scannumber > 0: scannos = [ scannumber ] else: scannos = scans.keys() scannos.sort() for scanno in scannos: print("Scan #%03d" % scanno) try: bufscan = scans[scanno][0] except TypeError: print("Scan #%03d is a buffer" % scanno) continue try: conc = scans[scanno][1] except TypeError: print("No concentration for scan #02d." % scanno) conc = 1.0 print("Using concentration %g g/l." % conc) stackname = "s%03d" % scanno stack = loadmat(indir+'/'+stackname+'.mat')[stackname] subs = np.zeros_like(stack) (npos, nrep, _, _) = stack.shape for pos in range(npos): print(pos) buf = get_bg(indir, bufscan, pos) for rep in range(nrep): subs[pos,rep,...] = errsubtract(stack[pos,rep,...], buf) subs[pos,rep,1:3,:] = subs[pos,rep,1:3,:] / conc outname = "subs%03d" % scanno savemat(outdir+'/'+outname + ".mat", {outname: subs}, do_compression=1, oned_as='row')
def subtract_background_from_ydats(scanfile, indir, outdir, scannumber=-1, highqnorm=False): """Subtract backround from SAXS data in .ydat files. If `highqnorm` is True, normalize the buffer to the sample intensity in q-range [4.0, 5.0] 1/nm and adjust with a constant before subtracting. """ scans = read_yaml(scanfile) if scannumber > 0: scannos = [ scannumber ] else: scannos = scans.keys() scannos.sort() for scanno in scannos: print("Scan #%03d" % scanno) try: bufscan = scans[scanno][0] except TypeError: print("Scan #%03d is a buffer" % scanno) continue try: conc = scans[scanno][1] except TypeError: print("No concentration for scan #02d." % scanno) conc = 1.0 print("Using concentration %g g/l." % conc) filelist = glob.glob(indir+"/s%03d.*.fil.ydat" % scanno) for posno in xrange(len(filelist)): bufname = indir + "/bufs%03d.p%02d.out.ydat" % (bufscan, posno) buf, dbuf = read_ydat(bufname, addict=1) fname = indir + "/s%03d.p%02d.fil.ydat" % (scanno, posno) sam, dsam = read_ydat(fname, addict=1) outname = os.path.basename(fname) outname = outdir+'/'+outname[:outname.find('.fil.ydat')]+'.sub.ydat' ad = { 'samfile': [os.path.basename(fname), md5_file(fname)], 'buffile': [os.path.basename(bufname), md5_file(bufname)], 'position' : dsam.get('inputposition', "unknown"), 'q~unit' : dsam.get('q~unit', "unknown"), 'I~unit' : dsam.get('I~unit', "unknown"), 'Ierr~unit' : dsam.get('Ierr~unit', "unknown"), } if highqnorm: # 1 + 0.007 1/(g/l) is the excess of scattered intensity # in a protein sample versus buffer in the q-range # used [4.0, 5.0] 1/nm per concentration. scale = highq_scale(sam, buf) bufscale = scale * 1.0/(1.0 + 0.007*conc) print("scale: %g, bufscale: %g" % (scale, bufscale)) buf[1,:] = bufscale * buf[1,:] buf[2,:] = bufscale * buf[2,:] ad['normalization'] = float(bufscale) else: ad['normalization'] = 'transmission' # Assumes the standard q, I, Ierr ordering in index 0 columns sub = errsubtract(sam, buf) sub[1:3,:] = sub[1:3,:] / conc write_ydat(sub, outname, addict=ad, attributes=['~unit']) print(os.path.basename(outname))
def read_experiment_conf(fname): """Return a dictionary with values read from YAML-format conffile. """ yd = read_yaml(fname) c = {} c['Basedir'] = yd['basedir'] c['Pilatusdir'] = c['Basedir'] + yd['pilatusdir'] c['Eigerdir'] = c['Basedir'] + yd.get('eigerdir', '') c['Expno'] = int(yd['expno']) c['Detno'] = int(yd['detno']) c['Cbfext'] = yd['cbfext'] c['Specfile'] = c['Basedir'] + yd['specfile'] c['Indfile'] = c['Basedir'] + yd['indfile'] return c
def excess_ratio(scanfile, qrange=[4.0, 5.0], cnorm=True): """Return ratio of (sam/buf)-1 in subtractions in the `qrange` given. Subtractions are made from data given in `scanfile` as in 'subtract_background_from_ydats()', but only the ratios of sample / buffer intensity are returned in a list of arrays. If `cnorm` is True (default) then the ratio is normalized to the concentration read from the scanfile. Results from this function can be used to calibrate high-q normalized subtraction. """ scans = read_yaml(scanfile) scannos = scans.keys() scannos.sort() indir = '.' mlist = [] indlist = [] clist = [] for scanno in scannos: try: bufscan = scans[scanno][0] except TypeError: logging.warning("Scan #%03d is a buffer" % scanno) continue try: conc = scans[scanno][1] except TypeError: print("No concentration for scan #02d." % scanno) raise TypeError() logging.warning("Scan #%03d" % scanno) filelist = glob.glob(indir+"/s%03d.*.fil.ydat" % scanno) marr= np.zeros((len(filelist))) for posno in xrange(len(filelist)): bufname = indir + "/bufs%03d.p%02d.out.ydat" % (bufscan, posno) buf, dbuf = read_ydat(bufname, addict=1) fname = indir + "/s%03d.p%02d.fil.ydat" % (scanno, posno) sam, dsam = read_ydat(fname, addict=1) # Assumes the standard q, I, Ierr ordering in index 0 columns q = sam[0,:] qind = np.logical_and(q > qrange[0], q < qrange[1]) ratio = np.mean(sam[1,qind]) / np.mean(buf[1,qind]) - 1.0 if cnorm: ratio = ratio / conc marr[posno] = ratio mlist.append(marr) indlist.append(scanno) clist.append(conc) return mlist, indlist, clist
def stack_files(scanfile, conffile, outdir, modulus=10, eiger=0, matfile=1, scannumber=-1): """Create stacks from scans read from YAML-file `scanfile`. If `matfile` is true (default), write output stacks to a MAT-file. Otherwise writes (slowly) to a YAML-file. """ if not os.path.isdir(outdir): # FIXME: Create the directory raise IOError("Output directory does not exist.") conf = read_experiment_conf(conffile) specscans = read_spec(conf['Specfile']) radind = read_matclean(conf['Indfile'])['radind'] q = radind['q'] if scannumber > 0: scannos = [ scannumber ] else: scans = read_yaml(scanfile) scannos = scans.keys() scannos.sort() for scanno in scannos: outname = "s%03d" % scanno if eiger: stack, fnames, dvals = \ stack_eiger(conf, scanno, specscans, radind, modulus) else: stack, fnames, dvals = \ stack_scan(conf, scanno, specscans, radind, modulus) stack = stack.squeeze() if matfile: outfn = outdir+'/'+outname + ".mat" savemat(outfn, {outname: stack}, do_compression=1, oned_as='row') print("Wrote output to '%s'." % outfn) else: for pos in range(stack.shape[0]): outfn = outname+'.p%02d.all.ydat' % pos write_stack_ydat(outdir+'/'+outfn, stack[pos], fnames[pos], dvals[pos], conf) print("Wrote output to '%s'." % outfn)