<commit_before>
#include <algorithm>
#include <ctime>
#include <vector>

#include "absl/strings/str_cat.h"
#include "astronomy/frames.hpp"
#include "geometry/interval.hpp"
#include "geometry/named_quantities.hpp"
#include "glog/logging.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "integrators/methods.hpp"
#include "integrators/symmetric_linear_multistep_integrator.hpp"
#include "mathematica/mathematica.hpp"
#include "numerics/apodization.hpp"
#include "numerics/fast_fourier_transform.hpp"
#include "numerics/frequency_analysis.hpp"
#include "numerics/poisson_series.hpp"
#include "numerics/polynomial_evaluators.hpp"
#include "physics/ephemeris.hpp"
#include "physics/solar_system.hpp"
#include "quantities/astronomy.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"
#include "testing_utilities/approximate_quantity.hpp"

namespace principia {
namespace physics {

using astronomy::ICRS;
using geometry::Displacement;
using geometry::Instant;
using geometry::Interval;
using geometry::Position;
using integrators::SymmetricLinearMultistepIntegrator;
using integrators::methods::QuinlanTremaine1990Order12;
using numerics::EstrinEvaluator;
using numerics::FastFourierTransform;
using numerics::PoissonSeries;
using quantities::Angle;
using quantities::AngularFrequency;
using quantities::Infinity;
using quantities::Length;
using quantities::Time;
using quantities::astronomy::JulianYear;
using quantities::si::Day;
using quantities::si::Metre;
using quantities::si::Milli;
using quantities::si::Minute;
using quantities::si::Radian;
using quantities::si::Second;

namespace apodization = numerics::apodization;
namespace frequency_analysis = numerics::frequency_analysis;

static constexpr int aperiodic_approximation_degree = 5;
static constexpr int periodic_approximation_degree = 3;
static constexpr int log2_number_of_samples = 14;
static constexpr int number_of_frequencies = 10;
static constexpr Length acceptable_residual = 1 * Metre;
static constexpr Time min_projection_duration = 4 * Day;
static constexpr Time max_projection_duration = 0.25 * JulianYear;

class AnalyticalSeriesTest : public ::testing::Test {
 protected:
  AnalyticalSeriesTest()
      : logger_(TEMP_DIR / "analytical_series.wl",
               /*make_unique=*/false) {
    google::LogToStderr();
  }

  std::string ApplyParameters(std::string const& name) {
    return mathematica::Evaluate(
        mathematica::Apply(name,
                           std::tuple{aperiodic_approximation_degree,
                                      periodic_approximation_degree,
                                      celestial_}));
  }

  template<int degree>
  PoissonSeries<Displacement<ICRS>,
                aperiodic_approximation_degree, periodic_approximation_degree,
                EstrinEvaluator>
  ComputeCompactRepresentation(ContinuousTrajectory<ICRS> const& trajectory) {
    Instant const t_min = trajectory.t_min();
    Instant const t_max = trajectory.t_max();
    auto const piecewise_poisson_series =
        trajectory.ToPiecewisePoissonSeries<degree, 0>(t_min, t_max);

    logger_.Append("tMin",
                   std::tuple(projection_duration_, t_min),
                   mathematica::ExpressIn(Second));
    logger_.Append("tMax",
                   std::tuple(projection_duration_, t_max),
                   mathematica::ExpressIn(Second));

    int step = 0;
    std::clock_t const start_cpu = std::clock();

    auto angular_frequency_calculator =
        [this, start_cpu, &step, t_min, t_max](
            auto const& residual) -> std::optional<AngularFrequency> {
      Time const Δt = (t_max - t_min) / (1 << log2_number_of_samples);
      LOG(INFO) << "step=" << step;
      if (step == 0) {
        ++step;
        return AngularFrequency();
      } else if (step <= number_of_frequencies) {
        ++step;
        Length max_residual;
        std::vector<Displacement<ICRS>> residuals;
        for (int i = 0; i < 1 << log2_number_of_samples; ++i) {
          residuals.push_back(residual(t_min + i * Δt));
          max_residual = std::max(max_residual, residuals.back().Norm());
        }
        LOG(INFO) << "max_residual=" << max_residual;

        std::clock_t const end_cpu = std::clock();
        logger_.Append(
            ApplyParameters("maxResidual"),
            std::tuple(projection_duration_, step - 1,
                       max_residual,
                       1000.0 * (end_cpu - start_cpu) / CLOCKS_PER_SEC),
            mathematica::ExpressIn(Metre, Second));

        if (max_residual < acceptable_residual) {
          return std::nullopt;
        }
        auto fft =
            std::make_unique<FastFourierTransform<Displacement<ICRS>,
                                                  Instant,
                                                  1 << log2_number_of_samples>>(
                residuals, Δt);
        auto const mode = fft->Mode(2 * π * Radian / (t_max - t_min),
                                    Infinity<AngularFrequency>);
        Interval<Time> const period{2 * π * Radian / mode.max,
                                    2 * π * Radian / mode.min};
        LOG(INFO) << "period=" << period;
        auto const precise_mode = frequency_analysis::PreciseMode(
            mode, residual, apodization::Hann<EstrinEvaluator>(t_min, t_max));
        auto const precise_period = 2 * π * Radian / precise_mode;
        LOG(INFO) << "precise_period=" << precise_period;
        return precise_mode;
      } else {
        Length max_residual;
        for (int i = 0; i < 1 << log2_number_of_samples; ++i) {
          max_residual =
              std::max(max_residual, residual(t_min + i * Δt).Norm());
        }
        LOG(INFO) << "max_residual=" << max_residual
                  << (max_residual > acceptable_residual ? " ***" : "");

        std::clock_t const end_cpu = std::clock();
        logger_.Append(
            ApplyParameters("maxResidual"),
            std::tuple(projection_duration_, step,
                       max_residual,
                       1000.0 * (end_cpu - start_cpu) / CLOCKS_PER_SEC),
            mathematica::ExpressIn(Metre, Second));

        return std::nullopt;
      }
    };

    return frequency_analysis::IncrementalProjection<
        aperiodic_approximation_degree, periodic_approximation_degree>(
        piecewise_poisson_series,
        angular_frequency_calculator,
        apodization::Dirichlet<EstrinEvaluator>(t_min, t_max),
        t_min, t_max);
  }

  mathematica::Logger logger_;
  std::string celestial_;
  Time projection_duration_;
};

#define PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(                 \
    degree, approximation, trajectory)                                 \
  case degree: {                                                       \
    approximation =                                                    \
        std::make_unique<PoissonSeries<Displacement<ICRS>,             \
                                       aperiodic_approximation_degree, \
                                       periodic_approximation_degree,  \
                                       EstrinEvaluator>>(              \
            ComputeCompactRepresentation<(degree)>(trajectory));       \
    break;                                                             \
  }

#if !_DEBUG
TEST_F(AnalyticalSeriesTest, CompactRepresentation) {
  SolarSystem<ICRS> solar_system_at_j2000(
      SOLUTION_DIR / "astronomy" / "sol_gravity_model.proto.txt",
      SOLUTION_DIR / "astronomy" /
          "sol_initial_state_jd_2451545_000000000.proto.txt");

  for (Time projection_duration = min_projection_duration;
       projection_duration <= max_projection_duration;
       projection_duration *= 2) {
    // NOTE(phl): Keep these parameters aligned with
    // sol_numerics_blueprint.proto.txt.
    auto const ephemeris = solar_system_at_j2000.MakeEphemeris(
        /*accuracy_parameters=*/{/*fitting_tolerance=*/1 * Milli(Metre),
                                 /*geopotential_tolerance=*/0x1p-24},
        Ephemeris<ICRS>::FixedStepParameters(
            SymmetricLinearMultistepIntegrator<QuinlanTremaine1990Order12,
                                               Position<ICRS>>(),
            /*step=*/10 * Minute));
    ephemeris->Prolong(solar_system_at_j2000.epoch() + projection_duration);

    for (auto const& celestial : {"Io", "Moon", "Phobos"}) {
      LOG(INFO) << "---------- " << celestial << " " << projection_duration;
      auto const& celestial_trajectory =
          solar_system_at_j2000.trajectory(*ephemeris, celestial);
      int const celestial_piecewise_poisson_series_degree =
          celestial_trajectory.PiecewisePoissonSeriesDegree(
              celestial_trajectory.t_min(), celestial_trajectory.t_max());
      std::unique_ptr<PoissonSeries<Displacement<ICRS>,
                                    aperiodic_approximation_degree,
                                    periodic_approximation_degree,
                                    EstrinEvaluator>>
          celestial_approximation;

      celestial_ = celestial;
      projection_duration_ = projection_duration;

      switch (celestial_piecewise_poisson_series_degree) {
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            3, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            4, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            5, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            6, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            7, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            8, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            9, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            10, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            11, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            12, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            13, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            14, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            15, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            16, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            17, celestial_approximation, celestial_trajectory);
        default:
          LOG(FATAL) << "Unexpected degree "
                     << celestial_piecewise_poisson_series_degree;
      };

      logger_.Set(ApplyParameters("approximation"),
                  *celestial_approximation,
                  mathematica::ExpressIn(Metre, Second, Radian));
    }
  }
}
#endif

#undef PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE

}  // namespace physics
}  // namespace principia
<commit_msg>Lint.<commit_after>
#include <algorithm>
#include <ctime>
#include <string>
#include <vector>

#include "absl/strings/str_cat.h"
#include "astronomy/frames.hpp"
#include "geometry/interval.hpp"
#include "geometry/named_quantities.hpp"
#include "glog/logging.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "integrators/methods.hpp"
#include "integrators/symmetric_linear_multistep_integrator.hpp"
#include "mathematica/mathematica.hpp"
#include "numerics/apodization.hpp"
#include "numerics/fast_fourier_transform.hpp"
#include "numerics/frequency_analysis.hpp"
#include "numerics/poisson_series.hpp"
#include "numerics/polynomial_evaluators.hpp"
#include "physics/ephemeris.hpp"
#include "physics/solar_system.hpp"
#include "quantities/astronomy.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"
#include "testing_utilities/approximate_quantity.hpp"

namespace principia {
namespace physics {

using astronomy::ICRS;
using geometry::Displacement;
using geometry::Instant;
using geometry::Interval;
using geometry::Position;
using integrators::SymmetricLinearMultistepIntegrator;
using integrators::methods::QuinlanTremaine1990Order12;
using numerics::EstrinEvaluator;
using numerics::FastFourierTransform;
using numerics::PoissonSeries;
using quantities::Angle;
using quantities::AngularFrequency;
using quantities::Infinity;
using quantities::Length;
using quantities::Time;
using quantities::astronomy::JulianYear;
using quantities::si::Day;
using quantities::si::Metre;
using quantities::si::Milli;
using quantities::si::Minute;
using quantities::si::Radian;
using quantities::si::Second;

namespace apodization = numerics::apodization;
namespace frequency_analysis = numerics::frequency_analysis;

static constexpr int aperiodic_approximation_degree = 5;
static constexpr int periodic_approximation_degree = 3;
static constexpr int log2_number_of_samples = 14;
static constexpr int number_of_frequencies = 10;
static constexpr Length acceptable_residual = 1 * Metre;
static constexpr Time min_projection_duration = 4 * Day;
static constexpr Time max_projection_duration = 0.25 * JulianYear;

class AnalyticalSeriesTest : public ::testing::Test {
 protected:
  AnalyticalSeriesTest()
      : logger_(TEMP_DIR / "analytical_series.wl",
               /*make_unique=*/false) {
    google::LogToStderr();
  }

  std::string ApplyParameters(std::string const& name) {
    return mathematica::Evaluate(
        mathematica::Apply(name,
                           std::tuple{aperiodic_approximation_degree,
                                      periodic_approximation_degree,
                                      celestial_}));
  }

