<commit_before>#include <algorithm>
#include <functional>
#include <iomanip>

#include "hidb.hh"
#include "variant-id.hh"
#include "vaccines.hh"

// ----------------------------------------------------------------------

#pragma GCC diagnostic push
#ifdef __clang__
#pragma GCC diagnostic ignored "-Wexit-time-destructors"
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#endif

static std::map<std::string, std::vector<hidb::Vaccine>> sVaccines = {
    {"A(H1N1)", {
            {"CALIFORNIA/7/2009",        hidb::Vaccine::Previous},
            {"MICHIGAN/45/2015",         hidb::Vaccine::Current},
        }},
    {"A(H3N2)", {
            {"BRISBANE/10/2007",         hidb::Vaccine::Previous},
            {"PERTH/16/2009",            hidb::Vaccine::Previous},
            {"VICTORIA/361/2011",        hidb::Vaccine::Previous},
            {"TEXAS/50/2012",            hidb::Vaccine::Previous},
            {"SWITZERLAND/9715293/2013", hidb::Vaccine::Previous},
            {"HONG KONG/4801/2014",      hidb::Vaccine::Current},
            {"SAITAMA/103/2014",         hidb::Vaccine::Surrogate},
            {"HONG KONG/7295/2014",      hidb::Vaccine::Surrogate},
        }},
    {"BVICTORIA", {
            {"MALAYSIA/2506/2004",       hidb::Vaccine::Previous},
            {"BRISBANE/60/2008",         hidb::Vaccine::Current},
              // {"PARIS/1762/2009",          hidb::Vaccine::Current}, // not used by Crick anymore, B/Ireland/3154/2016 is used instead (2017-08-21)
            {"SOUTH AUSTRALIA/81/2012",  hidb::Vaccine::Surrogate},
            {"IRELAND/3154/2016",  hidb::Vaccine::Surrogate},
        }},
    {"BYAMAGATA", {
            {"FLORIDA/4/2006",           hidb::Vaccine::Previous},
            {"WISCONSIN/1/2010",         hidb::Vaccine::Previous},
            {"MASSACHUSETTS/2/2012",     hidb::Vaccine::Previous},
            {"PHUKET/3073/2013",         hidb::Vaccine::Current},
        }},
};

#pragma GCC diagnostic pop

// ----------------------------------------------------------------------

std::string hidb::Vaccine::type_as_string(hidb::Vaccine::Type aType)
{
    switch (aType) {
      case Previous:
          return "previous";
      case Current:
          return "current";
      case Surrogate:
          return "surrogate";
    }
    return {};

} // hidb::Vaccine::type_as_string

// ----------------------------------------------------------------------

hidb::Vaccine::Type hidb::Vaccine::type_from_string(std::string aType)
{
    if (aType == "previous")
        return Previous;
    else if (aType == "current")
        return Current;
    else if (aType == "surrogate")
        return Surrogate;
    return Previous;

} // hidb::Vaccine::type_from_string

// ----------------------------------------------------------------------

const std::vector<hidb::Vaccine>& hidb::vaccines(std::string aSubtype, std::string aLineage)
{
    return sVaccines.at(aSubtype + aLineage);

} // hidb::vaccines

// ----------------------------------------------------------------------

const std::vector<hidb::Vaccine>& hidb::vaccines(const Chart& aChart)
{
    return vaccines(aChart.chart_info().virus_type(), aChart.lineage());

} // hidb::vaccines

// ----------------------------------------------------------------------

std::string hidb::Vaccine::type_as_string() const
{
    return type_as_string(type);

} // hidb::Vaccine::type_as_string

// ----------------------------------------------------------------------

inline bool hidb::Vaccines::Entry::operator < (const hidb::Vaccines::Entry& a) const
{
    const auto a_nt = a.antigen_data->number_of_tables(), t_nt = antigen_data->number_of_tables();
    return t_nt == a_nt ? most_recent_table_date > a.most_recent_table_date : t_nt > a_nt;
}

// ----------------------------------------------------------------------

bool hidb::Vaccines::HomologousSerum::operator < (const hidb::Vaccines::HomologousSerum& a) const
{
    bool result = true;
    if (serum->serum_species() == "SHEEP") { // avoid using sheep serum as homologous (NIMR)
        result = false;
    }
    else {
        const auto s_nt = a.serum_data->number_of_tables(), t_nt = serum_data->number_of_tables();
        result = t_nt == s_nt ? most_recent_table_date > a.most_recent_table_date : t_nt > s_nt;
    }
    return result;

} // hidb::Vaccines::HomologousSerum::operator <

// ----------------------------------------------------------------------

size_t hidb::Vaccines::HomologousSerum::number_of_tables() const
{
    return serum_data->number_of_tables();

} // hidb::Vaccines::HomologousSerum::number_of_tables

// ----------------------------------------------------------------------

std::string hidb::Vaccines::report(size_t aIndent) const
{
    std::ostringstream out;
    if (!empty()) {
        out << std::string(aIndent, ' ') << "Vaccine " << type_as_string() << ' ' << mNameType.name << std::endl;
        for_each_passage_type([&](PassageType pt) { out << this->report(pt, aIndent + 2); });
    }
    return out.str();

} // hidb::Vaccines::report

// ----------------------------------------------------------------------

std::string hidb::Vaccines::report(PassageType aPassageType, size_t aIndent, size_t aMark) const
{
    std::ostringstream out;
    const std::string indent(aIndent, ' ');
    auto entry_report = [&](size_t aNo, const auto& entry, bool aMarkIt) {
        out << indent << (aMarkIt ? ">>" : "  ") << std::setw(2) << aNo << ' ' << entry.antigen_index << ' ' << entry.antigen->full_name() << " tables:" << entry.antigen_data->number_of_tables() << " recent:" << entry.antigen_data->most_recent_table().table_id() << std::endl;
        for (const auto& hs: entry.homologous_sera)
            out << indent << "      " << hs.serum->serum_id() << ' ' << hs.serum->annotations().join() << " tables:" << hs.serum_data->number_of_tables() << " recent:" << hs.serum_data->most_recent_table().table_id() << std::endl;
    };

    const auto& entry = mEntries[aPassageType];
    if (!entry.empty()) {
        out << indent << passage_type_name(aPassageType) << " (" << entry.size() << ')' << std::endl;
        for (size_t no = 0; no < entry.size(); ++no)
            entry_report(no, entry[no], aMark == no);
    }
    return out.str();

} // hidb::Vaccines::report

// ----------------------------------------------------------------------

void hidb::vaccines_for_name(Vaccines& aVaccines, std::string aName, const Chart& aChart, const hidb::HiDb& aHiDb)
{
    for (size_t ag_no: aChart.antigens().find_by_name(aName)) {
        try {
            const auto& ag = static_cast<const Antigen&>(aChart.antigen(ag_no));
              // std::cerr << ag.full_name() << std::endl;
            const auto& data = aHiDb.find_antigen_of_chart(ag);
            std::vector<hidb::Vaccines::HomologousSerum> homologous_sera;
            for (const auto* sd: aHiDb.find_homologous_sera(data)) {
                if (const auto sr_no = aChart.sera().find_by_full_name(hidb::name_for_exact_matching(sd->data())))
                    homologous_sera.emplace_back(*sr_no, static_cast<const Serum*>(&aChart.serum(*sr_no)), sd, aHiDb.charts()[sd->most_recent_table().table_id()].chart_info().date());
            }
            aVaccines.add(ag_no, ag, &data, std::move(homologous_sera), aHiDb.charts()[data.most_recent_table().table_id()].chart_info().date());
        }
        catch (hidb::HiDb::NotFound&) {
        }
    }
    aVaccines.sort();

} // hidb::vaccines_for_name

// ----------------------------------------------------------------------

hidb::Vaccines* hidb::find_vaccines_in_chart(std::string aName, const Chart& aChart, const hidb::HiDb& aHiDb)
{
    Vaccines* result = new Vaccines(Vaccine(aName, hidb::Vaccine::Previous));
    vaccines_for_name(*result, aName, aChart, aHiDb);
    return result;

} // find_vaccines_in_chart

// ----------------------------------------------------------------------

void hidb::vaccines(VaccinesOfChart& aVaccinesOfChart, const Chart& aChart, const hidb::HiDb& aHiDb)
{
    for (const auto& name_type: vaccines(aChart)) {
        aVaccinesOfChart.emplace_back(name_type);
        vaccines_for_name(aVaccinesOfChart.back(), name_type.name, aChart, aHiDb);
    }

} // hidb::vaccines

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

std::string hidb::VaccinesOfChart::report(size_t aIndent) const
{
    std::string result;
    for (const auto& v: *this)
        result += v.report(aIndent);
    return result;

} // hidb::VaccinesOfChart::report

// ----------------------------------------------------------------------

// void hidb::VaccinesOfChart::remove(std::string aName, std::string aType, std::string aPassageType)
// {
//     for (auto& v: *this) {
//         if (v.match(aName, aType))
//             v.remove(aPassageType);
//     }
//     erase(std::remove_if(begin(), end(), std::mem_fn<bool() const>(&hidb::Vaccines::empty)), end());

// } // hidb::VaccinesOfChart::remove

// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>new H3 vaccine<commit_after>#include <algorithm>
#include <functional>
#include <iomanip>

#include "hidb.hh"
#include "variant-id.hh"
#include "vaccines.hh"

// ----------------------------------------------------------------------

#pragma GCC diagnostic push
#ifdef __clang__
#pragma GCC diagnostic ignored "-Wexit-time-destructors"
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#endif

static std::map<std::string, std::vector<hidb::Vaccine>> sVaccines = {
    {"A(H1N1)", {
            {"CALIFORNIA/7/2009",        hidb::Vaccine::Previous},
            {"MICHIGAN/45/2015",         hidb::Vaccine::Current},
        }},
    {"A(H3N2)", {
            {"BRISBANE/10/2007",         hidb::Vaccine::Previous},
            {"PERTH/16/2009",            hidb::Vaccine::Previous},
            {"VICTORIA/361/2011",        hidb::Vaccine::Previous},
            {"TEXAS/50/2012",            hidb::Vaccine::Previous},
            {"SWITZERLAND/9715293/2013", hidb::Vaccine::Previous},
            {"HONG KONG/4801/2014",      hidb::Vaccine::Previous},
            {"SINGAPORE/INFIMH-16-0019/2016", hidb::Vaccine::Current},
            {"SAITAMA/103/2014",         hidb::Vaccine::Surrogate},
            {"HONG KONG/7295/2014",      hidb::Vaccine::Surrogate},
        }},
    {"BVICTORIA", {
            {"MALAYSIA/2506/2004",       hidb::Vaccine::Previous},
            {"BRISBANE/60/2008",         hidb::Vaccine::Current},
              // {"PARIS/1762/2009",          hidb::Vaccine::Current}, // not used by Crick anymore, B/Ireland/3154/2016 is used instead (2017-08-21)
            {"SOUTH AUSTRALIA/81/2012",  hidb::Vaccine::Surrogate},
            {"IRELAND/3154/2016",        hidb::Vaccine::Surrogate},
        }},
    {"BYAMAGATA", {
            {"FLORIDA/4/2006",           hidb::Vaccine::Previous},
            {"WISCONSIN/1/2010",         hidb::Vaccine::Previous},
            {"MASSACHUSETTS/2/2012",     hidb::Vaccine::Previous},
            {"PHUKET/3073/2013",         hidb::Vaccine::Current},
        }},
};

#pragma GCC diagnostic pop

// ----------------------------------------------------------------------

std::string hidb::Vaccine::type_as_string(hidb::Vaccine::Type aType)
{
    switch (aType) {
      case Previous:
          return "previous";
      case Current:
          return "current";
      case Surrogate:
          return "surrogate";
    }
    return {};

} // hidb::Vaccine::type_as_string

