diff --git a/Framework/PythonInterface/plugins/algorithms/Abins.py b/Framework/PythonInterface/plugins/algorithms/Abins.py index ce744ec8e744ec858f0d3ff95ae285b66ba2b7c7..39a7ea5570040eb9233f2e06c49eb981a8d44df8 100644 --- a/Framework/PythonInterface/plugins/algorithms/Abins.py +++ b/Framework/PythonInterface/plugins/algorithms/Abins.py @@ -14,7 +14,7 @@ from mantid.api import WorkspaceFactory, AnalysisDataService # noinspection PyProtectedMember from mantid.api._api import WorkspaceGroup -from mantid.simpleapi import CloneWorkspace, GroupWorkspaces, SaveAscii, Load +from mantid.simpleapi import CloneWorkspace, GroupWorkspaces, SaveAscii, Load, Scale from mantid.kernel import logger, StringListValidator, Direction, StringArrayProperty, Atom import AbinsModules @@ -26,6 +26,7 @@ class Abins(PythonAlgorithm): _phonon_file = None _experimental_file = None _temperature = None + _bin_width = None _scale = None _sample_form = None _instrument_name = None @@ -67,11 +68,13 @@ class Abins(PythonAlgorithm): extensions=["raw", "dat"]), doc="File with the experimental inelastic spectrum to compare.") - self.declareProperty(name="Temperature", + self.declareProperty(name="TemperatureInKelvin", direction=Direction.Input, defaultValue=10.0, doc="Temperature in K for which dynamical structure factor S should be calculated.") + self.declareProperty(name="BinWidthInWavenumber", defaultValue=1.0, doc="Width of bins used during rebining.") + self.declareProperty(name="Scale", defaultValue=1.0, doc='Scale the intensity by the given factor. Default is no scaling.') @@ -122,14 +125,18 @@ class Abins(PythonAlgorithm): issues = dict() - temperature = self.getProperty("Temperature").value + temperature = self.getProperty("TemperatureInKelvin").value if temperature < 0: - issues["Temperature"] = "Temperature must be positive." + issues["TemperatureInKelvin"] = "Temperature must be positive." scale = self.getProperty("Scale").value if scale < 0: issues["Scale"] = "Scale must be positive." + bin_width = self.getProperty("BinWidthInWavenumber").value + if not (isinstance(bin_width, float) and 1.0 <= bin_width <= 10.0): + issues["BinWidthInWavenumber"] = ["Invalid bin width. Valid range is [1.0, 10.0] cm^-1"] + dft_program = self.getProperty("DFTprogram").value phonon_filename = self.getProperty("PhononFile").value output = input_file_validators[dft_program](filename_full_path=phonon_filename) @@ -177,7 +184,8 @@ class Abins(PythonAlgorithm): s_calculator = AbinsModules.CalculateS.init(filename=self._phonon_file, temperature=self._temperature, sample_form=self._sample_form, abins_data=dft_data, instrument=self._instrument, - quantum_order_num=self._num_quantum_order_events) + quantum_order_num=self._num_quantum_order_events, + bin_width=self._bin_width) s_data = s_calculator.get_formatted_data() prog_reporter.report("Dynamical structure factors have been determined.") @@ -227,7 +235,8 @@ class Abins(PythonAlgorithm): num_workspaces = mtd[self._out_ws_name].getNumberOfEntries() for wrk_num in range(num_workspaces): wrk = mtd[self._out_ws_name].getItem(wrk_num) - SaveAscii(InputWorkspace=wrk, Filename=wrk.name() + ".dat", Separator="Space", WriteSpectrumID=False) + SaveAscii(InputWorkspace=Scale(wrk, 1.0/self._bin_width, "Multiply"), + Filename=wrk.name() + ".dat", Separator="Space", WriteSpectrumID=False) prog_reporter.report("All workspaces have been saved to ASCII files.") # 9) set OutputWorkspace @@ -544,11 +553,6 @@ class Abins(PythonAlgorithm): if not (isinstance(pkt_per_peak, six.integer_types) and 1 <= pkt_per_peak <= 1000): raise RuntimeError("Invalid value of pkt_per_peak" + message_end) - # bin width is expressed in cm^-1 - bin_width = AbinsModules.AbinsParameters.bin_width - if not (isinstance(bin_width, float) and 1.0 <= bin_width <= 10.0): - raise RuntimeError("Invalid value of bin_width" + message_end) - min_wavenumber = AbinsModules.AbinsParameters.min_wavenumber if not (isinstance(min_wavenumber, float) and min_wavenumber >= 0.0): raise RuntimeError("Invalid value of min_wavenumber" + message_end) @@ -723,7 +727,8 @@ class Abins(PythonAlgorithm): self._dft_program = self.getProperty("DFTprogram").value self._phonon_file = self.getProperty("PhononFile").value self._experimental_file = self.getProperty("ExperimentalFile").value - self._temperature = self.getProperty("Temperature").value + self._temperature = self.getProperty("TemperatureInKelvin").value + self._bin_width = self.getProperty("BinWidthInWavenumber").value self._scale = self.getProperty("Scale").value self._sample_form = self.getProperty("SampleForm").value @@ -749,7 +754,7 @@ class Abins(PythonAlgorithm): # AbinsModules.AbinsParameters.min_wavenumber # AbinsModules.AbinsParameters.max_wavenumber # with bin width AbinsModules.AbinsParameters.bin_width - step = AbinsModules.AbinsParameters.bin_width + step = self._bin_width start = AbinsModules.AbinsParameters.min_wavenumber + step / 2.0 stop = AbinsModules.AbinsParameters.max_wavenumber + step / 2.0 self._bins = np.arange(start=start, stop=stop, step=step, dtype=AbinsModules.AbinsConstants.FLOAT_TYPE) diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/AbinsAdvancedParametersTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/AbinsAdvancedParametersTest.py index 34f994fa9a98b60d65ca4ea190379fd80f7123ab..eb2bb4ede7c3ff1a19a0252bf566fe572e47b8b5 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/AbinsAdvancedParametersTest.py +++ b/Framework/PythonInterface/test/python/plugins/algorithms/AbinsAdvancedParametersTest.py @@ -159,25 +159,6 @@ class AbinsAdvancedParametersTest(unittest.TestCase): AbinsParameters.powder_data_group = "NiceName" self.assertRaises(RuntimeError, Abins, PhononFile=self._Si2 + ".phonon", OutputWorkspace=self._wrk_name) - # Test for rebinning parameters - def test_wrong_bin_width(self): - - # width cannot be 0 - AbinsParameters.bin_width = 0.0 - self.assertRaises(RuntimeError, Abins, PhononFile=self._Si2 + ".phonon", OutputWorkspace=self._wrk_name) - - # width must be float - AbinsParameters.bin_width = 5 - self.assertRaises(RuntimeError, Abins, PhononFile=self._Si2 + ".phonon", OutputWorkspace=self._wrk_name) - - # width must be positive - AbinsParameters.bin_width = -1.0 - self.assertRaises(RuntimeError, Abins, PhononFile=self._Si2 + ".phonon", OutputWorkspace=self._wrk_name) - - # width should be smaller than 10 cm^-1 - AbinsParameters.bin_width = 20.0 - self.assertRaises(RuntimeError, Abins, PhononFile=self._Si2 + ".phonon", OutputWorkspace=self._wrk_name) - def test_wrong_min_wavenumber(self): # minimum wavenumber cannot be negative diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/AbinsBasicTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/AbinsBasicTest.py index 76263f6c84848fdf97272df54f924251f32d783b..b0ca8bb78c4ce7279d6a30d7a5ec9eb5a365d849 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/AbinsBasicTest.py +++ b/Framework/PythonInterface/test/python/plugins/algorithms/AbinsBasicTest.py @@ -49,14 +49,14 @@ class AbinsBasicTest(unittest.TestCase): AllKpointsGiven=False, OutputWorkspace=self._workspace_name) # no name for workspace - self.assertRaises(RuntimeError, Abins, PhononFile=self._si2 + ".phonon", Temperature=self._temperature) + self.assertRaises(RuntimeError, Abins, PhononFile=self._si2 + ".phonon", TemperatureInKelvin=self._temperature) # keyword total in the name of the workspace - self.assertRaises(RuntimeError, Abins, PhononFile=self._si2 + ".phonon", Temperature=self._temperature, + self.assertRaises(RuntimeError, Abins, PhononFile=self._si2 + ".phonon", TemperatureInKelvin=self._temperature, OutputWorkspace=self._workspace_name + "total") # negative temperature in K - self.assertRaises(RuntimeError, Abins, PhononFile=self._si2 + ".phonon", Temperature=-1.0, + self.assertRaises(RuntimeError, Abins, PhononFile=self._si2 + ".phonon", TemperatureInKelvin=-1.0, OutputWorkspace=self._workspace_name) # negative scale @@ -86,7 +86,7 @@ class AbinsBasicTest(unittest.TestCase): """ wrk_ref = Abins(DFTprogram=self._dft_program, PhononFile=self._squaricn + ".phonon", - Temperature=self._temperature, + TemperatureInKelvin=self._temperature, SampleForm=self._sample_form, Instrument=self._instrument_name, Atoms=self._atoms, @@ -98,7 +98,7 @@ class AbinsBasicTest(unittest.TestCase): wrk = Abins(DFTprogram=self._dft_program, PhononFile=self._squaricn + ".phonon", - Temperature=self._temperature, + TemperatureInKelvin=self._temperature, SampleForm=self._sample_form, Instrument=self._instrument_name, Atoms=self._atoms, @@ -121,7 +121,7 @@ class AbinsBasicTest(unittest.TestCase): Abins(DFTprogram=self._dft_program, PhononFile="benzene_Abins.phonon", ExperimentalFile="benzene_Abins.dat", - Temperature=self._temperature, + TemperatureInKelvin=self._temperature, SampleForm=self._sample_form, Instrument=self._instrument_name, Atoms=self._atoms, @@ -148,7 +148,7 @@ class AbinsBasicTest(unittest.TestCase): wrk_ref = Abins(DFTprogram=self._dft_program, PhononFile=self._squaricn + ".phonon", ExperimentalFile=experimental_file, - Temperature=self._temperature, + TemperatureInKelvin=self._temperature, SampleForm=self._sample_form, Instrument=self._instrument_name, Atoms=self._atoms, diff --git a/Testing/Data/SystemTest/BenzeneBinWidthCASTEP.nxs.md5 b/Testing/Data/SystemTest/BenzeneBinWidthCASTEP.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..949f9d5f2af3e83b1e89d822ef2eb3a0df69e725 --- /dev/null +++ b/Testing/Data/SystemTest/BenzeneBinWidthCASTEP.nxs.md5 @@ -0,0 +1 @@ +9f52c317a2ed01f26514b539139df5e6 diff --git a/Testing/Data/SystemTest/BenzeneBinWidthCASTEP.phonon.md5 b/Testing/Data/SystemTest/BenzeneBinWidthCASTEP.phonon.md5 new file mode 100644 index 0000000000000000000000000000000000000000..39fee330d857b5fae54c6c887f8608bf181f3546 --- /dev/null +++ b/Testing/Data/SystemTest/BenzeneBinWidthCASTEP.phonon.md5 @@ -0,0 +1 @@ +ec53aa8ff74b7cd257d7a82c3d6547fd diff --git a/Testing/Data/UnitTest/BENZENE4_g03_win_LoadGAUSSIAN_data.txt.md5 b/Testing/Data/UnitTest/BENZENE4_g03_win_LoadGAUSSIAN_data.txt.md5 index e3eeb3cd4596e1fd2fa72bdf04feb117f15c34cc..7b52d96e871aaa6383c00f35ea3877048da88efa 100644 --- a/Testing/Data/UnitTest/BENZENE4_g03_win_LoadGAUSSIAN_data.txt.md5 +++ b/Testing/Data/UnitTest/BENZENE4_g03_win_LoadGAUSSIAN_data.txt.md5 @@ -1 +1 @@ -2032778ae20e60af1de825be6248aff3 +6b5197fbef6bee2cf77af67b69a2b7c7 diff --git a/Testing/Data/UnitTest/BENZENE4_g09_win_LoadGAUSSIAN_data.txt.md5 b/Testing/Data/UnitTest/BENZENE4_g09_win_LoadGAUSSIAN_data.txt.md5 index 3431a1585dad567535f79707561b88c73e622d7d..2bff40fa76f5352e176ac45c8c028f5fdbe0f348 100644 --- a/Testing/Data/UnitTest/BENZENE4_g09_win_LoadGAUSSIAN_data.txt.md5 +++ b/Testing/Data/UnitTest/BENZENE4_g09_win_LoadGAUSSIAN_data.txt.md5 @@ -1 +1 @@ -ee3349c525b6601afc84643acc49fdc8 +cf3e550f13a672eb6a96cf01c94a5bb7 diff --git a/Testing/Data/UnitTest/C6H5Cl_LoadGAUSSIAN_data.txt.md5 b/Testing/Data/UnitTest/C6H5Cl_LoadGAUSSIAN_data.txt.md5 index a2625c0bac4525f992391369ed53f36958744a75..842e130c16ae2086b418006808b1087a96091e6b 100644 --- a/Testing/Data/UnitTest/C6H5Cl_LoadGAUSSIAN_data.txt.md5 +++ b/Testing/Data/UnitTest/C6H5Cl_LoadGAUSSIAN_data.txt.md5 @@ -1 +1 @@ -26850832776754a46affe765b25ca483 +dff2c2d024be9dd9eca8c13f05bfc53f diff --git a/Testing/Data/UnitTest/LTA_40_O2_LoadDMOL3_data.txt.md5 b/Testing/Data/UnitTest/LTA_40_O2_LoadDMOL3_data.txt.md5 index 6485be690a605f2f07445a2ca93c3450708ba668..b62f96a44867eca8b10e70df82d8206223943bdb 100644 --- a/Testing/Data/UnitTest/LTA_40_O2_LoadDMOL3_data.txt.md5 +++ b/Testing/Data/UnitTest/LTA_40_O2_LoadDMOL3_data.txt.md5 @@ -1 +1 @@ -d49a0a0f8dc9181978afe3405e0eea87 +c520c602a74b93695bbe1a89691678d3 diff --git a/Testing/Data/UnitTest/MgO-222-DISP_LoadCRYSTAL_data.txt.md5 b/Testing/Data/UnitTest/MgO-222-DISP_LoadCRYSTAL_data.txt.md5 index 1bee96dafaa649c6111045b90c5da0cbb1a036b9..c963b21e0444242d97d6d86de51810c0f8483761 100644 --- a/Testing/Data/UnitTest/MgO-222-DISP_LoadCRYSTAL_data.txt.md5 +++ b/Testing/Data/UnitTest/MgO-222-DISP_LoadCRYSTAL_data.txt.md5 @@ -1 +1 @@ -e3da9633a53d6b455c1ee0ad29165fa6 +577a6eec372861923277b3b1c3faaafb diff --git a/Testing/Data/UnitTest/Na2SiF6_LoadDMOL3_data.txt.md5 b/Testing/Data/UnitTest/Na2SiF6_LoadDMOL3_data.txt.md5 index 815fca680ac2de053e1056d05b93d3033ead8ee8..e5cec5364fcf673405749b5e88e2afa06c8de671 100644 --- a/Testing/Data/UnitTest/Na2SiF6_LoadDMOL3_data.txt.md5 +++ b/Testing/Data/UnitTest/Na2SiF6_LoadDMOL3_data.txt.md5 @@ -1 +1 @@ -90c877eb6b8135167b9b3a20b30983d6 +65f9da379be14b6ca29dbf0bf13cbba3 diff --git a/Testing/Data/UnitTest/Si2-phonon_LoadCASTEP_data.txt.md5 b/Testing/Data/UnitTest/Si2-phonon_LoadCASTEP_data.txt.md5 index 823a708ee7ada2d9f9bb378ed62e30277e3906bb..c234c4a8620c77cf44edfdd1424174eded29a612 100644 --- a/Testing/Data/UnitTest/Si2-phonon_LoadCASTEP_data.txt.md5 +++ b/Testing/Data/UnitTest/Si2-phonon_LoadCASTEP_data.txt.md5 @@ -1 +1 @@ -123cb44bf4f85a910c76f09707a7269a +80e89da494a27217a5f7bb6076dd3acc diff --git a/Testing/Data/UnitTest/Si2-sc_LoadCASTEP_data.txt.md5 b/Testing/Data/UnitTest/Si2-sc_LoadCASTEP_data.txt.md5 index d991e12a019dbe23957a2de75d74f08a688440e9..a1005479e0bda7dd781ce4a51805aec60b29f7d8 100644 --- a/Testing/Data/UnitTest/Si2-sc_LoadCASTEP_data.txt.md5 +++ b/Testing/Data/UnitTest/Si2-sc_LoadCASTEP_data.txt.md5 @@ -1 +1 @@ -5170df22d172e8c3119822ec737f63ac +f4ea42523fbc06af7483c3d83fb3b840 diff --git a/Testing/Data/UnitTest/crystalB3LYP_LoadCRYSTAL_data.txt.md5 b/Testing/Data/UnitTest/crystalB3LYP_LoadCRYSTAL_data.txt.md5 index ae6e02b501f01588953727435650a5db71fd83f8..8cd88ad2b04aefd2ff24860bf3781077a7c6cc9b 100644 --- a/Testing/Data/UnitTest/crystalB3LYP_LoadCRYSTAL_data.txt.md5 +++ b/Testing/Data/UnitTest/crystalB3LYP_LoadCRYSTAL_data.txt.md5 @@ -1 +1 @@ -1ac7f6365ed8e892792282e6e90c2105 +b8f79f3908691d510118b488022bb8ac diff --git a/Testing/Data/UnitTest/crystal_set_key_LoadCRYSTAL_data.txt.md5 b/Testing/Data/UnitTest/crystal_set_key_LoadCRYSTAL_data.txt.md5 index 405e268a1b1254ef600b9951a18285e1b70e6801..3779aea147e516400b2af749977bf610e9bc8b74 100644 --- a/Testing/Data/UnitTest/crystal_set_key_LoadCRYSTAL_data.txt.md5 +++ b/Testing/Data/UnitTest/crystal_set_key_LoadCRYSTAL_data.txt.md5 @@ -1 +1 @@ -9d387ae304bce294e0a519faf78e3eec +8b770a47fda2ebfef83d629f249afbb7 diff --git a/Testing/Data/UnitTest/mgo-GX_LoadCRYSTAL_data.txt.md5 b/Testing/Data/UnitTest/mgo-GX_LoadCRYSTAL_data.txt.md5 index efd214fe9f325f56d9afd99a2585b210f494c537..5654e4c8cd98709e45f68d76067e021d524c6c76 100644 --- a/Testing/Data/UnitTest/mgo-GX_LoadCRYSTAL_data.txt.md5 +++ b/Testing/Data/UnitTest/mgo-GX_LoadCRYSTAL_data.txt.md5 @@ -1 +1 @@ -3506d19561fc285fac73b60fa3035f8a +2692a6473cb7a15fc08374edefbea78d diff --git a/Testing/Data/UnitTest/squaricn_no_sum_LoadCASTEP_data.txt.md5 b/Testing/Data/UnitTest/squaricn_no_sum_LoadCASTEP_data.txt.md5 index 6129cb61d1c2f36d8a9feebe3a987c9e13c26e26..e662c8c63dca8c899ebe8968f27d95149a52e43d 100644 --- a/Testing/Data/UnitTest/squaricn_no_sum_LoadCASTEP_data.txt.md5 +++ b/Testing/Data/UnitTest/squaricn_no_sum_LoadCASTEP_data.txt.md5 @@ -1 +1 @@ -98c2ca72a9e327319d8ca57cdd97b5d2 +d3e5e26e8ba40e6a56bb8a784c5bd3bd diff --git a/Testing/Data/UnitTest/squaricn_sum_LoadCASTEP_data.txt.md5 b/Testing/Data/UnitTest/squaricn_sum_LoadCASTEP_data.txt.md5 index fa3dfc0b25fe56822c9c1736e89a1cb0afcddeea..60ae627f2cb3c45ae46b482ed312d0da4196e6a7 100644 --- a/Testing/Data/UnitTest/squaricn_sum_LoadCASTEP_data.txt.md5 +++ b/Testing/Data/UnitTest/squaricn_sum_LoadCASTEP_data.txt.md5 @@ -1 +1 @@ -fd1c5797c11dd7d457f0d6c5bb4adefe +0e70113b983001d0b3b01e12d5e8fce4 diff --git a/Testing/Data/UnitTest/toluene_molecule_LoadCRYSTAL_data.txt.md5 b/Testing/Data/UnitTest/toluene_molecule_LoadCRYSTAL_data.txt.md5 index 073be69b37b4d53521e4e0e1e8140356347bd9b8..3eddc1fa45e6ebf91b8550a34149d0c94dfd4a62 100644 --- a/Testing/Data/UnitTest/toluene_molecule_LoadCRYSTAL_data.txt.md5 +++ b/Testing/Data/UnitTest/toluene_molecule_LoadCRYSTAL_data.txt.md5 @@ -1 +1 @@ -0841e8243fd2c4d3bdbc5b3e6c791f6c +987fbda90cd24c1caa6f5b3b1fa099dd diff --git a/Testing/SystemTests/tests/analysis/AbinsTest.py b/Testing/SystemTests/tests/analysis/AbinsTest.py index 8c345d86a8ee0b2560b0035608f844e36e21009e..e5d4cb8e1e43354cf2d1d04ca96f188ee8760bf4 100644 --- a/Testing/SystemTests/tests/analysis/AbinsTest.py +++ b/Testing/SystemTests/tests/analysis/AbinsTest.py @@ -17,11 +17,17 @@ class HelperTestingClass(object): self._output_name = "output_workspace" self._ref = "reference_workspace" self._scale = 1.0 + self._bin_width = 1.0 self._dft_program = None self._quantum_order_event = None self._system_name = None + def set_bin_width(self, width): + if not (isinstance(width, float) and 1.0 <= width <= 10.0): + raise ValueError("Invalid bin width: {}. ".format(width) + "Valid range is [1.0, 10.0] cm^-1") + self._bin_width = width + def set_instrument_name(self, instrument_name=None): if instrument_name in AbinsConstants.ALL_INSTRUMENTS: @@ -70,7 +76,8 @@ class HelperTestingClass(object): User performs calculation from scratch (not loaded from hdf file). All data is calculated. """ Abins(DFTprogram=self._dft_program, PhononFile=self._system_name + self._extension[self._dft_program], - Temperature=self._temperature, SampleForm=self._sample_form, Instrument=self._instrument_name, + TemperatureInKelvin=self._temperature, SampleForm=self._sample_form, Instrument=self._instrument_name, + BinWidthInWavenumber=self._bin_width, Atoms=self._atoms, SumContributions=self._sum_contributions, QuantumOrderEventsNumber=str(self._quantum_order_event), Scale=self._scale, ScaleByCrossSection=self._cross_section_factor, OutputWorkspace=self._output_name) @@ -88,21 +95,24 @@ class HelperTestingClass(object): # T = 10 K Abins(DFTprogram=self._dft_program, PhononFile=self._system_name + self._extension[self._dft_program], - Temperature=self._temperature, SampleForm=self._sample_form, Instrument=self._instrument_name, + TemperatureInKelvin=self._temperature, SampleForm=self._sample_form, Instrument=self._instrument_name, + BinWidthInWavenumber=self._bin_width, Atoms=self._atoms, SumContributions=self._sum_contributions, Scale=self._scale, QuantumOrderEventsNumber=str(self._quantum_order_event), ScaleByCrossSection=self._cross_section_factor, OutputWorkspace=wrk_name + "init") # T = 20 K Abins(DFTprogram=self._dft_program, PhononFile=self._system_name + self._extension[self._dft_program], - Temperature=temperature_for_test, SampleForm=self._sample_form, Instrument=self._instrument_name, + TemperatureInKelvin=temperature_for_test, SampleForm=self._sample_form, Instrument=self._instrument_name, + BinWidthInWavenumber=self._bin_width, Atoms=self._atoms, SumContributions=self._sum_contributions, Scale=self._scale, QuantumOrderEventsNumber=str(self._quantum_order_event), ScaleByCrossSection=self._cross_section_factor, OutputWorkspace=wrk_name + "_mod") # T = 10 K Abins(DFTprogram=self._dft_program, PhononFile=self._system_name + self._extension[self._dft_program], - Temperature=self._temperature, SampleForm=self._sample_form, Instrument=self._instrument_name, + TemperatureInKelvin=self._temperature, SampleForm=self._sample_form, Instrument=self._instrument_name, + BinWidthInWavenumber=self._bin_width, Atoms=self._atoms, SumContributions=self._sum_contributions, Scale=self._scale, QuantumOrderEventsNumber=str(self._quantum_order_event), ScaleByCrossSection=self._cross_section_factor, OutputWorkspace=self._output_name) @@ -117,7 +127,8 @@ class HelperTestingClass(object): self.case_from_scratch() DeleteWorkspace(self._output_name) Abins(DFTprogram=self._dft_program, PhononFile=self._system_name + self._extension[self._dft_program], - Temperature=self._temperature, SampleForm=self._sample_form, Instrument=self._instrument_name, + TemperatureInKelvin=self._temperature, SampleForm=self._sample_form, Instrument=self._instrument_name, + BinWidthInWavenumber=self._bin_width, Atoms=self._atoms, SumContributions=self._sum_contributions, Scale=self._scale, QuantumOrderEventsNumber=str(order), ScaleByCrossSection=self._cross_section_factor, OutputWorkspace=self._output_name) @@ -414,3 +425,28 @@ class AbinsGAUSSIANestScratch(stresstesting.MantidStressTest, HelperTestingClass def validate(self): self.tolerance = 1e-2 return self._output_name, self.ref_result + + +class AbinsBinWidth(stresstesting.MantidStressTest, HelperTestingClass): + """ + In this benchmark it is tested if calculation with bin width different than the default value is correct. + Calculation performed for crystalline benzene for 1st and 2nd quantum event for output from CASTEP and bin width + 3 cm^-1. This system test should be fast so no need for excludeInPullRequests flag. + """ + tolerance = None + ref_result = None + + def runTest(self): + HelperTestingClass.__init__(self) + name = "BenzeneBinWidthCASTEP" + self.ref_result = name + ".nxs" + self.set_dft_program("CASTEP") + self.set_name(name) + self.set_order(AbinsConstants.QUANTUM_ORDER_TWO) + self.set_cross_section(cross_section="Incoherent") + self.set_bin_width(width=3.0) + self.case_from_scratch() + + def validate(self): + self.tolerance = 1e-2 + return self._output_name, self.ref_result diff --git a/docs/source/algorithms/Abins-v1.rst b/docs/source/algorithms/Abins-v1.rst index afdba918ec56bd69ab5d63724c754082a71db4a5..d3fbd678a1adc17d851b7e390b1b7ec83377c031 100644 --- a/docs/source/algorithms/Abins-v1.rst +++ b/docs/source/algorithms/Abins-v1.rst @@ -93,8 +93,9 @@ Output: .. testcode:: AbinsexplicitParameters wrk_verbose=Abins(DFTprogram="CASTEP", PhononFile="benzene.phonon", ExperimentalFile="benzene_experimental.dat", - Temperature=10, SampleForm="Powder", Instrument="TOSCA", Atoms="H", SumContributions=True, - QuantumOrderEventsNumber="1", ScaleByCrossSection="Incoherent") + TemperatureInKelvin=10, BinWidthInWavenumber=1.0, SampleForm="Powder", Instrument="TOSCA", + Atoms="H", SumContributions=True, + QuantumOrderEventsNumber="1", ScaleByCrossSection="Incoherent") for name in wrk_verbose.getNames(): print(name) diff --git a/scripts/AbinsModules/AbinsParameters.py b/scripts/AbinsModules/AbinsParameters.py index 32cd5add0905d7a2e727d4ddea69109f468da6f2..25d596e39aa8d355ebab24a5adce692f957b68e6 100644 --- a/scripts/AbinsModules/AbinsParameters.py +++ b/scripts/AbinsModules/AbinsParameters.py @@ -39,7 +39,6 @@ crystal_data_group = "SingleCrystal" # name of the group where SingleCrystalDat s_data_group = "S" # name of the group where dynamical factor is stored pkt_per_peak = 50 # number of points for each peak broadened by the experimental resolution -bin_width = 1.0 # defines width of bins used in rebinning of S max_wavenumber = 4100.0 # maximum wavenumber in cm^-1 taken into account while creating workspaces (exclusive) min_wavenumber = 0.0 # minimal wavenumber in cm^-1 taken into account while creating workspaces (exclusive) acoustic_phonon_threshold = 0.0 # frequencies below this value are treated as acoustic and neglected. diff --git a/scripts/AbinsModules/CalculateS.py b/scripts/AbinsModules/CalculateS.py index 4bc0cfaf60cc0e3a5466d5ed27c2b30d1d440cdf..35cb2925cff554074bc4fb7c1c1a4edf63004a51 100644 --- a/scripts/AbinsModules/CalculateS.py +++ b/scripts/AbinsModules/CalculateS.py @@ -12,7 +12,7 @@ class CalculateS(object): @staticmethod def init(filename=None, temperature=None, sample_form=None, abins_data=None, instrument=None, - quantum_order_num=None): + quantum_order_num=None, bin_width=1.0): """ :param filename: name of input DFT file (CASTEP: foo.phonon) :param temperature: temperature in K for which calculation of S should be done @@ -20,13 +20,15 @@ class CalculateS(object): :param abins_data: object of type AbinsData with data from phonon file :param instrument: object of type Instrument for which simulation should be performed :param quantum_order_num: number of quantum order events taken into account during the simulation + :param bin_width: width of bins in wavenumber """ if sample_form in AbinsModules.AbinsConstants.ALL_SAMPLE_FORMS: if sample_form == "Powder": return AbinsModules.SPowderSemiEmpiricalCalculator(filename=filename, temperature=temperature, abins_data=abins_data, instrument=instrument, - quantum_order_num=quantum_order_num) + quantum_order_num=quantum_order_num, + bin_width=bin_width) # TODO: implement numerical powder averaging # elif sample == "SingleCrystal": #TODO implement single crystal scenario diff --git a/scripts/AbinsModules/SData.py b/scripts/AbinsModules/SData.py index 7660cce9635f519aec5f38c14ff5f0aa6fdb81ff..fa02e8f0b02dd34bbfd2cf2672cde1dbd5af4c7d 100644 --- a/scripts/AbinsModules/SData.py +++ b/scripts/AbinsModules/SData.py @@ -21,6 +21,10 @@ class SData(AbinsModules.GeneralData): raise ValueError("Invalid sample form %s" % sample_form) self._data = None # dictionary which stores dynamical structure factor for all atoms + self._bin_width = None + + def set_bin_width(self, width=None): + self._bin_width = width def set(self, items=None): """ @@ -44,7 +48,7 @@ class SData(AbinsModules.GeneralData): elif "frequencies" == item: - step = AbinsModules.AbinsParameters.bin_width + step = self._bin_width bins = np.arange(start=AbinsModules.AbinsParameters.min_wavenumber, stop=AbinsModules.AbinsParameters.max_wavenumber + step, step=step, diff --git a/scripts/AbinsModules/SPowderSemiEmpiricalCalculator.py b/scripts/AbinsModules/SPowderSemiEmpiricalCalculator.py index fd58b3bb10405589b8eeae60431d8bbc5a6c66a8..a7f050950de2d0b0eac270b4f2c5fedf95d0cc2f 100644 --- a/scripts/AbinsModules/SPowderSemiEmpiricalCalculator.py +++ b/scripts/AbinsModules/SPowderSemiEmpiricalCalculator.py @@ -34,7 +34,8 @@ class SPowderSemiEmpiricalCalculator(object): Class for calculating S(Q, omega) """ - def __init__(self, filename=None, temperature=None, abins_data=None, instrument=None, quantum_order_num=None): + def __init__(self, filename=None, temperature=None, abins_data=None, instrument=None, quantum_order_num=None, + bin_width=1.0): """ :param filename: name of input DFT file (CASTEP: foo.phonon) :param temperature: temperature in K for which calculation of S should be done @@ -42,6 +43,7 @@ class SPowderSemiEmpiricalCalculator(object): :param abins_data: object of type AbinsData with data from phonon file :param instrument: name of instrument (str) :param quantum_order_num: number of quantum order events taken into account during the simulation + :param bin_width: bin width used in rebining in wavenumber """ if not isinstance(temperature, (int, float)): raise ValueError("Invalid value of the temperature. Number was expected.") @@ -96,7 +98,8 @@ class SPowderSemiEmpiricalCalculator(object): AbinsModules.AbinsConstants.QUANTUM_ORDER_THREE: self._calculate_order_three, AbinsModules.AbinsConstants.QUANTUM_ORDER_FOUR: self._calculate_order_four} - step = AbinsModules.AbinsParameters.bin_width + step = bin_width + self._bin_width = bin_width start = AbinsModules.AbinsParameters.min_wavenumber + step stop = AbinsModules.AbinsParameters.max_wavenumber + step self._bins = np.arange(start=start, stop=stop, step=step, dtype=AbinsModules.AbinsConstants.FLOAT_TYPE) @@ -281,6 +284,7 @@ class SPowderSemiEmpiricalCalculator(object): # put data to SData object s_data = AbinsModules.SData(temperature=self._temperature, sample_form=self._sample_form) + s_data.set_bin_width(width=self._bin_width) s_data.set(items=data) return s_data @@ -505,7 +509,8 @@ class SPowderSemiEmpiricalCalculator(object): rebined_broad_spectrum = self._fix_empty_array() # multiply by k-point weight and scaling constant - factor = self._weight / AbinsModules.AbinsParameters.bin_width + # factor = self._weight / self._bin_width + factor = self._weight rebined_broad_spectrum = rebined_broad_spectrum * factor return local_freq, local_coeff, rebined_broad_spectrum @@ -655,9 +660,8 @@ class SPowderSemiEmpiricalCalculator(object): else: inds = np.digitize(x=array_x, bins=self._bins) - AbinsModules.AbinsConstants.PYTHON_INDEX_SHIFT output_array_x = self._frequencies - output_array_y = np.asarray( - a=[array_y[inds == i].sum() for i in range(self._freq_size)], - dtype=AbinsModules.AbinsConstants.FLOAT_TYPE) / AbinsModules.AbinsParameters.bin_width + output_array_y = np.asarray(a=[array_y[inds == i].sum() for i in range(self._freq_size)], + dtype=AbinsModules.AbinsConstants.FLOAT_TYPE) return output_array_x, output_array_y @@ -725,6 +729,7 @@ class SPowderSemiEmpiricalCalculator(object): data["datasets"]["data"] = temp_data s_data = AbinsModules.SData(temperature=self._temperature, sample_form=self._sample_form) + s_data.set_bin_width(width=self._bin_width) s_data.set(items=data["datasets"]["data"]) return s_data diff --git a/scripts/test/AbinsCalculateSPowderTest.py b/scripts/test/AbinsCalculateSPowderTest.py index 5d8e58a61a52f274ce53b035c02e428d7537387a..730af9dbc9c3ee67dabc49e78f78dd1ae58dd808 100644 --- a/scripts/test/AbinsCalculateSPowderTest.py +++ b/scripts/test/AbinsCalculateSPowderTest.py @@ -32,28 +32,24 @@ class AbinsCalculateSPowderTest(unittest.TestCase): # wrong filename with self.assertRaises(ValueError): - AbinsModules.CalculateS.init(filename=1, temperature=self._temperature, sample_form=self._sample_form, abins_data=good_data, instrument=self._instrument, quantum_order_num=self._order_event) # wrong temperature with self.assertRaises(ValueError): - AbinsModules.CalculateS.init(filename=full_path_filename, temperature=-1, sample_form=self._sample_form, abins_data=good_data, instrument=self._instrument, quantum_order_num=self._order_event) # wrong sample with self.assertRaises(ValueError): - - AbinsModules.CalculateS.init(filename=full_path_filename, temperature=self._temperature, sample_form="SOLID", - abins_data=good_data, instrument=self._instrument, + AbinsModules.CalculateS.init(filename=full_path_filename, temperature=self._temperature, + sample_form="SOLID", abins_data=good_data, instrument=self._instrument, quantum_order_num=self._order_event) # wrong abins data: content of abins data instead of object abins_data with self.assertRaises(ValueError): - AbinsModules.CalculateS.init(filename=full_path_filename, temperature=self._temperature, sample_form=self._sample_form, abins_data=good_data.extract(), instrument=self._instrument, quantum_order_num=self._order_event) @@ -75,18 +71,18 @@ class AbinsCalculateSPowderTest(unittest.TestCase): # calculation of powder data good_data = self._get_good_data(filename=name) good_tester = AbinsModules.CalculateS.init( - filename=AbinsModules.AbinsTestHelpers.find_file(filename=name + ".phonon"), - temperature=self._temperature, sample_form=self._sample_form, abins_data=good_data["DFT"], - instrument=self._instrument, quantum_order_num=self._order_event) + filename=AbinsModules.AbinsTestHelpers.find_file(filename=name + ".phonon"), temperature=self._temperature, + sample_form=self._sample_form, abins_data=good_data["DFT"], instrument=self._instrument, + quantum_order_num=self._order_event) calculated_data = good_tester.get_formatted_data() self._check_data(good_data=good_data["S"], data=calculated_data.extract()) # check if loading powder data is correct - new_tester = AbinsModules.CalculateS.init(filename=AbinsModules.AbinsTestHelpers.find_file(filename=name + ".phonon"), - temperature=self._temperature, sample_form=self._sample_form, - abins_data=good_data["DFT"], instrument=self._instrument, - quantum_order_num=self._order_event) + new_tester = AbinsModules.CalculateS.init( + filename=AbinsModules.AbinsTestHelpers.find_file(filename=name + ".phonon"), temperature=self._temperature, + sample_form=self._sample_form, abins_data=good_data["DFT"], instrument=self._instrument, + quantum_order_num=self._order_event) loaded_data = new_tester.load_formatted_data() self._check_data(good_data=good_data["S"], data=loaded_data.extract())