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

#include "global.hpp"
#include "MMGAPNSConnection.hpp"
#include "MMGDevice.hpp"
#include "MMGIOSPayload.hpp"
#include "MMGTools.hpp"
#include <vector>
#include <cstdlib>

#ifdef __APPLE__
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma gcc diagnostic ignored "-Wdeprecated-declarations"
#endif

static size_t get_devices_list(std::vector<MMGDevice*>& vec)
{
	// Implement your code logic to grab a list of devices
	const unsigned int badge = 1;
	MMGDevice* device = new MMGDevice("token", badge);
	vec.push_back(device);
	return vec.size();
#if 0
	/* MySQL bridging example

	 need to link with libmysqlclient or libmysqclient_r (multithread)
	 also #include <mysql/mysql.h>

	 let's assume we have a simple table like that
	 --------------
	 |   devices  |
	 |------------|
	 |token       |
	 |unread_count|
	 --------------
	 */

	mysql_library_init(0, NULL, NULL);

	// Connect to db
	MYSQL* conn = mysql_init(NULL);
	if (NULL == conn)
	{
		MMG_ERRLOG("[!] Not enough memory to allocate the MySQL connection\n");
		return 0;
	}
	mysql_options(conn, MYSQL_SET_CHARSET_NAME, "utf8");
	if (!mysql_real_connect(conn, "host-or-ip", "user", "password", "database", 0, NULL, 0))
	{
		MMG_ERRLOG("[!] mysql_real_connect: %s\n", mysql_error(conn));
		mysql_close(conn);
		return 0;
	}

	// SELECT devices list
	const char* query = "SELECT token, unread_count FROM devices";
	if (mysql_query(conn, query) != 0)
	{
		MMG_ERRLOG("[!] mysql_query: %s\n", mysql_error(conn));
		mysql_close(conn);
		return 0;
	}
	MYSQL_RES* res = mysql_use_result(conn);
	if (NULL == res)
	{
		MMG_ERRLOG("[!] mysql_use_result: %s\n", mysql_error(conn));
		mysql_close(conn);
		return 0;
	}

	// Build the list of MMGDevices
	MYSQL_ROW row = NULL;
	while ((row = mysql_fetch_row(res)))
	{
		MMGDevice* device = new MMGDevice(row[0], MMGTools::StringToUnsignedInteger(row[1]));
		vec.push_back(device);
    }

	mysql_free_result(res);
	mysql_close(conn);

	return vec.size();
#endif
}

