#include "SARImage/FEKOBaseToolClass.h"
#include <math.h>
#include "BaseToolLib/BaseConstVariable.h"
#include <QMessageBox>
#include <math.h>
#include <complex>
#include "BaseToollib/ImageOperatorBase.h"
#include <SARBaseToolLib/SARImageBase.h>
#include "SARBaseToolLib/SARBaseTool.h"
#include "BaseToollib/FileOperator.h"
#include <QtXml/qdom.h>









QString FEKOBase::FEKOImageModeenumToString(FEKOBase::FEKOImageMode mode)
{
	switch (mode) {
	case Strip:
		return "STRIP";
	case Scane:
		return "SCANE";
	case ISAR:
		return "ISAR";
	case CircleSAR:
		return "CircleSAR";
	}
	// 如果枚举值不匹配任何字符串，则返回一个默认值，或者抛出异常
	return "UNKNOW"; // 默认返回Unknown
}

FEKOBase::FEKOCoordinateSystem FEKOBase::FEKOCoordinateSystemString2Enum(QString str)
{
	if (str.toUpper() == "SPHERICAL") { return FEKOBase::Spherical; }
	else if (str.toUpper() == "CARTESIAN") { return FEKOBase::Cartesian; }
	else {
		return FEKOBase::UNKONWFEKOCOORDINATESYSTEM;
	}
 
}

QString FEKOBase::QString2FEKOCoordinateSystem(FEKOBase::FEKOCoordinateSystem mode)
{
	switch (mode) {
	case FEKOBase::Spherical:
		return "SPHERICAL";
	case FEKOBase::Cartesian:
		return "CARTESIAN";
	default:
		return "UNKONWFEKOCOORDINATESYSTEM";
	
	}	
}

FEKOBase::FEKOImageMode FEKOBase::FEKOImageModeString2Enum(QString str)
{
	if (str.toUpper() == "STRIP") {
		return FEKOBase::FEKOImageMode::Strip;
	}
	else if (str.toUpper() == "SCANE") {
		return FEKOBase::FEKOImageMode::Scane;
	}
	else if (str.toUpper() == "ISAR") {
		return FEKOBase::FEKOImageMode::ISAR;
	}
	else if (str.toUpper() == "CIRCLESAR") {
		return FEKOBase::FEKOImageMode::CircleSAR;
	}
	// 如果输入的字符串不匹配任何枚举值，则返回一个默认值，或者抛出异常
	return FEKOBase::FEKOImageMode::UNKNOW; // 默认返回UNKNOW 
}

FEKOBase::freqParams FEKOBase::getFreqSetting(double centerFreq, double resolution, double bandWidth, double scenceRange, bool isResolution) {

	FEKOBase::freqParams result{ 0,0,0 };
	{
		if (isResolution) {
			bandWidth = 0.299792458 / 2 / resolution; // 计算带宽
		}
		else {
			resolution = 0.299792458 / 2 / bandWidth; // 计算分辨率
		}
	}
	size_t samplePoint = std::ceil((scenceRange) / resolution) + 1;
	result.startfreqs = centerFreq - 0.5 * bandWidth;
	result.endfreqs = centerFreq + 0.5 * bandWidth;
	result.freqpoint = samplePoint;
	return result;
}

FEKOBase::FEKOSatelliteParams FEKOBase::createFEKOSatelliteParams(double Px, double Py, double Pz, double Vx, double Vy, double Vz, double incidenceAngle, double AzAngle, double theta, double phi, bool isRight, size_t PRFIdx)
{
	FEKOBase::FEKOSatelliteParams result{
		PRFIdx,
		FEKOBase::SatelliteState{
			FEKOBase::SatellitePosition{Px,Py,Pz},
			FEKOBase::SatelliteVelocity{Vx,Vy,Vz}
				},
		incidenceAngle,AzAngle,
		FEKOBase::FEKOantPitionDirect{Px,Py,Pz,theta,phi},
		isRight
	};
	return result;
}

FEKOBase::FEKOSatelliteParams FEKOBase::createFEKOSatelliteParams(SatelliteState pose, double incidenceAngle, double AzAngle, FEKOantPitionDirect antpos, size_t PRFIdx)
{
	FEKOBase::FEKOSatelliteParams result{
		PRFIdx,pose,incidenceAngle,AzAngle,antpos
	};
	return result;
}

FEKOBase::SatelliteState FEKOBase::FEKOSatelliteParams2SatelliteState(FEKOSatelliteParams parmas)
{
	return parmas.pose;
}

FEKOBase::FEKOantPitionDirect FEKOBase::FEKOSatelliteParams2FEKOantPitionDirect(FEKOSatelliteParams parmas)
{
	return parmas.antpos;
}

