Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Writing compound datasets of two dimensional datatypes #305

Open
flappah opened this issue Jun 21, 2023 · 4 comments
Open

Writing compound datasets of two dimensional datatypes #305

flappah opened this issue Jun 21, 2023 · 4 comments

Comments

@flappah
Copy link

flappah commented Jun 21, 2023

Hi Lior,

Again, another question. Is there any way to write a compound dataset of a two dimensional custom data type? For example this:

            var surfaceCurrent2DItems = new SurfaceCurrentInstance[3, 3];
            surfaceCurrent2DItems[0, 0] = new SurfaceCurrentInstance(speed: 1.61, direction: 50.9);
            surfaceCurrent2DItems[0, 1] = new SurfaceCurrentInstance(speed: 1.58, direction: 53.4);
            surfaceCurrent2DItems[0, 2] = new SurfaceCurrentInstance(speed: 1.54, direction: 56.1);
            surfaceCurrent2DItems[1, 0] = new SurfaceCurrentInstance(speed: 1.61, direction: 50.9);
            surfaceCurrent2DItems[1, 1] = new SurfaceCurrentInstance(speed: 1.5, direction: 59.0);
            surfaceCurrent2DItems[1, 2] = new SurfaceCurrentInstance(speed: 1.46, direction: 61.9);
            surfaceCurrent2DItems[2, 0] = new SurfaceCurrentInstance(speed: 1.42, direction: 65.1);
            surfaceCurrent2DItems[2, 1] = new SurfaceCurrentInstance(speed: 1.39, direction: 68.4);
            surfaceCurrent2DItems[2, 2] = new SurfaceCurrentInstance(speed: 1.35, direction: 71.9);

            Hdf5.WriteCompounds(group001Id, "values", surfaceCurrent2DItems, new Dictionary<string, List<string>>());

I know this won't work since it's not an IEnumerable. But is there any other way to get this going through the Hdf5 Csharp library? I also know using PureHDF won't work since that one only enables me to read compound datasets, not writing. Any ideas?

[edit]
Oh yeah, and this is the definition of SurfaceCurrentInstance:

    public struct SurfaceCurrentInstance
    {
        [Hdf5EntryName("surfaceCurrentSpeed")]
        public double speed;

        [Hdf5EntryName("surfaceCurrentDirection")]
        public double direction;

        /// <summary>
        ///     
        /// </summary>
        /// <param name="height"></param>
        /// <param name="trend"></param>
        public SurfaceCurrentInstance(double speed, double direction)
        {
            this.speed = speed;
            this.direction = direction;
        }
    }

@LiorBanai
Copy link
Owner

Hi,
I'll have to take a look to answer correctly.
Hopefully I'll be able to do it next week

@flappah
Copy link
Author

flappah commented Jun 25, 2023

Also for this one I got around the issue by adding my own implementation. It’s an ugly one but I just made an extension method that I could call if I had to write 2D arrays. I’ll add my code to this issue tomorrow since I’ve only got it on usb stick. I literally looked at your code and MacGyver’ed my way through it. :)
I’ll add it tomorrow!

@LiorBanai
Copy link
Owner

MacGyvering stuff is the best approach to bypass limitations hh

@flappah
Copy link
Author

flappah commented Jun 26, 2023

Hahaha .. true! True!

This is the helper class I'm using:

using HDF.PInvoke;
using System.Runtime.InteropServices;

namespace Hdf5Fase2Test.Hdf5
{
    public class Hdf5Extensions
    {
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="groupId"></param>
        /// <param name="name"></param>
        /// <param name="data"></param>
        /// <param name="attributes"></param>
        /// <returns></returns>
        public static (int success, long createdGroupId) Write2DCompounds<T>(long groupId, string name, T[,] data, Dictionary<string, List<string>> attributes)
        {
            long spaceId = H5S.create_simple(2, new ulong[] { (ulong)data.GetLength(0), (ulong)data.GetLength(1) }, null);
            long dataTypeId = HDF5CSharp.Hdf5.CreateType(typeof(T));
            GCHandle? handleStorage = null;
            int statusId = -1;
            try
            {
                handleStorage = GCHandle.Alloc(data, GCHandleType.Pinned);
                long datasetId = H5D.create(groupId, name, dataTypeId, spaceId);
                statusId = H5D.write(datasetId, dataTypeId, spaceId, H5S.ALL, H5P.DEFAULT, ((GCHandle) handleStorage).AddrOfPinnedObject());

                H5D.close(datasetId);
                H5T.close(dataTypeId);
                H5S.close(spaceId);
            }
            finally
            {
                if (handleStorage != null)
                {
                    ((GCHandle)handleStorage).Free();
                }
            }


            return (statusId, dataTypeId);
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants