<commit_before>// ---------------------------------------------------------------------
//
// Copyright (C) 1998 - 2017 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, 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.
// The full text of the license can be found in the file LICENSE at
// the top level of the deal.II distribution.
//
// ---------------------------------------------------------------------

#include <deal.II/base/exceptions.h>
#include <deal.II/base/logstream.h>
#include <deal.II/base/utilities.h>
#include <deal.II/base/mpi.h>

#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <sstream>

#ifdef DEAL_II_WITH_MPI
#  include <mpi.h>
#endif

#ifdef DEAL_II_HAVE_GLIBC_STACKTRACE
#  include <execinfo.h>
#endif

#ifdef DEAL_II_HAVE_LIBSTDCXX_DEMANGLER
#  include <cxxabi.h>
#endif

DEAL_II_NAMESPACE_OPEN

namespace deal_II_exceptions
{

  std::string additional_assert_output;

  void set_additional_assert_output (const char *const p)
  {
    additional_assert_output = p;
  }

  bool show_stacktrace = true;

  void suppress_stacktrace_in_exceptions ()
  {
    show_stacktrace = false;
  }

  bool abort_on_exception = true;

  void disable_abort_on_exception ()
  {
    abort_on_exception = false;
  }

}

ExceptionBase::ExceptionBase ()
  :
  file(""),
  line(0),
  function(""),
  cond(""),
  exc(""),
  stacktrace (nullptr),
  n_stacktrace_frames (0),
  what_str("")
{
#ifdef DEAL_II_HAVE_GLIBC_STACKTRACE
  for (unsigned int i=0; i<sizeof(raw_stacktrace)/sizeof(raw_stacktrace[0]); ++i)
    raw_stacktrace[i] = nullptr;
#endif
}

ExceptionBase::ExceptionBase (const ExceptionBase &exc)
  :
  file(exc.file),
  line(exc.line),
  function(exc.function),
  cond(exc.cond),
  exc(exc.exc),
  stacktrace (nullptr), // don't copy stacktrace to avoid double de-allocation problem
  n_stacktrace_frames (0),
  what_str("") // don't copy the error message, it gets generated dynamically by what()
{
#ifdef DEAL_II_HAVE_GLIBC_STACKTRACE
  for (unsigned int i=0; i<sizeof(raw_stacktrace)/sizeof(raw_stacktrace[0]); ++i)
    raw_stacktrace[i] = nullptr;
#endif
}

ExceptionBase::~ExceptionBase () noexcept
{
  free (stacktrace); // free(NULL) is allowed
  stacktrace = nullptr;
}

void ExceptionBase::set_fields (const char *f,
                                const int  l,
                                const char *func,
                                const char *c,
                                const char *e)
{
  file = f;
  line = l;
  function = func;
  cond = c;
  exc  = e;

  // If the system supports this, get a stacktrace how we got here:
  // Note that we defer the symbol lookup done by backtrace_symbols()
  // to when we need it (see what() below). This is for performance
  // reasons, as this requires loading libraries and can take in the
  // order of seconds on some machines.
#ifdef DEAL_II_HAVE_GLIBC_STACKTRACE
  n_stacktrace_frames = backtrace(raw_stacktrace, 25);
#endif
}

const char *ExceptionBase::what() const noexcept
{
  // If no error c_string was generated so far, do it now:
  if (what_str == "")
    {
#ifdef DEAL_II_HAVE_GLIBC_STACKTRACE
      // We have deferred the symbol lookup to this point to avoid costly
      // runtime penalties due to linkage of external libraries by
      // backtrace_symbols.

      // first delete old stacktrace if necessary
      free (stacktrace); // free(NULL) is allowed
      stacktrace = backtrace_symbols(raw_stacktrace, n_stacktrace_frames);
#endif

      generate_message();
    }

  return what_str.c_str();
}

const char *ExceptionBase::get_exc_name () const
{
  return exc;
}

void ExceptionBase::print_exc_data (std::ostream &out) const
{
  // print a header for the exception
  out << "An error occurred in line <" << line
      << "> of file <" << file
      << "> in function" << std::endl
      << "    " << function << std::endl
      << "The violated condition was: "<< std::endl
      << "    " << cond << std::endl;

  // print the way the additional information message was generated.
  // this is useful if the names of local variables appear in the
  // generation of the error message, because it allows the identification
  // of parts of the error text with what variables may have cause this
  //
  // On the other hand, this is almost never the case for ExcMessage
  // exceptions which would simply print the same text twice: once for
  // the way the message was composed, and once for the additional
  // information. Furthermore, the former of these two is often spread
  // between numerous "..."-enclosed strings that the preprocessor
  // collates into a single string, making it awkward to read. Consequently,
  // elide this text if the message was generated via an ExcMessage object
  if (std::strstr(cond, "dealii::ExcMessage") != nullptr)
    out << "The name and call sequence of the exception was:" << std::endl
        << "    " << exc  << std::endl;

  // finally print the additional information the exception provides:
  out << "Additional information: " << std::endl;
}

void ExceptionBase::print_info (std::ostream &out) const
{
  out << "    (none)" << std::endl;
}

void ExceptionBase::print_stack_trace (std::ostream &out) const
{
  if (n_stacktrace_frames == 0)
    return;

  if (deal_II_exceptions::show_stacktrace == false)
    return;

  // if there is a stackframe stored, print it
  out << std::endl;
  out << "Stacktrace:" << std::endl
      << "-----------" << std::endl;

  // print the stacktrace. first omit all those frames that have
  // ExceptionBase or deal_II_exceptions in their names, as these
  // correspond to the exception raising mechanism themselves, rather than
  // the place where the exception was triggered
  int frame = 0;
  while ((frame < n_stacktrace_frames)
         &&
         ((std::string(stacktrace[frame]).find ("ExceptionBase") != std::string::npos)
          ||
          (std::string(stacktrace[frame]).find ("deal_II_exceptions") != std::string::npos)))
    ++frame;

  // output the rest
  const unsigned int first_significant_frame = frame;
  for (; frame < n_stacktrace_frames; ++frame)
    {
      out << '#' << frame - first_significant_frame
          << "  ";

      // the stacktrace frame is actually of the format
      // "filename(functionname+offset) [address]". let's try to get the
      // mangled functionname out:
      std::string stacktrace_entry (stacktrace[frame]);
      const unsigned int pos_start = stacktrace_entry.find('('),
                         pos_end   = stacktrace_entry.find('+');
      std::string functionname = stacktrace_entry.substr (pos_start+1,
                                                          pos_end-pos_start-1);

      // demangle, and if successful replace old mangled string by
      // unmangled one (skipping address and offset). treat "main"
      // differently, since it is apparently demangled as "unsigned int"
      // for unknown reasons :-) if we can, demangle the function name
#ifdef DEAL_II_HAVE_LIBSTDCXX_DEMANGLER
      int         status;
      char *p = abi::__cxa_demangle(functionname.c_str(), nullptr, nullptr, &status);

      if ((status == 0) && (functionname != "main"))
        {
          std::string realname(p);
          // in MT mode, one often gets backtraces spanning several lines
          // because we have so many boost::tuple arguments in the MT
          // calling functions. most of the trailing arguments of these
          // tuples are actually unused boost::tuples::null_type, so we
          // should split them off if they are trailing a template argument
          // list
          while (realname.find (", boost::tuples::null_type>")
                 != std::string::npos)
            realname.erase (realname.find (", boost::tuples::null_type>"),
                            std::string (", boost::tuples::null_type").size());

          stacktrace_entry = stacktrace_entry.substr(0, pos_start)
                             +
                             ": "
                             +
                             realname;
        }
      else
        stacktrace_entry = stacktrace_entry.substr(0, pos_start)
                           +
                           ": "
                           +
                           functionname;

      free (p);

#else

      stacktrace_entry = stacktrace_entry.substr(0, pos_start)
                         +
                         ": "
                         +
                         functionname;
#endif

      // then output what we have
      out << stacktrace_entry
          << std::endl;

      // stop if we're in main()
      if (functionname == "main")
        break;
    }
}

void ExceptionBase::generate_message () const
{
  // build up a c_string with the error message.
  // Guard this procedure with a try block, we shall not throw at this
  // place...
  try
    {
      std::ostringstream converter;

      converter << std::endl
                << "--------------------------------------------------------"
                << std::endl;

      // print out general data
      print_exc_data (converter);
      // print out exception specific data
      print_info (converter);
      print_stack_trace (converter);

      if (!deal_II_exceptions::additional_assert_output.empty())
        {
          converter << "--------------------------------------------------------"
                    << std::endl
                    << deal_II_exceptions::additional_assert_output
                    << std::endl;
        }

      converter << "--------------------------------------------------------"
                << std::endl;

      what_str = converter.str();
    }
  catch (...)
    {
      // On error, resume next. There is nothing better we can do...
      what_str = "ExceptionBase::generate_message () failed";
    }
}

#ifdef DEAL_II_WITH_MPI
namespace StandardExceptions
{
  ExcMPI::ExcMPI (const int error_code)
    :
    error_code (error_code)
  {}

  void ExcMPI::print_info (std::ostream &out) const
  {
    char error_name[MPI_MAX_ERROR_STRING];
    error_name[0] = '\0';
    int resulting_length = MPI_MAX_ERROR_STRING;

    bool error_name_known = false;
    // workaround for Open MPI 1.6.5 not accepting
    // MPI_ERR_LASTCODE in MPI_Error_class
    if (error_code < MPI_ERR_LASTCODE)
      {
        // get the string name of the error code by first converting it to an
        // error class.
        int error_class = 0;
        int ierr = MPI_Error_class (error_code, &error_class);
        error_name_known = (ierr == MPI_SUCCESS);

        // Check the output of the error printing functions. If either MPI
        // function fails we should just print a less descriptive message.
        if (error_name_known)
          {
            ierr = MPI_Error_string (error_class, error_name, &resulting_length);
            error_name_known = error_name_known && (ierr == MPI_SUCCESS);
          }
      }

    out << "deal.II encountered an error while calling an MPI function."
        << std::endl;
    if (error_name_known)
      {
        out << "The description of the error provided by MPI is \""
            << error_name
            << "\"."
            << std::endl;
      }
    else
      {
        out << "This error code is not equal to any of the standard MPI error codes."
            << std::endl;
      }
    out << "The numerical value of the original error code is "
        << error_code
        << "."
        << std::endl;
  }
}
#endif // DEAL_II_WITH_MPI

namespace deal_II_exceptions
{
  namespace internals
  {

    void abort (const ExceptionBase &exc, bool nothrow /*= false*/)
    {
      if (dealii::deal_II_exceptions::abort_on_exception)
        {
          // Print the error message and bail out:
          std::cerr << exc.what() << std::endl;
          std::abort();
        }
      else if (nothrow)
        {
          // We are not allowed to throw, and not allowed to abort.
          // Just print the exception name to deallog and continue
          // normally:
          deallog << "Exception: " << exc.get_exc_name() << std::endl;
        }
      else
        {
          // We are not allowed to abort, so just throw the error so just
          // throw the error so just throw the error so just throw the
          // error:
          throw exc;
        }
    }

  } /*namespace internals*/
} /*namespace deal_II_exceptions*/

DEAL_II_NAMESPACE_CLOSE

