source: Sophya/trunk/SophyaPI/PIext/pihisto2d.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: 33.7 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <pisysdep.h>
4#include PIAPP_H
5
6#include <iostream>
7#include <math.h>
8
9#include "sopnamsp.h"
10#include "pihisto2d.h"
11#include "srandgen.h"
12
13static int dbg = 0;
14
15
16//------ Implementation classe P2DHistoWrapper
17P2DHistoWrapper::P2DHistoWrapper(int_4 asx, int_4 asy)
18 : P2DArrayAdapter(asx, asy) ,
19 mScale(1.) , mOff(0.) , mRetFg(0)
20{
21}
22
23P2DHistoWrapper::~P2DHistoWrapper()
24{
25}
26
27int P2DHistoWrapper::GetStatInfoAsText(vector<string> & /* text */ )
28{
29 return 0;
30}
31
32int P2DHistoWrapper::DecodeOptionString(vector<string> & opt, bool rmdecopt)
33{
34 if(opt.size() < 1) return(0);
35
36 vector<string> udopt; // On gardera ici les options non decodees
37 unsigned int k = 0;
38 int ndec = opt.size();
39 for( k=0; k<opt.size(); k++ ) {
40 string & opts = opt[k];
41 if(opts.substr(0,7) == "hs1") {
42 mScale = 1.; mOff = 0.;
43 }
44 else if(opts.substr(0,7) == "hscale=") {
45 mScale = atof(opts.substr(7).c_str());
46 }
47 else if(opts.substr(0,8) == "hoffset=") {
48 mOff = atof(opts.substr(8).c_str());
49 }
50 else if(opts.substr(0,8) == "hbincont") {
51 mRetFg = 0;
52 }
53 else if(opts.substr(0,8) == "hbinerr") {
54 mRetFg = 1;
55 }
56 else if(opts.substr(0,8) == "hbinent") {
57 mRetFg = 2;
58 }
59 else {
60 ndec--;
61 // S'il faut supprimer les options decodees
62 if (rmdecopt) udopt.push_back(opts);
63 }
64 }
65 // S'il faut supprimer les options decodees, on remplace l'argument opt
66 // par le vecteur des options non decodees.
67 if (rmdecopt) opt = udopt;
68 return(ndec);
69}
70
71int
72P2DHistoWrapper::OptionToString(vector<string> & opt) const
73{
74 char buff[64];
75 sprintf(buff, "hscale=%g", mScale); opt.push_back(buff);
76 sprintf(buff, "hoffset=%g", mOff); opt.push_back(buff);
77 if (mRetFg == 2) opt.push_back("hbinent");
78 else if (mRetFg == 1) opt.push_back("hbinerr");
79 else opt.push_back("hbincont");
80
81 return 1;
82}
83
84//++
85// Class PIHisto2D
86// Lib PIext
87// include pihisto2d.h
88//
89// Classes de dessin des histogrammes a 2 dimensions pour
90// objets *Histo2D*
91//--
92
93//++
94// Links Parents
95// PIDrawer
96//--
97
98//++
99// Titre Constructeur, méthodes
100//--
101
102//++
103PIHisto2D::PIHisto2D(P2DHistoWrapper* histowp, bool ad)
104//
105// Createur d'une classe de dessin pour l'histogramme 2D histo.
106//--
107: PIDrawer(), mHistoWp(histowp), mAdDO(ad), mLogScale(10.), mFPoints(0.5)
108{
109// mAdDO : Flag pour suppression automatique de mHistoWp
110// Attention: mFPoints n'est initialise que si on display par nuages de points
111// mLogScale n'est initialise que si on utilise une echelle log
112UseScale();
113UseColors();
114UseDisplay();
115UseDyn();
116UseFrac();
117SetStats();
118SetStatPosOffset();
119SetName("Histo2DDrw");
120// PIHisto2D has specific control tools
121mFgSpecContWind = true;
122}
123
124//++
125PIHisto2D::~PIHisto2D()
126//
127// Destructeur.
128//--
129{
130// La fonction virtuelle DeactivateControlWindow() doit etre appele
131// a ce niveau - En effet au niveau du destructeur de base, il
132// semble pointer sur la fonction de la classe de base
133// Reza - Octobre 2002
134// Desactivation totale de la fenetre de controle specialise
135// ---> parametre d'appel PIBaseWdgGen* wdg=NULL
136DeactivateControlWindow(NULL);
137if(mAdDO && mHistoWp!=NULL) delete mHistoWp;
138}
139
140//++
141void PIHisto2D::UseColors(bool fg,CMapId cmap,bool revcmap)
142//
143// Choix de la couleur si fg=true avec la color map cmap.
144// (pour la couleur cmap cf picmap.h).
145// Independamment du choix du display, la dynamique est
146// codee sur la color map donnant ainsi une double
147// information. Par exemple, carres de tailles variables
148// en couleur. Cette option est incontournable dans le cas
149// d'un display par des carres de taille fixe.
150// revcmap doit etre mis a "true" si on veut avoir une color map
151// inversee.
152//| -**- gestion dans H2WinArg par menu deroulant Black&White etc...
153//--
154{
155mFgCol = fg; mCmap = cmap; mRevCmap = revcmap;
156}
157
158//++
159void PIHisto2D::UseScale(unsigned short type,float logscale)
160//
161// Pour changer les echelles (lineaire ou logarithmique)
162//| Type = 0 : echelle lineaire
163//| = 1 : echelle log10
164//| -**- Explication du codage en type=0 (lineaire) :
165//| 1. [hmin,hmax] -> [0,1]
166//| h -> f = (h-hmin)/(hmax-hmin)
167//| 2. codage de f=[0,1] sur la dynamique du display choisi
168//| -**- Explication du codage en type=1 (logarithmique base 10) :
169//| 1. map lineaire entre 0 et 1:
170//| [hmin,hmax] -> [0,1]
171//| h -> f = (h-hmin)/(hmax-hmin)
172//| 2. transformation logarithmique de base 10 :
173//| [0,1] -> [0,1]
174//| f -> lf = log10(1.+f*(logscale-1))/log10(logscale)
175//| 3. codage de lf=[0,1] sur la dynamique du display choisi
176//| -**- gestion dans H2WinArg par menu deroulant Lineaire/Log10
177//| et "logscale" par saisie de valeur dans champ LogScal
178//--
179{
180if(type==0) mTypScal=0;
181else if(type==1) {mTypScal=1; if(logscale>1.) mLogScale=logscale;}
182else mTypScal=0;
183}
184
185//++
186void PIHisto2D::UseDisplay(unsigned short type,float fnpt)
187//
188// Type de Display
189//| Type = 0 : carres de tailles variables
190//| Type = 1 : nuages de points
191//| Le nombre de points a utiliser est fnpt*N
192//| ou N est le nombre de pixels ecran contenu
193//| dans un bin de l'histogramme.
194//| Type = 2 : code a la "hbook2" " .+123...9AB...YZ*"
195//| (cf detail PIHisto2D::HPrint2)
196//| Type = 3 : carres de taille fixe (couleur).
197//| -**- gestion dans H2WinArg par menu deroulant Carres_Var etc...
198//| et "fnpt" par saisie de valeur dans champ PerPt
199//--
200{
201if(type==0) mTypDisp = 0;
202else if(type==1) {
203 mTypDisp = 1;
204 if(fnpt<0.) mFPoints = 0.;
205 else if(fnpt>1.) mFPoints = 1.;
206 else mFPoints = fnpt;
207}
208else if(type==2) mTypDisp = 2;
209else if(type==3) mTypDisp = 3;
210else mTypDisp = 1;
211}
212
213//++
214void PIHisto2D::UseDyn(float fmin,float fmax)
215//
216// Gestion de la dynamique a representer:
217//| La dynamique va etre transformee de [hmin,hmax] vers [0,1] selon
218//| [hmin,hmax] -> [0,1]
219//| h -> f = (h-hmin)/(hmax-hmin)
220//| Par la suite, selon ce qui est demande, f va coder le display
221//| ou etre transforme en une autre echelle [0,1] (ex: echelle log10).
222//| Si hmax<=hmin, ils sont forces a la dynamique totale de l'histo2D.
223//| -**- gestion dans H2WinArg par saisie de valeurs dans champ Dyn
224//--
225{
226 if( (mHistoWp) && (mHistoWp->NBinX()>0) && (mHistoWp->NBinY()>0) && (fmin>=fmax) ) {
227 double v,hmin,hmax;
228 hmin = hmax = (*mHistoWp)(0,0);
229 for (int_4 i=0; i<mHistoWp->NBinX(); i++)
230 for (int_4 j=0; j<mHistoWp->NBinY(); j++) {
231 v = (*mHistoWp)(i, j);
232 if(v<hmin) hmin = v;
233 if(v>hmax) hmax = v;
234 }
235 fmin = hmin; fmax = hmax; // $CHECK$ CMV : attention, double vers float !!
236 }
237
238// $CHECK$ CMV : Ne faut-il pas passer les attributs de la classe en double ??
239if(fmin>=fmax) fmax = fmin+1.;
240mHMin = fmin; mHMax = fmax;
241}
242
243//++
244void PIHisto2D::UseFrac(float frmin,float frmax)
245//
246// Pour definir la fraction de la dynamique a dessiner:
247//| Selon le type de display (f=[0,1] cf PIHisto2D::UseDyn),
248//| - on ne dessine rien si f <= frmin dans les cas de display avec
249//| des nuages de points ou des carres de tailles variables.
250//| Pour un display "a la hbook2" on force frmin = 0.
251//| - frmax n'est utilise que pour la representation avec
252//| des carres de tailles variables: c'est la taille
253//| maximum que peut avoir le carre exprimee en unite
254//| de la taille du bin (ex: si frmax=0.8 le carre
255//| le + grand qui pourra etre dessine dans un bin
256//| aura une taille egale a 0.8*(taille du bin)).
257//| -**- gestion dans H2WinArg par saisie de valeurs dans champ Frac
258//--
259{
260if(frmin<0. || frmin>=1.) frmin = 0.;
261if(frmax<=0. || frmax>1. ) frmax = 1.;
262if(frmin>=frmax) {frmin=0.1; frmax=0.9;}
263mFracMin = frmin; mFracMax = frmax;
264}
265
266//++
267void PIHisto2D::Print(int lp)
268//
269// Print de l'etat des options du display.
270//--
271{
272printf("PIHisto2D::Print FgCol=%d Cmap=%d (Rev=%d) TypScal=%d TypDisp=%d (FPoints=%g)\n"
273 ,(int)mFgCol,(int)mCmap,(int)mRevCmap,mTypScal,mTypDisp,mFPoints);
274printf(" Dyn=%g,%g Frac=%g,%g LogSc=%g H=%p\n"
275 ,mHMin,mHMax,mFracMin,mFracMax,mLogScale,mHistoWp);
276// if(lp>=1) mHistoWp->PrintStatus(); $CHECK$ CMV : que faut-il faire ?
277fflush(stdout);
278}
279
280//++
281void PIHisto2D::UpdateLimits()
282//
283// Definition des tailles graphiques en fonction
284// des caracteristiques de l'histogramme a dessiner.
285//--
286{
287 if(!mHistoWp) return;
288 SetLimits(mHistoWp->XMin(), mHistoWp->XMax(), mHistoWp->YMin() , mHistoWp->YMax());
289}
290
291//++
292void PIHisto2D::ShowControlWindow(PIBaseWdgGen* wdg)
293//
294// Affichage de la fenetre de controle H2WinArg
295//--
296{
297 H2WinArg::SetCurrentPIHisto2D(this);
298 H2WinArg::ShowPIHisto2DTools(wdg);
299}
300
301//++
302void PIHisto2D::DeactivateControlWindow(PIBaseWdgGen* wdg)
303//
304// Desactivation de la fenetre de controle specialisee
305//--
306{
307 if (H2WinArg::GetCurrentPIHisto2D() == this) {
308 // si wdg != NULL, c'est un Detach (Drawer detache du PIBaseWdg
309 // si wdg == NULL, c'est un delete du PIHisto2D (du PIDrawer)
310 if ((wdg == NULL) || (H2WinArg::GetCurrentBaseWdg() == wdg)) {
311 H2WinArg::SetCurrentBaseWdg(NULL);
312 H2WinArg::SetCurrentPIHisto2D(NULL);
313 H2WinArg::HidePIHisto2DTools();
314 }
315 }
316 PIDrawer::DeactivateControlWindow(wdg);
317 return;
318}
319
320//++
321void PIHisto2D::Draw(PIGraphicUC* g,double xmin,double ymin,double xmax,double ymax)
322//
323// Dessin de l'histogramme.
324//| -**- Code de dessin selon choix des options:
325//| (detail voir UseColors UseScale UseDisplay UseDyn UseFrac)
326//| - [hmin,hmax] -> f=[0,1]
327//| (Choix hmin,hmax champ Dyn de H2WinArg)
328//| - Eventuellement ech Log -> re-codage log10 entre f=[0,1]
329//| (Choix menu deroulant et champ LogScal de H2WinArg)
330//| - Restriction de f=[0,1] -> f=[Frac(min),Frac(max)]
331//| (Choix champ Frac de H2WinArg)
332//| -**- Puis selon display:
333//| 0 carres variables, menu "Carres Var." de H2WinArg:
334//| if(f>Frac(min)) taille carre = f * Frac(max) * taille_du_bin
335//| 1 nuage de points, menu "....." et champ PerPt de H2WinArg:
336//| if(f>Frac(min)) npoints = f * PerPt * npoints_ecran_dans_bin
337//| 2 code hbook2, menu ".12..Z*" de H2WinArg:
338//| if(f>0) map de f=]0,1] dans ".+...Z*"
339//| 3 carres pleins, menu "Carres Pleins" et couleurs de H2WinArg):
340//| couleur = lut[ f * nombre_d_entree_dans_la_lut ]
341//--
342{
343if (axesFlags != kAxesNone) DrawAxes(g);
344
345if(!mHistoWp) return;
346if(mHistoWp->NBinX()<=0 || mHistoWp->NBinY()<=0) return;
347
348// Caracteristiques histogramme
349double dx = mHistoWp->WBinX(),dy = mHistoWp->WBinY();
350double p1dx,p1dy;
351g->DGrC2UC(1.,1.,p1dx,p1dy);
352
353// Gamme a representer entre [0,1] mais >=fracmin et scale fracmax
354float fracmin=FMin(), fracmax=FMax();
355float llscale = (float) log10((double)LogScale());
356
357// gestion Couleurs.
358PIColors fgcoul = GetGraphicAtt().GetFgColor();
359PIColors bgcoul = GetGraphicAtt().GetBgColor();
360PIColorMap* cmap=NULL;
361int ncol = 0;
362if (mFgCol) {
363 cmap = new PIColorMap(mCmap);
364 cmap->ReverseColorIndex(mRevCmap);
365 ncol = cmap->NCol();
366 if(mTypDisp==3) fracmin=-1.;
367}
368
369// gestion epaisseur de ligne
370PILineAtt LineAtt = GetGraphicAtt().GetLineAtt();
371if(LineAtt == PI_NotDefLineAtt) GetGraphicAtt().SetLineAtt(PI_ThinLine);
372
373// gestion Markers ou plot avec des points.
374PIMarker Mk = GetGraphicAtt().GetMarker();
375int MkSz = GetGraphicAtt().GetMarkerSize();
376int npt = 1;
377if(mTypDisp==1) {
378 g->SelMarker(1,PI_DotMarker);
379 npt = (int) ((float)NPixBin(g)*FPoints()); if(npt<=0) npt = 2;
380}
381
382// gestion Font.
383PIFontAtt FontAtt = GetGraphicAtt().GetFontAtt();
384int FontSize = GetGraphicAtt().GetFontSzPt();
385if(mTypDisp==2) {
386 double dxg,dyg,dg;
387 g->DUC2GrC(dx,dy,dxg,dyg);
388 dg =(dxg<dyg) ? dxg : dyg;
389 int npix = (int) (dg*0.9); if(npix<8) npix = 8;
390 g->SelFontSzPt(npix,FontAtt);
391 fracmin = 0;
392}
393
394// Plot de l'histogramme
395for(int i=0; i<mHistoWp->NBinX(); i++)
396 for(int j=0; j<mHistoWp->NBinY(); j++) {
397
398 r_8 left0,bottom0;
399 mHistoWp->BinLowEdge(i,j,left0,bottom0);
400
401 // Gestion de la dynamique a dessiner
402 float frac = ((*mHistoWp)(i,j)-HMin())/(HMax()-HMin());
403 if(frac<0.) continue;
404 if(mTypScal==1) { // echelle log10
405 frac = log10(1.+frac*(LogScale()-1.))/llscale;
406 if(frac<0.) continue;
407 }
408 if(frac<=fracmin) continue;
409 if(frac>1.) frac = 1.;
410 float fracred = frac * fracmax;
411
412 // Gestion de la couleur
413 int icol = 0;
414 if (cmap) {
415 icol = int( (float) ncol*frac );
416 if(icol>=ncol) icol = ncol-1; else if(icol<0) icol=0;
417 g->SelForeground(*cmap,icol);
418 }
419
420// Pour ne pas dessiner en dehors des axes
421 if ( (left0+dx/2. < xmin) || (left0+dx/2. > xmax) ||
422 (bottom0+dy/2. < ymin) || (bottom0+dy/2. > ymax) ) continue;
423
424 // Dessin proprement dit selon le choix graphique.
425 if(mTypDisp==0) {
426 //..... carres de tailles variables
427 double left = left0 + 0.5*(1.-fracred)*dx, width = fracred*dx;
428 double bottom = bottom0 + 0.5*(1.-fracred)*dy, height = fracred*dy;
429 if (cmap) g->DrawFBox(left,bottom,width,height);
430 else g->DrawBox(left,bottom,width,height);
431 } else if(mTypDisp==1) {
432 //..... nuage de points .....
433 int ipt = int( (float) npt *frac );
434 for(int k=0;k<ipt;k++) {
435 double x = left0 + frand01()*dx;
436 double y = bottom0 + frand01()*dy;
437 g->DrawMarker(x,y);
438 }
439 } else if(mTypDisp==2) {
440 //..... type hbook2/hprint .+23-Z*
441 char c[2];
442 c[0] = HPrint2(frac); c[1]='\0';
443 double x = left0 + dx/2.;
444 double y = bottom0 + dy/2.;
445 g->DrawString(x,y,c,PI_HorizontalCenter|PI_VerticalCenter);
446 } else if(mTypDisp==3) {
447 //..... carres de tailles fixes (avec gestion de continuite)
448 if (cmap) g->DrawFBox(left0,bottom0,dx+p1dx,dy+p1dy);
449 else g->DrawBox(left0,bottom0,dx+p1dx,dy+p1dy);
450 }
451
452}
453
454// Remise dans les conditions ulterieures pour la suite du graphique.
455GetGraphicAtt().SetMarkerAtt(MkSz,Mk);
456GetGraphicAtt().SetColAtt(fgcoul,bgcoul);
457g->SelFontSzPt(FontSize,FontAtt);
458GetGraphicAtt().SetLineAtt(LineAtt);
459if (cmap) delete cmap;
460
461// Fin du dessin, ecriture de la statistique.
462if(stats) DrawStats(g);
463}
464
465//++
466void PIHisto2D::GetClickInfo(string& info,double x,double y,double x0,double y0,bool fgdiff)
467//
468// Info specifique du drawer pour la position x,y
469//--
470{
471P2DHistoWrapper* h = HistoWrapper();
472if(h == NULL) return;
473
474int_4 i,j;
475i = floor((x-h->XMin())/h->WBinX());
476j = floor((y-h->YMin())/h->WBinY());
477
478if(i>=0 && i<h->NBinX() && j>=0 && j<h->NBinY()) {
479 char str[64];
480 if(fgdiff) {
481 int i0,j0;
482 i0 = floor((x0-h->XMin())/h->WBinX());
483 j0 = floor((y0-h->YMin())/h->WBinY());
484 if(i0>=0 && i0<h->NBinX() && j0>=0 && j0<h->NBinY()) {
485 sprintf(str," DV=%g",(*h)(i,j)-(*h)(i0,j0));
486 info += str;
487 } else {
488 info += " DV=?";
489 }
490 }
491 sprintf(str," V=%g",(*h)(i,j));
492 info += str;
493} else {
494 info += " V=?";
495}
496
497return;
498}
499
500//++
501void PIHisto2D::DrawStats(PIGraphicUC* g)
502//
503// Dessin des informations statistiques de l'histogramme.
504//--
505{
506 if (!mHistoWp) return;
507 if (GetGraphicAtt().GetLineAtt() == PI_NotDefLineAtt) g->SelLine(PI_ThinLine);
508 g->SelFontSz((YMax() - YMin())/30);
509
510 // La hauteur de la cellule
511 PIGrCoord a, d;
512 double cH = (double)g->GetFontHeight(a,d);
513 vector<string> lines;
514 int nlig = mHistoWp->GetStatInfoAsText(lines);
515 if (nlig < 1) return;
516
517 double cellHeight = nlig*1.2 * cH;
518
519 int idxll = 0;
520
521 int kl;
522 // on recherche la ligne la plus longue
523 for(kl=1; kl<nlig; kl++)
524 if ( lines[kl].length() > lines[idxll].length() ) idxll = kl;
525
526 double cellWidth = 1.1 * (double)g->CalcStringWidth(lines[idxll].c_str());
527
528
529 double ofpx = spoX*(XMax()-XMin());
530 double ofpy = spoY*(YMax()-YMin());
531
532 double xu, yu, cw;
533 // Les limites du cadre
534 xu = g->DeltaUCX(XMax(), -cellWidth);
535 yu = g->DeltaUCY(YMax(), -cellHeight);
536 double recw = XMax()-xu;
537 double rech = YMax()-yu;
538 xu += ofpx; yu += ofpy;
539 g->DrawBox(xu, yu, recw, rech);
540
541 // L'ecriture des labels
542 cw = (g->isAxeXDirRtoL()) ? -0.05*cellWidth : -0.95*cellWidth;
543 xu = g->DeltaUCX(XMax(),cw);
544
545 cw = (g->isAxeYDirUpDown()) ? -0.15*cH : -1.15*cH;
546 yu = g->DeltaUCY(YMax(),cw);
547 xu += ofpx; yu += ofpy;
548
549 for(kl=0; kl<nlig; kl++) {
550 g->DrawString(xu, yu, lines[kl].c_str() );
551 cw += -1.15*cH;
552 yu = g->DeltaUCY(YMax(),cw); yu += ofpy;
553 }
554
555
556 // printf("H[%d,%d] Dynamique: [%g,%g] Frac [%g,%g]\n"
557 // ,mHistoWp->NBinX(),mHistoWp->NBinY(),HMin(),HMax(),FMin(),FMax());
558}
559
560//++
561char PIHisto2D::HPrint2(float f)
562//
563// Codage des valeurs en caracteres (fct privee).
564//| f entre [0,1] mappee entre valeur=[0,37]
565//| si <0 alors =0, si >1 alors 1
566//| Display 4 ==> 4<=valeur<5
567//| C ==> 12<=valeur<13
568//| ==> valeur<=0
569//| * ==> valeur>=1
570//| . ==> 0<valeur<1
571//|------------------------------------------
572//| 1 2 3
573//| 01234567890123456789012345678901234567
574//| .+23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*
575//|------------------------------------------
576//--
577{
578char str[39] = " .+23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*";
579int i;
580if(f<=0.) i = 0;
581else if(f>=1.) i = 37;
582else { i = (int) (f*36.); i++;}
583if(i<0) i=0; else if (i>=38) i = 37;
584return str[i];
585}
586
587//++
588int PIHisto2D::NPixBin(PIGraphicUC* g)
589//
590// Nombre de pixels ecran dans un bin d'histogramme
591// (fct privee).
592//--
593{
594double dx = mHistoWp->WBinX(),dy = mHistoWp->WBinY();
595double dxg,dyg;
596g->DUC2GrC(dx,dy,dxg,dyg);
597int np = (int) dxg * (int) dyg;
598//printf("PIHisto2D::NPixBin H dx=%g dy=%g, G dx=%g dy=%g, np = %d\n"
599// ,dx,dy,dxg,dyg,np);
600return np;
601}
602
603//++
604int PIHisto2D::DecodeOptionString(vector<string> & opt, bool rmdecopt)
605//
606// Decodage des options
607//--
608{
609 // Decodage des options generales pidrawer
610 int optsz1 = opt.size();
611 if(optsz1<1) return(0);
612 int ndec1 = PIDrawer::DecodeOptionString(opt, rmdecopt);
613 if(optsz1-ndec1<1) return(ndec1); // si tout a ete decode
614
615 // Options generales pidrawer interessant le display Histo2D
616 bool rev;
617 if(GetGraphicAtt().GetColMapId(rev) != CMAP_OTHER) {
618 UseColors(true,GetGraphicAtt().GetColMapId(),rev);
619 } else UseColors(false);
620
621 // Decodage des options propres au display Histo2D
622 vector<string> udopt; // On gardera ici les options non decodees
623 unsigned int k = 0;
624 int ndec = opt.size();
625 bool listopt=false;
626 for( k=0; k<opt.size(); k++ ) {
627 string opts = opt[k];
628 if(opts=="h2help") {
629 string info; GetOptionsHelpInfo(info);
630 size_t q = info.find("PIHisto2D");
631 if(q<info.length()-1) cout<<info.substr(q)<<endl;
632 } else if(opts=="h2list") {
633 listopt=true;
634 } else if(opts=="sta" || opts=="stat" || opts=="stats") {
635 SetStats(true);
636 } else if( opts=="nsta" || opts=="nstat"
637 || opts=="nostat" || opts=="nostats") {
638 SetStats(false);
639 } else if(opts.substr(0,11) == "statposoff=") {
640 float xo=0., yo=0.;
641 sscanf(opts.substr(11).c_str(),"%g,%g",&xo, &yo);
642 SetStatPosOffset(xo, yo);
643 } else if(opts.substr(0,8)=="h2scale=") {
644 unsigned short t=TypScale(); float ls=LogScale();
645 if(opts.substr(8,3)=="lin") t=0;
646 else if(opts.substr(8,3)=="log")
647 {t=1; sscanf(opts.c_str(),"h2scale=log,%g",&ls);}
648 UseScale(t,ls);
649 } else if(opts.substr(0,7)=="h2disp=") {
650 unsigned short t=TypDisplay(); float fpts=FPoints();
651 if(opts.substr(7,3)=="var") t=0;
652 else if(opts.substr(7,3)=="hbk") t=2;
653 else if(opts.substr(7,3)=="img") t=3;
654 else if(opts.substr(7,3)=="pts")
655 {t=1; sscanf(opts.c_str(),"h2disp=pts,%g",&fpts);}
656 UseDisplay(t,fpts);
657 } else if(opts.substr(0,6)=="h2dyn=") {
658 float hmin=HMin(),hmax=HMax(); size_t q = opts.find(',');
659 sscanf(opts.c_str(),"h2dyn=%g",&hmin);
660 if(q<opts.length()-1) sscanf(opts.substr(q+1).c_str(),"%g",&hmax);
661 UseDyn(hmin,hmax);
662 } else if(opts.substr(0,7)=="h2frac=") {
663 float fmin=FMin(),fmax=FMax(); size_t q = opts.find(',');
664 sscanf(opts.c_str(),"h2frac=%g",&fmin);
665 if(q<opts.length()-1) sscanf(opts.substr(q+1).c_str(),"%g",&fmax);
666 UseFrac(fmin,fmax);
667 } else {
668 ndec--;
669 // S'il faut supprimer les options decodees
670 if (rmdecopt) udopt.push_back(opts);
671 }
672 }
673
674 // S'il faut supprimer les options decodees, on remplace l'argument opt
675 // par le vecteur des options non decodees.
676 if (rmdecopt) opt = udopt;
677
678 // Decodage des options par le histo-wrapper
679 int ndec2 = 0;
680 if ( ( optsz1-ndec1-ndec > 0) && (mHistoWp) ) {
681 ndec2 = mHistoWp->DecodeOptionString(opt, rmdecopt);
682 }
683
684 // Liste des options si demande
685 if(listopt) Print();
686
687 return(ndec+ndec1+ndec2);
688}
689
690int PIHisto2D::OptionToString(vector<string> & opt) const
691{
692 PIDrawer::OptionToString(opt);
693 char str[256];
694
695 if(stats) opt.push_back("stat"); else opt.push_back("nstat");
696
697 sprintf(str,"statposoff=%f,%f",spoX,spoY);
698 opt.push_back(str);
699
700 if(mTypDisp==0) sprintf(str,"h2disp=var");
701 else if(mTypDisp==1) sprintf(str,"h2disp=pts,%g",mFPoints);
702 else if(mTypDisp==2) sprintf(str,"h2disp=hbk");
703 else if(mTypDisp==3) sprintf(str,"h2disp=img");
704 opt.push_back(str);
705
706 if(mTypScal==0) sprintf(str,"h2scale=lin");
707 else if(mTypScal==1) sprintf(str,"h2disp=log,%g",mLogScale);
708 opt.push_back(str);
709
710 sprintf(str,"h2dyn=%g,%g",mHMin,mHMax);
711 opt.push_back(str);
712
713 sprintf(str,"h2frac=%g,%g",mFracMin,mFracMax);
714 opt.push_back(str);
715
716 if(mRevCmap) opt.push_back("revcmap");
717
718 // Les options du Histo2DWrapper :
719 mHistoWp->OptionToString(opt);
720 return 1;
721}
722
723
724//++
725void PIHisto2D::GetOptionsHelpInfo(string& info)
726//
727// Help relatif au options
728//--
729{
730info += " ---- PIHisto2D options help info (see also ALT-O): \n" ;
731info += "- h2help: get this help text\n";
732info += "- h2list: list choosen options\n";
733info += "- sta,stat,stats: activate statistic display\n";
734info += " nsta,nstat,nostat,nostats: deactivate statistic display\n";
735info += "- h2disp=typ[,fracpts]: choose display type\n";
736info += " typ=var: variable size boxes\n";
737info += " typ=hbk: \"a la hbook2\"\n";
738info += " typ=img: image like (use \"h2col\" for color map)\n";
739info += " typ=pts: point clouds (fracpts=max possible fraction\n";
740info += " of used pixels per bin [0,1])\n";
741info += "- h2scale=lin/log[,logscale]: choose linear or logarithmic scale\n";
742info += "- h2dyn=[hmin][,hmax]: choose histogramme range for display\n";
743info += "- use graphic att. to define color table (ex: grey32,midas_heat,...)\n";
744info += " (see general graphicatt description)\n";
745info += "- use \"revcmap\" to reverse color table\n";
746info += "- h2frac=[fmin][,fmax]: choose sub-range display [0,1]\n";
747info += " ---- HistoWrapper options : \n" ;
748info += " hbincont: select bin content as Y value for display (default) \n";
749info += " hbinerr: select bin error as Y value for display \n";
750info += " hbinent: select bin entries as Y value for display \n";
751info += " hscale=value : multiplicative factor for Y value \n" ;
752info += " hoffset=value : additive coefficient for Y value \n" ;
753info += " hs1: set hscale=1 hoffset=0 (default) \n" ;
754// On recupere ensuite la chaine info de la classe de base
755PIDrawer::GetOptionsHelpInfo(info);
756return;
757}
758
759/////////////////////////////////////////////////////////////////
760// Classe H2WinArg
761/////////////////////////////////////////////////////////////////
762//++
763// Class H2WinArg
764// Lib PIext
765// include pihisto2d.h
766//
767// Fenêtre de dialogue pour le choix des options de tracé pour "PIHisto2D"
768// Classe de fenêtre de dialogue permettant de modifier interactivement
769// Les différents attributs de visualisation pour les *PIImage* .
770//--
771//++
772// Links Parents
773// PIWindow
774//--
775//++
776// Links Voir aussi
777// PIHisto2D
778// PIH2DWdg
779//--
780
781//++
782// Titre Constructeur, méthodes
783//--
784
785PIBaseWdgGen* H2WinArg::mBWdg = NULL;
786PIHisto2D* H2WinArg::mH2DDrw = NULL;
787static H2WinArg* cur_h2winarg = NULL;
788
789void H2WinArg::ShowPIHisto2DTools()
790{
791 if (cur_h2winarg == NULL) cur_h2winarg = new H2WinArg(PIApplicationGetApp());
792 cur_h2winarg->Show();
793}
794
795void H2WinArg::ShowPIHisto2DTools(PIBaseWdgGen* cbw)
796{
797 if (cur_h2winarg == NULL) cur_h2winarg = new H2WinArg(PIApplicationGetApp());
798 mBWdg = cbw;
799 cur_h2winarg->Show();
800}
801
802void H2WinArg::HidePIHisto2DTools()
803{
804 if (cur_h2winarg != NULL) cur_h2winarg->Hide();
805}
806
807void H2WinArg::SetCurrentBaseWdg(PIBaseWdgGen* cbw)
808{
809 mBWdg = cbw;
810}
811
812void H2WinArg::SetCurrentPIHisto2D(PIHisto2D* h2ddrw)
813{
814 mH2DDrw = h2ddrw;
815}
816
817PIBaseWdgGen* H2WinArg::GetCurrentBaseWdg()
818{
819 return(mBWdg);
820}
821
822PIHisto2D* H2WinArg::GetCurrentPIHisto2D()
823{
824 return(mH2DDrw);
825}
826
827//++
828H2WinArg::H2WinArg(PIMsgHandler* par)
829//
830// Creation de la fenetre de gestion des parametres
831// des dessins des histogrammes 2D. Cette fenetre de
832// dialogue est partagee par tous les widget de dessin
833// des histogrammes 2D. Pour faire apparaitre la fenetre
834// tapez ALT-O.
835//--
836//++
837//| - Menu 1: Choix du type de display
838//| Carres variables, nuages de points, caracteres a la hbook2
839//| et carres de tailles fixe (couleur ou niveauz de gris).
840//| - Menu 2: Choix du type d'echelle
841//| Lineaire ou logarithmique
842//| - Menu 3: Choix de la couleur
843//| noir et blanc, niveau de gris et couleurs diverses.
844//| - Champ texte Dyn: Pour donner la dynamique, si min>=max
845//| alors prend le min et le max de l'histogramme
846//| (cf PIHisto2D::UseDyn)
847//| - Champ texte Frac: fraction mini et maxi
848//| (cf PIHisto2D::UseFrac)
849//| - Champ texte LogScal: niveau de scaling pour le choix d'une
850//| echelle logarithmique (cf PIHisto2D::UseScale)
851//--
852//++
853//| - Curseur interactif PerPt: pourcentage de points a dessiner
854//| dans chaque bin (cf PIHisto2D::UseDisplay)
855//| - Bouton Apply: dessiner avec les options affichees
856//| - Bouton Dismiss: fermeture de la fenetre de dialogue.
857//| - Bouton Get: re-prendre les valeurs de display stoquees
858//| pour un histogramme donne.
859//| - Bouton Print: Imprimer les caracteristiques du display
860//| et de l'histogramme.
861//--
862: PIWindow((PIMsgHandler *)par,"H2D-Options",PIWK_dialog,250,260,150,150)
863, mFgCol(false), mCmap(CMAP_GREYINV32), mRevCmap(false)
864, mTypScal(0) , mLogScale(10.)
865, mTypDisp(0) , mFPoints(0.5)
866, mHMin(1.) , mHMax(-1.)
867, mFracMin(0.1), mFracMax(0.9)
868{
869if(dbg) printf("H2WinArg::H2WinArg %p par=%p\n",this,par);
870
871// Taille automatique
872int bsx, bsy;
873PIApplicationPrefCompSize(bsx, bsy); // environ 6 lettres
874int spx = (bsx>=10) ? bsx/10 : 1; // intervalle entre lettres X
875int spy = (bsy>=5) ? bsy/5 : 1; // intervalle entre lettres Y
876int wszx = 5*spx+bsx+int(2.5*bsx); // Taille fenetre en X
877int wszy = 11*spy+int(8.5*bsy); // Taille fenetre en Y
878SetSize(wszx, wszy);
879
880// menu du style de display des bins
881 int cpx = 2*spx, cpy = 2*spy;
882mOPop[0] = new PIOptMenu(this,"optmen-h2d-1",2*bsx,bsy,cpx,cpy);
883mOPop[0]->AppendItem("Carres Var." ,6101);
884mOPop[0]->AppendItem("....." ,6102);
885mOPop[0]->AppendItem(".+12..Z*" ,6103);
886mOPop[0]->AppendItem("Carres Pleins",6104);
887mOPop[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
888
889// Menu du choix de la dynamique
890 cpy += bsy+spy;
891mOPop[1] = new PIOptMenu(this,"optmen-h2d-2",2*bsx,bsy,cpx,cpy);
892mOPop[1]->AppendItem("Lineaire",6201);
893mOPop[1]->AppendItem("Log10" ,6202);
894mOPop[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
895
896// Menu du choix de la table des couleurs
897 cpy += bsy+spy;
898mOPop[2] = new PIOptMenu(this,"optmen-h2d-3",2*bsx,bsy,cpx,cpy);
899mOPop[2]->AppendItem("Black&White",7000);
900mCasc[0] = new PIMenu(mOPop[2]->Menu(),"PIStd-128Col");
901mCasc[1] = new PIMenu(mOPop[2]->Menu(), "PIUniCol32");
902mCasc[2] = new PIMenu(mOPop[2]->Menu(),"MIDAS-CMap");
903int kcc,nsct1=5,nsct2=9,nsct3=17,nsct4=PIColorMap::NumberStandardColorMaps()-2;
904for(kcc=0; kcc<nsct1; kcc++)
905 mOPop[2]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(),7001+kcc);
906for(kcc=nsct1; kcc<nsct2; kcc++)
907 mCasc[0]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(),7001+kcc);
908mOPop[2]->AppendPDMenu(mCasc[0]);
909for(kcc=nsct2; kcc<nsct3; kcc++)
910 mCasc[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(),7001+kcc);
911mOPop[2]->AppendPDMenu(mCasc[1]);
912for(kcc=nsct3; kcc<nsct4; kcc++)
913 mCasc[2]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(),7001+kcc);
914mOPop[2]->AppendPDMenu(mCasc[2]);
915for(kcc=nsct4; kcc<PIColorMap::NumberStandardColorMaps(); kcc++)
916 mOPop[2]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(),7001+kcc);
917//mOPop[2]->SetValue(7000);
918mOPop[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
919
920// Reverse color map
921 cpy += bsy+spy;
922mCkb = new PICheckBox(this,"Reverse CMap",8001,2*bsx,bsy,cpx,cpy);
923mCkb->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
924
925// Labels et zones de saisie texte
926 cpy += bsy+spy;
927mLab[0] = new PILabel(this," Dyn: ",bsx,bsy,cpx,cpy);
928mLab[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
929mText[0] = new PIText(this,"Dynamique",int(2.5*bsx),bsy,cpx+bsx+spx,cpy);
930mText[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
931 cpy += bsy+spy;
932mLab[1] = new PILabel(this," Frac: ",bsx,bsy,cpx,cpy);
933mLab[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
934mText[1] = new PIText(this,"Fraction",int(2.5*bsx),bsy,cpx+bsx+spx,cpy);
935mText[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
936 cpy += bsy+spy;
937mLab[2] = new PILabel(this," LogScal: ",bsx,bsy,cpx,cpy);
938mLab[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
939mText[2] = new PIText(this,"LogScale",int(2.5*bsx),bsy,cpx+bsx+spx,cpy);
940mText[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
941
942// Labels et curseur mobile
943cpy += bsy+spy;
944mLab[3] = new PILabel(this," PerPt: ",bsx,bsy,cpx,cpy+int(0.25*bsy));
945mLab[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
946mPScal = new PIScale(this,"FracPoints",6401,kSDirLtoR
947 ,int(2.5*bsx),int(1.25*bsy),cpx+bsx+spx,cpy);
948mPScal->SetMinMax(0,100);
949mPScal->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
950
951//
952SetText();
953//
954
955// Boutons
956 cpx = 2*bsx+5*spx, cpy = 2*spy;
957mBut[0] = new PIButton(this,"Apply",6001,bsx,bsy,cpx,cpy);
958mBut[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
959 cpy += bsy+spy;
960mBut[1] = new PIButton(this,"Dismiss",6002,bsx,bsy,cpx,cpy);
961mBut[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
962 cpy += bsy+spy;
963mBut[2] = new PIButton(this,"Get",6003,bsx,bsy,cpx,cpy);
964mBut[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
965 cpy += bsy+spy;
966mBut[3] = new PIButton(this,"Print",6004,bsx,bsy,cpx,cpy);
967mBut[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
968// FinishCreate();
969}
970
971//++
972H2WinArg::~H2WinArg()
973//
974// Destructeur.
975//--
976{
977int i;
978if(dbg) printf("H2WinArg::~H2WinArg %p\n",this);
979for(i=0;i<3;i++) delete mCasc[i];
980for(i=0;i<3;i++) delete mOPop[i];
981for(i=0;i<4;i++) delete mBut[i];
982for(i=0;i<4;i++) delete mLab[i];
983for(i=0;i<3;i++) delete mText[i];
984delete mCkb;
985delete mPScal;
986}
987
988//++
989void H2WinArg::Show()
990//
991// Initialisation sur ouverture ALT-O
992//--
993{
994 if(dbg) printf("H2WinArg::Show() mH2DDrw=%p\n",mH2DDrw);
995 // Pour recuperer les valeurs du Drawer sur lequel on fait ALT-O
996 PIWindow::Show();
997 return;
998}
999
1000//++
1001void H2WinArg::SetText()
1002//
1003// Gestion des fenetres de saisie de texte et des pop-menus.
1004//--
1005{
1006if(dbg) printf("H2WinArg::SetText()\n");
1007string sdum;
1008char str[256];
1009
1010sprintf(str,"%g %g",mHMin,mHMax);
1011mText[0]->SetText(str);
1012
1013sprintf(str,"%g %g",mFracMin,mFracMax);
1014mText[1]->SetText(str);
1015
1016sprintf(str,"%g",mLogScale);
1017mText[2]->SetText(str);
1018if(mTypScal==1) mText[2]->SetSensitive();
1019 else mText[2]->SetUnSensitive();
1020
1021if(mTypDisp==0) {sdum="Carres Var."; mOPop[0]->SetValueStr(sdum);}
1022else if(mTypDisp==1) {sdum="....."; mOPop[0]->SetValueStr(sdum);}
1023else if(mTypDisp==2) {sdum=".+12..Z*"; mOPop[0]->SetValueStr(sdum);}
1024else if(mTypDisp==3) {sdum="Carres Pleins"; mOPop[0]->SetValueStr(sdum);}
1025
1026if(mTypScal==0) {sdum="Lineaire"; mOPop[1]->SetValueStr(sdum);}
1027else if(mTypScal==1) {sdum="Log10"; mOPop[1]->SetValueStr(sdum);}
1028
1029if(!mFgCol) {mOPop[2]->SetValue(7000);}
1030else {
1031 for(int kk=0;kk<PIColorMap::NumberStandardColorMaps();kk++)
1032 if(mCmap == PIColorMap::GetStandardColorMapId(kk))
1033 {mOPop[2]->SetValue(7001+kk); break;}
1034}
1035mCkb->SetState(mRevCmap);
1036
1037mPScal->SetValue(int(mFPoints*100.));
1038if(mTypDisp==1) mPScal->SetSensitive();
1039 else mPScal->SetUnSensitive();
1040}
1041
1042//++
1043void H2WinArg::Process(PIMessage msg, PIMsgHandler* sender, void*)
1044//
1045// Gestions des messages.
1046//--
1047{
1048if(dbg) printf("H2WinArg::Process(%d-%d , %p ...) \n"
1049 ,(int)UserMsg(msg),(int)ModMsg(msg),sender);
1050
1051// if(!mH2Wdg) return;
1052if(!mBWdg) return;
1053// PIHisto2D* mpih = mH2Wdg->GetPIHisto();
1054PIHisto2D* mpih = mH2DDrw;
1055if(!mpih) return;
1056
1057int opt = UserMsg(msg);
1058
1059 if(opt == 6101) {mTypDisp = 0;}
1060else if(opt == 6102) {mTypDisp = 1;}
1061else if(opt == 6103) {mTypDisp = 2;}
1062else if(opt == 6104) {mTypDisp = 3;}
1063
1064else if(opt == 6201) {mTypScal = 0;}
1065else if(opt == 6202) {mTypScal = 1;}
1066
1067else if(opt == 7000) {mFgCol = false;}
1068else if(opt >= 7001 && opt <8000) {
1069 int k = opt-7001;
1070 mFgCol = true;
1071 mCmap = PIColorMap::GetStandardColorMapId(k);
1072}
1073
1074else if(opt == 8001) mRevCmap = mCkb->GetState();
1075
1076else if(opt == 6401) mFPoints = mPScal->GetValue()/100.;
1077
1078else if(opt==6001) {
1079 sscanf(mText[0]->GetText().c_str(),"%g %g",&mHMin,&mHMax);
1080 sscanf(mText[1]->GetText().c_str(),"%g %g",&mFracMin,&mFracMax);
1081 sscanf(mText[2]->GetText().c_str(),"%g",&mLogScale);
1082 mpih->UseColors(mFgCol,mCmap,mRevCmap);
1083 mpih->UseScale(mTypScal,mLogScale);
1084 mpih->UseDisplay(mTypDisp,mFPoints);
1085 mpih->UseDyn(mHMin,mHMax);
1086 mpih->UseFrac(mFracMin,mFracMax);
1087 mBWdg->Refresh(); // On rafraichit le dessin (tout le PIScDrawWdg)
1088}
1089else if(opt==6002) this->Hide();
1090else if (opt==6003) {
1091 mFgCol = mpih->Color(); mCmap = mpih->ColMap();
1092 mRevCmap = mpih->IsColMapRev();
1093 mTypScal = mpih->TypScale(); mLogScale = mpih->LogScale();
1094 mTypDisp = mpih->TypDisplay(); mFPoints = mpih->FPoints();
1095 mHMin = mpih->HMin(); mHMax = mpih->HMax();
1096 mFracMin = mpih->FMin(); mFracMax = mpih->FMax();
1097}
1098else if(opt==6004) mpih->Print(2);
1099
1100SetText();
1101
1102if(dbg) {
1103 printf("H2WinArg::Process opt=%d col=%d,%d,%d scal=%d disp=%d npt=%g\n"
1104 ,opt,(int)mFgCol,(int)mCmap,(int)mRevCmap,mTypScal,mTypDisp,mFPoints);
1105 printf(" min,max= %g,%g frac= %g,%g logsc= %g\n"
1106 ,mHMin,mHMax,mFracMin,mFracMax,mLogScale);
1107}
1108
1109}
Note: See TracBrowser for help on using the repository browser.