<commit_before>/*
	Enumerates paths from a source node to a destination node. Enumerated paths are limited by a
maximum bound on their path weight.

	Path enumeration through a subgraph builds on top of a topological traversal function. Hence
the constituent functions are meant to be passed-in to a topological traversal function (see topological_traversal.h)

*/

#include "enumerate.h"
#include "exception.h"
#include "wotan_util.h"

#include "draw.h"
#include "analysis_main.h"

using namespace std;

/**** Function Declarations ****/
/* propagates path counts stored in the bucket structure of the parent node to the bucket structure of the child node */
static void propagate_path_counts(int parent_ind, int child_ind, t_rr_node &rr_node, t_ss_distances &ss_distances, t_node_topo_inf &node_topo_inf,
			e_traversal_dir traversal_dir, int max_path_weight, e_bucket_mode enumerate_mode);

/**** Function Definitions ****/
/* Called when node is popped from expansion queue during topological traversal */
void enumerate_node_popped_func(int popped_node, int from_node_ind, int to_node_ind, t_rr_node &rr_node, t_ss_distances &ss_distances, t_node_topo_inf &node_topo_inf,
                          e_traversal_dir traversal_dir, int max_path_weight, User_Options *user_opts, void *user_data){

	/* increment node demand */
	if (traversal_dir == FORWARD_TRAVERSAL){
		/* increment node demand of all nodes except SOURCE & SINK */
		e_rr_type node_type = rr_node[popped_node].get_rr_type();
		if (node_type != SOURCE && node_type != SINK){
			int node_weight = rr_node[popped_node].get_weight();
			int dist_to_source = ss_distances[popped_node].get_source_distance();
			float demand_contribution = node_topo_inf[popped_node].buckets.get_num_paths(node_weight, dist_to_source, max_path_weight);
			rr_node[popped_node].increment_demand( demand_contribution );

			/* TODO: comment */
			if (user_opts->keep_path_count_history){
				e_rr_type type = rr_node[popped_node].get_rr_type();
				if (type == OPIN || type == IPIN || type == CHANX || type == CHANY){
					rr_node[popped_node].increment_path_count_history(demand_contribution, rr_node[from_node_ind]);
					rr_node[popped_node].increment_path_count_history(demand_contribution, rr_node[to_node_ind]);
				}
			}
		}

		/* add to existing count of the number of routing nodes (CHANX/CHANY/IPIN/OPIN) in the legal subgraph */
		Enumerate_Structs *enumerate_structs = (Enumerate_Structs *)user_data;
		int popped_node_weight = rr_node[popped_node].get_weight();
		if ( ss_distances[popped_node].is_legal(popped_node_weight, max_path_weight) ){
			if (node_type == CHANX || node_type == CHANY || node_type == IPIN || node_type == OPIN){
				enumerate_structs->num_routing_nodes_in_subgraph++;
			}
		}
	}

}

/* Called when topological traversal is iterateing over a node's children */
bool enumerate_child_iterated_func(int parent_ind, int node_ind, t_rr_node &rr_node, t_ss_distances &ss_distances, t_node_topo_inf &node_topo_inf,
                          e_traversal_dir traversal_dir, int max_path_weight, int from_node_ind, int to_node_ind, User_Options *user_opts, void *user_data){
	bool ignore_node = false;

	Enumerate_Structs *enumerate_structs = (Enumerate_Structs *)user_data;

	/* propagate the path counts (stored in the bucket structure) of the parent node to this node */
	//if (enumerate_structs->mode == BY_PATH_HOPS){
	//	cout << "from: " << from_node_ind << "  to: " << to_node_ind << endl;
	//	cout << "child: " << node_ind << "  parent: " << parent_ind << endl;
	//}
	propagate_path_counts(parent_ind, node_ind, rr_node, ss_distances, node_topo_inf, traversal_dir, max_path_weight, enumerate_structs->mode);

	//if (from_node_ind == 5784 && to_node_ind == 6950){
	//	cout << parent_ind << " to " << node_ind << endl;
	//}

	return ignore_node;
}

/* Called once topological traversal is complete. */
void enumerate_traversal_done_func(int from_node_ind, int to_node_ind, t_rr_node &rr_node, t_ss_distances &ss_distances, t_node_topo_inf &node_topo_inf,
                          e_traversal_dir traversal_dir, int max_path_weight, User_Options *user_opts, void *user_data){

	/* nothing to be done */
}

/* propagates path counts stored in the bucket structure of the parent node to the bucket structure of the child node */
static void propagate_path_counts(int parent_ind, int child_ind, t_rr_node &rr_node, t_ss_distances &ss_distances, t_node_topo_inf &node_topo_inf,
			e_traversal_dir traversal_dir, int max_path_weight, e_bucket_mode enumerate_mode){

	if (enumerate_mode != BY_PATH_WEIGHT && enumerate_mode != BY_PATH_HOPS){
		WTHROW(EX_PATH_ENUM, "Unknown enumeration mode: " << enumerate_mode);
	}

	float *parent_buckets;
	float *child_buckets;
	int num_buckets;
	int child_dist_to_target = UNDEFINED;	//minimum distance from child to target node
	int parent_dist_to_start = UNDEFINED;	//minimum distance from parent to start node

	int max_dist = max_path_weight;
	int child_weight = rr_node[child_ind].get_weight();
	if (enumerate_mode == BY_PATH_HOPS){
		child_weight = 1;
		max_dist += 3;
	}

	/* get bucket structures according to direction of traversal */
	if (traversal_dir == FORWARD_TRAVERSAL){
		parent_buckets = node_topo_inf[parent_ind].buckets.source_buckets;
		child_buckets = node_topo_inf[child_ind].buckets.source_buckets;
		num_buckets = node_topo_inf[parent_ind].buckets.get_num_source_buckets();

		if (enumerate_mode == BY_PATH_WEIGHT){
			/* path weight to a node already includes the weight of that node */
			child_dist_to_target = ss_distances[child_ind].get_sink_distance();
			parent_dist_to_start = ss_distances[parent_ind].get_source_distance();
		} else {
			/* # hops between two nodes is essentially the number of edges between them */
			child_dist_to_target = ss_distances[child_ind].get_sink_hops() + 1;	//need to account for hop between parent/child
			parent_dist_to_start = ss_distances[parent_ind].get_source_hops();
			//cout << "child to target: " << child_dist_to_target << "  parent to start: " << parent_dist_to_start << endl;
		}
	} else {
		parent_buckets = node_topo_inf[parent_ind].buckets.sink_buckets;
		child_buckets = node_topo_inf[child_ind].buckets.sink_buckets;
		num_buckets = node_topo_inf[parent_ind].buckets.get_num_sink_buckets();

		if (enumerate_mode == BY_PATH_WEIGHT){
			/* path weight to a node already includes the weight of that node */
			child_dist_to_target = ss_distances[child_ind].get_source_distance();
			parent_dist_to_start = ss_distances[parent_ind].get_sink_distance();
		} else {
			child_dist_to_target = ss_distances[child_ind].get_source_hops() + 1;	//need to account for hop between parent/child
			parent_dist_to_start = ss_distances[parent_ind].get_sink_hops();
		}
	}

	if (parent_dist_to_start < 0){
		WTHROW(EX_PATH_ENUM, "Parent node has distance to start node of < 0: " << parent_dist_to_start);
	}

	/* now propagate parent path counts to the child */
	for (int ibucket = parent_dist_to_start; ibucket < num_buckets; ibucket++){	//parent cannot carry paths of weight smaller than itself

		/* we're done if this set of paths cannot possibly reach the target node
		   in under the minimum allowable path weight */
		if (ibucket + child_dist_to_target > max_dist){
			break;
		}

		/* parent has no paths in this bucket -- nothing to propagate */
		if (parent_buckets[ibucket] == UNDEFINED){
			continue;
		}

		//if (enumerate_mode == BY_PATH_HOPS){
		//	cout << "\tbucket " << ibucket << ": " << parent_buckets[ibucket] << endl;
		//}

		/* bucket into which to propagate probabilities */
		int target_bucket = ibucket + child_weight;

		/* propagate the parent path counts to child */
		if (child_buckets[target_bucket] == UNDEFINED){
			child_buckets[target_bucket] = parent_buckets[ibucket];
		} else {
			child_buckets[target_bucket] += parent_buckets[ibucket];
		}
	}
}