int main(void)
{
	// SLL init only once
	SSL_load_error_strings();
	SSL_library_init();

	// Get a list of devices
	std::vector<MMGDevice*> devices;
	get_devices_list(devices);

	// Create a payload object
	MMGIOSPayload payload("Push message", "Slider label", 1, "sound.caf");

	// Create the APNS connection, empty string if no password for the private key
	MMGAPNSConnection connection(MMG_APNS_CA_PATH, MMG_APNS_CERT_PATH, MMG_APNS_PRIVATEKEY_PATH, "private-key-password", true);
	// Open the connection
	if (connection.OpenConnection() != MMGConnectionError::MMGNoError)
		return EXIT_FAILURE;

	// Send the payload
	uint32_t notifId = 1;
	for (MMGDevice* device : devices)
	{
		// Update payload badge number to reflect device's one
		payload.SetBadgeNumber(device->GetBadge());
		// Send payload to the device
		connection.SendPayloadToDevice_new(payload, *device, notifId++);
	}

	// Free up memory
	for (MMGDevice* device : devices)
		delete device;

	// Close the connection
	connection.CloseConnection();

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

#include "global.hpp"
#include "MMGAPNSConnection.hpp"
#include "MMGDevice.hpp"
#include "MMGIOSPayload.hpp"
#include "MMGTools.hpp"
#include <vector>
#include <cstdlib>

#ifdef __APPLE__
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif

static size_t get_devices_list(std::vector<MMGDevice*>& vec)
{
	// Implement your code logic to grab a list of devices
	const unsigned int badge = 1;
	MMGDevice* device = new MMGDevice("token", badge);
	vec.push_back(device);
	return vec.size();
#if 0
	/* MySQL bridging example

	 need to link with libmysqlclient or libmysqclient_r (multithread)
	 also #include <mysql/mysql.h>

	 let's assume we have a simple table like that
	 --------------
	 |   devices  |
	 |------------|
	 |token       |
	 |unread_count|
	 --------------
	 */

	mysql_library_init(0, NULL, NULL);

	// Connect to db
	MYSQL* conn = mysql_init(NULL);
	if (NULL == conn)
	{
		MMG_ERRLOG("[!] Not enough memory to allocate the MySQL connection\n");
		return 0;
	}
	mysql_options(conn, MYSQL_SET_CHARSET_NAME, "utf8");
	if (!mysql_real_connect(conn, "host-or-ip", "user", "password", "database", 0, NULL, 0))
	{
		MMG_ERRLOG("[!] mysql_real_connect: %s\n", mysql_error(conn));
		mysql_close(conn);
		return 0;
	}

	// SELECT devices list
	const char* query = "SELECT token, unread_count FROM devices";
	if (mysql_query(conn, query) != 0)
	{
		MMG_ERRLOG("[!] mysql_query: %s\n", mysql_error(conn));
		mysql_close(conn);
		return 0;
	}
	MYSQL_RES* res = mysql_use_result(conn);
	if (NULL == res)
	{
		MMG_ERRLOG("[!] mysql_use_result: %s\n", mysql_error(conn));
		mysql_close(conn);
		return 0;
	}

	// Build the list of MMGDevices
	MYSQL_ROW row = NULL;
	while ((row = mysql_fetch_row(res)))
	{
		MMGDevice* device = new MMGDevice(row[0], MMGTools::StringToUnsignedInteger(row[1]));
		vec.push_back(device);
    }

	mysql_free_result(res);
	mysql_close(conn);

	return vec.size();
#endif
}

int main(void)
{
	// SLL init only once
	SSL_load_error_strings();
	SSL_library_init();

	// Get a list of devices
	std::vector<MMGDevice*> devices;
	get_devices_list(devices);

	// Create a payload object
	MMGIOSPayload payload("Push message", "Slider label", 1, "sound.caf");

	// Create the APNS connection, empty string if no password for the private key
	MMGAPNSConnection connection(MMG_APNS_CA_PATH, MMG_APNS_CERT_PATH, MMG_APNS_PRIVATEKEY_PATH, "private-key-password", true);
	// Open the connection
	if (connection.OpenConnection() != MMGConnectionError::MMGNoError)
		return EXIT_FAILURE;

	// Send the payload
	uint32_t notifId = 1;
	for (MMGDevice* device : devices)
	{
		// Update payload badge number to reflect device's one
		payload.SetBadgeNumber(device->GetBadge());
		// Send payload to the device
		connection.SendPayloadToDevice_new(payload, *device, notifId++);
	}

	// Free up memory
	for (MMGDevice* device : devices)
		delete device;

	// Close the connection
	connection.CloseConnection();

	return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/* my own headers */
#include "landscape.h"
#include "error_handling.h"
#include "command_line.h"
#include "popsim.h"
#include "stats.h"
#include "sequence.h"

/* system headers */
#include <iostream>
#include <string>

using namespace std;

void usage(void);

int main(int argc, char *argv[]) { try {
   Args ar;
   if (argc == 1) {
      usage();
      return 0;
   }

   /* read in the command line arguments and print them out */
   ar.populate(argc, argv);
   cout << "args: " << ar << endl;

   /* create the random number generator */
   RandomNumberGenerator *rng = 0;
   rng = new RandomNumberGenerator(ar.rand_seed);

   /* create the landscape */
   Landscape *l = 0;
   switch (ar.model) {
      case block:
         l = new LandscapeBlockModel(ar.num_blocks,
            ar.seq_length/ar.num_blocks, ar.distr_mean, ar.distr_sd, rng);
         break;
      case segal:
         if (ar.autofit) {
            cerr << "autofitting" << endl;
            l = new LandscapeSegalModelFitted(ar.num_tfs, ar.pwm_filename,
               ar.segal_conditions, (unsigned int)19, ar.steps, rng,
               ar.segal_obs_expr, ar.segal_sd_lambda, ar.segal_sd_alpha,
               ar.segal_sd_gamma, ar.sequences, ar.num_slots, ar.segal_logistic_parameter, ar.segal_min_tf_sep);
         } else {
            if (ar.sampling_method == importance) {
               cerr << "using importance sampling method" << endl;
               /* we use the IS_* parameters as the importance distribution
                * from which we'll sample. And then we pass the segal_* parameters
                * as the target distribution parameters that is then used to
                * calculate the importance weights */
               l = new LandscapeSegalModelSpecifiedIS(ar.num_tfs, ar.pwm_filename,
                  ar.segal_lambda, ar.IS_segal_alpha, ar.segal_conditions,
                  ar.IS_segal_gamma, ar.steps, ar.segal_expr_fit_func, 19, rng,
                  ar.segal_gamma, ar.segal_alpha, ar.segal_logistic_parameter, ar.segal_min_tf_sep);
            } else { /* regular iid sampling */
               l = new LandscapeSegalModelSpecifiedIID(ar.num_tfs, ar.pwm_filename,
                  ar.segal_lambda, ar.segal_alpha, ar.segal_conditions,
                  ar.segal_gamma, ar.steps, ar.segal_expr_fit_func, 19, rng,
                  ar.segal_logistic_parameter, ar.segal_min_tf_sep);
            }
         }
         break;
      case neutral:
         l = new LandscapeNeutralModel(rng);
         break;
      default:
         throw SimError("invalid landscape type");
   }

   if (ar.autofit) {
      /* We're trying to fit fit the model to the provided expression data */

      LandscapeSegalModelFitted *lpt = (LandscapeSegalModelFitted*)l;
      lpt->create_chains(ar.num_chains, *ar.segal_chain_temps);
      cerr << "auto fit created " << lpt->parallel_tempered.num_chains() <<
         " chains" << endl;
      lpt->precompute_lookup_tables(ar.sequences, ar.steps);
      cerr << "initing energies" << endl;
      lpt->parallel_tempered.init_energies();
      cerr << "running chains" << endl;
      lpt->parallel_tempered.run_chains(ar.segal_chain_steps);

   } else if (ar.do_popsim) {
      /* we're doing a population simulation */

      PopState ps(ar.pop_size, ar.mu_rate, ar.rec_rate, l, ar.deletion_params,
         ar.duplication_params);

      /* give the popstats access to the popstate and set stats marked print
       * at end, to print at the end. */
      for (vector<PopStat>::iterator i = ar.popstats.begin();
            i != ar.popstats.end(); i++) {
         i->set_popstate(&ps);
         if (i->modulo == PRINT_STAT_AT_END)
            i->modulo = ar.generations;
      }

      /* create an allele unless we have ones from the command line */
      if (ar.sequences.size() < 1) {
         string empty(ar.seq_length, l->alphabet[0]);
         Sequence s(empty, l->alphabet);
         l->rng->uniform_dna(s, ar.seq_length, l);
         ps.alleles[s] = new Allele(s, ps.N, ps.generation, l);
      }
      for (vector<string>::iterator i = ar.sequences.begin();
            i != ar.sequences.end(); i++) {
         Sequence s(*i, l->alphabet);
         ps.alleles[s] = new Allele(s, ps.N/ar.sequences.size(),
            ps.generation, l);
      }

      /* run the simulation */
      ps.run(ar.popstats, ar.generations);

   } else {
      /* characterization of landscape part */

      /* make sure we're not asked for popstats if not doing a popsim */
      if (ar.popstats.size() > 0) {
         cerr << "pop stats require --popsim option" << endl;
         usage();
      }

      /* give the scapetats access to the landscape */
      for (vector<ScapeStat>::iterator i = ar.scapestats.begin();
            i != ar.scapestats.end(); i++)
         i->set_landscape(l);

      /* loop, sampling nodes in the landscape uniformly until we do enough */
      set<Sequence> draws;
      for (vector<string>::iterator i = ar.sequences.begin();
            i != ar.sequences.end(); i++) {
         Sequence s(*i, l->alphabet);
         draws.insert(s);
      }
      sort(ar.scapestats.rbegin(), ar.scapestats.rend());
      for (l->cur_rep = 0; l->cur_rep < ar.max_reps; l->cur_rep++) {
         if (draws.size() == 0) {
            Sequence draw = l->sample(ar.seq_length);
            draws.insert(draw);
         }
         unsigned int ns = ar.neighbor_steps;
         while (ns-- > 0) {
            /* add neighbors */
            l->insert_neighbors(draws);
         }
         for (set<Sequence>::iterator dr=draws.begin(); dr!=draws.end(); dr++) {
            for (vector<ScapeStat>::iterator i = ar.scapestats.begin();
                  i != ar.scapestats.end(); i++) {
               if (l->cur_rep < i->reps) {
                  i->calc_and_show(cout, *dr);
               } else {
                  /* since we've sorted the stats by reps required, when we
                   * encounter a stat that's already done enough reps we know
                   * the rest have also done enough reps */
                  break;
               }
            }
         }
         draws.clear();
      }
   }

   if (rng != 0) delete rng;
   if (l!=0) delete l;

/* deal with various possible errors */
} catch (SimUsageError e) {
   cerr << endl << "detected usage error: " << e.detail << endl << endl;
   usage();
   return 1;
} catch(SimError &e) {
   cerr << "uncaught exception: " << e.detail << endl;

/* exit */
} return 0; }

/* print out usage information */
void usage(void) {
   cerr <<
"usage: scapestats [options]\n"
"\n"
"  general options:\n"
"     -m/--model (block|segal|neutral)\n"
"     --popsim                   - run a population simulation\n"
"     --seed <int>               - random number generator seed\n"
"     --seq <string>             - a sequence to queue\n"
"\n"
"  model-specific options: \n"
"     block model:\n"
"        --mean <float>          - mean of within-block distr.\n"
"        --sd <float>            - sd of within-block distr.\n"
"        --blocks <int>          - number of blocks\n"
"        --length <int>          - length of sequence\n"
"\n"
"     segal model, general:\n"
"        --length <int>          - length of sequence\n"
"        --tfs <int>             - number of transcription factors\n"
"        --pwm <filename>        - filename containing PWM definitions\n"
"        --condition=c1,c2,...   - list of floats specifying TF levels\n"
"                                  multiple of conditions may be specified\n"
"        --steps <int>           - number of iid samples for estimating expr.\n"
"\n"
"     segal model automatic parameter estimation:\n"
"        --autofit               - when specified, will try and fit params\n"
"        --chains <int>          - number of parallel tempering chains\n"
"        --chain_steps <int>     - number of steps to run the chain\n"
"        --expression=e1,e2,...  - observed expression. One entry per seq.\n"
"        --psd_lambda <float>    - proposal variance for lambda updates\n"
"        --psd_alpha <float>     - proposal variance for alpha updates\n"
"        --psd_gamma <float>     - proposal variance for gamma updates\n"
//"        --alpha_lattice=a1,a2,  - grid of alpha (expr scalar) values for IS\n"
"\n"
"     segal model paremeters\n"
"        --lambda=l0,l1,l2,...   - list of floats for baseline and TF lambda\n"
"        --gamma=g11,g21,g12,g22 - cooperativity matrix by column\n"
"        --alpha=s1,s2,...       - expression scaling parameters\n"
"        --logistic_param=d      - use 1/(1+exp(-x/d))\n"
"        --tfsep <int>           - minimum spacing between TFs in a config\n"
"\n"
"     segal expression-fitness function\n"
"        --ffunc <choice>        - here are the fitness function choices.\n"
"                                  --coef must bi given with the correct\n"
"                                  number of coefficients.\n"
"           linear : f = <x> dot <c> where x is the expr. vec., c coef vec.\n"
"           nop : f = 1\n"
"           f1 : f = a * (x1-b)^2 + c * (x2-d)^2 + e\n"
"           f2 : f = a^(-b*(x1-c)^2) * d^(-e*(x2-f)^2)\n"
"           f3 : f = prod(a^(-b*(xi-ci)^2))^(1/C) : i in (1..C) for C cond.\n"
"           f4 : f = exp((-1)*sum((xi-bi)^2/a)) : i in (1...C) for C cond.\n"
"        --coef=a,b,c,..         - list of coefficients for chosen fit. func.\n"
"\n"
"     segal model sampling parameters:\n"
"        --sampling=<iid|importance>  - which sampling method to employ\n"
"        --IS_gamma=g11,g21,g12,g22   - IS distr. cooperativity matrix\n"
"        --IS_alpha=s1,s2,...         - list of expr. scalars, one per TF\n"
"\n"
"  population simulation options:\n"
"     -g/--generations <int>     - number of gen to run\n"
"     -u/--mutation <float>      - per bp mutation rate\n"
"     -N/--popsize <int>         - effective population size\n"
"     --deletion=u,n,p           - rate, and negative binomial dup params\n"
"     --duplication=u,n,p        - rate, and negative binomial dup params\n"
"\n"
"  population statistics options (only valid in the presence\n"
"           of --popsim. May use multiple pstat options. Of the form\n"
"           --pstat=statname to print at the end or --pstat=statname,2\n"
"           if one wants statname printed every 2 generations. Default is\n"
"           each generation).\n"
"     --pstat=most_freq_seq      - most frequent allele\n"
"     --pstat=most_freq_noseq    - most frequent allele minus the sequence\n"
"     --pstat=mean_fitness       - population mean fitness\n"
"     --pstat=all_alleles        - details of each allele, sorted by # copies\n"
"     --pstat=allele_counter     - number of alleles queried so far\n"
//"     --pstat=site_frequencies   - positions and frequencies of seg. sites\n"
"\n"
"  population real-time statistics:\n"
"     --pstat=mutational_effects - print fitness info for new mutants\n"
"     --pstat=allele_loss        - print the generation and allele id for\n"
"                                  alleles when they're lost\n"
"\n"
"  landscape sampling/traversal options:\n"
"     --neighbors <int>          - for each sample, include neighbors within\n"
"                                  the specified number of steps\n"
"\n"
"  landscape statistic options (only valid in the absence of --popsim.\n"
"           May use multiple lstat options. In all cases, reps is the number\n"
"           of nodes for which the statistic will be printed, all uniformly\n"
"           sampled from the landscape. If multiple statistics are requested\n"
"           the same starting points will be used up until the number of reps\n"
"           for each particular statistic is reached. All parameters are\n"
"           always required for each statistic.)\n"
"     --lstat=fitness,reps          - node fitness\n"
"     --lstat=n_step_mean,reps,n,s  - mean fitness (s samples) n steps away\n"
"     --lstat=banding,reps,x        - band statistics for tried size x\n"
"     --lstat=sequence,reps         - print out sequence per rep\n"
"\n"
"  landscape statistics specifically for Segal model\n"
"     --lstat=expression,reps       - print vector of expression levels\n"
"     --lstat=tf_occupancy,reps     - print list of TF occupancy levels for\n"
"                                     each condition and TF combination\n"
"     --lstat=wsum,reps             - the sum of all configuration weights\n"
"     --lstat=configs,1             - print out configurations\n"
"\n";
   return;
}
<commit_msg>Changed the program name from scapestats to regevscape<commit_after>/* my own headers */
#include "landscape.h"
#include "error_handling.h"
#include "command_line.h"
#include "popsim.h"
#include "stats.h"
#include "sequence.h"

/* system headers */
#include <iostream>
#include <string>

using namespace std;

void usage(void);

int main(int argc, char *argv[]) { try {
   Args ar;
   if (argc == 1) {
      usage();
      return 0;
   }

   /* read in the command line arguments and print them out */
   ar.populate(argc, argv);
   cout << "args: " << ar << endl;

   /* create the random number generator */
   RandomNumberGenerator *rng = 0;
   rng = new RandomNumberGenerator(ar.rand_seed);

   /* create the landscape */
   Landscape *l = 0;
   switch (ar.model) {
      case block:
         l = new LandscapeBlockModel(ar.num_blocks,
            ar.seq_length/ar.num_blocks, ar.distr_mean, ar.distr_sd, rng);
         break;
      case segal:
         if (ar.autofit) {
            cerr << "autofitting" << endl;
            l = new LandscapeSegalModelFitted(ar.num_tfs, ar.pwm_filename,
               ar.segal_conditions, (unsigned int)19, ar.steps, rng,
               ar.segal_obs_expr, ar.segal_sd_lambda, ar.segal_sd_alpha,
               ar.segal_sd_gamma, ar.sequences, ar.num_slots, ar.segal_logistic_parameter, ar.segal_min_tf_sep);
         } else {
            if (ar.sampling_method == importance) {
               cerr << "using importance sampling method" << endl;
               /* we use the IS_* parameters as the importance distribution
                * from which we'll sample. And then we pass the segal_* parameters
                * as the target distribution parameters that is then used to
                * calculate the importance weights */
               l = new LandscapeSegalModelSpecifiedIS(ar.num_tfs, ar.pwm_filename,
                  ar.segal_lambda, ar.IS_segal_alpha, ar.segal_conditions,
                  ar.IS_segal_gamma, ar.steps, ar.segal_expr_fit_func, 19, rng,
                  ar.segal_gamma, ar.segal_alpha, ar.segal_logistic_parameter, ar.segal_min_tf_sep);
            } else { /* regular iid sampling */
               l = new LandscapeSegalModelSpecifiedIID(ar.num_tfs, ar.pwm_filename,
                  ar.segal_lambda, ar.segal_alpha, ar.segal_conditions,
                  ar.segal_gamma, ar.steps, ar.segal_expr_fit_func, 19, rng,
                  ar.segal_logistic_parameter, ar.segal_min_tf_sep);
            }
         }
         break;
      case neutral:
         l = new LandscapeNeutralModel(rng);
         break;
      default:
         throw SimError("invalid landscape type");
   }

   if (ar.autofit) {
      /* We're trying to fit fit the model to the provided expression data */

      LandscapeSegalModelFitted *lpt = (LandscapeSegalModelFitted*)l;
      lpt->create_chains(ar.num_chains, *ar.segal_chain_temps);
      cerr << "auto fit created " << lpt->parallel_tempered.num_chains() <<
         " chains" << endl;
      lpt->precompute_lookup_tables(ar.sequences, ar.steps);
      cerr << "initing energies" << endl;
      lpt->parallel_tempered.init_energies();
      cerr << "running chains" << endl;
      lpt->parallel_tempered.run_chains(ar.segal_chain_steps);

   } else if (ar.do_popsim) {
      /* we're doing a population simulation */

      PopState ps(ar.pop_size, ar.mu_rate, ar.rec_rate, l, ar.deletion_params,
         ar.duplication_params);

      /* give the popstats access to the popstate and set stats marked print
       * at end, to print at the end. */
      for (vector<PopStat>::iterator i = ar.popstats.begin();
            i != ar.popstats.end(); i++) {
         i->set_popstate(&ps);
         if (i->modulo == PRINT_STAT_AT_END)
            i->modulo = ar.generations;
      }

      /* create an allele unless we have ones from the command line */
      if (ar.sequences.size() < 1) {
         string empty(ar.seq_length, l->alphabet[0]);
         Sequence s(empty, l->alphabet);
         l->rng->uniform_dna(s, ar.seq_length, l);
         ps.alleles[s] = new Allele(s, ps.N, ps.generation, l);
      }
      for (vector<string>::iterator i = ar.sequences.begin();
            i != ar.sequences.end(); i++) {
         Sequence s(*i, l->alphabet);
         ps.alleles[s] = new Allele(s, ps.N/ar.sequences.size(),
            ps.generation, l);
      }

      /* run the simulation */
      ps.run(ar.popstats, ar.generations);

   } else {
      /* characterization of landscape part */

      /* make sure we're not asked for popstats if not doing a popsim */
      if (ar.popstats.size() > 0) {
         cerr << "pop stats require --popsim option" << endl;
         usage();
      }

      /* give the scapetats access to the landscape */
      for (vector<ScapeStat>::iterator i = ar.scapestats.begin();
            i != ar.scapestats.end(); i++)
         i->set_landscape(l);

      /* loop, sampling nodes in the landscape uniformly until we do enough */
      set<Sequence> draws;
      for (vector<string>::iterator i = ar.sequences.begin();
            i != ar.sequences.end(); i++) {
         Sequence s(*i, l->alphabet);
         draws.insert(s);
      }
      sort(ar.scapestats.rbegin(), ar.scapestats.rend());
      for (l->cur_rep = 0; l->cur_rep < ar.max_reps; l->cur_rep++) {
         if (draws.size() == 0) {
            Sequence draw = l->sample(ar.seq_length);
            draws.insert(draw);
         }
         unsigned int ns = ar.neighbor_steps;
         while (ns-- > 0) {
            /* add neighbors */
            l->insert_neighbors(draws);
         }
         for (set<Sequence>::iterator dr=draws.begin(); dr!=draws.end(); dr++) {
            for (vector<ScapeStat>::iterator i = ar.scapestats.begin();
                  i != ar.scapestats.end(); i++) {
               if (l->cur_rep < i->reps) {
                  i->calc_and_show(cout, *dr);
               } else {
                  /* since we've sorted the stats by reps required, when we
                   * encounter a stat that's already done enough reps we know
                   * the rest have also done enough reps */
                  break;
               }
            }
         }
         draws.clear();
      }
   }

   if (rng != 0) delete rng;
   if (l!=0) delete l;

/* deal with various possible errors */
} catch (SimUsageError e) {
   cerr << endl << "detected usage error: " << e.detail << endl << endl;
   usage();
   return 1;
} catch(SimError &e) {
   cerr << "uncaught exception: " << e.detail << endl;

/* exit */
} return 0; }

/* print out usage information */
void usage(void) {
   cerr <<
"usage: regevscape [options]\n"
"\n"
"  general options:\n"
"     -m/--model (block|segal|neutral)\n"
"     --popsim                   - run a population simulation\n"
"     --seed <int>               - random number generator seed\n"
"     --seq <string>             - a sequence to queue\n"
"\n"
"  model-specific options: \n"
"     block model:\n"
"        --mean <float>          - mean of within-block distr.\n"
"        --sd <float>            - sd of within-block distr.\n"
"        --blocks <int>          - number of blocks\n"
"        --length <int>          - length of sequence\n"
"\n"
"     segal model, general:\n"
"        --length <int>          - length of sequence\n"
"        --tfs <int>             - number of transcription factors\n"
"        --pwm <filename>        - filename containing PWM definitions\n"
"        --condition=c1,c2,...   - list of floats specifying TF levels\n"
"                                  multiple of conditions may be specified\n"
"        --steps <int>           - number of iid samples for estimating expr.\n"
"\n"
"     segal model automatic parameter estimation:\n"
"        --autofit               - when specified, will try and fit params\n"
"        --chains <int>          - number of parallel tempering chains\n"
"        --chain_steps <int>     - number of steps to run the chain\n"
"        --expression=e1,e2,...  - observed expression. One entry per seq.\n"
"        --psd_lambda <float>    - proposal variance for lambda updates\n"
"        --psd_alpha <float>     - proposal variance for alpha updates\n"
"        --psd_gamma <float>     - proposal variance for gamma updates\n"
//"        --alpha_lattice=a1,a2,  - grid of alpha (expr scalar) values for IS\n"
"\n"
"     segal model paremeters\n"
"        --lambda=l0,l1,l2,...   - list of floats for baseline and TF lambda\n"
"        --gamma=g11,g21,g12,g22 - cooperativity matrix by column\n"
"        --alpha=s1,s2,...       - expression scaling parameters\n"
"        --logistic_param=d      - use 1/(1+exp(-x/d))\n"
"        --tfsep <int>           - minimum spacing between TFs in a config\n"
"\n"
"     segal expression-fitness function\n"
"        --ffunc <choice>        - here are the fitness function choices.\n"
"                                  --coef must bi given with the correct\n"
"                                  number of coefficients.\n"
"           linear : f = <x> dot <c> where x is the expr. vec., c coef vec.\n"
"           nop : f = 1\n"
"           f1 : f = a * (x1-b)^2 + c * (x2-d)^2 + e\n"
"           f2 : f = a^(-b*(x1-c)^2) * d^(-e*(x2-f)^2)\n"
"           f3 : f = prod(a^(-b*(xi-ci)^2))^(1/C) : i in (1..C) for C cond.\n"
"           f4 : f = exp((-1)*sum((xi-bi)^2/a)) : i in (1...C) for C cond.\n"
"        --coef=a,b,c,..         - list of coefficients for chosen fit. func.\n"
"\n"
"     segal model sampling parameters:\n"
"        --sampling=<iid|importance>  - which sampling method to employ\n"
"        --IS_gamma=g11,g21,g12,g22   - IS distr. cooperativity matrix\n"
"        --IS_alpha=s1,s2,...         - list of expr. scalars, one per TF\n"
"\n"
"  population simulation options:\n"
"     -g/--generations <int>     - number of gen to run\n"
"     -u/--mutation <float>      - per bp mutation rate\n"
"     -N/--popsize <int>         - effective population size\n"
"     --deletion=u,n,p           - rate, and negative binomial dup params\n"
"     --duplication=u,n,p        - rate, and negative binomial dup params\n"
"\n"
"  population statistics options (only valid in the presence\n"
"           of --popsim. May use multiple pstat options. Of the form\n"
"           --pstat=statname to print at the end or --pstat=statname,2\n"
"           if one wants statname printed every 2 generations. Default is\n"
"           each generation).\n"
"     --pstat=most_freq_seq      - most frequent allele\n"
"     --pstat=most_freq_noseq    - most frequent allele minus the sequence\n"
"     --pstat=mean_fitness       - population mean fitness\n"
"     --pstat=all_alleles        - details of each allele, sorted by # copies\n"
"     --pstat=allele_counter     - number of alleles queried so far\n"
//"     --pstat=site_frequencies   - positions and frequencies of seg. sites\n"
"\n"
"  population real-time statistics:\n"
"     --pstat=mutational_effects - print fitness info for new mutants\n"
"     --pstat=allele_loss        - print the generation and allele id for\n"
"                                  alleles when they're lost\n"
"\n"
"  landscape sampling/traversal options:\n"
"     --neighbors <int>          - for each sample, include neighbors within\n"
"                                  the specified number of steps\n"
"\n"
"  landscape statistic options (only valid in the absence of --popsim.\n"
"           May use multiple lstat options. In all cases, reps is the number\n"
"           of nodes for which the statistic will be printed, all uniformly\n"
"           sampled from the landscape. If multiple statistics are requested\n"
"           the same starting points will be used up until the number of reps\n"
"           for each particular statistic is reached. All parameters are\n"
"           always required for each statistic.)\n"
"     --lstat=fitness,reps          - node fitness\n"
"     --lstat=n_step_mean,reps,n,s  - mean fitness (s samples) n steps away\n"
"     --lstat=banding,reps,x        - band statistics for tried size x\n"
"     --lstat=sequence,reps         - print out sequence per rep\n"
"\n"
"  landscape statistics specifically for Segal model\n"
"     --lstat=expression,reps       - print vector of expression levels\n"
"     --lstat=tf_occupancy,reps     - print list of TF occupancy levels for\n"
"                                     each condition and TF combination\n"
"     --lstat=wsum,reps             - the sum of all configuration weights\n"
"     --lstat=configs,1             - print out configurations\n"
"\n";
   return;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2018 Sven Willner <sven.willner@pik-potsdam.de>
 * Free software under GNU Affero General Public License v3, see LICENSE
 */

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "Hector.h"
#include "Observable.h"
#include "h_exception.hpp"
#include "h_util.hpp"

namespace py = pybind11;

namespace pyhector {

PYBIND11_MODULE(_binding, m) {
    m.doc() = R"pbdoc(
        pyhector._binding
        -----------------

        `pyhector` is a Python wrapper for the simple global climate
        carbon-cycle model Hector (https://github.com/JGCRI/hector).

        See README.rst and repository for details:
        https://github.com/openclimatedata/pyhector
    )pbdoc";

    static py::exception<h_exception> hector_exception(m, "HectorException");
    py::register_exception_translator([](std::exception_ptr p) {
        try {
            if (p) {
                std::rethrow_exception(p);
            }
        } catch (const h_exception& e) {
            hector_exception(e.what());
        }
    });

    py::class_<Hector>(m, "_Hector", "Class providing an interface to Hector")
        .def(py::init())
        .def_property_readonly("run_size", &Hector::run_size, "Number of steps to run")
        .def_property_readonly("spinup_size", &Hector::spinup_size, "Number of spinup steps run")
        .def_property_readonly("start_date", &Hector::start_date, "Start date")
        .def_property_readonly("end_date", &Hector::end_date, "End date")
        .def("add_observable", &Hector::add_observable,
             R"doc(
                   Set a variable that can be read later.
                   See :mod:`pyhector.output` for available components and variables.

                   Parameters
                   ----------
                   component : str
                       Name of Hector component
                   name : string
                       Name of variable in component
                   needs_date : bool, default ``False``
                       Whether variable needs a date
                   in_spinup : bool, default ``False``
                       True to return from spinup phase, else from run phase
            )doc",
             py::arg("component"), py::arg("name"), py::arg("needs_date") = false, py::arg("in_spinup") = false)
        .def("get_observable", &Hector::get_observable,
             R"doc(
                   Returns output variable.
                   See :mod:`pyhector.output` for available variables.

                   Parameters
                   ----------
                   component : str
                       Name of Hector component
                   name : string
                       Name of variable in component
                   in_spinup : bool, default ``False``
                       True to return from spinup phase, else from run phase. Must have
                       been set in :py:meth:`add_observable` accordingly
             )doc",
             py::arg("component"), py::arg("name"), py::arg("in_spinup") = false)
        .def("clear_observables", &Hector::clear_observables, "Clear observables registered so far.")
        .def("reset", &Hector::reset, "Reset Hector.")
        .def("run", &Hector::run, "Run Hector.", py::arg("until") = py::none())
        .def("shutdown", &Hector::shutdown, "Shutdown Hector.")
        .def("_set_string", (void (Hector::*)(const std::string&, const std::string&, const std::string&)) & Hector::set, "Set Parameters.")
        .def("_set_double", (void (Hector::*)(const std::string&, const std::string&, double)) & Hector::set, "Set Parameters.")
        .def("_set_double_unit", (void (Hector::*)(const std::string&, const std::string&, double, const std::string&)) & Hector::set, "Set Parameters.")
        .def("_set_timed_double", (void (Hector::*)(const std::string&, const std::string&, std::size_t, double)) & Hector::set, "Set Parameters.")
        .def("_set_timed_double_unit", (void (Hector::*)(const std::string&, const std::string&, std::size_t, double, const std::string&)) & Hector::set,
             "Set Parameters.")
        .def("_set_timed_array",
             (void (Hector::*)(const std::string&, const std::string&, const std::vector<std::size_t>&, const std::vector<double>&)) & Hector::set,
             "Set Parameters.")
        .def("_set_timed_array_unit",
             (void (Hector::*)(const std::string&, const std::string&, const std::vector<std::size_t>&, const std::vector<double>&, const std::string&))
                 & Hector::set,
             "Set Parameters.");

    m.attr("__hector_version__") = MODEL_VERSION;
}

}  // namespace pyhector
<commit_msg>Add documentation for until parameter<commit_after>/*
 * Copyright (c) 2018 Sven Willner <sven.willner@pik-potsdam.de>
 * Free software under GNU Affero General Public License v3, see LICENSE
 */

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "Hector.h"
#include "Observable.h"
#include "h_exception.hpp"
#include "h_util.hpp"

namespace py = pybind11;

namespace pyhector {

PYBIND11_MODULE(_binding, m) {
    m.doc() = R"pbdoc(
        pyhector._binding
        -----------------

        `pyhector` is a Python wrapper for the simple global climate
        carbon-cycle model Hector (https://github.com/JGCRI/hector).

        See README.rst and repository for details:
        https://github.com/openclimatedata/pyhector
    )pbdoc";

    static py::exception<h_exception> hector_exception(m, "HectorException");
    py::register_exception_translator([](std::exception_ptr p) {
        try {
            if (p) {
                std::rethrow_exception(p);
            }
        } catch (const h_exception& e) {
            hector_exception(e.what());
        }
    });

    py::class_<Hector>(m, "_Hector", "Class providing an interface to Hector")
        .def(py::init())
        .def_property_readonly("run_size", &Hector::run_size, "Number of steps to run by default")
        .def_property_readonly("spinup_size", &Hector::spinup_size, "Number of spinup steps run")
        .def_property_readonly("start_date", &Hector::start_date, "Start date")
        .def_property_readonly("end_date", &Hector::end_date, "End date")
        .def("add_observable", &Hector::add_observable,
             R"doc(
                   Set a variable that can be read later.
                   See :mod:`pyhector.output` for available components and variables.

                   Parameters
                   ----------
                   component : str
                       Name of Hector component
                   name : string
                       Name of variable in component
                   needs_date : bool, default ``False``
                       Whether variable needs a date
                   in_spinup : bool, default ``False``
                       True to return from spinup phase, else from run phase
            )doc",
             py::arg("component"), py::arg("name"), py::arg("needs_date") = false, py::arg("in_spinup") = false)
        .def("get_observable", &Hector::get_observable,
             R"doc(
                   Returns output variable.
                   See :mod:`pyhector.output` for available variables.

                   Parameters
                   ----------
                   component : str
                       Name of Hector component
                   name : string
                       Name of variable in component
                   in_spinup : bool, default ``False``
                       True to return from spinup phase, else from run phase. Must have
                       been set in :py:meth:`add_observable` accordingly
             )doc",
             py::arg("component"), py::arg("name"), py::arg("in_spinup") = false)
        .def("clear_observables", &Hector::clear_observables, "Clear observables registered so far.")
        .def("reset", &Hector::reset, "(Hard) reset Hector.")
        .def("run", &Hector::run,
             R"doc(
                   Run Hector.

                   Parameters
                   ----------
                   until : double, default ``None``
                       Year to run until (including) or run till end date as given by
                       configuration if None
             )doc",
             py::arg("until") = py::none())
        .def("shutdown", &Hector::shutdown, "Shutdown Hector.")
        .def("_set_string", (void (Hector::*)(const std::string&, const std::string&, const std::string&)) & Hector::set, "Set Parameters.")
        .def("_set_double", (void (Hector::*)(const std::string&, const std::string&, double)) & Hector::set, "Set Parameters.")
        .def("_set_double_unit", (void (Hector::*)(const std::string&, const std::string&, double, const std::string&)) & Hector::set, "Set Parameters.")
        .def("_set_timed_double", (void (Hector::*)(const std::string&, const std::string&, std::size_t, double)) & Hector::set, "Set Parameters.")
        .def("_set_timed_double_unit", (void (Hector::*)(const std::string&, const std::string&, std::size_t, double, const std::string&)) & Hector::set,
             "Set Parameters.")
        .def("_set_timed_array",
             (void (Hector::*)(const std::string&, const std::string&, const std::vector<std::size_t>&, const std::vector<double>&)) & Hector::set,
             "Set Parameters.")
        .def("_set_timed_array_unit",
             (void (Hector::*)(const std::string&, const std::string&, const std::vector<std::size_t>&, const std::vector<double>&, const std::string&))
                 & Hector::set,
             "Set Parameters.");

    m.attr("__hector_version__") = MODEL_VERSION;
}

}  // namespace pyhector
<|endoftext|>


