diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4f33bfef96b3b85f81313ad10d0995deefc0d2cb..a390c51a19b34cc6ee9706458789efc8a58b3f42 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,6 +18,7 @@ set(SRC_FILES
 	log.cpp
 	normalize.cpp
 	basicmath.cpp
+	finitetr.cpp
 )
 
 set(API_HEADERS_CPP_DIR eisgenerator/)
diff --git a/cap.cpp b/cap.cpp
index 61e9041dabc5c0ad680df5701b7c906bbd173dd8..19933dd431e7b57c174d22cdd558ad978fad52f5 100644
--- a/cap.cpp
+++ b/cap.cpp
@@ -56,6 +56,11 @@ void Cap::setParam(const std::vector<fvalue>& param)
 	_C = param[0];
 }
 
+char Cap::getComponantChar() const
+{
+	return Cap::staticGetComponantChar();
+}
+
 size_t Cap::paramCount()
 {
 	return 1;
diff --git a/componant.cpp b/componant.cpp
index 7ea0e0b4bdb848499f95013cba84e35ba96921bf..f0e29eb89fea1f199c6ee98c4b9b2779fb9aa42f 100644
--- a/componant.cpp
+++ b/componant.cpp
@@ -7,51 +7,34 @@
 #include "warburg.h"
 #include "log.h"
 #include "inductor.h"
+#include "finitetr.h"
 
 using namespace eis;
 
 Componant* Componant::copy(Componant* componant)
 {
-	switch(getComponantChar(componant))
+	switch(componant->getComponantChar())
 	{
-		case 'r':
+		case Resistor::staticGetComponantChar():
 			return new Resistor(*dynamic_cast<Resistor*>(componant));
-		case 'c':
+		case Cap::staticGetComponantChar():
 			return new Cap(*dynamic_cast<Cap*>(componant));
-		case 'i':
+		case Inductor::staticGetComponantChar():
 			return new Inductor(*dynamic_cast<Inductor*>(componant));
-		case 'p':
+		case Cpe::staticGetComponantChar():
 			return new Cpe(*dynamic_cast<Cpe*>(componant));
-		case 'w':
+		case Warburg::staticGetComponantChar():
 			return new Warburg(*dynamic_cast<Warburg*>(componant));
-		case 'l':
+		case FiniteTransmitionline::staticGetComponantChar():
+			return new FiniteTransmitionline(*dynamic_cast<FiniteTransmitionline*>(componant));
+		case Parallel::staticGetComponantChar():
 			return new Parallel(*dynamic_cast<Parallel*>(componant));
-		case 's':
+		case Serial::staticGetComponantChar():
 			return new Serial(*dynamic_cast<Serial*>(componant));
 		default:
-			Log(Log::ERROR)<<"unimplmented type copy for "<<getComponantChar(componant)<<'\n';
+			Log(Log::ERROR)<<"unimplmented type copy for "<<componant->getComponantChar();
 			assert(0);
 			break;
 	}
 	return nullptr;
 }
-
-char Componant::getComponantChar(Componant* componant)
-{
-	if(dynamic_cast<Resistor*>(componant))
-		return 'r';
-	if(dynamic_cast<Cap*>(componant))
-		return 'c';
-	if(dynamic_cast<Inductor*>(componant))
-		return 'i';
-	if(dynamic_cast<Cpe*>(componant))
-		return 'p';
-	if(dynamic_cast<Warburg*>(componant))
-		return 'w';
-	if(dynamic_cast<Parallel*>(componant))
-		return 'l';
-	if(dynamic_cast<Serial*>(componant))
-		return 's';
-
-	return 'x';
-}
diff --git a/constantphase.cpp b/constantphase.cpp
index 6022ba85d52da43f1931e8f8e4cdc7db6539b641..834a884d64d9526cc5f0ff12cb3f6e4b263ede19 100644
--- a/constantphase.cpp
+++ b/constantphase.cpp
@@ -65,3 +65,8 @@ size_t Cpe::paramCount()
 {
 	return 2;
 }
+
+char Cpe::getComponantChar() const
+{
+	return Cpe::staticGetComponantChar();
+}
diff --git a/eisgenerator/cap.h b/eisgenerator/cap.h
index d394f833b3d05a23553fa4baa34d893195fb351e..e0e66c4ddd70504841c7fbe8e43d23b9edf5cbb5 100644
--- a/eisgenerator/cap.h
+++ b/eisgenerator/cap.h
@@ -18,6 +18,8 @@ public:
 	virtual std::vector<fvalue> getParam() override;
 	virtual void setParam(const std::vector<fvalue>& param) override;
 	virtual size_t paramCount() override;
+	virtual char getComponantChar() const override;
+	static constexpr char staticGetComponantChar(){return 'c';}
 	virtual ~Cap() = default;
 };
 
