<commit_before>#ifndef WLWalker_HPP_
#define WLWalker_HPP_

#include "WL_Window.hpp"
#include "MC_Walker.hpp"

#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <iomanip>

struct WL_State
{
   int    ibin;
   double Sval;
   void copy(const WL_State& orig) { ibin=orig.ibin; Sval=orig.Sval; }
   void operator=(const WL_State& orig) { copy(orig); }
};

// Expands an MCWalker to include Wang-Landau information
template<typename Config, typename Observables>
class WL_Walker : public MC_Walker<Config,Observables>
{

public:

   typedef MC_Walker<Config,Observables> BASE;

   double               wlgamma;            // Wang-Landau gamma = ln(f)
   WL_State             wl_now,wl_old;      // Wang-Landau information
   WL_Window            window;             // Wang-Landau Window provides limits and binning
   std::vector<double>  S;                  // Entropy = log-density-of-states
   std::vector<double>  Sfixed;             // Changes only very slowly
   std::vector<double>  h;                  // Visit histogram

   // The sampling window might be smaller than the energy window
   double WEmin,WEmax;

   // Combined WL-Transition Matrix: RG Ghulghazaryan, S. Hayryan, CK Hu, J Comp Chem 28,  715-726 (2007)
   // wleta comes from Eq. (24) S_WL[I] <- (1-wleta)*S_WL[I] + wleta*S_TM[I]
   std::vector<double>  Sittm;              // A local version of the Infinite-temperature transition matrix result
   std::vector<double>  Vittm;              // A local version of the Vittm error matrix
   double    EStepSum;                      // Statistics of how big a MC step is
   long long EStepCnt;

public:

   // Clear the visit histogram
   void clear_histogram()
   {
      if( h.size()!=window.NBin ) h.resize(window.NBin);
      fill(h.begin(),h.end(),0);
   }

   // Clear the estimated entropy
   void clear_entropy()
   {
      S.resize(window.NBin);
      fill(S.begin(),S.end(),0);
      Sfixed.resize(window.NBin);
      fill(Sfixed.begin(),Sfixed.end(),0);
   }

   // Set values of member array. Window must already be set
   void set_values(const std::vector<double>& E, const std::vector<double>& y, std::vector<double>& seq)
   {
      const int nread = E.size();
      if( E.size()<2 )
      {
         std::cout << __FILE__ << ":" << __LINE__ << " Energy array is length " << nread << std::endl;
         int nbin = window.NBin;
         seq.resize(nbin);
         for(int i=0; i<nbin; i++) seq[i] = 0;
         return;
      }
      if( y.size()<nread ) std::cout << __FILE__ << ":" << __LINE__ << " array y is too small" << std::endl;
      int iread = 0;
      int nbin = window.NBin;
      seq.resize(nbin);
      for(int ibin=0; ibin<nbin; ibin++)
      {
         double Eset = window.unbin(ibin);
         while( iread<nread && E[iread]<Eset ) iread++;
         if(iread>=nread) iread = nread-1;
         if(iread<1) iread = 1;
         double E0 = E[iread];
         double y0 = y[iread];
         double E1 = E[iread-1];
         double y1 = y[iread-1];
         double slope = (y1-y0)/(E1-E0);
         seq[ibin] = y0 + slope*(Eset-E0);
      }
   }

   void set_fixed(const std::vector<double>& E, const std::vector<double>& y)
   {
      this->set_values(E,y,this->Sfixed);
   }

   // Deep copy of the walker
   void copy(const WL_Walker<Config,Observables>& orig)
   {
      this->BASE::copy(orig);
      wlgamma = orig.wlgamma;
      wl_now = orig.wl_now;
      wl_old = orig.wl_old;
      window = orig.window;
      S = orig.S;
      Sfixed = orig.Sfixed;
      Sittm = orig.Sittm;
      Vittm = orig.Vittm;
      h = orig.h;
      EStepSum = orig.EStepSum;
      EStepCnt = orig.EStepCnt;
   }

   WL_Walker()
   {
   }

   WL_Walker(const WL_Walker& orig)
   {
       this->copy(orig);
   }

   // Use this to find the current bin of the walker
   int bin() { return wl_now.ibin = window.bin(BASE::now.E); }

   // Estimate Entropy/lndos using linear interpolation
   double get_lndos(double E, bool LinearInterp=true)
   {
      int ibin = window.bin(E);
      double E0 = window.unbin(ibin);
      double S0 = S[ibin] + Sfixed[ibin];
      if( !LinearInterp ) return S0;
      double S1,E1;
      if( E<E0 )
      {
         // look left
         if( ibin==0 )
         {
            // Interpolate to edge half a bin away. Force WL portion to zero
            E1 = window.Elo;
            S1 = S[ibin]+Sfixed[ibin] - 0.5*( Sfixed[ibin+1]-Sfixed[ibin] );
         }
         else
         {
            E1 = window.unbin(ibin-1);
            S1 = S[ibin-1] + Sfixed[ibin-1];
         }
      }
      else
      {
         // look right
         if( ibin==(window.NBin-1) )
         {
            E1 = window.Ehi;
            S1 = S[ibin]+Sfixed[ibin] + 0.5*( Sfixed[ibin]-Sfixed[ibin-1] );
         }
         else
         {
            E1 = window.unbin(ibin+1);
            S1 = S[ibin+1] + Sfixed[ibin+1];
         }
      }
      double slope = (S1-S0)/(E1-E0);
      double SE = S0 + slope*(E-E0);
      return SE;
   }

   float flatness() const
   {
      // Find the prefactor that normalizes histogram such that
      // h_ibin = 1 for perfectly flat histogram (divide by mean h_ibin)
      long long htot = 0;
      int hbin = 0;
      for(int i=0; i<this->window.NBin; i++)
      {
	 if(h[i]>0)
	 {
	    htot += h[i];
	    hbin++;
	 }
      }
      double hnorm = static_cast<double>(hbin)/static_cast<double>(htot);
      // Calculate the flatness for the frozen entropy
      // Q = (1/nbin) \sum_ibin (h_ibin-1)^2
      double Q = 0;
      for(int i=0; i<window.NBin; i++)
      {
	 if( h[i]>0 )
	 {
	    double Qi=(hnorm*h[i]-1);
 	    Q+=Qi*Qi;
	 }
      }
      if( hbin<10 ) Q=1.e+6;   // Not flat if trapped
      return Q;
   }

/*
   bool move_walls(double qflat=0.1)
   {
      //if( move_walls_pileup() ) return true;
      // Calculate the flatness from high energy down
      int ilft = window.bin(WEmin);
      int irgt = window.bin(WEmax);
      const int mincts = 500;   // Minimum vists before move wall past a bin
      int jmax = irgt;
      long long htot = 0;
      int hbin = 0;
      int jbin=jmax;
      for(int kbin=jmax; kbin>0 && kbin>(jmax-5); kbin--)
         if( h[kbin]>1000000 ) jbin=kbin;
      bool flat = true;
      while( jbin>=0 && (flat || h[jbin]>1000000) )
      {
         if( h[jbin]>mincts )
         {
            htot += h[jbin];
            hbin++;
            double hnorm = static_cast<double>(hbin)/static_cast<double>(htot);
            double Q = 0;
            for(int i=jbin; i<=jmax; i++)
            {
               double Q1 = hnorm*h[i]-1;
               Q += Q1*Q1;
            }
            if(hbin>1) Q /= static_cast<double>(hbin);
            flat = (Q<=qflat);
            jbin--;
         }
         else
         {
            flat = false;
         }
      }
      jmax = jbin;
      // Cacluate the flatness from low energy up
      int jmin = ilft;
      htot = 0;
      hbin = 0;
      jbin = jmin;
      if( jbin<(window.NBin-1) && h[jbin+1]>1000000 ) jbin++;
      flat = true;
      while( jbin<window.NBin && (flat || h[jbin]>1000000) )
      {
         if( h[jbin]>mincts )
         {
            htot += h[jbin];
            hbin++;
            double hnorm = static_cast<double>(hbin)/static_cast<double>(htot);
            double Q = 0;
            for(int i=jmin; i<=jbin; i++)
            {
               double Q1 = hnorm*h[i]-1;
               Q += Q1*Q1;
            }
            if(hbin>1) Q /= static_cast<double>(hbin);
            flat = (Q<=qflat);
            jbin++;
         }
         else
         {
            flat = false;
         }
      }
      const int overlap = 5;
      jmin = jbin;
      flat = (jmin>jmax);
      jmax += overlap;
      if(jmax<irgt) irgt=jmax;
      jmin -= overlap;
      if(jmin>ilft) ilft=jmin;
      WEmin = window.unbin(ilft);
      WEmax = window.unbin(irgt);
      return flat;
   }
*/

public:

   void save_initial()
   {
      BASE::save_initial();
      wl_old = wl_now;
   }

   void restore_initial()
   {
      wl_now = wl_old;
      BASE::restore_initial();
   }

};

