<commit_before>/*************************************************************************
 *
 *  $RCSfile: frm_module.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2004-04-13 11:19:01 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef FRM_MODULE_HXX
#include "frm_module.hxx"
#endif

#define FORMS_MODULE_IMPLEMENTATION_INCLUDE_CONTEXT
    #define FORMS_MODULE_NAMESPACE  frm
    #include "forms_module_impl.hxx"
#undef FORMS_MODULE_IMPLEMENTATION_INCLUDE_CONTEXT

<commit_msg>INTEGRATION: CWS ooo19126 (1.2.154); FILE MERGED 2005/09/05 13:50:40 rt 1.2.154.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: frm_module.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 23:00:36 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef FRM_MODULE_HXX
#include "frm_module.hxx"
#endif

#define FORMS_MODULE_IMPLEMENTATION_INCLUDE_CONTEXT
    #define FORMS_MODULE_NAMESPACE  frm
    #include "forms_module_impl.hxx"
#undef FORMS_MODULE_IMPLEMENTATION_INCLUDE_CONTEXT

<|endoftext|>


<commit_before><commit_msg>Avoiding creation of new string for component version.<commit_after><|endoftext|>


<commit_before>/*
 * HTTPConnection.cpp
 *****************************************************************************
 * Copyright (C) 2014-2015 - VideoLAN and VLC Authors
 *
 * This program 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 program 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 program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "HTTPConnection.hpp"
#include "ConnectionParams.hpp"
#include "Sockets.hpp"
#include "../adaptive/tools/Helper.h"

#include <sstream>
#include <vlc_stream.h>

using namespace adaptive::http;

AbstractConnection::AbstractConnection(vlc_object_t *p_object_)
{
    p_object = p_object_;
    available = true;
    bytesRead = 0;
    contentLength = 0;
}

AbstractConnection::~AbstractConnection()
{

}

bool AbstractConnection::prepare(const ConnectionParams &params_)
{
    if (!available)
        return false;
    params = params_;
    available = false;
    return true;
}

size_t AbstractConnection::getContentLength() const
{
    return contentLength;
}

HTTPConnection::HTTPConnection(vlc_object_t *p_object_, Socket *socket_, bool persistent)
    : AbstractConnection( p_object_ )
{
    socket = socket_;
    psz_useragent = var_InheritString(p_object_, "http-user-agent");
    queryOk = false;
    retries = 0;
    connectionClose = !persistent;
}

HTTPConnection::~HTTPConnection()
{
    free(psz_useragent);
    delete socket;
}

bool HTTPConnection::canReuse(const ConnectionParams &params_) const
{
    return ( available &&
             params.getHostname() == params_.getHostname() &&
             params.getScheme() == params_.getScheme() &&
             params.getPort() == params_.getPort() );
}

bool HTTPConnection::connect()
{
    return socket->connect(p_object, params.getHostname().c_str(),
                                     params.getPort());
}

bool HTTPConnection::connected() const
{
    return socket->connected();
}

void HTTPConnection::disconnect()
{
    queryOk = false;
    bytesRead = 0;
    contentLength = 0;
    bytesRange = BytesRange();
    socket->disconnect();
}

int HTTPConnection::request(const std::string &path, const BytesRange &range)
{
    queryOk = false;

    /* Set new path for this query */
    params.setPath(path);

    msg_Dbg(p_object, "Retrieving %s @%zu", params.getUrl().c_str(),
                       range.isValid() ? range.getStartByte() : 0);

    if(!connected() && ( params.getHostname().empty() || !connect() ))
        return VLC_EGENERIC;

    bytesRange = range;
    if(range.isValid() && range.getEndByte() > 0)
        contentLength = range.getEndByte() - range.getStartByte() + 1;

    std::string header = buildRequestHeader(path);
    if(connectionClose)
        header.append("Connection: close\r\n");
    header.append("\r\n");

    if(!send( header ))
    {
        socket->disconnect();
        if(!connectionClose)
        {
            /* server closed connection pipeline after last req. need new */
            connectionClose = true;
            return request(path, range);
        }
        return VLC_EGENERIC;
    }

    int i_ret = parseReply();
    if(i_ret == VLC_SUCCESS)
    {
        queryOk = true;
    }
    else if(i_ret == VLC_EGENERIC)
    {
        socket->disconnect();
        if(!connectionClose)
        {
            connectionClose = true;
            return request(path, range);
        }
    }

    return i_ret;
}

ssize_t HTTPConnection::read(void *p_buffer, size_t len)
{
    if( !connected() ||
       (!queryOk && bytesRead == 0) )
        return VLC_EGENERIC;

    if(len == 0)
        return VLC_SUCCESS;

    queryOk = false;

    const size_t toRead = (contentLength) ? contentLength - bytesRead : len;
    if (toRead == 0)
        return VLC_SUCCESS;

    if(len > toRead)
        len = toRead;

    ssize_t ret = socket->read(p_object, p_buffer, len);
    if(ret >= 0)
        bytesRead += ret;

    if(ret < 0 || (size_t)ret < len) /* set EOF */
    {
        socket->disconnect();
        return ret;
    }

    return ret;
}

bool HTTPConnection::send(const std::string &data)
{
    return send(data.c_str(), data.length());
}

bool HTTPConnection::send(const void *buf, size_t size)
{
    return socket->send(p_object, buf, size);
}

int HTTPConnection::parseReply()
{
    std::string line = readLine();

    if(line.empty())
        return VLC_EGENERIC;

    if (line.compare(0, 9, "HTTP/1.1 ")!=0)
        return VLC_ENOOBJ;

    std::istringstream ss(line.substr(9));
    ss.imbue(std::locale("C"));
    int replycode;
    ss >> replycode;
    if (replycode != 200 && replycode != 206)
        return VLC_ENOOBJ;

    line = readLine();

    while(!line.empty() && line.compare("\r\n"))
    {
        size_t split = line.find_first_of(':');
        size_t value = split + 1;

        while(line.at(value) == ' ')
            value++;

        onHeader(line.substr(0, split), line.substr(value));
        line = readLine();
    }

    return VLC_SUCCESS;
}

std::string HTTPConnection::readLine()
{
    return socket->readline(p_object);
}

void HTTPConnection::setUsed( bool b )
{
    available = !b;
    if(available)
    {
        if(!connectionClose && contentLength == bytesRead )
        {
            queryOk = false;
            bytesRead = 0;
            contentLength = 0;
            bytesRange = BytesRange();
        }
        else  /* We can't resend request if we haven't finished reading */
            disconnect();
    }
}

void HTTPConnection::onHeader(const std::string &key,
                              const std::string &value)
{
    if(key == "Content-Length")
    {
        std::istringstream ss(value);
        ss.imbue(std::locale("C"));
        size_t length;
        ss >> length;
        contentLength = length;
    }
    else if (key == "Connection" && value =="close")
    {
        connectionClose = true;
    }
}

std::string HTTPConnection::buildRequestHeader(const std::string &path) const
{
    std::stringstream req;
    req << "GET " << path << " HTTP/1.1\r\n" <<
           "Host: " << params.getHostname() << "\r\n" <<
           "Cache-Control: no-cache" << "\r\n" <<
           "Accept-Encoding: " << "\r\n" <<
           "User-Agent: " << std::string(psz_useragent) << "\r\n";
    req << extraRequestHeaders();
    return req.str();
}

std::string HTTPConnection::extraRequestHeaders() const
{
    std::stringstream ss;
    ss.imbue(std::locale("C"));
    if(bytesRange.isValid())
    {
        ss << "Range: bytes=" << bytesRange.getStartByte() << "-";
        if(bytesRange.getEndByte())
            ss << bytesRange.getEndByte();
        ss << "\r\n";
    }
    return ss.str();
}

ConnectionFactory::ConnectionFactory()
{
}

ConnectionFactory::~ConnectionFactory()
{
}

