Beispiel #1
0
 public double[] ExtractProfile(int column, int profileIndex, TopographyProcessType type)
 {
     // some range checks
     if (column < 0)
     {
         return(InvalidProfile());
     }
     if (column >= NumberOfColumns)
     {
         return(InvalidProfile());
     }
     if (profileIndex < 0)
     {
         return(InvalidProfile());
     }
     if (profileIndex > scanMetaData.NumberOfProfiles)
     {
         return(InvalidProfile());                                              // starts at 1 !
     }
     if (profileIndex == 0)
     {
         return(ProcessTwoProfiles(AllProfiles(column, ScanDirection.Forward), AllProfiles(column, ScanDirection.Backward), type));
     }
     return(ProcessTwoProfiles(SingleProfile(column, profileIndex, ScanDirection.Forward), SingleProfile(column, profileIndex, ScanDirection.Backward), type));
 }
Beispiel #2
0
 private static void WarpNmmProfiles(TopographyProcessType processType, List <IntensityProfile> tempList)
 {
     for (int profileIndex = 0; profileIndex < theData.MetaData.NumberOfProfiles; profileIndex++)
     {
         double[] xData = theData.ExtractProfile(options.XAxisDesignation, profileIndex + 1, processType);
         double[] zData = theData.ExtractProfile(options.ZAxisDesignation, profileIndex + 1, processType);
         // convert Xdata from meter to micrometer
         for (int i = 0; i < xData.Length; i++)
         {
             xData[i] = xData[i] * 1.0e6;
         }
         tempList.Add(new IntensityProfile(xData, zData));
     }
 }
Beispiel #3
0
 // overload in case the column index is known already
 public double[] ExtractProfile(int columnIndex, int profileIndex, TopographyProcessType type)
 {
     return(topographyData.ExtractProfile(columnIndex, profileIndex, type));
 }
Beispiel #4
0
 // this is the main method: returns the profile for a given symbol and index
 public double[] ExtractProfile(string columnSymbol, int profileIndex, TopographyProcessType type)
 {
     return(ExtractProfile(GetColumnIndexFor(columnSymbol), profileIndex, type));
 }
Beispiel #5
0
        public static void Main(string[] args)
        {
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
            if (!CommandLine.Parser.Default.ParseArgumentsStrict(args, options))
            {
                Console.WriteLine("*** ParseArgumentsStrict returned false");
            }
            // consume the verbosity option
            if (options.BeQuiet == true)
            {
                ConsoleUI.BeSilent();
            }
            else
            {
                ConsoleUI.BeVerbatim();
            }
            // print a welcome message
            ConsoleUI.Welcome();
            ConsoleUI.WriteLine();
            // get the filename(s)
            fileNames = options.ListOfFileNames.ToArray();
            if (fileNames.Length == 0)
            {
                ConsoleUI.ErrorExit("!Missing input file", 1);
            }

            // if no filetype was choosen, use default one
            if (!(options.convertBcr ||
                  options.convertPrDe ||
                  options.convertPrEn ||
                  options.convertPrf ||
                  options.convertSig ||
                  options.convertSmd ||
                  options.convertTxt ||
                  options.convertCsv ||
                  options.convertX3p))
            {
                options.convertSig = true;                      // this should be convertBcr in the future
            }
            // read all relevant scan data
            ConsoleUI.StartOperation("Reading and evaluating files");
            nmmFileNameObject = new NmmFileName(fileNames[0]);
            nmmFileNameObject.SetScanIndex(options.ScanIndex);
            theData = new NmmScanData(nmmFileNameObject);
            ConsoleUI.Done();
            ConsoleUI.WriteLine();

            if (options.DoHeydemann)
            {
                theData.ApplyHeydemannCorrection();
                if (theData.HeydemannCorrectionApplied)
                {
                    ConsoleUI.WriteLine($"Heydemann correction applied, span {theData.HeydemannCorrectionSpan * 1e9:F1} nm");
                }
                else
                {
                    ConsoleUI.WriteLine($"Heydemann correction not successful.");
                }
                ConsoleUI.WriteLine();
            }

            // some checks of the provided CLA options
            if (options.ProfileIndex < 0)
            {
                options.ProfileIndex = 0;   // automatically extract all profiles
            }
            if (options.ProfileIndex > theData.MetaData.NumberOfProfiles)
            {
                options.ProfileIndex = theData.MetaData.NumberOfProfiles;
            }

            topographyProcessType = TopographyProcessType.ForwardOnly;
            if (options.UseBack)
            {
                topographyProcessType = TopographyProcessType.BackwardOnly;
            }
            if (options.UseBoth)
            {
                topographyProcessType = TopographyProcessType.Average;
            }
            if (options.UseDiff)
            {
                topographyProcessType = TopographyProcessType.Difference;
            }
            if (theData.MetaData.ScanStatus == ScanDirectionStatus.ForwardOnly)
            {
                if (topographyProcessType != TopographyProcessType.ForwardOnly)
                {
                    ConsoleUI.WriteLine("No backward scan data present, switching to forward only.");
                }
                topographyProcessType = TopographyProcessType.ForwardOnly;
            }
            if (theData.MetaData.ScanStatus == ScanDirectionStatus.Unknown)
            {
                ConsoleUI.ErrorExit("!Unknown scan type", 2);
            }
            if (theData.MetaData.ScanStatus == ScanDirectionStatus.NoData)
            {
                ConsoleUI.ErrorExit("!No scan data present", 3);
            }

            // now we can start to sort and format everything we need

            prf.CreationDate         = theData.MetaData.CreationDate;
            prf.SampleIdentification = theData.MetaData.SampleIdentifier;
            prf.DeltaX      = theData.MetaData.ScanFieldDeltaX * 1e6;
            prf.UserComment = options.UserComment;

            // extract the requested profile
            if (options.ProfileIndex != 0)
            {
                ProcessSingleProfile(options.ProfileIndex);
                return;
            }
            // (ProfileIndex == 0) => extract all profiles
            for (int i = 1; i <= theData.MetaData.NumberOfProfiles; i++)
            {
                ProcessSingleProfile(i);
            }
        }
