helpers.py 5.9 KB
Newer Older
Damien Naudet's avatar
Damien Naudet committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2015-2016 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ###########################################################################*/

26 27
from __future__ import absolute_import

Damien Naudet's avatar
Damien Naudet committed
28 29 30 31 32 33
__authors__ = ["D. Naudet"]
__license__ = "MIT"
__date__ = "01/03/2016"

import os

34
from ... import config
Damien Naudet's avatar
Damien Naudet committed
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
from . import KmapMerger
from . import KmapSpecParser


def merge_scan_data(output_dir,
                    spec_fname,
                    beam_energy=None,
                    chan_per_deg=None,
                    center_chan=None,
                    scan_ids=None,
                    img_dir=None,
                    n_proc=None,
                    version=1,
                    nr_padding=None,
                    nr_offset=None,
50
                    compression='DEFAULT',
51 52
                    overwrite=False,
                    image_roi=None):
Damien Naudet's avatar
Damien Naudet committed
53 54 55 56 57 58 59 60
    """
    Creates a "master" HDF5 file and one HDF5 per scan. Those scan HDF5 files
    contain spec data (from *spec_fname*) as well as the associated
    image data. This file will either contain all valid scans or the one
    selected using the scan_ids parameter. A valid scan is a scan associated
    with an (existing) image file. Existing output files will be
    overwritten.

Thomas Vincent's avatar
Thomas Vincent committed
61 62
    :param str output_dir: folder name into which output data
        (as well as temporary files) will be written.
Damien Naudet's avatar
Damien Naudet committed
63

Thomas Vincent's avatar
Thomas Vincent committed
64
    :param str spec_fname: path to the spec file.
Damien Naudet's avatar
Damien Naudet committed
65

Thomas Vincent's avatar
Thomas Vincent committed
66
    :param float beam_energy: beam energy in ....
Damien Naudet's avatar
Damien Naudet committed
67 68 69 70 71 72 73 74 75 76

    :param chan_per_deg: 2 elements array containing the number of channels
        per degree (v, h) (as defined by xrayutilitied, used when converting to
        reciprocal space coordinates).
    :type chan_per_deg: array_like

    :param center_chan: 2 elements array containing the coordinates (v, h) of
        the direct beam position in the detector coordinates.
    :type center_chan: *optional* array_like

Thomas Vincent's avatar
Thomas Vincent committed
77 78
    :param scan_ids: array of scan numbers to add to the merged file.
        If None, all valid scans will be merged.
Damien Naudet's avatar
Damien Naudet committed
79 80
    :type scan_ids: *optional* array of int

Thomas Vincent's avatar
Thomas Vincent committed
81
    :param str img_dir: directory path. If provided the image files will be
Damien Naudet's avatar
Damien Naudet committed
82 83 84
        looked for into that folder instead of the one found in the scan
        headers.

85 86 87 88
    :param Union[int,None] n_proc:
        Number of threads to use when merging files.
        If None, the number of processes used will be the
        default config value (usually the number of cores).
Damien Naudet's avatar
Damien Naudet committed
89

Thomas Vincent's avatar
Thomas Vincent committed
90 91 92 93 94
    :param int version: version of the spec file.
        It is currently used to get the offset and padding to apply to
        the nextNr value found in the spec scan headers.
        This nextNr is then used to generate the image file name.
        Set it to 0 if you are merging data generated before April 2016 (TBC).
Damien Naudet's avatar
Damien Naudet committed
95

Thomas Vincent's avatar
Thomas Vincent committed
96
    :param int nr_padding: zero padding to apply to the nextNr number found
Damien Naudet's avatar
Damien Naudet committed
97
        in the SPEC file.
Thomas Vincent's avatar
Thomas Vincent committed
98 99 100

    :param int nr_offset:
        Offset to apply to the nextNr number found in the SPEC file.
Damien Naudet's avatar
Damien Naudet committed
101

102 103 104 105
    :param Union[str,int] compression: The HDF5 compression to use.

    :param bool overwrite: True to allow overwriting already existing output file

Thomas Vincent's avatar
Thomas Vincent committed
106
    :param Union[List[int],None] image_roi:
107 108 109
        Detector image ROI (origin_row, origin_column, height, width) to save,
        or None (default) to save the whole image

Damien Naudet's avatar
Damien Naudet committed
110
    :returns: a list of scan IDs that were merged
Thomas Vincent's avatar
Thomas Vincent committed
111
    :rtype: List
Damien Naudet's avatar
Damien Naudet committed
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
    """

    base_spec = os.path.basename(spec_fname)

    spec_h5 = os.path.join(output_dir, '{}.h5'.format(base_spec))

    if os.path.exists(spec_h5) and not overwrite:
        raise ValueError('The temporary file {0} already exists.'
                         ''.format(spec_h5))

    parser = KmapSpecParser(spec_fname,
                            spec_h5,
                            img_dir=img_dir,
                            version=version,
                            nr_padding=nr_padding,
                            nr_offset=nr_offset)

    parser.parse()

    if parser.status != KmapSpecParser.DONE:
132 133 134
        raise ValueError('Parsing failed with error code {0}:{1}'
                         ''.format(parser.status,
                                   parser.statusMsg))
Damien Naudet's avatar
Damien Naudet committed
135 136 137 138 139 140 141 142 143 144 145

    p_results = parser.results

    merger = KmapMerger(p_results.spec_h5,
                        p_results,
                        output_dir)

    merger.beam_energy = beam_energy
    merger.center_chan = center_chan
    merger.chan_per_deg = chan_per_deg
    merger.n_proc = n_proc
146 147
    if compression == 'DEFAULT':
        compression = config.DEFAULT_HDF5_COMPRESSION
Damien Naudet's avatar
Damien Naudet committed
148
    merger.compression = compression
149
    merger.image_roi = image_roi
Damien Naudet's avatar
Damien Naudet committed
150 151 152 153 154 155 156 157 158 159 160 161 162 163

    merger.select(scan_ids, clear=True)

    merger.output_dir = output_dir

    merger.merge(overwrite=overwrite)

    if merger.status != KmapMerger.DONE:
        raise ValueError('Merging failed with error code {0}'
                         ''.format(parser.status))

    m_results = merger.results

    return m_results