<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/

#include "itkMinimumImageFilter.h"
#include "itkImageRegionIteratorWithIndex.h"
#include "itkTestingMacros.h"

int itkMinimumImageFilterTest( int, char* [] )
{

  // Define the dimension of the images
  const unsigned int Dimension = 3;

  typedef unsigned char PixelType;

  // Declare the types of the images
  typedef itk::Image< PixelType, Dimension >    ImageType;

  // Declare the type of the index to access images
  typedef itk::Index< Dimension >               IndexType;

  // Declare the type of the size
  typedef itk::Size< Dimension >                SizeType;

  // Declare the type of the Region
  typedef itk::ImageRegion< Dimension >         RegionType;

  // Declare the type for the MULTIPLY filter
  typedef itk::MinimumImageFilter< ImageType, ImageType,
    ImageType > MinimumFilterType;

  // Create two images
  ImageType::Pointer inputImageA = ImageType::New();
  ImageType::Pointer inputImageB = ImageType::New();

  // Define their size, and start index
  SizeType size;
  size[0] = 2;
  size[1] = 2;
  size[2] = 2;

  IndexType start;
  start[0] = 0;
  start[1] = 0;
  start[2] = 0;

  RegionType region;
  region.SetIndex( start );
  region.SetSize( size );

  // Initialize Image A
  inputImageA->SetLargestPossibleRegion( region );
  inputImageA->SetBufferedRegion( region );
  inputImageA->SetRequestedRegion( region );
  inputImageA->Allocate();

  // Initialize Image B
  inputImageB->SetLargestPossibleRegion( region );
  inputImageB->SetBufferedRegion( region );
  inputImageB->SetRequestedRegion( region );
  inputImageB->Allocate();

  // Define the pixel values for each image
  PixelType largePixelValue = 3.0;
  PixelType smallPixelValue = 2.0;

  // Declare Iterator types apropriated for each image
  typedef itk::ImageRegionIteratorWithIndex< ImageType > IteratorType;

  // Create one iterator for Image A (this is a light object)
  IteratorType it1( inputImageA, inputImageA->GetBufferedRegion() );

  // Initialize the content of Image A
  while( !it1.IsAtEnd() )
  {
    it1.Set( smallPixelValue );
    ++it1;
  }

  // Create one iterator for Image B (this is a light object)
  IteratorType it2( inputImageB, inputImageB->GetBufferedRegion() );

  // Initialize the content of Image B
  while( !it2.IsAtEnd() )
  {
    it2.Set( largePixelValue );
    ++it2;
  }

  // Create the filter
  MinimumFilterType::Pointer minimumImageFilter = MinimumFilterType::New();

  EXERCISE_BASIC_OBJECT_METHODS( minimumImageFilter, MinimumImageFilter,
    BinaryFunctorImageFilter);

  // Connect the input images
  minimumImageFilter->SetInput1( inputImageA );
  minimumImageFilter->SetInput2( inputImageB );

  // Get the Smart Pointer to the filter output
  ImageType::Pointer outputImage = minimumImageFilter->GetOutput();

  minimumImageFilter->SetFunctor( minimumImageFilter->GetFunctor() );

  // Execute the filter
  minimumImageFilter->Update();

  // Test some pixels in the result image
  // Note that we are not comparing the entirety of the filter output in order
  // to keep compile time as small as possible

  ImageType::IndexType pixelIndex = {{0, 1, 1}};

  TEST_EXPECT_EQUAL( outputImage->GetPixel( start ), smallPixelValue );
  TEST_EXPECT_EQUAL( outputImage->GetPixel( pixelIndex ), smallPixelValue );

  // All objects should be automatically destroyed at this point
  return EXIT_SUCCESS;

}
<commit_msg>COMP: Fix double to unsigned char conversion warning.<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/

#include "itkMinimumImageFilter.h"
#include "itkImageRegionIteratorWithIndex.h"
#include "itkTestingMacros.h"

int itkMinimumImageFilterTest( int, char* [] )
{

  // Define the dimension of the images
  const unsigned int Dimension = 3;

  typedef unsigned char PixelType;

  // Declare the types of the images
  typedef itk::Image< PixelType, Dimension >    ImageType;

  // Declare the type of the index to access images
  typedef itk::Index< Dimension >               IndexType;

  // Declare the type of the size
  typedef itk::Size< Dimension >                SizeType;

  // Declare the type of the Region
  typedef itk::ImageRegion< Dimension >         RegionType;

  // Declare the type for the MULTIPLY filter
  typedef itk::MinimumImageFilter< ImageType, ImageType,
    ImageType > MinimumFilterType;

  // Create two images
  ImageType::Pointer inputImageA = ImageType::New();
  ImageType::Pointer inputImageB = ImageType::New();

  // Define their size, and start index
  SizeType size;
  size[0] = 2;
  size[1] = 2;
  size[2] = 2;

  IndexType start;
  start[0] = 0;
  start[1] = 0;
  start[2] = 0;

  RegionType region;
  region.SetIndex( start );
  region.SetSize( size );

  // Initialize Image A
  inputImageA->SetLargestPossibleRegion( region );
  inputImageA->SetBufferedRegion( region );
  inputImageA->SetRequestedRegion( region );
  inputImageA->Allocate();

  // Initialize Image B
  inputImageB->SetLargestPossibleRegion( region );
  inputImageB->SetBufferedRegion( region );
  inputImageB->SetRequestedRegion( region );
  inputImageB->Allocate();

  // Define the pixel values for each image
  PixelType largePixelValue = 3;
  PixelType smallPixelValue = 2;

  // Declare Iterator types apropriated for each image
  typedef itk::ImageRegionIteratorWithIndex< ImageType > IteratorType;

  // Create one iterator for Image A (this is a light object)
  IteratorType it1( inputImageA, inputImageA->GetBufferedRegion() );

  // Initialize the content of Image A
  while( !it1.IsAtEnd() )
  {
    it1.Set( smallPixelValue );
    ++it1;
  }

  // Create one iterator for Image B (this is a light object)
  IteratorType it2( inputImageB, inputImageB->GetBufferedRegion() );

  // Initialize the content of Image B
  while( !it2.IsAtEnd() )
  {
    it2.Set( largePixelValue );
    ++it2;
  }

  // Create the filter
  MinimumFilterType::Pointer minimumImageFilter = MinimumFilterType::New();

  EXERCISE_BASIC_OBJECT_METHODS( minimumImageFilter, MinimumImageFilter,
    BinaryFunctorImageFilter);

  // Connect the input images
  minimumImageFilter->SetInput1( inputImageA );
  minimumImageFilter->SetInput2( inputImageB );

  // Get the Smart Pointer to the filter output
  ImageType::Pointer outputImage = minimumImageFilter->GetOutput();

  minimumImageFilter->SetFunctor( minimumImageFilter->GetFunctor() );

  // Execute the filter
  minimumImageFilter->Update();

  // Test some pixels in the result image
  // Note that we are not comparing the entirety of the filter output in order
  // to keep compile time as small as possible

  ImageType::IndexType pixelIndex = {{0, 1, 1}};

  TEST_EXPECT_EQUAL( outputImage->GetPixel( start ), smallPixelValue );
  TEST_EXPECT_EQUAL( outputImage->GetPixel( pixelIndex ), smallPixelValue );

  // All objects should be automatically destroyed at this point
  return EXIT_SUCCESS;

}
<|endoftext|>


<commit_before>#include "../../local/include/gtest/gtest.h"

#include <vector>

// uncomment to use threads
//#define THREADED

#ifdef THREADED

// Tron
//#define NUM_CORES 4
// Clue
#define NUM_CORES 12

#include <thread>
#include <future>

#endif  // THREADED

#include "genetic.h"
#include "genetic_circuit.h"
#include "circuit.h"
#include "utility.h"

TEST(InnocuousAttempt, XOR) {
  BooleanTable expected_o = {{false},
                             {true},
                             {false},
                             {true}};
  BooleanTable expected_o = {{false},
                             {true},
                             {true},
                             {false}};

  std::mt19937 rand(std::random_device{}());
  // std::minstd_rand0 rand(std::random_device{}());
  GeneticCircuit* c = new GeneticCircuit(2, 1, &rand);
  BooleanTable answer = c->evaluateAllInputs();
  int i = 0;

  // #ifdef THREADED
  // std::vector<std::future<BooleanTable>> boolean_table_futures;
  // #endif THREADED

  while ((answer != expected_o) || (answer != expected_o_bar)) {
    // #ifdef THREADED
    // for (int i = 0; i < (NUM_CORES - 1); ++i) {
    //   boolean_table_futures.push_back(
    //       std::async(std::launch::async, , points));
    // }
    // #endif THREADED

    // std::vector<Path> paths;  // vector of possible paths
    // // Calculate a path on main thread while waiting for other threads
    // // If we're doing more than 1 set, do NUM_SETS random path calculations
    // on
    // // main thread
    // for (int i = 0; i < NUM_SETS; i++) {
    //   paths.push_back(FindRandomPath(points));
    // }

    // // Get Paths from threads
    // for (auto& pathfuture : pathfutures) {
    //   paths.push_back(pathfuture.get());
    // }

    delete c;
    c = new GeneticCircuit(2, 1, &rand);
    std::cerr << "Iteration: " + std::to_string(++i) << std::endl;
    // std::cerr << *c << std::endl;
    answer = c->evaluateAllInputs();
  }
}

TEST(InnocuousAttempt, FullAdder) {
  BooleanTable expected_o = {{false, false},
                             {false, true},
                             {false, true},
                             {true, false},
                             {false, true},
                             {true, false},
                             {true, false},
                             {true, true}};
  BooleanTable expected_o_bar = {{false, false},
                                 {true, false},
                                 {true, false},
                                 {false, true},
                                 {true, false},
                                 {false, true},
                                 {false, true},
                                 {true, true}};
  std::mt19937 rand(std::random_device{}());
  // std::minstd_rand0 rand(std::random_device{}());
  GeneticCircuit* c = new GeneticCircuit(3, 2, &rand);
  BooleanTable answer = c->evaluateAllInputs();
  int i = 0;

  // #ifdef THREADED
  // std::vector<std::future<BooleanTable>> boolean_table_futures;
  // #endif THREADED

  while ((answer != expected_o) || (answer != expected_o_bar)) {
    // #ifdef THREADED
    // for (int i = 0; i < (NUM_CORES - 1); ++i) {
    //   boolean_table_futures.push_back(
    //       std::async(std::launch::async, , points));
    // }
    // #endif THREADED

    // std::vector<Path> paths;  // vector of possible paths
    // // Calculate a path on main thread while waiting for other threads
    // // If we're doing more than 1 set, do NUM_SETS random path calculations
    // on
    // // main thread
    // for (int i = 0; i < NUM_SETS; i++) {
    //   paths.push_back(FindRandomPath(points));
    // }

    // // Get Paths from threads
    // for (auto& pathfuture : pathfutures) {
    //   paths.push_back(pathfuture.get());
    // }

    delete c;
    c = new GeneticCircuit(3, 2, &rand);
    std::cerr << "Iteration: " + std::to_string(++i) << std::endl;
    // std::cerr << *c << std::endl;
    answer = c->evaluateAllInputs();
  }
}

// TEST(InnocuousAttempt, InvertInputs) {
//   BooleanTable expected_o = {{true, true, true},
//                              {true, true, false},
//                              {true, false, true},
//                              {true, false, false},
//                              {false, true, true},
//                              {false, true, false},
//                              {false, false, true},
//                              {false, false, false}};
//   std::mt19937 rand(std::random_device{}());
//   // std::minstd_rand0 rand(std::random_device{}());
//   GeneticCircuit* c = new GeneticCircuit(3, 3, &rand);
//   while (c->evaluateAllInputs() != expected_o) {
//     delete c;
//     c = new GeneticCircuit(3, 3, &rand);
//     std::cerr << *c << std::endl;
//   }
// }
<commit_msg>fixed expected_o_bar name<commit_after>#include "../../local/include/gtest/gtest.h"

