Skip to content

Commit b6e39ac

Browse files
author
Martin D. Weinberg
committed
Add static functions to read and parse HDF5 directories to save the user the trouble of having to pass full file lists (which will still work)
1 parent 29ade32 commit b6e39ac

2 files changed

Lines changed: 86 additions & 2 deletions

File tree

exputil/ParticleReader.cc

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <filesystem>
12
#include <algorithm>
23
#include <iostream>
34
#include <iomanip>
@@ -7,6 +8,7 @@
78
#include <numeric>
89
#include <string>
910
#include <vector>
11+
#include <cctype>
1012
// HighFive API
1113
#include <H5Cpp.h>
1214
#include <highfive/highfive.hpp>
@@ -638,17 +640,66 @@ namespace PR {
638640
else return 0;
639641
}
640642
}
643+
644+
std::vector<std::string>
645+
ParticleReader::scanDirectory(const std::string& dir)
646+
{
647+
// Will contain the filenames from the directory scan
648+
std::vector<std::string> ret;
649+
650+
// Check if the directory exists
651+
std::filesystem::path p(dir);
652+
653+
// If the directory does not exist, ret will be returned with zero
654+
// length
655+
if (std::filesystem::is_directory(p)) {
656+
657+
// Iterate over the directory entries
658+
for (const auto& entry : std::filesystem::directory_iterator(p)) {
659+
660+
// Check if the entry is a regular file
661+
if (std::filesystem::is_regular_file(entry.status())) {
662+
663+
// Get the filename
664+
std::string filename = entry.path().string();
665+
666+
// Check if the last character is a digit
667+
if (std::isdigit(filename.back())) {
668+
669+
// Assume that this is a snapshot file. We could check if
670+
// this is HDF5 here but I'd rather that this procedure be
671+
// file-type agnostic.
672+
ret.push_back(filename);
673+
}
674+
}
675+
}
676+
}
677+
678+
return ret;
679+
}
641680

642-
681+
643682
PSPhdf5::PSPhdf5(const std::vector<std::string>& files, bool verbose)
644683
{
645684
_files = files;
646685
_verbose = verbose;
647686

687+
// Do we have a directory of snapshot files?
688+
//
689+
if (_files.size()==1) {
690+
std::vector<std::string> fscan = scanDirectory(_files[0]);
691+
if (fscan.size() != 0) _files = fscan;
692+
// Put the first file at the top of the list
693+
std::partial_sort(_files.begin(), _files.begin()+1, _files.end());
694+
}
695+
696+
// Read metadata from the first file
697+
//
648698
getInfo();
649699

650700
// Sanity check
651-
if (nfiles != files.size())
701+
//
702+
if (nfiles != _files.size())
652703
throw GenericError("PSPhdf5: number of files does not match number expected for this snapshot", __FILE__, __LINE__, 1042, true);
653704

654705
curfile = _files.begin();
@@ -1832,6 +1883,28 @@ namespace PR {
18321883
return parseStringList(files, delimit);
18331884
}
18341885

1886+
// Are all the files in the list directories?
1887+
bool
1888+
ParticleReader::parseDirectoryList(const std::vector<std::string>& files)
1889+
{
1890+
int dcount = 0; // The directory count
1891+
int fcount = 0; // The file count
1892+
1893+
for (auto f : files) {
1894+
if (std::filesystem::is_directory(f))
1895+
dcount++;
1896+
else
1897+
fcount++;
1898+
}
1899+
1900+
if (dcount>0 and fcount>0)
1901+
throw std::runtime_error("ParticleReader::parseDirectoryList: "
1902+
"cannot mix directories and files");
1903+
1904+
return dcount>0;
1905+
}
1906+
1907+
18351908
std::vector<std::vector<std::string>>
18361909
ParticleReader::parseStringList
18371910
(const std::vector<std::string>& infiles, const std::string& delimit)
@@ -1842,6 +1915,14 @@ namespace PR {
18421915
auto files = infiles;
18431916
std::sort(files.begin(), files.end());
18441917

1918+
// Check to see if these are all directories
1919+
if (parseDirectoryList(files)) {
1920+
for (auto d : files) {
1921+
batches.push_back(std::vector<std::string>{d});
1922+
}
1923+
return batches;
1924+
}
1925+
18451926
std::vector<std::string> batch;
18461927
std::string templ;
18471928

include/ParticleReader.H

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ namespace PR
3636
int numprocs, myid;
3737
bool use_mpi;
3838

39+
static bool parseDirectoryList(const std::vector<std::string>& files);
40+
static std::vector<std::string> scanDirectory(const std::string& dir);
41+
3942
public:
4043

4144
//! Constructor: check for and set up MPI

0 commit comments

Comments
 (0)