// Return integer index of wlgamma assuming wlgamma_i+1 = wlgamma_i/2
int igamma(double wlgamma)
{
   int p2 = static_cast<int>(-std::log(wlgamma)/std::log(2.)+0.01);
   return p2;
}

#endif  // WLWalker_HPP_
<commit_msg>Addes Slast<commit_after>#ifndef WLWalker_HPP_
#define WLWalker_HPP_

#include "WL_Window.hpp"
#include "MC_Walker.hpp"

#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <iomanip>

struct WL_State
{
   int    ibin;
   double Sval;
   void copy(const WL_State& orig) { ibin=orig.ibin; Sval=orig.Sval; }
   void operator=(const WL_State& orig) { copy(orig); }
};

// Expands an MCWalker to include Wang-Landau information
template<typename Config, typename Observables>
class WL_Walker : public MC_Walker<Config,Observables>
{

public:

   typedef MC_Walker<Config,Observables> BASE;

   double               wlgamma;            // Wang-Landau gamma = ln(f)
   WL_State             wl_now,wl_old;      // Wang-Landau information
   WL_Window            window;             // Wang-Landau Window provides limits and binning
   std::vector<double>  S;                  // Entropy = log-density-of-states
   std::vector<double>  Slast;              // Last set of values, used to check convergence
   std::vector<double>  Sfixed;             // Changes only very slowly
   std::vector<double>  h;                  // Visit histogram

   // The sampling window might be smaller than the energy window
   double WEmin,WEmax;

   // Combined WL-Transition Matrix: RG Ghulghazaryan, S. Hayryan, CK Hu, J Comp Chem 28,  715-726 (2007)
   // wleta comes from Eq. (24) S_WL[I] <- (1-wleta)*S_WL[I] + wleta*S_TM[I]
   std::vector<double>  Sittm;              // A local version of the Infinite-temperature transition matrix result
   std::vector<double>  Vittm;              // A local version of the Vittm error matrix
   double    EStepSum;                      // Statistics of how big a MC step is
   long long EStepCnt;

public:

   // Clear the visit histogram
   void clear_histogram()
   {
      if( h.size()!=window.NBin ) h.resize(window.NBin);
      fill(h.begin(),h.end(),0);
   }

   // Clear the estimated entropy
   void clear_entropy()
   {
      S.resize(window.NBin);
      fill(S.begin(),S.end(),0);
      Sfixed.resize(window.NBin);
      fill(Sfixed.begin(),Sfixed.end(),0);
   }

   // Set values of member array. Window must already be set
   void set_values(const std::vector<double>& E, const std::vector<double>& y, std::vector<double>& seq)
   {
      const int nread = E.size();
      if( E.size()<2 )
      {
         std::cout << __FILE__ << ":" << __LINE__ << " Energy array is length " << nread << std::endl;
         int nbin = window.NBin;
         seq.resize(nbin);
         for(int i=0; i<nbin; i++) seq[i] = 0;
         return;
      }
      if( y.size()<nread ) std::cout << __FILE__ << ":" << __LINE__ << " array y is too small" << std::endl;
      int iread = 0;
      int nbin = window.NBin;
      seq.resize(nbin);
      for(int ibin=0; ibin<nbin; ibin++)
      {
         double Eset = window.unbin(ibin);
         while( iread<nread && E[iread]<Eset ) iread++;
         if(iread>=nread) iread = nread-1;
         if(iread<1) iread = 1;
         double E0 = E[iread];
         double y0 = y[iread];
         double E1 = E[iread-1];
         double y1 = y[iread-1];
         double slope = (y1-y0)/(E1-E0);
         seq[ibin] = y0 + slope*(Eset-E0);
      }
   }

   void set_fixed(const std::vector<double>& E, const std::vector<double>& y)
   {
      this->set_values(E,y,this->Sfixed);
   }

   // Deep copy of the walker
   void copy(const WL_Walker<Config,Observables>& orig)
   {
      this->BASE::copy(orig);
      wlgamma = orig.wlgamma;
      wl_now = orig.wl_now;
      wl_old = orig.wl_old;
      window = orig.window;
      S = orig.S;
      Sfixed = orig.Sfixed;
      Sittm = orig.Sittm;
      Vittm = orig.Vittm;
      h = orig.h;
      EStepSum = orig.EStepSum;
      EStepCnt = orig.EStepCnt;
   }

   WL_Walker()
   {
   }

   WL_Walker(const WL_Walker& orig)
   {
       this->copy(orig);
   }

   // Use this to find the current bin of the walker
   int bin() { return wl_now.ibin = window.bin(BASE::now.E); }

   // Estimate Entropy/lndos using linear interpolation
   double get_lndos(double E, bool LinearInterp=true)
   {
      int ibin = window.bin(E);
      double E0 = window.unbin(ibin);
      double S0 = S[ibin] + Sfixed[ibin];
      if( !LinearInterp ) return S0;
      double S1,E1;
      if( E<E0 )
      {
         // look left
         if( ibin==0 )
         {
            // Interpolate to edge half a bin away. Force WL portion to zero
            E1 = window.Elo;
            S1 = S[ibin]+Sfixed[ibin] - 0.5*( Sfixed[ibin+1]-Sfixed[ibin] );
         }
         else
         {
            E1 = window.unbin(ibin-1);
            S1 = S[ibin-1] + Sfixed[ibin-1];
         }
      }
      else
      {
         // look right
         if( ibin==(window.NBin-1) )
         {
            E1 = window.Ehi;
            S1 = S[ibin]+Sfixed[ibin] + 0.5*( Sfixed[ibin]-Sfixed[ibin-1] );
         }
         else
         {
            E1 = window.unbin(ibin+1);
            S1 = S[ibin+1] + Sfixed[ibin+1];
         }
      }
      double slope = (S1-S0)/(E1-E0);
      double SE = S0 + slope*(E-E0);
      return SE;
   }

   float flatness() const
   {
      // Find the prefactor that normalizes histogram such that
      // h_ibin = 1 for perfectly flat histogram (divide by mean h_ibin)
      long long htot = 0;
      int hbin = 0;
      for(int i=0; i<this->window.NBin; i++)
      {
	 if(h[i]>0)
	 {
	    htot += h[i];
	    hbin++;
	 }
      }
      double hnorm = static_cast<double>(hbin)/static_cast<double>(htot);
      // Calculate the flatness for the frozen entropy
      // Q = (1/nbin) \sum_ibin (h_ibin-1)^2
      double Q = 0;
      for(int i=0; i<window.NBin; i++)
      {
	 if( h[i]>0 )
	 {
	    double Qi=(hnorm*h[i]-1);
 	    Q+=Qi*Qi;
	 }
      }
      if( hbin<10 ) Q=1.e+6;   // Not flat if trapped
      return Q;
   }

/*
   bool move_walls(double qflat=0.1)
   {
      //if( move_walls_pileup() ) return true;
      // Calculate the flatness from high energy down
      int ilft = window.bin(WEmin);
      int irgt = window.bin(WEmax);
      const int mincts = 500;   // Minimum vists before move wall past a bin
      int jmax = irgt;
      long long htot = 0;
      int hbin = 0;
      int jbin=jmax;
      for(int kbin=jmax; kbin>0 && kbin>(jmax-5); kbin--)
         if( h[kbin]>1000000 ) jbin=kbin;
      bool flat = true;
      while( jbin>=0 && (flat || h[jbin]>1000000) )
      {
         if( h[jbin]>mincts )
         {
            htot += h[jbin];
            hbin++;
            double hnorm = static_cast<double>(hbin)/static_cast<double>(htot);
            double Q = 0;
            for(int i=jbin; i<=jmax; i++)
            {
               double Q1 = hnorm*h[i]-1;
               Q += Q1*Q1;
            }
            if(hbin>1) Q /= static_cast<double>(hbin);
            flat = (Q<=qflat);
            jbin--;
         }
         else
         {
            flat = false;
         }
      }
      jmax = jbin;
      // Cacluate the flatness from low energy up
      int jmin = ilft;
      htot = 0;
      hbin = 0;
      jbin = jmin;
      if( jbin<(window.NBin-1) && h[jbin+1]>1000000 ) jbin++;
      flat = true;
      while( jbin<window.NBin && (flat || h[jbin]>1000000) )
      {
         if( h[jbin]>mincts )
         {
            htot += h[jbin];
            hbin++;
            double hnorm = static_cast<double>(hbin)/static_cast<double>(htot);
            double Q = 0;
            for(int i=jmin; i<=jbin; i++)
            {
               double Q1 = hnorm*h[i]-1;
               Q += Q1*Q1;
            }
            if(hbin>1) Q /= static_cast<double>(hbin);
            flat = (Q<=qflat);
            jbin++;
         }
         else
         {
            flat = false;
         }
      }
      const int overlap = 5;
      jmin = jbin;
      flat = (jmin>jmax);
      jmax += overlap;
      if(jmax<irgt) irgt=jmax;
      jmin -= overlap;
      if(jmin>ilft) ilft=jmin;
      WEmin = window.unbin(ilft);
      WEmax = window.unbin(irgt);
      return flat;
   }
*/

public:

   void save_initial()
   {
      BASE::save_initial();
      wl_old = wl_now;
   }

   void restore_initial()
   {
      wl_now = wl_old;
      BASE::restore_initial();
   }

};

// Return integer index of wlgamma assuming wlgamma_i+1 = wlgamma_i/2
int igamma(double wlgamma)
{
   int p2 = static_cast<int>(-std::log(wlgamma)/std::log(2.)+0.01);
   return p2;
}

#endif  // WLWalker_HPP_
<|endoftext|>


<commit_before>#pragma once

#include <any.hpp>

namespace shadow
{
class object
{
public:
private:
    any value_;
};
}
<commit_msg>Add class type_tag with some member functions. 	modified:   include/api_types.hpp<commit_after>#pragma once

#include <string>
#include <cstddef>

#include <any.hpp>
#include <reflection_info.hpp>

namespace shadow
{

class type_tag
{
public:
    std::string name() const;
    std::size_t size() const;

private:
    const type_info* info_ptr_;
};

class object
{
public:
private:
    any value_;
};
}

namespace shadow
{

inline std::string
type_tag::name() const
{
    return std::string(info_ptr_->name);
}

inline std::size_t
type_tag::size() const
{
    return info_ptr_->size;
}
}
<|endoftext|>


<commit_before>#ifndef APOLLO_GC_HPP_INCLUDED
#define APOLLO_GC_HPP_INCLUDED APOLLO_GC_HPP_INCLUDED

#include <lua.hpp>
#include <type_traits>
#include <boost/assert.hpp>
#include <apollo/detail/meta_util.hpp>

namespace apollo {

template <typename T>
int gc_object(lua_State* L) BOOST_NOEXCEPT
{
    BOOST_ASSERT(lua_type(L, 1) == LUA_TUSERDATA);
    static_cast<T*>(lua_touserdata(L, 1))->~T();
    return 0;
}

template <typename T>
typename detail::remove_qualifiers<T>::type*
push_gc_object(lua_State* L, T&& o)
{
    using obj_t = typename detail::remove_qualifiers<T>::type;
    void* uf = lua_newuserdata(L, sizeof(obj_t));
    try {
        new(uf) obj_t(std::forward<T>(o));
    } catch (...) {
        lua_pop(L, 1);
        throw;
    }
#ifdef BOOST_MSVC
#   pragma warning(push)
#   pragma warning(disable:4127) // Conditional expression is constant.
#endif
    if (!std::is_trivially_destructible<obj_t>::value) {
#ifdef BOOST_MSVC
#   pragma warning(pop)
#endif
        lua_createtable(L, 0, 1);
        lua_pushcfunction(L, &gc_object<obj_t>);
        lua_setfield(L, -2, "__gc");
        lua_setmetatable(L, -2);
    }
    return static_cast<obj_t*>(uf);
}

} // namespace apollo

#endif // APOLLO_GC_HPP_INCLUDED
<commit_msg>gc: Include missing header.<commit_after>#ifndef APOLLO_GC_HPP_INCLUDED
#define APOLLO_GC_HPP_INCLUDED APOLLO_GC_HPP_INCLUDED

#include <lua.hpp>
#include <type_traits>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <apollo/detail/meta_util.hpp>

namespace apollo {

template <typename T>
int gc_object(lua_State* L) BOOST_NOEXCEPT
{
    BOOST_ASSERT(lua_type(L, 1) == LUA_TUSERDATA);
    static_cast<T*>(lua_touserdata(L, 1))->~T();
    return 0;
}

template <typename T>
typename detail::remove_qualifiers<T>::type*
push_gc_object(lua_State* L, T&& o)
{
    using obj_t = typename detail::remove_qualifiers<T>::type;
    void* uf = lua_newuserdata(L, sizeof(obj_t));
    try {
        new(uf) obj_t(std::forward<T>(o));
    } catch (...) {
        lua_pop(L, 1);
        throw;
    }
#ifdef BOOST_MSVC
#   pragma warning(push)
#   pragma warning(disable:4127) // Conditional expression is constant.
#endif
    if (!std::is_trivially_destructible<obj_t>::value) {
#ifdef BOOST_MSVC
#   pragma warning(pop)
#endif
        lua_createtable(L, 0, 1);
        lua_pushcfunction(L, &gc_object<obj_t>);
        lua_setfield(L, -2, "__gc");
        lua_setmetatable(L, -2);
    }
    return static_cast<obj_t*>(uf);
}

} // namespace apollo

#endif // APOLLO_GC_HPP_INCLUDED
<|endoftext|>


<commit_before>/*

  Copyright (c) 2014, Michael Tesch
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.

  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

  * Neither the name of Michael Tesch nor the names of other
    contributors may be used to endorse or promote products derived from
    this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  https://github.com/tesch1/qt-google-analytics-collector

*/
#include <unistd.h>
#include <map>
#include <QCoreApplication>
#include <QSettings>
#ifdef QT_GUI_LIB
#include <QApplication>
#include <QDesktopWidget>
#endif
#include <QUuid>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QDebug>

/*!
 * send google tracking data according to
 * https://developers.google.com/analytics/devguides/collection/protocol/v1/reference
 */

class GAnalytics : public QObject {
  Q_OBJECT
private:
  typedef std::map<QNetworkReply *, bool> reply_map;
public:
  GAnalytics(QCoreApplication * parent,
             QString trackingID,
             QString clientID = "",
             bool useGET = false)
    : QObject(parent), _qnam(this), _trackingID(trackingID), _clientID(clientID), _useGET(useGET), _isFail(false)
  {
    if (parent) {
      setAppName(parent->applicationName());
      setAppVersion(parent->applicationVersion());
#ifdef QT_GUI_LIB
      parent->dumpObjectTree();
#endif
    }
    if (!_clientID.size()) {
      // load client id from settings
      QSettings settings;
      if (!settings.contains("GAnalytics-cid")) {
        settings.setValue("GAnalytics-cid", QUuid::createUuid().toString());
      }
      _clientID = settings.value("GAnalytics-cid").toString();
    }
    connect(&_qnam, SIGNAL(finished(QNetworkReply *)), this, SLOT(postFinished(QNetworkReply *)));
    if (!_qnam.networkAccessible())
      qDebug() << "error: network inaccessible\n";
  }
  ~GAnalytics() {
    // wait up to half a second to let replies finish up
    // this generally happens after the event-loop is done, so no more network processing
#if 1 // not sure if this is necessary? does ~_qnam() delete all its replies? i guess it should
    for (reply_map::iterator it = _replies.begin(); it != _replies.end(); it++) {
      QNetworkReply * reply = it->first;
      if (reply->isRunning())
        qDebug() << "~GAnalytics, request still running: " << reply->url().toString() << ", aborting.";
      //reply->deleteLater();
    }
#endif
  }
  // manual ip and user agent
  void setClientID(QString clientID) { _clientID = clientID; }
  void setUserIPAddr(QString userIPAddr) { _userIPAddr = userIPAddr; }
  void setUserAgent(QString userAgent) { _userAgent = userAgent; }
  void setAppName(QString appName) { _appName = appName; }
  void setAppVersion(QString appVersion) { _appVersion = appVersion; }
  void setScreenResolution(QString screenResolution) { _screenResolution = screenResolution; }
  void setViewportSize(QString viewportSize) { _viewportSize = viewportSize; }
  void setUserLanguage(QString userLanguage) { _userLanguage = userLanguage; }
  QString getClientID() const { return _clientID; }
  //
  // hit types
  //
  // - https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide
  //

public Q_SLOTS:

  // pageview
  void sendPageview(QString docHostname, QString page, QString title) const {
    QUrl params = build_metric("pageview");
    params.addQueryItem("dh", docHostname);    // document hostname
    params.addQueryItem("dp", page);            // page
    params.addQueryItem("dt", title);           // title
    send_metric(params);
  }

  // event
  void sendEvent(QString eventCategory = "", QString eventAction = "",
                 QString eventLabel = "", int eventValue = 0) const {
    QUrl params = build_metric("event");
    if (_appName.size()) params.addQueryItem("an", _appName); // mobile event app tracking
    if (_appVersion.size()) params.addQueryItem("av", _appVersion); // mobile event app tracking
    if (eventCategory.size()) params.addQueryItem("ec", eventCategory);
    if (eventAction.size()) params.addQueryItem("ea", eventAction);
    if (eventLabel.size()) params.addQueryItem("el", eventLabel);
    if (eventValue) params.addQueryItem("ev", QString::number(eventValue));
    send_metric(params);
  }

  // transaction
  void sendTransaction(QString transactionID, QString transactionAffiliation = "" /*...todo...*/) const {
    QUrl params = build_metric("transaction");
    params.addQueryItem("ti", transactionID);
    if (transactionAffiliation.size()) params.addQueryItem("ta", transactionAffiliation);
    send_metric(params);
  }