#include <vector>

// uncomment to use threads
//#define THREADED

#ifdef THREADED

// Tron
//#define NUM_CORES 4
// Clue
#define NUM_CORES 12

#include <thread>
#include <future>

#endif  // THREADED

#include "genetic.h"
#include "genetic_circuit.h"
#include "circuit.h"
#include "utility.h"

TEST(InnocuousAttempt, XOR) {
  BooleanTable expected_o = {{false}, {true}, {false}, {true}};
  BooleanTable expected_o_bar = {{false}, {true}, {true}, {false}};

  std::mt19937 rand(std::random_device{}());
  // std::minstd_rand0 rand(std::random_device{}());
  GeneticCircuit* c = new GeneticCircuit(2, 1, &rand);
  BooleanTable answer = c->evaluateAllInputs();
  int i = 0;

  // #ifdef THREADED
  // std::vector<std::future<BooleanTable>> boolean_table_futures;
  // #endif THREADED

  while ((answer != expected_o) || (answer != expected_o_bar)) {
    // #ifdef THREADED
    // for (int i = 0; i < (NUM_CORES - 1); ++i) {
    //   boolean_table_futures.push_back(
    //       std::async(std::launch::async, , points));
    // }
    // #endif THREADED

    // std::vector<Path> paths;  // vector of possible paths
    // // Calculate a path on main thread while waiting for other threads
    // // If we're doing more than 1 set, do NUM_SETS random path calculations
    // on
    // // main thread
    // for (int i = 0; i < NUM_SETS; i++) {
    //   paths.push_back(FindRandomPath(points));
    // }

    // // Get Paths from threads
    // for (auto& pathfuture : pathfutures) {
    //   paths.push_back(pathfuture.get());
    // }

    delete c;
    c = new GeneticCircuit(2, 1, &rand);
    std::cerr << "Iteration: " + std::to_string(++i) << std::endl;
    // std::cerr << *c << std::endl;
    answer = c->evaluateAllInputs();
  }
}

TEST(InnocuousAttempt, FullAdder) {
  BooleanTable expected_o = {{false, false},
                             {false, true},
                             {false, true},
                             {true, false},
                             {false, true},
                             {true, false},
                             {true, false},
                             {true, true}};
  BooleanTable expected_o_bar = {{false, false},
                                 {true, false},
                                 {true, false},
                                 {false, true},
                                 {true, false},
                                 {false, true},
                                 {false, true},
                                 {true, true}};
  std::mt19937 rand(std::random_device{}());
  // std::minstd_rand0 rand(std::random_device{}());
  GeneticCircuit* c = new GeneticCircuit(3, 2, &rand);
  BooleanTable answer = c->evaluateAllInputs();
  int i = 0;

  // #ifdef THREADED
  // std::vector<std::future<BooleanTable>> boolean_table_futures;
  // #endif THREADED

  while ((answer != expected_o) || (answer != expected_o_bar)) {
    // #ifdef THREADED
    // for (int i = 0; i < (NUM_CORES - 1); ++i) {
    //   boolean_table_futures.push_back(
    //       std::async(std::launch::async, , points));
    // }
    // #endif THREADED

    // std::vector<Path> paths;  // vector of possible paths
    // // Calculate a path on main thread while waiting for other threads
    // // If we're doing more than 1 set, do NUM_SETS random path calculations
    // on
    // // main thread
    // for (int i = 0; i < NUM_SETS; i++) {
    //   paths.push_back(FindRandomPath(points));
    // }

    // // Get Paths from threads
    // for (auto& pathfuture : pathfutures) {
    //   paths.push_back(pathfuture.get());
    // }

    delete c;
    c = new GeneticCircuit(3, 2, &rand);
    std::cerr << "Iteration: " + std::to_string(++i) << std::endl;
    // std::cerr << *c << std::endl;
    answer = c->evaluateAllInputs();
  }
}

// TEST(InnocuousAttempt, InvertInputs) {
//   BooleanTable expected_o = {{true, true, true},
//                              {true, true, false},
//                              {true, false, true},
//                              {true, false, false},
//                              {false, true, true},
//                              {false, true, false},
//                              {false, false, true},
//                              {false, false, false}};
//   std::mt19937 rand(std::random_device{}());
//   // std::minstd_rand0 rand(std::random_device{}());
//   GeneticCircuit* c = new GeneticCircuit(3, 3, &rand);
//   while (c->evaluateAllInputs() != expected_o) {
//     delete c;
//     c = new GeneticCircuit(3, 3, &rand);
//     std::cerr << *c << std::endl;
//   }
// }
<|endoftext|>


<commit_before>#include <stdio.h>
#include <limits.h>

#include <vector>
#include <string>
#include <iostream>

#include "api/BamReader.h"
#include "api/BamWriter.h"
#include "../OutSources/fasta/Fasta.h"
#include "../OutSources/stripedSW/ssw_cpp.h"

using namespace std;

const StripedSmithWaterman::Filter kFilter(false, false, 0, 32467);
const int kAlignmentMapSize = 10000;

struct Alignment {
  BamTools::BamAlignment bam_alignment;
  bool hit_insertion;
  string ins_prefix;

  Alignment()
      : bam_alignment()
      , hit_insertion(false)
      , ins_prefix()
  {}

  void Clear() {
    hit_insertion = false;
    ins_prefix.clear();
  }
};

void ShowHelp() {
  fprintf(stderr, "Usage: tangram_bam <in_bam> <ref_fa> <out_bam>\n\n");
  fprintf(stderr, "tangram_bam will generate ZA tags for bams");
  fprintf(stderr, " that are not generated by MOSAIK.\n");

  fprintf(stderr, "<ref_fa> is a fasta file containing insertion sequences\n");
  fprintf(stderr, " that we are going to detect them.\n");
}

bool OpenBams(
    const string& infilename,
    const string& outfilename,
    const int& no_arg,
    char** arguments,
    BamTools::BamReader* reader,
    BamTools::BamWriter* writer) {

  reader->Open(infilename);
  if (!reader->IsOpen()) {
    fprintf(stderr, "ERROR: The bam file, %s, cannot be open\n", infilename.c_str());
    return false;
  }

  // Load header and ref
  string header = reader->GetHeaderText();
  size_t pos1 = header.find("SO:");
  if (pos1 != string::npos) {
    size_t pos2 = header.find("SO:queryname");
    if (pos2 != string::npos) header.replace(pos2, 12, "SO:unsorted");
    pos2 = header.find("SO:coordinate");
    if (pos2 != string::npos) header.replace(pos2, 13, "SO:unsorted");
  }
  header += "@PG\tID:tangram_bam\tCL:";
  for (int i = 0; i < no_arg; ++i) {
    header += arguments[i];
  }
  header += "\n";
  BamTools::RefVector ref = reader->GetReferenceData();

  if (!writer->Open(outfilename, header, ref)) {
    fprintf(stderr, "ERROR: The bam file, %s, cannot be open\n", outfilename.c_str());
    reader->Close();
    return false;
  }

  return true;
}

inline bool LoadReference(const char* fa, FastaReference* fasta) {
  string filename = fa;
  fasta->open(filename);

  return true;
}

bool BuildAligner(
    FastaReference* fasta,
    vector<StripedSmithWaterman::Aligner*>* aligners,
    vector<string>* ref_names) {
  for (vector<string>::const_iterator ite = fasta->index->sequenceNames.begin();
       ite != fasta->index->sequenceNames.end(); ++ite) {
    StripedSmithWaterman::Aligner* al_ptr = new StripedSmithWaterman::Aligner;
    al_ptr->SetReferenceSequence(fasta->getSequence(*ite).c_str(),
                                 fasta->sequenceLength(*ite));
    aligners->push_back(al_ptr);
    ref_names->push_back(*ite);
  }

  return true;
}

void GetReverseComplement(const string& query, string* reverse) {
  reverse->clear();

  for (string::const_reverse_iterator ite = query.rbegin(); ite != query.rend(); ++ite) {
    switch(*ite) {
      case 'A': *reverse += 'T'; break;
      case 'C': *reverse += 'G'; break;
      case 'G': *reverse += 'C'; break;
      case 'T': *reverse += 'A'; break;
      default: *reverse += 'N';
    }
  }
}

void Align(
    const string& query,
    const vector<StripedSmithWaterman::Aligner*>& aligners,
    vector<StripedSmithWaterman::Alignment>* alignments) {
  for (unsigned int i = 0; i < aligners.size(); ++i) {
    (*alignments)[i].Clear();
    aligners[i]->Align(query.c_str(), kFilter, &((*alignments)[i]));
  }
}

int PickBestAlignment(
    const int& request_score,
    const vector<StripedSmithWaterman::Alignment>& alignments) {

  int sw_score_max = INT_MIN;
  int index = 0;
  for (unsigned int i = 0; i < alignments.size(); ++i) {
    if (alignments[i].sw_score > sw_score_max) {
      sw_score_max = alignments[i].sw_score;
      index = i;
    }
  }

  if (sw_score_max > request_score) return index;
  else return -1;
}

void GetZa(const Alignment& al, const Alignment& mate, string* za) {
  const bool mate1 = al.bam_alignment.IsFirstMate();
  Alignment const *mate1_ptr, *mate2_ptr;

  if (mate1) {
    *za = "<@;";
    mate1_ptr = &al;
    mate2_ptr = &mate;
  } else {
    *za = "<&;";
    mate1_ptr = &mate;
    mate2_ptr = &al;
  }

  *za += (std::to_string(mate1_ptr->bam_alignment.MapQuality) + ";;"
          + (mate1_ptr->hit_insertion ? mate1_ptr->ins_prefix : "")
	  + ";1;");

  if (mate1) {
    *za += ";><&;";
  } else {
    *za += ";><@;";
  }

  *za += (std::to_string(mate2_ptr->bam_alignment.MapQuality) + ";;"
          + (mate2_ptr->hit_insertion ? mate2_ptr->ins_prefix : "")
	  + ";1;;>");

}

void WriteAlignment(
    const Alignment& mate,
    Alignment* al,
    BamTools::BamWriter* writer) {
  string za;
  GetZa(*al, mate, &za);

  al->bam_alignment.AddTag("ZA","Z",za);

  writer->SaveAlignment(al->bam_alignment);
}

void WriteAlignment(map<string, Alignment>* al_map_ite,
                    BamTools::BamWriter* writer) {
  for (map<string, Alignment>::iterator ite = al_map_ite->begin();
       ite != al_map_ite->end(); ++ite) {
    Alignment* al = &(ite->second);
    string za;
    if (al->bam_alignment.IsPaired()) {
      if (al->bam_alignment.IsFirstMate()) {
        za = "<@;" + std::to_string(al->bam_alignment.MapQuality) + ";;"
             + (al->hit_insertion ? al->ins_prefix : "") + ";1;;>"
	     + "<&;;;;;;>";
      } else {
        za = "<&;;;;;;><@;" + std::to_string(al->bam_alignment.MapQuality) + ";;"
             + (al->hit_insertion ? al->ins_prefix : "") + ";1;;>";
      }
    } else {
      za = "<@;" + std::to_string(al->bam_alignment.MapQuality) + ";;"
           + (al->hit_insertion ? al->ins_prefix : "") + ";1;;>";
    }

    al->bam_alignment.AddTag("ZA","Z",za);
    writer->SaveAlignment(al->bam_alignment);
  }
}