TopoDS_Shape FEKOBase::SatellitePos2FEKOAntPos(SatelliteState satepos, double incidenceAngle, double AzAngle, bool isRIGHT, FEKOantPitionDirect* antposition_Direct, TopoDS_Shape antModel)
{
	incidenceAngle = incidenceAngle * M_PI / 180; // 转换为弧度
	AzAngle = AzAngle * M_PI / 180; // 扫描角度转换为弧度
	TopoDS_Shape tempShape;
	if (!antModel.IsNull()) {
		// 创建一个复制
		BRepBuilderAPI_Copy copyBuilder(antModel);
		tempShape = copyBuilder.Shape();
	}

	double Sx = satepos.pos.Px;
	double Sy = satepos.pos.Py;
	double Sz = satepos.pos.Pz;
	double Vx = satepos.vel.Vx;
	double Vy = satepos.vel.Vy;
	double Vz = satepos.vel.Vz;
	//qDebug() << u8"// 0. 卫星状态矢量";
	gp_Vec SateVelocity(gp_Pnt(0, 0, 0), gp_Pnt(Vx, Vy, Vz)); // 卫星速度矢量
	gp_Vec SatePosition(gp_Pnt(0, 0, 0), gp_Pnt(Sx, Sy, Sz)); // 卫星位置矢量
	gp_Vec sch_X(gp_Pnt(0, 0, 0), gp_Pnt(1.0, 0.0, 0.0));
	gp_Vec sch_Y(gp_Pnt(0, 0, 0), gp_Pnt(0.0, 1.0, 0.0));  // 飞行方向 y
	gp_Vec sch_Z(gp_Pnt(0, 0, 0), gp_Pnt(0.0, 0.0, 1.0)); // 雷达照射方向

//	qDebug() << u8"// 1. 卫星坐标系 sch -->飞行坐标系 fly 保证Z轴指向不变化";
	gp_Vec sch_X_fly;
	gp_Vec sch_Y_fly; // 飞行向
	gp_Vec sch_Z_fly;

	{
		CartesianCoordinates Sp_car{ sch_Y.X(),sch_Y.Y(), sch_Y.Z() };
		CartesianCoordinates tp_car{ SateVelocity.X(),SateVelocity.Y(), SateVelocity.Z() };

		SphericalCoordinates sp_sph = cartesianToSpherical(Sp_car);
		SphericalCoordinates tp_sph = cartesianToSpherical(tp_car);

		// 计算
		double delta_theta = tp_sph.theta - sp_sph.theta;
		double delta_phi = tp_sph.phi - sp_sph.phi;

		gp_Trsf rotationTransform_theta;
		rotationTransform_theta.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 1, 0)), delta_theta);  // 绕 y 轴旋转
		sch_X_fly = sch_X.Transformed(rotationTransform_theta);
		sch_Y_fly = sch_Y.Transformed(rotationTransform_theta);
		sch_Z_fly = sch_Z.Transformed(rotationTransform_theta);

		gp_Trsf rotationTransform_phi;
		rotationTransform_phi.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)), delta_phi);  // 绕 z 轴旋转
		sch_X_fly = sch_X_fly.Transformed(rotationTransform_phi);
		sch_Y_fly = sch_Y_fly.Transformed(rotationTransform_phi);
		sch_Z_fly = sch_Z_fly.Transformed(rotationTransform_phi);

		if (!tempShape.IsNull()) {
			BRepBuilderAPI_Transform shapeTransform_theta(tempShape, rotationTransform_theta);
			tempShape = shapeTransform_theta.Shape();
			BRepBuilderAPI_Transform shapeTransform_phi(tempShape, rotationTransform_phi);
			tempShape = shapeTransform_phi.Shape();
		}
	}

//	qDebug() << u8"// 2. 根据方位角与俯仰角，调整雷达姿态 --- 此步确定 Y 轴已经调整完毕 ";
//	qDebug() << u8"// 2. a 根据 incidenceAngle 调整 Z 的指向，需要先根据左右视判断出雷达照射方向";

	{	// 按照 Y 轴进行计算
		incidenceAngle = M_PI - incidenceAngle;  // 下Z轴
		Standard_Real ZRotation_angle = 0;
		if (isRIGHT) { // 右视 + 
			ZRotation_angle = incidenceAngle;
		}
		else { // 左视 - 
			ZRotation_angle = -1 * incidenceAngle;
		}
		gp_Trsf fly_incidence_trsf;
		fly_incidence_trsf.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), sch_Y_fly), ZRotation_angle); // 计算入射角

		sch_X_fly = sch_X_fly.Transformed(fly_incidence_trsf);
		sch_Y_fly = sch_Y_fly.Transformed(fly_incidence_trsf);
		sch_Z_fly = sch_Z_fly.Transformed(fly_incidence_trsf); // 此时获取雷达的照射方向

		if (!tempShape.IsNull()) {
			BRepBuilderAPI_Transform shapeTransform_incidence(tempShape, fly_incidence_trsf); 	//  fly_Z --> incidenceAngle 
			tempShape = shapeTransform_incidence.Shape();
		}

	}

//	qDebug() << u8"// 2.b 根据 AzAngle 调整 Z 的指向 ";
//	qDebug() << u8"// Az 应该变化在  YoZ， 也就是绕 X 轴 旋转；";

	{ // 沿Z 轴进行计算
		gp_Trsf fly_AZ_trsf;
		fly_AZ_trsf.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), sch_X_fly), AzAngle); // 计算方位角变化

		sch_X_fly = sch_X_fly.Transformed(fly_AZ_trsf);
		sch_Y_fly = sch_Y_fly.Transformed(fly_AZ_trsf);
		sch_Z_fly = sch_Z_fly.Transformed(fly_AZ_trsf); // 此时获取雷达的照射方向

		if (!tempShape.IsNull()) {
			BRepBuilderAPI_Transform shapeTransform_AZ(tempShape, fly_AZ_trsf); 	//  fly_Z --> incidenceAngle
			tempShape = shapeTransform_AZ.Shape(); // 旋转卫星模型
		}

	}
