Last active
July 16, 2024 11:13
-
-
Save carlodri/66c471498e6b52caf213 to your computer and use it in GitHub Desktop.
Simple Python I/O functions for the Gwyddion Simple Field (.gsf) format
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def gsf_read(file_name): | |
| '''Read a Gwyddion Simple Field 1.0 file format | |
| http://gwyddion.net/documentation/user-guide-en/gsf.html | |
| Args: | |
| file_name (string): the name of the output (any extension will be replaced) | |
| Returns: | |
| metadata (dict): additional metadata to be included in the file | |
| data (2darray): an arbitrary sized 2D array of arbitrary numeric type | |
| ''' | |
| if file_name.rpartition('.')[1] == '.': | |
| file_name = file_name[0:file_name.rfind('.')] | |
| gsfFile = open(file_name + '.gsf', 'rb') | |
| metadata = {} | |
| # check if header is OK | |
| if not(gsfFile.readline().decode('UTF-8') == 'Gwyddion Simple Field 1.0\n'): | |
| gsfFile.close() | |
| raise ValueError('File has wrong header') | |
| term = b'00' | |
| # read metadata header | |
| while term != b'\x00': | |
| line_string = gsfFile.readline().decode('UTF-8') | |
| metadata[line_string.rpartition(' = ')[0]] = line_string.rpartition('=')[2] | |
| term = gsfFile.read(1) | |
| gsfFile.seek(-1, 1) | |
| gsfFile.read(4 - gsfFile.tell() % 4) | |
| #fix known metadata types from .gsf file specs | |
| #first the mandatory ones... | |
| metadata['XRes'] = np.int(metadata['XRes']) | |
| metadata['YRes'] = np.int(metadata['YRes']) | |
| #now check for the optional ones | |
| if 'XReal' in metadata: | |
| metadata['XReal'] = np.float(metadata['XReal']) | |
| if 'YReal' in metadata: | |
| metadata['YReal'] = np.float(metadata['YReal']) | |
| if 'XOffset' in metadata: | |
| metadata['XOffset'] = np.float(metadata['XOffset']) | |
| if 'YOffset' in metadata: | |
| metadata['YOffset'] = np.float(metadata['YOffset']) | |
| data = np.frombuffer(gsfFile.read(),dtype='float32').reshape(metadata['YRes'],metadata['XRes']) | |
| gsfFile.close() | |
| return metadata, data |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def gsf_write(data, file_name, metadata={}): | |
| '''Write a 2D array to a Gwyddion Simple Field 1.0 file format | |
| http://gwyddion.net/documentation/user-guide-en/gsf.html | |
| Args: | |
| file_name (string): the name of the output (any extension will be replaced) | |
| data (2darray): an arbitrary sized 2D array of arbitrary numeric type | |
| metadata (dict): additional metadata to be included in the file | |
| Returns: | |
| nothing | |
| ''' | |
| XRes = data.shape[0] | |
| YRes = data.shape[1] | |
| data = data.astype('float32') | |
| if file_name.rpartition('.')[1] == '.': | |
| file_name = file_name[0:file_name.rfind('.')] | |
| gsfFile = open(file_name + '.gsf', 'wb') | |
| s = '' | |
| s += 'Gwyddion Simple Field 1.0' + '\n' | |
| s += 'XRes = {0:d}'.format(XRes) + '\n' | |
| s += 'YRes = {0:d}'.format(YRes) + '\n' | |
| for i in metadata.keys(): | |
| try: | |
| s += i + ' = ' + '{0:G}'.format(metadata[i]) + '\n' | |
| except: | |
| s += i + ' = ' + str(metadata[i]) + '\n' | |
| gsfFile.write(bytes(s, 'UTF-8')) | |
| gsfFile.write(b'\x00' * (4 - len(s) % 4)) | |
| gsfFile.write(data.tobytes(None)) | |
| gsfFile.close() |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To everyone interested in this: the tool has been published as a Python package (gsffile) thanks to the great review and rework of my dear friend @angelo-peronio! 🚀
It is available on PyPI and very soon on conda-forge.