/// <summary> /// Creates an uninitialized instance. /// </summary> public StateMachineDesigner(ReadoutLayerSettings readoutLayerCfg) { InputEncoderCfg = null; ReadoutLayerCfg = readoutLayerCfg ?? throw new ArgumentNullException("readoutCfg"); _rand = new Random(0); return; }
//Constructors /// <summary> /// Creates an uninitialized instance. /// </summary> public StateMachineSettings() { //Default settings RandomizerSeek = 0; NeuralPreprocessorConfig = new NeuralPreprocessorSettings(); ReadoutLayerConfig = new ReadoutLayerSettings(); MapperConfig = null; return; }
//Constructors /// <summary> /// Creates an uninitialized instance. /// </summary> public StateMachineSettings() { //Default settings RandomizerSeek = 0; InputConfig = new InputSettings(); ReservoirInstanceDefinitionCollection = new List <ReservoirInstanceDefinition>(); ReadoutLayerConfig = new ReadoutLayerSettings(); return; }
/// <summary> /// The deep copy constructor /// </summary> /// <param name="source">Source instance</param> public ReadoutLayerSettings(ReadoutLayerSettings source) { //Copy TestDataRatio = source.TestDataRatio; NumOfFolds = source.NumOfFolds; ReadoutUnitCfg = source.ReadoutUnitCfg.DeepClone(); OutputFieldNameCollection = new List <string>(source.OutputFieldNameCollection); return; }
//Constructors /// <summary> /// Creates an uninitialized instance. /// </summary> public StateMachineSettings() { //Default settings TaskType = CommonEnums.TaskType.Prediction; RandomizerSeek = 0; InputFieldNameCollection = new List <string>(); ReservoirInstanceDefinitionCollection = new List <ReservoirInstanceDefinition>(); RouteInputToReadout = false; ReadoutLayerConfig = new ReadoutLayerSettings(); return; }
//Constructor /// <summary> /// Creates an uninitialized instance /// </summary> /// <param name="taskType">Type of the task</param> /// <param name="settings">Readout layer configuration</param> /// <param name="rand">Random object to be used</param> public ReadoutLayer(CommonEnums.TaskType taskType, ReadoutLayerSettings settings, System.Random rand ) { _taskType = taskType; _settings = settings.DeepClone(); _rand = rand; _clusterCollection = new ReadoutUnit[_settings.OutputFieldNameCollection.Count][]; _clusterErrStatisticsCollection = new List <ClusterErrStatistics>(); return; }
//Constructors /// <summary> /// Creates an initialized instance /// </summary> /// <param name="neuralPreprocessorCfg">Configuration of the neural preprocessor</param> /// <param name="readoutLayerCfg">Configuration of the readout layer</param> /// <param name="mapperCfg">Configuration of mapper of predictors to readout units</param> /// <param name="randomizerSeek">Specifies random number generator's initial seek</param> public StateMachineSettings(NeuralPreprocessorSettings neuralPreprocessorCfg, ReadoutLayerSettings readoutLayerCfg, MapperSettings mapperCfg = null, int randomizerSeek = DefaultRandomizerSeek) { NeuralPreprocessorCfg = neuralPreprocessorCfg == null ? null : (NeuralPreprocessorSettings)neuralPreprocessorCfg.DeepClone(); ReadoutLayerCfg = (ReadoutLayerSettings)readoutLayerCfg.DeepClone(); MapperCfg = mapperCfg == null ? null : (MapperSettings)mapperCfg.DeepClone(); RandomizerSeek = randomizerSeek; Check(); return; }
//Constructors /// <summary> /// The deep copy constructor /// </summary> /// <param name="source">Source instance</param> public StateMachineSettings(StateMachineSettings source) { //Copy RandomizerSeek = source.RandomizerSeek; NeuralPreprocessorConfig = source.NeuralPreprocessorConfig.DeepClone(); ReadoutLayerConfig = new ReadoutLayerSettings(source.ReadoutLayerConfig); MapperCfg = null; if(source.MapperCfg != null) { MapperCfg = source.MapperCfg.DeepClone(); } return; }
/// <summary> /// The deep copy constructor /// </summary> /// <param name="source">Source instance</param> public StateMachineSettings(StateMachineSettings source) { //Copy RandomizerSeek = source.RandomizerSeek; InputConfig = source.InputConfig.DeepClone(); ReservoirInstanceDefinitionCollection = new List <ReservoirInstanceDefinition>(source.ReservoirInstanceDefinitionCollection.Count); foreach (ReservoirInstanceDefinition mapping in source.ReservoirInstanceDefinitionCollection) { ReservoirInstanceDefinitionCollection.Add(mapping.DeepClone()); } ReadoutLayerConfig = new ReadoutLayerSettings(source.ReadoutLayerConfig); return; }
/// <summary> /// The deep copy constructor /// </summary> /// <param name="source">Source instance</param> public StateMachineSettings(StateMachineSettings source) { //Copy TaskType = source.TaskType; RandomizerSeek = source.RandomizerSeek; InputFieldNameCollection = new List <string>(source.InputFieldNameCollection); ReservoirInstanceDefinitionCollection = new List <ReservoirInstanceDefinition>(source.ReservoirInstanceDefinitionCollection.Count); foreach (ReservoirInstanceDefinition mapping in source.ReservoirInstanceDefinitionCollection) { ReservoirInstanceDefinitionCollection.Add(mapping.DeepClone()); } RouteInputToReadout = source.RouteInputToReadout; ReadoutLayerConfig = new ReadoutLayerSettings(source.ReadoutLayerConfig); return; }
//Methods /// <summary> /// See the base. /// </summary> public override bool Equals(object obj) { if (obj == null) { return(false); } ReadoutLayerSettings cmpSettings = obj as ReadoutLayerSettings; if (TestDataRatio != cmpSettings.TestDataRatio || NumOfFolds != cmpSettings.NumOfFolds || !ReadoutUnitCfg.Equals(cmpSettings.ReadoutUnitCfg) || !OutputFieldNameCollection.ToArray().ContainsEqualValues(cmpSettings.OutputFieldNameCollection.ToArray()) ) { return(false); } return(true); }
/// <summary> /// Creates an initialized instance. /// </summary> /// <param name="elem">Xml element containing the initialization settings</param> public StateMachineSettings(XElement elem) { //Validation XElement settingsElem = Validate(elem, XsdTypeName); //Parsing RandomizerSeek = int.Parse(settingsElem.Attribute("randomizerSeek").Value); //Neural preprocessor XElement neuralPreprocessorElem = settingsElem.Elements("neuralPreprocessor").FirstOrDefault(); NeuralPreprocessorCfg = neuralPreprocessorElem == null ? null : new NeuralPreprocessorSettings(neuralPreprocessorElem); //Readout layer ReadoutLayerCfg = new ReadoutLayerSettings(settingsElem.Elements("readoutLayer").First()); //Mapper XElement mapperSettingsElem = settingsElem.Elements("mapper").FirstOrDefault(); MapperCfg = mapperSettingsElem == null ? null : new MapperSettings(mapperSettingsElem); Check(); return; }
//Constructor /// <summary> /// Creates an uninitialized instance. /// </summary> /// <param name="readoutLayerConfig">The configuration of the readout layer.</param> public VerificationResults(ReadoutLayerSettings readoutLayerConfig) { ReadoutLayerConfig = (ReadoutLayerSettings)readoutLayerConfig.DeepClone(); ComputationResultBundle = new ResultBundle(); ReadoutUnitStatCollection = new List <ReadoutUnitErrorStat>(ReadoutLayerConfig.ReadoutUnitsCfg.ReadoutUnitCfgCollection.Count); for (int i = 0; i < ReadoutLayerConfig.ReadoutUnitsCfg.ReadoutUnitCfgCollection.Count; i++) { ReadoutUnitStatCollection.Add(new ReadoutUnitErrorStat(i, ReadoutLayerConfig.ReadoutUnitsCfg.ReadoutUnitCfgCollection[i])); } OneTakesAllGroupStatCollection = new List <OneTakesAllGroupErrorStat>(); if (ReadoutLayerConfig.OneTakesAllGroupsCfg != null) { foreach (OneTakesAllGroupSettings groupCfg in ReadoutLayerConfig.OneTakesAllGroupsCfg.OneTakesAllGroupCfgCollection) { int[] unitIndexes = ReadoutLayerConfig.GetOneTakesAllGroupMemberRUnitIndexes(groupCfg.Name).ToArray(); OneTakesAllGroupStatCollection.Add(new OneTakesAllGroupErrorStat(groupCfg.Name, unitIndexes, ReadoutLayerConfig.ReadoutUnitsCfg.ReadoutUnitCfgCollection)); } } return; }
//Constructor /// <summary> /// Creates initialized instance /// </summary> /// <param name="readoutLayerConfig">Configuration of the Readout Layer</param> public VerificationResults(ReadoutLayerSettings readoutLayerConfig) { ReadoutLayerConfig = (ReadoutLayerSettings)readoutLayerConfig.DeepClone(); ComputationResultBundle = new ResultBundle(); ReadoutUnitStatCollection = new List <ReadoutUnitStat>(ReadoutLayerConfig.ReadoutUnitsCfg.ReadoutUnitCfgCollection.Count); for (int i = 0; i < ReadoutLayerConfig.ReadoutUnitsCfg.ReadoutUnitCfgCollection.Count; i++) { ReadoutUnitStatCollection.Add(new ReadoutUnitStat(i, ReadoutLayerConfig.ReadoutUnitsCfg.ReadoutUnitCfgCollection[i])); } OneWinnerGroupStatCollection = new List <OneWinnerGroupStat>(ReadoutLayerConfig.ReadoutUnitsCfg.OneWinnerGroupCollection.Keys.Count); foreach (string groupName in ReadoutLayerConfig.ReadoutUnitsCfg.OneWinnerGroupCollection.Keys) { ReadoutUnitsSettings.OneWinnerGroup owg = ReadoutLayerConfig.ReadoutUnitsCfg.OneWinnerGroupCollection[groupName]; int[] unitIndexes = new int[owg.Members.Count]; for (int i = 0; i < owg.Members.Count; i++) { unitIndexes[i] = ReadoutLayerConfig.ReadoutUnitsCfg.GetReadoutUnitID(owg.Members[i].Name); } OneWinnerGroupStatCollection.Add(new OneWinnerGroupStat(groupName, unitIndexes, ReadoutLayerConfig.ReadoutUnitsCfg.OneWinnerGroupCollection[groupName].Members)); } return; }
/// <summary> /// Creates the deep copy instance of this instance /// </summary> public ReadoutLayerSettings DeepClone() { ReadoutLayerSettings clone = new ReadoutLayerSettings(this); return(clone); }
/// <summary> /// Creates the instance and initializes it from given xml element. /// This is the preferred way to instantiate State Machine settings. /// </summary> /// <param name="elem"> /// Xml data containing State Machine settings. /// Content of xml element is always validated against the xml schema. /// </param> public StateMachineSettings(XElement elem) { //Validation ElemValidator validator = new ElemValidator(); Assembly assemblyRCNet = Assembly.GetExecutingAssembly(); validator.AddXsdFromResources(assemblyRCNet, "RCNet.Neural.Network.SM.StateMachineSettings.xsd"); validator.AddXsdFromResources(assemblyRCNet, "RCNet.RCNetTypes.xsd"); XElement stateMachineSettingsElem = validator.Validate(elem, "rootElem"); //Parsing //Task type TaskType = CommonEnums.ParseTaskType(stateMachineSettingsElem.Attribute("taskType").Value); //Randomizer seek RandomizerSeek = int.Parse(stateMachineSettingsElem.Attribute("randomizerSeek").Value); //Input fields XElement inputFieldsElem = stateMachineSettingsElem.Descendants("inputFields").First(); RouteInputToReadout = (inputFieldsElem.Attribute("routeToReadout") == null) ? false : bool.Parse(inputFieldsElem.Attribute("routeToReadout").Value); if (TaskType != CommonEnums.TaskType.Prediction && RouteInputToReadout) { throw new Exception("Routing input to readout is allowed for prediction task only."); } InputFieldNameCollection = new List <string>(); foreach (XElement inputFieldElem in inputFieldsElem.Descendants("field")) { InputFieldNameCollection.Add(inputFieldElem.Attribute("name").Value); } //Collect available reservoir settings List <ReservoirSettings> availableResSettings = new List <ReservoirSettings>(); XElement reservoirSettingsContainerElem = stateMachineSettingsElem.Descendants("reservoirCfgContainer").First(); foreach (XElement reservoirSettingsElem in reservoirSettingsContainerElem.Descendants("reservoirCfg")) { availableResSettings.Add(new ReservoirSettings(reservoirSettingsElem)); } //Readout layer XElement readoutLayerElem = stateMachineSettingsElem.Descendants("readoutLayer").First(); ReadoutLayerConfig = new ReadoutLayerSettings(readoutLayerElem); //Mapping of input fields to reservoir settings (future reservoir instance) ReservoirInstanceDefinitionCollection = new List <ReservoirInstanceDefinition>(); XElement reservoirInstancesContainerElem = stateMachineSettingsElem.Descendants("reservoirInstanceContainer").First(); foreach (XElement reservoirInstanceElem in reservoirInstancesContainerElem.Descendants("reservoirInstance")) { ReservoirInstanceDefinition newMap = new ReservoirInstanceDefinition(); newMap.InstanceName = reservoirInstanceElem.Attribute("name").Value; newMap.AugmentedStates = bool.Parse(reservoirInstanceElem.Attribute("augmentedStates").Value); //Select reservoir settings newMap.ReservoirSettings = (from settings in availableResSettings where settings.SettingsName == reservoirInstanceElem.Attribute("cfg").Value select settings).FirstOrDefault(); if (newMap.ReservoirSettings == null) { throw new Exception($"Reservoir settings '{reservoirInstanceElem.Attribute("cfg").Value}' was not found among available settings."); } //Associated State Machine input fields foreach (XElement inputFieldElem in reservoirInstanceElem.Descendants("inputFields").First().Descendants("field")) { string inputFieldName = inputFieldElem.Attribute("name").Value; //Index in InputFieldsNames int inputFieldIdx = InputFieldNameCollection.IndexOf(inputFieldName); //Found? if (inputFieldIdx < 0) { //Not found throw new Exception($"Reservoir instance {newMap.InstanceName}: input field {inputFieldName} is not defined among State Machine input fields."); } newMap.InputFieldMappingCollection.Add(inputFieldIdx); } ReservoirInstanceDefinitionCollection.Add(newMap); } return; }
/// <summary> /// Creates the instance and initializes it from given xml element. /// This is the preferred way to instantiate State Machine settings. /// </summary> /// <param name="elem"> /// Xml data containing State Machine settings. /// Content of xml element is always validated against the xml schema. /// </param> public StateMachineSettings(XElement elem) { //Validation ElemValidator validator = new ElemValidator(); Assembly assemblyRCNet = Assembly.GetExecutingAssembly(); validator.AddXsdFromResources(assemblyRCNet, "RCNet.Neural.Network.SM.StateMachineSettings.xsd"); validator.AddXsdFromResources(assemblyRCNet, "RCNet.RCNetTypes.xsd"); XElement stateMachineSettingsElem = validator.Validate(elem, "rootElem"); //Parsing //Randomizer seek RandomizerSeek = int.Parse(stateMachineSettingsElem.Attribute("randomizerSeek").Value); //Input InputConfig = new InputSettings(stateMachineSettingsElem.Descendants("input").First()); //Collect available reservoir settings List <ReservoirSettings> availableResSettings = new List <ReservoirSettings>(); XElement reservoirSettingsContainerElem = stateMachineSettingsElem.Descendants("reservoirCfgContainer").First(); foreach (XElement reservoirSettingsElem in reservoirSettingsContainerElem.Descendants("reservoirCfg")) { availableResSettings.Add(new ReservoirSettings(reservoirSettingsElem)); } //Readout layer XElement readoutLayerElem = stateMachineSettingsElem.Descendants("readoutLayer").First(); ReadoutLayerConfig = new ReadoutLayerSettings(readoutLayerElem); //Mapping of input fields to reservoir settings (future reservoir instance) ReservoirInstanceDefinitionCollection = new List <ReservoirInstanceDefinition>(); XElement reservoirInstancesContainerElem = stateMachineSettingsElem.Descendants("reservoirInstanceContainer").First(); int numOfNeuronsInLargestReservoir = 0; foreach (XElement reservoirInstanceElem in reservoirInstancesContainerElem.Descendants("reservoirInstance")) { ReservoirInstanceDefinition reservoirInstanceDefinition = new ReservoirInstanceDefinition { InstanceName = reservoirInstanceElem.Attribute("name").Value, AugmentedStates = bool.Parse(reservoirInstanceElem.Attribute("augmentedStates").Value), //Select reservoir settings Settings = (from settings in availableResSettings where settings.SettingsName == reservoirInstanceElem.Attribute("cfg").Value select settings).FirstOrDefault() }; if (reservoirInstanceDefinition.Settings == null) { throw new Exception($"Reservoir settings '{reservoirInstanceElem.Attribute("cfg").Value}' was not found among available settings."); } //Update number of neurons in the largest reservoir int numOfReservoirNeurons = 0; foreach (PoolSettings ps in reservoirInstanceDefinition.Settings.PoolSettingsCollection) { numOfReservoirNeurons += ps.Dim.Size; } if (numOfNeuronsInLargestReservoir < numOfReservoirNeurons) { numOfNeuronsInLargestReservoir = numOfReservoirNeurons; } //Distinct input field names and corresponding indexes using by the reservoir instance List <string> resInpFieldNameCollection = new List <string>(); foreach (XElement inputFieldConnectionElem in reservoirInstanceElem.Descendants("inputConnections").First().Descendants("inputConnection")) { //Input field name string inputFieldName = inputFieldConnectionElem.Attribute("fieldName").Value; //Index in InputConfig int inputFieldIdx = InputConfig.IndexOf(inputFieldName); //Found? if (inputFieldIdx < 0) { //Not found throw new Exception($"Reservoir instance {reservoirInstanceDefinition.InstanceName}: input field {inputFieldName} is not defined among State Machine input fields."); } //Add distinct name to the collection if (resInpFieldNameCollection.IndexOf(inputFieldName) < 0) { reservoirInstanceDefinition.SMInputFieldIdxCollection.Add(inputFieldIdx); resInpFieldNameCollection.Add(inputFieldName); } } //Connections of the reservoir's input fields to the pools foreach (XElement inputConnectionElem in reservoirInstanceElem.Descendants("inputConnections").First().Descendants("inputConnection")) { //Input field string inputFieldName = inputConnectionElem.Attribute("fieldName").Value; //Index in resInpFieldNameCollection int resInputFieldIdx = resInpFieldNameCollection.IndexOf(inputFieldName); //Found? if (resInputFieldIdx < 0) { //Not found throw new Exception($"Reservoir instance {reservoirInstanceDefinition.InstanceName}: input field {inputFieldName} is not defined among Reservoir's input fields."); } //Target pool string targetPoolName = inputConnectionElem.Attribute("poolName").Value; int targetPoolID = -1; //Find target pool ID (index) for (int idx = 0; idx < reservoirInstanceDefinition.Settings.PoolSettingsCollection.Count; idx++) { if (reservoirInstanceDefinition.Settings.PoolSettingsCollection[idx].Name == targetPoolName) { targetPoolID = idx; break; } } //Found? if (targetPoolID < 0) { //Not found throw new Exception($"Reservoir instance {reservoirInstanceDefinition.InstanceName}: pool {targetPoolName} is not defined among Reservoir pools."); } //Density double density = double.Parse(inputConnectionElem.Attribute("density").Value, CultureInfo.InvariantCulture); //Static synapse settings StaticSynapseSettings synapseCfg = new StaticSynapseSettings(inputConnectionElem.Descendants("staticSynapse").First()); //Add new assignment reservoirInstanceDefinition.InputConnectionCollection.Add(new ReservoirInstanceDefinition.InputConnection(resInputFieldIdx, targetPoolID, density, synapseCfg)); } ReservoirInstanceDefinitionCollection.Add(reservoirInstanceDefinition); } //Finalize boot cycles if necessary if (InputConfig.BootCycles == -1 && InputConfig.FeedingType == CommonEnums.InputFeedingType.Continuous) { InputConfig.BootCycles = numOfNeuronsInLargestReservoir; } return; }
/// <summary> /// Creates the instance and initializes it from given xml element. /// This is the preferred way to instantiate State Machine settings. /// </summary> /// <param name="elem"> /// Xml data containing State Machine settings. /// Content of xml element is always validated against the xml schema. /// </param> public StateMachineSettings(XElement elem) { //Validation ElemValidator validator = new ElemValidator(); Assembly assemblyRCNet = Assembly.GetExecutingAssembly(); validator.AddXsdFromResources(assemblyRCNet, "RCNet.Neural.Network.SM.StateMachineSettings.xsd"); validator.AddXsdFromResources(assemblyRCNet, "RCNet.RCNetTypes.xsd"); XElement stateMachineSettingsElem = validator.Validate(elem, "rootElem"); //Parsing //Randomizer seek RandomizerSeek = int.Parse(stateMachineSettingsElem.Attribute("randomizerSeek").Value); //Neural preprocessor NeuralPreprocessorConfig = new NeuralPreprocessorSettings(stateMachineSettingsElem.Descendants("neuralPreprocessor").First()); //Readout layer ReadoutLayerConfig = new ReadoutLayerSettings(stateMachineSettingsElem.Descendants("readoutLayer").First()); //Mapper XElement mapperSettingsElem = stateMachineSettingsElem.Descendants("mapper").FirstOrDefault(); if(mapperSettingsElem != null) { //Create mapper object MapperCfg = new MapperSettings(); //Loop through mappings foreach(XElement mapElem in mapperSettingsElem.Descendants("map")) { //Readout unit name string readoutUnitName = mapElem.Attribute("readoutUnitName").Value; int readoutUnitIdx = -1; for (int i = 0; i < ReadoutLayerConfig.ReadoutUnitCfgCollection.Count; i++) { if(ReadoutLayerConfig.ReadoutUnitCfgCollection[i].Name == readoutUnitName) { readoutUnitIdx = i; break; } else if(i == ReadoutLayerConfig.ReadoutUnitCfgCollection.Count - 1) { throw new Exception($"Name {readoutUnitName} not found among readout units."); } } //Allowed pools List<MapperSettings.AllowedPool> allowedPools = new List<MapperSettings.AllowedPool>(); XElement allowedPoolsElem = mapElem.Descendants("allowedPools").FirstOrDefault(); if (allowedPoolsElem != null) { foreach (XElement allowedPoolElem in allowedPoolsElem.Descendants("pool")) { //Reservoir instance name string reservoirInstanceName = allowedPoolElem.Attribute("reservoirInstanceName").Value; int reservoirInstanceIdx = -1; for (int i = 0; i < NeuralPreprocessorConfig.ReservoirInstanceDefinitionCollection.Count; i++) { if (NeuralPreprocessorConfig.ReservoirInstanceDefinitionCollection[i].InstanceName == reservoirInstanceName) { reservoirInstanceIdx = i; break; } else if (i == NeuralPreprocessorConfig.ReservoirInstanceDefinitionCollection.Count - 1) { throw new Exception($"Name {reservoirInstanceName} not found among resevoir instances."); } } //Pool name string reservoirCfgName = NeuralPreprocessorConfig.ReservoirInstanceDefinitionCollection[reservoirInstanceIdx].Settings.SettingsName; ReservoirSettings reservoirSettings = NeuralPreprocessorConfig.ReservoirInstanceDefinitionCollection[reservoirInstanceIdx].Settings; string poolName = allowedPoolElem.Attribute("poolName").Value; int poolIdx = -1; for (int i = 0; i < reservoirSettings.PoolSettingsCollection.Count; i++) { if (reservoirSettings.PoolSettingsCollection[i].Name == poolName) { poolIdx = i; break; } else if (i == reservoirSettings.PoolSettingsCollection.Count - 1) { throw new Exception($"Name {poolName} not found among resevoir's pools."); } } allowedPools.Add(new MapperSettings.AllowedPool { _reservoirInstanceIdx = reservoirInstanceIdx, _poolIdx = poolIdx }); } MapperCfg.PoolsMap.Add(readoutUnitName, allowedPools); } //Allowed routed input fields List<int> allowedRoutedFieldsIdxs = new List<int>(); XElement allowedInputFieldsElem = mapElem.Descendants("allowedInputFields").FirstOrDefault(); List<string> routedInputFieldNames = NeuralPreprocessorConfig.InputConfig.RoutedFieldNameCollection(); if (allowedInputFieldsElem != null) { foreach (XElement allowedInputFieldElem in allowedInputFieldsElem.Descendants("field")) { //Input field name string inputFieldName = allowedInputFieldElem.Attribute("name").Value; int routedFieldIdx = routedInputFieldNames.IndexOf(inputFieldName); if (routedFieldIdx == -1) { throw new Exception($"Name {inputFieldName} not found among input fields allowed to be routed to readout."); } allowedRoutedFieldsIdxs.Add(routedFieldIdx); } MapperCfg.RoutedInputFieldsMap.Add(readoutUnitName, allowedRoutedFieldsIdxs); } } } return; }