Line data Source code
1 : //
2 : // DUNE DAQ modification notice:
3 : // This file has been modified from the original ATLAS oks_utils source for the DUNE DAQ project.
4 : // Fork baseline commit: c2e7dfc7 (2022-03-30).
5 : // Renamed since fork: yes (from src/bin/oks_report_equal_objects.cpp to apps/oks_report_equal_objects.cxx).
6 : //
7 :
8 : /**
9 : * \file oks_diff_data.cpp
10 : *
11 : * This file is part of the OKS package.
12 : * Author: <Igor.Soloviev@cern.ch>
13 : *
14 : * This file contains the implementation of the OKS application to show equal objects.
15 : */
16 :
17 : #include <iostream>
18 : #include <sstream>
19 :
20 : #include <map>
21 : #include <set>
22 :
23 : #include <boost/program_options.hpp>
24 :
25 : #include "oks/attribute.hpp"
26 : #include "oks/class.hpp"
27 : #include "oks/kernel.hpp"
28 : #include "oks/object.hpp"
29 : #include "oks/relationship.hpp"
30 :
31 : using namespace dunedaq;
32 : using namespace dunedaq::oks;
33 : ////////////////////////////////////////////////////////////////////////////////////////////////////
34 :
35 : struct SortObjById
36 : {
37 0 : bool operator()(const OksObject* o1, const OksObject* o2) const { return o1->GetId() < o2->GetId(); }
38 : };
39 :
40 : typedef std::set<const OksObject*, SortObjById> ObjsSet;
41 :
42 : ////////////////////////////////////////////////////////////////////////////////////////////////////
43 :
44 : static void
45 0 : process_class(const OksClass* c, bool verbose)
46 : {
47 0 : bool printed_class(false);
48 :
49 0 : if (verbose) {
50 0 : std::cout << "* processing class \'" << c->get_name() << "\'" << std::endl;
51 : printed_class = true;
52 : }
53 :
54 0 : const OksObject::Map* objects = c->objects();
55 0 : if (!objects || objects->empty()) {
56 0 : if (verbose) {
57 0 : std::cout << " no objects" << std::endl;
58 : }
59 0 : return;
60 : }
61 :
62 0 : std::multimap<std::string, const OksObject*> vals;
63 :
64 0 : const std::list<OksAttribute*>* alist = c->all_attributes();
65 0 : const std::list<OksRelationship*>* rlist = c->all_relationships();
66 :
67 0 : OksDataInfo di(0, (const OksAttribute*)(0));
68 :
69 0 : for (OksObject::Map::const_iterator i = objects->begin(); i != objects->end(); ++i) {
70 0 : const OksObject* o(i->second);
71 0 : std::ostringstream s;
72 0 : OksData* d(o->GetAttributeValue(&di));
73 :
74 0 : if (alist) {
75 0 : for (std::list<OksAttribute*>::const_iterator j = alist->begin(); j != alist->end(); ++j, ++d) {
76 0 : s << (*j)->get_name() << *d << '\n';
77 : }
78 : }
79 :
80 0 : if (rlist) {
81 0 : for (std::list<OksRelationship*>::const_iterator j = rlist->begin(); j != rlist->end(); ++j, ++d) {
82 0 : s << (*j)->get_name() << *d << '\n';
83 : }
84 : }
85 :
86 0 : s << std::ends;
87 :
88 0 : vals.insert(std::make_pair(s.str(), o));
89 0 : }
90 :
91 0 : std::string last;
92 0 : const OksObject* prev(0);
93 :
94 0 : for (std::multimap<std::string, const OksObject*>::iterator i = vals.begin(); i != vals.end();) {
95 0 : if (last == i->first) {
96 0 : ObjsSet equal_objs;
97 0 : equal_objs.insert(prev);
98 0 : equal_objs.insert(i->second);
99 0 : ++i;
100 0 : for (; i != vals.end(); ++i) {
101 0 : if (last == i->first) {
102 0 : equal_objs.insert(i->second);
103 : } else {
104 0 : if (!printed_class) {
105 0 : std::cout << "* found equal objects in class \'" << c->get_name() << "\'" << std::endl;
106 : printed_class = true;
107 : }
108 :
109 0 : std::cout << " # the following " << equal_objs.size() << " objects are equal:\n";
110 0 : for (ObjsSet::const_iterator j = equal_objs.begin(); j != equal_objs.end(); ++j) {
111 0 : std::cout << " - " << (*j) << " from \'" << (*j)->get_file()->get_full_file_name() << "\'\n";
112 : }
113 :
114 0 : last = i->first;
115 0 : prev = i->second;
116 0 : ++i;
117 0 : break;
118 : }
119 : }
120 0 : } else {
121 0 : last = i->first;
122 0 : prev = i->second;
123 0 : ++i;
124 : }
125 : }
126 0 : }
127 :
128 : namespace po = boost::program_options;
129 :
130 : int
131 0 : main(int argc, char** argv)
132 : {
133 0 : std::vector<std::string> files;
134 0 : std::string class_name;
135 0 : bool verbose(false);
136 :
137 0 : try {
138 0 : po::options_description desc("This program is loading OKS data files and searching for equal object.\nUsage: "
139 0 : "oks_report_equal_objects [options] [-f] file+ ");
140 :
141 0 : desc.add_options()(
142 0 : "class,c", po::value<std::string>(&class_name), "If defined, only compare objects of this class")(
143 0 : "files,f", po::value<std::vector<std::string>>(&files), "Names of input OKS files")(
144 0 : "verbose,v", "Run in verbose mode")("help,h", "Print help message");
145 :
146 0 : po::positional_options_description p;
147 0 : p.add("files", -1);
148 :
149 0 : po::variables_map vm;
150 0 : po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
151 0 : po::notify(vm);
152 :
153 0 : if (vm.count("help")) {
154 0 : std::cout << desc << std::endl;
155 0 : return EXIT_SUCCESS;
156 : }
157 0 : if (vm.count("verbose")) {
158 0 : verbose = true;
159 : }
160 :
161 0 : if (files.empty()) {
162 0 : throw std::runtime_error("Missing application name");
163 : }
164 0 : } catch (std::exception& ex) {
165 0 : std::cerr << "ERROR: " << ex.what() << std::endl;
166 0 : return EXIT_FAILURE;
167 0 : }
168 :
169 0 : try {
170 0 : OksKernel kernel;
171 0 : kernel.set_test_duplicated_objects_via_inheritance_mode(true);
172 0 : kernel.set_silence_mode(!verbose);
173 :
174 0 : for (std::vector<std::string>::const_iterator i = files.begin(); i != files.end(); ++i) {
175 0 : kernel.load_file(*i);
176 : }
177 :
178 0 : if (!class_name.empty()) {
179 0 : if (OksClass* c = kernel.find_class(class_name)) {
180 0 : process_class(c, verbose);
181 : return 0;
182 : } else {
183 0 : std::cerr << "ERROR: cannot find class \'" << class_name << '\'' << std::endl;
184 : return EXIT_FAILURE;
185 : }
186 : }
187 :
188 0 : for (OksClass::Map::const_iterator i = kernel.classes().begin(); i != kernel.classes().end(); ++i) {
189 0 : process_class(i->second, verbose);
190 : }
191 0 : } catch (oks::exception& ex) {
192 0 : std::cerr << "ERROR: " << ex.what() << std::endl;
193 0 : return EXIT_FAILURE;
194 0 : }
195 :
196 0 : return 0;
197 0 : }
|