<commit_before>/**
 * @file radon.cpp
 *
 * @date Oct 28, 2012
 * @author tack
 */

#include "radon.h"
#include "logger_factory.h"
#include "plugin_factory.h"
#include <thread>
#include <sstream>
#include "util.h"
#include "unistd.h" // getuid())
#include "regular_grid.h"

using namespace std;
using namespace himan::plugin;

const int MAX_WORKERS = 16;
once_flag oflag;

radon::radon() : itsInit(false), itsRadonDB()
{
	itsLogger = unique_ptr<logger> (logger_factory::Instance()->GetLog("radon"));

	// no lambda functions for gcc 4.4 :(
	// call_once(oflag, [](){ NFmiNeonsDBPool::MaxWorkers(MAX_WORKERS); });

	call_once(oflag, &himan::plugin::radon::InitPool, this);
}

void radon::InitPool()
{
	NFmiRadonDBPool::Instance()->MaxWorkers(MAX_WORKERS);

	uid_t uid = getuid();

	if (uid == 1459) // weto
	{
		char* base = getenv("MASALA_BASE");

		if (string(base) == "/masala")
		{
			NFmiRadonDBPool::Instance()->Username("wetodb");
			NFmiRadonDBPool::Instance()->Password("3loHRgdio");
		}
		else
		{
			itsLogger->Warning("Program executed as uid 1459 ('weto') but MASALA_BASE not set");
		}
	}
}

vector<string> radon::Files(search_options& options)
{

	Init();

	vector<string> files;

	string analtime = options.time.OriginDateTime().String("%Y-%m-%d %H:%M:%S+00");
	string levelvalue = boost::lexical_cast<string> (options.level.Value());

	string ref_prod = options.prod.Name();
	// long no_vers = options.prod.TableVersion();

	string level_name = HPLevelTypeToString.at(options.level.Type());

	vector<vector<string> > gridgeoms;
	vector<string> sourceGeoms = options.configuration->SourceGeomNames();

	if (sourceGeoms.empty())
	{
		// Get all geometries
		gridgeoms = itsRadonDB->GetGridGeoms(ref_prod, analtime);
	}
	else
	{
		for (size_t i = 0; i < sourceGeoms.size(); i++)
		{
			vector<vector<string>> geoms = itsRadonDB->GetGridGeoms(ref_prod, analtime, sourceGeoms[i]);
			gridgeoms.insert(gridgeoms.end(), geoms.begin(), geoms.end());
		}
	}

	if (gridgeoms.empty())
	{
		itsLogger->Warning("No geometries found for producer " + ref_prod +
		", analysistime " + analtime + ", source geom name(s) '" + util::Join(sourceGeoms, ",") +"', param " + options.param.Name());

		return files;
	}

	for (size_t i = 0; i < gridgeoms.size(); i++)
	{
		string tablename = gridgeoms[i][1];
		string geomid = gridgeoms[i][0];

		string parm_name = options.param.Name();

		string query = "SELECT param_id, level_id, level_value, forecast_period, file_location, file_server "
				   "FROM "+tablename+"_v "
				   "WHERE analysis_time = '"+analtime+"' "
				   "AND param_name = '"+parm_name+"' "
				   "AND level_name = upper('"+level_name+"') "
				   "AND level_value = "+levelvalue+" "
				   "AND forecast_period = '"+util::MakeSQLInterval(options.time)+"' "
				   "AND geometry_id = "+geomid+" "
				   "ORDER BY forecast_period, level_id, level_value";

		itsRadonDB->Query(query);

		vector<string> values = itsRadonDB->FetchRow();

		if (values.empty())
		{
			continue;
		}

		itsLogger->Trace("Found data for parameter " + parm_name + " from radon geometry " + gridgeoms[i][3]);

		files.push_back(values[4]);

		break; // discontinue loop on first positive match

	}

	return files;

}

bool radon::Save(const info& resultInfo, const string& theFileName)
{

	Init();

	stringstream query;

    if (resultInfo.Grid()->Type() != kRegularGrid)
    {
        itsLogger->Error("Only grid data can be stored to radon for now");
        return false;
    }

    const regular_grid* g = dynamic_cast<regular_grid*> (resultInfo.Grid());

	/*
	 * 1. Get grid information
	 * 2. Get model information
	 * 3. Get data set information (ie model run)
	 * 4. Insert or update
	 */

    himan::point firstGridPoint = g->FirstGridPoint();

	/*
	 * pas_latitude and pas_longitude cannot be checked programmatically
	 * since f.ex. in the case for GFS in radon we have value 500 and
	 * by calculating we have value 498. But not check these columns should
	 * not matter as long as row_cnt, col_cnt, lat_orig and lon_orig match
	 * (since pas_latitude and pas_longitude are derived from these anyway)
	 */

	query 	<< "SELECT geom_id "
			<< "FROM geom_v "
			<< "WHERE nj = " << g->Nj()
			<< " AND ni = " << g->Ni()
			<< " AND first_lat = " << (firstGridPoint.Y() * 1e-2)
			<< " AND first_lon = " << (firstGridPoint.X() * 1e-2);

	itsRadonDB->Query(query.str());

	vector<string> row;

	row = itsRadonDB->FetchRow();

	if (row.empty())
	{
		itsLogger->Warning("Grid geometry not found from radon");
		return false;
	}

	string geom_id = row[0];

	query.str("");

	query	<< "SELECT "
			<< "id, table_name "
			<< "FROM as_grid "
			<< "WHERE geometry_id = '" << geom_id << "'"
			<< " AND analysis_time = '" << resultInfo.OriginDateTime().String("%Y-%m-%d %H:%M:%S+00") << "'"
			<< " AND producer_id = " << resultInfo.Producer().Id();

	itsRadonDB->Query(query.str());

	row = itsRadonDB->FetchRow();

	if (row.empty())
	{
		itsLogger->Warning("Data set definition not found from radon");
		return false;
	}

	string table_name = row[1];
	string dset_id = row[0];

	string eps_specifier = "0";

	query.str("");

	string host = "undetermined host";

	char* hostname = getenv("HOSTNAME");

	if (hostname != NULL)
	{
		host = string(hostname);
	}

	/*
	 * We have our own error loggings for unique key violations
	 */

	// itsRadonDB->Verbose(false);
	query  << "INSERT INTO data." << table_name
		   << " (producer_id, analysis_time, geometry_id, param_id, level_id, level_value, forecast_period, forecast_type_id, file_location, file_server) "
		   << "SELECT " << resultInfo.Producer().Id() << ", "
		   << "'" << resultInfo.OriginDateTime().String("%Y-%m-%d %H:%M:%S+00") << "', "
		   << "'" << geom_id << "', "
		   << "param.id, level.id, "
		   << resultInfo.Level().Value() << ", "
		   << "'" << util::MakeSQLInterval(resultInfo.Time()) << "', "
		   << "1, "
		   << "'" << theFileName << "', "
		   << "'" << host << "' "
		   << "FROM param, level "
		   << "WHERE param.name = '" << resultInfo.Param().Name() << "' "
		   << "AND level.name = upper('" << HPLevelTypeToString.at(resultInfo.Level().Type()) << "')";

	try
	{
		itsRadonDB->Execute(query.str());
		itsRadonDB->Commit();
	}
	catch (int e)
	{
		itsLogger->Error("Error code: " + boost::lexical_cast<string> (e));
		itsLogger->Error("Query: " + query.str());

		itsRadonDB->Rollback();

		return false;
	}

	itsLogger->Trace("Saved information on file '" + theFileName + "' to radon");

	return true;
}

map<string,string> radon::Grib1ParameterName(long producer, long fmiParameterId, long codeTableVersion, long timeRangeIndicator, long levelId, double level_value)
{
	Init();

	map<string,string> paramName = itsRadonDB->GetParameterFromGrib1(producer, codeTableVersion, fmiParameterId, timeRangeIndicator, levelId, level_value);
	return paramName;
}

map<string,string> radon::Grib2ParameterName(long fmiParameterId, long category, long discipline, long producer, long levelId, double level_value)
{
	Init();

	map<string,string> paramName = itsRadonDB->GetParameterFromGrib2(producer, discipline, category, fmiParameterId, levelId, level_value);
	return paramName;
}

string radon::ProducerMetaData(long producerId, const string& attribute) const
{
	string ret;

	if (attribute == "last hybrid level number")
	{
		switch (producerId)
		{
			case 1:
			case 199:
			case 210:
			case 230:
				ret = "65";
			break;

			case 131:
			case 240:
				ret = "137";
				break;

			default:
				throw runtime_error(ClassName() + ": Producer not supported");
				break;

		}
	}
	else if (attribute == "first hybrid level number")
	{
		switch (producerId)
		{
			case 1:
			case 199:
			case 210:
			case 230:
				ret = "1";
				break;

			case 131:
			case 240:
				ret = "24";
				break;

			default:
				throw runtime_error(ClassName() + ": Producer not supported");
				break;

		}
	}
	else
	{
		throw runtime_error(ClassName() + ": Attribute not recognized");
	}

	return ret;

	// In the future maybe something like this:

	//Init();

	//string query = "SELECT value FROM producers_eav WHERE producer_id = " + boost::lexical_cast<string> (producerId) + " AND attribute = '" + attribute + "'";
}

<commit_msg>geom table changes<commit_after>/**
 * @file radon.cpp
 *
 * @date Oct 28, 2012
 * @author tack
 */

#include "radon.h"
#include "logger_factory.h"
#include "plugin_factory.h"
#include <thread>
#include <sstream>
#include "util.h"
#include "unistd.h" // getuid())
#include "regular_grid.h"

using namespace std;
using namespace himan::plugin;

const int MAX_WORKERS = 16;
once_flag oflag;

radon::radon() : itsInit(false), itsRadonDB()
{
	itsLogger = unique_ptr<logger> (logger_factory::Instance()->GetLog("radon"));

	// no lambda functions for gcc 4.4 :(
	// call_once(oflag, [](){ NFmiNeonsDBPool::MaxWorkers(MAX_WORKERS); });

	call_once(oflag, &himan::plugin::radon::InitPool, this);
}

void radon::InitPool()
{
	NFmiRadonDBPool::Instance()->MaxWorkers(MAX_WORKERS);

	uid_t uid = getuid();

	if (uid == 1459) // weto
	{
		char* base = getenv("MASALA_BASE");

		if (string(base) == "/masala")
		{
			NFmiRadonDBPool::Instance()->Username("wetodb");
			NFmiRadonDBPool::Instance()->Password("3loHRgdio");
		}
		else
		{
			itsLogger->Warning("Program executed as uid 1459 ('weto') but MASALA_BASE not set");
		}
	}
}

vector<string> radon::Files(search_options& options)
{

	Init();

	vector<string> files;

	string analtime = options.time.OriginDateTime().String("%Y-%m-%d %H:%M:%S+00");
	string levelvalue = boost::lexical_cast<string> (options.level.Value());

	string ref_prod = options.prod.Name();
	// long no_vers = options.prod.TableVersion();

	string level_name = HPLevelTypeToString.at(options.level.Type());

	vector<vector<string> > gridgeoms;
	vector<string> sourceGeoms = options.configuration->SourceGeomNames();

	if (sourceGeoms.empty())
	{
		// Get all geometries
		gridgeoms = itsRadonDB->GetGridGeoms(ref_prod, analtime);
	}
	else
	{
		for (size_t i = 0; i < sourceGeoms.size(); i++)
		{
			vector<vector<string>> geoms = itsRadonDB->GetGridGeoms(ref_prod, analtime, sourceGeoms[i]);
			gridgeoms.insert(gridgeoms.end(), geoms.begin(), geoms.end());
		}
	}

	if (gridgeoms.empty())
	{
		itsLogger->Warning("No geometries found for producer " + ref_prod +
		", analysistime " + analtime + ", source geom name(s) '" + util::Join(sourceGeoms, ",") +"', param " + options.param.Name());

		return files;
	}

	for (size_t i = 0; i < gridgeoms.size(); i++)
	{
		string tablename = gridgeoms[i][1];
		string geomid = gridgeoms[i][0];

		string parm_name = options.param.Name();

		string query = "SELECT param_id, level_id, level_value, forecast_period, file_location, file_server "
				   "FROM "+tablename+"_v "
				   "WHERE analysis_time = '"+analtime+"' "
				   "AND param_name = '"+parm_name+"' "
				   "AND level_name = upper('"+level_name+"') "
				   "AND level_value = "+levelvalue+" "
				   "AND forecast_period = '"+util::MakeSQLInterval(options.time)+"' "
				   "AND geometry_id = "+geomid+" "
				   "ORDER BY forecast_period, level_id, level_value";

		itsRadonDB->Query(query);

		vector<string> values = itsRadonDB->FetchRow();

		if (values.empty())
		{
			continue;
		}

		itsLogger->Trace("Found data for parameter " + parm_name + " from radon geometry " + gridgeoms[i][3]);

		files.push_back(values[4]);

		break; // discontinue loop on first positive match

	}

	return files;

}

