ROOT logo
// @(#)root/treeviewer:$Id: TParallelCoordRange.cxx 41349 2011-10-12 09:22:28Z couet $
// Author: Bastien Dalla Piazza  02/08/2007

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TParallelCoordRange.h"
#include "TParallelCoord.h"
#include "TParallelCoordVar.h"

#include "TBox.h"
#include "TPolyLine.h"
#include "TList.h"
#include "TVirtualPad.h"
#include "TVirtualX.h"
#include "TPoint.h"
#include "TFrame.h"
#include "Riostream.h"
#include "TCanvas.h"
#include "TString.h"

ClassImp(TParallelCoordRange)

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TParallelCoordRange                                                  //
//                                                                      //
// A TParallelCoordRange is a range used for parallel                   //
// coordinates plots.                                                   //
//                                                                      //
//////////////////////////////////////////////////////////////////////////


//______________________________________________________________________________
TParallelCoordRange::TParallelCoordRange()
   :TNamed("Range","Range"), TAttLine(), fSize(0.01)
{
   // default constructor.

   fMin = 0;
   fMax = 0;
   fVar = NULL;
   fSelect = NULL;
   SetBit(kShowOnPad,kTRUE);
   SetBit(kLiveUpdate,kFALSE);
}


//______________________________________________________________________________
TParallelCoordRange::~TParallelCoordRange()
{
   // Destructor.
}


//______________________________________________________________________________
TParallelCoordRange::TParallelCoordRange(TParallelCoordVar *var, Double_t min, Double_t max, TParallelCoordSelect *sel)
   :TNamed("Range","Range"), TAttLine(1,1,1), fSize(0.01)
{
   // Normal constructor.

   if(min == max) {
      min = var->GetCurrentMin();
      max = var->GetCurrentMax();
   }
   fMin = min;
   fMax = max;
   
   fVar = var;
   if (!sel) fSelect = var->GetParallel()->GetCurrentSelection();
   else fSelect = sel;
   
   SetLineColor(fSelect->GetLineColor());
   
   SetBit(kShowOnPad,kTRUE);
   SetBit(kLiveUpdate,var->GetParallel()->TestBit(TParallelCoord::kLiveUpdate));
}


//______________________________________________________________________________
void TParallelCoordRange::BringOnTop()
{
   // Make the selection which owns the range to be drawn on top of the others.

   TList *list = fVar->GetParallel()->GetSelectList();
   list->Remove(fSelect);
   list->AddLast(fSelect);
   gPad->Update();
}


//______________________________________________________________________________
void TParallelCoordRange::Delete(const Option_t* /*options*/)
{
   // Delete the range.

   fVar->GetRanges()->Remove(this);
   fVar->GetParallel()->CleanUpSelections(this);
   delete this;
}


//______________________________________________________________________________
Int_t TParallelCoordRange::DistancetoPrimitive(Int_t px, Int_t py)
{
   // Compute the distance to the primitive.
   
   if(TestBit(kShowOnPad)){
      Double_t xx,yy,thisx=0,thisy=0;
      xx = gPad->AbsPixeltoX(px);
      yy = gPad->AbsPixeltoY(py);
      fVar->GetXYfromValue(fMin,thisx,thisy);
      Int_t dist = 9999;
      if(fVar->GetVert()){
         if(xx > thisx-2*fSize && xx < thisx && yy > thisy-fSize && yy<thisy+fSize) dist = 0;
         fVar->GetXYfromValue(fMax,thisx,thisy);
         if(xx > thisx-2*fSize && xx < thisx && yy > thisy-fSize && yy<thisy+fSize) dist = 0;
      } else {
         if(yy > thisy-2*fSize && yy < thisy && xx > thisx-fSize && xx<thisx+fSize) dist = 0;
         fVar->GetXYfromValue(fMax,thisx,thisy);
         if(yy > thisy-2*fSize && yy < thisy && xx > thisx-fSize && xx<thisx+fSize) dist = 0;
      }
      return dist;
   } else return 9999;
}


//______________________________________________________________________________
void TParallelCoordRange::Draw(Option_t* options)
{
   // Draw a TParallelCoordRange.

   AppendPad(options);
}


