Anaphe Home Page Reference Documentation

Main Page     Namespaces     Classes     Source Code    

AIDAPlotter.cpp

Go to the documentation of this file.
00001 // 
00002 // Copyright (C) CERN, Geneva 
00003 // 
00004 // implementation file for class AIDAPlotter 
00005 // 
00006 // Created by: Andreas Pfeiffer
00007 // 
00008 // Last update: 
00009 // 
00010 
00011 #include <stdlib.h>
00012 #include <math.h>
00013 
00014 #ifndef INCLUDED_AIDAPLOTTER_H
00015 #include "AIDA_Plotter/AIDAPlotter.h"
00016 #endif
00017 
00018 #include "Interfaces/IScatter2D.h"
00019 #include "Interfaces/IVector.h"
00020 #include "Interfaces/IAnnotation.h"
00021 
00022 #include "Qplotter/viewer/viewerFactory.h"
00023 #include <algorithm>
00024 
00025 using Anaphe::AIDAPlotter;
00026 
00027 AIDAPlotter::AIDAPlotter(int nX, int nY) : myViewer(0), myPage(0), myZone(0), whichZone(0)
00028 {
00029   init(nX, nY);
00030 }
00031 
00032 AIDAPlotter::~AIDAPlotter()
00033 {
00034   delete myViewer;
00035 }
00036 
00037 void AIDAPlotter::init(int nX, int nY)
00038 {
00039   if (myViewer == 0) myViewer  = ViewerFactory::Viewer();
00040   nZonesX   = nX;
00041   nZonesY   = nY;
00042   myPage    = myViewer->createPage(nZonesX, nZonesY);
00043   whichZone = -1;
00044 
00045 }
00046 
00047 void AIDAPlotter::reset()
00048 {
00049   zoneOption("","");
00050   resetMinMax();
00051   dataOption("","");
00052   dataStyle();
00053   textStyle();
00054   xAxisOption("","");
00055   yAxisOption("","");
00056 }
00057 
00058 void AIDAPlotter::refresh()
00059 {
00060   if (myViewer == 0) return;
00061   
00062   myViewer->draw();
00063   myViewer->draw();
00064 }
00065 
00066 
00067 void  AIDAPlotter::pageTitle(const char *title) {
00068   IText *pText = myPage->setTitle(title); 
00069   // Apply text properties to the page title
00070   applyTextProperties(pText->getStyle());
00071   myViewer->draw();
00072 }
00073 
00074 void  AIDAPlotter::zoneTitle(const char *title, int selZone) {
00075   selZone -= 1;                 // the user counts from 1 ...
00076   if (selZone < 0 || selZone >= nZonesX*nZonesY) return;
00077   IText *zText = myPage->selectZone(selZone)->setTitle(title);
00078   // Apply text properties to the zone title
00079   applyTextProperties(zText->getStyle());
00080   myViewer->draw();
00081 }
00082 
00083 void AIDAPlotter::applyTextProperties(ITextStyle *itx) {
00084   typedef std::multimap<std::string,std::string>::iterator MI;
00085   MI mItr;
00086   for (mItr = textStyles.begin(); mItr != textStyles.end(); mItr++ ) {
00087     itx->setProperty(mItr->first.c_str(), mItr->second.c_str());
00088   }
00089 }
00090 
00091 void  AIDAPlotter::pageText(double xC, double yC, const char *text) {
00092   IText *pText = myPage->addText(xC,yC,text); 
00093   // Apply text properties to the page 
00094   applyTextProperties(pText->getStyle());
00095   myViewer->draw();
00096 }
00097 
00098 void  AIDAPlotter::zoneText(double xC, double yC, const char *text, int selZone) {
00099   selZone -= 1;                 // the user counts from 1 ...
00100   if (selZone < 0 || selZone >= nZonesX*nZonesY) return;
00101   IText *zText = myPage->selectZone(selZone)->addText(xC,yC,text);
00102   // Apply text properties to the zone 
00103   applyTextProperties(zText->getStyle());
00104   myViewer->draw();
00105 }
00106 
00107 void AIDAPlotter::psPrint(const char *file)
00108 {
00109   std::string fileName = "lizard.ps";
00110   if (file != 0) fileName = file;
00111 
00112   myViewer->makePS(const_cast<char *>(fileName.c_str()));
00113 
00114   // use env. var PRINT_CMD (from HepIX ?) instead of "hardwired" xprint 
00115   if (file == 0) system("/usr/local/bin/xprint lizard.ps");
00116 }
00117 
00118 void AIDAPlotter::makePicture(const char *file)
00119 {
00120   myViewer->makePicture(file);
00121 }
00122  
00123 void AIDAPlotter::resetZones(int nx, int ny) {
00124   myViewer->clear();
00125   init(nx, ny);
00126 }
00127 
00128 void AIDAPlotter::createRegion(double x, double y, double w, double h)
00129 { 
00130   myPage->createIrregularZone(x,y,w,h);
00131 }
00132 
00133 void AIDAPlotter::zone(int nx, int ny, int iSel, const char *opt) 
00134 { 
00135   resetZones(nx,ny);
00136   iSel -= 1;                    // the user counts from 1 ...
00137   if (iSel < 0)  
00138     whichZone = -1; 
00139   else 
00140     whichZone = ( iSel % (nZonesX*nZonesY) ) - 1; 
00141   
00142   xMinMax.clear();
00143   yMinMax.clear();
00144 }
00145 
00146 void AIDAPlotter::setMinMaxX(double xMin, double xMax, int selZone)
00147 {
00148   selZone -= 1;                 // the user counts from 1 ...
00149   if (selZone < 0 || selZone >= nZonesX*nZonesY) {
00150     std::cerr << "illegal zone for setMinMaxX : " << selZone << std::endl;
00151     return;
00152   }
00153 
00154 //  std::cerr << "storing zone " << whichZone 
00155 //       << " xmin = " << xMin
00156 //       << " xmax = " << xMax
00157 //       << std::endl;
00158   std::pair <double, double> minMax(xMin, xMax);
00159   xMinMax[selZone] = minMax;
00160 }
00161 
00162 void AIDAPlotter::setMinMaxY(double yMin, double yMax, int selZone)
00163 {
00164   selZone -= 1;                 // the user counts from 1 ...
00165   if (selZone < 0 || selZone >= nZonesX*nZonesY) return;
00166 
00167 //  std::cerr << "storing zone " << whichZone 
00168 //       << " ymin = " << yMin
00169 //       << " ymax = " << yMax
00170 //       << std::endl;
00171   std::pair <double, double> minMax(yMin, yMax);
00172   yMinMax[selZone] = minMax;
00173 }
00174 
00175 void AIDAPlotter::resetMinMax()
00176 {
00177   xMinMax.clear();
00178   yMinMax.clear();
00179 }
00180 
00181 void AIDAPlotter::textStyle(const char *opt, const  char *val) 
00182 {
00183   if (opt == 0 && val == 0) {   // reset all
00184     textStyles.clear();
00185     return;
00186   }
00187 
00188   if (val == 0 || (strlen(val) == 0)) {         // reset one property 
00189     textStyles.erase(opt);
00190     return;
00191   }
00192 
00193   std::pair<const std::string, std::string> option(opt, val);
00194   textStyles.erase(opt);
00195   textStyles.insert( option );
00196 }
00197 
00198 void AIDAPlotter::dataStyle(const char *opt, const  char *val) 
00199 {
00200   if (opt == 0 && val == 0) {   // reset all
00201     dataStyles.clear();
00202     return;
00203   }
00204 
00205   if (val == 0 || (strlen(val) == 0)) {         // reset one property 
00206     dataStyles.erase(opt);
00207     return;
00208   }
00209 
00210   std::pair<const std::string, std::string> option(opt, val);
00211   dataStyles.erase(opt);
00212   dataStyles.insert( option );
00213 }
00214 
00215 void AIDAPlotter::dataOption(const char *opt, const  char *val) 
00216 {
00217   handleOption(dataProperties, opt, val);
00218 }
00219 
00220 void AIDAPlotter::zoneOption(const char *opt, const  char *val) 
00221 {
00222   handleOption(zoneProperties, opt, val);
00223 }
00224 
00225 void AIDAPlotter::xAxisOption(const char *opt, const  char *val) 
00226 {
00227   handleOption(xAxisProperties, opt, val);
00228 }
00229 
00230 void AIDAPlotter::yAxisOption(const char *opt, const  char *val) 
00231 {
00232   handleOption(yAxisProperties, opt, val);
00233 }
00234 
00235 void AIDAPlotter::handleOption(Property_t &pList, const char *opt, const  char *val) 
00236 {
00237 
00238   if ( (opt == 0 && val == 0) ||
00239        (std::string(opt) == "" && ( val != 0 && std::string(val) == "" ) ) ) {  // reset all
00240     pList.clear();
00241     return;
00242   }
00243 
00244   // All options become lowercase
00245   std::string name(opt);
00246 #ifdef __sun
00247   std::string::iterator itr = name.begin();
00248   while (itr != name.end()) {
00249     *itr = tolower(*itr);
00250     itr++;
00251   }
00252 #else
00253   std::transform(name.begin(),name.end(),name.begin(), tolower);  
00254 #endif
00255 
00256   if (val == 0 || std::string(val) == "") {    // reset one property 
00257     pList.erase(name);
00258     return;
00259   }
00260 
00261   std::pair<const std::string, std::string> option(name, val);
00262   // If the property already exists, remove it first
00263   if ((name != "option") && (pList.find(name )!= pList.end()))
00264     pList.erase(name);
00265   pList.insert( option );
00266 
00267 }
00268 
00269 
00270 void AIDAPlotter::listOptions(std::ostream& os)
00271 {
00272   os << "\nOptions for Zones" << std::endl;
00273   myPage->selectZone(whichZone)->listOptions(os); //-ap should become: (os)
00274 
00275   os << "\nOptions for Datasets (curves)" << std::endl;
00276   IDataset *ds = myPage->selectZone(whichZone)->getDataset(0);
00277   if (ds != 0) {
00278     ds->listOptions(os);              //-ap should become: (os)
00279   } else
00280     os << "\nNo Dataset available" << std::endl;
00281   
00282   os << "\nDraw style options" << std::endl;
00283   myPage->selectZone(whichZone)->getDrawStyle()->listOptions(os);
00284 
00285   os << "\nText style options" << std::endl;
00286   myPage->selectZone(whichZone)->getTextStyle()->listOptions(os);
00287 
00288 }
00289 
00290 void AIDAPlotter::setAxisProperty(IZone *z, Anaphe::IVector *v1, const std::string ax, const std::string prop, Property_t &pList) 
00291 {
00292   // check for and add title from histogram if existing and not yet set ...
00293 
00294   if ( (pList.find(prop) != pList.end()) &&  // title has been set explicitely ...
00295        (pList.find(prop)->second != "") ) {    // ... and is non-empty 
00296     z->getAxis( ax )->setProperty(prop, pList.find(prop)->second);
00297       
00298   } else {                      // property not yet set, check if it's in the annotation
00299     // either {"xaxistitle","yaxistitle"}
00300     std::string what = ax + "axis" + prop; 
00301     if (v1->annotation() != 0) {
00302       for (int index=0; index < v1->annotation()->size(); index++) {
00303         // Transform annotation key to lowercase
00304         std::string lowerKey(v1->annotation()->key(index));
00305         std::transform(lowerKey.begin(),lowerKey.end(),lowerKey.begin(),tolower);  
00306         if ( (what == lowerKey) &&  (v1->annotation()->value(index).size() != 0 )) { // there it is ...
00307           z->getAxis( ax )->setProperty(prop, v1->annotation()->value(index));
00308         }
00309       }
00310     }
00311   }
00312 }
00313 
00314 void AIDAPlotter::plot(Anaphe::IScatter2D *scat) {
00315   if (scat == 0) return;                // nothing to plot
00316 
00317   // clear page if changeover to new page
00318   if (whichZone == 0) {
00319     resetZones(nZonesX, nZonesY);
00320     whichZone = 0;              // reset zone number
00321   } 
00322 
00323   // now start setting up zone ...
00324   IZone *z = myPage->selectZone(whichZone); // re-select zone ...
00325   z->addScatter(scat);
00326 
00327   myViewer->draw();
00328 
00329   whichZone++;
00330 
00331   if ( whichZone > (nZonesX*nZonesY)-1 ) { // reset info if last zone on this plot
00332     whichZone = 0;
00333   }
00334 }
00335 
00336 void AIDAPlotter::plot(Anaphe::IVector *v1, Anaphe::IVector *v2)
00337 {
00338   if (v1 == 0) return;          // nothing to plot, as v2 is 0 by default
00339 
00340   if (v1->dimension() == 0) return; // non-existing vector
00341   if (v1->nPoints  () == 0) return; // empty vector
00342 
00343   whichZone++;
00344 
00345   if ( whichZone > (nZonesX*nZonesY)-1 ) { 
00346     // reset info if last zone on this plot
00347     whichZone = 0;
00348   }
00349 
00350   // clear page if changeover to new page
00351   if (whichZone == 0) {
00352     resetZones(nZonesX, nZonesY);
00353     whichZone = 0;              // reset zone number
00354   } 
00355 
00356   // now start setting up zone ...
00357 
00358   typedef std::multimap<std::string,std::string>::iterator MI;
00359 
00360   MI mItr;
00361   IZone *z = myPage->selectZone(whichZone); // re-select zone ...
00362 
00363 
00364   IDataset *ds = z->addDataset(*v1);
00365   for (mItr = dataProperties.begin(); mItr != dataProperties.end(); mItr++ ) {
00366     ds->setProperty(mItr->first.c_str(), mItr->second.c_str());
00367   }
00368 
00369   IDrawStyle *idx = ds->getStyle();
00370   for (mItr = dataStyles.begin(); mItr != dataStyles.end(); mItr++ ) {
00371     idx->setProperty(mItr->first.c_str(), mItr->second.c_str());
00372   }
00373 
00374   // Apply text properties to the zone 
00375   ITextStyle *itx = z->getTextStyle();
00376   for (mItr = textStyles.begin(); mItr != textStyles.end(); mItr++ ) {
00377     itx->setProperty(mItr->first.c_str(), mItr->second.c_str());
00378   }
00379 
00380   for (mItr = zoneProperties.begin(); mItr != zoneProperties.end(); mItr++ ) {
00381     z->setProperty(mItr->first.c_str(), mItr->second.c_str());
00382   }
00383 
00384   setAxisProperty(z, v1, "x", "title", xAxisProperties);
00385   setAxisProperty(z, v1, "y", "title", yAxisProperties);
00386 
00387   setAxisProperty(z, v1, "x", "label", xAxisProperties);
00388   setAxisProperty(z, v1, "y", "label", yAxisProperties);
00389 
00390   // Set limits on zones
00391   if (xMinMax.find(whichZone) != xMinMax.end()) 
00392     z->xMinMax (xMinMax[whichZone].first, xMinMax[whichZone].second);
00393 
00394   if (yMinMax.find(whichZone) != yMinMax.end()) 
00395     z->yMinMax (yMinMax[whichZone].first, yMinMax[whichZone].second);
00396 
00397   myViewer->draw();
00398 
00399   if (v2 != 0) {  // prepare to superimpose second vector if existing
00400 
00401     // store line mode and colour for later reset ...
00402     MI lineMode   = dataProperties.find("Representation");
00403     std::string lm;
00404     if (lineMode != dataProperties.end()) {
00405       lm = lineMode->second;
00406     } else {
00407       lm = "histo";
00408     }
00409 
00410     MI lineColour = dataStyles.find("lineColor");
00411     std::string lc;
00412     if (lineColour != dataStyles.end()) {
00413       lc = lineColour->second;
00414     } else {
00415       lc = "black";
00416     }
00417 
00418     // set them to 'red' 'line'
00419     dataOption("Representation",0);          // erase option
00420     dataOption("Representation","Line");
00421     dataStyle ("lineColor", "red");
00422 
00423     // overlay plot to last zone ...
00424     overlay(v2);
00425 
00426     // ... and reset values
00427     dataOption("Representation",0);          // erase option
00428     dataOption("Representation", lm.c_str());
00429     dataStyle ("lineColor"     , lc.c_str());
00430 
00431   } // end if v2 != 0
00432 
00433   return;
00434 }
00435 
00436 void AIDAPlotter::overlay(Anaphe::IVector *v2, int selZone)
00437 {
00438   if (selZone == -1) {
00439     selZone = whichZone;        // use the last one ...
00440   } else {
00441     selZone -= 1;               // the user counts from 1 ...
00442     if (selZone < 0 || selZone >= nZonesX*nZonesY) return;
00443   }
00444 
00445   if (v2 == 0) return;          // nothing to plot
00446 
00447   if (v2->dimension() == 0) return; // non-existing vector
00448   if (v2->nPoints  () == 0) return; // empty vector
00449   
00450   typedef std::multimap<std::string,std::string>::iterator MI;
00451 
00452   IZone *z = myPage->selectZone(selZone); // re-select zone ...
00453 
00454   IDataset *ds = z->addDataset(*v2);
00455   for (MI mItr = dataProperties.begin(); mItr != dataProperties.end(); mItr++ ) {
00456     ds->setProperty(mItr->first.c_str(), mItr->second.c_str());
00457   }
00458   IDrawStyle *idx = ds->getStyle();
00459   for (MI mItr = dataStyles.begin(); mItr != dataStyles.end(); mItr++ ) {
00460     idx->setProperty(mItr->first.c_str(), mItr->second.c_str());
00461   }
00462 
00463   myViewer->draw();
00464 
00465   return;
00466 }
00467 
00468 void AIDAPlotter::interact()
00469 {
00470   myViewer->activateOutline();
00471   return;
00472 }
00473 
00474 
00475 
00476 Anaphe::IPlotter * createIPlotter() { return new AIDAPlotter(); }
00477 
00478 
00479 


Anaphe documentation generated by Doxygen (www.doxygen.org)