Beispiel #1
0
        public bool ImportFile0(string fileName)
        {
            IVisuMap app = CustomImporter.App.ScriptApp;

            if (!fileName.ToLower().EndsWith(".fcs"))
            {
                return(false);  // Let other import handle it.
            }

            INumberTable dataTable   = null;
            IFreeTable   textTable   = null;
            bool         compensated = false;
            bool         logScaled   = false;

            using (StreamReader sr = new StreamReader(fileName)) {
                //
                // Read the text segment.
                //
                char[] header = new char[42];
                sr.ReadBlock(header, 0, header.Length);
                int textBegin = int.Parse(new string(header, 10, 8));
                int textEnd   = int.Parse(new string(header, 18, 8));
                int beginData = int.Parse(new string(header, 26, 8));
                int endData   = int.Parse(new string(header, 34, 8));

                char[] line = new char[textEnd + 4];
                sr.ReadBlock(line, header.Length, line.Length - header.Length);
                string textSeg   = new string(line, textBegin + 1, textEnd - textBegin);
                char   delimiter = line[textBegin];

                textTable = app.New.FreeTable();
                textTable.AddColumn("Value", false);

                string[] textFields = textSeg.Split(delimiter);
                textTable.AddRows("P", textFields.Length / 2);
                IList <IRowSpec> rowSpecList = textTable.RowSpecList;
                for (int row = 0; row < textTable.Rows; row++)
                {
                    rowSpecList[row].Id      = textFields[2 * row];
                    textTable.Matrix[row][0] = textFields[2 * row + 1];
                }

                //
                // Read in the data segement
                //
                fcsInfo = new FcsInfo(textTable, header);
                if ((beginData == 0) && (textTable.IndexOfRow("$BEGINDATA") > 0))
                {
                    beginData = int.Parse(textTable.Matrix[textTable.IndexOfRow("$BEGINDATA")][0]);
                }
                if ((endData == 0) && (textTable.IndexOfRow("$ENDDATA") > 0))
                {
                    endData = int.Parse(textTable.Matrix[textTable.IndexOfRow("$ENDDATA")][0]);
                }
                dataTable = app.New.NumberTable(fcsInfo.Rows, fcsInfo.Columns);

                using (BinaryReader br = new BinaryReader(sr.BaseStream)) {
                    br.BaseStream.Seek(beginData, SeekOrigin.Begin);

                    Byte[] buf4 = new byte[4];
                    Byte[] buf8 = new byte[8];

                    int bitOffset = 0;
                    for (int row = 0; row < fcsInfo.Rows; row++)
                    {
                        for (int col = 0; col < fcsInfo.Columns; col++)
                        {
                            ColumnInfo ci   = fcsInfo.ColumnInfo[col];
                            Byte[]     data = ReadBits(br, ci.Bits, ref bitOffset);
                            if (data.Length < ci.Bytes)
                            {
                                row = fcsInfo.Rows; // enforce premature loop-end.
                                break;
                            }
                            Byte[] buf = (fcsInfo.DataType == FcsInfo.DataTypes.Double) ? buf8 : buf4;
                            Array.Clear(buf, 0, buf.Length);
                            Array.Copy(data, 0, buf, 0, ci.Bytes);
                            if (!fcsInfo.BigEndian)
                            {
                                // Intel CPU expects BigEndian format.
                                Array.Reverse(buf, 0, ci.Bytes);
                            }

                            switch (fcsInfo.DataType)
                            {
                            case FcsInfo.DataTypes.Integer:
                                dataTable.Matrix[row][col] = (BitConverter.ToUInt32(buf, 0) & ci.RangeMask);
                                break;

                            case FcsInfo.DataTypes.Float:
                                dataTable.Matrix[row][col] = BitConverter.ToSingle(buf, 0);
                                break;

                            case FcsInfo.DataTypes.Double:
                                dataTable.Matrix[row][col] = BitConverter.ToDouble(buf, 0);
                                break;
                            }
                        }
                    }
                }
            }

            // Post processing
            for (int col = 0; col < fcsInfo.Columns; col++)
            {
                IColumnSpec cs    = dataTable.ColumnSpecList[col];
                ColumnInfo  cInfo = fcsInfo.ColumnInfo[col];
                cs.Id = cInfo.ShortName;
                //cs.Name = cInfo.Name + ( cInfo.IsLinear ? ".Lin" : ".Log");
                cs.Name = cInfo.Name;

                if ((cs.Id == "TIME") || (cs.Id == "TIME1"))
                {
                    int timeStepIdx = textTable.IndexOfRow("$TIMESTEP");
                    if (timeStepIdx >= 0)
                    {
                        double timeStep = double.Parse(textTable.Matrix[timeStepIdx][0]);
                        for (int row = 0; row < fcsInfo.Rows; row++)
                        {
                            dataTable.Matrix[row][col] *= timeStep;
                        }
                    }
                }
            }

            IList <IRowSpec> rSpecList = dataTable.RowSpecList;

            for (int row = 0; row < fcsInfo.Rows; row++)
            {
                rSpecList[row].Id = row.ToString();
            }


            FileInfo fInfo     = new FileInfo(fileName);
            string   shortName = fInfo.Name.Substring(0, fInfo.Name.LastIndexOf('.'));

            if (saveMetaInfo >= 1)
            {
                SaveParameterTable(textTable, shortName);
                if (saveMetaInfo >= 2)
                {
                    textTable.SaveAsDataset(shortName + " (Text Seg)", "Text segement of data table " + shortName);
                }
            }

            if (autoCompensation)
            {
                try {
                    string sMatrix = null;
                    for (int i = 0; i < textTable.Rows; i++)
                    {
                        string id = textTable.RowSpecList[i].Id.ToLower();
                        if (id.StartsWith("$"))
                        {
                            id = id.Substring(1);
                        }
                        if ((id == "spill") || (id == "spillover"))
                        {
                            sMatrix = textTable.Matrix[i][0];
                            break;
                        }
                    }

                    if (sMatrix == null)
                    {
                        throw new Exception("");                   // silently ignore compensation as no compensation matrix available.
                    }
                    string[] fs        = sMatrix.Split(',');
                    int      dimension = int.Parse(fs[0]);

                    if (fs.Length != (dimension * dimension + dimension + 1))
                    {
                        throw new Exception("Invalid spill over matrix.");
                    }

                    INumberTable  cMatrix = app.New.NumberTable(dimension, dimension);
                    List <string> parList = fs.Skip(1).Take(dimension).ToList();

                    int idx;
                    if (parList.Count(id => int.TryParse(id, out idx)) == parList.Count)
                    {
                        // The columns are specified by a list of indexes. We convert them here to ids
                        for (int i = 0; i < parList.Count; i++)
                        {
                            parList[i] = dataTable.ColumnSpecList[int.Parse(parList[i]) - 1].Id;   // index starts with 1 !
                        }
                    }

                    for (int col = 0; col < cMatrix.Columns; col++)
                    {
                        cMatrix.ColumnSpecList[col].Id = parList[col];
                    }
                    int fsIdx = dimension + 1;
                    for (int row = 0; row < cMatrix.Rows; row++)
                    {
                        for (int col = 0; col < cMatrix.Columns; col++)
                        {
                            cMatrix.Matrix[row][col] = double.Parse(fs[fsIdx++]);
                        }
                    }

                    var cData = dataTable.SelectColumnsById(parList);
                    if (cData.Columns != parList.Count)
                    {
                        if (dataTable.ColumnSpecList.Count(cl => cl.Id.Equals("<" + parList[0] + ">")) == 1)
                        {
                            // siliently ignore aready compensated data.
                            throw new Exception("");
                        }
                        else
                        {
                            throw new Exception("Invalid spill over matrix: unknown names.");
                        }
                    }

                    var math = CustomImporter.App.GetMathAdaptor();
                    var m    = math.InvertMatrix((double[][])cMatrix.Matrix);
                    for (int row = 0; row < cMatrix.Rows; row++)
                    {
                        cMatrix.Matrix[row] = m[row];
                    }

                    cData = cData.Multiply(cMatrix);  // perform the comensation with the inverse matrix of the spill over matrix.
                    cData.CopyValuesTo(dataTable);
                    compensated = true;
                } catch (Exception ex) {
                    if (ex.Message != "")
                    {
                        MessageBox.Show("Cannot perform compensation: " + ex.Message);
                    }
                }
            }

            if (logTransform)
            {
                double[][] m = (double[][])dataTable.Matrix;

                double   T        = 262144;
                double   W        = 1.0;
                double   M        = 4.5;
                string[] settings = app.GetProperty(
                    "CustomImporter.Logicle.Settings", "262144; 1.0; 4.5").Split(';');
                if (settings.Length == 3)
                {
                    double.TryParse(settings[0], out T);
                    double.TryParse(settings[1], out W);
                    double.TryParse(settings[2], out M);
                }
                var    fastLogicle = new VisuMap.DataCleansing.FastLogicle(T, W, M);
                double maxVal      = fastLogicle.MaxValue;
                double minVal      = fastLogicle.MinValue;

                for (int col = 0; col < fcsInfo.Columns; col++)
                {
                    if (fcsInfo.ColumnInfo[col].LogTrans)
                    {
                        for (int row = 0; row < fcsInfo.Rows; row++)
                        {
                            m[row][col] = M * fastLogicle.scale(Math.Min(maxVal, Math.Max(minVal, m[row][col])));
                        }
                        logScaled = true;
                    }
                }
            }

            string msg = "Dataset imported from " + fileName + ". Version: " + fcsInfo.version;

            if (compensated)
            {
                msg += ", compensated";
            }
            if (logScaled)
            {
                msg += ", log-scaled";
            }
            string dsName = dataTable.SaveAsDataset(shortName, msg);

            app.Folder.OpenDataset(dsName);
            INumberTable nTable = app.GetNumberTable();


            List <IColumnSpec> csList = nTable.ColumnSpecList as List <IColumnSpec>;
            int fsc = csList.FindIndex(cs => cs.Id == "FSC-A");
            int ssc = csList.FindIndex(cs => cs.Id == "SSC-A");

            if ((fsc >= 0) && (ssc >= 0))
            {
                var xy = app.New.XyPlot(nTable);
                xy.Show();
                xy.XAxisIndex  = fsc;
                xy.YAxisIndex  = ssc;
                xy.AutoScaling = true;
                xy.Redraw();
                xy.CaptureMap();
                xy.Close();
                app.Map.Name = "FSC/SSC";
            }
            else
            {
                // We just do create a simple PCA view.
                IPcaView pca = nTable.ShowPcaView();
                pca.ResetView();
                pca.CaptureMap();
                app.Map.Redraw();
                pca.Close();
                app.Map.Name = "PCA-All";
            }

            app.Map.GlyphType = glyphName;
            app.Map.Redraw();

            if (showResult)
            {
                app.New.SpectrumBand(nTable).Show();
            }

            fcsInfo = null;
            return(true);
        }