void StoreAlignment(
    Alignment* al,
    map<string, Alignment> *al_map_cur,
    map<string, Alignment> *al_map_pre,
    BamTools::BamWriter* writer) {
  if ((static_cast<int>(al_map_cur->size()) > kAlignmentMapSize)) {
    WriteAlignment(al_map_pre, writer);
    al_map_pre->clear();
    map<string, Alignment> *tmp = al_map_pre;
    al_map_pre = al_map_cur;
    al_map_cur = tmp;

  }

  map<string, Alignment>::iterator ite_cur = al_map_cur->find(al->bam_alignment.Name);
  if (ite_cur == al_map_cur->end()) {
    if (!al_map_pre) {
      map<string, Alignment>::iterator ite_pre = al_map_pre->find(al->bam_alignment.Name);
      if (ite_pre == al_map_pre->end()) { // al is not found in cur or pre either
        (*al_map_cur)[al->bam_alignment.Name] = *al;
      } else { // find the mate in al_map_pre
        WriteAlignment(ite_pre->second, al, writer);
        WriteAlignment(*al, &(ite_pre->second), writer);
        al_map_pre->erase(ite_pre);
      }
    } else { // al is not found in cur and pre is NULL
      (*al_map_cur)[al->bam_alignment.Name] = *al;
    }
  } else { // find the mate in al_map_cur
    WriteAlignment(ite_cur->second, al, writer);
    WriteAlignment(*al, &(ite_cur->second), writer);
    al_map_cur->erase(ite_cur);
  }

}

int main(int argc, char** argv) {
  if (argc != 4) {
    ShowHelp();
    return 1;
  }

  // Open input bam
  string infilename = argv[1];
  string outfilename = argv[3];
  BamTools::BamReader reader;
  BamTools::BamWriter writer;
  if (!OpenBams(infilename, outfilename, argc, argv, &reader, &writer)) return 1;

  // Open fasta
  FastaReference fasta;
  LoadReference(argv[2], &fasta);

  // Build SSW aligners for every reference in fasta
  vector<StripedSmithWaterman::Aligner*> aligners;
  vector<string> ref_names;
  BuildAligner(&fasta, &aligners, &ref_names);

  // Prepare alignment vector
  vector<StripedSmithWaterman::Alignment> alignments(aligners.size());

  // CORE ALGORITHM
  BamTools::BamAlignment bam_alignment;
  map<string, Alignment> al_map1, al_map2;
  map<string, Alignment> *al_map_cur = &al_map1, *al_map_pre = &al_map2;
  Alignment al;
  while (reader.GetNextAlignment(bam_alignment)) {
    Align(bam_alignment.QueryBases, aligners, &alignments);
    int index = PickBestAlignment(bam_alignment.Length, alignments);
    if (index == -1) {
      string reverse;
      GetReverseComplement(bam_alignment.QueryBases, &reverse);
      Align(reverse, aligners, &alignments);
      index = PickBestAlignment(bam_alignment.Length, alignments);
    }
    al.Clear();
    al.bam_alignment = bam_alignment;
    al.hit_insertion = (index == -1) ? false: true;
    al.ins_prefix    = (index == -1) ? "" : ref_names[index].substr(8,2);
    StoreAlignment(&al, al_map_cur, al_map_pre, &writer);
  }

  // Close
  WriteAlignment(&al_map1, &writer);
  WriteAlignment(&al_map2, &writer);
  al_map1.clear();
  al_map2.clear();
  reader.Close();
  writer.Close();
  for (vector<StripedSmithWaterman::Aligner*>::iterator ite = aligners.begin();
       ite != aligners.end(); ++ite)
    free(*ite);
}
<commit_msg>Tangram_bam concatenates special references for ssw<commit_after>#include "tangram_bam.h"
#include <stdio.h>
#include <limits.h>
#include <getopt.h>

#include <vector>
#include <string>
#include <iostream>

#include "api/BamReader.h"
#include "api/BamWriter.h"
#include "../OutSources/fasta/Fasta.h"
#include "../OutSources/stripedSW/ssw_cpp.h"

using namespace std;

void ShowHelp() {
  fprintf(stderr, "Usage: tangram_bam <in_bam> <ref_fa> <out_bam>\n\n");
  fprintf(stderr, "tangram_bam will generate ZA tags for bams");
  fprintf(stderr, " that are not generated by MOSAIK.\n");

  fprintf(stderr, "<ref_fa> is a fasta file containing insertion sequences\n");
  fprintf(stderr, " that we are going to detect them.\n");
}

bool OpenBams(
    const string& infilename,
    const string& outfilename,
    const string& command_line,
    BamTools::BamReader* reader,
    BamTools::BamWriter* writer) {

  reader->Open(infilename);
  if (!reader->IsOpen()) {
    fprintf(stderr, "ERROR: The bam file, %s, cannot be open\n", infilename.c_str());
    return false;
  }

  // Load header and ref
  string header = reader->GetHeaderText();
  size_t pos1 = header.find("SO:");
  if (pos1 != string::npos) {
    size_t pos2 = header.find("SO:queryname");
    if (pos2 != string::npos) header.replace(pos2, 12, "SO:unsorted");
    pos2 = header.find("SO:coordinate");
    if (pos2 != string::npos) header.replace(pos2, 13, "SO:unsorted");
  }
  header += "@PG\tID:tangram_bam\tCL:";
  header += (command_line + '\n');
  BamTools::RefVector ref = reader->GetReferenceData();

  if (!writer->Open(outfilename, header, ref)) {
    fprintf(stderr, "ERROR: The bam file, %s, cannot be open\n", outfilename.c_str());
    reader->Close();
    return false;
  }

  return true;
}

inline bool LoadReference(const char* fa, FastaReference* fasta) {
  string filename = fa;
  fasta->open(filename);

  return true;
}

bool ConcatenateSpecialReference(
    FastaReference* fasta,
    SpecialReference* s_ref) {
  int total_len = 0;
  for (vector<string>::const_iterator ite = fasta->index->sequenceNames.begin();
       ite != fasta->index->sequenceNames.end(); ++ite) {
    s_ref->concatnated += fasta->getSequence(*ite).c_str();
    s_ref->ref_lens.push_back(fasta->sequenceLength(*ite));
    s_ref->ref_names.push_back(*ite);
    total_len += fasta->sequenceLength(*ite);
  }

  s_ref->concatnated_len = total_len;

  return true;
}

void GetReverseComplement(const string& query, string* reverse) {
  reverse->clear();

  for (string::const_reverse_iterator ite = query.rbegin(); ite != query.rend(); ++ite) {
    switch(*ite) {
      case 'A': *reverse += 'T'; break;
      case 'C': *reverse += 'G'; break;
      case 'G': *reverse += 'C'; break;
      case 'T': *reverse += 'A'; break;
      default: *reverse += 'N';
    }
  }
}

void Align(
    const string& query,
    const StripedSmithWaterman::Aligner& aligner,
    StripedSmithWaterman::Alignment* alignment) {

    alignment->Clear();
    aligner.Align(query.c_str(), kFilter, alignment);
}

void GetZa(const Alignment& al, const Alignment& mate, string* za) {
  const bool mate1 = al.bam_alignment.IsFirstMate();
  Alignment const *mate1_ptr, *mate2_ptr;

  if (mate1) {
    *za = "<@;";
    mate1_ptr = &al;
    mate2_ptr = &mate;
  } else {
    *za = "<&;";
    mate1_ptr = &mate;
    mate2_ptr = &al;
  }

  *za += (std::to_string(mate1_ptr->bam_alignment.MapQuality) + ";;"
          + (mate1_ptr->hit_insertion ? mate1_ptr->ins_prefix : "")
	  + ";1;");

  if (mate1) {
    *za += ";><&;";
  } else {
    *za += ";><@;";
  }

  *za += (std::to_string(mate2_ptr->bam_alignment.MapQuality) + ";;"
          + (mate2_ptr->hit_insertion ? mate2_ptr->ins_prefix : "")
	  + ";1;;>");

}

void WriteAlignment(
    const bool& add_za,
    const Alignment& mate,
    Alignment* al,
    BamTools::BamWriter* writer) {

  if (add_za) {
    string za;
    GetZa(*al, mate, &za);
    al->bam_alignment.AddTag("ZA","Z",za);
  }

  writer->SaveAlignment(al->bam_alignment);
}

void WriteAlignment(const bool& add_za,
                    map<string, Alignment>* al_map_ite,
                    BamTools::BamWriter* writer) {

  for (map<string, Alignment>::iterator ite = al_map_ite->begin();
       ite != al_map_ite->end(); ++ite) {
    Alignment* al = &(ite->second);
    if (add_za) {
      string za;
      if (al->bam_alignment.IsPaired()) { // paired-end read
        if (al->bam_alignment.IsFirstMate()) {
          za = "<@;" + std::to_string(al->bam_alignment.MapQuality) + ";;"
               + (al->hit_insertion ? al->ins_prefix : "") + ";1;;>"
	       + "<&;0;;;0;;>";
        } else {
          za = "<&;0;;;0;;><@;" + std::to_string(al->bam_alignment.MapQuality) + ";;"
               + (al->hit_insertion ? al->ins_prefix : "") + ";1;;>";
        }
      } else { // sinle-end read
        za = "<@;" + std::to_string(al->bam_alignment.MapQuality) + ";;"
             + (al->hit_insertion ? al->ins_prefix : "") + ";1;;>";
      }

      al->bam_alignment.AddTag("ZA","Z",za);
    }

    writer->SaveAlignment(al->bam_alignment);
  }
}

// Return true if an alignment contains too many soft clips
inline bool IsTooManyClips (const BamTools::BamAlignment& al) {
  if (al.CigarData.empty()) return true;

  int clip = 0;
  if ((al.CigarData.begin())->Type == 'S') clip += (al.CigarData.begin())->Length;
  if ((al.CigarData.rbegin())->Type == 'S') clip += (al.CigarData.rbegin())->Length;

  if (clip > (al.Length * kSoftClipRate)) return true;
  else return false;
}

inline void MarkAsUnmapped (BamTools::BamAlignment* al, BamTools::BamAlignment* mate) {
  const bool al_unmapped   = IsTooManyClips(*al);
  const bool mate_unmapped = IsTooManyClips(*mate);

  if (!al_unmapped && !mate_unmapped) {
    // nothing
  } else {
    al->SetIsMapped(!al_unmapped);
    mate->SetIsMapped(!mate_unmapped);
    al->SetIsMateMapped(!mate_unmapped);
    mate->SetIsMateMapped(!al_unmapped);
  }
}

void StoreAlignment(
    const bool& add_za,
    Alignment* al,
    map<string, Alignment> *al_map_cur,
    map<string, Alignment> *al_map_pre,
    BamTools::BamWriter* writer) {
  // Clear up the buffers once the al_map_cur buffer is full
  // 1. Clear up al_map_pre
  // 2. move al_map_cur to al_map_pre
  if ((static_cast<int>(al_map_cur->size()) > kAlignmentMapSize)) {
    WriteAlignment(add_za, al_map_pre, writer);
    al_map_pre->clear();
    map<string, Alignment> *tmp = al_map_pre;
    al_map_pre = al_map_cur;
    al_map_cur = tmp;
  }

  map<string, Alignment>::iterator ite_cur = al_map_cur->find(al->bam_alignment.Name);
  if (ite_cur == al_map_cur->end()) {
    if (!al_map_pre) {
      map<string, Alignment>::iterator ite_pre = al_map_pre->find(al->bam_alignment.Name);
      if (ite_pre == al_map_pre->end()) { // al is not found in cur or pre either
        (*al_map_cur)[al->bam_alignment.Name] = *al;
      } else { // find the mate in al_map_pre
        MarkAsUnmapped(&(al->bam_alignment), &(ite_pre->second.bam_alignment));
	WriteAlignment(add_za, ite_pre->second, al, writer);
        WriteAlignment(add_za, *al, &(ite_pre->second), writer);
        al_map_pre->erase(ite_pre);
      }
    } else { // al is not found in cur and pre is NULL
      (*al_map_cur)[al->bam_alignment.Name] = *al;
    }
  } else { // find the mate in al_map_cur
    MarkAsUnmapped(&(al->bam_alignment), &(ite_cur->second.bam_alignment));
    WriteAlignment(add_za, ite_cur->second, al, writer);
    WriteAlignment(add_za, *al, &(ite_cur->second), writer);
    al_map_cur->erase(ite_cur);
  }

}

