<commit_before>// Copyright 2019 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "iree/compiler/Dialect/Flow/Transforms/Passes.h"

#include <memory>

#include "iree/compiler/Dialect/Shape/Transforms/Passes.h"
#include "mlir/Dialect/Linalg/Passes.h"
#include "mlir/Dialect/MemRef/Transforms/Passes.h"
#include "mlir/Pass/PassOptions.h"
#include "mlir/Pass/PassRegistry.h"
#include "mlir/Transforms/Passes.h"

// TODO(ravishankarm): Change to a pipeline option.
static llvm::cl::opt<bool> clExportBenchmarkFuncs(
    "iree-flow-export-benchmark-funcs",
    llvm::cl::desc(
        "Exports one function per original module entry point and "
        "unique flow.executable that dispatches with dummy arguments."),
    llvm::cl::init(false));

// TODO(ravishankarm): Change to a pipeline option.
static llvm::cl::opt<bool> clTraceDispatchTensors(
    "iree-flow-trace-dispatch-tensors2",
    llvm::cl::desc(
        "Trace runtime input/output tensors for each dispatch function."),
    llvm::cl::init(false));

static llvm::cl::opt<bool> clDemoteF32ToF16(
    "iree-flow-demote-f32-to-f16",
    llvm::cl::desc("Convert all f32 ops and values into f16 counterparts "
                   "unconditionally before main flow conversions"),
    llvm::cl::init(false));

static llvm::cl::opt<bool> clEnable1x1ConvToMatmul(
    "iree-flow-enable-1x1-conv-to-matmul",
    llvm::cl::desc("Enable converting 1x1 linalg convolution ops to linalg "
                   "matmul ops pass."),
    llvm::cl::init(true));

static llvm::cl::opt<bool> clEnableConvToImg2Col(
    "iree-flow-enable-conv-img2col-transform",
    llvm::cl::desc("Enable converting convolution ops to img2col form."),
    llvm::cl::init(false));

static llvm::cl::opt<bool> clEnablePaddingLinalgOps(
    "iree-flow-enable-padding-linalg-ops",
    llvm::cl::desc("Enable padding linalg ops to an integer multiple of "
                   "flow-padding-size"),
    llvm::cl::init(false));

static llvm::cl::opt<int> clLinalgOpsPaddingSize(
    "iree-flow-linalg-ops-padding-size",
    llvm::cl::desc("Enable padding linalg ops to an integer multiple of "
                   "flow-padding-size"),
    llvm::cl::init(4));

namespace mlir {
namespace iree_compiler {
namespace IREE {
namespace Flow {

void buildFlowTransformPassPipeline(OpPassManager &passManager) {
  // Simplify flow.variable accesses early on; this can help with dispatch
  // region formation as redundant store-loads are removed.
  passManager.addNestedPass<FuncOp>(
      IREE::Flow::createSimplifyVariableAccessesPass());

  // Perform cleanup after variable simplification as more canonicalizers may be
  // able to kick in.
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());
  passManager.addNestedPass<FuncOp>(mlir::createCSEPass());

  // Replaces variables with !shapex.ranked_shape types with individual
  // variables for each dimension. This allows for constant dimensions to be
  // DCE'd in following passes.
  passManager.addPass(IREE::Flow::createExpandVariableDynamicDimsPass());

  // Materialize dynamic shapes in the IR, also expanding function signatures
  // such that:
  //   - Dynamic ranked tensors: (tensor<?x?xf32>) expands to
  //     (tensor<?x?xf32>, ranked_shape<[?,?]>), and ultimately expands to
  //     (tensor<?x?xf32>, i32, i32)
  //   - Unranked tensors: **unsupported**
  // The generated ABI wrappers assume such an expansion and will generate code
  // to produce it from the original reflection metadata captured in the
  // previous pass.
  passManager.addNestedPass<FuncOp>(
      Shape::createExpandFunctionDynamicDimsPass());

  // Special case peephole optimizations.
  if (clEnable1x1ConvToMatmul) {
    passManager.addNestedPass<FuncOp>(createConvertConv2D1x1ToMatmulPass());
  }
  if (clEnableConvToImg2Col) {
    passManager.addNestedPass<FuncOp>(createConvertConv2DToImg2ColPass());
  }
  // Pad linalg op
  if (clEnablePaddingLinalgOps) {
    passManager.addNestedPass<FuncOp>(
        createPadLinalgOpsToIntegerMultiplePass(clLinalgOpsPaddingSize));
  }
  passManager.addPass(createPadTensorToSubTensorInsertPass());

  // Elementwise, fusion, tiling and distribution.
  passManager.addNestedPass<FuncOp>(
      mlir::createConvertElementwiseToLinalgPass());
  passManager.addNestedPass<FuncOp>(mlir::createLinalgFoldUnitExtentDimsPass());
  passManager.addNestedPass<FuncOp>(createInterchangeGenericOpsPass());
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());
  passManager.addNestedPass<FuncOp>(createFusionOfTensorOpsPass());
  passManager.addNestedPass<FuncOp>(mlir::createCSEPass());
  passManager.addPass(memref::createResolveShapedTypeResultDimsPass());
  passManager.addNestedPass<FuncOp>(
      IREE::Flow::createConvertToFlowTensorOpsPass(
          /*runBeforeDispatchRegionFormation=*/true));
  passManager.addNestedPass<FuncOp>(
      IREE::Flow::createDispatchLinalgOnTensorsPass());
  passManager.addPass(memref::createResolveShapedTypeResultDimsPass());
  passManager.addNestedPass<FuncOp>(
      IREE::Flow::createConvertToFlowTensorOpsPass(
          /*runBeforeDispatchRegionFormation=*/false));
  // NOTE: required because the current dispatch-linalg-on-tensors pass
  // creates a lot of dead IR that needs to be cleaned up.
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());

  // Outline the dispatch regions into their own functions wrapped in
  // executables.
  passManager.addPass(IREE::Flow::createOutlineDispatchRegionsPass());

  // Cleanup identity ops that clutter up the IR and canonicalize.
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());

  // Deduplicate executables created from dispatch regions.
  // Note: this only deduplicates equivalent executables. We could in addition
  // generalize executables to prune further (e.g. by promoting a dimension to
  // an argument if two executables differ only in that one dimension).
  passManager.addPass(IREE::Flow::createDeduplicateExecutablesPass());

  // TODO: Prune and rename this pass. This runs after sending everything
  // possible to the device and then legalizes any remaining h<->d loads,
  // typically coming from top level flow control.
  passManager.addNestedPass<FuncOp>(IREE::Flow::createPromoteTensorLoadsPass());

  // Create one function per remaining flow.executable that can be used with
  // iree-benchmark-module to benchmark each dispatch individually, as well as
  // exporting all original model entry points.
  if (clExportBenchmarkFuncs) {
    passManager.addPass(IREE::Flow::createExportBenchmarkFuncsPass());
  }

  // Inject tracing that logs both input and output tensors from all dispatches.
  // We do this after deduping so that the executable names match later stages.
  if (clTraceDispatchTensors) {
    passManager.addNestedPass<FuncOp>(
        IREE::Flow::createInjectDispatchTracingPass());
  }

  //----------------------------------------------------------------------------
  // Stream formation.
  // Pre-conditions:
  //   - Full formation of dispatch regions
  //----------------------------------------------------------------------------

  // Form streams.
  // Cleanup the IR before we try to form streams.
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());
  passManager.addNestedPass<FuncOp>(mlir::createCSEPass());

  // Reorder blocks to increase the grouping of streamable ops.
  passManager.addNestedPass<FuncOp>(
      IREE::Flow::createHoistUnstreamableOpsPass());

  // The hoisting pass does some reordering. Canonicalize to avoid unnecessary
  // arbitrary ordering.
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());
  passManager.addNestedPass<FuncOp>(mlir::createCSEPass());

  // Clone constants that escape basic blocks until we have better analysis.
  passManager.addNestedPass<FuncOp>(
      IREE::Flow::createInsertConstantClonesPass());

  // Group streamable ops into streams.
  passManager.addNestedPass<FuncOp>(IREE::Flow::createFormStreamsPass());

  // Prior to leaving the pipeline we need to clean things up for following
  // layers. These transforms may be undone by subsequent CSE/folding passes.
  passManager.addPass(IREE::Flow::createOutlineLargeConstantsPass());

  // Forming streams involves a fair amount of subgraph stitching, which can
  // cause duplication. Run CSE to collapse.
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());
  passManager.addNestedPass<FuncOp>(mlir::createCSEPass());

  // Symbol DCE any remaining variables/functions that are now no longer
  // required.
  passManager.addPass(mlir::createSymbolDCEPass());
}

void registerFlowTransformPassPipeline() {
  PassPipelineRegistration<> transformPassPipeline(
      "iree-flow-transformation-pipeline",
      "Runs the full IREE flow dialect transformation pipeline",
      [](OpPassManager &passManager) {
        buildFlowTransformPassPipeline(passManager);
      });
}

namespace {
#define GEN_PASS_REGISTRATION
#include "iree/compiler/Dialect/Flow/Transforms/Passes.h.inc"  // IWYU pragma: export
}  // namespace

