Main
unknown
c_cpp
21 days ago
6.9 kB
8
Indexable
#include <iostream> #include <fstream> #include <vector> #include <string> #include <sstream> #include <algorithm> #include <numeric> #include <filesystem> #include <map> #include <set> #include <functional> #include <unordered_set> using namespace std; namespace fs = filesystem; struct Parameters { int vt, width, pulse_delta, below_drop_ratio; double drop_ratio; }; bool parseIniFile(const string& filename, Parameters& params) { ifstream file(filename); if (!file) { cerr << "Invalid INI file: " << filename << " could not be opened.\n"; return false; } map<string, string> paramMap; set<string> allowedKeys = { "vt", "width", "pulse_delta", "drop_ratio", "below_drop_ratio" }; string line; while (getline(file, line)) { if (line.empty() || line[0] == '#') continue; istringstream iss(line); string key, value; if (getline(iss, key, '=') && getline(iss, value)) { // Checking for any unexpected keys if (allowedKeys.find(key) == allowedKeys.end()) { cerr << "Invalid or duplicate INI key: " << key << "\n"; return false; } // Checking for duplicates if (paramMap.find(key) != paramMap.end()) { cerr << "Invalid or duplicate INI key: " << key << "\n"; return false; } paramMap[key] = value; } } // Check for missing keys for (const string& requiredKey : allowedKeys) { if (paramMap.find(requiredKey) == paramMap.end()) { cerr << "Invalid INI file: missing one or more keys\n"; return false; } } try { params.vt = stoi(paramMap.at("vt")); params.width = stoi(paramMap.at("width")); params.pulse_delta = stoi(paramMap.at("pulse_delta")); params.drop_ratio = stod(paramMap.at("drop_ratio")); params.below_drop_ratio = stoi(paramMap.at("below_drop_ratio")); } catch (const invalid_argument& e) { cerr << "Invalid value for vt in " << filename << "\n"; return false; } return true; } vector<int> readAndNegateFile(const string& filename) { ifstream file(filename); vector<int> data((istream_iterator<int>(file)), istream_iterator<int>()); transform(data.begin(), data.end(), data.begin(), negate<int>()); return data; } vector<int> smoothData(const vector<int>& data) { if (data.size() < 7) return data; vector<int> smoothed; copy(data.begin(), data.begin() + 3, back_inserter(smoothed)); for (size_t i = 3; i < data.size() - 3; ++i) { int avg = ((data[i - 3]) + (2 * data[i - 2]) + (3 * data[i - 1]) + (3 * data[i]) + (3 * data[i + 1]) + (2 * data[i + 2]) + (data[i + 3])) / 15; smoothed.push_back(avg); } copy(data.end() - 3, data.end(), back_inserter(smoothed)); return smoothed; } vector<int> detectPulses(const vector<int>& smoothed, int vt) { vector<int> pulses; for (size_t i = 0; i < smoothed.size() - 2; ++i) { if (smoothed[i + 2] - smoothed[i] > vt) { pulses.push_back(i); while (i + 2 < smoothed.size() && smoothed[i + 2] >= smoothed[i]) { i++; } } } return pulses; } void processFiles(const Parameters& params) { for (const auto& entry : fs::directory_iterator(".")) { if (entry.path().extension() == ".dat") { vector<int> data = readAndNegateFile(entry.path().string()); if (data.empty()) continue; vector<int> smoothed = smoothData(data); vector<int> pulses = detectPulses(smoothed, params.vt); if (pulses.empty()) continue; cout << entry.path().filename() << ":\n"; unordered_set<int> ignored_pulses; for (auto it = pulses.begin(); it != pulses.end(); ++it) { auto nextIt = adjacent_find(it, pulses.end(), [params](int a, int b) { return b - a <= params.pulse_delta; }); if (nextIt != pulses.end()) { int firstPulse = *it; int nextPulse = *nextIt; int peak = smoothed[firstPulse]; for (int j = firstPulse + 1; j <= nextPulse; ++j) { peak = max(peak, smoothed[j]); } if (peak > 0) { int drop_count = 0; for (int j = firstPulse + 1; j < nextPulse; ++j) { if (smoothed[j] > params.drop_ratio * peak) { drop_count++; } } if (drop_count < params.below_drop_ratio) { // Ensure the first pulse is not already ignored if (ignored_pulses.count(firstPulse) == 0) { ignored_pulses.insert(firstPulse); cout << "Found piggyback at " << firstPulse << "\n"; } } } it = nextIt; } } for (size_t i = 0; i < pulses.size(); ++i) { if (ignored_pulses.count(pulses[i])) continue; int pulseStart = pulses[i]; int pulseEnd = min(pulseStart + params.width, static_cast<int>(data.size())); for (size_t j = i + 1; j < pulses.size(); ++j) { if (pulses[j] < pulseEnd) { pulseEnd = pulses[j]; break; } } int area = 0; for (int k = pulseStart; k < pulseEnd && k < data.size(); ++k) { area += data[k]; } cout << pulseStart << " (" << area << ")\n"; } } } } void printParameters(const Parameters& params) { cout << "# Pulse parameters\n"; cout << "vt = " << params.vt << "\n"; cout << "width = " << params.width << "\n"; cout << "pulse_delta = " << params.pulse_delta << "\n"; cout << "drop_ratio = " << params.drop_ratio << "\n"; cout << "below_drop_ratio = " << params.below_drop_ratio << "\n"; cout << "\n"; } int main(int argc, char* argv[]) { if (argc != 2) { cerr << "Usage: " << argv[0] << " <ini_file>\n"; return 1; } Parameters params; if (!parseIniFile(argv[1], params)) { return 1; } printParameters(params); processFiles(params); return 0; }
Editor is loading...
Leave a Comment