  // item
  void sendItem(QString itemName) const {
    QUrl params = build_metric("item");
    params.addQueryItem("in", itemName);
    //if (appName.size()) params.addQueryItem("an", appName);
    send_metric(params);
  }

  // social
  void sendSocial(QString socialNetwork, QString socialAction, QString socialActionTarget) const {
    QUrl params = build_metric("social");
    params.addQueryItem("sn", socialNetwork);
    params.addQueryItem("sa", socialAction);
    params.addQueryItem("st", socialActionTarget);
    send_metric(params);
  }

  // exception
  void sendException(QString exceptionDescription, bool exceptionFatal = true) const {
    QUrl params = build_metric("exception");
    if (exceptionDescription.size()) params.addQueryItem("exd", exceptionDescription);
    if (!exceptionFatal) params.addQueryItem("exf", "0");
    send_metric(params);
  }

  // timing
  void sendTiming(/* todo */) const {
    QUrl params = build_metric("timing");
    //if (appName.size()) params.addQueryItem("an", appName);
    send_metric(params);
  }

  // appview
  void sendAppview(QString appName, QString appVersion = "", QString screenName = "") const {
    QUrl params = build_metric("appview");
    if (_appName.size()) params.addQueryItem("an", _appName);
    else if (appName.size()) params.addQueryItem("an", appName);
    if (_appVersion.size()) params.addQueryItem("av", _appVersion);
    else if (appVersion.size()) params.addQueryItem("av", appVersion);
    if (screenName.size()) params.addQueryItem("cd", screenName);
    send_metric(params);
  }

  // custom dimensions / metrics
  // todo

  // experiment id / variant
  // todo

  //void startSession();
  void endSession() const {
    QUrl params = build_metric("event");
    params.addQueryItem("sc", "end");
    send_metric(params);
  }

public:

  void generateUserAgentEtc() {
    QString locale = QLocale::system().name().toLower().replace("_", "-");
#if __APPLE__
    QString machine = "Macintosh; Intel Mac OS X 10.9; ";
#endif
#if __linux__
    QString machine = "X11; ";
#endif
    _userAgent = "Mozilla/5.0 (" + machine + "N; " + locale + ")";
    QNetworkRequest req;
    qDebug() << "User-Agent:" << req.rawHeader("User-Agent").constData() << "->" << _userAgent;

#ifdef QT_GUI_LIB
    QString geom = QString::number(QApplication::desktop()->screenGeometry().width())
      + "x" + QString::number(QApplication::desktop()->screenGeometry().height());
    _screenResolution = geom;
    //qDebug() << "screen resolution:" << _screenResolution;
    setUserLanguage(locale);
#endif
  }

private Q_SLOTS:
  void postFinished(QNetworkReply * reply) {
    //qDebug() << "reply:" << reply->readAll().toHex();
    if (QNetworkReply::NoError != reply->error()) {
      qDebug() << "postFinished error: " << reply->errorString() << "\n";
    }
    else {
      int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
      //qDebug() << "http response code: " << httpStatus;
      if (httpStatus < 200 || httpStatus > 299) {
        _isFail = true;
      }
    }
    _replies.erase(reply);
    reply->deleteLater();
  }
  void postError(QNetworkReply::NetworkError code) {
    qDebug() << "network error signal: " << code << "\n";
  }

private:
  GAnalytics(const GAnalytics &); // disable copy const constructor
  QUrl build_metric(QString hitType) const {
    QUrl params;
    // required in v1
    params.addQueryItem("v", "1" ); // version
    params.addQueryItem("tid", _trackingID);
    params.addQueryItem("cid", _clientID);
    params.addQueryItem("t", hitType);
    if (_userIPAddr.size())
      params.addQueryItem("uip", _userIPAddr);
    if (_screenResolution.size())
      params.addQueryItem("sr", _screenResolution);
    if (_viewportSize.size())
      params.addQueryItem("vp", _viewportSize);
    if (_userLanguage.size())
      params.addQueryItem("ul", _userLanguage);
    //if (_userAgent.size())
    //  params.addQueryItem("ua", _userAgent);
    return params;
  }
  void send_metric(QUrl & params) const {
    // when google has err'd us, then stop sending events!
    if (_isFail)
      return;
    QUrl collect_url("http://www.google-analytics.com/collect");
    QNetworkRequest request;
    if (_userAgent.size())
      request.setRawHeader("User-Agent", _userAgent.toUtf8());
    QNetworkReply * reply;
    if (_useGET) {
      // add cache-buster "z" to params
      //params.addQueryItem("z", QString::number(qrand()) );
      collect_url.setQueryItems(params.queryItems());
      request.setUrl(collect_url);
      reply = _qnam.get(request);
    }
    else {
      request.setUrl(collect_url);
      request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
      reply = _qnam.post(request, params.encodedQuery());
    }
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
            this, SLOT(postError(QNetworkReply::NetworkError)));
    _replies[reply] = true;
  }
  mutable QNetworkAccessManager _qnam;
  QString _trackingID;
  QString _clientID;
  bool _useGET; // true=GET, false=POST
  QString _userID;

  // various parameters:
  bool _anonymizeIP;
  bool _cacheBust;
  //
  QString _userIPAddr;
  QString _userAgent;
  QString _appName;
  QString _appVersion;
#if 0 // todo
  // traffic sources
  QString _documentReferrer;
  QString _campaignName;
  QString _campaignSource;
  QString _campaignMedium;
  QString _campaignKeyword;
  QString _campaignContent;
  QString _campaignID;
  QString _adwordsID;
  QString _displayAdsID;
#endif
  // system info
  QString _screenResolution;
  QString _viewportSize;
  QString _userLanguage;
  // etc...

  // internal
  bool _isFail;
  mutable reply_map _replies;
};

<commit_msg>better machine and os<commit_after>/*

  Copyright (c) 2014, Michael Tesch
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.

  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

  * Neither the name of Michael Tesch nor the names of other
    contributors may be used to endorse or promote products derived from
    this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  https://github.com/tesch1/qt-google-analytics-collector

*/
#include <unistd.h>
#include <map>
#include <QCoreApplication>
#include <QSettings>
#ifdef QT_GUI_LIB
#include <QApplication>
#include <QDesktopWidget>
#endif
#include <QUuid>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QDebug>

/*!
 * send google tracking data according to
 * https://developers.google.com/analytics/devguides/collection/protocol/v1/reference
 */

class GAnalytics : public QObject {
  Q_OBJECT
private:
  typedef std::map<QNetworkReply *, bool> reply_map;
public:
  GAnalytics(QCoreApplication * parent,
             QString trackingID,
             QString clientID = "",
             bool useGET = false)
    : QObject(parent), _qnam(this), _trackingID(trackingID), _clientID(clientID), _useGET(useGET), _isFail(false)
  {
    if (parent) {
      setAppName(parent->applicationName());
      setAppVersion(parent->applicationVersion());
#ifdef QT_GUI_LIB
      parent->dumpObjectTree();
#endif
    }
    if (!_clientID.size()) {
      // load client id from settings
      QSettings settings;
      if (!settings.contains("GAnalytics-cid")) {
        settings.setValue("GAnalytics-cid", QUuid::createUuid().toString());
      }
      _clientID = settings.value("GAnalytics-cid").toString();
    }
    connect(&_qnam, SIGNAL(finished(QNetworkReply *)), this, SLOT(postFinished(QNetworkReply *)));
    if (!_qnam.networkAccessible())
      qDebug() << "error: network inaccessible\n";
  }
  ~GAnalytics() {
    // wait up to half a second to let replies finish up
    // this generally happens after the event-loop is done, so no more network processing
#if 1 // not sure if this is necessary? does ~_qnam() delete all its replies? i guess it should
    for (reply_map::iterator it = _replies.begin(); it != _replies.end(); it++) {
      QNetworkReply * reply = it->first;
      if (reply->isRunning())
        qDebug() << "~GAnalytics, request still running: " << reply->url().toString() << ", aborting.";
      //reply->deleteLater();
    }
#endif
  }
  // manual ip and user agent
  void setClientID(QString clientID) { _clientID = clientID; }
  void setUserIPAddr(QString userIPAddr) { _userIPAddr = userIPAddr; }
  void setUserAgent(QString userAgent) { _userAgent = userAgent; }
  void setAppName(QString appName) { _appName = appName; }
  void setAppVersion(QString appVersion) { _appVersion = appVersion; }
  void setScreenResolution(QString screenResolution) { _screenResolution = screenResolution; }
  void setViewportSize(QString viewportSize) { _viewportSize = viewportSize; }
  void setUserLanguage(QString userLanguage) { _userLanguage = userLanguage; }
  QString getClientID() const { return _clientID; }
  //
  // hit types
  //
  // - https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide
  //

public Q_SLOTS:

  // pageview
  void sendPageview(QString docHostname, QString page, QString title) const {
    QUrl params = build_metric("pageview");
    params.addQueryItem("dh", docHostname);    // document hostname
    params.addQueryItem("dp", page);            // page
    params.addQueryItem("dt", title);           // title
    send_metric(params);
  }