void registerFlowPasses() {
  // Generated.
  registerPasses();

  // Pipelines.
  registerFlowTransformPassPipeline();
}

}  // namespace Flow
}  // namespace IREE
}  // namespace iree_compiler
}  // namespace mlir
<commit_msg>Add linalg detensorizing behind a flag. (#6626)<commit_after>// Copyright 2019 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "iree/compiler/Dialect/Flow/Transforms/Passes.h"

#include <memory>

#include "iree/compiler/Dialect/Shape/Transforms/Passes.h"
#include "mlir/Dialect/Linalg/Passes.h"
#include "mlir/Dialect/MemRef/Transforms/Passes.h"
#include "mlir/Pass/PassOptions.h"
#include "mlir/Pass/PassRegistry.h"
#include "mlir/Transforms/Passes.h"

// TODO(ravishankarm): Change to a pipeline option.
static llvm::cl::opt<bool> clExportBenchmarkFuncs(
    "iree-flow-export-benchmark-funcs",
    llvm::cl::desc(
        "Exports one function per original module entry point and "
        "unique flow.executable that dispatches with dummy arguments."),
    llvm::cl::init(false));

// TODO(ravishankarm): Change to a pipeline option.
static llvm::cl::opt<bool> clTraceDispatchTensors(
    "iree-flow-trace-dispatch-tensors2",
    llvm::cl::desc(
        "Trace runtime input/output tensors for each dispatch function."),
    llvm::cl::init(false));

static llvm::cl::opt<bool> clDemoteF32ToF16(
    "iree-flow-demote-f32-to-f16",
    llvm::cl::desc("Convert all f32 ops and values into f16 counterparts "
                   "unconditionally before main flow conversions"),
    llvm::cl::init(false));

static llvm::cl::opt<bool> clEnable1x1ConvToMatmul(
    "iree-flow-enable-1x1-conv-to-matmul",
    llvm::cl::desc("Enable converting 1x1 linalg convolution ops to linalg "
                   "matmul ops pass."),
    llvm::cl::init(true));

static llvm::cl::opt<bool> clEnableConvToImg2Col(
    "iree-flow-enable-conv-img2col-transform",
    llvm::cl::desc("Enable converting convolution ops to img2col form."),
    llvm::cl::init(false));

static llvm::cl::opt<bool> clEnablePaddingLinalgOps(
    "iree-flow-enable-padding-linalg-ops",
    llvm::cl::desc("Enable padding linalg ops to an integer multiple of "
                   "flow-padding-size"),
    llvm::cl::init(false));

static llvm::cl::opt<int> clLinalgOpsPaddingSize(
    "iree-flow-linalg-ops-padding-size",
    llvm::cl::desc("Enable padding linalg ops to an integer multiple of "
                   "flow-padding-size"),
    llvm::cl::init(4));

// TODO(#1159): enable by default or remove this option once it works on
//              a broader set of programs
static llvm::cl::opt<bool> clEnableLinalgDetensorize(
    "iree-flow-enable-linalg-detensorize",
    llvm::cl::desc("Enable detensorizing linalg ops to operate on primitives"),
    llvm::cl::init(false));

namespace mlir {
namespace iree_compiler {
namespace IREE {
namespace Flow {

void buildFlowTransformPassPipeline(OpPassManager &passManager) {
  // Simplify flow.variable accesses early on; this can help with dispatch
  // region formation as redundant store-loads are removed.
  passManager.addNestedPass<FuncOp>(
      IREE::Flow::createSimplifyVariableAccessesPass());

  // Perform cleanup after variable simplification as more canonicalizers may be
  // able to kick in.
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());
  passManager.addNestedPass<FuncOp>(mlir::createCSEPass());

  // Replaces variables with !shapex.ranked_shape types with individual
  // variables for each dimension. This allows for constant dimensions to be
  // DCE'd in following passes.
  passManager.addPass(IREE::Flow::createExpandVariableDynamicDimsPass());

  // Materialize dynamic shapes in the IR, also expanding function signatures
  // such that:
  //   - Dynamic ranked tensors: (tensor<?x?xf32>) expands to
  //     (tensor<?x?xf32>, ranked_shape<[?,?]>), and ultimately expands to
  //     (tensor<?x?xf32>, i32, i32)
  //   - Unranked tensors: **unsupported**
  // The generated ABI wrappers assume such an expansion and will generate code
  // to produce it from the original reflection metadata captured in the
  // previous pass.
  passManager.addNestedPass<FuncOp>(
      Shape::createExpandFunctionDynamicDimsPass());

  // Special case peephole optimizations.
  if (clEnable1x1ConvToMatmul) {
    passManager.addNestedPass<FuncOp>(createConvertConv2D1x1ToMatmulPass());
  }
  if (clEnableConvToImg2Col) {
    passManager.addNestedPass<FuncOp>(createConvertConv2DToImg2ColPass());
  }
  // Pad linalg op
  if (clEnablePaddingLinalgOps) {
    passManager.addNestedPass<FuncOp>(
        createPadLinalgOpsToIntegerMultiplePass(clLinalgOpsPaddingSize));
  }
  passManager.addPass(createPadTensorToSubTensorInsertPass());

  // Elementwise, fusion, tiling and distribution.
  passManager.addNestedPass<FuncOp>(
      mlir::createConvertElementwiseToLinalgPass());
  passManager.addNestedPass<FuncOp>(mlir::createLinalgFoldUnitExtentDimsPass());
  passManager.addNestedPass<FuncOp>(createInterchangeGenericOpsPass());
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());
  passManager.addNestedPass<FuncOp>(createFusionOfTensorOpsPass());
  passManager.addNestedPass<FuncOp>(mlir::createCSEPass());
  if (clEnableLinalgDetensorize) {
    passManager.addNestedPass<FuncOp>(mlir::createLinalgDetensorizePass());
  }
  passManager.addPass(memref::createResolveShapedTypeResultDimsPass());
  passManager.addNestedPass<FuncOp>(
      IREE::Flow::createConvertToFlowTensorOpsPass(
          /*runBeforeDispatchRegionFormation=*/true));
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());
  passManager.addNestedPass<FuncOp>(
      IREE::Flow::createDispatchLinalgOnTensorsPass());
  passManager.addPass(memref::createResolveShapedTypeResultDimsPass());
  passManager.addNestedPass<FuncOp>(
      IREE::Flow::createConvertToFlowTensorOpsPass(
          /*runBeforeDispatchRegionFormation=*/false));
  // NOTE: required because the current dispatch-linalg-on-tensors pass
  // creates a lot of dead IR that needs to be cleaned up.
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());

  // Outline the dispatch regions into their own functions wrapped in
  // executables.
  passManager.addPass(IREE::Flow::createOutlineDispatchRegionsPass());

  // Cleanup identity ops that clutter up the IR and canonicalize.
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());

  // Deduplicate executables created from dispatch regions.
  // Note: this only deduplicates equivalent executables. We could in addition
  // generalize executables to prune further (e.g. by promoting a dimension to
  // an argument if two executables differ only in that one dimension).
  passManager.addPass(IREE::Flow::createDeduplicateExecutablesPass());

  // TODO: Prune and rename this pass. This runs after sending everything
  // possible to the device and then legalizes any remaining h<->d loads,
  // typically coming from top level flow control.
  passManager.addNestedPass<FuncOp>(IREE::Flow::createPromoteTensorLoadsPass());

  // Create one function per remaining flow.executable that can be used with
  // iree-benchmark-module to benchmark each dispatch individually, as well as
  // exporting all original model entry points.
  if (clExportBenchmarkFuncs) {
    passManager.addPass(IREE::Flow::createExportBenchmarkFuncsPass());
  }

  // Inject tracing that logs both input and output tensors from all dispatches.
  // We do this after deduping so that the executable names match later stages.
  if (clTraceDispatchTensors) {
    passManager.addNestedPass<FuncOp>(
        IREE::Flow::createInjectDispatchTracingPass());
  }

  //----------------------------------------------------------------------------
  // Stream formation.
  // Pre-conditions:
  //   - Full formation of dispatch regions
  //----------------------------------------------------------------------------

  // Form streams.
  // Cleanup the IR before we try to form streams.
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());
  passManager.addNestedPass<FuncOp>(mlir::createCSEPass());

  // Reorder blocks to increase the grouping of streamable ops.
  passManager.addNestedPass<FuncOp>(
      IREE::Flow::createHoistUnstreamableOpsPass());

  // The hoisting pass does some reordering. Canonicalize to avoid unnecessary
  // arbitrary ordering.
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());
  passManager.addNestedPass<FuncOp>(mlir::createCSEPass());

  // Clone constants that escape basic blocks until we have better analysis.
  passManager.addNestedPass<FuncOp>(
      IREE::Flow::createInsertConstantClonesPass());

  // Group streamable ops into streams.
  passManager.addNestedPass<FuncOp>(IREE::Flow::createFormStreamsPass());

  // Prior to leaving the pipeline we need to clean things up for following
  // layers. These transforms may be undone by subsequent CSE/folding passes.
  passManager.addPass(IREE::Flow::createOutlineLargeConstantsPass());

  // Forming streams involves a fair amount of subgraph stitching, which can
  // cause duplication. Run CSE to collapse.
  passManager.addNestedPass<FuncOp>(mlir::createCanonicalizerPass());
  passManager.addNestedPass<FuncOp>(mlir::createCSEPass());

  // Symbol DCE any remaining variables/functions that are now no longer
  // required.
  passManager.addPass(mlir::createSymbolDCEPass());
}

void registerFlowTransformPassPipeline() {
  PassPipelineRegistration<> transformPassPipeline(
      "iree-flow-transformation-pipeline",
      "Runs the full IREE flow dialect transformation pipeline",
      [](OpPassManager &passManager) {
        buildFlowTransformPassPipeline(passManager);
      });
}

namespace {
#define GEN_PASS_REGISTRATION
#include "iree/compiler/Dialect/Flow/Transforms/Passes.h.inc"  // IWYU pragma: export
}  // namespace

void registerFlowPasses() {
  // Generated.
  registerPasses();

  // Pipelines.
  registerFlowTransformPassPipeline();
}

}  // namespace Flow
}  // namespace IREE
}  // namespace iree_compiler
}  // namespace mlir
<|endoftext|>


<commit_before>#include <BALL/VIEW/GUI/DIALOGS/colorMeshDialog.h>
#include <BALL/SYSTEM/path.h>
#include <BALL/DATATYPE/regularData3D.h>
#include <BALL/SYSTEM/file.h>
#include <BALL/VIEW/DATATYPE/colorTable.h>
#include <BALL/VIEW/GUI/KERNEL/mainControl.h>

#include <qlineedit.h>
#include <qpushbutton.h>
#include <qspinbox.h>
#include <qfiledialog.h>
#include <qcolordialog.h>
#include <qtabwidget.h>

namespace BALL
{
	namespace VIEW
	{

/*
 *  Constructs a ColorMeshDialog which is a child of 'parent', with the
 *  name 'name' and widget flags set to 'f'
 *
 *  The dialog will by default be modeless, unless you set 'modal' to
 *  TRUE to construct a modal dialog.
 */
ColorMeshDialog::ColorMeshDialog( QWidget* parent,  const char* name, bool modal, WFlags fl )
    : ColorMeshDialogData( parent, name, modal, fl )
{
}

ColorMeshDialog::~ColorMeshDialog()
{
 // no need to delete child widgets, Qt does it all for us
}

void ColorMeshDialog::apply_clicked()
{
	String fileName(location_edit->text().latin1());

	if (surface_tab->currentPage() == by_file)
	{
		// coloring by file
		RegularData3D dat;
		String filename = String(location_edit->text());
		File infile;
		try
		{
			infile = File(fileName, std::ios::in);
		}
		catch(Exception::FileNotFound)
		{
			Log.error() << "File could not be found!" << std::endl;
			return;
		}

		infile >> dat;
		infile.close();

		// now do the colorizing stuff...
		mesh->colorList.resize(mesh->vertex.size());
		ColorRGBA list[3];
		list[0] = ColorRGBA(0.,0.,1.,1.);
		list[1] = ColorRGBA(0.,1.,1.,1.);
		list[2] = ColorRGBA(1.,1.,0.,1.);

		ColorTable table(list, 3);
		table.setNumberOfColors(levels_box->value());
		table.createTable();
		table.setRange(atof(min_box->text().latin1()), atof(max_box->text().latin1()));

		try
		{
			for (Position i=0; i<mesh->colorList.size(); i++)
			{
				mesh->colorList[i] = table.map(dat[mesh->vertex[i]]);
			}
		}
		catch (Exception::OutOfGrid)
		{
			Log.error() << "Error! There is a point contained in the surface that is not "
									<< "inside the grid! Aborting the coloring..." << std::endl;
			return;
		}
	}
	if (surface_tab->currentPage() == by_color)
	{
		ColorRGBA col(red_box->value(), green_box->value(), blue_box->value(), alpha_box->value());

		mesh->colorList.resize(1);

		mesh->colorList[0] = col;
	}

	// repaint of the scene and the composites needed
	MainControl::getMainControl(this)->updateAll();
	MainControl::getMainControl(this)->repaint();

	hide();
}

void ColorMeshDialog::browse_clicked()
{
	// look up the full path of the parameter file
	Path p;
	String filename = p.find((String)location_edit->text());
	QString result = QFileDialog::getOpenFileName(filename.c_str(), "*", 0, "Select a RegularData file");
	if (!result.isEmpty())
	{
		// store the new filename in the lineedit field
		location_edit->setText(result);
	}
}

void ColorMeshDialog::cancel_clicked()
{
	hide();
}

QColor ColorMeshDialog::setColor(QPushButton* button)
{
	QPalette p = button->palette();
	QColor qcolor = QColorDialog::getColor(button->backgroundColor());
	p.setColor(QColorGroup::Button, qcolor);
	p.setColor(QColorGroup::Base, qcolor);
	p.setColor(QColorGroup::Light, qcolor);
	p.setColor(QColorGroup::Mid, qcolor);
	p.setColor(QColorGroup::Midlight, qcolor);
	p.setColor(QColorGroup::Shadow, qcolor);
	button->setPalette(p);
	return qcolor;
}

void ColorMeshDialog::choose_clicked()
{
	QColor qcolor = setColor(choose_button);
	selected_color.set(qcolor.red(), qcolor.blue(), qcolor.green());
	red_box->setValue(qcolor.red());
	blue_box->setValue(qcolor.blue());
	green_box->setValue(qcolor.green());
}

void ColorMeshDialog::color_boxes_changed()
{
	selected_color.set(red_box->value(),
										 blue_box->value(),
										 green_box->value(),
										 alpha_box->value());
	QColor qcolor(red_box->value(), blue_box->value(), green_box->value());
	QPalette p = choose_button->palette();
	p.setColor(QColorGroup::Button, qcolor);
	p.setColor(QColorGroup::Base, qcolor);
	p.setColor(QColorGroup::Light, qcolor);
	p.setColor(QColorGroup::Mid, qcolor);
	p.setColor(QColorGroup::Midlight, qcolor);
	p.setColor(QColorGroup::Shadow, qcolor);
	choose_button->setPalette(p);
}

void ColorMeshDialog::location_changed()
{
	if (String(location_edit->text()).size() != 0) apply_button->setEnabled(true);
		else	apply_button->setEnabled(false);
}

void ColorMeshDialog::max_clicked()
{
	QColor qcolor = setColor(max_button);
	max_color.set(qcolor.red(), qcolor.blue(), qcolor.green());;
}

void ColorMeshDialog::mid_clicked()
{
	QColor qcolor = setColor(mid_button);
	mid_color.set(qcolor.red(), qcolor.blue(), qcolor.green());;
}

void ColorMeshDialog::min_clicked()
{
	QColor qcolor = setColor(min_button);
	min_color.set(qcolor.red(), qcolor.blue(), qcolor.green());;
}

void ColorMeshDialog::min_min_clicked()
{
	QColor qcolor = setColor(min_min_button);
	min_min_color.set(qcolor.red(), qcolor.blue(), qcolor.green());;
}

void ColorMeshDialog::max_max_clicked()
{
	QColor qcolor = setColor(max_max_button);
	max_max_color.set(qcolor.red(), qcolor.blue(), qcolor.green());;
}

void ColorMeshDialog::tab_changed()
{
	if (surface_tab->currentPage() == by_file ||
			surface_tab->currentPage() == colormap_tab)
	{
		// in coloring by file, allow apply if filename set
		if (location_edit->text() == "")
		{
			apply_button->setEnabled(false);
		}
		else
		{
			apply_button->setEnabled(true);
		}
		return;
	}

	if (surface_tab->currentPage() == by_color)
	{
		// if coloring by selected color, always enabled
		apply_button->setEnabled(true);
	}
}

// NAMESPACE
	}
}
<commit_msg>setting of colors should be fixed now<commit_after>#include <BALL/VIEW/GUI/DIALOGS/colorMeshDialog.h>
#include <BALL/SYSTEM/path.h>
#include <BALL/DATATYPE/regularData3D.h>
#include <BALL/SYSTEM/file.h>
#include <BALL/VIEW/DATATYPE/colorTable.h>
#include <BALL/VIEW/GUI/KERNEL/mainControl.h>

