Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] : Nanosurf file format #90

Open
alicepyne opened this issue Dec 12, 2024 · 2 comments
Open

[feature] : Nanosurf file format #90

alicepyne opened this issue Dec 12, 2024 · 2 comments
Assignees
Labels
enhancement New feature or request v0.1.0

Comments

@alicepyne
Copy link
Member

Is your feature request related to a problem?

Nanosurf software can export images to gwyddion file format, but they now have their own fileformat and python code for reading in their python library: https://pypi.org/project/nanosurf/ (install from command line by pip install nanosurf; or pip install -U nanosurf for upgrading).

Describe the solution you would like.

In nanosurf\lib\util, you’ll find nhf_reader.py there are ready-to-use functions to load our NHF files with python. Contact point for questions is Benjamin Titze (cc-ed). It is hoped we can largely copy and paste existing functions to implement Nanosurf NHF file format support into AFMReader.

Describe the alternatives you have considered.

N/A

Sample Image

N/A

Additional context

This is following an email request from Bart Hoogenboom and Benjamin Titze

@alicepyne alicepyne added the enhancement New feature or request label Dec 12, 2024
@ns-rse ns-rse added this to the Expand supported file formats milestone Dec 16, 2024
@ns-rse ns-rse added the v0.1.0 label Dec 16, 2024
@ns-rse
Copy link
Collaborator

ns-rse commented Dec 17, 2024

Add nanosurf as a dependency and use their functions rather than copying and pasting code over. That way when the file specification changes in the future we pull in the updates automatically.

@ns-rse ns-rse self-assigned this Feb 11, 2025
@ns-rse
Copy link
Collaborator

ns-rse commented Feb 11, 2025

After some messing around with nanosurf I did some searching and found this video
tutorial
on
loading and working with files and have started using the NSFopen and have started
work on using this to extract data.

There are a bunch of sample files included in the package itself along with Jupyter Notebooks and Python scripts (see
<path/to/env/lib/python<version>/site-packages/NSFopen/example/*).

# 2025-02-11 - NSFopen
from pathlib import Path
from typing import Any
from NSFopen.read import read
import NSFopen


BASE_DIR = Path.cwd()
TMP_DIR = BASE_DIR / "tmp"
NSF_DIR = TMP_DIR / "nsfopen"
NSF_PATHS = list(NSF_DIR.glob("**/*.nid"))
nsf_files = {nsf_path.stem: read(nsf_path) for nsf_path in NSF_PATHS}


def extract_features(nsf_file: NSFopen.read, direction: str = "Forward") -> dict[str, Any]:
    """Extract features."""
    return {"shape": nsf_file.param.shape, "data": nsf_file.data}


extracted_data = {key: extract_features(read) for key, read in nsf_files.items()}

Looking at the data there is...

In [70]: nsf_files["grid"].data
Out[70]:
Image  Forward   Z-Axis       [[7.186671541805752e-07, 7.188438053975441e-07...
                 Amplitude    [[0.32497746869921684, 0.3225776180624962, 0.3...
                 Phase        [[81.04582741856575, 80.40699429810047, 79.109...
       Backward  Z-Axis       [[7.196525316214748e-07, 7.216558547009155e-07...
                 Amplitude    [[0.33070050179958344, 0.3338928334414959, 0.3...
                 Phase        [[80.04852812737226, 78.79850942641497, 77.087...
dtype: object

...and a lot of parameters

In [77]: dir(nsf_files["grid"].param)
Out[77]:
['HeaderDump',
 'Scan',
 'Spec',
 'T',
 'Tip',
 'X',
 'Y',
 'Z',
 '_AXIS_LEN',
 '_AXIS_ORDERS',
 '_AXIS_TO_AXIS_NUMBER',
 '_HANDLED_TYPES',
 '__abs__',
 '__add__',
 '__and__',
 '__annotations__',
 '__array__',
 '__array_priority__',
 '__array_ufunc__',
 '__bool__',
 '__class__',
 '__column_consortium_standard__',
 '__contains__',
 '__copy__',
 '__deepcopy__',
 '__delattr__',
 '__delitem__',
 '__dict__',
 '__dir__',
 '__divmod__',
 '__doc__',
 '__eq__',
 '__finalize__',
 '__firstlineno__',
 '__float__',
 '__floordiv__',
 '__format__',
 '__ge__',
 '__getattr__',
 '__getattribute__',
 '__getitem__',
 '__getstate__',
 '__gt__',
 '__hash__',
 '__iadd__',
 '__iand__',
 '__ifloordiv__',
 '__imod__',
 '__imul__',
 '__init__',
 '__init_subclass__',
 '__int__',
 '__invert__',
 '__ior__',
 '__ipow__',
 '__isub__',
 '__iter__',
 '__itruediv__',
 '__ixor__',
 '__le__',
 '__len__',
 '__lt__',
 '__matmul__',
 '__mod__',
 '__module__',
 '__mul__',
 '__ne__',
 '__neg__',
 '__new__',
 '__nonzero__',
 '__or__',
 '__pandas_priority__',
 '__pos__',
 '__pow__',
 '__radd__',
 '__rand__',
 '__rdivmod__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__rfloordiv__',
 '__rmatmul__',
 '__rmod__',
 '__rmul__',
 '__ror__',
 '__round__',
 '__rpow__',
 '__rsub__',
 '__rtruediv__',
 '__rxor__',
 '__setattr__',
 '__setitem__',
 '__setstate__',
 '__sizeof__',
 '__static_attributes__',
 '__str__',
 '__sub__',
 '__subclasshook__',
 '__truediv__',
 '__weakref__',
 '__xor__',
 '_accessors',
 '_accum_func',
 '_agg_examples_doc',
 '_agg_see_also_doc',
 '_align_for_op',
 '_align_frame',
 '_align_series',
 '_append',
 '_arith_method',
 '_as_manager',
 '_attrs',
 '_binop',
 '_can_hold_na',
 '_check_inplace_and_allows_duplicate_labels',
 '_check_is_chained_assignment_possible',
 '_check_label_or_level_ambiguity',
 '_check_setitem_copy',
 '_clear_item_cache',
 '_clip_with_one_bound',
 '_clip_with_scalar',
 '_cmp_method',
 '_consolidate',
 '_consolidate_inplace',
 '_construct_axes_dict',
 '_construct_result',
 '_constructor',
 '_constructor_expanddim',
 '_constructor_expanddim_from_mgr',
 '_constructor_from_mgr',
 '_data',
 '_deprecate_downcast',
 '_dir_additions',
 '_dir_deletions',
 '_drop_axis',
 '_drop_labels_or_levels',
 '_duplicated',
 '_find_valid_index',
 '_flags',
 '_flex_method',
 '_from_mgr',
 '_get_axis',
 '_get_axis_name',
 '_get_axis_number',
 '_get_axis_resolvers',
 '_get_block_manager_axis',
 '_get_bool_data',
 '_get_cacher',
 '_get_cleaned_column_resolvers',
 '_get_index_resolvers',
 '_get_label_or_level_values',
 '_get_numeric_data',
 '_get_rows_with_mask',
 '_get_value',
 '_get_values_tuple',
 '_get_with',
 '_getitem_slice',
 '_gotitem',
 '_hidden_attrs',
 '_indexed_same',
 '_info_axis',
 '_info_axis_name',
 '_info_axis_number',
 '_init_dict',
 '_init_mgr',
 '_inplace_method',
 '_internal_names',
 '_internal_names_set',
 '_is_cached',
 '_is_copy',
 '_is_label_or_level_reference',
 '_is_label_reference',
 '_is_level_reference',
 '_is_mixed_type',
 '_is_view',
 '_is_view_after_cow_rules',
 '_item_cache',
 '_ixs',
 '_logical_func',
 '_logical_method',
 '_map_values',
 '_maybe_update_cacher',
 '_memory_usage',
 '_metadata',
 '_mgr',
 '_min_count_stat_function',
 '_name',
 '_needs_reindex_multi',
 '_pad_or_backfill',
 '_protect_consolidate',
 '_reduce',
 '_references',
 '_reindex_axes',
 '_reindex_indexer',
 '_reindex_multi',
 '_reindex_with_indexers',
 '_rename',
 '_replace_single',
 '_repr_data_resource_',
 '_repr_latex_',
 '_reset_cache',
 '_reset_cacher',
 '_set_as_cached',
 '_set_axis',
 '_set_axis_name',
 '_set_axis_nocheck',
 '_set_is_copy',
 '_set_labels',
 '_set_name',
 '_set_value',
 '_set_values',
 '_set_with',
 '_set_with_engine',
 '_shift_with_freq',
 '_slice',
 '_stat_function',
 '_stat_function_ddof',
 '_take_with_is_copy',
 '_to_latex_via_styler',
 '_typ',
 '_update_inplace',
 '_validate_dtype',
 '_values',
 '_where',
 'abs',
 'add',
 'add_prefix',
 'add_suffix',
 'agg',
 'aggregate',
 'align',
 'all',
 'any',
 'apply',
 'argmax',
 'argmin',
 'argsort',
 'array',
 'asfreq',
 'asof',
 'astype',
 'at',
 'at_time',
 'attrs',
 'autocorr',
 'axes',
 'backfill',
 'between',
 'between_time',
 'bfill',
 'bool',
 'case_when',
 'clip',
 'combine',
 'combine_first',
 'compare',
 'convert_dtypes',
 'copy',
 'corr',
 'count',
 'cov',
 'cummax',
 'cummin',
 'cumprod',
 'cumsum',
 'describe',
 'diff',
 'div',
 'divide',
 'divmod',
 'dot',
 'drop',
 'drop_duplicates',
 'droplevel',
 'dropna',
 'dtype',
 'dtypes',
 'duplicated',
 'empty',
 'eq',
 'equals',
 'ewm',
 'expanding',
 'explode',
 'factorize',
 'ffill',
 'fillna',
 'filter',
 'first',
 'first_valid_index',
 'flags',
 'floordiv',
 'ge',
 'get',
 'groupby',
 'gt',
 'hasnans',
 'head',
 'hist',
 'iat',
 'idxmax',
 'idxmin',
 'iloc',
 'index',
 'infer_objects',
 'info',
 'interpolate',
 'is_monotonic_decreasing',
 'is_monotonic_increasing',
 'is_unique',
 'isin',
 'isna',
 'isnull',
 'item',
 'items',
 'keys',
 'kurt',
 'kurtosis',
 'last',
 'last_valid_index',
 'le',
 'list',
 'loc',
 'lt',
 'map',
 'mask',
 'max',
 'mean',
 'median',
 'memory_usage',
 'min',
 'mod',
 'mode',
 'mul',
 'multiply',
 'name',
 'nbytes',
 'ndim',
 'ne',
 'nlargest',
 'notna',
 'notnull',
 'nsmallest',
 'nunique',
 'pad',
 'pct_change',
 'pipe',
 'plot',
 'pop',
 'pow',
 'prod',
 'product',
 'quantile',
 'radd',
 'rank',
 'ravel',
 'rdiv',
 'rdivmod',
 'reindex',
 'reindex_like',
 'rename',
 'rename_axis',
 'reorder_levels',
 'repeat',
 'replace',
 'resample',
 'reset_index',
 'rfloordiv',
 'rmod',
 'rmul',
 'rolling',
 'round',
 'rpow',
 'rsub',
 'rtruediv',
 'sample',
 'searchsorted',
 'sem',
 'set_axis',
 'set_flags',
 'shape',
 'shift',
 'size',
 'skew',
 'sort_index',
 'sort_values',
 'squeeze',
 'std',
 'str',
 'struct',
 'sub',
 'subtract',
 'sum',
 'swapaxes',
 'swaplevel',
 'tail',
 'take',
 'to_clipboard',
 'to_csv',
 'to_dict',
 'to_excel',
 'to_frame',
 'to_hdf',
 'to_json',
 'to_latex',
 'to_list',
 'to_markdown',
 'to_numpy',
 'to_period',
 'to_pickle',
 'to_sql',
 'to_string',
 'to_timestamp',
 'to_xarray',
 'transform',
 'transpose',
 'truediv',
 'truncate',
 'tz_convert',
 'tz_localize',
 'unique',
 'unstack',
 'update',
 'value_counts',
 'values',
 'var',
 'view',
 'where',
 'xs']

This leads me to ask the first of will no doubt be many questions...

  • What data should be extracted? We can make whether Forward or Backward is extracted configurable but would anyone
    ever want both?
  • Which of Z-Axis, Amplitude and Phase should be extracted by default? Again we can make this configurable but
    what would people expect by default?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request v0.1.0
Projects
None yet
Development

No branches or pull requests

2 participants