Ejemplo n.º 1
0
        public async Task FitSingleProfile(FittingProfile profile)
        {
            var d_data = WideScan.GetRestrictedData(profile.RangeBegin, profile.RangeEnd).Differentiate(_differentialWindow);

            var fitting_results = new FittingProfile.FittingResult();

            // キーはサイクル数.
            EqualIntervalData target_data = new EqualIntervalData();

            // 1.まず,フィッティングの計算を行う.
            {
                #region  固定参照スペクトルを取得する。(一時的にコメントアウト中)

                /*
                 * List<decimal> fixed_data = new List<decimal>();
                 * if (FixedSpectra.Count > 0)
                 * {
                 *      var v_data = await FixedSpectra.ForEachAsync(
                 *              async sp => await sp.GetShiftedDataAsync(d_data.Parameter, 3), 10);
                 *
                 *      for (int j = 0; j < v_data.First().Count; j++)
                 *      {
                 *              fixed_data.Add(v_data.Sum(one => one[j]));
                 *      }
                 * }
                 */
                #endregion

                /// フィッティング対象となるデータ。すなわち、もとのデータからFixされた分を差し引いたデータ。
                //var target_data = fixed_data.Count > 0 ? data.Substract(fixed_data) : data;
                // なんだけど、とりあえずはFixedを考慮しない。
                target_data = d_data.Data;

                //fitting_tasks.Add(i, profile.FitOneCycle(i, target_data[i], d_data.Parameter));
                fitting_results = profile.FitOneCycle(-1, target_data, d_data.Parameter);
            }

            // 2.その後に,チャート出力を行う?

            Gnuplot charts = await Output(d_data.Parameter, profile, target_data, fitting_results);


            // pltファイルも出力してみる。
            using (var writer = new StreamWriter(GetCsvFileName(profile.Name, -1) + ".plt"))
            {
                await charts.OutputPltFileAsync(writer);
            }
            // チャートを描画する。
            await charts.Draw();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// ファイルからスペクトルを読み込み,指定されたプロファイルの参照データとします.
        /// </summary>
        /// <param name="idFileName"></param>
        /// <param name="profile"></param>
        /// <returns></returns>
        public async Task AddReferenceSpectrumAsync(string idFileName, FittingProfile profile)
        {
            var dir = Path.GetDirectoryName(idFileName);

            if ((await IdFile.CheckTypeAsync(idFileName)) == DataType.WideScan)
            {
                // OK
                profile.ReferenceSpectra.Add(new ReferenceSpectrum {
                    DirectoryName = dir
                });
            }
            else
            {
                //var error_message = new SimpleMessage(this) { Message = "WideScanじゃないとだめだよ!" };
                //Messenger.Default.Send(this, error_message);
            }
        }
Ejemplo n.º 3
0
        // とりあえず分けた.

        /// <summary>
        /// profileで指定した範囲に最適なROIを探し出します.
        /// </summary>
        /// <param name="profile"></param>
        protected ROISpectra FindROI(FittingProfile profile)
        {
            // profileがBaseROIを持つのではなく,ここでBaseとなるROIを決定するようにしてみた.

            // ★一応,範囲から推測するのをベースにするけど,
            // ★ROIの名前からでも指定できるようにするのがいいのでは?

            // ProfileのRangeを包含するROIを探す.
            var suitable_roi_list = ROISpectraCollection.Where(roi => roi.Parameter.Start <= profile.RangeBegin && roi.Parameter.Stop >= profile.RangeEnd);

            if (suitable_roi_list.Count() == 0)
            {
                var message = $"{profile.Name}に対応する測定データがありませんでした。エネルギー範囲を確認して下さい。 {profile.RangeBegin} - {profile.RangeEnd}";
                // 終了.並列実行することがあるので,例外を発生させる.
                throw new MyException(message);
            }
            return(suitable_roi_list.OrderBy(roi => roi.Parameter.Step).First());
        }
Ejemplo n.º 4
0
        public void LoadFrom(StreamReader reader)
        {
            var doc  = XDocument.Load(reader);
            var root = doc.Root;

            if (root.Name == ELEMENT_NAME)
            {
                this.OutputDestination = (string)root.Attribute(OUTPUTDESTINATION_ATTRIBUTE);
                var chart_format = (string)root.Attribute(CHARTFORMAT_ATTRIBUTE);
                if (!string.IsNullOrEmpty(chart_format))
                {
                    this.ChartFormat = (ChartFormat)Enum.Parse(typeof(ChartFormat), chart_format);
                }
            }

            FittingProfiles.Clear();
            foreach (var profile in root.Element(PROFILES_ELEMENT).Elements(FittingProfile.ELEMENT_NAME))
            {
                this.FittingProfiles.Add(FittingProfile.LoadProfile(profile));
            }
        }
Ejemplo n.º 5
0
        // (0.1.0)メソッド名をFitからOutputに変更.というか,これどこにおけばいいのかな?
        private async Task <Gnuplot> Output(
            ScanParameter originalParameter,
            FittingProfile profile,
            EqualIntervalData target_data,
            FittingProfile.FittingResult result)
        {
            // フィッティングした結果をチャートにする?
            // ★とりあえずFixedなデータは表示しない。

            bool output_convolution = result.Standards.Count > 1;

            // それには、csvを出力する必要がある。
            //string fitted_csv_path = Path.Combine(FittingCondition.OutputDestination, $"{FittingCondition.Name}_{layer}.csv");
            using (var csv_writer = new StreamWriter(GetCsvFileName(profile.Name)))
            {
                await OutputFittedCsv(csv_writer, originalParameter, target_data, result, output_convolution).ConfigureAwait(false);
            }

            // チャート出力の準備?
            return(ConfigureChart(result, profile, output_convolution));
        }
Ejemplo n.º 6
0
        // (0.1.0)メソッド名をFitからOutputに変更.というか,これどこにおけばいいのかな?
        #region *CSVを出力して,グラフ描画の準備を行う(Output)
        /// <summary>
        /// フィッティングした結果から,チャートの出力を設定します.
        /// </summary>
        /// <param name="cycle"></param>
        /// <param name="originalParameter"></param>
        /// <param name="profile"></param>
        /// <param name="target_data"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private async Task <Gnuplot> Output(
            int cycle,
            ScanParameter originalParameter,
            FittingProfile profile,
            EqualIntervalData target_data,
            FittingProfile.FittingResult result)
        {
            // フィッティングした結果をチャートにする?
            // ★とりあえずFixedなデータは表示しない。
            Trace.WriteLine($"Let's start outputting! cycle{cycle} {DateTime.Now}     [{Thread.CurrentThread.ManagedThreadId}]");
            bool output_convolution = result.Standards.Count > 1;

            // それには、csvを出力する必要がある。
            using (var csv_writer = new StreamWriter(GetCsvFileName(cycle, profile.Name)))
            {
                await OutputFittedCsv(csv_writer, originalParameter, target_data, result, output_convolution);
            }
            Trace.WriteLine($"CSV output Completed! cycle{cycle} {DateTime.Now}     [{Thread.CurrentThread.ManagedThreadId}]");

            // チャート出力の準備?
            return(ConfigureChart(result, profile, output_convolution, cycle));

            #region こうすると,1024バイトほど書き込んだところで落ちる.
            // どう違うのかはよくわかっていない.

            /*
             * Gnuplot chartConfiguration;
             * // chartConfigurationを構成して返す処理とcsv出力処理が入り交じっているので注意.(こういう書き方しか思いつかなかった.)
             * using (var csv_writer = new StreamWriter(GetCsvFileName(cycle, profile.Name)))
             * {
             *      //var outputCsvTask = OutputFittedCsv(csv_writer, originalParameter, target_data, result, output_convolution);
             *      //chartConfiguration = ConfigureChart(cycle, result, profile, output_convolution);
             *      //await outputCsvTask;
             *      await OutputFittedCsv(csv_writer, originalParameter, target_data, result, output_convolution);
             * }
             * return chartConfiguration;
             */
            #endregion
        }
