<commit_before>#include <QApplication>
#include <QSet>
#include <QXmlStreamWriter>
#include <QXmlStreamReader>

#include <QMetaObject>
#include <QMetaProperty>
#include <QPushButton>
#include <QDebug>
#include <iostream>
#include <QtDeclarative>
#include <QtDeclarative/private/qdeclarativemetatype_p.h>
#include <QtDeclarative/QDeclarativeView>

static QHash<QByteArray, const QDeclarativeType *> qmlTypeByCppName;
static QHash<QByteArray, QByteArray> cppToQml;

QByteArray convertToQmlType(const QByteArray &cppName)
{
    QByteArray qmlName = cppToQml.value(cppName, cppName);
    qmlName.replace("::", ".");
    qmlName.replace("/", ".");
    return qmlName;
}

void erasure(QByteArray *typeName, bool *isList, bool *isPointer)
{
    static QByteArray declListPrefix = "QDeclarativeListProperty<";

    if (typeName->endsWith('*')) {
        *isPointer = true;
        typeName->truncate(typeName->length() - 1);
        erasure(typeName, isList, isPointer);
    } else if (typeName->startsWith(declListPrefix)) {
        *isList = true;
        typeName->truncate(typeName->length() - 1); // get rid of the suffix '>'
        *typeName = typeName->mid(declListPrefix.size());
        erasure(typeName, isList, isPointer);
    }

    *typeName = convertToQmlType(*typeName);
}

void processMetaObject(const QMetaObject *meta, QSet<const QMetaObject *> *metas)
{
    if (! meta || metas->contains(meta))
        return;

    metas->insert(meta);
    processMetaObject(meta->superClass(), metas);
}

void processObject(QObject *object, QSet<const QMetaObject *> *metas)
{
    if (! object)
        return;

    const QMetaObject *meta = object->metaObject();
    processMetaObject(meta, metas);

    for (int index = 0; index < meta->propertyCount(); ++index) {
        QMetaProperty prop = meta->property(index);
        if (QDeclarativeMetaType::isQObject(prop.userType())) {
            QObject *oo = QDeclarativeMetaType::toQObject(prop.read(object));
            processObject(oo, metas);
        }
    }

}

void processDeclarativeType(const QDeclarativeType *ty, QSet<const QMetaObject *> *metas)
{
    processMetaObject(ty->metaObject(), metas);
}

void writeType(QXmlStreamAttributes *attrs, QByteArray typeName)
{
    bool isList = false, isPointer = false;
    erasure(&typeName, &isList, &isPointer);
    attrs->append(QXmlStreamAttribute("type", typeName));
    if (isList)
        attrs->append(QXmlStreamAttribute("isList", "true"));
}

void dump(const QMetaProperty &prop, QXmlStreamWriter *xml)
{
    xml->writeStartElement("property");

    QXmlStreamAttributes attributes;
    attributes.append(QXmlStreamAttribute("name", QString::fromUtf8(prop.name())));

    writeType(&attributes, prop.typeName());

    xml->writeAttributes(attributes);
    xml->writeEndElement();
}

void dump(const QMetaMethod &meth, QXmlStreamWriter *xml)
{
    if (meth.methodType() == QMetaMethod::Signal) {
        if (meth.access() != QMetaMethod::Protected)
            return; // nothing to do.
    } else if (meth.access() != QMetaMethod::Public) {
        return; // nothing to do.
    }

    QByteArray name = meth.signature();
    int lparenIndex = name.indexOf('(');
    if (lparenIndex == -1) {
        return; // invalid signature
    }

    name = name.left(lparenIndex);

    QString elementName = QLatin1String("method");

    QXmlStreamAttributes attributes;
    if (meth.methodType() == QMetaMethod::Signal)
        elementName = QLatin1String("signal");

    xml->writeStartElement(elementName);

    attributes.append(QXmlStreamAttribute("name", name));

    const QString typeName = convertToQmlType(meth.typeName());
    if (! typeName.isEmpty())
        attributes.append(QXmlStreamAttribute("type", typeName));

    xml->writeAttributes(attributes);

    for (int i = 0; i < meth.parameterTypes().size(); ++i) {
        QByteArray argName = meth.parameterNames().at(i);

        xml->writeStartElement("param");

        QXmlStreamAttributes attrs;

        if (! argName.isEmpty())
            attrs.append(QXmlStreamAttribute("name", argName));

        writeType(&attrs, meth.parameterTypes().at(i));
        xml->writeAttributes(attrs);

        xml->writeEndElement();
    }

    xml->writeEndElement();
}

void dump(const QMetaEnum &e, QXmlStreamWriter *xml)
{
    xml->writeStartElement("enum");

    QXmlStreamAttributes attributes;
    attributes.append(QXmlStreamAttribute("name", QString::fromUtf8(e.name()))); // ### FIXME
    xml->writeAttributes(attributes);

    for (int index = 0; index < e.keyCount(); ++index) {
        xml->writeStartElement("enumerator");

        QXmlStreamAttributes attributes;
        attributes.append(QXmlStreamAttribute("name", QString::fromUtf8(e.key(index))));
        attributes.append(QXmlStreamAttribute("value", QString::number(e.value(index))));
        xml->writeAttributes(attributes);

        xml->writeEndElement();
    }

    xml->writeEndElement();
}

class FriendlyQObject: public QObject
{
public:
    static const QMetaObject *qtMeta() { return &staticQtMetaObject; }
};

void dump(const QMetaObject *meta, QXmlStreamWriter *xml)
{
    xml->writeStartElement("type");

    QXmlStreamAttributes attributes;
    attributes.append(QXmlStreamAttribute("name", convertToQmlType(meta->className())));

    if (const QDeclarativeType *qmlTy = qmlTypeByCppName.value(meta->className())) {
        attributes.append(QXmlStreamAttribute("version", QString("%1.%2").arg(qmlTy->majorVersion()).arg(qmlTy->minorVersion())));
    }

    QString version;

    if (meta->superClass())
        attributes.append(QXmlStreamAttribute("extends", convertToQmlType(meta->superClass()->className())));

    if (! version.isEmpty())
        attributes.append(QXmlStreamAttribute("version", version));

    xml->writeAttributes(attributes);

    for (int index = meta->enumeratorOffset(); index < meta->enumeratorCount(); ++index)
        dump(meta->enumerator(index), xml);

    for (int index = meta->propertyOffset(); index < meta->propertyCount(); ++index)
        dump(meta->property(index), xml);

    for (int index = meta->methodOffset(); index < meta->methodCount(); ++index)
        dump(meta->method(index), xml);

    xml->writeEndElement();
}

void writeScriptElement(QXmlStreamWriter *xml)
{
    xml->writeStartElement("type");
    {
        QXmlStreamAttributes attributes;
        attributes.append(QXmlStreamAttribute("name", "Script"));
        xml->writeAttributes(attributes);
    }

    xml->writeStartElement("property");
    {
        QXmlStreamAttributes attributes;
        attributes.append(QXmlStreamAttribute("name", "script"));
        attributes.append(QXmlStreamAttribute("type", "string"));
        xml->writeAttributes(attributes);
    }
    xml->writeEndElement();

    xml->writeStartElement("property");
    {
        QXmlStreamAttributes attributes;
        attributes.append(QXmlStreamAttribute("name", "source"));
        attributes.append(QXmlStreamAttribute("type", "QUrl"));
        xml->writeAttributes(attributes);
    }
    xml->writeEndElement();

    xml->writeEndElement();
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QDeclarativeView view;
    QDeclarativeEngine *engine = view.engine();

    cppToQml.insert("QString", "string");

    QSet<const QMetaObject *> metas;

    metas.insert(FriendlyQObject::qtMeta());

    foreach (const QDeclarativeType *ty, QDeclarativeMetaType::qmlTypes()) {
        cppToQml.insert(ty->metaObject()->className(), ty->qmlTypeName());
        qmlTypeByCppName.insert(ty->metaObject()->className(), ty);
        processDeclarativeType(ty, &metas);
    }

    foreach (const QDeclarativeType *ty, QDeclarativeMetaType::qmlTypes()) {
        QByteArray tyName = ty->qmlTypeName();
        tyName = tyName.mid(tyName.lastIndexOf('/') + 1);

        QByteArray code;
        code += "import Qt 4.6;\n";
        code += tyName;
        code += " {}\n";

        QDeclarativeComponent c(engine);
        c.setData(code, QUrl("xxx"));
        processObject(c.create(), &metas);
    }

    QByteArray bytes;
    QXmlStreamWriter xml(&bytes);
    xml.setAutoFormatting(true);

    xml.writeStartDocument("1.0");
    xml.writeStartElement("module");

    foreach (const QMetaObject *meta, metas) {
        dump(meta, &xml);
    }

    writeScriptElement(&xml);

    xml.writeEndElement();
    xml.writeEndDocument();

    std::cout << bytes.constData();

    QTimer timer;
    timer.setSingleShot(true);
    timer.setInterval(0);
    QObject::connect(&timer, SIGNAL(timeout()), &app, SLOT(quit()));

    timer.start();

    return app.exec();
}
<commit_msg>In the XML describing the Qml types, order the types by name.<commit_after>#include <QApplication>
#include <QSet>
#include <QXmlStreamWriter>
#include <QXmlStreamReader>

#include <QMetaObject>
#include <QMetaProperty>
#include <QPushButton>
#include <QDebug>
#include <iostream>
#include <QtDeclarative>
#include <QtDeclarative/private/qdeclarativemetatype_p.h>
#include <QtDeclarative/QDeclarativeView>

static QHash<QByteArray, const QDeclarativeType *> qmlTypeByCppName;
static QHash<QByteArray, QByteArray> cppToQml;

QByteArray convertToQmlType(const QByteArray &cppName)
{
    QByteArray qmlName = cppToQml.value(cppName, cppName);
    qmlName.replace("::", ".");
    qmlName.replace("/", ".");
    return qmlName;
}