bool ParseArguments(const int argc, char* const * argv, Param* param) {
  if (argc == 1) { // no argument
    ShowHelp();
    return false;
  }

  // record command line
  param->command_line = argv[0];
  for ( int i = 1; i < argc; ++i ) {
    param->command_line += " ";
    param->command_line += argv[i];
  }

  const char *short_option = "hi:o:r:z";
  const struct option long_option[] = {
    {"help", no_argument, NULL, 'h'},
    {"input", required_argument, NULL, 'i'},
    {"output", required_argument, NULL, 'o'},
    {"ref", required_argument, NULL, 'r'},
    {"no-za-add", no_argument, NULL, 'z'},

    {0, 0, 0, 0}
  };

  int c = 0;
  bool show_help = false;
  while (true) {
    int option_index = 0;
    c = getopt_long(argc, argv, short_option, long_option, &option_index);

    if (c == -1) // end of options
      break;

    switch (c) {
      case 'h': show_help = true; break;
      case 'i': param->in_bam = optarg; break;
      case 'o': param->out_bam = optarg; break;
      case 'r': param->ref_fasta = optarg; break;
      case 'z': param->za_add = false; break;
    }
  }

  if (show_help || param->in_bam.empty()
   || param->out_bam.empty() || param->ref_fasta.empty()) {
    ShowHelp();
    return false;
  }

  return true;
}

int PickBestAlignment(const int& request_score,
                      const StripedSmithWaterman::Alignment& alignment,
		      const SpecialReference& s_ref) {
  if (alignment.sw_score < request_score) {
    return -1; // no proper alignment is found
  } else {
    int accu_len = 0;
    for (unsigned int i = 0; i < s_ref.ref_lens.size(); ++i) {
      accu_len += s_ref.ref_lens[i];
      if (alignment.ref_begin < accu_len) {
        if (alignment.ref_end < accu_len) return i;
	else return -1;
      }
    }
  }

  return -1;
}

int main(int argc, char** argv) {
  Param param;

  if (!ParseArguments(argc, argv, &param)) return 1;

  // Open input bam
  string infilename = param.in_bam;
  string outfilename = param.out_bam;
  BamTools::BamReader reader;
  BamTools::BamWriter writer;
  if (!OpenBams(infilename, outfilename, param.command_line, &reader, &writer)) return 1;

  // Open fasta
  FastaReference fasta;
  LoadReference(param.ref_fasta.c_str(), &fasta);

  // Build SSW aligners for every reference in fasta
  SpecialReference s_ref;
  ConcatenateSpecialReference(&fasta, &s_ref);

  // Build SSW aligner
  StripedSmithWaterman::Aligner aligner;
  aligner.SetReferenceSequence(s_ref.concatnated.c_str(), s_ref.concatnated_len);

  // CORE ALGORITHM
  BamTools::BamAlignment bam_alignment;
  map<string, Alignment> al_map1, al_map2;
  map<string, Alignment> *al_map_cur = &al_map1, *al_map_pre = &al_map2;
  StripedSmithWaterman::Alignment alignment;
  Alignment al;
  while (reader.GetNextAlignment(bam_alignment)) {
    int index = -1;
    if (param.za_add) {
      Align(bam_alignment.QueryBases, aligner, &alignment);
      index = PickBestAlignment(bam_alignment.Length, alignment, s_ref);
      if (index == -1) { // try the reverse complement sequences
        string reverse;
        GetReverseComplement(bam_alignment.QueryBases, &reverse);
        Align(reverse, aligner, &alignment);
        index = PickBestAlignment(bam_alignment.Length, alignment, s_ref);
      }
    }
    al.Clear();
    al.bam_alignment = bam_alignment;
    al.hit_insertion = (index == -1) ? false: true;
    al.ins_prefix    = (index == -1) ? "" : s_ref.ref_names[index].substr(8,2);
    StoreAlignment(param.za_add, &al, al_map_cur, al_map_pre, &writer);
  }

  // Close
  WriteAlignment(param.za_add, &al_map1, &writer);
  WriteAlignment(param.za_add, &al_map2, &writer);
  al_map1.clear();
  al_map2.clear();
  reader.Close();
  writer.Close();
}
<|endoftext|>


<commit_before><commit_msg>[TritonCTS] Fix TechChar logs<commit_after><|endoftext|>


<commit_before><commit_msg>Update de_web_plugin.cpp<commit_after><|endoftext|>


<commit_before>
#include <ionWindow.h>
#include <ionGraphics.h>
#include <ionGraphicsGL.h>
#include <ionScene.h>
#include <ionApplication.h>

using namespace ion;
using namespace ion::Scene;
using namespace ion::Graphics;

int main()
{
	////////////////////
	// ionEngine Init //
	////////////////////

	Log::AddDefaultOutputs();

	SingletonPointer<CGraphicsAPI> GraphicsAPI;
	SingletonPointer<CWindowManager> WindowManager;
	SingletonPointer<CTimeManager> TimeManager;
	SingletonPointer<CSceneManager> SceneManager;
	SingletonPointer<CAssetManager> AssetManager;

	GraphicsAPI->Init(new Graphics::COpenGLImplementation());
	WindowManager->Init(GraphicsAPI);
	TimeManager->Init(WindowManager);
	SceneManager->Init(GraphicsAPI);
	AssetManager->Init(GraphicsAPI);

	CWindow * Window = WindowManager->CreateWindow(vec2i(1600, 900), "DemoApplication", EWindowType::Windowed);

	AssetManager->SetAssetPath("Assets/");
	AssetManager->SetShaderPath("Shaders/");
	AssetManager->SetTexturePath("Images/");

	SharedPointer<IGraphicsContext> Context = GraphicsAPI->GetWindowContext(Window);
	SharedPointer<IRenderTarget> RenderTarget = Context->GetBackBuffer();
	RenderTarget->SetClearColor(color3f(0.3f));

	/////////////////
	// Load Assets //
	/////////////////

	CSimpleMesh * SphereMesh = CGeometryCreator::CreateSphere();
	CSimpleMesh * SkySphereMesh = CGeometryCreator::CreateSkySphere();
	CSimpleMesh * PlaneMesh = CGeometryCreator::CreatePlane(vec2f(100.f));

	SharedPointer<IShaderProgram> DiffuseShader = AssetManager->LoadShader("Diffuse");
	SharedPointer<IShaderProgram> SimpleShader = AssetManager->LoadShader("Simple");
	SharedPointer<IShaderProgram> SpecularShader = AssetManager->LoadShader("Specular");
	SharedPointer<IShaderProgram> SkySphereShader = AssetManager->LoadShader("SkySphere");

	SharedPointer<ITexture2D> SkyMap = AssetManager->LoadTexture("SkyMap.jpg");
	SkyMap->SetMagFilter(ITexture::EFilter::Nearest);

	////////////////////
	// ionScene Setup //
	////////////////////

	CRenderPass * RenderPass = new CRenderPass(Context);
	RenderPass->SetRenderTarget(RenderTarget);
	SceneManager->AddRenderPass(RenderPass);

	CPerspectiveCamera * Camera = new CPerspectiveCamera(Window->GetAspectRatio());
	Camera->SetPosition(vec3f(0, 3, -5));
	Camera->SetFocalLength(0.4f);
	RenderPass->SetActiveCamera(Camera);

	CCameraController * Controller = new CCameraController(Camera);
	Controller->SetTheta(15.f * Constants32::Pi / 48.f);
	Controller->SetPhi(-Constants32::Pi / 16.f);
	Window->AddListener(Controller);
	TimeManager->MakeUpdateTick(0.02)->AddListener(Controller);

	/////////////////
	// Add Objects //
	/////////////////

	CSimpleMeshSceneObject * LightSphere1 = new CSimpleMeshSceneObject();
	LightSphere1->SetMesh(SphereMesh);
	LightSphere1->SetShader(SimpleShader);
	LightSphere1->SetPosition(vec3f(0, 1, 0));
	RenderPass->AddSceneObject(LightSphere1);

	CSimpleMeshSceneObject * LightSphere2 = new CSimpleMeshSceneObject();
	LightSphere2->SetMesh(SphereMesh);
	LightSphere2->SetShader(SimpleShader);
	LightSphere2->SetPosition(vec3f(4, 2, 0));
	RenderPass->AddSceneObject(LightSphere2);

	CSimpleMeshSceneObject * LightSphere3 = new CSimpleMeshSceneObject();
	LightSphere3->SetMesh(SphereMesh);
	LightSphere3->SetShader(SimpleShader);
	LightSphere3->SetPosition(vec3f(12, 3, 0));
	RenderPass->AddSceneObject(LightSphere3);

	CSimpleMeshSceneObject * SpecularSphere = new CSimpleMeshSceneObject();
	SpecularSphere->SetMesh(SphereMesh);
	SpecularSphere->SetShader(SpecularShader);
	SpecularSphere->SetPosition(vec3f(3, 3, 6));
	RenderPass->AddSceneObject(SpecularSphere);

	CSimpleMeshSceneObject * PlaneObject = new CSimpleMeshSceneObject();
	PlaneObject->SetMesh(PlaneMesh);
	PlaneObject->SetShader(DiffuseShader);
	RenderPass->AddSceneObject(PlaneObject);

	CSimpleMeshSceneObject * SkySphereObject = new CSimpleMeshSceneObject();
	SkySphereObject->SetMesh(SkySphereMesh);
	SkySphereObject->SetShader(SkySphereShader);
	SkySphereObject->SetTexture("uTexture", SkyMap);
	RenderPass->AddSceneObject(SkySphereObject);

	CPointLight * Light1 = new CPointLight();
	Light1->SetPosition(vec3f(0, 1, 0));
	Light1->SetColor(Colors::Red);
	RenderPass->AddLight(Light1);

	CPointLight * Light2 = new CPointLight();
	Light2->SetPosition(vec3f(4, 2, 0));
	Light2->SetColor(Colors::Green);
	RenderPass->AddLight(Light2);

	CPointLight * Light3 = new CPointLight();
	Light3->SetPosition(vec3f(12, 3, 0));
	Light3->SetColor(Colors::Blue);
	RenderPass->AddLight(Light3);

	///////////////
	// Main Loop //
	///////////////

	TimeManager->Init(WindowManager);
	while (WindowManager->Run())
	{
		TimeManager->Update();

		float const MinimumBrightness = 0.2f;
		float const MaximumBrightness = 1.f - MinimumBrightness;
		float const Brightness = (Sin<float>((float) TimeManager->GetRunTime()) / 2.f + 0.5f) * MaximumBrightness + MinimumBrightness;
		float const Radius = Brightness * 10.f;
		Light1->SetRadius(Radius);
		Light2->SetRadius(Radius);
		Light3->SetRadius(Radius);

		float const Bright = 1;
		float const Dim = 0.5f;
		LightSphere1->GetMaterial().Diffuse = color3f(Bright, Dim, Dim) * Brightness;
		LightSphere2->GetMaterial().Diffuse = color3f(Dim, Bright, Dim) * Brightness;
		LightSphere3->GetMaterial().Diffuse = color3f(Dim, Dim, Bright) * Brightness;
		LightSphere1->SetScale(Brightness);
		LightSphere2->SetScale(Brightness);
		LightSphere3->SetScale(Brightness);

		SkySphereObject->SetPosition(Camera->GetPosition());

		RenderTarget->ClearColorAndDepth();
		SceneManager->DrawAll();
		Window->SwapBuffers();
	}

	return 0;
}
<commit_msg>[Demo05] Fix materials<commit_after>
#include <ionWindow.h>
#include <ionGraphics.h>
#include <ionGraphicsGL.h>
#include <ionScene.h>
#include <ionApplication.h>

using namespace ion;
using namespace ion::Scene;
using namespace ion::Graphics;

