<commit_before>/*
	The MIT License (MIT)
	Copyright (c) 2016 Gagan Kumar(scopeInfinity)
	Complete License at https://raw.githubusercontent.com/scopeInfinity/NaturalSort/master/LICENSE.md
*/

/**********************************************************************
Calling Methods :

	//For Natural Sorting
	void SI::natural::sort(Container<String>);
	void SI::natural::sort(IteratorBegin<String>,IteratorEnd<String>);
	void SI::natural::sort<String,CArraySize>(CArray<String>);

	//For Natural Comparision
	bool SI::natural::compare<String>(String lhs,String rhs);
	bool SI::natural::compare<String>(char *const lhs,char *const rhs);

	Here we can have
		std::vector<std::string> 	as Container<String>
		String 						as std::string
		CArray<String>				as std::string[CArraySize]

***********************************************************************/
#ifndef SI_sort_HPP
#define SI_sort_HPP
#include <cctype>
#include <algorithm>
#include <vector>

namespace SI
{
namespace natural
{
	namespace detail
	{
		/********** Compare Two Character CaseInsensitive ********/
		template<typename ElementType>
		bool natural_less(const ElementType &lhs,const ElementType &rhs)
		{
			if(tolower(lhs)<tolower(rhs))
				return true;
			return false;
		}

		template<typename ElementType>
		bool is_not_digit(const ElementType &x)
		{
			return !isdigit(x);
		}

		/********** Compare Two Iterators CaseInsensitive ********/
		template<typename ElementType,typename Iterator>
		struct comp_over_iterator
		{
			int operator()(const Iterator &lhs,const Iterator &rhs) const
			{
				if(natural_less<ElementType>(*lhs,*rhs))
					return -1;
				if(natural_less<ElementType>(*rhs,*lhs))
					return +1;
				return 0;
			}
		};

		/****************************************************
		Comparing two SubString from (Begin,End Iterator each)
		with only digits.
		Usage :
			int compare_number()(\
			FirstNumberBeginIterator,FirstNumberEndIterator,isFirstNumberFractionalPart\
			SecondNumberBeginIterator,SecondNumberEndIterator,isSecondNumberFractionalPart\
			);

		Returns :
			-1  - Number1  <   Number2
			 0  - Number1  ==  Number2
			 1  - Number1  >   Number2

		***************************************************/

		template<typename ValueType, typename Iterator>
		struct compare_number
		{
		private:
			//If Number is Itself fractional Part
			int fractional(Iterator lhsBegin,Iterator lhsEnd, Iterator rhsBegin,Iterator rhsEnd)
			{
				while(lhsBegin<lhsEnd && rhsBegin<rhsEnd)
				{
					int local_compare = comp_over_iterator<ValueType, Iterator>()(lhsBegin,rhsBegin);
					if(local_compare!=0)
						return local_compare;
					lhsBegin++;
					rhsBegin++;
				}
				while(lhsBegin<lhsEnd && *lhsBegin=='0') lhsBegin++;
				while(rhsBegin<rhsEnd && *rhsBegin=='0') rhsBegin++;
				if(lhsBegin==lhsEnd && rhsBegin!=rhsEnd)
					return -1;
				else if(lhsBegin!=lhsEnd && rhsBegin==rhsEnd)
					return +1;
				else //lhsBegin==lhsEnd && rhsBegin==rhsEnd
					return 0;
			}
			int non_fractional(Iterator lhsBegin,Iterator lhsEnd, Iterator rhsBegin,Iterator rhsEnd)
			{
				//Skip Inital Zero's
				while(lhsBegin<lhsEnd && *lhsBegin=='0') lhsBegin++;
				while(rhsBegin<rhsEnd && *rhsBegin=='0') rhsBegin++;

				//Comparing By Length of Both String
				if(lhsEnd-lhsBegin<rhsEnd-rhsBegin)
					return -1;
				if(lhsEnd-lhsBegin>rhsEnd-rhsBegin)
					return +1;

				//Equal In length
				while(lhsBegin<lhsEnd)
				{
					int local_compare = comp_over_iterator<ValueType, Iterator>()(lhsBegin,rhsBegin);
					if(local_compare!=0)
						return local_compare;
					lhsBegin++;
					rhsBegin++;
				}
				return 0;
			}

		public:
			int operator()(\
				Iterator lhsBegin,Iterator lhsEnd,bool isFractionalPart1,\
				Iterator rhsBegin,Iterator rhsEnd,bool isFractionalPart2)
			{
				if(isFractionalPart1 && !isFractionalPart2)
					return true;	//0<num1<1 && num2>=1
				if(!isFractionalPart1 && isFractionalPart2)
					return false;	//0<num2<1 && num1>=1

				//isFractionPart1 == isFactionalPart2
				if(isFractionalPart1)
					return fractional(lhsBegin,lhsEnd,rhsBegin,rhsEnd);
				else
					return non_fractional(lhsBegin,lhsEnd,rhsBegin,rhsEnd);
			}
		};

	}// namespace detail

	/***********************************************************************
	Natural Comparision of Two String using both's (Begin and End Iterator)

	Returns :
		-1  - String1  <   String2
		 0  - String1  ==  String2
		 1  - String1  >   String2

	Suffix 1 represents for components of 1st String
	Suffix 2 represents for components of 2nd String
	************************************************************************/

	template<typename ElementType, typename Iterator>
	bool _compare(\
		const Iterator &lhsBegin,const Iterator &lhsEnd,\
		const Iterator &rhsBegin,const Iterator &rhsEnd)
	{
		Iterator current1 = lhsBegin,current2 = rhsBegin;

		//Flag for Space Found Check
		bool flag_found_space1 = false,flag_found_space2 = false;

		while(current1!=lhsEnd && current2!=rhsEnd)
		{
			//Ignore More than One Continous Space

			/******************************************
			For HandlingComparision Like
				Hello   9
				Hello  10
				Hello 123
			******************************************/
			while(flag_found_space1 && current1!=lhsEnd && *current1==' ') current1++;
			flag_found_space1=false;
			if(*current1==' ') flag_found_space1 = true;

			while(flag_found_space2 && current2!=rhsEnd && *current2==' ') current2++;
			flag_found_space2=false;
			if(*current2==' ') flag_found_space2 = true;

			if( !isdigit(*current1 ) && !isdigit(*current2))
			{
				//If Both Are Non Digits do Normal Comparision
				if(detail::natural_less<ElementType>(*current1,*current2))
					return true;
				if(detail::natural_less<ElementType>(*current2,*current1))
					return false;
				current1++;
				current2++;
			}
			else
			{
				/*********************************
				Capture Numeric Part of Both String
				and then using it to compare Both

				***********************************/
				Iterator last_nondigit1 = 	std::find_if(current1,lhsEnd,detail::is_not_digit<ElementType>);
				Iterator last_nondigit2 = 	std::find_if(current2,rhsEnd,detail::is_not_digit<ElementType>);

				int result = detail::compare_number<ElementType, Iterator>()(\
					current1,last_nondigit1,(current1>lhsBegin && *(current1-1)=='.'), \
					current2,last_nondigit2,(current2>rhsBegin && *(current2-1)=='.'));
				if(result<0)
					return true;
				if(result>0)
					return false;
				current1 = last_nondigit1;
				current2 = last_nondigit2;
			}
		}
		return current1 == lhsEnd;
	}

	template<typename String>
	inline bool compare(const String &first ,const String &second)
	{
		return _compare<typename String::value_type,typename String::const_iterator>(first.begin(),first.end(),second.begin(),second.end());
	}
	template<>
	inline bool compare(char *const &first ,char *const &second)
	{
		char* it1 = first;
		while(*it1!='\0')it1++;
		char* it2 = second;
		while(*it2!='\0')it2++;
		return _compare<char,char*>(first,it1,second,it2);
	}

	template<typename Container>
	inline void sort(Container &container)
	{
		std::sort(container.begin(),container.end(),compare<typename Container::value_type>);
	}

	template<typename Iterator>
	inline void sort(const Iterator &first,const Iterator &end)
	{
		std::sort(first,end,compare<typename Iterator::value_type>);
	}

	template<typename ValueType>
	inline void sort(ValueType* const first,ValueType* const end)
	{
		std::sort(first,end,compare<ValueType>);
	}

	template<typename ValueType,int N>
	inline void sort(ValueType container[N])
	{
		std::sort(&container[0],&container[0]+N,compare<ValueType>);
	}

}//namespace natural
}//namespace SI

#endif
<commit_msg>return false at _compare(a,a)<commit_after>/*
	The MIT License (MIT)
	Copyright (c) 2016 Gagan Kumar(scopeInfinity)
	Complete License at https://raw.githubusercontent.com/scopeInfinity/NaturalSort/master/LICENSE.md
*/

/**********************************************************************
Calling Methods :

	//For Natural Sorting
	void SI::natural::sort(Container<String>);
	void SI::natural::sort(IteratorBegin<String>,IteratorEnd<String>);
	void SI::natural::sort<String,CArraySize>(CArray<String>);

	//For Natural Comparision
	bool SI::natural::compare<String>(String lhs,String rhs);
	bool SI::natural::compare<String>(char *const lhs,char *const rhs);

	Here we can have
		std::vector<std::string> 	as Container<String>
		String 						as std::string
		CArray<String>				as std::string[CArraySize]

***********************************************************************/
#ifndef SI_sort_HPP
#define SI_sort_HPP
#include <cctype>
#include <algorithm>
#include <vector>

namespace SI
{
namespace natural
{
	namespace detail
	{
		/********** Compare Two Character CaseInsensitive ********/
		template<typename ElementType>
		bool natural_less(const ElementType &lhs,const ElementType &rhs)
		{
			if(tolower(lhs)<tolower(rhs))
				return true;
			return false;
		}

		template<typename ElementType>
		bool is_not_digit(const ElementType &x)
		{
			return !isdigit(x);
		}

		/********** Compare Two Iterators CaseInsensitive ********/
		template<typename ElementType,typename Iterator>
		struct comp_over_iterator
		{
			int operator()(const Iterator &lhs,const Iterator &rhs) const
			{
				if(natural_less<ElementType>(*lhs,*rhs))
					return -1;
				if(natural_less<ElementType>(*rhs,*lhs))
					return +1;
				return 0;
			}
		};

		/****************************************************
		Comparing two SubString from (Begin,End Iterator each)
		with only digits.
		Usage :
			int compare_number()(\
			FirstNumberBeginIterator,FirstNumberEndIterator,isFirstNumberFractionalPart\
			SecondNumberBeginIterator,SecondNumberEndIterator,isSecondNumberFractionalPart\
			);

		Returns :
			-1  - Number1  <   Number2
			 0  - Number1  ==  Number2
			 1  - Number1  >   Number2

		***************************************************/

		template<typename ValueType, typename Iterator>
		struct compare_number
		{
		private:
			//If Number is Itself fractional Part
			int fractional(Iterator lhsBegin,Iterator lhsEnd, Iterator rhsBegin,Iterator rhsEnd)
			{
				while(lhsBegin<lhsEnd && rhsBegin<rhsEnd)
				{
					int local_compare = comp_over_iterator<ValueType, Iterator>()(lhsBegin,rhsBegin);
					if(local_compare!=0)
						return local_compare;
					lhsBegin++;
					rhsBegin++;
				}
				while(lhsBegin<lhsEnd && *lhsBegin=='0') lhsBegin++;
				while(rhsBegin<rhsEnd && *rhsBegin=='0') rhsBegin++;
				if(lhsBegin==lhsEnd && rhsBegin!=rhsEnd)
					return -1;
				else if(lhsBegin!=lhsEnd && rhsBegin==rhsEnd)
					return +1;
				else //lhsBegin==lhsEnd && rhsBegin==rhsEnd
					return 0;
			}
			int non_fractional(Iterator lhsBegin,Iterator lhsEnd, Iterator rhsBegin,Iterator rhsEnd)
			{
				//Skip Inital Zero's
				while(lhsBegin<lhsEnd && *lhsBegin=='0') lhsBegin++;
				while(rhsBegin<rhsEnd && *rhsBegin=='0') rhsBegin++;

				//Comparing By Length of Both String
				if(lhsEnd-lhsBegin<rhsEnd-rhsBegin)
					return -1;
				if(lhsEnd-lhsBegin>rhsEnd-rhsBegin)
					return +1;

				//Equal In length
				while(lhsBegin<lhsEnd)
				{
					int local_compare = comp_over_iterator<ValueType, Iterator>()(lhsBegin,rhsBegin);
					if(local_compare!=0)
						return local_compare;
					lhsBegin++;
					rhsBegin++;
				}
				return 0;
			}