void erasure(QByteArray *typeName, bool *isList, bool *isPointer)
{
    static QByteArray declListPrefix = "QDeclarativeListProperty<";

    if (typeName->endsWith('*')) {
        *isPointer = true;
        typeName->truncate(typeName->length() - 1);
        erasure(typeName, isList, isPointer);
    } else if (typeName->startsWith(declListPrefix)) {
        *isList = true;
        typeName->truncate(typeName->length() - 1); // get rid of the suffix '>'
        *typeName = typeName->mid(declListPrefix.size());
        erasure(typeName, isList, isPointer);
    }

    *typeName = convertToQmlType(*typeName);
}

void processMetaObject(const QMetaObject *meta, QSet<const QMetaObject *> *metas)
{
    if (! meta || metas->contains(meta))
        return;

    metas->insert(meta);
    processMetaObject(meta->superClass(), metas);
}

void processObject(QObject *object, QSet<const QMetaObject *> *metas)
{
    if (! object)
        return;

    const QMetaObject *meta = object->metaObject();
    processMetaObject(meta, metas);

    for (int index = 0; index < meta->propertyCount(); ++index) {
        QMetaProperty prop = meta->property(index);
        if (QDeclarativeMetaType::isQObject(prop.userType())) {
            QObject *oo = QDeclarativeMetaType::toQObject(prop.read(object));
            processObject(oo, metas);
        }
    }

}

void processDeclarativeType(const QDeclarativeType *ty, QSet<const QMetaObject *> *metas)
{
    processMetaObject(ty->metaObject(), metas);
}

void writeType(QXmlStreamAttributes *attrs, QByteArray typeName)
{
    bool isList = false, isPointer = false;
    erasure(&typeName, &isList, &isPointer);
    attrs->append(QXmlStreamAttribute("type", typeName));
    if (isList)
        attrs->append(QXmlStreamAttribute("isList", "true"));
}

void dump(const QMetaProperty &prop, QXmlStreamWriter *xml)
{
    xml->writeStartElement("property");

    QXmlStreamAttributes attributes;
    attributes.append(QXmlStreamAttribute("name", QString::fromUtf8(prop.name())));

    writeType(&attributes, prop.typeName());

    xml->writeAttributes(attributes);
    xml->writeEndElement();
}

void dump(const QMetaMethod &meth, QXmlStreamWriter *xml)
{
    if (meth.methodType() == QMetaMethod::Signal) {
        if (meth.access() != QMetaMethod::Protected)
            return; // nothing to do.
    } else if (meth.access() != QMetaMethod::Public) {
        return; // nothing to do.
    }

    QByteArray name = meth.signature();
    int lparenIndex = name.indexOf('(');
    if (lparenIndex == -1) {
        return; // invalid signature
    }

    name = name.left(lparenIndex);

    QString elementName = QLatin1String("method");

    QXmlStreamAttributes attributes;
    if (meth.methodType() == QMetaMethod::Signal)
        elementName = QLatin1String("signal");

    xml->writeStartElement(elementName);

    attributes.append(QXmlStreamAttribute("name", name));

    const QString typeName = convertToQmlType(meth.typeName());
    if (! typeName.isEmpty())
        attributes.append(QXmlStreamAttribute("type", typeName));

    xml->writeAttributes(attributes);

    for (int i = 0; i < meth.parameterTypes().size(); ++i) {
        QByteArray argName = meth.parameterNames().at(i);

        xml->writeStartElement("param");

        QXmlStreamAttributes attrs;

        if (! argName.isEmpty())
            attrs.append(QXmlStreamAttribute("name", argName));

        writeType(&attrs, meth.parameterTypes().at(i));
        xml->writeAttributes(attrs);

        xml->writeEndElement();
    }

    xml->writeEndElement();
}

void dump(const QMetaEnum &e, QXmlStreamWriter *xml)
{
    xml->writeStartElement("enum");

    QXmlStreamAttributes attributes;
    attributes.append(QXmlStreamAttribute("name", QString::fromUtf8(e.name()))); // ### FIXME
    xml->writeAttributes(attributes);

    for (int index = 0; index < e.keyCount(); ++index) {
        xml->writeStartElement("enumerator");

        QXmlStreamAttributes attributes;
        attributes.append(QXmlStreamAttribute("name", QString::fromUtf8(e.key(index))));
        attributes.append(QXmlStreamAttribute("value", QString::number(e.value(index))));
        xml->writeAttributes(attributes);

        xml->writeEndElement();
    }

    xml->writeEndElement();
}

class FriendlyQObject: public QObject
{
public:
    static const QMetaObject *qtMeta() { return &staticQtMetaObject; }
};

void dump(const QMetaObject *meta, QXmlStreamWriter *xml)
{
    xml->writeStartElement("type");

    QXmlStreamAttributes attributes;
    attributes.append(QXmlStreamAttribute("name", convertToQmlType(meta->className())));

    if (const QDeclarativeType *qmlTy = qmlTypeByCppName.value(meta->className())) {
        attributes.append(QXmlStreamAttribute("version", QString("%1.%2").arg(qmlTy->majorVersion()).arg(qmlTy->minorVersion())));
    }

    QString version;

    if (meta->superClass())
        attributes.append(QXmlStreamAttribute("extends", convertToQmlType(meta->superClass()->className())));

    if (! version.isEmpty())
        attributes.append(QXmlStreamAttribute("version", version));

    xml->writeAttributes(attributes);

    for (int index = meta->enumeratorOffset(); index < meta->enumeratorCount(); ++index)
        dump(meta->enumerator(index), xml);

    for (int index = meta->propertyOffset(); index < meta->propertyCount(); ++index)
        dump(meta->property(index), xml);

    for (int index = meta->methodOffset(); index < meta->methodCount(); ++index)
        dump(meta->method(index), xml);

    xml->writeEndElement();
}

void writeScriptElement(QXmlStreamWriter *xml)
{
    xml->writeStartElement("type");
    {
        QXmlStreamAttributes attributes;
        attributes.append(QXmlStreamAttribute("name", "Script"));
        xml->writeAttributes(attributes);
    }

    xml->writeStartElement("property");
    {
        QXmlStreamAttributes attributes;
        attributes.append(QXmlStreamAttribute("name", "script"));
        attributes.append(QXmlStreamAttribute("type", "string"));
        xml->writeAttributes(attributes);
    }
    xml->writeEndElement();

    xml->writeStartElement("property");
    {
        QXmlStreamAttributes attributes;
        attributes.append(QXmlStreamAttribute("name", "source"));
        attributes.append(QXmlStreamAttribute("type", "QUrl"));
        xml->writeAttributes(attributes);
    }
    xml->writeEndElement();

    xml->writeEndElement();
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QDeclarativeView view;
    QDeclarativeEngine *engine = view.engine();

    cppToQml.insert("QString", "string");

    QSet<const QMetaObject *> metas;

    metas.insert(FriendlyQObject::qtMeta());

    foreach (const QDeclarativeType *ty, QDeclarativeMetaType::qmlTypes()) {
        cppToQml.insert(ty->metaObject()->className(), ty->qmlTypeName());
        qmlTypeByCppName.insert(ty->metaObject()->className(), ty);
        processDeclarativeType(ty, &metas);
    }

    foreach (const QDeclarativeType *ty, QDeclarativeMetaType::qmlTypes()) {
        QByteArray tyName = ty->qmlTypeName();
        tyName = tyName.mid(tyName.lastIndexOf('/') + 1);

        QByteArray code;
        code += "import Qt 4.6;\n";
        code += tyName;
        code += " {}\n";

        QDeclarativeComponent c(engine);
        c.setData(code, QUrl("xxx"));
        processObject(c.create(), &metas);
    }

    QByteArray bytes;
    QXmlStreamWriter xml(&bytes);
    xml.setAutoFormatting(true);

    xml.writeStartDocument("1.0");
    xml.writeStartElement("module");

    QMap<QString, const QMetaObject *> nameToMeta;
    foreach (const QMetaObject *meta, metas) {
        nameToMeta.insert(convertToQmlType(meta->className()), meta);
    }
    foreach (const QMetaObject *meta, nameToMeta) {
        dump(meta, &xml);
    }

    writeScriptElement(&xml);

    xml.writeEndElement();
    xml.writeEndDocument();

    std::cout << bytes.constData();

    QTimer timer;
    timer.setSingleShot(true);
    timer.setInterval(0);
    QObject::connect(&timer, SIGNAL(timeout()), &app, SLOT(quit()));

    timer.start();

    return app.exec();
}
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkDiffusionHeaderSiemensDICOMFileReader.h"

#include "gdcmScanner.h"
#include "gdcmReader.h"

enum SiemensDiffusionHeaderType {
  SIEMENS_CSA1 = 0,
  SIEMENS_CSA2
};

static SiemensDiffusionHeaderType GetHeaderType( std::string header )
{
  // The CSA2 format begins with the string ‘SV10’, the CSA1 format does not.
  if( header.find("SV10") != std::string::npos )
  {
    return SIEMENS_CSA2;
  }
  else
  {
    return SIEMENS_CSA1;
  }
}

struct Siemens_Header_Format
{
  Siemens_Header_Format( size_t nlen,
                         size_t vm,
                         size_t vr,
                         size_t syngodt,
                         size_t nitems )
    : NameLength( nlen ),
      VM( vm ),
      VR( vr ),
      Syngodt( syngodt ),
      NumItems( nitems ),
      Delimiter( "\0" )
  {}
  size_t NameLength;
  std::string Delimiter;
  size_t VM;
  size_t VR;
  size_t Syngodt;
  size_t NumItems;
};

static std::vector< Siemens_Header_Format > SiemensFormatsCollection;

struct DiffusionImageHeaderInformation
{
  DiffusionImageHeaderInformation()
    : b_value(0)
  {
    g_vector.fill(0);
  }

  void Print()
  {
    MITK_INFO << " DiffusionImageHeaderInformation : \n"
              << "    : b value  : " << b_value << "\n"
              << "    : gradient : " << g_vector << "\n --- \n";
  }

  unsigned int b_value;
  vnl_vector_fixed< double, 3> g_vector;
};

static bool ParseInputString( std::string input, std::vector<double>& values, Siemens_Header_Format format_specs )
{

  int offset = 84;
  int vm = *(input.c_str() + format_specs.NameLength );

  for (int k = 0; k < vm; k++)
  {
    int itemLength = *(input.c_str() + offset + 4);

    int strideSize = static_cast<int> (ceil(static_cast<double>(itemLength)/4) * 4);
    std::string valueString = input.substr( offset+16, itemLength );

    double value = atof( valueString.c_str() );
    values.push_back( value );

    offset += 16+strideSize;
  }

  return true;
}

