<commit_before>/**
 * This file is part of the CernVM File System.
 */

#include "catalog_merge_tool.h"

#include "catalog.h"
#include "hash.h"
#include "logging.h"
#include "manifest.h"
#include "options.h"
#include "upload.h"
#include "util/posix.h"

namespace {

PathString MakeRelative(const PathString& path) {
  std::string rel_path;
  std::string abs_path = path.ToString();
  if (abs_path[0] == '/') {
    rel_path = abs_path.substr(1);
  } else {
    rel_path = abs_path;
  }
  return PathString(rel_path);
}

}  // namespace

namespace receiver {

CatalogMergeTool::ChangeItem::ChangeItem(ChangeType type,
                                         const PathString& path,
                                         const catalog::DirectoryEntry& entry1)
    : type_(type),
      path_(path),
      xattrs_(),
      entry1_(new catalog::DirectoryEntry(entry1)),
      entry2_(NULL) {}

CatalogMergeTool::ChangeItem::ChangeItem(ChangeType type,
                                         const PathString& path,
                                         const catalog::DirectoryEntry& entry1,
                                         const XattrList& xattrs)
    : type_(type),
      path_(path),
      xattrs_(xattrs),
      entry1_(new catalog::DirectoryEntry(entry1)),
      entry2_(NULL) {}

CatalogMergeTool::ChangeItem::ChangeItem(ChangeType type,
                                         const PathString& path,
                                         const catalog::DirectoryEntry& entry1,
                                         const catalog::DirectoryEntry& entry2)
    : type_(type),
      path_(path),
      xattrs_(),
      entry1_(new catalog::DirectoryEntry(entry1)),
      entry2_(new catalog::DirectoryEntry(entry2)) {}

CatalogMergeTool::ChangeItem::ChangeItem(const ChangeItem& other)
    : type_(other.type_),
      path_(other.path_),
      xattrs_(other.xattrs_),
      entry1_(new catalog::DirectoryEntry(*(other.entry1_))),
      entry2_(other.entry2_ ? new catalog::DirectoryEntry(*(other.entry2_))
                            : NULL) {}

CatalogMergeTool::ChangeItem::~ChangeItem() {
  if (entry1_) {
    delete entry1_;
    entry1_ = NULL;
  }
  if (entry2_) {
    delete entry2_;
    entry2_ = NULL;
  }
}

CatalogMergeTool::ChangeItem& CatalogMergeTool::ChangeItem::operator=(
    const ChangeItem& other) {
  type_ = other.type_;
  path_ = other.path_;
  xattrs_ = other.xattrs_;
  entry1_ = new catalog::DirectoryEntry(*other.entry1_);
  entry2_ = new catalog::DirectoryEntry(*other.entry2_);

  return *this;
}

CatalogMergeTool::CatalogMergeTool(const std::string& repo_path,
                                   const shash::Any& old_root_hash,
                                   const shash::Any& new_root_hash,
                                   const std::string& temp_dir_prefix,
                                   download::DownloadManager* download_manager,
                                   manifest::Manifest* manifest)
    : CatalogDiffTool(repo_path, old_root_hash, new_root_hash, temp_dir_prefix,
                      download_manager),
      repo_path_(repo_path),
      temp_dir_prefix_(temp_dir_prefix),
      download_manager_(download_manager),
      manifest_(manifest) {}

CatalogMergeTool::~CatalogMergeTool() {}

bool CatalogMergeTool::Run(const Params& params,
                           std::string* new_manifest_path) {
  bool ret = CatalogDiffTool::Run();

  upload::SpoolerDefinition definition(
      params.spooler_configuration, params.hash_alg, params.compression_alg,
      params.use_file_chunking, params.min_chunk_size, params.avg_chunk_size,
      params.max_chunk_size, "dummy_token", "dummy_key");
  UniquePtr<upload::Spooler> spooler(upload::Spooler::Construct(definition));
  perf::Statistics stats;
  const std::string temp_dir = CreateTempDir(temp_dir_prefix_);
  output_catalog_mgr_ = new catalog::WritableCatalogManager(
      manifest_->catalog_hash(), repo_path_, temp_dir, spooler,
      download_manager_, params.entry_warn_thresh, &stats,
      params.use_autocatalogs, params.max_weight, params.min_weight);
  output_catalog_mgr_->Init();

  ret &= InsertChangesIntoOutputCatalog();

  ret &= CreateNewManifest(new_manifest_path);

  return ret;
}

void CatalogMergeTool::ReportAddition(const PathString& path,
                                      const catalog::DirectoryEntry& entry,
                                      const XattrList& xattrs) {
  changes_.push_back(
      ChangeItem(ChangeItem::kAddition, MakeRelative(path), entry, xattrs));
}

void CatalogMergeTool::ReportRemoval(const PathString& path,
                                     const catalog::DirectoryEntry& entry) {
  changes_.push_back(
      ChangeItem(ChangeItem::kRemoval, MakeRelative(path), entry));
}

void CatalogMergeTool::ReportModification(
    const PathString& path, const catalog::DirectoryEntry& entry1,
    const catalog::DirectoryEntry& entry2) {
  changes_.push_back(ChangeItem(ChangeItem::kModification, MakeRelative(path),
                                entry1, entry2));
}

bool CatalogMergeTool::InsertChangesIntoOutputCatalog() {
  for (size_t i = 0; i < changes_.size(); ++i) {
    ChangeItem change = changes_[i];
    const std::string parent_path = std::strchr(change.path_.c_str(), '/')
                                        ? GetParentPath(change.path_).c_str()
                                        : "";
    switch (change.type_) {
      case ChangeItem::kAddition:

        if (change.entry1_->IsDirectory()) {
          output_catalog_mgr_->AddDirectory(*change.entry1_, parent_path);
        } else if (change.entry1_->IsRegular() || change.entry1_->IsLink()) {
          const catalog::DirectoryEntryBase* base_entry =
              static_cast<const catalog::DirectoryEntryBase*>(change.entry1_);
          output_catalog_mgr_->AddFile(*base_entry, change.xattrs_,
                                       parent_path);
        }
        break;

      case ChangeItem::kRemoval:

        if (change.entry1_->IsDirectory()) {
          output_catalog_mgr_->RemoveDirectory(change.path_.c_str());
        } else if (change.entry1_->IsRegular() || change.entry1_->IsLink()) {
          output_catalog_mgr_->RemoveFile(change.path_.c_str());
        }
        break;

      case ChangeItem::kModification:

        if (change.entry1_->IsDirectory() && change.entry2_->IsDirectory()) {
          // From directory to directory
          const catalog::DirectoryEntryBase* base_entry =
              static_cast<const catalog::DirectoryEntryBase*>(change.entry2_);
          output_catalog_mgr_->TouchDirectory(*base_entry,
                                              change.path_.c_str());

        } else if ((change.entry1_->IsRegular() || change.entry1_->IsLink()) &&
                   change.entry2_->IsDirectory()) {
          // From file to directory
          output_catalog_mgr_->RemoveFile(change.path_.c_str());
          output_catalog_mgr_->AddDirectory(*change.entry2_, parent_path);

        } else if (change.entry1_->IsDirectory() &&
                   (change.entry2_->IsRegular() || change.entry2_->IsLink())) {
          // From directory to file
          const catalog::DirectoryEntryBase* base_entry =
              static_cast<const catalog::DirectoryEntryBase*>(change.entry2_);
          output_catalog_mgr_->RemoveDirectory(change.path_.c_str());
          output_catalog_mgr_->AddFile(*base_entry, change.xattrs_,
                                       parent_path);

        } else if ((change.entry1_->IsRegular() || change.entry1_->IsLink()) &&
                   (change.entry2_->IsRegular() || change.entry2_->IsLink())) {
          // From file to file
          const catalog::DirectoryEntryBase* base_entry =
              static_cast<const catalog::DirectoryEntryBase*>(change.entry2_);
          output_catalog_mgr_->RemoveFile(change.path_.c_str());
          output_catalog_mgr_->AddFile(*base_entry, change.xattrs_,
                                       parent_path);
        }
        break;

      default:

        LogCvmfs(kLogCvmfs, kLogStderr,
                 "What should not be representable presented itself. Exiting.");
        abort();
        break;
    }
  }

  return true;
}

bool CatalogMergeTool::CreateNewManifest(std::string* new_manifest_path) {
  if (!output_catalog_mgr_->Commit(false, 0, manifest_)) {
    LogCvmfs(kLogCvmfs, kLogStderr,
             "CatalogMergeTool - Could not commit output catalog");
    return false;
  }

  const std::string temp_dir = CreateTempDir(temp_dir_prefix_);
  const std::string new_path = temp_dir + "/new_manifest";

  if (!manifest_->Export(new_path)) {
    LogCvmfs(kLogCvmfs, kLogStderr,
             "CatalogMergeTool - Could not export new manifest");
  }

  *new_manifest_path = new_path;

  return true;
}

}  // namespace receiver
<commit_msg>Remove redundant checks in ChangeItem destructor<commit_after>/**
 * This file is part of the CernVM File System.
 */

#include "catalog_merge_tool.h"

#include "catalog.h"
#include "hash.h"
#include "logging.h"
#include "manifest.h"
#include "options.h"
#include "upload.h"
#include "util/posix.h"

namespace {

PathString MakeRelative(const PathString& path) {
  std::string rel_path;
  std::string abs_path = path.ToString();
  if (abs_path[0] == '/') {
    rel_path = abs_path.substr(1);
  } else {
    rel_path = abs_path;
  }
  return PathString(rel_path);
}

}  // namespace

