private PCC.RootObject BuildUpPCCConfiguration(string driverName, CyPhy.PCCDriver PCCDriver, int upMethodNum, int saMethodNum) { PCC.RootObject rootConfig = new PCC.RootObject(); PCC.Configurations configs = new PCC.Configurations(); configs.Configuration = new PCC.Configuration(); configs.Configuration.Parts = new List<PCC.Part>(); PCC.Part part = new PCC.Part(); PCC.PCCInputArguments pccInputArgs = new PCC.PCCInputArguments(); part.ModelConfigFileName = "test_bench_model_config.json"; part.ToolConfigFileName = "test_bench_tool_config.json"; configs.Configuration.Parts.Add(part); configs.Configuration.Name = driverName; configs.Configuration.ID = PCCDriver.ID; configs.Configuration.PCCInputArguments = new PCC.PCCInputArguments(); pccInputArgs = configs.Configuration.PCCInputArguments; pccInputArgs.InputIDs = new List<string>(); pccInputArgs.OutputIDs = new List<string>(); pccInputArgs.StochasticInputs = new PCC.StochasticInputs(); pccInputArgs.StochasticInputs.InputDistributions = new List<PCCInputDistribution>(); pccInputArgs.PCCMetrics = new List<PCC.PCCMetric>(); foreach (var item in PCCDriver.Children.PCCParameterCollection) { //pccInputArgs.InputIDs.Add(item.ID); PCCInputDistribution inputDist = new PCCInputDistribution(); if (item is CyPhy.PCCParameterNormal) { inputDist.Distribution = "NORM"; inputDist.Param1 = (item as CyPhy.PCCParameterNormal).Attributes.Mean; inputDist.Param2 = (item as CyPhy.PCCParameterNormal).Attributes.StandardDeviation; } else if (item is CyPhy.PCCParameterUniform) { inputDist.Distribution = "UNIF"; inputDist.Param1 = (item as CyPhy.PCCParameterUniform).Attributes.LowLimit; inputDist.Param2 = (item as CyPhy.PCCParameterUniform).Attributes.HighLimit; } else if (item is CyPhy.PCCParameterLNormal) { inputDist.Distribution = "LNORM"; inputDist.Param1 = (item as CyPhy.PCCParameterLNormal).Attributes.Shape; inputDist.Param2 = (item as CyPhy.PCCParameterLNormal).Attributes.LogScale; } else if (item is CyPhy.PCCParameterBeta) { inputDist.Distribution = "BETA"; inputDist.Param1 = (item as CyPhy.PCCParameterBeta).Attributes.Shape1; inputDist.Param2 = (item as CyPhy.PCCParameterBeta).Attributes.Shape2; inputDist.Param3 = (item as CyPhy.PCCParameterBeta).Attributes.LowLimit; inputDist.Param4 = (item as CyPhy.PCCParameterBeta).Attributes.HighLimit; } foreach (var driveParameter in item.DstConnections.DriveParameterCollection) { inputDist.TestBenchParameterNames.Add(driveParameter.DstEnd.Name); } //inputDist.ID = inputDist.ID == null ? item.ID : inputDist.ID; inputDist.ID = item.ID; inputDist.Name = item.Name; pccInputArgs.StochasticInputs.InputDistributions.Add(inputDist); } pccInputArgs.StochasticInputs.InputDistributions = pccInputArgs.StochasticInputs.InputDistributions.OrderBy(p => p.TestBenchParameterNames.FirstOrDefault()).ToList(); foreach (var item in pccInputArgs.StochasticInputs.InputDistributions) { pccInputArgs.InputIDs.Add(item.ID); } foreach (var item in PCCDriver.Children.PCCOutputCollection) { //pccInputArgs.OutputIDs.Add(item.ID); if (item.Attributes.TargetPCCValue == 0) { this.Logger.WriteWarning("TargetPCCValue is set to zero. Is this correct?"); } var pccMetric = new PCC.PCCMetric(); pccMetric.ID = item.ID; pccMetric.TestBenchMetricName = item.SrcConnections.PCCOutputMappingCollection.FirstOrDefault().SrcEnd.Name; pccMetric.Name = "TestBench." + pccMetric.TestBenchMetricName; pccMetric.PCC_Spec = item.Attributes.TargetPCCValue; // Could this ever present a problem? var metricLimits = new PCC.Limits(); double dMin = double.NegativeInfinity; double dMax = double.PositiveInfinity; if (double.TryParse(item.Attributes.MinValue, out dMin) == false) { // using min infinity this.Logger.WriteWarning("MinValue must be 'Infinity,' '-Infinity,' or a double."); } if (double.TryParse(item.Attributes.MaxValue, out dMax) == false) { // using max infinity this.Logger.WriteWarning("MaxValue must be 'Infinity,' '-Infinity,' or a double."); } metricLimits.Min = dMin; metricLimits.Max = dMax; metricLimits.op = null; // "min/max/avg/none"; // metricLimits.minrange = null; // "value or n/a"; // TODO: add these 3 attributes to the PCCOutput component in CyPhy metricLimits.maxrange = null; //"value or n/a"; // pccMetric.Limits = metricLimits; pccInputArgs.PCCMetrics.Add(pccMetric); } pccInputArgs.PCCMetrics = pccInputArgs.PCCMetrics.OrderBy(m => m.TestBenchMetricName).ToList(); foreach (var item in pccInputArgs.PCCMetrics) { pccInputArgs.OutputIDs.Add(item.ID); } pccInputArgs.Methods = new List<int>(); if (upMethodNum > 0) { pccInputArgs.Methods.Add(upMethodNum); } if (saMethodNum > 0) { pccInputArgs.Methods.Add(saMethodNum); } rootConfig = new PCC.RootObject() { Configurations = configs }; return rootConfig; }
/// <summary> /// Goes through all Properties of component and looks for a registry node Distribution. If found at least three arguments divided by /// ',' is expected. The first argument is the type of input distribution, the rest (2 or 4) are the parameters for the input distribution. /// If everything is fulfilled the input is added to pccInputs. Which will be written to a json-file at the end of the code-generation. /// </summary> /// <param name="component">CyPhyComponent to extract PCCInputs from.</param> /// <param name="componentURI">The modelica URI for the component.</param> private void ExtractPCCInputs(CyPhy.Component component, string componentURI) { // TODO: Give feedback to user (move to checker?) foreach (var property in component.Children.PropertyCollection) { var dist = (property.Impl as GME.MGA.MgaFCO).RegistryNode["Distribution"].Value; if (dist != null) { var inputDistribution = new PCCInputDistribution(); var distParameters = dist.Split(','); string distType = distParameters.FirstOrDefault().Trim(); var pccInput = new PCCInputDistribution(); if (distType == "NORM" || distType == "UNIF" || distType == "LNORM" || distType == "BETA") { double param1; double param2; double param3 = 0; double param4 = 0; if (distParameters.Count() < 3 || double.TryParse(distParameters[1].Trim(), out param1) == false || double.TryParse(distParameters[2].Trim(), out param2) == false) { this.Logger.WriteWarning( "Found Distribution registry node for property : {0}, in component : {1}, but in wrong format.", property.Name, component.Name); continue; } else { if (distType == "BETA" && (distParameters.Count() < 5 || double.TryParse(distParameters[3].Trim(), out param3) == false || double.TryParse(distParameters[4].Trim(), out param4) == false)) { this.Logger.WriteWarning( "Found Distribution registry node for property : {0}, in component : {1}, but in wrong format.", property.Name, component.Name); continue; } pccInput.Distribution = distType; pccInput.Param1 = param1; pccInput.Param2 = param2; pccInput.Param3 = param3; pccInput.Param4 = param4; } } else { this.Logger.WriteWarning( "Found Distribution registry node for property : {0}, in component : {1}, but in wrong format.", property.Name, component.Name); continue; } bool badChars = false; foreach (char c in property.Name) { if(Rules.Global.invalidCharacters.Contains(c)) { badChars = true; break; } } if (badChars) { this.Logger.WriteWarning( "Found Distribution registry node for property : {0}, in component : {1}, property name is invalid '{0}'.", property.Name, component.Name); continue; } pccInput.Name = string.Format("{0}.{1}", componentURI, property.Name).Replace('.', '_'); pccInput.ID = property.ID; foreach (var modelicaPortMap in property.DstConnections.ModelicaParameterPortMapCollection) { pccInput.TestBenchParameterNames.Add(string.Format("{0}.{1}", componentURI, modelicaPortMap.DstEnds.ModelicaParameter.Name)); } this.pccInputs.Add(pccInput); } } }