/**
 * @brief Extract b value from the siemens diffusion tag
 */
static bool ExtractDiffusionTagInformation( std::string tag_value, DiffusionImageHeaderInformation& values)
{
  SiemensDiffusionHeaderType hformat = GetHeaderType( tag_value );
  Siemens_Header_Format specs = SiemensFormatsCollection.at( hformat );

  MITK_INFO << " Header format: " << hformat;
  MITK_INFO << " :: Retrieving b value. ";

  std::string::size_type tag_position =
      tag_value.find( "B_value", 0 );

  if( tag_position == std::string::npos )
  {
    MITK_ERROR << "No b value information found. ";
    return false;
  }

  std::string value_string = tag_value.substr( tag_position, tag_value.size() - tag_position + 1 );

  std::vector<double> value_array;
  if( ParseInputString(value_string, value_array, specs) )
  {
    values.b_value = value_array.at(0);
  }

  // search for GradientDirectionInformation if the bvalue is not null
  if( values.b_value > 0 )
  {
    std::string::size_type tag_position = tag_value.find( "DiffusionGradientDirection", 0 );
    if( tag_position == std::string::npos )
    {
      MITK_INFO << "No gradient direction information. ";
    }

    value_array.clear();
    std::string gradient_direction_str = tag_value.substr( tag_position, tag_value.size() - tag_position + 1 );

    if( ParseInputString(gradient_direction_str, value_array, specs) )
    {
      if( value_array.size() != 3 )
      {
        MITK_ERROR << " Retrieved gradient information of length " << value_array.size();
        return false;
      }

      for( unsigned int i=0; i<value_array.size(); i++)
      {
        values.g_vector[i] = value_array.at(i);
      }
    }

  }

  return true;
}

mitk::DiffusionHeaderSiemensDICOMFileReader
::DiffusionHeaderSiemensDICOMFileReader()
{
  Siemens_Header_Format Siemens_CSA1_Format( 64, sizeof(int32_t), 4, sizeof(int32_t), sizeof(int32_t)  );
  Siemens_Header_Format Siemens_CSA2_Format( 64, sizeof(int32_t), 4, sizeof(int32_t), sizeof(int32_t)  );

  SiemensFormatsCollection.push_back( Siemens_CSA1_Format );
  SiemensFormatsCollection.push_back( Siemens_CSA2_Format );
}

mitk::DiffusionHeaderSiemensDICOMFileReader
::~DiffusionHeaderSiemensDICOMFileReader()
{

}

bool mitk::DiffusionHeaderSiemensDICOMFileReader
::ReadDiffusionHeader(std::string filename)
{
  gdcm::Reader gdcmReader;
  gdcmReader.SetFileName( filename.c_str() );

  gdcmReader.Read();

  MITK_INFO << " -- Analyzing: " << filename;

  const gdcm::DataSet& dataset = gdcmReader.GetFile().GetDataSet();

  const gdcm::Tag t_sie_diffusion( 0x0029,0x1010 );
  const gdcm::Tag t_sie_diffusion_vec( 0x0029,0x100e );
  const gdcm::Tag t_sie_diffusion2( 0x0029,0x100c );

  std::string siemens_diffusionheader_str;
  if( RevealBinaryTag( t_sie_diffusion, dataset, siemens_diffusionheader_str ) )
  {
    DiffusionImageHeaderInformation values;
    ExtractDiffusionTagInformation( siemens_diffusionheader_str, values );

    values.Print();
  }

}
<commit_msg>Isotropic data handling<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkDiffusionHeaderSiemensDICOMFileReader.h"

#include "gdcmScanner.h"
#include "gdcmReader.h"

enum SiemensDiffusionHeaderType {
  SIEMENS_CSA1 = 0,
  SIEMENS_CSA2
};

static SiemensDiffusionHeaderType GetHeaderType( std::string header )
{
  // The CSA2 format begins with the string ‘SV10’, the CSA1 format does not.
  if( header.find("SV10") != std::string::npos )
  {
    return SIEMENS_CSA2;
  }
  else
  {
    return SIEMENS_CSA1;
  }
}

struct Siemens_Header_Format
{
  Siemens_Header_Format( size_t nlen,
                         size_t vm,
                         size_t vr,
                         size_t syngodt,
                         size_t nitems )
    : NameLength( nlen ),
      VM( vm ),
      VR( vr ),
      Syngodt( syngodt ),
      NumItems( nitems ),
      Delimiter( "\0" )
  {}
  size_t NameLength;
  std::string Delimiter;
  size_t VM;
  size_t VR;
  size_t Syngodt;
  size_t NumItems;
};

static std::vector< Siemens_Header_Format > SiemensFormatsCollection;

struct DiffusionImageHeaderInformation
{
  DiffusionImageHeaderInformation()
    : b_value(0),
      isotropic(false)
  {
    g_vector.fill(0);
  }

  void Print()
  {
    MITK_INFO << " DiffusionImageHeaderInformation : \n"
              << "    : b value   : " << b_value << "\n"
              << "    : gradient  : " << g_vector << "\n"
              << "    : isotropic : " << isotropic << "\n --- \n";
  }

  unsigned int b_value;
  vnl_vector_fixed< double, 3> g_vector;
  bool isotropic;
};

static bool ParseInputString( std::string input, std::vector<double>& values, Siemens_Header_Format format_specs )
{

  int offset = 84;
  int vm = *(input.c_str() + format_specs.NameLength );

  for (int k = 0; k < vm; k++)
  {
    int itemLength = *(input.c_str() + offset + 4);

    int strideSize = static_cast<int> (ceil(static_cast<double>(itemLength)/4) * 4);
    std::string valueString = input.substr( offset+16, itemLength );

    double value = atof( valueString.c_str() );
    values.push_back( value );

    offset += 16+strideSize;
  }

  return true;
}

/**
 * @brief Extract b value from the siemens diffusion tag
 */
static bool ExtractDiffusionTagInformation( std::string tag_value, DiffusionImageHeaderInformation& values)
{
  SiemensDiffusionHeaderType hformat = GetHeaderType( tag_value );
  Siemens_Header_Format specs = SiemensFormatsCollection.at( hformat );

  MITK_DEBUG << " Header format: " << hformat;
  MITK_DEBUG << " :: Retrieving b value. ";

  std::string::size_type tag_position =
      tag_value.find( "B_value", 0 );

  if( tag_position == std::string::npos )
  {
    MITK_ERROR << "No b value information found. ";
    return false;
  }

  std::string value_string = tag_value.substr( tag_position, tag_value.size() - tag_position + 1 );

  std::vector<double> value_array;
  if( ParseInputString(value_string, value_array, specs) )
  {
    values.b_value = value_array.at(0);
  }

  // search for GradientDirectionInformation if the bvalue is not null
  if( values.b_value > 0 )
  {
    std::string::size_type tag_position = tag_value.find( "DiffusionGradientDirection", 0 );
    // Possibly it is a IVIM dataset, i.e. the gradient direction is not relevant
    // and possibly either not set or set to zero
    if( tag_position == std::string::npos )
    {
      MITK_WARN << "No gradient direction information, but non-zero b-value. Possibly an IVIM dataset. " << "\n"
                << "Setting gradient to (1,1,1).";

      values.isotropic = true;
      values.g_vector.fill(1);
      return false;
    }

    value_array.clear();
    std::string gradient_direction_str = tag_value.substr( tag_position, tag_value.size() - tag_position + 1 );

    if( ParseInputString(gradient_direction_str, value_array, specs) )
    {
      if( value_array.size() != 3 )
      {
        MITK_ERROR << " Retrieved gradient information of length " << value_array.size();
        return false;
      }

      for( unsigned int i=0; i<value_array.size(); i++)
      {
        values.g_vector[i] = value_array.at(i);
      }

      // Test for isotropic data (i.e. IVIM)
      if( values.g_vector.two_norm() < vnl_math::eps )
      {
        values.g_vector.fill(1);
        values.isotropic = true;
      }
    }

  }

  return true;
}

mitk::DiffusionHeaderSiemensDICOMFileReader
::DiffusionHeaderSiemensDICOMFileReader()
{
  Siemens_Header_Format Siemens_CSA1_Format( 64, sizeof(int32_t), 4, sizeof(int32_t), sizeof(int32_t)  );
  Siemens_Header_Format Siemens_CSA2_Format( 64, sizeof(int32_t), 4, sizeof(int32_t), sizeof(int32_t)  );

  SiemensFormatsCollection.push_back( Siemens_CSA1_Format );
  SiemensFormatsCollection.push_back( Siemens_CSA2_Format );
}

mitk::DiffusionHeaderSiemensDICOMFileReader
::~DiffusionHeaderSiemensDICOMFileReader()
{

}

bool mitk::DiffusionHeaderSiemensDICOMFileReader
::ReadDiffusionHeader(std::string filename)
{
  gdcm::Reader gdcmReader;
  gdcmReader.SetFileName( filename.c_str() );

  gdcmReader.Read();

  MITK_INFO << " -- Analyzing: " << filename;

  const gdcm::DataSet& dataset = gdcmReader.GetFile().GetDataSet();

  const gdcm::Tag t_sie_diffusion( 0x0029,0x1010 );
  const gdcm::Tag t_sie_diffusion_vec( 0x0029,0x100e );
  const gdcm::Tag t_sie_diffusion2( 0x0029,0x100c );

  std::string siemens_diffusionheader_str;
  if( RevealBinaryTag( t_sie_diffusion, dataset, siemens_diffusionheader_str ) )
  {
    DiffusionImageHeaderInformation values;
    ExtractDiffusionTagInformation( siemens_diffusionheader_str, values );

    values.Print();
  }

}
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Nathan Osman
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 **/

#include <QApplication>
#include <QIcon>
#include <QStyle>

#include "transfermodel.h"
#include "transfermodel_p.h"
#include "transferreceiver.h"
#include "transfersender.h"

TransferModelPrivate::TransferModelPrivate(TransferModel *transferModel)
    : QObject(transferModel),
      q(transferModel)
{
}

TransferModelPrivate::~TransferModelPrivate()
{
    qDeleteAll(transfers);
}