<commit_before>#include <SFML/Window.hpp>
#include <cmath>
#include <iostream>

#include "renderer.h"
#include "input.h"
#include "octree.h"

using namespace std;

Octree<bool> makeTerrain(int level)
{
    cout << "At level " << level << endl;
    vector<Octree<bool> >blocks;
    for(int i = 0; i < 8; i++)
    {
        bool leaf = (sf::Randomizer::Random(-1.f, 1.f) <= 0.0f ? true : false);
        if(level < 2)
        {

            if(leaf)
            {
                bool type = (sf::Randomizer::Random(-1.f, 1.f) <= 0.0f ? true : false);
                blocks.push_back(Octree<bool>(type));
            }
            else
            {
                cout << "Going deeper!" << endl;
                blocks.push_back(makeTerrain(level + 1));
            }
        }
        else if(level == 2)
        {
            bool type = (sf::Randomizer::Random(-1.f, 1.f) <= 0.0f ? true : false);
            blocks.push_back(Octree<bool>(type));
        }
        cout << "Block " << i << "at level " << level << ": " << (leaf ? "leaf" : "node") << endl;
    }
    Octree<bool> terrain(blocks);
    return terrain;
}

int main()
{
    // Create the main window
    sf::Window App(sf::VideoMode(800, 600, 32), "MineCube");

    Octree<bool> terrain = makeTerrain(0);

    // Create a renderer and input handler
    Renderer renderer(terrain);
    InputHandler input_handler(&App);

    //App.UseVerticalSync(true);

    // Create a clock for measuring time elapsed
    sf::Clock Clock;

    const float PI = 3.14159265358979323846264338329750288419716939937510582;

    const float Speed = 5.f;
    float Left = 5.f;
    float Top  = 20.f;
    float Up  = 5.f;

    float rotation = 0.f;
    float zRotation = 180.f;

    App.ShowMouseCursor(false);

    // Start game loop
    while (App.IsOpened())
    {
        float ElapsedTime = Clock.GetElapsedTime();
        Clock.Reset();

        bool moving = false;
        float xStep =  Speed * sin((PI * zRotation) / 180) * ElapsedTime;
        float yStep =  Speed * cos((PI * zRotation) / 180) * ElapsedTime;
        float zStep = -Speed * sin((PI *  rotation) / 180) * ElapsedTime;

        if ((App.GetInput().IsKeyDown(sf::Key::S)))    // W = forwards
        {
            moving = true;
            Left -= (xStep * cos((PI * rotation) / 180));
            Top -= (yStep * cos((PI * rotation) / 180));
            Up -= zStep;
        }

        if ((App.GetInput().IsKeyDown(sf::Key::W)))    // S = backwards
        {
            moving = true;
            Left += (xStep * cos((PI * rotation) / 180));
            Top += (yStep * cos((PI * rotation) / 180));
            Up += zStep;
        }

        if ((App.GetInput().IsKeyDown(sf::Key::D)))    //A = strafe left
        {
            if ((moving = true))
            {
                xStep *= 0.707106;
                yStep *= 0.707106;
            }
            Left += yStep;
            Top -= xStep;
        }

        if ((App.GetInput().IsKeyDown(sf::Key::A)))    //D = strafe right
        {
            if ((moving = true))
            {
                xStep *= 0.707106;
                yStep *= 0.707106;
            }
            Left -= yStep;
            Top += xStep;
        }

        if (App.GetInput().IsKeyDown(sf::Key::Q)) Up   -= Speed * ElapsedTime;
        if (App.GetInput().IsKeyDown(sf::Key::E)) Up   += Speed * ElapsedTime;

        if (App.GetInput().IsKeyDown(sf::Key::Space)) renderer.terrain = makeTerrain(0);

        // Rotate view based on mouse movement
        float mouseDeltaX = App.GetInput().GetMouseX() - 100;
        float mouseDeltaY = App.GetInput().GetMouseY() - 100;
        App.SetCursorPosition(100, 100);
        if (!(mouseDeltaX == -100 && mouseDeltaY == -100)) {
            zRotation += (mouseDeltaX / 10);
            rotation += (mouseDeltaY / 10);
            //cout << "DeltaX: " << mouseDeltaX << " DeltaY: " << mouseDeltaY << endl;

            // Z rotation normalisation - between 0 and 360
            if (zRotation >= 360)
            {
                zRotation -= 360;
            }

            if (zRotation < 0)
            {
                zRotation += 360;
            }

            // X/Y rotation limits
            if (rotation < -90)
            {
                rotation = -90;
            }
            if (rotation >= 90)
            {
                rotation = 90;
            }
        }

        input_handler.handleEvents();

        // Set the active window before using OpenGL commands
        // It's useless here because active window is always the same,
        // but don't forget it if you use multiple windows or controls
        App.SetActive();

        renderer.render(Left, Top, Up, rotation, zRotation);

        // Finally, display rendered frame on screen
        App.Display();
    }

    return EXIT_SUCCESS;
}

