import sys import os import datetime import h5py import socket from PIL import Image def getDatasetFileName(program='Unknown'): year = datetime.datetime.now().strftime('%Y') month = datetime.datetime.now().strftime('%m') day = datetime.datetime.now().strftime('%d') path = '/sf/data/measurements/%s' % year if not os.path.exists(path): os.makedirs(path) path = '%s/%s' % (path,month) if not os.path.exists(path): os.makedirs(path) path = '%s/%s' % (path,day) if not os.path.exists(path): os.makedirs(path) datetag = datetime.datetime.now().strftime('%Y_%m_%d_%H_%M_%S_%f') filename=('%s/%s_%s' % (path, program.replace(' ','_'), datetag)) return filename def saveDataset(program,data,actuator=None,snap=None,analysis=None,figures=None): hid,filename = openDataset(program) if not hid: return None # check if scan is multiple instances of a scan if isinstance(data,list): for iscan,singledata in enumerate(data): writeData(hid,singledata,iscan) else: writeData(hid,data,1) # same for actuator if isinstance(actuator,list): for iscan,singleactuator in enumerate(actuator): writeActuator(hid,singleactuator,iscan) else: writeActuator(hid,actuator,1) # and same for analysis if isinstance(analysis,list): for iscan,singleana in enumerate(analysis): writeAnalysis(hid,singleana,iscan) else: writeAnalysis(hid,analysis,1) # write aux data writeSnap(hid,snap) hid.close() if figures: writeFigure(filename,figures) return filename def openDataset(program): if isinstance(program,str): program={'Name':program,'Author':'Unknown','Version':'Unknown'} if not isinstance(program,dict): return None,None if not 'Author' in program.keys(): program['Author']='Unknown' if not 'Version' in program.keys(): program['Version']='Unknown' filename=getDatasetFileName(program['Name']) hid= h5py.File(filename+'.h5', "w") # meta data header dt = h5py.special_dtype(vlen=bytes) dset=hid.create_dataset('general/user',(1,),dtype=dt) dset[0]=os.getlogin() dset=hid.create_dataset('general/application',(1,),dtype=dt) dset[0]=program['Name'] dset=hid.create_dataset('general/author',(1,),dtype=dt) dset[0]=program['Author'] dset=hid.create_dataset('general/version',(1,),dtype=dt) dset[0]=program['Version'] dset=hid.create_dataset('general/created',(1,),dtype=dt) dset[0]=str(datetime.datetime.now()) return hid,filename def writeData(hid, data, scanrun=1): # write the sensor raw value for ele in data.keys(): name=ele.split(':') if len(name)>1: dset=hid.create_dataset('scan_%d/data/%s/%s' % (scanrun, name[0], name[1]), data=data[ele]) else: dset=hid.create_dataset('scan_%d/data/%s' % (scanrun, name[0]), data=data[ele]) dset.attrs['system'] = getDatasetSystem(name[0]) dset.attrs['units'] = 'unknown' # this part is obsolete - dimension should be given from the individual datasets if not 'pid' in data.keys(): return shape = data['pid'].shape ndim = len(shape) nsam = shape[-1] nrec = 0 if ndim > 1: nrec = shape[:-1][0] hid.create_dataset("scan_%d/method/records" % scanrun,data=[nrec]) hid.create_dataset("scan_%d/method/samples" % scanrun,data=[nsam]) hid.create_dataset("scan_%d/method/dimension" % scanrun,data=[ndim]) hid.create_dataset("scan_%d/method/reducedData" % scanrun,data=[0]) # indicating that there is at least a 2D array for scalar data def writeActuator(hid,act,scanrun=1): if not act: return dt = h5py.special_dtype(vlen=bytes) dset=hid.create_dataset("scan_%d/method/type" % scanrun,(1,),dtype=dt) nact = len(act.keys()) if nact>0: dset[0]='Scan' else: dset[0]='Time Recording' for ele in act.keys(): name=ele.split(':') if len(name)>1: dset=hid.create_dataset("scan_%d/method/actuators/%s/%s" % (scanrun,name[0],name[1]),data=act[ele]) else: dset=hid.create_dataset("scan_%d/method/actuators/%s" % (scanrun,name[0]),data=act[ele]) dset.attrs['system']=getDatasetSystem(name[0]) dset.attrs['units']='unknown' def writeSnap(hid,val): if not val: return for key in val.keys(): name=key.split(':') if len(name)>1: dset=hid.create_dataset('experiment/%s/%s' % (name[0],name[1]),data=val[key]) else: dset=hid.create_dataset('experiment/%s/%s' % (name[0]),data=val[key]) dset.attrs['system']=getDatasetSystem(name[0]) dset.attrs['units']='unknown' def writeAnalysis(hid,data,scanrun=1): if not data: return for key in data.keys(): name=key.split(':') if len(name)>1: dset=hid.create_dataset('scan_%d/analysis/%s/%s' % (scanrun, name[0], name[1]), data=data[key]) else: dset=hid.create_dataset('scan_%d/analysis/%s/%s' % (scanrun, name[0]), data=data[key]) dset.attrs['system']='analysis' dset.attrs['units']='unknown' def writeFigure(filename,figs): for i,ele in enumerate(figs): if ele == None: continue plotname='%s_Fig%d.png' % (filename,(i+1)) im = Image.open(ele) im.save(plotname) return None def getDatasetSystem(name): if len(name) > 11: tag=name[8:9] fulltag=name[8:12] else: tag='' fulltag='' sys='Unknown' if tag =='P': sys='Photonics' if tag =='D': sys='Diagnostics' if fulltag =='DSCR': sys='Camera' if tag == 'R': sys='RF' if tag == 'M': sys='Magnets' if tag == 'U': sys='Undulator' return sys