//______________________________________________________________________________
void TParallelCoordRange::ExecuteEvent(Int_t entry, Int_t px, Int_t py)
{
   // Execute the entry.

   if (!gPad) return;
   if (!gPad->IsEditable() && entry!=kMouseEnter) return;
   
   Bool_t vert = fVar->GetVert();
   static Int_t pxold, pyold;
   static Int_t mindragged = -1; //-1:nothing dragged, 0:max dragged, 1:mindragged, 2:both dragged;
   Int_t plx1,plx2,ply1,ply2;
   
   Double_t xx,yy,txxmin=0,txxmax=0,tyymin=0,tyymax=0;
   TFrame *frame = gPad->GetFrame();
   xx = gPad->AbsPixeltoX(px);
   yy = gPad->AbsPixeltoY(py);
   fVar->GetXYfromValue(fMin,txxmin,tyymin);
   fVar->GetXYfromValue(fMax,txxmax,tyymax);
   if (vert) {
      plx1 = gPad->XtoAbsPixel(txxmin-2*fSize);
      plx2 = gPad->XtoAbsPixel(txxmax-2*fSize);
      ply1 = gPad->YtoAbsPixel(tyymin+fSize);
      ply2 = gPad->YtoAbsPixel(tyymax-fSize);
   } else {
      plx1 = gPad->XtoAbsPixel(txxmin+fSize);
      plx2 = gPad->XtoAbsPixel(txxmax-fSize);
      ply1 = gPad->YtoAbsPixel(tyymin-2*fSize);
      ply2 = gPad->YtoAbsPixel(tyymax-2*fSize);
   }
   
   gPad->SetCursor(kPointer);
   gVirtualX->SetLineColor(-1);
   gVirtualX->SetLineWidth(1);
   TPoint *p = NULL;
   switch (entry) {
      case kButton1Down:
         fVar->GetParallel()->SetCurrentSelection(fSelect);
         ((TCanvas*)gPad)->Selected(gPad,fVar->GetParallel(),1);
         if ((vert && yy<tyymax-fSize) || (!vert && xx < txxmax-fSize)) {     //checks if the min slider is clicked.
            mindragged = 1;
            p = GetSliderPoints(fMin);
            gVirtualX->DrawPolyLine(5,p);
            delete [] p;
         } else {
            mindragged = 0;
            p = GetSliderPoints(fMax);
            gVirtualX->DrawPolyLine(5,p);
            delete [] p;
         }
         gVirtualX->DrawLine(plx1,ply1,plx2,ply2);
         break;
      case kButton1Up: {
         Double_t min = fMin, max= fMax;
         if (mindragged == 1) min = fVar->GetValuefromXY(xx,yy);
         if (mindragged == 0) max = fVar->GetValuefromXY(xx,yy);
         if(fMin!=min || fMax != max) {
            if (min>max) {
               Double_t mem = min;
               min = max;
               max = mem;
            }
            fMin = min;
            fMax = max;
            gPad->Modified();
         }
         mindragged = -1;
         break;
      }
      case kMouseMotion:
         pxold = px;
         pyold = py;
         break;
      /*case  7: // == Button1Down + shift
         mindragged = 2;
         if ((vert && yy<tyymax-fSize) || (!vert && xx < txxmax-fSize)) mouseonmin = kTRUE;    //checks if the min slider is clicked.
         else mouseonmin = kFALSE;
         p = GetSliderPoints(fMin);
         gVirtualX->DrawPolyLine(5,p);
         p = GetSliderPoints(fMax);
         gVirtualX->DrawPolyLine(5,p);
         gVirtualX->DrawLine(plx1,ply1,plx2,ply2);
         if (vert) pminmax = gPad->YtoAbsPixel(tyymax-tyymin);
         else pminmax = gPad->XtoAbsPixel(txxmax-txxmin);
         break;
      case 8: // == Button1Motion + shift
         if((vert && yy > frame->GetY1() && yy < frame->GetY2()) ||
            (!vert && xx > frame->GetX1() && xx < frame->GetX2())){
            if (vert) p = GetSliderPoints(pyold);
            else      p = GetSliderPoints(pxold);
            gVirtualX->DrawPolyLine(5,p);
            delete [] p;
            if (vert) p = GetBindingLinePoints(pyold,mindragged);
            else p = GetBindingLinePoints(pxold,mindragged);
            gVirtualX->DrawPolyLine(2,p);
            delete [] p;
            if (mouseonmin) {
               if (vert) p = GetSliderPoints(pyold+pminmax);
               else      p = GetSliderPoints(pxold+pminmax);
               gVirtualX->DrawPolyLine(5,p);
               delete [] p;
            } else {
               if (vert) p = GetSliderPoints(pyold-pminmax);
               else      p = GetSliderPoints(pxold-pminmax);
               gVirtualX->DrawPolyLine(5,p);
               delete [] p;
            }
            if (vert) p = GetSliderPoints(py);
            else      p = GetSliderPoints(px);
            gVirtualX->DrawPolyLine(5,p);
            delete [] p;
            if (vert) p = GetBindingLinePoints(py,mindragged);
            else p = GetBindingLinePoints(px,mindragged);
            gVirtualX->DrawPolyLine(2,p);
            delete [] p;
            if (mouseonmin) {
               if (vert) p = GetSliderPoints(py+pminmax);
               else      p = GetSliderPoints(px+pminmax);
               gVirtualX->DrawPolyLine(5,p);
               delete [] p;
            } else {
               if (vert) p = GetSliderPoints(py-pminmax);
               else      p = GetSliderPoints(px-pminmax);
               gVirtualX->DrawPolyLine(5,p);
               delete [] p;
            }
         }
         pxold = px;
         pyold = py;
         break*/;
      case kButton1Motion:
         if((vert && yy > frame->GetY1() && yy < frame->GetY2()) ||
            (!vert && xx > frame->GetX1() && xx < frame->GetX2())){
            if (vert) p = GetSliderPoints(pyold);
            else      p = GetSliderPoints(pxold);
            gVirtualX->DrawPolyLine(5,p);
            delete [] p;
            if (vert) p = GetBindingLinePoints(pyold,mindragged);
            else p = GetBindingLinePoints(pxold,mindragged);
            gVirtualX->DrawPolyLine(2,p);
            delete [] p;
            if (vert) p = GetSliderPoints(py);
            else      p = GetSliderPoints(px);
            gVirtualX->DrawPolyLine(5,p);
            delete [] p;
            if (vert) p = GetBindingLinePoints(py,mindragged);
            else p = GetBindingLinePoints(px,mindragged);
            gVirtualX->DrawPolyLine(2,p);
            delete [] p;
            if (TestBit(kLiveUpdate)){
               Double_t min = fMin, max= fMax;
               if (mindragged == 1) min = fVar->GetValuefromXY(xx,yy);
               if (mindragged == 0) max = fVar->GetValuefromXY(xx,yy);
               if(fMin!=min || fMax != max) {
                  if (min>max) {
                     Double_t mem = min;
                     min = max;
                     max = mem;
                  }
                  fMin = min;
                  fMax = max;
                  gPad->Modified();
                  gPad->Update();
               }
            }
         }
         pxold = px;
         pyold = py;
         break;
      default:
         //cout<<"entry: "<<entry<<endl;
         break;
   }
}