AbstractConnection * ConnectionFactory::createConnection(vlc_object_t *p_object,
                                                         const ConnectionParams &params)
{
    if((params.getScheme() != "http" && params.getScheme() != "https") || params.getHostname().empty())
        return NULL;

    const int sockettype = (params.getScheme() == "https") ? TLSSocket::TLS : Socket::REGULAR;
    Socket *socket = (sockettype == TLSSocket::TLS) ? new (std::nothrow) TLSSocket()
                                                    : new (std::nothrow) Socket();
    if(!socket)
        return NULL;

    /* disable pipelined tls until we have ticket/resume session support */
    HTTPConnection *conn = new (std::nothrow)
            HTTPConnection(p_object, socket, sockettype != TLSSocket::TLS);
    if(!conn)
    {
        delete socket;
        return NULL;
    }

    return conn;
}
<commit_msg>demux: adaptive: close when read contentlength<commit_after>/*
 * HTTPConnection.cpp
 *****************************************************************************
 * Copyright (C) 2014-2015 - VideoLAN and VLC Authors
 *
 * This program 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 program 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 program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "HTTPConnection.hpp"
#include "ConnectionParams.hpp"
#include "Sockets.hpp"
#include "../adaptive/tools/Helper.h"

#include <sstream>
#include <vlc_stream.h>

using namespace adaptive::http;

AbstractConnection::AbstractConnection(vlc_object_t *p_object_)
{
    p_object = p_object_;
    available = true;
    bytesRead = 0;
    contentLength = 0;
}

AbstractConnection::~AbstractConnection()
{

}

bool AbstractConnection::prepare(const ConnectionParams &params_)
{
    if (!available)
        return false;
    params = params_;
    available = false;
    return true;
}

size_t AbstractConnection::getContentLength() const
{
    return contentLength;
}

HTTPConnection::HTTPConnection(vlc_object_t *p_object_, Socket *socket_, bool persistent)
    : AbstractConnection( p_object_ )
{
    socket = socket_;
    psz_useragent = var_InheritString(p_object_, "http-user-agent");
    queryOk = false;
    retries = 0;
    connectionClose = !persistent;
}

HTTPConnection::~HTTPConnection()
{
    free(psz_useragent);
    delete socket;
}

bool HTTPConnection::canReuse(const ConnectionParams &params_) const
{
    return ( available &&
             params.getHostname() == params_.getHostname() &&
             params.getScheme() == params_.getScheme() &&
             params.getPort() == params_.getPort() );
}

bool HTTPConnection::connect()
{
    return socket->connect(p_object, params.getHostname().c_str(),
                                     params.getPort());
}

bool HTTPConnection::connected() const
{
    return socket->connected();
}

void HTTPConnection::disconnect()
{
    queryOk = false;
    bytesRead = 0;
    contentLength = 0;
    bytesRange = BytesRange();
    socket->disconnect();
}

int HTTPConnection::request(const std::string &path, const BytesRange &range)
{
    queryOk = false;

    /* Set new path for this query */
    params.setPath(path);

    msg_Dbg(p_object, "Retrieving %s @%zu", params.getUrl().c_str(),
                       range.isValid() ? range.getStartByte() : 0);

    if(!connected() && ( params.getHostname().empty() || !connect() ))
        return VLC_EGENERIC;

    bytesRange = range;
    if(range.isValid() && range.getEndByte() > 0)
        contentLength = range.getEndByte() - range.getStartByte() + 1;

    std::string header = buildRequestHeader(path);
    if(connectionClose)
        header.append("Connection: close\r\n");
    header.append("\r\n");

    if(!send( header ))
    {
        socket->disconnect();
        if(!connectionClose)
        {
            /* server closed connection pipeline after last req. need new */
            connectionClose = true;
            return request(path, range);
        }
        return VLC_EGENERIC;
    }

    int i_ret = parseReply();
    if(i_ret == VLC_SUCCESS)
    {
        queryOk = true;
    }
    else if(i_ret == VLC_EGENERIC)
    {
        socket->disconnect();
        if(!connectionClose)
        {
            connectionClose = true;
            return request(path, range);
        }
    }

    return i_ret;
}

ssize_t HTTPConnection::read(void *p_buffer, size_t len)
{
    if( !connected() ||
       (!queryOk && bytesRead == 0) )
        return VLC_EGENERIC;

    if(len == 0)
        return VLC_SUCCESS;

    queryOk = false;

    const size_t toRead = (contentLength) ? contentLength - bytesRead : len;
    if (toRead == 0)
        return VLC_SUCCESS;

    if(len > toRead)
        len = toRead;

    ssize_t ret = socket->read(p_object, p_buffer, len);
    if(ret >= 0)
        bytesRead += ret;

    if(ret < 0 || (size_t)ret < len || /* set EOF */
       contentLength == bytesRead )
    {
        socket->disconnect();
        return ret;
    }

    return ret;
}

bool HTTPConnection::send(const std::string &data)
{
    return send(data.c_str(), data.length());
}

bool HTTPConnection::send(const void *buf, size_t size)
{
    return socket->send(p_object, buf, size);
}

int HTTPConnection::parseReply()
{
    std::string line = readLine();

    if(line.empty())
        return VLC_EGENERIC;

    if (line.compare(0, 9, "HTTP/1.1 ")!=0)
        return VLC_ENOOBJ;

    std::istringstream ss(line.substr(9));
    ss.imbue(std::locale("C"));
    int replycode;
    ss >> replycode;
    if (replycode != 200 && replycode != 206)
        return VLC_ENOOBJ;

    line = readLine();

    while(!line.empty() && line.compare("\r\n"))
    {
        size_t split = line.find_first_of(':');
        size_t value = split + 1;

        while(line.at(value) == ' ')
            value++;

        onHeader(line.substr(0, split), line.substr(value));
        line = readLine();
    }

    return VLC_SUCCESS;
}

std::string HTTPConnection::readLine()
{
    return socket->readline(p_object);
}

void HTTPConnection::setUsed( bool b )
{
    available = !b;
    if(available)
    {
        if(!connectionClose && contentLength == bytesRead )
        {
            queryOk = false;
            bytesRead = 0;
            contentLength = 0;
            bytesRange = BytesRange();
        }
        else  /* We can't resend request if we haven't finished reading */
            disconnect();
    }
}

void HTTPConnection::onHeader(const std::string &key,
                              const std::string &value)
{
    if(key == "Content-Length")
    {
        std::istringstream ss(value);
        ss.imbue(std::locale("C"));
        size_t length;
        ss >> length;
        contentLength = length;
    }
    else if (key == "Connection" && value =="close")
    {
        connectionClose = true;
    }
}

std::string HTTPConnection::buildRequestHeader(const std::string &path) const
{
    std::stringstream req;
    req << "GET " << path << " HTTP/1.1\r\n" <<
           "Host: " << params.getHostname() << "\r\n" <<
           "Cache-Control: no-cache" << "\r\n" <<
           "Accept-Encoding: " << "\r\n" <<
           "User-Agent: " << std::string(psz_useragent) << "\r\n";
    req << extraRequestHeaders();
    return req.str();
}

std::string HTTPConnection::extraRequestHeaders() const
{
    std::stringstream ss;
    ss.imbue(std::locale("C"));
    if(bytesRange.isValid())
    {
        ss << "Range: bytes=" << bytesRange.getStartByte() << "-";
        if(bytesRange.getEndByte())
            ss << bytesRange.getEndByte();
        ss << "\r\n";
    }
    return ss.str();
}

ConnectionFactory::ConnectionFactory()
{
}

ConnectionFactory::~ConnectionFactory()
{
}

AbstractConnection * ConnectionFactory::createConnection(vlc_object_t *p_object,
                                                         const ConnectionParams &params)
{
    if((params.getScheme() != "http" && params.getScheme() != "https") || params.getHostname().empty())
        return NULL;

    const int sockettype = (params.getScheme() == "https") ? TLSSocket::TLS : Socket::REGULAR;
    Socket *socket = (sockettype == TLSSocket::TLS) ? new (std::nothrow) TLSSocket()
                                                    : new (std::nothrow) Socket();
    if(!socket)
        return NULL;

    /* disable pipelined tls until we have ticket/resume session support */
    HTTPConnection *conn = new (std::nothrow)
            HTTPConnection(p_object, socket, sockettype != TLSSocket::TLS);
    if(!conn)
    {
        delete socket;
        return NULL;
    }

    return conn;
}
<|endoftext|>


<commit_before>#include "read_bases.h"
#include "utils/hts_memory.h"

#include <string>
#include <sstream>
#include <stdexcept>

using namespace std;

namespace gamgee {
  const map<Base, const char*> ReadBases::base_to_string_map = { {Base::A, "A"}, {Base::C, "C"}, {Base::G, "G"}, {Base::T, "T"}, {Base::N, "N"} };

  /**
   * @brief creates a ReadBases object that points to htslib memory already allocated
   * @param sam_record a shared pointer to an htslib raw sam record pointer for this object to take shared ownership
   * @note the resulting ReadBases object shares ownership of the pre-allocated memory via
   *       shared_ptr reference counting
   */
  ReadBases::ReadBases(const std::shared_ptr<bam1_t>& sam_record) :
    m_sam_record { sam_record },
    m_bases { bam_get_seq(sam_record.get()) },
    m_num_bases { uint32_t((sam_record.get())->core.l_qseq) }
  {}

  /**
   * @brief creates a deep copy of a ReadBases object
   *
   * @note the copy will have exclusive ownership over the newly-allocated htslib memory
   */
  ReadBases::ReadBases(const ReadBases& other) :
    m_sam_record { utils::make_shared_sam(utils::sam_deep_copy(other.m_sam_record.get())) },
    m_bases { bam_get_seq(m_sam_record.get()) },
    m_num_bases { other.m_num_bases }
  {}

  /**
   * @brief creates a deep copy of a ReadBases object
   *
   * @note the copy will have exclusive ownership over the newly-allocated htslib memory
   */
  ReadBases& ReadBases::operator=(const ReadBases& other) {
    if ( &other == this )
      return *this;
    m_sam_record = utils::make_shared_sam(utils::sam_deep_copy(other.m_sam_record.get())); ///< shared_ptr assignment will take care of deallocating old sam record if necessary
    m_bases = bam_get_seq(m_sam_record.get());
    m_num_bases = other.m_num_bases;
    return *this;
  }