  // event
  void sendEvent(QString eventCategory = "", QString eventAction = "",
                 QString eventLabel = "", int eventValue = 0) const {
    QUrl params = build_metric("event");
    if (_appName.size()) params.addQueryItem("an", _appName); // mobile event app tracking
    if (_appVersion.size()) params.addQueryItem("av", _appVersion); // mobile event app tracking
    if (eventCategory.size()) params.addQueryItem("ec", eventCategory);
    if (eventAction.size()) params.addQueryItem("ea", eventAction);
    if (eventLabel.size()) params.addQueryItem("el", eventLabel);
    if (eventValue) params.addQueryItem("ev", QString::number(eventValue));
    send_metric(params);
  }

  // transaction
  void sendTransaction(QString transactionID, QString transactionAffiliation = "" /*...todo...*/) const {
    QUrl params = build_metric("transaction");
    params.addQueryItem("ti", transactionID);
    if (transactionAffiliation.size()) params.addQueryItem("ta", transactionAffiliation);
    send_metric(params);
  }

  // item
  void sendItem(QString itemName) const {
    QUrl params = build_metric("item");
    params.addQueryItem("in", itemName);
    //if (appName.size()) params.addQueryItem("an", appName);
    send_metric(params);
  }

  // social
  void sendSocial(QString socialNetwork, QString socialAction, QString socialActionTarget) const {
    QUrl params = build_metric("social");
    params.addQueryItem("sn", socialNetwork);
    params.addQueryItem("sa", socialAction);
    params.addQueryItem("st", socialActionTarget);
    send_metric(params);
  }

  // exception
  void sendException(QString exceptionDescription, bool exceptionFatal = true) const {
    QUrl params = build_metric("exception");
    if (exceptionDescription.size()) params.addQueryItem("exd", exceptionDescription);
    if (!exceptionFatal) params.addQueryItem("exf", "0");
    send_metric(params);
  }

  // timing
  void sendTiming(/* todo */) const {
    QUrl params = build_metric("timing");
    //if (appName.size()) params.addQueryItem("an", appName);
    send_metric(params);
  }

  // appview
  void sendAppview(QString appName, QString appVersion = "", QString screenName = "") const {
    QUrl params = build_metric("appview");
    if (_appName.size()) params.addQueryItem("an", _appName);
    else if (appName.size()) params.addQueryItem("an", appName);
    if (_appVersion.size()) params.addQueryItem("av", _appVersion);
    else if (appVersion.size()) params.addQueryItem("av", appVersion);
    if (screenName.size()) params.addQueryItem("cd", screenName);
    send_metric(params);
  }

  // custom dimensions / metrics
  // todo

  // experiment id / variant
  // todo

  //void startSession();
  void endSession() const {
    QUrl params = build_metric("event");
    params.addQueryItem("sc", "end");
    send_metric(params);
  }

public:

  void generateUserAgentEtc() {
    QString locale = QLocale::system().name().toLower().replace("_", "-");
#ifdef __APPLE__
    QString machine = "Macintosh; Intel Mac OS X 10.9; ";
#endif
#ifdef __linux__
    QString machine = "X11; Linux ";
#ifdef __amd64__ || __x86_64__ || __ppc64__
    machine += "x86_64; ";
#else
    machine += "i686; ";
#endif
#endif
#ifdef Q_WS_WIN
    QString machine = "Windows; ";
#endif
    _userAgent = "Mozilla/5.0 (" + machine + "N; " + locale + ") GAnalytics/1.0 (Qt/" QT_VERSION_STR " )";
    QNetworkRequest req;
    qDebug() << "User-Agent:" << req.rawHeader("User-Agent").constData() << "->" << _userAgent;

#ifdef QT_GUI_LIB
    QString geom = QString::number(QApplication::desktop()->screenGeometry().width())
      + "x" + QString::number(QApplication::desktop()->screenGeometry().height());
    _screenResolution = geom;
    //qDebug() << "screen resolution:" << _screenResolution;
    setUserLanguage(locale);
#endif
  }

private Q_SLOTS:
  void postFinished(QNetworkReply * reply) {
    //qDebug() << "reply:" << reply->readAll().toHex();
    if (QNetworkReply::NoError != reply->error()) {
      qDebug() << "postFinished error: " << reply->errorString() << "\n";
    }
    else {
      int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
      //qDebug() << "http response code: " << httpStatus;
      if (httpStatus < 200 || httpStatus > 299) {
        _isFail = true;
      }
    }
    _replies.erase(reply);
    reply->deleteLater();
  }
  void postError(QNetworkReply::NetworkError code) {
    qDebug() << "network error signal: " << code << "\n";
  }

private:
  GAnalytics(const GAnalytics &); // disable copy const constructor
  QUrl build_metric(QString hitType) const {
    QUrl params;
    // required in v1
    params.addQueryItem("v", "1" ); // version
    params.addQueryItem("tid", _trackingID);
    params.addQueryItem("cid", _clientID);
    params.addQueryItem("t", hitType);
    if (_userIPAddr.size())
      params.addQueryItem("uip", _userIPAddr);
    if (_screenResolution.size())
      params.addQueryItem("sr", _screenResolution);
    if (_viewportSize.size())
      params.addQueryItem("vp", _viewportSize);
    if (_userLanguage.size())
      params.addQueryItem("ul", _userLanguage);
    //if (_userAgent.size())
    //  params.addQueryItem("ua", _userAgent);
    return params;
  }
  void send_metric(QUrl & params) const {
    // when google has err'd us, then stop sending events!
    if (_isFail)
      return;
    QUrl collect_url("http://www.google-analytics.com/collect");
    QNetworkRequest request;
    if (_userAgent.size())
      request.setRawHeader("User-Agent", _userAgent.toUtf8());
    QNetworkReply * reply;
    if (_useGET) {
      // add cache-buster "z" to params
      //params.addQueryItem("z", QString::number(qrand()) );
      collect_url.setQueryItems(params.queryItems());
      request.setUrl(collect_url);
      reply = _qnam.get(request);
    }
    else {
      request.setUrl(collect_url);
      request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
      reply = _qnam.post(request, params.encodedQuery());
    }
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
            this, SLOT(postError(QNetworkReply::NetworkError)));
    _replies[reply] = true;
  }
  mutable QNetworkAccessManager _qnam;
  QString _trackingID;
  QString _clientID;
  bool _useGET; // true=GET, false=POST
  QString _userID;

  // various parameters:
  bool _anonymizeIP;
  bool _cacheBust;
  //
  QString _userIPAddr;
  QString _userAgent;
  QString _appName;
  QString _appVersion;
#if 0 // todo
  // traffic sources
  QString _documentReferrer;
  QString _campaignName;
  QString _campaignSource;
  QString _campaignMedium;
  QString _campaignKeyword;
  QString _campaignContent;
  QString _campaignID;
  QString _adwordsID;
  QString _displayAdsID;
#endif
  // system info
  QString _screenResolution;
  QString _viewportSize;
  QString _userLanguage;
  // etc...

  // internal
  bool _isFail;
  mutable reply_map _replies;
};

<|endoftext|>


<commit_before>/**
 * @file		container.hpp
 * @brief		component container class
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 8. 6
 * @details	Component container
 */

#ifndef _COSSB_CONTAINER_HPP_
#define _COSSB_CONTAINER_HPP_

#include <string>
#include <list>
#include <map>
#include "interface/icomponent.hpp"
#include "arch/singleton.hpp"
#include "driver.hpp"

using namespace std;

namespace cossb {
namespace container {

typedef std::map<string, driver::component_driver*> comp_container;

class component_container : private arch::singleton<component_container> {

public:
	/**
	 * @brief	construct
	 */
	component_container() = default;

	/**
	 * @brief	destructor
	 */
	virtual ~component_container() { clear(); }

private:
	/**
	 * @brief	return size of the component container
	 */
	int size() { return _container.size(); }

	/**
	 * @brief	empty check
	 * @return	true, if the container is empty
	 */
	bool empty() { return _container.size()==0; }

	/**
	 * @brief	find component driver if it exists, and getting its driver
	 */
	driver::component_driver* get_driver(const char* component_name) {
		comp_container::iterator itr = _container.find(component_name);
		if(itr!=_container.end())
			return itr->second;
		else
			return nullptr;
	}

	/**
	 * @brief	add new component
	 * @return	true, if success
	 */
	bool add(const char* component_name, driver::component_driver* driver) {
		if(_container.find(component_name)==_container.end() && driver->valid()) {
			_container.insert(comp_container::value_type(component_name, driver));
			return true;
		}
		else {
			delete driver;
			return false;
		}
	}

	/**
	 * @brief	remove specific component
	 */
	bool remove(const char* component_name) {
		comp_container::iterator itr = _container.find(component_name);
		if(itr!=_container.end()) {
			if(itr->second) {
				delete itr->second;
				itr->second = nullptr;
			}
			_container.erase(itr);
			return true;
		}
		return false;
	}

	/**
	 * @brief	check for component existence
	 */
	bool exist(const char* component_name) {
		if(_container.find(component_name)!=_container.end())
			return true;
		else
			return false;
	}