//	qDebug() << u8"// 2.c 参数记录 ";
	{
		CartesianCoordinates Sp_car{ 0,0,1 };
		CartesianCoordinates tp_car{ sch_Z_fly.X(),sch_Z_fly.Y(), sch_Z_fly.Z() };

		SphericalCoordinates sp_sph = cartesianToSpherical(Sp_car);
		SphericalCoordinates tp_sph = cartesianToSpherical(tp_car); // 计算phi角度

		double delta_theta = tp_sph.theta - sp_sph.theta;
		double delta_phi = tp_sph.phi - sp_sph.phi;

		antposition_Direct->x = Sx; //-- FEKO  设置 
		antposition_Direct->y = Sy; //-- FEKO  设置
		antposition_Direct->z = Sz; //-- FEKO  设置
		antposition_Direct->theta = delta_theta / M_PI * 180; //-- FEKO 设置 theta
		antposition_Direct->phi = delta_phi / M_PI * 180;//--- FEKO 设置 phi

	}
//	qDebug() << u8"//3. 执行模型平移";
	{
		if (!tempShape.IsNull()) {
			gp_Trsf fly_move_trsf;
			fly_move_trsf.SetTranslation(SatePosition);
			BRepBuilderAPI_Transform shapeTransform_move(tempShape, fly_move_trsf); 	//  fly_Z --> incidenceAngle
			tempShape = shapeTransform_move.Shape(); // 平移卫星模型	

		}
	}

	qDebug() << QString(u8"雷达坐标与姿态（X,Y,Z,theta,phi): （%1,%2,%3,%4,%5)").arg(antposition_Direct->x)
		.arg(antposition_Direct->y)
		.arg(antposition_Direct->z)
		.arg(antposition_Direct->theta)
		.arg(antposition_Direct->phi);

	return tempShape;
}

bool FEKOBase::compareElectricFieldDataInFreq(const ElectricFieldData& a, const ElectricFieldData& b)
{
	return a.frequency < b.frequency;
}

bool FEKOBase::comparePRFPluseDataInPRFIdx(const PRFPluseData& a, const PRFPluseData& b)
{
	return a.prfidx < b.prfidx;
}
 
FEKOBase::NearFieldEchoCSVParser::NearFieldEchoCSVParser()
{
}

FEKOBase::NearFieldEchoCSVParser::~NearFieldEchoCSVParser()
{
}

bool FEKOBase::NearFieldEchoCSVParser::checkPRFModel()
{

	qDebug() << u8"正在检查是否可以采用脉冲计数模式 configuration Name  ：PRF_{脉冲计数}";

	QRegExp regex("(\\d+)");
	// 判断是否需要按照脉冲次序排序
	bool usePRFbool = true;
	QMap<QString, size_t> configName_prfidx;
	// 使用迭代器遍历 QMap
	QMap<QString, std::vector<ElectricFieldData>>::const_iterator it;
	for (it = this->electricFieldDataList.constBegin(); it != this->electricFieldDataList.constEnd(); ++it) {
		for (size_t i = 0; i < this->electricFieldDataList[it.key()].size(); i++) {
			QString value = this->electricFieldDataList[it.key()][i].configurationName;
			if (value.indexOf("PRF") != -1) {
				if (regex.indexIn(value) != -1) {
					// 提取匹配到的部分
					QString matchedText = regex.cap(1);

					size_t PRFidx = matchedText.toInt(&usePRFbool);
					if (usePRFbool) {
						configName_prfidx.insert(this->electricFieldDataList[it.key()][i].configurationName, PRFidx);
					}
					else {
						qDebug() << u8"不能采用脉冲计数模型";
						QMessageBox::information(nullptr, u8"警告", u8"无法根据Configuration Name识别脉冲顺序，按照读取顺序，计数PRF", QMessageBox::Ok);
						this->usePRFCountMode = false;
						return false;
					}
				}
			}
			else {
				qDebug() << u8"不能采用脉冲计数模型";
				QMessageBox::information(nullptr, u8"警告", u8"无法根据Configuration Name识别脉冲顺序，按照读取顺序，计数PRF", QMessageBox::Ok);
				this->usePRFCountMode = false;
				return false;
			}
		}
	}

	// 更新prfidx
	for (it = this->electricFieldDataList.constBegin(); it != this->electricFieldDataList.constEnd(); ++it) {
		if (!(this->electricFieldDataList[it.key()].size() > 0)) {
			QMessageBox::warning(nullptr, u8"错误", u8"发现空脉冲：" + it.key());
			qWarning() << u8"发现空脉冲：" + it.key();
			return false;
		}
		else {}

		QString value = this->electricFieldDataList[it.key()][0].configurationName;

		for (size_t i = 0; i < this->electricFieldDataList[it.key()].size(); i++) {
			if (value != this->electricFieldDataList[it.key()][0].configurationName) {
				QMessageBox::warning(nullptr, u8"错误", u8"脉冲解析错误，名称不一致：" + it.key() + " | " + value);
				qWarning() << u8"脉冲解析错误，名称不一致：" + it.key() + " | " + value;
			}
			else {}
			size_t tempprfidx = configName_prfidx[value];
			this->electricFieldDataList[it.key()][i].prfidx = tempprfidx;
		}
	}

	qDebug() << u8"结束检查是否可以采用脉冲计数模式 configuration Name  ：PRF_{脉冲计数}";
	return true;
}

