ATLAS Offline Software
Loading...
Searching...
No Matches
TGoodRunsListWriter.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6/**********************************************************************************
7 * Class : TGoodRunsListWriter *
8 * *
9 * Authors (alphabetical): *
10 * Max Baak <mbaak@cern.ch> - CERN, Switzerland *
11 *
12 * Inspiration from: http://194.199.20.115/examples/testWriter.c
13 **********************************************************************************/
14
15#include <iostream>
16#include <stdlib.h>
17// #include <stdio.h>
18#include <string.h>
19#include "TROOT.h"
20
25
26#ifndef __NOLIBXML__
27#ifdef __clang__
28# define LIBXML_ATTR_ALLOC_SIZE(x)
29#endif
30#include <libxml/encoding.h>
31#include <libxml/xmlwriter.h>
32#endif
33
34#define MY_ENCODING "ISO-8859-1"
35
37
38using namespace std;
39
40
42 : TObject()
43 , m_logger ( "TGoodRunsListWriter" )
44 , m_mergegrls(false)
45 , m_individuals(false)
46{
47}
48
49
50Root::TGoodRunsListWriter::TGoodRunsListWriter( const Root::TGoodRunsList& goodrunslist, const TString& dataCardName )
51 : TObject()
52 , m_dataCardName( dataCardName )
53 , m_logger ( "TGoodRunsListWriter" )
54 , m_mergegrls(false)
55 , m_individuals(false)
56{
57 m_grlvec.push_back(goodrunslist);
58}
59
60
65
66
67void
69{
70 m_grlvec.Reset();
71 m_grl.clear();
72 m_mergegrls = false;
73 m_individuals = false;
74 m_prefix="";
75 m_xmlstring="";
76 m_xmlstringVec.clear();
77}
78
79
80Bool_t
82{
83 if (m_grlvec.IsEmpty()) {
84 m_logger << kWARNING << "GoodRunsList is empty - nothing to write. Return false." << GEndl;
85 return kFALSE;
86 }
87
88 m_individuals=true;
89 TString olddatacardname=m_dataCardName;
90
92 std::vector< Root::TGoodRunsList >::const_iterator litr = m_grlvec.begin();
93 for (int i=0; litr!=m_grlvec.end(); ++litr, ++i) {
95 m_grl = (*litr);
96 // write xml for this goodrunslist
97 m_dataCardName = m_prefix + Form("merged_%d_",i) + litr->GetSuggestedName() + ".xml" ;
98 (void) this->WriteXMLFile();
99 }
100
101 // reset back to original values
102 m_individuals=false;
103 m_dataCardName=olddatacardname;
104
105 return kTRUE;
106}
107
108
109Bool_t
111{
112 if (m_grlvec.IsEmpty()) {
113 m_logger << kWARNING << "GoodRunsList is empty - nothing to write to <" << m_dataCardName << ">. Return false." << GEndl;
114 return kFALSE;
115 }
116 if (m_dataCardName.IsNull()) {
117 m_logger << kINFO << "Output filename not set. Will be generated automatically." << GEndl;
118 }
119
120#ifndef __NOLIBXML__
121
122 int rc;
124 xmlDocPtr doc;
125
126 /* Create a new XmlWriter for DOM, with no compression. */
127 writer = xmlNewTextWriterDoc(&doc, 0);
128 if (writer == NULL) {
129 m_logger << kWARNING << "testXmlwriterDoc: Error creating the xml writer" << GEndl;
130 return kFALSE;
131 }
132
133 /* Write out goodrunslist here */
135
136 /* Here we could close the elements NamedLumiRange and LumiRangeCollection using the
137 * function xmlTextWriterEndElement, but since we do not want to
138 * write any other elements, we simply call xmlTextWriterEndDocument,
139 * which will do all the work. */
140 rc = xmlTextWriterEndDocument(writer);
141 if (rc < 0) {
142 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterEndDocument" << GEndl;
143 return kFALSE;
144 }
145
146 xmlFreeTextWriter(writer);
147 //xmlSaveFileEnc(m_dataCardName.Data(), doc, MY_ENCODING);
148 xmlSaveFormatFile(m_dataCardName.Data(), doc, 1);
149 xmlFreeDoc(doc);
150
151 m_logger << kINFO << "GoodRunsList stored as : " << m_dataCardName << GEndl;
152
153#else
154
155 m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
156 m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
157
158#endif
159
160 return kTRUE;
161}
162
163
164const std::vector<TString>&
166{
167 m_xmlstringVec.clear();
168
169 if (m_grlvec.IsEmpty()) {
170 m_logger << kWARNING << "GoodRunsList is empty - nothing to write. Return false." << GEndl;
171 return m_xmlstringVec;
172 }
173
174 // individual strings
175 m_individuals=true;
176
178 for (const TGoodRunsList& grl : m_grlvec) {
180 m_grl = grl;
181 // get xml string for this goodrunslist
182 m_xmlstringVec.push_back( this->GetXMLString() );
183 }
184
185 // reset back to original values
186 m_individuals=false;
187
188 return m_xmlstringVec;
189}
190
191
192const TString&
194{
195 m_xmlstring="";
196
197 if (m_grlvec.IsEmpty()) {
198 m_logger << kWARNING << "GoodRunsList is empty - nothing to write. Return false." << GEndl;
199 return m_xmlstring;
200 }
201
202#ifndef __NOLIBXML__
203
204 int rc;
206 xmlBufferPtr buf;
207
208 /* Create a new XML buffer, to which the XML document will be
209 * written */
210 buf = xmlBufferCreate();
211 if (buf == NULL) {
212 m_logger << kWARNING << "testXmlwriterMemory: Error creating the xml buffer" << GEndl;
213 return m_xmlstring;
214 }
215
216 /* Create a new XmlWriter for memory, with no compression.
217 * Remark: there is no compression for this kind of xmlTextWriter */
218 writer = xmlNewTextWriterMemory(buf, 0);
219 if (writer == NULL) {
220 m_logger << kWARNING << "testXmlwriterMemory: Error creating the xml writer" << GEndl;
221 return m_xmlstring;
222 }
223
224 /* Write out goodrunslist here */
226
227 /* Here we could close the elements ORDER and EXAMPLE using the
228 * function xmlTextWriterEndElement, but since we do not want to
229 * write any other elements, we simply call xmlTextWriterEndDocument,
230 * which will do all the work. */
231 rc = xmlTextWriterEndDocument(writer);
232 if (rc < 0) {
233 m_logger << kWARNING << "testXmlwriterMemory: Error at xmlTextWriterEndDocument" << GEndl;
234 return m_xmlstring;
235 }
236
237 xmlFreeTextWriter(writer);
238 m_xmlstring = (const char *) buf->content;
239 xmlBufferFree(buf);
240
241#else
242
243 m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
244 m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
245
246#endif
247
248 return m_xmlstring;
249}
250
251
252Bool_t
254{
255#ifndef __NOLIBXML__
256
257 int rc;
258 xmlChar *tmp;
259
260 /* Start the document with the xml default for the version,
261 * default encoding, and the default for the standalone declaration. */
262 rc = xmlTextWriterStartDocument(writer, NULL, NULL/*MY_ENCODING*/, NULL);
263 if (rc < 0) {
264 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterStartDocument" << GEndl;
265 return kFALSE;
266 }
267
268 /* Write DTD section */
269 rc = xmlTextWriterWriteDTD(writer, ConvertInput("LumiRangeCollection",MY_ENCODING), NULL,
270 ConvertInput("http://atlas-runquery.cern.ch/LumiRangeCollection.dtd", MY_ENCODING), NULL);
271 if (rc < 0) {
272 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTestWriterWriteDTD" << GEndl;
273 return kFALSE;
274 }
275
276 /* Write a comment as child of LumiRangeCollection.
277 * Please observe, that the input to the xmlTextWriter functions
278 * HAS to be in UTF-8, even if the output XML is encoded
279 * in iso-8859-1 */
280 tmp = ConvertInput("This document is created by GoodRunsListWriter.", MY_ENCODING);
281 rc = xmlTextWriterWriteComment(writer, tmp);
282 if (rc < 0) {
283 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterWriteComment" << GEndl;
284 return kFALSE;
285 }
286 if (tmp != NULL) xmlFree(tmp);
287
288 /* Start an element named "LumiRangeCollection". Since thist is the first
289 * element, this will be the root element of the document. */
290 rc = xmlTextWriterStartElement(writer, BAD_CAST "LumiRangeCollection");
291 if (rc < 0) {
292 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterStartElement" << GEndl;
293 return kFALSE;
294 }
295
296 /* Write the actual goodrunslist here.
297 * Use m_grl as global grl currently processed
298 */
299 if (m_individuals) {
300 // m_grl has already been set.
302 } else {
303 // m_grl is set here below
304 if (!m_mergegrls) {
305 std::vector< Root::TGoodRunsList >::const_iterator litr = m_grlvec.begin();
306 for (; litr!=m_grlvec.end(); ++litr) {
307 m_grl = (*litr);
309 }
310 } else {
311 m_grl = this->GetMergedGoodRunsList(); // OR merging
313 }
314 }
315
316 /* Close the element */
317 rc = xmlTextWriterEndElement(writer);
318 if (rc < 0) {
319 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterEndElement" << GEndl;
320 return kFALSE;
321 }
322
323#else
324
325 m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
326 m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
327
328
329#endif
330
331 return kTRUE;
332}
333
334
335Bool_t
337{
338 if (m_dataCardName.IsNull()) {
339 m_dataCardName = m_prefix + "merged_" + m_grl.GetSuggestedName() + ".xml" ;
340 }
341
342#ifndef __NOLIBXML__
343
344 int rc;
345 /* Start an element named "NamedLumiRange" as child of LumiRangeCollection. */
346 rc = xmlTextWriterStartElement(writer, BAD_CAST "NamedLumiRange");
347 if (rc < 0) {
348 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterStartElement" << GEndl;
349 return kFALSE;
350 }
351
352 /* Compress grl before writing to file */
353 m_grl.Compress(); // safe space, remove duplicates.
354 /* Write an element named "NAME" as child of NamedLumiRange. */
355 this->WriteElement(writer,"Name",m_grl.GetName());
356 /* Write an element named "VERSION" as child of NamedLumiRange. */
357 if (m_grl.GetVersion().Length()>0) {
358 this->WriteElement(writer,"Version",m_grl.GetVersion().Data());
359 } else { m_logger << kINFO << "<Version> written to xml file <" << m_dataCardName << "> is empty." << GEndl; }
360 /* Write Metadata */
361 if (!m_grl.GetMetaData().empty()) {
362 std::map<TString,TString>::const_iterator mitr = m_grl.GetMetaData().begin();
363 for (; mitr!=m_grl.GetMetaData().end(); ++mitr)
364 this->WriteElement(writer,"Metadata",mitr->second.Data(),"Name",mitr->first.Data());
365 } else { m_logger << kINFO << "<Metadata> written to xml file <" << m_dataCardName << "> is empty." << GEndl; }
366 /* loop over goodruns */
367 std::map<Int_t,Root::TGoodRun>::const_iterator gitr = m_grl.begin();
368 for (; gitr!=m_grl.end(); ++gitr)
369 this->WriteLumiBlockCollection(writer,gitr->second);
370
371 /* Close the element named NamedLumiRange. */
372 rc = xmlTextWriterEndElement(writer);
373 if (rc < 0) {
374 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterEndElement" << GEndl;
375 return kFALSE;
376 }
377
378#else
379
380 m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
381 m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
382
383
384#endif
385
386 return kTRUE;
387}
388
389
390Bool_t
392{
393#ifndef __NOLIBXML__
394 int rc;
395
396 /* Start an element named "NamedLumiRange" as child of LumiRangeCollection. */
397 rc = xmlTextWriterStartElement(writer, BAD_CAST "LumiBlockCollection");
398 if (rc < 0) {
399 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterStartElement" << GEndl;
400 return kFALSE;
401 }
402
403 if (!goodrun.IsEmpty()) {
404 /* Runnumber */
405 this->WriteElement(writer,"Run",Form("%d",goodrun.GetRunNumber()));
406 /* Start an element named "LBRange" */
407 std::vector<TLumiBlockRange>::const_iterator litr = goodrun.begin();
408 for (; litr!=goodrun.end(); ++litr)
409 if (!litr->IsEmpty()) {
410 if (litr->End()!=2147483647)
411 this->WriteElement(writer,"LBRange",0,"Start",Form("%d",litr->Begin()),"End",Form("%d",litr->End()));
412 else
413 this->WriteElement(writer,"LBRange",0,"Start",Form("%d",litr->Begin()));
414 }
415 }
416
417 /* Close the element named Metadata. */
418 rc = xmlTextWriterEndElement(writer);
419 if (rc < 0) {
420 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterEndElement" << GEndl;
421 return kFALSE;
422 }
423
424#else
425
426 m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
427 m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
428
429#endif
430
431 return kTRUE;
432}
433
434
435Bool_t
437 const char* name, const char* value,
438 const char* atr1, const char* val1, const char* atr2, const char* val2)
439{
440#ifndef __NOLIBXML__
441
442 int rc;
443 /* Start an element named 'name' as child of previous element. */
444 rc = xmlTextWriterStartElement(writer, BAD_CAST (name));
445 if (rc < 0) {
446 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterStartElement" << GEndl;
447 return kFALSE;
448 }
449 /* Add an attribute 'atr1' and value 'val1' to element. */
450 if ((atr1!=0) && (val1!=0)) {
451 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST (atr1), BAD_CAST (val1));
452 if (rc < 0) {
453 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterWriteAttribute" << GEndl;
454 return kFALSE;
455 }
456 }
457 /* Add an attribute 'atr2' and value 'val2' to element. */
458 if ((atr2!=0) && (val2!=0)) {
459 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST (atr2), BAD_CAST (val2));
460 if (rc < 0) {
461 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterWriteAttribute" << GEndl;
462 return kFALSE;
463 }
464 }
465 /* Add value 'value' to the element */
466 if ((value!=0)) {
467 rc = xmlTextWriterWriteString(writer, BAD_CAST (value));
468 if(rc < 0) {
469 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterWriteString" << GEndl;
470 return kFALSE;
471 }
472 }
473 /* Close the element */
474 rc = xmlTextWriterEndElement(writer);
475 if (rc < 0) {
476 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterEndElement" << GEndl;
477 return kFALSE;
478 }
479
480#else
481
482 m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
483 m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
484
485
486#endif
487
488 return kTRUE;
489}
490
491
501xmlChar *
502Root::TGoodRunsListWriter::ConvertInput(const char *in, const char *encoding)
503{
504 xmlChar* out(0);
505
506#ifndef __NOLIBXML__
507
508 int ret;
509 int size;
510 int out_size;
511 int temp;
512 xmlCharEncodingHandlerPtr handler;
513
514 if (in == 0)
515 return 0;
516
517 handler = xmlFindCharEncodingHandler(encoding);
518
519 if (!handler) {
520 m_logger << kWARNING << "ConvertInput: no encoding handler found for " << (encoding ? encoding : "") << GEndl;
521 return 0;
522 }
523
524 size = (int) strlen(in) + 1;
525 out_size = size * 2 - 1;
526 out = (unsigned char *) xmlMalloc((size_t) out_size);
527
528 if (out != 0) {
529 temp = size - 1;
530 ret = handler->input(out, &out_size, (const xmlChar *) in, &temp);
531 if ((ret < 0) || (temp - size + 1)) {
532 if (ret < 0) {
533 m_logger << kWARNING << "ConvertInput: conversion wasn't successful." << GEndl;
534 } else {
535 m_logger << kWARNING << "ConvertInput: conversion wasn't successful. Converted: " << temp << " octets." << GEndl;
536 }
537
538 xmlFree(out);
539 out = 0;
540 } else {
541 out = (unsigned char *) xmlRealloc(out, out_size + 1);
542 out[out_size] = 0; /*null terminating out */
543 }
544 } else {
545 m_logger << kWARNING << "ConvertInput: no mem" << GEndl;
546 }
547
548#else
549
550 m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
551 m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
552
553
554#endif
555
556 return out;
557}
558
559
std::shared_ptr< HepMC3::Writer > writer
static Double_t rc
ClassImp(Root::TGoodRunsListWriter) using namespace std
#define MY_ENCODING
xmlTextWriter * xmlTextWriterPtr
unsigned char xmlChar
#define GEndl
Definition TMsgLogger.h:147
Bool_t IsEmpty() const
Definition TGoodRun.cxx:249
Int_t GetRunNumber() const
Definition TGoodRun.h:42
xmlChar * ConvertInput(const char *in, const char *encoding)
ConvertInput: @in: string in a given encoding @encoding: the encoding used.
const TGoodRunsList GetMergedGoodRunsList(const Root::BoolOperation &operation=OR) const
Bool_t WriteNamedLumiRange(xmlTextWriterPtr writer)
Bool_t WriteLumiRangeCollection(xmlTextWriterPtr writer)
std::vector< TString > m_xmlstringVec
Bool_t WriteElement(xmlTextWriterPtr writer, const char *name, const char *value=0, const char *atr1=0, const char *val1=0, const char *atr2=0, const char *val2=0)
const std::vector< TString > & GetXMLStrings()
Bool_t WriteLumiBlockCollection(xmlTextWriterPtr writer, const TGoodRun &goodrun)
@ kWARNING
Definition TMsgLogger.h:41
@ kINFO
Definition TMsgLogger.h:40
STL namespace.
void handler(int sig)
signal handler
Definition rmain.cxx:99