int main()
{
	////////////////////
	// ionEngine Init //
	////////////////////

	Log::AddDefaultOutputs();

	SingletonPointer<CGraphicsAPI> GraphicsAPI;
	SingletonPointer<CWindowManager> WindowManager;
	SingletonPointer<CTimeManager> TimeManager;
	SingletonPointer<CSceneManager> SceneManager;
	SingletonPointer<CAssetManager> AssetManager;

	GraphicsAPI->Init(new Graphics::COpenGLImplementation());
	WindowManager->Init(GraphicsAPI);
	TimeManager->Init(WindowManager);
	SceneManager->Init(GraphicsAPI);
	AssetManager->Init(GraphicsAPI);

	CWindow * Window = WindowManager->CreateWindow(vec2i(1600, 900), "DemoApplication", EWindowType::Windowed);

	AssetManager->SetAssetPath("Assets/");
	AssetManager->SetShaderPath("Shaders/");
	AssetManager->SetTexturePath("Images/");

	SharedPointer<IGraphicsContext> Context = GraphicsAPI->GetWindowContext(Window);
	SharedPointer<IRenderTarget> RenderTarget = Context->GetBackBuffer();
	RenderTarget->SetClearColor(color3f(0.3f));

	/////////////////
	// Load Assets //
	/////////////////

	CSimpleMesh * SphereMesh = CGeometryCreator::CreateSphere();
	CSimpleMesh * SkySphereMesh = CGeometryCreator::CreateSkySphere();
	CSimpleMesh * PlaneMesh = CGeometryCreator::CreatePlane(vec2f(100.f));

	SharedPointer<IShaderProgram> DiffuseShader = AssetManager->LoadShader("Diffuse");
	SharedPointer<IShaderProgram> SimpleShader = AssetManager->LoadShader("Simple");
	SharedPointer<IShaderProgram> SpecularShader = AssetManager->LoadShader("Specular");
	SharedPointer<IShaderProgram> SkySphereShader = AssetManager->LoadShader("SkySphere");

	SharedPointer<ITexture2D> SkyMap = AssetManager->LoadTexture("SkyMap.jpg");
	SkyMap->SetMagFilter(ITexture::EFilter::Nearest);

	////////////////////
	// ionScene Setup //
	////////////////////

	CRenderPass * RenderPass = new CRenderPass(Context);
	RenderPass->SetRenderTarget(RenderTarget);
	SceneManager->AddRenderPass(RenderPass);

	CPerspectiveCamera * Camera = new CPerspectiveCamera(Window->GetAspectRatio());
	Camera->SetPosition(vec3f(0, 3, -5));
	Camera->SetFocalLength(0.4f);
	RenderPass->SetActiveCamera(Camera);

	CCameraController * Controller = new CCameraController(Camera);
	Controller->SetTheta(15.f * Constants32::Pi / 48.f);
	Controller->SetPhi(-Constants32::Pi / 16.f);
	Window->AddListener(Controller);
	TimeManager->MakeUpdateTick(0.02)->AddListener(Controller);

	/////////////////
	// Add Objects //
	/////////////////

	CSimpleMeshSceneObject * LightSphere1 = new CSimpleMeshSceneObject();
	LightSphere1->SetMesh(SphereMesh);
	LightSphere1->SetShader(SimpleShader);
	LightSphere1->SetPosition(vec3f(0, 1, 0));
	RenderPass->AddSceneObject(LightSphere1);

	CSimpleMeshSceneObject * LightSphere2 = new CSimpleMeshSceneObject();
	LightSphere2->SetMesh(SphereMesh);
	LightSphere2->SetShader(SimpleShader);
	LightSphere2->SetPosition(vec3f(4, 2, 0));
	RenderPass->AddSceneObject(LightSphere2);

	CSimpleMeshSceneObject * LightSphere3 = new CSimpleMeshSceneObject();
	LightSphere3->SetMesh(SphereMesh);
	LightSphere3->SetShader(SimpleShader);
	LightSphere3->SetPosition(vec3f(12, 3, 0));
	RenderPass->AddSceneObject(LightSphere3);

	CSimpleMeshSceneObject * SpecularSphere = new CSimpleMeshSceneObject();
	SpecularSphere->SetMesh(SphereMesh);
	SpecularSphere->SetShader(SpecularShader);
	SpecularSphere->SetPosition(vec3f(3, 3, 6));
	SpecularSphere->GetMaterial().Ambient = vec3f(0.05f);
	RenderPass->AddSceneObject(SpecularSphere);

	CSimpleMeshSceneObject * PlaneObject = new CSimpleMeshSceneObject();
	PlaneObject->SetMesh(PlaneMesh);
	PlaneObject->SetShader(DiffuseShader);
	PlaneObject->GetMaterial().Ambient = vec3f(0.05f);
	RenderPass->AddSceneObject(PlaneObject);

	CSimpleMeshSceneObject * SkySphereObject = new CSimpleMeshSceneObject();
	SkySphereObject->SetMesh(SkySphereMesh);
	SkySphereObject->SetShader(SkySphereShader);
	SkySphereObject->SetTexture("uTexture", SkyMap);
	RenderPass->AddSceneObject(SkySphereObject);

	CPointLight * Light1 = new CPointLight();
	Light1->SetPosition(vec3f(0, 1, 0));
	Light1->SetColor(Colors::Red);
	RenderPass->AddLight(Light1);

	CPointLight * Light2 = new CPointLight();
	Light2->SetPosition(vec3f(4, 2, 0));
	Light2->SetColor(Colors::Green);
	RenderPass->AddLight(Light2);

	CPointLight * Light3 = new CPointLight();
	Light3->SetPosition(vec3f(12, 3, 0));
	Light3->SetColor(Colors::Blue);
	RenderPass->AddLight(Light3);

	///////////////
	// Main Loop //
	///////////////

	TimeManager->Init(WindowManager);
	while (WindowManager->Run())
	{
		TimeManager->Update();

		float const MinimumBrightness = 0.2f;
		float const MaximumBrightness = 1.f - MinimumBrightness;
		float const Brightness = (Sin<float>((float) TimeManager->GetRunTime()) / 2.f + 0.5f) * MaximumBrightness + MinimumBrightness;
		float const Radius = Brightness * 10.f;
		Light1->SetRadius(Radius);
		Light2->SetRadius(Radius);
		Light3->SetRadius(Radius);

		float const Bright = 1;
		float const Dim = 0.5f;
		LightSphere1->GetMaterial().Diffuse = color3f(Bright, Dim, Dim) * Brightness;
		LightSphere2->GetMaterial().Diffuse = color3f(Dim, Bright, Dim) * Brightness;
		LightSphere3->GetMaterial().Diffuse = color3f(Dim, Dim, Bright) * Brightness;
		LightSphere1->SetScale(Brightness);
		LightSphere2->SetScale(Brightness);
		LightSphere3->SetScale(Brightness);

		SkySphereObject->SetPosition(Camera->GetPosition());

		RenderTarget->ClearColorAndDepth();
		SceneManager->DrawAll();
		Window->SwapBuffers();
	}

	return 0;
}
<|endoftext|>


<commit_before>#include <QtSerialPort/QtSerialPort>
#include <iostream>
#include "PositionDispatcher.h"
#include "MavState.h"

#define DISPATCH_INTERVAL 100 //ms

PositionDispatcher::PositionDispatcher(QObject *parent) :
    QObject(parent),
    _serial(this)
{
    _serial.setPortName("/dev/ttyUSB0");

    // Open serial port

    if(!_serial.open(QSerialPort::ReadWrite)) {

        qCritical() << "Error opening serial port";
        emit finished();
        return;
    }

    _serial.setBaudRate(QSerialPort::Baud57600);
    _serial.setFlowControl(QSerialPort::NoFlowControl);

    // Start dispatch time counter
    _dispatchTime.start();
    qDebug() << "Connected to MavLink Radio...";
}

PositionDispatcher::~PositionDispatcher()
{
    _serial.close();
    qDebug() << "Serial Port closed";
}

void PositionDispatcher::sendPosition(int64_t ts, geometry::pose vision, geometry::pose sp, bool visionValid, bool spValid)
{

    mavlink_message_t msg1;
    mavlink_message_t msg2;
    MavState conv;
    conv.setOrientation(vision.orientation[0],vision.orientation[1],vision.orientation[2],vision.orientation[3]);
    float roll,pitch,yaw;
    conv.orientation(&roll,&pitch,&yaw);

    mavlink_msg_vision_position_estimate_pack(
            1,
            MAV_COMP_ID_ALL, &msg1,
            (uint64_t) ts * 1000,
            (float)vision.position[0],
            (float)vision.position[1],
            (float)vision.position[2],
            roll, //rad
            pitch, //rad
            yaw); //rad
/*
    mavlink_msg_vicon_position_estimate_pack(
            1,
            MAV_COMP_ID_ALL, &msg2,
            (uint64_t) ts * 1000,
            (float)sp.position[0],
            (float)sp.position[1],
            (float)sp.position[2],
            0, //rad
            0,//rad
            sp.yaw); //rad

*/

   mavlink_msg_set_position_target_local_ned_pack(
           1,
           MAV_COMP_ID_ALL,
           &msg2,
           (uint64_t) ts * 1000,
           1,
           MAV_COMP_ID_ALL,
           MAV_FRAME_LOCAL_NED,
           0b0000001111111000,
           1,
           2,
           3,
           0,
           0,
           0,
           0,
           0,
           0,
           0,
           0);

    if(_dispatchTime.elapsed() >= DISPATCH_INTERVAL){

       // if(visionValid) {
            _sendMavlinkMessage(&msg1);
            std::cout << "Vision estimate: " << vision.position[0] << " " << vision.position[1] <<
            " " << vision.position[2] <<" \\ " <<roll <<" " <<pitch <<" " <<" " <<yaw << std::endl;
        //}

        if(spValid){
            _sendMavlinkMessage(&msg2);
            std::cout << "Position SP: " << sp.position[0] << " " <<sp.position[1] <<
            " " << sp.position[2] << std::endl;

        }

        _dispatchTime.restart();

    }

}

void PositionDispatcher::_sendMavlinkMessage(mavlink_message_t *msg)
{
    // Initialize the required buffers
    uint8_t buf[MAVLINK_MAX_PACKET_LEN];

    // Copy the message to the send buffer
    uint16_t len = mavlink_msg_to_send_buffer(buf, msg);

    // Send the message
    QByteArray sendBuff((const char*)buf, len);
    int written = _serial.write(sendBuff);

    //Wait for data to be sent
    if(!_serial.waitForBytesWritten(500)) {
        qCritical() << "Serial unable to send data";
        emit finished();
    }

}
<commit_msg>pack position set point<commit_after>#include <QtSerialPort/QtSerialPort>
#include <iostream>
#include "PositionDispatcher.h"
#include "MavState.h"

#define DISPATCH_INTERVAL 100 //ms

PositionDispatcher::PositionDispatcher(QObject *parent) :
    QObject(parent),
    _serial(this)
{
    _serial.setPortName("/dev/ttyUSB0");

    // Open serial port

    if(!_serial.open(QSerialPort::ReadWrite)) {

        qCritical() << "Error opening serial port";
        emit finished();
        return;
    }

    _serial.setBaudRate(QSerialPort::Baud57600);
    _serial.setFlowControl(QSerialPort::NoFlowControl);

    // Start dispatch time counter
    _dispatchTime.start();
    qDebug() << "Connected to MavLink Radio...";
}

PositionDispatcher::~PositionDispatcher()
{
    _serial.close();
    qDebug() << "Serial Port closed";
}

