Example #1
0
        /// <summary>
        /// main Monte Carlo CommandLine (MCCL) application
        /// </summary>
        /// <param name="args"></param>
        /// <returns>int = 0 (successful completion)</returns>
        /// <returns>int = 1 (infile null or missing)</returns>
        /// <returns>int = 2 (infile exists but does not pass validation)</returns>
        public static int Main(string[] args)
        {
#if PROCESS_ATTACH_DEBUG
            Console.Read();
#endif
            string                 inFile         = "";
            List <string>          inFiles        = new List <string>();
            string                 outName        = "";
            string                 outPath        = "";
            bool                   infoOnlyOption = false;
            IList <ParameterSweep> paramSweep     = new List <ParameterSweep>();

            args.Process(() =>
            {
                logger.Info("\nVirtual Photonics MC 1.0\n");
                logger.Info("For more information type mc help");
                logger.Info("For help on a specific topic type mc.exe help=<topicname>\n");
            },
                         new CommandLine.Switch("help", val =>
            {
                var helpTopic = val.First();
                if (helpTopic != "")
                {
                    ShowHelp(helpTopic);
                }
                else
                {
                    ShowHelp();
                }
                infoOnlyOption = true;
                return;
            }),
                         new CommandLine.Switch("geninfiles", val =>
            {
                GenerateDefaultInputFiles();
                infoOnlyOption = true;
                return;
            }),
                         new CommandLine.Switch("infile", val =>
            {
                inFile = val.First();
                logger.Info(() => "input file specified as " + inFile);
                // MonteCarloSetup.InputFile = val.First();
            }),
                         new CommandLine.Switch("infiles", val =>
            {
                inFiles.AddRange(val);
                foreach (var file in inFiles)
                {
                    logger.Info(() => "input file specified as " + file);
                }
                // MonteCarloSetup.InputFile = val.First();
            }),
                         new CommandLine.Switch("outname", val =>
            {
                outName = val.First();
                logger.Info(() => "output name overridden as " + outName);
                //MonteCarloSetup.OutputFolder = val.First();
            }),
                         new CommandLine.Switch("outpath", val =>
            {
                outPath = val.First();
                logger.Info(() => "output path specified as " + outPath);
                //MonteCarloSetup.OutputFolder = val.First();
            }),
                         new CommandLine.Switch("paramsweep", val =>
            {
                var sweepString = val.ToArray();
                var sweep       = MonteCarloSetup.CreateParameterSweep(sweepString, ParameterSweepType.Count);
                if (sweep != null)
                {
                    paramSweep.Add(sweep);
                    logger.Info(() => "parameter sweep specified as " + sweepString[0] + " from " + sweepString[1] + " to " + sweepString[2] + ", with a count of " + sweepString[3]);
                }
            }),
                         new CommandLine.Switch("paramsweepdelta", val =>
            {
                var sweepString = val.ToArray();
                var sweep       = MonteCarloSetup.CreateParameterSweep(sweepString, ParameterSweepType.Delta);
                if (sweep != null)
                {
                    paramSweep.Add(sweep);
                    logger.Info(() => "parameter sweep specified as " + sweepString[0] + " from " + sweepString[1] + " to " + sweepString[2] + ", with a delta of " + sweepString[3]);
                }
            }),
                         new CommandLine.Switch("paramsweeplist", val =>
            {
                var sweepString = val.ToArray();
                var sweep       = MonteCarloSetup.CreateParameterSweep(sweepString, ParameterSweepType.List);
                if (sweep != null)
                {
                    paramSweep.Add(sweep);
                    logger.Info(() => "parameter sweep specified as " + sweepString[0] + " values");
                }
            }));

            if (!infoOnlyOption)
            {
                Func <SimulationInput, bool> checkValid = simInput =>
                {
                    var validationResult = MonteCarloSetup.ValidateSimulationInput(simInput);
                    if (!validationResult.IsValid)
                    {
                        Console.Write("\nSimulation(s) contained one or more errors. Details:");
                        Console.Write("\nValidation rule:" + validationResult.ValidationRule);
                        Console.Write("\nRemarks:" + validationResult.Remarks);
                        Console.Write("\nPress enter key to exit.");

                        if (Environment.GetEnvironmentVariable("TEST") == null)     // skip this if we're in a unit-test framework, so we can fail w/o waiting for user input
                        {
                            Console.Read();
                        }
                        return(false);
                    }
                    return(true);
                };

                if (paramSweep.Count() > 0 || inFiles.Count() > 0)
                {
                    IEnumerable <SimulationInput> inputs = null;
                    if (paramSweep.Count() > 0)
                    {
                        var input = MonteCarloSetup.ReadSimulationInputFromFile(inFile);
                        if (input == null)
                        {
                            return(1);
                        }
                        if (!string.IsNullOrEmpty(outName))
                        {
                            input.OutputName = outName;
                        }

                        //var sweeps = paramSweep.Select(sweep => MonteCarloSetup.CreateParameterSweep(sweep));
                        inputs = MonteCarloSetup.ApplyParameterSweeps(input, paramSweep);
                    }
                    else // if infiles.Count() > 0
                    {
                        inputs = inFiles.Select(file => MonteCarloSetup.ReadSimulationInputFromFile(file));
                        if (inputs.Count() == 0)
                        {
                            return(1);
                        }
                    }

                    foreach (var simulationInput in inputs)
                    {
                        if (!checkValid(simulationInput))
                        {
                            return(2);                    // override the output name with the user-specified name
                        }
                    }

                    MonteCarloSetup.RunSimulations(inputs, outPath);
                    logger.Info("\nSimulations complete.");
                    return(0);
                }
                else
                {
                    var input = MonteCarloSetup.ReadSimulationInputFromFile(inFile);
                    if (input == null)
                    {
                        return(1);
                    }

                    if (!checkValid(input))
                    {
                        return(2);
                    }

                    if (!string.IsNullOrEmpty(outName))
                    {
                        input.OutputName = outName;
                    }

                    MonteCarloSetup.RunSimulation(input, outPath);
                    logger.Info("\nSimulation complete.");
                    return(0);
                }
            }

            LogManager.Configuration = null;
            return(0);
        }
        /// <summary>
        /// main Monte Carlo CommandLine (MCCL) application
        /// </summary>
        /// <param name="args"></param>
        /// <returns>int = 0 (successful completion)</returns>
        /// <returns>int = 1 (infile null or missing)</returns>
        /// <returns>int = 2 (infile exists but does not pass validation)</returns>
        public static int Main(string[] args)
        {
#if PROCESS_ATTACH_DEBUG
            Console.Read();
#endif
            var inFile         = "";
            var inFiles        = new List <string>();
            var outName        = "";
            var outPath        = "";
            var CPUCount       = "1"; // default is to use 1
            var infoOnlyOption = false;
            IList <ParameterSweep> paramSweep = new List <ParameterSweep>();

            args.Process(() =>
            {
                logger.Info($"\nVirtual Photonics MC {GetVersionNumber(3)}\n");
                logger.Info("For more information type mc help");
                logger.Info("For help on a specific topic type dotnet mc.dll help=<topicname>\n");
            },
                         new CommandLine.Switch("help", val =>
            {
                var helpTopic = val.First();
                if (helpTopic != "")
                {
                    ShowHelp(helpTopic);
                }
                else
                {
                    ShowHelp();
                }
                infoOnlyOption = true;
            }),
                         new CommandLine.Switch("geninfiles", val =>
            {
                GenerateDefaultInputFiles();
                infoOnlyOption = true;
            }),
                         new CommandLine.Switch("infile", val =>
            {
                inFile = val.First();
                logger.Info(() => "input file specified as " + inFile);
            }),
                         new CommandLine.Switch("infiles", val =>
            {
                inFiles.AddRange(val);
                foreach (var file in inFiles)
                {
                    logger.Info(() => "input file specified as " + file);
                }
            }),
                         new CommandLine.Switch("outname", val =>
            {
                outName = val.First();
                logger.Info(() => "output name overridden as " + outName);
            }),
                         new CommandLine.Switch("outpath", val =>
            {
                outPath = val.First();
                logger.Info(() => "output path specified as " + outPath);
            }),
                         new CommandLine.Switch("cpucount", val =>
            {
                CPUCount = val.First();
                if (CPUCount == "all")
                {
                    CPUCount = Environment.ProcessorCount.ToString();
                    logger.Info(() => "changed to maximum CPUs on system " + CPUCount);
                }
                else
                {
                    if (!int.TryParse(CPUCount, out var CPUCountInt))
                    {
                        logger.Info(() => "unknown cpucount option " + CPUCount);
                    }
                    else
                    {
                        logger.Info(() => "number of CPUs specified as " + CPUCount);
                    }
                }
            }),
                         new CommandLine.Switch("paramsweep", val =>
            {
                var sweepString = val.ToArray();
                var sweep       = MonteCarloSetup.CreateParameterSweep(sweepString, ParameterSweepType.Count);
                if (sweep == null)
                {
                    return;
                }
                paramSweep.Add(sweep);
                logger.Info(() => "parameter sweep specified as " + sweepString[0] + " from " + sweepString[1] + " to " + sweepString[2] + ", with a count of " + sweepString[3]);
            }),
                         new CommandLine.Switch("paramsweepdelta", val =>
            {
                var sweepString = val.ToArray();
                var sweep       = MonteCarloSetup.CreateParameterSweep(sweepString, ParameterSweepType.Delta);
                if (sweep == null)
                {
                    return;
                }
                paramSweep.Add(sweep);
                logger.Info(() => "parameter sweep specified as " + sweepString[0] + " from " + sweepString[1] + " to " + sweepString[2] + ", with a delta of " + sweepString[3]);
            }),
                         new CommandLine.Switch("paramsweeplist", val =>
            {
                var sweepString = val.ToArray();
                var sweep       = MonteCarloSetup.CreateParameterSweep(sweepString, ParameterSweepType.List);
                if (sweep == null)
                {
                    return;
                }
                paramSweep.Add(sweep);
                logger.Info(() => "parameter sweep specified as " + sweepString[0] + " values");
            }));

            if (!infoOnlyOption)
            {
                Func <SimulationInput, bool> checkValid = simInput =>
                {
                    var validationResult = MonteCarloSetup.ValidateSimulationInput(simInput);
                    if (validationResult.IsValid)
                    {
                        return(true);
                    }
                    Console.Write("\nSimulation(s) contained one or more errors. Details:");
                    Console.Write("\nValidation rule:" + validationResult.ValidationRule);
                    Console.Write("\nRemarks:" + validationResult.Remarks);
                    Console.Write("\nPress enter key to exit.");
                    Console.Read();
                    return(false);
                };

                if (paramSweep.Any() || inFiles.Any())
                {
                    IList <SimulationInput> inputs;
                    if (paramSweep.Any())
                    {
                        var input = MonteCarloSetup.ReadSimulationInputFromFile(inFile);
                        if (input == null)
                        {
                            return(1);
                        }
                        if (!string.IsNullOrEmpty(outName))
                        {
                            input.OutputName = outName;
                        }

                        inputs = MonteCarloSetup.ApplyParameterSweeps(input, paramSweep).ToList();
                    }
                    else // if infiles.Count() > 0
                    {
                        inputs = inFiles.Select(file => MonteCarloSetup.ReadSimulationInputFromFile(file)).ToList();
                        if (!inputs.Any())
                        {
                            return(1);
                        }
                    }
                    // validate input
                    if (inputs.Any(simulationInput => !checkValid(simulationInput)))
                    {
                        return(2);
                    }
                    // make sure input does not specify Database if CPUCount>1
                    if (int.Parse(CPUCount) > 1 && (inputs.First().Options.Databases != null && inputs.First().Options.Databases.Count != 0))
                    {
                        CPUCount = 1.ToString();
                        logger.Info(() => "parallel processing cannot be performed when a Database is specified, changed CPUCount to 1");
                    }

                    MonteCarloSetup.RunSimulations(inputs, outPath, int.Parse(CPUCount));
                    logger.Info("\nSimulations complete.");
                    return(0);
                }
                else
                {
                    var input = MonteCarloSetup.ReadSimulationInputFromFile(inFile);
                    if (input == null)
                    {
                        return(1);
                    }

                    if (!checkValid(input))
                    {
                        return(2);
                    }

                    if (!string.IsNullOrEmpty(outName))
                    {
                        input.OutputName = outName;
                    }
                    // make sure input does not specify Database if CPUCount>1
                    if (int.Parse(CPUCount) > 1 && (input.Options.Databases != null && input.Options.Databases?.Count != 0))
                    {
                        CPUCount = 1.ToString();
                        logger.Info(() => "parallel processing cannot be performed when a Database is specified, changed CPUCount to 1");
                    }
                    MonteCarloSetup.RunSimulation(input, outPath, int.Parse(CPUCount));
                    logger.Info("\nSimulation complete.");
                    return(0);
                }
            }

            LogManager.Configuration = null;
            return(0);
        }