  template<int degree>
  PoissonSeries<Displacement<ICRS>,
                aperiodic_approximation_degree, periodic_approximation_degree,
                EstrinEvaluator>
  ComputeCompactRepresentation(ContinuousTrajectory<ICRS> const& trajectory) {
    Instant const t_min = trajectory.t_min();
    Instant const t_max = trajectory.t_max();
    auto const piecewise_poisson_series =
        trajectory.ToPiecewisePoissonSeries<degree, 0>(t_min, t_max);

    logger_.Append("tMin",
                   std::tuple(projection_duration_, t_min),
                   mathematica::ExpressIn(Second));
    logger_.Append("tMax",
                   std::tuple(projection_duration_, t_max),
                   mathematica::ExpressIn(Second));

    int step = 0;
    std::clock_t const start_cpu = std::clock();

    auto angular_frequency_calculator =
        [this, start_cpu, &step, t_min, t_max](
            auto const& residual) -> std::optional<AngularFrequency> {
      Time const Δt = (t_max - t_min) / (1 << log2_number_of_samples);
      LOG(INFO) << "step=" << step;
      if (step == 0) {
        ++step;
        return AngularFrequency();
      } else if (step <= number_of_frequencies) {
        ++step;
        Length max_residual;
        std::vector<Displacement<ICRS>> residuals;
        for (int i = 0; i < 1 << log2_number_of_samples; ++i) {
          residuals.push_back(residual(t_min + i * Δt));
          max_residual = std::max(max_residual, residuals.back().Norm());
        }
        LOG(INFO) << "max_residual=" << max_residual;

        std::clock_t const end_cpu = std::clock();
        logger_.Append(
            ApplyParameters("maxResidual"),
            std::tuple(projection_duration_, step - 1,
                       max_residual,
                       1000.0 * (end_cpu - start_cpu) / CLOCKS_PER_SEC),
            mathematica::ExpressIn(Metre, Second));

        if (max_residual < acceptable_residual) {
          return std::nullopt;
        }
        auto fft =
            std::make_unique<FastFourierTransform<Displacement<ICRS>,
                                                  Instant,
                                                  1 << log2_number_of_samples>>(
                residuals, Δt);
        auto const mode = fft->Mode(2 * π * Radian / (t_max - t_min),
                                    Infinity<AngularFrequency>);
        Interval<Time> const period{2 * π * Radian / mode.max,
                                    2 * π * Radian / mode.min};
        LOG(INFO) << "period=" << period;
        auto const precise_mode = frequency_analysis::PreciseMode(
            mode, residual, apodization::Hann<EstrinEvaluator>(t_min, t_max));
        auto const precise_period = 2 * π * Radian / precise_mode;
        LOG(INFO) << "precise_period=" << precise_period;
        return precise_mode;
      } else {
        Length max_residual;
        for (int i = 0; i < 1 << log2_number_of_samples; ++i) {
          max_residual =
              std::max(max_residual, residual(t_min + i * Δt).Norm());
        }
        LOG(INFO) << "max_residual=" << max_residual
                  << (max_residual > acceptable_residual ? " ***" : "");

        std::clock_t const end_cpu = std::clock();
        logger_.Append(
            ApplyParameters("maxResidual"),
            std::tuple(projection_duration_, step,
                       max_residual,
                       1000.0 * (end_cpu - start_cpu) / CLOCKS_PER_SEC),
            mathematica::ExpressIn(Metre, Second));

        return std::nullopt;
      }
    };

    return frequency_analysis::IncrementalProjection<
        aperiodic_approximation_degree, periodic_approximation_degree>(
        piecewise_poisson_series,
        angular_frequency_calculator,
        apodization::Dirichlet<EstrinEvaluator>(t_min, t_max),
        t_min, t_max);
  }

  mathematica::Logger logger_;
  std::string celestial_;
  Time projection_duration_;
};

#define PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(                 \
    degree, approximation, trajectory)                                 \
  case degree: {                                                       \
    approximation =                                                    \
        std::make_unique<PoissonSeries<Displacement<ICRS>,             \
                                       aperiodic_approximation_degree, \
                                       periodic_approximation_degree,  \
                                       EstrinEvaluator>>(              \
            ComputeCompactRepresentation<(degree)>(trajectory));       \
    break;                                                             \
  }

#if !_DEBUG
TEST_F(AnalyticalSeriesTest, CompactRepresentation) {
  SolarSystem<ICRS> solar_system_at_j2000(
      SOLUTION_DIR / "astronomy" / "sol_gravity_model.proto.txt",
      SOLUTION_DIR / "astronomy" /
          "sol_initial_state_jd_2451545_000000000.proto.txt");

  for (Time projection_duration = min_projection_duration;
       projection_duration <= max_projection_duration;
       projection_duration *= 2) {
    // NOTE(phl): Keep these parameters aligned with
    // sol_numerics_blueprint.proto.txt.
    auto const ephemeris = solar_system_at_j2000.MakeEphemeris(
        /*accuracy_parameters=*/{/*fitting_tolerance=*/1 * Milli(Metre),
                                 /*geopotential_tolerance=*/0x1p-24},
        Ephemeris<ICRS>::FixedStepParameters(
            SymmetricLinearMultistepIntegrator<QuinlanTremaine1990Order12,
                                               Position<ICRS>>(),
            /*step=*/10 * Minute));
    ephemeris->Prolong(solar_system_at_j2000.epoch() + projection_duration);

    for (auto const& celestial : {"Io", "Moon", "Phobos"}) {
      LOG(INFO) << "---------- " << celestial << " " << projection_duration;
      auto const& celestial_trajectory =
          solar_system_at_j2000.trajectory(*ephemeris, celestial);
      int const celestial_piecewise_poisson_series_degree =
          celestial_trajectory.PiecewisePoissonSeriesDegree(
              celestial_trajectory.t_min(), celestial_trajectory.t_max());
      std::unique_ptr<PoissonSeries<Displacement<ICRS>,
                                    aperiodic_approximation_degree,
                                    periodic_approximation_degree,
                                    EstrinEvaluator>>
          celestial_approximation;

      celestial_ = celestial;
      projection_duration_ = projection_duration;

      switch (celestial_piecewise_poisson_series_degree) {
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            3, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            4, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            5, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            6, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            7, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            8, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            9, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            10, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            11, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            12, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            13, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            14, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            15, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            16, celestial_approximation, celestial_trajectory);
        PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
            17, celestial_approximation, celestial_trajectory);
        default:
          LOG(FATAL) << "Unexpected degree "
                     << celestial_piecewise_poisson_series_degree;
      };

      logger_.Set(ApplyParameters("approximation"),
                  *celestial_approximation,
                  mathematica::ExpressIn(Metre, Second, Radian));
    }
  }
}
#endif

#undef PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE

}  // namespace physics
}  // namespace principia
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: graphsh.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: nn $ $Date: 2000-11-25 14:55:21 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef PCH
#include "ui_pch.hxx"
#endif

#pragma hdrstop

//------------------------------------------------------------------

#include <sfx2/app.hxx>
#include <sfx2/objface.hxx>
#include <sfx2/request.hxx>
#include <svtools/whiter.hxx>
#include <svx/svdograf.hxx>
#include <svx/grfflt.hxx>

#include "graphsh.hxx"
#include "sc.hrc"
#include "viewdata.hxx"
#include "drawview.hxx"
#include "scresid.hxx"

#define ScGraphicShell
#include "scslots.hxx"

#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()

SFX_IMPL_INTERFACE(ScGraphicShell, ScDrawShell, ScResId(SCSTR_GRAPHICSHELL) )
{
    SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
                                ScResId(RID_GRAPHIC_OBJECTBAR) );
    SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_GRAPHIC) );
    SFX_OBJECTMENU_REGISTRATION( SID_OBJECTMENU0, ScResId(RID_OBJECTMENU_DRAW) );
}

TYPEINIT1( ScGraphicShell, ScDrawShell );

ScGraphicShell::ScGraphicShell(ScViewData* pData) :
    ScDrawShell(pData)
{
    SetHelpId(HID_SCSHELL_GRAPHIC);
    SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GraphicObject")));
}

ScGraphicShell::~ScGraphicShell()
{
}

void ScGraphicShell::GetAttrState( SfxItemSet& rSet )
{
    SfxItemSet      aAttrSet( GetPool() );
    SfxWhichIter    aIter( rSet );
    USHORT          nWhich = aIter.FirstWhich();

    ScDrawView* pView = GetViewData()->GetScDrawView();
    pView->GetAttributes( aAttrSet );

    while( nWhich )
    {
        USHORT nSlotId = SfxItemPool::IsWhich( nWhich )
                            ? GetPool().GetSlotId( nWhich )
                            : nWhich;

        switch( nSlotId )
        {
            case( SID_ATTR_GRAF_MODE ):
            {
                if( SFX_ITEM_AVAILABLE <= aAttrSet.GetItemState( SDRATTR_GRAFMODE ) )
                {
                    rSet.Put( SfxUInt16Item( nSlotId,
                        ITEMVALUE( aAttrSet, SDRATTR_GRAFMODE, SdrGrafModeItem ) ) );
                }
            }
            break;

            case( SID_ATTR_GRAF_RED ):
            {
                if( SFX_ITEM_AVAILABLE <= aAttrSet.GetItemState( SDRATTR_GRAFRED ) )
                {
                    rSet.Put( SfxInt16Item( nSlotId,
                        ITEMVALUE( aAttrSet, SDRATTR_GRAFRED, SdrGrafRedItem ) ) );
                }
            }
            break;

            case( SID_ATTR_GRAF_GREEN ):
            {
                if( SFX_ITEM_AVAILABLE <= aAttrSet.GetItemState( SDRATTR_GRAFGREEN ) )
                {
                    rSet.Put( SfxInt16Item( nSlotId,
                        ITEMVALUE( aAttrSet, SDRATTR_GRAFGREEN, SdrGrafGreenItem ) ) );
                }
            }
            break;

            case( SID_ATTR_GRAF_BLUE ):
            {
                if( SFX_ITEM_AVAILABLE <= aAttrSet.GetItemState( SDRATTR_GRAFBLUE ) )
                {
                    rSet.Put( SfxInt16Item( nSlotId,
                        ITEMVALUE( aAttrSet, SDRATTR_GRAFBLUE, SdrGrafBlueItem ) ) );
                }
            }
            break;

            case( SID_ATTR_GRAF_LUMINANCE ):
            {
                if( SFX_ITEM_AVAILABLE <= aAttrSet.GetItemState( SDRATTR_GRAFLUMINANCE ) )
                {
                    rSet.Put( SfxInt16Item( nSlotId,
                        ITEMVALUE( aAttrSet, SDRATTR_GRAFLUMINANCE, SdrGrafLuminanceItem ) ) );
                }
            }
            break;

            case( SID_ATTR_GRAF_CONTRAST ):
            {
                if( SFX_ITEM_AVAILABLE <= aAttrSet.GetItemState( SDRATTR_GRAFCONTRAST ) )
                {
                    rSet.Put( SfxInt16Item( nSlotId,
                        ITEMVALUE( aAttrSet, SDRATTR_GRAFCONTRAST, SdrGrafContrastItem ) ) );
                }
            }
            break;

            case( SID_ATTR_GRAF_GAMMA ):
            {
                if( SFX_ITEM_AVAILABLE <= aAttrSet.GetItemState( SDRATTR_GRAFGAMMA ) )
                {
                    rSet.Put( SfxUInt32Item( nSlotId,
                        ITEMVALUE( aAttrSet, SDRATTR_GRAFGAMMA, SdrGrafGamma100Item ) ) );
                }
            }
            break;

            case( SID_ATTR_GRAF_TRANSPARENCE ):
            {
                if( SFX_ITEM_AVAILABLE <= aAttrSet.GetItemState( SDRATTR_GRAFTRANSPARENCE ) )
                {
                    const SdrMarkList&  rMarkList = pView->GetMarkList();
                    BOOL                bEnable = TRUE;

                    for( USHORT i = 0, nCount = rMarkList.GetMarkCount();
                            ( i < nCount ) && bEnable; i++ )
                    {
                        SdrObject* pObj = rMarkList.GetMark( 0 )->GetObj();

                        if( !pObj || !pObj->ISA( SdrGrafObj ) ||
                            ( (SdrGrafObj*) pObj )->HasGDIMetaFile() ||
                            ( (SdrGrafObj*) pObj )->IsAnimated() )
                        {
                            bEnable = FALSE;
                        }
                    }

                    if( bEnable )
                        rSet.Put( SfxUInt16Item( nSlotId,
                            ITEMVALUE( aAttrSet, SDRATTR_GRAFTRANSPARENCE, SdrGrafTransparenceItem ) ) );
                    else
                        rSet.DisableItem( SID_ATTR_GRAF_TRANSPARENCE );
                }
            }
            break;

            default:
            break;
        }

        nWhich = aIter.NextWhich();
    }
}

void ScGraphicShell::Execute( SfxRequest& rReq )
{
    SfxItemSet aSet( GetPool(), SDRATTR_GRAF_FIRST, SDRATTR_GRAF_LAST-1 );

    const SfxItemSet*   pArgs = rReq.GetArgs();
    const SfxPoolItem*  pItem;
    USHORT              nSlot = rReq.GetSlot();
    BOOL                bGeometryChanged = FALSE;

    if( !pArgs || SFX_ITEM_SET != pArgs->GetItemState( nSlot, FALSE, &pItem ))
        pItem = 0;

    switch( nSlot )
    {
        case SID_ATTR_GRAF_RED:
            if( pItem )
                aSet.Put( SdrGrafRedItem( ((SfxInt16Item*)pItem)->GetValue() ));
        break;

        case SID_ATTR_GRAF_GREEN:
            if( pItem )
                aSet.Put( SdrGrafGreenItem( ((SfxInt16Item*)pItem)->GetValue() ));
        break;

        case SID_ATTR_GRAF_BLUE:
            if( pItem )
                aSet.Put( SdrGrafBlueItem( ((SfxInt16Item*)pItem)->GetValue() ));
        break;

        case SID_ATTR_GRAF_LUMINANCE:
            if( pItem )
                aSet.Put( SdrGrafLuminanceItem( ((SfxInt16Item*)pItem)->GetValue() ));
        break;

        case SID_ATTR_GRAF_CONTRAST:
            if( pItem )
                aSet.Put( SdrGrafContrastItem( ((SfxInt16Item*)pItem)->GetValue() ));
        break;

        case SID_ATTR_GRAF_GAMMA:
            if( pItem )
                aSet.Put( SdrGrafGamma100Item( ((SfxUInt32Item*)pItem)->GetValue() ));
        break;

        case SID_ATTR_GRAF_TRANSPARENCE:
            if( pItem )
                aSet.Put( SdrGrafTransparenceItem( ((SfxUInt16Item*)pItem)->GetValue() ));
        break;

        case SID_ATTR_GRAF_MODE:
            if( pItem )
                aSet.Put( SdrGrafModeItem( (GraphicDrawMode)
                                        ((SfxUInt16Item*)pItem)->GetValue() ));
        break;

        default:
            break;
    }

    if( aSet.Count() )
    {
        ScDrawView* pView = GetViewData()->GetScDrawView();
        pView->SetAttributes( aSet );
    }

    Invalidate();
}