void PositionDispatcher::sendPosition(int64_t ts, geometry::pose vision, geometry::pose sp, bool visionValid, bool spValid)
{

    mavlink_message_t msg1;
    mavlink_message_t msg2;
    MavState conv;
    conv.setOrientation(vision.orientation[0],vision.orientation[1],vision.orientation[2],vision.orientation[3]);
    float roll,pitch,yaw;
    conv.orientation(&roll,&pitch,&yaw);

    mavlink_msg_vision_position_estimate_pack(
            1,
            MAV_COMP_ID_ALL, &msg1,
            (uint64_t) ts * 1000,
            (float)vision.position[0],
            (float)vision.position[1],
            (float)vision.position[2],
            roll, //rad
            pitch, //rad
            yaw); //rad
/*
    mavlink_msg_vicon_position_estimate_pack(
            1,
            MAV_COMP_ID_ALL, &msg2,
            (uint64_t) ts * 1000,
            (float)sp.position[0],
            (float)sp.position[1],
            (float)sp.position[2],
            0, //rad
            0,//rad
            sp.yaw); //rad

*/

   mavlink_msg_set_position_target_local_ned_pack(
           1,
           MAV_COMP_ID_ALL,
           &msg2,
           (uint64_t) ts * 1000,
           1,
           MAV_COMP_ID_ALL,
           MAV_FRAME_LOCAL_NED,
           0b0000001111111000,
           sp.position[0],     //x        [m]
           sp.position[1],     //y
           sp.position[2],     //z        Be careful, z is directed downwards!!
           0,                  //vx       [m/s]
           0,                  //vy
           0,                  //vz
           0,                  //ax       [m/s^2]
           0,                  //ay
           0,                  //az
           0,                  //yaw      [rad]
           0);                 //yaw_rate [rad/s]

    if(_dispatchTime.elapsed() >= DISPATCH_INTERVAL){

       // if(visionValid) {
            _sendMavlinkMessage(&msg1);
            std::cout << "Vision estimate: " << vision.position[0] << " " << vision.position[1] <<
            " " << vision.position[2] <<" \\ " <<roll <<" " <<pitch <<" " <<" " <<yaw << std::endl;
        //}

        if(spValid){
            _sendMavlinkMessage(&msg2);
            std::cout << "Position SP: " << sp.position[0] << " " <<sp.position[1] <<
            " " << sp.position[2] << std::endl;

        }

        _dispatchTime.restart();

    }

}

void PositionDispatcher::_sendMavlinkMessage(mavlink_message_t *msg)
{
    // Initialize the required buffers
    uint8_t buf[MAVLINK_MAX_PACKET_LEN];

    // Copy the message to the send buffer
    uint16_t len = mavlink_msg_to_send_buffer(buf, msg);

    // Send the message
    QByteArray sendBuff((const char*)buf, len);
    int written = _serial.write(sendBuff);

    //Wait for data to be sent
    if(!_serial.waitForBytesWritten(500)) {
        qCritical() << "Serial unable to send data";
        emit finished();
    }

}
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////
/// @file      ClickEventHandler.cpp
/// @author    Chris L Baker (clb) <chris@chimail.net>
/// @date      2015.01.13
/// @brief     Handle Click Events
///
/// @attention Copyright (C) 2015
/// @attention All rights reserved
/////////////////////////////////////////////////////////////////

#include "ClickEventHandler.h"

namespace d3
{

/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
ClickEventHandler::ClickEventHandler() :
    Parent_t()
{
};

/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
ClickEventHandler::~ClickEventHandler()
{
};

/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
bool ClickEventHandler::add(const osgGA::GUIEventAdapter::MouseButtonMask& button,
                            const std::function<bool(const osgGA::GUIEventAdapter&)>& func,
                            const std::string& description)
{
    // add this click handler to the map
    m_clickFuncMap[button].push_back({button, func, description});

    return true;
};

/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
bool ClickEventHandler::handle(const osgGA::GUIEventAdapter& eventAdapter,
                               osgGA::GUIActionAdapter&)
{
    // find this handler
    ClickMap_t::iterator itt( m_clickFuncMap.find((osgGA::GUIEventAdapter::MouseButtonMask)eventAdapter.getButton()) );
    if ( m_clickFuncMap.end() == itt ) return false;

    // envoke the function(s)
    bool rv(true);
    for ( const auto& entry : itt->second )
        rv &= entry.func(eventAdapter);

    return rv;
};

} // namespace d3
<commit_msg>catching the :bug: where, if no event handler was registered, we would incorrectly report the action as being handled<commit_after>/////////////////////////////////////////////////////////////////
/// @file      ClickEventHandler.cpp
/// @author    Chris L Baker (clb) <chris@chimail.net>
/// @date      2015.01.13
/// @brief     Handle Click Events
///
/// @attention Copyright (C) 2015
/// @attention All rights reserved
/////////////////////////////////////////////////////////////////

#include "ClickEventHandler.h"

namespace d3
{

/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
ClickEventHandler::ClickEventHandler() :
    Parent_t()
{
};

/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
ClickEventHandler::~ClickEventHandler()
{
};

/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
bool ClickEventHandler::add(const osgGA::GUIEventAdapter::MouseButtonMask& button,
                            const std::function<bool(const osgGA::GUIEventAdapter&)>& func,
                            const std::string& description)
{
    // add this click handler to the map
    m_clickFuncMap[button].push_back({button, func, description});

    return true;
};

/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
bool ClickEventHandler::handle(const osgGA::GUIEventAdapter& eventAdapter,
                               osgGA::GUIActionAdapter&)
{
    if ( 0x7 & eventAdapter.getButton() )
    {
        // find this handler
        ClickMap_t::iterator itt( m_clickFuncMap.find((osgGA::GUIEventAdapter::MouseButtonMask)eventAdapter.getButton()) );
        if ( m_clickFuncMap.end() == itt ) return false;

        // envoke the function(s)
        bool rv(false);
        if ( not itt->second.empty() )
        {
            rv = true;
            for ( const auto& entry : itt->second )
                rv &= entry.func(eventAdapter);
        }

        return rv;
    }

    return false;
};

} // namespace d3
<|endoftext|>


<commit_before>
#include "Output.h"
#include "../ObjectStore.h"
#include "../EspConnection.h"
#include "../../IPC/Message.h"
#include "../../IPOCS/Message.h"
#include "../../IPOCS/Packets/SetOutputPacket.h"
#include "../log.h"

Output::Output(): lastOrderTime(0), offDelay(0), outputPin(0),
                  lastSentState(IPOCS::OutputStatusPacket::E_RQ_OUTPUT_STATE::OFF) {
}

void Output::handleOrder(IPOCS::Packet* basePacket)
{
  if (basePacket->RNID_PACKET == 13) {
    IPOCS::SetOutputPacket* packet = (IPOCS::SetOutputPacket*)basePacket;
    // Set output high
    this->lastOrderTime = millis();
    if (packet->RQ_OUTPUT_COMMAND == IPOCS::SetOutputPacket::E_RQ_OUTPUT_COMMAND::ON) {
      this->offDelay = packet->RT_DURATION;
      digitalWrite(this->outputPin, HIGH);
      if (this->lastSentState == IPOCS::OutputStatusPacket::E_RQ_OUTPUT_STATE::OFF) {
        this->lastSentState = IPOCS::OutputStatusPacket::E_RQ_OUTPUT_STATE::ON;
        this->sendStatus();
      }
    } else {
      this->offDelay = 0;
      digitalWrite(this->outputPin, LOW);
      if (this->lastSentState == IPOCS::OutputStatusPacket::E_RQ_OUTPUT_STATE::ON) {
        this->lastSentState = IPOCS::OutputStatusPacket::E_RQ_OUTPUT_STATE::OFF;
        this->sendStatus();
      }
    }
  } else if (basePacket->RNID_PACKET == 7) {
    this->sendStatus();
  } else {
    // TODO: Send alarm or something about invalid packet type.
  }
}

IPOCS::Packet* Output::getStatusPacket() {
  IPOCS::OutputStatusPacket* pkt = (IPOCS::OutputStatusPacket*)IPOCS::OutputStatusPacket::create();
  pkt->RQ_OUTPUT_STATE = this->lastSentState;
  return pkt;
}

void Output::loop() {
  if ((offDelay != 0) && (millis() - this->lastOrderTime) >= offDelay) {
    this->offDelay = 0;
    digitalWrite(this->outputPin, LOW);
    if (this->lastSentState == IPOCS::OutputStatusPacket::E_RQ_OUTPUT_STATE::ON) {
      this->lastSentState = IPOCS::OutputStatusPacket::E_RQ_OUTPUT_STATE::OFF;
      this->sendStatus();
    }
  }
}

void Output::objectInit(const uint8_t configData[], int configDataLen)
{
  this->outputPin = configData[0] + 1;

  pinMode(this->outputPin, OUTPUT);
  digitalWrite(this->outputPin, LOW);
}

static BasicObject* createOutput()
{
  return new Output();
}

__attribute__((constructor))
static void initialize_output() {
  ObjectStore::getInstance().registerType(10, &createOutput);
}
<commit_msg>Fix bug with output order duration<commit_after>
#include "Output.h"
#include "../ObjectStore.h"
#include "../EspConnection.h"
#include "../../IPC/Message.h"
#include "../../IPOCS/Message.h"
#include "../../IPOCS/Packets/SetOutputPacket.h"
#include "../log.h"

Output::Output(): lastOrderTime(0), offDelay(0), outputPin(0),
                  lastSentState(IPOCS::OutputStatusPacket::E_RQ_OUTPUT_STATE::OFF) {
}

void Output::handleOrder(IPOCS::Packet* basePacket)
{
  if (basePacket->RNID_PACKET == 13) {
    IPOCS::SetOutputPacket* packet = (IPOCS::SetOutputPacket*)basePacket;
    // Set output high
    this->lastOrderTime = millis();
    if (packet->RQ_OUTPUT_COMMAND == IPOCS::SetOutputPacket::E_RQ_OUTPUT_COMMAND::ON) {
      this->offDelay = packet->RT_DURATION;
      digitalWrite(this->outputPin, HIGH);
      if (this->lastSentState == IPOCS::OutputStatusPacket::E_RQ_OUTPUT_STATE::OFF) {
        this->lastSentState = IPOCS::OutputStatusPacket::E_RQ_OUTPUT_STATE::ON;
        this->sendStatus();
      }
    } else {
      this->offDelay = 0;
      digitalWrite(this->outputPin, LOW);
      if (this->lastSentState == IPOCS::OutputStatusPacket::E_RQ_OUTPUT_STATE::ON) {
        this->lastSentState = IPOCS::OutputStatusPacket::E_RQ_OUTPUT_STATE::OFF;
        this->sendStatus();
      }
    }
  } else if (basePacket->RNID_PACKET == 7) {
    this->sendStatus();
  } else {
    // TODO: Send alarm or something about invalid packet type.
  }
}

IPOCS::Packet* Output::getStatusPacket() {
  IPOCS::OutputStatusPacket* pkt = (IPOCS::OutputStatusPacket*)IPOCS::OutputStatusPacket::create();
  pkt->RQ_OUTPUT_STATE = this->lastSentState;
  return pkt;
}

void Output::loop() {
  if ((offDelay != 0) && (millis() - this->lastOrderTime) >= this->offDelay * 100) {
    this->offDelay = 0;
    digitalWrite(this->outputPin, LOW);
    if (this->lastSentState == IPOCS::OutputStatusPacket::E_RQ_OUTPUT_STATE::ON) {
      this->lastSentState = IPOCS::OutputStatusPacket::E_RQ_OUTPUT_STATE::OFF;
      this->sendStatus();
    }
  }
}

void Output::objectInit(const uint8_t configData[], int configDataLen)
{
  this->outputPin = configData[0] + 1;

  pinMode(this->outputPin, OUTPUT);
  digitalWrite(this->outputPin, LOW);
}

static BasicObject* createOutput()
{
  return new Output();
}

__attribute__((constructor))
static void initialize_output() {
  ObjectStore::getInstance().registerType(10, &createOutput);
}
<|endoftext|>


<commit_before>//
// Copyright (C) 2014, 2015 Ableton AG, Berlin. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//

#include <atria/prelude/comp.hpp>
#include <atria/testing/gtest.hpp>