#include <qlineedit.h>
#include <qpushbutton.h>
#include <qspinbox.h>
#include <qfiledialog.h>
#include <qcolordialog.h>
#include <qtabwidget.h>

namespace BALL
{
	namespace VIEW
	{

/*
 *  Constructs a ColorMeshDialog which is a child of 'parent', with the
 *  name 'name' and widget flags set to 'f'
 *
 *  The dialog will by default be modeless, unless you set 'modal' to
 *  TRUE to construct a modal dialog.
 */
ColorMeshDialog::ColorMeshDialog( QWidget* parent,  const char* name, bool modal, WFlags fl )
    : ColorMeshDialogData( parent, name, modal, fl )
{
}

ColorMeshDialog::~ColorMeshDialog()
{
 // no need to delete child widgets, Qt does it all for us
}

void ColorMeshDialog::apply_clicked()
{
	String fileName(location_edit->text().latin1());

	if (surface_tab->currentPage() == by_file)
	{
		// coloring by file
		RegularData3D dat;
		String filename = String(location_edit->text());
		File infile;
		try
		{
			infile = File(fileName, std::ios::in);
		}
		catch(Exception::FileNotFound)
		{
			Log.error() << "File could not be found!" << std::endl;
			return;
		}

		infile >> dat;
		infile.close();

		// now do the colorizing stuff...
		mesh->colorList.resize(mesh->vertex.size());
		ColorRGBA list[3];
		list[0] = ColorRGBA(0.,0.,1.,1.);
		list[1] = ColorRGBA(0.,1.,1.,1.);
		list[2] = ColorRGBA(1.,1.,0.,1.);

		ColorTable table(list, 3);
		table.setNumberOfColors(levels_box->value());
		table.createTable();
		table.setRange(atof(min_box->text().latin1()), atof(max_box->text().latin1()));

		try
		{
			for (Position i=0; i<mesh->colorList.size(); i++)
			{
				mesh->colorList[i] = table.map(dat[mesh->vertex[i]]);
			}
		}
		catch (Exception::OutOfGrid)
		{
			Log.error() << "Error! There is a point contained in the surface that is not "
									<< "inside the grid! Aborting the coloring..." << std::endl;
			return;
		}
	}
	if (surface_tab->currentPage() == by_color)
	{
		ColorRGBA col(red_box->value(), green_box->value(), blue_box->value(), alpha_box->value());

		mesh->colorList.resize(1);

		mesh->colorList[0] = col;
	}

	// repaint of the scene and the composites needed
	MainControl::getMainControl(this)->updateAll();
	MainControl::getMainControl(this)->repaint();

	hide();
}

void ColorMeshDialog::browse_clicked()
{
	// look up the full path of the parameter file
	Path p;
	String filename = p.find((String)location_edit->text());
	QString result = QFileDialog::getOpenFileName(filename.c_str(), "*", 0, "Select a RegularData file");
	if (!result.isEmpty())
	{
		// store the new filename in the lineedit field
		location_edit->setText(result);
	}
}

void ColorMeshDialog::cancel_clicked()
{
	hide();
}

QColor ColorMeshDialog::setColor(QPushButton* button)
{
	QPalette p = button->palette();
	QColor qcolor = QColorDialog::getColor(button->backgroundColor());
	p.setColor(QColorGroup::Button, qcolor);
	p.setColor(QColorGroup::Base, qcolor);
	p.setColor(QColorGroup::Light, qcolor);
	p.setColor(QColorGroup::Mid, qcolor);
	p.setColor(QColorGroup::Midlight, qcolor);
	p.setColor(QColorGroup::Shadow, qcolor);
	button->setPalette(p);
	return qcolor;
}

void ColorMeshDialog::choose_clicked()
{
	QColor qcolor = setColor(choose_button);
	selected_color.set(qcolor.red(), qcolor.green(), qcolor.blue());
	red_box->setValue(qcolor.red());
	blue_box->setValue(qcolor.blue());
	green_box->setValue(qcolor.green());
}

void ColorMeshDialog::color_boxes_changed()
{
	selected_color.set(red_box->value(),
										 green_box->value(),
										 blue_box->value(),
										 alpha_box->value());
	QColor qcolor(red_box->value(), green_box->value(), blue_box->value());
	QPalette p = choose_button->palette();
	p.setColor(QColorGroup::Button, qcolor);
	p.setColor(QColorGroup::Base, qcolor);
	p.setColor(QColorGroup::Light, qcolor);
	p.setColor(QColorGroup::Mid, qcolor);
	p.setColor(QColorGroup::Midlight, qcolor);
	p.setColor(QColorGroup::Shadow, qcolor);
	choose_button->setPalette(p);
}

void ColorMeshDialog::location_changed()
{
	if (String(location_edit->text()).size() != 0) apply_button->setEnabled(true);
		else	apply_button->setEnabled(false);
}

void ColorMeshDialog::max_clicked()
{
	QColor qcolor = setColor(max_button);
	max_color.set(qcolor.red(), qcolor.green(), qcolor.blue());;
}

void ColorMeshDialog::mid_clicked()
{
	QColor qcolor = setColor(mid_button);
	mid_color.set(qcolor.red(), qcolor.green(), qcolor.blue());;
}

void ColorMeshDialog::min_clicked()
{
	QColor qcolor = setColor(min_button);
	min_color.set(qcolor.red(), qcolor.green(), qcolor.blue());;

}

void ColorMeshDialog::min_min_clicked()
{
	QColor qcolor = setColor(min_min_button);
	min_min_color.set(qcolor.red(), qcolor.green(), qcolor.blue());;
}

void ColorMeshDialog::max_max_clicked()
{
	QColor qcolor = setColor(max_max_button);
	max_max_color.set(qcolor.red(), qcolor.green(), qcolor.blue());;
}

void ColorMeshDialog::tab_changed()
{
	if (surface_tab->currentPage() == by_file ||
			surface_tab->currentPage() == colormap_tab)
	{
		// in coloring by file, allow apply if filename set
		if (location_edit->text() == "")
		{
			apply_button->setEnabled(false);
		}
		else
		{
			apply_button->setEnabled(true);
		}
		return;
	}

	if (surface_tab->currentPage() == by_color)
	{
		// if coloring by selected color, always enabled
		apply_button->setEnabled(true);
	}
}

// NAMESPACE
	}
}
<|endoftext|>