bool FEKOBase::NearFieldEchoCSVParser::resizePRFPluse()
{
	qDebug() << u8"根据数据文件，重新整理成脉冲形式";

	QMap<QString, PRFPluseData> prfPluseMap; // 采用字典映射方式

	qDebug() << u8"QMap<QString, std::vector<ElectricFieldData>>   ==>    QMap<QString, PRFPluseData>";
	double px; // 2. 计算姿态，近场点坐标
	double py;
	double pz;
	double R;
	double theta; // x0y
	double phi; // y0z
	size_t PRFidx;

	for (QMap<QString, std::vector<ElectricFieldData>>::const_iterator it = this->electricFieldDataList.constBegin(); it != this->electricFieldDataList.constEnd(); ++it) {
		PRFPluseData temp;
		std::vector<ElectricFieldData> tempData = this->electricFieldDataList[it.key()]; // 脉冲已经排序号
		std::sort(tempData.begin(), tempData.end(), compareElectricFieldDataInFreq);
		temp.electricFieldDataList = tempData; // 按照脉冲排序

		temp.freqstart = tempData[0].frequency; // 1. 频率
		temp.freqend = tempData[tempData.size() - 1].frequency;
		temp.freqpoints = tempData.size();

		px = tempData[0].origin.x; // 2. 近场接收点计算姿态，近场点坐标
		py = tempData[0].origin.y;
		pz = tempData[0].origin.z;
		

		R = tempData[0].radius;
		theta = tempData[0].theta; // x0y
		phi = tempData[0].phi; // y0z
		



		PRFidx = tempData[0].prfidx;
		qDebug() << u8"分析姿态:" + it.key();
		for (size_t i = 0; i < tempData.size(); i++) {
			if (abs(px - tempData[i].origin.x) > 0.001 || abs(py - tempData[i].origin.y) > 0.001 ||
				abs(pz - tempData[i].origin.z) > 0.001 || abs(R - tempData[i].radius) > 0.001 ||
				abs(theta - tempData[i].theta) > 0.001 || abs(phi - tempData[i].phi) > 0.001)
			{
				qDebug() << u8"发现 configuration Name:" + it.key() + u8" , 发现问题，请检查";
				QMessageBox::warning(nullptr, u8"警告", u8"发现 configuration Name:" + it.key() + u8" , 发现问题，请检查");
				return false;
			}
			else {}
		}
		// 计算增量 R, theta, phi ==> delta_R,delta_theta,delta_phi
		theta = theta * M_PI / 180;
		phi = phi * M_PI / 180;

		px = px + R * std::sin(theta) * std::cos(phi);
		py = py + R * std::sin(theta) * std::sin(phi);
		pz = pz + R * std::cos(theta);

		temp.px = px;
		temp.py = py;
		temp.pz = pz;
		temp.prfidx = PRFidx;


		prfPluseMap.insert(it.key(), temp);
	}


	qDebug() << u8"判断是所有回波均一性";
	this->prfData = std::vector<PRFPluseData>(0);
	size_t freqpointnum = prfPluseMap.first().freqpoints;
	for (QMap<QString, PRFPluseData>::const_iterator it = prfPluseMap.constBegin(); it != prfPluseMap.constEnd(); ++it) {
		if (it.value().freqpoints != freqpointnum) {
			qDebug() << u8"回波数据频点数不一致，无法进行脉冲计数";
			QMessageBox::information(nullptr, u8"警告", u8"回波数据频点数不一致，无法进行脉冲计数", QMessageBox::Ok);
			this->usePRFCountMode = false;
			return false;
		}
		this->prfData.push_back(it.value());
	}
	this->freqPoints = freqpointnum;
	std::sort(this->prfData.begin(), this->prfData.end(), comparePRFPluseDataInPRFIdx);

	this->freqStart = this->prfData[0].freqstart;
	this->freqEnd = this->prfData[0].freqend;
	qDebug() << u8"根据数据文件，结束整理成脉冲形式";
	return true;

}

