<commit_before>/*
Copyright (c) 2014-2021 AscEmu Team <http://www.ascemu.org>
This file is released under the MIT license. See README-MIT for more information.
*/

#include "MoveSplineInit.h"
#include "../world/Units/Creatures/Creature.h"
#include "MoveSpline.h"
#include "MovementPacketBuilder.h"
#include "../world/Units/Unit.h"
#include "../world/Objects/Transporter.h"
#include "WorldPacket.h"

namespace MovementNew
{
    UnitSpeedType SelectSpeedType(uint32 moveFlags)
    {
        if (moveFlags & MOVEFLAG_FLYING)
        {
            if (moveFlags & MOVEFLAG_MOVE_BACKWARD )
                return TYPE_FLY_BACK;
            else
                return TYPE_FLY;
        }
        else if (moveFlags & MOVEFLAG_SWIMMING)
        {
            if (moveFlags & MOVEFLAG_MOVE_BACKWARD)
                return TYPE_SWIM_BACK;
            else
                return TYPE_SWIM;
        }
        else if (moveFlags & MOVEFLAG_WALK)
        {
            return TYPE_WALK;
        }
        else if (moveFlags & MOVEFLAG_MOVE_BACKWARD)
            return TYPE_RUN_BACK;

        // Flying creatures use MOVEFLAG_CAN_FLY or MOVEFLAG_DISABLE_GRAVITY
        // Run speed is their default flight speed.
        return TYPE_RUN;
    }

    int32 MoveSplineInit::Launch()
    {
        MoveSpline& move_spline = *unit->movespline;

        // Elevators also use MOVEFLAG_TRANSPORT but we do not keep track of their position changes
        bool transport = unit->hasUnitMovementFlag(MOVEFLAG_TRANSPORT) && unit->GetTransport();
        Location real_position;
        // there is a big chance that current position is unknown if current state is not finalized, need compute it
        // this also allows CalculatePath spline position and update map position in much greater intervals
        // Don't compute for transport movement if the unit is in a motion between two transports
        if (!move_spline.Finalized() && move_spline.onTransport == transport)
            real_position = move_spline.ComputePosition();
        else
        {
            LocationVector const* pos;
            if (!transport)
                pos = &unit->GetPosition();
            else
                pos = &unit->movement_info.transport_position;

            real_position.x = pos->getPositionX();
            real_position.y = pos->getPositionY();
            real_position.z = pos->getPositionZ();
            real_position.orientation = unit->GetOrientation();
        }

        // should i do the things that user should do? - no.
        if (args.path.empty())
            return 0;

        // corrent first vertex
        args.path[0] = real_position;
        args.initialOrientation = real_position.orientation;
        args.flags.enter_cycle = args.flags.cyclic;
        move_spline.onTransport = transport;

        uint32 moveFlags = unit->obj_movement_info.getMovementFlags();

#if VERSION_STRING <= WotLK
        moveFlags |= MOVEFLAG_SPLINE_ENABLED;
#endif

        if (!args.flags.backward)
            moveFlags = (moveFlags & ~(MOVEFLAG_MOVE_BACKWARD)) | MOVEFLAG_MOVE_FORWARD;
        else
            moveFlags = (moveFlags & ~(MOVEFLAG_MOVE_FORWARD)) | MOVEFLAG_MOVE_BACKWARD;

        if (moveFlags & MOVEFLAG_ROOTED)
            moveFlags &= ~MOVEFLAG_MOVING_MASK;

        if (!args.HasVelocity)
        {
            // If spline is initialized with SetWalk method it only means we need to select
            // walk move speed for it but not add walk flag to unit
            uint32 moveFlagsForSpeed = moveFlags;
            if (args.walk)
                moveFlagsForSpeed |= MOVEFLAG_WALK;
            else
                moveFlagsForSpeed &= ~MOVEFLAG_WALK;

            args.velocity = unit->getSpeedRate(SelectSpeedType(moveFlagsForSpeed), true);
            if (Creature* creature = static_cast<Creature*>(unit))
                if (creature->GetAIInterface()->hasCalledForHelp())
                    args.velocity *= 0.66f;
        }

        // limit the speed in the same way the client does
        args.velocity = std::min(args.velocity, args.flags.catmullrom || args.flags.flying ? 50.0f : std::max(28.0f, unit->getSpeedRate(TYPE_RUN,  true) * 4.0f));

        if (!args.Validate(unit))
            return 0;

        unit->obj_movement_info.flags = moveFlags;
        move_spline.Initialize(args);

        WorldPacket data(SMSG_MONSTER_MOVE, 64);
        data << WoWGuid(unit->getGuid());
        if (transport)
        {
            data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT);
            data << WoWGuid(unit->getTransGuid());
#if VERSION_STRING >= WotLK
            data << int8(unit->GetTransSeat());
#endif
        }

        PacketBuilder::WriteMonsterMove(move_spline, data);
        unit->SendMessageToSet(&data, true);

        return move_spline.Duration();
    }

    void MoveSplineInit::Stop()
    {
        MoveSpline& move_spline = *unit->movespline;

        // No need to stop if we are not moving
        if (move_spline.Finalized())
            return;

        bool transport = unit->hasUnitMovementFlag(MOVEFLAG_TRANSPORT) && unit->getTransGuid();
        Location loc;
        if (move_spline.onTransport == transport)
            loc = move_spline.ComputePosition();
        else
        {
            LocationVector const* pos;
            if (!transport)
                pos = &unit->GetPosition();
            else
                pos = &unit->obj_movement_info.transport_position;

            loc.x = pos->getPositionX();
            loc.y = pos->getPositionY();
            loc.z = pos->getPositionZ();
            loc.orientation = unit->GetOrientation();
        }

        args.flags = MoveSplineFlag::Done;

#if VERSION_STRING <= WotLK
        unit->obj_movement_info.removeMovementFlag(MOVEFLAG_SPLINE_FORWARD_ENABLED);
#endif

#if VERSION_STRING >= Cata
        unit->obj_movement_info.removeMovementFlag(MOVEFLAG_MOVE_FORWARD);
#endif

        move_spline.onTransport = transport;
        move_spline.Initialize(args);

        WorldPacket data(SMSG_MONSTER_MOVE, 64);
        data << WoWGuid(unit->getGuid());
        if (transport)
        {
            data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT);
            data << WoWGuid(unit->getTransGuid());
#if VERSION_STRING >= WotLK
            data << int8(unit->GetTransSeat());
#endif
        }

        PacketBuilder::WriteStopMovement(loc, args.splineId, data);
        unit->SendMessageToSet(&data, true);
    }

    MoveSplineInit::MoveSplineInit(Unit* m) : unit(m)
    {
        args.splineId = splineIdGen.NewId();
        // Elevators also use MOVEFLAG_TRANSPORT but we do not keep track of their position changes
        args.TransformForTransport = unit->hasUnitMovementFlag(MOVEFLAG_TRANSPORT) && unit->getTransGuid();
        // mix existing state into new
        args.flags.canswim = unit->CanSwim();
        args.walk = unit->hasUnitMovementFlag(MOVEFLAG_WALK);
        args.flags.flying = unit->obj_movement_info.hasMovementFlag(MOVEFLAG_FLYING_MASK);
    }

    MoveSplineInit::~MoveSplineInit() = default;

    void MoveSplineInit::SetFacing(Vector3 const& spot)
    {
        TransportPathTransform transform(unit, args.TransformForTransport);
        Vector3 finalSpot = transform(spot);
        args.facing.f.x = finalSpot.x;
        args.facing.f.y = finalSpot.y;
        args.facing.f.z = finalSpot.z;
        args.flags.EnableFacingPoint();
    }

    void MoveSplineInit::SetFacing(Unit const* target)
    {
        args.flags.EnableFacingTarget();
        args.facing.target = target->getGuid();
    }

    void MoveSplineInit::SetFacing(float angle)
    {
        if (args.TransformForTransport)
        {
            if (Unit* vehicle = unit->getVehicleBase())
                angle -= vehicle->GetOrientation();
            else if (Transporter* transport = unit->GetTransport())
                angle -= transport->GetOrientation();
        }

        args.facing.angle = G3D::wrap(angle, 0.f, (float)G3D::twoPi());
        args.flags.EnableFacingAngle();
    }

    void MoveSplineInit::MovebyPath(PointsArray const& controls, int32 path_offset)
    {
        args.path_Idx_offset = path_offset;
        args.path.resize(controls.size());
        std::transform(controls.begin(), controls.end(), args.path.begin(), TransportPathTransform(unit, args.TransformForTransport));
    }

    void MoveSplineInit::MoveTo(float x, float y, float z, bool generatePath, bool forceDestination)
    {
        MoveTo(G3D::Vector3(x, y, z), generatePath, forceDestination);
    }

    void MoveSplineInit::MoveTo(Vector3 const& dest, bool generatePath, bool forceDestination)
    {
        if (generatePath)
        {
            // ToDo
        }

        args.path_Idx_offset = 0;
        args.path.resize(2);
        TransportPathTransform transform(unit, args.TransformForTransport);
        args.path[1] = transform(dest);
    }

    Vector3 TransportPathTransform::operator()(Vector3 input)
    {
        if (_transformForTransport)
        {
            if (TransportBase* transport = _owner->getCurrentVehicle())
            {
                transport->CalculatePassengerOffset(input.x, input.y, input.z);
            }
            else if (TransportBase* transport = _owner->GetTransport())
            {
                transport->CalculatePassengerOffset(input.x, input.y, input.z);
            }
        }
        return input;
    }
}
<commit_msg>Fix unix build<commit_after>/*
Copyright (c) 2014-2021 AscEmu Team <http://www.ascemu.org>
This file is released under the MIT license. See README-MIT for more information.
*/

#include "MoveSplineInit.h"
#include "../world/Units/Creatures/Creature.h"
#include "MoveSpline.h"
#include "MovementPacketBuilder.h"
#include "../world/Units/Unit.h"
#include "../world/Objects/Transporter.h"
#include "WorldPacket.h"

namespace MovementNew
{
    UnitSpeedType SelectSpeedType(uint32 moveFlags)
    {
        if (moveFlags & MOVEFLAG_FLYING)
        {
            if (moveFlags & MOVEFLAG_MOVE_BACKWARD )
                return TYPE_FLY_BACK;
            else
                return TYPE_FLY;
        }
        else if (moveFlags & MOVEFLAG_SWIMMING)
        {
            if (moveFlags & MOVEFLAG_MOVE_BACKWARD)
                return TYPE_SWIM_BACK;
            else
                return TYPE_SWIM;
        }
        else if (moveFlags & MOVEFLAG_WALK)
        {
            return TYPE_WALK;
        }
        else if (moveFlags & MOVEFLAG_MOVE_BACKWARD)
            return TYPE_RUN_BACK;

        // Flying creatures use MOVEFLAG_CAN_FLY or MOVEFLAG_DISABLE_GRAVITY
        // Run speed is their default flight speed.
        return TYPE_RUN;
    }

