File indexing completed on 2026-07-16 08:14:22
0001 #include <Garfield/MediumMagboltz.hh>
0002 #include <phool/phool.h>
0003
0004 #include <filesystem>
0005 #include <iostream>
0006 #include <map>
0007 #include <regex>
0008 #include <set>
0009 #include <string>
0010 #include <utility>
0011 #include <sstream>
0012 #include <iomanip>
0013 #include <exception>
0014
0015
0016 namespace fs = std::filesystem;
0017 std::string mergedName(const std::string& path, unsigned int eindex);
0018
0019 bool searchAndUnpackDirectory(
0020 const std::string& directoryPath,
0021 std::set<unsigned int>& Eindices,
0022 std::set<unsigned int>& Bindices,
0023 std::map<std::pair<unsigned int, unsigned int>, std::string>& FileList);
0024
0025 int main(int argc, char* argv[])
0026 {
0027 try
0028 {
0029 if (argc != 3)
0030 {
0031 std::cerr << "Usage:\n"
0032 << argv[0]
0033 << " path_to_gasfiles name_of_output_file\n";
0034 return 1;
0035 }
0036
0037 const std::string path = argv[1];
0038 const std::string output = path + "/" + argv[2];
0039
0040 std::set<unsigned int> Eindices;
0041 std::set<unsigned int> Bindices;
0042 std::map<std::pair<unsigned int, unsigned int>, std::string> FileList;
0043
0044 if (!searchAndUnpackDirectory(path, Eindices, Bindices, FileList))
0045 {
0046 std::cerr << PHWHERE << " Imperfect directory." << std::endl;
0047 return 1;
0048 }
0049
0050 Garfield::MediumMagboltz gas;
0051
0052 for (const auto Eindex : Eindices)
0053 {
0054 bool firstB = true;
0055
0056 for (const auto Bindex : Bindices)
0057 {
0058 const auto it = FileList.find({Eindex, Bindex});
0059 if (it == FileList.end())
0060 {
0061 std::cerr << PHWHERE << " Missing file for E=" << Eindex
0062 << " B=" << Bindex << std::endl;
0063 return 1;
0064 }
0065
0066 const std::string& nextfile = it->second;
0067
0068 if (firstB)
0069 {
0070 gas.LoadGasFile(nextfile);
0071 firstB = false;
0072 }
0073 else
0074 {
0075 gas.MergeGasFile(nextfile, true);
0076 }
0077 }
0078
0079 const std::string mergedFile = mergedName(path, Eindex);
0080
0081 std::cout << "Writing " << mergedFile << std::endl;
0082 gas.WriteGasFile(mergedFile);
0083
0084 std::vector<double> nE;
0085 std::vector<double> nB;
0086 std::vector<double> nA;
0087 gas.GetFieldGrid(nE, nB, nA);
0088
0089 std::cout << "Merged Gas File created: "<< mergedFile
0090 << " with Grid Dimensions: "
0091 << nE.size() << " E-fields, "
0092 << nB.size() << " B-fields, "
0093 << nA.size() << " Angles." << std::endl;
0094 }
0095
0096 bool firstE = true;
0097
0098 for (const auto Eindex : Eindices)
0099 {
0100
0101 const std::string mergedFile = mergedName(path, Eindex);
0102
0103 if (!fs::exists(mergedFile))
0104 {
0105 std::cerr << PHWHERE << " Missing merged file " << mergedFile << std::endl;
0106 return 1;
0107 }
0108
0109 if (firstE)
0110 {
0111 gas.LoadGasFile(mergedFile);
0112 firstE = false;
0113 }
0114 else
0115 {
0116 gas.MergeGasFile(mergedFile, true);
0117 }
0118 }
0119
0120 std::cout << "Writing final file " << output << std::endl;
0121 gas.WriteGasFile(output);
0122
0123 std::vector<double> nE;
0124 std::vector<double> nB;
0125 std::vector<double> nA;
0126 gas.GetFieldGrid(nE, nB, nA);
0127
0128 std::cout << "Final Gas File created: "<< output
0129 << " with Grid Dimensions: "
0130 << nE.size() << " E-fields, "
0131 << nB.size() << " B-fields, "
0132 << nA.size() << " Angles." << std::endl;
0133
0134 return 0;
0135 }
0136
0137 catch (const std::exception& e)
0138 {
0139 std::cerr << PHWHERE << " Exception: " << e.what() << std::endl;
0140 return 1;
0141 }
0142 catch (...)
0143 {
0144 std::cerr << PHWHERE << " Unknown exception." << std::endl;
0145 return 1;
0146 }
0147 }
0148
0149 bool searchAndUnpackDirectory(const std::string& directoryPath, std::set<unsigned int> &Eindices, std::set<unsigned int> &Bindices, std::map<std::pair<unsigned int, unsigned int>, std::string> &FileList)
0150 {
0151
0152 if (!fs::exists(directoryPath) || !fs::is_directory(directoryPath))
0153 {
0154 std::cerr << "Error: Invalid directory path." << std::endl;
0155 return false;
0156 }
0157
0158 std::regex filePattern(R"(^E([0-9]{3})_B([0-9]{3})\.gas$)");
0159 std::smatch matchResults;
0160
0161
0162 for (const auto& entry : fs::directory_iterator(directoryPath))
0163 {
0164
0165 if (entry.is_regular_file())
0166 {
0167 std::string filename = entry.path().filename().string();
0168
0169
0170 if (std::regex_match(filename, matchResults, filePattern))
0171 {
0172
0173
0174
0175 unsigned int eValue = std::stoul(matchResults[1].str());
0176 unsigned int bValue = std::stoul(matchResults[2].str());
0177 Eindices.insert(eValue);
0178 Bindices.insert(bValue);
0179 FileList[{eValue, bValue}] = entry.path().string();
0180 }
0181 }
0182 }
0183
0184
0185 if (Eindices.empty()) { return false; }
0186 if (Bindices.empty()) { return false; }
0187
0188 unsigned int maxE = *Eindices.rbegin();
0189 unsigned int maxB = *Bindices.rbegin();
0190 for (unsigned int i=0; i<=maxE; i++)
0191 {
0192 for (unsigned int j=0; j<=maxB; j++)
0193 {
0194 if ( !FileList.contains({i,j}) ) { return false; }
0195 }
0196 }
0197
0198 std::cout << " *** Gas File List Valid ***" << std::endl;
0199 std::cout << "Electric field indices 0 --> " << maxE << std::endl;
0200 std::cout << "Magnetic field indices 0 --> " << maxB << std::endl;
0201
0202 return true;
0203 }
0204
0205 std::string mergedName(const std::string& path, unsigned int eindex)
0206 {
0207 std::ostringstream name;
0208 name << path << "/MERGED_E"
0209 << std::setw(3) << std::setfill('0') << eindex
0210 << ".gas";
0211 return name.str();
0212 }