Newer
Older
// In this example we serialize an object and construct another from
// the XML representation. We do this twice, once directly through the
// derived class and once through an abstract base class.
//
// Compile with a command similar to
// g++ -o serializationDemo -I /opt/boost143/include/ -L /opt/boost143/lib/ -lboost_serialization -lboost_system serializationDemo.C
//
// Author: Ruediger Berlich
// Standard headers
#include <iostream>
#include <sstream>
#include <string>
// Boost headers required for serialization
#include <boost/shared_ptr.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/export.hpp>
// PWA test includes
//#include "Examples/MATpbarpToOmegaPi/serSpin.hh"
#include "PwaUtils/pbarpStates.hh"
#include "Examples/MATpbarpToOmegaPi/pbarpToOmegaPi0States.hh"
#include "Examples/MATpbarpToOmegaPi/GOmegaPiIndividual.hh"
#include "Examples/MATpbarpToOmegaPi/OmegaPiEventList.hh"
#include "Examples/EtacToapi0Fit/EtacToapi0Lh.hh"
//#include "Examples/MATpbarpToOmegaPi/OmegaPiHist.hh"
#include "Examples/MATpbarpToOmegaPi/OmegaPiData.hh"
//#include "Setup/PwaEnv.hh"
#include "Particle/ParticleTable.hh"
#include "Particle/Particle.hh"
#include "Event/EventList.hh"
#include "Event/Event.hh"
#include "Event/CBElsaReader.hh"
#include "Particle/PdtParser.hh"
#include "ErrLogger/ErrLogger.hh"
using namespace Gem::Geneva;
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/****************************************************************/
class serializationBaseClass
{
////////////////////////////////////////////////////////////////
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive & ar, const unsigned int) {
using boost::serialization::make_nvp;
// Trigger serialization of the local data
ar & BOOST_SERIALIZATION_NVP(testVar_);
}
////////////////////////////////////////////////////////////////
public:
serializationBaseClass()
{ /* nothing */ }
serializationBaseClass(int testVar): testVar_(testVar)
{ /* nothing */ }
virtual ~serializationBaseClass()
{ /* nothing */ }
int getSecret() const { return testVar_; }
// The base class is purely virtual so it cannot be instantiated
virtual void ImPurelyVirtual() = 0;
private:
int testVar_;
};
// Let the Boost serialization library know that this class is abstract / purely virtual
BOOST_SERIALIZATION_ASSUME_ABSTRACT(serializationBaseClass)
/****************************************************************/
class serializationClass
:public serializationBaseClass
{
////////////////////////////////////////////////////////////////
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive & ar, const unsigned int) {
using boost::serialization::make_nvp;
// Make sure the base class (and its data) gets serialized
ar & make_nvp("serializationBaseClass", boost::serialization::base_object<serializationBaseClass>(*this));
}
////////////////////////////////////////////////////////////////
public:
serializationClass()
{ /* nothing */ }
serializationClass(int testVar) : serializationBaseClass(testVar)
{ /* nothing */ }
virtual ~serializationClass()
{ /* nothing */ }
// Make sure we can instantiate this class -- need to re-implement the
// purely virtual function of the base class.
virtual void ImPurelyVirtual() { /* nothing */ }
};
// Register this class with the boost serialization library.
// Note: This macro and the associated header would usually reside in
// the implementation file (.cpp), not in the header file.
#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT(serializationClass)
/****************************************************************/
int main() {
// The objects that should be (de-)serialized
boost::shared_ptr<serializationClass> p_derived(new serializationClass(123));
boost::shared_ptr<serializationBaseClass> p_base(new serializationClass(456));
// Will hold reconstructed objects. Here these pointers are empty
boost::shared_ptr<serializationClass> p_derived_reconstructed;
boost::shared_ptr<serializationBaseClass> p_base_reconstructed;
// The PWA-objects that should be (de-)serialized and changed inbetween
//Spin
// boost::shared_ptr<serSpin> mySpin_init(new serSpin());
// boost::shared_ptr<serSpin> mySpin_reco1;
// boost::shared_ptr<serSpin> mySpin_reco2;
// boost::shared_ptr<pbarpStates> myStates_init(new pbarpStates(2));
// boost::shared_ptr<pbarpStates> myStates_reco1;
// boost::shared_ptr<pbarpStates> myStates_reco2;
// boost::shared_ptr<pbarpToOmegaPi0States> myOmStates_init(new pbarpToOmegaPi0States(myStates_init));
// boost::shared_ptr<pbarpToOmegaPi0States> myOmStates_reco1;
// boost::shared_ptr<pbarpToOmegaPi0States> myOmStates_reco2;
//OmegaPiEvent List / GOmegaPiIndividual
std::string theSourcePath=getenv("CMAKE_SOURCE_DIR");
std::string piomegaDatFile;
std::string piomegaMcFile;
piomegaDatFile=theSourcePath+"/Examples/MATpbarpToOmegaPi/data/510_0600.dat";
piomegaMcFile=theSourcePath+"/Examples/MATpbarpToOmegaPi/data/mc510_0600.dat";
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
ParticleTable pTable;
PdtParser parser;
std::string pdtFile(theSourcePath+"/Particle/pdt.table");
if (!parser.parse(pdtFile, pTable)) {
Alert << "Error: could not parse " << pdtFile << endmsg;
exit(1);
}
std::vector<std::string> fileNames;
fileNames.push_back(piomegaDatFile);
CBElsaReader eventReader(fileNames, 3, 0);
EventList piOmegaEventsData;
eventReader.fillAll(piOmegaEventsData);
if (!piOmegaEventsData.findParticleTypes(pTable))
Warning << "could not find all particles" << endmsg;
Info << "\nFile has " << piOmegaEventsData.size() << " events. Each event has "
<< piOmegaEventsData.nextEvent()->size() << " final state particles.\n" << endmsg;
piOmegaEventsData.rewind();
Event* anEvent;
int evtCount = 0;
while ((anEvent = piOmegaEventsData.nextEvent()) != 0 && evtCount < 20) {
Info << "\n"
<< *(anEvent->p4(0)) << "\tm = " << anEvent->p4(0)->Mass() << "\n"
<< *(anEvent->p4(1)) << "\tm = " << anEvent->p4(1)->Mass() << "\n"
<< *(anEvent->p4(2)) << "\tm = " << anEvent->p4(2)->Mass() << "\n"
<< endmsg;
++evtCount;
}
piOmegaEventsData.rewind();
std::vector<std::string> fileNamesMc;
fileNamesMc.push_back(piomegaMcFile);
CBElsaReader eventReaderMc(fileNamesMc, 3, 0);
EventList piOmegaEventsMc;
eventReaderMc.fillAll(piOmegaEventsMc);
piOmegaEventsMc.rewind();
boost::shared_ptr<pbarpStates> pbarpStatesPtr(new pbarpStates(1));
//boost::shared_ptr<pbarpToOmegaPi0States> pbarpToOmegaPi0StatesPtr(new pbarpToOmegaPi0States(pbarpStatesPtr));
boost::shared_ptr<pbarpToOmegaPi0States> pbarpToOmegaPi0StatesPtr = pbarpToOmegaPi0States::getStates(pbarpStatesPtr);
//boost::shared_ptr<const OmegaPiEventList> theOmegaPiEventPtr(new OmegaPiEventList(piOmegaEventsData, piOmegaEventsMc, 1, 600));
boost::shared_ptr<OmegaPiEventList> theOmegaPiEventPtr = OmegaPiEventList::getList(piOmegaEventsData, piOmegaEventsMc, 1, 600);
//theOmegaPiEventPtr->initList(piOmegaEventsData, piOmegaEventsMc, 1, 600);
//boost::shared_ptr<const OmegaPiEventList> theOmegaPiEventPtr_reco1;
// boost::shared_ptr<const OmegaPiEventList> theOmegaPiEventPtr_reco2;
boost::shared_ptr<GOmegaPiIndividual> gdii_ptr_init(new GOmegaPiIndividual(pbarpToOmegaPi0StatesPtr));
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
boost::shared_ptr<GOmegaPiIndividual> gdii_ptr_reco1;
boost::shared_ptr<GOmegaPiIndividual> gdii_ptr_reco2;
//////////////////////////////////////////////////////////////////////////////////
std::ostringstream oarchive_stream_pwa1;
// Serialization (through boost::shared_ptr)
{
boost::archive::xml_oarchive oa(oarchive_stream_pwa1);
oa << boost::serialization::make_nvp("mySpin", gdii_ptr_init);
} // Explicit scope necessary -- makes sure oa's destructor is called
// Here is the serialized data
std::string spin_init_ser = oarchive_stream_pwa1.str();
// We now have an XML representation of the object. Print it out just to look at it
std::cout << "=============================================================" << std::endl
<< "Class representation, when serializing initial OmegaPiEventList class:" << std::endl
<< std::endl
<< spin_init_ser << std::endl;
// Feed the data into an istringstream object
std::istringstream iarchive_stream_pwa1(spin_init_ser);
// De-Serialization
{
boost::archive::xml_iarchive ia(iarchive_stream_pwa1);
ia >> boost::serialization::make_nvp("mySpin", gdii_ptr_reco1);
} // note: explicit scope here is essential so the ia-destructor gets called
//make changes (pretend being network client)
//boost::shared_ptr<pbarpStates> pbarpStatesPtr_new(new pbarpStates(1));
//boost::shared_ptr<const pbarpToOmegaPi0States> pbarpToOmegaPi0StatesPtr_new(new pbarpToOmegaPi0States(pbarpStatesPtr_new));
//boost::shared_ptr<const OmegaPiEventList> theOmegaPiEventPtr_new(new OmegaPiEventList(piOmegaEventsData, piOmegaEventsMc, 2, 600));
boost::shared_ptr<OmegaPiEventList> theOmegaPiEventPtr_new = OmegaPiEventList::getList();
//theOmegaPiEventPtr_new->initList(piOmegaEventsData, piOmegaEventsMc, 2, 600);
boost::shared_ptr<GOmegaPiIndividual> gdii_ptr_new(new GOmegaPiIndividual(pbarpToOmegaPi0StatesPtr));
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
gdii_ptr_reco1=gdii_ptr_new;
std::ostringstream oarchive_stream_pwa2;
// Serialization (through boost::shared_ptr)
{
boost::archive::xml_oarchive oa(oarchive_stream_pwa2);
oa << boost::serialization::make_nvp("mySpin", gdii_ptr_reco1);
} // Explicit scope necessary -- makes sure oa's destructor is called
// Here is the serialized data
std::string spin_changed_ser = oarchive_stream_pwa2.str();
// We now have an XML representation of the object. Print it out just to look at it
std::cout << "=============================================================" << std::endl
<< "Class representation, when serializing changed OmegaPiEventList class:" << std::endl
<< std::endl
<< spin_changed_ser << std::endl;
// Feed the data into an istringstream object
std::istringstream iarchive_stream_pwa2(spin_changed_ser);
// De-Serialization through derived object
{
boost::archive::xml_iarchive ia(iarchive_stream_pwa2);
ia >> boost::serialization::make_nvp("mySpin", gdii_ptr_reco2);
} // note: explicit scope here is essential so the ia-destructor gets called
// Print testVar_ of original and reconstructed class
OmegaPiData::fitParamVal myFitParmVal;
std::cout << std::endl;
std::cout << " Init: " << gdii_ptr_init->getFitParams(myFitParmVal) << std::endl;
//theOmegaPiEventPtr_init->print(cout);
std::cout << std::endl << " Reco1: " << gdii_ptr_reco1->getFitParams(myFitParmVal) << std::endl;
//theOmegaPiEventPtr_reco1->print(cout);
std::cout << std::endl << " Reco2: " << gdii_ptr_reco2->getFitParams(myFitParmVal) << std::endl;
//theOmegaPiEventPtr_reco2->print(cout);
std::cout << std::endl;
//////////////////////////////////////////////////////////////////////////////////
std::ostringstream oarchive_stream_derived;
// Serialization through derived class (through boost::shared_ptr)
{
boost::archive::xml_oarchive oa(oarchive_stream_derived);
oa << boost::serialization::make_nvp("classHierarchyFromDerived", p_derived);
} // Explicit scope necessary -- makes sure oa's destructor is called
// Here is the serialized data
std::string derived_class_serialized = oarchive_stream_derived.str();
// We now have an XML representation of the object. Print it out just to look at it
std::cout << "=============================================================" << std::endl
<< "Class representation, when serializing the derived class:" << std::endl
<< std::endl
<< derived_class_serialized << std::endl;
// Feed the data into an istringstream object
std::istringstream iarchive_stream_derived(derived_class_serialized);
// De-Serialization through derived object
{
boost::archive::xml_iarchive ia(iarchive_stream_derived);
ia >> boost::serialization::make_nvp("classHierarchyFromDerived", p_derived_reconstructed);
} // note: explicit scope here is essential so the ia-destructor gets called
// Print testVar_ of original and reconstructed class
std::cout << std::endl
<< "Before: " << p_derived->getSecret() << " After: " << p_derived_reconstructed->getSecret() << std::endl;
//////////////////////////////////////////////////////////////////////////////////
std::ostringstream oarchive_stream_base;
// Serialization through a base pointer to purely abstract class
{
boost::archive::xml_oarchive oa(oarchive_stream_base);
oa << boost::serialization::make_nvp("classHierarchyFromBasePointer", p_base);
} // Explicit scope necessary -- makes sure oa's destructor is called
// Here is the serialized data
std::string base_class_serialized = oarchive_stream_base.str();
// We now have an XML representation of the object. Print it out just to look at it
std::cout << "=============================================================" << std::endl
<< "Class representation, when serialized through a base pointer" << std::endl
<< std::endl
<< base_class_serialized << std::endl;
// Feed the data in the istringstream
std::istringstream iarchive_stream_base(base_class_serialized);
// De-Serialization through a base pointer
{
boost::archive::xml_iarchive ia(iarchive_stream_base);
ia >> boost::serialization::make_nvp("classHierarchyFromBasePointer", p_base_reconstructed);
} // note: explicit scope here is essential so the ia-destructor gets called
// Print testVar_ of original and reconstructed class
std::cout << std::endl
<< "Before: " << p_base->getSecret() << " After: " << p_base_reconstructed->getSecret() << std::endl;
// Destructor's correct?
// while(true) {
// boost::shared_ptr<pbarpStates> pbarpStatesPtr_test(new pbarpStates(2));
// boost::shared_ptr<const pbarpToOmegaPi0States> pbarpToOmegaPi0StatesPtr_test(new pbarpToOmegaPi0States(pbarpStatesPtr_test));
// boost::shared_ptr<const OmegaPiEventList> theOmegaPiEventPtr_test(new OmegaPiEventList(piOmegaEventsData, piOmegaEventsMc, 2, 600));
// boost::shared_ptr<GOmegaPiIndividual> gdii_ptr_test(new GOmegaPiIndividual(theOmegaPiEventPtr_test, pbarpToOmegaPi0StatesPtr_test));
// }