void TransferModelPrivate::add(Transfer *transfer)
{
    q->beginInsertRows(QModelIndex(), transfers.count(), transfers.count());
    transfers.append(transfer);
    q->endInsertRows();

    // Whenever the transfer changes, emit the appropriate signal
    connect(transfer, &Transfer::dataChanged, [this, transfer]() {
        int index = transfers.indexOf(transfer);
        emit q->dataChanged(q->index(index, 0), q->index(index, TransferModel::ColumnCount - 1));
    });

    transfer->start();
}

TransferModel::TransferModel()
    : d(new TransferModelPrivate(this))
{
}

int TransferModel::rowCount(const QModelIndex &parent) const
{
    return parent.isValid() ? 0 : d->transfers.count();
}

int TransferModel::columnCount(const QModelIndex &parent) const
{
    return parent.isValid() ? 0 : ColumnCount;
}

QVariant TransferModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid() || index.model() != this) {
        return QVariant();
    }

    Transfer *transfer = d->transfers.at(index.row());

    switch(role) {
    case Qt::DisplayRole:
        switch(index.column()) {
        case ColumnDeviceName:
            return transfer->deviceName();
        case ColumnProgress:
            return QString("%1%").arg(transfer->progress());
        case ColumnState:
            switch(transfer->state()) {
            case Connecting:
                return tr("Connecting");
            case InProgress:
                return tr("In Progress");
            case Canceled:
                return tr("Canceled");
            case Failed:
                return tr("Failed: %1").arg(transfer->error());
            case Succeeded:
                return tr("Succeeded");
            }
        }
        break;
    case Qt::DecorationRole:
        if(index.column() == ColumnDeviceName) {
            switch(transfer->direction()) {
            case Send:
                return QApplication::style()->standardIcon(QStyle::SP_ArrowUp);
            case Receive:
                return QApplication::style()->standardIcon(QStyle::SP_ArrowDown);
            }
        }
        break;
    case DeviceNameRole:
        return transfer->deviceName();
    case ProgressRole:
        return transfer->progress();
    case DirectionRole:
        return transfer->direction();
    case StateRole:
        return transfer->state();
    case ErrorRole:
        return transfer->error();
    }

    return QVariant();
}

QVariant TransferModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(orientation != Qt::Horizontal || role != Qt::DisplayRole) {
        return QAbstractTableModel::headerData(section, orientation, role);
    }

    switch(section) {
    case ColumnDeviceName:
        return tr("Device Name");
    case ColumnProgress:
        return tr("Progress");
    case ColumnState:
        return tr("Status");
    }

    return QVariant();
}

QHash<int, QByteArray> TransferModel::roleNames() const
{
    return {
        {DeviceNameRole, "device_name"},
        {ProgressRole, "progress"},
        {DirectionRole, "direction"},
        {StateRole, "state"},
        {ErrorRole, "error"}
    };
}

void TransferModel::addReceiver(qintptr socketDescriptor)
{
    d->add(new TransferReceiver(socketDescriptor));
}

void TransferModel::addSender(const QString &deviceName, const QHostAddress &address, quint16 port, BundlePointer bundle)
{
    d->add(new TransferSender(deviceName, address, port, bundle));
}

void TransferModel::cancel(int index)
{
    if(index > 0 && index < d->transfers.count()) {
        d->transfers.at(index)->cancel();
    }
}

void TransferModel::restart(int index)
{
    if(index > 0 && index < d->transfers.count()) {
        d->transfers.at(index)->restart();
    }
}

void TransferModel::clear()
{
    // Iterate over the list in reverse to preserve indices when items are removed
    for(int i = d->transfers.count() - 1; i >= 0; --i) {
        Transfer *transfer = d->transfers.at(i);

        // Remove only items that are finished
        if(transfer->state() == Canceled || transfer->state() == Failed || transfer->state() == Succeeded) {
            beginRemoveRows(QModelIndex(), i, i);
            d->transfers.removeAt(i);
            endRemoveRows();

            delete transfer;
        }
    }
}
<commit_msg>Added coloring to state in the transfer window.<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Nathan Osman
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 **/

#include <QApplication>
#include <QBrush>
#include <QIcon>
#include <QStyle>

#include "transfermodel.h"
#include "transfermodel_p.h"
#include "transferreceiver.h"
#include "transfersender.h"

TransferModelPrivate::TransferModelPrivate(TransferModel *transferModel)
    : QObject(transferModel),
      q(transferModel)
{
}

TransferModelPrivate::~TransferModelPrivate()
{
    qDeleteAll(transfers);
}

void TransferModelPrivate::add(Transfer *transfer)
{
    q->beginInsertRows(QModelIndex(), transfers.count(), transfers.count());
    transfers.append(transfer);
    q->endInsertRows();

    // Whenever the transfer changes, emit the appropriate signal
    connect(transfer, &Transfer::dataChanged, [this, transfer]() {
        int index = transfers.indexOf(transfer);
        emit q->dataChanged(q->index(index, 0), q->index(index, TransferModel::ColumnCount - 1));
    });

    transfer->start();
}

TransferModel::TransferModel()
    : d(new TransferModelPrivate(this))
{
}

int TransferModel::rowCount(const QModelIndex &parent) const
{
    return parent.isValid() ? 0 : d->transfers.count();
}

int TransferModel::columnCount(const QModelIndex &parent) const
{
    return parent.isValid() ? 0 : ColumnCount;
}

QVariant TransferModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid() || index.model() != this) {
        return QVariant();
    }

    Transfer *transfer = d->transfers.at(index.row());

    switch(role) {
    case Qt::DisplayRole:
        switch(index.column()) {
        case ColumnDeviceName:
            return transfer->deviceName();
        case ColumnProgress:
            return QString("%1%").arg(transfer->progress());
        case ColumnState:
            switch(transfer->state()) {
            case Connecting:
                return tr("Connecting");
            case InProgress:
                return tr("In Progress");
            case Canceled:
                return tr("Canceled");
            case Failed:
                return tr("Failed: %1").arg(transfer->error());
            case Succeeded:
                return tr("Succeeded");
            }
        }
        break;
    case Qt::DecorationRole:
        if(index.column() == ColumnDeviceName) {
            switch(transfer->direction()) {
            case Send:
                return QApplication::style()->standardIcon(QStyle::SP_ArrowUp);
            case Receive:
                return QApplication::style()->standardIcon(QStyle::SP_ArrowDown);
            }
        }
        break;
    case Qt::ForegroundRole:
        if(index.column() == ColumnState) {
            switch(transfer->state()) {
            case Canceled:
            case Failed:
                return QBrush(Qt::darkRed);
            case Succeeded:
                return QBrush(Qt::darkGreen);
            default:
                break;
            }
        }
        break;
    case DeviceNameRole:
        return transfer->deviceName();
    case ProgressRole:
        return transfer->progress();
    case DirectionRole:
        return transfer->direction();
    case StateRole:
        return transfer->state();
    case ErrorRole:
        return transfer->error();
    }

    return QVariant();
}

QVariant TransferModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(orientation != Qt::Horizontal || role != Qt::DisplayRole) {
        return QAbstractTableModel::headerData(section, orientation, role);
    }

    switch(section) {
    case ColumnDeviceName:
        return tr("Device Name");
    case ColumnProgress:
        return tr("Progress");
    case ColumnState:
        return tr("Status");
    }

    return QVariant();
}

QHash<int, QByteArray> TransferModel::roleNames() const
{
    return {
        {DeviceNameRole, "device_name"},
        {ProgressRole, "progress"},
        {DirectionRole, "direction"},
        {StateRole, "state"},
        {ErrorRole, "error"}
    };
}

void TransferModel::addReceiver(qintptr socketDescriptor)
{
    d->add(new TransferReceiver(socketDescriptor));
}

void TransferModel::addSender(const QString &deviceName, const QHostAddress &address, quint16 port, BundlePointer bundle)
{
    d->add(new TransferSender(deviceName, address, port, bundle));
}

void TransferModel::cancel(int index)
{
    if(index > 0 && index < d->transfers.count()) {
        d->transfers.at(index)->cancel();
    }
}

void TransferModel::restart(int index)
{
    if(index > 0 && index < d->transfers.count()) {
        d->transfers.at(index)->restart();
    }
}

void TransferModel::clear()
{
    // Iterate over the list in reverse to preserve indices when items are removed
    for(int i = d->transfers.count() - 1; i >= 0; --i) {
        Transfer *transfer = d->transfers.at(i);

        // Remove only items that are finished
        if(transfer->state() == Canceled || transfer->state() == Failed || transfer->state() == Succeeded) {
            beginRemoveRows(QModelIndex(), i, i);
            d->transfers.removeAt(i);
            endRemoveRows();

            delete transfer;
        }
    }
}
<|endoftext|>


<commit_before>/*!
 * Copyright 2014 by Contributors
 * \file updater_prune-inl.hpp
 * \brief prune a tree given the statistics
 * \author Tianqi Chen
 */
#ifndef XGBOOST_TREE_UPDATER_PRUNE_INL_HPP_
#define XGBOOST_TREE_UPDATER_PRUNE_INL_HPP_

#include <vector>
#include "./param.h"
#include "./updater.h"
#include "./updater_sync-inl.hpp"

namespace xgboost {
namespace tree {
/*! \brief pruner that prunes a tree after growing finishes */
class TreePruner: public IUpdater {
 public:
  virtual ~TreePruner(void) {}
  // set training parameter
  virtual void SetParam(const char *name, const char *val) {
    using namespace std;
    param.SetParam(name, val);
    syncher.SetParam(name, val);
    if (!strcmp(name, "silent")) silent = atoi(val);
  }
  // update the tree, do pruning
  virtual void Update(const std::vector<bst_gpair> &gpair,
                      IFMatrix *p_fmat,
                      const BoosterInfo &info,
                      const std::vector<RegTree*> &trees) {
    // rescale learning rate according to size of trees
    float lr = param.learning_rate;
    param.learning_rate = lr / trees.size();
    for (size_t i = 0; i < trees.size(); ++i) {
      this->DoPrune(*trees[i]);
    }
    param.learning_rate = lr;
    syncher.Update(gpair, p_fmat, info, trees);
  }

