<commit_before>#include "SequenceVectorizer.h"
#include "Opts.h"
#include "ContaminationDetection.h"
#include "Logger.h"
#include "TarjansAlgorithm.h"
#include "BarnesHutSNEAdapter.h"
#include "KrakenAdapter.h"
#include "RnammerAdapter.h"
#include "ResultIO.h"
#include "IOUtil.h"
#include "MLUtil.h"
#include "HierarchicalClustering.h"
#include "TaxonomyAnnotation.h"

#include <boost/filesystem.hpp>
#include <string>
#include <fstream>
#include <streambuf>
#include <future>
#include <map>

#include <Eigen/Dense>
#include "MatrixUtil.h"

int main(int argc, char *argv[])
{
	std::string banner = "";

	// build program arguments

	try
	{
		Opts::initializeOnce(argc, argv);

		std::ifstream ifs(Opts::sharePath() + "/banner.txt");
		banner = std::string((std::istreambuf_iterator<char>(ifs)),
		                 std::istreambuf_iterator<char>());
	}
	catch(const std::exception & e)
	{
		std::cerr << e.what() << std::endl;
		return EXIT_FAILURE;
	}

	// show help

	if (Opts::needsHelp())
	{
		std::cout << banner << std::endl;
		std::cout << Opts::helpDesc() << std::endl;
		return EXIT_SUCCESS;
	}

	// configure logger

	switch (Opts::logLevel())
	{
		case -1: Logger::getInstance().setLevel(Off); break;
		case 0: Logger::getInstance().setLevel(Error); break;
		case 1: Logger::getInstance().setLevel(Info); break;
		case 2: Logger::getInstance().setLevel(Verbose); break;
		case 3: Logger::getInstance().setLevel(Debug); break;
		default: throw std::runtime_error("Loglevel undefined!");
	}

	// check for input files

	if (Opts::inputFASTAs().empty())
	{
		ELOG << "No input FASTA file(s) given (--input-fasta,-i)." << std::endl;
		return EXIT_FAILURE;
	}

	// setup Kraken

	KrakenAdapter krk;
	bool krakenExists = krk.krakenExists();
	if (!krakenExists)
	{
		ELOG << "Kraken not found! It will be disabled.\n- Please make sure that the folders containing the 'kraken' and 'kraken-translate' executables is in your $PATH.\n- Please make sure to supply a database using the --kraken-db switch." << std::endl;
	}

	// setup Rnammer
	bool rmrExists = RnammerAdapter::rnammerExists();
	if (!rmrExists)
	{
		ELOG << "Rnammer not found! It will be disabled.\n- Please make sure that the folders containing the 'rnammer' executable is in your $PATH." << std::endl;
	}

    // create output / export directory

	boost::filesystem::path exportPath (Opts::outputDir());
	boost::system::error_code returnedError;
	boost::filesystem::create_directories(exportPath, returnedError);
	if (returnedError)
	{
		ELOG << "Could not create output/export directory, aborting." << std::endl;
		return EXIT_FAILURE;
	}

	// copy result assets

	try
	{
		IOUtil::copyDir(boost::filesystem::path(Opts::sharePath() + "/assets"), Opts::outputDir(), true);
	} catch(const boost::filesystem::filesystem_error & e)
	{
		ELOG << e.what() << std::endl;
		return EXIT_FAILURE;
	}

	// remove old data.js file if necessary

	std::string dataFile = Opts::outputDir() + "/data.js";
	if (boost::filesystem::exists(boost::filesystem::path(dataFile)))
	{
		std::remove(dataFile.c_str());
	}

    // process files

	ResultIO rio(Opts::outputDir(), krakenExists);
	unsigned idCnt = 1;

	for (const auto & fasta : Opts::inputFASTAs())
	{
		if (!boost::filesystem::is_regular_file(boost::filesystem::path(fasta)))
		{
			ELOG << "File '" << fasta << "' does not exist or is not a regular file! Skipping..." << std::endl;
			continue;
		}

		ILOG << "Processing file: " << fasta << std::endl;
		ResultContainer result;

		result.id = idCnt++;
		result.fasta = fasta;

		try
		{
			// run kraken

			if (krakenExists)
			{
				ILOG << "Running Kraken..." << std::endl;
				try
				{
					result.kraken = krk.runKraken(fasta);
				} catch(const std::exception & e)
				{
					ELOG << e.what() << std::endl;
					ELOG << "Kraken will be disabled." << std::endl;
					krakenExists = false;
				}
			}

			// gather information about input fasta

			ILOG << "Gathering fasta information..." << std::endl;

            result.stats = SequenceUtil::calculateStats(fasta, Opts::minContigLength());

            // convert sequences into vectorial data

			ILOG << "Vectorizing contigs..." << std::endl;
			SequenceVectorizer sv(fasta);
			auto svr = sv.vectorize();
			result.seqVectorization = svr;

			// run Rnammer

			if (rmrExists)
			{
				ILOG << "Running Rnammer..." << std::endl;

				try
				{
					result._16S = RnammerAdapter::find16S(fasta, svr);
				} catch(const std::exception & e)
				{
					ELOG << e.what() << std::endl;
					ELOG << "16S highlighting will be disabled." << std::endl;
					rmrExists = false;
				}
			}

			// contamination screening

			ILOG << "Detecting contamination..." << std::endl;

			std::vector<ContaminationDetectionResult> bootstraps = ContaminationDetection::analyzeBootstraps(svr);
			ContaminationDetectionResult oneshot = bootstraps.at(0);
			bootstraps.erase(bootstraps.begin());

			result.contaminationAnalysis = ContaminationDetection::summarizeBootstraps(bootstraps);

			result.dataSne = oneshot.dataSne;
			result.dataPca = oneshot.dataPca;

			// data clustering for decontamination

			ILOG << "Clustering..." << std::endl;

			result.clusterings = Decontamination::findLikelyClusterings(result.dataSne, result.dataPca, svr);

            // annotate taxonomy if exists

            if (result.contaminationAnalysis.state != "clean" && Opts::taxonomyFile() != "")
            {
				if(result.contaminationAnalysis.confidenceCC > result.contaminationAnalysis.confidenceDip)
				{
					unsigned optK = result.clusterings.numClustCC;
					VLOG << "Optimal clustering = cc with k = " << optK << std::endl;
					result.clusterings.mostLikelyClusteringName = "cc";
					result.clusterings.mostLikelyClustering = & (result.clusterings.clustsCC[0]);
				} else
				{
					unsigned optK = result.clusterings.numClustSne;
					VLOG << "Optimal clustering = validity_sne with k = " << optK << std::endl;
					result.clusterings.mostLikelyClusteringName = "validity_sne";
					result.clusterings.mostLikelyClustering = & (result.clusterings.clustsSne[optK-1]);
				}

				if (!boost::filesystem::is_regular_file(boost::filesystem::path(Opts::taxonomyFile())))
				{
					ELOG << "Taxonomy file '" << Opts::taxonomyFile() << "' does not exist or is not a regular file! Ignoring..." << std::endl;
				} else
				{
					ILOG << "Annotating taxonomy from file..." << std::endl;
	            	TaxonomyAnnotation::annotateFromFile(result, Opts::taxonomyFile());
	            	ILOG << "Annotating unknown taxonomies..." << std::endl;
					TaxonomyAnnotation::annotateUnknown(result);
				}
            }

			// write output files

            ILOG << "Writing result..." << std::endl;
			rio.processResult(result);

		} catch(const std::exception & e)
		{
			ELOG << "An error occurred processing this file: " << e.what() << std::endl;
		}
	}

	return EXIT_SUCCESS;
}
<commit_msg>tabs to spaces main.cpp<commit_after>#include "SequenceVectorizer.h"
#include "Opts.h"
#include "ContaminationDetection.h"
#include "Logger.h"
#include "TarjansAlgorithm.h"
#include "BarnesHutSNEAdapter.h"
#include "KrakenAdapter.h"
#include "RnammerAdapter.h"
#include "ResultIO.h"
#include "IOUtil.h"
#include "MLUtil.h"
#include "HierarchicalClustering.h"
#include "TaxonomyAnnotation.h"

#include <boost/filesystem.hpp>
#include <string>
#include <fstream>
#include <streambuf>
#include <future>
#include <map>

#include <Eigen/Dense>
#include "MatrixUtil.h"