Ejemplo n.º 7
0
        public static FittingProfile LoadProfile(XElement profileElement)
        {
            var profile = new FittingProfile();

            profile.Name       = (string)profileElement.Attribute(NAME_ATTRIBUTE);
            profile.RangeBegin = (decimal)profileElement.Attribute(ENERGYBEGIN_ATTRIBUTE);
            profile.RangeEnd   = (decimal)profileElement.Attribute(ENERGYEND_ATTRIBUTE);
            profile.WithOffset = (bool)profileElement.Attribute(WITHOFFSET_ATTRIBUTE);

            var energy_shift = (decimal?)profileElement.Attribute(ENERGYSHIFT_ATTRIBUTE);

            if (profile.FixEnergyShift = energy_shift.HasValue)
            {
                profile.FixedEnergyShift = energy_shift.Value;
            }

            profile.ReferenceSpectra.Clear();
            foreach (var reference in profileElement.Element(REFERENCES_ELEMENT).Elements(REFERENCE_ELEMENT))
            {
                profile.ReferenceSpectra.Add(new ReferenceSpectrum {
                    DirectoryName = (string)reference.Attribute(DIRECTORY_ATTRIBUTE)
                });
            }

            profile.FixedSpectra.Clear();
            foreach (var reference in profileElement.Element(REFERENCES_ELEMENT).Elements(FIXED_REFERENCES_ELEMENT))
            {
                profile.FixedSpectra.Add(new FixedSpectrum {
                    DirectoryName = (string)reference.Attribute(DIRECTORY_ATTRIBUTE),
                    Gain          = (decimal)reference.Attribute(GAIN_ATTRIBUTE),
                    Shift         = (decimal)reference.Attribute(SHIFT_ATTRIBUTE)
                });
            }

            return(profile);
        }