 private:
  // try to prune off current leaf
  inline int TryPruneLeaf(RegTree &tree, int nid, int depth, int npruned) { // NOLINT(*)
    if (tree[nid].is_root()) return npruned;
    int pid = tree[nid].parent();
    RegTree::NodeStat &s = tree.stat(pid);
    ++s.leaf_child_cnt;
    if (s.leaf_child_cnt >= 2 && param.need_prune(s.loss_chg, depth - 1)) {
      // need to be pruned
      tree.ChangeToLeaf(pid, param.learning_rate * s.base_weight);
      // tail recursion
      return this->TryPruneLeaf(tree, pid, depth - 1, npruned+2);
    } else {
      return npruned;
    }
  }
  /*! \brief do pruning of a tree */
  inline void DoPrune(RegTree &tree) { // NOLINT(*)
    int npruned = 0;
    // initialize auxiliary statistics
    for (int nid = 0; nid < tree.param.num_nodes; ++nid) {
      tree.stat(nid).leaf_child_cnt = 0;
    }
    for (int nid = 0; nid < tree.param.num_nodes; ++nid) {
      if (tree[nid].is_leaf()) {
        npruned = this->TryPruneLeaf(tree, nid, tree.GetDepth(nid), npruned);
      }
    }
    if (silent == 0) {
      utils::Printf("tree pruning end, %d roots, %d extra nodes, %d pruned nodes ,max_depth=%d\n",
                    tree.param.num_roots, tree.num_extra_nodes(), npruned, tree.MaxDepth());
    }
  }

 private:
  // synchronizer
  TreeSyncher syncher;
  // shutup
  int silent;
  // training parameter
  TrainParam param;
};
}  // namespace tree
}  // namespace xgboost
#endif  // XGBOOST_TREE_UPDATER_PRUNE_INL_HPP_
<commit_msg>fix minor typo<commit_after>/*!
 * Copyright 2014 by Contributors
 * \file updater_prune-inl.hpp
 * \brief prune a tree given the statistics
 * \author Tianqi Chen
 */
#ifndef XGBOOST_TREE_UPDATER_PRUNE_INL_HPP_
#define XGBOOST_TREE_UPDATER_PRUNE_INL_HPP_

#include <vector>
#include "./param.h"
#include "./updater.h"
#include "./updater_sync-inl.hpp"

namespace xgboost {
namespace tree {
/*! \brief pruner that prunes a tree after growing finishes */
class TreePruner: public IUpdater {
 public:
  virtual ~TreePruner(void) {}
  // set training parameter
  virtual void SetParam(const char *name, const char *val) {
    using namespace std;
    param.SetParam(name, val);
    syncher.SetParam(name, val);
    if (!strcmp(name, "silent")) silent = atoi(val);
  }
  // update the tree, do pruning
  virtual void Update(const std::vector<bst_gpair> &gpair,
                      IFMatrix *p_fmat,
                      const BoosterInfo &info,
                      const std::vector<RegTree*> &trees) {
    // rescale learning rate according to size of trees
    float lr = param.learning_rate;
    param.learning_rate = lr / trees.size();
    for (size_t i = 0; i < trees.size(); ++i) {
      this->DoPrune(*trees[i]);
    }
    param.learning_rate = lr;
    syncher.Update(gpair, p_fmat, info, trees);
  }

 private:
  // try to prune off current leaf
  inline int TryPruneLeaf(RegTree &tree, int nid, int depth, int npruned) { // NOLINT(*)
    if (tree[nid].is_root()) return npruned;
    int pid = tree[nid].parent();
    RegTree::NodeStat &s = tree.stat(pid);
    ++s.leaf_child_cnt;
    if (s.leaf_child_cnt >= 2 && param.need_prune(s.loss_chg, depth - 1)) {
      // need to be pruned
      tree.ChangeToLeaf(pid, param.learning_rate * s.base_weight);
      // tail recursion
      return this->TryPruneLeaf(tree, pid, depth - 1, npruned+2);
    } else {
      return npruned;
    }
  }
  /*! \brief do pruning of a tree */
  inline void DoPrune(RegTree &tree) { // NOLINT(*)
    int npruned = 0;
    // initialize auxiliary statistics
    for (int nid = 0; nid < tree.param.num_nodes; ++nid) {
      tree.stat(nid).leaf_child_cnt = 0;
    }
    for (int nid = 0; nid < tree.param.num_nodes; ++nid) {
      if (tree[nid].is_leaf()) {
        npruned = this->TryPruneLeaf(tree, nid, tree.GetDepth(nid), npruned);
      }
    }
    if (silent == 0) {
      utils::Printf("tree pruning end, %d roots, %d extra nodes, %d pruned nodes, max_depth=%d\n",
                    tree.param.num_roots, tree.num_extra_nodes(), npruned, tree.MaxDepth());
    }
  }

 private:
  // synchronizer
  TreeSyncher syncher;
  // shutup
  int silent;
  // training parameter
  TrainParam param;
};
}  // namespace tree
}  // namespace xgboost
#endif  // XGBOOST_TREE_UPDATER_PRUNE_INL_HPP_
<|endoftext|>


<commit_before>#include <kernel/timers.hpp>

#include <kernel/os.hpp>
#include <service>
#include <smp>
#include <statman>
#include <map>
#include <vector>

using namespace std::chrono;
typedef Timers::duration_t duration_t;
typedef Timers::handler_t  handler_t;

static void sched_timer(duration_t when, Timers::id_t id);

struct Timer
{
  Timer(duration_t p, handler_t cb)
    : period(p), callback(cb), deferred_destruct(false) {}

  bool is_alive() const noexcept {
    return deferred_destruct == false;
  }

  bool is_oneshot() const noexcept {
    return period.count() == 0;
  }

  void reset() {
    callback.reset();
    deferred_destruct = false;
  }

  duration_t period;
  handler_t  callback;
  bool deferred_destruct = false;
};

/**
 * 1. There are no restrictions on when timers can be started or stopped
 * 2. A period of 0 means start a one-shot timer
 * 3. Each timer is a separate object living in a "fixed" vector
 * 4. A dead timer is simply a timer which has its handler reset, as well as
 *     having been removed from schedule
 * 5. No timer may be scheduled more than once at a time, as that will needlessly
 *     inflate the schedule container, as well as complicate stopping timers
 * 6. Free timer IDs are retrieved from a stack of free timer IDs (or through
 *     expanding the "fixed" vector)
**/
static bool signal_ready = false;

struct alignas(SMP_ALIGN) timer_system
{
  bool     is_running  = false;
  uint32_t dead_timers = 0;
  Timers::start_func_t arch_start_func;
  Timers::stop_func_t  arch_stop_func;
  std::vector<Timer>        timers;
  std::vector<Timers::id_t> free_timers;
  // timers sorted by timestamp
  std::multimap<duration_t, Timers::id_t> scheduled;
  /** Stats */
  int64_t*  oneshot_started;
  int64_t*  oneshot_stopped;
  uint32_t* periodic_started;
  uint32_t* periodic_stopped;
};
static SMP_ARRAY<timer_system> systems;

static inline timer_system& get() {
  return PER_CPU(systems);
}

void Timers::init(const start_func_t& start, const stop_func_t& stop)
{
  auto& system = get();
  // architecture specific start and stop functions
  system.arch_start_func = start;
  system.arch_stop_func  = stop;

  std::string CPU = "cpu" + std::to_string(SMP::cpu_id());
  system.oneshot_started = (int64_t*) &Statman::get().create(Stat::UINT64, CPU + ".timers.oneshot_started").get_uint64();
  system.oneshot_stopped = (int64_t*) &Statman::get().create(Stat::UINT64, CPU + ".timers.oneshot_stopped").get_uint64();
  system.periodic_started = &Statman::get().create(Stat::UINT32, CPU + ".timers.periodic_started").get_uint32();
  system.periodic_stopped = &Statman::get().create(Stat::UINT32, CPU + ".timers.periodic_stopped").get_uint32();
}

bool Timers::is_ready()
{
  return signal_ready;
}
void Timers::ready()
{
  signal_ready = true;
  // begin processing timers if any are queued
  if (get().is_running == false) {
    timers_handler();
  }
  // call Service::ready(), because timer system is ready!
  Service::ready();
}

Timers::id_t Timers::periodic(duration_t when, duration_t period, handler_t handler)
{
  auto& system = get();
  Timers::id_t id;

  if (UNLIKELY(system.free_timers.empty()))
  {
    if (LIKELY(system.dead_timers))
    {
      // look for dead timer
      auto it = system.scheduled.begin();
      while (it != system.scheduled.end()) {
        // take over this timer, if dead
        Timers::id_t id = it->second;

        if (system.timers[id].deferred_destruct)
        {
          system.dead_timers--;
          // remove from schedule
          system.scheduled.erase(it);
          // reset timer
          system.timers[id].reset();
          // reuse timer
          new (&system.timers[id]) Timer(period, handler);
          sched_timer(when, id);

          // Stat increment timer started
          if (system.timers[id].is_oneshot()) {
            if (system.oneshot_started) (*system.oneshot_started)++;
          } else {
            if (system.periodic_started) (*system.periodic_started)++;
          }

          return id;
        }
        ++it;
      }
    }
    id = system.timers.size();
    // occupy new slot
    system.timers.emplace_back(period, handler);
  }
  else {
    // get free timer slot
    id = system.free_timers.back();
    system.free_timers.pop_back();

    // occupy free slot
    new (&system.timers[id]) Timer(period, handler);
  }

  // immediately schedule timer
  sched_timer(when, id);

  // Stat increment timer started
  if (system.timers[id].is_oneshot()) {
    if (system.oneshot_started) (*system.oneshot_started)++;
  } else {
    if (system.periodic_started) (*system.periodic_started)++;
  }

  return id;
}

void Timers::stop(Timers::id_t id)
{
  auto& system = get();
  if (LIKELY(system.timers[id].deferred_destruct == false))
  {
    // mark as dead already
    system.timers[id].deferred_destruct = true;
    // free resources immediately
    system.timers[id].callback.reset();
    system.dead_timers++;

    if (system.timers[id].is_oneshot())
      (*system.oneshot_stopped)++;
    else
      (*system.periodic_stopped)++;
  }
}

