// Peida Interactive - PI R. Ansari 97-99 // Traceur (Drawer) pour NTupleInterface // LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA #include #include "pintuple.h" //++ // Class PINTuple // Lib PIext // include pintuple.h // // Classe de traceur 2D (dans un plan) à partir des données // d'un objet implémentant l'interface *NTupleInterface*. // Les objets "PINTuple" peuvent tracer des signes (markers) // éventuellement avec des barres d'erreur et une étiquette // pour chaque point. Si un attribut de ligne, autre que // "PI_NotDefLineAtt" est spécifié, les points sont connectés // par une ligne. //-- //++ // Links Parents // PIDrawer //-- //++ // Links Voir aussi // NTupleInterface // PINTuple3D //-- //++ // Titre Constructeur //-- //++ // PINTuple(NTupleInterface* nt, bool ad) // Constructeur. Si "ad == true", l'objet "nt" est détruit par // le destructeur de l'objet "PINTuple" // Note : "nt" doit être créé par new //-- /* --Methode-- */ PINTuple::PINTuple(NTupleInterface* nt, bool ad) : PIDrawer() { mNT = nt; mAdDO = ad; SetStats(true); SelectXY(NULL, NULL); SelectWt(NULL, 1); SelectErrBar(); SelectLabel(NULL); SetName("NTupleDrw"); } PINTuple::~PINTuple() { if (mAdDO && mNT) delete mNT; } //++ // Titre Méthodes //-- //++ // void SelectXY(const char* px, const char* py) // Choix des noms de colonnes X,Y définissant les coordonnées des points. // Ces deux colonnes doivent être spécifiées pour obtenir un tracé. // void SelectErrBar(const char* erbx=NULL, const char* erby=NULL) // Choix des noms de colonnes pour le tracé des barres d'erreur. // void SelectWt(const char* pw=NULL, int nbins=10) // Choix du nom de colonne poids. Dans ce cas, la taille du signe // (marker) sera proportionnel à la valeur de cette colonne pour // chaque point. // void SelectLabel(const char* plabel=NULL) // Choix du nom de colonne correspondant à l'étiquette. //-- /* --Methode-- */ void PINTuple::SelectXY(const char* px, const char* py) { string name; if (mNT == NULL) xK = yK = -1; if (px == NULL) xK = -1; else { name = px; xK = mNT->ColumnIndex(name); } if (py == NULL) yK = -1; else { name = py; yK = mNT->ColumnIndex(name); } } /* --Methode-- */ void PINTuple::SelectWt(const char* pw, int nbins) { nWbins = (nbins > 0) ? nbins : 10; if (pw == NULL) wK = -1; else { string name = pw; wK = mNT->ColumnIndex(name); } if (wK >= 0) mNT->GetMinMax(wK, wMin, wMax); else { wMin = 0.; wMax = 1.; } } /* --Methode-- */ void PINTuple::SelectLabel(const char* plabel) { if (plabel == NULL) lK = -1; else { string name = plabel; lK = mNT->ColumnIndex(name); } } /* --Methode-- */ void PINTuple::SelectErrBar(const char* erbx, const char* erby) { string name; if (mNT == NULL) xebK = yebK = -1; if (erbx == NULL) xebK = -1; else { name = erbx; xebK = mNT->ColumnIndex(name); } if (erby == NULL) yebK = -1; else { name = erby; yebK = mNT->ColumnIndex(name); } } /* --Methode-- */ void PINTuple::UpdateLimits() { if (!mNT) return; if (mNT->NbLines() <= 0) return; if ( (xK < 0) || (yK < 0) ) return; // Commencer par trouver nos limites double dx, dy; double xmin, xmax, ymin, ymax; xmin = ymin = 9.e19; xmax = ymax = -9.e19; mNT->GetMinMax(xK, xmin, xmax); mNT->GetMinMax(yK, ymin, ymax); dx = 0.02*(xmax-xmin); dy = 0.02*(ymax-ymin); SetLimits(xmin-dx, xmax+dx, ymin-dy, ymax+dy); // SetAxesFlags(kBoxAxes | kExtTicks | kLabels); Ne pas faire - Reza 11/99 } /* --Methode-- */ void PINTuple::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax) { double xp,yp,xer,yer,wp; double xl,yl; int nok; if (!mNT) return; if (axesFlags != kAxesNone) DrawAxes(g); if ( (xK < 0) || (yK < 0) ) return; if (GetGraphicAtt().GetLineAtt() == PI_NotDefLineAtt) g->SelLine(PI_ThinLine); // Pour tracer des markers avec taille fonction de Wt (poids) double dw = (wMax-wMin)/nWbins; if (dw < 1.e-19) dw = 1.e19; int msz,sz; PIMarker mmrk = GetGraphicAtt().GetMarker(); PIMarker mrk; if (wK >= 0) mrk = (mmrk != PI_NotDefMarker) ? mmrk : PI_CircleMarker; else mrk = (mmrk != PI_NotDefMarker) ? mmrk : PI_DotMarker; msz = GetGraphicAtt().GetMarkerSz();; if (msz < 1) msz = 1; g->SelMarker(msz, mrk); PIGrCoord uxmin, uxmax, uymin, uymax; g->GetGrSpace(uxmin, uxmax, uymin, uymax); double xmin2 = uxmin; double ymin2 = uymin; double xmax2 = uxmax; double ymax2 = uymax; nok = 0; xp = yp = xl = yl = 0; for (int i=0; iNbLines(); i++) { xl = xp; yl = yp; xp = mNT->GetCell(i, xK); yp = mNT->GetCell(i, yK); if ( (xp < xmin2) || (xp > xmax2) || (yp < ymin2) || (yp > ymax2) ) continue; nok++; if ( (xp < xmin) || (xp > xmax) || (yp < ymin) || (yp > ymax) ) continue; if ( (i > 0) && (GetGraphicAtt().GetLineAtt() != PI_NotDefLineAtt) ) g->DrawLine(xl, yl, xp, yp); // On relie les points ... if ( xebK >= 0 ) { xer = mNT->GetCell(i, xebK); if(xer>0.) g->DrawLine(xp-xer, yp, xp+xer, yp); } if ( yebK >= 0 ) { yer = mNT->GetCell(i, yebK); if(yer>0.) g->DrawLine(xp, yp-yer, xp, yp+yer); } if (wK >= 0) { // Taille de marker en fonction du poids wp = mNT->GetCell(i, wK); sz = (int)((wp-wMin)/dw); if (sz < 0) sz = 0; if (sz > nWbins) sz = nWbins; sz += msz; if (sz < 2) g->SelMarker(sz, PI_DotMarker); else g->SelMarker(sz, mrk); } // Trace du marker if ((wK >= 0)||(lK < 0)||(mmrk != PI_NotDefMarker)) g->DrawMarker(xp, yp); // Trace eventuel du label if (lK >= 0) g->DrawString(xp, yp, mNT->GetCelltoString(i, lK).c_str()); } if (stats) { // Trace de stats g->SelFontSz((YMax() - YMin())/30); // La hauteur de la cellule PIGrCoord a,d; double cH = (double)g->GetFontHeight(a,d); double cellHeight = 1.2 * cH; // Les labels et leurs longueurs -> largeur de la cellule char label[64]; sprintf(label, "Nd= %d / Ntot= %d", nok, mNT->NbLines()); double cellWidth = 1.1 * (double)g->CalcStringWidth(label); double xu, yu, cw; // Les limites du cadre xu = g->DeltaUCX(XMax(), - cellWidth); yu = g->DeltaUCY(YMax(), - cellHeight); g->DrawLine(xu, YMax(), xu, yu); g->DrawLine(xu, yu, XMax(), yu); // L'ecriture des labels (attention aux inversions possibles des axes!) cw = (g->isAxeXDirRtoL()) ? -0.05*cellWidth : -0.95*cellWidth; xu = g->DeltaUCX(XMax(),cw); cw = (g->isAxeYDirUpDown()) ? -0.1*cH : -1.1*cH; yu = g->DeltaUCY(YMax(),cw); g->DrawString(xu,yu,label); } return; } /* --Methode-- */ void PINTuple::AppendTextInfo(string& info, double xmin, double ymin, double xmax, double ymax) { if (!mNT) return; if ( (xK < 0) || (yK < 0) ) return; int ncnt = 0; double xp,yp; char buff[128]; sprintf(buff,"PINTuple: NLines= %d NCol= %d \n", mNT->NbLines(), mNT->NbColumns()); info += buff; info += mNT->LineHeaderToString(); for (int i=0; iNbLines(); i++) { xp = mNT->GetCell(i, xK); yp = mNT->GetCell(i, yK); if ( (xp < xmin) || (xp > xmax) || (yp < ymin) || (yp > ymax) ) continue; ncnt++; if (ncnt > 101) continue; info += mNT->LineToString(i); } if (ncnt >= 101) info += " .... \n"; sprintf(buff," %d points inside selected region \n", ncnt); info += buff; // printf("PINTuple::AppendTextInfo()-DBG %g %g %g %g - %d\n", xmin, ymin, xmax, ymax, ncnt); return; }