bool radon::Save(const info& resultInfo, const string& theFileName)
{

	Init();

	stringstream query;

	if (resultInfo.Grid()->Type() != kRegularGrid)
	{
		itsLogger->Error("Only grid data can be stored to radon for now");
		return false;
	}

	const regular_grid* g = dynamic_cast<regular_grid*> (resultInfo.Grid());

	/*
	 * 1. Get grid information
	 * 2. Get model information
	 * 3. Get data set information (ie model run)
	 * 4. Insert or update
	 */

	himan::point firstGridPoint = g->FirstGridPoint();

	/*
	 * pas_latitude and pas_longitude cannot be checked programmatically
	 * since f.ex. in the case for GFS in radon we have value 500 and
	 * by calculating we have value 498. But not check these columns should
	 * not matter as long as row_cnt, col_cnt, lat_orig and lon_orig match
	 * (since pas_latitude and pas_longitude are derived from these anyway)
	 */

	query 	<< "SELECT geometry_id "
			<< "FROM geom_v "
			<< "WHERE nj = " << g->Nj()
			<< " AND ni = " << g->Ni()
			<< " AND first_lat = " << firstGridPoint.Y()
			<< " AND first_lon = " << firstGridPoint.X();

	itsRadonDB->Query(query.str());

	vector<string> row;

	row = itsRadonDB->FetchRow();

	if (row.empty())
	{
		itsLogger->Warning("Grid geometry not found from radon");
		return false;
	}

	string geom_id = row[0];

	query.str("");

	query	<< "SELECT "
			<< "id, table_name "
			<< "FROM as_grid "
			<< "WHERE geometry_id = '" << geom_id << "'"
			<< " AND analysis_time = '" << resultInfo.OriginDateTime().String("%Y-%m-%d %H:%M:%S+00") << "'"
			<< " AND producer_id = " << resultInfo.Producer().Id();

	itsRadonDB->Query(query.str());

	row = itsRadonDB->FetchRow();

	if (row.empty())
	{
		itsLogger->Warning("Data set definition not found from radon");
		return false;
	}

	string table_name = row[1];
	string dset_id = row[0];

	string eps_specifier = "0";

	query.str("");

	string host = "undetermined host";

	char* hostname = getenv("HOSTNAME");

	if (hostname != NULL)
	{
		host = string(hostname);
	}

	/*
	 * We have our own error loggings for unique key violations
	 */

	// itsRadonDB->Verbose(false);
	query  << "INSERT INTO data." << table_name
		   << " (producer_id, analysis_time, geometry_id, param_id, level_id, level_value, forecast_period, forecast_type_id, file_location, file_server) "
		   << "SELECT " << resultInfo.Producer().Id() << ", "
		   << "'" << resultInfo.OriginDateTime().String("%Y-%m-%d %H:%M:%S+00") << "', "
		   << "'" << geom_id << "', "
		   << "param.id, level.id, "
		   << resultInfo.Level().Value() << ", "
		   << "'" << util::MakeSQLInterval(resultInfo.Time()) << "', "
		   << "1, "
		   << "'" << theFileName << "', "
		   << "'" << host << "' "
		   << "FROM param, level "
		   << "WHERE param.name = '" << resultInfo.Param().Name() << "' "
		   << "AND level.name = upper('" << HPLevelTypeToString.at(resultInfo.Level().Type()) << "')";

	try
	{
		itsRadonDB->Execute(query.str());
		itsRadonDB->Commit();
	}
	catch (int e)
	{
		itsLogger->Error("Error code: " + boost::lexical_cast<string> (e));
		itsLogger->Error("Query: " + query.str());

		itsRadonDB->Rollback();

		return false;
	}

	itsLogger->Trace("Saved information on file '" + theFileName + "' to radon");

	return true;
}

map<string,string> radon::Grib1ParameterName(long producer, long fmiParameterId, long codeTableVersion, long timeRangeIndicator, long levelId, double level_value)
{
	Init();

	map<string,string> paramName = itsRadonDB->GetParameterFromGrib1(producer, codeTableVersion, fmiParameterId, timeRangeIndicator, levelId, level_value);
	return paramName;
}

map<string,string> radon::Grib2ParameterName(long fmiParameterId, long category, long discipline, long producer, long levelId, double level_value)
{
	Init();

	map<string,string> paramName = itsRadonDB->GetParameterFromGrib2(producer, discipline, category, fmiParameterId, levelId, level_value);
	return paramName;
}

string radon::ProducerMetaData(long producerId, const string& attribute) const
{
	string ret;

	if (attribute == "last hybrid level number")
	{
		switch (producerId)
		{
			case 1:
			case 199:
			case 210:
			case 230:
				ret = "65";
			break;

			case 131:
			case 240:
				ret = "137";
				break;

			default:
				throw runtime_error(ClassName() + ": Producer not supported");
				break;

		}
	}
	else if (attribute == "first hybrid level number")
	{
		switch (producerId)
		{
			case 1:
			case 199:
			case 210:
			case 230:
				ret = "1";
				break;

			case 131:
			case 240:
				ret = "24";
				break;

			default:
				throw runtime_error(ClassName() + ": Producer not supported");
				break;

		}
	}
	else
	{
		throw runtime_error(ClassName() + ": Attribute not recognized");
	}

	return ret;

	// In the future maybe something like this:

	//Init();

	//string query = "SELECT value FROM producers_eav WHERE producer_id = " + boost::lexical_cast<string> (producerId) + " AND attribute = '" + attribute + "'";
}

<|endoftext|>


<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <sys/types.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>

extern "C" {

typedef void * (*mmap_function) (void *addr, size_t length, int prot, int flags, int fd, off_t offset);
typedef void * (*mmap64_function) (void *addr, size_t length, int prot, int flags, int fd, off64_t offset);
typedef int (*munmap_function) (void *addr, size_t length);

void * local_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) __asm__("mmap");
void * local_mmap64(void *addr, size_t length, int prot, int flags, int fd, off64_t offset) __asm__("mmap64");
int munmap(void *addr, size_t length) __asm__("munmap");

// This is a dirty prototype of an internal, yet visible method in libc that avoids
// allocations as they will cause a loop when used with vespamalloc.
void *_dl_sym (void *handle, const char *name, void *who);

static size_t getLogLimit()
{
    static size_t LogLimit = -2l;
    if (LogLimit == static_cast<size_t>(-2l)) {
        const char * s = getenv("VESPA_MMAP_BIGBLOCK_LOGLIMIT");
        if (s) {
            LogLimit = strtoul(s, NULL, 0);
        } else {
            LogLimit = -1l;
        }
    }
    return LogLimit;
}

const size_t MagicVespaMallocStartOfHeap = 0x100000000;
const size_t MagicVespaMallocStartOfHeapFilter = 0xffffffff00000000ul;

static bool isFromVespaMalloc(const void * addr)
{
    size_t v(reinterpret_cast<size_t>(addr));
    return (v & MagicVespaMallocStartOfHeapFilter) == MagicVespaMallocStartOfHeap;
}

void * local_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
    static mmap_function real_func = NULL;
    // This is a dirty trick for use with vespamalloc as there can be
    // no allocations before the initial mmap from vespamalloc has succeded.
    if (real_func == NULL) {
        real_func = (mmap_function) _dl_sym (RTLD_NEXT, "mmap", __builtin_return_address (0));
        if (real_func == NULL) {
            fprintf (stderr, "Could not find the mmap function!\n");
            abort();
        }
    }
    if ((length >= getLogLimit()) && !isFromVespaMalloc(addr)) {
        fprintf (stderr, "mmap requesting block of size %ld from %s\n", length, "no backtrace");
    }
    return (*real_func)(addr, length, prot, flags, fd, offset);
}

void * local_mmap64(void *addr, size_t length, int prot, int flags, int fd, off64_t offset)
{
    static mmap64_function real_func = NULL;
    if (real_func == NULL) {
        real_func = (mmap64_function) dlsym (RTLD_NEXT, "mmap64");
        if (real_func == NULL) {
            fprintf (stderr, "Could not find the mmap64 function!\n");
            abort();
        }
    }
    if (length >= getLogLimit() && !isFromVespaMalloc(addr)) {
        fprintf (stderr, "mmap requesting block of size %ld from %s\n", length, "no backtrace");
    }
    return (*real_func)(addr, length, prot, flags, fd, offset);
}

int local_munmap(void *addr, size_t length)
{
    static munmap_function real_func = NULL;
    if (real_func == NULL) {
        real_func = (munmap_function) dlsym (RTLD_NEXT, "munmap");
        if (real_func == NULL) {
            fprintf (stderr, "Could not find the munmap function!\n");
            abort();
        }
    }
    if ((length >= getLogLimit()) && !isFromVespaMalloc(addr)) {
        fprintf (stderr, "munmap releasing block of size %ld from %s\n", length, "no backtrace");
    }
    return (*real_func)(addr, length);
}

}
<commit_msg>Use dlsym() to get original mmap function address from libc.<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <sys/types.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>

extern "C" {

typedef void * (*mmap_function) (void *addr, size_t length, int prot, int flags, int fd, off_t offset);
typedef void * (*mmap64_function) (void *addr, size_t length, int prot, int flags, int fd, off64_t offset);
typedef int (*munmap_function) (void *addr, size_t length);

void * local_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) __asm__("mmap");
void * local_mmap64(void *addr, size_t length, int prot, int flags, int fd, off64_t offset) __asm__("mmap64");
int munmap(void *addr, size_t length) __asm__("munmap");

// This is a dirty prototype of an internal, yet visible method in libc that avoids
// allocations as they will cause a loop when used with vespamalloc.
void *_dl_sym (void *handle, const char *name, void *who);

static size_t getLogLimit()
{
    static size_t LogLimit = -2l;
    if (LogLimit == static_cast<size_t>(-2l)) {
        const char * s = getenv("VESPA_MMAP_BIGBLOCK_LOGLIMIT");
        if (s) {
            LogLimit = strtoul(s, NULL, 0);
        } else {
            LogLimit = -1l;
        }
    }
    return LogLimit;
}

const size_t MagicVespaMallocStartOfHeap = 0x100000000;
const size_t MagicVespaMallocStartOfHeapFilter = 0xffffffff00000000ul;

static bool isFromVespaMalloc(const void * addr)
{
    size_t v(reinterpret_cast<size_t>(addr));
    return (v & MagicVespaMallocStartOfHeapFilter) == MagicVespaMallocStartOfHeap;
}

void * local_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
    static mmap_function real_func = NULL;
    if (real_func == NULL) {
        real_func = (mmap_function) dlsym (RTLD_NEXT, "mmap");
        if (real_func == NULL) {
            fprintf (stderr, "Could not find the mmap function!\n");
            abort();
        }
    }
    if ((length >= getLogLimit()) && !isFromVespaMalloc(addr)) {
        fprintf (stderr, "mmap requesting block of size %ld from %s\n", length, "no backtrace");
    }
    return (*real_func)(addr, length, prot, flags, fd, offset);
}

void * local_mmap64(void *addr, size_t length, int prot, int flags, int fd, off64_t offset)
{
    static mmap64_function real_func = NULL;
    if (real_func == NULL) {
        real_func = (mmap64_function) dlsym (RTLD_NEXT, "mmap64");
        if (real_func == NULL) {
            fprintf (stderr, "Could not find the mmap64 function!\n");
            abort();
        }
    }
    if (length >= getLogLimit() && !isFromVespaMalloc(addr)) {
        fprintf (stderr, "mmap requesting block of size %ld from %s\n", length, "no backtrace");
    }
    return (*real_func)(addr, length, prot, flags, fd, offset);
}