size_t Timers::active()
{
  auto& system = get();
  return system.scheduled.size();
}

/// time functions ///

static inline std::chrono::microseconds now() noexcept
{
  return microseconds(OS::micros_since_boot());
}

/// scheduling ///

void Timers::timers_handler()
{
  auto& system = get();
  // assume the hardware timer called this function
  system.is_running = false;

  while (LIKELY(!system.scheduled.empty()))
  {
    auto it         = system.scheduled.begin();
    auto when       = it->first;
    Timers::id_t id = it->second;

    // remove dead timers
    if (system.timers[id].deferred_destruct)
    {
      system.dead_timers--;
      // remove from schedule
      system.scheduled.erase(it);
      // delete timer
      system.timers[id].reset();
      system.free_timers.push_back(id);
    }
    else
    {
      auto ts_now = now();

      if (ts_now >= when) {
        // erase immediately
        system.scheduled.erase(it);

        // call the users callback function
        system.timers[id].callback(id);
        // if the timers struct was modified in callback, eg. due to
        // creating a timer, then the timer reference below would have
        // been invalidated, hence why its BELOW, AND MUST STAY THERE
        auto& timer = system.timers[id];

        // oneshot timers are automatically freed
        if (timer.deferred_destruct || timer.is_oneshot())
        {
          timer.reset();
          if (timer.deferred_destruct) system.dead_timers--;
          system.free_timers.push_back(id);
        }
        else if (timer.is_oneshot() == false)
        {
          // if the timer is recurring, we will simply reschedule it
          // NOTE: we are carefully using (when + period) to avoid drift
          system.scheduled.
            emplace(std::piecewise_construct,
                    std::forward_as_tuple(when + timer.period),
                    std::forward_as_tuple(id));
        }

      } else {
        // not yet time, so schedule it for later
        system.is_running = true;
        system.arch_start_func(when - ts_now);
        // exit early, because we have nothing more to do,
        // and there is a deferred handler
        return;
      }
    }
  }
  // stop hardware timer, since no timers are enabled
  system.arch_stop_func();
}
static void sched_timer(duration_t when, Timers::id_t id)
{
  auto& system = get();
  system.scheduled.
    emplace(std::piecewise_construct,
            std::forward_as_tuple(now() + when),
            std::forward_as_tuple(id));

  // dont start any hardware until after calibration
  if (UNLIKELY(!signal_ready)) return;

  // if the hardware timer is not running, try starting it
  if (UNLIKELY(system.is_running == false)) {
    Timers::timers_handler();
    return;
  }
  // if the scheduled timer is the new front, restart timer
  auto it = system.scheduled.begin();
  if (it->second == id)
      Timers::timers_handler();
}
<commit_msg>kernel: Bounds check timers stop function<commit_after>#include <kernel/timers.hpp>

#include <kernel/os.hpp>
#include <service>
#include <smp>
#include <statman>
#include <map>
#include <vector>

using namespace std::chrono;
typedef Timers::duration_t duration_t;
typedef Timers::handler_t  handler_t;

static void sched_timer(duration_t when, Timers::id_t id);

struct Timer
{
  Timer(duration_t p, handler_t cb)
    : period(p), callback(cb), deferred_destruct(false) {}

  bool is_alive() const noexcept {
    return deferred_destruct == false;
  }

  bool is_oneshot() const noexcept {
    return period.count() == 0;
  }

  void reset() {
    callback.reset();
    deferred_destruct = false;
  }

  duration_t period;
  handler_t  callback;
  bool deferred_destruct = false;
};

/**
 * 1. There are no restrictions on when timers can be started or stopped
 * 2. A period of 0 means start a one-shot timer
 * 3. Each timer is a separate object living in a "fixed" vector
 * 4. A dead timer is simply a timer which has its handler reset, as well as
 *     having been removed from schedule
 * 5. No timer may be scheduled more than once at a time, as that will needlessly
 *     inflate the schedule container, as well as complicate stopping timers
 * 6. Free timer IDs are retrieved from a stack of free timer IDs (or through
 *     expanding the "fixed" vector)
**/
static bool signal_ready = false;

struct alignas(SMP_ALIGN) timer_system
{
  bool     is_running  = false;
  uint32_t dead_timers = 0;
  Timers::start_func_t arch_start_func;
  Timers::stop_func_t  arch_stop_func;
  std::vector<Timer>        timers;
  std::vector<Timers::id_t> free_timers;
  // timers sorted by timestamp
  std::multimap<duration_t, Timers::id_t> scheduled;
  /** Stats */
  int64_t*  oneshot_started;
  int64_t*  oneshot_stopped;
  uint32_t* periodic_started;
  uint32_t* periodic_stopped;
};
static SMP_ARRAY<timer_system> systems;

static inline timer_system& get() {
  return PER_CPU(systems);
}

void Timers::init(const start_func_t& start, const stop_func_t& stop)
{
  auto& system = get();
  // architecture specific start and stop functions
  system.arch_start_func = start;
  system.arch_stop_func  = stop;

  std::string CPU = "cpu" + std::to_string(SMP::cpu_id());
  system.oneshot_started = (int64_t*) &Statman::get().create(Stat::UINT64, CPU + ".timers.oneshot_started").get_uint64();
  system.oneshot_stopped = (int64_t*) &Statman::get().create(Stat::UINT64, CPU + ".timers.oneshot_stopped").get_uint64();
  system.periodic_started = &Statman::get().create(Stat::UINT32, CPU + ".timers.periodic_started").get_uint32();
  system.periodic_stopped = &Statman::get().create(Stat::UINT32, CPU + ".timers.periodic_stopped").get_uint32();
}

bool Timers::is_ready()
{
  return signal_ready;
}
void Timers::ready()
{
  signal_ready = true;
  // begin processing timers if any are queued
  if (get().is_running == false) {
    timers_handler();
  }
  // call Service::ready(), because timer system is ready!
  Service::ready();
}

Timers::id_t Timers::periodic(duration_t when, duration_t period, handler_t handler)
{
  auto& system = get();
  Timers::id_t id;

  if (UNLIKELY(system.free_timers.empty()))
  {
    if (LIKELY(system.dead_timers))
    {
      // look for dead timer
      auto it = system.scheduled.begin();
      while (it != system.scheduled.end()) {
        // take over this timer, if dead
        Timers::id_t id = it->second;

        if (system.timers[id].deferred_destruct)
        {
          system.dead_timers--;
          // remove from schedule
          system.scheduled.erase(it);
          // reset timer
          system.timers[id].reset();
          // reuse timer
          new (&system.timers[id]) Timer(period, handler);

          // Stat increment timer started
          if (system.timers[id].is_oneshot()) {
            if (system.oneshot_started) (*system.oneshot_started)++;
          } else {
            if (system.periodic_started) (*system.periodic_started)++;
          }

          sched_timer(when, id);
          return id;
        }
        ++it;
      }
    }
    id = system.timers.size();
    // occupy new slot
    system.timers.emplace_back(period, handler);
  }
  else {
    // get free timer slot
    id = system.free_timers.back();
    system.free_timers.pop_back();

    // occupy free slot
    new (&system.timers[id]) Timer(period, handler);
  }

  // Stat increment timer started
  if (system.timers[id].is_oneshot()) {
    if (system.oneshot_started) (*system.oneshot_started)++;
  } else {
    if (system.periodic_started) (*system.periodic_started)++;
  }

  // immediately schedule timer
  sched_timer(when, id);
  return id;
}

void Timers::stop(Timers::id_t id)
{
  auto& system = get();
  if (LIKELY(system.timers.at(id).deferred_destruct == false))
  {
    // mark as dead already
    system.timers[id].deferred_destruct = true;
    // free resources immediately
    system.timers[id].callback.reset();
    system.dead_timers++;

    if (system.timers[id].is_oneshot())
      (*system.oneshot_stopped)++;
    else
      (*system.periodic_stopped)++;
  }
}

size_t Timers::active()
{
  auto& system = get();
  return system.scheduled.size();
}

/// time functions ///

static inline std::chrono::microseconds now() noexcept
{
  return microseconds(OS::micros_since_boot());
}

/// scheduling ///

void Timers::timers_handler()
{
  auto& system = get();
  // assume the hardware timer called this function
  system.is_running = false;

  while (LIKELY(!system.scheduled.empty()))
  {
    auto it         = system.scheduled.begin();
    auto when       = it->first;
    Timers::id_t id = it->second;

    // remove dead timers
    if (system.timers[id].deferred_destruct)
    {
      system.dead_timers--;
      // remove from schedule
      system.scheduled.erase(it);
      // delete timer
      system.timers[id].reset();
      system.free_timers.push_back(id);
    }
    else
    {
      auto ts_now = now();

      if (ts_now >= when) {
        // erase immediately
        system.scheduled.erase(it);

        // call the users callback function
        system.timers[id].callback(id);
        // if the timers struct was modified in callback, eg. due to
        // creating a timer, then the timer reference below would have
        // been invalidated, hence why its BELOW, AND MUST STAY THERE
        auto& timer = system.timers[id];

        // oneshot timers are automatically freed
        if (timer.deferred_destruct || timer.is_oneshot())
        {
          timer.reset();
          if (timer.deferred_destruct) system.dead_timers--;
          system.free_timers.push_back(id);
        }
        else
        {
          // if the timer is recurring, we will simply reschedule it
          // NOTE: we are carefully using (when + period) to avoid drift
          system.scheduled.
            emplace(std::piecewise_construct,
                    std::forward_as_tuple(when + timer.period),
                    std::forward_as_tuple(id));
        }

      } else {
        // not yet time, so schedule it for later
        system.is_running = true;
        system.arch_start_func(when - ts_now);
        // exit early, because we have nothing more to do,
        // and there is a deferred handler
        return;
      }
    }
  }
  // stop hardware timer, since no timers are enabled
  system.arch_stop_func();
}
static void sched_timer(duration_t when, Timers::id_t id)
{
  assert(when != microseconds::zero());

  auto& system = get();
  system.scheduled.
    emplace(std::piecewise_construct,
            std::forward_as_tuple(now() + when),
            std::forward_as_tuple(id));

  // dont start any hardware until after calibration
  if (UNLIKELY(!signal_ready)) return;

  // if the hardware timer is not running, try starting it
  if (UNLIKELY(system.is_running == false)) {
    Timers::timers_handler();
    return;
  }
  // if the scheduled timer is the new front, restart timer
  auto it = system.scheduled.begin();
  if (it->second == id)
      Timers::timers_handler();
}
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#include "kudu/util/init.h"