<commit_msg>KILL WITH FIRE<commit_after>#include <SFML/Window.hpp>
#include <cmath>
#include <iostream>

#include "renderer.h"
#include "input.h"
#include "octree.h"

using namespace std;

Octree<bool> makeTerrain(int level)
{
    vector<Octree<bool> >blocks;
    for(int i = 0; i < 8; i++)
    {
        bool leaf = (sf::Randomizer::Random(-1.f, 1.f) <= 0.0f ? true : false);
        if(level < 2)
        {

            if(leaf)
            {
                bool type = (sf::Randomizer::Random(-1.f, 1.f) <= 0.0f ? true : false);
                blocks.push_back(Octree<bool>(type));
            }
            else
            {
                blocks.push_back(makeTerrain(level + 1));
            }
        }
        else if(level == 2)
        {
            bool type = (sf::Randomizer::Random(-1.f, 1.f) <= 0.0f ? true : false);
            blocks.push_back(Octree<bool>(type));
        }
    }
    Octree<bool> terrain(blocks);
    return terrain;
}

int main()
{
    // Create the main window
    sf::Window App(sf::VideoMode(800, 600, 32), "MineCube");

    Octree<bool> terrain = makeTerrain(0);

    // Create a renderer and input handler
    Renderer renderer(terrain);
    InputHandler input_handler(&App);

    //App.UseVerticalSync(true);

    // Create a clock for measuring time elapsed
    sf::Clock Clock;

    const float PI = 3.14159265358979323846264338329750288419716939937510582;

    const float Speed = 5.f;
    float Left = 5.f;
    float Top  = 20.f;
    float Up  = 5.f;

    float rotation = 0.f;
    float zRotation = 180.f;

    App.ShowMouseCursor(false);

    // Start game loop
    while (App.IsOpened())
    {
        float ElapsedTime = Clock.GetElapsedTime();
        Clock.Reset();

        bool moving = false;
        float xStep =  Speed * sin((PI * zRotation) / 180) * ElapsedTime;
        float yStep =  Speed * cos((PI * zRotation) / 180) * ElapsedTime;
        float zStep = -Speed * sin((PI *  rotation) / 180) * ElapsedTime;

        if ((App.GetInput().IsKeyDown(sf::Key::S)))    // W = forwards
        {
            moving = true;
            Left -= (xStep * cos((PI * rotation) / 180));
            Top -= (yStep * cos((PI * rotation) / 180));
            Up -= zStep;
        }

        if ((App.GetInput().IsKeyDown(sf::Key::W)))    // S = backwards
        {
            moving = true;
            Left += (xStep * cos((PI * rotation) / 180));
            Top += (yStep * cos((PI * rotation) / 180));
            Up += zStep;
        }

        if ((App.GetInput().IsKeyDown(sf::Key::D)))    //A = strafe left
        {
            if ((moving = true))
            {
                xStep *= 0.707106;
                yStep *= 0.707106;
            }
            Left += yStep;
            Top -= xStep;
        }

        if ((App.GetInput().IsKeyDown(sf::Key::A)))    //D = strafe right
        {
            if ((moving = true))
            {
                xStep *= 0.707106;
                yStep *= 0.707106;
            }
            Left -= yStep;
            Top += xStep;
        }

        if (App.GetInput().IsKeyDown(sf::Key::Q)) Up   -= Speed * ElapsedTime;
        if (App.GetInput().IsKeyDown(sf::Key::E)) Up   += Speed * ElapsedTime;

        if (App.GetInput().IsKeyDown(sf::Key::Space)) renderer.terrain = makeTerrain(0);

        // Rotate view based on mouse movement
        float mouseDeltaX = App.GetInput().GetMouseX() - 100;
        float mouseDeltaY = App.GetInput().GetMouseY() - 100;
        App.SetCursorPosition(100, 100);
        if (!(mouseDeltaX == -100 && mouseDeltaY == -100)) {
            zRotation += (mouseDeltaX / 10);
            rotation += (mouseDeltaY / 10);
            //cout << "DeltaX: " << mouseDeltaX << " DeltaY: " << mouseDeltaY << endl;

            // Z rotation normalisation - between 0 and 360
            if (zRotation >= 360)
            {
                zRotation -= 360;
            }

            if (zRotation < 0)
            {
                zRotation += 360;
            }

            // X/Y rotation limits
            if (rotation < -90)
            {
                rotation = -90;
            }
            if (rotation >= 90)
            {
                rotation = 90;
            }
        }

        input_handler.handleEvents();

        // Set the active window before using OpenGL commands
        // It's useless here because active window is always the same,
        // but don't forget it if you use multiple windows or controls
        App.SetActive();

        renderer.render(Left, Top, Up, rotation, zRotation);

        // Finally, display rendered frame on screen
        App.Display();
    }

    return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>#include "main.h"

#include <math.h>
#include <stdio.h>

#include "drivers/Driver.h"
#include "drivers/TeleopDriver.h"
#include "drivers/BaselockDriver.h"
#include "subsystems/Drive.h"
#include "subsystems/Shooter.h"
#include "subsystems/OperatorControl.h"
#include "subsystems/Pid.h"
#include "subsystems/PidCommander.h"
#include "util/Functions.h"
#include "util/Logger.h"
#include "util/PidTuner.h"
#include "vision/BackboardFinder.h"

MainRobot::MainRobot() {
  // Constants
  constants_ = Constants::GetInstance();

  // Motors
  leftDriveMotorA_ = new Victor((int)constants_->leftDrivePwmA);
  leftDriveMotorB_ = new Victor((int)constants_->leftDrivePwmB);
  rightDriveMotorA_ = new Victor((int)constants_->rightDrivePwmA);
  rightDriveMotorB_ = new Victor((int)constants_->rightDrivePwmB);
  intakeMotor_ = new Victor((int)constants_->intakePwm);
  conveyorMotor_ = new Victor((int)constants_->conveyorPwm);
  leftShooterMotor_ = new Victor((int)constants_->leftShooterPwm);
  rightShooterMotor_ = new Victor((int)constants_->rightShooterPwm);

  // Sensors
  leftEncoder_ = new Encoder((int)constants_->leftEncoderPortA, (int)constants_->leftEncoderPortB);
  leftEncoder_->Start();
  rightEncoder_ = new Encoder((int)constants_->rightEncoderPortA, (int)constants_->rightEncoderPortB);
  rightEncoder_->Start();
  shooterEncoder_ = new Encoder((int)constants_->shooterEncoderPortA, (int)constants_->shooterEncoderPortB);
  shooterEncoder_->Start();
  gyro_ = new Gyro((int)constants_->gyroPort);
  gyro_->SetSensitivity(1.0);

  double accelerometerSensitivity = 1.0;
  accelerometerX_ = new Accelerometer((int)constants_->accelerometerXPort);
  accelerometerY_ = new Accelerometer((int)constants_->accelerometerYPort);
  accelerometerZ_ = new Accelerometer((int)constants_->accelerometerZPort);
  //accelerometerX_->SetSensitivity(accelerometerSensitivity);
  //  accelerometerY_->SetSensitivity(accelerometerSensitivity);
  //  accelerometerZ_->SetSensitivity(accelerometerSensitivity);
  bumpSensor_ = new DigitalInput((int)constants_->bumpSensorPort);

  // Pneumatics
  compressor_ = new Compressor((int)constants_->compressorPressureSwitchPort,(int)constants_->compressorRelayPort);
  compressor_->Start();
  shiftSolenoid_ = new Solenoid((int)constants_->shiftSolenoidPort);
//  hoodSolenoid_ = new Solenoid((int)constants_->hoodSolenoidPort);
  pizzaWheelSolenoid_ = new DoubleSolenoid((int)constants_->pizzaWheelSolenoidDownPort, (int)constants_->pizzaWheelSolenoidUpPort);
//  intakeSolenoid_ = new DoubleSolenoid((int)constants_->intakeSolenoidHighPort,(int)constants_->intakeSolenoidLowPort);
  brakeSolenoid_ = new DoubleSolenoid((int)constants_->brakeSolenoidHighPort, (int)constants_->brakeSolenoidLowPort);

  // Subsystems
  drivebase_ = new Drive(leftDriveMotorA_, leftDriveMotorB_, rightDriveMotorA_, rightDriveMotorB_,
                         shiftSolenoid_, pizzaWheelSolenoid_, brakeSolenoid_,  leftEncoder_,
                         rightEncoder_, gyro_, accelerometerX_, accelerometerY_,
                         accelerometerZ_, bumpSensor_);
//  shooter_ = new Shooter(intakeMotor_, conveyorMotor_, leftShooterMotor_, rightShooterMotor_,
//                         shooterEncoder_, hoodSolenoid_, intakeSolenoid_);

  // Drivers
  teleopDriver_ = new TeleopDriver(drivebase_, leftJoystick_, rightJoystick_, operatorControl_);
  baselockDriver_ = new BaselockDriver(drivebase_, leftJoystick_);
  // Set the current Driver to teleop, though this will change later
  currDriver_ = teleopDriver_;

  // Control Board
  leftJoystick_ = new Joystick((int)constants_->leftJoystickPort);
  rightJoystick_ = new Joystick((int)constants_->rightJoystickPort);
  operatorControl_ = new OperatorControl((int)constants_->operatorControlPort);

  testPid_ = new Pid(constants_->driveKP, constants_->driveKI, constants_->driveKD);
  testTimer_ = new Timer();
  testLogger_ = new Logger("/test.log", 2);

  // Watchdog
  GetWatchdog().SetExpiration(100);

  // Get a local instance of the Driver Station LCD
  lcd_ = DriverStationLCD::GetInstance();
  lcd_->PrintfLine(DriverStationLCD::kUser_Line1,"***Teleop Ready!***");

  oldBaseLockSwitch_ = operatorControl_->GetBaseLockSwitch();
}

void MainRobot::DisabledInit() {
}

void MainRobot::AutonomousInit() {
  constants_->LoadFile();
  delete testPid_;
  testPid_ = new Pid(constants_->driveKP, constants_->driveKI, constants_->driveKD);
  drivebase_->ResetGyro();
  drivebase_->ResetEncoders();
  testPid_->ResetError();
  testTimer_->Reset();
  testTimer_->Start();
  GetWatchdog().SetEnabled(false);
}

void MainRobot::TeleopInit() {
  constants_->LoadFile();
  drivebase_->ResetGyro();
  drivebase_->ResetEncoders();
  //baseLockPosition_ = drivebase_->GetLeftEncoderDistance();
  //baseLockPid_->ResetError();

  // Start off with the TeleopDriver
  currDriver_ = teleopDriver_;
  currDriver_->Reset();
  GetWatchdog().SetEnabled(true);
}

void MainRobot::DisabledPeriodic() {
  drivebase_->SetPizzaWheelDown(false);
  lcd_->UpdateLCD();
}

void MainRobot::AutonomousPeriodic() {
  double time = testTimer_->Get();
  double inputValue = Functions::SineWave(time, 5, 2);
  double position = drivebase_->GetLeftEncoderDistance();
  double signal = testPid_->Update(inputValue, position);
  drivebase_->SetLinearPower(signal, signal);
  testLogger_->Log("%f,%f,%f,%f\n", time, inputValue, signal, position);
  PidTuner::PushData(inputValue, position);
}

void MainRobot::TeleopPeriodic() {
  GetWatchdog().Feed();

  // Only have Teleop and Baselock Drivers right now
  if (operatorControl_->GetBaseLockSwitch() && !oldBaseLockSwitch_) {
      // If the baselock switch has been flipped on, switch to baselock
      currDriver_ = baselockDriver_;
      currDriver_->Reset();
  } else if (!operatorControl_->GetBaseLockSwitch() && oldBaseLockSwitch_) {
      // If the baselock switch has been flipped off, switch back to teleop
      currDriver_ = teleopDriver_;
      currDriver_->Reset();
  }

  // Update the driver and the baselock switch status
  currDriver_->UpdateDriver();
  oldBaseLockSwitch_ = operatorControl_->GetBaseLockSwitch();

  static int i = 0;
  lcd_->PrintfLine(DriverStationLCD::kUser_Line3, "%d, %f, %f, %f\n", i,(float) drivebase_->GetXAcceleration(),(float)drivebase_->GetXAcceleration(),(float) drivebase_->GetXAcceleration());
  lcd_->UpdateLCD();

  Logger::GetSysLog()->Log("%d, %f, %f, %f\n", i,(float) drivebase_->GetXAcceleration(),(float)drivebase_->GetXAcceleration(),(float) drivebase_->GetXAcceleration());

  i++;
}

<commit_msg>Added temp support for xbox controller<commit_after>#include "main.h"

#include <math.h>
#include <stdio.h>

#include "drivers/Driver.h"
#include "drivers/TeleopDriver.h"
#include "drivers/BaselockDriver.h"
#include "subsystems/Drive.h"
#include "subsystems/Shooter.h"
#include "subsystems/OperatorControl.h"
#include "subsystems/Pid.h"
#include "subsystems/PidCommander.h"
#include "util/Functions.h"
#include "util/Logger.h"
#include "util/PidTuner.h"
#include "vision/BackboardFinder.h"

Joystick* xbox = new Joystick(3);

MainRobot::MainRobot() {
  // Constants
  constants_ = Constants::GetInstance();

  // Motors
  leftDriveMotorA_ = new Victor((int)constants_->leftDrivePwmA);
  leftDriveMotorB_ = new Victor((int)constants_->leftDrivePwmB);
  rightDriveMotorA_ = new Victor((int)constants_->rightDrivePwmA);
  rightDriveMotorB_ = new Victor((int)constants_->rightDrivePwmB);
  intakeMotor_ = new Victor((int)constants_->intakePwm);
  conveyorMotor_ = new Victor((int)constants_->conveyorPwm);
  leftShooterMotor_ = new Victor((int)constants_->leftShooterPwm);
  rightShooterMotor_ = new Victor((int)constants_->rightShooterPwm);

  // Sensors
  leftEncoder_ = new Encoder((int)constants_->leftEncoderPortA, (int)constants_->leftEncoderPortB);
  leftEncoder_->Start();
  rightEncoder_ = new Encoder((int)constants_->rightEncoderPortA, (int)constants_->rightEncoderPortB);
  rightEncoder_->Start();
  shooterEncoder_ = new Encoder((int)constants_->shooterEncoderPortA, (int)constants_->shooterEncoderPortB);
  shooterEncoder_->Start();
  gyro_ = new Gyro((int)constants_->gyroPort);
  gyro_->SetSensitivity(1.0);

  double accelerometerSensitivity = 1.0;
  accelerometerX_ = new Accelerometer((int)constants_->accelerometerXPort);
  accelerometerY_ = new Accelerometer((int)constants_->accelerometerYPort);
  accelerometerZ_ = new Accelerometer((int)constants_->accelerometerZPort);
  //accelerometerX_->SetSensitivity(accelerometerSensitivity);
  //  accelerometerY_->SetSensitivity(accelerometerSensitivity);
  //  accelerometerZ_->SetSensitivity(accelerometerSensitivity);
  bumpSensor_ = new DigitalInput((int)constants_->bumpSensorPort);

  // Pneumatics
  compressor_ = new Compressor((int)constants_->compressorPressureSwitchPort,(int)constants_->compressorRelayPort);
  compressor_->Start();
  shiftSolenoid_ = new Solenoid((int)constants_->shiftSolenoidPort);
  hoodSolenoid_ = new Solenoid((int)constants_->hoodSolenoidPort);
  pizzaWheelSolenoid_ = new DoubleSolenoid((int)constants_->pizzaWheelSolenoidDownPort, (int)constants_->pizzaWheelSolenoidUpPort);
  intakeSolenoid_ = new DoubleSolenoid((int)constants_->intakeSolenoidHighPort,(int)constants_->intakeSolenoidLowPort);
  brakeSolenoid_ = new DoubleSolenoid((int)constants_->brakeSolenoidHighPort, (int)constants_->brakeSolenoidLowPort);

  // Subsystems
  drivebase_ = new Drive(leftDriveMotorA_, leftDriveMotorB_, rightDriveMotorA_, rightDriveMotorB_,
                         shiftSolenoid_, pizzaWheelSolenoid_, brakeSolenoid_,  leftEncoder_,
                         rightEncoder_, gyro_, accelerometerX_, accelerometerY_,
                         accelerometerZ_, bumpSensor_);
  shooter_ = new Shooter(intakeMotor_, conveyorMotor_, leftShooterMotor_, rightShooterMotor_,
                         shooterEncoder_, hoodSolenoid_, intakeSolenoid_);

  // Drivers
  teleopDriver_ = new TeleopDriver(drivebase_, leftJoystick_, rightJoystick_, operatorControl_);
  baselockDriver_ = new BaselockDriver(drivebase_, leftJoystick_);
  // Set the current Driver to teleop, though this will change later
  currDriver_ = teleopDriver_;

  // Control Board
  leftJoystick_ = new Joystick((int)constants_->leftJoystickPort);
  rightJoystick_ = new Joystick((int)constants_->rightJoystickPort);
  operatorControl_ = new OperatorControl((int)constants_->operatorControlPort);

  testPid_ = new Pid(constants_->driveKP, constants_->driveKI, constants_->driveKD);
  testTimer_ = new Timer();
  testLogger_ = new Logger("/test.log", 2);

  // Watchdog
  GetWatchdog().SetExpiration(100);

  // Get a local instance of the Driver Station LCD
  lcd_ = DriverStationLCD::GetInstance();
  lcd_->PrintfLine(DriverStationLCD::kUser_Line1,"***Teleop Ready!***");

  oldBaseLockSwitch_ = operatorControl_->GetBaseLockSwitch();
}

void MainRobot::DisabledInit() {
}

void MainRobot::AutonomousInit() {
  constants_->LoadFile();
  delete testPid_;
  testPid_ = new Pid(constants_->driveKP, constants_->driveKI, constants_->driveKD);
  drivebase_->ResetGyro();
  drivebase_->ResetEncoders();
  testPid_->ResetError();
  testTimer_->Reset();
  testTimer_->Start();
  GetWatchdog().SetEnabled(false);
}

void MainRobot::TeleopInit() {
  constants_->LoadFile();
  drivebase_->ResetGyro();
  drivebase_->ResetEncoders();
  //baseLockPosition_ = drivebase_->GetLeftEncoderDistance();
  //baseLockPid_->ResetError();

  // Start off with the TeleopDriver
  currDriver_ = teleopDriver_;
  currDriver_->Reset();
  GetWatchdog().SetEnabled(true);
}

void MainRobot::DisabledPeriodic() {
  drivebase_->SetPizzaWheelDown(false);
  lcd_->UpdateLCD();
}

void MainRobot::AutonomousPeriodic() {
  double time = testTimer_->Get();
  double inputValue = Functions::SineWave(time, 5, 2);
  double position = drivebase_->GetLeftEncoderDistance();
  double signal = testPid_->Update(inputValue, position);
  drivebase_->SetLinearPower(signal, signal);
  testLogger_->Log("%f,%f,%f,%f\n", time, inputValue, signal, position);
  PidTuner::PushData(inputValue, position);
}

void MainRobot::TeleopPeriodic() {
  GetWatchdog().Feed();

  double ljoy = xbox->GetY();
  double trigger = -xbox->GetRawAxis(3);
  double rjoy = -xbox->GetRawAxis(5);

  shooter_->SetLinearPower(ljoy);
  shooter_->SetConveyorPower(trigger);
  shooter_->SetIntakePower(rjoy);

  // Only have Teleop and Baselock Drivers right now
  if (operatorControl_->GetBaseLockSwitch() && !oldBaseLockSwitch_) {
      // If the baselock switch has been flipped on, switch to baselock
      currDriver_ = baselockDriver_;
      currDriver_->Reset();
  } else if (!operatorControl_->GetBaseLockSwitch() && oldBaseLockSwitch_) {
      // If the baselock switch has been flipped off, switch back to teleop
      currDriver_ = teleopDriver_;
      currDriver_->Reset();
  }

  // Update the driver and the baselock switch status
  currDriver_->UpdateDriver();
  oldBaseLockSwitch_ = operatorControl_->GetBaseLockSwitch();

  static int i = 0;
  lcd_->PrintfLine(DriverStationLCD::kUser_Line3, "%d, %f, %f, %f\n", i,(float) drivebase_->GetXAcceleration(),(float)drivebase_->GetXAcceleration(),(float) drivebase_->GetXAcceleration());
  lcd_->UpdateLCD();

  Logger::GetSysLog()->Log("%d, %f, %f, %f\n", i,(float) drivebase_->GetXAcceleration(),(float)drivebase_->GetXAcceleration(),(float) drivebase_->GetXAcceleration());

  i++;
}

<|endoftext|>


<commit_before>/*
src/main.cpp

Created by Jon Stewart on 2010-01-04.
Copyright (c) 2010 Lightbox Technologies, Inc.
*/

#include <boost/program_options.hpp>
#include <boost/bind.hpp>

#include <iostream>
#include <iomanip>
#include <algorithm>

#include "tsk.h"

namespace po = boost::program_options;

template<class T>
const T& j(const T& x) {
  return x;
}

template<>
const string& j<string>(const string& x) {
  static string S; // so evil
  S = "\"";
  S += x;
  S += "\"";
  return S;
}

template<class T>
class JsonPair {
public:
  JsonPair(const string& key, const T& val, bool first): Key(key), Value(val), First(first) {}

  const string& Key;
  const T& Value;
  bool First;
};

template<class T>
JsonPair<T> j(const string& key, const T& val, bool first = false) {
  return JsonPair<T>(key, val, first);
}

template<class T>
ostream& operator<<(ostream& out, const JsonPair<T>& pair) {
  if (!pair.First) {
    out << ",";
  }
  out << j(pair.Key) << ":";
  out << j(pair.Value);
  return out;
}

void outputFS(ostream& buf, shared_ptr<Filesystem> fs) {
  buf << "," << j(string("filesystem")) << ":{"
      << j("numBlocks", fs->numBlocks(), true)
      << j("blockSize", fs->blockSize())
      << j("deviceBlockSize", fs->deviceBlockSize())
      << j("blockName", fs->blockName())
      << j("littleEndian", fs->littleEndian())
      << j("firstBlock", fs->firstBlock())
      << j("firstInum", fs->firstInum())
      << j("flags", fs->flags())
      << j("fsID", fs->fsIDAsString())
      << j("type", fs->fsType())
      << j("typeName", fs->fsName())
      << j("isOrphanHunting", fs->isOrphanHunting())
      << j("journalInum", fs->journalInum())
      << j("numInums", fs->numInums())
      << j("lastBlock", fs->lastBlock())
      << j("lastBlockAct", fs->lastBlockAct())
      << j("lastInum", fs->lastInum())
      << j("byteOffset", fs->byteOffset())
      << j("rootInum", fs->rootInum())
      << "}";
}

string j(const weak_ptr< Volume >& vol) {
  stringstream buf;
  if (shared_ptr< Volume > p = vol.lock()) {
    buf << "{"
        << j("description", p->desc(), true)
        << j("flags", p->flags())
        << j("numBlocks", p->numBlocks())
        << j("slotNum", p->slotNum())
        << j("startBlock", p->startBlock())
        << j("tableNum", p->tableNum());
    if (shared_ptr<Filesystem> fs = p->filesystem().lock()) {
      outputFS(buf, fs);
    }
    buf << "}";
  }
  return buf.str();
}

template<class ItType>
void writeSequence(ostream& out, ItType begin, ItType end, const string& delimiter) {
  if (begin != end) {
    ItType it(begin);
    out << j(*it);
    for (++it; it != end; ++it) {
      out << delimiter << j(*it);
    }
  }
}

void writeAttr(ostream& out, const TSK_FS_ATTR* a) {
  out << "{"
      << j("flags", a->flags, true)
      << j("id", a->id)
      << j("name", a->name ? string(a->name): string(""))
      << j("size", a->size)
      << j("type", a->type)
      << j("rd_buf_size", a->rd.buf_size)
      << j("nrd_allocsize", a->nrd.allocsize)
      << j("nrd_compsize", a->nrd.compsize)
      << j("nrd_initsize", a->nrd.initsize)
      << j("nrd_skiplen", a->nrd.skiplen);
  if (a->flags & TSK_FS_ATTR_RES && a->rd.buf_size && a->rd.buf) {
    out << ", " << j(string("rd_buf")) << ":\"";
    ios::fmtflags oldFlags = out.flags();
    out << hex << setfill('0');
    size_t numBytes = min(a->rd.buf_size, (size_t)a->size);
    for (size_t i = 0; i < numBytes; ++i) {
      out << setw(2) << (unsigned int)a->rd.buf[i];
    }
    out.flags(oldFlags);
    out << "\"";
  }
  if (a->flags & TSK_FS_ATTR_NONRES && a->nrd.run) {
    out << ", \"nrd_runs\":[";
    for (TSK_FS_ATTR_RUN* curRun = a->nrd.run; curRun; curRun = curRun->next) {
      if (curRun != a->nrd.run) {
        out << ", ";
      }
      out << "{"
          << j("addr", curRun->addr, true)
          << j("flags", curRun->flags)
          << j("len", curRun->len)
          << j("offset", curRun->offset)
          << "}";
    }
    out << "]";
  }
  out << "}";
}

string bytesAsString(const unsigned char* idBeg, const unsigned char* idEnd) {
  stringstream buf;
  buf << hex;
  for (const unsigned char* cur = idBeg; cur < idEnd; ++cur) {
    buf << hex << (unsigned int)*cur;
  }
  return buf.str();
}

class LbtTskAuto: public TskAuto {
public:
  virtual void finishWalk() {}
};

class FileCounter: public LbtTskAuto {
public:
  FileCounter(ostream& out): NumFiles(0), Out(out) {}

  virtual ~FileCounter() {}

  virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE*, const char*) {
    ++NumFiles;
    return TSK_OK;
  }

  virtual void finishWalk() {
    Out << NumFiles << endl;
  }

  unsigned int NumFiles;

protected:
  ostream& Out;
};

