Ejemplo n.º 1
0
def test_init():
    meta = Meta()
    meta.td = [200, 400]
    assert meta.td[0] == 200
    assert meta.si is None
    meta['si'] = 'a string'
    assert isinstance(meta.si, str)
    assert meta.si.startswith('a')
Ejemplo n.º 2
0
def test_init():
    meta = Meta()
    meta.td = [200, 400]
    assert meta.td[0] == 200
    assert meta.si is None
    meta["si"] = "a string"
    assert isinstance(meta.si, str)
    assert meta.si.startswith("a")
Ejemplo n.º 3
0
def test_readonly():
    meta = Meta()
    meta.chaine = "a string"
    assert meta.chaine == 'a string'
    meta.readonly = True
    with raises(ValueError):
        meta.chaine = "a modified string"
    assert meta.chaine != "a modified string"
Ejemplo n.º 4
0
def test_invalid_key():
    meta = Meta()
    meta.readonly = False  # this is accepted`
    with raises(KeyError):
        meta['readonly'] = True  # this not because readonly is reserved
    with raises(KeyError):
        meta[
            '_data'] = True  # this not because _xxx type attributes are private
Ejemplo n.º 5
0
def test_swap():
    meta = Meta()
    meta.td = [200, 400, 500]
    meta.xe = [30, 40, 80]
    meta.si = 2048
    meta.swap(1, 2)
    assert meta.td == [200, 500, 400]
    assert meta.xe == [30, 80, 40]
    assert meta.si == 2048
Ejemplo n.º 6
0
def figure(preferences=Meta(), **kwargs):
    """
    Method to open a new figure

    Parameters
    ----------
    kwargs : any
        keywords arguments to be passed to the matplotlib figure constructor.
    preferences : Meta dictionary
        per object saved plot configuration
    """
    return get_figure(preferences=preferences, **kwargs)
Ejemplo n.º 7
0
def test_iterator():
    meta = Meta()
    meta.td = [200, 400]
    meta.si = 2048
    meta.ls = 3
    meta.ns = 1024
    assert sorted([val for val in meta]) == ['ls', 'ns', 'si', 'td']
Ejemplo n.º 8
0
def test_iterator():
    meta = Meta()
    meta.td = [200, 400]
    meta.si = 2048
    meta.ls = 3
    meta.ns = 1024
    assert sorted([val for val in meta]) == ["ls", "ns", "si", "td"]
Ejemplo n.º 9
0
def test_permute():
    meta = Meta()
    meta.td = [200, 400, 500]
    meta.xe = [30, 40, 80]
    meta.si = 2048

    p = (2, 0, 1)
    meta.permute(*p)
    assert meta.td == [500, 200, 400]
    assert meta.xe == [80, 30, 40]
    assert meta.si == 2048
Ejemplo n.º 10
0
def test_copy():
    meta = Meta()
    meta.td = [200, 400]
    meta.si = 2048
    meta.ls = 3
    meta.ns = 1024

    meta2 = meta
    assert meta2 is meta

    meta2 = meta.copy()
    assert meta2 is not meta
    assert sorted([val for val in meta2]) == ['ls', 'ns', 'si', 'td']

    # bug with quantity

    si = 2048 * ur.s
    meta.si = si

    meta3 = meta.copy()
    meta3.si = si / 2.

    assert meta3 is not meta
Ejemplo n.º 11
0
def test_copy():
    meta = Meta()
    meta.td = [200, 400]
    meta.si = 2048
    meta.ls = 3
    meta.ns = 1024

    meta2 = meta
    assert meta2 is meta

    meta2 = meta.copy()
    assert meta2 is not meta
    assert sorted([val for val in meta2]) == ["ls", "ns", "si", "td"]

    # bug with quantity

    si = 2048 * ur.s
    meta.si = si

    meta3 = meta.copy()
    meta3.si = si / 2.0

    assert meta3 is not meta
