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