<commit_before>///A simple SAM viewer. Convert a SAM alignment file into a SVG vector graphic.
#include <fstream>
#include <iostream>
#include <string>

#include <seqan/store.h>
#include <seqan/misc/misc_cmdparser.h>
#include <seqan/misc/misc_svg.h>

using namespace seqan;

int main(int argc, const char *argv[])
{
	typedef FragmentStore<> TFragStore;
	typedef TFragStore::TContigPos TContigPos;

	//////////////////////////////////////////////////////////////////////////////
	// Define options
	CommandLineParser parser;
	addUsageLine(parser, "[OPTION]... <SAM file> <SVG file>");
	addUsageLine(parser, "[OPTION]... <SAM file> <GENOME file> <SVG file>");

	addOption(parser, CommandLineOption("c",  "contig",    "display only contig #NUM (default: show all contigs)", OptionType::Int | OptionType::Label | OptionType::List));
	addOption(parser, CommandLineOption("p",  "pos",    2, "set begin and end position (default: show whole strands)", OptionType::Int | OptionType::Label));
	addOption(parser, CommandLineOption("l",  "lines",  2, "set first and last line of the alignment (default: show whole alignment)", OptionType::Int | OptionType::Label));
	addOption(parser, CommandLineOption("a",  "ascii",     "output alignment in ASCII format instead of SVG", OptionType::Bool | OptionType::Label));
	requiredArguments(parser, 2);

	bool stop = !parse(parser, argc, argv, std::cerr);
	if (stop) return 0;

	//////////////////////////////////////////////////////////////////////////////
	// Extract and check options
	String<unsigned> contigs;
	TContigPos left = 0;
	TContigPos right = SupremumValue<TContigPos>::VALUE;
	unsigned firstLine = 0;
	unsigned lastLine = SupremumValue<unsigned>::VALUE;
	bool inASCII = false;

	if (isSetLong(parser, "pos"))
	{
		__int64 l = 0, r = 0;
		getOptionValueLong(parser, "pos", 0, l);
		getOptionValueLong(parser, "pos", 1, r);
		if ((l >= r) && (stop = true))
			std::cerr << "Begin position must be less than end position." << std::endl;
		left = l;
		right = r;
	}

	if (isSetLong(parser, "lines"))
	{
		getOptionValueLong(parser, "lines", 0, firstLine);
		getOptionValueLong(parser, "lines", 1, lastLine);
		if ((firstLine >= lastLine) && (stop = true))
			std::cerr << "First line must be less or equal than last line." << std::endl;
	}

	TFragStore store;
	std::ifstream samFile(toCString(getArgumentValue(parser, 0)), std::ios_base::in | std::ios_base::binary);
	std::ofstream ascii;
	SVGFile svg;

	//////////////////////////////////////////////////////////////////////////////
	// Optionally load genome file
	uint outArgNo = 1;
	if (argumentCount(parser) > 2)
	{
		if (!loadContigs(store, getArgumentValue(parser, 1)) && (stop = true))
			std::cerr << "Failed to load genome." << std::endl;
		++outArgNo;
	}

	//////////////////////////////////////////////////////////////////////////////
	// Load SAM file
	if (!stop) read(samFile, store, SAM());

	//////////////////////////////////////////////////////////////////////////////
	// Choose contigs
	if (isSetLong(parser, "contig"))
	{
		resize(contigs, length(getOptionValuesLong(parser, "contig")));
		for (unsigned i = 0; i < length(contigs); ++i)
			getOptionValueLong(parser, "contig", i, contigs[i]);
	} else {
		resize(contigs, length(store.contigStore));
		for (unsigned i = 0; i < length(contigs); ++i)
			contigs[i] = i;
	}

	if (isSetLong(parser, "ascii"))
		inASCII = true;

	//////////////////////////////////////////////////////////////////////////////
	// Optionally load genome and open SVG file for writing
	if (!stop)
	{
		if (inASCII)
		{
			ascii.open(toCString(getArgumentValue(parser, outArgNo)), std::ios_base::out | std::ios_base::trunc);
			if (!ascii.is_open()) stop = true;
		} else
			if (!open(svg, toCString(getArgumentValue(parser, outArgNo)))) stop = true;

		if (stop) std::cerr << "Failed to open output file for writing." << std::endl;
	}

	// something went wrong
	if (stop)
	{
		std::cerr << "Exiting ..." << std::endl;
		return 1;
	}

	for(unsigned o=0;o<length(store.contigStore);++o)
	std::cerr<<store.contigNameStore[o]<<std::endl;

	//////////////////////////////////////////////////////////////////////////////
	// Output alignment
	AlignedReadLayout layout;
	std::cout << "Layouting reads ... " << std::flush;
	layoutAlignment(layout, store);
	std::cout << "done" << std::endl;

	for (unsigned i = 0; i < length(contigs); ++i)
		if (i < length(store.contigStore))
		{
			std::cout << "Writing contig " << contigs[i] << " ... " << std::flush;
			TContigPos right_ = right;
			if (right_ == SupremumValue<TContigPos>::VALUE)
			{
				right_ = 0;
				for (unsigned j = 0; j < length(layout.contigRows[i]); ++j)
				{
					unsigned id = back(layout.contigRows[i][j]);
					if (right_ < store.alignedReadStore[id].beginPos)
						right_ = store.alignedReadStore[id].beginPos;
					if (right_ < store.alignedReadStore[id].endPos)
						right_ = store.alignedReadStore[id].endPos;
				}
			}
			std::cout << left<<'\t'<<right_<<'\t'<<firstLine<<'\t'<<lastLine<<std::endl;
			if (inASCII)
				printAlignment(ascii, Raw(), layout, store, contigs[i], left, right_, firstLine, lastLine);
			else
				printAlignment(svg, Raw(), layout, store, contigs[i], left, right_, firstLine, lastLine);

			std::cout << "done" << std::endl;
		}

	return 0;
}
<commit_msg>fixed compilation bug<commit_after>///A simple SAM viewer. Convert a SAM alignment file into a SVG vector graphic.
#include <fstream>
#include <iostream>
#include <string>

#include <seqan/store.h>
#include <seqan/misc/misc_cmdparser.h>
#include <seqan/misc/misc_svg.h>

using namespace seqan;

int main(int argc, const char *argv[])
{
	typedef FragmentStore<> TFragStore;
	typedef TFragStore::TContigPos TContigPos;

	//////////////////////////////////////////////////////////////////////////////
	// Define options
	CommandLineParser parser;
	addUsageLine(parser, "[OPTION]... <SAM file> <SVG file>");
	addUsageLine(parser, "[OPTION]... <SAM file> <GENOME file> <SVG file>");

	addOption(parser, CommandLineOption("c",  "contig",    "display only contig #NUM (default: show all contigs)", OptionType::Int | OptionType::Label | OptionType::List));
	addOption(parser, CommandLineOption("p",  "pos",    2, "set begin and end position (default: show whole strands)", OptionType::Int | OptionType::Label));
	addOption(parser, CommandLineOption("l",  "lines",  2, "set first and last line of the alignment (default: show whole alignment)", OptionType::Int | OptionType::Label));
	addOption(parser, CommandLineOption("a",  "ascii",     "output alignment in ASCII format instead of SVG", OptionType::Bool | OptionType::Label));
	requiredArguments(parser, 2);

	bool stop = !parse(parser, argc, argv, std::cerr);
	if (stop) return 0;

	//////////////////////////////////////////////////////////////////////////////
	// Extract and check options
	String<unsigned> contigs;
	TContigPos left = 0;
	TContigPos right = SupremumValue<TContigPos>::VALUE;
	unsigned firstLine = 0;
	unsigned lastLine = SupremumValue<unsigned>::VALUE;
	bool inASCII = false;

	if (isSetLong(parser, "pos"))
	{
		__int64 l = 0, r = 0;
		getOptionValueLong(parser, "pos", 0, l);
		getOptionValueLong(parser, "pos", 1, r);
		if ((l >= r) && (stop = true))
			std::cerr << "Begin position must be less than end position." << std::endl;
		left = l;
		right = r;
	}

	if (isSetLong(parser, "lines"))
	{
		getOptionValueLong(parser, "lines", 0, firstLine);
		getOptionValueLong(parser, "lines", 1, lastLine);
		if ((firstLine >= lastLine) && (stop = true))
			std::cerr << "First line must be less or equal than last line." << std::endl;
	}

	TFragStore store;
	std::ifstream samFile(toCString(getArgumentValue(parser, 0)), std::ios_base::in | std::ios_base::binary);
	std::ofstream ascii;
	SVGFile svg;

	//////////////////////////////////////////////////////////////////////////////
	// Optionally load genome file
	unsigned outArgNo = 1;
	if (argumentCount(parser) > 2)
	{
		if (!loadContigs(store, getArgumentValue(parser, 1)) && (stop = true))
			std::cerr << "Failed to load genome." << std::endl;
		++outArgNo;
	}

	//////////////////////////////////////////////////////////////////////////////
	// Load SAM file
	if (!stop) read(samFile, store, SAM());

	//////////////////////////////////////////////////////////////////////////////
	// Choose contigs
	if (isSetLong(parser, "contig"))
	{
		resize(contigs, length(getOptionValuesLong(parser, "contig")));
		for (unsigned i = 0; i < length(contigs); ++i)
			getOptionValueLong(parser, "contig", i, contigs[i]);
	} else {
		resize(contigs, length(store.contigStore));
		for (unsigned i = 0; i < length(contigs); ++i)
			contigs[i] = i;
	}

	if (isSetLong(parser, "ascii"))
		inASCII = true;

	//////////////////////////////////////////////////////////////////////////////
	// Optionally load genome and open SVG file for writing
	if (!stop)
	{
		if (inASCII)
		{
			ascii.open(toCString(getArgumentValue(parser, outArgNo)), std::ios_base::out | std::ios_base::trunc);
			if (!ascii.is_open()) stop = true;
		} else
			if (!open(svg, toCString(getArgumentValue(parser, outArgNo)))) stop = true;

		if (stop) std::cerr << "Failed to open output file for writing." << std::endl;
	}

	// something went wrong
	if (stop)
	{
		std::cerr << "Exiting ..." << std::endl;
		return 1;
	}

	for(unsigned o=0;o<length(store.contigStore);++o)
	std::cerr<<store.contigNameStore[o]<<std::endl;

	//////////////////////////////////////////////////////////////////////////////
	// Output alignment
	AlignedReadLayout layout;
	std::cout << "Layouting reads ... " << std::flush;
	layoutAlignment(layout, store);
	std::cout << "done" << std::endl;

	for (unsigned i = 0; i < length(contigs); ++i)
		if (i < length(store.contigStore))
		{
			std::cout << "Writing contig " << contigs[i] << " ... " << std::flush;
			TContigPos right_ = right;
			if (right_ == SupremumValue<TContigPos>::VALUE)
			{
				right_ = 0;
				for (unsigned j = 0; j < length(layout.contigRows[i]); ++j)
				{
					unsigned id = back(layout.contigRows[i][j]);
					if (right_ < store.alignedReadStore[id].beginPos)
						right_ = store.alignedReadStore[id].beginPos;
					if (right_ < store.alignedReadStore[id].endPos)
						right_ = store.alignedReadStore[id].endPos;
				}
			}
			std::cout << left<<'\t'<<right_<<'\t'<<firstLine<<'\t'<<lastLine<<std::endl;
			if (inASCII)
				printAlignment(ascii, Raw(), layout, store, contigs[i], left, right_, firstLine, lastLine);
			else
				printAlignment(svg, Raw(), layout, store, contigs[i], left, right_, firstLine, lastLine);

			std::cout << "done" << std::endl;
		}

	return 0;
}
<|endoftext|>


<commit_before>/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * OlaServer.cpp
 * OlaServer is the main OLA Server class
 * Copyright (C) 2005-2008 Simon Newton
 */

#if HAVE_CONFIG_H
#  include <config.h>
#endif

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <map>
#include <vector>