  /**
   * @brief access an individual base by index
   *
   * @return base at the specified index as an enumerated value
   */
  Base ReadBases::operator[](const uint32_t index) const {
    if ( index >= m_num_bases )
      throw out_of_range(string("Index ") + std::to_string(index) + " out of range in ReadBases::operator[]");
    return static_cast<Base>(bam_seqi(m_bases, index));
  }

  /**
   * @brief set an individual base at the given index to the specified value
   *
   * @note there's no way to implement this using non-const operator[], since
   *       we can't return a reference to a half-byte in memory
   */
  void ReadBases::set_base(const uint32_t index, const Base base) {
    if ( index >= m_num_bases )
      throw out_of_range(string("Index ") + std::to_string(index) + " out of range in ReadBases::set_base");

    m_bases[index >> 1] &= ~(0xF << ((~index & 1) << 2));   ///< zero out previous 4-bit base encoding
    m_bases[index >> 1] |= static_cast<uint8_t>(base) << ((~index & 1) << 2);  ///< insert new 4-bit base encoding
  }

  /**
   * @brief check whether this object contains the same bases as another ReadBases object
   */
  bool ReadBases::operator==(const ReadBases& other) const {
    if ( m_num_bases != other.m_num_bases )
      return false;

    for ( auto i = 0u; i < m_num_bases; ++i ) {
      if ( (*this)[i] != other[i] )
        return false;
    }

    return true;
  }

  /**
   * @brief check whether this object does not contain the same bases as another ReadBases object
   */
  bool ReadBases::operator!=(const ReadBases& other) const {
    return !(*this == other);
  }

  /**
   * @brief returns a string representation of the bases in this read
   */
  string ReadBases::to_string() const {
    stringstream ss;

    for ( uint32_t i = 0; i < m_num_bases; i++ ) {
      ss << base_to_string_map.at((*this)[i]);
    }

    return ss.str();
  }
}
<commit_msg>ReadBases: move all boundary checks to utils::check_max_boundary<commit_after>#include "read_bases.h"
#include "utils/hts_memory.h"
#include "utils/utils.h"

#include <string>
#include <sstream>
#include <stdexcept>

using namespace std;

namespace gamgee {
  const map<Base, const char*> ReadBases::base_to_string_map = { {Base::A, "A"}, {Base::C, "C"}, {Base::G, "G"}, {Base::T, "T"}, {Base::N, "N"} };

  /**
   * @brief creates a ReadBases object that points to htslib memory already allocated
   * @param sam_record a shared pointer to an htslib raw sam record pointer for this object to take shared ownership
   * @note the resulting ReadBases object shares ownership of the pre-allocated memory via
   *       shared_ptr reference counting
   */
  ReadBases::ReadBases(const std::shared_ptr<bam1_t>& sam_record) :
    m_sam_record { sam_record },
    m_bases { bam_get_seq(sam_record.get()) },
    m_num_bases { uint32_t((sam_record.get())->core.l_qseq) }
  {}

  /**
   * @brief creates a deep copy of a ReadBases object
   *
   * @note the copy will have exclusive ownership over the newly-allocated htslib memory
   */
  ReadBases::ReadBases(const ReadBases& other) :
    m_sam_record { utils::make_shared_sam(utils::sam_deep_copy(other.m_sam_record.get())) },
    m_bases { bam_get_seq(m_sam_record.get()) },
    m_num_bases { other.m_num_bases }
  {}

  /**
   * @brief creates a deep copy of a ReadBases object
   *
   * @note the copy will have exclusive ownership over the newly-allocated htslib memory
   */
  ReadBases& ReadBases::operator=(const ReadBases& other) {
    if ( &other == this )
      return *this;
    m_sam_record = utils::make_shared_sam(utils::sam_deep_copy(other.m_sam_record.get())); ///< shared_ptr assignment will take care of deallocating old sam record if necessary
    m_bases = bam_get_seq(m_sam_record.get());
    m_num_bases = other.m_num_bases;
    return *this;
  }

  /**
   * @brief access an individual base by index
   *
   * @return base at the specified index as an enumerated value
   */
  Base ReadBases::operator[](const uint32_t index) const {
    utils::check_max_boundary(index, m_num_bases);
    return static_cast<Base>(bam_seqi(m_bases, index));
  }

  /**
   * @brief set an individual base at the given index to the specified value
   *
   * @note there's no way to implement this using non-const operator[], since
   *       we can't return a reference to a half-byte in memory
   */
  void ReadBases::set_base(const uint32_t index, const Base base) {
    utils::check_max_boundary(index, m_num_bases);
    m_bases[index >> 1] &= ~(0xF << ((~index & 1) << 2));   ///< zero out previous 4-bit base encoding
    m_bases[index >> 1] |= static_cast<uint8_t>(base) << ((~index & 1) << 2);  ///< insert new 4-bit base encoding
  }

  /**
   * @brief check whether this object contains the same bases as another ReadBases object
   */
  bool ReadBases::operator==(const ReadBases& other) const {
    if ( m_num_bases != other.m_num_bases )
      return false;

    for ( auto i = 0u; i < m_num_bases; ++i ) {
      if ( (*this)[i] != other[i] )
        return false;
    }

    return true;
  }

  /**
   * @brief check whether this object does not contain the same bases as another ReadBases object
   */
  bool ReadBases::operator!=(const ReadBases& other) const {
    return !(*this == other);
  }

  /**
   * @brief returns a string representation of the bases in this read
   */
  string ReadBases::to_string() const {
    stringstream ss;

    for ( uint32_t i = 0; i < m_num_bases; i++ ) {
      ss << base_to_string_map.at((*this)[i]);
    }

    return ss.str();
  }
}
<|endoftext|>


<commit_before>#ifndef GARF_SPLIT_FITTER_HPP
#define GARF_SPLIT_FITTER_HPP

#include <random>

#include "options.hpp"
#include "splitter.hpp"
#include "util/multi_dim_gaussian.hpp"
#include "util/information_gain.hpp"

namespace garf {

    template<typename FeatT, typename LabT>
    class SplFitter {
    public:
        const SplitOptions split_opts;
        const label_idx_t label_dims;
        const datapoint_idx_t total_num_datapoints;
        const feat_idx_t feature_dimensionality;

        util::MultiDimGaussianX<LabT> left_child_dist;
        util::MultiDimGaussianX<LabT> right_child_dist;

        RngSource rng; // Mersenne twister

        // ref to the mutex which we need to lock to print anything
        tbb::mutex & print_mutex;

        // Store all the different feature values for every single datapoint to land at the node.
        // We made this total_datapoints x num_splits_to_try, which will only be fully used
        // at the root node, afterwards we only use however many topmost rows as we need.
        feature_mtx<FeatT> candidate_feature_values;

        // Store the min and max values for each feature we are trying to generate data on
        feature_vec<FeatT> min_feature_values;
        feature_vec<FeatT> max_feature_values;

        // Temporary vector to store which direction things go in (to calculate
        // information gains etc) -
        split_dir_vec candidate_split_directions;

        // Temporary vectors to store which data is going left and right. As with feature_values
        // we only need
        data_indices_vec samples_going_left;
        data_indices_vec samples_going_right;

        // Keep track of the amounts in the above vectors which are valid
        datapoint_idx_t num_going_left;
        datapoint_idx_t num_going_right;

        LabT best_inf_gain;
        bool good_split_found;

        // This stores the randomly samples thresholds we come up with for each feature,
        // it is initialised to size num_splits_to_try x threshes_per_split
        feature_mtx<FeatT> split_thresholds;

        // Pick some thresholds for each candidate feature, with min and max values
        void generate_split_thresholds();

        // Check whether the candidate splits are okay
        void check_split_thresholds();

        // Find the min and max values of the features we have
        void find_min_max_features(const datapoint_idx_t num_in_parent);

        bool is_admissible_split(eigen_idx_t num_going_left, eigen_idx_t num_going_right) const;

        void evaluate_single_split(const data_indices_vec & data_indices,
                                   const datapoint_idx_t num_in_parent,
                                   split_idx_t split_feature, FeatT thresh,
                                   split_dir_vec * candidate_split_directions,
                                   data_indices_vec * const indices_going_left,
                                   data_indices_vec * const indices_going_right,
                                   datapoint_idx_t * const num_going_left,
                                   datapoint_idx_t * const num_going_right) const;