// Newer versions of gcc have a very nice feature: you can set a verbose
// terminate handler, that not only aborts a program when an exception is
// thrown and not caught somewhere, but before aborting it prints that an
// exception has been thrown, and possibly what the std::exception::what()
// function has to say. Since many people run into the trap of not having a
// catch clause in main(), they wonder where that abort may be coming from.
// The terminate handler then at least says what is missing in their
// program.
#ifdef DEAL_II_HAVE_VERBOSE_TERMINATE
namespace __gnu_cxx
{
  extern void __verbose_terminate_handler ();
}

namespace
{
  struct preload_terminate_dummy
  {
    preload_terminate_dummy()
    {
      std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
    }
  };

  static preload_terminate_dummy dummy;
}
#endif
<commit_msg>Use MPI_Abort instead of std::abort.<commit_after>// ---------------------------------------------------------------------
//
// Copyright (C) 1998 - 2017 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, 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.
// The full text of the license can be found in the file LICENSE at
// the top level of the deal.II distribution.
//
// ---------------------------------------------------------------------

#include <deal.II/base/exceptions.h>
#include <deal.II/base/logstream.h>
#include <deal.II/base/utilities.h>
#include <deal.II/base/mpi.h>

#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <sstream>

#ifdef DEAL_II_WITH_MPI
#  include <mpi.h>
#endif

#ifdef DEAL_II_HAVE_GLIBC_STACKTRACE
#  include <execinfo.h>
#endif

#ifdef DEAL_II_HAVE_LIBSTDCXX_DEMANGLER
#  include <cxxabi.h>
#endif

DEAL_II_NAMESPACE_OPEN

namespace deal_II_exceptions
{

  std::string additional_assert_output;

  void set_additional_assert_output (const char *const p)
  {
    additional_assert_output = p;
  }

  bool show_stacktrace = true;

  void suppress_stacktrace_in_exceptions ()
  {
    show_stacktrace = false;
  }

  bool abort_on_exception = true;

  void disable_abort_on_exception ()
  {
    abort_on_exception = false;
  }

}

ExceptionBase::ExceptionBase ()
  :
  file(""),
  line(0),
  function(""),
  cond(""),
  exc(""),
  stacktrace (nullptr),
  n_stacktrace_frames (0),
  what_str("")
{
#ifdef DEAL_II_HAVE_GLIBC_STACKTRACE
  for (unsigned int i=0; i<sizeof(raw_stacktrace)/sizeof(raw_stacktrace[0]); ++i)
    raw_stacktrace[i] = nullptr;
#endif
}

ExceptionBase::ExceptionBase (const ExceptionBase &exc)
  :
  file(exc.file),
  line(exc.line),
  function(exc.function),
  cond(exc.cond),
  exc(exc.exc),
  stacktrace (nullptr), // don't copy stacktrace to avoid double de-allocation problem
  n_stacktrace_frames (0),
  what_str("") // don't copy the error message, it gets generated dynamically by what()
{
#ifdef DEAL_II_HAVE_GLIBC_STACKTRACE
  for (unsigned int i=0; i<sizeof(raw_stacktrace)/sizeof(raw_stacktrace[0]); ++i)
    raw_stacktrace[i] = nullptr;
#endif
}

ExceptionBase::~ExceptionBase () noexcept
{
  free (stacktrace); // free(NULL) is allowed
  stacktrace = nullptr;
}

void ExceptionBase::set_fields (const char *f,
                                const int  l,
                                const char *func,
                                const char *c,
                                const char *e)
{
  file = f;
  line = l;
  function = func;
  cond = c;
  exc  = e;

  // If the system supports this, get a stacktrace how we got here:
  // Note that we defer the symbol lookup done by backtrace_symbols()
  // to when we need it (see what() below). This is for performance
  // reasons, as this requires loading libraries and can take in the
  // order of seconds on some machines.
#ifdef DEAL_II_HAVE_GLIBC_STACKTRACE
  n_stacktrace_frames = backtrace(raw_stacktrace, 25);
#endif
}

const char *ExceptionBase::what() const noexcept
{
  // If no error c_string was generated so far, do it now:
  if (what_str == "")
    {
#ifdef DEAL_II_HAVE_GLIBC_STACKTRACE
      // We have deferred the symbol lookup to this point to avoid costly
      // runtime penalties due to linkage of external libraries by
      // backtrace_symbols.

      // first delete old stacktrace if necessary
      free (stacktrace); // free(NULL) is allowed
      stacktrace = backtrace_symbols(raw_stacktrace, n_stacktrace_frames);
#endif

      generate_message();
    }

  return what_str.c_str();
}

const char *ExceptionBase::get_exc_name () const
{
  return exc;
}

void ExceptionBase::print_exc_data (std::ostream &out) const
{
  // print a header for the exception
  out << "An error occurred in line <" << line
      << "> of file <" << file
      << "> in function" << std::endl
      << "    " << function << std::endl
      << "The violated condition was: "<< std::endl
      << "    " << cond << std::endl;

  // print the way the additional information message was generated.
  // this is useful if the names of local variables appear in the
  // generation of the error message, because it allows the identification
  // of parts of the error text with what variables may have cause this
  //
  // On the other hand, this is almost never the case for ExcMessage
  // exceptions which would simply print the same text twice: once for
  // the way the message was composed, and once for the additional
  // information. Furthermore, the former of these two is often spread
  // between numerous "..."-enclosed strings that the preprocessor
  // collates into a single string, making it awkward to read. Consequently,
  // elide this text if the message was generated via an ExcMessage object
  if (std::strstr(cond, "dealii::ExcMessage") != nullptr)
    out << "The name and call sequence of the exception was:" << std::endl
        << "    " << exc  << std::endl;

  // finally print the additional information the exception provides:
  out << "Additional information: " << std::endl;
}

void ExceptionBase::print_info (std::ostream &out) const
{
  out << "    (none)" << std::endl;
}

void ExceptionBase::print_stack_trace (std::ostream &out) const
{
  if (n_stacktrace_frames == 0)
    return;

  if (deal_II_exceptions::show_stacktrace == false)
    return;

  // if there is a stackframe stored, print it
  out << std::endl;
  out << "Stacktrace:" << std::endl
      << "-----------" << std::endl;

  // print the stacktrace. first omit all those frames that have
  // ExceptionBase or deal_II_exceptions in their names, as these
  // correspond to the exception raising mechanism themselves, rather than
  // the place where the exception was triggered
  int frame = 0;
  while ((frame < n_stacktrace_frames)
         &&
         ((std::string(stacktrace[frame]).find ("ExceptionBase") != std::string::npos)
          ||
          (std::string(stacktrace[frame]).find ("deal_II_exceptions") != std::string::npos)))
    ++frame;

  // output the rest
  const unsigned int first_significant_frame = frame;
  for (; frame < n_stacktrace_frames; ++frame)
    {
      out << '#' << frame - first_significant_frame
          << "  ";

      // the stacktrace frame is actually of the format
      // "filename(functionname+offset) [address]". let's try to get the
      // mangled functionname out:
      std::string stacktrace_entry (stacktrace[frame]);
      const unsigned int pos_start = stacktrace_entry.find('('),
                         pos_end   = stacktrace_entry.find('+');
      std::string functionname = stacktrace_entry.substr (pos_start+1,
                                                          pos_end-pos_start-1);

      // demangle, and if successful replace old mangled string by
      // unmangled one (skipping address and offset). treat "main"
      // differently, since it is apparently demangled as "unsigned int"
      // for unknown reasons :-) if we can, demangle the function name
#ifdef DEAL_II_HAVE_LIBSTDCXX_DEMANGLER
      int         status;
      char *p = abi::__cxa_demangle(functionname.c_str(), nullptr, nullptr, &status);

      if ((status == 0) && (functionname != "main"))
        {
          std::string realname(p);
          // in MT mode, one often gets backtraces spanning several lines
          // because we have so many boost::tuple arguments in the MT
          // calling functions. most of the trailing arguments of these
          // tuples are actually unused boost::tuples::null_type, so we
          // should split them off if they are trailing a template argument
          // list
          while (realname.find (", boost::tuples::null_type>")
                 != std::string::npos)
            realname.erase (realname.find (", boost::tuples::null_type>"),
                            std::string (", boost::tuples::null_type").size());

          stacktrace_entry = stacktrace_entry.substr(0, pos_start)
                             +
                             ": "
                             +
                             realname;
        }
      else
        stacktrace_entry = stacktrace_entry.substr(0, pos_start)
                           +
                           ": "
                           +
                           functionname;

      free (p);

#else

      stacktrace_entry = stacktrace_entry.substr(0, pos_start)
                         +
                         ": "
                         +
                         functionname;
#endif

      // then output what we have
      out << stacktrace_entry
          << std::endl;

      // stop if we're in main()
      if (functionname == "main")
        break;
    }
}

void ExceptionBase::generate_message () const
{
  // build up a c_string with the error message.
  // Guard this procedure with a try block, we shall not throw at this
  // place...
  try
    {
      std::ostringstream converter;

      converter << std::endl
                << "--------------------------------------------------------"
                << std::endl;

      // print out general data
      print_exc_data (converter);
      // print out exception specific data
      print_info (converter);
      print_stack_trace (converter);

      if (!deal_II_exceptions::additional_assert_output.empty())
        {
          converter << "--------------------------------------------------------"
                    << std::endl
                    << deal_II_exceptions::additional_assert_output
                    << std::endl;
        }

      converter << "--------------------------------------------------------"
                << std::endl;

      what_str = converter.str();
    }
  catch (...)
    {
      // On error, resume next. There is nothing better we can do...
      what_str = "ExceptionBase::generate_message () failed";
    }
}

#ifdef DEAL_II_WITH_MPI
namespace StandardExceptions
{
  ExcMPI::ExcMPI (const int error_code)
    :
    error_code (error_code)
  {}

  void ExcMPI::print_info (std::ostream &out) const
  {
    char error_name[MPI_MAX_ERROR_STRING];
    error_name[0] = '\0';
    int resulting_length = MPI_MAX_ERROR_STRING;

    bool error_name_known = false;
    // workaround for Open MPI 1.6.5 not accepting
    // MPI_ERR_LASTCODE in MPI_Error_class
    if (error_code < MPI_ERR_LASTCODE)
      {
        // get the string name of the error code by first converting it to an
        // error class.
        int error_class = 0;
        int ierr = MPI_Error_class (error_code, &error_class);
        error_name_known = (ierr == MPI_SUCCESS);

        // Check the output of the error printing functions. If either MPI
        // function fails we should just print a less descriptive message.
        if (error_name_known)
          {
            ierr = MPI_Error_string (error_class, error_name, &resulting_length);
            error_name_known = error_name_known && (ierr == MPI_SUCCESS);
          }
      }

    out << "deal.II encountered an error while calling an MPI function."
        << std::endl;
    if (error_name_known)
      {
        out << "The description of the error provided by MPI is \""
            << error_name
            << "\"."
            << std::endl;
      }
    else
      {
        out << "This error code is not equal to any of the standard MPI error codes."
            << std::endl;
      }
    out << "The numerical value of the original error code is "
        << error_code
        << "."
        << std::endl;
  }
}
#endif // DEAL_II_WITH_MPI

namespace deal_II_exceptions
{
  namespace internals
  {