void ScGraphicShell::GetFilterState( SfxItemSet& rSet )
{
    ScDrawView* pView = GetViewData()->GetScDrawView();
    const SdrMarkList& rMarkList = pView->GetMarkList();
    BOOL bEnable = FALSE;

    if( rMarkList.GetMarkCount() == 1 )
    {
        SdrObject* pObj = rMarkList.GetMark( 0 )->GetObj();

        if( pObj && pObj->ISA( SdrGrafObj ) && ( ( (SdrGrafObj*) pObj )->GetGraphicType() == GRAPHIC_BITMAP ) )
            bEnable = TRUE;
    }

    if( !bEnable )
        SvxGraphicFilter::DisableGraphicFilterSlots( rSet );
}

void ScGraphicShell::ExecuteFilter( SfxRequest& rReq )
{
    ScDrawView* pView = GetViewData()->GetScDrawView();
    const SdrMarkList& rMarkList = pView->GetMarkList();

    if( rMarkList.GetMarkCount() == 1 )
    {
        SdrObject* pObj = rMarkList.GetMark( 0 )->GetObj();

        if( pObj && pObj->ISA( SdrGrafObj ) && ( (SdrGrafObj*) pObj )->GetGraphicType() == GRAPHIC_BITMAP )
        {
            GraphicObject aFilterObj( ( (SdrGrafObj*) pObj )->GetGraphicObject() );

            if( SVX_GRAPHICFILTER_ERRCODE_NONE ==
                SvxGraphicFilter::ExecuteGrfFilterSlot( rReq, aFilterObj ) )
            {
                SdrPageView* pPageView = pView->GetPageViewPvNum( 0 );

                if( pPageView )
                {
                    SdrGrafObj* pFilteredObj = (SdrGrafObj*) pObj->Clone();
                    String      aStr( pView->GetMarkDescription() );

                    aStr.Append( sal_Unicode(' ') );
                    aStr.Append( String( ScResId( SCSTR_UNDO_GRAFFILTER ) ) );
                    pView->BegUndo( aStr );
                    pFilteredObj->SetGraphicObject( aFilterObj );
                    pView->ReplaceObject( pObj, *pPageView, pFilteredObj );
                    pView->EndUndo();
                }
            }
        }
    }

    Invalidate();
}

<commit_msg>#80753# use SvxGrafAttrHelper<commit_after>/*************************************************************************
 *
 *  $RCSfile: graphsh.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: nn $ $Date: 2000-11-26 15:17:45 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef PCH
#include "ui_pch.hxx"
#endif

#pragma hdrstop

//------------------------------------------------------------------

#include <sfx2/app.hxx>
#include <sfx2/objface.hxx>
#include <sfx2/request.hxx>
#include <svtools/whiter.hxx>
#include <svx/svdograf.hxx>
#include <svx/grfflt.hxx>
#include <svx/grafctrl.hxx>

#include "graphsh.hxx"
#include "sc.hrc"
#include "viewdata.hxx"
#include "drawview.hxx"
#include "scresid.hxx"

#define ScGraphicShell
#include "scslots.hxx"

#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()

SFX_IMPL_INTERFACE(ScGraphicShell, ScDrawShell, ScResId(SCSTR_GRAPHICSHELL) )
{
    SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
                                ScResId(RID_GRAPHIC_OBJECTBAR) );
    SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_GRAPHIC) );
    SFX_OBJECTMENU_REGISTRATION( SID_OBJECTMENU0, ScResId(RID_OBJECTMENU_DRAW) );
}

TYPEINIT1( ScGraphicShell, ScDrawShell );

ScGraphicShell::ScGraphicShell(ScViewData* pData) :
    ScDrawShell(pData)
{
    SetHelpId(HID_SCSHELL_GRAPHIC);
    SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GraphicObject")));
}

ScGraphicShell::~ScGraphicShell()
{
}

void ScGraphicShell::GetAttrState( SfxItemSet& rSet )
{
    ScDrawView* pView = GetViewData()->GetScDrawView();

    if( pView )
        SvxGrafAttrHelper::GetGrafAttrState( rSet, *pView );
}

void ScGraphicShell::Execute( SfxRequest& rReq )
{
    ScDrawView* pView = GetViewData()->GetScDrawView();

    if( pView )
    {
        SvxGrafAttrHelper::ExecuteGrafAttr( rReq, *pView );
        Invalidate();
    }
}

void ScGraphicShell::GetFilterState( SfxItemSet& rSet )
{
    ScDrawView* pView = GetViewData()->GetScDrawView();
    const SdrMarkList& rMarkList = pView->GetMarkList();
    BOOL bEnable = FALSE;

    if( rMarkList.GetMarkCount() == 1 )
    {
        SdrObject* pObj = rMarkList.GetMark( 0 )->GetObj();

        if( pObj && pObj->ISA( SdrGrafObj ) && ( ( (SdrGrafObj*) pObj )->GetGraphicType() == GRAPHIC_BITMAP ) )
            bEnable = TRUE;
    }

    if( !bEnable )
        SvxGraphicFilter::DisableGraphicFilterSlots( rSet );
}

void ScGraphicShell::ExecuteFilter( SfxRequest& rReq )
{
    ScDrawView* pView = GetViewData()->GetScDrawView();
    const SdrMarkList& rMarkList = pView->GetMarkList();

    if( rMarkList.GetMarkCount() == 1 )
    {
        SdrObject* pObj = rMarkList.GetMark( 0 )->GetObj();

        if( pObj && pObj->ISA( SdrGrafObj ) && ( (SdrGrafObj*) pObj )->GetGraphicType() == GRAPHIC_BITMAP )
        {
            GraphicObject aFilterObj( ( (SdrGrafObj*) pObj )->GetGraphicObject() );

            if( SVX_GRAPHICFILTER_ERRCODE_NONE ==
                SvxGraphicFilter::ExecuteGrfFilterSlot( rReq, aFilterObj ) )
            {
                SdrPageView* pPageView = pView->GetPageViewPvNum( 0 );

                if( pPageView )
                {
                    SdrGrafObj* pFilteredObj = (SdrGrafObj*) pObj->Clone();
                    String      aStr( pView->GetMarkDescription() );

                    aStr.Append( sal_Unicode(' ') );
                    aStr.Append( String( ScResId( SCSTR_UNDO_GRAFFILTER ) ) );
                    pView->BegUndo( aStr );
                    pFilteredObj->SetGraphicObject( aFilterObj );
                    pView->ReplaceObject( pObj, *pPageView, pFilteredObj );
                    pView->EndUndo();
                }
            }
        }
    }

    Invalidate();
}

<|endoftext|>


<commit_before>//=====================================================================//
/*!	@file
	@brief	A/D 変換による複数スイッチ検出サンプル @n
			P22/ANI2(54) に抵抗ネットワークの複数スイッチを接続 @n
                      P22                           @n
                       |                            @n
			VDD - 10K -+- 3.3K -+- 6.8K -+- 20K -+  @n
                       |        |        |       |  @n
			         RIGHT     UP      DOWN    LEFT @n
                       |        |        |       |  @n
                      VSS      VSS      VSS     VSS
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <cstdint>
#include "common/port_utils.hpp"
#include "common/fifo.hpp"
#include "common/uart_io.hpp"
#include "common/format.hpp"
#include "common/itimer.hpp"
#include "common/adc_io.hpp"
#include "common/task.hpp"
#include "common/bitset.hpp"
#include "common/switch_man.hpp"

namespace {

	typedef utils::fifo<uint8_t, 32> buffer;
	device::uart_io<device::SAU02, device::SAU03, buffer, buffer> uart_;

	device::itimer<uint8_t> itm_;

	typedef device::adc_io<utils::null_task> adc;
	adc adc_;

	enum class SWITCH : uint8_t {
		RIGHT,
		UP,
		DOWN,
		LEFT
	};

	typedef utils::bitset<uint8_t, SWITCH> switch_bits;
	utils::switch_man<switch_bits> switch_man_;
}

/// 割り込みベクターの定義
const void* ivec_[] __attribute__ ((section (".ivec"))) = {
	/*  0 */  nullptr,
	/*  1 */  nullptr,
	/*  2 */  nullptr,
	/*  3 */  nullptr,
	/*  4 */  nullptr,
	/*  5 */  nullptr,
	/*  6 */  nullptr,
	/*  7 */  nullptr,
	/*  8 */  nullptr,
	/*  9 */  nullptr,
	/* 10 */  nullptr,
	/* 11 */  nullptr,
	/* 12 */  nullptr,
	/* 13 */  nullptr,
	/* 14 */  nullptr,
	/* 15 */  nullptr,
	/* 16 */  reinterpret_cast<void*>(uart_.send_task),  // UART1-TX
	/* 17 */  reinterpret_cast<void*>(uart_.recv_task),  // UART1-RX
	/* 18 */  reinterpret_cast<void*>(uart_.error_task), // UART1-ER
	/* 19 */  nullptr,
	/* 20 */  nullptr,
	/* 21 */  nullptr,
	/* 22 */  nullptr,
	/* 23 */  nullptr,
	/* 24 */  nullptr,
	/* 25 */  nullptr,
	/* 26 */  reinterpret_cast<void*>(itm_.task),
};

extern "C" {
	void sci_putch(char ch)
	{
		uart_.putch(ch);
	}

	void sci_puts(const char* str)
	{
		uart_.puts(str);
	}
};

int main(int argc, char* argv[])
{
	utils::port::pullup_all();  ///< 安全の為、全ての入力をプルアップ

	device::PM4.B3 = 0;  // output

	{
		uint8_t intr_level = 1;
		uart_.start(115200, intr_level);
	}

	{
		uint8_t intr_level = 1;
		itm_.start(60, intr_level);
	}

	{
		device::PM2.B2 = 1;
		device::PM2.B3 = 1;
		uint8_t intr_level = 0;
		adc_.start(adc::REFP::VDD, adc::REFM::VSS, intr_level);
	}

	uart_.puts("Start RL78/G13 A/D Switch sample\n");

	uint8_t n = 0;
	while(1) {
		itm_.sync();
		switch_bits tmp;

		auto val = adc_.get(2);
		val >>= 6;   // 0 to 1023
		val += 128;  // 閾値のオフセット（1024 / 4(SWITCH) / 2）
		val /= 256;  // デコード（1024 / 4(SWITCH）
		if(val < 4) {
			tmp.set(static_cast<SWITCH>(val));
		}
		switch_man_.service(tmp);

		if(switch_man_.get_positive().get(SWITCH::UP)) {
			utils::format("UP: on\n");
		}
		if(switch_man_.get_positive().get(SWITCH::DOWN)) {
			utils::format("DOWN: on\n");
		}
		if(switch_man_.get_positive().get(SWITCH::LEFT)) {
			utils::format("LEFT: on\n");
		}
		if(switch_man_.get_positive().get(SWITCH::RIGHT)) {
			utils::format("RIGHT: on\n");
		}

		if(switch_man_.get_negative().get(SWITCH::UP)) {
			utils::format("UP: off\n");
		}
		if(switch_man_.get_negative().get(SWITCH::DOWN)) {
			utils::format("DOWN: off\n");
		}
		if(switch_man_.get_negative().get(SWITCH::LEFT)) {
			utils::format("LEFT: off\n");
		}
		if(switch_man_.get_negative().get(SWITCH::RIGHT)) {
			utils::format("RIGHT: off\n");
		}

		++n;
		if(n >= 30) {
			n = 0;
		}
		device::P4.B3 = n < 10 ? false : true;
	}
}
<commit_msg>add double switch input<commit_after>//=====================================================================//
/*!	@file
	@brief	A/D 変換による複数スイッチ検出サンプル @n
			P22/ANI2(54) ４つのスイッチ（排他）@n
                      P22                           @n
                       |                            @n
			VDD - 10K -+- 3.3K -+- 6.8K -+- 20K -+  @n
                       |        |        |       |  @n
			         RIGHT     UP      DOWN    LEFT @n
                       |        |        |       |  @n
                      VSS      VSS      VSS     VSS @n
			P23/ANI3(55)：２つのスイッチ（同時押し対応）@n
            VDD - 5K -+- 10K -+- 5K -+- VSS @n
                      |       |      |      @n
                      +-  A  -+-  B -+
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <cstdint>
#include "common/port_utils.hpp"
#include "common/fifo.hpp"
#include "common/uart_io.hpp"
#include "common/format.hpp"
#include "common/itimer.hpp"
#include "common/adc_io.hpp"
#include "common/task.hpp"
#include "common/bitset.hpp"
#include "common/switch_man.hpp"

namespace {

	typedef utils::fifo<uint8_t, 32> buffer;
	device::uart_io<device::SAU02, device::SAU03, buffer, buffer> uart_;

	device::itimer<uint8_t> itm_;

	typedef device::adc_io<utils::null_task> adc;
	adc adc_;

	enum class SWITCH : uint8_t {
		RIGHT,
		UP,
		DOWN,
		LEFT,
		A,
		B
	};

	typedef utils::bitset<uint8_t, SWITCH> switch_bits;
	utils::switch_man<switch_bits> switch_man_;
}

/// 割り込みベクターの定義
const void* ivec_[] __attribute__ ((section (".ivec"))) = {
	/*  0 */  nullptr,
	/*  1 */  nullptr,
	/*  2 */  nullptr,
	/*  3 */  nullptr,
	/*  4 */  nullptr,
	/*  5 */  nullptr,
	/*  6 */  nullptr,
	/*  7 */  nullptr,
	/*  8 */  nullptr,
	/*  9 */  nullptr,
	/* 10 */  nullptr,
	/* 11 */  nullptr,
	/* 12 */  nullptr,
	/* 13 */  nullptr,
	/* 14 */  nullptr,
	/* 15 */  nullptr,
	/* 16 */  reinterpret_cast<void*>(uart_.send_task),  // UART1-TX
	/* 17 */  reinterpret_cast<void*>(uart_.recv_task),  // UART1-RX
	/* 18 */  reinterpret_cast<void*>(uart_.error_task), // UART1-ER
	/* 19 */  nullptr,
	/* 20 */  nullptr,
	/* 21 */  nullptr,
	/* 22 */  nullptr,
	/* 23 */  nullptr,
	/* 24 */  nullptr,
	/* 25 */  nullptr,
	/* 26 */  reinterpret_cast<void*>(itm_.task),
};

