//private void ImageProcessing(ImagesProcessingData ipdt)
        //{

        //}



        private void EnumerateFilesToProcess()
        {
            string        directory = Path.GetDirectoryName(inputBasePath);
            string        filemask  = "*.jpg";
            List <string> filesList =
                new List <string>(Directory.EnumerateFiles(directory, filemask,
                                                           bEnumerateFilesRecursively ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly));



            #region filter by camID
            //...devID1.jpg
            string ptrnCamID = "devid" + CamIDtoProcess + ".jpg";

            filesList = filesList.Where(fname => fname.ToLower().Contains(ptrnCamID)).ToList();

            #endregion



            Console.WriteLine("found " + filesList.Count + " images.");


            #region list, read and map image stats files

            Console.WriteLine("filtering by ready-to-use GrIxYRGB XML files...");
            List <string> statsFilesList =
                new List <string>(Directory.EnumerateFiles(imageYRGBstatsXMLdataFilesDirectory, ConventionalTransitions.ImageGrIxYRGBstatsFileNamesPattern(),
                                                           bEnumerateFilesRecursively ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly));
            List <string> statsFilesListWOpath = statsFilesList.ConvertAll(Path.GetFileName);


            Console.WriteLine("found " + statsFilesList.Count + " XML stats files in directory " + Environment.NewLine +
                              imageYRGBstatsXMLdataFilesDirectory + Environment.NewLine + "by mask " +
                              Environment.NewLine + ConventionalTransitions.ImageGrIxYRGBstatsFileNamesPattern());

            int removed =
                filesList.RemoveAll(
                    fname =>
                    !statsFilesListWOpath.Contains(ConventionalTransitions.ImageGrIxYRGBstatsDataFileName(fname, "",
                                                                                                          false)));

            Console.WriteLine("removed " + removed + " items (couldn`t find stats data files). Remains " + filesList.Count + " to process.");


            if (!filesList.Any())
            {
                Console.WriteLine("There is no " + filemask + " files that sutisfy settings specified. Processing will not be started.");
                return;
            }


            lStatsProcessing = filesList.ConvertAll(strImgFname =>
            {
                ImagesProcessingData retVal = new ImagesProcessingData()
                {
                    filename = strImgFname
                };
                return(retVal);
            });

#if DEBUG
            //lStatsProcessing = lStatsProcessing.Where((ipd, ind) => ind < 10).ToList();
#endif

            Console.WriteLine("started reading and mapping stats data");

            int totalFilesCountToRead = lStatsProcessing.Count;
            int filesRead             = 0;
            int currProgressPerc      = 0;

            foreach (ImagesProcessingData ipdt in lStatsProcessing)
            {
                ipdt.grixyrgbStatsXMLfile =
                    statsFilesList.First(
                        statsFname =>
                        statsFname.Contains(ConventionalTransitions.ImageGrIxYRGBstatsDataFileName(ipdt.filename, "",
                                                                                                   false)));

                ipdt.grixyrgbStats =
                    ServiceTools.ReadObjectFromXML(ipdt.grixyrgbStatsXMLfile, typeof(SkyImageIndexesStatsData)) as
                    SkyImageIndexesStatsData;

                #region calculate and report progress

                filesRead++;
                double progress = 100.0d * (double)filesRead / (double)totalFilesCountToRead;
                if (progress - (double)currProgressPerc > 1.0d)
                {
                    currProgressPerc = Convert.ToInt32(progress);
                    Console.WriteLine("read " + currProgressPerc + "%");
                }

                #endregion calculate and report progress
            }

            #endregion



            #region list, read and map concurrent data

            List <string> concurrentDataFilesList =
                Directory.EnumerateFiles(ConcurrentDataXMLfilesDirectory,
                                         ConventionalTransitions.ImageConcurrentDataFilesNamesPattern(),
                                         bEnumerateFilesRecursively ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).ToList();

            List <ConcurrentData> lConcurrentData = null;

            #region reading
            Console.WriteLine("started concurrent data reading");

            totalFilesCountToRead = concurrentDataFilesList.Count;
            filesRead             = 0;
            currProgressPerc      = 0;

            List <Dictionary <string, object> > lDictionariesConcurrentData =
                new List <Dictionary <string, object> >();
            foreach (string strConcDataXMLFile in concurrentDataFilesList)
            {
                Dictionary <string, object> currDict = ServiceTools.ReadDictionaryFromXML(strConcDataXMLFile);
                currDict.Add("XMLfileName", Path.GetFileName(strConcDataXMLFile));

                lDictionariesConcurrentData.Add(currDict);

                #region calculate and report progress

                filesRead++;
                double progress = 100.0d * (double)filesRead / (double)totalFilesCountToRead;
                if (progress - (double)currProgressPerc > 1.0d)
                {
                    currProgressPerc = Convert.ToInt32(progress);
                    Console.WriteLine("read " + currProgressPerc + "%");
                }

                #endregion calculate and report progress
            }

            lDictionariesConcurrentData.RemoveAll(dict => dict == null);
            lConcurrentData =
                lDictionariesConcurrentData.ConvertAll <ConcurrentData>(dict =>
            {
                ConcurrentData retVal = null;
                try
                {
                    retVal = new ConcurrentData(dict);
                }
                catch (Exception ex)
                {
                    string strError = "couldn`t parse XML file " + dict["XMLfileName"] + " : " +
                                      Environment.NewLine + ex.Message;
                    Console.WriteLine(strError);
                }
                return(retVal);
            });
            lConcurrentData.RemoveAll(val => val == null);
            #endregion reading


            #region mapping

            // map obtained concurrent data to images by its datetime
            Console.WriteLine("concurrent data mapping started");

            lStatsProcessing = lStatsProcessing.ConvertAll(ipdt =>
            {
                string currImgFilename = ipdt.filename;
                currImgFilename        = Path.GetFileNameWithoutExtension(currImgFilename);

                string ptrn = @"(devID\d)";
                Regex rgxp  = new Regex(ptrn, RegexOptions.IgnoreCase);

                string strCurrImgDT = rgxp.Replace(currImgFilename.Substring(4), "");
                //2015-12-16T06-01-38
                strCurrImgDT = strCurrImgDT.Substring(0, 11) + strCurrImgDT.Substring(11).Replace("-", ":");

                DateTime currImgDT = DateTime.Parse(strCurrImgDT, null,
                                                    System.Globalization.DateTimeStyles.AdjustToUniversal);

                ConcurrentData nearestConcurrentData = lConcurrentData.Aggregate((cDt1, cDt2) =>
                {
                    TimeSpan tspan1 = new TimeSpan(Math.Abs((cDt1.datetimeUTC - currImgDT).Ticks));
                    TimeSpan tspan2 = new TimeSpan(Math.Abs((cDt2.datetimeUTC - currImgDT).Ticks));
                    return((tspan1 <= tspan2) ? (cDt1) : (cDt2));
                });


                if (new TimeSpan(Math.Abs((nearestConcurrentData.datetimeUTC - currImgDT).Ticks)) >=
                    TimeSpanForConcurrentDataMappingTolerance)
                {
                    string strError = "couldn`t find close enough concurrent data file for image:" + Environment.NewLine +
                                      currImgFilename + Environment.NewLine + "closest concurrent data file is:" +
                                      Environment.NewLine + nearestConcurrentData.filename + Environment.NewLine +
                                      "with date-time value " + nearestConcurrentData.datetimeUTC.ToString("o");
                    Console.WriteLine(strError);
                    nearestConcurrentData = null;
                }

                ipdt.concurrentData = nearestConcurrentData;
                if (nearestConcurrentData != null)
                {
                    ipdt.concurrentDataXMLfile = nearestConcurrentData.filename;
                }

                return(ipdt);
            });

            #endregion mapping

            removed = lStatsProcessing.RemoveAll(ipdt => ipdt.concurrentData == null);
            Console.WriteLine("removed " + removed + " items (couldn`t find concurrent data). " + lStatsProcessing.Count + " files remains to process.");

            #endregion list, read and map concurrent data


            if (!lStatsProcessing.Any())
            {
                Console.WriteLine("There is no files that sutisfy settings specified and have all required concurrent data (stats or GPS etc.). Processing will not be proceeded.");
                return;
            }


            #region Predict SDC values using pre-trained NN parameters


            string csvHeader = lStatsProcessing[0].grixyrgbStats.CSVHeader() +
                               ",SunElevationDeg,SunAzimuthDeg,sunDiskCondition";
            List <string> lCSVheader      = csvHeader.Split(',').ToList();
            List <int>    columnsToDelete =
                lCSVheader.Select((str, idx) => new Tuple <int, string>(idx, str))
                .Where(tpl => tpl.Item2.ToLower().Contains("filename")).ToList().ConvertAll(tpl => tpl.Item1);

            List <List <string> > lCalculatedData = lStatsProcessing.ConvertAll(dt =>
            {
                string currImageALLstatsDataCSVWithConcurrentData = dt.grixyrgbStats.ToCSV() + "," +
                                                                    dt.concurrentData.gps.SunZenithAzimuth()
                                                                    .ElevationAngle.ToString()
                                                                    .Replace(",", ".") + "," +
                                                                    dt.concurrentData.gps.SunZenithAzimuth()
                                                                    .Azimuth.ToString()
                                                                    .Replace(",", ".");
                List <string> retVal = currImageALLstatsDataCSVWithConcurrentData.Split(',').ToList();
                retVal = retVal.Where((str, idx) => !columnsToDelete.Contains(idx)).ToList();
                return(retVal);
            });


            List <DenseVector> lDV_objects_features =
                lCalculatedData.ConvertAll(
                    list =>
                    DenseVector.OfEnumerable(list.ConvertAll <double>(str => Convert.ToDouble(str.Replace(".", ",")))));


            DenseVector dvMeans  = (DenseVector)((DenseMatrix)ServiceTools.ReadDataFromCSV(NormMeansFile, 0, ",")).Row(0);
            DenseVector dvRanges = (DenseVector)((DenseMatrix)ServiceTools.ReadDataFromCSV(NormRangeFile, 0, ",")).Row(0);

            lDV_objects_features = lDV_objects_features.ConvertAll(dv =>
            {
                DenseVector dvShifted = dv - dvMeans;
                DenseVector dvNormed  = (DenseVector)dvShifted.PointwiseDivide(dvRanges);
                return(dvNormed);
            });

            DenseMatrix dmObjectsFeatures = DenseMatrix.OfRowVectors(lDV_objects_features);

            DenseVector dvThetaValues  = (DenseVector)ServiceTools.ReadDataFromCSV(NNtrainedParametersFile, 0, ",");
            List <int>  NNlayersConfig =
                new List <double>(((DenseMatrix)ServiceTools.ReadDataFromCSV(NNconfigFile, 0, ",")).Row(0)).ConvertAll
                    (dVal => Convert.ToInt32(dVal));


            List <List <double> > lDecisionProbabilities = null;

            List <SunDiskCondition> predictedSDClist =
                NNclassificatorPredictor <SunDiskCondition> .NNpredict(dmObjectsFeatures, dvThetaValues, NNlayersConfig,
                                                                       out lDecisionProbabilities, SunDiskConditionData.MatlabEnumeratedSDCorderedList()).ToList();


            //List<SunDiskCondition> predictedSDClist = predictedSDC.ConvertAll(sdcInt =>
            //{
            //    switch (sdcInt)
            //    {
            //        case 4:
            //            return SunDiskCondition.NoSun;
            //            break;
            //        case 1:
            //            return SunDiskCondition.Sun0;
            //            break;
            //        case 2:
            //            return SunDiskCondition.Sun1;
            //            break;
            //        case 3:
            //            return SunDiskCondition.Sun2;
            //            break;
            //        default:
            //            return SunDiskCondition.Defect;
            //    }
            //});

            string strToShow = "SDC values probabilities: " + Environment.NewLine +
                               "| No Sun | Sun_0  | Sun_1  | Sun_2  | Detected |" + Environment.NewLine;
            foreach (List <double> lDecisionProbability in lDecisionProbabilities)
            {
                strToShow += "| " + lDecisionProbability[3].ToString("F4") +
                             " | " + lDecisionProbability[0].ToString("F4") +
                             " | " + lDecisionProbability[1].ToString("F4") +
                             " | " + lDecisionProbability[2].ToString("F4") + " |" +
                             predictedSDClist[lDecisionProbabilities.IndexOf(lDecisionProbability)] + "|" +
                             Environment.NewLine;
            }
            ServiceTools.logToTextFile(errorLogFilename, strToShow, true, false);

            #endregion



            //lStatsProcessing =
            //    lStatsProcessing.Where((ipd, idx) => predictedSDClist[idx] == SunDiskCondition.Sun2).ToList();
            lStatsProcessing =
                lStatsProcessing.Where((ipd, idx) => predictedSDClist[idx] == sdcFilter).ToList();


            Console.WriteLine("Detected " + lStatsProcessing.Count + " images with SDC = " + sdcFilter.ToString());

            if (!lStatsProcessing.Any())
            {
                Console.WriteLine("There is no files with SDC = Sun2. Processing will not be proceeded.");
                return;
            }


            Console.WriteLine("finished enumerating and filtering files. Files to process: " + lStatsProcessing.Count);
        }
        public void Start(string[] args)
        {
            readDefaultProperties();

            List <string> argsList = new List <string>(args);

            string filename = argsList.Last();

            if (!File.Exists(filename))
            {
                Console.WriteLine("Couldn`t find input file \"" + filename + "\"");
                return;
            }

            CommonTools.PrintDictionaryToConsole(defaultProperties,
                                                 "Default settings specified in file \"" + defaultPropertiesXMLfileName + "\"");


            if (!File.Exists(NNconfigFile) || !File.Exists(NNtrainedParametersFile) || !File.Exists(NormMeansFile) || !File.Exists(NormRangeFile))
            {
                Console.WriteLine(
                    "couldn`t find at least one of pre-calculated NN parameters file specified in settings: ");
                return;
            }



            List <List <string> > csvFileContentStrings = ServiceTools.ReadDataFromCSV(filename, 0, true, ",");
            List <string>         csvFileHeader         = csvFileContentStrings[0];

            csvFileContentStrings = csvFileContentStrings.Where((list, idx) => idx > 0).ToList();
            List <int> columnsToDelete =
                csvFileHeader.Select((str, idx) => new Tuple <int, string>(idx, str))
                .Where(tpl => tpl.Item2.ToLower().Contains("filename")).ToList().ConvertAll(tpl => tpl.Item1);
            List <List <string> > csvFileContentStringsFiltered = new List <List <string> >();

            foreach (List <string> listDataStrings in csvFileContentStrings)
            {
                csvFileContentStringsFiltered.Add(
                    listDataStrings.Where((str, idx) => !columnsToDelete.Contains(idx)).ToList());
            }

            List <SunDiskCondition> trueAnswers =
                csvFileContentStringsFiltered.ConvertAll(
                    lstr => (SunDiskCondition)Enum.Parse(typeof(SunDiskCondition), lstr.Last()));


            //List<int> trueAnswersInt = trueAnswers.ConvertAll(sdc => SunDiskConditionData.MatlabNumeralSDC(sdc));

            List <List <string> > csvFileContentStringsFiltered_wo_sdc =
                csvFileContentStringsFiltered.ConvertAll(list => list.Where((val, idx) => idx < list.Count - 1).ToList());

            List <DenseVector> lDV_objects_features =
                csvFileContentStringsFiltered_wo_sdc.ConvertAll(
                    list =>
                    DenseVector.OfEnumerable(list.ConvertAll <double>(str => Convert.ToDouble(str.Replace(".", ",")))));


            DenseVector dvMeans  = (DenseVector)((DenseMatrix)ServiceTools.ReadDataFromCSV(NormMeansFile, 0, ",")).Row(0);
            DenseVector dvRanges = (DenseVector)((DenseMatrix)ServiceTools.ReadDataFromCSV(NormRangeFile, 0, ",")).Row(0);

            lDV_objects_features = lDV_objects_features.ConvertAll(dv =>
            {
                DenseVector dvShifted = dv - dvMeans;
                DenseVector dvNormed  = (DenseVector)dvShifted.PointwiseDivide(dvRanges);
                return(dvNormed);
            });

            DenseMatrix dmObjectsFeatures = DenseMatrix.OfRowVectors(lDV_objects_features);

            DenseVector dvThetaValues  = (DenseVector)ServiceTools.ReadDataFromCSV(NNtrainedParametersFile, 0, ",");
            List <int>  NNlayersConfig =
                new List <double>(((DenseMatrix)ServiceTools.ReadDataFromCSV(NNconfigFile, 0, ",")).Row(0)).ConvertAll
                    (dVal => Convert.ToInt32(dVal));

            List <SunDiskCondition> predictedSDC =
                NNclassificatorPredictor <SunDiskCondition> .NNpredict(dmObjectsFeatures, dvThetaValues, NNlayersConfig,
                                                                       SunDiskConditionData.MatlabEnumeratedSDCorderedList()).ToList();

            List <Tuple <SunDiskCondition, SunDiskCondition> > PredictedVStrue = predictedSDC.Zip(trueAnswers,
                                                                                                  (predVal, trueVal) => new Tuple <SunDiskCondition, SunDiskCondition>(predVal, trueVal)).ToList();


            Console.WriteLine("=== Prediction result vs true ===");
            foreach (Tuple <SunDiskCondition, SunDiskCondition> tpl in PredictedVStrue)
            {
                Console.WriteLine("pred: " + tpl.Item1.ToString() + ":" + tpl.Item2.ToString() + " :true");
            }

            double accuracy = 100.0d * ((double)PredictedVStrue.Count(tpl => tpl.Item1 == tpl.Item2)) /
                              (double)PredictedVStrue.Count();

            Console.WriteLine("accuracy: " + accuracy);


            Console.WriteLine("Finished. Press any key...");
            Console.ReadKey();
        }
        public static List<SunDiskCondition> PredictSDC_NN(
            List<Tuple<SkyImageIndexesStatsData, ConcurrentData>> lTplInputData, IEnumerable<int> SDC_NNconfig,
            IEnumerable<double> SDC_NNtrainedParameters,
            IEnumerable<double> NNfeturesNormMeans, IEnumerable<double> NNfeaturesNormRange,
            out List<List<double>> decisionProbabilitiesList)
        {

            List<string> lImagesALLstatsDataCSVWithConcurrentData = lTplInputData.ConvertAll(tpl =>
            {
                SkyImageIndexesStatsData imageStats = tpl.Item1;
                ConcurrentData snapshotConcurrentData = tpl.Item2;
                return imageStats.ToCSV() + "," +
                       snapshotConcurrentData.gps.SunZenithAzimuth().ElevationAngle.ToString().Replace(",", ".") + "," +
                       snapshotConcurrentData.gps.SunZenithAzimuth().Azimuth.ToString().Replace(",", ".");
            });
            // string currImageALLstatsDataCSVWithConcurrentData = 

            string csvHeader = lTplInputData.First().Item1.CSVHeader() +
                               ",SunElevationDeg,SunAzimuthDeg,sunDiskCondition";

            List<string> lCalculatedData = new List<string>();
            // lCalculatedData.Add(currImageALLstatsDataCSVWithConcurrentData);
            lCalculatedData.AddRange(lImagesALLstatsDataCSVWithConcurrentData);

            List<List<string>> csvFileContentStrings =
                lCalculatedData.ConvertAll(str => str.Split(',').ToList()).ToList();
            List<string> lCSVheader = csvHeader.Split(',').ToList();

            List<int> columnsToDelete =
                lCSVheader.Select((str, idx) => new Tuple<int, string>(idx, str))
                    .Where(tpl => tpl.Item2.ToLower().Contains("filename")).ToList().ConvertAll(tpl => tpl.Item1);
            List<List<string>> csvFileContentStringsFiltered = new List<List<string>>();
            foreach (List<string> listDataStrings in csvFileContentStrings)
            {
                csvFileContentStringsFiltered.Add(
                    listDataStrings.Where((str, idx) => !columnsToDelete.Contains(idx)).ToList());
            }



            List<List<string>> csvFileContentStringsFiltered_wo_sdc = csvFileContentStringsFiltered;

            List<DenseVector> lDV_objects_features =
                csvFileContentStringsFiltered_wo_sdc.ConvertAll(
                    list =>
                        DenseVector.OfEnumerable(list.ConvertAll<double>(str => Convert.ToDouble(str.Replace(".", ",")))));


            DenseVector dvMeans = DenseVector.OfEnumerable(NNfeturesNormMeans);
            DenseVector dvRanges = DenseVector.OfEnumerable(NNfeaturesNormRange);
            DenseVector dvThetaValues = DenseVector.OfEnumerable(SDC_NNtrainedParameters);
            List<int> NNlayersConfig = SDC_NNconfig.ToList();

            lDV_objects_features = lDV_objects_features.ConvertAll(dv =>
            {
                DenseVector dvShifted = dv - dvMeans;
                DenseVector dvNormed = (DenseVector)dvShifted.PointwiseDivide(dvRanges);
                return dvNormed;
            });

            DenseMatrix dmObjectsFeatures = DenseMatrix.OfRowVectors(lDV_objects_features);




            List<List<double>> lDecisionProbabilities = null;

            List<SunDiskCondition> predictedSDClist =
                NNclassificatorPredictor<SunDiskCondition>.NNpredict(dmObjectsFeatures, dvThetaValues, NNlayersConfig,
                    out lDecisionProbabilities, SunDiskConditionData.MatlabEnumeratedSDCorderedList()).ToList();

            //List<SunDiskCondition> predictedSDClist =
            //    predictedSDC.ConvertAll(sdcInt => SunDiskConditionData.MatlabSDCenum(sdcInt));


            decisionProbabilitiesList = lDecisionProbabilities;
            return predictedSDClist;
        }