        SplFitter(const SplitOptions & _split_opts,
                  datapoint_idx_t _total_num_datapoints,
                  feat_idx_t _feature_dimensionality,
                  label_idx_t _label_dims,
                  tbb::mutex & _print_mutex,
                  std::seed_seq * seed_value = NULL)
            : split_opts(_split_opts),
              label_dims(_label_dims),
              total_num_datapoints(_total_num_datapoints),
              feature_dimensionality(_feature_dimensionality),
              left_child_dist(_label_dims),
              right_child_dist(_label_dims),
              print_mutex(_print_mutex),
              candidate_feature_values(_total_num_datapoints, _split_opts.num_splits_to_try),
              min_feature_values(_split_opts.num_splits_to_try),
              max_feature_values(_split_opts.num_splits_to_try),
              candidate_split_directions(_total_num_datapoints),
              samples_going_left(_total_num_datapoints),
              samples_going_right(_total_num_datapoints),
              num_going_left(-1),
              num_going_right(-1),
              split_thresholds(_split_opts.num_splits_to_try, _split_opts.threshes_per_split) {
            // Seed the RNG
            if (split_opts.properly_random) {
                if (seed_value == NULL) {
                    throw std::logic_error("using proper randomness, but no random seed provided");
                }
                print_mutex.lock();
                std::cout << this << ": seeding RNG with proper randomness" << std::endl;   // << seed_value << std::endl;
                print_mutex.unlock();
                rng.seed(*seed_value);
            }
        };
    };

    template<typename FeatT, typename LabT>
    class AxisAlignedSplFitter : public SplFitter<FeatT, LabT> {

        // Used to select feature indices to pick from
        std::uniform_int_distribution<feat_idx_t> feat_idx_dist;

        // Store which features we are going to look at. this is a vector
        // of length split_opts.num_splits_to_try (currently constant per node)
        feat_idx_vec feature_indices_to_evaluate;

        // Fill the feature_indices_to_evaluate vector with some new features
        void select_candidate_features();

        // For each datapoint which lands in this node
        void evaluate_datapoints_at_each_feature(const feature_mtx<FeatT> & features,
                                                 const data_indices_vec & parent_data_indices,
                                                 const datapoint_idx_t num_in_parent);

        void set_parameters_in_splitter(const split_idx_t split_idx,
                                        const split_idx_t thresh_idx,
                                        AxisAlignedSplt<FeatT> * const split);

    public:

        AxisAlignedSplFitter(const SplitOptions & _split_opts,
                             datapoint_idx_t _total_num_datapoints,
                             feat_idx_t _feature_dimensionality,
                             label_idx_t _label_dims,
                             tbb::mutex & _print_mutex,
                             std::seed_seq * seed_value)
            : SplFitter<FeatT, LabT>(_split_opts, _total_num_datapoints, _feature_dimensionality, _label_dims, _print_mutex, seed_value),
              feat_idx_dist(0, _feature_dimensionality-1),
              feature_indices_to_evaluate(_split_opts.num_splits_to_try)
              {};

        // This is the function we call that does everything. The return values indicates
        // whether a decent split has been found
        bool choose_split_parameters(const feature_mtx<FeatT> & features,
                                     const label_mtx<LabT> & labels,
                                     const data_indices_vec & parent_data_indices,
                                     const util::MultiDimGaussianX<LabT> & parent_dist,
                                     AxisAlignedSplt<FeatT> * split,
                                     data_indices_vec * left_child_indices_out,
                                     data_indices_vec * right_child_indices_out);
    };

    template<typename FeatT, typename LabT>
    class TwoDimSplFitter : public SplFitter<FeatT, LabT> {

        // Used to select feature indices to pick from
        std::uniform_int_distribution<feat_idx_t> feat_idx_dist;

        // Used to select weights for
        std::normal_distribution<weight_t> weight_dist;

        // Store which features we are considering for the first feature
        feat_idx_vec feat_indices_1_to_evaluate;
        feat_idx_vec feat_indices_2_to_evaluate;

        // Store the weights are are multiplying each feature value by
        weight_vec weights_1_to_evaluate;
        weight_vec weights_2_to_evaluate;

        void select_candidate_features();

        // For each datapoint which lands in this node
        void evaluate_datapoints_at_each_feature(const feature_mtx<FeatT> & features,
                                                 const data_indices_vec & parent_data_indices,
                                                 const datapoint_idx_t num_in_parent);

        void set_parameters_in_splitter(const split_idx_t split_idx,
                                        const split_idx_t thresh_idx,
                                        TwoDimSplt<FeatT> * const splitter);
    public:

        TwoDimSplFitter(const SplitOptions & _split_opts,
                        datapoint_idx_t _total_num_datapoints,
                        feat_idx_t _feature_dimensionality,
                        label_idx_t _label_dims,
                        tbb::mutex & _print_mutex,
                        std::seed_seq * seed_value)
            : SplFitter<FeatT, LabT>(_split_opts, _total_num_datapoints, _feature_dimensionality, _label_dims, _print_mutex, seed_value),
            feat_idx_dist(0, _feature_dimensionality-1),
            weight_dist(0, 1),  // standard normal distribution
            feat_indices_1_to_evaluate(_split_opts.num_splits_to_try),
            feat_indices_2_to_evaluate(_split_opts.num_splits_to_try),
            weights_1_to_evaluate(_split_opts.num_splits_to_try),
            weights_2_to_evaluate(_split_opts.num_splits_to_try)
            {};

        bool choose_split_parameters(const feature_mtx<FeatT> & features,
                                     const label_mtx<LabT> & labels,
                                     const data_indices_vec & parent_data_indices,
                                     const util::MultiDimGaussianX<LabT> & parent_dist,
                                     TwoDimSplt<FeatT> * split,
                                     data_indices_vec * left_child_indices_out,
                                     data_indices_vec * right_child_indices_out);
    };
}

#include "splits/splfitter.cpp"
#include "splits/axis_aligned_splfitter.cpp"
#include "splits/two_dim_splfitter.cpp"

#endif<commit_msg>stopped extraneous printing about random seeds<commit_after>#ifndef GARF_SPLIT_FITTER_HPP
#define GARF_SPLIT_FITTER_HPP

#include <random>

#include "options.hpp"
#include "splitter.hpp"
#include "util/multi_dim_gaussian.hpp"
#include "util/information_gain.hpp"

namespace garf {

    template<typename FeatT, typename LabT>
    class SplFitter {
    public:
        const SplitOptions split_opts;
        const label_idx_t label_dims;
        const datapoint_idx_t total_num_datapoints;
        const feat_idx_t feature_dimensionality;

        util::MultiDimGaussianX<LabT> left_child_dist;
        util::MultiDimGaussianX<LabT> right_child_dist;

        RngSource rng; // Mersenne twister

        // ref to the mutex which we need to lock to print anything
        tbb::mutex & print_mutex;

        // Store all the different feature values for every single datapoint to land at the node.
        // We made this total_datapoints x num_splits_to_try, which will only be fully used
        // at the root node, afterwards we only use however many topmost rows as we need.
        feature_mtx<FeatT> candidate_feature_values;

        // Store the min and max values for each feature we are trying to generate data on
        feature_vec<FeatT> min_feature_values;
        feature_vec<FeatT> max_feature_values;

        // Temporary vector to store which direction things go in (to calculate
        // information gains etc) -
        split_dir_vec candidate_split_directions;

        // Temporary vectors to store which data is going left and right. As with feature_values
        // we only need
        data_indices_vec samples_going_left;
        data_indices_vec samples_going_right;

        // Keep track of the amounts in the above vectors which are valid
        datapoint_idx_t num_going_left;
        datapoint_idx_t num_going_right;

        LabT best_inf_gain;
        bool good_split_found;

        // This stores the randomly samples thresholds we come up with for each feature,
        // it is initialised to size num_splits_to_try x threshes_per_split
        feature_mtx<FeatT> split_thresholds;

        // Pick some thresholds for each candidate feature, with min and max values
        void generate_split_thresholds();

        // Check whether the candidate splits are okay
        void check_split_thresholds();

        // Find the min and max values of the features we have
        void find_min_max_features(const datapoint_idx_t num_in_parent);

        bool is_admissible_split(eigen_idx_t num_going_left, eigen_idx_t num_going_right) const;

        void evaluate_single_split(const data_indices_vec & data_indices,
                                   const datapoint_idx_t num_in_parent,
                                   split_idx_t split_feature, FeatT thresh,
                                   split_dir_vec * candidate_split_directions,
                                   data_indices_vec * const indices_going_left,
                                   data_indices_vec * const indices_going_right,
                                   datapoint_idx_t * const num_going_left,
                                   datapoint_idx_t * const num_going_right) const;

        SplFitter(const SplitOptions & _split_opts,
                  datapoint_idx_t _total_num_datapoints,
                  feat_idx_t _feature_dimensionality,
                  label_idx_t _label_dims,
                  tbb::mutex & _print_mutex,
                  std::seed_seq * seed_value = NULL)
            : split_opts(_split_opts),
              label_dims(_label_dims),
              total_num_datapoints(_total_num_datapoints),
              feature_dimensionality(_feature_dimensionality),
              left_child_dist(_label_dims),
              right_child_dist(_label_dims),
              print_mutex(_print_mutex),
              candidate_feature_values(_total_num_datapoints, _split_opts.num_splits_to_try),
              min_feature_values(_split_opts.num_splits_to_try),
              max_feature_values(_split_opts.num_splits_to_try),
              candidate_split_directions(_total_num_datapoints),
              samples_going_left(_total_num_datapoints),
              samples_going_right(_total_num_datapoints),
              num_going_left(-1),
              num_going_right(-1),
              split_thresholds(_split_opts.num_splits_to_try, _split_opts.threshes_per_split) {
            // Seed the RNG
            if (split_opts.properly_random) {
                if (seed_value == NULL) {
                    throw std::logic_error("using proper randomness, but no random seed provided");
                }
                // print_mutex.lock();
                // std::cout << this << ": seeding RNG with proper randomness" << std::endl;   // << seed_value << std::endl;
                // print_mutex.unlock();
                rng.seed(*seed_value);
            } else {
                print_mutex.lock();
                std::cout << this << ": WARNING not using real randomness" << std::endl;
                print_mutex.unlock();

            }
        };
    };