#include "ola/network/Socket.h"
#include "common/protocol/Ola.pb.h"
#include "common/rpc/StreamRpcChannel.h"
#include "ola/BaseTypes.h"
#include "ola/ExportMap.h"
#include "ola/Logging.h"
#include "ola/network/InterfacePicker.h"
#include "ola/rdm/UID.h"
#include "olad/Client.h"
#include "olad/DeviceManager.h"
#include "olad/ClientBroker.h"
#include "olad/OlaServer.h"
#include "olad/OlaServerServiceImpl.h"
#include "olad/Plugin.h"
#include "olad/PluginAdaptor.h"
#include "olad/PluginManager.h"
#include "olad/Port.h"
#include "olad/PortBroker.h"
#include "olad/PortManager.h"
#include "olad/Preferences.h"
#include "olad/Universe.h"
#include "olad/UniverseStore.h"

#ifdef HAVE_LIBMICROHTTPD
#include "olad/OlaHttpServer.h"
#endif

namespace ola {

using ola::rpc::StreamRpcChannel;
using std::pair;

const char OlaServer::UNIVERSE_PREFERENCES[] = "universe";
const char OlaServer::K_CLIENT_VAR[] = "clients-connected";
const char OlaServer::K_UID_VAR[] = "server-uid";
const unsigned int OlaServer::K_HOUSEKEEPING_TIMEOUT_MS = 10000;

/*
 * Create a new OlaServer
 * @param factory the factory to use to create OlaService objects
 * @param m_plugin_loader the loader to use for the plugins
 * @param socket the socket to listen on for new connections
 */
OlaServer::OlaServer(OlaClientServiceFactory *factory,
                     const vector<PluginLoader*> &plugin_loaders,
                     PreferencesFactory *preferences_factory,
                     ola::network::SelectServer *select_server,
                     ola_server_options *ola_options,
                     ola::network::AcceptingSocket *socket,
                     ExportMap *export_map)
    : m_service_factory(factory),
      m_plugin_loaders(plugin_loaders),
      m_ss(select_server),
      m_accepting_socket(socket),
      m_device_manager(NULL),
      m_plugin_manager(NULL),
      m_plugin_adaptor(NULL),
      m_preferences_factory(preferences_factory),
      m_universe_preferences(NULL),
      m_universe_store(NULL),
      m_export_map(export_map),
      m_port_manager(NULL),
      m_service_impl(NULL),
      m_broker(NULL),
      m_port_broker(NULL),
      m_reload_plugins(false),
      m_init_run(false),
      m_free_export_map(false),
      m_housekeeping_timeout(ola::network::INVALID_TIMEOUT),
      m_httpd(NULL),
      m_options(*ola_options),
      m_default_uid(OPEN_LIGHTING_ESTA_CODE, 0) {
  if (!m_export_map) {
    m_export_map = new ExportMap();
    m_free_export_map = true;
  }

  if (!m_options.http_port)
    m_options.http_port = DEFAULT_HTTP_PORT;

  m_export_map->GetIntegerVar(K_CLIENT_VAR);
}

/*
 * Shutdown the server
 */
OlaServer::~OlaServer() {
#ifdef HAVE_LIBMICROHTTPD
  if (m_httpd) {
    m_httpd->Stop();
    delete m_httpd;
    m_httpd = NULL;
  }
#endif

  if (m_housekeeping_timeout != ola::network::INVALID_TIMEOUT)
    m_ss->RemoveTimeout(m_housekeeping_timeout);

  StopPlugins();

  map<int, OlaClientService*>::iterator iter;
  for (iter = m_sd_to_service.begin(); iter != m_sd_to_service.end(); ++iter) {
    CleanupConnection(iter->second);
    // TODO(simon): close the socket here

    /*Socket *socket = ;
    m_ss->RemoveReadDescriptor(socket);
    socket->Close();
    */
  }

  if (m_broker)
    delete m_broker;

  if (m_port_broker)
    delete m_port_broker;

  if (m_accepting_socket &&
      m_accepting_socket->ValidReadDescriptor())
    m_ss->RemoveReadDescriptor(m_accepting_socket);

  if (m_universe_store) {
    m_universe_store->DeleteAll();
    delete m_universe_store;
  }

  if (m_universe_preferences) {
    m_universe_preferences->Save();
  }

  delete m_port_manager;
  delete m_plugin_adaptor;
  delete m_device_manager;
  delete m_plugin_manager;
  delete m_service_impl;

  if (m_free_export_map)
    delete m_export_map;
}

/*
 * Initialise the server
 * * @return true on success, false on failure
 */
bool OlaServer::Init() {
  if (m_init_run)
    return false;

  if (!m_service_factory || !m_ss)
    return false;

  // TODO(simon): run without preferences & PluginLoader
  if (m_plugin_loaders.empty() || !m_preferences_factory)
    return false;

  if (m_accepting_socket) {
    if (!m_accepting_socket->Listen()) {
      OLA_FATAL << "Could not listen on the RPC port, you probably have " <<
        "another instance of olad running";
      return false;
    }
    m_accepting_socket->SetOnAccept(
      ola::NewCallback(this, &OlaServer::NewConnection));
    m_ss->AddReadDescriptor(m_accepting_socket);
  }

#ifndef WIN32
  signal(SIGPIPE, SIG_IGN);
#endif

  // fetch the interface info
  ola::network::Interface iface;
  ola::network::InterfacePicker *picker =
    ola::network::InterfacePicker::NewPicker();
  if (!picker->ChooseInterface(&iface, "")) {
    OLA_WARN << "No network interface found";
  } else {
    // default to using the ip as a id
    m_default_uid = ola::rdm::UID(OPEN_LIGHTING_ESTA_CODE,
                                  iface.ip_address.AsInt());
  }
  delete picker;
  m_export_map->GetStringVar(K_UID_VAR)->Set(m_default_uid.ToString());
  OLA_INFO << "Server UID is " << m_default_uid;

  m_universe_preferences = m_preferences_factory->NewPreference(
      UNIVERSE_PREFERENCES);
  m_universe_preferences->Load();
  m_universe_store = new UniverseStore(m_universe_preferences, m_export_map);

  m_port_broker = new PortBroker();
  m_port_manager = new PortManager(m_universe_store, m_port_broker);
  m_broker = new ClientBroker();

  // setup the objects
  m_device_manager = new DeviceManager(m_preferences_factory, m_port_manager);
  m_plugin_adaptor = new PluginAdaptor(m_device_manager,
                                       m_ss,
                                       m_preferences_factory,
                                       m_port_broker);

  m_plugin_manager = new PluginManager(m_plugin_loaders, m_plugin_adaptor);
  m_service_impl = new OlaServerServiceImpl(
      m_universe_store,
      m_device_manager,
      m_plugin_manager,
      m_export_map,
      m_port_manager,
      m_broker,
      m_ss->WakeUpTime(),
      m_default_uid);

  if (!m_port_broker || !m_universe_store || !m_device_manager ||
      !m_plugin_adaptor || !m_port_manager || !m_plugin_manager || !m_broker ||
      !m_service_impl) {
    delete m_plugin_adaptor;
    delete m_device_manager;
    delete m_port_manager;
    delete m_universe_store;
    delete m_plugin_manager;
    return false;
  }

  m_plugin_manager->LoadAll();

#ifdef HAVE_LIBMICROHTTPD
  if (!StartHttpServer(iface))
    OLA_WARN << "Failed to start the HTTP server.";
#endif

  m_housekeeping_timeout = m_ss->RegisterRepeatingTimeout(
      K_HOUSEKEEPING_TIMEOUT_MS,
      ola::NewCallback(this, &OlaServer::RunHousekeeping));
  m_ss->RunInLoop(ola::NewCallback(this, &OlaServer::CheckForReload));

  m_init_run = true;
  return true;
}

/*
 * Reload all plugins, this can be called from a separate thread or in an
 * interrupt handler.
 */
void OlaServer::ReloadPlugins() {
  m_reload_plugins = true;
}

/*
 * Add a new ConnectedDescriptor to this Server.
 * @param socket the new ConnectedDescriptor
 */
void OlaServer::NewConnection(ola::network::ConnectedDescriptor *socket) {
  if (!socket)
    return;

  StreamRpcChannel *channel = new StreamRpcChannel(NULL, socket, m_export_map);
  socket->SetOnClose(NewSingleCallback(this, &OlaServer::SocketClosed, socket));
  OlaClientService_Stub *stub = new OlaClientService_Stub(channel);
  Client *client = new Client(stub);
  OlaClientService *service = m_service_factory->New(client, m_service_impl);
  m_broker->AddClient(client);
  channel->SetService(service);

  map<int, OlaClientService*>::const_iterator iter;
  iter = m_sd_to_service.find(socket->ReadDescriptor());

  if (iter != m_sd_to_service.end())
    OLA_INFO << "New socket but the client already exists!";

  pair<int, OlaClientService*> pair(socket->ReadDescriptor(), service);
  m_sd_to_service.insert(pair);

  // This hands off ownership to the select server
  m_ss->AddReadDescriptor(socket, true);
  (*m_export_map->GetIntegerVar(K_CLIENT_VAR))++;
}

/*
 * Called when a socket is closed
 */
void OlaServer::SocketClosed(ola::network::ConnectedDescriptor *socket) {
  map<int, OlaClientService*>::iterator iter;
  iter = m_sd_to_service.find(socket->ReadDescriptor());

  if (iter == m_sd_to_service.end())
    OLA_INFO << "A socket was closed but we didn't find the client";

  (*m_export_map->GetIntegerVar(K_CLIENT_VAR))--;
  CleanupConnection(iter->second);
  m_sd_to_service.erase(iter);
}

/*
 * Run the garbage collector
 */
bool OlaServer::RunHousekeeping() {
  OLA_DEBUG << "Garbage collecting";
  m_universe_store->GarbageCollectUniverses();
  return true;
}

/*
 * Called once per loop iteration
 */
void OlaServer::CheckForReload() {
  if (m_reload_plugins) {
    m_reload_plugins = false;
    OLA_INFO << "Reloading plugins";
    StopPlugins();
    m_plugin_manager->LoadAll();
  }
}

/*
 * Setup the HTTP server if required.
 * @param interface the primary interface that the server is using.
 */
#ifdef HAVE_LIBMICROHTTPD
bool OlaServer::StartHttpServer(const ola::network::Interface &iface) {
  if (!m_options.http_enable)
    return true;

  // create a pipe socket for the http server to communicate with the main
  // server on.
  ola::network::PipeDescriptor *pipe_descriptor =
    new ola::network::PipeDescriptor();
  if (!pipe_descriptor->Init()) {
    delete pipe_descriptor;
    return false;
  }

  // ownership of the pipe_descriptor is transferred here.
  m_httpd = new OlaHttpServer(m_export_map,
                              pipe_descriptor->OppositeEnd(),
                              this,
                              m_options.http_port,
                              m_options.http_enable_quit,
                              m_options.http_data_dir,
                              iface);

  if (m_httpd->Init()) {
    m_httpd->Start();
    // register the pipe descriptor as a client
    NewConnection(pipe_descriptor);
    return true;
  } else {
    pipe_descriptor->Close();
    delete pipe_descriptor;
    delete m_httpd;
    m_httpd = NULL;
    return false;
  }
}
#endif

/*
 * Stop and unload all the plugins
 */
void OlaServer::StopPlugins() {
  if (m_plugin_manager)
    m_plugin_manager->UnloadAll();
  if (m_device_manager) {
    if (m_device_manager->DeviceCount()) {
      OLA_WARN << "Some devices failed to unload, we're probably leaking "
        << "memory now";
    }
    m_device_manager->UnregisterAllDevices();
  }
}

/*
 * Cleanup everything related to a client connection
 */
void OlaServer::CleanupConnection(OlaClientService *service) {
  Client *client = service->GetClient();
  m_broker->RemoveClient(client);

  vector<Universe*> universe_list;
  m_universe_store->GetList(&universe_list);
  vector<Universe*>::iterator uni_iter;

  // O(universes * clients). Clean this up sometime.
  for (uni_iter = universe_list.begin();
       uni_iter != universe_list.end();
       ++uni_iter) {
    (*uni_iter)->RemoveSourceClient(client);
    (*uni_iter)->RemoveSinkClient(client);
  }
  delete client->Stub()->channel();
  delete client->Stub();
  delete client;
  delete service;
}
}  // ola
<commit_msg> * server: load plugins in the main loop<commit_after>/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * OlaServer.cpp
 * OlaServer is the main OLA Server class
 * Copyright (C) 2005-2008 Simon Newton
 */

#if HAVE_CONFIG_H
#  include <config.h>
#endif

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <map>
#include <vector>

