static public bool SaveToSPC(double[] wavelengths, double[] intensities, string filename, string xAxisLabel, string yAxisLabel, string notes = "") { try { SPCStructs.SPCHDR header = new SPCStructs.SPCHDR(); // Single file, uneven X spacing header.ftflgs = SPCConstants.TXVALS; // First and last X values header.ffirst = Convert.ToSingle(wavelengths[0]); header.flast = Convert.ToSingle(wavelengths[wavelengths.Length - 1]); // Number of points header.fnpts = Convert.ToUInt32(wavelengths.Length); // SPC Version header.fversn = 0x4B; // Experiment type header.fexper = SPCConstants.SPCFLR; // This sets the Y data to 32-bit float header.fexp = 128; // Number of subfiles header.fnsub = 1; // X,Y,Z axis types header.fxtype = SPCConstants.XNMETR; header.fytype = SPCConstants.YCOUNT; // Date DateTime dt = DateTime.Now; header.fdate = (uint)dt.Year << 20; header.fdate |= (uint)dt.Month << 16; header.fdate |= (uint)dt.Day << 11; header.fdate |= (uint)dt.Hour << 6; header.fdate |= (uint)dt.Minute; if (notes.Length > 0) { header.fcmnt = notes; } header.fxtype = (byte)GetValueFromDescription <SPC_XTypes>(xAxisLabel); header.fytype = (byte)GetValueFromDescription <SPC_YTypes>(yAxisLabel); SPCStructs.SUBHDR subHeader = new SPCStructs.SUBHDR(); subHeader.subindx = 0; BinaryWriter binWriter = new BinaryWriter(File.Open(filename, FileMode.Create)); binWriter.Write(StructToByteArray(header)); foreach (double value in wavelengths) { binWriter.Write(Convert.ToSingle(value)); } binWriter.Write(StructToByteArray(subHeader)); foreach (double value in intensities) { binWriter.Write(Convert.ToSingle(value)); } /* * if (notes.Length > 0) * { * while (binWriter.BaseStream.Position % 4 != 0) * binWriter.Write((byte)0); * * //64 byte log header block * uint currentPosition = (uint)binWriter.BaseStream.Position; * binWriter.BaseStream.Seek(248, SeekOrigin.Begin); * binWriter.Write(currentPosition);//header.flogoff; * binWriter.BaseStream.Seek(currentPosition, SeekOrigin.Begin); * int logsizd = System.Text.ASCIIEncoding.ASCII.GetByteCount(notes) + 64; * int logsizm = ((logsizd / 4096) + 1) * 4096; * binWriter.Write(logsizd); * binWriter.Write(logsizm); * binWriter.Write(64); //text offset * binWriter.Write(0); //binary log size * binWriter.Write(0); //size of disk area ??? * byte[] fill = new byte[64 - 20]; * binWriter.Write(fill); * byte[] bytes = Encoding.ASCII.GetBytes(notes); * binWriter.Write(bytes); * } */ binWriter.Close(); } catch (Exception ex) { App.Current.Dispatcher.Invoke(new Action(() => System.Windows.MessageBox.Show(App.Current.MainWindow, ex.Message, "Save Failed"))); return(false); } return(true); }
static public bool OpenSPC(string filename, ref double[] wavelengths, ref double[] intensities, ref string xAxisLabel, ref string yAxisLabel, ref string notes) { try { using (BinaryReader reader = new BinaryReader(File.Open(filename, FileMode.Open), Encoding.ASCII)) { //read Main Header Block SPCStructs.SPCHDR header = new SPCStructs.SPCHDR(); header.ftflgs = reader.ReadByte(); header.fversn = reader.ReadByte(); header.fexper = reader.ReadByte(); header.fexp = reader.ReadByte(); header.fnpts = reader.ReadUInt32(); header.ffirst = reader.ReadDouble(); header.flast = reader.ReadDouble(); header.fnsub = reader.ReadUInt32(); header.fxtype = reader.ReadByte(); header.fytype = reader.ReadByte(); header.fztype = reader.ReadByte(); header.fpost = reader.ReadByte(); header.fdate = reader.ReadUInt32(); header.fres = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(9)); header.fsource = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(9)); header.fpeakpt = reader.ReadUInt16(); reader.ReadBytes(32);//fspare header.fcmnt = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(130)); header.fcatxt = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(30)); header.flogoff = reader.ReadUInt32(); xAxisLabel = Enum <SPC_XTypes> .Description((SPC_XTypes)header.fxtype); yAxisLabel = Enum <SPC_YTypes> .Description((SPC_YTypes)header.fytype); //skip rest of header reader.ReadBytes(512 - 252); if (header.fversn != 0x4B) { throw (new Exception("Invalid format")); } if ((header.ftflgs & 0x04) != 0) { throw (new Exception("Multifile format is not supported")); } if (header.fnpts <= 1) { throw (new Exception("Bad SPC file, not enough data points")); } //if filetype is XY then read X-axis data if ((header.ftflgs & 0x80) != 0) { wavelengths = new double[header.fnpts]; intensities = new double[header.fnpts]; for (int i = 0; i < header.fnpts; i++) { wavelengths[i] = reader.ReadSingle(); } } else if (header.ftflgs == 0) { wavelengths = new double[header.fnpts]; intensities = new double[header.fnpts]; for (int i = 0; i < header.fnpts; i++) { wavelengths[i] = header.ffirst + (i * ((header.flast - header.ffirst) / (header.fnpts - 1))); } } else { throw (new Exception("Unsupported SPC file type")); } //read sub-header bytes reader.ReadBytes(32); //read intensities if (header.fexp == 0x80) { for (int i = 0; i < header.fnpts; i++) { intensities[i] = reader.ReadSingle(); } } else { int intensity = 0; int exp = ((header.ftflgs & 0x1) != 0) ? 16 : 32; for (int i = 0; i < header.fnpts; i++) { if (exp == 16) { intensity = reader.ReadInt16(); } else { intensity = reader.ReadInt32(); } intensities[i] = Math.Pow(2, header.fexp) * intensity / Math.Pow(2, exp); } } header.fcmnt = header.fcmnt.Replace("\0", ""); if (!String.IsNullOrEmpty(header.fcmnt) && header.fcmnt.Length > 0) { notes = header.fcmnt; } //64 byte log header block /* * if (header.flogoff > 0) * { * reader.BaseStream.Seek(header.flogoff, SeekOrigin.Begin); * int logBlockSize = reader.ReadInt32(); * reader.ReadInt32(); //don't care * int logTextOffset = reader.ReadInt32(); * reader.BaseStream.Seek(header.flogoff + logTextOffset, SeekOrigin.Begin); * notes = System.Text.Encoding.ASCII.GetString(reader.ReadBytes((int)header.flogoff + logBlockSize - logTextOffset)); * } */ } } catch (Exception e) { //MessageBox.Show(e.ToString(), "Could not open file"); return(false); } return(true); }