<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xmlTableFilterPattern.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 14:10:44 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef DBA_XMLTABLEFILTERPATTERN_HXX
#include "xmlTableFilterPattern.hxx"
#endif
#ifndef DBA_XMLTABLEFILTERLIST_HXX
#include "xmlTableFilterList.hxx"
#endif

namespace dbaxml
{
    using namespace ::rtl;
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::xml::sax;

OXMLTableFilterPattern::OXMLTableFilterPattern( SvXMLImport& rImport,
                sal_uInt16 nPrfx
                ,const OUString& _sLocalName
                ,sal_Bool _bNameFilter
                ,OXMLTableFilterList& _rParent) :
    SvXMLImportContext( rImport, nPrfx, _sLocalName )
        ,m_bNameFilter(_bNameFilter)
        ,m_rParent(_rParent)
{
}
// -----------------------------------------------------------------------------

OXMLTableFilterPattern::~OXMLTableFilterPattern()
{
}
// -----------------------------------------------------------------------------
void OXMLTableFilterPattern::Characters( const ::rtl::OUString& rChars )
{
    if ( m_bNameFilter )
        m_rParent.pushTableFilterPattern(rChars);
    else
        m_rParent.pushTableTypeFilter(rChars);
}

//----------------------------------------------------------------------------
} // namespace dbaxml
// -----------------------------------------------------------------------------
<commit_msg>INTEGRATION: CWS dba201b (1.2.146); FILE MERGED 2005/09/21 07:34:36 oj 1.2.146.2: RESYNC: (1.2-1.3); FILE MERGED 2005/07/11 13:37:07 fs 1.2.146.1: merging CWS dba201 into CWS dba201b<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xmlTableFilterPattern.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2005-09-23 12:13:26 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef DBA_XMLTABLEFILTERPATTERN_HXX
#include "xmlTableFilterPattern.hxx"
#endif
#ifndef DBA_XMLTABLEFILTERLIST_HXX
#include "xmlTableFilterList.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

namespace dbaxml
{
    using namespace ::rtl;
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::xml::sax;
DBG_NAME(OXMLTableFilterPattern)

OXMLTableFilterPattern::OXMLTableFilterPattern( SvXMLImport& rImport,
                sal_uInt16 nPrfx
                ,const OUString& _sLocalName
                ,sal_Bool _bNameFilter
                ,OXMLTableFilterList& _rParent) :
    SvXMLImportContext( rImport, nPrfx, _sLocalName )
        ,m_bNameFilter(_bNameFilter)
        ,m_rParent(_rParent)
{
    DBG_CTOR(OXMLTableFilterPattern,NULL);

}
// -----------------------------------------------------------------------------

OXMLTableFilterPattern::~OXMLTableFilterPattern()
{

    DBG_DTOR(OXMLTableFilterPattern,NULL);
}
// -----------------------------------------------------------------------------
void OXMLTableFilterPattern::Characters( const ::rtl::OUString& rChars )
{
    if ( m_bNameFilter )
        m_rParent.pushTableFilterPattern(rChars);
    else
        m_rParent.pushTableTypeFilter(rChars);
}

//----------------------------------------------------------------------------
} // namespace dbaxml
// -----------------------------------------------------------------------------
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2008-2016 the MRtrix3 contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/
 *
 * MRtrix is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * For more details, see www.mrtrix.org
 *
 */

#include "command.h"
#include "progressbar.h"
#include "image.h"
#include "math/SH.h"
#include "dwi/gradient.h"
#include "dwi/shells.h"
#include "algo/threaded_loop.h"

using namespace MR;
using namespace App;

void usage ()
{
  AUTHOR = "J-Donald Tournier (jdtournier@gmail.com)";

  DESCRIPTION
  + "convert a set of amplitudes (defined along a set of corresponding directions) "
    "to their spherical harmonic representation. The spherical harmonic decomposition is "
    "calculated by least-squares linear fitting."

  + "The directions can be defined either as a DW gradient scheme (for example to compute "
    "the SH representation of the DW signal) or a set of [az el] pairs as output by the dirgen "
    "command. The DW gradient scheme or direction set can be supplied within the input "
    "image header or using the -gradient or -directions option. Note that if a direction set "
    "and DW gradient scheme can be found, the direction set will be used by default."

  + Math::SH::encoding_description;

  ARGUMENTS
  + Argument ("amp", "the input amplitude image.").type_image_in ()
  + Argument ("SH", "the output spherical harmonics coefficients image.").type_image_out ();

  OPTIONS
  + Option ("lmax",
            "set the maximum harmonic order for the output series. By default, the "
            "program will use the highest possible lmax given the number of "
            "diffusion-weighted images, up to a maximum of 8.")
  +   Argument ("order").type_integer (0, 30)

  + Option ("normalise", "normalise the DW signal to the b=0 image")

  + Option ("directions", "the directions corresponding to the input amplitude image used to sample AFD. "
                          "By default this option is not required providing the direction set is supplied "
                          "in the amplitude image. This should be supplied as a list of directions [az el], "
                          "as generated using the dirgen command")
  +   Argument ("file").type_file_in()

  + Option ("rician", "correct for Rician noise induced bias, using noise map supplied")
  +   Argument ("noise").type_image_in()

  + DWI::GradImportOptions()
  + DWI::ShellOption
  + Stride::Options;
}

#define RICIAN_POWER 2.25

typedef float value_type;

class Amp2SHCommon {
  public:
    template <class MatrixType>
      Amp2SHCommon (const MatrixType& sh2amp,
          const std::vector<size_t>& bzeros,
          const std::vector<size_t>& dwis,
          bool normalise_to_bzero) :
        sh2amp (sh2amp),
        amp2sh (Math::pinv (sh2amp)),
        bzeros (bzeros),
        dwis (dwis),
        normalise (normalise_to_bzero) { }

    Eigen::MatrixXd sh2amp, amp2sh;
    const std::vector<size_t>& bzeros;
    const std::vector<size_t>& dwis;
    bool normalise;
};

class Amp2SH {
  public:
    Amp2SH (const Amp2SHCommon& common) :
      C (common),
      a (common.amp2sh.cols()),
      s (common.amp2sh.rows()),
      c (common.amp2sh.rows()) { }

    template <class SHImageType, class AmpImageType>
      void operator() (SHImageType& SH, AmpImageType& amp)
      {
        get_amps (amp);
        c.noalias() = C.amp2sh * a;
        write_SH (SH);
      }

    // Rician-corrected version:
    template <class SHImageType, class AmpImageType, class NoiseImageType>
      void operator() (SHImageType& SH, AmpImageType& amp, const NoiseImageType& noise)
      {
        w = Eigen::VectorXd::Ones (C.sh2amp.rows());

        get_amps (amp);
        c = C.amp2sh * a;

        for (size_t iter = 0; iter < 20; ++iter) {
          sh2amp = C.sh2amp;
          if (get_rician_bias (sh2amp, noise.value()))
            break;
          for (ssize_t n = 0; n < sh2amp.rows(); ++n)
            sh2amp.row (n).array() *= w[n];

          s.noalias() = sh2amp.transpose() * ap;
          Q.triangularView<Eigen::Lower>() = sh2amp.transpose() * sh2amp;
          llt.compute (Q);
          c = llt.solve (s);
        }

        write_SH (SH);
      }

  protected:
    const Amp2SHCommon& C;
    Eigen::VectorXd a, s, c, w, ap;
    Eigen::MatrixXd Q, sh2amp;
    Eigen::LLT<Eigen::MatrixXd> llt;

    template <class AmpImageType>
      void get_amps (AmpImageType& amp) {
        double norm = 1.0;
        if (C.normalise) {
          for (size_t n = 0; n < C.bzeros.size(); n++) {
            amp.index(3) = C.bzeros[n];
            norm += amp.value ();
          }
          norm = C.bzeros.size() / norm;
        }

        for (ssize_t n = 0; n < a.size(); n++) {
          amp.index(3) = C.dwis.size() ? C.dwis[n] : n;
          a[n] = amp.value() * norm;
        }
      }

    template <class SHImageType>
      void write_SH (SHImageType& SH) {
        for (auto l = Loop(3) (SH); l; ++l)
          SH.value() = c[SH.index(3)];
      }

    bool get_rician_bias (const Eigen::MatrixXd& sh2amp, default_type noise) {
      ap = sh2amp * c;
      default_type norm_diff = 0.0;
      default_type norm_amp = 0.0;
      for (ssize_t n = 0; n < ap.size() ; ++n) {
        ap[n] = std::max (ap[n], default_type(0.0));
        default_type t = std::pow (ap[n]/noise, default_type(RICIAN_POWER));
        w[n] = Math::pow2 ((t + 1.7)/(t + 1.12));
        default_type diff = a[n] - noise * std::pow (t + 1.65, 1.0/RICIAN_POWER);
        norm_diff += Math::pow2 (diff);
        norm_amp += Math::pow2 (a[n]);
        ap[n] += diff;
      }
      return norm_diff/norm_amp < 1.0e-8;
    }
};

void run ()
{
  auto amp = Image<value_type>::open (argument[0]).with_direct_io (3);
  Header header (amp);

  std::vector<size_t> bzeros, dwis;
  Eigen::MatrixXd dirs;
  auto opt = get_options ("directions");
  if (opt.size()) {
    dirs = load_matrix (opt[0][0]);
  }
  else {
    auto hit = header.keyval().find ("directions");
    if (hit != header.keyval().end()) {
      std::vector<default_type> dir_vector;
      for (auto line : split_lines (hit->second)) {
        auto v = parse_floats (line);
        dir_vector.insert (dir_vector.end(), v.begin(), v.end());
      }
      dirs.resize(dir_vector.size() / 2, 2);
      for (size_t i = 0; i < dir_vector.size(); i += 2) {
        dirs(i/2, 0) = dir_vector[i];
        dirs(i/2, 1) = dir_vector[i+1];
      }
      header.keyval()["basis_directions"] = hit->second;
      header.keyval().erase (hit);
    }
    else {
      auto grad = DWI::get_valid_DW_scheme (amp);
      DWI::Shells shells (grad);
      shells.select_shells (true, true);
      if (shells.smallest().is_bzero())
        bzeros = shells.smallest().get_volumes();
      dwis = shells.largest().get_volumes();
      dirs = DWI::gen_direction_matrix (grad, dwis);
      DWI::stash_DW_scheme (header, grad);
    }
  }

  auto sh2amp = DWI::compute_SH2amp_mapping (dirs, true, 8);

  bool normalise = get_options ("normalise").size();
  if (normalise && !bzeros.size())
    throw Exception ("the normalise option is only available if the input data contains b=0 images.");

  header.size (3) = sh2amp.cols();
  Stride::set_from_command_line (header);
  auto SH = Image<value_type>::create (argument[1], header);

  Amp2SHCommon common (sh2amp, bzeros, dwis, normalise);

  opt = get_options ("rician");
  if (opt.size()) {
    auto noise = Image<value_type>::open (opt[0][0]).with_direct_io();
    ThreadedLoop ("mapping amplitudes to SH coefficients", amp, 0, 3)
      .run (Amp2SH (common), SH, amp, noise);
  }
  else {
    ThreadedLoop ("mapping amplitudes to SH coefficients", amp, 0, 3)
      .run (Amp2SH (common), SH, amp);
  }
}
<commit_msg>single-shell selection in amp2sh<commit_after>/*
 * Copyright (c) 2008-2016 the MRtrix3 contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/
 *
 * MRtrix is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * For more details, see www.mrtrix.org
 *
 */

#include "command.h"
#include "progressbar.h"
#include "image.h"
#include "math/SH.h"
#include "dwi/gradient.h"
#include "dwi/shells.h"
#include "algo/threaded_loop.h"

