138 ClassImp(TUnfoldBinningXML);
147 void TUnfoldBinningXML::WriteDTD(std::ostream &out) {
149 <<
"<!-- TUnfold Version "<<TUnfold::GetTUnfoldVersion()<<
" -->\n"
150 <<
"<!ELEMENT TUnfoldBinning (BinningNode)+ >\n"
151 <<
"<!ELEMENT BinningNode (BinningNode+|(Binfactorlist?,Axis)|Bins) >\n"
152 <<
"<!ATTLIST BinningNode name ID #REQUIRED firstbin CDATA \"-1\"\n"
153 <<
" factor CDATA \"1.\">\n"
154 <<
"<!ELEMENT Axis ((Bin+,Axis?)|(Axis)) >\n"
155 <<
"<!ATTLIST Axis name CDATA #REQUIRED lowEdge CDATA #REQUIRED>\n"
156 <<
"<!ELEMENT Binfactorlist (#PCDATA)>\n"
157 <<
"<!ATTLIST Binfactorlist length CDATA #REQUIRED>\n"
158 <<
"<!ELEMENT Bin EMPTY>\n"
159 <<
"<!ATTLIST Bin width CDATA #REQUIRED location CDATA #IMPLIED\n"
160 <<
" center CDATA #IMPLIED repeat CDATA #IMPLIED>\n"
161 <<
"<!ELEMENT Bins (BinLabel)* >\n"
162 <<
"<!ATTLIST Bins nbin CDATA #REQUIRED>\n"
163 <<
"<!ELEMENT BinLabel EMPTY>\n"
164 <<
"<!ATTLIST BinLabel index CDATA #REQUIRED name CDATA #REQUIRED>\n";
172 void TUnfoldBinningXML::WriteDTD(
const char *file) {
190 TUnfoldBinningXML *TUnfoldBinningXML::ImportXML
191 (
const TXMLDocument *document,
const char *name) {
192 TUnfoldBinningXML *r=0;
193 TXMLNode *root=document->GetRootNode();
194 TXMLNode *binningNode=0;
195 if(root && (!TString(root->GetNodeName()).CompareTo(
"TUnfoldBinning")) &&
196 (root->GetNodeType()==TXMLNode::kXMLElementNode)) {
198 for(TXMLNode *node=root->GetChildren();node && !binningNode;
199 node=node->GetNextNode()) {
200 if(node->GetNodeType()==TXMLNode::kXMLElementNode &&
201 !TString(node->GetNodeName()).CompareTo(
"BinningNode") &&
202 node->GetAttributes()) {
204 TIterator *i=node->GetAttributes()->MakeIterator();
206 while((attr=(TXMLAttr *)i->Next())) {
207 if((!TString(attr->GetName()).CompareTo(
"name")) &&
208 ((!TString(attr->GetValue()).CompareTo(name)) ||
218 r=ImportXMLNode(binningNode);
232 TUnfoldBinningXML *TUnfoldBinningXML::ImportXMLNode
236 TUnfoldBinningXML *r=0;
238 const char *binNames=0;
239 TIterator *i=node->GetAttributes()->MakeIterator();
242 while((attr=(TXMLAttr *)i->Next())) {
243 TString attName(attr->GetName());
244 if(!attName.CompareTo(
"name")) {
245 name=attr->GetValue();
247 if(!attName.CompareTo(
"factor")) {
248 factor=TString(attr->GetValue()).Atof();
252 TString binNameList=
"";
254 for(TXMLNode *child=node->GetChildren();child;
255 child=child->GetNextNode()) {
257 if(child->GetNodeType()==TXMLNode::kXMLElementNode &&
258 !TString(child->GetNodeName()).CompareTo(
"Bins")) {
261 if(child->GetAttributes()) {
262 i=child->GetAttributes()->MakeIterator();
263 while((attr=(TXMLAttr *)i->Next())) {
264 TString attName(attr->GetName());
265 if(!attName.CompareTo(
"nbin")) {
267 nBins=TString(attr->GetValue()).Atoi();
272 TObjArray theBinNames;
273 for(TXMLNode *binName=child->GetChildren();binName;
274 binName=binName->GetNextNode()) {
275 if(binName->GetNodeType()==TXMLNode::kXMLElementNode &&
276 !TString(binName->GetNodeName()).CompareTo(
"BinLabel")) {
277 i=binName->GetAttributes()->MakeIterator();
278 const char *binLabelName=0;
280 while((attr=(TXMLAttr *)i->Next())) {
281 TString attName(attr->GetName());
282 if(!attName.CompareTo(
"index")) {
283 index=TString(attr->GetValue()).Atoi();
285 if(!attName.CompareTo(
"name")) {
286 binLabelName=attr->GetValue();
289 if((index>=0)&&(binLabelName)) {
290 if(index>=theBinNames.GetEntriesFast()) {
291 theBinNames.AddAtAndExpand
292 (
new TObjString(binLabelName),index);
298 for(Int_t ii=0;ii<theBinNames.GetEntriesFast()&&(ii<nBins);ii++) {
299 if(theBinNames.At(ii)) {
300 for(Int_t k=0;k<emptyName;k++) binNameList+=
";";
303 ((TObjString *)theBinNames.At(ii))->GetString();
307 if(binNameList.Length()>0) {
308 binNames=binNameList;
312 r=
new TUnfoldBinningXML(name,nBins,binNames);
318 TVectorD *perBinFactors=0;
319 for(TXMLNode *child=node->GetChildren();child;
320 child=child->GetNextNode()) {
322 if(child->GetNodeType()==TXMLNode::kXMLElementNode &&
323 !TString(child->GetNodeName()).CompareTo(
"Binfactorlist")) {
325 i=child->GetAttributes()->MakeIterator();
326 while((attr=(TXMLAttr *)i->Next())) {
327 TString attName(attr->GetName());
328 if(!attName.CompareTo(
"length")) {
329 length=TString(attr->GetValue()).Atoi();
333 if(length==r->GetDistributionNumberOfBins()) {
334 perBinFactors=
new TVectorD(length);
335 const char *text=child->GetText();
337 stringstream readFactors(text);
338 for(;nread<length;nread++) {
339 readFactors>> (*perBinFactors)(nread);
340 if(readFactors.fail())
break;
345 child->Error(
"ImportXMLNode",
"while reading per-bin factors"
346 " node=%s length=%d (expected %d)",r->GetName(),
347 length,r->GetDistributionNumberOfBins());
348 }
else if(nread!=length) {
349 child->Error(
"ImportXMLNode",
"while reading per-bin factors"
350 " TUnfoldBinning=%s expected %d found %d",
351 r->GetName(),length,nread);
352 delete perBinFactors;
359 r->SetBinFactor(factor,perBinFactors);
362 for(TXMLNode *child=node->GetChildren();child;
363 child=child->GetNextNode()) {
364 if(child->GetNodeType()==TXMLNode::kXMLElementNode &&
365 !TString(child->GetNodeName()).CompareTo(
"BinningNode") &&
366 child->GetAttributes()) {
367 TUnfoldBinning *childBinning=ImportXMLNode(child);
368 r->AddBinning(childBinning);
382 void TUnfoldBinningXML::AddAxisXML(TXMLNode *node) {
384 for(TXMLNode *child=node->GetChildren();child;
385 child=child->GetNextNode()) {
386 if(child->GetNodeType()==TXMLNode::kXMLElementNode) {
387 TString nodeName(child->GetNodeName());
388 if(!nodeName.CompareTo(
"Axis")) axis=child;
392 const char *axisName=0;
394 TIterator *i=axis->GetAttributes()->MakeIterator();
396 while((attr=(TXMLAttr *)i->Next())) {
397 TString attName(attr->GetName());
398 if(!attName.CompareTo(
"name")) {
399 axisName=attr->GetValue();
401 if(!attName.CompareTo(
"lowEdge")) {
402 binEdges[0]=TString(attr->GetValue()).Atof();
405 Bool_t hasMoreAxes=kFALSE;
406 Bool_t underflow=kFALSE,overflow=kFALSE;
407 for(TXMLNode *child=axis->GetChildren();child;
408 child=child->GetNextNode()) {
409 if(child->GetNodeType()==TXMLNode::kXMLElementNode) {
410 TString nodeName(child->GetNodeName());
411 if(!nodeName.CompareTo(
"Axis")) hasMoreAxes=kTRUE;
412 if(!nodeName.CompareTo(
"Bin")) {
413 Bool_t isUnderflow=kFALSE,isOverflow=kFALSE;
415 i=child->GetAttributes()->MakeIterator();
416 while((attr=(TXMLAttr *)i->Next())) {
417 TString attName(attr->GetName());
418 TString attText(attr->GetValue());
419 if(!attName.CompareTo(
"location")) {
420 isUnderflow= !attText.CompareTo(
"underflow");
421 isOverflow= !attText.CompareTo(
"overflow");
423 if(!attName.CompareTo(
"repeat")) {
424 repeat=attText.Atof();
428 node->Warning(
"AddAxisXML",
429 "attribute repeat=%d changed to repeat=1",
433 if((isUnderflow || isOverflow)&&(repeat!=1)) {
434 node->Error(
"AddAxisXML",
435 "underflow/overflow can not have repeat!=1 attribute");
437 if(isUnderflow || isOverflow) {
438 underflow |= isUnderflow;
439 overflow |= isOverflow;
441 Int_t iBin0=binEdges.GetSize();
442 Int_t iBin1=iBin0+repeat;
443 Double_t binWidth=0.0;
445 i=child->GetAttributes()->MakeIterator();
446 while((attr=(TXMLAttr *)i->Next())) {
447 TString attName(attr->GetName());
448 if(!attName.CompareTo(
"width")) {
449 binWidth=TString(attr->GetValue()).Atof();
453 node->Error(
"AddAxisXML",
454 "bin width can not be smaller than zero");
456 for(
int iBin=iBin0;iBin<iBin1;iBin++) {
457 binEdges[iBin]=binEdges[iBin0-1]+(iBin-iBin0+1)*binWidth;
463 AddAxis(axisName,binEdges.GetSize()-1,binEdges.GetArray(),
484 Int_t TUnfoldBinningXML::ExportXML
485 (
const TUnfoldBinning &binning,std::ostream &out,Bool_t writeHeader,
486 Bool_t writeFooter,Int_t indent) {
488 out<<
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
489 <<
"<!DOCTYPE TUnfoldBinning SYSTEM \"tunfoldbinning.dtd\">\n"
490 <<
"<TUnfoldBinning>\n";
492 TString trailer(
' ',indent);
493 out<<trailer<<
"<BinningNode name=\""<<binning.GetName()<<
"\" firstbin=\""
494 <<binning.GetStartBin();
495 if(binning.IsBinFactorGlobal()) {
496 out<<
"\" factor=\""<<binning.GetGlobalFactor()<<
"\">\n";
499 out<<trailer<<
" <Binfactorlist length=\""
500 <<binning.GetDistributionNumberOfBins()<<
"\">\n";
501 for(
int i=0;i<binning.GetDistributionNumberOfBins();i++) {
502 if(!(i % 10)) out<<trailer<<
" ";
503 out<<
" "<<binning.GetBinFactor(i+binning.GetStartBin());
504 if(((i %10)==9)||(i==binning.GetDistributionNumberOfBins()-1))
507 out<<trailer<<
" </Binfactorlist>\n";
509 if(binning.HasUnconnectedBins()) {
510 out<<trailer<<
" <Bins nbin=\""<<binning.GetDistributionNumberOfBins()
512 for(Int_t i=0;i<binning.GetDistributionNumberOfBins();i++) {
513 const TObjString *name=binning.GetUnconnectedBinName(i);
515 out<<trailer<<
" <BinLabel index=\""<<i<<
"\" name=\""
516 <<name->GetString()<<
"\" />\n";
518 out<<trailer<<
" </Bins>\n";
520 for(Int_t axis=0;axis<binning.GetDistributionDimension();axis++) {
521 TString axisTrailer(
' ',indent+1+axis);
522 TVectorD
const *edges=binning.GetDistributionBinning(axis);
523 out<<axisTrailer<<
"<Axis name=\""<<binning.GetDistributionAxisLabel(axis)
524 <<
"\" lowEdge=\""<<(*edges)[0]<<
"\">\n";
525 if(binning.HasUnderflow(axis)) {
526 out<<axisTrailer<<
" <Bin location=\"underflow\" width=\""
527 <<binning.GetDistributionUnderflowBinWidth(axis)<<
"\" center=\""
528 <<binning.GetDistributionBinCenter(axis,-1)<<
"\" />\n";
530 for(Int_t i=0;i<edges->GetNrows()-1;i++) {
532 Double_t width=(*edges)[i+1]-(*edges)[i];
533 Double_t center=binning.GetDistributionBinCenter(axis,i);
534 for(Int_t j=i+1;j<edges->GetNrows()-1;j++) {
535 double xEnd=(j-i+1)*width+(*edges)[i];
536 double xCent=center+(j-i)*width;
537 if((TMath::Abs(xEnd-(*edges)[j+1])<width*1.E-7)&&
538 (TMath::Abs(xCent-binning.GetDistributionBinCenter(axis,j))<
546 out<<axisTrailer<<
" <Bin width=\""
547 <<width<<
"\" center=\""<<center<<
"\" />\n";
549 out<<axisTrailer<<
" <Bin repeat=\""<<repeat
550 <<
"\" width=\""<<width<<
"\" center=\""<<center<<
"\" />\n";
554 if(binning.HasOverflow(axis)) {
555 out<<axisTrailer<<
" <Bin location=\"overflow\" width=\""
556 <<binning.GetDistributionOverflowBinWidth(axis)<<
"\" center=\""
557 <<binning.GetDistributionBinCenter(axis,edges->GetNrows()-1)<<
"\"/>\n";
560 for(Int_t axis=binning.GetDistributionDimension()-1;axis>=0;axis--) {
561 TString axisTrailer(
' ',indent+1+axis);
562 out<<axisTrailer<<
"</Axis>\n";
565 for(TUnfoldBinning
const *child=binning.GetChildNode();child;
566 child=child->GetNextNode()) {
567 ExportXML(*child,out,kFALSE,kFALSE,indent+1);
569 out<<trailer<<
"</BinningNode>\n";
571 out<<
"</TUnfoldBinning>\n";
573 return out.fail() ? 0 : 1;
586 Int_t TUnfoldBinningXML::ExportXML(
char const *fileName)
const {
587 ofstream outFile(fileName);
588 Int_t r=ExportXML(*
this,outFile,kTRUE,kTRUE);