extern "C" {
	void sci_putch(char ch)
	{
		uart_.putch(ch);
	}

	void sci_puts(const char* str)
	{
		uart_.puts(str);
	}
};

int main(int argc, char* argv[])
{
	utils::port::pullup_all();  ///< 安全の為、全ての入力をプルアップ

	device::PM4.B3 = 0;  // output

	{
		uint8_t intr_level = 1;
		uart_.start(115200, intr_level);
	}

	{
		uint8_t intr_level = 1;
		itm_.start(60, intr_level);
	}

	{
		device::PM2.B2 = 1;
		device::PM2.B3 = 1;
		uint8_t intr_level = 0;
		adc_.start(adc::REFP::VDD, adc::REFM::VSS, intr_level);
	}

	uart_.puts("Start RL78/G13 A/D Switch sample\n");

	uint8_t n = 0;
	while(1) {
		itm_.sync();

		// ４つのスイッチ判定（排他的）
		auto val = adc_.get(2);
		val >>= 6;   // 0 to 1023
		val += 128;  // 閾値のオフセット（1024 / 4(SWITCH) / 2）
		val /= 256;  // デコード（1024 / 4(SWITCH）

		switch_bits tmp;
		if(val < 4) {
			tmp.set(static_cast<SWITCH>(val));
		}

		// ２つのスイッチ判定（同時押し判定）
		val = adc_.get(3);
		val >>= 6;  // 0 to 1023
		if(val < 256) {
			tmp.set(SWITCH::A);
			tmp.set(SWITCH::B);
		} else if(val < 594) {
			tmp.set(SWITCH::A);
		} else if(val < 722) {
			tmp.set(SWITCH::B);
		}

		switch_man_.service(tmp);

		if(switch_man_.get_positive().get(SWITCH::UP)) {
			utils::format("UP   : on\n");
		}
		if(switch_man_.get_positive().get(SWITCH::DOWN)) {
			utils::format("DOWN : on\n");
		}
		if(switch_man_.get_positive().get(SWITCH::LEFT)) {
			utils::format("LEFT : on\n");
		}
		if(switch_man_.get_positive().get(SWITCH::RIGHT)) {
			utils::format("RIGHT: on\n");
		}

		if(switch_man_.get_positive().get(SWITCH::A)) {
			utils::format("A    : on\n");
		}
		if(switch_man_.get_positive().get(SWITCH::B)) {
			utils::format("B    : on\n");
		}

		if(switch_man_.get_negative().get(SWITCH::UP)) {
			utils::format("UP   : off\n");
		}
		if(switch_man_.get_negative().get(SWITCH::DOWN)) {
			utils::format("DOWN : off\n");
		}
		if(switch_man_.get_negative().get(SWITCH::LEFT)) {
			utils::format("LEFT : off\n");
		}
		if(switch_man_.get_negative().get(SWITCH::RIGHT)) {
			utils::format("RIGHT: off\n");
		}

		if(switch_man_.get_negative().get(SWITCH::A)) {
			utils::format("A    : off\n");
		}
		if(switch_man_.get_negative().get(SWITCH::B)) {
			utils::format("B    : off\n");
		}

		++n;
		if(n >= 30) {
			n = 0;
		}
		device::P4.B3 = n < 10 ? false : true;
	}
}
<|endoftext|>