    int32 MoveSplineInit::Launch()
    {
        MoveSpline& move_spline = *unit->movespline;

        // Elevators also use MOVEFLAG_TRANSPORT but we do not keep track of their position changes
        bool transport = unit->hasUnitMovementFlag(MOVEFLAG_TRANSPORT) && unit->GetTransport();
        Location real_position;
        // there is a big chance that current position is unknown if current state is not finalized, need compute it
        // this also allows CalculatePath spline position and update map position in much greater intervals
        // Don't compute for transport movement if the unit is in a motion between two transports
        if (!move_spline.Finalized() && move_spline.onTransport == transport)
            real_position = move_spline.ComputePosition();
        else
        {
            LocationVector const pos = transport ? unit->movement_info.transport_position : unit->GetPosition();
            real_position.x = pos.getPositionX();
            real_position.y = pos.getPositionY();
            real_position.z = pos.getPositionZ();
            real_position.orientation = unit->GetOrientation();
        }

        // should i do the things that user should do? - no.
        if (args.path.empty())
            return 0;

        // corrent first vertex
        args.path[0] = real_position;
        args.initialOrientation = real_position.orientation;
        args.flags.enter_cycle = args.flags.cyclic;
        move_spline.onTransport = transport;

        uint32 moveFlags = unit->obj_movement_info.getMovementFlags();

#if VERSION_STRING <= WotLK
        moveFlags |= MOVEFLAG_SPLINE_ENABLED;
#endif

        if (!args.flags.backward)
            moveFlags = (moveFlags & ~(MOVEFLAG_MOVE_BACKWARD)) | MOVEFLAG_MOVE_FORWARD;
        else
            moveFlags = (moveFlags & ~(MOVEFLAG_MOVE_FORWARD)) | MOVEFLAG_MOVE_BACKWARD;

        if (moveFlags & MOVEFLAG_ROOTED)
            moveFlags &= ~MOVEFLAG_MOVING_MASK;

        if (!args.HasVelocity)
        {
            // If spline is initialized with SetWalk method it only means we need to select
            // walk move speed for it but not add walk flag to unit
            uint32 moveFlagsForSpeed = moveFlags;
            if (args.walk)
                moveFlagsForSpeed |= MOVEFLAG_WALK;
            else
                moveFlagsForSpeed &= ~MOVEFLAG_WALK;

            args.velocity = unit->getSpeedRate(SelectSpeedType(moveFlagsForSpeed), true);
            if (Creature* creature = static_cast<Creature*>(unit))
                if (creature->GetAIInterface()->hasCalledForHelp())
                    args.velocity *= 0.66f;
        }

        // limit the speed in the same way the client does
        args.velocity = std::min(args.velocity, args.flags.catmullrom || args.flags.flying ? 50.0f : std::max(28.0f, unit->getSpeedRate(TYPE_RUN,  true) * 4.0f));

        if (!args.Validate(unit))
            return 0;

        unit->obj_movement_info.flags = moveFlags;
        move_spline.Initialize(args);

        WorldPacket data(SMSG_MONSTER_MOVE, 64);
        data << WoWGuid(unit->getGuid());
        if (transport)
        {
            data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT);
            data << WoWGuid(unit->getTransGuid());
#if VERSION_STRING >= WotLK
            data << int8(unit->GetTransSeat());
#endif
        }

        PacketBuilder::WriteMonsterMove(move_spline, data);
        unit->SendMessageToSet(&data, true);

        return move_spline.Duration();
    }

    void MoveSplineInit::Stop()
    {
        MoveSpline& move_spline = *unit->movespline;

        // No need to stop if we are not moving
        if (move_spline.Finalized())
            return;

        bool transport = unit->hasUnitMovementFlag(MOVEFLAG_TRANSPORT) && unit->getTransGuid();
        Location loc;
        if (move_spline.onTransport == transport)
            loc = move_spline.ComputePosition();
        else
        {
            LocationVector const* pos;
            if (!transport)
                pos = &unit->GetPosition();
            else
                pos = &unit->obj_movement_info.transport_position;

            loc.x = pos->getPositionX();
            loc.y = pos->getPositionY();
            loc.z = pos->getPositionZ();
            loc.orientation = unit->GetOrientation();
        }

        args.flags = MoveSplineFlag::Done;

#if VERSION_STRING <= WotLK
        unit->obj_movement_info.removeMovementFlag(MOVEFLAG_SPLINE_FORWARD_ENABLED);
#endif

#if VERSION_STRING >= Cata
        unit->obj_movement_info.removeMovementFlag(MOVEFLAG_MOVE_FORWARD);
#endif

        move_spline.onTransport = transport;
        move_spline.Initialize(args);

        WorldPacket data(SMSG_MONSTER_MOVE, 64);
        data << WoWGuid(unit->getGuid());
        if (transport)
        {
            data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT);
            data << WoWGuid(unit->getTransGuid());
#if VERSION_STRING >= WotLK
            data << int8(unit->GetTransSeat());
#endif
        }

        PacketBuilder::WriteStopMovement(loc, args.splineId, data);
        unit->SendMessageToSet(&data, true);
    }

    MoveSplineInit::MoveSplineInit(Unit* m) : unit(m)
    {
        args.splineId = splineIdGen.NewId();
        // Elevators also use MOVEFLAG_TRANSPORT but we do not keep track of their position changes
        args.TransformForTransport = unit->hasUnitMovementFlag(MOVEFLAG_TRANSPORT) && unit->getTransGuid();
        // mix existing state into new
        args.flags.canswim = unit->CanSwim();
        args.walk = unit->hasUnitMovementFlag(MOVEFLAG_WALK);
        args.flags.flying = unit->obj_movement_info.hasMovementFlag(MOVEFLAG_FLYING_MASK);
    }

    MoveSplineInit::~MoveSplineInit() = default;

    void MoveSplineInit::SetFacing(Vector3 const& spot)
    {
        TransportPathTransform transform(unit, args.TransformForTransport);
        Vector3 finalSpot = transform(spot);
        args.facing.f.x = finalSpot.x;
        args.facing.f.y = finalSpot.y;
        args.facing.f.z = finalSpot.z;
        args.flags.EnableFacingPoint();
    }

    void MoveSplineInit::SetFacing(Unit const* target)
    {
        args.flags.EnableFacingTarget();
        args.facing.target = target->getGuid();
    }

    void MoveSplineInit::SetFacing(float angle)
    {
        if (args.TransformForTransport)
        {
            if (Unit* vehicle = unit->getVehicleBase())
                angle -= vehicle->GetOrientation();
            else if (Transporter* transport = unit->GetTransport())
                angle -= transport->GetOrientation();
        }

        args.facing.angle = G3D::wrap(angle, 0.f, (float)G3D::twoPi());
        args.flags.EnableFacingAngle();
    }

    void MoveSplineInit::MovebyPath(PointsArray const& controls, int32 path_offset)
    {
        args.path_Idx_offset = path_offset;
        args.path.resize(controls.size());
        std::transform(controls.begin(), controls.end(), args.path.begin(), TransportPathTransform(unit, args.TransformForTransport));
    }

    void MoveSplineInit::MoveTo(float x, float y, float z, bool generatePath, bool forceDestination)
    {
        MoveTo(G3D::Vector3(x, y, z), generatePath, forceDestination);
    }

    void MoveSplineInit::MoveTo(Vector3 const& dest, bool generatePath, bool forceDestination)
    {
        if (generatePath)
        {
            // ToDo
        }

        args.path_Idx_offset = 0;
        args.path.resize(2);
        TransportPathTransform transform(unit, args.TransformForTransport);
        args.path[1] = transform(dest);
    }

    Vector3 TransportPathTransform::operator()(Vector3 input)
    {
        if (_transformForTransport)
        {
            if (TransportBase* transport = _owner->getCurrentVehicle())
            {
                transport->CalculatePassengerOffset(input.x, input.y, input.z);
            }
            else if (TransportBase* transport = _owner->GetTransport())
            {
                transport->CalculatePassengerOffset(input.x, input.y, input.z);
            }
        }
        return input;
    }
}
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_SCAL_PROB_NEG_BINOMIAL_2_LPMF_HPP
#define STAN_MATH_PRIM_SCAL_PROB_NEG_BINOMIAL_2_LPMF_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/scal/err/check_consistent_sizes.hpp>
#include <stan/math/prim/scal/err/check_positive_finite.hpp>
#include <stan/math/prim/scal/err/check_nonnegative.hpp>
#include <stan/math/prim/scal/fun/size_zero.hpp>
#include <stan/math/prim/scal/fun/multiply_log.hpp>
#include <stan/math/prim/scal/fun/digamma.hpp>
#include <stan/math/prim/scal/fun/square.hpp>
#include <stan/math/prim/scal/fun/lgamma.hpp>
#include <stan/math/prim/scal/fun/binomial_coefficient_log.hpp>
#include <stan/math/prim/scal/fun/value_of.hpp>
#include <stan/math/prim/scal/prob/poisson_lpmf.hpp>
#include <cmath>

