Reading EER Metadata
I was looking into the Falcon4 Electron-event representation (EER) image format1 and I had no idea that it’s basically just a BigTIFF file2. Having the ability to easily read metadata from our microscope datasets is really useful for automation and reporting.
TIFF files organise their data into sections which are referred to using tags. In the case of EER files, the tag 65001
is used to describe the metadata section. The metadata itself is in XML format with each piece of information held in an <item>
tag. I really hate XML formatting but it’s nice and simple in this case. A few fields have an extra attribute to describe the unit but otherwise one item -> one value.
<metadata>
<item name="[name]" unit="[unit]">[value]</item>
<item name="[name]">[value]</item>
...
</metadata>
Knowing these details, it should be easy enough to read the EER, extract the metadata in XML format and then convert it to a python dict. We need a few libraries first: Tifffile, xmltodict.
python3 -m pip install tifffile xmltodict
Now we’re ready to go but there’s one other thing to be aware of. Converting XML to a python dictionary results in a dict where each item will have a value and possibly a unit (see the XML example above). I would rather have a dict returned with a single value for each key. I’ve included some extra code in the function below to achieve this.
def eer_to_metadata(eer) -> dict:
# Read EER and extract data under tag 65001
from tifffile import TiffFile
with TiffFile(eer) as tif:
tag = tif.pages[0].tags['65001']
data = tag.value.decode('UTF-8')
# Convert the XML to a dict
import xmltodict
parsed = xmltodict.parse(data)
# Flatten the dict into key:value pairs
metadata = {}
for item in parsed["metadata"]["item"]:
key = item["@name"]
value = item["#text"]
metadata[key] = value
# If the value has an associated unit
try:
unit = item["@unit"]
metadata[f"{key}.unit"] = unit
except:
pass
return meta
With everything available in a nice dictionary, we can easily read and use the values.
metadata = eer_to_metadata("example.eer")
for key, value in metadata.items():
print (f"{key}: {value}")
acquisitionID: TEMApps_xxxxxxxx_xxxxxx
cameraName: BM-Falcon
commercialName: Falcon 4
eerGainReference: xxxxxxxx_xxxxxx_EER_GainReference.gain
exposureTime: 6.984477
exposureTime.unit: s
meanDoseRate: 6.8230315484203778
meanDoseRate.unit: e/pixel/s
numberOfFrames: 1680
sensorImageHeight: 4096
sensorImageHeight.unit: pixel
sensorImageWidth: 4096
sensorImageWidth.unit: pixel
sensorPixelSize.height: 9.14242085e-11
sensorPixelSize.height.unit: m
sensorPixelSize.width: 9.14242085e-11
sensorPixelSize.width.unit: m
serialNumber: xx-xx-xxx-xxx
timestamp: 2022-xx-xxTxx:xx:xx.xxx+xx:xx
totalDose: 47.600436100504119
totalDose.unit: e/pixel
-
There’s a C++ library which gives some format details from FEI themselves https://github.com/fei-company/EerReaderLib ↩︎