<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkTableToGraph.cxx

  Copyright (c) <NAME>, <NAME>, <NAME>
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

#include "vtkTableToGraph.h"

#include "vtkBitArray.h"
#include "vtkCellData.h"
#include "vtkCommand.h"
#include "vtkDataArray.h"
#include "vtkEdgeListIterator.h"
#include "vtkExecutive.h"
#include "vtkGraph.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkIntArray.h"
#include "vtkMutableDirectedGraph.h"
#include "vtkMutableUndirectedGraph.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkSmartPointer.h"
#include "vtkStringArray.h"
#include "vtkTable.h"
#include "vtkVariant.h"
#include "vtkVariantArray.h"

#include <vtksys/stl/algorithm>
#include <vtksys/stl/map>
#include <vtksys/stl/set>
#include <vtksys/stl/vector>

#define VTK_CREATE(type, name) \
  vtkSmartPointer<type> name = vtkSmartPointer<type>::New()

vtkCxxRevisionMacro(vtkTableToGraph, "1.6");
vtkStandardNewMacro(vtkTableToGraph);
vtkCxxSetObjectMacro(vtkTableToGraph, LinkGraph, vtkMutableDirectedGraph);
//---------------------------------------------------------------------------
vtkTableToGraph::vtkTableToGraph()
{
  this->Directed = 0;
  this->LinkGraph = vtkMutableDirectedGraph::New();
  this->SetNumberOfInputPorts(2);
  this->SetNumberOfOutputPorts(1);
}

//---------------------------------------------------------------------------
vtkTableToGraph::~vtkTableToGraph()
{
  this->SetLinkGraph(0);
}

//---------------------------------------------------------------------------
int vtkTableToGraph::ValidateLinkGraph()
{
  if (!this->LinkGraph)
    {
    this->LinkGraph = vtkMutableDirectedGraph::New();
    }
  if (!vtkStringArray::SafeDownCast(
      this->LinkGraph->GetVertexData()->GetAbstractArray("column")))
    {
    if (this->LinkGraph->GetNumberOfVertices() == 0)
      {
      vtkStringArray* column = vtkStringArray::New();
      column->SetName("column");
      this->LinkGraph->GetVertexData()->AddArray(column);
      column->Delete();
      this->Modified();
      }
    else
      {
      vtkErrorMacro("The link graph must contain a string array named \"column\".");
      return 0;
      }
    }
  if (!vtkStringArray::SafeDownCast(
      this->LinkGraph->GetVertexData()->GetAbstractArray("domain")))
    {
    vtkStringArray* domain = vtkStringArray::New();
    domain->SetName("domain");
    domain->SetNumberOfTuples(this->LinkGraph->GetNumberOfVertices());
    for (vtkIdType i = 0; i < this->LinkGraph->GetNumberOfVertices(); i++)
      {
      domain->SetValue(i, "");
      }
    this->LinkGraph->GetVertexData()->AddArray(domain);
    domain->Delete();
    this->Modified();
    }
  if (!vtkBitArray::SafeDownCast(
      this->LinkGraph->GetVertexData()->GetAbstractArray("hidden")))
    {
    vtkBitArray* hidden = vtkBitArray::New();
    hidden->SetName("hidden");
    hidden->SetNumberOfTuples(this->LinkGraph->GetNumberOfVertices());
    this->LinkGraph->GetVertexData()->AddArray(hidden);
    hidden->Delete();
    this->Modified();
    }
  return 1;
}

//---------------------------------------------------------------------------
void vtkTableToGraph::AddLinkVertex(const char* column, const char* domain, int hidden)
{
  if (!column)
    {
    vtkErrorMacro("Column name cannot be null");
    }
  
  vtkStdString domainStr = "";
  if (domain)
    {
    domainStr = domain;
    }
  
  if (!this->ValidateLinkGraph())
    {
    return;
    }
  
  vtkStringArray* columnArr = vtkStringArray::SafeDownCast(
      this->LinkGraph->GetVertexData()->GetAbstractArray("column"));
  vtkStringArray* domainArr = vtkStringArray::SafeDownCast(
      this->LinkGraph->GetVertexData()->GetAbstractArray("domain"));
  vtkBitArray* hiddenArr = vtkBitArray::SafeDownCast(
      this->LinkGraph->GetVertexData()->GetAbstractArray("hidden"));
  
  vtkIdType index = -1;
  for (vtkIdType i = 0; i < this->LinkGraph->GetNumberOfVertices(); i++)
    {
    if (!strcmp(column, columnArr->GetValue(i)))
      {
      index = i;
      break;
      }
    }
  if (index >= 0)
    {
    domainArr->SetValue(index, domainStr);
    hiddenArr->SetValue(index, hidden);
    }
  else
    {
    this->LinkGraph->AddVertex();
    columnArr->InsertNextValue(column);
    domainArr->InsertNextValue(domainStr);
    hiddenArr->InsertNextValue(hidden);
    }
  this->Modified();
}

