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;
123 xmlTextWriterPtr writer;
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 */
134 this->WriteLumiRangeCollection(writer);
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 std::vector< Root::TGoodRunsList >::const_iterator litr = m_grlvec.begin();
179 for (int i=0; litr!=m_grlvec.end(); ++litr, ++i) {
181 m_grl = (*litr);
182 // get xml string for this goodrunslist
183 m_xmlstringVec.push_back( this->GetXMLString() );
184 }
185
186 // reset back to original values
187 m_individuals=false;
188
189 return m_xmlstringVec;
190}
191
192
193const TString&
195{
196 m_xmlstring="";
197
198 if (m_grlvec.IsEmpty()) {
199 m_logger << kWARNING << "GoodRunsList is empty - nothing to write. Return false." << GEndl;
200 return m_xmlstring;
201 }
202
203#ifndef __NOLIBXML__
204
205 int rc;
206 xmlTextWriterPtr writer;
207 xmlBufferPtr buf;
208
209 /* Create a new XML buffer, to which the XML document will be
210 * written */
211 buf = xmlBufferCreate();
212 if (buf == NULL) {
213 m_logger << kWARNING << "testXmlwriterMemory: Error creating the xml buffer" << GEndl;
214 return m_xmlstring;
215 }
216
217 /* Create a new XmlWriter for memory, with no compression.
218 * Remark: there is no compression for this kind of xmlTextWriter */
219 writer = xmlNewTextWriterMemory(buf, 0);
220 if (writer == NULL) {
221 m_logger << kWARNING << "testXmlwriterMemory: Error creating the xml writer" << GEndl;
222 return m_xmlstring;
223 }
224
225 /* Write out goodrunslist here */
226 this->WriteLumiRangeCollection(writer);
227
228 /* Here we could close the elements ORDER and EXAMPLE using the
229 * function xmlTextWriterEndElement, but since we do not want to
230 * write any other elements, we simply call xmlTextWriterEndDocument,
231 * which will do all the work. */
232 rc = xmlTextWriterEndDocument(writer);
233 if (rc < 0) {
234 m_logger << kWARNING << "testXmlwriterMemory: Error at xmlTextWriterEndDocument" << GEndl;
235 return m_xmlstring;
236 }
237
238 xmlFreeTextWriter(writer);
239 m_xmlstring = (const char *) buf->content;
240 xmlBufferFree(buf);
241
242#else
243
244 m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
245 m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
246
247#endif
248
249 return m_xmlstring;
250}
251
252
253Bool_t
255{
256#ifndef __NOLIBXML__
257
258 int rc;
259 xmlChar *tmp;
260
261 /* Start the document with the xml default for the version,
262 * default encoding, and the default for the standalone declaration. */
263 rc = xmlTextWriterStartDocument(writer, NULL, NULL/*MY_ENCODING*/, NULL);
264 if (rc < 0) {
265 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterStartDocument" << GEndl;
266 return kFALSE;
267 }
268
269 /* Write DTD section */
270 rc = xmlTextWriterWriteDTD(writer, (xmlChar *)"LumiRangeCollection", NULL,
271 (xmlChar *)"http://atlas-runquery.cern.ch/LumiRangeCollection.dtd", NULL);
272 if (rc < 0) {
273 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTestWriterWriteDTD" << GEndl;
274 return kFALSE;
275 }
276
277 /* Write a comment as child of LumiRangeCollection.
278 * Please observe, that the input to the xmlTextWriter functions
279 * HAS to be in UTF-8, even if the output XML is encoded
280 * in iso-8859-1 */
281 tmp = ConvertInput("This document is created by GoodRunsListWriter.", MY_ENCODING);
282 rc = xmlTextWriterWriteComment(writer, tmp);
283 if (rc < 0) {
284 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterWriteComment" << GEndl;
285 return kFALSE;
286 }
287 if (tmp != NULL) xmlFree(tmp);
288
289 /* Start an element named "LumiRangeCollection". Since thist is the first
290 * element, this will be the root element of the document. */
291 rc = xmlTextWriterStartElement(writer, BAD_CAST "LumiRangeCollection");
292 if (rc < 0) {
293 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterStartElement" << GEndl;
294 return kFALSE;
295 }
296
297 /* Write the actual goodrunslist here.
298 * Use m_grl as global grl currently processed
299 */
300 if (m_individuals) {
301 // m_grl has already been set.
302 this->WriteNamedLumiRange(writer);
303 } else {
304 // m_grl is set here below
305 if (!m_mergegrls) {
306 std::vector< Root::TGoodRunsList >::const_iterator litr = m_grlvec.begin();
307 for (; litr!=m_grlvec.end(); ++litr) {
308 m_grl = (*litr);
309 this->WriteNamedLumiRange(writer);
310 }
311 } else {
312 m_grl = this->GetMergedGoodRunsList(); // OR merging
313 this->WriteNamedLumiRange(writer);
314 }
315 }
316
317 /* Close the element */
318 rc = xmlTextWriterEndElement(writer);
319 if (rc < 0) {
320 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterEndElement" << GEndl;
321 return kFALSE;
322 }
323
324#else
325
326 m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
327 m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
328
329
330#endif
331
332 return kTRUE;
333}
334
335
336Bool_t
338{
339 if (m_dataCardName.IsNull()) {
340 m_dataCardName = m_prefix + "merged_" + m_grl.GetSuggestedName() + ".xml" ;
341 }
342
343#ifndef __NOLIBXML__
344
345 int rc;
346 /* Start an element named "NamedLumiRange" as child of LumiRangeCollection. */
347 rc = xmlTextWriterStartElement(writer, BAD_CAST "NamedLumiRange");
348 if (rc < 0) {
349 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterStartElement" << GEndl;
350 return kFALSE;
351 }
352
353 /* Compress grl before writing to file */
354 m_grl.Compress(); // safe space, remove duplicates.
355 /* Write an element named "NAME" as child of NamedLumiRange. */
356 this->WriteElement(writer,"Name",m_grl.GetName());
357 /* Write an element named "VERSION" as child of NamedLumiRange. */
358 if (m_grl.GetVersion().Length()>0) {
359 this->WriteElement(writer,"Version",m_grl.GetVersion().Data());
360 } else { m_logger << kINFO << "<Version> written to xml file <" << m_dataCardName << "> is empty." << GEndl; }
361 /* Write Metadata */
362 if (!m_grl.GetMetaData().empty()) {
363 std::map<TString,TString>::const_iterator mitr = m_grl.GetMetaData().begin();
364 for (; mitr!=m_grl.GetMetaData().end(); ++mitr)
365 this->WriteElement(writer,"Metadata",mitr->second.Data(),"Name",mitr->first.Data());
366 } else { m_logger << kINFO << "<Metadata> written to xml file <" << m_dataCardName << "> is empty." << GEndl; }
367 /* loop over goodruns */
368 std::map<Int_t,Root::TGoodRun>::const_iterator gitr = m_grl.begin();
369 for (; gitr!=m_grl.end(); ++gitr)
370 this->WriteLumiBlockCollection(writer,gitr->second);
371
372 /* Close the element named NamedLumiRange. */
373 rc = xmlTextWriterEndElement(writer);
374 if (rc < 0) {
375 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterEndElement" << GEndl;
376 return kFALSE;
377 }
378
379#else
380
381 m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
382 m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
383
384
385#endif
386
387 return kTRUE;
388}
389
390
391Bool_t
393{
394#ifndef __NOLIBXML__
395 int rc;
396
397 /* Start an element named "NamedLumiRange" as child of LumiRangeCollection. */
398 rc = xmlTextWriterStartElement(writer, BAD_CAST "LumiBlockCollection");
399 if (rc < 0) {
400 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterStartElement" << GEndl;
401 return kFALSE;
402 }
403
404 if (!goodrun.IsEmpty()) {
405 /* Runnumber */
406 this->WriteElement(writer,"Run",Form("%d",goodrun.GetRunNumber()));
407 /* Start an element named "LBRange" */
408 std::vector<TLumiBlockRange>::const_iterator litr = goodrun.begin();
409 for (; litr!=goodrun.end(); ++litr)
410 if (!litr->IsEmpty()) {
411 if (litr->End()!=2147483647)
412 this->WriteElement(writer,"LBRange",0,"Start",Form("%d",litr->Begin()),"End",Form("%d",litr->End()));
413 else
414 this->WriteElement(writer,"LBRange",0,"Start",Form("%d",litr->Begin()));
415 }
416 }
417
418 /* Close the element named Metadata. */
419 rc = xmlTextWriterEndElement(writer);
420 if (rc < 0) {
421 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterEndElement" << GEndl;
422 return kFALSE;
423 }
424
425#else
426
427 m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
428 m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
429
430#endif
431
432 return kTRUE;
433}
434
435
436Bool_t
438 const char* name, const char* value,
439 const char* atr1, const char* val1, const char* atr2, const char* val2)
440{
441#ifndef __NOLIBXML__
442
443 int rc;
444 /* Start an element named 'name' as child of previous element. */
445 rc = xmlTextWriterStartElement(writer, BAD_CAST (name));
446 if (rc < 0) {
447 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterStartElement" << GEndl;
448 return kFALSE;
449 }
450 /* Add an attribute 'atr1' and value 'val1' to element. */
451 if ((atr1!=0) && (val1!=0)) {
452 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST (atr1), BAD_CAST (val1));
453 if (rc < 0) {
454 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterWriteAttribute" << GEndl;
455 return kFALSE;
456 }
457 }
458 /* Add an attribute 'atr2' and value 'val2' to element. */
459 if ((atr2!=0) && (val2!=0)) {
460 rc = xmlTextWriterWriteAttribute(writer, BAD_CAST (atr2), BAD_CAST (val2));
461 if (rc < 0) {
462 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterWriteAttribute" << GEndl;
463 return kFALSE;
464 }
465 }
466 /* Add value 'value' to the element */
467 if ((value!=0)) {
468 rc = xmlTextWriterWriteString(writer, BAD_CAST (value));
469 if(rc < 0) {
470 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterWriteString" << GEndl;
471 return kFALSE;
472 }
473 }
474 /* Close the element */
475 rc = xmlTextWriterEndElement(writer);
476 if (rc < 0) {
477 m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterEndElement" << GEndl;
478 return kFALSE;
479 }
480
481#else
482
483 m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
484 m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
485
486
487#endif
488
489 return kTRUE;
490}
491
492
502xmlChar *
503Root::TGoodRunsListWriter::ConvertInput(const char *in, const char *encoding)
504{
505 xmlChar* out(0);
506
507#ifndef __NOLIBXML__
508
509 int ret;
510 int size;
511 int out_size;
512 int temp;
513 xmlCharEncodingHandlerPtr handler;
514
515 if (in == 0)
516 return 0;
517
518 handler = xmlFindCharEncodingHandler(encoding);
519
520 if (!handler) {
521 m_logger << kWARNING << "ConvertInput: no encoding handler found for " << (encoding ? encoding : "") << GEndl;
522 return 0;
523 }
524
525 size = (int) strlen(in) + 1;
526 out_size = size * 2 - 1;
527 out = (unsigned char *) xmlMalloc((size_t) out_size);
528
529 if (out != 0) {
530 temp = size - 1;
531 ret = handler->input(out, &out_size, (const xmlChar *) in, &temp);
532 if ((ret < 0) || (temp - size + 1)) {
533 if (ret < 0) {
534 m_logger << kWARNING << "ConvertInput: conversion wasn't successful." << GEndl;
535 } else {
536 m_logger << kWARNING << "ConvertInput: conversion wasn't successful. Converted: " << temp << " octets." << GEndl;
537 }
538
539 xmlFree(out);
540 out = 0;
541 } else {
542 out = (unsigned char *) xmlRealloc(out, out_size + 1);
543 out[out_size] = 0; /*null terminating out */
544 }
545 } else {
546 m_logger << kWARNING << "ConvertInput: no mem" << GEndl;
547 }
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
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