    void abort (const ExceptionBase &exc, bool nothrow /*= false*/)
    {
      if (dealii::deal_II_exceptions::abort_on_exception)
        {
          // first print the error
          std::cerr << exc.what() << std::endl;

          // then bail out. if in MPI mode, bring down the entire
          // house by asking the MPI system to do a best-effort
          // operation at also terminating all of the other MPI
          // processes. this is useful because if only one process
          // runs into an assertion, then that may lead to deadlocks
          // if the others don't recognize this, or at the very least
          // delay their termination until they realize that their
          // communication with the job that died times out.
#ifdef DEAL_II_WITH_MPI
          int is_initialized;
          MPI_Initialized(&is_initialized);
          if (is_initialized)
            MPI_Abort (MPI_COMM_WORLD,
                       /* return code = */ 255);
          else
            std::abort ();
#else
          std::abort();
#endif
        }
      else if (nothrow)
        {
          // We are not allowed to throw, and not allowed to abort.
          // Just print the exception name to deallog and continue
          // normally:
          deallog << "Exception: " << exc.get_exc_name() << std::endl;
        }
      else
        {
          // We are not allowed to abort, so just throw the error so just
          // throw the error so just throw the error so just throw the
          // error:
          throw exc;
        }
    }

  } /*namespace internals*/
} /*namespace deal_II_exceptions*/

DEAL_II_NAMESPACE_CLOSE

// Newer versions of gcc have a very nice feature: you can set a verbose
// terminate handler, that not only aborts a program when an exception is
// thrown and not caught somewhere, but before aborting it prints that an
// exception has been thrown, and possibly what the std::exception::what()
// function has to say. Since many people run into the trap of not having a
// catch clause in main(), they wonder where that abort may be coming from.
// The terminate handler then at least says what is missing in their
// program.
#ifdef DEAL_II_HAVE_VERBOSE_TERMINATE
namespace __gnu_cxx
{
  extern void __verbose_terminate_handler ();
}

namespace
{
  struct preload_terminate_dummy
  {
    preload_terminate_dummy()
    {
      std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
    }
  };

  static preload_terminate_dummy dummy;
}
#endif
<|endoftext|>


<commit_before>#pragma once

#include <cstddef>
#include <cstdint>

namespace AO
{
	namespace Allocator
	{
		inline namespace Version_1
		{
			namespace Private
			{
				class IStack
				{
				public:
					// Constructors
					IStack(void) = default;

					IStack(IStack const &) = default;

					IStack(IStack &&) = default;

					// Assignment Operators
					IStack &operator=(IStack const &) = default;

					IStack &operator=(IStack &&) = default;

					// Destructor
					virtual ~IStack(void) = default;

					// Virtual Methods
					virtual bool empty(void) const noexcept = 0;

					virtual std::size_t size(void) const noexcept = 0;

					virtual std::size_t capacity(void) const noexcept = 0;

					virtual void reset(void) noexcept = 0;

					virtual void *allocate(std::size_t numberOfBytes, std::size_t alignment) = 0;

					virtual void deallocate(void const *memory, std::size_t numberOfBytes) = 0;
				};
			}
		}
	}
}<commit_msg>Update IStack.hpp<commit_after>#pragma once

#include <cstddef>
#include <cstdint>
#include <memory>

namespace AO
{
	namespace Allocator
	{
		inline namespace Version_1
		{
			namespace Private
			{
				class IStack
				{
				public:
					// Constructors
					IStack(void) = default;

					IStack(IStack const &) = default;

					IStack(IStack &&) = default;

					// Assignment Operators
					IStack &operator=(IStack const &) = default;

					IStack &operator=(IStack &&) = default;

					// Destructor
					virtual ~IStack(void) = default;

					// Virtual Methods
					virtual bool empty(void) const noexcept = 0;

					virtual std::size_t size(void) const noexcept = 0;

					virtual std::size_t capacity(void) const noexcept = 0;

					virtual void reset(void) noexcept = 0;

					virtual void *allocate(std::size_t numberOfBytes, std::size_t alignment) = 0;

					virtual void deallocate(void const *memory, std::size_t numberOfBytes) = 0;

				protected:
					// Static Attributes
					static constexpr const std::size_t Alignment = alignof(std::max_align_t);
				};
			}
		}
	}
}
<|endoftext|>


<commit_before>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/profiler/utils/cost_utils.h"

#include "tensorflow/core/framework/tensor_shape.pb.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/grappler/costs/op_performance_data.pb.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/profiler/utils/tf_op_utils.h"
#include "tensorflow/core/profiler/utils/xplane_schema.h"

namespace tensorflow {
namespace profiler {

namespace {

// Decode the string that encodes tensor shape and type information and convert
// to TensorProperties.
// Returns an empty TensorProperties if error or input is "".
// See OpKernel::TraceString() to see when the shape is encoded as "".
// Input format is <DTYPE>[<dim1>, <dim2>,...]
static OpInfo::TensorProperties GetTensorProperties(absl::string_view info) {
  OpInfo::TensorProperties tensor_prop;
  std::vector<absl::string_view> parts = absl::StrSplit(info, '[');
  if (parts.size() != 2) return tensor_prop;
  DataType data_type = DT_INVALID;
  if (!DataTypeFromString(parts[0], &data_type)) return tensor_prop;
  tensor_prop.set_dtype(data_type);
  absl::ConsumeSuffix(&parts[1], "]");
  std::vector<absl::string_view> dims = absl::StrSplit(parts[1], ',');
  for (const auto dim : dims) {
    int size;
    if (!absl::SimpleAtoi(dim, &size)) return OpInfo::TensorProperties();
    tensor_prop.mutable_shape()->add_dim()->set_size(size);
  }
  if (dims.empty()) tensor_prop.mutable_shape()->add_dim()->set_size(1);
  return tensor_prop;
}

}  // namespace

TfOpRoofLineCostEstimator::~TfOpRoofLineCostEstimator() {
  if (!unsupported_ops_.empty()) {
    LOG(ERROR) << "Unsupported Op for Roofline Cost Analysis are:"
               << absl::StrJoin(unsupported_ops_, ",");
  }
}

grappler::DeviceInfo TfOpRoofLineCostEstimator::GetDeviceInfo(
    const DeviceProperties& device) const {
  // Hypothetical devices that is used to measure peak flops and memory bytes
  // accessed.
  return grappler::DeviceInfo(/*gigaops=*/1, /*gb_per_sec=*/1);
}

TfOpRoofLineCostEstimator::OpRoofLineStats TfOpRoofLineCostEstimator::Predict(
    const XEventVisitor& event) {
  TfOp tf_op;
  bool has_shape_stats = false;
  std::vector<std::string> input_tensors;
  event.ForEachStat([&](const XStatVisitor& stat) {
    if (stat.Type() == StatType::kLevel0) {
      tf_op = ParseTfOpFullname(stat.StrValue());
    } else if (stat.Type() == StatType::kTensorShapes) {
      has_shape_stats = true;
      auto shapes_stats = stat.StrValue();
      absl::ConsumePrefix(&shapes_stats, "(");
      absl::ConsumeSuffix(&shapes_stats, ")");
      input_tensors = absl::StrSplit(shapes_stats, ';');
    }
  });

  // Return empty OpRoofLineStats if shape is not traced or this is not a tf op.
  if (tf_op.type.empty() || !has_shape_stats) {
    return {0ULL, 0ULL, /*inaccurate=*/true};
  }

  grappler::OpContext op_context;
  op_context.name = std::string(tf_op.type);
  op_context.op_info.set_op(op_context.name);
  for (const auto& tensor : input_tensors) {
    *op_context.op_info.add_inputs() = GetTensorProperties(tensor);
  }
  grappler::Costs costs = PredictCosts(op_context);
  if (costs.inaccurate) unsupported_ops_.insert(std::string(tf_op.type));

  VLOG(1) << tf_op.type << "[" << absl::StrJoin(input_tensors, ",") << "]"
          << " flops:" << costs.compute_time.count()
          << " bytes:" << costs.memory_time.count();

  /* The compute_time is measured in nanoseconds, therefore numerically it is
   * equal to flops because giga ops / second cancel the nanoseconds.
   * Same for memory_time */
  return {/*flops=*/static_cast<uint64>(costs.compute_time.count()),
          /*bytes_accessed=*/static_cast<uint64>(costs.memory_time.count()),
          /*inaccurate=*/costs.inaccurate};
}

}  // namespace profiler
}  // namespace tensorflow
<commit_msg>handle scalar type correctly.<commit_after>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/profiler/utils/cost_utils.h"

#include "tensorflow/core/framework/tensor_shape.pb.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/grappler/costs/op_performance_data.pb.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/profiler/utils/tf_op_utils.h"
#include "tensorflow/core/profiler/utils/xplane_schema.h"

namespace tensorflow {
namespace profiler {

namespace {

// Decode the string that encodes tensor shape and type information and convert
// to TensorProperties.
// Returns an empty TensorProperties if error or input is "".
// See OpKernel::TraceString() to see when the shape is encoded as "".
// Input format is <DTYPE>[<dim1>, <dim2>,...]
static OpInfo::TensorProperties GetTensorProperties(absl::string_view info) {
  OpInfo::TensorProperties tensor_prop;
  std::vector<absl::string_view> parts = absl::StrSplit(info, '[');
  if (parts.size() != 2) return tensor_prop;
  DataType data_type = DT_INVALID;
  if (!DataTypeFromString(parts[0], &data_type)) return tensor_prop;
  tensor_prop.set_dtype(data_type);
  absl::ConsumeSuffix(&parts[1], "]");
  if (parts[1].empty()) {  // Scalar type.
    tensor_prop.mutable_shape()->add_dim()->set_size(1);
    return tensor_prop;
  }
  std::vector<absl::string_view> dims = absl::StrSplit(parts[1], ',');
  for (const auto dim : dims) {
    int size;
    if (!absl::SimpleAtoi(dim, &size)) return OpInfo::TensorProperties();
    tensor_prop.mutable_shape()->add_dim()->set_size(size);
  }
  return tensor_prop;
}

}  // namespace

TfOpRoofLineCostEstimator::~TfOpRoofLineCostEstimator() {
  if (!unsupported_ops_.empty()) {
    LOG(ERROR) << "Unsupported Op for Roofline Cost Analysis are:"
               << absl::StrJoin(unsupported_ops_, ",");
  }
}

grappler::DeviceInfo TfOpRoofLineCostEstimator::GetDeviceInfo(
    const DeviceProperties& device) const {
  // Hypothetical devices that is used to measure peak flops and memory bytes
  // accessed.
  return grappler::DeviceInfo(/*gigaops=*/1, /*gb_per_sec=*/1);
}

TfOpRoofLineCostEstimator::OpRoofLineStats TfOpRoofLineCostEstimator::Predict(
    const XEventVisitor& event) {
  TfOp tf_op;
  bool has_shape_stats = false;
  std::vector<std::string> input_tensors;
  event.ForEachStat([&](const XStatVisitor& stat) {
    if (stat.Type() == StatType::kLevel0) {
      tf_op = ParseTfOpFullname(stat.StrValue());
    } else if (stat.Type() == StatType::kTensorShapes) {
      has_shape_stats = true;
      auto shapes_stats = stat.StrValue();
      absl::ConsumePrefix(&shapes_stats, "(");
      absl::ConsumeSuffix(&shapes_stats, ")");
      input_tensors = absl::StrSplit(shapes_stats, ';');
    }
  });

  // Return empty OpRoofLineStats if shape is not traced or this is not a tf op.
  if (tf_op.type.empty() || !has_shape_stats) {
    return {0ULL, 0ULL, /*inaccurate=*/true};
  }

  grappler::OpContext op_context;
  op_context.name = std::string(tf_op.type);
  op_context.op_info.set_op(op_context.name);
  for (const auto& tensor : input_tensors) {
    *op_context.op_info.add_inputs() = GetTensorProperties(tensor);
  }
  grappler::Costs costs = PredictCosts(op_context);
  if (costs.inaccurate) unsupported_ops_.insert(std::string(tf_op.type));

  VLOG(1) << tf_op.type << "[" << absl::StrJoin(input_tensors, ",") << "]"
          << " flops:" << costs.compute_time.count()
          << " bytes:" << costs.memory_time.count();

  /* The compute_time is measured in nanoseconds, therefore numerically it is
   * equal to flops because giga ops / second cancel the nanoseconds.
   * Same for memory_time */
  return {/*flops=*/static_cast<uint64>(costs.compute_time.count()),
          /*bytes_accessed=*/static_cast<uint64>(costs.memory_time.count()),
          /*inaccurate=*/costs.inaccurate};
}

}  // namespace profiler
}  // namespace tensorflow
<|endoftext|>