int local_munmap(void *addr, size_t length)
{
    static munmap_function real_func = NULL;
    if (real_func == NULL) {
        real_func = (munmap_function) dlsym (RTLD_NEXT, "munmap");
        if (real_func == NULL) {
            fprintf (stderr, "Could not find the munmap function!\n");
            abort();
        }
    }
    if ((length >= getLogLimit()) && !isFromVespaMalloc(addr)) {
        fprintf (stderr, "munmap releasing block of size %ld from %s\n", length, "no backtrace");
    }
    return (*real_func)(addr, length);
}

}
<|endoftext|>


<commit_before>/*******************************************************************************
 * c7a/core/reduce_post_table.hpp
 *
 * Hash table with support for reduce and partitions.
 *
 * Part of Project c7a.
 *
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_CORE_REDUCE_POST_TABLE_HEADER
#define C7A_CORE_REDUCE_POST_TABLE_HEADER

#include <c7a/api/function_traits.hpp>
#include <c7a/data/manager.hpp>
#include <c7a/common/logger.hpp>

#include <map>
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include <array>

namespace c7a {
namespace core {

template <typename KeyExtractor, typename ReduceFunction, typename EmitterFunction>
class ReducePostTable
{
    static const bool debug = false;

    // TODO(ms): according to coding style: Types are CamelCase.
    using key_t = typename FunctionTraits<KeyExtractor>::result_type;

    using value_t = typename FunctionTraits<ReduceFunction>::result_type;

    using KeyValuePair = std::pair<key_t, value_t>;

protected:
    template <typename key_t, typename value_t>
    struct node {
        key_t   key;
        value_t value;
        node    * next;
    };

public:
    ReducePostTable(size_t num_buckets, size_t num_buckets_resize_scale,
                    size_t max_num_items_per_bucket, size_t max_num_items_table,
                    KeyExtractor key_extractor, ReduceFunction reduce_function,
                    std::vector<EmitterFunction>& emit)
        : num_buckets_init_scale_(num_buckets),
          num_buckets_resize_scale_(num_buckets_resize_scale),
          max_num_items_per_bucket_(max_num_items_per_bucket),
          max_num_items_table_(max_num_items_table),
          key_extractor_(key_extractor),
          reduce_function_(reduce_function),
          emit_(std::move(emit)) {
        init();
    }

    ReducePostTable(KeyExtractor key_extractor,
                    ReduceFunction reduce_function, std::vector<EmitterFunction>& emit)
        : key_extractor_(key_extractor),
          reduce_function_(reduce_function),
          emit_(std::move(emit)) {
        init();
    }

    ~ReducePostTable() { }

    void init() {
        num_buckets_ = num_buckets_init_scale_;
        vector_.resize(num_buckets_, nullptr);
    }

    /*!
     * Inserts a key/value pair.
     *
     * Optionally, this may be reduce using the reduce function
     * in case the key already exists.
     */
    void Insert(KeyValuePair p) {

        key_t key = p.first;

        size_t hashed_key = std::hash<key_t>() (key) % num_buckets_;

        LOG << "key: "
            << key
            << " to idx: "
            << hashed_key;

        // TODO(ms): the first nullptr case is identical. remove and use null as
        // sentinel.

        // bucket is empty
        if (vector_[hashed_key] == nullptr) {
            LOG << "bucket empty, inserting...";

            node<key_t, value_t>* n = new node<key_t, value_t>;
            n->key = key;
            n->value = p.second;
            n->next = nullptr;
            vector_[hashed_key] = n;

            // increase total counter
            table_size_++;
        }
        else {
            LOG << "bucket not empty, checking if key already exists...";

            // check if item with same key
            node<key_t, value_t>* curr_node = vector_[hashed_key];
            do {
                if (key == curr_node->key) {
                    LOG << "match of key: "
                        << key
                        << " and "
                        << curr_node->key
                        << " ... reducing...";

                    (*curr_node).value = reduce_function_(curr_node->value, p.second);

                    LOG << "...finished reduce!";

                    break;
                }

                curr_node = curr_node->next;
            } while (curr_node != nullptr);

            // no item found with key
            if (curr_node == nullptr) {
                LOG << "key doesn't exist in baguette, appending...";

                // insert at first pos
                node<key_t, value_t>* n = new node<key_t, value_t>;
                n->key = key;
                n->value = p.second;
                n->next = vector_[hashed_key];
                vector_[hashed_key] = n;

                // increase total counter
                table_size_++;

                LOG << "key appended, metrics updated!";
            }
        }

        if (table_size_ > max_num_items_table_) {
            throw std::invalid_argument("Hashtable overflown. No external memory functionality implemented yet");
        }
    }

    /*!
     * Emits element to all childs
     */
    void EmitAll(value_t& element) {
        for (auto& emitter : emit_) {
            emitter(element);
        }
    }
    /*!
     * Flushes all items.
     */
    void Flush() {
        LOG << "Flushing in progress";

        // retrieve items
        for (size_t i = 0; i < num_buckets_; i++) {
            if (vector_[i] != nullptr) {
                node<key_t, value_t>* curr_node = vector_[i];
                do {
                    EmitAll(curr_node->value);
                    curr_node = curr_node->next;
                } while (curr_node != nullptr);
                vector_[i] = nullptr; //TODO(ms) I can't see deallocation of the nodes. Is that done somewhere else?
            }
        }

        // reset counters
        table_size_ = 0;
    }

    /*!
     * Returns the total num of items.
     */
    size_t Size() {
        return table_size_;
    }

    /*!
     * Returns the total num of buckets.
     */
    size_t NumBuckets() {
        return num_buckets_;
    }

    /*!
     * Sets the maximum size of the hash table. We don't want to push 2vt elements before flush happens.
     */
    void SetMaxSize(size_t size) {
        max_num_items_table_ = size;
    }

    /*!
     * Resizes the table by increasing the number of buckets using some
     * resize scale factor. All items are rehashed as part of the operation
     */
    void ResizeUp() {
        LOG << "Resizing";
        num_buckets_ *= num_buckets_resize_scale_;
        // init new array
        std::vector<node<key_t, value_t>*> vector_old = vector_;
        std::vector<node<key_t, value_t>*> vector_new;
        vector_new.resize(num_buckets_, nullptr);
        vector_ = vector_new;
        // rehash all items in old array
        for (auto bucket : vector_old) {
            Insert(bucket);
        }
        LOG << "Resized";
    }

    /*!
     * Removes all items in the table, but NOT flushing them.
     */
    void Clear() {
        LOG << "Clearing";
        std::fill(vector_.begin(), vector_.end(), nullptr);
        table_size_ = 0;
        LOG << "Cleared";
    }

    /*!
     * Removes all items in the table, but NOT flushing them.
     */
    void Reset() {
        LOG << "Resetting";
        num_buckets_ = num_buckets_init_scale_;
        vector_.resize(num_buckets_, nullptr);
        table_size_ = 0;
        LOG << "Resetted";
    }

    // prints content of hash table
    void Print() {
        for (size_t i = 0; i < num_buckets_; i++) {
            if (vector_[i] == nullptr) {
                LOG << "bucket "
                    << i
                    << " empty";
            }
            else {
                std::string log = "";

                // check if item with same key
                node<key_t, value_t>* curr_node = vector_[i];
                value_t curr_item;
                do {
                    curr_item = curr_node->value;

                    log += "(";
                    //log += curr_item.second;
                    log += ") ";

                    curr_node = curr_node->next;
                } while (curr_node != nullptr);

                LOG << "bucket "
                    << i
                    << ": "
                    << log;
            }
        }

        return;
    }

private:
    // TODO(ms): reformat using doxygen-style comments

    //! num buckets
    size_t num_buckets_;

    //! set number of buckets per partition based on num_partitions
    size_t num_buckets_init_scale_ = 65536;

    // multiplied with some scaling factor, must be equal to or greater than 1

    size_t num_buckets_resize_scale_ = 2;   // resize scale on max_num_items_per_bucket_

    size_t max_num_items_per_bucket_ = 256; // max num of items per bucket before resize

    size_t table_size_ = 0;                 // total number of items

    size_t max_num_items_table_ = 1048576;  // max num of items before spilling of largest partition

    KeyExtractor key_extractor_;

    ReduceFunction reduce_function_;

    std::vector<EmitterFunction> emit_;

    std::vector<node<key_t, value_t>*> vector_;
};

} // namespace core
} // namespace c7a

#endif // !C7A_CORE_REDUCE_POST_TABLE_HEADER

/******************************************************************************/
<commit_msg>default hash function for post table<commit_after>/*******************************************************************************
 * c7a/core/reduce_post_table.hpp
 *
 * Hash table with support for reduce and partitions.
 *
 * Part of Project c7a.
 *
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_CORE_REDUCE_POST_TABLE_HEADER
#define C7A_CORE_REDUCE_POST_TABLE_HEADER

#include <c7a/api/function_traits.hpp>
#include <c7a/data/manager.hpp>
#include <c7a/common/logger.hpp>

#include <map>
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include <array>

namespace c7a {
namespace core {

template <typename KeyExtractor, typename ReduceFunction, typename EmitterFunction>
class ReducePostTable
{
    static const bool debug = false;

    // TODO(ms): according to coding style: Types are CamelCase.
    using key_t = typename FunctionTraits<KeyExtractor>::result_type;

    using value_t = typename FunctionTraits<ReduceFunction>::result_type;

    using KeyValuePair = std::pair<key_t, value_t>;

protected:
    template <typename key_t, typename value_t>
    struct node {
        key_t   key;
        value_t value;
        node    * next;
    };

public:
    ReducePostTable(size_t num_buckets, size_t num_buckets_resize_scale,
                    size_t max_num_items_per_bucket, size_t max_num_items_table,
                    KeyExtractor key_extractor, ReduceFunction reduce_function,
                    std::vector<EmitterFunction>& emit,
                    std::function<size_t(key_t, ReducePostTable*)> hash_function
                    = [](key_t key, ReducePostTable* pt) {
                        return std::hash<key_t>() (key) % pt->num_buckets_;
                    }
        )
        : num_buckets_init_scale_(num_buckets),
          num_buckets_resize_scale_(num_buckets_resize_scale),
          max_num_items_per_bucket_(max_num_items_per_bucket),
          max_num_items_table_(max_num_items_table),
          key_extractor_(key_extractor),
          reduce_function_(reduce_function),
          emit_(std::move(emit)),
          hash_function_(hash_function)
    {
        init();
    }

    ReducePostTable(KeyExtractor key_extractor,
                    ReduceFunction reduce_function,
                    std::vector<EmitterFunction>& emit,
                    std::function<size_t(key_t, ReducePostTable*)> hash_function
                    = [](key_t key, ReducePostTable* pt) {
                        return std::hash<key_t>() (key) % pt->num_buckets_;
                    }
)
        : key_extractor_(key_extractor),
          reduce_function_(reduce_function),
          emit_(std::move(emit)),
          hash_function_(hash_function)
    {
        init();
    }

    ~ReducePostTable() { }

    void init() {
        num_buckets_ = num_buckets_init_scale_;
        vector_.resize(num_buckets_, nullptr);
    }

    /*!
     * Inserts a key/value pair.
     *
     * Optionally, this may be reduce using the reduce function
     * in case the key already exists.
     */
    void Insert(KeyValuePair p) {

        key_t key = p.first;

        size_t hashed_key = hash_function_(key, this);

        LOG << "key: "
            << key
            << " to idx: "
            << hashed_key;

        // TODO(ms): the first nullptr case is identical. remove and use null as
        // sentinel.

        // bucket is empty
        if (vector_[hashed_key] == nullptr) {
            LOG << "bucket empty, inserting...";

            node<key_t, value_t>* n = new node<key_t, value_t>;
            n->key = key;
            n->value = p.second;
            n->next = nullptr;
            vector_[hashed_key] = n;

            // increase total counter
            table_size_++;
        }
        else {
            LOG << "bucket not empty, checking if key already exists...";

            // check if item with same key
            node<key_t, value_t>* curr_node = vector_[hashed_key];
            do {
                if (key == curr_node->key) {
                    LOG << "match of key: "
                        << key
                        << " and "
                        << curr_node->key
                        << " ... reducing...";

                    (*curr_node).value = reduce_function_(curr_node->value, p.second);

                    LOG << "...finished reduce!";

                    break;
                }

                curr_node = curr_node->next;
            } while (curr_node != nullptr);

            // no item found with key
            if (curr_node == nullptr) {
                LOG << "key doesn't exist in baguette, appending...";

                // insert at first pos
                node<key_t, value_t>* n = new node<key_t, value_t>;
                n->key = key;
                n->value = p.second;
                n->next = vector_[hashed_key];
                vector_[hashed_key] = n;

                // increase total counter
                table_size_++;

                LOG << "key appended, metrics updated!";
            }
        }

        if (table_size_ > max_num_items_table_) {
            throw std::invalid_argument("Hashtable overflown. No external memory functionality implemented yet");
        }
    }

    /*!
     * Emits element to all childs
     */
    void EmitAll(value_t& element) {
        for (auto& emitter : emit_) {
            emitter(element);
        }
    }
    /*!
     * Flushes all items.
     */
    void Flush() {
        LOG << "Flushing in progress";

        // retrieve items
        for (size_t i = 0; i < num_buckets_; i++) {
            if (vector_[i] != nullptr) {
                node<key_t, value_t>* curr_node = vector_[i];
                do {
                    EmitAll(curr_node->value);
                    curr_node = curr_node->next;
                } while (curr_node != nullptr);
                vector_[i] = nullptr; //TODO(ms) I can't see deallocation of the nodes. Is that done somewhere else?
            }
        }

        // reset counters
        table_size_ = 0;
    }

    /*!
     * Returns the total num of items.
     */
    size_t Size() {
        return table_size_;
    }

    /*!
     * Returns the total num of buckets.
     */
    size_t NumBuckets() {
        return num_buckets_;
    }

    /*!
     * Sets the maximum size of the hash table. We don't want to push 2vt elements before flush happens.
     */
    void SetMaxSize(size_t size) {
        max_num_items_table_ = size;
    }

    /*!
     * Resizes the table by increasing the number of buckets using some
     * resize scale factor. All items are rehashed as part of the operation
     */
    void ResizeUp() {
        LOG << "Resizing";
        num_buckets_ *= num_buckets_resize_scale_;
        // init new array
        std::vector<node<key_t, value_t>*> vector_old = vector_;
        std::vector<node<key_t, value_t>*> vector_new;
        vector_new.resize(num_buckets_, nullptr);
        vector_ = vector_new;
        // rehash all items in old array
        for (auto bucket : vector_old) {
            Insert(bucket);
        }
        LOG << "Resized";
    }

    /*!
     * Removes all items in the table, but NOT flushing them.
     */
    void Clear() {
        LOG << "Clearing";
        std::fill(vector_.begin(), vector_.end(), nullptr);
        table_size_ = 0;
        LOG << "Cleared";
    }

    /*!
     * Removes all items in the table, but NOT flushing them.
     */
    void Reset() {
        LOG << "Resetting";
        num_buckets_ = num_buckets_init_scale_;
        vector_.resize(num_buckets_, nullptr);
        table_size_ = 0;
        LOG << "Resetted";
    }

    // prints content of hash table
    void Print() {
        for (size_t i = 0; i < num_buckets_; i++) {
            if (vector_[i] == nullptr) {
                LOG << "bucket "
                    << i
                    << " empty";
            }
            else {
                std::string log = "";

                // check if item with same key
                node<key_t, value_t>* curr_node = vector_[i];
                value_t curr_item;
                do {
                    curr_item = curr_node->value;

                    log += "(";
                    //log += curr_item.second;
                    log += ") ";

                    curr_node = curr_node->next;
                } while (curr_node != nullptr);

                LOG << "bucket "
                    << i
                    << ": "
                    << log;
            }
        }

        return;
    }