// ----------------------------------------------------------------------

hidb::Vaccine::Type hidb::Vaccine::type_from_string(std::string aType)
{
    if (aType == "previous")
        return Previous;
    else if (aType == "current")
        return Current;
    else if (aType == "surrogate")
        return Surrogate;
    return Previous;

} // hidb::Vaccine::type_from_string

// ----------------------------------------------------------------------

const std::vector<hidb::Vaccine>& hidb::vaccines(std::string aSubtype, std::string aLineage)
{
    return sVaccines.at(aSubtype + aLineage);

} // hidb::vaccines

// ----------------------------------------------------------------------

const std::vector<hidb::Vaccine>& hidb::vaccines(const Chart& aChart)
{
    return vaccines(aChart.chart_info().virus_type(), aChart.lineage());

} // hidb::vaccines

// ----------------------------------------------------------------------

std::string hidb::Vaccine::type_as_string() const
{
    return type_as_string(type);

} // hidb::Vaccine::type_as_string

// ----------------------------------------------------------------------

inline bool hidb::Vaccines::Entry::operator < (const hidb::Vaccines::Entry& a) const
{
    const auto a_nt = a.antigen_data->number_of_tables(), t_nt = antigen_data->number_of_tables();
    return t_nt == a_nt ? most_recent_table_date > a.most_recent_table_date : t_nt > a_nt;
}

// ----------------------------------------------------------------------

bool hidb::Vaccines::HomologousSerum::operator < (const hidb::Vaccines::HomologousSerum& a) const
{
    bool result = true;
    if (serum->serum_species() == "SHEEP") { // avoid using sheep serum as homologous (NIMR)
        result = false;
    }
    else {
        const auto s_nt = a.serum_data->number_of_tables(), t_nt = serum_data->number_of_tables();
        result = t_nt == s_nt ? most_recent_table_date > a.most_recent_table_date : t_nt > s_nt;
    }
    return result;

} // hidb::Vaccines::HomologousSerum::operator <

// ----------------------------------------------------------------------

size_t hidb::Vaccines::HomologousSerum::number_of_tables() const
{
    return serum_data->number_of_tables();

} // hidb::Vaccines::HomologousSerum::number_of_tables

// ----------------------------------------------------------------------

std::string hidb::Vaccines::report(size_t aIndent) const
{
    std::ostringstream out;
    if (!empty()) {
        out << std::string(aIndent, ' ') << "Vaccine " << type_as_string() << ' ' << mNameType.name << std::endl;
        for_each_passage_type([&](PassageType pt) { out << this->report(pt, aIndent + 2); });
    }
    return out.str();

} // hidb::Vaccines::report

// ----------------------------------------------------------------------

std::string hidb::Vaccines::report(PassageType aPassageType, size_t aIndent, size_t aMark) const
{
    std::ostringstream out;
    const std::string indent(aIndent, ' ');
    auto entry_report = [&](size_t aNo, const auto& entry, bool aMarkIt) {
        out << indent << (aMarkIt ? ">>" : "  ") << std::setw(2) << aNo << ' ' << entry.antigen_index << ' ' << entry.antigen->full_name() << " tables:" << entry.antigen_data->number_of_tables() << " recent:" << entry.antigen_data->most_recent_table().table_id() << std::endl;
        for (const auto& hs: entry.homologous_sera)
            out << indent << "      " << hs.serum->serum_id() << ' ' << hs.serum->annotations().join() << " tables:" << hs.serum_data->number_of_tables() << " recent:" << hs.serum_data->most_recent_table().table_id() << std::endl;
    };

    const auto& entry = mEntries[aPassageType];
    if (!entry.empty()) {
        out << indent << passage_type_name(aPassageType) << " (" << entry.size() << ')' << std::endl;
        for (size_t no = 0; no < entry.size(); ++no)
            entry_report(no, entry[no], aMark == no);
    }
    return out.str();

} // hidb::Vaccines::report

// ----------------------------------------------------------------------

void hidb::vaccines_for_name(Vaccines& aVaccines, std::string aName, const Chart& aChart, const hidb::HiDb& aHiDb)
{
    for (size_t ag_no: aChart.antigens().find_by_name(aName)) {
        try {
            const auto& ag = static_cast<const Antigen&>(aChart.antigen(ag_no));
              // std::cerr << ag.full_name() << std::endl;
            const auto& data = aHiDb.find_antigen_of_chart(ag);
            std::vector<hidb::Vaccines::HomologousSerum> homologous_sera;
            for (const auto* sd: aHiDb.find_homologous_sera(data)) {
                if (const auto sr_no = aChart.sera().find_by_full_name(hidb::name_for_exact_matching(sd->data())))
                    homologous_sera.emplace_back(*sr_no, static_cast<const Serum*>(&aChart.serum(*sr_no)), sd, aHiDb.charts()[sd->most_recent_table().table_id()].chart_info().date());
            }
            aVaccines.add(ag_no, ag, &data, std::move(homologous_sera), aHiDb.charts()[data.most_recent_table().table_id()].chart_info().date());
        }
        catch (hidb::HiDb::NotFound&) {
        }
    }
    aVaccines.sort();

} // hidb::vaccines_for_name

// ----------------------------------------------------------------------

hidb::Vaccines* hidb::find_vaccines_in_chart(std::string aName, const Chart& aChart, const hidb::HiDb& aHiDb)
{
    Vaccines* result = new Vaccines(Vaccine(aName, hidb::Vaccine::Previous));
    vaccines_for_name(*result, aName, aChart, aHiDb);
    return result;

} // find_vaccines_in_chart

// ----------------------------------------------------------------------

void hidb::vaccines(VaccinesOfChart& aVaccinesOfChart, const Chart& aChart, const hidb::HiDb& aHiDb)
{
    for (const auto& name_type: vaccines(aChart)) {
        aVaccinesOfChart.emplace_back(name_type);
        vaccines_for_name(aVaccinesOfChart.back(), name_type.name, aChart, aHiDb);
    }

} // hidb::vaccines

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

std::string hidb::VaccinesOfChart::report(size_t aIndent) const
{
    std::string result;
    for (const auto& v: *this)
        result += v.report(aIndent);
    return result;

} // hidb::VaccinesOfChart::report

// ----------------------------------------------------------------------

// void hidb::VaccinesOfChart::remove(std::string aName, std::string aType, std::string aPassageType)
// {
//     for (auto& v: *this) {
//         if (v.match(aName, aType))
//             v.remove(aPassageType);
//     }
//     erase(std::remove_if(begin(), end(), std::mem_fn<bool() const>(&hidb::Vaccines::empty)), end());

// } // hidb::VaccinesOfChart::remove

// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    DicomSeriesReadPrintTags.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

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

//  Software Guide : BeginLatex
//
//  This example illustrates how to read a DICOM series into a volume
//  and then save this volume in another file format.
//
//  Software Guide : EndLatex

#include "itkImageSeriesReader.h"
#include "itkGDCMImageIO.h"
#include "itkGDCMSeriesFileNames.h"

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

  if( argc < 2 )
    {
    std::cerr << "Usage: " << argv[0] << " DicomDirectory " << std::endl;
    return EXIT_FAILURE;
    }

  typedef itk::Image<unsigned short,3>            ImageType;
  typedef itk::ImageSeriesReader< ImageType >     ReaderType;

  typedef itk::GDCMImageIO                        ImageIOType;

  ImageIOType::Pointer dicomIO = ImageIOType::New();

  // Get the DICOM filenames from the directory
  typedef itk::GDCMSeriesFileNames NamesGeneratorType;
  NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
  nameGenerator->SetInputDirectory( argv[1] );

  typedef std::vector<std::string> fileNamesContainer;
  fileNamesContainer fileNames;
  fileNames = nameGenerator->GetInputFileNames();
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileNames( fileNames );
  reader->SetImageIO( dicomIO );

  try
    {
    reader->Update();
    }
  catch (itk::ExceptionObject &ex)
    {
    std::cout << ex << std::endl;
    return EXIT_FAILURE;
    }

  typedef itk::MetaDataDictionary   DictionaryType;

  const  DictionaryType & dictionary = dicomIO->GetMetaDataDictionary();

  DictionaryType::ConstIterator itr = dictionary.Begin();
  DictionaryType::ConstIterator end = dictionary.End();

  typedef itk::MetaDataObject< std::string > MetaDataStringType;

  while( itr != end )
    {
    itk::MetaDataObjectBase::Pointer  entry = itr->second;

    MetaDataStringType::Pointer entryvalue =
      dynamic_cast<MetaDataStringType *>( entry.GetPointer() ) ;

    if( entryvalue )
      {
      std::string tagkey   = itr->first;
      std::string tagvalue = entryvalue->GetMetaDataObjectValue();
      std::cout << tagkey <<  " = " << tagvalue << std::endl;
      }
    ++itr;
    }

//  Software Guide : BeginLatex
//
//  In order to read a specific tag, the string of the entry can be used
//  for quering the MetaDataDictionary.
//
//  Software Guide : EndLatex

    std::string entryId = "Patient Name";
    itk::MetaDataObjectBase::ConstPointer  entry = dictionary[entryId];

    MetaDataStringType::ConstPointer entryvalue =
      dynamic_cast<const MetaDataStringType *>( entry.GetPointer() ) ;

    if( entryvalue )
      {
      std::string tagvalue = entryvalue->GetMetaDataObjectValue();
      std::cout << entryId <<  " = " << tagvalue << std::endl;
      }

  return EXIT_SUCCESS;

}

<commit_msg>ENH: Corrected a few typoes<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    DicomSeriesReadPrintTags.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

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

//  Software Guide : BeginLatex
//
//  This example illustrates how to read a DICOM series into a volume
//  and then print most of the DICOM header information (binary field are skipped)
//
//  Software Guide : EndLatex

#include "itkImageSeriesReader.h"
#include "itkGDCMImageIO.h"
#include "itkGDCMSeriesFileNames.h"

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

  if( argc < 2 )
    {
    std::cerr << "Usage: " << argv[0] << " DicomDirectory " << std::endl;
    return EXIT_FAILURE;
    }

  typedef itk::Image<unsigned short,3>            ImageType;
  typedef itk::ImageSeriesReader< ImageType >     ReaderType;

  typedef itk::GDCMImageIO                        ImageIOType;

  ImageIOType::Pointer dicomIO = ImageIOType::New();

  // Get the DICOM filenames from the directory
  typedef itk::GDCMSeriesFileNames NamesGeneratorType;
  NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
  nameGenerator->SetInputDirectory( argv[1] );

  typedef std::vector<std::string> fileNamesContainer;
  fileNamesContainer fileNames;
  fileNames = nameGenerator->GetInputFileNames();
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileNames( fileNames );
  reader->SetImageIO( dicomIO );

  try
    {
    reader->Update();
    }
  catch (itk::ExceptionObject &ex)
    {
    std::cout << ex << std::endl;
    return EXIT_FAILURE;
    }

  typedef itk::MetaDataDictionary   DictionaryType;

  const  DictionaryType & dictionary = dicomIO->GetMetaDataDictionary();

  DictionaryType::ConstIterator itr = dictionary.Begin();
  DictionaryType::ConstIterator end = dictionary.End();

  typedef itk::MetaDataObject< std::string > MetaDataStringType;

  while( itr != end )
    {
    itk::MetaDataObjectBase::Pointer  entry = itr->second;

    MetaDataStringType::Pointer entryvalue =
      dynamic_cast<MetaDataStringType *>( entry.GetPointer() ) ;

    if( entryvalue )
      {
      std::string tagkey   = itr->first;
      std::string tagvalue = entryvalue->GetMetaDataObjectValue();
      std::cout << tagkey <<  " = " << tagvalue << std::endl;
      }
    ++itr;
    }