namespace stan {
namespace math {

namespace internal {
// Exposing to let me us this in tests
// The current tests fail when the cutoff is 1e8 and pass with 1e9,
// setting 1e10 to be safe
constexpr double neg_binomial_2_phi_cutoff = 1e10;
}  // namespace internal

// NegBinomial(n|mu, phi)  [mu >= 0; phi > 0;  n >= 0]
template <bool propto, typename T_n, typename T_location, typename T_precision>
return_type_t<T_location, T_precision> neg_binomial_2_lpmf(
    const T_n& n, const T_location& mu, const T_precision& phi) {
  using T_partials_return = partials_return_t<T_n, T_location, T_precision>;

  static const char* function = "neg_binomial_2_lpmf";

  if (size_zero(n, mu, phi)) {
    return 0.0;
  }

  T_partials_return logp(0.0);
  check_nonnegative(function, "Failures variable", n);
  check_positive_finite(function, "Location parameter", mu);
  check_positive_finite(function, "Precision parameter", phi);
  check_consistent_sizes(function, "Failures variable", n, "Location parameter",
                         mu, "Precision parameter", phi);

  if (!include_summand<propto, T_location, T_precision>::value) {
    return 0.0;
  }

  using std::log;

  scalar_seq_view<T_n> n_vec(n);
  scalar_seq_view<T_location> mu_vec(mu);
  scalar_seq_view<T_precision> phi_vec(phi);
  size_t size = max_size(n, mu, phi);

  operands_and_partials<T_location, T_precision> ops_partials(mu, phi);

  size_t len_ep = max_size(mu, phi);
  size_t len_np = max_size(n, phi);

  VectorBuilder<true, T_partials_return, T_location> mu__(length(mu));
  for (size_t i = 0, size = length(mu); i < size; ++i) {
    mu__[i] = value_of(mu_vec[i]);
  }

  VectorBuilder<true, T_partials_return, T_precision> phi__(length(phi));
  for (size_t i = 0, size = length(phi); i < size; ++i) {
    phi__[i] = value_of(phi_vec[i]);
  }

  VectorBuilder<true, T_partials_return, T_precision> log_phi(length(phi));
  for (size_t i = 0, size = length(phi); i < size; ++i) {
    log_phi[i] = log(phi__[i]);
  }

  VectorBuilder<true, T_partials_return, T_location, T_precision>
      log_mu_plus_phi(len_ep);
  for (size_t i = 0; i < len_ep; ++i) {
    log_mu_plus_phi[i] = log(mu__[i] + phi__[i]);
  }

  VectorBuilder<true, T_partials_return, T_n, T_precision> n_plus_phi(len_np);
  for (size_t i = 0; i < len_np; ++i) {
    n_plus_phi[i] = n_vec[i] + phi__[i];
  }

  for (size_t i = 0; i < size; i++) {
    if (phi__[i] > internal::neg_binomial_2_phi_cutoff) {
      // Phi is large, deferring to Poisson.
      // Copying the code here as just calling
      // poisson_lpmf does not preserve propto logic correctly
      if (include_summand<propto>::value) {
        logp -= lgamma(n_vec[i] + 1.0);
      }
      if (include_summand<propto, T_location>::value) {
        logp += multiply_log(n_vec[i], mu__[i]) - mu__[i];
      }

      if (!is_constant_all<T_location>::value) {
        // This is the Taylor series of the full derivative for phi -> Inf
        // Obtained in Mathematica via
        // Series[n/mu - (n + phi)/(mu+phi),{phi,Infinity, 1}]
        // Currently ignoring the term (mu__[i] - n_vec[i]) / phi__[i]
        ops_partials.edge1_.partials_[i] += n_vec[i] / mu__[i] - 1;
      }

      // The derivative wrt. phi = 0 + O(1/neg_binomial_2_phi_cutoff^2),
      // But the quadratic term is big enough to warrant inclusion here
      // (can be around 1e-6 at cutoff).
      // Expansion obtained in Mathematica via
      // Series[1 - (n + phi) / (mu + phi) + Log[phi] - Log[mu + phi] -
      //  PolyGamma[phi] + PolyGamma[n + phi],{phi,Infinity, 2}]
      if (!is_constant_all<T_precision>::value) {
        ops_partials.edge2_.partials_[i]
            += (mu__[i] * (-mu__[i] + 2 * n_vec[i]) + n_vec[i] * (1 - n_vec[i]))
               / (2 * square(phi__[i]));
      }

    } else {
      if (include_summand<propto, T_precision>::value) {
        logp += binomial_coefficient_log(n_plus_phi[i] - 1, n_vec[i]);
      }

      logp += phi__[i] * (log_phi[i] - log_mu_plus_phi[i])
              - (n_vec[i]) * log_mu_plus_phi[i];

      if (include_summand<propto, T_location>::value) {
        logp += multiply_log(n_vec[i], mu__[i]);
      }

      if (!is_constant_all<T_location>::value) {
        ops_partials.edge1_.partials_[i]
            += n_vec[i] / mu__[i]
               - (n_vec[i] + phi__[i]) / (mu__[i] + phi__[i]);
      }
      if (!is_constant_all<T_precision>::value) {
        ops_partials.edge2_.partials_[i]
            += 1.0 - n_plus_phi[i] / (mu__[i] + phi__[i]) + log_phi[i]
               - log_mu_plus_phi[i] - digamma(phi__[i])
               + digamma(n_plus_phi[i]);
      }
    }
  }
  return ops_partials.build(logp);
}

template <typename T_n, typename T_location, typename T_precision>
inline return_type_t<T_location, T_precision> neg_binomial_2_lpmf(
    const T_n& n, const T_location& mu, const T_precision& phi) {
  return neg_binomial_2_lpmf<false>(n, mu, phi);
}

}  // namespace math
}  // namespace stan
#endif
<commit_msg>Fixed #1531 for neg_binomial_2_lpmf<commit_after>#ifndef STAN_MATH_PRIM_SCAL_PROB_NEG_BINOMIAL_2_LPMF_HPP
#define STAN_MATH_PRIM_SCAL_PROB_NEG_BINOMIAL_2_LPMF_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/scal/err/check_consistent_sizes.hpp>
#include <stan/math/prim/scal/err/check_positive_finite.hpp>
#include <stan/math/prim/scal/err/check_nonnegative.hpp>
#include <stan/math/prim/scal/fun/size_zero.hpp>
#include <stan/math/prim/scal/fun/multiply_log.hpp>
#include <stan/math/prim/scal/fun/digamma.hpp>
#include <stan/math/prim/scal/fun/square.hpp>
#include <stan/math/prim/scal/fun/lgamma.hpp>
#include <stan/math/prim/scal/fun/binomial_coefficient_log.hpp>
#include <stan/math/prim/scal/fun/value_of.hpp>
#include <stan/math/prim/scal/prob/poisson_lpmf.hpp>
#include <cmath>

namespace stan {
namespace math {

namespace internal {
// Exposing to let me us this in tests
// The current tests fail when the cutoff is 1e8 and pass with 1e9,
// setting 1e10 to be safe
constexpr double neg_binomial_2_phi_cutoff = 1e10;
}  // namespace internal

// NegBinomial(n|mu, phi)  [mu >= 0; phi > 0;  n >= 0]
template <bool propto, typename T_n, typename T_location, typename T_precision>
return_type_t<T_location, T_precision> neg_binomial_2_lpmf(
    const T_n& n, const T_location& mu, const T_precision& phi) {
  using T_partials_return = partials_return_t<T_n, T_location, T_precision>;

  static const char* function = "neg_binomial_2_lpmf";

  if (size_zero(n, mu, phi)) {
    return 0.0;
  }

  T_partials_return logp(0.0);
  check_nonnegative(function, "Failures variable", n);
  check_positive_finite(function, "Location parameter", mu);
  check_positive_finite(function, "Precision parameter", phi);
  check_consistent_sizes(function, "Failures variable", n, "Location parameter",
                         mu, "Precision parameter", phi);

  if (!include_summand<propto, T_location, T_precision>::value) {
    return 0.0;
  }

  using std::log;

  scalar_seq_view<T_n> n_vec(n);
  scalar_seq_view<T_location> mu_vec(mu);
  scalar_seq_view<T_precision> phi_vec(phi);
  size_t size_max = max_size(n, mu, phi);

  operands_and_partials<T_location, T_precision> ops_partials(mu, phi);

  size_t len_ep = max_size(mu, phi);
  size_t len_np = max_size(n, phi);

  size_t len_mu = length(mu);
  VectorBuilder<true, T_partials_return, T_location> mu__(len_mu);
  for (size_t i = 0; i < len_mu; ++i) {
    mu__[i] = value_of(mu_vec[i]);
  }

  size_t len_phi = length(phi);
  VectorBuilder<true, T_partials_return, T_precision> phi__(len_phi);
  VectorBuilder<true, T_partials_return, T_precision> log_phi(len_phi);
  for (size_t i = 0; i < len_phi; ++i) {
    phi__[i] = value_of(phi_vec[i]);
    log_phi[i] = log(phi__[i]);
  }

  VectorBuilder<true, T_partials_return, T_location, T_precision>
      log_mu_plus_phi(len_ep);
  for (size_t i = 0; i < len_ep; ++i) {
    log_mu_plus_phi[i] = log(mu__[i] + phi__[i]);
  }

  VectorBuilder<true, T_partials_return, T_n, T_precision> n_plus_phi(len_np);
  for (size_t i = 0; i < len_np; ++i) {
    n_plus_phi[i] = n_vec[i] + phi__[i];
  }

  for (size_t i = 0; i < size_max; i++) {
    if (phi__[i] > internal::neg_binomial_2_phi_cutoff) {
      // Phi is large, deferring to Poisson.
      // Copying the code here as just calling
      // poisson_lpmf does not preserve propto logic correctly
      if (include_summand<propto>::value) {
        logp -= lgamma(n_vec[i] + 1.0);
      }
      if (include_summand<propto, T_location>::value) {
        logp += multiply_log(n_vec[i], mu__[i]) - mu__[i];
      }

      if (!is_constant_all<T_location>::value) {
        // This is the Taylor series of the full derivative for phi -> Inf
        // Obtained in Mathematica via
        // Series[n/mu - (n + phi)/(mu+phi),{phi,Infinity, 1}]
        // Currently ignoring the term (mu__[i] - n_vec[i]) / phi__[i]
        ops_partials.edge1_.partials_[i] += n_vec[i] / mu__[i] - 1;
      }

      // The derivative wrt. phi = 0 + O(1/neg_binomial_2_phi_cutoff^2),
      // But the quadratic term is big enough to warrant inclusion here
      // (can be around 1e-6 at cutoff).
      // Expansion obtained in Mathematica via
      // Series[1 - (n + phi) / (mu + phi) + Log[phi] - Log[mu + phi] -
      //  PolyGamma[phi] + PolyGamma[n + phi],{phi,Infinity, 2}]
      if (!is_constant_all<T_precision>::value) {
        ops_partials.edge2_.partials_[i]
            += (mu__[i] * (-mu__[i] + 2 * n_vec[i]) + n_vec[i] * (1 - n_vec[i]))
               / (2 * square(phi__[i]));
      }

    } else {
      if (include_summand<propto, T_precision>::value) {
        logp += binomial_coefficient_log(n_plus_phi[i] - 1, n_vec[i]);
      }

      logp += phi__[i] * (log_phi[i] - log_mu_plus_phi[i])
              - (n_vec[i]) * log_mu_plus_phi[i];

      if (include_summand<propto, T_location>::value) {
        logp += multiply_log(n_vec[i], mu__[i]);
      }

      if (!is_constant_all<T_location>::value) {
        ops_partials.edge1_.partials_[i]
            += n_vec[i] / mu__[i]
               - (n_vec[i] + phi__[i]) / (mu__[i] + phi__[i]);
      }
      if (!is_constant_all<T_precision>::value) {
        ops_partials.edge2_.partials_[i]
            += 1.0 - n_plus_phi[i] / (mu__[i] + phi__[i]) + log_phi[i]
               - log_mu_plus_phi[i] - digamma(phi__[i])
               + digamma(n_plus_phi[i]);
      }
    }
  }
  return ops_partials.build(logp);
}

template <typename T_n, typename T_location, typename T_precision>
inline return_type_t<T_location, T_precision> neg_binomial_2_lpmf(
    const T_n& n, const T_location& mu, const T_precision& phi) {
  return neg_binomial_2_lpmf<false>(n, mu, phi);
}

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before><commit_msg>forgot to change the Invalidate to InvalidateEntry in treelistbox<commit_after><|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#ifndef _COM_SUN_STAR_EMBED_XCOMPONENTSUPPLIER_HPP_
#include <com/sun/star/embed/XComponentSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_EMBEDSTATES_HPP_
#include <com/sun/star/embed/EmbedStates.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XVISUALOBJECT_HPP_
#include <com/sun/star/embed/XVisualObject.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XEMBEDPERSIST_HPP_
#include <com/sun/star/embed/XEmbedPersist.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_NOVISUALAREASIZEEXCEPTION_HPP_
#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
#endif
#ifndef _COM_SUN_STAR_DATATRANSFER_XTRANSFERABLE_HPP_
#include <com/sun/star/datatransfer/XTransferable.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_ASPECTS_HPP_
#include <com/sun/star/embed/Aspects.hpp>
#endif

#include <embedtransfer.hxx>
#include <vcl/mapunit.hxx>
#include <vcl/outdev.hxx>
#include <comphelper/storagehelper.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <unotools/streamwrap.hxx>
#include <unotools/tempfile.hxx>
#include <toolkit/helper/vclunohelper.hxx>

#include "embedhlp.hxx"

using namespace ::com::sun::star;

SvEmbedTransferHelper::SvEmbedTransferHelper( const uno::Reference< embed::XEmbeddedObject >& xObj,
                                                Graphic* pGraphic,
                                                sal_Int64 nAspect )
: m_xObj( xObj )
, m_pGraphic( pGraphic ? new Graphic( *pGraphic ) : NULL )
, m_nAspect( nAspect )
{
}

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

SvEmbedTransferHelper::~SvEmbedTransferHelper()
{
    if ( m_pGraphic )
    {
        delete m_pGraphic;
        m_pGraphic = NULL;
    }
}

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

void SvEmbedTransferHelper::AddSupportedFormats()
{
    AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
    AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
    AddFormat( FORMAT_GDIMETAFILE );
}

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

sal_Bool SvEmbedTransferHelper::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
{
    sal_Bool bRet = sal_False;

    if( m_xObj.is() )
    {
        try
        {
            sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
            if( HasFormat( nFormat ) )
            {
                if( nFormat == SOT_FORMATSTR_ID_OBJECTDESCRIPTOR )
                {
                    TransferableObjectDescriptor aDesc;
                    FillTransferableObjectDescriptor( aDesc, m_xObj, m_pGraphic, m_nAspect );
                    bRet = SetTransferableObjectDescriptor( aDesc, rFlavor );
                }
                else if( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
                {
                    try
                    {
                        // TODO/LATER: Propbably the graphic should be copied here as well
                        // currently it is handled by the applications
                        utl::TempFile aTmp;
                        aTmp.EnableKillingFile( TRUE );
                        uno::Reference < embed::XEmbedPersist > xPers( m_xObj, uno::UNO_QUERY );
                        if ( xPers.is() )
                        {
                            uno::Reference < embed::XStorage > xStg = comphelper::OStorageHelper::GetTemporaryStorage();
                            ::rtl::OUString aName = ::rtl::OUString::createFromAscii("Dummy");
                            SvStream* pStream = NULL;
                            BOOL bDeleteStream = FALSE;
                            uno::Sequence < beans::PropertyValue > aEmpty;
                            xPers->storeToEntry( xStg, aName, aEmpty, aEmpty );
                            if ( xStg->isStreamElement( aName ) )
                            {
                                uno::Reference < io::XStream > xStm = xStg->cloneStreamElement( aName );
                                pStream = utl::UcbStreamHelper::CreateStream( xStm );
                                bDeleteStream = TRUE;
                            }
                            else
                            {
                                pStream = aTmp.GetStream( STREAM_STD_READWRITE );
                                uno::Reference < embed::XStorage > xStor = comphelper::OStorageHelper::GetStorageFromStream( new utl::OStreamWrapper( *pStream ) );
                                xStg->openStorageElement( aName, embed::ElementModes::READ )->copyToStorage( xStor );
                            }

                            ::com::sun::star::uno::Any                  aAny;
                            const sal_uInt32                            nLen = pStream->Seek( STREAM_SEEK_TO_END );
                            ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( nLen );

                            pStream->Seek( STREAM_SEEK_TO_BEGIN );
                            pStream->Read( aSeq.getArray(),  nLen );
                            if ( bDeleteStream )
                                delete pStream;

                            if( ( bRet = ( aSeq.getLength() > 0 ) ) == sal_True )
                            {
                                aAny <<= aSeq;
                                SetAny( aAny, rFlavor );
                            }
                        }
                        else
                        {
                            //TODO/LATER: how to handle objects without persistance?!
                        }
                    }
                    catch ( uno::Exception& )
                    {
                    }
                }
                else if ( nFormat == FORMAT_GDIMETAFILE && m_pGraphic )
                {
                    SvMemoryStream aMemStm( 65535, 65535 );
                    aMemStm.SetVersion( SOFFICE_FILEFORMAT_CURRENT );

                    const GDIMetaFile& aMetaFile = m_pGraphic->GetGDIMetaFile();
                    ((GDIMetaFile*)(&aMetaFile))->Write( aMemStm );
                    uno::Any aAny;
                    aAny <<= uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ),
                                                    aMemStm.Seek( STREAM_SEEK_TO_END ) );
                    SetAny( aAny, rFlavor );
                    bRet = sal_True;
                }
                else if ( m_xObj.is() && :: svt::EmbeddedObjectRef::TryRunningState( m_xObj ) )
                {
                    uno::Reference< datatransfer::XTransferable > xTransferable( m_xObj->getComponent(), uno::UNO_QUERY );
                    if ( xTransferable.is() )
                    {
                        uno::Any aAny = xTransferable->getTransferData( rFlavor );
                        SetAny( aAny, rFlavor );
                        bRet = sal_True;
                    }
                }
            }
        }
        catch( uno::Exception& )
        {
            // Error handling?
        }
    }