    template<typename FeatT, typename LabT>
    class AxisAlignedSplFitter : public SplFitter<FeatT, LabT> {

        // Used to select feature indices to pick from
        std::uniform_int_distribution<feat_idx_t> feat_idx_dist;

        // Store which features we are going to look at. this is a vector
        // of length split_opts.num_splits_to_try (currently constant per node)
        feat_idx_vec feature_indices_to_evaluate;

        // Fill the feature_indices_to_evaluate vector with some new features
        void select_candidate_features();

        // For each datapoint which lands in this node
        void evaluate_datapoints_at_each_feature(const feature_mtx<FeatT> & features,
                                                 const data_indices_vec & parent_data_indices,
                                                 const datapoint_idx_t num_in_parent);

        void set_parameters_in_splitter(const split_idx_t split_idx,
                                        const split_idx_t thresh_idx,
                                        AxisAlignedSplt<FeatT> * const split);

    public:

        AxisAlignedSplFitter(const SplitOptions & _split_opts,
                             datapoint_idx_t _total_num_datapoints,
                             feat_idx_t _feature_dimensionality,
                             label_idx_t _label_dims,
                             tbb::mutex & _print_mutex,
                             std::seed_seq * seed_value)
            : SplFitter<FeatT, LabT>(_split_opts, _total_num_datapoints, _feature_dimensionality, _label_dims, _print_mutex, seed_value),
              feat_idx_dist(0, _feature_dimensionality-1),
              feature_indices_to_evaluate(_split_opts.num_splits_to_try)
              {};

        // This is the function we call that does everything. The return values indicates
        // whether a decent split has been found
        bool choose_split_parameters(const feature_mtx<FeatT> & features,
                                     const label_mtx<LabT> & labels,
                                     const data_indices_vec & parent_data_indices,
                                     const util::MultiDimGaussianX<LabT> & parent_dist,
                                     AxisAlignedSplt<FeatT> * split,
                                     data_indices_vec * left_child_indices_out,
                                     data_indices_vec * right_child_indices_out);
    };

    template<typename FeatT, typename LabT>
    class TwoDimSplFitter : public SplFitter<FeatT, LabT> {

        // Used to select feature indices to pick from
        std::uniform_int_distribution<feat_idx_t> feat_idx_dist;

        // Used to select weights for
        std::normal_distribution<weight_t> weight_dist;

        // Store which features we are considering for the first feature
        feat_idx_vec feat_indices_1_to_evaluate;
        feat_idx_vec feat_indices_2_to_evaluate;

        // Store the weights are are multiplying each feature value by
        weight_vec weights_1_to_evaluate;
        weight_vec weights_2_to_evaluate;

        void select_candidate_features();

        // For each datapoint which lands in this node
        void evaluate_datapoints_at_each_feature(const feature_mtx<FeatT> & features,
                                                 const data_indices_vec & parent_data_indices,
                                                 const datapoint_idx_t num_in_parent);

        void set_parameters_in_splitter(const split_idx_t split_idx,
                                        const split_idx_t thresh_idx,
                                        TwoDimSplt<FeatT> * const splitter);
    public:

        TwoDimSplFitter(const SplitOptions & _split_opts,
                        datapoint_idx_t _total_num_datapoints,
                        feat_idx_t _feature_dimensionality,
                        label_idx_t _label_dims,
                        tbb::mutex & _print_mutex,
                        std::seed_seq * seed_value)
            : SplFitter<FeatT, LabT>(_split_opts, _total_num_datapoints, _feature_dimensionality, _label_dims, _print_mutex, seed_value),
            feat_idx_dist(0, _feature_dimensionality-1),
            weight_dist(0, 1),  // standard normal distribution
            feat_indices_1_to_evaluate(_split_opts.num_splits_to_try),
            feat_indices_2_to_evaluate(_split_opts.num_splits_to_try),
            weights_1_to_evaluate(_split_opts.num_splits_to_try),
            weights_2_to_evaluate(_split_opts.num_splits_to_try)
            {};

        bool choose_split_parameters(const feature_mtx<FeatT> & features,
                                     const label_mtx<LabT> & labels,
                                     const data_indices_vec & parent_data_indices,
                                     const util::MultiDimGaussianX<LabT> & parent_dist,
                                     TwoDimSplt<FeatT> * split,
                                     data_indices_vec * left_child_indices_out,
                                     data_indices_vec * right_child_indices_out);
    };
}

#include "splits/splfitter.cpp"
#include "splits/axis_aligned_splfitter.cpp"
#include "splits/two_dim_splfitter.cpp"

#endif<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2012-2014 Danny Y., Rapptz

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef GEARS_UTILITY_ANY_HPP
#define GEARS_UTILITY_ANY_HPP

#include <type_traits>
#include <utility>
#include <typeinfo>
#include <memory>

namespace gears {
namespace utility {
namespace detail {
struct bad_any_cast : public std::bad_cast {
    virtual const char* what() const noexcept {
        return "bad_any_cast";
    }
};
} // detail

class any {
private:
    template<typename T>
    using Decayed = typename std::decay<T>::type;

    struct base {
        virtual ~base() {}
        virtual std::unique_ptr<base> clone() const = 0;
    };

    std::unique_ptr<base> obj;

    template<typename T>
    struct object : base {
        static_assert(std::is_copy_constructible<Decayed<T>>(), "Concept violation: T is not CopyConstructible");
        template<typename U>
        object(U&& v): value(std::forward<U>(v)) {}
        T value;

        std::unique_ptr<base> clone() const {
            return std::unique_ptr<base>(new object<T>(value));
        }
    };

    std::unique_ptr<base> clone() const {
        return obj ? obj->clone() : nullptr;
    }
public:
    any() noexcept = default;
    template<typename T>
    any(T&& actual) noexcept: obj(new(std::nothrow) object<Decayed<T>>(std::forward<T>(actual))) {}
    any(any&)       = default;
    any(const any&) = default;
    any(any&&)      = default;

    explicit operator bool() const {
        return static_cast<bool>(obj);
    }

    template<typename T>
    bool is() const {
        auto ptr = dynamic_cast<object<Decayed<T>>*>(obj.get());
        return ptr;
    }

   template<typename T>
    Decayed<T>& as() {
        auto ptr = dynamic_cast<object<Decayed<T>>*>(obj.get());
        if(!ptr)
            throw detail::bad_any_cast();
        return ptr->value;
    }

    template<typename T>
    const Decayed<T>& as() const {
        auto ptr = dynamic_cast<object<Decayed<T>>*>(obj.get());
        if(!ptr)
            throw detail::bad_any_cast();
        return ptr->value;
    }

    any& operator=(const any& other) {
        if(obj == other.obj)
            return *this;

        obj = other.clone();
        return *this;
    }

    any& operator=(any&& other) {
        if(obj == other.obj)
            return *this;

        obj.swap(other.obj);
        return *this;
    }
};

template<typename T>
inline auto any_cast(const any& object) -> decltype(object.as<T>()) {
    return object.as<T>();
}
} // utility
} // gears

#endif // GEARS_UTILITY_ANY_HPP
<commit_msg>Fix some compiler errors dealing with any<commit_after>// The MIT License (MIT)

// Copyright (c) 2012-2014 Danny Y., Rapptz

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef GEARS_UTILITY_ANY_HPP
#define GEARS_UTILITY_ANY_HPP

#include <type_traits>
#include <utility>
#include <typeinfo>
#include <memory>

namespace gears {
namespace utility {
namespace detail {
struct bad_any_cast : public std::bad_cast {
    virtual const char* what() const noexcept {
        return "bad_any_cast";
    }
};
} // detail

class any {
private:
    template<typename T>
    using Decayed = typename std::decay<T>::type;

    struct base {
        virtual ~base() {}
        virtual std::unique_ptr<base> clone() const = 0;
    };

    std::unique_ptr<base> obj;

    template<typename T>
    struct object : base {
        static_assert(std::is_copy_constructible<Decayed<T>>(), "Concept violation: T is not CopyConstructible");
        template<typename U>
        object(U&& v): value(std::forward<U>(v)) {}
        T value;

        std::unique_ptr<base> clone() const {
            return std::unique_ptr<base>(new object<T>(value));
        }
    };