private:
    // TODO(ms): reformat using doxygen-style comments

    //! num buckets
    size_t num_buckets_;

    //! set number of buckets per partition based on num_partitions
    size_t num_buckets_init_scale_ = 65536;

    // multiplied with some scaling factor, must be equal to or greater than 1

    size_t num_buckets_resize_scale_ = 2;   // resize scale on max_num_items_per_bucket_

    size_t max_num_items_per_bucket_ = 256; // max num of items per bucket before resize

    size_t table_size_ = 0;                 // total number of items

    size_t max_num_items_table_ = 1048576;  // max num of items before spilling of largest partition

    KeyExtractor key_extractor_;

    ReduceFunction reduce_function_;

    std::vector<EmitterFunction> emit_;

    std::vector<node<key_t, value_t>*> vector_;

    std::function<size_t(key_t, ReducePostTable*)> hash_function_;
};

} // namespace core
} // namespace c7a

#endif // !C7A_CORE_REDUCE_POST_TABLE_HEADER

/******************************************************************************/
<|endoftext|>


<commit_before>//
//  generateSimulatedData.cpp
//  cPWP
//
//  Created by Evan McCartney-Melstad on 12/31/14.
//  Copyright (c) 2014 Evan McCartney-Melstad. All rights reserved.
//

#include "generateSimulatedData.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

int generateReadsAndMap (int numIndividuals, double mutationRateStepSize, std::string baseErrorRate, std::string libFragmentSize, std::string stdevLibFragmentSize, std::string numReadPairs, std::string readLengths, std::string randomSeed, std::string reference, std::string threads) {
/*// supply 1) number of individuals, 2) the mutation rate steps between them, 3) the base error rate, 4) the average library fragment size, 5) the standard deviation of the library fragment size, 6) the number of read pairs for each individual, 7) read lengths (per read), 8) random number generator seed

    So, for instance, if numIndividuals is 5, and mutationRateSteps is 0.01, then there will be four individuals generated with mutation rate steps of 0.01, 0.02, 0.03, and 0.04 away from the reference genome. Individual 0 is created as being identical to the reference genome (mutation rate parameter set to 0.00).
*/

    std::ofstream bamsFile;
    bamsFile.open("bamlist.txt", std::ios::out | std::ios::app);

    std::cout << "**********\nChecking if processor is available...";
    if (system(NULL)) puts ("Ok");
    else exit (EXIT_FAILURE);

    std::vector<std::string> wgsimCommands;
    int step = 0;
    while(step <= numIndividuals) {
        double mutRate = step * mutationRateStepSize;
        // Covert the mutation rate into a string for the system command
        std::ostringstream mutStrs;
        mutStrs << mutRate;
        std::string mutRateString = mutStrs.str();

        std::cout << "**********\nGenerating sequence reads for individual " << step << " using a mutation rate of " << mutRateString << " from the reference genome\n**********\n";

        // Get the number of the individual as a string
        std::ostringstream stepString;
        stepString << step;
        std::string ind = stepString.str();

        // Generate the output file names as strings
        std::string R1out = "ind" + ind + "_R1.fastq";
        std::string R2out = "ind" + ind + "_R2.fastq";
        std::string polymorphismFile = "ind" + ind + "_polymorphisms.txt";

        // Generate the wgsim command and then run it using a system call
        std::string wgsimCommandToRun = "wgsim -N " + numReadPairs + " -r " + mutRateString + " -R 0.00 -X 0.00 -d " + libFragmentSize + " -s " + stdevLibFragmentSize +  " -1 " + readLengths + " -2 " + readLengths + " -S " + randomSeed + " -e0 " + reference + " " + R1out + " " + R2out + " > " + polymorphismFile; // No indels, no probability of indel extension, no base call error rates
        if (system((wgsimCommandToRun).c_str()) != 0) {
            std::cout << "**********\nFailure running the following command: " << wgsimCommandToRun << "\n**********\n";
            exit(EXIT_FAILURE);
        } else {
            std::cout << "**********\nExecuted the following command: " << wgsimCommandToRun << "\n**********\n";

        }

        // Generate the bwa mem command and then run it using a system call
        std::string bamOut = "ind" + ind + ".bam";
        std::string bwaCommandToRun = "bwa mem -t " + threads + " " + reference + " " + R1out + " " + R2out + " | samtools view -bS - | samtools sort -T temp -o " + bamOut + " -";
        if (system((bwaCommandToRun).c_str()) != 0) {
            std::cout << "**********\nFailure running the following command: " << bwaCommandToRun << "\n**********\n";
            exit(EXIT_FAILURE);
        } else {
            std::cout << "**********\nExecuted the following command: " << bwaCommandToRun << "\n**********\n";
        }
        bamsFile << bamOut << endl;
        step++; // Move on to the next individual
    }
    bamsFile.close();
    return 0;
}

/*
 /home/evan/bin/angsd0.613/angsd -bam bamlist272.txt -out 272torts_allCounts_minmapq20minq30 -uniqueOnly 1 -only_proper_pairs 1 -remove_bads 1 -doCounts 1 -nThreads 8 -dumpCounts 4 -doMaf 1 -doMajorMinor 2 -GL 2 -minMapQ 20 -minQ 30 > 272tortsangsdMapQ30_allSites.log 2>&1

*/

/*
 wgsim -N 10000000 -r 0.01 -R 0.00 -X 0.00 -1 100 -2 100 -S11 -e0 lgv2.fasta r1_noerr1percDivergent_10mil.fq r2_noerr1percDivergent_10mil.fq > 1perc_polymorphisms.txt
 wgsim -N 10000000 -r 0.00 -1 100 -2 100 -S11 -e0 lgv2.fasta r1_noerrnomut_10mil.fq r2_noerrnomut_10mil.fq

 bwa mem -t 10 lgv2.fasta r1_noerrnomut_10mil.fq r2_noerrnomut_10mil.fq
 bwa mem -t 10 lgv2.fasta r1_noerr1percDivergent_10mil.fq r2_noerr1percDivergent_10mil.fq

 samtools sort -T noMut -o 1XcoverageNoErrNoMutSorted.bam 1XcoverageNoErrNoMut.bam
 samtools sort -T mut -o 1XcoverageNoErr1PercentDivergentSorted.bam 1XcoverageNoErr1PercDivergent.bam

 echo -e "1XcoverageNoErrNoMutSorted.bam\n1XcoverageNoErr1PercentDivergentSorted.bam" > bamlist2sim.txt

 /home/evan/bin/angsd0.613/angsd -bam bamlist2sim.txt -out 2tortsim1perDiv -uniqueOnly 1 -only_proper_pairs 1 -remove_bads 1 -doCounts 1 -nThreads 8 -dumpCounts 4 -doMaf 1 -doMajorMinor 2 -GL 2 -minMapQ 20 -minQ 30 > 2tortANGSD.log 2>&1 &

*/

/*
 Usage:   wgsim [options] <in.ref.fa> <out.read1.fq> <out.read2.fq>

 Options:
 -e FLOAT      base error rate [0.000]
 -d INT        outer distance between the two ends [500]
 -s INT        standard deviation [50]
 -N INT        number of read pairs [1000000]
 -1 INT        length of the first read [70]
 -2 INT        length of the second read [70]
 -r FLOAT      rate of mutations [0.0010]
 -R FLOAT      fraction of indels [0.15]
 -X FLOAT      probability an indel is extended [0.30]
 -S INT        seed for random generator [-1]
 -h            haplotype mode

 */
<commit_msg>Minor change<commit_after>//
//  generateSimulatedData.cpp
//  cPWP
//
//  Created by Evan McCartney-Melstad on 12/31/14.
//  Copyright (c) 2014 Evan McCartney-Melstad. All rights reserved.
//

#include "generateSimulatedData.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