class MetadataWriter: public FileCounter {
public:
  MetadataWriter(ostream& out);

  virtual ~MetadataWriter() {}

  virtual TSK_FILTER_ENUM filterFs(TSK_FS_INFO *fs_info);

  virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE *fs_file, const char *path);
  virtual void finishWalk() {}

private:
  string  FsInfo,
          Null,
          CurDir;

  TSK_FS_INFO* Fs;

  unsigned int CurDirIndex;
};

MetadataWriter::MetadataWriter(ostream& out):
  FileCounter(out), Fs(0), CurDirIndex(0) {}

TSK_FILTER_ENUM MetadataWriter::filterFs(TSK_FS_INFO *fs) {
  stringstream buf;
  buf << j(string("fs")) << ":{"
      << j("byteOffset", fs->offset, true)
      << j("blockSize", fs->block_size)
      << j("fsID", bytesAsString(fs->fs_id, &fs->fs_id[fs->fs_id_used]))
      << "}";
  FsInfo = buf.str();
  Fs = fs;
  return TSK_FILTER_CONT;
}

TSK_RETVAL_ENUM MetadataWriter::processFile(TSK_FS_FILE* file, const char* path) {
  ++CurDirIndex;
  if (0 != CurDir.compare(path)) {
    CurDirIndex = 0;
    CurDir.assign(path);
  }
  // cerr << "beginning callback" << endl;
  try {
    if (file) {
      Out << "{" << FsInfo;
      if (path) {
        Out << j("path", string(path));
      }
      if (file->meta) {
        // need to come back for name2 and attrlist
        TSK_FS_META* i = file->meta;
        Out << ", \"meta\":{"
            << j("addr", i->addr, true)
            << j("atime", i->atime)
            << j("content_len", i->content_len)
            << j("crtime", i->crtime)
            << j("ctime", i->ctime)
            << j("flags", i->flags)
            << j("gid", i->gid);
        if (i->link) {
          Out << j("link", string(i->link));
        }
        if (TSK_FS_TYPE_ISEXT(Fs->ftype)) {
          Out << j("dtime", i->time2.ext2.dtime);
        }
        else if (TSK_FS_TYPE_ISHFS(Fs->ftype)) {
          Out << j("bkup_time", i->time2.hfs.bkup_time);
        }
        Out << j("mode", i->mode)
            << j("mtime", i->mtime)
            << j("nlink", i->nlink)
            << j("seq", i->seq)
            << j("size", i->size)
            << j("type", i->type)
            << j("uid", i->uid)
            << "}";
      }
      if (file->name) {
        TSK_FS_NAME* n = file->name;
        Out << ", \"name\":{"
            << j("flags", n->flags, true)
            << j("meta_addr", n->meta_addr)
            << j("meta_seq", n->meta_seq)
            << j("name", (n->name && n->name_size ? string(n->name): Null))
            << j("shrt_name", (n->shrt_name && n->shrt_name_size ? string(n->shrt_name): Null))
            << j("type", n->type)
            << j("dirIndex", CurDirIndex)
            << "}";

      }
      int numAttrs = tsk_fs_file_attr_getsize(file);
      if (numAttrs > 0) {
        Out << ", \"attrs\":[";
        uint num = 0;
        for (int i = 0; i < numAttrs; ++i) {
          const TSK_FS_ATTR* a = tsk_fs_file_attr_get_idx(file, i);
          if (a) {
            if (num > 0) {
              Out << ", ";
            }
            writeAttr(Out, a);
            ++num;
          }
        }
        Out << "]";
      }
      Out << "}" << endl;
    }
  }
  catch (std::exception& e) {
    cerr << "Error on " << NumFiles << ": " << e.what() << endl;
  }
  // cerr << "finishing callback" << endl;
  FileCounter::processFile(file, path);
  return TSK_OK;
}