bool FEKOBase::NearFieldEchoCSVParser::parseCSV(const QString& filePath)
{

	std::vector<ElectricFieldData> dataList;

	QFile file(filePath);
	if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
		QTextStream in(&file);

		// 读取标题行
		QString headerLine = in.readLine();
		QStringList headers = headerLine.split(QRegularExpression(",(?!\\s)"));

		while (!in.atEnd()) {
			QString line = in.readLine();

			QStringList fields = line.split(QRegularExpression(",(?!\\s)"));

			ElectricFieldData data;
			// 解析数据根据列名
			for (int i = 0; i < headers.size(); ++i) {
				QString header = headers[i].trimmed();
				QString value = fields[i];// .trimmed();

				if (header == "File Type") {
					data.fileType = value;
				}
				else if (header == "File Format") {
					data.fileFormat = value;
				}
				else if (header == "Source") {
					data.source = value;
				}
				else if (header == "Date") {
					data.date = value;
				}
				else if (header == "Radius") { // 半径
					data.radius = value.toDouble();
				}
				else if (header == "Theta") { // theta 角
					data.theta = value.toDouble();
				}
				else if (header == "Phi") {// phi 角
					data.phi = value.toDouble();
				}
				else if (header == "Re(Er)") {
					data.reEr = value.toDouble();
				}
				else if (header == "Im(Er)") {
					data.imEr = value.toDouble();
				}
				else if (header == "Re(Etheta)") {
					data.reEtheta = value.toDouble();
				}
				else if (header == "Im(Etheta)") {
					data.imEtheta = value.toDouble();
				}
				else if (header == "Re(Ephi)") {
					data.reEphi = value.toDouble();
				}
				else if (header == "Im(Ephi)") {
					data.imEphi = value.toDouble();
				}
				else if (header == "Configuration Name") { // 脉冲次序名称
					data.configurationName = value.trimmed();
				}
				else if (header == "Request Name") {
					data.requestName = value.trimmed();
				}
				else if (header == "Frequency") {
					data.frequency = value.toDouble();
				}
				else if (header == "Coordinate System") {
					data.coordinateSystem = value;
				}
				else if (header == "Origin") { // 坐标参考原点
					QStringList vls = value.replace("\"", "").replace("(", "").replace(")", "").split(",");
					if (vls.length() < 3) {
						qDebug() << "******************** ERROR  INFO ******************************************";
						qDebug() << "origin point has error ," << value;
						qDebug() << "line: " << line;
						qDebug() << "head: " << header;
						qDebug() << "***************************************************************************";
						QMessageBox::information(nullptr, u8"警告", u8"无法解析Origin 参数，请检查", QMessageBox::Ok);
						return false;
					}
					data.origin = Point_3d{ vls.at(0).toDouble(),
											vls.at(1).toDouble(),
											vls.at(2).toDouble() };
				}
				else if (header == "Num Radius Samples") {
					data.numRadiusSamples = value.toInt();
				}
				else if (header == "Num Theta Samples") {
					data.numThetaSamples = value.toInt();
				}
				else if (header == "Num Phi Samples") {
					data.numPhiSamples = value.toInt();
				}
				else if (header == "Result Type") {
					data.resultType = value;
				}
				else if (header == "Num Header Lines") {
					data.numHeaderLines = value.toInt();
				}
				// 添加其他字段的解析...
			}
			dataList.push_back(data);
		}

		file.close();
	}
	else {
		qDebug() << "Failed to open the file:" << file.errorString();
		return false;
	}

	//this->electricFieldDataList = dataList;

	qDebug() << u8"文件读取结果，对文件结果进行重新整理与检查";
	//获取脉冲最小值，最大值，如果是 使用软件生产的 configname 应该为 PRF_1  PRF_2 这里通过判断 1,2 来确定脉冲序号
	QSet<QString> configNameSet;
	size_t curPRF = 0;
	for (int i = 0; i < dataList.size(); i++) {
		if (!configNameSet.contains(dataList[i].configurationName)) {
			curPRF = curPRF + 1;
		}
		dataList[i].prfidx = curPRF;
		configNameSet.insert(dataList[i].configurationName);
	}

	// 初始化	
	for (const QString& elementconfigName : configNameSet) {
		this->electricFieldDataList.insert(elementconfigName, std::vector<ElectricFieldData>(0));
	}

	// 数据初始化
	for (size_t i = 0; i < dataList.size(); i++) {
		this->electricFieldDataList[dataList[i].configurationName].push_back(dataList[i]);
	}
	// 每个Pluse 进行排序,按照频率： 小 -> 大，
	QMap<QString, std::vector<ElectricFieldData>>::const_iterator it;
	for (it = this->electricFieldDataList.constBegin(); it != this->electricFieldDataList.constEnd(); ++it) {
		std::sort(this->electricFieldDataList[it.key()].begin(), this->electricFieldDataList[it.key()].end(), compareElectricFieldDataInFreq);
	}

	// 检查每个electricFieldDataList 是否按照频率进行排序
	for (it = this->electricFieldDataList.constBegin(); it != this->electricFieldDataList.constEnd(); ++it) {
		for (size_t i = 0; i < this->electricFieldDataList[it.key()].size() - 1; i++) {
			if (this->electricFieldDataList[it.key()][i].frequency > this->electricFieldDataList[it.key()][i + 1].frequency) {
				qDebug() << u8"发现 configuration Name:" + it.key() + u8" , 发现问题，请检查";
				QMessageBox::warning(nullptr, u8"警告", u8"发现 configuration Name:" + it.key() + u8" , 发现问题，请检查");
				return false;
			}
		}
	}


	if (!this->checkPRFModel() || !this->resizePRFPluse()) {
		return false;
	}

	return true;

}

void FEKOBase::NearFieldEchoCSVParser::toThetapolar(const QString& filePath)
{

	this->toEchoData(filePath, 2);
}

void FEKOBase::NearFieldEchoCSVParser::toPhiPolar(const QString& filePath)
{
	this->toEchoData(filePath, 1);
}

void FEKOBase::NearFieldEchoCSVParser::toRPolar(const QString& filePath)
{
	this->toEchoData(filePath, 0);
}

void FEKOBase::NearFieldEchoCSVParser::saveCSV(const QString& filePath)
{
}