int main(int argc, char *argv[])
{
    std::string banner = "";

    // build program arguments

    try
    {
        Opts::initializeOnce(argc, argv);

        std::ifstream ifs(Opts::sharePath() + "/banner.txt");
        banner = std::string((std::istreambuf_iterator<char>(ifs)),
                         std::istreambuf_iterator<char>());
    }
    catch(const std::exception & e)
    {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    // show help

    if (Opts::needsHelp())
    {
        std::cout << banner << std::endl;
        std::cout << Opts::helpDesc() << std::endl;
        return EXIT_SUCCESS;
    }

    // configure logger

    switch (Opts::logLevel())
    {
        case -1: Logger::getInstance().setLevel(Off); break;
        case 0: Logger::getInstance().setLevel(Error); break;
        case 1: Logger::getInstance().setLevel(Info); break;
        case 2: Logger::getInstance().setLevel(Verbose); break;
        case 3: Logger::getInstance().setLevel(Debug); break;
        default: throw std::runtime_error("Loglevel undefined!");
    }

    // check for input files

    if (Opts::inputFASTAs().empty())
    {
        ELOG << "No input FASTA file(s) given (--input-fasta,-i)." << std::endl;
        return EXIT_FAILURE;
    }

    // setup Kraken

    KrakenAdapter krk;
    bool krakenExists = krk.krakenExists();
    if (!krakenExists)
    {
        ELOG << "Kraken not found! It will be disabled.\n- Please make sure that the folders containing the 'kraken' and 'kraken-translate' executables is in your $PATH.\n- Please make sure to supply a database using the --kraken-db switch." << std::endl;
    }

    // setup Rnammer
    bool rmrExists = RnammerAdapter::rnammerExists();
    if (!rmrExists)
    {
        ELOG << "Rnammer not found! It will be disabled.\n- Please make sure that the folders containing the 'rnammer' executable is in your $PATH." << std::endl;
    }

    // create output / export directory

    boost::filesystem::path exportPath (Opts::outputDir());
    boost::system::error_code returnedError;
    boost::filesystem::create_directories(exportPath, returnedError);
    if (returnedError)
    {
        ELOG << "Could not create output/export directory, aborting." << std::endl;
        return EXIT_FAILURE;
    }

    // copy result assets

    try
    {
        IOUtil::copyDir(boost::filesystem::path(Opts::sharePath() + "/assets"), Opts::outputDir(), true);
    } catch(const boost::filesystem::filesystem_error & e)
    {
        ELOG << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    // remove old data.js file if necessary

    std::string dataFile = Opts::outputDir() + "/data.js";
    if (boost::filesystem::exists(boost::filesystem::path(dataFile)))
    {
        std::remove(dataFile.c_str());
    }

    // process files

    ResultIO rio(Opts::outputDir(), krakenExists);
    unsigned idCnt = 1;

    for (const auto & fasta : Opts::inputFASTAs())
    {
        if (!boost::filesystem::is_regular_file(boost::filesystem::path(fasta)))
        {
            ELOG << "File '" << fasta << "' does not exist or is not a regular file! Skipping..." << std::endl;
            continue;
        }

        ILOG << "Processing file: " << fasta << std::endl;
        ResultContainer result;

        result.id = idCnt++;
        result.fasta = fasta;

        try
        {
            // run kraken

            if (krakenExists)
            {
                ILOG << "Running Kraken..." << std::endl;
                try
                {
                    result.kraken = krk.runKraken(fasta);
                } catch(const std::exception & e)
                {
                    ELOG << e.what() << std::endl;
                    ELOG << "Kraken will be disabled." << std::endl;
                    krakenExists = false;
                }
            }

            // gather information about input fasta

            ILOG << "Gathering fasta information..." << std::endl;

            result.stats = SequenceUtil::calculateStats(fasta, Opts::minContigLength());

            // convert sequences into vectorial data

            ILOG << "Vectorizing contigs..." << std::endl;
            SequenceVectorizer sv(fasta);
            auto svr = sv.vectorize();
            result.seqVectorization = svr;

            // run Rnammer

            if (rmrExists)
            {
                ILOG << "Running Rnammer..." << std::endl;

                try
                {
                    result._16S = RnammerAdapter::find16S(fasta, svr);
                } catch(const std::exception & e)
                {
                    ELOG << e.what() << std::endl;
                    ELOG << "16S highlighting will be disabled." << std::endl;
                    rmrExists = false;
                }
            }

            // contamination screening

            ILOG << "Detecting contamination..." << std::endl;

            std::vector<ContaminationDetectionResult> bootstraps = ContaminationDetection::analyzeBootstraps(svr);
            ContaminationDetectionResult oneshot = bootstraps.at(0);
            bootstraps.erase(bootstraps.begin());

            result.contaminationAnalysis = ContaminationDetection::summarizeBootstraps(bootstraps);

            result.dataSne = oneshot.dataSne;
            result.dataPca = oneshot.dataPca;

            // data clustering for decontamination

            ILOG << "Clustering..." << std::endl;

            result.clusterings = Decontamination::findLikelyClusterings(result.dataSne, result.dataPca, svr);

            // annotate taxonomy if exists

            if (result.contaminationAnalysis.state != "clean" && Opts::taxonomyFile() != "")
            {
                if(result.contaminationAnalysis.confidenceCC > result.contaminationAnalysis.confidenceDip)
                {
                    unsigned optK = result.clusterings.numClustCC;
                    VLOG << "Optimal clustering = cc with k = " << optK << std::endl;
                    result.clusterings.mostLikelyClusteringName = "cc";
                    result.clusterings.mostLikelyClustering = & (result.clusterings.clustsCC[0]);
                } else
                {
                    unsigned optK = result.clusterings.numClustSne;
                    VLOG << "Optimal clustering = validity_sne with k = " << optK << std::endl;
                    result.clusterings.mostLikelyClusteringName = "validity_sne";
                    result.clusterings.mostLikelyClustering = & (result.clusterings.clustsSne[optK-1]);
                }

                if (!boost::filesystem::is_regular_file(boost::filesystem::path(Opts::taxonomyFile())))
                {
                    ELOG << "Taxonomy file '" << Opts::taxonomyFile() << "' does not exist or is not a regular file! Ignoring..." << std::endl;
                } else
                {
                    ILOG << "Annotating taxonomy from file..." << std::endl;
                    TaxonomyAnnotation::annotateFromFile(result, Opts::taxonomyFile());
                    ILOG << "Annotating unknown taxonomies..." << std::endl;
                    TaxonomyAnnotation::annotateUnknown(result);
                }
            }

            // write output files

            ILOG << "Writing result..." << std::endl;
            rio.processResult(result);

        } catch(const std::exception & e)
        {
            ELOG << "An error occurred processing this file: " << e.what() << std::endl;
        }
    }

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include <stdint.h>
#include <iostream>

#include "demo.pb.h"
#include "netmessages.pb.h"

#include "bitstream.h"
#include "debug.h"
#include "demo.h"
#include "entity.h"
#include "state.h"
#include "death_recording_visitor.h"

#define INSTANCE_BASELINE_TABLE "instancebaseline"
#define KEY_HISTORY_SIZE 32
#define MAX_EDICTS 0x800
#define MAX_KEY_SIZE 0x400
#define MAX_VALUE_SIZE 0x4000

enum UpdateFlag {
  UF_LeavePVS = 1,
  UF_Delete = 2,
  UF_EnterPVS = 4,
};

State *state = 0;
Visitor *visitor = new DeathRecordingVisitor();

uint32_t read_var_int(const char *data, size_t length, size_t *offset) {
  uint32_t b;
  int count = 0;
  uint32_t result = 0;

  do {
    XASSERT(count != 5, "Corrupt data.");
    XASSERT(*offset <= length, "Premature end of stream.");

    b = data[(*offset)++];
    result |= (b & 0x7F) << (7 * count);
    ++count;
  } while (b & 0x80);

  return result;
}

void dump_SVC_SendTable(const CSVCMsg_SendTable &table) {
  XASSERT(state, "SVC_SendTable but no state created.");

  SendTable &converted = state->create_send_table(table.net_table_name(), table.needs_decoder());

  size_t prop_count = table.props_size();
  for (size_t i = 0; i < prop_count; ++i) {
    const CSVCMsg_SendTable_sendprop_t &prop = table.props(i);

    SendProp c(
        static_cast<SP_Types>(prop.type()),
        prop.var_name(),
        prop.flags(),
        prop.priority(),
        prop.dt_name(),
        prop.num_elements(),
        prop.low_value(),
        prop.high_value(),
        prop.num_bits());

    converted.props.add(c);
  }
}

void dump_DEM_SendTables(const CDemoSendTables &tables) {
  const char *data = tables.data().c_str();
  size_t offset = 0;
  size_t length = tables.data().length();

  while (offset < length) {
    uint32_t command = read_var_int(data, length, &offset);
    uint32_t size = read_var_int(data, length, &offset);
    XASSERT(offset + size <= length, "Reading data outside of table.");

    XASSERT(command == svc_SendTable, "Command %u in DEM_SendTables.", command);

    CSVCMsg_SendTable send_table;
    send_table.ParseFromArray(&(data[offset]), size);
    dump_SVC_SendTable(send_table);

    offset += size;
  }
}

const StringTableEntry &get_baseline_for(int class_i) {
  XASSERT(state, "No state created.");

  StringTable &instance_baseline = state->get_string_table(INSTANCE_BASELINE_TABLE);

  char buf[32];
  sprintf(buf, "%d", class_i);

  return instance_baseline.get(buf);
}

uint32_t read_entity_header(uint32_t *base, Bitstream &stream) {
  uint32_t value = stream.get_bits(6);

  if (value & 0x30) {
    uint32_t a = (value >> 4) & 3;
    uint32_t b = (a == 3) ? 16 : 0;

    value = stream.get_bits(4 * a + b) << 4 | (value & 0xF);
  }

  *base += value + 1;

  unsigned int update_flags = 0;

  if (!stream.get_bits(1)) {
    if (stream.get_bits(1)) {
      update_flags |= UF_EnterPVS;
    }
  } else {
    update_flags |= UF_LeavePVS;
    if (stream.get_bits(1)) {
      update_flags |= UF_Delete;
    }
  }

  return update_flags;
}

void read_entity_enter_pvs(uint32_t entity_id, Bitstream &stream) {
  uint32_t class_i = stream.get_bits(state->class_bits);
  uint32_t serial = stream.get_bits(10);

  XASSERT(entity_id < MAX_EDICTS, "Entity %ld exceeds max edicts.", entity_id);

  const Class &clazz = state->get_class(class_i);
  const FlatSendTable &flat_send_table = state->flat_send_tables[clazz.dt_name];

  Entity &entity = state->entities[entity_id];

  if (entity.id != -1) {
    visitor->visit_entity_deleted(entity);
  }

  entity = Entity(entity_id, clazz, flat_send_table);

  const StringTableEntry &baseline = get_baseline_for(class_i);
  Bitstream baseline_stream(baseline.value);
  entity.update(baseline_stream);

  entity.update(stream);

  visitor->visit_entity_created(entity);
}

void read_entity_update(uint32_t entity_id, Bitstream &stream) {
  XASSERT(entity_id < MAX_ENTITIES, "Entity id too big");

  Entity &entity = state->entities[entity_id];
  XASSERT(entity.id != -1, "Entity %d is not set up.", entity_id);

  entity.update(stream);

  visitor->visit_entity_updated(entity);
}

void dump_SVC_PacketEntities(const CSVCMsg_PacketEntities &entities) {
  // Seem to get the first packet twice.
  static bool first = true;
  if (first) {
    first = false;
    return;
  }

  Bitstream stream(entities.entity_data());

  uint32_t entity_id = -1;
  size_t found = 0;
  uint32_t update_type;

  while (found < entities.updated_entries()) {
    update_type = read_entity_header(&entity_id, stream);

    if (update_type & UF_EnterPVS) {
      read_entity_enter_pvs(entity_id, stream);
    } else if (update_type & UF_LeavePVS) {
      XASSERT(entities.is_delta(), "Leave PVS on full update");

      if (update_type & UF_Delete) {
        visitor->visit_entity_deleted(state->entities[entity_id]);

        state->entities[entity_id].id = -1;
      }
    } else {
      read_entity_update(entity_id, stream);
    }

    ++found;
  }

  if (entities.is_delta()) {
    while (stream.get_bits(1)) {
      entity_id = stream.get_bits(11);
      visitor->visit_entity_deleted(state->entities[entity_id]);
      state->entities[entity_id].id = -1;
    }
  }
}

void dump_SVC_ServerInfo(const CSVCMsg_ServerInfo &info) {
  XASSERT(!state, "Already seen SVC_ServerInfo.");

  state = new State(info.max_classes());
}

void dump_DEM_ClassInfo(const CDemoClassInfo &info) {
  XASSERT(state, "DEM_ClassInfo but no state.");

  for (size_t i = 0; i < info.classes_size(); ++i) {
    const CDemoClassInfo_class_t &clazz = info.classes(i);
    state->create_class(clazz.class_id(), clazz.table_name(), clazz.network_name());
  }

  for (auto iter = state->send_tables.begin(); iter != state->send_tables.end(); ++iter) {
    SendTable &table = *iter;

    for (size_t i = 0; i < table.props.size(); ++i) {
      SendProp &prop = table.props[i];

      prop.in_table = &table;

      if (prop.type == SP_Array) {
        XASSERT(i > 0, "Array prop %s is at index zero.", prop.var_name.c_str());
        prop.array_prop = &(table.props[i - 1]);
      }
    }
  }

  state->compile_send_tables();
}

void read_string_table_key(uint32_t first_bit, Bitstream &stream, char *buf,
    size_t buf_length, std::vector<std::string> &key_history) {
  if (first_bit && stream.get_bits(1)) {
    XERROR("Not sure how to read this key");
  } else {
    uint32_t is_substring = stream.get_bits(1);

    if (is_substring) {
      uint32_t from_index = stream.get_bits(5);
      uint32_t from_length = stream.get_bits(5);
      key_history[from_index].copy(buf, from_length, 0);

      stream.read_string(buf + from_length, buf_length - from_length);
    } else {
      stream.read_string(buf, buf_length);
    }
  }
}

void update_string_table(StringTable &table, size_t num_entries, const std::string &data) {
  // These do something with precaches. This isn't a client so I'm assuming this
  // is irrelevant.
  if (table.flags & 2) {
    return;
  }

  Bitstream stream(data);

  uint32_t first_bit = stream.get_bits(1);

  std::vector<std::string> key_history;

  uint32_t entry_id = -1;
  size_t entries_read = 0;
  while (entries_read < num_entries) {
    if (!stream.get_bits(1)) {
      entry_id = stream.get_bits(table.entry_bits);
    } else {
      entry_id += 1;
    }

    XASSERT(entry_id < table.max_entries, "Entry id too large");

    char key_buffer[MAX_KEY_SIZE];
    char *key = 0;
    if (stream.get_bits(1)) {
      read_string_table_key(first_bit, stream, key_buffer, MAX_KEY_SIZE, key_history);

      key = key_buffer;

      // So technically we should only store the first 32 characters but I'm lazy.
      if (key_history.size() == KEY_HISTORY_SIZE) {
        key_history.erase(key_history.begin());
      }

      key_history.push_back(key);
    }

    char value_buffer[MAX_VALUE_SIZE];
    char *value = 0;
    size_t bit_length = 0;
    size_t length = 0;
    if (stream.get_bits(1)) {
      if (table.flags & ST_FixedLength) {
        length = table.user_data_size;
        bit_length = table.user_data_size_bits;
      } else {
        length = stream.get_bits(14);
        bit_length = 8 * length;
      }

      XASSERT(length < MAX_VALUE_SIZE, "Message too long.");

      stream.read_bits(value_buffer, bit_length);
    }

    if (entry_id < table.count()) {
      StringTableEntry &item = table.get(entry_id);

      if (key) {
        XASSERT(item.key == key, "Entry's keys don't match.");
      }

      if (value) {
        item.value = std::string(value, length);
      }
    } else {
      XASSERT(key, "Creating a new string table entry but no key specified.");

      table.put(key, std::string(value_buffer, length));
    }

    ++entries_read;
  }
}

void handle_SVC_CreateStringTable(const CSVCMsg_CreateStringTable &table) {
  XASSERT(state, "SVC_CreateStringTable but no state.");

  StringTable &converted = state->create_string_table(table.name(),
      (size_t) table.max_entries(), table.flags(), table.user_data_fixed_size(),
      table.user_data_size(), table.user_data_size_bits());

  update_string_table(converted, table.num_entries(), table.string_data());
}

void handle_SVC_UpdateStringTable(const CSVCMsg_UpdateStringTable &update) {
  XASSERT(state, "SVC_UpdateStringTable but no state.");

  StringTable &table = state->get_string_table(update.table_id());

  update_string_table(table, update.num_changed_entries(), update.string_data());
}

void clear_entities() {
  for (size_t i = 0; i < MAX_ENTITIES; ++i) {
    Entity &entity = state->entities[i];

    if (entity.id != -1) {
      visitor->visit_entity_deleted(entity);
      entity.id = -1;
    }
  }
}

void dump_DEM_Packet(const CDemoPacket &packet) {
  const char *data = packet.data().c_str();
  size_t offset = 0;
  size_t length = packet.data().length();

  while (offset < length) {
    uint32_t command = read_var_int(data, length, &offset);
    uint32_t size = read_var_int(data, length, &offset);
    XASSERT(offset + size <= length, "Reading data outside of packet.");

    if (command == svc_ServerInfo) {
      CSVCMsg_ServerInfo info;
      info.ParseFromArray(&(data[offset]), size);

      dump_SVC_ServerInfo(info);
    } else if (command == svc_PacketEntities) {
      CSVCMsg_PacketEntities entities;
      entities.ParseFromArray(&(data[offset]), size);

      dump_SVC_PacketEntities(entities);
    } else if (command == svc_CreateStringTable) {
      CSVCMsg_CreateStringTable table;
      table.ParseFromArray(&(data[offset]), size);

      handle_SVC_CreateStringTable(table);
    } else if (command == svc_UpdateStringTable) {
      CSVCMsg_UpdateStringTable table;
      table.ParseFromArray(&(data[offset]), size);

      handle_SVC_UpdateStringTable(table);
    }

    offset += size;
  }
}

void dump(const char *file) {
  Demo demo(file);

  for (int frame = 0; !demo.eof(); ++frame) {
    int tick = 0;
    size_t size;
    bool compressed;
    size_t uncompressed_size;

    EDemoCommands command = demo.get_message_type(&tick, &compressed);
    demo.read_message(compressed, &size, &uncompressed_size);

    visitor->visit_tick(tick);

    if (command == DEM_ClassInfo) {
      CDemoClassInfo info;
      info.ParseFromArray(demo.expose_buffer(), uncompressed_size);

      dump_DEM_ClassInfo(info);
    } else if (command == DEM_SendTables) {
      CDemoSendTables tables;
      tables.ParseFromArray(demo.expose_buffer(), uncompressed_size);

      dump_DEM_SendTables(tables);
    } else if (command == DEM_FullPacket) {
      CDemoFullPacket packet;
      packet.ParseFromArray(demo.expose_buffer(), uncompressed_size);

      clear_entities();
      dump_DEM_Packet(packet.packet());
    } else if (command == DEM_Packet || command == DEM_SignonPacket) {
      CDemoPacket packet;
      packet.ParseFromArray(demo.expose_buffer(), uncompressed_size);

      dump_DEM_Packet(packet);
    }
  }
}

int main(int argc, char **argv) {
  if (argc <= 1) {
    printf("Usage: %s something.dem\n", argv[0]);
    exit(1);
  } else {
    dump(argv[1]);
  }

  return 0;
}

<commit_msg>Removed full packets, fixed bug #4.<commit_after>#include <stdint.h>
#include <iostream>

#include "demo.pb.h"
#include "netmessages.pb.h"

#include "bitstream.h"
#include "debug.h"
#include "demo.h"
#include "entity.h"
#include "state.h"
#include "death_recording_visitor.h"

#define INSTANCE_BASELINE_TABLE "instancebaseline"
#define KEY_HISTORY_SIZE 32
#define MAX_EDICTS 0x800
#define MAX_KEY_SIZE 0x400
#define MAX_VALUE_SIZE 0x4000

enum UpdateFlag {
  UF_LeavePVS = 1,
  UF_Delete = 2,
  UF_EnterPVS = 4,
};

State *state = 0;
Visitor *visitor = new DeathRecordingVisitor();

uint32_t read_var_int(const char *data, size_t length, size_t *offset) {
  uint32_t b;
  int count = 0;
  uint32_t result = 0;

  do {
    XASSERT(count != 5, "Corrupt data.");
    XASSERT(*offset <= length, "Premature end of stream.");

    b = data[(*offset)++];
    result |= (b & 0x7F) << (7 * count);
    ++count;
  } while (b & 0x80);

  return result;
}

void dump_SVC_SendTable(const CSVCMsg_SendTable &table) {
  XASSERT(state, "SVC_SendTable but no state created.");

  SendTable &converted = state->create_send_table(table.net_table_name(), table.needs_decoder());

  size_t prop_count = table.props_size();
  for (size_t i = 0; i < prop_count; ++i) {
    const CSVCMsg_SendTable_sendprop_t &prop = table.props(i);

    SendProp c(
        static_cast<SP_Types>(prop.type()),
        prop.var_name(),
        prop.flags(),
        prop.priority(),
        prop.dt_name(),
        prop.num_elements(),
        prop.low_value(),
        prop.high_value(),
        prop.num_bits());

    converted.props.add(c);
  }
}

void dump_DEM_SendTables(const CDemoSendTables &tables) {
  const char *data = tables.data().c_str();
  size_t offset = 0;
  size_t length = tables.data().length();

  while (offset < length) {
    uint32_t command = read_var_int(data, length, &offset);
    uint32_t size = read_var_int(data, length, &offset);
    XASSERT(offset + size <= length, "Reading data outside of table.");

    XASSERT(command == svc_SendTable, "Command %u in DEM_SendTables.", command);

    CSVCMsg_SendTable send_table;
    send_table.ParseFromArray(&(data[offset]), size);
    dump_SVC_SendTable(send_table);

    offset += size;
  }
}

const StringTableEntry &get_baseline_for(int class_i) {
  XASSERT(state, "No state created.");

  StringTable &instance_baseline = state->get_string_table(INSTANCE_BASELINE_TABLE);

  char buf[32];
  sprintf(buf, "%d", class_i);

  return instance_baseline.get(buf);
}

uint32_t read_entity_header(uint32_t *base, Bitstream &stream) {
  uint32_t value = stream.get_bits(6);

  if (value & 0x30) {
    uint32_t a = (value >> 4) & 3;
    uint32_t b = (a == 3) ? 16 : 0;

    value = stream.get_bits(4 * a + b) << 4 | (value & 0xF);
  }

  *base += value + 1;

  unsigned int update_flags = 0;

  if (!stream.get_bits(1)) {
    if (stream.get_bits(1)) {
      update_flags |= UF_EnterPVS;
    }
  } else {
    update_flags |= UF_LeavePVS;
    if (stream.get_bits(1)) {
      update_flags |= UF_Delete;
    }
  }

  return update_flags;
}

void read_entity_enter_pvs(uint32_t entity_id, Bitstream &stream) {
  uint32_t class_i = stream.get_bits(state->class_bits);
  uint32_t serial = stream.get_bits(10);

  XASSERT(entity_id < MAX_EDICTS, "Entity %ld exceeds max edicts.", entity_id);

  const Class &clazz = state->get_class(class_i);
  const FlatSendTable &flat_send_table = state->flat_send_tables[clazz.dt_name];

  Entity &entity = state->entities[entity_id];

  if (entity.id != -1) {
    visitor->visit_entity_deleted(entity);
  }

  entity = Entity(entity_id, clazz, flat_send_table);

  const StringTableEntry &baseline = get_baseline_for(class_i);
  Bitstream baseline_stream(baseline.value);
  entity.update(baseline_stream);

  entity.update(stream);

  visitor->visit_entity_created(entity);
}

void read_entity_update(uint32_t entity_id, Bitstream &stream) {
  XASSERT(entity_id < MAX_ENTITIES, "Entity id too big");

  Entity &entity = state->entities[entity_id];
  XASSERT(entity.id != -1, "Entity %d is not set up.", entity_id);

  entity.update(stream);

  visitor->visit_entity_updated(entity);
}

void dump_SVC_PacketEntities(const CSVCMsg_PacketEntities &entities) {
  Bitstream stream(entities.entity_data());

  uint32_t entity_id = -1;
  size_t found = 0;
  uint32_t update_type;

  while (found < entities.updated_entries()) {
    update_type = read_entity_header(&entity_id, stream);

    if (update_type & UF_EnterPVS) {
      read_entity_enter_pvs(entity_id, stream);
    } else if (update_type & UF_LeavePVS) {
      XASSERT(entities.is_delta(), "Leave PVS on full update");

      if (update_type & UF_Delete) {
        visitor->visit_entity_deleted(state->entities[entity_id]);

        state->entities[entity_id].id = -1;
      }
    } else {
      read_entity_update(entity_id, stream);
    }

    ++found;
  }

  if (entities.is_delta()) {
    while (stream.get_bits(1)) {
      entity_id = stream.get_bits(11);
      visitor->visit_entity_deleted(state->entities[entity_id]);
      state->entities[entity_id].id = -1;
    }
  }
}

void dump_SVC_ServerInfo(const CSVCMsg_ServerInfo &info) {
  XASSERT(!state, "Already seen SVC_ServerInfo.");

  state = new State(info.max_classes());
}

void dump_DEM_ClassInfo(const CDemoClassInfo &info) {
  XASSERT(state, "DEM_ClassInfo but no state.");

  for (size_t i = 0; i < info.classes_size(); ++i) {
    const CDemoClassInfo_class_t &clazz = info.classes(i);
    state->create_class(clazz.class_id(), clazz.table_name(), clazz.network_name());
  }

  for (auto iter = state->send_tables.begin(); iter != state->send_tables.end(); ++iter) {
    SendTable &table = *iter;

    for (size_t i = 0; i < table.props.size(); ++i) {
      SendProp &prop = table.props[i];

      prop.in_table = &table;

      if (prop.type == SP_Array) {
        XASSERT(i > 0, "Array prop %s is at index zero.", prop.var_name.c_str());
        prop.array_prop = &(table.props[i - 1]);
      }
    }
  }

  state->compile_send_tables();
}

void read_string_table_key(uint32_t first_bit, Bitstream &stream, char *buf,
    size_t buf_length, std::vector<std::string> &key_history) {
  if (first_bit && stream.get_bits(1)) {
    XERROR("Not sure how to read this key");
  } else {
    uint32_t is_substring = stream.get_bits(1);

    if (is_substring) {
      uint32_t from_index = stream.get_bits(5);
      uint32_t from_length = stream.get_bits(5);
      key_history[from_index].copy(buf, from_length, 0);

      stream.read_string(buf + from_length, buf_length - from_length);
    } else {
      stream.read_string(buf, buf_length);
    }
  }
}

void update_string_table(StringTable &table, size_t num_entries, const std::string &data) {
  // These do something with precaches. This isn't a client so I'm assuming this
  // is irrelevant.
  if (table.flags & 2) {
    return;
  }

  Bitstream stream(data);

  uint32_t first_bit = stream.get_bits(1);

  std::vector<std::string> key_history;

  uint32_t entry_id = -1;
  size_t entries_read = 0;
  while (entries_read < num_entries) {
    if (!stream.get_bits(1)) {
      entry_id = stream.get_bits(table.entry_bits);
    } else {
      entry_id += 1;
    }

    XASSERT(entry_id < table.max_entries, "Entry id too large");

    char key_buffer[MAX_KEY_SIZE];
    char *key = 0;
    if (stream.get_bits(1)) {
      read_string_table_key(first_bit, stream, key_buffer, MAX_KEY_SIZE, key_history);

      key = key_buffer;

      // So technically we should only store the first 32 characters but I'm lazy.
      if (key_history.size() == KEY_HISTORY_SIZE) {
        key_history.erase(key_history.begin());
      }

      key_history.push_back(key);
    }

    char value_buffer[MAX_VALUE_SIZE];
    char *value = 0;
    size_t bit_length = 0;
    size_t length = 0;
    if (stream.get_bits(1)) {
      if (table.flags & ST_FixedLength) {
        length = table.user_data_size;
        bit_length = table.user_data_size_bits;
      } else {
        length = stream.get_bits(14);
        bit_length = 8 * length;
      }

      XASSERT(length < MAX_VALUE_SIZE, "Message too long.");

      stream.read_bits(value_buffer, bit_length);
    }

    if (entry_id < table.count()) {
      StringTableEntry &item = table.get(entry_id);

      if (key) {
        XASSERT(item.key == key, "Entry's keys don't match.");
      }

      if (value) {
        item.value = std::string(value, length);
      }
    } else {
      XASSERT(key, "Creating a new string table entry but no key specified.");

      table.put(key, std::string(value_buffer, length));
    }

    ++entries_read;
  }
}

void handle_SVC_CreateStringTable(const CSVCMsg_CreateStringTable &table) {
  XASSERT(state, "SVC_CreateStringTable but no state.");

  StringTable &converted = state->create_string_table(table.name(),
      (size_t) table.max_entries(), table.flags(), table.user_data_fixed_size(),
      table.user_data_size(), table.user_data_size_bits());

  update_string_table(converted, table.num_entries(), table.string_data());
}

void handle_SVC_UpdateStringTable(const CSVCMsg_UpdateStringTable &update) {
  XASSERT(state, "SVC_UpdateStringTable but no state.");

  StringTable &table = state->get_string_table(update.table_id());

  update_string_table(table, update.num_changed_entries(), update.string_data());
}

void clear_entities() {
  for (size_t i = 0; i < MAX_ENTITIES; ++i) {
    Entity &entity = state->entities[i];

    if (entity.id != -1) {
      visitor->visit_entity_deleted(entity);
      entity.id = -1;
    }
  }
}

void dump_DEM_Packet(const CDemoPacket &packet) {
  const char *data = packet.data().c_str();
  size_t offset = 0;
  size_t length = packet.data().length();

  while (offset < length) {
    uint32_t command = read_var_int(data, length, &offset);
    uint32_t size = read_var_int(data, length, &offset);
    XASSERT(offset + size <= length, "Reading data outside of packet.");

    if (command == svc_ServerInfo) {
      CSVCMsg_ServerInfo info;
      info.ParseFromArray(&(data[offset]), size);

      dump_SVC_ServerInfo(info);
    } else if (command == svc_PacketEntities) {
      CSVCMsg_PacketEntities entities;
      entities.ParseFromArray(&(data[offset]), size);

      dump_SVC_PacketEntities(entities);
    } else if (command == svc_CreateStringTable) {
      CSVCMsg_CreateStringTable table;
      table.ParseFromArray(&(data[offset]), size);

      handle_SVC_CreateStringTable(table);
    } else if (command == svc_UpdateStringTable) {
      CSVCMsg_UpdateStringTable table;
      table.ParseFromArray(&(data[offset]), size);

      handle_SVC_UpdateStringTable(table);
    }

    offset += size;
  }
}

void dump(const char *file) {
  Demo demo(file);

  for (int frame = 0; !demo.eof(); ++frame) {
    int tick = 0;
    size_t size;
    bool compressed;
    size_t uncompressed_size;

    EDemoCommands command = demo.get_message_type(&tick, &compressed);
    demo.read_message(compressed, &size, &uncompressed_size);

    visitor->visit_tick(tick);

    if (command == DEM_ClassInfo) {
      CDemoClassInfo info;
      info.ParseFromArray(demo.expose_buffer(), uncompressed_size);

      dump_DEM_ClassInfo(info);
    } else if (command == DEM_SendTables) {
      CDemoSendTables tables;
      tables.ParseFromArray(demo.expose_buffer(), uncompressed_size);

      dump_DEM_SendTables(tables);
    } else if (command == DEM_Packet || command == DEM_SignonPacket) {
      CDemoPacket packet;
      packet.ParseFromArray(demo.expose_buffer(), uncompressed_size);

      dump_DEM_Packet(packet);
    }
  }
}

int main(int argc, char **argv) {
  if (argc <= 1) {
    printf("Usage: %s something.dem\n", argv[0]);
    exit(1);
  } else {
    dump(argv[1]);
  }

  return 0;
}

<|endoftext|>


<commit_before>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you under
the Apache License, Version 2.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License at

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

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

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

//==============================================================================
// Main
//==============================================================================

#include "checkforupdateswindow.h"
#include "cliutils.h"
#include "guiutils.h"
#include "mainwindow.h"
#include "settings.h"
#include "splashscreenwindow.h"

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

#include <QDir>
#include <QLocale>
#include <QProcess>
#include <QSettings>
#include <QVariant>

#ifdef Q_OS_WIN
    #include <QWebSettings>
#endif

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

#include <QtSingleApplication>

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

int main(int pArgC, char *pArgV[])
{
    // Initialise Qt's message pattern

    OpenCOR::initQtMessagePattern();

    // Determine whether we should try the CLI version of OpenCOR:
    //  - Windows: we never try the CLI version of OpenCOR. We go straight for
    //             its GUI version.
    //  - Linux: we always try the CLI version of OpenCOR and then go for its
    //           GUI version, if needed.
    //  - OS X: we try the CLI version of OpenCOR unless the user double clicks
    //          on the OpenCOR bundle or opens it from the command line by
    //          entering something like:
    //              open OpenCOR.app
    //          in which case we go for its GUI version.
    // Note #1: on Windows, we have two binaries (.com and .exe that are for the
    //          CLI and GUI versions of OpenCOR, respectively). This means that
    //          when a console window is open, to enter something like:
    //              C:\>OpenCOR
    //          will effectively call OpenCOR.com. From there, should there be
    //          no argument that requires CLI treatment, then the GUI version of
    //          OpenCOR will be run. This is, unfortunately, the only way to
    //          have OpenCOR to behave as both a CLI and a GUI application on
    //          Windows, hence the [OpenCOR]/windows/main.cpp file, which is
    //          used to generate the CLI version of OpenCOR...
    // Note #2: on OS X, if we were to try to open the OpenCOR bundle from the
    //          command line, then we would get an error message similar to:
    //              LSOpenURLsWithRole() failed with error -10810 for the file [SomePath]/OpenCOR.app.
    //          Fortunately, when double clicking on the OpenCOR bundle or
    //          opening it from the command line, a special argument in the form
    //          of -psn_0_1234567 is passed to OpenCOR, so we can use that to
    //          determine whether we need to force OpenCOR to be run in GUI mode
    //          or whether we first try the CLI version of OpenCOR, and then its
    //          GUI version, if needed...

#if defined(Q_OS_WIN)
    bool tryCliVersion = false;
#elif defined(Q_OS_LINUX)
    bool tryCliVersion = true;
#elif defined(Q_OS_MAC)
    bool tryCliVersion = (pArgC == 1) || memcmp(pArgV[1], "-psn_", 5);
#else
    #error Unsupported platform
#endif

    // Run the CLI version of OpenCOR, if possible/needed

    if (tryCliVersion) {
        // Initialise the plugins path

        OpenCOR::initPluginsPath(pArgV[0]);

        // Create and initialise the CLI version of OpenCOR

        QCoreApplication *cliApp = new QCoreApplication(pArgC, pArgV);

        OpenCOR::initApplication(cliApp);

        // Try to run the CLI version of OpenCOR

        int res;

        bool runCliApplication = OpenCOR::cliApplication(cliApp, &res);

        OpenCOR::removeGlobalSettings();

        delete cliApp;

        if (runCliApplication) {
            // OpenCOR was run as a CLI application, so leave

            return res;
        }

        // Note: at this stage, we tried the CLI version of OpenCOR, but in the
        //       end we need to go for its GUI version, so start over but with
        //       the GUI version of OpenCOR this time...
    }

    // Make sure that we always use indirect rendering on Linux
    // Note: indeed, depending on which plugins are selected, OpenCOR may need
    //       LLVM. If that's the case, and in case the user's video card uses a
    //       driver that relies on LLVM (e.g. Gallium3D and Mesa 3D), then there
    //       may be a conflict between the version of LLVM used by OpenCOR and
    //       the one used by the video card. One way to address this issue is by
    //       using indirect rendering...

#ifdef Q_OS_LINUX
    qputenv("LIBGL_ALWAYS_INDIRECT", "1");
#endif

    // Initialise the plugins path

    OpenCOR::initPluginsPath(pArgV[0]);

    // Create the GUI version of OpenCOR

    SharedTools::QtSingleApplication *guiApp = new SharedTools::QtSingleApplication(QFileInfo(pArgV[0]).baseName(),
                                                                                pArgC, pArgV);

    // Send a message (containing the arguments that were passed to this
    // instance of OpenCOR minus the first one since it corresponds to the full
    // path to our executable, which we are not interested in) to our 'official'
    // instance of OpenCOR, should there be one. If there is none, then just
    // carry on as normal, otherwise exit since we want only one instance of
    // OpenCOR at any given time

    QStringList appArguments = guiApp->arguments();

    appArguments.removeFirst();

    QString arguments = appArguments.join("|");

    if (guiApp->isRunning()) {
        guiApp->sendMessage(arguments);

        delete guiApp;

        return 0;
    }

    // Initialise the GUI version of OpenCOR

    QString appDate = QString();

    OpenCOR::initApplication(guiApp, &appDate);

    // Check whether we want to check for new versions at startup and, if so,
    // whether a new version of OpenCOR is available

    QSettings settings(OpenCOR::SettingsOrganization, OpenCOR::SettingsApplication);

#ifndef QT_DEBUG
    settings.beginGroup("CheckForUpdatesWindow");
        bool checkForUpdatesAtStartup = settings.value(OpenCOR::SettingsCheckForUpdatesAtStartup, true).toBool();
        bool includeSnapshots = settings.value(OpenCOR::SettingsIncludeSnapshots, false).toBool();
    settings.endGroup();

    if (checkForUpdatesAtStartup) {
        OpenCOR::CheckForUpdatesEngine *checkForUpdatesEngine = new OpenCOR::CheckForUpdatesEngine(appDate);

        checkForUpdatesEngine->check();

        if (   ( includeSnapshots && checkForUpdatesEngine->hasNewerVersion())
            || (!includeSnapshots && checkForUpdatesEngine->hasNewerOfficialVersion())) {
            // Retrieve the language to be used to show the check for updates
            // window

            QString locale = OpenCOR::locale();

            QLocale::setDefault(QLocale(locale));

            QTranslator qtTranslator;
            QTranslator appTranslator;

            qtTranslator.load(":qt_"+locale);
            qApp->installTranslator(&qtTranslator);

            appTranslator.load(":app_"+locale);
            qApp->installTranslator(&appTranslator);

            // Show the check for updates window
            // Note: checkForUpdatesEngine gets deleted by
            //       checkForUpdatesWindow...

            OpenCOR::CheckForUpdatesWindow checkForUpdatesWindow(checkForUpdatesEngine);

            settings.beginGroup(checkForUpdatesWindow.objectName());
                checkForUpdatesWindow.loadSettings(&settings);
            settings.endGroup();

            checkForUpdatesWindow.exec();

            settings.beginGroup(checkForUpdatesWindow.objectName());
                checkForUpdatesWindow.saveSettings(&settings);
            settings.endGroup();
        } else {
            delete checkForUpdatesEngine;
        }
    }
#endif

    // Create and show our splash screen, if we are not in debug mode

#ifndef QT_DEBUG
    OpenCOR::SplashScreenWindow *splashScreen = new OpenCOR::SplashScreenWindow();

    splashScreen->show();
#endif

    // Create our main window

    OpenCOR::MainWindow *win = new OpenCOR::MainWindow(guiApp, appDate);

    // Keep track of our main window (required by QtSingleApplication so that it
    // can do what it's supposed to be doing)

    guiApp->setActivationWindow(win);

    // Handle our arguments

    win->handleArguments(arguments);

    // Show our main window

    win->show();

    // By default, we can and should execute our application

    bool canExecuteAplication = true;

    // Close and delete our splash screen once our main window is visible, if we
    // are not in debug mode

#ifndef QT_DEBUG
    splashScreen->closeAndDeleteAfter(win);

    // Make sure that our main window is in the foreground, unless the user
    // decided to close our main window while we were showing our splash screen
    // Note: indeed, on Linux, to show our splash screen may result in our main
    //       window being shown in the background...

    if (!win->shuttingDown())
        win->showSelf();
    else
        canExecuteAplication = false;
#endif

    // Execute our application, if possible

    int res;

    if (canExecuteAplication)
        res = guiApp->exec();
    else
        res = 0;

    // Keep track of our application file and directory paths (in case we need
    // to restart OpenCOR)

    QString appFilePath = guiApp->applicationFilePath();
    QString appDirPath  = guiApp->applicationDirPath();

    // Delete our main window

    delete win;

    // We use QtWebKit, and QWebPage in particular, which results in some leak
    // messages being generated on Windows when leaving OpenCOR. This is because
    // an object cache is shared between all QWebPage instances. So to destroy a
    // QWebPage instance doesn't clear the cache, hence the leak messages.
    // However, those messages are 'only' warnings, so we can safely live with
    // them. Still, it doesn't look 'good', so we clear the memory caches, thus
    // avoiding those leak messages...
    // Note: the below must absolutely be done after calling guiApp->exec() and
    //       before deleting guiApp...

#ifdef Q_OS_WIN
    QWebSettings::clearMemoryCaches();
#endif

    // Remove the global settings that were created and used during this session

    OpenCOR::removeGlobalSettings();

    // Delete our application

    delete guiApp;

    // We are done with the execution of our application, so now the question is
    // whether we need to restart
    // Note: we do this here rather than 'within' the GUI because once we have
    //       launched a new instance of OpenCOR, we want this instance of
    //       OpenCOR to finish as soon as possible, which will be the case here
    //       since all that remains to be done is to return the result of the
    //       execution of our application...

    if ((res == OpenCOR::CleanRestart) || (res == OpenCOR::NormalRestart)) {
        // We want to restart, so the question is whether we want a normal
        // restart or a clean one

        if (res == OpenCOR::CleanRestart) {
            // We want a clean restart, so clear all the user settings (indeed,
            // this will ensure that the various windows are, for instance,
            // properly reset with regards to their dimensions)

            settings.clear();
        }

        // Restart OpenCOR, but without providing any of the arguments that were
        // originally passed to us since we want to reset everything

        QProcess::startDetached(appFilePath, QStringList(), appDirPath);
    }

    // We are done running the GUI version of OpenCOR, so leave

    return res;
}

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Some minor cleaning up [ci skip].<commit_after>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you under
the Apache License, Version 2.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License at

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

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

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

//==============================================================================
// Main
//==============================================================================

#include "checkforupdateswindow.h"
#include "cliutils.h"
#include "guiutils.h"
#include "mainwindow.h"
#include "settings.h"
#include "splashscreenwindow.h"

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

#include <QDir>
#include <QLocale>
#include <QProcess>
#include <QSettings>
#include <QVariant>

#ifdef Q_OS_WIN
    #include <QWebSettings>
#endif

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

#include <QtSingleApplication>

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

int main(int pArgC, char *pArgV[])
{
    // Initialise Qt's message pattern

    OpenCOR::initQtMessagePattern();

    // Determine whether we should try the CLI version of OpenCOR:
    //  - Windows: we never try the CLI version of OpenCOR. We go straight for
    //             its GUI version.
    //  - Linux: we always try the CLI version of OpenCOR and then go for its
    //           GUI version, if needed.
    //  - OS X: we try the CLI version of OpenCOR unless the user double clicks
    //          on the OpenCOR bundle or opens it from the command line by
    //          entering something like:
    //              open OpenCOR.app
    //          in which case we go for its GUI version.
    // Note #1: on Windows, we have two binaries (.com and .exe that are for the
    //          CLI and GUI versions of OpenCOR, respectively). This means that
    //          when a console window is open, to enter something like:
    //              C:\>OpenCOR
    //          will effectively call OpenCOR.com. From there, should there be
    //          no argument that requires CLI treatment, then the GUI version of
    //          OpenCOR will be run. This is, unfortunately, the only way to
    //          have OpenCOR to behave as both a CLI and a GUI application on
    //          Windows, hence the [OpenCOR]/windows/main.cpp file, which is
    //          used to generate the CLI version of OpenCOR...
    // Note #2: on OS X, if we were to try to open the OpenCOR bundle from the
    //          command line, then we would get an error message similar to:
    //              LSOpenURLsWithRole() failed with error -10810 for the file [SomePath]/OpenCOR.app.
    //          Fortunately, when double clicking on the OpenCOR bundle or
    //          opening it from the command line, a special argument in the form
    //          of -psn_0_1234567 is passed to OpenCOR, so we can use that to
    //          determine whether we need to force OpenCOR to be run in GUI mode
    //          or whether we first try the CLI version of OpenCOR, and then its
    //          GUI version, if needed...

#if defined(Q_OS_WIN)
    bool tryCliVersion = false;
#elif defined(Q_OS_LINUX)
    bool tryCliVersion = true;
#elif defined(Q_OS_MAC)
    bool tryCliVersion = (pArgC == 1) || memcmp(pArgV[1], "-psn_", 5);
#else
    #error Unsupported platform
#endif

    // Run the CLI version of OpenCOR, if possible/needed

    if (tryCliVersion) {
        // Initialise the plugins path

        OpenCOR::initPluginsPath(pArgV[0]);

        // Create and initialise the CLI version of OpenCOR

        QCoreApplication *cliApp = new QCoreApplication(pArgC, pArgV);

        OpenCOR::initApplication(cliApp);

        // Try to run the CLI version of OpenCOR

        int res;

        bool runCliApplication = OpenCOR::cliApplication(cliApp, &res);

        OpenCOR::removeGlobalSettings();

        delete cliApp;

        if (runCliApplication) {
            // OpenCOR was run as a CLI application, so leave

            return res;
        }

        // Note: at this stage, we tried the CLI version of OpenCOR, but in the
        //       end we need to go for its GUI version, so start over but with
        //       the GUI version of OpenCOR this time...
    }

    // Make sure that we always use indirect rendering on Linux
    // Note: indeed, depending on which plugins are selected, OpenCOR may need
    //       LLVM. If that's the case, and in case the user's video card uses a
    //       driver that relies on LLVM (e.g. Gallium3D and Mesa 3D), then there
    //       may be a conflict between the version of LLVM used by OpenCOR and
    //       the one used by the video card. One way to address this issue is by
    //       using indirect rendering...

#ifdef Q_OS_LINUX
    qputenv("LIBGL_ALWAYS_INDIRECT", "1");
#endif

    // Initialise the plugins path

    OpenCOR::initPluginsPath(pArgV[0]);

    // Create the GUI version of OpenCOR

    SharedTools::QtSingleApplication *guiApp = new SharedTools::QtSingleApplication(QFileInfo(pArgV[0]).baseName(),
                                                                                pArgC, pArgV);

    // Send a message (containing the arguments that were passed to this
    // instance of OpenCOR minus the first one since it corresponds to the full
    // path to our executable, which we are not interested in) to our 'official'
    // instance of OpenCOR, should there be one. If there is none, then just
    // carry on as normal, otherwise exit since we want only one instance of
    // OpenCOR at any given time

    QStringList appArguments = guiApp->arguments();

    appArguments.removeFirst();

    QString arguments = appArguments.join("|");

    if (guiApp->isRunning()) {
        guiApp->sendMessage(arguments);

        delete guiApp;

        return 0;
    }

    // Initialise the GUI version of OpenCOR

    QString appDate = QString();

    OpenCOR::initApplication(guiApp, &appDate);

    // Check whether we want to check for new versions at startup and, if so,
    // whether a new version of OpenCOR is available

    QSettings settings(OpenCOR::SettingsOrganization, OpenCOR::SettingsApplication);

#ifndef QT_DEBUG
    settings.beginGroup("CheckForUpdatesWindow");
        bool checkForUpdatesAtStartup = settings.value(OpenCOR::SettingsCheckForUpdatesAtStartup, true).toBool();
        bool includeSnapshots = settings.value(OpenCOR::SettingsIncludeSnapshots, false).toBool();
    settings.endGroup();

    if (checkForUpdatesAtStartup) {
        OpenCOR::CheckForUpdatesEngine *checkForUpdatesEngine = new OpenCOR::CheckForUpdatesEngine(appDate);

        checkForUpdatesEngine->check();

        if (   ( includeSnapshots && checkForUpdatesEngine->hasNewerVersion())
            || (!includeSnapshots && checkForUpdatesEngine->hasNewerOfficialVersion())) {
            // Retrieve the language to be used to show the check for updates
            // window

            QString locale = OpenCOR::locale();

            QLocale::setDefault(QLocale(locale));

            QTranslator qtTranslator;
            QTranslator appTranslator;

            qtTranslator.load(":qt_"+locale);
            guiApp->installTranslator(&qtTranslator);

            appTranslator.load(":app_"+locale);
            guiApp->installTranslator(&appTranslator);

            // Show the check for updates window
            // Note: checkForUpdatesEngine gets deleted by
            //       checkForUpdatesWindow...

            OpenCOR::CheckForUpdatesWindow checkForUpdatesWindow(checkForUpdatesEngine);

            settings.beginGroup(checkForUpdatesWindow.objectName());
                checkForUpdatesWindow.loadSettings(&settings);
            settings.endGroup();

            checkForUpdatesWindow.exec();

            settings.beginGroup(checkForUpdatesWindow.objectName());
                checkForUpdatesWindow.saveSettings(&settings);
            settings.endGroup();
        } else {
            delete checkForUpdatesEngine;
        }
    }
#endif

    // Create and show our splash screen, if we are not in debug mode

#ifndef QT_DEBUG
    OpenCOR::SplashScreenWindow *splashScreen = new OpenCOR::SplashScreenWindow();

    splashScreen->show();
#endif

    // Create our main window

    OpenCOR::MainWindow *win = new OpenCOR::MainWindow(guiApp, appDate);

    // Keep track of our main window (required by QtSingleApplication so that it
    // can do what it's supposed to be doing)

    guiApp->setActivationWindow(win);

    // Handle our arguments

    win->handleArguments(arguments);

    // Show our main window

    win->show();

    // By default, we can and should execute our application

    bool canExecuteAplication = true;

    // Close and delete our splash screen once our main window is visible, if we
    // are not in debug mode

#ifndef QT_DEBUG
    splashScreen->closeAndDeleteAfter(win);

    // Make sure that our main window is in the foreground, unless the user
    // decided to close our main window while we were showing our splash screen
    // Note: indeed, on Linux, to show our splash screen may result in our main
    //       window being shown in the background...

    if (!win->shuttingDown())
        win->showSelf();
    else
        canExecuteAplication = false;
#endif

    // Execute our application, if possible

    int res;

    if (canExecuteAplication)
        res = guiApp->exec();
    else
        res = 0;

    // Keep track of our application file and directory paths (in case we need
    // to restart OpenCOR)

    QString appFilePath = guiApp->applicationFilePath();
    QString appDirPath  = guiApp->applicationDirPath();

    // Delete our main window

    delete win;

    // We use QtWebKit, and QWebPage in particular, which results in some leak
    // messages being generated on Windows when leaving OpenCOR. This is because
    // an object cache is shared between all QWebPage instances. So to destroy a
    // QWebPage instance doesn't clear the cache, hence the leak messages.
    // However, those messages are 'only' warnings, so we can safely live with
    // them. Still, it doesn't look 'good', so we clear the memory caches, thus
    // avoiding those leak messages...
    // Note: the below must absolutely be done after calling guiApp->exec() and
    //       before deleting guiApp...

#ifdef Q_OS_WIN
    QWebSettings::clearMemoryCaches();
#endif

    // Remove the global settings that were created and used during this session

    OpenCOR::removeGlobalSettings();

    // Delete our application

    delete guiApp;

    // We are done with the execution of our application, so now the question is
    // whether we need to restart
    // Note: we do this here rather than 'within' the GUI because once we have
    //       launched a new instance of OpenCOR, we want this instance of
    //       OpenCOR to finish as soon as possible, which will be the case here
    //       since all that remains to be done is to return the result of the
    //       execution of our application...

    if ((res == OpenCOR::CleanRestart) || (res == OpenCOR::NormalRestart)) {
        // We want to restart, so the question is whether we want a normal
        // restart or a clean one

        if (res == OpenCOR::CleanRestart) {
            // We want a clean restart, so clear all the user settings (indeed,
            // this will ensure that the various windows are, for instance,
            // properly reset with regards to their dimensions)

            settings.clear();
        }

        // Restart OpenCOR, but without providing any of the arguments that were
        // originally passed to us since we want to reset everything

        QProcess::startDetached(appFilePath, QStringList(), appDirPath);
    }

    // We are done running the GUI version of OpenCOR, so leave

    return res;
}

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


<commit_before>#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/highgui.hpp>
#include "RobustFeatureMatching.hpp"

#include <iostream>

cv::Mat stichImages (cv::Mat imgInput1, std::vector<cv::Point2f> &inlierPoints1, cv::Mat imgInput2, std::vector<cv::Point2f> &inlierPoints2)
{
    cv::Mat H = cv::findHomography(cv::Mat(inlierPoints2),
                                   cv::Mat(inlierPoints1),
                                   cv::FM_RANSAC,
                                   1.0);
    // Use the Homography Matrix to warp the images
    std::cout << "Homo: " << H << std::endl;
    cv::Mat result, warpImage2;
    cv::warpPerspective(imgInput2, warpImage2, H, cv::Size(imgInput2.cols * 2, imgInput2.rows * 2), cv::INTER_CUBIC);
    // cv::imwrite("warp.jpg", warpImage2);
    cv::Mat finalHomo(cv::Size(imgInput2.cols * 2 + imgInput1.cols, imgInput2.rows * 2), imgInput2.type());
    // cv::imwrite("finalHomo.jpg", finalHomo);
    cv::Mat roi1(finalHomo, cv::Rect(0, 0,  imgInput1.cols, imgInput1.rows));
    cv::Mat roi2(finalHomo, cv::Rect(0, 0, warpImage2.cols, warpImage2.rows));
    // cv::imwrite("roi1.jpg", roi1);
    // cv::imwrite("roi2.jpg", roi2);
    warpImage2.copyTo(roi2);
    // cv::imwrite("roi2.jpg", roi2);
    imgInput1.copyTo(roi1);
    // cv::imwrite("roi1.jpg", roi1);
    // cv::imwrite("finalHomo.jpg", finalHomo);

   int colInx = 0;
    for (size_t i(0); i < warpImage2.cols; i++)
    {

        cv::Scalar res = cv::sum(warpImage2.col(i));
        if (res[0] == 0)
        {
            colInx = i;
            break;
        }
    }
    std::cout << "Col Inx: " << colInx << std::endl;

    int rowInx = 0;
    for (size_t i(0); i < warpImage2.rows; i++)
    {

        cv::Scalar res = cv::sum(warpImage2.row(i));
        if (res[0] == 0)
        {
            rowInx = i;
            break;
        }
    }
    std::cout << "Row Inx: " << rowInx << std::endl;

    cv::Mat cropImage(warpImage2, cv::Rect(0 , 0, colInx, rowInx));
    return cropImage;

    /// crop over the finalHomo
    // int colInx = 0;
    // for (size_t i(0); i < finalHomo.cols; i++)
    // {

    //     cv::Scalar res = cv::sum(finalHomo.col(i));
    //     if (res[0] == 0)
    //     {
    //         colInx = i;
    //         break;
    //     }
    // }
    // std::cout << "Col Inx: " << colInx << std::endl;

    // int rowInx = 0;
    // for (size_t i(0); i < finalHomo.rows; i++)
    // {

    //     cv::Scalar res = cv::sum(finalHomo.row(i));
    //     if (res[0] == 0)
    //     {
    //         rowInx = i;
    //         break;
    //     }
    // }
    // std::cout << "Row Inx: " << rowInx << std::endl;

    // cv::Mat cropImage(finalHomo, cv::Rect(0 , 0, colInx, rowInx));
    // return cropImage;
}

int main(int argc, char *argv[])
{
	cv::Mat imgInput1 = cv::imread(argv[1], cv::IMREAD_GRAYSCALE);
    cv::Mat imgInput2 = cv::imread(argv[2], cv::IMREAD_GRAYSCALE);
    std::vector <cv::Point2f> inlierPoints1;
    std::vector <cv::Point2f> inlierPoints2;
    cv::Mat fundamental;
    RobustFeatureMatching matcher(0.8, 1.0, 0.99, 6);
    std::vector <cv::DMatch> finalMatches = matcher.run(imgInput1, imgInput2);
    std::cout << "Size Matched Points: " << finalMatches.size() << std::endl;
    std::pair < std::vector <cv::KeyPoint>, std::vector <cv::KeyPoint> > keyPoints = matcher.getKeyPoints();
    cv::Mat matchImage;
    cv::drawMatches(imgInput1, keyPoints.first, imgInput2, keyPoints.second, finalMatches, matchImage);
    cv::imwrite(argv[3], matchImage);
    std::pair < std::vector <cv::Point2f>, std::vector <cv::Point2f> > inlierPoints = matcher.getInlierPoints();
    cv::Mat cropImage = stichImages (imgInput1, inlierPoints.first, imgInput2, inlierPoints.second);
    cv::imwrite(argv[4], cropImage);

    finalMatches = matcher.run(imgInput1, cropImage);
    std::cout << "Size Matched Points: " << finalMatches.size() << std::endl;
    keyPoints = matcher.getKeyPoints();
    cv::drawMatches(imgInput1, keyPoints.first, cropImage, keyPoints.second, finalMatches, matchImage);
    cv::imwrite(argv[5], matchImage);

    // cv::imshow("Image Matches", matchImage);
   	// cv::waitKey(0);
	return 0;
}<commit_msg>Run feature matching for wrap image and first image<commit_after>#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/highgui.hpp>
#include "RobustFeatureMatching.hpp"

#include <iostream>

cv::Mat stichImages (cv::Mat imgInput1, std::vector<cv::Point2f> &inlierPoints1, cv::Mat imgInput2, std::vector<cv::Point2f> &inlierPoints2)
{
    cv::Mat H = cv::findHomography(cv::Mat(inlierPoints2),
                                   cv::Mat(inlierPoints1),
                                   cv::FM_RANSAC,
                                   1.0);
    // Use the Homography Matrix to warp the images
    std::cout << "Homo: " << H << std::endl;
    cv::Mat result, warpImage2;
    cv::warpPerspective(imgInput2, warpImage2, H, cv::Size(imgInput2.cols * 2, imgInput2.rows * 2), cv::INTER_CUBIC);
    // cv::imwrite("warp.jpg", warpImage2);
    cv::Mat finalHomo(cv::Size(imgInput2.cols * 2 + imgInput1.cols, imgInput2.rows * 2), imgInput2.type());
    // cv::imwrite("finalHomo.jpg", finalHomo);
    cv::Mat roi1(finalHomo, cv::Rect(0, 0,  imgInput1.cols, imgInput1.rows));
    cv::Mat roi2(finalHomo, cv::Rect(0, 0, warpImage2.cols, warpImage2.rows));
    // cv::imwrite("roi1.jpg", roi1);
    // cv::imwrite("roi2.jpg", roi2);
    warpImage2.copyTo(roi2);
    // cv::imwrite("roi2.jpg", roi2);
    imgInput1.copyTo(roi1);
    // cv::imwrite("roi1.jpg", roi1);
    // cv::imwrite("finalHomo.jpg", finalHomo);

   int colInx = 0;
    for (size_t i(0); i < warpImage2.cols; i++)
    {

        cv::Scalar res = cv::sum(warpImage2.col(i));
        if (res[0] == 0)
        {
            colInx = i;
            break;
        }
    }
    std::cout << "Col Inx: " << colInx << std::endl;

    int rowInx = 0;
    for (size_t i(0); i < warpImage2.rows; i++)
    {

        cv::Scalar res = cv::sum(warpImage2.row(i));
        if (res[0] == 0)
        {
            rowInx = i;
            break;
        }
    }
    std::cout << "Row Inx: " << rowInx << std::endl;

    cv::Mat cropImage(warpImage2, cv::Rect(0 , 0, colInx, rowInx));
    return cropImage;

    /// crop over the finalHomo
    // int colInx = 0;
    // for (size_t i(0); i < finalHomo.cols; i++)
    // {

    //     cv::Scalar res = cv::sum(finalHomo.col(i));
    //     if (res[0] == 0)
    //     {
    //         colInx = i;
    //         break;
    //     }
    // }
    // std::cout << "Col Inx: " << colInx << std::endl;

    // int rowInx = 0;
    // for (size_t i(0); i < finalHomo.rows; i++)
    // {

    //     cv::Scalar res = cv::sum(finalHomo.row(i));
    //     if (res[0] == 0)
    //     {
    //         rowInx = i;
    //         break;
    //     }
    // }
    // std::cout << "Row Inx: " << rowInx << std::endl;

    // cv::Mat cropImage(finalHomo, cv::Rect(0 , 0, colInx, rowInx));
    // return cropImage;
}

int main(int argc, char *argv[])
{
	cv::Mat imgInput1 = cv::imread(argv[1], cv::IMREAD_GRAYSCALE);
    cv::Mat imgInput2 = cv::imread(argv[2], cv::IMREAD_GRAYSCALE);
    std::vector <cv::Point2f> inlierPoints1;
    std::vector <cv::Point2f> inlierPoints2;
    cv::Mat fundamental;
    RobustFeatureMatching matcher(0.8, 1.0, 0.99, 6);
    std::vector <cv::DMatch> finalMatches = matcher.run(imgInput1, imgInput2);
    std::cout << "Size Matched Points: " << finalMatches.size() << std::endl;
    std::pair < std::vector <cv::KeyPoint>, std::vector <cv::KeyPoint> > keyPoints = matcher.getKeyPoints();
    cv::Mat matchImage;
    cv::drawMatches(imgInput1, keyPoints.first, imgInput2, keyPoints.second, finalMatches, matchImage);
    cv::imwrite(argv[3], matchImage);
    std::pair < std::vector <cv::Point2f>, std::vector <cv::Point2f> > inlierPoints = matcher.getInlierPoints();
    cv::Mat cropImage = stichImages (imgInput1, inlierPoints.first, imgInput2, inlierPoints.second);
    cv::imwrite(argv[4], cropImage);

    RobustFeatureMatching matcher2(0.8, 1.0, 0.99, 6);
    finalMatches = matcher2.run(imgInput1, cropImage);
    std::cout << "Size Matched Points: " << finalMatches.size() << std::endl;
    keyPoints = matcher2.getKeyPoints();
    cv::drawMatches(imgInput1, keyPoints.first, cropImage, keyPoints.second, finalMatches, matchImage);
    cv::imwrite(argv[5], matchImage);

    // cv::imshow("Image Matches", matchImage);
   	// cv::waitKey(0);
	return 0;
}<|endoftext|>


<commit_before>#include <iostream>

using namespace std;

// swap integers
void swap(int &a, int &b){
	int t = b;
	b = a;
	a = t;
}

int bigger(int a, int b){
	return a>b?a:b;
}

int main()
{
	cout << "hello world/n";
	return 0;
}
<commit_msg>added swap test case<commit_after>#include <iostream>

using namespace std;

// swap integers
void swap(int &a, int &b){
	int t = b;
	b = a;
	a = t;
}

int bigger(int a, int b){
	return a>b?a:b;
}

int main()
{
	cout << swap(1,2);
	return 0;
}
<|endoftext|>


<commit_before>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);
	// Read galaxies
	Gals G;
    if(F.Ascii){
        G=read_galaxies_ascii(F);}
    else{
        G = read_galaxies(F);
    }
	F.Ngal = G.size();
	printf("# Read %s galaxies from %s \n",f(F.Ngal).c_str(),F.galFile.c_str());
    std::vector<int> count;
    count=count_galaxies(G);
    for(int i=0;i<8;i++){printf ("   %d  \n",count[i]);}
    // make MTL
    MTL M=make_MTL(G,F);
    for(int i=0;i<M.priority_list.size();++i){
        printf(" priority   %d",M.priority_list[i]);
    }
    printf(" \n");
    assign_priority_class(M);
    //find available SS and SF galaxies on each petal

    std::vector <int> count_class(M.priority_list.size(),0);
    for(int i;i<M.size();++i){
        count_class[M[i].priority_class]+=1;
    }
    for(int i;i<M.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }

    printf(" number of MTL galaxies  %d\n",M.size());
    printf("Read fiber center positions and compute related things\n");
	PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1;
    printf("spectrometer has to be identified from 0 to F.Npetal-1\n");
	F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F); pp.compute_fibsofsp(F);
    printf("get neighbors of each fiber;\n");
                                                //for each spectrometer, get list of fibers

    printf("Read plates in order they are to be observed\n ");

	Plates P_original = read_plate_centers(F);
    F.Nplate=P_original.size();
    printf("This takes the place of Opsim or NextFieldSelector; will be replaced by appropriate code\n");
    Plates P;
    P.resize(F.Nplate);
    List permut = random_permut(F.Nplate);
    for (int jj=0; jj<F.Nplate; jj++){
        P[jj]=P_original[permut[jj]];
    }

	printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.Nplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct target> T(M,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();

	// For plates/fibers, collect available galaxies; done in parallel  P[plate j].av_gal[k]=[g1,g2,..]
	collect_galaxies_for_all(M,T,P,pp,F);

	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(M,P,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf("before assignment\n");
	Assignment A(M,F);
	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
	//new_assign_fibers(G,P,pp,F,A); // Plans whole survey without sky fibers, standard stars
                                   // assumes maximum number of observations needed for QSOs, LRGs
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);

    simple_assign(M,P,pp,F,A);
    diagnostic(M,G,F,A);
    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs
                                    // Want to have even distribution of unused fibers
                                    // so we can put in sky fibers and standard stars

	// Smooth out distribution of free fibers, and increase the number of assignments
	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {                           // more iterations will improve performance slightly
		improve(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
	}
	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);

	// Still not updated, so all QSO targets have multiple observations etc
	// Apply and update the plan --------------------------------------
	init_time_at(time,"# Begin real time assignment",t);
	for (int jj=0; jj<F.Nplate; jj++) {
		int j = A.next_plate;

		//assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF just before an observation
		//assign_unused(j,M,P,pp,F,A);
		//if (j%2000==0) pyplotTile(j,"doc/figs",G,P,pp,F,A); // Picture of positioners, galaxies

		//printf(" %s not as - ",format(5,f(A.unused_f(j,F))).c_str()); fl();
		// Update corrects all future occurrences of wrong QSOs etc and tries to observe something else

		if (0<=j-F.Analysis) update_plan_from_one_obs(G,M,P,pp,F,A,F.Nplate-1); else printf("\n");

		A.next_plate++;
		// Redistribute and improve on various occasions  add more times if desired

		if ( j==2000 || j==4000) {
            printf("  j == %d \n",j);
			redistribute_tf(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
			improve(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
            diagnostic(M,G,F,A);
		}
	}
	print_time(time,"# ... took :");

	// Results -------------------------------------------------------
	if (F.Output) for (int j=0; j<F.Nplate; j++) write_FAtile_ascii(j,F.outDir,M,P,pp,F,A); // Write output
	display_results("doc/figs/",M,P,pp,F,A,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

	print_time(t,"# Finished !... in");

	return(0);

}
<commit_msg>print j at 2000,4000, remove assign_unused<commit_after>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);
	// Read galaxies
	Gals G;
    if(F.Ascii){
        G=read_galaxies_ascii(F);}
    else{
        G = read_galaxies(F);
    }
	F.Ngal = G.size();
	printf("# Read %s galaxies from %s \n",f(F.Ngal).c_str(),F.galFile.c_str());
    std::vector<int> count;
    count=count_galaxies(G);
    for(int i=0;i<8;i++){printf ("   %d  \n",count[i]);}
    // make MTL
    MTL M=make_MTL(G,F);
    for(int i=0;i<M.priority_list.size();++i){
        printf(" priority   %d",M.priority_list[i]);
    }
    printf(" \n");
    assign_priority_class(M);
    //find available SS and SF galaxies on each petal

    std::vector <int> count_class(M.priority_list.size(),0);
    for(int i;i<M.size();++i){
        count_class[M[i].priority_class]+=1;
    }
    for(int i;i<M.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }

    printf(" number of MTL galaxies  %d\n",M.size());
    printf("Read fiber center positions and compute related things\n");
	PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1;
    printf("spectrometer has to be identified from 0 to F.Npetal-1\n");
	F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F); pp.compute_fibsofsp(F);
    printf("get neighbors of each fiber;\n");
                                                //for each spectrometer, get list of fibers

    printf("Read plates in order they are to be observed\n ");

	Plates P_original = read_plate_centers(F);
    F.Nplate=P_original.size();
    printf("This takes the place of Opsim or NextFieldSelector; will be replaced by appropriate code\n");
    Plates P;
    P.resize(F.Nplate);
    List permut = random_permut(F.Nplate);
    for (int jj=0; jj<F.Nplate; jj++){
        P[jj]=P_original[permut[jj]];
    }

	printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.Nplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct target> T(M,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();

	// For plates/fibers, collect available galaxies; done in parallel  P[plate j].av_gal[k]=[g1,g2,..]
	collect_galaxies_for_all(M,T,P,pp,F);

	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(M,P,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf("before assignment\n");
	Assignment A(M,F);
	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
	//new_assign_fibers(G,P,pp,F,A); // Plans whole survey without sky fibers, standard stars
                                   // assumes maximum number of observations needed for QSOs, LRGs
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);

    simple_assign(M,P,pp,F,A);
    diagnostic(M,G,F,A);
    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs
                                    // Want to have even distribution of unused fibers
                                    // so we can put in sky fibers and standard stars

	// Smooth out distribution of free fibers, and increase the number of assignments
	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {                           // more iterations will improve performance slightly
		improve(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
	}
	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);

	// Still not updated, so all QSO targets have multiple observations etc
	// Apply and update the plan --------------------------------------
	init_time_at(time,"# Begin real time assignment",t);
	for (int jj=0; jj<F.Nplate; jj++) {
		int j = A.next_plate;
        printf("  j == %d \n",j);

		//assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF just before an observation
		//assign_unused(j,M,P,pp,F,A);
		//if (j%2000==0) pyplotTile(j,"doc/figs",G,P,pp,F,A); // Picture of positioners, galaxies

		//printf(" %s not as - ",format(5,f(A.unused_f(j,F))).c_str()); fl();
		// Update corrects all future occurrences of wrong QSOs etc and tries to observe something else

		if (0<=j-F.Analysis) update_plan_from_one_obs(G,M,P,pp,F,A,F.Nplate-1); else printf("\n");

		A.next_plate++;
		// Redistribute and improve on various occasions  add more times if desired

		if ( j==2000 || j==4000) {
			redistribute_tf(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
			improve(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
            diagnostic(M,G,F,A);
		}
	}
	print_time(time,"# ... took :");

	// Results -------------------------------------------------------
	if (F.Output) for (int j=0; j<F.Nplate; j++) write_FAtile_ascii(j,F.outDir,M,P,pp,F,A); // Write output
	display_results("doc/figs/",M,P,pp,F,A,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

	print_time(t,"# Finished !... in");

	return(0);

}
<|endoftext|>


<commit_before>//
// Projectname: amos-ss16-proj5
//
// Copyright (c) 2016 de.fau.cs.osr.amos2016.gruppe5
//
// This file is part of the AMOS Project 2016 @ FAU
// (Friedrich-Alexander University Erlangen-Nürnberg)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//

/**
* This is the global main of amos-ss16-proj5.
*
* It takes a video (hdf5 or mp4), extracts it, executes object detection and scenario analysation.
* Every time a specific scenario is detected, the communication is performed.
*/

//std
#include <iostream>
#include <sstream>
#include <vector>

//local
#include "StreamDecoder/hdf5_frame_selector.h"
#include "StreamDecoder/frame_selector_factory.h"
#include "StreamDecoder/image_view.h"
#include "ProcessControl/controller.h"
//#include "ProcessControl/multithreadedcontroller.h"
#include "CarCommunication/protoagent.h"

using namespace std;

static bool
str_to_uint16(const char *str, uint16_t *res)
{
  char *end;
  errno = 0;
  intmax_t val = strtoimax(str, &end, 10);
  if (errno == ERANGE || val < 0 || val > UINT16_MAX || end == str || *end != '\0')
    return false;
  *res = (uint16_t) val;
  return true;
}

int main(int argc, const char* argv[]) {

    std::cout << "AMOS Project 2016 - Group 5 @ University of Erlangen-Nuremberg		\n"
    "																					\n"
    "                 _____   															\n"
    "                | ____|   															\n"
    "  __ _ _ __ ___ | |__   ___  ___ 													\n"
    " / _` | '_ ` _ \\|___ \\ / _ \\/ __|												\n"
    "| (_| | | | | | |___) | (_) \\__ \\												\n"
    " \\__,_|_| |_| |_|____/ \\___/|___/												\n"
    "																					\n" << std::endl;

    if (argc > 4 || argc == 1){
        cerr << "Usage1:  " << " FULL_PATH_TO_VIDEO_FILE (IMAGE_INDEX)\n";
        cerr << "Usage2:  " << " PORT (SERVERIP FULL_PATH_TO_VIDEO_FILE)" << endl;
        return -1;

    }

    if(argc == 2){
        uint16_t port;
        if(str_to_uint16(argv[1],&port))
        {
            cout << "Server port: " << port << endl;
            ProtoAgent protoagent(port);
        }
        else
        {
            cerr << "Analysing video in file " << argv[1] << endl;
            Controller controller;
            controller.AnalyseVideo(argv[1]);
        }
    }

    if(argc == 3){
        /*FrameSelectorFactory frame_selector_factory(argv[1]);
        FrameSelector* pipeline = frame_selector_factory.GetFrameSelector();
        // read one image
        unsigned int index = 0;
        stringstream string_index(argv[2]);
        string_index >> index;
        Image * result_image = pipeline->ReadImage(index);

        ImageView image_viewer;
        image_viewer.ShowImage(result_image, 0);*/
    }

    if(argc == 4){
        uint16_t port;
        if(str_to_uint16(argv[1],&port))
        {
            //MultithreadedController controller(argv[3],port,argv[2]);
            Controller controller;
            controller.InitilalizeCarConnection(port,argv[2]);
            controller.AnalyseVideo(argv[3]);
        }
        else
        {
            cerr << "Could not read port" << endl;
        }

}

    return 0;
}

<commit_msg>removed handling of arg==3 as it is no loonger used - in main<commit_after>//
// Projectname: amos-ss16-proj5
//
// Copyright (c) 2016 de.fau.cs.osr.amos2016.gruppe5
//
// This file is part of the AMOS Project 2016 @ FAU
// (Friedrich-Alexander University Erlangen-Nürnberg)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//

/**
* This is the global main of amos-ss16-proj5.
*
* It takes a video (hdf5 or mp4), extracts it, executes object detection and scenario analysation.
* Every time a specific scenario is detected, the communication is performed.
*/

//std
#include <iostream>
#include <sstream>
#include <vector>

//local
#include "StreamDecoder/hdf5_frame_selector.h"
#include "StreamDecoder/frame_selector_factory.h"
#include "StreamDecoder/image_view.h"
#include "ProcessControl/controller.h"
//#include "ProcessControl/multithreadedcontroller.h"
#include "CarCommunication/protoagent.h"

using namespace std;

static bool
str_to_uint16(const char *str, uint16_t *res)
{
  char *end;
  errno = 0;
  intmax_t val = strtoimax(str, &end, 10);
  if (errno == ERANGE || val < 0 || val > UINT16_MAX || end == str || *end != '\0')
    return false;
  *res = (uint16_t) val;
  return true;
}

int main(int argc, const char* argv[]) {

    std::cout << "AMOS Project 2016 - Group 5 @ University of Erlangen-Nuremberg		\n"
    "																					\n"
    "                 _____   															\n"
    "                | ____|   															\n"
    "  __ _ _ __ ___ | |__   ___  ___ 													\n"
    " / _` | '_ ` _ \\|___ \\ / _ \\/ __|												\n"
    "| (_| | | | | | |___) | (_) \\__ \\												\n"
    " \\__,_|_| |_| |_|____/ \\___/|___/												\n"
    "																					\n" << std::endl;

    if (argc > 4 || argc == 1 || argc == 3){
        cerr << "Usage1:  " << " FULL_PATH_TO_VIDEO_FILE (IMAGE_INDEX)\n";
        cerr << "Usage2:  " << " PORT (SERVERIP FULL_PATH_TO_VIDEO_FILE)" << endl;
        return -1;

    }

    if(argc == 2){
        uint16_t port;
        if(str_to_uint16(argv[1],&port))
        {
            cout << "Server port: " << port << endl;
            ProtoAgent protoagent(port);
        }
        else
        {
            cerr << "Analysing video in file " << argv[1] << endl;
            Controller controller;
            controller.AnalyseVideo(argv[1]);
        }
    }

    if(argc == 4){
        uint16_t port;
        if(str_to_uint16(argv[1],&port))
        {
            //MultithreadedController controller(argv[3],port,argv[2]);
            Controller controller;
            controller.InitilalizeCarConnection(port,argv[2]);
            controller.AnalyseVideo(argv[3]);
        }
        else
        {
            cerr << "Could not read port" << endl;
        }

}

    return 0;
}

<|endoftext|>