Exemple #1
0
    def test_keep_file_open(self):
        for fn in self.text_example_file_list:
            # Text file can be opened as binary or text
            with open(fn, 'rb') as f:
                open_topography(f)
                self.assertFalse(f.closed, msg=fn)
            with open(fn, 'r') as f:
                open_topography(f)
                self.assertFalse(f.closed, msg=fn)
        for fn in self.binary_example_file_list:
            with open(fn, 'rb') as f:
                open_topography(f)
                self.assertFalse(f.closed, msg=fn)
        for datastr in self.text_example_memory_list:
            with io.StringIO(datastr) as f:
                open_topography(f)
                self.assertFalse(
                    f.closed,
                    msg="text memory stream for '{}' was closed".format(
                        datastr))

            # Doing the same when but only giving a binary stream
            with io.BytesIO(datastr.encode(encoding='utf-8')) as f:
                open_topography(f)
                self.assertFalse(
                    f.closed,
                    msg="binary memory stream for '{}' was closed".format(
                        datastr))
Exemple #2
0
def test_keep_text_file_open(fn):
    # Text file can be opened as binary or text
    with open(fn, 'rb') as f:
        open_topography(f)
        assert not f.closed, f"Text file {fn} was opened as binary file and is closed, but should not"
    with open(fn, 'r') as f:
        open_topography(f)
        assert not f.closed, f"Text file {fn} was opened as text file and is closed, but should not"
Exemple #3
0
def test_keep_stream_from_memory_open(datastr):
    with io.StringIO(datastr) as f:
        open_topography(f)
        assert not f.closed, "text memory stream for '{}' was closed".format(
            datastr)

    # Doing the same when but only giving a binary stream
    with io.BytesIO(datastr.encode(encoding='utf-8')) as f:
        open_topography(f)
        assert not f.closed, "binary memory stream for '{}' was closed".format(
            datastr)
Exemple #4
0
def test_can_be_pickled(fn):
    reader = open_topography(fn)
    physical_sizes = None
    if reader.default_channel.physical_sizes is None:
        physical_sizes = (1., ) * reader.default_channel.dim

    topography = reader.topography(physical_sizes=physical_sizes)
    topographies = [topography]
    if hasattr(topography, 'to_uniform'):
        topographies += [topography.to_uniform(100, 0)]
    for t in topographies:
        s = pickle.dumps(t)
        pickled_t = pickle.loads(s)

        #
        # Compare some attributes after unpickling
        #
        # sometimes the result is a list of topographies
        multiple = isinstance(t, list)
        if not multiple:
            t = [t]
            pickled_t = [pickled_t]

        for x, y in zip(t, pickled_t):
            for attr in ['dim', 'physical_sizes', 'is_periodic']:
                assert getattr(x, attr) == getattr(y, attr)
            if x.physical_sizes is not None:
                assert_array_equal(x.positions(), y.positions())
                assert_array_equal(x.heights(), y.heights())
Exemple #5
0
def test_reader_arguments(fn):
    """Check whether all readers have channel, physical_sizes and
    height_scale_factor arguments. Also check whether we can execute
    `topography` multiple times for all readers"""
    physical_sizes0 = (1.2, 1.3)

    # Test open -> topography
    r = open_topography(fn)
    physical_sizes = None if r.channels[
        0].physical_sizes is not None else physical_sizes0

    t = r.topography(channel_index=0,
                     physical_sizes=physical_sizes,
                     height_scale_factor=None)
    if physical_sizes is not None:
        assert t.physical_sizes == physical_sizes
    # Second call to topography
    t2 = r.topography(channel_index=0,
                      physical_sizes=physical_sizes,
                      height_scale_factor=None)
    if physical_sizes is not None:
        assert t2.physical_sizes == physical_sizes
    assert_array_equal(t.heights(), t2.heights())
    # Test read_topography
    t = read_topography(fn,
                        channel_index=0,
                        physical_sizes=physical_sizes,
                        height_scale_factor=None)
    if physical_sizes is not None:
        assert t.physical_sizes == physical_sizes
