#include "stdafx.h"
#include "SARSatelliteSimulationAbstractCls.h"
#include <Eigen/Core>
#include <Eigen/Dense>
#include <QDebug>
#include <QFile>
#include <QDomDocument>
#include <QDateTime>
#include <QString>
#include "BaseTool.h"
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QStringList>
#include <QDebug>
#include <vector>
#include <unordered_map>
#include <qfileinfo.h>


AbstractSatelliteOribtModel::~AbstractSatelliteOribtModel()
{
}

SatelliteOribtNode AbstractSatelliteOribtModel::getSatelliteOribtNode(double& timeFromStartTime, bool& antAzAngleFlag)
{
	return SatelliteOribtNode();
}

ErrorCode AbstractSatelliteOribtModel::getSatelliteOribtNode(double& timeFromStartTime, SatelliteOribtNode& node, bool& antAzAngleFlag)
{
	return ErrorCode::VIRTUALABSTRACT;
}

ErrorCode AbstractSatelliteOribtModel::getSatelliteAntDirectNormal(SatelliteOribtNode& Rs, Vector3D& Rt, SatelliteAntDirect& antNode)
{
	return ErrorCode();
}

void AbstractSatelliteOribtModel::setSatelliteOribtStartTime(long double oribtRefrenceTime)
{
}

long double AbstractSatelliteOribtModel::getSatelliteOribtStartTime()
{
	return 0;
}



void AbstractSatelliteOribtModel::setbeamAngle(double beamAngle, bool RightLook)
{
}

void AbstractSatelliteOribtModel::setAzAngleRange(double cycletime, double minAzAngle, double maxAzAngle, double referenceAzAngle, double referenceTimeFromStartTime)
{
}

double AbstractSatelliteOribtModel::getAzAngleInCurrentTimeFromStartTime(double& currentTime)
{
	return 0.0;
}

ErrorCode AbstractSatelliteOribtModel::getAzAngleInCurrentTimeFromStartTime(double& currentTime, double& AzAngle)
{
	return ErrorCode::VIRTUALABSTRACT;
}

void AbstractSatelliteOribtModel::setAntnnaAxisX(double X, double Y, double Z)
{
}

void AbstractSatelliteOribtModel::setAntnnaAxisY(double X, double Y, double Z)
{
}

void AbstractSatelliteOribtModel::setAntnnaAxisZ(double X, double Y, double Z)
{
}

ErrorCode AbstractSatelliteOribtModel::getZeroDopplerAntDirect(SatelliteOribtNode& node)
{
	return ErrorCode();
}

ErrorCode AbstractSatelliteOribtModel::getAntnnaDirection(SatelliteOribtNode& node)
{
	return ErrorCode::VIRTUALABSTRACT;
}

double AbstractSatelliteOribtModel::getPt()
{
	return 0.0;
}

double AbstractSatelliteOribtModel::getGri()
{
	return 0.0;
}

void AbstractSatelliteOribtModel::setPt(double Pt)
{
}

void AbstractSatelliteOribtModel::setGri(double gri)
{
}

SatelliteOribtNode AbstractSARSatelliteModel::getSatelliteOribtNode(double& timeFromStartTime, bool& antAzAngleFlag)
{
	return SatelliteOribtNode();
}

ErrorCode AbstractSARSatelliteModel::getSatelliteOribtNode(double& timeFromStartTime, SatelliteOribtNode& node, bool& antAzAngleFlag)
{
	return ErrorCode();
}

ErrorCode AbstractSARSatelliteModel::getSatelliteAntDirectNormal(SatelliteOribtNode& Rs, Vector3D& Rt, SatelliteAntDirect& antNode)
{
	return ErrorCode();
}

void AbstractSARSatelliteModel::setSatelliteOribtModel(std::shared_ptr<AbstractSatelliteOribtModel>  model)
{
}

void AbstractSARSatelliteModel::setSARImageStartTime(long double imageStartTime)
{
}

void AbstractSARSatelliteModel::setSARImageEndTime(long double imageEndTime)
{
}