//---------------------------------------------------------------------------
void vtkTableToGraph::ClearLinkVertices()
{
  if (!this->LinkGraph)
    {
    this->LinkGraph = vtkMutableDirectedGraph::New();
    }
  this->LinkGraph->Initialize();
  this->Modified();
}

//---------------------------------------------------------------------------
void vtkTableToGraph::AddLinkEdge(const char* column1, const char* column2)
{
  if (!column1 || !column2)
    {
    vtkErrorMacro("Column names may not be null.");
    }
  this->ValidateLinkGraph();
  vtkStringArray* columnArr = vtkStringArray::SafeDownCast(
      this->LinkGraph->GetVertexData()->GetAbstractArray("column"));
  vtkIdType source = -1;
  vtkIdType target = -1;
  for (vtkIdType i = 0; i < this->LinkGraph->GetNumberOfVertices(); i++)
    {
    if (!strcmp(column1, columnArr->GetValue(i)))
      {
      source = i;
      }
    if (!strcmp(column2, columnArr->GetValue(i)))
      {
      target = i;
      }
    }
  if (source < 0)
    {
    this->AddLinkVertex(column1);
    source = this->LinkGraph->GetNumberOfVertices() - 1;
    }
  if (target < 0)
    {
    this->AddLinkVertex(column2);
    target = this->LinkGraph->GetNumberOfVertices() - 1;
    }
  this->LinkGraph->AddEdge(source, target);
  this->Modified();
}

//---------------------------------------------------------------------------
void vtkTableToGraph::ClearLinkEdges()
{
  VTK_CREATE(vtkMutableDirectedGraph, newLinkGraph);
  for (vtkIdType i = 0; i < this->LinkGraph->GetNumberOfVertices(); ++i)
    {
    newLinkGraph->AddVertex();
    }
  newLinkGraph->GetVertexData()->ShallowCopy(this->LinkGraph->GetVertexData());
  this->SetLinkGraph(newLinkGraph);
}

//---------------------------------------------------------------------------
void vtkTableToGraph::LinkColumnPath(
  vtkStringArray* column, 
  vtkStringArray* domain, 
  vtkBitArray* hidden)
{
  vtkMutableDirectedGraph *g = vtkMutableDirectedGraph::New();
  for (vtkIdType i = 0; i < column->GetNumberOfTuples(); i++)
    {
    g->AddVertex();
    }
  for (vtkIdType i = 1; i < column->GetNumberOfTuples(); i++)
    {
    g->AddEdge(i-1, i);
    }
  column->SetName("column");
  g->GetVertexData()->AddArray(column);
  if (domain)
    {
    domain->SetName("domain");
    g->GetVertexData()->AddArray(domain);
    }
  if (hidden)
    {
    hidden->SetName("hidden");
    g->GetVertexData()->AddArray(hidden);
    }
  this->SetLinkGraph(g);
  g->Delete();
}

//---------------------------------------------------------------------------
int vtkTableToGraph::FillInputPortInformation(int port, vtkInformation* info)
{
  if (port == 0)
    {
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTable");
    return 1;
    }
  else if (port == 1)
    {
    info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTable");
    return 1;
    }
  return 0;
}

//---------------------------------------------------------------------------
class vtkVariantCompare
{
public:
  bool operator()(
    const vtkVariant& a, 
    const vtkVariant& b) const
  {
    if (a.GetType() != b.GetType())
      {
      return a.GetType() < b.GetType();
      }
    if (a.GetType() == VTK_STRING)
      {
      return a.ToString() < b.ToString();
      }
    else
      {
      return a.ToDouble() < b.ToDouble();
      }
  }
};