#include "ola/network/Socket.h"
#include "common/protocol/Ola.pb.h"
#include "common/rpc/StreamRpcChannel.h"
#include "ola/BaseTypes.h"
#include "ola/ExportMap.h"
#include "ola/Logging.h"
#include "ola/network/InterfacePicker.h"
#include "ola/rdm/UID.h"
#include "olad/Client.h"
#include "olad/DeviceManager.h"
#include "olad/ClientBroker.h"
#include "olad/OlaServer.h"
#include "olad/OlaServerServiceImpl.h"
#include "olad/Plugin.h"
#include "olad/PluginAdaptor.h"
#include "olad/PluginManager.h"
#include "olad/Port.h"
#include "olad/PortBroker.h"
#include "olad/PortManager.h"
#include "olad/Preferences.h"
#include "olad/Universe.h"
#include "olad/UniverseStore.h"

#ifdef HAVE_LIBMICROHTTPD
#include "olad/OlaHttpServer.h"
#endif

namespace ola {

using ola::rpc::StreamRpcChannel;
using std::pair;

const char OlaServer::UNIVERSE_PREFERENCES[] = "universe";
const char OlaServer::K_CLIENT_VAR[] = "clients-connected";
const char OlaServer::K_UID_VAR[] = "server-uid";
const unsigned int OlaServer::K_HOUSEKEEPING_TIMEOUT_MS = 10000;

/*
 * Create a new OlaServer
 * @param factory the factory to use to create OlaService objects
 * @param m_plugin_loader the loader to use for the plugins
 * @param socket the socket to listen on for new connections
 */
OlaServer::OlaServer(OlaClientServiceFactory *factory,
                     const vector<PluginLoader*> &plugin_loaders,
                     PreferencesFactory *preferences_factory,
                     ola::network::SelectServer *select_server,
                     ola_server_options *ola_options,
                     ola::network::AcceptingSocket *socket,
                     ExportMap *export_map)
    : m_service_factory(factory),
      m_plugin_loaders(plugin_loaders),
      m_ss(select_server),
      m_accepting_socket(socket),
      m_device_manager(NULL),
      m_plugin_manager(NULL),
      m_plugin_adaptor(NULL),
      m_preferences_factory(preferences_factory),
      m_universe_preferences(NULL),
      m_universe_store(NULL),
      m_export_map(export_map),
      m_port_manager(NULL),
      m_service_impl(NULL),
      m_broker(NULL),
      m_port_broker(NULL),
      m_reload_plugins(false),
      m_init_run(false),
      m_free_export_map(false),
      m_housekeeping_timeout(ola::network::INVALID_TIMEOUT),
      m_httpd(NULL),
      m_options(*ola_options),
      m_default_uid(OPEN_LIGHTING_ESTA_CODE, 0) {
  if (!m_export_map) {
    m_export_map = new ExportMap();
    m_free_export_map = true;
  }

  if (!m_options.http_port)
    m_options.http_port = DEFAULT_HTTP_PORT;

  m_export_map->GetIntegerVar(K_CLIENT_VAR);
}

/*
 * Shutdown the server
 */
OlaServer::~OlaServer() {
#ifdef HAVE_LIBMICROHTTPD
  if (m_httpd) {
    m_httpd->Stop();
    delete m_httpd;
    m_httpd = NULL;
  }
#endif

  if (m_housekeeping_timeout != ola::network::INVALID_TIMEOUT)
    m_ss->RemoveTimeout(m_housekeeping_timeout);

  StopPlugins();

  map<int, OlaClientService*>::iterator iter;
  for (iter = m_sd_to_service.begin(); iter != m_sd_to_service.end(); ++iter) {
    CleanupConnection(iter->second);
    // TODO(simon): close the socket here

    /*Socket *socket = ;
    m_ss->RemoveReadDescriptor(socket);
    socket->Close();
    */
  }

  if (m_broker)
    delete m_broker;

  if (m_port_broker)
    delete m_port_broker;

  if (m_accepting_socket &&
      m_accepting_socket->ValidReadDescriptor())
    m_ss->RemoveReadDescriptor(m_accepting_socket);

  if (m_universe_store) {
    m_universe_store->DeleteAll();
    delete m_universe_store;
  }

  if (m_universe_preferences) {
    m_universe_preferences->Save();
  }

  delete m_port_manager;
  delete m_plugin_adaptor;
  delete m_device_manager;
  delete m_plugin_manager;
  delete m_service_impl;

  if (m_free_export_map)
    delete m_export_map;
}

/*
 * Initialise the server
 * * @return true on success, false on failure
 */
bool OlaServer::Init() {
  if (m_init_run)
    return false;

  if (!m_service_factory || !m_ss)
    return false;

  // TODO(simon): run without preferences & PluginLoader
  if (m_plugin_loaders.empty() || !m_preferences_factory)
    return false;

  if (m_accepting_socket) {
    if (!m_accepting_socket->Listen()) {
      OLA_FATAL << "Could not listen on the RPC port, you probably have " <<
        "another instance of olad running";
      return false;
    }
    m_accepting_socket->SetOnAccept(
      ola::NewCallback(this, &OlaServer::NewConnection));
    m_ss->AddReadDescriptor(m_accepting_socket);
  }

#ifndef WIN32
  signal(SIGPIPE, SIG_IGN);
#endif

  // fetch the interface info
  ola::network::Interface iface;
  ola::network::InterfacePicker *picker =
    ola::network::InterfacePicker::NewPicker();
  if (!picker->ChooseInterface(&iface, "")) {
    OLA_WARN << "No network interface found";
  } else {
    // default to using the ip as a id
    m_default_uid = ola::rdm::UID(OPEN_LIGHTING_ESTA_CODE,
                                  iface.ip_address.AsInt());
  }
  delete picker;
  m_export_map->GetStringVar(K_UID_VAR)->Set(m_default_uid.ToString());
  OLA_INFO << "Server UID is " << m_default_uid;

  m_universe_preferences = m_preferences_factory->NewPreference(
      UNIVERSE_PREFERENCES);
  m_universe_preferences->Load();
  m_universe_store = new UniverseStore(m_universe_preferences, m_export_map);

  m_port_broker = new PortBroker();
  m_port_manager = new PortManager(m_universe_store, m_port_broker);
  m_broker = new ClientBroker();

  // setup the objects
  m_device_manager = new DeviceManager(m_preferences_factory, m_port_manager);
  m_plugin_adaptor = new PluginAdaptor(m_device_manager,
                                       m_ss,
                                       m_preferences_factory,
                                       m_port_broker);

  m_plugin_manager = new PluginManager(m_plugin_loaders, m_plugin_adaptor);
  m_service_impl = new OlaServerServiceImpl(
      m_universe_store,
      m_device_manager,
      m_plugin_manager,
      m_export_map,
      m_port_manager,
      m_broker,
      m_ss->WakeUpTime(),
      m_default_uid);

  if (!m_port_broker || !m_universe_store || !m_device_manager ||
      !m_plugin_adaptor || !m_port_manager || !m_plugin_manager || !m_broker ||
      !m_service_impl) {
    delete m_plugin_adaptor;
    delete m_device_manager;
    delete m_port_manager;
    delete m_universe_store;
    delete m_plugin_manager;
    return false;
  }

  // The plugin load procedure can take a while so we run it in the main loop.
  m_ss->Execute(
      ola::NewCallback(m_plugin_manager, &PluginManager::LoadAll));

#ifdef HAVE_LIBMICROHTTPD
  if (!StartHttpServer(iface))
    OLA_WARN << "Failed to start the HTTP server.";
#endif

  m_housekeeping_timeout = m_ss->RegisterRepeatingTimeout(
      K_HOUSEKEEPING_TIMEOUT_MS,
      ola::NewCallback(this, &OlaServer::RunHousekeeping));
  m_ss->RunInLoop(ola::NewCallback(this, &OlaServer::CheckForReload));

  m_init_run = true;
  return true;
}

/*
 * Reload all plugins, this can be called from a separate thread or in an
 * interrupt handler.
 */
void OlaServer::ReloadPlugins() {
  m_reload_plugins = true;
}

/*
 * Add a new ConnectedDescriptor to this Server.
 * @param socket the new ConnectedDescriptor
 */
void OlaServer::NewConnection(ola::network::ConnectedDescriptor *socket) {
  if (!socket)
    return;

  StreamRpcChannel *channel = new StreamRpcChannel(NULL, socket, m_export_map);
  socket->SetOnClose(NewSingleCallback(this, &OlaServer::SocketClosed, socket));
  OlaClientService_Stub *stub = new OlaClientService_Stub(channel);
  Client *client = new Client(stub);
  OlaClientService *service = m_service_factory->New(client, m_service_impl);
  m_broker->AddClient(client);
  channel->SetService(service);

  map<int, OlaClientService*>::const_iterator iter;
  iter = m_sd_to_service.find(socket->ReadDescriptor());

  if (iter != m_sd_to_service.end())
    OLA_INFO << "New socket but the client already exists!";

  pair<int, OlaClientService*> pair(socket->ReadDescriptor(), service);
  m_sd_to_service.insert(pair);

  // This hands off ownership to the select server
  m_ss->AddReadDescriptor(socket, true);
  (*m_export_map->GetIntegerVar(K_CLIENT_VAR))++;
}

/*
 * Called when a socket is closed
 */
void OlaServer::SocketClosed(ola::network::ConnectedDescriptor *socket) {
  map<int, OlaClientService*>::iterator iter;
  iter = m_sd_to_service.find(socket->ReadDescriptor());

  if (iter == m_sd_to_service.end())
    OLA_INFO << "A socket was closed but we didn't find the client";

  (*m_export_map->GetIntegerVar(K_CLIENT_VAR))--;
  CleanupConnection(iter->second);
  m_sd_to_service.erase(iter);
}

/*
 * Run the garbage collector
 */
bool OlaServer::RunHousekeeping() {
  OLA_DEBUG << "Garbage collecting";
  m_universe_store->GarbageCollectUniverses();
  return true;
}

/*
 * Called once per loop iteration
 */
void OlaServer::CheckForReload() {
  if (m_reload_plugins) {
    m_reload_plugins = false;
    OLA_INFO << "Reloading plugins";
    StopPlugins();
    m_plugin_manager->LoadAll();
  }
}

/*
 * Setup the HTTP server if required.
 * @param interface the primary interface that the server is using.
 */
#ifdef HAVE_LIBMICROHTTPD
bool OlaServer::StartHttpServer(const ola::network::Interface &iface) {
  if (!m_options.http_enable)
    return true;

  // create a pipe socket for the http server to communicate with the main
  // server on.
  ola::network::PipeDescriptor *pipe_descriptor =
    new ola::network::PipeDescriptor();
  if (!pipe_descriptor->Init()) {
    delete pipe_descriptor;
    return false;
  }

  // ownership of the pipe_descriptor is transferred here.
  m_httpd = new OlaHttpServer(m_export_map,
                              pipe_descriptor->OppositeEnd(),
                              this,
                              m_options.http_port,
                              m_options.http_enable_quit,
                              m_options.http_data_dir,
                              iface);

  if (m_httpd->Init()) {
    m_httpd->Start();
    // register the pipe descriptor as a client
    NewConnection(pipe_descriptor);
    return true;
  } else {
    pipe_descriptor->Close();
    delete pipe_descriptor;
    delete m_httpd;
    m_httpd = NULL;
    return false;
  }
}
#endif

/*
 * Stop and unload all the plugins
 */
void OlaServer::StopPlugins() {
  if (m_plugin_manager)
    m_plugin_manager->UnloadAll();
  if (m_device_manager) {
    if (m_device_manager->DeviceCount()) {
      OLA_WARN << "Some devices failed to unload, we're probably leaking "
        << "memory now";
    }
    m_device_manager->UnregisterAllDevices();
  }
}

/*
 * Cleanup everything related to a client connection
 */
void OlaServer::CleanupConnection(OlaClientService *service) {
  Client *client = service->GetClient();
  m_broker->RemoveClient(client);

  vector<Universe*> universe_list;
  m_universe_store->GetList(&universe_list);
  vector<Universe*>::iterator uni_iter;

  // O(universes * clients). Clean this up sometime.
  for (uni_iter = universe_list.begin();
       uni_iter != universe_list.end();
       ++uni_iter) {
    (*uni_iter)->RemoveSourceClient(client);
    (*uni_iter)->RemoveSinkClient(client);
  }
  delete client->Stub()->channel();
  delete client->Stub();
  delete client;
  delete service;
}
}  // ola
<|endoftext|>


