- Timestamp:
- Jun 21, 2018 2:04:35 PM (7 years ago)
- Branches:
- master, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, unittest-saveload
- Children:
- 3bab401
- Parents:
- 316b9c1 (diff), 6bd4235 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - Location:
- src/sas
- Files:
-
- 19 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py
r61f329f0 r18af6d2 38 38 # CanSAS version 39 39 cansas_version = 2.0 40 # Logged warnings or messages41 logging = None42 # List of errors for the current data set43 errors = None44 # Raw file contents to be processed45 raw_data = None46 # List of plottable1D objects that should be linked to the current_datainfo47 data1d = None48 # List of plottable2D objects that should be linked to the current_datainfo49 data2d = None50 40 # Data type name 51 41 type_name = "CanSAS 2.0" … … 111 101 self.errors = set() 112 102 self.logging = [] 103 self.q_name = [] 104 self.mask_name = u'' 105 self.i_name = u'' 106 self.i_node = u'' 107 self.q_uncertainties = u'' 108 self.q_resolutions = u'' 109 self.i_uncertainties = u'' 113 110 self.parent_class = u'' 114 111 self.detector = Detector() … … 147 144 self.add_data_set(key) 148 145 elif class_prog.match(u'SASdata'): 146 self._find_data_attributes(value) 149 147 self._initialize_new_data_set(parent_list) 150 148 # Recursion step to access data within the group … … 159 157 data_set = data[key][:] 160 158 unit = self._get_unit(value) 161 162 # I and Q Data163 if key == u'I':164 if isinstance(self.current_dataset, plottable_2D):165 self.current_dataset.data = data_set166 self.current_dataset.zaxis("Intensity", unit)167 else:168 self.current_dataset.y = data_set.flatten()169 self.current_dataset.yaxis("Intensity", unit)170 continue171 elif key == u'Idev':172 if isinstance(self.current_dataset, plottable_2D):173 self.current_dataset.err_data = data_set.flatten()174 else:175 self.current_dataset.dy = data_set.flatten()176 continue177 elif key == u'Q':178 self.current_dataset.xaxis("Q", unit)179 if isinstance(self.current_dataset, plottable_2D):180 self.current_dataset.q = data_set.flatten()181 else:182 self.current_dataset.x = data_set.flatten()183 continue184 elif key == u'Qdev':185 self.current_dataset.dx = data_set.flatten()186 continue187 elif key == u'dQw':188 self.current_dataset.dxw = data_set.flatten()189 continue190 elif key == u'dQl':191 self.current_dataset.dxl = data_set.flatten()192 continue193 elif key == u'Qy':194 self.current_dataset.yaxis("Q_y", unit)195 self.current_dataset.qy_data = data_set.flatten()196 continue197 elif key == u'Qydev':198 self.current_dataset.dqy_data = data_set.flatten()199 continue200 elif key == u'Qx':201 self.current_dataset.xaxis("Q_x", unit)202 self.current_dataset.qx_data = data_set.flatten()203 continue204 elif key == u'Qxdev':205 self.current_dataset.dqx_data = data_set.flatten()206 continue207 elif key == u'Mask':208 self.current_dataset.mask = data_set.flatten()209 continue210 # Transmission Spectrum211 elif (key == u'T'212 and self.parent_class == u'SAStransmission_spectrum'):213 self.trans_spectrum.transmission = data_set.flatten()214 continue215 elif (key == u'Tdev'216 and self.parent_class == u'SAStransmission_spectrum'):217 self.trans_spectrum.transmission_deviation = \218 data_set.flatten()219 continue220 elif (key == u'lambda'221 and self.parent_class == u'SAStransmission_spectrum'):222 self.trans_spectrum.wavelength = data_set.flatten()223 continue224 159 225 160 for data_point in data_set: … … 232 167 if key == u'definition': 233 168 self.current_datainfo.meta_data['reader'] = data_point 169 # Run 234 170 elif key == u'run': 235 171 self.current_datainfo.run.append(data_point) … … 240 176 except Exception: 241 177 pass 178 # Title 242 179 elif key == u'title': 243 180 self.current_datainfo.title = data_point 181 # Note 244 182 elif key == u'SASnote': 245 183 self.current_datainfo.notes.append(data_point) 246 247 184 # Sample Information 248 # CanSAS 2.0 format 249 elif key == u'Title' and self.parent_class == u'SASsample': 250 self.current_datainfo.sample.name = data_point 251 # NXcanSAS format 252 elif key == u'name' and self.parent_class == u'SASsample': 253 self.current_datainfo.sample.name = data_point 254 # NXcanSAS format 255 elif key == u'ID' and self.parent_class == u'SASsample': 256 self.current_datainfo.sample.name = data_point 257 elif (key == u'thickness' 258 and self.parent_class == u'SASsample'): 259 self.current_datainfo.sample.thickness = data_point 260 elif (key == u'temperature' 261 and self.parent_class == u'SASsample'): 262 self.current_datainfo.sample.temperature = data_point 263 elif (key == u'transmission' 264 and self.parent_class == u'SASsample'): 265 self.current_datainfo.sample.transmission = data_point 266 elif (key == u'x_position' 267 and self.parent_class == u'SASsample'): 268 self.current_datainfo.sample.position.x = data_point 269 elif (key == u'y_position' 270 and self.parent_class == u'SASsample'): 271 self.current_datainfo.sample.position.y = data_point 272 elif key == u'pitch' and self.parent_class == u'SASsample': 273 self.current_datainfo.sample.orientation.x = data_point 274 elif key == u'yaw' and self.parent_class == u'SASsample': 275 self.current_datainfo.sample.orientation.y = data_point 276 elif key == u'roll' and self.parent_class == u'SASsample': 277 self.current_datainfo.sample.orientation.z = data_point 278 elif (key == u'details' 279 and self.parent_class == u'SASsample'): 280 self.current_datainfo.sample.details.append(data_point) 281 185 elif self.parent_class == u'SASsample': 186 self.process_sample(data_point, key) 282 187 # Instrumental Information 283 188 elif (key == u'name' 284 189 and self.parent_class == u'SASinstrument'): 285 190 self.current_datainfo.instrument = data_point 286 elif key == u'name' and self.parent_class == u'SASdetector': 287 self.detector.name = data_point 288 elif key == u'SDD' and self.parent_class == u'SASdetector': 289 self.detector.distance = float(data_point) 290 self.detector.distance_unit = unit 291 elif (key == u'slit_length' 292 and self.parent_class == u'SASdetector'): 293 self.detector.slit_length = float(data_point) 294 self.detector.slit_length_unit = unit 295 elif (key == u'x_position' 296 and self.parent_class == u'SASdetector'): 297 self.detector.offset.x = float(data_point) 298 self.detector.offset_unit = unit 299 elif (key == u'y_position' 300 and self.parent_class == u'SASdetector'): 301 self.detector.offset.y = float(data_point) 302 self.detector.offset_unit = unit 303 elif (key == u'pitch' 304 and self.parent_class == u'SASdetector'): 305 self.detector.orientation.x = float(data_point) 306 self.detector.orientation_unit = unit 307 elif key == u'roll' and self.parent_class == u'SASdetector': 308 self.detector.orientation.z = float(data_point) 309 self.detector.orientation_unit = unit 310 elif key == u'yaw' and self.parent_class == u'SASdetector': 311 self.detector.orientation.y = float(data_point) 312 self.detector.orientation_unit = unit 313 elif (key == u'beam_center_x' 314 and self.parent_class == u'SASdetector'): 315 self.detector.beam_center.x = float(data_point) 316 self.detector.beam_center_unit = unit 317 elif (key == u'beam_center_y' 318 and self.parent_class == u'SASdetector'): 319 self.detector.beam_center.y = float(data_point) 320 self.detector.beam_center_unit = unit 321 elif (key == u'x_pixel_size' 322 and self.parent_class == u'SASdetector'): 323 self.detector.pixel_size.x = float(data_point) 324 self.detector.pixel_size_unit = unit 325 elif (key == u'y_pixel_size' 326 and self.parent_class == u'SASdetector'): 327 self.detector.pixel_size.y = float(data_point) 328 self.detector.pixel_size_unit = unit 329 elif (key == u'distance' 330 and self.parent_class == u'SAScollimation'): 331 self.collimation.length = data_point 332 self.collimation.length_unit = unit 333 elif (key == u'name' 334 and self.parent_class == u'SAScollimation'): 335 self.collimation.name = data_point 336 elif (key == u'shape' 337 and self.parent_class == u'SASaperture'): 338 self.aperture.shape = data_point 339 elif (key == u'x_gap' 340 and self.parent_class == u'SASaperture'): 341 self.aperture.size.x = data_point 342 elif (key == u'y_gap' 343 and self.parent_class == u'SASaperture'): 344 self.aperture.size.y = data_point 345 191 # Detector 192 elif self.parent_class == u'SASdetector': 193 self.process_detector(data_point, key, unit) 194 # Collimation 195 elif self.parent_class == u'SAScollimation': 196 self.process_collimation(data_point, key, unit) 197 # Aperture 198 elif self.parent_class == u'SASaperture': 199 self.process_aperture(data_point, key) 346 200 # Process Information 347 elif (key == u'Title' 348 and self.parent_class == u'SASprocess'): # CanSAS 2.0 349 self.process.name = data_point 350 elif (key == u'name' 351 and self.parent_class == u'SASprocess'): # NXcanSAS 352 self.process.name = data_point 353 elif (key == u'description' 354 and self.parent_class == u'SASprocess'): 355 self.process.description = data_point 356 elif key == u'date' and self.parent_class == u'SASprocess': 357 self.process.date = data_point 358 elif key == u'term' and self.parent_class == u'SASprocess': 359 self.process.term = data_point 360 elif self.parent_class == u'SASprocess': 361 self.process.notes.append(data_point) 362 201 elif self.parent_class == u'SASprocess': # CanSAS 2.0 202 self.process_process(data_point, key) 363 203 # Source 364 elif (key == u'wavelength' 365 and self.parent_class == u'SASdata'): 366 self.current_datainfo.source.wavelength = data_point 367 self.current_datainfo.source.wavelength_unit = unit 368 elif (key == u'incident_wavelength' 369 and self.parent_class == 'SASsource'): 370 self.current_datainfo.source.wavelength = data_point 371 self.current_datainfo.source.wavelength_unit = unit 372 elif (key == u'wavelength_max' 373 and self.parent_class == u'SASsource'): 374 self.current_datainfo.source.wavelength_max = data_point 375 self.current_datainfo.source.wavelength_max_unit = unit 376 elif (key == u'wavelength_min' 377 and self.parent_class == u'SASsource'): 378 self.current_datainfo.source.wavelength_min = data_point 379 self.current_datainfo.source.wavelength_min_unit = unit 380 elif (key == u'incident_wavelength_spread' 381 and self.parent_class == u'SASsource'): 382 self.current_datainfo.source.wavelength_spread = \ 383 data_point 384 self.current_datainfo.source.wavelength_spread_unit = \ 385 unit 386 elif (key == u'beam_size_x' 387 and self.parent_class == u'SASsource'): 388 self.current_datainfo.source.beam_size.x = data_point 389 self.current_datainfo.source.beam_size_unit = unit 390 elif (key == u'beam_size_y' 391 and self.parent_class == u'SASsource'): 392 self.current_datainfo.source.beam_size.y = data_point 393 self.current_datainfo.source.beam_size_unit = unit 394 elif (key == u'beam_shape' 395 and self.parent_class == u'SASsource'): 396 self.current_datainfo.source.beam_shape = data_point 397 elif (key == u'radiation' 398 and self.parent_class == u'SASsource'): 399 self.current_datainfo.source.radiation = data_point 400 elif (key == u'transmission' 401 and self.parent_class == u'SASdata'): 402 self.current_datainfo.sample.transmission = data_point 403 204 elif self.parent_class == u'SASsource': 205 self.process_source(data_point, key, unit) 404 206 # Everything else goes in meta_data 207 elif self.parent_class == u'SASdata': 208 self.process_data_object(data_set, key, unit) 209 break 210 elif self.parent_class == u'SAStransmission_spectrum': 211 self.process_trans_spectrum(data_set, key) 212 break 405 213 else: 406 214 new_key = self._create_unique_key( … … 411 219 # I don't know if this reachable code 412 220 self.errors.add("ShouldNeverHappenException") 221 222 def process_data_object(self, data_set, key, unit): 223 """ 224 SASdata processor method 225 :param data_set: data from HDF5 file 226 :param key: canSAS_class attribute 227 :param unit: unit attribute 228 """ 229 if key == self.i_name: 230 if isinstance(self.current_dataset, plottable_2D): 231 self.current_dataset.data = data_set 232 self.current_dataset.zaxis("Intensity", unit) 233 else: 234 self.current_dataset.y = data_set.flatten() 235 self.current_dataset.yaxis("Intensity", unit) 236 elif key == self.i_uncertainties: 237 if isinstance(self.current_dataset, plottable_2D): 238 self.current_dataset.err_data = data_set.flatten() 239 else: 240 self.current_dataset.dy = data_set.flatten() 241 elif key in self.q_name: 242 self.current_dataset.xaxis("Q", unit) 243 if isinstance(self.current_dataset, plottable_2D): 244 self.current_dataset.q = data_set.flatten() 245 else: 246 self.current_dataset.x = data_set.flatten() 247 elif key in self.q_resolutions: 248 if key == u'dQw': 249 self.current_dataset.dxw = data_set.flatten() 250 elif key == u'dQl': 251 self.current_dataset.dxl = data_set.flatten() 252 else: 253 self.current_dataset.dx = data_set.flatten() 254 elif key == u'Qy': 255 self.current_dataset.yaxis("Q_y", unit) 256 self.current_dataset.qy_data = data_set.flatten() 257 elif key == u'Qydev': 258 self.current_dataset.dqy_data = data_set.flatten() 259 elif key == u'Qx': 260 self.current_dataset.xaxis("Q_x", unit) 261 self.current_dataset.qx_data = data_set.flatten() 262 elif key == u'Qxdev': 263 self.current_dataset.dqx_data = data_set.flatten() 264 elif key == self.mask_name: 265 self.current_dataset.mask = data_set.flatten() 266 elif key == u'wavelength': 267 self.current_datainfo.source.wavelength = data_set[0] 268 self.current_datainfo.source.wavelength_unit = unit 269 270 def process_trans_spectrum(self, data_set, key): 271 """ 272 SAStransmission_spectrum processor 273 :param data_set: data from HDF5 file 274 :param key: canSAS_class attribute 275 """ 276 if key == u'T': 277 self.trans_spectrum.transmission = data_set.flatten() 278 elif key == u'Tdev': 279 self.trans_spectrum.transmission_deviation = data_set.flatten() 280 elif key == u'lambda': 281 self.trans_spectrum.wavelength = data_set.flatten() 282 283 def process_sample(self, data_point, key): 284 """ 285 SASsample processor 286 :param data_point: Single point from an HDF5 data file 287 :param key: class name data_point was taken from 288 """ 289 if key == u'Title': 290 self.current_datainfo.sample.name = data_point 291 elif key == u'name': 292 self.current_datainfo.sample.name = data_point 293 elif key == u'ID': 294 self.current_datainfo.sample.name = data_point 295 elif key == u'thickness': 296 self.current_datainfo.sample.thickness = data_point 297 elif key == u'temperature': 298 self.current_datainfo.sample.temperature = data_point 299 elif key == u'transmission': 300 self.current_datainfo.sample.transmission = data_point 301 elif key == u'x_position': 302 self.current_datainfo.sample.position.x = data_point 303 elif key == u'y_position': 304 self.current_datainfo.sample.position.y = data_point 305 elif key == u'pitch': 306 self.current_datainfo.sample.orientation.x = data_point 307 elif key == u'yaw': 308 self.current_datainfo.sample.orientation.y = data_point 309 elif key == u'roll': 310 self.current_datainfo.sample.orientation.z = data_point 311 elif key == u'details': 312 self.current_datainfo.sample.details.append(data_point) 313 314 def process_detector(self, data_point, key, unit): 315 """ 316 SASdetector processor 317 :param data_point: Single point from an HDF5 data file 318 :param key: class name data_point was taken from 319 :param unit: unit attribute from data set 320 """ 321 if key == u'name': 322 self.detector.name = data_point 323 elif key == u'SDD': 324 self.detector.distance = float(data_point) 325 self.detector.distance_unit = unit 326 elif key == u'slit_length': 327 self.detector.slit_length = float(data_point) 328 self.detector.slit_length_unit = unit 329 elif key == u'x_position': 330 self.detector.offset.x = float(data_point) 331 self.detector.offset_unit = unit 332 elif key == u'y_position': 333 self.detector.offset.y = float(data_point) 334 self.detector.offset_unit = unit 335 elif key == u'pitch': 336 self.detector.orientation.x = float(data_point) 337 self.detector.orientation_unit = unit 338 elif key == u'roll': 339 self.detector.orientation.z = float(data_point) 340 self.detector.orientation_unit = unit 341 elif key == u'yaw': 342 self.detector.orientation.y = float(data_point) 343 self.detector.orientation_unit = unit 344 elif key == u'beam_center_x': 345 self.detector.beam_center.x = float(data_point) 346 self.detector.beam_center_unit = unit 347 elif key == u'beam_center_y': 348 self.detector.beam_center.y = float(data_point) 349 self.detector.beam_center_unit = unit 350 elif key == u'x_pixel_size': 351 self.detector.pixel_size.x = float(data_point) 352 self.detector.pixel_size_unit = unit 353 elif key == u'y_pixel_size': 354 self.detector.pixel_size.y = float(data_point) 355 self.detector.pixel_size_unit = unit 356 357 def process_collimation(self, data_point, key, unit): 358 """ 359 SAScollimation processor 360 :param data_point: Single point from an HDF5 data file 361 :param key: class name data_point was taken from 362 :param unit: unit attribute from data set 363 """ 364 if key == u'distance': 365 self.collimation.length = data_point 366 self.collimation.length_unit = unit 367 elif key == u'name': 368 self.collimation.name = data_point 369 370 def process_aperture(self, data_point, key): 371 """ 372 SASaperture processor 373 :param data_point: Single point from an HDF5 data file 374 :param key: class name data_point was taken from 375 """ 376 if key == u'shape': 377 self.aperture.shape = data_point 378 elif key == u'x_gap': 379 self.aperture.size.x = data_point 380 elif key == u'y_gap': 381 self.aperture.size.y = data_point 382 383 def process_source(self, data_point, key, unit): 384 """ 385 SASsource processor 386 :param data_point: Single point from an HDF5 data file 387 :param key: class name data_point was taken from 388 :param unit: unit attribute from data set 389 """ 390 if key == u'incident_wavelength': 391 self.current_datainfo.source.wavelength = data_point 392 self.current_datainfo.source.wavelength_unit = unit 393 elif key == u'wavelength_max': 394 self.current_datainfo.source.wavelength_max = data_point 395 self.current_datainfo.source.wavelength_max_unit = unit 396 elif key == u'wavelength_min': 397 self.current_datainfo.source.wavelength_min = data_point 398 self.current_datainfo.source.wavelength_min_unit = unit 399 elif key == u'incident_wavelength_spread': 400 self.current_datainfo.source.wavelength_spread = data_point 401 self.current_datainfo.source.wavelength_spread_unit = unit 402 elif key == u'beam_size_x': 403 self.current_datainfo.source.beam_size.x = data_point 404 self.current_datainfo.source.beam_size_unit = unit 405 elif key == u'beam_size_y': 406 self.current_datainfo.source.beam_size.y = data_point 407 self.current_datainfo.source.beam_size_unit = unit 408 elif key == u'beam_shape': 409 self.current_datainfo.source.beam_shape = data_point 410 elif key == u'radiation': 411 self.current_datainfo.source.radiation = data_point 412 413 def process_process(self, data_point, key): 414 """ 415 SASprocess processor 416 :param data_point: Single point from an HDF5 data file 417 :param key: class name data_point was taken from 418 """ 419 if key == u'Title': # CanSAS 2.0 420 self.process.name = data_point 421 elif key == u'name': # NXcanSAS 422 self.process.name = data_point 423 elif key == u'description': 424 self.process.description = data_point 425 elif key == u'date': 426 self.process.date = data_point 427 elif key == u'term': 428 self.process.term = data_point 429 else: 430 self.process.notes.append(data_point) 413 431 414 432 def add_intermediate(self): … … 515 533 self.current_datainfo = DataInfo() 516 534 517 518 535 def _initialize_new_data_set(self, parent_list=None): 519 536 """ … … 534 551 self.current_dataset = plottable_1D(x, y) 535 552 self.current_datainfo.filename = self.raw_data.filename 553 self.mask_name = "" 554 self.i_name = "" 555 self.i_node = "" 556 self.q_name = [] 557 self.q_uncertainties = "" 558 self.q_resolutions = "" 559 self.i_uncertainties = "" 560 561 def _find_data_attributes(self, value): 562 """ 563 A class to find the indices for Q, the name of the Qdev and Idev, and 564 the name of the mask. 565 :param value: SASdata/NXdata HDF5 Group 566 """ 567 attrs = value.attrs 568 signal = attrs.get("signal") 569 i_axes = np.array(str(attrs.get("I_axes")).split(",")) 570 q_indices = np.int_(attrs.get("Q_indices").split(",")) 571 keys = value.keys() 572 self.mask_name = attrs.get("mask") 573 for val in q_indices: 574 self.q_name.append(i_axes[val]) 575 self.i_name = signal 576 self.i_node = value.get(self.i_name) 577 for item in self.q_name: 578 if item in keys: 579 q_vals = value.get(item) 580 self.q_uncertainties = q_vals.attrs.get("uncertainty") 581 self.q_resolutions = q_vals.attrs.get("resolution") 582 if self.i_name in keys: 583 i_vals = value.get(self.i_name) 584 self.i_uncertainties = i_vals.attrs.get("uncertainty") 536 585 537 586 def _find_intermediate(self, parent_list, basename=""): -
src/sas/sascalc/dataloader/file_reader_base_class.py
ra58b5a0 r4a8d55c 31 31 FIELDS_2D = ('data', 'qx_data', 'qy_data', 'q_data', 'err_data', 32 32 'dqx_data', 'dqy_data', 'mask') 33 33 DEPRECATION_MESSAGE = ("\rThe extension of this file suggests the data set migh" 34 "t not be fully reduced. Support for the reader associat" 35 "ed with this file type has been removed. An attempt to " 36 "load the file was made, but, should it be successful, " 37 "SasView cannot guarantee the accuracy of the data.") 34 38 35 39 class FileReader(object): … … 40 44 # List of allowed extensions 41 45 ext = ['.txt'] 46 # Deprecated extensions 47 deprecated_extensions = ['.asc', '.nxs'] 42 48 # Bypass extension check and try to load anyway 43 49 allow_all = False … … 87 93 if not self.f_open.closed: 88 94 self.f_open.close() 95 if any(filepath.lower().endswith(ext) for ext in 96 self.deprecated_extensions): 97 self.handle_error_message(DEPRECATION_MESSAGE) 89 98 if len(self.output) > 0: 90 99 # Sort the data that's been loaded … … 146 155 else: 147 156 logger.warning(msg) 157 raise NoKnownLoaderException(msg) 148 158 149 159 def send_to_output(self): -
src/sas/sascalc/dataloader/loader.py
rdc8d1c2 r4a8d55c 90 90 ascii_loader = ascii_reader.Reader() 91 91 return ascii_loader.read(path) 92 except NoKnownLoaderException: 93 pass # Try the Cansas XML reader 92 94 except DefaultReaderException: 93 95 pass # Loader specific error to try the cansas XML reader … … 100 102 cansas_loader = cansas_reader.Reader() 101 103 return cansas_loader.read(path) 104 except NoKnownLoaderException: 105 pass # Try the NXcanSAS reader 102 106 except DefaultReaderException: 103 107 pass # Loader specific error to try the NXcanSAS reader -
src/sas/sascalc/fit/pagestate.py
r9e6aeaf r3b070a0 646 646 name = value.split(':', 1)[1].strip() 647 647 file_value = "File name:" + name 648 #Truncating string so print doesn't complain of being outside margins 649 if sys.platform != "win32": 650 MAX_STRING_LENGHT = 50 651 if len(file_value) > MAX_STRING_LENGHT: 652 file_value = "File name:.."+file_value[-MAX_STRING_LENGHT+10:] 648 653 file_name = CENTRE % file_value 649 654 if len(title) == 0: … … 721 726 html_str, text_str, title = self._get_report_string() 722 727 # Allow 2 figures to append 723 image_links = [FEET_2%fig for fig in fig_urls] 724 728 #Constraining image width for OSX and linux, so print doesn't complain of being outside margins 729 if sys.platform == "win32": 730 image_links = [FEET_2%fig for fig in fig_urls] 731 else: 732 image_links = [FEET_2_unix%fig for fig in fig_urls] 725 733 # final report html strings 726 734 report_str = html_str + ELINE.join(image_links) 727 735 report_str += FEET_3 728 736 return report_str, text_str 729 737 … … 1368 1376 """ 1369 1377 FEET_2 = \ 1370 """<img src="%s" ></img> 1378 """<img src="%s"></img> 1379 """ 1380 FEET_2_unix = \ 1381 """<img src="%s" width="540"></img> 1371 1382 """ 1372 1383 FEET_3 = \ -
src/sas/sasgui/guiframe/local_perspectives/data_loader/data_loader.py
r20fa5fe r2924532 185 185 try: 186 186 message = "Loading {}...\n".format(p_file) 187 self.load_update( output=output,message=message, info="info")187 self.load_update(message=message, info="info") 188 188 temp = self.loader.load(p_file, format) 189 189 if not isinstance(temp, list): … … 201 201 else: 202 202 file_errors[basename] = [error_message] 203 self.load_update(output=output, 204 message=error_message, info="warning") 205 206 self.load_update(output=output, 207 message="Loaded {}\n".format(p_file), 208 info="info") 203 204 self.load_update(message="Loaded {}\n".format(p_file), 205 info="info") 209 206 210 207 except NoKnownLoaderException as e: 211 208 exception_occurred = True 212 logger.error(e.message)213 214 209 error_message = "Loading data failed!\n" + e.message 215 self.load_update(output=None, message=e.message, info="warning") 210 self.load_complete(output=None, 211 message=error_message, 212 info="warning") 216 213 217 214 except Exception as e: 218 215 exception_occurred = True 219 logger.error(e.message)220 221 216 file_err = "The Data file you selected could not be " 222 217 file_err += "loaded.\nMake sure the content of your file" … … 225 220 file_err += " following:\n" 226 221 file_err += e.message 227 file_errors[basename] = [file_err] 222 self.load_complete(output=None, 223 message=file_err, 224 info="error") 228 225 229 226 if len(file_errors) > 0: 230 227 error_message = "" 231 228 for filename, error_array in file_errors.iteritems(): 232 error_message += "The following errors occured whilst "229 error_message += "The following issues were found whilst " 233 230 error_message += "loading {}:\n".format(filename) 234 231 for message in error_array: 235 232 error_message += message + "\n" 236 error_message += "\n" 237 if not exception_occurred: # Some data loaded but with errors 238 self.load_update(output=output, message=error_message, info="error") 239 240 if not exception_occurred: # Everything loaded as expected 233 error_message = error_message[:-1] 234 self.load_complete(output=output, 235 message=error_message, 236 info="error") 237 238 elif not exception_occurred: # Everything loaded as expected 241 239 self.load_complete(output=output, message="Loading data complete!", 242 240 info="info") … … 244 242 self.load_complete(output=None, message=error_message, info="error") 245 243 246 247 def load_update(self, output=None, message="", info="warning"): 244 def load_update(self, message="", info="warning"): 248 245 """ 249 246 print update on the status bar 250 247 """ 251 248 if message != "": 252 wx.PostEvent(self.parent, StatusEvent(status=message, info=info, 249 wx.PostEvent(self.parent, StatusEvent(status=message, 250 info=info, 253 251 type="progress")) 254 252 … … 257 255 post message to status bar and return list of data 258 256 """ 259 wx.PostEvent(self.parent, StatusEvent(status=message, info=info, 257 wx.PostEvent(self.parent, StatusEvent(status=message, 258 info=info, 260 259 type="stop")) 261 260 if output is not None: -
src/sas/sasgui/guiframe/media/data_formats_help.rst
r959eb01 r1eb86a5 28 28 29 29 * .TXT 30 * .ASC31 30 * .DAT 32 31 * .XML (in canSAS format v1.0 and 1.1) 32 * .H5 (as NeXus NXcanSAS only) 33 * .NXS (as NeXus NXcanSAS only) 34 35 .. note:: 36 From SasView version 4.2 onwards files written in the NIST .ASC format are no longer read. This is because that 37 format normally represents *raw* and not reduced data. 33 38 34 39 If using CSV output from, for example, a spreadsheet, ensure that it is not using commas as delimiters for thousands. … … 40 45 41 46 For a description of the ISIS 1D format see: 42 http ://www.isis.stfc.ac.uk/instruments/loq/software/colette-ascii-file-format-descriptions9808.pdf47 https://www.isis.stfc.ac.uk/Pages/colette-ascii-file-format-descriptions.pdf 43 48 44 49 For a description of the NXcanSAS format see: … … 58 63 -------------- 59 64 60 SasView will read ASCII ('text') files in the NIST 2D format (with the extension s .ASC or .DAT) or files in the NeXus NXcanSAS (HDF5) format (with the extension .H5). File extensions are not case-sensitive. Both of these formats are written by the `Mantid Framework <http://www.mantidproject.org/>`_.65 SasView will read ASCII ('text') files in the NIST 2D format (with the extension .DAT) or files in the NeXus NXcanSAS (HDF5) format (with the extension .H5 or .NXS). File extensions are not case-sensitive. Both of these formats are written by the `Mantid Framework <http://www.mantidproject.org/>`_. 61 66 62 67 Most of the header lines in the NIST 2D format can actually be removed except the last line, and only the first three columns (*Qx, Qy,* and *I(Qx,Qy)*) are actually required. 68 69 .. note:: 70 From SasView version 4.2 onwards files written in the NIST .ASC format are no longer read. This is because that 71 format normally represents *raw* and not reduced data. 72 73 .. note:: 74 SasView does not read the standard NeXus format, only the NXcanSAS subset. 63 75 64 76 The SasView :ref:`File_Converter_Tool` available in SasView 4.1 onwards can be used to convert data sets in the 2D BSL/OTOKO format into the NeXus NXcanSAS (HDF5) format. -
src/sas/sasgui/guiframe/report_dialog.py
r69a6897 r91552b5 27 27 class BaseReportDialog(wx.Dialog): 28 28 29 def __init__(self, report_list, *args, **kwds):29 def __init__(self, report_list, imgRAM, fig_urls, *args, **kwds): 30 30 """ 31 31 Initialization. The parameters added to Dialog are: … … 37 37 kwds["image"] = 'Dynamic Image' 38 38 39 #MemoryFSHandle for storing images 40 self.imgRAM = imgRAM 41 #Images location in urls 42 self.fig_urls = fig_urls 39 43 # title 40 44 self.SetTitle("Report") … … 75 79 hbox.Add(button_print) 76 80 77 button_save = wx.Button(self, wx.NewId(), "Save") 78 button_save.SetToolTipString("Save this report.") 79 button_save.Bind(wx.EVT_BUTTON, self.onSave, id=button_save.GetId()) 80 hbox.Add(button_save) 81 if sys.platform != "darwin": 82 button_save = wx.Button(self, wx.NewId(), "Save") 83 button_save.SetToolTipString("Save this report.") 84 button_save.Bind(wx.EVT_BUTTON, self.onSave, id=button_save.GetId()) 85 hbox.Add(button_save) 81 86 82 87 # panel for report page … … 111 116 printh.PrintText(self.report_html) 112 117 118 113 119 def OnClose(self, event=None): 114 120 """ … … 116 122 : event: Close button event 117 123 """ 124 for fig in self.fig_urls: 125 self.imgRAM.RemoveFile(fig) 126 118 127 self.Close() 119 128 -
src/sas/sasgui/perspectives/calculator/calculator.py
r235f514 r61bfd36 86 86 ("Generic Scattering Calculator", 87 87 gensas_help, self.on_gen_model), 88 ("Orientation Viewer", "Show 3-D view of oriented shape", self.on_show_orientation), 88 89 ("Python Shell/Editor", pyconsole_help, self.on_python_console), 89 90 ("Image Viewer", imageviewer_help, self.on_image_viewer), ] … … 190 191 self.gen_frame.Show(False) 191 192 self.gen_frame.Show(True) 193 194 def on_show_orientation(self, event): 195 """ 196 Make sasmodels orientation & jitter viewer available 197 """ 198 from sasmodels.jitter import run 199 run() 192 200 193 201 def on_image_viewer(self, event): -
src/sas/sasgui/perspectives/calculator/media/resolution_calculator_help.rst
r5ed76f8 r3bd58f0 29 29 careful to note that distances are specified in cm! 30 30 31 4) Enter values for the source wavelength(s), $\lambda$, and its spread (= $\ text{FWHM}/\lambda$).31 4) Enter values for the source wavelength(s), $\lambda$, and its spread (= $\mathrm{FWHM}/\lambda$). 32 32 33 33 For monochromatic sources, the inputs are just one value. For TOF sources, … … 58 58 region near the beam block/stop 59 59 60 [i.e., $Q < (2 \pi \cdot \text{beam block diameter}) / (\text{sample-to-detector distance} \cdot \lambda_\text{min})$]60 [i.e., $Q < (2 \pi \cdot w) / (d_s \cdot \lambda_\mathrm{min})$, where $w$ is the beam block diameter, $d_s$ is the sample-to-detector distance, and $\lambda_\mathrm{min}$ is the minimum wavelength.] 61 61 62 62 the variance is slightly under estimated. -
src/sas/sasgui/perspectives/calculator/media/sas_calculator_help.rst
r1b67f3e r55abe4f 88 88 89 89 Now let us assume that the angles of the $\vec Q$ vector and the spin-axis ($x'$) 90 to the $x$-axis are $\phi$ and $\theta_\ text{up}$ respectively (see above). Then,90 to the $x$-axis are $\phi$ and $\theta_\mathrm{up}$ respectively (see above). Then, 91 91 depending upon the polarization (spin) state of neutrons, the scattering 92 92 length densities, including the nuclear scattering length density ($\beta_N$) … … 107 107 .. math:: 108 108 109 M_{\perp x'} &= M_{0q_x}\cos\theta_\ text{up} + M_{0q_y}\sin\theta_\text{up} \\110 M_{\perp y'} &= M_{0q_y}\cos\theta_\ text{up} - M_{0q_x}\sin\theta_\text{up} \\109 M_{\perp x'} &= M_{0q_x}\cos\theta_\mathrm{up} + M_{0q_y}\sin\theta_\mathrm{up} \\ 110 M_{\perp y'} &= M_{0q_y}\cos\theta_\mathrm{up} - M_{0q_x}\sin\theta_\mathrm{up} \\ 111 111 M_{\perp z'} &= M_{0z} \\ 112 112 M_{0q_x} &= (M_{0x}\cos\phi - M_{0y}\sin\phi)\cos\phi \\ -
src/sas/sasgui/perspectives/calculator/model_editor.py
r2469df7 r9258c43c 391 391 self._msg_box.SetLabel(msg) 392 392 self._msg_box.SetForegroundColour(color) 393 self._set_model_list() 393 394 if self.parent.parent is not None: 394 395 from sas.sasgui.guiframe.events import StatusEvent … … 432 433 if len(main_list) > 1: 433 434 main_list.sort() 435 self.model1.Clear() 436 self.model2.Clear() 434 437 for idx in range(len(main_list)): 435 438 self.model1.Append(str(main_list[idx]), idx) … … 660 663 Do the layout for parameter related widgets 661 664 """ 662 param_txt = wx.StaticText(self, -1, 'Fit Parameters NOT requiring' + \ 663 ' polydispersity (if any): ') 664 665 param_tip = "#Set the parameters NOT requiring polydispersity " + \ 666 "and their initial values.\n" 665 param_txt = wx.StaticText(self, -1, 'Fit Parameters: ') 666 667 param_tip = "#Set the parameters and their initial values.\n" 667 668 param_tip += "#Example:\n" 668 669 param_tip += "A = 1\nB = 1" … … 678 679 (self.param_tcl, 1, wx.EXPAND | wx.ALL, 10)]) 679 680 680 # Parameters with polydispersity681 pd_param_txt = wx.StaticText(self, -1, 'Fit Parameters requiring ' + \682 'polydispersity (if any): ')683 684 pd_param_tip = "#Set the parameters requiring polydispersity and " + \685 "their initial values.\n"686 pd_param_tip += "#Example:\n"687 pd_param_tip += "C = 2\nD = 2"688 newid = wx.NewId()689 self.pd_param_tcl = EditWindow(self, newid, wx.DefaultPosition,690 wx.DefaultSize,691 wx.CLIP_CHILDREN | wx.SUNKEN_BORDER)692 self.pd_param_tcl.setDisplayLineNumbers(True)693 self.pd_param_tcl.SetToolTipString(pd_param_tip)694 695 self.param_sizer.AddMany([(pd_param_txt, 0, wx.LEFT, 10),696 (self.pd_param_tcl, 1, wx.EXPAND | wx.ALL, 10)])697 681 698 682 def _layout_function(self): … … 896 880 description = self.desc_tcl.GetValue() 897 881 param_str = self.param_tcl.GetText() 898 pd_param_str = self.pd_param_tcl.GetText()899 882 func_str = self.function_tcl.GetText() 900 883 # No input for the model function … … 902 885 if func_str.count('return') > 0: 903 886 self.write_file(self.fname, name, description, param_str, 904 pd_param_str,func_str)887 func_str) 905 888 try: 906 889 result, msg = check_model(self.fname), None … … 942 925 self.warning = msg 943 926 944 def write_file(self, fname, name, desc_str, param_str, pd_param_str,func_str):927 def write_file(self, fname, name, desc_str, param_str, func_str): 945 928 """ 946 929 Write content in file … … 949 932 :param desc_str: content of the description strings 950 933 :param param_str: content of params; Strings 951 :param pd_param_str: content of params requiring polydispersity; Strings952 934 :param func_str: content of func; Strings 953 935 """ … … 963 945 # Write out parameters 964 946 param_names = [] # to store parameter names 965 pd_params = []966 947 out_f.write('parameters = [ \n') 967 948 out_f.write('# ["name", "units", default, [lower, upper], "type", "description"],\n') … … 970 951 out_f.write(" ['%s', '', %s, [-inf, inf], '', '%s'],\n" 971 952 % (pname, pvalue, desc)) 972 for pname, pvalue, desc in self.get_param_helper(pd_param_str):973 param_names.append(pname)974 pd_params.append(pname)975 out_f.write(" ['%s', '', %s, [-inf, inf], 'volume', '%s'],\n"976 % (pname, pvalue, desc))977 953 out_f.write(' ]\n') 978 954 979 955 # Write out function definition 956 out_f.write('\n') 980 957 out_f.write('def Iq(%s):\n' % ', '.join(['x'] + param_names)) 981 958 out_f.write(' """Absolute scattering"""\n') … … 987 964 out_f.write(' import numpy as np') 988 965 for func_line in func_str.split('\n'): 989 out_f.write('%s%s\n' % ( spaces4, func_line))966 out_f.write('%s%s\n' % (' ', func_line)) 990 967 out_f.write('## uncomment the following if Iq works for vector x\n') 991 968 out_f.write('#Iq.vectorized = True\n') 992 993 # If polydisperse, create place holders for form_volume, ER and VR994 if pd_params:995 out_f.write('\n')996 out_f.write(CUSTOM_TEMPLATE_PD % {'args': ', '.join(pd_params)})997 969 998 970 # Create place holder for Iqxy … … 1125 1097 description = """%(description)s""" 1126 1098 1127 '''1128 1129 CUSTOM_TEMPLATE_PD = '''\1130 def form_volume(%(args)s):1131 """1132 Volume of the particles used to compute absolute scattering intensity1133 and to weight polydisperse parameter contributions.1134 """1135 return 0.01136 1137 def ER(%(args)s):1138 """1139 Effective radius of particles to be used when computing structure factors.1140 1141 Input parameters are vectors ranging over the mesh of polydispersity values.1142 """1143 return 0.01144 1145 def VR(%(args)s):1146 """1147 Volume ratio of particles to be used when computing structure factors.1148 1149 Input parameters are vectors ranging over the mesh of polydispersity values.1150 """1151 return 1.01152 1099 ''' 1153 1100 -
src/sas/sasgui/perspectives/calculator/resolution_calculator_panel.py
r7432acb r1cf490b6 18 18 matplotlib.use('WXAgg') 19 19 from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas 20 from matplotlib.backends.backend_wxagg import NavigationToolbar2Wx as Toolbar20 from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as Toolbar 21 21 from matplotlib.backend_bases import FigureManagerBase 22 22 # Wx-Pylab magic for displaying plots within an application's window. -
src/sas/sasgui/perspectives/corfunc/media/corfunc_help.rst
rad476d1 r501712f 188 188 * Average Hard Block Thickness :math:`= L_c` 189 189 * Average Core Thickness :math:`= D_0` 190 * Average Interface Thickness :math:` \text{}= D_{tr}`191 * Polydispersity :math:`= \Gamma_{\ text{min}}/\Gamma_{\text{max}}`190 * Average Interface Thickness :math:`= D_{tr}` 191 * Polydispersity :math:`= \Gamma_{\mathrm{min}}/\Gamma_{\mathrm{max}}` 192 192 * Local Crystallinity :math:`= L_c/L_p` 193 193 … … 203 203 * Bound Fraction :math:`= <p>` 204 204 * Second Moment :math:`= \sigma` 205 * Maximum Extent :math:`= \delta_{\ text{h}}`205 * Maximum Extent :math:`= \delta_{\mathrm{h}}` 206 206 * Adsorbed Amount :math:`= \Gamma` 207 207 -
src/sas/sasgui/perspectives/file_converter/media/file_converter_help.rst
r59decb81 rfafb396 19 19 or with a comma or semi-colon delimiter 20 20 * 2D `ISIS ASCII formatted 21 <http://www.isis.stfc.ac.uk/instruments/loq/software/ 22 colette-ascii-file-format-descriptions9808.pdf>`_ data 21 <https://www.isis.stfc.ac.uk/Pages/colette-ascii-file-format-descriptions.pdf>`_ data 23 22 * `1D BSL/OTOKO format 24 23 <http://www.diamond.ac.uk/Beamlines/Soft-Condensed-Matter/small-angle/ -
src/sas/sasgui/perspectives/fitting/basepage.py
r58a8f76 rc192960 641 641 # get the strings for report 642 642 report_str, text_str = self.state.report(fig_urls=refs) 643 644 643 # Show the dialog 645 644 report_list = [report_str, text_str, images] 646 dialog = ReportDialog(report_list, None, wx.ID_ANY, "")645 dialog = ReportDialog(report_list, imgRAM, refs, None, wx.ID_ANY, "") 647 646 dialog.Show() 648 647 … … 677 676 refs.append('memory:' + name) 678 677 imgRAM.AddFile(name, canvas.bitmap, wx.BITMAP_TYPE_PNG) 679 680 678 # append figs 681 679 images.append(fig) … … 1367 1365 except Exception: 1368 1366 logger.error(traceback.format_exc()) 1369 selection = self._find_polyfunc_selection(disp_model)1367 index, selection = self._find_polyfunc_selection(disp_model) 1370 1368 for list in self.fittable_param: 1371 1369 if list[1] == key and list[7] is not None: 1372 list[7].SetSelection( selection)1370 list[7].SetSelection(index) 1373 1371 # For the array disp_model, set the values and weights 1374 if selection == 1:1372 if selection == 'array': 1375 1373 disp_model.set_weights(self.values[key], 1376 1374 self.weights[key]) … … 1385 1383 logger.error(traceback.format_exc()) 1386 1384 # For array, disable all fixed params 1387 if selection == 1:1385 if selection == 'array': 1388 1386 for item in self.fixed_param: 1389 1387 if item[1].split(".")[0] == key.split(".")[0]: … … 1472 1470 # we need to check here ourselves. 1473 1471 if not is_modified: 1474 is_modified = (self._check_value_enter(self.fittable_param) 1475 or self._check_value_enter(self.fixed_param) 1476 or self._check_value_enter(self.parameters)) 1472 is_modified = self._check_value_enter(self.fittable_param) 1473 is_modified = self._check_value_enter( 1474 self.fixed_param) or is_modified 1475 is_modified = self._check_value_enter( 1476 self.parameters) or is_modified 1477 1477 1478 1478 # Here we should check whether the boundaries have been modified. … … 1536 1536 data=[self.data]) 1537 1537 # Check the values 1538 is_modified = (self._check_value_enter(self.fittable_param)1539 or self._check_value_enter(self.fixed_param)1540 or self._check_value_enter(self.parameters))1538 is_modified = self._check_value_enter(self.fittable_param) 1539 is_modified = self._check_value_enter(self.fixed_param) or is_modified 1540 is_modified = self._check_value_enter(self.parameters) or is_modified 1541 1541 1542 1542 # If qmin and qmax have been modified, update qmin and qmax and … … 2324 2324 2325 2325 # Update value in model if it has changed 2326 if value != self.model.getParam(name): 2326 if (value != self.model.getParam(name) or 2327 (np.isnan(value) and np.isnan(self.model.getParam(name)))): 2327 2328 self.model.setParam(name, value) 2328 2329 is_modified = True … … 2668 2669 def _find_polyfunc_selection(self, disp_func=None): 2669 2670 """ 2670 F Ind Comboox selection from disp_func2671 Find Combobox selection from disp_func 2671 2672 2672 2673 :param disp_function: dispersion distr. function … … 2675 2676 if disp_func is not None: 2676 2677 try: 2677 return POLYDISPERSITY_MODELS.values().index(disp_func.__class__) 2678 return (list(POLYDISPERSITY_MODELS).index(disp_func.type), 2679 disp_func.type) 2678 2680 except ValueError: 2679 2681 pass # Fall through to default class 2680 return POLYDISPERSITY_MODELS.keys().index('gaussian')2682 return (list(POLYDISPERSITY_MODELS).index('gaussian'), 'gaussian') 2681 2683 2682 2684 def on_reset_clicked(self, event): -
src/sas/sasgui/perspectives/fitting/fitpage.py
rbfeb823 ra7c6f38 365 365 # StaticText for chi2, N(for fitting), Npts + Log/linear spacing 366 366 self.tcChi = BGTextCtrl(self, wx.ID_ANY, "-", size=(75, 20), style=0) 367 self.tcChi.SetToolTipString("Chi2/ Npts(Fit)")367 self.tcChi.SetToolTipString("Chi2/DOF (DOF=Npts-Npar fitted)") 368 368 self.Npts_fit = BGTextCtrl(self, wx.ID_ANY, "-", size=(75, 20), style=0) 369 369 self.Npts_fit.SetToolTipString( … … 391 391 self.points_sizer.Add(self.pointsbox) 392 392 393 box_description_1 = wx.StaticText(self, wx.ID_ANY, ' Chi2/Npts')393 box_description_1 = wx.StaticText(self, wx.ID_ANY, 'Reduced Chi2') 394 394 box_description_2 = wx.StaticText(self, wx.ID_ANY, 'Npts(Fit)') 395 395 -
src/sas/sasgui/perspectives/fitting/media/fitting_help.rst
r5005ae0 r9258c43c 180 180 *checked*\ . 181 181 182 Also note that the 'Fit Parameters' have been split into two sections: those183 which can be polydisperse (shape and orientation parameters) and those which are184 not (eg, scattering length densities).185 186 182 A model file generated by this option can be viewed and further modified using 187 183 the :ref:`Advanced_Plugin_Editor` . 188 184 189 **SasView version 4.2** made it possible to specify whether a plugin created with 190 the *New Plugin Model* dialog is actually a form factor P(Q) or a structure factor 191 S(Q). To do this, simply add one or other of the following lines under the *import* 192 statements. 185 Note that the New Plugin Model Feature currently does not allow for parameters 186 to be polydisperse. However they can be edited in the Advanced Editor. 187 188 189 **SasView version 4.2** made it possible to specify whether a plugin created 190 with the *New Plugin Model* dialog is actually a form factor P(Q) or a structure 191 factor S(Q). To do this, simply add one or other of the following lines under 192 the *import* statements. 193 193 194 194 For a form factor:: … … 200 200 structure_factor = True 201 201 202 If the plugin is a structure factor it is *also* necessary to add two variables to203 t he parameter list::202 If the plugin is a structure factor it is *also* necessary to add two variables 203 to the parameter list:: 204 204 205 205 parameters = [ … … 426 426 See :ref:`Assessing_Fit_Quality`. 427 427 428 The objective of model-fitting is to find a *physically-plausible* model, and set429 of model parameters, that generate a theory that reproduces the experimental data 430 and gives residual values as close to zero as possible.428 The objective of model-fitting is to find a *physically-plausible* model, and 429 set of model parameters, that generate a theory that reproduces the experimental 430 data and minimizes the values of the residuals. 431 431 432 432 Change the default values of the model parameters by hand until the theory line 433 starts to represent the experimental data. Then uncheck the tick boxes alongside 434 all parameters *except* the 'background' and the 'scale'. Click the *Fit* button. 435 SasView will optimise the values of the 'background' and 'scale' and also display 436 the corresponding uncertainties on the optimised values. 437 438 *NB: If no uncertainty is shown it generally means that the model is not very* 439 *dependent on the corresponding parameter (or that one or more parameters are* 440 *'correlated').* 441 442 In the bottom left corner of the *Fit Page* is a box displaying the normalised value 443 of the statistical $\chi^2$ parameter returned by the optimiser. 433 starts to represent the experimental data. Then check the tick boxes alongside 434 the 'background' and 'scale' parameters. Click the *Fit* button. SasView 435 will optimise the values of the 'background' and 'scale' and also display the 436 corresponding uncertainties on the optimised values. 437 438 .. note:: 439 If the uncertainty on a fitted parameter is unrealistically large, or if it 440 displays as NaN, the model is most likely a poor representation of the data, 441 the parameter in question is highly correlated with one or more of the other 442 fitted parameters, or the model is relatively insensitive to the value of 443 that particular parameter. 444 445 In the bottom left corner of the *Fit Page* is a box displaying a normalised 446 value of the statistical $\chi^2$ parameter (the reduced $\chi^2$, 447 See :ref:`Assessing_Fit_Quality`) returned by the optimiser. 444 448 445 449 Now check the box for another model parameter and click *Fit* again. Repeat this 446 process until most or all parameters are checked and have been optimised. As the447 fit of the theory to the experimental data improves the value of 'chi2/Npts' will 448 decrease. A good model fit should easily produce values of 'chi2/Npts' that are 449 close to one, and certainly < 100. See :ref:`Assessing_Fit_Quality`.450 process until all relevant parameters are checked and have been optimised. As 451 the fit of the theory to the experimental data improves, the value of 'Reduced 452 Chi2' will decrease. A good model fit should produce values of Reduced Chi2 453 close to one, and certainly << 100. See :ref:`Assessing_Fit_Quality`. 450 454 451 455 SasView has a number of different optimisers (see the section :ref:`Fitting_Options`). … … 462 466 *the Data Explorer is checked (see the section* :ref:`Loading_data` *).* 463 467 464 This mode is an extension of the :ref:`Single_Fit_Mode` that fits two or more data 465 sets *to the same model* simultaneously. If necessary it is possible to constrain 466 fit parameters between data sets (eg, to fix a background level, or radius, etc). 468 This mode is an extension of the :ref:`Single_Fit_Mode` that allows for some 469 relatively extensive constraints between fitted parameters in a single *FitPage* 470 or between several *FitPage*'s (eg, to constrain all fitted parameters to be the 471 same in a contrast series of *FitPages* except for the solvent sld parameter, 472 constrain the length to be twice that of the radius in a single *FitPage*, 473 fix the radius of the sphere in one *FitPage* to be the same as the radius of 474 the cylinder in a second *FitPage*, etc). 467 475 468 476 If the data to be fit are in multiple files, load each file, then select each file … … 501 509 next to *Add Constraint?* in the *Fit Constraints* box. 502 510 511 To constrain all identically named parameters to fit *simultaneously* to the 512 same value across all the *Fitpages* use the *Easy Setup* drop-down buttons in 513 the *Const & Simul Fit* page. 514 503 515 *NB: You can only constrain parameters that are set to refine.* 516 517 Constraints will generally be of the form 518 519 Mi Parameter1 = Mj.Parameter1 520 521 however the text box after the '=' sign can be used to adjust this 522 relationship; for example 523 524 Mi Parameter1 = scalar \* Mj.Parameter1 525 526 A 'free-form' constraint box is also provided. 527 528 Many constraints can be entered for a single fit. 504 529 505 530 When ready, click the *Fit* button on the *Const & Simul Fit* page, NOT the *Fit* 506 531 button on the individual *FitPage*'s. 507 532 508 Simultaneous Fits without Constraints509 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^510 511 533 The results of the model-fitting will be returned to each of the individual 512 534 *FitPage*'s. 513 535 514 Note that the chi2/Npts value returned is the SUM of the chi2/Npts of each fit. To 515 see the chi2/Npts value for a specific *FitPage*, click the *Compute* button at the 516 bottom of that *FitPage* to recalculate. Also see :ref:`Assessing_Fit_Quality`. 517 518 Simultaneous Fits with Constraints 519 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 520 521 Use the *Easy Setup* drop-down buttons in the *Const & Simul Fit* page to set 522 up constraints between *FitPage*'s. 523 524 Constraints will generally be of the form 525 526 Mi Parameter1 = Mj.Parameter1 527 528 however the text box after the '=' sign can be used to adjust this 529 relationship; for example 530 531 Mi Parameter1 = scalar \* Mj.Parameter1 532 533 A 'free-form' constraint box is also provided. 534 535 Many constraints can be entered for a single fit. 536 537 The results of the model-fitting will be returned to each of the individual 538 *FitPage*'s. 539 540 Note that the chi2/Npts value returned is the SUM of the chi2/Npts of each fit. To 541 see the chi2/Npts value for a specific *FitPage*, click the *Compute* button at the 542 bottom of that *FitPage* to recalculate. Also see :ref:`Assessing_Fit_Quality`. 536 Note that the Reduced Chi2 value returned is the SUM of the Reduced Chi2 of 537 each fit. To see the Reduced Chi2 value for a specific *FitPage*, click the 538 *Compute* button at the bottom of that *FitPage* to recalculate. Note that in 539 doing so the degrees of freedom will be set to Npts. 540 See :ref:`Assessing_Fit_Quality`. Moreover in the case of constraints the 541 degrees of freedom are less than one might think due to those constraints. 543 542 544 543 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ … … 766 765 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 767 766 768 .. note:: This help document was last changed by Paul Butler, 10 September 769 2017 767 .*Document History* 768 769 | 2017-09-10 Paul Butler 770 | 2017-09-15 Steve King 771 | 2018-03-05 Paul Butler -
src/sas/sasgui/perspectives/fitting/media/residuals_help.rst
r99ded31 r84ac3f1 27 27 28 28 $\chi^2$ is a statistical parameter that quantifies the differences between 29 an observed data set and an expected dataset (or 'theory'). 30 31 When showing the a model with the data, *SasView* displays this parameter 32 normalized to the number of data points, $N_\mathrm{pts}$ such that 29 an observed data set and an expected dataset (or 'theory') calculated as 33 30 34 31 .. math:: 35 32 36 \chi^2 _N37 = \sum[(Y_i - \mathrm{theory}_i)^2 / \mathrm{error}_i^2] / N_\mathrm{pts}33 \chi^2 34 = \sum[(Y_i - \mathrm{theory}_i)^2 / \mathrm{error}_i^2] 38 35 39 When performing a fit, *SasView* instead displays the reduced $\chi^2_R$, 40 which takes into account the number of fitting parameters $N_\mathrm{par}$ 41 (to calculate the number of 'degrees of freedom'). This is computed as 36 Fitting typically minimizes the value of $\chi^2$. For assessing the quality of 37 the model and its "fit" however, *SasView* displays the traditional reduced 38 $\chi^2_R$ which normalizes this parameter by dividing it by the number of 39 degrees of freedom (or DOF). The DOF is the number of data points being 40 considered, $N_\mathrm{pts}$, reduced by the number of free (i.e. fitted) 41 parameters, $N_\mathrm{par}$. Note that model parameters that are kept fixed do 42 *not* contribute to the DOF (they are not "free"). This reduced value is then 43 given as 42 44 43 45 .. math:: … … 47 49 / [N_\mathrm{pts} - N_\mathrm{par}] 48 50 49 The normalized $\chi^2_N$ and the reduced $\chi^2_R$ are very close to each 50 other when $N_\mathrm{pts} \gg N_\mathrm{par}$. 51 Note that this means the displayed value will vary depending on the number of 52 parameters used in the fit. In particular, when doing a calculation without a 53 fit (e.g. manually changing a parameter) the DOF will now equal $N_\mathrm{pts}$ 54 and the $\chi^2_R$ will be the smallest possible for that combination of model, 55 data set, and set of parameter values. 56 57 When $N_\mathrm{pts} \gg N_\mathrm{par}$ as it should for proper fitting, the 58 value of the reduced $\chi^2_R$ will not change very much. 51 59 52 60 For a good fit, $\chi^2_R$ tends to 1. … … 90 98 | 2015-06-08 Steve King 91 99 | 2017-09-28 Paul Kienzle 100 | 2018-03-04 Paul Butler -
src/sas/sasview/sasview.py
r20fa5fe r1270e3c 43 43 from sas.sasgui.guiframe.gui_manager import SasViewApp 44 44 self.gui = SasViewApp(0) 45 if sys.platform == "darwin": 46 self.check_sasmodels_compiler() 45 47 # Set the application manager for the GUI 46 48 self.gui.set_manager(self) … … 130 132 self.gui.MainLoop() 131 133 134 def check_sasmodels_compiler(self): 135 """ 136 Checking c compiler for sasmodels and raises xcode command line 137 tools for installation 138 """ 139 #wx should be importable at this stage 140 import wx 141 import subprocess 142 #Generic message box created becuase standard MessageBox is not moveable 143 class GenericMessageBox(wx.Dialog): 144 def __init__(self, parent, text, title = ''): 145 146 wx.Dialog.__init__(self, parent, -1, title = title, 147 size = (360,200), pos=(20,60), 148 style = wx.STAY_ON_TOP | wx.DEFAULT_DIALOG_STYLE) 149 panel = wx.Panel(self, -1) 150 top_row_sizer = wx.BoxSizer(wx.HORIZONTAL) 151 152 error_bitmap = wx.ArtProvider.GetBitmap( 153 wx.ART_ERROR, wx.ART_MESSAGE_BOX 154 ) 155 error_bitmap_ctrl = wx.StaticBitmap(panel, -1) 156 error_bitmap_ctrl.SetBitmap(error_bitmap) 157 label = wx.StaticText(panel, -1, text) 158 top_row_sizer.Add(error_bitmap_ctrl, flag=wx.ALL, border=10) 159 top_row_sizer.Add(label, flag=wx.ALIGN_CENTER_VERTICAL) 160 161 #Create the OK button in the bottom row. 162 ok_button = wx.Button(panel, wx.ID_OK ) 163 self.Bind(wx.EVT_BUTTON, self.on_ok, source=ok_button) 164 ok_button.SetFocus() 165 ok_button.SetDefault() 166 167 sizer = wx.BoxSizer(wx.VERTICAL) 168 sizer.Add(top_row_sizer) 169 sizer.Add(ok_button, flag=wx.ALIGN_CENTER | wx.ALL, border=5) 170 panel.SetSizer(sizer) 171 172 def on_ok(self, event): 173 self.Destroy() 174 175 logger = logging.getLogger(__name__) 176 try: 177 subprocess.check_output(["cc","--version"], stderr=subprocess.STDOUT) 178 except subprocess.CalledProcessError as exc: 179 dlg = GenericMessageBox(parent=None, 180 text='No compiler installed. Please install command line\n' 181 'developers tools by clicking \"Install\" in another winodw\n\n' 182 'Alternatively click \"Not Now\" and use OpenCL\n' 183 'compiler, which can be set up from menu Fitting->OpenCL Options\n\n', 184 title = 'Compiler Info') 185 dlg.Show() 186 logger.error("No compiler installed. %s\n"%(exc)) 187 logger.error(traceback.format_exc()) 132 188 133 189 def setup_logging():
Note: See TracChangeset
for help on using the changeset viewer.