<commit_before>/*!
  \copyright (c) RDO-Team, 2011
  \file      result_group.cpp
  \author    Урусов Андрей (rdo@rk9.bmstu.ru)
  \date      04.03.2011
  \brief     Группы собираемых показателей
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "simulator/runtime/pch/stdpch.h"
// ----------------------------------------------------------------------- INCLUDES
#include <boost/foreach.hpp>
#include <boost/format.hpp>
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/runtime/result/result_group.h"
#include "simulator/runtime/rdo_runtime.h"
#include "simulator/runtime/rdo_model_i.h"
#include "repository/rdorepository.h"
// --------------------------------------------------------------------------------

OPEN_RDO_RUNTIME_NAMESPACE

// --------------------------------------------------------------------------------
// -------------------- RDOPMDResult
// --------------------------------------------------------------------------------
RDOPMDResultGroup::RDOPMDResultGroup(CREF(tstring) name)
	: m_name (name                               )
	, m_state(name.empty() ? RGS_START : RGS_STOP)
{}

RDOPMDResultGroup::~RDOPMDResultGroup()
{}

void RDOPMDResultGroup::resetResult(CREF(LPRDORuntime) pRuntime)
{
	if (m_state == RGS_STOP)
		return;

	ASSERT(pRuntime);

	m_timeStart = pRuntime->getCurrentTime();

	if (!m_name.empty())
	{
		if (!m_streamFull.is_open())
		{
			LPIThreadProxy pThreadProxy = pRuntime->getThreadProxy();
			ASSERT(pThreadProxy);
			rdo::repository::RDOThreadRepository::CreateFileInfo file(
				boost::str(boost::format(_T("- %1% - full")) % m_name),
				_T("txt"),
				m_streamFull
			);
			pThreadProxy->sendMessage(IThreadProxy::TID_REPOSITORY, RDOThread::RT_REPOSITORY_CREATE_FILE, &file);
		}
		if (!m_streamTable.is_open())
		{
			LPIThreadProxy pThreadProxy = pRuntime->getThreadProxy();
			ASSERT(pThreadProxy);
			rdo::repository::RDOThreadRepository::CreateFileInfo file(
				boost::str(boost::format(_T("- %1% - table")) % m_name),
				_T("txt"),
				m_streamTable
			);
			pThreadProxy->sendMessage(IThreadProxy::TID_REPOSITORY, RDOThread::RT_REPOSITORY_CREATE_FILE, &file);
			if (m_streamTable.is_open())
			{
				BOOST_FOREACH(const LPIResult& pResult, m_resultList)
				{
					LPIResultGetValue pGetValue = pResult;
					if (pGetValue)
					{
						LPIName pName = pGetValue;
						ASSERT(pName);
						m_streamTable << pName->name() << _T("\t");
					}
				}
				m_streamTable << std::endl;
			}
		}
	}

	BOOST_FOREACH(LPIResult& pResult, m_resultList)
	{
		pResult->resetResult(pRuntime);
	}
}

void RDOPMDResultGroup::checkResult(CREF(LPRDORuntime) pRuntime)
{
	if (m_state == RGS_STOP)
		return;

	BOOST_FOREACH(LPIResult& pResult, m_resultList)
	{
		pResult->checkResult(pRuntime);
	}
}

void RDOPMDResultGroup::calcStat(CREF(LPRDORuntime) pRuntime, REF(rdo::ostream) stream)
{
	if (m_state == RGS_STOP)
		return;

	if (!m_name.empty())
	{
		double timeStop = pRuntime->getCurrentTime();
		boost::format header(_T("---> %1%, %2$1.6f -> %3$1.6f = %4$1.6f\n"));
		header
			% m_name
			% m_timeStart
			% timeStop
			% (timeStop - m_timeStart);

		stream << header.str();

		if (m_streamFull.is_open())
		{
			m_streamFull << header.str();
		}
	}

	rbool tableWrite = false;
	BOOST_FOREACH(LPIResult& pResult, m_resultList)
	{
		rdo::textstream textStream;

		pResult->calcStat(pRuntime, textStream);

		stream << textStream.str();
		if (m_streamFull.is_open())
		{
			m_streamFull << textStream.str();
		}

		LPIResultGetValue pGetValue = pResult;
		if (pGetValue)
		{
			if (pGetValue->getValue().typeID() != RDOType::t_real)
			{
				m_streamTable << pGetValue->getValue().getAsString() << _T("\t");
			}
			else
			{
				setlocale(LC_NUMERIC, "rus");
				m_streamTable << rdo::format(_T("%f"), pGetValue->getValue().getDouble()) << _T("\t");
				setlocale(LC_NUMERIC, "eng");
			}
			tableWrite = true;
		}
	}

	if (tableWrite)
	{
		m_streamTable << std::endl;
	}

	if (!m_name.empty())
	{
		boost::format footer(_T("<--- %1%\n"));
		footer % m_name;
		stream << footer.str();
		if (m_streamFull.is_open())
		{
			m_streamFull << footer.str();
		}
	}
	pRuntime->getResults().flush();
}

void RDOPMDResultGroup::onStart(CREF(LPRDORuntime) pRuntime)
{
	m_state = RGS_START;
	resetResult(pRuntime);
}

void RDOPMDResultGroup::onStop(CREF(LPRDORuntime) pRuntime)
{
	calcStat(pRuntime, pRuntime->getResults().getOStream());
	m_state = RGS_STOP;
}

void RDOPMDResultGroup::onAppend(CREF(LPIResult) pResult)
{
	ASSERT(pResult);

	m_resultList.push_back(pResult);
}

CLOSE_RDO_RUNTIME_NAMESPACE
<commit_msg> - после перевода кодировки исходников на utf-8<commit_after>/*!
  \copyright (c) RDO-Team, 2011
  \file      result_group.cpp
  \author    Урусов Андрей (rdo@rk9.bmstu.ru)
  \date      04.03.2011
  \brief     Группы собираемых показателей
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "simulator/runtime/pch/stdpch.h"
// ----------------------------------------------------------------------- INCLUDES
#include <boost/foreach.hpp>
#include <boost/format.hpp>
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/runtime/result/result_group.h"
#include "simulator/runtime/rdo_runtime.h"
#include "simulator/runtime/rdo_model_i.h"
#include "repository/rdorepository.h"
// --------------------------------------------------------------------------------

OPEN_RDO_RUNTIME_NAMESPACE

// --------------------------------------------------------------------------------
// -------------------- RDOPMDResult
// --------------------------------------------------------------------------------
RDOPMDResultGroup::RDOPMDResultGroup(CREF(tstring) name)
	: m_name (name                               )
	, m_state(name.empty() ? RGS_START : RGS_STOP)
{}

RDOPMDResultGroup::~RDOPMDResultGroup()
{}

void RDOPMDResultGroup::resetResult(CREF(LPRDORuntime) pRuntime)
{
	if (m_state == RGS_STOP)
		return;

	ASSERT(pRuntime);

	m_timeStart = pRuntime->getCurrentTime();

	if (!m_name.empty())
	{
		if (!m_streamFull.is_open())
		{
			LPIThreadProxy pThreadProxy = pRuntime->getThreadProxy();
			ASSERT(pThreadProxy);
			rdo::repository::RDOThreadRepository::CreateFileInfo file(
				boost::str(boost::format(_T("- %1% - full")) % m_name),
				_T("txt"),
				m_streamFull
			);
			pThreadProxy->sendMessage(IThreadProxy::TID_REPOSITORY, RDOThread::RT_REPOSITORY_CREATE_FILE, &file);
		}
		if (!m_streamTable.is_open())
		{
			LPIThreadProxy pThreadProxy = pRuntime->getThreadProxy();
			ASSERT(pThreadProxy);
			rdo::repository::RDOThreadRepository::CreateFileInfo file(
				boost::str(boost::format(_T("- %1% - table")) % m_name),
				_T("txt"),
				m_streamTable
			);
			pThreadProxy->sendMessage(IThreadProxy::TID_REPOSITORY, RDOThread::RT_REPOSITORY_CREATE_FILE, &file);
			if (m_streamTable.is_open())
			{
				BOOST_FOREACH(const LPIResult& pResult, m_resultList)
				{
					LPIResultGetValue pGetValue = pResult;
					if (pGetValue)
					{
						LPIName pName = pGetValue;
						ASSERT(pName);
						m_streamTable << pName->name() << _T("\t");
					}
				}
				m_streamTable << std::endl;
			}
		}
	}

	BOOST_FOREACH(LPIResult& pResult, m_resultList)
	{
		pResult->resetResult(pRuntime);
	}
}

void RDOPMDResultGroup::checkResult(CREF(LPRDORuntime) pRuntime)
{
	if (m_state == RGS_STOP)
		return;

	BOOST_FOREACH(LPIResult& pResult, m_resultList)
	{
		pResult->checkResult(pRuntime);
	}
}

void RDOPMDResultGroup::calcStat(CREF(LPRDORuntime) pRuntime, REF(rdo::ostream) stream)
{
	if (m_state == RGS_STOP)
		return;

	if (!m_name.empty())
	{
		double timeStop = pRuntime->getCurrentTime();
		boost::format header(_T("---> %1%, %2$1.6f -> %3$1.6f = %4$1.6f\n"));
		header
			% m_name
			% m_timeStart
			% timeStop
			% (timeStop - m_timeStart);

		stream << header.str();

		if (m_streamFull.is_open())
		{
			m_streamFull << header.str();
		}
	}

	rbool tableWrite = false;
	BOOST_FOREACH(LPIResult& pResult, m_resultList)
	{
		rdo::textstream textStream;

		pResult->calcStat(pRuntime, textStream);

		stream << textStream.str();
		if (m_streamFull.is_open())
		{
			m_streamFull << textStream.str();
		}

		LPIResultGetValue pGetValue = pResult;
		if (pGetValue)
		{
			if (pGetValue->getValue().typeID() != RDOType::t_real)
			{
				m_streamTable << pGetValue->getValue().getAsString() << _T("\t");
			}
			else
			{
				m_streamTable << rdo::format(_T("%f"), pGetValue->getValue().getDouble()) << _T("\t");
			}
			tableWrite = true;
		}
	}

	if (tableWrite)
	{
		m_streamTable << std::endl;
	}

	if (!m_name.empty())
	{
		boost::format footer(_T("<--- %1%\n"));
		footer % m_name;
		stream << footer.str();
		if (m_streamFull.is_open())
		{
			m_streamFull << footer.str();
		}
	}
	pRuntime->getResults().flush();
}

void RDOPMDResultGroup::onStart(CREF(LPRDORuntime) pRuntime)
{
	m_state = RGS_START;
	resetResult(pRuntime);
}

void RDOPMDResultGroup::onStop(CREF(LPRDORuntime) pRuntime)
{
	calcStat(pRuntime, pRuntime->getResults().getOStream());
	m_state = RGS_STOP;
}

void RDOPMDResultGroup::onAppend(CREF(LPIResult) pResult)
{
	ASSERT(pResult);

	m_resultList.push_back(pResult);
}

CLOSE_RDO_RUNTIME_NAMESPACE
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef otbLabelImageSmallRegionMergingFilter_hxx
#define otbLabelImageSmallRegionMergingFilter_hxx

#include "otbLabelImageSmallRegionMergingFilter.h"
#include "itkImageConstIterator.h"
#include "itkConstShapedNeighborhoodIterator.h"
#include "itkProgressReporter.h"

namespace otb
{
template <class TInputLabelImage, class TInputSpectralImage>
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::PersistentLabelImageSmallRegionMergingFilter() : m_Size(1)
{
}

template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::SetInputLabelImage( const TInputLabelImage * labelImage)
{
  // Process object is not const-correct so the const casting is required.
  this->SetNthInput(0, const_cast<TInputLabelImage *>( labelImage ));
}

template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::SetInputSpectralImage( const TInputSpectralImage * spectralImage)
{
  // Process object is not const-correct so the const casting is required.
  this->SetNthInput(1, const_cast<TInputSpectralImage *>( spectralImage ));
}

template <class TInputLabelImage, class TInputSpectralImage>
TInputLabelImage *
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::GetInputLabelImage()
{
  return dynamic_cast<TInputLabelImage*>(itk::ProcessObject::GetInput(0));
}

template <class TInputLabelImage, class TInputSpectralImage>
TInputSpectralImage *
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::GetInputSpectralImage()
{
  return dynamic_cast<TInputSpectralImage*>(itk::ProcessObject::GetInput(1));
}

template <class TInputLabelImage, class TInputSpectralImage>
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::~PersistentLabelImageSmallRegionMergingFilter()
{

}

template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::Reset()
{
  std::cout << "Reset" << std::endl;

  m_NeighboursMapsTmp.clear();
  m_NeighboursMapsTmp.resize( this->GetNumberOfThreads() );
}

template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::Synthetize()
{
  std::cout << "Synthetize" << std::endl;
  NeigboursMapType neighboursMap;
  // Merge the neighbours maps from all threads
  for( unsigned int threadId = 0; threadId < this->GetNumberOfThreads(); threadId++)
  {
    for (auto it = m_NeighboursMapsTmp[threadId].begin(); it != m_NeighboursMapsTmp[threadId].end(); it++)
    {
      neighboursMap[ it->first ].insert( it->second.begin(), it->second.end() );
    }
  }

  // For each label of the label map, find the "closest" connected label, according
  // to the euclidian distance between the corresponding m_labelStatistic elements.
  for (auto neighbours : neighboursMap)
  {
    double proximity = std::numeric_limits<double>::max();
    InputLabelType label = neighbours.first;
    InputLabelType closestNeighbour = label;
    for (auto neighbour : neighbours.second)
    {

      auto statsLabel = m_LabelStatistic[ label ];
      auto statsNeighbour = m_LabelStatistic[ neighbour ];
      assert( statsLabel.Size() == statsNeighbour.Size() );
      double distance = 0;
      for (int i = 0 ; i < statsLabel.Size(); i++)
      {
        distance += pow( statsLabel[i] - statsNeighbour[i] , 2);
      }

      if (distance < proximity)
      {
        proximity = distance;
        closestNeighbour = neighbour;
      }
      std::cout << label << " " << neighbour << " " << distance << " " << closestNeighbour <<std::endl;
    }
    m_CorrespondanceMap[label] = closestNeighbour;
    //InputLabelType neighbor = itLabel->first;
    //

    /*for (auto itNeigh = itLabel->second.begin(); itNeigh != itLabel->second.end(); ++itNeigh)
    {
      // Compute squared distance between the current label and the current neighbour
      //double dist = std::abs( std::pow( m_labelStatistic[itLabel->first], 2) - std::pow( m_labelStatistic[*itNeigh], 2) );
      for (auto
    }*/
  }

  // We have to update corresponding label to propagate the correspondance between the labels.
  for (auto corres : m_CorrespondanceMap)
  {
    corres.second = FindCorrespondingLabel(corres.second);
    std::cout << "label : " << corres.first << " closest : " << corres.second << std::endl;
  }

  /*
  for (auto it = m_NeighboursMap.begin(); it != m_NeighboursMap.end(); it++)
  {
    std::cout << it->first << " " ;
    for  (auto itSet = it->second.begin(); itSet != it->second.end(); itSet++)
      std::cout << *itSet << " " ;
    std::cout << std::endl;
  }*/
}

template <class TInputLabelImage, class TInputSpectralImage>
typename PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>::InputLabelType
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::FindCorrespondingLabel( typename PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
                            ::InputLabelType label)
{
  auto correspondingLabel = m_CorrespondanceMap[label];
  while (label != correspondingLabel)
  {std::cout << "yo" << std::endl;
    label = correspondingLabel;
    correspondingLabel = m_CorrespondanceMap[correspondingLabel];
  }
  return correspondingLabel;
}

template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::GenerateOutputInformation()
{
  Superclass::GenerateOutputInformation();
}