		public:
			int operator()(\
				Iterator lhsBegin,Iterator lhsEnd,bool isFractionalPart1,\
				Iterator rhsBegin,Iterator rhsEnd,bool isFractionalPart2)
			{
				if(isFractionalPart1 && !isFractionalPart2)
					return true;	//0<num1<1 && num2>=1
				if(!isFractionalPart1 && isFractionalPart2)
					return false;	//0<num2<1 && num1>=1

				//isFractionPart1 == isFactionalPart2
				if(isFractionalPart1)
					return fractional(lhsBegin,lhsEnd,rhsBegin,rhsEnd);
				else
					return non_fractional(lhsBegin,lhsEnd,rhsBegin,rhsEnd);
			}
		};

	}// namespace detail

	/***********************************************************************
	Natural Comparision of Two String using both's (Begin and End Iterator)

	Returns :
		-1  - String1  <   String2
		 0  - String1  ==  String2
		 1  - String1  >   String2

	Suffix 1 represents for components of 1st String
	Suffix 2 represents for components of 2nd String
	************************************************************************/

	template<typename ElementType, typename Iterator>
	bool _compare(\
		const Iterator &lhsBegin,const Iterator &lhsEnd,\
		const Iterator &rhsBegin,const Iterator &rhsEnd)
	{
		Iterator current1 = lhsBegin,current2 = rhsBegin;

		//Flag for Space Found Check
		bool flag_found_space1 = false,flag_found_space2 = false;

		while(current1!=lhsEnd && current2!=rhsEnd)
		{
			//Ignore More than One Continous Space

			/******************************************
			For HandlingComparision Like
				Hello   9
				Hello  10
				Hello 123
			******************************************/
			while(flag_found_space1 && current1!=lhsEnd && *current1==' ') current1++;
			flag_found_space1=false;
			if(*current1==' ') flag_found_space1 = true;

			while(flag_found_space2 && current2!=rhsEnd && *current2==' ') current2++;
			flag_found_space2=false;
			if(*current2==' ') flag_found_space2 = true;

			if( !isdigit(*current1 ) && !isdigit(*current2))
			{
				//If Both Are Non Digits do Normal Comparision
				if(detail::natural_less<ElementType>(*current1,*current2))
					return true;
				if(detail::natural_less<ElementType>(*current2,*current1))
					return false;
				current1++;
				current2++;
			}
			else
			{
				/*********************************
				Capture Numeric Part of Both String
				and then using it to compare Both

				***********************************/
				Iterator last_nondigit1 = 	std::find_if(current1,lhsEnd,detail::is_not_digit<ElementType>);
				Iterator last_nondigit2 = 	std::find_if(current2,rhsEnd,detail::is_not_digit<ElementType>);

				int result = detail::compare_number<ElementType, Iterator>()(\
					current1,last_nondigit1,(current1>lhsBegin && *(current1-1)=='.'), \
					current2,last_nondigit2,(current2>rhsBegin && *(current2-1)=='.'));
				if(result<0)
					return true;
				if(result>0)
					return false;
				current1 = last_nondigit1;
				current2 = last_nondigit2;
			}
		}

		if (current1 == lhsEnd && current2 == rhsEnd) {
			return false;
		} else {
			return current1 == lhsEnd;
		}
	}

	template<typename String>
	inline bool compare(const String &first ,const String &second)
	{
		return _compare<typename String::value_type,typename String::const_iterator>(first.begin(),first.end(),second.begin(),second.end());
	}
	template<>
	inline bool compare(char *const &first ,char *const &second)
	{
		char* it1 = first;
		while(*it1!='\0')it1++;
		char* it2 = second;
		while(*it2!='\0')it2++;
		return _compare<char,char*>(first,it1,second,it2);
	}

	template<typename Container>
	inline void sort(Container &container)
	{
		std::sort(container.begin(),container.end(),compare<typename Container::value_type>);
	}

	template<typename Iterator>
	inline void sort(const Iterator &first,const Iterator &end)
	{
		std::sort(first,end,compare<typename Iterator::value_type>);
	}

	template<typename ValueType>
	inline void sort(ValueType* const first,ValueType* const end)
	{
		std::sort(first,end,compare<ValueType>);
	}

	template<typename ValueType,int N>
	inline void sort(ValueType container[N])
	{
		std::sort(&container[0],&container[0]+N,compare<ValueType>);
	}

}//namespace natural
}//namespace SI

#endif
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2020 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include "vp9/ratectrl_rtc.h"

#include <fstream>  // NOLINT
#include <string>

#include "./vpx_config.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/video_source.h"
#include "vpx/vpx_codec.h"
#include "vpx_ports/bitops.h"

namespace {

const size_t kNumFrame = 850;

struct FrameInfo {
  friend std::istream &operator>>(std::istream &is, FrameInfo &info) {
    is >> info.frame_id >> info.spatial_id >> info.temporal_id >> info.base_q >>
        info.target_bandwidth >> info.buffer_level >> info.filter_level_ >>
        info.bytes_used;
    return is;
  }
  int frame_id;
  int spatial_id;
  int temporal_id;
  // Base QP
  int base_q;
  size_t target_bandwidth;
  size_t buffer_level;
  // Loopfilter level
  int filter_level_;
  // Frame size for current frame, used for pose encode update
  size_t bytes_used;
};

// This test runs the rate control interface and compare against ground truth
// generated by encoders.
// Settings for the encoder:
// For 1 layer:
//
// examples/vpx_temporal_svc_encoder gipsrec_motion1.1280_720.yuv out vp9
//    1280 720 1 30 7 0 0 1 0 1000
//
// For SVC (3 temporal layers, 3 spatial layers):
//
// examples/vp9_spatial_svc_encoder -f 10000 -w 1280 -h 720 -t 1/30 -sl 3
// -k 10000 -bl 100,140,200,250,350,500,450,630,900 -b 1600 --rc-end-usage=1
// --lag-in-frames=0 --passes=1 --speed=7 --threads=1
// --temporal-layering-mode=3 -aq 1 -rcstat 1
// gipsrec_motion1.1280_720.yuv -o out.webm
//
// - AQ_Mode 0
// - Disable golden refresh
// - Bitrate x 2 at frame/superframe 200
// - Bitrate / 4 at frame/superframe 400
//
// The generated file includes:
// frame number, spatial layer ID, temporal layer ID, base QP, target
// bandwidth, buffer level, loopfilter level, encoded frame size
// TODO(jianj): Remove golden files, and run actual encoding in this test.
class RcInterfaceTest : public ::testing::Test {
 public:
  explicit RcInterfaceTest() {}

  virtual ~RcInterfaceTest() {}

 protected:
  void RunOneLayer() {
    SetConfigOneLayer();
    rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_);
    FrameInfo frame_info;
    libvpx::VP9FrameParamsQpRTC frame_params;
    frame_params.frame_type = KEY_FRAME;
    frame_params.spatial_layer_id = 0;
    frame_params.temporal_layer_id = 0;
    std::ifstream one_layer_file;
    one_layer_file.open(libvpx_test::GetDataPath() +
                        "/rc_interface_test_one_layer");
    ASSERT_TRUE(one_layer_file.good());
    for (size_t i = 0; i < kNumFrame; i++) {
      one_layer_file >> frame_info;
      if (frame_info.frame_id > 0) frame_params.frame_type = INTER_FRAME;
      if (frame_info.frame_id == 200) {
        rc_cfg_.target_bandwidth = rc_cfg_.target_bandwidth * 2;
        rc_api_->UpdateRateControl(rc_cfg_);
      } else if (frame_info.frame_id == 400) {
        rc_cfg_.target_bandwidth = rc_cfg_.target_bandwidth / 4;
        rc_api_->UpdateRateControl(rc_cfg_);
      }
      ASSERT_EQ(frame_info.spatial_id, 0);
      ASSERT_EQ(frame_info.temporal_id, 0);
      rc_api_->ComputeQP(frame_params);
      ASSERT_EQ(rc_api_->GetQP(), frame_info.base_q);
      ASSERT_EQ(rc_api_->GetLoopfilterLevel(), frame_info.filter_level_);
      rc_api_->PostEncodeUpdate(frame_info.bytes_used);
    }
  }

  void RunSVC() {
    SetConfigSVC();
    rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_);
    FrameInfo frame_info;
    libvpx::VP9FrameParamsQpRTC frame_params;
    frame_params.frame_type = KEY_FRAME;
    std::ifstream svc_file;
    svc_file.open(std::string(std::getenv("LIBVPX_TEST_DATA_PATH")) +
                  "/rc_interface_test_svc");
    ASSERT_TRUE(svc_file.good());
    for (size_t i = 0; i < kNumFrame * rc_cfg_.ss_number_layers; i++) {
      svc_file >> frame_info;
      if (frame_info.frame_id > 0) frame_params.frame_type = INTER_FRAME;
      if (frame_info.frame_id == 200 * rc_cfg_.ss_number_layers) {
        for (int layer = 0;
             layer < rc_cfg_.ss_number_layers * rc_cfg_.ts_number_layers;
             layer++)
          rc_cfg_.layer_target_bitrate[layer] *= 2;
        rc_cfg_.target_bandwidth *= 2;
        rc_api_->UpdateRateControl(rc_cfg_);
      } else if (frame_info.frame_id == 400 * rc_cfg_.ss_number_layers) {
        for (int layer = 0;
             layer < rc_cfg_.ss_number_layers * rc_cfg_.ts_number_layers;
             layer++)
          rc_cfg_.layer_target_bitrate[layer] /= 4;
        rc_cfg_.target_bandwidth /= 4;
        rc_api_->UpdateRateControl(rc_cfg_);
      }
      frame_params.spatial_layer_id = frame_info.spatial_id;
      frame_params.temporal_layer_id = frame_info.temporal_id;
      rc_api_->ComputeQP(frame_params);
      ASSERT_EQ(rc_api_->GetQP(), frame_info.base_q);
      ASSERT_EQ(rc_api_->GetLoopfilterLevel(), frame_info.filter_level_);
      rc_api_->PostEncodeUpdate(frame_info.bytes_used);
    }
  }

 private:
  void SetConfigOneLayer() {
    rc_cfg_.width = 1280;
    rc_cfg_.height = 720;
    rc_cfg_.max_quantizer = 52;
    rc_cfg_.min_quantizer = 2;
    rc_cfg_.target_bandwidth = 1000;
    rc_cfg_.buf_initial_sz = 600;
    rc_cfg_.buf_optimal_sz = 600;
    rc_cfg_.buf_sz = 1000;
    rc_cfg_.undershoot_pct = 50;
    rc_cfg_.overshoot_pct = 50;
    rc_cfg_.max_intra_bitrate_pct = 1000;
    rc_cfg_.framerate = 30.0;
    rc_cfg_.ss_number_layers = 1;
    rc_cfg_.ts_number_layers = 1;
    rc_cfg_.scaling_factor_num[0] = 1;
    rc_cfg_.scaling_factor_den[0] = 1;
    rc_cfg_.layer_target_bitrate[0] = 1000;
    rc_cfg_.max_quantizers[0] = 52;
    rc_cfg_.min_quantizers[0] = 2;
  }

  void SetConfigSVC() {
    rc_cfg_.width = 1280;
    rc_cfg_.height = 720;
    rc_cfg_.max_quantizer = 56;
    rc_cfg_.min_quantizer = 2;
    rc_cfg_.target_bandwidth = 1600;
    rc_cfg_.buf_initial_sz = 500;
    rc_cfg_.buf_optimal_sz = 600;
    rc_cfg_.buf_sz = 1000;
    rc_cfg_.undershoot_pct = 50;
    rc_cfg_.overshoot_pct = 50;
    rc_cfg_.max_intra_bitrate_pct = 900;
    rc_cfg_.framerate = 30.0;
    rc_cfg_.ss_number_layers = 3;
    rc_cfg_.ts_number_layers = 3;

    rc_cfg_.scaling_factor_num[0] = 1;
    rc_cfg_.scaling_factor_den[0] = 4;
    rc_cfg_.scaling_factor_num[1] = 2;
    rc_cfg_.scaling_factor_den[1] = 4;
    rc_cfg_.scaling_factor_num[2] = 4;
    rc_cfg_.scaling_factor_den[2] = 4;

    rc_cfg_.ts_rate_decimator[0] = 4;
    rc_cfg_.ts_rate_decimator[1] = 2;
    rc_cfg_.ts_rate_decimator[2] = 1;

    rc_cfg_.layer_target_bitrate[0] = 100;
    rc_cfg_.layer_target_bitrate[1] = 140;
    rc_cfg_.layer_target_bitrate[2] = 200;
    rc_cfg_.layer_target_bitrate[3] = 250;
    rc_cfg_.layer_target_bitrate[4] = 350;
    rc_cfg_.layer_target_bitrate[5] = 500;
    rc_cfg_.layer_target_bitrate[6] = 450;
    rc_cfg_.layer_target_bitrate[7] = 630;
    rc_cfg_.layer_target_bitrate[8] = 900;

    for (int sl = 0; sl < rc_cfg_.ss_number_layers; ++sl) {
      for (int tl = 0; tl < rc_cfg_.ts_number_layers; ++tl) {
        const int i = sl * rc_cfg_.ts_number_layers + tl;
        rc_cfg_.max_quantizers[i] = 56;
        rc_cfg_.min_quantizers[i] = 2;
      }
    }
  }

  std::unique_ptr<libvpx::VP9RateControlRTC> rc_api_;
  libvpx::VP9RateControlRtcConfig rc_cfg_;
};