    std::unique_ptr<base> clone() const {
        return obj ? obj->clone() : nullptr;
    }
public:
    any() noexcept = default;
    template<typename T>
    any(T&& actual) noexcept: obj(new(std::nothrow) object<Decayed<T>>(std::forward<T>(actual))) {}
    any(const any& other): obj(other.clone()) {}
    any(any&& other): obj(std::move(other.obj)) {}

    any& operator=(const any& other) {
        if(obj == other.obj)
            return *this;

        obj = other.clone();
        return *this;
    }

    any& operator=(any&& other) {
        if(obj == other.obj)
            return *this;

        obj.swap(other.obj);
        return *this;
    }

    explicit operator bool() const {
        return static_cast<bool>(obj);
    }

    template<typename T>
    bool is() const {
        auto ptr = dynamic_cast<object<Decayed<T>>*>(obj.get());
        return ptr;
    }

   template<typename T>
    Decayed<T>& as() {
        auto ptr = dynamic_cast<object<Decayed<T>>*>(obj.get());
        if(!ptr)
            throw detail::bad_any_cast();
        return ptr->value;
    }

    template<typename T>
    const Decayed<T>& as() const {
        auto ptr = dynamic_cast<object<Decayed<T>>*>(obj.get());
        if(!ptr)
            throw detail::bad_any_cast();
        return ptr->value;
    }
};

template<typename T>
inline auto any_cast(const any& object) -> decltype(object.as<T>()) {
    return object.as<T>();
}
} // utility
} // gears

#endif // GEARS_UTILITY_ANY_HPP
<|endoftext|>


<commit_before>// @(#)root/thread:$Id$
// Author: Enric Tejedor, CERN  12/09/2016

/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TTreeProcessorMT
#define ROOT_TTreeProcessorMT

#include "TKey.h"
#include "TTree.h"
#include "TFile.h"
#include "TChain.h"
#include "TTreeReader.h"
#include "TError.h"
#include "TEntryList.h"
#include "ROOT/TThreadedObject.hxx"

#include <string.h>
#include <functional>
#include <vector>

/** \class TTreeView
    \brief A helper class that encapsulates a file and a tree.

A helper class that encapsulates a TFile and a TTree, along with their names.
It is used together with TTProcessor and ROOT::TThreadedObject, so that
in the TTProcessor::Process method each thread can work on its own
<TFile,TTree> pair.

This class can also be used with a collection of file names or a TChain, in case
the tree is stored in more than one file. A view will always contain only the
current (active) tree and file objects.

A copy constructor is defined for TTreeView to work with ROOT::TThreadedObject.
The latter makes a copy of a model object every time a new thread accesses
the threaded object.
*/

namespace ROOT {
   namespace Internal {
      class TTreeView {
      private:
         std::vector<std::string> fFileNames; ///< Names of the files
         std::string fTreeName;               ///< Name of the tree
         std::unique_ptr<TFile> fCurrentFile; ///<! Current file object of this view.
         std::unique_ptr<TTree> fCurrentTree; ///<! Current tree object of this view.
         unsigned int fCurrentIdx;            ///<! Index of the current file.
         std::vector<TEntryList> fEntryLists; ///< Entry numbers to be processed per tree/file
         TEntryList fCurrentEntryList;        ///< Entry numbers for the current range being processed

         ////////////////////////////////////////////////////////////////////////////////
         /// Initialize the file and the tree for this view, first looking for a tree in
         /// the file if necessary.
         void Init()
         {
            fCurrentFile.reset(TFile::Open(fFileNames[fCurrentIdx].data()));

            // If the tree name is empty, look for a tree in the file
            if (fTreeName.empty()) {
               TIter next(fCurrentFile->GetListOfKeys());
               while (TKey *key = (TKey*)next()) {
                  const char *className = key->GetClassName();
                  if (strcmp(className, "TTree") == 0) {
                     fTreeName = key->GetName();
                     break;
                  }
               }
               if (fTreeName.empty())
                  ::Error("TreeView constructor", "Cannot find any tree in file %s", fFileNames[fCurrentIdx].data());
            }

            // We cannot use here the template method (TFile::GetObject) because the header will finish
            // in the PCH and the specialization will be available. PyROOT will not be able to specialize
            // the method for types other that TTree.
            TTree *tp = (TTree*)fCurrentFile->Get(fTreeName.data());
            fCurrentTree.reset(tp);
         }