namespace atria {
namespace prelude {

TEST(comp, compose_one_fn)
{
  auto fn = comp(
    [](int x) { return x + 1; });
  EXPECT_EQ(fn(1), 2);
  EXPECT_EQ(fn(42), 43);
}

TEST(comp, compose_two_fn)
{
  auto fn = comp(
    [](int x) { return x + 1; },
    [](int x) { return x * 2; });
  EXPECT_EQ(fn(3), 7);
  EXPECT_EQ(fn(42), 85);
}

TEST(comp, compose_three_fn)
{
  auto fn = comp(
    [](int x) { return x + 1; },
    [](int x) { return x * 2; },
    [](int x) { return x - 1; });
  EXPECT_EQ(fn(3), 5);
  EXPECT_EQ(fn(42), 83);
}

TEST(comp, various_types)
{
  auto fn = comp(
    [](double x) { return x + 1; },
    [](std::string) { return 42.0; },
    [](int x) { return std::to_string(x); });
  EXPECT_EQ(fn(3), 43.0);
  EXPECT_EQ(fn(42), 43.0);
}

namespace
{

struct thingy
{
  int value;

  thingy& times2() { value *= 2; return *this; }
  thingy& plus2()  { value += 2; return *this; }
  int extract()    { return value; }
};

int free_func(int x, int y) { return x - y; }

} // anon

TEST(comp, uses_invoke)
{
  auto res = comp(
    &thingy::extract,
    &thingy::times2,
    &thingy::plus2,
    [](int x) { return thingy{x}; },
    free_func);
  EXPECT_EQ(res(10, 5), 14);
}

} // namespace prelude
} // namespace atria
<commit_msg>prelude: oops! fix stupid UB in `comp` unit test<commit_after>//
// Copyright (C) 2014, 2015 Ableton AG, Berlin. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//

#include <atria/prelude/comp.hpp>
#include <atria/testing/gtest.hpp>

namespace atria {
namespace prelude {

TEST(comp, compose_one_fn)
{
  auto fn = comp(
    [](int x) { return x + 1; });
  EXPECT_EQ(fn(1), 2);
  EXPECT_EQ(fn(42), 43);
}

TEST(comp, compose_two_fn)
{
  auto fn = comp(
    [](int x) { return x + 1; },
    [](int x) { return x * 2; });
  EXPECT_EQ(fn(3), 7);
  EXPECT_EQ(fn(42), 85);
}

TEST(comp, compose_three_fn)
{
  auto fn = comp(
    [](int x) { return x + 1; },
    [](int x) { return x * 2; },
    [](int x) { return x - 1; });
  EXPECT_EQ(fn(3), 5);
  EXPECT_EQ(fn(42), 83);
}

TEST(comp, various_types)
{
  auto fn = comp(
    [](double x) { return x + 1; },
    [](std::string) { return 42.0; },
    [](int x) { return std::to_string(x); });
  EXPECT_EQ(fn(3), 43.0);
  EXPECT_EQ(fn(42), 43.0);
}

namespace
{

struct thingy
{
  int value;

  thingy times2() { value *= 2; return *this; }
  thingy plus2()  { value += 2; return *this; }
  int extract()   { return value; }
};

int free_func(int x, int y) { return x - y; }

} // anon

TEST(comp, uses_invoke)
{
  auto res = comp(
    &thingy::extract,
    &thingy::times2,
    &thingy::plus2,
    [](int x) { return thingy{x}; },
    free_func);
  EXPECT_EQ(res(10, 5), 14);
}

} // namespace prelude
} // namespace atria
<|endoftext|>


<commit_before>/*

Copyright 2015-2020 Igor Petrovic

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.

*/

#include "board/Board.h"
#include "board/common/io/Helpers.h"
#include "board/Internal.h"
#include "core/src/general/Helpers.h"
#include "core/src/general/Atomic.h"
#include "Pins.h"
#include "io/leds/LEDs.h"

///
/// \brief Total number of states between fully off and fully on for LEDs.
///
#define NUMBER_OF_LED_TRANSITIONS 64

namespace
{
#if !defined(NUMBER_OF_OUT_SR) || defined(NUMBER_OF_LED_COLUMNS)
    core::io::mcuPin_t pin;
#endif

    ///
    /// \brief Variables holding calculated current LED index and state.
    /// Used only to avoid stack usage in interrupt.
    /// @{

#if defined(NUMBER_OF_LED_COLUMNS) || defined(NUMBER_OF_OUT_SR)
    uint8_t ledIndex;
#endif
#ifdef NUMBER_OF_LED_COLUMNS
    bool ledStateSingle;
#endif
    /// @}

    uint8_t ledState[MAX_NUMBER_OF_LEDS];

#ifdef LED_FADING
    volatile uint8_t pwmSteps;
    volatile int8_t  transitionCounter[MAX_NUMBER_OF_LEDS];

    ///
    /// \brief Array holding values needed to achieve more natural LED transition between states.
    ///
    const uint8_t ledTransitionScale[NUMBER_OF_LED_TRANSITIONS] = {
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        1,
        1,
        1,
        1,
        2,
        2,
        2,
        2,
        3,
        3,
        4,
        4,
        5,
        5,
        6,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        16,
        17,
        19,
        21,
        23,
        25,
        28,
        30,
        33,
        36,
        40,
        44,
        48,
        52,
        57,
        62,
        68,
        74,
        81,
        89,
        97,
        106,
        115,
        126,
        138,
        150,
        164,
        179,
        195,
        213,
        255
    };
#endif

#ifndef NUMBER_OF_LED_COLUMNS
    ///
    /// \brief Used to indicate whether or not outputs should be updated.
    /// Set to true in ::writeState if the new state differs from the current one.
    ///
    volatile bool updateOutputs = false;
#else
    ///
    /// \brief Holds value of currently active output matrix column.
    ///
    volatile uint8_t activeOutColumn;

    ///
    /// \brief Switches to next LED matrix column.
    ///
    inline void activateOutputColumn()
    {
        BIT_READ(activeOutColumn, 0) ? CORE_IO_SET_HIGH(DEC_LM_A0_PORT, DEC_LM_A0_PIN) : CORE_IO_SET_LOW(DEC_LM_A0_PORT, DEC_LM_A0_PIN);
        BIT_READ(activeOutColumn, 1) ? CORE_IO_SET_HIGH(DEC_LM_A1_PORT, DEC_LM_A1_PIN) : CORE_IO_SET_LOW(DEC_LM_A1_PORT, DEC_LM_A1_PIN);
        BIT_READ(activeOutColumn, 2) ? CORE_IO_SET_HIGH(DEC_LM_A2_PORT, DEC_LM_A2_PIN) : CORE_IO_SET_LOW(DEC_LM_A2_PORT, DEC_LM_A2_PIN);
    }

    ///
    /// \brief Used to turn the given LED row off.
    ///
    inline void ledRowOff(uint8_t row)
    {
#ifdef LED_FADING
        //turn off pwm
        core::io::pwmOff(Board::detail::map::pwmChannel(row));
#endif

        pin = Board::detail::map::led(row);
        EXT_LED_OFF(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin));
    }

    ///
    /// \brief Used to turn the given LED row on.
    /// If led fading is supported on board, intensity must be specified as well.
    ///
    inline void ledRowOn(uint8_t row
#ifdef LED_FADING
                         ,
                         uint8_t intensity
#endif
    )
    {
#ifdef LED_FADING
        if (intensity == 255)
#endif
        {
            pin = Board::detail::map::led(row);

            //max value, don't use pwm
            EXT_LED_ON(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin));
        }
#ifdef LED_FADING
        else
        {
#ifdef LED_EXT_INVERT
            intensity = 255 - intensity;
#endif

            core::io::pwmOn(Board::detail::map::pwmChannel(row), intensity);
        }
#endif
    }
#endif
}    // namespace

namespace Board
{
    namespace io
    {
        void writeLEDstate(uint8_t ledID, bool state)
        {
            ATOMIC_SECTION
            {
                ledState[ledID] = state;
#ifndef NUMBER_OF_LED_COLUMNS
                updateOutputs = true;
#endif
            }
        }

#ifdef LED_FADING
        void setLEDfadeSpeed(uint8_t transitionSpeed)
        {
            //reset transition counter
            ATOMIC_SECTION
            {
                for (int i = 0; i < MAX_NUMBER_OF_LEDS; i++)
                    transitionCounter[i] = 0;

                pwmSteps = transitionSpeed;
            }
        }
#else
        __attribute__((weak)) void setLEDfadeSpeed(uint8_t transitionSpeed)
        {
        }
#endif

        uint8_t getRGBaddress(uint8_t rgbID, Board::io::rgbIndex_t index)
        {
#ifdef NUMBER_OF_LED_COLUMNS
            uint8_t column  = rgbID % NUMBER_OF_LED_COLUMNS;
            uint8_t row     = (rgbID / NUMBER_OF_LED_COLUMNS) * 3;
            uint8_t address = column + NUMBER_OF_LED_COLUMNS * row;

            switch (index)
            {
            case rgbIndex_t::r:
                return address;

            case rgbIndex_t::g:
                return address + NUMBER_OF_LED_COLUMNS * 1;

            case rgbIndex_t::b:
                return address + NUMBER_OF_LED_COLUMNS * 2;
            }

            return 0;
#else
            return rgbID * 3 + static_cast<uint8_t>(index);
#endif
        }

        uint8_t getRGBID(uint8_t ledID)
        {
#ifdef NUMBER_OF_LED_COLUMNS
            uint8_t row = ledID / NUMBER_OF_LED_COLUMNS;

            uint8_t mod = row % 3;
            row -= mod;

            uint8_t column = ledID % NUMBER_OF_LED_COLUMNS;

            uint8_t result = (row * NUMBER_OF_LED_COLUMNS) / 3 + column;

            if (result >= MAX_NUMBER_OF_RGB_LEDS)
                return MAX_NUMBER_OF_RGB_LEDS - 1;
            else
                return result;
#else
            uint8_t result = ledID / 3;

            if (result >= MAX_NUMBER_OF_RGB_LEDS)
                return MAX_NUMBER_OF_RGB_LEDS - 1;
            else
                return result;
#endif
        }
    }    // namespace io

    namespace detail
    {
        namespace io
        {
#ifdef NUMBER_OF_LED_COLUMNS
            void checkDigitalOutputs()
            {
                for (int i = 0; i < NUMBER_OF_LED_ROWS; i++)
                    ledRowOff(i);

                activateOutputColumn();

                //if there is an active LED in current column, turn on LED row
                //do fancy transitions here
                for (int i = 0; i < NUMBER_OF_LED_ROWS; i++)
                {
                    ledIndex       = activeOutColumn + i * NUMBER_OF_LED_COLUMNS;
                    ledStateSingle = ledState[ledIndex] && (NUMBER_OF_LED_TRANSITIONS - 1);

                    //don't bother with pwm if it's disabled
                    if (!pwmSteps && ledStateSingle)
                    {
                        ledRowOn(i
#ifdef LED_FADING
                                 ,
                                 255
#endif
                        );
                    }
                    else
                    {
                        if (ledTransitionScale[transitionCounter[ledIndex]])
                            ledRowOn(i
#ifdef LED_FADING
                                     ,
                                     ledTransitionScale[transitionCounter[ledIndex]]
#endif
                            );

                        if (transitionCounter[ledIndex] != ledStateSingle)
                        {
                            //fade up
                            if (transitionCounter[ledIndex] < ledStateSingle)
                            {
                                transitionCounter[ledIndex] += pwmSteps;

                                if (transitionCounter[ledIndex] > ledStateSingle)
                                    transitionCounter[ledIndex] = ledStateSingle;
                            }
                            else
                            {
                                //fade down
                                transitionCounter[ledIndex] -= pwmSteps;

                                if (transitionCounter[ledIndex] < 0)
                                    transitionCounter[ledIndex] = 0;
                            }
                        }
                    }
                }

                if (++activeOutColumn == NUMBER_OF_LED_COLUMNS)
                    activeOutColumn = 0;
            }
#elif defined(NUMBER_OF_OUT_SR)
            ///
            /// \brief Checks if any LED state has been changed and writes changed state to output shift registers.
            ///
            void checkDigitalOutputs()
            {
                if (updateOutputs)
                {
                    CORE_IO_SET_LOW(SR_OUT_LATCH_PORT, SR_OUT_LATCH_PIN);

                    for (int j = 0; j < NUMBER_OF_OUT_SR; j++)
                    {
                        for (int i = 0; i < NUMBER_OF_OUT_SR_INPUTS; i++)
                        {
                            ledIndex = i + j * NUMBER_OF_OUT_SR_INPUTS;

                            ledState[ledIndex] ? EXT_LED_ON(SR_OUT_DATA_PORT, SR_OUT_DATA_PIN) : EXT_LED_OFF(SR_OUT_DATA_PORT, SR_OUT_DATA_PIN);
                            CORE_IO_SET_LOW(SR_OUT_CLK_PORT, SR_OUT_CLK_PIN);
                            _NOP();
                            _NOP();
                            CORE_IO_SET_HIGH(SR_OUT_CLK_PORT, SR_OUT_CLK_PIN);
                        }
                    }

                    CORE_IO_SET_HIGH(SR_OUT_LATCH_PORT, SR_OUT_LATCH_PIN);
                    updateOutputs = false;
                }
            }
#else
            void checkDigitalOutputs()
            {
                if (updateOutputs)
                {
                    for (int i = 0; i < MAX_NUMBER_OF_LEDS; i++)
                    {
                        pin = Board::detail::map::led(i);

                        if (ledState[i])
                            EXT_LED_ON(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin));
                        else
                            EXT_LED_OFF(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin));
                    }