double AbstractSARSatelliteModel::getSARImageStartTime()
{
	return 0;
}

double AbstractSARSatelliteModel::getSARImageEndTime()
{
	return 0;
}

double AbstractSARSatelliteModel::getNearRange()
{
	return 0.0;
}

void AbstractSARSatelliteModel::setNearRange(double NearRange)
{
}


double AbstractSARSatelliteModel::getFarRange()
{
	return 0.0;
}

void AbstractSARSatelliteModel::setFarRange(double FarRange)
{
}

bool AbstractSARSatelliteModel::getIsRightLook()
{
	return false;
}

void AbstractSARSatelliteModel::setIsRightLook(bool isR)
{
}


void AbstractSARSatelliteModel::setCenterFreq(double Freq)
{
}

double AbstractSARSatelliteModel::getCenterFreq()
{
	return 0.0;
}

void AbstractSARSatelliteModel::setCenterLamda(double Lamda)
{
}

double AbstractSARSatelliteModel::getCenterLamda()
{
	return 0.0;
}

void AbstractSARSatelliteModel::setBandWidth(double bandwidth)
{
}

double AbstractSARSatelliteModel::getBandWidth()
{
	return 0.0;
}

QVector<double> AbstractSARSatelliteModel::getFreqList()
{
	double bandwidth = this->getBandWidth()/1e6; // 频率范围
	double centerFreq = this->getCenterFreq() / 1e6; // 中心频率
	double nearR = this->getNearRange();
	double farR = this->getFarRange();
	// 计算分辨率
 
	long long centerFreq_long = long long(centerFreq);
	long long bandwidth_long = long long(bandwidth);
	long long bandhalf = ceil(bandwidth_long / 2);
	long long bw = bandhalf * 2;
	double Resolution = LIGHTSPEED / 2.0/1e6 / bw;
	long freqpoints = ceil((farR - nearR) / Resolution + 1);

	Eigen::VectorXd freqs=Eigen::VectorXd::LinSpaced(freqpoints, -bandhalf, bandhalf);
	freqs = freqs.array() + 1.0 * centerFreq_long;
 
	QVector<double> freqlist(freqpoints);

	for (long i = 0; i < freqpoints; i++) {
		freqlist[i] = freqs[i]*1e6;
	}
	return freqlist;
}

void AbstractSARSatelliteModel::setRefphaseRange(double refRange)
{
}

double AbstractSARSatelliteModel::getRefphaseRange()
{
	return 0.0;
}

POLARTYPEENUM AbstractSARSatelliteModel::getPolarType()
{
	return POLARTYPEENUM();
}

void AbstractSARSatelliteModel::setPolarType(POLARTYPEENUM type)
{
}

void AbstractSARSatelliteModel::setPRF(double prf)
{
}

double AbstractSARSatelliteModel::getPRF()
{
	return 0;
}

double AbstractSARSatelliteModel::getFs()
{
	//double NearRange = this->getNearRange();
	//double FarRange = this->getFarRange();

	//QVector<double> freqpoints = this->getFreqList();
	//long freqNum = freqpoints.size();

	//double timeRange = 2 * (FarRange - NearRange) / LIGHTSPEED;
	//double fs = freqNum / timeRange;

	//return fs;
	return 0.0;
}

void AbstractSARSatelliteModel::setFs(double fs)
{
}
 
double AbstractSARSatelliteModel::getCenterLookAngle()
{
	return 0.0;
}

void AbstractSARSatelliteModel::setCenterLookAngle(double angle)
{
}

void AbstractSARSatelliteModel::setTransformRadiationPattern(std::shared_ptr<AbstractRadiationPattern> radiationPanttern)
{
}

void AbstractSARSatelliteModel::setReceiveRadiationPattern(std::shared_ptr<AbstractRadiationPattern> radiationPanttern)
{
}

std::shared_ptr<AbstractRadiationPattern> AbstractSARSatelliteModel::getTransformRadiationPattern()
{
	return std::shared_ptr<AbstractRadiationPattern>();
}