Exemple #6
0
def test_reader_topography_same(fn):
    """
    Tests that properties like physical sizes, units and nb_grid_pts are
    the same in the ChannelInfo and the loaded topography.
    """

    reader = open_topography(fn)

    for channel in reader.channels:
        foo_str = reader.format() + "-%d" % (channel.index,
                                             )  # unique for each channel
        topography = channel.topography(
            physical_sizes=(1, 1) if channel.physical_sizes is None else None,
            info=dict(foo=foo_str))
        assert channel.nb_grid_pts == topography.nb_grid_pts

        # some checks on info dict in channel and topography
        assert topography.info['foo'] == foo_str
        if channel.unit is not None or topography.unit is not None:
            assert channel.unit == topography.unit
            assert channel.info['unit'] == topography.unit
            assert channel.unit == topography.info['unit']

        if channel.physical_sizes is not None:
            assert channel.physical_sizes == topography.physical_sizes

        if channel.height_scale_factor is not None and hasattr(
                topography, 'scale_factor'):
            assert channel.height_scale_factor == topography.scale_factor
Exemple #7
0
 def test_reader_arguments(self):
     """Check whether all readers have channel, physical_sizes and
     height_scale_factor arguments. Also check whether we can execute
     `topography` multiple times for all readers"""
     physical_sizes0 = (1.2, 1.3)
     for fn in self.text_example_file_list + self.binary_example_file_list:
         # Test open -> topography
         r = open_topography(fn)
         physical_sizes = None if r.channels[0].dim == 1 \
             else physical_sizes0
         t = r.topography(channel_index=0,
                          physical_sizes=physical_sizes,
                          height_scale_factor=None)
         if physical_sizes is not None:
             self.assertEqual(t.physical_sizes, physical_sizes)
         # Second call to topography
         t2 = r.topography(channel_index=0,
                           physical_sizes=physical_sizes,
                           height_scale_factor=None)
         if physical_sizes is not None:
             self.assertEqual(t2.physical_sizes, physical_sizes)
         assert_array_equal(t.heights(), t2.heights())
         # Test read_topography
         t = read_topography(fn,
                             channel_index=0,
                             physical_sizes=physical_sizes,
                             height_scale_factor=None)
         if physical_sizes is not None:
             self.assertEqual(t.physical_sizes, physical_sizes)
Exemple #8
0
def test_periodic_flag(fn):
    reader = open_topography(fn)
    ch = reader.default_channel
    physical_sizes_arg_if_missing_in_file = (1., ) * ch.dim
    physical_sizes_arg = physical_sizes_arg_if_missing_in_file if ch.physical_sizes is None else None

    t = reader.topography(physical_sizes=physical_sizes_arg, periodic=True)
    assert t.is_periodic, fn

    t = reader.topography(physical_sizes=physical_sizes_arg, periodic=False)
    assert not t.is_periodic, fn
Exemple #9
0
def test_nb_grid_pts_and_physical_sizes_are_tuples_or_none(fn):
    r = open_topography(fn)
    assert isinstance(
        r.default_channel.nb_grid_pts,
        tuple), f'{fn} - {r.__class__}: {r.default_channel.nb_grid_pts}'
    if r.default_channel.physical_sizes is not None:
        assert isinstance(r.default_channel.physical_sizes, tuple), \
            f'{fn} - {r.__class__}: {r.default_channel.physical_sizes}'
        # If it is a tuple, it cannot contains None's
        assert np.all([p is not None for p in r.default_channel.physical_sizes]), \
            f'{fn} - {r.__class__}: {r.default_channel.physical_sizes}'