<commit_before>/*
    subscriptiondialog.cpp

    This program 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 2 of the License, or
    (at your option) any later version.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software Foundation,
    Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, US
*/

#include "subscriptiondialog.h"
#include "kmmessage.h"

#include <klocale.h>
#include <kdebug.h>

namespace KMail {

SubscriptionDialog::SubscriptionDialog( QWidget *parent, const QString &caption,
    KAccount * acct )
  : KSubscription( parent, caption, acct, User1, QString::null, false )
{
  // hide unneeded checkboxes
  hideTreeCheckbox();
  hideNewOnlyCheckbox();

  // connect to folderlisting
  ImapAccountBase* iaccount = static_cast<ImapAccountBase*>(acct);
  connect(iaccount, SIGNAL(receivedFolders(QStringList, QStringList,
          QStringList, const ImapAccountBase::jobData &)),
      this, SLOT(slotListDirectory(QStringList, QStringList,
          QStringList, const ImapAccountBase::jobData &)));

  // ok-button
  connect(this, SIGNAL(okClicked()), SLOT(slotSave()));

  // reload-list button
  connect(this, SIGNAL(user1Clicked()), SLOT(slotLoadFolders()));

  // get the folders
  slotLoadFolders();
}

//------------------------------------------------------------------------------
void SubscriptionDialog::slotListDirectory( QStringList mSubfolderNames,
                                            QStringList mSubfolderPaths,
                                            QStringList mSubfolderMimeTypes,
                                            const ImapAccountBase::jobData & jobData )
{
  if (mSubfolderPaths.size() <= 0) return;
  bool onlySubscribed = jobData.onlySubscribed;
  GroupItem *parent = 0;
  mLoading = true;

  if (!onlySubscribed)
  {
    /* we need to find our root-item
       remove the name (and the separator) from the path */
    int start = mSubfolderPaths[0].length() - (mSubfolderNames[0].length()+2);
    int length = mSubfolderNames[0].length()+1;
    if (start < 0) start = 0;
    QString compare = mSubfolderPaths[0];
    compare.remove(start, length);

    QListViewItemIterator it( groupView );
    GroupItem *tmp;
    while ( it.current() != 0 )
    {
      // compare it with each item to find the current root
      tmp = static_cast<GroupItem*>(it.current());
      if (tmp->info().path == compare) {
        parent = tmp;
        break;
      }
      ++it;
    }
  }
  GroupItem *item = 0;
  QString text;
  for (uint i = 0; i < mSubfolderNames.count(); i++)
  {
    if (!onlySubscribed)
    {
      bool create = true;
      if (parent)
      {
        for ( QListViewItem *it = parent->firstChild() ;
            it ; it = it->nextSibling() )
        {
          // check if this item already exists in this hierarchy
          item = static_cast<GroupItem*>(it);
          if (item->info().path == mSubfolderPaths[i])
            create = false;
        }
      }
      if (create)
      {
        KGroupInfo info(mSubfolderNames[i]);
        if (mSubfolderNames[i].upper() == "INBOX")
          info.name = i18n("inbox");
        info.subscribed = false;
        info.path = mSubfolderPaths[i];
        // create a new checkable item
        if (parent)
          item = new GroupItem(parent, info, this, true);
        else
          item = new GroupItem(folderTree(), info, this, true);
      }
      if (item)
      {
        // reset
        item->setOn(false);
      }
    } else {
      // find the item
      QListViewItemIterator it( groupView );
      while ( it.current() != 0 )
      {
        item = static_cast<GroupItem*>(it.current());
        if (item->info().path == mSubfolderPaths[i])
        {
          // subscribed
          item->setOn(true);
        }
        ++it;
      }
    }
    if (mSubfolderMimeTypes[i] == "message/directory" ||
        mSubfolderMimeTypes[i] == "inode/directory")
    {
      // descend
      static_cast<ImapAccountBase*>(mAcct)->listDirectory(mSubfolderPaths[i],
          onlySubscribed);
    }
  }
  if (jobData.inboxOnly)
  {
    ImapAccountBase* ai = static_cast<ImapAccountBase*>(mAcct);
    ai->listDirectory(ai->prefix(), false, true);
    ai->listDirectory(ai->prefix(), true, true);
  }
  slotLoadingComplete();
}

//------------------------------------------------------------------------------
void SubscriptionDialog::slotSave()
{
  if (!account())
    return;
  // subscribe
  QListViewItemIterator it(subView);
  for ( ; it.current(); ++it)
  {
    static_cast<ImapAccountBase*>(account())->changeSubscription(true,
        static_cast<GroupItem*>(it.current())->info().path);
  }

  // unsubscribe
  QListViewItemIterator it2(unsubView);
  for ( ; it2.current(); ++it2)
  {
    static_cast<ImapAccountBase*>(account())->changeSubscription(false,
        static_cast<GroupItem*>(it2.current())->info().path);
  }
}

//------------------------------------------------------------------------------
void SubscriptionDialog::slotLoadFolders()
{
  KSubscription::slotLoadFolders();
  if ( !account())
    return;
  ImapAccountBase* ai = static_cast<ImapAccountBase*>(account());
  // get folders
  ai->listDirectory(ai->prefix(), false);
  ai->listDirectory(ai->prefix(), true);
}

}

#include "subscriptiondialog.moc"
<commit_msg>Fix loop with courier and personal namespace. CCMAIL: 60516-done@bugs.kde.org<commit_after>/*
    subscriptiondialog.cpp

    This program 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 2 of the License, or
    (at your option) any later version.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software Foundation,
    Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, US
*/

#include "subscriptiondialog.h"
#include "kmmessage.h"

#include <klocale.h>
#include <kdebug.h>

namespace KMail {

SubscriptionDialog::SubscriptionDialog( QWidget *parent, const QString &caption,
    KAccount * acct )
  : KSubscription( parent, caption, acct, User1, QString::null, false )
{
  // hide unneeded checkboxes
  hideTreeCheckbox();
  hideNewOnlyCheckbox();

  // connect to folderlisting
  ImapAccountBase* iaccount = static_cast<ImapAccountBase*>(acct);
  connect(iaccount, SIGNAL(receivedFolders(QStringList, QStringList,
          QStringList, const ImapAccountBase::jobData &)),
      this, SLOT(slotListDirectory(QStringList, QStringList,
          QStringList, const ImapAccountBase::jobData &)));

  // ok-button
  connect(this, SIGNAL(okClicked()), SLOT(slotSave()));

  // reload-list button
  connect(this, SIGNAL(user1Clicked()), SLOT(slotLoadFolders()));

  // get the folders
  slotLoadFolders();
}

//------------------------------------------------------------------------------
void SubscriptionDialog::slotListDirectory( QStringList mSubfolderNames,
                                            QStringList mSubfolderPaths,
                                            QStringList mSubfolderMimeTypes,
                                            const ImapAccountBase::jobData & jobData )
{
  if (mSubfolderPaths.size() <= 0) return;
  bool onlySubscribed = jobData.onlySubscribed;
  GroupItem *parent = 0;
  mLoading = true;
  ImapAccountBase* ai = static_cast<ImapAccountBase*>(mAcct);

  if (!onlySubscribed)
  {
    /* we need to find our root-item
       remove the name (and the separator) from the path */
    int start = mSubfolderPaths[0].length() - (mSubfolderNames[0].length()+2);
    int length = mSubfolderNames[0].length()+1;
    if (start < 0) start = 0;
    QString compare = mSubfolderPaths[0];
    compare.remove(start, length);

    QListViewItemIterator it( groupView );
    GroupItem *tmp;
    while ( it.current() != 0 )
    {
      // compare it with each item to find the current root
      tmp = static_cast<GroupItem*>(it.current());
      if (tmp->info().path == compare) {
        parent = tmp;
        break;
      }
      ++it;
    }
  }
  GroupItem *item = 0;
  QString text;
  for (uint i = 0; i < mSubfolderNames.count(); i++)
  {
    if (!onlySubscribed)
    {
      bool create = true;
      QListViewItem *start = folderTree()->firstChild();
      if ( parent )
        start = parent->firstChild();
      if ( start )
      {
        for ( QListViewItem *it = start; it; it = it->nextSibling() )
        {
          // check if this item already exists in this hierarchy
          item = static_cast<GroupItem*>(it);
          if ( item->info().path == mSubfolderPaths[i] )
            create = false;
        }
      }
      if ( create )
      {
        KGroupInfo info(mSubfolderNames[i]);
        if (mSubfolderNames[i].upper() == "INBOX")
          info.name = i18n("inbox");
        info.subscribed = false;
        info.path = mSubfolderPaths[i];
        // create a new checkable item
        if (parent)
          item = new GroupItem(parent, info, this, true);
        else
          item = new GroupItem(folderTree(), info, this, true);
      }
      if ( item ) // reset
        item->setOn(false);

    } else
    {
      // find the item
      QListViewItemIterator it( groupView );
      while ( it.current() != 0 )
      {
        item = static_cast<GroupItem*>(it.current());
        if (item->info().path == mSubfolderPaths[i])
        {
          // subscribed
          item->setOn(true);
        }
        ++it;
      }
    }
    if ( mSubfolderMimeTypes[i] == "message/directory" ||
         mSubfolderMimeTypes[i] == "inode/directory" )
    {
      // descend
      bool secondStep = (mSubfolderPaths[i] == ai->prefix()) ? true : false;
      static_cast<ImapAccountBase*>(mAcct)->listDirectory( mSubfolderPaths[i],
          onlySubscribed, secondStep );
    }
  }
  if ( jobData.inboxOnly )
    ai->listDirectory( ai->prefix(), onlySubscribed, true );

  // active buttons and stuff
  slotLoadingComplete();
}

//------------------------------------------------------------------------------
void SubscriptionDialog::slotSave()
{
  if (!account())
    return;
  // subscribe
  QListViewItemIterator it(subView);
  for ( ; it.current(); ++it)
  {
    static_cast<ImapAccountBase*>(account())->changeSubscription(true,
        static_cast<GroupItem*>(it.current())->info().path);
  }

  // unsubscribe
  QListViewItemIterator it2(unsubView);
  for ( ; it2.current(); ++it2)
  {
    static_cast<ImapAccountBase*>(account())->changeSubscription(false,
        static_cast<GroupItem*>(it2.current())->info().path);
  }
}

//------------------------------------------------------------------------------
void SubscriptionDialog::slotLoadFolders()
{
  // clear the views
  KSubscription::slotLoadFolders();
  if ( !account() )
    return;
  ImapAccountBase* ai = static_cast<ImapAccountBase*>(account());
  if ( ai->prefix().isEmpty() )
    return;
  // get folders
  ai->listDirectory( ai->prefix(), false );
  ai->listDirectory( ai->prefix(), true );
}

}