//______________________________________________________________________________
TPoint* TParallelCoordRange::GetBindingLinePoints(Int_t pos,Int_t mindragged)
{
   // return the points of the line binding the two niddles of the range.

   Double_t txx,tyy,txxo,tyyo=0;
   if (fVar->GetVert()){
      txx = fVar->GetX();
      tyy = gPad->AbsPixeltoY(pos);
   } else {
      tyy = fVar->GetY();
      txx = gPad->AbsPixeltoX(pos);
   }
   if (mindragged==1) fVar->GetXYfromValue(fMax,txxo,tyyo);
   else fVar->GetXYfromValue(fMin,txxo,tyyo);
   
   TPoint *bindline = new TPoint[2];
   if (fVar->GetVert()) {
      if (mindragged==1) {
         bindline[0] = TPoint(gPad->XtoAbsPixel(txx-2*fSize),gPad->YtoAbsPixel(tyy+fSize));
         bindline[1] = TPoint(gPad->XtoAbsPixel(txx-2*fSize),gPad->YtoAbsPixel(tyyo-fSize));
      } else {
         bindline[0] = TPoint(gPad->XtoAbsPixel(txx-2*fSize),gPad->YtoAbsPixel(tyyo+fSize));
         bindline[1] = TPoint(gPad->XtoAbsPixel(txx-2*fSize),gPad->YtoAbsPixel(tyy-fSize));
      }
   } else {
      if (mindragged==1) {
         bindline[0] = TPoint(gPad->XtoAbsPixel(txx+fSize),gPad->YtoAbsPixel(tyy-2*fSize));
         bindline[1] = TPoint(gPad->XtoAbsPixel(txxo-fSize),gPad->YtoAbsPixel(tyy-2*fSize));
      } else {
         bindline[0] = TPoint(gPad->XtoAbsPixel(txxo+fSize),gPad->YtoAbsPixel(tyy-2*fSize));
         bindline[1] = TPoint(gPad->XtoAbsPixel(txx-fSize),gPad->YtoAbsPixel(tyy-2*fSize));
      }
   }
   return bindline;
}


//______________________________________________________________________________
TPoint* TParallelCoordRange::GetSliderPoints(Double_t value)
{
   // return the points to paint the niddle at "value".

   Double_t txx=0,tyy=0;
   fVar->GetXYfromValue(value,txx,tyy);
   Int_t tx[5];
   Int_t ty[5];
   if (fVar->GetVert()) {
      tx[0]=gPad->XtoAbsPixel(txx);
      tx[1]=tx[4]=gPad->XtoAbsPixel(txx-fSize);
      ty[0]=ty[1]=ty[4]=gPad->YtoAbsPixel(tyy);
      tx[2]=tx[3]=gPad->XtoAbsPixel(txx-2*fSize);
      ty[2]=gPad->YtoAbsPixel(tyy+fSize);
      ty[3]=gPad->YtoAbsPixel(tyy-fSize);
   } else {
      ty[0]=gPad->YtoAbsPixel(tyy);
      ty[1]=ty[4]=gPad->YtoAbsPixel(tyy-fSize);
      tx[0]=tx[1]=tx[4]=gPad->XtoAbsPixel(txx);
      ty[2]=ty[3]=gPad->YtoAbsPixel(tyy-2*fSize);
      tx[2]=gPad->XtoAbsPixel(txx-fSize);
      tx[3]=gPad->XtoAbsPixel(txx+fSize);
   }
   TPoint *slider = new TPoint[5];
   for(UInt_t ui=0;ui<5;++ui) slider[ui] = TPoint(tx[ui],ty[ui]);
   return slider;
}


//______________________________________________________________________________
TPoint* TParallelCoordRange::GetSliderPoints(Int_t pos)
{
   //  return the points to paint the niddle at "pos".

   Double_t txx,tyy;
   if (fVar->GetVert()){
      txx = fVar->GetX();
      tyy = gPad->AbsPixeltoY(pos);
   } else {
      tyy = fVar->GetY();
      txx = gPad->AbsPixeltoX(pos);
   }
   
   Int_t tx[5];
   Int_t ty[5];
   if (fVar->GetVert()) {
      tx[0]=gPad->XtoAbsPixel(txx);
      tx[1]=tx[4]=gPad->XtoAbsPixel(txx-fSize);
      ty[0]=ty[1]=ty[4]=gPad->YtoAbsPixel(tyy);
      tx[2]=tx[3]=gPad->XtoAbsPixel(txx-2*fSize);
      ty[2]=gPad->YtoAbsPixel(tyy+fSize);
      ty[3]=gPad->YtoAbsPixel(tyy-fSize);
   } else {
      ty[0]=gPad->YtoAbsPixel(tyy);
      ty[1]=ty[4]=gPad->YtoAbsPixel(tyy-fSize);
      tx[0]=tx[1]=tx[4]=gPad->XtoAbsPixel(txx);
      ty[2]=ty[3]=gPad->YtoAbsPixel(tyy-2*fSize);
      tx[2]=gPad->XtoAbsPixel(txx-fSize);
      tx[3]=gPad->XtoAbsPixel(txx+fSize);
   }
   TPoint *slider = new TPoint[5];
   for(UInt_t ui=0;ui<5;++ui) slider[ui] = TPoint(tx[ui],ty[ui]);
   return slider;
}


//______________________________________________________________________________
Bool_t TParallelCoordRange::IsIn(Double_t evtval)
{
   // Evaluate if the given value is within the range or not.

   return evtval>=fMin && evtval<=fMax;
}


//______________________________________________________________________________
void TParallelCoordRange::Paint(Option_t* /*options*/)
{
   // Paint a TParallelCoordRange

   if(TestBit(kShowOnPad)){
      PaintSlider(fMin,kTRUE);
      PaintSlider(fMax,kTRUE);
   }
}