namespace receiver {

CatalogMergeTool::ChangeItem::ChangeItem(ChangeType type,
                                         const PathString& path,
                                         const catalog::DirectoryEntry& entry1)
    : type_(type),
      path_(path),
      xattrs_(),
      entry1_(new catalog::DirectoryEntry(entry1)),
      entry2_(NULL) {}

CatalogMergeTool::ChangeItem::ChangeItem(ChangeType type,
                                         const PathString& path,
                                         const catalog::DirectoryEntry& entry1,
                                         const XattrList& xattrs)
    : type_(type),
      path_(path),
      xattrs_(xattrs),
      entry1_(new catalog::DirectoryEntry(entry1)),
      entry2_(NULL) {}

CatalogMergeTool::ChangeItem::ChangeItem(ChangeType type,
                                         const PathString& path,
                                         const catalog::DirectoryEntry& entry1,
                                         const catalog::DirectoryEntry& entry2)
    : type_(type),
      path_(path),
      xattrs_(),
      entry1_(new catalog::DirectoryEntry(entry1)),
      entry2_(new catalog::DirectoryEntry(entry2)) {}

CatalogMergeTool::ChangeItem::ChangeItem(const ChangeItem& other)
    : type_(other.type_),
      path_(other.path_),
      xattrs_(other.xattrs_),
      entry1_(new catalog::DirectoryEntry(*(other.entry1_))),
      entry2_(other.entry2_ ? new catalog::DirectoryEntry(*(other.entry2_))
                            : NULL) {}

CatalogMergeTool::ChangeItem::~ChangeItem() {
  delete entry1_;
  delete entry2_;
}

CatalogMergeTool::ChangeItem& CatalogMergeTool::ChangeItem::operator=(
    const ChangeItem& other) {
  type_ = other.type_;
  path_ = other.path_;
  xattrs_ = other.xattrs_;
  entry1_ = new catalog::DirectoryEntry(*other.entry1_);
  entry2_ = new catalog::DirectoryEntry(*other.entry2_);

  return *this;
}

CatalogMergeTool::CatalogMergeTool(const std::string& repo_path,
                                   const shash::Any& old_root_hash,
                                   const shash::Any& new_root_hash,
                                   const std::string& temp_dir_prefix,
                                   download::DownloadManager* download_manager,
                                   manifest::Manifest* manifest)
    : CatalogDiffTool(repo_path, old_root_hash, new_root_hash, temp_dir_prefix,
                      download_manager),
      repo_path_(repo_path),
      temp_dir_prefix_(temp_dir_prefix),
      download_manager_(download_manager),
      manifest_(manifest) {}

CatalogMergeTool::~CatalogMergeTool() {}

bool CatalogMergeTool::Run(const Params& params,
                           std::string* new_manifest_path) {
  bool ret = CatalogDiffTool::Run();

  upload::SpoolerDefinition definition(
      params.spooler_configuration, params.hash_alg, params.compression_alg,
      params.use_file_chunking, params.min_chunk_size, params.avg_chunk_size,
      params.max_chunk_size, "dummy_token", "dummy_key");
  UniquePtr<upload::Spooler> spooler(upload::Spooler::Construct(definition));
  perf::Statistics stats;
  const std::string temp_dir = CreateTempDir(temp_dir_prefix_);
  output_catalog_mgr_ = new catalog::WritableCatalogManager(
      manifest_->catalog_hash(), repo_path_, temp_dir, spooler,
      download_manager_, params.entry_warn_thresh, &stats,
      params.use_autocatalogs, params.max_weight, params.min_weight);
  output_catalog_mgr_->Init();

  ret &= InsertChangesIntoOutputCatalog();

  ret &= CreateNewManifest(new_manifest_path);

  return ret;
}

void CatalogMergeTool::ReportAddition(const PathString& path,
                                      const catalog::DirectoryEntry& entry,
                                      const XattrList& xattrs) {
  changes_.push_back(
      ChangeItem(ChangeItem::kAddition, MakeRelative(path), entry, xattrs));
}

void CatalogMergeTool::ReportRemoval(const PathString& path,
                                     const catalog::DirectoryEntry& entry) {
  changes_.push_back(
      ChangeItem(ChangeItem::kRemoval, MakeRelative(path), entry));
}

void CatalogMergeTool::ReportModification(
    const PathString& path, const catalog::DirectoryEntry& entry1,
    const catalog::DirectoryEntry& entry2) {
  changes_.push_back(ChangeItem(ChangeItem::kModification, MakeRelative(path),
                                entry1, entry2));
}

bool CatalogMergeTool::InsertChangesIntoOutputCatalog() {
  for (size_t i = 0; i < changes_.size(); ++i) {
    ChangeItem change = changes_[i];
    const std::string parent_path = std::strchr(change.path_.c_str(), '/')
                                        ? GetParentPath(change.path_).c_str()
                                        : "";
    switch (change.type_) {
      case ChangeItem::kAddition:

        if (change.entry1_->IsDirectory()) {
          output_catalog_mgr_->AddDirectory(*change.entry1_, parent_path);
        } else if (change.entry1_->IsRegular() || change.entry1_->IsLink()) {
          const catalog::DirectoryEntryBase* base_entry =
              static_cast<const catalog::DirectoryEntryBase*>(change.entry1_);
          output_catalog_mgr_->AddFile(*base_entry, change.xattrs_,
                                       parent_path);
        }
        break;

      case ChangeItem::kRemoval:

        if (change.entry1_->IsDirectory()) {
          output_catalog_mgr_->RemoveDirectory(change.path_.c_str());
        } else if (change.entry1_->IsRegular() || change.entry1_->IsLink()) {
          output_catalog_mgr_->RemoveFile(change.path_.c_str());
        }
        break;

      case ChangeItem::kModification:

        if (change.entry1_->IsDirectory() && change.entry2_->IsDirectory()) {
          // From directory to directory
          const catalog::DirectoryEntryBase* base_entry =
              static_cast<const catalog::DirectoryEntryBase*>(change.entry2_);
          output_catalog_mgr_->TouchDirectory(*base_entry,
                                              change.path_.c_str());

        } else if ((change.entry1_->IsRegular() || change.entry1_->IsLink()) &&
                   change.entry2_->IsDirectory()) {
          // From file to directory
          output_catalog_mgr_->RemoveFile(change.path_.c_str());
          output_catalog_mgr_->AddDirectory(*change.entry2_, parent_path);

        } else if (change.entry1_->IsDirectory() &&
                   (change.entry2_->IsRegular() || change.entry2_->IsLink())) {
          // From directory to file
          const catalog::DirectoryEntryBase* base_entry =
              static_cast<const catalog::DirectoryEntryBase*>(change.entry2_);
          output_catalog_mgr_->RemoveDirectory(change.path_.c_str());
          output_catalog_mgr_->AddFile(*base_entry, change.xattrs_,
                                       parent_path);

        } else if ((change.entry1_->IsRegular() || change.entry1_->IsLink()) &&
                   (change.entry2_->IsRegular() || change.entry2_->IsLink())) {
          // From file to file
          const catalog::DirectoryEntryBase* base_entry =
              static_cast<const catalog::DirectoryEntryBase*>(change.entry2_);
          output_catalog_mgr_->RemoveFile(change.path_.c_str());
          output_catalog_mgr_->AddFile(*base_entry, change.xattrs_,
                                       parent_path);
        }
        break;

      default:

        LogCvmfs(kLogCvmfs, kLogStderr,
                 "What should not be representable presented itself. Exiting.");
        abort();
        break;
    }
  }

  return true;
}

bool CatalogMergeTool::CreateNewManifest(std::string* new_manifest_path) {
  if (!output_catalog_mgr_->Commit(false, 0, manifest_)) {
    LogCvmfs(kLogCvmfs, kLogStderr,
             "CatalogMergeTool - Could not commit output catalog");
    return false;
  }

  const std::string temp_dir = CreateTempDir(temp_dir_prefix_);
  const std::string new_path = temp_dir + "/new_manifest";

  if (!manifest_->Export(new_path)) {
    LogCvmfs(kLogCvmfs, kLogStderr,
             "CatalogMergeTool - Could not export new manifest");
  }

  *new_manifest_path = new_path;

  return true;
}

}  // namespace receiver
<|endoftext|>


<commit_before><commit_msg>fix compile<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (c) 2008-2014 John Connor (BM-NC49AxAjcqVcF5jNPu85Rb8MJ2d9JqZt)
 *
 * This file is part of coinpp.
 *
 * coinpp is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <set>
#include <thread>

#include <boost/algorithm/string.hpp>

#include <database/logger.hpp>
#include <database/node.hpp>
#include <database/stack.hpp>
#include <database/stack_impl.hpp>
#include <database/utility.hpp>

using namespace database;

stack_impl::stack_impl(stack & owner)
    : stack_(owner)
    , strand_(m_io_service)
    , udp_resolver_(m_io_service)
{
    // ...
}

void stack_impl::start(const stack::configuration & config)
{
    /**
     * Allocate the node.
     */
    m_node.reset(new node(m_io_service, *this));

    /**
     * Start the node.
     */
    m_node->start(config);

    /**
     * Calculate the number of threads.
     */
    std::size_t threads = 1
        /*
        //:FIXME: There is a deadlock somewhere, udp stops working
        (std::thread::hardware_concurrency() == 0 ? 1 :
        std::thread::hardware_concurrency())
        */
    ;

    log_info(
        "Stack is starting with " << threads << " concurrent threads."
    );

    for (auto i = 0; i < threads; i++)
    {
        threads_.push_back(
            std::make_shared<std::thread>(&stack_impl::run, this)
        );
    }
}

void stack_impl::stop()
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    /**
     * Stop the node.
     */
    m_node->stop();

    /**
     * Stop the boost::asio::io_service.
     */
    m_io_service.stop();

    try
    {
        for (auto & i : threads_)
        {
            if (i)
            {
                i->join();
            }
        }
    }
    catch (std::exception & e)
    {
        // ...
    }
}

void stack_impl::run()
{
    m_io_service.run();
}

void stack_impl::join(
    const std::vector< std::pair<std::string, unsigned short> > & contacts
    )
{
    m_io_service.post(strand_.wrap(
        std::bind(&stack_impl::do_join, this, contacts))
    );
}

void stack_impl::leave()
{
    m_io_service.post(strand_.wrap(
        std::bind(&stack_impl::do_leave, this))
    );
}

void stack_impl::do_join(
    const std::vector< std::pair<std::string, unsigned short> > & contacts
    )
{
    /**
     * Randomize the bootstrap nodes.
     */
    std::vector< std::pair<std::string, unsigned short> > randomized;
    randomized.insert(randomized.begin(), contacts.begin(), contacts.end());
    std::random_shuffle(randomized.begin(), randomized.end());

    std::lock_guard<std::recursive_mutex> l(mutex_);

    for (auto & i : randomized)
    {
        try
        {
            boost::asio::ip::udp::endpoint ep(
                boost::asio::ip::address::from_string(i.first.c_str()), i.second
            );

            /**
             * Add the bootstrap contact.
             */
            m_node->bootstrap_contacts().push_back(ep);

            /**
             * Queue the endpoint to be pinged.
             */
            m_node->queue_ping(ep);
        }
        catch (std::exception & e)
        {
            boost::asio::ip::udp::resolver::query query(
                i.first, utility::to_string(i.second)
            );

            udp_resolver_.async_resolve(query, strand_.wrap(
                std::bind(&stack_impl::handle_udp_resolve, this,
                std::placeholders::_1, std::placeholders::_2))
            );
        }
    }
}

void stack_impl::do_leave()
{
    // ...
}

std::uint16_t stack_impl::store(const std::string & query_string)
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    if (m_node.get())
    {
        return m_node->store(query_string);
    }

    return 0;
}

std::uint16_t stack_impl::find(
    const std::string & query_string, const std::size_t & max_results
    )
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    if (m_node.get())
    {
        return m_node->find(query_string, max_results);
    }

    return 0;
}

std::uint16_t stack_impl::proxy(
    const char * addr, const std::uint16_t & port, const char * buf,
    const std::size_t & len
    )
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    if (m_node.get())
    {
        return m_node->proxy(addr, port, buf, len);
    }

    return 0;
}

std::list< std::pair<std::string, std::uint16_t> > stack_impl::endpoints()
{
    if (m_node.get())
    {
        return m_node->endpoints();
    }

    return std::list< std::pair<std::string, std::uint16_t> > ();
}

void stack_impl::on_connected(const boost::asio::ip::tcp::endpoint & ep)
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    stack_.on_connected(ep.address().to_string().c_str(), ep.port());
}

void stack_impl::on_disconnected(const boost::asio::ip::tcp::endpoint & ep)
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    stack_.on_disconnected(ep.address().to_string().c_str(), ep.port());
}

void stack_impl::on_find(
    const std::uint16_t & transaction_id, const std::string & query_string
    )
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    stack_.on_find(transaction_id, query_string);
}

void stack_impl::on_proxy(
    const std::uint16_t & tid, const char * addr, const std::uint16_t & port,
    const std::string & value
    )
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    stack_.on_proxy(tid, addr, port, value);
}

void stack_impl::on_udp_receive(
    const char * addr, const std::uint16_t & port, const char * buf,
    const std::size_t & len
    )
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    stack_.on_udp_receive(addr, port, buf, len);
}

void stack_impl::handle_udp_resolve(
    const boost::system::error_code & ec,
    boost::asio::ip::udp::resolver::iterator it
    )
{
    if (ec)
    {
        // ...
    }
    else
    {
        for (; it != boost::asio::ip::udp::resolver::iterator(); ++it)
        {
            std::lock_guard<std::recursive_mutex> l(mutex_);

            if (m_node.get())
            {
                /**
                 * Add the bootstrap contact.
                 */
                m_node->bootstrap_contacts().push_back(it->endpoint());

                /**
                 * Queue the endpoint to be pinged.
                 */
                m_node->queue_ping(it->endpoint());
            }
        }
    }
}

boost::asio::io_service & stack_impl::io_service()
{
    return m_io_service;
}
<commit_msg>Note on routing thread usage.<commit_after>/*
 * Copyright (c) 2008-2014 John Connor (BM-NC49AxAjcqVcF5jNPu85Rb8MJ2d9JqZt)
 *
 * This file is part of coinpp.
 *
 * coinpp is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <set>
#include <thread>

#include <boost/algorithm/string.hpp>

#include <database/logger.hpp>
#include <database/node.hpp>
#include <database/stack.hpp>
#include <database/stack_impl.hpp>
#include <database/utility.hpp>

using namespace database;

stack_impl::stack_impl(stack & owner)
    : stack_(owner)
    , strand_(m_io_service)
    , udp_resolver_(m_io_service)
{
    // ...
}

void stack_impl::start(const stack::configuration & config)
{
    /**
     * Allocate the node.
     */
    m_node.reset(new node(m_io_service, *this));

    /**
     * Start the node.
     */
    m_node->start(config);

    /**
     * Optimal operation requires only is a single thread.
     */
    std::size_t threads = 1;

    log_info(
        "Stack is starting with " << threads << " concurrent threads."
    );

    for (auto i = 0; i < threads; i++)
    {
        threads_.push_back(
            std::make_shared<std::thread>(&stack_impl::run, this)
        );
    }
}