<commit_before>/*!
  \copyright (c) RDO-Team, 2003-2012
  \file      chart_tree.cpp
  \author    Захаров Павел
  \date      12.03.2003
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "app/rdo_studio/pch/stdpch.h"
// ----------------------------------------------------------------------- INCLUDES
#include "utils/warning_disable.h"
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <QProcess>
#include <QTextStream>
#include <QFileDialog>
#include <QDrag>
#include "utils/warning_enable.h"
// ----------------------------------------------------------------------- SYNOPSIS
#include "app/rdo_studio/src/application.h"
#include "app/rdo_studio/src/main_window.h"
#include "app/rdo_studio/src/model/model.h"
#include "app/rdo_studio/src/tracer/tracer.h"
#include "app/rdo_studio/src/tracer/chart/chart_tree.h"
#include "app/rdo_studio/src/tracer/chart/chart_serie.h"
#include "app/rdo_studio/src/tracer/tracer_resource_type.h"
#include "app/rdo_studio/src/tracer/tracer_resource.h"
#include "app/rdo_studio/src/tracer/tracer_pattern.h"
#include "app/rdo_studio/src/tracer/tracer_operation.h"
#include "app/rdo_studio/src/tracer/tracer_result.h"
// --------------------------------------------------------------------------------

using namespace rdo::gui::tracer;

Q_DECLARE_METATYPE(const ChartTreeItem*);

ChartTree::ChartTree(PTR(QWidget) pParent)
	: parent_type(pParent)
{
	setColumnCount    (1);
	setHeaderHidden   (true);
	setRootIsDecorated(false);

	m_iconList.reserve(IT_COUNT);
	m_iconList.push_back(QIcon(QString::fromUtf8(":/images/images/tree_chart_root.png")));
	m_iconList.push_back(QIcon(QString::fromUtf8(":/images/images/tree_chart_sub_root_1.png")));
	m_iconList.push_back(QIcon(QString::fromUtf8(":/images/images/tree_chart_sub_root_2.png")));
	m_iconList.push_back(QIcon(QString::fromUtf8(":/images/images/tree_chart_sub_root_3.png")));
	m_iconList.push_back(QIcon(QString::fromUtf8(":/images/images/tree_chart_value.png")));
	m_iconList.push_back(QIcon(QString::fromUtf8(":/images/images/tree_chart_erased.png")));

	m_root    = rdo::Factory<ChartTreeItem>::create();
	m_rootRTP = rdo::Factory<ChartTreeItem>::create();
	m_rootPAT = rdo::Factory<ChartTreeItem>::create();
	m_rootPMV = rdo::Factory<ChartTreeItem>::create();

	m_root->setCtrlItem(new QTreeWidgetItem(this));
	m_root->getCtrlItem().setText(0, "Модель");
	m_root->getCtrlItem().setIcon(0, m_iconList[IT_ROOT]);

	createItem(m_root, m_rootRTP, "Типы ресурсов", IT_SUB_ROOT_1);
	createItem(m_root, m_rootPAT, "Образцы",       IT_SUB_ROOT_1);
	createItem(m_root, m_rootPMV, "Результаты",    IT_SUB_ROOT_1);

	m_root->getCtrlItem().setExpanded(true);

	connect(this, &ChartTree::itemDoubleClicked, this, &ChartTree::onTreeWidgetItemDoubleClicked);

	Ui::MainWindow* pMainWindow = g_pApp->getMainWndUI();
	ASSERT(pMainWindow);

	m_pPopupMenu = new QMenu(pParent);
	m_pPopupMenu->addAction(pMainWindow->actChartCreate);
	m_pPopupMenu->addAction(pMainWindow->actChartExport);
}

ChartTree::~ChartTree()
{}

LPChartTreeItem ChartTree::getIfItemIsDrawable(CPTR(QTreeWidgetItem) pCtrlItem) const
{
	LPChartTreeItem pRes;
	if (pCtrlItem)
	{
		PTR(ChartTreeItem) pItem = const_cast<PTR(ChartTreeItem)>(pCtrlItem->data(0, Qt::UserRole).value<CPTR(ChartTreeItem)>());
		pRes = pItem && pItem->isDrawable()
			? pItem
			: NULL;
	}
	return pRes;
}

void ChartTree::doDragDrop(CREF(LPSerie) pSerie)
{
	quintptr address=(quintptr)pSerie.get();
	QByteArray serieData(QString::number(address).toLatin1());

	QDrag *drag = new QDrag(this);
	QMimeData *mimeData = new QMimeData;

	mimeData->setData("ChartSerie", serieData);
	drag->setMimeData(mimeData);
	drag->exec();
}

void ChartTree::setModelName(CREF(QString) modelName)
{
	m_root->getCtrlItem().setText(0, QString("Модель : %1").arg(modelName));
}

void ChartTree::createItem(CREF(LPChartTreeItem) parent, CREF(LPChartTreeItem) item, CREF(QString) name, IconType iconType)
{
	PTR(QTreeWidgetItem) pCtrlItem = new QTreeWidgetItem(&parent->getCtrlItem());
	pCtrlItem->setText(0, name);
	pCtrlItem->setIcon(0, m_iconList[iconType]);
	//! @todo smart_ptr
	const ChartTreeItem* pRawItem = item.get();
	pCtrlItem->setData(0, Qt::UserRole, QVariant::fromValue(pRawItem));
	item->setCtrlItem(pCtrlItem);
}

void ChartTree::addResourceType(CREF(LPResourceType) pRTP)
{
	ASSERT(pRTP);
	createItem(m_rootRTP, pRTP, pRTP->getName(), IT_SUB_ROOT_2);
}

void ChartTree::addResource(CREF(LPResource) pRSS)
{
	LPResourceType pRTP = pRSS->getType();
	ASSERT(pRTP);
	ASSERT(pRSS);
	createItem(pRTP, pRSS, pRSS->getName(), IT_SUB_ROOT_3);

	int count = pRTP->getParamsCount();
	for (int i = 0; i < count; i++)
	{
		LPChartTreeItem pParam = pRSS->getParam(i);
		ASSERT(pParam);
		createItem(pRSS, pParam, pRTP->getParamInfo(i)->getName(), IT_VALUE);
	}
	updateResource(pRSS);
}

void ChartTree::updateResource(CREF(LPResource) pRSS)
{
	if (pRSS->isErased())
	{
		pRSS->getCtrlItem().setIcon(0, m_iconList[IT_ERASED]);
	}
	else
	{
		pRSS->getCtrlItem().setIcon(0, m_iconList[IT_SUB_ROOT_3]);
	}
}

void ChartTree::addPattern(CREF(LPPattern) pPAT)
{
	ASSERT(pPAT);
	createItem(m_rootPAT, pPAT, pPAT->getName(), IT_SUB_ROOT_2);
}

void ChartTree::addOperation(CREF(LPOperationBase) pOPR)
{
	createItem(pOPR->getPattern(), pOPR, pOPR->getName(), IT_VALUE);
}

void ChartTree::addResult(CREF(LPResult) pPMV)
{
	createItem(m_rootPMV, pPMV, pPMV->getName(), IT_VALUE);
}

void ChartTree::deleteChildren(CREF(LPChartTreeItem) pParent)
{
	QList<PTR(QTreeWidgetItem)> children = pParent->getCtrlItem().takeChildren();
	BOOST_FOREACH(PTR(QTreeWidgetItem) item, children)
	{
		pParent->getCtrlItem().removeChild(item);
	}
}

void ChartTree::clear()
{
	deleteChildren(m_rootRTP);
	deleteChildren(m_rootPAT);
	deleteChildren(m_rootPMV);
	m_root->getCtrlItem().setText(0, "Модель");
}

void ChartTree::createChart(PTR(QTreeWidgetItem) pCtrlItem) const
{
	LPSerie pSerie = getIfItemIsDrawable(pCtrlItem).object_dynamic_cast<Serie>();
	if (pSerie)
	{
		g_pTracer->addSerieToChart(pSerie);
	}
}

rbool ChartTree::activateExistingChart(PTR(QTreeWidgetItem) pCtrlItem) const
{
	LPSerie pSerie = getIfItemIsDrawable(pCtrlItem).object_dynamic_cast<Serie>();
	if (pSerie)
	{
		return pSerie->activateFirstDoc();
	}
	return false;
}

PTR(QTreeWidgetItem) ChartTree::getSelected() const
{
	QList<PTR(QTreeWidgetItem)> selected = selectedItems();
	return selected.size() == 1
		? selected.front()
		: NULL;
}

void ChartTree::onTreeWidgetItemDoubleClicked(QTreeWidgetItem* pCtrlItem, int)
{
	if (!g_pTracer->getDrawTrace())
		return;

	if (!activateExistingChart(pCtrlItem))
	{
		createChart(pCtrlItem);
	}
}

void ChartTree::onChartCreate()
{
	createChart(getSelected());
}

void ChartTree::onChartExport()
{
	if (!g_pTracer->getDrawTrace())
		return;

	LPChartTreeItem pItem = getIfItemIsDrawable(getSelected());
	if (!pItem)
		return;

	LPSerie pSerie = pItem.object_dynamic_cast<Serie>();
	ASSERT(pSerie);
	Serie::ExportData exportData = pSerie->exportData();
	if (exportData.empty())
		return;

	boost::filesystem::path path =
		boost::filesystem::path(g_pModel->getFullName().toLocal8Bit().constData()).parent_path() /
		QString("%1.csv").arg(pSerie->getTitle()).toLocal8Bit().constData();

	QString fileName = QFileDialog::getSaveFileName(
		this,
		"Сохранить",
		QString::fromLocal8Bit(path.string().c_str()),
		"csv-файл (*.csv);;Все файлы (*.*)"
	);
	if (fileName.isEmpty())
		return;

	QFile data(fileName);
	if (data.open(QIODevice::Text | QFile::WriteOnly | QFile::Truncate))
	{
		QTextStream stream(&data);
		BOOST_FOREACH(CREF(Serie::ExportData::value_type) exportItem, exportData)
		{
			stream << exportItem << endl;
		}
		data.close();
	}
}

void ChartTree::focusInEvent(QFocusEvent* pEvent)
{
	parent_type::focusInEvent(pEvent);
	activate(pEvent);
}

void ChartTree::focusOutEvent(QFocusEvent* pEvent)
{
	parent_type::focusOutEvent(pEvent);
	deactivate(pEvent);
}

void ChartTree::onUpdateActions(rbool activated)
{
	MainWindow* pMainWindow = g_pApp->getMainWndUI();
	ASSERT(pMainWindow);

	updateAction(
		pMainWindow->actChartCreate,
		activated && g_pTracer->getDrawTrace() && getIfItemIsDrawable(getSelected()),
		this, &ChartTree::onChartCreate
	);

	updateAction(
		pMainWindow->actChartExport,
		activated && g_pTracer->getDrawTrace() && getIfItemIsDrawable(getSelected()),
		this, &ChartTree::onChartExport
	);

	updateAction(
		pMainWindow->actHelpContext,
		activated,
		this, &ChartTree::onHelpContext
	);
}

void ChartTree::onHelpContext()
{
	QByteArray ba;
	ba.append("setSource qthelp://studio/doc/rdo_studio_rus/html/work_model/work_model_chart.htm\n");
	g_pApp->callQtAssistant(ba);
}

void ChartTree::mousePressEvent(QMouseEvent* pEvent)
{
	QTreeWidgetItem* item = itemAt(pEvent->pos());
	this->setCurrentItem(item);
	onUpdateActions(isActivated());
	if (pEvent->button() == Qt::LeftButton)
	{
		LPSerie pSerie = getIfItemIsDrawable(getSelected()).object_dynamic_cast<Serie>();
		if(pSerie)
		{
			doDragDrop(pSerie);
		}
		parent_type::mousePressEvent(pEvent);
	}
	else if (pEvent->button() == Qt::RightButton)
	{
		m_pPopupMenu->exec(pEvent->globalPos());
	}
}<commit_msg> - исправлен родитель<commit_after>/*!
  \copyright (c) RDO-Team, 2003-2012
  \file      chart_tree.cpp
  \author    Захаров Павел
  \date      12.03.2003
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "app/rdo_studio/pch/stdpch.h"
// ----------------------------------------------------------------------- INCLUDES
#include "utils/warning_disable.h"
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <QProcess>
#include <QTextStream>
#include <QFileDialog>
#include <QDrag>
#include "utils/warning_enable.h"
// ----------------------------------------------------------------------- SYNOPSIS
#include "app/rdo_studio/src/application.h"
#include "app/rdo_studio/src/main_window.h"
#include "app/rdo_studio/src/model/model.h"
#include "app/rdo_studio/src/tracer/tracer.h"
#include "app/rdo_studio/src/tracer/chart/chart_tree.h"
#include "app/rdo_studio/src/tracer/chart/chart_serie.h"
#include "app/rdo_studio/src/tracer/tracer_resource_type.h"
#include "app/rdo_studio/src/tracer/tracer_resource.h"
#include "app/rdo_studio/src/tracer/tracer_pattern.h"
#include "app/rdo_studio/src/tracer/tracer_operation.h"
#include "app/rdo_studio/src/tracer/tracer_result.h"
// --------------------------------------------------------------------------------

using namespace rdo::gui::tracer;

Q_DECLARE_METATYPE(const ChartTreeItem*);

ChartTree::ChartTree(PTR(QWidget) pParent)
	: parent_type(pParent)
{
	setColumnCount    (1);
	setHeaderHidden   (true);
	setRootIsDecorated(false);

	m_iconList.reserve(IT_COUNT);
	m_iconList.push_back(QIcon(QString::fromUtf8(":/images/images/tree_chart_root.png")));
	m_iconList.push_back(QIcon(QString::fromUtf8(":/images/images/tree_chart_sub_root_1.png")));
	m_iconList.push_back(QIcon(QString::fromUtf8(":/images/images/tree_chart_sub_root_2.png")));
	m_iconList.push_back(QIcon(QString::fromUtf8(":/images/images/tree_chart_sub_root_3.png")));
	m_iconList.push_back(QIcon(QString::fromUtf8(":/images/images/tree_chart_value.png")));
	m_iconList.push_back(QIcon(QString::fromUtf8(":/images/images/tree_chart_erased.png")));

	m_root    = rdo::Factory<ChartTreeItem>::create();
	m_rootRTP = rdo::Factory<ChartTreeItem>::create();
	m_rootPAT = rdo::Factory<ChartTreeItem>::create();
	m_rootPMV = rdo::Factory<ChartTreeItem>::create();

	m_root->setCtrlItem(new QTreeWidgetItem(this));
	m_root->getCtrlItem().setText(0, "Модель");
	m_root->getCtrlItem().setIcon(0, m_iconList[IT_ROOT]);

	createItem(m_root, m_rootRTP, "Типы ресурсов", IT_SUB_ROOT_1);
	createItem(m_root, m_rootPAT, "Образцы",       IT_SUB_ROOT_1);
	createItem(m_root, m_rootPMV, "Результаты",    IT_SUB_ROOT_1);

	m_root->getCtrlItem().setExpanded(true);

	connect(this, &ChartTree::itemDoubleClicked, this, &ChartTree::onTreeWidgetItemDoubleClicked);

	Ui::MainWindow* pMainWindow = g_pApp->getMainWndUI();
	ASSERT(pMainWindow);

	m_pPopupMenu = new QMenu(this);
	m_pPopupMenu->addAction(pMainWindow->actChartCreate);
	m_pPopupMenu->addAction(pMainWindow->actChartExport);
}

ChartTree::~ChartTree()
{}

LPChartTreeItem ChartTree::getIfItemIsDrawable(CPTR(QTreeWidgetItem) pCtrlItem) const
{
	LPChartTreeItem pRes;
	if (pCtrlItem)
	{
		PTR(ChartTreeItem) pItem = const_cast<PTR(ChartTreeItem)>(pCtrlItem->data(0, Qt::UserRole).value<CPTR(ChartTreeItem)>());
		pRes = pItem && pItem->isDrawable()
			? pItem
			: NULL;
	}
	return pRes;
}

void ChartTree::doDragDrop(CREF(LPSerie) pSerie)
{
	quintptr address=(quintptr)pSerie.get();
	QByteArray serieData(QString::number(address).toLatin1());

	QDrag *drag = new QDrag(this);
	QMimeData *mimeData = new QMimeData;

	mimeData->setData("ChartSerie", serieData);
	drag->setMimeData(mimeData);
	drag->exec();
}

void ChartTree::setModelName(CREF(QString) modelName)
{
	m_root->getCtrlItem().setText(0, QString("Модель : %1").arg(modelName));
}

void ChartTree::createItem(CREF(LPChartTreeItem) parent, CREF(LPChartTreeItem) item, CREF(QString) name, IconType iconType)
{
	PTR(QTreeWidgetItem) pCtrlItem = new QTreeWidgetItem(&parent->getCtrlItem());
	pCtrlItem->setText(0, name);
	pCtrlItem->setIcon(0, m_iconList[iconType]);
	//! @todo smart_ptr
	const ChartTreeItem* pRawItem = item.get();
	pCtrlItem->setData(0, Qt::UserRole, QVariant::fromValue(pRawItem));
	item->setCtrlItem(pCtrlItem);
}

void ChartTree::addResourceType(CREF(LPResourceType) pRTP)
{
	ASSERT(pRTP);
	createItem(m_rootRTP, pRTP, pRTP->getName(), IT_SUB_ROOT_2);
}

void ChartTree::addResource(CREF(LPResource) pRSS)
{
	LPResourceType pRTP = pRSS->getType();
	ASSERT(pRTP);
	ASSERT(pRSS);
	createItem(pRTP, pRSS, pRSS->getName(), IT_SUB_ROOT_3);

	int count = pRTP->getParamsCount();
	for (int i = 0; i < count; i++)
	{
		LPChartTreeItem pParam = pRSS->getParam(i);
		ASSERT(pParam);
		createItem(pRSS, pParam, pRTP->getParamInfo(i)->getName(), IT_VALUE);
	}
	updateResource(pRSS);
}

void ChartTree::updateResource(CREF(LPResource) pRSS)
{
	if (pRSS->isErased())
	{
		pRSS->getCtrlItem().setIcon(0, m_iconList[IT_ERASED]);
	}
	else
	{
		pRSS->getCtrlItem().setIcon(0, m_iconList[IT_SUB_ROOT_3]);
	}
}

void ChartTree::addPattern(CREF(LPPattern) pPAT)
{
	ASSERT(pPAT);
	createItem(m_rootPAT, pPAT, pPAT->getName(), IT_SUB_ROOT_2);
}

void ChartTree::addOperation(CREF(LPOperationBase) pOPR)
{
	createItem(pOPR->getPattern(), pOPR, pOPR->getName(), IT_VALUE);
}

void ChartTree::addResult(CREF(LPResult) pPMV)
{
	createItem(m_rootPMV, pPMV, pPMV->getName(), IT_VALUE);
}

void ChartTree::deleteChildren(CREF(LPChartTreeItem) pParent)
{
	QList<PTR(QTreeWidgetItem)> children = pParent->getCtrlItem().takeChildren();
	BOOST_FOREACH(PTR(QTreeWidgetItem) item, children)
	{
		pParent->getCtrlItem().removeChild(item);
	}
}

void ChartTree::clear()
{
	deleteChildren(m_rootRTP);
	deleteChildren(m_rootPAT);
	deleteChildren(m_rootPMV);
	m_root->getCtrlItem().setText(0, "Модель");
}

void ChartTree::createChart(PTR(QTreeWidgetItem) pCtrlItem) const
{
	LPSerie pSerie = getIfItemIsDrawable(pCtrlItem).object_dynamic_cast<Serie>();
	if (pSerie)
	{
		g_pTracer->addSerieToChart(pSerie);
	}
}

rbool ChartTree::activateExistingChart(PTR(QTreeWidgetItem) pCtrlItem) const
{
	LPSerie pSerie = getIfItemIsDrawable(pCtrlItem).object_dynamic_cast<Serie>();
	if (pSerie)
	{
		return pSerie->activateFirstDoc();
	}
	return false;
}

PTR(QTreeWidgetItem) ChartTree::getSelected() const
{
	QList<PTR(QTreeWidgetItem)> selected = selectedItems();
	return selected.size() == 1
		? selected.front()
		: NULL;
}

void ChartTree::onTreeWidgetItemDoubleClicked(QTreeWidgetItem* pCtrlItem, int)
{
	if (!g_pTracer->getDrawTrace())
		return;

	if (!activateExistingChart(pCtrlItem))
	{
		createChart(pCtrlItem);
	}
}

void ChartTree::onChartCreate()
{
	createChart(getSelected());
}

void ChartTree::onChartExport()
{
	if (!g_pTracer->getDrawTrace())
		return;

	LPChartTreeItem pItem = getIfItemIsDrawable(getSelected());
	if (!pItem)
		return;

	LPSerie pSerie = pItem.object_dynamic_cast<Serie>();
	ASSERT(pSerie);
	Serie::ExportData exportData = pSerie->exportData();
	if (exportData.empty())
		return;

	boost::filesystem::path path =
		boost::filesystem::path(g_pModel->getFullName().toLocal8Bit().constData()).parent_path() /
		QString("%1.csv").arg(pSerie->getTitle()).toLocal8Bit().constData();

	QString fileName = QFileDialog::getSaveFileName(
		this,
		"Сохранить",
		QString::fromLocal8Bit(path.string().c_str()),
		"csv-файл (*.csv);;Все файлы (*.*)"
	);
	if (fileName.isEmpty())
		return;

	QFile data(fileName);
	if (data.open(QIODevice::Text | QFile::WriteOnly | QFile::Truncate))
	{
		QTextStream stream(&data);
		BOOST_FOREACH(CREF(Serie::ExportData::value_type) exportItem, exportData)
		{
			stream << exportItem << endl;
		}
		data.close();
	}
}

void ChartTree::focusInEvent(QFocusEvent* pEvent)
{
	parent_type::focusInEvent(pEvent);
	activate(pEvent);
}

void ChartTree::focusOutEvent(QFocusEvent* pEvent)
{
	parent_type::focusOutEvent(pEvent);
	deactivate(pEvent);
}

void ChartTree::onUpdateActions(rbool activated)
{
	MainWindow* pMainWindow = g_pApp->getMainWndUI();
	ASSERT(pMainWindow);

	updateAction(
		pMainWindow->actChartCreate,
		activated && g_pTracer->getDrawTrace() && getIfItemIsDrawable(getSelected()),
		this, &ChartTree::onChartCreate
	);

	updateAction(
		pMainWindow->actChartExport,
		activated && g_pTracer->getDrawTrace() && getIfItemIsDrawable(getSelected()),
		this, &ChartTree::onChartExport
	);

	updateAction(
		pMainWindow->actHelpContext,
		activated,
		this, &ChartTree::onHelpContext
	);
}

void ChartTree::onHelpContext()
{
	QByteArray ba;
	ba.append("setSource qthelp://studio/doc/rdo_studio_rus/html/work_model/work_model_chart.htm\n");
	g_pApp->callQtAssistant(ba);
}

void ChartTree::mousePressEvent(QMouseEvent* pEvent)
{
	QTreeWidgetItem* item = itemAt(pEvent->pos());
	this->setCurrentItem(item);
	onUpdateActions(isActivated());
	if (pEvent->button() == Qt::LeftButton)
	{
		LPSerie pSerie = getIfItemIsDrawable(getSelected()).object_dynamic_cast<Serie>();
		if(pSerie)
		{
			doDragDrop(pSerie);
		}
		parent_type::mousePressEvent(pEvent);
	}
	else if (pEvent->button() == Qt::RightButton)
	{
		m_pPopupMenu->exec(pEvent->globalPos());
	}
}<|endoftext|>


<commit_before>//#include "../shutdown/shutdown.h"
#include "../windlg/windlg.h"
#include "../fswork/fswork.h"

#include "./header/menu_apps.h"

#include <unistd.h>
#include <stdlib.h>
#include <curses.h>

using namespace std;

string local_user;

int draw_desktop(int selected, bool open_label, bool new_draw, unsigned int maxX, unsigned int maxY) {
	unsigned x, y;
	if (new_draw) {
		for (x = 15; x < maxX; x++) mvprintw(0, x, "-");
		for (x = 0; x < maxX; x++) mvprintw(maxY - 1, x, "-");
		for (y = 0; y < maxY; y++) {mvprintw(y, 0, "|"); mvprintw(y, maxX - 1, "|");}
	}
		if (selected == 0) attron(COLOR_PAIR(1) | A_BOLD); // Белый цвет
		mvprintw(0, 1, "Menu");
		if (selected == 0) attroff(COLOR_PAIR(1) | A_BOLD);
		if (selected == 1) attron(COLOR_PAIR(1) | A_BOLD); // Белый цвет
		mvprintw(0, 6, "Edit");
		if (selected == 1) attroff(COLOR_PAIR(1) | A_BOLD);
		if (selected == 2) attron(COLOR_PAIR(1) | A_BOLD); // Белый цвет
		mvprintw(0, 11, "Exit");
		if (selected == 2) attroff(COLOR_PAIR(1) | A_BOLD);
	return 0;
}

int work_desktop() {
	unsigned int maxY, maxYb = 0, maxX, maxXb = 0;
	bool cycle = true, open_label = false, new_draw = false;
	int key_pressed, selected = 2;
	while (cycle) {
		getmaxyx(stdscr, maxY, maxX); // Получение размера терминала
		if ((maxX != maxXb) || (maxY != maxYb)) {
			new_draw = true;
			erase();
		}
		timeout(0);
		draw_desktop(selected, open_label, new_draw, maxX, maxY);
		new_draw = false;
		key_pressed = getch();
		switch (key_pressed) {
			case KEY_RIGHT: if (selected != 2) selected++; break;
			case KEY_LEFT: if (selected != 0) selected--; break;
			case '\n': switch (selected) {
							case 2: cycle = false; break;
							// default: warning_win("Ooops... It's not work...", 0); /*open_label = true;*/ break;
						}
			case 27: if (open_label) open_label = false;
					/*else shutdown_process();*/
					break;
		}
	}
	return 0;
}