bool printDeviceInfo(const shared_ptr< Image >& img) {
  std::cout << "{";

  std::cout << j(string("files")) << ":[";
  writeSequence(cout, img->files().begin(), img->files().end(), ", ");
  std::cout << "]"
            << j("description", img->desc())
            << j("size", img->size());

  if (shared_ptr<VolumeSystem> vs = img->volumeSystem().lock()) {
    std::cout << "," << j("volumeSystem") << ":{"
              << j("type", vs->type(), true)
              << j("description", vs->desc())
              << j("blockSize", vs->blockSize())
              << j("numVolumes", vs->numVolumes())
              << j("offset", vs->offset());

    if (vs->numVolumes()) {
      std::cout << "," << j(string("volumes")) << ":[";
      writeSequence(std::cout, vs->volBegin(), vs->volEnd(), ",");
      std::cout << "]";
    }
    else {
      cerr << "Image has volume system, but no volumes" << endl;
    }
    std::cout << "}";
  }
  else if (shared_ptr<Filesystem> fs = img->filesystem().lock()) {
    outputFS(std::cout, fs);
  }
  else {
    cerr << "Image had neither a volume system nor a filesystem" << endl;
  }
  std::cout << "}" << std::endl;
  return true;
}

void printHelp(const po::options_description& desc) {
  std::cout << "fsrip, Copyright (c) 2010-2011, Lightbox Technologies, Inc." << std::endl;
  std::cout << "TSK version is " << tsk_version_get_str() << std::endl;
  std::cout << "Boost program options version is " << BOOST_PROGRAM_OPTIONS_VERSION << std::endl;
  std::cout << desc << std::endl;
}