int generateReadsAndMap (int numIndividuals, double mutationRateStepSize, std::string baseErrorRate, std::string libFragmentSize, std::string stdevLibFragmentSize, std::string numReadPairs, std::string readLengths, std::string randomSeed, std::string reference, std::string threads) {
/*// supply 1) number of individuals, 2) the mutation rate steps between them, 3) the base error rate, 4) the average library fragment size, 5) the standard deviation of the library fragment size, 6) the number of read pairs for each individual, 7) read lengths (per read), 8) random number generator seed

    So, for instance, if numIndividuals is 5, and mutationRateSteps is 0.01, then there will be four individuals generated with mutation rate steps of 0.01, 0.02, 0.03, and 0.04 away from the reference genome. Individual 0 is created as being identical to the reference genome (mutation rate parameter set to 0.00).
*/

    std::ofstream bamsFile;
    bamsFile.open("bamlist.txt", std::ios::out | std::ios::app);

    std::cout << "**********\nChecking if processor is available...";
    if (system(NULL)) puts ("Ok");
    else exit (EXIT_FAILURE);

    std::vector<std::string> wgsimCommands;
    int step = 0;
    while(step <= numIndividuals) {
        double mutRate = step * mutationRateStepSize;
        // Covert the mutation rate into a string for the system command
        std::ostringstream mutStrs;
        mutStrs << mutRate;
        std::string mutRateString = mutStrs.str();

        std::cout << "**********\nGenerating sequence reads for individual " << step << " using a mutation rate of " << mutRateString << " from the reference genome\n**********\n";

        // Get the number of the individual as a string
        std::ostringstream stepString;
        stepString << step;
        std::string ind = stepString.str();

        // Generate the output file names as strings
        std::string R1out = "ind" + ind + "_R1.fastq";
        std::string R2out = "ind" + ind + "_R2.fastq";
        std::string polymorphismFile = "ind" + ind + "_polymorphisms.txt";

        // Generate the wgsim command and then run it using a system call
        std::string wgsimCommandToRun = "wgsim -N " + numReadPairs + " -r " + mutRateString + " -R 0.00 -X 0.00 -d " + libFragmentSize + " -s " + stdevLibFragmentSize +  " -1 " + readLengths + " -2 " + readLengths + " -S " + randomSeed + " -e0 " + reference + " " + R1out + " " + R2out + " > " + polymorphismFile; // No indels, no probability of indel extension, no base call error rates
        if (system((wgsimCommandToRun).c_str()) != 0) {
            std::cout << "**********\nFailure running the following command: " << wgsimCommandToRun << "\n**********\n";
            exit(EXIT_FAILURE);
        } else {
            std::cout << "**********\nExecuted the following command: " << wgsimCommandToRun << "\n**********\n";

        }

        // Generate the bwa mem command and then run it using a system call
        std::string bamOut = "ind" + ind + ".bam";
        std::string bwaCommandToRun = "bwa mem -t " + threads + " " + reference + " " + R1out + " " + R2out + " | samtools view -bS - | samtools sort -T temp -o " + bamOut + " -";
        if (system((bwaCommandToRun).c_str()) != 0) {
            std::cout << "**********\nFailure running the following command: " << bwaCommandToRun << "\n**********\n";
            exit(EXIT_FAILURE);
        } else {
            std::cout << "**********\nExecuted the following command: " << bwaCommandToRun << "\n**********\n";
        }
        bamsFile << bamOut << std::endl;
        step++; // Move on to the next individual
    }
    bamsFile.close();
    return 0;
}

/*
 /home/evan/bin/angsd0.613/angsd -bam bamlist272.txt -out 272torts_allCounts_minmapq20minq30 -uniqueOnly 1 -only_proper_pairs 1 -remove_bads 1 -doCounts 1 -nThreads 8 -dumpCounts 4 -doMaf 1 -doMajorMinor 2 -GL 2 -minMapQ 20 -minQ 30 > 272tortsangsdMapQ30_allSites.log 2>&1

*/

/*
 wgsim -N 10000000 -r 0.01 -R 0.00 -X 0.00 -1 100 -2 100 -S11 -e0 lgv2.fasta r1_noerr1percDivergent_10mil.fq r2_noerr1percDivergent_10mil.fq > 1perc_polymorphisms.txt
 wgsim -N 10000000 -r 0.00 -1 100 -2 100 -S11 -e0 lgv2.fasta r1_noerrnomut_10mil.fq r2_noerrnomut_10mil.fq

 bwa mem -t 10 lgv2.fasta r1_noerrnomut_10mil.fq r2_noerrnomut_10mil.fq
 bwa mem -t 10 lgv2.fasta r1_noerr1percDivergent_10mil.fq r2_noerr1percDivergent_10mil.fq

 samtools sort -T noMut -o 1XcoverageNoErrNoMutSorted.bam 1XcoverageNoErrNoMut.bam
 samtools sort -T mut -o 1XcoverageNoErr1PercentDivergentSorted.bam 1XcoverageNoErr1PercDivergent.bam

 echo -e "1XcoverageNoErrNoMutSorted.bam\n1XcoverageNoErr1PercentDivergentSorted.bam" > bamlist2sim.txt

 /home/evan/bin/angsd0.613/angsd -bam bamlist2sim.txt -out 2tortsim1perDiv -uniqueOnly 1 -only_proper_pairs 1 -remove_bads 1 -doCounts 1 -nThreads 8 -dumpCounts 4 -doMaf 1 -doMajorMinor 2 -GL 2 -minMapQ 20 -minQ 30 > 2tortANGSD.log 2>&1 &

*/

/*
 Usage:   wgsim [options] <in.ref.fa> <out.read1.fq> <out.read2.fq>

 Options:
 -e FLOAT      base error rate [0.000]
 -d INT        outer distance between the two ends [500]
 -s INT        standard deviation [50]
 -N INT        number of read pairs [1000000]
 -1 INT        length of the first read [70]
 -2 INT        length of the second read [70]
 -r FLOAT      rate of mutations [0.0010]
 -R FLOAT      fraction of indels [0.15]
 -X FLOAT      probability an indel is extended [0.30]
 -S INT        seed for random generator [-1]
 -h            haplotype mode

 */
<|endoftext|>


<commit_before>#include <iostream>;

#include "common/SystemPaths.hh"

#include "ObjectInstantiatorPlugin.hh"

using namespace gazebo;

ObjectInstantiator::ObjectInstantiator() : WorldPlugin()
{
  this->object_lifetime = common::Time(10.0);
}

void ObjectInstantiator::Init() {
  this->next_expire = common::Time::GetWallTime();
}

void ObjectInstantiator::Load(physics::WorldPtr _world, sdf::ElementPtr _sdf)
{
  this->world = _world;
  this->object_count = 0;

  this->node = transport::NodePtr(new transport::Node());
  this->node->Init(this->world->GetName());

  this->objectSub = this->node->Subscribe(std::string("~/SceneReconstruction/ObjectInstantiator/Object"), &ObjectInstantiatorPlugin::OnSceneObjectMsg, this);
  this->srguiPub = this->node->Advertise<msgs::Response>(std::string("~/SceneReconstruction/ObjectInstantiator/Response"));
  this->framePub = this->node->Advertise<msgs::Request>(std::string("~/SceneReconstruction/ObjectInstantiator/Request"));

  sdf::ElementPtr settingsElem;
  if (_sdf->HasElement("settings")) {
    settingsElem = _sdf->GetElement("settings");
    if(settingsElem->HasElement("overlapping")) {
      if(!settingsElem->GetElement("overlapping")->GetValue()->Get(overlapping)) {
    	  gzerr << "<overlapping> is not a bool, defaulting to true\n";
        overlapping = true;
      }
    }
    else {
      overlapping = true;
    }

    if(settingsElem->HasElement("temporary")) {
      if(!settingsElem->GetElement("temporary")->GetValue()->Get(overlapping)) {
    	  gzerr << "<temporary> is not a bool, defaulting to false\n";
        temporary = false;
      }
    }
    else {
      temporary = false;
    }

    if(settingsElem->HasElement("object_lifetime")) {
      double lifetime;
      if(!settingsElem->GetElement("object_lifetime")->GetValue()->Get(lifetime)) {
    	  gzerr << "<object_lifetime> is not a double, defaulting to 10 seconds\n";
      }
      else {
        this->object_lifetime = common::Time(lifetime);
      }
    }
  }

  sdf::ElementPtr objectElem;
  if (_sdf->HasElement("object")) {
    objectElem = _sdf->GetElement("object");
    while(objectElem) {
      std::string name;
      std::string data;

      if(objectElem->HasElement("name")) {
        if(!objectElem->GetElement("name")->GetValue()->Get(gname)) {
      	  gzerr << "<name> is not a string, leaving out this <object>\n";
        }
        else {
          if(objectElem->HasElement("filename")) {
            std::string filename;
            if(!objectElem->GetElement("filename")->GetValue()->Get(filename)) {
          	  gzerr << "<filename> is not a string, leaving out this <object>\n";
            }

            std::string _filename = common::SystemPaths::Instance()->FindFileWithGazeboPaths(filename);
            std::ifstream ifile(_filename);

            if(!ifile) {
          	  gzerr << "\"" << filename << "\" does not exist, leaving out this <object>\n";
            }
            else {
              std::ostringstream _data;
              std::string line;
              while(!ifile.eof()) {
                getline(ifile,line);
                _data << line;
              }
              data = _data.str();

              objects[name] = data;
              ifile.close();
            }
          }
          else if(objectElem->HasElement("data")) {
            if(!objectElem->GetElement("data")->GetValue()->Get(data)) {
          	  gzerr << "<data> is not a string, leaving out this <object>\n";
            }
            else {
              objects[name] = data;
            }
          }
          else {
        	  gzerr << "neither <filename> nor <data> available, leaving out this <object>\n";
          }
        }
      }
      else {
      	gzerr << "missing required element <name>\n";
      }
      objectElem = objectElem->GetNextElement("object");
    }
  }
}

void ObjectInstantiator::OnSceneObjectMsg(ConstSceneObject_VPtr &_msg) {
  if(overlapping)
    process_objects_overlapping(_msg);
  else if(temporary)
    process_objects_temporary(_msg);
  else
    process_objects_non_overlapping(_msg);
}

void ObjectInstantiator::OnRequestMsg(ConstRequestPtr &_msg) {
  msgs::Response response;
  response.set_id(_msg->id());
  response.set_request(_msg->request());
  response.set_response("success");

  if(_msg->request() == "object_list") {
    msgs::SceneObject_V src;
    response.set_type(src.GetTypeName());
    fill_object_v_msg(src);
    std::string *serializedData = response.mutable_serialized_data();
    src.SerializeToString(serializedData);

    this->srguiPub->Publish(response);
  }
  else if(_msg->request() == "object_data") {
    response.set_response("success");
    msgs::SceneObject src;
    response.set_type(src.GetTypeName());
    if(_msg->has_data() && fill_object_msg(_msg->data(), src)) {
      msgs::Request request;
      request.set_request(_msg->request());
      request.set_id(_msg->id());
      request.set_data(src.objectid());
      fill_object_msg(src);
      std::string *serializedData = response.mutable_serialized_data();
      src.SerializeToString(serializedData);

      this->framePub->Publish(request);
      this->srguiPub->Publish(response);
    }
    else {
      std::ostringstream tmp;
      tmp << "failure: " << _msg->data() << " not an object known to the objectinstantiator";
      response.set_response(tmp.str());
      this->srguiPub->Publish(response);
    }
  }
  else if(_msg->request() == "object_repository") {
    msgs::String_V src;
    response.set_type(src.GetTypeName());
    fill_repository_msg(src);
    std::string *serializedData = response.mutable_serialized_data();
    src.SerializeToString(serializedData);

    this->srguiPub->Publish(response);
  }
}

void ObjectInstantiator::OnUpdate() {
  if (this->temporary)
    return;

  if(common::Time::GetWallTime() < this->next_expire)
    return;

  common::Time now = common::Time::GetWallTime();
  common::Time old_expire = this->next_expire;
  this->next_expire = now + this->object_lifetime + this->object_lifetime + this->object_lifetime;
  std::map< std::string, SceneObject>::iterator it;
  for(it = object_list.begin(); it != object_list.end(); it++) {
    if(it->second.expiretime < now) {
      this->world->rootElement->RemoveChild(it->second.model->GetID());
      object_list.erase(it);
    }
    else if(it->second.expiretime < this->next_expire) {
      this->next_expire = it->second.expiretime;
    }
  }
}

bool ObjectInstantiator::fill_object_msg(std::string name, msgs::SceneObject &_msg) {
  std::map< std::string, SceneObject>::iterator it =  object_list.find(name);
  if(it != object_list.end()) {
    _msg.add_object_type(it->second.type);
    const math::Pose pose = it->second.model->GetWorldPose();
    _msg.add_pos_x(pose.pos.x);
    _msg.add_pos_y(pose.pos.y);
    _msg.add_pos_z(pose.pos.z);
    _msg.add_rot_w(pose.rot.w);
    _msg.add_rot_x(pose.rot.x);
    _msg.add_rot_y(pose.rot.y);
    _msg.add_rot_z(pose.rot.z);
    _msg.add_frame(it->second.frame);
    _msg.add_child_frame(it->second.child_frame);
    _msg.add_objectid(it->second.objectid);
    _msg.add_name(it->first);
    return true;
  }

  return false;
}

void ObjectInstantiator::fill_object_v_msg(msgs::SceneObject_V &_msg) {
  std::map< std::string, SceneObject>::iterator it;
  for(it = object_list.begin(); it != object_list.end(); it++) {
    _msg.add_object_type(it->second.type);
    const math::Pose pose = it->second.model->GetWorldPose();
    _msg.add_pos_x(pose.pos.x);
    _msg.add_pos_y(pose.pos.y);
    _msg.add_pos_z(pose.pos.z);
    _msg.add_rot_w(pose.rot.w);
    _msg.add_rot_x(pose.rot.x);
    _msg.add_rot_y(pose.rot.y);
    _msg.add_rot_z(pose.rot.z);
    _msg.add_frame(it->second.frame);
    _msg.add_child_frame(it->second.child_frame);
    _msg.add_objectid(it->second.objectid);
    _msg.add_name(it->first);
  }
}

