Changeset c7634fd in sasview for src


Ignore:
Timestamp:
Jun 21, 2018 2:04:35 PM (7 years ago)
Author:
krzywon
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.
Message:

Merge branch 'ticket-976' into ticket-1111

Location:
src/sas
Files:
19 edited
1 moved

Legend:

Unmodified
Added
Removed
  • src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py

    r61f329f0 r18af6d2  
    3838    # CanSAS version 
    3939    cansas_version = 2.0 
    40     # Logged warnings or messages 
    41     logging = None 
    42     # List of errors for the current data set 
    43     errors = None 
    44     # Raw file contents to be processed 
    45     raw_data = None 
    46     # List of plottable1D objects that should be linked to the current_datainfo 
    47     data1d = None 
    48     # List of plottable2D objects that should be linked to the current_datainfo 
    49     data2d = None 
    5040    # Data type name 
    5141    type_name = "CanSAS 2.0" 
     
    111101        self.errors = set() 
    112102        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'' 
    113110        self.parent_class = u'' 
    114111        self.detector = Detector() 
     
    147144                    self.add_data_set(key) 
    148145                elif class_prog.match(u'SASdata'): 
     146                    self._find_data_attributes(value) 
    149147                    self._initialize_new_data_set(parent_list) 
    150148                # Recursion step to access data within the group 
     
    159157                data_set = data[key][:] 
    160158                unit = self._get_unit(value) 
    161  
    162                 # I and Q Data 
    163                 if key == u'I': 
    164                     if isinstance(self.current_dataset, plottable_2D): 
    165                         self.current_dataset.data = data_set 
    166                         self.current_dataset.zaxis("Intensity", unit) 
    167                     else: 
    168                         self.current_dataset.y = data_set.flatten() 
    169                         self.current_dataset.yaxis("Intensity", unit) 
    170                     continue 
    171                 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                     continue 
    177                 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                     continue 
    184                 elif key == u'Qdev': 
    185                     self.current_dataset.dx = data_set.flatten() 
    186                     continue 
    187                 elif key == u'dQw': 
    188                     self.current_dataset.dxw = data_set.flatten() 
    189                     continue 
    190                 elif key == u'dQl': 
    191                     self.current_dataset.dxl = data_set.flatten() 
    192                     continue 
    193                 elif key == u'Qy': 
    194                     self.current_dataset.yaxis("Q_y", unit) 
    195                     self.current_dataset.qy_data = data_set.flatten() 
    196                     continue 
    197                 elif key == u'Qydev': 
    198                     self.current_dataset.dqy_data = data_set.flatten() 
    199                     continue 
    200                 elif key == u'Qx': 
    201                     self.current_dataset.xaxis("Q_x", unit) 
    202                     self.current_dataset.qx_data = data_set.flatten() 
    203                     continue 
    204                 elif key == u'Qxdev': 
    205                     self.current_dataset.dqx_data = data_set.flatten() 
    206                     continue 
    207                 elif key == u'Mask': 
    208                     self.current_dataset.mask = data_set.flatten() 
    209                     continue 
    210                 # Transmission Spectrum 
    211                 elif (key == u'T' 
    212                       and self.parent_class == u'SAStransmission_spectrum'): 
    213                     self.trans_spectrum.transmission = data_set.flatten() 
    214                     continue 
    215                 elif (key == u'Tdev' 
    216                       and self.parent_class == u'SAStransmission_spectrum'): 
    217                     self.trans_spectrum.transmission_deviation = \ 
    218                         data_set.flatten() 
    219                     continue 
    220                 elif (key == u'lambda' 
    221                       and self.parent_class == u'SAStransmission_spectrum'): 
    222                     self.trans_spectrum.wavelength = data_set.flatten() 
    223                     continue 
    224159 
    225160                for data_point in data_set: 
     
    232167                    if key == u'definition': 
    233168                        self.current_datainfo.meta_data['reader'] = data_point 
     169                    # Run 
    234170                    elif key == u'run': 
    235171                        self.current_datainfo.run.append(data_point) 
     
    240176                        except Exception: 
    241177                            pass 
     178                    # Title 
    242179                    elif key == u'title': 
    243180                        self.current_datainfo.title = data_point 
     181                    # Note 
    244182                    elif key == u'SASnote': 
    245183                        self.current_datainfo.notes.append(data_point) 
    246  
    247184                    # 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) 
    282187                    # Instrumental Information 
    283188                    elif (key == u'name' 
    284189                          and self.parent_class == u'SASinstrument'): 
    285190                        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) 
    346200                    # 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) 
    363203                    # 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) 
    404206                    # 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 
    405213                    else: 
    406214                        new_key = self._create_unique_key( 
     
    411219                # I don't know if this reachable code 
    412220                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) 
    413431 
    414432    def add_intermediate(self): 
     
    515533        self.current_datainfo = DataInfo() 
    516534 
    517  
    518535    def _initialize_new_data_set(self, parent_list=None): 
    519536        """ 
     
    534551            self.current_dataset = plottable_1D(x, y) 
    535552        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") 
    536585 
    537586    def _find_intermediate(self, parent_list, basename=""): 
  • src/sas/sascalc/dataloader/file_reader_base_class.py

    ra58b5a0 r4a8d55c  
    3131FIELDS_2D = ('data', 'qx_data', 'qy_data', 'q_data', 'err_data', 
    3232                 'dqx_data', 'dqy_data', 'mask') 
    33  
     33DEPRECATION_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.") 
    3438 
    3539class FileReader(object): 
     
    4044    # List of allowed extensions 
    4145    ext = ['.txt'] 
     46    # Deprecated extensions 
     47    deprecated_extensions = ['.asc', '.nxs'] 
    4248    # Bypass extension check and try to load anyway 
    4349    allow_all = False 
     
    8793                    if not self.f_open.closed: 
    8894                        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) 
    8998                    if len(self.output) > 0: 
    9099                        # Sort the data that's been loaded 
     
    146155        else: 
    147156            logger.warning(msg) 
     157            raise NoKnownLoaderException(msg) 
    148158 
    149159    def send_to_output(self): 
  • src/sas/sascalc/dataloader/loader.py

    rdc8d1c2 r4a8d55c  
    9090            ascii_loader = ascii_reader.Reader() 
    9191            return ascii_loader.read(path) 
     92        except NoKnownLoaderException: 
     93            pass  # Try the Cansas XML reader 
    9294        except DefaultReaderException: 
    9395            pass  # Loader specific error to try the cansas XML reader 
     
    100102            cansas_loader = cansas_reader.Reader() 
    101103            return cansas_loader.read(path) 
     104        except NoKnownLoaderException: 
     105            pass  # Try the NXcanSAS reader 
    102106        except DefaultReaderException: 
    103107            pass  # Loader specific error to try the NXcanSAS reader 
  • src/sas/sascalc/fit/pagestate.py

    r9e6aeaf r3b070a0  
    646646                    name = value.split(':', 1)[1].strip() 
    647647                    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:] 
    648653                    file_name = CENTRE % file_value 
    649654                    if len(title) == 0: 
     
    721726        html_str, text_str, title = self._get_report_string() 
    722727        # 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] 
    725733        # final report html strings 
    726734        report_str = html_str + ELINE.join(image_links) 
    727  
     735        report_str += FEET_3 
    728736        return report_str, text_str 
    729737 
     
    13681376""" 
    13691377FEET_2 = \ 
    1370 """<img src="%s" ></img> 
     1378"""<img src="%s"></img> 
     1379""" 
     1380FEET_2_unix = \ 
     1381"""<img src="%s" width="540"></img> 
    13711382""" 
    13721383FEET_3 = \ 
  • src/sas/sasgui/guiframe/local_perspectives/data_loader/data_loader.py

    r20fa5fe r2924532  
    185185            try: 
    186186                message = "Loading {}...\n".format(p_file) 
    187                 self.load_update(output=output, message=message, info="info") 
     187                self.load_update(message=message, info="info") 
    188188                temp = self.loader.load(p_file, format) 
    189189                if not isinstance(temp, list): 
     
    201201                        else: 
    202202                            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") 
    209206 
    210207            except NoKnownLoaderException as e: 
    211208                exception_occurred = True 
    212                 logger.error(e.message) 
    213  
    214209                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") 
    216213 
    217214            except Exception as e: 
    218215                exception_occurred = True 
    219                 logger.error(e.message) 
    220  
    221216                file_err = "The Data file you selected could not be " 
    222217                file_err += "loaded.\nMake sure the content of your file" 
     
    225220                file_err += " following:\n" 
    226221                file_err += e.message 
    227                 file_errors[basename] = [file_err] 
     222                self.load_complete(output=None, 
     223                                   message=file_err, 
     224                                   info="error") 
    228225 
    229226        if len(file_errors) > 0: 
    230227            error_message = "" 
    231228            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 " 
    233230                error_message += "loading {}:\n".format(filename) 
    234231                for message in error_array: 
    235232                    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 
    241239            self.load_complete(output=output, message="Loading data complete!", 
    242240                               info="info") 
     
    244242            self.load_complete(output=None, message=error_message, info="error") 
    245243 
    246  
    247     def load_update(self, output=None, message="", info="warning"): 
     244    def load_update(self, message="", info="warning"): 
    248245        """ 
    249246        print update on the status bar 
    250247        """ 
    251248        if message != "": 
    252             wx.PostEvent(self.parent, StatusEvent(status=message, info=info, 
     249            wx.PostEvent(self.parent, StatusEvent(status=message, 
     250                                                  info=info, 
    253251                                                  type="progress")) 
    254252 
     
    257255         post message to status bar and return list of data 
    258256        """ 
    259         wx.PostEvent(self.parent, StatusEvent(status=message, info=info, 
     257        wx.PostEvent(self.parent, StatusEvent(status=message, 
     258                                              info=info, 
    260259                                              type="stop")) 
    261260        if output is not None: 
  • src/sas/sasgui/guiframe/media/data_formats_help.rst

    r959eb01 r1eb86a5  
    2828 
    2929*  .TXT 
    30 *  .ASC 
    3130*  .DAT 
    3231*  .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. 
    3338 
    3439If using CSV output from, for example, a spreadsheet, ensure that it is not using commas as delimiters for thousands. 
     
    4045 
    4146For a description of the ISIS 1D format see: 
    42 http://www.isis.stfc.ac.uk/instruments/loq/software/colette-ascii-file-format-descriptions9808.pdf 
     47https://www.isis.stfc.ac.uk/Pages/colette-ascii-file-format-descriptions.pdf 
    4348 
    4449For a description of the NXcanSAS format see: 
     
    5863-------------- 
    5964 
    60 SasView will read ASCII ('text') files in the NIST 2D format (with the extensions .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/>`_. 
     65SasView 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/>`_. 
    6166 
    6267Most 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.  
    6375 
    6476The 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  
    2727class BaseReportDialog(wx.Dialog): 
    2828 
    29     def __init__(self, report_list, *args, **kwds): 
     29    def __init__(self, report_list, imgRAM, fig_urls, *args, **kwds): 
    3030        """ 
    3131        Initialization. The parameters added to Dialog are: 
     
    3737        kwds["image"] = 'Dynamic Image' 
    3838 
     39        #MemoryFSHandle for storing images 
     40        self.imgRAM = imgRAM 
     41        #Images location in urls 
     42        self.fig_urls = fig_urls 
    3943        # title 
    4044        self.SetTitle("Report") 
     
    7579        hbox.Add(button_print) 
    7680 
    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) 
    8186 
    8287        # panel for report page 
     
    111116        printh.PrintText(self.report_html) 
    112117 
     118 
    113119    def OnClose(self, event=None): 
    114120        """ 
     
    116122        : event: Close button event 
    117123        """ 
     124        for fig in self.fig_urls: 
     125            self.imgRAM.RemoveFile(fig) 
     126 
    118127        self.Close() 
    119128 
  • src/sas/sasgui/perspectives/calculator/calculator.py

    r235f514 r61bfd36  
    8686                ("Generic Scattering Calculator", 
    8787                        gensas_help, self.on_gen_model), 
     88                ("Orientation Viewer", "Show 3-D view of oriented shape", self.on_show_orientation), 
    8889                ("Python Shell/Editor", pyconsole_help, self.on_python_console), 
    8990                ("Image Viewer", imageviewer_help, self.on_image_viewer), ] 
     
    190191            self.gen_frame.Show(False) 
    191192        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() 
    192200 
    193201    def on_image_viewer(self, event): 
  • src/sas/sasgui/perspectives/calculator/media/resolution_calculator_help.rst

    r5ed76f8 r3bd58f0  
    2929   careful to note that distances are specified in cm! 
    3030 
    31 4) Enter values for the source wavelength(s), $\lambda$, and its spread (= $\text{FWHM}/\lambda$). 
     314) Enter values for the source wavelength(s), $\lambda$, and its spread (= $\mathrm{FWHM}/\lambda$). 
    3232 
    3333   For monochromatic sources, the inputs are just one value. For TOF sources, 
     
    5858   region near the beam block/stop 
    5959 
    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.] 
    6161 
    6262   the variance is slightly under estimated. 
  • src/sas/sasgui/perspectives/calculator/media/sas_calculator_help.rst

    r1b67f3e r55abe4f  
    8888 
    8989Now 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, 
     90to the $x$-axis are $\phi$ and $\theta_\mathrm{up}$ respectively (see above). Then, 
    9191depending upon the polarization (spin) state of neutrons, the scattering 
    9292length densities, including the nuclear scattering length density ($\beta_N$) 
     
    107107.. math:: 
    108108 
    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} \\ 
    111111    M_{\perp z'} &= M_{0z} \\ 
    112112    M_{0q_x} &= (M_{0x}\cos\phi - M_{0y}\sin\phi)\cos\phi \\ 
  • src/sas/sasgui/perspectives/calculator/model_editor.py

    r2469df7 r9258c43c  
    391391        self._msg_box.SetLabel(msg) 
    392392        self._msg_box.SetForegroundColour(color) 
     393        self._set_model_list() 
    393394        if self.parent.parent is not None: 
    394395            from sas.sasgui.guiframe.events import StatusEvent 
     
    432433        if len(main_list) > 1: 
    433434            main_list.sort() 
     435        self.model1.Clear() 
     436        self.model2.Clear() 
    434437        for idx in range(len(main_list)): 
    435438            self.model1.Append(str(main_list[idx]), idx) 
     
    660663        Do the layout for parameter related widgets 
    661664        """ 
    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" 
    667668        param_tip += "#Example:\n" 
    668669        param_tip += "A = 1\nB = 1" 
     
    678679                                  (self.param_tcl, 1, wx.EXPAND | wx.ALL, 10)]) 
    679680 
    680         # Parameters with polydispersity 
    681         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)]) 
    697681 
    698682    def _layout_function(self): 
     
    896880            description = self.desc_tcl.GetValue() 
    897881            param_str = self.param_tcl.GetText() 
    898             pd_param_str = self.pd_param_tcl.GetText() 
    899882            func_str = self.function_tcl.GetText() 
    900883            # No input for the model function 
     
    902885                if func_str.count('return') > 0: 
    903886                    self.write_file(self.fname, name, description, param_str, 
    904                                     pd_param_str, func_str) 
     887                                    func_str) 
    905888                    try: 
    906889                        result, msg = check_model(self.fname), None 
     
    942925        self.warning = msg 
    943926 
    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): 
    945928        """ 
    946929        Write content in file 
     
    949932        :param desc_str: content of the description strings 
    950933        :param param_str: content of params; Strings 
    951         :param pd_param_str: content of params requiring polydispersity; Strings 
    952934        :param func_str: content of func; Strings 
    953935        """ 
     
    963945        # Write out parameters 
    964946        param_names = []    # to store parameter names 
    965         pd_params = [] 
    966947        out_f.write('parameters = [ \n') 
    967948        out_f.write('#   ["name", "units", default, [lower, upper], "type", "description"],\n') 
     
    970951            out_f.write("    ['%s', '', %s, [-inf, inf], '', '%s'],\n" 
    971952                        % (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)) 
    977953        out_f.write('    ]\n') 
    978954 
    979955        # Write out function definition 
     956        out_f.write('\n') 
    980957        out_f.write('def Iq(%s):\n' % ', '.join(['x'] + param_names)) 
    981958        out_f.write('    """Absolute scattering"""\n') 
     
    987964            out_f.write('    import numpy as np') 
    988965        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)) 
    990967        out_f.write('## uncomment the following if Iq works for vector x\n') 
    991968        out_f.write('#Iq.vectorized = True\n') 
    992  
    993         # If polydisperse, create place holders for form_volume, ER and VR 
    994         if pd_params: 
    995             out_f.write('\n') 
    996             out_f.write(CUSTOM_TEMPLATE_PD % {'args': ', '.join(pd_params)}) 
    997969 
    998970        # Create place holder for Iqxy 
     
    11251097description = """%(description)s""" 
    11261098 
    1127 ''' 
    1128  
    1129 CUSTOM_TEMPLATE_PD = '''\ 
    1130 def form_volume(%(args)s): 
    1131     """ 
    1132     Volume of the particles used to compute absolute scattering intensity 
    1133     and to weight polydisperse parameter contributions. 
    1134     """ 
    1135     return 0.0 
    1136  
    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.0 
    1144  
    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.0 
    11521099''' 
    11531100 
  • src/sas/sasgui/perspectives/calculator/resolution_calculator_panel.py

    r7432acb r1cf490b6  
    1818matplotlib.use('WXAgg') 
    1919from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas 
    20 from matplotlib.backends.backend_wxagg import NavigationToolbar2Wx as Toolbar 
     20from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as Toolbar 
    2121from matplotlib.backend_bases import FigureManagerBase 
    2222# Wx-Pylab magic for displaying plots within an application's window. 
  • src/sas/sasgui/perspectives/corfunc/media/corfunc_help.rst

    rad476d1 r501712f  
    188188*   Average Hard Block Thickness :math:`= L_c` 
    189189*   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}}` 
    192192*   Local Crystallinity :math:`= L_c/L_p` 
    193193 
     
    203203*   Bound Fraction :math:`= <p>` 
    204204*   Second Moment :math:`= \sigma` 
    205 *   Maximum Extent :math:`= \delta_{\text{h}}` 
     205*   Maximum Extent :math:`= \delta_{\mathrm{h}}` 
    206206*   Adsorbed Amount :math:`= \Gamma` 
    207207 
  • src/sas/sasgui/perspectives/file_converter/media/file_converter_help.rst

    r59decb81 rfafb396  
    1919    or with a comma or semi-colon delimiter 
    2020*   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 
    2322*   `1D BSL/OTOKO format 
    2423    <http://www.diamond.ac.uk/Beamlines/Soft-Condensed-Matter/small-angle/ 
  • src/sas/sasgui/perspectives/fitting/basepage.py

    r58a8f76 rc192960  
    641641        # get the strings for report 
    642642        report_str, text_str = self.state.report(fig_urls=refs) 
    643  
    644643        # Show the dialog 
    645644        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, "") 
    647646        dialog.Show() 
    648647 
     
    677676            refs.append('memory:' + name) 
    678677            imgRAM.AddFile(name, canvas.bitmap, wx.BITMAP_TYPE_PNG) 
    679  
    680678            # append figs 
    681679            images.append(fig) 
     
    13671365            except Exception: 
    13681366                logger.error(traceback.format_exc()) 
    1369             selection = self._find_polyfunc_selection(disp_model) 
     1367            index, selection = self._find_polyfunc_selection(disp_model) 
    13701368            for list in self.fittable_param: 
    13711369                if list[1] == key and list[7] is not None: 
    1372                     list[7].SetSelection(selection) 
     1370                    list[7].SetSelection(index) 
    13731371                    # For the array disp_model, set the values and weights 
    1374                     if selection == 1: 
     1372                    if selection == 'array': 
    13751373                        disp_model.set_weights(self.values[key], 
    13761374                                               self.weights[key]) 
     
    13851383                            logger.error(traceback.format_exc()) 
    13861384            # For array, disable all fixed params 
    1387             if selection == 1: 
     1385            if selection == 'array': 
    13881386                for item in self.fixed_param: 
    13891387                    if item[1].split(".")[0] == key.split(".")[0]: 
     
    14721470            # we need to check here ourselves. 
    14731471            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 
    14771477 
    14781478            # Here we should check whether the boundaries have been modified. 
     
    15361536                        data=[self.data]) 
    15371537            # 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 
    15411541 
    15421542            # If qmin and qmax have been modified, update qmin and qmax and 
     
    23242324 
    23252325            # 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)))): 
    23272328                self.model.setParam(name, value) 
    23282329                is_modified = True 
     
    26682669    def _find_polyfunc_selection(self, disp_func=None): 
    26692670        """ 
    2670         FInd Comboox selection from disp_func 
     2671        Find Combobox selection from disp_func 
    26712672 
    26722673        :param disp_function: dispersion distr. function 
     
    26752676        if disp_func is not None: 
    26762677            try: 
    2677                 return POLYDISPERSITY_MODELS.values().index(disp_func.__class__) 
     2678                return (list(POLYDISPERSITY_MODELS).index(disp_func.type), 
     2679                       disp_func.type) 
    26782680            except ValueError: 
    26792681                pass  # Fall through to default class 
    2680         return POLYDISPERSITY_MODELS.keys().index('gaussian') 
     2682        return (list(POLYDISPERSITY_MODELS).index('gaussian'), 'gaussian') 
    26812683 
    26822684    def on_reset_clicked(self, event): 
  • src/sas/sasgui/perspectives/fitting/fitpage.py

    rbfeb823 ra7c6f38  
    365365        # StaticText for chi2, N(for fitting), Npts + Log/linear spacing 
    366366        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)") 
    368368        self.Npts_fit = BGTextCtrl(self, wx.ID_ANY, "-", size=(75, 20), style=0) 
    369369        self.Npts_fit.SetToolTipString( 
     
    391391        self.points_sizer.Add(self.pointsbox) 
    392392 
    393         box_description_1 = wx.StaticText(self, wx.ID_ANY, '   Chi2/Npts') 
     393        box_description_1 = wx.StaticText(self, wx.ID_ANY, 'Reduced Chi2') 
    394394        box_description_2 = wx.StaticText(self, wx.ID_ANY, 'Npts(Fit)') 
    395395 
  • src/sas/sasgui/perspectives/fitting/media/fitting_help.rst

    r5005ae0 r9258c43c  
    180180*checked*\ . 
    181181 
    182 Also note that the 'Fit Parameters' have been split into two sections: those 
    183 which can be polydisperse (shape and orientation parameters) and those which are 
    184 not (eg, scattering length densities). 
    185  
    186182A model file generated by this option can be viewed and further modified using 
    187183the :ref:`Advanced_Plugin_Editor` . 
    188184 
    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. 
     185Note that the New Plugin Model Feature currently does not allow for parameters 
     186to 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 
     190with the *New Plugin Model* dialog is actually a form factor P(Q) or a structure 
     191factor S(Q). To do this, simply add one or other of the following lines under 
     192the *import* statements. 
    193193 
    194194For a form factor:: 
     
    200200     structure_factor = True 
    201201 
    202 If the plugin is a structure factor it is *also* necessary to add two variables to 
    203 the parameter list:: 
     202If the plugin is a structure factor it is *also* necessary to add two variables 
     203to the parameter list:: 
    204204 
    205205     parameters = [ 
     
    426426See :ref:`Assessing_Fit_Quality`. 
    427427 
    428 The objective of model-fitting is to find a *physically-plausible* model, and set 
    429 of model parameters, that generate a theory that reproduces the experimental data 
    430 and gives residual values as close to zero as possible. 
     428The objective of model-fitting is to find a *physically-plausible* model, and 
     429set of model parameters, that generate a theory that reproduces the experimental 
     430data and minimizes the values of the residuals. 
    431431 
    432432Change 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. 
     433starts to represent the experimental data. Then check the tick boxes alongside 
     434the 'background' and 'scale' parameters. Click the *Fit* button. SasView 
     435will optimise the values of the 'background' and 'scale' and also display the 
     436corresponding 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 
     445In the bottom left corner of the *Fit Page* is a box displaying a normalised 
     446value of the statistical $\chi^2$ parameter (the reduced $\chi^2$, 
     447See :ref:`Assessing_Fit_Quality`) returned by the optimiser. 
    444448 
    445449Now 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 the 
    447 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`. 
     450process until all relevant parameters are checked and have been optimised. As 
     451the fit of the theory to the experimental data improves, the value of 'Reduced 
     452Chi2' will decrease. A good model fit should produce values of Reduced Chi2 
     453close to one, and certainly << 100. See :ref:`Assessing_Fit_Quality`. 
    450454 
    451455SasView has a number of different optimisers (see the section :ref:`Fitting_Options`). 
     
    462466*the Data Explorer is checked (see the section* :ref:`Loading_data` *).* 
    463467 
    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). 
     468This mode is an extension of the :ref:`Single_Fit_Mode` that allows for some 
     469relatively extensive constraints between fitted parameters in a single *FitPage* 
     470or between several *FitPage*'s (eg, to constrain all fitted parameters to be the 
     471same in a contrast series of *FitPages* except for the solvent sld parameter, 
     472constrain the length to be twice that of the radius in a single *FitPage*, 
     473fix the radius of the sphere in one *FitPage* to be the same as the radius of 
     474the cylinder in a second *FitPage*, etc). 
    467475 
    468476If the data to be fit are in multiple files, load each file, then select each file 
     
    501509next to *Add Constraint?* in the *Fit Constraints* box. 
    502510 
     511To constrain all identically named parameters to fit *simultaneously* to the 
     512same value across all the *Fitpages* use the *Easy Setup* drop-down buttons in 
     513the *Const & Simul Fit* page. 
     514 
    503515*NB: You can only constrain parameters that are set to refine.* 
     516 
     517Constraints will generally be of the form 
     518 
     519  Mi Parameter1 = Mj.Parameter1 
     520 
     521however the text box after the '=' sign can be used to adjust this 
     522relationship; for example 
     523 
     524  Mi Parameter1 = scalar \* Mj.Parameter1 
     525 
     526A 'free-form' constraint box is also provided. 
     527 
     528Many constraints can be entered for a single fit. 
    504529 
    505530When ready, click the *Fit* button on the *Const & Simul Fit* page, NOT the *Fit* 
    506531button on the individual *FitPage*'s. 
    507532 
    508 Simultaneous Fits without Constraints 
    509 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    510  
    511533The results of the model-fitting will be returned to each of the individual 
    512534*FitPage*'s. 
    513535 
    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`. 
     536Note that the Reduced Chi2 value returned is the SUM of the Reduced Chi2 of 
     537each 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 
     539doing so the degrees of freedom will be set to Npts. 
     540See :ref:`Assessing_Fit_Quality`.  Moreover in the case of constraints the 
     541degrees of freedom are less than one might think due to those constraints. 
    543542 
    544543.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     
    766765.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    767766 
    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  
    2727 
    2828$\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 
     29an observed data set and an expected dataset (or 'theory') calculated as 
    3330 
    3431.. math:: 
    3532 
    36   \chi^2_N 
    37   =  \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] 
    3835 
    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 
     36Fitting typically minimizes the value of $\chi^2$.  For assessing the quality of 
     37the 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 
     39degrees of freedom (or DOF). The DOF is the number of data points being 
     40considered, $N_\mathrm{pts}$, reduced by the number of free (i.e. fitted) 
     41parameters, $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 
     43given as 
    4244 
    4345.. math:: 
     
    4749  / [N_\mathrm{pts} - N_\mathrm{par}] 
    4850 
    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}$. 
     51Note that this means the displayed value will vary depending on the number of 
     52parameters used in the fit. In particular, when doing a calculation without a 
     53fit (e.g. manually changing a parameter) the DOF will now equal $N_\mathrm{pts}$ 
     54and the $\chi^2_R$ will be the smallest possible for that combination of model, 
     55data set, and set of parameter values. 
     56 
     57When $N_\mathrm{pts} \gg N_\mathrm{par}$ as it should for proper fitting, the 
     58value of the reduced $\chi^2_R$ will not change very much. 
    5159 
    5260For a good fit, $\chi^2_R$ tends to 1. 
     
    9098| 2015-06-08 Steve King 
    9199| 2017-09-28 Paul Kienzle 
     100| 2018-03-04 Paul Butler 
  • src/sas/sasview/sasview.py

    r20fa5fe r1270e3c  
    4343        from sas.sasgui.guiframe.gui_manager import SasViewApp 
    4444        self.gui = SasViewApp(0) 
     45        if sys.platform == "darwin": 
     46            self.check_sasmodels_compiler() 
    4547        # Set the application manager for the GUI 
    4648        self.gui.set_manager(self) 
     
    130132        self.gui.MainLoop() 
    131133 
     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()) 
    132188 
    133189def setup_logging(): 
Note: See TracChangeset for help on using the changeset viewer.