Beispiel #4
0
        public static int PredictTCC_NN(SkyImageIndexesStatsData imageStats, ConcurrentData snapshotConcurrentData,
                                        IEnumerable <int> SDC_NNconfig, IEnumerable <double> SDC_NNtrainedParameters,
                                        IEnumerable <double> SDC_NNfeturesNormMeans,
                                        IEnumerable <double> SDC_NNfeaturesNormRange, IEnumerable <int> TCCnnLayersConfig,
                                        IEnumerable <double> TCC_NNtrainedParameters, IEnumerable <double> TCC_NNfeturesNormMeans,
                                        IEnumerable <double> TCC_NNfeaturesNormRange, IEnumerable <int> TCCnnConfigVarsToExclude,
                                        out List <double> TCCdecisionProbabilities)
        {
            string currImageALLstatsDataCSVWithConcurrentData = imageStats.ToCSV() + "," +
                                                                snapshotConcurrentData.gps.SunZenithAzimuth().ElevationAngle.ToString().Replace(",", ".") + "," +
                                                                snapshotConcurrentData.gps.SunZenithAzimuth().Azimuth.ToString().Replace(",", ".");

            List <string> lCalculatedData = new List <string>();

            lCalculatedData.Add(currImageALLstatsDataCSVWithConcurrentData);

            string        csvHeader       = imageStats.CSVHeader();
            List <string> lCSVheader      = csvHeader.Split(',').ToList();
            List <int>    columnsToDelete =
                lCSVheader.Select((str, idx) => new Tuple <int, string>(idx, str))
                .Where(tpl => tpl.Item2.ToLower().Contains("filename")).ToList().ConvertAll(tpl => tpl.Item1);


            List <List <string> > csvFileContentStrings =
                lCalculatedData.ConvertAll(str => str.Split(',').ToList()).ToList();
            List <List <string> > csvFileContentStringsFiltered = new List <List <string> >();

            foreach (List <string> listDataStrings in csvFileContentStrings)
            {
                csvFileContentStringsFiltered.Add(
                    listDataStrings.Where((str, idx) => !columnsToDelete.Contains(idx)).ToList());
            }

            #region SDC prediction

            List <List <string> > csvFileContentStringsFiltered_wo_CC = csvFileContentStringsFiltered;


            List <DenseVector> lDV_objects_features =
                csvFileContentStringsFiltered_wo_CC.ConvertAll(
                    list =>
                    DenseVector.OfEnumerable(list.ConvertAll <double>(CommonTools.ParseDouble)));
            DenseMatrix dmSDCpredictionObjectsFeatures = DenseMatrix.OfRows(lDV_objects_features);

            // DenseVector dvMeans = DenseVector.OfEnumerable(SDC_NNfeturesNormMeans);
            // DenseVector dvRanges = DenseVector.OfEnumerable(SDC_NNfeaturesNormRange);
            DenseMatrix dmSDCpredictionObjectsFeaturesNormed =
                ANNservice.FeatureNormalization(dmSDCpredictionObjectsFeatures, SDC_NNfeturesNormMeans,
                                                SDC_NNfeaturesNormRange);


            #region Predict SDC

            List <int>       sdcMatlabValues             = new List <int>();
            List <double>    lSDCpredictionProbabilities = new List <double>();
            SunDiskCondition sdc = SDCpredictorNN.PredictSDC_NN(imageStats, snapshotConcurrentData, SDC_NNconfig,
                                                                SDC_NNtrainedParameters, SDC_NNfeturesNormMeans, SDC_NNfeaturesNormRange, out lSDCpredictionProbabilities);
            sdcMatlabValues.Add(SunDiskConditionData.MatlabNumeralSDC(sdc));

            //lDV_objects_features = lDV_objects_features.Zip(sdcMatlabValues, (dv, intSDC) =>
            //{
            //    List<double> lFeaturesWithSDCdata = lDV_objects_features[0].ToList();
            //    lFeaturesWithSDCdata.Add((double)intSDC);
            //    return DenseVector.OfEnumerable(lFeaturesWithSDCdata);
            //}).ToList();

            #endregion Predict SDC

            #endregion SDC prediction

            DenseMatrix           dmTCCpredictionObjectsFeatures = dmSDCpredictionObjectsFeatures.Copy();
            List <List <double> > rowsSDCprobabilitiesPerObject  = new List <List <double> >();
            rowsSDCprobabilitiesPerObject.Add(lSDCpredictionProbabilities);
            DenseMatrix dmToAppend = DenseMatrix.OfRows(rowsSDCprobabilitiesPerObject);
            dmTCCpredictionObjectsFeatures = (DenseMatrix)dmTCCpredictionObjectsFeatures.Append(dmToAppend);

            // remove vars listed in TCCnnConfigVarsToExclude
            List <int> TCCnnConfigVarsToExcludeIndexes = TCCnnConfigVarsToExclude.ToList();
            TCCnnConfigVarsToExcludeIndexes = TCCnnConfigVarsToExcludeIndexes.ConvertAll(i => i - 1);           // based_1 indexes to based_0
            DenseMatrix dmTCCpredictionObjectsFeatures_RemovedExcludingFeatures =
                dmTCCpredictionObjectsFeatures.RemoveColumns(TCCnnConfigVarsToExcludeIndexes);


            DenseMatrix dmTCCpredictionObjectsFeatures_RemovedExcludingFeatures_Normed =
                ANNservice.FeatureNormalization(dmTCCpredictionObjectsFeatures_RemovedExcludingFeatures,
                                                TCC_NNfeturesNormMeans,
                                                TCC_NNfeaturesNormRange);


            List <List <double> > lTCCdecisionProbabilities = null;

            List <int> TCCvaluesSet = new List <int>();
            for (int i = 0; i < 9; i++)
            {
                TCCvaluesSet.Add(i);
            }
            List <int> predictedTCC =
                NNclassificatorPredictor <int> .NNpredict(dmTCCpredictionObjectsFeatures_RemovedExcludingFeatures_Normed,
                                                          TCC_NNtrainedParameters, TCCnnLayersConfig, out lTCCdecisionProbabilities, TCCvaluesSet).ToList();


            // Matlab trained TCC model: classes 1-9
            //predictedTCC = predictedTCC.ConvertAll(iVal => iVal - 1);

            TCCdecisionProbabilities = lTCCdecisionProbabilities[0];


            return(predictedTCC[0]);
        }