ATLAS Offline Software
TGoodRunsListWriter.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 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 
23 #include "GoodRunsLists/TGoodRun.h"
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 
38 using namespace std;
39 
40 
42  : TObject()
43  , m_logger ( "TGoodRunsListWriter" )
44  , m_mergegrls(false)
45  , m_individuals(false)
46 {
47 }
48 
49 
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 
62 {
63  this->reset();
64 }
65 
66 
67 void
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 
80 Bool_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 
109 Bool_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 */
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 
164 const 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 
193 const 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;
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 
253 Bool_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  xmlTextWriterWriteDTD(writer, (xmlChar *)"LumiRangeCollection", NULL,
271  (xmlChar *)"http://atlas-runquery.cern.ch/LumiRangeCollection.dtd", NULL);
272 
273  /* Write a comment as child of LumiRangeCollection.
274  * Please observe, that the input to the xmlTextWriter functions
275  * HAS to be in UTF-8, even if the output XML is encoded
276  * in iso-8859-1 */
277  tmp = ConvertInput("This document is created by GoodRunsListWriter.", MY_ENCODING);
278  rc = xmlTextWriterWriteComment(writer, tmp);
279  if (rc < 0) {
280  m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterWriteComment" << GEndl;
281  return kFALSE;
282  }
283  if (tmp != NULL) xmlFree(tmp);
284 
285  /* Start an element named "LumiRangeCollection". Since thist is the first
286  * element, this will be the root element of the document. */
287  rc = xmlTextWriterStartElement(writer, BAD_CAST "LumiRangeCollection");
288  if (rc < 0) {
289  m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterStartElement" << GEndl;
290  return kFALSE;
291  }
292 
293  /* Write the actual goodrunslist here.
294  * Use m_grl as global grl currently processed
295  */
296  if (m_individuals) {
297  // m_grl has already been set.
298  this->WriteNamedLumiRange(writer);
299  } else {
300  // m_grl is set here below
301  if (!m_mergegrls) {
302  std::vector< Root::TGoodRunsList >::const_iterator litr = m_grlvec.begin();
303  for (; litr!=m_grlvec.end(); ++litr) {
304  m_grl = (*litr);
305  this->WriteNamedLumiRange(writer);
306  }
307  } else {
308  m_grl = this->GetMergedGoodRunsList(); // OR merging
309  this->WriteNamedLumiRange(writer);
310  }
311  }
312 
313  /* Close the element */
314  rc = xmlTextWriterEndElement(writer);
315  if (rc < 0) {
316  m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterEndElement" << GEndl;
317  return kFALSE;
318  }
319 
320 #else
321 
322  m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
323  m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
324 
325 
326 #endif
327 
328  return kTRUE;
329 }
330 
331 
332 Bool_t
334 {
335  if (m_dataCardName.IsNull()) {
336  m_dataCardName = m_prefix + "merged_" + m_grl.GetSuggestedName() + ".xml" ;
337  }
338 
339 #ifndef __NOLIBXML__
340 
341  int rc;
342  /* Start an element named "NamedLumiRange" as child of LumiRangeCollection. */
343  rc = xmlTextWriterStartElement(writer, BAD_CAST "NamedLumiRange");
344  if (rc < 0) {
345  m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterStartElement" << GEndl;
346  return kFALSE;
347  }
348 
349  /* Compress grl before writing to file */
350  m_grl.Compress(); // safe space, remove duplicates.
351  /* Write an element named "NAME" as child of NamedLumiRange. */
352  this->WriteElement(writer,"Name",m_grl.GetName());
353  /* Write an element named "VERSION" as child of NamedLumiRange. */
354  if (m_grl.GetVersion().Length()>0) {
355  this->WriteElement(writer,"Version",m_grl.GetVersion().Data());
356  } else { m_logger << kINFO << "<Version> written to xml file <" << m_dataCardName << "> is empty." << GEndl; }
357  /* Write Metadata */
358  if (!m_grl.GetMetaData().empty()) {
359  std::map<TString,TString>::const_iterator mitr = m_grl.GetMetaData().begin();
360  for (; mitr!=m_grl.GetMetaData().end(); ++mitr)
361  this->WriteElement(writer,"Metadata",mitr->second.Data(),"Name",mitr->first.Data());
362  } else { m_logger << kINFO << "<Metadata> written to xml file <" << m_dataCardName << "> is empty." << GEndl; }
363  /* loop over goodruns */
364  std::map<Int_t,Root::TGoodRun>::const_iterator gitr = m_grl.begin();
365  for (; gitr!=m_grl.end(); ++gitr)
366  this->WriteLumiBlockCollection(writer,gitr->second);
367 
368  /* Close the element named NamedLumiRange. */
369  rc = xmlTextWriterEndElement(writer);
370  if (rc < 0) {
371  m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterEndElement" << GEndl;
372  return kFALSE;
373  }
374 
375 #else
376 
377  m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
378  m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
379 
380 
381 #endif
382 
383  return kTRUE;
384 }
385 
386 
387 Bool_t
389 {
390 #ifndef __NOLIBXML__
391  int rc;
392 
393  /* Start an element named "NamedLumiRange" as child of LumiRangeCollection. */
394  rc = xmlTextWriterStartElement(writer, BAD_CAST "LumiBlockCollection");
395  if (rc < 0) {
396  m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterStartElement" << GEndl;
397  return kFALSE;
398  }
399 
400  if (!goodrun.IsEmpty()) {
401  /* Runnumber */
402  this->WriteElement(writer,"Run",Form("%d",goodrun.GetRunNumber()));
403  /* Start an element named "LBRange" */
404  std::vector<TLumiBlockRange>::const_iterator litr = goodrun.begin();
405  for (; litr!=goodrun.end(); ++litr)
406  if (!litr->IsEmpty()) {
407  if (litr->End()!=2147483647)
408  this->WriteElement(writer,"LBRange",0,"Start",Form("%d",litr->Begin()),"End",Form("%d",litr->End()));
409  else
410  this->WriteElement(writer,"LBRange",0,"Start",Form("%d",litr->Begin()));
411  }
412  }
413 
414  /* Close the element named Metadata. */
415  rc = xmlTextWriterEndElement(writer);
416  if (rc < 0) {
417  m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterEndElement" << GEndl;
418  return kFALSE;
419  }
420 
421 #else
422 
423  m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
424  m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
425 
426 #endif
427 
428  return kTRUE;
429 }
430 
431 
432 Bool_t
434  const char* name, const char* value,
435  const char* atr1, const char* val1, const char* atr2, const char* val2)
436 {
437 #ifndef __NOLIBXML__
438 
439  int rc;
440  /* Start an element named 'name' as child of previous element. */
441  rc = xmlTextWriterStartElement(writer, BAD_CAST (name));
442  if (rc < 0) {
443  m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterStartElement" << GEndl;
444  return kFALSE;
445  }
446  /* Add an attribute 'atr1' and value 'val1' to element. */
447  if ((atr1!=0) && (val1!=0)) {
448  rc = xmlTextWriterWriteAttribute(writer, BAD_CAST (atr1), BAD_CAST (val1));
449  if (rc < 0) {
450  m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterWriteAttribute" << GEndl;
451  return kFALSE;
452  }
453  }
454  /* Add an attribute 'atr2' and value 'val2' to element. */
455  if ((atr2!=0) && (val2!=0)) {
456  rc = xmlTextWriterWriteAttribute(writer, BAD_CAST (atr2), BAD_CAST (val2));
457  if (rc < 0) {
458  m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterWriteAttribute" << GEndl;
459  return kFALSE;
460  }
461  }
462  /* Add value 'value' to the element */
463  if ((value!=0)) {
464  rc = xmlTextWriterWriteString(writer, BAD_CAST (value));
465  if(rc < 0) {
466  m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterWriteString" << GEndl;
467  return kFALSE;
468  }
469  }
470  /* Close the element */
471  rc = xmlTextWriterEndElement(writer);
472  if (rc < 0) {
473  m_logger << kWARNING << "testXmlwriterDoc: Error at xmlTextWriterEndElement" << GEndl;
474  return kFALSE;
475  }
476 
477 #else
478 
479  m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
480  m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
481 
482 
483 #endif
484 
485  return kTRUE;
486 }
487 
488 
498 xmlChar *
500 {
501  xmlChar* out(0);
502 
503 #ifndef __NOLIBXML__
504 
505  int ret;
506  int size;
507  int out_size;
508  int temp;
509  xmlCharEncodingHandlerPtr handler;
510 
511  if (in == 0)
512  return 0;
513 
514  handler = xmlFindCharEncodingHandler(encoding);
515 
516  if (!handler) {
517  m_logger << kWARNING << "ConvertInput: no encoding handler found for " << (encoding ? encoding : "") << GEndl;
518  return 0;
519  }
520 
521  size = (int) strlen(in) + 1;
522  out_size = size * 2 - 1;
523  out = (unsigned char *) xmlMalloc((size_t) out_size);
524 
525  if (out != 0) {
526  temp = size - 1;
527  ret = handler->input(out, &out_size, (const xmlChar *) in, &temp);
528  if ((ret < 0) || (temp - size + 1)) {
529  if (ret < 0) {
530  m_logger << kWARNING << "ConvertInput: conversion wasn't successful." << GEndl;
531  } else {
532  m_logger << kWARNING << "ConvertInput: conversion wasn't successful. Converted: " << temp << " octets." << GEndl;
533  }
534 
535  xmlFree(out);
536  out = 0;
537  } else {
538  out = (unsigned char *) xmlRealloc(out, out_size + 1);
539  out[out_size] = 0; /*null terminating out */
540  }
541  } else {
542  m_logger << kWARNING << "ConvertInput: no mem" << GEndl;
543  }
544 
545 #else
546 
547  m_logger << kWARNING << "GoodRunsLists package compiled without libxml2" << GEndl;
548  m_logger << kWARNING << "can not write out GoodRunsList" << GEndl;
549 
550 
551 #endif
552 
553  return out;
554 }
555 
556 
xmlChar
unsigned char xmlChar
Definition: TGoodRunsListWriter.h:28
TGoodRunsList.h
temp
Definition: JetEventDict.h:21
TLumiBlockRange.h
Root::kWARNING
@ kWARNING
Definition: TMsgLogger.h:51
Root::TGoodRun
Definition: TGoodRun.h:27
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
Root::TGoodRunsListWriter::TGoodRunsListWriter
TGoodRunsListWriter()
Definition: TGoodRunsListWriter.cxx:41
Root::TGoodRunsListWriter::~TGoodRunsListWriter
~TGoodRunsListWriter()
Definition: TGoodRunsListWriter.cxx:61
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
athena.value
value
Definition: athena.py:124
Root::TGoodRunsListWriter::reset
void reset()
Definition: TGoodRunsListWriter.cxx:68
Root::TGoodRunsListWriter::WriteElement
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)
Definition: TGoodRunsListWriter.cxx:433
Root::TGoodRunsListWriter::m_grlvec
TGRLCollection m_grlvec
Definition: TGoodRunsListWriter.h:81
GEndl
#define GEndl
Definition: TMsgLogger.h:151
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
handler
void handler(int sig)
signal handler
Definition: rmain.cxx:98
Root::TGoodRunsListWriter::WriteLumiBlockCollection
Bool_t WriteLumiBlockCollection(xmlTextWriterPtr writer, const TGoodRun &goodrun)
Definition: TGoodRunsListWriter.cxx:388
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
Root::TGoodRunsListWriter::WriteXMLFile
Bool_t WriteXMLFile()
Definition: TGoodRunsListWriter.cxx:110
Root::TGoodRunsListWriter::GetXMLString
const TString & GetXMLString()
Definition: TGoodRunsListWriter.cxx:194
lumiFormat.i
int i
Definition: lumiFormat.py:85
Root::TGoodRun::IsEmpty
Bool_t IsEmpty() const
Definition: TGoodRun.cxx:251
Root::kINFO
@ kINFO
Definition: TMsgLogger.h:50
xmlTextWriterPtr
xmlTextWriter * xmlTextWriterPtr
Definition: TGoodRunsListWriter.h:30
generateReferenceFile.encoding
encoding
Definition: generateReferenceFile.py:15
Root::TGoodRunsListWriter::WriteLumiRangeCollection
Bool_t WriteLumiRangeCollection(xmlTextWriterPtr writer)
Definition: TGoodRunsListWriter.cxx:254
Root::TGoodRunsListWriter
Definition: TGoodRunsListWriter.h:38
TGoodRun.h
MY_ENCODING
#define MY_ENCODING
Definition: TGoodRunsListWriter.cxx:34
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
Root::TGoodRunsListWriter::ConvertInput
xmlChar * ConvertInput(const char *in, const char *encoding)
ConvertInput: @in: string in a given encoding @encoding: the encoding used.
Definition: TGoodRunsListWriter.cxx:499
merge_scale_histograms.doc
string doc
Definition: merge_scale_histograms.py:9
Root::TGoodRunsListWriter::WriteXMLFiles
Bool_t WriteXMLFiles()
Definition: TGoodRunsListWriter.cxx:81
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
ClassImp
ClassImp(Root::TGoodRunsListWriter) using namespace std
Root::TGoodRunsList
Definition: TGoodRunsList.h:31
example.goodrunslist
goodrunslist
Definition: example.py:26
Root::TGoodRunsListWriter::WriteNamedLumiRange
Bool_t WriteNamedLumiRange(xmlTextWriterPtr writer)
Definition: TGoodRunsListWriter.cxx:333
Root::TGoodRunsListWriter::GetXMLStrings
const std::vector< TString > & GetXMLStrings()
Definition: TGoodRunsListWriter.cxx:165
CxxUtils::reset
constexpr std::enable_if_t< is_bitmask_v< E >, E & > reset(E &lhs, E rhs)
Convenience function to clear bits in a class enum bitmask.
Definition: bitmask.h:251
Root::TGoodRun::GetRunNumber
Int_t GetRunNumber() const
Definition: TGoodRun.h:52
example.writer
writer
show summary of content
Definition: example.py:36
TGoodRunsListWriter.h