From 5853619ee7869bf8fa03ee956dd3930360a66479 Mon Sep 17 00:00:00 2001
From: Carl Philipp Klemm <philipp@uvos.xyz>
Date: Thu, 16 Nov 2023 13:39:58 +0100
Subject: [PATCH] add cli utility to fit drts on cmdline

---
 CMakeLists.txt |   7 +++
 cli.cpp        | 117 +++++++++++++++++++++++++++++++++++++++++++++++++
 main.cpp       |   4 +-
 3 files changed, 126 insertions(+), 2 deletions(-)
 create mode 100644 cli.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f5ac9b1..4cc5180 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -75,6 +75,13 @@ if(DEFINED EIS_FOUND)
 	target_include_directories(${PROJECT_NAME}_test PRIVATE . ${EIGEN3_INCLUDE_DIRS} ${EIS_INCLUDE_DIRS})
 	set_target_properties(${PROJECT_NAME}_test PROPERTIES COMPILE_FLAGS "-Wall -O2 -march=native -g" LINK_FLAGS "-flto")
 
+	link_directories(${CMAKE_CURRENT_BINARY_DIR})
+	add_executable(${PROJECT_NAME}_cli cli.cpp)
+	add_dependencies(${PROJECT_NAME}_cli ${PROJECT_NAME})
+	target_link_libraries(${PROJECT_NAME}_cli -l${PROJECT_NAME} ${EIGEN3_LIBRARIES} ${EIS_LIBRARIES})
+	target_include_directories(${PROJECT_NAME}_cli PRIVATE . ${EIGEN3_INCLUDE_DIRS} ${EIS_INCLUDE_DIRS})
+	set_target_properties(${PROJECT_NAME}_cli PROPERTIES COMPILE_FLAGS "-Wall -O2 -march=native -g" LINK_FLAGS "-flto")
+
 	if(DEFINED TORCH_LIBRARIES)
 		link_directories(${CMAKE_CURRENT_BINARY_DIR})
 		add_executable(${PROJECT_NAME}_test_torch testtorchdrt.cpp eistotorch.cpp)
diff --git a/cli.cpp b/cli.cpp
new file mode 100644
index 0000000..2109619
--- /dev/null
+++ b/cli.cpp
@@ -0,0 +1,117 @@
+//
+// libeisdrt - A library to calculate EIS Drts
+// Copyright (C) 2023 Carl Klemm <carl@uvos.xyz>
+//
+// This file is part of libeisdrt.
+//
+// libeisdrt is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// libeisdrt is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with libeisdrt.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include <iostream>
+#include <eisgenerator/eistype.h>
+
+#include "eisdrt/eisdrt.h"
+
+static void print_drt(const std::vector<fvalue>& data)
+{
+	std::cout<<'[';
+	size_t colcount = 0;
+	for(const fvalue point : data)
+	{
+		std::cout<<point;
+		std::cout<<' ';
+		if(++colcount > 1)
+		{
+			std::cout<<'\n';
+			colcount = 0;
+		}
+	}
+	std::cout<<"]\n";
+}
+
+static eis::EisSpectra transform_to_drt_spectra(const std::vector<fvalue>& drt, const eis::EisSpectra& spectra)
+{
+	assert(spectra.data.size() == drt.size());
+	eis::EisSpectra drtSpectra = spectra;
+	drtSpectra.data.clear();
+	drtSpectra.data.reserve(drt.size());
+
+	for(size_t i = 0; i < drt.size(); ++i)
+		drtSpectra.data.push_back(eis::DataPoint(std::complex<fvalue>(drt[i], 0), spectra.data[i].omega));
+
+	return drtSpectra;
+}
+
+static void print_help(char* name)
+{
+	std::cout<<"Usage "<<name<<" [INPUT_SPECTRA_FILENAME] [OUTPUT_FILE_FILENAME]\n";
+	std::cout<<"The input spectra is expected to be in eisgenerator format\n";
+}
+
+int main(int argc, char** argv)
+{
+	if(argc != 3 && argc > 0)
+		print_help(argv[0]);
+	if(argc != 3)
+		return 1;
+
+	bool toStdout = std::string(argv[2]) == "-";
+
+	try
+	{
+		eis::EisSpectra spectra;
+		if(std::string(argv[1]) != "-")
+		{
+			if(!toStdout)
+				std::cout<<"Loading spectra\n";
+			spectra = eis::EisSpectra::loadFromDisk(argv[1]);
+		}
+		else
+		{
+			if(!toStdout)
+				std::cout<<"Waiting for spectra on stdin\n";
+			spectra = eis::EisSpectra::loadFromStream(std::cin);
+		}
+
+		if(!toStdout)
+			std::cout<<"Calculateing Drt\n";
+		FitMetics fm;
+		std::vector<fvalue> drt = calcDrt(spectra.data, fm, FitParameters(1000));
+
+		if(!toStdout)
+		{
+			std::cout<<"Calculated Drt:\n";
+			print_drt(drt);
+		}
+
+		eis::EisSpectra drtSpectra = transform_to_drt_spectra(drt, spectra);
+		bool ret = true;
+		if(!toStdout)
+			ret = drtSpectra.saveToDisk(argv[2]);
+		else
+			drtSpectra.saveToStream(std::cout);
+		if(!ret)
+		{
+			std::cerr<<"Could not save spectra to "<<argv[2]<<'\n';
+			return 1;
+		}
+	}
+	catch(const eis::file_error& err)
+	{
+		std::cerr<<"Could not read spectra from "<<argv[1]<<' '<<err.what()<<'\n';
+		return 1;
+	}
+
+	return 0;
+}
diff --git a/main.cpp b/main.cpp
index 3c0469c..478b011 100644
--- a/main.cpp
+++ b/main.cpp
@@ -24,7 +24,7 @@
 
 #include "eisdrt/eisdrt.h"
 
-void printImpedance(const std::vector<eis::DataPoint>& data)
+static void printImpedance(const std::vector<eis::DataPoint>& data)
 {
 	std::cout<<'[';
 	size_t colcount = 0;
@@ -41,7 +41,7 @@ void printImpedance(const std::vector<eis::DataPoint>& data)
 	std::cout<<"]\n";
 }
 
-void printFvalueVector(const std::vector<fvalue>& data)
+static void printFvalueVector(const std::vector<fvalue>& data)
 {
 	std::cout<<'[';
 	size_t colcount = 0;
-- 
GitLab