std::shared_ptr<AbstractRadiationPattern> AbstractSARSatelliteModel::getReceiveRadiationPattern()
{
	return std::shared_ptr<AbstractRadiationPattern>();
}

double AbstractSARSatelliteModel::getPt()
{
	return 0.0;
}

double AbstractSARSatelliteModel::getGri()
{
	return 0.0;
}

void AbstractSARSatelliteModel::setPt(double Pt)
{

}

void AbstractSARSatelliteModel::setGri(double gri)
{
}

double AbstractSARSatelliteModel::getDopplerParametersReferenceTime()
{
	return 0.0;
}

void AbstractSARSatelliteModel::setDopplerParametersReferenceTime(double time)
{
}

std::vector<double> AbstractSARSatelliteModel::getDopplerCentroidCoefficients()
{
	return std::vector<double>();
}

void AbstractSARSatelliteModel::setDopplerCentroidCoefficients(std::vector<double> DopplerCentroids)
{
}

std::vector<double> AbstractSARSatelliteModel::getDopplerRateValuesCoefficients()
{
	return std::vector<double>();
}

void AbstractSARSatelliteModel::setDopplerRateValuesCoefficients(std::vector<double> DopplerRateValues)
{
}


ErrorCode ReadSateGPSPointsXML(QString xmlPath, std::vector<SatelliteOribtNode>& nodes)
{
	// 读取文件
	QFile file(xmlPath);
	if (!file.open(QIODevice::ReadOnly)) {
		qDebug() << "Cannot open file for reading.";
		return ErrorCode::FILEOPENFAIL;

	}

	QDomDocument doc;
	if (!doc.setContent(&file)) {
		qDebug() << "Failed to parse the XML.";
		file.close();
		return ErrorCode::XMLPARSEFAIL;
	}
	file.close();

	QDomElement root = doc.documentElement();
	QDomNodeList gpsParamList = root.firstChildElement("GPS").elementsByTagName("GPSParam");
	nodes.clear();
	for (int i = 0; i < gpsParamList.size(); ++i) {
		QDomElement gpsParam = gpsParamList.at(i).toElement();

		QDomElement timeStampElement = gpsParam.firstChildElement("TimeStamp");
		QDomElement xPositionElement = gpsParam.firstChildElement("xPosition");
		QDomElement yPositionElement = gpsParam.firstChildElement("yPosition");
		QDomElement zPositionElement = gpsParam.firstChildElement("zPosition");
		QDomElement xVelocityElement = gpsParam.firstChildElement("xVelocity");
		QDomElement yVelocityElement = gpsParam.firstChildElement("yVelocity");
		QDomElement zVelocityElement = gpsParam.firstChildElement("zVelocity");

		if (timeStampElement.isNull() ||
			xPositionElement.isNull() || yPositionElement.isNull() || zPositionElement.isNull() ||
			xVelocityElement.isNull() || yVelocityElement.isNull() || zVelocityElement.isNull()) {
			nodes.clear();
			return ErrorCode::XMLNOTFOUNDElEMENT;

		}

		QString timeStamp = timeStampElement.text();
		QString xPosition = xPositionElement.text();
		QString yPosition = yPositionElement.text();
		QString zPosition = zPositionElement.text();
		QString xVelocity = xVelocityElement.text();
		QString yVelocity = yVelocityElement.text();
		QString zVelocity = zVelocityElement.text();

		// 转换

		long double timestamp = convertToMilliseconds(timeStamp.toStdString());
		SatelliteOribtNode node;
		node.time = timestamp;
		node.Px = xPosition.toDouble();
		node.Py = yPosition.toDouble();
		node.Pz = zPosition.toDouble();
		node.Vx = xVelocity.toDouble();
		node.Vy = yVelocity.toDouble();
		node.Vz = zVelocity.toDouble();

		nodes.push_back(node);
	}


	qDebug() << "---  GPS Node Extracted -----------------------------------------------------------";
	qDebug() << "time\tPx\tPy\tPz\tVx\tVy\tVz";
	for (int i = 0; i < nodes.size(); ++i) {
		SatelliteOribtNode node = nodes[i];
		// 打印解译结果
		qDebug() << (double)node.time << "\t" << node.Px << "\t" << node.Py << "\t" << node.Pz << "\t" << node.Vx << "\t" << node.Vy << "\t" << node.Vz;

	}
	qDebug() << "\n\n\n";

	return ErrorCode::SUCCESS;
}

