Skip to content

Commit 983d584

Browse files
committed
Updates for v2 arch
1 parent ac3dd27 commit 983d584

2 files changed

Lines changed: 244 additions & 2 deletions

File tree

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
package org.hdf5javalib.utils;
2+
3+
import org.hdf5javalib.dataclass.HdfData;
4+
import org.hdf5javalib.dataclass.HdfFixedPoint;
5+
import org.hdf5javalib.datasource.TypedDataSource;
6+
import org.hdf5javalib.hdffile.dataobjects.HdfObjectHeaderPrefix;
7+
import org.hdf5javalib.hdffile.dataobjects.messages.AttributeMessage;
8+
import org.hdf5javalib.hdffile.dataobjects.messages.HdfMessage;
9+
import org.hdf5javalib.hdffile.dataobjects.messages.LinkMessage;
10+
import org.hdf5javalib.hdfjava.HdfDataFile;
11+
import org.hdf5javalib.hdfjava.HdfDataset;
12+
import org.hdf5javalib.hdfjava.HdfFileReader;
13+
import org.slf4j.Logger;
14+
import org.slf4j.LoggerFactory;
15+
16+
import java.io.IOException;
17+
import java.lang.reflect.InvocationTargetException;
18+
import java.nio.channels.SeekableByteChannel;
19+
import java.nio.file.Files;
20+
import java.nio.file.Path;
21+
import java.nio.file.StandardOpenOption;
22+
import java.util.Arrays;
23+
import java.util.Comparator;
24+
import java.util.Optional;
25+
import java.util.stream.Collectors;
26+
27+
/**
28+
* Utility class for displaying HDF5 dataset data and managing attributes.
29+
* <p>
30+
* The {@code HdfDisplayUtils} class provides methods to display scalar and vector data
31+
* from HDF5 datasets using a {@link TypedDataSource}, as well as to create version attributes
32+
* for datasets. It supports various data types and formats the output for easy inspection,
33+
* handling both primitive and array types.
34+
* </p>
35+
*/
36+
public class HdfDisplayCountUtils {
37+
private static final Logger log = LoggerFactory.getLogger(HdfDisplayCountUtils.class);
38+
public static final String UNDEFINED = "<Undefined>";
39+
private static final String STREAM_EQUALS = " stream = ";
40+
41+
public static void displayLinkMessages(HdfObjectHeaderPrefix objectHeader) {
42+
for( HdfMessage hdfMessage: objectHeader.getHeaderMessages()) {
43+
if ( hdfMessage instanceof LinkMessage ) {
44+
LinkMessage linkMessage = (LinkMessage) hdfMessage;
45+
System.out.println("\tLinkMessage: " + linkMessage.toString());
46+
}
47+
48+
}
49+
}
50+
51+
// Define a functional interface for actions that may need channel, dataset, and reader
52+
@FunctionalInterface
53+
interface FileAction {
54+
void perform(SeekableByteChannel channel, HdfDataset dataSet, HdfFileReader reader) throws Exception;
55+
}
56+
57+
public static String undefinedArrayToString(HdfFixedPoint[] values) {
58+
if (values == null || values.length == 0) {
59+
return "Not Present";
60+
}
61+
StringBuilder sb = new StringBuilder("[");
62+
for (int i = 0; i < values.length; i++) {
63+
sb.append(values[i].isUndefined()?UNDEFINED:values[i].toString() );
64+
if (i != values.length - 1) {
65+
sb.append(", ");
66+
}
67+
}
68+
sb.append(']');
69+
return sb.toString();
70+
}
71+
72+
// Generalized method to process the file and apply a custom action per dataset
73+
private static void processFile(Path filePath, FileAction action) {
74+
try (SeekableByteChannel channel = Files.newByteChannel(filePath, StandardOpenOption.READ)) {
75+
HdfFileReader reader = new HdfFileReader(channel).readFile();
76+
for (HdfDataset dataSet : reader.getDatasets()) {
77+
System.out.println("{} " + dataSet);
78+
// log.info("{} ", dataSet);
79+
action.perform(channel, dataSet, reader);
80+
}
81+
} catch (Exception e) {
82+
log.error("Exception in processFile: {}", filePath, e);
83+
}
84+
}
85+
86+
public static void displayFileAttr(Path filePath) {
87+
processFile(filePath, (channel, dataSet, reader) -> displayAttributes(dataSet));
88+
}
89+
90+
public static void displayFile(Path filePath) {
91+
processFile(filePath, HdfDisplayCountUtils::displayData);
92+
}
93+
94+
public static void displayAttributes(HdfDataset dataSet) throws InvocationTargetException, InstantiationException, IllegalAccessException, IOException {
95+
for (AttributeMessage message : dataSet.getAttributeMessages()) {
96+
HdfDataHolder dataHolder = message.getHdfDataHolder();
97+
if (dataHolder.getDimensionality() == 1) {
98+
HdfData[] data = dataHolder.getAll(HdfData[].class);
99+
log.info("Data = {}", Arrays.toString(data));
100+
} else if (dataHolder.getDimensionality() == 2) {
101+
HdfData[][] data = dataHolder.getAll(HdfData[][].class);
102+
for (HdfData[] row : data) {
103+
log.info("Row = {}", Arrays.toString(row));
104+
}
105+
}
106+
}
107+
}
108+
109+
// public static String getDataObjectFullName(HdfDataObject hdfDataObject) {
110+
// List<String> parents = new ArrayList<>();
111+
// HdfDataObject currentNode = hdfDataObject;
112+
// while(currentNode.getParent() != null) {
113+
// parents.add(currentNode.getObjectName());
114+
// currentNode = currentNode.getParent().getDataObject();
115+
// }
116+
// Collections.reverse(parents);
117+
// String objectPathString = '/' + currentNode.getObjectName() + String.join("/", parents);
118+
// return objectPathString;
119+
// }
120+
121+
public static void displayData(SeekableByteChannel channel, HdfDataset ds, HdfFileReader reader) throws Exception {
122+
log.debug("Dataset path: {}", ds.getObjectPath());
123+
if (ds.hasData()) {
124+
switch (ds.getDimensionality()) {
125+
case 0:
126+
displayScalarData(channel, ds, HdfData.class, reader);
127+
break;
128+
case 1:
129+
displayVectorData(channel, ds, HdfData.class, reader);
130+
break;
131+
case 2:
132+
displayMatrixData(channel, ds, HdfData.class, reader);
133+
break;
134+
default:
135+
displayNDimData(channel, ds, HdfData.class, reader);
136+
break;
137+
138+
}
139+
} else if (ds.isDataset() && ds.getHardLink() != null) {
140+
log.info("{}: HARDLINK = {} ", ds.getObjectName(), ds.getHardLink());
141+
}
142+
}
143+
144+
/**
145+
* Displays scalar data from a dataset.
146+
* <p>
147+
* Reads and prints the scalar value from the dataset using both direct reading and
148+
* streaming methods, formatting the output with the dataset name and type information.
149+
* </p>
150+
*
151+
* @param fileChannel the seekable byte channel for reading the HDF5 file
152+
* @param dataSet the dataset to read from
153+
* @param clazz the class type of the data
154+
* @param hdfDataFile the HDF5 file context
155+
* @param <T> the type of the data
156+
* @throws IOException if an I/O error occurs
157+
*/
158+
public static <T> void displayScalarData(SeekableByteChannel fileChannel, HdfDataset dataSet, Class<T> clazz, HdfDataFile hdfDataFile) throws IOException, InvocationTargetException, InstantiationException, IllegalAccessException {
159+
TypedDataSource<T> dataSource = new TypedDataSource<>(fileChannel, hdfDataFile, dataSet, clazz);
160+
161+
// Optional<String> max = dataSource.parallelStreamScalar().map(h->h.toString()).max(Comparator.naturalOrder());
162+
// System.out.println(dataSet.getObjectPath() + " stream count = " + max.orElse("NO MAX"));
163+
long count = dataSource.parallelStreamScalar().count();
164+
System.out.println(dataSet.getObjectPath() + " stream count = " + String.format("%,d", count) + ":" + dataSet.getDatatype().toString());
165+
}
166+
167+
/**
168+
* Displays vector data from a dataset.
169+
* <p>
170+
* Reads and prints the vector data from the dataset using both direct reading and
171+
* streaming methods, formatting the output with type information and a comma-separated
172+
* list of values.
173+
* </p>
174+
*
175+
* @param fileChannel the seekable byte channel for reading the HDF5 file
176+
* @param dataSet the dataset to read from
177+
* @param clazz the class type of the data elements
178+
* @param hdfDataFile the HDF5 file context
179+
* @param <T> the type of the data elements
180+
* @throws IOException if an I/O error occurs
181+
*/
182+
public static <T> void displayVectorData(SeekableByteChannel fileChannel, HdfDataset dataSet, Class<T> clazz, HdfDataFile hdfDataFile) throws IOException, InvocationTargetException, InstantiationException, IllegalAccessException {
183+
TypedDataSource<T> dataSource = new TypedDataSource<>(fileChannel, hdfDataFile, dataSet, clazz);
184+
185+
// T[] resultArray = dataSource.readVector();
186+
// log.info("{} read = {}", displayType(clazz, resultArray), displayValue(resultArray));
187+
188+
// Optional<String> max = dataSource.parallelStreamVector().map(h->h.toString()).max(Comparator.naturalOrder());
189+
// System.out.println(dataSet.getObjectPath() + " stream count = " + max.orElse("NO MAX"));
190+
191+
long count = dataSource.parallelStreamVector().count();
192+
System.out.println(dataSet.getObjectPath() + " stream count = " + String.format("%,d", count) + ":" + dataSet.getDatatype().toString());
193+
}
194+
195+
/**
196+
* Displays vector data from a dataset.
197+
* <p>
198+
* Reads and prints the vector data from the dataset using both direct reading and
199+
* streaming methods, formatting the output with type information and a comma-separated
200+
* list of values.
201+
* </p>
202+
*
203+
* @param fileChannel the seekable byte channel for reading the HDF5 file
204+
* @param dataSet the dataset to read from
205+
* @param clazz the class type of the data elements
206+
* @param hdfDataFile the HDF5 file context
207+
* @param <T> the type of the data elements
208+
* @throws IOException if an I/O error occurs
209+
*/
210+
public static <T> void displayMatrixData(SeekableByteChannel fileChannel, HdfDataset dataSet, Class<T> clazz, HdfDataFile hdfDataFile) throws IOException, InvocationTargetException, InstantiationException, IllegalAccessException {
211+
TypedDataSource<T> dataSource = new TypedDataSource<>(fileChannel, hdfDataFile, dataSet, clazz);
212+
213+
long count = dataSource.parallelStreamMatrix().count();
214+
System.out.println(dataSet.getObjectPath() + " stream count = " + String.format("%,d", count) + ":" + dataSet.getDatatype().toString());
215+
}
216+
217+
/**
218+
* Displays vector data from a dataset.
219+
* <p>
220+
* Reads and prints the vector data from the dataset using both direct reading and
221+
* streaming methods, formatting the output with type information and a comma-separated
222+
* list of values.
223+
* </p>
224+
*
225+
* @param fileChannel the seekable byte channel for reading the HDF5 file
226+
* @param dataSet the dataset to read from
227+
* @param clazz the class type of the data elements
228+
* @param hdfDataFile the HDF5 file context
229+
* @param <T> the type of the data elements
230+
* @throws IOException if an I/O error occurs
231+
*/
232+
private static <T> void displayNDimData(SeekableByteChannel fileChannel, HdfDataset dataSet, Class<T> clazz, HdfDataFile hdfDataFile) throws IOException, InvocationTargetException, InstantiationException, IllegalAccessException {
233+
TypedDataSource<T> dataSource = new TypedDataSource<>(fileChannel, hdfDataFile, dataSet, clazz);
234+
235+
// String readResult = flattenedArrayToString(dataSource.readFlattened(), dataSource.getShape());
236+
// log.info("read = {}", readResult);
237+
238+
long count = dataSource.parallelStreamFlattened().count();
239+
System.out.println(dataSet.getObjectPath() + " stream count = " + String.format("%,d", count) + ":" + dataSet.getDatatype().toString());
240+
}
241+
242+
}

src/main/java/org/hdf5javalib/utils/HdfDisplayUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ private static void processFile(Path filePath, FileAction action) {
7878
for (HdfDataset dataSet : reader.getDatasets()) {
7979
System.out.println("{} " + dataSet);
8080
// log.info("{} ", dataSet);
81-
// action.perform(channel, dataSet, reader);
81+
action.perform(channel, dataSet, reader);
8282
}
8383
} catch (Exception e) {
8484
log.error("Exception in processFile: {}", filePath, e);
@@ -90,7 +90,7 @@ public static void displayFileAttr(Path filePath) {
9090
}
9191

9292
public static void displayFile(Path filePath) {
93-
processFile(filePath, HdfDisplayUtils::displayData);
93+
processFile(filePath, HdfDisplayCountUtils::displayData);
9494
}
9595

9696
public static void displayAttributes(HdfDataset dataSet) throws InvocationTargetException, InstantiationException, IllegalAccessException, IOException {

0 commit comments

Comments
 (0)