From 7cdfbf7dc069d689b85da31033597e73b9a9fc79 Mon Sep 17 00:00:00 2001 From: Lukas Pielsticker <50139597+lukaspie@users.noreply.github.com> Date: Wed, 27 Nov 2024 21:54:37 +0100 Subject: [PATCH] bring in examples from north --- src/pynxtools_mpes/nomad/entrypoints.py | 1 + .../nomad/examples/E2 Binning of WSe2.ipynb | 711 ------------------ .../nomad/examples/MoTe.archive.json | 2 +- src/pynxtools_mpes/nomad/examples/README.md | 1 + .../nomad/examples/config_file_MoTe2.json | 419 ----------- .../nomad/examples/downloads.archive.yaml | 4 +- tests/test_nomad_examples.py | 3 +- 7 files changed, 7 insertions(+), 1134 deletions(-) delete mode 100644 src/pynxtools_mpes/nomad/examples/E2 Binning of WSe2.ipynb delete mode 100644 src/pynxtools_mpes/nomad/examples/config_file_MoTe2.json diff --git a/src/pynxtools_mpes/nomad/entrypoints.py b/src/pynxtools_mpes/nomad/entrypoints.py index 569b00c..1208d53 100644 --- a/src/pynxtools_mpes/nomad/entrypoints.py +++ b/src/pynxtools_mpes/nomad/entrypoints.py @@ -34,6 +34,7 @@ There exists a [NeXus application definition for MPES](https://manual.nexusformat.org/classes/contributed_definitions/NXmpes.html#nxmpes) which details the internal structure of such a file. - Binning of raw data (see [here](https://www.nature.com/articles/s41597-020-00769-8) for additional resources) into a h5 file and consecutively generating a NeXus file from it. - An analysis example using data in the NeXus format and employing the [pyARPES](https://github.com/chstan/arpes) analysis tool to reproduce the main findings of [this paper](https://arxiv.org/pdf/2107.07158.pdf). + - Importing angle-resolved data stored in NXmpes_arpes, and convert these into momentum space coordinates using tools in pyARPES. """, plugin_package="pynxtools_mpes", resources=["nomad/examples/*"], diff --git a/src/pynxtools_mpes/nomad/examples/E2 Binning of WSe2.ipynb b/src/pynxtools_mpes/nomad/examples/E2 Binning of WSe2.ipynb deleted file mode 100644 index eed9baf..0000000 --- a/src/pynxtools_mpes/nomad/examples/E2 Binning of WSe2.ipynb +++ /dev/null @@ -1,711 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Binning raw Multidimensional Photoemission Spectroscopy (MPES) data and converting it into the NeXus format" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This example shows how to generate xarray based h5 files from WSe2 trARPES measurement data as detailed in this [paper](https://www.nature.com/articles/s41597-020-00769-8) and how to generate a file in the standardised [MPES NeXus format](https://manual.nexusformat.org/classes/contributed_definitions/NXmpes.html#nxmpes) from it.\n", - "Due to the size of the example file (~6GB) you need at least 40 GB of memory on your computer you're executing this example on. If you just want to have a look on how to convert a pre-binned xarray based h5 file into the NeXus format you may have a look at the simpler [Convert to NeXus example](./E1%20Convert%20to%20NeXus.ipynb), which has lower hardware requirements." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Download RAW data (trARPES data of WSe2)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "Here, we just set the main file folder for holding the measurement data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "FDIR = f'{os.getcwd()}/Scan049_1'\n", - "ECAL = f'{os.getcwd()}/energycal_2019_01_08'" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Since the provided measurement files are rather large (~6GB), they are not directly provided with the example.\n", - "You can [download](https://zenodo.org/record/6369728/files/WSe2.zip) it from zenodo. This may take some time. Place the file in the directory of this notebook afterwards. Under Linux, macOS and in a NORTH container you can directly use the cell below to download the file with curl." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "! curl -o WSe2.zip \"https://zenodo.org/records/6369728/files/WSe2.zip\"" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we extract the measurement files." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "! unzip WSe2.zip" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Binning of measurement data" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First we import the necessary packages. For a manual on how to install this dependencies refer to the provided [INSTALL.md](./INSTALL.md) file. If you're running a pre-built docker container or working with the NORTH tools, these dependencies are already available for you." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from mpes import base as base, fprocessing as fp, analysis as aly\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import os\n", - "from dask import compute\n", - "import datetime as dt\n", - "import h5py" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Initial data binning for distortion correction" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "parp = fp.parallelHDF5Processor(folder=FDIR)\n", - "parp.gather(identifier=r'/*.h5', file_sorting=True)\n", - "len(parp.files)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Bin a small range of of files to create a momentum map for distortion correction\n", - "parp.files = parp.files[0:50]\n", - "axes = ['X', 'Y', 't']\n", - "# Important to keep the whole detector area for the initial binning!\n", - "bins = [512, 512, 300]\n", - "ranges = [(0, 2048), (0, 2048), (64000, 68000)]\n", - "parp.parallelBinning(axes=axes, nbins=bins, ranges=ranges, scheduler='threads', ret=False)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Determine correction landmarks" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Select an energy slice at the valence band maximum, containing the 6 K-points and the Gamma point as distinct features\n", - "mc = aly.MomentumCorrector(parp.combinedresult['binned'])\n", - "mc.selectSlice2D(slice(165, 175), 2)\n", - "# Extract these high-symmetry points \n", - "mc.featureExtract(mc.slice, sigma=5, fwhm=10, sigma_radius=3)\n", - "mc.view(points=mc.features, annotated=True)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Calculate thin plate spline symmetry correction" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate a non-linear coordinate transformation based on thin plate splines that restores 6-fold symmetry\n", - "mc.splineWarpEstimate(image=mc.slice, landmarks=mc.pouter_ord, include_center=True,\n", - " iterative=False, interp_order=2, update=True)\n", - "mc.view(image=mc.slice_transformed, annotated=True, points={'feats':mc.ptargs}, backend='bokeh', crosshair=True, radii=[75,110,150], crosshair_thickness=0.2)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Image registration" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Apply a coordinate translation to move the image into the center of the detector\n", - "mc.coordinateTransform(type='translation', xtrans=70., ytrans=70., keep=True)\n", - "plt.imshow(mc.slice_transformed, origin='lower', cmap='terrain_r')\n", - "plt.axvline(x=256)\n", - "plt.axhline(y=256)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Rotate the image into a high-symmetry direction\n", - "mc.coordinateTransform( type='rotation', angle=-5, center=(256., 256.), keep=True)\n", - "plt.imshow(mc.slice_transformed, origin='lower', cmap='terrain_r')\n", - "plt.axvline(x=256)\n", - "plt.axhline(y=256)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Display the final deformation field\n", - "subs = 20\n", - "plt.scatter(mc.cdeform_field[::subs,::subs].ravel(), mc.rdeform_field[::subs,::subs].ravel(), c='b')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Momentum calibration" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Pick one high-symmetry point\n", - "point_b = [252.,255.]\n", - "# Pick the BZ center\n", - "point_a = [308.,346.]\n", - "# give the distance of the two in inverse Angstrom\n", - "distance = np.pi*4/3/3.297\n", - "# Momentum calibration assuming equal scaling along both x and y directions (equiscale=True)\n", - "# Requirements : pixel coordinates of and the momentum space distance between two symmetry points, \n", - "# plus the momentum coordinates\n", - "# of one of the two points \n", - "ext = mc.calibrate(mc.slice_transformed,\n", - " point_from=point_a,\n", - " point_to=point_b,\n", - " dist=distance,\n", - " equiscale=True,\n", - " ret=['extent'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Display corrected image in calibrated coordinates\n", - "mc.view(image=mc.slice_transformed, imkwds=ext)\n", - "plt.xlabel('$k_x$', fontsize=15)\n", - "plt.ylabel('$k_y$', fontsize=15)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Energy calibration" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Bin traces for energy calibration\n", - "axes = ['t']\n", - "bins = [1000]\n", - "ranges = [(63000, 80000)]\n", - "traces, tof = fp.extractEDC(folder=ECAL,\n", - " axes=axes, bins=bins, ranges=ranges)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Applied bias voltages (negated, in order to achieve negative binding energies, E-E_F)\n", - "voltages = np.arange(-12.2, -23.2, -1)\n", - "ec = aly.EnergyCalibrator(biases=voltages, traces=traces, tof=tof)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Normalize traces to maximum\n", - "ec.normalize(smooth=True, span=7, order=1)\n", - "ec.view(traces=ec.traces_normed, xaxis=ec.tof, backend='bokeh')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Define a TOF feature range, and translate it for each of the traces according to their shift in bias voltage\n", - "rg = [(65000, 65200)]\n", - "ec.addFeatures(traces=ec.traces_normed, refid=0, ranges=rg[0], infer_others=True, mode='append')\n", - "ec.featranges" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Extract the first peak from each feature range\n", - "ec.featureExtract(traces=ec.traces_normed, ranges=ec.featranges)\n", - "ec.view(traces=ec.traces_normed, peaks=ec.peaks, backend='bokeh')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Calculate energy calibration" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# calculate the energy calibration (3rd order polynom). Eref corresponds to the binding energy (E-E_F) of the selected feature in the refid trace.\n", - "refid=5\n", - "Eref=-1.3\n", - "axs = ec.calibrate(ret='all', Eref=Eref, t=ec.tof, refid=refid)\n", - "ec.view(traces=ec.traces_normed, xaxis=ec.calibration['axis'], backend='bokeh')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Quality of calibration" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# inspect the quality of the energy calibration\n", - "for i in range(0,len(voltages)):\n", - " plt.plot(ec.calibration['axis']-(voltages[i]-voltages[refid]), ec.traces_normed[i])\n", - "plt.xlim([-15,5])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Inspect calibration function" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# energy calibration function vs. TOF\n", - "ec.view(traces=ec.calibration['axis'][None,:], xaxis=ec.tof, backend='matplotlib', show_legend=False)\n", - "plt.scatter(ec.peaks[:,0], ec.biases-ec.biases[refid]+Eref, s=50, c='k')\n", - "plt.xlabel('Time-of-flight', fontsize=15)\n", - "plt.ylabel('Energy (eV)', fontsize=15)\n", - "plt.ylim([-8,6])\n", - "plt.xlim([63400,69800])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Dataframe processor" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# create the dask data frame processor\n", - "dfp = fp.dataframeProcessor(datafolder=FDIR)\n", - "dfp.read(source='folder', ftype='h5', timeStamps=True)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Apply energy calibration" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# apply the energy calibration\n", - "dfp.appendEAxis(E0=ec.calibration['E0'], a=ec.calibration['coeffs'])\n", - "dfp.edf.head(8)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Apply distortion correction" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# apply the distortion correction\n", - "dfp.applyKCorrection(type='tps_matrix',\n", - " rdeform_field = mc.rdeform_field,\n", - " cdeform_field = mc.cdeform_field,\n", - " X='X', Y='Y', newX='Xm', newY='Ym')\n", - "dfp.edf.head(8)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Apply momentum calibration" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# apply the momentum calibration\n", - "dfp.appendKAxis(point_b[0], point_b[1], X='Xm', Y='Ym', rstart=parp.binranges[0][0],\n", - " cstart=parp.binranges[1][0],\n", - " rstep=parp.binsteps[0],\n", - " cstep=parp.binsteps[1],\n", - " fc=mc.calibration['coeffs'][0],\n", - " fr=mc.calibration['coeffs'][1])\n", - "dfp.edf.head(8)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Apply pump-probe delay axis conversion" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# calculate the pump-probe delay from the ADC coordinates\n", - "ADCRange = (650, 6900)\n", - "timeRange = (-100, 200)\n", - "dfp.edf['delay'] = timeRange[0] + (dfp.edf['ADC']-ADCRange[0]) *\\\n", - " (timeRange[1] - timeRange[0])/(ADCRange[1]-ADCRange[0])\n", - "dfp.edf.head(8)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Bin 4D data in transformed grid" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# process the 4-dimensional binning\n", - "axes = ['kx', 'ky', 'E', 'delay']\n", - "bins = [50, 50, 100, 21]\n", - "ranges = [(-2, 2), (-2, 2), (-3, 2), (-110, 190)]\n", - "# jittering of energy and ADC should best be done on the bin size of the hardware, \n", - "# not the rebinned bin size. This requires reverse-calculating the jitter amplitudes\n", - "# from the bin sizes.\n", - "TOFrange=[64500,67000]\n", - "e_t_conversion = (base.tof2evpoly(ec.calibration['coeffs'],\n", - " ec.calibration['E0'], \n", - " TOFrange[0])\n", - " - base.tof2evpoly(ec.calibration['coeffs'],\n", - " ec.calibration['E0'], TOFrange[1])\n", - " ) / (TOFrange[1] - TOFrange[0])\n", - "d_adc_conversion = (timeRange[1] - timeRange[0]) / (ADCRange[1] - ADCRange[0])\n", - "jitter_amplitude = [0.5,\n", - " 0.5,\n", - " 1*bins[2]/abs(ranges[2][1]-ranges[2][0])*e_t_conversion,\n", - " 1*bins[3]/abs(ranges[3][1]-ranges[3][0])*d_adc_conversion]\n", - "dfp.distributedBinning(axes=axes,\n", - " nbins=bins,\n", - " ranges=ranges,\n", - " scheduler='threads',\n", - " ret=False,\n", - " jittered=True,\n", - " jitter_amplitude=jitter_amplitude)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Run the following cell to store metadata from EPICS archive only if outside the FHI network\n", - "This adds additional metadata to the xarray. This data may also be provided through additional ELN entries through a NOMAD instance or with a handwritten file directly to the mpes parser." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "metadata = {\"file\": {}}\n", - "metadata['file'][\"KTOF:Lens:Extr:I\"] = -0.12877\n", - "metadata['file'][\"KTOF:Lens:UDLD:V\"] = 399.99905\n", - "metadata['file'][\"KTOF:Lens:Sample:V\"] = 17.19976\n", - "metadata['file'][\"KTOF:Apertures:m1.RBV\"] = 3.729931\n", - "metadata['file'][\"KTOF:Apertures:m2.RBV\"] = -5.200078\n", - "metadata['file'][\"KTOF:Apertures:m3.RBV\"] = -11.000425\n", - "\n", - "# Sample motor positions\n", - "metadata['file']['trARPES:Carving:TRX.RBV'] = 7.1900000000000004\n", - "metadata['file']['trARPES:Carving:TRY.RBV'] = -6.1700200225439552\n", - "metadata['file']['trARPES:Carving:TRZ.RBV'] = 33.4501953125\n", - "metadata['file']['trARPES:Carving:THT.RBV'] = 423.30500940561586\n", - "metadata['file']['trARPES:Carving:PHI.RBV'] = 0.99931647456264949\n", - "metadata['file']['trARPES:Carving:OMG.RBV'] = 11.002500171914066" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Generate xarray\n", - "Remember to remove the optional argument, metadata_dict, from the gather_metadata() function if the previous cell was not run.\n", - "The missing archive metadata warnings are not critical for this example and can thus be ignored." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import copy\n", - "res_xarray = dfp.gather_metadata(metadata_dict=copy.deepcopy(metadata), ec=ec, mc=mc)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## Create a NeXus file from a xarray\n", - "This conversion basically follows the same procedure as in the [convert to NeXus example](./E1%20Convert%20to%20Nexus.ipynb). Please refer to this notebook for details on the convert function. Here, we are using the objects keywords of `convert` to pass the generated xarray directly, instead of loading a h5 datafile." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from pynxtools.dataconverter.convert import convert" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "convert(input_file=[\"config_file.json\", \"WSe2_eln.yaml\"],\n", - " objects=res_xarray,\n", - " reader='mpes',\n", - " nxdl='NXmpes',\n", - " output='WSe2.mpes.nxs')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "tags": [] - }, - "source": [ - "## View the data with H5Web\n", - "H5Web is a tool for visualizing any data in the h5 data format. Since the NeXus format builds opon h5 it can be used to view this data as well. We just import the package and call H5Web with the output filename from the convert command above. For an analysis on NeXus data files please refer to [analysis example](./E3%20pyARPES%20analysis.ipynb).\n", - "\n", - "You can also view this data with the H5Viewer or other tools from your local filesystem." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from jupyterlab_h5web import H5Web" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "H5Web('WSe2.mpes.nxs')" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.4" - }, - "vscode": { - "interpreter": { - "hash": "c2ecc4d45d4efcd07af778d75fd26bf86d0642a6646ea5c57f06d5857684e419" - } - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": {}, - "version_major": 2, - "version_minor": 0 - } - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/src/pynxtools_mpes/nomad/examples/MoTe.archive.json b/src/pynxtools_mpes/nomad/examples/MoTe.archive.json index 3b2b334..21bf872 100644 --- a/src/pynxtools_mpes/nomad/examples/MoTe.archive.json +++ b/src/pynxtools_mpes/nomad/examples/MoTe.archive.json @@ -3,7 +3,7 @@ "m_def": "pynxtools.nomad.dataconverter.NexusDataConverter", "input_files": [ "MoTe2.h5", - "config_file_MoTe2.json" + "config_file.json" ], "reader": "mpes", "nxdl": "NXmpes", diff --git a/src/pynxtools_mpes/nomad/examples/README.md b/src/pynxtools_mpes/nomad/examples/README.md index 4b4a8c3..e7967bc 100644 --- a/src/pynxtools_mpes/nomad/examples/README.md +++ b/src/pynxtools_mpes/nomad/examples/README.md @@ -5,6 +5,7 @@ This example presents the capabilities of the NOMAD platform to store and standa - Taking a pre-binned file, here stored in a h5 file, and converting it into the standardized MPES NeXus format. There exists a [NeXus application definition for MPES](https://manual.nexusformat.org/classes/contributed_definitions/NXmpes.html#nxmpes) which details the internal structure of such a file. - Binning of raw data (see [here](https://www.nature.com/articles/s41597-020-00769-8) for additional resources) into a h5 file and consecutively generating a NeXus file from it. - An analysis example using data in the NeXus format and employing the [pyARPES](https://github.com/chstan/arpes) analysis tool to reproduce the main findings of [this paper](https://arxiv.org/pdf/2107.07158.pdf). +- Importing angle-resolved data stored in NXmpes_arpes, and convert these into momentum space coordinates using tools in pyARPES. # Viewing uploaded data diff --git a/src/pynxtools_mpes/nomad/examples/config_file_MoTe2.json b/src/pynxtools_mpes/nomad/examples/config_file_MoTe2.json deleted file mode 100644 index d08c6c1..0000000 --- a/src/pynxtools_mpes/nomad/examples/config_file_MoTe2.json +++ /dev/null @@ -1,419 +0,0 @@ -{ - "/@default": "entry", - "/ENTRY/@default": "data", - "/ENTRY/title": "@attrs:metadata/entry_title", - "/ENTRY/start_time": "@attrs:metadata/timing/acquisition_start", - "/ENTRY/experiment_institution": "Fritz Haber Institute - Max Planck Society", - "/ENTRY/experiment_facility": "Time Resolved ARPES", - "/ENTRY/experiment_laboratory": "Clean Room 4", - "/ENTRY/entry_identifier": { - "identifier":"@attrs:metadata/entry_identifier" - }, - "/ENTRY/end_time": "@attrs:metadata/timing/acquisition_stop", - "/ENTRY/duration": "@attrs:metadata/timing/acquisition_duration", - "/ENTRY/duration/@units": "s", - "/ENTRY/collection_time": "@attrs:metadata/timing/collection_time", - "/ENTRY/collection_time/@units": "s", - "/ENTRY/USER[user]": { - "name": "@attrs:metadata/user0/name", - "role": "@attrs:metadata/user0/role", - "affiliation": "@attrs:metadata/user0/affiliation", - "address": "@attrs:metadata/user0/address", - "email": "@attrs:metadata/user0/email" - }, - "/ENTRY/INSTRUMENT[instrument]": { - "name": "Time-of-flight momentum microscope equipped delay line detector, at the endstation of the high rep-rate HHG source at FHI", - "name/@short_name": "TR-ARPES @ FHI", - "energy_resolution": { - "resolution": 140.0, - "resolution/@units": "meV", - "physical_quantity": "energy", - "type": "estimated" - }, - "RESOLUTION[temporal_resolution]": { - "resolution": 35.0, - "resolution/@units": "fs", - "physical_quantity": "time", - "type": "estimated" - }, - "RESOLUTION[momentum_resolution]": { - "resolution": "@attrs:metadata/instrument/analyzer/momentum_resolution", - "resolution/@units": "1/angstrom", - "physical_quantity": "momentum", - "type": "estimated" - }, - "pressure_gauge": { - "name": "sample_chamber_pressure", - "measurement": "pressure", - "value": "@attrs:metadata/file/trARPES:XGS600:PressureAC:P_RD", - "value/@units": "mbar" - }, - "ELECTRONANALYSER[electronanalyser]": { - "description": "SPECS Metis 1000 Momentum Microscope", - "device_information": { - "vendor": "SPECS GmbH", - "model": "Metis 1000 Momentum Microscope" - }, - "fast_axes": [ - "kx", - "ky", - "E" - ], - "slow_axes": "@attrs:metadata/instrument/analyzer/slow_axes", - "energy_resolution": { - "resolution": 110.0, - "resolution/@units": "meV", - "physical_quantity": "energy", - "type": "estimated" - }, - "momentum_resolution": { - "resolution": "@attrs:metadata/instrument/analyzer/momentum_resolution", - "resolution/@units": "1/angstrom", - "physical_quantity": "momentum", - "type": "estimated" - }, - "spatial_resolution": { - "resolution": "@attrs:metadata/instrument/analyzer/spatial_resolution", - "resolution/@units": "µm", - "physical_quantity": "length", - "type": "estimated" - }, - "depends_on": "/entry/instrument/electronanalyser/transformations/trans_z", - "TRANSFORMATIONS[transformations]": { - "AXISNAME[trans_z]": 4.0, - "AXISNAME[trans_z]/@depends_on": "rot_y", - "AXISNAME[trans_z]/@transformation_type": "translation", - "AXISNAME[trans_z]/@units": "mm", - "AXISNAME[trans_z]/@vector": [ - 0, - 0, - 1 - ], - "AXISNAME[rot_y]": -115.0, - "AXISNAME[rot_y]/@depends_on": ".", - "AXISNAME[rot_y]/@transformation_type": "rotation", - "AXISNAME[rot_y]/@units": "degrees", - "AXISNAME[rot_y]/@vector": [ - 0, - 1, - 0 - ] - } - } - }, - "/ENTRY/INSTRUMENT[instrument]/ELECTRONANALYSER[electronanalyser]/COLLECTIONCOLUMN[collectioncolumn]": { - "projection": "@attrs:metadata/instrument/analyzer/projection", - "scheme": "momentum dispersive", - "lens_mode": "@attrs:metadata/instrument/analyzer/lens_mode", - "extractor_voltage": "@attrs:metadata/file/KTOF:Lens:Extr:V", - "extractor_voltage/@units": "V", - "extractor_current": "@attrs:metadata/file/KTOF:Lens:Extr:I", - "extractor_current/@units": "µA", - "working_distance": 4.0, - "working_distance/@units": "mm", - "LENS_EM[lens_*{A,B,C,D,E,F,G,H,I,UCA,UFA,Foc}]": { - "name": "*", - "voltage": "@attrs:metadata/file/KTOF:Lens:*:V", - "voltage/@units": "V" - }, - "field_aperture": { - "shape": "@attrs:metadata/instrument/analyzer/fa_shape", - "size": "@attrs:metadata/instrument/analyzer/fa_size", - "size/@units": "µm", - "POSITIONER[fa_m1]": { - "value": "@attrs:metadata/file/KTOF:Apertures:m1.RBV", - "value/@units": "mm" - }, - "POSITIONER[fa_m2]": { - "value": "@attrs:metadata/file/KTOF:Apertures:m2.RBV", - "value/@units": "mm" - } - }, - "contrast_aperture": { - "shape": "@attrs:metadata/instrument/analyzer/ca_shape", - "size": "@attrs:metadata/instrument/analyzer/ca_size", - "size/@units": "µm", - "POSITIONER[ca_m3]": { - "value": "@attrs:metadata/file/KTOF:Apertures:m3.RBV", - "value/@units": "mm" - } - } - }, - "/ENTRY/INSTRUMENT[instrument]/ELECTRONANALYSER[electronanalyser]/ENERGYDISPERSION[energydispersion]": { - "pass_energy": "@attrs:metadata/file/KTOF:Lens:TOF:V", - "pass_energy/@units": "eV", - "scheme": "tof", - "tof_distance": 0.9, - "tof_distance/@units": "m" - }, - "/ENTRY/INSTRUMENT[instrument]/ELECTRONANALYSER[electronanalyser]/DETECTOR[detector]": { - "amplifier_type": "MCP", - "detector_type": "DLD", - "sensor_pixels": [ - 1800, - 1800 - ], - "sensor_pixels/@units": "", - "amplifier_bias": "@attrs:metadata/file/KTOF:Lens:MCPfront:V", - "amplifier_bias/@units": "V", - "amplifier_voltage": "@attrs:metadata/file/KTOF:Lens:MCPback:V", - "amplifier_voltage/@units": "V", - "detector_voltage": "@attrs:metadata/file/KTOF:Lens:UDLD:V", - "detector_voltage/@units": "V" - }, - "/ENTRY/INSTRUMENT[instrument]/sourceTYPE[source_probe]": { - "name": "HHG @ TR-ARPES @ FHI", - "probe": "photon", - "type": "HHG laser", - "mode": "Single Bunch", - "frequency": "@attrs:metadata/instrument/beam/probe/frequency", - "frequency/@units": "kHz", - "associated_beam": "/entry/instrument/beam_probe" - }, - "/ENTRY/INSTRUMENT[instrument]/beamTYPE[beam_probe]": { - "distance": 0.0, - "distance/@units": "mm", - "incident_energy": "@attrs:metadata/instrument/beam/probe/incident_energy", - "incident_energy/@units": "eV", - "incident_energy_spread": "@attrs:metadata/instrument/beam/probe/incident_energy_spread", - "incident_energy_spread/@units": "eV", - "pulse_duration": "@attrs:metadata/instrument/beam/probe/pulse_duration", - "pulse_duration/@units": "fs", - "incident_polarization": "@attrs:metadata/instrument/beam/probe/incident_polarization", - "incident_polarization/@units": "V^2/mm^2", - "extent": "@attrs:metadata/instrument/beam/probe/extent", - "extent/@units": "µm", - "associated_source": "/entry/instrument/source_probe" - }, - "/ENTRY/INSTRUMENT[instrument]/sourceTYPE[source_pump]": { - "name": "OPCPA @ TR-ARPES @ FHI", - "probe": "visible light", - "type": "Optical Laser", - "mode": "Single Bunch", - "frequency": "@attrs:metadata/instrument/beam/pump/frequency", - "frequency/@units": "kHz", - "associated_beam": "/entry/instrument/beam_pump" - }, - "/ENTRY/INSTRUMENT[instrument]/beamTYPE[beam_pump]": { - "distance": 0.0, - "distance/@units": "mm", - "incident_energy": "@attrs:metadata/instrument/beam/pump/incident_energy", - "incident_energy/@units": "eV", - "incident_energy_spread": "@attrs:metadata/instrument/beam/pump/incident_energy_spread", - "incident_energy_spread/@units": "eV", - "incident_wavelength": "@attrs:metadata/instrument/beam/pump/incident_wavelength", - "incident_wavelength/@units": "nm", - "pulse_duration": "@attrs:metadata/instrument/beam/pump/pulse_duration", - "pulse_duration/@units": "fs", - "incident_polarization": "@attrs:metadata/instrument/beam/pump/incident_polarization", - "incident_polarization/@units": "V^2/mm^2", - "pulse_energy": "@attrs:metadata/instrument/beam/pump/pulse_energy", - "pulse_energy/@units": "µJ", - "average_power": "@attrs:metadata/instrument/beam/pump/average_power", - "average_power/@units": "mW", - "extent": "@attrs:metadata/instrument/beam/pump/extent", - "extent/@units": "µm", - "fluence": "@attrs:metadata/instrument/beam/pump/fluence", - "fluence/@units": "mJ/cm^2", - "associated_source": "/entry/instrument/source_pump" - }, - "/ENTRY/INSTRUMENT[instrument]/MANIPULATOR[manipulator]": { - "temperature_sensor": { - "name": "sample_temperature", - "measurement": "temperature", - "value": "@attrs:metadata/file/trARPES:Carving:TEMP_RBV", - "value/@units": "K" - }, - "sample_bias_voltmeter": { - "name": "sample_bias", - "measurement": "voltage", - "value": "@attrs:metadata/file/KTOF:Lens:Sample:V", - "value/@units": "V" - }, - "depends_on": "/entry/instrument/manipulator/transformations/trans_z", - "TRANSFORMATIONS[transformations]": { - "AXISNAME[trans_z]": -0.32, - "AXISNAME[trans_z]/@depends_on": "rot_z", - "AXISNAME[trans_z]/@transformation_type": "translation", - "AXISNAME[trans_z]/@units": "m", - "AXISNAME[trans_z]/@vector": [ - 0, - 0, - 1 - ], - "AXISNAME[rot_z]/@depends_on": "rot_x", - "AXISNAME[rot_z]": -25.0, - "AXISNAME[rot_z]/@transformation_type": "rotation", - "AXISNAME[rot_z]/@units": "degrees", - "AXISNAME[rot_z]/@vector": [ - 0, - 0, - 1 - ], - "AXISNAME[rot_x]/@depends_on": ".", - "AXISNAME[rot_x]": -90.0, - "AXISNAME[rot_x]/@transformation_type": "rotation", - "AXISNAME[rot_x]/@units": "degrees", - "AXISNAME[rot_x]/@vector": [ - 1, - 0, - 0 - ] - } - }, - "/ENTRY/SAMPLE[sample]": { - "preparation_date": "@attrs:metadata/sample/preparation_date", - "history/notes/type": "text/plain", - "history/notes/description": "@attrs:metadata/sample/sample_history", - "description": "@attrs:metadata/sample/chemical_formula", - "name": "@attrs:metadata/sample/chemical_formula", - "situation": "vacuum", - "SUBSTANCE[substance]/molecular_formula_hill": "@attrs:metadata/sample/chemical_formula", - "temperature_env": { - "temperature_sensor": "@link:/entry/instrument/manipulator/temperature_sensor" - }, - "gas_pressure_env": { - "pressure_gauge": "@link:/entry/instrument/pressure_gauge" - }, - "bias_env": { - "voltmeter": "@link:/entry/instrument/manipulator/sample_bias_voltmeter" - }, - "depends_on": "/entry/sample/transformations/corrected_phi", - "TRANSFORMATIONS[transformations]": { - "AXISNAME[corrected_phi]/@depends_on": "rot_omg", - "AXISNAME[corrected_phi]": 90.0, - "AXISNAME[corrected_phi]/@units": "degrees", - "AXISNAME[corrected_phi]/@transformation_type": "rotation", - "AXISNAME[corrected_phi]/@vector": [ - 0, - 1, - 0 - ], - "AXISNAME[rot_omg]/@depends_on": "rot_phi", - "AXISNAME[rot_omg]": "@attrs:metadata/file/trARPES:Carving:OMG.RBV", - "AXISNAME[rot_omg]/@units": "degrees", - "AXISNAME[rot_omg]/@transformation_type": "rotation", - "AXISNAME[rot_omg]/@vector": [ - 1, - 0, - 0 - ], - "AXISNAME[rot_phi]/@depends_on": "rot_tht", - "AXISNAME[rot_phi]": "@attrs:metadata/file/trARPES:Carving:PHI.RBV", - "AXISNAME[rot_phi]/@units": "degrees", - "AXISNAME[rot_phi]/@transformation_type": "rotation", - "AXISNAME[rot_phi]/@vector": [ - 0, - 1, - 0 - ], - "AXISNAME[rot_tht]/@depends_on": "trans_z", - "AXISNAME[rot_tht]": "@attrs:metadata/file/trARPES:Carving:THT.RBV", - "AXISNAME[rot_tht]/@units": "degrees", - "AXISNAME[rot_tht]/@transformation_type": "rotation", - "AXISNAME[rot_tht]/@vector": [ - 0, - 0, - 1 - ], - "AXISNAME[trans_z]/@depends_on": "trans_y", - "AXISNAME[trans_z]": "@attrs:metadata/file/trARPES:Carving:TRZ.RBV", - "AXISNAME[trans_z]/@units": "mm", - "AXISNAME[trans_z]/@transformation_type": "translation", - "AXISNAME[trans_z]/@vector": [ - 0, - 0, - 1 - ], - "AXISNAME[trans_y]/@depends_on": "trans_x", - "AXISNAME[trans_y]": "@attrs:metadata/file/trARPES:Carving:TRY.RBV", - "AXISNAME[trans_y]/@units": "mm", - "AXISNAME[trans_y]/@transformation_type": "translation", - "AXISNAME[trans_y]/@vector": [ - 0, - 1, - 0 - ], - "AXISNAME[trans_x]/@depends_on": "/entry/instrument/manipulator/transformations/trans_z", - "AXISNAME[trans_x]": "@attrs:metadata/file/trARPES:Carving:TRX.RBV", - "AXISNAME[trans_x]/@units": "mm", - "AXISNAME[trans_x]/@transformation_type": "translation", - "AXISNAME[trans_x]/@vector": [ - 1, - 0, - 0 - ] - } - }, - "/ENTRY/PROCESS_MPES[process]/DISTORTION[distortion]": { - "symmetry": "@attrs:metadata/momentum_correction/rotsym", - "symmetry/@units": "", - "original_centre": "@attrs:metadata/momentum_correction/pcent", - "original_centre/@units": "", - "original_points": "@attrs:metadata/momentum_correction/pouter", - "original_points/@units": "", - "cdeform_field": "@attrs:metadata/momentum_correction/cdeform_field", - "cdeform_field/@units": "", - "rdeform_field": "@attrs:metadata/momentum_correction/rdeform_field", - "rdeform_field/@units": "" - }, - "/ENTRY/PROCESS_MPES[process]/REGISTRATION[registration]": { - "depends_on": "/entry/process/registration/transformations/rot_z", - "TRANSFORMATIONS[transformations]": { - "AXISNAME[trans_x]": "@attrs:metadata/momentum_correction/adjust_params/xtrans", - "AXISNAME[trans_x]/@transformation_type": "translation", - "AXISNAME[trans_x]/@units": "pixels", - "AXISNAME[trans_x]/@vector": "@attrs:metadata/momentum_correction/adjust_params/x_vector", - "AXISNAME[trans_x]/@depends_on": ".", - "AXISNAME[trans_y]": "@attrs:metadata/momentum_correction/adjust_params/ytrans", - "AXISNAME[trans_y]/@units": "pixels", - "AXISNAME[trans_y]/@transformation_type": "translation", - "AXISNAME[trans_y]/@vector": "@attrs:metadata/momentum_correction/adjust_params/y_vector", - "AXISNAME[trans_y]/@depends_on": "trans_x", - "AXISNAME[rot_z]": "@attrs:metadata/momentum_correction/adjust_params/angle", - "AXISNAME[rot_z]/@units": "degrees", - "AXISNAME[rot_z]/@transformation_type": "rotation", - "AXISNAME[rot_z]/@offset": "@attrs:metadata/momentum_correction/adjust_params/offset", - "AXISNAME[rot_z]/@vector": "@attrs:metadata/momentum_correction/adjust_params/rotation_vector", - "AXISNAME[rot_z]/@depends_on": "trans_y" - } - }, - "/ENTRY/PROCESS_MPES[process]/energy_calibration":{ - "coefficients": "@attrs:metadata/energy_correction/calibration/coefficients", - "coefficients/@units": "", - "fit_function": "@attrs:metadata/energy_correction/calibration/fit_function", - "original_axis": "@attrs:metadata/energy_correction/tof", - "original_axis/@units": "ns", - "calibrated_axis": "@attrs:metadata/energy_correction/calibration/axis", - "calibrated_axis/@units": "eV", - "physical_quantity": "energy" - }, - "/ENTRY/PROCESS_MPES[process]/CALIBRATION[kx_calibration]": { - "scaling": "@attrs:metadata/momentum_correction/calibration/scale_kx", - "scaling/@units": "", - "offset": "@attrs:metadata/momentum_correction/offset_kx", - "offset/@units": "", - "calibrated_axis": "@attrs:metadata/momentum_correction/calibration/axis_kx", - "calibrated_axis/@units": "1/angstrom", - "physical_quantity": "momentum" - }, - "/ENTRY/PROCESS_MPES[process]/CALIBRATION[ky_calibration]": { - "scaling": "@attrs:metadata/momentum_correction/calibration/scale_ky", - "scaling/@units": "", - "offset": "@attrs:metadata/momentum_correction/offset_ky", - "offset/@units": "", - "calibrated_axis": "@attrs:metadata/momentum_correction/calibration/axis_ky", - "calibrated_axis/@units": "1/angstrom", - "physical_quantity": "momentum" - }, - "/ENTRY/data": { - "@axes": "@data:dims", - "@*_indices": "@data:*.index", - "@signal": "data", - "data": "@data:data", - "data/@units": "counts", - "*": "@data:*.data", - "*/@units": "@data:*.unit", - "energy/@type": "binding" - } -} \ No newline at end of file diff --git a/src/pynxtools_mpes/nomad/examples/downloads.archive.yaml b/src/pynxtools_mpes/nomad/examples/downloads.archive.yaml index 6df6b50..e65757e 100644 --- a/src/pynxtools_mpes/nomad/examples/downloads.archive.yaml +++ b/src/pynxtools_mpes/nomad/examples/downloads.archive.yaml @@ -10,4 +10,6 @@ data: - url: https://zenodo.org/records/5541490/files/TiTe2_0deg.nxs?download=1 output: TiTe2/TiTe2_0deg.nxs - url: https://zenodo.org/records/5541490/files/TiTe2_60deg.nxs?download=1 - output: TiTe2/TiTe2_60deg.nxs \ No newline at end of file + output: TiTe2/TiTe2_60deg.nxs + - url: https://nomad-lab.eu/prod/v1/api/v1/entries/xV9yMspIyXMfia6nNw3NIbnlZ91H/raw/Scan1496.nxs + output: Scan1496.nxs \ No newline at end of file diff --git a/tests/test_nomad_examples.py b/tests/test_nomad_examples.py index fe22907..22604ca 100644 --- a/tests/test_nomad_examples.py +++ b/tests/test_nomad_examples.py @@ -21,8 +21,7 @@ import pytest try: - from nomad.parsing.parser import ArchiveParser - from nomad.datamodel import EntryArchive, Context + import nomad except ImportError: pytest.skip( "Skipping NOMAD example tests because nomad is not installed",