<commit_before>#include "SkClipStack.h"
#include "SkPath.h"
#include <new>

struct SkClipStack::Rec {
    enum State {
        kEmpty_State,
        kRect_State,
        kPath_State
    };

    SkPath          fPath;
    SkRect          fRect;
    int             fSaveCount;
    SkRegion::Op    fOp;
    State           fState;

    Rec(int saveCount, const SkRect& rect, SkRegion::Op op) : fRect(rect) {
        fSaveCount = saveCount;
        fOp = op;
        fState = kRect_State;
    }

    Rec(int saveCount, const SkPath& path, SkRegion::Op op) : fPath(path) {
        fSaveCount = saveCount;
        fOp = op;
        fState = kPath_State;
    }

    bool operator==(const Rec& b) const {
        if (fSaveCount != b.fSaveCount || fOp != b.fOp || fState != b.fState) {
            return false;
        }
        switch (fState) {
            case kEmpty_State:
                return true;
            case kRect_State:
                return fRect == b.fRect;
            case kPath_State:
                return fPath == b.fPath;
        }
        return false;  // Silence the compiler.
    }

    bool operator!=(const Rec& b) const {
        return !(*this == b);
    }

    /**
     *  Returns true if this Rec can be intersected in place with a new clip
     */
    bool canBeIntersected(int saveCount, SkRegion::Op op) const {
        if (kEmpty_State == fState && (
                    SkRegion::kDifference_Op == op ||
                    SkRegion::kIntersect_Op == op)) {
            return true;
        }
        return  fSaveCount == saveCount &&
                SkRegion::kIntersect_Op == fOp &&
                SkRegion::kIntersect_Op == op;
    }
};

SkClipStack::SkClipStack() : fDeque(sizeof(Rec)) {
    fSaveCount = 0;
}

SkClipStack::SkClipStack(const SkClipStack& b) : fDeque(sizeof(Rec)) {
    *this = b;
}

SkClipStack& SkClipStack::operator=(const SkClipStack& b) {
    if (this == &b) {
        return *this;
    }
    reset();

    fSaveCount = b.fSaveCount;
    SkDeque::F2BIter recIter(b.fDeque);
    for (const Rec* rec = (const Rec*)recIter.next();
            rec != NULL;
            rec = (const Rec*)recIter.next()) {
        new (fDeque.push_back()) Rec(*rec);
    }

    return *this;
}

bool SkClipStack::operator==(const SkClipStack& b) const {
    if (fSaveCount != b.fSaveCount || fDeque.count() != b.fDeque.count()) {
        return false;
    }
    SkDeque::F2BIter myIter(fDeque);
    SkDeque::F2BIter bIter(b.fDeque);
    const Rec* myRec = (const Rec*)myIter.next();
    const Rec* bRec = (const Rec*)bIter.next();

    while (myRec != NULL && bRec != NULL) {
        if (*myRec != *bRec) {
            return false;
        }
        myRec = (const Rec*)myIter.next();
        bRec = (const Rec*)bIter.next();
    }
    return myRec == NULL && bRec == NULL;
}

void SkClipStack::reset() {
    // don't have a reset() on SkDeque, so fake it here
    fDeque.~SkDeque();
    new (&fDeque) SkDeque(sizeof(Rec));

    fSaveCount = 0;
}

void SkClipStack::save() {
    fSaveCount += 1;
}

void SkClipStack::restore() {
    fSaveCount -= 1;
    while (!fDeque.empty()) {
        Rec* rec = (Rec*)fDeque.back();
        if (rec->fSaveCount <= fSaveCount) {
            break;
        }
        rec->~Rec();
        fDeque.pop_back();
    }
}

void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op) {
    Rec* rec = (Rec*)fDeque.back();
    if (rec && rec->canBeIntersected(fSaveCount, op)) {
        switch (rec->fState) {
            case Rec::kEmpty_State:
                return;
            case Rec::kRect_State:
                if (!rec->fRect.intersect(rect)) {
                    rec->fState = Rec::kEmpty_State;
                }
                return;
            case Rec::kPath_State:
                if (!SkRect::Intersects(rec->fPath.getBounds(), rect)) {
                    rec->fState = Rec::kEmpty_State;
                    return;
                }
                break;
        }
    }
    new (fDeque.push_back()) Rec(fSaveCount, rect, op);
}

void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op) {
    Rec* rec = (Rec*)fDeque.back();
    if (rec && rec->canBeIntersected(fSaveCount, op)) {
        const SkRect& pathBounds = path.getBounds();
        switch (rec->fState) {
            case Rec::kEmpty_State:
                return;
            case Rec::kRect_State:
                if (!SkRect::Intersects(rec->fRect, pathBounds)) {
                    rec->fState = Rec::kEmpty_State;
                    return;
                }
                break;
            case Rec::kPath_State:
                if (!SkRect::Intersects(rec->fPath.getBounds(), pathBounds)) {
                    rec->fState = Rec::kEmpty_State;
                    return;
                }
                break;
        }
    }
    new (fDeque.push_back()) Rec(fSaveCount, path, op);
}

///////////////////////////////////////////////////////////////////////////////

SkClipStack::B2FIter::B2FIter() {
}

bool operator==(const SkClipStack::B2FIter::Clip& a,
               const SkClipStack::B2FIter::Clip& b) {
    return a.fOp == b.fOp &&
           ((a.fRect == NULL && b.fRect == NULL) || *a.fRect == *b.fRect) &&
           ((a.fPath == NULL && b.fPath == NULL) || *a.fPath == *b.fPath);
}

bool operator!=(const SkClipStack::B2FIter::Clip& a,
               const SkClipStack::B2FIter::Clip& b) {
    return !(a == b);
}

SkClipStack::B2FIter::B2FIter(const SkClipStack& stack) {
    this->reset(stack);
}

const SkClipStack::B2FIter::Clip* SkClipStack::B2FIter::next() {
    const SkClipStack::Rec* rec = (const SkClipStack::Rec*)fIter.next();
    if (NULL == rec) {
        return NULL;
    }

    switch (rec->fState) {
        case SkClipStack::Rec::kEmpty_State:
            fClip.fRect = NULL;
            fClip.fPath = NULL;
            break;
        case SkClipStack::Rec::kRect_State:
            fClip.fRect = &rec->fRect;
            fClip.fPath = NULL;
            break;
        case SkClipStack::Rec::kPath_State:
            fClip.fRect = NULL;
            fClip.fPath = &rec->fPath;
            break;
    }
    fClip.fOp = rec->fOp;
    return &fClip;
}

void SkClipStack::B2FIter::reset(const SkClipStack& stack) {
    fIter.reset(stack.fDeque);
}
<commit_msg>Handle possibly NULL deref in comparison<commit_after>#include "SkClipStack.h"
#include "SkPath.h"
#include <new>

struct SkClipStack::Rec {
    enum State {
        kEmpty_State,
        kRect_State,
        kPath_State
    };

    SkPath          fPath;
    SkRect          fRect;
    int             fSaveCount;
    SkRegion::Op    fOp;
    State           fState;

    Rec(int saveCount, const SkRect& rect, SkRegion::Op op) : fRect(rect) {
        fSaveCount = saveCount;
        fOp = op;
        fState = kRect_State;
    }

    Rec(int saveCount, const SkPath& path, SkRegion::Op op) : fPath(path) {
        fSaveCount = saveCount;
        fOp = op;
        fState = kPath_State;
    }

    bool operator==(const Rec& b) const {
        if (fSaveCount != b.fSaveCount || fOp != b.fOp || fState != b.fState) {
            return false;
        }
        switch (fState) {
            case kEmpty_State:
                return true;
            case kRect_State:
                return fRect == b.fRect;
            case kPath_State:
                return fPath == b.fPath;
        }
        return false;  // Silence the compiler.
    }

    bool operator!=(const Rec& b) const {
        return !(*this == b);
    }

    /**
     *  Returns true if this Rec can be intersected in place with a new clip
     */
    bool canBeIntersected(int saveCount, SkRegion::Op op) const {
        if (kEmpty_State == fState && (
                    SkRegion::kDifference_Op == op ||
                    SkRegion::kIntersect_Op == op)) {
            return true;
        }
        return  fSaveCount == saveCount &&
                SkRegion::kIntersect_Op == fOp &&
                SkRegion::kIntersect_Op == op;
    }
};

SkClipStack::SkClipStack() : fDeque(sizeof(Rec)) {
    fSaveCount = 0;
}

SkClipStack::SkClipStack(const SkClipStack& b) : fDeque(sizeof(Rec)) {
    *this = b;
}

SkClipStack& SkClipStack::operator=(const SkClipStack& b) {
    if (this == &b) {
        return *this;
    }
    reset();

    fSaveCount = b.fSaveCount;
    SkDeque::F2BIter recIter(b.fDeque);
    for (const Rec* rec = (const Rec*)recIter.next();
            rec != NULL;
            rec = (const Rec*)recIter.next()) {
        new (fDeque.push_back()) Rec(*rec);
    }

    return *this;
}

bool SkClipStack::operator==(const SkClipStack& b) const {
    if (fSaveCount != b.fSaveCount || fDeque.count() != b.fDeque.count()) {
        return false;
    }
    SkDeque::F2BIter myIter(fDeque);
    SkDeque::F2BIter bIter(b.fDeque);
    const Rec* myRec = (const Rec*)myIter.next();
    const Rec* bRec = (const Rec*)bIter.next();

    while (myRec != NULL && bRec != NULL) {
        if (*myRec != *bRec) {
            return false;
        }
        myRec = (const Rec*)myIter.next();
        bRec = (const Rec*)bIter.next();
    }
    return myRec == NULL && bRec == NULL;
}

void SkClipStack::reset() {
    // don't have a reset() on SkDeque, so fake it here
    fDeque.~SkDeque();
    new (&fDeque) SkDeque(sizeof(Rec));

    fSaveCount = 0;
}

void SkClipStack::save() {
    fSaveCount += 1;
}

void SkClipStack::restore() {
    fSaveCount -= 1;
    while (!fDeque.empty()) {
        Rec* rec = (Rec*)fDeque.back();
        if (rec->fSaveCount <= fSaveCount) {
            break;
        }
        rec->~Rec();
        fDeque.pop_back();
    }
}

void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op) {
    Rec* rec = (Rec*)fDeque.back();
    if (rec && rec->canBeIntersected(fSaveCount, op)) {
        switch (rec->fState) {
            case Rec::kEmpty_State:
                return;
            case Rec::kRect_State:
                if (!rec->fRect.intersect(rect)) {
                    rec->fState = Rec::kEmpty_State;
                }
                return;
            case Rec::kPath_State:
                if (!SkRect::Intersects(rec->fPath.getBounds(), rect)) {
                    rec->fState = Rec::kEmpty_State;
                    return;
                }
                break;
        }
    }
    new (fDeque.push_back()) Rec(fSaveCount, rect, op);
}

void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op) {
    Rec* rec = (Rec*)fDeque.back();
    if (rec && rec->canBeIntersected(fSaveCount, op)) {
        const SkRect& pathBounds = path.getBounds();
        switch (rec->fState) {
            case Rec::kEmpty_State:
                return;
            case Rec::kRect_State:
                if (!SkRect::Intersects(rec->fRect, pathBounds)) {
                    rec->fState = Rec::kEmpty_State;
                    return;
                }
                break;
            case Rec::kPath_State:
                if (!SkRect::Intersects(rec->fPath.getBounds(), pathBounds)) {
                    rec->fState = Rec::kEmpty_State;
                    return;
                }
                break;
        }
    }
    new (fDeque.push_back()) Rec(fSaveCount, path, op);
}