<commit_before>
#include "api/constants.hpp"
#include "api/IBuffer.hpp"
#include "api/IRequest.hpp"
#include "api/IModuleManager.hpp"
#include "api/IModule.hpp"
#include "utils/Path.hpp"
#include "utils/Logger.hpp"
#include "utils/macros.hpp"
#include "config.hpp"

#include "DirListing.hpp"

using namespace zhttpd;
using namespace zhttpd::mod;

DirListing::DirListing(api::IModuleManager*)
{
}

DirListing::~DirListing()
{
}

bool DirListing::processRequest(api::event::Type event, api::IRequest* request, api::IBuffer*)
{
    if (event == api::event::ON_END)
    {
        Path dir(request->getFilePath());
        std::list<std::string> files = dir.getDirectoryContent();
        std::string slash("/");
        std::string const& path = request->getRequestQuery(); // XXX stop at '?' or '#'
        if (path == "/")
            slash.clear();
        std::string out =
            "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
            "\n"
                "\n"
                    "<title>Index of " + path + "</title>\n"
                    "\n"
                "\n"
                "\n"
                    "
 Index of " + path + "
\n"
                    "
\n"
                    "
\n"
                        "
..
";

        std::list<std::string>::const_iterator it = files.begin();
        std::list<std::string>::const_iterator itEnd = files.end();
        for (; it != itEnd; ++it)
            out += "
" + *it + "
\n"; // XXX replace '"' in path !

        out +=      "
\n"
                    "
\n"
                    "
"
                        ZHTTPD_FULLNAME
                    "
\n"
                "\n"
            "";
        request->giveData(request->getBufferManager().allocate(out.data(), out.size()));
        request->raiseEnd();
        return true;
    }
    return false;
}

<commit_msg>dirlisting send html5 now<commit_after>
#include "api/constants.hpp"
#include "api/IBuffer.hpp"
#include "api/IRequest.hpp"
#include "api/IModuleManager.hpp"
#include "api/IModule.hpp"
#include "utils/Path.hpp"
#include "utils/Logger.hpp"
#include "utils/macros.hpp"
#include "config.hpp"

#include "DirListing.hpp"

using namespace zhttpd;
using namespace zhttpd::mod;

DirListing::DirListing(api::IModuleManager*)
{
}

DirListing::~DirListing()
{
}

bool DirListing::processRequest(api::event::Type event, api::IRequest* request, api::IBuffer*)
{
    if (event == api::event::ON_END)
    {
        Path dir(request->getFilePath());
        std::list<std::string> files = dir.getDirectoryContent();
        std::string slash("/");
        std::string const& path = request->getRequestQuery(); // XXX stop at '?' or '#'
        if (path == "/")
            slash.clear();
        std::string out =
            "<!DOCTYPE html>\n"
            "\n"
                "\n"
                    "<title>Index of " + path + "</title>\n"
                    "\n"
                "\n"
                "\n"
                    "
 Index of " + path + "
\n"
                    "
\n"
                    "
\n"
                        "
..
";

        std::list<std::string>::const_iterator it = files.begin();
        std::list<std::string>::const_iterator itEnd = files.end();
        for (; it != itEnd; ++it)
            out += "
" + *it + "
\n"; // XXX replace '"' in path !

        out +=      "
\n"
                    "
\n"
                    "
"
                        ZHTTPD_FULLNAME
                    "
\n"
                "\n"
            "";
        request->giveData(request->getBufferManager().allocate(out.data(), out.size()));
        request->raiseEnd();
        return true;
    }
    return false;
}

<|endoftext|>


<commit_before>// Copyright 2015-2020 Elviss Strazdins. All rights reserved.

#ifndef OUZEL_HASH_FNV1_HPP
#define OUZEL_HASH_FNV1_HPP

#include <cstdint>

namespace ouzel::hash::fnv1
{
    inline namespace detail
    {
        template <typename T> struct prime;
        template <typename T> struct offsetBasis;

        template <> struct prime<std::uint32_t>
        {
            static constexpr std::uint32_t value = 16777619U;
        };

        template <> struct offsetBasis<std::uint32_t>
        {
            static constexpr std::uint32_t value = 2166136261U;
        };

        template <> struct prime<std::uint64_t>
        {
            static constexpr std::uint64_t value = 1099511628211ULL;
        };

        template <> struct offsetBasis<std::uint64_t>
        {
            static constexpr std::uint64_t value = 14695981039346656037ULL;
        };
    }

    template <typename Result, typename Value>
    constexpr Result hash(const Value value, const std::size_t i = 0,
                          const Result result = offsetBasis<Result>::value) noexcept
    {
        return (i < sizeof(Value)) ? hash<Result>(value, i + 1, (result * prime<Result>::value) ^ ((value >> (i * 8)) & 0xFF)) : result;
    }
}

#endif // OUZEL_HASH_FNV1_HPP
<commit_msg>Move the constants to a single struct<commit_after>// Copyright 2015-2020 Elviss Strazdins. All rights reserved.

#ifndef OUZEL_HASH_FNV1_HPP
#define OUZEL_HASH_FNV1_HPP

#include <cstdint>

namespace ouzel::hash::fnv1
{
    inline namespace detail
    {
        template <typename T> struct Constants;

        template <> struct Constants<std::uint32_t>
        {
            static constexpr std::uint32_t prime = 16777619U;
            static constexpr std::uint32_t offsetBasis = 2166136261U;
        };

        template <> struct Constants<std::uint64_t>
        {
            static constexpr std::uint64_t prime = 1099511628211ULL;
            static constexpr std::uint64_t offsetBasis = 14695981039346656037ULL;
        };
    }

    template <typename Result, typename Value>
    constexpr Result hash(const Value value, const std::size_t i = 0,
                          const Result result = Constants<Result>::offsetBasis) noexcept
    {
        return (i < sizeof(Value)) ? hash<Result>(value, i + 1, (result * Constants<Result>::prime) ^ ((value >> (i * 8)) & 0xFF)) : result;
    }
}

#endif // OUZEL_HASH_FNV1_HPP
<|endoftext|>


<commit_before>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
// StdAir
#include <stdair/stdair_inventory_types.hpp>
#include <stdair/basic/BasFileMgr.hpp>
#include <stdair/basic/BasChronometer.hpp>
#include <stdair/bom/BomManager.hpp>
#include <stdair/bom/LegCabin.hpp>
#include <stdair/command/CmdBomManager.hpp>
#include <stdair/service/Logger.hpp>
#include <stdair/STDAIR_Service.hpp>
// RMOL
#include <rmol/basic/BasConst_RMOL_Service.hpp>
#include <rmol/factory/FacSupervisor.hpp>
#include <rmol/factory/FacRmolServiceContext.hpp>
#include <rmol/command/Optimiser.hpp>
#include <rmol/command/Unconstrainer.hpp>
#include <rmol/command/Forecaster.hpp>
#include <rmol/service/RMOL_ServiceContext.hpp>
#include <rmol/RMOL_Service.hpp>

namespace RMOL {

  // ////////////////////////////////////////////////////////////////////
  RMOL_Service::RMOL_Service () : _rmolServiceContext (NULL) {
    assert (false);
  }

  // ////////////////////////////////////////////////////////////////////
  RMOL_Service::RMOL_Service (const RMOL_Service& iService) :
    _rmolServiceContext (NULL) {
    assert (false);
  }

  // ////////////////////////////////////////////////////////////////////
  RMOL_Service::RMOL_Service (const stdair::BasLogParams& iLogParams,
                              const stdair::CabinCapacity_T& iCabinCapacity) :
    _rmolServiceContext (NULL) {

    // Initialise the service context
    initServiceContext ();

    // Initialise the STDAIR service handler
    initStdAirService (iLogParams);

    // Build a dummy inventory with a leg-cabin which has the given capacity.
    buildInventorySample (iCabinCapacity);

  }

  // ////////////////////////////////////////////////////////////////////
  RMOL_Service::RMOL_Service (const stdair::BasLogParams& iLogParams) :
    _rmolServiceContext (NULL) {

    // Initialise the service context
    initServiceContext ();

    // Initialise the STDAIR service handler
    initStdAirService (iLogParams);
  }

  // ////////////////////////////////////////////////////////////////////
  RMOL_Service:: RMOL_Service (stdair::STDAIR_ServicePtr_T ioSTDAIRServicePtr)
    : _rmolServiceContext (NULL) {

    // Initialise the context
    initServiceContext ();

    // Add the StdAir service context to the RMOL service context
    addStdAirService (ioSTDAIRServicePtr);
  }