int main_desktop(string user_name/*...*/) {
	local_user = user_name;
	work_desktop();
	/*vector <string> app_list;
	get_apps_list(app_list);*/
	getch();
	return 0;
}<commit_msg>Added menu algorithm<commit_after>//#include "../shutdown/shutdown.h"
#include "../windlg/windlg.h"
#include "../fswork/fswork.h"

#include "./header/menu_apps.h"

#include <unistd.h>
#include <stdlib.h>
#include <curses.h>

using namespace std;

void open_menu(vector <string>& app_list) {
	DLGSTR menu_panel = {};
	menu_panel.xpos = 1;
	menu_panel.ypos = 1;
	// menu_panel.style = 3;
	menu_panel.border_menu = true;
	bool cycle = true;
	int key;
	while (cycle) {
		menu_win(menu_panel, app_list);
		key = getch();
		switch (key) {
			case 27: cycle = false; break;
			case KEY_UP: if (menu_panel.selected != 1) menu_panel.selected--; break;
			case KEY_DOWN: if (menu_panel.selected != menu_panel.second_border) menu_panel.selected++; break;
			/*case '\n': switch (menu_panel.selected) {
							case 1: abaut_fm(); break;
							case 2: return; break;
						} break;*/
		}
	}
	return;
}

int draw_desktop(int selected, bool open_label, bool new_draw, unsigned int maxX, unsigned int maxY) {
	unsigned x, y;
	if (new_draw) {
		for (x = 0; x < maxX; x++) {
			mvprintw(maxY - 1, x, "-");
			mvprintw(0, x, "-");
		}
		for (y = 0; y < maxY; y++) {mvprintw(y, 0, "|"); mvprintw(y, maxX - 1, "|");}
	}
		if (selected == 0) attron(COLOR_PAIR(1) | A_BOLD); // Белый цвет
		mvprintw(0, 1, "Menu");
		if (selected == 0) attroff(COLOR_PAIR(1) | A_BOLD);
		if (selected == 1) attron(COLOR_PAIR(1) | A_BOLD); // Белый цвет
		mvprintw(0, 6, "Edit");
		if (selected == 1) attroff(COLOR_PAIR(1) | A_BOLD);
		if (selected == 2) attron(COLOR_PAIR(1) | A_BOLD); // Белый цвет
		mvprintw(0, 11, "Exit");
		if (selected == 2) attroff(COLOR_PAIR(1) | A_BOLD);
	return 0;
}

int work_desktop(vector <string> app_list, string user_name) {
	unsigned int maxY, maxYb = 0, maxX, maxXb = 0;
	bool cycle = true, open_label = false, new_draw = false;
	int key_pressed, selected = 2;
	while (cycle) {
		getmaxyx(stdscr, maxY, maxX); // Получение размера терминала
		if ((maxX != maxXb) || (maxY != maxYb)) {
			new_draw = true;
			erase();
		}
		timeout(0);
		draw_desktop(selected, open_label, new_draw, maxX, maxY);
		new_draw = false;
		key_pressed = getch();
		switch (key_pressed) {
			case KEY_RIGHT: if (selected != 2) selected++; break;
			case KEY_LEFT: if (selected != 0) selected--; break;
			case '\n': switch (selected) {
							case 0: open_menu(app_list); break;
							case 2: cycle = false; break;
						}
			case 27: if (open_label) open_label = false;
					/*else shutdown_process();*/
					break;
		}
	}
	return 0;
}

int main_desktop(string user_name/*...*/) {
	vector <string> app_list;
	get_apps_list(app_list);
	work_desktop(app_list, user_name);
	return 0;
}<|endoftext|>


<commit_before><commit_msg>core: scene: session: extend debug message with participantType<commit_after><|endoftext|>


<commit_before>#include <chrono>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <vector>
#include <random>
#include <parallel_hashmap/phmap.h>

// -------------------------------------------------------------------
// -------------------------------------------------------------------
class Timer
{
public:
    Timer(std::string name) : _name(name), _start(std::chrono::high_resolution_clock::now()) {}

    ~Timer()
    {
        std::chrono::duration<float> elapsed_seconds = std::chrono::high_resolution_clock::now() - _start;
        printf("%s: %.3fs\n", _name.c_str(), elapsed_seconds.count());
    }

private:
    std::string _name;
    std::chrono::high_resolution_clock::time_point _start;
};

// --------------------------------------------------------------------------
//  from: https://github.com/preshing/RandomSequence
// --------------------------------------------------------------------------
class RSU
{
private:
    uint32_t m_index;
    uint32_t m_intermediateOffset;

    static uint32_t permuteQPR(uint32_t x)
    {
        static const uint32_t prime = 4294967291u;
        if (x >= prime)
            return x;  // The 5 integers out of range are mapped to themselves.
        uint32_t residue = ((unsigned long long) x * x) % prime;
        return (x <= prime / 2) ? residue : prime - residue;
    }

public:
    RSU(uint32_t seedBase, uint32_t seedOffset)
    {
        m_index = permuteQPR(permuteQPR(seedBase) + 0x682f0161);
        m_intermediateOffset = permuteQPR(permuteQPR(seedOffset) + 0x46790905);
    }

    uint32_t next()
    {
        return permuteQPR((permuteQPR(m_index++) + m_intermediateOffset) ^ 0x5bf03635);
    }
};

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
template<class Set, size_t N>
void test(const char *name, std::function<void (std::vector<uint64_t> &)> perturb)
{
    Set s;

    unsigned int seed = 76687;
	RSU rsu(seed, seed + 1);

    for (uint32_t i=0; i<N; ++i)
        s.insert(rsu.next());

    std::vector<uint64_t> order(s.begin(), s.end());
    perturb(order);
    order.resize(N/4);

    Timer t(name);
    Set c(order.begin(), order.end());
}

template <class T, size_t N>
using pset = phmap::parallel_flat_hash_set<T,
                                           phmap::container_internal::hash_default_hash<T>,
                                           phmap::container_internal::hash_default_eq<T>,
                                           phmap::container_internal::Allocator<T>, // alias for std::allocator
                                           N>;

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
int main()
{
    auto shuffle = [](std::vector<uint64_t> &order) {
        std::random_device rd;
        std::mt19937 g(rd());
        std::shuffle(order.begin(), order.end(), g);
    };

    auto noop = [](std::vector<uint64_t> &) {};

    constexpr uint32_t num_keys = 10000000;
    using T = uint64_t;

    test<phmap::flat_hash_set<T>, num_keys>("flat_hash_set ordered ", noop);

    test<phmap::flat_hash_set<T>, num_keys>("flat_hash_set shuffled", shuffle);

    test<pset<T, 4>, num_keys>("parallel (16) ordered ", noop);

    test<pset<T, 4>, num_keys>("parallel (16) shuffled", shuffle);

    test<pset<T, 6>, num_keys>("parallel (64) ordered ", noop);

    test<pset<T, 6>, num_keys>("parallel (64) shuffled", shuffle);

    test<pset<T, 8>, num_keys>("parallel (128) ordered ", noop);

    test<pset<T, 8>, num_keys>("parallel (128) shuffled", shuffle);
}

<commit_msg>fix typo incorrect number of submaps<commit_after>#include <chrono>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <vector>
#include <random>
#include <parallel_hashmap/phmap.h>

// -------------------------------------------------------------------
// -------------------------------------------------------------------
class Timer
{
public:
    Timer(std::string name) : _name(name), _start(std::chrono::high_resolution_clock::now()) {}