    return bRet;
}

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

void SvEmbedTransferHelper::ObjectReleased()
{
    m_xObj = uno::Reference< embed::XEmbeddedObject >();
}

void SvEmbedTransferHelper::FillTransferableObjectDescriptor( TransferableObjectDescriptor& rDesc,
    const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XEmbeddedObject >& xObj,
    Graphic* pGraphic,
    sal_Int64 nAspect )
{
    //TODO/LATER: need TypeName to fill it into the Descriptor (will be shown in listbox)
    ::com::sun::star::datatransfer::DataFlavor aFlavor;
    SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aFlavor );

    rDesc.maClassName = SvGlobalName( xObj->getClassID() );
    rDesc.maTypeName = aFlavor.HumanPresentableName;

    //TODO/LATER: the aspect size in the descriptor is wrong, unfortunately the stream
    // representation of the descriptor allows only 4 bytes for the aspect
    // so for internal transport something different should be found
    rDesc.mnViewAspect = sal::static_int_cast<sal_uInt16>( nAspect );

    //TODO/LATER: status needs to become sal_Int64
    rDesc.mnOle2Misc = sal::static_int_cast<sal_Int32>(xObj->getStatus( rDesc.mnViewAspect ));

    Size aSize;
    MapMode aMapMode( MAP_100TH_MM );
    if ( nAspect == embed::Aspects::MSOLE_ICON )
    {
        if ( pGraphic )
        {
            aMapMode = pGraphic->GetPrefMapMode();
            aSize = pGraphic->GetPrefSize();
        }
        else
            aSize = Size( 2500, 2500 );
    }
    else
    {
        try
        {
            awt::Size aSz;
            aSz = xObj->getVisualAreaSize( rDesc.mnViewAspect );
            aSize = Size( aSz.Width, aSz.Height );
        }
        catch( embed::NoVisualAreaSizeException& )
        {
            OSL_ENSURE( sal_False, "Can not get visual area size!\n" );
            aSize = Size( 5000, 5000 );
        }

        // TODO/LEAN: getMapUnit can switch object to running state
        aMapMode = MapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( rDesc.mnViewAspect ) ) );
    }

    rDesc.maSize = OutputDevice::LogicToLogic( aSize, aMapMode, MapMode( MAP_100TH_MM ) );
    rDesc.maDragStartPos = Point();
    rDesc.maDisplayName = String();
    rDesc.mbCanLink = FALSE;
}

<commit_msg>INTEGRATION: CWS vgbugs07 (1.9.182); FILE MERGED 2007/06/04 13:31:43 vg 1.9.182.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: embedtransfer.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 21:49:16 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#ifndef _COM_SUN_STAR_EMBED_XCOMPONENTSUPPLIER_HPP_
#include <com/sun/star/embed/XComponentSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_EMBEDSTATES_HPP_
#include <com/sun/star/embed/EmbedStates.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XVISUALOBJECT_HPP_
#include <com/sun/star/embed/XVisualObject.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XEMBEDPERSIST_HPP_
#include <com/sun/star/embed/XEmbedPersist.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_NOVISUALAREASIZEEXCEPTION_HPP_
#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
#endif
#ifndef _COM_SUN_STAR_DATATRANSFER_XTRANSFERABLE_HPP_
#include <com/sun/star/datatransfer/XTransferable.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_ASPECTS_HPP_
#include <com/sun/star/embed/Aspects.hpp>
#endif

#include <svtools/embedtransfer.hxx>
#include <vcl/mapunit.hxx>
#include <vcl/outdev.hxx>
#include <comphelper/storagehelper.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <unotools/streamwrap.hxx>
#include <unotools/tempfile.hxx>
#include <toolkit/helper/vclunohelper.hxx>

#include "embedhlp.hxx"

using namespace ::com::sun::star;

SvEmbedTransferHelper::SvEmbedTransferHelper( const uno::Reference< embed::XEmbeddedObject >& xObj,
                                                Graphic* pGraphic,
                                                sal_Int64 nAspect )
: m_xObj( xObj )
, m_pGraphic( pGraphic ? new Graphic( *pGraphic ) : NULL )
, m_nAspect( nAspect )
{
}

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

SvEmbedTransferHelper::~SvEmbedTransferHelper()
{
    if ( m_pGraphic )
    {
        delete m_pGraphic;
        m_pGraphic = NULL;
    }
}

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

void SvEmbedTransferHelper::AddSupportedFormats()
{
    AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE );
    AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
    AddFormat( FORMAT_GDIMETAFILE );
}

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