/// <summary>
///  输出脉冲回波文件
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="outDataName">0: R,1: phi,2: theta</param>
void FEKOBase::NearFieldEchoCSVParser::toEchoData(const QString& filePath, size_t outDataName)
{
	// 脉冲整理
	Eigen::MatrixXcd echoData = Eigen::MatrixXcd::Zero(this->prfData.size(), this->freqPoints);
	Eigen::MatrixXd antpos = Eigen::MatrixXd::Zero(this->prfData.size(), 5); //x,y,z,theta,phi"

	for (size_t i = 0; i < this->prfData.size(); i++) {
		antpos(i, 0) = this->prfData[i].px;
		antpos(i, 1) = this->prfData[i].py;
		antpos(i, 2) = this->prfData[i].pz;
		antpos(i, 3) = this->prfData[i].electricFieldDataList[0].theta;
		antpos(i, 4) = this->prfData[i].electricFieldDataList[0].phi;
		for (size_t j = 0; j < this->freqPoints; j++) {
			if (outDataName == 0) {
				echoData(i, j) = std::complex<double>(this->prfData[i].electricFieldDataList[j].reEr, this->prfData[i].electricFieldDataList[j].imEr);
			}
			else if (outDataName == 1) {
				echoData(i, j) = std::complex<double>(this->prfData[i].electricFieldDataList[j].reEphi, this->prfData[i].electricFieldDataList[j].imEphi);
			}
			else {
				echoData(i, j) = std::complex<double>(this->prfData[i].electricFieldDataList[j].reEtheta, this->prfData[i].electricFieldDataList[j].imEtheta);
			}

		}
	}

	EchoDataClass echodataTemp;
	echodataTemp.setAntPos(antpos);
	echodataTemp.setFreqStart(this->freqStart);
	echodataTemp.setFreqEnd(this->freqEnd);
	echodataTemp.setFreqpoints(this->freqPoints);
	echodataTemp.setEchoData(echoData);
	echodataTemp.SaveEchoData(filePath);
}

FEKOBase::EchoDataClass::EchoDataClass(const FEKOBase::EchoDataClass& inecho)
{

	this->echoData = inecho.getEchoData();
	this->antPos = inecho.getAntPos();
	this->freqStart = inecho.getFreqStart();
	this->freqEnd = inecho.getFreqEnd();
	this->freqpoints = inecho.getFreqpoints();
}



FEKOBase::EchoDataClass::EchoDataClass()
{

}

FEKOBase::EchoDataClass::~EchoDataClass()
{
}




void FEKOBase::EchoDataClass::setEchoData(Eigen::MatrixXcd echoData)
{
	this->echoData = echoData;
}

Eigen::MatrixXcd FEKOBase::EchoDataClass::getEchoData() const
{
	return this->echoData;
}

void FEKOBase::EchoDataClass::setAntPos(Eigen::MatrixXd antPos)
{
	this->antPos = antPos;
}

Eigen::MatrixXd FEKOBase::EchoDataClass::getAntPos() const
{
	return this->antPos;
}

void FEKOBase::EchoDataClass::setFreqStart(double freqStart)
{
	this->freqStart = freqStart;
}

double FEKOBase::EchoDataClass::getFreqStart() const
{
	return this->freqStart;
}

void FEKOBase::EchoDataClass::setFreqEnd(double freqEnd)
{
	this->freqEnd = freqEnd;
}

double FEKOBase::EchoDataClass::getFreqEnd() const
{
	return this->freqEnd;
}

void FEKOBase::EchoDataClass::setFreqpoints(int freqpoints)
{
	this->freqpoints = freqpoints;
}

int FEKOBase::EchoDataClass::getFreqpoints() const
{
	return this->freqpoints;
}

void FEKOBase::EchoDataClass::loadEchoData(const QString& filePath)
{
	std::ifstream file(reinterpret_cast<const wchar_t*>(filePath.utf16()), std::ios::binary);

	if (file.is_open()) {
		// 保存频率变量
		INT32 PRFRow = 0;
		INT32 freqCol = 0;
		// 读取其他成员变量
		file.read(reinterpret_cast<char*>(&freqStart), sizeof(double));
		file.read(reinterpret_cast<char*>(&freqEnd), sizeof(double));
		file.read(reinterpret_cast<char*>(&freqpoints), sizeof(INT32));
		file.read(reinterpret_cast<char*>(&PRFRow), sizeof(INT32));
		file.read(reinterpret_cast<char*>(&freqCol), sizeof(INT32));
		echoData = Eigen::MatrixXcd::Zero(PRFRow, freqCol); // 重新分配内存
		antPos = Eigen::MatrixXd::Zero(PRFRow, 5);
		file.read(reinterpret_cast<char*>(antPos.data()), sizeof(double) * PRFRow * 5); 		// 保存天线位置
		file.read(reinterpret_cast<char*>(echoData.data()), sizeof(std::complex<double>) * PRFRow * freqCol); 		// 保存回波数据
		file.close(); // 关闭文件

		this->freqStart = freqStart;
		this->freqEnd = freqEnd;
		this->freqpoints = freqpoints;
		this->echoData = echoData;
		this->antPos = antPos;
		qDebug() << u8"回波数据加载完成";
	}
	else {
		qWarning() << "Error: Unable to open file for reading.";
	}
}

void FEKOBase::EchoDataClass::SaveEchoData(const QString& filePath)
{
	if (echoData.rows() != antPos.rows() || antPos.cols() != 5) {
		qDebug() << "Error: antPos.size()!=echoData.rows()*5"
			+ QString::number(echoData.rows()) + u8"!=" + QString::number(antPos.rows())
			+ QString::number(antPos.cols()) + u8"!=5";
		return;
	}
	else {}
	std::ofstream file(reinterpret_cast<const wchar_t*>(filePath.utf16()), std::ios::binary);
	qDebug() << "===================================================================";
	qDebug() << u8"回波脉冲文件格式说明：";
	qDebug() << u8"|freqStart(double)，freqEnd(double)，freqpoints(int)|PRFROW(int),PRFCol(int)|antPos|echodata|";
	qDebug() << u8"其中antPos:   PRFrow*3        double    x,y,z,incidence,azangle,theta,phi";
	qDebug() << u8"其中echodata: PRFrow*PRFCol   complex<double>     ";
	qDebug() << "===================================================================";
	if (file.is_open()) {
		INT32 PRFRow = echoData.rows();
		INT32 freqCol = echoData.cols();
		file.write(reinterpret_cast<const char*>(&freqStart), sizeof(double)); // 保存频率变量
		file.write(reinterpret_cast<const char*>(&freqEnd), sizeof(double));
		file.write(reinterpret_cast<const char*>(&freqpoints), sizeof(INT32));
		file.write(reinterpret_cast<const char*>(&PRFRow), sizeof(INT32));
		file.write(reinterpret_cast<const char*>(&freqCol), sizeof(INT32));
		file.write(reinterpret_cast<const char*>(antPos.data()), sizeof(double) * antPos.size()); 		// 保存天线位置
		file.write(reinterpret_cast<const char*>(echoData.data()), sizeof(std::complex<double>) * echoData.size()); 		// 保存回波数据
		file.close(); 		// 关闭文件

	}
	else {
		qDebug() << "Error: Unable to open file for writing.";
	}
}