    ~Timer()
    {
        std::chrono::duration<float> elapsed_seconds = std::chrono::high_resolution_clock::now() - _start;
        printf("%s: %.3fs\n", _name.c_str(), elapsed_seconds.count());
    }

private:
    std::string _name;
    std::chrono::high_resolution_clock::time_point _start;
};

// --------------------------------------------------------------------------
//  from: https://github.com/preshing/RandomSequence
// --------------------------------------------------------------------------
class RSU
{
private:
    uint32_t m_index;
    uint32_t m_intermediateOffset;

    static uint32_t permuteQPR(uint32_t x)
    {
        static const uint32_t prime = 4294967291u;
        if (x >= prime)
            return x;  // The 5 integers out of range are mapped to themselves.
        uint32_t residue = ((unsigned long long) x * x) % prime;
        return (x <= prime / 2) ? residue : prime - residue;
    }

public:
    RSU(uint32_t seedBase, uint32_t seedOffset)
    {
        m_index = permuteQPR(permuteQPR(seedBase) + 0x682f0161);
        m_intermediateOffset = permuteQPR(permuteQPR(seedOffset) + 0x46790905);
    }

    uint32_t next()
    {
        return permuteQPR((permuteQPR(m_index++) + m_intermediateOffset) ^ 0x5bf03635);
    }
};

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
template<class Set, size_t N>
void test(const char *name, std::function<void (std::vector<uint64_t> &)> perturb)
{
    Set s;

    unsigned int seed = 76687;
	RSU rsu(seed, seed + 1);

    for (uint32_t i=0; i<N; ++i)
        s.insert(rsu.next());

    std::vector<uint64_t> order(s.begin(), s.end());
    perturb(order);
    order.resize(N/4);

    Timer t(name);
    Set c(order.begin(), order.end());
}

template <class T, size_t N>
using pset = phmap::parallel_flat_hash_set<T,
                                           phmap::container_internal::hash_default_hash<T>,
                                           phmap::container_internal::hash_default_eq<T>,
                                           phmap::container_internal::Allocator<T>, // alias for std::allocator
                                           N>;

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
int main()
{
    auto shuffle = [](std::vector<uint64_t> &order) {
        std::random_device rd;
        std::mt19937 g(rd());
        std::shuffle(order.begin(), order.end(), g);
    };

    auto noop = [](std::vector<uint64_t> &) {};

    constexpr uint32_t num_keys = 10000000;
    using T = uint64_t;

    test<phmap::flat_hash_set<T>, num_keys>("flat_hash_set ordered ", noop);

    test<phmap::flat_hash_set<T>, num_keys>("flat_hash_set shuffled", shuffle);

    test<pset<T, 4>, num_keys>("parallel (16) ordered ", noop);

    test<pset<T, 4>, num_keys>("parallel (16) shuffled", shuffle);

    test<pset<T, 6>, num_keys>("parallel (64) ordered ", noop);

    test<pset<T, 6>, num_keys>("parallel (64) shuffled", shuffle);

    test<pset<T, 8>, num_keys>("parallel (256) ordered ", noop);

    test<pset<T, 8>, num_keys>("parallel (256) shuffled", shuffle);
}

<|endoftext|>


<commit_before>#include "region.h"
#include "config.h"
#include "util.h"
#include "binomial.h"
#include <algorithm>

using namespace std;

region::region(int32_t _lpos, int32_t _rpos, int _ltype, int _rtype, const split_interval_map *_mmap, const split_interval_map *_imap)
	:lpos(_lpos), rpos(_rpos), mmap(_mmap), imap(_imap), ltype(_ltype), rtype(_rtype)
{

	build_join_interval_map();
	smooth_join_interval_map();
	build_partial_exons();
}

region::~region()
{}

int region::build_join_interval_map()
{
	jmap.clear();

	SIMI lit, rit;
	tie(lit, rit) = locate_boundary_iterators(*mmap, lpos, rpos);
	if(lit == mmap->end() || rit == mmap->end()) return 0;

	SIMI it = lit;
	while(true)
	{
		// TODO
		//if(it->second >= 2)
		jmap += make_pair(it->first, 1);
		if(it == rit) break;
		it++;
	}

	for(JIMI it = jmap.begin(); it != jmap.end(); it++)
	{
		assert(it->second == 1);
	}

	return 0;
}

int region::smooth_join_interval_map()
{
	int32_t gap = min_subregion_gap;

	/*
	bool b1 = false, b2 = false;
	if(ltype == START_BOUNDARY) b1 = true;
	if(ltype == RIGHT_SPLICE) b1 = true;
	if(rtype == END_BOUNDARY) b2 = true;
	if(rtype == LEFT_SPLICE) b2 = true;
	if(b1 == true && b2 == true) gap = 2 * min_subregion_gap;
	*/

	vector<PI32> v;
	int32_t p = lpos;
	for(JIMI it = jmap.begin(); it != jmap.end(); it++)
	{
		int32_t p1 = lower(it->first);
		int32_t p2 = upper(it->first);
		assert(p1 >= p);
		assert(p2 > p1);
		if(p1 - p <= gap) v.push_back(PI32(p, p1));
		p = p2;
	}

	if(p < rpos && rpos - p <= gap) v.push_back(PI32(p, rpos));

	for(int i = 0; i < v.size(); i++)
	{
		jmap += make_pair(ROI(v[i].first, v[i].second), 1);
	}

	for(JIMI it = jmap.begin(); it != jmap.end(); it++)
	{
		assert(it->second == 1);
	}

	return 0;
}

bool region::empty_subregion(int32_t p1, int32_t p2)
{
	assert(p1 < p2);
	assert(p1 >= lpos && p2 <= rpos);

	//printf(" region = [%d, %d), subregion [%d, %d), length = %d\n", lpos, rpos, p1, p2, p2 - p1);
	if(p2 - p1 < min_subregion_length) return true;

	SIMI it1, it2;
	tie(it1, it2) = locate_boundary_iterators(*mmap, p1, p2);
	if(it1 == mmap->end() || it2 == mmap->end()) return true;

	int32_t sum = compute_sum_overlap(*mmap, it1, it2);
	double ratio = sum * 1.0 / (p2 - p1);
	//printf(" region = [%d, %d), subregion [%d, %d), overlap = %.2lf\n", lpos, rpos, p1, p2, ratio);
	if(ratio < min_subregion_overlap) return true;

	int32_t indel = 0;
	SIMI jit1 = imap->lower_bound(ROI(p1, p1 + 1));
	SIMI jit2 = imap->upper_bound(ROI(p2 - 1, p2));
	for(SIMI jit = jit1; jit != jit2; jit++) indel += jit->second;

	//printf(" region = [%d, %d), subregion [%d, %d), indel = %d\n", lpos, rpos, p1, p2, indel);
	if(indel * 1.0 / (p2 - p1) > max_indel_ratio) return true;

	return false;
}

int32_t region::identify_boundary(bool tag)
{
	if(lower(jmap.begin()->first) != lpos || upper(jmap.begin()->first) != rpos) return -1;

	typedef pair<int32_t, int64_t> PI64;
	vector<PI64> v;
	SIMI lit, rit;
	tie(lit, rit) = locate_boundary_iterators(*mmap, lpos, rpos);
	if(lit == mmap->end() || rit == mmap->end()) return -1;

	v.push_back(PPI(lpos, 0));
	for(SIMI it = lit; it != rit; it++)
	{
		int32_t s = lower(it->first);
		int32_t t = upper(it->first);
		int k = v.size() - 1;
		int64_t x = v[k].second + (t - s) * it->second;
		v.push_back(PI64(t, x));
	}

	int64_t sum = v[v.size() - 1].second;

	int32_t pos = -1;
	uint32_t score = 0;
	double ave1 = 0, ave2 = 0;
	for(int i = 0; i < v.size(); i++)
	{
		int32_t p = v[i].first;
		int32_t len1 = p - lpos;
		int32_t len2 = rpos - p;

		if(len1 < min_boundary_length) continue;
		if(len2 < min_boundary_length) continue;

		int n1 = v[i].second / average_read_length + 5;
		int n2 = (sum - v[i].second) / average_read_length + 5;

		uint32_t s = 0;
		if(tag == true)
		{
			double pr = len1 * 1.0 / (len1 + len2);
			s = compute_binomial_score(n1 + n2, pr, n1);
		}
		else
		{
			double pr = len2 * 1.0 / (len1 + len2);
			s = compute_binomial_score(n1 + n2, pr, n2);
		}

		if(score > s) continue;

		score = s;
		pos = p;
		ave1 = v[i].second * 1.0 / len1;
		ave2 = (sum - v[i].second) * 1.0 / len2;
	}

	if(pos == -1) return -1;

	int32_t p = lpos;
	double var1 = 0, var2 = 0;
	for(SIMI it = lit; it != rit; it++)
	{
		int32_t s = lower(it->first);
		int32_t t = upper(it->first);
		assert(s >= p);

		if(t <= pos)
		{
			var1 += (s - p) * ave1 * ave1;
			var1 += (t - s) * (it->second - ave1) * (it->second - ave1);
		}
		else
		{
			var2 += (s - p) * ave2 * ave2;
			var2 += (t - s) * (it->second - ave2) * (it->second - ave2);
		}
		p = t;
	}
	var2 += (rpos - p) * ave2 * ave2;

	int len1 = pos - lpos;
	int len2 = rpos - pos;
	double dev1 = sqrt(var1 / len1);
	double dev2 = sqrt(var2 / len2);

	/*
	printf("%s-position: region = %d-%d, score = %d, pos = %d, len = (%d, %d) ave = (%.1lf, %.1lf), dev = (%.1lf, %.1lf)\n",
			tag ? "end" : "start", lpos, rpos, score, pos, len1, len2, ave1, ave2, dev1, dev2);
	*/

	if(score < min_boundary_score) return -1;
	if(tag == true && ave1 < ave2 + min_boundary_sigma * dev2) return -1;
	if(tag == false && ave2 < ave1 + min_boundary_sigma * dev1) return -1;

	return pos;
}

int region::build_partial_exons()
{
	pexons.clear();

	if(jmap.size() == 0) return 0;

	//printf("size = %lu, size2 = %lu, [%d, %d), [%d, %d)\n", jmap.size(), distance(jmap.begin(), jmap.end()), lower(jmap.begin()->first), upper(jmap.begin()->first), lpos, rpos);

	if(lower(jmap.begin()->first) == lpos && upper(jmap.begin()->first) == rpos)
	{
		if(ltype == START_BOUNDARY || rtype == END_BOUNDARY)
		{
			partial_exon pe(lpos, rpos, ltype, rtype);
			evaluate_rectangle(*mmap, pe.lpos, pe.rpos, pe.ave, pe.dev);
			pexons.push_back(pe);
			return 0;
		}

		int32_t p1 = identify_boundary(true);
		int32_t p2 = identify_boundary(false);

		if(p1 < 0 && p2 < 0)
		{
			partial_exon pe(lpos, rpos, ltype, rtype);
			evaluate_rectangle(*mmap, pe.lpos, pe.rpos, pe.ave, pe.dev);
			pexons.push_back(pe);
			return 0;
		}
		else if(p1 > 0)
		{
			partial_exon pe1(lpos, p1, ltype, END_BOUNDARY);
			partial_exon pe2(p1, rpos, MIDDLE_CUT, rtype);
			evaluate_rectangle(*mmap, pe1.lpos, pe1.rpos, pe1.ave, pe1.dev);
			evaluate_rectangle(*mmap, pe2.lpos, pe2.rpos, pe2.ave, pe2.dev);
			pexons.push_back(pe1);
			pexons.push_back(pe2);
		}
		else if(p2 > 0)
		{
			partial_exon pe1(lpos, p2, ltype, MIDDLE_CUT);
			partial_exon pe2(p2, rpos, START_BOUNDARY, rtype);
			evaluate_rectangle(*mmap, pe1.lpos, pe1.rpos, pe1.ave, pe1.dev);
			evaluate_rectangle(*mmap, pe2.lpos, pe2.rpos, pe2.ave, pe2.dev);
			pexons.push_back(pe1);
			pexons.push_back(pe2);
		}
		return 0;
	}

	if(ltype == RIGHT_SPLICE && jmap.find(ROI(lpos, lpos + 1)) == jmap.end())
	{
		partial_exon pe(lpos, lpos + 1, ltype, END_BOUNDARY);
		pe.ave = 1.0;
		pe.dev = 1.0;
		pexons.push_back(pe);
	}

	for(JIMI it = jmap.begin(); it != jmap.end(); it++)
	{
		int32_t p1 = lower(it->first);
		int32_t p2 = upper(it->first);
		assert(p1 < p2);

		bool b = empty_subregion(p1, p2);

		//printf(" subregion [%d, %d), empty = %c\n", p1, p2, b ? 'T' : 'F');

		if(p1 == lpos && ltype == RIGHT_SPLICE) b = false;
		if(p2 == rpos && rtype == LEFT_SPLICE) b = false;

		if(b == true) continue;

		int lt = (p1 == lpos) ? ltype : START_BOUNDARY;
		int rt = (p2 == rpos) ? rtype : END_BOUNDARY;

		partial_exon pe(p1, p2, lt, rt);
		evaluate_rectangle(*mmap, pe.lpos, pe.rpos, pe.ave, pe.dev);
		pexons.push_back(pe);
	}

	if(rtype == LEFT_SPLICE && jmap.find(ROI(rpos - 1, rpos)) == jmap.end())
	{
		partial_exon pe(rpos - 1, rpos, START_BOUNDARY, rtype);
		pe.ave = 1.0;
		pe.dev = 1.0;
		pexons.push_back(pe);
	}

	return 0;
}