//______________________________________________________________________________
void TParallelCoordRange::PaintSlider(Double_t value, Bool_t fill)
{
   // Paint a slider.
   
   SetLineColor(fSelect->GetLineColor());
   
   TPolyLine *p= new TPolyLine();
   p->SetLineStyle(1);
   p->SetLineColor(1);
   p->SetLineWidth(1);
   
   Double_t *x = new Double_t[5];
   Double_t *y = new Double_t[5];
   
   Double_t xx,yy;
   
   fVar->GetXYfromValue(value,xx,yy);
   if(fVar->GetVert()){
      x[0] = xx; x[1]=x[4]=xx-fSize; x[2]=x[3]=xx-2*fSize;
      y[0]=y[1]=y[4]=yy; y[2] = yy+fSize; y[3] = yy-fSize;
   } else {
      y[0] = yy; y[1]=y[4]=yy-fSize; y[2]=y[3]= yy-2*fSize;
      x[0]=x[1]=x[4]=xx; x[2]=xx-fSize; x[3] = xx+fSize;
   }
   if (fill) {     
      p->SetFillStyle(1001);
      p->SetFillColor(0);
      p->PaintPolyLine(4,&x[1],&y[1],"f");
      p->SetFillColor(GetLineColor());
      p->SetFillStyle(3001);
      p->PaintPolyLine(4,&x[1],&y[1],"f");
   }
   p->PaintPolyLine(5,x,y);
   
   delete p;
   delete [] x;
   delete [] y;
}


//______________________________________________________________________________
void TParallelCoordRange::Print(Option_t* /*options*/) const
{
   // Print info about the range.
   
   printf("On \"%s\" : min = %f, max = %f\n", fVar->GetTitle(), fMin, fMax);
}


//______________________________________________________________________________
void TParallelCoordRange::SendToBack()
{
   // Make the selection which owns the range to be drawn under all the others.

   TList *list = fVar->GetParallel()->GetSelectList();
   list->Remove(fSelect);
   list->AddFirst(fSelect);
   gPad->Update();
}


//______________________________________________________________________________
void  TParallelCoordRange::SetLineColor(Color_t col)
{
   // Set the selection line color.

   fSelect->SetLineColor(col);
   TAttLine::SetLineColor(col);
}


//______________________________________________________________________________
void  TParallelCoordRange::SetLineWidth(Width_t wid)
{
   // Set the selection line width.

   fSelect->SetLineWidth(wid);
}


ClassImp(TParallelCoordSelect)
//______________________________________________________________________________
/* Begin_Html
<center><h2>Selections:</h2></center>
<p>
A TParallelCoordSelect is a specialised TList to hold TParallelCoordRanges used by TParallelCoord.
<p>
Selections of specific entries can be defined over the data se using parallel coordinates. With that representation, a selection is an ensemble of ranges defined on the axes. Ranges defined on the same axis are conjugated with OR (an entry must be in one or the other ranges to be selected). Ranges on different axes are are conjugated with AND (an entry must be in all the ranges to be selected). Several selections can be defined with different colors. It is possible to generate an entry list from a given selection and apply it to the tree using the editor ("Apply to tree" button).
End_Html
*/


//______________________________________________________________________________
TParallelCoordSelect::TParallelCoordSelect()
   : TList(), TAttLine(kBlue,1,1)
{
   // Default constructor.
   
   fTitle = "Selection";
   SetBit(kActivated,kTRUE);
   SetBit(kShowRanges,kTRUE);
}


//______________________________________________________________________________
TParallelCoordSelect::TParallelCoordSelect(const char* title)
   : TList(), TAttLine(kBlue,1,1)
{
   // Normal constructor.
   
   fTitle = title;
   SetBit(kActivated,kTRUE);
   SetBit(kShowRanges,kTRUE);
}


//______________________________________________________________________________
TParallelCoordSelect::~TParallelCoordSelect()
{
   // Destructor.

   TIter next(this);
   TParallelCoordRange* range;
   while ((range = (TParallelCoordRange*)next())) range->GetVar()->GetRanges()->Remove(range);
   TList::Delete();
}


//______________________________________________________________________________
void TParallelCoordSelect::SetActivated(Bool_t on)
{
   // Activate the selection.

   TIter next(this);
   TParallelCoordRange* range;
   while ((range = (TParallelCoordRange*)next())) range->SetBit(TParallelCoordRange::kShowOnPad,on);
   SetBit(kActivated,on);
}