Ejemplo n.º 12
0
def test_get_keys_items():
    meta = Meta()
    meta.td = [200, 400]
    meta.si = 1024
    assert list(meta.keys()) == ['si', 'td']
    assert list(meta.items()) == [('si', 1024), ('td', [200, 400])]
Ejemplo n.º 13
0
def test_get_inexistent():
    meta = Meta()
    assert meta.existepas is None
Ejemplo n.º 14
0
def test_get_keys_items():
    meta = Meta()
    meta.td = [200, 400]
    meta.si = 1024
    assert list(meta.keys()) == ["si", "td"]
    assert list(meta.items()) == [("si", 1024), ("td", [200, 400])]
Ejemplo n.º 15
0
def _read_txt(*args, **kwargs):
    # read Labspec *txt files or series

    dataset, filename = args
    content = kwargs.get('content', False)

    if content:
        fid = io.StringIO(content)
        # TODO: get the l list of string

    else:
        fid = open(filename, 'r', encoding='utf-8')
        try:
            lines = fid.readlines()
        except UnicodeDecodeError:
            fid = open(filename, 'r', encoding='latin-1')
            lines = fid.readlines()
            fid.close()

    # Metadata
    meta = Meta()

    i = 0
    while lines[i].startswith('#'):
        key, val = lines[i].split('=')
        key = key[1:]
        if key in meta.keys():
            key = f'{key} {i}'
        meta[key] = val.strip()
        i += 1

    # read spec
    rawdata = np.genfromtxt(lines[i:], delimiter='\t')

    # populate the dataset
    if rawdata.shape[1] == 2:
        data = rawdata[:, 1][np.newaxis]
        _x = Coord(rawdata[:, 0], title='Raman shift', units='1/cm')
        _y = Coord(None, title='Time', units='s')
        date_acq, _y = _transf_meta(_y, meta)

    else:
        data = rawdata[1:, 1:]
        _x = Coord(rawdata[0, 1:], title='Raman shift', units='1/cm')
        _y = Coord(rawdata[1:, 0], title='Time', units='s')
        date_acq, _y = _transf_meta(_y, meta)

    # try to transform to linear coord
    _x.linear = True

    # if success linear should still be True
    if _x.linear:
        _x = LinearCoord(_x)

    # set dataset metadata
    dataset.data = data
    dataset.set_coordset(y=_y, x=_x)
    dataset.title = 'raman Intensity'
    dataset.units = 'absorbance'
    dataset.name = filename.stem
    dataset.meta = meta

    # date_acq is Acquisition date at start (first moment of acquisition)
    dataset.description = 'Spectrum acquisition : ' + str(date_acq)

    # Set the NDDataset date
    dataset._date = datetime.datetime.now(datetime.timezone.utc)
    dataset._modified = dataset.date

    # Set origin, description and history
    dataset.history = f'{dataset.date}:imported from LabSpec6 text file {filename}'

    return dataset
Ejemplo n.º 16
0
 def _meta_default(self):
     return Meta()
Ejemplo n.º 17
0
 def _ranges_default(self):
     ranges = Meta()
     for dim in self.dims:
         ranges[dim] = dict(masks={}, baselines={}, integrals={}, others={})
     return ranges