//  Software Guide : BeginLatex
//
//  In order to read a specific tag, the string of the entry can be used
//  for quering the MetaDataDictionary.
//
//  Software Guide : EndLatex

    //std::string entryId = "Patient Name"; //DICOM 2002
    std::string entryId = "Patient's Name"; //DICOM 2003
    itk::MetaDataObjectBase::ConstPointer  entry = dictionary[entryId];

    MetaDataStringType::ConstPointer entryvalue =
      dynamic_cast<const MetaDataStringType *>( entry.GetPointer() ) ;

    if( entryvalue )
      {
      std::string tagvalue = entryvalue->GetMetaDataObjectValue();
      std::cout << entryId <<  " = " << tagvalue << std::endl;
      }

  return EXIT_SUCCESS;

}

<|endoftext|>


<commit_before>/**
 * @file SparseVector.hpp
 *
 * SparseVector class.
 *
 * @author Kamil Ritz <kritz@ethz.ch>
 * @author Julian Kent <julian@auterion.com>
 *
 */

#pragma once

#include "math.hpp"

namespace matrix {
template<int N> struct force_constexpr_eval {
    static const int value = N;
};

// Vector that only store nonzero elements,
// which indices are specified as parameter pack
template<typename Type, size_t M, size_t... Idxs>
class SparseVector {
private:
    static constexpr size_t N = sizeof...(Idxs);
    static constexpr size_t _indices[N] {Idxs...};

    static constexpr bool duplicateIndices() {
        for (size_t i = 0; i < N; i++)
            for (size_t j = 0; j < i; j++)
                if (_indices[i] == _indices[j])
                    return true;
        return false;
    }
    static constexpr size_t findMaxIndex() {
        size_t maxIndex = 0;
        for (size_t i = 0; i < N; i++) {
            if (maxIndex < _indices[i]) {
                maxIndex = _indices[i];
            }
        }
        return maxIndex;
    }

    static_assert(duplicateIndices() == false, "Duplicate indices");
    static_assert(N < M, "More entries than elements, use a dense vector");
    static_assert(N > 0, "A sparse vector needs at least one element");
    static_assert(findMaxIndex() < M, "Largest entry doesn't fit in sparse vector");

    Type _data[N] {};

    static constexpr int findCompressedIndex(size_t index) {
        int compressedIndex = -1;
        for (size_t i = 0; i < N; i++) {
            if (index == _indices[i]) {
                compressedIndex = static_cast<int>(i);
            }
        }
        return compressedIndex;
    }

public:
    constexpr size_t non_zeros() const {
        return N;
    }

    constexpr size_t index(size_t i) const {
        return SparseVector::_indices[i];
    }

    SparseVector() = default;

    SparseVector(const matrix::Vector<Type, M>& data) {
        for (size_t i = 0; i < N; i++) {
            _data[i] = data(_indices[i]);
        }
    }

    explicit SparseVector(const Type data[N]) {
        memcpy(_data, data, sizeof(_data));
    }

    template <size_t i>
    inline Type at() const {
        static constexpr int compressed_index = force_constexpr_eval<findCompressedIndex(i)>::value;
        static_assert(compressed_index >= 0, "cannot access unpopulated indices");
        return _data[compressed_index];
    }

    template <size_t i>
    inline Type& at() {
        static constexpr int compressed_index = force_constexpr_eval<findCompressedIndex(i)>::value;
        static_assert(compressed_index >= 0, "cannot access unpopulated indices");
        return _data[compressed_index];
    }

    inline Type atCompressedIndex(size_t i) const {
        assert(i < N);
        return _data[i];
    }

    inline Type& atCompressedIndex(size_t i) {
        assert(i < N);
        return _data[i];
    }

    void setZero() {
        for (size_t i = 0; i < N; i++) {
            _data[i] = Type(0);
        }
    }

    Type dot(const matrix::Vector<Type, M>& other) const {
        Type accum (0);
        for (size_t i = 0; i < N; i++) {
            accum += _data[i] * other(_indices[i]);
        }
        return accum;
    }

    matrix::Vector<Type, M> operator+(const matrix::Vector<Type, M>& other) const {
        matrix::Vector<Type, M> vec = other;
        for (size_t i = 0; i < N; i++) {
            vec(_indices[i]) +=  _data[i];
        }
        return vec;
    }

    SparseVector& operator+=(Type t) {
        for (size_t i = 0; i < N; i++) {
            _data[i] += t;
        }
        return *this;
    }

    Type norm_squared() const
    {
        Type accum(0);
        for (size_t i = 0; i < N; i++) {
            accum += _data[i] * _data[i];
        }
        return accum;
    }

    Type norm() const
    {
        return matrix::sqrt(norm_squared());
    }

    bool longerThan(Type testVal) const
    {
        return norm_squared() > testVal*testVal;
    }
};

template<typename Type, size_t Q, size_t M, size_t ... Idxs>
matrix::Vector<Type, Q> operator*(const matrix::Matrix<Type, Q, M>& mat, const matrix::SparseVector<Type, M, Idxs...>& vec) {
    matrix::Vector<Type, Q> res;
    for (size_t i = 0; i < Q; i++) {
        const Vector<Type, M> row = mat.row(i);
        res(i) = vec.dot(row);
    }
    return res;
}

template<typename Type,size_t M, size_t... Idxs>
constexpr size_t SparseVector<Type, M, Idxs...>::_indices[SparseVector<Type, M, Idxs...>::N];

template<size_t M, size_t ... Idxs>
using SparseVectorf = SparseVector<float, M, Idxs...>;

}
<commit_msg>comply with Firmware style requirements<commit_after>/**
 * @file SparseVector.hpp
 *
 * SparseVector class.
 *
 * @author Kamil Ritz <kritz@ethz.ch>
 * @author Julian Kent <julian@auterion.com>
 *
 */

#pragma once

#include "math.hpp"

namespace matrix {
template<int N> struct force_constexpr_eval {
    static const int value = N;
};

// Vector that only store nonzero elements,
// which indices are specified as parameter pack
template<typename Type, size_t M, size_t... Idxs>
class SparseVector {
private:
    static constexpr size_t N = sizeof...(Idxs);
    static constexpr size_t _indices[N] {Idxs...};

    static constexpr bool duplicateIndices() {
        for (size_t i = 0; i < N; i++) {
            for (size_t j = 0; j < i; j++) {
                if (_indices[i] == _indices[j]) {
                    return true;
                }
            }
        }
        return false;
    }
    static constexpr size_t findMaxIndex() {
        size_t maxIndex = 0;
        for (size_t i = 0; i < N; i++) {
            if (maxIndex < _indices[i]) {
                maxIndex = _indices[i];
            }
        }
        return maxIndex;
    }

    static_assert(!duplicateIndices(), "Duplicate indices");
    static_assert(N < M, "More entries than elements, use a dense vector");
    static_assert(N > 0, "A sparse vector needs at least one element");
    static_assert(findMaxIndex() < M, "Largest entry doesn't fit in sparse vector");

    Type _data[N] {};

    static constexpr int findCompressedIndex(size_t index) {
        int compressedIndex = -1;
        for (size_t i = 0; i < N; i++) {
            if (index == _indices[i]) {
                compressedIndex = static_cast<int>(i);
            }
        }
        return compressedIndex;
    }

public:
    constexpr size_t non_zeros() const {
        return N;
    }

    constexpr size_t index(size_t i) const {
        return SparseVector::_indices[i];
    }

    SparseVector() = default;

    SparseVector(const matrix::Vector<Type, M>& data) {
        for (size_t i = 0; i < N; i++) {
            _data[i] = data(_indices[i]);
        }
    }

    explicit SparseVector(const Type data[N]) {
        memcpy(_data, data, sizeof(_data));
    }

    template <size_t i>
    inline Type at() const {
        static constexpr int compressed_index = force_constexpr_eval<findCompressedIndex(i)>::value;
        static_assert(compressed_index >= 0, "cannot access unpopulated indices");
        return _data[compressed_index];
    }

    template <size_t i>
    inline Type& at() {
        static constexpr int compressed_index = force_constexpr_eval<findCompressedIndex(i)>::value;
        static_assert(compressed_index >= 0, "cannot access unpopulated indices");
        return _data[compressed_index];
    }

    inline Type atCompressedIndex(size_t i) const {
        assert(i < N);
        return _data[i];
    }

    inline Type& atCompressedIndex(size_t i) {
        assert(i < N);
        return _data[i];
    }

    void setZero() {
        for (size_t i = 0; i < N; i++) {
            _data[i] = Type(0);
        }
    }

    Type dot(const matrix::Vector<Type, M>& other) const {
        Type accum (0);
        for (size_t i = 0; i < N; i++) {
            accum += _data[i] * other(_indices[i]);
        }
        return accum;
    }

    matrix::Vector<Type, M> operator+(const matrix::Vector<Type, M>& other) const {
        matrix::Vector<Type, M> vec = other;
        for (size_t i = 0; i < N; i++) {
            vec(_indices[i]) +=  _data[i];
        }
        return vec;
    }

    SparseVector& operator+=(Type t) {
        for (size_t i = 0; i < N; i++) {
            _data[i] += t;
        }
        return *this;
    }

    Type norm_squared() const
    {
        Type accum(0);
        for (size_t i = 0; i < N; i++) {
            accum += _data[i] * _data[i];
        }
        return accum;
    }

    Type norm() const
    {
        return matrix::sqrt(norm_squared());
    }

    bool longerThan(Type testVal) const
    {
        return norm_squared() > testVal*testVal;
    }
};

template<typename Type, size_t Q, size_t M, size_t ... Idxs>
matrix::Vector<Type, Q> operator*(const matrix::Matrix<Type, Q, M>& mat, const matrix::SparseVector<Type, M, Idxs...>& vec) {
    matrix::Vector<Type, Q> res;
    for (size_t i = 0; i < Q; i++) {
        const Vector<Type, M> row = mat.row(i);
        res(i) = vec.dot(row);
    }
    return res;
}

template<typename Type,size_t M, size_t... Idxs>
constexpr size_t SparseVector<Type, M, Idxs...>::_indices[SparseVector<Type, M, Idxs...>::N];

template<size_t M, size_t ... Idxs>
using SparseVectorf = SparseVector<float, M, Idxs...>;

}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_i18npool.hxx"

#include <transliteration_commonclass.hxx>
#include <com/sun/star/i18n/CollatorOptions.hpp>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::rtl;