using namespace MR;
using namespace App;

void usage ()
{
  AUTHOR = "J-Donald Tournier (jdtournier@gmail.com)";

  DESCRIPTION
  + "convert a set of amplitudes (defined along a set of corresponding directions) "
    "to their spherical harmonic representation. The spherical harmonic decomposition is "
    "calculated by least-squares linear fitting."

  + "The directions can be defined either as a DW gradient scheme (for example to compute "
    "the SH representation of the DW signal) or a set of [az el] pairs as output by the dirgen "
    "command. The DW gradient scheme or direction set can be supplied within the input "
    "image header or using the -gradient or -directions option. Note that if a direction set "
    "and DW gradient scheme can be found, the direction set will be used by default."

  + Math::SH::encoding_description;

  ARGUMENTS
  + Argument ("amp", "the input amplitude image.").type_image_in ()
  + Argument ("SH", "the output spherical harmonics coefficients image.").type_image_out ();

  OPTIONS
  + Option ("lmax",
            "set the maximum harmonic order for the output series. By default, the "
            "program will use the highest possible lmax given the number of "
            "diffusion-weighted images, up to a maximum of 8.")
  +   Argument ("order").type_integer (0, 30)

  + Option ("normalise", "normalise the DW signal to the b=0 image")

  + Option ("directions", "the directions corresponding to the input amplitude image used to sample AFD. "
                          "By default this option is not required providing the direction set is supplied "
                          "in the amplitude image. This should be supplied as a list of directions [az el], "
                          "as generated using the dirgen command")
  +   Argument ("file").type_file_in()

  + Option ("rician", "correct for Rician noise induced bias, using noise map supplied")
  +   Argument ("noise").type_image_in()

  + DWI::GradImportOptions()
  + DWI::ShellOption
  + Stride::Options;
}

#define RICIAN_POWER 2.25

typedef float value_type;

class Amp2SHCommon {
  public:
    template <class MatrixType>
      Amp2SHCommon (const MatrixType& sh2amp,
          const std::vector<size_t>& bzeros,
          const std::vector<size_t>& dwis,
          bool normalise_to_bzero) :
        sh2amp (sh2amp),
        amp2sh (Math::pinv (sh2amp)),
        bzeros (bzeros),
        dwis (dwis),
        normalise (normalise_to_bzero) { }

    Eigen::MatrixXd sh2amp, amp2sh;
    const std::vector<size_t>& bzeros;
    const std::vector<size_t>& dwis;
    bool normalise;
};

class Amp2SH {
  public:
    Amp2SH (const Amp2SHCommon& common) :
      C (common),
      a (common.amp2sh.cols()),
      s (common.amp2sh.rows()),
      c (common.amp2sh.rows()) { }

    template <class SHImageType, class AmpImageType>
      void operator() (SHImageType& SH, AmpImageType& amp)
      {
        get_amps (amp);
        c.noalias() = C.amp2sh * a;
        write_SH (SH);
      }

    // Rician-corrected version:
    template <class SHImageType, class AmpImageType, class NoiseImageType>
      void operator() (SHImageType& SH, AmpImageType& amp, const NoiseImageType& noise)
      {
        w = Eigen::VectorXd::Ones (C.sh2amp.rows());

        get_amps (amp);
        c = C.amp2sh * a;

        for (size_t iter = 0; iter < 20; ++iter) {
          sh2amp = C.sh2amp;
          if (get_rician_bias (sh2amp, noise.value()))
            break;
          for (ssize_t n = 0; n < sh2amp.rows(); ++n)
            sh2amp.row (n).array() *= w[n];

          s.noalias() = sh2amp.transpose() * ap;
          Q.triangularView<Eigen::Lower>() = sh2amp.transpose() * sh2amp;
          llt.compute (Q);
          c = llt.solve (s);
        }

        write_SH (SH);
      }

  protected:
    const Amp2SHCommon& C;
    Eigen::VectorXd a, s, c, w, ap;
    Eigen::MatrixXd Q, sh2amp;
    Eigen::LLT<Eigen::MatrixXd> llt;

    template <class AmpImageType>
      void get_amps (AmpImageType& amp) {
        double norm = 1.0;
        if (C.normalise) {
          for (size_t n = 0; n < C.bzeros.size(); n++) {
            amp.index(3) = C.bzeros[n];
            norm += amp.value ();
          }
          norm = C.bzeros.size() / norm;
        }

        for (ssize_t n = 0; n < a.size(); n++) {
          amp.index(3) = C.dwis.size() ? C.dwis[n] : n;
          a[n] = amp.value() * norm;
        }
      }

    template <class SHImageType>
      void write_SH (SHImageType& SH) {
        for (auto l = Loop(3) (SH); l; ++l)
          SH.value() = c[SH.index(3)];
      }

    bool get_rician_bias (const Eigen::MatrixXd& sh2amp, default_type noise) {
      ap = sh2amp * c;
      default_type norm_diff = 0.0;
      default_type norm_amp = 0.0;
      for (ssize_t n = 0; n < ap.size() ; ++n) {
        ap[n] = std::max (ap[n], default_type(0.0));
        default_type t = std::pow (ap[n]/noise, default_type(RICIAN_POWER));
        w[n] = Math::pow2 ((t + 1.7)/(t + 1.12));
        default_type diff = a[n] - noise * std::pow (t + 1.65, 1.0/RICIAN_POWER);
        norm_diff += Math::pow2 (diff);
        norm_amp += Math::pow2 (a[n]);
        ap[n] += diff;
      }
      return norm_diff/norm_amp < 1.0e-8;
    }
};

void run ()
{
  auto amp = Image<value_type>::open (argument[0]).with_direct_io (3);
  Header header (amp);

  std::vector<size_t> bzeros, dwis;
  Eigen::MatrixXd dirs;
  auto opt = get_options ("directions");
  if (opt.size()) {
    dirs = load_matrix (opt[0][0]);
  }
  else {
    auto hit = header.keyval().find ("directions");
    if (hit != header.keyval().end()) {
      std::vector<default_type> dir_vector;
      for (auto line : split_lines (hit->second)) {
        auto v = parse_floats (line);
        dir_vector.insert (dir_vector.end(), v.begin(), v.end());
      }
      dirs.resize(dir_vector.size() / 2, 2);
      for (size_t i = 0; i < dir_vector.size(); i += 2) {
        dirs(i/2, 0) = dir_vector[i];
        dirs(i/2, 1) = dir_vector[i+1];
      }
      header.keyval()["basis_directions"] = hit->second;
      header.keyval().erase (hit);
    }
    else {
      auto grad = DWI::get_valid_DW_scheme (amp);
      DWI::Shells shells (grad);
      shells.select_shells (true, false, false);
      if (shells.smallest().is_bzero())
        bzeros = shells.smallest().get_volumes();
      dwis = shells.largest().get_volumes();
      dirs = DWI::gen_direction_matrix (grad, dwis);
      DWI::stash_DW_scheme (header, grad);
    }
  }

  auto sh2amp = DWI::compute_SH2amp_mapping (dirs, true, 8);

  bool normalise = get_options ("normalise").size();
  if (normalise && !bzeros.size())
    throw Exception ("the normalise option is only available if the input data contains b=0 images.");

  header.size (3) = sh2amp.cols();
  Stride::set_from_command_line (header);
  auto SH = Image<value_type>::create (argument[1], header);

  Amp2SHCommon common (sh2amp, bzeros, dwis, normalise);

  opt = get_options ("rician");
  if (opt.size()) {
    auto noise = Image<value_type>::open (opt[0][0]).with_direct_io();
    ThreadedLoop ("mapping amplitudes to SH coefficients", amp, 0, 3)
      .run (Amp2SH (common), SH, amp, noise);
  }
  else {
    ThreadedLoop ("mapping amplitudes to SH coefficients", amp, 0, 3)
      .run (Amp2SH (common), SH, amp);
  }
}
<|endoftext|>


<commit_before>#include <datatable.h>
#include <datasample.h>
#include <serialize.h>
#include <iostream>

using namespace MultivariateSplines;

int main() {
    DataTable t;
    t.addSample(2.0, 1.0);

    std::cout << get_size(t) << std::endl;

    auto sample = *t.getSamples().begin();

    std::cout << get_size(sample) << std::endl;

    StreamType stream;
    serialize(t, stream);

    auto it = stream.cbegin();

    DataTable deserialized = deserialize<DataTable>(it, stream.cend());

    t.printSamples(std::cout);
    deserialized.printSamples(std::cout);

    return 0;
}
<commit_msg>Added initial test for the new load and save functionality<commit_after>#include <datatable.h>
#include <datasample.h>
#include <serialize.h>
#include <iostream>

using namespace MultivariateSplines;

// Checks if a is within margin of b
bool equalsWithinRange(double a, double b, double margin = 0.0)
{
    return b - margin <= a && a <= b + margin;
}

bool is_identical(DataTable &a, DataTable &b)
{
    if (a.getNumVariables() != b.getNumVariables())
        return false;

    auto ait = a.cbegin(), bit = b.cbegin();
    for (; ait != a.cend() && bit != b.cend(); ait++, bit++)
    {
        for (unsigned int i = 0; i < a.getNumVariables(); i++)
        {
//            std::cout << std::setprecision(SAVE_DOUBLE_PRECISION) << ait->getX().at(i) << " == " << std::setprecision(SAVE_DOUBLE_PRECISION) << bit->getX().at(i) << " ";
            if (!equalsWithinRange(ait->getX().at(i), bit->getX().at(i)))
                return false;
        }

//            std::cout << std::setprecision(SAVE_DOUBLE_PRECISION) << ait->getY().at(j) << " == " << std::setprecision(SAVE_DOUBLE_PRECISION) << bit->getY().at(j) << " ";
        if (!equalsWithinRange(ait->getY(), bit->getY()))
            return false;
//        std::cout << std::endl;
    }

//    std::cout << "Finished comparing samples..." << std::endl;

    return ait == a.cend() && bit == b.cend();
}

bool test()
{
    DataTable table;

    auto x = std::vector<double>(4);
    double y;
    for (double i = -0.0001; i <= 0.0001; i += 0.000001)
    {
        for (double j = -0.01; j <= 0.01; j += 0.001)
        {
            for (double k = -0.01; k <= 0.01; k += 0.001)
            {
                for (double l = -100000.0; l < 0.0; l += 13720.0)
                {
                    x.at(0) = i;
                    x.at(1) = j;
                    x.at(2) = k;
                    x.at(3) = l;
                    y = i * j;
                    table.addSample(x, y);
                }
            }
        }
    }

    std::cout << "Size of serialized table: " << get_size(table) << std::endl;
    exit(1);

    StreamType stream;
    serialize(table, stream);
    save_to_file("test.datatable", stream);

    DataTable deserializedTable = deserialize<DataTable>(load_from_file("test.datatable"));

    return is_identical(table, deserializedTable);
}

int main() {
    if(test()) {
        std::cout << "Equal!" << std::endl;
    }

    return 0;
}
<|endoftext|>


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

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html 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 notices for more information.

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

#include "mitkStepper.h"

mitk::Stepper::Stepper() : m_Pos(0), m_Steps(0), m_StepSize(1), m_PosToUnitFactor(1), m_ZeroLine(0)
{

}

mitk::Stepper::~Stepper()
{

}

//##ModelId=3DF8B9410142
void mitk::Stepper::Previous()
{
	if(m_Pos>0)
  {
		--m_Pos;
    Modified();
  }
}

//##ModelId=3DF8B92F01DF
void mitk::Stepper::Last()
{
  if(m_Pos != m_Steps-1)
  {
	  m_Pos = m_Steps-1;
    Modified();
  }
}