std::vector<SatelliteOribtNode> FilterSatelliteOribtNode(std::vector<SatelliteOribtNode>& nodes, double startTime, double endTime, long minCount)
{
	if (minCount < nodes.size()) {
		return std::vector<SatelliteOribtNode>(0);
	}
	else {}

	std::vector<double> dtime(nodes.size());
	double centerTime = startTime + (endTime - startTime) / 2.0;


	// 排序 小 --> 大
	std::sort(nodes.begin(), nodes.end(), [](SatelliteOribtNode& a, SatelliteOribtNode& b) {
		return a.time < b.time;
		});



	// 计算插值
	for (long i = 0; i < nodes.size(); i++) {
		dtime[i] = std::abs(nodes[i].time - centerTime);
	}

	// find min value idx
	long minIdx = 0;
	double min = dtime[0];
	for (long i = 1; i < nodes.size(); i++) {
		if (dtime[i] < min) {
			min = (dtime[i]);
			minIdx = i;
		}
		else {}
	}
	std::vector<SatelliteOribtNode> result(0);
	// 左右查找
	long left = minIdx;
	long right = minIdx + 1;
	while (left >= 0 || right < nodes.size()) {
		// 左右检索
		if (left >= 0) {
			result.push_back(nodes[left]);
		}
		else {}
		left--;

		if (right < nodes.size()) {
			result.push_back(nodes[right]);
		}
		else {}
		right++;

		if (result.size() > minCount) {
			break;
		}
	}

	return result;
}

std::shared_ptr<AbstractRadiationPattern> CreateAbstractRadiationPattern(std::vector<RadiationPatternGainPoint> antPatternPoints)
{
	std::shared_ptr<AbstractRadiationPattern> pattern(new AbstractRadiationPattern);
	for (long i = 0; i < antPatternPoints.size(); i++) {
		pattern->setGain(antPatternPoints[i].theta, antPatternPoints[i].phi, antPatternPoints[i].GainValue);

	}
	pattern->RecontructGainMatrix();
	return pattern;
}