void stack_impl::stop()
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    /**
     * Stop the node.
     */
    m_node->stop();

    /**
     * Stop the boost::asio::io_service.
     */
    m_io_service.stop();

    try
    {
        for (auto & i : threads_)
        {
            if (i)
            {
                i->join();
            }
        }
    }
    catch (std::exception & e)
    {
        // ...
    }
}

void stack_impl::run()
{
    m_io_service.run();
}

void stack_impl::join(
    const std::vector< std::pair<std::string, unsigned short> > & contacts
    )
{
    m_io_service.post(strand_.wrap(
        std::bind(&stack_impl::do_join, this, contacts))
    );
}

void stack_impl::leave()
{
    m_io_service.post(strand_.wrap(
        std::bind(&stack_impl::do_leave, this))
    );
}

void stack_impl::do_join(
    const std::vector< std::pair<std::string, unsigned short> > & contacts
    )
{
    /**
     * Randomize the bootstrap nodes.
     */
    std::vector< std::pair<std::string, unsigned short> > randomized;
    randomized.insert(randomized.begin(), contacts.begin(), contacts.end());
    std::random_shuffle(randomized.begin(), randomized.end());

    std::lock_guard<std::recursive_mutex> l(mutex_);

    for (auto & i : randomized)
    {
        try
        {
            boost::asio::ip::udp::endpoint ep(
                boost::asio::ip::address::from_string(i.first.c_str()), i.second
            );

            /**
             * Add the bootstrap contact.
             */
            m_node->bootstrap_contacts().push_back(ep);

            /**
             * Queue the endpoint to be pinged.
             */
            m_node->queue_ping(ep);
        }
        catch (std::exception & e)
        {
            boost::asio::ip::udp::resolver::query query(
                i.first, utility::to_string(i.second)
            );

            udp_resolver_.async_resolve(query, strand_.wrap(
                std::bind(&stack_impl::handle_udp_resolve, this,
                std::placeholders::_1, std::placeholders::_2))
            );
        }
    }
}

void stack_impl::do_leave()
{
    // ...
}

std::uint16_t stack_impl::store(const std::string & query_string)
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    if (m_node.get())
    {
        return m_node->store(query_string);
    }

    return 0;
}

std::uint16_t stack_impl::find(
    const std::string & query_string, const std::size_t & max_results
    )
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    if (m_node.get())
    {
        return m_node->find(query_string, max_results);
    }

    return 0;
}

std::uint16_t stack_impl::proxy(
    const char * addr, const std::uint16_t & port, const char * buf,
    const std::size_t & len
    )
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    if (m_node.get())
    {
        return m_node->proxy(addr, port, buf, len);
    }

    return 0;
}

std::list< std::pair<std::string, std::uint16_t> > stack_impl::endpoints()
{
    if (m_node.get())
    {
        return m_node->endpoints();
    }

    return std::list< std::pair<std::string, std::uint16_t> > ();
}

void stack_impl::on_connected(const boost::asio::ip::tcp::endpoint & ep)
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    stack_.on_connected(ep.address().to_string().c_str(), ep.port());
}

void stack_impl::on_disconnected(const boost::asio::ip::tcp::endpoint & ep)
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    stack_.on_disconnected(ep.address().to_string().c_str(), ep.port());
}

void stack_impl::on_find(
    const std::uint16_t & transaction_id, const std::string & query_string
    )
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    stack_.on_find(transaction_id, query_string);
}

void stack_impl::on_proxy(
    const std::uint16_t & tid, const char * addr, const std::uint16_t & port,
    const std::string & value
    )
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    stack_.on_proxy(tid, addr, port, value);
}

void stack_impl::on_udp_receive(
    const char * addr, const std::uint16_t & port, const char * buf,
    const std::size_t & len
    )
{
    std::lock_guard<std::recursive_mutex> l(mutex_);

    stack_.on_udp_receive(addr, port, buf, len);
}

void stack_impl::handle_udp_resolve(
    const boost::system::error_code & ec,
    boost::asio::ip::udp::resolver::iterator it
    )
{
    if (ec)
    {
        // ...
    }
    else
    {
        for (; it != boost::asio::ip::udp::resolver::iterator(); ++it)
        {
            std::lock_guard<std::recursive_mutex> l(mutex_);

            if (m_node.get())
            {
                /**
                 * Add the bootstrap contact.
                 */
                m_node->bootstrap_contacts().push_back(it->endpoint());

                /**
                 * Queue the endpoint to be pinged.
                 */
                m_node->queue_ping(it->endpoint());
            }
        }
    }
}

boost::asio::io_service & stack_impl::io_service()
{
    return m_io_service;
}
<|endoftext|>


<commit_before>
/**************************************************************************
 * Copyright(c) 1998-2000, 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.                  *
 **************************************************************************/

/* $Id$ */

/******************************************************************
 *    Produde digits from hits
 *       digits is TObject and includes
 *	We are writing array if C & A  TDC
 *	C & A  ADC (will need for slow simulation)
 *	TOF first particle C & A
 *	mean time and time difference (vertex position)
 *
 *      Alla.Maevskaya@cern.ch
 ****************************************************************/

#include <TArrayI.h>
#include <TFile.h>
#include <TGraph.h>
#include <TH1F.h>
#include <TMath.h>
#include <TRandom.h>
#include <TTree.h>

#include "AliLog.h"
#include "AliT0Digitizer.h"
#include "AliT0.h"
#include "AliT0hit.h"
#include "AliT0digit.h"
#include "AliRunDigitizer.h"
#include "AliRun.h"
#include <AliLoader.h>
#include <AliRunLoader.h>
#include <stdlib.h>
#include "AliT0Parameters.h"

ClassImp(AliT0Digitizer)

//___________________________________________
  AliT0Digitizer::AliT0Digitizer()  :AliDigitizer(),
				     fT0(0),
				     fHits(0),
				     fdigits(0),
				     ftimeCFD(new TArrayI(24)),
				     ftimeLED (new TArrayI(24)),
				     fADC(new TArrayI(24)),
				     fADC0 (new TArrayI(24)),
				     fSumMult(0),
				     fAmpLED(0),
				     fParam(0)

{
// Default ctor - don't use it
  ;
}

//___________________________________________
AliT0Digitizer::AliT0Digitizer(AliRunDigitizer* manager)
  :AliDigitizer(manager),
   fT0(0),
   fHits(0),
   fdigits(0),
   ftimeCFD(new TArrayI(24)),
   ftimeLED (new TArrayI(24)),
   fADC(new TArrayI(24)),
   fADC0 (new TArrayI(24)),
   fSumMult(0),
   fAmpLED(0),
   fParam(0)
{
// ctor which should be used

  AliDebug(1,"processed");
  fParam = AliT0Parameters::Instance();
  fParam->Init();
  Int_t index[25000];
  Bool_t down=true;

  for (Int_t i=0; i<24; i++){
    TGraph* gr = fParam ->GetAmpLEDRec(i);
    Int_t np = gr->GetN();
    Double_t *x = gr->GetX();
    Double_t *y = gr->GetY();

    Double_t *x1 = new Double_t[np];
    Double_t *y1 = new Double_t[np];
    for (Int_t ii=0; ii<np; ii++) {
      y1[ii]=y[np-ii-1]; x1[ii]=x[np-ii-1];
    }

    TGraph *grInverse = new TGraph(np,y1,x1);
    fAmpLED.AddAtAndExpand(grInverse,i);

     TGraph* grw = fParam ->GetWalk(i);
      Int_t npw = grw->GetN();
     Double_t *yw = grw->GetY();
    TMath::Sort(npw, yw, index,down);
    fMaxValue[i]=Int_t(yw[index[0]]);
  }

    //    delete [] x1;
    //   delete [] y1;
}

//------------------------------------------------------------------------
AliT0Digitizer::~AliT0Digitizer()
{
// Destructor

  AliDebug(1,"T0");

  delete ftimeCFD;
  delete fADC;
  delete ftimeLED;
  delete  fADC0;
  //  delete fAmpLED;
}

//------------------------------------------------------------------------
Bool_t AliT0Digitizer::Init()
{
// Initialization
  AliDebug(1," Init");
 return kTRUE;
}

