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

  Program:   Visualization Toolkit
  Module:    vtkEnSightReader.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.

=========================================================================*/
#include "vtkEnSightReader.h"

#include "vtkDataArrayCollection.h"
#include "vtkFloatArray.h"
#include "vtkIdList.h"
#include "vtkIdListCollection.h"
#include "vtkObjectFactory.h"
#include "vtkRectilinearGrid.h"
#include "vtkSmartPointer.h"
#include "vtkStructuredGrid.h"
#include "vtkStructuredPoints.h"
#include "vtkUnstructuredGrid.h"

#include <vtkstd/string>
#include <vtkstd/vector>

vtkCxxRevisionMacro(vtkEnSightReader, "1.55");

//----------------------------------------------------------------------------
typedef vtkstd::vector< vtkSmartPointer<vtkIdList> > vtkEnSightReaderCellIdsTypeBase;
class vtkEnSightReaderCellIdsType: public vtkEnSightReaderCellIdsTypeBase {};

//----------------------------------------------------------------------------
vtkEnSightReader::vtkEnSightReader()
{
  this->MeasuredFileName = NULL;
  this->MatchFileName = NULL;

  this->IS = NULL;
  
  this->VariableMode = -1;
  
  this->UnstructuredPartIds = vtkIdList::New();
  this->CellIds = NULL;
  
  this->VariableFileNames = NULL;
  this->ComplexVariableFileNames = NULL;
  
  this->VariableDescriptions = NULL;
  this->ComplexVariableDescriptions = NULL;

  this->VariableTimeSetIds = vtkIdList::New();
  this->ComplexVariableTimeSetIds = vtkIdList::New();
  this->VariableFileSetIds = vtkIdList::New();
  this->ComplexVariableFileSetIds = vtkIdList::New();

  this->TimeSetFileNameNumbers = vtkIdListCollection::New();
  this->TimeSetsWithFilenameNumbers = vtkIdList::New();
  this->TimeSets = vtkDataArrayCollection::New();
  this->FileSetFileNameNumbers = vtkIdListCollection::New();
  this->FileSetsWithFilenameNumbers = vtkIdList::New();
  this->FileSetNumberOfSteps = vtkIdListCollection::New();

  this->TimeSetIds = vtkIdList::New();
  this->FileSets = vtkIdList::New();
  
  this->GeometryTimeSet = 1;
  this->GeometryFileSet = 1;
  this->MeasuredTimeSet = 1;
  this->MeasuredFileSet = 1;
  
  this->UseTimeSets = 0;
  this->UseFileSets = 0;

  this->GeometryTimeValue = -1;
  this->MeasuredTimeValue = -1;
  
  this->NumberOfGeometryParts = 0;

  this->NumberOfMeasuredPoints = 0;
  
  this->OutputsAreValid = 1;
  this->InitialRead = 1;
  this->NumberOfNewOutputs = 0;
}

//----------------------------------------------------------------------------
vtkEnSightReader::~vtkEnSightReader()
{
  int i;

  if (this->CellIds)
    {
    delete this->CellIds;
    this->CellIds = NULL;
    }
  
  if (this->MeasuredFileName)
    {
    delete [] this->MeasuredFileName;
    this->MeasuredFileName = NULL;
    }
  if (this->MatchFileName)
    {
    delete [] this->MatchFileName;
    this->MatchFileName = NULL;
    }

  if (this->NumberOfVariables > 0)
    {
    for (i = 0; i < this->NumberOfVariables; i++)
      {
      delete [] this->VariableFileNames[i];
      }
    delete [] this->VariableFileNames;
    this->VariableFileNames = NULL;
    }

  if (this->NumberOfComplexVariables > 0)
    {
    for (i = 0; i < this->NumberOfComplexVariables*2; i++)
      {
      delete [] this->ComplexVariableFileNames[i];
      }
    delete [] this->ComplexVariableFileNames;
    this->ComplexVariableFileNames = NULL;
    }
  
  this->UnstructuredPartIds->Delete();
  this->UnstructuredPartIds = NULL;  
    
  this->VariableTimeSetIds->Delete();
  this->VariableTimeSetIds = NULL;
  this->ComplexVariableTimeSetIds->Delete();
  this->ComplexVariableTimeSetIds = NULL;
  this->VariableFileSetIds->Delete();
  this->VariableFileSetIds = NULL;
  this->ComplexVariableFileSetIds->Delete();
  this->ComplexVariableFileSetIds = NULL;
  
  this->TimeSetFileNameNumbers->Delete();
  this->TimeSetFileNameNumbers = NULL;
  this->TimeSetsWithFilenameNumbers->Delete();
  this->TimeSetsWithFilenameNumbers = NULL;
  this->TimeSets->Delete();
  this->TimeSets = NULL;
  this->FileSetFileNameNumbers->Delete();
  this->FileSetFileNameNumbers = NULL;
  this->FileSetsWithFilenameNumbers->Delete();
  this->FileSetsWithFilenameNumbers = NULL;
  this->FileSetNumberOfSteps->Delete();
  this->FileSetNumberOfSteps = NULL;
  
  this->TimeSetIds->Delete();
  this->TimeSets = NULL;
  this->FileSets->Delete();
  this->FileSets = NULL;
}