Ejemplo n.º 8
0
 // 指定したプロファイルを削除する?
 public void RemoveFittingProfile(FittingProfile profile)
 {
     FittingCondition.FittingProfiles.Remove(profile);
 }
Ejemplo n.º 9
0
        /// <summary>
        /// 具体的なチャートの設定を行います.
        /// </summary>
        /// <param name="cycle"></param>
        /// <param name="result"></param>
        /// <param name="profile"></param>
        /// <param name="outputConvolution"></param>
        /// <returns></returns>
        public Gnuplot ConfigureChart(FittingProfile.FittingResult result, FittingProfile profile, bool outputConvolution, int cycle = -1)
        {
            string chart_ext = string.Empty;

            switch (FittingCondition.ChartFormat)
            {
            case ChartFormat.Png:
                chart_ext = ".png";
                break;

            case ChartFormat.Svg:
                chart_ext = ".svg";
                break;
            }

            var chart_destination = Path.Combine(FittingCondition.OutputDestination, $"{profile.Name}{(cycle >= 0 ? string.Format("_{0}", cycle) : string.Empty)}{chart_ext}");

            #region チャート設定
            var gnuplot = new Gnuplot
            {
                Format      = FittingCondition.ChartFormat,
                Width       = 800,
                Height      = 600,
                FontScale   = 1.6,
                Destination = chart_destination,
                XTitle      = "Kinetic Energy / eV",
                YTitle      = "dN(E)/dE",
                Title       = (cycle >= 0 ? $"Cycle {cycle} , " : string.Empty) + $"Shift {result.Shift} eV"
            };

            var source_csv = GetCsvFileName(profile.Name, cycle);

            gnuplot.DataSeries.Add(new LineChartSeries
            {
                SourceFile = source_csv,
                XColumn    = 1,
                YColumn    = 2,
                Title      = "data",
                Style      = new LineChartSeriesStyle(LineChartStyle.Lines)
                {
                    Style = new LinePointStyle
                    {
                        LineColor = "#FF0000",
                        LineWidth = 3,
                    }
                }
            });

            var reference_names = profile.ReferenceSpectra.Select(r => r.Name).ToList();
            for (int j = 0; j < reference_names.Count; j++)
            {
                gnuplot.DataSeries.Add(new LineChartSeries
                {
                    SourceFile = source_csv,
                    XColumn    = 1,
                    YColumn    = j + 3,
                    Title      = $"{result.Gains[j].ToString("f3")} * {reference_names[j]}",
                    Style      = new LineChartSeriesStyle(LineChartStyle.Lines)
                    {
                        Style = new LinePointStyle
                        {
                            LineColorIndex = j,
                            LineWidth      = 2,
                        }
                    }
                });
            }

            if (outputConvolution)
            {
                gnuplot.DataSeries.Add(new LineChartSeries
                {
                    SourceFile = source_csv,
                    XColumn    = 1,
                    YColumn    = reference_names.Count + 3,
                    Title      = "Convolution",
                    Style      = new LineChartSeriesStyle(LineChartStyle.Lines)
                    {
                        Style = new LinePointStyle
                        {
                            LineColor = "#0000FF",
                            LineWidth = 3,
                        }
                    }
                });
            }
            #endregion

            gnuplot.PreConfigureAxis();

            return(gnuplot);
        }