template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::ThreadedGenerateData(const RegionType& outputRegionForThread, itk::ThreadIdType threadId )
{
  std::cout << threadId << " " << outputRegionForThread.GetSize() << " " << outputRegionForThread.GetIndex() << std::endl;

  using IteratorType = itk::ImageRegionConstIterator< TInputLabelImage >;
  using NeighborhoodIteratorType = itk::ConstShapedNeighborhoodIterator< TInputLabelImage >;
  typename NeighborhoodIteratorType::RadiusType radius;
  radius.Fill(1);

  auto labelImage = this->GetInputLabelImage();

  IteratorType it(labelImage, outputRegionForThread);
  NeighborhoodIteratorType itN(radius, labelImage, outputRegionForThread);

  // 4 connected Neighborhood (top, bottom, left and right)
  typename IteratorType::OffsetType top = {{0,-1}};
  itN.ActivateOffset(top);
  typename IteratorType::OffsetType bottom = {{0,1}};
  itN.ActivateOffset(bottom);
  typename IteratorType::OffsetType right = {{1,0}};
  itN.ActivateOffset(right);
  typename IteratorType::OffsetType left = {{-1,0}};
  itN.ActivateOffset(left);

  for (it.GoToBegin(); ! it.IsAtEnd(); ++it, ++itN)
  {
    assert( !itN.IsAtEnd() );
    //if ( it.Get() == m_Size )
    if ( m_LabelPopulation[it.Get()] == m_Size )
    {
      //std::cout << it.Get() << std::endl;
      for (auto ci = itN.Begin() ; !ci.IsAtEnd(); ci++)
      {
        int neighbourLabel = FindCorrespondingLabel(ci.Get() );
        std::cout << neighbourLabel << " " << ci.Get() << " " << it.Get() << std::endl;
        if (neighbourLabel != it.Get() && m_LabelPopulation[neighbourLabel] > m_Size)
          m_NeighboursMapsTmp[threadId][ it.Get() ].insert( neighbourLabel );
      }
    }
  }

}

template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  Superclass::PrintSelf(os, indent);
}

} // end namespace otb

#endif
<commit_msg>ENH : reference in the range based loop so we can modify the correspondance map<commit_after>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef otbLabelImageSmallRegionMergingFilter_hxx
#define otbLabelImageSmallRegionMergingFilter_hxx

#include "otbLabelImageSmallRegionMergingFilter.h"
#include "itkImageConstIterator.h"
#include "itkConstShapedNeighborhoodIterator.h"
#include "itkProgressReporter.h"

namespace otb
{
template <class TInputLabelImage, class TInputSpectralImage>
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::PersistentLabelImageSmallRegionMergingFilter() : m_Size(1)
{
}

template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::SetInputLabelImage( const TInputLabelImage * labelImage)
{
  // Process object is not const-correct so the const casting is required.
  this->SetNthInput(0, const_cast<TInputLabelImage *>( labelImage ));
}

template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::SetInputSpectralImage( const TInputSpectralImage * spectralImage)
{
  // Process object is not const-correct so the const casting is required.
  this->SetNthInput(1, const_cast<TInputSpectralImage *>( spectralImage ));
}

template <class TInputLabelImage, class TInputSpectralImage>
TInputLabelImage *
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::GetInputLabelImage()
{
  return dynamic_cast<TInputLabelImage*>(itk::ProcessObject::GetInput(0));
}

template <class TInputLabelImage, class TInputSpectralImage>
TInputSpectralImage *
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::GetInputSpectralImage()
{
  return dynamic_cast<TInputSpectralImage*>(itk::ProcessObject::GetInput(1));
}

template <class TInputLabelImage, class TInputSpectralImage>
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::~PersistentLabelImageSmallRegionMergingFilter()
{

}

template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::Reset()
{
  std::cout << "Reset" << std::endl;

  m_NeighboursMapsTmp.clear();
  m_NeighboursMapsTmp.resize( this->GetNumberOfThreads() );
}

template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::Synthetize()
{
  std::cout << "Synthetize" << std::endl;
  NeigboursMapType neighboursMap;
  // Merge the neighbours maps from all threads
  for( unsigned int threadId = 0; threadId < this->GetNumberOfThreads(); threadId++)
  {
    for (auto it = m_NeighboursMapsTmp[threadId].begin(); it != m_NeighboursMapsTmp[threadId].end(); it++)
    {
      neighboursMap[ it->first ].insert( it->second.begin(), it->second.end() );
    }
  }

  // For each label of the label map, find the "closest" connected label, according
  // to the euclidian distance between the corresponding m_labelStatistic elements.
  for (auto neighbours : neighboursMap)
  {
    double proximity = std::numeric_limits<double>::max();
    InputLabelType label = neighbours.first;
    InputLabelType closestNeighbour = label;
    for (auto neighbour : neighbours.second)
    {

      auto statsLabel = m_LabelStatistic[ label ];
      auto statsNeighbour = m_LabelStatistic[ neighbour ];
      assert( statsLabel.Size() == statsNeighbour.Size() );
      double distance = 0;
      for (int i = 0 ; i < statsLabel.Size(); i++)
      {
        distance += pow( statsLabel[i] - statsNeighbour[i] , 2);
      }

      if (distance < proximity)
      {
        proximity = distance;
        closestNeighbour = neighbour;
      }
      std::cout << label << " " << neighbour << " " << distance << " " << closestNeighbour <<std::endl;
    }
    m_CorrespondanceMap[label] = closestNeighbour;
    //InputLabelType neighbor = itLabel->first;
    //

    /*for (auto itNeigh = itLabel->second.begin(); itNeigh != itLabel->second.end(); ++itNeigh)
    {
      // Compute squared distance between the current label and the current neighbour
      //double dist = std::abs( std::pow( m_labelStatistic[itLabel->first], 2) - std::pow( m_labelStatistic[*itNeigh], 2) );
      for (auto
    }*/
  }

  // We have to update corresponding label to propagate the correspondance between the labels.
  for (auto & corres : m_CorrespondanceMap)
  {
    corres.second = FindCorrespondingLabel(corres.second);
    std::cout << "label : " << corres.first << " closest : " << corres.second << std::endl;
  }

  /*
  for (auto it = m_NeighboursMap.begin(); it != m_NeighboursMap.end(); it++)
  {
    std::cout << it->first << " " ;
    for  (auto itSet = it->second.begin(); itSet != it->second.end(); itSet++)
      std::cout << *itSet << " " ;
    std::cout << std::endl;
  }*/
}

template <class TInputLabelImage, class TInputSpectralImage>
typename PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>::InputLabelType
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::FindCorrespondingLabel( typename PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
                            ::InputLabelType label)
{
  auto correspondingLabel = m_CorrespondanceMap[label];
  while (label != correspondingLabel)
  {std::cout << "yo" << std::endl;
    label = correspondingLabel;
    correspondingLabel = m_CorrespondanceMap[correspondingLabel];
  }
  return correspondingLabel;
}

template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::GenerateOutputInformation()
{
  Superclass::GenerateOutputInformation();
}

template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::ThreadedGenerateData(const RegionType& outputRegionForThread, itk::ThreadIdType threadId )
{
  std::cout << threadId << " " << outputRegionForThread.GetSize() << " " << outputRegionForThread.GetIndex() << std::endl;

  using IteratorType = itk::ImageRegionConstIterator< TInputLabelImage >;
  using NeighborhoodIteratorType = itk::ConstShapedNeighborhoodIterator< TInputLabelImage >;
  typename NeighborhoodIteratorType::RadiusType radius;
  radius.Fill(1);

  auto labelImage = this->GetInputLabelImage();

  IteratorType it(labelImage, outputRegionForThread);
  NeighborhoodIteratorType itN(radius, labelImage, outputRegionForThread);

  // 4 connected Neighborhood (top, bottom, left and right)
  typename IteratorType::OffsetType top = {{0,-1}};
  itN.ActivateOffset(top);
  typename IteratorType::OffsetType bottom = {{0,1}};
  itN.ActivateOffset(bottom);
  typename IteratorType::OffsetType right = {{1,0}};
  itN.ActivateOffset(right);
  typename IteratorType::OffsetType left = {{-1,0}};
  itN.ActivateOffset(left);

  for (it.GoToBegin(); ! it.IsAtEnd(); ++it, ++itN)
  {
    assert( !itN.IsAtEnd() );
    //if ( it.Get() == m_Size )
    if ( m_LabelPopulation[it.Get()] == m_Size )
    {
      //std::cout << it.Get() << std::endl;
      for (auto ci = itN.Begin() ; !ci.IsAtEnd(); ci++)
      {
        int neighbourLabel = FindCorrespondingLabel(ci.Get() );
        std::cout << neighbourLabel << " " << ci.Get() << " " << it.Get() << std::endl;
        if (neighbourLabel != it.Get() && m_LabelPopulation[neighbourLabel] > m_Size)
          m_NeighboursMapsTmp[threadId][ it.Get() ].insert( neighbourLabel );
      }
    }
  }

}

template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  Superclass::PrintSelf(os, indent);
}

} // end namespace otb

#endif
<|endoftext|>


<commit_before>//
//  curl_easy.cpp
//  curl_wrapper
//
//  Created by Giuseppe Persico on 06/01/14.
//  Copyright (c) 2014 Giuseppe Persico. All rights reserved.
//

#include <algorithm>
#include "curl_easy.h"
#include <iostream>

using std::for_each;
using curl::curl_easy;

namespace curl {
    curl_easy::curl_easy() : abstract_curl() {
	    this->curl = curl_easy_init();
    }

    curl_easy::curl_easy(const long flag) : abstract_curl(flag) {
	    curl_easy();
    }

    curl_easy::~curl_easy() {
        if (this->curl!=nullptr) {
            curl_easy_cleanup(this->curl);
            this->curl = nullptr;
            std::cout<<"ok"<<std::endl;
        }
    }

    const string curl_easy::error_to_string(const CURLcode code) const noexcept {
        return curl_easy_strerror(code);
    }

    CURL *curl_easy::get_curl() const noexcept {
        return this->curl;
    }

    int curl_easy::perform() {
        if (this->curl!=nullptr) {
            return curl_easy_perform(this->curl);
        } else {
            throw new null_pointer_exception("perform() : NULL pointer intercepted");
        }
    }

    void curl_easy::escape(string &url) {
        char *url_encoded = curl_easy_escape(this->curl,url.c_str(),(int)url.length());
        if (url_encoded==nullptr) {
            throw new null_pointer_exception("escape(...) : NULL pointer intercepted");
        }
        url = string(url_encoded);
        this->free(url_encoded);
    }

    void curl_easy::unescape(string &url) {
        char *url_decoded = curl_easy_unescape(this->curl,url.c_str(),(int)url.length(),nullptr);
        if (url_decoded==nullptr) {
            throw new null_pointer_exception("escape(...) : NULL pointer intercepted");
        }
        url = string(url_decoded);
        this->free(url_decoded);
    }

    void curl_easy::reset() noexcept {
        if (this->curl!=nullptr) {
            curl_easy_reset(this->curl);
        }
    }
}
<commit_msg>Update curl_easy.cpp<commit_after>//
//  curl_easy.cpp
//  curl_wrapper
//
//  Created by Giuseppe Persico on 06/01/14.
//  Copyright (c) 2014 Giuseppe Persico. All rights reserved.
//

#include <algorithm>
#include "curl_easy.h"

using std::for_each;
using curl::curl_easy;

namespace curl {
    curl_easy::curl_easy() : abstract_curl() {
	    this->curl = curl_easy_init();
    }

    curl_easy::curl_easy(const long flag) : abstract_curl(flag) {
	    curl_easy();
    }

    curl_easy::~curl_easy() {
        if (this->curl!=nullptr) {
            curl_easy_cleanup(this->curl);
            this->curl = nullptr;
        }
    }

    const string curl_easy::error_to_string(const CURLcode code) const noexcept {
        return curl_easy_strerror(code);
    }

    CURL *curl_easy::get_curl() const noexcept {
        return this->curl;
    }

    int curl_easy::perform() {
        if (this->curl!=nullptr) {
            return curl_easy_perform(this->curl);
        } else {
            throw new null_pointer_exception("perform() : NULL pointer intercepted");
        }
    }

    void curl_easy::escape(string &url) {
        char *url_encoded = curl_easy_escape(this->curl,url.c_str(),(int)url.length());
        if (url_encoded==nullptr) {
            throw new null_pointer_exception("escape(...) : NULL pointer intercepted");
        }
        url = string(url_encoded);
        this->free(url_encoded);
    }

