using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data; using System.IO; namespace mainProgram { class SpectralProcessor { public void OpenNolinerData() { } public void OpenCalData() { } public void NonLinearCorrection(double[] coefficient, double[] rawData, int bandnumber) { for (int i = 0; i < bandnumber; i++) { rawData[i] = rawData[i] / (coefficient[0] + coefficient[1] * rawData[i] + coefficient[2] * Math.Pow(rawData[i], 2) + coefficient[3] * Math.Pow(rawData[i], 3) + coefficient[4] * Math.Pow(rawData[i], 4) + coefficient[5] * Math.Pow(rawData[i], 5) + coefficient[6] * Math.Pow(rawData[i], 6) + coefficient[7] * Math.Pow(rawData[i], 7) ); } } public void RadCorrection(double[] calData, uint integrationTime_cal, double[] targetData, int integrationTime_target, int bandnumber) { for (int i = 0; i < bandnumber; i++) { targetData[i] = calData[i] * targetData[i] * (integrationTime_cal * 1.0) / (integrationTime_target * 1.0); if (targetData[i] < 0 || integrationTime_target == 0)//如果福亮度为负值,则设置为0 { targetData[i] = 0.0000000000000001;//丰建议:不设置为0,而设置为很小的数,他的sif算法就不会出错 } } } } public enum DataStatus { NoData, Raw, NonLinearCorrection, Rad, Sif }; public struct SpectralData { public DataStatus dataStatus; public string SN; public int position; public int exposureTime; public int spectralDataLength; public double[] spectral;//long or double ????????????????????????? } public struct SifData { public string deviceType; public string[] position; public string[] time; public double[,] sif;//二维数组 } public struct CalData { public uint exposureTime; public int pixelCount; public float temperature; public float[] waveLengthInNM; public double[] gain; public double[] offset; public string SN; public int position; } public struct NonLinearData { public double[] nonLinearData; public string SN; } public class FileEncoding { // 给定文件的路径,读取文件的二进制数据,判断文件的编码类型 public static Encoding GetType(string FILE_NAME) { FileStream fs = new FileStream(FILE_NAME, FileMode.Open, FileAccess.Read); Encoding r = GetType(fs); fs.Close(); return r; } // 通过给定的文件流,判断文件的编码类型 public static Encoding GetType(FileStream fs) { byte[] Unicode = new byte[] { 0xFF, 0xFE, 0x41 }; byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF, 0x00 }; byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //带BOM Encoding reVal = Encoding.Default; BinaryReader r = new BinaryReader(fs, Encoding.Default); int i; int.TryParse(fs.Length.ToString(), out i); byte[] ss = r.ReadBytes(i); if (IsUTF8Bytes(ss) || (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF)) { reVal = Encoding.UTF8; } else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00) { reVal = Encoding.BigEndianUnicode; } else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41) { reVal = Encoding.Unicode; } r.Close(); return reVal; } // 判断是否是不带 BOM 的 UTF8 格式 private static bool IsUTF8Bytes(byte[] data) { int charByteCounter = 1; //计算当前正分析的字符应还有的字节数 byte curByte; //当前分析的字节. for (int i = 0; i < data.Length; i++) { curByte = data[i]; if (charByteCounter == 1) { if (curByte >= 0x80) { //判断当前 while (((curByte <<= 1) & 0x80) != 0) { charByteCounter++; } //标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X  if (charByteCounter == 1 || charByteCounter > 6) { return false; } } } else { //若是UTF-8 此时第一位必须为1 if ((curByte & 0xC0) != 0x80) { return false; } charByteCounter--; } } if (charByteCounter > 1) { throw new Exception("非预期的byte格式"); } return true; } } public class SpectralDataReaderWriter { public SpectralDataReaderWriter(string csvPath) { mCsvPath = csvPath; OpenCSV(); GetMetaData(); } private string mCsvPath; public DataTable mDataTable = null; private int mTotalSpectrometer; private int mTotalSpectralCount; private int mSpectralCountOfOneSpectrometer; private int[] mWavelengthCountOfSpectrometers;//mWavelengthCountOfSpectrometers private string[] mSN; public int TotalSpectralCount { get { return mTotalSpectralCount; } set { mTotalSpectralCount = value; } } public int findMaxColunmCount(string filePath) { Encoding encoding = FileEncoding.GetType(filePath); //Encoding.ASCII;// DataTable dt = new DataTable(); FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fs, encoding); string strLine = ""; string[] aryLine = null; int maxColunmCount = 0; int tmp; while ((strLine = sr.ReadLine()) != null) { aryLine = strLine.Split(','); tmp = aryLine.Length; if (maxColunmCount < tmp) { maxColunmCount = tmp; } } sr.Close(); fs.Close(); return maxColunmCount; } //https://www.jb51.net/article/193012.htm public void OpenCSV()//从csv读取数据返回table { mDataTable = new DataTable(); int columnCount1 = findMaxColunmCount(mCsvPath); for (int i = 0; i < columnCount1; i++) { DataColumn dc1 = new DataColumn(); mDataTable.Columns.Add(dc1); } Encoding encoding = FileEncoding.GetType(mCsvPath); //Encoding.ASCII;// FileStream fs = new FileStream(mCsvPath, FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fs, encoding); string strLine = "";//记录每次读取的一行记录 string[] aryLine = null;//记录每行记录中的各字段内容 while ((strLine = sr.ReadLine()) != null)//逐行读取CSV中的数据 { aryLine = strLine.Split(','); DataRow dr = mDataTable.NewRow(); for (int j = 0; j < aryLine.Length; j++) { dr[j] = aryLine[j]; } mDataTable.Rows.Add(dr); } sr.Close(); fs.Close(); } public void GetMetaData() { mTotalSpectrometer = int.Parse(mDataTable.Rows[1][1].ToString()); mWavelengthCountOfSpectrometers = new int[mTotalSpectrometer]; mSN = new string[mTotalSpectrometer]; for (int i = 0; i < mTotalSpectrometer; i++) { mWavelengthCountOfSpectrometers[i] = int.Parse(mDataTable.Rows[i * 2 + 2][6].ToString()); mSN[i] = mDataTable.Rows[i * 2 + 2][4].ToString(); } mTotalSpectralCount = mDataTable.Rows.Count - 3 - mTotalSpectrometer * 2; mSpectralCountOfOneSpectrometer = mTotalSpectralCount / mTotalSpectrometer; } public SpectralData GetSpectral(int index) { SpectralData spectralData; if (index > mTotalSpectralCount) { //return spectralData; } int rowOffset = 3 + mTotalSpectrometer * 2; int wavelengthCountIndex = GetIndex(index); spectralData.SN = mSN[wavelengthCountIndex]; spectralData.position = GetPosition(index); spectralData.spectralDataLength = mWavelengthCountOfSpectrometers[wavelengthCountIndex]; spectralData.exposureTime = int.Parse(mDataTable.Rows[index - 1 + rowOffset][2].ToString()); spectralData.spectral = new double[mWavelengthCountOfSpectrometers[wavelengthCountIndex]]; for (int i = 0; i < mWavelengthCountOfSpectrometers[wavelengthCountIndex]; i++) { string tmp = mDataTable.Rows[index - 1 + rowOffset][i + 3].ToString(); spectralData.spectral[i] = long.Parse(tmp); } spectralData.dataStatus = DataStatus.Raw; return spectralData; } public void UpdateSpectral(int index, SpectralData spectralData) { int rowOffset = 3 + mTotalSpectrometer * 2; int wavelengthCountIndex = GetIndex(index); for (int i = 0; i < spectralData.spectralDataLength; i++) { mDataTable.Rows[index - 1 + rowOffset][i + 3] = spectralData.spectral[i]; } } public int GetIndex(int index) { index -= 1;//因为0基索引,所以减1 double wavelengthCountIndexTmp = index / mSpectralCountOfOneSpectrometer; int wavelengthCountIndex = (int)Math.Floor(wavelengthCountIndexTmp);//因为0基索引,所以向下取整,否则向上取整 return wavelengthCountIndex; } public int GetPosition(int index) { //index -= 1;//因为0基索引,所以减1 //int position; //int chushu = index / mSpectralCountOfOneSpectrometer; //int yushu = index % mSpectralCountOfOneSpectrometer; //if (yushu == 0) //{ // position = mSpectralCountOfOneSpectrometer; //} //else //{ // position = yushu; //} //return position; int position; int chushu = index / mSpectralCountOfOneSpectrometer; int yushu = index % mSpectralCountOfOneSpectrometer; if (yushu == 0) { position = mSpectralCountOfOneSpectrometer; } else { position = yushu; } return position; } public void SaveCSV(string fullPath)//table数据写入csv { FileInfo fi = new FileInfo(fullPath); if (!fi.Directory.Exists) { fi.Directory.Create(); } FileStream fs = new FileStream(fullPath, FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fs, Encoding.UTF8); string data = ""; //for (int i = 0; i < mDataTable.Columns.Count; i++)//写入列名 //{ // data += mDataTable.Columns[i].ColumnName.ToString(); // if (i < mDataTable.Columns.Count - 1) // { // data += ","; // } //} //sw.WriteLine(data); for (int i = 0; i < mDataTable.Rows.Count; i++) //写入各行数据 { data = ""; for (int j = 0; j < mDataTable.Columns.Count; j++) { string str = mDataTable.Rows[i][j].ToString(); str = str.Replace("\"", "\"\"");//替换英文冒号 英文冒号需要换成两个冒号 if (str.Contains(',') || str.Contains('"') || str.Contains('\r') || str.Contains('\n')) //含逗号 冒号 换行符的需要放到引号中 { str = string.Format("\"{0}\"", str); } data += str; if (j < mDataTable.Columns.Count - 1) { data += ","; } } sw.WriteLine(data); } sw.Close(); fs.Close(); } public bool ChangeFileName(string OldPath, string NewPath) { bool re = false; try { if (File.Exists(OldPath)) { File.Move(OldPath, NewPath); re = true; } } catch { re = false; } return re; } public bool SaveCSV(string fullPath, string Data) { bool re = true; try { FileStream FileStream = new FileStream(fullPath, FileMode.Append); StreamWriter sw = new StreamWriter(FileStream, Encoding.UTF8); sw.WriteLine(Data); //清空缓冲区 sw.Flush(); //关闭流 sw.Close(); FileStream.Close(); } catch { re = false; } return re; } }; public class SifDataReaderWriter { public SifDataReaderWriter(string csvPath) { mCsvPath = csvPath; OpenCSV(); GetMetaData(); } private string mCsvPath; public DataTable mDataTable = null; private int mTotalPositionCount; private int mTotalSifCount; //https://www.jb51.net/article/193012.htm public void OpenCSV()//从csv读取数据返回table { mDataTable = new DataTable(); int columnCount1 = findMaxColunmCount(mCsvPath); for (int i = 0; i < columnCount1; i++) { DataColumn dc1 = new DataColumn(); mDataTable.Columns.Add(dc1); } Encoding encoding = FileEncoding.GetType(mCsvPath); //Encoding.ASCII;// FileStream fs = new FileStream(mCsvPath, FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fs, encoding); string strLine = "";//记录每次读取的一行记录 string[] aryLine = null;//记录每行记录中的各字段内容 while ((strLine = sr.ReadLine()) != null)//逐行读取CSV中的数据 { aryLine = strLine.Split(','); DataRow dr = mDataTable.NewRow(); for (int j = 0; j < aryLine.Length; j++) { dr[j] = aryLine[j]; } mDataTable.Rows.Add(dr); } sr.Close(); fs.Close(); } public int findMaxColunmCount(string filePath) { Encoding encoding = FileEncoding.GetType(filePath); //Encoding.ASCII;// DataTable dt = new DataTable(); FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fs, encoding); string strLine = ""; string[] aryLine = null; int maxColunmCount = 0; int tmp; while ((strLine = sr.ReadLine()) != null) { aryLine = strLine.Split(','); tmp = aryLine.Length; if (maxColunmCount < tmp) { maxColunmCount = tmp; } } sr.Close(); fs.Close(); return maxColunmCount; } public void GetMetaData() { mTotalPositionCount = mDataTable.Columns.Count - 2; mTotalSifCount = mDataTable.Rows.Count - 1; } public SifData GetSifData() { SifData sifData; //if (index > mTotalSifCount)//错误:本文件没有第index条sif时间序列光谱!!!! //{ // //return sifData; //} sifData.deviceType = mDataTable.Rows[1][mDataTable.Columns.Count - 1].ToString(); sifData.position = new string[mTotalPositionCount]; sifData.sif = new double[mTotalSifCount, mTotalPositionCount]; sifData.time = new string[mTotalSifCount]; for (int i = 1; i < mTotalPositionCount + 1; i++)//第一列是时间 { sifData.position[i - 1] = mDataTable.Rows[0][i].ToString(); for (int j = 1; j < mTotalSifCount + 1; j++)//第一行是描述标题 { string timeTmp = mDataTable.Rows[j][0].ToString(); sifData.time[j - 1] = timeTmp; string sifTmp = mDataTable.Rows[j][i].ToString(); if (sifTmp.Length == 0) { sifData.sif[j - 1, i - 1] = 0; } else { sifData.sif[j - 1, i - 1] = double.Parse(sifTmp); } } } return sifData; } } }