Ejemplo n.º 10
0
        // (0.1.0)1つのProfileについてのみフィッティングを行う.
        #region *1つのProfileに対してフィッティングを行う(FitSingleProfile)
        public async Task FitSingleProfile(FittingProfile profile)
        {
            // profileがBaseROIを持つのではなく,ここでBaseとなるROIを決定するようにしてみた.

            // ★一応,範囲から推測するのをベースにするけど,
            // ★ROIの名前からでも指定できるようにするのがいいのでは?

            // ProfileのRangeを包含するROIを探す.
            var baseROI = FindROI(profile);

            var d_data = baseROI.Restrict(profile.RangeBegin, profile.RangeEnd)
                         .Differentiate(3);

            //var fitting_tasks = new Dictionary<int, Task<FittingProfile.FittingResult>>();
            var fitting_results = new Dictionary <int, FittingProfile.FittingResult>();

            // キーはサイクル数.
            Dictionary <int, EqualIntervalData> target_data = new Dictionary <int, EqualIntervalData>();

            // 1.まず,フィッティングの計算を行う.
            foreach (int i in FittingCondition.TargetCycles)
            {
                #region  固定参照スペクトルを取得する。(一時的にコメントアウト中)

                /*
                 * List<decimal> fixed_data = new List<decimal>();
                 * if (FixedSpectra.Count > 0)
                 * {
                 *      var v_data = await FixedSpectra.ForEachAsync(
                 *              async sp => await sp.GetShiftedDataAsync(d_data.Parameter, 3), 10);
                 *
                 *      for (int j = 0; j < v_data.First().Count; j++)
                 *      {
                 *              fixed_data.Add(v_data.Sum(one => one[j]));
                 *      }
                 * }
                 */
                #endregion

                /// フィッティング対象となるデータ。すなわち、もとのデータからFixされた分を差し引いたデータ。
                //var target_data = fixed_data.Count > 0 ? data.Substract(fixed_data) : data;
                // なんだけど、とりあえずはFixedを考慮しない。
                target_data[i] = d_data.Data[i];

                fitting_results.Add(i, profile.FitOneCycle(i, target_data[i], d_data.Parameter));
            }

            // 2.その後に,チャート出力を行う?

            //Dictionary<int, Gnuplot> charts = new Dictionary<int, Gnuplot>();
            Dictionary <int, Task <Gnuplot> > gnuplot_tasks = new Dictionary <int, Task <Gnuplot> >();
            foreach (int i in FittingCondition.TargetCycles)
            {
                gnuplot_tasks[i] = Output(i, d_data.Parameter, profile, target_data[i], fitting_results[i]);
            }
            await Task.WhenAll(gnuplot_tasks.Values.ToArray());

            Dictionary <int, Gnuplot> charts = new Dictionary <int, Gnuplot>();
            foreach (var task in gnuplot_tasks)
            {
                charts[task.Key] = task.Value.Result;
            }

            // 全てのchartで共通の軸範囲を使用する.
            Range x_range = Range.Union(charts.Select(gnuplot => gnuplot.Value.XAxis.Range).ToArray());
            Range y_range = Range.Union(charts.Select(gnuplot => gnuplot.Value.YAxis.Range).ToArray());
            //Range x_range = Range.Union(charts.Select(gnuplot => gnuplot.Value.Result.XAxis.Range).ToArray());
            //Range y_range = Range.Union(charts.Select(gnuplot => gnuplot.Value.Result.YAxis.Range).ToArray());

            Parallel.ForEach(charts.Keys,
                             async(i) =>
            {
                charts[i].DefineXAxis(x_range);
                charts[i].DefineYAxis(y_range);
                //charts[i].Result.SetXAxis(x_range);
                //charts[i].Result.SetYAxis(y_range);

                // pltファイルも出力してみる。
                using (var writer = new StreamWriter(GetCsvFileName(i, profile.Name) + ".plt"))
                {
                    await charts[i].OutputPltFileAsync(writer);
                    //await charts[i].Result.OutputPltFileAsync(writer);
                }
                // チャートを描画する。
                await charts[i].Draw();
                //await charts[i].Result.Draw();
            }
                             );
        }