Changeset b09095a in sasview
- Timestamp:
- Apr 17, 2017 12:39:50 PM (8 years ago)
- Branches:
- master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- 8ffafd1
- Parents:
- beba407
- git-author:
- Jeff Krzywon <krzywon@…> (04/17/17 12:39:50)
- git-committer:
- krzywon <krzywon@…> (04/17/17 12:39:50)
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sascalc/dataloader/file_reader_base_class.py
rbeba407 rb09095a 1 1 """ 2 This is the base file reader class allfile readers should inherit from.2 This is the base file reader class most file readers should inherit from. 3 3 All generic functionality required for a file loader/reader is built into this 4 4 class … … 7 7 import os 8 8 import logging 9 import numpy as np 9 10 from abc import abstractmethod 10 11 from loader_exceptions import NoKnownLoaderException, FileContentsException,\ … … 19 20 # List of Data1D and Data2D objects to be sent back to data_loader 20 21 output = [] 21 # Current plottable 1D/2Dobject being loaded in22 # Current plottable_(1D/2D) object being loaded in 22 23 current_dataset = None 23 # Current DataInfo objec ct being loaded in24 # Current DataInfo object being loaded in 24 25 current_datainfo = None 25 # Wildcards 26 type = ["Text files (*.txt)"] 26 # String to describe the type of data this reader can load 27 type_name = "ASCII" 28 # Wildcards to display 29 type = ["Text files (*.txt|*.TXT)"] 27 30 # List of allowed extensions 28 31 ext = ['.txt'] 29 32 # Bypass extension check and try to load anyway 30 33 allow_all = False 34 # Able to import the unit converter 35 has_converter = True 36 # Open file handle 37 f_open = None 38 # Default value of zero 39 _ZERO = 1e-16 31 40 32 41 def read(self, filepath): … … 42 51 # Try to load the file, but raise an error if unable to. 43 52 try: 44 input_f = open(filepath, 'rb') 45 self.get_file_contents(input_f) 53 self.unit_converter() 54 self.f_open = open(filepath, 'rb') 55 self.get_file_contents() 56 self.sort_one_d_data() 46 57 except RuntimeError: 58 # Reader specific errors 59 # TODO: Give a specific error. 47 60 pass 48 61 except OSError as e: 62 # If the file cannot be opened 49 63 msg = "Unable to open file: {}\n".format(filepath) 50 64 msg += e.message 51 65 self.handle_error_message(msg) 52 66 except Exception as e: 53 self.handle_error_message(e.message) 67 # Handle any other generic error 68 # TODO: raise or log? 69 raise 70 finally: 71 if not self.f_open.closed: 72 self.f_open.close() 54 73 else: 55 74 msg = "Unable to find file at: {}\n".format(filepath) 56 75 msg += "Please check your file path and try again." 57 76 self.handle_error_message(msg) 58 # Return a list of parsed entries that data loader can manage77 # Return a list of parsed entries that data_loader can manage 59 78 return self.output 60 79 … … 79 98 self.output.append(data_obj) 80 99 100 def unit_converter(self): 101 """ 102 Generic unit conversion import 103 """ 104 # Check whether we have a converter available 105 self.has_converter = True 106 try: 107 from sas.sascalc.data_util.nxsunit import Converter 108 except: 109 self.has_converter = False 110 111 def sort_one_d_data(self): 112 """ 113 Sort 1D data along the X axis for consistency 114 """ 115 final_list = [] 116 for data in self.output: 117 if isinstance(data, Data1D): 118 ind = np.lexsort((data.y, data.x)) 119 data.x = np.asarray([data.x[i] for i in ind]) 120 data.y = np.asarray([data.y[i] for i in ind]) 121 if data.dx is not None: 122 data.dx = np.asarray([data.dx[i] for i in ind]) 123 if data.dxl is not None: 124 data.dxl = np.asarray([data.dxl[i] for i in ind]) 125 if data.dxw is not None: 126 data.dxw = np.asarray([data.dxw[i] for i in ind]) 127 if data.dy is not None: 128 data.dy = np.asarray([data.dy[i] for i in ind]) 129 if data.lam is not None: 130 data.lam = np.asarray([data.lam[i] for i in ind]) 131 if data.dlam is not None: 132 data.dlam = np.asarray([data.dlam[i] for i in ind]) 133 final_list.append(data) 134 self.output = final_list 135 136 @staticmethod 137 def splitline(line): 138 """ 139 Splits a line into pieces based on common delimeters 140 :param line: A single line of text 141 :return: list of values 142 """ 143 # Initial try for CSV (split on ,) 144 toks = line.split(',') 145 # Now try SCSV (split on ;) 146 if len(toks) < 2: 147 toks = line.split(';') 148 # Now go for whitespace 149 if len(toks) < 2: 150 toks = line.split() 151 return toks 152 81 153 @abstractmethod 82 def get_file_contents(self , contents):154 def get_file_contents(self): 83 155 """ 84 All reader classes that inherit from here should implement 85 :param contents: 156 All reader classes that inherit from FileReader must implement 86 157 """ 87 158 pass -
src/sas/sascalc/dataloader/readers/ascii_reader.py
r235f514 rb09095a 1 1 """ 2 ASCIIreader2 Generic multi-column ASCII data reader 3 3 """ 4 4 ############################################################################ 5 # This software was developed by the University of Tennessee as part of the6 # Distributed Data Analysis of Neutron Scattering Experiments (DANSE)7 # project funded by the US National Science Foundation.8 # If you use DANSE applications to do scientific research that leads to9 # publication, we ask that you acknowledge the use of the software with the10 # following sentence:11 # This work benefited from DANSE software developed under NSF award DMR-0520547.12 # copyright 2008, University of Tennessee5 # This software was developed by the University of Tennessee as part of the 6 # Distributed Data Analysis of Neutron Scattering Experiments (DANSE) 7 # project funded by the US National Science Foundation. 8 # If you use DANSE applications to do scientific research that leads to 9 # publication, we ask that you acknowledge the use of the software with the 10 # following sentence: 11 # This work benefited from DANSE software developed under NSF award DMR-0520547. 12 # copyright 2008, University of Tennessee 13 13 ############################################################################# 14 14 15 import logging 16 import numpy as np 17 from sas.sascalc.dataloader.file_reader_base_class import FileReader 18 from sas.sascalc.dataloader.data_info import DataInfo, plottable_1D 15 19 16 import numpy as np 17 import os 18 from sas.sascalc.dataloader.data_info import Data1D 19 20 # Check whether we have a converter available 21 has_converter = True 22 try: 23 from sas.sascalc.data_util.nxsunit import Converter 24 except: 25 has_converter = False 26 _ZERO = 1e-16 20 logger = logging.getLogger(__name__) 27 21 28 22 29 class Reader :23 class Reader(FileReader): 30 24 """ 31 25 Class to load ascii files (2, 3 or 4 columns). 32 26 """ 33 # #File type27 # File type 34 28 type_name = "ASCII" 35 36 ## Wildcards 29 # Wildcards 37 30 type = ["ASCII files (*.txt)|*.txt", 38 31 "ASCII files (*.dat)|*.dat", 39 32 "ASCII files (*.abs)|*.abs", 40 33 "CSV files (*.csv)|*.csv"] 41 ## List of allowed extensions 42 ext = ['.txt', '.TXT', '.dat', '.DAT', '.abs', '.ABS', 'csv', 'CSV'] 34 # List of allowed extensions 35 ext = ['.txt', '.dat', '.abs', '.csv'] 36 # Flag to bypass extension check 37 allow_all = True 38 # data unless that is the only data 39 min_data_pts = 5 43 40 44 ## Flag to bypass extension check 45 allow_all = True 41 def get_file_contents(self): 42 """ 43 Get the contents of the file 44 """ 46 45 47 def read(self, path): 48 """ 49 Load data file 46 buff = self.f_open.read() 47 filepath = self.f_open.name 48 lines = buff.splitlines() 49 self.output = [] 50 self.current_datainfo = DataInfo() 51 self.current_datainfo.filename = filepath 52 self.reset_data_list(len(lines)) 50 53 51 :param path: file path 52 :return: Data1D object, or None 54 # The first good line of data will define whether 55 # we have 2-column or 3-column ascii 56 has_error_dx = None 57 has_error_dy = None 53 58 54 :raise RuntimeError: when the file can't be opened 55 :raise ValueError: when the length of the data vectors are inconsistent 56 """ 57 if os.path.isfile(path): 58 basename = os.path.basename(path) 59 _, extension = os.path.splitext(basename) 60 if self.allow_all or extension.lower() in self.ext: 61 try: 62 # Read in binary mode since GRASP frequently has no-ascii 63 # characters that breaks the open operation 64 input_f = open(path,'rb') 65 except: 66 raise RuntimeError, "ascii_reader: cannot open %s" % path 67 buff = input_f.read() 68 lines = buff.splitlines() 59 # Initialize counters for data lines and header lines. 60 is_data = False 61 # More than "5" lines of data is considered as actual 62 # To count # of current data candidate lines 63 candidate_lines = 0 64 # To count total # of previous data candidate lines 65 candidate_lines_previous = 0 66 # Current line number 67 line_no = 0 68 # minimum required number of columns of data 69 lentoks = 2 70 for line in lines: 71 toks = self.splitline(line.strip()) 72 # To remember the number of columns in the current line of data 73 new_lentoks = len(toks) 74 try: 75 if new_lentoks == 0: 76 # If the line is blank, skip and continue on 77 # In case of breaks within data sets. 78 continue 79 elif new_lentoks != lentoks and is_data: 80 # If a footer is found, break the loop and save the data 81 break 82 elif new_lentoks != lentoks and not is_data: 83 # If header lines are numerical 84 candidate_lines = 0 85 self.reset_data_list(len(lines) - line_no) 69 86 70 # Arrays for data storage 71 tx = np.zeros(0) 72 ty = np.zeros(0) 73 tdy = np.zeros(0) 74 tdx = np.zeros(0) 87 candidate_lines += 1 88 # If 5 or more lines, this is considering the set data 89 if candidate_lines >= self.min_data_pts: 90 is_data = True 75 91 76 # The first good line of data will define whether 77 # we have 2-column or 3-column ascii 92 self.current_dataset.x[candidate_lines - 1] = float(toks[0]) 93 self.current_dataset.y[candidate_lines - 1] = float(toks[1]) 94 95 # If a 3rd row is present, consider it dy 96 if new_lentoks > 2: 97 self.current_dataset.dy[candidate_lines - 1] = \ 98 float(toks[2]) 99 has_error_dy = True 100 101 # If a 4th row is present, consider it dx 102 if new_lentoks > 3: 103 self.current_dataset.dx[candidate_lines - 1] = \ 104 float(toks[3]) 105 has_error_dx = True 106 107 # To remember the # of columns on the current line 108 # for the next line of data 109 lentoks = new_lentoks 110 line_no += 1 111 except ValueError: 112 # It is data and meet non - number, then stop reading 113 if is_data: 114 break 115 # Delete the previously stored lines of data candidates if 116 # the list is not data 117 self.reset_data_list(len(lines) - line_no) 118 lentoks = 2 78 119 has_error_dx = None 79 120 has_error_dy = None 121 # Reset # of lines of data candidates 122 candidate_lines = 0 123 except Exception: 124 # Handle any unexpected exceptions 125 raise 80 126 81 #Initialize counters for data lines and header lines. 82 is_data = False 83 # More than "5" lines of data is considered as actual 84 # data unless that is the only data 85 min_data_pts = 5 86 # To count # of current data candidate lines 87 candidate_lines = 0 88 # To count total # of previous data candidate lines 89 candidate_lines_previous = 0 90 #minimum required number of columns of data 91 lentoks = 2 92 for line in lines: 93 toks = self.splitline(line) 94 # To remember the # of columns in the current line of data 95 new_lentoks = len(toks) 96 try: 97 if new_lentoks == 1 and not is_data: 98 ## If only one item in list, no longer data 99 raise ValueError 100 elif new_lentoks == 0: 101 ## If the line is blank, skip and continue on 102 ## In case of breaks within data sets. 103 continue 104 elif new_lentoks != lentoks and is_data: 105 ## If a footer is found, break the loop and save the data 106 break 107 elif new_lentoks != lentoks and not is_data: 108 ## If header lines are numerical 109 candidate_lines = 0 110 candidate_lines_previous = 0 127 if not is_data: 128 # TODO: Check file extension - primary reader, throw error. 129 # TODO: Secondary check, pass and try next reader 130 msg = "ascii_reader: x has no data" 131 raise RuntimeError(msg) 132 # Sanity check 133 if has_error_dy and not len(self.current_dataset.y) == \ 134 len(self.current_dataset.dy): 135 msg = "ascii_reader: y and dy have different length" 136 raise RuntimeError(msg) 137 if has_error_dx and not len(self.current_dataset.x) == \ 138 len(self.current_dataset.dx): 139 msg = "ascii_reader: y and dy have different length" 140 raise RuntimeError(msg) 141 # If the data length is zero, consider this as 142 # though we were not able to read the file. 143 if len(self.current_dataset.x) < 1: 144 raise RuntimeError("ascii_reader: could not load file") 145 return None 111 146 112 #Make sure that all columns are numbers. 113 for colnum in range(len(toks)): 114 # Any non-floating point values throw ValueError 115 float(toks[colnum]) 147 # Data 148 self.current_dataset.x = \ 149 self.current_dataset.x[self.current_dataset.x != 0] 150 self.current_dataset.y = \ 151 self.current_dataset.y[self.current_dataset.x != 0] 152 self.current_dataset.dy = \ 153 self.current_dataset.dy[self.current_dataset.x != 0] if \ 154 has_error_dy else np.zeros(len(self.current_dataset.y)) 155 self.current_dataset.dx = \ 156 self.current_dataset.dx[self.current_dataset.x != 0] if \ 157 has_error_dx else np.zeros(len(self.current_dataset.x)) 116 158 117 candidate_lines += 1 118 _x = float(toks[0]) 119 _y = float(toks[1]) 120 _dx = None 121 _dy = None 159 self.current_dataset.xaxis("\\rm{Q}", 'A^{-1}') 160 self.current_dataset.yaxis("\\rm{Intensity}", "cm^{-1}") 122 161 123 #If 5 or more lines, this is considering the set data124 if candidate_lines >= min_data_pts:125 is_data = True162 # Store loading process information 163 self.current_datainfo.meta_data['loader'] = self.type_name 164 self.send_to_output() 126 165 127 # If a 3rd row is present, consider it dy 128 if new_lentoks > 2: 129 _dy = float(toks[2]) 130 has_error_dy = False if _dy is None else True 131 132 # If a 4th row is present, consider it dx 133 if new_lentoks > 3: 134 _dx = float(toks[3]) 135 has_error_dx = False if _dx is None else True 136 137 # Delete the previously stored lines of data candidates if 138 # the list is not data 139 if candidate_lines == 1 and -1 < candidate_lines_previous < min_data_pts and \ 140 is_data == False: 141 try: 142 tx = np.zeros(0) 143 ty = np.zeros(0) 144 tdy = np.zeros(0) 145 tdx = np.zeros(0) 146 except: 147 pass 148 149 if has_error_dy == True: 150 tdy = np.append(tdy, _dy) 151 if has_error_dx == True: 152 tdx = np.append(tdx, _dx) 153 tx = np.append(tx, _x) 154 ty = np.append(ty, _y) 155 156 #To remember the # of columns on the current line 157 # for the next line of data 158 lentoks = new_lentoks 159 candidate_lines_previous = candidate_lines 160 except ValueError: 161 # It is data and meet non - number, then stop reading 162 if is_data == True: 163 break 164 lentoks = 2 165 has_error_dx = None 166 has_error_dy = None 167 #Reset # of lines of data candidates 168 candidate_lines = 0 169 except: 170 pass 171 172 input_f.close() 173 if not is_data: 174 msg = "ascii_reader: x has no data" 175 raise RuntimeError, msg 176 # Sanity check 177 if has_error_dy == True and not len(ty) == len(tdy): 178 msg = "ascii_reader: y and dy have different length" 179 raise RuntimeError, msg 180 if has_error_dx == True and not len(tx) == len(tdx): 181 msg = "ascii_reader: y and dy have different length" 182 raise RuntimeError, msg 183 # If the data length is zero, consider this as 184 # though we were not able to read the file. 185 if len(tx) == 0: 186 raise RuntimeError, "ascii_reader: could not load file" 187 188 #Let's re-order the data to make cal. 189 # curve look better some cases 190 ind = np.lexsort((ty, tx)) 191 x = np.zeros(len(tx)) 192 y = np.zeros(len(ty)) 193 dy = np.zeros(len(tdy)) 194 dx = np.zeros(len(tdx)) 195 output = Data1D(x, y, dy=dy, dx=dx) 196 self.filename = output.filename = basename 197 198 for i in ind: 199 x[i] = tx[ind[i]] 200 y[i] = ty[ind[i]] 201 if has_error_dy == True: 202 dy[i] = tdy[ind[i]] 203 if has_error_dx == True: 204 dx[i] = tdx[ind[i]] 205 # Zeros in dx, dy 206 if has_error_dx: 207 dx[dx == 0] = _ZERO 208 if has_error_dy: 209 dy[dy == 0] = _ZERO 210 #Data 211 output.x = x[x != 0] 212 output.y = y[x != 0] 213 output.dy = dy[x != 0] if has_error_dy == True\ 214 else np.zeros(len(output.y)) 215 output.dx = dx[x != 0] if has_error_dx == True\ 216 else np.zeros(len(output.x)) 217 218 output.xaxis("\\rm{Q}", 'A^{-1}') 219 output.yaxis("\\rm{Intensity}", "cm^{-1}") 220 221 # Store loading process information 222 output.meta_data['loader'] = self.type_name 223 if len(output.x) < 1: 224 raise RuntimeError, "%s is empty" % path 225 return output 226 227 else: 228 raise RuntimeError, "%s is not a file" % path 229 return None 230 231 def splitline(self, line): 166 def reset_data_list(self, no_lines): 232 167 """ 233 Splits a line into pieces based on common delimeters 234 :param line: A single line of text 235 :return: list of values 168 Reset the plottable_1D object 236 169 """ 237 # Initial try for CSV (split on ,) 238 toks = line.split(',') 239 # Now try SCSV (split on ;) 240 if len(toks) < 2: 241 toks = line.split(';') 242 # Now go for whitespace 243 if len(toks) < 2: 244 toks = line.split() 245 return toks 170 # Initialize data sets with arrays the maximum possible size 171 x = np.zeros(no_lines) 172 y = np.zeros(no_lines) 173 dy = np.zeros(no_lines) 174 dx = np.zeros(no_lines) 175 self.current_dataset = plottable_1D(x, y, dx, dy) -
test/sascalculator/test/utest_slit_length_calculator.py
r959eb01 rb09095a 5 5 import unittest 6 6 from sas.sascalc.dataloader.readers.ascii_reader import Reader 7 from sas.sascalc.calculator.slit_length_calculator import SlitlengthCalculator as calculator 7 from sas.sascalc.calculator.slit_length_calculator import SlitlengthCalculator \ 8 as calculator 8 9 9 import os.path10 10 11 class slit_calculator(unittest.TestCase):11 class SlitCalculator(unittest.TestCase): 12 12 13 13 def setUp(self): … … 15 15 self.reader = Reader() 16 16 17 def test_slit length_calculation(self):17 def test_slit_length_calculation(self): 18 18 """ 19 19 Test slit_length_calculator" 20 20 """ 21 f = self.reader.read("beam profile.DAT") 21 list = self.reader.read("beam profile.DAT") 22 self.assertTrue(len(list) == 1) 23 f = list[0] 22 24 cal = calculator() 23 25 cal.set_data(f.x,f.y) 24 slit length = cal.calculate_slit_length()26 slit_length = cal.calculate_slit_length() 25 27 26 28 # The value "5.5858" was obtained by manual calculation. 27 29 # It turns out our slit length is FWHM/2 28 self.assertAlmostEqual(slit length,5.5858/2, 3)30 self.assertAlmostEqual(slit_length, 5.5858/2, 3) 29 31 30 32 -
test/sasdataloader/test/utest_ascii.py
r959eb01 rb09095a 6 6 7 7 import unittest 8 from sas.sascalc.dataloader.loader import Loader 9 10 import os.path 8 from sas.sascalc.dataloader.loader import Loader 11 9 12 class abs_reader(unittest.TestCase): 10 11 class ABSReaderTests(unittest.TestCase): 13 12 14 13 def setUp(self): 15 14 self.loader = Loader() 15 self.f1_list = self.loader.load("ascii_test_1.txt") 16 self.f1 = self.f1_list[0] 17 self.f2_list = self.loader.load("ascii_test_2.txt") 18 self.f2 = self.f2_list[0] 19 self.f3_list = self.loader.load("ascii_test_3.txt") 20 self.f3 = self.f3_list[0] 21 self.f4_list = self.loader.load("ascii_test_4.abs") 22 self.f4 = self.f4_list[0] 23 self.f5_list = self.loader.load("ascii_test_5.txt") 24 self.f5 = self.f5_list[0] 16 25 17 26 def test_checkdata(self): … … 19 28 Test .ABS file loaded as ascii 20 29 """ 21 f = self.loader.load("ascii_test_1.txt")22 30 # The length of the data is 10 23 self.assertEqual(len( f.x), 10)24 self.assertEqual( f.x[0],0.002618)25 self.assertEqual( f.x[9],0.0497)26 self.assertEqual( f.x_unit, '1/A')27 self.assertEqual( f.y_unit, '1/cm')31 self.assertEqual(len(self.f1.x), 10) 32 self.assertEqual(self.f1.x[0],0.002618) 33 self.assertEqual(self.f1.x[9],0.0497) 34 self.assertEqual(self.f1.x_unit, '1/A') 35 self.assertEqual(self.f1.y_unit, '1/cm') 28 36 29 self.assertEqual( f.meta_data['loader'],"ASCII")37 self.assertEqual(self.f1.meta_data['loader'],"ASCII") 30 38 31 39 def test_truncated_1(self): … … 38 46 as though it were the start of a footer). 39 47 """ 40 # Test .ABS file loaded as ascii 41 f = self.loader.load("ascii_test_2.txt") 42 # The length of the data is 10 43 self.assertEqual(len(f.x), 5) 44 self.assertEqual(f.x[0],0.002618) 45 self.assertEqual(f.x[4],0.02356) 48 # The length of the data is 5 49 self.assertEqual(len(self.f2.x), 5) 50 self.assertEqual(self.f2.x[0],0.002618) 51 self.assertEqual(self.f2.x[4],0.02356) 46 52 47 53 def test_truncated_2(self): … … 52 58 reading at the first inconsitent line. 53 59 """ 54 # Test .ABS file loaded as ascii55 f = self.loader.load("ascii_test_3.txt")56 60 # The length of the data is 5 57 self.assertEqual(len( f.x), 5)58 self.assertEqual( f.x[0],0.002618)59 self.assertEqual( f.x[4],0.02356)61 self.assertEqual(len(self.f3.x), 5) 62 self.assertEqual(self.f3.x[0],0.002618) 63 self.assertEqual(self.f3.x[4],0.02356) 60 64 61 65 def test_truncated_3(self): … … 66 70 reading at the last line of header. 67 71 """ 68 # Test .ABS file loaded as ascii69 f = self.loader.load("ascii_test_4.abs")70 72 # The length of the data is 5 71 self.assertEqual(len( f.x), 5)72 self.assertEqual( f.x[0],0.012654)73 self.assertEqual( f.x[4],0.02654)73 self.assertEqual(len(self.f4.x), 5) 74 self.assertEqual(self.f4.x[0],0.012654) 75 self.assertEqual(self.f4.x[4],0.02654) 74 76 75 77 def test_truncated_4(self): … … 78 80 Only the last 5 2-col lines should be read. 79 81 """ 80 # Test .ABS file loaded as ascii81 f = self.loader.load("ascii_test_5.txt")82 82 # The length of the data is 5 83 self.assertEqual(len( f.x), 5)84 self.assertEqual( f.x[0],0.02879)85 self.assertEqual( f.x[4],0.0497)83 self.assertEqual(len(self.f5.x), 5) 84 self.assertEqual(self.f5.x[0],0.02879) 85 self.assertEqual(self.f5.x[4],0.0497) 86 86 87 87 def test_truncated_5(self): 88 88 """ 89 Test a 6-col ascii file with complex header where one of them has a letter and90 many lines with 2 or 2 columns in the middle of the data section.91 Only last four lines should be read.89 Test a 6-col ascii file with complex header where one of them has a 90 letter and many lines with 2 or 2 columns in the middle of the data 91 section. Will be rejected because fewer than 5 lines. 92 92 """ 93 93 # Test .ABS file loaded as ascii -
test/sasdataloader/test/utest_averaging.py
r9a5097c rb09095a 3 3 import math 4 4 5 from sas.sascalc.dataloader.loader import 5 from sas.sascalc.dataloader.loader import Loader 6 6 from sas.sascalc.dataloader.manipulations import Ring, CircularAverage, SectorPhi, get_q,reader2D_converter 7 7 … … 110 110 111 111 o = r(self.data) 112 answer = Loader().load('ring_testdata.txt') 112 data_list = Loader().load('ring_testdata.txt') 113 answer = data_list[0] 113 114 114 115 for i in range(r.nbins_phi - 1): -
test/sasinvariant/test/utest_use_cases.py
r959eb01 rb09095a 6 6 import unittest 7 7 from sas.sascalc.dataloader.loader import Loader 8 9 8 from sas.sascalc.invariant import invariant 9 10 10 11 11 class Data1D: 12 12 pass 13 13 14 14 15 class TestLineFit(unittest.TestCase): 15 16 """ … … 17 18 """ 18 19 def setUp(self): 19 self.data = Loader().load("linefittest.txt") 20 20 self.data_list = Loader().load("linefittest.txt") 21 self.data = self.data_list[0] 22 21 23 def test_fit_line_data(self): 22 24 """ 23 25 Fit_Test_1: test linear fit, ax +b, without fixed 24 26 """ 25 27 26 28 # Create invariant object. Background and scale left as defaults. 27 29 fit = invariant.Extrapolator(data=self.data) 28 30 29 # #Without holding31 # Without holding 30 32 p, dp = fit.fit(power=None) 31 33 … … 33 35 self.assertAlmostEquals(p[0], 2.3983,3) 34 36 self.assertAlmostEquals(p[1], 0.87833,3) 35 36 37 37 38 def test_fit_line_data_fixed(self): … … 39 40 Fit_Test_2: test linear fit, ax +b, with 'a' fixed 40 41 """ 41 42 42 43 # Create invariant object. Background and scale left as defaults. 43 44 fit = invariant.Extrapolator(data=self.data) 44 45 # With holding a = -power =445 46 # With holding a = -power =4 46 47 p, dp = fit.fit(power=-4) 47 48 … … 49 50 self.assertAlmostEquals(p[0], 4) 50 51 self.assertAlmostEquals(p[1], -4.0676,3) 51 52 53 52 54 class TestLineFitNoweight(unittest.TestCase): 53 55 """ … … 55 57 """ 56 58 def setUp(self): 57 self.data = Loader().load("linefittest_no_weight.txt") 58 59 self.data_list = Loader().load("linefittest_no_weight.txt") 60 self.data = self.data_list[0] 61 59 62 def skip_test_fit_line_data_no_weight(self): 60 63 """ 61 64 Fit_Test_1: test linear fit, ax +b, without fixed 62 65 """ 63 66 64 67 # Create invariant object. Background and scale left as defaults. 65 68 fit = invariant.Extrapolator(data=self.data) 66 67 # #Without holding69 70 # Without holding 68 71 p, dp = fit.fit(power=None) 69 72 … … 71 74 self.assertAlmostEquals(p[0], 2.4727,3) 72 75 self.assertAlmostEquals(p[1], 0.6,3) 73 74 76 75 77 def test_fit_line_data_fixed_no_weight(self): … … 77 79 Fit_Test_2: test linear fit, ax +b, with 'a' fixed 78 80 """ 79 81 80 82 # Create invariant object. Background and scale left as defaults. 81 83 fit = invariant.Extrapolator(data=self.data) 82 84 83 85 #With holding a = -power =4 84 86 p, dp = fit.fit(power=-4) … … 87 89 self.assertAlmostEquals(p[0], 4) 88 90 self.assertAlmostEquals(p[1], -7.8,3) 89 91 92 90 93 class TestInvPolySphere(unittest.TestCase): 91 94 """ … … 93 96 """ 94 97 def setUp(self): 95 self.data = Loader().load("PolySpheres.txt") 96 98 self.data_list = Loader().load("PolySpheres.txt") 99 self.data = self.data_list[0] 100 97 101 def test_wrong_data(self): 98 102 """ test receiving Data1D not of type loader""" 99 100 101 103 self.assertRaises(ValueError,invariant.InvariantCalculator, Data1D()) 102 104 103 105 def test_use_case_1(self): 104 106 """ … … 107 109 # Create invariant object. Background and scale left as defaults. 108 110 inv = invariant.InvariantCalculator(data=self.data) 109 111 110 112 # We have to be able to tell the InvariantCalculator whether we want the 111 113 # extrapolation or not. By default, when the user doesn't specify, we 112 # should compute Q* without extrapolation. That's what should be done in __init__. 113 114 # should compute Q* without extrapolation. That's what should be done 115 # in __init__. 116 114 117 # We call get_qstar() with no argument, which signifies that we do NOT 115 118 # want extrapolation. 116 119 qstar = inv.get_qstar() 117 120 118 121 # The volume fraction and surface use Q*. That means that the following 119 122 # methods should check that Q* has been computed. If not, it should … … 121 124 v, dv = inv.get_volume_fraction_with_error(contrast=2.6e-6) 122 125 s, ds = inv.get_surface_with_error(contrast=2.6e-6, porod_const=2) 123 126 124 127 # Test results 125 128 self.assertAlmostEquals(qstar, 7.48959e-5,2) 126 129 self.assertAlmostEquals(v, 0.005644689, 4) 127 130 self.assertAlmostEquals(s , 941.7452, 3) 128 131 129 132 def test_use_case_2(self): 130 133 """ 131 132 133 """ 134 # Create invariant object. Background and scale left as defaults. 135 inv = invariant.InvariantCalculator(data=self.data) 136 134 Invariant without extrapolation. Invariant, volume fraction and surface 135 are given with errors. 136 """ 137 # Create invariant object. Background and scale left as defaults. 138 inv = invariant.InvariantCalculator(data=self.data) 139 137 140 # Get the invariant with errors 138 141 qstar, qstar_err = inv.get_qstar_with_error() 139 142 140 143 # The volume fraction and surface use Q*. That means that the following 141 144 # methods should check that Q* has been computed. If not, it should … … 147 150 self.assertAlmostEquals(v, 0.005644689, 1) 148 151 self.assertAlmostEquals(s , 941.7452, 3) 149 150 152 151 153 def test_use_case_3(self): 152 154 """ … … 155 157 # Create invariant object. Background and scale left as defaults. 156 158 inv = invariant.InvariantCalculator(data=self.data) 157 159 158 160 # Set the extrapolation parameters for the low-Q range 159 161 160 162 # The npts parameter should have a good default. 161 163 # The range parameter should be 'high' or 'low' 162 164 # The function parameter should default to None. If it is None, 163 # the method should pick a good default (Guinier at low-Q and 1/q^4 at high-Q). 164 # The method should also check for consistency of the extrapolation and function 165 # parameters. For instance, you might not want to allow 'high' and 'guinier'. 165 # the method should pick a good default 166 # (Guinier at low-Q and 1/q^4 at high-Q). 167 # The method should also check for consistency of the extrapolation 168 # and function parameters. For instance, you might not want to allow 169 # 'high' and 'guinier'. 166 170 # The power parameter (not shown below) should default to 4. 167 171 inv.set_extrapolation(range='low', npts=10, function='guinier') 168 169 # The version of the call without error 170 # At this point, we could still compute Q* without extrapolation by calling171 # get_qstar with arguments, or with extrapolation=None.172 173 # The version of the call without error 174 # At this point, we could still compute Q* without extrapolation by 175 # calling get_qstar with arguments, or with extrapolation=None. 172 176 qstar = inv.get_qstar(extrapolation='low') 173 177 174 178 # The version of the call with error 175 179 qstar, qstar_err = inv.get_qstar_with_error(extrapolation='low') … … 178 182 v, dv = inv.get_volume_fraction_with_error(contrast=2.6e-6) 179 183 s, ds = inv.get_surface_with_error(contrast=2.6e-6, porod_const=2) 180 184 181 185 # Test results 182 186 self.assertAlmostEquals(qstar, 7.49e-5, 1) 183 187 self.assertAlmostEquals(v, 0.005648401, 4) 184 188 self.assertAlmostEquals(s , 941.7452, 3) 185 189 186 190 def test_use_case_4(self): 187 191 """ … … 190 194 # Create invariant object. Background and scale left as defaults. 191 195 inv = invariant.InvariantCalculator(data=self.data) 196 197 # Set the extrapolation parameters for the high-Q range 198 inv.set_extrapolation(range='high', npts=10, function='power_law', 199 power=4) 192 200 193 # Set the extrapolation parameters for the high-Q range 194 inv.set_extrapolation(range='high', npts=10, function='power_law', power=4) 195 196 # The version of the call without error 197 # The function parameter defaults to None, then is picked to be 'power_law' for extrapolation='high' 201 # The version of the call without error 202 # The function parameter defaults to None, then is picked to be 203 # 'power_law' for extrapolation='high' 198 204 qstar = inv.get_qstar(extrapolation='high') 199 205 200 206 # The version of the call with error 201 207 qstar, qstar_err = inv.get_qstar_with_error(extrapolation='high') … … 204 210 v, dv = inv.get_volume_fraction_with_error(contrast=2.6e-6) 205 211 s, ds = inv.get_surface_with_error(contrast=2.6e-6, porod_const=2) 206 212 207 213 # Test results 208 214 self.assertAlmostEquals(qstar, 7.49e-5,2) 209 215 self.assertAlmostEquals(v, 0.005952674, 3) 210 216 self.assertAlmostEquals(s , 941.7452, 3) 211 217 212 218 def test_use_case_5(self): 213 219 """ … … 216 222 # Create invariant object. Background and scale left as defaults. 217 223 inv = invariant.InvariantCalculator(data=self.data) 218 224 219 225 # Set the extrapolation parameters for the low- and high-Q ranges 220 226 inv.set_extrapolation(range='low', npts=10, function='guinier') 221 inv.set_extrapolation(range='high', npts=10, function='power_law', power=4) 222 223 # The version of the call without error 224 # The function parameter defaults to None, then is picked to be 'power_law' for extrapolation='high' 227 inv.set_extrapolation(range='high', npts=10, function='power_law', 228 power=4) 229 230 # The version of the call without error 231 # The function parameter defaults to None, then is picked to be 232 # 'power_law' for extrapolation='high' 225 233 qstar = inv.get_qstar(extrapolation='both') 226 234 … … 231 239 v, dv = inv.get_volume_fraction_with_error(contrast=2.6e-6) 232 240 s, ds = inv.get_surface_with_error(contrast=2.6e-6, porod_const=2) 233 241 234 242 # Test results 235 243 self.assertAlmostEquals(qstar, 7.88981e-5,2) 236 244 self.assertAlmostEquals(v, 0.005952674, 3) 237 245 self.assertAlmostEquals(s , 941.7452, 3) 238 246 239 247 def test_use_case_6(self): 240 248 """ … … 243 251 # Create invariant object. Background and scale left as defaults. 244 252 inv = invariant.InvariantCalculator(data=self.data) 245 253 246 254 # Set the extrapolation parameters for the high-Q range 247 255 inv.set_extrapolation(range='low', npts=10, function='power_law', power=4) 248 256 249 257 # The version of the call without error 250 258 # The function parameter defaults to None, then is picked to be 'power_law' for extrapolation='high' 251 259 qstar = inv.get_qstar(extrapolation='low') 252 260 253 261 # The version of the call with error 254 262 qstar, qstar_err = inv.get_qstar_with_error(extrapolation='low') … … 257 265 v, dv = inv.get_volume_fraction_with_error(contrast=2.6e-6) 258 266 s, ds = inv.get_surface_with_error(contrast=2.6e-6, porod_const=2) 259 267 260 268 # Test results 261 269 self.assertAlmostEquals(qstar, 7.49e-5,2) 262 270 self.assertAlmostEquals(v, 0.005952674, 3) 263 271 self.assertAlmostEquals(s , 941.7452, 3) 264 272 273 265 274 class TestInvPinholeSmear(unittest.TestCase): 266 275 """ … … 271 280 list = Loader().load("latex_smeared.xml") 272 281 self.data_q_smear = list[0] 273 282 274 283 def test_use_case_1(self): 275 284 """ … … 278 287 inv = invariant.InvariantCalculator(data=self.data_q_smear) 279 288 qstar = inv.get_qstar() 280 289 281 290 v = inv.get_volume_fraction(contrast=2.6e-6) 282 291 s = inv.get_surface(contrast=2.6e-6, porod_const=2) … … 285 294 self.assertAlmostEquals(v, 0.115352622, 2) 286 295 self.assertAlmostEquals(s , 941.7452, 3 ) 287 296 288 297 def test_use_case_2(self): 289 298 """ … … 293 302 # Create invariant object. Background and scale left as defaults. 294 303 inv = invariant.InvariantCalculator(data=self.data_q_smear) 295 304 296 305 # Get the invariant with errors 297 306 qstar, qstar_err = inv.get_qstar_with_error() … … 303 312 self.assertAlmostEquals(v, 0.115352622, 2) 304 313 self.assertAlmostEquals(s , 941.7452, 3 ) 305 314 306 315 def test_use_case_3(self): 307 316 """ … … 319 328 v, dv = inv.get_volume_fraction_with_error(contrast=2.6e-6) 320 329 s, ds = inv.get_surface_with_error(contrast=2.6e-6, porod_const=2) 321 330 322 331 # Test results 323 332 self.assertAlmostEquals(qstar, 0.00138756,2) 324 333 self.assertAlmostEquals(v, 0.117226896,2) 325 334 self.assertAlmostEquals(s ,941.7452, 3) 326 335 327 336 def test_use_case_4(self): 328 337 """ … … 337 346 # The version of the call with error 338 347 qstar, qstar_err = inv.get_qstar_with_error(extrapolation='high') 339 340 # Get the volume fraction and surface341 # WHY SHOULD THIS FAIL?342 #self.assertRaises(RuntimeError, inv.get_volume_fraction_with_error, 2.6e-6)343 344 # Check that an exception is raised when the 'surface' is not defined345 # WHY SHOULD THIS FAIL?346 #self.assertRaises(RuntimeError, inv.get_surface_with_error, 2.6e-6, 2)347 348 348 349 # Test results 349 350 self.assertAlmostEquals(qstar, 0.0045773,2) 350 351 351 352 def test_use_case_5(self): 352 353 """ … … 357 358 # Set the extrapolation parameters for the low- and high-Q ranges 358 359 inv.set_extrapolation(range='low', npts=10, function='guinier') 359 inv.set_extrapolation(range='high', npts=10, function='power_law', power=4) 360 # The version of the call without error 361 # The function parameter defaults to None, then is picked to be 'power_law' for extrapolation='high' 360 inv.set_extrapolation(range='high', npts=10, function='power_law', 361 power=4) 362 # The version of the call without error 363 # The function parameter defaults to None, then is picked to be 364 # 'power_law' for extrapolation='high' 362 365 qstar = inv.get_qstar(extrapolation='both') 363 366 # The version of the call with error 364 367 qstar, qstar_err = inv.get_qstar_with_error(extrapolation='both') 365 366 # Get the volume fraction and surface 367 # WHY SHOULD THIS FAIL? 368 #self.assertRaises(RuntimeError, inv.get_volume_fraction_with_error, 2.6e-6) 369 #self.assertRaises(RuntimeError, inv.get_surface_with_error, 2.6e-6, 2) 370 368 371 369 # Test results 372 370 self.assertAlmostEquals(qstar, 0.00460319,3)
Note: See TracChangeset
for help on using the changeset viewer.