Beispiel #6
0
        static void Main(string[] args)
        {
            // parse command line arguments
            var options = new Options();

            if (!CommandLine.Parser.Default.ParseArgumentsStrict(args, options))
            {
                Console.WriteLine("*** ParseArgumentsStrict returned false");
            }
            if (options.BeQuiet == true)
            {
                ConsoleUI.BeSilent();
            }
            else
            {
                ConsoleUI.BeVerbatim();
            }
            ConsoleUI.Welcome();

            // get the filename(s)
            string[] fileNames = options.ListOfFileNames.ToArray();
            if (fileNames.Length == 0)
            {
                ConsoleUI.ErrorExit("!Missing input file", 1);
            }
            // read all relevant scan data
            ConsoleUI.StartOperation("Reading and evaluating files");
            NmmFileName nmmFileName = new NmmFileName(fileNames[0]);

            nmmFileName.SetScanIndex(options.ScanIndex);
            NmmScanData nmmScanData = new NmmScanData(nmmFileName);

            ConsoleUI.Done();

            if (options.DoHeydemann)
            {
                nmmScanData.ApplyHeydemannCorrection();
                if (nmmScanData.HeydemannCorrectionApplied)
                {
                    ConsoleUI.WriteLine($"Heydemann correction applied, span {nmmScanData.HeydemannCorrectionSpan * 1e9:F1} nm");
                }
                else
                {
                    ConsoleUI.WriteLine($"Heydemann correction not successful.");
                }
            }

            // some checks of the provided CLA options
            if (options.ProfileIndex < 0)
            {
                options.ProfileIndex = 0;
            }
            if (options.ProfileIndex > nmmScanData.MetaData.NumberOfProfiles)
            {
                options.ProfileIndex = nmmScanData.MetaData.NumberOfProfiles;
            }

            TopographyProcessType topographyProcessType = TopographyProcessType.ForwardOnly;

            if (options.UseBack)
            {
                topographyProcessType = TopographyProcessType.BackwardOnly;
            }
            if (options.UseBoth)
            {
                topographyProcessType = TopographyProcessType.Average;
            }
            if (options.UseDiff)
            {
                topographyProcessType = TopographyProcessType.Difference;
            }
            if (nmmScanData.MetaData.ScanStatus == ScanDirectionStatus.ForwardOnly)
            {
                if (topographyProcessType != TopographyProcessType.ForwardOnly)
                {
                    ConsoleUI.WriteLine("No backward scan data present, switching to forward only.");
                }
                topographyProcessType = TopographyProcessType.ForwardOnly;
            }
            if (nmmScanData.MetaData.ScanStatus == ScanDirectionStatus.Unknown)
            {
                ConsoleUI.ErrorExit("!Unknown scan type", 2);
            }
            if (nmmScanData.MetaData.ScanStatus == ScanDirectionStatus.NoData)
            {
                ConsoleUI.ErrorExit("!No scan data present", 3);
            }

            // now we can start to sort and format everything we need
            BcrWriter bcr = new BcrWriter();

            bcr.Relaxed = !options.Strict; // overrules Relaxed
            ConsoleUI.WriteLine(bcr.Relaxed ? "Relaxed formatting" : "Strict formatting");
            bcr.ForceIsoFormat = options.IsoFormat;
            ConsoleUI.WriteLine(bcr.ForceIsoFormat ? "ISO 25178-71 format" : "Legacy format");

            // ISO 25178-71 file header
            bcr.CreationDate             = nmmScanData.MetaData.CreationDate;
            bcr.ManufacurerId            = nmmScanData.MetaData.InstrumentIdentifier;
            bcr.NumberOfPointsPerProfile = nmmScanData.MetaData.NumberOfDataPoints;
            if (options.ProfileIndex == 0)
            {
                bcr.NumberOfProfiles = nmmScanData.MetaData.NumberOfProfiles;
                bcr.YScale           = nmmScanData.MetaData.ScanFieldDeltaY;
                ConsoleUI.WriteLine("Extract complete scanfield");
            }
            else
            {
                bcr.NumberOfProfiles = 1;
                bcr.YScale           = 0;
                ConsoleUI.WriteLine($"Extract single profile {options.ProfileIndex} only");
            }
            bcr.XScale = nmmScanData.MetaData.ScanFieldDeltaX;
            bcr.ZScale = options.ZScale;

            // read actual topography data for given channel
            if (!nmmScanData.ColumnPresent(options.ChannelSymbol))
            {
                ConsoleUI.ErrorExit($"!Channel {options.ChannelSymbol} not in scan data", 5);
            }
            double[] rawData = nmmScanData.ExtractProfile(options.ChannelSymbol, options.ProfileIndex, topographyProcessType);

            // level data
            DataLeveling levelObject;

            if (options.ProfileIndex == 0)
            {
                levelObject = new DataLeveling(rawData, nmmScanData.MetaData.NumberOfDataPoints, nmmScanData.MetaData.NumberOfProfiles);
            }
            else
            {
                levelObject = new DataLeveling(rawData, nmmScanData.MetaData.NumberOfDataPoints);
            }
            levelObject.BiasValue = options.Bias * 1.0e-6; //  bias is given in µm on the command line
            double[] leveledTopographyData = levelObject.LevelData(MapOptionToReference(options.ReferenceMode));

            // generate a dictionary with all relevant metadata for the ISO 25178-71 file trailer
            Dictionary <string, string> bcrMetaData = new Dictionary <string, string>();

            bcrMetaData.Add("InputFile", nmmScanData.MetaData.BaseFileName);
            bcrMetaData.Add("ConvertedBy", $"{ConsoleUI.Title} version {ConsoleUI.Version}");
            bcrMetaData.Add("UserComment", options.UserComment);
            bcrMetaData.Add("OperatorName", nmmScanData.MetaData.User);
            bcrMetaData.Add("Organisation", nmmScanData.MetaData.Organisation);
            bcrMetaData.Add("SampleIdentifier", nmmScanData.MetaData.SampleIdentifier);
            bcrMetaData.Add("SampleSpecies", nmmScanData.MetaData.SampleSpecies);
            bcrMetaData.Add("SampleSpecification", nmmScanData.MetaData.SampleSpecification);
            bcrMetaData.Add("SPMtechnique", nmmScanData.MetaData.SpmTechnique);
            bcrMetaData.Add("Probe", nmmScanData.MetaData.ProbeDesignation);
            bcrMetaData.Add("ZAxisSource", options.ChannelSymbol);
            bcrMetaData.Add("Trace", topographyProcessType.ToString());
            if (options.ProfileIndex != 0)
            {
                bcrMetaData.Add("NumProfiles", $"{nmmScanData.MetaData.NumberOfProfiles}");
                bcrMetaData.Add("ExtractedProfile", $"{options.ProfileIndex}");
            }
            if (nmmScanData.MetaData.NumberOfScans > 1)
            {
                bcrMetaData.Add("NumberOfScans", $"{nmmScanData.MetaData.NumberOfScans}");
                bcrMetaData.Add("Scan", $"{nmmScanData.MetaData.ScanIndex}");
            }
            bcrMetaData.Add("ReferenceDatum", levelObject.LevelModeDescription);
            if (nmmScanData.HeydemannCorrectionApplied)
            {
                bcrMetaData.Add("HeydemannCorrection", $"Span {nmmScanData.HeydemannCorrectionSpan * 1e9:F1} nm");
            }
            bcrMetaData.Add("EnvironmentMode", nmmScanData.MetaData.EnvironmentMode);
            bcrMetaData.Add("SampleTemperature", $"{nmmScanData.MetaData.SampleTemperature:F3} oC");
            bcrMetaData.Add("AirTemperature", $"{nmmScanData.MetaData.AirTemperature:F3} oC");
            bcrMetaData.Add("AirPressure", $"{nmmScanData.MetaData.BarometricPressure:F0} Pa");
            bcrMetaData.Add("AirHumidity", $"{nmmScanData.MetaData.RelativeHumidity:F1} %");
            bcrMetaData.Add("TemperatureGradient", $"{nmmScanData.MetaData.AirTemperatureGradient:F3} oC");
            bcrMetaData.Add("TemperatureRange", $"{nmmScanData.MetaData.AirTemperatureDrift:F3} oC");
            bcrMetaData.Add("ScanSpeed", $"{nmmScanData.MetaData.ScanSpeed * 1e6} um/s");
            bcrMetaData.Add("AngularOrientation", $"{nmmScanData.MetaData.ScanFieldRotation:F3} grad");
            bcrMetaData.Add("ScanFieldCenterX", $"{nmmScanData.MetaData.ScanFieldCenterZ * 1000:F3} mm");
            bcrMetaData.Add("ScanFieldCenterY", $"{nmmScanData.MetaData.ScanFieldCenterY * 1000:F3} mm");
            bcrMetaData.Add("ScanFieldCenterZ", $"{nmmScanData.MetaData.ScanFieldCenterZ * 1000:F3} mm");
            bcrMetaData.Add("ScanFieldOriginX", $"{nmmScanData.MetaData.ScanFieldOriginX} m");
            bcrMetaData.Add("ScanFieldOriginY", $"{nmmScanData.MetaData.ScanFieldOriginY} m");
            bcrMetaData.Add("ScanFieldOriginZ", $"{nmmScanData.MetaData.ScanFieldOriginZ} m");
            bcrMetaData.Add("ScanDuration", $"{nmmScanData.MetaData.ScanDuration.TotalSeconds:F0} s");
            bcrMetaData.Add("GlitchedDataPoints", $"{nmmScanData.MetaData.NumberOfGlitchedDataPoints}");
            bcrMetaData.Add("SpuriousDataLines", $"{nmmScanData.MetaData.SpuriousDataLines}");
            for (int i = 0; i < nmmScanData.MetaData.ScanComments.Count; i++)
            {
                bcrMetaData.Add($"ScanComment{i + 1}", nmmScanData.MetaData.ScanComments[i]);
            }

            // ISO 25178-71 main section
            bcr.PrepareMainSection(leveledTopographyData);

            // ISO 25178-71 file trailer
            bcr.PrepareTrailerSection(bcrMetaData);

            // now generate output
            string outFileName;

            if (fileNames.Length >= 2)
            {
                outFileName = fileNames[1];
            }
            else
            {
                outFileName = nmmFileName.GetFreeFileNameWithIndex("sdf");
            }

            ConsoleUI.WritingFile(outFileName);
            if (!bcr.WriteToFile(outFileName))
            {
                ConsoleUI.Abort();
                ConsoleUI.ErrorExit("!could not write file", 4);
            }
            ConsoleUI.Done();
        }
Beispiel #7
0
        private double[] ProcessTwoProfiles(double[] fwdProfile, double[] bwdProfile, TopographyProcessType type)
        {
            if (fwdProfile.Length != bwdProfile.Length)
            {
                return(null);
            }
            double[] resultProfile = new double[fwdProfile.Length];
            switch (type)
            {
            case TopographyProcessType.None:
                return(InvalidProfile());

            case TopographyProcessType.ForwardOnly:
                return(fwdProfile);

            case TopographyProcessType.BackwardOnly:
                return(bwdProfile);

            case TopographyProcessType.Average:
                for (int i = 0; i < fwdProfile.Length; i++)
                {
                    resultProfile[i] = (fwdProfile[i] + bwdProfile[i]) * 0.5;
                }
                break;

            case TopographyProcessType.Difference:
                for (int i = 0; i < fwdProfile.Length; i++)
                {
                    resultProfile[i] = fwdProfile[i] - bwdProfile[i];
                }
                break;
            }
            return(resultProfile);
        }