sal_Bool SvEmbedTransferHelper::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
{
    sal_Bool bRet = sal_False;

    if( m_xObj.is() )
    {
        try
        {
            sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
            if( HasFormat( nFormat ) )
            {
                if( nFormat == SOT_FORMATSTR_ID_OBJECTDESCRIPTOR )
                {
                    TransferableObjectDescriptor aDesc;
                    FillTransferableObjectDescriptor( aDesc, m_xObj, m_pGraphic, m_nAspect );
                    bRet = SetTransferableObjectDescriptor( aDesc, rFlavor );
                }
                else if( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
                {
                    try
                    {
                        // TODO/LATER: Propbably the graphic should be copied here as well
                        // currently it is handled by the applications
                        utl::TempFile aTmp;
                        aTmp.EnableKillingFile( TRUE );
                        uno::Reference < embed::XEmbedPersist > xPers( m_xObj, uno::UNO_QUERY );
                        if ( xPers.is() )
                        {
                            uno::Reference < embed::XStorage > xStg = comphelper::OStorageHelper::GetTemporaryStorage();
                            ::rtl::OUString aName = ::rtl::OUString::createFromAscii("Dummy");
                            SvStream* pStream = NULL;
                            BOOL bDeleteStream = FALSE;
                            uno::Sequence < beans::PropertyValue > aEmpty;
                            xPers->storeToEntry( xStg, aName, aEmpty, aEmpty );
                            if ( xStg->isStreamElement( aName ) )
                            {
                                uno::Reference < io::XStream > xStm = xStg->cloneStreamElement( aName );
                                pStream = utl::UcbStreamHelper::CreateStream( xStm );
                                bDeleteStream = TRUE;
                            }
                            else
                            {
                                pStream = aTmp.GetStream( STREAM_STD_READWRITE );
                                uno::Reference < embed::XStorage > xStor = comphelper::OStorageHelper::GetStorageFromStream( new utl::OStreamWrapper( *pStream ) );
                                xStg->openStorageElement( aName, embed::ElementModes::READ )->copyToStorage( xStor );
                            }

                            ::com::sun::star::uno::Any                  aAny;
                            const sal_uInt32                            nLen = pStream->Seek( STREAM_SEEK_TO_END );
                            ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( nLen );

                            pStream->Seek( STREAM_SEEK_TO_BEGIN );
                            pStream->Read( aSeq.getArray(),  nLen );
                            if ( bDeleteStream )
                                delete pStream;

                            if( ( bRet = ( aSeq.getLength() > 0 ) ) == sal_True )
                            {
                                aAny <<= aSeq;
                                SetAny( aAny, rFlavor );
                            }
                        }
                        else
                        {
                            //TODO/LATER: how to handle objects without persistance?!
                        }
                    }
                    catch ( uno::Exception& )
                    {
                    }
                }
                else if ( nFormat == FORMAT_GDIMETAFILE && m_pGraphic )
                {
                    SvMemoryStream aMemStm( 65535, 65535 );
                    aMemStm.SetVersion( SOFFICE_FILEFORMAT_CURRENT );

                    const GDIMetaFile& aMetaFile = m_pGraphic->GetGDIMetaFile();
                    ((GDIMetaFile*)(&aMetaFile))->Write( aMemStm );
                    uno::Any aAny;
                    aAny <<= uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ),
                                                    aMemStm.Seek( STREAM_SEEK_TO_END ) );
                    SetAny( aAny, rFlavor );
                    bRet = sal_True;
                }
                else if ( m_xObj.is() && :: svt::EmbeddedObjectRef::TryRunningState( m_xObj ) )
                {
                    uno::Reference< datatransfer::XTransferable > xTransferable( m_xObj->getComponent(), uno::UNO_QUERY );
                    if ( xTransferable.is() )
                    {
                        uno::Any aAny = xTransferable->getTransferData( rFlavor );
                        SetAny( aAny, rFlavor );
                        bRet = sal_True;
                    }
                }
            }
        }
        catch( uno::Exception& )
        {
            // Error handling?
        }
    }

    return bRet;
}

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

void SvEmbedTransferHelper::ObjectReleased()
{
    m_xObj = uno::Reference< embed::XEmbeddedObject >();
}

void SvEmbedTransferHelper::FillTransferableObjectDescriptor( TransferableObjectDescriptor& rDesc,
    const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XEmbeddedObject >& xObj,
    Graphic* pGraphic,
    sal_Int64 nAspect )
{
    //TODO/LATER: need TypeName to fill it into the Descriptor (will be shown in listbox)
    ::com::sun::star::datatransfer::DataFlavor aFlavor;
    SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aFlavor );

    rDesc.maClassName = SvGlobalName( xObj->getClassID() );
    rDesc.maTypeName = aFlavor.HumanPresentableName;

    //TODO/LATER: the aspect size in the descriptor is wrong, unfortunately the stream
    // representation of the descriptor allows only 4 bytes for the aspect
    // so for internal transport something different should be found
    rDesc.mnViewAspect = sal::static_int_cast<sal_uInt16>( nAspect );

    //TODO/LATER: status needs to become sal_Int64
    rDesc.mnOle2Misc = sal::static_int_cast<sal_Int32>(xObj->getStatus( rDesc.mnViewAspect ));

    Size aSize;
    MapMode aMapMode( MAP_100TH_MM );
    if ( nAspect == embed::Aspects::MSOLE_ICON )
    {
        if ( pGraphic )
        {
            aMapMode = pGraphic->GetPrefMapMode();
            aSize = pGraphic->GetPrefSize();
        }
        else
            aSize = Size( 2500, 2500 );
    }
    else
    {
        try
        {
            awt::Size aSz;
            aSz = xObj->getVisualAreaSize( rDesc.mnViewAspect );
            aSize = Size( aSz.Width, aSz.Height );
        }
        catch( embed::NoVisualAreaSizeException& )
        {
            OSL_ENSURE( sal_False, "Can not get visual area size!\n" );
            aSize = Size( 5000, 5000 );
        }

        // TODO/LEAN: getMapUnit can switch object to running state
        aMapMode = MapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( rDesc.mnViewAspect ) ) );
    }

    rDesc.maSize = OutputDevice::LogicToLogic( aSize, aMapMode, MapMode( MAP_100TH_MM ) );
    rDesc.maDragStartPos = Point();
    rDesc.maDisplayName = String();
    rDesc.mbCanLink = FALSE;
}

<|endoftext|>


<commit_before>#include <image/parser/parser.hpp>
#include "renderer.hpp"

renderer_t::renderer_t(QWidget * parent)
{
}

void renderer_t::initializeGL()
{
   vertex_array_obj_ = new QOpenGLVertexArrayObject();
   vertex_array_obj_->create();
   vertex_array_obj_->bind();

   vertex_buffer_ = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
   vertex_buffer_->create();
   vertex_buffer_->setUsagePattern(QOpenGLBuffer::StaticDraw);
   vertex_buffer_->bind();

   GLfloat vertices[] = {
         //Position   Texcoords
         -1.f, -1.f,  0.f, 1.f, // bottom-left  - 0
          1.f, -1.f,  1.f, 1.f, // bottom-right - 1
          1.f,  1.f,  1.f, 0.f, // top-right    - 2
         -1.f,  1.f,  0.f, 0.f, // top-left     - 3
   };

   vertex_buffer_->allocate(vertices, sizeof(vertices));

   index_buffer_ = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
   index_buffer_->create();
   index_buffer_->setUsagePattern(QOpenGLBuffer::StaticDraw);
   index_buffer_->bind();

   GLuint elements[] = {
         0, 1, 2, 3
   };

   index_buffer_->allocate(elements, sizeof(elements));

   index_buffer_->bind();
   vertex_buffer_->bind();
   vertex_array_obj_->bind();

   vertex_shader_ = new QOpenGLShader(QOpenGLShader::Vertex);
   vertex_shader_->compileSourceCode(vertex_shader_src_.c_str());
   fragment_shader_ = new QOpenGLShader(QOpenGLShader::Fragment);
   fragment_shader_->compileSourceCode(fragment_shader_src_.c_str());

   program_.addShader(vertex_shader_);
   program_.addShader(fragment_shader_);
   program_.link();
   program_.bind();

   program_.enableAttributeArray(0);
   program_.setAttributeBuffer(0, GL_FLOAT, 0, 2, sizeof(float) * 4);
   program_.enableAttributeArray(2);
   program_.setAttributeBuffer(2, GL_FLOAT, sizeof(float) * 2, 2, sizeof(float) * 4);

//   parser_t parser("sample.tif");
//   float ** image = parser.parse();

   texture_ = new QOpenGLTexture(QImage("Lenna.png"));
   texture_->bind();
}

void renderer_t::paintGL()
{
   glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
   glClear(GL_COLOR_BUFFER_BIT);

   index_buffer_->bind();
   vertex_buffer_->bind();
   vertex_array_obj_->bind();
   program_.bind();
   texture_->bind();

   glDrawArrays(GL_QUADS, 0, 4);
}

void renderer_t::resizeGL(int width, int height)
{
   QGLWidget::resizeGL(width, height);
}

renderer_t::~renderer_t()
{
   vertex_buffer_->release();
   vertex_buffer_->destroy();
}<commit_msg>correct image size<commit_after>#include <image/parser/parser.hpp>
#include "renderer.hpp"

renderer_t::renderer_t(QWidget * parent)
{
}

void renderer_t::initializeGL()
{
   vertex_array_obj_ = new QOpenGLVertexArrayObject();
   vertex_array_obj_->create();
   vertex_array_obj_->bind();

   vertex_buffer_ = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
   vertex_buffer_->create();
   vertex_buffer_->setUsagePattern(QOpenGLBuffer::StaticDraw);
   vertex_buffer_->bind();

   GLfloat vertices[] = {
         //Position   Texcoords
         -1.f, -1.f,  0.f, 1.f, // bottom-left  - 0
          1.f, -1.f,  1.f, 1.f, // bottom-right - 1
          1.f,  1.f,  1.f, 0.f, // top-right    - 2
         -1.f,  1.f,  0.f, 0.f, // top-left     - 3
   };

   vertex_buffer_->allocate(vertices, sizeof(vertices));

   index_buffer_ = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
   index_buffer_->create();
   index_buffer_->setUsagePattern(QOpenGLBuffer::StaticDraw);
   index_buffer_->bind();

   GLuint elements[] = {
         0, 1, 2, 3
   };

   index_buffer_->allocate(elements, sizeof(elements));

   index_buffer_->bind();
   vertex_buffer_->bind();
   vertex_array_obj_->bind();

   vertex_shader_ = new QOpenGLShader(QOpenGLShader::Vertex);
   vertex_shader_->compileSourceCode(vertex_shader_src_.c_str());
   fragment_shader_ = new QOpenGLShader(QOpenGLShader::Fragment);
   fragment_shader_->compileSourceCode(fragment_shader_src_.c_str());

   program_.addShader(vertex_shader_);
   program_.addShader(fragment_shader_);
   program_.link();
   program_.bind();

   program_.enableAttributeArray(0);
   program_.setAttributeBuffer(0, GL_FLOAT, 0, 2, sizeof(float) * 4);
   program_.enableAttributeArray(2);
   program_.setAttributeBuffer(2, GL_FLOAT, sizeof(float) * 2, 2, sizeof(float) * 4);

//   parser_t parser("sample.tif");
//   float ** image = parser.parse();

   texture_ = new QOpenGLTexture(QImage("Lenna.png"));
   texture_->bind();
}

void renderer_t::paintGL()
{
   glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
   glClear(GL_COLOR_BUFFER_BIT);

   index_buffer_->bind();
   vertex_buffer_->bind();
   vertex_array_obj_->bind();
   program_.bind();
   texture_->bind();

   glDrawArrays(GL_QUADS, 0, 4);
}

void renderer_t::resizeGL(int width, int height)
{
   int side = qMin(width, height);
   glViewport((width - side) / 2, (height - side) / 2, side, side);
}

renderer_t::~renderer_t()
{
   vertex_buffer_->release();
   vertex_buffer_->destroy();
}<|endoftext|>


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

Program:   Insight Segmentation & Registration Toolkit
Module:    BiasFieldEstimator.cxx
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) 2002 Insight Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

=========================================================================*/
#include <string>
#include <vector>
#include <vnl/vnl_math.h>

#include "imageutils.h"
#include "OptionList.h"
#include "itkMRIBiasFieldCorrectionFilter.h"