#include <string>

#include "kudu/gutil/cpu.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/util/status.h"

using std::string;

namespace kudu {

Status BadCPUStatus(const base::CPU& cpu, const char* instruction_set) {
  return Status::NotSupported(strings::Substitute(
      "The CPU on this system ($0) does not support the $1 instruction "
      "set which is required for running Kudu. If you are running inside a VM, "
      "you may need to enable SSE4.2 pass-through.",
      cpu.cpu_brand(), instruction_set));
}

Status CheckCPUFlags() {
  base::CPU cpu;
  if (!cpu.has_sse42()) {
    return BadCPUStatus(cpu, "SSE4.2");
  }

  if (!cpu.has_ssse3()) {
    return BadCPUStatus(cpu, "SSSE3");
  }

  return Status::OK();
}

void InitKuduOrDie() {
  CHECK_OK(CheckCPUFlags());
  // NOTE: this function is called before flags are parsed.
  // Do not add anything in here which is flag-dependent.
}

} // namespace kudu
<commit_msg>Check sanity of standard file descriptors when starting daemons<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#include "kudu/util/init.h"

#include <fcntl.h>
#include <unistd.h>

#include <string>

#include "kudu/gutil/cpu.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/util/status.h"

using std::string;

namespace kudu {

Status BadCPUStatus(const base::CPU& cpu, const char* instruction_set) {
  return Status::NotSupported(strings::Substitute(
      "The CPU on this system ($0) does not support the $1 instruction "
      "set which is required for running Kudu. If you are running inside a VM, "
      "you may need to enable SSE4.2 pass-through.",
      cpu.cpu_brand(), instruction_set));
}

bool IsFdOpen(int fd) {
  return fcntl(fd, F_GETFL) != -1;
}

// Checks that the standard file descriptors are open when the process
// starts.
//
// If these descriptors aren't open, we can run into serious issues:
// we later might open some other files which end up reusing the same
// file descriptor numbers as stderr, and then some library like glog
// may decide to write a log message to what it thinks is stderr. That
// would then overwrite one of our important data files and cause
// corruption!
void CheckStandardFds() {
  if (!IsFdOpen(STDIN_FILENO) ||
      !IsFdOpen(STDOUT_FILENO) ||
      !IsFdOpen(STDERR_FILENO)) {
    // We can't use LOG(FATAL) here because glog isn't initialized yet, and even if it
    // were, it would try to write to stderr, which might end up writing the log message
    // into some unexpected place. This is a rare enough issue that people can deal with
    // the core dump.
    abort();
  }
}

Status CheckCPUFlags() {
  base::CPU cpu;
  if (!cpu.has_sse42()) {
    return BadCPUStatus(cpu, "SSE4.2");
  }

  if (!cpu.has_ssse3()) {
    return BadCPUStatus(cpu, "SSSE3");
  }

  return Status::OK();
}

void InitKuduOrDie() {
  CheckStandardFds();
  CHECK_OK(CheckCPUFlags());
  // NOTE: this function is called before flags are parsed.
  // Do not add anything in here which is flag-dependent.
}

} // namespace kudu
<|endoftext|>


<commit_before>/*
 *
 * Author: Jeffrey Leung
 * Last edited: 2015-11-06
 *
 * This C++ header file contains the LabyrinthMap class which creates, updates,
 * and displays a map of a given Labyrinth.
 *
 */

#include <stdexcept>

#include "../include/labyrinth_map.hpp"

// This method creates the Wall of a given Wall coordinate.
// May be used to set a Wall which has already been set.
// An exception is thrown if:
//   d is kNone (invalid_argument)
void LabyrinthMapCoordinateBorder::SetWall( Direction d )
{
  switch( d )
  {
    case Direction::kNorth:
      wall_north_ = false;
      return;
    case Direction::kEast:
      wall_east_ = false;
      return;
    case Direction::kSouth:
      wall_south_ = false;
      return;
    case Direction::kWest:
      wall_west_ = false;
      return;
    default:
      throw std::invalid_argument( "Error: SetWall() was given an invalid "\
        "direction (kNone)." );
  }
  return;
}

// This method sets the current inhabitant of the map's Room.
// May be used to set the inhabitant to the same inhabitant, or to
// no inhabitant.
void LabyrinthMapCoordinateRoom::SetInhabitant( Inhabitant inh )
{
  i_ = inh;
}

// This method places the treasure in the map's Room.
// May be used when there is already a treasure in the map's Room.
void LabyrinthMapCoordinateRoom::SetTreasure()
{
  treasure_ = true;
}

//TODO Implementation of labyrinth_map.hpp
<commit_msg>Implementing RemoveTreasure().<commit_after>/*
 *
 * Author: Jeffrey Leung
 * Last edited: 2015-12-05
 *
 * This C++ header file contains the LabyrinthMap class which creates, updates,
 * and displays a map of a given Labyrinth.
 *
 */

#include <stdexcept>

#include "../include/labyrinth_map.hpp"

// This method creates the Wall of a given Wall coordinate.
// May be used to set a Wall which has already been set.
// An exception is thrown if:
//   d is kNone (invalid_argument)
void LabyrinthMapCoordinateBorder::SetWall( Direction d )
{
  switch( d )
  {
    case Direction::kNorth:
      wall_north_ = false;
      return;
    case Direction::kEast:
      wall_east_ = false;
      return;
    case Direction::kSouth:
      wall_south_ = false;
      return;
    case Direction::kWest:
      wall_west_ = false;
      return;
    default:
      throw std::invalid_argument( "Error: SetWall() was given an invalid "\
        "direction (kNone)." );
  }
  return;
}

// This method sets the current inhabitant of the map's Room.
// May be used to set the inhabitant to the same inhabitant, or to
// no inhabitant.
void LabyrinthMapCoordinateRoom::SetInhabitant( Inhabitant inh )
{
  i_ = inh;
}

// This method places the treasure in the map's Room.
// May be used when there is already a treasure in the map's Room.
void LabyrinthMapCoordinateRoom::SetTreasure()
{
  treasure_ = true;
}

// This method removes the treasure from the Room.
// May be used when there is no treasure in the map's Room.
void LabyrinthMapCoordinateRoom::RemoveTreasure()
{
  treasure_ = false;
}

//TODO Implementation of labyrinth_map.hpp
<|endoftext|>


<commit_before>#include "latexImprover.h"

#include <iostream>

#include "stringFinder.h"

latexImprover::latexImprover(std::stringstream& file, std::stringstream& output){
    std::stringstream fileCopy;
    fileCopy << file.rdbuf();
    latexImprover::preFormater(fileCopy);

}
std::vector<latexImprover::ReplaceInstruction> latexImprover::preFormater(std::stringstream& file){
    std::vector<std::string> stringsToFind;
    stringsToFind.push_back("\\begin{align}"); //0
    stringsToFind.push_back("\\end{align}");
    stringsToFind.push_back("\\begin{align*}");
    stringsToFind.push_back("\\begin{equation}");
    stringsToFind.push_back("\\end{equation}");
    stringsToFind.push_back("\\begin{equation*}"); //5
    stringsToFind.push_back("\\left(");
    stringsToFind.push_back("\\right)");
    stringsToFind.push_back("\\left[");
    stringsToFind.push_back("\\right]");
    stringsToFind.push_back("\\label{"); //10
    stringsToFind.push_back("\\end{equation*}");
    stringsToFind.push_back("\\end{align*}");
    stringsToFind.push_back("\\usepackage{amsmath}");
    stringFinder* stringFinderObj = new stringFinder(stringsToFind);

    std::vector<latexImprover::ReplaceInstruction> outputVect;

    char prev_c = '\0';
    char c;
    int pos = 0;
    while(file.get(c)){
        if(c == '%' && prev_c != '\\'){
            //Comment line
            std::string line;
            std::getline(file, line); //get rest of comment line
            pos += line.size() + 1;
            continue; //We don't need to run anything below if comment.
        }
        int foundPos = stringFinderObj->read(c);
        if(foundPos >= 0){
            switch(foundPos){
                case 0:     latexImprover::inEnviromentAlign = true;
                            break;
                case 1:     latexImprover::inEnviromentAlign = false;
                            break;
                case 2:     latexImprover::inEnviromentAlign = true;
                            break;
                case 3:     latexImprover::inEnviromentEquation = true;
                            break;
                case 4:     latexImprover::inEnviromentEquation = false;
                            break;
                case 5:     latexImprover::inEnviromentEquation = true;
                            break;
                case 10:    latexImprover::inLabel = true;
                            break;
                case 11:    latexImprover::inEnviromentEquation = false;
                            break;
                case 12:    latexImprover::inEnviromentAlign = false;
                            break;
                case 13:    latexImprover::usePackageAmsmath = true;
                            break;
            }

        }
        if(prev_c == '\\' && (c == '(' || c == '[')){
            latexImprover::inSimpelEquation = true;
        }
        else if(prev_c == '\\' && (c == ')' || c == ']')){
            latexImprover::inSimpelEquation = false;
        }
        else if(c == '}' && latexImprover::inLabel){
            latexImprover::inLabel = false;
        }
        else if(c == '$'){
            if(latexImprover::inShortEquation){
                latexImprover::inShortEquation = false;
            }
            else{
                latexImprover::inShortEquation = true;
            }
        }

        if((latexImprover::inEnviromentAlign || latexImprover::inEnviromentEquation || latexImprover::inSimpelEquation || latexImprover::inShortEquation)
            && !latexImprover::inLabel && latexImprover::usePackageAmsmath){
            if(foundPos >= 6 && foundPos <= 9){ // foundPos in range 6 to 9
            }
            else if(prev_c != '\\'){
                if(c == '('){
                    latexImprover::ReplaceInstruction output;
                    output.pos = pos;
                    output.replacment = "\\left(";
                    outputVect.push_back(output);
                }
                else if(c == ')'){
                    latexImprover::ReplaceInstruction output;
                    output.pos = pos;
                    output.replacment = "\\right)";
                    outputVect.push_back(output);
                }
                else if(c == '['){
                    latexImprover::ReplaceInstruction output;
                    output.pos = pos;
                    output.replacment = "\\left[";
                    outputVect.push_back(output);
                }
                else if(c == ']'){
                    latexImprover::ReplaceInstruction output;
                    output.pos = pos;
                    output.replacment = "\\right]";
                    outputVect.push_back(output);
                }
            }
        }
        prev_c = c;
        pos++;
    }
    return outputVect;
}
void latexImprover::formater(std::stringstream& file, std::stringstream& output, std::vector<ReplaceInstruction> instructions){
    char c;
    int pos = 0;
    while(file.get(c)){
        if(instructions.empty()){ //No more special things we can output the rest directly
            output << file.str();
            break;
        }
        else if(instructions.front().pos == pos){

            output << instructions.front().replacment;
            pos += instructions.front().replacment.size();

            instructions.erase(instructions.begin());
        }
        else{
            output << c;
        }
        pos++;
    }
}
<commit_msg>Fixed the code.<commit_after>#include "latexImprover.h"