//---------------------------------------------------------------------
void AliT0Digitizer::Exec(Option_t* /*option*/)
{

  /*
    Produde digits from hits
        digits is TObject and includes
	We are writing array if C & A  TDC
	C & A  ADC (will need for slow simulation)
	TOF first particle C & A
	mean time and time difference (vertex position)

  */

  //output loader
  AliRunLoader *outRL = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
  AliLoader * pOutStartLoader = outRL->GetLoader("T0Loader");

  AliDebug(1,"start...");
  //input loader
  //
  // From hits to digits
  //
  Int_t hit, nhits;
  Int_t countE[24];
  Int_t volume, pmt, trCFD, trLED;
  Float_t sl, qt;
  Int_t  bestATDC, bestCTDC, qtCh;
  Float_t time[24], besttime[24], timeGaus[24] ;
  //Q->T-> coefficients !!!! should be asked!!!
  Float_t timeDelayCFD[24];
  Int_t threshold =50; //photoelectrons
  Float_t zdetA, zdetC;
  Int_t sumMultCoeff = 100;
  Int_t refpoint=0;

  Int_t ph2Mip = fParam->GetPh2Mip();
  Float_t channelWidth = fParam->GetChannelWidth() ;
  Float_t delayVertex = fParam->GetTimeDelayTVD();

  zdetC = TMath::Abs(fParam->GetZPosition("T0/C/PMT1"));
  zdetA  = TMath::Abs(fParam->GetZPosition("T0/A/PMT15"));

  AliT0hit  *startHit;
  TBranch *brHits=0;

  Int_t nFiles=fManager->GetNinputs();
  for (Int_t inputFile=0; inputFile<nFiles;  inputFile++) {
    if (inputFile < nFiles-1) {
      AliWarning(Form("ignoring input stream %d", inputFile));
      continue;

    }

    Float_t besttimeC=99999.;
    Float_t besttimeA=99999.;
    Int_t pmtBestC=9999;
    Int_t pmtBestA=9999;
    Int_t timeDiff=999, meanTime=0;
    Int_t sumMult =0;   fSumMult=0;
    bestATDC = 99999;  bestCTDC = 99999;

    ftimeCFD -> Reset();
    fADC -> Reset();
    fADC0 -> Reset();
    ftimeLED ->Reset();
    for (Int_t i0=0; i0<24; i0++)
      {
	time[i0]=besttime[i0]=timeGaus[i0]=99999; countE[i0]=0;
      }
    AliRunLoader * inRL = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inputFile));
    AliLoader * pInStartLoader = inRL->GetLoader("T0Loader");
    if (!inRL->GetAliRun()) inRL->LoadgAlice();
    AliT0 *fT0  = (AliT0*)inRL ->GetAliRun()->GetDetector("T0");

       //read Hits
    pInStartLoader->LoadHits("READ");//probably it is necessary to load them before
    TClonesArray *fHits = fT0->Hits ();
    TTree *th = pInStartLoader->TreeH();
    brHits = th->GetBranch("T0");
    if (brHits) {
      fT0->SetHitsAddressBranch(brHits);
    }else{
      AliError("Branch T0 hit not found");
      exit(111);
    }
    Int_t ntracks    = (Int_t) th->GetEntries();

    if (ntracks<=0) return;
    // Start loop on tracks in the hits containers
    for (Int_t track=0; track<ntracks;track++) {
      brHits->GetEntry(track);
      nhits = fHits->GetEntriesFast();
      for (hit=0;hit<nhits;hit++)
	{
	  startHit   = (AliT0hit*) fHits->UncheckedAt(hit);
	  if (!startHit) {
 	    AliError("The unchecked hit doesn't exist");
	    break;
	  }
	  pmt=startHit->Pmt();
	  Int_t numpmt=pmt-1;
	  Double_t e=startHit->Etot();
	  volume = startHit->Volume();

	  //	  if(e>0 && RegisterPhotoE(numpmt,e)) {
	  if(e>0 ) {
	    countE[numpmt]++;
	    besttime[numpmt] = startHit->Time();
	    if(besttime[numpmt]<time[numpmt])
	      {
		time[numpmt]=besttime[numpmt];
	      }
	  } //photoelectron accept
	} //hits loop
    } //track loop

    //spread time A&C by 25ps   && besttime
    Float_t c = 0.0299792; // cm/ps

    Float_t koef=(zdetA-zdetC)/c; //correction position difference by cable
    for (Int_t ipmt=0; ipmt<12; ipmt++){
      if(countE[ipmt] > threshold) {
	timeGaus[ipmt]=gRandom->Gaus(time[ipmt],25)+koef;
	if(timeGaus[ipmt]<besttimeC){
	  besttimeC=timeGaus[ipmt]; //timeC
	  pmtBestC=ipmt;}
      }
    }
    for ( Int_t ipmt=12; ipmt<24; ipmt++){
      if(countE[ipmt] > threshold) {
	timeGaus[ipmt]=gRandom->Gaus(time[ipmt],25);
	if(timeGaus[ipmt]<besttimeA) {
	  besttimeA=timeGaus[ipmt]; //timeA
	  pmtBestA=ipmt;}
      }
    }

    timeDelayCFD[0] = fParam->GetTimeDelayCFD(0);

    for (Int_t i=0; i<24; i++)
      {
       	Float_t  al = countE[i];
	if (al>threshold && timeGaus[i]<50000 ) {
	  //fill ADC
	  // QTC procedure:
	  // phe -> mV 0.3; 1MIP ->500phe -> ln (amp (mV)) = 5;
	  // max 200ns, HIJING  mean 50000phe -> 15000mv -> ln = 15 (s zapasom)
	  // channel 25ps
	  qt= 50.*al/ph2Mip;  // 50mv/Mip amp in mV
	  //  fill TDC
	  timeDelayCFD[i] = fParam->GetTimeDelayCFD(i);
 	  trCFD = Int_t (timeGaus[i]/channelWidth + timeDelayCFD[i]);
	  TGraph* gr = ((TGraph*)fAmpLED.At(i));
	  sl = gr->Eval(qt);

	  trLED = Int_t(( timeGaus[i] + 1000*sl )/channelWidth);
	  qtCh=Int_t (1000.*TMath::Log(qt) / channelWidth);
	  fADC0->AddAt(0,i);
	  fADC->AddAt(qtCh,i);
	  ftimeLED->AddAt(trLED,i);
	  //	  sumMult += Int_t ((al*gain[i]/ph2Mip)*50) ;
	  sumMult += Int_t (qt/sumMultCoeff)  ;

	  // put slewing
	  TGraph *fu=(TGraph*) fParam ->GetWalk(i) ;
	  Float_t slew=fu->Eval(Float_t(qtCh));

	  //	  trCFD=trCFD-Int_t(fMaxValue[i]-slew);
	  trCFD = trCFD-Int_t(fMaxValue[i]-slew) + 2000; //for the same channel as cosmic
	  ftimeCFD->AddAt(Int_t (trCFD),i);
	  AliDebug(10,Form("  pmt %i : time in ns %f time in channels %i  LEd %i  ",  i, timeGaus[i],trCFD, trLED ));
	  AliDebug(10,Form(" qt in mV %f qt in ns %f qt in channels %i   ",qt,
			   TMath::Log(qt), qtCh));

	}
      } //pmt loop

    //folding with alignmentz position distribution
    if( besttimeC > 10000. && besttimeC <15000)
      bestCTDC=Int_t ((besttimeC+timeDelayCFD[pmtBestC])
			 /channelWidth);

    if( besttimeA > 10000. && besttimeA <15000)
      bestATDC=Int_t ((besttimeA+timeDelayCFD[pmtBestA])
			/channelWidth);

    if (bestATDC < 99999 && bestCTDC < 99999)
      {
	timeDiff=Int_t (((besttimeC-besttimeA)+1000*delayVertex)
			/channelWidth);
	meanTime=Int_t (((besttimeC+besttimeA)/2. )/channelWidth);
      }
	AliDebug(10,Form(" time A& C %i %i  time diff && mean time in channels %i %i",bestATDC,bestCTDC, timeDiff, meanTime));

    if (sumMult > threshold){
      fSumMult =  Int_t (1000.* TMath::Log(Double_t(sumMult) / Double_t(sumMultCoeff))
			 /channelWidth);
      AliDebug(10,Form("summult mv %i   mult  in chammens %i in ps %i ",
		      sumMult, fSumMult, fSumMult*channelWidth));
    }

    fT0->AddDigit(bestATDC,bestCTDC,meanTime,timeDiff,fSumMult, refpoint,
		       ftimeCFD,fADC0,ftimeLED,fADC);

      AliDebug(10,Form(" Digits wrote refpoint %i bestATDC %i bestCTDC %i  meanTime %i  timeDiff %i fSumMult %i ",refpoint ,bestATDC,bestCTDC,meanTime,timeDiff,fSumMult ));
    pOutStartLoader->UnloadHits();
  } //input streams loop

    //load digits
    pOutStartLoader->LoadDigits("UPDATE");
    TTree *treeD  = pOutStartLoader->TreeD();
    if (treeD == 0x0) {
      pOutStartLoader->MakeTree("D");
      treeD = pOutStartLoader->TreeD();
    }
    treeD->Reset();
    fT0  = (AliT0*)outRL ->GetAliRun()->GetDetector("T0");
    // Make a branch in the tree
    fT0->MakeBranch("D");
     treeD->Fill();

     pOutStartLoader->WriteDigits("OVERWRITE");

     fT0->ResetDigits();
     pOutStartLoader->UnloadDigits();

}
<commit_msg>fixed redeclare the member data fHits(thanks Andreas)<commit_after>
/**************************************************************************
 * Copyright(c) 1998-2000, 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.                  *
 **************************************************************************/

/* $Id$ */

/******************************************************************
 *    Produde digits from hits
 *       digits is TObject and includes
 *	We are writing array if C & A  TDC
 *	C & A  ADC (will need for slow simulation)
 *	TOF first particle C & A
 *	mean time and time difference (vertex position)
 *
 *      Alla.Maevskaya@cern.ch
 ****************************************************************/

#include <TArrayI.h>
#include <TFile.h>
#include <TGraph.h>
#include <TH1F.h>
#include <TMath.h>
#include <TRandom.h>
#include <TTree.h>

#include "AliLog.h"
#include "AliT0Digitizer.h"
#include "AliT0.h"
#include "AliT0hit.h"
#include "AliT0digit.h"
#include "AliRunDigitizer.h"
#include "AliRun.h"
#include <AliLoader.h>
#include <AliRunLoader.h>
#include <stdlib.h>
#include "AliT0Parameters.h"

ClassImp(AliT0Digitizer)

//___________________________________________
  AliT0Digitizer::AliT0Digitizer()  :AliDigitizer(),
				     fT0(0),
				     fHits(0),
				     fdigits(0),
				     ftimeCFD(new TArrayI(24)),
				     ftimeLED (new TArrayI(24)),
				     fADC(new TArrayI(24)),
				     fADC0 (new TArrayI(24)),
				     fSumMult(0),
				     fAmpLED(0),
				     fParam(0)

{
// Default ctor - don't use it
  ;
}

//___________________________________________
AliT0Digitizer::AliT0Digitizer(AliRunDigitizer* manager)
  :AliDigitizer(manager),
   fT0(0),
   fHits(0),
   fdigits(0),
   ftimeCFD(new TArrayI(24)),
   ftimeLED (new TArrayI(24)),
   fADC(new TArrayI(24)),
   fADC0 (new TArrayI(24)),
   fSumMult(0),
   fAmpLED(0),
   fParam(0)
{
// ctor which should be used

  AliDebug(1,"processed");
  fParam = AliT0Parameters::Instance();
  fParam->Init();
  Int_t index[25000];
  Bool_t down=true;

  for (Int_t i=0; i<24; i++){
    TGraph* gr = fParam ->GetAmpLEDRec(i);
    Int_t np = gr->GetN();
    Double_t *x = gr->GetX();
    Double_t *y = gr->GetY();

    Double_t *x1 = new Double_t[np];
    Double_t *y1 = new Double_t[np];
    for (Int_t ii=0; ii<np; ii++) {
      y1[ii]=y[np-ii-1]; x1[ii]=x[np-ii-1];
    }

    TGraph *grInverse = new TGraph(np,y1,x1);
    fAmpLED.AddAtAndExpand(grInverse,i);

     TGraph* grw = fParam ->GetWalk(i);
      Int_t npw = grw->GetN();
     Double_t *yw = grw->GetY();
    TMath::Sort(npw, yw, index,down);
    fMaxValue[i]=Int_t(yw[index[0]]);
  }

    //    delete [] x1;
    //   delete [] y1;
}

//------------------------------------------------------------------------
AliT0Digitizer::~AliT0Digitizer()
{
// Destructor

  AliDebug(1,"T0");

  delete ftimeCFD;
  delete fADC;
  delete ftimeLED;
  delete  fADC0;
  //  delete fAmpLED;
}

//------------------------------------------------------------------------
Bool_t AliT0Digitizer::Init()
{
// Initialization
  AliDebug(1," Init");
 return kTRUE;
}

