def get_data(run=127, threshold=0.05, force=False, ishotref=0, ishotsam=1): fname = "../data/fig_focusing_run%04d.h5" % run if not os.path.isfile(fname) or force: # this functions splits the data based on FOM < 0.5 --> p1 is the ref, p2 is the sample data = xppl37_spectra.calcSpectraForRun(run, force) idx = data.run.results[0].fom < 0.5 E = data.run.E ref = ds.DataStorage(E=E, p1=data.p1[0], p2=data.p2[0]) sample = ds.DataStorage(E=E, p1=data.p1[1], p2=data.p2[1]) _, _, Abs = xppl37_spectra.calcAbs(ref, ref, threshold=threshold) ref.Abs = Abs _, _, Abs = xppl37_spectra.calcAbs(ref, sample, threshold=threshold) sample.Abs = Abs temp = ds.DataStorage(ref=ref, sample=sample) temp.info = "Abs calculated with threshold = %.3f" % threshold temp.save(fname) print('maybe forced to calculate again the Spectra to get idx_fom') data = ds.read(fname) ref = data.ref sample = data.sample _, _, Abs = xppl37_spectra.calcAbs(ref, ref, threshold=threshold) ref.Abs = Abs _, _, Abs = xppl37_spectra.calcAbs(ref, sample, threshold=threshold) sample.Abs = Abs data = ds.DataStorage(ref=ref, sample=sample) data["threshold"] = threshold return data, idx
def saveAndRead(obj,fname="/tmp/test.h5",link_copy=False): obj = datastorage.DataStorage(obj) t0 = time.time() obj.save(fname,link_copy=link_copy,raiseError=True) t1 = time.time() obj1 = datastorage.read(fname) # for k in obj: # print(" %s %s %s"%(k,str(obj[k])[:10],str(obj1[k])[:10])) t2 = time.time() return t2-t1,t1-t0
def get_data(run=82,calib=1,threshold=0.02,force=False): fname = "../data/fig_fe_xas_run%04d.h5" % run if not os.path.isfile(fname) or force: E,p1,p2,Abs=xppl37_spectra.calcAbsForRun(run,merge_calibs=True,threshold=threshold) temp = ds.DataStorage( E=E,p1=p1,p2=p2,Abs=Abs) temp.info="Abs calculated with threshold = %.3f" % threshold temp.save(fname) data = ds.read(fname) # nan is saved as -1 for masked arrays for k in data.keys(): try: data[k][data[k]==-1] =np.nan except TypeError: pass return data
def get_data(runs=(155,156),threshold=0.02,force=False): run_hash = "_".join(map(str,runs)) fname = "../data/fig_fe_xas_runs_%s.h5" % run_hash if not os.path.isfile(fname) or force: E,p1,p2,Abs=xppl37_spectra.calcAbsForRun(runs,merge_calibs=True,threshold=threshold) temp = ds.DataStorage( E=E,p1=p1,p2=p2,Abs=Abs) temp.info="Abs calculated with threshold = %.3f" % threshold temp.save(fname) data = ds.read(fname) # nan is saved as -1 for masked arrays for k in data.keys(): try: data[k][data[k]==-1] =np.nan except TypeError: pass # for runs 155,156 the vernier stopped working after shots ~ 2000 if runs == (155,156): data.p1=data.p1[:2000] data.p2=data.p2[:2000] data.Abs=data.Abs[:2000] return data
def get_data(run, threshold=0.02, force=False): if run == 80: refCalibs = slice(1, None, 2) elif run == 84: refCalibs = slice(None, None, 2) elif run == 60: refCalibs = slice(None, None, 2) elif run == 76: refCalibs = slice(None, None) else: refCalibs = slice(None, None, 2) fname = "../data/fig_fel_modes_run%04d.h5" % run if not os.path.isfile(fname) or force: r = xanes_analyzeRun.AnalyzeRun(run=run) r.load() E = r.E calibs = list(r.results.keys()) calibs.sort() calibs = calibs[refCalibs] p1 = np.vstack([r.results[c].p1 for c in calibs]) p2 = np.vstack([r.results[c].p2 for c in calibs]) #temp = ds.DataStorage( E=E,p1=p1.astype(np.float16),p2=p2.astype(np.float16)) temp = ds.DataStorage(E=E, p1=p1, p2=p2) _, _, Abs = xppl37_spectra.calcAbs(temp, threshold=0.02) temp.Abs = Abs #.astype(np.float16) temp.info = "Abs calculated with threshold = 0.02" temp.save(fname) data = ds.read(fname) # nan is saved as -1 for masked arrays for k in data.keys(): try: data[k][data[k] == -1] = np.nan except (TypeError, AttributeError): pass print("Run %d → nshots = %d" % (run, len(data.p1))) p1, p2, Abs = xppl37_spectra.calcAbs(data, threshold=threshold) data.Abs = Abs return data
def read_2dscan(fname,keys="all"): data = datastorage.read(fname) if data.info.num_motors != 2: print("Did not find 2 motors names in num_motors") return size = list(_get_npoints(data.info.positions)) #size = list(data.npoints_per_axis) for iaxis,axis in enumerate(data.info.motors): data[axis] = data.info.positions[:,iaxis].reshape(size) if iaxis == 1: data[axis+"_1d"] = data[axis][0] else: data[axis+"_1d"] = data[axis][:,0] if keys == "all" : keys = data.keys() for key in keys: if isinstance(data[key],np.ndarray): try: newsize = size.copy() if data[key].ndim == 2: newsize.append( -1 ) data[key] = np.squeeze(data[key].reshape( newsize )) except ValueError: pass return data
def propagate( beam=id18h, optics=[[40, "x1", "coll"], [150, "x1", "focus@200"]], z=np.arange(0, 230, 0.5), use_transfocator=True, transfocator=transfocator, fixed_f=None, fname=None, force=False, ): """ beam is a GSM or a GSM_Numeric beam optics = [ [ pos1, aperture1, coll|flat|focus@dist|sizeUM@dist,None ], [ pos2, aperture2, coll|flat|focus@dist|sizeUM@dism,None ], [ .................................... ], ] sizeUM@dist means that FL to get as close as possible to UM um at a certain distance will be calculated (and used) if optics element starts with 'crl_', a CRL lens set will be used. The use of lenses can be 'forced' using use_transfocator=True transfocator is either an istance of crl.Transfocator or a dictionary of transfocator instances (key is the distance from source) fixed_f is to take into account constrains in one direction (e.g. h) imposed by having fixed focal length or lenses in v direction It should be a dictionary of focal length or CRL lenset (key is distance) aperture can be an: - absolute value, "x1.2" is 1.2 times the FWHM CL, coherence length, None """ print( "WARNING: hard apertures are implemented as shown in Vartanyans 2013 JSR paper" ) print(" They are an approximations (valid in the far field?)") if not force and fname is not None and os.path.isfile(fname): data = datastorage.read(fname) return data info = ds() energy = 12.398 / (beam.wavelen * 1e10) positions = [0] apertures = [None] focal_lengths = [None] desired_focal_lengths = [None] lenses = [None] beams_before_aperture_before_optics = [beam] beams_after_aperture_before_optics = [beam] beams_after_aperture_after_optics = [beam] log = ["source"] for i, o in enumerate(optics, start=1): _log = [] _log.append(f"Working on optics element {i}") _pos, _aperture, _element = o if isinstance(_element, (int, float)): fl = _element _element = "" # to make if statements below happy _log.append(f"Explicitly asked to use {fl:.3f} focal_length") if _element is not None and _element.startswith("crl_"): _use_transfocator = True _element = _element[:4] _log.append( "Will use CRL for this element because element name starts with crl_" ) else: _use_transfocator = False _use_transfocator = _use_transfocator or use_transfocator positions.append(_pos) dpos = _pos - positions[i - 1] # babo = before aperture, before optics babo = beams_after_aperture_after_optics[-1].propagate(dpos) ### WORK ON APERTURE ### # aabo = after aperture, before optics if _aperture is None: aabo = babo apertures.append(None) _log.append("no aperture for this element") else: if isinstance(_aperture, str): # "x1.2" aperture_as_fraction_of_cl = float(_aperture[1:]) _aperture = aperture_as_fraction_of_cl * babo.rms_cl * 2.35 _log.append( f"aperture defined as {aperture_as_fraction_of_cl:.2f} of FWHM CL {babo.rms_cl * 2.35:.2e} m" ) _log.append(f"aperture of {_aperture:.2e} m") apertures.append(_aperture) _aperture = hard_aperture(_aperture) aabo = babo.apply(_aperture) ### WORK ON FOCUSING OPTICS ### # aaao = after aperture, after optics if _element is None: aaao = aabo focal_lengths.append(None) desired_focal_lengths.append(None) lenses.append(None) _log.append(f"No focusing optics for this element") else: if fixed_f is not None and _pos in fixed_f: c = fixed_f[_pos] _log.append("Adding constrain from other direction:" + str(c)) if isinstance(c, (float, int)): c = lens(c) aabo = aabo.apply(c) if _element[:4].lower() == "coll": fl = aabo.radius _log.append( f"Asked for collimating, will try to use focal length = radius of curvature {fl:.3e} m" ) if _element[:5].lower() == "focus": where_to_focus = float(_element.split("@")[1]) dist_to_focus = where_to_focus - _pos _log.append( f"Asked for focusing at {where_to_focus:.3f} m from source (meaning {dist_to_focus:.3f} m from optical element)" ) fl = find_fl(aabo, dist_to_focus) _log.append(f"Found the FL needed: {fl:.3f} m") if _element[:4].lower() == "size": size, where = _element[4:].split("@") size = float(size) * 1e-6 dist = float(where) - _pos _log.append( f"Asked for imaging beam to a size of {size:.3e} m at a distance of {float(where):.3f} m (meaning {float(dist):.3f} m from optical element)" ) fl = find_fl_to_get_size(aabo, dist, size) _log.append(f"Found the FL needed: {fl:.3f} m") desired_focal_lengths.append(fl) if _use_transfocator: _log.append( f"Using transfocator, finding best combination for FL {fl:.3f} m" ) if not isinstance(transfocator, Transfocator): _transfocator = transfocator[_pos] else: _transfocator = transfocator ret_transf = _transfocator.find_best_set_for_focal_length( energy=energy, focal_length=fl, accuracy_needed=min(fl / 1000, 0.1), beam_fwhm=None, ) fl = ret_transf.focal_length _log.append( f"Using transfocator, found set with FL of {fl:.2f} m") _log.append( f"Using transfocator, using set {str(ret_transf.best_lens_set)}" ) fl_obj = ret_transf.best_lens_set _log.append(fl_obj) lenses.append(fl_obj) else: lenses.append(fl) fl_obj = lens(fl) focal_lengths.append(fl) if fl == np.inf: aaao = aabo else: aaao = aabo.apply(fl_obj) beams_before_aperture_before_optics.append(babo) beams_after_aperture_before_optics.append(aabo) beams_after_aperture_after_optics.append(aaao) log.append(_log) print("\n".join([l for l in _log if isinstance(l, str)])) positions = np.asarray(positions) info = ds( log=log, inputs=optics, optics_positions=positions, apertures=apertures, focal_lengths=focal_lengths, desired_focal_lengths=desired_focal_lengths, beams_before_aperture_before_optics=beams_before_aperture_before_optics, beams_after_aperture_before_optics=beams_after_aperture_before_optics, beams_after_aperture_after_optics=beams_after_aperture_after_optics, lenses=lenses) size = np.zeros_like(z) cl = np.zeros_like(z) gdc = np.zeros_like(z) radius = np.zeros_like(z) for i, zi in enumerate(z): print(f"calculating {i}/{len(z)}", end="\r") # calc which beam to use div = np.floor_divide(positions, zi) temp_idx = np.ravel(np.argwhere(div == 0)) if len(temp_idx) == 0: idx = 0 else: idx = temp_idx[-1] beam = beams_after_aperture_after_optics[idx] dpos = zi - positions[idx] b = beam.propagate(dpos) size[i] = b.rms_size * 2.35 * 1e6 cl[i] = b.rms_cl * 2.35 * 1e6 gdc[i] = b.global_degree_of_coherence radius[i] = b.radius divergence = np.gradient(size, z) ret = ds( z=z, divergence=divergence, fwhm_size=size, fwhm_cl=cl, global_degree_of_coherence=gdc, radius=radius, info=info, ) if fname is not None: ret.save(fname) return ret
def read_1dscan(fname,keys="all"): data = datastorage.read(fname) return data
# can also handle lists/tuples ... data.key5 = [1, 2, 3] # but this will not work...(or rather will not be saved) # data.key5 = [1,np.arange(10)] # convert object to Datastorage class MM: def __init__(self): self.f = sum ds(MM()) ## Save and read ## nested = dict(data1=np.random.random((100, 100)), info="this is a test") # adding a datastorage within another one data1 = ds(key1=np.arange(100), key2=nested, rawdata=data) # save in npz file format data1.save("/tmp/datastorage_example.npz") # save in hdf5 files data1.save("/tmp/datastorage_example.h5") # and reading it again data = datastorage.read("/tmp/datastorage_example.h5")