///////////////////////////////////////////////////////////////////////////////

SkClipStack::B2FIter::B2FIter() {
}

bool operator==(const SkClipStack::B2FIter::Clip& a,
               const SkClipStack::B2FIter::Clip& b) {
    return a.fOp == b.fOp &&
           ((a.fRect == NULL && b.fRect == NULL) ||
               (a.fRect != NULL && b.fRect != NULL && *a.fRect == *b.fRect)) &&
           ((a.fPath == NULL && b.fPath == NULL) ||
               (a.fPath != NULL && b.fPath != NULL && *a.fPath == *b.fPath));
}

bool operator!=(const SkClipStack::B2FIter::Clip& a,
               const SkClipStack::B2FIter::Clip& b) {
    return !(a == b);
}

SkClipStack::B2FIter::B2FIter(const SkClipStack& stack) {
    this->reset(stack);
}

const SkClipStack::B2FIter::Clip* SkClipStack::B2FIter::next() {
    const SkClipStack::Rec* rec = (const SkClipStack::Rec*)fIter.next();
    if (NULL == rec) {
        return NULL;
    }

    switch (rec->fState) {
        case SkClipStack::Rec::kEmpty_State:
            fClip.fRect = NULL;
            fClip.fPath = NULL;
            break;
        case SkClipStack::Rec::kRect_State:
            fClip.fRect = &rec->fRect;
            fClip.fPath = NULL;
            break;
        case SkClipStack::Rec::kPath_State:
            fClip.fRect = NULL;
            fClip.fPath = &rec->fPath;
            break;
    }
    fClip.fOp = rec->fOp;
    return &fClip;
}

void SkClipStack::B2FIter::reset(const SkClipStack& stack) {
    fIter.reset(stack.fDeque);
}
<|endoftext|>


<commit_before>#ifndef MJOLNIR_CORE_TOPOLOGY_HPP
#define MJOLNIR_CORE_TOPOLOGY_HPP
#include <mjolnir/util/throw_exception.hpp>
#include <utility>
#include <algorithm>
#include <stdexcept>
#include <string>
#include <vector>

namespace mjolnir
{

// XXX Topology class manages the connections between beads.
//
// NOTE: connection kind "bond" is used to determine the molecules.
//       Other kind of connections also can be defined (and overlayed
//       if nessesary). In that case, you can traverse the graph by using
//       your connection kind also, but it will not be considered when
//       it detemines "molecule"s.
//
// Most of the time, "molecule" defined by this class is equivalent to "chain".
// But calling "molecule" as "chain" is misreading because there can be a
// circular molecule or tiny molecule that only has a few number of beads.
// For example, lipid membrane is composed of a large number of lipid molecules
// and people useally does not call each lipid as "chain".
//
// Generally, traversing graph takes time rather than finding value from
// contiguous container. So there are ExclusionList class that stores the
// information for NeighborLists (usually, nonlocal potentials are ignored if
// the two particles are connected by covarent bond). While the simulation,
// ExclusionLists would be called many time, but Topology would only be called
// to construct ExclusionList at the beginning ofjthe simulation.
//
// Since the members of this class are rarely called, in most cases, the speed
// of these methods does not affect to the overall efficiency.class Topology
class Topology
{
  public:

    using molecule_id_type     = std::size_t;
    using group_id_type        = std::string;
    using name_type            = std::string;
    using connection_kind_type = std::string;
    using edge_type            = std::pair<std::size_t, connection_kind_type>;

    static constexpr molecule_id_type uninitialized() noexcept
    {
        return std::numeric_limits<molecule_id_type>::max();
    }

    struct node
    {
        std::size_t molecule_id;
        std::vector<edge_type> adjacents;
    };

  public:

    Topology()  = default;
    ~Topology() = default;
    Topology(const Topology&) = default;
    Topology(Topology&&)      = default;
    Topology& operator=(const Topology&) = default;
    Topology& operator=(Topology&&)      = default;

    explicit Topology(const std::size_t N)
        : num_molecules_(1), nodes_(N, node{uninitialized(), {}})
    {}

    bool        empty() const noexcept {return nodes_.empty();}
    std::size_t size()  const noexcept {return nodes_.size();}
    void clear()
    {
        std::fill(nodes_.begin(), nodes_.end(), node{uninitialized(), {}});
        return ;
    }

    molecule_id_type  molecule_of(const std::size_t i) const
    {return nodes_.at(i).molecule_id;}
    molecule_id_type& molecule_of(const std::size_t i)
    {return nodes_.at(i).molecule_id;}

    molecule_id_type  molecule_of(const std::size_t i, const std::nothrow_t&) const
    {return nodes_[i].molecule_id;}
    molecule_id_type& molecule_of(const std::size_t i, const std::nothrow_t&)
    {return nodes_[i].molecule_id;}

    void add_connection  (const std::size_t i, const std::size_t j,
                          const connection_kind_type& kind);
    void erase_connection(const std::size_t i, const std::size_t j,
                          const connection_kind_type& kind);
    bool has_connection  (const std::size_t i, const std::size_t j,
                          const connection_kind_type& kind);
    // has_connection returns true if i == j.

    std::vector<std::size_t>
    list_adjacent_within(const std::size_t node_idx, const std::size_t dist,
                         const connection_kind_type& kind) const;

    std::vector<connection_kind_type>
    list_connections_between(const std::size_t i, const std::size_t j) const;

    //! reset molecule_id of all the particles
    void construct_molecules();
    void resize(const std::size_t N) {nodes_.resize(N); return;}

    std::size_t number_of_molecules() const noexcept {return this->num_molecules_;}

    bool operator==(const Topology& other) const
    {
        return this->nodes_ == other.nodes_ &&
               this->num_molecules_ == other.num_molecules_;
    }
    bool operator!=(const Topology& other) const
    {
        return !(*this == other);
    }

  private:

    void list_adjacent_within(
        const std::size_t node_idx, const std::size_t dist,
        const connection_kind_type& kind, std::vector<std::size_t>& out) const
    {
        if(dist == 0)
        {
            out.push_back(node_idx);
            return;
        }

        for(auto edge : this->nodes_.at(node_idx).adjacents)
        {
            if(edge.second != kind)
            {
                continue;
            }
            out.push_back(edge.first);
            this->list_adjacent_within(edge.first, dist-1, kind, out);
        }
        return;
    }

  private:
    // each node corresponds to the particle having the same idx in a system.
    std::size_t       num_molecules_;
    std::vector<node> nodes_;
};

inline void Topology::add_connection(
        const std::size_t i, const std::size_t j,
        const connection_kind_type& kind)
{
    if(nodes_.size() <= std::max(i, j))
    {
        throw_exception<std::out_of_range>(
            "mjolnir::Topology::add_connection: size of nodes = ",
            nodes_.size(), ", i = ", i, ", j = ", j);
    }

    {
        const edge_type edge = std::make_pair(j, kind);

        auto& adjs = nodes_[i].adjacents;
        if(std::find(adjs.cbegin(), adjs.cend(), edge) == adjs.cend())
        {
            adjs.push_back(edge);
        }
    }
    {
        const edge_type edge = std::make_pair(i, kind);

        auto& adjs = nodes_[j].adjacents;
        if(std::find(adjs.cbegin(), adjs.cend(), edge) == adjs.cend())
        {
            adjs.push_back(edge);
        }
    }
    return ;
}

inline void Topology::erase_connection(
        const std::size_t i, const std::size_t j,
        const connection_kind_type& kind)
{
    if(nodes_.size() <= std::max(i, j))
    {
        throw_exception<std::out_of_range>(
            "mjolnir::Topology::erase_connection: size of nodes = ",
            nodes_.size(), ", i = ", i, ", j = ", j);
    }

    {
        auto& adjs = nodes_[i].adjacents;
        const auto found = std::find(
                adjs.begin(), adjs.end(), std::make_pair(j, kind));
        if(found != adjs.end())
        {
            adjs.erase(found);
        }
    }
    {
        auto& adjs = nodes_[j].adjacents;
        const auto found = std::find(
                adjs.begin(), adjs.end(), std::make_pair(i, kind));
        if(found != adjs.end())
        {
            adjs.erase(found);
        }
    }
    return ;
}

inline bool Topology::has_connection(
        const std::size_t i, const std::size_t j,
        const connection_kind_type& kind)
{
    if(nodes_.size() <= std::max(i, j))
    {
        throw_exception<std::out_of_range>(
            "mjolnir::Topology::has_connection: size of nodes = ",
            nodes_.size(), ", i = ", i, ", j = ", j);
    }
    if(i == j) {return true;} // XXX

    const auto& adjs = nodes_[i].adjacents;
    const auto found =
        std::find(adjs.cbegin(), adjs.cend(), std::make_pair(j, kind));
    return found != adjs.cend();
}

inline std::vector<std::size_t>
Topology::list_adjacent_within(
        const std::size_t node_idx, const std::size_t dist,
        const connection_kind_type& kind) const
{
    std::vector<std::size_t> retval = {node_idx};
    if(dist == 0) {return retval;}

    for(auto edge : this->nodes_.at(node_idx).adjacents)
    {
        if(edge.second != kind)
        {
            continue;
        }
        retval.push_back(edge.first);
        this->list_adjacent_within(edge.first, dist - 1, kind, retval);
    }
    std::sort(retval.begin(), retval.end());
    const auto new_end = std::unique(retval.begin(), retval.end());
    retval.erase(new_end, retval.end());
    return retval;
}

inline std::vector<typename Topology::connection_kind_type>
Topology::list_connections_between(const std::size_t i, const std::size_t j) const
{
    std::vector<connection_kind_type> connections;
    for(const auto& edge : this->nodes_.at(i).adjacents)
    {
        if(edge.first == j)
        {
            connections.push_back(edge.second);
        }
    }
    return connections;
}

inline void
Topology::construct_molecules()
{
    if(this->nodes_.empty()){return;}
    // reset molecule-ids
    for(auto& node : nodes_)
    {
        node.molecule_id = uninitialized();
    }

    molecule_id_type next_molecule_id = 0;
    for(auto& node : nodes_)
    {
        // look all the adjacents and update node by their molecule id
        for(const auto& edge : node.adjacents)
        {
            // ignore all the edges that are not bonds
            if(edge.second != "bond") {continue;}

            // if an adjacent that is connected by a "bond",
            // it should be in the same molecule.
            const auto& adj = this->nodes_.at(edge.first);
            if(adj.molecule_id != uninitialized())
            {
                node.molecule_id = adj.molecule_id;
                break;
            }
        }
        // if the molecule_id of this node is still not initialized, that means
        // this node belongs to a new molecule.
        if(node.molecule_id == uninitialized())
        {
            node.molecule_id = next_molecule_id++;
        }
    }
    this->num_molecules_ = next_molecule_id;
    return;
}

} // mjolnir
#endif// MJOLNIR_STRUCTURE_TOPOLOGY_H
<commit_msg>fix: add comparison operators to Topology::node<commit_after>#ifndef MJOLNIR_CORE_TOPOLOGY_HPP
#define MJOLNIR_CORE_TOPOLOGY_HPP
#include <mjolnir/util/throw_exception.hpp>
#include <utility>
#include <algorithm>
#include <stdexcept>
#include <string>
#include <vector>

