Raw Data and the .rw.dat File¶
The raw data collected during a dc magnetic measurement is voltage vs. position data collected by moving the sample through the magnetometer's gradiometer. Quantum Design's MPMS3 stores this data in a .rw.dat file with the same name as the .dat file containing the processed data.
MagnetoPy gives an easy way to access this raw data by associating the individual scans within the .rw.dat file with the corresponding data points in the .dat file.
When creating the DatFile
object add parse_raw = True
to the arguments. If a .rw.dat file exists with the same name within the same directory, the DatFile
object will automatically parse the raw data and associate it with the corresponding data points in the .dat file.
from pathlib import Path
import magnetopy as mp
DATA_PATH = Path("../../tests/data")
zfc5 = mp.DatFile(DATA_PATH / "zfc5.dat", parse_raw=True)
The raw data is added as a column called "raw_scan"
in the data
attribute (you'll likely have to scroll to the right end of the following DataFrame
).
zfc5.data.head()
Comment | Time Stamp (sec) | Temperature (K) | Magnetic Field (Oe) | Moment (emu) | M. Std. Err. (emu) | Transport Action | Averaging Time (sec) | Frequency (Hz) | Peak Amplitude (mm) | ... | Map 08 | Map 09 | Map 10 | Map 11 | Map 12 | Map 13 | Map 14 | Map 15 | Map 16 | raw_scan | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | NaN | 3.876038e+09 | 2.001670 | 199.96196 | NaN | NaN | 6 | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | DcMeasurement(199.96 Oe, 2.00 K) |
1 | NaN | 3.876038e+09 | 2.201302 | 199.96196 | NaN | NaN | 6 | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | DcMeasurement(199.96 Oe, 2.20 K) |
2 | NaN | 3.876039e+09 | 2.401609 | 199.96196 | NaN | NaN | 6 | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | DcMeasurement(199.96 Oe, 2.40 K) |
3 | NaN | 3.876039e+09 | 2.601313 | 199.96196 | NaN | NaN | 6 | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | DcMeasurement(199.96 Oe, 2.60 K) |
4 | NaN | 3.876039e+09 | 2.800433 | 199.96196 | NaN | NaN | 6 | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | DcMeasurement(199.96 Oe, 2.80 K) |
5 rows × 90 columns
The DcMeasurement
Class¶
Each element in the "raw_scan"
column is a DcMeasurement
object, which contains the raw voltage data from the directional scans (stored as RawScan
objects), as well as the results of the fit performed by the MPMS software used to convert the voltage to a magnetic moment (stored as a FitDcScan
object).
dc_measurement: mp.DcMeasurement = zfc5.data["raw_scan"].iloc[0]
dc_measurement
DcMeasurement(199.96 Oe, 2.00 K)
dc_measurement.__dict__
{'up': RawDcScan(up, 199.96 Oe, 2.00 K), 'down': RawDcScan(down, 199.96 Oe, 2.00 K), 'fit_scan': FitDcScan(3876038315.32042 sec)}
The RawDcScan
class contains information stored in the individual scan headers as well as the actual raw voltage data. Here are the attributes containing the information stored in the scan header:
up_scan = dc_measurement.up
{attribute: value for attribute, value in up_scan.__dict__.items() if attribute not in ["text", "data"]}
{'direction': 'up', 'low_temp': 1.99824821949005, 'high_temp': 2.00186586380005, 'avg_temp': 2.00000633691487, 'low_field': 199.961959838867, 'high_field': 199.961959838867, 'drift': 0.00359456760634202, 'slope': 0.000410807726439089, 'squid_range': 10.0, 'given_center': 33.4032707214355, 'calculated_center': 33.3980560302734, 'amp_fixed': -1.51181256771088, 'amp_free': -1.51181125640869, 'start_time': 3876038306.03405}
and here is the data:
up_scan.data.head()
Time Stamp (sec) | Raw Position (mm) | Raw Voltage (V) | Processed Voltage (V) | |
---|---|---|---|---|
0 | 3.876038e+09 | 15.986061 | 0.036862 | 0.304230 |
1 | 3.876038e+09 | 16.160303 | 0.045246 | 0.312542 |
2 | 3.876038e+09 | 16.333939 | 0.054017 | 0.321242 |
3 | 3.876038e+09 | 16.508030 | 0.063230 | 0.330383 |
4 | 3.876038e+09 | 16.682274 | 0.072727 | 0.339809 |
The FitScan
object only contains the time stamp at which it was created and the data from the fit:
fit_scan = dc_measurement.fit_scan
fit_scan.start_time
3876038315.32042
fit_scan.data.head()
Time Stamp (sec) | Raw Position (mm) | Fixed C Fitted (V) | Free C Fitted (V) | |
---|---|---|---|---|
0 | 3.876038e+09 | 15.903271 | 0.262449 | 0.327815 |
1 | 3.876038e+09 | 16.078270 | 0.269636 | 0.337026 |
2 | 3.876038e+09 | 16.253271 | 0.277069 | 0.346514 |
3 | 3.876038e+09 | 16.428270 | 0.284755 | 0.356277 |
4 | 3.876038e+09 | 16.603271 | 0.292696 | 0.366315 |
fig, ax = mp.plot_raw(zfc5.data, (0, 1))
The same method exists on the DatFile
object itself, so it's not necessary to pass in the data. We'll still need the data_slice
argument in this case, though.
fig, ax = zfc5.plot_raw((0, 1))
Note that the y-axis is "Scaled Voltage (V)"
. This scaling is based on the squid_range
(an attribute stored in both directional scan headers). Note that the scaling is only done during plotting, and the actual data is unchanged. This may be important for someone looking to implement in-depth analysis of the raw data (e.g., manual background subtractions, residual analysis, etc.).
The default behavior of plot_raw
is to plot the processed data from a single directional scan. The processed data is adjusted for drift and offset. We can also use plot_raw
to plot the fit data -- i.e., the simulated data from the results of the fit performed by the Quantum Design software.
fig, ax = zfc5.plot_raw((0, 1), scan="fit")
Typically we'll be using plot_raw
and related functions/methods to plot many scans. For example,
fig, ax = zfc5.plot_raw()
Lastly, MagnetoPy provides plotting functionality for looking at the residual curves. The following plots illustrate the difference between having a free-floating or a fixed center when fitting the data.
The default behavior of plot_raw_residual
uses the free fit center.
fig, ax = zfc5.plot_raw_residual()
Here's what the residuals look like when the center is fixed:
fig, ax = zfc5.plot_raw_residual(center="fixed")
The example used in this notebook is a file containing a single ZFC measurement, so the DatFile
method works well for visualizing the raw data. In situations where multiple experiments are in the same file or for M vs. H measurements, the raw data visualization at the DatFile
level may become convoluted. For example, here's a file containing a single M vs. H measurement:
mvsh5 = mp.DatFile(DATA_PATH / "mvsh5.dat", parse_raw=True)
fig, ax = mvsh5.plot_raw()
The plot above shows the raw data from both forward and reverse scans. It'd be much more clear to plot the data from each scan separately. While this could be done by passing a data_slice
argument to plot_raw
, MagnetoPy provides plot_raw
methods in experiment-specific classes. We'll see in the next tutorial how to use the MvsH
class for this purpose.