/// <summary>Main entry-point for this application.</summary> /// <exception cref="ArgumentNullException">Thrown when one or more required arguments are null.</exception> /// <param name="outputDirectory"> Directory to write files.</param> /// <param name="dataDirectory"> Allow passing in of data directory.</param> /// <param name="outputFormat"> The output format, JSON or XML (default: JSON).</param> /// <param name="state"> State to restrict generation to (default: none).</param> /// <param name="postalCode"> Postal code to restrict generation to (default: none).</param> /// <param name="facilityCount"> Number of facilities to generate.</param> /// <param name="timeSteps"> Number of time-step updates to generate.</param> /// <param name="timePeriodHours"> Time-step period in hours (default: 24).</param> /// <param name="seed"> Starting seed to use in generation, 0 for none (default: 0).</param> /// <param name="recordsToSkip"> Number of records to skip before starting generation (default: 0).</param> /// <param name="orgSource"> Source for organization records: generate|csv|connectathon (default: connectathon).</param> /// <param name="prettyPrint"> If output files should be formatted for display.</param> /// <param name="bedTypes"> Bar separated bed types: ICU|ER... (default: ICU|ER|HU).</param> /// <param name="operationalStatuses"> Bar separated operational status: U|O|K (default: O|U).</param> /// <param name="minBedsPerOrg"> The minimum number of beds per hospital (default: 10).</param> /// <param name="maxBedsPerOrg"> The maximum number of beds per hospital (default: 1000).</param> /// <param name="changeFactor"> The amount of change in bed state per step (default 0.2).</param> /// <param name="minIcuPercent"> Minimum percentage of beds for an org which are ICU type.</param> /// <param name="maxIcuPercent"> Maximum percentage of beds for an org which are ICU type.</param> /// <param name="ventilatorsPerIcu"> Average number of ventilators per ICU bed.</param> /// <param name="initialOccupancy"> Initial occupancy of bed percentage.</param> /// <param name="positiveTestRate"> Rate of people being tested returning positive.</param> /// <param name="hospitalizationRate"> Rate of people testing positive requiring hospitalization.</param> /// <param name="patientToIcuRate"> Rate of people hospitalized requiring ICU.</param> /// <param name="icuToVentilatorRate"> Rate of people in ICU requiring ventilators.</param> /// <param name="recoveryRate"> Rate of people recovering during hospitalization.</param> /// <param name="deathRate"> Rate of people dying in hospitalization, when care is available.</param> /// <param name="outputBundles"> True to output Bundles, false to output raw resources.</param> /// <param name="outputFlat"> True to output into a single directory, false to nest.</param> /// <param name="measureMarkdown"> If specified, the filename of the Measure Markdown file.</param> public static void Main( string outputDirectory, string dataDirectory = null, string outputFormat = "JSON", string state = null, string postalCode = null, int facilityCount = 10, int timeSteps = 2, int timePeriodHours = 24, int seed = 0, int recordsToSkip = 0, string orgSource = "connectathon", bool prettyPrint = true, string bedTypes = "ICU|ER|HU", string operationalStatuses = "O|U", int minBedsPerOrg = 10, int maxBedsPerOrg = 1000, double changeFactor = 0.2, double minIcuPercent = 0.05, double maxIcuPercent = 0.20, double ventilatorsPerIcu = 0.20, double initialOccupancy = 0.20, double positiveTestRate = 0.5, double hospitalizationRate = 0.30, double patientToIcuRate = 0.30, double icuToVentilatorRate = 0.70, double recoveryRate = 0.1, double deathRate = 0.05, bool outputBundles = true, bool outputFlat = false, string measureMarkdown = "") { // sanity checks if (string.IsNullOrEmpty(outputDirectory)) { throw new ArgumentNullException(nameof(outputDirectory)); } if (string.IsNullOrEmpty(outputFormat)) { throw new ArgumentNullException(nameof(outputFormat)); } if (!Directory.Exists(outputDirectory)) { Directory.CreateDirectory(outputDirectory); } _changeFactor = changeFactor; _minIcuPercent = minIcuPercent; _maxIcuPercent = maxIcuPercent; _ventilatorsPerIcu = ventilatorsPerIcu; _initialOccupancy = initialOccupancy; _positiveTestRate = positiveTestRate; _hospitalizationRate = hospitalizationRate; _patientToIcuRate = patientToIcuRate; _icuToVentilatorRate = icuToVentilatorRate; _recoveryRate = recoveryRate; _noResourceRecoveryRate = recoveryRate * 0.1; _deathRate = deathRate; _noResourceDeathRate = Math.Min(deathRate * 10, 1.0); _outputBundles = outputBundles; _outputFlat = outputFlat; _useJson = outputFormat.ToUpperInvariant().Equals("JSON", StringComparison.Ordinal); if (_useJson) { SerializerSettings settings = new SerializerSettings() { Pretty = prettyPrint, }; _jsonSerializer = new FhirJsonSerializer(settings); _extension = ".json"; } else { SerializerSettings settings = new SerializerSettings() { Pretty = prettyPrint, }; _xmlSerializer = new FhirXmlSerializer(settings); _extension = ".xml"; } _useLookup = (!string.IsNullOrEmpty(orgSource)) || (orgSource.ToUpperInvariant() != "GENERATE"); _connectathon = string.IsNullOrEmpty(orgSource) || (orgSource.ToUpperInvariant() == "CONNECTATHON"); if (seed == 0) { _rand = new Random(); } else { _rand = new Random(seed); } // always need the geo manager GeoManager.Init(seed, minBedsPerOrg, maxBedsPerOrg, dataDirectory); OrgWorkerData.Init(seed); // only need hospital manager if we are using lookup (avoid loading otherwise) if (_useLookup || _connectathon) { HospitalManager.Init( seed, minBedsPerOrg, maxBedsPerOrg, dataDirectory, _connectathon); } string dir; // create our time step directories if (!_outputFlat) { for (int step = 0; step < timeSteps; step++) { dir = Path.Combine(outputDirectory, $"t{step}"); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } } } // create our organization records CreateOrgs(facilityCount, state, postalCode, recordsToSkip); ExportAggregate(outputDirectory, timeSteps, timePeriodHours); if (!string.IsNullOrEmpty(measureMarkdown)) { File.WriteAllText(measureMarkdown, SanerMeasure.GetMarkdown()); } }