namespace com { namespace sun { namespace star { namespace i18n {

transliteration_commonclass::transliteration_commonclass()
{
        transliterationName = "";
        implementationName = "";
        useOffset = sal_True;
}

OUString SAL_CALL transliteration_commonclass::getName() throw(RuntimeException)
{
        return OUString::createFromAscii(transliterationName);
}

void SAL_CALL transliteration_commonclass::loadModule( TransliterationModules /*modName*/, const Locale& rLocale )
        throw(RuntimeException)
{
        aLocale = rLocale;
}

void SAL_CALL
transliteration_commonclass::loadModuleNew( const Sequence < TransliterationModulesNew >& /*modName*/, const Locale& /*rLocale*/ )
        throw(RuntimeException)
{
        throw RuntimeException();
}

void SAL_CALL
transliteration_commonclass::loadModuleByImplName( const OUString& /*implName*/, const Locale& /*rLocale*/ )
        throw(RuntimeException)
{
        throw RuntimeException();
}

void SAL_CALL
transliteration_commonclass::loadModulesByImplNames(const Sequence< OUString >& /*modNamelist*/, const Locale& /*rLocale*/)
        throw(RuntimeException)
{
        throw RuntimeException();
}

Sequence< OUString > SAL_CALL
transliteration_commonclass::getAvailableModules( const Locale& /*rLocale*/, sal_Int16 /*sType*/ )
        throw(RuntimeException)
{
        throw RuntimeException();
}

sal_Int32 SAL_CALL
transliteration_commonclass::compareSubstring(
        const OUString& str1, sal_Int32 off1, sal_Int32 len1,
        const OUString& str2, sal_Int32 off2, sal_Int32 len2)
        throw(RuntimeException)
{
        const sal_Unicode* unistr1 = NULL;
        const sal_Unicode* unistr2 = NULL;
        sal_uInt32 strlen1;
        sal_uInt32 strlen2;

        Sequence <sal_Int32> offset1(2*len1);
        Sequence <sal_Int32> offset2(2*len2);

        OUString in_str1 = this->transliterate(str1, off1, len1, offset1);
        OUString in_str2 = this->transliterate(str2, off2, len2, offset2);
        strlen1 = in_str1.getLength();
        strlen2 = in_str2.getLength();
        unistr1 = in_str1.getStr();
        unistr2 = in_str2.getStr();

        while (strlen1 && strlen2)
        {
            sal_uInt32 ret = *unistr1 - *unistr2;
            if (ret)
               return ret;

            unistr1++;
            unistr2++;
            strlen1--;
            strlen2--;
        }
        return strlen1 - strlen2;
}

sal_Int32 SAL_CALL
transliteration_commonclass::compareString( const OUString& str1, const OUString& str2 ) throw ( RuntimeException)
{
        return( this->compareSubstring(str1, 0, str1.getLength(), str2, 0, str2.getLength()));
}

OUString SAL_CALL
transliteration_commonclass::transliterateString2String( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount ) throw(RuntimeException)
{
    static Sequence < sal_Int32 > dummy_offset;
    useOffset = sal_False;
    OUString tmpStr = transliterate(inStr, startPos, nCount, dummy_offset);
    useOffset = sal_True;
    return tmpStr;
}

OUString SAL_CALL
transliteration_commonclass::transliterateChar2String( sal_Unicode inChar ) throw(RuntimeException)
{
    return transliteration_commonclass::transliterateString2String(OUString(&inChar, 1), 0, 1);
}

OUString SAL_CALL transliteration_commonclass::getImplementationName() throw( RuntimeException )
{
    return OUString::createFromAscii(implementationName);
}

const sal_Char cTrans[] = "com.sun.star.i18n.Transliteration.l10n";

sal_Bool SAL_CALL transliteration_commonclass::supportsService(const OUString& rServiceName) throw( RuntimeException )
{
        return rServiceName.equalsAscii(cTrans);
}

Sequence< OUString > SAL_CALL transliteration_commonclass::getSupportedServiceNames() throw( RuntimeException )
{
        Sequence< OUString > aRet(1);
        aRet[0] = OUString::createFromAscii(cTrans);
        return aRet;
}

} } } }

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>overly static<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_i18npool.hxx"

#include <transliteration_commonclass.hxx>
#include <com/sun/star/i18n/CollatorOptions.hpp>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::rtl;

namespace com { namespace sun { namespace star { namespace i18n {

transliteration_commonclass::transliteration_commonclass()
{
        transliterationName = "";
        implementationName = "";
        useOffset = sal_True;
}

OUString SAL_CALL transliteration_commonclass::getName() throw(RuntimeException)
{
        return OUString::createFromAscii(transliterationName);
}

void SAL_CALL transliteration_commonclass::loadModule( TransliterationModules /*modName*/, const Locale& rLocale )
        throw(RuntimeException)
{
        aLocale = rLocale;
}

void SAL_CALL
transliteration_commonclass::loadModuleNew( const Sequence < TransliterationModulesNew >& /*modName*/, const Locale& /*rLocale*/ )
        throw(RuntimeException)
{
        throw RuntimeException();
}

void SAL_CALL
transliteration_commonclass::loadModuleByImplName( const OUString& /*implName*/, const Locale& /*rLocale*/ )
        throw(RuntimeException)
{
        throw RuntimeException();
}

void SAL_CALL
transliteration_commonclass::loadModulesByImplNames(const Sequence< OUString >& /*modNamelist*/, const Locale& /*rLocale*/)
        throw(RuntimeException)
{
        throw RuntimeException();
}

Sequence< OUString > SAL_CALL
transliteration_commonclass::getAvailableModules( const Locale& /*rLocale*/, sal_Int16 /*sType*/ )
        throw(RuntimeException)
{
        throw RuntimeException();
}

sal_Int32 SAL_CALL
transliteration_commonclass::compareSubstring(
        const OUString& str1, sal_Int32 off1, sal_Int32 len1,
        const OUString& str2, sal_Int32 off2, sal_Int32 len2)
        throw(RuntimeException)
{
        const sal_Unicode* unistr1 = NULL;
        const sal_Unicode* unistr2 = NULL;
        sal_uInt32 strlen1;
        sal_uInt32 strlen2;

        Sequence <sal_Int32> offset1(2*len1);
        Sequence <sal_Int32> offset2(2*len2);

        OUString in_str1 = this->transliterate(str1, off1, len1, offset1);
        OUString in_str2 = this->transliterate(str2, off2, len2, offset2);
        strlen1 = in_str1.getLength();
        strlen2 = in_str2.getLength();
        unistr1 = in_str1.getStr();
        unistr2 = in_str2.getStr();

        while (strlen1 && strlen2)
        {
            sal_uInt32 ret = *unistr1 - *unistr2;
            if (ret)
               return ret;

            unistr1++;
            unistr2++;
            strlen1--;
            strlen2--;
        }
        return strlen1 - strlen2;
}

sal_Int32 SAL_CALL
transliteration_commonclass::compareString( const OUString& str1, const OUString& str2 ) throw ( RuntimeException)
{
        return( this->compareSubstring(str1, 0, str1.getLength(), str2, 0, str2.getLength()));
}

OUString SAL_CALL
transliteration_commonclass::transliterateString2String( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount ) throw(RuntimeException)
{
    Sequence < sal_Int32 > dummy_offset;
    useOffset = sal_False;
    OUString tmpStr = transliterate(inStr, startPos, nCount, dummy_offset);
    useOffset = sal_True;
    return tmpStr;
}

OUString SAL_CALL
transliteration_commonclass::transliterateChar2String( sal_Unicode inChar ) throw(RuntimeException)
{
    return transliteration_commonclass::transliterateString2String(OUString(&inChar, 1), 0, 1);
}

OUString SAL_CALL transliteration_commonclass::getImplementationName() throw( RuntimeException )
{
    return OUString::createFromAscii(implementationName);
}

const sal_Char cTrans[] = "com.sun.star.i18n.Transliteration.l10n";

sal_Bool SAL_CALL transliteration_commonclass::supportsService(const OUString& rServiceName) throw( RuntimeException )
{
        return rServiceName.equalsAscii(cTrans);
}

Sequence< OUString > SAL_CALL transliteration_commonclass::getSupportedServiceNames() throw( RuntimeException )
{
        Sequence< OUString > aRet(1);
        aRet[0] = OUString::createFromAscii(cTrans);
        return aRet;
}

} } } }

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before><commit_msg>fix bugs of multiplication for integers<commit_after><|endoftext|>


<commit_before>//RUN: make -C %testexecdir/../../clang/ test TESTSUITE=Sema CLANG=%p/clangTestUnloader.sh
//XFAIL: *

// Current SemaCXX failures:
// Expected Passes    : 392
// Expected Failures  : 1
// Unexpected Failures: 184

// Current Sema failures:
// Expected Passes    : 331
// Unexpected Failures: 90
<commit_msg>This test is a no-op in CMake - we need to fix that.<commit_after>//RUN: make -C %testexecdir/../../clang/ test TESTSUITE=Sema CLANG=%p/clangTestUnloader.sh

// FIXME: this test is a no-op in CMake :-(

// Current SemaCXX failures:
// Expected Passes    : 392
// Expected Failures  : 1
// Unexpected Failures: 184

// Current Sema failures:
// Expected Passes    : 331
// Unexpected Failures: 90
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

// From Apache Impala as of 2016-01-29. Pared down to a minimal set of
// functions needed for parquet-cpp

#include "parquet/util/cpu-info.h"

#ifdef __APPLE__
#include <sys/sysctl.h>
#endif

#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <boost/algorithm/string.hpp>

#include <algorithm>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>

#include "parquet/exception.h"

using boost::algorithm::contains;
using boost::algorithm::trim;
using std::max;
using std::string;

namespace parquet {

bool CpuInfo::initialized_ = false;
int64_t CpuInfo::hardware_flags_ = 0;
int64_t CpuInfo::original_hardware_flags_;
int64_t CpuInfo::cache_sizes_[L3_CACHE + 1];
int64_t CpuInfo::cycles_per_ms_;
int CpuInfo::num_cores_ = 1;
string CpuInfo::model_name_ = "unknown";  // NOLINT

static struct {
  string name;
  int64_t flag;
} flag_mappings[] = {
    {"ssse3", CpuInfo::SSSE3}, {"sse4_1", CpuInfo::SSE4_1}, {"sse4_2", CpuInfo::SSE4_2},
    {"popcnt", CpuInfo::POPCNT},
};
static const int64_t num_flags = sizeof(flag_mappings) / sizeof(flag_mappings[0]);

// Helper function to parse for hardware flags.
// values contains a list of space-seperated flags.  check to see if the flags we
// care about are present.
// Returns a bitmap of flags.
int64_t ParseCPUFlags(const string& values) {
  int64_t flags = 0;
  for (int i = 0; i < num_flags; ++i) {
    if (contains(values, flag_mappings[i].name)) { flags |= flag_mappings[i].flag; }
  }
  return flags;
}

void CpuInfo::Init() {
  string line;
  string name;
  string value;

  float max_mhz = 0;
  int num_cores = 0;

  memset(&cache_sizes_, 0, sizeof(cache_sizes_));

  // Read from /proc/cpuinfo
  std::ifstream cpuinfo("/proc/cpuinfo", std::ios::in);
  while (cpuinfo) {
    getline(cpuinfo, line);
    size_t colon = line.find(':');
    if (colon != string::npos) {
      name = line.substr(0, colon - 1);
      value = line.substr(colon + 1, string::npos);
      trim(name);
      trim(value);
      if (name.compare("flags") == 0) {
        hardware_flags_ |= ParseCPUFlags(value);
      } else if (name.compare("cpu MHz") == 0) {
        // Every core will report a different speed.  We'll take the max, assuming
        // that when impala is running, the core will not be in a lower power state.
        // TODO: is there a more robust way to do this, such as
        // Window's QueryPerformanceFrequency()
        float mhz = atof(value.c_str());
        max_mhz = max(mhz, max_mhz);
      } else if (name.compare("processor") == 0) {
        ++num_cores;
      } else if (name.compare("model name") == 0) {
        model_name_ = value;
      }
    }
  }
  if (cpuinfo.is_open()) cpuinfo.close();

#ifdef __APPLE__
  // On Mac OS X use sysctl() to get the cache sizes
  size_t len = 0;
  sysctlbyname("hw.cachesize", NULL, &len, NULL, 0);
  uint64_t* data = static_cast<uint64_t*>(malloc(len));
  sysctlbyname("hw.cachesize", data, &len, NULL, 0);
  DCHECK(len / sizeof(uint64_t) >= 3);
  for (size_t i = 0; i < 3; ++i) {
    cache_sizes_[i] = data[i];
  }
#else
  // Call sysconf to query for the cache sizes
  cache_sizes_[0] = sysconf(_SC_LEVEL1_DCACHE_SIZE);
  cache_sizes_[1] = sysconf(_SC_LEVEL2_CACHE_SIZE);
  cache_sizes_[2] = sysconf(_SC_LEVEL3_CACHE_SIZE);
#endif

  if (max_mhz != 0) {
    cycles_per_ms_ = max_mhz * 1000;
  } else {
    cycles_per_ms_ = 1000000;
  }
  original_hardware_flags_ = hardware_flags_;

  if (num_cores > 0) {
    num_cores_ = num_cores;
  } else {
    num_cores_ = 1;
  }

  initialized_ = true;
}

void CpuInfo::VerifyCpuRequirements() {
  if (!CpuInfo::IsSupported(CpuInfo::SSSE3)) {
    throw ParquetException("CPU does not support the Supplemental SSE3 instruction set");
  }
}

void CpuInfo::EnableFeature(int64_t flag, bool enable) {
  DCHECK(initialized_);
  if (!enable) {
    hardware_flags_ &= ~flag;
  } else {
    // Can't turn something on that can't be supported
    DCHECK((original_hardware_flags_ & flag) != 0);
    hardware_flags_ |= flag;
  }
}

}  // namespace parquet
<commit_msg>PARQUET-846: CpuInfo::Init() is not thread safe<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