    void curl_easy::unescape(string &url) {
        char *url_decoded = curl_easy_unescape(this->curl,url.c_str(),(int)url.length(),nullptr);
        if (url_decoded==nullptr) {
            throw new null_pointer_exception("escape(...) : NULL pointer intercepted");
        }
        url = string(url_decoded);
        this->free(url_decoded);
    }

    void curl_easy::reset() noexcept {
        if (this->curl!=nullptr) {
            curl_easy_reset(this->curl);
        }
    }
}
<|endoftext|>


<commit_before>/*
 * AttentionSCM.cc
 *
 * Guile Scheme bindings for the attentionbank
 * Copyright (C) 2014 Cosmo Harrigan
 * Copyright (c) 2008, 2014, 2015, 2018 Linas Vepstas <linasvepstas@gmail.com>
 */

#ifdef HAVE_GUILE

#include <opencog/attentionbank/AttentionBank.h>
#include <opencog/guile/SchemePrimitive.h>

namespace opencog {

class AttentionSCM
{
	protected:
		static void* init_in_guile(void*);
		static void init_in_module(void*);
		void init(void);
	public:
		AttentionSCM(void);
		~AttentionSCM();

		int af_size(void);
		int set_af_size(int);
		Handle stimulate (const Handle&, double);
};

}

#include <opencog/atomspace/AtomSpace.h>
#include <opencog/guile/SchemePrimitive.h>
#include <opencog/guile/SchemeSmob.h>

using namespace opencog;

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

AttentionSCM::AttentionSCM(void)
{
	static bool is_init = false;
	if (is_init) return;
	is_init = true;
	scm_with_guile(init_in_guile, this);
}

void* AttentionSCM::init_in_guile(void* self)
{
	scm_c_define_module("opencog attention-bank", init_in_module, self);
	scm_c_use_module("opencog attention-bank");
	return NULL;
}

void AttentionSCM::init_in_module(void* data)
{
	AttentionSCM* self = (AttentionSCM*) data;
	self->init();
}

/// This is called while (opencog attention-bank) is the current module.
/// Thus, all the definitions below happen in that module.
void AttentionSCM::init(void)
{
	define_scheme_primitive("cog-af-size", &AttentionSCM::af_size, this, "attention-bank");
	define_scheme_primitive("cog-set-af-size!", &AttentionSCM::set_af_size, this, "attention-bank");
	define_scheme_primitive("cog-stimulate", &AttentionSCM::stimulate, this, "attention-bank");
}

AttentionSCM::~AttentionSCM()
{
}

/**
 *   Return AttentionalFocus Size
 **/
int AttentionSCM::af_size(void)
{
    AtomSpace* atomspace = SchemeSmob::ss_get_env_as("cog-af-size");
    return attentionbank(atomspace).get_af_size();
}

/**
 * Set AttentionalFocus Size
 */
int AttentionSCM::set_af_size (int ssize)
{
    AtomSpace* atomspace = SchemeSmob::ss_get_env_as("cog-set-af-size!");

    attentionbank(atomspace).set_af_size(ssize);
    return attentionbank(atomspace).get_af_size();
}

#ifdef FOO
xxxxxxxxxxxxxxxxxxxxxxx
/**
 * Return the list of top n atoms in the AttentionalFocus or
 * return all atoms in the AF if n is unspecified or is larger
 * than the AF size.
 */
SCM SchemeSmob::ss_af (SCM n)
{
	AtomSpace* atomspace = ss_get_env_as("cog-af");
	HandleSeq attentionalFocus;
	attentionbank(atomspace).get_handle_set_in_attentional_focus(back_inserter(attentionalFocus));
	size_t isz = attentionalFocus.size();
	if (0 == isz) return SCM_EOL;

	SCM head = SCM_EOL;
	size_t N = isz;
	if( SCM_UNDEFINED != n) N = scm_to_uint(n);
	if( N > isz)  N = isz;
	for (size_t i = isz - N; i < isz; i++) {
		Handle hi = attentionalFocus[i];
		SCM smob = handle_to_scm(hi);
		head = scm_cons(smob, head);
	}

	return head;
}
#endif

/**
 *  Stimulate an atom with given stimulus amount.
 */
Handle AttentionSCM::stimulate (const Handle& h, double stimulus)
{
	AtomSpace* atomspace = SchemeSmob::ss_get_env_as("cog-stimulate");
	attentionbank(atomspace).stimulate(h, stimulus);
	return h;
}

extern "C" {
void opencog_attention_init(void);
};

void opencog_attention_init(void)
{
	static AttentionSCM atty;
}
#endif // HAVE_GUILE
<commit_msg>Move attention focus to the atomspace3<commit_after>/*
 * AttentionSCM.cc
 *
 * Guile Scheme bindings for the attentionbank
 * Copyright (C) 2014 Cosmo Harrigan
 * Copyright (c) 2008, 2014, 2015, 2018 Linas Vepstas <linasvepstas@gmail.com>
 */

#ifdef HAVE_GUILE

#include <opencog/atoms/base/Link.h>
#include <opencog/attentionbank/AttentionBank.h>
#include <opencog/guile/SchemePrimitive.h>

namespace opencog {

class AttentionSCM
{
	protected:
		static void* init_in_guile(void*);
		static void init_in_module(void*);
		void init(void);
	public:
		AttentionSCM(void);
		~AttentionSCM();

		Handle update_af(int);
		int af_size(void);
		int set_af_size(int);
		Handle stimulate (const Handle&, double);
};

}

#include <opencog/atomspace/AtomSpace.h>
#include <opencog/guile/SchemePrimitive.h>
#include <opencog/guile/SchemeSmob.h>

using namespace opencog;

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

AttentionSCM::AttentionSCM(void)
{
	static bool is_init = false;
	if (is_init) return;
	is_init = true;
	scm_with_guile(init_in_guile, this);
}

void* AttentionSCM::init_in_guile(void* self)
{
	scm_c_define_module("opencog attention-bank", init_in_module, self);
	scm_c_use_module("opencog attention-bank");
	return NULL;
}

void AttentionSCM::init_in_module(void* data)
{
	AttentionSCM* self = (AttentionSCM*) data;
	self->init();
}

/// This is called while (opencog attention-bank) is the current module.
/// Thus, all the definitions below happen in that module.
void AttentionSCM::init(void)
{
	define_scheme_primitive("cog-update-af", &AttentionSCM::update_af, this, "attention-bank");
	define_scheme_primitive("cog-af-size", &AttentionSCM::af_size, this, "attention-bank");
	define_scheme_primitive("cog-set-af-size!", &AttentionSCM::set_af_size, this, "attention-bank");
	define_scheme_primitive("cog-stimulate", &AttentionSCM::stimulate, this, "attention-bank");
}

AttentionSCM::~AttentionSCM()
{
}

/**
 *   Return AttentionalFocus Size
 **/
int AttentionSCM::af_size(void)
{
    AtomSpace* atomspace = SchemeSmob::ss_get_env_as("cog-af-size");
    return attentionbank(atomspace).get_af_size();
}

/**
 * Set AttentionalFocus Size
 */
int AttentionSCM::set_af_size (int ssize)
{
    AtomSpace* atomspace = SchemeSmob::ss_get_env_as("cog-set-af-size!");

    attentionbank(atomspace).set_af_size(ssize);
    return attentionbank(atomspace).get_af_size();
}

/**
 * Return the list of top n atoms in the AttentionalFocus or
 * return all atoms in the AF if n is unspecified or is larger
 * than the AF size.
 */
Handle AttentionSCM::update_af(int n)
{
	AtomSpace* atomspace = SchemeSmob::ss_get_env_as("cog-af");

	Handle af_anchor = atomspace->add_node(ANCHOR_NODE,
	                                "*-attentional-focus-boundary-*");

	// Get the atoms that were previously in attention focus
	IncomingSet paf(af_anchor->getIncomingSetByType(MEMBER_LINK));
	HandleSet prev_af;
	for (const LinkPtr& lp: paf)
	{
		Handle h(lp->getOutgoingAtom(0));
		if (h != af_anchor)
			prev_af.insert(h);
	}

	HandleSeq attentionalFocus;
	attentionbank(atomspace).get_handle_set_in_attentional_focus(back_inserter(attentionalFocus));
	size_t isz = attentionalFocus.size();

	size_t N = isz;
	if (0 < n) N = n;
	if( N > isz)  N = isz;

	/* Add all the atoms in the current attentional focus that are not
	 * already there. */
	HandleSet curr_af;
	for (size_t i = isz - N; i < isz; i++)
	{
		Handle hi = attentionalFocus[i];
		auto gone = prev_af.find(hi);
		if (prev_af.end() == gone)
		{
			atomspace->add_link(MEMBER_LINK, hi, af_anchor);
		}
		else
		{
			curr_af.insert(hi);
		}
	}

	/* Remove the atoms no longer in attentional focus */
	for (const Handle& h: prev_af)
	{
		auto gone = curr_af.find(h);
		if (curr_af.end() == gone)
		{
			atomspace->extract_atom(h);
		}
	}

	return af_anchor;
}

/**
 *  Stimulate an atom with given stimulus amount.
 */
Handle AttentionSCM::stimulate (const Handle& h, double stimulus)
{
	AtomSpace* atomspace = SchemeSmob::ss_get_env_as("cog-stimulate");
	attentionbank(atomspace).stimulate(h, stimulus);
	return h;
}

extern "C" {
void opencog_attention_init(void);
};

void opencog_attention_init(void)
{
	static AttentionSCM atty;
}
#endif // HAVE_GUILE
<|endoftext|>


<commit_before>/*
 *  SystemFunctions.cpp
 *  OpenLieroX
 *
 *  Created by Albert Zeyer on 01.12.09.
 *  code under LGPL
 *
 */

#include <iomanip>
#include <time.h>
#include <SDL.h>
#define Font Font_Xlib // Hack to prevent name clash in precompiled header
#include <SDL_syswm.h>
#undef Font
#ifdef REAL_OPENGL
#include <SDL_opengl.h>
#endif
#include <cstdlib>
#include <sstream>
#include <cstring>

#if defined(__APPLE__)
#include <mach/host_info.h>
#include <mach/mach_host.h>
#include <mach/mach_init.h>
#include <sys/sysctl.h>
#include <mach/mach_traps.h>
#elif defined(WIN32) || defined(WIN64)
#include <windows.h>
#else
#include <cstdio>
#include <unistd.h>
#endif

#ifdef __FREEBSD__
#include <sys/sysctl.h>
#include <vm/vm_param.h>
#include <sys/vmmeter.h>
#endif

#ifndef WIN32
#include <sys/types.h>
#include <sys/resource.h>
#include <unistd.h>
#include <signal.h>
#endif

#include "StringUtils.h"
#include "ThreadPool.h"
#include "util/macros.h"

#if !defined(WIN32) || defined(HAVE_PTHREAD)
#include <pthread.h>
#ifndef HAVE_PTHREAD
#define HAVE_PTHREAD
#endif

// pthread_setname_np only available since MacOSX SDK 10.6
#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
#define HAVE_PTHREAD_NAME
#endif

#endif

#ifdef THREADNAME_VIA_SIGUSR1
static void setCurThreadName__signalraiser(const char* name) {
#ifndef _MSC_VER
	// this signal is only for debuggers, we should ignore it
	signal( SIGUSR1, SIG_IGN );

	// KDevelop will catch this, read the 'name' parameter and continue execution
	raise( SIGUSR1 );
#endif
}
#endif

ThreadId getCurrentThreadId() {
#ifdef HAVE_PTHREAD
	return (ThreadId) pthread_self();
#else
	// SDL_ThreadID returns a Uint32.
	// On 64bit systems, this might not be enough information about the current thread.
	// Win64 thread HANDLE is 64bit, aswell as pthread_t.
	return (ThreadId) SDL_ThreadID();
#endif
}