//---------------------------------------------------------------------
void AliT0Digitizer::Exec(Option_t* /*option*/)
{

  /*
    Produde digits from hits
        digits is TObject and includes
	We are writing array if C & A  TDC
	C & A  ADC (will need for slow simulation)
	TOF first particle C & A
	mean time and time difference (vertex position)

  */

  //output loader
  AliRunLoader *outRL = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
  AliLoader * pOutStartLoader = outRL->GetLoader("T0Loader");

  AliDebug(1,"start...");
  //input loader
  //
  // From hits to digits
  //
  Int_t hit, nhits;
  Int_t countE[24];
  Int_t volume, pmt, trCFD, trLED;
  Float_t sl, qt;
  Int_t  bestATDC, bestCTDC, qtCh;
  Float_t time[24], besttime[24], timeGaus[24] ;
  //Q->T-> coefficients !!!! should be asked!!!
  Float_t timeDelayCFD[24];
  Int_t threshold =50; //photoelectrons
  Float_t zdetA, zdetC;
  Int_t sumMultCoeff = 100;
  Int_t refpoint=0;

  Int_t ph2Mip = fParam->GetPh2Mip();
  Float_t channelWidth = fParam->GetChannelWidth() ;
  Float_t delayVertex = fParam->GetTimeDelayTVD();

  zdetC = TMath::Abs(fParam->GetZPosition("T0/C/PMT1"));
  zdetA  = TMath::Abs(fParam->GetZPosition("T0/A/PMT15"));

  AliT0hit  *startHit;
  TBranch *brHits=0;

  Int_t nFiles=fManager->GetNinputs();
  for (Int_t inputFile=0; inputFile<nFiles;  inputFile++) {
    if (inputFile < nFiles-1) {
      AliWarning(Form("ignoring input stream %d", inputFile));
      continue;

    }

    Float_t besttimeC=99999.;
    Float_t besttimeA=99999.;
    Int_t pmtBestC=9999;
    Int_t pmtBestA=9999;
    Int_t timeDiff=999, meanTime=0;
    Int_t sumMult =0;   fSumMult=0;
    bestATDC = 99999;  bestCTDC = 99999;

    ftimeCFD -> Reset();
    fADC -> Reset();
    fADC0 -> Reset();
    ftimeLED ->Reset();
    for (Int_t i0=0; i0<24; i0++)
      {
	time[i0]=besttime[i0]=timeGaus[i0]=99999; countE[i0]=0;
      }
    AliRunLoader * inRL = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inputFile));
    AliLoader * pInStartLoader = inRL->GetLoader("T0Loader");
    if (!inRL->GetAliRun()) inRL->LoadgAlice();
    AliT0 *fT0  = (AliT0*)inRL ->GetAliRun()->GetDetector("T0");

       //read Hits
    pInStartLoader->LoadHits("READ");//probably it is necessary to load them before
    fHits = fT0->Hits ();
    TTree *th = pInStartLoader->TreeH();
    brHits = th->GetBranch("T0");
    if (brHits) {
      fT0->SetHitsAddressBranch(brHits);
    }else{
      AliError("Branch T0 hit not found");
      exit(111);
    }
    Int_t ntracks    = (Int_t) th->GetEntries();

    if (ntracks<=0) return;
    // Start loop on tracks in the hits containers
    for (Int_t track=0; track<ntracks;track++) {
      brHits->GetEntry(track);
      nhits = fHits->GetEntriesFast();
      for (hit=0;hit<nhits;hit++)
	{
	  startHit   = (AliT0hit*) fHits->UncheckedAt(hit);
	  if (!startHit) {
 	    AliError("The unchecked hit doesn't exist");
	    break;
	  }
	  pmt=startHit->Pmt();
	  Int_t numpmt=pmt-1;
	  Double_t e=startHit->Etot();
	  volume = startHit->Volume();

	  //	  if(e>0 && RegisterPhotoE(numpmt,e)) {
	  if(e>0 ) {
	    countE[numpmt]++;
	    besttime[numpmt] = startHit->Time();
	    if(besttime[numpmt]<time[numpmt])
	      {
		time[numpmt]=besttime[numpmt];
	      }
	  } //photoelectron accept
	} //hits loop
    } //track loop

    //spread time A&C by 25ps   && besttime
    Float_t c = 0.0299792; // cm/ps

    Float_t koef=(zdetA-zdetC)/c; //correction position difference by cable
    for (Int_t ipmt=0; ipmt<12; ipmt++){
      if(countE[ipmt] > threshold) {
	timeGaus[ipmt]=gRandom->Gaus(time[ipmt],25)+koef;
	if(timeGaus[ipmt]<besttimeC){
	  besttimeC=timeGaus[ipmt]; //timeC
	  pmtBestC=ipmt;}
      }
    }
    for ( Int_t ipmt=12; ipmt<24; ipmt++){
      if(countE[ipmt] > threshold) {
	timeGaus[ipmt]=gRandom->Gaus(time[ipmt],25);
	if(timeGaus[ipmt]<besttimeA) {
	  besttimeA=timeGaus[ipmt]; //timeA
	  pmtBestA=ipmt;}
      }
    }

    timeDelayCFD[0] = fParam->GetTimeDelayCFD(0);

    for (Int_t i=0; i<24; i++)
      {
       	Float_t  al = countE[i];
	if (al>threshold && timeGaus[i]<50000 ) {
	  //fill ADC
	  // QTC procedure:
	  // phe -> mV 0.3; 1MIP ->500phe -> ln (amp (mV)) = 5;
	  // max 200ns, HIJING  mean 50000phe -> 15000mv -> ln = 15 (s zapasom)
	  // channel 25ps
	  qt= 50.*al/ph2Mip;  // 50mv/Mip amp in mV
	  //  fill TDC
	  timeDelayCFD[i] = fParam->GetTimeDelayCFD(i);
 	  trCFD = Int_t (timeGaus[i]/channelWidth + timeDelayCFD[i]);
	  TGraph* gr = ((TGraph*)fAmpLED.At(i));
	  sl = gr->Eval(qt);

	  trLED = Int_t(( timeGaus[i] + 1000*sl )/channelWidth);
	  qtCh=Int_t (1000.*TMath::Log(qt) / channelWidth);
	  fADC0->AddAt(0,i);
	  fADC->AddAt(qtCh,i);
	  ftimeLED->AddAt(trLED,i);
	  //	  sumMult += Int_t ((al*gain[i]/ph2Mip)*50) ;
	  sumMult += Int_t (qt/sumMultCoeff)  ;

	  // put slewing
	  TGraph *fu=(TGraph*) fParam ->GetWalk(i) ;
	  Float_t slew=fu->Eval(Float_t(qtCh));

	  //	  trCFD=trCFD-Int_t(fMaxValue[i]-slew);
	  trCFD = trCFD-Int_t(fMaxValue[i]-slew) + 2000; //for the same channel as cosmic
	  ftimeCFD->AddAt(Int_t (trCFD),i);
	  AliDebug(10,Form("  pmt %i : time in ns %f time in channels %i  LEd %i  ",  i, timeGaus[i],trCFD, trLED ));
	  AliDebug(10,Form(" qt in mV %f qt in ns %f qt in channels %i   ",qt,
			   TMath::Log(qt), qtCh));

	}
      } //pmt loop

    //folding with alignmentz position distribution
    if( besttimeC > 10000. && besttimeC <15000)
      bestCTDC=Int_t ((besttimeC+timeDelayCFD[pmtBestC])
			 /channelWidth);

    if( besttimeA > 10000. && besttimeA <15000)
      bestATDC=Int_t ((besttimeA+timeDelayCFD[pmtBestA])
			/channelWidth);

    if (bestATDC < 99999 && bestCTDC < 99999)
      {
	timeDiff=Int_t (((besttimeC-besttimeA)+1000*delayVertex)
			/channelWidth);
	meanTime=Int_t (((besttimeC+besttimeA)/2. )/channelWidth);
      }
	AliDebug(10,Form(" time A& C %i %i  time diff && mean time in channels %i %i",bestATDC,bestCTDC, timeDiff, meanTime));

    if (sumMult > threshold){
      fSumMult =  Int_t (1000.* TMath::Log(Double_t(sumMult) / Double_t(sumMultCoeff))
			 /channelWidth);
      AliDebug(10,Form("summult mv %i   mult  in chammens %i in ps %i ",
		      sumMult, fSumMult, fSumMult*channelWidth));
    }

    fT0->AddDigit(bestATDC,bestCTDC,meanTime,timeDiff,fSumMult, refpoint,
		       ftimeCFD,fADC0,ftimeLED,fADC);

      AliDebug(10,Form(" Digits wrote refpoint %i bestATDC %i bestCTDC %i  meanTime %i  timeDiff %i fSumMult %i ",refpoint ,bestATDC,bestCTDC,meanTime,timeDiff,fSumMult ));
    pOutStartLoader->UnloadHits();
  } //input streams loop

    //load digits
    pOutStartLoader->LoadDigits("UPDATE");
    TTree *treeD  = pOutStartLoader->TreeD();
    if (treeD == 0x0) {
      pOutStartLoader->MakeTree("D");
      treeD = pOutStartLoader->TreeD();
    }
    treeD->Reset();
    fT0  = (AliT0*)outRL ->GetAliRun()->GetDetector("T0");
    // Make a branch in the tree
    fT0->MakeBranch("D");
     treeD->Fill();

     pOutStartLoader->WriteDigits("OVERWRITE");

     fT0->ResetDigits();
     pOutStartLoader->UnloadDigits();

}
<|endoftext|>


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

#include <map>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/test/test_timeouts.h"
#include "base/test/trace_event_analyzer.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/perf/perf_test.h"
#include "chrome/test/ui/javascript_test_util.h"
#include "chrome/test/ui/ui_perf_test.h"
#include "net/base/net_util.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_switches.h"

namespace {

enum FrameRateTestFlags {
  kUseGpu             = 1 << 0, // Only execute test if --enable-gpu, and verify
                                // that test ran on GPU. This is required for
                                // tests that run on GPU.
  kForceGpuComposited = 1 << 1, // Force the test to use the compositor.
  kDisableVsync       = 1 << 2, // Do not limit framerate to vertical refresh.
                                // when on GPU, nor to 60hz when not on GPU.
  kUseReferenceBuild  = 1 << 3, // Run test using the reference chrome build.
  kInternal           = 1 << 4, // Test uses internal test data.
  kHasRedirect        = 1 << 5, // Test page contains an HTML redirect.
};

class FrameRateTest
  : public UIPerfTest
  , public ::testing::WithParamInterface<int> {
 public:
  FrameRateTest() {
    show_window_ = true;
    dom_automation_enabled_ = true;
  }

  bool HasFlag(FrameRateTestFlags flag) const {
    return (GetParam() & flag) == flag;
  }

  bool IsGpuAvailable() const {
    return CommandLine::ForCurrentProcess()->HasSwitch("enable-gpu");
  }

  std::string GetSuffixForTestFlags() {
    std::string suffix;
    if (HasFlag(kForceGpuComposited))
      suffix += "_comp";
    if (HasFlag(kUseGpu))
      suffix += "_gpu";
    if (HasFlag(kDisableVsync))
      suffix += "_novsync";
    if (HasFlag(kUseReferenceBuild))
      suffix += "_ref";
    return suffix;
  }

  virtual FilePath GetDataPath(const std::string& name) {
    // Make sure the test data is checked out.
    FilePath test_path;
    PathService::Get(chrome::DIR_TEST_DATA, &test_path);
    test_path = test_path.Append(FILE_PATH_LITERAL("perf"));
    test_path = test_path.Append(FILE_PATH_LITERAL("frame_rate"));
    if (HasFlag(kInternal)) {
      test_path = test_path.Append(FILE_PATH_LITERAL("private"));
    } else {
      test_path = test_path.Append(FILE_PATH_LITERAL("content"));
    }
    test_path = test_path.AppendASCII(name);
    return test_path;
  }

  virtual void SetUp() {
    if (HasFlag(kUseReferenceBuild))
      UseReferenceBuild();

    // Turn on chrome.Interval to get higher-resolution timestamps on frames.
    launch_arguments_.AppendSwitch(switches::kEnableBenchmarking);

    // Required additional argument to make the kEnableBenchmarking switch work.
    launch_arguments_.AppendSwitch(switches::kEnableStatsTable);

    // UI tests boot up render views starting from about:blank. This causes
    // the renderer to start up thinking it cannot use the GPU. To work
    // around that, and allow the frame rate test to use the GPU, we must
    // pass kAllowWebUICompositing.
    launch_arguments_.AppendSwitch(switches::kAllowWebUICompositing);

    // Some of the tests may launch http requests through JSON or AJAX
    // which causes a security error (cross domain request) when the page
    // is loaded from the local file system ( file:// ). The following switch
    // fixes that error.
    launch_arguments_.AppendSwitch(switches::kAllowFileAccessFromFiles);

    if (!HasFlag(kUseGpu)) {
      launch_arguments_.AppendSwitch(switches::kDisableAcceleratedCompositing);
      launch_arguments_.AppendSwitch(switches::kDisableExperimentalWebGL);
      launch_arguments_.AppendSwitch(switches::kDisableAccelerated2dCanvas);
    } else {
      // This switch is required for enabling the accelerated 2d canvas on
      // Chrome versions prior to Chrome 15, which may be the case for the
      // reference build.
      launch_arguments_.AppendSwitch(switches::kEnableAccelerated2dCanvas);
    }

    if (HasFlag(kDisableVsync))
      launch_arguments_.AppendSwitch(switches::kDisableGpuVsync);

    UIPerfTest::SetUp();
  }

  bool DidRunOnGpu(const std::string& json_events) {
    using trace_analyzer::Query;
    using trace_analyzer::TraceAnalyzer;

    // Check trace for GPU accleration.
    scoped_ptr<TraceAnalyzer> analyzer(TraceAnalyzer::Create(json_events));

    gfx::GLImplementation gl_impl = gfx::kGLImplementationNone;
    const trace_analyzer::TraceEvent* gpu_event = analyzer->FindOneEvent(
        Query::EventName() == Query::String("SwapBuffers") &&
        Query::EventHasNumberArg("GLImpl"));
    if (gpu_event)
      gl_impl = static_cast<gfx::GLImplementation>(
          gpu_event->GetKnownArgAsInt("GLImpl"));
    return (gl_impl == gfx::kGLImplementationDesktopGL ||
            gl_impl == gfx::kGLImplementationEGLGLES2);
  }

  void RunTest(const std::string& name) {
    if (HasFlag(kUseGpu) && !IsGpuAvailable()) {
      printf("Test skipped: requires gpu. Pass --enable-gpu on the command "
             "line if use of GPU is desired.\n");
      return;
    }

    // Verify flag combinations.
    ASSERT_TRUE(HasFlag(kUseGpu) || !HasFlag(kForceGpuComposited));
    ASSERT_TRUE(!HasFlag(kUseGpu) || IsGpuAvailable());

    FilePath test_path = GetDataPath(name);
    ASSERT_TRUE(file_util::DirectoryExists(test_path))
        << "Missing test directory: " << test_path.value();

    test_path = test_path.Append(FILE_PATH_LITERAL("test.html"));

    scoped_refptr<TabProxy> tab(GetActiveTab());
    ASSERT_TRUE(tab.get());

    // TODO(jbates): remove this check when ref builds are updated.
    if (!HasFlag(kUseReferenceBuild))
      ASSERT_TRUE(automation()->BeginTracing("test_gpu"));

    if (HasFlag(kHasRedirect)) {
      // If the test file is known to contain an html redirect, we must block
      // until the second navigation is complete and reacquire the active tab
      // in order to avoid a race condition.
      // If the following assertion is triggered due to a timeout, it is
      // possible that the current test does not re-direct and therefore should
      // not have the kHasRedirect flag turned on.
      ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS,
        tab->NavigateToURLBlockUntilNavigationsComplete(
        net::FilePathToFileURL(test_path), 2));
      tab = GetActiveTab();
      ASSERT_TRUE(tab.get());
    } else {
      ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS,
        tab->NavigateToURL(net::FilePathToFileURL(test_path)));
    }