typedef itk::MRIBiasFieldCorrectionFilter<ImageType, ImageType, MaskType> Corrector ;

void print_usage()
{
  print_line("MRIBiasCorrection 1.0 (21.June.2001)");

  print_line("usage: BiasFieldEstimator --input file" ) ;
  print_line("       --class-mean mean(1) ... mean(i)" ) ;
  print_line("       --class-sigma sigma(1) ... sigma(i)" ) ;
  print_line("       --use-log [yes|no]") ;
  print_line("       [--input-mask file]" ) ;
  print_line("       [--degree int] [--coefficients c0,..,cn]" ) ;
  print_line("       [--growth double] [--shrink double] ") ;
  print_line("       [--volume-max-iteration int] [--inter-slice-max-iteration int]");
  print_line("       [--init-step-size double] ");

  print_line("");

  print_line("--input file") ;
  print_line("        input data set [meta image format]" );
  print_line("--class-mean mean(1),...,mean(i)" ) ;
  print_line("        intensity means  of the differen i tissue classes") ;
  print_line("--class-sigma sig(1),...,sig(i)" ) ;
  print_line("        intensity sigmas of the different i tissue clases") ;
  print_line("        NOTE: The sigmas should be listed in the SAME ORDER") ;
  print_line("              of means");
  print_line("        and each value should be SEPERATED BY A SPACE)") ;
  print_line("--input-mask file" ) ;
  print_line("        mask input with file [meta image format]");
  print_line("--degree int") ;
  print_line("        degree of legendre polynomial used for the") ;
  print_line("        approximation of the bias field" );
  print_line("--use-log [yes|no]") ;
  print_line("        if yes, assume a multiplicative bias field") ;
  print_line("        (use log of image, class-mean, class-sigma,") ;
  print_line("         and init-step-size)" );
  print_line("--grow double") ;
  print_line("        stepsize growth factor. must be greater than 1.0") ;
  print_line("        [default 1.05]" ) ;
  print_line("--shrink double") ;
  print_line("        stepsize shrink factor ") ;
  print_line("        [default grow^(-0.25)]" ) ;
  print_line("--volume-max-iteration int") ;
  print_line("        maximal number of iterations for 3D volume correction") ;
  print_line("        [default 20]" ) ;
  print_line("--inter-slicemax-iteration int") ;
  print_line("        maximal number of iterations for each inter-slice correction") ;
  print_line("        [default 20]" ) ;
  print_line("--init-step-size double") ;
  print_line("        inital step size [default 1.02]" );
  print_line("--coefficients c(0),..,c(n)") ;
  print_line("        coefficients of the polynomial") ;
  print_line("        (used for generating bias field)") ;

  print_line("");

  print_line("example: BiasFieldEstimator --input sample.mhd") ;
  print_line("         --class-mean 1500 570") ;
  print_line("         --class-sigma 100 70 --use-log yes");
  print_line("         --input-mask sample.mask.mhd ") ;
  print_line("         --degree 3 --grow 1.05 --shrink 0.9");
  print_line("         --max-iteration 2000 --init-step-size 1.02") ;
  print_line("         --coefficients 0.056789 -1.00004 0.78945 ... -0.02345");
}

void printResult(Corrector::Pointer filter, OptionList& options)
{

  options.DumpOption("input") ;
  options.DumpOption("input-mask") ;
  options.DumpOption("class-mean") ;
  options.DumpOption("class-sigma") ;
  options.DumpOption("use-log") ;

  std::cout << " --degree " << filter->GetBiasFieldDegree() ;

  Corrector::BiasFieldType::DomainSizeType sizes =
    filter->GetBiasFieldDomainSize() ;
  std::cout << " --size " ;
  for (unsigned int i = 0 ; i < sizes.size() ; i++)
    {
      std::cout << sizes[i] << " " ;
    }

  std::cout << "--grow " << filter->GetOptimizerGrowthFactor() ;
  std::cout << " --shrink " << filter->GetOptimizerShrinkFactor() ;
  std::cout << " --volume-max-iteration " << filter->GetVolumeCorrectionMaximumIteration();
  std::cout << " --inter-slice-max-iteration " << filter->GetInterSliceCorrectionMaximumIteration();

  if (filter->IsBiasFieldMultiplicative())
    std::cout << " --init-step-size "
              << exp(filter->GetOptimizerInitialRadius()) ;
  else
    std::cout << " --init-step-size " << filter->GetOptimizerInitialRadius() ;

  std::cout << " --coefficient-length " << filter->GetNoOfBiasFieldCoefficients()
            << " --coefficients " ;

  Corrector::BiasFieldType::CoefficientArrayType coefficients =
    filter->GetEstimatedBiasFieldCoefficients() ;

  Corrector::BiasFieldType::CoefficientArrayType::iterator iter =
    coefficients.begin() ;

  while (iter != coefficients.end())
    {
      std::cout << *iter << " " ;
      iter++ ;
    }
  std::cout << std::endl ;
}

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

  if (argc <= 1)
    {
      print_usage() ;
      exit(0) ;
    }

  OptionList options(argc, argv) ;

  Corrector::Pointer filter = Corrector::New() ;

  std::string inputFileName ;
  std::string inputMaskFileName = "" ;
  bool useLog = true;
  int degree = 3;
  itk::Array<double> coefficientVector ;
  itk::Array<double> classMeans ;
  itk::Array<double> classSigmas ;
  int volumeMaximumIteration = 20;
  int interSliceMaximumIteration = 20;
  double initialRadius = 1.02;
  double grow  = 1.05;
  double shrink = pow(grow, -0.25);

  try
    {
      // get image file options
      options.GetStringOption("input", &inputFileName, true) ;
      options.GetStringOption("input-mask", &inputMaskFileName, false) ;

      // get bias field options
      useLog = options.GetBooleanOption("use-log", true, true) ;
      degree = options.GetIntOption("degree", 3, false) ;

      std::vector<double> coefficients ;
      options.GetMultiDoubleOption("coefficients", &coefficients, false) ;

      int length = coefficients.size() ;
      coefficientVector.resize(length) ;
      for (int i = 0 ; i < length ; i++)
        coefficientVector[i] = coefficients[i] ;

      // get energyfunction options
      options.GetMultiDoubleOption("class-mean", &classMeans, true) ;
      options.GetMultiDoubleOption("class-sigma", &classSigmas, true) ;

      // get optimizer options
      volumeMaximumIteration = options.GetIntOption("volume-max-iteration", 20, false) ;
      interSliceMaximumIteration = options.GetIntOption("inter-slice-max-iteration", 20, false) ;
      grow = options.GetDoubleOption("grow", 1.05, false) ;
      shrink = pow(grow, -0.25) ;
      shrink = options.GetDoubleOption("shrink", shrink, false) ;
      initialRadius = options.GetDoubleOption("init-step-size", 1.02, false) ;
    }
  catch(OptionList::RequiredOptionMissing e)
    {
      std::cout << "Error: The '" << e.OptionTag
                << "' option is required but missing."
                << std::endl ;
    }

  // load images
  ImagePointer input ;
  MaskPointer inputMask ;

  ImageReaderType::Pointer imageReader = ImageReaderType::New() ;
  MaskReaderType::Pointer maskReader = MaskReaderType::New() ;
  try
    {
      std::cout << "Loading images..." << std::endl ;
      imageReader->SetFileName(inputFileName.c_str()) ;
      imageReader->Update() ;
      input = imageReader->GetOutput() ;
      filter->SetInput(input) ;
      if (inputMaskFileName != "")
        {
          maskReader->SetFileName(inputMaskFileName.c_str()) ;
          maskReader->Update() ;
          inputMask = maskReader->GetOutput() ;
          filter->SetInputMask(inputMask) ;
        }
      std::cout << "Images loaded." << std::endl ;
    }
  catch (itk::ExceptionObject e)
    {
      e.Print(std::cout) ;
      exit(0) ;
    }

  filter->IsBiasFieldMultiplicative(useLog) ;
  filter->SetInitialBiasFieldCoefficients(coefficientVector) ;
  // sets tissue classes' statistics for creating the energy function
  filter->SetTissueClassStatistics(classMeans, classSigmas) ;
  // setting standard optimizer parameters
  filter->SetOptimizerGrowthFactor(grow) ;
  filter->SetOptimizerShrinkFactor(shrink) ;
  filter->SetVolumeCorrectionMaximumIteration(volumeMaximumIteration) ;
  filter->SetInterSliceCorrectionMaximumIteration(interSliceMaximumIteration) ;
  filter->SetOptimizerInitialRadius(initialRadius) ;
  // this member function call is not necessary since the filter's internal
  // InterSliceIntensityCorrection() member sets the bias field degree to
  // zero.
  filter->SetBiasFieldDegree(degree) ;
  // turn on inter-slice intensity correction
  filter->SetUsingInterSliceIntensityCorrection(true) ;
  // disable slab identifcation
  // the filter will think the largest possible region as the only one
  // slab.
  filter->SetUsingSlabIdentification(false) ;
  // disable 3D bias correction
  filter->SetUsingBiasFieldCorrection(true) ;
  // disable output image generation
  filter->SetGeneratingOutput(false) ;
  filter->SetSlicingDirection(2) ;

  std::cout << "Estimating the bias field..." << std::endl ;
  filter->Update() ;

  printResult(filter, options) ;

  return 0 ;
}
<commit_msg><commit_after>/*=========================================================================

Program:   Insight Segmentation & Registration Toolkit
Module:    BiasFieldEstimator.cxx
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) 2002 Insight Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

=========================================================================*/
#include <string>
#include <vector>
#include <vnl/vnl_math.h>

#include "imageutils.h"
#include "OptionList.h"
#include "itkMRIBiasFieldCorrectionFilter.h"

typedef itk::MRIBiasFieldCorrectionFilter<ImageType, ImageType, MaskType> Corrector ;