<commit_msg>Removing all demand from OPIN/IPIN nodes<commit_after>/*
	Enumerates paths from a source node to a destination node. Enumerated paths are limited by a
maximum bound on their path weight.

	Path enumeration through a subgraph builds on top of a topological traversal function. Hence
the constituent functions are meant to be passed-in to a topological traversal function (see topological_traversal.h)

*/

#include "enumerate.h"
#include "exception.h"
#include "wotan_util.h"

#include "draw.h"
#include "analysis_main.h"

using namespace std;

/**** Function Declarations ****/
/* propagates path counts stored in the bucket structure of the parent node to the bucket structure of the child node */
static void propagate_path_counts(int parent_ind, int child_ind, t_rr_node &rr_node, t_ss_distances &ss_distances, t_node_topo_inf &node_topo_inf,
			e_traversal_dir traversal_dir, int max_path_weight, e_bucket_mode enumerate_mode);

/**** Function Definitions ****/
/* Called when node is popped from expansion queue during topological traversal */
void enumerate_node_popped_func(int popped_node, int from_node_ind, int to_node_ind, t_rr_node &rr_node, t_ss_distances &ss_distances, t_node_topo_inf &node_topo_inf,
                          e_traversal_dir traversal_dir, int max_path_weight, User_Options *user_opts, void *user_data){

	/* increment node demand */
	if (traversal_dir == FORWARD_TRAVERSAL){
		/* increment node demand of all nodes except SOURCE & SINK */
		e_rr_type node_type = rr_node[popped_node].get_rr_type();
		if (node_type != SOURCE && node_type != SINK     && node_type != OPIN && node_type != IPIN){
			int node_weight = rr_node[popped_node].get_weight();
			int dist_to_source = ss_distances[popped_node].get_source_distance();
			float demand_contribution = node_topo_inf[popped_node].buckets.get_num_paths(node_weight, dist_to_source, max_path_weight);
			rr_node[popped_node].increment_demand( demand_contribution );

			/* TODO: comment */
			if (user_opts->keep_path_count_history){
				e_rr_type type = rr_node[popped_node].get_rr_type();
				if (type == OPIN || type == IPIN || type == CHANX || type == CHANY){
					rr_node[popped_node].increment_path_count_history(demand_contribution, rr_node[from_node_ind]);
					rr_node[popped_node].increment_path_count_history(demand_contribution, rr_node[to_node_ind]);
				}
			}
		}

		/* add to existing count of the number of routing nodes (CHANX/CHANY/IPIN/OPIN) in the legal subgraph */
		Enumerate_Structs *enumerate_structs = (Enumerate_Structs *)user_data;
		int popped_node_weight = rr_node[popped_node].get_weight();
		if ( ss_distances[popped_node].is_legal(popped_node_weight, max_path_weight) ){
			if (node_type == CHANX || node_type == CHANY || node_type == IPIN || node_type == OPIN){
				enumerate_structs->num_routing_nodes_in_subgraph++;
			}
		}
	}

}

/* Called when topological traversal is iterateing over a node's children */
bool enumerate_child_iterated_func(int parent_ind, int node_ind, t_rr_node &rr_node, t_ss_distances &ss_distances, t_node_topo_inf &node_topo_inf,
                          e_traversal_dir traversal_dir, int max_path_weight, int from_node_ind, int to_node_ind, User_Options *user_opts, void *user_data){
	bool ignore_node = false;

	Enumerate_Structs *enumerate_structs = (Enumerate_Structs *)user_data;

	/* propagate the path counts (stored in the bucket structure) of the parent node to this node */
	//if (enumerate_structs->mode == BY_PATH_HOPS){
	//	cout << "from: " << from_node_ind << "  to: " << to_node_ind << endl;
	//	cout << "child: " << node_ind << "  parent: " << parent_ind << endl;
	//}
	propagate_path_counts(parent_ind, node_ind, rr_node, ss_distances, node_topo_inf, traversal_dir, max_path_weight, enumerate_structs->mode);

	//if (from_node_ind == 5784 && to_node_ind == 6950){
	//	cout << parent_ind << " to " << node_ind << endl;
	//}

	return ignore_node;
}

/* Called once topological traversal is complete. */
void enumerate_traversal_done_func(int from_node_ind, int to_node_ind, t_rr_node &rr_node, t_ss_distances &ss_distances, t_node_topo_inf &node_topo_inf,
                          e_traversal_dir traversal_dir, int max_path_weight, User_Options *user_opts, void *user_data){

	/* nothing to be done */
}

/* propagates path counts stored in the bucket structure of the parent node to the bucket structure of the child node */
static void propagate_path_counts(int parent_ind, int child_ind, t_rr_node &rr_node, t_ss_distances &ss_distances, t_node_topo_inf &node_topo_inf,
			e_traversal_dir traversal_dir, int max_path_weight, e_bucket_mode enumerate_mode){

	if (enumerate_mode != BY_PATH_WEIGHT && enumerate_mode != BY_PATH_HOPS){
		WTHROW(EX_PATH_ENUM, "Unknown enumeration mode: " << enumerate_mode);
	}

	float *parent_buckets;
	float *child_buckets;
	int num_buckets;
	int child_dist_to_target = UNDEFINED;	//minimum distance from child to target node
	int parent_dist_to_start = UNDEFINED;	//minimum distance from parent to start node

	int max_dist = max_path_weight;
	int child_weight = rr_node[child_ind].get_weight();
	if (enumerate_mode == BY_PATH_HOPS){
		child_weight = 1;
		max_dist += 3;
	}

	/* get bucket structures according to direction of traversal */
	if (traversal_dir == FORWARD_TRAVERSAL){
		parent_buckets = node_topo_inf[parent_ind].buckets.source_buckets;
		child_buckets = node_topo_inf[child_ind].buckets.source_buckets;
		num_buckets = node_topo_inf[parent_ind].buckets.get_num_source_buckets();

		if (enumerate_mode == BY_PATH_WEIGHT){
			/* path weight to a node already includes the weight of that node */
			child_dist_to_target = ss_distances[child_ind].get_sink_distance();
			parent_dist_to_start = ss_distances[parent_ind].get_source_distance();
		} else {
			/* # hops between two nodes is essentially the number of edges between them */
			child_dist_to_target = ss_distances[child_ind].get_sink_hops() + 1;	//need to account for hop between parent/child
			parent_dist_to_start = ss_distances[parent_ind].get_source_hops();
			//cout << "child to target: " << child_dist_to_target << "  parent to start: " << parent_dist_to_start << endl;
		}
	} else {
		parent_buckets = node_topo_inf[parent_ind].buckets.sink_buckets;
		child_buckets = node_topo_inf[child_ind].buckets.sink_buckets;
		num_buckets = node_topo_inf[parent_ind].buckets.get_num_sink_buckets();

		if (enumerate_mode == BY_PATH_WEIGHT){
			/* path weight to a node already includes the weight of that node */
			child_dist_to_target = ss_distances[child_ind].get_source_distance();
			parent_dist_to_start = ss_distances[parent_ind].get_sink_distance();
		} else {
			child_dist_to_target = ss_distances[child_ind].get_source_hops() + 1;	//need to account for hop between parent/child
			parent_dist_to_start = ss_distances[parent_ind].get_sink_hops();
		}
	}

	if (parent_dist_to_start < 0){
		WTHROW(EX_PATH_ENUM, "Parent node has distance to start node of < 0: " << parent_dist_to_start);
	}

	/* now propagate parent path counts to the child */
	for (int ibucket = parent_dist_to_start; ibucket < num_buckets; ibucket++){	//parent cannot carry paths of weight smaller than itself

		/* we're done if this set of paths cannot possibly reach the target node
		   in under the minimum allowable path weight */
		if (ibucket + child_dist_to_target > max_dist){
			break;
		}

		/* parent has no paths in this bucket -- nothing to propagate */
		if (parent_buckets[ibucket] == UNDEFINED){
			continue;
		}

		//if (enumerate_mode == BY_PATH_HOPS){
		//	cout << "\tbucket " << ibucket << ": " << parent_buckets[ibucket] << endl;
		//}

		/* bucket into which to propagate probabilities */
		int target_bucket = ibucket + child_weight;

		/* propagate the parent path counts to child */
		if (child_buckets[target_bucket] == UNDEFINED){
			child_buckets[target_bucket] = parent_buckets[ibucket];
		} else {
			child_buckets[target_bucket] += parent_buckets[ibucket];
		}
	}
}