#include "subscriptiondialog.moc"
<|endoftext|>


<commit_before>#include "main.hpp"

#include "Renderer.hpp"
#include "SampleBuffer.hpp"

namespace sound {

static void sdlAudioCallback(void *userdata, Uint8 *stream, int len) {
  static_cast<Renderer *>(userdata)->audioCallback(stream, len);
}

bool Renderer::create() {
  {
    SDL_AudioSpec desiredAudioSpec;
    desiredAudioSpec.freq = 48000;
    desiredAudioSpec.format = AUDIO_F32SYS;
    desiredAudioSpec.channels = 2;
    desiredAudioSpec.samples = 512;
    desiredAudioSpec.callback = sdlAudioCallback;
    desiredAudioSpec.userdata = this;

    audioDevice =
        SDL_OpenAudioDevice(nullptr, 0, &desiredAudioSpec, &audioSpec, 0);
    if (!audioDevice) {
      SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
                               "Could not open audio device", SDL_GetError(),
                               NULL);
      return false;
    }
  }

  std::cout << "Audio:\n"
      << "\tsamplerate: " << audioSpec.freq << "\n"
      << "\tchannels: " << (int)audioSpec.channels << "\n"
      << "\tsamples: " << audioSpec.samples << "\n";

  assert(std::atomic_is_lock_free(&voices[0].sampleBuffer));
  assert(std::atomic_is_lock_free(&voices[0].state));
  assert(std::atomic_is_lock_free(&voices[0].cursor));

  for (auto &voice : voices) {
    voice.state = Voice::State::Empty;
  }

  SDL_PauseAudioDevice(audioDevice, 0);

  return true;
}

void Renderer::destroy() {
  if (audioDevice)
    SDL_CloseAudioDevice(audioDevice);
}

void Renderer::killAllVoices() {
  SDL_LockAudioDevice(audioDevice);
  for(auto &voice : voices) {
    voice.state.store(Voice::State::Empty);
  }
  SDL_UnlockAudioDevice(audioDevice);
}

void Renderer::update() {
  auto activeVoicesCount = 0u;

  for (auto &voice : voices) {
    if (voice.state.load() == Voice::State::Empty)
      continue;

    assert(voice.state == Voice::State::Playing);
    activeVoicesCount++;

    const auto sampleBufferValue =
        voice.sampleBuffer.load(std::memory_order_relaxed);
    const int32_t cursorValue = voice.cursor.load(std::memory_order_relaxed);

    const int32_t sampleBufferLengthSamples =
        sampleBufferValue->getBufferLengthSamples();

    if (cursorValue == sampleBufferLengthSamples) {
      voice.state.store(Voice::State::Empty);
    }
  }

#if 0
  std::cout << "active voices: " << activeVoicesCount << "\n";
#endif
}

Voice *Renderer::play(const SampleBuffer *sampleBuffer,
                      const PlayParameters &parameters) {
  assert(sampleBuffer);

  for (auto &voice : voices) {
    if (voice.state.load() != Voice::State::Empty)
      continue;

    voice.sampleBuffer.store(sampleBuffer, std::memory_order_relaxed);
    voice.cursor.store(-parameters.startDelay * audioSpec.freq / 1000.,
                       std::memory_order_relaxed);
    voice.looping.store(parameters.looping, std::memory_order_relaxed);

    voice.state.store(Voice::State::Playing, std::memory_order_release);

    return &voice;
  }

  std::cout << "out of voices\n";

  return nullptr;
}

void Renderer::audioCallback(Uint8 *stream, int len) {
  memset(stream, 0, len);

  float *const buffer = reinterpret_cast<float *>(stream);
  const auto bufferLengthSamples =
      int32_t(len / sizeof(float) / 2); // two channels per sample

  for (auto &voice : voices) {
    if (voice.state.load() == Voice::State::Empty)
      continue;

    auto cursorValue = voice.cursor.load(std::memory_order_relaxed);

    const auto sampleBufferValue =
        voice.sampleBuffer.load(std::memory_order_relaxed);

    const auto sampleBuffer = sampleBufferValue->getBuffer();
    const auto sampleBufferLengthSamples =
        int32_t(sampleBufferValue->getBufferLengthSamples());

    const auto loopingValue = voice.looping.load(std::memory_order_relaxed);

    // start delay
    if (cursorValue + bufferLengthSamples <= 0) {
      voice.cursor.store(cursorValue + bufferLengthSamples);
      continue;
    }

    // finished
    if (cursorValue == sampleBufferLengthSamples) {
      continue;
    }

    auto destinationOffset = cursorValue < 0 ? -cursorValue : 0;

  loop : {
    const auto copySamplesCount =
        std::min(bufferLengthSamples - destinationOffset,
                 sampleBufferLengthSamples - std::max(cursorValue, 0));
    assert(copySamplesCount > 0);

    // please don't generalize/combine the cases, so that there's a better
    // chance for optimization
    switch (sampleBufferValue->getChannels()) {
    case 1: {
      const auto copySrc = sampleBuffer + 1 * std::max(cursorValue, 0);
      const auto copyDest = buffer + 2 * destinationOffset;

      for (auto i = 0; i < copySamplesCount; ++i) {
        copyDest[2 * i + 0] += copySrc[i];
        copyDest[2 * i + 1] += copySrc[i];
      }
    } break;

    case 2: {
      const auto copySrc = sampleBuffer + 2 * std::max(cursorValue, 0);
      const auto copyDest = buffer + 2 * destinationOffset;

      for (auto i = 0; i < copySamplesCount; ++i) {
        copyDest[2 * i + 0] += copySrc[2 * i + 0];
        copyDest[2 * i + 1] += copySrc[2 * i + 1];
      }
    } break;
    }

    cursorValue += copySamplesCount;

    if (loopingValue && cursorValue == sampleBufferLengthSamples) {
      cursorValue = 0;
      destinationOffset += copySamplesCount;
      if(destinationOffset != bufferLengthSamples) {
        goto loop;
      }
    }
  }

    voice.cursor.store(cursorValue);
  }

  // disable sound (for listening to smooth jazz while coding :) )
#if 0
  memset(stream, 0, len);
#endif
}

} // namespace sound
<commit_msg>Increase audio buffer size to fix dropouts on my MacMini<commit_after>#include "main.hpp"

#include "Renderer.hpp"
#include "SampleBuffer.hpp"

namespace sound {

static void sdlAudioCallback(void *userdata, Uint8 *stream, int len) {
  static_cast<Renderer *>(userdata)->audioCallback(stream, len);
}

bool Renderer::create() {
  {
    SDL_AudioSpec desiredAudioSpec;
    desiredAudioSpec.freq = 48000;
    desiredAudioSpec.format = AUDIO_F32SYS;
    desiredAudioSpec.channels = 2;
    desiredAudioSpec.samples = 1024;
    desiredAudioSpec.callback = sdlAudioCallback;
    desiredAudioSpec.userdata = this;

    audioDevice =
        SDL_OpenAudioDevice(nullptr, 0, &desiredAudioSpec, &audioSpec, 0);
    if (!audioDevice) {
      SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
                               "Could not open audio device", SDL_GetError(),
                               NULL);
      return false;
    }
  }

  std::cout << "Audio:\n"
      << "\tsamplerate: " << audioSpec.freq << "\n"
      << "\tchannels: " << (int)audioSpec.channels << "\n"
      << "\tsamples: " << audioSpec.samples << "\n";

  assert(std::atomic_is_lock_free(&voices[0].sampleBuffer));
  assert(std::atomic_is_lock_free(&voices[0].state));
  assert(std::atomic_is_lock_free(&voices[0].cursor));

  for (auto &voice : voices) {
    voice.state = Voice::State::Empty;
  }

  SDL_PauseAudioDevice(audioDevice, 0);

  return true;
}

void Renderer::destroy() {
  if (audioDevice)
    SDL_CloseAudioDevice(audioDevice);
}

void Renderer::killAllVoices() {
  SDL_LockAudioDevice(audioDevice);
  for(auto &voice : voices) {
    voice.state.store(Voice::State::Empty);
  }
  SDL_UnlockAudioDevice(audioDevice);
}

void Renderer::update() {
  auto activeVoicesCount = 0u;

  for (auto &voice : voices) {
    if (voice.state.load() == Voice::State::Empty)
      continue;

    assert(voice.state == Voice::State::Playing);
    activeVoicesCount++;

    const auto sampleBufferValue =
        voice.sampleBuffer.load(std::memory_order_relaxed);
    const int32_t cursorValue = voice.cursor.load(std::memory_order_relaxed);

    const int32_t sampleBufferLengthSamples =
        sampleBufferValue->getBufferLengthSamples();

    if (cursorValue == sampleBufferLengthSamples) {
      voice.state.store(Voice::State::Empty);
    }
  }

#if 0
  std::cout << "active voices: " << activeVoicesCount << "\n";
#endif
}

Voice *Renderer::play(const SampleBuffer *sampleBuffer,
                      const PlayParameters &parameters) {
  assert(sampleBuffer);

  for (auto &voice : voices) {
    if (voice.state.load() != Voice::State::Empty)
      continue;

    voice.sampleBuffer.store(sampleBuffer, std::memory_order_relaxed);
    voice.cursor.store(-parameters.startDelay * audioSpec.freq / 1000.,
                       std::memory_order_relaxed);
    voice.looping.store(parameters.looping, std::memory_order_relaxed);

    voice.state.store(Voice::State::Playing, std::memory_order_release);

    return &voice;
  }

  std::cout << "out of voices\n";

  return nullptr;
}

void Renderer::audioCallback(Uint8 *stream, int len) {
  memset(stream, 0, len);

  float *const buffer = reinterpret_cast<float *>(stream);
  const auto bufferLengthSamples =
      int32_t(len / sizeof(float) / 2); // two channels per sample

  for (auto &voice : voices) {
    if (voice.state.load() == Voice::State::Empty)
      continue;

    auto cursorValue = voice.cursor.load(std::memory_order_relaxed);

    const auto sampleBufferValue =
        voice.sampleBuffer.load(std::memory_order_relaxed);

    const auto sampleBuffer = sampleBufferValue->getBuffer();
    const auto sampleBufferLengthSamples =
        int32_t(sampleBufferValue->getBufferLengthSamples());

    const auto loopingValue = voice.looping.load(std::memory_order_relaxed);

    // start delay
    if (cursorValue + bufferLengthSamples <= 0) {
      voice.cursor.store(cursorValue + bufferLengthSamples);
      continue;
    }

    // finished
    if (cursorValue == sampleBufferLengthSamples) {
      continue;
    }

    auto destinationOffset = cursorValue < 0 ? -cursorValue : 0;

  loop : {
    const auto copySamplesCount =
        std::min(bufferLengthSamples - destinationOffset,
                 sampleBufferLengthSamples - std::max(cursorValue, 0));
    assert(copySamplesCount > 0);

    // please don't generalize/combine the cases, so that there's a better
    // chance for optimization
    switch (sampleBufferValue->getChannels()) {
    case 1: {
      const auto copySrc = sampleBuffer + 1 * std::max(cursorValue, 0);
      const auto copyDest = buffer + 2 * destinationOffset;

      for (auto i = 0; i < copySamplesCount; ++i) {
        copyDest[2 * i + 0] += copySrc[i];
        copyDest[2 * i + 1] += copySrc[i];
      }
    } break;

    case 2: {
      const auto copySrc = sampleBuffer + 2 * std::max(cursorValue, 0);
      const auto copyDest = buffer + 2 * destinationOffset;

      for (auto i = 0; i < copySamplesCount; ++i) {
        copyDest[2 * i + 0] += copySrc[2 * i + 0];
        copyDest[2 * i + 1] += copySrc[2 * i + 1];
      }
    } break;
    }

    cursorValue += copySamplesCount;

    if (loopingValue && cursorValue == sampleBufferLengthSamples) {
      cursorValue = 0;
      destinationOffset += copySamplesCount;
      if(destinationOffset != bufferLengthSamples) {
        goto loop;
      }
    }
  }

    voice.cursor.store(cursorValue);
  }

  // disable sound (for listening to smooth jazz while coding :) )
#if 0
  memset(stream, 0, len);
#endif
}

} // namespace sound
<|endoftext|>