                    updateOutputs = false;
                }
            }
#endif
        }    // namespace io
    }        // namespace detail
}    // namespace Board<commit_msg>board: make sure led control can be compiled in matrix setup without fade support<commit_after>/*

Copyright 2015-2020 Igor Petrovic

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.

*/

#include "board/Board.h"
#include "board/common/io/Helpers.h"
#include "board/Internal.h"
#include "core/src/general/Helpers.h"
#include "core/src/general/Atomic.h"
#include "Pins.h"
#include "io/leds/LEDs.h"

///
/// \brief Total number of states between fully off and fully on for LEDs.
///
#define NUMBER_OF_LED_TRANSITIONS 64

namespace
{
#if !defined(NUMBER_OF_OUT_SR) || defined(NUMBER_OF_LED_COLUMNS)
    core::io::mcuPin_t pin;
#endif

    ///
    /// \brief Variables holding calculated current LED index and state.
    /// Used only to avoid stack usage in interrupt.
    /// @{

#if defined(NUMBER_OF_LED_COLUMNS) || defined(NUMBER_OF_OUT_SR)
    uint8_t ledIndex;
#endif
#ifdef NUMBER_OF_LED_COLUMNS
    bool ledStateSingle;
#endif
    /// @}

    uint8_t ledState[MAX_NUMBER_OF_LEDS];

#ifdef LED_FADING
    volatile uint8_t pwmSteps;
    volatile int8_t  transitionCounter[MAX_NUMBER_OF_LEDS];

    ///
    /// \brief Array holding values needed to achieve more natural LED transition between states.
    ///
    const uint8_t ledTransitionScale[NUMBER_OF_LED_TRANSITIONS] = {
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        1,
        1,
        1,
        1,
        2,
        2,
        2,
        2,
        3,
        3,
        4,
        4,
        5,
        5,
        6,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        16,
        17,
        19,
        21,
        23,
        25,
        28,
        30,
        33,
        36,
        40,
        44,
        48,
        52,
        57,
        62,
        68,
        74,
        81,
        89,
        97,
        106,
        115,
        126,
        138,
        150,
        164,
        179,
        195,
        213,
        255
    };
#endif

#ifndef NUMBER_OF_LED_COLUMNS
    ///
    /// \brief Used to indicate whether or not outputs should be updated.
    /// Set to true in ::writeState if the new state differs from the current one.
    ///
    volatile bool updateOutputs = false;
#else
    ///
    /// \brief Holds value of currently active output matrix column.
    ///
    volatile uint8_t activeOutColumn;

    ///
    /// \brief Switches to next LED matrix column.
    ///
    inline void activateOutputColumn()
    {
        BIT_READ(activeOutColumn, 0) ? CORE_IO_SET_HIGH(DEC_LM_A0_PORT, DEC_LM_A0_PIN) : CORE_IO_SET_LOW(DEC_LM_A0_PORT, DEC_LM_A0_PIN);
        BIT_READ(activeOutColumn, 1) ? CORE_IO_SET_HIGH(DEC_LM_A1_PORT, DEC_LM_A1_PIN) : CORE_IO_SET_LOW(DEC_LM_A1_PORT, DEC_LM_A1_PIN);
        BIT_READ(activeOutColumn, 2) ? CORE_IO_SET_HIGH(DEC_LM_A2_PORT, DEC_LM_A2_PIN) : CORE_IO_SET_LOW(DEC_LM_A2_PORT, DEC_LM_A2_PIN);
    }

    ///
    /// \brief Used to turn the given LED row off.
    ///
    inline void ledRowOff(uint8_t row)
    {
#ifdef LED_FADING
        //turn off pwm
        core::io::pwmOff(Board::detail::map::pwmChannel(row));
#endif

        pin = Board::detail::map::led(row);
        EXT_LED_OFF(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin));
    }

    ///
    /// \brief Used to turn the given LED row on.
    /// If led fading is supported on board, intensity must be specified as well.
    ///
    inline void ledRowOn(uint8_t row
#ifdef LED_FADING
                         ,
                         uint8_t intensity
#endif
    )
    {
#ifdef LED_FADING
        if (intensity == 255)
#endif
        {
            pin = Board::detail::map::led(row);

            //max value, don't use pwm
            EXT_LED_ON(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin));
        }
#ifdef LED_FADING
        else
        {
#ifdef LED_EXT_INVERT
            intensity = 255 - intensity;
#endif

            core::io::pwmOn(Board::detail::map::pwmChannel(row), intensity);
        }
#endif
    }
#endif
}    // namespace

namespace Board
{
    namespace io
    {
        void writeLEDstate(uint8_t ledID, bool state)
        {
            ATOMIC_SECTION
            {
                ledState[ledID] = state;
#ifndef NUMBER_OF_LED_COLUMNS
                updateOutputs = true;
#endif
            }
        }

#ifdef LED_FADING
        void setLEDfadeSpeed(uint8_t transitionSpeed)
        {
            //reset transition counter
            ATOMIC_SECTION
            {
                for (int i = 0; i < MAX_NUMBER_OF_LEDS; i++)
                    transitionCounter[i] = 0;

                pwmSteps = transitionSpeed;
            }
        }
#else
        __attribute__((weak)) void setLEDfadeSpeed(uint8_t transitionSpeed)
        {
        }
#endif

        uint8_t getRGBaddress(uint8_t rgbID, Board::io::rgbIndex_t index)
        {
#ifdef NUMBER_OF_LED_COLUMNS
            uint8_t column  = rgbID % NUMBER_OF_LED_COLUMNS;
            uint8_t row     = (rgbID / NUMBER_OF_LED_COLUMNS) * 3;
            uint8_t address = column + NUMBER_OF_LED_COLUMNS * row;

            switch (index)
            {
            case rgbIndex_t::r:
                return address;

            case rgbIndex_t::g:
                return address + NUMBER_OF_LED_COLUMNS * 1;

            case rgbIndex_t::b:
                return address + NUMBER_OF_LED_COLUMNS * 2;
            }

            return 0;
#else
            return rgbID * 3 + static_cast<uint8_t>(index);
#endif
        }

        uint8_t getRGBID(uint8_t ledID)
        {
#ifdef NUMBER_OF_LED_COLUMNS
            uint8_t row = ledID / NUMBER_OF_LED_COLUMNS;

            uint8_t mod = row % 3;
            row -= mod;

            uint8_t column = ledID % NUMBER_OF_LED_COLUMNS;

            uint8_t result = (row * NUMBER_OF_LED_COLUMNS) / 3 + column;

            if (result >= MAX_NUMBER_OF_RGB_LEDS)
                return MAX_NUMBER_OF_RGB_LEDS - 1;
            else
                return result;
#else
            uint8_t result = ledID / 3;

            if (result >= MAX_NUMBER_OF_RGB_LEDS)
                return MAX_NUMBER_OF_RGB_LEDS - 1;
            else
                return result;
#endif
        }
    }    // namespace io

    namespace detail
    {
        namespace io
        {
#ifdef NUMBER_OF_LED_COLUMNS
            void checkDigitalOutputs()
            {
                for (int i = 0; i < NUMBER_OF_LED_ROWS; i++)
                    ledRowOff(i);

                activateOutputColumn();

                //if there is an active LED in current column, turn on LED row
                //do fancy transitions here
                for (int i = 0; i < NUMBER_OF_LED_ROWS; i++)
                {
                    ledIndex       = activeOutColumn + i * NUMBER_OF_LED_COLUMNS;
                    ledStateSingle = ledState[ledIndex] && (NUMBER_OF_LED_TRANSITIONS - 1);

                    //don't bother with pwm if it's disabled
#ifdef LED_FADING
                    if (!pwmSteps && ledStateSingle)
                    {
                        ledRowOn(i, 255);
                    }
                    else
                    {
                        if (ledTransitionScale[transitionCounter[ledIndex]])
                            ledRowOn(i, ledTransitionScale[transitionCounter[ledIndex]]);

                        if (transitionCounter[ledIndex] != ledStateSingle)
                        {
                            //fade up
                            if (transitionCounter[ledIndex] < ledStateSingle)
                            {
                                transitionCounter[ledIndex] += pwmSteps;

                                if (transitionCounter[ledIndex] > ledStateSingle)
                                    transitionCounter[ledIndex] = ledStateSingle;
                            }
                            else
                            {
                                //fade down
                                transitionCounter[ledIndex] -= pwmSteps;

                                if (transitionCounter[ledIndex] < 0)
                                    transitionCounter[ledIndex] = 0;
                            }
                        }
                    }
#else
                    if (ledStateSingle)
                        ledRowOn(i);
#endif
                }

                if (++activeOutColumn == NUMBER_OF_LED_COLUMNS)
                    activeOutColumn = 0;
            }
#elif defined(NUMBER_OF_OUT_SR)
            ///
            /// \brief Checks if any LED state has been changed and writes changed state to output shift registers.
            ///
            void checkDigitalOutputs()
            {
                if (updateOutputs)
                {
                    CORE_IO_SET_LOW(SR_OUT_LATCH_PORT, SR_OUT_LATCH_PIN);

                    for (int j = 0; j < NUMBER_OF_OUT_SR; j++)
                    {
                        for (int i = 0; i < NUMBER_OF_OUT_SR_INPUTS; i++)
                        {
                            ledIndex = i + j * NUMBER_OF_OUT_SR_INPUTS;

                            ledState[ledIndex] ? EXT_LED_ON(SR_OUT_DATA_PORT, SR_OUT_DATA_PIN) : EXT_LED_OFF(SR_OUT_DATA_PORT, SR_OUT_DATA_PIN);
                            CORE_IO_SET_LOW(SR_OUT_CLK_PORT, SR_OUT_CLK_PIN);
                            _NOP();
                            _NOP();
                            CORE_IO_SET_HIGH(SR_OUT_CLK_PORT, SR_OUT_CLK_PIN);
                        }
                    }

                    CORE_IO_SET_HIGH(SR_OUT_LATCH_PORT, SR_OUT_LATCH_PIN);
                    updateOutputs = false;
                }
            }
#else
            void checkDigitalOutputs()
            {
                if (updateOutputs)
                {
                    for (int i = 0; i < MAX_NUMBER_OF_LEDS; i++)
                    {
                        pin = Board::detail::map::led(i);

                        if (ledState[i])
                            EXT_LED_ON(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin));
                        else
                            EXT_LED_OFF(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin));
                    }

                    updateOutputs = false;
                }
            }
#endif
        }    // namespace io
    }        // namespace detail
}    // namespace Board<|endoftext|>