#include <iostream>

#include "stringFinder.h"

latexImprover::latexImprover(std::stringstream& file, std::stringstream& output){
    std::vector<latexImprover::ReplaceInstruction> inst = latexImprover::preFormater(file);
    file.clear();
    file.seekg(0,file.beg);
    latexImprover::formater(file, output, inst);
}
std::vector<latexImprover::ReplaceInstruction> latexImprover::preFormater(std::stringstream& file){
    std::vector<std::string> stringsToFind;
    stringsToFind.push_back("\\begin{align}"); //0
    stringsToFind.push_back("\\end{align}");
    stringsToFind.push_back("\\begin{align*}");
    stringsToFind.push_back("\\begin{equation}");
    stringsToFind.push_back("\\end{equation}");
    stringsToFind.push_back("\\begin{equation*}"); //5
    stringsToFind.push_back("\\left(");
    stringsToFind.push_back("\\right)");
    stringsToFind.push_back("\\left[");
    stringsToFind.push_back("\\right]");
    stringsToFind.push_back("\\label{"); //10
    stringsToFind.push_back("\\end{equation*}");
    stringsToFind.push_back("\\end{align*}");
    stringsToFind.push_back("\\usepackage{amsmath}");
    stringFinder* stringFinderObj = new stringFinder(stringsToFind);

    std::vector<latexImprover::ReplaceInstruction> outputVect;

    char prev_c = '\0';
    char c;
    int pos = 0;
    while(file.get(c)){
        if(c == '%' && prev_c != '\\'){
            //Comment line
            std::string line;
            std::getline(file, line); //get rest of comment line
            pos += line.size() + 1;
            continue; //We don't need to run anything below if comment.
        }
        int foundPos = stringFinderObj->read(c);
        if(foundPos >= 0){
            switch(foundPos){
                case 0:     latexImprover::inEnviromentAlign = true;
                            break;
                case 1:     latexImprover::inEnviromentAlign = false;
                            break;
                case 2:     latexImprover::inEnviromentAlign = true;
                            break;
                case 3:     latexImprover::inEnviromentEquation = true;
                            break;
                case 4:     latexImprover::inEnviromentEquation = false;
                            break;
                case 5:     latexImprover::inEnviromentEquation = true;
                            break;
                case 10:    latexImprover::inLabel = true;
                            break;
                case 11:    latexImprover::inEnviromentEquation = false;
                            break;
                case 12:    latexImprover::inEnviromentAlign = false;
                            break;
                case 13:    latexImprover::usePackageAmsmath = true;
                            break;
            }

        }
        if(prev_c == '\\' && (c == '(' || c == '[')){
            latexImprover::inSimpelEquation = true;
        }
        else if(prev_c == '\\' && (c == ')' || c == ']')){
            latexImprover::inSimpelEquation = false;
        }
        else if(c == '}' && latexImprover::inLabel){
            latexImprover::inLabel = false;
        }
        else if(c == '$'){
            if(latexImprover::inShortEquation){
                latexImprover::inShortEquation = false;
            }
            else{
                latexImprover::inShortEquation = true;
            }
        }

        if((latexImprover::inEnviromentAlign || latexImprover::inEnviromentEquation || latexImprover::inSimpelEquation || latexImprover::inShortEquation)
            && !latexImprover::inLabel && latexImprover::usePackageAmsmath){
            if(foundPos >= 6 && foundPos <= 9){ // foundPos in range 6 to 9
            }
            else if(prev_c != '\\'){
                if(c == '('){
                    latexImprover::ReplaceInstruction output;
                    output.pos = pos;
                    output.replacment = "\\left(";
                    outputVect.push_back(output);
                }
                else if(c == ')'){
                    latexImprover::ReplaceInstruction output;
                    output.pos = pos;
                    output.replacment = "\\right)";
                    outputVect.push_back(output);
                }
                else if(c == '['){
                    latexImprover::ReplaceInstruction output;
                    output.pos = pos;
                    output.replacment = "\\left[";
                    outputVect.push_back(output);
                }
                else if(c == ']'){
                    latexImprover::ReplaceInstruction output;
                    output.pos = pos;
                    output.replacment = "\\right]";
                    outputVect.push_back(output);
                }
            }
        }
        prev_c = c;
        pos++;
    }
    return outputVect;
}
void latexImprover::formater(std::stringstream& file, std::stringstream& output, std::vector<ReplaceInstruction> instructions){
    char c;
    int pos = 0;
    while(file.get(c)){
        if(instructions.empty()){ //No more special things we can output the rest directly
            output << file.str();
            break;
        }
        else if(instructions.front().pos == pos){

            output << instructions.front().replacment;
            pos += instructions.front().replacment.size();

            instructions.erase(instructions.begin());
        }
        else{
            output << c;
        }
        pos++;
    }
}
<|endoftext|>


<commit_before>#ifndef JARNGREIPR_FORCEFIELD_GENERATOR
#define JARNGREIPR_FORCEFIELD_GENERATOR
#include <jarngreipr/io/PDBAtom.hpp>
#include <jarngreipr/io/PDBResidue.hpp>
#include <jarngreipr/io/PDBChain.hpp>
#include <jarngreipr/model/Bead.hpp>
#include <jarngreipr/model/CGChain.hpp>
#include <jarngreipr/model/CarbonAlpha.hpp>
#include <jarngreipr/forcefield/ConnectingIndices.hpp>
#include <ostream>

namespace mjolnir
{

template<typename coordT>
class ForceFieldGenerator
{
  public:
    typedef coordT                      coordinate_type;
    typedef PDBAtom<coordinate_type>    atom_type;
    typedef PDBResidue<coordinate_type> residue_type;
    typedef PDBChain<coordinate_type>   chain_type;
    typedef Bead<coordinate_type>       bead_type;
    typedef CGChain<coordinate_type>    cg_chain_type;
    typedef std::map<std::size_t, ConnectingIndices> connection_info;

  public:
    virtual ~ForceFieldGenerator() = default;

    //!@brief generate parameter values and write out to ostream.
    //@return return connection info. for scaling or ignoring Lennard-Jones.
    virtual connection_info
    generate(std::ostream& ostrm, const cg_chain_type& chain) const = 0;

    //!@brief if chain contains invalid bead, return false.
    virtual bool
    check_bead_kind(const cg_chain_type& chain) const = 0;
};

} // mjolnir
#endif// JARNGREIPR_FORCEFIELD_GENERATOR
<commit_msg>add (Intra|Inter)ChainForceFieldGenerator<commit_after>#ifndef JARNGREIPR_FORCEFIELD_GENERATOR
#define JARNGREIPR_FORCEFIELD_GENERATOR
#include <jarngreipr/io/PDBAtom.hpp>
#include <jarngreipr/io/PDBResidue.hpp>
#include <jarngreipr/io/PDBChain.hpp>
#include <jarngreipr/model/Bead.hpp>
#include <jarngreipr/model/CGChain.hpp>
#include <jarngreipr/model/CarbonAlpha.hpp>
#include <jarngreipr/forcefield/ConnectingIndices.hpp>
#include <ostream>

namespace mjolnir
{

template<typename coordT>
class IntraChainForceFieldGenerator
{
  public:
    typedef coordT                      coordinate_type;
    typedef PDBAtom<coordinate_type>    atom_type;
    typedef PDBResidue<coordinate_type> residue_type;
    typedef PDBChain<coordinate_type>   chain_type;
    typedef Bead<coordinate_type>       bead_type;
    typedef CGChain<coordinate_type>    cg_chain_type;
    typedef std::map<std::size_t, ConnectingIndices> connection_info;

  public:
    virtual ~IntraChainForceFieldGenerator() = default;

    //!@brief generate parameter values and write out to ostream.
    //@return connection_information. for scaling or ignoring Global interaction
    virtual connection_info
    generate(std::ostream& ostrm,
             const cg_chain_type& chain, const std::size_t offset) const = 0;

    //!@brief if chain contains invalid bead, return false.
    virtual bool
    check_bead_kind(const cg_chain_type& chain) const = 0;
};

// mainly for GoContact.
template<typename coordT>
class InterChainForceFieldGenerator
{
  public:
    typedef coordT                      coordinate_type;
    typedef PDBAtom<coordinate_type>    atom_type;
    typedef PDBResidue<coordinate_type> residue_type;
    typedef PDBChain<coordinate_type>   chain_type;
    typedef Bead<coordinate_type>       bead_type;
    typedef CGChain<coordinate_type>    cg_chain_type;
    typedef std::map<std::size_t, ConnectingIndices> connection_info;

  public:
    virtual ~IntraChainForceFieldGenerator() = default;

    //!@brief generate parameter values and write out to ostream.
    //@return connection_information. for scaling or ignoring Global interaction
    virtual connection_info
    generate(std::ostream& ostrm,
        const std::vector<std::pair<cg_chain_type, std::size_t>>& chain_offset
        ) const = 0;

    //!@brief if chain contains invalid bead, return false.
    virtual bool
    check_bead_kind(const cg_chain_type& chain) const = 0;
};

} // mjolnir
#endif// JARNGREIPR_FORCEFIELD_GENERATOR
<|endoftext|>