void ObjectInstantiator::fill_repository_msg(msgs::String_V &_msg) {
  std::map< std::string, std::string>::iterator it;
  for(it = objects.begin(); it != objects.end(); it++) {
    _msg.add_data(it->first);
    _msg.add_data(it->second);
  }
}

void ObjectInstantiator::process_objects_overlapping(ConstSceneObject_VPtr &_msg) {
  // add new models
  for(int n=0; n<_msg->object_type_size(); n++) {
    sdf::SDF _sdf;
    std::string sdf_data;
    sdf_data = objects[_msg->object_type(n)];
    std::string modelname = set_sdf_values(sdf_data, _msg->name(n), _msg->pos_x(n), _msg->pos_y(n), _msg->pos_z(n), _msg->rot_w(n), _msg->rot_x(n), _msg->rot_y(n), _msg->rot_z(n));
    SceneObject so;
    so.type = _msg->object_type(n);
    so.frame = _msg->frame(n);
    so.child_frame = _msg->child_frame(n);
    so.objectid = _msg->objectid(n);
    _sdf.SetFromString(sdf_data);
    this->world->InsertModel(_sdf);
    so.model = this->world->GetModel(modelname);
    if(so.expiretime <= this->next_expire)
      this->next_expire = so.expiretime;
    object_list[modelname] = so;
  }
}

void ObjectInstantiator::process_objects_non_overlapping(ConstSceneObject_VPtr &_msg) {
  // add new models
  for(int n=0; n<_msg->object_type_size(); n++) {
    // check for overlapping existing models
//    for(it = object_list.begin(); it != object_list.end(); it++) {
//    }

    sdf::SDF _sdf;
    std::string sdf_data;
    sdf_data = objects[_msg->object_type(n)];
    std::string modelname = set_sdf_values(sdf_data, _msg->name(n), _msg->pos_x(n), _msg->pos_y(n), _msg->pos_z(n), _msg->rot_w(n), _msg->rot_x(n), _msg->rot_y(n), _msg->rot_z(n));
    SceneObject so;
    so.type = _msg->object_type(n);
    so.frame = _msg->frame(n);
    so.child_frame = _msg->child_frame(n);
    so.objectid = _msg->objectid(n);
    _sdf.SetFromString(sdf_data);
    this->world->InsertModel(_sdf);
    so.model = this->world->GetModel(modelname);
    so.expiretime = common::Time::GetWallTime()+this->object_lifetime;
    if(so.expiretime <= this->next_expire)
      this->next_expire = so.expiretime;
    object_list[modelname] = so;
  }
}

void ObjectInstantiator::process_objects_temporary(ConstSceneObject_VPtr &_msg) {
  // remove all previouse models
  for(it = object_list.begin(); it != object_list.end(); it++) {
    this->world->rootElement->RemoveChild(it->second.model->GetID());
  }
  object_list.clear();

  // add new models
  for(int n=0; n<_msg->object_type_size(); n++) {
    sdf::SDF _sdf;
    std::string sdf_data;
    sdf_data = objects[_msg->object_type(n)];
    std::string modelname = set_sdf_values(sdf_data, _msg->name(n), _msg->pos_x(n), _msg->pos_y(n), _msg->pos_z(n), _msg->rot_w(n), _msg->rot_x(n), _msg->rot_y(n), _msg->rot_z(n));
    SceneObject so;
    so.type = _msg->object_type(n);
    so.frame = _msg->frame(n);
    so.child_frame = _msg->child_frame(n);
    so.objectid = _msg->objectid(n);
    _sdf.SetFromString(sdf_data);
    this->world->InsertModel(_sdf);
    so.model = this->world->GetModel(modelname);
    object_list[modelname] = so;
  }
}

std::string ObjectInstantiator::set_sdf_values(std::string &_sdf, std::string name, double pos_x, double pos_y, double pos_z, double rot_w, double rot_x, double rot_y, double rot_z) {
  std::ostringstream converter;
  std::string modelname;
  converter << name << "_" << this->object_count;
  modelname = converter.str();
  object_count++;
  replace(_sdf, "@NAME@", modelname);

  converter.str("");
  converter << pos_x;
  replace(_sdf, "@POSX@", converter.str());

  converter.str("");
  converter << pos_y;
  replace(_sdf, "@POSY@", converter.str());

  converter.str("");
  converter << pos_z;
  replace(_sdf, "@POSZ@", converter.str());

  converter.str("");
  converter << rot_w;
  replace(_sdf, "@ROTW@", converter.str());

  converter.str("");
  converter << rot_x;
  replace(_sdf, "@ROTX@", converter.str());

  converter.str("");
  converter << rot_y;
  replace(_sdf, "@ROTY@", converter.str());

  converter.str("");
  converter << rot_z;
  replace(_sdf, "@ROTZ@", converter.str());

  return modelname;
}

void replace(std::string &text, std::string search, std::string replace) {
  size_t position = text.find(search);
  size_t length = search.length();
  text.erase(position, length);
  text.insert(position, replace);
}
<commit_msg>some minor fixes<commit_after>#include <iostream>;

#include "common/SystemPaths.hh"

#include "ObjectInstantiatorPlugin.hh"

using namespace gazebo;

ObjectInstantiator::ObjectInstantiator() : WorldPlugin()
{
  this->object_lifetime = common::Time(10.0);
}

void ObjectInstantiator::Init() {
  this->next_expire = common::Time::GetWallTime();
}

void ObjectInstantiator::Load(physics::WorldPtr _world, sdf::ElementPtr _sdf)
{
  this->world = _world;
  this->object_count = 0;

  this->node = transport::NodePtr(new transport::Node());
  this->node->Init(this->world->GetName());

  this->objectSub = this->node->Subscribe(std::string("~/SceneReconstruction/ObjectInstantiator/Object"), &ObjectInstantiatorPlugin::OnSceneObjectMsg, this);
  this->srguiPub = this->node->Advertise<msgs::Response>(std::string("~/SceneReconstruction/ObjectInstantiator/Response"));
  this->framePub = this->node->Advertise<msgs::Request>(std::string("~/SceneReconstruction/ObjectInstantiator/Request"));

  sdf::ElementPtr settingsElem;
  if (_sdf->HasElement("settings")) {
    settingsElem = _sdf->GetElement("settings");
    if(settingsElem->HasElement("overlapping")) {
      if(!settingsElem->GetElement("overlapping")->GetValue()->Get(overlapping)) {
    	  gzerr << "<overlapping> is not a bool, defaulting to true\n";
        overlapping = true;
      }
    }
    else {
      overlapping = true;
    }

    if(settingsElem->HasElement("temporary")) {
      if(!settingsElem->GetElement("temporary")->GetValue()->Get(overlapping)) {
    	  gzerr << "<temporary> is not a bool, defaulting to false\n";
        temporary = false;
      }
    }
    else {
      temporary = false;
    }

    if(settingsElem->HasElement("object_lifetime")) {
      double lifetime;
      if(!settingsElem->GetElement("object_lifetime")->GetValue()->Get(lifetime)) {
    	  gzerr << "<object_lifetime> is not a double, defaulting to 10 seconds\n";
      }
      else {
        this->object_lifetime = common::Time(lifetime);
      }
    }
  }

  sdf::ElementPtr objectElem;
  if (_sdf->HasElement("object")) {
    objectElem = _sdf->GetElement("object");
    while(objectElem) {
      std::string name;
      std::string data;

      if(objectElem->HasElement("name")) {
        if(!objectElem->GetElement("name")->GetValue()->Get(gname)) {
      	  gzerr << "<name> is not a string, leaving out this <object>\n";
        }
        else {
          if(objectElem->HasElement("filename")) {
            std::string filename;
            if(!objectElem->GetElement("filename")->GetValue()->Get(filename)) {
          	  gzerr << "<filename> is not a string, leaving out this <object>\n";
            }

            std::string _filename = common::SystemPaths::Instance()->FindFileWithGazeboPaths(filename);
            std::ifstream ifile(_filename);

            if(!ifile) {
          	  gzerr << "\"" << filename << "\" does not exist, leaving out this <object>\n";
            }
            else {
              std::ostringstream _data;
              std::string line;
              while(!ifile.eof()) {
                getline(ifile,line);
                _data << line;
              }
              data = _data.str();

              objects[name] = data;
              ifile.close();
            }
          }
          else if(objectElem->HasElement("data")) {
            if(!objectElem->GetElement("data")->GetValue()->Get(data)) {
          	  gzerr << "<data> is not a string, leaving out this <object>\n";
            }
            else {
              objects[name] = data;
            }
          }
          else {
        	  gzerr << "neither <filename> nor <data> available, leaving out this <object>\n";
          }
        }
      }
      else {
      	gzerr << "missing required element <name>\n";
      }
      objectElem = objectElem->GetNextElement("object");
    }
  }
}

void ObjectInstantiator::OnSceneObjectMsg(ConstSceneObject_VPtr &_msg) {
  if(overlapping)
    process_objects_overlapping(_msg);
  else if(temporary)
    process_objects_temporary(_msg);
  else
    process_objects_non_overlapping(_msg);
}

void ObjectInstantiator::OnRequestMsg(ConstRequestPtr &_msg) {
  msgs::Response response;
  response.set_id(_msg->id());
  response.set_request(_msg->request());
  response.set_response("success");

  if(_msg->request() == "object_list") {
    msgs::String_V src;
    response.set_type(src.GetTypeName());
    fill_list_msg(src);
    std::string *serializedData = response.mutable_serialized_data();
    src.SerializeToString(serializedData);

    this->srguiPub->Publish(response);
  }
  else if(_msg->request() == "object_data") {
    response.set_response("success");
    msgs::SceneObject src;
    response.set_type(src.GetTypeName());
    if(_msg->has_data() && fill_object_msg(_msg->data(), src)) {
      msgs::Request request;
      request.set_request(_msg->request());
      request.set_id(_msg->id());
      request.set_data(src.objectid());
      fill_object_msg(src);
      std::string *serializedData = response.mutable_serialized_data();
      src.SerializeToString(serializedData);

      this->framePub->Publish(request);
      this->srguiPub->Publish(response);
    }
    else {
      std::ostringstream tmp;
      tmp << "failure: " << _msg->data() << " not an object known to the objectinstantiator";
      response.set_response(tmp.str());
      this->srguiPub->Publish(response);
    }
  }
  else if(_msg->request() == "object_repository") {
    msgs::String_V src;
    response.set_type(src.GetTypeName());
    fill_repository_msg(src);
    std::string *serializedData = response.mutable_serialized_data();
    src.SerializeToString(serializedData);

    this->srguiPub->Publish(response);
  }
}

void ObjectInstantiator::OnUpdate() {
  if (this->temporary)
    return;

  if(common::Time::GetWallTime() < this->next_expire)
    return;

  common::Time now = common::Time::GetWallTime();
  common::Time old_expire = this->next_expire;
  this->next_expire = now + this->object_lifetime + this->object_lifetime + this->object_lifetime;
  std::map< std::string, SceneObject>::iterator it;
  for(it = object_list.begin(); it != object_list.end(); it++) {
    if(it->second.expiretime < now) {
      this->world->rootElement->RemoveChild(it->second.model->GetID());
      object_list.erase(it);
    }
    else if(it->second.expiretime < this->next_expire) {
      this->next_expire = it->second.expiretime;
    }
  }
}

bool ObjectInstantiator::fill_object_msg(std::string name, msgs::SceneObject &_msg) {
  std::map< std::string, SceneObject>::iterator it =  object_list.find(name);
  if(it != object_list.end()) {
    _msg.add_object_type(it->second.type);
    const math::Pose pose = it->second.model->GetWorldPose();
    _msg.add_pos_x(pose.pos.x);
    _msg.add_pos_y(pose.pos.y);
    _msg.add_pos_z(pose.pos.z);
    _msg.add_rot_w(pose.rot.w);
    _msg.add_rot_x(pose.rot.x);
    _msg.add_rot_y(pose.rot.y);
    _msg.add_rot_z(pose.rot.z);
    _msg.add_frame(it->second.frame);
    _msg.add_child_frame(it->second.child_frame);
    _msg.add_objectid(it->second.objectid);
    _msg.add_name(it->first);
    return true;
  }

  return false;
}