std::vector<RadiationPatternGainPoint> ReadGainFile(QString antPatternFilePath)
{
	std::vector<RadiationPatternGainPoint> dataPoints(0);
	//std::vector<std::string> dataPoints;

	if (!QFileInfo(antPatternFilePath).exists()) {
		return dataPoints;
	}
	std::string filepath = antPatternFilePath.toLocal8Bit().constData();
	qDebug() << "ant file path:\t" << QString::fromStdString(filepath);

	std::ifstream file(filepath);

	if (!file.is_open()) {
		std::cerr << "Failed to open the file." << std::endl;
		return dataPoints; // 返回空向量
	}
	file.seekg(0);
	std::string headerline;
	std::getline(file, headerline); // 读取标题行
	std::vector<std::string> headers;
	std::stringstream ss(headerline);
	std::string header;

	while (std::getline(ss, header, ',')) {
		headers.push_back(header);
	}

	qDebug() << "Headers:";
	for (const auto& h : headers) {
		qDebug() << " " << QString::fromStdString(h);
	}
 
	if (headers.size() < 3) {
		file.close();
		return dataPoints; // 返回空向量
	}

	qDebug() << "Parse ant radiation pattern contains "  ;

	long theta_id = -1;
	long phi_id = -1;
	long gain_id = -1;

	// 查找 'theta', 'phi', 'gain' 字段
	for (size_t i = 0; i < headers.size(); ++i) {
		std::string header_lower = headers[i];
		std::transform(header_lower.begin(), header_lower.end(), header_lower.begin(), ::tolower);

		if (header_lower.find("theta") != std::string::npos) {
			theta_id = i;
		}
		else if (header_lower.find("phi") != std::string::npos) {
			phi_id = i;
		}
		else if (header_lower.find("gain") != std::string::npos) {
			gain_id = i;
		}
	}

	if (theta_id == -1 || phi_id == -1 || gain_id == -1) {
		std::cerr << "Failed to find the field." << std::endl;
		file.close();
		return dataPoints; // 返回空向量
	}

	std::vector<std::string> lines(0);
	// 读取数据行
	std::string line;
	while (std::getline(file, line)) {
		if (line.empty()) {
			break;
		}
		lines.push_back(line);
	}

	qDebug() << "Read file over"  ;
	file.close();



	dataPoints = std::vector< RadiationPatternGainPoint>(lines.size());
	for (long ii = 0; ii < dataPoints.size(); ii++) {
		line = lines[ii];
		QStringList fields = QString::fromStdString(line).split(",");
		if (fields.size() >= 3) {
			if (fields[0].isEmpty()) {
				continue;
			}
			RadiationPatternGainPoint point{ 0,0,0 };
			bool thetaflag = false;
			bool phiflag = false;
			bool gainflag = false;
			point.theta = fields[theta_id].toDouble(&thetaflag); // 这里存在风险，如果数据不是数字，会导致程序崩溃
			point.phi = fields[phi_id].toDouble(&phiflag);
			point.GainValue = fields[gain_id].toDouble(&gainflag);
			if (!(thetaflag && phiflag && gainflag)) {
				file.close();
				return std::vector< RadiationPatternGainPoint>(0);
			}
			// 角度转换为 -180 ~ 180  -- 废弃角度
			//point.theta = point.theta > 180 ? point.theta - 360 : point.theta;
			//point.phi = point.phi > 180 ? point.phi - 360 : point.phi;

			dataPoints[ii] = point;
		}
		else {}
	}

	lines.clear();
	//lines.swap(std::vector<std::string>(0));

	return dataPoints;
}

double getDopplerCenterFreq(double& lamda, double& R, Vector3D& Rs, Vector3D& Rt, Vector3D& Vs, Vector3D& Vt)
{
	return (-2 / lamda) * dot(Rs - Rt, Vs - Vt) / R; // 星载合成孔径雷达原始回波数据模拟研究 3.18
}

double getDopplerFreqRate(double& lamda, double& R, Vector3D& Rs, Vector3D& Rt, Vector3D& Vs, Vector3D& Vt, Vector3D& Ast)
{
	return -(2 / lamda) * (dot(Vs - Vt, Vs - Vt) / R + dot(Ast, Rs - Rt) / R - std::pow(dot(Vs - Vt, Rs - Rt), 2) / std::pow(R, 3));// 星载合成孔径雷达原始回波数据模拟研究 3.19
}


AbstractRadiationPattern::AbstractRadiationPattern()
{
	this->GainMap = std::vector<RadiationPatternGainPoint>(0);
	this->thetas = std::vector<double>(0);
	this->phis = std::vector<double>(0);
	this->GainMatrix = Eigen::MatrixXd(0, 0);
}

AbstractRadiationPattern::~AbstractRadiationPattern()
{
}

double AbstractRadiationPattern::getGain(double theta, double phi)
{
	double gainValue = 0;
	ErrorCode state = getGain(theta, phi, gainValue);
	return gainValue;
}

std::vector<RadiationPatternGainPoint> AbstractRadiationPattern::getGainList()
{
	return this->GainMap;
}