diff --git a/eisgenerator/componant.h b/eisgenerator/componant.h
index 141049e50eb674a472e3dd74ebc72295d31e649f..eb5ca6de542ed39050e045ac2ff9ea8daa9eca52 100644
--- a/eisgenerator/componant.h
+++ b/eisgenerator/componant.h
@@ -24,9 +24,9 @@ class Componant
 		virtual void setParam(const std::vector<fvalue>& param){};
 		virtual size_t paramCount(){return 0;}
 		virtual ~Componant() = default;
+		virtual char getComponantChar() const = 0;
 
 		static Componant* copy(Componant* componant);
-		static char getComponantChar(Componant* componant);
 };
 
 }
diff --git a/eisgenerator/constantphase.h b/eisgenerator/constantphase.h
index 11587171c525bd7200310251423969943d4cec28..0706e26e7f20f6ccfef77c5194fe7cf3d58f443e 100644
--- a/eisgenerator/constantphase.h
+++ b/eisgenerator/constantphase.h
@@ -19,7 +19,10 @@ public:
 	virtual std::vector<fvalue> getParam() override;
 	virtual void setParam(const std::vector<fvalue>& param) override;
 	virtual size_t paramCount() override;
+	virtual char getComponantChar() const override;
+	static constexpr char staticGetComponantChar(){return 'p';}
 	virtual ~Cpe() = default;
+
 };
 
 }
diff --git a/eisgenerator/eistype.h b/eisgenerator/eistype.h
index 43c6e3cdf838abe0ad77493a35e5a6c223f9b0c0..7c0b5947cd9d80e44ba87097466a51370bdb383d 100644
--- a/eisgenerator/eistype.h
+++ b/eisgenerator/eistype.h
@@ -17,6 +17,7 @@ struct Range
 	fvalue end;
 	size_t count;
 	bool log = false;
+	char type = 'x';
 
 	fvalue stepSize() const
 	{
@@ -38,7 +39,7 @@ struct Range
 	{
 		return operator*(static_cast<fvalue>(1.0)/in);
 	}
-	Range(fvalue startI, fvalue endI, size_t countI, bool logI = false): start(startI), end(endI), count(countI), log(logI){}
+	Range(fvalue startI, fvalue endI, size_t countI, bool logI = false, char typeI = 'x'): start(startI), end(endI), count(countI), log(logI), type(typeI){}
 	Range() = default;
 };
 
diff --git a/eisgenerator/finitetr.h b/eisgenerator/finitetr.h
new file mode 100644
index 0000000000000000000000000000000000000000..fbaf35d7f7be703e1d8c254993e2ea3597f8c1da
--- /dev/null
+++ b/eisgenerator/finitetr.h
@@ -0,0 +1,30 @@
+#pragma once
+#include "componant.h"
+
+namespace eis
+{
+
+class FiniteTransmitionline: public Componant
+{
+	fvalue _C;
+	fvalue _R;
+	unsigned int _n;
+
+	Componant* subComponant = nullptr;
+
+	static Componant* createTransmitionLine(fvalue c, fvalue r, unsigned int n);
+
+public:
+	FiniteTransmitionline(fvalue c, fvalue r, unsigned int n);
+	FiniteTransmitionline(std::string paramStr);
+	FiniteTransmitionline(const FiniteTransmitionline& in);
+	virtual std::complex<fvalue> execute(fvalue omega) override;
+	virtual std::vector<fvalue> getParam();
+	virtual void setParam(const std::vector<fvalue>& param);
+	virtual size_t paramCount();
+	virtual ~FiniteTransmitionline();
+	virtual char getComponantChar() const override;
+	static constexpr char staticGetComponantChar(){return 't';}
+};
+
+}
diff --git a/eisgenerator/inductor.h b/eisgenerator/inductor.h
index 8edba47b832863251913472f74c74a201cffab86..a2634625520fff3c09abfd1da05ec125b0bd0fdd 100644
--- a/eisgenerator/inductor.h
+++ b/eisgenerator/inductor.h
@@ -18,6 +18,8 @@ public:
 	virtual std::vector<fvalue> getParam() override;
 	virtual void setParam(const std::vector<fvalue>& param) override;
 	virtual size_t paramCount() override;
+	virtual char getComponantChar() const override;
+	static constexpr char staticGetComponantChar(){return 'l';}
 	virtual ~Inductor() = default;
 };
 
diff --git a/eisgenerator/log.h b/eisgenerator/log.h
index e07cb23e8ad7c9b935d30744c024fb60c509e0c3..d4240ca1087aeb5a92837cf6359d2706662fcf42 100644
--- a/eisgenerator/log.h
+++ b/eisgenerator/log.h
@@ -39,6 +39,7 @@ public:
 private:
 	bool opened = false;
 	Level msglevel = DEBUG;
+	bool endline = true;
 
 	std::string getLabel(Level level);
 	