<|endoftext|>


<commit_before>#include "selfdrive/camerad/cameras/camera_replay.h"

#include <cassert>
#include <thread>

#include "common/clutil.h"
#include "common/util.h"

extern ExitHandler do_exit;

void camera_autoexposure(CameraState *s, float grey_frac) {}

namespace {

const char *BASE_URL = "https://commadataci.blob.core.windows.net/openpilotci/";

const std::string road_camera_route = "0c94aa1e1296d7c6|2021-05-05--19-48-37";
// const std::string driver_camera_route = "534ccd8a0950a00c|2021-06-08--12-15-37";

std::string get_url(std::string route_name, const std::string &camera, int segment_num) {
  std::replace(route_name.begin(), route_name.end(), '|', '/');
  return util::string_format("%s%s/%d/%s.hevc", BASE_URL, route_name.c_str(), segment_num, camera.c_str());
}

void camera_init(VisionIpcServer *v, CameraState *s, int camera_id, unsigned int fps, cl_device_id device_id, cl_context ctx, VisionStreamType rgb_type, VisionStreamType yuv_type, const std::string &url) {
  s->frame = new FrameReader();
  if (!s->frame->load(url)) {
    printf("failed to load stream from %s", url.c_str());
    assert(0);
  }

  CameraInfo ci = {
      .frame_width = (uint32_t)s->frame->width,
      .frame_height = (uint32_t)s->frame->height,
      .frame_stride = (uint32_t)s->frame->width * 3,
  };
  s->ci = ci;
  s->camera_num = camera_id;
  s->fps = fps;
  s->buf.init(device_id, ctx, s, v, FRAME_BUF_COUNT, rgb_type, yuv_type);
}

void camera_close(CameraState *s) {
  delete s->frame;
}

void run_camera(CameraState *s) {
  uint32_t stream_frame_id = 0, frame_id = 0;
  size_t buf_idx = 0;
  std::unique_ptr<uint8_t[]> yuv_buf = std::make_unique<uint8_t[]>(s->frame->getYUVSize());
  while (!do_exit) {
    if (stream_frame_id == s->frame->getFrameCount()) {
      // loop stream
      stream_frame_id = 0;
    }
    if (s->frame->get(stream_frame_id++, yuv_buf.get())) {
      s->buf.camera_bufs_metadata[buf_idx] = {.frame_id = frame_id};
      auto &buf = s->buf.camera_bufs[buf_idx];
      CL_CHECK(clEnqueueWriteBuffer(buf.copy_q, buf.buf_cl, CL_TRUE, 0, s->frame->getYUVSize(), yuv_buf.get(), 0, NULL, NULL));
      s->buf.queue(buf_idx);
      ++frame_id;
      buf_idx = (buf_idx + 1) % FRAME_BUF_COUNT;
    }
    util::sleep_for(1000 / s->fps);
  }
}

void road_camera_thread(CameraState *s) {
  util::set_thread_name("replay_road_camera_thread");
  run_camera(s);
}

// void driver_camera_thread(CameraState *s) {
//   util::set_thread_name("replay_driver_camera_thread");
//   run_camera(s);
// }

void process_road_camera(MultiCameraState *s, CameraState *c, int cnt) {
  const CameraBuf *b = &c->buf;
  MessageBuilder msg;
  auto framed = msg.initEvent().initRoadCameraState();
  fill_frame_data(framed, b->cur_frame_data);
  framed.setImage(kj::arrayPtr((const uint8_t *)b->cur_yuv_buf->addr, b->cur_yuv_buf->len));
  framed.setTransform(b->yuv_transform.v);
  s->pm->send("roadCameraState", msg);
}

// void process_driver_camera(MultiCameraState *s, CameraState *c, int cnt) {
//   MessageBuilder msg;
//   auto framed = msg.initEvent().initDriverCameraState();
//   framed.setFrameType(cereal::FrameData::FrameType::FRONT);
//   fill_frame_data(framed, c->buf.cur_frame_data);
//   s->pm->send("driverCameraState", msg);
// }

}  // namespace

void cameras_init(VisionIpcServer *v, MultiCameraState *s, cl_device_id device_id, cl_context ctx) {
  camera_init(v, &s->road_cam, CAMERA_ID_LGC920, 20, device_id, ctx,
              VISION_STREAM_RGB_ROAD, VISION_STREAM_ROAD, get_url(road_camera_route, "fcamera", 0));
  // camera_init(v, &s->driver_cam, CAMERA_ID_LGC615, 10, device_id, ctx,
  //             VISION_STREAM_RGB_DRIVER, VISION_STREAM_DRIVER, get_url(driver_camera_route, "dcamera", 0));
  s->pm = new PubMaster({"roadCameraState", "driverCameraState", "thumbnail"});
}

void cameras_open(MultiCameraState *s) {}

void cameras_close(MultiCameraState *s) {
  camera_close(&s->road_cam);
  camera_close(&s->driver_cam);
  delete s->pm;
}

void cameras_run(MultiCameraState *s) {
  std::vector<std::thread> threads;
  threads.push_back(start_process_thread(s, &s->road_cam, process_road_camera));
  // threads.push_back(start_process_thread(s, &s->driver_cam, process_driver_camera));
  // threads.push_back(std::thread(driver_camera_thread, &s->driver_cam));
  road_camera_thread(&s->road_cam);

  for (auto &t : threads) t.join();

  cameras_close(s);
}
<commit_msg>remove that too<commit_after><|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright (c) 2012, Dougal J. Sutherland (dsutherl@cs.cmu.edu).             *
 * All rights reserved.                                                        *
 *                                                                             *
 * Redistribution and use in source and binary forms, with or without          *
 * modification, are permitted provided that the following conditions are met: *
 *                                                                             *
 *     * Redistributions of source code must retain the above copyright        *
 *       notice, this list of conditions and the following disclaimer.         *
 *                                                                             *
 *     * 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.  *
 *                                                                             *
 *     * Neither the name of Carnegie Mellon University nor the                *
 *       names of the contributors may be used to endorse or promote products  *
 *       derived from this software without specific prior written permission. *
 *                                                                             *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 "np-divs/np_divs.hpp"
#include "np-divs/matrix_io.hpp"
#include "np-divs/div-funcs/div_func.hpp"
#include "np-divs/div_func_from_str.hpp"

#include <iostream>
#include <fstream>
#include <string>

#include <boost/bind.hpp>
#include <boost/program_options.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/utility.hpp>

#include <flann/util/matrix.h>

using namespace NPDivs;
using namespace std;
using namespace boost;
namespace po = boost::program_options;

typedef struct s_popts : noncopyable {
    string x_bags_file;
    string y_bags_file;
    string results_file;

    ptr_vector<DivFunc> div_funcs;

    size_t k;
    size_t num_threads;

    flann::IndexParams index_params;
    flann::SearchParams search_params;

    void parse_div_funcs(const vector<string> &names) {
        if (names.size() == 0) {
            div_funcs.push_back(div_func_from_str("l2"));
        } else {
            for (size_t i = 0; i < names.size(); i++) {
                div_funcs.push_back(div_func_from_str(names[i]));
            }
        }
    }

    void parse_index(const string name) {
        // TODO: more index types, support arguments
        if (name == "linear" || name == "brute") {
            index_params = flann::LinearIndexParams();

        } else if (name == "kdtree" || name == "kd") {
            index_params = flann::KDTreeSingleIndexParams();

        } else {
            throw domain_error((format("unknown index type %s") % name).str());
        }
    }
} ProgOpts;