Exemple #10
0
def test_gwyddion_txt_import(lang_filename_infix):
    fname = os.path.join(DATADIR,
                         'gwyddion-export-{}.txt'.format(lang_filename_infix))

    #
    # test channel infos
    #
    reader = open_topography(fname)

    assert len(reader.channels) == 1
    channel = reader.default_channel

    assert channel.name == "My Channel Name"
    assert channel.unit == 'm'
    assert pytest.approx(
        channel.physical_sizes[0]) == 12.34 * 1e-6  # was given as µm
    assert pytest.approx(
        channel.physical_sizes[1]) == 5678.9 * 1e-9  # was given as nm

    #
    # test metadata of topography
    #
    topo = reader.topography()
    assert topo.unit == 'm'
    assert pytest.approx(
        topo.physical_sizes[0]) == 12.34 * 1e-6  # was given as µm
    assert pytest.approx(
        topo.physical_sizes[1]) == 5678.9 * 1e-9  # was given as nm

    #
    # test scaling and order of data
    #
    # The order of the lines in the text files mimic the lines as they
    # are shown in the gwyddion plot.
    #
    # In gwyddion's text export:
    # - first index corresponds to y dimension (rows), second index (columns)
    #   to x dimension
    # - y coordinates grow from top row to bottom row
    # - x coordinates grow from left column to column of array
    #
    # PyCo's heights() has a different order:
    # - first index corresponds to x dimension, second index to y dimension
    # - plot from the heights correspond to same image in gwyddion if plotted
    #   with "pcolormesh(t.heights.T)", but with origin in lower left, i.e. the
    #   image looks flipped vertically when compared to gwyddion
    #
    # => heights() must be same array as in file, but transposed
    #
    heights_in_file = [[1, 1.5, 3], [-2, -3, -6], [0, 0, 0], [9, 9, 9]]

    expected_heights = np.array(heights_in_file).T

    np.testing.assert_allclose(topo.heights(), expected_heights)
Exemple #11
0
    def test_periodic_flag(self):
        file_list = self.text_example_file_list + self.binary_example_file_list
        for fn in file_list:
            reader = open_topography(fn)
            physical_sizes = None
            if reader.default_channel.dim != 1:
                physical_sizes = reader.default_channel.physical_sizes \
                    if reader.default_channel.physical_sizes is not None \
                    else [1., ] * reader.default_channel.dim
            t = reader.topography(physical_sizes=physical_sizes, periodic=True)
            assert t.is_periodic, fn

            t = reader.topography(physical_sizes=physical_sizes,
                                  periodic=False)
            assert not t.is_periodic, fn
Exemple #12
0
    def test_read(self):
        # All units are nm
        for (fn, n, s, rmslist) in [
            ('di1.di', 512, 500.0, [(9.9459868005603909, "Height"),
                                    (114.01328027385664, "Height"),
                                    (None, "Phase"),
                                    (None, "AmplitudeError")]),
            ('di2.di', 512, 300.0, [(24.721922008645919, "Height"),
                                    (24.807150576054838, "Height"),
                                    (0.13002312109876774, "Deflection")]),
            ('di3.di', 256, 10000.0, [(226.42539668457405, "ZSensor"),
                                      (None, "AmplitudeError"),
                                      (None, "Phase"),
                                      (264.00285276203158, "Height")]),
                # Height
            (
                'di4.di',
                512,
                10000.0,
                [
                    (81.622909804184744, "ZSensor"),  # ZSensor
                    (0.83011806260022758, "AmplitudeError"),  # AmplitudeError
                    (None, "Phase")
                ])  # Phase
        ]:
            reader = open_topography(os.path.join(DATADIR, '{}').format(fn),
                                     format="di")

            for i, (rms, name) in enumerate(rmslist):
                assert reader.channels[i].name == name
                surface = reader.topography(channel_index=i)

                nx, ny = surface.nb_grid_pts
                self.assertEqual(nx, n)
                self.assertEqual(ny, n)
                sx, sy = surface.physical_sizes
                if type(surface.info['unit']) is tuple:
                    unit, dummy = surface.info['unit']
                else:
                    unit = surface.info['unit']
                self.assertAlmostEqual(
                    sx * get_unit_conversion_factor(unit, 'nm'), s)
                self.assertAlmostEqual(
                    sy * get_unit_conversion_factor(unit, 'nm'), s)
                if rms is not None:
                    self.assertAlmostEqual(surface.rms_height(), rms)
                    self.assertEqual(unit, 'nm')
                self.assertTrue(surface.is_uniform)
Exemple #13
0
def test_save_and_load_np(comm_self, file_format_examples):
    # sometimes the surface isn't transposed the same way when

    topography = open_topography(os.path.join(file_format_examples, 'di4.di'),
                                 format="di").topography()

    with tempfile.TemporaryDirectory() as d:
        npyfile = os.path.join(d, 'test_save_and_load_np.npy')
        np.save(npyfile, topography.heights())

        loaded_topography = NPYReader(
            npyfile,
            communicator=comm_self).topography(physical_sizes=(1., 1.))

        np.testing.assert_allclose(loaded_topography.heights(),
                                   topography.heights())