//----------------------------------------------------------------------------
void vtkEnSightReader::Execute()
{
  vtkDebugMacro("In execute ");

  int i, timeSet, fileSet, timeStep, timeStepInFile, fileNum;
  vtkDataArray *times;
  vtkIdList *numStepsList, *filenameNumbers;
  float newTime;
  int numSteps;
  char* fileName;
  int filenameNum;
  
  if ( ! this->CaseFileRead)
    {
    vtkErrorMacro("error reading case file");
    return;
    }
  
  this->OutputsAreValid = 1;
  this->NumberOfNewOutputs = 0;
  this->NumberOfGeometryParts = 0;
  if (this->GeometryFileName)
    {
    timeStep = timeStepInFile = 1;
    fileNum = 1;
    fileName = new char[strlen(this->GeometryFileName) + 1];
    strcpy(fileName, this->GeometryFileName);
    
    if (this->UseTimeSets)
      {
      timeSet = this->TimeSetIds->IsId(this->GeometryTimeSet);
      if (timeSet >= 0)
        {
        times = this->TimeSets->GetItem(timeSet);
        this->GeometryTimeValue = times->GetComponent(0, 0);
        for (i = 1; i < times->GetNumberOfTuples(); i++)
          {
          newTime = times->GetComponent(i, 0);
          if (newTime <= this->TimeValue && newTime > this->GeometryTimeValue)
            {
            this->GeometryTimeValue = newTime;
            timeStep++;
            timeStepInFile++;
            }
          }
        if (this->TimeSetFileNameNumbers->GetNumberOfItems() > 0)
          {
          int collectionNum = this->TimeSetsWithFilenameNumbers->
            IsId(this->GeometryTimeSet);
          if (collectionNum > -1)
            {
            filenameNumbers =
              this->TimeSetFileNameNumbers->GetItem(collectionNum);
            filenameNum = filenameNumbers->GetId(timeStep-1);
            this->ReplaceWildcards(fileName, filenameNum);
            }
          }
      
        // There can only be file sets if there are also time sets.
        if (this->UseFileSets)
          {
          fileSet = this->FileSets->IsId(this->GeometryFileSet);
          numStepsList = (vtkIdList*)this->FileSetNumberOfSteps->
            GetItemAsObject(fileSet);
          
          if (timeStep > numStepsList->GetId(0))
            {
            numSteps = numStepsList->GetId(0);
            timeStepInFile -= numSteps;
            for (i = 1; i < numStepsList->GetNumberOfIds(); i++)
              {
              numSteps += numStepsList->GetId(i);
              if (timeStep > numSteps)
                {
                fileNum++;
                timeStepInFile -= numStepsList->GetId(i);
                }
              }
            }
          if (this->FileSetFileNameNumbers->GetNumberOfItems() > 0)
            {
            int collectionNum = this->FileSetsWithFilenameNumbers->
              IsId(this->GeometryFileSet);
            if (collectionNum > -1)
              {
              filenameNumbers = this->TimeSetFileNameNumbers->
                GetItem(collectionNum);
              filenameNum = filenameNumbers->GetId(fileNum-1);
              this->ReplaceWildcards(fileName, filenameNum);
              }
            }
          }
        }
      }
    
    if (!this->ReadGeometryFile(fileName, timeStepInFile))
      {
      vtkErrorMacro("error reading geometry file");
      delete [] fileName;
      return;
      }
    
    delete [] fileName;
    }
  if (this->MeasuredFileName)
    {
    timeStep = timeStepInFile = 1;
    fileNum = 1;
    fileName = new char[strlen(this->MeasuredFileName) + 1];
    strcpy(fileName, this->MeasuredFileName);
    
    if (this->UseTimeSets)
      {
      timeSet = this->TimeSetIds->IsId(this->MeasuredTimeSet);
      if (timeSet >= 0)
        {
        times = this->TimeSets->GetItem(timeSet);
        this->MeasuredTimeValue = times->GetComponent(0, 0);
        for (i = 1; i < times->GetNumberOfTuples(); i++)
          {
          newTime = times->GetComponent(i, 0);
          if (newTime <= this->TimeValue && newTime > this->MeasuredTimeValue)
            {
            this->MeasuredTimeValue = newTime;
            timeStep++;
            timeStepInFile++;
            }
          }
        if (this->TimeSetFileNameNumbers->GetNumberOfItems() > 0)
          {
          int collectionNum = this->TimeSetsWithFilenameNumbers->
            IsId(this->MeasuredTimeSet);
          if (collectionNum > -1)
            {
            filenameNumbers = this->TimeSetFileNameNumbers->
              GetItem(collectionNum);
            filenameNum = filenameNumbers->GetId(timeStep-1);
            this->ReplaceWildcards(fileName, filenameNum);
            }
          }
        
        // There can only be file sets if there are also time sets.
        if (this->UseFileSets)
          {
          fileSet = this->FileSets->IsId(this->MeasuredFileSet);
          numStepsList = (vtkIdList*)this->FileSetNumberOfSteps->
            GetItemAsObject(fileSet);
          
          if (timeStep > numStepsList->GetId(0))
            {
            numSteps = numStepsList->GetId(0);
            timeStepInFile -= numSteps;
            for (i = 1; i < numStepsList->GetNumberOfIds(); i++)
              {
              numSteps += numStepsList->GetId(i);
              if (timeStep > numSteps)
                {
                fileNum++;
                timeStepInFile -= numStepsList->GetId(i);
                }
              }
            }
          if (this->FileSetFileNameNumbers->GetNumberOfItems() > 0)
            {
            int collectionNum = this->FileSetsWithFilenameNumbers->
              IsId(this->MeasuredFileSet);
            if (collectionNum > -1)
              {
              filenameNumbers = this->TimeSetFileNameNumbers->
                GetItem(fileSet);
              filenameNum = filenameNumbers->GetId(fileNum-1);
              this->ReplaceWildcards(fileName, filenameNum);
              }
            }
          }
        }
      }
    if (!this->ReadMeasuredGeometryFile(fileName, timeStepInFile))
      {
      vtkErrorMacro("error reading measured geometry file");
      delete [] fileName;
      return;
      }
    delete [] fileName;
    }
  if (!this->CheckOutputConsistency())
    {
    for (i = 0; i < this->NumberOfOutputs; i++)
      {
      this->GetOutput(i)->Initialize();
      }
    return;
    }

  if ((this->NumberOfVariables + this->NumberOfComplexVariables) > 0)
    {
    if (!this->ReadVariableFiles())
      {
      vtkErrorMacro("error reading variable files");
      return;
      }
    }
}

//----------------------------------------------------------------------------
void vtkEnSightReader::Update()
{
  vtkDebugMacro("In update");;
  int i;
  
  this->UpdateInformation();
  this->UpdateData(0);
  
  for (i = 0; i < this->GetNumberOfOutputs(); i++)
    {
    if ( this->GetOutput(i) )
      {
      this->GetOutput(i)->DataHasBeenGenerated();
      }
    }
}
//----------------------------------------------------------------------------
void vtkEnSightReader::ExecuteInformation()
{
  vtkDebugMacro("In execute information");
  this->CaseFileRead = this->ReadCaseFile();
}