// From Apache Impala as of 2016-01-29. Pared down to a minimal set of
// functions needed for parquet-cpp

#include "parquet/util/cpu-info.h"

#ifdef __APPLE__
#include <sys/sysctl.h>
#endif

#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <boost/algorithm/string.hpp>

#include <algorithm>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <mutex>
#include <sstream>
#include <string>

#include "parquet/exception.h"

using boost::algorithm::contains;
using boost::algorithm::trim;
using std::max;
using std::string;

namespace parquet {

bool CpuInfo::initialized_ = false;
int64_t CpuInfo::hardware_flags_ = 0;
int64_t CpuInfo::original_hardware_flags_;
int64_t CpuInfo::cache_sizes_[L3_CACHE + 1];
int64_t CpuInfo::cycles_per_ms_;
int CpuInfo::num_cores_ = 1;
string CpuInfo::model_name_ = "unknown";  // NOLINT
static std::mutex cpuinfo_mutex;

static struct {
  string name;
  int64_t flag;
} flag_mappings[] = {
    {"ssse3", CpuInfo::SSSE3}, {"sse4_1", CpuInfo::SSE4_1}, {"sse4_2", CpuInfo::SSE4_2},
    {"popcnt", CpuInfo::POPCNT},
};
static const int64_t num_flags = sizeof(flag_mappings) / sizeof(flag_mappings[0]);

// Helper function to parse for hardware flags.
// values contains a list of space-seperated flags.  check to see if the flags we
// care about are present.
// Returns a bitmap of flags.
int64_t ParseCPUFlags(const string& values) {
  int64_t flags = 0;
  for (int i = 0; i < num_flags; ++i) {
    if (contains(values, flag_mappings[i].name)) { flags |= flag_mappings[i].flag; }
  }
  return flags;
}

void CpuInfo::Init() {
  std::lock_guard<std::mutex> cpuinfo_lock(cpuinfo_mutex);

  if (initialized()) { return; }

  string line;
  string name;
  string value;

  float max_mhz = 0;
  int num_cores = 0;

  memset(&cache_sizes_, 0, sizeof(cache_sizes_));

  // Read from /proc/cpuinfo
  std::ifstream cpuinfo("/proc/cpuinfo", std::ios::in);
  while (cpuinfo) {
    getline(cpuinfo, line);
    size_t colon = line.find(':');
    if (colon != string::npos) {
      name = line.substr(0, colon - 1);
      value = line.substr(colon + 1, string::npos);
      trim(name);
      trim(value);
      if (name.compare("flags") == 0) {
        hardware_flags_ |= ParseCPUFlags(value);
      } else if (name.compare("cpu MHz") == 0) {
        // Every core will report a different speed.  We'll take the max, assuming
        // that when impala is running, the core will not be in a lower power state.
        // TODO: is there a more robust way to do this, such as
        // Window's QueryPerformanceFrequency()
        float mhz = atof(value.c_str());
        max_mhz = max(mhz, max_mhz);
      } else if (name.compare("processor") == 0) {
        ++num_cores;
      } else if (name.compare("model name") == 0) {
        model_name_ = value;
      }
    }
  }
  if (cpuinfo.is_open()) cpuinfo.close();

#ifdef __APPLE__
  // On Mac OS X use sysctl() to get the cache sizes
  size_t len = 0;
  sysctlbyname("hw.cachesize", NULL, &len, NULL, 0);
  uint64_t* data = static_cast<uint64_t*>(malloc(len));
  sysctlbyname("hw.cachesize", data, &len, NULL, 0);
  DCHECK(len / sizeof(uint64_t) >= 3);
  for (size_t i = 0; i < 3; ++i) {
    cache_sizes_[i] = data[i];
  }
#else
  // Call sysconf to query for the cache sizes
  cache_sizes_[0] = sysconf(_SC_LEVEL1_DCACHE_SIZE);
  cache_sizes_[1] = sysconf(_SC_LEVEL2_CACHE_SIZE);
  cache_sizes_[2] = sysconf(_SC_LEVEL3_CACHE_SIZE);
#endif

  if (max_mhz != 0) {
    cycles_per_ms_ = max_mhz * 1000;
  } else {
    cycles_per_ms_ = 1000000;
  }
  original_hardware_flags_ = hardware_flags_;

  if (num_cores > 0) {
    num_cores_ = num_cores;
  } else {
    num_cores_ = 1;
  }

  initialized_ = true;
}

void CpuInfo::VerifyCpuRequirements() {
  if (!CpuInfo::IsSupported(CpuInfo::SSSE3)) {
    throw ParquetException("CPU does not support the Supplemental SSE3 instruction set");
  }
}

void CpuInfo::EnableFeature(int64_t flag, bool enable) {
  DCHECK(initialized_);
  if (!enable) {
    hardware_flags_ &= ~flag;
  } else {
    // Can't turn something on that can't be supported
    DCHECK((original_hardware_flags_ & flag) != 0);
    hardware_flags_ |= flag;
  }
}

}  // namespace parquet
<|endoftext|>


<commit_before>/**
* @file IMUModel.cpp
*
* Definition of class IMUModel
*
* @author Steffen Kaden
*/

#include "IMUModel.h"

IMUModel::IMUModel() :
    integrated(1,0,0,0)
{
    DEBUG_REQUEST_REGISTER("IMUModel:reset_filter", "reset filter", false);
    DEBUG_REQUEST_REGISTER("IMUModel:reset_representation", "reset representation", false);
    DEBUG_REQUEST_REGISTER("IMUModel:reloadParameters", "", false);
    DEBUG_REQUEST_REGISTER("IMUModel:enableFilterWhileWalking", "enables filter update while walking", false);

    DEBUG_REQUEST_REGISTER("IMUModel:drawOnlyOrientation","if activated it only draws the orientation (x,y)",false);
    DEBUG_REQUEST_REGISTER("IMUModel:enablePlotsAndDrawings", "enables plots and the drawings in 3d viewer", false);

    ukf_acc_global.P = Eigen::Matrix<double,3,3>::Identity(); // covariance matrix of current state
    ukf_rot.P        = Eigen::Matrix<double,6,6>::Identity(); // covariance matrix of current state

    getDebugParameterList().add(&imuParameters);

    reloadParameters();
}

IMUModel::~IMUModel()
{
    getDebugParameterList().remove(&imuParameters);
}

void IMUModel::execute()
{
    DEBUG_REQUEST("IMUModel:reset_filter",
                  ukf_rot.reset();
                  ukf_acc_global.reset();
                  integrated=Eigen::Quaterniond(1,0,0,0);
    );

    DEBUG_REQUEST("IMUModel:reset_representation",
        getIMUData().reset();
    );

    DEBUG_REQUEST("IMUModel:reloadParameters",
        reloadParameters();
    );

    /* handle ukf filter for rotation */
    if(getMotionStatus().currentMotion == motion::walk){
        ukf_rot.Q = Q_rotation_walk;
    } else {
        ukf_rot.Q = Q_rotation;
    }

    ukf_rot.generateSigmaPoints();

    Eigen::Vector3d u_rot(0,0,0); // TODO: use generated angular acceleration as control vector?
    ukf_rot.predict(u_rot, getRobotInfo().getBasicTimeStepInSecond());

    // don't generate sigma points again because the process noise would be applied a second time
    // ukf.generateSigmaPoints();

    Eigen::Vector3d gyro;
    gyro << getGyrometerData().data.x, getGyrometerData().data.y, getGyrometerData().data.z;
    Eigen::Vector3d acceleration = Eigen::Vector3d(getAccelerometerData().data.x, getAccelerometerData().data.y, getAccelerometerData().data.z);

    IMU_RotationMeasurement z;
    z << acceleration.normalized(), gyro;

    if(getMotionStatus().currentMotion == motion::walk) {
        if(imuParameters.enableWhileWalking) {
            ukf_rot.update(z, R_rotation_walk);
        }
    } else {
        ukf_rot.update(z, R_rotation);
    }
    /* rotation ukf end */

    /* handle ukf filter for global acceleration */
    // transform acceleration measurement into global reference frame
    // TODO: Odometry as location measurement?
    // TODO: velocity of trunk in supfoot / local robot frame as velocity measurement
    // TODO: really needs bias removal or "calibration" of g
    IMU_AccMeasurementGlobal z_acc = ukf_rot.state.getRotationAsQuaternion()._transformVector(acceleration);

    if(getMotionStatus().currentMotion == motion::walk) {
        ukf_acc_global.Q = Q_acc_walk;
    } else {
        ukf_acc_global.Q = Q_acc;
    }

    ukf_acc_global.generateSigmaPoints();

    Eigen::Vector3d u_acc(0,0,0); // TODO: use generated jerk as control vector?
    ukf_acc_global.predict(u_acc, getRobotInfo().getBasicTimeStepInSecond());

    if(getMotionStatus().currentMotion == motion::walk) {
        if(imuParameters.enableWhileWalking) {
            ukf_acc_global.update(z_acc, R_acc_walk);
        }
    } else {
        ukf_acc_global.update(z_acc, R_acc);
    }
    /* acc ukf end */

    writeIMUData();

    DEBUG_REQUEST("IMUModel:enablePlotsAndDrawings",
        plots();
    );

    lastFrameInfo = getFrameInfo();
}