shared_ptr<LbtTskAuto> createVisitor(const string& cmd, ostream& out) {
/*  if (cmd == "info") {
    return shared_ptr<TskAuto>(new ImgInfo(out));
  }
  else*/ if (cmd == "dumpfs") {
    return shared_ptr<LbtTskAuto>(new MetadataWriter(out));
  }
  else if (cmd == "count") {
    return shared_ptr<LbtTskAuto>(new FileCounter(out));
  }
  else {
    return shared_ptr<LbtTskAuto>();
  }
}

int main(int argc, char *argv[]) {
  po::options_description desc("Allowed Options");
  po::positional_options_description posOpts;
  posOpts.add("command", 1);
  posOpts.add("ev-files", -1);
  desc.add_options()
    ("help", "produce help message")
    ("command", po::value< std::string >(), "command to perform [info|dumpfs|count]")
    ("ev-files", po::value< std::vector< std::string > >(), "evidence files");

  po::variables_map vm;
  try {
    po::store(po::command_line_parser(argc, argv).options(desc).positional(posOpts).run(), vm);
    po::notify(vm);

    shared_ptr<LbtTskAuto> walker;

    if (vm.count("help")) {
      printHelp(desc);
    }
    else if (vm.count("command") && vm.count("ev-files") && (walker = createVisitor(vm["command"].as<string>(), cout))) {
      std::vector< string >       imgSegs(vm["ev-files"].as< vector< string > >());
      scoped_array< TSK_TCHAR* >  segments(new TSK_TCHAR*[imgSegs.size()]);
      for (unsigned int i = 0; i < imgSegs.size(); ++i) {
        segments[i] = (TSK_TCHAR*)imgSegs[i].c_str();
      }
      if (0 == walker->openImage(imgSegs.size(), segments.get(), TSK_IMG_TYPE_DETECT, 0)) {
        if (0 == walker->findFilesInImg()) {
          walker->finishWalk();
          return 0;
        }
        else {
          cerr << "Had an error parsing filesystem" << endl;
        }
      }
      else {
        cerr << "Had an error opening the evidence file" << endl;
        return 1;
      }
    }
    else {
      std::cerr << "did not understand arguments" << std::endl;
      return 1;
    }
  }
  catch (std::exception& err) {
    std::cerr << "Error: " << err.what() << "\n\n";
    printHelp(desc);
    return 1;
  }
  return 0;
}
<commit_msg>Re-added the dumpimg command<commit_after>/*
src/main.cpp

Created by Jon Stewart on 2010-01-04.
Copyright (c) 2010 Lightbox Technologies, Inc.
*/

#include <boost/program_options.hpp>
#include <boost/bind.hpp>

#include <iostream>
#include <iomanip>
#include <algorithm>

#include "tsk.h"

namespace po = boost::program_options;

template<class T>
const T& j(const T& x) {
  return x;
}

template<>
const string& j<string>(const string& x) {
  static string S; // so evil
  S = "\"";
  S += x;
  S += "\"";
  return S;
}

template<class T>
class JsonPair {
public:
  JsonPair(const string& key, const T& val, bool first): Key(key), Value(val), First(first) {}

  const string& Key;
  const T& Value;
  bool First;
};

template<class T>
JsonPair<T> j(const string& key, const T& val, bool first = false) {
  return JsonPair<T>(key, val, first);
}

template<class T>
ostream& operator<<(ostream& out, const JsonPair<T>& pair) {
  if (!pair.First) {
    out << ",";
  }
  out << j(pair.Key) << ":";
  out << j(pair.Value);
  return out;
}

void outputFS(ostream& buf, shared_ptr<Filesystem> fs) {
  buf << "," << j(string("filesystem")) << ":{"
      << j("numBlocks", fs->numBlocks(), true)
      << j("blockSize", fs->blockSize())
      << j("deviceBlockSize", fs->deviceBlockSize())
      << j("blockName", fs->blockName())
      << j("littleEndian", fs->littleEndian())
      << j("firstBlock", fs->firstBlock())
      << j("firstInum", fs->firstInum())
      << j("flags", fs->flags())
      << j("fsID", fs->fsIDAsString())
      << j("type", fs->fsType())
      << j("typeName", fs->fsName())
      << j("isOrphanHunting", fs->isOrphanHunting())
      << j("journalInum", fs->journalInum())
      << j("numInums", fs->numInums())
      << j("lastBlock", fs->lastBlock())
      << j("lastBlockAct", fs->lastBlockAct())
      << j("lastInum", fs->lastInum())
      << j("byteOffset", fs->byteOffset())
      << j("rootInum", fs->rootInum())
      << "}";
}

string j(const weak_ptr< Volume >& vol) {
  stringstream buf;
  if (shared_ptr< Volume > p = vol.lock()) {
    buf << "{"
        << j("description", p->desc(), true)
        << j("flags", p->flags())
        << j("numBlocks", p->numBlocks())
        << j("slotNum", p->slotNum())
        << j("startBlock", p->startBlock())
        << j("tableNum", p->tableNum());
    if (shared_ptr<Filesystem> fs = p->filesystem().lock()) {
      outputFS(buf, fs);
    }
    buf << "}";
  }
  return buf.str();
}

template<class ItType>
void writeSequence(ostream& out, ItType begin, ItType end, const string& delimiter) {
  if (begin != end) {
    ItType it(begin);
    out << j(*it);
    for (++it; it != end; ++it) {
      out << delimiter << j(*it);
    }
  }
}

void writeAttr(ostream& out, const TSK_FS_ATTR* a) {
  out << "{"
      << j("flags", a->flags, true)
      << j("id", a->id)
      << j("name", a->name ? string(a->name): string(""))
      << j("size", a->size)
      << j("type", a->type)
      << j("rd_buf_size", a->rd.buf_size)
      << j("nrd_allocsize", a->nrd.allocsize)
      << j("nrd_compsize", a->nrd.compsize)
      << j("nrd_initsize", a->nrd.initsize)
      << j("nrd_skiplen", a->nrd.skiplen);
  if (a->flags & TSK_FS_ATTR_RES && a->rd.buf_size && a->rd.buf) {
    out << ", " << j(string("rd_buf")) << ":\"";
    ios::fmtflags oldFlags = out.flags();
    out << hex << setfill('0');
    size_t numBytes = min(a->rd.buf_size, (size_t)a->size);
    for (size_t i = 0; i < numBytes; ++i) {
      out << setw(2) << (unsigned int)a->rd.buf[i];
    }
    out.flags(oldFlags);
    out << "\"";
  }
  if (a->flags & TSK_FS_ATTR_NONRES && a->nrd.run) {
    out << ", \"nrd_runs\":[";
    for (TSK_FS_ATTR_RUN* curRun = a->nrd.run; curRun; curRun = curRun->next) {
      if (curRun != a->nrd.run) {
        out << ", ";
      }
      out << "{"
          << j("addr", curRun->addr, true)
          << j("flags", curRun->flags)
          << j("len", curRun->len)
          << j("offset", curRun->offset)
          << "}";
    }
    out << "]";
  }
  out << "}";
}

string bytesAsString(const unsigned char* idBeg, const unsigned char* idEnd) {
  stringstream buf;
  buf << hex;
  for (const unsigned char* cur = idBeg; cur < idEnd; ++cur) {
    buf << hex << (unsigned int)*cur;
  }
  return buf.str();
}

class LbtTskAuto: public TskAuto {
public:
  virtual ~LbtTskAuto() {}

  virtual uint8_t start() {
    return findFilesInImg();
  }

  virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE*, const char*) { return TSK_OK; }

  virtual void finishWalk() {}
};

class ImageDumper: public LbtTskAuto {
public:
  ImageDumper(ostream& out): Out(out) {}

  virtual uint8_t start() {
    ssize_t rlen;
    char buf[4096];
    TSK_OFF_T off = 0;

    while (off < m_img_info->size) {
      rlen = tsk_img_read(m_img_info, off, buf, sizeof(buf));
      if (rlen == -1) {
        return -1;
      }
      off += rlen;
      Out.write(buf, rlen);
      if (!Out.good()) {
        return -1;
      }
    }
    return 0;
  }

private:
  ostream& Out;
};

class FileCounter: public LbtTskAuto {
public:
  FileCounter(ostream& out): NumFiles(0), Out(out) {}

  virtual ~FileCounter() {}

  virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE*, const char*) {
    ++NumFiles;
    return TSK_OK;
  }

  virtual void finishWalk() {
    Out << NumFiles << endl;
  }

  unsigned int NumFiles;

protected:
  ostream& Out;
};

class MetadataWriter: public FileCounter {
public:
  MetadataWriter(ostream& out);

  virtual ~MetadataWriter() {}

  virtual TSK_FILTER_ENUM filterFs(TSK_FS_INFO *fs_info);

  virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE *fs_file, const char *path);
  virtual void finishWalk() {}

private:
  string  FsInfo,
          Null,
          CurDir;

  TSK_FS_INFO* Fs;

  unsigned int CurDirIndex;
};

MetadataWriter::MetadataWriter(ostream& out):
  FileCounter(out), Fs(0), CurDirIndex(0) {}

TSK_FILTER_ENUM MetadataWriter::filterFs(TSK_FS_INFO *fs) {
  stringstream buf;
  buf << j(string("fs")) << ":{"
      << j("byteOffset", fs->offset, true)
      << j("blockSize", fs->block_size)
      << j("fsID", bytesAsString(fs->fs_id, &fs->fs_id[fs->fs_id_used]))
      << "}";
  FsInfo = buf.str();
  Fs = fs;
  return TSK_FILTER_CONT;
}

