__version__ = '2024-03-30' import os import sys import subprocess import h5py import glob import numpy as np import argparse import matplotlib.pyplot as plt import matplotlib as mpl import time import logging from datetime import datetime #============================================================================== #============================================================================== class Detector: def __init__(self): self.nBlades = 14 # number of active blades in the detector angle = np.deg2rad( 5.1 ) # deg angle of incidence of the beam on the blades (def: 5.1) self.dZ = 4.0 * np.sin(angle) # mm height-distance of neighboring pixels on one blade self.dX = 4.0 * np.cos(angle) # mm depth-distance of neighboring pixels on one blace self.bladeZ = 10.7 # mm distance between detector blades (consistent with nu!) self.zero = 0.5 * self.nBlades * self.bladeZ # mm vertical center of the detector #============================================================================== def pixel2quantity(): det = Detector() nPixel = 64 * 32 * det.nBlades pixelID = np.arange(nPixel) (bladeNr, bPixel) = np.divmod(pixelID, 64*32) (bZ, bY) = np.divmod(bPixel, 64) z = det.zero - bladeNr * det.bladeZ - bZ * det.dZ x = (31 - bZ) * det.dX bladeAngle = np.rad2deg( 2. * np.arcsin(0.5*det.bladeZ / detectorDistance) ) delta = (det.nBlades/2. - bladeNr) * bladeAngle - np.rad2deg( np.arctan(bZ*det.dZ / ( detectorDistance + bZ * det.dX) ) ) dZ = bladeNr * 32 + bZ quantity = np.vstack((dZ.T, bY.T, delta.T, x.T)).T return quantity #============================================================================== def analyse_ev(event_e, tof_e, yMin, yMax, thetaMin, thetaMax): data_e = np.zeros((len(event_e), 9), dtype=float) # data_e column description: # 0: wall time / s # 1: pixelID # 2: z on detector # 3: y on detector # 4: delta / deg = angle on detector # 5: path within detector / mm # 6: lambda / angstrom # 7: theta / deg # 8: q_z / angstrom^-1 data_e[:,0] = tof_e[:] data_e[:,1] = event_e[:] # filter 'strange' tof times > 2 tau if True: filter_e = (data_e[:,0] <= 2*tau) #print(event_e[~filter_e]) #print(data_e[~filter_e,0]) data_e = data_e[filter_e,:] if np.shape(filter_e)[0]-np.shape(data_e)[0] > 0.5 and verbous: logging.warning(f'## strange times: {np.shape(filter_e)[0]-np.shape(data_e)[0]}') pixelLookUp = pixel2quantity() data_e[:,2:6] = pixelLookUp[np.int_(data_e[:,1])-1,:] #================================ # filter y range filter_e = (yMin <= data_e[:,3]) & (data_e[:,3] <= yMax) data_e = data_e[filter_e,:] # correct tof for beam size effect at chopper data_e[:,0] -= ( data_e[:,4] / 180. ) * tau # effective flight path length #data_e[:,5] = chopperDetectorDistance + data_e[:,5] # calculate lambda hdm = 6.626176e-34/1.674928e-27 # h / m data_e[:,6] = 1.e13 * data_e[:,0] * hdm / ( chopperDetectorDistance + data_e[:,5] ) # theta data_e[:,7] = nu - mu + data_e[:,4] # gravity compensation data_e[:,7] += np.rad2deg( np.arctan( 3.07e-10 * ( detectorDistance + data_e[:,5]) * data_e[:,6] * data_e[:,6] ) ) # filter theta range filter_l = (thetaMin <= data_e[:,7]) & (data_e[:,7] <= thetaMax) data_e = data_e[filter_l,:] # q_z data_e[:,8] = 4*np.pi * np.sin( np.deg2rad( data_e[:,7] ) ) / data_e[:,6] # filter q_z range #filter_e = (qMin < data_e[:,6]) & (data_e[:,6] < qMax) #data_e = data_e[filter_e,:] return data_e #============================================================================== class Meta: # AMOR hdf dataset with associated properties from metadata def __init__(self, fileName): self.fileName = fileName fh = h5py.File(fileName, 'r', swmr=True) # for processing self.chopperDistance = float(np.take(fh['/entry1/Amor/chopper/pair_separation'], 0)) # mm # the following is the distance from the sample to the detector entry window, not to the center of rotation self.detectorDistance = float(np.take(fh['/entry1/Amor/detector/transformation/distance'], 0)) # mm self.chopperDetectorDistance = self.detectorDistance - float(np.take(fh['entry1/Amor/chopper/distance'], 0)) # mm self.lamdaCut = 2.5 # Aa startDate = str(fh['/entry1/start_time'][0].decode('utf-8')) self.startDate = datetime.strptime(startDate, '%Y-%m-%d %H:%M:%S') startDate = datetime.timestamp(self.startDate) self.countingTime = float(np.take(fh['/entry1/Amor/detector/data/event_time_zero'], -1))/1e9 - startDate # not exact for low rates ka0 = 0.245 # given inclination of the beam after the Selene guide year_date = str(datetime.today()).split(' ')[0].replace("-", "/", 1) # deside from where to take the control paralemters try: self.mu = float(np.take(fh['/entry1/Amor/master_parameters/mu/value'], 0)) self.nu = float(np.take(fh['/entry1/Amor/master_parameters/nu/value'], 0)) self.kap = float(np.take(fh['/entry1/Amor/master_parameters/kap/value'], 0)) self.kad = float(np.take(fh['/entry1/Amor/master_parameters/kad/value'], 0)) self.div = float(np.take(fh['/entry1/Amor/master_parameters/div/value'], 0)) chSp = float(np.take(fh['/entry1/Amor/chopper/rotation_speed/value'], 0)) self.chPh = float(np.take(fh['/entry1/Amor/chopper/phase/value'], 0)) except (KeyError, IndexError): logging.warning(f" using parameters from nicos cache") #cachePath = '/home/amor/nicosdata/amor/cache/' cachePath = '/home/nicos/amorcache/' value = str(subprocess.getoutput('/usr/bin/grep "value" '+cachePath+'nicos-mu/'+year_date)).split('\t')[-1] self.mu = float(value) value = str(subprocess.getoutput('/usr/bin/grep "value" '+cachePath+'nicos-nu/'+year_date)).split('\t')[-1] self.nu = float(value) value = str(subprocess.getoutput('/usr/bin/grep "value" '+cachePath+'nicos-kap/'+year_date)).split('\t')[-1] self.kap = float(value) value = str(subprocess.getoutput('/usr/bin/grep "value" '+cachePath+'nicos-kad/'+year_date)).split('\t')[-1] self.kad = float(value) value = str(subprocess.getoutput('/usr/bin/grep "value" '+cachePath+'nicos-div/'+year_date)).split('\t')[-1] self.div = float(value) value = str(subprocess.getoutput('/usr/bin/grep "value" '+cachePath+'nicos-ch1_speed/'+year_date)).split('\t')[-1] chSp = float(value) self.chPh = np.nan if chSp: self.tau = 30. / chSp else: self.tau = 0 try: # not yet correctly implemented in nexus template spin = str(fh['/entry1/polarizer/spin_flipper/spin'][0].decode('utf-8')) if spin == "b'p'": self.spin = 'p' elif spin == "b'm'": self.spin = 'm' elif spin == "b'up'": self.spin = 'p' elif spin == "b'down'": self.spin = 'm' elif spin == '?': self.spin = '?' else: self.spin = 'n' except (KeyError, IndexError): self.spin = '?' fh.close() #============================================================================== def resolveNumber(dataPath, ident): if ident == '0' or '-' in ident[0]: try: nnr = int(ident) except: logging.error("ERROR: '{}' is no valid file identifier!".format(ident)) fileNames = glob.glob(dataPath+'/*.hdf') fileNames.sort() fileName = fileNames[nnr-1] fileName = fileName.split('/')[-1] fileNumber = fileName.split('n')[1].split('.')[0].lstrip('0') else: fileNumber = ident return fileNumber #============================================================================== def fileNameCreator(dataPath, ident): clas = commandLineArgs() ident=str(ident) try: nnr = int(ident) except: logging.error("ERROR: '{}' is no valid file identifier!".format(ident)) if nnr <= 0 : fileName = glob.glob(dataPath+'/*.hdf')[nnr-1] fileName = fileName.split('/')[-1] else: fileName = f'amor{clas.year}n{ident:>06s}' fileName = fileName.split('.')[0] fileName = fileName+'.hdf' fileName = dataPath+fileName fileNumber = fileName.split('n')[-1].split('.')[0].lstrip('0') return fileName, fileNumber #============================================================================== class PlotSelection: def headline(self, fileNumber, totalCounts): headLine = "#{} \u03bc={:>1.2f} \u03bd={:>1.2f} {:>12,} cts {:>8.1f} s".format(fileNumber, mu+5e-3, nu+5e-3, totalCounts, countingTime) return headLine # grids def y_grid(self): y_grid = np.arange(yMin, yMax+1, 1) return y_grid def lamda_grid(self): dldl = 0.005 # Delta lambda / lambda lMin = max(2, lamdaMin) lamda_grid = lMin*(1+dldl)**np.arange(int(np.log(lamdaMax/lMin)/np.log(1+dldl)+1)) return lamda_grid def theta_grid(self): det = Detector() bladeAngle = np.rad2deg( 2. * np.arcsin(0.5*det.bladeZ / detectorDistance) ) blade_grid = np.arctan( np.arange(33) * det.dZ / ( detectorDistance + np.arange(33) * det.dX) ) blade_grid = np.rad2deg(blade_grid) stepWidth = blade_grid[1] - blade_grid[0] blade_grid = blade_grid - 0.2 * stepWidth delta_grid = [] for b in np.arange(det.nBlades-1): delta_grid = np.concatenate((delta_grid, blade_grid), axis=None) blade_grid = blade_grid + bladeAngle delta_grid = delta_grid[delta_grid=thetaMin] theta_grid = theta_grid[theta_grid<=thetaMax] return theta_grid def q_grid(self): dqdq = 0.010 # Delta q_z / q_z q_grid = qMin*(1.+dqdq)**np.arange(int(np.log(qMax/qMin)/np.log(1+dqdq))) return q_grid # create PNG with several plots def all(self, fileNumber, arg, data_e): #cmap='gist_earth' cmap = mpl.cm.gnuplot(np.arange(256)) cmap[:1, :] = np.array([256/256, 255/256, 236/256, 1]) cmap = mpl.colors.ListedColormap(cmap, name='myColorMap', N=cmap.shape[0]) I_yt, bins_y, bins_t = np.histogram2d(data_e[:,3], data_e[:,7], bins = (self.y_grid(), self.theta_grid())) I_lt, bins_l, bins_t = np.histogram2d(data_e[:,6], data_e[:,7], bins = (self.lamda_grid(), self.theta_grid())) I_q, bins_q = np.histogram(data_e[:,8], bins = self.q_grid()) q_lim = 4*np.pi*np.array([ max( np.sin(self.theta_grid()[0]*np.pi/180.)/self.lamda_grid()[-1] , 1e-4 ), min( np.sin(self.theta_grid()[-1]*np.pi/180.)/self.lamda_grid()[0] , 0.03 )]) if arg == 'lin': #vmin = min(np.min(I_lt), np.min(I_yt)) vmin = 0 vmax = max(5, np.max(I_lt), np.max(I_yt)) else: vmin = 0 vmax = max(1, np.log(np.max(I_lt)+.1)/np.log(10)*1.05, np.log(np.max(I_yt)+.1)/np.log(10)*1.05) # I(y, theta) fig = plt.figure() axs = fig.add_gridspec(2,3) myt = fig.add_subplot(axs[0,0]) myt.set_title('detector area') myt.set_xlabel('$y ~/~ \\mathrm{bins}$') myt.set_ylabel('$\\theta ~/~ \\mathrm{deg}$') if arg == 'lin': myt.pcolormesh(bins_y, bins_t, I_yt.T, cmap=cmap, vmin=vmin, vmax=vmax) else: myt.pcolormesh(bins_y, bins_t, (np.log(I_yt + 5.e-1) / np.log(10.)).T, cmap=cmap, vmin=vmin, vmax=vmax) # I(lambda, theta) mlt = fig.add_subplot(axs[0,1:]) mlt.set_title('angle- and energy disperse') mlt.set_xlabel('$\\lambda ~/~ \\mathrm{\\AA}$') mlt.axes.get_yaxis().set_visible(False) if arg == 'lin': cb = mlt.pcolormesh(bins_l, bins_t, I_lt.T, cmap=cmap, vmin=vmin, vmax=vmax) else: cb = mlt.pcolormesh(bins_l, bins_t, (np.log(I_lt + 5.e-1) / np.log(10.)).T, cmap=cmap, vmin=vmin, vmax=vmax) # I(q_z) lqz = fig.add_subplot(axs[1,:]) lqz.set_title('$I(q_z)$') lqz.set_ylabel('$\\log_{10}(\\mathrm{cnts})$') lqz.set_xlabel('$q_z~/~\\mathrm{\\AA}^{-1}$') lqz.set_xlim(q_lim) if arg == 'lin': plt.plot(bins_q[:-1], I_q, color='blue', linewidth=0.5) else: err_q = np.sqrt(I_q+1) low_q = np.where(I_q-err_q>0, I_q-err_q, 0.1) plt.fill_between(bins_q[:-1], np.log(low_q)/np.log(10), np.log(I_q+err_q/2)/np.log(10), color='lightgrey') plt.plot(bins_q[:-1], np.log(I_q+5e-1)/np.log(10), color='blue', linewidth=0.5) lw = I_q[ ((q_lim[0] < bins_q[:-1]) & (bins_q[:-1] < q_lim[1])) ].min() plt.ylim(max(-0.1, np.log(lw+.1)/np.log(10)-0.1), ) # headline = self.headline(fileNumber, np.shape(data_e)[0]) plt.title(headline, loc='left', y=2.8, c='r') fig.colorbar(cb, ax=mlt) plt.subplots_adjust(hspace=0.6, wspace=0.1) plt.savefig(output, format='png', dpi=150) # create PNG with one plot def Iyz(self, fileNumber, arg, data_e): det = Detector() cmap = mpl.cm.gnuplot(np.arange(256)) cmap[:1, :] = np.array([256/256, 255/256, 236/256, 1]) cmap = mpl.colors.ListedColormap(cmap, name='myColorMap', N=cmap.shape[0]) z_grid = np.arange(det.nBlades*32) I_yz, bins_y, bins_z = np.histogram2d(data_e[:,3], data_e[:,2], bins = (self.y_grid(), z_grid)) if arg == 'log': vmin = 0 vmax = max(1, np.log(np.max(I_yt)+.1)/np.log(10)*1.05) plt.pcolormesh(bins_y[:],bins_z[:],(np.log(I_yz+6e-1)/np.log(10)).T, cmap=cmap, vmin=vmin, vmax=vmax) else: plt.pcolormesh(bins_y[:],bins_z[:],I_yz.T, cmap=cmap) plt.xlabel('$y ~/~ \\mathrm{bins}$') plt.ylabel('$z ~/~ \\mathrm{bins}$') headline = self.headline(fileNumber, np.shape(data_e)[0]) plt.title(headline, loc='left', y=1.0, c='r') plt.colorbar() plt.savefig(output, format='png', dpi=150) def Ilt(self, fileNumber, arg, data_e) : cmap = mpl.cm.gnuplot(np.arange(256)) cmap[:1, :] = np.array([256/256, 255/256, 236/256, 1]) cmap = mpl.colors.ListedColormap(cmap, name='myColorMap', N=cmap.shape[0]) I_lt, bins_l, bins_t = np.histogram2d(data_e[:,6], data_e[:,7], bins = (self.lamda_grid(), self.theta_grid())) if arg == 'log': vmax = max(1, np.log(np.max(I_lt)+.1)/np.log(10)*1.05 ) plt.pcolormesh(bins_l, bins_t, (np.log(I_lt+I_lt[I_lt>0].min()/2)/np.log(10.)).T, cmap=cmap, vmin=0, vmax=vmax) else : vmax = max(np.max(I_lt), 5) plt.pcolormesh(bins_l, bins_t, I_lt.T, cmap=cmap, vmin=0, vmax=vmax) plt.xlim(0,) #if np.min(bins_t) > 0.01 : # plt.ylim(bottom=0) #else: # plt.ylim(bottom=np.min(bins_t)) #if np.max(bins_t) < -0.01: # plt.ylim(top=0) #else: # plt.ylim(top=np.max(bins_t)) plt.xlim(lamdaMin, lamdaMax) plt.ylim(thetaMin, thetaMax) plt.xlabel('$\\lambda ~/~ \\mathrm{\\AA}$') plt.ylabel('$\\theta ~/~ \\mathrm{deg}$') headline = self.headline(fileNumber, np.shape(data_e)[0]) plt.title(headline, loc='left', y=1.0, c='r') plt.colorbar() plt.savefig(output, format='png', dpi=150) def Itz(self, fileNumber, arg, data_e): det = Detector() cmap = mpl.cm.gnuplot(np.arange(256)) cmap[:1, :] = np.array([256/256, 255/256, 236/256, 1]) cmap = mpl.colors.ListedColormap(cmap, name='myColorMap', N=cmap.shape[0]) time_grid = np.arange(0, tau, 0.0005) z_grid = np.arange(det.nBlades*32+1) I_tz, bins_t, bins_z = np.histogram2d(data_e[:,0], data_e[:,2], bins = (time_grid, z_grid)) if arg == 'log': vmax = max(2., np.log(np.max(I_tz)+.1)/np.log(10)*1.05 ) plt.pcolormesh(bins_t, bins_z, (np.log(I_tz+5.e-1)/np.log(10.)).T, cmap=cmap, vmin=0, vmax=vmax) else : vmax = max(np.max(I_tz), 5) plt.pcolormesh(bins_t, bins_z, I_tz.T, cmap=cmap, vmin=0, vmax=vmax) if True: plt.xlim(0,) plt.ylim(0,) plt.xlabel('$t ~/~ \\mathrm{s}$') plt.ylabel('$z$ pixel row') headline = self.headline(fileNumber, np.shape(data_e)[0]) plt.title(headline, loc='left', y=1.0, c='r') plt.colorbar() plt.savefig(output, format='png', dpi=150) def Iq(self, fileNumber, arg, data_e): I_q, bins_q = np.histogram(data_e[:,8], bins = self.q_grid()) err_q = np.sqrt(I_q+1) q_lim = 4*np.pi*np.array([ max( np.sin(self.theta_grid()[0]*np.pi/180.)/self.lamda_grid()[-1] , 1e-4 ), min( np.sin(self.theta_grid()[-1]*np.pi/180.)/self.lamda_grid()[0] , 0.03 )]) if arg == 'log': low_q = np.where(I_q-err_q>0, I_q-err_q, 0.1) plt.fill_between(bins_q[:-1], np.log(low_q)/np.log(10), np.log(I_q+err_q/2)/np.log(10), color='lightgrey') plt.plot(bins_q[:-1], np.log(I_q+5e-1)/np.log(10), color='blue', linewidth=0.5) lw = I_q[ ((q_lim[0] < bins_q[:-1]) & (bins_q[:-1] < q_lim[1])) ].min() plt.ylim(max(-0.1, np.log(lw+.1)/np.log(10)-0.1), ) else: plt.plot(bins_q[:-1], I_q, color='blue', linewidth=0.5) plt.ylabel('$\\log_{10}(\\mathrm{cnts})$') plt.xlabel('$q_z ~/~ \\mathrm{\\AA}^{-1}$') plt.xlim(q_lim) headline = self.headline(fileNumber, np.shape(data_e)[0]) plt.title(headline, loc='left', y=1.0, c='r') plt.savefig(output, format='png', dpi=150) def Il(self, fileNumber, arg, data_e): I_l, bins_l = np.histogram(data_e[:,6], bins = self.lamda_grid()) if arg == 'lin': plt.plot(bins_l[:-1], I_l) plt.ylabel('$I ~/~ \\mathrm{cnts}$') else: plt.plot(bins_l[:-1], np.log(I_l+5.e-1)/np.log(10.)) plt.ylabel('$\\log_{10} I ~/~ \\mathrm{cnts}$') plt.xlabel('$\\lambda ~/~ \\mathrm{\\AA}$') headline = self.headline(fileNumber, np.shape(data_e)[0]) plt.title(headline, loc='left', y=1.0, c='r') plt.savefig(output, format='png', dpi=150) def It(self, fileNumber, arg, data_e): I_t, bins_t = np.histogram(data_e[:,7], bins = self.theta_grid()) plt.plot( I_t, bins_t[:-1]) plt.xlabel('$\\mathrm{cnts}$') plt.ylabel('$\\theta ~/~ \\mathrm{deg}$') headline = self.headline(fileNumber, np.shape(data_e)[0]) plt.title(headline, loc='left', y=1.0, c='r') plt.savefig(output, format='png', dpi=150) def tof(self, fileNumber, arg, data_e): time_grid = np.arange(0, 1.3*tau, 0.0005) I_t, bins_t = np.histogram(data_e[:,0], bins = time_grid) if arg == 'lin': plt.plot(bins_t[:-1]+tau, I_t) plt.plot(bins_t[:-1], I_t) plt.plot(bins_t[:-1]+2*tau, I_t) else: lI_t = np.log(I_t+5.e-1)/np.log(10.) plt.plot(bins_t[:-1]+tau, lI_t) plt.plot(bins_t[:-1], lI_t) plt.plot(bins_t[:-1]+2*tau, lI_t) plt.ylabel('log(counts)') plt.xlabel('time / s') headline = self.headline(fileNumber, np.shape(data_e)[0]) plt.title(headline, loc='left', y=1.0, c='r') plt.savefig(output, format='png') #============================================================================== def process(dataPath, ident, clas): #================================ # constants hdm = 6.626176e-34/1.674928e-27 # h / m #================================ # instrument specific parameters #================================ global lamdaMin, lamdaMax, qMin, qMax, thetaMin, thetaMax, yMin, yMax # defaults lamdaCut = 2.5 # Aa used to reshuffle tof # data filtering and folding #================================ if clas.lambdaRange: lamdaMin = clas.lambdaRange[0] lamdaMax = clas.lambdaRange[1] else: lamdaMin = lamdaCut chopperPhase = clas.chopperPhase tofOffset = clas.TOFOffset thetaMin = clas.thetaRange[0] thetaMax = clas.thetaRange[1] yMin = clas.yRange[0] yMax = clas.yRange[1] qMin = clas.qRange[0] qMax = clas.qRange[1] #================================ # find and open input file global ev data_eSum = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0]]) sumTime = 0 number = resolveNumber(dataPath, ident) fileName, fileNumber = fileNameCreator(dataPath, str(number)) if verbous: logging.info('life_histogrammer processing file ->\033[1m {} \033[0m<-'.format(fileNumber)) for i in range(6): ev = h5py.File(fileName, 'r', swmr=True) try: ev['/entry1/Amor/detector/data/event_time_zero'][-1] break except (KeyError, IndexError): ev.close() if i < 5: if verbous: print("no data yet, retrying ({}) ".format(10-2*i), end='\r') time.sleep(2) continue else: if verbous: print("# time-out: no longer waiting for data!\a") return # get and process data meta = Meta(fileName) global mu, nu, tau if clas.mu < 98.: mu = clas.mu else: mu = meta.mu + clas.muOffset if clas.nu < 98.: nu = clas.nu else: nu = meta.nu if clas.chopperSpeed: tau = 30./ clas.chopperSpeed else: tau = meta.tau try: chPh except NameError: chPh = meta.chPh spin = meta.spin global countingTime, detectorDistance, chopperDetectorDistance detectorDistance = meta.detectorDistance chopperDetectorDistance = meta.chopperDetectorDistance countingTime = meta.countingTime if verbous: logging.info(" mu = {:>4.2f} deg, nu = {:>4.2f} deg".format(mu, nu)) if spin == 'u': logging.info(' spin <+|') elif spin == 'd': logging.info(' spin <-|') try: lamdaMax except NameError: lamdaMax = lamdaMin + tau * hdm/chopperDetectorDistance * 1e13 tofOffset = tau * chopperPhase / 180. # mismatch of chopper pulse and time-zero tofCut = lamdaCut * chopperDetectorDistance / hdm * 1.e-13 # tof of frame start tof_e = np.array(ev['/entry1/Amor/detector/data/event_time_offset'][:], dtype=np.uint64)/1.e9 + tofOffset # tof detPixelID_e = np.array(ev['/entry1/Amor/detector/data/event_id'][:], dtype=np.uint64) # pixel index dataPacket_p = np.array(ev['/entry1/Amor/detector/data/event_index'][:], dtype=np.uint64) # data packet index tof_e = np.where(tof_etau+tofCut, tof_e-tau, tof_e) data_e = analyse_ev(detPixelID_e, tof_e, yMin, yMax, thetaMin, thetaMax) ev.close() data_eSum = np.append(data_eSum, data_e, axis=0) sumTime += countingTime if verbous: logging.info(" total counts = {} in {:6.1f} s".format(np.shape(data_e)[0], sumTime)) #================================ # plotting data plotType = clas.plot[0] try: arg = clas.plot[1] except IndexError: arg = 'def' plott = PlotSelection() try: plotFunction = getattr(plott, plotType) plotFunction(fileNumber, arg, data_e) plt.close() except Exception as e: logging.error(f"ERROR: '{plotType}' is no known output format!") logging.error(f" original error: {e}") #============================================================================== def commandLineArgs(): msg = "events2histogram reads the eventstream from an hdf raw file and \ creates various histogrammed outputs or plots." clas = argparse.ArgumentParser(description = msg) clas.add_argument("-c", "--chopperSpeed", type=float, help ="chopper speed in rpm") clas.add_argument("-d", "--dataPath", help ="relative path to directory with .hdf files") clas.add_argument("-f", "--fileIdent", default='0', help ="file number or offset (if negative)") clas.add_argument("-l", "--lambdaRange", nargs=2, type=float, help ="wavelength range to be used") clas.add_argument("-M", "--muOffset", default=0., type=float, help ="mu offset") clas.add_argument("-m", "--mu", default=99., type=float, help ="value of mu") clas.add_argument("-n", "--nu", default=99., type=float, help ="value of nu") clas.add_argument("-P", "--chopperPhase", default=-5., type=float, help ="chopper phase offset") clas.add_argument("-p", "--plot", default=['all', 'def'], nargs='+', help ="select what to plot or write") clas.add_argument("-q", "--qRange", default=[0.005, 0.30], nargs=2, type=float, help ="q_z range") clas.add_argument("-T", "--TOFOffset", default=0.0, type=float, help ="TOF zero offset") clas.add_argument("-t", "--thetaRange", default=[-12., 12.], nargs=2, type=float, help ="theta range to be used") clas.add_argument("-Y", "--year", default = str(datetime.today()).split('-')[0], help = "year, the measurement was performed") clas.add_argument("-y", "--yRange", default=[0, 63], nargs=2, type=int, help ="detector y range to be used") return clas.parse_args() #============================================================================== def get_dataPath(clas): if clas.dataPath: dataPath = clas.dataPath + '/' if not os.path.exists(dataPath): sys.exit('# *** the directory "'+dataPath+'" does not exist ***') elif os.path.exists('./raw'): dataPath = "./raw/" elif os.path.exists('../raw'): dataPath = "../raw/" else: sys.exit('# *** please provide the path to the .hdf data files (-d , default is "./raw")') return dataPath #============================================================================== def get_directDataPath(clas): #dataPath = clas.dataPath + '/' year = str(datetime.today()).split('-')[0] year_date = str(datetime.today()).split(' ')[0].replace("-", "/", 1) pNr = str(subprocess.getoutput('/usr/bin/grep "proposal\t" /home/amor/nicosdata/amor/cache/nicos-exp/'+year_date)[-1]).split('\'')[1] dataPath = '/home/amor/nicosdata/amor/data/'+year+'/'+pNr+'/' if not os.path.exists(dataPath): sys.exit('# *** the directory "'+dataPath+'" does not exist ***') return dataPath #============================================================================== def main(): global verbous, output, dataPath clas = commandLineArgs() dataPath = get_dataPath(clas) logging.basicConfig(level=logging.INFO, format='# %(message)s') verbous = True output = 'life_plot.png' process(dataPath, clas.fileIdent, clas) #============================================================================== #============================================================================== if __name__ == "__main__": main()