Mercurial > repos > dereeper > sniplay
view egglib/egglib-2.1.5/include/egglib-cpp/Edge.hpp @ 15:31c23d943c29 draft default tip
Uploaded
author | dereeper |
---|---|
date | Tue, 08 Jan 2019 08:47:56 -0500 |
parents | 420b57c3c185 |
children |
line wrap: on
line source
/* Copyright 2009-2010 Stéphane De Mita, Mathieu Siol This file is part of the EggLib library. EggLib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. EggLib 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 General Public License for more details. You should have received a copy of the GNU General Public License along with EggLib. If not, see <http://www.gnu.org/licenses/>. */ #ifndef EGGLIB_EDGE_HPP #define EGGLIB_EDGE_HPP #include <vector> #include <climits> #include "EggException.hpp" namespace egglib { class Random; /** \brief Edge of the ancestral recombination graph * * \ingroup coalesce * * Each Edge instance provides access to its 0, 1 or 2 descendants * (the former holds for a terminal node, the middle for the parent * of a recombined node and the latter for the parent of a coalesced * node (most classical node in the coalescent).The Edge also * provides to the edge length. Note that the Edge instance must be * understood as an ARG node and the branch above it (latter in the * coalescence process). Edge instances also keep track of the list * of descendants descending from this node (which may differ along * recombining segment). Edge instances *must* be created through one * of the "default" and "coalescence" constructors or through the * recombination method. Edge instances should never be copied but * manipulated by references. * */ class Edge { public: /// Destructor virtual ~Edge(); /** \brief Constructor * * \param numberOfSegments the number of recombining segments * (one for a non-recombining region). * * Use the Pool, instead. Objects are delivered with a * complete coverage. * */ Edge(unsigned int numberOfSegments); /// Restore object to `factory` state void reset(); /** \brief Builds for internal node * * \param date the date of creation of the edge. * \param son1 first edge descending from this edge. * \param son2 second edge descending from this edge. * \param edgesPerSegments counts the current number of * (non-coalesced lineages for each lineages); must have the * appropriate size and will be updated. * \param MRCA the list where to place the address of segment * MRCA, if it occurs. * \param totalLength the total length of the tree. * \param segmentLengths the table of tree lengths per * segment. * * Assumes the current object has the correct number of * segments. * */ void coalescence(double date, Edge* son1, Edge* son2, unsigned int* edgesPerSegments, Edge** MRCA, double& totalLength, double* segmentLengths); /** \brief Generates a recombination event * * \param date the date of the event. * \param dest1 destination for the first resulting edge. * \param dest2 destination for the second resulting edge. * \param random pointer to the Random instance used by the * simulator. * \param totalLength the total length of the tree. * \param segmentLengths the table of tree lengths per * segment. * * dest1 and dest2 must be Edge address initialized with the * appropriate number of segments. * */ void recombination(double date, Edge* dest1, Edge* dest2, Random* random, double& totalLength, double* segmentLengths); /** \brief Define this edge to be terminal * * The edge have only non-covered segments * */ void set_terminal(unsigned int leaf_index); /// Branch's raw length (doesn't take account segment coverage) double length; /// Number of covered segments unsigned int coverage; /// Time position of the branch's bottom double bottom; /// Time position of the branch's top double top; /// Address of the first son Edge* son1; /// Address of the second son Edge* son2; /// Number of sons (0, 1 or 2) unsigned int numberOfSons; /// Checks if a given segment is covered inline bool segment(unsigned int segmentIndex) const { //while(segments[segmentIndex]==0) segmentIndex--; if (segments[segmentIndex]==0) return false; if (segments[segmentIndex]==UINT_MAX) return true; return segbools[segmentIndex]; } /// leaf index (0 for internal nodes) inline unsigned int label() const { return _label; } /// Number of mutations per segment unsigned int* numberOfMutationsPerActualSite; /// Sets the actual number of sites void set_actualNumberOfSites(unsigned int actualNumberOfSites); private: unsigned int _label; /// Default constructor is not available Edge(); /// Copy constructor is not available Edge(const Edge& edge) {} /// Assignment operator is not available Edge& operator=(const Edge& edge) { return *this; } void init(unsigned int numberOfSegments); unsigned int numberOfSegments; unsigned int* segments; bool* segbools; /// complete the covered ranges with UINT_MAX's and the non-covered by 0's inline void fill() { coverage=0.; unsigned int i=0,j; while (i<numberOfSegments) { if (segbools[i]==true) { coverage += segments[i]; for (j=1; j<segments[i]; j++) { segments[i+j] = UINT_MAX; } } i+=segments[i]; } } /// update containing Arg's branch lengths inline void update_lengths(double& totalLength, double* segmentLengths) { unsigned int i=0,j; while (i<numberOfSegments) { if (segbools[i]==true) { totalLength += segments[i]*length; for (j=0; j<segments[i]; j++) { segmentLengths[i+j] += length; } } i+=segments[i]; } } }; /** \brief Pool of Edge objects * * \ingroup coalesce * * Holds a pool of Edge objects that can be recycled to spare the * building burden. A construction time, a number of Edge objects * equals to the predicted number of needed instances should be * requested. The Edge's will be prebuilt immediately and delivered * upon request. After use, the Edge's should be released. It is only * possible to release the last issued Edge instance or all of them * at once. * */ class EdgePool { public: /// Default constructor (nothing allocated) EdgePool(); /// Destructor virtual ~EdgePool(); /** \brief Configure pool * * Pre-allocates a given number of Edge objects. The objects * will be immediately available. * * Data previously allocated (by a previous call of this * function or by the deliver() method) will be lost so it * can be required to use clear() before. * * \param numberOfSegments the number of segments of the * simulation; all Edge instances will use this value. * * \param numberOfPreAllocated the number of Edge that should * be kept ready for immediate use. * */ void set(unsigned int numberOfSegments, unsigned numberOfPreAllocated); /** \brief Frees internally stored memory * * This invalidate all points that have been delivered * previously. However, any previously set number of segments * (0, by default) is retained. * */ void clear(); /** \brief Deliver an Edge * * The object must not be freed by the client! This object is * allocated on the heap if the cache is not large enough, * only reset if it was previously released, or just delivered * if it is one of the initially allocated instances. * */ Edge* deliver(); /** \brief Release an Edge * * Release the last delivered Edge. The instance is only * cached for a potential future use; it is not freed nor * reset immediately. If no Edge's are in use, nothing is * done. * */ void releaseLast(); /** \brief Release all Edge's * * Release all delivered Edges. The instances are only * cached for a potential future use; they are not freed nor * reset immediately. If no Edge's are in use, nothing is * done. * */ void releaseAll(); private: /// Not available EdgePool(const EdgePool& ep) {} /// Not available EdgePool& operator=(const EdgePool& ep) { return *this; } unsigned int numberOfSegments; unsigned int used; unsigned int released; unsigned int ready; Edge** cache; }; } #endif