TEST_F(RcInterfaceTest, OneLayer) { RunOneLayer(); }

TEST_F(RcInterfaceTest, SVC) { RunSVC(); }
}  // namespace

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>Change the data path in svc rate control test<commit_after>/*
 *  Copyright (c) 2020 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include "vp9/ratectrl_rtc.h"

#include <fstream>  // NOLINT
#include <string>

#include "./vpx_config.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/video_source.h"
#include "vpx/vpx_codec.h"
#include "vpx_ports/bitops.h"

namespace {

const size_t kNumFrame = 850;

struct FrameInfo {
  friend std::istream &operator>>(std::istream &is, FrameInfo &info) {
    is >> info.frame_id >> info.spatial_id >> info.temporal_id >> info.base_q >>
        info.target_bandwidth >> info.buffer_level >> info.filter_level_ >>
        info.bytes_used;
    return is;
  }
  int frame_id;
  int spatial_id;
  int temporal_id;
  // Base QP
  int base_q;
  size_t target_bandwidth;
  size_t buffer_level;
  // Loopfilter level
  int filter_level_;
  // Frame size for current frame, used for pose encode update
  size_t bytes_used;
};

// This test runs the rate control interface and compare against ground truth
// generated by encoders.
// Settings for the encoder:
// For 1 layer:
//
// examples/vpx_temporal_svc_encoder gipsrec_motion1.1280_720.yuv out vp9
//    1280 720 1 30 7 0 0 1 0 1000
//
// For SVC (3 temporal layers, 3 spatial layers):
//
// examples/vp9_spatial_svc_encoder -f 10000 -w 1280 -h 720 -t 1/30 -sl 3
// -k 10000 -bl 100,140,200,250,350,500,450,630,900 -b 1600 --rc-end-usage=1
// --lag-in-frames=0 --passes=1 --speed=7 --threads=1
// --temporal-layering-mode=3 -aq 1 -rcstat 1
// gipsrec_motion1.1280_720.yuv -o out.webm
//
// - AQ_Mode 0
// - Disable golden refresh
// - Bitrate x 2 at frame/superframe 200
// - Bitrate / 4 at frame/superframe 400
//
// The generated file includes:
// frame number, spatial layer ID, temporal layer ID, base QP, target
// bandwidth, buffer level, loopfilter level, encoded frame size
// TODO(jianj): Remove golden files, and run actual encoding in this test.
class RcInterfaceTest : public ::testing::Test {
 public:
  explicit RcInterfaceTest() {}

  virtual ~RcInterfaceTest() {}

 protected:
  void RunOneLayer() {
    SetConfigOneLayer();
    rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_);
    FrameInfo frame_info;
    libvpx::VP9FrameParamsQpRTC frame_params;
    frame_params.frame_type = KEY_FRAME;
    frame_params.spatial_layer_id = 0;
    frame_params.temporal_layer_id = 0;
    std::ifstream one_layer_file;
    one_layer_file.open(libvpx_test::GetDataPath() +
                        "/rc_interface_test_one_layer");
    ASSERT_TRUE(one_layer_file.good());
    for (size_t i = 0; i < kNumFrame; i++) {
      one_layer_file >> frame_info;
      if (frame_info.frame_id > 0) frame_params.frame_type = INTER_FRAME;
      if (frame_info.frame_id == 200) {
        rc_cfg_.target_bandwidth = rc_cfg_.target_bandwidth * 2;
        rc_api_->UpdateRateControl(rc_cfg_);
      } else if (frame_info.frame_id == 400) {
        rc_cfg_.target_bandwidth = rc_cfg_.target_bandwidth / 4;
        rc_api_->UpdateRateControl(rc_cfg_);
      }
      ASSERT_EQ(frame_info.spatial_id, 0);
      ASSERT_EQ(frame_info.temporal_id, 0);
      rc_api_->ComputeQP(frame_params);
      ASSERT_EQ(rc_api_->GetQP(), frame_info.base_q);
      ASSERT_EQ(rc_api_->GetLoopfilterLevel(), frame_info.filter_level_);
      rc_api_->PostEncodeUpdate(frame_info.bytes_used);
    }
  }

  void RunSVC() {
    SetConfigSVC();
    rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_);
    FrameInfo frame_info;
    libvpx::VP9FrameParamsQpRTC frame_params;
    frame_params.frame_type = KEY_FRAME;
    std::ifstream svc_file;
    svc_file.open(libvpx_test::GetDataPath() + "/rc_interface_test_svc");
    ASSERT_TRUE(svc_file.good());
    for (size_t i = 0; i < kNumFrame * rc_cfg_.ss_number_layers; i++) {
      svc_file >> frame_info;
      if (frame_info.frame_id > 0) frame_params.frame_type = INTER_FRAME;
      if (frame_info.frame_id == 200 * rc_cfg_.ss_number_layers) {
        for (int layer = 0;
             layer < rc_cfg_.ss_number_layers * rc_cfg_.ts_number_layers;
             layer++)
          rc_cfg_.layer_target_bitrate[layer] *= 2;
        rc_cfg_.target_bandwidth *= 2;
        rc_api_->UpdateRateControl(rc_cfg_);
      } else if (frame_info.frame_id == 400 * rc_cfg_.ss_number_layers) {
        for (int layer = 0;
             layer < rc_cfg_.ss_number_layers * rc_cfg_.ts_number_layers;
             layer++)
          rc_cfg_.layer_target_bitrate[layer] /= 4;
        rc_cfg_.target_bandwidth /= 4;
        rc_api_->UpdateRateControl(rc_cfg_);
      }
      frame_params.spatial_layer_id = frame_info.spatial_id;
      frame_params.temporal_layer_id = frame_info.temporal_id;
      rc_api_->ComputeQP(frame_params);
      ASSERT_EQ(rc_api_->GetQP(), frame_info.base_q);
      ASSERT_EQ(rc_api_->GetLoopfilterLevel(), frame_info.filter_level_);
      rc_api_->PostEncodeUpdate(frame_info.bytes_used);
    }
  }

 private:
  void SetConfigOneLayer() {
    rc_cfg_.width = 1280;
    rc_cfg_.height = 720;
    rc_cfg_.max_quantizer = 52;
    rc_cfg_.min_quantizer = 2;
    rc_cfg_.target_bandwidth = 1000;
    rc_cfg_.buf_initial_sz = 600;
    rc_cfg_.buf_optimal_sz = 600;
    rc_cfg_.buf_sz = 1000;
    rc_cfg_.undershoot_pct = 50;
    rc_cfg_.overshoot_pct = 50;
    rc_cfg_.max_intra_bitrate_pct = 1000;
    rc_cfg_.framerate = 30.0;
    rc_cfg_.ss_number_layers = 1;
    rc_cfg_.ts_number_layers = 1;
    rc_cfg_.scaling_factor_num[0] = 1;
    rc_cfg_.scaling_factor_den[0] = 1;
    rc_cfg_.layer_target_bitrate[0] = 1000;
    rc_cfg_.max_quantizers[0] = 52;
    rc_cfg_.min_quantizers[0] = 2;
  }

  void SetConfigSVC() {
    rc_cfg_.width = 1280;
    rc_cfg_.height = 720;
    rc_cfg_.max_quantizer = 56;
    rc_cfg_.min_quantizer = 2;
    rc_cfg_.target_bandwidth = 1600;
    rc_cfg_.buf_initial_sz = 500;
    rc_cfg_.buf_optimal_sz = 600;
    rc_cfg_.buf_sz = 1000;
    rc_cfg_.undershoot_pct = 50;
    rc_cfg_.overshoot_pct = 50;
    rc_cfg_.max_intra_bitrate_pct = 900;
    rc_cfg_.framerate = 30.0;
    rc_cfg_.ss_number_layers = 3;
    rc_cfg_.ts_number_layers = 3;

    rc_cfg_.scaling_factor_num[0] = 1;
    rc_cfg_.scaling_factor_den[0] = 4;
    rc_cfg_.scaling_factor_num[1] = 2;
    rc_cfg_.scaling_factor_den[1] = 4;
    rc_cfg_.scaling_factor_num[2] = 4;
    rc_cfg_.scaling_factor_den[2] = 4;

    rc_cfg_.ts_rate_decimator[0] = 4;
    rc_cfg_.ts_rate_decimator[1] = 2;
    rc_cfg_.ts_rate_decimator[2] = 1;

    rc_cfg_.layer_target_bitrate[0] = 100;
    rc_cfg_.layer_target_bitrate[1] = 140;
    rc_cfg_.layer_target_bitrate[2] = 200;
    rc_cfg_.layer_target_bitrate[3] = 250;
    rc_cfg_.layer_target_bitrate[4] = 350;
    rc_cfg_.layer_target_bitrate[5] = 500;
    rc_cfg_.layer_target_bitrate[6] = 450;
    rc_cfg_.layer_target_bitrate[7] = 630;
    rc_cfg_.layer_target_bitrate[8] = 900;

    for (int sl = 0; sl < rc_cfg_.ss_number_layers; ++sl) {
      for (int tl = 0; tl < rc_cfg_.ts_number_layers; ++tl) {
        const int i = sl * rc_cfg_.ts_number_layers + tl;
        rc_cfg_.max_quantizers[i] = 56;
        rc_cfg_.min_quantizers[i] = 2;
      }
    }
  }

  std::unique_ptr<libvpx::VP9RateControlRTC> rc_api_;
  libvpx::VP9RateControlRtcConfig rc_cfg_;
};

TEST_F(RcInterfaceTest, OneLayer) { RunOneLayer(); }

TEST_F(RcInterfaceTest, SVC) { RunSVC(); }
}  // namespace

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>/*
 * opencog/server/BuiltinRequestsModule.cc
 *
 * Copyright (C) 2008 by OpenCog Foundation
 * All Rights Reserved
 *
 * Written by Gustavo Gama <gama@vettalabs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "BuiltinRequestsModule.h"

#include <opencog/server/CogServer.h>
#include <opencog/util/ansi.h>

using namespace opencog;

DECLARE_MODULE(BuiltinRequestsModule)

BuiltinRequestsModule::BuiltinRequestsModule(CogServer& cs) : Module(cs)
{
    _cogserver.registerRequest(ListRequest::info().id,         &listFactory);
    _cogserver.registerRequest(SleepRequest::info().id,        &sleepFactory);
    _cogserver.registerRequest(ShutdownRequest::info().id,     &shutdownFactory);
    _cogserver.registerRequest(LoadModuleRequest::info().id,   &loadmoduleFactory);
    _cogserver.registerRequest(UnloadModuleRequest::info().id, &unloadmoduleFactory);
    _cogserver.registerRequest(ListModulesRequest::info().id,  &listmodulesFactory);
    registerAgentRequests();
}

BuiltinRequestsModule::~BuiltinRequestsModule()
{
    _cogserver.unregisterRequest(ListRequest::info().id);
    _cogserver.unregisterRequest(SleepRequest::info().id);
    _cogserver.unregisterRequest(ShutdownRequest::info().id);
    _cogserver.unregisterRequest(LoadModuleRequest::info().id);
    _cogserver.unregisterRequest(UnloadModuleRequest::info().id);
    _cogserver.unregisterRequest(ListModulesRequest::info().id);
    unregisterAgentRequests();
}

void BuiltinRequestsModule::registerAgentRequests()
{
    do_help_register();
    do_h_register();

    do_exit_register();
    do_quit_register();
    do_q_register();
    do_ctrld_register();

    do_startAgents_register();
    do_stopAgents_register();
    do_stepAgents_register();
    do_startAgentLoop_register();
    do_stopAgentLoop_register();
    do_listAgents_register();
    do_activeAgents_register();
}

void BuiltinRequestsModule::unregisterAgentRequests()
{
    do_help_unregister();
    do_h_unregister();

    do_exit_unregister();
    do_quit_unregister();
    do_q_unregister();
    do_ctrld_unregister();

    do_startAgents_unregister();
    do_stopAgents_unregister();
    do_stepAgents_unregister();
    do_startAgentLoop_unregister();
    do_stopAgentLoop_unregister();
    do_listAgents_unregister();
    do_activeAgents_unregister();
}

void BuiltinRequestsModule::init()
{
}

// ====================================================================
// Various flavors of closing the connection
std::string BuiltinRequestsModule::do_exit(Request *req, std::list<std::string> args)
{
    RequestResult* rr = req->getRequestResult();
    if (rr) {
        rr->Exit();
        req->setRequestResult(NULL);
    }
    return "";
}

std::string BuiltinRequestsModule::do_quit(Request *req, std::list<std::string> args)
{
    return do_exit(req, args);
}

std::string BuiltinRequestsModule::do_q(Request *req, std::list<std::string> args)
{
    return do_exit(req, args);
}

std::string BuiltinRequestsModule::do_ctrld(Request *req, std::list<std::string> args)
{
    return do_exit(req, args);
}

// ====================================================================
// Various flavors of help
std::string BuiltinRequestsModule::do_help(Request *req, std::list<std::string> args)
{
    std::ostringstream oss;

    if (args.empty()) {
        std::list<const char*> commands = _cogserver.requestIds();

        size_t maxl = 0;
        std::list<const char*>::const_iterator it;
        for (it = commands.begin(); it != commands.end(); ++it) {
            size_t len = strlen(*it);
            if (len > maxl) maxl = len;
        }

        oss << "Available commands:" << std::endl;
        for (it = commands.begin(); it != commands.end(); ++it) {
            // Skip hidden commands
            if (_cogserver.requestInfo(*it).hidden) continue;
            std::string cmdname(*it);
            std::string ansi_cmdname;
            ansi_green(ansi_cmdname); ansi_bright(ansi_cmdname);
            ansi_cmdname.append(cmdname);
            ansi_off(ansi_cmdname);
            ansi_green(ansi_cmdname);
            ansi_cmdname.append(":");
            ansi_off(ansi_cmdname);
            size_t cmd_length = strlen(cmdname.c_str());
            size_t ansi_code_length = strlen(ansi_cmdname.c_str()) - cmd_length;
            oss << "  " << std::setw(maxl+ansi_code_length+2) << std::left << ansi_cmdname
                << _cogserver.requestInfo(*it).description << std::endl;
        }
    } else if (args.size() == 1) {
        const RequestClassInfo& cci = _cogserver.requestInfo(args.front());
        if (cci.help != "")
            oss << cci.help << std::endl;
    } else {
        oss << do_helpRequest::info().help << std::endl;
    }

    return oss.str();
}

std::string BuiltinRequestsModule::do_h(Request *req, std::list<std::string> args)
{
    return do_help(req, args);
}

// ====================================================================
// Various agents commands
std::string BuiltinRequestsModule::do_startAgents(Request *dummy, std::list<std::string> args)
{
    std::list<const char*> availableAgents = _cogserver.agentIds();

    std::vector<std::string> agents;

    if (args.size() == 0)
        return "Error: No agents to start specified";

    for (std::list<std::string>::const_iterator it = args.begin();
         it != args.end(); ++it) {
        std::string agent_type = *it;
        // check that this is a valid type; give an error and return otherwise
        if (availableAgents.end() ==
         find(availableAgents.begin(), availableAgents.end(), *it)) {
            std::ostringstream oss;
            oss << "Invalid Agent ID (" << *it << ")";
            return oss.str();
        }

        agents.push_back(agent_type);
     }

    for (std::vector<std::string>::const_iterator it = agents.begin();
         it != agents.end(); ++it) {
        _cogserver.createAgent(*it, true);
    }

    return "Successfully started agents";
}

std::string BuiltinRequestsModule::do_stopAgents(Request *dummy, std::list<std::string> args)
{
    std::list<const char*> availableAgents = _cogserver.agentIds();

    std::vector<std::string> agents;

    if (args.size() == 0)
        return "Error: No agents to stop specified";

    for (std::list<std::string>::const_iterator it = args.begin();
         it != args.end(); ++it) {
        std::string agent_type = *it;
        // check that this is a valid type; give an error and return otherwise
        if (availableAgents.end() ==
         find(availableAgents.begin(), availableAgents.end(), *it)) {
            std::ostringstream oss;
            oss << "Invalid Agent ID (" << *it << ")";
            return oss.str();
        }

        agents.push_back(agent_type);
    }
    // doesn't give an error if there is no instance of that agent type running

    for (std::vector<std::string>::const_iterator it = agents.begin();
         it != agents.end(); ++it) {
        // Check if this Agent instance is also a module
        if (_cogserver.getModule(*it) != NULL) {
            // delete the Agent instance if it is not
            _cogserver.destroyAllAgents(*it);
        }
    }

    return "Successfully stopped agents";
}

std::string BuiltinRequestsModule::do_stepAgents(Request *dummy, std::list<std::string> args)
{
    AgentSeq agents = _cogserver.runningAgents();

    if (args.size() == 0) {
        for (AgentSeq::const_iterator it = agents.begin();
             it != agents.end(); ++it) {
            (*it)->run();
        }
        return "Ran a step of each active agent";
    } else {
        std::list<std::string> unknownAgents;
        int numberAgentsRun = 0;
        for (std::list<std::string>::const_iterator it = args.begin();
             it != args.end(); ++it) {

            std::string agent_type = *it;

            // try to find an already started agent with that name
            AgentSeq::const_iterator tmp = agents.begin();
            for ( ; tmp != agents.end() ; tmp++ ) if ( *it == (*tmp)->classinfo().id ) break;

            AgentPtr agent;
            if (agents.end() == tmp) {
                // construct a temporary agent
                agent = AgentPtr(_cogserver.createAgent(*it, false));
                if (agent) {
                    agent->run();
                    _cogserver.destroyAgent(agent);
                    numberAgentsRun++;
                } else {
                    unknownAgents.push_back(*it);
                }
            } else {
                agent = *tmp;
                agent->run();
            }
        }
        std::stringstream returnMsg;
        for (std::list<std::string>::iterator it = unknownAgents.begin();
                it != unknownAgents.end(); ++it) {
            returnMsg << "Unknown agent " << *it << std::endl;
        }
        returnMsg << "Successfully ran a step of " << numberAgentsRun <<
            "/" << args.size() << " agents." << std::endl;
        return returnMsg.str();
    }
}

std::string BuiltinRequestsModule::do_stopAgentLoop(Request *dummy, std::list<std::string> args)
{
    _cogserver.stopAgentLoop();

    return "Stopped agent loop";
}

std::string BuiltinRequestsModule::do_startAgentLoop(Request *dummy, std::list<std::string> args)
{
    _cogserver.startAgentLoop();

    return "Started agent loop";
}

std::string BuiltinRequestsModule::do_listAgents(Request *dummy, std::list<std::string> args)
{
    std::list<const char*> agentNames = _cogserver.agentIds();
    std::ostringstream oss;

    for (std::list<const char*>::const_iterator it = agentNames.begin();
         it != agentNames.end(); ++it) {
        oss << (*it) << std::endl;
    }

    return oss.str();
}

std::string BuiltinRequestsModule::do_activeAgents(Request *dummy, std::list<std::string> args)
{
    AgentSeq agents = _cogserver.runningAgents();
    std::ostringstream oss;

    for (AgentSeq::const_iterator it = agents.begin();
         it != agents.end(); ++it) {
        oss << (*it)->to_string() << std::endl;
    }

    return oss.str();
}
<commit_msg>Add a missing carriage return<commit_after>/*
 * opencog/server/BuiltinRequestsModule.cc
 *
 * Copyright (C) 2008 by OpenCog Foundation
 * All Rights Reserved
 *
 * Written by Gustavo Gama <gama@vettalabs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "BuiltinRequestsModule.h"

#include <opencog/server/CogServer.h>
#include <opencog/util/ansi.h>

using namespace opencog;

DECLARE_MODULE(BuiltinRequestsModule)

BuiltinRequestsModule::BuiltinRequestsModule(CogServer& cs) : Module(cs)
{
    _cogserver.registerRequest(ListRequest::info().id,         &listFactory);
    _cogserver.registerRequest(SleepRequest::info().id,        &sleepFactory);
    _cogserver.registerRequest(ShutdownRequest::info().id,     &shutdownFactory);
    _cogserver.registerRequest(LoadModuleRequest::info().id,   &loadmoduleFactory);
    _cogserver.registerRequest(UnloadModuleRequest::info().id, &unloadmoduleFactory);
    _cogserver.registerRequest(ListModulesRequest::info().id,  &listmodulesFactory);
    registerAgentRequests();
}

BuiltinRequestsModule::~BuiltinRequestsModule()
{
    _cogserver.unregisterRequest(ListRequest::info().id);
    _cogserver.unregisterRequest(SleepRequest::info().id);
    _cogserver.unregisterRequest(ShutdownRequest::info().id);
    _cogserver.unregisterRequest(LoadModuleRequest::info().id);
    _cogserver.unregisterRequest(UnloadModuleRequest::info().id);
    _cogserver.unregisterRequest(ListModulesRequest::info().id);
    unregisterAgentRequests();
}

void BuiltinRequestsModule::registerAgentRequests()
{
    do_help_register();
    do_h_register();

    do_exit_register();
    do_quit_register();
    do_q_register();
    do_ctrld_register();

    do_startAgents_register();
    do_stopAgents_register();
    do_stepAgents_register();
    do_startAgentLoop_register();
    do_stopAgentLoop_register();
    do_listAgents_register();
    do_activeAgents_register();
}

void BuiltinRequestsModule::unregisterAgentRequests()
{
    do_help_unregister();
    do_h_unregister();

    do_exit_unregister();
    do_quit_unregister();
    do_q_unregister();
    do_ctrld_unregister();

    do_startAgents_unregister();
    do_stopAgents_unregister();
    do_stepAgents_unregister();
    do_startAgentLoop_unregister();
    do_stopAgentLoop_unregister();
    do_listAgents_unregister();
    do_activeAgents_unregister();
}

void BuiltinRequestsModule::init()
{
}

// ====================================================================
// Various flavors of closing the connection
std::string BuiltinRequestsModule::do_exit(Request *req, std::list<std::string> args)
{
    RequestResult* rr = req->getRequestResult();
    if (rr) {
        rr->Exit();
        req->setRequestResult(NULL);
    }
    return "";
}

std::string BuiltinRequestsModule::do_quit(Request *req, std::list<std::string> args)
{
    return do_exit(req, args);
}

std::string BuiltinRequestsModule::do_q(Request *req, std::list<std::string> args)
{
    return do_exit(req, args);
}

std::string BuiltinRequestsModule::do_ctrld(Request *req, std::list<std::string> args)
{
    return do_exit(req, args);
}

// ====================================================================
// Various flavors of help
std::string BuiltinRequestsModule::do_help(Request *req, std::list<std::string> args)
{
    std::ostringstream oss;

    if (args.empty()) {
        std::list<const char*> commands = _cogserver.requestIds();

        size_t maxl = 0;
        std::list<const char*>::const_iterator it;
        for (it = commands.begin(); it != commands.end(); ++it) {
            size_t len = strlen(*it);
            if (len > maxl) maxl = len;
        }

        oss << "Available commands:" << std::endl;
        for (it = commands.begin(); it != commands.end(); ++it) {
            // Skip hidden commands
            if (_cogserver.requestInfo(*it).hidden) continue;
            std::string cmdname(*it);
            std::string ansi_cmdname;
            ansi_green(ansi_cmdname); ansi_bright(ansi_cmdname);
            ansi_cmdname.append(cmdname);
            ansi_off(ansi_cmdname);
            ansi_green(ansi_cmdname);
            ansi_cmdname.append(":");
            ansi_off(ansi_cmdname);
            size_t cmd_length = strlen(cmdname.c_str());
            size_t ansi_code_length = strlen(ansi_cmdname.c_str()) - cmd_length;
            oss << "  " << std::setw(maxl+ansi_code_length+2) << std::left << ansi_cmdname
                << _cogserver.requestInfo(*it).description << std::endl;
        }
    } else if (args.size() == 1) {
        const RequestClassInfo& cci = _cogserver.requestInfo(args.front());
        if (cci.help != "")
            oss << cci.help << std::endl;
    } else {
        oss << do_helpRequest::info().help << std::endl;
    }

    return oss.str();
}

std::string BuiltinRequestsModule::do_h(Request *req, std::list<std::string> args)
{
    return do_help(req, args);
}

// ====================================================================
// Various agents commands
std::string BuiltinRequestsModule::do_startAgents(Request *dummy, std::list<std::string> args)
{
    std::list<const char*> availableAgents = _cogserver.agentIds();

    std::vector<std::string> agents;

    if (args.size() == 0)
        return "Error: No agents to start specified\n";

    for (std::list<std::string>::const_iterator it = args.begin();
         it != args.end(); ++it) {
        std::string agent_type = *it;
        // check that this is a valid type; give an error and return otherwise
        if (availableAgents.end() ==
         find(availableAgents.begin(), availableAgents.end(), *it)) {
            std::ostringstream oss;
            oss << "Invalid Agent ID \"" << *it << "\"\n";
            return oss.str();
        }

        agents.push_back(agent_type);
     }

    for (std::vector<std::string>::const_iterator it = agents.begin();
         it != agents.end(); ++it) {
        _cogserver.createAgent(*it, true);
    }

    return "Successfully started agents\n";
}

std::string BuiltinRequestsModule::do_stopAgents(Request *dummy, std::list<std::string> args)
{
    std::list<const char*> availableAgents = _cogserver.agentIds();

    std::vector<std::string> agents;

    if (args.size() == 0)
        return "Error: No agents to stop specified\n";

    for (std::list<std::string>::const_iterator it = args.begin();
         it != args.end(); ++it) {
        std::string agent_type = *it;
        // check that this is a valid type; give an error and return otherwise
        if (availableAgents.end() ==
         find(availableAgents.begin(), availableAgents.end(), *it)) {
            std::ostringstream oss;
            oss << "Invalid Agent ID \"" << *it << "\"\n";
            return oss.str();
        }

        agents.push_back(agent_type);
    }
    // doesn't give an error if there is no instance of that agent type running

    for (std::vector<std::string>::const_iterator it = agents.begin();
         it != agents.end(); ++it) {
        // Check if this Agent instance is also a module
        if (_cogserver.getModule(*it) != NULL) {
            // delete the Agent instance if it is not
            _cogserver.destroyAllAgents(*it);
        }
    }

    return "Successfully stopped agents\n";
}

std::string BuiltinRequestsModule::do_stepAgents(Request *dummy, std::list<std::string> args)
{
    AgentSeq agents = _cogserver.runningAgents();

    if (args.size() == 0) {
        for (AgentSeq::const_iterator it = agents.begin();
             it != agents.end(); ++it) {
            (*it)->run();
        }
        return "Ran a step of each active agent\n";
    } else {
        std::list<std::string> unknownAgents;
        int numberAgentsRun = 0;
        for (std::list<std::string>::const_iterator it = args.begin();
             it != args.end(); ++it) {

            std::string agent_type = *it;

            // try to find an already started agent with that name
            AgentSeq::const_iterator tmp = agents.begin();
            for ( ; tmp != agents.end() ; tmp++ ) if ( *it == (*tmp)->classinfo().id ) break;

            AgentPtr agent;
            if (agents.end() == tmp) {
                // construct a temporary agent
                agent = AgentPtr(_cogserver.createAgent(*it, false));
                if (agent) {
                    agent->run();
                    _cogserver.destroyAgent(agent);
                    numberAgentsRun++;
                } else {
                    unknownAgents.push_back(*it);
                }
            } else {
                agent = *tmp;
                agent->run();
            }
        }
        std::stringstream returnMsg;
        for (std::list<std::string>::iterator it = unknownAgents.begin();
                it != unknownAgents.end(); ++it) {
            returnMsg << "Unknown agent \"" << *it << "\"" << std::endl;
        }
        returnMsg << "Successfully ran a step of " << numberAgentsRun <<
            "/" << args.size() << " agents." << std::endl;
        return returnMsg.str();
    }
}

std::string BuiltinRequestsModule::do_stopAgentLoop(Request *dummy, std::list<std::string> args)
{
    _cogserver.stopAgentLoop();

    return "Stopped agent loop\n";
}

std::string BuiltinRequestsModule::do_startAgentLoop(Request *dummy, std::list<std::string> args)
{
    _cogserver.startAgentLoop();

    return "Started agent loop\n";
}

std::string BuiltinRequestsModule::do_listAgents(Request *dummy, std::list<std::string> args)
{
    std::list<const char*> agentNames = _cogserver.agentIds();
    std::ostringstream oss;

    for (std::list<const char*>::const_iterator it = agentNames.begin();
         it != agentNames.end(); ++it) {
        oss << (*it) << std::endl;
    }

    return oss.str();
}

std::string BuiltinRequestsModule::do_activeAgents(Request *dummy, std::list<std::string> args)
{
    AgentSeq agents = _cogserver.runningAgents();
    std::ostringstream oss;

    for (AgentSeq::const_iterator it = agents.begin();
         it != agents.end(); ++it) {
        oss << (*it)->to_string() << std::endl;
    }

    return oss.str();
}
<|endoftext|>


<commit_before>/*
 * opencog/server/BuiltinRequestsModule.cc
 *
 * Copyright (C) 2008 by Singularity Institute for Artificial Intelligence
 * All Rights Reserved
 *
 * Written by Gustavo Gama <gama@vettalabs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "BuiltinRequestsModule.h"

#include <opencog/server/CogServer.h>

using namespace opencog;

// load/unload functions for the Module interface
extern "C" const char* opencog_module_id()                   { return BuiltinRequestsModule::id(); }
extern "C" Module*     opencog_module_load()                 { return new BuiltinRequestsModule(); }
extern "C" void        opencog_module_unload(Module* module) { delete module; }

BuiltinRequestsModule::BuiltinRequestsModule()
{
    CogServer& cogserver = static_cast<CogServer&>(server());
    cogserver.registerRequest(ListRequest::info().id,         &listFactory);
    cogserver.registerRequest(LoadRequest::info().id,         &loadFactory);
    cogserver.registerRequest(SaveRequest::info().id,         &saveFactory);
    cogserver.registerRequest(DataRequest::info().id,         &dataFactory);
    cogserver.registerRequest(HelpRequest::info().id,         &helpFactory);
    cogserver.registerRequest(ExitRequest::info().id,         &exitFactory);
    cogserver.registerRequest(SleepRequest::info().id,        &sleepFactory);
    cogserver.registerRequest(ShutdownRequest::info().id,     &shutdownFactory);
    cogserver.registerRequest(LoadModuleRequest::info().id,   &loadmoduleFactory);
    cogserver.registerRequest(UnloadModuleRequest::info().id, &unloadmoduleFactory);
    registerAgentRequests();
}

BuiltinRequestsModule::~BuiltinRequestsModule()
{
    CogServer& cogserver = static_cast<CogServer&>(server());
    cogserver.unregisterRequest(ListRequest::info().id);
    cogserver.unregisterRequest(LoadRequest::info().id);
    cogserver.unregisterRequest(SaveRequest::info().id);
    cogserver.unregisterRequest(DataRequest::info().id);
    cogserver.unregisterRequest(HelpRequest::info().id);
    cogserver.unregisterRequest(ExitRequest::info().id);
    cogserver.unregisterRequest(SleepRequest::info().id);
    cogserver.unregisterRequest(ShutdownRequest::info().id);
    cogserver.unregisterRequest(LoadModuleRequest::info().id);
    cogserver.unregisterRequest(UnloadModuleRequest::info().id);
    unregisterAgentRequests();
}

void BuiltinRequestsModule::registerAgentRequests()
{
    do_startAgents_register();
    do_stopAgents_register();
    do_stepAgents_register();
    do_startAgentLoop_register();
    do_stopAgentLoop_register();
    do_listAgents_register();
    do_activeAgents_register();
}

void BuiltinRequestsModule::unregisterAgentRequests()
{
    do_startAgents_unregister();
    do_stopAgents_unregister();
    do_stepAgents_unregister();
    do_startAgentLoop_unregister();
    do_stopAgentLoop_unregister();
    do_listAgents_unregister();
    do_activeAgents_unregister();
}

void BuiltinRequestsModule::init()
{
}

std::string BuiltinRequestsModule::do_startAgents(Request *dummy, std::list<std::string> args)
{
    std::list<const char*> availableAgents = cogserver().agentIds();

    std::vector<std::string> agents;

    if (agents.size() == 0)
        return "Error: No agents to stop specified";

    for (std::list<std::string>::const_iterator it = args.begin();
         it != args.end(); ++it) {
        std::string agent_type = *it;
        // check that this is a valid type; give an error and return otherwise
        if (availableAgents.end() ==
         find(availableAgents.begin(), availableAgents.end(), *it)) {
            std::ostringstream oss;
            oss << "Invalid Agent ID (" << *it << ")";
            return oss.str();
        }

        agents.push_back(agent_type);
     }

    for (std::vector<std::string>::const_iterator it = agents.begin();
         it != agents.end(); ++it) {
        cogserver().createAgent(*it, true);
    }

    return "Successfully started agents";
}

std::string BuiltinRequestsModule::do_stopAgents(Request *dummy, std::list<std::string> args)
{
    std::list<const char*> availableAgents = cogserver().agentIds();

    std::vector<std::string> agents;

    if (agents.size() == 0)
        return "Error: No agents to stop specified";

    for (std::list<std::string>::const_iterator it = args.begin();
         it != args.end(); ++it) {
        std::string agent_type = *it;
        // check that this is a valid type; give an error and return otherwise
        if (availableAgents.end() ==
         find(availableAgents.begin(), availableAgents.end(), *it)) {
            std::ostringstream oss;
            oss << "Invalid Agent ID (" << *it << ")";
            return oss.str();
        }

        agents.push_back(agent_type);
    }
    // doesn't give an error if there is no instance of that agent type running

    for (std::vector<std::string>::const_iterator it = agents.begin();
         it != agents.end(); ++it) {
        // Check if this Agent instance is also a module
        if (cogserver().getModule(*it) != NULL) {
            // delete the Agent instance if it is not
            cogserver().destroyAllAgents(*it);
        }
    }

    return "Successfully stopped agents";
}

std::string BuiltinRequestsModule::do_stepAgents(Request *dummy, std::list<std::string> args)
{
    std::vector<Agent*> agents = cogserver().runningAgents();

    if (args.size() == 0) {
        for (std::vector<Agent*>::const_iterator it = agents.begin();
             it != agents.end(); ++it) {
            (*it)->run(&cogserver());
        }
        return "Ran a step of each active agent";
    } else {
        std::list<std::string> unknownAgents;
        int numberAgentsRun = 0;
        for (std::list<std::string>::const_iterator it = args.begin();
             it != args.end(); ++it) {

            std::string agent_type = *it;

            // try to find an already started agent with that name
            std::vector<Agent*>::const_iterator tmp = agents.begin();
            for ( ; tmp!=agents.end() ; tmp++ ) if ( *it == (*tmp)->classinfo().id ) break;

            Agent* agent;
            if (agents.end() == tmp) {
                // construct a temporary agent
                agent = cogserver().createAgent(*it, false);
                if (agent) {
                    agent->run(&cogserver());
                    cogserver().destroyAgent(agent);
                    numberAgentsRun++;
                } else {
                    unknownAgents.push_back(*it);
                }
            } else {
                agent = *tmp;
                agent->run(&cogserver());
            }
        }
        std::stringstream returnMsg;
        for (std::list<std::string>::iterator it = unknownAgents.begin();
                it != unknownAgents.end(); ++it) {
            returnMsg << "Unknown agent " << *it << std::endl;
        }
        returnMsg << "Successfully ran a step of " << numberAgentsRun <<
            "/" << args.size() << " agents." << std::endl;
        return returnMsg.str();
    }
}

std::string BuiltinRequestsModule::do_stopAgentLoop(Request *dummy, std::list<std::string> args)
{
    cogserver().stopAgentLoop();

    return "Stopped agent loop";
}

std::string BuiltinRequestsModule::do_startAgentLoop(Request *dummy, std::list<std::string> args)
{
    cogserver().startAgentLoop();

    return "Started agent loop";
}

std::string BuiltinRequestsModule::do_listAgents(Request *dummy, std::list<std::string> args)
{
    std::list<const char*> agentNames = cogserver().agentIds();
    std::ostringstream oss;

    for (std::list<const char*>::const_iterator it = agentNames.begin();
         it != agentNames.end(); ++it) {
        oss << (*it) << std::endl;
    }

    return oss.str();
}

std::string BuiltinRequestsModule::do_activeAgents(Request *dummy, std::list<std::string> args)
{
    std::vector<Agent*> agents = cogserver().runningAgents();
    std::ostringstream oss;

    for (std::vector<Agent*>::const_iterator it = agents.begin();
         it != agents.end(); ++it) {
        oss << (*it)->to_string() << std::endl;
    }

    return oss.str();
}
<commit_msg>Fix agents-start and agents-stop<commit_after>/*
 * opencog/server/BuiltinRequestsModule.cc
 *
 * Copyright (C) 2008 by Singularity Institute for Artificial Intelligence
 * All Rights Reserved
 *
 * Written by Gustavo Gama <gama@vettalabs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "BuiltinRequestsModule.h"

#include <opencog/server/CogServer.h>

using namespace opencog;

// load/unload functions for the Module interface
extern "C" const char* opencog_module_id()                   { return BuiltinRequestsModule::id(); }
extern "C" Module*     opencog_module_load()                 { return new BuiltinRequestsModule(); }
extern "C" void        opencog_module_unload(Module* module) { delete module; }

BuiltinRequestsModule::BuiltinRequestsModule()
{
    CogServer& cogserver = static_cast<CogServer&>(server());
    cogserver.registerRequest(ListRequest::info().id,         &listFactory);
    cogserver.registerRequest(LoadRequest::info().id,         &loadFactory);
    cogserver.registerRequest(SaveRequest::info().id,         &saveFactory);
    cogserver.registerRequest(DataRequest::info().id,         &dataFactory);
    cogserver.registerRequest(HelpRequest::info().id,         &helpFactory);
    cogserver.registerRequest(ExitRequest::info().id,         &exitFactory);
    cogserver.registerRequest(SleepRequest::info().id,        &sleepFactory);
    cogserver.registerRequest(ShutdownRequest::info().id,     &shutdownFactory);
    cogserver.registerRequest(LoadModuleRequest::info().id,   &loadmoduleFactory);
    cogserver.registerRequest(UnloadModuleRequest::info().id, &unloadmoduleFactory);
    registerAgentRequests();
}

BuiltinRequestsModule::~BuiltinRequestsModule()
{
    CogServer& cogserver = static_cast<CogServer&>(server());
    cogserver.unregisterRequest(ListRequest::info().id);
    cogserver.unregisterRequest(LoadRequest::info().id);
    cogserver.unregisterRequest(SaveRequest::info().id);
    cogserver.unregisterRequest(DataRequest::info().id);
    cogserver.unregisterRequest(HelpRequest::info().id);
    cogserver.unregisterRequest(ExitRequest::info().id);
    cogserver.unregisterRequest(SleepRequest::info().id);
    cogserver.unregisterRequest(ShutdownRequest::info().id);
    cogserver.unregisterRequest(LoadModuleRequest::info().id);
    cogserver.unregisterRequest(UnloadModuleRequest::info().id);
    unregisterAgentRequests();
}

void BuiltinRequestsModule::registerAgentRequests()
{
    do_startAgents_register();
    do_stopAgents_register();
    do_stepAgents_register();
    do_startAgentLoop_register();
    do_stopAgentLoop_register();
    do_listAgents_register();
    do_activeAgents_register();
}

void BuiltinRequestsModule::unregisterAgentRequests()
{
    do_startAgents_unregister();
    do_stopAgents_unregister();
    do_stepAgents_unregister();
    do_startAgentLoop_unregister();
    do_stopAgentLoop_unregister();
    do_listAgents_unregister();
    do_activeAgents_unregister();
}

void BuiltinRequestsModule::init()
{
}

std::string BuiltinRequestsModule::do_startAgents(Request *dummy, std::list<std::string> args)
{
    std::list<const char*> availableAgents = cogserver().agentIds();

    std::vector<std::string> agents;

    if (args.size() == 0)
        return "Error: No agents to start specified";

    for (std::list<std::string>::const_iterator it = args.begin();
         it != args.end(); ++it) {
        std::string agent_type = *it;
        // check that this is a valid type; give an error and return otherwise
        if (availableAgents.end() ==
         find(availableAgents.begin(), availableAgents.end(), *it)) {
            std::ostringstream oss;
            oss << "Invalid Agent ID (" << *it << ")";
            return oss.str();
        }

        agents.push_back(agent_type);
     }

    for (std::vector<std::string>::const_iterator it = agents.begin();
         it != agents.end(); ++it) {
        cogserver().createAgent(*it, true);
    }

    return "Successfully started agents";
}

std::string BuiltinRequestsModule::do_stopAgents(Request *dummy, std::list<std::string> args)
{
    std::list<const char*> availableAgents = cogserver().agentIds();

    std::vector<std::string> agents;

    if (args.size() == 0)
        return "Error: No agents to stop specified";

    for (std::list<std::string>::const_iterator it = args.begin();
         it != args.end(); ++it) {
        std::string agent_type = *it;
        // check that this is a valid type; give an error and return otherwise
        if (availableAgents.end() ==
         find(availableAgents.begin(), availableAgents.end(), *it)) {
            std::ostringstream oss;
            oss << "Invalid Agent ID (" << *it << ")";
            return oss.str();
        }

        agents.push_back(agent_type);
    }
    // doesn't give an error if there is no instance of that agent type running

    for (std::vector<std::string>::const_iterator it = agents.begin();
         it != agents.end(); ++it) {
        // Check if this Agent instance is also a module
        if (cogserver().getModule(*it) != NULL) {
            // delete the Agent instance if it is not
            cogserver().destroyAllAgents(*it);
        }
    }

    return "Successfully stopped agents";
}

std::string BuiltinRequestsModule::do_stepAgents(Request *dummy, std::list<std::string> args)
{
    std::vector<Agent*> agents = cogserver().runningAgents();

    if (args.size() == 0) {
        for (std::vector<Agent*>::const_iterator it = agents.begin();
             it != agents.end(); ++it) {
            (*it)->run(&cogserver());
        }
        return "Ran a step of each active agent";
    } else {
        std::list<std::string> unknownAgents;
        int numberAgentsRun = 0;
        for (std::list<std::string>::const_iterator it = args.begin();
             it != args.end(); ++it) {

            std::string agent_type = *it;

            // try to find an already started agent with that name
            std::vector<Agent*>::const_iterator tmp = agents.begin();
            for ( ; tmp!=agents.end() ; tmp++ ) if ( *it == (*tmp)->classinfo().id ) break;

            Agent* agent;
            if (agents.end() == tmp) {
                // construct a temporary agent
                agent = cogserver().createAgent(*it, false);
                if (agent) {
                    agent->run(&cogserver());
                    cogserver().destroyAgent(agent);
                    numberAgentsRun++;
                } else {
                    unknownAgents.push_back(*it);
                }
            } else {
                agent = *tmp;
                agent->run(&cogserver());
            }
        }
        std::stringstream returnMsg;
        for (std::list<std::string>::iterator it = unknownAgents.begin();
                it != unknownAgents.end(); ++it) {
            returnMsg << "Unknown agent " << *it << std::endl;
        }
        returnMsg << "Successfully ran a step of " << numberAgentsRun <<
            "/" << args.size() << " agents." << std::endl;
        return returnMsg.str();
    }
}

std::string BuiltinRequestsModule::do_stopAgentLoop(Request *dummy, std::list<std::string> args)
{
    cogserver().stopAgentLoop();

    return "Stopped agent loop";
}

std::string BuiltinRequestsModule::do_startAgentLoop(Request *dummy, std::list<std::string> args)
{
    cogserver().startAgentLoop();

    return "Started agent loop";
}

std::string BuiltinRequestsModule::do_listAgents(Request *dummy, std::list<std::string> args)
{
    std::list<const char*> agentNames = cogserver().agentIds();
    std::ostringstream oss;

    for (std::list<const char*>::const_iterator it = agentNames.begin();
         it != agentNames.end(); ++it) {
        oss << (*it) << std::endl;
    }

    return oss.str();
}

std::string BuiltinRequestsModule::do_activeAgents(Request *dummy, std::list<std::string> args)
{
    std::vector<Agent*> agents = cogserver().runningAgents();
    std::ostringstream oss;

    for (std::vector<Agent*>::const_iterator it = agents.begin();
         it != agents.end(); ++it) {
        oss << (*it)->to_string() << std::endl;
    }

    return oss.str();
}
<|endoftext|>


<commit_before>#include <extlib/toml/toml.hpp>
#include <jarngreipr/io/PDBReader.hpp>
#include <jarngreipr/io/PDBWriter.hpp>
#include <jarngreipr/io/write_as_xyz.hpp>
#include <jarngreipr/io/write_as_xyz.hpp>
#include <jarngreipr/model/CGChain.hpp>
#include <jarngreipr/model/make_coarse_grained.hpp>
#include <jarngreipr/forcefield/ForceFieldGenerator.hpp>
#include <jarngreipr/forcefield/ClementiGo.hpp>
#include <mjolnir/math/Vector.hpp>
#include <mjolnir/core/RandomNumberGenerator.hpp>
#include <algorithm>
#include <map>

using mjolnir::operator"" _str;

namespace mjolnir
{

std::vector<char> split_chain_ids(const std::string& key)
{
    if(key.size() == 1)
    {
        if(not std::isupper(key.front()))
        {
            throw std::runtime_error("jarngreipr::split_chain_ids: "
                    "chain ID should be specified in upper case.");
        }
        return std::vector<char>{key.front()};
    }

    if(not (key.size() == 3 && (key.at(1) == '-' || key.at(1) == '&') &&
            std::isupper(key.front()) && std::isupper(key.back())))
    {
        throw std::runtime_error("jarngreipr::split_chain_ids: "
                "chain ID must be upper case and supplied in this way: "
                "'A', 'A-C', or 'A&D'");
    }

    if(key.at(1) == '&')
    {
        // "A&D" -> {A, D}
        return std::vector<char>{key.front(), key.back()};
    }

    // "A-D" -> {A, B, C, D}
    std::vector<char> ids;
    for(char c = key.front(); c <= key.back(); ++c)
    {
        ids.push_back(c);
    }
    return ids;
}

template<typename coordT>
std::vector<std::map<char, PDBChain<coordT>>>
read_reference_structures(const std::vector<toml::Table>& structures)
{
    std::vector<std::map<char, PDBChain<coordT>>> tables;
    for(const auto& conf : structures)
    {
        std::map<char, PDBChain<coordT>> table;
        for(const auto& kvp : conf)
        {
            std::vector<char> chIDs = split_chain_ids(kvp.first);
            const toml::Table val = toml::get<toml::Table>(kvp.second);

            std::string filename;
            try
            {
                filename = toml::get<std::string>(val.at("file"));
            }
            catch(const std::exception& except)
            {
                throw std::runtime_error("jarngreipr::read_reference_structures: "
                        "file is not specified for chain " + kvp.first);
            }

            if(filename.substr(filename.size() - 4) == ".pdb")
            {
                mjolnir::PDBReader<coordT> pdb_reader(filename);
                if(not pdb_reader.is_good())
                {
                    throw std::runtime_error(
                            "jarngreipr::read_reference_structures: "
                            "file open error: filename = " + filename);
                }
                while(not pdb_reader.is_eof())
                {
                    const auto chain = pdb_reader.read_next_chain();
                    const char chain_id = chain.chain_id();
                    const auto found = std::find(
                            chIDs.begin(), chIDs.end(), chain_id);
                    if(found != chIDs.end())
                    {
                        table[*found] = chain;
                        chIDs.erase(found);
                    }
                }
            }
            else
            {
                throw std::runtime_error("jarngreipr::read_reference_structures: "
                        "unrecognizable file: " + filename);
            }

            if(not chIDs.empty())
            {
                std::string mes("jarngreipr::read_reference_structures: "
                                "missing chains in : ");
                mes += filename;
                mes += ", ID = ";
                mes += std::string(chIDs.begin(), chIDs.end());
                throw std::runtime_error(mes);
            }
        }
        tables.push_back(std::move(table));
    }
    return tables;
}

template<typename coordT>
std::vector<std::map<char, PDBChain<coordT>>>
read_initial_structures(const std::vector<toml::Table>& structures)
{
    std::vector<std::map<char, PDBChain<coordT>>> tables;
    for(const auto& conf : structures)
    {
        std::map<char, PDBChain<coordT>> table;
        for(const auto& kvp : conf)
        {
            std::vector<char> chIDs = split_chain_ids(kvp.first);
            const toml::Table val = toml::get<toml::Table>(kvp.second);

            std::string filename;
            try
            {
                filename = toml::get<std::string>(val.at("initial"));
            }
            catch(const std::exception& except)
            {
                // do nothing. initial configuration is optional.
            }
            try
            {
                filename = toml::get<std::string>(val.at("file"));
            }
            catch(const std::exception& except)
            {
                throw std::runtime_error("jarngreipr::read_initial_structures: "
                        "neither file nor initial exists for chain " + kvp.first);
            }

            if(filename.substr(filename.size() - 4) == ".pdb")
            {
                mjolnir::PDBReader<coordT> pdb_reader(filename);
                if(not pdb_reader.is_good())
                {
                    throw std::runtime_error(
                            "jarngreipr::read_reference_structures: "
                            "file open error: " + filename);
                }
                while(not pdb_reader.is_eof())
                {
                    const auto chain = pdb_reader.read_next_chain();
                    const char chain_id = chain.chain_id();
                    const auto found = std::find(
                            chIDs.begin(), chIDs.end(), chain_id);
                    if(found != chIDs.end())
                    {
                        table[*found] = chain;
                        chIDs.erase(found);
                    }
                }
            }
            else
            {
                throw std::runtime_error("jarngreipr::read_reference_structures: "
                        "unrecognizable file: " + filename);
            }

            if(not chIDs.empty())
            {
                std::string mes("jarngreipr::read_reference_structures: "
                                "missing chains in : ");
                mes += filename;
                mes += ", ID = ";
                mes += std::string(chIDs.begin(), chIDs.end());
                throw std::runtime_error(mes);
            }
        }

        tables.push_back(std::move(table));
    }
    return tables;
}

inline std::vector<std::map<char, std::string>>
read_coarse_grained_models(const std::vector<toml::Table>& structures)
{
    std::vector<std::map<char, std::string>> tables;
    for(const auto& conf : structures)
    {
        std::map<char, std::string> table;
        for(const auto& kvp : conf)
        {
            const std::vector<char> chIDs = split_chain_ids(kvp.first);
            const toml::Table val = toml::get<toml::Table>(kvp.second);

            std::string model_name;
            try
            {
                model_name = toml::get<std::string>(val.at("model"));
            }
            catch(const std::exception& except)
            {
                throw std::runtime_error("jarngreipr::read_coarse_grained model: "
                        "model is not specified for chain " + kvp.first);
            }

            for(char id : chIDs)
            {
                table[id] = model_name;
            }
        }
        tables.push_back(std::move(table));
    }
    return tables;
}

template<typename coordT>
std::vector<std::map<char, CGChain<coordT>>>
apply_coarse_grained_models(
        const std::vector<std::map<char, PDBChain<coordT>>>& pdbs,
        const std::vector<std::map<char, std::string>>& models)
{
    assert(pdbs.size() == models.size());
    std::vector<std::map<char, CGChain<coordT>>> cgss;
    for(std::size_t i=0; i<pdbs.size(); ++i)
    {
        std::map<char, CGChain<coordT>> cgs;
        const auto& pdb   = pdbs.at(i);
        const auto& model = models.at(i);

        for(const auto& kv : pdb)
        {
            const auto chid = kv.first;
            const auto&  ch = kv.second;
            cgs[chid] = make_coarse_grained(ch, model.at(chid));
        }

        std::size_t index = 0;
        for(auto& id_chain: cgs)
        {
            for(auto& bead : id_chain.second)
            {
                bead->index() = index;
                ++index;
            }
        }

        cgss.push_back(std::move(cgs));
    }
    return cgss;
}

} // mjolnir

int main(int argc, char **argv)
{
    typedef mjolnir::Vector<double, 3>    coord_type;
    typedef mjolnir::PDBChain<coord_type> pdb_chain_type;
    typedef mjolnir::CGChain<coord_type>  cg_chain_type;

    if(argc != 2)
    {
        std::cerr << "Usage: $ jarngreipr [file.toml]\n";
        std::cerr << "    see input/example.toml for the format" << std::endl;
        return 1;
    }

    const auto input_data = toml::parse(std::string(argv[1]));

    /* prepairing parameters */
    const auto general   = toml::get<toml::Table>(input_data.at("general"));
    const auto file_name = toml::get<std::string>(general.at("file_prefix"));
    std::random_device devrand;
    std::mt19937 mt(devrand());

    /* output general information */{
        std::cout << "[general]\n";
        std::cout << "file_name   = "
                  << toml::get_or(general, "file_prefix", "data"_str) << '\n';
        std::cout << "output_path = "
                  << toml::get_or(general, "output_path", "./"_str) << '\n';
        std::cout << "precision = "
                  << toml::get_or(general, "precision", "double"_str) << '\n';
        std::cout << "boundary  = "
                  << toml::get_or(general, "boundary", "Unlimited"_str) << '\n';
        std::cout << "thread    = " << std::boolalpha
                  << toml::get_or(general, "thread", false) << '\n';
        std::cout << "GPU       = " << std::boolalpha
                  << toml::get_or(general, "GPU",    false) << '\n';
        const std::int64_t default_seed = devrand();
        std::cout << "seed      = "
                  << toml::get_or(general, "seed", default_seed) << '\n';
    }

    const auto parameters =
        toml::parse(toml::get<std::string>(general.at("parameters")));
    const auto phys_paras = toml::get<toml::Table>(parameters.at("physical_constants"));
    const auto vac_permit = toml::get<double>(phys_paras.at("ε0"));

    const auto& mass =
        toml::get<toml::Table>(parameters.at("mass"));
    const auto& phys =
        toml::get<toml::Table>(parameters.at("physical_constants"));

    const auto system_config =
        toml::get<std::vector<toml::Table>>(input_data.at("systems"));

    /* generating coarse-grained structures */
    const auto structure_config =
            toml::get<std::vector<toml::Table>>(input_data.at("structures"));

    // vector<map<char, PDBChain<coord>>>
    // in most cases, the size of vector is one.
    const auto ref_pdbs =
        mjolnir::read_reference_structures<coord_type>(structure_config);
    const auto ini_pdbs =
        mjolnir::read_initial_structures  <coord_type>(structure_config);
    const auto models   =
        mjolnir::read_coarse_grained_models(structure_config);

    // apply coarse-grained model to input pdbs
    const auto ref_cgss = mjolnir::apply_coarse_grained_models(ref_pdbs, models);
    const auto ini_cgss = mjolnir::apply_coarse_grained_models(ini_pdbs, models);

    // output system setting and cg structure
    assert(system_config.size() == ini_cgss.size());
    for(std::size_t i=0; i<system_config.size(); ++i)
    {
        std::cout << "[[systems]]\n";
        // TODO {{{
        const auto& sysconf = system_config.at(i);
        const auto T = toml::get<double>(sysconf.at("temperature"));
        std::cout << "temperature    = " << std::fixed << T << '\n';
        std::cout << "ionic_strength = " << std::fixed
                  << toml::get<double>(sysconf.at("ionic_strength")) << '\n';
        std::cout << "boundary = {";
        for(const auto& kv : toml::get<toml::Table>(sysconf.at("boundary")))
        {
            if(kv.first == "type")
            {
                std::cout << kv.first << "=\"" << toml::get<std::string>(kv.second) << '\"';
            }
            else
            {
                const auto& crd = toml::get<std::array<double, 3>>(kv.second);
                std::cout << kv.first << "=[" << crd[0] << ',' << crd[1] << ','
                          << crd[2] << ']';
            }
        }
        std::cout << "}\n";
        // }}}

        std::cout << "particles = [\n";
        const auto& chain_table = ini_cgss.at(i);
        for(const auto& id_chain_pair : chain_table)
        {
            std::cerr << "chain ID = " << id_chain_pair.first;
            std::cerr << " has " << id_chain_pair.second.size() << " beads." << std::endl;
            for(std::size_t j=0; j<id_chain_pair.second.size(); ++j)
            {
                const auto& bead = id_chain_pair.second.at(j);
                const auto kB = toml::get<double>(phys.at("kB"));
                const auto m  = toml::get<double>(mass.at(bead->name()));
                const auto p  = bead->position();
                std::normal_distribution<double> mxw_blz(0.0, std::sqrt(kB*T/m));
                std::cout << "{mass = " << m
                          <<  ", position = [" << p[0] << ',' << p[1] << ',' << p[2]
                          << "], velocity = [" << mxw_blz(mt) << ','
                          << mxw_blz(mt) << ',' << mxw_blz(mt) << "]},\n";
            }
        }
        std::cout << "]\n";
    }

    const std::unique_ptr<mjolnir::IntraChainForceFieldGenerator<coord_type>>
        ffgen = mjolnir::make_unique<mjolnir::ClementiGo<coord_type>>();

    for(const auto& chains : ref_cgss)
    {
        std::cout << "[[forcefields]]\n";
        for(const auto& idch : chains)
        {
            const auto& ch = idch.second;
            const auto connect = ffgen->generate(std::cout, ch);
        }
    }

    // output parameter

    return 0;
}
<commit_msg>use value_or(toml, key, position)<commit_after>#include <extlib/toml/toml.hpp>
#include <jarngreipr/io/PDBReader.hpp>
#include <jarngreipr/io/PDBWriter.hpp>
#include <jarngreipr/io/write_as_xyz.hpp>
#include <jarngreipr/io/write_as_xyz.hpp>
#include <jarngreipr/model/CGChain.hpp>
#include <jarngreipr/model/make_coarse_grained.hpp>
#include <jarngreipr/forcefield/ForceFieldGenerator.hpp>
#include <jarngreipr/forcefield/ClementiGo.hpp>
#include <mjolnir/math/Vector.hpp>
#include <mjolnir/core/RandomNumberGenerator.hpp>
#include <mjolnir/input/get_toml_value.hpp>
#include <algorithm>
#include <map>

