source: Sophya/trunk/SophyaPI/PIext/pihisto.cc@ 3145

Last change on this file since 3145 was 3145, checked in by ansari, 19 years ago

1/ Petites modifs ds PIHisto et le P1DHistoWrapper - en particulier decodage des options et choix renvoi BinContent/Error/NEntries
2/ Codage Wrapper pour Histo-2D et modifs PIHisto2D
3/ Suppression des adaptateurs de tableaux PI des Histos2D ds pipodrw.h .cc, les
Wrappers d'histos heritant de P1D,P2DArrayAdapter
4/ Mise a jour Makefile et smakefile

Reza , 18/01/2007

File size: 11.5 KB
RevLine 
[544]1// Classe traceur d histogramme 96-99
[3125]2// C. Magneville , R. Ansari 2000-2007
3// (C) CEA-DAPNIA LAL-IN2P3/CNRS
[544]4
[165]5#include <stdio.h>
[2517]6#include <stdlib.h>
7#include <iostream>
8#include <math.h>
[295]9#include <typeinfo>
10
[165]11#include "pihisto.h"
12
[3132]13//------ Implementation classe P1DHistoWrapper
[3145]14P1DHistoWrapper::P1DHistoWrapper(int_4 asx)
15 : P1DArrayAdapter(asx) ,
16 mScale(1.) , mOff(0.) , mRetFg(0)
[3132]17{
18}
19
20P1DHistoWrapper::~P1DHistoWrapper()
21{
22}
23
24int P1DHistoWrapper::GetStatInfoAsText(vector<string> & /* text */ )
25{
26 return 0;
27}
28
29int P1DHistoWrapper::DecodeOptionString(vector<string> & opt, bool rmdecopt)
30{
31 if(opt.size() < 1) return(0);
32
33 vector<string> udopt; // On gardera ici les options non decodees
34 unsigned int k = 0;
35 int ndec = opt.size();
36 for( k=0; k<opt.size(); k++ ) {
37 string & opts = opt[k];
38 if(opts.substr(0,7) == "hs1") {
39 mScale = 1.; mOff = 0.;
40 }
41 else if(opts.substr(0,7) == "hscale=") {
42 mScale = atof(opts.substr(7).c_str());
43 }
[3135]44 else if(opts.substr(0,8) == "hoffset=") {
[3132]45 mOff = atof(opts.substr(8).c_str());
46 }
[3145]47 else if(opts.substr(0,8) == "hbincont") {
48 mRetFg = 0;
49 }
50 else if(opts.substr(0,8) == "hbinerr") {
51 mRetFg = 1;
52 }
53 else if(opts.substr(0,8) == "hbinent") {
54 mRetFg = 2;
55 }
[3132]56 else {
57 ndec--;
58 // S'il faut supprimer les options decodees
59 if (rmdecopt) udopt.push_back(opts);
60 }
61 }
62 // S'il faut supprimer les options decodees, on remplace l'argument opt
63 // par le vecteur des options non decodees.
64 if (rmdecopt) opt = udopt;
65 return(ndec);
66}
67
[3145]68int
69P1DHistoWrapper::OptionToString(vector<string> & opt) const
70{
71 char buff[64];
72 sprintf(buff, "hscale=%g", mScale); opt.push_back(buff);
73 sprintf(buff, "hoffset=%g", mOff); opt.push_back(buff);
74 if (mRetFg == 2) opt.push_back("hbinent");
75 else if (mRetFg == 1) opt.push_back("hbinerr");
76 else opt.push_back("hbincont");
[3132]77
[3145]78 return 1;
79}
80
81
[544]82//++
83// Class PIHisto
84// Lib PIext
85// include pihisto.h
86//
[3125]87// Classe traceur d'objet histogramme (classe *P1DHistoWrapper*)
[544]88//--
89//++
90// Links Parents
91// PIDrawer
92//--
93//++
94// Titre Constructeur, méthodes
95//--
96//++
[3135]97// PIHisto(P1DHistoWrapper* histowp, bool ad=false)
98// Constructeur. Si "ad == true", l'objet "histowp" est détruit par
[544]99// le destructeur de l'objet "PIHisto"
[3145]100// Note : "histowp" doit être créé par new si ad==true
[544]101//
102//--
103
104
[3135]105PIHisto::PIHisto(P1DHistoWrapper* histowp, bool ad)
106: PIDrawer(), mHistoWp(histowp)
[165]107{
[3135]108 mAdDO = ad; // Flag pour suppression automatique de mHistoWp
109 stats=true;
[3145]110 pline=true;
111 error=false;
[3135]112 filled=false;
113 spoX=-0.01; spoY=-0.01;
[1856]114 SetName("HistoDrw");
[165]115}
116
117PIHisto::~PIHisto()
118{
[3135]119 if(mAdDO) delete mHistoWp;
[165]120}
121
122void
123PIHisto::UpdateLimits()
124{
[3135]125 if (!mHistoWp) return;
[3145]126 if ( mHistoWp->NBins() < 1 ) {
127 SetLimits(mHistoWp->XMin(), mHistoWp->XMax(), 0., 1.);
128 }
[3135]129 double v,hmin,hmax;
[3145]130 hmin = hmax = (*mHistoWp)(0);
131 for (int_4 i=1; i<mHistoWp->NBins(); i++) {
132 v = (*mHistoWp)(i);
[3135]133 if(v<hmin) hmin = v;
134 if(v>hmax) hmax = v;
[165]135 }
[3145]136 if ( isLogScaleY() ) {
137 if ( hmin >= 0.) {
138 if ( hmax <= hmin ) {
139 hmax = hmin*10.;
140 if (hmax <= 0.) hmax = 1.;
141 if (hmin <= 0.) hmin = hmax / 100.;
142 }
143 else if ( (hmin == 0.) && (hmax > hmin) ) hmin = hmax/1.e6;
144 else hmin /= 1.1;
145 }
146 else if (hmax > 0.) hmax *= 1.1;
147 }
148 else {
149 v = 0.05*(hmax-hmin);
150 hmin -= v; hmax += v;
151 }
[2229]152 if(hmax<=hmin) hmax = hmin+1.;
[3145]153
[3135]154 SetLimits(mHistoWp->XMin(), mHistoWp->XMax(), hmin, hmax);
[165]155}
156
157void
[205]158PIHisto::Draw(PIGraphicUC* g, double /*xmin*/, double /*ymin*/, double /*xmax*/, double /*ymax*/)
[165]159{
[548]160 if (axesFlags != kAxesNone) DrawAxes(g);
161
[3135]162 if (!mHistoWp) return;
163 if (mHistoWp->NBins()<=0) return;
[2229]164
[3135]165 mHistoWp->Update();
[203]166
[2517]167 // Tracer d'une polyline si demandee
168 bool drawpline=false;
[3145]169 if (pline) drawpline=true;
[2469]170 // Tracer des marqueurs si demande ou si HProf
171 bool drawmarker=false;
[3125]172 if (GetGraphicAtt().GetMarker() != PI_NotDefMarker) drawmarker = true;
[2469]173 // Tracer des erreurs ?
174 bool drawerr=false;
[3145]175 if (error) drawerr = true;
[2517]176 // Fill de l'histo ?
177 bool drawfill=false;
178 if(filled) drawfill=true; else drawfill=false;
[3145]179 // Et aussi si on ne demande ni ligne ni marqueur ni erreur ni fill ?
180 if( !drawmarker && !drawfill && !drawerr ) drawpline=true;
[2229]181
[2517]182 // Remplissage des bins avec la couleur courante (trace en premier)
183 if(drawfill) {
[3135]184 for(int i=0; i<mHistoWp->NBins(); i++) {
185 double left = mHistoWp->BinLowEdge(i);
186 double width = mHistoWp->BinWidth();
[2517]187 double bottom = 0;
[3145]188 double height = (*mHistoWp)(i);
[2517]189 g->DrawFBox(left,bottom,width,height);
190 }
191 }
192
[2229]193 // Trace des marqeurs
194 if(drawmarker) {
[3145]195 double x1,y1;
[3135]196 for(int i=0; i<mHistoWp->NBins(); i++) {
197 x1 = mHistoWp->BinCenter(i);
[3145]198 y1 = (*mHistoWp)(i);
[2229]199 g->DrawMarker(x1,y1);
200 }
201 }
202
203 // Trace des erreurs
204 if(drawerr) {
205 if(GetGraphicAtt().GetLineAtt()==PI_NotDefLineAtt) g->SelLine(PI_ThinLine);
[3145]206 double x1,x2,y1,y2;
[3135]207 double bw = mHistoWp->BinWidth();
208 for(int i=0; i<mHistoWp->NBins(); i++) {
209 if(mHistoWp->Error(i)>0.) {
[165]210 // barres d'erreur verticales
[3135]211 x1 = x2 = mHistoWp->BinCenter(i);
[3145]212 y1 = (*mHistoWp)(i) - mHistoWp->Error(i);
213 y2 = (*mHistoWp)(i) + mHistoWp->Error(i);
[165]214 g->DrawLine(x1,y1, x1, y2);
215 // limites de barres d'erreurs (horizontales)
216 x1 -= bw/3.; x2 += bw/3.;
217 g->DrawLine(x1,y1, x2, y1);
218 g->DrawLine(x1,y2, x2, y2);
219 }
220 }
221 }
[2229]222
[2517]223 // Trace de la ligne continue si demandee
224 if(drawpline) {
[3145]225 if(GetGraphicAtt().GetLineAtt()==PI_NotDefLineAtt) g->SelLine(PI_ThinLine);
[3135]226 PIGrCoord* x1 = new PIGrCoord[2*mHistoWp->NBins()+2];
227 PIGrCoord* y1 = new PIGrCoord[2*mHistoWp->NBins()+2];
228 double dx = mHistoWp->BinWidth();
[2469]229 int npt=0;
[3135]230 x1[npt] = mHistoWp->BinLowEdge(0);
[2469]231 y1[npt] = 0;
232 npt++;
[3135]233 for(int i=0; i<mHistoWp->NBins(); i++) {
234 x1[npt] = mHistoWp->BinLowEdge(i);
[3145]235 y1[npt] = (*mHistoWp)(i);
[2469]236 npt++;
237 x1[npt] = (double)x1[npt-1] + dx;
238 y1[npt] = y1[npt-1];
239 npt++;
[165]240 }
[2469]241 x1[npt] = x1[npt-1];
242 y1[npt] = 0;
243 npt++;
[2517]244 g->DrawPolygon(x1,y1,npt,false);
245 delete [] x1; delete [] y1;
[165]246 }
[2229]247
248 // Trace/Ecriture des statistiques
[203]249 // A faire a la fin - DrawStats change l'attribut de ligne
[1057]250 if(stats) DrawStats(g);
[165]251}
252
[1971]253int
254PIHisto::DecodeOptionString(vector<string> & opt, bool rmdecopt)
255{
[2229]256 int optsz1 = opt.size();
257 if(optsz1<1) return(0);
[1971]258 int ndec1 = PIDrawer::DecodeOptionString(opt, rmdecopt);
[2229]259 if(optsz1-ndec1<1) return(ndec1); // si tout a ete decode
[1971]260
261 vector<string> udopt; // On gardera ici les options non decodees
262 unsigned int k = 0;
263 int ndec = opt.size();
264 for( k=0; k<opt.size(); k++ ) {
265 string opts = opt[k];
[3135]266 if(opts=="sta" || opts=="stat" || opts=="stats") stats=true;
[2229]267 else if( opts=="nsta" || opts=="nstat"
[3135]268 || opts=="nostat" || opts=="nostats") stats=false;
[3145]269 else if(opts=="err") error=true;
270 else if(opts=="noerr" || opts=="nerr") error=false;
271 // $CHECK$CMV : on desactive pline si fill ?
272 else if(opts=="fill") { filled=true; pline=false; }
[3135]273 else if(opts=="nofill" || opts=="nfill") filled=false;
[3145]274 // $CHECK$CMV : on desactive fill si pline ?
275 else if(opts=="pline") { pline=true; filled=false; }
276 else if(opts=="nopline") pline=false;
[2383]277 else if(opts.substr(0,11) == "statposoff=") {
278 float xo=0., yo=0.;
279 sscanf(opts.substr(11).c_str(),"%g,%g",&xo, &yo);
[3135]280 spoX=xo; spoY=yo;
[2383]281 }
[1971]282 else {
283 ndec--;
284 // S'il faut supprimer les options decodees
285 if (rmdecopt) udopt.push_back(opts);
286 }
[2229]287 }
[3132]288
[1971]289 // S'il faut supprimer les options decodees, on remplace l'argument opt
290 // par le vecteur des options non decodees.
291 if (rmdecopt) opt = udopt;
[3132]292
293 // Decodage des options par le histo-wrapper
294 int ndec2 = 0;
[3135]295 if ( ( optsz1-ndec1-ndec > 0) && (mHistoWp) ) {
296 ndec2 = mHistoWp->DecodeOptionString(opt, rmdecopt);
[3132]297 }
298 return(ndec+ndec1+ndec2);
[1971]299}
300
[2523]301int
302PIHisto::OptionToString(vector<string> & opt) const
303{
304 PIDrawer::OptionToString(opt);
305
[3145]306 if(stats) opt.push_back("stat"); else opt.push_back("nostat");
307 if(error) opt.push_back("err"); else opt.push_back("noerr");
[2523]308 if(filled) opt.push_back("fill"); else opt.push_back("nofill");
[3145]309 if(pline) opt.push_back("pline"); else opt.push_back("nopline");
[2523]310
311 char str[256]; sprintf(str,"statposoff=%g,%g",spoX,spoY);
312 opt.push_back(str);
313
[3145]314 mHistoWp->OptionToString(opt);
[2523]315 return 1;
316}
317
[165]318void
[2229]319PIHisto::GetOptionsHelpInfo(string& info)
320{
321info += " ---- PIHisto options help info : \n" ;
[3145]322info += " sta,stat,stats: activate statistic display\n";
323info += " nsta,nstat,nostat,nostats: deactivate statistic display\n";
324info += " pline/nopline: display/do not display as polyline (def= pline) \n";
325info += " err/noerr,nerr: draw/do not draw error bars (def= noerr) \n";
326info += " fill/nofill,nfill: fill/do not fill histo (def= nofill) \n";
327info += " - Use marker attribute (marker=...) to draw markers \n";
328info += " statposoff=OffsetX,OffsetY : Position offset for Stats drawing \n";
329info += " as a fraction of total size \n";
[3132]330info += " ---- HistoWrapper options : \n" ;
[3145]331info += " hbincont: select bin content as Y value for display (default) \n";
332info += " hbinerr: select bin error as Y value for display \n";
333info += " hbinent: select bin entries as Y value for display \n";
334info += " hscale=value : multiplicative factor for Y value \n" ;
335info += " hoffset=value : additive coefficient for Y value \n" ;
336info += " hs1: set hscale=1 hoffset=0 (default) \n" ;
[2388]337// On recupere ensuite la chaine info de la classe de base
338PIDrawer::GetOptionsHelpInfo(info);
[2229]339return;
340}
341
342void
[165]343PIHisto::DrawStats(PIGraphicUC* g)
344{
[3135]345 if (!mHistoWp) return;
[203]346 // if (mLAtt == PI_NotDefLineAtt) g->SelLine(PI_ThinLine);
347 g->SelLine(PI_ThinLine);
[1905]348 g->SelFontSz((YMax() - YMin())/30);
[1644]349
350 // La hauteur de la cellule
[544]351 PIGrCoord a, d;
352 double cH = (double)g->GetFontHeight(a,d);
[3125]353 vector<string> lines;
[3135]354 int nlig = mHistoWp->GetStatInfoAsText(lines);
[3125]355 if (nlig < 1) return;
[1644]356
[3145]357 double cellHeight = nlig*1.2 * cH;
[1644]358
[3125]359 int idxll = 0;
360
361 int kl;
362 // on recherche la ligne la plus longue
363 for(kl=1; kl<nlig; kl++)
364 if ( lines[kl].length() > lines[idxll].length() ) idxll = kl;
365
366 double cellWidth = 1.1 * (double)g->CalcStringWidth(lines[idxll].c_str());
367
[2383]368 double ofpx = spoX*(XMax()-XMin());
369 double ofpy = spoY*(YMax()-YMin());
370
[1645]371 double xu, yu, cw;
[1644]372 // Les limites du cadre
[1645]373 xu = g->DeltaUCX(XMax(), -cellWidth);
374 yu = g->DeltaUCY(YMax(), -cellHeight);
[2383]375 double recw = XMax()-xu;
376 double rech = YMax()-yu;
377 xu += ofpx; yu += ofpy;
378 g->DrawBox(xu, yu, recw, rech);
[1644]379
[1645]380 // L'ecriture des labels (attention aux inversions possibles des axes!)
381 cw = (g->isAxeXDirRtoL()) ? -0.05*cellWidth : -0.95*cellWidth;
382 xu = g->DeltaUCX(XMax(),cw);
383
384 cw = (g->isAxeYDirUpDown()) ? -0.15*cH : -1.15*cH;
385 yu = g->DeltaUCY(YMax(),cw);
[2383]386 xu += ofpx; yu += ofpy;
[3125]387
388 for(kl=0; kl<nlig; kl++) {
389 g->DrawString(xu, yu, lines[kl].c_str() );
390 cw += -1.15*cH;
391 yu = g->DeltaUCY(YMax(),cw); yu += ofpy;
392 }
[165]393
394}
[2517]395
396/* --Methode-- */
[3135]397double
398PIHisto::GetDistanceToPoint(double x, double y)
[2517]399{
[3135]400 if (!mHistoWp) return 1.e+9;
[2517]401
402 double dist = -1.e+18;
[3135]403 for(int i=0; i<mHistoWp->NBins(); i++) {
404 double xp=mHistoWp->BinCenter(i);
[3145]405 double yp=(*mHistoWp)(i);
[2517]406 xp = (xp-x)/(XMax()-XMin())/0.5;
407 yp = (yp-y)/(YMax()-YMin())/0.5;
408 xp = xp*xp+yp*yp;
409 if(dist<0. || xp<dist) dist = xp;
410 }
411 dist=sqrt(fabs(dist));
412 //cout<<dist<<"PIHisto: xlim="<<XMin()<<","<<XMax()<<" ylim="<<YMin()<<","<<YMax()
[3135]413 // <<" NBins="<<mHistoWp->NBins()<<endl;
[2517]414 //cout<<"....d="<<dist<<" x="<<x<<" y="<<y<<endl;
415
416 return dist;
417}
Note: See TracBrowser for help on using the repository browser.