//////////////////
// Gives a name to the thread
// Code taken from http://www.codeproject.com/KB/threads/Name_threads_in_debugger.aspx
void setCurThreadName(const std::string& name)
{
#ifdef _MSC_VER // Currently only for MSVC, haven't found a Windows-general way (I doubt there is one)
	typedef struct tagTHREADNAME_INFO
	{
		DWORD dwType; // Must be 0x1000.
		LPCSTR szName; // Pointer to name (in user addr space).
		DWORD dwThreadID; // Thread ID (-1=caller thread).
		DWORD dwFlags; // Reserved for future use, must be zero.
	} THREADNAME_INFO;

	THREADNAME_INFO info;
	{
		info.dwType = 0x1000;
		info.szName = name.c_str();
		info.dwThreadID = (DWORD)-1;
		info.dwFlags = 0;
	}

	__try
	{
		RaiseException( 0x406D1388 /* MSVC EXCEPTION */, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info );
	}
	__except (EXCEPTION_CONTINUE_EXECUTION)
	{
	}
#endif

#ifdef THREADNAME_VIA_SIGUSR1
	setCurThreadName__signalraiser(name.c_str());
#endif

#ifdef HAVE_PTHREAD_NAME
	pthread_setname_np(name.c_str());
#endif
}

std::string getThreadName(ThreadId tid) {
#ifdef HAVE_PTHREAD
	char buf[128] = "\0";
	if(pthread_getname_np((pthread_t) tid, buf, sizeof(buf)) == 0)
		if(strlen(buf) > 0)
			return buf;
#endif

	if(threadPool) {
		std::map<ThreadId, std::string> threads;
		threadPool->getAllWorkingThreads(threads);
		foreach(t, threads) {
			if(t->first == tid)
				return t->second;
		}
	}

	return "";
}

void setCurThreadPriority(float p) {
#ifdef WIN32

#elif defined(__APPLE__)
	//int curp = getpriority(PRIO_DARWIN_THREAD, 0);
	//int newp = p >= 0 ? 0 : 1;
	//notes << "curp:" << curp << ", newp:" << newp << endl;
	//setpriority(PRIO_DARWIN_THREAD, 0, newp);
#endif
}

size_t GetFreeSysMemory() {
#if defined(__APPLE__)
	vm_statistics_data_t page_info;
	vm_size_t pagesize;
	mach_msg_type_number_t count;
	kern_return_t kret;

	pagesize = 0;
	kret = host_page_size (mach_host_self(), &pagesize);
	count = HOST_VM_INFO_COUNT;

	kret = host_statistics (mach_host_self(), HOST_VM_INFO,(host_info_t)&page_info, &count);
	return page_info.free_count * pagesize;
#elif defined(__WIN64__)
	MEMORYSTATUSEX memStatex;
	memStatex.dwLength = sizeof (memStatex);
	::GlobalMemoryStatusEx (&memStatex);
	return memStatex.ullAvailPhys;
#elif defined(__WIN32__)
	MEMORYSTATUS memStatus;
	memStatus.dwLength = sizeof(MEMORYSTATUS);
	::GlobalMemoryStatus(&memStatus);
	return memStatus.dwAvailPhys;
#elif defined(__SUN__) && defined(_SC_AVPHYS_PAGES)
	return sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE);
#elif defined(__FREEBSD__)
	int vm_vmtotal[] = { CTL_VM, VM_METER };
	struct vmtotal vmdata;

	size_t len = sizeof(vmdata);
	int result = sysctl(vm_vmtotal, sizeof(vm_vmtotal) / sizeof(*vm_vmtotal), &vmdata, &len, NULL, 0);
	if(result != 0) return 0;

	return vmdata.t_free * sysconf(_SC_PAGESIZE);
#elif defined(__linux__)

	// get it from /proc/meminfo
	FILE *fp = fopen("/proc/meminfo", "r");
	if ( fp )
	{
		unsigned long freeMem = 0;
		unsigned long buffersMem = 0;
		unsigned long cachedMem = 0;
		struct SearchTerm { const char* name; unsigned long* var; };
		SearchTerm terms[] = { {"MemFree:", &freeMem}, {"Buffers:", &buffersMem}, {"Cached:", &cachedMem} };

		char buf[1024];
		int n = fread(buf, sizeof(char), sizeof(buf) - 1, fp);
		buf[sizeof(buf)-1] = '\0';
		if(n > 0) {
			for(unsigned int i = 0; i < sizeof(terms) / sizeof(SearchTerm); ++i) {
				char* p = strstr(buf, terms[i].name);
				if(p) {
					p += strlen(terms[i].name);
					*terms[i].var = strtoul(p, NULL, 10);
				}
			}
		}

		fclose(fp);
		// it's written in KB in meminfo
		return ((size_t)freeMem + (size_t)buffersMem + (size_t)cachedMem) * 1024;
	}

	return 0;
#else
#warning No GetFreeSysMemory implementation for this arch/sys
	return 50 * 1024 * 1024; // return 50 MB (really randomly made up, but helps for cache system)
#endif
}

std::string GetDateTimeText()
{
	time_t t = time(NULL);

	if (t == (time_t)-1)
		return "TIME-ERROR1";

	char* timeCstr = ctime(&t);
	if(timeCstr == NULL)
		return "TIME-ERROR2";

	std::string timeStr(timeCstr);
	TrimSpaces(timeStr);
	return timeStr;
}

std::string GetDateTimeFilename()
{
	// Add date and server name to screenshot filename
	time_t curtime1 = time(NULL);
	if (curtime1 == (time_t)-1)
		return "TIME-ERROR1";
	struct tm *curtime = localtime(&curtime1);
	if (curtime == NULL)
		return "TIME-ERROR2";
	char filePrefixTime[200] = {0};
	strftime(filePrefixTime, sizeof(filePrefixTime), "%Y%m%d-%H%M", curtime);
	return filePrefixTime;
}

<commit_msg>small fix<commit_after>/*
 *  SystemFunctions.cpp
 *  OpenLieroX
 *
 *  Created by Albert Zeyer on 01.12.09.
 *  code under LGPL
 *
 */

#include <iomanip>
#include <time.h>
#include <SDL.h>
#define Font Font_Xlib // Hack to prevent name clash in precompiled header
#include <SDL_syswm.h>
#undef Font
#ifdef REAL_OPENGL
#include <SDL_opengl.h>
#endif
#include <cstdlib>
#include <sstream>
#include <cstring>

#if defined(__APPLE__)
#include <mach/host_info.h>
#include <mach/mach_host.h>
#include <mach/mach_init.h>
#include <sys/sysctl.h>
#include <mach/mach_traps.h>
#elif defined(WIN32) || defined(WIN64)
#include <windows.h>
#else
#include <cstdio>
#include <unistd.h>
#endif

#ifdef __FREEBSD__
#include <sys/sysctl.h>
#include <vm/vm_param.h>
#include <sys/vmmeter.h>
#endif

#ifndef WIN32
#include <sys/types.h>
#include <sys/resource.h>
#include <unistd.h>
#include <signal.h>
#endif

#include "StringUtils.h"
#include "ThreadPool.h"
#include "util/macros.h"

#if !defined(WIN32) || defined(HAVE_PTHREAD)
#include <pthread.h>
#ifndef HAVE_PTHREAD
#define HAVE_PTHREAD
#endif

// pthread_setname_np only available since MacOSX SDK 10.6
#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
#define HAVE_PTHREAD_NAME
#endif

#endif

#ifdef THREADNAME_VIA_SIGUSR1
static void setCurThreadName__signalraiser(const char* name) {
#ifndef _MSC_VER
	// this signal is only for debuggers, we should ignore it
	signal( SIGUSR1, SIG_IGN );

	// KDevelop will catch this, read the 'name' parameter and continue execution
	raise( SIGUSR1 );
#endif
}
#endif

ThreadId getCurrentThreadId() {
#ifdef HAVE_PTHREAD
	return (ThreadId) pthread_self();
#else
	// SDL_ThreadID returns a Uint32.
	// On 64bit systems, this might not be enough information about the current thread.
	// Win64 thread HANDLE is 64bit, aswell as pthread_t.
	return (ThreadId) SDL_ThreadID();
#endif
}

//////////////////
// Gives a name to the thread
// Code taken from http://www.codeproject.com/KB/threads/Name_threads_in_debugger.aspx
void setCurThreadName(const std::string& name)
{
#ifdef _MSC_VER // Currently only for MSVC, haven't found a Windows-general way (I doubt there is one)
	typedef struct tagTHREADNAME_INFO
	{
		DWORD dwType; // Must be 0x1000.
		LPCSTR szName; // Pointer to name (in user addr space).
		DWORD dwThreadID; // Thread ID (-1=caller thread).
		DWORD dwFlags; // Reserved for future use, must be zero.
	} THREADNAME_INFO;

	THREADNAME_INFO info;
	{
		info.dwType = 0x1000;
		info.szName = name.c_str();
		info.dwThreadID = (DWORD)-1;
		info.dwFlags = 0;
	}

	__try
	{
		RaiseException( 0x406D1388 /* MSVC EXCEPTION */, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info );
	}
	__except (EXCEPTION_CONTINUE_EXECUTION)
	{
	}
#endif

#ifdef THREADNAME_VIA_SIGUSR1
	setCurThreadName__signalraiser(name.c_str());
#endif

#ifdef HAVE_PTHREAD_NAME
	pthread_setname_np(name.c_str());
#endif
}

std::string getThreadName(ThreadId tid) {
#ifdef HAVE_PTHREAD_NAME
	char buf[128] = "\0";
	if(pthread_getname_np((pthread_t) tid, buf, sizeof(buf)) == 0)
		if(strlen(buf) > 0)
			return buf;
#endif

	if(threadPool) {
		std::map<ThreadId, std::string> threads;
		threadPool->getAllWorkingThreads(threads);
		foreach(t, threads) {
			if(t->first == tid)
				return t->second;
		}
	}

	return "";
}

void setCurThreadPriority(float p) {
#ifdef WIN32

#elif defined(__APPLE__)
	//int curp = getpriority(PRIO_DARWIN_THREAD, 0);
	//int newp = p >= 0 ? 0 : 1;
	//notes << "curp:" << curp << ", newp:" << newp << endl;
	//setpriority(PRIO_DARWIN_THREAD, 0, newp);
#endif
}

size_t GetFreeSysMemory() {
#if defined(__APPLE__)
	vm_statistics_data_t page_info;
	vm_size_t pagesize;
	mach_msg_type_number_t count;
	kern_return_t kret;

	pagesize = 0;
	kret = host_page_size (mach_host_self(), &pagesize);
	count = HOST_VM_INFO_COUNT;

	kret = host_statistics (mach_host_self(), HOST_VM_INFO,(host_info_t)&page_info, &count);
	return page_info.free_count * pagesize;
#elif defined(__WIN64__)
	MEMORYSTATUSEX memStatex;
	memStatex.dwLength = sizeof (memStatex);
	::GlobalMemoryStatusEx (&memStatex);
	return memStatex.ullAvailPhys;
#elif defined(__WIN32__)
	MEMORYSTATUS memStatus;
	memStatus.dwLength = sizeof(MEMORYSTATUS);
	::GlobalMemoryStatus(&memStatus);
	return memStatus.dwAvailPhys;
#elif defined(__SUN__) && defined(_SC_AVPHYS_PAGES)
	return sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE);
#elif defined(__FREEBSD__)
	int vm_vmtotal[] = { CTL_VM, VM_METER };
	struct vmtotal vmdata;

	size_t len = sizeof(vmdata);
	int result = sysctl(vm_vmtotal, sizeof(vm_vmtotal) / sizeof(*vm_vmtotal), &vmdata, &len, NULL, 0);
	if(result != 0) return 0;

	return vmdata.t_free * sysconf(_SC_PAGESIZE);
#elif defined(__linux__)

	// get it from /proc/meminfo
	FILE *fp = fopen("/proc/meminfo", "r");
	if ( fp )
	{
		unsigned long freeMem = 0;
		unsigned long buffersMem = 0;
		unsigned long cachedMem = 0;
		struct SearchTerm { const char* name; unsigned long* var; };
		SearchTerm terms[] = { {"MemFree:", &freeMem}, {"Buffers:", &buffersMem}, {"Cached:", &cachedMem} };

		char buf[1024];
		int n = fread(buf, sizeof(char), sizeof(buf) - 1, fp);
		buf[sizeof(buf)-1] = '\0';
		if(n > 0) {
			for(unsigned int i = 0; i < sizeof(terms) / sizeof(SearchTerm); ++i) {
				char* p = strstr(buf, terms[i].name);
				if(p) {
					p += strlen(terms[i].name);
					*terms[i].var = strtoul(p, NULL, 10);
				}
			}
		}

		fclose(fp);
		// it's written in KB in meminfo
		return ((size_t)freeMem + (size_t)buffersMem + (size_t)cachedMem) * 1024;
	}

	return 0;