<commit_before>/**************************************************************************************/
/*                                                                                */
/*  Visualization Library                                                             */
/*  http://www.visualizationlibrary.com                                               */
/*                                                                                */
/*  Copyright (c) 2005-2010, Michele Bosi                                             */
/*  All rights reserved.                                                              */
/*                                                                                */
/*  Redistribution and use in source and binary forms, with or without modification,  */
/*  are permitted provided that the following conditions are met:                     */
/*                                                                                */
/*  - Redistributions of source code must retain the above copyright notice, this     */
/*  list of conditions and the following disclaimer.                                  */
/*                                                                                */
/*  - Redistributions in binary form must reproduce the above copyright notice, this  */
/*  list of conditions and the following disclaimer in the documentation and/or       */
/*  other materials provided with the distribution.                                   */
/*                                                                                */
/*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
/*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
/*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
/*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
/*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
/*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
/*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
/*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
/*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
/*                                                                                */
/**************************************************************************************/

#ifndef VisualizationLibrary_INCLUDE_ONCE
#define VisualizationLibrary_INCLUDE_ONCE

#include <vl/VirtualFile.hpp>
#include <vl/version.hpp>

namespace vl
{
  class FileSystem;
  class ResourceDatabase;
  class KeyValues;
  class StandardLog;
  class FontManager;
  class LoadWriterManager;
  class RenderingAbstract;

  //! Global application settings controlling how Visualization Library behaves.
  class Settings: public Object
  {
    friend class VisualizationLibrary;
  public:
    Settings()
    {
      #ifndef NDEBUG
        mVerbosityLevel  = vl::VEL_VERBOSITY_NORMAL;
        mCheckOpenGLStates = true;
      #else
        mVerbosityLevel  = VERBOSITY_ERROR;
        mCheckOpenGLStates = false;
      #endif
    }

    bool checkOpenGLStates() const { return mCheckOpenGLStates; }
    void setCheckOpenGLStates(bool check_clean) { mCheckOpenGLStates = check_clean; }

    EVerbosityLevel verbosityLevel() const { return mVerbosityLevel; }
    void setVerbosityLevel(EVerbosityLevel verb_level) { mVerbosityLevel = verb_level; }

    const String& defaultLogPath() const { return mDefaultLogPath; }

    const String& defaultDataPath() const { return mDefaultDataPath; }

  protected:
    EVerbosityLevel mVerbosityLevel;
    bool mCheckOpenGLStates;
    String mDefaultLogPath;
    String mDefaultDataPath;
  };

  //! Used to initialize/shutdown VisualizationLibrary and to access important global data.
  class VisualizationLibrary
  {
  public:
    //! Initializes Visualization Library's internal data.
    static void init();

    //! Releases all the resources acquired by Visualization Library.
    static void shutdown();

    //! Returns true if init() has been called and shutdown() has not been called yet.
    static bool initialized();

    //! Returns the Visualization Library's version string.
    static const char* versionString();

    //! Returns Visualization Library's rendering root.
    static RenderingAbstract* rendering();
    static void setRendering(RenderingAbstract* rendering);

    //! Returns Visualization Library's default FileSystem.
    static FileSystem* fileSystem();

    //! Returns Visualization Library's default FontManager.
    static FontManager* fontManager();

    //! Returns Visualization Library's default LoadWriterManager.
    static LoadWriterManager* loadWriterManager();

    //! Returns the environment variables used by Visualization Library.
    //! Can also be used to globally pass parameters across different parts of an application.
    static KeyValues* envVars();

    //! Returns the default Log object.
    static StandardLog* logger();

    //! Returns the global settings of VL.
    static Settings* settings();

    //! For internal use only
    static void* freeTypeLibrary();

  protected:
    //! Initializes the environment variables
    static void initEnvVars();
  };

  //! Shows a console window that displays the standard output. This function is meant to be used only under Windows.
  void showWin32Console();
}

#endif
<commit_msg>Fixed compilation error.<commit_after>/**************************************************************************************/
/*                                                                                */
/*  Visualization Library                                                             */
/*  http://www.visualizationlibrary.com                                               */
/*                                                                                */
/*  Copyright (c) 2005-2010, Michele Bosi                                             */
/*  All rights reserved.                                                              */
/*                                                                                */
/*  Redistribution and use in source and binary forms, with or without modification,  */
/*  are permitted provided that the following conditions are met:                     */
/*                                                                                */
/*  - Redistributions of source code must retain the above copyright notice, this     */
/*  list of conditions and the following disclaimer.                                  */
/*                                                                                */
/*  - Redistributions in binary form must reproduce the above copyright notice, this  */
/*  list of conditions and the following disclaimer in the documentation and/or       */
/*  other materials provided with the distribution.                                   */
/*                                                                                */
/*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
/*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
/*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
/*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
/*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
/*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
/*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
/*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
/*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
/*                                                                                */
/**************************************************************************************/

#ifndef VisualizationLibrary_INCLUDE_ONCE
#define VisualizationLibrary_INCLUDE_ONCE

#include <vl/VirtualFile.hpp>
#include <vl/version.hpp>

namespace vl
{
  class FileSystem;
  class ResourceDatabase;
  class KeyValues;
  class StandardLog;
  class FontManager;
  class LoadWriterManager;
  class RenderingAbstract;

  //! Global application settings controlling how Visualization Library behaves.
  class Settings: public Object
  {
    friend class VisualizationLibrary;
  public:
    Settings()
    {
      #ifndef NDEBUG
        mVerbosityLevel  = vl::VEL_VERBOSITY_NORMAL;
        mCheckOpenGLStates = true;
      #else
        mVerbosityLevel  = vl::VEL_VERBOSITY_ERROR;
        mCheckOpenGLStates = false;
      #endif
    }

    bool checkOpenGLStates() const { return mCheckOpenGLStates; }
    void setCheckOpenGLStates(bool check_clean) { mCheckOpenGLStates = check_clean; }

    EVerbosityLevel verbosityLevel() const { return mVerbosityLevel; }
    void setVerbosityLevel(EVerbosityLevel verb_level) { mVerbosityLevel = verb_level; }

    const String& defaultLogPath() const { return mDefaultLogPath; }

    const String& defaultDataPath() const { return mDefaultDataPath; }

  protected:
    EVerbosityLevel mVerbosityLevel;
    bool mCheckOpenGLStates;
    String mDefaultLogPath;
    String mDefaultDataPath;
  };

  //! Used to initialize/shutdown VisualizationLibrary and to access important global data.
  class VisualizationLibrary
  {
  public:
    //! Initializes Visualization Library's internal data.
    static void init();

    //! Releases all the resources acquired by Visualization Library.
    static void shutdown();

    //! Returns true if init() has been called and shutdown() has not been called yet.
    static bool initialized();

    //! Returns the Visualization Library's version string.
    static const char* versionString();

    //! Returns Visualization Library's rendering root.
    static RenderingAbstract* rendering();
    static void setRendering(RenderingAbstract* rendering);

    //! Returns Visualization Library's default FileSystem.
    static FileSystem* fileSystem();

    //! Returns Visualization Library's default FontManager.
    static FontManager* fontManager();

    //! Returns Visualization Library's default LoadWriterManager.
    static LoadWriterManager* loadWriterManager();

    //! Returns the environment variables used by Visualization Library.
    //! Can also be used to globally pass parameters across different parts of an application.
    static KeyValues* envVars();

    //! Returns the default Log object.
    static StandardLog* logger();

    //! Returns the global settings of VL.
    static Settings* settings();

    //! For internal use only
    static void* freeTypeLibrary();

  protected:
    //! Initializes the environment variables
    static void initEnvVars();
  };

  //! Shows a console window that displays the standard output. This function is meant to be used only under Windows.
  void showWin32Console();
}

#endif
<|endoftext|>


<commit_before><commit_msg>Fix the doc<commit_after><|endoftext|>


<commit_before>/*************************************************************************
* Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

/**********************************
 * create an event and perform    *
 * flow analysis 'on the fly'     *
 *                                *
 * authors: Raimond Snellings     *
 *           (snelling@nikhef.nl) *
 *          Ante Bilandzic        *
 *           (anteb@nikhef.nl)    *
 *********************************/

#include "Riostream.h"
#include "TMath.h"
#include "TF1.h"
#include "TRandom3.h"

#include "AliFlowEventSimpleMakerOnTheFly.h"
#include "AliFlowEventSimple.h"
#include "AliFlowTrackSimple.h"

ClassImp(AliFlowEventSimpleMakerOnTheFly)

//========================================================================

AliFlowEventSimpleMakerOnTheFly::AliFlowEventSimpleMakerOnTheFly(UInt_t iseed):
  fMultiplicityOfRP(0),
  fMultiplicitySpreadOfRP(0.),
  fV1RP(0.),
  fV1SpreadRP(0.),
  fV2RP(0.),
  fV2SpreadRP(0.),
  fPtSpectra(NULL),
  fPhiDistribution(NULL),
  fMyTRandom3(NULL),
  fCount(0)
 {
  // constructor
   fMyTRandom3 = new TRandom3(iseed);
 }

//========================================================================

AliFlowEventSimpleMakerOnTheFly::~AliFlowEventSimpleMakerOnTheFly()
{
 // destructor
  if (fPtSpectra) delete fPtSpectra;
  if (fPhiDistribution) delete fPhiDistribution;
  if (fMyTRandom3) delete  fMyTRandom3;
}

//========================================================================