bool parse_args(int argc, char ** argv, ProgOpts& opts);

int main(int argc, char ** argv) {
    typedef flann::Matrix<double> Matrix;

    ProgOpts opts;
    opts.search_params = flann::SearchParams(64);
    if (!parse_args(argc, argv, opts))
        return 1;

    size_t num_df = opts.div_funcs.size();

    // load input bags
    // TODO - gracefully handle nonexisting files
    size_t num_x;
    Matrix* x_bags;
    if (opts.x_bags_file == "-") {
        x_bags = matrices_from_csv(cin, num_x);
    } else {
        ifstream ifs(opts.x_bags_file.c_str(), ifstream::in);
        x_bags = matrices_from_csv(ifs, num_x);
    }

    size_t num_y;
    Matrix* y_bags;
    if (opts.y_bags_file.empty()) {
        y_bags = NULL;
        num_y = num_x;
    } else if (opts.y_bags_file == "-") {
        y_bags = matrices_from_csv(cin, num_y);
    } else {
        ifstream ifs(opts.y_bags_file.c_str(), ifstream::in);
        y_bags = matrices_from_csv(ifs, num_y);
    }

    Matrix* results = alloc_matrix_array<double>(num_df, num_x, num_y);

    try {
        np_divs(x_bags, num_x, y_bags, num_y, opts.div_funcs, results, opts.k,
                opts.index_params, opts.search_params, opts.num_threads);
    } catch (std::exception e) {
        cerr << "Error: " << e.what() << endl;
        exit(1);
    }

    if (opts.results_file == "-") {
        matrix_array_to_csv(cout, results, num_df);
    } else {
        ofstream ofs(opts.results_file.c_str());
        matrix_array_to_csv(ofs, results, num_df);
    }

    free_matrix_array(results, num_df);

    return 0;
}

// TODO nicer handling of matrix inputs
// TODO optionally support HDF5 inputs
// TODO positional arguments for x_bags, y_bags
// TODO support setting {index,search}_params
bool parse_args(int argc, char ** argv, ProgOpts& opts) {
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help,h", "Produce this help message.")
        ("x-bags,x",
            po::value<string>(&opts.x_bags_file)->default_value("-"),
            "CSV-style file containing matrices separated by blank lines; "
            "- means stdin.")
        ("y-bags,y",
            po::value<string>(&opts.y_bags_file),
            "CSV-style file containing matrices separated by blank lines. "
            "If passed, divergences are calculated between the x bags (rows "
            "in the output matrix) and the y bags (columns); if not passed, "
            "divergences are calculated from the x bags to themselves. Pass "
            "- to use stdin; if both x and y are from stdin, x is read first "
            "and the two groups must be separated by exactly two blank lines. ")
        ("results,r",
            po::value<string>(&opts.results_file)->default_value("-"),
            "Where to write CSV-style matrix of results, where m[i,j] = "
            "div(x_i, y_j). Use - for stdout.")
        ("div-func,f",
            po::value< vector<string> >()->composing()
               ->notifier(bind(&ProgOpts::parse_div_funcs, ref(opts), _1)),
            "Divergence functions to use; can be specified more than once. If "
            "none passed, uses L2. Format is name:arg1:arg2:..., where argN "
            "refers to the Nth argument to the corresponding DivFunc's "
            "constructor. Some support a first argument specifying a "
            "parameter: renyi:.99 means the Renyi-.99 divergence. All support "
            "a last parameter, which determines the way that large values are "
            "normalized: l2:.95 or renyi:.99:.95 means certain calculated "
            "intermediate values above the 95th percentile are cut down; 1 "
            "means not to do this; default is .99. All extra arguments are "
            "optional.")
        ("num-threads",
            po::value<size_t>(&opts.num_threads)->default_value(0),
            "Number of threads to use for calculations. 0 means one per core.")
        ("neighbors,k",
            po::value<size_t>(&opts.k)->default_value(3),
            "The k for k-nearest-neighbor calculations.")
        ("index,i",
            po::value<string>()->default_value("kdtree")
                ->notifier(bind(&ProgOpts::parse_index, ref(opts), _1)),
            "The nearest-neighbor index to use. Options: linear, kdtree.")
    ;

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

        if (vm.count("help")) {
            std::cout << desc << "\n";
            exit(0);
        }

        po::notify(vm);

    } catch (std::exception &e) {
        cerr << "Error: " << e.what() << endl;
        return false;
    }

    return true;
}
<commit_msg>notifier isn't actually called if the arg isn't passed<commit_after>/*******************************************************************************
 * Copyright (c) 2012, Dougal J. Sutherland (dsutherl@cs.cmu.edu).             *
 * All rights reserved.                                                        *
 *                                                                             *
 * Redistribution and use in source and binary forms, with or without          *
 * modification, are permitted provided that the following conditions are met: *
 *                                                                             *
 *     * Redistributions of source code must retain the above copyright        *
 *       notice, this list of conditions and the following disclaimer.         *
 *                                                                             *
 *     * 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.  *
 *                                                                             *
 *     * Neither the name of Carnegie Mellon University nor the                *
 *       names of the contributors may be used to endorse or promote products  *
 *       derived from this software without specific prior written permission. *
 *                                                                             *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 "np-divs/np_divs.hpp"
#include "np-divs/matrix_io.hpp"
#include "np-divs/div-funcs/div_func.hpp"
#include "np-divs/div_func_from_str.hpp"

#include <iostream>
#include <fstream>
#include <string>

#include <boost/bind.hpp>
#include <boost/program_options.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/utility.hpp>

#include <flann/util/matrix.h>

using namespace NPDivs;
using namespace std;
using namespace boost;
namespace po = boost::program_options;

typedef struct s_popts : noncopyable {
    string x_bags_file;
    string y_bags_file;
    string results_file;

    ptr_vector<DivFunc> div_funcs;

    size_t k;
    size_t num_threads;

    flann::IndexParams index_params;
    flann::SearchParams search_params;

    void parse_div_funcs(const vector<string> &names) {
        for (size_t i = 0; i < names.size(); i++) {
            div_funcs.push_back(div_func_from_str(names[i]));
        }
    }

    void parse_index(const string name) {
        // TODO: more index types, support arguments
        if (name == "linear" || name == "brute") {
            index_params = flann::LinearIndexParams();

        } else if (name == "kdtree" || name == "kd") {
            index_params = flann::KDTreeSingleIndexParams();

        } else {
            throw domain_error((format("unknown index type %s") % name).str());
        }
    }
} ProgOpts;

bool parse_args(int argc, char ** argv, ProgOpts& opts);

int main(int argc, char ** argv) {
    typedef flann::Matrix<double> Matrix;

    ProgOpts opts;
    opts.search_params = flann::SearchParams(64);
    if (!parse_args(argc, argv, opts))
        return 1;

    size_t num_df = opts.div_funcs.size();
    if (num_df == 0) {
        cerr << "Error: at least one div func is required\n";
        return 1;
    }

    // load input bags
    // TODO - gracefully handle nonexisting files
    size_t num_x;
    Matrix* x_bags;
    if (opts.x_bags_file == "-") {
        x_bags = matrices_from_csv(cin, num_x);
    } else {
        ifstream ifs(opts.x_bags_file.c_str(), ifstream::in);
        x_bags = matrices_from_csv(ifs, num_x);
    }

    size_t num_y;
    Matrix* y_bags;
    if (opts.y_bags_file.empty()) {
        y_bags = NULL;
        num_y = num_x;
    } else if (opts.y_bags_file == "-") {
        y_bags = matrices_from_csv(cin, num_y);
    } else {
        ifstream ifs(opts.y_bags_file.c_str(), ifstream::in);
        y_bags = matrices_from_csv(ifs, num_y);
    }

    Matrix* results = alloc_matrix_array<double>(num_df, num_x, num_y);

    try {
        np_divs(x_bags, num_x, y_bags, num_y, opts.div_funcs, results, opts.k,
                opts.index_params, opts.search_params, opts.num_threads);
    } catch (std::exception e) {
        cerr << "Error: " << e.what() << endl;
        exit(1);
    }

    if (opts.results_file == "-") {
        matrix_array_to_csv(cout, results, num_df);
    } else {
        ofstream ofs(opts.results_file.c_str());
        matrix_array_to_csv(ofs, results, num_df);
    }

    free_matrix_array(results, num_df);

    return 0;
}

// TODO nicer handling of matrix inputs
// TODO optionally support HDF5 inputs
// TODO positional arguments for x_bags, y_bags
// TODO support setting {index,search}_params
bool parse_args(int argc, char ** argv, ProgOpts& opts) {
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help,h", "Produce this help message.")
        ("x-bags,x",
            po::value<string>(&opts.x_bags_file)->default_value("-"),
            "CSV-style file containing matrices separated by blank lines; "
            "- means stdin.")
        ("y-bags,y",
            po::value<string>(&opts.y_bags_file),
            "CSV-style file containing matrices separated by blank lines. "
            "If passed, divergences are calculated between the x bags (rows "
            "in the output matrix) and the y bags (columns); if not passed, "
            "divergences are calculated from the x bags to themselves. Pass "
            "- to use stdin; if both x and y are from stdin, x is read first "
            "and the two groups must be separated by exactly two blank lines. ")
        ("results,r",
            po::value<string>(&opts.results_file)->default_value("-"),
            "Where to write CSV-style matrix of results, where m[i,j] = "
            "div(x_i, y_j). Use - for stdout.")
        ("div-func,f",
            po::value< vector<string> >()->composing()
               ->notifier(bind(&ProgOpts::parse_div_funcs, ref(opts), _1)),
            "Divergence functions to use; can be specified more than once. If "
            "none passed, uses L2. Format is name:arg1:arg2:..., where argN "
            "refers to the Nth argument to the corresponding DivFunc's "
            "constructor. Some support a first argument specifying a "
            "parameter: renyi:.99 means the Renyi-.99 divergence. All support "
            "a last parameter, which determines the way that large values are "
            "normalized: l2:.95 or renyi:.99:.95 means certain calculated "
            "intermediate values above the 95th percentile are cut down; 1 "
            "means not to do this; default is .99. All extra arguments are "
            "optional.")
        ("num-threads",
            po::value<size_t>(&opts.num_threads)->default_value(0),
            "Number of threads to use for calculations. 0 means one per core.")
        ("neighbors,k",
            po::value<size_t>(&opts.k)->default_value(3),
            "The k for k-nearest-neighbor calculations.")
        ("index,i",
            po::value<string>()->default_value("kdtree")
                ->notifier(bind(&ProgOpts::parse_index, ref(opts), _1)),
            "The nearest-neighbor index to use. Options: linear, kdtree.")
    ;

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

        if (vm.count("help")) {
            std::cout << desc << "\n";
            exit(0);
        }

        po::notify(vm);

    } catch (std::exception &e) {
        cerr << "Error: " << e.what() << endl;
        return false;
    }

    return true;
}
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkDiffusionImage.h"
#include "mitkBaseData.h"
#include <mitkIOUtil.h>

#include <itkDiffusionTensor3DReconstructionImageFilter.h>
#include <itkDiffusionTensor3D.h>
#include <itkImageFileWriter.h>
#include <itkNrrdImageIO.h>
#include "mitkCommandLineParser.h"
#include <itksys/SystemTools.hxx>

using namespace mitk;
/**
 * Convert files from one ending to the other
 */