void IMUModel::writeIMUData()
{
    // raw sensor values
    getIMUData().rotational_velocity_sensor = getGyrometerData().data;
    getIMUData().acceleration_sensor        = getAccelerometerData().data;

    // global position data
    // TODO: check for correct integration
    // TODO: prediction or state?
    getIMUData().acceleration.x = ukf_acc_global.state.acceleration()(0,0);
    getIMUData().acceleration.y = ukf_acc_global.state.acceleration()(1,0);
    getIMUData().acceleration.z = ukf_acc_global.state.acceleration()(2,0) - 9.81; //Math::g

    getIMUData().location += getIMUData().velocity * getRobotInfo().getBasicTimeStepInSecond() + getIMUData().acceleration * getRobotInfo().getBasicTimeStepInSecond() * getRobotInfo().getBasicTimeStepInSecond() * 0.5;
    getIMUData().velocity += getIMUData().acceleration * getRobotInfo().getBasicTimeStepInSecond();

    // the state we are estimating in ukf_rot is 20 ms in the past. so predict 20 ms as estimate for the real current state
    UKF<RotationState<Measurement<6>,6> > sensor_delay_corrected_rot = ukf_rot;
    sensor_delay_corrected_rot.generateSigmaPoints();
    Eigen::Vector3d u_rot(0,0,0);
    sensor_delay_corrected_rot.predict(u_rot, 2 * getRobotInfo().getBasicTimeStepInSecond());

    // store rotation in IMUData as a rotation vector
    getIMUData().rotation = eigenVectorToVector3D(sensor_delay_corrected_rot.state.rotation());
    RotationMatrix bodyIntoGlobalMapping(getIMUData().rotation);

    /*
     * Note: the following code lines use the inverse mapping, i.e. globalIntoBodyMapping, by using the third row of bodyIntoGlobalMapping's matrix representation
     * Note: The negative of the determined angles is the correct solution in this case because the projected "global" z axis is not pointing upwards in the torso's coordinate system.
     * The projected "global" z axis in the Body frame is NOT (0,0,1)!
     * So actually we want the inverse mapping.
     * Inverting the angle is sufficient because it's basically only a 2D rotation in the XZ or YZ plane
     * Note: using bodyIntoGlobalMapping would be wrong because the global frame can be rotated around z regarding the body
     * this would result in a redistribution of the inclination on the x,y axis.
     * (e.g. z rotation about 90° -> a rotation about the body's y axis becomes a rotation about the global x axis)
     * Note: don't use the y axis to determine the inclination in YZ plane because it might be mapped onto the x axis (a rotation about 90° around z)
     * this results in huge devation of the angles determined by atan2 because the projected y axis might end up in the second or third quadrant of the YZ plane
     */

    Eigen::Vector3d global_Z_in_body(bodyIntoGlobalMapping[0].z, bodyIntoGlobalMapping[1].z, bodyIntoGlobalMapping[2].z);
    getIMUData().orientation_rotvec = quaternionToVector3D(Eigen::Quaterniond::FromTwoVectors(global_Z_in_body, Eigen::Vector3d(0,0,1)));
    RotationMatrix bodyIntoGlobalMappingWithoutZ(getIMUData().orientation_rotvec);

    getIMUData().orientation = Vector2d(-atan2(bodyIntoGlobalMappingWithoutZ[2].y, bodyIntoGlobalMappingWithoutZ[1].y),
                                        -atan2(-bodyIntoGlobalMappingWithoutZ[2].x, bodyIntoGlobalMappingWithoutZ[0].x));

    PLOT("IMUModel:State:orientation:x", Math::toDegrees(getIMUData().orientation.x));
    PLOT("IMUModel:State:orientation:y", Math::toDegrees(getIMUData().orientation.y));

    getIMUData().rotational_velocity.x = ukf_rot.state.rotational_velocity()(0,0);
    getIMUData().rotational_velocity.y = ukf_rot.state.rotational_velocity()(1,0);
    getIMUData().rotational_velocity.z = ukf_rot.state.rotational_velocity()(2,0);
}

void IMUModel::plots()
{
    // --- for testing integration
        Eigen::Matrix3d rot_vel_mat;
        // getGyrometerData().data.z is inverted!
        rot_vel_mat << 1                             , -getGyrometerData().data.z*0.01,  getGyrometerData().data.y*0.01,
                       getGyrometerData().data.z*0.01,                               1, -getGyrometerData().data.x*0.01,
                      -getGyrometerData().data.y*0.01,  getGyrometerData().data.x*0.01,                               1;

        // continue rotation assuming constant velocity
        integrated = integrated * Eigen::Quaterniond(rot_vel_mat);

        Vector3d translation(0,250,250);
        LINE_3D(ColorClasses::red, translation, translation + quaternionToVector3D(integrated) * 100.0);
        LINE_3D(ColorClasses::blue, translation, translation + quaternionToVector3D(ukf_rot.state.getRotationAsQuaternion()) * 100.0);

        PLOT("IMUModel:Error:relative_to_pure_integration[°]", Math::toDegrees(Eigen::AngleAxisd(integrated*ukf_rot.state.getRotationAsQuaternion().inverse()).angle()));
    // --- end

    Eigen::Vector3d temp2 = ukf_rot.state.rotation();
    Vector3d rot_vec(temp2(0),temp2(1),temp2(2));
    RotationMatrix rot(rot_vec);

    DEBUG_REQUEST("IMUModel:drawOnlyOrientation",
        rot = RotationMatrix(getIMUData().orientation_rotvec);
    );

    Pose3D pose(rot);
    pose.translation = Vector3d(0,0,250);

    // plot gravity
    Eigen::Vector3d acceleration;
    acceleration << getAccelerometerData().data.x, getAccelerometerData().data.y, getAccelerometerData().data.z;
    Eigen::Vector3d temp3 = ukf_rot.state.getRotationAsQuaternion()._transformVector(acceleration);
    Vector3d gravity(6*temp3(0),6*temp3(1),6*temp3(2));

    COLOR_CUBE(30, pose);
    LINE_3D(ColorClasses::black, pose.translation, pose.translation + gravity*10.0);

    PLOT("IMUModel:Measurement:rotational_velocity:x", getGyrometerData().data.x);
    PLOT("IMUModel:Measurement:rotational_velocity:y", getGyrometerData().data.y);
    PLOT("IMUModel:Measurement:rotational_velocity:z", getGyrometerData().data.z);

    PLOT("IMUModel:State:orientation:x", Math::toDegrees(getIMUData().orientation.x));
    PLOT("IMUModel:State:orientation:y", Math::toDegrees(getIMUData().orientation.y));
}

void IMUModel::reloadParameters()
{   /* parameters for the acceleration filter */
    // process noise
    Q_acc.setIdentity();
    Q_acc *= imuParameters.acceleration.stand.processNoiseAcc;

    Q_acc_walk.setIdentity();
    Q_acc *= imuParameters.acceleration.walk.processNoiseAcc;

    // measurement covariance matrix
    R_acc.setIdentity();
    R_acc *= imuParameters.acceleration.stand.measurementNoiseAcc;

    R_acc_walk.setIdentity();
    R_acc_walk *= imuParameters.acceleration.walk.measurementNoiseAcc;

    /* parameters for the rotation filter */
    // process noise
    Q_rotation.setIdentity();
    Q_rotation.block<3,3>(0,0) *= imuParameters.rotation.stand.processNoiseRot;
    Q_rotation.block<3,3>(3,3) *= imuParameters.rotation.stand.processNoiseGyro;

    Q_rotation_walk.setIdentity();
    Q_rotation.block<3,3>(0,0) *= imuParameters.rotation.walk.processNoiseRot;
    Q_rotation.block<3,3>(3,3) *= imuParameters.rotation.walk.processNoiseGyro;

    // measurement covariance matrix
    R_rotation.setIdentity();
    R_rotation.block<3,3>(0,0) *= imuParameters.rotation.stand.measurementNoiseAcc;
    R_rotation.block<3,3>(3,3) *= imuParameters.rotation.stand.measurementNoiseGyro;

    R_rotation_walk.setIdentity();
    R_rotation_walk.block<3,3>(0,0) *= imuParameters.rotation.walk.measurementNoiseAcc;
    R_rotation_walk.block<3,3>(3,3) *= imuParameters.rotation.walk.measurementNoiseGyro;
}
<commit_msg>parameters for walking were applied to the wrong matrix<commit_after>/**
* @file IMUModel.cpp
*
* Definition of class IMUModel
*
* @author Steffen Kaden
*/

#include "IMUModel.h"

IMUModel::IMUModel() :
    integrated(1,0,0,0)
{
    DEBUG_REQUEST_REGISTER("IMUModel:reset_filter", "reset filter", false);
    DEBUG_REQUEST_REGISTER("IMUModel:reset_representation", "reset representation", false);
    DEBUG_REQUEST_REGISTER("IMUModel:reloadParameters", "", false);
    DEBUG_REQUEST_REGISTER("IMUModel:enableFilterWhileWalking", "enables filter update while walking", false);

    DEBUG_REQUEST_REGISTER("IMUModel:drawOnlyOrientation","if activated it only draws the orientation (x,y)",false);
    DEBUG_REQUEST_REGISTER("IMUModel:enablePlotsAndDrawings", "enables plots and the drawings in 3d viewer", false);

    ukf_acc_global.P = Eigen::Matrix<double,3,3>::Identity(); // covariance matrix of current state
    ukf_rot.P        = Eigen::Matrix<double,6,6>::Identity(); // covariance matrix of current state

    getDebugParameterList().add(&imuParameters);

    reloadParameters();
}

IMUModel::~IMUModel()
{
    getDebugParameterList().remove(&imuParameters);
}

void IMUModel::execute()
{
    DEBUG_REQUEST("IMUModel:reset_filter",
                  ukf_rot.reset();
                  ukf_acc_global.reset();
                  integrated=Eigen::Quaterniond(1,0,0,0);
    );

    DEBUG_REQUEST("IMUModel:reset_representation",
        getIMUData().reset();
    );

    DEBUG_REQUEST("IMUModel:reloadParameters",
        reloadParameters();
    );

    /* handle ukf filter for rotation */
    if(getMotionStatus().currentMotion == motion::walk){
        ukf_rot.Q = Q_rotation_walk;
    } else {
        ukf_rot.Q = Q_rotation;
    }

    ukf_rot.generateSigmaPoints();

    Eigen::Vector3d u_rot(0,0,0); // TODO: use generated angular acceleration as control vector?
    ukf_rot.predict(u_rot, getRobotInfo().getBasicTimeStepInSecond());

    // don't generate sigma points again because the process noise would be applied a second time
    // ukf.generateSigmaPoints();

    Eigen::Vector3d gyro;
    gyro << getGyrometerData().data.x, getGyrometerData().data.y, getGyrometerData().data.z;
    Eigen::Vector3d acceleration = Eigen::Vector3d(getAccelerometerData().data.x, getAccelerometerData().data.y, getAccelerometerData().data.z);

    IMU_RotationMeasurement z;
    z << acceleration.normalized(), gyro;

    if(getMotionStatus().currentMotion == motion::walk) {
        if(imuParameters.enableWhileWalking) {
            ukf_rot.update(z, R_rotation_walk);
        }
    } else {
        ukf_rot.update(z, R_rotation);
    }
    /* rotation ukf end */

    /* handle ukf filter for global acceleration */
    // transform acceleration measurement into global reference frame
    // TODO: Odometry as location measurement?
    // TODO: velocity of trunk in supfoot / local robot frame as velocity measurement
    // TODO: really needs bias removal or "calibration" of g
    IMU_AccMeasurementGlobal z_acc = ukf_rot.state.getRotationAsQuaternion()._transformVector(acceleration);

    if(getMotionStatus().currentMotion == motion::walk) {
        ukf_acc_global.Q = Q_acc_walk;
    } else {
        ukf_acc_global.Q = Q_acc;
    }

    ukf_acc_global.generateSigmaPoints();

    Eigen::Vector3d u_acc(0,0,0); // TODO: use generated jerk as control vector?
    ukf_acc_global.predict(u_acc, getRobotInfo().getBasicTimeStepInSecond());

    if(getMotionStatus().currentMotion == motion::walk) {
        if(imuParameters.enableWhileWalking) {
            ukf_acc_global.update(z_acc, R_acc_walk);
        }
    } else {
        ukf_acc_global.update(z_acc, R_acc);
    }
    /* acc ukf end */

    writeIMUData();

    DEBUG_REQUEST("IMUModel:enablePlotsAndDrawings",
        plots();
    );

    lastFrameInfo = getFrameInfo();
}