	/**
	 * @brief	clear all components
	 */
	void clear() {
		for(auto itr:_container) {
			if(itr.second) {
				delete itr.second;
				itr.second = nullptr;
			}
		}
		_container.clear();
	}

private:
	comp_container _container;

	friend class manager::component_manager;
};

#define cossb_component_container	cossb::container::component_container::instance()

} /* namespace container */
} /* namesapce cossb */

#endif /* _COSSB_CONTAINER_HPP_ */
<commit_msg>remove the list header<commit_after>/**
 * @file		container.hpp
 * @brief		component container class
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 8. 6
 * @details	Component container
 */

#ifndef _COSSB_CONTAINER_HPP_
#define _COSSB_CONTAINER_HPP_

#include <string>
#include <map>
#include "interface/icomponent.hpp"
#include "arch/singleton.hpp"
#include "driver.hpp"

using namespace std;

namespace cossb {
namespace container {

typedef std::map<string, driver::component_driver*> comp_container;

class component_container : private arch::singleton<component_container> {

public:
	/**
	 * @brief	construct
	 */
	component_container() = default;

	/**
	 * @brief	destructor
	 */
	virtual ~component_container() { clear(); }

private:
	/**
	 * @brief	return size of the component container
	 */
	int size() { return _container.size(); }

	/**
	 * @brief	empty check
	 * @return	true, if the container is empty
	 */
	bool empty() { return _container.size()==0; }

	/**
	 * @brief	find component driver if it exists, and getting its driver
	 */
	driver::component_driver* get_driver(const char* component_name) {
		comp_container::iterator itr = _container.find(component_name);
		if(itr!=_container.end())
			return itr->second;
		else
			return nullptr;
	}

	/**
	 * @brief	add new component
	 * @return	true, if success
	 */
	bool add(const char* component_name, driver::component_driver* driver) {
		if(_container.find(component_name)==_container.end() && driver->valid()) {
			_container.insert(comp_container::value_type(component_name, driver));
			return true;
		}
		else {
			delete driver;
			return false;
		}
	}

	/**
	 * @brief	remove specific component
	 */
	bool remove(const char* component_name) {
		comp_container::iterator itr = _container.find(component_name);
		if(itr!=_container.end()) {
			if(itr->second) {
				delete itr->second;
				itr->second = nullptr;
			}
			_container.erase(itr);
			return true;
		}
		return false;
	}

	/**
	 * @brief	check for component existence
	 */
	bool exist(const char* component_name) {
		if(_container.find(component_name)!=_container.end())
			return true;
		else
			return false;
	}

	/**
	 * @brief	clear all components
	 */
	void clear() {
		for(auto itr:_container) {
			if(itr.second) {
				delete itr.second;
				itr.second = nullptr;
			}
		}
		_container.clear();
	}

private:
	comp_container _container;

	friend class manager::component_manager;
};

#define cossb_component_container	cossb::container::component_container::instance()

} /* namespace container */
} /* namesapce cossb */

#endif /* _COSSB_CONTAINER_HPP_ */
<|endoftext|>


<commit_before>/*
 *
 * Copyright 2015, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <malloc.h>

#include <vector>

#include <node.h>
#include <nan.h>
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "channel.h"
#include "credentials.h"

namespace grpc {
namespace node {

using v8::Arguments;
using v8::Array;
using v8::Exception;
using v8::Function;
using v8::FunctionTemplate;
using v8::Handle;
using v8::HandleScope;
using v8::Integer;
using v8::Local;
using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Value;

Persistent<Function> Channel::constructor;
Persistent<FunctionTemplate> Channel::fun_tpl;

Channel::Channel(grpc_channel *channel, NanUtf8String *host)
    : wrapped_channel(channel), host(host) {}

Channel::~Channel() {
  if (wrapped_channel != NULL) {
    grpc_channel_destroy(wrapped_channel);
  }
  delete host;
}

void Channel::Init(Handle<Object> exports) {
  NanScope();
  Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
  tpl->SetClassName(NanNew("Channel"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
  NanSetPrototypeTemplate(tpl, "close",
                          FunctionTemplate::New(Close)->GetFunction());
  NanAssignPersistent(fun_tpl, tpl);
  NanAssignPersistent(constructor, tpl->GetFunction());
  exports->Set(NanNew("Channel"), constructor);
}

bool Channel::HasInstance(Handle<Value> val) {
  NanScope();
  return NanHasInstance(fun_tpl, val);
}

grpc_channel *Channel::GetWrappedChannel() { return this->wrapped_channel; }

char *Channel::GetHost() { return **this->host; }

NAN_METHOD(Channel::New) {
  NanScope();

  if (args.IsConstructCall()) {
    if (!args[0]->IsString()) {
      return NanThrowTypeError("Channel expects a string and an object");
    }
    grpc_channel *wrapped_channel;
    // Owned by the Channel object
    NanUtf8String *host = new NanUtf8String(args[0]);
    if (args[1]->IsUndefined()) {
      wrapped_channel = grpc_channel_create(**host, NULL);
    } else if (args[1]->IsObject()) {
      grpc_credentials *creds = NULL;
      Handle<Object> args_hash(args[1]->ToObject()->Clone());
      if (args_hash->HasOwnProperty(NanNew("credentials"))) {
        Handle<Value> creds_value = args_hash->Get(NanNew("credentials"));
        if (!Credentials::HasInstance(creds_value)) {
          return NanThrowTypeError(
              "credentials arg must be a Credentials object");
        }
        Credentials *creds_object =
            ObjectWrap::Unwrap<Credentials>(creds_value->ToObject());
        creds = creds_object->GetWrappedCredentials();
        args_hash->Delete(NanNew("credentials"));
      }
      Handle<Array> keys(args_hash->GetOwnPropertyNames());
      grpc_channel_args channel_args;
      channel_args.num_args = keys->Length();
      channel_args.args = reinterpret_cast<grpc_arg *>(
          calloc(channel_args.num_args, sizeof(grpc_arg)));
      /* These are used to keep all strings until then end of the block, then
         destroy them */
      std::vector<NanUtf8String *> key_strings(keys->Length());
      std::vector<NanUtf8String *> value_strings(keys->Length());
      for (unsigned int i = 0; i < channel_args.num_args; i++) {
        Handle<String> current_key(keys->Get(i)->ToString());
        Handle<Value> current_value(args_hash->Get(current_key));
        key_strings[i] = new NanUtf8String(current_key);
        channel_args.args[i].key = **key_strings[i];
        if (current_value->IsInt32()) {
          channel_args.args[i].type = GRPC_ARG_INTEGER;
          channel_args.args[i].value.integer = current_value->Int32Value();
        } else if (current_value->IsString()) {
          channel_args.args[i].type = GRPC_ARG_STRING;
          value_strings[i] = new NanUtf8String(current_value);
          channel_args.args[i].value.string = **value_strings[i];
        } else {
          free(channel_args.args);
          return NanThrowTypeError("Arg values must be strings");
        }
      }
      if (creds == NULL) {
        wrapped_channel = grpc_channel_create(**host, &channel_args);
      } else {
        wrapped_channel =
            grpc_secure_channel_create(creds, **host, &channel_args);
      }
      free(channel_args.args);
    } else {
      return NanThrowTypeError("Channel expects a string and an object");
    }
    Channel *channel = new Channel(wrapped_channel, host);
    channel->Wrap(args.This());
    NanReturnValue(args.This());
  } else {
    const int argc = 2;
    Local<Value> argv[argc] = {args[0], args[1]};
    NanReturnValue(constructor->NewInstance(argc, argv));
  }
}