//----------------------------------------------------------------------------
int vtkEnSightReader::ReadCaseFile()
{
  char line[256], formatLine[256];
  char subLine[256], subLine2[256];
  int stringRead;
  int timeSet, fileSet, numTimeSteps, i, filenameNum, increment, lineRead;
  float timeStep;
  
  // Initialize
  //
  if (!this->CaseFileName)
    {
    vtkErrorMacro("A CaseFileName must be specified.");
    return 0;
    }
  vtkstd::string sfilename;
  if (this->FilePath)
    {
    sfilename = this->FilePath;
    if (sfilename.at(sfilename.length()-1) != '/')
      {
      sfilename += "/";
      }
    sfilename += this->CaseFileName;
    vtkDebugMacro("full path to case file: " << sfilename.c_str());
    }
  else
    {
    sfilename = this->CaseFileName;
    }
  
  this->IS = new ifstream(sfilename.c_str(), ios::in);
  if (this->IS->fail())
    {
    vtkErrorMacro("Unable to open file: " << sfilename.c_str());
    delete this->IS;
    this->IS = NULL;
    return 0;
    }

  this->TimeSets->RemoveAllItems();

  for (i = 0; i < this->NumberOfVariables; i++)
    {
    delete [] this->VariableFileNames[i];
    this->VariableFileNames[i] = NULL;
    delete [] this->VariableDescriptions[i];
    this->VariableDescriptions[i] = NULL;
    }
  delete [] this->VariableFileNames;
  this->VariableFileNames = NULL;
  delete [] this->VariableDescriptions;
  this->VariableDescriptions = NULL;
  delete [] this->VariableTypes;
  this->VariableTypes = NULL;
  
  for (i = 0; i < this->NumberOfComplexVariables; i++)
    {
    delete [] this->ComplexVariableFileNames[2*i];
    this->ComplexVariableFileNames[2*i] = NULL;
    delete [] this->ComplexVariableFileNames[2*i+1];
    this->ComplexVariableFileNames[2*i+1] = NULL;
    delete [] this->ComplexVariableDescriptions[i];
    this->ComplexVariableDescriptions[i] = NULL;
    }
  delete [] this->ComplexVariableFileNames;
  this->ComplexVariableFileNames = NULL;
  delete [] this->ComplexVariableDescriptions;
  this->ComplexVariableDescriptions = NULL;
  delete [] this->ComplexVariableTypes;
  this->ComplexVariableTypes = NULL;
  
  this->NumberOfVariables = 0;
  this->NumberOfComplexVariables = 0;
  
  this->ReadNextDataLine(line);
  
  if (strncmp(line, "FORMAT", 6) == 0)
    {
    // found the FORMAT section
    vtkDebugMacro("*** FORMAT section");
    this->ReadNextDataLine(line);
    
    stringRead = sscanf(line, " %*s %*s %s", subLine);
    if (stringRead == 1)
      {
      if (strcmp(subLine, "gold") == 0 &&
          strcmp(this->GetClassName(), "vtkEnSight6Reader") == 0)
        {
        // The class is vtkEnSight6Reader, but the case file says "gold".
        vtkErrorMacro("This is not an EnSight6 file.");
        delete this->IS;
        this->IS = NULL;
        return 0;
        }
      }
    else
      {
      if (strcmp(this->GetClassName(), "vtkEnSightGoldReader") == 0)
        {
        // The class is vtkEnSightGoldReader, but the case file does
        // not say "gold".
        vtkErrorMacro("This is not an EnSight Gold file.");
        delete this->IS;
        this->IS = NULL;
        return 0;
        }
      }
    }
  
  // We know how many lines to read in the FORMAT section, so we haven't read
  // the "GEOMETRY" line yet.
  this->ReadNextDataLine(line);
  if (strncmp(line, "GEOMETRY", 8) == 0)
    {
    // found the GEOMETRY section
    vtkDebugMacro("*** GEOMETRY section");
    
    // There will definitely be a "model" line.  There may also be "measured"
    // and "match" lines.
    while(this->ReadNextDataLine(line) != 0 &&
          strncmp(line, "m", 1) == 0)
      {
      if (strncmp(line, "model:", 6) == 0)
        {
        if (sscanf(line, " %*s %d%*[ ]%d%*[ ]%s", &timeSet, &fileSet, subLine) == 3)
          {
          this->GeometryTimeSet = timeSet;
          this->GeometryFileSet = fileSet;
          this->SetGeometryFileName(subLine);
          vtkDebugMacro(<<this->GetGeometryFileName());
          }
        else if (sscanf(line, " %*s %d%*[ ]%s", &timeSet, subLine) == 2)
          {
          this->GeometryTimeSet = timeSet;
          this->SetGeometryFileName(subLine);
          vtkDebugMacro(<<this->GetGeometryFileName());
          }
        else if (sscanf(line, " %*s %s", subLine) == 1)
          {
          this->SetGeometryFileName(subLine);
          vtkDebugMacro(<<this->GetGeometryFileName());
          }
        }
      else if (strncmp(line, "measured:", 9) == 0)
        {
        if (sscanf(line, " %*s %d%*[ ]%d%*[ ]%s", &timeSet, &fileSet, subLine) == 3)
          {
          this->MeasuredTimeSet = timeSet;
          this->MeasuredFileSet = fileSet;
          this->SetMeasuredFileName(subLine);
          vtkDebugMacro(<< this->GetMeasuredFileName());
          }
        else if (sscanf(line, " %*s %d%*[ ]%s", &timeSet, subLine) == 2)
          {
          this->MeasuredTimeSet = timeSet;
          this->SetMeasuredFileName(subLine);
          vtkDebugMacro(<< this->GetMeasuredFileName());
          }
        else if (sscanf(line, " %*s %s", subLine) == 1)
          {
          this->SetMeasuredFileName(subLine);
          vtkDebugMacro(<< this->GetMeasuredFileName());
          }
        }
      else if (strncmp(line, "match:", 6) == 0)
        {
        sscanf(line, " %*s %s", subLine);
        this->SetMatchFileName(subLine);
        vtkDebugMacro(<< this->GetMatchFileName());
        }
      }
    }
  
  if (strncmp(line, "VARIABLE", 8) == 0)
    {
    // found the VARIABLE section
    vtkDebugMacro(<< "*** VARIABLE section");

    this->NumberOfScalarsPerNode = 0;
    this->NumberOfVectorsPerNode = 0;
    this->NumberOfTensorsSymmPerNode = 0;
    this->NumberOfScalarsPerElement = 0;
    this->NumberOfVectorsPerElement = 0;
    this->NumberOfTensorsSymmPerElement = 0;
    this->NumberOfScalarsPerMeasuredNode = 0;
    this->NumberOfVectorsPerMeasuredNode = 0;
    this->NumberOfComplexScalarsPerNode = 0;
    this->NumberOfComplexVectorsPerNode = 0;
    this->NumberOfComplexScalarsPerElement = 0;
    this->NumberOfComplexVectorsPerElement = 0;
      
    while(this->ReadNextDataLine(line) != 0 &&
          strncmp(line, "TIME", 4) != 0 &&
          strncmp(line, "FILE", 4) != 0)
      {
      if (strncmp(line, "constant", 8) == 0)
        {
        vtkDebugMacro(<< line);
        }
      else if (strncmp(line, "scalar", 6) == 0)
        {
        sscanf(line, " %*s %*s %s", subLine);
        if (strcmp(subLine, "node:") == 0)
          {
          vtkDebugMacro("scalar per node");
          this->VariableMode = vtkEnSightReader::SCALAR_PER_NODE;
          if (sscanf(line, " %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %d %s", &timeSet, subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfScalarsPerNode++;
          }
        else if (strcmp(subLine, "element:") == 0)
          {
          vtkDebugMacro("scalar per element");
          this->VariableMode = vtkEnSightReader::SCALAR_PER_ELEMENT;
          if (sscanf(line, " %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %d %s", &timeSet, subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfScalarsPerElement++;
          }
        else if (strcmp(subLine, "measured") == 0)
          {
          vtkDebugMacro("scalar per measured node");
          this->VariableMode = vtkEnSightReader::SCALAR_PER_MEASURED_NODE;
          if (sscanf(line, " %*s %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %d %s", &timeSet,
                          subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfScalarsPerMeasuredNode++;
          }
        this->AddVariableFileName(subLine);
        this->NumberOfVariables++;
        }
      else if (strncmp(line, "vector", 6) == 0)
        {
        sscanf(line, " %*s %*s %s", subLine);
        if (strcmp(subLine, "node:") == 0)
          {
          vtkDebugMacro("vector per node");
          this->VariableMode = vtkEnSightReader::VECTOR_PER_NODE;
          if (sscanf(line, " %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %d %s", &timeSet, subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfVectorsPerNode++;
          }
        else if (strcmp(subLine, "element:") == 0)
          {
          vtkDebugMacro("vector per element");
          this->VariableMode = vtkEnSightReader::VECTOR_PER_ELEMENT;
          if (sscanf(line, " %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %d %s", &timeSet, subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfVectorsPerElement++;
          }
        else if (strcmp(subLine, "measured") == 0)
          {
          vtkDebugMacro("vector per measured node");
          this->VariableMode = vtkEnSightReader::VECTOR_PER_MEASURED_NODE;
          if (sscanf(line, " %*s %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %d %s", &timeSet,
                          subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfVectorsPerMeasuredNode++;
          }
        this->AddVariableFileName(subLine);
        this->NumberOfVariables++;
        }
      else if (strncmp(line, "tensor", 6) == 0)
        {
        sscanf(line, " %*s %*s %*s %s", subLine);
        if (strcmp(subLine, "node:") == 0)
          {
          vtkDebugMacro("tensor symm per node");
          this->VariableMode = vtkEnSightReader::TENSOR_SYMM_PER_NODE;
          if (sscanf(line, " %*s %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %d %s", &timeSet,
                          subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfTensorsSymmPerNode++;
          }
        else if (strcmp(subLine, "element:") == 0)
          {
          vtkDebugMacro("tensor symm per element");
          this->VariableMode = vtkEnSightReader::TENSOR_SYMM_PER_ELEMENT;
          if (sscanf(line, " %*s %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %d %s", &timeSet,
                          subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfTensorsSymmPerElement++;
          }
        this->AddVariableFileName(subLine);
        this->NumberOfVariables++;
        }
      else if (strncmp(line, "complex", 6) == 0)
        {
        sscanf(line, " %*s %s", subLine);
        if (strcmp(subLine, "scalar") == 0)
          {
          sscanf(line, " %*s %*s %*s %s", subLine);
          if (strcmp(subLine, "node:") == 0)
            {
            vtkDebugMacro("complex scalar per node");<commit_msg>ENH: accept "tensor per node (or element)" as well as "tensor symm"<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkEnSightReader.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.

=========================================================================*/
#include "vtkEnSightReader.h"

#include "vtkDataArrayCollection.h"
#include "vtkFloatArray.h"
#include "vtkIdList.h"
#include "vtkIdListCollection.h"
#include "vtkObjectFactory.h"
#include "vtkRectilinearGrid.h"
#include "vtkSmartPointer.h"
#include "vtkStructuredGrid.h"
#include "vtkStructuredPoints.h"
#include "vtkUnstructuredGrid.h"

#include <vtkstd/string>
#include <vtkstd/vector>

vtkCxxRevisionMacro(vtkEnSightReader, "1.55.6.1");

//----------------------------------------------------------------------------
typedef vtkstd::vector< vtkSmartPointer<vtkIdList> > vtkEnSightReaderCellIdsTypeBase;
class vtkEnSightReaderCellIdsType: public vtkEnSightReaderCellIdsTypeBase {};

//----------------------------------------------------------------------------
vtkEnSightReader::vtkEnSightReader()
{
  this->MeasuredFileName = NULL;
  this->MatchFileName = NULL;

  this->IS = NULL;
  
  this->VariableMode = -1;
  
  this->UnstructuredPartIds = vtkIdList::New();
  this->CellIds = NULL;
  
  this->VariableFileNames = NULL;
  this->ComplexVariableFileNames = NULL;
  
  this->VariableDescriptions = NULL;
  this->ComplexVariableDescriptions = NULL;

  this->VariableTimeSetIds = vtkIdList::New();
  this->ComplexVariableTimeSetIds = vtkIdList::New();
  this->VariableFileSetIds = vtkIdList::New();
  this->ComplexVariableFileSetIds = vtkIdList::New();

  this->TimeSetFileNameNumbers = vtkIdListCollection::New();
  this->TimeSetsWithFilenameNumbers = vtkIdList::New();
  this->TimeSets = vtkDataArrayCollection::New();
  this->FileSetFileNameNumbers = vtkIdListCollection::New();
  this->FileSetsWithFilenameNumbers = vtkIdList::New();
  this->FileSetNumberOfSteps = vtkIdListCollection::New();

  this->TimeSetIds = vtkIdList::New();
  this->FileSets = vtkIdList::New();
  
  this->GeometryTimeSet = 1;
  this->GeometryFileSet = 1;
  this->MeasuredTimeSet = 1;
  this->MeasuredFileSet = 1;
  
  this->UseTimeSets = 0;
  this->UseFileSets = 0;

  this->GeometryTimeValue = -1;
  this->MeasuredTimeValue = -1;
  
  this->NumberOfGeometryParts = 0;

  this->NumberOfMeasuredPoints = 0;
  
  this->OutputsAreValid = 1;
  this->InitialRead = 1;
  this->NumberOfNewOutputs = 0;
}

//----------------------------------------------------------------------------
vtkEnSightReader::~vtkEnSightReader()
{
  int i;

  if (this->CellIds)
    {
    delete this->CellIds;
    this->CellIds = NULL;
    }
  
  if (this->MeasuredFileName)
    {
    delete [] this->MeasuredFileName;
    this->MeasuredFileName = NULL;
    }
  if (this->MatchFileName)
    {
    delete [] this->MatchFileName;
    this->MatchFileName = NULL;
    }

  if (this->NumberOfVariables > 0)
    {
    for (i = 0; i < this->NumberOfVariables; i++)
      {
      delete [] this->VariableFileNames[i];
      }
    delete [] this->VariableFileNames;
    this->VariableFileNames = NULL;
    }

  if (this->NumberOfComplexVariables > 0)
    {
    for (i = 0; i < this->NumberOfComplexVariables*2; i++)
      {
      delete [] this->ComplexVariableFileNames[i];
      }
    delete [] this->ComplexVariableFileNames;
    this->ComplexVariableFileNames = NULL;
    }
  
  this->UnstructuredPartIds->Delete();
  this->UnstructuredPartIds = NULL;  
    
  this->VariableTimeSetIds->Delete();
  this->VariableTimeSetIds = NULL;
  this->ComplexVariableTimeSetIds->Delete();
  this->ComplexVariableTimeSetIds = NULL;
  this->VariableFileSetIds->Delete();
  this->VariableFileSetIds = NULL;
  this->ComplexVariableFileSetIds->Delete();
  this->ComplexVariableFileSetIds = NULL;
  
  this->TimeSetFileNameNumbers->Delete();
  this->TimeSetFileNameNumbers = NULL;
  this->TimeSetsWithFilenameNumbers->Delete();
  this->TimeSetsWithFilenameNumbers = NULL;
  this->TimeSets->Delete();
  this->TimeSets = NULL;
  this->FileSetFileNameNumbers->Delete();
  this->FileSetFileNameNumbers = NULL;
  this->FileSetsWithFilenameNumbers->Delete();
  this->FileSetsWithFilenameNumbers = NULL;
  this->FileSetNumberOfSteps->Delete();
  this->FileSetNumberOfSteps = NULL;
  
  this->TimeSetIds->Delete();
  this->TimeSets = NULL;
  this->FileSets->Delete();
  this->FileSets = NULL;
}

//----------------------------------------------------------------------------
void vtkEnSightReader::Execute()
{
  vtkDebugMacro("In execute ");

  int i, timeSet, fileSet, timeStep, timeStepInFile, fileNum;
  vtkDataArray *times;
  vtkIdList *numStepsList, *filenameNumbers;
  float newTime;
  int numSteps;
  char* fileName;
  int filenameNum;
  
  if ( ! this->CaseFileRead)
    {
    vtkErrorMacro("error reading case file");
    return;
    }
  
  this->OutputsAreValid = 1;
  this->NumberOfNewOutputs = 0;
  this->NumberOfGeometryParts = 0;
  if (this->GeometryFileName)
    {
    timeStep = timeStepInFile = 1;
    fileNum = 1;
    fileName = new char[strlen(this->GeometryFileName) + 1];
    strcpy(fileName, this->GeometryFileName);
    
    if (this->UseTimeSets)
      {
      timeSet = this->TimeSetIds->IsId(this->GeometryTimeSet);
      if (timeSet >= 0)
        {
        times = this->TimeSets->GetItem(timeSet);
        this->GeometryTimeValue = times->GetComponent(0, 0);
        for (i = 1; i < times->GetNumberOfTuples(); i++)
          {
          newTime = times->GetComponent(i, 0);
          if (newTime <= this->TimeValue && newTime > this->GeometryTimeValue)
            {
            this->GeometryTimeValue = newTime;
            timeStep++;
            timeStepInFile++;
            }
          }
        if (this->TimeSetFileNameNumbers->GetNumberOfItems() > 0)
          {
          int collectionNum = this->TimeSetsWithFilenameNumbers->
            IsId(this->GeometryTimeSet);
          if (collectionNum > -1)
            {
            filenameNumbers =
              this->TimeSetFileNameNumbers->GetItem(collectionNum);
            filenameNum = filenameNumbers->GetId(timeStep-1);
            this->ReplaceWildcards(fileName, filenameNum);
            }
          }
      
        // There can only be file sets if there are also time sets.
        if (this->UseFileSets)
          {
          fileSet = this->FileSets->IsId(this->GeometryFileSet);
          numStepsList = (vtkIdList*)this->FileSetNumberOfSteps->
            GetItemAsObject(fileSet);
          
          if (timeStep > numStepsList->GetId(0))
            {
            numSteps = numStepsList->GetId(0);
            timeStepInFile -= numSteps;
            for (i = 1; i < numStepsList->GetNumberOfIds(); i++)
              {
              numSteps += numStepsList->GetId(i);
              if (timeStep > numSteps)
                {
                fileNum++;
                timeStepInFile -= numStepsList->GetId(i);
                }
              }
            }
          if (this->FileSetFileNameNumbers->GetNumberOfItems() > 0)
            {
            int collectionNum = this->FileSetsWithFilenameNumbers->
              IsId(this->GeometryFileSet);
            if (collectionNum > -1)
              {
              filenameNumbers = this->TimeSetFileNameNumbers->
                GetItem(collectionNum);
              filenameNum = filenameNumbers->GetId(fileNum-1);
              this->ReplaceWildcards(fileName, filenameNum);
              }
            }
          }
        }
      }
    
    if (!this->ReadGeometryFile(fileName, timeStepInFile))
      {
      vtkErrorMacro("error reading geometry file");
      delete [] fileName;
      return;
      }
    
    delete [] fileName;
    }
  if (this->MeasuredFileName)
    {
    timeStep = timeStepInFile = 1;
    fileNum = 1;
    fileName = new char[strlen(this->MeasuredFileName) + 1];
    strcpy(fileName, this->MeasuredFileName);
    
    if (this->UseTimeSets)
      {
      timeSet = this->TimeSetIds->IsId(this->MeasuredTimeSet);
      if (timeSet >= 0)
        {
        times = this->TimeSets->GetItem(timeSet);
        this->MeasuredTimeValue = times->GetComponent(0, 0);
        for (i = 1; i < times->GetNumberOfTuples(); i++)
          {
          newTime = times->GetComponent(i, 0);
          if (newTime <= this->TimeValue && newTime > this->MeasuredTimeValue)
            {
            this->MeasuredTimeValue = newTime;
            timeStep++;
            timeStepInFile++;
            }
          }
        if (this->TimeSetFileNameNumbers->GetNumberOfItems() > 0)
          {
          int collectionNum = this->TimeSetsWithFilenameNumbers->
            IsId(this->MeasuredTimeSet);
          if (collectionNum > -1)
            {
            filenameNumbers = this->TimeSetFileNameNumbers->
              GetItem(collectionNum);
            filenameNum = filenameNumbers->GetId(timeStep-1);
            this->ReplaceWildcards(fileName, filenameNum);
            }
          }
        
        // There can only be file sets if there are also time sets.
        if (this->UseFileSets)
          {
          fileSet = this->FileSets->IsId(this->MeasuredFileSet);
          numStepsList = (vtkIdList*)this->FileSetNumberOfSteps->
            GetItemAsObject(fileSet);
          
          if (timeStep > numStepsList->GetId(0))
            {
            numSteps = numStepsList->GetId(0);
            timeStepInFile -= numSteps;
            for (i = 1; i < numStepsList->GetNumberOfIds(); i++)
              {
              numSteps += numStepsList->GetId(i);
              if (timeStep > numSteps)
                {
                fileNum++;
                timeStepInFile -= numStepsList->GetId(i);
                }
              }
            }
          if (this->FileSetFileNameNumbers->GetNumberOfItems() > 0)
            {
            int collectionNum = this->FileSetsWithFilenameNumbers->
              IsId(this->MeasuredFileSet);
            if (collectionNum > -1)
              {
              filenameNumbers = this->TimeSetFileNameNumbers->
                GetItem(fileSet);
              filenameNum = filenameNumbers->GetId(fileNum-1);
              this->ReplaceWildcards(fileName, filenameNum);
              }
            }
          }
        }
      }
    if (!this->ReadMeasuredGeometryFile(fileName, timeStepInFile))
      {
      vtkErrorMacro("error reading measured geometry file");
      delete [] fileName;
      return;
      }
    delete [] fileName;
    }
  if (!this->CheckOutputConsistency())
    {
    for (i = 0; i < this->NumberOfOutputs; i++)
      {
      this->GetOutput(i)->Initialize();
      }
    return;
    }

  if ((this->NumberOfVariables + this->NumberOfComplexVariables) > 0)
    {
    if (!this->ReadVariableFiles())
      {
      vtkErrorMacro("error reading variable files");
      return;
      }
    }
}

//----------------------------------------------------------------------------
void vtkEnSightReader::Update()
{
  vtkDebugMacro("In update");;
  int i;
  
  this->UpdateInformation();
  this->UpdateData(0);
  
  for (i = 0; i < this->GetNumberOfOutputs(); i++)
    {
    if ( this->GetOutput(i) )
      {
      this->GetOutput(i)->DataHasBeenGenerated();
      }
    }
}
//----------------------------------------------------------------------------
void vtkEnSightReader::ExecuteInformation()
{
  vtkDebugMacro("In execute information");
  this->CaseFileRead = this->ReadCaseFile();
}

//----------------------------------------------------------------------------
int vtkEnSightReader::ReadCaseFile()
{
  char line[256], formatLine[256];
  char subLine[256], subLine2[256];
  int stringRead;
  int timeSet, fileSet, numTimeSteps, i, filenameNum, increment, lineRead;
  float timeStep;
  
  // Initialize
  //
  if (!this->CaseFileName)
    {
    vtkErrorMacro("A CaseFileName must be specified.");
    return 0;
    }
  vtkstd::string sfilename;
  if (this->FilePath)
    {
    sfilename = this->FilePath;
    if (sfilename.at(sfilename.length()-1) != '/')
      {
      sfilename += "/";
      }
    sfilename += this->CaseFileName;
    vtkDebugMacro("full path to case file: " << sfilename.c_str());
    }
  else
    {
    sfilename = this->CaseFileName;
    }
  
  this->IS = new ifstream(sfilename.c_str(), ios::in);
  if (this->IS->fail())
    {
    vtkErrorMacro("Unable to open file: " << sfilename.c_str());
    delete this->IS;
    this->IS = NULL;
    return 0;
    }

  this->TimeSets->RemoveAllItems();

  for (i = 0; i < this->NumberOfVariables; i++)
    {
    delete [] this->VariableFileNames[i];
    this->VariableFileNames[i] = NULL;
    delete [] this->VariableDescriptions[i];
    this->VariableDescriptions[i] = NULL;
    }
  delete [] this->VariableFileNames;
  this->VariableFileNames = NULL;
  delete [] this->VariableDescriptions;
  this->VariableDescriptions = NULL;
  delete [] this->VariableTypes;
  this->VariableTypes = NULL;
  
  for (i = 0; i < this->NumberOfComplexVariables; i++)
    {
    delete [] this->ComplexVariableFileNames[2*i];
    this->ComplexVariableFileNames[2*i] = NULL;
    delete [] this->ComplexVariableFileNames[2*i+1];
    this->ComplexVariableFileNames[2*i+1] = NULL;
    delete [] this->ComplexVariableDescriptions[i];
    this->ComplexVariableDescriptions[i] = NULL;
    }
  delete [] this->ComplexVariableFileNames;
  this->ComplexVariableFileNames = NULL;
  delete [] this->ComplexVariableDescriptions;
  this->ComplexVariableDescriptions = NULL;
  delete [] this->ComplexVariableTypes;
  this->ComplexVariableTypes = NULL;
  
  this->NumberOfVariables = 0;
  this->NumberOfComplexVariables = 0;
  
  this->ReadNextDataLine(line);
  
  if (strncmp(line, "FORMAT", 6) == 0)
    {
    // found the FORMAT section
    vtkDebugMacro("*** FORMAT section");
    this->ReadNextDataLine(line);
    
    stringRead = sscanf(line, " %*s %*s %s", subLine);
    if (stringRead == 1)
      {
      if (strcmp(subLine, "gold") == 0 &&
          strcmp(this->GetClassName(), "vtkEnSight6Reader") == 0)
        {
        // The class is vtkEnSight6Reader, but the case file says "gold".
        vtkErrorMacro("This is not an EnSight6 file.");
        delete this->IS;
        this->IS = NULL;
        return 0;
        }
      }
    else
      {
      if (strcmp(this->GetClassName(), "vtkEnSightGoldReader") == 0)
        {
        // The class is vtkEnSightGoldReader, but the case file does
        // not say "gold".
        vtkErrorMacro("This is not an EnSight Gold file.");
        delete this->IS;
        this->IS = NULL;
        return 0;
        }
      }
    }
  
  // We know how many lines to read in the FORMAT section, so we haven't read
  // the "GEOMETRY" line yet.
  this->ReadNextDataLine(line);
  if (strncmp(line, "GEOMETRY", 8) == 0)
    {
    // found the GEOMETRY section
    vtkDebugMacro("*** GEOMETRY section");
    
    // There will definitely be a "model" line.  There may also be "measured"
    // and "match" lines.
    while(this->ReadNextDataLine(line) != 0 &&
          strncmp(line, "m", 1) == 0)
      {
      if (strncmp(line, "model:", 6) == 0)
        {
        if (sscanf(line, " %*s %d%*[ ]%d%*[ ]%s", &timeSet, &fileSet, subLine) == 3)
          {
          this->GeometryTimeSet = timeSet;
          this->GeometryFileSet = fileSet;
          this->SetGeometryFileName(subLine);
          vtkDebugMacro(<<this->GetGeometryFileName());
          }
        else if (sscanf(line, " %*s %d%*[ ]%s", &timeSet, subLine) == 2)
          {
          this->GeometryTimeSet = timeSet;
          this->SetGeometryFileName(subLine);
          vtkDebugMacro(<<this->GetGeometryFileName());
          }
        else if (sscanf(line, " %*s %s", subLine) == 1)
          {
          this->SetGeometryFileName(subLine);
          vtkDebugMacro(<<this->GetGeometryFileName());
          }
        }
      else if (strncmp(line, "measured:", 9) == 0)
        {
        if (sscanf(line, " %*s %d%*[ ]%d%*[ ]%s", &timeSet, &fileSet, subLine) == 3)
          {
          this->MeasuredTimeSet = timeSet;
          this->MeasuredFileSet = fileSet;
          this->SetMeasuredFileName(subLine);
          vtkDebugMacro(<< this->GetMeasuredFileName());
          }
        else if (sscanf(line, " %*s %d%*[ ]%s", &timeSet, subLine) == 2)
          {
          this->MeasuredTimeSet = timeSet;
          this->SetMeasuredFileName(subLine);
          vtkDebugMacro(<< this->GetMeasuredFileName());
          }
        else if (sscanf(line, " %*s %s", subLine) == 1)
          {
          this->SetMeasuredFileName(subLine);
          vtkDebugMacro(<< this->GetMeasuredFileName());
          }
        }
      else if (strncmp(line, "match:", 6) == 0)
        {
        sscanf(line, " %*s %s", subLine);
        this->SetMatchFileName(subLine);
        vtkDebugMacro(<< this->GetMatchFileName());
        }
      }
    }
  
  if (strncmp(line, "VARIABLE", 8) == 0)
    {
    // found the VARIABLE section
    vtkDebugMacro(<< "*** VARIABLE section");

    this->NumberOfScalarsPerNode = 0;
    this->NumberOfVectorsPerNode = 0;
    this->NumberOfTensorsSymmPerNode = 0;
    this->NumberOfScalarsPerElement = 0;
    this->NumberOfVectorsPerElement = 0;
    this->NumberOfTensorsSymmPerElement = 0;
    this->NumberOfScalarsPerMeasuredNode = 0;
    this->NumberOfVectorsPerMeasuredNode = 0;
    this->NumberOfComplexScalarsPerNode = 0;
    this->NumberOfComplexVectorsPerNode = 0;
    this->NumberOfComplexScalarsPerElement = 0;
    this->NumberOfComplexVectorsPerElement = 0;
      
    while(this->ReadNextDataLine(line) != 0 &&
          strncmp(line, "TIME", 4) != 0 &&
          strncmp(line, "FILE", 4) != 0)
      {
      if (strncmp(line, "constant", 8) == 0)
        {
        vtkDebugMacro(<< line);
        }
      else if (strncmp(line, "scalar", 6) == 0)
        {
        sscanf(line, " %*s %*s %s", subLine);
        if (strcmp(subLine, "node:") == 0)
          {
          vtkDebugMacro("scalar per node");
          this->VariableMode = vtkEnSightReader::SCALAR_PER_NODE;
          if (sscanf(line, " %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %d %s", &timeSet, subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfScalarsPerNode++;
          }
        else if (strcmp(subLine, "element:") == 0)
          {
          vtkDebugMacro("scalar per element");
          this->VariableMode = vtkEnSightReader::SCALAR_PER_ELEMENT;
          if (sscanf(line, " %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %d %s", &timeSet, subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfScalarsPerElement++;
          }
        else if (strcmp(subLine, "measured") == 0)
          {
          vtkDebugMacro("scalar per measured node");
          this->VariableMode = vtkEnSightReader::SCALAR_PER_MEASURED_NODE;
          if (sscanf(line, " %*s %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %d %s", &timeSet,
                          subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfScalarsPerMeasuredNode++;
          }
        this->AddVariableFileName(subLine);
        this->NumberOfVariables++;
        }
      else if (strncmp(line, "vector", 6) == 0)
        {
        sscanf(line, " %*s %*s %s", subLine);
        if (strcmp(subLine, "node:") == 0)
          {
          vtkDebugMacro("vector per node");
          this->VariableMode = vtkEnSightReader::VECTOR_PER_NODE;
          if (sscanf(line, " %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %d %s", &timeSet, subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfVectorsPerNode++;
          }
        else if (strcmp(subLine, "element:") == 0)
          {
          vtkDebugMacro("vector per element");
          this->VariableMode = vtkEnSightReader::VECTOR_PER_ELEMENT;
          if (sscanf(line, " %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %d %s", &timeSet, subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfVectorsPerElement++;
          }
        else if (strcmp(subLine, "measured") == 0)
          {
          vtkDebugMacro("vector per measured node");
          this->VariableMode = vtkEnSightReader::VECTOR_PER_MEASURED_NODE;
          if (sscanf(line, " %*s %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %d %s", &timeSet,
                          subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfVectorsPerMeasuredNode++;
          }
        this->AddVariableFileName(subLine);
        this->NumberOfVariables++;
        }
      else if (strncmp(line, "tensor", 6) == 0)
        {
        // According to EnSight documentation tensor entry should be of the form:
        // tensor symm per node/element
        // but it seems like you can also find:
        // tensor per node/element
        // Let handle this case here:
        char symm[10];
        char per[10];
        if( sscanf(line, " %*s %s %s %s", symm, per, subLine) != 3 )
          {
          vtkErrorMacro( "Error while reading: " << line );
          }
        if (!(strcmp(symm, "symm") == 0 && strcmp(per, "per") == 0))
          {
          if( sscanf(line, " %*s %s %s", per, subLine) != 2 )
            {
            vtkErrorMacro( "Error while reading: " << line );
            }
          if (strcmp(per, "per") == 0)
            {
            //Not valid file but seems alright, only 'symm' is missing
            vtkWarningMacro( "Looks almost like a valid case file, continuing" );
            }
          else
            {
            vtkErrorMacro("Trouble reading: " << line );
            }
          }
        if (strcmp(subLine, "node:") == 0)
          {
          vtkDebugMacro("tensor symm per node");
          this->VariableMode = vtkEnSightReader::TENSOR_SYMM_PER_NODE;
          if (sscanf(line, " %*s %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %d %s", &timeSet,
                          subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfTensorsSymmPerNode++;
          }
        else if (strcmp(subLine, "element:") == 0)
          {
          vtkDebugMacro("tensor symm per element");
          this->VariableMode = vtkEnSightReader::TENSOR_SYMM_PER_ELEMENT;
          if (sscanf(line, " %*s %*s %*s %*s %d %d %s", &timeSet, &fileSet,
                     subLine) == 3)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->VariableFileSetIds->InsertNextId(fileSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %d %s", &timeSet,
                          subLine) == 2)
            {
            this->VariableTimeSetIds->InsertNextId(timeSet);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*d %*s %s", subLine);
            }
          else if (sscanf(line, " %*s %*s %*s %*s %s", subLine) == 1)
            {
            this->VariableTimeSetIds->InsertNextId(1);
            this->AddVariableDescription(subLine);
            sscanf(line, " %*s %*s %*s %*s %*s %s", subLine);
            }
          this->AddVariableType();
          this->NumberOfTensorsSymmPerElement++;
          }
        else
          {
          vtkErrorMacro("Unknow type, faulty line was:" << line );
          }
        this->AddVariableFileName(subLine);
        this->NumberOfVariables++;
        }
      else if (strncmp(line, "complex", 6) == 0)
        {
        sscanf(line, " %*s %s", subLine);
        if (strcmp(subLine, "scalar") == 0)
          {
          sscanf(line, " %*s %*s %*s %s", subLine);
          if (strcmp(subLine, "node:") == 0)
            {
            vtkDebugMacro("complex scalar per node");
{'fraction_non_alphanumeric': 0.1657933490872975, 'fraction_numerical': 0.0066269392787424225, 'mean_word_length': 2.042248385080225, 'pattern_counts': {'":': 0, '<': 93, '<?xml version=': 0, '>': 861, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 1, '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': '3358226', 'n_tokens_mistral': 18798, 'n_tokens_neox': 18282, 'n_words': 3502}