Basic Data Exploration¶
[2]:
from arpes.io import example_data
f = example_data.cut
[3]:
f.S.plot()
Although we can plot the spectrum off of a Dataset
, which might contain additional attributes like the photocurrent, beam current, temperature, or wall-clock time, by using .S.plot()
, we can also get the spectrum attribute from the full data:
[4]:
f.spectrum
[4]:
<xarray.DataArray 'spectrum' (phi: 240, eV: 240)> array([[ 1, 2, 0, ..., 110, 76, 61], [ 0, 1, 0, ..., 79, 74, 42], [ 1, 0, 0, ..., 65, 65, 41], ..., [ 0, 11, 35, ..., 54, 77, 53], [ 0, 5, 26, ..., 60, 76, 48], [ 1, 2, 25, ..., 74, 72, 42]]) Coordinates: * phi (phi) float64 0.2217 0.2234 0.2251 0.2269 ... 0.6353 0.637 0.6388 * eV (eV) float64 -0.4256 -0.4233 -0.4209 ... 0.1256 0.1279 0.1302 x float64 -0.7704 y float64 34.75 z float64 -3.4e-05 theta float64 0.0 beta float64 0.0 chi float64 -0.1091 hv float64 5.93 alpha int32 0 psi int32 0 Attributes: (12/99) file: c:\users\chsta\documents\github\arpes\arpes\ex... location: ALG-MC BITPIX: 8 NAXIS: 0 START_T: 2/3/2016 1:45:34 PM START_TS: 3537380734.727 ... ... analyzer_radius: 150 analyzer_type: hemispherical mcp_voltage: None probe_linewidth: 0.015 chi_offset: -0.10909301748228785 df: None
- phi: 240
- eV: 240
- 1 2 0 6 45 72 35 37 64 68 52 37 ... 125 82 68 62 76 82 95 84 74 72 42
array([[ 1, 2, 0, ..., 110, 76, 61], [ 0, 1, 0, ..., 79, 74, 42], [ 1, 0, 0, ..., 65, 65, 41], ..., [ 0, 11, 35, ..., 54, 77, 53], [ 0, 5, 26, ..., 60, 76, 48], [ 1, 2, 25, ..., 74, 72, 42]])
- phi(phi)float640.2217 0.2234 ... 0.637 0.6388
array([0.221657, 0.223402, 0.225147, ..., 0.6353 , 0.637045, 0.638791])
- eV(eV)float64-0.4256 -0.4233 ... 0.1279 0.1302
array([-0.425581, -0.423256, -0.42093 , ..., 0.125581, 0.127907, 0.130232])
- x()float64-0.7704
array(-0.7704345)
- y()float6434.75
array(34.74984)
- z()float64-3.4e-05
array(-3.4e-05)
- theta()float640.0
array(0.)
- beta()float640.0
array(0.)
- chi()float64-0.1091
array(-0.10909302)
- hv()float645.93
array(5.93)
- alpha()int320
array(0)
- psi()int320
array(0)
- file :
- c:\users\chsta\documents\github\arpes\arpes\example_data\cut.fits
- location :
- ALG-MC
- BITPIX :
- 8
- NAXIS :
- 0
- START_T :
- 2/3/2016 1:45:34 PM
- START_TS :
- 3537380734.727
- HOST :
- ALG-DAQ
- HOST_IP :
- 192.168.131.3
- PMOTOR0 :
- -0.7268
- PMOTOR1 :
- 34.74984
- PMOTOR2 :
- -0.1781
- PMOTOR3 :
- 0.0
- PMOTOR4 :
- 0.497900419916
- PMOTOR5 :
- -6.250569476082
- PMOTOR6 :
- 45.84724
- LOFFSET0 :
- 0.0
- LOFFSET1 :
- 0.0
- LOFFSET2 :
- 0.0
- LOFFSET3 :
- 0.0
- LOFFSET4 :
- -0.4998983638986
- LOFFSET5 :
- -2.84217094304e-14
- LOFFSET6 :
- -306.74698936
- SMOTOR0 :
- -4.505929176249
- SMOTOR1 :
- 34.46412947579
- SMOTOR2 :
- -0.1781
- SMOTOR3 :
- 0.0
- SMOTOR4 :
- 0.497900419916
- SMOTOR5 :
- -6.250569476082
- SOFFSET0 :
- 0.0
- SOFFSET1 :
- 0.0
- SOFFSET2 :
- 0.0
- SOFFSET3 :
- 0.0
- SOFFSET4 :
- 0.0
- SOFFSET5 :
- 0.0
- MMX0_0 :
- 1.0
- MMX0_2 :
- 0.245
- MMX1_1 :
- 1.0
- MMX2_0 :
- -0.245
- MMX2_2 :
- 1.0
- MMX3_3 :
- 1.0
- MMX4_4 :
- 1.0
- MMX5_5 :
- 1.0
- MMX6_6 :
- 6.671
- LWLVNM :
- None
- LWLVLPN :
- 1
- SCNTYP0 :
- 0
- DEVNM_0 :
- None
- NMSBDV0 :
- 1
- NM_0_0 :
- null
- ST_0_0 :
- 0.0
- EN_0_0 :
- 0.0
- N_0_0 :
- 1
- SF_MODEL :
- PHOIBOS HSA3500 CCD 150 R6-HiRes
- SF_SER :
- SF_NUM :
- 1
- SF_PPEV :
- 218.4
- SF_KE0 :
- 340.0
- SF_HV :
- 5.9
- SFRGN0 :
- Wentao
- SFPE_0 :
- 5
- SFE_0 :
- 0.1
- SFIM0 :
- 0
- SFPEV_0 :
- 860.0
- SFKE0_0 :
- 340.0
- SFX0_0 :
- 60
- SFX1_0 :
- 539
- SFY0_0 :
- 127
- SFY1_0 :
- 367
- UN_0_0 :
- x :
- -0.7704345
- y :
- 34.74984
- z :
- -3.400000000001e-05
- theta :
- 0.0
- beta :
- 0.0
- chi :
- -0.10909301748228785
- delay :
- -0.90005132
- lens_mode_name :
- WideAngleMode:40V
- frames_per_slice :
- 500
- phi_prebinning :
- 1
- eV_prebinning :
- 2
- id :
- 04b9b89e-ee38-11eb-ac39-d6eaadaaa3db
- provenance :
- {'record': {'what': 'Loaded MC dataset from FITS.', 'by': 'load_MC'}, 'file': 'c:\\users\\chsta\\documents\\github\\arpes\\arpes\\example_data\\cut.fits', 'jupyter_context': ['tool = ImageTool()\ntool.make_tool(example_data.cut.spectrum)', 'import arpes\nfrom arpes.io import example_data\nfrom arpes.plotting.interactive import ImageTool', 'tool = ImageTool()\ntool.make_tool(example_data.cut.spectrum)', '"""nbconvert header\n\nWe are just configuring to hide some unnecessary warnings.\n"""\n\nimport arpes.config\narpes.config.DOCS_BUILD = True', 'from arpes.io import example_data\n\nf = example_data.cut'], 'parents_provenance': 'filesystem', 'time': '2021-07-26T10:36:32.980165', 'version': '3.0.0'}
- hv :
- 5.93
- alpha :
- 0
- psi :
- 0
- phi_offset :
- 0.405
- spectrum_type :
- cut
- time :
- 1:45:34 pm
- date :
- 2/3/2016
- analyzer :
- Specs PHOIBOS 150
- analyzer_name :
- Specs PHOIBOS 150
- parallel_deflectors :
- False
- perpendicular_deflectors :
- False
- analyzer_radius :
- 150
- analyzer_type :
- hemispherical
- mcp_voltage :
- None
- probe_linewidth :
- 0.015
- chi_offset :
- -0.10909301748228785
- df :
- None
Selecting Data¶
Typically, we will not want to use the full spectrometer window. Instead we will want to focus on a particular energy or momentum range, such as the region just above, below, or around the chemical potential, or at the energy distribution curves (EDCs) around a particular significant momentum. Data selections can be performed either on Dataset
s or DataArray
s. In the former case, it has the effect of selecting on a particular dimension or set of dimensions for each attribute that has
those dimensions.
In general, we do not need to know the indices of the region we want to select: we can use the physically meaningful coordinates. As an example, to get the band structure from our data f
between the ground reference of the spectrometer (the chemical potential) and a point 200 millivolts below, we can use .sel
.
[5]:
f.sel(eV=slice(-0.2, 0)).S.plot()
.sel
accepts any number of dimensions specified by a slice
. The arguments to the slice provide a low and high cutoff respectively.
We can also select just a single point along an axis by passing a value instead of a slice. In general we will want to be safe and pass the method='nearest'
argument, in order to ensure that if the exact value we requested is not included, we will get the nearest pixel.
[6]:
# get the EDC nearly at the gamma point
f.sel(phi=0.4, method="nearest").S.plot()
Of course, we can select over a wider window for better statistics, so long as we average or sum out the angle axis after selecting.
[7]:
# get the EDC nearly at the gamma point
f.sel(phi=slice(0.38, 0.42)).sum("phi").S.plot()
Selecting with array indices¶
In instances where you would like to subselect by an index (ranging above from 0 to 239), as opposed to the physically significant coordinate value, we can use .isel
instead.
[8]:
f.isel(phi=40).S.plot()
Open ended selections¶
Selections can be made open ended on one or both sides by passing None
. In the follow example, the inclusion of None
will cause the selection to continue to the end of the data on the high end, i.e pixels 40 to 240 on the ‘phi’ axis.
[9]:
f.isel(phi=slice(40, None)).S.plot()
Summing and Averaging¶
We saw above an example of taking a binned EDC by selecting a narrow angular region and taking the sum over that axis. We can also request means or sums over multiple axes with .mean
and .sum
.
[10]:
f.mean("eV").S.plot()
[11]:
# to get the value as a plain float instead of a scalar dataset
# use `.mean(["eV", "phi"]).item()` instead
f.spectrum.mean(["eV", "phi"])
[11]:
<xarray.DataArray 'spectrum' ()> array(355.37399306) Coordinates: x float64 -0.7704 y float64 34.75 z float64 -3.4e-05 theta float64 0.0 beta float64 0.0 chi float64 -0.1091 hv float64 5.93 alpha int32 0 psi int32 0
- 355.4
array(355.37399306)
- x()float64-0.7704
array(-0.7704345)
- y()float6434.75
array(34.74984)
- z()float64-3.4e-05
array(-3.4e-05)
- theta()float640.0
array(0.)
- beta()float640.0
array(0.)
- chi()float64-0.1091
array(-0.10909302)
- hv()float645.93
array(5.93)
- alpha()int320
array(0)
- psi()int320
array(0)
Caveat: Summing an axis will remove all attributes unless the keep_attrs=True
parameter is included in the call to .sum
. Forgetting to do this where it is necessary can cause issues down the line for analysis that requires access to the attributes, such as in converting to momentum space, where the photon energy and coordinate offset for normal emission are stored as attributes.
Transposing¶
To transpose axes, you can use .transpose
or .T
. In xarray
and therefore in PyARPES, you interact with data using named dimensions. As a result, transposing is rarely necessary except to set axis order when plotting.
[12]:
f.transpose("eV", "phi").S.plot() # equivalently, f.T.S.plot()
Interactive Data Browsing¶
Facilities are included for doing interactive data exploration and analysis both directly in Jupyter, via Bokeh. And in a separate standalone window using PyQt5. To learn more about interactive analysis, please read the interactive analysis section of the documentation.
[13]:
from arpes.plotting.qt_tool import qt_tool
qt_tool(f)
PyARPES philosophy on interactive tools¶
Instead of one large interactive application where you perform analysis, PyARPES has many small interactive utilities which are built for a single purpose. These include:
A data browser:
arpes.plotting.qt_tool.qt_tool
A momentum offset browser:
arpes.plotting.qt_ktool.ktool
A tool for path selection:
arpes.plotting.basic_tools.path_tool
A tool for mask selection:
arpes.plotting.basic_tools.mask_tool
A tool to show a slice on a BZ recorded by the spectrometer or scan:
arpes.plotting.bz_tool.bz_tool
and others.
PyARPES prefers simpler specific tools because it makes them easier to write and maintain, and because PyARPES prefers you do as much analysis via the notebook as possible. This makes for better, more reproducible science.
Learning more about data manipulation¶
PyARPES uses the excellent xarray to provide a rich “Wave”-like data model. For non-spectroscopy related analysis tasks, you should read their documentation.
Exercises¶
Learning more about xarray
¶
Skim the data structures guide at the
xarray
docs.Open a PyARPES Jupyter cell and print one of the piece of example data with
from arpes.io import example_data; example_data.cut
or similar. Make sure you can understand the correspondence between the data structures guide and ARPES idioms.
Practicing data selection¶
What happens if you select a range backward?
What happens to attributes and coordinates when you select a single value or range?
Practicing interactive browsing¶
Try using
qt_tool
to find the projection of the gamma point inexample_data.map
?In
qt_tool
, press H to open the help panel and learn the cursor scrolling controls.