TSK_RETVAL_ENUM MetadataWriter::processFile(TSK_FS_FILE* file, const char* path) {
  ++CurDirIndex;
  if (0 != CurDir.compare(path)) {
    CurDirIndex = 0;
    CurDir.assign(path);
  }
  // cerr << "beginning callback" << endl;
  try {
    if (file) {
      Out << "{" << FsInfo;
      if (path) {
        Out << j("path", string(path));
      }
      if (file->meta) {
        // need to come back for name2 and attrlist
        TSK_FS_META* i = file->meta;
        Out << ", \"meta\":{"
            << j("addr", i->addr, true)
            << j("atime", i->atime)
            << j("content_len", i->content_len)
            << j("crtime", i->crtime)
            << j("ctime", i->ctime)
            << j("flags", i->flags)
            << j("gid", i->gid);
        if (i->link) {
          Out << j("link", string(i->link));
        }
        if (TSK_FS_TYPE_ISEXT(Fs->ftype)) {
          Out << j("dtime", i->time2.ext2.dtime);
        }
        else if (TSK_FS_TYPE_ISHFS(Fs->ftype)) {
          Out << j("bkup_time", i->time2.hfs.bkup_time);
        }
        Out << j("mode", i->mode)
            << j("mtime", i->mtime)
            << j("nlink", i->nlink)
            << j("seq", i->seq)
            << j("size", i->size)
            << j("type", i->type)
            << j("uid", i->uid)
            << "}";
      }
      if (file->name) {
        TSK_FS_NAME* n = file->name;
        Out << ", \"name\":{"
            << j("flags", n->flags, true)
            << j("meta_addr", n->meta_addr)
            << j("meta_seq", n->meta_seq)
            << j("name", (n->name && n->name_size ? string(n->name): Null))
            << j("shrt_name", (n->shrt_name && n->shrt_name_size ? string(n->shrt_name): Null))
            << j("type", n->type)
            << j("dirIndex", CurDirIndex)
            << "}";

      }
      int numAttrs = tsk_fs_file_attr_getsize(file);
      if (numAttrs > 0) {
        Out << ", \"attrs\":[";
        uint num = 0;
        for (int i = 0; i < numAttrs; ++i) {
          const TSK_FS_ATTR* a = tsk_fs_file_attr_get_idx(file, i);
          if (a) {
            if (num > 0) {
              Out << ", ";
            }
            writeAttr(Out, a);
            ++num;
          }
        }
        Out << "]";
      }
      Out << "}" << endl;
    }
  }
  catch (std::exception& e) {
    cerr << "Error on " << NumFiles << ": " << e.what() << endl;
  }
  // cerr << "finishing callback" << endl;
  FileCounter::processFile(file, path);
  return TSK_OK;
}

bool printImageDump(const shared_ptr< Image >& img) {
  return img->dump(std::cout) != -1;
}

bool printDeviceInfo(const shared_ptr< Image >& img) {
  std::cout << "{";

  std::cout << j(string("files")) << ":[";
  writeSequence(cout, img->files().begin(), img->files().end(), ", ");
  std::cout << "]"
            << j("description", img->desc())
            << j("size", img->size());

  if (shared_ptr<VolumeSystem> vs = img->volumeSystem().lock()) {
    std::cout << "," << j("volumeSystem") << ":{"
              << j("type", vs->type(), true)
              << j("description", vs->desc())
              << j("blockSize", vs->blockSize())
              << j("numVolumes", vs->numVolumes())
              << j("offset", vs->offset());

    if (vs->numVolumes()) {
      std::cout << "," << j(string("volumes")) << ":[";
      writeSequence(std::cout, vs->volBegin(), vs->volEnd(), ",");
      std::cout << "]";
    }
    else {
      cerr << "Image has volume system, but no volumes" << endl;
    }
    std::cout << "}";
  }
  else if (shared_ptr<Filesystem> fs = img->filesystem().lock()) {
    outputFS(std::cout, fs);
  }
  else {
    cerr << "Image had neither a volume system nor a filesystem" << endl;
  }
  std::cout << "}" << std::endl;
  return true;
}

void printHelp(const po::options_description& desc) {
  std::cout << "fsrip, Copyright (c) 2010-2011, Lightbox Technologies, Inc." << std::endl;
  std::cout << "TSK version is " << tsk_version_get_str() << std::endl;
  std::cout << "Boost program options version is " << BOOST_PROGRAM_OPTIONS_VERSION << std::endl;
  std::cout << desc << std::endl;
}

shared_ptr<LbtTskAuto> createVisitor(const string& cmd, ostream& out) {
/*  if (cmd == "info") {
    return shared_ptr<TskAuto>(new ImgInfo(out));
  }*/
  if (cmd == "dumpimg") {
    return shared_ptr<LbtTskAuto>(new ImageDumper(out));
  }
  else if (cmd == "dumpfs") {
    return shared_ptr<LbtTskAuto>(new MetadataWriter(out));
  }
  else if (cmd == "count") {
    return shared_ptr<LbtTskAuto>(new FileCounter(out));
  }
  else {
    return shared_ptr<LbtTskAuto>();
  }
}

int main(int argc, char *argv[]) {
  po::options_description desc("Allowed Options");
  po::positional_options_description posOpts;
  posOpts.add("command", 1);
  posOpts.add("ev-files", -1);
  desc.add_options()
    ("help", "produce help message")
    ("command", po::value< std::string >(), "command to perform [info|dumpimg|dumpfs|count]")
    ("ev-files", po::value< std::vector< std::string > >(), "evidence files");

  po::variables_map vm;
  try {
    po::store(po::command_line_parser(argc, argv).options(desc).positional(posOpts).run(), vm);
    po::notify(vm);

    shared_ptr<LbtTskAuto> walker;

    if (vm.count("help")) {
      printHelp(desc);
    }
    else if (vm.count("command") && vm.count("ev-files") && (walker = createVisitor(vm["command"].as<string>(), cout))) {
      std::vector< string >       imgSegs(vm["ev-files"].as< vector< string > >());
      scoped_array< TSK_TCHAR* >  segments(new TSK_TCHAR*[imgSegs.size()]);
      for (unsigned int i = 0; i < imgSegs.size(); ++i) {
        segments[i] = (TSK_TCHAR*)imgSegs[i].c_str();
      }
      if (0 == walker->openImage(imgSegs.size(), segments.get(), TSK_IMG_TYPE_DETECT, 0)) {
        if (0 == walker->start()) {
          walker->finishWalk();
          return 0;
        }
        else {
          cerr << "Had an error parsing filesystem" << endl;
        }
      }
      else {
        cerr << "Had an error opening the evidence file" << endl;
        return 1;
      }
    }
    else {
      std::cerr << "did not understand arguments" << std::endl;
      return 1;
    }
  }
  catch (std::exception& err) {
    std::cerr << "Error: " << err.what() << "\n\n";
    printHelp(desc);
    return 1;
  }
  return 0;
}
<|endoftext|>


<commit_before>// Halide tutorial lesson 2.

// This lesson demonstrates how to pass in input images.

// On linux, you can compile and run it like so:
// g++ lesson_02.cpp -I ../include -L ../bin -lHalide -lpthread -ldl -lpng -o lesson_02
// LD_LIBRARY_PATH=../bin ./lesson_02

// The only Halide header file you need is Halide.h. It includes all of Halide.
#include <Halide.h>

// We'll also include stdio for printf.
#include <stdio.h>

// Include some support code for loading pngs. It assumes there's an
// Image type, so we'll pull the one from Halide namespace;
using Halide::Image;
#include "../apps/support/image_io.h"

int main(int argc, char **argv) {

    // This program defines a single-stage imaging pipeline that
    // brightens an image.

    // First we'll load the input image we wish to brighten.
    Halide::Image<uint8_t> input = load<uint8_t>("../apps/images/rgb.png");

    // Next we define our Func object that represents our one pipeline
    // stage.
    Halide::Func brighter;

    // Our Func will have three arguments, representing the position
    // in the image and the color channel. Halide treats color
    // channels as an extra dimension of the image.
    Halide::Var x, y, c;

    // Normally we'd probably write the whole function definition on
    // one line. Here we'll break it apart so we can explain what
    // we're doing at every step.

    // For each pixel of the input image.
    Halide::Expr value = input(x, y, c);

    // Cast it to a floating point value.
    value = Halide::cast<float>(value);

    // Multiply it by 1.5 to brighten it. Halide represents real
    // numbers as floats, not doubles, so we stick an 'f' on the end
    // of our constant.
    value = value * 1.5f;

    // Clamp it to between zero and 255 so we don't get overflow when
    // we cast it back to an 8-bit unsigned int.
    value = Halide::clamp(value, 0.0f, 255.0f);

    // Cast it back to an 8-bit unsigned integer.
    value = Halide::cast<uint8_t>(value);

    // Define the function.
    brighter(x, y, c) = value;

    // The equivalent one-liner to all of the above is:
    //
    // brighter(x, y, c) = Halide::cast<uint8_t>(clamp(input(x, y, c) * 1.5f, 0, 255));
    //
    // In the shorter version:
    // - I skipped the cast to float, because multiplying by 1.5f does
    //   that automatically.
    // - I also used integer constants in clamp, because they get cast
    //   to match the type of the first argument.
    // - I left the Halide:: off clamp. It's unnecessary due to Koenig
    //   lookup.

    // Remember. All we've done so far is build a representation of a
    // Halide program in memory. We haven't actually processed any
    // pixels yet. We haven't even compiled that Halide program yet.

    // So now we'll realize the Func. The size of the output image
    // should match the size of the input image. If we just wanted to
    // brighten a portion of the input image we could request a
    // smaller size. If we request a larger size Halide will throw an
    // error at runtime telling us we're trying to read out of bounds
    // on the input image.
    Halide::Image<uint8_t> output = brighter.realize(input.width(), input.height(), input.channels());

    // Save the output for inspection. It should look like a bright parrot.
    save(output, "brighter.png");

    return 0;
}
<commit_msg>Tweaks to tutorial lesson 2<commit_after>// Halide tutorial lesson 2.

// This lesson demonstrates how to pass in input images.

// On linux, you can compile and run it like so:
// g++ lesson_02.cpp -I ../include -L ../bin -lHalide -lpthread -ldl -lpng -o lesson_02
// LD_LIBRARY_PATH=../bin ./lesson_02

// The only Halide header file you need is Halide.h. It includes all of Halide.
#include <Halide.h>

// Include some support code for loading pngs. It assumes there's an
// Image type, so we'll pull the one from Halide namespace;
using Halide::Image;
#include "../apps/support/image_io.h"

int main(int argc, char **argv) {

    // This program defines a single-stage imaging pipeline that
    // brightens an image.

    // First we'll load the input image we wish to brighten.
    Halide::Image<uint8_t> input = load<uint8_t>("../apps/images/rgb.png");

    // Next we define our Func object that represents our one pipeline
    // stage.
    Halide::Func brighter;

    // Our Func will have three arguments, representing the position
    // in the image and the color channel. Halide treats color
    // channels as an extra dimension of the image.
    Halide::Var x, y, c;

    // Normally we'd probably write the whole function definition on
    // one line. Here we'll break it apart so we can explain what
    // we're doing at every step.

    // For each pixel of the input image.
    Halide::Expr value = input(x, y, c);

    // Cast it to a floating point value.
    value = Halide::cast<float>(value);

    // Multiply it by 1.5 to brighten it. Halide represents real
    // numbers as floats, not doubles, so we stick an 'f' on the end
    // of our constant.
    value = value * 1.5f;

    // Clamp it to be less than 255, so we don't get overflow when we
    // cast it back to an 8-bit unsigned int.
    value = Halide::min(value, 255.0f);

    // Cast it back to an 8-bit unsigned integer.
    value = Halide::cast<uint8_t>(value);

    // Define the function.
    brighter(x, y, c) = value;

    // The equivalent one-liner to all of the above is:
    //
    // brighter(x, y, c) = Halide::cast<uint8_t>(min(input(x, y, c) * 1.5f, 255));
    //
    // In the shorter version:
    // - I skipped the cast to float, because multiplying by 1.5f does
    //   that automatically.
    // - I also used integer constants in clamp, because they get cast
    //   to match the type of the first argument.
    // - I left the Halide:: off clamp. It's unnecessary due to Koenig
    //   lookup.

    // Remember. All we've done so far is build a representation of a
    // Halide program in memory. We haven't actually processed any
    // pixels yet. We haven't even compiled that Halide program yet.

    // So now we'll realize the Func. The size of the output image
    // should match the size of the input image. If we just wanted to
    // brighten a portion of the input image we could request a
    // smaller size. If we request a larger size Halide will throw an
    // error at runtime telling us we're trying to read out of bounds
    // on the input image.
    Halide::Image<uint8_t> output = brighter.realize(input.width(), input.height(), input.channels());

    // Save the output for inspection. It should look like a bright parrot.
    save(output, "brighter.png");

    return 0;
}
<|endoftext|>