ErrorCode AbstractRadiationPattern::getGain(double& theta, double& phi, double& GainValue)
{
	if (this->mintheta > theta || this->maxtheta<theta || this->minphi>phi || this->maxphi < phi) {
		GainValue = 0;
		return ErrorCode::OUTOFRANGE;
	}


	// 插值计算增益
	if (this->GainMap.size() == 0) { // 原始增益
		GainValue = 1;
	}
	else {
		// --双线性插值
		if (this->GainMatrix.rows() != this->thetas.size() || this->GainMatrix.cols() != this->phis.size()) {
			return ErrorCode::OUTOFRANGE;
		}

		// 考虑根据双线性采样方法
		long lasttheta = FindValueInStdVectorLast(this->thetas, theta);
		long nextTheta = lasttheta + 1;
		long lastphi = FindValueInStdVectorLast(this->phis, phi);;
		long nextPhi = lastphi + 1;

		if (lasttheta == -1 || nextTheta == -1 || lastphi == -1 || nextPhi == -1) {
			return ErrorCode::FIND_ID_ERROR;
		}
		double x1 = this->thetas[lasttheta];
		double x2 = this->thetas[nextTheta];
		double y1 = this->phis[lastphi];
		double y2 = this->phis[nextPhi];
		//double z11 = this->GainMatrix(lasttheta, lastphi);//std::pow(10,this->GainMatrix(lasttheta, lastphi)/10);
		//double z12 = this->GainMatrix(lasttheta, nextPhi);//std::pow(10,this->GainMatrix(lasttheta, nextPhi)/10);
		//double z21 = this->GainMatrix(nextTheta, lastphi);//std::pow(10,this->GainMatrix(nextTheta, lastphi)/10);
		//double z22 = this->GainMatrix(nextTheta, nextPhi);//std::pow(10,this->GainMatrix(nextTheta, nextPhi)/10);
		//double z11 = std::pow(10, this->GainMatrix(lasttheta, lastphi) / 10);
		//double z12 = std::pow(10, this->GainMatrix(lasttheta, nextPhi) / 10);
		//double z21 = std::pow(10, this->GainMatrix(nextTheta, lastphi) / 10);
		//double z22 = std::pow(10, this->GainMatrix(nextTheta, nextPhi) / 10);

		double z11 =  this->GainMatrix(lasttheta, lastphi) ;
		double z12 =  this->GainMatrix(lasttheta, nextPhi) ;
		double z21 =  this->GainMatrix(nextTheta, lastphi) ;
		double z22 =  this->GainMatrix(nextTheta, nextPhi) ;




		double x = theta;
		double y = phi;
		GainValue = (z11 * (x2 - x) * (y2 - y)
			+ z21 * (x - x1) * (y2 - y)
			+ z12 * (x2 - x) * (y - y1)
			+ z22 * (x - x1) * (y - y1));
		GainValue = GainValue / ((x2 - x1) * (y2 - y1));
		//GainValue = 10.0 * std::log10(GainValue); // 返回dB
		//qDebug() << "GainValue:" << GainValue << " " << lasttheta << " " << nextTheta << " " << lastphi << " " << nextPhi << " " << z11 << " " << z12 << " " << z21 << " " << z22;
		ErrorCode::SUCCESS;
	}


	return ErrorCode::SUCCESS;
}

ErrorCode AbstractRadiationPattern::getGainLinear(double& theta, double& phi, double& GainValue)
{
	ErrorCode statecode = this->getGain(theta, phi, GainValue);
	if (statecode == ErrorCode::OUTOFRANGE) {
		GainValue = 0;
		return ErrorCode::SUCCESS;
	}
	else {
		return statecode;
	}


}

double AbstractRadiationPattern::getGainLearThetaPhi(double theta, double phi)
{
	double gainvlaue = 0;
	this->getGainLinear(theta, phi, gainvlaue);
	return gainvlaue;
}

ErrorCode AbstractRadiationPattern::setGain(double theta, double phi, double GainValue)
{
	this->GainMap.push_back(RadiationPatternGainPoint{ theta,phi,GainValue });
	return ErrorCode::SUCCESS;
}