AliFlowEventSimple* AliFlowEventSimpleMakerOnTheFly::CreateEventOnTheFly()
{
  // method to create event on the fly

  AliFlowEventSimple* pEvent = new AliFlowEventSimple(fMultiplicityOfRP);

  //reaction plane
  Double_t fMCReactionPlaneAngle = fMyTRandom3->Uniform(0.,TMath::TwoPi());

  // pt:
  Double_t dPtMin = 0.; // to be improved
  Double_t dPtMax = 10.; // to be improved

  fPtSpectra = new TF1("fPtSpectra","[0]*x*TMath::Exp(-x*x)",dPtMin,dPtMax);
  fPtSpectra->SetParName(0,"Multiplicity of RPs");
  // sampling the multiplicity:
  fMultiplicityOfRP = fMyTRandom3->Gaus(fMultiplicityOfRP,fMultiplicitySpreadOfRP);
  fPtSpectra->SetParameter(0,fMultiplicityOfRP);

  // phi:
  Double_t dPhiMin = 0.; // to be improved
  Double_t dPhiMax = TMath::TwoPi(); // to be improved

  fPhiDistribution = new TF1("fPhiDistribution","1+2.*[0]*TMath::Cos(x)+2.*[1]*TMath::Cos(2*x)",dPhiMin,dPhiMax);

  // sampling the V1:
  fPhiDistribution->SetParName(0,"directed flow");
  if(fV1RP>0.0) fV1RP = fMyTRandom3->Gaus(fV1RP,fV1SpreadRP);
  fPhiDistribution->SetParameter(0,fV1RP);

  // sampling the V2:
  fPhiDistribution->SetParName(1,"elliptic flow");
  fV2RP = fMyTRandom3->Gaus(fV2RP,fV2SpreadRP);
  fPhiDistribution->SetParameter(1,fV2RP);

  // eta:
  Double_t dEtaMin = -1.; // to be improved
  Double_t dEtaMax = 1.; // to be improved

  Int_t iGoodTracks = 0;
  Int_t iSelParticlesRP = 0;
  Int_t iSelParticlesPOI = 0;
  for(Int_t i=0;i<fMultiplicityOfRP;i++) {
    AliFlowTrackSimple* pTrack = new AliFlowTrackSimple();
    pTrack->SetPt(fPtSpectra->GetRandom());
    pTrack->SetEta(fMyTRandom3->Uniform(dEtaMin,dEtaMax));
    pTrack->SetPhi(fPhiDistribution->GetRandom()+fMCReactionPlaneAngle);
    pTrack->SetForRPSelection(kTRUE);
    iSelParticlesRP++;
    pTrack->SetForPOISelection(kTRUE);
    iSelParticlesPOI++;

    pEvent->TrackCollection()->Add(pTrack);
    iGoodTracks++;
  }

  pEvent->SetEventNSelTracksRP(iSelParticlesRP);
  pEvent->SetNumberOfTracks(iGoodTracks);//tracks used either for RP or for POI selection
  pEvent->SetMCReactionPlaneAngle(fMCReactionPlaneAngle);

  if (!fMCReactionPlaneAngle == 0) cout<<" MC Reaction Plane Angle = "<<  fMCReactionPlaneAngle << endl;
  else cout<<" MC Reaction Plane Angle = unknown "<< endl;

  cout<<" iGoodTracks = "<< iGoodTracks << endl;
  cout<<" # of RP selected tracks = "<<iSelParticlesRP<<endl;
  cout<<" # of POI selected tracks = "<<iSelParticlesPOI<<endl;
  cout << "# " << ++fCount << " events processed" << endl;

 return pEvent;

} // end of CreateEventOnTheFly()

<commit_msg>fix memory leak and funny multiplicity<commit_after>/*************************************************************************
* Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

/**********************************
 * create an event and perform    *
 * flow analysis 'on the fly'     *
 *                                *
 * authors: Raimond Snellings     *
 *           (snelling@nikhef.nl) *
 *          Ante Bilandzic        *
 *           (anteb@nikhef.nl)    *
 *********************************/

#include "Riostream.h"
#include "TMath.h"
#include "TF1.h"
#include "TRandom3.h"

#include "AliFlowEventSimpleMakerOnTheFly.h"
#include "AliFlowEventSimple.h"
#include "AliFlowTrackSimple.h"

ClassImp(AliFlowEventSimpleMakerOnTheFly)

//========================================================================

AliFlowEventSimpleMakerOnTheFly::AliFlowEventSimpleMakerOnTheFly(UInt_t iseed):
  fMultiplicityOfRP(0),
  fMultiplicitySpreadOfRP(0.),
  fV1RP(0.),
  fV1SpreadRP(0.),
  fV2RP(0.),
  fV2SpreadRP(0.),
  fPtSpectra(NULL),
  fPhiDistribution(NULL),
  fMyTRandom3(NULL),
  fCount(0)
 {
  // constructor
   fMyTRandom3 = new TRandom3(iseed);
 }

//========================================================================

AliFlowEventSimpleMakerOnTheFly::~AliFlowEventSimpleMakerOnTheFly()
{
 // destructor
  if (fPtSpectra) delete fPtSpectra;
  if (fPhiDistribution) delete fPhiDistribution;
  if (fMyTRandom3) delete  fMyTRandom3;
}

//========================================================================

