Changeset 8cb1a07 in sasview


Ignore:
Timestamp:
Aug 18, 2016 7:03:43 AM (8 years ago)
Author:
lewis
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
eb98f24
Parents:
1f6d293
Message:

Implement writing 2D data to NXcanSAS

File:
1 edited

Legend:

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

    r1f6d293 r8cb1a07  
    390390        :param filename: Where to write the CanSAS 2.0 file 
    391391        """ 
    392         is_1d = all([isinstance(d, Data1D) for d in dataset]) 
    393         is_2d = all([isinstance(d, Data2D) for d in dataset]) 
    394  
    395         if not (is_1d or is_2d): 
    396             msg = ("All elements of dataset must be of the same class " 
    397                 "(Data1D or Data2D)") 
    398             raise ValueError(msg) 
    399392 
    400393        def _h5_string(string): 
     
    414407            return np.array(x, dtype=np.float32) 
    415408 
     409        valid_data = all([issubclass(d.__class__, (Data1D, Data2D)) for d in dataset]) 
     410        if not valid_data: 
     411            raise ValueError("All entries of dataset must be Data1D or Data2D objects") 
     412 
    416413        # Get run name and number from first Data object 
    417414        data_info = dataset[0] 
     
    434431        i = 1 
    435432 
    436         if is_1d: 
    437             for data_obj in dataset: 
    438                 data_entry = sasentry.create_group("sasdata{0:0=2d}".format(i)) 
    439                 data_entry.attrs['canSAS_class'] = 'SASdata' 
    440                 data_entry.attrs['signal'] = 'I' 
    441                 data_entry.attrs['I_axes'] = 'Q' 
    442                 data_entry.attrs['I_uncertainties'] = 'Idev' 
    443                 data_entry.attrs['Q_indicies'] = 0 
    444                 Q_data = data_entry.create_dataset('Q', data=data_obj.x) 
    445                 I_data = data_entry.create_dataset('I', data=data_obj.y) 
    446                 dI_data = data_entry.create_dataset('Idev', data=data_obj.dy) 
     433        for data_obj in dataset: 
     434            data_entry = sasentry.create_group("sasdata{0:0=2d}".format(i)) 
     435            data_entry.attrs['canSAS_class'] = 'SASdata' 
     436            if isinstance(data_obj, Data1D): 
     437                self._write_1d_data(data_obj, data_entry) 
     438            elif isinstance(data_obj, Data2D): 
     439                self._write_2d_data(data_obj, data_entry) 
     440            i += 1 
     441 
     442        data_info = dataset[0] 
     443        sample_entry = sasentry.create_group('sassample') 
     444        sample_entry.attrs['canSAS_class'] = 'SASsample' 
     445        sample_entry['name'] = _h5_string(data_info.sample.name) 
     446        sample_attrs = ['thickness', 'temperature'] 
     447        for key in sample_attrs: 
     448            if getattr(data_info.sample, key) is not None: 
     449                sample_entry.create_dataset(key, data=np.array([getattr(data_info.sample, key)])) 
     450 
     451        instrument_entry = sasentry.create_group('sasinstrument') 
     452        instrument_entry.attrs['canSAS_class'] = 'SASinstrument' 
     453        instrument_entry['name'] = _h5_string(data_info.instrument) 
     454 
     455        source_entry = instrument_entry.create_group('sassource') 
     456        source_entry.attrs['canSAS_class'] = 'SASsource' 
     457        if data_info.source.radiation is None: 
     458            source_entry['radiation'] = _h5_string('neutron') 
     459        else: 
     460            source_entry['radiation'] = _h5_string(data_info.source.radiation) 
     461 
     462        if len(data_info.collimation) > 0: 
     463            i = 1 
     464            for coll_info in data_info.collimation: 
     465                collimation_entry = instrument_entry.create_group( 
     466                    'sascollimation{0:0=2d}'.format(i)) 
     467                collimation_entry.attrs['canSAS_class'] = 'SAScollimation' 
     468                if coll_info.length is not None: 
     469                    collimation_entry['SDD'] = _h5_float(coll_info.length) 
     470                    collimation_entry['SDD'].attrs['units'] = coll_info.length_unit 
     471                if coll_info.name is not None: 
     472                    collimation_entry['name'] = _h5_string(coll_info.name) 
     473        else: 
     474            collimation_entry = instrument_entry.create_group('sascollimation01') 
     475 
     476        if len(data_info.detector) > 0: 
     477            i = 1 
     478            for det_info in data_info.detector: 
     479                detector_entry = instrument_entry.create_group( 
     480                    'sasdetector{0:0=2d}'.format(i)) 
     481                detector_entry.attrs['canSAS_class'] = 'SASdetector' 
     482                if det_info.distance is not None: 
     483                    detector_entry['SDD'] = _h5_float(det_info.distance) 
     484                    detector_entry['SDD'].attrs['units'] = det_info.distance_unit 
     485                if det_info.name is not None: 
     486                    detector_entry['name'] = _h5_string(det_info.name) 
     487                else: 
     488                    detector_entry['name'] = _h5_string('') 
    447489                i += 1 
    448  
    449             data_info = dataset[0] 
    450             sample_entry = sasentry.create_group('sassample') 
    451             sample_entry.attrs['canSAS_class'] = 'SASsample' 
    452             sample_entry['name'] = _h5_string(data_info.sample.name) 
    453             sample_attrs = ['thickness', 'temperature'] 
    454             for key in sample_attrs: 
    455                 if getattr(data_info.sample, key) is not None: 
    456                     sample_entry.create_dataset(key, data=np.array([getattr(data_info.sample, key)])) 
    457  
    458             instrument_entry = sasentry.create_group('sasinstrument') 
    459             instrument_entry.attrs['canSAS_class'] = 'SASinstrument' 
    460             instrument_entry['name'] = _h5_string(data_info.instrument) 
    461  
    462             source_entry = instrument_entry.create_group('sassource') 
    463             source_entry.attrs['canSAS_class'] = 'SASsource' 
    464             if data_info.source.radiation is None: 
    465                 source_entry['radiation'] = _h5_string('neutron') 
    466             else: 
    467                 source_entry['radiation'] = _h5_string(data_info.source.radiation) 
    468  
    469             if len(data_info.collimation) > 0: 
    470                 i = 1 
    471                 for coll_info in data_info.collimation: 
    472                     collimation_entry = instrument_entry.create_group( 
    473                         'sascollimation{0:0=2d}'.format(i)) 
    474                     collimation_entry.attrs['canSAS_class'] = 'SAScollimation' 
    475                     if coll_info.length is not None: 
    476                         collimation_entry['SDD'] = _h5_float(coll_info.length) 
    477                         collimation_entry['SDD'].attrs['units'] = coll_info.length_unit 
    478                     if coll_info.name is not None: 
    479                         collimation_entry['name'] = _h5_string(coll_info.name) 
    480             else: 
    481                 collimation_entry = instrument_entry.create_group('sascollimation01') 
    482  
    483             if len(data_info.detector) > 0: 
    484                 i = 1 
    485                 for det_info in data_info.detector: 
    486                     detector_entry = instrument_entry.create_group( 
    487                         'sasdetector{0:0=2d}'.format(i)) 
    488                     detector_entry.attrs['canSAS_class'] = 'SASdetector' 
    489                     if det_info.distance is not None: 
    490                         detector_entry['SDD'] = _h5_float(det_info.distance) 
    491                         detector_entry['SDD'].attrs['units'] = det_info.distance_unit 
    492                     if det_info.name is not None: 
    493                         detector_entry['name'] = _h5_string(det_info.name) 
    494                     else: 
    495                         detector_entry['name'] = _h5_string('') 
    496                     i += 1 
    497             else: 
    498                 detector_entry = instrument_entry.create_group('sasdetector01') 
    499                 detector_entry.attrs['canSAS_class'] = 'SASdetector' 
    500                 detector_entry.attrs['name'] = '' 
    501  
    502             # TODO: implement writing SASnote 
    503             note_entry = sasentry.create_group('sasnote{0:0=2d}'.format(i)) 
    504             note_entry.attrs['canSAS_class'] = 'SASnote' 
    505  
    506         elif is_2d: 
    507             f.close() 
    508             raise NotImplementedError("Saving 2D data as CanSAS 2.0 is not yet implemented") 
     490        else: 
     491            detector_entry = instrument_entry.create_group('sasdetector01') 
     492            detector_entry.attrs['canSAS_class'] = 'SASdetector' 
     493            detector_entry.attrs['name'] = '' 
     494 
     495        # TODO: implement writing SASnote 
     496        note_entry = sasentry.create_group('sasnote{0:0=2d}'.format(i)) 
     497        note_entry.attrs['canSAS_class'] = 'SASnote' 
    509498 
    510499        f.close() 
     500 
     501    def _write_1d_data(self, data_obj, data_entry): 
     502        """ 
     503        Writes the contents of a Data1D object to a SASdata h5py Group 
     504 
     505        :param data_obj: A Data1D object to write to the file 
     506        :param data_entry: A h5py Group object representing the SASdata 
     507        """ 
     508        data_entry.attrs['signal'] = 'I' 
     509        data_entry.attrs['I_axes'] = 'Q' 
     510        data_entry.attrs['I_uncertainties'] = 'Idev' 
     511        data_entry.attrs['Q_indicies'] = 0 
     512        data_entry.create_dataset('Q', data=data_obj.x) 
     513        data_entry.create_dataset('I', data=data_obj.y) 
     514        data_entry.create_dataset('Idev', data=data_obj.dy) 
     515 
     516    def _write_2d_data(self, data, data_entry): 
     517        """ 
     518        Writes the contents of a Data2D object to a SASdata h5py Group 
     519 
     520        :param data: A Data2D object to write to the file 
     521        :param data_entry: A h5py Group object representing the SASdata 
     522        """ 
     523        data_entry.attrs['signal'] = 'I' 
     524        data_entry.attrs['I_axes'] = 'Q,Q' 
     525        data_entry.attrs['I_uncertainties'] = 'Idev' 
     526        data_entry.attrs['Q_indicies'] = [0,1] 
     527 
     528        # Calculate rows and columns, assuming detector is square 
     529        # Same logic as used in PlotPanel.py _get_bins 
     530        n_cols = int(np.floor(np.sqrt(len(data.qy_data)))) 
     531        n_rows = int(np.floor(len(data.qy_data) / n_cols)) 
     532 
     533        if n_rows * n_cols != len(data.qy_data): 
     534            raise ValueError("Unable to calculate dimensions of data") 
     535 
     536        I = np.reshape(data.data, (n_rows, n_cols)) 
     537        dI = np.reshape(data.err_data, (n_rows, n_cols)) 
     538        qx =  np.reshape(data.qx_data, (n_rows, n_cols)) 
     539        qy = np.reshape(data.qy_data, (n_rows, n_cols)) 
     540        I_entry = data_entry.create_dataset('I', data=I) 
     541        I_entry.attrs['units'] = data.I_unit 
     542        Qx_entry = data_entry.create_dataset('Qx', data=qx) 
     543        Qx_entry.attrs['units'] = data.Q_unit 
     544        Qy_entry = data_entry.create_dataset('Qy', data=qy) 
     545        Qy_entry.attrs['units'] = data.Q_unit 
    511546 
    512547 
Note: See TracChangeset for help on using the changeset viewer.