Exemple #14
0
def test_reader_height_scale_factor_arg_for_topography(fn):
    """Test whether height_scale_factor can be given to .topography() and is effective.

    Also checking whether the reader channels have .height_scale_factor attribute and
    whether it is equal to the scaling factor known from topography.

    Also tests that info dict of channel and topography have no height_scale_factor,
    because this should be a channel property now.
    """
    reader = open_topography(fn)
    ch = reader.default_channel

    assert hasattr(ch, 'height_scale_factor')
    assert 'height_scale_factor' not in ch.info

    height_scale_factor_if_missing_in_file = 2  # just some number

    # calculate argument for .topography()
    height_scale_factor_arg = height_scale_factor_if_missing_in_file if ch.height_scale_factor is None else None

    # which factor we expect at the end
    exp_height_scale_factor = height_scale_factor_if_missing_in_file if ch.height_scale_factor is None \
        else ch.height_scale_factor

    # in order to call .topography(), we also need valid physical_sizes
    physical_sizes_arg_if_missing_in_file = (1., ) * ch.dim
    physical_sizes_arg = physical_sizes_arg_if_missing_in_file if ch.physical_sizes is None else None

    # The check whether an exception is raised if meta data like `physical_sizes`
    # and `height_scale_factor` has already been defined in the file and
    # one tries to override it, is done in another test.
    #
    # (only do this if not an NC file with units, since this is special: height_scale_factor
    # should only be choosable then.)
    if reader.format != 'nc' and 'unit' not in ch.info:
        topography = reader.topography(
            physical_sizes=physical_sizes_arg,
            height_scale_factor=height_scale_factor_arg)
        if hasattr(topography, 'scale_factor'):
            # sometimes we use height_scale_factor = 1 in the channel info in order
            # to denote that the height scale factor cannot be changed later.
            # This does not mean that the topography also really has been scaled, so
            # we compare the scale factor here only of it is available
            assert pytest.approx(exp_height_scale_factor) == topography.scale_factor, \
                "Difference in height scale factor between channel/argument and resulting topography"
Exemple #15
0
def test_ibw_file_with_one_channel_without_name():
    """
    After implementing new IBW readers there was an issue
    https://github.com/pastewka/TopoBank/issues/413

    This test should ensure that it's fixed.
    """
    fn = os.path.join(DATADIR, "10x10-one_channel_without_name.ibw")

    reader = open_topography(fn)

    assert len(reader.channels) == 1

    ch_info = reader.channels[0]

    # we could use "Default" here, but what if there are multiple no names?
    assert ch_info.name == 'no name (1)'
    assert ch_info.dim == 2
    assert ch_info.nb_grid_pts == (10, 10)
Exemple #16
0
    def test_reader_topography_same(self):
        """
        Tests that properties like physical sizes, units and nb_grid_pts are
        the  same in the ChannelInfo and the loaded topography
        """

        for fn in self.text_example_file_list + self.binary_example_file_list:
            reader = open_topography(fn)

            for channel in reader.channels:
                topography = channel.topography(physical_sizes=(
                    1, 1) if channel.physical_sizes is None else None)
                assert channel.nb_grid_pts == topography.nb_grid_pts
                if "unit" in channel.info.keys() or \
                        "unit" in topography.info.keys():
                    assert channel.info["unit"] == topography.info["unit"]

                if channel.physical_sizes is not None:
                    assert channel.physical_sizes == topography.physical_sizes
def test_save_and_load(comm_self, file_format_examples):
    # sometimes the surface isn't transposed the same way when
    topography = open_topography(
        os.path.join(file_format_examples, 'di4.di'),
        format="di").topography()

    npyfile = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                           "test_save_and_load.npy")
    save_npy(npyfile, topography)

    loaded_topography = NPYReader(npyfile, communicator=comm_self).topography(
        # nb_subdomain_grid_pts=topography.nb_grid_pts,
        # subdomain_locations=(0,0),
        physical_sizes=(1., 1.))

    np.testing.assert_allclose(loaded_topography.heights(),
                               topography.heights())

    os.remove(npyfile)