namespace mjolnir
{

// XXX Topology class manages the connections between beads.
//
// NOTE: connection kind "bond" is used to determine the molecules.
//       Other kind of connections also can be defined (and overlayed
//       if nessesary). In that case, you can traverse the graph by using
//       your connection kind also, but it will not be considered when
//       it detemines "molecule"s.
//
// Most of the time, "molecule" defined by this class is equivalent to "chain".
// But calling "molecule" as "chain" is misreading because there can be a
// circular molecule or tiny molecule that only has a few number of beads.
// For example, lipid membrane is composed of a large number of lipid molecules
// and people useally does not call each lipid as "chain".
//
// Generally, traversing graph takes time rather than finding value from
// contiguous container. So there are ExclusionList class that stores the
// information for NeighborLists (usually, nonlocal potentials are ignored if
// the two particles are connected by covarent bond). While the simulation,
// ExclusionLists would be called many time, but Topology would only be called
// to construct ExclusionList at the beginning ofjthe simulation.
//
// Since the members of this class are rarely called, in most cases, the speed
// of these methods does not affect to the overall efficiency.class Topology
class Topology
{
  public:

    using molecule_id_type     = std::size_t;
    using group_id_type        = std::string;
    using name_type            = std::string;
    using connection_kind_type = std::string;
    using edge_type            = std::pair<std::size_t, connection_kind_type>;

    static constexpr molecule_id_type uninitialized() noexcept
    {
        return std::numeric_limits<molecule_id_type>::max();
    }

    struct node
    {
        std::size_t molecule_id;
        std::vector<edge_type> adjacents;

        bool operator==(const node& other) const
        {
            return molecule_id == other.molecule_id &&
                   adjacents   == other.adjacents;
        }
        bool operator!=(const node& other) const
        {
            return !(*this == other);
        }
    };

  public:

    Topology()  = default;
    ~Topology() = default;
    Topology(const Topology&) = default;
    Topology(Topology&&)      = default;
    Topology& operator=(const Topology&) = default;
    Topology& operator=(Topology&&)      = default;

    explicit Topology(const std::size_t N)
        : num_molecules_(1), nodes_(N, node{uninitialized(), {}})
    {}

    bool        empty() const noexcept {return nodes_.empty();}
    std::size_t size()  const noexcept {return nodes_.size();}
    void clear()
    {
        std::fill(nodes_.begin(), nodes_.end(), node{uninitialized(), {}});
        return ;
    }

    molecule_id_type  molecule_of(const std::size_t i) const
    {return nodes_.at(i).molecule_id;}
    molecule_id_type& molecule_of(const std::size_t i)
    {return nodes_.at(i).molecule_id;}

    molecule_id_type  molecule_of(const std::size_t i, const std::nothrow_t&) const
    {return nodes_[i].molecule_id;}
    molecule_id_type& molecule_of(const std::size_t i, const std::nothrow_t&)
    {return nodes_[i].molecule_id;}

    void add_connection  (const std::size_t i, const std::size_t j,
                          const connection_kind_type& kind);
    void erase_connection(const std::size_t i, const std::size_t j,
                          const connection_kind_type& kind);
    bool has_connection  (const std::size_t i, const std::size_t j,
                          const connection_kind_type& kind);
    // has_connection returns true if i == j.

    std::vector<std::size_t>
    list_adjacent_within(const std::size_t node_idx, const std::size_t dist,
                         const connection_kind_type& kind) const;

    std::vector<connection_kind_type>
    list_connections_between(const std::size_t i, const std::size_t j) const;

    //! reset molecule_id of all the particles
    void construct_molecules();
    void resize(const std::size_t N) {nodes_.resize(N); return;}

    std::size_t number_of_molecules() const noexcept {return this->num_molecules_;}

    bool operator==(const Topology& other) const
    {
        return this->nodes_ == other.nodes_ &&
               this->num_molecules_ == other.num_molecules_;
    }
    bool operator!=(const Topology& other) const
    {
        return !(*this == other);
    }

  private:

    void list_adjacent_within(
        const std::size_t node_idx, const std::size_t dist,
        const connection_kind_type& kind, std::vector<std::size_t>& out) const
    {
        if(dist == 0)
        {
            out.push_back(node_idx);
            return;
        }

        for(auto edge : this->nodes_.at(node_idx).adjacents)
        {
            if(edge.second != kind)
            {
                continue;
            }
            out.push_back(edge.first);
            this->list_adjacent_within(edge.first, dist-1, kind, out);
        }
        return;
    }