NAN_METHOD(Channel::Close) {
  NanScope();
  if (!HasInstance(args.This())) {
    return NanThrowTypeError("close can only be called on Channel objects");
  }
  Channel *channel = ObjectWrap::Unwrap<Channel>(args.This());
  if (channel->wrapped_channel != NULL) {
    grpc_channel_destroy(channel->wrapped_channel);
    channel->wrapped_channel = NULL;
  }
  NanReturnUndefined();
}

}  // namespace node
}  // namespace grpc
<commit_msg>Fixed TLS host resolution problems<commit_after>/*
 *
 * Copyright 2015, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <malloc.h>

#include <vector>

#include <node.h>
#include <nan.h>
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "channel.h"
#include "credentials.h"

namespace grpc {
namespace node {

using v8::Arguments;
using v8::Array;
using v8::Exception;
using v8::Function;
using v8::FunctionTemplate;
using v8::Handle;
using v8::HandleScope;
using v8::Integer;
using v8::Local;
using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Value;

Persistent<Function> Channel::constructor;
Persistent<FunctionTemplate> Channel::fun_tpl;

Channel::Channel(grpc_channel *channel, NanUtf8String *host)
    : wrapped_channel(channel), host(host) {}

Channel::~Channel() {
  if (wrapped_channel != NULL) {
    grpc_channel_destroy(wrapped_channel);
  }
  delete host;
}

void Channel::Init(Handle<Object> exports) {
  NanScope();
  Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
  tpl->SetClassName(NanNew("Channel"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
  NanSetPrototypeTemplate(tpl, "close",
                          FunctionTemplate::New(Close)->GetFunction());
  NanAssignPersistent(fun_tpl, tpl);
  NanAssignPersistent(constructor, tpl->GetFunction());
  exports->Set(NanNew("Channel"), constructor);
}

bool Channel::HasInstance(Handle<Value> val) {
  NanScope();
  return NanHasInstance(fun_tpl, val);
}

grpc_channel *Channel::GetWrappedChannel() { return this->wrapped_channel; }

char *Channel::GetHost() { return **this->host; }

NAN_METHOD(Channel::New) {
  NanScope();

  if (args.IsConstructCall()) {
    if (!args[0]->IsString()) {
      return NanThrowTypeError("Channel expects a string and an object");
    }
    grpc_channel *wrapped_channel;
    // Owned by the Channel object
    NanUtf8String *host = new NanUtf8String(args[0]);
    NanUtf8String *host_override = NULL;
    if (args[1]->IsUndefined()) {
      wrapped_channel = grpc_channel_create(**host, NULL);
    } else if (args[1]->IsObject()) {
      grpc_credentials *creds = NULL;
      Handle<Object> args_hash(args[1]->ToObject()->Clone());
      if (args_hash->HasOwnProperty(NanNew(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG))) {
        host_override = new NanUtf8String(args_hash->Get(NanNew(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)));
      }
      if (args_hash->HasOwnProperty(NanNew("credentials"))) {
        Handle<Value> creds_value = args_hash->Get(NanNew("credentials"));
        if (!Credentials::HasInstance(creds_value)) {
          return NanThrowTypeError(
              "credentials arg must be a Credentials object");
        }
        Credentials *creds_object =
            ObjectWrap::Unwrap<Credentials>(creds_value->ToObject());
        creds = creds_object->GetWrappedCredentials();
        args_hash->Delete(NanNew("credentials"));
      }
      Handle<Array> keys(args_hash->GetOwnPropertyNames());
      grpc_channel_args channel_args;
      channel_args.num_args = keys->Length();
      channel_args.args = reinterpret_cast<grpc_arg *>(
          calloc(channel_args.num_args, sizeof(grpc_arg)));
      /* These are used to keep all strings until then end of the block, then
         destroy them */
      std::vector<NanUtf8String *> key_strings(keys->Length());
      std::vector<NanUtf8String *> value_strings(keys->Length());
      for (unsigned int i = 0; i < channel_args.num_args; i++) {
        Handle<String> current_key(keys->Get(i)->ToString());
        Handle<Value> current_value(args_hash->Get(current_key));
        key_strings[i] = new NanUtf8String(current_key);
        channel_args.args[i].key = **key_strings[i];
        if (current_value->IsInt32()) {
          channel_args.args[i].type = GRPC_ARG_INTEGER;
          channel_args.args[i].value.integer = current_value->Int32Value();
        } else if (current_value->IsString()) {
          channel_args.args[i].type = GRPC_ARG_STRING;
          value_strings[i] = new NanUtf8String(current_value);
          channel_args.args[i].value.string = **value_strings[i];
        } else {
          free(channel_args.args);
          return NanThrowTypeError("Arg values must be strings");
        }
      }
      if (creds == NULL) {
        wrapped_channel = grpc_channel_create(**host, &channel_args);
      } else {
        wrapped_channel =
            grpc_secure_channel_create(creds, **host, &channel_args);
      }
      free(channel_args.args);
    } else {
      return NanThrowTypeError("Channel expects a string and an object");
    }
    Channel *channel;
    if (host_override == NULL) {
      channel = new Channel(wrapped_channel, host);
    } else {
      channel = new Channel(wrapped_channel, host_override);
    }
    channel->Wrap(args.This());
    NanReturnValue(args.This());
  } else {
    const int argc = 2;
    Local<Value> argv[argc] = {args[0], args[1]};
    NanReturnValue(constructor->NewInstance(argc, argv));
  }
}

NAN_METHOD(Channel::Close) {
  NanScope();
  if (!HasInstance(args.This())) {
    return NanThrowTypeError("close can only be called on Channel objects");
  }
  Channel *channel = ObjectWrap::Unwrap<Channel>(args.This());
  if (channel->wrapped_channel != NULL) {
    grpc_channel_destroy(channel->wrapped_channel);
    channel->wrapped_channel = NULL;
  }
  NanReturnUndefined();
}

}  // namespace node
}  // namespace grpc
<|endoftext|>