int main(int argc, char* argv[])
{
    std::cout << "TensorReconstruction";
    mitkCommandLineParser parser;
    parser.setArgumentPrefix("--", "-");
    parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input file", "input raw dwi (.dwi or .fsl/.fslgz)", us::Any(), false);
    parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output file", "output file", us::Any(), false);
    parser.addArgument("b0Threshold", "t", mitkCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0, true);

    parser.setCategory("Preprocessing Tools");
    parser.setTitle("Tensor Reconstruction");
    parser.setDescription("");
    parser.setContributor("MBI");

    map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
    if (parsedArgs.size()==0)
        return EXIT_FAILURE;

    std::string inFileName = us::any_cast<string>(parsedArgs["input"]);
    std::string outfilename = us::any_cast<string>(parsedArgs["outFile"]);
    outfilename = itksys::SystemTools::GetFilenamePath(outfilename)+"/"+itksys::SystemTools::GetFilenameWithoutExtension(outfilename);
    outfilename += ".dti";

    int threshold = 0;
    if (parsedArgs.count("b0Threshold"))
        threshold = us::any_cast<int>(parsedArgs["b0Threshold"]);

    try
    {
        std::vector<BaseData::Pointer> infile = IOUtil::Load( inFileName );
        DiffusionImage<short>::Pointer dwi = dynamic_cast<DiffusionImage<short>*>(infile.at(0).GetPointer());

        typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, float > TensorReconstructionImageFilterType;
        TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New();
        filter->SetGradientImage( dwi->GetDirections(), dwi->GetVectorImage() );
        filter->SetBValue(dwi->GetReferenceBValue());
        filter->SetThreshold(threshold);
        filter->Update();

        // Save tensor image
        itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
        io->SetFileType( itk::ImageIOBase::Binary );
        io->UseCompressionOn();

        itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::Pointer writer = itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::New();
        writer->SetInput(filter->GetOutput());
        writer->SetFileName(outfilename);
        writer->SetImageIO(io);
        writer->UseCompressionOn();
        writer->Update();
    }
    catch ( itk::ExceptionObject &err)
    {
        std::cout << "Exception: " << err;
    }
    catch ( std::exception err)
    {
        std::cout << "Exception: " << err.what();
    }
    catch ( ... )
    {
        std::cout << "Exception!";
    }
    return EXIT_SUCCESS;

}
<commit_msg>COMP: Force continuous dartclients to run.<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkDiffusionImage.h"
#include "mitkBaseData.h"
#include <mitkIOUtil.h>

#include <itkDiffusionTensor3DReconstructionImageFilter.h>
#include <itkDiffusionTensor3D.h>
#include <itkImageFileWriter.h>
#include <itkNrrdImageIO.h>
#include "mitkCommandLineParser.h"
#include <itksys/SystemTools.hxx>

using namespace mitk;

/**
 * Convert files from one ending to the other
 */

int main(int argc, char* argv[])
{
    std::cout << "TensorReconstruction";
    mitkCommandLineParser parser;
    parser.setArgumentPrefix("--", "-");
    parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input file", "input raw dwi (.dwi or .fsl/.fslgz)", us::Any(), false);
    parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output file", "output file", us::Any(), false);
    parser.addArgument("b0Threshold", "t", mitkCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0, true);

    parser.setCategory("Preprocessing Tools");
    parser.setTitle("Tensor Reconstruction");
    parser.setDescription("");
    parser.setContributor("MBI");

    map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
    if (parsedArgs.size()==0)
        return EXIT_FAILURE;

    std::string inFileName = us::any_cast<string>(parsedArgs["input"]);
    std::string outfilename = us::any_cast<string>(parsedArgs["outFile"]);
    outfilename = itksys::SystemTools::GetFilenamePath(outfilename)+"/"+itksys::SystemTools::GetFilenameWithoutExtension(outfilename);
    outfilename += ".dti";

    int threshold = 0;
    if (parsedArgs.count("b0Threshold"))
        threshold = us::any_cast<int>(parsedArgs["b0Threshold"]);

    try
    {
        std::vector<BaseData::Pointer> infile = IOUtil::Load( inFileName );
        DiffusionImage<short>::Pointer dwi = dynamic_cast<DiffusionImage<short>*>(infile.at(0).GetPointer());

        typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, float > TensorReconstructionImageFilterType;
        TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New();
        filter->SetGradientImage( dwi->GetDirections(), dwi->GetVectorImage() );
        filter->SetBValue(dwi->GetReferenceBValue());
        filter->SetThreshold(threshold);
        filter->Update();

        // Save tensor image
        itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
        io->SetFileType( itk::ImageIOBase::Binary );
        io->UseCompressionOn();

        itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::Pointer writer = itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::New();
        writer->SetInput(filter->GetOutput());
        writer->SetFileName(outfilename);
        writer->SetImageIO(io);
        writer->UseCompressionOn();
        writer->Update();
    }
    catch ( itk::ExceptionObject &err)
    {
        std::cout << "Exception: " << err;
    }
    catch ( std::exception err)
    {
        std::cout << "Exception: " << err.what();
    }
    catch ( ... )
    {
        std::cout << "Exception!";
    }
    return EXIT_SUCCESS;

}
<|endoftext|>