    // Block until initialization completes
    // If the following assertion fails intermittently, it could be due to a
    // race condition caused by an html redirect. If that is the case, verify
    // that flag kHasRedirect is enabled for the current test.
    ASSERT_TRUE(WaitUntilJavaScriptCondition(
      tab, L"", L"window.domAutomationController.send(__initialized);",
      TestTimeouts::large_test_timeout_ms()));

    if (HasFlag(kForceGpuComposited)) {
      ASSERT_TRUE(tab->NavigateToURLAsync(
        GURL("javascript:__make_body_composited();")));
    }

    // Start the tests.
    ASSERT_TRUE(tab->NavigateToURLAsync(GURL("javascript:__start_all();")));

    // Block until the tests completes.
    ASSERT_TRUE(WaitUntilJavaScriptCondition(
        tab, L"", L"window.domAutomationController.send(!__running_all);",
        TestTimeouts::large_test_timeout_ms()));

    // TODO(jbates): remove this check when ref builds are updated.
    if (!HasFlag(kUseReferenceBuild)) {
      std::string json_events;
      ASSERT_TRUE(automation()->EndTracing(&json_events));

      bool did_run_on_gpu = DidRunOnGpu(json_events);
      bool expect_gpu = HasFlag(kUseGpu);
      EXPECT_EQ(expect_gpu, did_run_on_gpu);
    }

    // Read out the results.
    std::wstring json;
    ASSERT_TRUE(tab->ExecuteAndExtractString(
        L"",
        L"window.domAutomationController.send("
        L"JSON.stringify(__calc_results_total()));",
        &json));

    std::map<std::string, std::string> results;
    ASSERT_TRUE(JsonDictionaryToMap(WideToUTF8(json), &results));

    ASSERT_TRUE(results.find("mean") != results.end());
    ASSERT_TRUE(results.find("sigma") != results.end());
    ASSERT_TRUE(results.find("gestures") != results.end());
    ASSERT_TRUE(results.find("means") != results.end());
    ASSERT_TRUE(results.find("sigmas") != results.end());

    std::string trace_name = "interval" + GetSuffixForTestFlags();
    printf("GESTURES %s: %s= [%s] [%s] [%s]\n", name.c_str(),
                                                trace_name.c_str(),
                                                results["gestures"].c_str(),
                                                results["means"].c_str(),
                                                results["sigmas"].c_str());

    std::string mean_and_error = results["mean"] + "," + results["sigma"];
    perf_test::PrintResultMeanAndError(name, "", trace_name, mean_and_error,
                                       "milliseconds-per-frame", true);
  }
};

// Must use a different class name to avoid test instantiation conflicts
// with FrameRateTest. An alias is good enough. The alias names must match
// the pattern FrameRate*Test* for them to get picked up by the test bots.
typedef FrameRateTest FrameRateCompositingTest;