Eigen::MatrixXd FEKOBase::WINDOWFun(Eigen::MatrixXcd& echo, ImageAlgWindowFun winfun)
{
	size_t Nxa = echo.rows();
	size_t Nf = echo.cols();
	Eigen::MatrixXd normw = Eigen::MatrixXd::Zero(Nxa, Nf); // 归一化窗函数

	if (winfun == ImageAlgWindowFun::HANMMING) {
		normw = Hanning(Nf, Nxa);
		echo = echo.array() * normw.array();
	}
	else {
		normw = normw.array() * 0 + 1 / (Nxa * Nf);
	}

	return normw;
}

QList<QString> FEKOBase::getFEKOImageAlgorithmList()
{
	QList<QString> list;
	FEKOImageAlgorithm alg;
	for (alg = FEKOImageAlgorithm::TBP_TIME; alg < FEKOImageAlgorithm::UNKONW; alg = (FEKOImageAlgorithm)(alg + 1)) {
		list.append(FEKOImageAlgorithm2String(alg));
	}
	return list;
}

FEKOBase::FEKOImageAlgorithm FEKOBase::String2FEKOImageAlgorithm(QString str)
{
	FEKOImageAlgorithm alg;
	for (alg = FEKOImageAlgorithm::TBP_TIME; alg < FEKOImageAlgorithm::UNKONW; alg = (FEKOImageAlgorithm)(alg + 1)) {
		if (str == FEKOImageAlgorithm2String(alg)) {
			return alg;
		}
		else {}
	}
	return alg;
}

QString FEKOBase::FEKOImageAlgorithm2String(FEKOImageAlgorithm alg)
{
	// 将FEKOImageAlgorithm 枚举转换为字符串
	switch (alg)
	{
	case FEKOBase::TBP_TIME:
		return u8"TBP_TIME";
	case FEKOBase::TBP_FREQ:
		return u8"TBP_FREQ";
	default:
		return u8"UNKONW";
	}
}

// 请仿照FEKOImageAlgorithm枚举的写法，构建QString  与 ImageAlgWindowFun 的转换函数

QList<QString> FEKOBase::getImageAlgWindowFunList()
{
	QList<QString> list;
	ImageAlgWindowFun alg;
	for (alg = ImageAlgWindowFun::NOWINDOWS; alg < ImageAlgWindowFun::UNKONWWINDOW; alg = (ImageAlgWindowFun)(alg + 1)) {
		list.append(ImageAlgWindowFun2String(alg));
	}
	return list;
}

FEKOBase::ImageAlgWindowFun FEKOBase::String2ImageAlgWindowFun(QString str)
{
	ImageAlgWindowFun alg;
	for (alg = ImageAlgWindowFun::UNKONWWINDOW; alg < ImageAlgWindowFun::UNKONWWINDOW; alg = (ImageAlgWindowFun)(alg + 1)) {
		if (str == ImageAlgWindowFun2String(alg)) {
			return alg;
		}
		else {}
	}
	return alg;
}

QString FEKOBase::ImageAlgWindowFun2String(FEKOBase::ImageAlgWindowFun alg)
{
	switch (alg)
	{
	case FEKOBase::NOWINDOWS:
		return u8"NOWINDOWS";
	case FEKOBase::HANMMING:
		return u8"HANMMING";
	default:
		return u8"UNKONWWINDOW";
	}
}


bool FEKOBase::BPImage_TIME(QString& restiffpath, Eigen::MatrixXcd& echoData, Eigen::MatrixXd& antPos, Eigen::MatrixXd& freqmatrix, Eigen::MatrixXd& X, Eigen::MatrixXd& Y, Eigen::MatrixXd& Z, ImageAlgWindowFun winfun)
{
	// BP成像算法
	const double c = 0.299792458;  // 光速

	return true;
}