      public:
         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a file name.
         /// \param[in] fn Name of the file containing the tree to process.
         /// \param[in] tn Name of the tree to process. If not provided,
         ///               the implementation will automatically search for a
         ///               tree in the file.
         TTreeView(std::string_view fn, std::string_view tn) : fTreeName(tn), fCurrentIdx(0)
         {
            fFileNames.emplace_back(fn);
            Init();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a collection of file names.
         /// \param[in] fns Collection of file names containing the tree to process.
         /// \param[in] tn Name of the tree to process. If not provided,
         ///               the implementation will automatically search for a
         ///               tree in the collection of files.
         TTreeView(const std::vector<std::string_view>& fns, std::string_view tn) : fTreeName(tn), fCurrentIdx(0)
         {
            if (fns.size() > 0) {
               for (auto& fn : fns)
                  fFileNames.emplace_back(fn);
               Init();
             }
             else {
                ::Error("TreeView constructor", "The provided list of file names is empty, cannot process tree %s", fTreeName.data());
             }
         }

         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a TTree.
         /// \param[in] tree Tree or chain of files containing the tree to process.
         TTreeView(TTree& tree) : fTreeName(tree.GetName()), fCurrentIdx(0)
         {
            static const TClassRef clRefTChain("TChain");
            if (clRefTChain == tree.IsA()) {
               TObjArray* filelist = dynamic_cast<TChain&>(tree).GetListOfFiles();
               if (filelist->GetEntries() > 0) {
                  for (auto f : *filelist)
                     fFileNames.emplace_back(f->GetTitle());
                  Init();
               }
               else {
                  ::Error("TreeView constructor", "The provided chain of files is empty, cannot process tree %s", fTreeName.data());
               }
            }
            else {
               fFileNames.emplace_back(tree.GetCurrentFile()->GetName());
               Init();
            }
         }

         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a TTree and a TEntryList.
         /// \param[in] tree Tree or chain of files containing the tree to process.
         /// \param[in] entries List of entry numbers to process.
         TTreeView(TTree& tree, TEntryList& entries) : TTreeView(tree)
         {
            static const TClassRef clRefTChain("TChain");
            if (clRefTChain == tree.IsA()) {
               // We need to convert the global entry numbers to per-tree entry numbers.
               // This will allow us to build a TEntryList for a given entry range of a tree of the chain.
               size_t nTrees = fFileNames.size();
               fEntryLists.resize(nTrees);

               TChain *chain = dynamic_cast<TChain*>(&tree);
               Long64_t currListEntry  = entries.GetEntry(0);
               Long64_t currTreeOffset = 0;

               for (unsigned int treeNum = 0; treeNum < nTrees && currListEntry >= 0; ++treeNum) {
                  chain->LoadTree(currTreeOffset);
                  TTree *currTree = chain->GetTree();
                  Long64_t currTreeEntries = currTree->GetEntries();
                  Long64_t nextTreeOffset = currTreeOffset + currTreeEntries;

                  while (currListEntry >= 0 && currListEntry < nextTreeOffset) {
                     fEntryLists[treeNum].Enter(currListEntry - currTreeOffset);
                     currListEntry = entries.Next();
                  }

                  currTreeOffset = nextTreeOffset;
               }
            }
            else {
               fEntryLists.emplace_back(entries);
            }
         }

         //////////////////////////////////////////////////////////////////////////
         /// Copy constructor.
         /// \param[in] view Object to copy.
         TTreeView(const TTreeView& view) : fTreeName(view.fTreeName), fCurrentIdx(view.fCurrentIdx)
         {
            for (auto& fn : view.fFileNames)
               fFileNames.emplace_back(fn);

            for (auto& el : view.fEntryLists)
               fEntryLists.emplace_back(el);

            Init();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get the cluster iterator for the current tree of this view, starting
         /// from entry zero.
         TTree::TClusterIterator GetClusterIterator()
         {
            return fCurrentTree->GetClusterIterator(0);
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get a TTreeReader for the current tree of this view.
         std::unique_ptr<TTreeReader> GetTreeReader(Long64_t start, Long64_t end)
         {
            TTreeReader *reader;
            if (fEntryLists.size() > 0 && fEntryLists[fCurrentIdx].GetN() > 0) {
               // TEntryList and SetEntriesRange do not work together (the former has precedence).
               // We need to construct a TEntryList that contains only those entry numbers
               // in our desired range.
               fCurrentEntryList.Reset();
               Long64_t entry = fEntryLists[fCurrentIdx].GetEntry(0);
               do {
                  if (entry >= start && entry < end) fCurrentEntryList.Enter(entry);
               } while ((entry = fEntryLists[fCurrentIdx].Next()) >= 0);

               reader = new TTreeReader(fCurrentTree.get(), &fCurrentEntryList);

            }
            else {
               // If no TEntryList is involved we can safely set the range in the reader
               reader = new TTreeReader(fCurrentTree.get());
               reader->SetEntriesRange(start, end);
            }

            return std::unique_ptr<TTreeReader>(reader);
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get the number of entries of the current tree of this view.
         Long64_t GetEntries() const
         {
            return fCurrentTree->GetEntries();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get the number of files of this view.
         size_t GetNumFiles() const
         {
            return fFileNames.size();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Set the current file and tree of this view.
         void SetCurrent(unsigned int i)
         {
            if (i != fCurrentIdx) {
               fCurrentIdx = i;
               TFile *f = TFile::Open(fFileNames[fCurrentIdx].data());
               TTree *t = (TTree*)f->Get(fTreeName.data());
               fCurrentTree.reset(t);
               fCurrentFile.reset(f);
            }
         }
      };
   } // End of namespace Internal

   class TTreeProcessorMT {
   private:
      ROOT::TThreadedObject<ROOT::Internal::TTreeView> treeView; ///<! Threaded object with <file,tree> per thread

   public:
      TTreeProcessorMT(std::string_view filename, std::string_view treename = "");
      TTreeProcessorMT(const std::vector<std::string_view>& filenames, std::string_view treename = "");
      TTreeProcessorMT(TTree& tree);
      TTreeProcessorMT(TTree& tree, TEntryList& entries);

      void Process(std::function<void(TTreeReader&)> func);

   };

} // End of namespace ROOT

#endif // defined TTreeProcessorMT
<commit_msg>Fix race condition when removing TTrees from list of cleanups concurrently<commit_after>// @(#)root/thread:$Id$
// Author: Enric Tejedor, CERN  12/09/2016

/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TTreeProcessorMT
#define ROOT_TTreeProcessorMT

#include "TKey.h"
#include "TTree.h"
#include "TFile.h"
#include "TChain.h"
#include "TTreeReader.h"
#include "TError.h"
#include "TEntryList.h"
#include "ROOT/TThreadedObject.hxx"

#include <string.h>
#include <functional>
#include <vector>

/** \class TTreeView
    \brief A helper class that encapsulates a file and a tree.

A helper class that encapsulates a TFile and a TTree, along with their names.
It is used together with TTProcessor and ROOT::TThreadedObject, so that
in the TTProcessor::Process method each thread can work on its own
<TFile,TTree> pair.

This class can also be used with a collection of file names or a TChain, in case
the tree is stored in more than one file. A view will always contain only the
current (active) tree and file objects.

A copy constructor is defined for TTreeView to work with ROOT::TThreadedObject.
The latter makes a copy of a model object every time a new thread accesses
the threaded object.
*/

namespace ROOT {
   namespace Internal {
      class TTreeView {
      private:
         std::vector<std::string> fFileNames; ///< Names of the files
         std::string fTreeName;               ///< Name of the tree
         std::unique_ptr<TFile> fCurrentFile; ///<! Current file object of this view.
         TTree *fCurrentTree;                 ///<! Current tree object of this view.
         unsigned int fCurrentIdx;            ///<! Index of the current file.
         std::vector<TEntryList> fEntryLists; ///< Entry numbers to be processed per tree/file
         TEntryList fCurrentEntryList;        ///< Entry numbers for the current range being processed

         ////////////////////////////////////////////////////////////////////////////////
         /// Initialize the file and the tree for this view, first looking for a tree in
         /// the file if necessary.
         void Init()
         {
            fCurrentFile.reset(TFile::Open(fFileNames[fCurrentIdx].data()));

            // If the tree name is empty, look for a tree in the file
            if (fTreeName.empty()) {
               TIter next(fCurrentFile->GetListOfKeys());
               while (TKey *key = (TKey*)next()) {
                  const char *className = key->GetClassName();
                  if (strcmp(className, "TTree") == 0) {
                     fTreeName = key->GetName();
                     break;
                  }
               }
               if (fTreeName.empty())
                  ::Error("TreeView constructor", "Cannot find any tree in file %s", fFileNames[fCurrentIdx].data());
            }

            // We cannot use here the template method (TFile::GetObject) because the header will finish
            // in the PCH and the specialization will be available. PyROOT will not be able to specialize
            // the method for types other that TTree.
            fCurrentTree = (TTree*)fCurrentFile->Get(fTreeName.data());

            // Do not remove this tree from list of cleanups (thread unsafe)
            fCurrentTree->ResetBit(TObject::kMustCleanup);
         }

      public:
         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a file name.
         /// \param[in] fn Name of the file containing the tree to process.
         /// \param[in] tn Name of the tree to process. If not provided,
         ///               the implementation will automatically search for a
         ///               tree in the file.
         TTreeView(std::string_view fn, std::string_view tn) : fTreeName(tn), fCurrentIdx(0)
         {
            fFileNames.emplace_back(fn);
            Init();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a collection of file names.
         /// \param[in] fns Collection of file names containing the tree to process.
         /// \param[in] tn Name of the tree to process. If not provided,
         ///               the implementation will automatically search for a
         ///               tree in the collection of files.
         TTreeView(const std::vector<std::string_view>& fns, std::string_view tn) : fTreeName(tn), fCurrentIdx(0)
         {
            if (fns.size() > 0) {
               for (auto& fn : fns)
                  fFileNames.emplace_back(fn);
               Init();
             }
             else {
                ::Error("TreeView constructor", "The provided list of file names is empty, cannot process tree %s", fTreeName.data());
             }
         }

         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a TTree.
         /// \param[in] tree Tree or chain of files containing the tree to process.
         TTreeView(TTree& tree) : fTreeName(tree.GetName()), fCurrentIdx(0)
         {
            static const TClassRef clRefTChain("TChain");
            if (clRefTChain == tree.IsA()) {
               TObjArray* filelist = dynamic_cast<TChain&>(tree).GetListOfFiles();
               if (filelist->GetEntries() > 0) {
                  for (auto f : *filelist)
                     fFileNames.emplace_back(f->GetTitle());
                  Init();
               }
               else {
                  ::Error("TreeView constructor", "The provided chain of files is empty, cannot process tree %s", fTreeName.data());
               }
            }
            else {
               fFileNames.emplace_back(tree.GetCurrentFile()->GetName());
               Init();
            }
         }

         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a TTree and a TEntryList.
         /// \param[in] tree Tree or chain of files containing the tree to process.
         /// \param[in] entries List of entry numbers to process.
         TTreeView(TTree& tree, TEntryList& entries) : TTreeView(tree)
         {
            static const TClassRef clRefTChain("TChain");
            if (clRefTChain == tree.IsA()) {
               // We need to convert the global entry numbers to per-tree entry numbers.
               // This will allow us to build a TEntryList for a given entry range of a tree of the chain.
               size_t nTrees = fFileNames.size();
               fEntryLists.resize(nTrees);

               TChain *chain = dynamic_cast<TChain*>(&tree);
               Long64_t currListEntry  = entries.GetEntry(0);
               Long64_t currTreeOffset = 0;

               for (unsigned int treeNum = 0; treeNum < nTrees && currListEntry >= 0; ++treeNum) {
                  chain->LoadTree(currTreeOffset);
                  TTree *currTree = chain->GetTree();
                  Long64_t currTreeEntries = currTree->GetEntries();
                  Long64_t nextTreeOffset = currTreeOffset + currTreeEntries;

                  while (currListEntry >= 0 && currListEntry < nextTreeOffset) {
                     fEntryLists[treeNum].Enter(currListEntry - currTreeOffset);
                     currListEntry = entries.Next();
                  }

                  currTreeOffset = nextTreeOffset;
               }
            }
            else {
               fEntryLists.emplace_back(entries);
            }
         }

         //////////////////////////////////////////////////////////////////////////
         /// Copy constructor.
         /// \param[in] view Object to copy.
         TTreeView(const TTreeView& view) : fTreeName(view.fTreeName), fCurrentIdx(view.fCurrentIdx)
         {
            for (auto& fn : view.fFileNames)
               fFileNames.emplace_back(fn);

            for (auto& el : view.fEntryLists)
               fEntryLists.emplace_back(el);

            Init();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get the cluster iterator for the current tree of this view, starting
         /// from entry zero.
         TTree::TClusterIterator GetClusterIterator()
         {
            return fCurrentTree->GetClusterIterator(0);
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get a TTreeReader for the current tree of this view.
         std::unique_ptr<TTreeReader> GetTreeReader(Long64_t start, Long64_t end)
         {
            TTreeReader *reader;
            if (fEntryLists.size() > 0 && fEntryLists[fCurrentIdx].GetN() > 0) {
               // TEntryList and SetEntriesRange do not work together (the former has precedence).
               // We need to construct a TEntryList that contains only those entry numbers
               // in our desired range.
               fCurrentEntryList.Reset();
               Long64_t entry = fEntryLists[fCurrentIdx].GetEntry(0);
               do {
                  if (entry >= start && entry < end) fCurrentEntryList.Enter(entry);
               } while ((entry = fEntryLists[fCurrentIdx].Next()) >= 0);

               reader = new TTreeReader(fCurrentTree, &fCurrentEntryList);

            }
            else {
               // If no TEntryList is involved we can safely set the range in the reader
               reader = new TTreeReader(fCurrentTree);
               reader->SetEntriesRange(start, end);
            }

            return std::unique_ptr<TTreeReader>(reader);
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get the number of entries of the current tree of this view.
         Long64_t GetEntries() const
         {
            return fCurrentTree->GetEntries();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get the number of files of this view.
         size_t GetNumFiles() const
         {
            return fFileNames.size();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Set the current file and tree of this view.
         void SetCurrent(unsigned int i)
         {
            if (i != fCurrentIdx) {
               fCurrentIdx = i;
               TFile *f = TFile::Open(fFileNames[fCurrentIdx].data());
               fCurrentTree = (TTree*)f->Get(fTreeName.data());
               fCurrentTree->ResetBit(TObject::kMustCleanup);
               fCurrentFile.reset(f);
            }
         }
      };
   } // End of namespace Internal

   class TTreeProcessorMT {
   private:
      ROOT::TThreadedObject<ROOT::Internal::TTreeView> treeView; ///<! Threaded object with <file,tree> per thread

   public:
      TTreeProcessorMT(std::string_view filename, std::string_view treename = "");
      TTreeProcessorMT(const std::vector<std::string_view>& filenames, std::string_view treename = "");
      TTreeProcessorMT(TTree& tree);
      TTreeProcessorMT(TTree& tree, TEntryList& entries);

      void Process(std::function<void(TTreeReader&)> func);

   };

} // End of namespace ROOT

#endif // defined TTreeProcessorMT
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////////////
//
// 'Bayesian Calculator' RooStats tutorial macro #701
// author: Gregory Schott
// date Sep 2009
//
// This tutorial shows an example of using the BayesianCalculator class
//
/////////////////////////////////////////////////////////////////////////

#include "RooRealVar.h"
#include "RooWorkspace.h"
#include "RooDataSet.h"
#include "RooPlot.h"
#include "RooMsgService.h"

#include "RooStats/BayesianCalculator.h"
#include "RooStats/SimpleInterval.h"
#include "TCanvas.h"

using namespace RooFit;
using namespace RooStats;

void rs701_BayesianCalculator(bool useBkg = true, double confLevel = 0.90)
{

  RooWorkspace* w = new RooWorkspace("w",true);
  w->factory("SUM::pdf(s[0,15]*Uniform(x[0,1]),b[1,0,2]*Uniform(x))");
  w->factory("Gaussian::prior_b(b,1,1)");
  w->factory("PROD::model(pdf,prior_b)");
  RooAbsPdf* model = w->pdf("model");  // pdf*priorNuisance
  RooArgSet nuisanceParameters(*(w->var("b")));

  RooAbsRealLValue* POI = w->var("s");
  RooAbsPdf* priorPOI  = (RooAbsPdf *) w->factory("Uniform::priorPOI(s)");
  RooAbsPdf* priorPOI2 = (RooAbsPdf *) w->factory("GenericPdf::priorPOI2('1/s',s)");

  w->factory("n[3]"); // observed number of events
  // create a data set with n observed events
  RooDataSet data("data","",RooArgSet(*(w->var("x")),*(w->var("n"))),"n");
  data.add(RooArgSet(*(w->var("x"))),w->var("n")->getVal());

  // to suppress messgaes when pdf goes to zero
  RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL) ;

  RooArgSet * nuisPar = 0;
  if (useBkg) nuisPar = &nuisanceParameters;
  //if (!useBkg) ((RooRealVar *)w->var("b"))->setVal(0);

  double size = 1.-confLevel;
  std::cout << "\nBayesian Result using a Flat prior " << std::endl;
  BayesianCalculator bcalc(data,*model,RooArgSet(*POI),*priorPOI, nuisPar);
  bcalc.SetTestSize(size);
  SimpleInterval* interval = bcalc.GetInterval();
  double cl = bcalc.ConfidenceLevel();
  std::cout << cl <<"% CL central interval: [ " << interval->LowerLimit() << " - " << interval->UpperLimit()
            << " ] or "
            << cl+(1.-cl)/2 << "% CL limits\n";
  RooPlot * plot = bcalc.GetPosteriorPlot();
  TCanvas * c1 = new TCanvas("c1","Bayesian Calculator Result");
  c1->Divide(1,2);
  c1->cd(1);
  plot->Draw();

  // don;t run with background events - will take too long
  std::cout << "\nBayesian Result using a 1/s prior (no background) " << std::endl;
  BayesianCalculator bcalc2(data,*model,RooArgSet(*POI),*priorPOI2);
  bcalc2.SetTestSize(size);
  SimpleInterval* interval2 = bcalc2.GetInterval();
  cl = bcalc2.ConfidenceLevel();
  std::cout << cl <<"% CL central interval: [ " << interval2->LowerLimit() << " - " << interval2->UpperLimit()
            << " ] or "
            << cl+(1.-cl)/2 << "% CL limits\n";

  RooPlot * plot2 = bcalc2.GetPosteriorPlot();
  c1->cd(2);
  plot2->Draw();
  c1->Update();

  // observe one event while expecting one background event -> the 95% CL upper limit on s is 4.10
  // observe one event while expecting zero background event -> the 95% CL upper limit on s is 4.74
}
<commit_msg>fix a problem with runniong 1/s prior. Use now also a 1/sqrt(s) prior<commit_after>/////////////////////////////////////////////////////////////////////////
//
// 'Bayesian Calculator' RooStats tutorial macro #701
// author: Gregory Schott
// date Sep 2009
//
// This tutorial shows an example of using the BayesianCalculator class
//
/////////////////////////////////////////////////////////////////////////

#include "RooRealVar.h"
#include "RooWorkspace.h"
#include "RooDataSet.h"
#include "RooPlot.h"
#include "RooMsgService.h"

#include "RooStats/BayesianCalculator.h"
#include "RooStats/SimpleInterval.h"
#include "TCanvas.h"

using namespace RooFit;
using namespace RooStats;

void rs701_BayesianCalculator(bool useBkg = true, double confLevel = 0.90)
{

  RooWorkspace* w = new RooWorkspace("w",true);
  w->factory("SUM::pdf(s[0.001,15]*Uniform(x[0,1]),b[1,0,2]*Uniform(x))");
  w->factory("Gaussian::prior_b(b,1,1)");
  w->factory("PROD::model(pdf,prior_b)");
  RooAbsPdf* model = w->pdf("model");  // pdf*priorNuisance
  RooArgSet nuisanceParameters(*(w->var("b")));

  RooAbsRealLValue* POI = w->var("s");
  RooAbsPdf* priorPOI  = (RooAbsPdf *) w->factory("Uniform::priorPOI(s)");
  RooAbsPdf* priorPOI2 = (RooAbsPdf *) w->factory("GenericPdf::priorPOI2('1/sqrt(@0)',s)");

  w->factory("n[3]"); // observed number of events
  // create a data set with n observed events
  RooDataSet data("data","",RooArgSet(*(w->var("x")),*(w->var("n"))),"n");
  data.add(RooArgSet(*(w->var("x"))),w->var("n")->getVal());

  // to suppress messgaes when pdf goes to zero
  RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL) ;

  RooArgSet * nuisPar = 0;
  if (useBkg) nuisPar = &nuisanceParameters;
  //if (!useBkg) ((RooRealVar *)w->var("b"))->setVal(0);

  double size = 1.-confLevel;
  std::cout << "\nBayesian Result using a Flat prior " << std::endl;
  BayesianCalculator bcalc(data,*model,RooArgSet(*POI),*priorPOI, nuisPar);
  bcalc.SetTestSize(size);
  SimpleInterval* interval = bcalc.GetInterval();
  double cl = bcalc.ConfidenceLevel();
  std::cout << cl <<"% CL central interval: [ " << interval->LowerLimit() << " - " << interval->UpperLimit()
            << " ] or "
            << cl+(1.-cl)/2 << "% CL limits\n";
  RooPlot * plot = bcalc.GetPosteriorPlot();
  TCanvas * c1 = new TCanvas("c1","Bayesian Calculator Result");
  c1->Divide(1,2);
  c1->cd(1);
  plot->Draw();
  c1->Update();

  std::cout << "\nBayesian Result using a 1/sqrt(s) prior  " << std::endl;
  BayesianCalculator bcalc2(data,*model,RooArgSet(*POI),*priorPOI2,nuisPar);
  bcalc2.SetTestSize(size);
  SimpleInterval* interval2 = bcalc2.GetInterval();
  cl = bcalc2.ConfidenceLevel();
  std::cout << cl <<"% CL central interval: [ " << interval2->LowerLimit() << " - " << interval2->UpperLimit()
            << " ] or "
            << cl+(1.-cl)/2 << "% CL limits\n";

  RooPlot * plot2 = bcalc2.GetPosteriorPlot();
  c1->cd(2);
  plot2->Draw();
  gPad->SetLogy();
  c1->Update();

  // observe one event while expecting one background event -> the 95% CL upper limit on s is 4.10
  // observe one event while expecting zero background event -> the 95% CL upper limit on s is 4.74
}
<|endoftext|>