Ejemplo n.º 18
0
def _read_topspin(*args, **kwargs):
    debug_("Bruker TOPSPIN file reading")
    dataset, path = args
    #    content = kwargs.get('content', None)

    # is-it a processed dataset (1r, 2rr ....
    processed = True if path.match("pdata/*/*") else False

    # ------------------------------------------------------------------------
    # start reading ....
    # ------------------------------------------------------------------------

    parents = path.parents

    # Get data and acquisition parameters

    if not processed:
        # a fid or a ser has been selected
        f_expno = parents[0]
        expno = f_expno.name
        procno = kwargs.get("procno", "1")
        f_procno = f_expno / "pdata" / procno
        f_name = parents[1]

    else:
        # a processes spectra has been selected (1r, ....)
        f_procno = parents[0]
        procno = f_procno.name
        f_expno = parents[2]
        expno = f_expno.name
        f_name = parents[3]

    acqus_files = _get_files(f_expno, "acqu")
    procs_files = _get_files(f_procno, "proc")

    if not processed:

        dic, data = read_fid(f_expno,
                             acqus_files=acqus_files,
                             procs_files=procs_files)

        # apply a -90 phase shift to be compatible with topspin
        data = data * np.exp(-1j * np.pi / 2.0)

        # Look the case when the reshaping was not correct
        # for example, this happen when the number
        # of accumulated row was incomplete
        if path.name in ["ser"] and data.ndim == 1:
            # we must reshape using the acqu parameters
            td1 = dic["acqu2"]["TD"]
            try:
                data = data.reshape(td1, -1)
            except ValueError:
                try:
                    td = dic["acqu"]["TD"] // 2
                    data = data.reshape(-1, td)
                except ValueError:
                    raise KeyError("Inconsistency between TD's and data size")

            # reduce to td
            ntd = dic["acqus"]["TD"] // 2
            data = data[..., :ntd]

        # Eliminate the digital filter
        if kwargs.get("remove_digital_filter",
                      True) and dic["acqus"]["DECIM"] > 1:
            data = _remove_digital_filter(dic, data)

    else:

        dic, datalist = read_pdata(
            f_procno,
            acqus_files=acqus_files,
            procs_files=procs_files,
            all_components=True,
        )
        if isinstance(datalist, list):
            if datalist[0].ndim == 2:
                data, dataRI, dataIR, dataII = datalist
                # make quaternion
                shape = data.shape
                data = as_quat_array(
                    list(
                        zip(
                            data.flatten(),
                            dataRI.flatten(),
                            dataIR.flatten(),
                            dataII.flatten(),
                        )))
                data = data.reshape(shape)

            elif datalist[0].ndim == 1:
                # make complex
                data, dataI = datalist
                data = data + dataI * 1.0j

            else:
                return None
        else:
            data = datalist

    # ........................................................................................................
    # we now make some rearrangement of the dic to have something more user friendly
    # we assume that all experiments have similar (important) parameters so that the experiments are compatibles

    meta = Meta()  # This is the parameter dictionary
    datatype = path.name.upper() if not processed else f"{data.ndim}D"

    keys = sorted(dic.keys())

    # we need the ndim of the data
    parmode = int(dic["acqus"].get("PARMODE", data.ndim - 1))
    if parmode + 1 != data.ndim:
        raise KeyError(
            f"The NMR data were not read properly as the PARMODE+1 parameter ({parmode + 1}) doesn't fit"
            f" the actual number of dimensions ({data.ndim})")

    # read the acqu and proc
    valid_keys = list(zip(*nmr_valid_meta))[0]
    keys_units = dict(nmr_valid_meta)

    for item in keys:

        if item[:4] in ["acqu", "proc"]:
            dim = parmode
            if len(item) > 4 and item[4] in ["2", "3"]:
                dim = parmode + 1 - int(item[4])

            for key in sorted(dic[item]):

                if key.startswith("_") or key.lower() not in valid_keys:
                    continue

                value = dic[item][key]
                units = ur(keys_units[key.lower()]) if keys_units[
                    key.lower()] else None

                if units is not None:
                    if isinstance(value, (float, int)):
                        value = value * units  # make a quantity
                    elif isinstance(value, list) and isinstance(
                            value[0], (float, int)):
                        value = np.array(value) * units

                if key.lower() not in meta:
                    meta[key.lower()] = [None] * data.ndim

                try:
                    meta[key.lower()][dim] = value
                except Exception:
                    pass

        else:

            meta[item.lower()] = dic[item]

    # Warning: from now all parameter keys are lowercase.

    # correct some initial values

    meta.encoding = [0] * (parmode + 1)
    meta.iscomplex = [False] * (parmode + 1)

    if not processed:
        meta.isfreq = [False]
        meta.encoding[-1] = AQ_mod[meta.aq_mod[-1]]
        meta.iscomplex[-1] = meta.aq_mod[-1] > 0

    if datatype in ["SER"]:
        meta.isfreq.insert(0, False)

        if meta.fnmode[-2] == 0:
            # For historical reasons,
            # MC2 is interpreted when the acquisition status
            # parameter FnMODE has the value undefined, i.e. 0
            if meta.mc2 is not None:
                meta.fnmode[-2] = meta.mc2[-2] + 1

        meta.encoding[-2] = FnMODE[meta.fnmode[-2]]
        meta.iscomplex[-2] = meta.fnmode[-2] > 1

        if parmode == 2:
            meta.isfreq.insert(0, False)
            if meta.fnmode[-3] == 0 and meta.mc2 is not None:
                meta.fnmode[-3] = meta.mc2[-3] + 1
            meta.encoding[-3] = FnMODE[meta.fnmode[-3]]
            meta.iscomplex[-3] = meta.fnmode[-3] > 1

    # correct TD, so it is the number of complex points, not the number of data
    # not for the last dimension which is already correct
    meta.tdeff = meta.td[:]
    meta.td = list(data.shape)

    for axis in range(parmode + 1):
        if meta.iscomplex[axis]:
            if axis != parmode:  # already done for last axis
                meta.td[axis] = meta.td[axis] // 2
            meta.tdeff[axis] = meta.tdeff[axis] // 2

    meta.sw_h = [(meta.sw[axis].m * meta.sfo1[axis] * 1e-6).to("Hz")
                 for axis in range(parmode + 1)]

    if processed:
        meta.si = [si for si in data.shape]
        meta.isfreq = [True] * (parmode + 1)  # at least we assume this
        meta.phc0 = [0] * data.ndim

    # this transformation is to make data coherent with bruker processing
    if meta.iscomplex[-1]:
        data = np.conj(data * np.exp(np.pi * 1j / 2.0))

    # normalised amplitudes to ns=1 and rg=1
    def _norm(dat):
        meta.ns = meta.get(
            "ns",
            [1] * data.ndim)  # sometimes these parameters are not present
        meta.rg = meta.get("rg", [1.0] * data.ndim)
        fac = float(meta.ns[-1]) * float(meta.rg[-1])
        meta.rgold = [meta.rg[-1]]
        meta.rg[-1] = 1.0
        meta.nsold = [meta.ns[-1]]  # store the old value of NS
        meta.ns[-1] = 1
        dat /= fac
        return dat

    data = _norm(data)

    # add some additional information in meta
    meta.expno = [int(expno)]

    # and the metadata (and make them readonly)
    meta.datatype = datatype
    meta.pathname = str(path)

    # add two parameters needed for phasing
    meta.pivot = [0] * data.ndim
    meta.exptc = [0] * data.ndim

    # make the corresponding axis
    # debug_('Create coords...')
    coords = []
    axe_range = list(range(parmode + 1))

    for axis in axe_range:
        if not meta.isfreq[axis]:
            # the axis is in time units
            dw = (1.0 / meta.sw_h[axis]).to("us")
            # coordpoints = np.arange(meta.td[axis])
            # coord = Coord(coordpoints * dw,
            #             title=f"F{axis + 1} acquisition time")  # TODO: use AQSEQ for >2D data
            coord = LinearCoord(
                offset=0.0,
                increment=dw,
                units="us",
                size=meta.td[axis],
                title=f"F{axis + 1} acquisition time",
            )
            coord.meta.larmor = meta.sfo1[axis]
            coords.append(coord)
        else:
            size = meta.si[axis]
            sizem = max(size - 1, 1)
            deltaf = -meta.sw_h[axis] / sizem
            first = meta.sfo1[axis] - meta.sf[axis] - deltaf * sizem / 2.0

            # coord = Coord(np.arange(size) * deltaf + first)
            coord = LinearCoord(offset=first, increment=deltaf, size=size)
            coord.meta.larmor = meta.sfo1[
                axis]  # needed for ppm transformation
            coord.ito("ppm")
            if meta.nuc1 is not None:
                nuc1 = meta.nuc1[axis]
                regex = r"([^a-zA-Z]+)([a-zA-Z]+)"
                m = re.match(regex, nuc1)
                mass = m[1]
                name = m[2]
                nucleus = "^{" + mass + "}" + name
            else:
                nucleus = ""
            coord.title = rf"$\delta\ {nucleus}$"
            coords.append(coord)

    dataset.data = data

    for axis, cplex in enumerate(meta.iscomplex[::-1]):
        if cplex and axis > 0:
            dataset.set_quaternion(inplace=True)

    dataset.meta.update(meta)
    dataset.meta.readonly = True
    dataset.set_coordset(*tuple(coords))

    dataset.title = "intensity"
    dataset.origin = "topspin"
    dataset.name = f"{f_name.name} expno:{expno} procno:{procno} ({datatype})"
    dataset.filename = f_name

    return dataset