#else
#warning No GetFreeSysMemory implementation for this arch/sys
	return 50 * 1024 * 1024; // return 50 MB (really randomly made up, but helps for cache system)
#endif
}

std::string GetDateTimeText()
{
	time_t t = time(NULL);

	if (t == (time_t)-1)
		return "TIME-ERROR1";

	char* timeCstr = ctime(&t);
	if(timeCstr == NULL)
		return "TIME-ERROR2";

	std::string timeStr(timeCstr);
	TrimSpaces(timeStr);
	return timeStr;
}

std::string GetDateTimeFilename()
{
	// Add date and server name to screenshot filename
	time_t curtime1 = time(NULL);
	if (curtime1 == (time_t)-1)
		return "TIME-ERROR1";
	struct tm *curtime = localtime(&curtime1);
	if (curtime == NULL)
		return "TIME-ERROR2";
	char filePrefixTime[200] = {0};
	strftime(filePrefixTime, sizeof(filePrefixTime), "%Y%m%d-%H%M", curtime);
	return filePrefixTime;
}

<|endoftext|>


<commit_before>#include "curlwebclient.h"

#include <curl/curl.h>

namespace lastpass
{

namespace
{

class CurlGlobalInitializer
{
public:
    CurlGlobalInitializer()
    {
        curl_global_init(CURL_GLOBAL_ALL);
    }

    ~CurlGlobalInitializer()
    {
        curl_global_cleanup();
    }
} curl_global_initializer;

}

std::string CurlWebClient::get(std::string const &url, std::map<std::string, std::string> const &values)
{
    return {};
}

std::string CurlWebClient::post(std::string const &url, std::map<std::string, std::string> const &values)
{
    return {};
}

}
<commit_msg>Curl wrapper<commit_after>#include "curlwebclient.h"

#include <curl/curl.h>

namespace lastpass
{

namespace
{

class CurlGlobalInitializer
{
public:
    CurlGlobalInitializer()
    {
        curl_global_init(CURL_GLOBAL_ALL);
    }

    ~CurlGlobalInitializer()
    {
        curl_global_cleanup();
    }
} curl_global_initializer;

class Curl
{
public:
    Curl(): curl_(curl_easy_init())
    {
        if (curl_ == nullptr)
            throw std::runtime_error("Failed to initialize cURL");
    }

    ~Curl()
    {
        curl_easy_cleanup(curl_);
    }

    operator CURL *() const
    {
        return curl_;
    }

private:
    CURL *curl_;

    // No copies
    Curl(Curl const &) = delete;
    Curl &operator =(Curl const &) = delete;
};

}

std::string CurlWebClient::get(std::string const &url, std::map<std::string, std::string> const &values)
{
    return {};
}

std::string CurlWebClient::post(std::string const &url, std::map<std::string, std::string> const &values)
{
    return {};
}

}
<|endoftext|>


<commit_before>/* parsing.hh -- parsers
 *
 * Copyright (C) 2018 Camille Scott
 * All rights reserved.
 *
 * This software may be modified and distributed under the terms
 * of the MIT license.  See the LICENSE file for details.
 */

#ifndef PARSING_HH
#define PARSING_HH

#include <string>
#include <utility>
#include <vector>

#include "oxli/read_parsers.hh"
#include "utils/stringutils.h"

using namespace oxli;
using namespace oxli:: read_parsers;

using namespace utils;

namespace boink {

using std::string;
using std::vector;
using std::pair;

struct ReadBundle {

    bool has_left;
    bool has_right;

    Read left;
    Read right;

};

bool check_char(const char c, const string against) {
    for (auto ag : against) {
        if (c == ag) {
            return true;
        }
    }
    return false;
}

pair<string, string> split_on_first(const string& name,
                                    const string delims=" \t") {
    string left = "";
    string right = "";
    for (size_t i = 0; i < name.length(); ++i) {
        const char c = name[i];
        if (left == "") {
            if (check_char(c, delims)) {
                left = name.substr(0, i);
            }
        } else {
            if (!check_char(c, delims)) {
                right = name.substr(i, name.length());
                break;
            }
        }
    }
    if (left == "") {
        left = name;
    }

    return std::make_pair(left, right);
}

bool check_is_pair(const string& left, const string& right) {
    auto left_split = split_on_first(left);
    auto right_split = split_on_first(right);

    if (StringUtils::endsWith(left_split.first, "/1") &&
        StringUtils::endsWith(right_split.first, "/2")) {

        auto left_sub = split_on_first(left_split.first, "/");
        auto right_sub = split_on_first(right_split.first, "/");

        if (left_sub.first != ""  && left_sub.first == right_sub.first) {
            return true;
        }
    } else if (left_split.first == right_split.first &&
               StringUtils::endsWith(left_split.second, "1:") &&
               StringUtils::endsWith(right_split.second, "2:")) {
        return true;
    } else if (left_split.first == right_split.first &&
               StringUtils::endsWith(left_split.second, "/1") &&
               StringUtils::endsWith(right_split.second, "/2")) {
        auto left_sub = split_on_first(left_split.second, "/");
        auto right_sub = split_on_first(right_split.second, "/");

        if (left_sub.first != "" && left_sub.first == right_sub.first) {
            return true;
        }
    }
    return false;
}

bool check_is_left(const string& name) {
    auto split = split_on_first(name);
    if (StringUtils::endsWith(split.first, "/1") ||
        StringUtils::endsWith(split.second, "1:") ||
        StringUtils::endsWith(split.second, "/1")) {
        return true;
    }
    return false;
}

bool check_is_right(const string& name) {
    auto split = split_on_first(name);
    if (StringUtils::endsWith(split.first, "/2") ||
        StringUtils::endsWith(split.second, "2:") ||
        StringUtils::endsWith(split.second, "/2")) {
        return true;
    }
    return false;
}

template <class ParserType = FastxReader>
class SplitPairedReader {

    ReadParserPtr<ParserType> left_parser;
    ReadParserPtr<ParserType> right_parser;
    uint32_t _min_length;
    bool     _force_name_match;
    uint64_t _n_reads;

    SplitPairedReader(const string &left,
                      const string &right,
                      uint32_t min_length=1,
                      bool force_name_match=false)
        : _min_length(min_length),
          _force_name_match(force_name_match) {

        left_parser = get_parser<ParserType>(left);
        right_parser = get_parser<ParserType>(right);
    }

    ReadBundle next() {
        ReadBundle result;
        try {
            result.left = left_parser->get_next_read();
            result.right = right_parser->get_next_read();
        } catch (NoMoreReadsAvailable) {
            result.has_left = false;
            result.has_right = false;
            return result;
        }

        result.left.set_clean_seq();
        result.right.set_clean_seq();
        result.has_left = true;
        result.has_right = true;

        if (_force_name_match) {
            if (check_is_pair(result.left.name, result.right.name)) {
                return result;
            } else {
                throw BoinkException("Unpaired reads");
            }
        }

        return result;
    }

    bool is_complete() const {
        if (left_parser->is_complete() != right_parser->is_complete()) {
            throw BoinkException("Mismatched split paired files.");
        }
        return left_parser->is_complete();
    }

};

}

#endif
<commit_msg>Support filter-length with Split Paired Reader<commit_after>/* parsing.hh -- parsers
 *
 * Copyright (C) 2018 Camille Scott
 * All rights reserved.
 *
 * This software may be modified and distributed under the terms
 * of the MIT license.  See the LICENSE file for details.
 */

#ifndef PARSING_HH
#define PARSING_HH

#include <string>
#include <utility>
#include <vector>

#include "oxli/read_parsers.hh"
#include "utils/stringutils.h"

using namespace oxli;
using namespace oxli:: read_parsers;

using namespace utils;

namespace boink {

using std::string;
using std::vector;
using std::pair;

struct ReadBundle {

    bool has_left;
    bool has_right;

    Read left;
    Read right;

};

bool check_char(const char c, const string against) {
    for (auto ag : against) {
        if (c == ag) {
            return true;
        }
    }
    return false;
}

pair<string, string> split_on_first(const string& name,
                                    const string delims=" \t") {
    string left = "";
    string right = "";
    for (size_t i = 0; i < name.length(); ++i) {
        const char c = name[i];
        if (left == "") {
            if (check_char(c, delims)) {
                left = name.substr(0, i);
            }
        } else {
            if (!check_char(c, delims)) {
                right = name.substr(i, name.length());
                break;
            }
        }
    }
    if (left == "") {
        left = name;
    }

    return std::make_pair(left, right);
}

bool check_is_pair(const string& left, const string& right) {
    auto left_split = split_on_first(left);
    auto right_split = split_on_first(right);

    if (StringUtils::endsWith(left_split.first, "/1") &&
        StringUtils::endsWith(right_split.first, "/2")) {

        auto left_sub = split_on_first(left_split.first, "/");
        auto right_sub = split_on_first(right_split.first, "/");

        if (left_sub.first != ""  && left_sub.first == right_sub.first) {
            return true;
        }
    } else if (left_split.first == right_split.first &&
               StringUtils::endsWith(left_split.second, "1:") &&
               StringUtils::endsWith(right_split.second, "2:")) {
        return true;
    } else if (left_split.first == right_split.first &&
               StringUtils::endsWith(left_split.second, "/1") &&
               StringUtils::endsWith(right_split.second, "/2")) {
        auto left_sub = split_on_first(left_split.second, "/");
        auto right_sub = split_on_first(right_split.second, "/");

        if (left_sub.first != "" && left_sub.first == right_sub.first) {
            return true;
        }
    }
    return false;
}

bool check_is_left(const string& name) {
    auto split = split_on_first(name);
    if (StringUtils::endsWith(split.first, "/1") ||
        StringUtils::endsWith(split.second, "1:") ||
        StringUtils::endsWith(split.second, "/1")) {
        return true;
    }
    return false;
}

bool check_is_right(const string& name) {
    auto split = split_on_first(name);
    if (StringUtils::endsWith(split.first, "/2") ||
        StringUtils::endsWith(split.second, "2:") ||
        StringUtils::endsWith(split.second, "/2")) {
        return true;
    }
    return false;
}

void filter_length(ReadBundle& bundle, uint32_t length) {
    if (bundle.left.sequence.length() < length) {
        bundle.has_left = false;
    }
    if (bundle.right.sequence.length() < length) {
        bundle.has_right = false;
    }
}

template <class ParserType = FastxReader>
class SplitPairedReader {

    ReadParserPtr<ParserType> left_parser;
    ReadParserPtr<ParserType> right_parser;
    uint32_t _min_length;
    bool     _force_name_match;
    uint64_t _n_reads;

    SplitPairedReader(const string &left,
                 const string &right,
                 uint32_t min_length=0,
                 bool force_name_match=false)
        : _min_length(min_length),
          _force_name_match(force_name_match) {

        left_parser = get_parser<ParserType>(left);
        right_parser = get_parser<ParserType>(right);
    }

    bool is_complete() const {
        if (left_parser->is_complete() != right_parser->is_complete()) {
            throw BoinkException("Mismatched split paired files.");
        }
        return left_parser->is_complete();
    }

    ReadBundle next() {
        ReadBundle result;
        try {
            result.left = this->left_parser->get_next_read();
            result.right = this->right_parser->get_next_read();
        } catch (NoMoreReadsAvailable) {
            result.has_left = false;
            result.has_right = false;
            return result;
        }

        result.left.set_clean_seq();
        result.right.set_clean_seq();
        result.has_left = true;
        result.has_right = true;

        if (this->_force_name_match) {
            if (!check_is_pair(result.left.name, result.right.name)) {
                throw BoinkException("Unpaired reads");
            }
        }

        if (this->_min_length > 0) {
            filter_length(result, this->_min_length);
        }

        return result;
    }
};

}

#endif
<|endoftext|>