public void Parse(WaveformConfigFileType file, RFmxInstrMX instr)
        {
            // Ensure CanParse was first called prior to executing this function
            if (rootData == null)
            {
                bool result = CanParse(file);
                if (!result)
                {
                    throw new InvalidOperationException($"{file.FileName} is not a valid file for this plugin.");
                }
            }
            using (LogContext.PushProperty("Plugin", nameof(NrRfwsPlugin)))
            {
                // The RFWS file breaks up the NR configuration in two sections: a section representing carrier definitions (in which
                // the NR specific configurations are set), and then a all of the carrier sets in the waveform. These carrier sets
                // reference one of the carrier definitions and configure properties such as the frequency offset for the carrier.
                //
                // This doesn't neatly map to RFmx, so an extra step is performed after reading in these objects to then create
                // a unified object matching the RFmx layout.

                int carrierSetIndex = 0;
                List <RfwsCarrierSet> carrierSets = new List <RfwsCarrierSet>();
                foreach (XElement carrierSetSection in rootData.FindSections <RfwsCarrierSet>())
                {
                    RfwsCarrierSet set = carrierSetSection.Deserialize <RfwsCarrierSet>();
                    carrierSets.Add(set);
                }
                List <Carrier> carriers = new List <Carrier>();
                foreach (XElement carrierDefinitionSetion in rootData.FindSections <Carrier>())
                {
                    Carrier carrier = carrierDefinitionSetion.Deserialize <Carrier>();
                    carriers.Add(carrier);
                }
                // Now that we have loaded all relevant information from the file, construct the final object
                // and pass the data to the serialization engine to create the RFmx NR signal
                foreach (RfwsCarrierSet set in carrierSets)
                {
                    NrSignalModel signal   = new NrSignalModel(set, carriers);
                    RFmxNRMX      nrSignal = instr.CreateNRSignalConfigurationFromObject(signal, signalName: $"CarrierSet{carrierSetIndex}");
                    // Select initial measurements so RFmx doesn't complain on launch that nothing is selected
                    nrSignal.SelectMeasurements("", RFmxNRMXMeasurementTypes.Acp | RFmxNRMXMeasurementTypes.ModAcc, true);
                    // RFmx will complain in some configurations if this enabled; since the plugin identifes the RBs this uneeded
                    nrSignal.SetAutoResourceBlockDetectionEnabled("", RFmxNRMXAutoResourceBlockDetectionEnabled.False);
                    carrierSetIndex++;
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Constructs the unified signal model from an individual RFWS carrier set definition and the list of carriers
        /// that are included within that carrier set definition.
        /// </summary>
        /// <param name="set"></param>
        /// <param name="carriers"></param>
        public NrSignalModel(RfwsCarrierSet set, List <Carrier> carriers)
        {
            int numSubblocks = set.SubblockCarrierSettings.Max(s => (int)s.SubblockIndex) + 1;

            AutoIncrementCellId = set.AutoIncrementCellId;
            NumberOfSubblocks   = numSubblocks;
            Subblocks           = new List <Subblock>(numSubblocks);

            for (int i = 0; i < numSubblocks; i++)
            {
                // Get all component carriers for the current subblock iteration
                var currentSubblockSettings = set.SubblockCarrierSettings.Where(s => s.SubblockIndex == i);
                // The subblock properties are identical in each subblock configuration, so using the first is fine
                RfwsSubblockCarrierSettings settings = currentSubblockSettings.First();

                // Since the RFWS file uses a flattened structure, there will be a separate subblock configuraiton object
                // for each component carriers. Since we have already filtered the list to select the currrent subblock,
                // the number of items now represents the number of component carriers within this subblock.
                int numComponentCarriers = currentSubblockSettings.Count();

                Subblock subblock = new Subblock
                {
                    CarrierSubblockOffset     = settings.CarrierSubblockOffset,
                    NumberOfComponentCarriers = numComponentCarriers,
                    ComponentCarriers         = new List <Carrier>(numComponentCarriers)
                };
                for (int j = 0; j < numComponentCarriers; j++)
                {
                    // Load the specific settings for the current component carrier that is being configured
                    RfwsSubblockCarrierSettings currentCcSettings = currentSubblockSettings.Where(s => s.ComponentCarrierIndex == j).First();
                    // The object contains a CarrierDefinitionIndex field that describes which carrier definition it is using.
                    // Since these may be used multiple times and certain properties may be changed depending on the configuration,
                    // we clone the object so that we have a unique instance.
                    Carrier associatedCarrier = carriers[(int)currentCcSettings.CarrierDefinitionIndex].ShallowCopy();

                    associatedCarrier.CarrierFrequencyOffset = currentCcSettings.CarrierFrequencyOffset;
                    subblock.ComponentCarriers.Add(associatedCarrier);
                }
                Subblocks.Add(subblock);
            }
        }