bool region::left_inclusive()
{
	if(pexons.size() == 0) return false;
	if(pexons[0].lpos == lpos) return true;
	else return false;
}

bool region::right_inclusive()
{
	if(pexons.size() == 0) return false;
	if(pexons[pexons.size() - 1].rpos == rpos) return true;
	else return false;
}

int region::print(int index) const
{
	int32_t lc = compute_overlap(*mmap, lpos);
	int32_t rc = compute_overlap(*mmap, rpos - 1);
	printf("region %d: partial-exons = %lu, type = (%d, %d), pos = [%d, %d), boundary coverage = (%d, %d)\n",
			index, pexons.size(), ltype, rtype, lpos, rpos, lc, rc);

	/*
	for(JIMI it = jmap.begin(); it != jmap.end(); it++)
	{
		printf(" [%d, %d) -> %d\n", lower(it->first), upper(it->first), it->second);
	}
	*/

	return 0;
}
<commit_msg>test: print regions as a whole<commit_after>#include "region.h"
#include "config.h"
#include "util.h"
#include "binomial.h"
#include <algorithm>

using namespace std;

region::region(int32_t _lpos, int32_t _rpos, int _ltype, int _rtype, const split_interval_map *_mmap, const split_interval_map *_imap)
	:lpos(_lpos), rpos(_rpos), mmap(_mmap), imap(_imap), ltype(_ltype), rtype(_rtype)
{

	build_join_interval_map();
	smooth_join_interval_map();
	build_partial_exons();
}

region::~region()
{}

int region::build_join_interval_map()
{
	jmap.clear();

	SIMI lit, rit;
	tie(lit, rit) = locate_boundary_iterators(*mmap, lpos, rpos);
	if(lit == mmap->end() || rit == mmap->end()) return 0;

	SIMI it = lit;
	while(true)
	{
		// TODO
		//if(it->second >= 2)
		jmap += make_pair(it->first, 1);
		if(it == rit) break;
		it++;
	}

	for(JIMI it = jmap.begin(); it != jmap.end(); it++)
	{
		assert(it->second == 1);
	}

	return 0;
}

int region::smooth_join_interval_map()
{
	int32_t gap = min_subregion_gap;

	/*
	bool b1 = false, b2 = false;
	if(ltype == START_BOUNDARY) b1 = true;
	if(ltype == RIGHT_SPLICE) b1 = true;
	if(rtype == END_BOUNDARY) b2 = true;
	if(rtype == LEFT_SPLICE) b2 = true;
	if(b1 == true && b2 == true) gap = 2 * min_subregion_gap;
	*/

	vector<PI32> v;
	int32_t p = lpos;
	for(JIMI it = jmap.begin(); it != jmap.end(); it++)
	{
		int32_t p1 = lower(it->first);
		int32_t p2 = upper(it->first);
		assert(p1 >= p);
		assert(p2 > p1);
		if(p1 - p <= gap) v.push_back(PI32(p, p1));
		p = p2;
	}

	if(p < rpos && rpos - p <= gap) v.push_back(PI32(p, rpos));

	for(int i = 0; i < v.size(); i++)
	{
		jmap += make_pair(ROI(v[i].first, v[i].second), 1);
	}

	for(JIMI it = jmap.begin(); it != jmap.end(); it++)
	{
		assert(it->second == 1);
	}

	return 0;
}

bool region::empty_subregion(int32_t p1, int32_t p2)
{
	assert(p1 < p2);
	assert(p1 >= lpos && p2 <= rpos);

	//printf(" region = [%d, %d), subregion [%d, %d), length = %d\n", lpos, rpos, p1, p2, p2 - p1);
	if(p2 - p1 < min_subregion_length) return true;

	SIMI it1, it2;
	tie(it1, it2) = locate_boundary_iterators(*mmap, p1, p2);
	if(it1 == mmap->end() || it2 == mmap->end()) return true;

	int32_t sum = compute_sum_overlap(*mmap, it1, it2);
	double ratio = sum * 1.0 / (p2 - p1);
	//printf(" region = [%d, %d), subregion [%d, %d), overlap = %.2lf\n", lpos, rpos, p1, p2, ratio);
	if(ratio < min_subregion_overlap) return true;

	int32_t indel = 0;
	SIMI jit1 = imap->lower_bound(ROI(p1, p1 + 1));
	SIMI jit2 = imap->upper_bound(ROI(p2 - 1, p2));
	for(SIMI jit = jit1; jit != jit2; jit++) indel += jit->second;

	//printf(" region = [%d, %d), subregion [%d, %d), indel = %d\n", lpos, rpos, p1, p2, indel);
	if(indel * 1.0 / (p2 - p1) > max_indel_ratio) return true;

	return false;
}

int32_t region::identify_boundary(bool tag)
{
	if(lower(jmap.begin()->first) != lpos || upper(jmap.begin()->first) != rpos) return -1;

	typedef pair<int32_t, int64_t> PI64;
	vector<PI64> v;
	SIMI lit, rit;
	tie(lit, rit) = locate_boundary_iterators(*mmap, lpos, rpos);
	if(lit == mmap->end() || rit == mmap->end()) return -1;

	v.push_back(PPI(lpos, 0));
	for(SIMI it = lit; it != rit; it++)
	{
		int32_t s = lower(it->first);
		int32_t t = upper(it->first);
		int k = v.size() - 1;
		int64_t x = v[k].second + (t - s) * it->second;
		v.push_back(PI64(t, x));
	}

	int64_t sum = v[v.size() - 1].second;

	int32_t pos = -1;
	uint32_t score = 0;
	double ave1 = 0, ave2 = 0;
	for(int i = 0; i < v.size(); i++)
	{
		int32_t p = v[i].first;
		int32_t len1 = p - lpos;
		int32_t len2 = rpos - p;

		if(len1 < min_boundary_length) continue;
		if(len2 < min_boundary_length) continue;

		int n1 = v[i].second / average_read_length + 5;
		int n2 = (sum - v[i].second) / average_read_length + 5;

		uint32_t s = 0;
		if(tag == true)
		{
			double pr = len1 * 1.0 / (len1 + len2);
			s = compute_binomial_score(n1 + n2, pr, n1);
		}
		else
		{
			double pr = len2 * 1.0 / (len1 + len2);
			s = compute_binomial_score(n1 + n2, pr, n2);
		}

		if(score > s) continue;

		score = s;
		pos = p;
		ave1 = v[i].second * 1.0 / len1;
		ave2 = (sum - v[i].second) * 1.0 / len2;
	}

	if(pos == -1) return -1;

	int32_t p = lpos;
	double var1 = 0, var2 = 0;
	for(SIMI it = lit; it != rit; it++)
	{
		int32_t s = lower(it->first);
		int32_t t = upper(it->first);
		assert(s >= p);

		if(t <= pos)
		{
			var1 += (s - p) * ave1 * ave1;
			var1 += (t - s) * (it->second - ave1) * (it->second - ave1);
		}
		else
		{
			var2 += (s - p) * ave2 * ave2;
			var2 += (t - s) * (it->second - ave2) * (it->second - ave2);
		}
		p = t;
	}
	var2 += (rpos - p) * ave2 * ave2;

	int len1 = pos - lpos;
	int len2 = rpos - pos;
	double dev1 = sqrt(var1 / len1);
	double dev2 = sqrt(var2 / len2);

	/*
	printf("%s-position: region = %d-%d, score = %d, pos = %d, len = (%d, %d) ave = (%.1lf, %.1lf), dev = (%.1lf, %.1lf)\n",
			tag ? "end" : "start", lpos, rpos, score, pos, len1, len2, ave1, ave2, dev1, dev2);
	*/

	if(score < min_boundary_score) return -1;
	if(tag == true && ave1 < ave2 + min_boundary_sigma * dev2) return -1;
	if(tag == false && ave2 < ave1 + min_boundary_sigma * dev1) return -1;

	return pos;
}

int region::build_partial_exons()
{
	pexons.clear();

	if(jmap.size() == 0) return 0;

	//printf("size = %lu, size2 = %lu, [%d, %d), [%d, %d)\n", jmap.size(), distance(jmap.begin(), jmap.end()), lower(jmap.begin()->first), upper(jmap.begin()->first), lpos, rpos);

	if(lower(jmap.begin()->first) == lpos && upper(jmap.begin()->first) == rpos)
	{
		if(ltype == START_BOUNDARY || rtype == END_BOUNDARY)
		{
			partial_exon pe(lpos, rpos, ltype, rtype);
			evaluate_rectangle(*mmap, pe.lpos, pe.rpos, pe.ave, pe.dev);
			pexons.push_back(pe);

			printf("whole region: ");
			pe.print(9);

			return 0;
		}

		int32_t p1 = identify_boundary(true);
		int32_t p2 = identify_boundary(false);

		if(p1 < 0 && p2 < 0)
		{
			partial_exon pe(lpos, rpos, ltype, rtype);
			evaluate_rectangle(*mmap, pe.lpos, pe.rpos, pe.ave, pe.dev);
			pexons.push_back(pe);
			return 0;
		}
		else if(p1 > 0)
		{
			partial_exon pe1(lpos, p1, ltype, END_BOUNDARY);
			partial_exon pe2(p1, rpos, MIDDLE_CUT, rtype);
			evaluate_rectangle(*mmap, pe1.lpos, pe1.rpos, pe1.ave, pe1.dev);
			evaluate_rectangle(*mmap, pe2.lpos, pe2.rpos, pe2.ave, pe2.dev);
			pexons.push_back(pe1);
			pexons.push_back(pe2);
		}
		else if(p2 > 0)
		{
			partial_exon pe1(lpos, p2, ltype, MIDDLE_CUT);
			partial_exon pe2(p2, rpos, START_BOUNDARY, rtype);
			evaluate_rectangle(*mmap, pe1.lpos, pe1.rpos, pe1.ave, pe1.dev);
			evaluate_rectangle(*mmap, pe2.lpos, pe2.rpos, pe2.ave, pe2.dev);
			pexons.push_back(pe1);
			pexons.push_back(pe2);
		}
		return 0;
	}

	if(ltype == RIGHT_SPLICE && jmap.find(ROI(lpos, lpos + 1)) == jmap.end())
	{
		partial_exon pe(lpos, lpos + 1, ltype, END_BOUNDARY);
		pe.ave = 1.0;
		pe.dev = 1.0;
		pexons.push_back(pe);
	}

	for(JIMI it = jmap.begin(); it != jmap.end(); it++)
	{
		int32_t p1 = lower(it->first);
		int32_t p2 = upper(it->first);
		assert(p1 < p2);

		bool b = empty_subregion(p1, p2);

		//printf(" subregion [%d, %d), empty = %c\n", p1, p2, b ? 'T' : 'F');

		if(p1 == lpos && ltype == RIGHT_SPLICE) b = false;
		if(p2 == rpos && rtype == LEFT_SPLICE) b = false;

		if(b == true) continue;

		int lt = (p1 == lpos) ? ltype : START_BOUNDARY;
		int rt = (p2 == rpos) ? rtype : END_BOUNDARY;

		partial_exon pe(p1, p2, lt, rt);
		evaluate_rectangle(*mmap, pe.lpos, pe.rpos, pe.ave, pe.dev);
		pexons.push_back(pe);
	}

	if(rtype == LEFT_SPLICE && jmap.find(ROI(rpos - 1, rpos)) == jmap.end())
	{
		partial_exon pe(rpos - 1, rpos, START_BOUNDARY, rtype);
		pe.ave = 1.0;
		pe.dev = 1.0;
		pexons.push_back(pe);
	}

	return 0;
}

bool region::left_inclusive()
{
	if(pexons.size() == 0) return false;
	if(pexons[0].lpos == lpos) return true;
	else return false;
}

bool region::right_inclusive()
{
	if(pexons.size() == 0) return false;
	if(pexons[pexons.size() - 1].rpos == rpos) return true;
	else return false;
}

int region::print(int index) const
{
	int32_t lc = compute_overlap(*mmap, lpos);
	int32_t rc = compute_overlap(*mmap, rpos - 1);
	printf("region %d: partial-exons = %lu, type = (%d, %d), pos = [%d, %d), boundary coverage = (%d, %d)\n",
			index, pexons.size(), ltype, rtype, lpos, rpos, lc, rc);

	/*
	for(JIMI it = jmap.begin(); it != jmap.end(); it++)
	{
		printf(" [%d, %d) -> %d\n", lower(it->first), upper(it->first), it->second);
	}
	*/

	return 0;
}
<|endoftext|>