<commit_before>#ifndef MITK_MinMaxImageFilterWithIndex_HXX
#define MITK_MinMaxImageFilterWithIndex_HXX

#include <mitkMinMaxImageFilterWithIndex.h>
#include <limits>

namespace itk
{

template< typename TInputImage >
void MinMaxImageFilterWithIndex< TInputImage >::AllocateOutputs()
{
  // Pass the input through as the output
  typename TInputImage::Pointer image =
    const_cast< TInputImage * >( this->GetInput() );

  this->GraftOutput(image);

  // Nothing that needs to be allocated for the remaining outputs
}

template< typename TInputImage >
void MinMaxImageFilterWithIndex< TInputImage >::ThreadedGenerateData(const RegionType &
                                      outputRegionForThread,
                                      ThreadIdType threadId)
{
  const SizeValueType size0 = outputRegionForThread.GetSize(0);
  if( size0 == 0)
    {
    return;
    }
  PixelType value;

  PixelType threadMin, threadMax;
  IndexType threadMinIndex, threadMaxIndex;

  threadMin = std::numeric_limits<PixelType>::max();
  threadMax = std::numeric_limits<PixelType>::min();

  ImageRegionConstIteratorWithIndex< TInputImage > it (this->GetInput(), outputRegionForThread);

  // do the work
  while ( !it.IsAtEnd() )
  {
    value = it.Get();
    if (value < threadMin)
    {
      threadMin = value;
      threadMinIndex = it.GetIndex();
    }
    if (value > threadMax)
    {
      threadMax = value;
      threadMaxIndex = it.GetIndex();
    }
    ++it;
  }

  m_ThreadMax[threadId] = threadMax;
  m_ThreadMin[threadId] = threadMin;
  m_ThreadMaxIndex[threadId] = threadMaxIndex;
  m_ThreadMinIndex[threadId] = threadMinIndex;
}

template< typename TInputImage >
void MinMaxImageFilterWithIndex< TInputImage >::BeforeThreadedGenerateData()
{
  ThreadIdType numberOfThreads = this->GetNumberOfThreads();
  m_ThreadMin.resize(numberOfThreads);
  m_ThreadMax.resize(numberOfThreads);
  m_ThreadMinIndex.resize(numberOfThreads);
  m_ThreadMaxIndex.resize(numberOfThreads);

  for (unsigned int i =0; i < numberOfThreads; i++)
  {
    m_ThreadMin[i] = std::numeric_limits<PixelType>::max();
    m_ThreadMax[i] = std::numeric_limits<PixelType>::min();
  }

  m_Min = std::numeric_limits<PixelType>::max();
  m_Max = std::numeric_limits<PixelType>::min();

}

template< typename TInputImage >
void MinMaxImageFilterWithIndex< TInputImage >::AfterThreadedGenerateData()
{
  ThreadIdType numberOfThreads = this->GetNumberOfThreads();

  for (ThreadIdType i = 0; i < numberOfThreads; i++)
  {
    if (m_ThreadMin[i] < m_Min)
    {
      m_Min = m_ThreadMin[i];
      m_MinIndex = m_ThreadMinIndex[i];
    }
    if (m_ThreadMax[i] > m_Max)
    {
      m_Max = m_ThreadMax[i];
      m_MaxIndex = m_ThreadMaxIndex[i];
    }
  }
}
}
#endif
<commit_msg>initialized variable<commit_after>#ifndef MITK_MinMaxImageFilterWithIndex_HXX
#define MITK_MinMaxImageFilterWithIndex_HXX

#include <mitkMinMaxImageFilterWithIndex.h>
#include <limits>

namespace itk
{

template< typename TInputImage >
void MinMaxImageFilterWithIndex< TInputImage >::AllocateOutputs()
{
  // Pass the input through as the output
  typename TInputImage::Pointer image =
    const_cast< TInputImage * >( this->GetInput() );

  this->GraftOutput(image);

  // Nothing that needs to be allocated for the remaining outputs
}

template< typename TInputImage >
void MinMaxImageFilterWithIndex< TInputImage >::ThreadedGenerateData(const RegionType &
                                      outputRegionForThread,
                                      ThreadIdType threadId)
{
  const SizeValueType size0 = outputRegionForThread.GetSize(0);
  if( size0 == 0)
    {
    return;
    }
  PixelType value;

  PixelType threadMin, threadMax;
  IndexType threadMinIndex;
  IndexType threadMaxIndex;
  threadMinIndex.Fill(0);
  threadMaxIndex.Fill(0);

  threadMin = std::numeric_limits<PixelType>::max();
  threadMax = std::numeric_limits<PixelType>::min();

  ImageRegionConstIteratorWithIndex< TInputImage > it (this->GetInput(), outputRegionForThread);

  // do the work
  while ( !it.IsAtEnd() )
  {
    value = it.Get();
    if (value < threadMin)
    {
      threadMin = value;
      threadMinIndex = it.GetIndex();
    }
    if (value > threadMax)
    {
      threadMax = value;
      threadMaxIndex = it.GetIndex();
    }
    ++it;
  }

  m_ThreadMax[threadId] = threadMax;
  m_ThreadMin[threadId] = threadMin;
  m_ThreadMaxIndex[threadId] = threadMaxIndex;
  m_ThreadMinIndex[threadId] = threadMinIndex;
}

template< typename TInputImage >
void MinMaxImageFilterWithIndex< TInputImage >::BeforeThreadedGenerateData()
{
  ThreadIdType numberOfThreads = this->GetNumberOfThreads();
  m_ThreadMin.resize(numberOfThreads);
  m_ThreadMax.resize(numberOfThreads);
  m_ThreadMinIndex.resize(numberOfThreads);
  m_ThreadMaxIndex.resize(numberOfThreads);

  for (unsigned int i =0; i < numberOfThreads; i++)
  {
    m_ThreadMin[i] = std::numeric_limits<PixelType>::max();
    m_ThreadMax[i] = std::numeric_limits<PixelType>::min();
  }

  m_Min = std::numeric_limits<PixelType>::max();
  m_Max = std::numeric_limits<PixelType>::min();

}

template< typename TInputImage >
void MinMaxImageFilterWithIndex< TInputImage >::AfterThreadedGenerateData()
{
  ThreadIdType numberOfThreads = this->GetNumberOfThreads();

  for (ThreadIdType i = 0; i < numberOfThreads; i++)
  {
    if (m_ThreadMin[i] < m_Min)
    {
      m_Min = m_ThreadMin[i];
      m_MinIndex = m_ThreadMinIndex[i];
    }
    if (m_ThreadMax[i] > m_Max)
    {
      m_Max = m_ThreadMax[i];
      m_MaxIndex = m_ThreadMaxIndex[i];
    }
  }
}
}
#endif
<|endoftext|>


<commit_before>/**
 *  @copyright Copyright 2018 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  @file JPetOptionsGeneratorTools.cpp
 */

#include "./JPetCommonTools/JPetCommonTools.h"
#include "./JPetOptionsGeneratorTools.h"

using namespace jpet_options_tools;