//##ModelId=3DF8B91502F8
void mitk::Stepper::First()
{
  if(m_Pos != 0)
  {
  	m_Pos = 0;
    Modified();
  }
}

//##ModelId=3DF8B92703A4
void mitk::Stepper::Next()
{
	if(m_Pos<m_Steps)
  {
		++m_Pos;
    Modified();
  }
}

float mitk::Stepper::ConvertPosToUnit(unsigned int posValue)
{
  if(posValue >= m_Steps)
  {
    if(m_Steps==0)
      posValue = 0;
    else
      posValue = m_Steps-1;
  }
  return posValue*m_PosToUnitFactor-m_ZeroLine;
}

unsigned int mitk::Stepper::ConvertUnitToPos(float unitValue)
{
  unsigned int posValue = (unsigned int)(unitValue/m_PosToUnitFactor+m_ZeroLine+0.5);
  if(posValue >= m_Steps)
  {
    if(m_Steps==0)
      posValue = 0;
    else
      posValue = m_Steps-1;
  }
  return posValue;
}

<commit_msg>FIX: Next(): last is m_Steps-1 ENH: reformatted<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html 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 notices for more information.

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

#include "mitkStepper.h"

mitk::Stepper::Stepper() : m_Pos(0), m_Steps(0), m_StepSize(1), m_PosToUnitFactor(1), m_ZeroLine(0)
{

}

mitk::Stepper::~Stepper()
{

}

//##ModelId=3DF8B9410142
void mitk::Stepper::Previous()
{
  if(m_Pos>0)
  {
    --m_Pos;
    Modified();
  }
}

//##ModelId=3DF8B92F01DF
void mitk::Stepper::Last()
{
  if(m_Pos != m_Steps-1)
  {
    m_Pos = m_Steps-1;
    Modified();
  }
}

//##ModelId=3DF8B91502F8
void mitk::Stepper::First()
{
  if(m_Pos != 0)
  {
    m_Pos = 0;
    Modified();
  }
}

//##ModelId=3DF8B92703A4
void mitk::Stepper::Next()
{
  if(m_Pos<m_Steps-1)
  {
    ++m_Pos;
    Modified();
  }
}

float mitk::Stepper::ConvertPosToUnit(unsigned int posValue)
{
  if(posValue >= m_Steps)
  {
    if(m_Steps==0)
      posValue = 0;
    else
      posValue = m_Steps-1;
  }
  return posValue*m_PosToUnitFactor-m_ZeroLine;
}

unsigned int mitk::Stepper::ConvertUnitToPos(float unitValue)
{
  unsigned int posValue = (unsigned int)(unitValue/m_PosToUnitFactor+m_ZeroLine+0.5);
  if(posValue >= m_Steps)
  {
    if(m_Steps==0)
      posValue = 0;
    else
      posValue = m_Steps-1;
  }
  return posValue;
}
<|endoftext|>


<commit_before>#include "nico-live.hpp"
#include <QtCore>
#include "nico-live-watcher.hpp"
#include "nicolive-log.h"
#include "nicolive-operation.h"
#include "nicolive.h"

NicoLiveWatcher::NicoLiveWatcher(NicoLive *nicolive, int margin_sec)
    : QObject(nicolive), nicolive(nicolive), marginTime(margin_sec * 1000)
{
	this->timer = new QTimer(this);
	this->timer->setSingleShot(true);
	connect(timer, SIGNAL(timeout()), this, SLOT(watch()));
}

NicoLiveWatcher::~NicoLiveWatcher()
{
	if (isActive()) stop();
}

void NicoLiveWatcher::start(long long sec)
{
	if (sec < NicoLiveWatcher::MIN_INTERVAL_SEC)
		sec = NicoLiveWatcher::MIN_INTERVAL_SEC;
	else if (sec > NicoLiveWatcher::MAX_INTERVAL_SEC)
		sec = NicoLiveWatcher::MAX_INTERVAL_SEC;
	this->interval = static_cast<int>(sec * 1000);

	if (!this->timer->isActive()) {
		nicolive_log_debug("check session before timer start");
		nicolive->checkSession();
		nicolive_log_debug("start watch, interval: %d", this->interval);
		// this->timer->start(this->interval);
		this->timer->start(this->marginTime);
	}
	this->active = true;
}

void NicoLiveWatcher::stop()
{
	if (this->timer->isActive()) {
		nicolive_log_debug("stop watch ");
		this->timer->stop();
	}
	this->active = false;
}

bool NicoLiveWatcher::isActive() { return this->active; }

int NicoLiveWatcher::remainingTime()
{
	return this->timer->remainingTime() / 1000;
}

void NicoLiveWatcher::watch()
{
	nicolive_log_debug("watching!");

	int next_interval = this->interval;
	int remaining_msec;

	nicolive->sitePubStat();
	remaining_msec = nicolive->getRemainingLive() * 1000;
	if (remaining_msec < 0) remaining_msec = 0;

	if (nicolive->getLiveId().isEmpty() || !nicolive->enabledLive()) {
		if (nicolive->isOnair()) {
			nicolive_log_debug("stop streaming because live end");
			nicolive_streaming_stop();
			next_interval = this->marginTime;
		}
	} else {
		if (nicolive->getLiveId() != nicolive->getOnairLiveId()) {
			if (nicolive->isOnair()) {
				nicolive_log_debug(
						"stop streaming for restart");
				nicolive_streaming_stop();
				QThread::sleep(1); // sleep 1 sec
			}
			nicolive_log_debug("start streaming for next live");
			nicolive_streaming_start();
		} else if (remaining_msec + this->marginTime < next_interval) {
			next_interval = remaining_msec + this->marginTime;
		}
	}
	this->timer->start(next_interval);
}
<commit_msg>60秒間(1秒間x60)は止まるのを待つようにする。<commit_after>#include "nico-live.hpp"
#include <QtCore>
#include "nico-live-watcher.hpp"
#include "nicolive-log.h"
#include "nicolive-operation.h"
#include "nicolive.h"

NicoLiveWatcher::NicoLiveWatcher(NicoLive *nicolive, int margin_sec)
    : QObject(nicolive), nicolive(nicolive), marginTime(margin_sec * 1000)
{
	this->timer = new QTimer(this);
	this->timer->setSingleShot(true);
	connect(timer, SIGNAL(timeout()), this, SLOT(watch()));
}

NicoLiveWatcher::~NicoLiveWatcher()
{
	if (isActive()) stop();
}

void NicoLiveWatcher::start(long long sec)
{
	if (sec < NicoLiveWatcher::MIN_INTERVAL_SEC)
		sec = NicoLiveWatcher::MIN_INTERVAL_SEC;
	else if (sec > NicoLiveWatcher::MAX_INTERVAL_SEC)
		sec = NicoLiveWatcher::MAX_INTERVAL_SEC;
	this->interval = static_cast<int>(sec * 1000);

	if (!this->timer->isActive()) {
		nicolive_log_debug("check session before timer start");
		nicolive->checkSession();
		nicolive_log_debug("start watch, interval: %d", this->interval);
		// this->timer->start(this->interval);
		this->timer->start(this->marginTime);
	}
	this->active = true;
}

void NicoLiveWatcher::stop()
{
	if (this->timer->isActive()) {
		nicolive_log_debug("stop watch ");
		this->timer->stop();
	}
	this->active = false;
}

bool NicoLiveWatcher::isActive() { return this->active; }

int NicoLiveWatcher::remainingTime()
{
	return this->timer->remainingTime() / 1000;
}