/*
* 重构天线方向图矩阵
* 这个函数存在堆溢出问题，与2024年12月19日重写
* 根据阈值计算方位向扫描角的范围，注意这里以dB为单位，选择phi=0 时（即飞行方向，求解不同theta的最大增益）
*/
ErrorCode AbstractRadiationPattern::RecontructGainMatrix(double threshold)
{
	this->thetas.clear();
	this->phis.clear();


	for (long i = 0; i < this->GainMap.size(); i++) {
		double thetatempp = this->GainMap[i].theta;
		double phitempp = this->GainMap[i].phi;
		InsertValueInStdVector(this->thetas, this->GainMap[i].theta, false);
		InsertValueInStdVector(this->phis, this->GainMap[i].phi, false);
	}

	this->GainMatrix = Eigen::MatrixXd::Zero(this->thetas.size(), this->phis.size());
	for (long i = 0; i < this->GainMap.size(); i++) {
		long theta_idx = FindValueInStdVector(this->thetas, this->GainMap[i].theta);
		long phi_idx = FindValueInStdVector(this->phis, this->GainMap[i].phi);
		if (theta_idx == -1 || phi_idx == -1||theta_idx<0||phi_idx<0||theta_idx>=this->thetas.size()||phi_idx>=this->phis.size()) {
			qDebug() << "Error: RecontructGainMatrix failed";
			return ErrorCode::FIND_ID_ERROR;
		}
		this->GainMatrix(theta_idx, phi_idx) = this->GainMap[i].GainValue;
	}
	// double mintheta, maxtheta, minphi, maxphi;
	this->mintheta = this->thetas[0];
	this->maxtheta = this->thetas[this->thetas.size() - 1];
	this->minphi = this->phis[0];
	this->maxphi = this->phis[this->phis.size() - 1];

	long thetanum = this->thetas.size();
	long phinum = this->phis.size();

	Eigen::VectorXd thetapoints = linspace(mintheta, maxtheta, thetanum);
	Eigen::VectorXd phipoints = linspace(minphi, maxphi, phinum);
	
	Eigen::MatrixXd gaintemp = Eigen::MatrixXd::Zero(thetanum, phinum);
	qDebug() << "gain init" ;
	for (long i = 0; i < thetanum; i++) {
		for (long j = 0; j < phinum; j++) {
			gaintemp(i, j) = this->getGain(thetapoints[i], phipoints[j]);
		}
	}

	this->GainMatrix = Eigen::MatrixXd::Zero(thetanum, phinum);

	for (long i = 0; i < thetanum; i++) {
		for (long j = 0; j < phinum; j++) {
			this->GainMatrix(i, j) = gaintemp(i, j);
		}
	}


	this->thetas.clear();
	for (long i = 0; i < thetanum; i++) {
		this->thetas.push_back(thetapoints[i]);
	}

	this->phis.clear();
	for (long i = 0; i < phinum; i++) {
		this->phis.push_back(phipoints[i]);
	}

	return ErrorCode::SUCCESS;
}

std::vector<double> AbstractRadiationPattern::getThetas()
{
	return this->thetas;
}

std::vector<double> AbstractRadiationPattern::getPhis()
{
	return this->phis;
}

Eigen::MatrixXd AbstractRadiationPattern::getGainMatrix()
{
	return this->GainMatrix;
}

double AbstractRadiationPattern::getMaxTheta()
{
	double maxtheta = this->thetas[0];
	long len = this->thetas.size();
	if (maxtheta < this->thetas[len - 1]) {
		maxtheta = this->thetas[len - 1];
	}
	return maxtheta;
}

double AbstractRadiationPattern::getMinTheta()
{
	double mintheta = this->thetas[0];
	long len = this->thetas.size();
	if (mintheta > this->thetas[len - 1]) {
		mintheta = this->thetas[len - 1];
	}
	return mintheta;

	return 0.0;
}

double AbstractRadiationPattern::getMaxPhi()
{
	double maxphi = this->phis[0];
	long len = this->phis.size();
	if (maxphi < this->phis[len - 1]) {
		maxphi = this->phis[len - 1];
	}
	return maxphi;
	return 0.0;
}

double AbstractRadiationPattern::getMinPhi()
{
	double minphi = this->phis[0];
	long len = this->phis.size();
	if (minphi > this->phis[len - 1]) {
		minphi = this->phis[len - 1];
	}
	return minphi;
	return 0.0;
}