00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <algorithm>
00036 #include "Interfaces/IAxis.h"
00037 #include "Translator.h"
00038
00039
00040
00041
00042 namespace Anaphe {
00043
00044
00045
00046
00048
00049
00050
00052
00053 const int Translator::constant_UNDERFLOW = -1;
00054 const int Translator::constant_OVERFLOW = -2;
00055 const int Translator::RUBBISH = -999;
00056 const int Translator::SCI_PRECISION = 8;
00057 const double Translator::ROUNDOFF_TOLERANCE = 1.0E-9;
00058 const AIDA_STD::string Translator::XML_VERSION = "1.0";
00059 const AIDA_STD::string Translator::ENCODING_TYPE = "ISO-8859-1";
00060
00061
00062
00063
00065
00066
00067
00069
00070 Translator::Translator(void)
00071 : silent (false),
00072 iXmlStream (0),
00073 iRootElement(0),
00074 iHisto1DIt (0),
00075 iHisto2DIt (0),
00076 iHisto3DIt (0),
00077 oStream (0),
00078 oRootElement(0)
00079 {
00080
00081 }
00082
00083
00084
00085
00086 Translator::Translator(const Translator& rhs)
00087 : silent (rhs.silent),
00088 iXmlStream (0),
00089 iRootElement(0),
00090 iHisto1DIt (0),
00091 iHisto2DIt (0),
00092 iHisto3DIt (0),
00093 oStream (0),
00094 oRootElement(0)
00095 {
00096
00097 }
00098
00099
00100
00101
00102 Translator::~Translator(void)
00103 {
00104 flush();
00105 removeOTree();
00106 removeITree();
00107 }
00108
00109
00110
00111
00112 const Translator& Translator::operator=(const Translator& rhs)
00113 {
00114
00115
00116 removeOTree();
00117 removeITree();
00118 silent = rhs.silent;
00119 return *this;
00120 }
00121
00122
00123
00124
00126
00127
00128
00130
00131 void Translator::noWarnings(const bool& b)
00132 {
00133 silent = b;
00134 }
00135
00136
00137
00138
00139 bool Translator::setInputStream(AIDA_STD::istream& s)
00140 {
00141 removeITree();
00142 return createNewITree(s);
00143 }
00144
00145
00146
00147
00148 bool Translator::setOutputStream(AIDA_STD::ostream& s)
00149 {
00150 oStream = &s;
00151 return true;
00152 }
00153
00154
00155
00156
00157 bool Translator::read(HistoParameters1D& hp)
00158 {
00159 if (!iRootElement) return false;
00160 while (iHisto1DIt != iRootElement->children().end()) {
00161 if (dimensionality(iHisto1DIt) == 1) readHistoElement(iHisto1DIt, hp);
00162 ++iHisto1DIt;
00163 if (goodParameters(hp)) return true;
00164 }
00165 return false;
00166 }
00167
00168
00169
00170
00171 bool Translator::read(HistoParameters2D& hp)
00172 {
00173 if (!iRootElement) return false;
00174 while (iHisto2DIt != iRootElement->children().end()) {
00175 if (dimensionality(iHisto2DIt) == 2) readHistoElement(iHisto2DIt, hp);
00176 ++iHisto2DIt;
00177 if (goodParameters(hp)) return true;
00178 }
00179 return false;
00180 }
00181
00182
00183
00184
00185 bool Translator::read(HistoParameters3D& hp)
00186 {
00187 if (!iRootElement) return false;
00188 while (iHisto3DIt != iRootElement->children().end()) {
00189 if (dimensionality(iHisto3DIt) == 3) readHistoElement(iHisto3DIt, hp);
00190 ++iHisto3DIt;
00191 if (goodParameters(hp)) return true;
00192 }
00193 return false;
00194 }
00195
00196
00197
00198
00199 bool Translator::write(const IHistogram1D& h)
00200 {
00201 return genericWrite(h);
00202 }
00203
00204
00205
00206
00207 bool Translator::write(const IHistogram2D& h)
00208 {
00209 return genericWrite(h);
00210 }
00211
00212
00213
00214
00215 bool Translator::write(const IHistogram3D& h)
00216 {
00217 return genericWrite(h);
00218 }
00219
00220
00221
00222
00223 void Translator::flush(void)
00224 {
00225 if (!oStream || !oRootElement) return;
00226 writeHeader(*oStream);
00227 DataXML::OutputXMLStream oxml(*oStream);
00228 oxml.write(*oRootElement);
00229 writeFooter(*oStream);
00230 removeOTree();
00231 }
00232
00233
00234
00235
00237
00238
00239
00241
00242 template<class HistoType>
00243 bool Translator::genericWrite(const HistoType& h)
00244 {
00245
00246
00247 if (!oStream) { noOutputStreamError(); return false; }
00248 else {
00249 if (!oRootElement) createNewOTree();
00250 if (!oRootElement) return false;
00251 else return appendHisto(h,oRootElement);
00252 }
00253 }
00254
00255
00256
00257
00258 template<class HistoType>
00259 bool Translator::appendHisto(const HistoType& h, const ElementIterator& parent)
00260 {
00261 DataXML::DataObject histoElement;
00262 bool allOK = writeHistoElement(h, &histoElement);
00263 if (!allOK) return false;
00264 else {
00265 parent->appendChild(histoElement);
00266 return true;
00267 }
00268 }
00269
00270
00271
00272
00273 template<class FP>
00274 AIDA_STD::string Translator::toString(const FP& number) const
00275 {
00276
00277 AIDA_STD::ostrstream buf;
00278 buf.setf(AIDA_STD::ios::scientific);
00279 buf.precision(SCI_PRECISION);
00280 buf << number << AIDA_STD::ends;
00281 AIDA_STD::string ret = buf.str();
00282 buf.freeze(false);
00283 return ret;
00284 }
00285
00286
00287
00288
00289 AIDA_STD::string Translator::toString(const int& number) const
00290 {
00291
00292 AIDA_STD::ostrstream buf;
00293 buf << number << AIDA_STD::ends;
00294 AIDA_STD::string ret = buf.str();
00295 buf.freeze(false);
00296 return ret;
00297 }
00298
00299
00300
00301
00302 void Translator::removeITree(void)
00303 {
00304 if (iXmlStream) { delete iXmlStream; iXmlStream = 0; }
00305 iRootElement = 0;
00306 resetIterators();
00307 }
00308
00309
00310
00311
00312 void Translator::removeOTree(void)
00313 {
00314 if (oRootElement) { delete oRootElement; oRootElement = 0; }
00315 }
00316
00317
00318
00319
00320 bool Translator::createNewITree(AIDA_STD::istream& s)
00321 {
00322 removeITree();
00323 iXmlStream = new DataXML::InputXMLStream;
00324 if (!iXmlStream) return false;
00325 iRootElement = &(iXmlStream->read(s));
00326 if (!iXmlStream->success()) {
00327 removeITree();
00328 badInputStreamError();
00329 return false;
00330 }
00331 else if (iRootElement->name() != "aida") {
00332 removeITree();
00333 wrongDocTypeError();
00334 return false;
00335 }
00336 else {
00337 resetIterators();
00338 return true;
00339 }
00340 }
00341
00342
00343
00344
00345 bool Translator::createNewOTree(void)
00346 {
00347 removeOTree();
00348 oRootElement = new DataXML::DataObject;
00349 if (!oRootElement) return false;
00350 oRootElement->setName("aida");
00351 appendHistoTypeElement(oRootElement);
00352 return true;
00353 }
00354
00355
00356
00357
00358 void Translator::appendHistoTypeElement(const ElementIterator& parent)
00359 {
00360
00361 if (!parent) return;
00362 DataXML::DataObject hto;
00363 hto.setName("histoType");
00364 hto.setAttribute("package", "Anaphe");
00365 parent->appendChild(hto);
00366 }
00367
00368
00369
00370
00371 bool Translator::writeHistoElement(const IHistogram1D& h, const ElementIterator& histoElement)
00372 {
00373 if (!histoElement) return false;
00374 histoElement->setName("histogram1d");
00375 setTitle(h, histoElement);
00376 if (!setAxes (h, histoElement)) return false;
00377 if (!setStats(h, histoElement)) return false;
00378 if (!setData (h, histoElement)) return false;
00379 return true;
00380 }
00381
00382
00383
00384
00385 bool Translator::writeHistoElement(const IHistogram2D& h, const ElementIterator& histoElement)
00386 {
00387 if (!histoElement) return false;
00388 histoElement->setName("histogram2d");
00389 setTitle(h, histoElement);
00390 if (!setAxes (h, histoElement)) return false;
00391 if (!setStats(h, histoElement)) return false;
00392 if (!setData (h, histoElement)) return false;
00393 return true;
00394 }
00395
00396
00397
00398
00399 bool Translator::writeHistoElement(const IHistogram3D& h, const ElementIterator& histoElement)
00400 {
00401 if (!histoElement) return false;
00402 histoElement->setName("histogram3d");
00403 setTitle(h, histoElement);
00404 if (!setAxes (h, histoElement)) return false;
00405 if (!setStats(h, histoElement)) return false;
00406 if (!setData (h, histoElement)) return false;
00407 return true;
00408 }
00409
00410
00411
00412
00413 void Translator::setTitle(const IHistogram& h, const ElementIterator& histoElement)
00414 {
00415 histoElement->setAttribute("title", h.title());
00416 }
00417
00418
00419
00420
00421 bool Translator::setAxes(const IHistogram1D& h, const ElementIterator& histoElement)
00422 {
00423 const IAxis* xaxis = h.xAxis();
00424 if (!xaxis) return false;
00425 appendAxis (histoElement, "x", *xaxis);
00426 return true;
00427 }
00428
00429
00430
00431
00432 bool Translator::setAxes(const IHistogram2D& h, const ElementIterator& histoElement)
00433 {
00434 const IAxis* xaxis = h.xAxis();
00435 const IAxis* yaxis = h.yAxis();
00436 if (!xaxis || !yaxis) return false;
00437 appendAxis (histoElement, "x", *xaxis);
00438 appendAxis (histoElement, "y", *yaxis);
00439 return true;
00440 }
00441
00442
00443
00444
00445 bool Translator::setAxes(const IHistogram3D& h, const ElementIterator& histoElement)
00446 {
00447 const IAxis* xaxis = h.xAxis();
00448 const IAxis* yaxis = h.yAxis();
00449 const IAxis* zaxis = h.zAxis();
00450 if (!xaxis || !yaxis || !zaxis) return false;
00451 appendAxis (histoElement, "x", *xaxis);
00452 appendAxis (histoElement, "y", *yaxis);
00453 appendAxis (histoElement, "z", *zaxis);
00454 return true;
00455 }
00456
00457
00458
00459
00460 bool Translator::appendAxis(const ElementIterator& histoElement,
00461 const AIDA_STD::string& axisName,
00462 const IAxis& axis)
00463 {
00464
00465 DataXML::DataObject axisElement;
00466 axisElement.setName("axis");
00467 axisElement.setAttribute("direction", axisName);
00468 axisElement.setAttribute("min", toString(axis.lowerEdge()));
00469 axisElement.setAttribute("max", toString(axis.upperEdge()));
00470 axisElement.setAttribute("numberOfBins", toString(axis.bins()));
00471 if (variableBins(axis)) {
00472 DataXML::DataObject borderElement;
00473 borderElement.setName("binBorder");
00474 const int nEdges = axis.bins() - 1;
00475 for (int i = 0; i < nEdges; ++i) {
00476 borderElement.setAttribute("value", toString(axis.binUpperEdge(i)));
00477 axisElement.appendChild(borderElement);
00478 }
00479 }
00480 histoElement->appendChild(axisElement);
00481 return true;
00482 }
00483
00484
00485
00486
00487 bool Translator::variableBins(const IAxis& axis) const
00488 {
00489
00490
00491 const int nBins = axis.bins();
00492 if (nBins < 2) return false;
00493 const int nEdges = nBins - 1;
00494 const double low = axis.lowerEdge(), high = axis.upperEdge();
00495 const double binWidth = (high-low)/static_cast<double>(nBins);
00496 for (int i = 0; i < nEdges; ++i) {
00497 if (significantlyDifferent(axis.binUpperEdge(i),
00498 low+(binWidth*(i+1))
00499 )) return true;
00500 }
00501 return false;
00502 }
00503
00504
00505
00506
00507 bool Translator::setStats(const IHistogram1D& h, const ElementIterator& histoElement)
00508 {
00509
00510 DataXML::DataObject allStats;
00511 allStats.setName("statistics");
00512 allStats.setAttribute("entries", toString(h.entries()));
00513 appendStat(&allStats, "x", h.mean(), h.rms());
00514 histoElement->appendChild(allStats);
00515 return true;
00516 }
00517
00518
00519
00520
00521 bool Translator::setStats(const IHistogram2D& h, const ElementIterator& histoElement)
00522 {
00523
00524 DataXML::DataObject allStats;
00525 allStats.setName("statistics");
00526 allStats.setAttribute("entries", toString(h.entries()));
00527 appendStat(&allStats, "x", h.meanX(), h.rmsX());
00528 appendStat(&allStats, "y", h.meanY(), h.rmsY());
00529 histoElement->appendChild(allStats);
00530 return true;
00531 }
00532
00533
00534
00535
00536 bool Translator::setStats(const IHistogram3D& h, const ElementIterator& histoElement)
00537 {
00538
00539 DataXML::DataObject allStats;
00540 allStats.setName("statistics");
00541 allStats.setAttribute("entries", toString(h.entries()));
00542 appendStat(&allStats, "x", h.meanX(), h.rmsX());
00543 appendStat(&allStats, "y", h.meanY(), h.rmsY());
00544 appendStat(&allStats, "z", h.meanZ(), h.rmsZ());
00545 histoElement->appendChild(allStats);
00546 return true;
00547 }
00548
00549
00550
00551
00552 bool Translator::appendStat(const ElementIterator& statisticsElement,
00553 const AIDA_STD::string& axisName,
00554 const double& mean, const double& rms)
00555 {
00556
00557 DataXML::DataObject statElement;
00558 statElement.setName("statistic");
00559 statElement.setAttribute("direction", axisName);
00560 statElement.setAttribute("mean",toString(mean));
00561 statElement.setAttribute("rms", toString(rms));
00562 statisticsElement->appendChild(statElement);
00563 return true;
00564 }
00565
00566
00567
00568
00569 bool Translator::setData(const IHistogram1D& h, const ElementIterator& histoElement)
00570 {
00571
00572
00573 DataXML::DataObject dataElement;
00574 dataElement.setName("data1d");
00575 const int dim = 1;
00576 const int nbx = h.xAxis()->bins();
00577 for (int i = -2; i < nbx; ++i) {
00578 int hi = binConversion(i,true);
00579 int ti = binConversion(i,false);
00580 int entries = h.binEntries(hi);
00581 double height = h.binHeight (hi);
00582 double error = h.binError (hi);
00583 appendDataPoint(dim, &dataElement, ti, 0, 0, entries, height, error);
00584 }
00585 histoElement->appendChild(dataElement);
00586 return true;
00587 }
00588
00589
00590
00591
00592 bool Translator::setData(const IHistogram2D& h, const ElementIterator& histoElement)
00593 {
00594
00595
00596 DataXML::DataObject dataElement;
00597 dataElement.setName("data2d");
00598 const int dim = 2;
00599 const int nbx = h.xAxis()->bins();
00600 const int nby = h.yAxis()->bins();
00601 for (int i = -2; i < nbx; ++i) {
00602 int hi = binConversion(i,true);
00603 int ti = binConversion(i,false);
00604 for (int j = -2; j < nby; ++j) {
00605 int hj = binConversion(j,true);
00606 int tj = binConversion(j,false);
00607 int entries = h.binEntries(hi, hj);
00608 double height = h.binHeight (hi, hj);
00609 double error = h.binError (hi, hj);
00610 appendDataPoint(dim, &dataElement, ti, tj, 0, entries, height, error);
00611 }
00612 }
00613 histoElement->appendChild(dataElement);
00614 return true;
00615 }
00616
00617
00618
00619
00620 bool Translator::setData(const IHistogram3D& h, const ElementIterator& histoElement)
00621 {
00622
00623
00624 DataXML::DataObject dataElement;
00625 dataElement.setName("data3d");
00626 const int dim = 3;
00627 const int nbx = h.xAxis()->bins();
00628 const int nby = h.yAxis()->bins();
00629 const int nbz = h.zAxis()->bins();
00630 for (int i = -2; i < nbx; ++i) {
00631 int hi = binConversion(i,true);
00632 int ti = binConversion(i,false);
00633 for (int j = -2; j < nby; ++j) {
00634 int hj = binConversion(j,true);
00635 int tj = binConversion(j,false);
00636 for (int k = -2; k < nbz; ++k) {
00637 int hk = binConversion(k,true);
00638 int tk = binConversion(k,false);
00639 int entries = h.binEntries(hi, hj, hk);
00640 double height = h.binHeight (hi, hj, hk);
00641 double error = h.binError (hi, hj, hk);
00642 appendDataPoint(dim, &dataElement, ti, tj, tk, entries, height, error);
00643 }
00644 }
00645 }
00646 histoElement->appendChild(dataElement);
00647 return true;
00648 }
00649
00650
00651
00652
00653 int Translator::binConversion(const int& i, const bool& histoMetric) const
00654 {
00655
00656
00657
00658 if (i == -2) return (histoMetric ? IHistogram::UNDERFLOW_BIN : constant_UNDERFLOW);
00659 else if (i == -1) return (histoMetric ? IHistogram::OVERFLOW_BIN : constant_OVERFLOW);
00660 else return i;
00661 }
00662
00663
00664
00665
00666 void Translator::appendDataPoint(const int& dim, const ElementIterator& parent,
00667 const int& xbin, const int& ybin, const int& zbin,
00668 const int& entries, const double& height,
00669 const double& error)
00670 {
00671
00672 DataXML::DataObject binElement;
00673 binElement.setName(AIDA_STD::string("bin")+toString(dim)+AIDA_STD::string("d"));
00674 if (dim >= 1) addBinNumberAttribute(&binElement, "binNumX", xbin);
00675 if (dim >= 2) addBinNumberAttribute(&binElement, "binNumY", ybin);
00676 if (dim >= 3) addBinNumberAttribute(&binElement, "binNumZ", zbin);
00677 binElement.setAttribute("height", toString(height) );
00678 binElement.setAttribute("error", toString(error) );
00679 binElement.setAttribute("entries", toString(entries));
00680 parent->appendChild(binElement);
00681 }
00682
00683
00684
00685
00686 void Translator::addBinNumberAttribute(const ElementIterator& el,
00687 const AIDA_STD::string& attName,
00688 const int& bn)
00689 {
00690 AIDA_STD::string id;
00691 if (bn == constant_UNDERFLOW) id = "UNDERFLOW";
00692 else if (bn == constant_OVERFLOW) id = "OVERFLOW";
00693 else id = toString(bn);
00694 el->setAttribute(attName, id);
00695 }
00696
00697
00698
00699
00700 void Translator::resetIterators(void)
00701 {
00702 if (iRootElement)
00703 iHisto1DIt = iHisto2DIt = iHisto3DIt = iRootElement->children().begin();
00704 else
00705 iHisto1DIt = iHisto2DIt = iHisto3DIt = 0;
00706 }
00707
00708
00709
00710
00711 bool Translator::readHistoElement(const ElementCIterator& histoElement,
00712 HistoParameters1D& hp)
00713 {
00714 if (dimensionality(histoElement) == 1) {
00715 getTitle (histoElement, hp);
00716 getXAxis (histoElement, hp);
00717 getStatistics (histoElement, hp);
00718 getData (histoElement, hp);
00719 return goodParameters(hp);
00720 }
00721 else return false;
00722 }
00723
00724
00725
00726
00727 bool Translator::readHistoElement(const ElementCIterator& histoElement,
00728 HistoParameters2D& hp)
00729 {
00730 if (dimensionality(histoElement) == 2) {
00731 getTitle (histoElement, hp);
00732 getXAndYAxes (histoElement, hp);
00733 getStatistics (histoElement, hp);
00734 getData (histoElement, hp);
00735 return goodParameters(hp);
00736 }
00737 else return false;
00738 }
00739
00740
00741
00742
00743 bool Translator::readHistoElement(const ElementCIterator& histoElement,
00744 HistoParameters3D& hp)
00745 {
00746 if (dimensionality(histoElement) == 3) {
00747 getTitle (histoElement, hp);
00748 getXYAndZAxes (histoElement, hp);
00749 getStatistics (histoElement, hp);
00750 getData (histoElement, hp);
00751 return goodParameters(hp);
00752 }
00753 else return false;
00754 }
00755
00756
00757
00758
00759 void Translator::writeHeader(AIDA_STD::ostream& stream) const
00760 {
00761 stream << "<?xml"
00762 << " "
00763 << "version=\"" << XML_VERSION << "\""
00764 << " "
00765 << "encoding=\"" << ENCODING_TYPE << "\""
00766 << "?>"
00767 << AIDA_STD::endl;
00768 stream << "<!"
00769 << "DOCTYPE"
00770 << " " << "aida" << " "
00771 << "SYSTEM"
00772 << " " << "\"aida.dtd\"" << " "
00773 << ">"
00774 << AIDA_STD::endl;
00775 }
00776
00777
00778
00779
00780 void Translator::writeFooter(AIDA_STD::ostream& stream) const
00781 {
00782
00783 }
00784
00785
00786
00787
00788 int Translator::dimensionality(const ElementCIterator& histoElement) const
00789 {
00790 if (histoElement->name() == "histogram1d") return 1;
00791 else if (histoElement->name() == "histogram2d") return 2;
00792 else if (histoElement->name() == "histogram3d") return 3;
00793 else return 0;
00794 }
00795
00796
00797
00798
00799 void Translator::getTitle(const ElementCIterator& histoElement,
00800 HistoParameters& hp) const
00801 {
00802 hp.setTitle(histoElement->getAttributeValue("title"));
00803 }
00804
00805
00806
00807
00808 void Translator::getXAxis(const ElementCIterator& histoElement,
00809 HistoParameters1D& hp) const
00810 {
00811 int nbx = 0;
00812 double lowx = 0.0, highx = 0.0;
00813 HistoParameters::VecDouble vecx;
00814 getAxis(histoElement, "x", nbx, lowx, highx, vecx);
00815 hp.setLowX (lowx);
00816 hp.setHighX (highx);
00817 hp.setNbX (nbx);
00818 hp.setEdgesX(vecx);
00819 }
00820
00821
00822
00823
00824 void Translator::getXAndYAxes(const ElementCIterator& histoElement,
00825 HistoParameters2D& hp) const
00826 {
00827 int nbx = 0, nby = 0;
00828 double lowx = 0.0, lowy = 0.0, highx = 0.0, highy = 0.0;
00829 HistoParameters::VecDouble vecx, vecy;
00830 getAxis(histoElement, "x", nbx, lowx, highx, vecx);
00831 getAxis(histoElement, "y", nby, lowy, highy, vecy);
00832 hp.setNbX (nbx); hp.setNbY (nby);
00833 hp.setLowX (lowx); hp.setLowY (lowy);
00834 hp.setHighX (highx); hp.setHighY (highy);
00835 hp.setEdgesX(vecx); hp.setEdgesY(vecy);
00836 }
00837
00838
00839
00840
00841 void Translator::getXYAndZAxes(const ElementCIterator& histoElement,
00842 HistoParameters3D& hp) const
00843 {
00844 int nbx = 0, nby = 0, nbz = 0;
00845 double lowx = 0.0, lowy = 0.0, lowz = 0.0, highx = 0.0, highy = 0.0, highz = 0.0;
00846 HistoParameters::VecDouble vecx, vecy, vecz;
00847 getAxis(histoElement, "x", nbx, lowx, highx, vecx);
00848 getAxis(histoElement, "y", nby, lowy, highy, vecy);
00849 getAxis(histoElement, "z", nbz, lowz, highz, vecz);
00850 hp.setNbX (nbx); hp.setNbY (nby); hp.setNbZ (nbz);
00851 hp.setLowX (lowx); hp.setLowY (lowy); hp.setLowZ (lowz);
00852 hp.setHighX (highx); hp.setHighY (highy); hp.setHighZ (highz);
00853 hp.setEdgesX(vecx); hp.setEdgesY(vecy); hp.setEdgesZ(vecz);
00854 }
00855
00856
00857
00858
00859 void Translator::getAxis(const ElementCIterator& histoElement,
00860 const AIDA_STD::string& axisName,
00861 int& nBins, double& low, double& high,
00862 HistoParameters::VecDouble& vec) const
00863 {
00864
00865 for (ElementCIterator i = histoElement->children().begin();
00866 i != histoElement->children().end(); ++i) {
00867 if (i->name() == "axis" && i->getAttributeValue("direction") == axisName) {
00868
00869 DataXML::to_value(i->getAttributeValue("min"), low);
00870 DataXML::to_value(i->getAttributeValue("max"), high);
00871 DataXML::to_value(i->getAttributeValue("numberOfBins"), nBins);
00872
00873 getBinEdges(i, vec, low, high);
00874 if (vec.empty()) return;
00875 else {
00876
00877
00878
00879 if (nBins != static_cast<int>(vec.size())-1) { vec.clear(); return; }
00880 else AIDA_STD::sort(vec.begin(), vec.end());
00881 }
00882 }
00883 }
00884 }
00885
00886
00887
00888
00889 void Translator::getBinEdges(const ElementCIterator& elm,
00890 HistoParameters::VecDouble& vec,
00891 const double& low, const double& high) const
00892 {
00893
00894 vec.clear();
00895 vec.push_back(low);
00896 for (ElementCIterator i = elm->children().begin();
00897 i != elm->children().end(); ++i) {
00898 if (i->name() == "binBorder") {
00899 double edge = 0.0;
00900 if (DataXML::to_value(i->getAttributeValue("value"), edge))
00901 vec.push_back(edge);
00902 }
00903 }
00904
00905 if (static_cast<int>(vec.size()) > 1) vec.push_back(high);
00906 else vec.clear();
00907 }
00908
00909
00910
00911
00912 void Translator::getStatistics(const ElementCIterator& histoElement,
00913 HistoParameters1D& hp) const
00914 {
00915 int nev = 0;
00916 double meanx = 0.0, rmsx = 0.0, skewx = 0.0;
00917 getNumberOfEntries(histoElement, nev);
00918 getStatistic(histoElement, "x", meanx, rmsx, skewx);
00919 hp.setNev(nev);
00920 hp.setEbe(static_cast<double>(nev));
00921 hp.setMeanX(meanx);
00922 hp.setRMSX(rmsx);
00923 }
00924
00925
00926
00927
00928 void Translator::getStatistics(const ElementCIterator& histoElement,
00929 HistoParameters2D& hp) const
00930 {
00931 int nev = 0;
00932 double meanx = 0.0, rmsx = 0.0, skewx = 0.0;
00933 double meany = 0.0, rmsy = 0.0, skewy = 0.0;
00934 getNumberOfEntries(histoElement, nev);
00935 getStatistic(histoElement, "x", meanx, rmsx, skewx);
00936 getStatistic(histoElement, "y", meany, rmsy, skewy);
00937 hp.setNev(nev);
00938 hp.setEbe(static_cast<double>(nev));
00939 hp.setMeanX(meanx); hp.setMeanY(meany);
00940 hp.setRMSX(rmsx); hp.setRMSY(rmsy);
00941 }
00942
00943
00944
00945
00946 void Translator::getStatistics(const ElementCIterator& histoElement,
00947 HistoParameters3D& hp) const
00948 {
00949 int nev = 0;
00950 double meanx = 0.0, rmsx = 0.0, skewx = 0.0;
00951 double meany = 0.0, rmsy = 0.0, skewy = 0.0;
00952 double meanz = 0.0, rmsz = 0.0, skewz = 0.0;
00953 getNumberOfEntries(histoElement, nev);
00954 getStatistic(histoElement, "x", meanx, rmsx, skewx);
00955 getStatistic(histoElement, "y", meany, rmsy, skewy);
00956 getStatistic(histoElement, "z", meanz, rmsz, skewz);
00957 hp.setNev(nev);
00958 hp.setEbe(static_cast<double>(nev));
00959 hp.setMeanX(meanx); hp.setMeanY(meany); hp.setMeanZ(meanz);
00960 hp.setRMSX(rmsx); hp.setRMSY(rmsy); hp.setRMSZ(rmsz);
00961 }
00962
00963
00964
00965
00966 void Translator::getNumberOfEntries(const ElementCIterator& histoElement,
00967 int& nev) const
00968 {
00969 ElementCIterator statisticsElement = histoElement->getChild("statistics");
00970 if (statisticsElement == histoElement->children().end()) {
00971 missingElementError("statistics");
00972 return;
00973 }
00974 else DataXML::to_value(statisticsElement->getAttributeValue("entries"), nev);
00975 }
00976
00977
00978
00979
00980 void Translator::getStatistic(const ElementCIterator& histoElement,
00981 const AIDA_STD::string& axisName,
00982 double& mean, double& rms, double& skew) const
00983 {
00984 ElementCIterator statisticsElement = histoElement->getChild("statistics");
00985 if (statisticsElement == histoElement->children().end()) {
00986 missingElementError("statistics");
00987 return;
00988 }
00989 for (ElementCIterator i = statisticsElement->children().begin();
00990 i != statisticsElement->children().end(); ++i) {
00991 if (i->name() == "statistic" && i->getAttributeValue("direction") == axisName) {
00992 DataXML::to_value(i->getAttributeValue("mean"), mean);
00993 DataXML::to_value(i->getAttributeValue("rms"), rms);
00994 DataXML::to_value(i->getAttributeValue("skewness"), skew);
00995 return;
00996 }
00997 }
00998 missingElementError("statistic ("+axisName+" axis)");
00999 }
01000
01001
01002
01003
01004 void Translator::getData(const ElementCIterator& histoElement,
01005 HistoParameters1D& p) const
01006 {
01007 const AIDA_STD::string dataName = "data1d";
01008 const AIDA_STD::string binName = "bin1d";
01009 const ElementCIterator dataElement = getChild(histoElement, dataName);
01010 if (!dataElement) return;
01011 const int nBinsX = p.nbX(), vecSizeX = nBinsX+2;
01012 if (nBinsX < 1) return;
01013 HistoParameters::VecData binMatrix;
01014 resizeMatrix(binMatrix, vecSizeX);
01015 for (ElementCIterator elm = dataElement->children().begin();
01016 elm != dataElement->children().end(); ++elm) {
01017 if (elm->name() == binName) {
01018 int bnx = xBinNumber(elm);
01019
01020 if (!consistentBin(bnx,p)) { nonsenseBinError(); return; }
01021
01022 convertBinNumber(bnx, nBinsX);
01023 fillBin(elm, binMatrix[bnx]);
01024 }
01025 }
01026 p.setValues(binMatrix);
01027 }
01028
01029
01030
01031
01032 void Translator::getData(const ElementCIterator& histoElement,
01033 HistoParameters2D& p) const
01034 {
01035 const AIDA_STD::string dataName = "data2d";
01036 const AIDA_STD::string binName = "bin2d";
01037 const ElementCIterator dataElement = getChild(histoElement, dataName);
01038 if (!dataElement) return;
01039 const int nBinsX = p.nbX(), vecSizeX = nBinsX+2;
01040 const int nBinsY = p.nbY(), vecSizeY = nBinsY+2;
01041 if (nBinsX < 1 || nBinsY < 1) return;
01042 HistoParameters::VecVecData binMatrix;
01043 resizeMatrix(binMatrix, vecSizeX, vecSizeY);
01044 for (ElementCIterator elm = dataElement->children().begin();
01045 elm != dataElement->children().end(); ++elm) {
01046 if (elm->name() == binName) {
01047 int bnx = xBinNumber(elm);
01048 int bny = yBinNumber(elm);
01049
01050 if (!consistentBin(bnx,bny,p)) { nonsenseBinError(); return; }
01051
01052 convertBinNumber(bnx, nBinsX);
01053 convertBinNumber(bny, nBinsY);
01054 fillBin(elm, binMatrix[bnx][bny]);
01055 }
01056 }
01057 p.setValues(binMatrix);
01058 }
01059
01060
01061
01062
01063 void Translator::getData(const ElementCIterator& histoElement,
01064 HistoParameters3D& p) const
01065 {
01066 const AIDA_STD::string dataName = "data3d";
01067 const AIDA_STD::string binName = "bin3d";
01068 const ElementCIterator dataElement = getChild(histoElement, dataName);
01069 if (!dataElement) return;
01070 const int nBinsX = p.nbX(), vecSizeX = nBinsX+2;
01071 const int nBinsY = p.nbY(), vecSizeY = nBinsY+2;
01072 const int nBinsZ = p.nbZ(), vecSizeZ = nBinsZ+2;
01073 if (nBinsX < 1 || nBinsY < 1 || nBinsZ < 1) return;
01074 HistoParameters::VecVecVecData binMatrix;
01075 resizeMatrix(binMatrix, vecSizeX, vecSizeY, vecSizeZ);
01076 for (ElementCIterator elm = dataElement->children().begin();
01077 elm != dataElement->children().end(); ++elm) {
01078 if (elm->name() == binName) {
01079 int bnx = xBinNumber(elm);
01080 int bny = yBinNumber(elm);
01081 int bnz = zBinNumber(elm);
01082
01083 if (!consistentBin(bnx,bny,bnz,p)) { nonsenseBinError(); return; }
01084
01085 convertBinNumber(bnx, nBinsX);
01086 convertBinNumber(bny, nBinsY);
01087 convertBinNumber(bnz, nBinsZ);
01088 fillBin(elm, binMatrix[bnx][bny][bnz]);
01089 }
01090 }
01091 p.setValues(binMatrix);
01092 }
01093
01094
01095
01096
01097 void Translator::fillBin(const ElementCIterator& elm, HistoParameters::BinInfo& bin) const
01098 {
01099 bin.height = binHeight(elm);
01100 bin.error = binError(elm);
01101 bin.error2 = binError2(elm);
01102 bin.entries = binEntries(elm);
01103 }
01104
01105
01106
01107
01108 Translator::ElementCIterator Translator::getChild(const ElementCIterator& parent,
01109 const AIDA_STD::string& childName) const
01110 {
01111 ElementCIterator child = parent->getChild(childName);
01112 if (child == parent->children().end() || child == 0) {
01113 missingElementError(childName);
01114 return 0;
01115 }
01116 else return child;
01117 }
01118
01119
01120
01121
01122 void Translator::convertBinNumber(int& i, const int& nbins) const
01123 {
01124
01125
01126 if (i == constant_UNDERFLOW) i = 0;
01127 else if (i == constant_OVERFLOW) i = nbins+1;
01128 else ++i;
01129 }
01130
01131
01132
01133
01134 int Translator::binNumber(const ElementCIterator& it) const
01135 {
01136 const AIDA_STD::string sbn = it->getAttributeValue("binNum");
01137 return binNumber(sbn);
01138 }
01139
01140
01141
01142
01143 int Translator::xBinNumber(const ElementCIterator& it) const
01144 {
01145 AIDA_STD::string sbn = it->getAttributeValue("binNumX");
01146 if (sbn == "") sbn = it->getAttributeValue("binNum");
01147 return binNumber(sbn);
01148 }
01149
01150
01151
01152
01153 int Translator::yBinNumber(const ElementCIterator& it) const
01154 {
01155 const AIDA_STD::string sbn = it->getAttributeValue("binNumY");
01156 return binNumber(sbn);
01157 }
01158
01159
01160
01161
01162 int Translator::zBinNumber(const ElementCIterator& it) const
01163 {
01164 const AIDA_STD::string sbn = it->getAttributeValue("binNumZ");
01165 return binNumber(sbn);
01166 }
01167
01168
01169
01170
01171 int Translator::binNumber(const AIDA_STD::string& sbn) const
01172 {
01173 if (sbn == "UNDERFLOW" || sbn == "") return constant_UNDERFLOW;
01174 else if (sbn == "OVERFLOW") return constant_OVERFLOW;
01175 else return stringToInt(sbn);
01176 }
01177
01178
01179
01180
01181 double Translator::binHeight(const ElementCIterator& binElement) const
01182 {
01183 double val = 0.0;
01184 return ((DataXML::to_value(binElement->getAttributeValue("height"),val)) ? val : 0.0);
01185 }
01186
01187
01188
01189
01190 double Translator::binError(const ElementCIterator& binElement) const
01191 {
01192 double val = 0.0;
01193 return ((DataXML::to_value(binElement->getAttributeValue("error"),val)) ? val : 0.0);
01194 }
01195
01196
01197
01198
01199 double Translator::binError2(const ElementCIterator& binElement) const
01200 {
01201 double val = 0.0;
01202 return ((DataXML::to_value(binElement->getAttributeValue("error2"),val)) ? val : 0.0);
01203 }
01204
01205
01206
01207
01208 int Translator::binEntries(const ElementCIterator& binElement) const
01209 {
01210 int val;
01211 return ((DataXML::to_value(binElement->getAttributeValue("entries"),val)) ? val : 0);
01212 }
01213
01214
01215
01216
01217 bool Translator::consistentBin(const int& binNumberX,
01218 const HistoParameters1D& hp) const
01219 {
01220
01221 const int minBinX = 0;
01222 const int maxBinX = hp.nbX()-1;
01223 bool xok = binNumberX == constant_UNDERFLOW
01224 || binNumberX == constant_OVERFLOW
01225 || (binNumberX >= minBinX && binNumberX <= maxBinX);
01226 return (xok);
01227 }
01228
01229
01230
01231
01232 bool Translator::consistentBin(const int& binNumberX,
01233 const int& binNumberY,
01234 const HistoParameters2D& hp) const
01235 {
01236
01237 const int minBinX = 0, minBinY = 0;
01238 const int maxBinX = hp.nbX()-1, maxBinY = hp.nbY()-1;
01239 bool xok = binNumberX == constant_UNDERFLOW
01240 || binNumberX == constant_OVERFLOW
01241 || (binNumberX >= minBinX && binNumberX <= maxBinX);
01242 bool yok = binNumberY == constant_UNDERFLOW
01243 || binNumberY == constant_OVERFLOW
01244 || (binNumberY >= minBinY && binNumberY <= maxBinY);
01245 return (xok && yok);
01246 }
01247
01248
01249
01250
01251 bool Translator::consistentBin(const int& binNumberX,
01252 const int& binNumberY,
01253 const int& binNumberZ,
01254 const HistoParameters3D& hp) const
01255 {
01256
01257 const int minBinX = 0, minBinY = 0, minBinZ = 0;
01258 const int maxBinX = hp.nbX()-1, maxBinY = hp.nbY()-1, maxBinZ = hp.nbZ()-1;
01259 bool xok = binNumberX == constant_UNDERFLOW
01260 || binNumberX == constant_OVERFLOW
01261 || (binNumberX >= minBinX && binNumberX <= maxBinX);
01262 bool yok = binNumberY == constant_UNDERFLOW
01263 || binNumberY == constant_OVERFLOW
01264 || (binNumberY >= minBinY && binNumberY <= maxBinY);
01265 bool zok = binNumberZ == constant_UNDERFLOW
01266 || binNumberZ == constant_OVERFLOW
01267 || (binNumberZ >= minBinZ && binNumberZ <= maxBinZ);
01268 return (xok && yok && zok);
01269 }
01270
01271
01272
01273
01274 int Translator::stringToInt(const AIDA_STD::string& c) const
01275 {
01276 int ans = 0;
01277 if (c.length() < 1) return false;
01278 AIDA_STD::string s = c;
01279 for (unsigned int i = 0; i < s.length(); ++i) {
01280 if (s[i] == '0') s.erase(0,1);
01281 else break;
01282 }
01283 if (s.length() < 1) return false;
01284 for (unsigned int i = 0; i < s.length(); ++i) {
01285 if (!isdigit(s[i])) return false;
01286 }
01287 ans = atoi(s.c_str());
01288 return (ans > 0) ? ans : RUBBISH;
01289 }
01290
01291
01292
01293
01294 bool Translator::goodParameters(const HistoParameters1D& p) const
01295 {
01296
01297 int nb = p.nbX();
01298 int sov = p.edgesX().size();
01299 bool goodFixed = nb > 0 && sov == 0 && p.lowX() < p.highX();
01300 bool goodVar = nb > 0 && nb == sov-1 &&
01301 p.edgesX()[0] == p.lowX() && p.edgesX()[sov-1] == p.highX();
01302 return (goodFixed || goodVar);
01303 }
01304
01305
01306
01307
01308 bool Translator::goodParameters(const HistoParameters2D& p) const
01309 {
01310
01311 bool goodX = p.nbX() > 0 && p.lowX() < p.highX();
01312 bool goodY = p.nbY() > 0 && p.lowY() < p.highY();
01313 return (goodX && goodY);
01314 }
01315
01316
01317
01318
01319 bool Translator::goodParameters(const HistoParameters3D& p) const
01320 {
01321
01322 bool goodX = p.nbX() > 0 && p.lowX() < p.highX();
01323 bool goodY = p.nbY() > 0 && p.lowY() < p.highY();
01324 bool goodZ = p.nbZ() > 0 && p.lowZ() < p.highZ();
01325 return (goodX && goodY && goodZ);
01326 }
01327
01328
01329
01330
01331 void Translator::resizeMatrix(HistoParameters::VecData& vec,
01332 const int& xdim) const
01333 {
01334 vec.clear();
01335 vec.resize(xdim);
01336 }
01337
01338
01339
01340
01341 void Translator::resizeMatrix(HistoParameters::VecVecData& vec,
01342 const int& xdim, const int& ydim) const
01343 {
01344 vec.clear();
01345 vec.resize(xdim);
01346 for (int i = 0; i < xdim; ++i) {
01347 vec[i].resize(ydim);
01348 }
01349 }
01350
01351
01352
01353
01354 void Translator::resizeMatrix(HistoParameters::VecVecVecData& vec,
01355 const int& xdim, const int& ydim, const int& zdim) const
01356 {
01357 vec.clear();
01358 vec.resize(xdim);
01359 for (int i = 0; i < xdim; ++i) {
01360 vec[i].resize(ydim);
01361 for (int j = 0; j < ydim; ++j) {
01362 (vec[i])[j].resize(zdim);
01363 }
01364 }
01365 }
01366
01367
01368
01369
01370 void Translator::badInputStreamError(void) const
01371 {
01372 errorMessage("malformed or unreadable XML input stream!");
01373 }
01374
01375
01376
01377
01378 void Translator::wrongDocTypeError(void) const
01379 {
01380 errorMessage("input stream is not AIDA standard XML");
01381 }
01382
01383
01384
01385
01386 void Translator::missingElementError(const AIDA_STD::string& elementName) const
01387 {
01388 errorMessage("no \"" + elementName + "\" element found in input");
01389 }
01390
01391
01392
01393
01394 void Translator::nonsenseBinError(void) const
01395 {
01396 errorMessage("bin index inconsistent with histo parameters");
01397 }
01398
01399
01400
01401
01402 void Translator::badNBError(void) const
01403 {
01404 errorMessage("incorrect number of bins found in data element");
01405 }
01406
01407
01408
01409
01410 void Translator::noOutputStreamError(void) const
01411 {
01412 errorMessage("output stream has not been set!");
01413 }
01414
01415
01416
01417
01418 void Translator::errorMessage(const AIDA_STD::string& msg) const
01419 {
01420 if (!silent) AIDA_STD::cerr << "AidaXML::Translator ERROR: " << msg << AIDA_STD::endl;
01421 }
01422
01423
01424
01425
01426 bool Translator::significantlyDifferent(const double& a, const double& b) const
01427 {
01428
01429
01430 const double minus = -1.0;
01431 const double zero = 0.0;
01432 const double absa = (a >= zero ? a : minus*a);
01433 const double absb = (b >= zero ? b : minus*b);
01434 const double magnitude = (absa > absb ? absa : absb);
01435 const double difference = (absa > absb ? absa - absb : absb - absa);
01436 const double delta = difference * magnitude;
01437 return (delta > ROUNDOFF_TOLERANCE);
01438 }
01439
01440
01441
01442
01443 }