def test_hard_wall_bearing_area(comm):
    # Test that at very low hardness we converge to (almost) the bearing
    # area geometry
    pnp = Reduction(comm)
    fullsurface = open_topography(os.path.join(FIXTURE_DIR, 'surface1.out'))
    fullsurface = fullsurface.topography(
        physical_sizes=fullsurface.channels[0].nb_grid_pts)
    nb_domain_grid_pts = fullsurface.nb_grid_pts
    substrate = PeriodicFFTElasticHalfSpace(nb_domain_grid_pts,
                                            1.0,
                                            fft='mpi',
                                            communicator=comm)
    surface = Topography(
        fullsurface.heights(),
        physical_sizes=nb_domain_grid_pts,
        decomposition='domain',
        subdomain_locations=substrate.topography_subdomain_locations,
        nb_subdomain_grid_pts=substrate.topography_nb_subdomain_grid_pts,
        communicator=substrate.communicator)

    plastic_surface = PlasticTopography(surface, 1e-12)
    system = PlasticNonSmoothContactSystem(substrate, plastic_surface)
    offset = -0.002
    if comm.rank == 0:

        def cb(it, p_r, d):
            print("{0}: area = {1}".format(it, d["area"]))
    else:

        def cb(it, p_r, d):
            pass

    result = system.minimize_proxy(offset=offset, callback=cb)
    assert result.success
    c = result.jac > 0.0
    ncontact = pnp.sum(c)
    assert plastic_surface.plastic_area == ncontact * surface.area_per_pt
    bearing_area = bisect(
        lambda x: pnp.sum((surface.heights() > x)) - ncontact, -0.03, 0.03)
    cba = surface.heights() > bearing_area
    # print(comm.Get_rank())
    assert pnp.sum(np.logical_not(c == cba)) < 25
Exemple #19
0
def test_ibw_kpfm_file():
    """
    We had an issue with KPFM files, see
    https://github.com/pastewka/PyCo/pull/231#discussion_r354687995

    This test should ensure that it's fixed.
    """
    fn = os.path.join(DATADIR, 'spot_1-1000nm.ibw')
    reader = open_topography(fn)

    #
    # Try to read all channels
    #
    for channel_info in reader.channels:
        assert pytest.approx(channel_info.physical_sizes[0],
                             abs=0.01) == 2e-05  # 20 µm
        assert pytest.approx(channel_info.physical_sizes[1],
                             abs=0.01) == 2e-05  # 20 µm

        channel_info.topography()
Exemple #20
0
    def test_nb_grid_pts_and_physical_sizes_are_tuples_or_none(self):
        file_list = self.text_example_file_list + self.binary_example_file_list

        for fn in file_list:
            r = open_topography(fn)
            self.assertTrue(
                isinstance(r.default_channel.nb_grid_pts, tuple),
                msg=f'{fn} - {r.__class__}: {r.default_channel.nb_grid_pts}')
            if r.default_channel.physical_sizes is not None:
                self.assertTrue(
                    isinstance(r.default_channel.physical_sizes, tuple),
                    msg=
                    f'{fn} - {r.__class__}: {r.default_channel.physical_sizes}'
                )
                # If it is a tuple, it cannot contains None's
                self.assertTrue(
                    np.all([
                        p is not None for p in r.default_channel.physical_sizes
                    ]),
                    msg=
                    f'{fn} - {r.__class__}: {r.default_channel.physical_sizes}'
                )
def plot(fn):
    r = open_topography(fn)

    t = r.topography()
    if 'unit' in t.info:
        unit = t.info['unit']
    else:
        unit = '?'
    fig = plt.figure(figsize=(10, 10))
    fig.suptitle("{}, channel {}".format(fn, r.default_channel.name))

    ax = fig.add_subplot(2, 2, 1)
    ax.set_title("pcolormesh(t.heights().T)")
    ax.pcolormesh(t.heights().T)

    ax = fig.add_subplot(2, 2, 2)
    ax.set_title("pcolormesh(*t.positions_and_heights())")
    ax.set_xlabel("x [{}]".format(unit))
    ax.set_ylabel("y [{}]".format(unit))
    ax.pcolormesh(*t.positions_and_heights())

    ax = fig.add_subplot(2, 2, 3)
    ax.set_title("above is correct, if this is like Gwyddion")
    ax.pcolormesh(np.flipud(t.heights().T))

    ax = fig.add_subplot(2, 2, 4)
    ax.set_title("imshow(t.heights().T)")
    extent = (0, t.physical_sizes[0], t.physical_sizes[1], 0)
    ax.imshow(t.heights().T, extent=extent)
    fig.subplots_adjust(hspace=0.5)
    fig.show()

    h = t.heights()
    for i, j in [(0, 0), (0, -1), (-1, 0), (-1, -1)]:
        print("h[{},{}] == {}".format(i, j, h[i, j]))

    return t