@@ -46,10 +47,9 @@ public:
 
 	static bool headers;
 	static Level level;
-	static bool endline;
 
 	Log() {}
-	Log(Level type);
+	Log(Level type, bool endlineI = true);
 	~Log();
 	
 	template<class T> Log &operator<<(const T &msg) 
diff --git a/eisgenerator/model.h b/eisgenerator/model.h
index 0a654b39e58c118227502b0101ca21a6325987bd..7f47ccd27354ac209458c64a8c2e9695ab875fe8 100644
--- a/eisgenerator/model.h
+++ b/eisgenerator/model.h
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <complex>
+#include <cstddef>
 #include <string>
 #include <vector>
 #include <functional>
@@ -18,7 +19,8 @@ private:
 	Componant *processBrackets(std::string& str, size_t& bracketCounter);
 	Componant *processBracket(std::string& str);
 	std::string getParamStr(const std::string& str, size_t index);
-	void addComponantToFlat(Componant* componant);
+	static void addComponantToFlat(Componant* componant, std::vector<Componant*>* flatComponants);
+	Componant* flatParameterToFlatComponant(size_t parameterIndex);
 
 private:
 	Componant *_model = nullptr;
@@ -31,16 +33,17 @@ public:
 	Model(const Model& in);
 	Model& operator=(const Model& in);
 	~Model();
-	DataPoint execute(fvalue omaga);
-	std::vector<DataPoint> executeSweep(const Range& omega);
+	DataPoint execute(fvalue omaga, Componant* model);
+	std::vector<DataPoint> executeSweep(const Range& omega, Componant *model = nullptr);
 	bool executeParamSweep(const std::vector<Range>& componantRanges, const Range& omega, std::function<void(std::vector<DataPoint>&, const std::vector<fvalue>&)> dataCb);
 	std::vector<DataPoint> executeParamByIndex(const std::vector<Range>& componantRanges, const Range& omega, size_t index);
-
+	std::vector<DataPoint> executeParamByIndexC(const std::vector<Range>& componantRanges, const Range& omega, size_t index);
 	std::string getModelStr();
-	std::vector<Componant*> getFlatComponants();
-	std::vector<fvalue> getFlatParameters();
+	std::vector<Componant*> getFlatComponants(Componant *model = nullptr);
+	std::vector<fvalue> getFlatParameters(Componant *model = nullptr);
 	size_t getFlatParametersCount();
-	bool setFlatParameters(const std::vector<fvalue>& parameters);
+	bool setFlatParameters(const std::vector<fvalue>& parameters, Componant *model = nullptr);
+	bool checkParameterRanges(const std::vector<eis::Range> ranges, Componant* model = nullptr);
 
 	static std::vector<fvalue> getSweepParamByIndex(const std::vector<Range>& componantRanges, size_t index);
 	static size_t getRequiredStepsForSweeps(const std::vector<Range>& componantRanges);
diff --git a/eisgenerator/paralellseriel.h b/eisgenerator/paralellseriel.h
index e764c970083106ec9ad887bae40ee4bc72f3c74e..1a63dbf3523ad80de052f8975fe7a7f238c54dfd 100644
--- a/eisgenerator/paralellseriel.h
+++ b/eisgenerator/paralellseriel.h
@@ -16,6 +16,8 @@ public:
 	void operator=(const Parallel& in);
 	~Parallel();
 	virtual std::complex<fvalue> execute(fvalue omaga) override;
+	virtual char getComponantChar() const override;
+	static constexpr char staticGetComponantChar(){return '|';}
 };
 
 class Serial: public Componant
@@ -28,6 +30,8 @@ public:
 	void operator=(const Serial& in);
 	~Serial();
 	virtual std::complex<fvalue> execute(fvalue omaga) override;
+	virtual char getComponantChar() const override;
+	static constexpr char staticGetComponantChar(){return 's';}
 };
 
 }
diff --git a/eisgenerator/resistor.h b/eisgenerator/resistor.h
index 42bc4d68eb64cacddd4b1248affffa4c1b15e525..f9d412da40741fe35f7943126aeb623de3c21700 100644
--- a/eisgenerator/resistor.h
+++ b/eisgenerator/resistor.h
@@ -17,6 +17,8 @@ public:
 	virtual std::vector<fvalue> getParam() override;
 	virtual void setParam(const std::vector<fvalue>& param) override;
 	virtual size_t paramCount() override;
+	virtual char getComponantChar() const override;
+	static constexpr char staticGetComponantChar(){return 'r';}
 	virtual ~Resistor() = default;
 };
 