namespace jpet_options_generator_tools
{
std::map<std::string, boost::any> kDefaultOptions = {
  {"inputFile_std::string", std::string("")},
  {"inputFileType_std::string", std::string("")},
  {"scopeConfigFile_std::string", std::string("")},
  {"scopeInputDirectory_std::string", std::string("")},
  {"outputPath_std::string", std::string("")},
  {"outputFile_std::string", std::string("test.root")},
  {"outputFileType_std::string", std::string("root")},
  {"firstEvent_int", -1},
  {"lastEvent_int", -1},
  {"progressBar_bool", false},
  {"runId_int", -1},
  {"unpackerConfigFile_std::string", std::string("conf_trb3.xml")},
  {"unpackerCalibFile_std::string", std::string("")}
};

std::map<std::string, std::string> kOptCmdLineNameToExtendedName = {
  {"type", "type_std::string"},
  {"file", "file_std::vector<std::string>"},
  {"outputPath", "outputPath_std::string"},
  {"range", "range_std::vector<int>"},
  {"unpackerConfigFile", "unpackerConfigFile_std::string"},
  {"unpackerCalibFile", "unpackerCalibFile_std::string"},
  {"runId", "runId_int"},
  {"progressBar", "progressBar_bool"},
  {"localDB", "localDB_std::string"},
  {"localDBCreate", "localDBCreate_std::string"},
  {"userCfg", "userCfg_std::string"}
};

std::map<std::string, boost::any> transformOptions(
  const TransformersMap& transformationMap,
  const std::map<std::string,
  boost::any>& oldOptionsMap)
{
  std::map<std::string, boost::any> newOptionsMap(oldOptionsMap);
  for (auto& transformGroup : transformationMap) {
    auto key = transformGroup.first;
    if (newOptionsMap.find(key) != newOptionsMap.end()) {
      for (auto& transformFunc : transformGroup.second) {
        auto newOpt = transformFunc(newOptionsMap.at(key));
        newOptionsMap[newOpt.first] = newOpt.second;
      }
    }
  }
  return newOptionsMap;
}

/**
 * Method returns a set of Options based on the input set and the control settings
 * If no special options are present in the control settings, the inOptions
 * are just passed further. Currenty if controlSettings contain option:
 * 1. "resetEventRange_bool"->true then, the generated inOptions will contain
 * the first and the last event values set to -1, which means
 * 'process all available events'.
 * 2. option 'outputFileType_std::string'->value set, then the generated
 * inOptions will contain inputFileType_str::string set to value
 * 3.'outputPath_std::string'-> path then the generated inOptions will contain
 * 'inputFile_std::string' ->path/nameOfFile
 */
OptsStrAny generateOptionsForTask(const OptsStrAny& inOptions, const OptsStrAny& controlSettings)
{
  auto newOpts(inOptions);
  if (isOptionSet(controlSettings, "resetEventRange_bool")) {
    if (getOptionAsBool(controlSettings, "resetEventRange_bool")) {
      newOpts = resetEventRange(newOpts);
    }
  }
  if (isOptionSet(controlSettings, "outputFileType_std::string")) {
    newOpts["inputFileType_std::string"] = getOptionAsString(controlSettings,
      "outputFileType_std::string");
  }
  if (isOptionSet(controlSettings, "outputFile_std::string")) {
    newOpts["inputFile_std::string"] = getOptionAsString(controlSettings,
      "outputFile_std::string");
  }
  if (isOptionSet(controlSettings, "outputPath_std::string")) {
    auto outPath  = std::string(getOutputPath(controlSettings));
    if (!outPath.empty()) {
      newOpts.at("inputFile_std::string") = outPath
        + JPetCommonTools::extractFileNameFromFullPath(getInputFile(newOpts));
    }
  }
  return newOpts;
}

std::map<std::string, boost::any> transformToStrAnyMap(const po::variables_map& inMap)
{
  std::map<std::string, boost::any> outMap;
  for (auto& option : inMap) {
    outMap[option.first] = option.second.value();
  }
  return outMap;
}

std::map<std::string, boost::any>  addMissingDefaultOptions(
  const std::map<std::string, boost::any>& oldOptions)
{
  std::map<std::string, boost::any> newOptions(oldOptions);
  auto defaultOptions = getDefaultOptions();
  newOptions.insert(defaultOptions.begin(), defaultOptions.end());
  return newOptions;
}

/**
 * The keys usedin this method correspond to the keys defined in the CmdArgMap
 */
std::map<std::string, std::vector<Transformer> > generateTransformationMap(OptsStrAny& options)
{
  std::map<std::string, std::vector<Transformer> > transformationMap;
  transformationMap["outputPath_std::string"].push_back(appendSlash);
  transformationMap["range_std::vector<int>"].push_back(generateLowerEventBound);
  transformationMap["range_std::vector<int>"].push_back(generateHigherEventBound);
  addTransformFunction(transformationMap, "type_std::string",
    jpet_options_tools::generateSetFileTypeTransformator(options));
  return transformationMap;
}

OptsStrAny resetEventRange(const OptsStrAny& srcOpts)
{
  OptsStrAny opts(srcOpts);
  opts.at("firstEvent_int") = -1;
  opts.at("lastEvent_int") = -1;
  return opts;
}

/**
 * Methods add type suffixes to the elements of the map according to the key name.
 */
OptsStrAny addTypeSuffixes(const std::map<std::string, boost::any>& oldMap)
{
  std::map<std::string, boost::any> newMap(oldMap);
  for (auto& elem : kOptCmdLineNameToExtendedName) {
    auto oldKey = elem.first;
    auto newKey = elem.second;
    const auto it = newMap.find(oldKey);
    if (it != newMap.end()) {
      newMap[newKey] = it->second;
      newMap.erase(it);
    }
  }
  return newMap;
}

std::map<std::string, boost::any> getDefaultOptions()
{
  return kDefaultOptions;
}

void addTransformFunction(TransformersMap& map,
  const std::string& name,
  Transformer transformFunction)
{
  map[name].push_back(transformFunction);
}

/**
 * Adding an option to already existing ones. If the key already exists the element
 * will not be updated.
 */
void addNewOptionsFromCfgFile(const std::string& cfgFile, std::map<std::string, boost::any>& options)
{
  std::map<std::string, boost::any> optionsFromJson = jpet_options_tools::createOptionsFromConfigFile(cfgFile);
  options.insert(optionsFromJson.begin(), optionsFromJson.end());
}

void setOutputFileType(OptsStrAny& options, const std::string& fileType)
{
  options["outputFileType_std::string"] = fileType;
}

/**
 * Please note that those methods change the input options. If the key does not
 * exist, it will be created, if it exists the value will be overwritten
 */
void setResetEventRangeOption(OptsStrAny& options, bool isReset)
{
  options["resetEventRange_bool"] = isReset;
}

void setOutputFile(OptsStrAny& options, const std::string& file)
{
  options["outputFile_std::string"] = file;
}

void setOutputPath(OptsStrAny& options, const std::string& path)
{
  options["outputPath_std::string"] = path;
}

}
<commit_msg>Fix coping refereces to map<commit_after>/**
 *  @copyright Copyright 2018 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  @file JPetOptionsGeneratorTools.cpp
 */

#include "./JPetCommonTools/JPetCommonTools.h"
#include "./JPetOptionsGeneratorTools.h"

using namespace jpet_options_tools;

