diff --git a/core/src/main/scala/eu/nomad_lab/h5/ArchiveH5.scala b/core/src/main/scala/eu/nomad_lab/h5/ArchiveH5.scala index a605a7b2d46bca0a7f36e7f575054b2e41baa4f8..2f6ddc84698ec3371cfc117e344765e0eb295c44 100644 --- a/core/src/main/scala/eu/nomad_lab/h5/ArchiveH5.scala +++ b/core/src/main/scala/eu/nomad_lab/h5/ArchiveH5.scala @@ -1,6 +1,13 @@ package eu.nomad_lab.h5 import eu.nomad_lab.{ H5Lib, RefCount } +import hdf.hdf5lib.{ H5, HDF5Constants } + +case class GroupObjectInfoH5( + oname: String, + otype: Int, + orefs: Long +) /** * represents an archive in an hdf5 file @@ -19,6 +26,16 @@ class ArchiveH5( H5Lib.groupClose(archiveGroup) fileH5.release() } + + protected var calcRemaining: Int = 0 + protected var cursor: Int = 0 + val count = if (archiveGroup >= 0) H5.H5Gn_members(archiveGroup, "/").toInt else 0 + protected var childNames: Array[String] = new Array[String](count) + protected var childTypes: Array[Int] = new Array[Int](count) + protected var lTypes: Array[Int] = new Array[Int](count) + protected var childRefs: Array[Long] = new Array[Long](count) + protected var currentCalc: Option[CalculationH5] = None + val archiveRef = this /** * returns a calculation with the given gid if contained in this archive @@ -30,4 +47,48 @@ class ArchiveH5( calculationGroup = H5Lib.groupGet(archiveGroup, calculationGid, false) ) } + def closeLastCalculation() = { + currentCalc match { + case None => () + case Some(calc) => + H5Lib.groupClose(calc.calculationGroup) + } + } + + if (archiveGroup >= 0) { + H5.H5Gget_obj_info_all(archiveGroup, "/", childNames, childTypes, lTypes, childRefs, HDF5Constants.H5_INDEX_NAME) + calcRemaining = childNames.length + } + + def iterator: Iterator[CalculationH5] = new Iterator[CalculationH5] { + + override def hasNext: Boolean = if (calcRemaining > 0) true else false + + override def next(): CalculationH5 = { + closeLastCalculation() + if (hasNext) { + currentCalc = Some(new CalculationH5( + archive = archiveRef, + calculationGid = childNames(cursor), + calculationGroup = H5Lib.groupGet(archiveGroup, childNames(cursor), false) + )) + calcRemaining -= 1 + cursor += 1 + currentCalc.get + } else + throw new java.util.NoSuchElementException("Next on empty iterator") + } + } + +// def visit():org.json4s.JValue = { +// val itr = iterator +// var res = org.json4s.JObject() +// itr foreach( c => res = res + c.visit) +// } } +/* override def apply(idx: Int): CalculationH5 = { + new CalculationH5( archive = archiveRef, + calculationGid = oname(idx), + calculationGroup = H5Lib.groupOpen(archiveGroup,oname(idx)) + ) + }*/ \ No newline at end of file diff --git a/core/src/main/scala/eu/nomad_lab/h5/CalculationH5.scala b/core/src/main/scala/eu/nomad_lab/h5/CalculationH5.scala index 50459c36eb57561b51cdfcc3fd324f5bd70eb4ab..ea7bf50012888ba4e0d30d99d3ed16701f329048 100644 --- a/core/src/main/scala/eu/nomad_lab/h5/CalculationH5.scala +++ b/core/src/main/scala/eu/nomad_lab/h5/CalculationH5.scala @@ -7,7 +7,7 @@ import eu.nomad_lab.JsonUtils import eu.nomad_lab.meta.KnownMetaInfoEnvs import eu.nomad_lab.meta.MetaInfoEnv import eu.nomad_lab.meta.MetaInfoRecord - +import org.json4s.{ JArray, JBool, JDecimal, JDouble, JField, JInt, JNothing, JNull, JObject, JString, JValue } import scala.collection.mutable object CalculationH5 { @@ -36,6 +36,7 @@ class CalculationH5( val sectionTables0: Map[String, SectionTableH5] = Map(), val valueTables0: Map[String, ValueTableH5] = Map() ) extends RefCount { + archive.retain() def metaInfoEnv: MetaInfoEnv = { @@ -121,7 +122,11 @@ class CalculationH5( } } } - +// def visit: JValue = { +// JObject( +// JField("calculationGid",JString(calculationGid) )::Nil +// ) +// } /** * clears the value table cache */ diff --git a/core/src/main/scala/eu/nomad_lab/h5/Section.scala b/core/src/main/scala/eu/nomad_lab/h5/Section.scala index cf66652db7b808798e5c702b4ab4feb65133d121..270058c4d4c8a3712cb099d14e08aa056a5eddaf 100644 --- a/core/src/main/scala/eu/nomad_lab/h5/Section.scala +++ b/core/src/main/scala/eu/nomad_lab/h5/Section.scala @@ -245,7 +245,7 @@ class SectionCollectionH5( /** * gIndex of the last section in this collection (inclusive) * - * If there are no entires then upperGIndex < lowerGIndex + * If there are no entries then upperGIndex < lowerGIndex */ val upperGIndex: Long = upperGIndex0 match { case Some(i) => i @@ -267,7 +267,7 @@ class SectionCollectionH5( /** * gIndex of the first section in this collection (inclusive) * - * If there are no entires then upperGIndex < lowerGIndex + * If there are no entries then upperGIndex < lowerGIndex */ var lowerGIndex: Long = lowerGIndex0 match { case Some(i) => i diff --git a/core/src/main/scala/eu/nomad_lab/h5/Value.scala b/core/src/main/scala/eu/nomad_lab/h5/Value.scala index 2ccbe27dbfda0ffcd86012613b4a84fa30e01237..0f8f8791d9490bae64d8b8f86711e4aba3a57469 100644 --- a/core/src/main/scala/eu/nomad_lab/h5/Value.scala +++ b/core/src/main/scala/eu/nomad_lab/h5/Value.scala @@ -859,7 +859,7 @@ abstract class ValueArrayH5[T <: NArray]( } } - override def arrayValue(valueOffset: Seq[Long] = Seq(), valueDims: Seq[Long] = Seq()): T; + override def arrayValue(valueOffset: Seq[Long] = Seq(), valueDims: Seq[Long] = Seq()): T def jValue: jn.JValue = { val shape = arrayShape diff --git a/core/src/test/scala/eu/nomad_lab/h5/FileH5Spec.scala b/core/src/test/scala/eu/nomad_lab/h5/FileH5Spec.scala index 38839b586cf7ec3d14f24a7e71c2b281b4e95dce..2a490a04bbf9505504586a787cb2160fac6a0530 100644 --- a/core/src/test/scala/eu/nomad_lab/h5/FileH5Spec.scala +++ b/core/src/test/scala/eu/nomad_lab/h5/FileH5Spec.scala @@ -8,18 +8,26 @@ object FileH5Spec extends Specification { skipAllUnless(H5Lib.readSupport) "h5Tests" >> { - val fileH5 = FileH5(filePath = Paths.get("src/test/resources/testMetaInfoCompiler/P0Hx_S10YdRE_zQvqKyvYWSPw_pyK.h5")) - val archiveH5 = fileH5.archive("RseHEMpz-OaPkanAHPxea8srdAPjh") - val calculation = archiveH5.calculation("C0Hx_S10YdRE_zQvqKyvYWSPw_pyK") - val section_run: SectionTableH5 = calculation.sectionTable("section_run") - val firstRun = section_run(0) - val singleConfTable = firstRun.table.subSectionTable("section_single_configuration_calculation") - val firstConf = singleConfTable(0) - val energies = firstConf.table.subValueTable("energy_total") - val energy = energies(0) - "energy" >> { - energy.isEmpty must_== (false) + "should be able to read the energy value stored in HDF5 file" >> { + val fileH5 = FileH5(filePath = Paths.get("src/test/resources/testMetaInfoCompiler/P0Hx_S10YdRE_zQvqKyvYWSPw_pyK.h5")) + val archiveH5 = fileH5.archive("RseHEMpz-OaPkanAHPxea8srdAPjh") + val calculation = archiveH5.calculation("C0Hx_S10YdRE_zQvqKyvYWSPw_pyK") + val section_run: SectionTableH5 = calculation.sectionTable("section_run") + val firstRun = section_run(0) + val singleConfTable = section_run.subSectionTable("section_single_configuration_calculation") + val firstConf = singleConfTable(0) + val energies = singleConfTable.subValueTable("energy_total") + val (datasetName, datasetId) = energies.openValueDataset(Seq(1)) + val v = energies.valueGetLocal(datasetId, 0) +// println(v) + singleConfTable.closeSectionGroup() + section_run.isEmpty must_== false + firstRun.isEmpty must_== false + firstConf.isEmpty must_== false + energies.isEmpty must_== false + v.getDouble(0) == -1.6605525795476488E-13 must_== true + } }