Ejemplo n.º 19
0
def test_instance():
    meta = Meta()
    assert isinstance(meta, Meta)
Ejemplo n.º 20
0
def _read_txt(*args, **kwargs):
    # read Labspec *txt files or series

    dataset, filename = args
    content = kwargs.get("content", False)

    if content:
        pass
        # fid = io.StringIO(content)
        # TODO: get the l list of string

    else:
        fid = open(filename, "r", encoding="utf-8")
        try:
            lines = fid.readlines()
        except UnicodeDecodeError:
            fid = open(filename, "r", encoding="latin-1")
            lines = fid.readlines()
            fid.close()

    if len(lines) == 0:
        return

    # Metadata
    meta = Meta()

    i = 0
    while lines[i].startswith("#"):
        key, val = lines[i].split("=")
        key = key[1:]
        if key in meta.keys():
            key = f"{key} {i}"
        meta[key] = val.strip()
        i += 1

    # .txt extension is fairly common. We determine non labspc files based
    # on the absence of few keys. Two types of files (1D or 2D) are considered:
    labspec_keys_1D = ["Acq. time (s)", "Dark correction"]
    labspec_keys_2D = ["Exposition", "Grating"]

    if all(keywd in meta.keys() for keywd in labspec_keys_1D):
        pass
    elif all(keywd in meta.keys() for keywd in labspec_keys_2D):
        pass
    else:
        # this is not a labspec txt file"
        return

    # read spec
    rawdata = np.genfromtxt(lines[i:], delimiter="\t")

    # populate the dataset
    if rawdata.shape[1] == 2:
        data = rawdata[:, 1][np.newaxis]
        _x = Coord(rawdata[:, 0], title="Raman shift", units="1/cm")
        _y = Coord(None, title="Time", units="s")
        date_acq, _y = _transf_meta(_y, meta)

    else:
        data = rawdata[1:, 1:]
        _x = Coord(rawdata[0, 1:], title="Raman shift", units="1/cm")
        _y = Coord(rawdata[1:, 0], title="Time", units="s")
        date_acq, _y = _transf_meta(_y, meta)

    # try to transform to linear coord
    _x.linear = True

    # if success linear should still be True
    if _x.linear:
        _x = LinearCoord(_x)

    # set dataset metadata
    dataset.data = data
    dataset.set_coordset(y=_y, x=_x)
    dataset.title = "Counts"
    dataset.units = None
    dataset.name = filename.stem
    dataset.meta = meta

    # date_acq is Acquisition date at start (first moment of acquisition)
    dataset.description = "Spectrum acquisition : " + str(date_acq)

    # Set the NDDataset date
    dataset._date = datetime.datetime.now(datetime.timezone.utc)
    dataset._modified = dataset.date

    # Set origin, description and history
    dataset.history = f"{dataset.date}:imported from LabSpec6 text file {filename}"

    return dataset
Ejemplo n.º 21
0
def test_equal():
    meta1 = Meta()
    meta2 = Meta()
    assert meta1 == meta2