namespace jpet_options_generator_tools
{
std::map<std::string, boost::any> kDefaultOptions = {
  {"inputFile_std::string", std::string("")},
  {"inputFileType_std::string", std::string("")},
  {"scopeConfigFile_std::string", std::string("")},
  {"scopeInputDirectory_std::string", std::string("")},
  {"outputPath_std::string", std::string("")},
  {"outputFile_std::string", std::string("test.root")},
  {"outputFileType_std::string", std::string("root")},
  {"firstEvent_int", -1},
  {"lastEvent_int", -1},
  {"progressBar_bool", false},
  {"runId_int", -1},
  {"unpackerConfigFile_std::string", std::string("conf_trb3.xml")},
  {"unpackerCalibFile_std::string", std::string("")}
};

std::map<std::string, std::string> kOptCmdLineNameToExtendedName = {
  {"type", "type_std::string"},
  {"file", "file_std::vector<std::string>"},
  {"outputPath", "outputPath_std::string"},
  {"range", "range_std::vector<int>"},
  {"unpackerConfigFile", "unpackerConfigFile_std::string"},
  {"unpackerCalibFile", "unpackerCalibFile_std::string"},
  {"runId", "runId_int"},
  {"progressBar", "progressBar_bool"},
  {"localDB", "localDB_std::string"},
  {"localDBCreate", "localDBCreate_std::string"},
  {"userCfg", "userCfg_std::string"}
};

std::map<std::string, boost::any> transformOptions(
  const TransformersMap& transformationMap,
  const std::map<std::string,
  boost::any>& oldOptionsMap)
{
  std::map<std::string, boost::any> newOptionsMap(oldOptionsMap);
  for (auto& transformGroup : transformationMap) {
    auto key = transformGroup.first;
    if (newOptionsMap.find(key) != newOptionsMap.end()) {
      for (auto& transformFunc : transformGroup.second) {
        auto newOpt = transformFunc(newOptionsMap.at(key));
        newOptionsMap[newOpt.first] = newOpt.second;
      }
    }
  }
  return newOptionsMap;
}

/**
 * Method returns a set of Options based on the input set and the control settings
 * If no special options are present in the control settings, the inOptions
 * are just passed further. Currenty if controlSettings contain option:
 * 1. "resetEventRange_bool"->true then, the generated inOptions will contain
 * the first and the last event values set to -1, which means
 * 'process all available events'.
 * 2. option 'outputFileType_std::string'->value set, then the generated
 * inOptions will contain inputFileType_str::string set to value
 * 3.'outputPath_std::string'-> path then the generated inOptions will contain
 * 'inputFile_std::string' ->path/nameOfFile
 */
OptsStrAny generateOptionsForTask(const OptsStrAny& inOptions, const OptsStrAny& controlSettings)
{
  auto newOpts(inOptions);
  if (isOptionSet(controlSettings, "resetEventRange_bool")) {
    if (getOptionAsBool(controlSettings, "resetEventRange_bool")) {
      newOpts = resetEventRange(newOpts);
    }
  }
  if (isOptionSet(controlSettings, "outputFileType_std::string")) {
    newOpts["inputFileType_std::string"] = getOptionAsString(controlSettings,
                                           "outputFileType_std::string");
  }
  if (isOptionSet(controlSettings, "outputFile_std::string")) {
    newOpts["inputFile_std::string"] = getOptionAsString(controlSettings,
                                       "outputFile_std::string");
  }
  if (isOptionSet(controlSettings, "outputPath_std::string")) {
    auto outPath  = std::string(getOutputPath(controlSettings));
    if (!outPath.empty()) {
      newOpts.at("inputFile_std::string") = outPath
                                            + JPetCommonTools::extractFileNameFromFullPath(getInputFile(newOpts));
    }
  }
  return newOpts;
}

std::map<std::string, boost::any> transformToStrAnyMap(const po::variables_map& inMap)
{
  std::map<std::string, boost::any> outMap;
  for (auto& option : inMap) {
    outMap[option.first] = option.second.value();
  }
  return outMap;
}

std::map<std::string, boost::any>  addMissingDefaultOptions(
  const std::map<std::string, boost::any>& oldOptions)
{
  std::map<std::string, boost::any> newOptions(oldOptions);
  auto defaultOptions = getDefaultOptions();
  newOptions.insert(defaultOptions.begin(), defaultOptions.end());
  return newOptions;
}

/**
 * The keys usedin this method correspond to the keys defined in the CmdArgMap
 */
std::map<std::string, std::vector<Transformer> > generateTransformationMap(OptsStrAny& options)
{
  std::map<std::string, std::vector<Transformer> > transformationMap;
  transformationMap["outputPath_std::string"].push_back(appendSlash);
  transformationMap["range_std::vector<int>"].push_back(generateLowerEventBound);
  transformationMap["range_std::vector<int>"].push_back(generateHigherEventBound);
  addTransformFunction(transformationMap, "type_std::string",
                       jpet_options_tools::generateSetFileTypeTransformator(options));
  return transformationMap;
}

OptsStrAny resetEventRange(const OptsStrAny& srcOpts)
{
  OptsStrAny opts(srcOpts);
  opts.at("firstEvent_int") = -1;
  opts.at("lastEvent_int") = -1;
  return opts;
}

/**
 * Methods add type suffixes to the elements of the map according to the key name.
 */
OptsStrAny addTypeSuffixes(const std::map<std::string, boost::any>& oldMap)
{
  std::map<std::string, boost::any> newMap(oldMap);
  for (auto& elem : kOptCmdLineNameToExtendedName) {
    auto oldKey = elem.first;
    auto newKey = elem.second;
    const auto it = newMap.find(oldKey);
    if (it != newMap.end()) {
      newMap[newKey] = it->second;
      newMap.erase(it);
    }
  }
  return newMap;
}

std::map<std::string, boost::any> getDefaultOptions()
{
  return kDefaultOptions;
}

void addTransformFunction(TransformersMap& map,
                          const std::string& name,
                          Transformer transformFunction)
{
  map[name].push_back(transformFunction);
}

/**
 * Adding an option to already existing ones. If the key already exists the element
 * will not be updated.
 */
void addNewOptionsFromCfgFile(const std::string& cfgFile, std::map<std::string, boost::any>& options)
{
  std::map<std::string, boost::any> optionsFromJson = jpet_options_tools::createOptionsFromConfigFile(cfgFile);
  options.insert(optionsFromJson.begin(), optionsFromJson.end());
}

void setOutputFileType(OptsStrAny& options, const std::string fileType)
{
  options["outputFileType_std::string"] = fileType;
}

/**
 * Please note that those methods change the input options. If the key does not
 * exist, it will be created, if it exists the value will be overwritten
 */
void setResetEventRangeOption(OptsStrAny& options, bool isReset)
{
  options["resetEventRange_bool"] = isReset;
}

void setOutputFile(OptsStrAny& options, const std::string file)
{
  options["outputFile_std::string"] = file;
}

void setOutputPath(OptsStrAny& options, const std::string path)
{
  options["outputPath_std::string"] = path;
}

}
<|endoftext|>


<commit_before>AliAnalysisTaskSE * AddTaskPhysPHOSQA()
{
  gROOT->LoadMacro("$ALICE_PHYSICS/PWGGA/PHOSTasks/CaloCellQA/macros/AddTaskCaloCellsPhysQA.C");

  AliAnalysisTaskCaloCellsPhysQA *taskPHOSCellQA = AddTaskCaloCellsPhysQA(5, 1, "CaloCellsQA.root","PHOSCellsQA");
  taskPHOSCellQA->GetCaloCellsQA()->SetClusterEnergyCuts(0.3,0.3,1.0);

  AliCaloCellsPhysQA * qa = (AliCaloCellsPhysQA *) taskPHOSCellQA->GetCaloCellsQA();
  qa->SetPhysicsClusterCut(0.3, 3, 12.5e-9);

  return taskPHOSCellQA;
}<commit_msg>Fix path to the AddTaskPhysPHOSQA<commit_after>AliAnalysisTaskSE * AddTaskPhysPHOSQA()
{
  gROOT->LoadMacro("$ALICE_PHYSICS/PWGGA/PHOSTasks/CaloCellQA/phys/macros/AddTaskCaloCellsPhysQA.C");

  AliAnalysisTaskCaloCellsPhysQA *taskPHOSCellQA = AddTaskCaloCellsPhysQA(5, 1, "CaloCellsQA.root","PHOSCellsQA");
  taskPHOSCellQA->GetCaloCellsQA()->SetClusterEnergyCuts(0.3,0.3,1.0);

  AliCaloCellsPhysQA * qa = (AliCaloCellsPhysQA *) taskPHOSCellQA->GetCaloCellsQA();
  qa->SetPhysicsClusterCut(0.3, 3, 12.5e-9);

  return taskPHOSCellQA;
}
<|endoftext|>


<commit_before><commit_msg>Complete a task related to the answer of the second part of question 3.7<commit_after><|endoftext|>