// Tests that trigger compositing with a -webkit-translateZ(0)
#define FRAME_RATE_TEST_WITH_AND_WITHOUT_ACCELERATED_COMPOSITING(content) \
TEST_P(FrameRateCompositingTest, content) { \
  RunTest(#content); \
}

INSTANTIATE_TEST_CASE_P(, FrameRateCompositingTest, ::testing::Values(
                        0,
                        kUseGpu | kForceGpuComposited,
                        kUseReferenceBuild,
                        kUseReferenceBuild | kUseGpu | kForceGpuComposited));

FRAME_RATE_TEST_WITH_AND_WITHOUT_ACCELERATED_COMPOSITING(blank);
FRAME_RATE_TEST_WITH_AND_WITHOUT_ACCELERATED_COMPOSITING(googleblog);

typedef FrameRateTest FrameRateNoVsyncCanvasInternalTest;

// Tests for animated 2D canvas content with and without disabling vsync
#define INTERNAL_FRAME_RATE_TEST_CANVAS_WITH_AND_WITHOUT_NOVSYNC(content) \
TEST_P(FrameRateNoVsyncCanvasInternalTest, content) { \
  RunTest(#content); \
}

INSTANTIATE_TEST_CASE_P(, FrameRateNoVsyncCanvasInternalTest, ::testing::Values(
    kInternal | kHasRedirect,
    kInternal | kHasRedirect | kUseGpu,
    kInternal | kHasRedirect | kUseGpu | kDisableVsync,
    kUseReferenceBuild | kInternal | kHasRedirect,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu | kDisableVsync));

INTERNAL_FRAME_RATE_TEST_CANVAS_WITH_AND_WITHOUT_NOVSYNC(fishbowl)

typedef FrameRateTest FrameRateGpuCanvasInternalTest;

// Tests for animated 2D canvas content to be tested only with GPU
// acceleration.
// tests are run with and without Vsync
#define INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(content) \
TEST_P(FrameRateGpuCanvasInternalTest, content) { \
  RunTest(#content); \
}

INSTANTIATE_TEST_CASE_P(, FrameRateGpuCanvasInternalTest, ::testing::Values(
    kInternal | kHasRedirect | kUseGpu,
    kInternal | kHasRedirect | kUseGpu | kDisableVsync,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu | kDisableVsync));

INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(fireflies)
INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(FishIE)
INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(speedreading)

}  // namespace
<commit_msg>Mark speedreading frame-rate tests as FAILS_ on Linux.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <map>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/test/test_timeouts.h"
#include "base/test/trace_event_analyzer.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/perf/perf_test.h"
#include "chrome/test/ui/javascript_test_util.h"
#include "chrome/test/ui/ui_perf_test.h"
#include "net/base/net_util.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_switches.h"

namespace {

enum FrameRateTestFlags {
  kUseGpu             = 1 << 0, // Only execute test if --enable-gpu, and verify
                                // that test ran on GPU. This is required for
                                // tests that run on GPU.
  kForceGpuComposited = 1 << 1, // Force the test to use the compositor.
  kDisableVsync       = 1 << 2, // Do not limit framerate to vertical refresh.
                                // when on GPU, nor to 60hz when not on GPU.
  kUseReferenceBuild  = 1 << 3, // Run test using the reference chrome build.
  kInternal           = 1 << 4, // Test uses internal test data.
  kHasRedirect        = 1 << 5, // Test page contains an HTML redirect.
};

class FrameRateTest
  : public UIPerfTest
  , public ::testing::WithParamInterface<int> {
 public:
  FrameRateTest() {
    show_window_ = true;
    dom_automation_enabled_ = true;
  }

  bool HasFlag(FrameRateTestFlags flag) const {
    return (GetParam() & flag) == flag;
  }

  bool IsGpuAvailable() const {
    return CommandLine::ForCurrentProcess()->HasSwitch("enable-gpu");
  }

  std::string GetSuffixForTestFlags() {
    std::string suffix;
    if (HasFlag(kForceGpuComposited))
      suffix += "_comp";
    if (HasFlag(kUseGpu))
      suffix += "_gpu";
    if (HasFlag(kDisableVsync))
      suffix += "_novsync";
    if (HasFlag(kUseReferenceBuild))
      suffix += "_ref";
    return suffix;
  }

  virtual FilePath GetDataPath(const std::string& name) {
    // Make sure the test data is checked out.
    FilePath test_path;
    PathService::Get(chrome::DIR_TEST_DATA, &test_path);
    test_path = test_path.Append(FILE_PATH_LITERAL("perf"));
    test_path = test_path.Append(FILE_PATH_LITERAL("frame_rate"));
    if (HasFlag(kInternal)) {
      test_path = test_path.Append(FILE_PATH_LITERAL("private"));
    } else {
      test_path = test_path.Append(FILE_PATH_LITERAL("content"));
    }
    test_path = test_path.AppendASCII(name);
    return test_path;
  }

  virtual void SetUp() {
    if (HasFlag(kUseReferenceBuild))
      UseReferenceBuild();

    // Turn on chrome.Interval to get higher-resolution timestamps on frames.
    launch_arguments_.AppendSwitch(switches::kEnableBenchmarking);

    // Required additional argument to make the kEnableBenchmarking switch work.
    launch_arguments_.AppendSwitch(switches::kEnableStatsTable);

    // UI tests boot up render views starting from about:blank. This causes
    // the renderer to start up thinking it cannot use the GPU. To work
    // around that, and allow the frame rate test to use the GPU, we must
    // pass kAllowWebUICompositing.
    launch_arguments_.AppendSwitch(switches::kAllowWebUICompositing);

    // Some of the tests may launch http requests through JSON or AJAX
    // which causes a security error (cross domain request) when the page
    // is loaded from the local file system ( file:// ). The following switch
    // fixes that error.
    launch_arguments_.AppendSwitch(switches::kAllowFileAccessFromFiles);

    if (!HasFlag(kUseGpu)) {
      launch_arguments_.AppendSwitch(switches::kDisableAcceleratedCompositing);
      launch_arguments_.AppendSwitch(switches::kDisableExperimentalWebGL);
      launch_arguments_.AppendSwitch(switches::kDisableAccelerated2dCanvas);
    } else {
      // This switch is required for enabling the accelerated 2d canvas on
      // Chrome versions prior to Chrome 15, which may be the case for the
      // reference build.
      launch_arguments_.AppendSwitch(switches::kEnableAccelerated2dCanvas);
    }

    if (HasFlag(kDisableVsync))
      launch_arguments_.AppendSwitch(switches::kDisableGpuVsync);

    UIPerfTest::SetUp();
  }

  bool DidRunOnGpu(const std::string& json_events) {
    using trace_analyzer::Query;
    using trace_analyzer::TraceAnalyzer;

    // Check trace for GPU accleration.
    scoped_ptr<TraceAnalyzer> analyzer(TraceAnalyzer::Create(json_events));

    gfx::GLImplementation gl_impl = gfx::kGLImplementationNone;
    const trace_analyzer::TraceEvent* gpu_event = analyzer->FindOneEvent(
        Query::EventName() == Query::String("SwapBuffers") &&
        Query::EventHasNumberArg("GLImpl"));
    if (gpu_event)
      gl_impl = static_cast<gfx::GLImplementation>(
          gpu_event->GetKnownArgAsInt("GLImpl"));
    return (gl_impl == gfx::kGLImplementationDesktopGL ||
            gl_impl == gfx::kGLImplementationEGLGLES2);
  }

  void RunTest(const std::string& name) {
    if (HasFlag(kUseGpu) && !IsGpuAvailable()) {
      printf("Test skipped: requires gpu. Pass --enable-gpu on the command "
             "line if use of GPU is desired.\n");
      return;
    }

    // Verify flag combinations.
    ASSERT_TRUE(HasFlag(kUseGpu) || !HasFlag(kForceGpuComposited));
    ASSERT_TRUE(!HasFlag(kUseGpu) || IsGpuAvailable());

    FilePath test_path = GetDataPath(name);
    ASSERT_TRUE(file_util::DirectoryExists(test_path))
        << "Missing test directory: " << test_path.value();

    test_path = test_path.Append(FILE_PATH_LITERAL("test.html"));

    scoped_refptr<TabProxy> tab(GetActiveTab());
    ASSERT_TRUE(tab.get());

    // TODO(jbates): remove this check when ref builds are updated.
    if (!HasFlag(kUseReferenceBuild))
      ASSERT_TRUE(automation()->BeginTracing("test_gpu"));

    if (HasFlag(kHasRedirect)) {
      // If the test file is known to contain an html redirect, we must block
      // until the second navigation is complete and reacquire the active tab
      // in order to avoid a race condition.
      // If the following assertion is triggered due to a timeout, it is
      // possible that the current test does not re-direct and therefore should
      // not have the kHasRedirect flag turned on.
      ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS,
        tab->NavigateToURLBlockUntilNavigationsComplete(
        net::FilePathToFileURL(test_path), 2));
      tab = GetActiveTab();
      ASSERT_TRUE(tab.get());
    } else {
      ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS,
        tab->NavigateToURL(net::FilePathToFileURL(test_path)));
    }

    // Block until initialization completes
    // If the following assertion fails intermittently, it could be due to a
    // race condition caused by an html redirect. If that is the case, verify
    // that flag kHasRedirect is enabled for the current test.
    ASSERT_TRUE(WaitUntilJavaScriptCondition(
      tab, L"", L"window.domAutomationController.send(__initialized);",
      TestTimeouts::large_test_timeout_ms()));

    if (HasFlag(kForceGpuComposited)) {
      ASSERT_TRUE(tab->NavigateToURLAsync(
        GURL("javascript:__make_body_composited();")));
    }

    // Start the tests.
    ASSERT_TRUE(tab->NavigateToURLAsync(GURL("javascript:__start_all();")));

    // Block until the tests completes.
    ASSERT_TRUE(WaitUntilJavaScriptCondition(
        tab, L"", L"window.domAutomationController.send(!__running_all);",
        TestTimeouts::large_test_timeout_ms()));

    // TODO(jbates): remove this check when ref builds are updated.
    if (!HasFlag(kUseReferenceBuild)) {
      std::string json_events;
      ASSERT_TRUE(automation()->EndTracing(&json_events));

      bool did_run_on_gpu = DidRunOnGpu(json_events);
      bool expect_gpu = HasFlag(kUseGpu);
      EXPECT_EQ(expect_gpu, did_run_on_gpu);
    }

    // Read out the results.
    std::wstring json;
    ASSERT_TRUE(tab->ExecuteAndExtractString(
        L"",
        L"window.domAutomationController.send("
        L"JSON.stringify(__calc_results_total()));",
        &json));

    std::map<std::string, std::string> results;
    ASSERT_TRUE(JsonDictionaryToMap(WideToUTF8(json), &results));

    ASSERT_TRUE(results.find("mean") != results.end());
    ASSERT_TRUE(results.find("sigma") != results.end());
    ASSERT_TRUE(results.find("gestures") != results.end());
    ASSERT_TRUE(results.find("means") != results.end());
    ASSERT_TRUE(results.find("sigmas") != results.end());

    std::string trace_name = "interval" + GetSuffixForTestFlags();
    printf("GESTURES %s: %s= [%s] [%s] [%s]\n", name.c_str(),
                                                trace_name.c_str(),
                                                results["gestures"].c_str(),
                                                results["means"].c_str(),
                                                results["sigmas"].c_str());

    std::string mean_and_error = results["mean"] + "," + results["sigma"];
    perf_test::PrintResultMeanAndError(name, "", trace_name, mean_and_error,
                                       "milliseconds-per-frame", true);
  }
};

// Must use a different class name to avoid test instantiation conflicts
// with FrameRateTest. An alias is good enough. The alias names must match
// the pattern FrameRate*Test* for them to get picked up by the test bots.
typedef FrameRateTest FrameRateCompositingTest;

// Tests that trigger compositing with a -webkit-translateZ(0)
#define FRAME_RATE_TEST_WITH_AND_WITHOUT_ACCELERATED_COMPOSITING(content) \
TEST_P(FrameRateCompositingTest, content) { \
  RunTest(#content); \
}

INSTANTIATE_TEST_CASE_P(, FrameRateCompositingTest, ::testing::Values(
                        0,
                        kUseGpu | kForceGpuComposited,
                        kUseReferenceBuild,
                        kUseReferenceBuild | kUseGpu | kForceGpuComposited));

FRAME_RATE_TEST_WITH_AND_WITHOUT_ACCELERATED_COMPOSITING(blank);
FRAME_RATE_TEST_WITH_AND_WITHOUT_ACCELERATED_COMPOSITING(googleblog);

typedef FrameRateTest FrameRateNoVsyncCanvasInternalTest;

// Tests for animated 2D canvas content with and without disabling vsync
#define INTERNAL_FRAME_RATE_TEST_CANVAS_WITH_AND_WITHOUT_NOVSYNC(content) \
TEST_P(FrameRateNoVsyncCanvasInternalTest, content) { \
  RunTest(#content); \
}

INSTANTIATE_TEST_CASE_P(, FrameRateNoVsyncCanvasInternalTest, ::testing::Values(
    kInternal | kHasRedirect,
    kInternal | kHasRedirect | kUseGpu,
    kInternal | kHasRedirect | kUseGpu | kDisableVsync,
    kUseReferenceBuild | kInternal | kHasRedirect,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu | kDisableVsync));

INTERNAL_FRAME_RATE_TEST_CANVAS_WITH_AND_WITHOUT_NOVSYNC(fishbowl)

typedef FrameRateTest FrameRateGpuCanvasInternalTest;

// Tests for animated 2D canvas content to be tested only with GPU
// acceleration.
// tests are run with and without Vsync
#define INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(content) \
TEST_P(FrameRateGpuCanvasInternalTest, content) { \
  RunTest(#content); \
}

INSTANTIATE_TEST_CASE_P(, FrameRateGpuCanvasInternalTest, ::testing::Values(
    kInternal | kHasRedirect | kUseGpu,
    kInternal | kHasRedirect | kUseGpu | kDisableVsync,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu,
    kUseReferenceBuild | kInternal | kHasRedirect | kUseGpu | kDisableVsync));

INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(fireflies)
INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(FishIE)

// crbug.com/115720
#if defined(OS_LINUX)
#define MAYBE_speedreading FAILS_speedreading
#else
#define MAYBE_speedreading speedreading
#endif
INTERNAL_FRAME_RATE_TEST_CANVAS_GPU(MAYBE_speedreading)

}  // namespace
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, 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.                  *
 **************************************************************************/
//...
//  Checks the quality assurance.
//  By comparing with reference data
//  Skeleton for T0
//---------------------------------------------
//checkig without reference data:
//for RAW QA all histograms should have approximatly the same
//number of entries as RefPoint
//for Rec Points checks
//  - amplitude measured by 2 methos
//  - online and offline T0 measurements
// for ESD quality of reconstruction ( and measurements):
// RMS of vertex and T0 less than 75ps
//
// Alla.Maevskaya@cern.ch
//...

// --- ROOT system ---
#include <Riostream.h>
#include <TClass.h>
#include <TH1F.h>
#include <TF1.h>
#include <TFitResultPtr.h>
#include <TH2.h>
#include <TIterator.h>
#include <TKey.h>
#include <TFile.h>
#include <TMath.h>
#include <TString.h>
#include <TPaveText.h>

// --- Standard library ---

// --- AliRoot header files ---
#include "AliLog.h"
#include "AliQAv1.h"
#include "AliQAChecker.h"
#include "AliCDBEntry.h"
#include "AliQAManager.h"
#include "AliT0QAChecker.h"

ClassImp(AliT0QAChecker)
//____________________________________________________________________________
AliT0QAChecker::AliT0QAChecker() :
AliQACheckerBase("T0","T0 Quality Assurance Checker")

{
  // Standard constructor

}

//____________________________________________________________________________
AliT0QAChecker::AliT0QAChecker(const AliT0QAChecker& qac):
  AliQACheckerBase(qac.GetName(), qac.GetTitle())
{
  // copy constructor
  AliError("Copy should not be used with this class\n");
}
//____________________________________________________________________________
AliT0QAChecker& AliT0QAChecker::operator=(const AliT0QAChecker& qac){
  // assignment operator
  this->~AliT0QAChecker();
  new(this)AliT0QAChecker(qac);
  return *this;
}

//____________________________________________________________________________
AliT0QAChecker::~AliT0QAChecker(){
  // destructor

}

//__________________________________________________________________
void AliT0QAChecker::Check(Double_t *  test, AliQAv1::ALITASK_t index, TObjArray ** list, const AliDetectorRecoParam * /*recoParam*/)
{

  // Super-basic check on the QA histograms on the input list:
  // look whether they are empty!

 char * detOCDBDir = Form("T0/%s/%s", AliQAv1::GetRefOCDBDirName(), AliQAv1::GetRefDataDirName()) ;

  AliCDBEntry *QARefRec = AliQAManager::QAManager()->Get(detOCDBDir);
  //  QARefRec->Dump();
  if( !QARefRec){
    AliInfo("QA reference data NOT retrieved for Reconstruction check. No T0 reference distribution");
  }

  for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++)
    test[specie]    = 10.0 ;

  for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
    //  TString dataType = AliQAv1::GetAliTaskName(index);
    if (!(AliQAv1::Instance()->IsEventSpecieSet(specie) && list[specie]) || list[specie]->GetEntries() == 0) {
      test[specie] = 1. ; // nothing to check
      continue;
    }
    if (index == AliQAv1::kRAW && AliRecoParam::ConvertIndex(specie) == AliRecoParam::kCalib)
      //      if (index == AliQAv1::kRAW )
      {
	test[specie] = CheckRaw(list[specie]);
      }
    if (index == AliQAv1::kESD && AliRecoParam::Convert(specie) != AliRecoParam::kCalib)
      test[specie] = CheckESD(list[specie]);
    //
  }
}

//--------------------------------------------------------------------------
Double_t AliT0QAChecker::CheckRaw(TObjArray *listrec) const
{
   Float_t checkr = 0;

  TString hname[10];
   TH1*hdata;
   const char *cname;
   TH1 *fhRawEff[10];
   Int_t nh=0;

   //   Int_t nnn[4] = { 420, 458, 459, 460};
   Int_t nnn[4] = { 169, 207, 208, 209};
   for (Int_t ir=0; ir<4; ir++)
     {
	 hdata = (TH1*) listrec->UncheckedAt(nnn[ir]);
	 if(hdata) {
	   cname = hdata->GetName();
	   hname[ir] = cname;
	   fhRawEff[nh] = hdata;
	   nh++;
	 }
    }

   TLine *linelowyellow = new TLine(0, 0.7, 24, 0.7);
   linelowyellow->SetLineColor(5);
   linelowyellow->SetLineStyle(3);
   linelowyellow->SetLineWidth(4);
   TLine *linelowred = new TLine(0, 0.2, 24, 0.2);
   linelowred->SetLineColor(2);
   linelowred->SetLineStyle(3);
   linelowred->SetLineWidth(4);

   Float_t thryell = 0.7;
   //   TPaveText* text = new TPaveText(0.30,0.50,0.99,0.99,"NDC");
   Float_t thrred = 0.2;
   Float_t chcont =0;
    for (Int_t ih= 0; ih<4; ih++)
     {
       fhRawEff[ih]->SetLineWidth(2);
       fhRawEff[ih]->SetMaximum(2.);
       fhRawEff[ih]->SetMinimum(0.);
       fhRawEff[ih]->GetListOfFunctions()->Add(linelowyellow);
       fhRawEff[ih]->GetListOfFunctions()->Add(linelowred);

       Int_t nbins= fhRawEff[ih]->GetNbinsX();
       Bool_t yell = kFALSE;
       Bool_t red = kFALSE;
       for (Int_t in=1; in<nbins-1; in++)
	 {
	   if(ih==0 && in==5) continue;
	   chcont=fhRawEff[ih]->GetBinContent(in);
	   if (chcont < thryell  ) yell = kTRUE;
	   if (chcont < thrred  ) red = kTRUE;
	 }

       if (! yell && !red) {
	 AliDebug(AliQAv1::GetQADebugLevel(), Form(" efficiency in all channes %s  is good", fhRawEff[ih]->GetName() ));
	 checkr=1.;
	 //	 text->AddText(Form("T0 RUN %d ",AliCDBManager::Instance()->GetRun()));
	 //	 text->AddText(Form(" No problems "));
	 //	 text->SetFillColor(3);
       }

       if(red ) {
	 checkr = 0.;
	 AliDebug(AliQAv1::GetQADebugLevel(), Form(" efficiency in all channes %s  is not so good", fhRawEff[ih]->GetName() ));
	 //	 text->AddText(Form("T0 RUN %d ",AliCDBManager::Instance()->GetRun()));
	 //	 text->AddText(Form("Very serious problem, call expert "));
	 //	 text->SetFillColor(2);
       }

       if ( yell && !red) {
	 AliDebug(AliQAv1::GetQADebugLevel(), Form(" efficiency in all channes %s  is not so good", fhRawEff[ih]->GetName() ));
	 checkr=0.75;
	 //	 text->AddText(Form("T0 RUN %d ",AliCDBManager::Instance()->GetRun()));
	 //	 text->AddText(Form("Some problems "));
	 //	 text->SetFillColor(5);
      }
       // fhRawEff[ih]->GetListOfFunctions()->Add(text);

     }
  return checkr;

}

//--------------------------------------------------------------------------
Double_t AliT0QAChecker::CheckESD(TObjArray *listrec ) const
{
  Float_t checkr = 0;
  TH1 *fhESD;

  fhESD  = (TH1*) listrec->UncheckedAt(2);
  if(fhESD){
    AliDebug(AliQAv1::GetQADebugLevel(), Form("count %s ", fhESD->GetName()) );
     TF1 *f1 = new TF1("f1","gaus",-1,1);
    fhESD->Fit("f1","R","Q", -1,1);
    Double_t par[3];
    f1->GetParameters(&par[0]);

    TPaveText* text = new TPaveText(0.30,0.50,0.99,0.99,"NDC");

    text->AddText(Form("T0 RUN %d ",AliCDBManager::Instance()->GetRun()));

    AliDebug(AliQAv1::GetQADebugLevel(), Form("numentries %d mean %f  #sigma %f", (int)fhESD->GetEntries(),par[1], par[2]));

    if (par[2] > 0.07 && par[2] < 1.) {
      checkr=0.5;
       text->AddText(Form("not good resolution :\n %f ns\n", par[2] ));
       text->SetFillColor(5);
       printf("T0 detector resolution is not good enouph: %f ns\n",par[2] );
    }
    if(TMath::Abs(par[1])>0.05) {
      checkr = 0.5;
      text->AddText(Form(" Check clock shift on %f ns", par[1]));
      text->SetFillColor(5);
    }
    if (par[2] >  1. || TMath::Abs(par[1])>0.1) {
      checkr = 0.25;
      text->AddText(Form(" Bad resolution:\n mean %f ns sigma %f ns", par[1], par[2]));
      text->SetFillColor(2);

      fhESD->GetListOfFunctions()->Add(text);
       AliDebug(AliQAv1::GetQADebugLevel(),
		Form("Please, check calibration: shift= %f resolution %f test=%f\n",
		     par[1], par[2], checkr) ) ;
    }
  }
  else
    {
      AliDebug(AliQAv1::GetQADebugLevel(),
	       Form("No ESD QA histogram found, nothing to check"));
	checkr=0;
    }

  return checkr;
}
<commit_msg>memory leak<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, 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.                  *
 **************************************************************************/
//...
//  Checks the quality assurance.
//  By comparing with reference data
//  Skeleton for T0
//---------------------------------------------
//checkig without reference data:
//for RAW QA all histograms should have approximatly the same
//number of entries as RefPoint
//for Rec Points checks
//  - amplitude measured by 2 methos
//  - online and offline T0 measurements
// for ESD quality of reconstruction ( and measurements):
// RMS of vertex and T0 less than 75ps
//
// Alla.Maevskaya@cern.ch
//...

// --- ROOT system ---
#include <Riostream.h>
#include <TClass.h>
#include <TH1F.h>
#include <TF1.h>
#include <TFitResultPtr.h>
#include <TH2.h>
#include <TIterator.h>
#include <TKey.h>
#include <TFile.h>
#include <TMath.h>
#include <TString.h>
#include <TPaveText.h>

// --- Standard library ---

// --- AliRoot header files ---
#include "AliLog.h"
#include "AliQAv1.h"
#include "AliQAChecker.h"
#include "AliCDBEntry.h"
#include "AliQAManager.h"
#include "AliT0QAChecker.h"

ClassImp(AliT0QAChecker)
//____________________________________________________________________________
AliT0QAChecker::AliT0QAChecker() :
AliQACheckerBase("T0","T0 Quality Assurance Checker")

{
  // Standard constructor

}

//____________________________________________________________________________
AliT0QAChecker::AliT0QAChecker(const AliT0QAChecker& qac):
  AliQACheckerBase(qac.GetName(), qac.GetTitle())
{
  // copy constructor
  AliError("Copy should not be used with this class\n");
}
//____________________________________________________________________________
AliT0QAChecker& AliT0QAChecker::operator=(const AliT0QAChecker& qac){
  // assignment operator
  this->~AliT0QAChecker();
  new(this)AliT0QAChecker(qac);
  return *this;
}

//____________________________________________________________________________
AliT0QAChecker::~AliT0QAChecker(){
  // destructor

}

//__________________________________________________________________
void AliT0QAChecker::Check(Double_t *  test, AliQAv1::ALITASK_t index, TObjArray ** list, const AliDetectorRecoParam * /*recoParam*/)
{

  // Super-basic check on the QA histograms on the input list:
  // look whether they are empty!

 char * detOCDBDir = Form("T0/%s/%s", AliQAv1::GetRefOCDBDirName(), AliQAv1::GetRefDataDirName()) ;

  AliCDBEntry *QARefRec = AliQAManager::QAManager()->Get(detOCDBDir);
  //  QARefRec->Dump();
  if( !QARefRec){
    AliInfo("QA reference data NOT retrieved for Reconstruction check. No T0 reference distribution");
  }

  for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++)
    test[specie]    = 10.0 ;

  for (Int_t specie = 0 ; specie < AliRecoParam::kNSpecies ; specie++) {
    //  TString dataType = AliQAv1::GetAliTaskName(index);
    if (!(AliQAv1::Instance()->IsEventSpecieSet(specie) && list[specie]) || list[specie]->GetEntries() == 0) {
      test[specie] = 1. ; // nothing to check
      continue;
    }
    if (index == AliQAv1::kRAW && AliRecoParam::ConvertIndex(specie) == AliRecoParam::kCalib)
      //      if (index == AliQAv1::kRAW )
      {
	test[specie] = CheckRaw(list[specie]);
      }
    if (index == AliQAv1::kESD && AliRecoParam::Convert(specie) != AliRecoParam::kCalib)
      test[specie] = CheckESD(list[specie]);
    //
  }
}