void ObjectInstantiator::fill_list_msg(msgs::String_V &_msg) {
  std::map< std::string, SceneObject>::iterator it;
  for(it = object_list.begin(); it != object_list.end(); it++) {
    _msg.add_name(it->first);
  }
}

void ObjectInstantiator::fill_repository_msg(msgs::String_V &_msg) {
  std::map< std::string, std::string>::iterator it;
  for(it = objects.begin(); it != objects.end(); it++) {
    _msg.add_data(it->first);
  }
}

void ObjectInstantiator::process_objects_overlapping(ConstSceneObject_VPtr &_msg) {
  // add new models
  for(int n=0; n<_msg->object_type_size(); n++) {
    sdf::SDF _sdf;
    std::string sdf_data;
    sdf_data = objects[_msg->object_type(n)];
    std::string modelname = set_sdf_values(sdf_data, _msg->name(n), _msg->pos_x(n), _msg->pos_y(n), _msg->pos_z(n), _msg->rot_w(n), _msg->rot_x(n), _msg->rot_y(n), _msg->rot_z(n));
    SceneObject so;
    so.type = _msg->object_type(n);
    so.frame = _msg->frame(n);
    so.child_frame = _msg->child_frame(n);
    so.objectid = _msg->objectid(n);
    _sdf.SetFromString(sdf_data);
    this->world->InsertModel(_sdf);
    so.model = this->world->GetModel(modelname);
    if(so.expiretime <= this->next_expire)
      this->next_expire = so.expiretime;
    object_list[modelname] = so;
  }
}

void ObjectInstantiator::process_objects_non_overlapping(ConstSceneObject_VPtr &_msg) {
  // add new models
  for(int n=0; n<_msg->object_type_size(); n++) {
    // check for overlapping existing models
//    for(it = object_list.begin(); it != object_list.end(); it++) {
//    }

    sdf::SDF _sdf;
    std::string sdf_data;
    sdf_data = objects[_msg->object_type(n)];
    std::string modelname = set_sdf_values(sdf_data, _msg->name(n), _msg->pos_x(n), _msg->pos_y(n), _msg->pos_z(n), _msg->rot_w(n), _msg->rot_x(n), _msg->rot_y(n), _msg->rot_z(n));
    SceneObject so;
    so.type = _msg->object_type(n);
    so.frame = _msg->frame(n);
    so.child_frame = _msg->child_frame(n);
    so.objectid = _msg->objectid(n);
    _sdf.SetFromString(sdf_data);
    this->world->InsertModel(_sdf);
    so.model = this->world->GetModel(modelname);
    so.expiretime = common::Time::GetWallTime()+this->object_lifetime;
    if(so.expiretime <= this->next_expire)
      this->next_expire = so.expiretime;
    object_list[modelname] = so;
  }
}

void ObjectInstantiator::process_objects_temporary(ConstSceneObject_VPtr &_msg) {
  // remove all previouse models
  for(it = object_list.begin(); it != object_list.end(); it++) {
    this->world->rootElement->RemoveChild(it->second.model->GetID());
  }
  object_list.clear();

  // add new models
  for(int n=0; n<_msg->object_type_size(); n++) {
    sdf::SDF _sdf;
    std::string sdf_data;
    sdf_data = objects[_msg->object_type(n)];
    std::string modelname = set_sdf_values(sdf_data, _msg->name(n), _msg->pos_x(n), _msg->pos_y(n), _msg->pos_z(n), _msg->rot_w(n), _msg->rot_x(n), _msg->rot_y(n), _msg->rot_z(n));
    SceneObject so;
    so.type = _msg->object_type(n);
    so.frame = _msg->frame(n);
    so.child_frame = _msg->child_frame(n);
    so.objectid = _msg->objectid(n);
    _sdf.SetFromString(sdf_data);
    this->world->InsertModel(_sdf);
    so.model = this->world->GetModel(modelname);
    object_list[modelname] = so;
  }
}

std::string ObjectInstantiator::set_sdf_values(std::string &_sdf, std::string name, double pos_x, double pos_y, double pos_z, double rot_w, double rot_x, double rot_y, double rot_z) {
  std::ostringstream converter;
  std::string modelname;
  converter << name << "_" << this->object_count;
  modelname = converter.str();
  object_count++;
  replace(_sdf, "@NAME@", modelname);

  converter.str("");
  converter << pos_x;
  replace(_sdf, "@POSX@", converter.str());

  converter.str("");
  converter << pos_y;
  replace(_sdf, "@POSY@", converter.str());

  converter.str("");
  converter << pos_z;
  replace(_sdf, "@POSZ@", converter.str());

  converter.str("");
  converter << rot_w;
  replace(_sdf, "@ROTW@", converter.str());

  converter.str("");
  converter << rot_x;
  replace(_sdf, "@ROTX@", converter.str());

  converter.str("");
  converter << rot_y;
  replace(_sdf, "@ROTY@", converter.str());

  converter.str("");
  converter << rot_z;
  replace(_sdf, "@ROTZ@", converter.str());

  return modelname;
}

void replace(std::string &text, std::string search, std::string replace) {
  size_t position = text.find(search);
  size_t length = search.length();
  text.erase(position, length);
  text.insert(position, replace);
}
<|endoftext|>


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

#include "chrome/browser/gtk/bookmark_utils_gtk.h"

#include "app/resource_bundle.h"
#include "base/gfx/gtk_util.h"
#include "base/pickle.h"
#include "base/string_util.h"
#include "chrome/browser/bookmarks/bookmark_drag_data.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/gtk/gtk_chrome_button.h"
#include "chrome/browser/gtk/gtk_dnd_util.h"
#include "chrome/browser/profile.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"

namespace {

// Used in gtk_selection_data_set(). (I assume from this parameter that gtk has
// to some really exotic hardware...)
const int kBitsInAByte = 8;

// Maximum number of characters on a bookmark button.
const size_t kMaxCharsOnAButton = 15;

// Only used for the background of the drag widget.
const GdkColor kBackgroundColor = GDK_COLOR_RGB(0xe6, 0xed, 0xf4);

// Color of the button text, taken from TextButtonView.
const GdkColor kEnabledColor = GDK_COLOR_RGB(6, 45, 117);
const GdkColor kDisabledColor = GDK_COLOR_RGB(161, 161, 146);
// TextButtonView uses 255, 255, 255 with opacity of 200. We don't support
// transparent text though, so just use a slightly lighter version of
// kEnabledColor.
const GdkColor kHighlightColor = GDK_COLOR_RGB(56, 95, 167);

void* AsVoid(const BookmarkNode* node) {
  return const_cast<BookmarkNode*>(node);
}

}  // namespace

namespace bookmark_utils {

const char kBookmarkNode[] = "bookmark-node";

const int kBarButtonPadding = 2;

GdkPixbuf* GetFolderIcon() {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  static GdkPixbuf* default_folder_icon = rb.GetPixbufNamed(
      IDR_BOOKMARK_BAR_FOLDER);
  return default_folder_icon;
}

GdkPixbuf* GetDefaultFavicon() {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  static GdkPixbuf* default_bookmark_icon = rb.GetPixbufNamed(
      IDR_DEFAULT_FAVICON);
  return default_bookmark_icon;
}

GdkPixbuf* GetPixbufForNode(const BookmarkNode* node, BookmarkModel* model) {
  GdkPixbuf* pixbuf;

  if (node->is_url()) {
    if (model->GetFavIcon(node).width() != 0) {
      pixbuf = gfx::GdkPixbufFromSkBitmap(&model->GetFavIcon(node));
    } else {
      pixbuf = GetDefaultFavicon();
      g_object_ref(pixbuf);
    }
  } else {
    pixbuf = GetFolderIcon();
    g_object_ref(pixbuf);
  }

  return pixbuf;
}

GtkWidget* GetDragRepresentation(const BookmarkNode* node,
                                 BookmarkModel* model) {
  // Build a windowed representation for our button.
  GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP);
  gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &kBackgroundColor);
  gtk_widget_realize(window);

  GtkWidget* frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
  gtk_container_add(GTK_CONTAINER(window), frame);
  gtk_widget_show(frame);

  GtkWidget* floating_button = gtk_chrome_button_new();
  bookmark_utils::ConfigureButtonForNode(node, model, floating_button);
  gtk_container_add(GTK_CONTAINER(frame), floating_button);
  gtk_widget_show(floating_button);

  return window;
}

void ConfigureButtonForNode(const BookmarkNode* node, BookmarkModel* model,
                            GtkWidget* button) {
  std::string tooltip = BuildTooltipFor(node);
  if (!tooltip.empty())
    gtk_widget_set_tooltip_text(button, tooltip.c_str());

  // We pack the button manually (rather than using gtk_button_set_*) so that
  // we can have finer control over its label.
  GdkPixbuf* pixbuf = bookmark_utils::GetPixbufForNode(node, model);
  GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf);
  g_object_unref(pixbuf);

  GtkWidget* label = gtk_label_new(WideToUTF8(node->GetTitle()).c_str());
  gtk_label_set_max_width_chars(GTK_LABEL(label), kMaxCharsOnAButton);
  gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);

  GtkWidget* box = gtk_hbox_new(FALSE, kBarButtonPadding);
  gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
  gtk_container_add(GTK_CONTAINER(button), box);

  SetButtonTextColors(label);
  g_object_set_data(G_OBJECT(button), bookmark_utils::kBookmarkNode,
                    AsVoid(node));
}

std::string BuildTooltipFor(const BookmarkNode* node) {
  // TODO(erg): Actually build the tooltip. For now, we punt and just return
  // the URL.
  return node->GetURL().possibly_invalid_spec();
}

const BookmarkNode* BookmarkNodeForWidget(GtkWidget* widget) {
  return reinterpret_cast<const BookmarkNode*>(
      g_object_get_data(G_OBJECT(widget), bookmark_utils::kBookmarkNode));
}

void SetButtonTextColors(GtkWidget* label) {
  gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &kEnabledColor);
  gtk_widget_modify_fg(label, GTK_STATE_ACTIVE, &kEnabledColor);
  gtk_widget_modify_fg(label, GTK_STATE_PRELIGHT, &kHighlightColor);
  gtk_widget_modify_fg(label, GTK_STATE_INSENSITIVE, &kDisabledColor);
}

// DnD-related -----------------------------------------------------------------

void WriteBookmarkToSelection(const BookmarkNode* node,
                              GtkSelectionData* selection_data,
                              guint target_type,
                              Profile* profile) {
  DCHECK(node);
  std::vector<const BookmarkNode*> nodes;
  nodes.push_back(node);
  WriteBookmarksToSelection(nodes, selection_data, target_type, profile);
}

void WriteBookmarksToSelection(const std::vector<const BookmarkNode*>& nodes,
                               GtkSelectionData* selection_data,
                               guint target_type,
                               Profile* profile) {
  switch (target_type) {
    case GtkDndUtil::X_CHROME_BOOKMARK_ITEM: {
      BookmarkDragData data(nodes);
      Pickle pickle;
      data.WriteToPickle(profile, &pickle);

      gtk_selection_data_set(selection_data, selection_data->target,
                             kBitsInAByte,
                             static_cast<const guchar*>(pickle.data()),
                             pickle.size());
      break;
    }
    default: {
      DLOG(ERROR) << "Unsupported drag get type!";
    }
  }
}

std::vector<const BookmarkNode*> GetNodesFromSelection(
    GdkDragContext* context,
    GtkSelectionData* selection_data,
    guint target_type,
    Profile* profile,
    gboolean* delete_selection_data,
    gboolean* dnd_success) {
  *delete_selection_data = FALSE;
  *dnd_success = FALSE;

  if ((selection_data != NULL) && (selection_data->length >= 0)) {
    if (context->action == GDK_ACTION_MOVE) {
      *delete_selection_data = TRUE;
    }

    switch (target_type) {
      case GtkDndUtil::X_CHROME_BOOKMARK_ITEM: {
        *dnd_success = TRUE;
        Pickle pickle(reinterpret_cast<char*>(selection_data->data),
                      selection_data->length);
        BookmarkDragData drag_data;
        drag_data.ReadFromPickle(&pickle);
        return drag_data.GetNodes(profile);
      }
      default: {
        DLOG(ERROR) << "Unsupported drag received type: " << target_type;
      }
    }
  }

  return std::vector<const BookmarkNode*>();
}

}  // namespace bookmark_utils
<commit_msg>Fix bookmark util crash<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/bookmark_utils_gtk.h"

