def _convert_units_wavelength(self, unit, input_ws, output_ws, target): if unit != 'Wavelength': # Configure conversion if unit == 'dSpacing': emode = 'Elastic' efixed = 0.0 elif unit == 'DeltaE': emode = 'Indirect' from IndirectCommon import getEfixed efixed = getEfixed(input_ws) else: raise ValueError( 'Unit %s in sample workspace is not supported' % unit) # Do conversion # Use temporary workspace so we don't modify data s_api.ConvertUnits(InputWorkspace=input_ws, OutputWorkspace=output_ws, Target=target, EMode=emode, EFixed=efixed) else: # No need to convert s_api.CloneWorkspace(InputWorkspace=input_ws, OutputWorkspace=output_ws)
def _get_efixed(self, workspace): """ Gets an efixed value form a workspace. @param workspace Name of workspace to extract from @return Fixed energy value """ from IndirectCommon import getEfixed try: # Try to get efixed from the parameters first efixed = getEfixed(workspace) except ValueError: # If that fails then get it by taking from group of all detectors wsHandle = mtd[workspace] spectra_list = list(range(0, wsHandle.getNumberHistograms())) GroupDetectors(InputWorkspace=workspace, OutputWorkspace=workspace, SpectraList=spectra_list) wsHandle = mtd[workspace] det = wsHandle.getDetector(0) efixed = wsHandle.getEFixed(det.getID()) return efixed
def _convert_units_wavelength(self, unit, input_ws, output_ws, target): if unit != 'Wavelength': # Configure conversion if unit == 'dSpacing': emode = 'Elastic' efixed = 0.0 elif unit == 'DeltaE': emode = 'Indirect' from IndirectCommon import getEfixed efixed = getEfixed(input_ws) else: raise ValueError('Unit %s in sample workspace is not supported' % unit) # Do conversion # Use temporary workspace so we don't modify data s_api.ConvertUnits(InputWorkspace=input_ws, OutputWorkspace=output_ws, Target=target, EMode=emode, EFixed=efixed) else: # No need to convert s_api.CloneWorkspace(InputWorkspace=input_ws, OutputWorkspace=output_ws)
def _ascii_3d_import(self): """ Import 3D ASCII data (e.g. I(Q, t)). """ logger.notice('Loading ASCII data') from IndirectCommon import getEfixed from IndirectNeutron import ChangeAngles, InstrParas # Read file data = [] x_axis = ('time', 'ns') v_axis = ('q', 'ang^-1') with open(self._file_name, 'r') as handle: for line in handle: line = line.strip() # Ignore empty lines if line == '': continue # Data line (if not comment) elif line.strip()[0] != '#': line_values = np.array([ast.literal_eval(t.strip()) if 'nan' not in t.lower() else np.nan for t in line.split()]) data.append(line_values) if x_axis is None or v_axis is None: raise ValueError('Data is not in expected format for 3D data') logger.debug('X axis: {0}'.format(x_axis)) logger.debug('V axis: {0}'.format(v_axis)) # Get axis and Y values data = np.swapaxes(np.array(data), 0, 1) x_axis_values = data[0,1:] v_axis_values = data[1:,0] y_values = np.ravel(data[1:,1:]) # Create the workspace wks = CreateWorkspace(OutputWorkspace=self._out_ws, DataX=x_axis_values, DataY=y_values, NSpec=v_axis_values.size, UnitX=x_axis[1], EnableLogging=False) # Load the MolDyn instrument q_max = v_axis_values[-1] instrument = 'MolDyn' reflection = '2' if q_max <= 2.0 else '4' InstrParas(wks.name(), instrument, 'simul', reflection) # Process angles efixed = getEfixed(wks.name()) logger.information('Qmax={0}, Efixed={1}'.format(q_max, efixed)) wave = 1.8 * math.sqrt(25.2429 / efixed) qw = wave * v_axis_values / (4.0 * math.pi) theta = 2.0 * np.degrees(np.arcsin(qw)) ChangeAngles(wks.name(), instrument, theta) return wks
def _pre_process_corrections(self): """ If the sample is not in wavelength then convert the corrections to whatever units the sample is in. """ unit_id = mtd[self._sample_ws_name].getAxis(0).getUnit().unitID() logger.information('x-unit is ' + unit_id) factor_types = ['ass'] if self._use_can: factor_types.extend(['acc', 'acsc', 'assc']) for factor_type in factor_types: input_name = self._get_correction_factor_ws_name(factor_type) output_name = self._corrections + '_' + factor_type if unit_id != 'Wavelength': # Configure conversion if unit_id == 'dSpacing': emode = 'Elastic' efixed = 0.0 elif unit_id == 'DeltaE': emode = 'Indirect' from IndirectCommon import getEfixed efixed = getEfixed(mtd[self._sample_ws_name]) else: raise ValueError( 'Unit %s in sample workspace is not supported' % unit_id) # Do conversion ConvertUnits(InputWorkspace=input_name, OutputWorkspace=output_name, Target=unit_id, EMode=emode, EFixed=efixed) else: # No need to convert CloneWorkspace(InputWorkspace=input_name, OutputWorkspace=output_name) # Group the temporary factor workspaces (for easy removal later) GroupWorkspaces(InputWorkspaces=[ self._corrections + '_' + f_type for f_type in factor_types ], OutputWorkspace=self._corrections)
def RunParas(ascWS, _instr, run, title): ws = mtd[ascWS] inst = ws.getInstrument() AddSampleLog(Workspace=ascWS, LogName="facility", LogType="String", LogText="ILL") ws.getRun()['run_number'] = run ws.getRun()['run_title'] = title efixed = getEfixed(ascWS) facility = ws.getRun().getLogData('facility').value logger.information('Facility is ' + facility) runNo = ws.getRun()['run_number'].value runTitle = ws.getRun()['run_title'].value.strip() logger.information('Run : ' + str(runNo) + ' ; Title : ' + runTitle) an = inst.getStringParameter('analyser')[0] ref = inst.getStringParameter('reflection')[0] logger.information('Analyser : ' + an + ref + ' with energy = ' + str(efixed)) return efixed
def _pre_process_corrections(self): """ If the sample is not in wavelength then convert the corrections to whatever units the sample is in. """ unit_id = mtd[self._sample_ws_name].getAxis(0).getUnit().unitID() logger.information("x-unit is " + unit_id) factor_types = ["ass"] if self._use_can: factor_types.extend(["acc", "acsc", "assc"]) for factor_type in factor_types: input_name = self._get_correction_factor_ws_name(factor_type) output_name = self._corrections + "_" + factor_type if unit_id != "Wavelength": # Configure conversion if unit_id == "dSpacing": emode = "Elastic" efixed = 0.0 elif unit_id == "DeltaE": emode = "Indirect" from IndirectCommon import getEfixed efixed = getEfixed(mtd[self._sample_ws_name]) else: raise ValueError("Unit %s in sample workspace is not supported" % unit_id) # Do conversion ConvertUnits( InputWorkspace=input_name, OutputWorkspace=output_name, Target=unit_id, EMode=emode, EFixed=efixed ) else: # No need to convert CloneWorkspace(InputWorkspace=input_name, OutputWorkspace=output_name) # Group the temporary factor workspaces (for easy removal later) GroupWorkspaces( InputWorkspaces=[self._corrections + "_" + f_type for f_type in factor_types], OutputWorkspace=self._corrections, )
def AbsRunFeeder(inputws, geom, beam, ncan, size, density, sigs, siga, avar, plotOpt='None'): '''Handles the feeding of input and plotting of output for the F2PY absorption correction routine.''' ws = mtd[inputws] ## workdir is default save directory workdir = mantid.getConfigProperty('defaultsave.directory') ## prefix is instrument short name prefix = ws.getInstrument().getName() prefix = ConfigService().facility().instrument(prefix).shortName().lower() ## sam = run number sam = ws.getRun().getLogData("run_number").value ## efixed can be taken from the instrument parameter file efixed = getEfixed(inputws) ## Run the routine workspaces = AbsRun(workdir, prefix, sam, geom, beam, ncan, size, density, sigs, siga, avar, efixed, inputWS=inputws) if ( plotOpt == 'None' ): return if ( plotOpt == 'Wavelength' or plotOpt == 'Both' ): graph = plotSpectrum(workspaces, 0) if ( plotOpt == 'Angle' or plotOpt == 'Both' ): graph = plotTimeBin(workspaces, 0) graph.activeLayer().setAxisTitle(Layer.Bottom, 'Angle')
def _get_amplitude_and_fwhm_from_fit(self, workspace): from IndirectCommon import getEfixed parameter_values = self._get_fit_parameters_from_fit(workspace, getEfixed(self._temporary_fit_name)) return parameter_values[0], parameter_values[2]
def PyExec(self): from IndirectCommon import getEfixed self._setup() # Set up progress reporting n_prog_reports = 2 if self._can_ws_name is not None: n_prog_reports += 1 prog = Progress(self, 0.0, 1.0, n_prog_reports) efixed = getEfixed(self._sample_ws_name) sample_wave_ws = '__sam_wave' ConvertUnits(InputWorkspace=self._sample_ws_name, OutputWorkspace=sample_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed, EnableLogging=False) sample_thickness = self._sample_outer_radius - self._sample_inner_radius logger.information('Sample thickness: ' + str(sample_thickness)) prog.report('Calculating sample corrections') if self._sample_density_type == 'Mass Density': builder = MaterialBuilder() mat = builder.setFormula( self._sample_chemical_formula).setMassDensity( self._sample_density).build() self._sample_density = mat.numberDensity SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_density) AnnularRingAbsorption( InputWorkspace=sample_wave_ws, OutputWorkspace=self._ass_ws, SampleHeight=3.0, SampleThickness=sample_thickness, CanInnerRadius=self._can_inner_radius, CanOuterRadius=self._can_outer_radius, SampleChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_density, NumberOfWavelengthPoints=10, EventsPerPoint=self._events) group = self._ass_ws if self._can_ws_name is not None: can1_wave_ws = '__can1_wave' can2_wave_ws = '__can2_wave' ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can1_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed, EnableLogging=False) if self._can_scale != 1.0: logger.information('Scaling container by: ' + str(self._can_scale)) Scale(InputWorkspace=can1_wave_ws, OutputWorkspace=can1_wave_ws, Factor=self._can_scale, Operation='Multiply') CloneWorkspace(InputWorkspace=can1_wave_ws, OutputWorkspace=can2_wave_ws, EnableLogging=False) can_thickness_1 = self._sample_inner_radius - self._can_inner_radius can_thickness_2 = self._can_outer_radius - self._sample_outer_radius logger.information('Container thickness: %f & %f' % (can_thickness_1, can_thickness_2)) if self._use_can_corrections: prog.report('Calculating container corrections') Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) if self._can_density_type == 'Mass Density': builder = MaterialBuilder() mat = builder.setFormula( self._can_chemical_formula).setMassDensity( self._can_density).build() self._can_density = mat.numberDensity SetSampleMaterial(can1_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_density) AnnularRingAbsorption( InputWorkspace=can1_wave_ws, OutputWorkspace='__Acc1', SampleHeight=3.0, SampleThickness=can_thickness_1, CanInnerRadius=self._can_inner_radius, CanOuterRadius=self._sample_outer_radius, SampleChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_density, NumberOfWavelengthPoints=10, EventsPerPoint=self._events) SetSampleMaterial(can2_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_density) AnnularRingAbsorption( InputWorkspace=can2_wave_ws, OutputWorkspace='__Acc2', SampleHeight=3.0, SampleThickness=can_thickness_2, CanInnerRadius=self._sample_inner_radius, CanOuterRadius=self._can_outer_radius, SampleChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_density, NumberOfWavelengthPoints=10, EventsPerPoint=self._events) Multiply(LHSWorkspace='__Acc1', RHSWorkspace='__Acc2', OutputWorkspace=self._acc_ws, EnableLogging=False) DeleteWorkspace('__Acc1', EnableLogging=False) DeleteWorkspace('__Acc2', EnableLogging=False) Divide(LHSWorkspace=can1_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can1_wave_ws) Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can1_wave_ws, OutputWorkspace=sample_wave_ws) group += ',' + self._acc_ws else: prog.report('Calculating can scaling') Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can1_wave_ws, OutputWorkspace=sample_wave_ws) Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) DeleteWorkspace(can1_wave_ws, EnableLogging=False) DeleteWorkspace(can2_wave_ws, EnableLogging=False) else: Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws, Target='DeltaE', EMode='Indirect', EFixed=efixed, EnableLogging=False) DeleteWorkspace(sample_wave_ws, EnableLogging=False) prog.report('Recording sample logs') sample_log_workspaces = [self._output_ws, self._ass_ws] sample_logs = [('sample_shape', 'annulus'), ('sample_filename', self._sample_ws_name), ('sample_inner', self._sample_inner_radius), ('sample_outer', self._sample_outer_radius), ('can_inner', self._can_inner_radius), ('can_outer', self._can_outer_radius)] if self._can_ws_name is not None: sample_logs.append(('container_filename', self._can_ws_name)) sample_logs.append(('container_scale', self._can_scale)) if self._use_can_corrections: sample_log_workspaces.append(self._acc_ws) sample_logs.append(('container_thickness_1', can_thickness_1)) sample_logs.append(('container_thickness_2', can_thickness_2)) log_names = [item[0] for item in sample_logs] log_values = [item[1] for item in sample_logs] for ws_name in sample_log_workspaces: AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values, EnableLogging=False) self.setProperty('OutputWorkspace', self._output_ws) # Output the Ass workspace if it is wanted, delete if not if self._abs_ws == '': DeleteWorkspace(self._ass_ws, EnableLogging=False) if self._can_ws_name is not None and self._use_can_corrections: DeleteWorkspace(self._acc_ws, EnableLogging=False) else: GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws, EnableLogging=False) self.setProperty('CorrectionsWorkspace', self._abs_ws)
def PyExec(self): # Check for platform support if not is_supported_f2py_platform(): unsupported_msg = "This algorithm can only be run on valid platforms." \ + " please view the algorithm documentation to see" \ + " what platforms are currently supported" raise RuntimeError(unsupported_msg) from IndirectBayes import (CalcErange, GetXYE, ReadNormFile, ReadWidthFile, QLAddSampleLogs, C2Fw, C2Se, QuasiPlot) from IndirectCommon import (CheckXrange, CheckAnalysers, getEfixed, GetThetaQ, CheckHistZero, CheckHistSame, IndentifyDataBoundaries) setup_prog = Progress(self, start=0.0, end=0.3, nreports=5) self.log().information('BayesQuasi input') erange = [self._e_min, self._e_max] nbins = [self._sam_bins, self._res_bins] setup_prog.report('Converting to binary for Fortran') #convert true/false to 1/0 for fortran o_el = 1 if self._elastic else 0 o_w1 = 1 if self._width else 0 o_res = 1 if self._res_norm else 0 #fortran code uses background choices defined using the following numbers setup_prog.report('Encoding input options') if self._background == 'Sloping': o_bgd = 2 elif self._background == 'Flat': o_bgd = 1 elif self._background == 'Zero': o_bgd = 0 fitOp = [o_el, o_bgd, o_w1, o_res] setup_prog.report('Establishing save path') workdir = config['defaultsave.directory'] if not os.path.isdir(workdir): workdir = os.getcwd() logger.information( 'Default Save directory is not set. Defaulting to current working Directory: ' + workdir) array_len = 4096 # length of array in Fortran setup_prog.report('Checking X Range') CheckXrange(erange, 'Energy') nbin, nrbin = nbins[0], nbins[1] logger.information('Sample is ' + self._samWS) logger.information('Resolution is ' + self._resWS) # Check for trailing and leading zeros in data setup_prog.report( 'Checking for leading and trailing zeros in the data') first_data_point, last_data_point = IndentifyDataBoundaries( self._samWS) if first_data_point > self._e_min: logger.warning( "Sample workspace contains leading zeros within the energy range." ) logger.warning("Updating eMin: eMin = " + str(first_data_point)) self._e_min = first_data_point if last_data_point < self._e_max: logger.warning( "Sample workspace contains trailing zeros within the energy range." ) logger.warning("Updating eMax: eMax = " + str(last_data_point)) self._e_max = last_data_point # update erange with new values erange = [self._e_min, self._e_max] setup_prog.report('Checking Analysers') CheckAnalysers(self._samWS, self._resWS) setup_prog.report('Obtaining EFixed, theta and Q') efix = getEfixed(self._samWS) theta, Q = GetThetaQ(self._samWS) nsam, ntc = CheckHistZero(self._samWS) totalNoSam = nsam #check if we're performing a sequential fit if self._loop != True: nsam = 1 nres = CheckHistZero(self._resWS)[0] setup_prog.report('Checking Histograms') if self._program == 'QL': if nres == 1: prog = 'QLr' # res file else: prog = 'QLd' # data file CheckHistSame(self._samWS, 'Sample', self._resWS, 'Resolution') elif self._program == 'QSe': if nres == 1: prog = 'QSe' # res file else: raise ValueError('Stretched Exp ONLY works with RES file') logger.information('Version is ' + prog) logger.information(' Number of spectra = ' + str(nsam)) logger.information(' Erange : ' + str(erange[0]) + ' to ' + str(erange[1])) setup_prog.report('Reading files') Wy, We = ReadWidthFile(self._width, self._wfile, totalNoSam) dtn, xsc = ReadNormFile(self._res_norm, self._resnormWS, totalNoSam) setup_prog.report('Establishing output workspace name') fname = self._samWS[:-4] + '_' + prog probWS = fname + '_Prob' fitWS = fname + '_Fit' wrks = os.path.join(workdir, self._samWS[:-4]) logger.information(' lptfile : ' + wrks + '_' + prog + '.lpt') lwrk = len(wrks) wrks.ljust(140, ' ') wrkr = self._resWS wrkr.ljust(140, ' ') setup_prog.report('Initialising probability list') # initialise probability list if self._program == 'QL': prob0 = [] prob1 = [] prob2 = [] xQ = np.array([Q[0]]) for m in range(1, nsam): xQ = np.append(xQ, Q[m]) xProb = xQ xProb = np.append(xProb, xQ) xProb = np.append(xProb, xQ) eProb = np.zeros(3 * nsam) group = '' workflow_prog = Progress(self, start=0.3, end=0.7, nreports=nsam * 3) for m in range(0, nsam): logger.information('Group ' + str(m) + ' at angle ' + str(theta[m])) nsp = m + 1 nout, bnorm, Xdat, Xv, Yv, Ev = CalcErange(self._samWS, m, erange, nbin) Ndat = nout[0] Imin = nout[1] Imax = nout[2] if prog == 'QLd': mm = m else: mm = 0 Nb, Xb, Yb, Eb = GetXYE(self._resWS, mm, array_len) # get resolution data numb = [nsam, nsp, ntc, Ndat, nbin, Imin, Imax, Nb, nrbin] rscl = 1.0 reals = [efix, theta[m], rscl, bnorm] if prog == 'QLr': workflow_prog.report( 'Processing Sample number %i as Lorentzian' % nsam) nd, xout, yout, eout, yfit, yprob = QLr.qlres( numb, Xv, Yv, Ev, reals, fitOp, Xdat, Xb, Yb, Wy, We, dtn, xsc, wrks, wrkr, lwrk) message = ' Log(prob) : ' + str(yprob[0]) + ' ' + str( yprob[1]) + ' ' + str(yprob[2]) + ' ' + str(yprob[3]) logger.information(message) if prog == 'QLd': workflow_prog.report('Processing Sample number %i' % nsam) nd, xout, yout, eout, yfit, yprob = QLd.qldata( numb, Xv, Yv, Ev, reals, fitOp, Xdat, Xb, Yb, Eb, Wy, We, wrks, wrkr, lwrk) message = ' Log(prob) : ' + str(yprob[0]) + ' ' + str( yprob[1]) + ' ' + str(yprob[2]) + ' ' + str(yprob[3]) logger.information(message) if prog == 'QSe': workflow_prog.report( 'Processing Sample number %i as Stretched Exp' % nsam) nd,xout,yout,eout,yfit,yprob=Qse.qlstexp(numb,Xv,Yv,Ev,reals,fitOp,\ Xdat,Xb,Yb,Wy,We,dtn,xsc,\ wrks,wrkr,lwrk) dataX = xout[:nd] dataX = np.append(dataX, 2 * xout[nd - 1] - xout[nd - 2]) yfit_list = np.split(yfit[:4 * nd], 4) dataF1 = yfit_list[1] if self._program == 'QL': dataF2 = yfit_list[2] workflow_prog.report('Processing data') dataG = np.zeros(nd) datX = dataX datY = yout[:nd] datE = eout[:nd] datX = np.append(datX, dataX) datY = np.append(datY, dataF1[:nd]) datE = np.append(datE, dataG) res1 = dataF1[:nd] - yout[:nd] datX = np.append(datX, dataX) datY = np.append(datY, res1) datE = np.append(datE, dataG) nsp = 3 names = 'data,fit.1,diff.1' res_plot = [0, 1, 2] if self._program == 'QL': workflow_prog.report('Processing Lorentzian result data') datX = np.append(datX, dataX) datY = np.append(datY, dataF2[:nd]) datE = np.append(datE, dataG) res2 = dataF2[:nd] - yout[:nd] datX = np.append(datX, dataX) datY = np.append(datY, res2) datE = np.append(datE, dataG) nsp += 2 names += ',fit.2,diff.2' res_plot.append(4) prob0.append(yprob[0]) prob1.append(yprob[1]) prob2.append(yprob[2]) # create result workspace fitWS = fname + '_Workspaces' fout = fname + '_Workspace_' + str(m) workflow_prog.report('Creating OutputWorkspace') CreateWorkspace(OutputWorkspace=fout, DataX=datX, DataY=datY, DataE=datE,\ Nspec=nsp, UnitX='DeltaE', VerticalAxisUnit='Text', VerticalAxisValues=names) # append workspace to list of results group += fout + ',' comp_prog = Progress(self, start=0.7, end=0.8, nreports=2) comp_prog.report('Creating Group Workspace') GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=fitWS) if self._program == 'QL': comp_prog.report('Processing Lorentzian probability data') yPr0 = np.array([prob0[0]]) yPr1 = np.array([prob1[0]]) yPr2 = np.array([prob2[0]]) for m in range(1, nsam): yPr0 = np.append(yPr0, prob0[m]) yPr1 = np.append(yPr1, prob1[m]) yPr2 = np.append(yPr2, prob2[m]) yProb = yPr0 yProb = np.append(yProb, yPr1) yProb = np.append(yProb, yPr2) probWs = CreateWorkspace(OutputWorkspace=probWS, DataX=xProb, DataY=yProb, DataE=eProb,\ Nspec=3, UnitX='MomentumTransfer') outWS = C2Fw(self._samWS[:-4], fname) if self._plot != 'None': QuasiPlot(fname, self._plot, res_plot, self._loop) if self._program == 'QSe': comp_prog.report('Runnning C2Se') outWS = C2Se(fname) if self._plot != 'None': QuasiPlot(fname, self._plot, res_plot, self._loop) log_prog = Progress(self, start=0.8, end=1.0, nreports=8) #Add some sample logs to the output workspaces log_prog.report('Copying Logs to outputWorkspace') CopyLogs(InputWorkspace=self._samWS, OutputWorkspace=outWS) log_prog.report('Adding Sample logs to Output workspace') QLAddSampleLogs(outWS, self._resWS, prog, self._background, self._elastic, erange, (nbin, nrbin), self._resnormWS, self._wfile) log_prog.report('Copying logs to fit Workspace') CopyLogs(InputWorkspace=self._samWS, OutputWorkspace=fitWS) log_prog.report('Adding sample logs to Fit workspace') QLAddSampleLogs(fitWS, self._resWS, prog, self._background, self._elastic, erange, (nbin, nrbin), self._resnormWS, self._wfile) log_prog.report('Finialising log copying') if self._save: log_prog.report('Saving workspaces') fit_path = os.path.join(workdir, fitWS + '.nxs') SaveNexusProcessed(InputWorkspace=fitWS, Filename=fit_path) out_path = os.path.join(workdir, outWS + '.nxs') # path name for nxs file SaveNexusProcessed(InputWorkspace=outWS, Filename=out_path) logger.information('Output fit file created : ' + fit_path) logger.information('Output paramter file created : ' + out_path) self.setProperty('OutputWorkspaceFit', fitWS) self.setProperty('OutputWorkspaceResult', outWS) log_prog.report('Setting workspace properties') if self._program == 'QL': self.setProperty('OutputWorkspaceProb', probWS)
def PyExec(self): from IndirectCommon import getEfixed self._setup() # Set up progress reporting n_prog_reports = 2 if self._can_ws_name is not None: n_prog_reports += 1 prog = Progress(self, 0.0, 1.0, n_prog_reports) efixed = getEfixed(self._sample_ws) sample_wave_ws = '__sam_wave' ConvertUnits(InputWorkspace=self._sample_ws, OutputWorkspace=sample_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed) SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_number_density) prog.report('Calculating sample corrections') FlatPlateAbsorption(InputWorkspace=sample_wave_ws, OutputWorkspace=self._ass_ws, SampleHeight=self._sample_height, SampleWidth=self._sample_width, SampleThickness=self._sample_thickness, ElementSize=self._element_size, EMode='Indirect', EFixed=efixed, NumberOfWavelengthPoints=10) plot_data = [self._output_ws, self._sample_ws] plot_corr = [self._ass_ws] group = self._ass_ws if self._can_ws_name is not None: can_wave_ws = '__can_wave' ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed) if self._can_scale != 1.0: logger.information('Scaling container by: ' + str(self._can_scale)) Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply') if self._use_can_corrections: prog.report('Calculating container corrections') Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) SetSampleMaterial(can_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_number_density) FlatPlateAbsorption(InputWorkspace=can_wave_ws, OutputWorkspace=self._acc_ws, SampleHeight=self._sample_height, SampleWidth=self._sample_width, SampleThickness=self._can_front_thickness + self._can_back_thickness, ElementSize=self._element_size, EMode='Indirect', EFixed=efixed, NumberOfWavelengthPoints=10) Divide(LHSWorkspace=can_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can_wave_ws) Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) plot_corr.append(self._acc_ws) group += ',' + self._acc_ws else: prog.report('Calculating container scaling') Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) DeleteWorkspace(can_wave_ws) plot_data.append(self._can_ws_name) else: Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws, Target='DeltaE', EMode='Indirect', EFixed=efixed) DeleteWorkspace(sample_wave_ws) prog.report('Recording samle logs') sample_log_workspaces = [self._output_ws, self._ass_ws] sample_logs = [('sample_shape', 'flatplate'), ('sample_filename', self._sample_ws), ('sample_height', self._sample_height), ('sample_width', self._sample_width), ('sample_thickness', self._sample_thickness), ('element_size', self._element_size)] if self._can_ws_name is not None: sample_logs.append(('container_filename', self._can_ws_name)) sample_logs.append(('container_scale', self._can_scale)) if self._use_can_corrections: sample_log_workspaces.append(self._acc_ws) sample_logs.append(('container_front_thickness', self. _can_front_thickness)) sample_logs.append(('container_back_thickness', self. _can_back_thickness)) log_names = [item[0] for item in sample_logs] log_values = [item[1] for item in sample_logs] for ws_name in sample_log_workspaces: AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values) self.setProperty('OutputWorkspace', self._output_ws) # Output the Ass workspace if it is wanted, delete if not if self._abs_ws == '': DeleteWorkspace(self._ass_ws) if self._can_ws_name is not None and self._use_can_corrections: DeleteWorkspace(self._acc_ws) else: GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws) self.setProperty('CorrectionsWorkspace', self._abs_ws) if self._plot: from IndirectImport import import_mantidplot mantid_plot = import_mantidplot() mantid_plot.plotSpectrum(plot_data, 0) if self._abs_ws != '': mantid_plot.plotSpectrum(plot_corr, 0)
def PyExec(self): from IndirectCommon import getEfixed self._setup() # Set up progress reporting n_prog_reports = 2 if self._can_ws_name is not None: n_prog_reports += 1 prog = Progress(self, 0.0, 1.0, n_prog_reports) efixed = getEfixed(self._sample_ws) sample_wave_ws = "__sam_wave" ConvertUnits( InputWorkspace=self._sample_ws, OutputWorkspace=sample_wave_ws, Target="Wavelength", EMode="Indirect", EFixed=efixed, EnableLogging=False, ) if self._sample_density_type == "Mass Density": builder = MaterialBuilder() mat = builder.setFormula(self._sample_chemical_formula).setMassDensity(self._sample_density).build() self._sample_density = mat.numberDensity SetSampleMaterial( sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_density ) prog.report("Calculating sample corrections") FlatPlateAbsorption( InputWorkspace=sample_wave_ws, OutputWorkspace=self._ass_ws, SampleHeight=self._sample_height, SampleWidth=self._sample_width, SampleThickness=self._sample_thickness, ElementSize=self._element_size, EMode="Indirect", EFixed=efixed, NumberOfWavelengthPoints=10, ) group = self._ass_ws if self._can_ws_name is not None: can_wave_ws = "__can_wave" ConvertUnits( InputWorkspace=self._can_ws_name, OutputWorkspace=can_wave_ws, Target="Wavelength", EMode="Indirect", EFixed=efixed, EnableLogging=False, ) if self._can_scale != 1.0: logger.information("Scaling container by: " + str(self._can_scale)) Scale( InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation="Multiply", ) if self._use_can_corrections: prog.report("Calculating container corrections") Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) if self._sample_density_type == "Mass Density": builder = MaterialBuilder() mat = builder.setFormula(self._can_chemical_formula).setMassDensity(self._can_density).build() self._can_density = mat.numberDensity SetSampleMaterial( can_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_density ) FlatPlateAbsorption( InputWorkspace=can_wave_ws, OutputWorkspace=self._acc_ws, SampleHeight=self._sample_height, SampleWidth=self._sample_width, SampleThickness=self._can_front_thickness + self._can_back_thickness, ElementSize=self._element_size, EMode="Indirect", EFixed=efixed, NumberOfWavelengthPoints=10, ) Divide(LHSWorkspace=can_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can_wave_ws) Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) group += "," + self._acc_ws else: prog.report("Calculating container scaling") Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) DeleteWorkspace(can_wave_ws, EnableLogging=False) else: Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) ConvertUnits( InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws, Target="DeltaE", EMode="Indirect", EFixed=efixed, EnableLogging=False, ) DeleteWorkspace(sample_wave_ws, EnableLogging=False) prog.report("Recording sample logs") sample_log_workspaces = [self._output_ws, self._ass_ws] sample_logs = [ ("sample_shape", "flatplate"), ("sample_filename", self._sample_ws), ("sample_height", self._sample_height), ("sample_width", self._sample_width), ("sample_thickness", self._sample_thickness), ("element_size", self._element_size), ] if self._can_ws_name is not None: sample_logs.append(("container_filename", self._can_ws_name)) sample_logs.append(("container_scale", self._can_scale)) if self._use_can_corrections: sample_log_workspaces.append(self._acc_ws) sample_logs.append(("container_front_thickness", self._can_front_thickness)) sample_logs.append(("container_back_thickness", self._can_back_thickness)) log_names = [item[0] for item in sample_logs] log_values = [item[1] for item in sample_logs] for ws_name in sample_log_workspaces: AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values, EnableLogging=False) self.setProperty("OutputWorkspace", self._output_ws) # Output the Ass workspace if it is wanted, delete if not if self._abs_ws == "": DeleteWorkspace(self._ass_ws, EnableLogging=False) if self._can_ws_name is not None and self._use_can_corrections: DeleteWorkspace(self._acc_ws, EnableLogging=False) else: GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws, EnableLogging=False) self.setProperty("CorrectionsWorkspace", self._abs_ws)
def _ascii_import(self, data, name): """ Import ASCII data. @param data Raw ASCII data @param name Name of data file """ from IndirectCommon import getEfixed from IndirectNeutron import ChangeAngles, InstrParas logger.notice('Loading ASCII data: %s' % name) val = _split_line(data[3]) Q = [] for n in range(1, len(val)): Q.append(val[n]) nQ = len(Q) x = [] y = [] for n in range(4, len(data)): val = _split_line(data[n]) x.append(val[0]) yval = val[1:] y.append(yval) nX = len(x) logger.information('nQ = ' + str(nQ)) logger.information('nT = ' + str(nX)) xT = np.array(x) eZero = np.zeros(nX) #Qaxis = '' for m in range(0, nQ): logger.information('Q[' + str(m + 1) + '] : ' + str(Q[m])) S = [] for n in range(0, nX): S.append(y[n][m]) if m == 0: #Qaxis += str(Q[m]) xDat = xT yDat = np.array(S) eDat = eZero else: #Qaxis += ',' + str(Q[m]) xDat = np.append(xDat, xT) yDat = np.append(yDat, np.array(S)) eDat = np.append(eDat, eZero) CreateWorkspace(OutputWorkspace=self._out_ws, DataX=xDat, DataY=yDat, DataE=eDat, Nspec=nQ, UnitX='TOF') Qmax = Q[nQ - 1] instr = 'MolDyn' ana = 'simul' if Qmax <= 2.0: refl = '2' else: refl = '4' InstrParas(self._out_ws, instr, ana, refl) efixed = getEfixed(self._out_ws)# RunParas(self._out_ws, instr, name, name) logger.information('Qmax = ' + str(Qmax) + ' ; efixed = ' + str(efixed)) pi4 = 4.0 * math.pi wave = 1.8 * math.sqrt(25.2429 / efixed) theta = [] for n in range(0, nQ): qw = wave * Q[n] / pi4 ang = 2.0 * math.degrees(math.asin(qw)) theta.append(ang) ChangeAngles(self._out_ws, instr, theta)
def _ascii_3d_import(self): """ Import 3D ASCII data (e.g. I(Q, t)). """ logger.notice('Loading ASCII data') from IndirectCommon import getEfixed from IndirectNeutron import ChangeAngles, InstrParas # Read file data = [] x_axis = ('time', 'ns') v_axis = ('q', 'ang^-1') with open(self._file_name, 'r') as handle: for line in handle: line = line.strip() # Ignore empty lines if line == '': continue # Data line (if not comment) elif line.strip()[0] != '#': line_values = np.array([ ast.literal_eval(t.strip()) if 'nan' not in t.lower() else np.nan for t in line.split() ]) data.append(line_values) if x_axis is None or v_axis is None: raise ValueError('Data is not in expected format for 3D data') logger.debug('X axis: {0}'.format(x_axis)) logger.debug('V axis: {0}'.format(v_axis)) # Get axis and Y values data = np.swapaxes(np.array(data), 0, 1) x_axis_values = data[0, 1:] v_axis_values = data[1:, 0] y_values = np.ravel(data[1:, 1:]) # Create the workspace wks = CreateWorkspace(OutputWorkspace=self._out_ws, DataX=x_axis_values, DataY=y_values, NSpec=v_axis_values.size, UnitX=x_axis[1], EnableLogging=False) # Load the MolDyn instrument q_max = v_axis_values[-1] instrument = 'MolDyn' reflection = '2' if q_max <= 2.0 else '4' InstrParas(wks.name(), instrument, 'simul', reflection) # Process angles efixed = getEfixed(wks.name()) logger.information('Qmax={0}, Efixed={1}'.format(q_max, efixed)) wave = 1.8 * math.sqrt(25.2429 / efixed) qw = wave * v_axis_values / (4.0 * math.pi) theta = 2.0 * np.degrees(np.arcsin(qw)) ChangeAngles(wks.name(), instrument, theta) return wks
def PyExec(self): from IndirectCommon import getEfixed self._setup() # Set up progress reporting n_prog_reports = 2 if self._can_ws_name is not None: n_prog_reports += 1 prog = Progress(self, 0.0, 1.0, n_prog_reports) efixed = getEfixed(self._sample_ws) sample_wave_ws = '__sam_wave' ConvertUnits(InputWorkspace=self._sample_ws, OutputWorkspace=sample_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed, EnableLogging = False) if self._sample_density_type == 'Mass Density': builder = MaterialBuilder() mat = builder.setFormula(self._sample_chemical_formula).setMassDensity(self._sample_density).build() self._sample_density = mat.numberDensity SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_density) prog.report('Calculating sample corrections') FlatPlateAbsorption(InputWorkspace=sample_wave_ws, OutputWorkspace=self._ass_ws, SampleHeight=self._sample_height, SampleWidth=self._sample_width, SampleThickness=self._sample_thickness, ElementSize=self._element_size, EMode='Indirect', EFixed=efixed, NumberOfWavelengthPoints=10) group = self._ass_ws if self._can_ws_name is not None: can_wave_ws = '__can_wave' ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed, EnableLogging = False) if self._can_scale != 1.0: logger.information('Scaling container by: ' + str(self._can_scale)) Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply') if self._use_can_corrections: prog.report('Calculating container corrections') Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) if self._sample_density_type == 'Mass Density': builder = MaterialBuilder() mat = builder.setFormula(self._can_chemical_formula).setMassDensity(self._can_density).build() self._can_density = mat.numberDensity SetSampleMaterial(can_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_density) FlatPlateAbsorption(InputWorkspace=can_wave_ws, OutputWorkspace=self._acc_ws, SampleHeight=self._sample_height, SampleWidth=self._sample_width, SampleThickness=self._can_front_thickness + self._can_back_thickness, ElementSize=self._element_size, EMode='Indirect', EFixed=efixed, NumberOfWavelengthPoints=10) Divide(LHSWorkspace=can_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can_wave_ws) Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) group += ',' + self._acc_ws else: prog.report('Calculating container scaling') Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) DeleteWorkspace(can_wave_ws, EnableLogging = False) else: Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws, Target='DeltaE', EMode='Indirect', EFixed=efixed, EnableLogging = False) DeleteWorkspace(sample_wave_ws, EnableLogging = False) prog.report('Recording sample logs') sample_log_workspaces = [self._output_ws, self._ass_ws] sample_logs = [('sample_shape', 'flatplate'), ('sample_filename', self._sample_ws), ('sample_height', self._sample_height), ('sample_width', self._sample_width), ('sample_thickness', self._sample_thickness), ('element_size', self._element_size)] if self._can_ws_name is not None: sample_logs.append(('container_filename', self._can_ws_name)) sample_logs.append(('container_scale', self._can_scale)) if self._use_can_corrections: sample_log_workspaces.append(self._acc_ws) sample_logs.append(('container_front_thickness', self. _can_front_thickness)) sample_logs.append(('container_back_thickness', self. _can_back_thickness)) log_names = [item[0] for item in sample_logs] log_values = [item[1] for item in sample_logs] for ws_name in sample_log_workspaces: AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values, EnableLogging = False) self.setProperty('OutputWorkspace', self._output_ws) # Output the Ass workspace if it is wanted, delete if not if self._abs_ws == '': DeleteWorkspace(self._ass_ws, EnableLogging = False) if self._can_ws_name is not None and self._use_can_corrections: DeleteWorkspace(self._acc_ws, EnableLogging = False) else: GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws, EnableLogging = False) self.setProperty('CorrectionsWorkspace', self._abs_ws)
def _get_e_fixed(self, workspace): from IndirectCommon import getEfixed return getEfixed(workspace)
def PyExec(self): run_f2py_compatibility_test() from IndirectBayes import (CalcErange, GetXYE) from IndirectCommon import (CheckXrange, CheckAnalysers, getEfixed, GetThetaQ, CheckHistZero) setup_prog = Progress(self, start=0.0, end=0.3, nreports = 5) logger.information('BayesStretch input') logger.information('Sample is %s' % self._sam_name) logger.information('Resolution is %s' % self._res_name) setup_prog.report('Converting to binary for Fortran') fitOp = self._encode_fit_ops(self._elastic, self._background) setup_prog.report('Establishing save path') workdir = self._establish_save_path() setup_prog.report('Checking X Range') CheckXrange(self._erange, 'Energy') setup_prog.report('Checking Analysers') CheckAnalysers(self._sam_name, self._res_name) setup_prog.report('Obtaining EFixed, theta and Q') efix = getEfixed(self._sam_name) theta, Q = GetThetaQ(self._sam_name) setup_prog.report('Checking Histograms') nsam,ntc = CheckHistZero(self._sam_name) #check if we're performing a sequential fit if self._loop != True: nsam = 1 logger.information('Version is Stretch') logger.information('Number of spectra = %s ' % nsam) logger.information('Erange : %f to %f ' % (self._erange[0], self._erange[1])) setup_prog.report('Creating FORTRAN Input') fname = self._sam_name[:-4] + '_Stretch' wrks=os.path.join(workdir, self._sam_name[:-4]) logger.information('lptfile : %s_Qst.lpt' % wrks) lwrk=len(wrks) wrks.ljust(140, ' ') wrkr=self._res_name wrkr.ljust(140, ' ') eBet0 = np.zeros(self._nbet) # set errors to zero eSig0 = np.zeros(self._nsig) # set errors to zero rscl = 1.0 Qaxis = '' workflow_prog = Progress(self, start=0.3, end=0.7, nreports=nsam*3) # Empty arrays to hold Sigma and Bet x,y,e values xSig, ySig, eSig = [],[],[] xBet, yBet, eBet = [],[],[] for m in range(nsam): logger.information('Group %i at angle %f' % (m, theta[m])) nsp = m + 1 nout, bnorm, Xdat, Xv, Yv, Ev = CalcErange(self._sam_name, m, self._erange, self._nbins[0]) Ndat = nout[0] Imin = nout[1] Imax = nout[2] # get resolution data (4096 = FORTRAN array length) Nb, Xb, Yb, _ = GetXYE(self._res_name, 0, 4096) numb = [nsam, nsp, ntc, Ndat, self._nbins[0], Imin, Imax, Nb, self._nbins[1], self._nbet, self._nsig] reals = [efix, theta[m], rscl, bnorm] workflow_prog.report('Processing spectrum number %i' % m) xsout, ysout, xbout, ybout, zpout=Que.quest(numb, Xv, Yv, Ev, reals, fitOp, Xdat, Xb, Yb, wrks, wrkr, lwrk) dataXs = xsout[:self._nsig] # reduce from fixed FORTRAN array dataYs = ysout[:self._nsig] dataXb = xbout[:self._nbet] dataYb = ybout[:self._nbet] zpWS = fname + '_Zp' +str(m) if m > 0: Qaxis += ',' Qaxis += str(Q[m]) dataXz = [] dataYz = [] dataEz = [] for n in range(self._nsig): yfit_list = np.split(zpout[:self._nsig*self._nbet], self._nsig) dataYzp = yfit_list[n] dataXz = np.append(dataXz, xbout[:self._nbet]) dataYz = np.append(dataYz, dataYzp[:self._nbet]) dataEz = np.append(dataEz, eBet0) zpWS = fname + '_Zp' + str(m) self._create_workspace(zpWS, [dataXz, dataYz, dataEz], self._nsig, dataXs, True) xSig = np.append(xSig,dataXs) ySig = np.append(ySig,dataYs) eSig = np.append(eSig,eSig0) xBet = np.append(xBet,dataXb) yBet = np.append(yBet,dataYb) eBet = np.append(eBet,eBet0) if m == 0: groupZ = zpWS else: groupZ = groupZ +','+ zpWS #create workspaces for sigma and beta workflow_prog.report('Creating OutputWorkspace') self._create_workspace(fname + '_Sigma', [xSig, ySig, eSig], nsam, Qaxis) self._create_workspace(fname + '_Beta', [xBet, yBet, eBet], nsam, Qaxis) group = fname + '_Sigma,' + fname + '_Beta' fit_ws = fname + '_Fit' s_api.GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=fit_ws) contour_ws = fname + '_Contour' s_api.GroupWorkspaces(InputWorkspaces=groupZ, OutputWorkspace=contour_ws) #Add some sample logs to the output workspaces log_prog = Progress(self, start=0.8, end =1.0, nreports=6) log_prog.report('Copying Logs to Fit workspace') copy_log_alg = self.createChildAlgorithm('CopyLogs', enableLogging=False) copy_log_alg.setProperty('InputWorkspace', self._sam_name) copy_log_alg.setProperty('OutputWorkspace',fit_ws) copy_log_alg.execute() log_prog.report('Adding Sample logs to Fit workspace') self._add_sample_logs(fit_ws, self._erange, self._nbins[0]) log_prog.report('Copying logs to Contour workspace') copy_log_alg.setProperty('InputWorkspace',self._sam_name) copy_log_alg.setProperty('OutputWorkspace',contour_ws) copy_log_alg.execute() log_prog.report('Adding sample logs to Contour workspace') self._add_sample_logs(contour_ws, self._erange, self._nbins[0]) log_prog.report('Finialising log copying') self.setProperty('OutputWorkspaceFit', fit_ws) self.setProperty('OutputWorkspaceContour', contour_ws) log_prog.report('Setting workspace properties')
def _calculate_parameters(self): """ Calculates the TransformToIqt parameters and saves in a table workspace. """ from IndirectCommon import getEfixed end_prog = 0.3 if self._calculate_errors else 0.9 workflow_prog = Progress(self, start=0.0, end=end_prog, nreports=8) workflow_prog.report('Cropping Workspace') CropWorkspace(InputWorkspace=self._sample, OutputWorkspace='__TransformToIqt_sample_cropped', Xmin=self._e_min, Xmax=self._e_max) workflow_prog.report('Calculating table properties') x_data = mtd['__TransformToIqt_sample_cropped'].readX(0) number_input_points = len(x_data) - 1 num_bins = int(number_input_points / self._number_points_per_bin) self._e_width = (abs(self._e_min) + abs(self._e_max)) / num_bins workflow_prog.report('Attempting to Access IPF') try: workflow_prog.report('Access IPF') instrument = mtd[self._sample].getInstrument() analyserName = instrument.getStringParameter('analyser')[0] analyser = instrument.getComponentByName(analyserName) if analyser is not None: logger.debug( 'Found %s component in instrument %s, will look for resolution there' % (analyserName, instrument)) resolution = analyser.getNumberParameter('resolution')[0] else: logger.debug( 'No %s component found on instrument %s, will look for resolution in top level instrument' % (analyserName, instrument)) resolution = instrument.getNumberParameter('resolution')[0] logger.information('Got resolution from IPF: %f' % resolution) workflow_prog.report('IPF resolution obtained') except (AttributeError, IndexError): workflow_prog.report('Resorting to Default') resolution = getEfixed(self._sample) * 0.01 logger.warning( 'Could not get the resolution from the IPF, using 1% of the E Fixed value for the ' 'resolution: {0}'.format(resolution)) resolution_bins = int(round((2 * resolution) / self._e_width)) if resolution_bins < 5: logger.warning( 'Resolution curve has <5 points. Results may be unreliable.') workflow_prog.report('Creating Parameter table') param_table = CreateEmptyTableWorkspace( OutputWorkspace=self._parameter_table) workflow_prog.report('Populating Parameter table') param_table.addColumn('int', 'SampleInputBins') param_table.addColumn('float', 'BinReductionFactor') param_table.addColumn('int', 'SampleOutputBins') param_table.addColumn('float', 'EnergyMin') param_table.addColumn('float', 'EnergyMax') param_table.addColumn('float', 'EnergyWidth') param_table.addColumn('float', 'Resolution') param_table.addColumn('int', 'ResolutionBins') param_table.addRow([ number_input_points, self._number_points_per_bin, num_bins, self._e_min, self._e_max, self._e_width, resolution, resolution_bins ]) workflow_prog.report('Deleting temp Workspace') if mtd.doesExist('__TransformToIqt_sample_cropped'): DeleteWorkspace('__TransformToIqt_sample_cropped') self.setProperty('ParameterWorkspace', param_table)
def _calculate_parameters(self): """ Calculates the TransformToIqt parameters and saves in a table workspace. """ from IndirectCommon import getEfixed end_prog = 0.3 if self._calculate_errors else 0.9 workflow_prog = Progress(self, start=0.0, end=end_prog, nreports=8) workflow_prog.report('Cropping Workspace') CropWorkspace(InputWorkspace=self._sample, OutputWorkspace='__TransformToIqt_sample_cropped', Xmin=self._e_min, Xmax=self._e_max) workflow_prog.report('Calculating table properties') x_data = mtd['__TransformToIqt_sample_cropped'].readX(0) number_input_points = len(x_data) - 1 num_bins = int(number_input_points / self._number_points_per_bin) self._e_width = (abs(self._e_min) + abs(self._e_max)) / num_bins workflow_prog.report('Attempting to Access IPF') try: workflow_prog.report('Access IPF') instrument = mtd[self._sample].getInstrument() analyserName = instrument.getStringParameter('analyser')[0] analyser = instrument.getComponentByName(analyserName) if analyser is not None: logger.debug('Found %s component in instrument %s, will look for resolution there' % (analyserName, instrument)) resolution = analyser.getNumberParameter('resolution')[0] else: logger.debug('No %s component found on instrument %s, will look for resolution in top level instrument' % (analyserName, instrument)) resolution = instrument.getNumberParameter('resolution')[0] logger.information('Got resolution from IPF: %f' % resolution) workflow_prog.report('IPF resolution obtained') except (AttributeError, IndexError): workflow_prog.report('Resorting to Default') resolution = getEfixed(self._sample) * 0.01 logger.warning('Could not get the resolution from the IPF, using 1% of the E Fixed value for the ' 'resolution: {0}'.format(resolution)) resolution_bins = int(round((2 * resolution) / self._e_width)) if resolution_bins < 5: logger.warning( 'Resolution curve has <5 points. Results may be unreliable.') workflow_prog.report('Creating Parameter table') param_table = CreateEmptyTableWorkspace( OutputWorkspace=self._parameter_table) workflow_prog.report('Populating Parameter table') param_table.addColumn('int', 'SampleInputBins') param_table.addColumn('float', 'BinReductionFactor') param_table.addColumn('int', 'SampleOutputBins') param_table.addColumn('float', 'EnergyMin') param_table.addColumn('float', 'EnergyMax') param_table.addColumn('float', 'EnergyWidth') param_table.addColumn('float', 'Resolution') param_table.addColumn('int', 'ResolutionBins') param_table.addRow([number_input_points, self._number_points_per_bin, num_bins, self._e_min, self._e_max, self._e_width, resolution, resolution_bins]) workflow_prog.report('Deleting temp Workspace') if mtd.doesExist('__TransformToIqt_sample_cropped'): DeleteWorkspace('__TransformToIqt_sample_cropped') self.setProperty('ParameterWorkspace', param_table)
def PyExec(self): #from IndirectImport import run_f2py_compatibility_test, is_supported_f2py_platform run_f2py_compatibility_test() from IndirectBayes import (CalcErange, GetXYE, ReadNormFile, ReadWidthFile, QLAddSampleLogs, C2Fw, C2Se, QuasiPlot) from IndirectCommon import (CheckXrange, CheckAnalysers, getEfixed, GetThetaQ, CheckHistZero, CheckHistSame) setup_prog = Progress(self, start=0.0, end=0.3, nreports = 5) self.log().information('BayesQuasi input') erange = [self._e_min, self._e_max] nbins = [self._sam_bins, self._res_bins] setup_prog.report('Converting to binary for Fortran') #convert true/false to 1/0 for fortran o_el = 1 if self._elastic else 0 o_w1 = 1 if self._width else 0 o_res = 1 if self._res_norm else 0 #fortran code uses background choices defined using the following numbers setup_prog.report('Encoding input options') if self._background == 'Sloping': o_bgd = 2 elif self._background == 'Flat': o_bgd = 1 elif self._background == 'Zero': o_bgd = 0 fitOp = [o_el, o_bgd, o_w1, o_res] setup_prog.report('Establishing save path') workdir = config['defaultsave.directory'] if not os.path.isdir(workdir): workdir = os.getcwd() logger.information('Default Save directory is not set. Defaulting to current working Directory: ' + workdir) array_len = 4096 # length of array in Fortran setup_prog.report('Checking X Range') CheckXrange(erange,'Energy') nbin,nrbin = nbins[0], nbins[1] logger.information('Sample is ' + self._samWS) logger.information('Resolution is ' + self._resWS) setup_prog.report('Checking Analysers') CheckAnalysers(self._samWS,self._resWS) setup_prog.report('Obtaining EFixed, theta and Q') efix = getEfixed(self._samWS) theta, Q = GetThetaQ(self._samWS) nsam,ntc = CheckHistZero(self._samWS) totalNoSam = nsam #check if we're performing a sequential fit if self._loop != True: nsam = 1 nres = CheckHistZero(self._resWS)[0] setup_prog.report('Checking Histograms') if self._program == 'QL': if nres == 1: prog = 'QLr' # res file else: prog = 'QLd' # data file CheckHistSame(self._samWS,'Sample',self._resWS,'Resolution') elif self._program == 'QSe': if nres == 1: prog = 'QSe' # res file else: raise ValueError('Stretched Exp ONLY works with RES file') logger.information('Version is ' +prog) logger.information(' Number of spectra = '+str(nsam)) logger.information(' Erange : '+str(erange[0])+' to '+str(erange[1])) setup_prog.report('Reading files') Wy,We = ReadWidthFile(self._width,self._wfile,totalNoSam) dtn,xsc = ReadNormFile(self._res_norm,self._resnormWS,totalNoSam) setup_prog.report('Establishing output workspace name') fname = self._samWS[:-4] + '_'+ prog probWS = fname + '_Prob' fitWS = fname + '_Fit' wrks=os.path.join(workdir, self._samWS[:-4]) logger.information(' lptfile : '+wrks+'_'+prog+'.lpt') lwrk=len(wrks) wrks.ljust(140,' ') wrkr=self._resWS wrkr.ljust(140,' ') setup_prog.report('Initialising probability list') # initialise probability list if self._program == 'QL': prob0 = [] prob1 = [] prob2 = [] xQ = np.array([Q[0]]) for m in range(1,nsam): xQ = np.append(xQ,Q[m]) xProb = xQ xProb = np.append(xProb,xQ) xProb = np.append(xProb,xQ) eProb = np.zeros(3*nsam) group = '' workflow_prog = Progress(self, start=0.3, end=0.7, nreports=nsam*3) for m in range(0,nsam): logger.information('Group ' +str(m)+ ' at angle '+ str(theta[m])) nsp = m+1 nout,bnorm,Xdat,Xv,Yv,Ev = CalcErange(self._samWS,m,erange,nbin) Ndat = nout[0] Imin = nout[1] Imax = nout[2] if prog == 'QLd': mm = m else: mm = 0 Nb,Xb,Yb,Eb = GetXYE(self._resWS,mm,array_len) # get resolution data numb = [nsam, nsp, ntc, Ndat, nbin, Imin, Imax, Nb, nrbin] rscl = 1.0 reals = [efix, theta[m], rscl, bnorm] if prog == 'QLr': workflow_prog.report('Processing Sample number %i as Lorentzian' % nsam) nd,xout,yout,eout,yfit,yprob=QLr.qlres(numb,Xv,Yv,Ev,reals,fitOp, Xdat,Xb,Yb,Wy,We,dtn,xsc, wrks,wrkr,lwrk) message = ' Log(prob) : '+str(yprob[0])+' '+str(yprob[1])+' '+str(yprob[2])+' '+str(yprob[3]) logger.information(message) if prog == 'QLd': workflow_prog.report('Processing Sample number %i' % nsam) nd,xout,yout,eout,yfit,yprob=QLd.qldata(numb,Xv,Yv,Ev,reals,fitOp, Xdat,Xb,Yb,Eb,Wy,We, wrks,wrkr,lwrk) message = ' Log(prob) : '+str(yprob[0])+' '+str(yprob[1])+' '+str(yprob[2])+' '+str(yprob[3]) logger.information(message) if prog == 'QSe': workflow_prog.report('Processing Sample number %i as Stretched Exp' % nsam) nd,xout,yout,eout,yfit,yprob=Qse.qlstexp(numb,Xv,Yv,Ev,reals,fitOp,\ Xdat,Xb,Yb,Wy,We,dtn,xsc,\ wrks,wrkr,lwrk) dataX = xout[:nd] dataX = np.append(dataX,2*xout[nd-1]-xout[nd-2]) yfit_list = np.split(yfit[:4*nd],4) dataF1 = yfit_list[1] if self._program == 'QL': dataF2 = yfit_list[2] workflow_prog.report('Processing data') dataG = np.zeros(nd) datX = dataX datY = yout[:nd] datE = eout[:nd] datX = np.append(datX,dataX) datY = np.append(datY,dataF1[:nd]) datE = np.append(datE,dataG) res1 = dataF1[:nd] - yout[:nd] datX = np.append(datX,dataX) datY = np.append(datY,res1) datE = np.append(datE,dataG) nsp = 3 names = 'data,fit.1,diff.1' res_plot = [0, 1, 2] if self._program == 'QL': workflow_prog.report('Processing Lorentzian result data') datX = np.append(datX,dataX) datY = np.append(datY,dataF2[:nd]) datE = np.append(datE,dataG) res2 = dataF2[:nd] - yout[:nd] datX = np.append(datX,dataX) datY = np.append(datY,res2) datE = np.append(datE,dataG) nsp += 2 names += ',fit.2,diff.2' res_plot.append(4) prob0.append(yprob[0]) prob1.append(yprob[1]) prob2.append(yprob[2]) # create result workspace fitWS = fname+'_Workspaces' fout = fname+'_Workspace_'+ str(m) workflow_prog.report('Creating OutputWorkspace') CreateWorkspace(OutputWorkspace=fout, DataX=datX, DataY=datY, DataE=datE,\ Nspec=nsp, UnitX='DeltaE', VerticalAxisUnit='Text', VerticalAxisValues=names) # append workspace to list of results group += fout + ',' comp_prog = Progress(self, start=0.7, end=0.8, nreports=2) comp_prog.report('Creating Group Workspace') GroupWorkspaces(InputWorkspaces=group,OutputWorkspace=fitWS) if self._program == 'QL': comp_prog.report('Processing Lorentzian probability data') yPr0 = np.array([prob0[0]]) yPr1 = np.array([prob1[0]]) yPr2 = np.array([prob2[0]]) for m in range(1,nsam): yPr0 = np.append(yPr0,prob0[m]) yPr1 = np.append(yPr1,prob1[m]) yPr2 = np.append(yPr2,prob2[m]) yProb = yPr0 yProb = np.append(yProb,yPr1) yProb = np.append(yProb,yPr2) probWs = CreateWorkspace(OutputWorkspace=probWS, DataX=xProb, DataY=yProb, DataE=eProb,\ Nspec=3, UnitX='MomentumTransfer') outWS = C2Fw(self._samWS[:-4],fname) if self._plot != 'None': QuasiPlot(fname,self._plot,res_plot,self._loop) if self._program == 'QSe': comp_prog.report('Runnning C2Se') outWS = C2Se(fname) if self._plot != 'None': QuasiPlot(fname,self._plot,res_plot,self._loop) log_prog = Progress(self, start=0.8, end =1.0, nreports=8) #Add some sample logs to the output workspaces log_prog.report('Copying Logs to outputWorkspace') CopyLogs(InputWorkspace=self._samWS, OutputWorkspace=outWS) log_prog.report('Adding Sample logs to Output workspace') QLAddSampleLogs(outWS, self._resWS, prog, self._background, self._elastic, erange, (nbin, nrbin), self._resnormWS, self._wfile) log_prog.report('Copying logs to fit Workspace') CopyLogs(InputWorkspace=self._samWS, OutputWorkspace=fitWS) log_prog.report('Adding sample logs to Fit workspace') QLAddSampleLogs(fitWS, self._resWS, prog, self._background, self._elastic, erange, (nbin, nrbin), self._resnormWS, self._wfile) log_prog.report('Finialising log copying') if self._save: log_prog.report('Saving workspaces') fit_path = os.path.join(workdir,fitWS+'.nxs') SaveNexusProcessed(InputWorkspace=fitWS, Filename=fit_path) out_path = os.path.join(workdir, outWS+'.nxs') # path name for nxs file SaveNexusProcessed(InputWorkspace=outWS, Filename=out_path) logger.information('Output fit file created : ' + fit_path) logger.information('Output paramter file created : ' + out_path) self.setProperty('OutputWorkspaceFit', fitWS) self.setProperty('OutputWorkspaceResult', outWS) log_prog.report('Setting workspace properties') if self._program == 'QL': self.setProperty('OutputWorkspaceProb', probWS)
def PyExec(self): run_f2py_compatibility_test() from IndirectBayes import (CalcErange, GetXYE) from IndirectCommon import (CheckXrange, CheckAnalysersOrEFixed, getEfixed, GetThetaQ, CheckHistZero) setup_prog = Progress(self, start=0.0, end=0.3, nreports=5) logger.information('BayesStretch input') logger.information('Sample is %s' % self._sam_name) logger.information('Resolution is %s' % self._res_name) setup_prog.report('Converting to binary for Fortran') fitOp = self._encode_fit_ops(self._elastic, self._background) setup_prog.report('Establishing save path') workdir = self._establish_save_path() setup_prog.report('Checking X Range') CheckXrange(self._erange, 'Energy') setup_prog.report('Checking Analysers') CheckAnalysersOrEFixed(self._sam_name, self._res_name) setup_prog.report('Obtaining EFixed, theta and Q') efix = getEfixed(self._sam_name) theta, Q = GetThetaQ(self._sam_name) setup_prog.report('Checking Histograms') nsam, ntc = CheckHistZero(self._sam_name) # check if we're performing a sequential fit if not self._loop: nsam = 1 logger.information('Version is Stretch') logger.information('Number of spectra = %s ' % nsam) logger.information('Erange : %f to %f ' % (self._erange[0], self._erange[1])) setup_prog.report('Creating FORTRAN Input') fname = self._sam_name[:-4] + '_Stretch' wrks = os.path.join(workdir, self._sam_name[:-4]) logger.information('lptfile : %s_Qst.lpt' % wrks) lwrk = len(wrks) wrks.ljust(140, ' ') wrkr = self._res_name wrkr.ljust(140, ' ') eBet0 = np.zeros(self._nbet) # set errors to zero eSig0 = np.zeros(self._nsig) # set errors to zero rscl = 1.0 Qaxis = '' workflow_prog = Progress(self, start=0.3, end=0.7, nreports=nsam * 3) # Empty arrays to hold Sigma and Bet x,y,e values xSig, ySig, eSig = [], [], [] xBet, yBet, eBet = [], [], [] for m in range(nsam): logger.information('Group %i at angle %f' % (m, theta[m])) nsp = m + 1 nout, bnorm, Xdat, Xv, Yv, Ev = CalcErange(self._sam_name, m, self._erange, self._nbins[0]) Ndat = nout[0] Imin = nout[1] Imax = nout[2] # get resolution data (4096 = FORTRAN array length) Nb, Xb, Yb, _ = GetXYE(self._res_name, 0, 4096) numb = [ nsam, nsp, ntc, Ndat, self._nbins[0], Imin, Imax, Nb, self._nbins[1], self._nbet, self._nsig ] reals = [efix, theta[m], rscl, bnorm] workflow_prog.report('Processing spectrum number %i' % m) xsout, ysout, xbout, ybout, zpout = Que.quest( numb, Xv, Yv, Ev, reals, fitOp, Xdat, Xb, Yb, wrks, wrkr, lwrk) dataXs = xsout[:self._nsig] # reduce from fixed FORTRAN array dataYs = ysout[:self._nsig] dataXb = xbout[:self._nbet] dataYb = ybout[:self._nbet] zpWS = fname + '_Zp' + str(m) if m > 0: Qaxis += ',' Qaxis += str(Q[m]) dataXz = [] dataYz = [] dataEz = [] for n in range(self._nsig): yfit_list = np.split(zpout[:self._nsig * self._nbet], self._nsig) dataYzp = yfit_list[n] dataXz = np.append(dataXz, xbout[:self._nbet]) dataYz = np.append(dataYz, dataYzp[:self._nbet]) dataEz = np.append(dataEz, eBet0) zpWS = fname + '_Zp' + str(m) self._create_workspace(zpWS, [dataXz, dataYz, dataEz], self._nsig, dataXs, True) xSig = np.append(xSig, dataXs) ySig = np.append(ySig, dataYs) eSig = np.append(eSig, eSig0) xBet = np.append(xBet, dataXb) yBet = np.append(yBet, dataYb) eBet = np.append(eBet, eBet0) if m == 0: groupZ = zpWS else: groupZ = groupZ + ',' + zpWS # create workspaces for sigma and beta workflow_prog.report('Creating OutputWorkspace') self._create_workspace(fname + '_Sigma', [xSig, ySig, eSig], nsam, Qaxis) self._create_workspace(fname + '_Beta', [xBet, yBet, eBet], nsam, Qaxis) group = fname + '_Sigma,' + fname + '_Beta' fit_ws = fname + '_Fit' s_api.GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=fit_ws) contour_ws = fname + '_Contour' s_api.GroupWorkspaces(InputWorkspaces=groupZ, OutputWorkspace=contour_ws) # Add some sample logs to the output workspaces log_prog = Progress(self, start=0.8, end=1.0, nreports=6) log_prog.report('Copying Logs to Fit workspace') copy_log_alg = self.createChildAlgorithm('CopyLogs', enableLogging=False) copy_log_alg.setProperty('InputWorkspace', self._sam_name) copy_log_alg.setProperty('OutputWorkspace', fit_ws) copy_log_alg.execute() log_prog.report('Adding Sample logs to Fit workspace') self._add_sample_logs(fit_ws, self._erange, self._nbins[0]) log_prog.report('Copying logs to Contour workspace') copy_log_alg.setProperty('InputWorkspace', self._sam_name) copy_log_alg.setProperty('OutputWorkspace', contour_ws) copy_log_alg.execute() log_prog.report('Adding sample logs to Contour workspace') self._add_sample_logs(contour_ws, self._erange, self._nbins[0]) log_prog.report('Finialising log copying') # sort x axis s_api.SortXAxis(InputWorkspace=fit_ws, OutputWorkspace=fit_ws, EnableLogging=False) s_api.SortXAxis(InputWorkspace=contour_ws, OutputWorkspace=contour_ws, EnableLogging=False) self.setProperty('OutputWorkspaceFit', fit_ws) self.setProperty('OutputWorkspaceContour', contour_ws) log_prog.report('Setting workspace properties')
def PyExec(self): from IndirectCommon import getEfixed self._setup() # Set up progress reporting n_prog_reports = 2 if self._can_ws_name is not None: n_prog_reports += 1 prog = Progress(self, 0.0, 1.0, n_prog_reports) efixed = getEfixed(self._sample_ws_name) sample_wave_ws = '__sam_wave' ConvertUnits(InputWorkspace=self._sample_ws_name, OutputWorkspace=sample_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed, EnableLogging=False) sample_thickness = self._sample_outer_radius - self._sample_inner_radius logger.information('Sample thickness: ' + str(sample_thickness)) prog.report('Calculating sample corrections') if self._sample_density_type == 'Mass Density': builder = MaterialBuilder() mat = builder.setFormula(self._sample_chemical_formula).setMassDensity(self._sample_density).build() self._sample_density = mat.numberDensity SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_density) AnnularRingAbsorption(InputWorkspace=sample_wave_ws, OutputWorkspace=self._ass_ws, SampleHeight=3.0, SampleThickness=sample_thickness, CanInnerRadius=self._can_inner_radius, CanOuterRadius=self._can_outer_radius, SampleChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_density, NumberOfWavelengthPoints=10, EventsPerPoint=self._events) group = self._ass_ws if self._can_ws_name is not None: can1_wave_ws = '__can1_wave' can2_wave_ws = '__can2_wave' ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can1_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed, EnableLogging=False) if self._can_scale != 1.0: logger.information('Scaling container by: ' + str(self._can_scale)) Scale(InputWorkspace=can1_wave_ws, OutputWorkspace=can1_wave_ws, Factor=self._can_scale, Operation='Multiply') CloneWorkspace(InputWorkspace=can1_wave_ws, OutputWorkspace=can2_wave_ws, EnableLogging=False) can_thickness_1 = self._sample_inner_radius - self._can_inner_radius can_thickness_2 = self._can_outer_radius - self._sample_outer_radius logger.information('Container thickness: %f & %f' % (can_thickness_1, can_thickness_2)) if self._use_can_corrections: prog.report('Calculating container corrections') Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) if self._can_density_type == 'Mass Density': builder = MaterialBuilder() mat = builder.setFormula(self._can_chemical_formula).setMassDensity(self._can_density).build() self._can_density = mat.numberDensity SetSampleMaterial(can1_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_density) AnnularRingAbsorption(InputWorkspace=can1_wave_ws, OutputWorkspace='__Acc1', SampleHeight=3.0, SampleThickness=can_thickness_1, CanInnerRadius=self._can_inner_radius, CanOuterRadius=self._sample_outer_radius, SampleChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_density, NumberOfWavelengthPoints=10, EventsPerPoint=self._events) SetSampleMaterial(can2_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_density) AnnularRingAbsorption(InputWorkspace=can2_wave_ws, OutputWorkspace='__Acc2', SampleHeight=3.0, SampleThickness=can_thickness_2, CanInnerRadius=self._sample_inner_radius, CanOuterRadius=self._can_outer_radius, SampleChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_density, NumberOfWavelengthPoints=10, EventsPerPoint=self._events) Multiply(LHSWorkspace='__Acc1', RHSWorkspace='__Acc2', OutputWorkspace=self._acc_ws, EnableLogging=False) DeleteWorkspace('__Acc1', EnableLogging=False) DeleteWorkspace('__Acc2', EnableLogging=False) Divide(LHSWorkspace=can1_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can1_wave_ws) Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can1_wave_ws, OutputWorkspace=sample_wave_ws) group += ',' + self._acc_ws else: prog.report('Calculating can scaling') Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can1_wave_ws, OutputWorkspace=sample_wave_ws) Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) DeleteWorkspace(can1_wave_ws, EnableLogging=False) DeleteWorkspace(can2_wave_ws, EnableLogging=False) else: Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws, Target='DeltaE', EMode='Indirect', EFixed=efixed, EnableLogging=False) DeleteWorkspace(sample_wave_ws, EnableLogging=False) prog.report('Recording sample logs') sample_log_workspaces = [self._output_ws, self._ass_ws] sample_logs = [('sample_shape', 'annulus'), ('sample_filename', self._sample_ws_name), ('sample_inner', self._sample_inner_radius), ('sample_outer', self._sample_outer_radius), ('can_inner', self._can_inner_radius), ('can_outer', self._can_outer_radius)] if self._can_ws_name is not None: sample_logs.append(('container_filename', self._can_ws_name)) sample_logs.append(('container_scale', self._can_scale)) if self._use_can_corrections: sample_log_workspaces.append(self._acc_ws) sample_logs.append(('container_thickness_1', can_thickness_1)) sample_logs.append(('container_thickness_2', can_thickness_2)) log_names = [item[0] for item in sample_logs] log_values = [item[1] for item in sample_logs] for ws_name in sample_log_workspaces: AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values, EnableLogging=False) self.setProperty('OutputWorkspace', self._output_ws) # Output the Ass workspace if it is wanted, delete if not if self._abs_ws == '': DeleteWorkspace(self._ass_ws, EnableLogging=False) if self._can_ws_name is not None and self._use_can_corrections: DeleteWorkspace(self._acc_ws, EnableLogging=False) else: GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws, EnableLogging=False) self.setProperty('CorrectionsWorkspace', self._abs_ws)
def PyExec(self): run_f2py_compatibility_test() from IndirectBayes import (CalcErange, GetXYE, C2Fwater) from IndirectCommon import (CheckXrange, CheckAnalysers, getEfixed, GetThetaQ, CheckHistZero, CheckHistSame) erange = [self._e_min, self._e_max] nbins = [self._sam_bins, self._res_bins] #convert true/false to 1/0 for fortran o_el = 1 if self._elastic else 0 o_w1 = 1 if self._width else 0 o_res = 1 if self._res_norm else 0 #fortran code uses background choices defined using the following numbers if self._background == 'Sloping': o_bgd = 2 elif self._background == 'Flat': o_bgd = 1 elif self._background == 'Zero': o_bgd = 0 fitOp = [o_el, o_bgd, o_w1, o_res] workdir = config['defaultsave.directory'] if not os.path.isdir(workdir): workdir = os.getcwd() logger.information('Default Save directory is not set. Defaulting to current working Directory: ' + workdir) array_len = 4096 # length of array in Fortran CheckXrange(erange, 'Energy') nbin,nrbin = nbins[0], nbins[1] logger.information('Sample is ' + self._sam_ws) logger.information('Resolution is ' + self._res_ws) CheckAnalysersOrEFixed(self._sam_ws, self._res_ws) efix = getEfixed(self._sam_ws) theta, Q = GetThetaQ(self._sam_ws) nsam,ntc = CheckHistZero(self._sam_ws) totalNoSam = nsam #check if we're performing a sequential fit if self._loop != True: nsam = 1 prog = 'QLw' # res file logger.information('Program is ' + prog) logger.information(' Number of spectra = %i' % nsam) logger.information(' Erange : %f to %f' % (erange[0], erange[1])) dtn, xsc = self._read_width_file(self._res_norm, self._resnorm_ws, totalNoSam) Wy, We = self._read_norm_file(self._width,self._wfile,totalNoSam) fname = self._sam_ws[:-4] + '_'+ prog fit_ws = fname + '_Fit' wrks=os.path.join(workdir, self._sam_ws[:-4]) logger.information(' lptfile : ' + wrks + '_' + prog + '.lpt') lwrk=len(wrks) wrks.ljust(140, ' ') wrkr=self._res_ws wrkr.ljust(140, ' ') group = '' workflow_prog = Progress(self, start=0.3, end=0.7, nreports=nsam*3) for m in range(nsam): logger.information('Group %i at angle %f' % (m, theta[m])) nsp = m + 1 nout, bnorm, Xdat, Xv, Yv, Ev = CalcErange(self._sam_ws, m, erange, nbin) Ndat = nout[0] Imin = nout[1] Imax = nout[2] if prog == 'QLd': mm = m else: mm = 0 Nb, Xb, Yb, Eb = GetXYE(self._res_ws, mm, array_len) # get resolution data numb = [nsam, nsp, ntc, Ndat, nbin, Imin, Imax, Nb, nrbin] rscl = 1.0 reals = [efix, theta[m], rscl, bnorm] workflow_prog.report('Processing spectrum number %i as Water' % m) nd,xout,yout,eout,yfit,yprob=QLwat.qlwat(numb, Xv, Yv, Ev, reals, fitOp, Xdat, Xb, Yb, Wy, We, dtn, xsc, wrks, wrkr, lwrk) dataX = xout[:nd] dataX = np.append(dataX, 2*xout[nd - 1] - xout[nd - 2]) yfit_list = np.split(yfit[:4*nd], 4) dataF1 = yfit_list[1] workflow_prog.report('Processing data') dataG = np.zeros(nd) datX = dataX datY = yout[:nd] datE = eout[:nd] datX = np.append(datX, dataX) datY = np.append(datY, dataF1[:nd]) datE = np.append(datE, dataG) res1 = dataF1[:nd] - yout[:nd] datX = np.append(datX, dataX) datY = np.append(datY, res1) datE = np.append(datE, dataG) nsp = 3 names = 'data, fit.1, diff.1' res_plot = [0, 1, 2] # create result workspace fit_ws = fname + '_Workspaces' fout = fname + '_Workspace_' + str(m) workflow_prog.report('Creating OutputWorkspace') CreateWorkspace(OutputWorkspace=fout, DataX=datX, DataY=datY, DataE=datE, Nspec=nsp, UnitX='DeltaE', VerticalAxisUnit='Text', VerticalAxisValues=names) # append workspace to list of results group += fout + ',' comp_prog = Progress(self, start=0.7, end=0.8, nreports=2) comp_prog.report('Creating Group Workspace') GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=fit_ws) out_ws = C2Fwater(fname) #Add some sample logs to the output workspaces CopyLogs(InputWorkspace=self._sam_ws, OutputWorkspace=out_ws) self._add_sample_logs(out_ws, prog, erange, nbins) CopyLogs(InputWorkspace=self._sam_ws, OutputWorkspace=fit_ws) self._add_sample_logs(fit_ws, prog, erange, nbins) self.setProperty('OutputWorkspaceFit', fit_ws) self.setProperty('OutputWorkspaceResult', out_ws)
def PyExec(self): from IndirectCommon import getEfixed self._setup() # Set up progress reporting n_prog_reports = 2 if self._can_ws_name is not None: n_prog_reports += 1 prog = Progress(self, 0.0, 1.0, n_prog_reports) efixed = getEfixed(self._sample_ws_name) sample_wave_ws = '__sam_wave' ConvertUnits(InputWorkspace=self._sample_ws_name, OutputWorkspace=sample_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed) SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_number_density) prog.report('Calculating sample corrections') CylinderAbsorption(InputWorkspace=sample_wave_ws, OutputWorkspace=self._ass_ws, SampleNumberDensity=self._sample_number_density, NumberOfWavelengthPoints=10, CylinderSampleHeight=3.0, CylinderSampleRadius=self._sample_radius, NumberOfSlices=1, NumberOfAnnuli=10) plot_data = [self._output_ws, self._sample_ws_name] plot_corr = [self._ass_ws] group = self._ass_ws if self._can_ws_name is not None: can_wave_ws = '__can_wave' ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can_wave_ws, Target='Wavelength', EMode='Indirect', EFixed=efixed) if self._can_scale != 1.0: logger.information('Scaling can by: ' + str(self._can_scale)) Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply') can_thickness = self._can_radius - self._sample_radius logger.information('Container thickness: ' + str(can_thickness)) if self._use_can_corrections: # Doing can corrections prog.report('Calculating container corrections') Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) SetSampleMaterial(can_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_number_density) AnnularRingAbsorption(InputWorkspace=can_wave_ws, OutputWorkspace=self._acc_ws, SampleHeight=3.0, SampleThickness=can_thickness, CanInnerRadius=0.9*self._sample_radius, CanOuterRadius=1.1*self._can_radius, SampleChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_number_density, NumberOfWavelengthPoints=10, EventsPerPoint=self._events) Divide(LHSWorkspace=can_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can_wave_ws) Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) plot_corr.append(self._acc_ws) group += ',' + self._acc_ws else: # Doing simple can subtraction prog.report('Calculating container scaling') Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws) Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) DeleteWorkspace(can_wave_ws) plot_data.append(self._can_ws_name) else: Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws) ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws, Target='DeltaE', EMode='Indirect', EFixed=efixed) DeleteWorkspace(sample_wave_ws) # Record sample logs prog.report('Recording sample logs') sample_log_workspaces = [self._output_ws, self._ass_ws] sample_logs = [('sample_shape', 'cylinder'), ('sample_filename', self._sample_ws_name), ('sample_radius', self._sample_radius)] if self._can_ws_name is not None: sample_logs.append(('container_filename', self._can_ws_name)) sample_logs.append(('container_scale', self._can_scale)) if self._use_can_corrections: sample_log_workspaces.append(self._acc_ws) sample_logs.append(('container_thickness', can_thickness)) log_names = [item[0] for item in sample_logs] log_values = [item[1] for item in sample_logs] for ws_name in sample_log_workspaces: AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values) self.setProperty('OutputWorkspace', self._output_ws) # Output the Abs group workspace if it is wanted, delete if not if self._abs_ws == '': DeleteWorkspace(self._ass_ws) if self._can_ws_name is not None and self._use_can_corrections: DeleteWorkspace(self._acc_ws) else: GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws) self.setProperty('CorrectionsWorkspace', self._abs_ws) if self._plot: from IndirectImport import import_mantidplot mantid_plot = import_mantidplot() mantid_plot.plotSpectrum(plot_data, 0) if self._abs_ws != '': mantid_plot.plotSpectrum(plot_corr, 0)