//______________________________________________________________________________
void TParallelCoordSelect::SetShowRanges(Bool_t s)
{
   // Show the ranges niddles.

   TIter next(this);
   TParallelCoordRange* range;
   while ((range = (TParallelCoordRange*)next())) range->SetBit(TParallelCoordRange::kShowOnPad,s);
   SetBit(kShowRanges,s);
}
 TParallelCoordRange.cxx:1
 TParallelCoordRange.cxx:2
 TParallelCoordRange.cxx:3
 TParallelCoordRange.cxx:4
 TParallelCoordRange.cxx:5
 TParallelCoordRange.cxx:6
 TParallelCoordRange.cxx:7
 TParallelCoordRange.cxx:8
 TParallelCoordRange.cxx:9
 TParallelCoordRange.cxx:10
 TParallelCoordRange.cxx:11
 TParallelCoordRange.cxx:12
 TParallelCoordRange.cxx:13
 TParallelCoordRange.cxx:14
 TParallelCoordRange.cxx:15
 TParallelCoordRange.cxx:16
 TParallelCoordRange.cxx:17
 TParallelCoordRange.cxx:18
 TParallelCoordRange.cxx:19
 TParallelCoordRange.cxx:20
 TParallelCoordRange.cxx:21
 TParallelCoordRange.cxx:22
 TParallelCoordRange.cxx:23
 TParallelCoordRange.cxx:24
 TParallelCoordRange.cxx:25
 TParallelCoordRange.cxx:26
 TParallelCoordRange.cxx:27
 TParallelCoordRange.cxx:28
 TParallelCoordRange.cxx:29
 TParallelCoordRange.cxx:30
 TParallelCoordRange.cxx:31
 TParallelCoordRange.cxx:32
 TParallelCoordRange.cxx:33
 TParallelCoordRange.cxx:34
 TParallelCoordRange.cxx:35
 TParallelCoordRange.cxx:36
 TParallelCoordRange.cxx:37
 TParallelCoordRange.cxx:38
 TParallelCoordRange.cxx:39
 TParallelCoordRange.cxx:40
 TParallelCoordRange.cxx:41
 TParallelCoordRange.cxx:42
 TParallelCoordRange.cxx:43
 TParallelCoordRange.cxx:44
 TParallelCoordRange.cxx:45
 TParallelCoordRange.cxx:46
 TParallelCoordRange.cxx:47
 TParallelCoordRange.cxx:48
 TParallelCoordRange.cxx:49
 TParallelCoordRange.cxx:50
 TParallelCoordRange.cxx:51
 TParallelCoordRange.cxx:52
 TParallelCoordRange.cxx:53
 TParallelCoordRange.cxx:54
 TParallelCoordRange.cxx:55
 TParallelCoordRange.cxx:56
 TParallelCoordRange.cxx:57
 TParallelCoordRange.cxx:58
 TParallelCoordRange.cxx:59
 TParallelCoordRange.cxx:60
 TParallelCoordRange.cxx:61
 TParallelCoordRange.cxx:62
 TParallelCoordRange.cxx:63
 TParallelCoordRange.cxx:64
 TParallelCoordRange.cxx:65
 TParallelCoordRange.cxx:66
 TParallelCoordRange.cxx:67
 TParallelCoordRange.cxx:68
 TParallelCoordRange.cxx:69
 TParallelCoordRange.cxx:70
 TParallelCoordRange.cxx:71
 TParallelCoordRange.cxx:72
 TParallelCoordRange.cxx:73
 TParallelCoordRange.cxx:74
 TParallelCoordRange.cxx:75
 TParallelCoordRange.cxx:76
 TParallelCoordRange.cxx:77
 TParallelCoordRange.cxx:78
 TParallelCoordRange.cxx:79
 TParallelCoordRange.cxx:80
 TParallelCoordRange.cxx:81
 TParallelCoordRange.cxx:82
 TParallelCoordRange.cxx:83
 TParallelCoordRange.cxx:84
 TParallelCoordRange.cxx:85
 TParallelCoordRange.cxx:86
 TParallelCoordRange.cxx:87
 TParallelCoordRange.cxx:88
 TParallelCoordRange.cxx:89
 TParallelCoordRange.cxx:90
 TParallelCoordRange.cxx:91
 TParallelCoordRange.cxx:92
 TParallelCoordRange.cxx:93
 TParallelCoordRange.cxx:94
 TParallelCoordRange.cxx:95
 TParallelCoordRange.cxx:96
 TParallelCoordRange.cxx:97
 TParallelCoordRange.cxx:98
 TParallelCoordRange.cxx:99
 TParallelCoordRange.cxx:100
 TParallelCoordRange.cxx:101
 TParallelCoordRange.cxx:102
 TParallelCoordRange.cxx:103
 TParallelCoordRange.cxx:104
 TParallelCoordRange.cxx:105
 TParallelCoordRange.cxx:106
 TParallelCoordRange.cxx:107
 TParallelCoordRange.cxx:108
 TParallelCoordRange.cxx:109
 TParallelCoordRange.cxx:110
 TParallelCoordRange.cxx:111
 TParallelCoordRange.cxx:112
 TParallelCoordRange.cxx:113
 TParallelCoordRange.cxx:114
 TParallelCoordRange.cxx:115
 TParallelCoordRange.cxx:116
 TParallelCoordRange.cxx:117
 TParallelCoordRange.cxx:118
 TParallelCoordRange.cxx:119
 TParallelCoordRange.cxx:120
 TParallelCoordRange.cxx:121
 TParallelCoordRange.cxx:122
 TParallelCoordRange.cxx:123
 TParallelCoordRange.cxx:124
 TParallelCoordRange.cxx:125
 TParallelCoordRange.cxx:126
 TParallelCoordRange.cxx:127
 TParallelCoordRange.cxx:128
 TParallelCoordRange.cxx:129
 TParallelCoordRange.cxx:130
 TParallelCoordRange.cxx:131
 TParallelCoordRange.cxx:132
 TParallelCoordRange.cxx:133
 TParallelCoordRange.cxx:134
 TParallelCoordRange.cxx:135
 TParallelCoordRange.cxx:136
 TParallelCoordRange.cxx:137
 TParallelCoordRange.cxx:138
 TParallelCoordRange.cxx:139
 TParallelCoordRange.cxx:140
 TParallelCoordRange.cxx:141
 TParallelCoordRange.cxx:142
 TParallelCoordRange.cxx:143
 TParallelCoordRange.cxx:144
 TParallelCoordRange.cxx:145
 TParallelCoordRange.cxx:146
 TParallelCoordRange.cxx:147
 TParallelCoordRange.cxx:148
 TParallelCoordRange.cxx:149
 TParallelCoordRange.cxx:150
 TParallelCoordRange.cxx:151
 TParallelCoordRange.cxx:152
 TParallelCoordRange.cxx:153
 TParallelCoordRange.cxx:154
 TParallelCoordRange.cxx:155
 TParallelCoordRange.cxx:156
 TParallelCoordRange.cxx:157
 TParallelCoordRange.cxx:158
 TParallelCoordRange.cxx:159
 TParallelCoordRange.cxx:160
 TParallelCoordRange.cxx:161
 TParallelCoordRange.cxx:162
 TParallelCoordRange.cxx:163
 TParallelCoordRange.cxx:164
 TParallelCoordRange.cxx:165
 TParallelCoordRange.cxx:166
 TParallelCoordRange.cxx:167
 TParallelCoordRange.cxx:168
 TParallelCoordRange.cxx:169
 TParallelCoordRange.cxx:170
 TParallelCoordRange.cxx:171
 TParallelCoordRange.cxx:172
 TParallelCoordRange.cxx:173
 TParallelCoordRange.cxx:174
 TParallelCoordRange.cxx:175
 TParallelCoordRange.cxx:176
 TParallelCoordRange.cxx:177
 TParallelCoordRange.cxx:178
 TParallelCoordRange.cxx:179
 TParallelCoordRange.cxx:180
 TParallelCoordRange.cxx:181
 TParallelCoordRange.cxx:182
 TParallelCoordRange.cxx:183
 TParallelCoordRange.cxx:184
 TParallelCoordRange.cxx:185
 TParallelCoordRange.cxx:186
 TParallelCoordRange.cxx:187
 TParallelCoordRange.cxx:188
 TParallelCoordRange.cxx:189
 TParallelCoordRange.cxx:190
 TParallelCoordRange.cxx:191
 TParallelCoordRange.cxx:192
 TParallelCoordRange.cxx:193
 TParallelCoordRange.cxx:194
 TParallelCoordRange.cxx:195
 TParallelCoordRange.cxx:196
 TParallelCoordRange.cxx:197
 TParallelCoordRange.cxx:198
 TParallelCoordRange.cxx:199
 TParallelCoordRange.cxx:200
 TParallelCoordRange.cxx:201
 TParallelCoordRange.cxx:202
 TParallelCoordRange.cxx:203
 TParallelCoordRange.cxx:204
 TParallelCoordRange.cxx:205
 TParallelCoordRange.cxx:206
 TParallelCoordRange.cxx:207
 TParallelCoordRange.cxx:208
 TParallelCoordRange.cxx:209
 TParallelCoordRange.cxx:210
 TParallelCoordRange.cxx:211
 TParallelCoordRange.cxx:212
 TParallelCoordRange.cxx:213
 TParallelCoordRange.cxx:214
 TParallelCoordRange.cxx:215
 TParallelCoordRange.cxx:216
 TParallelCoordRange.cxx:217
 TParallelCoordRange.cxx:218
 TParallelCoordRange.cxx:219
 TParallelCoordRange.cxx:220
 TParallelCoordRange.cxx:221
 TParallelCoordRange.cxx:222
 TParallelCoordRange.cxx:223
 TParallelCoordRange.cxx:224
 TParallelCoordRange.cxx:225
 TParallelCoordRange.cxx:226
 TParallelCoordRange.cxx:227
 TParallelCoordRange.cxx:228
 TParallelCoordRange.cxx:229
 TParallelCoordRange.cxx:230
 TParallelCoordRange.cxx:231
 TParallelCoordRange.cxx:232
 TParallelCoordRange.cxx:233
 TParallelCoordRange.cxx:234
 TParallelCoordRange.cxx:235
 TParallelCoordRange.cxx:236
 TParallelCoordRange.cxx:237
 TParallelCoordRange.cxx:238
 TParallelCoordRange.cxx:239
 TParallelCoordRange.cxx:240
 TParallelCoordRange.cxx:241
 TParallelCoordRange.cxx:242
 TParallelCoordRange.cxx:243
 TParallelCoordRange.cxx:244
 TParallelCoordRange.cxx:245
 TParallelCoordRange.cxx:246
 TParallelCoordRange.cxx:247
 TParallelCoordRange.cxx:248
 TParallelCoordRange.cxx:249
 TParallelCoordRange.cxx:250
 TParallelCoordRange.cxx:251
 TParallelCoordRange.cxx:252
 TParallelCoordRange.cxx:253
 TParallelCoordRange.cxx:254
 TParallelCoordRange.cxx:255
 TParallelCoordRange.cxx:256
 TParallelCoordRange.cxx:257
 TParallelCoordRange.cxx:258
 TParallelCoordRange.cxx:259
 TParallelCoordRange.cxx:260
 TParallelCoordRange.cxx:261
 TParallelCoordRange.cxx:262
 TParallelCoordRange.cxx:263
 TParallelCoordRange.cxx:264
 TParallelCoordRange.cxx:265
 TParallelCoordRange.cxx:266
 TParallelCoordRange.cxx:267
 TParallelCoordRange.cxx:268
 TParallelCoordRange.cxx:269
 TParallelCoordRange.cxx:270
 TParallelCoordRange.cxx:271
 TParallelCoordRange.cxx:272
 TParallelCoordRange.cxx:273
 TParallelCoordRange.cxx:274
 TParallelCoordRange.cxx:275
 TParallelCoordRange.cxx:276
 TParallelCoordRange.cxx:277
 TParallelCoordRange.cxx:278
 TParallelCoordRange.cxx:279
 TParallelCoordRange.cxx:280
 TParallelCoordRange.cxx:281
 TParallelCoordRange.cxx:282
 TParallelCoordRange.cxx:283
 TParallelCoordRange.cxx:284
 TParallelCoordRange.cxx:285
 TParallelCoordRange.cxx:286
 TParallelCoordRange.cxx:287
 TParallelCoordRange.cxx:288
 TParallelCoordRange.cxx:289
 TParallelCoordRange.cxx:290
 TParallelCoordRange.cxx:291
 TParallelCoordRange.cxx:292
 TParallelCoordRange.cxx:293
 TParallelCoordRange.cxx:294
 TParallelCoordRange.cxx:295
 TParallelCoordRange.cxx:296
 TParallelCoordRange.cxx:297
 TParallelCoordRange.cxx:298
 TParallelCoordRange.cxx:299
 TParallelCoordRange.cxx:300
 TParallelCoordRange.cxx:301
 TParallelCoordRange.cxx:302
 TParallelCoordRange.cxx:303
 TParallelCoordRange.cxx:304
 TParallelCoordRange.cxx:305
 TParallelCoordRange.cxx:306
 TParallelCoordRange.cxx:307
 TParallelCoordRange.cxx:308
 TParallelCoordRange.cxx:309
 TParallelCoordRange.cxx:310
 TParallelCoordRange.cxx:311
 TParallelCoordRange.cxx:312
 TParallelCoordRange.cxx:313
 TParallelCoordRange.cxx:314
 TParallelCoordRange.cxx:315
 TParallelCoordRange.cxx:316
 TParallelCoordRange.cxx:317
 TParallelCoordRange.cxx:318
 TParallelCoordRange.cxx:319
 TParallelCoordRange.cxx:320
 TParallelCoordRange.cxx:321
 TParallelCoordRange.cxx:322
 TParallelCoordRange.cxx:323
 TParallelCoordRange.cxx:324
 TParallelCoordRange.cxx:325
 TParallelCoordRange.cxx:326
 TParallelCoordRange.cxx:327
 TParallelCoordRange.cxx:328
 TParallelCoordRange.cxx:329
 TParallelCoordRange.cxx:330
 TParallelCoordRange.cxx:331
 TParallelCoordRange.cxx:332
 TParallelCoordRange.cxx:333
 TParallelCoordRange.cxx:334
 TParallelCoordRange.cxx:335
 TParallelCoordRange.cxx:336
 TParallelCoordRange.cxx:337
 TParallelCoordRange.cxx:338
 TParallelCoordRange.cxx:339
 TParallelCoordRange.cxx:340
 TParallelCoordRange.cxx:341
 TParallelCoordRange.cxx:342
 TParallelCoordRange.cxx:343
 TParallelCoordRange.cxx:344
 TParallelCoordRange.cxx:345
 TParallelCoordRange.cxx:346
 TParallelCoordRange.cxx:347
 TParallelCoordRange.cxx:348
 TParallelCoordRange.cxx:349
 TParallelCoordRange.cxx:350
 TParallelCoordRange.cxx:351
 TParallelCoordRange.cxx:352
 TParallelCoordRange.cxx:353
 TParallelCoordRange.cxx:354
 TParallelCoordRange.cxx:355
 TParallelCoordRange.cxx:356
 TParallelCoordRange.cxx:357
 TParallelCoordRange.cxx:358
 TParallelCoordRange.cxx:359
 TParallelCoordRange.cxx:360
 TParallelCoordRange.cxx:361
 TParallelCoordRange.cxx:362
 TParallelCoordRange.cxx:363
 TParallelCoordRange.cxx:364
 TParallelCoordRange.cxx:365
 TParallelCoordRange.cxx:366
 TParallelCoordRange.cxx:367
 TParallelCoordRange.cxx:368
 TParallelCoordRange.cxx:369
 TParallelCoordRange.cxx:370
 TParallelCoordRange.cxx:371
 TParallelCoordRange.cxx:372
 TParallelCoordRange.cxx:373
 TParallelCoordRange.cxx:374
 TParallelCoordRange.cxx:375
 TParallelCoordRange.cxx:376
 TParallelCoordRange.cxx:377
 TParallelCoordRange.cxx:378
 TParallelCoordRange.cxx:379
 TParallelCoordRange.cxx:380
 TParallelCoordRange.cxx:381
 TParallelCoordRange.cxx:382
 TParallelCoordRange.cxx:383
 TParallelCoordRange.cxx:384
 TParallelCoordRange.cxx:385
 TParallelCoordRange.cxx:386
 TParallelCoordRange.cxx:387
 TParallelCoordRange.cxx:388
 TParallelCoordRange.cxx:389
 TParallelCoordRange.cxx:390
 TParallelCoordRange.cxx:391
 TParallelCoordRange.cxx:392
 TParallelCoordRange.cxx:393
 TParallelCoordRange.cxx:394
 TParallelCoordRange.cxx:395
 TParallelCoordRange.cxx:396
 TParallelCoordRange.cxx:397
 TParallelCoordRange.cxx:398
 TParallelCoordRange.cxx:399
 TParallelCoordRange.cxx:400
 TParallelCoordRange.cxx:401
 TParallelCoordRange.cxx:402
 TParallelCoordRange.cxx:403
 TParallelCoordRange.cxx:404
 TParallelCoordRange.cxx:405
 TParallelCoordRange.cxx:406
 TParallelCoordRange.cxx:407
 TParallelCoordRange.cxx:408
 TParallelCoordRange.cxx:409
 TParallelCoordRange.cxx:410
 TParallelCoordRange.cxx:411
 TParallelCoordRange.cxx:412
 TParallelCoordRange.cxx:413
 TParallelCoordRange.cxx:414
 TParallelCoordRange.cxx:415
 TParallelCoordRange.cxx:416
 TParallelCoordRange.cxx:417
 TParallelCoordRange.cxx:418
 TParallelCoordRange.cxx:419
 TParallelCoordRange.cxx:420
 TParallelCoordRange.cxx:421
 TParallelCoordRange.cxx:422
 TParallelCoordRange.cxx:423
 TParallelCoordRange.cxx:424
 TParallelCoordRange.cxx:425
 TParallelCoordRange.cxx:426
 TParallelCoordRange.cxx:427
 TParallelCoordRange.cxx:428
 TParallelCoordRange.cxx:429
 TParallelCoordRange.cxx:430
 TParallelCoordRange.cxx:431
 TParallelCoordRange.cxx:432
 TParallelCoordRange.cxx:433
 TParallelCoordRange.cxx:434
 TParallelCoordRange.cxx:435
 TParallelCoordRange.cxx:436
 TParallelCoordRange.cxx:437
 TParallelCoordRange.cxx:438
 TParallelCoordRange.cxx:439
 TParallelCoordRange.cxx:440
 TParallelCoordRange.cxx:441
 TParallelCoordRange.cxx:442
 TParallelCoordRange.cxx:443
 TParallelCoordRange.cxx:444
 TParallelCoordRange.cxx:445
 TParallelCoordRange.cxx:446
 TParallelCoordRange.cxx:447
 TParallelCoordRange.cxx:448
 TParallelCoordRange.cxx:449
 TParallelCoordRange.cxx:450
 TParallelCoordRange.cxx:451
 TParallelCoordRange.cxx:452
 TParallelCoordRange.cxx:453
 TParallelCoordRange.cxx:454
 TParallelCoordRange.cxx:455
 TParallelCoordRange.cxx:456
 TParallelCoordRange.cxx:457
 TParallelCoordRange.cxx:458
 TParallelCoordRange.cxx:459
 TParallelCoordRange.cxx:460
 TParallelCoordRange.cxx:461
 TParallelCoordRange.cxx:462
 TParallelCoordRange.cxx:463
 TParallelCoordRange.cxx:464
 TParallelCoordRange.cxx:465
 TParallelCoordRange.cxx:466
 TParallelCoordRange.cxx:467
 TParallelCoordRange.cxx:468
 TParallelCoordRange.cxx:469
 TParallelCoordRange.cxx:470
 TParallelCoordRange.cxx:471
 TParallelCoordRange.cxx:472
 TParallelCoordRange.cxx:473
 TParallelCoordRange.cxx:474
 TParallelCoordRange.cxx:475
 TParallelCoordRange.cxx:476
 TParallelCoordRange.cxx:477
 TParallelCoordRange.cxx:478
 TParallelCoordRange.cxx:479
 TParallelCoordRange.cxx:480
 TParallelCoordRange.cxx:481
 TParallelCoordRange.cxx:482
 TParallelCoordRange.cxx:483
 TParallelCoordRange.cxx:484
 TParallelCoordRange.cxx:485
 TParallelCoordRange.cxx:486
 TParallelCoordRange.cxx:487
 TParallelCoordRange.cxx:488
 TParallelCoordRange.cxx:489
 TParallelCoordRange.cxx:490
 TParallelCoordRange.cxx:491
 TParallelCoordRange.cxx:492
 TParallelCoordRange.cxx:493
 TParallelCoordRange.cxx:494
 TParallelCoordRange.cxx:495
 TParallelCoordRange.cxx:496
 TParallelCoordRange.cxx:497
 TParallelCoordRange.cxx:498
 TParallelCoordRange.cxx:499
 TParallelCoordRange.cxx:500
 TParallelCoordRange.cxx:501
 TParallelCoordRange.cxx:502
 TParallelCoordRange.cxx:503
 TParallelCoordRange.cxx:504
 TParallelCoordRange.cxx:505
 TParallelCoordRange.cxx:506
 TParallelCoordRange.cxx:507
 TParallelCoordRange.cxx:508
 TParallelCoordRange.cxx:509
 TParallelCoordRange.cxx:510
 TParallelCoordRange.cxx:511
 TParallelCoordRange.cxx:512
 TParallelCoordRange.cxx:513
 TParallelCoordRange.cxx:514
 TParallelCoordRange.cxx:515
 TParallelCoordRange.cxx:516
 TParallelCoordRange.cxx:517
 TParallelCoordRange.cxx:518
 TParallelCoordRange.cxx:519
 TParallelCoordRange.cxx:520
 TParallelCoordRange.cxx:521
 TParallelCoordRange.cxx:522
 TParallelCoordRange.cxx:523
 TParallelCoordRange.cxx:524
 TParallelCoordRange.cxx:525
 TParallelCoordRange.cxx:526
 TParallelCoordRange.cxx:527
 TParallelCoordRange.cxx:528
 TParallelCoordRange.cxx:529
 TParallelCoordRange.cxx:530
 TParallelCoordRange.cxx:531
 TParallelCoordRange.cxx:532
 TParallelCoordRange.cxx:533
 TParallelCoordRange.cxx:534
 TParallelCoordRange.cxx:535
 TParallelCoordRange.cxx:536
 TParallelCoordRange.cxx:537
 TParallelCoordRange.cxx:538
 TParallelCoordRange.cxx:539
 TParallelCoordRange.cxx:540
 TParallelCoordRange.cxx:541
 TParallelCoordRange.cxx:542
 TParallelCoordRange.cxx:543
 TParallelCoordRange.cxx:544
 TParallelCoordRange.cxx:545
 TParallelCoordRange.cxx:546
 TParallelCoordRange.cxx:547
 TParallelCoordRange.cxx:548
 TParallelCoordRange.cxx:549
 TParallelCoordRange.cxx:550
 TParallelCoordRange.cxx:551
 TParallelCoordRange.cxx:552
 TParallelCoordRange.cxx:553
 TParallelCoordRange.cxx:554
 TParallelCoordRange.cxx:555
 TParallelCoordRange.cxx:556
 TParallelCoordRange.cxx:557
 TParallelCoordRange.cxx:558
 TParallelCoordRange.cxx:559
 TParallelCoordRange.cxx:560
 TParallelCoordRange.cxx:561
 TParallelCoordRange.cxx:562
 TParallelCoordRange.cxx:563
 TParallelCoordRange.cxx:564
 TParallelCoordRange.cxx:565
 TParallelCoordRange.cxx:566
 TParallelCoordRange.cxx:567
 TParallelCoordRange.cxx:568
 TParallelCoordRange.cxx:569
 TParallelCoordRange.cxx:570
 TParallelCoordRange.cxx:571
 TParallelCoordRange.cxx:572
 TParallelCoordRange.cxx:573
 TParallelCoordRange.cxx:574
 TParallelCoordRange.cxx:575
 TParallelCoordRange.cxx:576
 TParallelCoordRange.cxx:577
 TParallelCoordRange.cxx:578
 TParallelCoordRange.cxx:579
 TParallelCoordRange.cxx:580
 TParallelCoordRange.cxx:581
 TParallelCoordRange.cxx:582
 TParallelCoordRange.cxx:583
 TParallelCoordRange.cxx:584
 TParallelCoordRange.cxx:585
 TParallelCoordRange.cxx:586
 TParallelCoordRange.cxx:587
 TParallelCoordRange.cxx:588
 TParallelCoordRange.cxx:589
 TParallelCoordRange.cxx:590
 TParallelCoordRange.cxx:591
 TParallelCoordRange.cxx:592
 TParallelCoordRange.cxx:593
 TParallelCoordRange.cxx:594