void NicoLiveWatcher::watch()
{
	nicolive_log_debug("watching!");

	int next_interval = this->interval;
	int remaining_msec;

	nicolive->sitePubStat();
	remaining_msec = nicolive->getRemainingLive() * 1000;
	if (remaining_msec < 0) remaining_msec = 0;

	if (nicolive->getLiveId().isEmpty() || !nicolive->enabledLive()) {
		if (nicolive->isOnair()) {
			nicolive_log_debug("stop streaming because live end");
			nicolive_streaming_stop();
			next_interval = this->marginTime;
		}
	} else {
		if (nicolive->getLiveId() != nicolive->getOnairLiveId()) {
			if (nicolive->isOnair()) {
				nicolive_log_debug(
						"stop streaming for restart");
				nicolive_streaming_stop();
				// wait stoping 60 secs
				for (int i = 0; i < 60; ++i) {
					QThread::sleep(1); // sleep 1 sec
					if (!nicolive->isOnair()) {
						break;
					}
					nicolive_log_debug(
							"wait stopping... %d",
							i);
				}
			}
			nicolive_log_debug("start streaming for next live");
			nicolive_streaming_start();
		} else if (remaining_msec + this->marginTime < next_interval) {
			next_interval = remaining_msec + this->marginTime;
		}
	}
	this->timer->start(next_interval);
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of mcompositor.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/
/*!
  \class MCompositeWindowGroup
  \brief MCompositeWindowGroup allows a collection of windows to be rendered
  as a single texture.

  This class is useful for rendering a list of windows that needs to
  be treated as one item with transformations applied only to a single texture.
  Unlike QGraphicsItemGroup where each item is rendered separately for each
  frame, MCompositeWindowGroup can pre-render all items to an off-screen buffer
  before a frame starts and can render the resulting texture afterwards as a
  single quad which reduces GPU load and helps performance especially in panning
  and scaling transformations.

  Use this class to render a main window with its transient windows. Another
  use case is for a window that needs to have similar transformations to a
  main window. The addChildWindow() function adds windows that need to
  animate synchronously  with the main window. The removeChildWindow() function
  removes a window from the group.

  Implementation is hw-dependent. It relies on framebuffer objects on GLES2
  and the GL_EXT_framebuffer_object extension on the desktop.
*/

#include <QtOpenGL>
#include <QList>
#include <mcompositewindowgroup.h>

#include <mtexturepixmapitem.h>
#include <mcompositemanager.h>
#include <mcompositemanager_p.h>

#ifdef GLES2_VERSION
#define FORMAT GL_RGBA
#define DEPTH GL_DEPTH_COMPONENT16
#else
#define FORMAT GL_RGBA8
#define DEPTH GL_DEPTH_COMPONENT
#endif

class MCompositeWindowGroupPrivate
{
public:
    MCompositeWindowGroupPrivate(MTexturePixmapItem* mainWindow)
        :main_window(mainWindow),
         texture(0),
         fbo(0),
         depth_buffer(0),
         valid(false),
         renderer(new MTexturePixmapPrivate(0, mainWindow))
    {
    }
    MTexturePixmapItem* main_window;
    GLuint texture;
    GLuint fbo;
    GLuint depth_buffer;

    bool valid;
    QList<MTexturePixmapItem*> item_list;
    MTexturePixmapPrivate* renderer;
};

/*!
  Creates a window group object. Specify the main window
  with \a mainWindow
 */
MCompositeWindowGroup::MCompositeWindowGroup(MTexturePixmapItem* mainWindow)
    :MCompositeWindow(0, MWindowDummyPropertyCache::get()),
     d_ptr(new MCompositeWindowGroupPrivate(mainWindow))
{
    MCompositeManager *p = (MCompositeManager *) qApp;
    p->scene()->addItem(this);

    mainWindow->d->current_window_group = this;
    connect(mainWindow, SIGNAL(destroyed()), SLOT(deleteLater()));
    init();
    updateWindowPixmap();
    setZValue(mainWindow->zValue());
    stackBefore(mainWindow);
}

/*!
  Destroys this window group and frees resources. All windows that are within
  this group revert back to directly rendering its own texture.
 */
MCompositeWindowGroup::~MCompositeWindowGroup()
{
    Q_D(MCompositeWindowGroup);

    if (!QGLContext::currentContext()) {
        qWarning("MCompositeWindowGroup::%s(): no current GL context",
                 __func__);
        return;
    }

    GLuint texture = d->texture;
    glDeleteTextures(1, &texture);
    GLuint depth_buffer = d->depth_buffer;
    glDeleteRenderbuffers(1, &depth_buffer);
    GLuint fbo = d->fbo;
    glDeleteFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    // if stacking is dirty, stack windows now, otherwise we paint the scene
    // according to the old stacking
    MCompositeManager *p = (MCompositeManager*)qApp;
    if (p->d->stacking_timer.isActive())
        p->d->stackingTimeout();
}

void MCompositeWindowGroup::init()
{
    Q_D(MCompositeWindowGroup);

    if (!QGLContext::currentContext()) {
        qWarning("MCompositeWindowGroup::%s(): no current GL context",
                 __func__);
        d->valid = false;
        return;
    }
    d->renderer->current_window_group = this;

    glGenFramebuffers(1, &d->fbo);
    glGenRenderbuffers(1, &d->depth_buffer);
    glBindFramebuffer(GL_RENDERBUFFER, d->fbo);

    glGenTextures(1, &d->texture);
    glBindTexture(GL_TEXTURE_2D, d->texture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glBindRenderbuffer(GL_RENDERBUFFER, d->depth_buffer);
    glRenderbufferStorage(GL_RENDERBUFFER, DEPTH,
                          d->main_window->boundingRect().width(),
                          d->main_window->boundingRect().height());

    glBindFramebuffer(GL_FRAMEBUFFER, d->fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                           GL_TEXTURE_2D, d->texture, 0);

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                              GL_RENDERBUFFER, d->depth_buffer);

    glBindTexture(GL_TEXTURE_2D, d->texture);
    glTexImage2D(GL_TEXTURE_2D, 0, FORMAT,
                 d->main_window->boundingRect().width(),
                 d->main_window->boundingRect().height(), 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    GLenum ret = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (ret == GL_FRAMEBUFFER_COMPLETE)
        d->valid = true;
    else
        qWarning("MCompositeWindowGroup::%s(): incomplete FBO attachment 0x%x",
                 __func__, ret);

    glBindTexture(GL_TEXTURE_2D, 0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

static bool behindCompare(MTexturePixmapItem* a, MTexturePixmapItem* b)
{
    return a->indexInStack() < b->indexInStack();
}

/*!
  Adds the given \a window to this group except if it's already in the group.
  The window's transformations will remain unmodified.  Returns whether the
  \a window has been added.
 */
bool MCompositeWindowGroup::addChildWindow(MTexturePixmapItem* window)
{
    Q_D(MCompositeWindowGroup);
    if (d->item_list.contains(window))
        return false;
    window->d->current_window_group = this;
    connect(window, SIGNAL(destroyed()), SLOT(q_removeWindow()));
    d->item_list.append(window);

    // ensure group windows are already stacked in proper order in advance
    // for back to front rendering. Could use depth buffer attachment at some
    // point so this might be unecessary
    qSort(d->item_list.begin(), d->item_list.end(), behindCompare);
    updateWindowPixmap(); // FIXME: don't do this for each added child
    return true;
}

/*!
  Removes the given \a window to from group.
 */
void MCompositeWindowGroup::removeChildWindow(MTexturePixmapItem* window)
{
    Q_D(MCompositeWindowGroup);
    window->d->current_window_group = 0;
    d->item_list.removeAll(window);
}

void MCompositeWindowGroup::q_removeWindow()
{
    Q_D(MCompositeWindowGroup);
    MTexturePixmapItem* w = qobject_cast<MTexturePixmapItem*>(sender());
    if (w)
        d->item_list.removeAll(w);
}

void MCompositeWindowGroup::saveBackingStore() {}

void MCompositeWindowGroup::resize(int , int) {}

void MCompositeWindowGroup::clearTexture() {}

bool MCompositeWindowGroup::isDirectRendered() const { return false; }

QRectF MCompositeWindowGroup::boundingRect() const
{
    Q_D(const MCompositeWindowGroup);
    return d->main_window->boundingRect();
}

void MCompositeWindowGroup::paint(QPainter* painter,
                                  const QStyleOptionGraphicsItem* options,
                                  QWidget* widget)
{
    Q_D(MCompositeWindowGroup);
    Q_UNUSED(options)
    Q_UNUSED(widget)

#if QT_VERSION < 0x040600
    if (painter->paintEngine()->type() != QPaintEngine::OpenGL)
        return;
#else
    if (painter->paintEngine()->type() != QPaintEngine::OpenGL2) {
        return;
    }
#endif

    glBindTexture(GL_TEXTURE_2D, d->texture);
    if (d->main_window->propertyCache()->hasAlpha() ||
        (opacity() < 1.0f && !dimmedEffect()) ) {
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    }
    d->renderer->drawTexture(painter->combinedTransform(), boundingRect(),
                             opacity());
    glBlendFunc(GL_ONE, GL_ZERO);
    glDisable(GL_BLEND);
}

void MCompositeWindowGroup::windowRaised()
{
}

void MCompositeWindowGroup::updateWindowPixmap(XRectangle *rects, int num,
                                               Time t)
{
    Q_UNUSED(rects)
    Q_UNUSED(num)
    Q_UNUSED(t)
    Q_D(MCompositeWindowGroup);

    if (d->main_window->isWindowTransitioning()) {
        // updates during transitioning cause issues when texcoords_from_rect
        // is used in MTexturePixmapItemPrivate and is heavy, too
        return;
    }
    if (!d->valid) {
        qDebug() << "invalid fbo";
        return;
    }

    glBindFramebuffer(GL_FRAMEBUFFER, d->fbo);
    GLenum ret = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (ret == GL_FRAMEBUFFER_COMPLETE)
        d->valid = true;
    else {
        qWarning("MCompositeWindowGroup::%s(): incomplete FBO attachment 0x%x",
                 __func__, ret);
        d->valid = false;
    }
    bool orig_value = d->main_window->d->inverted_texture;
    d->main_window->d->inverted_texture = false;
    d->main_window->renderTexture(d->main_window->sceneTransform());
    d->main_window->d->inverted_texture = orig_value;
    for (int i = 0; i < d->item_list.size(); ++i) {
        MTexturePixmapItem* item = d->item_list[i];
        orig_value = item->d->inverted_texture;
        item->d->inverted_texture = false;
        item->renderTexture(item->sceneTransform());
        item->d->inverted_texture = orig_value;
    }
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

// internal re-implementation from MCompositeWindow
MTexturePixmapPrivate* MCompositeWindowGroup::renderer() const
{
    Q_D(const MCompositeWindowGroup);
    return d->renderer;
}

/*!
  \return Returns the texture used by the off-screen buffer
*/
GLuint MCompositeWindowGroup::texture()
{
    Q_D(MCompositeWindowGroup);
    return d->texture;
}

<commit_msg>make MCompositeWindowGroup::updateWindowPixmap() explicit<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of mcompositor.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/
/*!
  \class MCompositeWindowGroup
  \brief MCompositeWindowGroup allows a collection of windows to be rendered
  as a single texture.

  This class is useful for rendering a list of windows that needs to
  be treated as one item with transformations applied only to a single texture.
  Unlike QGraphicsItemGroup where each item is rendered separately for each
  frame, MCompositeWindowGroup can pre-render all items to an off-screen buffer
  before a frame starts and can render the resulting texture afterwards as a
  single quad which reduces GPU load and helps performance especially in panning
  and scaling transformations.

  Use this class to render a main window with its transient windows. Another
  use case is for a window that needs to have similar transformations to a
  main window. The addChildWindow() function adds windows that need to
  animate synchronously  with the main window. The removeChildWindow() function
  removes a window from the group.

  Implementation is hw-dependent. It relies on framebuffer objects on GLES2
  and the GL_EXT_framebuffer_object extension on the desktop.
*/

#include <QtOpenGL>
#include <QList>
#include <mcompositewindowgroup.h>

#include <mtexturepixmapitem.h>
#include <mcompositemanager.h>
#include <mcompositemanager_p.h>

#ifdef GLES2_VERSION
#define FORMAT GL_RGBA
#define DEPTH GL_DEPTH_COMPONENT16
#else
#define FORMAT GL_RGBA8
#define DEPTH GL_DEPTH_COMPONENT
#endif

class MCompositeWindowGroupPrivate
{
public:
    MCompositeWindowGroupPrivate(MTexturePixmapItem* mainWindow)
        :main_window(mainWindow),
         texture(0),
         fbo(0),
         depth_buffer(0),
         valid(false),
         renderer(new MTexturePixmapPrivate(0, mainWindow))
    {
    }
    MTexturePixmapItem* main_window;
    GLuint texture;
    GLuint fbo;
    GLuint depth_buffer;

    bool valid;
    QList<MTexturePixmapItem*> item_list;
    MTexturePixmapPrivate* renderer;
};

/*!
  Creates a window group object. Specify the main window
  with \a mainWindow
 */
MCompositeWindowGroup::MCompositeWindowGroup(MTexturePixmapItem* mainWindow)
    :MCompositeWindow(0, MWindowDummyPropertyCache::get()),
     d_ptr(new MCompositeWindowGroupPrivate(mainWindow))
{
    MCompositeManager *p = (MCompositeManager *) qApp;
    p->scene()->addItem(this);

    mainWindow->d->current_window_group = this;
    connect(mainWindow, SIGNAL(destroyed()), SLOT(deleteLater()));
    init();
    setZValue(mainWindow->zValue());
    stackBefore(mainWindow);
}

/*!
  Destroys this window group and frees resources. All windows that are within
  this group revert back to directly rendering its own texture.
 */
MCompositeWindowGroup::~MCompositeWindowGroup()
{
    Q_D(MCompositeWindowGroup);

    if (!QGLContext::currentContext()) {
        qWarning("MCompositeWindowGroup::%s(): no current GL context",
                 __func__);
        return;
    }

    GLuint texture = d->texture;
    glDeleteTextures(1, &texture);
    GLuint depth_buffer = d->depth_buffer;
    glDeleteRenderbuffers(1, &depth_buffer);
    GLuint fbo = d->fbo;
    glDeleteFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    // if stacking is dirty, stack windows now, otherwise we paint the scene
    // according to the old stacking
    MCompositeManager *p = (MCompositeManager*)qApp;
    if (p->d->stacking_timer.isActive())
        p->d->stackingTimeout();
}

void MCompositeWindowGroup::init()
{
    Q_D(MCompositeWindowGroup);

    if (!QGLContext::currentContext()) {
        qWarning("MCompositeWindowGroup::%s(): no current GL context",
                 __func__);
        d->valid = false;
        return;
    }
    d->renderer->current_window_group = this;

    glGenFramebuffers(1, &d->fbo);
    glGenRenderbuffers(1, &d->depth_buffer);
    glBindFramebuffer(GL_RENDERBUFFER, d->fbo);

    glGenTextures(1, &d->texture);
    glBindTexture(GL_TEXTURE_2D, d->texture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glBindRenderbuffer(GL_RENDERBUFFER, d->depth_buffer);
    glRenderbufferStorage(GL_RENDERBUFFER, DEPTH,
                          d->main_window->boundingRect().width(),
                          d->main_window->boundingRect().height());

    glBindFramebuffer(GL_FRAMEBUFFER, d->fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                           GL_TEXTURE_2D, d->texture, 0);

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                              GL_RENDERBUFFER, d->depth_buffer);

    glBindTexture(GL_TEXTURE_2D, d->texture);
    glTexImage2D(GL_TEXTURE_2D, 0, FORMAT,
                 d->main_window->boundingRect().width(),
                 d->main_window->boundingRect().height(), 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    GLenum ret = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (ret == GL_FRAMEBUFFER_COMPLETE)
        d->valid = true;
    else
        qWarning("MCompositeWindowGroup::%s(): incomplete FBO attachment 0x%x",
                 __func__, ret);

    glBindTexture(GL_TEXTURE_2D, 0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

static bool behindCompare(MTexturePixmapItem* a, MTexturePixmapItem* b)
{
    return a->indexInStack() < b->indexInStack();
}

/*!
  Adds the given \a window to this group except if it's already in the group.
  The window's transformations will remain unmodified.  Returns whether the
  \a window has been added.  You're supposed to call updateWindowPixmap()
  when you're finished adding children.
 */
bool MCompositeWindowGroup::addChildWindow(MTexturePixmapItem* window)
{
    Q_D(MCompositeWindowGroup);
    if (d->item_list.contains(window))
        return false;
    window->d->current_window_group = this;
    connect(window, SIGNAL(destroyed()), SLOT(q_removeWindow()));
    d->item_list.append(window);

    // ensure group windows are already stacked in proper order in advance
    // for back to front rendering. Could use depth buffer attachment at some
    // point so this might be unecessary
    qSort(d->item_list.begin(), d->item_list.end(), behindCompare);

    return true;
}

/*!
  Removes the given \a window to from group.
 */
void MCompositeWindowGroup::removeChildWindow(MTexturePixmapItem* window)
{
    Q_D(MCompositeWindowGroup);
    window->d->current_window_group = 0;
    d->item_list.removeAll(window);
}

void MCompositeWindowGroup::q_removeWindow()
{
    Q_D(MCompositeWindowGroup);
    MTexturePixmapItem* w = qobject_cast<MTexturePixmapItem*>(sender());
    if (w)
        d->item_list.removeAll(w);
}

void MCompositeWindowGroup::saveBackingStore() {}

void MCompositeWindowGroup::resize(int , int) {}

void MCompositeWindowGroup::clearTexture() {}

bool MCompositeWindowGroup::isDirectRendered() const { return false; }

QRectF MCompositeWindowGroup::boundingRect() const
{
    Q_D(const MCompositeWindowGroup);
    return d->main_window->boundingRect();
}

void MCompositeWindowGroup::paint(QPainter* painter,
                                  const QStyleOptionGraphicsItem* options,
                                  QWidget* widget)
{
    Q_D(MCompositeWindowGroup);
    Q_UNUSED(options)
    Q_UNUSED(widget)

#if QT_VERSION < 0x040600
    if (painter->paintEngine()->type() != QPaintEngine::OpenGL)
        return;
#else
    if (painter->paintEngine()->type() != QPaintEngine::OpenGL2) {
        return;
    }
#endif

    glBindTexture(GL_TEXTURE_2D, d->texture);
    if (d->main_window->propertyCache()->hasAlpha() ||
        (opacity() < 1.0f && !dimmedEffect()) ) {
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    }
    d->renderer->drawTexture(painter->combinedTransform(), boundingRect(),
                             opacity());
    glBlendFunc(GL_ONE, GL_ZERO);
    glDisable(GL_BLEND);
}

void MCompositeWindowGroup::windowRaised()
{
}

// Renders @main_window and all children into an FBO.
// Unredirects all involved windows.
void MCompositeWindowGroup::updateWindowPixmap(XRectangle *rects, int num,
                                               Time t)
{
    Q_UNUSED(rects)
    Q_UNUSED(num)
    Q_UNUSED(t)
    Q_D(MCompositeWindowGroup);

    if (d->main_window->isWindowTransitioning()) {
        // updates during transitioning cause issues when texcoords_from_rect
        // is used in MTexturePixmapItemPrivate and is heavy, too
        return;
    }
    if (!d->valid) {
        qDebug() << "invalid fbo";
        return;
    }

    glBindFramebuffer(GL_FRAMEBUFFER, d->fbo);
    GLenum ret = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (ret == GL_FRAMEBUFFER_COMPLETE)
        d->valid = true;
    else {
        qWarning("MCompositeWindowGroup::%s(): incomplete FBO attachment 0x%x",
                 __func__, ret);
        d->valid = false;
    }
    bool orig_value = d->main_window->d->inverted_texture;
    d->main_window->d->inverted_texture = false;
    // The redirection method is expected not to play with GL_FRAMEBUFFER.
    d->main_window->enableRedirectedRendering();
    d->main_window->renderTexture(d->main_window->sceneTransform());
    d->main_window->d->inverted_texture = orig_value;
    for (int i = 0; i < d->item_list.size(); ++i) {
        MTexturePixmapItem* item = d->item_list[i];
        orig_value = item->d->inverted_texture;
        item->d->inverted_texture = false;
        d->main_window->enableRedirectedRendering();
        item->renderTexture(item->sceneTransform());
        item->d->inverted_texture = orig_value;
    }
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

// internal re-implementation from MCompositeWindow
MTexturePixmapPrivate* MCompositeWindowGroup::renderer() const
{
    Q_D(const MCompositeWindowGroup);
    return d->renderer;
}

/*!
  \return Returns the texture used by the off-screen buffer
*/
GLuint MCompositeWindowGroup::texture()
{
    Q_D(MCompositeWindowGroup);
    return d->texture;
}

<|endoftext|>


<commit_before>#include <sirius.h>
#include <utils/json.hpp>

using namespace sirius;
using json = nlohmann::json;

const std::string aiida_output_file = "output_aiida.json";

enum class task_t : int
{
    ground_state_new     = 0,
    ground_state_restart = 1,
    k_point_path         = 2
};

void json_output_common(json& dict__)
{
    dict__["git_hash"] = git_hash;
    //dict__["build_date"] = build_date;
    dict__["comm_world_size"] = Communicator::world().size();
    dict__["threads_per_rank"] = omp_get_max_threads();
}

std::unique_ptr<Simulation_context> create_sim_ctx(std::string     fname__,
                                                   cmd_args const& args__)
{
    auto ctx_ptr = std::unique_ptr<Simulation_context>(new Simulation_context(fname__, Communicator::world()));
    Simulation_context& ctx = *ctx_ptr;

    auto& inp = ctx.parameters_input();
    if (inp.gamma_point_ && !(inp.ngridk_[0] * inp.ngridk_[1] * inp.ngridk_[2] == 1)) {
        TERMINATE("this is not a Gamma-point calculation")
    }

    auto mpi_grid_dims = args__.value("mpi_grid", ctx.mpi_grid_dims());
    ctx.set_mpi_grid_dims(mpi_grid_dims);

    auto std_evp_solver_name = args__.value("std_evp_solver_name", ctx.control().std_evp_solver_name_);
    ctx.std_evp_solver_name(std_evp_solver_name);

    auto gen_evp_solver_name = args__.value("gen_evp_solver_name", ctx.control().gen_evp_solver_name_);
    ctx.gen_evp_solver_name(gen_evp_solver_name);

    auto pu = args__.value("processing_unit", ctx.control().processing_unit_);
    if (pu == "") {
#ifdef __GPU
        pu = "gpu";
#else
        pu = "cpu";
#endif
    }
    ctx.set_processing_unit(pu);
    ctx.import(args__);

    return std::move(ctx_ptr);
}

double ground_state(Simulation_context& ctx,
                    task_t              task,
                    cmd_args const&     args,
                    int                 write_output)
{
    if (ctx.comm().rank() == 0 && ctx.control().print_memory_usage_) {
        MEMORY_USAGE_INFO();
    }

    auto& inp = ctx.parameters_input();

    std::string ref_file = args.value<std::string>("test_against", "");
    /* don't write output if we compare against the reference calculation */
    bool write_state = (ref_file.size() == 0);

    K_point_set kset(ctx, ctx.parameters_input().ngridk_, ctx.parameters_input().shiftk_, ctx.use_symmetry());
    DFT_ground_state dft(kset);

    if (ctx.comm().rank() == 0 && ctx.control().print_memory_usage_) {
        MEMORY_USAGE_INFO();
    }

    auto& potential = dft.potential();
    auto& density = dft.density();

    density.allocate();
    potential.allocate();

    if (task == task_t::ground_state_restart) {
        if (!utils::file_exists(storage_file_name)) {
            TERMINATE("storage file is not found");
        }
        density.load();
        potential.load();
    } else {
        dft.initial_state();
    }

    /* launch the calculation */
    auto result = dft.find(inp.potential_tol_, inp.energy_tol_, inp.num_dft_iter_, write_state);

    dft.print_magnetic_moment();

    if (ref_file.size() != 0) {
        json dict_ref;
        std::ifstream(ref_file) >> dict_ref;

        double e1 = result["energy"]["total"];
        double e2 = dict_ref["ground_state"]["energy"]["total"];

        if (std::abs(e1 - e2) > 1e-6) {
            printf("total energy is different: %18.7f computed vs. %18.7f reference\n", e1, e2);
            ctx.comm().abort(1);
        }
    }

    if (!ctx.full_potential()) {
        if (ctx.control().print_stress_) {
            Stress& s = dft.stress();
            s.calc_stress_total();
            s.print_info();
        }
        if (ctx.control().print_forces_) {
            Force& f = dft.forces();
            f.calc_forces_total();
            f.print_info();
        }
    }

    if (write_state && write_output) {
        json dict;
        json_output_common(dict);

        dict["task"] = static_cast<int>(task);
        dict["ground_state"] = result;
        dict["timers"] = utils::timer::serialize();
        dict["counters"] = json::object();
        dict["counters"]["local_operator_num_applied"] = Local_operator::num_applied();
        dict["counters"]["band_evp_work_count"] = Band::evp_work_count();

        if (ctx.comm().rank() == 0) {
            std::string output_file = args.value<std::string>("output", std::string("output_") +
                                                              ctx.start_time_tag() + std::string(".json"));
            std::ofstream ofs(output_file, std::ofstream::out | std::ofstream::trunc);
            ofs << dict.dump(4);
        }

        //if (args.exist("aiida_output")) {
        //    json dict;
        //    json_output_common(dict);
        //    dict["task"] = static_cast<int>(task);
        //    if (result >= 0) {
        //        dict["task_status"] = "converged";
        //        dict["num_scf_iterations"] =  result;
        //    } else {
        //        dict["task_status"] = "unconverged";
        //    }
        //    dict["volume"] = ctx.unit_cell().omega() * std::pow(bohr_radius, 3);
        //    dict["volume_units"] = "angstrom^3";
        //    dict["energy"] = dft.total_energy() * ha2ev;
        //    dict["energy_units"] = "eV";
        //    if (ctx.comm().rank() == 0) {
        //        std::ofstream ofs(aiida_output_file, std::ofstream::out | std::ofstream::trunc);
        //        ofs << dict.dump(4);
        //    }
        //}
    }

    /* wait for all */
    ctx.comm().barrier();

    return dft.total_energy();
}

/// Run a task based on a command line input.
void run_tasks(cmd_args const& args)
{
    /* get the task id */
    task_t task = static_cast<task_t>(args.value<int>("task", 0));
    /* get the input file name */
    std::string fname = args.value<std::string>("input", "sirius.json");
    if (!utils::file_exists(fname)) {
        if (Communicator::world().rank() == 0) {
            printf("input file does not exist\n");
        }
        return;
    }

    if (task == task_t::ground_state_new || task == task_t::ground_state_restart) {
        auto ctx = create_sim_ctx(fname, args);
        ctx->initialize();
        ground_state(*ctx, task, args, 1);
    }

    if (task == task_t::k_point_path) {
        auto ctx = create_sim_ctx(fname, args);
        ctx->set_iterative_solver_tolerance(1e-12);
        ctx->set_gamma_point(false);
        ctx->initialize();

        Potential potential(*ctx);
        if (ctx->full_potential()) {
            potential.allocate();
        }

        Hamiltonian H(*ctx, potential);

        Density density(*ctx);
        if (ctx->full_potential()) {
            density.allocate();
        }

        K_point_set ks(*ctx);

        json inp;
        std::ifstream(fname) >> inp;

        /* list of pairs (label, k-point vector) */
        std::vector<std::pair<std::string, std::vector<double>>> vertex;

        auto labels = inp["kpoints_path"].get<std::vector<std::string>>();
        for (auto e: labels) {
            auto v = inp["kpoints_rel"][e].get<std::vector<double>>();
            vertex.push_back({e, v});
        }

        std::vector<double> x_axis;
        std::vector<std::pair<double, std::string>> x_ticks;

        /* first point */
        x_axis.push_back(0);
        x_ticks.push_back({0, vertex[0].first});
        ks.add_kpoint(&vertex[0].second[0], 1.0);

        double t{0};
        for (size_t i = 0; i < vertex.size() - 1; i++) {
            vector3d<double> v0 = vector3d<double>(vertex[i].second);
            vector3d<double> v1 = vector3d<double>(vertex[i + 1].second);
            vector3d<double> dv = v1 - v0;
            vector3d<double> dv_cart = ctx->unit_cell().reciprocal_lattice_vectors() * dv;
            int np = std::max(10, static_cast<int>(30 * dv_cart.length()));
            for (int j = 1; j <= np; j++) {
                vector3d<double> v = v0 + dv * static_cast<double>(j) / np;
                ks.add_kpoint(&v[0], 1.0);
                t += dv_cart.length() / np;
                x_axis.push_back(t);
            }
            x_ticks.push_back({t, vertex[i + 1].first});
        }

        ks.initialize();

        //density.initial_density();
        density.load();
        potential.generate(density);
        Band band(*ctx);
        if (!ctx->full_potential()) {
            band.initialize_subspace(ks, H);
            if (ctx->hubbard_correction()) {
                TERMINATE("fix me");
                H.U().hubbard_compute_occupation_numbers(ks); // TODO: this is wrong; U matrix should come form the saved file
                H.U().calculate_hubbard_potential_and_energy();
            }
        }
        band.solve(ks, H, true);

        ks.sync_band_energies();
        if (Communicator::world().rank() == 0) {
            json dict;
            dict["header"] = {};
            dict["header"]["x_axis"] = x_axis;
            dict["header"]["x_ticks"] = std::vector<json>();
            dict["header"]["num_bands"] = ctx->num_bands();
            dict["header"]["num_mag_dims"] = ctx->num_mag_dims();
            for (auto& e: x_ticks) {
                json j;
                j["x"] = e.first;
                j["label"] = e.second;
                dict["header"]["x_ticks"].push_back(j);
            }
            dict["bands"] = std::vector<json>();

            for (int ik = 0; ik < ks.num_kpoints(); ik++) {
                json bnd_k;
                bnd_k["kpoint"] = std::vector<double>(3, 0);
                for (int x = 0; x < 3; x++) {
                    bnd_k["kpoint"][x] = ks[ik]->vk()[x];
                }
                std::vector<double> bnd_e;

                for (int ispn = 0; ispn < ctx->num_spin_dims(); ispn++) {
                    for (int j = 0; j < ctx->num_bands(); j++) {
                        bnd_e.push_back(ks[ik]->band_energy(j, ispn));
                    }
                }
                //ks.get_band_energies(ik, bnd_e.data());
                bnd_k["values"] = bnd_e;
                dict["bands"].push_back(bnd_k);
            }
            std::ofstream ofs("bands.json", std::ofstream::out | std::ofstream::trunc);
            ofs << dict.dump(4);
        }
    }
}

int main(int argn, char** argv)
{
    cmd_args args;
    args.register_key("--input=", "{string} input file name");
    args.register_key("--output=", "{string} output file name");
    args.register_key("--task=", "{int} task id");
    args.register_key("--mpi_grid=", "{vector int} MPI grid dimensions");
    args.register_key("--aiida_output", "write output for AiiDA");
    args.register_key("--test_against=", "{string} json file with reference values");
    args.register_key("--std_evp_solver_name=", "{string} standard eigen-value solver");
    args.register_key("--gen_evp_solver_name=", "{string} generalized eigen-value solver");
    args.register_key("--processing_unit=", "{string} type of the processing unit");
    args.register_key("--control.processing_unit=", "");
    args.register_key("--control.mpi_grid_dims=","");
    args.register_key("--control.std_evp_solver_name=", "");
    args.register_key("--control.gen_evp_solver_name=", "");
    args.register_key("--control.fft_mode", "");
    args.register_key("--control.memory_usage", "");
    args.register_key("--parameters.ngridk", "");
    args.register_key("--parameters.gamma_point", "");

    args.parse_args(argn, argv);
    if (args.exist("help")) {
        printf("Usage: %s [options]\n", argv[0]);
        args.print_help();
        return 0;
    }

    sirius::initialize(1);

    run_tasks(args);

    int my_rank = Communicator::world().rank();

    sirius::finalize(1);

    if (my_rank == 0)  {
        utils::timer::print();
        json dict;
        dict["flat"] = utils::timer::serialize();
        dict["tree"] = utils::timer::serialize_tree();
        std::ofstream ofs("timers.json", std::ofstream::out | std::ofstream::trunc);
        ofs << dict.dump(4);
    }

    return 0;
}
<commit_msg>fixes<commit_after>#include <sirius.h>
#include <utils/json.hpp>

using namespace sirius;
using json = nlohmann::json;

const std::string aiida_output_file = "output_aiida.json";

enum class task_t : int
{
    ground_state_new     = 0,
    ground_state_restart = 1,
    k_point_path         = 2
};

void json_output_common(json& dict__)
{
    dict__["git_hash"] = git_hash;
    //dict__["build_date"] = build_date;
    dict__["comm_world_size"] = Communicator::world().size();
    dict__["threads_per_rank"] = omp_get_max_threads();
}

std::unique_ptr<Simulation_context> create_sim_ctx(std::string     fname__,
                                                   cmd_args const& args__)
{
    auto ctx_ptr = std::unique_ptr<Simulation_context>(new Simulation_context(fname__, Communicator::world()));
    Simulation_context& ctx = *ctx_ptr;

    auto& inp = ctx.parameters_input();
    if (inp.gamma_point_ && !(inp.ngridk_[0] * inp.ngridk_[1] * inp.ngridk_[2] == 1)) {
        TERMINATE("this is not a Gamma-point calculation")
    }

    auto mpi_grid_dims = args__.value("mpi_grid", ctx.mpi_grid_dims());
    ctx.set_mpi_grid_dims(mpi_grid_dims);

    auto std_evp_solver_name = args__.value("std_evp_solver_name", ctx.control().std_evp_solver_name_);
    ctx.std_evp_solver_name(std_evp_solver_name);

    auto gen_evp_solver_name = args__.value("gen_evp_solver_name", ctx.control().gen_evp_solver_name_);
    ctx.gen_evp_solver_name(gen_evp_solver_name);

    auto pu = args__.value("processing_unit", ctx.control().processing_unit_);
    if (pu == "") {
#ifdef __GPU
        pu = "gpu";
#else
        pu = "cpu";
#endif
    }
    ctx.set_processing_unit(pu);
    ctx.import(args__);

    return std::move(ctx_ptr);
}

double ground_state(Simulation_context& ctx,
                    task_t              task,
                    cmd_args const&     args,
                    int                 write_output)
{
    if (ctx.comm().rank() == 0 && ctx.control().print_memory_usage_) {
        MEMORY_USAGE_INFO();
    }

    auto& inp = ctx.parameters_input();

    std::string ref_file = args.value<std::string>("test_against", "");
    /* don't write output if we compare against the reference calculation */
    bool write_state = (ref_file.size() == 0);

    K_point_set kset(ctx, ctx.parameters_input().ngridk_, ctx.parameters_input().shiftk_, ctx.use_symmetry());
    DFT_ground_state dft(kset);

    if (ctx.comm().rank() == 0 && ctx.control().print_memory_usage_) {
        MEMORY_USAGE_INFO();
    }

    auto& potential = dft.potential();
    auto& density = dft.density();

    density.allocate();
    potential.allocate();

    if (task == task_t::ground_state_restart) {
        if (!utils::file_exists(storage_file_name)) {
            TERMINATE("storage file is not found");
        }
        density.load();
        potential.load();
    } else {
        dft.initial_state();
    }

    /* launch the calculation */
    auto result = dft.find(inp.potential_tol_, inp.energy_tol_, inp.num_dft_iter_, write_state);

    dft.print_magnetic_moment();

    if (ref_file.size() != 0) {
        json dict_ref;
        std::ifstream(ref_file) >> dict_ref;

        double e1 = result["energy"]["total"];
        double e2 = dict_ref["ground_state"]["energy"]["total"];

        if (std::abs(e1 - e2) > 1e-6) {
            printf("total energy is different: %18.7f computed vs. %18.7f reference\n", e1, e2);
            ctx.comm().abort(1);
        }
    }

    if (!ctx.full_potential()) {
        if (ctx.control().print_stress_) {
            Stress& s = dft.stress();
            s.calc_stress_total();
            s.print_info();
        }
        if (ctx.control().print_forces_) {
            Force& f = dft.forces();
            f.calc_forces_total();
            f.print_info();
        }
    }

    if (write_state && write_output) {
        json dict;
        json_output_common(dict);

        dict["task"] = static_cast<int>(task);
        dict["ground_state"] = result;
        dict["timers"] = utils::timer::serialize();
        dict["counters"] = json::object();
        dict["counters"]["local_operator_num_applied"] = Local_operator::num_applied();
        dict["counters"]["band_evp_work_count"] = Band::evp_work_count();

        if (ctx.comm().rank() == 0) {
            std::string output_file = args.value<std::string>("output", std::string("output_") +
                                                              ctx.start_time_tag() + std::string(".json"));
            std::ofstream ofs(output_file, std::ofstream::out | std::ofstream::trunc);
            ofs << dict.dump(4);
        }

        //if (args.exist("aiida_output")) {
        //    json dict;
        //    json_output_common(dict);
        //    dict["task"] = static_cast<int>(task);
        //    if (result >= 0) {
        //        dict["task_status"] = "converged";
        //        dict["num_scf_iterations"] =  result;
        //    } else {
        //        dict["task_status"] = "unconverged";
        //    }
        //    dict["volume"] = ctx.unit_cell().omega() * std::pow(bohr_radius, 3);
        //    dict["volume_units"] = "angstrom^3";
        //    dict["energy"] = dft.total_energy() * ha2ev;
        //    dict["energy_units"] = "eV";
        //    if (ctx.comm().rank() == 0) {
        //        std::ofstream ofs(aiida_output_file, std::ofstream::out | std::ofstream::trunc);
        //        ofs << dict.dump(4);
        //    }
        //}
    }

    /* wait for all */
    ctx.comm().barrier();

    return dft.total_energy();
}

/// Run a task based on a command line input.
void run_tasks(cmd_args const& args)
{
    /* get the task id */
    task_t task = static_cast<task_t>(args.value<int>("task", 0));
    /* get the input file name */
    std::string fname = args.value<std::string>("input", "sirius.json");
    if (!utils::file_exists(fname)) {
        if (Communicator::world().rank() == 0) {
            printf("input file does not exist\n");
        }
        return;
    }

    if (task == task_t::ground_state_new || task == task_t::ground_state_restart) {
        auto ctx = create_sim_ctx(fname, args);
        ctx->initialize();
        ground_state(*ctx, task, args, 1);
    }

    if (task == task_t::k_point_path) {
        auto ctx = create_sim_ctx(fname, args);
        ctx->set_iterative_solver_tolerance(1e-12);
        ctx->set_gamma_point(false);
        ctx->initialize();

        Potential potential(*ctx);
        if (ctx->full_potential()) {
            potential.allocate();
        }

        Hamiltonian H(*ctx, potential);

        Density density(*ctx);
        if (ctx->full_potential()) {
            density.allocate();
        }

        K_point_set ks(*ctx);

        json inp;
        std::ifstream(fname) >> inp;

        /* list of pairs (label, k-point vector) */
        std::vector<std::pair<std::string, std::vector<double>>> vertex;

        auto labels = inp["kpoints_path"].get<std::vector<std::string>>();
        for (auto e: labels) {
            auto v = inp["kpoints_rel"][e].get<std::vector<double>>();
            vertex.push_back({e, v});
        }

        std::vector<double> x_axis;
        std::vector<std::pair<double, std::string>> x_ticks;

        /* first point */
        x_axis.push_back(0);
        x_ticks.push_back({0, vertex[0].first});
        ks.add_kpoint(&vertex[0].second[0], 1.0);

        double t{0};
        for (size_t i = 0; i < vertex.size() - 1; i++) {
            vector3d<double> v0 = vector3d<double>(vertex[i].second);
            vector3d<double> v1 = vector3d<double>(vertex[i + 1].second);
            vector3d<double> dv = v1 - v0;
            vector3d<double> dv_cart = ctx->unit_cell().reciprocal_lattice_vectors() * dv;
            int np = std::max(10, static_cast<int>(30 * dv_cart.length()));
            for (int j = 1; j <= np; j++) {
                vector3d<double> v = v0 + dv * static_cast<double>(j) / np;
                ks.add_kpoint(&v[0], 1.0);
                t += dv_cart.length() / np;
                x_axis.push_back(t);
            }
            x_ticks.push_back({t, vertex[i + 1].first});
        }

        ks.initialize();

        //density.initial_density();
        density.load();
        potential.generate(density);
        Band band(*ctx);
        if (!ctx->full_potential()) {
            band.initialize_subspace(ks, H);
            if (ctx->hubbard_correction()) {
                TERMINATE("fix me");
                H.U().hubbard_compute_occupation_numbers(ks); // TODO: this is wrong; U matrix should come form the saved file
                H.U().calculate_hubbard_potential_and_energy();
            }
        }
        band.solve(ks, H, true);

        ks.sync_band_energies();
        if (Communicator::world().rank() == 0) {
            json dict;
            dict["header"] = {};
            dict["header"]["x_axis"] = x_axis;
            dict["header"]["x_ticks"] = std::vector<json>();
            dict["header"]["num_bands"] = ctx->num_bands();
            dict["header"]["num_mag_dims"] = ctx->num_mag_dims();
            for (auto& e: x_ticks) {
                json j;
                j["x"] = e.first;
                j["label"] = e.second;
                dict["header"]["x_ticks"].push_back(j);
            }
            dict["bands"] = std::vector<json>();

            for (int ik = 0; ik < ks.num_kpoints(); ik++) {
                json bnd_k;
                bnd_k["kpoint"] = std::vector<double>(3, 0);
                for (int x = 0; x < 3; x++) {
                    bnd_k["kpoint"][x] = ks[ik]->vk()[x];
                }
                std::vector<double> bnd_e;

                for (int ispn = 0; ispn < ctx->num_spin_dims(); ispn++) {
                    for (int j = 0; j < ctx->num_bands(); j++) {
                        bnd_e.push_back(ks[ik]->band_energy(j, ispn));
                    }
                }
                //ks.get_band_energies(ik, bnd_e.data());
                bnd_k["values"] = bnd_e;
                dict["bands"].push_back(bnd_k);
            }
            std::ofstream ofs("bands.json", std::ofstream::out | std::ofstream::trunc);
            ofs << dict.dump(4);
        }
    }
}

int main(int argn, char** argv)
{
    cmd_args args;
    args.register_key("--input=", "{string} input file name");
    args.register_key("--output=", "{string} output file name");
    args.register_key("--task=", "{int} task id");
    args.register_key("--mpi_grid=", "{vector int} MPI grid dimensions");
    args.register_key("--aiida_output", "write output for AiiDA");
    args.register_key("--test_against=", "{string} json file with reference values");
    args.register_key("--std_evp_solver_name=", "{string} standard eigen-value solver");
    args.register_key("--gen_evp_solver_name=", "{string} generalized eigen-value solver");
    args.register_key("--processing_unit=", "{string} type of the processing unit");
    args.register_key("--control.processing_unit=", "");
    args.register_key("--control.mpi_grid_dims=","");
    args.register_key("--control.std_evp_solver_name=", "");
    args.register_key("--control.gen_evp_solver_name=", "");
    args.register_key("--control.fft_mode=", "");
    args.register_key("--control.memory_usage=", "");
    args.register_key("--parameters.ngridk=", "");
    args.register_key("--parameters.gamma_point=", "");

    args.parse_args(argn, argv);
    if (args.exist("help")) {
        printf("Usage: %s [options]\n", argv[0]);
        args.print_help();
        return 0;
    }

    sirius::initialize(1);

    run_tasks(args);

    int my_rank = Communicator::world().rank();

    sirius::finalize(1);

    if (my_rank == 0)  {
        utils::timer::print();
        json dict;
        dict["flat"] = utils::timer::serialize();
        dict["tree"] = utils::timer::serialize_tree();
        std::ofstream ofs("timers.json", std::ofstream::out | std::ofstream::trunc);
        ofs << dict.dump(4);
    }

    return 0;
}
<|endoftext|>


<commit_before>#include "types.h"
#include "kernel.hh"
#include "amd64.h"
#include "spinlock.h"
#include "condvar.h"
#include "proc.hh"
#include "cpu.hh"
#include "percpu.hh"
#include "wq.hh"
#include "kmtrace.hh"
#include "bits.hh"
#include "codex.hh"
#include "benchcodex.hh"

struct idle {
  struct proc *cur;
  struct proc *heir;
  SLIST_HEAD(zombies, proc) zombies;
  struct spinlock lock;
};

static percpu<idle> idlem;

void idleloop(void);

struct proc *
idleproc(void)
{
  return idlem->cur;
}

void
idlezombie(struct proc *p)
{
  acquire(&idlem[mycpu()->id].lock);
  SLIST_INSERT_HEAD(&idlem[mycpu()->id].zombies, p, child_next);
  release(&idlem[mycpu()->id].lock);
}

void
idlebequeath(void)
{
  // Only the current idle thread may call this function

  assert(mycpu()->ncli > 0);
  assert(myproc() == idlem->cur);

  assert(idlem->heir != nullptr);

  idlem->cur = idlem->heir;
  acquire(&idlem->heir->lock);
  idlem->heir->set_state(RUNNABLE);
  release(&idlem->heir->lock);
}

void
idleheir(void *x)
{
  post_swtch();

  idlem->heir = nullptr;
  idleloop();
}

static inline void
finishzombies(void)
{
  struct idle *i = &idlem[mycpu()->id];

  if (!SLIST_EMPTY(&i->zombies)) {
    struct proc *p, *np;
    acquire(&i->lock);
    SLIST_FOREACH_SAFE(p, &i->zombies, child_next, np) {
      SLIST_REMOVE(&i->zombies, p, proc, child_next);
      finishproc(p);
    }
    release(&i->lock);
  }
}

void
idleloop(void)
{
  // Test the work queue
  //extern void testwq(void);
  //testwq();

  //extern void benchwq(void);
  //benchwq();

  // Enabling mtrace calls in scheduler generates many mtrace_call_entrys.
  // mtrace_call_set(1, cpu->id);
  cprintf("idleloop(): myid()=%d\n", myid());
  mtstart(idleloop, myproc());

  // XXX: hacky bench for now- figure out how to test more later
#if CODEX
  if (myid() != 0) {
    benchcodex::ap(benchcodex::singleton_testcase());
  } else {
    benchcodex::main(benchcodex::singleton_testcase());
  }
#endif

  // The scheduler ensures that each idle loop always runs on the same CPU
  struct idle *myidle = idlem.get_unchecked();

  sti();
  for (;;) {
    acquire(&myproc()->lock);
    myproc()->set_state(RUNNABLE);
    sched();

    finishzombies();

    if (steal() == 0) {
      int worked;
      do {
        assert(mycpu()->ncli == 0);

        // If we don't have an heir, try to allocate one
        if (myidle->heir == nullptr) {
          struct proc *p;
          p = proc::alloc();
          if (p == nullptr)
            break;
          snprintf(p->name, sizeof(p->name), "idle_%u", mycpu()->id);
          p->cpuid = mycpu()->id;
          p->cpu_pin = 1;
          p->context->rip = (u64)idleheir;
          p->cwd = nullptr;
          myidle->heir = p;
        }

        worked = wq_trywork();
        // If we are no longer the idle thread, exit
        if (worked && myidle->cur != myproc())
          exit();
      } while(worked);
      sti();
      nop_pause();
    }
  }
}

void
initidle(void)
{
  struct proc *p = proc::alloc();
  if (!p)
    panic("initidle proc::alloc");

  if (myid() == 0) {
    u32 eax, ebx, ecx;
    cpuid(CPUID_FEATURES, nullptr, nullptr, &ecx, nullptr);
    if (ecx & FEATURE_ECX_MWAIT) {
      // Check smallest and largest line sizes
      cpuid(CPUID_MWAIT, &eax, &ebx, nullptr, nullptr);
      assert((u16)eax == 0x40);
      assert((u16)ebx == 0x40);
    }
  }

  SLIST_INIT(&idlem->zombies);
  idlem->lock = spinlock("idle_lock", LOCKSTAT_IDLE);

  snprintf(p->name, sizeof(p->name), "idle_%u", myid());
  mycpu()->proc = p;
  myproc()->cpuid = myid();
  myproc()->cpu_pin = 1;
  idlem->cur = p;
}
<commit_msg>be less chatty<commit_after>#include "types.h"
#include "kernel.hh"
#include "amd64.h"
#include "spinlock.h"
#include "condvar.h"
#include "proc.hh"
#include "cpu.hh"
#include "percpu.hh"
#include "wq.hh"
#include "kmtrace.hh"
#include "bits.hh"
#include "codex.hh"
#include "benchcodex.hh"

struct idle {
  struct proc *cur;
  struct proc *heir;
  SLIST_HEAD(zombies, proc) zombies;
  struct spinlock lock;
};

static percpu<idle> idlem;

void idleloop(void);

struct proc *
idleproc(void)
{
  return idlem->cur;
}

void
idlezombie(struct proc *p)
{
  acquire(&idlem[mycpu()->id].lock);
  SLIST_INSERT_HEAD(&idlem[mycpu()->id].zombies, p, child_next);
  release(&idlem[mycpu()->id].lock);
}

void
idlebequeath(void)
{
  // Only the current idle thread may call this function

  assert(mycpu()->ncli > 0);
  assert(myproc() == idlem->cur);

  assert(idlem->heir != nullptr);

  idlem->cur = idlem->heir;
  acquire(&idlem->heir->lock);
  idlem->heir->set_state(RUNNABLE);
  release(&idlem->heir->lock);
}

void
idleheir(void *x)
{
  post_swtch();

  idlem->heir = nullptr;
  idleloop();
}

static inline void
finishzombies(void)
{
  struct idle *i = &idlem[mycpu()->id];

  if (!SLIST_EMPTY(&i->zombies)) {
    struct proc *p, *np;
    acquire(&i->lock);
    SLIST_FOREACH_SAFE(p, &i->zombies, child_next, np) {
      SLIST_REMOVE(&i->zombies, p, proc, child_next);
      finishproc(p);
    }
    release(&i->lock);
  }
}

void
idleloop(void)
{
  // Test the work queue
  //extern void testwq(void);
  //testwq();

  //extern void benchwq(void);
  //benchwq();

  // Enabling mtrace calls in scheduler generates many mtrace_call_entrys.
  // mtrace_call_set(1, cpu->id);
#if CODEX
  cprintf("idleloop(): myid()=%d\n", myid());
#endif
  mtstart(idleloop, myproc());

  // XXX: hacky bench for now- figure out how to test more later
#if CODEX
  if (myid() != 0) {
    benchcodex::ap(benchcodex::singleton_testcase());
  } else {
    benchcodex::main(benchcodex::singleton_testcase());
  }
#endif

  // The scheduler ensures that each idle loop always runs on the same CPU
  struct idle *myidle = idlem.get_unchecked();

  sti();
  for (;;) {
    acquire(&myproc()->lock);
    myproc()->set_state(RUNNABLE);
    sched();

    finishzombies();

    if (steal() == 0) {
      int worked;
      do {
        assert(mycpu()->ncli == 0);

        // If we don't have an heir, try to allocate one
        if (myidle->heir == nullptr) {
          struct proc *p;
          p = proc::alloc();
          if (p == nullptr)
            break;
          snprintf(p->name, sizeof(p->name), "idle_%u", mycpu()->id);
          p->cpuid = mycpu()->id;
          p->cpu_pin = 1;
          p->context->rip = (u64)idleheir;
          p->cwd = nullptr;
          myidle->heir = p;
        }

        worked = wq_trywork();
        // If we are no longer the idle thread, exit
        if (worked && myidle->cur != myproc())
          exit();
      } while(worked);
      sti();
      nop_pause();
    }
  }
}

void
initidle(void)
{
  struct proc *p = proc::alloc();
  if (!p)
    panic("initidle proc::alloc");

  if (myid() == 0) {
    u32 eax, ebx, ecx;
    cpuid(CPUID_FEATURES, nullptr, nullptr, &ecx, nullptr);
    if (ecx & FEATURE_ECX_MWAIT) {
      // Check smallest and largest line sizes
      cpuid(CPUID_MWAIT, &eax, &ebx, nullptr, nullptr);
      assert((u16)eax == 0x40);
      assert((u16)ebx == 0x40);
    }
  }

  SLIST_INIT(&idlem->zombies);
  idlem->lock = spinlock("idle_lock", LOCKSTAT_IDLE);

  snprintf(p->name, sizeof(p->name), "idle_%u", myid());
  mycpu()->proc = p;
  myproc()->cpuid = myid();
  myproc()->cpu_pin = 1;
  idlem->cur = p;
}
<|endoftext|>


<commit_before>
#include "NNApplication.h"

NNApplication* NNApplication::m_pInstance = nullptr;

NNApplication::NNApplication()
	: m_Hwnd(nullptr), m_hInstance(nullptr),
	  m_ScreenHeight(0), m_ScreenWidth(0),
	  m_Fps(0.f), m_ElapsedTime(0.f), m_DeltaTime(0.f),
	  m_PrevTime(0), m_NowTime(0),
	  m_Renderer(nullptr), m_pSceneDirector(nullptr),
	  m_RendererStatus(UNKNOWN)
{

}
NNApplication::~NNApplication()
{

}

NNApplication* NNApplication::GetInstance()
{
	if ( m_pInstance == nullptr )
	{
		m_pInstance = new NNApplication();
	}

	return m_pInstance;
}
void NNApplication::ReleaseInstance()
{
	if ( m_pInstance != nullptr )
	{
		delete m_pInstance;
		m_pInstance = nullptr;
	}
}

bool NNApplication::Init( wchar_t* const title, int width, int height, RendererStatus renderStatus )
{
	m_hInstance = GetModuleHandle(0);

	m_Title = title;
	m_ScreenWidth = width;
	m_ScreenHeight = height;
	m_RendererStatus = renderStatus;

	_CreateWindow( m_Title, m_ScreenWidth, m_ScreenHeight );
	_CreateRenderer( renderStatus );

	m_pSceneDirector = NNSceneDirector::GetInstance();

	m_Renderer->Init();
	m_pSceneDirector->Init();

	return true;
}

bool NNApplication::Release()
{
 	SafeDelete( m_Renderer );
 	m_pSceneDirector->Release();

	NNSceneDirector::ReleaseInstance();
	NNResourceManager::ReleaseInstance();
	NNInputSystem::ReleaseInstance();
	NNAudioSystem::ReleaseInstance();
	ReleaseInstance();

	return true;
}

bool NNApplication::Run()
{
	//޼ ó
	MSG msg;
	ZeroMemory( &msg, sizeof(msg) );

	while (true)
	{
		if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{
			if ( msg.message == WM_QUIT )
			{
				return true;
			}
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		else
		{
			m_NowTime = timeGetTime();
			if ( m_PrevTime == 0.f )
			{
				m_PrevTime = m_NowTime;
			}
			m_DeltaTime = static_cast<float>(m_NowTime - m_PrevTime) / 1000.f;
			m_PrevTime = m_NowTime;
			m_Fps = 1.f / m_DeltaTime;

			m_ElapsedTime += m_DeltaTime;

			NNInputSystem::GetInstance()->UpdateKeyState();

			m_pSceneDirector->UpdateScene( m_DeltaTime );

			m_Renderer->Begin();
			m_Renderer->Clear();
			m_pSceneDirector->RenderScene();
			m_Renderer->End();

			if ( NNInputSystem::GetInstance()->GetKeyState( VK_ESCAPE ) == KEY_DOWN )
			{
				NNSceneDirector::GetInstance()->ChangeScene( CReturnScene::Create() );
			}
		}
	}

	return true;
}

bool NNApplication::_CreateWindow( wchar_t* title, int width, int height )
{
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = NULL;
	wcex.cbWndExtra = NULL;
	wcex.hInstance = m_hInstance;
	wcex.hIcon = NULL;
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = L"NNApplication";
	wcex.hIconSm = NULL;
	wcex.hIcon = NULL;

	RegisterClassEx( &wcex );

	DWORD style = WS_OVERLAPPED;

	m_Hwnd = CreateWindow( L"NNApplication", title, style, CW_USEDEFAULT, CW_USEDEFAULT,
		width, height, NULL, NULL, m_hInstance, NULL);

	ShowCursor(false);

#ifdef _DEBUG
	// not full screen
	ShowWindow( m_Hwnd, SW_SHOWNORMAL );
#endif

#ifndef _DEBUG
	// full screen
	SetWindowLong(m_Hwnd, GWL_STYLE, 0);
	ShowWindow( m_Hwnd, SW_SHOWMAXIMIZED );
#endif

	return true;
}
bool NNApplication::_CreateRenderer( RendererStatus renderStatus )
{
	switch( renderStatus )
	{
	case D2D:
		m_Renderer = new NND2DRenderer();
		break;
	default:
		return false;
	}

	return true;
}

LRESULT CALLBACK NNApplication::WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
	//޼ ó
	switch( message )
	{
	case WM_DESTROY:
		ExitProcess(0);
		PostQuitMessage(0);
		return 0;
		/*
	case WM_PAINT:
		PAINTSTRUCT ps;
		HDC hdc = BeginPaint( hWnd, &ps );
		EndPaint( hWnd, &ps );
		*/
	}

	return(DefWindowProc(hWnd,message,wParam,lParam));
}

<commit_msg>항상 전체화면!<commit_after>
#include "NNApplication.h"

NNApplication* NNApplication::m_pInstance = nullptr;

NNApplication::NNApplication()
	: m_Hwnd(nullptr), m_hInstance(nullptr),
	  m_ScreenHeight(0), m_ScreenWidth(0),
	  m_Fps(0.f), m_ElapsedTime(0.f), m_DeltaTime(0.f),
	  m_PrevTime(0), m_NowTime(0),
	  m_Renderer(nullptr), m_pSceneDirector(nullptr),
	  m_RendererStatus(UNKNOWN)
{

}
NNApplication::~NNApplication()
{

}

NNApplication* NNApplication::GetInstance()
{
	if ( m_pInstance == nullptr )
	{
		m_pInstance = new NNApplication();
	}

	return m_pInstance;
}
void NNApplication::ReleaseInstance()
{
	if ( m_pInstance != nullptr )
	{
		delete m_pInstance;
		m_pInstance = nullptr;
	}
}

bool NNApplication::Init( wchar_t* const title, int width, int height, RendererStatus renderStatus )
{
	m_hInstance = GetModuleHandle(0);

	m_Title = title;
	m_ScreenWidth = width;
	m_ScreenHeight = height;
	m_RendererStatus = renderStatus;

	_CreateWindow( m_Title, m_ScreenWidth, m_ScreenHeight );
	_CreateRenderer( renderStatus );

	m_pSceneDirector = NNSceneDirector::GetInstance();

	m_Renderer->Init();
	m_pSceneDirector->Init();

	return true;
}

bool NNApplication::Release()
{
 	SafeDelete( m_Renderer );
 	m_pSceneDirector->Release();

	NNSceneDirector::ReleaseInstance();
	NNResourceManager::ReleaseInstance();
	NNInputSystem::ReleaseInstance();
	NNAudioSystem::ReleaseInstance();
	ReleaseInstance();

	return true;
}

bool NNApplication::Run()
{
	//޼ ó
	MSG msg;
	ZeroMemory( &msg, sizeof(msg) );

	while (true)
	{
		if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{
			if ( msg.message == WM_QUIT )
			{
				return true;
			}
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		else
		{
			m_NowTime = timeGetTime();
			if ( m_PrevTime == 0.f )
			{
				m_PrevTime = m_NowTime;
			}
			m_DeltaTime = static_cast<float>(m_NowTime - m_PrevTime) / 1000.f;
			m_PrevTime = m_NowTime;
			m_Fps = 1.f / m_DeltaTime;

			m_ElapsedTime += m_DeltaTime;

			NNInputSystem::GetInstance()->UpdateKeyState();

			m_pSceneDirector->UpdateScene( m_DeltaTime );

			m_Renderer->Begin();
			m_Renderer->Clear();
			m_pSceneDirector->RenderScene();
			m_Renderer->End();

			if ( NNInputSystem::GetInstance()->GetKeyState( VK_ESCAPE ) == KEY_DOWN )
			{
				NNSceneDirector::GetInstance()->ChangeScene( CReturnScene::Create() );
			}
		}
	}

	return true;
}

bool NNApplication::_CreateWindow( wchar_t* title, int width, int height )
{
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = NULL;
	wcex.cbWndExtra = NULL;
	wcex.hInstance = m_hInstance;
	wcex.hIcon = NULL;
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = L"NNApplication";
	wcex.hIconSm = NULL;
	wcex.hIcon = NULL;

	RegisterClassEx( &wcex );

	DWORD style = WS_OVERLAPPED;

	m_Hwnd = CreateWindow( L"NNApplication", title, style, CW_USEDEFAULT, CW_USEDEFAULT,
		width, height, NULL, NULL, m_hInstance, NULL);

	ShowCursor(false);

	// full screen
	SetWindowLong(m_Hwnd, GWL_STYLE, 0);
	ShowWindow( m_Hwnd, SW_SHOWMAXIMIZED );

	return true;
}
bool NNApplication::_CreateRenderer( RendererStatus renderStatus )
{
	switch( renderStatus )
	{
	case D2D:
		m_Renderer = new NND2DRenderer();
		break;
	default:
		return false;
	}

	return true;
}

LRESULT CALLBACK NNApplication::WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
	//޼ ó
	switch( message )
	{
	case WM_DESTROY:
		ExitProcess(0);
		PostQuitMessage(0);
		return 0;
		/*
	case WM_PAINT:
		PAINTSTRUCT ps;
		HDC hdc = BeginPaint( hWnd, &ps );
		EndPaint( hWnd, &ps );
		*/
	}

	return(DefWindowProc(hWnd,message,wParam,lParam));
}

<|endoftext|>