File indexing completed on 2025-01-18 10:17:41
0001
0002
0003
0004
0005
0006
0007
0008 #include "JEventProcessor_regressiontest.h"
0009 #include "JANA/Utils/JInspector.h"
0010
0011 #include <tuple>
0012
0013
0014
0015 extern "C" {
0016 void InitPlugin(JApplication *app) {
0017 InitJANAPlugin(app);
0018 app->Add(new JEventProcessor_regressiontest());
0019 app->SetParameterValue("record_call_stack", true);
0020 }
0021 }
0022
0023
0024
0025
0026 void JEventProcessor_regressiontest::Init()
0027 {
0028 auto app = GetApplication();
0029 app->SetTicker(false);
0030 app->SetTimeoutEnabled(false);
0031 app->SetDefaultParameter("regressiontest:interactive", interactive);
0032 app->SetDefaultParameter("regressiontest:old_log", old_log_file_name);
0033 app->SetDefaultParameter("regressiontest:new_log", new_log_file_name);
0034 LOG << "Running regressiontest plugin" << LOG_END;
0035 old_log_file.open(old_log_file_name);
0036 if (old_log_file.good()) {
0037 have_old_log_file = true;
0038 }
0039 new_log_file.open(new_log_file_name);
0040
0041 blacklist_file.open(blacklist_file_name);
0042 std::string line;
0043 while (std::getline(blacklist_file, line)) {
0044 blacklist.insert(line);
0045 }
0046 }
0047
0048
0049
0050
0051 void JEventProcessor_regressiontest::BeginRun(const std::shared_ptr<const JEvent>&)
0052 {
0053 }
0054
0055
0056
0057
0058 void JEventProcessor_regressiontest::Process(const std::shared_ptr<const JEvent>& event)
0059 {
0060 auto evt_nr = event->GetEventNumber();
0061 for (auto fac : event->GetAllFactories()) {
0062 fac->Create(event);
0063 }
0064 auto facs = GetFactoriesTopologicallyOrdered(*event);
0065
0066 std::lock_guard<std::mutex> lock(m_mutex);
0067
0068 std::map<std::string, std::vector<std::string>> old_event_log;
0069 std::set<std::string> event_discrepancies;
0070 if (have_old_log_file) {
0071
0072 std::string line = "throwaway";
0073 while (true) {
0074
0075
0076 std::getline(old_log_file, line);
0077 if (line.empty()) break;
0078 int item_count;
0079 std::string fac_key;
0080 auto pair = ParseFactorySummary(line);
0081 fac_key = pair.first;
0082 item_count = pair.second;
0083
0084 std::vector<std::string> jobjs_summaries;
0085 for (int i=0; i<item_count; ++i) {
0086 std::getline(old_log_file, line);
0087 jobjs_summaries.push_back(line);
0088 }
0089 old_event_log[fac_key] = std::move(jobjs_summaries);
0090 }
0091 }
0092
0093 for (auto fac : facs) {
0094 bool found_discrepancy = false;
0095 auto jobs = fac->GetAs<JObject>();
0096 auto item_ct = jobs.size();
0097
0098
0099 std::ostringstream os;
0100 std::string fac_key = fac->GetObjectName();
0101 if (!fac->GetTag().empty()) fac_key += ":" + fac->GetTag();
0102
0103 os << evt_nr << "\t" << fac_key << "\t" << item_ct;
0104 std::string count_line = os.str();
0105
0106 new_log_file << count_line << std::endl;
0107
0108 std::vector<std::string> new_object_lines;
0109
0110 for (auto obj : jobs) {
0111
0112 JObjectSummary summary;
0113 obj->Summarize(summary);
0114
0115 std::stringstream ss;
0116 ss << evt_nr << "\t" << fac_key << "\t";
0117 ss << "{";
0118 for (auto& field : summary.get_fields()) {
0119 if (field.name == "JObject" || field.name == "id") continue;
0120 std::string blacklist_entry = fac_key + "\t" + field.name;
0121 if (blacklist.find(blacklist_entry) == blacklist.end()) {
0122 ss << field.name << ": " << field.value << ", ";
0123 }
0124 }
0125 ss << "}";
0126 new_object_lines.push_back(ss.str());
0127 }
0128
0129 std::sort(new_object_lines.begin(), new_object_lines.end());
0130 for (const auto& s : new_object_lines) {
0131 new_log_file << s << std::endl;
0132 }
0133
0134 if (have_old_log_file) {
0135 const std::vector<std::string>& old_object_lines = old_event_log[fac_key];
0136 if (item_ct != old_object_lines.size()) {
0137 found_discrepancy = true;
0138 event_discrepancies.insert(fac_key);
0139 std::cout << "MISCOUNT: " << fac_key << ", old=" << old_object_lines.size() << ", new=" << item_ct << std::endl;
0140 }
0141 else {
0142 for (size_t i=0; i<item_ct; ++i) {
0143 if (old_object_lines[i] != new_object_lines[i]) {
0144 found_discrepancy = true;
0145 event_discrepancies.insert(fac_key);
0146 std::cout << "MISMATCH: " << fac_key << std::endl;
0147 std::cout << "OLD OBJ: " << old_object_lines[i] << std::endl;
0148 std::cout << "NEW OBJ: " << new_object_lines[i] << std::endl;
0149 }
0150 }
0151 }
0152 }
0153 if (found_discrepancy) discrepancy_counts[fac_key] += 1;
0154 }
0155 new_log_file << std::endl;
0156
0157 if (interactive) {
0158 auto inspector = event->GetJInspector();
0159 inspector->SetDiscrepancies(std::move(event_discrepancies));
0160 inspector->Loop();
0161 }
0162 }
0163
0164
0165
0166
0167 void JEventProcessor_regressiontest::EndRun()
0168 {
0169 }
0170
0171
0172
0173
0174 void JEventProcessor_regressiontest::Finish()
0175 {
0176 std::cout << "OVERALL DISCREPANCIES" << std::endl;
0177 for (auto p : discrepancy_counts) {
0178 std::cout << p.first << "\t" << p.second << std::endl;
0179 }
0180 new_log_file.close();
0181 if (have_old_log_file) {
0182 old_log_file.close();
0183 }
0184 }
0185
0186
0187 std::vector<JFactory*> JEventProcessor_regressiontest::GetFactoriesTopologicallyOrdered(const JEvent& event) {
0188
0189 std::map<std::pair<std::string,std::string>, std::pair<JFactory*, bool>> factories;
0190 std::vector<JFactory*> sorted_factories;
0191
0192 for (JFactory* fac : event.GetAllFactories()) {
0193 factories[std::make_pair(fac->GetObjectName(), fac->GetTag())] = std::make_pair(fac, false);
0194 }
0195
0196 auto topologicalOrdering = event.GetJCallGraphRecorder()->TopologicalSort();
0197 for (auto pair : topologicalOrdering) {
0198 auto fac_name = pair.first;
0199 auto fac_tag = pair.second;
0200 auto result = factories.find(std::make_pair(fac_name,fac_tag));
0201 if (result != factories.end()) {
0202 result->second.second = true;
0203 sorted_factories.push_back(result->second.first);
0204 }
0205 }
0206
0207 for (auto pair : factories) {
0208 if (pair.second.second == false) {
0209 sorted_factories.push_back(pair.second.first);
0210 }
0211 }
0212 return sorted_factories;
0213
0214 }
0215
0216 std::pair<std::string, int> JEventProcessor_regressiontest::ParseFactorySummary(std::string line) {
0217
0218 std::istringstream iss(line);
0219 std::string facname;
0220 std::string split;
0221 std::getline(iss, split, '\t');
0222 std::getline(iss, facname, '\t');
0223 int count;
0224 iss >> count;
0225 if (iss.fail()) {
0226 throw JException("Unable to parse factory summary");
0227 }
0228 return std::make_pair(facname, count);
0229
0230 }