Table Of Contents

Previous topic

About

Next topic

Read a data file

Create a new data file

This example shows how to create a new data file object from scratch and add one condition and one data set.

Create main object

First, we import the DataFile class and define a datafile object:

from pyhmsa.datafile import DataFile
datafile = DataFile()

From the datafile object, the header can be modified using the attribute header, conditions can be added/modified/removed using the conditions which acts as a Python’s dictionary and data sets can be added/modified/removed in the same way as conditions using the data.

Condition

The next step is to create a condition. For this example, we will create an acquisition point condition (AcquisitionPoint). This condition requires to define a position. Positions are specified by the SpecimenPosition class. Note that per the HMSA specification, the specimen position could also be a condition on its own. All arguments of the specimen position are optional. We will define x, y and z.

from pyhmsa.spec.condition.specimenposition import SpecimenPosition
position = SpecimenPosition(x=0.0, y=1.0, z=2.0)

With this position we can create our acquisition condition object. The optional arguments (dwell_time, total_time, dwell_time_live) can be defined later.

from pyhmsa.spec.condition.acquisition import AcquisitionPoint
acq = AcquisitionPoint(position=position)

Numerical attributes with a magnitude (i.e. unit) can be defined in three different ways:

  • Using the set method and specify the unit as the second argument.

    acq.set_dwell_time(5.0, 's')
    
  • Using directly the attribute and a 2-item tuple where the first item is the value and the second the unit.

    acq.dwell_time = (5.0, 's')
    
  • Not specifying the unit. The default unit will be used. Refer to the documentation to know which unit is assigned by default.

    acq.dwell_time = 5.0
    

Note that regardless how a numerical attribute is set, all get methods will return a special object called arrayunit. The details of this object is not important for the users, except that it behaves as a regular number (i.e. Python’s float) and that it has an extra attribute unit to retrieve the unit. For example,

print(acq.dwell_time) # Returns: 5.0 s
print(acq.get_dwell_time()) # Returns: 5.0 s
print(acq.dwell_time.unit) # Returns: s

Finally, we can add our acquisition point condition to the datafile object. We use the identifier Acq0.

datafile.conditions['Acq0'] = acq

Data set

All data set classes are derived from NumPy’s arrays. NumPy is a powerful Python library to handle multi-dimensional arrays. It also allows to define the type of data (integer, float) and the number of bytes. Based on the HMSA specifications the following NumPy data types are allowed: uint8, int16, uint16, int32, uint32, int64, float32 and float64. If you want to perform advanced array manipulation, we refer you to the NumPy’s documentation.

For this example, we will create a 1D analysis data set (Analysis1D). This data set is designed to store a measurement at a single point in space or time with one datum dimension. It has no collection dimensions. An example of such data set would be an EDS spectrum.

We create the data set with 1000 channels using the int64 data type.

import numpy as np
from pyhmsa.spec.datum.analysis import Analysis1D
channels = 1000
datum = Analysis1D(channels, np.int64)

At this point, the data set does not contain any values. No assumption can be made on the initial values. For the purpose of this example, we will fill the array using random numbers generated from 0 to 5000.

import random
datum[:] = [random.randint(0, 5000) for _ in range(channels)]

As for the condition, we add the new data set to the datafile object.

datafile.data['Spectrum0'] = datum

Saving

Now our data file is created, we obviously would like to save it. The datafile object was an easy utility method write which allows to save the object to disk. The method takes one argument, the location (absolute or relative) where to save the data file. Note that the extension of the file can either be .xml or .hmsa. Both files will automatically be created as per the HMSA specifications.

datafile.write('example1.xml')

Once a datafile object has been saved, it can be saved again to the same location by just calling write() without any argument.

datafile.write() # Save to the same location

Full source code

#!/usr/bin/env python

from pyhmsa.datafile import DataFile
datafile = DataFile()

# Header
datafile.header.title = 'Example'
datafile.header['title'] = 'Example'

import datetime
datafile.header.datetime = datetime.datetime.now()

# Condition
## Create a position
from pyhmsa.spec.condition.specimenposition import SpecimenPosition
position = SpecimenPosition(x=0.0, y=1.0, z=2.0)

## Create an acquisition condition
from pyhmsa.spec.condition.acquisition import AcquisitionPoint
acq = AcquisitionPoint(position=position)
acq.set_dwell_time(5.0, 's')
acq.dwell_time = (5.0, 's')
acq.dwell_time = 5.0

print(acq.dwell_time) # Returns: 5.0 s
print(acq.get_dwell_time()) # Returns: 5.0 s
print(acq.dwell_time.unit) # Returns: s

## Add condition to datafile with the ID = Acq0
datafile.conditions['Acq0'] = acq

# Dataset
## Create a dataset (NumPy array) of 1000 64-bit integers
import numpy as np
from pyhmsa.spec.datum.analysis import Analysis1D
channels = 1000
datum = Analysis1D(channels, np.int64)

## Assign values to the array by generating a random integer between 0 and 5000
import random
datum[:] = [random.randint(0, 5000) for _ in range(channels)]

## Add dataset to datafile with the ID = Spectrum0
datafile.data['Spectrum0'] = datum

# Save datafile to a file
## Only one of the two files need to be specified, either .xml or .hmsa
datafile.write('example1.xml')
datafile.write() # Save to the same location