<commit_before>
/*
    Copyright 2008 Brain Research Institute, Melbourne, Australia

    Written by J-Donald Tournier, 27/06/08.

    This file is part of MRtrix.

    MRtrix 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.

    MRtrix 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 MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "command.h"
#include "progressbar.h"
#include "datatype.h"

#include "image.h"
#include "algo/loop.h"
#include "algo/threaded_loop.h"

using namespace MR;
using namespace App;

void usage ()
{
  AUTHOR = "J-Donald Tournier (jdtournier@gmail.com) and David Raffelt (david.raffelt@florey.edu.au) and Robert E. Smith (robert.smith@florey.edu.au)";

  DESCRIPTION
  + "compare two images for differences, optionally with a specified tolerance.";

  ARGUMENTS
  + Argument ("data1", "an image.").type_image_in()
  + Argument ("data2", "another image.").type_image_in()
  + Argument ("tolerance", "the tolerance value (default = 0.0).").type_float(0.0).optional();

  OPTIONS
  + Option ("abs", "test for absolute difference (the default)")
  + Option ("frac", "test for fractional absolute difference")
  + Option ("voxel", "test for fractional absolute difference relative to the maximum value in the voxel");
}

void run ()
{
  auto in1 = Image<cdouble>::open (argument[0]);
  auto in2 = Image<cdouble>::open (argument[1]);
  check_dimensions (in1, in2);
  for (size_t i = 0; i < in1.ndim(); ++i) {
    if (std::isfinite (in1.size(i)))
      if (in1.size(i) != in2.size(i))
        throw Exception ("images \"" + in1.name() + "\" and \"" + in2.name() + "\" do not have matching voxel spacings " +
                                       str(in1.size(i)) + " vs " + str(in2.size(i)));
  }
  for (size_t i  = 0; i < 3; ++i) {
    for (size_t j  = 0; j < 4; ++j) {
      if (std::abs (in1.transform().matrix()(i,j) - in2.transform().matrix()(i,j)) > 0.001)
        throw Exception ("images \"" + in1.name() + "\" and \"" + in2.name() + "\" do not have matching header transforms "
                           + "\n" + str(in1.transform().matrix()) + "vs \n " + str(in2.transform().matrix()) + ")");
    }
  }

  const double tol = argument.size() == 3 ? argument[2] : 0.0;

  const bool absolute = get_options ("abs").size();
  const bool fractional = get_options ("frac").size();
  const bool per_voxel = get_options ("voxel").size();

  double largest_diff = 0.0;
  size_t count = 0;

  if (absolute + fractional + per_voxel > 1)
    throw Exception ("options \"-abs\", \"-frac\", and \"-voxel\" are mutually exclusive");

  // per-voxel:
  if (per_voxel) {

    if (in1.ndim() != 4)
      throw Exception ("Option -voxel only works for 4D images");

    struct RunKernel {
      RunKernel (double& largest_diff, size_t& count, double tol) :
        largest_diff (largest_diff), count (count), tol (tol), max_diff (0.0), n (0) { }

      void operator() (decltype(in1)& a, decltype(in2)& b) {
        double maxa = 0.0, maxb = 0.0;
        for (auto l = Loop(3) (a, b); l; ++l) {
          maxa = std::max (maxa, std::abs (cdouble(a.value())));
          maxb = std::max (maxb, std::abs (cdouble(b.value())));
        }
        const double threshold = tol * 0.5 * (maxa + maxb);
        for (auto l = Loop(3) (a, b); l; ++l) {
          auto diff = std::abs (cdouble (a.value()) - cdouble (b.value()));
          if (diff > threshold) {
            ++n;
            max_diff = std::max (max_diff, diff);
          }
        }
      }

      double& largest_diff;
      size_t& count;
      const double tol;
      double max_diff;
      size_t n;
    };

    ThreadedLoop (in1, 0, 3).run (RunKernel (largest_diff, count, tol), in1, in2);
    if (count)
      throw Exception ("images \"" + in1.name() + "\" and \"" + in2.name() + "\" do not match within " + str(tol) + " of maximal voxel value"
          + " (" + str(count) + " voxels over threshold, maximum per-voxel relative difference = " + str(largest_diff) + ")");
  }
  else { // frac or abs:

    struct RunKernel { NOMEMALIGN
      RunKernel (double& largest_diff, size_t& count, double tol, bool fractional) :
        largest_diff (largest_diff), count (count), tol (tol), fractional (fractional), max_diff (0.0), n (0) { }

      ~RunKernel() { largest_diff = std::max (largest_diff, max_diff); count += n; }

      void operator() (const decltype(in1)& a, const decltype(in2)& b) {
        auto diff = std::abs (a.value() - b.value());
        if (fractional)
          diff /= 0.5 * std::abs (a.value() + b.value());
        if (diff > tol) {
          ++n;
          max_diff = std::max (max_diff, diff);
        }
      }

      double& largest_diff;
      size_t& count;
      const double tol;
      const bool fractional;
      double max_diff;
      size_t n;
    };

    ThreadedLoop (in1).run (RunKernel (largest_diff, count, tol, fractional), in1, in2);
    if (count)
      throw Exception ("images \"" + in1.name() + "\" and \"" + in2.name() + "\" do not match within "
          + ( fractional ? "relative" : "absolute" ) + " precision of " + str(tol)
          + " (" + str(count) + " voxels over threshold, maximum absolute difference = " + str(largest_diff) + ")");
  }

  CONSOLE ("data checked OK");
}

<commit_msg>testing_diff_data: fix memalign<commit_after>
/*
    Copyright 2008 Brain Research Institute, Melbourne, Australia

    Written by J-Donald Tournier, 27/06/08.

    This file is part of MRtrix.

    MRtrix 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.

    MRtrix 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 MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "command.h"
#include "progressbar.h"
#include "datatype.h"

#include "image.h"
#include "algo/loop.h"
#include "algo/threaded_loop.h"

using namespace MR;
using namespace App;

void usage ()
{
  AUTHOR = "J-Donald Tournier (jdtournier@gmail.com) and David Raffelt (david.raffelt@florey.edu.au) and Robert E. Smith (robert.smith@florey.edu.au)";

  DESCRIPTION
  + "compare two images for differences, optionally with a specified tolerance.";

  ARGUMENTS
  + Argument ("data1", "an image.").type_image_in()
  + Argument ("data2", "another image.").type_image_in()
  + Argument ("tolerance", "the tolerance value (default = 0.0).").type_float(0.0).optional();

  OPTIONS
  + Option ("abs", "test for absolute difference (the default)")
  + Option ("frac", "test for fractional absolute difference")
  + Option ("voxel", "test for fractional absolute difference relative to the maximum value in the voxel");
}

void run ()
{
  auto in1 = Image<cdouble>::open (argument[0]);
  auto in2 = Image<cdouble>::open (argument[1]);
  check_dimensions (in1, in2);
  for (size_t i = 0; i < in1.ndim(); ++i) {
    if (std::isfinite (in1.size(i)))
      if (in1.size(i) != in2.size(i))
        throw Exception ("images \"" + in1.name() + "\" and \"" + in2.name() + "\" do not have matching voxel spacings " +
                                       str(in1.size(i)) + " vs " + str(in2.size(i)));
  }
  for (size_t i  = 0; i < 3; ++i) {
    for (size_t j  = 0; j < 4; ++j) {
      if (std::abs (in1.transform().matrix()(i,j) - in2.transform().matrix()(i,j)) > 0.001)
        throw Exception ("images \"" + in1.name() + "\" and \"" + in2.name() + "\" do not have matching header transforms "
                           + "\n" + str(in1.transform().matrix()) + "vs \n " + str(in2.transform().matrix()) + ")");
    }
  }

  const double tol = argument.size() == 3 ? argument[2] : 0.0;

  const bool absolute = get_options ("abs").size();
  const bool fractional = get_options ("frac").size();
  const bool per_voxel = get_options ("voxel").size();

  double largest_diff = 0.0;
  size_t count = 0;

  if (absolute + fractional + per_voxel > 1)
    throw Exception ("options \"-abs\", \"-frac\", and \"-voxel\" are mutually exclusive");

  // per-voxel:
  if (per_voxel) {

    if (in1.ndim() != 4)
      throw Exception ("Option -voxel only works for 4D images");

    struct RunKernel { NOMEMALIGN
      RunKernel (double& largest_diff, size_t& count, double tol) :
        largest_diff (largest_diff), count (count), tol (tol), max_diff (0.0), n (0) { }

      void operator() (decltype(in1)& a, decltype(in2)& b) {
        double maxa = 0.0, maxb = 0.0;
        for (auto l = Loop(3) (a, b); l; ++l) {
          maxa = std::max (maxa, std::abs (cdouble(a.value())));
          maxb = std::max (maxb, std::abs (cdouble(b.value())));
        }
        const double threshold = tol * 0.5 * (maxa + maxb);
        for (auto l = Loop(3) (a, b); l; ++l) {
          auto diff = std::abs (cdouble (a.value()) - cdouble (b.value()));
          if (diff > threshold) {
            ++n;
            max_diff = std::max (max_diff, diff);
          }
        }
      }

      double& largest_diff;
      size_t& count;
      const double tol;
      double max_diff;
      size_t n;
    };

    ThreadedLoop (in1, 0, 3).run (RunKernel (largest_diff, count, tol), in1, in2);
    if (count)
      throw Exception ("images \"" + in1.name() + "\" and \"" + in2.name() + "\" do not match within " + str(tol) + " of maximal voxel value"
          + " (" + str(count) + " voxels over threshold, maximum per-voxel relative difference = " + str(largest_diff) + ")");
  }
  else { // frac or abs:

    struct RunKernel { NOMEMALIGN
      RunKernel (double& largest_diff, size_t& count, double tol, bool fractional) :
        largest_diff (largest_diff), count (count), tol (tol), fractional (fractional), max_diff (0.0), n (0) { }

      ~RunKernel() { largest_diff = std::max (largest_diff, max_diff); count += n; }

      void operator() (const decltype(in1)& a, const decltype(in2)& b) {
        auto diff = std::abs (a.value() - b.value());
        if (fractional)
          diff /= 0.5 * std::abs (a.value() + b.value());
        if (diff > tol) {
          ++n;
          max_diff = std::max (max_diff, diff);
        }
      }

      double& largest_diff;
      size_t& count;
      const double tol;
      const bool fractional;
      double max_diff;
      size_t n;
    };

    ThreadedLoop (in1).run (RunKernel (largest_diff, count, tol, fractional), in1, in2);
    if (count)
      throw Exception ("images \"" + in1.name() + "\" and \"" + in2.name() + "\" do not match within "
          + ( fractional ? "relative" : "absolute" ) + " precision of " + str(tol)
          + " (" + str(count) + " voxels over threshold, maximum absolute difference = " + str(largest_diff) + ")");
  }

  CONSOLE ("data checked OK");
}

<|endoftext|>


<commit_before>// Generator builder
// This is the device that builds generators.
#include <boost/filesystem.hpp>
#include <boost/range/iterator_range.hpp>
#include <gtk/gtk.h>
#include <ifstream>
#include <libxml/parser.h>
#include <string>
#include <vector>

namespace fs = boost::filesystem;
using namespace std;

// Add element to document.
// elementLabel is the label for the element, and
// listFile is the name of the list file.
void addElement(string elementToAdd, string elementLabel, string listFile)
{
	xmlNodePtr elementLabelNodePtr;
	xmlNodePtr elementNodePtr;
	elementLabelNodePtr = xmlNewNode(NULL, BAD_CAST "root");
	xmlNodeSetContent(n, BAD_CAST elementToAdd);
	xmlDocSetRootElement(doc, elementLabelNodePtr);
}

// Remove element from document.
void removeElement(xmlNodePtr elementToRemove)
{
	xmlUnlinkNode(elementToRemove);
	xmlFreeNode(elementToRemove);
}

// GTK
void activate(GtkApplication *app, gpointer user_data)
{
	GtkWidget *window;
	GtkWidget *button;
	GtkWidget *textTagTable;

	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title(GTK_WINDOW(window), "Generator Editor");
	gtk_window_set_default_size(GTK_WINDOW(window), 200, 200);

	g_signal_connect(window, "delete-event", G_CALLBACK(delete_event), NULL);
	g_signal_connect(window, "destroy", G_CALLBACK(destroy), NULL);

}

int main(void)
{
	gtk_init();

	// Build a list of directories.
	string dirPath = "/ListFiles"; // Path to directory
	fs::path p(dirPath);
	vector<string> fileNames = "";

	if(fs::is_directory(p))
	int i = 0;
	for (auto & p : fs::make_iterator_range(fs::directory_iterator(p), {}))
	{
		fileNames[i] = fs::entry;
		i++;
	}

	// Display the list of files.
		// CList
		// Vertical Scrollbar
	fileListBuffer = gtk_text_buffer_new (GTKTextTagTable *table);
	fileListWindow = gtk_text_view_new_with_buffer (fileListBuffer);

	fileListScrollbar = gtk_scrollbar_new(vertical);
	i
	xmlChar *xmlbuffer;
	int buffersize;

	// Create the XML document to store the generator.
	xmlDocPtr doc;
	doc = xmlNewDoc(BAD_CAST "1.0");

	// Generate the menu for selecting a list file.

	return(0);
}

<commit_msg>Delete genbuilder.cpp<commit_after><|endoftext|>