AliFlowEventSimple* AliFlowEventSimpleMakerOnTheFly::CreateEventOnTheFly()
{
  // method to create event on the fly

  AliFlowEventSimple* pEvent = new AliFlowEventSimple(fMultiplicityOfRP);

  //reaction plane
  Double_t fMCReactionPlaneAngle = fMyTRandom3->Uniform(0.,TMath::TwoPi());

  // pt:
  Double_t dPtMin = 0.; // to be improved
  Double_t dPtMax = 10.; // to be improved

  fPtSpectra = new TF1("fPtSpectra","[0]*x*TMath::Exp(-x*x)",dPtMin,dPtMax);
  fPtSpectra->SetParName(0,"Multiplicity of RPs");
  // sampling the multiplicity:
  Int_t fNewMultiplicityOfRP = fMyTRandom3->Gaus(fMultiplicityOfRP,fMultiplicitySpreadOfRP);
  fPtSpectra->SetParameter(0,fNewMultiplicityOfRP);

  // phi:
  Double_t dPhiMin = 0.; // to be improved
  Double_t dPhiMax = TMath::TwoPi(); // to be improved

  fPhiDistribution = new TF1("fPhiDistribution","1+2.*[0]*TMath::Cos(x)+2.*[1]*TMath::Cos(2*x)",dPhiMin,dPhiMax);

  // sampling the V1:
  fPhiDistribution->SetParName(0,"directed flow");
  if(fV1RP>0.0) fV1RP = fMyTRandom3->Gaus(fV1RP,fV1SpreadRP);
  fPhiDistribution->SetParameter(0,fV1RP);

  // sampling the V2:
  fPhiDistribution->SetParName(1,"elliptic flow");
  fV2RP = fMyTRandom3->Gaus(fV2RP,fV2SpreadRP);
  fPhiDistribution->SetParameter(1,fV2RP);

  // eta:
  Double_t dEtaMin = -1.; // to be improved
  Double_t dEtaMax = 1.; // to be improved

  Int_t iGoodTracks = 0;
  Int_t iSelParticlesRP = 0;
  Int_t iSelParticlesPOI = 0;
  for(Int_t i=0;i<fNewMultiplicityOfRP;i++) {
    AliFlowTrackSimple* pTrack = new AliFlowTrackSimple();
    pTrack->SetPt(fPtSpectra->GetRandom());
    pTrack->SetEta(fMyTRandom3->Uniform(dEtaMin,dEtaMax));
    pTrack->SetPhi(fPhiDistribution->GetRandom()+fMCReactionPlaneAngle);
    pTrack->SetForRPSelection(kTRUE);
    iSelParticlesRP++;
    pTrack->SetForPOISelection(kTRUE);
    iSelParticlesPOI++;

    pEvent->TrackCollection()->Add(pTrack);
    iGoodTracks++;
  }

  pEvent->SetEventNSelTracksRP(iSelParticlesRP);
  pEvent->SetNumberOfTracks(iGoodTracks);//tracks used either for RP or for POI selection
  pEvent->SetMCReactionPlaneAngle(fMCReactionPlaneAngle);

  if (!fMCReactionPlaneAngle == 0) cout<<" MC Reaction Plane Angle = "<<  fMCReactionPlaneAngle << endl;
  else cout<<" MC Reaction Plane Angle = unknown "<< endl;

  cout<<" iGoodTracks = "<< iGoodTracks << endl;
  cout<<" # of RP selected tracks = "<<iSelParticlesRP<<endl;
  cout<<" # of POI selected tracks = "<<iSelParticlesPOI<<endl;
  cout << "# " << ++fCount << " events processed" << endl;

  delete fPhiDistribution;
  delete fPtSpectra;
  return pEvent;

} // end of CreateEventOnTheFly()

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013, Moving Pixel Labs (http://www.mp-labs.net)
 * All rights reserved.

 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the name of the Moving Pixel Labs nor the names of its
 *      contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL MOVING PIXEL LABS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <QtCore/QtGlobal>
#include <assert.h>

/*!
 * @def K_NULL
 * @brief Null pointer.
 */
#define K_NULL      0

#define K_VIRTUAL   0

#define K_NULL_REF( type ) ( reinterpret_cast< type* >( K_NULL ) )

#ifndef K_DEBUG
#define _K_SAFE_BUILD
#endif /*_DEBUG*/

// Utilities
#define K_BLOCK_STR( x )    #x
#define K_BLOCK_XSTR( x )   K_BLOCK_STR( x )

/* Assert */
#ifdef K_DEBUG
#define K_ASSERT( expression )					assert( expression );
#else
#define K_ASSERT( expression )
#endif /*K_DEBUG*/
#define K_STRONG_ASSERT( expression )           assert( expression );

#define K_IS_ALIGNED( expression, alignment )\
    ( ! ( static_cast< size_t >( expression ) % alignment ) )

/* Inlining */
#define	_K_INLINE	inline

/* Unused */
#define _K_UNUSED( x )	x __attribute__( ( unused ) )

/* Memory alignment */
#if ( QT_POINTER_SIZE == 8 )
#   define _K_64
#endif

#ifdef _K_64
#define _K_DEFAULT_ALIGNMENT	16
#else
#define _K_DEFAULT_ALIGNMENT	8
#endif

#define _K_SSE_ALIGNMENT	16

#define _K_NEXT_ALIGNED_VALUE( value, alignment )\
    ( ( ( size_t ) value + ( alignment - 1 ) ) & ~( alignment - 1 ) )

#define _K_1TB	( 1024ll * 1024 * 1024 * 1024 )
#define _K_1GB	( 1024 * 1024 * 1024 )
#define _K_1MB	( 1024 * 1024 )
#define _K_1KB	( 1024 )

/* C++11 */
#define _K_DECL_OVERRIDE Q_DECL_OVERRIDE

#define K_FOURCC( a, b, c, d )\
    ( ( kuint ) ( ( ( d ) << 24 ) | ( ( c ) << 16 ) | ( ( b ) <<8 ) | ( a ) ) )

#define _K_PI	3.14159265358979323846

/* Min & Max */
#define K_MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
#define K_MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )

#ifdef _MSC_VER
#   define	_K_SSE_ALIGNED  __declspec( align( _K_SSE_ALIGNMENT ) )
#else
#   define	_K_SSE_ALIGNED  __attribute__( ( aligned( _K_SSE_ALIGNMENT ) ) )
#endif

#ifdef _K_BUILD_KORE
#   define KoreExport Q_DECL_EXPORT
#else
#   define KoreExport Q_DECL_IMPORT
#endif
<commit_msg>Fixing FOURCC macro to be defined on big endian basis.<commit_after>/*
 * Copyright (c) 2013, Moving Pixel Labs (http://www.mp-labs.net)
 * All rights reserved.

 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the name of the Moving Pixel Labs nor the names of its
 *      contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL MOVING PIXEL LABS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <QtCore/QtGlobal>
#include <assert.h>

/*!
 * @def K_NULL
 * @brief Null pointer.
 */
#define K_NULL      0

#define K_VIRTUAL   0

#define K_NULL_REF( type ) ( reinterpret_cast< type* >( K_NULL ) )

#ifndef K_DEBUG
#define _K_SAFE_BUILD
#endif /*_DEBUG*/

// Utilities
#define K_BLOCK_STR( x )    #x
#define K_BLOCK_XSTR( x )   K_BLOCK_STR( x )

/* Assert */
#ifdef K_DEBUG
#define K_ASSERT( expression )					assert( expression );
#else
#define K_ASSERT( expression )
#endif /*K_DEBUG*/
#define K_STRONG_ASSERT( expression )           assert( expression );

#define K_IS_ALIGNED( expression, alignment )\
    ( ! ( static_cast< size_t >( expression ) % alignment ) )

/* Inlining */
#define	_K_INLINE	inline

/* Unused */
#define _K_UNUSED( x )	x __attribute__( ( unused ) )

/* Memory alignment */
#if ( QT_POINTER_SIZE == 8 )
#   define _K_64
#endif

#ifdef _K_64
#define _K_DEFAULT_ALIGNMENT	16
#else
#define _K_DEFAULT_ALIGNMENT	8
#endif

#define _K_SSE_ALIGNMENT	16

#define _K_NEXT_ALIGNED_VALUE( value, alignment )\
    ( ( ( size_t ) value + ( alignment - 1 ) ) & ~( alignment - 1 ) )

#define _K_1TB	( 1024ll * 1024 * 1024 * 1024 )
#define _K_1GB	( 1024 * 1024 * 1024 )
#define _K_1MB	( 1024 * 1024 )
#define _K_1KB	( 1024 )

/* C++11 */
#define _K_DECL_OVERRIDE Q_DECL_OVERRIDE

#define K_FOURCC( a, b, c, d )\
    ( ( kuint ) ( ( ( a ) << 24 ) | ( ( b ) << 16 ) | ( ( c ) <<8 ) | ( d ) ) )

#define _K_PI	3.14159265358979323846

/* Min & Max */
#define K_MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
#define K_MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )

#ifdef _MSC_VER
#   define	_K_SSE_ALIGNED  __declspec( align( _K_SSE_ALIGNMENT ) )
#else
#   define	_K_SSE_ALIGNED  __attribute__( ( aligned( _K_SSE_ALIGNMENT ) ) )
#endif

#ifdef _K_BUILD_KORE
#   define KoreExport Q_DECL_EXPORT
#else
#   define KoreExport Q_DECL_IMPORT
#endif
<|endoftext|>


<commit_before><commit_msg>fixed default value for paused<commit_after><|endoftext|>


<commit_before>AliAnalysisTask *AddTask_cbaumann_LMEEPbPb2011(Bool_t runRejection=kFALSE, Bool_t setMC=kFALSE,Bool_t enableCF=kFALSE){
  //get the current analysis manager
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTask_cbaumann_LMEEPbPb2011", "No analysis manager found.");
    return 0;
  }

  //create config File names: TRAIN_ROOT is for running on GSI train,
  // ALICE_ROOT for CERN Lego trains
  TString configBasePath("$TRAIN_ROOT/cbaumann_dielectron/");
  TString trainRoot=gSystem->Getenv("TRAIN_ROOT");
  if (trainRoot.IsNull()) configBasePath= "$ALICE_ROOT/PWGDQ/dielectron/macrosLMEE/";
  TString configFile("ConfigLMEEPbPb2011.C");
  TString configLMEECutLib("LMEECutLib.C");

  TString configFilePath(configBasePath+configFile);
  TString configLMEECutLib(configBasePath+configLMEECutLib);

  //AOD Usage currently tested with separate task, to be merged
  if (mgr->GetInputEventHandler()->IsA()==AliAODInputHandler::Class()){
    ::Info("AddTaskLMEEPbPb2011", "no dedicated AOD configuration");
  }

  //Do we have an MC handler?
  Bool_t hasMC=setMC;
  if (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0)
    hasMC=kTRUE;

  if (!gROOT->GetListOfGlobalFunctions()->FindObject(configFile.Data()))
    gROOT->LoadMacro(configFilePath.Data());
  if (!gROOT->GetListOfGlobalFunctions()->FindObject(configLMEECutLib.Data()))
    gROOT->LoadMacro(configLMEECutLibPath.Data());

  LMEECutLib* cutlib = new LMEECutLib();
  AliAnalysisTaskMultiDielectron *task=new AliAnalysisTaskMultiDielectron("MultiDiEData");
  if (!hasMC){ task->UsePhysicsSelection();
  }
  task->SetTriggerMask(AliVEvent::kMB+AliVEvent::kCentral+AliVEvent::kSemiCentral);
  task->SetEventFilter(cutlib->GetEventCuts(LMEECutLib::kPbPb2011TPCandTOF)); //

  //load dielectron configuration file

  //add dielectron analysis with different cuts to the task
  if (runRejection) {

    AliDielectron *lowmass4=ConfigLMEEPbPb2011(4,hasMC,enableCF);
    task->AddDielectron(lowmass4);
    printf("add: %s\n",lowmass4->GetName());
  }
  else {

    AliDielectron *lowmass3=ConfigLMEEPbPb2011(3,hasMC,enableCF);
    task->AddDielectron(lowmass3);
    printf("add: %s\n",lowmass3->GetName())
      AliDielectron *lowmass1=ConfigLMEEPbPb2011(1,hasMC,enableCF);
    task->AddDielectron(lowmass1);
    printf("add: %s\n",lowmass1->GetName())
      AliDielectron *lowmass7=ConfigLMEEPbPb2011(7,hasMC,enableCF);
    task->AddDielectron(lowmass7);
    printf("add: %s\n",lowmass7->GetName())
  }

  mgr->AddTask(task);

  //create output container
  AliAnalysisDataContainer *coutput1 =
    mgr->CreateContainer("cbaumann_LMEEPbPb2011_tree",
	TTree::Class(),
	AliAnalysisManager::kExchangeContainer,
	"cbaumann_LMEEPbPb2011_default.root");

  AliAnalysisDataContainer *cOutputHist1 =
    mgr->CreateContainer("cbaumann_LMEEPbPb2011_out",
	TList::Class(),
	AliAnalysisManager::kOutputContainer,
	"cbaumann_LMEEPbPb2011_out.root");
  if (enableCF) {
    AliAnalysisDataContainer *cOutputHist2 =
      mgr->CreateContainer("cbaumann_LMEEPbPb2011_CF",
	  TList::Class(),
	  AliAnalysisManager::kOutputContainer,
	  "cbaumann_LMEEPbPb2011_out.root");

  }
  AliAnalysisDataContainer *cOutputHist3 =
    mgr->CreateContainer("cbaumann_EventStatPbPb2011",
	TH1D::Class(),
	AliAnalysisManager::kOutputContainer,
	"cbaumann_LMEEPbPb2011_out.root");

  mgr->ConnectInput(task,  0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 0, coutput1 );
  mgr->ConnectOutput(task, 1, cOutputHist1);
  if (enableCF) {
    mgr->ConnectOutput(task, 2, cOutputHist2);
  }
  mgr->ConnectOutput(task, 3, cOutputHist3);

  return task;
}
<commit_msg>adjust path<commit_after>AliAnalysisTask *AddTask_cbaumann_LMEEPbPb2011(Bool_t runRejection=kFALSE, Bool_t setMC=kFALSE,Bool_t enableCF=kFALSE){
  //get the current analysis manager
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTask_cbaumann_LMEEPbPb2011", "No analysis manager found.");
    return 0;
  }

  //create config File names: TRAIN_ROOT is for running on GSI train,
  // ALICE_ROOT for CERN Lego trains
  TString configBasePath("$TRAIN_ROOT/cbaumann_dielectron/");
  TString trainRoot=gSystem->Getenv("TRAIN_ROOT");
  if (trainRoot.IsNull()) configBasePath= "$ALICE_ROOT/PWGDQ/dielectron/macrosLMEE/";
  TString configFile("ConfigLMEEPbPb2011.C");
  TString configLMEECutLib("LMEECutLib.C");

  TString configFilePath(configBasePath+configFile);
  TString configLMEECutLibPath(configBasePath+configLMEECutLib);

  //AOD Usage currently tested with separate task, to be merged
  if (mgr->GetInputEventHandler()->IsA()==AliAODInputHandler::Class()){
    ::Info("AddTaskLMEEPbPb2011", "no dedicated AOD configuration");
  }

  //Do we have an MC handler?
  Bool_t hasMC=setMC;
  if (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0)
    hasMC=kTRUE;

  if (!gROOT->GetListOfGlobalFunctions()->FindObject(configFile.Data()))
    gROOT->LoadMacro(configFilePath.Data());
  if (!gROOT->GetListOfGlobalFunctions()->FindObject(configLMEECutLib.Data()))
    gROOT->LoadMacro(configLMEECutLibPath.Data());

  LMEECutLib* cutlib = new LMEECutLib();
  AliAnalysisTaskMultiDielectron *task=new AliAnalysisTaskMultiDielectron("MultiDiEData");
  if (!hasMC){ task->UsePhysicsSelection();
  }
  task->SetTriggerMask(AliVEvent::kMB+AliVEvent::kCentral+AliVEvent::kSemiCentral);
  task->SetEventFilter(cutlib->GetEventCuts(LMEECutLib::kPbPb2011TPCandTOF)); //

  //load dielectron configuration file

  //add dielectron analysis with different cuts to the task
  if (runRejection) {

    AliDielectron *lowmass4=ConfigLMEEPbPb2011(4,hasMC,enableCF);
    task->AddDielectron(lowmass4);
    printf("add: %s\n",lowmass4->GetName());
  }
  else {

    AliDielectron *lowmass3=ConfigLMEEPbPb2011(3,hasMC,enableCF);
    task->AddDielectron(lowmass3);
    printf("add: %s\n",lowmass3->GetName())
      AliDielectron *lowmass1=ConfigLMEEPbPb2011(1,hasMC,enableCF);
    task->AddDielectron(lowmass1);
    printf("add: %s\n",lowmass1->GetName())
      AliDielectron *lowmass7=ConfigLMEEPbPb2011(7,hasMC,enableCF);
    task->AddDielectron(lowmass7);
    printf("add: %s\n",lowmass7->GetName())
  }

  mgr->AddTask(task);

  //create output container
  AliAnalysisDataContainer *coutput1 =
    mgr->CreateContainer("cbaumann_LMEEPbPb2011_tree",
	TTree::Class(),
	AliAnalysisManager::kExchangeContainer,
	"cbaumann_LMEEPbPb2011_default.root");

  AliAnalysisDataContainer *cOutputHist1 =
    mgr->CreateContainer("cbaumann_LMEEPbPb2011_out",
	TList::Class(),
	AliAnalysisManager::kOutputContainer,
	"cbaumann_LMEEPbPb2011_out.root");
  if (enableCF) {
    AliAnalysisDataContainer *cOutputHist2 =
      mgr->CreateContainer("cbaumann_LMEEPbPb2011_CF",
	  TList::Class(),
	  AliAnalysisManager::kOutputContainer,
	  "cbaumann_LMEEPbPb2011_out.root");

  }
  AliAnalysisDataContainer *cOutputHist3 =
    mgr->CreateContainer("cbaumann_EventStatPbPb2011",
	TH1D::Class(),
	AliAnalysisManager::kOutputContainer,
	"cbaumann_LMEEPbPb2011_out.root");

  mgr->ConnectInput(task,  0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 0, coutput1 );
  mgr->ConnectOutput(task, 1, cOutputHist1);
  if (enableCF) {
    mgr->ConnectOutput(task, 2, cOutputHist2);
  }
  mgr->ConnectOutput(task, 3, cOutputHist3);

  return task;
}
<|endoftext|>