void IMUModel::writeIMUData()
{
    // raw sensor values
    getIMUData().rotational_velocity_sensor = getGyrometerData().data;
    getIMUData().acceleration_sensor        = getAccelerometerData().data;

    // global position data
    // TODO: check for correct integration
    // TODO: prediction or state?
    getIMUData().acceleration.x = ukf_acc_global.state.acceleration()(0,0);
    getIMUData().acceleration.y = ukf_acc_global.state.acceleration()(1,0);
    getIMUData().acceleration.z = ukf_acc_global.state.acceleration()(2,0) - 9.81; //Math::g

    getIMUData().location += getIMUData().velocity * getRobotInfo().getBasicTimeStepInSecond() + getIMUData().acceleration * getRobotInfo().getBasicTimeStepInSecond() * getRobotInfo().getBasicTimeStepInSecond() * 0.5;
    getIMUData().velocity += getIMUData().acceleration * getRobotInfo().getBasicTimeStepInSecond();

    // the state we are estimating in ukf_rot is 20 ms in the past. so predict 20 ms as estimate for the real current state
    UKF<RotationState<Measurement<6>,6> > sensor_delay_corrected_rot = ukf_rot;
    sensor_delay_corrected_rot.generateSigmaPoints();
    Eigen::Vector3d u_rot(0,0,0);
    sensor_delay_corrected_rot.predict(u_rot, 2 * getRobotInfo().getBasicTimeStepInSecond());

    // store rotation in IMUData as a rotation vector
    getIMUData().rotation = eigenVectorToVector3D(sensor_delay_corrected_rot.state.rotation());
    RotationMatrix bodyIntoGlobalMapping(getIMUData().rotation);

    /*
     * Note: the following code lines use the inverse mapping, i.e. globalIntoBodyMapping, by using the third row of bodyIntoGlobalMapping's matrix representation
     * Note: The negative of the determined angles is the correct solution in this case because the projected "global" z axis is not pointing upwards in the torso's coordinate system.
     * The projected "global" z axis in the Body frame is NOT (0,0,1)!
     * So actually we want the inverse mapping.
     * Inverting the angle is sufficient because it's basically only a 2D rotation in the XZ or YZ plane
     * Note: using bodyIntoGlobalMapping would be wrong because the global frame can be rotated around z regarding the body
     * this would result in a redistribution of the inclination on the x,y axis.
     * (e.g. z rotation about 90° -> a rotation about the body's y axis becomes a rotation about the global x axis)
     * Note: don't use the y axis to determine the inclination in YZ plane because it might be mapped onto the x axis (a rotation about 90° around z)
     * this results in huge devation of the angles determined by atan2 because the projected y axis might end up in the second or third quadrant of the YZ plane
     */

    Eigen::Vector3d global_Z_in_body(bodyIntoGlobalMapping[0].z, bodyIntoGlobalMapping[1].z, bodyIntoGlobalMapping[2].z);
    getIMUData().orientation_rotvec = quaternionToVector3D(Eigen::Quaterniond::FromTwoVectors(global_Z_in_body, Eigen::Vector3d(0,0,1)));
    RotationMatrix bodyIntoGlobalMappingWithoutZ(getIMUData().orientation_rotvec);

    getIMUData().orientation = Vector2d(-atan2(bodyIntoGlobalMappingWithoutZ[2].y, bodyIntoGlobalMappingWithoutZ[1].y),
                                        -atan2(-bodyIntoGlobalMappingWithoutZ[2].x, bodyIntoGlobalMappingWithoutZ[0].x));

    PLOT("IMUModel:State:orientation:x", Math::toDegrees(getIMUData().orientation.x));
    PLOT("IMUModel:State:orientation:y", Math::toDegrees(getIMUData().orientation.y));

    getIMUData().rotational_velocity.x = ukf_rot.state.rotational_velocity()(0,0);
    getIMUData().rotational_velocity.y = ukf_rot.state.rotational_velocity()(1,0);
    getIMUData().rotational_velocity.z = ukf_rot.state.rotational_velocity()(2,0);
}

void IMUModel::plots()
{
    // --- for testing integration
        Eigen::Matrix3d rot_vel_mat;
        // getGyrometerData().data.z is inverted!
        rot_vel_mat << 1                             , -getGyrometerData().data.z*0.01,  getGyrometerData().data.y*0.01,
                       getGyrometerData().data.z*0.01,                               1, -getGyrometerData().data.x*0.01,
                      -getGyrometerData().data.y*0.01,  getGyrometerData().data.x*0.01,                               1;

        // continue rotation assuming constant velocity
        integrated = integrated * Eigen::Quaterniond(rot_vel_mat);

        Vector3d translation(0,250,250);
        LINE_3D(ColorClasses::red, translation, translation + quaternionToVector3D(integrated) * 100.0);
        LINE_3D(ColorClasses::blue, translation, translation + quaternionToVector3D(ukf_rot.state.getRotationAsQuaternion()) * 100.0);

        PLOT("IMUModel:Error:relative_to_pure_integration[°]", Math::toDegrees(Eigen::AngleAxisd(integrated*ukf_rot.state.getRotationAsQuaternion().inverse()).angle()));
    // --- end

    Eigen::Vector3d temp2 = ukf_rot.state.rotation();
    Vector3d rot_vec(temp2(0),temp2(1),temp2(2));
    RotationMatrix rot(rot_vec);

    DEBUG_REQUEST("IMUModel:drawOnlyOrientation",
        rot = RotationMatrix(getIMUData().orientation_rotvec);
    );

    Pose3D pose(rot);
    pose.translation = Vector3d(0,0,250);

    // plot gravity
    Eigen::Vector3d acceleration;
    acceleration << getAccelerometerData().data.x, getAccelerometerData().data.y, getAccelerometerData().data.z;
    Eigen::Vector3d temp3 = ukf_rot.state.getRotationAsQuaternion()._transformVector(acceleration);
    Vector3d gravity(6*temp3(0),6*temp3(1),6*temp3(2));

    COLOR_CUBE(30, pose);
    LINE_3D(ColorClasses::black, pose.translation, pose.translation + gravity*10.0);

    PLOT("IMUModel:Measurement:rotational_velocity:x", getGyrometerData().data.x);
    PLOT("IMUModel:Measurement:rotational_velocity:y", getGyrometerData().data.y);
    PLOT("IMUModel:Measurement:rotational_velocity:z", getGyrometerData().data.z);

    PLOT("IMUModel:State:orientation:x", Math::toDegrees(getIMUData().orientation.x));
    PLOT("IMUModel:State:orientation:y", Math::toDegrees(getIMUData().orientation.y));
}

void IMUModel::reloadParameters()
{   /* parameters for the acceleration filter */
    // process noise
    Q_acc.setIdentity();
    Q_acc *= imuParameters.acceleration.stand.processNoiseAcc;

    Q_acc_walk.setIdentity();
    Q_acc_walk *= imuParameters.acceleration.walk.processNoiseAcc;

    // measurement covariance matrix
    R_acc.setIdentity();
    R_acc *= imuParameters.acceleration.stand.measurementNoiseAcc;

    R_acc_walk.setIdentity();
    R_acc_walk *= imuParameters.acceleration.walk.measurementNoiseAcc;

    /* parameters for the rotation filter */
    // process noise
    Q_rotation.setIdentity();
    Q_rotation.block<3,3>(0,0) *= imuParameters.rotation.stand.processNoiseRot;
    Q_rotation.block<3,3>(3,3) *= imuParameters.rotation.stand.processNoiseGyro;

    Q_rotation_walk.setIdentity();
    Q_rotation_walk.block<3,3>(0,0) *= imuParameters.rotation.walk.processNoiseRot;
    Q_rotation_walk.block<3,3>(3,3) *= imuParameters.rotation.walk.processNoiseGyro;

    // measurement covariance matrix
    R_rotation.setIdentity();
    R_rotation.block<3,3>(0,0) *= imuParameters.rotation.stand.measurementNoiseAcc;
    R_rotation.block<3,3>(3,3) *= imuParameters.rotation.stand.measurementNoiseGyro;

    R_rotation_walk.setIdentity();
    R_rotation_walk.block<3,3>(0,0) *= imuParameters.rotation.walk.measurementNoiseAcc;
    R_rotation_walk.block<3,3>(3,3) *= imuParameters.rotation.walk.measurementNoiseGyro;
}
<|endoftext|>


<commit_before>#ifndef _VKSPIRVPROGRAM_HPP
#define _VKSPIRVPROGRAM_HPP
/*-------------------------------------------------------------------------
 * Vulkan CTS Framework
 * --------------------
 *
 * Copyright (c) 2015 Google Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and/or associated documentation files (the
 * "Materials"), to deal in the Materials without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Materials, and to
 * permit persons to whom the Materials are furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice(s) and this permission notice shall be
 * included in all copies or substantial portions of the Materials.
 *
 * The Materials are Confidential Information as defined by the
 * Khronos Membership Agreement until designated non-confidential by
 * Khronos, at which point this condition clause shall be removed.
 *
 * THE MATERIALS ARE 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
 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 *
 *//*!
 * \file
 * \brief SPIR-V program and binary info.
 *//*--------------------------------------------------------------------*/

#include <string>
#include <sstream>

#include "vkDefs.hpp"
#include "tcuTestLog.hpp"

namespace vk
{

struct SpirVAsmSource
{
	template<typename T>
	SpirVAsmSource& operator<<(const T& val)
	{
		program << val;
		return *this;
	}
	std::ostringstream program;
};

struct SpirVProgramInfo
{
	SpirVProgramInfo()
		: source		(DE_NULL)
		, compileTimeUs	(0)
		, compileOk		(false)
	{
	}

	const SpirVAsmSource*	source;
	std::string				infoLog;
	deUint64				compileTimeUs;
	bool					compileOk;
};

tcu::TestLog&	operator<<			(tcu::TestLog& log, const SpirVProgramInfo& shaderInfo);
tcu::TestLog&	operator<<			(tcu::TestLog& log, const SpirVAsmSource& program);

}

#endif // _VKSPIRVPROGRAM_HPP
<commit_msg>Fix include order in vkSpirVProgram.hpp<commit_after>#ifndef _VKSPIRVPROGRAM_HPP
#define _VKSPIRVPROGRAM_HPP
/*-------------------------------------------------------------------------
 * Vulkan CTS Framework
 * --------------------
 *
 * Copyright (c) 2015 Google Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and/or associated documentation files (the
 * "Materials"), to deal in the Materials without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Materials, and to
 * permit persons to whom the Materials are furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice(s) and this permission notice shall be
 * included in all copies or substantial portions of the Materials.
 *
 * The Materials are Confidential Information as defined by the
 * Khronos Membership Agreement until designated non-confidential by
 * Khronos, at which point this condition clause shall be removed.
 *
 * THE MATERIALS ARE 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
 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 *
 *//*!
 * \file
 * \brief SPIR-V program and binary info.
 *//*--------------------------------------------------------------------*/

#include "vkDefs.hpp"
#include "tcuTestLog.hpp"

#include <string>
#include <sstream>

namespace vk
{

struct SpirVAsmSource
{
	template<typename T>
	SpirVAsmSource& operator<<(const T& val)
	{
		program << val;
		return *this;
	}
	std::ostringstream program;
};

struct SpirVProgramInfo
{
	SpirVProgramInfo()
		: source		(DE_NULL)
		, compileTimeUs	(0)
		, compileOk		(false)
	{
	}

	const SpirVAsmSource*	source;
	std::string				infoLog;
	deUint64				compileTimeUs;
	bool					compileOk;
};

tcu::TestLog&	operator<<			(tcu::TestLog& log, const SpirVProgramInfo& shaderInfo);
tcu::TestLog&	operator<<			(tcu::TestLog& log, const SpirVAsmSource& program);

}

#endif // _VKSPIRVPROGRAM_HPP
<|endoftext|>