void print_usage()
{
  print_line("MRIBiasCorrection 1.0 (21.June.2001)");

  print_line("usage: BiasFieldEstimator --input file" ) ;
  print_line("       --class-mean mean(1) ... mean(i)" ) ;
  print_line("       --class-sigma sigma(1) ... sigma(i)" ) ;
  print_line("       --use-log [yes|no]") ;
  print_line("       [--input-mask file]" ) ;
  print_line("       [--degree int] [--coefficients c0,..,cn]" ) ;
  print_line("       [--growth double] [--shrink double] ") ;
  print_line("       [--volume-max-iteration int] [--inter-slice-max-iteration int]");
  print_line("       [--init-step-size double] ");

  print_line("");

  print_line("--input file") ;
  print_line("        input data set [meta image format]" );
  print_line("--class-mean mean(1),...,mean(i)" ) ;
  print_line("        intensity means  of the differen i tissue classes") ;
  print_line("--class-sigma sig(1),...,sig(i)" ) ;
  print_line("        intensity sigmas of the different i tissue clases") ;
  print_line("        NOTE: The sigmas should be listed in the SAME ORDER") ;
  print_line("              of means");
  print_line("        and each value should be SEPERATED BY A SPACE)") ;
  print_line("--input-mask file" ) ;
  print_line("        mask input with file [meta image format]");
  print_line("--degree int") ;
  print_line("        degree of legendre polynomial used for the") ;
  print_line("        approximation of the bias field" );
  print_line("--use-log [yes|no]") ;
  print_line("        if yes, assume a multiplicative bias field") ;
  print_line("        (use log of image, class-mean, class-sigma,") ;
  print_line("         and init-step-size)" );
  print_line("--grow double") ;
  print_line("        stepsize growth factor. must be greater than 1.0") ;
  print_line("        [default 1.05]" ) ;
  print_line("--shrink double") ;
  print_line("        stepsize shrink factor ") ;
  print_line("        [default grow^(-0.25)]" ) ;
  print_line("--volume-max-iteration int") ;
  print_line("        maximal number of iterations for 3D volume correction") ;
  print_line("        [default 20]" ) ;
  print_line("--inter-slicemax-iteration int") ;
  print_line("        maximal number of iterations for each inter-slice correction") ;
  print_line("        [default 20]" ) ;
  print_line("--init-step-size double") ;
  print_line("        inital step size [default 1.02]" );
  print_line("--coefficients c(0),..,c(n)") ;
  print_line("        coefficients of the polynomial") ;
  print_line("        (used for generating bias field)") ;

  print_line("");

  print_line("example: BiasFieldEstimator --input sample.mhd") ;
  print_line("         --class-mean 1500 570") ;
  print_line("         --class-sigma 100 70 --use-log yes");
  print_line("         --input-mask sample.mask.mhd ") ;
  print_line("         --degree 3 --grow 1.05 --shrink 0.9");
  print_line("         --max-iteration 2000 --init-step-size 1.02") ;
  print_line("         --coefficients 0.056789 -1.00004 0.78945 ... -0.02345");
}

void printResult(Corrector::Pointer filter, OptionList& options)
{

  options.DumpOption("input") ;
  options.DumpOption("input-mask") ;
  options.DumpOption("class-mean") ;
  options.DumpOption("class-sigma") ;
  options.DumpOption("use-log") ;

  std::cout << " --degree " << filter->GetBiasFieldDegree() ;

  Corrector::BiasFieldType::DomainSizeType sizes =
    filter->GetBiasFieldDomainSize() ;
  std::cout << " --size " ;
  for (unsigned int i = 0 ; i < sizes.size() ; i++)
    {
      std::cout << sizes[i] << " " ;
    }

  std::cout << "--grow " << filter->GetOptimizerGrowthFactor() ;
  std::cout << " --shrink " << filter->GetOptimizerShrinkFactor() ;
  std::cout << " --volume-max-iteration " << filter->GetVolumeCorrectionMaximumIteration();
  std::cout << " --inter-slice-max-iteration " << filter->GetInterSliceCorrectionMaximumIteration();

  if (filter->IsBiasFieldMultiplicative())
    std::cout << " --init-step-size "
              << exp(filter->GetOptimizerInitialRadius()) ;
  else
    std::cout << " --init-step-size " << filter->GetOptimizerInitialRadius() ;

  std::cout << " --coefficient-length " << filter->GetNoOfBiasFieldCoefficients()
            << " --coefficients " ;

  Corrector::BiasFieldType::CoefficientArrayType coefficients =
    filter->GetEstimatedBiasFieldCoefficients() ;

  Corrector::BiasFieldType::CoefficientArrayType::iterator iter =
    coefficients.begin() ;

  while (iter != coefficients.end())
    {
      std::cout << *iter << " " ;
      iter++ ;
    }
  std::cout << std::endl ;
}

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

  if (argc <= 1)
    {
      print_usage() ;
      exit(0) ;
    }

  OptionList options(argc, argv) ;

  Corrector::Pointer filter = Corrector::New() ;

  std::string inputFileName ;
  std::string inputMaskFileName = "" ;
  bool useLog = true;
  int degree = 3;
  itk::Array<double> coefficientVector ;
  itk::Array<double> classMeans ;
  itk::Array<double> classSigmas ;
  int volumeMaximumIteration = 20;
  int interSliceMaximumIteration = 20;
  double initialRadius = 1.02;
  double grow  = 1.05;
  double shrink = pow(grow, -0.25);

  try
    {
      // get image file options
      options.GetStringOption("input", &inputFileName, true) ;
      options.GetStringOption("input-mask", &inputMaskFileName, false) ;

      // get bias field options
      useLog = options.GetBooleanOption("use-log", true, true) ;
      degree = options.GetIntOption("degree", 3, false) ;

      std::vector<double> coefficients ;
      options.GetMultiDoubleOption("coefficients", &coefficients, false) ;

      int length = coefficients.size() ;
      coefficientVector.resize(length) ;
      for (int i = 0 ; i < length ; i++)
        coefficientVector[i] = coefficients[i] ;

      // get energyfunction options
      options.GetMultiDoubleOption("class-mean", &classMeans, true) ;
      options.GetMultiDoubleOption("class-sigma", &classSigmas, true) ;

      // get optimizer options
      volumeMaximumIteration = options.GetIntOption("volume-max-iteration", 20, false) ;
      interSliceMaximumIteration = options.GetIntOption("inter-slice-max-iteration", 20, false) ;
      grow = options.GetDoubleOption("grow", 1.05, false) ;
      shrink = pow(grow, -0.25) ;
      shrink = options.GetDoubleOption("shrink", shrink, false) ;
      initialRadius = options.GetDoubleOption("init-step-size", 1.02, false) ;
    }
  catch(OptionList::RequiredOptionMissing e)
    {
      std::cout << "Error: The '" << e.OptionTag
                << "' option is required but missing."
                << std::endl ;
    }

  // load images
  ImagePointer input ;
  MaskPointer inputMask ;

  ImageReaderType::Pointer imageReader = ImageReaderType::New() ;
  MaskReaderType::Pointer maskReader = MaskReaderType::New() ;
  try
    {
      std::cout << "Loading images..." << std::endl ;
      imageReader->SetFileName(inputFileName.c_str()) ;
      imageReader->Update() ;
      input = imageReader->GetOutput() ;
      filter->SetInput(input) ;
      if (inputMaskFileName != "")
        {
          maskReader->SetFileName(inputMaskFileName.c_str()) ;
          maskReader->Update() ;
          inputMask = maskReader->GetOutput() ;
          filter->SetInputMask(inputMask) ;
        }
      std::cout << "Images loaded." << std::endl ;
    }
  catch (itk::ExceptionObject e)
    {
      e.Print(std::cout) ;
      exit(0) ;
    }

  filter->IsBiasFieldMultiplicative(useLog) ;
  filter->SetInitialBiasFieldCoefficients(coefficientVector) ;
  // sets tissue classes' statistics for creating the energy function
  filter->SetTissueClassStatistics(classMeans, classSigmas) ;
  // setting standard optimizer parameters
  filter->SetOptimizerGrowthFactor(grow) ;
  filter->SetOptimizerShrinkFactor(shrink) ;
  filter->SetVolumeCorrectionMaximumIteration(volumeMaximumIteration) ;
  filter->SetInterSliceCorrectionMaximumIteration(interSliceMaximumIteration) ;
  filter->SetOptimizerInitialRadius(initialRadius) ;
  // this member function call is not necessary since the filter's internal
  // InterSliceIntensityCorrection() member sets the bias field degree to
  // zero.
  filter->SetBiasFieldDegree(degree) ;
  // turn on inter-slice intensity correction
  filter->SetUsingInterSliceIntensityCorrection(false) ;
  // disable slab identifcation
  // the filter will think the largest possible region as the only one
  // slab.
  filter->SetUsingSlabIdentification(false) ;
  // disable 3D bias correction
  filter->SetUsingBiasFieldCorrection(true) ;
  // disable output image generation
  filter->SetGeneratingOutput(false) ;
  filter->SetSlicingDirection(2) ;

  std::cout << "Estimating the bias field..." << std::endl ;
  filter->Update() ;

  printResult(filter, options) ;

  return 0 ;
}
<|endoftext|>


<commit_before>/******************************************************************************
**
** Copyright (C) 2009-2011 Kyle Lutz <kyle.r.lutz@gmail.com>
** All rights reserved.
**
** This file is a part of the chemkit project. For more information
** see <http://www.chemkit.org>.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in the
**     documentation and/or other materials provided with the distribution.
**   * Neither the name of the chemkit project nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
******************************************************************************/

#include "pluginmanager.h"

#include <map>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string/case_conv.hpp>

#include <QtCore>

#include "plugin.h"
#include "foreach.h"