//---------------------------------------------------------------------------
class vtkTableToGraphCompare
{
public:
  bool operator()(
    const vtksys_stl::pair<vtkStdString, vtkVariant>& a, 
    const vtksys_stl::pair<vtkStdString, vtkVariant>& b) const
  {<commit_msg>BUG: vtkTableToGraph now converts numerics to doubles when comparing, instead of requiring the same underlying type.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkTableToGraph.cxx

  Copyright (c) <NAME>, <NAME>, <NAME>
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

#include "vtkTableToGraph.h"

#include "vtkBitArray.h"
#include "vtkCellData.h"
#include "vtkCommand.h"
#include "vtkDataArray.h"
#include "vtkEdgeListIterator.h"
#include "vtkExecutive.h"
#include "vtkGraph.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkIntArray.h"
#include "vtkMutableDirectedGraph.h"
#include "vtkMutableUndirectedGraph.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkSmartPointer.h"
#include "vtkStringArray.h"
#include "vtkTable.h"
#include "vtkVariant.h"
#include "vtkVariantArray.h"

#include <vtksys/stl/algorithm>
#include <vtksys/stl/map>
#include <vtksys/stl/set>
#include <vtksys/stl/vector>

#define VTK_CREATE(type, name) \
  vtkSmartPointer<type> name = vtkSmartPointer<type>::New()

vtkCxxRevisionMacro(vtkTableToGraph, "1.7");
vtkStandardNewMacro(vtkTableToGraph);
vtkCxxSetObjectMacro(vtkTableToGraph, LinkGraph, vtkMutableDirectedGraph);
//---------------------------------------------------------------------------
vtkTableToGraph::vtkTableToGraph()
{
  this->Directed = 0;
  this->LinkGraph = vtkMutableDirectedGraph::New();
  this->SetNumberOfInputPorts(2);
  this->SetNumberOfOutputPorts(1);
}

//---------------------------------------------------------------------------
vtkTableToGraph::~vtkTableToGraph()
{
  this->SetLinkGraph(0);
}

//---------------------------------------------------------------------------
int vtkTableToGraph::ValidateLinkGraph()
{
  if (!this->LinkGraph)
    {
    this->LinkGraph = vtkMutableDirectedGraph::New();
    }
  if (!vtkStringArray::SafeDownCast(
      this->LinkGraph->GetVertexData()->GetAbstractArray("column")))
    {
    if (this->LinkGraph->GetNumberOfVertices() == 0)
      {
      vtkStringArray* column = vtkStringArray::New();
      column->SetName("column");
      this->LinkGraph->GetVertexData()->AddArray(column);
      column->Delete();
      this->Modified();
      }
    else
      {
      vtkErrorMacro("The link graph must contain a string array named \"column\".");
      return 0;
      }
    }
  if (!vtkStringArray::SafeDownCast(
      this->LinkGraph->GetVertexData()->GetAbstractArray("domain")))
    {
    vtkStringArray* domain = vtkStringArray::New();
    domain->SetName("domain");
    domain->SetNumberOfTuples(this->LinkGraph->GetNumberOfVertices());
    for (vtkIdType i = 0; i < this->LinkGraph->GetNumberOfVertices(); i++)
      {
      domain->SetValue(i, "");
      }
    this->LinkGraph->GetVertexData()->AddArray(domain);
    domain->Delete();
    this->Modified();
    }
  if (!vtkBitArray::SafeDownCast(
      this->LinkGraph->GetVertexData()->GetAbstractArray("hidden")))
    {
    vtkBitArray* hidden = vtkBitArray::New();
    hidden->SetName("hidden");
    hidden->SetNumberOfTuples(this->LinkGraph->GetNumberOfVertices());
    this->LinkGraph->GetVertexData()->AddArray(hidden);
    hidden->Delete();
    this->Modified();
    }
  return 1;
}

//---------------------------------------------------------------------------
void vtkTableToGraph::AddLinkVertex(const char* column, const char* domain, int hidden)
{
  if (!column)
    {
    vtkErrorMacro("Column name cannot be null");
    }
  
  vtkStdString domainStr = "";
  if (domain)
    {
    domainStr = domain;
    }
  
  if (!this->ValidateLinkGraph())
    {
    return;
    }
  
  vtkStringArray* columnArr = vtkStringArray::SafeDownCast(
      this->LinkGraph->GetVertexData()->GetAbstractArray("column"));
  vtkStringArray* domainArr = vtkStringArray::SafeDownCast(
      this->LinkGraph->GetVertexData()->GetAbstractArray("domain"));
  vtkBitArray* hiddenArr = vtkBitArray::SafeDownCast(
      this->LinkGraph->GetVertexData()->GetAbstractArray("hidden"));
  
  vtkIdType index = -1;
  for (vtkIdType i = 0; i < this->LinkGraph->GetNumberOfVertices(); i++)
    {
    if (!strcmp(column, columnArr->GetValue(i)))
      {
      index = i;
      break;
      }
    }
  if (index >= 0)
    {
    domainArr->SetValue(index, domainStr);
    hiddenArr->SetValue(index, hidden);
    }
  else
    {
    this->LinkGraph->AddVertex();
    columnArr->InsertNextValue(column);
    domainArr->InsertNextValue(domainStr);
    hiddenArr->InsertNextValue(hidden);
    }
  this->Modified();
}

//---------------------------------------------------------------------------
void vtkTableToGraph::ClearLinkVertices()
{
  if (!this->LinkGraph)
    {
    this->LinkGraph = vtkMutableDirectedGraph::New();
    }
  this->LinkGraph->Initialize();
  this->Modified();
}

//---------------------------------------------------------------------------
void vtkTableToGraph::AddLinkEdge(const char* column1, const char* column2)
{
  if (!column1 || !column2)
    {
    vtkErrorMacro("Column names may not be null.");
    }
  this->ValidateLinkGraph();
  vtkStringArray* columnArr = vtkStringArray::SafeDownCast(
      this->LinkGraph->GetVertexData()->GetAbstractArray("column"));
  vtkIdType source = -1;
  vtkIdType target = -1;
  for (vtkIdType i = 0; i < this->LinkGraph->GetNumberOfVertices(); i++)
    {
    if (!strcmp(column1, columnArr->GetValue(i)))
      {
      source = i;
      }
    if (!strcmp(column2, columnArr->GetValue(i)))
      {
      target = i;
      }
    }
  if (source < 0)
    {
    this->AddLinkVertex(column1);
    source = this->LinkGraph->GetNumberOfVertices() - 1;
    }
  if (target < 0)
    {
    this->AddLinkVertex(column2);
    target = this->LinkGraph->GetNumberOfVertices() - 1;
    }
  this->LinkGraph->AddEdge(source, target);
  this->Modified();
}

//---------------------------------------------------------------------------
void vtkTableToGraph::ClearLinkEdges()
{
  VTK_CREATE(vtkMutableDirectedGraph, newLinkGraph);
  for (vtkIdType i = 0; i < this->LinkGraph->GetNumberOfVertices(); ++i)
    {
    newLinkGraph->AddVertex();
    }
  newLinkGraph->GetVertexData()->ShallowCopy(this->LinkGraph->GetVertexData());
  this->SetLinkGraph(newLinkGraph);
}

//---------------------------------------------------------------------------
void vtkTableToGraph::LinkColumnPath(
  vtkStringArray* column, 
  vtkStringArray* domain, 
  vtkBitArray* hidden)
{
  vtkMutableDirectedGraph *g = vtkMutableDirectedGraph::New();
  for (vtkIdType i = 0; i < column->GetNumberOfTuples(); i++)
    {
    g->AddVertex();
    }
  for (vtkIdType i = 1; i < column->GetNumberOfTuples(); i++)
    {
    g->AddEdge(i-1, i);
    }
  column->SetName("column");
  g->GetVertexData()->AddArray(column);
  if (domain)
    {
    domain->SetName("domain");
    g->GetVertexData()->AddArray(domain);
    }
  if (hidden)
    {
    hidden->SetName("hidden");
    g->GetVertexData()->AddArray(hidden);
    }
  this->SetLinkGraph(g);
  g->Delete();
}

//---------------------------------------------------------------------------
int vtkTableToGraph::FillInputPortInformation(int port, vtkInformation* info)
{
  if (port == 0)
    {
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTable");
    return 1;
    }
  else if (port == 1)
    {
    info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTable");
    return 1;
    }
  return 0;
}

//---------------------------------------------------------------------------
class vtkVariantCompare
{
public:
  bool operator()(
    const vtkVariant& a, 
    const vtkVariant& b) const
  {
    if (a.GetType() == VTK_STRING)
      {
      return a.ToString() < b.ToString();
      }
    else if (a.IsNumeric())
      {
      return a.ToDouble() < b.ToDouble();
      }
    else
      {
      // Punt, just do pointer difference.
      return &a < &b;
      }
  }
};

//---------------------------------------------------------------------------
class vtkTableToGraphCompare
{
public:
  bool operator()(
    const vtksys_stl::pair<vtkStdString, vtkVariant>& a, 
    const vtksys_stl::pair<vtkStdString, vtkVariant>& b) const
  {
{'fraction_non_alphanumeric': 0.261403708338073, 'fraction_numerical': 0.004322602661813218, 'mean_word_length': 2.3593809705769964, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 255, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '894710', 'n_tokens_mistral': 5393, 'n_tokens_neox': 5310, 'n_words': 918}