  // ////////////////////////////////////////////////////////////////////
  RMOL_Service::~RMOL_Service () {
    // Clean all the RMOL-scoped objects
    FacSupervisor::cleanFactory();
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::initServiceContext () {
    // Initialise the service context
    RMOL_ServiceContext& lRMOL_ServiceContext =
      FacRmolServiceContext::instance().create ();
    _rmolServiceContext = &lRMOL_ServiceContext;
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::
  initStdAirService (const stdair::BasLogParams& iLogParams) {
    assert (_rmolServiceContext != NULL);

    // Initialise the STDAIR service handler
    // Note that the track on the object memory is kept thanks to the Boost
    // Smart Pointers component.
    STDAIR_ServicePtr_T lSTDAIR_Service =
      STDAIR_ServicePtr_T (new stdair::STDAIR_Service (iLogParams));

    // Store the STDAIR service object within the (RMOL) service context
    addStdAirService (lSTDAIR_Service);
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::
  addStdAirService (stdair::STDAIR_ServicePtr_T ioSTDAIR_Service_ptr) {

    // Retrieve the RMOL service context
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext =
      *_rmolServiceContext;

    // Store the STDAIR service object within the (AIRINV) service context
    lRMOL_ServiceContext.setSTDAIR_Service (ioSTDAIR_Service_ptr);
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::
  buildInventorySample (const stdair::CabinCapacity_T& iCabinCapacity) {
    // Retrieve the BomRoot.
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
    stdair::STDAIR_Service& lSTDAIR_Service =
      lRMOL_ServiceContext.getSTDAIR_Service ();
    stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot ();

    stdair::CmdBomManager::buildSampleBomForRMOL (lBomRoot, iCabinCapacity);
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::readFromInputFile (const std::string& iInputFileName) {
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
    lRMOL_ServiceContext.readFromInputFile (iInputFileName);
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::reset () {
    // Retrieve the RMOL service context
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;

    lRMOL_ServiceContext.reset();
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::
  optimalOptimisationByMCIntegration (const int K) {
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;

    stdair::LegCabin& lLegCabin = lRMOL_ServiceContext.getLegCabinSample();

    stdair::BasChronometer lOptimisationChronometer;
    lOptimisationChronometer.start();

    Optimiser::optimalOptimisationByMCIntegration (K, lLegCabin);

    const double lOptimisationMeasure = lOptimisationChronometer.elapsed();

    // DEBUG
    STDAIR_LOG_DEBUG ("Optimisation by Monte-Carlo performed in "
                      << lOptimisationMeasure);
    //STDAIR_LOG_DEBUG ("Resulting buckets: " << oBucketHolder_ptr->display());

    std::ostringstream logStream;
    stdair::BidPriceVector_T lBidPriceVector = lLegCabin.getBidPriceVector();
    logStream << "Bid-Price Vector (BPV): ";
    unsigned int size = lBidPriceVector.size();

    for (unsigned int i = 0; i < size; ++i) {
      const double bidPrice = lBidPriceVector.at(i);
      logStream << std::fixed << std::setprecision (2) << bidPrice << ", ";
    }
    STDAIR_LOG_DEBUG (logStream.str());
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::
  optimalOptimisationByDP () {

  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::heuristicOptimisationByEmsr () {
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;

    stdair::LegCabin& lLegCabin = lRMOL_ServiceContext.getLegCabinSample();

    stdair::BasChronometer lOptimisationChronometer;
    lOptimisationChronometer.start();

    Optimiser::heuristicOptimisationByEmsr (lLegCabin);

    const double lOptimisationMeasure = lOptimisationChronometer.elapsed();
    // DEBUG
    STDAIR_LOG_DEBUG ("Optimisation EMSR performed in "
                      << lOptimisationMeasure);
    STDAIR_LOG_DEBUG ("Result: " << lLegCabin.displayVirtualClassList());

    std::ostringstream logStream;
    stdair::BidPriceVector_T lBidPriceVector = lLegCabin.getBidPriceVector();
    logStream << "Bid-Price Vector (BPV): ";
    unsigned int size = lBidPriceVector.size();

    for (unsigned int i = 0; i < size; ++i) {
      const double bidPrice = lBidPriceVector.at(i);
      logStream << std::fixed << std::setprecision (2) << bidPrice << ", ";
    }
    STDAIR_LOG_DEBUG (logStream.str());
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::heuristicOptimisationByEmsrA () {
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;

    stdair::LegCabin& lLegCabin = lRMOL_ServiceContext.getLegCabinSample();

    Optimiser::heuristicOptimisationByEmsrA (lLegCabin);

    // DEBUG
    STDAIR_LOG_DEBUG ("Result: " << lLegCabin.displayVirtualClassList());

  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::heuristicOptimisationByEmsrB () {
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;

    stdair::LegCabin& lLegCabin = lRMOL_ServiceContext.getLegCabinSample();

    Optimiser::heuristicOptimisationByEmsrB (lLegCabin);

    // DEBUG
    STDAIR_LOG_DEBUG ("Result: " << lLegCabin.displayVirtualClassList());
  }

}
<commit_msg>[Dev] Made a constant 'const'.<commit_after>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
// StdAir
#include <stdair/stdair_inventory_types.hpp>
#include <stdair/basic/BasFileMgr.hpp>
#include <stdair/basic/BasChronometer.hpp>
#include <stdair/bom/BomManager.hpp>
#include <stdair/bom/LegCabin.hpp>
#include <stdair/command/CmdBomManager.hpp>
#include <stdair/service/Logger.hpp>
#include <stdair/STDAIR_Service.hpp>
// RMOL
#include <rmol/basic/BasConst_RMOL_Service.hpp>
#include <rmol/factory/FacSupervisor.hpp>
#include <rmol/factory/FacRmolServiceContext.hpp>
#include <rmol/command/Optimiser.hpp>
#include <rmol/command/Unconstrainer.hpp>
#include <rmol/command/Forecaster.hpp>
#include <rmol/service/RMOL_ServiceContext.hpp>
#include <rmol/RMOL_Service.hpp>

namespace RMOL {

  // ////////////////////////////////////////////////////////////////////
  RMOL_Service::RMOL_Service () : _rmolServiceContext (NULL) {
    assert (false);
  }

  // ////////////////////////////////////////////////////////////////////
  RMOL_Service::RMOL_Service (const RMOL_Service& iService) :
    _rmolServiceContext (NULL) {
    assert (false);
  }

  // ////////////////////////////////////////////////////////////////////
  RMOL_Service::RMOL_Service (const stdair::BasLogParams& iLogParams,
                              const stdair::CabinCapacity_T& iCabinCapacity) :
    _rmolServiceContext (NULL) {

    // Initialise the service context
    initServiceContext ();

    // Initialise the STDAIR service handler
    initStdAirService (iLogParams);

    // Build a dummy inventory with a leg-cabin which has the given capacity.
    buildInventorySample (iCabinCapacity);

  }

  // ////////////////////////////////////////////////////////////////////
  RMOL_Service::RMOL_Service (const stdair::BasLogParams& iLogParams) :
    _rmolServiceContext (NULL) {

    // Initialise the service context
    initServiceContext ();

    // Initialise the STDAIR service handler
    initStdAirService (iLogParams);
  }

  // ////////////////////////////////////////////////////////////////////
  RMOL_Service:: RMOL_Service (stdair::STDAIR_ServicePtr_T ioSTDAIRServicePtr)
    : _rmolServiceContext (NULL) {

    // Initialise the context
    initServiceContext ();

    // Add the StdAir service context to the RMOL service context
    addStdAirService (ioSTDAIRServicePtr);
  }

  // ////////////////////////////////////////////////////////////////////
  RMOL_Service::~RMOL_Service () {
    // Clean all the RMOL-scoped objects
    FacSupervisor::cleanFactory();
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::initServiceContext () {
    // Initialise the service context
    RMOL_ServiceContext& lRMOL_ServiceContext =
      FacRmolServiceContext::instance().create ();
    _rmolServiceContext = &lRMOL_ServiceContext;
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::
  initStdAirService (const stdair::BasLogParams& iLogParams) {
    assert (_rmolServiceContext != NULL);

    // Initialise the STDAIR service handler
    // Note that the track on the object memory is kept thanks to the Boost
    // Smart Pointers component.
    STDAIR_ServicePtr_T lSTDAIR_Service =
      STDAIR_ServicePtr_T (new stdair::STDAIR_Service (iLogParams));

    // Store the STDAIR service object within the (RMOL) service context
    addStdAirService (lSTDAIR_Service);
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::
  addStdAirService (stdair::STDAIR_ServicePtr_T ioSTDAIR_Service_ptr) {

    // Retrieve the RMOL service context
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext =
      *_rmolServiceContext;

    // Store the STDAIR service object within the (AIRINV) service context
    lRMOL_ServiceContext.setSTDAIR_Service (ioSTDAIR_Service_ptr);
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::
  buildInventorySample (const stdair::CabinCapacity_T& iCabinCapacity) {
    // Retrieve the BomRoot.
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
    stdair::STDAIR_Service& lSTDAIR_Service =
      lRMOL_ServiceContext.getSTDAIR_Service ();
    stdair::BomRoot& lBomRoot = lSTDAIR_Service.getBomRoot ();

    stdair::CmdBomManager::buildSampleBomForRMOL (lBomRoot, iCabinCapacity);
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::readFromInputFile (const std::string& iInputFileName) {
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;
    lRMOL_ServiceContext.readFromInputFile (iInputFileName);
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::reset () {
    // Retrieve the RMOL service context
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;

    lRMOL_ServiceContext.reset();
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::
  optimalOptimisationByMCIntegration (const int K) {
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;

    stdair::LegCabin& lLegCabin = lRMOL_ServiceContext.getLegCabinSample();

    stdair::BasChronometer lOptimisationChronometer;
    lOptimisationChronometer.start();

    Optimiser::optimalOptimisationByMCIntegration (K, lLegCabin);

    const double lOptimisationMeasure = lOptimisationChronometer.elapsed();

    // DEBUG
    STDAIR_LOG_DEBUG ("Optimisation by Monte-Carlo performed in "
                      << lOptimisationMeasure);
    //STDAIR_LOG_DEBUG ("Resulting buckets: " << oBucketHolder_ptr->display());

    std::ostringstream logStream;
    stdair::BidPriceVector_T lBidPriceVector = lLegCabin.getBidPriceVector();
    logStream << "Bid-Price Vector (BPV): ";
    unsigned int size = lBidPriceVector.size();

    for (unsigned int i = 0; i < size; ++i) {
      const double bidPrice = lBidPriceVector.at(i);
      logStream << std::fixed << std::setprecision (2) << bidPrice << ", ";
    }
    STDAIR_LOG_DEBUG (logStream.str());
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::
  optimalOptimisationByDP () {

  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::heuristicOptimisationByEmsr () {
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;

    stdair::LegCabin& lLegCabin = lRMOL_ServiceContext.getLegCabinSample();

    stdair::BasChronometer lOptimisationChronometer;
    lOptimisationChronometer.start();

    Optimiser::heuristicOptimisationByEmsr (lLegCabin);

    const double lOptimisationMeasure = lOptimisationChronometer.elapsed();
    // DEBUG
    STDAIR_LOG_DEBUG ("Optimisation EMSR performed in "
                      << lOptimisationMeasure);
    STDAIR_LOG_DEBUG ("Result: " << lLegCabin.displayVirtualClassList());

    std::ostringstream logStream;
    stdair::BidPriceVector_T lBidPriceVector = lLegCabin.getBidPriceVector();
    logStream << "Bid-Price Vector (BPV): ";
    const unsigned int size = lBidPriceVector.size();

    for (unsigned int i = 0; i < size; ++i) {
      const double bidPrice = lBidPriceVector.at(i);
      logStream << std::fixed << std::setprecision (2) << bidPrice << ", ";
    }
    STDAIR_LOG_DEBUG (logStream.str());
  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::heuristicOptimisationByEmsrA () {
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;

    stdair::LegCabin& lLegCabin = lRMOL_ServiceContext.getLegCabinSample();

    Optimiser::heuristicOptimisationByEmsrA (lLegCabin);

    // DEBUG
    STDAIR_LOG_DEBUG ("Result: " << lLegCabin.displayVirtualClassList());

  }

  // ////////////////////////////////////////////////////////////////////
  void RMOL_Service::heuristicOptimisationByEmsrB () {
    assert (_rmolServiceContext != NULL);
    RMOL_ServiceContext& lRMOL_ServiceContext = *_rmolServiceContext;

    stdair::LegCabin& lLegCabin = lRMOL_ServiceContext.getLegCabinSample();

    Optimiser::heuristicOptimisationByEmsrB (lLegCabin);

    // DEBUG
    STDAIR_LOG_DEBUG ("Result: " << lLegCabin.displayVirtualClassList());
  }

}
<|endoftext|>


<commit_before>// -*-Mode: C++;-*-
// $Id$

//***************************************************************************
//
// File:
//    $Source$
//
// Purpose:
//    Class for reading and representing hpcrun profile data.
//
// Description:
//    [The set of functions, macros, etc. defined in the file]
//
// Author:
//    Written by John Mellor-Crummey and Nathan Tallent, Rice University.
//
//    Adapted from parts of The Visual Profiler by Curtis L. Janssen
//    (vmonfile.cc).
//
//***************************************************************************

#ifdef __GNUC__
#pragma implementation
#endif

//************************* System Include Files ****************************

#include <iostream>
#include <string>

#include <stdio.h>
#include <sys/stat.h>

//*************************** User Include Files ****************************

#include "hpcrun.h"
#include "proffile.h"
#include "io.h"

//*************************** Forward Declarations **************************

//#define PROFREADER_TEST

using namespace std;

static int read_string(FILE *fp, std::string& str);

//***************************************************************************

ProfFile::ProfFile()
{
  mtime_ = 0;
}

ProfFile::~ProfFile()
{
}

int
ProfFile::read(const string &filename)
{
  FILE *fp;

  mtime_ = 0;

  struct stat statbuf;
  if (stat(filename.c_str(), &statbuf)) {
    return 1;
  }
  name_ = filename;
  mtime_ = statbuf.st_mtime;

  fp = fopen(filename.c_str(), "r");

  // <header>
  char magic_str[HPCRUNFILE_MAGIC_STR_LEN];
  char version[HPCRUNFILE_VERSION_LEN];
  char endian;
  int c;
  size_t sz;

  sz = fread((char*)magic_str, 1, HPCRUNFILE_MAGIC_STR_LEN, fp);
  if (sz != HPCRUNFILE_MAGIC_STR_LEN) { return 1; }

  sz = fread((char*)version, 1, HPCRUNFILE_VERSION_LEN, fp);
  if (sz != HPCRUNFILE_VERSION_LEN) { return 1; }

  if ((c = fgetc(fp)) == EOF) { return 1; }
  endian = (char)c;

  // sanity check header
  if (strncmp(magic_str, HPCRUNFILE_MAGIC_STR,
	      HPCRUNFILE_MAGIC_STR_LEN) != 0) {
    return 1;
  }
  if (strncmp(version, HPCRUNFILE_VERSION, HPCRUNFILE_VERSION_LEN) != 0) {
    return 1;
  }
  if (endian != HPCRUNFILE_ENDIAN) { return 1; }

  // <loadmodule_list>
  uint32_t count;

  sz = hpc_fread_le4(&count, fp);
  if (sz != sizeof(count)) { return 1; }

  lmvec_.resize(count);
  for (unsigned int i = 0; i < count; ++i) {
    if (lmvec_[i].read(fp) != 0) { return 1; }
  }

  fclose(fp);
  return 0;
}

void
ProfFile::dump(std::ostream& o, const char* pre) const
{
  string p = pre;
  string p1 = p + "  ";

  o << p << "--- ProfFile Dump ---" << endl;
  o << p << "{ ProfFile: " << name_ << ", modtime: " << mtime_ << " }"
    << endl;

  for (unsigned int i = 0; i < num_load_modules(); ++i) {
    const ProfFileLM& proflm = load_module(i);
    proflm.dump(o, p1.c_str());
  }
}

//***************************************************************************

ProfFileLM::ProfFileLM()
{
}

ProfFileLM::~ProfFileLM()
{
}

#undef  DEBUG

int
ProfFileLM::read(FILE *fp)
{
  size_t sz;

  // <loadmodule_name>, <loadmodule_loadoffset>
  if (read_string(fp, name_) != 0) { return 1; }
#ifdef DEBUG
  cerr << name_ << " ";
#endif

  sz = hpc_fread_le8(&load_addr_, fp);
  if (sz != sizeof(load_addr_)) { return 1; }
#ifdef DEBUG
  cerr << "load address=" << load_addr_ << endl;
#endif

  // <loadmodule_eventcount>
  unsigned int count = 1;
  sz = hpc_fread_le4(&count, fp);
  if (sz != sizeof(count)) { return 1; }
  eventvec_.resize(count);

  // Event data
  for (unsigned int i = 0; i < count; ++i) {
    if (eventvec_[i].read(fp, load_addr_) != 0) { return 1; }
  }

  return 0;
}

void
ProfFileLM::dump(std::ostream& o, const char* pre) const
{
  string p = pre;
  string p1 = p + "  ";

  o << p << "{ ProfFileLM: " << name_ << ", loadAddr: 0x" << hex
    << load_addr_ << dec << " }" << endl;

  for (unsigned int i = 0; i < num_events(); ++i) {
    const ProfFileEvent& profevent = event(i);
    profevent.dump(o, p1.c_str());
  }
}

//***************************************************************************

ProfFileEvent::ProfFileEvent()
{
}

ProfFileEvent::~ProfFileEvent()
{
}

int
ProfFileEvent::read(FILE *fp, uint64_t load_addr)
{
  size_t sz;

  // <event_x_name> <event_x_description> <event_x_period>
  if (read_string(fp, name_) != 0) { return 1; }
  if (read_string(fp, desc_) != 0) { return 1; }

  sz = hpc_fread_le8(&period_, fp);
  if (sz != sizeof(period_)) { return 1; }

  // <event_x_data>
  dat_.clear();
  outofrange_ = 0;
  overflow_ = 0;

  // <histogram_non_zero_bucket_count>
  unsigned int ndat;    // number of profile entries
  sz = hpc_fread_le4(&ndat, fp);
  if (sz != sizeof(ndat)) { return 1; }
#ifdef DEBUG
  cerr << "ndat =" << ndat << endl;
#endif
  dat_.resize(ndat);

  // <histogram_non_zero_bucket_x_value>
  // <histogram_non_zero_bucket_x_offset>
  unsigned int count;   // profile count
  unsigned int offset;  // offset from load address
  for (unsigned int i = 0; i < ndat; ++i) {
    sz = hpc_fread_le4(&count, fp);        // count
    if (sz != sizeof(count)) { return 1; }

    sz = hpc_fread_le4(&offset, fp);       // offset
    if (sz != sizeof(offset)) { return 1; }
#ifdef DEBUG
  cerr << "  (cnt,offset)=(" << count << "," << offset << ")" << endl;
#endif

    pprof_off_t pc = load_addr + offset;
    dat_[i] = make_pair(pc, count);
  }

  return 0;
}

void
ProfFileEvent::dump(std::ostream& o, const char* pre) const
{
  string p = pre;
  string p1 = p + "  ";

  o << p << "{ ProfFileEvent: " << name() << ", period: " << period()
    << ", outofrange: " << outofrange() << ", overflow: " << overflow()
    << " }" << endl;

  for (unsigned int i = 0; i < num_data(); ++i) {
    const ProfFileEventDatum& dat = datum(i);
    o << p1 << "{ 0x" << hex << dat.first << ": " << dec
      << dat.second << " }" << endl;
  }
}

//***************************************************************************

static int
read_string(FILE *fp, std::string& str)
{
  size_t sz;
  uint32_t len; // string length
  int c;

  // <string_length> <string_without_terminator>
  sz = hpc_fread_le4(&len, fp);
  if (sz != sizeof(len)) { return 1; }

  str.resize(len);
  for (unsigned int n = 0; n < len; ++n) {
    if ((c = fgetc(fp)) == EOF) { return 1; }
    str[n] = (char)c;
  }
  return 0;
}

//***************************************************************************

#ifdef PROFREADER_TEST

int main(int argc, char **argv)
{
  std::string filename = argv[1];
  ProfFile f;

  int ret = f.read(filename);

  if (ret == 0) {
    cerr << "successfully read file!";
  } else {
    cerr << "error reading file!";
  }

  cout << "File dump:" << endl;
  f.dump(cout);
}

#endif
<commit_msg>When writing profile data, record load module offsets as 8 bytes (necessary for 64 bit address spaces)<commit_after>// -*-Mode: C++;-*-
// $Id$

//***************************************************************************
//
// File:
//    $Source$
//
// Purpose:
//    Class for reading and representing hpcrun profile data.
//
// Description:
//    [The set of functions, macros, etc. defined in the file]
//
// Author:
//    Written by John Mellor-Crummey and Nathan Tallent, Rice University.
//
//    Adapted from parts of The Visual Profiler by Curtis L. Janssen
//    (vmonfile.cc).
//
//***************************************************************************

#ifdef __GNUC__
#pragma implementation
#endif

//************************* System Include Files ****************************

#include <iostream>
#include <string>

#include <stdio.h>
#include <sys/stat.h>

//*************************** User Include Files ****************************

#include "hpcrun.h"
#include "proffile.h"
#include "io.h"

//*************************** Forward Declarations **************************

//#define PROFREADER_TEST

using namespace std;

static int read_string(FILE *fp, std::string& str);

//***************************************************************************

ProfFile::ProfFile()
{
  mtime_ = 0;
}

ProfFile::~ProfFile()
{
}

int
ProfFile::read(const string &filename)
{
  FILE *fp;

  mtime_ = 0;

  struct stat statbuf;
  if (stat(filename.c_str(), &statbuf)) {
    return 1;
  }
  name_ = filename;
  mtime_ = statbuf.st_mtime;

  fp = fopen(filename.c_str(), "r");

  // <header>
  char magic_str[HPCRUNFILE_MAGIC_STR_LEN];
  char version[HPCRUNFILE_VERSION_LEN];
  char endian;
  int c;
  size_t sz;

  sz = fread((char*)magic_str, 1, HPCRUNFILE_MAGIC_STR_LEN, fp);
  if (sz != HPCRUNFILE_MAGIC_STR_LEN) { return 1; }

  sz = fread((char*)version, 1, HPCRUNFILE_VERSION_LEN, fp);
  if (sz != HPCRUNFILE_VERSION_LEN) { return 1; }

  if ((c = fgetc(fp)) == EOF) { return 1; }
  endian = (char)c;

  // sanity check header
  if (strncmp(magic_str, HPCRUNFILE_MAGIC_STR,
	      HPCRUNFILE_MAGIC_STR_LEN) != 0) {
    return 1;
  }
  if (strncmp(version, HPCRUNFILE_VERSION, HPCRUNFILE_VERSION_LEN) != 0) {
    return 1;
  }
  if (endian != HPCRUNFILE_ENDIAN) { return 1; }

  // <loadmodule_list>
  uint32_t count;

  sz = hpc_fread_le4(&count, fp);
  if (sz != sizeof(count)) { return 1; }

  lmvec_.resize(count);
  for (unsigned int i = 0; i < count; ++i) {
    if (lmvec_[i].read(fp) != 0) { return 1; }
  }

  fclose(fp);
  return 0;
}

void
ProfFile::dump(std::ostream& o, const char* pre) const
{
  string p = pre;
  string p1 = p + "  ";

  o << p << "--- ProfFile Dump ---" << endl;
  o << p << "{ ProfFile: " << name_ << ", modtime: " << mtime_ << " }"
    << endl;

  for (unsigned int i = 0; i < num_load_modules(); ++i) {
    const ProfFileLM& proflm = load_module(i);
    proflm.dump(o, p1.c_str());
  }
  o << p << "--- End ProfFile Dump ---" << endl;
}

//***************************************************************************

ProfFileLM::ProfFileLM()
{
}

ProfFileLM::~ProfFileLM()
{
}

#undef  DEBUG

int
ProfFileLM::read(FILE *fp)
{
  size_t sz;

  // <loadmodule_name>, <loadmodule_loadoffset>
  if (read_string(fp, name_) != 0) { return 1; }
#ifdef DEBUG
  cerr << name_ << " ";
#endif

  sz = hpc_fread_le8(&load_addr_, fp);
  if (sz != sizeof(load_addr_)) { return 1; }
#ifdef DEBUG
  cerr << "load address=" << load_addr_ << endl;
#endif

  // <loadmodule_eventcount>
  unsigned int count = 1;
  sz = hpc_fread_le4(&count, fp);
  if (sz != sizeof(count)) { return 1; }
  eventvec_.resize(count);

  // Event data
  for (unsigned int i = 0; i < count; ++i) {
    if (eventvec_[i].read(fp, load_addr_) != 0) { return 1; }
  }

  return 0;
}

void
ProfFileLM::dump(std::ostream& o, const char* pre) const
{
  string p = pre;
  string p1 = p + "  ";

  o << p << "{ ProfFileLM: " << name_ << ", loadAddr: 0x" << hex
    << load_addr_ << dec << " }" << endl;

  for (unsigned int i = 0; i < num_events(); ++i) {
    const ProfFileEvent& profevent = event(i);
    profevent.dump(o, p1.c_str());
  }
}

//***************************************************************************

ProfFileEvent::ProfFileEvent()
{
}

ProfFileEvent::~ProfFileEvent()
{
}

int
ProfFileEvent::read(FILE *fp, uint64_t load_addr)
{
  size_t sz;

  // <event_x_name> <event_x_description> <event_x_period>
  if (read_string(fp, name_) != 0) { return 1; }
  if (read_string(fp, desc_) != 0) { return 1; }

  sz = hpc_fread_le8(&period_, fp);
  if (sz != sizeof(period_)) { return 1; }

  // <event_x_data>
  dat_.clear();
  outofrange_ = 0;
  overflow_ = 0;

  // <histogram_non_zero_bucket_count>
  uint64_t ndat;    // number of profile entries
  sz = hpc_fread_le8(&ndat, fp);
  if (sz != sizeof(ndat)) { return 1; }
#ifdef DEBUG
  cerr << "ndat =" << ndat << endl;
#endif
  dat_.resize(ndat);

  // <histogram_non_zero_bucket_x_value>
  // <histogram_non_zero_bucket_x_offset>
  uint32_t count;   // profile count
  uint64_t offset;  // offset from load address
  for (unsigned int i = 0; i < ndat; ++i) {
    sz = hpc_fread_le4(&count, fp);        // count
    if (sz != sizeof(count)) { return 1; }

    sz = hpc_fread_le8(&offset, fp);       // offset
    if (sz != sizeof(offset)) { return 1; }
#ifdef DEBUG
  cerr << "  (cnt,offset)=(" << count << "," << offset << ")" << endl;
#endif

    pprof_off_t pc = load_addr + offset;
    dat_[i] = make_pair(pc, count);
  }

  return 0;
}

void
ProfFileEvent::dump(std::ostream& o, const char* pre) const
{
  string p = pre;
  string p1 = p + "  ";

  o << p << "{ ProfFileEvent: " << name() << ", period: " << period()
    << ", outofrange: " << outofrange() << ", overflow: " << overflow()
    << " }" << endl;

  for (unsigned int i = 0; i < num_data(); ++i) {
    const ProfFileEventDatum& dat = datum(i);
    o << p1 << "{ 0x" << hex << dat.first << ": " << dec
      << dat.second << " }" << endl;
  }
}

//***************************************************************************

static int
read_string(FILE *fp, std::string& str)
{
  size_t sz;
  uint32_t len; // string length
  int c;

  // <string_length> <string_without_terminator>
  sz = hpc_fread_le4(&len, fp);
  if (sz != sizeof(len)) { return 1; }

  str.resize(len);
  for (unsigned int n = 0; n < len; ++n) {
    if ((c = fgetc(fp)) == EOF) { return 1; }
    str[n] = (char)c;
  }
  return 0;
}

//***************************************************************************

#ifdef PROFREADER_TEST

int main(int argc, char **argv)
{
  std::string filename = argv[1];
  ProfFile f;

  int ret = f.read(filename);

  if (ret == 0) {
    cerr << "successfully read file!";
  } else {
    cerr << "error reading file!";
  }

  cout << "File dump:" << endl;
  f.dump(cout);
}

#endif
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (C) 2012-2016, Ryan P. Wilson
//
//      Authority FX, Inc.
//      www.authorityfx.com

#include <DDImage/Iop.h>
#include <DDImage/Row.h>
#include <DDImage/Knobs.h>
#include <DDImage/ImagePlane.h>
#include <DDImage/Thread.h>
#include <DDImage/NukeWrapper.h>

#include <stdexcept>

#include <boost/bind.hpp>
#include <math.h>

#include "threading.h"
#include "image.h"
#include "nuke_helper.h"
#include "mlaa.h"

// The class name must match exactly what is in the meny.py: nuke.createNode(CLASS)
static const char* CLASS = "AFXAntiAlias";
static const char* HELP = "Anti Alias";

#define ThisClass AFXAntiAlias

using namespace DD::Image;

class ThisClass : public Iop {
private:

  // members to store knob values
  float k_threshold_;

  // members to store processed knob values
  boost::mutex mutex_;
  bool first_time_CPU_;
  Lock lock_;

  afx::Bounds info_bnds, req_bnds_, format_bnds_, format_f_bnds_;
  float proxy_scale_;

  afx::ImageArray out_imgs_;

  afx::Threader threader_;

  void MetricsCPU(afx::Bounds region, const ImagePlane& source, const ImagePlane& matte, float* ref_hsv, double* sum_rgb, double* sum, double* sum_sqrs, unsigned int& num);
  void ProcessCPU(int y, int x, int r, ChannelMask channels, Row& row);

public:
  ThisClass(Node* node);
  void knobs(Knob_Callback);
  const char* Class() const;
  const char* node_help() const;
  static const Iop::Description d;

  void _validate(bool);
  void _request(int x, int y, int r, int t, ChannelMask channels, int count);
  void _open();
  void _close();
  void engine(int y, int x, int r, ChannelMask channels, Row& row);
};
ThisClass::ThisClass(Node* node) : Iop(node) {
  inputs(1);

  first_time_CPU_ = true;

  //initialize knobs
  k_threshold_ = 0.25f;
}
void ThisClass::knobs(Knob_Callback f) {

  Float_knob(f, &k_threshold_, "threshold", "Threshold");
  Tooltip(f, "Anti Alias Threshold");
  SetRange(f, 0.0, 1.0);

}
const char* ThisClass::Class() const { return CLASS; }
const char* ThisClass::node_help() const { return HELP; }
static Iop* build(Node* node) { return (new NukeWrapper(new ThisClass(node)))->channelsRGBoptionalAlpha(); }
const Op::Description ThisClass::d(CLASS, "AuthorityFX/AFX Anti Alias", build);

void ThisClass::_validate(bool) {
  copy_info(0);

  format_bnds_ = afx::BoxToBounds(input(0)->format());
  format_f_bnds_ = afx::BoxToBounds(input(0)->full_size_format());
  proxy_scale_ = (float)format_bnds_.GetWidth() / (float)format_f_bnds_.GetWidth();

  info_bnds = afx::BoxToBounds(info_.box());
}
void ThisClass::_request(int x, int y, int r, int t, ChannelMask channels, int count) {
  //Request source
  Box req_box(x + 50, + 50, r + 50, t + 50); //expand this
  input0().request(req_box, channels, count);
  req_bnds_.SetBounds(x, y, r - 1, t - 1);
}
void ThisClass::_open() {
  first_time_CPU_ = true;
}
void ThisClass::_close() {
  first_time_CPU_ = true;
  out_imgs_.Clear();
}
void ThisClass::engine(int y, int x, int r, ChannelMask channels, Row& row) {
  callCloseAfter(0);
  try {
    ProcessCPU(y, x, r, channels, row);
  } catch (std::exception const& e) {
    foreach (z, channels) {
      memset(row.writable(z) + x, 0, (r - x) * sizeof(float));
    }
  }
}
void ThisClass::ProcessCPU(int y, int x, int r, ChannelMask channels, Row& row) {
  afx::Bounds row_bnds(x, y, r - 1, y);

  if (first_time_CPU_) {
    Guard guard(lock_);
    if (first_time_CPU_) {
      afx::Bounds req_pad_bnds = req_bnds_.GetPadBounds(50);
      req_pad_bnds.Intersect(info_bnds);

      ImagePlane source_plane(afx::BoundsToBox(req_pad_bnds), false, channels); // Create plane "false" = non-packed.
      input0().fetchPlane(source_plane); // Fetch plane
      out_imgs_.Clear();
      afx::Image in_img(req_pad_bnds);
      foreach (z, source_plane.channels()) { // For each channel in plane
        in_img.MemCpyIn(&source_plane.readable()[source_plane.chanNo(z) * source_plane.chanStride()], source_plane.rowStride() * sizeof(float), in_img.GetBounds());
        out_imgs_.AddImage(req_pad_bnds);
        out_imgs_.GetBackPtr()->AddAttribute("channel", z);
        out_imgs_.GetBackPtr()->MemCpyIn(in_img.GetPtr(), in_img.GetPitch(), in_img.GetBounds());
        afx::MorphAA aa;
        aa.Process(in_img, *out_imgs_.GetBackPtr(), k_threshold_, threader_);
      }
      first_time_CPU_ = false;
    }
  } // End first time guard

  if (aborted()) { return; }

  foreach (z, channels) {
    afx::Image* plane_ptr = out_imgs_.GetPtrByAttribute("channel", z);
    plane_ptr->MemCpyOut(row.writable(z) + row_bnds.x1(), row_bnds.GetWidth() * sizeof(float), row_bnds);
//     float* out_ptr = row.writable(z) + row_bnds.x1();
//     for (int x = row_bnds.x1(); x <= row_bnds.x2(); ++x) {
//       *out_ptr++ = plane_ptr->GetVal(x, y);
//     }
  }
}
<commit_msg>Bounds issue<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (C) 2012-2016, Ryan P. Wilson
//
//      Authority FX, Inc.
//      www.authorityfx.com

#include <DDImage/Iop.h>
#include <DDImage/Row.h>
#include <DDImage/Knobs.h>
#include <DDImage/ImagePlane.h>
#include <DDImage/Thread.h>
#include <DDImage/NukeWrapper.h>

#include <stdexcept>

#include <boost/bind.hpp>
#include <math.h>

#include "threading.h"
#include "image.h"
#include "nuke_helper.h"
#include "mlaa.h"

// The class name must match exactly what is in the meny.py: nuke.createNode(CLASS)
static const char* CLASS = "AFXAntiAlias";
static const char* HELP = "Anti Alias";

#define ThisClass AFXAntiAlias

using namespace DD::Image;

class ThisClass : public Iop {
private:

  // members to store knob values
  float k_threshold_;

  // members to store processed knob values
  boost::mutex mutex_;
  bool first_time_CPU_;
  Lock lock_;

  afx::Bounds info_bnds, req_bnds_, format_bnds_, format_f_bnds_;
  float proxy_scale_;

  afx::ImageArray out_imgs_;

  afx::Threader threader_;

  void MetricsCPU(afx::Bounds region, const ImagePlane& source, const ImagePlane& matte, float* ref_hsv, double* sum_rgb, double* sum, double* sum_sqrs, unsigned int& num);
  void ProcessCPU(int y, int x, int r, ChannelMask channels, Row& row);

public:
  ThisClass(Node* node);
  void knobs(Knob_Callback);
  const char* Class() const;
  const char* node_help() const;
  static const Iop::Description d;

  void _validate(bool);
  void _request(int x, int y, int r, int t, ChannelMask channels, int count);
  void _open();
  void _close();
  void engine(int y, int x, int r, ChannelMask channels, Row& row);
};
ThisClass::ThisClass(Node* node) : Iop(node) {
  inputs(1);

  first_time_CPU_ = true;

  //initialize knobs
  k_threshold_ = 0.25f;
}
void ThisClass::knobs(Knob_Callback f) {

  Float_knob(f, &k_threshold_, "threshold", "Threshold");
  Tooltip(f, "Anti Alias Threshold");
  SetRange(f, 0.0, 1.0);

}
const char* ThisClass::Class() const { return CLASS; }
const char* ThisClass::node_help() const { return HELP; }
static Iop* build(Node* node) { return (new NukeWrapper(new ThisClass(node)))->channelsRGBoptionalAlpha(); }
const Op::Description ThisClass::d(CLASS, "AuthorityFX/AFX Anti Alias", build);

void ThisClass::_validate(bool) {
  copy_info(0);

  format_bnds_ = afx::BoxToBounds(input(0)->format());
  format_f_bnds_ = afx::BoxToBounds(input(0)->full_size_format());
  proxy_scale_ = (float)format_bnds_.GetWidth() / (float)format_f_bnds_.GetWidth();

}
void ThisClass::_request(int x, int y, int r, int t, ChannelMask channels, int count) {
  //Request source
  Box req_box(x + 50, + 50, r + 50, t + 50); //expand this
  input0().request(req_box, channels, count);
  req_bnds_.SetBounds(x, y, r - 1, t - 1);
}
void ThisClass::_open() {
  first_time_CPU_ = true;
}
void ThisClass::_close() {
  first_time_CPU_ = true;
  out_imgs_.Clear();
}
void ThisClass::engine(int y, int x, int r, ChannelMask channels, Row& row) {
  callCloseAfter(0);
  try {
    ProcessCPU(y, x, r, channels, row);
  } catch (std::exception const& e) {
    foreach (z, channels) {
      memset(row.writable(z) + x, 0, (r - x) * sizeof(float));
    }
  }
}
void ThisClass::ProcessCPU(int y, int x, int r, ChannelMask channels, Row& row) {
  afx::Bounds row_bnds(x, y, r - 1, y);

  if (first_time_CPU_) {
    Guard guard(lock_);
    if (first_time_CPU_) {
      afx::Bounds req_pad_bnds = req_bnds_.GetPadBounds(50);
      req_pad_bnds.Intersect(afx::BoxToBounds(input(0)->info().box()));

      ImagePlane source_plane(afx::BoundsToBox(req_pad_bnds), false, channels); // Create plane "false" = non-packed.
      input0().fetchPlane(source_plane); // Fetch plane
      out_imgs_.Clear();
      afx::Image in_img(req_pad_bnds);
      foreach (z, source_plane.channels()) { // For each channel in plane
        in_img.MemCpyIn(&source_plane.readable()[source_plane.chanNo(z) * source_plane.chanStride()], source_plane.rowStride() * sizeof(float), in_img.GetBounds());
        out_imgs_.AddImage(req_pad_bnds);
        out_imgs_.GetBackPtr()->AddAttribute("channel", z);
        out_imgs_.GetBackPtr()->MemCpyIn(in_img.GetPtr(), in_img.GetPitch(), in_img.GetBounds());
        afx::MorphAA aa;
        aa.Process(in_img, *out_imgs_.GetBackPtr(), k_threshold_, threader_);
      }
      first_time_CPU_ = false;
    }
  } // End first time guard

  if (aborted()) { return; }

  foreach (z, channels) {
    afx::Image* plane_ptr = out_imgs_.GetPtrByAttribute("channel", z);
    plane_ptr->MemCpyOut(row.writable(z) + row_bnds.x1(), row_bnds.GetWidth() * sizeof(float), row_bnds);
  }
}
<|endoftext|>


<commit_before>/*****************************************************************************
  intersectMain.cpp

  (c) 2009 - Aaron Quinlan
  Hall Laboratory
  Department of Biochemistry and Molecular Genetics
  University of Virginia
  aaronquinlan@gmail.com

  Licenced under the GNU General Public License 2.0 license.
******************************************************************************/
using namespace std;

#include "intersectFile.h"
#include "Context.h"

// define our program name
#define PROGRAM_NAME "bedtools intersect"

void intersect_help(void);

int intersect_main(int argc, char* argv[]) {

    Context *context = new Context();
    if (!context->parseCmdArgs(argc, argv, 1) || context->getShowHelp() || !context->isValidState()) {
    	if (!context->getErrorMsg().empty()) {
    		cerr << context->getErrorMsg() << endl;
    	}
    	intersect_help();
    	delete context;
    	return 0;
    }
	FileIntersect *fileIntersect = new FileIntersect(context);

	bool retVal = fileIntersect->intersectFiles();
	delete fileIntersect;
	delete context;
	return retVal ? 0 : 1;
}

void intersect_help(void) {

    cerr << "\nTool:    bedtools intersect (aka intersectBed)" << endl;
    cerr << "Version: " << VERSION << "\n";
    cerr << "Summary: Report overlaps between two feature files." << endl << endl;

    cerr << "Usage:   " << PROGRAM_NAME << " [OPTIONS] -a <bed/gff/vcf> -b <bed/gff/vcf>" << endl << endl;

    cerr << "Options: " << endl;

    cerr << "\t-abam\t"         << "The A input file is in BAM format.  Output will be BAM as well." << endl << endl;

    cerr << "\t-ubam\t"         << "Write uncompressed BAM output. Default writes compressed BAM." << endl << endl;

    cerr << "\t-bed\t"          << "When using BAM input (-abam), write output as BED. The default" << endl;
    cerr                        << "\t\tis to write output in BAM when using -abam." << endl << endl;

    cerr << "\t-wa\t"           << "Write the original entry in A for each overlap." << endl << endl;

    cerr << "\t-wb\t"           << "Write the original entry in B for each overlap." << endl;
    cerr                        << "\t\t- Useful for knowing _what_ A overlaps. Restricted by -f and -r." << endl << endl;

    cerr << "\t-loj\t"          << "Perform a \"left outer join\". That is, for each feature in A" << endl;
    cerr                        << "\t\treport each overlap with B.  If no overlaps are found, " << endl;
    cerr                        << "\t\treport a NULL feature for B." << endl << endl;

    cerr << "\t-wo\t"           << "Write the original A and B entries plus the number of base" << endl;
    cerr                        << "\t\tpairs of overlap between the two features." << endl;
    cerr                        << "\t\t- Overlaps restricted by -f and -r." << endl;
    cerr                        << "\t\t  Only A features with overlap are reported." << endl << endl;

    cerr << "\t-wao\t"          << "Write the original A and B entries plus the number of base" << endl;
    cerr                        << "\t\tpairs of overlap between the two features." << endl;
    cerr                        << "\t\t- Overlapping features restricted by -f and -r." << endl;
    cerr                        << "\t\t  However, A features w/o overlap are also reported" << endl;
    cerr                        << "\t\t  with a NULL B feature and overlap = 0." << endl << endl;

    cerr << "\t-u\t"            << "Write the original A entry _once_ if _any_ overlaps found in B." << endl;
    cerr                        << "\t\t- In other words, just report the fact >=1 hit was found." << endl;
    cerr                        << "\t\t- Overlaps restricted by -f and -r." << endl << endl;

    cerr << "\t-c\t"            << "For each entry in A, report the number of overlaps with B." << endl;
    cerr                        << "\t\t- Reports 0 for A entries that have no overlap with B." << endl;
    cerr                        << "\t\t- Overlaps restricted by -f and -r." << endl << endl;

    cerr << "\t-v\t"            << "Only report those entries in A that have _no overlaps_ with B." << endl;
    cerr                        << "\t\t- Similar to \"grep -v\" (an homage)." << endl << endl;

    cerr << "\t-f\t"            << "Minimum overlap required as a fraction of A." << endl;
    cerr                        << "\t\t- Default is 1E-9 (i.e., 1bp)." << endl;
    cerr                        << "\t\t- FLOAT (e.g. 0.50)" << endl << endl;

    cerr << "\t-r\t"            << "Require that the fraction overlap be reciprocal for A and B." << endl;
    cerr                        << "\t\t- In other words, if -f is 0.90 and -r is used, this requires" << endl;
    cerr                        << "\t\t  that B overlap 90% of A and A _also_ overlaps 90% of B." << endl << endl;

    cerr << "\t-s\t"            << "Require same strandedness.  That is, only report hits in B" << endl;
    cerr                        << "\t\tthat overlap A on the _same_ strand." << endl;
    cerr                        << "\t\t- By default, overlaps are reported without respect to strand." << endl << endl;

    cerr << "\t-S\t"            << "Require different strandedness.  That is, only report hits in B" << endl;
    cerr                        << "\t\tthat overlap A on the _opposite_ strand." << endl;
    cerr                        << "\t\t- By default, overlaps are reported without respect to strand." << endl << endl;

    cerr << "\t-split\t"        << "Treat \"split\" BAM or BED12 entries as distinct BED intervals." << endl << endl;

    cerr << "\t-sorted\t"       << "Use the \"chromsweep\" algorithm for sorted (-k1,1 -k2,2n) input." << endl << endl;

    cerr << "\t-g\t"       		<< "Provide a genome file to enforce consistent chromosome sort order" << endl;
    cerr 						<<"\t\tacross input files. Only applies when used with -sorted option." << endl << endl;

    cerr << "\t-header\t"       << "Print the header from the A file prior to results." << endl << endl;

    cerr << "Notes: " << endl;
    cerr << "\t(1) When a BAM file is used for the A file, the alignment is retained if overlaps exist," << endl;
    cerr << "\tand exlcuded if an overlap cannot be found.  If multiple overlaps exist, they are not" << endl;
    cerr << "\treported, as we are only testing for one or more overlaps." << endl << endl;

    // end the program here
    exit(1);

}
<commit_msg>Added -nobuf option and definition to intersect help menu.<commit_after>/*****************************************************************************
  intersectMain.cpp

  (c) 2009 - Aaron Quinlan
  Hall Laboratory
  Department of Biochemistry and Molecular Genetics
  University of Virginia
  aaronquinlan@gmail.com

  Licenced under the GNU General Public License 2.0 license.
******************************************************************************/
using namespace std;

#include "intersectFile.h"
#include "Context.h"

// define our program name
#define PROGRAM_NAME "bedtools intersect"

void intersect_help(void);

int intersect_main(int argc, char* argv[]) {

    Context *context = new Context();
    if (!context->parseCmdArgs(argc, argv, 1) || context->getShowHelp() || !context->isValidState()) {
    	if (!context->getErrorMsg().empty()) {
    		cerr << context->getErrorMsg() << endl;
    	}
    	intersect_help();
    	delete context;
    	return 0;
    }
	FileIntersect *fileIntersect = new FileIntersect(context);

	bool retVal = fileIntersect->intersectFiles();
	delete fileIntersect;
	delete context;
	return retVal ? 0 : 1;
}

void intersect_help(void) {

    cerr << "\nTool:    bedtools intersect (aka intersectBed)" << endl;
    cerr << "Version: " << VERSION << "\n";
    cerr << "Summary: Report overlaps between two feature files." << endl << endl;

    cerr << "Usage:   " << PROGRAM_NAME << " [OPTIONS] -a <bed/gff/vcf> -b <bed/gff/vcf>" << endl << endl;

    cerr << "Options: " << endl;

    cerr << "\t-abam\t"         << "The A input file is in BAM format.  Output will be BAM as well." << endl << endl;

    cerr << "\t-ubam\t"         << "Write uncompressed BAM output. Default writes compressed BAM." << endl << endl;

    cerr << "\t-bed\t"          << "When using BAM input (-abam), write output as BED. The default" << endl;
    cerr                        << "\t\tis to write output in BAM when using -abam." << endl << endl;

    cerr << "\t-wa\t"           << "Write the original entry in A for each overlap." << endl << endl;

    cerr << "\t-wb\t"           << "Write the original entry in B for each overlap." << endl;
    cerr                        << "\t\t- Useful for knowing _what_ A overlaps. Restricted by -f and -r." << endl << endl;

    cerr << "\t-loj\t"          << "Perform a \"left outer join\". That is, for each feature in A" << endl;
    cerr                        << "\t\treport each overlap with B.  If no overlaps are found, " << endl;
    cerr                        << "\t\treport a NULL feature for B." << endl << endl;

    cerr << "\t-wo\t"           << "Write the original A and B entries plus the number of base" << endl;
    cerr                        << "\t\tpairs of overlap between the two features." << endl;
    cerr                        << "\t\t- Overlaps restricted by -f and -r." << endl;
    cerr                        << "\t\t  Only A features with overlap are reported." << endl << endl;

    cerr << "\t-wao\t"          << "Write the original A and B entries plus the number of base" << endl;
    cerr                        << "\t\tpairs of overlap between the two features." << endl;
    cerr                        << "\t\t- Overlapping features restricted by -f and -r." << endl;
    cerr                        << "\t\t  However, A features w/o overlap are also reported" << endl;
    cerr                        << "\t\t  with a NULL B feature and overlap = 0." << endl << endl;

    cerr << "\t-u\t"            << "Write the original A entry _once_ if _any_ overlaps found in B." << endl;
    cerr                        << "\t\t- In other words, just report the fact >=1 hit was found." << endl;
    cerr                        << "\t\t- Overlaps restricted by -f and -r." << endl << endl;

    cerr << "\t-c\t"            << "For each entry in A, report the number of overlaps with B." << endl;
    cerr                        << "\t\t- Reports 0 for A entries that have no overlap with B." << endl;
    cerr                        << "\t\t- Overlaps restricted by -f and -r." << endl << endl;

    cerr << "\t-v\t"            << "Only report those entries in A that have _no overlaps_ with B." << endl;
    cerr                        << "\t\t- Similar to \"grep -v\" (an homage)." << endl << endl;

    cerr << "\t-f\t"            << "Minimum overlap required as a fraction of A." << endl;
    cerr                        << "\t\t- Default is 1E-9 (i.e., 1bp)." << endl;
    cerr                        << "\t\t- FLOAT (e.g. 0.50)" << endl << endl;

    cerr << "\t-r\t"            << "Require that the fraction overlap be reciprocal for A and B." << endl;
    cerr                        << "\t\t- In other words, if -f is 0.90 and -r is used, this requires" << endl;
    cerr                        << "\t\t  that B overlap 90% of A and A _also_ overlaps 90% of B." << endl << endl;

    cerr << "\t-s\t"            << "Require same strandedness.  That is, only report hits in B" << endl;
    cerr                        << "\t\tthat overlap A on the _same_ strand." << endl;
    cerr                        << "\t\t- By default, overlaps are reported without respect to strand." << endl << endl;

    cerr << "\t-S\t"            << "Require different strandedness.  That is, only report hits in B" << endl;
    cerr                        << "\t\tthat overlap A on the _opposite_ strand." << endl;
    cerr                        << "\t\t- By default, overlaps are reported without respect to strand." << endl << endl;

    cerr << "\t-split\t"        << "Treat \"split\" BAM or BED12 entries as distinct BED intervals." << endl << endl;

    cerr << "\t-sorted\t"       << "Use the \"chromsweep\" algorithm for sorted (-k1,1 -k2,2n) input." << endl << endl;

    cerr << "\t-g\t"       		<< "Provide a genome file to enforce consistent chromosome sort order" << endl;
    cerr 						<<"\t\tacross input files. Only applies when used with -sorted option." << endl << endl;

    cerr << "\t-header\t"       << "Print the header from the A file prior to results." << endl << endl;

    cerr << "\t-nobuf\t"       << "Disable buffered output. Using this option will cause each line"<< endl;
    cerr 						<<"\t\tof output to be printed as it is generated, rather than saved" << endl;
    cerr 						<<"\t\tin a buffer. This will make printing large output files " << endl;

    cerr 						<<"\t\tnoticeably slower, but can be useful in conjunction with" << endl;
    cerr 						<<"\t\tother software tools and scripts that need to process one" << endl;
    cerr 						<<"\t\tline of bedtools output at a time." << endl << endl;

    cerr << "Notes: " << endl;
    cerr << "\t(1) When a BAM file is used for the A file, the alignment is retained if overlaps exist," << endl;
    cerr << "\tand exlcuded if an overlap cannot be found.  If multiple overlaps exist, they are not" << endl;
    cerr << "\treported, as we are only testing for one or more overlaps." << endl << endl;

    // end the program here
    exit(1);

}
<|endoftext|>