Changeset 54ba66e in sasview for src


Ignore:
Timestamp:
Aug 17, 2016 9:12:44 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:
88d85c6
Parents:
254f088
git-author:
Lewis O'Driscoll <lewis.o'driscoll@…> (08/17/16 08:59:36)
git-committer:
Lewis O'Driscoll <lewis.o'driscoll@…> (08/17/16 09:12:44)
Message:

Begin implementation of cansas HDF5 writer

File:
1 edited

Legend:

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

    rd72567e r54ba66e  
    376376        self.current_datainfo = DataInfo() 
    377377 
     378    def write(self, dataset, filename, entry_attrs={ 'title':'', 'run_number':'', 'run_name':'' }): 
     379        """ 
     380        Write an array of Data1d or Data2D objects to a CanSAS 2.0 file, as 
     381        one SASEntry with multiple SASData elements. The metadata of the first 
     382        elememt in the array will be written as the SASentry metadata 
     383        (detector, instrument, sample, etc) 
     384 
     385        :param dataset: A list of Data1D or Data2D objects to write 
     386        :param filename: Where to write the CanSAS 2.0 file 
     387        :entry_attrs: A dictionary containing the attributes of the SASEntry 
     388        """ 
     389        is_1d = all([isinstance(d, Data1D) for d in dataset]) 
     390        is_2d = all([isinstance(d, Data2D) for d in dataset]) 
     391 
     392        if not (is_1d or is_2d): 
     393            msg = ("All elements of dataset must be of the same class " 
     394                "(Data1D or Data2D)") 
     395            raise ValueError(msg) 
     396 
     397        def _h5_string(string): 
     398            """ 
     399            Convert a string to a numpy string in a numpy array. This way it is 
     400            written to the HDF5 file as a fixed length ASCII string and is 
     401            compatible with the Reader read() method. 
     402            """ 
     403            if not isinstance(string, str): 
     404                raise ValueError("String should be of type str") 
     405 
     406            return np.array([np.string_(string)]) 
     407 
     408        f = h5py.File(filename, 'w') 
     409        sasentry = f.create_group('sasentry01') 
     410        sasentry['definition'] = _h5_string('NXcanSAS') 
     411        sasentry['run'] = _h5_string(entry_attrs['run_number']) 
     412        sasentry['run'].attrs['name'] = entry_attrs['run_name'] 
     413        sasentry['title'] = _h5_string(entry_attrs['title']) 
     414        sasentry.attrs['canSAS_class'] = 'SASentry' 
     415        sasentry.attrs['version'] = '1.0' 
     416 
     417        i = 1 
     418 
     419        if is_1d: 
     420            for data_obj in dataset: 
     421                data_entry = sasentry.create_group("sasdata{0:0=2d}".format(i)) 
     422                data_entry.attrs['canSAS_class'] = 'SASdata' 
     423                data_entry.attrs['signal'] = 'I' 
     424                data_entry.attrs['I_axes'] = 'Q' 
     425                data_entry.attrs['I_uncertainties'] = 'Idev' 
     426                data_entry.attrs['Q_indicies'] = 0 
     427                Q_data = data_entry.create_dataset('Q', data=data_obj.x) 
     428                I_data = data_entry.create_dataset('I', data=data_obj.y) 
     429                dI_data = data_entry.create_dataset('Idev', data=data_obj.dy) 
     430                i += 1 
     431 
     432            data_info = dataset[0] 
     433            sample_entry = sasentry.create_group('sassample') 
     434            sample_entry.attrs['canSAS_class'] = 'SASsample' 
     435            sample_entry.attrs['name'] = data_info.sample.name 
     436            sample_entry['ID'] = _h5_string(data_info.sample.name) 
     437            sample_attrs = ['thickness', 'temperature'] 
     438            for key in sample_attrs: 
     439                if getattr(data_info.sample, key) is not None: 
     440                    sample_entry.create_dataset(key, data=np.array([getattr(data_info.sample, key)])) 
     441                    # sample_entry[key] = np.array(getattr(data_info.sample, key), 
     442                    #     dtype=np.float32) 
     443 
     444            instrument_entry = sasentry.create_group('sasinstrument') 
     445            instrument_entry.attrs['canSAS_class'] = 'SASinstrument' 
     446            instrument_entry['name'] = _h5_string(data_info.instrument) 
     447 
     448            source_entry = instrument_entry.create_group('sassource') 
     449            source_entry.attrs['canSAS_class'] = 'SASsource' 
     450            if data_info.source.radiation is None: 
     451                source_entry['radiation'] = _h5_string('neutron') 
     452            else: 
     453                source_entry['radiation'] = _h5_string(data_info.source.radiation) 
     454 
     455            if len(data_info.collimation) > 0: 
     456                i = 1 
     457                for coll_info in data_info.collimation: 
     458                    collimation_entry = instrument_entry.create_group( 
     459                        'sascollimation{0:0=2d}'.format(i)) 
     460                    collimation_entry.attrs['canSAS_class'] = 'SAScollimation' 
     461                    if coll_info.length is not None: 
     462                        collimation_entry['SDD'] = coll_info.length 
     463                        collimation_entry['SDD'].attrs['units'] = coll_info.length_unit 
     464                    if coll_info.name is not None: 
     465                        collimation_entry['name'] = _h5_string(coll_info.name) 
     466            else: 
     467                collimation_entry = instrument_entry.create_group('sascollimation01') 
     468 
     469            if len(data_info.detector) > 0: 
     470                i = 1 
     471                for det_info in data_info.detector: 
     472                    detector_entry = instrument_entry.create_group( 
     473                        'sasdetector{0:0=2d}'.format(i)) 
     474                    detector_entry.attrs['casnSAS_class'] = 'SASdetector' 
     475                    if det_info.distance is not None: 
     476                        detector_entry['SDD'] = det_info.distance 
     477                        detector_entry['SDD'].attrs['units'] = det_info.distance_unit 
     478                    if det_info.name is not None: 
     479                        detector_entry['name'] = _h5_string(det_info.name) 
     480                    else: 
     481                        detector_entry['name'] = _h5_string('') 
     482            else: 
     483                detector_entry = instrument_entry.create_group('sasdetector01') 
     484                detector_entry.attrs['casnSAS_class'] = 'SASdetector' 
     485                detector_entry.attrs['name'] = '' 
     486 
     487            # TODO: implement writing SASnote 
     488            note_entry = sasentry.create_group('sasnote{0:0=2d}'.format(i)) 
     489            note_entry.attrs['canSAS_class'] = 'SASnote' 
     490 
     491        elif is_2d: 
     492            f.close() 
     493            raise NotImplementedError("Saving 2D data as CanSAS 2.0 is not yet implemented") 
     494 
     495        f.close() 
     496 
     497 
    378498    def _initialize_new_data_set(self, parent_list = None): 
    379499        """ 
Note: See TracChangeset for help on using the changeset viewer.