#include "app/resource_bundle.h"
#include "base/gfx/gtk_util.h"
#include "base/pickle.h"
#include "base/string_util.h"
#include "chrome/browser/bookmarks/bookmark_drag_data.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/gtk/gtk_chrome_button.h"
#include "chrome/browser/gtk/gtk_dnd_util.h"
#include "chrome/browser/profile.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"

namespace {

// Used in gtk_selection_data_set(). (I assume from this parameter that gtk has
// to some really exotic hardware...)
const int kBitsInAByte = 8;

// Maximum number of characters on a bookmark button.
const size_t kMaxCharsOnAButton = 15;

// Only used for the background of the drag widget.
const GdkColor kBackgroundColor = GDK_COLOR_RGB(0xe6, 0xed, 0xf4);

// Color of the button text, taken from TextButtonView.
const GdkColor kEnabledColor = GDK_COLOR_RGB(6, 45, 117);
const GdkColor kDisabledColor = GDK_COLOR_RGB(161, 161, 146);
// TextButtonView uses 255, 255, 255 with opacity of 200. We don't support
// transparent text though, so just use a slightly lighter version of
// kEnabledColor.
const GdkColor kHighlightColor = GDK_COLOR_RGB(56, 95, 167);

void* AsVoid(const BookmarkNode* node) {
  return const_cast<BookmarkNode*>(node);
}

}  // namespace

namespace bookmark_utils {

const char kBookmarkNode[] = "bookmark-node";

const int kBarButtonPadding = 2;

GdkPixbuf* GetFolderIcon() {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  static GdkPixbuf* default_folder_icon = rb.GetPixbufNamed(
      IDR_BOOKMARK_BAR_FOLDER);
  return default_folder_icon;
}

GdkPixbuf* GetDefaultFavicon() {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  static GdkPixbuf* default_bookmark_icon = rb.GetPixbufNamed(
      IDR_DEFAULT_FAVICON);
  return default_bookmark_icon;
}

GdkPixbuf* GetPixbufForNode(const BookmarkNode* node, BookmarkModel* model) {
  GdkPixbuf* pixbuf;

  if (node->is_url()) {
    if (model->GetFavIcon(node).width() != 0) {
      pixbuf = gfx::GdkPixbufFromSkBitmap(&model->GetFavIcon(node));
    } else {
      pixbuf = GetDefaultFavicon();
      g_object_ref(pixbuf);
    }
  } else {
    pixbuf = GetFolderIcon();
    g_object_ref(pixbuf);
  }

  return pixbuf;
}

GtkWidget* GetDragRepresentation(const BookmarkNode* node,
                                 BookmarkModel* model) {
  // Build a windowed representation for our button.
  GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP);
  gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &kBackgroundColor);
  gtk_widget_realize(window);

  GtkWidget* frame = gtk_frame_new(NULL);
  gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
  gtk_container_add(GTK_CONTAINER(window), frame);
  gtk_widget_show(frame);

  GtkWidget* floating_button = gtk_chrome_button_new();
  bookmark_utils::ConfigureButtonForNode(node, model, floating_button);
  gtk_container_add(GTK_CONTAINER(frame), floating_button);
  gtk_widget_show(floating_button);

  return window;
}

void ConfigureButtonForNode(const BookmarkNode* node, BookmarkModel* model,
                            GtkWidget* button) {
  GtkWidget* former_child = gtk_bin_get_child(GTK_BIN(button));
  if (former_child)
    gtk_container_remove(GTK_CONTAINER(button), former_child);

  std::string tooltip = BuildTooltipFor(node);
  if (!tooltip.empty())
    gtk_widget_set_tooltip_text(button, tooltip.c_str());

  // We pack the button manually (rather than using gtk_button_set_*) so that
  // we can have finer control over its label.
  GdkPixbuf* pixbuf = bookmark_utils::GetPixbufForNode(node, model);
  GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf);
  g_object_unref(pixbuf);

  GtkWidget* label = gtk_label_new(WideToUTF8(node->GetTitle()).c_str());
  gtk_label_set_max_width_chars(GTK_LABEL(label), kMaxCharsOnAButton);
  gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);

  GtkWidget* box = gtk_hbox_new(FALSE, kBarButtonPadding);
  gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
  gtk_container_add(GTK_CONTAINER(button), box);

  SetButtonTextColors(label);
  g_object_set_data(G_OBJECT(button), bookmark_utils::kBookmarkNode,
                    AsVoid(node));
}

std::string BuildTooltipFor(const BookmarkNode* node) {
  // TODO(erg): Actually build the tooltip. For now, we punt and just return
  // the URL.
  return node->GetURL().possibly_invalid_spec();
}

const BookmarkNode* BookmarkNodeForWidget(GtkWidget* widget) {
  return reinterpret_cast<const BookmarkNode*>(
      g_object_get_data(G_OBJECT(widget), bookmark_utils::kBookmarkNode));
}

void SetButtonTextColors(GtkWidget* label) {
  gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &kEnabledColor);
  gtk_widget_modify_fg(label, GTK_STATE_ACTIVE, &kEnabledColor);
  gtk_widget_modify_fg(label, GTK_STATE_PRELIGHT, &kHighlightColor);
  gtk_widget_modify_fg(label, GTK_STATE_INSENSITIVE, &kDisabledColor);
}

// DnD-related -----------------------------------------------------------------

void WriteBookmarkToSelection(const BookmarkNode* node,
                              GtkSelectionData* selection_data,
                              guint target_type,
                              Profile* profile) {
  DCHECK(node);
  std::vector<const BookmarkNode*> nodes;
  nodes.push_back(node);
  WriteBookmarksToSelection(nodes, selection_data, target_type, profile);
}

void WriteBookmarksToSelection(const std::vector<const BookmarkNode*>& nodes,
                               GtkSelectionData* selection_data,
                               guint target_type,
                               Profile* profile) {
  switch (target_type) {
    case GtkDndUtil::X_CHROME_BOOKMARK_ITEM: {
      BookmarkDragData data(nodes);
      Pickle pickle;
      data.WriteToPickle(profile, &pickle);

      gtk_selection_data_set(selection_data, selection_data->target,
                             kBitsInAByte,
                             static_cast<const guchar*>(pickle.data()),
                             pickle.size());
      break;
    }
    default: {
      DLOG(ERROR) << "Unsupported drag get type!";
    }
  }
}

std::vector<const BookmarkNode*> GetNodesFromSelection(
    GdkDragContext* context,
    GtkSelectionData* selection_data,
    guint target_type,
    Profile* profile,
    gboolean* delete_selection_data,
    gboolean* dnd_success) {
  *delete_selection_data = FALSE;
  *dnd_success = FALSE;

  if ((selection_data != NULL) && (selection_data->length >= 0)) {
    if (context->action == GDK_ACTION_MOVE) {
      *delete_selection_data = TRUE;
    }

    switch (target_type) {
      case GtkDndUtil::X_CHROME_BOOKMARK_ITEM: {
        *dnd_success = TRUE;
        Pickle pickle(reinterpret_cast<char*>(selection_data->data),
                      selection_data->length);
        BookmarkDragData drag_data;
        drag_data.ReadFromPickle(&pickle);
        return drag_data.GetNodes(profile);
      }
      default: {
        DLOG(ERROR) << "Unsupported drag received type: " << target_type;
      }
    }
  }

  return std::vector<const BookmarkNode*>();
}

}  // namespace bookmark_utils
<|endoftext|>


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

#include "views/examples/double_split_view_example.h"

#include "views/controls/single_split_view.h"
#include "views/layout/grid_layout.h"

namespace {

// DoubleSplitViews's content, which draws gradient color on background.
class SplittedView : public views::View {
 public:
  SplittedView();
  virtual ~SplittedView();

  void SetColor(SkColor from, SkColor to);

  // Overridden from views::View.
  virtual gfx::Size GetPreferredSize() OVERRIDE;
  virtual gfx::Size GetMinimumSize() OVERRIDE;

 private:
  DISALLOW_COPY_AND_ASSIGN(SplittedView);
};

SplittedView::SplittedView() {
  SetColor(SK_ColorRED, SK_ColorGREEN);
}

SplittedView::~SplittedView() {
}

void SplittedView::SetColor(SkColor from, SkColor to) {
  set_background(
      views::Background::CreateVerticalGradientBackground(from, to));
}

gfx::Size SplittedView::GetPreferredSize() {
  return gfx::Size(width(), height());
}

gfx::Size SplittedView::GetMinimumSize() {
  return gfx::Size(10, 10);
}

}  // namespace

namespace examples {

DoubleSplitViewExample::DoubleSplitViewExample(ExamplesMain* main)
    : ExampleBase(main) {
}

DoubleSplitViewExample::~DoubleSplitViewExample() {
}

std::wstring DoubleSplitViewExample::GetExampleTitle() {
  return L"Double Split View";
}

void DoubleSplitViewExample::CreateExampleView(views::View* container) {
  SplittedView* splitted_view_1 = new SplittedView();
  SplittedView* splitted_view_2 = new SplittedView();
  SplittedView* splitted_view_3 = new SplittedView();

  inner_single_split_view_ = new views::SingleSplitView(
      splitted_view_1, splitted_view_2,
      views::SingleSplitView::HORIZONTAL_SPLIT,
      NULL);

  outer_single_split_view_ = new views::SingleSplitView(
      inner_single_split_view_, splitted_view_3,
      views::SingleSplitView::HORIZONTAL_SPLIT,
      NULL);

  views::GridLayout* layout = new views::GridLayout(container);
  container->SetLayoutManager(layout);

  // Add scroll view.
  views::ColumnSet* column_set = layout->AddColumnSet(0);
  column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
                        views::GridLayout::USE_PREF, 0, 0);
  layout->StartRow(1, 0);
  layout->AddView(outer_single_split_view_);
}

}  // namespace examples
<commit_msg>Fix for Left mouse drag which was not functional  after right drag in DoubleSplitViewExample.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "views/examples/double_split_view_example.h"

#include "views/controls/single_split_view.h"
#include "views/layout/grid_layout.h"

namespace {

// DoubleSplitViews's content, which draws gradient color on background.
class SplittedView : public views::View {
 public:
  SplittedView();
  virtual ~SplittedView();

  void SetColor(SkColor from, SkColor to);

  // Overridden from views::View.
  virtual gfx::Size GetMinimumSize() OVERRIDE;

 private:
  DISALLOW_COPY_AND_ASSIGN(SplittedView);
};

SplittedView::SplittedView() {
  SetColor(SK_ColorRED, SK_ColorGREEN);
}

SplittedView::~SplittedView() {
}

void SplittedView::SetColor(SkColor from, SkColor to) {
  set_background(
      views::Background::CreateVerticalGradientBackground(from, to));
}

gfx::Size SplittedView::GetMinimumSize() {
  return gfx::Size(10, 10);
}

}  // namespace

namespace examples {

DoubleSplitViewExample::DoubleSplitViewExample(ExamplesMain* main)
    : ExampleBase(main) {
}

DoubleSplitViewExample::~DoubleSplitViewExample() {
}

std::wstring DoubleSplitViewExample::GetExampleTitle() {
  return L"Double Split View";
}

void DoubleSplitViewExample::CreateExampleView(views::View* container) {
  SplittedView* splitted_view_1 = new SplittedView();
  SplittedView* splitted_view_2 = new SplittedView();
  SplittedView* splitted_view_3 = new SplittedView();

  inner_single_split_view_ = new views::SingleSplitView(
      splitted_view_1, splitted_view_2,
      views::SingleSplitView::HORIZONTAL_SPLIT,
      NULL);

  outer_single_split_view_ = new views::SingleSplitView(
      inner_single_split_view_, splitted_view_3,
      views::SingleSplitView::HORIZONTAL_SPLIT,
      NULL);

  views::GridLayout* layout = new views::GridLayout(container);
  container->SetLayoutManager(layout);

  // Add scroll view.
  views::ColumnSet* column_set = layout->AddColumnSet(0);
  column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
                        views::GridLayout::USE_PREF, 0, 0);
  layout->StartRow(1, 0);
  layout->AddView(outer_single_split_view_);
}

}  // namespace examples
<|endoftext|>