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

Last change on this file since 3135 was 3135, checked in by cmv, 19 years ago

suite du display des HistoErr avec Wrapper cmv 12/01/07

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