//--------------------------------------------------------------------------
Double_t AliT0QAChecker::CheckRaw(TObjArray *listrec) const
{
   Float_t checkr = 0;

  TString hname[10];
   TH1*hdata;
   const char *cname;
   TH1 *fhRawEff[10];
   Int_t nh=0;

   //   Int_t nnn[4] = { 420, 458, 459, 460};
   Int_t nnn[4] = { 169, 207, 208, 209};
   for (Int_t ir=0; ir<4; ir++)
     {
	 hdata = (TH1*) listrec->UncheckedAt(nnn[ir]);
	 if(hdata) {
	   cname = hdata->GetName();
	   hname[ir] = cname;
	   fhRawEff[nh] = hdata;
	   nh++;
	 }
    }

   TLine *linelowyellow = new TLine(0, 0.7, 24, 0.7);
   linelowyellow->SetLineColor(5);
   linelowyellow->SetLineStyle(3);
   linelowyellow->SetLineWidth(4);
   TLine *linelowred = new TLine(0, 0.2, 24, 0.2);
   linelowred->SetLineColor(2);
   linelowred->SetLineStyle(3);
   linelowred->SetLineWidth(4);

   Float_t thryell = 0.7;
   //   TPaveText* text = new TPaveText(0.30,0.50,0.99,0.99,"NDC");
   Float_t thrred = 0.2;
   Float_t chcont =0;
    for (Int_t ih= 0; ih<4; ih++)
     {
       fhRawEff[ih]->SetLineWidth(2);
       fhRawEff[ih]->SetMaximum(2.);
       fhRawEff[ih]->SetMinimum(0.);
       fhRawEff[ih]->GetListOfFunctions()->Add(linelowyellow);
       fhRawEff[ih]->GetListOfFunctions()->Add(linelowred);

       Int_t nbins= fhRawEff[ih]->GetNbinsX();
       Bool_t yell = kFALSE;
       Bool_t red = kFALSE;
       for (Int_t in=1; in<nbins-1; in++)
	 {
	   if(ih==0 && in==5) continue;
	   chcont=fhRawEff[ih]->GetBinContent(in);
	   if (chcont < thryell  ) yell = kTRUE;
	   if (chcont < thrred  ) red = kTRUE;
	 }

       if (! yell && !red) {
	 AliDebug(AliQAv1::GetQADebugLevel(), Form(" efficiency in all channes %s  is good", fhRawEff[ih]->GetName() ));
	 checkr=1.;
	 //	 text->AddText(Form("T0 RUN %d ",AliCDBManager::Instance()->GetRun()));
	 //	 text->AddText(Form(" No problems "));
	 //	 text->SetFillColor(3);
       }

       if(red ) {
	 checkr = 0.;
	 AliDebug(AliQAv1::GetQADebugLevel(), Form(" efficiency in all channes %s  is not so good", fhRawEff[ih]->GetName() ));
	 //	 text->AddText(Form("T0 RUN %d ",AliCDBManager::Instance()->GetRun()));
	 //	 text->AddText(Form("Very serious problem, call expert "));
	 //	 text->SetFillColor(2);
       }

       if ( yell && !red) {
	 AliDebug(AliQAv1::GetQADebugLevel(), Form(" efficiency in all channes %s  is not so good", fhRawEff[ih]->GetName() ));
	 checkr=0.75;
	 //	 text->AddText(Form("T0 RUN %d ",AliCDBManager::Instance()->GetRun()));
	 //	 text->AddText(Form("Some problems "));
	 //	 text->SetFillColor(5);
      }
       // fhRawEff[ih]->GetListOfFunctions()->Add(text);

     }
    delete linelowyellow;
    delete linelowred;
    return checkr;

}

//--------------------------------------------------------------------------
Double_t AliT0QAChecker::CheckESD(TObjArray *listrec ) const
{
  Float_t checkr = 0;
  TH1 *fhESD;

  fhESD  = (TH1*) listrec->UncheckedAt(2);
  if(fhESD){
    AliDebug(AliQAv1::GetQADebugLevel(), Form("count %s ", fhESD->GetName()) );
     TF1 *f1 = new TF1("f1","gaus",-1,1);
    fhESD->Fit("f1","R","Q", -1,1);
    Double_t par[3];
    f1->GetParameters(&par[0]);

    TPaveText* text = new TPaveText(0.30,0.50,0.99,0.99,"NDC");

    text->AddText(Form("T0 RUN %d ",AliCDBManager::Instance()->GetRun()));

    AliDebug(AliQAv1::GetQADebugLevel(), Form("numentries %d mean %f  #sigma %f", (int)fhESD->GetEntries(),par[1], par[2]));

    if (par[2] > 0.07 && par[2] < 1.) {
      checkr=0.5;
       text->AddText(Form("not good resolution :\n %f ns\n", par[2] ));
       text->SetFillColor(5);
       printf("T0 detector resolution is not good enouph: %f ns\n",par[2] );
    }
    if(TMath::Abs(par[1])>0.05) {
      checkr = 0.5;
      text->AddText(Form(" Check clock shift on %f ns", par[1]));
      text->SetFillColor(5);
    }
    if (par[2] >  1. || TMath::Abs(par[1])>0.1) {
      checkr = 0.25;
      text->AddText(Form(" Bad resolution:\n mean %f ns sigma %f ns", par[1], par[2]));
      text->SetFillColor(2);

      fhESD->GetListOfFunctions()->Add(text);
       AliDebug(AliQAv1::GetQADebugLevel(),
		Form("Please, check calibration: shift= %f resolution %f test=%f\n",
		     par[1], par[2], checkr) ) ;
    }
  }
  else
    {
      AliDebug(AliQAv1::GetQADebugLevel(),
	       Form("No ESD QA histogram found, nothing to check"));
	checkr=0;
    }

  return checkr;
}
<|endoftext|>