using mjolnir::operator"" _str;

namespace mjolnir
{

std::vector<char> split_chain_ids(const std::string& key)
{
    if(key.size() == 1)
    {
        if(not std::isupper(key.front()))
        {
            throw std::runtime_error("jarngreipr::split_chain_ids: "
                    "chain ID should be specified in upper case.");
        }
        return std::vector<char>{key.front()};
    }

    if(not (key.size() == 3 && (key.at(1) == '-' || key.at(1) == '&') &&
            std::isupper(key.front()) && std::isupper(key.back())))
    {
        throw std::runtime_error("jarngreipr::split_chain_ids: "
                "chain ID must be upper case and supplied in this way: "
                "'A', 'A-C', or 'A&D'");
    }

    if(key.at(1) == '&')
    {
        // "A&D" -> {A, D}
        return std::vector<char>{key.front(), key.back()};
    }

    // "A-D" -> {A, B, C, D}
    std::vector<char> ids;
    for(char c = key.front(); c <= key.back(); ++c)
    {
        ids.push_back(c);
    }
    return ids;
}

template<typename coordT>
std::vector<std::map<char, PDBChain<coordT>>>
read_reference_structures(const std::vector<toml::Table>& structures)
{
    std::vector<std::map<char, PDBChain<coordT>>> tables;
    for(const auto& conf : structures)
    {
        std::map<char, PDBChain<coordT>> table;
        for(const auto& kvp : conf)
        {
            std::vector<char> chIDs = split_chain_ids(kvp.first);
            const toml::Table val = toml::get<toml::Table>(kvp.second);

            std::string filename;
            try
            {
                filename = toml::get<std::string>(val.at("file"));
            }
            catch(const std::exception& except)
            {
                throw std::runtime_error("jarngreipr::read_reference_structures: "
                        "file is not specified for chain " + kvp.first);
            }

            if(filename.substr(filename.size() - 4) == ".pdb")
            {
                mjolnir::PDBReader<coordT> pdb_reader(filename);
                if(not pdb_reader.is_good())
                {
                    throw std::runtime_error(
                            "jarngreipr::read_reference_structures: "
                            "file open error: filename = " + filename);
                }
                while(not pdb_reader.is_eof())
                {
                    const auto chain = pdb_reader.read_next_chain();
                    const char chain_id = chain.chain_id();
                    const auto found = std::find(
                            chIDs.begin(), chIDs.end(), chain_id);
                    if(found != chIDs.end())
                    {
                        table[*found] = chain;
                        chIDs.erase(found);
                    }
                }
            }
            else
            {
                throw std::runtime_error("jarngreipr::read_reference_structures: "
                        "unrecognizable file: " + filename);
            }

            if(not chIDs.empty())
            {
                std::string mes("jarngreipr::read_reference_structures: "
                                "missing chains in : ");
                mes += filename;
                mes += ", ID = ";
                mes += std::string(chIDs.begin(), chIDs.end());
                throw std::runtime_error(mes);
            }
        }
        tables.push_back(std::move(table));
    }
    return tables;
}

template<typename coordT>
std::vector<std::map<char, PDBChain<coordT>>>
read_initial_structures(const std::vector<toml::Table>& structures)
{
    std::vector<std::map<char, PDBChain<coordT>>> tables;
    for(const auto& conf : structures)
    {
        std::map<char, PDBChain<coordT>> table;
        for(const auto& kvp : conf)
        {
            std::vector<char> chIDs = split_chain_ids(kvp.first);
            const toml::Table val = toml::get<toml::Table>(kvp.second);

            std::string filename;
            try
            {
                filename = toml::get<std::string>(
                        detail::value_at(val, "initial", "[[structures]]"));
            }
            catch(const std::exception& except)
            {
                // if no initial configuration is specified, start from
                // the reference structure.
                filename = toml::get<std::string>(
                        detail::value_at(val, "file", "[[structures]]"));
            }

            if(filename.substr(filename.size() - 4) == ".pdb")
            {
                mjolnir::PDBReader<coordT> pdb_reader(filename);
                if(not pdb_reader.is_good())
                {
                    throw std::runtime_error(
                            "jarngreipr::read_reference_structures: "
                            "file open error: " + filename);
                }
                while(not pdb_reader.is_eof())
                {
                    const auto chain = pdb_reader.read_next_chain();
                    const char chain_id = chain.chain_id();
                    const auto found = std::find(
                            chIDs.begin(), chIDs.end(), chain_id);
                    if(found != chIDs.end())
                    {
                        table[*found] = chain;
                        chIDs.erase(found);
                    }
                }
            }
            else
            {
                throw std::runtime_error("jarngreipr::read_reference_structures: "
                        "unrecognizable file: " + filename);
            }

            if(not chIDs.empty())
            {
                std::string mes("jarngreipr::read_reference_structures: "
                                "missing chains in : ");
                mes += filename;
                mes += ", ID = ";
                mes += std::string(chIDs.begin(), chIDs.end());
                throw std::runtime_error(mes);
            }
        }

        tables.push_back(std::move(table));
    }
    return tables;
}

inline std::vector<std::map<char, std::string>>
read_coarse_grained_models(const std::vector<toml::Table>& structures)
{
    std::vector<std::map<char, std::string>> tables;
    for(const auto& conf : structures)
    {
        std::map<char, std::string> table;
        for(const auto& kvp : conf)
        {
            const std::vector<char> chIDs = split_chain_ids(kvp.first);
            const toml::Table val = toml::get<toml::Table>(kvp.second);

            std::string model_name;
            model_name = toml::get<std::string>(
                    detail::value_at(val, "model", "[[structures]]"));
            for(char id : chIDs)
            {
                table[id] = model_name;
            }
        }
        tables.push_back(std::move(table));
    }
    return tables;
}

template<typename coordT>
std::vector<std::map<char, CGChain<coordT>>>
apply_coarse_grained_models(
        const std::vector<std::map<char, PDBChain<coordT>>>& pdbs,
        const std::vector<std::map<char, std::string>>& models)
{
    assert(pdbs.size() == models.size());
    std::vector<std::map<char, CGChain<coordT>>> cgss;
    for(std::size_t i=0; i<pdbs.size(); ++i)
    {
        std::map<char, CGChain<coordT>> cgs;
        const auto& pdb   = pdbs.at(i);
        const auto& model = models.at(i);

        for(const auto& kv : pdb)
        {
            const auto chid = kv.first;
            const auto&  ch = kv.second;
            cgs[chid] = make_coarse_grained(ch, model.at(chid));
        }

        std::size_t index = 0;
        for(auto& id_chain: cgs)
        {
            for(auto& bead : id_chain.second)
            {
                bead->index() = index;
                ++index;
            }
        }

        cgss.push_back(std::move(cgs));
    }
    return cgss;
}

} // mjolnir