diff --git a/eisgenerator/warburg.h b/eisgenerator/warburg.h
index 0974d9949933a6d39afacdd04d691db3ff9e816c..7fdd8b86bc7bb34161ef8b86256bc756abbc3ddc 100644
--- a/eisgenerator/warburg.h
+++ b/eisgenerator/warburg.h
@@ -18,6 +18,8 @@ public:
 	virtual std::vector<fvalue> getParam() override;
 	virtual void setParam(const std::vector<fvalue>& param) override;
 	virtual size_t paramCount() override;
+	virtual char getComponantChar() const override;
+	static constexpr char staticGetComponantChar(){return 'w';}
 	virtual ~Warburg() = default;
 };
 
diff --git a/finitetr.cpp b/finitetr.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a69487a496717b7204b995ae77f5550a2ed0e965
--- /dev/null
+++ b/finitetr.cpp
@@ -0,0 +1,137 @@
+#include "finitetr.h"
+#include <cstdlib>
+#include <math.h>
+
+#include "eisgenerator/componant.h"
+#include "eisgenerator/paralellseriel.h"
+#include "eisgenerator/resistor.h"
+#include "paralellseriel.h"
+#include "cap.h"
+#include "resistor.h"
+#include "log.h"
+#include "tokenize.h"
+
+using namespace eis;
+
+FiniteTransmitionline::FiniteTransmitionline(fvalue c, fvalue r, unsigned int n): _C(c), _R(r), _n(n)
+{
+	if(n < 1)
+	{
+		Log(Log::WARN)<<__func__<<" n must be > 0 setting n to 4";
+		_n = 4;
+	}
+
+	subComponant = createTransmitionLine(_C, _R, _n);
+}
+
+FiniteTransmitionline::FiniteTransmitionline(std::string paramStr)
+{
+	std::vector<std::string> tokens = tokenize(paramStr, ',');
+	if(tokens.size() < paramCount())
+	{
+		Log(Log::WARN)<<"to few parameters in "<<__func__<<" parameter string: "<<paramStr;
+		_C = 1e-6;
+		_R = 1000;
+		_n = 4;
+		subComponant = createTransmitionLine(_C, _R, _n);
+		return;
+	}
+	else
+	{
+		try
+		{
+			_R = std::stod(tokens[0]);
+			_C = std::stod(tokens[1]);
+			_n = std::stod(tokens[2]);
+			subComponant = createTransmitionLine(_C, _R, _n);
+		}
+		catch(const std::invalid_argument& ia)
+		{
+			Log(Log::WARN)<<"Warning: cant parse parameter in "<<__func__<<" parameter: "<<tokens[0]<<'\n';
+			_C = 1e3;
+		}
+	}
+}
+
+FiniteTransmitionline::FiniteTransmitionline(const FiniteTransmitionline& in)
+{
+	_R = in._R;
+	_C = in._C;
+	_n = in._n;
+	subComponant = createTransmitionLine(_C, _R, _n);
+}
+
+std::complex<fvalue> FiniteTransmitionline::execute(fvalue omega)
+{
+	if(subComponant)
+	{
+		return subComponant->execute(omega);
+	}
+	else
+	{
+		Log(Log::WARN)<<"Invalid transmitionline used";
+		return std::complex<fvalue>(1, 0);
+	}
+}
+
+std::vector<fvalue> FiniteTransmitionline::getParam()
+{
+	return std::vector<fvalue>({_R, _C, static_cast<fvalue>(_n)});
+}
+
+void FiniteTransmitionline::setParam(const std::vector<fvalue>& param)
+{
+	if(param.size() < paramCount())
+	{
+		Log(Log::WARN)<<"invalid parameter list sent to "<<__func__<<'\n';
+		return;
+	}
+
+	_R = param[0];
+	_C = param[1];
+	_n = param[2];
+
+	if(param[2] < 1)
+	{
+		Log(Log::WARN)<<"invalid parameter list sent to "<<__func__<<" n must be > 1 "<<'\n';
+		return;
+	}
+
+	_n = param[2];
+}
+
+char FiniteTransmitionline::getComponantChar() const
+{
+	return FiniteTransmitionline::staticGetComponantChar();
+}
+
+size_t FiniteTransmitionline::paramCount()
+{
+	return 3;
+}
+
+Componant* FiniteTransmitionline::createTransmitionLine(fvalue c, fvalue r, unsigned int n)
+{
+	Parallel* par = new Parallel;
+	par->componants.push_back(new Cap(c));
+	par->componants.push_back(new Resistor(r));
+
+	for(unsigned int i = 0; i < n; ++i)
+	{
+		Serial* ser = new Serial;
+		ser->componants.push_back(new Resistor(r));
+		ser->componants.push_back(par);
+
+		par = new Parallel;
+		par->componants.push_back(ser);
+		par->componants.push_back(new Cap(c));
+	}
+
+	return par;
+}
+
+FiniteTransmitionline::~FiniteTransmitionline()
+{
+	if(subComponant)
+		delete subComponant;
+}
diff --git a/inductor.cpp b/inductor.cpp
index 1c06219a802438cb7476f40a3a9b5c7989b3c1fe..195a78a4766e30fcff56a78efbf046e856e1837d 100644
--- a/inductor.cpp
+++ b/inductor.cpp
@@ -60,3 +60,8 @@ size_t Inductor::paramCount()
 {
 	return 1;
 }