Exemple #22
0
def get_topography_reader(filefield, format=None):
    """Returns SurfaceTopography.IO.ReaderBase object.

    Parameters
    ----------

    filefield: models.FileField instance
        reference to file which should be opened by the reader
    format: str, optional
        specify in which format the file should be interpreted;
        if not given, the format is determined automatically

    Returns
    -------
        Instance of a `ReaderBase` subclass according to the format.
    """
    # Workaround such that SurfaceTopography module recognizes this a binary stream
    if not hasattr(filefield, 'mode'):
        filefield.mode = 'rb'
    if hasattr(filefield.file, 'seek'):
        # make sure the file is rewound
        filefield.file.seek(0)
    reader = open_topography(filefield, format=format)
    return reader
Exemple #23
0
def test_reader_args_doesnt_overwrite_data_from_file(fn):
    """
    Tests that if some properties like `physical_sizes and `height_scale_factor`
    are given in the file, they cannot be overridden by given arguments to
    the .topography() method.
    """
    reader = open_topography(fn)
    ch = reader.default_channel
    physical_sizes_arg_if_missing_in_file = (1., ) * ch.dim
    physical_sizes_arg = physical_sizes_arg_if_missing_in_file if ch.physical_sizes is None else None

    if ch.physical_sizes is not None:
        with pytest.raises(MetadataAlreadyFixedByFile):
            reader.topography(
                physical_sizes=physical_sizes_arg_if_missing_in_file)

    if ch.height_scale_factor is not None:
        with pytest.raises(MetadataAlreadyFixedByFile):
            if ch.physical_sizes is None:
                reader.topography(physical_sizes=physical_sizes_arg,
                                  height_scale_factor=10)
            else:
                # if an exception happens, we want it because of height scale factor
                reader.topography(height_scale_factor=10)
 def test_example6(self):
     topography_file = open_topography(
         os.path.join(DATADIR, 'example6.txt'))
     surf = topography_file.topography(physical_sizes=(1,))
     self.assertTrue(isinstance(surf, UniformLineScan))
     np.testing.assert_allclose(surf.heights(), [1, 2, 3, 4, 5, 6, 7, 8, 9])
Exemple #25
0
 def test_detect_format_then_read(self):
     f = open(os.path.join(DATADIR, 'example.ibw'), 'rb')
     fmt = detect_format(f)
     self.assertTrue(fmt, 'ibw')
     open_topography(f, format=fmt).topography()
     f.close()
Exemple #26
0
                    type=int,
                    default=None,
                    help='use NBINS bins for radial average',
                    metavar='NBINS')
parser.add_argument('--detrend_mode',
                    dest='detrend_mode',
                    type=str,
                    default='center',
                    help='detrend surface; posibilities are '
                    'DETREND=center|height|slope|curvature',
                    metavar='DETREND')
arguments = parser.parse_args()

###

surface = DetrendedTopography(open_topography(arguments.filename),
                              detrend_mode=arguments.detrend_mode)
unit = surface.unit
nx, ny = surface.shape
nbins = arguments.nbins
if nbins is None:
    nbins = (nx + ny) / 2

###

r, A, A_xy = autocorrelation_2D(surface, nbins=nbins, return_map=True)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.loglog(r, A, 'ko')
ax.set_xlabel('Distance $r$ ({})'.format(unit))
Exemple #27
0
def test_keep_binary_file_open(fn):
    with open(fn, 'rb') as f:
        open_topography(f)
        assert not f.closed, f"Binary file {fn} was opened as binary file and is closed, but should not"