<commit_before>/*
    OpenDeck MIDI platform firmware
    Copyright (C) 2015-2018 Igor Petrovic

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "board/Board.h"
#include "Variables.h"

///
/// \brief Array used to store readings from digital input matrix.
///
volatile uint8_t    digitalInBuffer[DIGITAL_IN_BUFFER_SIZE][DIGITAL_IN_ARRAY_SIZE];

///
/// \brief Read only copy of digital input buffer.
/// Used to avoid data overwrite from ISR.
///
uint8_t             digitalInBufferReadOnly[DIGITAL_IN_ARRAY_SIZE];

#ifdef IN_MATRIX
///
/// \brief Holds value of currently active input matrix column.
///
volatile uint8_t    activeInColumn;
#endif

///
/// \brief Holds "head" index position in ring buffer.
///
volatile uint8_t    dIn_head;

///
/// \brief Holds "tail" index position in ring buffer.
///
volatile uint8_t    dIn_tail;

///
/// \brief Holds current number of elements stored in ring buffer.
///
volatile uint8_t    dIn_count;

bool Board::digitalInputDataAvailable()
{
    if (dIn_count)
    {
        ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
        {
            if (++dIn_tail == DIGITAL_IN_BUFFER_SIZE)
                dIn_tail = 0;

            for (int i=0; i<DIGITAL_IN_ARRAY_SIZE; i++)
                digitalInBufferReadOnly[i] = digitalInBuffer[dIn_tail][i];

            dIn_count--;
        }

        return true;
    }

    return false;
}
<commit_msg>avoid calling avr specific stuff in common dir<commit_after>/*
    OpenDeck MIDI platform firmware
    Copyright (C) 2015-2018 Igor Petrovic

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "board/Board.h"
#include "Variables.h"

///
/// \brief Array used to store readings from digital input matrix.
///
volatile uint8_t    digitalInBuffer[DIGITAL_IN_BUFFER_SIZE][DIGITAL_IN_ARRAY_SIZE];

///
/// \brief Read only copy of digital input buffer.
/// Used to avoid data overwrite from ISR.
///
uint8_t             digitalInBufferReadOnly[DIGITAL_IN_ARRAY_SIZE];

#ifdef IN_MATRIX
///
/// \brief Holds value of currently active input matrix column.
///
volatile uint8_t    activeInColumn;
#endif

///
/// \brief Holds "head" index position in ring buffer.
///
volatile uint8_t    dIn_head;

///
/// \brief Holds "tail" index position in ring buffer.
///
volatile uint8_t    dIn_tail;

///
/// \brief Holds current number of elements stored in ring buffer.
///
volatile uint8_t    dIn_count;

bool Board::digitalInputDataAvailable()
{
    if (dIn_count >= DIGITAL_IN_BUFFER_SIZE)
    {
        //ring buffer is full - this section is interrupt-safe currently
        if (++dIn_tail == DIGITAL_IN_BUFFER_SIZE)
            dIn_tail = 0;

        for (int i=0; i<DIGITAL_IN_ARRAY_SIZE; i++)
            digitalInBufferReadOnly[i] = digitalInBuffer[dIn_tail][i];

        dIn_count--;

        return true;
    }

    return false;
}
<|endoftext|>


<commit_before>#include "ciconprovider.h"
#include "../cfilesystemobject.h"
#include "ciconproviderimpl.h"

std::unique_ptr<CIconProvider> CIconProvider::_instance;

const QIcon& CIconProvider::iconForFilesystemObject(const CFileSystemObject &object)
{
	if (!_instance)
	{
		_instance = std::unique_ptr<CIconProvider>(new CIconProvider);
		settingsChanged();
	}

	return _instance->iconFor(object);
}

void CIconProvider::settingsChanged()
{
	if (_instance && _instance->_provider)
	{
		_instance->_provider->settingsChanged();
		_instance->_iconCache.clear();
		_instance->_iconForObject.clear();
	}
}

CIconProvider::CIconProvider() : _provider(new CIconProviderImpl)
{
}

inline static qulonglong hash(const CFileSystemObject& object)
{
	const auto properties = object.properties();
	const auto hashData = QCryptographicHash::hash(
		QByteArray::fromRawData((const char*)&properties.hash, sizeof(properties.hash)) +
			QByteArray::fromRawData((const char*)&properties.modificationDate, sizeof(properties.modificationDate)) +
			QByteArray::fromRawData((const char*)&properties.type, sizeof(properties.type)),
		QCryptographicHash::Md5);

	return *(qulonglong*)(hashData.data()) ^ *(qulonglong*)(hashData.data()+8);
}

const QIcon& CIconProvider::iconFor(const CFileSystemObject& object)
{
	const qulonglong objectHash = hash(object);
	if (_iconForObject.count(objectHash) == 0)
	{
		const QIcon icon = _provider->iconFor(object);
		Q_ASSERT(!icon.isNull());

		QCryptographicHash qCryptoHash(QCryptographicHash::Md5);

		const auto qimage = icon.pixmap(icon.availableSizes().front()).toImage();
		qCryptoHash.addData((const char*)qimage.constBits(), qimage.bytesPerLine() * qimage.height());
		const auto result = qCryptoHash.result();
		const qulonglong iconHash = *(qulonglong*)(result.data()) ^ *(qulonglong*)(result.data()+8);
		if (_iconCache.count(iconHash) == 0)
			_iconCache[iconHash] = icon;

		_iconForObject[objectHash] = iconHash;
		return _iconCache[iconHash];
	}

	return _iconCache[_iconForObject[objectHash]];
}
<commit_msg>CIconProvider: 300 icons container size limit; one map element lookup eliminated<commit_after>#include "ciconprovider.h"
#include "../cfilesystemobject.h"
#include "ciconproviderimpl.h"

std::unique_ptr<CIconProvider> CIconProvider::_instance;

const QIcon& CIconProvider::iconForFilesystemObject(const CFileSystemObject &object)
{
	if (!_instance)
	{
		_instance = std::unique_ptr<CIconProvider>(new CIconProvider);
		settingsChanged();
	}

	return _instance->iconFor(object);
}

void CIconProvider::settingsChanged()
{
	if (_instance && _instance->_provider)
	{
		_instance->_provider->settingsChanged();
		_instance->_iconCache.clear();
		_instance->_iconForObject.clear();
	}
}

CIconProvider::CIconProvider() : _provider(new CIconProviderImpl)
{
}

inline static qulonglong hash(const CFileSystemObject& object)
{
	const auto properties = object.properties();
	const auto hashData = QCryptographicHash::hash(
		QByteArray::fromRawData((const char*)&properties.hash, sizeof(properties.hash)) +
			QByteArray::fromRawData((const char*)&properties.modificationDate, sizeof(properties.modificationDate)) +
			QByteArray::fromRawData((const char*)&properties.type, sizeof(properties.type)),
		QCryptographicHash::Md5);

	return *(qulonglong*)(hashData.data()) ^ *(qulonglong*)(hashData.data()+8);
}

const QIcon& CIconProvider::iconFor(const CFileSystemObject& object)
{
	const qulonglong objectHash = hash(object);
	if (_iconForObject.count(objectHash) == 0)
	{
		const QIcon icon = _provider->iconFor(object);
		Q_ASSERT(!icon.isNull());

		QCryptographicHash qCryptoHash(QCryptographicHash::Md5);

		const auto qimage = icon.pixmap(icon.availableSizes().front()).toImage();
		qCryptoHash.addData((const char*)qimage.constBits(), qimage.bytesPerLine() * qimage.height());
		const auto result = qCryptoHash.result();
		const qulonglong iconHash = *(qulonglong*)(result.data()) ^ *(qulonglong*)(result.data()+8);

		if (_iconCache.count(iconHash) == 0)
		{
			if (_iconCache.size() > 300)
			{
				_iconCache.clear();
				_iconForObject.clear();
			}
			_iconCache[iconHash] = icon;
		}

		_iconForObject[objectHash] = iconHash;
		return icon;
	}

	return _iconCache[_iconForObject[objectHash]];
}
<|endoftext|>


<commit_before>// Copyright  2010-2017 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

#pragma once

#include "Stdafx.h"
#include "JavascriptRootObjectWrapper.h"
#include "CefAppUnmanagedWrapper.h"

using namespace System::Threading;

namespace CefSharp
{
    void JavascriptRootObjectWrapper::Bind(ICollection<JavascriptObject^>^ objects, const CefRefPtr<CefV8Value>& v8Value)
    {
        if (objects->Count > 0)
        {
            auto saveMethod = gcnew Func<JavascriptAsyncMethodCallback^, int64>(this, &JavascriptRootObjectWrapper::SaveMethodCallback);
            auto promiseCreator = v8Value->GetValue(CefAppUnmanagedWrapper::kPromiseCreatorFunction);

            for each (JavascriptObject^ obj in Enumerable::OfType<JavascriptObject^>(objects))
            {
                if (obj->IsAsync)
                {
                    auto wrapperObject = gcnew JavascriptAsyncObjectWrapper(_callbackRegistry, saveMethod);
                    wrapperObject->Bind(obj, v8Value, promiseCreator);

                    _wrappedAsyncObjects->Add(wrapperObject);
                }
                else
                {
                    auto wrapperObject = gcnew JavascriptObjectWrapper(_browserProcess);
                    wrapperObject->Bind(obj, v8Value, _callbackRegistry);

                    _wrappedObjects->Add(wrapperObject);
                }
            }
        }
    }

    JavascriptCallbackRegistry^ JavascriptRootObjectWrapper::CallbackRegistry::get()
    {
        return _callbackRegistry;
    }

    int64 JavascriptRootObjectWrapper::SaveMethodCallback(JavascriptAsyncMethodCallback^ callback)
    {
        auto callbackId = Interlocked::Increment(_lastCallback);
        _methodCallbacks->Add(callbackId, callback);
        return callbackId;
    }

    bool JavascriptRootObjectWrapper::TryGetAndRemoveMethodCallback(int64 id, JavascriptAsyncMethodCallback^% callback)
    {
        bool result = false;
        if (result = _methodCallbacks->TryGetValue(id, callback))
        {
            _methodCallbacks->Remove(id);
        }
        return result;
    }
}<commit_msg>JavascriptRootObjectWrapper - Log error when trying to bind sync object when IBrowserProcess is null<commit_after>// Copyright  2010-2017 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

#pragma once

#include "Stdafx.h"
#include "JavascriptRootObjectWrapper.h"
#include "CefAppUnmanagedWrapper.h"

using namespace System::Threading;

namespace CefSharp
{
    void JavascriptRootObjectWrapper::Bind(ICollection<JavascriptObject^>^ objects, const CefRefPtr<CefV8Value>& v8Value)
    {
        if (objects->Count > 0)
        {
            auto saveMethod = gcnew Func<JavascriptAsyncMethodCallback^, int64>(this, &JavascriptRootObjectWrapper::SaveMethodCallback);
            auto promiseCreator = v8Value->GetValue(CefAppUnmanagedWrapper::kPromiseCreatorFunction);

            for each (JavascriptObject^ obj in Enumerable::OfType<JavascriptObject^>(objects))
            {
                if (obj->IsAsync)
                {
                    auto wrapperObject = gcnew JavascriptAsyncObjectWrapper(_callbackRegistry, saveMethod);
                    wrapperObject->Bind(obj, v8Value, promiseCreator);

                    _wrappedAsyncObjects->Add(wrapperObject);
                }
                else
                {
                    if (_browserProcess == nullptr)
                    {
                        LOG(ERROR) << StringUtils::ToNative("IBrowserProcess is null, unable to bind object " + obj->JavascriptName).ToString();

                        continue;
                    }

                    auto wrapperObject = gcnew JavascriptObjectWrapper(_browserProcess);
                    wrapperObject->Bind(obj, v8Value, _callbackRegistry);

                    _wrappedObjects->Add(wrapperObject);
                }
            }
        }
    }

    JavascriptCallbackRegistry^ JavascriptRootObjectWrapper::CallbackRegistry::get()
    {
        return _callbackRegistry;
    }

    int64 JavascriptRootObjectWrapper::SaveMethodCallback(JavascriptAsyncMethodCallback^ callback)
    {
        auto callbackId = Interlocked::Increment(_lastCallback);
        _methodCallbacks->Add(callbackId, callback);
        return callbackId;
    }

    bool JavascriptRootObjectWrapper::TryGetAndRemoveMethodCallback(int64 id, JavascriptAsyncMethodCallback^% callback)
    {
        bool result = false;
        if (result = _methodCallbacks->TryGetValue(id, callback))
        {
            _methodCallbacks->Remove(id);
        }
        return result;
    }
}<|endoftext|>