bool FEKOBase::FBPImage_FREQ(QString& restiffpath, Eigen::MatrixXcd& echoData, Eigen::MatrixXd& antPos, Eigen::MatrixXd& freqmatrix, Eigen::MatrixXd& X, Eigen::MatrixXd& Y, Eigen::MatrixXd& Z, ImageAlgWindowFun winfun)
{

	// BP成像算法
	const double c = 0.299792458;  // 光速
	const std::complex<double> j(0, 1); // 虚数单位
	const size_t image_height = X.rows();
	const size_t image_width = X.cols();
	const size_t PRFCount = echoData.rows();
	const size_t frepoints = echoData.cols();
	Eigen::MatrixXcd factorj = Eigen::MatrixXcd::Zero(1, echoData.cols()); //  1 , freqs
	factorj = freqmatrix.array().cast<std::complex<double>>().array() * j * 4 * M_PI / c; // 声明校正矩阵
	Eigen::MatrixXcd im_final = Eigen::MatrixXcd::Zero(image_height, image_width);



#ifdef __SHOWPROCESS // 进度条展示
	QProgressDialog progressDialog(u8"BP_FREQ成像进度", u8"终止", 0, image_height);
	progressDialog.setWindowTitle(u8"成像中");
	progressDialog.setWindowModality(Qt::WindowModal);
	progressDialog.setAutoClose(true);
	progressDialog.setValue(0);
	progressDialog.setMaximum(image_height);
	progressDialog.setMinimum(0);
	progressDialog.show();
#endif // __SHOWPROCESS



#ifdef __SHOWIMAGEPROCESSRESULT // 加窗处理
	Eigen::MatrixXd normw = WINDOWFun(echoData, winfun);
#endif

#ifdef __IMAGEPARALLEL 
#pragma omp parallel for
	for (long ii = 0; ii < image_height; ii++)
	{
		Eigen::MatrixXd im_R = Eigen::MatrixXd::Zero(PRFCount, 1);// 图像到脉冲矩阵 prf*1
		Eigen::MatrixXcd term_R = Eigen::MatrixXcd::Zero(1, frepoints);
		Eigen::MatrixXcd pluse_R = Eigen::MatrixXcd::Zero(PRFCount, 1);

		for (size_t jj = 0; jj < image_width; jj++) {
			im_R.col(0) = ((antPos.col(0).array() - X(ii, jj)).array().pow(2) +
				(antPos.col(1).array() - Y(ii, jj)).array().pow(2) +
				(antPos.col(2).array() - Z(ii, jj)).array().pow(2))
				.array().sqrt().array(); // 获取目标到天线矩阵 计算 ok
			// im_R PRF_count x 1
			for (size_t tt = 0; tt < PRFCount; tt++) {
				term_R = (im_R(tt, 0) * factorj.array()).array().exp(); // ok
				pluse_R(tt, 0) = (echoData.row(tt).array() * term_R.array()).sum(); // 对每个脉冲校正求和
			}
			im_final(ii, jj) = pluse_R.array().sum(); // 计算图像
		}
	}
#else
 
	Eigen::MatrixXd im_R = Eigen::MatrixXd::Zero(PRFCount, 1);// 图像到脉冲矩阵 prf*1
	Eigen::MatrixXcd term_R = Eigen::MatrixXcd::Zero(1, frepoints);
	Eigen::MatrixXcd pluse_R = Eigen::MatrixXcd::Zero(PRFCount, 1);
	for (long ii = 0; ii < image_height; ii++)
	{
		for (size_t jj = 0; jj < image_width; jj++) {
			im_R.col(0) = ((antPos.col(0).array() - X(ii, jj)).array().pow(2) +
				(antPos.col(1).array() - Y(ii, jj)).array().pow(2) +
				(antPos.col(2).array() - Z(ii, jj)).array().pow(2))
				.array().sqrt().array(); // 获取目标到天线矩阵 计算 ok
			// im_R PRF_count x 1
			for (size_t tt = 0; tt < PRFCount; tt++) {
				term_R = (im_R(tt, 0) * factorj.array()).array().exp(); // ok
				pluse_R(tt, 0) = (echoData.row(tt).array() * term_R.array()).sum(); // 对每个脉冲校正求和
			}
			im_final(ii, jj) = pluse_R.array().sum(); // 计算图像
		}
#ifdef __SHOWPROCESS
		progressDialog.setValue(ii);
#endif
	}
#endif

#ifdef __SHOWIMAGEPROCESSRESULT // 加窗处理
	im_final = im_final.array() / (normw.array().sum());

#endif


	// 3. 保存图像


	QString newrestiffpath = restiffpath;

 
	Eigen::MatrixXd gt = Eigen::MatrixXd::Zero(2,3);
	gt(0, 0) = X(0, 0);
	gt(0, 1) = X(0, 1) - X(0, 0);
	gt(0, 2) = 0;
	gt(1, 0) = Y(0, 0);
	gt(1, 1) = 0;
	gt(1, 2) = Y(0, 0) - Y(1, 0);
	std::cout << gt << std::endl;
	gdalImageComplex im_final_gdal = CreategdalImageComplex(restiffpath,im_final.rows(),im_final.cols(),1,gt, QString(u8""), true,true);
	im_final_gdal.setData(im_final);
	im_final_gdal.saveImage();

 	qDebug() << QString(u8"保存文件地址：" + restiffpath);
#ifdef __SHOWPROCESS
	progressDialog.setWindowTitle(u8"保存文件：" + restiffpath);
	progressDialog.setValue(image_height);
	progressDialog.close();
#endif

	// 绘制图像
#ifdef   __SHOWIMAGEPROCESSRESULT
	// 将复数矩阵的幅度转换为实数矩阵
	matplot::figure();
	matplot::vector_2d amplitude_im_final(im_final.rows(), matplot::vector_1d(im_final.cols()));
	for (int i = 0; i < im_final.rows(); ++i) {
		for (int j = 0; j < im_final.cols(); ++j) {
			amplitude_im_final[i][j] = std::abs(im_final(i, j));
		}
	}
	matplot::imagesc(amplitude_im_final);
	matplot::colorbar();
	matplot::show();
#endif //  __SHOWMATPLOTLIBCPP

	return true;
}