+
+char Inductor::getComponantChar() const
+{
+	return staticGetComponantChar();
+}
diff --git a/log.cpp b/log.cpp
index 307929146c813cc8543443a807497c3fe2b66b5e..fc50c5889344ebd1f594778e957d98c9d4012ca5 100644
--- a/log.cpp
+++ b/log.cpp
@@ -21,7 +21,7 @@
 
 using namespace eis;
 
-Log::Log(Level type)
+Log::Log(Level type, bool endlineI): endline(endlineI)
 {
 	msglevel = type;
 	if(headers) 
@@ -32,7 +32,7 @@ Log::Log(Level type)
 
 Log::~Log() 
 {
-	if(opened && endline) 
+	if(opened && endline)
 	{
 		std::cout<<'\n';
 	}
@@ -63,4 +63,3 @@ std::string Log::getLabel(Level level)
 	
 bool Log::headers = false;
 Log::Level Log::level = WARN;
-bool Log::endline = true;
diff --git a/main.cpp b/main.cpp
index 3d2c811ed3e282731a66f495954d3f4d15e8d92d..4e7b9ebc0a9f94639e57cfb91d7309c3ac1c8645 100644
--- a/main.cpp
+++ b/main.cpp
@@ -13,7 +13,7 @@ static void printComponants(eis::Model& model)
 	eis::Log(eis::Log::DEBUG)<<"Compnants:";
 	for(eis::Componant* componant : model.getFlatComponants())
 	{
-		eis::Log(eis::Log::DEBUG)<<eis::Componant::getComponantChar(componant)<<"{";
+		eis::Log(eis::Log::DEBUG)<<componant->getComponantChar()<<"{";
 		for(size_t i = 0; i < componant->paramCount(); ++i)
 		{
 			eis::Log(eis::Log::DEBUG)<<componant->getParam()[i];
diff --git a/model.cpp b/model.cpp
index 6848fbc92501e3fbf6c22c16475429f4187ae598..033b41af6ec66d69669e347e054fbacace20b272 100644
--- a/model.cpp
+++ b/model.cpp
@@ -1,11 +1,14 @@
+#include <cstddef>
 #include <model.h>
 #include <iostream>
 #include <assert.h>
+#include <vector>
 #include "tokenize.h"
 #include "cap.h"
 #include "resistor.h"
 #include "inductor.h"
 #include "constantphase.h"
+#include "finitetr.h"
 #include "warburg.h"
 #include "paralellseriel.h"
 #include "log.h"
@@ -79,10 +82,10 @@ Componant *Model::processBrackets(std::string& str, size_t& bracketCounter)
 
 std::string Model::getParamStr(const std::string& str, size_t index)
 {
-	if(str.size()-index < 3 || str[index+1] != '{')
+	if(static_cast<int64_t>(str.size())-index < 3 || str[index+1] != '{')
 	{
-		Log(Log::DEBUG)<<"missing parameter for "<<str[index];
-		return 0;
+		Log(Log::WARN)<<"missing parameter string for "<<str[index];
+		return "";
 	}
 
 	size_t end = opposingBraket(str, index, '}');
@@ -107,35 +110,58 @@ Componant *Model::processBracket(std::string& str)
 			Log(Log::DEBUG)<<__func__<<" arg: "<<nodeStr[i];
 			switch(nodeStr[i])
 			{
-				case 'c':
-				case 'C':
+				case Cap::staticGetComponantChar():
+				{
 					componants.push_back(new Cap(getParamStr(nodeStr, i)));
-					i = opposingBraket(nodeStr, i, '}');
+					size_t opposing = opposingBraket(nodeStr, i, '}');
+					if(opposing != std::string::npos)
+						i = opposingBraket(nodeStr, i, '}');
 					break;
-				case 'r':
-				case 'R':
+				}
+				case Resistor::staticGetComponantChar():
+				{
 					componants.push_back(new Resistor(getParamStr(nodeStr, i)));
-					i = opposingBraket(nodeStr, i, '}');
+					size_t opposing = opposingBraket(nodeStr, i, '}');
+					if(opposing != std::string::npos)
+						i = opposingBraket(nodeStr, i, '}');
 					break;
-				case 'l':
-				case 'L':
+				}
+				case Inductor::staticGetComponantChar():
+				{
 					componants.push_back(new Inductor(getParamStr(nodeStr, i)));
-					i = opposingBraket(nodeStr, i, '}');
+					size_t opposing = opposingBraket(nodeStr, i, '}');
+					if(opposing != std::string::npos)
+						i = opposingBraket(nodeStr, i, '}');
 					break;
-				case 'p':
-				case 'P':
+				}
+				case Cpe::staticGetComponantChar():
+				{
 					componants.push_back(new Cpe(getParamStr(nodeStr, i)));
-					i = opposingBraket(nodeStr, i, '}');
+					size_t opposing = opposingBraket(nodeStr, i, '}');
+					if(opposing != std::string::npos)
+						i = opposingBraket(nodeStr, i, '}');
 					break;
-				case 'w':
-				case 'W':
+				}
+				case Warburg::staticGetComponantChar():
+				{
 					componants.push_back(new Warburg(getParamStr(nodeStr, i)));
-					i = opposingBraket(nodeStr, i, '}');
+					size_t opposing = opposingBraket(nodeStr, i, '}');
+					if(opposing != std::string::npos)
+						i = opposingBraket(nodeStr, i, '}');
+					break;
+				}
+				case FiniteTransmitionline::staticGetComponantChar():
+				{
+					componants.push_back(new FiniteTransmitionline(getParamStr(nodeStr, i)));
+					size_t opposing = opposingBraket(nodeStr, i, '}');
+					if(opposing != std::string::npos)
+						i = opposingBraket(nodeStr, i, '}');
 					break;
+				}
 				case '{':
 					i = opposingBraket(nodeStr, i, '}');
 				case '}':
-					Log(Log::WARN)<<"stray "<<nodeStr[i]<<" in model string";
+					Log(Log::WARN)<<getModelStr()<<" stray "<<nodeStr[i]<<" in model string";
 					break;
 				case '0' ... '9':
 				{
@@ -191,8 +217,11 @@ Model::~Model()
 	delete _model;
 }
 
-DataPoint Model::execute(fvalue omega)
+DataPoint Model::execute(fvalue omega, Componant* model)
 {
+	if(!model)
+		model = _model;
+
 	if(_model)
 	{
 		DataPoint dataPoint;
@@ -207,13 +236,13 @@ DataPoint Model::execute(fvalue omega)
 	return DataPoint({std::complex<fvalue>(0,0), 0});
 }
 
-void Model::addComponantToFlat(Componant* componant)
+void Model::addComponantToFlat(Componant* componant, std::vector<Componant*>* flatComponants)
 {
 	Parallel* paralell = dynamic_cast<Parallel*>(componant);
 	if(paralell)
 	{
 		for(Componant* element : paralell->componants)
-			addComponantToFlat(element);
+			addComponantToFlat(element, flatComponants);
 		return;
 	}
 
@@ -221,24 +250,36 @@ void Model::addComponantToFlat(Componant* componant)
 	if(serial)
 	{
 		for(Componant* element : serial->componants)
-			addComponantToFlat(element);
+			addComponantToFlat(element, flatComponants);
 		return;
 	}
 
-	_flatComponants.push_back(componant);
+	flatComponants->push_back(componant);
 }
 
-std::vector<Componant*> Model::getFlatComponants()
+std::vector<Componant*> Model::getFlatComponants(Componant *model)
 {
-	if(!_flatComponants.empty())
-		return _flatComponants;
+	if(model == nullptr || model == _model)
+	{
+		if(!_flatComponants.empty())
+			return _flatComponants;
 
-	addComponantToFlat(_model);
-	return getFlatComponants();
+		addComponantToFlat(_model, &_flatComponants);
+		return getFlatComponants();
+	}
+	else
+	{
+		std::vector<Componant*> flatComponants;
+		addComponantToFlat(model, &flatComponants);
+		return flatComponants;
+	}
 }
 
-std::vector<DataPoint> Model::executeSweep(const Range& omega)
+std::vector<DataPoint> Model::executeSweep(const Range& omega, Componant* model)
 {
+	if(!model)
+		model = _model;
+
 	std::vector<DataPoint> results;
 	results.reserve(omega.count);
 
@@ -249,7 +290,7 @@ std::vector<DataPoint> Model::executeSweep(const Range& omega)
 
 		for(size_t i = 0; i < omega.count; ++i)
 		{
-			results.push_back(execute(currOmega));
+			results.push_back(execute(currOmega, model));
 			currOmega+=step;
 		}
 	}
@@ -262,13 +303,27 @@ std::vector<DataPoint> Model::executeSweep(const Range& omega)
 
 		for(size_t i = 0; i < omega.count; ++i)
 		{
-			results.push_back(execute(pow(10, currOmegaL)));
+			results.push_back(execute(pow(10, currOmegaL), model));
 			currOmegaL+=step;
 		}
 	}
 	return results;
 }
 
+std::vector<DataPoint> Model::executeParamByIndexC(const std::vector<Range>& componantRanges, const Range& omega, size_t index)
+{
+	std::vector<fvalue> parameters = getSweepParamByIndex(componantRanges, index);
+
+	Componant* model = Componant::copy(_model);
+	setFlatParameters(parameters, model);
+
+	std::vector<DataPoint> data = executeSweep(omega, model);
+
+	delete model;
+
+	return data;
+}
+
 std::vector<DataPoint> Model::executeParamByIndex(const std::vector<Range>& componantRanges, const Range& omega, size_t index)
 {
 	std::vector<fvalue> parameters = getSweepParamByIndex(componantRanges, index);
@@ -306,25 +361,9 @@ bool Model::executeParamSweep(const std::vector<Range>& componantRanges, const R
                               std::function<void(std::vector<DataPoint>&, const std::vector<fvalue>&)> dataCb)
 {
 	size_t parametersCount = getFlatParametersCount();
-	if(componantRanges.size() != parametersCount)
-	{
-		Log(Log::ERROR)<<"a parameter range must be provided for eatch componant parameter";
-		return false;
-	}
 
-	for(size_t i = 0; i < parametersCount; ++i)
-	{
-		if(componantRanges[i].count == 0 || (componantRanges[i].count < 2 && componantRanges[i].start != componantRanges[i].end))
-		{
-			Log(Log::ERROR)<<"paramter range must specify at least one paramter point if only one paramer point is specified start and end must be the same";
-			return false;
-		}
-		else if(componantRanges[i].start > componantRanges[i].end)
-		{
-			Log(Log::ERROR)<<"paramter range end-start must be positive";
-			return false;
-		}
-	}
+	if(!checkParameterRanges(componantRanges))
+		return false;
 
 	size_t stepsRequired = getRequiredStepsForSweeps(componantRanges);
 
@@ -344,11 +383,14 @@ bool Model::executeParamSweep(const std::vector<Range>& componantRanges, const R
 	return true;
 }
 
-bool Model::setFlatParameters(const std::vector<fvalue>& parameters)
+bool Model::setFlatParameters(const std::vector<fvalue>& parameters, Componant* model)
 {
 	if(parameters.size() != getFlatParametersCount())
 		return false;
 
+	if(!model)
+		model = _model;
+
 	size_t i = 0;
 	for(Componant* componant : getFlatComponants())
 	{
@@ -361,10 +403,26 @@ bool Model::setFlatParameters(const std::vector<fvalue>& parameters)
 	return true;
 }
 
-std::vector<fvalue> Model::getFlatParameters()
+
+Componant* Model::flatParameterToFlatComponant(size_t parameterIndex)
+{
+	size_t i = 0;
+	for(Componant* componant : getFlatComponants())
+	{
+		i += componant->paramCount();
+		if(i > parameterIndex)
+			return componant;
+	}
+	return nullptr;
+}
+
+std::vector<fvalue> Model::getFlatParameters(Componant *model)
 {
+	if(!model)
+		model = _model;
+
 	std::vector<fvalue> params;
-	std::vector<Componant*> componants = getFlatComponants();
+	std::vector<Componant*> componants = getFlatComponants(model);
 	for(Componant* componant : componants)
 	{
 		for(fvalue param : componant->getParam())
@@ -402,3 +460,54 @@ std::string Model::getModelStr()
 	}
 	return output;
 }
+
+bool Model::checkParameterRanges(const std::vector<eis::Range> ranges, Componant* model)
+{
+	if(!model)
+		model = _model;
+
+	if(!model)
+	{
+		Log(Log::ERROR)<<"model not ready";
+		return false;
+	}
+
+	size_t parametersCount = getFlatParametersCount();
+	std::vector<Componant*> flatComponants = getFlatComponants(model);
+
+	if(ranges.size() != parametersCount)
+	{
+		Log(Log::ERROR)<<"a parameter range must be provided for eatch componant parameter";
+		return false;
+	}
+
+	for(size_t i = 0; i < parametersCount; ++i)
+	{
+		if(ranges[i].count == 0 || (ranges[i].count < 2 && ranges[i].start != ranges[i].end))
+		{
+			Log(Log::ERROR)<<getModelStr()<<" paramter range must specify at least one paramter point if"
+				<<"one paramer point is specified start and end must be the same";
+			return false;
+		}
+		else if(ranges[i].start > ranges[i].end)
+		{
+			Log(Log::ERROR)<<getModelStr()<<" paramter range end-start must be positive";
+			return false;
+		}
+		else if(ranges[i].type != 'x' && ranges[i].type != flatParameterToFlatComponant(i)->getComponantChar())
+		{
+			Log(Log::ERROR)<<getModelStr()<<" componnant "<<i<<"'s range is of invalid type "
+				<<ranges[i].type<<". expected "<<flatComponants[i]->getComponantChar()<<'\n'
+				<<"Expected order:";
+
+			for(const Componant* componant : flatComponants)
+			{
+				Log(Log::ERROR, false)<<componant->getComponantChar();
+			}
+			std::cout<<std::endl;
+
+			return false;
+		}
+	}
+	return true;
+}
diff --git a/options.h b/options.h
index 8cd800030b7be43ca263a0603615bae75de87a46..c0b14138f8ffcb1b1fbbc87bb84d3f3d2859f95a 100644
--- a/options.h
+++ b/options.h
@@ -19,7 +19,7 @@ static struct argp_option options[] =
   {"model",      'm', "[STRING]",    0,  "set model string" },
   {"omega",      'o', "[START-END]", 0,  "set omega range" },
   {"omegasteps", 'c', "[COUNT]",     0,  "set omega range steps" },
-  {"log",       'l', 0,      0,  "use logarithmic steps" },
+  {"linear",       'l', 0,      0,  "use linear instead of logarithmic steps" },
   {"normalize", 'n', 0,      0,  "normalize values" },
   {"reduce",    'r', 0,      0,  "reduce values to \"interesting\" range" },
   {"hz",        'h', 0,      0,  "freqency values as temporal frequency instead of angular frequency"},
@@ -43,7 +43,7 @@ struct Config
 	bool hertz = false;
 	bool invert = false;
 
-	Config(): omegaRange(1, 1001, 1)
+	Config(): omegaRange(1, 1001, 1, true)
 	{}
 };
 
@@ -70,7 +70,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
 		config->modelStr.assign(arg);
 		break;
 	case 'l':
-		config->omegaRange.log = true;
+		config->omegaRange.log = false;
 		break;
 	case 'n':
 		config->normalize = true;
diff --git a/paralellseriel.cpp b/paralellseriel.cpp
index 458675b300bf256b49344fee74b4d64e9f3c8411..b9c681cf17e28577d38431dd1c6b424f1bfd07f8 100644
--- a/paralellseriel.cpp
+++ b/paralellseriel.cpp
@@ -35,6 +35,11 @@ std::complex<fvalue> Parallel::execute(fvalue omega)
 	return std::complex<fvalue>(1,0)/accum;
 }
 
+char Parallel::getComponantChar() const
+{
+	return staticGetComponantChar();
+}
+
 Serial::Serial(std::vector<Componant*> componantsIn): componants(componantsIn)
 {
 }
@@ -67,3 +72,8 @@ std::complex<fvalue> Serial::execute(fvalue omega)
 	}
 	return accum;
 }
+
+char Serial::getComponantChar() const
+{
+	return staticGetComponantChar();
+}
diff --git a/resistor.cpp b/resistor.cpp
index eb487bcd4398c9dedd1cc5a5f60ffca731b0dccd..c83b9e2e0e48d8d4cb7c3a4fda022b78b4b98e0b 100644
--- a/resistor.cpp
+++ b/resistor.cpp
@@ -59,3 +59,8 @@ size_t Resistor::paramCount()
 {
 	return 1;
 }
+
+char Resistor::getComponantChar() const
+{
+	return staticGetComponantChar();
+}
diff --git a/test.cpp b/test.cpp
index 92a69f40f7bca4ca168db0af6d4eb055b6cf954b..a4034523f8e47237706d741dd1804148bb763d21 100644
--- a/test.cpp
+++ b/test.cpp
@@ -73,7 +73,7 @@ void printComponants(eis::Model& model)
 	eis::Log(eis::Log::DEBUG)<<"Compnants:";
 	for(eis::Componant* componant : model.getFlatComponants())
 	{
-		eis::Log(eis::Log::DEBUG)<<eis::Componant::getComponantChar(componant)<<"{";
+		eis::Log(eis::Log::DEBUG)<<componant->getComponantChar()<<"{";
 		for(size_t i = 0; i < componant->paramCount(); ++i)
 		{
 			eis::Log(eis::Log::DEBUG)<<componant->getParam()[i];
diff --git a/warburg.cpp b/warburg.cpp
index 2dd1f3aaae42cc63073e968363a4a619741e425f..c4e30f2d6f3b29cd05a7ad4f2b63e4be1c29d438 100644
--- a/warburg.cpp
+++ b/warburg.cpp
@@ -17,7 +17,7 @@ Warburg::Warburg(std::string paramStr)
 	std::vector<std::string> tokens = tokenize(paramStr, ',');
 	if(tokens.size() < 1)
 	{
-		Log(Log::WARN)<<"to few parameters in "<<__func__<<" parameter string: "<<paramStr<<'\n';
+		Log(Log::WARN)<<"to few parameters in "<<__func__<<" parameter string: "<<paramStr;
 		return;
 	}
 	else
@@ -59,3 +59,8 @@ size_t Warburg::paramCount()
 {
 	return 1;
 }
+
+char Warburg::getComponantChar() const
+{
+	return staticGetComponantChar();
+}