  private:
    // each node corresponds to the particle having the same idx in a system.
    std::size_t       num_molecules_;
    std::vector<node> nodes_;
};

inline void Topology::add_connection(
        const std::size_t i, const std::size_t j,
        const connection_kind_type& kind)
{
    if(nodes_.size() <= std::max(i, j))
    {
        throw_exception<std::out_of_range>(
            "mjolnir::Topology::add_connection: size of nodes = ",
            nodes_.size(), ", i = ", i, ", j = ", j);
    }

    {
        const edge_type edge = std::make_pair(j, kind);

        auto& adjs = nodes_[i].adjacents;
        if(std::find(adjs.cbegin(), adjs.cend(), edge) == adjs.cend())
        {
            adjs.push_back(edge);
        }
    }
    {
        const edge_type edge = std::make_pair(i, kind);

        auto& adjs = nodes_[j].adjacents;
        if(std::find(adjs.cbegin(), adjs.cend(), edge) == adjs.cend())
        {
            adjs.push_back(edge);
        }
    }
    return ;
}

inline void Topology::erase_connection(
        const std::size_t i, const std::size_t j,
        const connection_kind_type& kind)
{
    if(nodes_.size() <= std::max(i, j))
    {
        throw_exception<std::out_of_range>(
            "mjolnir::Topology::erase_connection: size of nodes = ",
            nodes_.size(), ", i = ", i, ", j = ", j);
    }

    {
        auto& adjs = nodes_[i].adjacents;
        const auto found = std::find(
                adjs.begin(), adjs.end(), std::make_pair(j, kind));
        if(found != adjs.end())
        {
            adjs.erase(found);
        }
    }
    {
        auto& adjs = nodes_[j].adjacents;
        const auto found = std::find(
                adjs.begin(), adjs.end(), std::make_pair(i, kind));
        if(found != adjs.end())
        {
            adjs.erase(found);
        }
    }
    return ;
}

inline bool Topology::has_connection(
        const std::size_t i, const std::size_t j,
        const connection_kind_type& kind)
{
    if(nodes_.size() <= std::max(i, j))
    {
        throw_exception<std::out_of_range>(
            "mjolnir::Topology::has_connection: size of nodes = ",
            nodes_.size(), ", i = ", i, ", j = ", j);
    }
    if(i == j) {return true;} // XXX

    const auto& adjs = nodes_[i].adjacents;
    const auto found =
        std::find(adjs.cbegin(), adjs.cend(), std::make_pair(j, kind));
    return found != adjs.cend();
}

inline std::vector<std::size_t>
Topology::list_adjacent_within(
        const std::size_t node_idx, const std::size_t dist,
        const connection_kind_type& kind) const
{
    std::vector<std::size_t> retval = {node_idx};
    if(dist == 0) {return retval;}

    for(auto edge : this->nodes_.at(node_idx).adjacents)
    {
        if(edge.second != kind)
        {
            continue;
        }
        retval.push_back(edge.first);
        this->list_adjacent_within(edge.first, dist - 1, kind, retval);
    }
    std::sort(retval.begin(), retval.end());
    const auto new_end = std::unique(retval.begin(), retval.end());
    retval.erase(new_end, retval.end());
    return retval;
}

inline std::vector<typename Topology::connection_kind_type>
Topology::list_connections_between(const std::size_t i, const std::size_t j) const
{
    std::vector<connection_kind_type> connections;
    for(const auto& edge : this->nodes_.at(i).adjacents)
    {
        if(edge.first == j)
        {
            connections.push_back(edge.second);
        }
    }
    return connections;
}

inline void
Topology::construct_molecules()
{
    if(this->nodes_.empty()){return;}
    // reset molecule-ids
    for(auto& node : nodes_)
    {
        node.molecule_id = uninitialized();
    }

    molecule_id_type next_molecule_id = 0;
    for(auto& node : nodes_)
    {
        // look all the adjacents and update node by their molecule id
        for(const auto& edge : node.adjacents)
        {
            // ignore all the edges that are not bonds
            if(edge.second != "bond") {continue;}

            // if an adjacent that is connected by a "bond",
            // it should be in the same molecule.
            const auto& adj = this->nodes_.at(edge.first);
            if(adj.molecule_id != uninitialized())
            {
                node.molecule_id = adj.molecule_id;
                break;
            }
        }
        // if the molecule_id of this node is still not initialized, that means
        // this node belongs to a new molecule.
        if(node.molecule_id == uninitialized())
        {
            node.molecule_id = next_molecule_id++;
        }
    }
    this->num_molecules_ = next_molecule_id;
    return;
}

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


<commit_before>/*
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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
 *
 * binwrap.cpp - Binary I/O wrapper, using standard iostreams library
 * Copyright (C) 2002, 2003 Simon Peter <dn.tlp@gmx.net>
 */

#include "binwrap.h"

#if BINIO_ENABLE_IOSTREAM

/***** biniwstream *****/

biniwstream::biniwstream(istream *istr)
  : in(istr)
{
}

biniwstream::~biniwstream()
{
}

void biniwstream::seek(long pos, Offset offs)
{
  if(!in) { err = NotOpen; return; }

  switch(offs) {
  case Set: in->seekg(pos, ios::beg); break;
  case Add: in->seekg(pos, ios::cur); break;
  case End: in->seekg(pos, ios::end); break;
  }
}

biniwstream::Byte biniwstream::getByte()
{
  if(!in) { err = NotOpen; return 0; }

  int i = in->get();
  if(i == EOF) err |= Eof;
  return (Byte)i;
}

long biniwstream::pos()
{
  if(!in) { err = NotOpen; return 0; }
  return (long)in->tellg();
}

/***** binowstream *****/

binowstream::binowstream(ostream *ostr)
  : out(ostr)
{
}

binowstream::~binowstream()
{
}

void binowstream::seek(long pos, Offset offs)
{
  if(!out) { err = NotOpen; return; }

  switch(offs) {
  case Set: out->seekp(pos, ios::beg); break;
  case Add: out->seekp(pos, ios::cur); break;
  case End: out->seekp(pos, ios::end); break;
  }
}

void binowstream::putByte(binio::Byte b)
{
  if(!out) { err = NotOpen; return; }
  out->put((char)b);
}

long binowstream::pos()
{
  if(!out) { err = NotOpen; return 0; }
  return (long)out->tellp();
}

/***** binwstream *****/

binwstream::binwstream(iostream *str)
  : biniwstream(str), binowstream(str), io(str)
{
}

binwstream::~binwstream()
{
}

void binwstream::seek(long pos, Offset offs)
{
  biniwstream::seek(pos, offs);
  binowstream::seek(pos, offs);
}

long binwstream::pos()
{
  if(!io) { err = NotOpen; return 0; }
  return (long)io->tellg();
}

binwstream::Byte binwstream::getByte()
{
  Byte in = biniwstream::getByte();
  binowstream::seek(biniwstream::pos(), Set);	// sync stream position
  return in;
}

void binwstream::putByte(Byte b)
{
  binowstream::putByte(b);
  biniwstream::seek(binowstream::pos(), Set);	// sync stream position
}

#endif
<commit_msg>G++ 4.4 has EOF defined only in cstdio. Use istream::eof() method instead of EOF returned from istream::getc().<commit_after>/*
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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
 *
 * binwrap.cpp - Binary I/O wrapper, using standard iostreams library
 * Copyright (C) 2002, 2003, 2009 Simon Peter <dn.tlp@gmx.net>
 */

#include "binwrap.h"

#if BINIO_ENABLE_IOSTREAM

/***** biniwstream *****/

biniwstream::biniwstream(istream *istr)
  : in(istr)
{
}

biniwstream::~biniwstream()
{
}

void biniwstream::seek(long pos, Offset offs)
{
  if(!in) { err = NotOpen; return; }

  switch(offs) {
  case Set: in->seekg(pos, ios::beg); break;
  case Add: in->seekg(pos, ios::cur); break;
  case End: in->seekg(pos, ios::end); break;
  }
}

biniwstream::Byte biniwstream::getByte()
{
  if(!in) { err = NotOpen; return 0; }

  if(!in->eof()) {
    return (Byte)in->get();
  } else {
    err |= Eof;
    return 0;
  }
}

long biniwstream::pos()
{
  if(!in) { err = NotOpen; return 0; }
  return (long)in->tellg();
}

/***** binowstream *****/

binowstream::binowstream(ostream *ostr)
  : out(ostr)
{
}

binowstream::~binowstream()
{
}

void binowstream::seek(long pos, Offset offs)
{
  if(!out) { err = NotOpen; return; }

  switch(offs) {
  case Set: out->seekp(pos, ios::beg); break;
  case Add: out->seekp(pos, ios::cur); break;
  case End: out->seekp(pos, ios::end); break;
  }
}

void binowstream::putByte(binio::Byte b)
{
  if(!out) { err = NotOpen; return; }
  out->put((char)b);
}

long binowstream::pos()
{
  if(!out) { err = NotOpen; return 0; }
  return (long)out->tellp();
}

/***** binwstream *****/

binwstream::binwstream(iostream *str)
  : biniwstream(str), binowstream(str), io(str)
{
}

binwstream::~binwstream()
{
}

void binwstream::seek(long pos, Offset offs)
{
  biniwstream::seek(pos, offs);
  binowstream::seek(pos, offs);
}

long binwstream::pos()
{
  if(!io) { err = NotOpen; return 0; }
  return (long)io->tellg();
}

binwstream::Byte binwstream::getByte()
{
  Byte in = biniwstream::getByte();
  binowstream::seek(biniwstream::pos(), Set);	// sync stream position
  return in;
}

void binwstream::putByte(Byte b)
{
  binowstream::putByte(b);
  biniwstream::seek(binowstream::pos(), Set);	// sync stream position
}

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/proxy/proxy_resolver_winhttp.h"

#include <windows.h>
#include <winhttp.h>

#include "base/histogram.h"
#include "net/base/net_errors.h"

#pragma comment(lib, "winhttp.lib")

namespace net {

// A small wrapper for histogramming purposes ;-)
static BOOL CallWinHttpGetProxyForUrl(HINTERNET session, LPCWSTR url,
                                      WINHTTP_AUTOPROXY_OPTIONS* options,
                                      WINHTTP_PROXY_INFO* results) {
  TimeTicks time_start = TimeTicks::Now();
  BOOL rv = WinHttpGetProxyForUrl(session, url, options, results);
  TimeDelta time_delta = TimeTicks::Now() - time_start;
  // Record separately success and failure times since they will have very
  // different characteristics.
  if (rv) {
    UMA_HISTOGRAM_LONG_TIMES(L"Net.GetProxyForUrl_OK", time_delta);
  } else {
    UMA_HISTOGRAM_LONG_TIMES(L"Net.GetProxyForUrl_FAIL", time_delta);
  }
  return rv;
}

static void FreeConfig(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* config) {
  if (config->lpszAutoConfigUrl)
    GlobalFree(config->lpszAutoConfigUrl);
  if (config->lpszProxy)
    GlobalFree(config->lpszProxy);
  if (config->lpszProxyBypass)
    GlobalFree(config->lpszProxyBypass);
}

static void FreeInfo(WINHTTP_PROXY_INFO* info) {
  if (info->lpszProxy)
    GlobalFree(info->lpszProxy);
  if (info->lpszProxyBypass)
    GlobalFree(info->lpszProxyBypass);
}

ProxyResolverWinHttp::ProxyResolverWinHttp()
    : session_handle_(NULL) {
}

ProxyResolverWinHttp::~ProxyResolverWinHttp() {
  CloseWinHttpSession();
}

int ProxyResolverWinHttp::GetProxyConfig(ProxyConfig* config) {
  WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_config = {0};
  if (!WinHttpGetIEProxyConfigForCurrentUser(&ie_config)) {
    LOG(ERROR) << "WinHttpGetIEProxyConfigForCurrentUser failed: " <<
        GetLastError();
    return ERR_FAILED;  // TODO(darin): Bug 1189288: translate error code.
  }

  if (ie_config.fAutoDetect)
    config->auto_detect = true;
  if (ie_config.lpszProxy)
    config->proxy_server = WideToASCII(ie_config.lpszProxy);
  if (ie_config.lpszProxyBypass)
    config->proxy_bypass = WideToASCII(ie_config.lpszProxyBypass);
  if (ie_config.lpszAutoConfigUrl)
    config->pac_url = WideToASCII(ie_config.lpszAutoConfigUrl);

  FreeConfig(&ie_config);
  return OK;
}

int ProxyResolverWinHttp::GetProxyForURL(const std::string& query_url,
                                         const std::string& pac_url,
                                         ProxyInfo* results) {
  // If we don't have a WinHTTP session, then create a new one.
  if (!session_handle_ && !OpenWinHttpSession())
    return ERR_FAILED;

  // If we have been given an empty PAC url, then use auto-detection.
  //
  // NOTE: We just use DNS-based auto-detection here like Firefox.  We do this
  // to avoid WinHTTP's auto-detection code, which while more featureful (it
  // supports DHCP based auto-detection) also appears to have issues.
  //
  WINHTTP_AUTOPROXY_OPTIONS options = {0};
  options.fAutoLogonIfChallenged = TRUE;
  options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
  options.lpszAutoConfigUrl =
      pac_url.empty() ? L"http://wpad/wpad.dat" : ASCIIToWide(pac_url).c_str();

  WINHTTP_PROXY_INFO info = {0};
  DCHECK(session_handle_);
  if (!CallWinHttpGetProxyForUrl(
          session_handle_, ASCIIToWide(query_url).c_str(), &options, &info)) {
    DWORD error = GetLastError();
    LOG(ERROR) << "WinHttpGetProxyForUrl failed: " << error;

    // If we got here because of RPC timeout during out of process PAC
    // resolution, no further requests on this session are going to work.
    if ((ERROR_WINHTTP_TIMEOUT == error) ||
        (ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR == error)) {
      CloseWinHttpSession();
    }

    return ERR_FAILED;  // TODO(darin): Bug 1189288: translate error code.
  }

  int rv = OK;

  switch (info.dwAccessType) {
    case WINHTTP_ACCESS_TYPE_NO_PROXY:
      results->UseDirect();
      break;
    case WINHTTP_ACCESS_TYPE_NAMED_PROXY:
      results->UseNamedProxy(WideToASCII(info.lpszProxy));
      break;
    default:
      NOTREACHED();
      rv = ERR_FAILED;
  }

  FreeInfo(&info);
  return rv;
}

bool ProxyResolverWinHttp::OpenWinHttpSession() {
  DCHECK(!session_handle_);
  session_handle_ = WinHttpOpen(NULL,
                                WINHTTP_ACCESS_TYPE_NO_PROXY,
                                WINHTTP_NO_PROXY_NAME,
                                WINHTTP_NO_PROXY_BYPASS,
                                0);
  if (!session_handle_)
    return false;

  // Since this session handle will never be used for WinHTTP connections,
  // these timeouts don't really mean much individually.  However, WinHTTP's
  // out of process PAC resolution will use a combined (sum of all timeouts)
  // value to wait for an RPC reply.
  BOOL rv = WinHttpSetTimeouts(session_handle_, 10000, 10000, 5000, 5000);
  DCHECK(rv);

  return true;
}

void ProxyResolverWinHttp::CloseWinHttpSession() {
  if (session_handle_) {
    WinHttpCloseHandle(session_handle_);
    session_handle_ = NULL;
  }
}

}  // namespace net

<commit_msg>Fix proxy code. The pac string was corrupted when a pac file was specified.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/proxy/proxy_resolver_winhttp.h"

#include <windows.h>
#include <winhttp.h>

#include "base/histogram.h"
#include "net/base/net_errors.h"

#pragma comment(lib, "winhttp.lib")

namespace net {

// A small wrapper for histogramming purposes ;-)
static BOOL CallWinHttpGetProxyForUrl(HINTERNET session, LPCWSTR url,
                                      WINHTTP_AUTOPROXY_OPTIONS* options,
                                      WINHTTP_PROXY_INFO* results) {
  TimeTicks time_start = TimeTicks::Now();
  BOOL rv = WinHttpGetProxyForUrl(session, url, options, results);
  TimeDelta time_delta = TimeTicks::Now() - time_start;
  // Record separately success and failure times since they will have very
  // different characteristics.
  if (rv) {
    UMA_HISTOGRAM_LONG_TIMES(L"Net.GetProxyForUrl_OK", time_delta);
  } else {
    UMA_HISTOGRAM_LONG_TIMES(L"Net.GetProxyForUrl_FAIL", time_delta);
  }
  return rv;
}

static void FreeConfig(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* config) {
  if (config->lpszAutoConfigUrl)
    GlobalFree(config->lpszAutoConfigUrl);
  if (config->lpszProxy)
    GlobalFree(config->lpszProxy);
  if (config->lpszProxyBypass)
    GlobalFree(config->lpszProxyBypass);
}

static void FreeInfo(WINHTTP_PROXY_INFO* info) {
  if (info->lpszProxy)
    GlobalFree(info->lpszProxy);
  if (info->lpszProxyBypass)
    GlobalFree(info->lpszProxyBypass);
}

ProxyResolverWinHttp::ProxyResolverWinHttp()
    : session_handle_(NULL) {
}

ProxyResolverWinHttp::~ProxyResolverWinHttp() {
  CloseWinHttpSession();
}

int ProxyResolverWinHttp::GetProxyConfig(ProxyConfig* config) {
  WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_config = {0};
  if (!WinHttpGetIEProxyConfigForCurrentUser(&ie_config)) {
    LOG(ERROR) << "WinHttpGetIEProxyConfigForCurrentUser failed: " <<
        GetLastError();
    return ERR_FAILED;  // TODO(darin): Bug 1189288: translate error code.
  }

  if (ie_config.fAutoDetect)
    config->auto_detect = true;
  if (ie_config.lpszProxy)
    config->proxy_server = WideToASCII(ie_config.lpszProxy);
  if (ie_config.lpszProxyBypass)
    config->proxy_bypass = WideToASCII(ie_config.lpszProxyBypass);
  if (ie_config.lpszAutoConfigUrl)
    config->pac_url = WideToASCII(ie_config.lpszAutoConfigUrl);

  FreeConfig(&ie_config);
  return OK;
}

int ProxyResolverWinHttp::GetProxyForURL(const std::string& query_url,
                                         const std::string& pac_url,
                                         ProxyInfo* results) {
  // If we don't have a WinHTTP session, then create a new one.
  if (!session_handle_ && !OpenWinHttpSession())
    return ERR_FAILED;

  // If we have been given an empty PAC url, then use auto-detection.
  //
  // NOTE: We just use DNS-based auto-detection here like Firefox.  We do this
  // to avoid WinHTTP's auto-detection code, which while more featureful (it
  // supports DHCP based auto-detection) also appears to have issues.
  //
  WINHTTP_AUTOPROXY_OPTIONS options = {0};
  options.fAutoLogonIfChallenged = TRUE;
  options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
  std::wstring pac_url_wide = ASCIIToWide(pac_url);
  options.lpszAutoConfigUrl =
      pac_url_wide.empty() ? L"http://wpad/wpad.dat" : pac_url_wide.c_str();

  WINHTTP_PROXY_INFO info = {0};
  DCHECK(session_handle_);
  if (!CallWinHttpGetProxyForUrl(
          session_handle_, ASCIIToWide(query_url).c_str(), &options, &info)) {
    DWORD error = GetLastError();
    LOG(ERROR) << "WinHttpGetProxyForUrl failed: " << error;

    // If we got here because of RPC timeout during out of process PAC
    // resolution, no further requests on this session are going to work.
    if ((ERROR_WINHTTP_TIMEOUT == error) ||
        (ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR == error)) {
      CloseWinHttpSession();
    }

    return ERR_FAILED;  // TODO(darin): Bug 1189288: translate error code.
  }

  int rv = OK;

  switch (info.dwAccessType) {
    case WINHTTP_ACCESS_TYPE_NO_PROXY:
      results->UseDirect();
      break;
    case WINHTTP_ACCESS_TYPE_NAMED_PROXY:
      results->UseNamedProxy(WideToASCII(info.lpszProxy));
      break;
    default:
      NOTREACHED();
      rv = ERR_FAILED;
  }

  FreeInfo(&info);
  return rv;
}

bool ProxyResolverWinHttp::OpenWinHttpSession() {
  DCHECK(!session_handle_);
  session_handle_ = WinHttpOpen(NULL,
                                WINHTTP_ACCESS_TYPE_NO_PROXY,
                                WINHTTP_NO_PROXY_NAME,
                                WINHTTP_NO_PROXY_BYPASS,
                                0);
  if (!session_handle_)
    return false;

  // Since this session handle will never be used for WinHTTP connections,
  // these timeouts don't really mean much individually.  However, WinHTTP's
  // out of process PAC resolution will use a combined (sum of all timeouts)
  // value to wait for an RPC reply.
  BOOL rv = WinHttpSetTimeouts(session_handle_, 10000, 10000, 5000, 5000);
  DCHECK(rv);

  return true;
}

void ProxyResolverWinHttp::CloseWinHttpSession() {
  if (session_handle_) {
    WinHttpCloseHandle(session_handle_);
    session_handle_ = NULL;
  }
}

}  // namespace net

<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

//
//  This example illustrates how to read a DICOM series into a volume
//  and then save this volume into another DICOM series using the
//  exact same name.
//  It makes use of the DCMTK library
//

#include "itkImageSeriesReader.h"
#include "itkImageSeriesWriter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkDCMTKImageIO.h"
#include "itkDCMTKSeriesFileNames.h"
#include "itkTestingMacros.h"

int
itkDCMTKSeriesReadImageWrite(int argc, char * argv[])
{
  if (argc != 6)
  {
    std::cerr << "Missing arguments." << std::endl;
    std::cerr << "Usage: " << std::endl;
    std::cerr << itkNameOfTestExecutableMacro(argv) << " DicomDirectory "
              << " outputFile"
              << " recursive"
              << " loadSequences"
              << " loadPrivateTags" << std::endl;
    return EXIT_FAILURE;
  }

  using ImageType = itk::Image<unsigned short, 3>;
  using ReaderType = itk::ImageSeriesReader<ImageType>;
  using ImageIOType = itk::DCMTKImageIO;
  using SeriesFileNames = itk::DCMTKSeriesFileNames;

  ImageIOType::Pointer     dcmtkIO = ImageIOType::New();
  SeriesFileNames::Pointer it = SeriesFileNames::New();

  ITK_EXERCISE_BASIC_OBJECT_METHODS(it, DCMTKSeriesFileNames, ProcessObject);

  it->SetInputDirectory(argv[1]);

  auto recursive = static_cast<bool>(std::stoi(argv[3]);
  ITK_TEST_SET_GET_BOOLEAN(it, Recursive, recursive);

  auto loadSequences = static_cast<bool>(std::stoi(argv[4]);
  ITK_TEST_SET_GET_BOOLEAN(it, LoadSequences, loadSequences);

  auto loadPrivateTags = static_cast<bool>(std::stoi(argv[5]);
  ITK_TEST_SET_GET_BOOLEAN(it, LoadPrivateTags, loadPrivateTags);

  ReaderType::Pointer reader = ReaderType::New();

  const ReaderType::FileNamesContainer & fileNames = it->GetInputFileNames();
  const unsigned int                     numberOfFileNames = fileNames.size();
  std::cout << numberOfFileNames << std::endl;
  for (unsigned int fni = 0; fni < numberOfFileNames; ++fni)
  {
    std::cout << "filename # " << fni << " = ";
    std::cout << fileNames[fni] << std::endl;
  }

  reader->SetFileNames(fileNames);
  reader->SetImageIO(dcmtkIO);

  ITK_TRY_EXPECT_NO_EXCEPTION(reader->Update());

  using WriterType = itk::ImageFileWriter<ImageType>;
  WriterType::Pointer writer = WriterType::New();

  writer->SetFileName(argv[2]);
  writer->SetInput(reader->GetOutput());

  ITK_TRY_EXPECT_NO_EXCEPTION(writer->Update());

  std::cout << "Test finished" << std::endl;
  return EXIT_SUCCESS;
}
<commit_msg>COMP: add missing parentheses<commit_after>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

//
//  This example illustrates how to read a DICOM series into a volume
//  and then save this volume into another DICOM series using the
//  exact same name.
//  It makes use of the DCMTK library
//

#include "itkImageSeriesReader.h"
#include "itkImageSeriesWriter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkDCMTKImageIO.h"
#include "itkDCMTKSeriesFileNames.h"
#include "itkTestingMacros.h"

int
itkDCMTKSeriesReadImageWrite(int argc, char * argv[])
{
  if (argc != 6)
  {
    std::cerr << "Missing arguments." << std::endl;
    std::cerr << "Usage: " << std::endl;
    std::cerr << itkNameOfTestExecutableMacro(argv) << " DicomDirectory "
              << " outputFile"
              << " recursive"
              << " loadSequences"
              << " loadPrivateTags" << std::endl;
    return EXIT_FAILURE;
  }

  using ImageType = itk::Image<unsigned short, 3>;
  using ReaderType = itk::ImageSeriesReader<ImageType>;
  using ImageIOType = itk::DCMTKImageIO;
  using SeriesFileNames = itk::DCMTKSeriesFileNames;

  ImageIOType::Pointer     dcmtkIO = ImageIOType::New();
  SeriesFileNames::Pointer it = SeriesFileNames::New();

  ITK_EXERCISE_BASIC_OBJECT_METHODS(it, DCMTKSeriesFileNames, ProcessObject);

  it->SetInputDirectory(argv[1]);

  auto recursive = static_cast<bool>(std::stoi(argv[3]));
  ITK_TEST_SET_GET_BOOLEAN(it, Recursive, recursive);

  auto loadSequences = static_cast<bool>(std::stoi(argv[4]));
  ITK_TEST_SET_GET_BOOLEAN(it, LoadSequences, loadSequences);

  auto loadPrivateTags = static_cast<bool>(std::stoi(argv[5]));
  ITK_TEST_SET_GET_BOOLEAN(it, LoadPrivateTags, loadPrivateTags);

  ReaderType::Pointer reader = ReaderType::New();

  const ReaderType::FileNamesContainer & fileNames = it->GetInputFileNames();
  const unsigned int                     numberOfFileNames = fileNames.size();
  std::cout << numberOfFileNames << std::endl;
  for (unsigned int fni = 0; fni < numberOfFileNames; ++fni)
  {
    std::cout << "filename # " << fni << " = ";
    std::cout << fileNames[fni] << std::endl;
  }

  reader->SetFileNames(fileNames);
  reader->SetImageIO(dcmtkIO);

  ITK_TRY_EXPECT_NO_EXCEPTION(reader->Update());

  using WriterType = itk::ImageFileWriter<ImageType>;
  WriterType::Pointer writer = WriterType::New();

  writer->SetFileName(argv[2]);
  writer->SetInput(reader->GetOutput());

  ITK_TRY_EXPECT_NO_EXCEPTION(writer->Update());

  std::cout << "Test finished" << std::endl;
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include "browser/knossos_handler.h"

#if defined(CEF_X11)
#include <X11/Xatom.h>
#include <X11/Xlib.h>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <gtk/gtk.h>
#pragma GCC diagnostic pop
#endif

#include <string>

#include "include/base/cef_logging.h"
#include "include/cef_browser.h"
#include "include/wrapper/cef_helpers.h"

void KnossosHandler::PlatformInit() { gtk_init(nullptr, nullptr); }

void KnossosHandler::PlatformTitleChange(CefRefPtr<CefBrowser> browser,
                                         const CefString &title) {
  std::string titleStr(title);

#if defined(CEF_X11)
  // Retrieve the X11 display shared with Chromium.
  ::Display *display = cef_get_xdisplay();
  DCHECK(display);

  // Retrieve the X11 window handle for the browser.
  ::Window window = browser->GetHost()->GetWindowHandle();
  if (window == kNullWindowHandle)
    return;

  // Retrieve the atoms required by the below XChangeProperty call.
  const char *kAtoms[] = {"_NET_WM_NAME", "UTF8_STRING"};
  Atom atoms[2];
  int result =
      XInternAtoms(display, const_cast<char **>(kAtoms), 2, false, atoms);
  if (!result)
    NOTREACHED();

  // Set the window title.
  XChangeProperty(display, window, atoms[0], atoms[1], 8, PropModeReplace,
                  reinterpret_cast<const unsigned char *>(titleStr.c_str()),
                  titleStr.size());

  // TODO(erg): This is technically wrong. So XStoreName and friends expect
  // this in Host Portable Character Encoding instead of UTF-8, which I believe
  // is Compound Text. This shouldn't matter 90% of the time since this is the
  // fallback to the UTF8 property above.
  XStoreName(display, browser->GetHost()->GetWindowHandle(), titleStr.c_str());
#endif // defined(CEF_X11)
}

CefRect KnossosHandler::GetScreenSize() {
  CEF_REQUIRE_UI_THREAD();
  CefRect screen_size;

#if defined(CEF_X11)
  XWindowAttributes attrs;
  XGetWindowAttributes(cef_get_xdisplay(),
                       XDefaultRootWindow(cef_get_xdisplay()), &attrs);

  screen_size.width = attrs.width;
  screen_size.height = attrs.height;
#endif

  return screen_size;
}

void KnossosHandler::ShowError(std::string msg) {
  auto dialog =
      gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
                             GTK_BUTTONS_CLOSE, "%s", msg.c_str());
  gtk_dialog_run(GTK_DIALOG(dialog));
  gtk_widget_destroy(dialog);
}

static void
InternalOpenFileDialog(const char *title, GtkFileChooserAction action,
                       const char *default_filepath,
                       std::vector<std::string> accepted,
                       CefRefPtr<CefRunFileDialogCallback> callback) {
  const char *open_label;
  switch (action) {
  case GTK_FILE_CHOOSER_ACTION_OPEN:
    open_label = "_Open";
    break;
  case GTK_FILE_CHOOSER_ACTION_SAVE:
    open_label = "_Save";
    break;
  case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
    open_label = "_Select Folder";
    break;
  default:
    open_label = "_Select";
  }

  auto dialog =
      gtk_file_chooser_native_new(title, NULL, action, open_label, "_Cancel");
  auto chooser = GTK_FILE_CHOOSER(dialog);

  if (action == GTK_FILE_CHOOSER_ACTION_SAVE) {
    gtk_file_chooser_set_do_overwrite_confirmation(chooser, true);
  }

  if (strlen(default_filepath) > 0) {
    gtk_file_chooser_set_filename(chooser, default_filepath);
  }

  std::vector<GtkFileFilter*> filters;
  for (auto item : accepted) {
    auto splitter = item.find("|");
    if (splitter == std::string::npos) {
      LOG(WARNING) << "Invalid file filter: " << item;
      continue;
    }

    auto filter = gtk_file_filter_new();
    gtk_file_filter_set_name(filter, item.substr(0, splitter).c_str());

    if (item.find("/") == std::string::npos) {
      gtk_file_filter_add_pattern(filter, item.substr(splitter + 1).c_str());
    } else {
      gtk_file_filter_add_mime_type(filter, item.substr(splitter + 1).c_str());
    }

    gtk_file_chooser_add_filter(chooser, filter);
    filters.push_back(filter);
  }

  auto result = gtk_native_dialog_run(GTK_NATIVE_DIALOG(dialog));
  if (result == GTK_RESPONSE_ACCEPT) {
    auto filename = gtk_file_chooser_get_filename(chooser);
    callback->OnFileDialogDismissed(0, std::vector<CefString>({filename}));
    g_free(filename);
  } else {
    callback->OnFileDialogDismissed(0, std::vector<CefString>({""}));
  }

  for (auto filter : filters) {
    g_object_unref(filter);
  }

  g_object_unref(dialog);
}

void KnossosHandler::SaveFileDialog(
    CefRefPtr<CefBrowser> browser, std::string title,
    std::string default_filepath, std::vector<std::string> accepted,
    CefRefPtr<CefRunFileDialogCallback> callback) {
  InternalOpenFileDialog(title.c_str(), GTK_FILE_CHOOSER_ACTION_SAVE,
                         default_filepath.c_str(), accepted, callback);
}

void KnossosHandler::OpenFileDialog(
    CefRefPtr<CefBrowser> browser, std::string title,
    std::string default_filepath, std::vector<std::string> accepted,
    CefRefPtr<CefRunFileDialogCallback> callback) {
  InternalOpenFileDialog(title.c_str(), GTK_FILE_CHOOSER_ACTION_OPEN,
                         default_filepath.c_str(), accepted, callback);
}

void KnossosHandler::OpenFolderDialog(
    CefRefPtr<CefBrowser> browser, std::string title, std::string folder,
    CefRefPtr<CefRunFileDialogCallback> callback) {
  InternalOpenFileDialog(title.c_str(), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
                         folder.c_str(), callback);
}
<commit_msg>fix(client): missing parameter in linux's openfolderdialog<commit_after>#include "browser/knossos_handler.h"

#if defined(CEF_X11)
#include <X11/Xatom.h>
#include <X11/Xlib.h>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <gtk/gtk.h>
#pragma GCC diagnostic pop
#endif

#include <string>

#include "include/base/cef_logging.h"
#include "include/cef_browser.h"
#include "include/wrapper/cef_helpers.h"

void KnossosHandler::PlatformInit() { gtk_init(nullptr, nullptr); }

void KnossosHandler::PlatformTitleChange(CefRefPtr<CefBrowser> browser,
                                         const CefString &title) {
  std::string titleStr(title);

#if defined(CEF_X11)
  // Retrieve the X11 display shared with Chromium.
  ::Display *display = cef_get_xdisplay();
  DCHECK(display);

  // Retrieve the X11 window handle for the browser.
  ::Window window = browser->GetHost()->GetWindowHandle();
  if (window == kNullWindowHandle)
    return;

  // Retrieve the atoms required by the below XChangeProperty call.
  const char *kAtoms[] = {"_NET_WM_NAME", "UTF8_STRING"};
  Atom atoms[2];
  int result =
      XInternAtoms(display, const_cast<char **>(kAtoms), 2, false, atoms);
  if (!result)
    NOTREACHED();

  // Set the window title.
  XChangeProperty(display, window, atoms[0], atoms[1], 8, PropModeReplace,
                  reinterpret_cast<const unsigned char *>(titleStr.c_str()),
                  titleStr.size());

  // TODO(erg): This is technically wrong. So XStoreName and friends expect
  // this in Host Portable Character Encoding instead of UTF-8, which I believe
  // is Compound Text. This shouldn't matter 90% of the time since this is the
  // fallback to the UTF8 property above.
  XStoreName(display, browser->GetHost()->GetWindowHandle(), titleStr.c_str());
#endif // defined(CEF_X11)
}

CefRect KnossosHandler::GetScreenSize() {
  CEF_REQUIRE_UI_THREAD();
  CefRect screen_size;

#if defined(CEF_X11)
  XWindowAttributes attrs;
  XGetWindowAttributes(cef_get_xdisplay(),
                       XDefaultRootWindow(cef_get_xdisplay()), &attrs);

  screen_size.width = attrs.width;
  screen_size.height = attrs.height;
#endif

  return screen_size;
}

void KnossosHandler::ShowError(std::string msg) {
  auto dialog =
      gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
                             GTK_BUTTONS_CLOSE, "%s", msg.c_str());
  gtk_dialog_run(GTK_DIALOG(dialog));
  gtk_widget_destroy(dialog);
}

static void
InternalOpenFileDialog(const char *title, GtkFileChooserAction action,
                       const char *default_filepath,
                       std::vector<std::string> accepted,
                       CefRefPtr<CefRunFileDialogCallback> callback) {
  const char *open_label;
  switch (action) {
  case GTK_FILE_CHOOSER_ACTION_OPEN:
    open_label = "_Open";
    break;
  case GTK_FILE_CHOOSER_ACTION_SAVE:
    open_label = "_Save";
    break;
  case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
    open_label = "_Select Folder";
    break;
  default:
    open_label = "_Select";
  }

  auto dialog =
      gtk_file_chooser_native_new(title, NULL, action, open_label, "_Cancel");
  auto chooser = GTK_FILE_CHOOSER(dialog);

  if (action == GTK_FILE_CHOOSER_ACTION_SAVE) {
    gtk_file_chooser_set_do_overwrite_confirmation(chooser, true);
  }

  if (strlen(default_filepath) > 0) {
    gtk_file_chooser_set_filename(chooser, default_filepath);
  }

  std::vector<GtkFileFilter*> filters;
  for (auto item : accepted) {
    auto splitter = item.find("|");
    if (splitter == std::string::npos) {
      LOG(WARNING) << "Invalid file filter: " << item;
      continue;
    }

    auto filter = gtk_file_filter_new();
    gtk_file_filter_set_name(filter, item.substr(0, splitter).c_str());

    if (item.find("/") == std::string::npos) {
      gtk_file_filter_add_pattern(filter, item.substr(splitter + 1).c_str());
    } else {
      gtk_file_filter_add_mime_type(filter, item.substr(splitter + 1).c_str());
    }

    gtk_file_chooser_add_filter(chooser, filter);
    filters.push_back(filter);
  }

  auto result = gtk_native_dialog_run(GTK_NATIVE_DIALOG(dialog));
  if (result == GTK_RESPONSE_ACCEPT) {
    auto filename = gtk_file_chooser_get_filename(chooser);
    callback->OnFileDialogDismissed(0, std::vector<CefString>({filename}));
    g_free(filename);
  } else {
    callback->OnFileDialogDismissed(0, std::vector<CefString>({""}));
  }

  for (auto filter : filters) {
    g_object_unref(filter);
  }

  g_object_unref(dialog);
}

void KnossosHandler::SaveFileDialog(
    CefRefPtr<CefBrowser> browser, std::string title,
    std::string default_filepath, std::vector<std::string> accepted,
    CefRefPtr<CefRunFileDialogCallback> callback) {
  InternalOpenFileDialog(title.c_str(), GTK_FILE_CHOOSER_ACTION_SAVE,
                         default_filepath.c_str(), accepted, callback);
}

void KnossosHandler::OpenFileDialog(
    CefRefPtr<CefBrowser> browser, std::string title,
    std::string default_filepath, std::vector<std::string> accepted,
    CefRefPtr<CefRunFileDialogCallback> callback) {
  InternalOpenFileDialog(title.c_str(), GTK_FILE_CHOOSER_ACTION_OPEN,
                         default_filepath.c_str(), accepted, callback);
}

void KnossosHandler::OpenFolderDialog(
    CefRefPtr<CefBrowser> browser, std::string title, std::string folder,
    CefRefPtr<CefRunFileDialogCallback> callback) {
  InternalOpenFileDialog(title.c_str(), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
                         folder.c_str(), {}, callback);
}
<|endoftext|>


<commit_before>
AliAnalysisTaskElectronEfficiencyV2* AddTask_jjung_efficiency(
		TString name = "name",
		Bool_t isAOD,
		Bool_t getFromAlien = kFALSE,
		TString configFile="Config_jjung_lowmass.C",
		Bool_t DoCentralityCorrection = kFALSE,
	        Int_t centrality,
		Int_t wagonnr = 0) {

  std::cout << "########################################\nADDTASK of ANALYSIS started\n########################################" << std::endl;

  // #########################################################
  // #########################################################
  // Configuring Analysis Manager
  AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
  if(!mgr){
    Error("AddTask_jjung_ElectronEfficiencyV2", "No analysis manager found.");
    return 0;
  }
  else { std::cout << "Analysis manager found!" << std::endl;}
  TString fileName = AliAnalysisManager::GetCommonFileName();
  fileName = "AnalysisResults.root"; // create a subfolder in the file

  // #########################################################
  // #########################################################
  // Loading individual config file either local or from Alien

  // TString configBasePath= "$ALICE_PHYSICS/PWGDQ/dielectron/macrosLMEE/";
  TString configBasePath= "/data4/jung/localLegotrainNewEfficiency/";
  //Load updated macros from private ALIEN path
  if (getFromAlien //&&
      && (!gSystem->Exec(Form("alien_cp alien:///alice/cern.ch/user/j/jjung/%s .",configFile.Data())))
      ) {
    configBasePath=Form("%s/",gSystem->pwd());
  }
  TString configFilePath(configBasePath+configFile);

  // Loading config and cutlib
  Bool_t err=kFALSE;
  err |= gROOT->LoadMacro(configFilePath.Data());
  if (err) { Error("AddTask_jjung_ElectronEfficiency_v2","Config(s) could not be loaded!"); return 0x0; }

  // Download resolution file (configured in your config.C)
  //if (GetResolutionFromAlien == kTRUE){
  //  std::cout << "Trying to download resolution file" << std::endl;
  //  gSystem->Exec(Form("alien_cp alien://%s .",resoFilenameFromAlien.c_str()));
  //  std::cout << "Load resolution file from AliEn" << std::endl;
  //}

  //// Download centrality file (configured in your config.C)
  //if (GetCentralityFromAlien == kTRUE && !gSystem->Exec(Form("alien_cp alien://%s .",CentralityFilenameFromAlien.c_str()))){
  //  std::cout << "Load centrality file from AliEn" << std::endl;
  //}

  // #########################################################
  // #########################################################
  // Creating an instance of the task
  AliAnalysisTaskElectronEfficiencyV2* task = new AliAnalysisTaskElectronEfficiencyV2(name.Data());

  // #########################################################
  // #########################################################
  // Possibility to set generator. If nothing set all generators are taken into account
  // task->SetGeneratorName(generatorName);
  task->SetGeneratorMCSignalName(generatorNameForMCSignal);
  task->SetGeneratorULSSignalName(generatorNameForULSSignal);

  // #########################################################
  // #########################################################
  // Event selection. Is the same for all the different cutsettings
  task->SetEnablePhysicsSelection(kTRUE);

  task->SetTriggerMask(triggerNames);
  task->SetEventFilter(SetupEventCuts(wagonnr)); //returns eventCuts from Config.
  task->SetCentrality(centMin, centMax);
  // #########################################################
  // #########################################################
  // Set minimum and maximum values of generated tracks. Only used to save computing power.
  // Do not set here your analysis pt-cuts
  task->SetMinPtGen(minGenPt);
  task->SetMaxPtGen(maxGenPt);
  task->SetMinEtaGen(minGenEta);
  task->SetMaxEtaGen(maxGenEta);

  // #########################################################
  // #########################################################
  // 4D single efficiency from pairs
  task->SetWriteLegsFromPair(WriteLegsFromPair);
  task->SetPtMinLegsFromPair(ptMinLegsFromPair);
  task->SetPtMaxLegsFromPair(ptMaxLegsFromPair);
  task->SetPtNBinsLegsFromPair(ptNBinsLegsFromPair);
  task->SetEtaMinLegsFromPair(etaMinLegsFromPair);
  task->SetEtaMaxLegsFromPair(etaMaxLegsFromPair);
  task->SetEtaNBinsLegsFromPair(etaNBinsLegsFromPair);
  task->SetPhiMinLegsFromPair(phiMinLegsFromPair);
  task->SetPhiMaxLegsFromPair(phiMaxLegsFromPair);
  task->SetPhiNBinsLegsFromPair(phiNBinsLegsFromPair);
  task->SetOpAngleMinLegsFromPair(opAngleMinLegsFromPair);
  task->SetOpAngleMaxLegsFromPair(opAngleMaxLegsFromPair);
  task->SetOpAngleNBinsLegsFromPair(opAngleNBinsLegsFromPair);

  // #########################################################
  // #########################################################
  // Set minimum and maximum values of generated tracks. Only used to save computing power.
  task->SetKinematicCuts(minPtCut, maxPtCut, minEtaCut, maxEtaCut);

  // #########################################################
  // #########################################################
  // Set Binning
  if (usePtVector == true) {
    std::vector<double> ptBinsVec;
    for (unsigned int i = 0; i < nBinsPt+1; ++i){
      ptBinsVec.push_back(PtBins[i]);
    }
    task->SetPtBins(ptBinsVec);
  }
  else task->SetPtBinsLinear   (minPtBin,  maxPtBin, stepsPtBin);
  task->SetEtaBinsLinear  (minEtaBin, maxEtaBin, stepsEtaBin);
  task->SetPhiBinsLinear  (minPhiBin, maxPhiBin, stepsPhiBin);
  task->SetThetaBinsLinear(minThetaBin, maxThetaBin, stepsThetaBin);
  if (useMeeVector == true) {
    std::vector<double> meeBinsVec;
    for (unsigned int i = 0; i < nBinsMee+1; ++i){
      meeBinsVec.push_back(MeeBins[i]);
    }
    task->SetMassBins(meeBinsVec);
  }
  else task->SetMassBinsLinear (minMassBin, maxMassBin, stepsMassBin);
  if (usePteeVector == true) {
    std::vector<double> pteeBinsVec;
    for (unsigned int i = 0; i < nBinsPtee+1; ++i){
      pteeBinsVec.push_back(PteeBins[i]);
    }
    task->SetPairPtBins(pteeBinsVec);
  }
  else task->SetPairPtBinsLinear(minPairPtBin, maxPairPtBin, stepsPairPtBin);

  // #########################################################
  // #########################################################
  // Resolution File, If resoFilename = "" no correction is applied
  task->SetResolutionFile(resoFilename);
  task->SetResolutionFileFromAlien(resoFilenameFromAlien);
  task->SetResolutionFile(resoFilename,resoFilenameFromAlien);
  task->SetSmearGenerated(SetGeneratedSmearingHistos);
  task->SetResolutionDeltaPtBinsLinear   (DeltaMomMin, DeltaMomMax, NbinsDeltaMom);
  task->SetResolutionRelPtBinsLinear   (RelMomMin, RelMomMax, NbinsRelMom);
  task->SetResolutionEtaBinsLinear  (DeltaEtaMin, DeltaEtaMax, NbinsDeltaEta);
  task->SetResolutionPhiBinsLinear  (DeltaPhiMin, DeltaPhiMax, NbinsDeltaPhi);
  task->SetResolutionThetaBinsLinear(DeltaThetaMin, DeltaThetaMax, NbinsDeltaTheta);

  // #########################################################
  // #########################################################
  // Set centrality correction. If resoFilename = "" no correction is applied
  task->SetCentralityFile(centralityFilename);
  task->SetCentralityFile(centralityFilename,centralityFilenameFromAlien);

  // #########################################################
  // #########################################################
  // Set MCSignal and Cutsetting to fill the support histograms
  task->SetSupportHistoMCSignalAndCutsetting(nMCSignal, nCutsetting);

  // #########################################################
  // #########################################################
  // Set Cocktail weighting
  task->SetDoCocktailWeighting(DoCocktailWeighting);
  task->SetCocktailWeighting(CocktailFilename);
  task->SetCocktailWeightingFromAlien(CocktailFilenameFromAlien);
  task->SetCocktailWeighting(CocktailFilename,CocktailFilenameFromAlien);

  // #########################################################
  // #########################################################
  // Pairing related config
  task->SetDoPairing(DoPairing);
  task->SetULSandLS(DoULSLS);
  task->SetDeactivateLS(DeactivateLS);

  // #########################################################
  // #########################################################
  // Add MCSignals. Can be set to see differences of:
  // e.g. secondaries and primaries. or primaries from charm and resonances
  AddSingleLegMCSignal(task);
  AddPairMCSignal(task);
  //Done in config
  //std::vector<bool> DielectronsPairNotFromSameMother = AddSingleLegMCSignal(task);
  //task->AddMCSignalsWhereDielectronPairNotFromSameMother(DielectronsPairNotFromSameMother);

  // #########################################################
  // #########################################################
  // Set mean and width correction for ITS, TPC and TOF
  //set PID map for ITS TOF in MC.
  TFile *rootfile = 0x0;
  if(calibFileName != "") rootfile = TFile::Open(calibFileName.c_str(),"READ");
  if(calibFileNameFromAlien != "" && !rootfile && getFromAlien){
    std::cout << "Location in AliEN: " << calibFileNameFromAlien << std::endl;
    gSystem->Exec(Form("alien_cp alien://%s .", calibFileNameFromAlien.c_str()));
    std::cout << "Copy resolution from Alien" << std::endl;
    rootfile = TFile::Open(calibFileName.c_str(), "READ");

    if (!rootfile) {
      std::cout << "Could not open file: " << calibFileNameFromAlien << std::endl;
    }
  }
  if(rootfile && rootfile->IsOpen()){
    TH3D *h3mean_ITS  = (TH3D*)rootfile->Get("h3mean_ITS");
    TH3D *h3width_ITS = (TH3D*)rootfile->Get("h3width_ITS");
    h3mean_ITS ->SetDirectory(0);
    h3width_ITS->SetDirectory(0);
    task->SetCentroidCorrFunction(AliAnalysisTaskElectronEfficiencyV2::kITS, h3mean_ITS, AliDielectronVarManager::kNSDDSSDclsEvent, AliDielectronVarManager::kPIn,  AliDielectronVarManager::kEta);
    task->SetWidthCorrFunction(AliAnalysisTaskElectronEfficiencyV2::kITS, h3width_ITS, AliDielectronVarManager::kNSDDSSDclsEvent, AliDielectronVarManager::kPIn,  AliDielectronVarManager::kEta );

    TH3D *h3mean_TOF = (TH3D*)rootfile->Get("h3mean_TOF");
    TH3D *h3width_TOF = (TH3D*)rootfile->Get("h3width_TOF");
    h3mean_TOF ->SetDirectory(0);
    h3width_TOF->SetDirectory(0);
    task->SetCentroidCorrFunction(AliAnalysisTaskElectronEfficiencyV2::kTOF, h3mean_TOF, AliDielectronVarManager::kNSDDSSDclsEvent, AliDielectronVarManager::kPIn,  AliDielectronVarManager::kEta);
    task->SetWidthCorrFunction(AliAnalysisTaskElectronEfficiencyV2::kTOF, h3width_TOF, AliDielectronVarManager::kNSDDSSDclsEvent, AliDielectronVarManager::kPIn,  AliDielectronVarManager::kEta);

    rootfile->Close();
  }

  // #########################################################
  // #########################################################
  // Adding cutsettings
  //TObjArray*  arrNames=names.Tokenize(";");
  const Int_t nDie=arrNames->GetEntriesFast();

  for (int iCut = 0; iCut < nDie; ++iCut){
    //TString cutDefinition(arrNames->At(iCut)->GetName());
    AliAnalysisFilter* filter = SetupTrackCutsAndSettings(iCut);
    task->AddTrackCuts(filter);
  }

  mgr->AddTask(task);
  mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 1, mgr->CreateContainer("efficiency", TList::Class(), AliAnalysisManager::kOutputContainer, fileName.Data()));
  return task;
}
<commit_msg>DQ:LMee: Update to personal AddTask for efficiencies<commit_after>
AliAnalysisTaskElectronEfficiencyV2* AddTask_jjung_efficiency(
		TString name = "name",
 		TString outputname = "AnalysisResults.root",
		Bool_t isAOD,
		Bool_t getFromAlien = kFALSE,
		TString configFile="Config_jjung_lowmass.C",
		Bool_t DoCentralityCorrection = kFALSE,
	        Int_t centrality,
		Int_t wagonnr = 0) {

  std::cout << "########################################\nADDTASK of ANALYSIS started\n########################################" << std::endl;

  // #########################################################
  // #########################################################
  // Configuring Analysis Manager
  AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
  if(!mgr){
    Error("AddTask_jjung_ElectronEfficiencyV2", "No analysis manager found.");
    return 0;
  }
  else { std::cout << "Analysis manager found!" << std::endl;}
  TString fileName = AliAnalysisManager::GetCommonFileName();
  fileName = outputname; // create a subfolder in the file

  // #########################################################
  // #########################################################
  // Loading individual config file either local or from Alien

  // TString configBasePath= "$ALICE_PHYSICS/PWGDQ/dielectron/macrosLMEE/";
  TString configBasePath= "/data4/jung/localLegotrainNewEfficiency/";
  //Load updated macros from private ALIEN path
  if (getFromAlien //&&
      && (!gSystem->Exec(Form("alien_cp alien:///alice/cern.ch/user/j/jjung/%s .",configFile.Data())))
      ) {
    configBasePath=Form("%s/",gSystem->pwd());
  }
  TString configFilePath(configBasePath+configFile);
  std::cout << configFilePath << std::endl;

  // Loading config and cutlib
  Bool_t err=kFALSE;
  err |= gROOT->LoadMacro(configFilePath.Data());
  //if (err) { Error("AddTask_jjung_ElectronEfficiency_v2","Config(s) could not be loaded!"); return 0x0; }

  // Download resolution file (configured in your config.C)
  //if (GetResolutionFromAlien == kTRUE){
  //  std::cout << "Trying to download resolution file" << std::endl;
  //  gSystem->Exec(Form("alien_cp alien://%s .",resoFilenameFromAlien.c_str()));
  //  std::cout << "Load resolution file from AliEn" << std::endl;
  //}

  //// Download centrality file (configured in your config.C)
  //if (GetCentralityFromAlien == kTRUE && !gSystem->Exec(Form("alien_cp alien://%s .",CentralityFilenameFromAlien.c_str()))){
  //  std::cout << "Load centrality file from AliEn" << std::endl;
  //}

  // #########################################################
  // #########################################################
  // Creating an instance of the task
  AliAnalysisTaskElectronEfficiencyV2* task = new AliAnalysisTaskElectronEfficiencyV2(name.Data());

  // #########################################################
  // #########################################################
  // Possibility to set generator. If nothing set all generators are taken into account
  // task->SetGeneratorName(generatorName);
  task->SetGeneratorMCSignalName(generatorNameForMCSignal);
  task->SetGeneratorULSSignalName(generatorNameForULSSignal);

  // #########################################################
  // #########################################################
  // Event selection. Is the same for all the different cutsettings
  task->SetEnablePhysicsSelection(kTRUE);

  task->SetTriggerMask(triggerNames);
  task->SetEventFilter(SetupEventCuts(wagonnr)); //returns eventCuts from Config.
  task->SetCentrality(centMin, centMax);
  // #########################################################
  // #########################################################
  // Set minimum and maximum values of generated tracks. Only used to save computing power.
  // Do not set here your analysis pt-cuts
  task->SetMinPtGen(minGenPt);
  task->SetMaxPtGen(maxGenPt);
  task->SetMinEtaGen(minGenEta);
  task->SetMaxEtaGen(maxGenEta);

  // #########################################################
  // #########################################################
  // 4D single efficiency from pairs
  task->SetWriteLegsFromPair(WriteLegsFromPair);
  task->SetPtMinLegsFromPair(ptMinLegsFromPair);
  task->SetPtMaxLegsFromPair(ptMaxLegsFromPair);
  task->SetPtNBinsLegsFromPair(ptNBinsLegsFromPair);
  task->SetEtaMinLegsFromPair(etaMinLegsFromPair);
  task->SetEtaMaxLegsFromPair(etaMaxLegsFromPair);
  task->SetEtaNBinsLegsFromPair(etaNBinsLegsFromPair);
  task->SetPhiMinLegsFromPair(phiMinLegsFromPair);
  task->SetPhiMaxLegsFromPair(phiMaxLegsFromPair);
  task->SetPhiNBinsLegsFromPair(phiNBinsLegsFromPair);
  task->SetOpAngleMinLegsFromPair(opAngleMinLegsFromPair);
  task->SetOpAngleMaxLegsFromPair(opAngleMaxLegsFromPair);
  task->SetOpAngleNBinsLegsFromPair(opAngleNBinsLegsFromPair);

  // #########################################################
  // #########################################################
  // Set minimum and maximum values of generated tracks. Only used to save computing power.
  task->SetKinematicCuts(minPtCut, maxPtCut, minEtaCut, maxEtaCut);

  // #########################################################
  // #########################################################
  // Set Binning
  if (usePtVector == true) {
    std::vector<double> ptBinsVec;
    for (unsigned int i = 0; i < nBinsPt+1; ++i){
      ptBinsVec.push_back(PtBins[i]);
    }
    task->SetPtBins(ptBinsVec);
  }
  else task->SetPtBinsLinear   (minPtBin,  maxPtBin, stepsPtBin);
  task->SetEtaBinsLinear  (minEtaBin, maxEtaBin, stepsEtaBin);
  task->SetPhiBinsLinear  (minPhiBin, maxPhiBin, stepsPhiBin);
  task->SetThetaBinsLinear(minThetaBin, maxThetaBin, stepsThetaBin);
  if (useMeeVector == true) {
    std::vector<double> meeBinsVec;
    for (unsigned int i = 0; i < nBinsMee+1; ++i){
      meeBinsVec.push_back(MeeBins[i]);
    }
    task->SetMassBins(meeBinsVec);
  }
  else task->SetMassBinsLinear (minMassBin, maxMassBin, stepsMassBin);
  if (usePteeVector == true) {
    std::vector<double> pteeBinsVec;
    for (unsigned int i = 0; i < nBinsPtee+1; ++i){
      pteeBinsVec.push_back(PteeBins[i]);
    }
    task->SetPairPtBins(pteeBinsVec);
  }
  else task->SetPairPtBinsLinear(minPairPtBin, maxPairPtBin, stepsPairPtBin);

  // #########################################################
  // #########################################################
  // Resolution File, If resoFilename = "" no correction is applied
  task->SetResolutionFile(resoFilename);
  task->SetResolutionFileFromAlien(resoFilenameFromAlien);
  task->SetResolutionFile(resoFilename,resoFilenameFromAlien);
  task->SetSmearGenerated(SetGeneratedSmearingHistos);
  task->SetResolutionDeltaPtBinsLinear   (DeltaMomMin, DeltaMomMax, NbinsDeltaMom);
  task->SetResolutionRelPtBinsLinear   (RelMomMin, RelMomMax, NbinsRelMom);
  task->SetResolutionEtaBinsLinear  (DeltaEtaMin, DeltaEtaMax, NbinsDeltaEta);
  task->SetResolutionPhiBinsLinear  (DeltaPhiMin, DeltaPhiMax, NbinsDeltaPhi);
  task->SetResolutionThetaBinsLinear(DeltaThetaMin, DeltaThetaMax, NbinsDeltaTheta);

  // #########################################################
  // #########################################################
  // Set centrality correction. If resoFilename = "" no correction is applied
  task->SetCentralityFile(centralityFilename);
  task->SetCentralityFile(centralityFilename,centralityFilenameFromAlien);

  // #########################################################
  // #########################################################
  // Set MCSignal and Cutsetting to fill the support histograms
  task->SetSupportHistoMCSignalAndCutsetting(nMCSignal, nCutsetting);

  // #########################################################
  // #########################################################
  // Set Cocktail weighting
  task->SetDoCocktailWeighting(DoCocktailWeighting);
  task->SetCocktailWeighting(CocktailFilename);
  task->SetCocktailWeightingFromAlien(CocktailFilenameFromAlien);
  task->SetCocktailWeighting(CocktailFilename,CocktailFilenameFromAlien);

  // #########################################################
  // #########################################################
  // Pairing related config
  task->SetDoPairing(DoPairing);
  task->SetULSandLS(DoULSLS);
  task->SetDeactivateLS(DeactivateLS);

  // #########################################################
  // #########################################################
  // Add MCSignals. Can be set to see differences of:
  // e.g. secondaries and primaries. or primaries from charm and resonances
  AddSingleLegMCSignal(task);
  AddPairMCSignal(task);
  //Done in config
  //std::vector<bool> DielectronsPairNotFromSameMother = AddSingleLegMCSignal(task);
  //task->AddMCSignalsWhereDielectronPairNotFromSameMother(DielectronsPairNotFromSameMother);

  // #########################################################
  // #########################################################
  // Set mean and width correction for ITS, TPC and TOF
  //set PID map for ITS TOF in MC.
  TFile *rootfile = 0x0;
  if(calibFileName != "") rootfile = TFile::Open(calibFileName.c_str(),"READ");
  if(calibFileNameFromAlien != "" && !rootfile && getFromAlien){
    std::cout << "Location in AliEN: " << calibFileNameFromAlien << std::endl;
    gSystem->Exec(Form("alien_cp alien://%s .", calibFileNameFromAlien.c_str()));
    std::cout << "Copy resolution from Alien" << std::endl;
    rootfile = TFile::Open(calibFileName.c_str(), "READ");

    if (!rootfile) {
      std::cout << "Could not open file: " << calibFileNameFromAlien << std::endl;
    }
  }
  if(rootfile && rootfile->IsOpen()){
    TH3D *h3mean_ITS  = (TH3D*)rootfile->Get("h3mean_ITS");
    TH3D *h3width_ITS = (TH3D*)rootfile->Get("h3width_ITS");
    h3mean_ITS ->SetDirectory(0);
    h3width_ITS->SetDirectory(0);
    task->SetCentroidCorrFunction(AliAnalysisTaskElectronEfficiencyV2::kITS, h3mean_ITS, AliDielectronVarManager::kNSDDSSDclsEvent, AliDielectronVarManager::kPIn,  AliDielectronVarManager::kEta);
    task->SetWidthCorrFunction(AliAnalysisTaskElectronEfficiencyV2::kITS, h3width_ITS, AliDielectronVarManager::kNSDDSSDclsEvent, AliDielectronVarManager::kPIn,  AliDielectronVarManager::kEta );

    TH3D *h3mean_TOF = (TH3D*)rootfile->Get("h3mean_TOF");
    TH3D *h3width_TOF = (TH3D*)rootfile->Get("h3width_TOF");
    h3mean_TOF ->SetDirectory(0);
    h3width_TOF->SetDirectory(0);
    task->SetCentroidCorrFunction(AliAnalysisTaskElectronEfficiencyV2::kTOF, h3mean_TOF, AliDielectronVarManager::kNSDDSSDclsEvent, AliDielectronVarManager::kPIn,  AliDielectronVarManager::kEta);
    task->SetWidthCorrFunction(AliAnalysisTaskElectronEfficiencyV2::kTOF, h3width_TOF, AliDielectronVarManager::kNSDDSSDclsEvent, AliDielectronVarManager::kPIn,  AliDielectronVarManager::kEta);

    rootfile->Close();
  }

  // #########################################################
  // #########################################################
  // Adding cutsettings
  //TObjArray*  arrNames=names.Tokenize(";");
  const Int_t nDie=arrNames->GetEntriesFast();

  for (int iCut = 0; iCut < nDie; ++iCut){
    //TString cutDefinition(arrNames->At(iCut)->GetName());
    AliAnalysisFilter* filter = SetupTrackCutsAndSettings(iCut);
    task->AddTrackCuts(filter);
  }

  mgr->AddTask(task);
  mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 1, mgr->CreateContainer(Form("efficiency%d",wagonnr), TList::Class(), AliAnalysisManager::kOutputContainer, fileName.Data()));
  return task;
}
<|endoftext|>