int main(int argc, char **argv)
{
    typedef mjolnir::Vector<double, 3>    coord_type;
    typedef mjolnir::PDBChain<coord_type> pdb_chain_type;
    typedef mjolnir::CGChain<coord_type>  cg_chain_type;

    if(argc != 2)
    {
        std::cerr << "Usage: $ jarngreipr [file.toml]\n";
        std::cerr << "    see input/example.toml for the format" << std::endl;
        return 1;
    }

    const auto input_data = toml::parse(std::string(argv[1]));

    /* prepairing parameters */
    const auto general   = toml::get<toml::Table>(
            mjolnir::detail::value_at(input_data, "general", "<root>"));
    const auto file_name = toml::get<std::string>(
            mjolnir::detail::value_at(general, "file_prefix", "<root>"));
    std::random_device devrand;
    std::mt19937 mt(devrand());

    /* output general information */{
        std::cout << "[general]\n";
        std::cout << "file_name   = "
                  << toml::get_or(general, "file_prefix", "data"_str) << '\n';
        std::cout << "output_path = "
                  << toml::get_or(general, "output_path", "./"_str) << '\n';
        std::cout << "precision = "
                  << toml::get_or(general, "precision", "double"_str) << '\n';
        std::cout << "boundary  = "
                  << toml::get_or(general, "boundary", "Unlimited"_str) << '\n';
        std::cout << "thread    = " << std::boolalpha
                  << toml::get_or(general, "thread", false) << '\n';
        std::cout << "GPU       = " << std::boolalpha
                  << toml::get_or(general, "GPU",    false) << '\n';
        const std::int64_t default_seed = devrand();
        std::cout << "seed      = "
                  << toml::get_or(general, "seed", default_seed) << '\n';
    }

    const auto parameters =
        toml::parse(toml::get<std::string>(general.at("parameters")));

    const auto& mass =
        toml::get<toml::Table>(parameters.at("mass"));
    const auto& phys =
        toml::get<toml::Table>(parameters.at("physical_constants"));

    const auto system_config =
        toml::get<std::vector<toml::Table>>(input_data.at("systems"));

    /* generating coarse-grained structures */
    const auto structure_config =
            toml::get<std::vector<toml::Table>>(input_data.at("structures"));

    // vector<map<char, PDBChain<coord>>>
    // in most cases, the size of vector is one.
    const auto ref_pdbs =
        mjolnir::read_reference_structures<coord_type>(structure_config);
    const auto ini_pdbs =
        mjolnir::read_initial_structures  <coord_type>(structure_config);
    const auto models   =
        mjolnir::read_coarse_grained_models(structure_config);

    // apply coarse-grained model to input pdbs
    const auto ref_cgss = mjolnir::apply_coarse_grained_models(ref_pdbs, models);
    const auto ini_cgss = mjolnir::apply_coarse_grained_models(ini_pdbs, models);

    // output system setting and cg structure
    assert(system_config.size() == ini_cgss.size());
    for(std::size_t i=0; i<system_config.size(); ++i)
    {
        std::cout << "[[systems]]\n";
        // TODO {{{
        const auto& sysconf = system_config.at(i);
        const auto T = toml::get<double>(sysconf.at("temperature"));
        std::cout << "temperature    = " << std::fixed << T << '\n';
        std::cout << "ionic_strength = " << std::fixed
                  << toml::get<double>(sysconf.at("ionic_strength")) << '\n';
        std::cout << "boundary = {";
        for(const auto& kv : toml::get<toml::Table>(sysconf.at("boundary")))
        {
            if(kv.first == "type")
            {
                std::cout << kv.first << "=\"" << toml::get<std::string>(kv.second) << '\"';
            }
            else
            {
                const auto& crd = toml::get<std::array<double, 3>>(kv.second);
                std::cout << kv.first << "=[" << crd[0] << ',' << crd[1] << ','
                          << crd[2] << ']';
            }
        }
        std::cout << "}\n";
        // }}}

        std::cout << "particles = [\n";
        const auto& chain_table = ini_cgss.at(i);
        for(const auto& id_chain_pair : chain_table)
        {
            std::cerr << "chain ID = " << id_chain_pair.first;
            std::cerr << " has " << id_chain_pair.second.size() << " beads." << std::endl;
            for(std::size_t j=0; j<id_chain_pair.second.size(); ++j)
            {
                const auto& bead = id_chain_pair.second.at(j);
                const auto kB = toml::get<double>(phys.at("kB"));
                const auto m  = toml::get<double>(mass.at(bead->name()));
                const auto p  = bead->position();
                std::normal_distribution<double> mxw_blz(0.0, std::sqrt(kB*T/m));
                std::cout << "{mass = " << m
                          <<  ", position = [" << p[0] << ',' << p[1] << ',' << p[2]
                          << "], velocity = [" << mxw_blz(mt) << ','
                          << mxw_blz(mt) << ',' << mxw_blz(mt) << "]},\n";
            }
        }
        std::cout << "]\n";
    }

    const std::unique_ptr<mjolnir::IntraChainForceFieldGenerator<coord_type>>
        ffgen = mjolnir::make_unique<mjolnir::ClementiGo<coord_type>>();

    for(const auto& chains : ref_cgss)
    {
        std::cout << "[[forcefields]]\n";
        for(const auto& idch : chains)
        {
            const auto& ch = idch.second;
            const auto connect = ffgen->generate(std::cout, ch);
        }
    }

    // output parameter

    return 0;
}
<|endoftext|>