def runTest(self): # Load raw data (bank 1) wsMD = LoadMD( "WISH38237_MD.nxs") # default so doesn't get overwrite van # For each mod vec, predict and integrate peaks and combine qs = [(0.15, 0, 0.3), (-0.15, 0, 0.3)] all_pks = CreatePeaksWorkspace(InstrumentWorkspace=wsMD, NumberOfPeaks=0, OutputWorkspace="all_pks") LoadIsawUB(InputWorkspace=all_pks, Filename='Wish_Diffuse_Scattering_ISAW_UB.mat') # PredictPeaks parent = PredictPeaks(InputWorkspace=all_pks, WavelengthMin=0.8, WavelengthMax=9.3, MinDSpacing=0.5, ReflectionCondition="Primitive") self._pfps = [] self._saved_files = [] for iq, q in enumerate(qs): wsname = f'pfp_{iq}' PredictFractionalPeaks(Peaks=parent, IncludeAllPeaksInRange=True, Hmin=0, Hmax=0, Kmin=1, Kmax=1, Lmin=0, Lmax=1, ReflectionCondition='Primitive', MaxOrder=1, ModVector1=",".join([str(qi) for qi in q]), FracPeaks=wsname) FilterPeaks(InputWorkspace=wsname, OutputWorkspace=wsname, FilterVariable='Wavelength', FilterValue=9.3, Operator='<') # should get rid of one peak in q1 table FilterPeaks(InputWorkspace=wsname, OutputWorkspace=wsname, FilterVariable='Wavelength', FilterValue=0.8, Operator='>') IntegratePeaksMD(InputWorkspace=wsMD, PeakRadius='0.1', BackgroundInnerRadius='0.1', BackgroundOuterRadius='0.15', PeaksWorkspace=wsname, OutputWorkspace=wsname, IntegrateIfOnEdge=False, UseOnePercentBackgroundCorrection=False) all_pks = CombinePeaksWorkspaces(LHSWorkspace=all_pks, RHSWorkspace=wsname) self._pfps.append(ADS.retrieve(wsname)) self._filepath = os.path.join(config['defaultsave.directory'], 'WISH_IntegratedSatellite.int') SaveReflections(InputWorkspace=all_pks, Filename=self._filepath, Format='Jana') self._all_pks = all_pks
def _generate_UBList(self): CreateSingleValuedWorkspace(OutputWorkspace='__ub') LoadIsawUB('__ub', self.getProperty("UBMatrix").value) ub = mtd['__ub'].sample().getOrientedLattice().getUB().copy() DeleteWorkspace(Workspace='__ub') symOps = self.getProperty("SymmetryOps").value if symOps: try: symOps = SpaceGroupFactory.subscribedSpaceGroupSymbols( int(symOps))[0] except ValueError: pass if SpaceGroupFactory.isSubscribedSymbol(symOps): symOps = SpaceGroupFactory.createSpaceGroup( symOps).getSymmetryOperations() else: symOps = SymmetryOperationFactory.createSymOps(symOps) logger.information('Using symmetries: ' + str([sym.getIdentifier() for sym in symOps])) ub_list = [] for sym in symOps: UBtrans = np.zeros((3, 3)) UBtrans[0] = sym.transformHKL([1, 0, 0]) UBtrans[1] = sym.transformHKL([0, 1, 0]) UBtrans[2] = sym.transformHKL([0, 0, 1]) UBtrans = np.matrix(UBtrans.T) ub_list.append(ub * UBtrans) return ub_list else: return [ub]
def getUBMatrix(self, peaks_ws, UBFile): # Load the UB Matrix if one is not already loaded if UBFile == '' and peaks_ws.sample().hasOrientedLattice(): logger.information("Using UB file already available in PeaksWorkspace") else: try: from mantid.simpleapi import LoadIsawUB LoadIsawUB(InputWorkspace=peaks_ws, FileName=UBFile) except: logger.error("peaks_ws does not have a UB matrix loaded. Must provide a file") UBMatrix = peaks_ws.sample().getOrientedLattice().getUB() return UBMatrix
def test_qtohkl_corelli(self): Load(Filename='CORELLI_29782.nxs', OutputWorkspace='data') SetGoniometer(Workspace='data', Axis0='BL9:Mot:Sample:Axis1,0,1,0,1') LoadIsawUB(InputWorkspace='data', Filename='SingleCrystalDiffuseReduction_UB.mat') ConvertToMD(InputWorkspace='data', QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='HKL', QConversionScales='HKL', OutputWorkspace='HKL', Uproj='1,1,0', Vproj='1,-1,0', Wproj='0,0,1', MinValues='-20,-20,-20', MaxValues='20,20,20') hkl_binned = BinMD('HKL', AlignedDim0='[H,H,0],-10.05,10.05,201', AlignedDim1='[H,-H,0],-10.05,10.05,201', AlignedDim2='[0,0,L],-1.05,1.05,21') ConvertToMD(InputWorkspace='data', QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='Q_sample', OutputWorkspace='q_sample', MinValues='-20,-20,-20', MaxValues='20,20,20') hkl = ConvertQtoHKLMDHisto( InputWorkspace=mtd["q_sample"], Uproj="1,1,0", Vproj="1,-1,0", Wproj="0,0,1", Extents="-10.05,10.05,-10.05,10.05,-1.05,1.05", Bins="201,201,21") for i in range(hkl.getNumDims()): self.assertEqual( hkl_binned.getDimension(i).name, hkl.getDimension(i).name) orig_sig = hkl_binned.getSignalArray() new_sig = hkl.getSignalArray() np.testing.assert_allclose(np.asarray(new_sig), np.asarray(orig_sig), rtol=1.0e-5, atol=3)
def loadUBFiles(self, ubFiles, omegaHand, phiHand, omegaLogName, phiLogName): """ load the ub files and update the :param ubFiles: list of paths to saved UB files :param omegaHand: handedness of omega rotation (ccw/cw) :param phiHand: handedness of phi rotation (ccw/cw) :param omegaLogName: name of log entry for omega angle :param phiLogName: name of log entry for phi angle :return: matUB: list containing the UB for each run :return: omega: array of omega values from log of each run :return: phiRef: array of nominal phi values from log of each run """ matUB = [] # container to hold UB matrix arrays omega = np.zeros( len(ubFiles)) # rot around vertical axis (assumed to be correct) phiRef = np.zeros( len(ubFiles)) # rot around gonio axis (needs to be refined) for irun in range(0, len(ubFiles)): # get rotation angles from logs (handedness given in input) # these rotation matrices are defined in right-handed coordinate system (i.e. omegaHand = 1 etc.) _, fname = path.split(ubFiles[irun]) dataPath = FileFinder.findRuns(fname.split('.mat')[0])[0] tmpWS = CreateSampleWorkspace(StoreInADS=False) if dataPath[-4:] == ".raw": # assume log is kept separately in a .log file with same path LoadLog(Workspace=tmpWS, Filename="".join(dataPath[:-4] + '.log')) elif dataPath[-4:] == '.nxs': # logs are kept with data in nexus file LoadNexusLogs(Workspace=tmpWS, Filename=dataPath) # read omega and phi (in RH coords) omega[irun] = omegaHand * tmpWS.getRun().getLogData( omegaLogName).value[0] phiRef[irun] = phiHand * tmpWS.getRun().getLogData( phiLogName).value[0] # load UB LoadIsawUB(InputWorkspace=tmpWS, Filename=ubFiles[irun], CheckUMatrix=True) tmpUB = tmpWS.sample().getOrientedLattice().getUB() # permute axes to use IPNS convention (as in saved .mat file) matUB += [tmpUB[[2, 0, 1], :]] DeleteWorkspace(tmpWS) return matUB, omega, phiRef
def PyExec(self): import ICCFitTools as ICCFT import BVGFitTools as BVGFT from mantid.simpleapi import LoadIsawUB import pickle from scipy.ndimage.filters import convolve MDdata = self.getProperty('InputWorkspace').value peaks_ws = self.getProperty('PeaksWorkspace').value fracHKL = self.getProperty('FracHKL').value fracStop = self.getProperty('FracStop').value dQMax = self.getProperty('DQMax').value UBFile = self.getProperty('UBFile').value padeFile = self.getProperty('ModeratorCoefficientsFile').value strongPeaksParamsFile = self.getProperty('StrongPeakParamsFile').value forceCutoff = self.getProperty('IntensityCutoff').value edgeCutoff = self.getProperty('EdgeCutoff').value peakNumberToFit = self.getProperty('PeakNumber').value LoadIsawUB(InputWorkspace=peaks_ws, FileName=UBFile) UBMatrix = peaks_ws.sample().getOrientedLattice().getUB() dQ = np.abs(ICCFT.getDQFracHKL(UBMatrix, frac=0.5)) dQ[dQ > dQMax] = dQMax dQPixel = self.getProperty('DQPixel').value q_frame = 'lab' mtd['MDdata'] = MDdata padeCoefficients = ICCFT.getModeratorCoefficients(padeFile) if sys.version_info[0] == 3: strongPeakParams = pickle.load(open(strongPeaksParamsFile, 'rb'), encoding='latin1') else: strongPeakParams = pickle.load(open(strongPeaksParamsFile, 'rb')) predpplCoefficients = self.getProperty('PredPplCoefficients').value nTheta = self.getProperty('NTheta').value nPhi = self.getProperty('NPhi').value zBG = 1.96 mindtBinWidth = self.getProperty('MindtBinWidth').value pplmin_frac = self.getProperty('MinpplFrac').value pplmax_frac = self.getProperty('MaxpplFrac').value sampleRun = self.getProperty('RunNumber').value neigh_length_m = 3 qMask = ICCFT.getHKLMask(UBMatrix, frac=fracHKL, dQPixel=dQPixel, dQ=dQ) numgood = 0 numerrors = 0 # Create the parameters workspace keys = [ 'peakNumber', 'Alpha', 'Beta', 'R', 'T0', 'bgBVG', 'chiSq3d', 'dQ', 'KConv', 'MuPH', 'MuTH', 'newQ', 'Scale', 'scale3d', 'SigP', 'SigX', 'SigY', 'Intens3d', 'SigInt3d' ] datatypes = ['float'] * len(keys) datatypes[np.where(np.array(keys) == 'newQ')[0][0]] = 'V3D' params_ws = CreateEmptyTableWorkspace() for key, datatype in zip(keys, datatypes): params_ws.addColumn(datatype, key) # Set the peak numbers we're fitting if peakNumberToFit < 0: peaksToFit = range(peaks_ws.getNumberPeaks()) else: peaksToFit = [peakNumberToFit] # And we're off! peaks_ws_out = peaks_ws.clone() np.warnings.filterwarnings( 'ignore' ) # There can be a lot of warnings for bad solutions that get rejected. for peakNumber in peaksToFit: #range(peaks_ws.getNumberPeaks()): peak = peaks_ws_out.getPeak(peakNumber) try: if peak.getRunNumber() == sampleRun: box = ICCFT.getBoxFracHKL(peak, peaks_ws, MDdata, UBMatrix, peakNumber, dQ, fracHKL=0.5, dQPixel=dQPixel, q_frame=q_frame) # Will force weak peaks to be fit using a neighboring peak profile Y3D, goodIDX, pp_lambda, params = BVGFT.get3DPeak( peak, box, padeCoefficients, qMask, nTheta=nTheta, nPhi=nPhi, plotResults=False, zBG=zBG, fracBoxToHistogram=1.0, bgPolyOrder=1, strongPeakParams=strongPeakParams, predCoefficients=predpplCoefficients, q_frame=q_frame, mindtBinWidth=mindtBinWidth, pplmin_frac=pplmin_frac, pplmax_frac=pplmax_frac, forceCutoff=forceCutoff, edgeCutoff=edgeCutoff) # First we get the peak intensity peakIDX = Y3D / Y3D.max() > fracStop intensity = np.sum(Y3D[peakIDX]) # Now the number of background counts under the peak assuming a constant bg across the box n_events = box.getNumEventsArray() convBox = 1.0 * np.ones([ neigh_length_m, neigh_length_m, neigh_length_m ]) / neigh_length_m**3 conv_n_events = convolve(n_events, convBox) bgIDX = reduce(np.logical_and, [~goodIDX, qMask, conv_n_events > 0]) bgEvents = np.mean(n_events[bgIDX]) * np.sum(peakIDX) # Now we consider the variation of the fit. These are done as three independent fits. So we need to consider # the variance within our fit sig^2 = sum(N*(yFit-yData)) / sum(N) and scale by the number of parameters that go into # the fit. In total: 10 (removing scale variables) # TODO: It's not clear to me if we should be normalizing by #params - so we'll leave it for now. w_events = n_events.copy() w_events[w_events == 0] = 1 varFit = np.average((n_events[peakIDX] - Y3D[peakIDX]) * (n_events[peakIDX] - Y3D[peakIDX]), weights=(w_events[peakIDX])) sigma = np.sqrt(intensity + bgEvents + varFit) compStr = 'peak {:d}; original: {:4.2f} +- {:4.2f}; new: {:4.2f} +- {:4.2f}'.format( peakNumber, peak.getIntensity(), peak.getSigmaIntensity(), intensity, sigma) logger.information(compStr) # Save the results params['peakNumber'] = peakNumber params['Intens3d'] = intensity params['SigInt3d'] = sigma params['newQ'] = V3D(params['newQ'][0], params['newQ'][1], params['newQ'][2]) params_ws.addRow(params) peak.setIntensity(intensity) peak.setSigmaIntensity(sigma) numgood += 1 except KeyboardInterrupt: np.warnings.filterwarnings('default') # Re-enable on exit raise except: #raise numerrors += 1 peak.setIntensity(0.0) peak.setSigmaIntensity(1.0) # Cleanup for wsName in mtd.getObjectNames(): if 'fit_' in wsName or 'bvgWS' in wsName or 'tofWS' in wsName or 'scaleWS' in wsName: mtd.remove(wsName) np.warnings.filterwarnings('default') # Re-enable on exit # Set the output self.setProperty('OutputPeaksWorkspace', peaks_ws_out) self.setProperty('OutputParamsWorkspace', params_ws)
def PyExec(self): # remove possible old temp workspaces [ DeleteWorkspace(ws) for ws in self.temp_workspace_list if mtd.doesExist(ws) ] _background = bool(self.getProperty("Background").value) self._load_inst = bool(self.getProperty("LoadInstrument").value) self._apply_cal = bool(self.getProperty("ApplyCalibration").value) self._detcal = bool(self.getProperty("DetCal").value) self._copy_params = bool( self.getProperty("CopyInstrumentParameters").value) _masking = bool(self.getProperty("MaskFile").value) _outWS_name = self.getPropertyValue("OutputWorkspace") _UB = self.getProperty("UBMatrix").value if len(_UB) == 1: _UB = np.tile(_UB, len(self.getProperty("Filename").value)) _offsets = self.getProperty("OmegaOffset").value if len(_offsets) == 0: _offsets = np.zeros(len(self.getProperty("Filename").value)) if self.getProperty("ReuseSAFlux").value and mtd.doesExist( '__sa') and mtd.doesExist('__flux'): logger.notice( "Reusing previously loaded SolidAngle and Flux workspaces. " "Set ReuseSAFlux to False if new files are selected or you change the momentum range." ) else: logger.notice("Loading SolidAngle and Flux from file") LoadNexus(Filename=self.getProperty("SolidAngle").value, OutputWorkspace='__sa') LoadNexus(Filename=self.getProperty("Flux").value, OutputWorkspace='__flux') if _masking: LoadMask(Instrument=mtd['__sa'].getInstrument().getName(), InputFile=self.getProperty("MaskFile").value, OutputWorkspace='__mask') MaskDetectors(Workspace='__sa', MaskedWorkspace='__mask') DeleteWorkspace('__mask') self.XMin = mtd['__sa'].getXDimension().getMinimum() self.XMax = mtd['__sa'].getXDimension().getMaximum() newXMin = self.getProperty("MomentumMin").value newXMax = self.getProperty("MomentumMax").value if newXMin != Property.EMPTY_DBL or newXMax != Property.EMPTY_DBL: if newXMin != Property.EMPTY_DBL: self.XMin = max(self.XMin, newXMin) if newXMax != Property.EMPTY_DBL: self.XMax = min(self.XMax, newXMax) logger.notice("Using momentum range {} to {} A^-1".format( self.XMin, self.XMax)) CropWorkspace(InputWorkspace='__flux', OutputWorkspace='__flux', XMin=self.XMin, XMax=self.XMax) for spectrumNumber in range(mtd['__flux'].getNumberHistograms()): Y = mtd['__flux'].readY(spectrumNumber) mtd['__flux'].setY(spectrumNumber, (Y - Y.min()) / (Y.max() - Y.min())) MinValues = [-self.XMax * 2] * 3 MaxValues = [self.XMax * 2] * 3 if _background: self.load_file_and_apply( self.getProperty("Background").value, '__bkg', 0) progress = Progress(self, 0.0, 1.0, len(self.getProperty("Filename").value)) for n, run in enumerate(self.getProperty("Filename").value): logger.notice("Working on " + run) self.load_file_and_apply(run, '__run', _offsets[n]) LoadIsawUB('__run', _UB[n]) ConvertToMD(InputWorkspace='__run', OutputWorkspace='__md', QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='Q_sample', MinValues=MinValues, MaxValues=MaxValues) RecalculateTrajectoriesExtents(InputWorkspace='__md', OutputWorkspace='__md') MDNorm( InputWorkspace='__md', FluxWorkspace='__flux', SolidAngleWorkspace='__sa', OutputDataWorkspace='__data', TemporaryDataWorkspace='__data' if mtd.doesExist('__data') else None, OutputNormalizationWorkspace='__norm', TemporaryNormalizationWorkspace='__norm' if mtd.doesExist('__norm') else None, OutputWorkspace=_outWS_name, QDimension0=self.getProperty('QDimension0').value, QDimension1=self.getProperty('QDimension1').value, QDimension2=self.getProperty('QDimension2').value, Dimension0Binning=self.getProperty('Dimension0Binning').value, Dimension1Binning=self.getProperty('Dimension1Binning').value, Dimension2Binning=self.getProperty('Dimension2Binning').value, SymmetryOperations=self.getProperty( 'SymmetryOperations').value) DeleteWorkspace('__md') if _background: # Set background Goniometer and UB to be the same as data CopySample(InputWorkspace='__run', OutputWorkspace='__bkg', CopyName=False, CopyMaterial=False, CopyEnvironment=False, CopyShape=False, CopyLattice=True) mtd['__bkg'].run().getGoniometer().setR( mtd['__run'].run().getGoniometer().getR()) ConvertToMD(InputWorkspace='__bkg', OutputWorkspace='__bkg_md', QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='Q_sample', MinValues=MinValues, MaxValues=MaxValues) RecalculateTrajectoriesExtents(InputWorkspace='__bkg_md', OutputWorkspace='__bkg_md') MDNorm(InputWorkspace='__bkg_md', FluxWorkspace='__flux', SolidAngleWorkspace='__sa', OutputDataWorkspace='__bkg_data', TemporaryDataWorkspace='__bkg_data' if mtd.doesExist('__bkg_data') else None, OutputNormalizationWorkspace='__bkg_norm', TemporaryNormalizationWorkspace='__bkg_norm' if mtd.doesExist('__bkg_norm') else None, OutputWorkspace='__normalizedBackground', QDimension0=self.getProperty('QDimension0').value, QDimension1=self.getProperty('QDimension1').value, QDimension2=self.getProperty('QDimension2').value, Dimension0Binning=self.getProperty( 'Dimension0Binning').value, Dimension1Binning=self.getProperty( 'Dimension1Binning').value, Dimension2Binning=self.getProperty( 'Dimension2Binning').value, SymmetryOperations=self.getProperty( 'SymmetryOperations').value) DeleteWorkspace('__bkg_md') progress.report() DeleteWorkspace('__run') if _background: # outWS = data / norm - bkg_data / bkg_norm * BackgroundScale CreateSingleValuedWorkspace( OutputWorkspace='__scale', DataValue=self.getProperty('BackgroundScale').value) MultiplyMD(LHSWorkspace='__normalizedBackground', RHSWorkspace='__scale', OutputWorkspace='__normalizedBackground') DeleteWorkspace('__scale') MinusMD(LHSWorkspace=_outWS_name, RHSWorkspace='__normalizedBackground', OutputWorkspace=_outWS_name) if self.getProperty('KeepTemporaryWorkspaces').value: RenameWorkspaces(InputWorkspaces=[ '__data', '__norm', '__bkg_data', '__bkg_norm' ], WorkspaceNames=[ _outWS_name + '_data', _outWS_name + '_normalization', _outWS_name + '_background_data', _outWS_name + '_background_normalization' ]) else: if self.getProperty('KeepTemporaryWorkspaces').value: RenameWorkspaces(InputWorkspaces=['__data', '__norm'], WorkspaceNames=[ _outWS_name + '_data', _outWS_name + '_normalization' ]) self.setProperty("OutputWorkspace", mtd[_outWS_name]) # remove temp workspaces [ DeleteWorkspace(ws) for ws in self.temp_workspace_list if mtd.doesExist(ws) ]
def PyExec(self): _load_inst = bool(self.getProperty("LoadInstrument").value) _detcal = bool(self.getProperty("DetCal").value) _masking = bool(self.getProperty("MaskFile").value) _outWS_name = self.getPropertyValue("OutputWorkspace") _UB = bool(self.getProperty("UBMatrix").value) MinValues = self.getProperty("MinValues").value MaxValues = self.getProperty("MaxValues").value if self.getProperty("OverwriteExisting").value: if mtd.doesExist(_outWS_name): DeleteWorkspace(_outWS_name) progress = Progress(self, 0.0, 1.0, len(self.getProperty("Filename").value)) for run in self.getProperty("Filename").value: logger.notice("Working on " + run) Load(Filename=run, OutputWorkspace='__run', FilterByTofMin=self.getProperty("FilterByTofMin").value, FilterByTofMax=self.getProperty("FilterByTofMax").value, FilterByTimeStop=self.getProperty("FilterByTimeStop").value) if _load_inst: LoadInstrument( Workspace='__run', Filename=self.getProperty("LoadInstrument").value, RewriteSpectraMap=False) if _detcal: LoadIsawDetCal(InputWorkspace='__run', Filename=self.getProperty("DetCal").value) if _masking: if not mtd.doesExist('__mask'): LoadMask(Instrument=mtd['__run'].getInstrument().getName(), InputFile=self.getProperty("MaskFile").value, OutputWorkspace='__mask') MaskDetectors(Workspace='__run', MaskedWorkspace='__mask') if self.getProperty('SetGoniometer').value: SetGoniometer( Workspace='__run', Goniometers=self.getProperty('Goniometers').value, Axis0=self.getProperty('Axis0').value, Axis1=self.getProperty('Axis1').value, Axis2=self.getProperty('Axis2').value) if _UB: LoadIsawUB(InputWorkspace='__run', Filename=self.getProperty("UBMatrix").value) if len(MinValues) == 0 or len(MaxValues) == 0: MinValues, MaxValues = ConvertToMDMinMaxGlobal( '__run', dEAnalysisMode='Elastic', Q3DFrames='HKL', QDimensions='Q3D') ConvertToMD( InputWorkspace='__run', OutputWorkspace=_outWS_name, QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='HKL', QConversionScales='HKL', Uproj=self.getProperty('Uproj').value, Vproj=self.getProperty('Vproj').value, Wproj=self.getProperty('Wproj').value, MinValues=MinValues, MaxValues=MaxValues, SplitInto=self.getProperty('SplitInto').value, SplitThreshold=self.getProperty('SplitThreshold').value, MaxRecursionDepth=self.getProperty( 'MaxRecursionDepth').value, OverwriteExisting=False) else: if len(MinValues) == 0 or len(MaxValues) == 0: MinValues, MaxValues = ConvertToMDMinMaxGlobal( '__run', dEAnalysisMode='Elastic', Q3DFrames='Q', QDimensions='Q3D') ConvertToMD( InputWorkspace='__run', OutputWorkspace=_outWS_name, QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='Q_sample', Uproj=self.getProperty('Uproj').value, Vproj=self.getProperty('Vproj').value, Wproj=self.getProperty('Wproj').value, MinValues=MinValues, MaxValues=MaxValues, SplitInto=self.getProperty('SplitInto').value, SplitThreshold=self.getProperty('SplitThreshold').value, MaxRecursionDepth=self.getProperty( 'MaxRecursionDepth').value, OverwriteExisting=False) DeleteWorkspace('__run') progress.report() if mtd.doesExist('__mask'): DeleteWorkspace('__mask') self.setProperty("OutputWorkspace", mtd[_outWS_name])
for i in range(peaks_ws.getNumberPeaks()): pi = peaks_ws.getPeak(i) if pi.getRow() < 16 or pi.getRow() > 240 or pi.getCol() < 16 or pi.getCol( ) > 240: peaks_on_edge.append(i) DeleteTableRows(TableWorkspace=peaks_ws, Rows=peaks_on_edge) # # Read or find UB for the run # Read or find UB for the run try: if read_UB: # Read orientation matrix from file ubpath = os.path.dirname(UB_filename) ubrunnum = run if os.path.exists(ubpath + '%s_Niggli.mat' % (run)): LoadIsawUB(InputWorkspace=peaks_ws, Filename=ubpath + '%s_Niggli.mat' % (run)) print 'Use UB: ', ubpath + '%s_Niggli.mat' % (run) IndexPeaks(PeaksWorkspace=peaks_ws, CommonUBForAll=True, Tolerance=tolerance) FindUBUsingIndexedPeaks(PeaksWorkspace=peaks_ws, Tolerance=tolerance) else: LoadIsawUB(InputWorkspace=peaks_ws, Filename=UB_filename) IndexPeaks(PeaksWorkspace=peaks_ws, CommonUBForAll=False, Tolerance=tolerance) FindUBUsingIndexedPeaks(PeaksWorkspace=peaks_ws, Tolerance=tolerance) IndexPeaks(PeaksWorkspace=peaks_ws,
def PyExec(self): self._load_inst = bool(self.getProperty("LoadInstrument").value) self._apply_cal = bool(self.getProperty("ApplyCalibration").value) self._detcal = bool(self.getProperty("DetCal").value) self._copy_params = bool( self.getProperty("CopyInstrumentParameters").value) self._masking = bool(self.getProperty("MaskFile").value) _outWS_name = self.getPropertyValue("OutputWorkspace") _UB = bool(self.getProperty("UBMatrix").value) self.XMin = self.getProperty("MomentumMin").value self.XMax = self.getProperty("MomentumMax").value MinValues = self.getProperty("MinValues").value MaxValues = self.getProperty("MaxValues").value if self.getProperty("OverwriteExisting").value: if mtd.doesExist(_outWS_name): DeleteWorkspace(_outWS_name) progress = Progress(self, 0.0, 1.0, len(self.getProperty("Filename").value)) for run in self.getProperty("Filename").value: logger.notice("Working on " + run) self.load_file_and_apply(run, '__run') if self.getProperty('SetGoniometer').value: SetGoniometer( Workspace='__run', Goniometers=self.getProperty('Goniometers').value, Axis0=self.getProperty('Axis0').value, Axis1=self.getProperty('Axis1').value, Axis2=self.getProperty('Axis2').value) if _UB: LoadIsawUB(InputWorkspace='__run', Filename=self.getProperty("UBMatrix").value) if len(MinValues) == 0 or len(MaxValues) == 0: MinValues, MaxValues = ConvertToMDMinMaxGlobal( '__run', dEAnalysisMode='Elastic', Q3DFrames='Q' if self.getProperty('QFrame').value == 'Q_sample' else 'HKL', QDimensions='Q3D') ConvertToMD( InputWorkspace='__run', OutputWorkspace=_outWS_name, QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames=self.getProperty('QFrame').value, QConversionScales='Q in A^-1' if self.getProperty('QFrame').value == 'Q_sample' else 'HKL', Uproj=self.getProperty('Uproj').value, Vproj=self.getProperty('Vproj').value, Wproj=self.getProperty('Wproj').value, MinValues=MinValues, MaxValues=MaxValues, SplitInto=self.getProperty('SplitInto').value, SplitThreshold=self.getProperty('SplitThreshold').value, MaxRecursionDepth=self.getProperty('MaxRecursionDepth').value, OverwriteExisting=False) DeleteWorkspace('__run') progress.report() if mtd.doesExist('__mask'): DeleteWorkspace('__mask') self.setProperty("OutputWorkspace", mtd[_outWS_name])
def PyExec(self): import ICCFitTools as ICCFT import BVGFitTools as BVGFT from mantid.simpleapi import LoadIsawUB import pickle from scipy.ndimage.filters import convolve MDdata = self.getProperty('InputWorkspace').value peaks_ws = self.getProperty('PeaksWorkspace').value fracStop = self.getProperty('FracStop').value dQMax = self.getProperty('DQMax').value UBFile = self.getProperty('UBFile').value padeFile = self.getProperty('ModeratorCoefficientsFile').value strongPeaksParamsFile = self.getProperty('StrongPeakParamsFile').value forceCutoff = self.getProperty('IntensityCutoff').value edgeCutoff = self.getProperty('EdgeCutoff').value peakNumberToFit = self.getProperty('PeakNumber').value pplmin_frac = self.getProperty('MinpplFrac').value pplmax_frac = self.getProperty('MaxpplFrac').value sampleRun = self.getProperty('RunNumber').value q_frame = 'lab' mtd['MDdata'] = MDdata zBG = 1.96 neigh_length_m = 3 iccFitDict = ICCFT.parseConstraints( peaks_ws) #Contains constraints and guesses for ICC Fitting padeCoefficients = ICCFT.getModeratorCoefficients(padeFile) # Load the UB Matrix if one is not already loaded if UBFile == '' and peaks_ws.sample().hasOrientedLattice(): logger.information( "Using UB file already available in PeaksWorkspace") else: try: LoadIsawUB(InputWorkspace=peaks_ws, FileName=UBFile) except: logger.error( "peaks_ws does not have a UB matrix loaded. Must provide a file" ) UBMatrix = peaks_ws.sample().getOrientedLattice().getUB() # There are a few instrument specific parameters that we define here. In some cases, # it may improve fitting to set tweak these parameters, but for simplicity we define these here # The default values are good for MaNDi - new instruments can be added by adding a different elif # statement. # If you change these values or add an instrument, documentation should also be changed. try: numDetRows = peaks_ws.getInstrument().getIntParameter( "numDetRows")[0] numDetCols = peaks_ws.getInstrument().getIntParameter( "numDetCols")[0] nPhi = peaks_ws.getInstrument().getIntParameter("numBinsPhi")[0] nTheta = peaks_ws.getInstrument().getIntParameter( "numBinsTheta")[0] nPhi = peaks_ws.getInstrument().getIntParameter("numBinsPhi")[0] mindtBinWidth = peaks_ws.getInstrument().getNumberParameter( "mindtBinWidth")[0] maxdtBinWidth = peaks_ws.getInstrument().getNumberParameter( "maxdtBinWidth")[0] fracHKL = peaks_ws.getInstrument().getNumberParameter("fracHKL")[0] dQPixel = peaks_ws.getInstrument().getNumberParameter("dQPixel")[0] peakMaskSize = peaks_ws.getInstrument().getIntParameter( "peakMaskSize")[0] except: raise logger.error( "Cannot find all parameters in instrument parameters file.") sys.exit(1) dQ = np.abs(ICCFT.getDQFracHKL(UBMatrix, frac=0.5)) dQ[dQ > dQMax] = dQMax qMask = ICCFT.getHKLMask(UBMatrix, frac=fracHKL, dQPixel=dQPixel, dQ=dQ) # Strong peak profiles - we set up the workspace and determine which peaks we'll fit. strongPeakKeys = [ 'Phi', 'Theta', 'Scale3d', 'FitPhi', 'FitTheta', 'SigTheta', 'SigPhi', 'SigP', 'PeakNumber' ] strongPeakDatatypes = ['float'] * len(strongPeakKeys) strongPeakParams_ws = CreateEmptyTableWorkspace() for key, datatype in zip(strongPeakKeys, strongPeakDatatypes): strongPeakParams_ws.addColumn(datatype, key) # Either load the provided strong peaks file or set the flag to generate it as we go if strongPeaksParamsFile != "": if sys.version_info[0] == 3: strongPeakParams = pickle.load(open(strongPeaksParamsFile, 'rb'), encoding='latin1') else: strongPeakParams = pickle.load( open(strongPeaksParamsFile, 'rb')) generateStrongPeakParams = False # A strong peaks file was provided - we don't need to generate it on the fly so we can fit in order runNumbers = np.array(peaks_ws.column('RunNumber')) peaksToFit = np.where(runNumbers == sampleRun)[0] intensities = np.array(peaks_ws.column('Intens')) rows = np.array(peaks_ws.column('Row')) cols = np.array(peaks_ws.column('Col')) runNumbers = np.array(peaks_ws.column('RunNumber')) intensIDX = intensities < forceCutoff edgeIDX = np.logical_or.reduce( np.array([ rows < edgeCutoff, rows > numDetRows - edgeCutoff, cols < edgeCutoff, cols > numDetCols - edgeCutoff ])) needsForcedProfile = np.logical_or(intensIDX, edgeIDX) needsForcedProfileIDX = np.where(needsForcedProfile)[0] canFitProfileIDX = np.where(~needsForcedProfile)[0] numPeaksCanFit = len(canFitProfileIDX) # We can populate the strongPeakParams_ws now for row in strongPeakParams: strongPeakParams_ws.addRow(row) else: generateStrongPeakParams = True #Figure out which peaks to fit without forcing a profile and set those to be fit first intensities = np.array(peaks_ws.column('Intens')) rows = np.array(peaks_ws.column('Row')) cols = np.array(peaks_ws.column('Col')) runNumbers = np.array(peaks_ws.column('RunNumber')) intensIDX = intensities < forceCutoff edgeIDX = np.logical_or.reduce( np.array([ rows < edgeCutoff, rows > numDetRows - edgeCutoff, cols < edgeCutoff, cols > numDetCols - edgeCutoff ])) needsForcedProfile = np.logical_or(intensIDX, edgeIDX) needsForcedProfileIDX = np.where(needsForcedProfile)[0] canFitProfileIDX = np.where(~needsForcedProfile)[0] numPeaksCanFit = len(canFitProfileIDX) peaksToFit = np.append( canFitProfileIDX, needsForcedProfileIDX) #Will fit in this order peaksToFit = peaksToFit[runNumbers[peaksToFit] == sampleRun] #Initialize our strong peaks dictionary strongPeakParams = np.empty([numPeaksCanFit, 9]) if peakNumberToFit > -1: peaksToFit = [peakNumberToFit] # Create the parameters workspace keys = [ 'peakNumber', 'Alpha', 'Beta', 'R', 'T0', 'bgBVG', 'chiSq3d', 'chiSq', 'dQ', 'KConv', 'MuPH', 'MuTH', 'newQ', 'Scale', 'scale3d', 'SigP', 'SigX', 'SigY', 'Intens3d', 'SigInt3d' ] datatypes = ['float'] * len(keys) datatypes[np.where(np.array(keys) == 'newQ')[0][0]] = 'V3D' params_ws = CreateEmptyTableWorkspace() for key, datatype in zip(keys, datatypes): params_ws.addColumn(datatype, key) # And we're off! peaks_ws_out = peaks_ws.clone() np.warnings.filterwarnings( 'ignore' ) # There can be a lot of warnings for bad solutions that get rejected. progress = Progress(self, 0.0, 1.0, len(peaksToFit)) for fitNumber, peakNumber in enumerate( peaksToFit): #range(peaks_ws.getNumberPeaks()): peak = peaks_ws_out.getPeak(peakNumber) progress.report(' ') try: box = ICCFT.getBoxFracHKL(peak, peaks_ws, MDdata, UBMatrix, peakNumber, dQ, fracHKL=0.5, dQPixel=dQPixel, q_frame=q_frame) if ~needsForcedProfile[peakNumber]: strongPeakParamsToSend = None else: strongPeakParamsToSend = strongPeakParams # Will allow forced weak and edge peaks to be fit using a neighboring peak profile Y3D, goodIDX, pp_lambda, params = BVGFT.get3DPeak( peak, peaks_ws, box, padeCoefficients, qMask, nTheta=nTheta, nPhi=nPhi, plotResults=False, zBG=zBG, fracBoxToHistogram=1.0, bgPolyOrder=1, strongPeakParams=strongPeakParamsToSend, q_frame=q_frame, mindtBinWidth=mindtBinWidth, maxdtBinWidth=maxdtBinWidth, pplmin_frac=pplmin_frac, pplmax_frac=pplmax_frac, forceCutoff=forceCutoff, edgeCutoff=edgeCutoff, peakMaskSize=peakMaskSize, iccFitDict=iccFitDict) # First we get the peak intensity peakIDX = Y3D / Y3D.max() > fracStop intensity = np.sum(Y3D[peakIDX]) # Now the number of background counts under the peak assuming a constant bg across the box n_events = box.getNumEventsArray() convBox = 1.0 * np.ones([ neigh_length_m, neigh_length_m, neigh_length_m ]) / neigh_length_m**3 conv_n_events = convolve(n_events, convBox) bgIDX = np.logical_and.reduce( np.array([~goodIDX, qMask, conv_n_events > 0])) bgEvents = np.mean(n_events[bgIDX]) * np.sum(peakIDX) # Now we consider the variation of the fit. These are done as three independent fits. So we need to consider # the variance within our fit sig^2 = sum(N*(yFit-yData)) / sum(N) and scale by the number of parameters that go into # the fit. In total: 10 (removing scale variables) w_events = n_events.copy() w_events[w_events == 0] = 1 varFit = np.average((n_events[peakIDX] - Y3D[peakIDX]) * (n_events[peakIDX] - Y3D[peakIDX]), weights=(w_events[peakIDX])) sigma = np.sqrt(intensity + bgEvents + varFit) compStr = 'peak {:d}; original: {:4.2f} +- {:4.2f}; new: {:4.2f} +- {:4.2f}'.format( peakNumber, peak.getIntensity(), peak.getSigmaIntensity(), intensity, sigma) logger.information(compStr) # Save the results params['peakNumber'] = peakNumber params['Intens3d'] = intensity params['SigInt3d'] = sigma params['newQ'] = V3D(params['newQ'][0], params['newQ'][1], params['newQ'][2]) params_ws.addRow(params) peak.setIntensity(intensity) peak.setSigmaIntensity(sigma) if generateStrongPeakParams and ~needsForcedProfile[peakNumber]: qPeak = peak.getQLabFrame() strongPeakParams[fitNumber, 0] = np.arctan2(qPeak[1], qPeak[0]) # phi strongPeakParams[fitNumber, 1] = np.arctan2( qPeak[2], np.hypot(qPeak[0], qPeak[1])) #2theta strongPeakParams[fitNumber, 2] = params['scale3d'] strongPeakParams[fitNumber, 3] = params['MuTH'] strongPeakParams[fitNumber, 4] = params['MuPH'] strongPeakParams[fitNumber, 5] = params['SigX'] strongPeakParams[fitNumber, 6] = params['SigY'] strongPeakParams[fitNumber, 7] = params['SigP'] strongPeakParams[fitNumber, 8] = peakNumber strongPeakParams_ws.addRow(strongPeakParams[fitNumber]) except KeyboardInterrupt: np.warnings.filterwarnings('default') # Re-enable on exit raise except: #raise peak.setIntensity(0.0) peak.setSigmaIntensity(1.0) # Cleanup for wsName in mtd.getObjectNames(): if 'fit_' in wsName or 'bvgWS' in wsName or 'tofWS' in wsName or 'scaleWS' in wsName: mtd.remove(wsName) np.warnings.filterwarnings('default') # Re-enable on exit # Set the output self.setProperty('OutputPeaksWorkspace', peaks_ws_out) self.setProperty('OutputParamsWorkspace', params_ws)