namespace chemkit {

// === PluginManagerPrivate ================================================ //
class PluginManagerPrivate
{
    public:
        std::vector<Plugin *> plugins;
        std::string errorString;
        bool defaultPluginsLoaded;
        std::map<std::string, std::map<std::string, PluginManager::Function> > pluginClasses;
};

// === PluginManager ======================================================= //
/// \class PluginManager pluginmanager.h chemkit/pluginmanager.h
/// \ingroup chemkit
/// \brief The PluginManager class manages the loading and unloading
///        of plugins.
///
/// \see Plugin

// --- Construction and Destruction ---------------------------------------- //
PluginManager::PluginManager()
    : d(new PluginManagerPrivate)
{
    d->defaultPluginsLoaded = false;
}

PluginManager::~PluginManager()
{
    foreach(Plugin *plugin, d->plugins){
        delete plugin;
    }

    delete d;
}

// --- Properties ---------------------------------------------------------- //
/// Returns the plugin with \p name. Returns \c 0 if no plugin with
// \p name is loaded.
Plugin* PluginManager::plugin(const std::string &name) const
{
    foreach(Plugin *plugin, d->plugins){
        if(plugin->name() == name){
            return plugin;
        }
    }

    return 0;
}

/// Returns a list of all the loaded plugins.
const std::vector<Plugin *>& PluginManager::plugins() const
{
    return d->plugins;
}

/// Returns the number of loaded plugins.
int PluginManager::pluginCount() const
{
    return d->plugins.size();
}

// --- Plugin Loading ------------------------------------------------------ //
/// Loads a plugin from \p fileName. Returns \c false if an error
/// occurs.
bool PluginManager::loadPlugin(const std::string &fileName)
{
    QPluginLoader plugin(QString::fromStdString(fileName));

    Plugin *instance = qobject_cast<Plugin *>(plugin.instance());
    if(!instance){
        qDebug() << "Failed to load plugin (" << fileName.c_str() << "): " << plugin.errorString();
        return false;
    }

    instance->setFileName(fileName);

    d->plugins.push_back(instance);

    return true;
}

/// Loads all plugins from \p directory.
void PluginManager::loadPlugins(const std::string &directory)
{
    boost::filesystem::path dir(directory);

    if(!boost::filesystem::exists(dir)){
        return;
    }

    for(boost::filesystem::directory_iterator iter(dir); iter != boost::filesystem::directory_iterator(); ++iter){
        if(QLibrary::isLibrary(iter->path().filename().c_str())){
            loadPlugin(iter->path().string());
        }
    }
}

void PluginManager::loadDefaultPlugins()
{
    if(d->defaultPluginsLoaded){
        return;
    }

    // list of directories to load plugins from
    std::vector<std::string> directories;

    // add default plugin directory
#if defined(CHEMKIT_OS_LINUX)
    directories.push_back(CHEMKIT_INSTALL_PREFIX "/share/chemkit/plugins/");
#elif defined(CHEMKIT_OS_WIN32)
    QSettings registry("HKEY_LOCAL_MACHINE\\Software\\chemkit", QSettings::NativeFormat);
    directories.push_back(registry.value("PluginPath").toString().toStdString());
#endif

    // add directory from the CHEMKIT_PLUGIN_PATH environment variable
    QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
    std::string path = environment.value("CHEMKIT_PLUGIN_PATH").toStdString();
    if(!path.empty()){
        directories.push_back(path);
    }

    // load plugins from each directory
    foreach(const std::string &directory, directories){
        loadPlugins(directory);
    }

    d->defaultPluginsLoaded = true;
}

/// Unloads the plugin.
bool PluginManager::unloadPlugin(Plugin *plugin)
{
    return false;
}

/// Unloads the plugin with \p name.
bool PluginManager::unloadPlugin(const std::string &name)
{
    CHEMKIT_UNUSED(name);

    return false;
}

// --- Error Handling ------------------------------------------------------ //
void PluginManager::setErrorString(const std::string &errorString)
{
    d->errorString = errorString;
}

/// Returns a string describing the last error that occured.
std::string PluginManager::errorString() const
{
    return d->errorString;
}

// --- Static Methods ------------------------------------------------------ //
/// Returns the instance of the plugin manager.
PluginManager* PluginManager::instance()
{
    static PluginManager singleton;

    return &singleton;
}

// --- Internal Methods ---------------------------------------------------- //
/// Registers a new plugin function for \p className and
/// \p pluginName.
bool PluginManager::registerPluginClass(const std::string &className, const std::string &pluginName, Function function)
{
    std::map<std::string, Function> &classPlugins = d->pluginClasses[className];

    // use lower case plugin name
    std::string lowerCasePluginName = boost::algorithm::to_lower_copy(pluginName);

    // prevent overwriting of previously registered plugins
    if(classPlugins.find(lowerCasePluginName) != classPlugins.end()){
        return false;
    }

    // add plugin class
    classPlugins[lowerCasePluginName] = function;

    return true;
}

/// Unregisters a plugin function for \p className and \p pluginName.
bool PluginManager::unregisterPluginClass(const std::string &className, const std::string &pluginName)
{
    std::map<std::string, Function> &classPlugins = d->pluginClasses[className];

    // use lower case plugin name
    std::string lowerCasePluginName = boost::algorithm::to_lower_copy(pluginName);

    // remove plugin class
    return classPlugins.erase(lowerCasePluginName) > 0;
}

/// Returns a vector of strings containing the names of registered
/// plugins for \p className.
std::vector<std::string> PluginManager::pluginClassNames(const std::string &className) const
{
    // ensure default plugins are loaded
    const_cast<PluginManager *>(this)->loadDefaultPlugins();

    const std::map<std::string, Function> &classPlugins = d->pluginClasses[className];

    std::vector<std::string> names;
    for(std::map<std::string, Function>::const_iterator i = classPlugins.begin(); i != classPlugins.end(); ++i){
        names.push_back(i->first);
    }

    return names;
}

/// Returns the registered function for the given \p className and \p pluginName.
PluginManager::Function PluginManager::pluginClassFunction(const std::string &className, const std::string &pluginName) const
{
    // ensure default plugins are loaded
    const_cast<PluginManager *>(this)->loadDefaultPlugins();

    // use lower case plugin name
    std::string lowerCasePluginName = boost::algorithm::to_lower_copy(pluginName);

    const std::map<std::string, Function> &classPlugins = d->pluginClasses[className];

    std::map<std::string, Function>::const_iterator location = classPlugins.find(lowerCasePluginName);
    if(location == classPlugins.end()){
        return 0;
    }

    return location->second;
}

} // end chemkit namespace
<commit_msg>Change PluginManager to use getenv()<commit_after>/******************************************************************************
**
** Copyright (C) 2009-2011 Kyle Lutz <kyle.r.lutz@gmail.com>
** All rights reserved.
**
** This file is a part of the chemkit project. For more information
** see <http://www.chemkit.org>.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in the
**     documentation and/or other materials provided with the distribution.
**   * Neither the name of the chemkit project nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
******************************************************************************/

#include "pluginmanager.h"

#include <map>
#include <cstdlib>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string/case_conv.hpp>

#include <QtCore>

#include "plugin.h"
#include "foreach.h"

namespace chemkit {

// === PluginManagerPrivate ================================================ //
class PluginManagerPrivate
{
    public:
        std::vector<Plugin *> plugins;
        std::string errorString;
        bool defaultPluginsLoaded;
        std::map<std::string, std::map<std::string, PluginManager::Function> > pluginClasses;
};

// === PluginManager ======================================================= //
/// \class PluginManager pluginmanager.h chemkit/pluginmanager.h
/// \ingroup chemkit
/// \brief The PluginManager class manages the loading and unloading
///        of plugins.
///
/// \see Plugin

// --- Construction and Destruction ---------------------------------------- //
PluginManager::PluginManager()
    : d(new PluginManagerPrivate)
{
    d->defaultPluginsLoaded = false;
}

PluginManager::~PluginManager()
{
    foreach(Plugin *plugin, d->plugins){
        delete plugin;
    }

    delete d;
}

// --- Properties ---------------------------------------------------------- //
/// Returns the plugin with \p name. Returns \c 0 if no plugin with
// \p name is loaded.
Plugin* PluginManager::plugin(const std::string &name) const
{
    foreach(Plugin *plugin, d->plugins){
        if(plugin->name() == name){
            return plugin;
        }
    }

    return 0;
}

/// Returns a list of all the loaded plugins.
const std::vector<Plugin *>& PluginManager::plugins() const
{
    return d->plugins;
}

/// Returns the number of loaded plugins.
int PluginManager::pluginCount() const
{
    return d->plugins.size();
}

// --- Plugin Loading ------------------------------------------------------ //
/// Loads a plugin from \p fileName. Returns \c false if an error
/// occurs.
bool PluginManager::loadPlugin(const std::string &fileName)
{
    QPluginLoader plugin(QString::fromStdString(fileName));

    Plugin *instance = qobject_cast<Plugin *>(plugin.instance());
    if(!instance){
        qDebug() << "Failed to load plugin (" << fileName.c_str() << "): " << plugin.errorString();
        return false;
    }

    instance->setFileName(fileName);

    d->plugins.push_back(instance);

    return true;
}

/// Loads all plugins from \p directory.
void PluginManager::loadPlugins(const std::string &directory)
{
    boost::filesystem::path dir(directory);

    if(!boost::filesystem::exists(dir)){
        return;
    }

    for(boost::filesystem::directory_iterator iter(dir); iter != boost::filesystem::directory_iterator(); ++iter){
        if(QLibrary::isLibrary(iter->path().filename().c_str())){
            loadPlugin(iter->path().string());
        }
    }
}

void PluginManager::loadDefaultPlugins()
{
    if(d->defaultPluginsLoaded){
        return;
    }

    // list of directories to load plugins from
    std::vector<std::string> directories;

    // add default plugin directory
#if defined(CHEMKIT_OS_LINUX)
    directories.push_back(CHEMKIT_INSTALL_PREFIX "/share/chemkit/plugins/");
#elif defined(CHEMKIT_OS_WIN32)
    QSettings registry("HKEY_LOCAL_MACHINE\\Software\\chemkit", QSettings::NativeFormat);
    directories.push_back(registry.value("PluginPath").toString().toStdString());
#endif

    // add directory from the CHEMKIT_PLUGIN_PATH environment variable
    std::string path = getenv("CHEMKIT_PLUGIN_PATH");
    if(!path.empty()){
        directories.push_back(path);
    }

    // load plugins from each directory
    foreach(const std::string &directory, directories){
        loadPlugins(directory);
    }

    d->defaultPluginsLoaded = true;
}

/// Unloads the plugin.
bool PluginManager::unloadPlugin(Plugin *plugin)
{
    return false;
}

/// Unloads the plugin with \p name.
bool PluginManager::unloadPlugin(const std::string &name)
{
    CHEMKIT_UNUSED(name);

    return false;
}

// --- Error Handling ------------------------------------------------------ //
void PluginManager::setErrorString(const std::string &errorString)
{
    d->errorString = errorString;
}

/// Returns a string describing the last error that occured.
std::string PluginManager::errorString() const
{
    return d->errorString;
}

// --- Static Methods ------------------------------------------------------ //
/// Returns the instance of the plugin manager.
PluginManager* PluginManager::instance()
{
    static PluginManager singleton;

    return &singleton;
}

// --- Internal Methods ---------------------------------------------------- //
/// Registers a new plugin function for \p className and
/// \p pluginName.
bool PluginManager::registerPluginClass(const std::string &className, const std::string &pluginName, Function function)
{
    std::map<std::string, Function> &classPlugins = d->pluginClasses[className];

    // use lower case plugin name
    std::string lowerCasePluginName = boost::algorithm::to_lower_copy(pluginName);

    // prevent overwriting of previously registered plugins
    if(classPlugins.find(lowerCasePluginName) != classPlugins.end()){
        return false;
    }

    // add plugin class
    classPlugins[lowerCasePluginName] = function;

    return true;
}

/// Unregisters a plugin function for \p className and \p pluginName.
bool PluginManager::unregisterPluginClass(const std::string &className, const std::string &pluginName)
{
    std::map<std::string, Function> &classPlugins = d->pluginClasses[className];

    // use lower case plugin name
    std::string lowerCasePluginName = boost::algorithm::to_lower_copy(pluginName);

    // remove plugin class
    return classPlugins.erase(lowerCasePluginName) > 0;
}

/// Returns a vector of strings containing the names of registered
/// plugins for \p className.
std::vector<std::string> PluginManager::pluginClassNames(const std::string &className) const
{
    // ensure default plugins are loaded
    const_cast<PluginManager *>(this)->loadDefaultPlugins();

    const std::map<std::string, Function> &classPlugins = d->pluginClasses[className];

    std::vector<std::string> names;
    for(std::map<std::string, Function>::const_iterator i = classPlugins.begin(); i != classPlugins.end(); ++i){
        names.push_back(i->first);
    }

    return names;
}

/// Returns the registered function for the given \p className and \p pluginName.
PluginManager::Function PluginManager::pluginClassFunction(const std::string &className, const std::string &pluginName) const
{
    // ensure default plugins are loaded
    const_cast<PluginManager *>(this)->loadDefaultPlugins();

    // use lower case plugin name
    std::string lowerCasePluginName = boost::algorithm::to_lower_copy(pluginName);

    const std::map<std::string, Function> &classPlugins = d->pluginClasses[className];

    std::map<std::string, Function>::const_iterator location = classPlugins.find(lowerCasePluginName);
    if(location == classPlugins.end()){
        return 0;
    }

    return location->second;
}

} // end chemkit namespace
<|endoftext|>