├── LICENSE.md ├── README.md ├── compileSimulatedRadarWG.m ├── docs ├── Matlab_Prerequisites.txt ├── Simulated_Radar_Waveform_Generator_GUI_manual.pdf └── figs │ ├── SimRadarWG_AWGN_GUI.PNG │ └── SimRadarWG_GUI.PNG └── src ├── app └── simulatedRadarWaveformGenerator.mlapp ├── dsp ├── interferenceAdder.m └── radarWaveform.m ├── res ├── CTL_logo.png ├── icon.ico └── splash.png └── util ├── VarNamesDialog.m ├── VarNamesDialogAPP.mlapp ├── folderBrowserGUI.m ├── folderBrowserGUIwithFileCheck.m └── parforuiprogressdlg.m /LICENSE.md: -------------------------------------------------------------------------------- 1 | NIST-developed software is provided by NIST as a public service. 2 | You may use, copy and distribute copies of the software in any medium, 3 | provided that you keep intact this entire notice. You may improve, 4 | modify and create derivative works of the software or any portion of 5 | the software, and you may copy and distribute such modifications or 6 | works. Modified works should carry a notice stating that you changed 7 | the software and should note the date and nature of any such change. 8 | Please explicitly acknowledge the National Institute of Standards and 9 | Technology as the source of the software. 10 | 11 | NIST-developed software is expressly provided "AS IS." NIST MAKES NO 12 | WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT OR ARISING BY 13 | OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY 14 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 15 | AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE 16 | OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR 17 | THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY 18 | REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS 19 | THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, 20 | RELIABILITY, OR USEFULNESS OF THE SOFTWARE. 21 | 22 | You are solely responsible for determining the appropriateness of 23 | using and distributing the software and you assume all risks 24 | associated with its use, including but not limited to the risks and 25 | costs of program errors, compliance with applicable laws, damage to 26 | or loss of data, programs or equipment, and the unavailability or 27 | interruption of operation. This software is not intended to be used in 28 | any situation where a failure could cause risk of injury or damage to 29 | property. The software developed by NIST employees is not subject to 30 | copyright protection within the United States. 31 | 32 | See [NIST Software Disclaimer](https://www.nist.gov/disclaimer) for more details. 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simulated Radar Waveform and RF Dataset Generator for Incumbent Signals in the 3.5 GHz CBRS Band 2 | 3 | 4 | - [1. Legal Disclaimers](#1-legal-disclaimers) 5 | - [1.1. Software Disclaimer](#11-software-disclaimer) 6 | - [1.2. Commercial Disclaimer](#12-commercial-disclaimer) 7 | - [2. Project Summary](#2-project-summary) 8 | - [2.1. Design Methodology](#21-design-methodology) 9 | - [2.1.1. Framework](#211-framework) 10 | - [2.1.2. GUI](#212-gui) 11 | - [3. Development Details](#3-development-details) 12 | - [4. How to run](#4-how-to-run) 13 | - [4.1. Run in MATLAB](#41-run-in-matlab) 14 | - [4.2. Run from Deployed executable](#42-run-from-deployed-executable) 15 | - [4.2.1. Compile from source](#421-compile-from-source) 16 | - [4.2.2. Precompiled Executable](#422-precompiled-executable) 17 | - [5. Prerequisites:](#5-prerequisites) 18 | 19 | 20 | 21 | # 1. Legal Disclaimers 22 | ## 1.1. Software Disclaimer 23 | NIST-developed software is provided by NIST as a public service. 24 | You may use, copy and distribute copies of the software in any medium, 25 | provided that you keep intact this entire notice. You may improve, 26 | modify and create derivative works of the software or any portion of 27 | the software, and you may copy and distribute such modifications or 28 | works. Modified works should carry a notice stating that you changed 29 | the software and should note the date and nature of any such change. 30 | Please explicitly acknowledge the National Institute of Standards and 31 | Technology as the source of the software. 32 | 33 | NIST-developed software is expressly provided "AS IS." NIST MAKES NO 34 | WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT OR ARISING BY 35 | OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY 36 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 37 | AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE 38 | OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR 39 | THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY 40 | REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS 41 | THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, 42 | RELIABILITY, OR USEFULNESS OF THE SOFTWARE. 43 | 44 | You are solely responsible for determining the appropriateness of 45 | using and distributing the software and you assume all risks 46 | associated with its use, including but not limited to the risks and 47 | costs of program errors, compliance with applicable laws, damage to 48 | or loss of data, programs or equipment, and the unavailability or 49 | interruption of operation. This software is not intended to be used in 50 | any situation where a failure could cause risk of injury or damage to 51 | property. The software developed by NIST employees is not subject to 52 | copyright protection within the United States. 53 | 54 | See [NIST Software Disclaimer](https://www.nist.gov/disclaimer) for more details. 55 | 56 | ## 1.2. Commercial Disclaimer 57 | Certain commercial equipment, instruments, or materials are identified in this README to foster understanding. Such identification does not imply recommendation or endorsement by the National Institute of Standards and Technology, nor does it imply that the materials or equipment identified are necessarily the best available for the purpose. 58 | 59 | # 2. Project Summary 60 | 61 | The simulated radar waveform generator is a software tool built with MATLAB to generate radar waveform datasets. The datasets can be used to develop and test detection algorithms for the 3.5 GHz CBRS or similar bands where the primary users of the band are federal incumbent radar systems. The software tool generates radar waveforms and randomizes the radar waveform parameters. The ranges of parameters values are selected based on NTIA testing procedures for ESC certification [1]. The parameters are pulse modulation, pulse duration, pulse repetition rate, chirp width and pulses per burst. In addition, we randomize the following parameters: start time, SNR, and the baseband center frequency of the radar signal. 62 | 63 | ## 2.1. Design Methodology 64 | This software consists of a MATLAB code and a graphical user interface (GUI). The MATLAB code generates simulated radar signals, mixes them with noise and manages the random generation of the parameters. The GUI simplifies the settings of the parameters and controls the dataset generation process. 65 | 66 | 67 | # 3. Development Details 68 | - Current development environment: MATLAB 2019b 69 | - The tool can be compiled and the executable can run without a MATLAB license. See the section [How to run](#4-how-to-run) for more details 70 | 71 | # 4. How to Run 72 | ## 4.1. Run in MATLAB 73 | 74 | * Add the following folders to MATLAB path: 75 | * \src\dsp\ 76 | * \src\util\ 77 | 78 | * At the MATLAB command prompt change the current directory to \src\app\ and run appdesigner('simulatedRadarWaveformGenerator.mlapp') 79 | 80 | * Requires the following toolboxes to run all the functionalities: 81 | * Signal Processing Toolbox 82 | * 'DSP System Toolbox' 83 | * 'Communications System Toolbox' 84 | * 'Parallel Computing Toolbox' 85 | * 'MATLAB Distributed Computing Server' 86 | * 'Phased Array System Toolbox' 87 | 88 | 89 | 90 | ## 4.2. Run from Deployed Executable 91 | It is possible to compile an executable and run it in a machine without MATLAB installation or license. However, the licenses for MATLAB and the toolboxes are required during compilation. 92 | ### 4.2.1. Compile from Source 93 | To generate an executable for the software tool: 94 | * Use either mcc see compileSimulatedRadarWG.m, or use the MATLAB deployment tool "deploytool". 95 | * All necessary toolboxes are required during compilation in addition to the MATLAB Compiler. 96 | 97 | ### 4.2.2. Prerequisites for Deployment: 98 | For running a precompiled executable, MATLAB prerequisites for deployment must be installed. Instructions can be found in [Matlab Prerequisites](docs/Matlab_Prerequisites.txt). 99 | 100 | # 5. Waveform Generation: 101 | The first tab in the application is for generating waveforms. Five modulation bins are available. You can set the number of waveforms and the sampling frequency. The random waveform parameters are selected according to Table 1 in [1]. For P0N#2, the type of phase coding can also be changed. 102 | 103 | ![alt text][GUI] 104 | 105 | [GUI]: docs/figs/SimRadarWG_GUI.PNG "Simulated radar waveform generator GUI" 106 | 107 | After generating and saving a dataset of waveforms, we load the dataset folder in the second tab. We can set different parameters for the dataset as demonstrated in the figure below. 108 | 109 | ![alt text][GUINoiseAdder] 110 | 111 | [GUINoiseAdder]: docs/figs/SimRadarWG_AWGN_GUI.PNG "Simulated radar waveform generator GUI noise addition" 112 | 113 | A reference RF dataset was generated using this software. The RF dataset is published at https://doi.org/10.18434/M32116. 114 | In addition a manual for using the GUI is available at [Simulated Rada Waveform Generator GUI manual](docs/Simulated_Radar_Waveform_Generator_GUI_manual.pdf). The manual contains a glossary of the parameters that are used for generation. In addition, it includes the exact parameters that were used to generate the reference RF dataset. For more information see the additional references below. 115 | 116 | Use the data record at https://data.nist.gov/od/id/mds2-2229 to cite this work. 117 | 118 | # 6. References: 119 | 120 | 1. F. H. Sanders, J. E. Carroll, G. A. Sanders, R. L. Sole, J. S. Devereux, and E. F. Drocella, “Procedures for Laboratory Testing of Environmental Sensing Capability Sensor Devices,” National Telecommunications and Information Administration, Technical Memorandum TM 18-527, Nov. 2017. Available at http://www.its.bldrdoc.gov/publications/3184.aspx. 121 | 2. R. Caromi, M. Souryal, T. Hall “RF Dataset of Incumbent Radar Signals in the 3.5 GHz CBRS Band,” Journal of Research (NIST JRES), Volume 124, Dec. 2019, available at https://www.nist.gov/publications/rf-dataset-incumbent-radar-signals-35-ghz-cbrs-band 122 | 3. T. Hall, R. Caromi, M. Souryal, and A. Wunderlich, "Reference Datasets for Training and Evaluating RF Signal Detection and Classification Models," in *Proc. IEEE GLOBECOM Workshop on Advancements in Spectrum Sharing*, Dec. 2019, available at https://www.nist.gov/publications/reference-data-sets-training-and-evaluating-rf-signal-detection-and-classification 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /compileSimulatedRadarWG.m: -------------------------------------------------------------------------------- 1 | ...%% Legal Disclaimer 2 | ...% NIST-developed software is provided by NIST as a public service. 3 | ...% You may use, copy and distribute copies of the software in any medium, 4 | ...% provided that you keep intact this entire notice. You may improve, 5 | ...% modify and create derivative works of the software or any portion of 6 | ...% the software, and you may copy and distribute such modifications or 7 | ...% works. Modified works should carry a notice stating that you changed 8 | ...% the software and should note the date and nature of any such change. 9 | ...% Please explicitly acknowledge the National Institute of Standards and 10 | ...% Technology as the source of the software. 11 | ...% 12 | ...% NIST-developed software is expressly provided "AS IS." NIST MAKES NO 13 | ...% WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT OR ARISING BY 14 | ...% OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY 15 | ...% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 16 | ...% AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE 17 | ...% OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR 18 | ...% THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY 19 | ...% REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS 20 | ...% THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, 21 | ...% RELIABILITY, OR USEFULNESS OF THE SOFTWARE. 22 | ...% 23 | ...% You are solely responsible for determining the appropriateness of 24 | ...% using and distributing the software and you assume all risks 25 | ...% associated with its use, including but not limited to the risks and 26 | ...% costs of program errors, compliance with applicable laws, damage to 27 | ...% or loss of data, programs or equipment, and the unavailability or 28 | ...% interruption of operation. This software is not intended to be used in 29 | ...% any situation where a failure could cause risk of injury or damage to 30 | ...% property. The software developed by NIST employees is not subject to 31 | ...% copyright protection within the United States. 32 | %% 33 | %Requires Toolboxes: 34 | % 'MATLAB' 35 | % 'Signal Processing Toolbox' 36 | % 'DSP System Toolbox' 37 | % 'Communications Toolbox' 38 | % 'Phased Array System Toolbox' 39 | % 'Parallel Computing Toolbox' 40 | %Additional Toolboxes: 41 | % 'MATLAB Compiler' --> for compiling 42 | % All toolboxes are needed for compilation 43 | 44 | ROOT_DIR=pwd; 45 | SOURCE_DIR='src'; 46 | BUILD_DIR='bin'; 47 | APP_DIR=['bin',filesep,'app']; 48 | IN_APP_DIR='app'; 49 | DSP_DIR='dsp'; 50 | UTIL_DIR='util'; 51 | RES_DIR='res'; 52 | APP_RES_DIR=['bin',filesep,'res']; 53 | 54 | ICON_FILE='icon.ico'; 55 | SPLASH_FILE='splash.png'; 56 | 57 | if exist(BUILD_DIR,'dir')~=7 58 | mkdir(BUILD_DIR) 59 | end 60 | if exist(APP_DIR,'dir')~=7 61 | mkdir(APP_DIR) 62 | end 63 | if exist(APP_RES_DIR,'dir')~=7 64 | mkdir(APP_RES_DIR) 65 | end 66 | 67 | APP_SOURCE_NAME='simulatedRadarWaveformGenerator.mlapp'; 68 | APP_NAME='simulatedRadarWaveformGenerator'; 69 | WinMain='WinMain:simulatedRadarWaveformGenerator'; 70 | APP_SOURCE_PATH=fullfile(ROOT_DIR,SOURCE_DIR,IN_APP_DIR,APP_SOURCE_NAME); 71 | 72 | 73 | OUT_DIR=fullfile(ROOT_DIR,APP_DIR); 74 | ICON_PATH=fullfile(ROOT_DIR,SOURCE_DIR,RES_DIR,ICON_FILE); 75 | SPLASH_FILE=fullfile(ROOT_DIR,SOURCE_DIR,RES_DIR,SPLASH_FILE); 76 | 77 | SEARCH_DIR1=fullfile(SOURCE_DIR,DSP_DIR); 78 | SEARCH_DIR2=fullfile(SOURCE_DIR,UTIL_DIR); 79 | 80 | if ispc 81 | mcc('-o', APP_NAME,'-W',WinMain,'-T', 'link:exe' ,'-d', OUT_DIR,'-v',APP_SOURCE_PATH,'-I',SEARCH_DIR1,'-I',SEARCH_DIR2,'-r',ICON_PATH); 82 | elseif isunix 83 | mcc('-o', APP_NAME, '-e', '-d', OUT_DIR,'-v',APP_SOURCE_PATH,'-I',SEARCH_DIR1,'-I',SEARCH_DIR2); 84 | end 85 | 86 | cd(SOURCE_DIR); 87 | 88 | copyfile(['res',filesep,'CTL_logo.png'], ['..',filesep,'bin',filesep,'res',filesep,'CTL_logo.png']); 89 | copyfile(['..',filesep,'README.md'], ['..',filesep,'bin',filesep,'res',filesep,'README.md']); 90 | copyfile(SPLASH_FILE, ['..',filesep,'bin',filesep,'app',filesep,'splash.png']); 91 | cd('..') 92 | return 93 | %% restart matlab 94 | !matlab & 95 | exit 96 | -------------------------------------------------------------------------------- /docs/Matlab_Prerequisites.txt: -------------------------------------------------------------------------------- 1 | simulatedRadarWaveformGenerator Executable 2 | 3 | 1. Prerequisites for Deployment 4 | 5 | Verify that version 9.7 (R2019b) of the MATLAB Runtime is installed. 6 | If not, you can run the MATLAB Runtime installer. 7 | To find its location, enter 8 | 9 | >>mcrinstaller 10 | 11 | at the MATLAB prompt. 12 | NOTE: You will need administrator rights to run the MATLAB Runtime installer. 13 | 14 | Alternatively, download and install the Windows version of the MATLAB Runtime for R2019b 15 | from the following link on the MathWorks website: 16 | 17 | http://www.mathworks.com/products/compiler/mcr/index.html 18 | 19 | For more information about the MATLAB Runtime and the MATLAB Runtime installer, see 20 | "Distribute Applications" in the MATLAB Compiler documentation 21 | in the MathWorks Documentation Center. 22 | 23 | 2. Files to Deploy and Package 24 | 25 | Files to Package for Standalone 26 | ================================ 27 | -simulatedRadarWaveformGenerator.exe 28 | -MCRInstaller.exe 29 | Note: if end users are unable to download the MATLAB Runtime using the 30 | instructions in the previous section, include it when building your 31 | component by clicking the "Runtime included in package" link in the 32 | Deployment Tool. 33 | -This readme file 34 | 35 | 36 | 37 | 3. Definitions 38 | 39 | For information on deployment terminology, go to 40 | http://www.mathworks.com/help and select MATLAB Compiler > 41 | Getting Started > About Application Deployment > 42 | Deployment Product Terms in the MathWorks Documentation 43 | Center. 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /docs/Simulated_Radar_Waveform_Generator_GUI_manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usnistgov/SimulatedRadarWaveformGenerator/b6cc38babaa43793263153e25a7c8af511b1d3bc/docs/Simulated_Radar_Waveform_Generator_GUI_manual.pdf -------------------------------------------------------------------------------- /docs/figs/SimRadarWG_AWGN_GUI.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usnistgov/SimulatedRadarWaveformGenerator/b6cc38babaa43793263153e25a7c8af511b1d3bc/docs/figs/SimRadarWG_AWGN_GUI.PNG -------------------------------------------------------------------------------- /docs/figs/SimRadarWG_GUI.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usnistgov/SimulatedRadarWaveformGenerator/b6cc38babaa43793263153e25a7c8af511b1d3bc/docs/figs/SimRadarWG_GUI.PNG -------------------------------------------------------------------------------- /src/app/simulatedRadarWaveformGenerator.mlapp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usnistgov/SimulatedRadarWaveformGenerator/b6cc38babaa43793263153e25a7c8af511b1d3bc/src/app/simulatedRadarWaveformGenerator.mlapp -------------------------------------------------------------------------------- /src/dsp/interferenceAdder.m: -------------------------------------------------------------------------------- 1 | ...%% Legal Disclaimer 2 | ...% NIST-developed software is provided by NIST as a public service. 3 | ...% You may use, copy and distribute copies of the software in any medium, 4 | ...% provided that you keep intact this entire notice. You may improve, 5 | ...% modify and create derivative works of the software or any portion of 6 | ...% the software, and you may copy and distribute such modifications or 7 | ...% works. Modified works should carry a notice stating that you changed 8 | ...% the software and should note the date and nature of any such change. 9 | ...% Please explicitly acknowledge the National Institute of Standards and 10 | ...% Technology as the source of the software. 11 | ...% 12 | ...% NIST-developed software is expressly provided "AS IS." NIST MAKES NO 13 | ...% WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT OR ARISING BY 14 | ...% OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY 15 | ...% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 16 | ...% AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE 17 | ...% OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR 18 | ...% THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY 19 | ...% REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS 20 | ...% THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, 21 | ...% RELIABILITY, OR USEFULNESS OF THE SOFTWARE. 22 | ...% 23 | ...% You are solely responsible for determining the appropriateness of 24 | ...% using and distributing the software and you assume all risks 25 | ...% associated with its use, including but not limited to the risks and 26 | ...% costs of program errors, compliance with applicable laws, damage to 27 | ...% or loss of data, programs or equipment, and the unavailability or 28 | ...% interruption of operation. This software is not intended to be used in 29 | ...% any situation where a failure could cause risk of injury or damage to 30 | ...% property. The software developed by NIST employees is not subject to 31 | ...% copyright protection within the United States. 32 | 33 | classdef interferenceAdder 34 | %RADARINTERFERENCE Summary of this class goes here 35 | % Detailed explanation goes here 36 | 37 | properties 38 | inType 39 | % numWaveforms 40 | inParameters 41 | end 42 | 43 | methods 44 | function this = interferenceAdder(inType) 45 | %interferenceAdder Construct an instance of this class 46 | % inType currently supports wgn 47 | this.inType =inType; 48 | %this.numWaveforms=numWaveforms; 49 | end 50 | 51 | function this=setInterferencePar(this,inPar) 52 | 53 | if strcmp(this.inType,'wgn') 54 | %inPar for wgn must be a struct and have these parameters 55 | %powerLevelMode: <,'Power Level Range','SNR Range'> 56 | %rangedBmOrdB: [lower,step,upper] 57 | %radarPeakPowerdBmP1MHzFixed: NaN for SNR mode or value for Power Level mode 58 | %noisePowerdBmP1MHzFixed: value for SNR mode or NaN for Power Level mode 59 | %includeNoiseOnlySet: true false whether to include noise only waveforms 60 | %waveformDurationMode: <'keep' (don't change orignal length), 'fix to max' (fix length to the maximum in the set), 'fix to' (set all to a fixed ms duration> 61 | %fixedWaveformDuration: for 'fix to' mode ms duration 62 | %need to add check for correct pars in the future 63 | this.inParameters.wgn=inPar; 64 | end 65 | 66 | 67 | end 68 | 69 | function [waveformCell,allWaveformTable]=addInterference(this,waveformCell,allWaveformTable) 70 | %addInterference passthrough function 71 | switch this.inType 72 | case 'wgn' 73 | [waveformCell,allWaveformTable]= addWGN(this,waveformCell,allWaveformTable); 74 | otherwise 75 | waveformCell=[]; 76 | allWaveformTable=[]; 77 | end 78 | 79 | end 80 | 81 | function [waveformCell,allWaveformTable]= addWGN(this,waveformCell,allWaveformTable) 82 | %addWGN add wgn to the waveforms 83 | lowerVal=this.inParameters.wgn.rangedBmOrdB(1); 84 | stepVal=this.inParameters.wgn.rangedBmOrdB(2); 85 | upperVal=this.inParameters.wgn.rangedBmOrdB(3); 86 | %sigScale=this.inParameters.wgn.sigScale; 87 | radarSignalStartTime=zeros(length(waveformCell),1); 88 | if strcmp(this.inParameters.wgn.waveformDurationMode,'fix to max')||strcmp(this.inParameters.wgn.waveformDurationMode,'fix to') 89 | waveformLength=cellfun(@length,waveformCell); 90 | if strcmp(this.inParameters.wgn.waveformDurationMode,'fix to max') 91 | newAllLength=repmat(max(waveformLength),length(waveformLength),1); 92 | end 93 | if strcmp(this.inParameters.wgn.waveformDurationMode,'fix to') 94 | newAllLength=round((this.inParameters.wgn.fixedWaveformDuration*1e-3)*allWaveformTable.SamplingFrequency); 95 | end 96 | diffInLength=newAllLength-waveformLength; 97 | diffInLength(diffInLength<=0)=1; 98 | waveformStartFrom=arrayfun(@(x) randi([1,x],1,1), diffInLength); 99 | waveformEndsAt=waveformStartFrom+waveformLength-1; 100 | waveformEndsAt(waveformEndsAt>newAllLength)=newAllLength(waveformEndsAt>newAllLength); 101 | waveformOriginalLengthTrim=newAllLength; 102 | waveformOriginalLengthTrim(waveformLength> sigPow_dB=SNR+noisePow_dB 182 | adjustPeaksBy=sqrt(db2pow(desiredPeakPowerdBwPerMHz))./peakPer1MHz; % desiredPeakPow=scale*currentPeakPow 183 | %rangedBm=(pow2db(sigScale^2)+30-lowerVal):stepVal:(pow2db(sigScale^2)+30-upperVal); 184 | %wPowdBmMat=repmat(rangedBm,[length(app.allSigs),1]); 185 | allWaveformTable=addvars(allWaveformTable,randomNoisePowdBmOrSNRdB,repmat(this.inParameters.wgn.noisePowerdBmP1MHzFixed,[length(waveformCell),1]),'NewVariableNames',{'SNR','NoisePowerdBmPerMHz'}); 186 | end 187 | 188 | % for I=1:length(waveformCell) 189 | % wpow{I,1}=rangedBm(randi([1,length(rangedBm)]))+pow2db((allWaveformTable.SamplingFrequency(I)/1e6));%+db2pow(3);%%%check check 190 | % end 191 | if this.inParameters.wgn.useParallel 192 | parfor I=1:length(waveformCell) 193 | %peakPer1MHz=measurePeakIn1MHz(this,waveformCell{I},allWaveformTable.SamplingFrequency(I)); 194 | waveformCell{I}=adjustPeaksBy(I)*waveformCell{I}+wgn(length(waveformCell{I}),1,noisePowerTotaldBw(I),'dBW','complex'); 195 | end 196 | else 197 | for I=1:length(waveformCell) 198 | %peakPer1MHz=measurePeakIn1MHz(this,waveformCell{I},allWaveformTable.SamplingFrequency(I)); 199 | waveformCell{I}=adjustPeaksBy(I)*waveformCell{I}+wgn(length(waveformCell{I}),1,noisePowerTotaldBw(I),'dBW','complex'); 200 | end 201 | end 202 | 203 | if this.inParameters.wgn.includeNoiseOnlySet 204 | if this.inParameters.wgn.useParallel 205 | parfor I=1:length(waveformCell) 206 | noiseWaveformCell{I,1}=wgn(length(waveformCell{I}),1,noisePowerTotaldBw(I),'dBW','complex'); 207 | end 208 | else 209 | for I=1:length(waveformCell) 210 | noiseWaveformCell{I,1}=wgn(length(waveformCell{I}),1,noisePowerTotaldBw(I),'dBW','complex'); 211 | end 212 | end 213 | 214 | 215 | waveformCell=[waveformCell;noiseWaveformCell]; 216 | 217 | numericOrLogicalVars = varfun(@(x) isnumeric(x)|islogical(x),allWaveformTable,'output','uniform'); 218 | newCellforWGN=cell(height(allWaveformTable),width(allWaveformTable)); 219 | newCellforWGN(repmat(~numericOrLogicalVars,[height(allWaveformTable),1]))={'NaN'}; 220 | varsToChange={'SamplingFrequency','radarStatus','NoisePowerdBmPerMHz'}; 221 | varsToChangeLogical=and(numericOrLogicalVars,ismember(allWaveformTable.Properties.VariableNames,varsToChange)); 222 | newCellforWGN(repmat(~varsToChangeLogical&numericOrLogicalVars,[height(allWaveformTable),1]))={NaN}; 223 | newCellforWGN(repmat(ismember(allWaveformTable.Properties.VariableNames,varsToChange{1}),[height(allWaveformTable),1]))=... 224 | mat2cell(allWaveformTable.SamplingFrequency,ones(height(allWaveformTable),1)); 225 | newCellforWGN(repmat(ismember(allWaveformTable.Properties.VariableNames,varsToChange{2}),[height(allWaveformTable),1]))={false}; 226 | newCellforWGN(repmat(ismember(allWaveformTable.Properties.VariableNames,varsToChange{3}),[height(allWaveformTable),1]))=... 227 | mat2cell(noisePowerTotaldBw+30-pow2db(allWaveformTable.SamplingFrequency./1e6),ones(height(allWaveformTable),1)); 228 | allWaveformTable=[allWaveformTable;cell2table(newCellforWGN,'VariableNames',allWaveformTable.Properties.VariableNames)]; 229 | 230 | end 231 | 232 | duration=cellfun(@length,waveformCell)./allWaveformTable.SamplingFrequency; 233 | allWaveformTable=addvars(allWaveformTable,duration); 234 | % randomize twice 235 | newIndex=randperm(length(waveformCell)).'; 236 | waveformCell=waveformCell(newIndex,:); 237 | allWaveformTable=allWaveformTable(newIndex,:); 238 | 239 | newIndex=randperm(length(waveformCell)).'; 240 | waveformCell=waveformCell(newIndex,:); 241 | allWaveformTable=allWaveformTable(newIndex,:); 242 | end 243 | 244 | function peakInMHz=measurePeakIn1MHz(this,sig,Fs) 245 | %1. design MeasFilt 246 | FsMHz=Fs/1e6; 247 | Hd=design1MFilter(this,FsMHz); 248 | t=(0:length(Hd.Numerator)-1)/Fs; 249 | %Calculate max location in freq domain 250 | % a faster approach 251 | % NFFT=length(sig); 252 | % moveAveResN=64; 253 | % moveAveResF=Fs/moveAveResN; 254 | % numPointsToAvoidFromSides=ceil(NFFT/(Fs/0.5e6));% avoid 0.5 MHz from the sides 255 | % f=(-NFFT/2:NFFT/2-1)*Fs/NFFT; 256 | % sigMoveAve = movmean(abs(fftshift(fft(sig,NFFT))),moveAveResN); 257 | % sigMoveAve(1:numPointsToAvoidFromSides)=0;sigMoveAve(end-numPointsToAvoidFromSides:end)=0; 258 | % [~,mIndx]=max(sigMoveAve); 259 | % 260 | NFFT=2048; 261 | win = hanning(NFFT,'periodic'); 262 | [sigSF,f,ts] =stft(sig,Fs,'Window',win,'OverlapLength',256,'FFTLength',NFFT); 263 | sigSFSum=sum(abs(sigSF),2); 264 | numPointsToAvoidFromSides=ceil(NFFT/(Fs/0.5e6)); 265 | sigSFSum(1:numPointsToAvoidFromSides)=0;sigSFSum(end-numPointsToAvoidFromSides:end)=0; 266 | [~,mIndx]=max(sigSFSum); 267 | 268 | Hd.Numerator=Hd.Numerator.*exp(2i*pi*f(mIndx)*t); 269 | peakInMHz=max(abs(Hd(sig))); 270 | 271 | end 272 | 273 | function Hd=design1MFilter(this,FsMHz) 274 | %FIRKAISERFLIT1MPER10M Returns a discrete-time filter object. 275 | % MATLAB Code 276 | % Generated by MATLAB(R) 9.5 and DSP System Toolbox 9.7. 277 | % Generated on: 25-Feb-2019 13:29:33 278 | % FIR Window Lowpass filter designed using the FIR1 function. 279 | % All frequency values are in MHz. 280 | %FsMHz = 10; % Sampling Frequency 281 | Fpass = 0.48; % Passband Frequency 282 | Fstop = 0.56; % Stopband Frequency 283 | Dpass = 0.057501127785; % Passband Ripple 284 | Dstop = 0.0031622776602; % Stopband Attenuation 285 | flag = 'scale'; % Sampling Flag 286 | % Calculate the order from the parameters using KAISERORD. 287 | [N,Wn,BETA,TYPE] = kaiserord([Fpass Fstop]/(FsMHz/2), [1 0], [Dstop Dpass]); 288 | % Calculate the coefficients using the FIR1 function. 289 | b = fir1(N, Wn, TYPE, kaiser(N+1, BETA), flag); 290 | %Hd = dfilt.dffir(b); 291 | Hd = dsp.FIRFilter('Numerator',b); 292 | end 293 | 294 | end 295 | end 296 | 297 | -------------------------------------------------------------------------------- /src/dsp/radarWaveform.m: -------------------------------------------------------------------------------- 1 | ...%% Legal Disclaimer 2 | ...% NIST-developed software is provided by NIST as a public service. 3 | ...% You may use, copy and distribute copies of the software in any medium, 4 | ...% provided that you keep intact this entire notice. You may improve, 5 | ...% modify and create derivative works of the software or any portion of 6 | ...% the software, and you may copy and distribute such modifications or 7 | ...% works. Modified works should carry a notice stating that you changed 8 | ...% the software and should note the date and nature of any such change. 9 | ...% Please explicitly acknowledge the National Institute of Standards and 10 | ...% Technology as the source of the software. 11 | ...% 12 | ...% NIST-developed software is expressly provided "AS IS." NIST MAKES NO 13 | ...% WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT OR ARISING BY 14 | ...% OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY 15 | ...% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 16 | ...% AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE 17 | ...% OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR 18 | ...% THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY 19 | ...% REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS 20 | ...% THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, 21 | ...% RELIABILITY, OR USEFULNESS OF THE SOFTWARE. 22 | ...% 23 | ...% You are solely responsible for determining the appropriateness of 24 | ...% using and distributing the software and you assume all risks 25 | ...% associated with its use, including but not limited to the risks and 26 | ...% costs of program errors, compliance with applicable laws, damage to 27 | ...% or loss of data, programs or equipment, and the unavailability or 28 | ...% interruption of operation. This software is not intended to be used in 29 | ...% any situation where a failure could cause risk of injury or damage to 30 | ...% property. The software developed by NIST employees is not subject to 31 | ...% copyright protection within the United States. 32 | 33 | classdef radarWaveform 34 | %ESC synthetic radar waveform generator 35 | %Waveform types and parameters based on NTIA Technical Memorandum 18-527 36 | %"Procedures for Laboratory Testing of Environmental Sensing Capability Sensor Devices" 37 | %Waveforms generated with Matlab phased array toolbox 38 | %For 'P0N#2' number of chips is fixed to 4 (pulse_width=number_of_chips*chip_width) this enables the use of all possible phase-coding without 39 | %changing number of chips 40 | %Phased array toolbox requires integer value for the ratio sampling_frequency/pulse_repetition_rate, therefor sampling rate is set differently 41 | %than the required sampling rate then the waveform is resampled to the desired sampling rate 42 | %Additional Requirement for phased.PhaseCodedWaveform, (i.e., 'P0N#2') is that (SampleRate*ChipWidth) must be an integer value, 43 | %therefore the pulse_width will end-up slightly different than the desired pulse_width 44 | 45 | properties 46 | sampleRate 47 | pulseModulation % {'P0N#1','P0N#2','Q3N#1','Q3N#2','Q3N#3'} 48 | pulseWidth % 49 | modifiedPulseWidth 50 | chirpWidth % 51 | chirpDir % ch{'Up','Down'} 52 | PRR % PRR (pulses per second) 53 | PPB %Pulses per Burst 54 | numWaves % number of waveforms 55 | waveforms 56 | PCType='Barker' 57 | useParallel=false 58 | % progBar 59 | %wgnState logical 60 | ERROR 61 | end 62 | 63 | properties (Constant, Access=private) 64 | pulseModulationTypes ={'P0N#1','P0N#2','Q3N#1','Q3N#2','Q3N#3'}; 65 | pulseWidthRanges=[0.5,2.5;13,52;3,5;10,30;50,100].'; 66 | pulseWidthDelta=[0.1 ,13,1,1,5]; 67 | chirpWidthRanges=[nan,nan;nan,nan;50,100;1,10;50,100].'; 68 | chirpWidthDelta=[nan ,nan,10,1,10]; 69 | PRRRanges=[900,1100;300,3000;300,3000;300,3000;300,3000].'; 70 | PPRDelta=[10,10,30,50,100]; 71 | PPBRanges=[15,40;5,20;8,24;2,8;8,24].'; 72 | PPBDelta=[5,5,2,2,2]; 73 | possChirpDir={'Up','Down'}; 74 | PCTypes={'Barker','Frank', 'P1', 'P2', 'P3', 'P4', 'Px', 'Zadoff-Chu'}; 75 | end 76 | 77 | methods 78 | function this = radarWaveform(sampleRate,pulseModulation,numWaves) 79 | %Construct an instance of this class 80 | if nargin>1 81 | % if ismember(pulseModulation,this.pulseModulationTypes) 82 | this.sampleRate = sampleRate; 83 | this.pulseModulation=pulseModulation; 84 | this.numWaves=numWaves; 85 | end 86 | end 87 | 88 | function this=set.sampleRate(this,sampleRate) 89 | this.sampleRate = sampleRate; 90 | end 91 | 92 | function this=set.pulseModulation(this,pulseModulation) 93 | if ismember(pulseModulation,this.pulseModulationTypes) 94 | this.pulseModulation = pulseModulation; 95 | else 96 | msgID = 'radarWaveform:initialization'; 97 | msgtext =['pulse modulation type must be one of the following: ',strjoin(this.pulseModulationTypes)]; 98 | this.ERROR=MException(msgID,msgtext); 99 | throw(this.ERROR); 100 | end 101 | end 102 | 103 | function this=set.numWaves(this,numWaves) 104 | this.numWaves=numWaves; 105 | end 106 | 107 | function this=set.useParallel(this,useParallel) 108 | if islogical(useParallel) 109 | this.useParallel=useParallel; 110 | else 111 | msgID = 'radarWaveform:initialization'; 112 | msgtext ='useParallel must be logical'; 113 | this.ERROR=MException(msgID,msgtext); 114 | throw(this.ERROR); 115 | end 116 | end 117 | 118 | function this=set.PCType(this,PCType) 119 | if ismember(PCType,this.PCTypes) 120 | this.PCType = PCType; 121 | else 122 | msgID = 'radarWaveform:initialization'; 123 | msgtext =['phase coding type must be one of the following: ',strjoin(this.PCTypes)]; 124 | this.ERROR=MException(msgID,msgtext); 125 | throw(this.ERROR); 126 | end 127 | end 128 | 129 | function b=designFilt(filtFs) 130 | %Fs = 2000790; % Sampling Frequency 131 | 132 | Fpass = 975000; % Passband Frequency 133 | Fstop = 1000000; % Stopband Frequency 134 | Dpass = 0.057501127785; % Passband Ripple 135 | Dstop = 0.0001; % Stopband Attenuation 136 | flag = 'scale'; % Sampling Flag 137 | 138 | % Calculate the order from the parameters using KAISERORD. 139 | [N,Wn,BETA,TYPE] = kaiserord([Fpass Fstop]/(filtFs/2), [1 0], [Dstop Dpass]); 140 | 141 | % Calculate the coefficients using the FIR1 function. 142 | b = fir1(N, Wn, TYPE, kaiser(N+1, BETA), flag); 143 | end 144 | 145 | function this = generateRandomPars(this) 146 | waveIndex=find(ismember(this.pulseModulationTypes,this.pulseModulation)); 147 | this.pulseWidth =1e-6*((this.pulseWidthDelta(waveIndex)*randi([0, (this.pulseWidthRanges(2,waveIndex)- this.pulseWidthRanges(1,waveIndex))... 148 | /this.pulseWidthDelta(waveIndex)],1,this.numWaves)) +this.pulseWidthRanges(1,waveIndex)).';%(5*randi([0, 50/5],1,this.numWaves)) + 50; % 50 - 100 Step=5 149 | this.PRR = ((this.PPRDelta(waveIndex)*randi([0, (this.PRRRanges(2,waveIndex)- this.PRRRanges(1,waveIndex))... 150 | /this.PPRDelta(waveIndex)],1,this.numWaves)) +this.PRRRanges(1,waveIndex)).';%(100*randi([0, 3000/100],1,this.numWaves))+ 300; % 300 - 3000 Step=100 us 151 | this.PPB = ((this.PPBDelta(waveIndex)*randi([0, (this.PPBRanges(2,waveIndex)- this.PPBRanges(1,waveIndex))... 152 | /this.PPBDelta(waveIndex)],1,this.numWaves)) +this.PPBRanges(1,waveIndex)).';%(2*randi([0, 16/2],1,this.numWaves))+ 8; % 8 - 24 Step=2 153 | if ~isnan(this.chirpWidthDelta(waveIndex)) 154 | this.chirpWidth = 1e6*((this.chirpWidthDelta(waveIndex)*randi([0, (this.chirpWidthRanges(2,waveIndex)- this.chirpWidthRanges(1,waveIndex))... 155 | /this.chirpWidthDelta(waveIndex)],1,this.numWaves)) +this.chirpWidthRanges(1,waveIndex)).'; %(10*randi([0, 50/10],1,this.numWaves))+ 50; % 50 - 100 Step=10 MHz 156 | this.chirpDir = this.possChirpDir(randi([1, 2],1,this.numWaves).').'; 157 | else 158 | this.chirpWidth =nan(this.numWaves,1); 159 | temp=cell(this.numWaves,1); 160 | temp(:)={'NaN'}; 161 | this.chirpDir=temp; 162 | end 163 | end 164 | 165 | function this=initWave(this) 166 | modifySamplingRate=10*ceil(this.sampleRate./this.PRR).*this.PRR; 167 | %modifySamplingRate=ceil(this.sampleRate./this.PRR).*this.PRR; 168 | 169 | switch this.pulseModulation 170 | case this.pulseModulationTypes{1} 171 | for I=1:this.numWaves 172 | 173 | this.waveforms{I,1}=phased.RectangularWaveform; 174 | this.waveforms{I,1}.SampleRate = modifySamplingRate(I); 175 | this.waveforms{I,1}.NumPulses=this.PPB(I); 176 | this.waveforms{I,1}.PRF=this.PRR(I); 177 | this.waveforms{I,1}.PulseWidth=this.pulseWidth(I); 178 | end 179 | case this.pulseModulationTypes{2} 180 | NumChips=4; 181 | chipWidth=this.pulseWidth/NumChips; 182 | modifyChipWidth=ceil(chipWidth.*modifySamplingRate)./modifySamplingRate; 183 | this.modifiedPulseWidth=modifyChipWidth*NumChips; 184 | for I=1:this.numWaves 185 | this.waveforms{I,1}=phased.PhaseCodedWaveform; 186 | this.waveforms{I,1}.SampleRate = modifySamplingRate(I); 187 | this.waveforms{I,1}.NumPulses=this.PPB(I); 188 | this.waveforms{I,1}.PRF=this.PRR(I); 189 | %this.waveforms{I,1}.PulseWidth=this.pulseWidth(I); 190 | this.waveforms{I,1}.Code = this.PCType; 191 | % 'Frank', 'P1', or 'Px' A perfect square 'Frank', 'P1', or 'Px' 192 | % 'P2' An even number that is a perfect square 193 | % 'Barker' 2, 3, 4, 5, 7, 11, or 13 194 | this.waveforms{I,1}.NumChips = NumChips; 195 | this.waveforms{I,1}.ChipWidth=(modifyChipWidth(I)); 196 | end 197 | case this.pulseModulationTypes(3:end) 198 | for I=1:this.numWaves 199 | this.waveforms{I,1}=phased.LinearFMWaveform; 200 | this.waveforms{I,1}.SampleRate = modifySamplingRate(I); 201 | this.waveforms{I,1}.SweepInterval='Symmetric'; 202 | this.waveforms{I,1}.NumPulses=this.PPB(I); 203 | this.waveforms{I,1}.PRF=this.PRR(I); 204 | this.waveforms{I,1}.PulseWidth=this.pulseWidth(I); 205 | this.waveforms{I,1}.SweepBandwidth=this.chirpWidth(I); 206 | this.waveforms{I,1}.SweepDirection=this.chirpDir{I}; 207 | end 208 | end 209 | end 210 | 211 | function waveOut=generateWave(this,uiFig) 212 | progBarFalg=false; 213 | if nargin>1 214 | progBarFalg=true; 215 | end 216 | if this.useParallel 217 | if progBarFalg 218 | progBar =parforuiprogressdlg(uiFig, 'Generating waveforms',this.numWaves,'Working on wavefom number: '); 219 | end 220 | parfor I=1:this.numWaves 221 | if progBarFalg 222 | progBar.iterate(1); 223 | end 224 | sigOut{I,:}=this.waveforms{I}(); 225 | [p,q] = rat(this.sampleRate/this.waveforms{I}.SampleRate,1e-4); 226 | waveOut{I,:}=resample(sigOut{I,:},p,q,0,10);% If n = 0, resample performs nearest-neighbor interpolation 227 | % resample(sig,p,q,n,Beta) Beta: Shape parameter of Kaiser window, specified as a positive real scalar. Increasing beta widens the mainlobe of the window 228 | % used to design the antialiasing filter and decreases the amplitude of the window’s sidelobes. 229 | end 230 | close(progBar); 231 | 232 | else 233 | 234 | if progBarFalg 235 | progBar=constructProgBar(this,uiFig); 236 | end 237 | for I=1:this.numWaves 238 | 239 | if progBarFalg 240 | incPrgBar(this,progBar,I,this.numWaves); 241 | if progBar.CancelRequested 242 | break 243 | end 244 | end 245 | 246 | sigOut{I,:}=this.waveforms{I}(); 247 | [p,q] = rat(this.sampleRate/this.waveforms{I}.SampleRate,1e-4); 248 | waveOut{I,:}=resample(sigOut{I,:},p,q,0,10);% If n = 0, resample performs nearest-neighbor interpolation 249 | end 250 | 251 | end 252 | 253 | end 254 | 255 | function progBar=constructProgBar(this,uiFig) 256 | progBar = uiprogressdlg(uiFig,'Title','Generating waveforms',... 257 | 'Message','1','Cancelable','on'); 258 | end 259 | 260 | function incPrgBar(this,progBar,val,num) 261 | progBar.Value = val/num; 262 | progBar.Message = sprintf('Working on wavefom number: %d out of %d',val,num); 263 | end 264 | 265 | function outTable=getParsTable(this) 266 | VariableNames={'PulseWidth', 'PulsesPerSecond', 'PulsesPerBurst', 'ChirpWidth','ChirpDirection','SamplingFrequency','ActualPulseWidth','PhaseCodingType'}; 267 | if strcmp(this.pulseModulation,'P0N#2') 268 | % VariableNames={'PulseWidth', 'PulsesPerSecond', 'PulsesPerBurst', 'ChirpWidth','ChirpDirection','SamplingFrequency','ActualPulseWidth','PhaseCodingType'}; 269 | temp=cell(this.numWaves,1); 270 | temp(:)={this.PCType}; 271 | outTable=table(this.pulseWidth, this.PRR, this.PPB, this.chirpWidth, this.chirpDir,this.sampleRate*ones(this.numWaves,1),this.modifiedPulseWidth,temp,'VariableNames',VariableNames); 272 | else 273 | % VariableNames={'PulseWidth', 'PulsesPerSecond', 'PulsesPerBurst', 'ChirpWidth','ChirpDirection','SamplingFrequency'}; 274 | temp= cell(this.numWaves, 1); 275 | temp(:) = {'NaN'}; 276 | outTable=table(this.pulseWidth, this.PRR, this.PPB, this.chirpWidth, this.chirpDir,this.sampleRate*ones(this.numWaves,1),this.pulseWidth,temp,'VariableNames',VariableNames); 277 | end 278 | end 279 | 280 | function outConst=getConstants(this) 281 | outConst.pulseModulationTypes=this.pulseModulationTypes; 282 | outConst.pulseWidthRanges=this.pulseWidthRanges; 283 | outConst.pulseWidthDelta=this.pulseWidthDelta; 284 | outConst.chirpWidthRanges=this.chirpWidthRanges; 285 | outConst.chirpWidthDelta=this.chirpWidthDelta; 286 | outConst.PRRRanges=this.PRRRanges; 287 | outConst.PPRDelta=this.PPRDelta; 288 | outConst.PPBRanges=this.PPBRanges; 289 | outConst.PPBDelta=this.PPBDelta; 290 | outConst.possChirpDir=this.possChirpDir; 291 | outConst.PCTypes=this.PCTypes; 292 | end 293 | 294 | end 295 | end 296 | 297 | -------------------------------------------------------------------------------- /src/res/CTL_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usnistgov/SimulatedRadarWaveformGenerator/b6cc38babaa43793263153e25a7c8af511b1d3bc/src/res/CTL_logo.png -------------------------------------------------------------------------------- /src/res/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usnistgov/SimulatedRadarWaveformGenerator/b6cc38babaa43793263153e25a7c8af511b1d3bc/src/res/icon.ico -------------------------------------------------------------------------------- /src/res/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usnistgov/SimulatedRadarWaveformGenerator/b6cc38babaa43793263153e25a7c8af511b1d3bc/src/res/splash.png -------------------------------------------------------------------------------- /src/util/VarNamesDialog.m: -------------------------------------------------------------------------------- 1 | ...%% Legal Disclaimer 2 | ...% NIST-developed software is provided by NIST as a public service. 3 | ...% You may use, copy and distribute copies of the software in any medium, 4 | ...% provided that you keep intact this entire notice. You may improve, 5 | ...% modify and create derivative works of the software or any portion of 6 | ...% the software, and you may copy and distribute such modifications or 7 | ...% works. Modified works should carry a notice stating that you changed 8 | ...% the software and should note the date and nature of any such change. 9 | ...% Please explicitly acknowledge the National Institute of Standards and 10 | ...% Technology as the source of the software. 11 | ...% 12 | ...% NIST-developed software is expressly provided "AS IS." NIST MAKES NO 13 | ...% WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT OR ARISING BY 14 | ...% OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY 15 | ...% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 16 | ...% AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE 17 | ...% OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR 18 | ...% THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY 19 | ...% REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS 20 | ...% THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, 21 | ...% RELIABILITY, OR USEFULNESS OF THE SOFTWARE. 22 | ...% 23 | ...% You are solely responsible for determining the appropriateness of 24 | ...% using and distributing the software and you assume all risks 25 | ...% associated with its use, including but not limited to the risks and 26 | ...% costs of program errors, compliance with applicable laws, damage to 27 | ...% or loss of data, programs or equipment, and the unavailability or 28 | ...% interruption of operation. This software is not intended to be used in 29 | ...% any situation where a failure could cause risk of injury or damage to 30 | ...% property. The software developed by NIST employees is not subject to 31 | ...% copyright protection within the United States. 32 | 33 | classdef VarNamesDialog < matlab.apps.AppBase 34 | 35 | % Properties that correspond to app components 36 | properties (Access = public) 37 | VariableNames matlab.ui.Figure 38 | WaveformdatavariableprefixLabel matlab.ui.control.Label 39 | WaveformDataVariable matlab.ui.control.EditField 40 | SignalstatusvariablePrefixLabel matlab.ui.control.Label 41 | SignalStatusVariable matlab.ui.control.EditField 42 | WaveformtablevariableLabel matlab.ui.control.Label 43 | WaveformTableVariable matlab.ui.control.EditField 44 | OK matlab.ui.control.Button 45 | DatasetreleasenoLabel matlab.ui.control.Label 46 | DataSetRelease matlab.ui.control.EditField 47 | end 48 | 49 | 50 | properties (Access = private) 51 | CallingApp 52 | end 53 | 54 | 55 | % Callbacks that handle component events 56 | methods (Access = private) 57 | 58 | % Code that executes after component creation 59 | function startupFcn(app, mainapp, WaveformDataVariable, SignalStatusVariable, WaveformTableVariable, DataSetRelease) 60 | % adjust dailog box relative position [left bottom width height] 61 | dialogPos=app.VariableNames.Position; 62 | % mainPos=mainapp.MultiRadarWaveformGenerator.Position; % note: this class does not exist when code is executed on Linux and halted the code 63 | mainPos=mainapp.UIAxes.Position; 64 | dialogPos(1)=mainPos(1)+round(mainPos(3)/2)-round(dialogPos(3)/2); 65 | dialogPos(2)=mainPos(2)+round(mainPos(4))-round(dialogPos(4)/2); 66 | app.VariableNames.Position=dialogPos; 67 | % app.VariableNames.Position(1:2)= mainapp.MultiRadarWaveformGenerator.Position(1:2)... 68 | % +round(mainapp.MultiRadarWaveformGenerator.Position(3:4)/2)- round(app.VariableNames.Position(3:4)/2); 69 | app.CallingApp = mainapp; 70 | app.WaveformDataVariable.Value=WaveformDataVariable; 71 | app.SignalStatusVariable.Value=SignalStatusVariable; 72 | app.WaveformTableVariable.Value=WaveformTableVariable; 73 | app.DataSetRelease.Value=DataSetRelease; 74 | end 75 | 76 | % Button pushed function: OK 77 | function OKButtonPushed(app, event) 78 | setPrefixVars(app.CallingApp, app.WaveformDataVariable.Value, app.SignalStatusVariable.Value,... 79 | app.WaveformTableVariable.Value,app.DataSetRelease.Value); 80 | 81 | % Delete the dialog box 82 | delete(app) 83 | end 84 | 85 | % Close request function: VariableNames 86 | function VariableNamesCloseRequest(app, event) 87 | delete(app) 88 | 89 | end 90 | end 91 | 92 | % Component initialization 93 | methods (Access = private) 94 | 95 | % Create UIFigure and components 96 | function createComponents(app) 97 | 98 | % Create VariableNames and hide until all components are created 99 | app.VariableNames = uifigure('Visible', 'off'); 100 | app.VariableNames.Position = [100 100 346 205]; 101 | app.VariableNames.Name = 'Variable Names'; 102 | app.VariableNames.Resize = 'off'; 103 | app.VariableNames.CloseRequestFcn = createCallbackFcn(app, @VariableNamesCloseRequest, true); 104 | app.VariableNames.Interruptible = 'off'; 105 | 106 | % Create WaveformdatavariableprefixLabel 107 | app.WaveformdatavariableprefixLabel = uilabel(app.VariableNames); 108 | app.WaveformdatavariableprefixLabel.HorizontalAlignment = 'right'; 109 | app.WaveformdatavariableprefixLabel.Position = [15 167 168 22]; 110 | app.WaveformdatavariableprefixLabel.Text = 'Waveform data variable prefix:'; 111 | 112 | % Create WaveformDataVariable 113 | app.WaveformDataVariable = uieditfield(app.VariableNames, 'text'); 114 | app.WaveformDataVariable.Position = [188 167 143 22]; 115 | 116 | % Create SignalstatusvariablePrefixLabel 117 | app.SignalstatusvariablePrefixLabel = uilabel(app.VariableNames); 118 | app.SignalstatusvariablePrefixLabel.HorizontalAlignment = 'right'; 119 | app.SignalstatusvariablePrefixLabel.Position = [16 126 157 22]; 120 | app.SignalstatusvariablePrefixLabel.Text = 'Signal status variable Prefix:'; 121 | 122 | % Create SignalStatusVariable 123 | app.SignalStatusVariable = uieditfield(app.VariableNames, 'text'); 124 | app.SignalStatusVariable.Position = [188 126 143 22]; 125 | 126 | % Create WaveformtablevariableLabel 127 | app.WaveformtablevariableLabel = uilabel(app.VariableNames); 128 | app.WaveformtablevariableLabel.HorizontalAlignment = 'right'; 129 | app.WaveformtablevariableLabel.Position = [16 84 134 22]; 130 | app.WaveformtablevariableLabel.Text = 'Waveform table variable'; 131 | 132 | % Create WaveformTableVariable 133 | app.WaveformTableVariable = uieditfield(app.VariableNames, 'text'); 134 | app.WaveformTableVariable.Position = [188 84 143 22]; 135 | 136 | % Create OK 137 | app.OK = uibutton(app.VariableNames, 'push'); 138 | app.OK.ButtonPushedFcn = createCallbackFcn(app, @OKButtonPushed, true); 139 | app.OK.Position = [115 16 100 22]; 140 | app.OK.Text = 'OK'; 141 | 142 | % Create DatasetreleasenoLabel 143 | app.DatasetreleasenoLabel = uilabel(app.VariableNames); 144 | app.DatasetreleasenoLabel.HorizontalAlignment = 'right'; 145 | app.DatasetreleasenoLabel.Position = [20 47 105 22]; 146 | app.DatasetreleasenoLabel.Text = 'Dataset release no.'; 147 | 148 | % Create DataSetRelease 149 | app.DataSetRelease = uieditfield(app.VariableNames, 'text'); 150 | app.DataSetRelease.Position = [187 47 143 22]; 151 | 152 | % Show the figure after all components are created 153 | app.VariableNames.Visible = 'on'; 154 | end 155 | end 156 | 157 | % App creation and deletion 158 | methods (Access = public) 159 | 160 | % Construct app 161 | function app = VarNamesDialog(varargin) 162 | 163 | % Create UIFigure and components 164 | createComponents(app) 165 | 166 | % Register the app with App Designer 167 | registerApp(app, app.VariableNames) 168 | 169 | % Execute the startup function 170 | runStartupFcn(app, @(app)startupFcn(app, varargin{:})) 171 | 172 | if nargout == 0 173 | clear app 174 | end 175 | end 176 | 177 | % Code that executes before app deletion 178 | function delete(app) 179 | 180 | % Delete UIFigure when app is deleted 181 | delete(app.VariableNames) 182 | end 183 | end 184 | end -------------------------------------------------------------------------------- /src/util/VarNamesDialogAPP.mlapp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usnistgov/SimulatedRadarWaveformGenerator/b6cc38babaa43793263153e25a7c8af511b1d3bc/src/util/VarNamesDialogAPP.mlapp -------------------------------------------------------------------------------- /src/util/folderBrowserGUI.m: -------------------------------------------------------------------------------- 1 | ...%% Legal Disclaimer 2 | ...% NIST-developed software is provided by NIST as a public service. 3 | ...% You may use, copy and distribute copies of the software in any medium, 4 | ...% provided that you keep intact this entire notice. You may improve, 5 | ...% modify and create derivative works of the software or any portion of 6 | ...% the software, and you may copy and distribute such modifications or 7 | ...% works. Modified works should carry a notice stating that you changed 8 | ...% the software and should note the date and nature of any such change. 9 | ...% Please explicitly acknowledge the National Institute of Standards and 10 | ...% Technology as the source of the software. 11 | ...% 12 | ...% NIST-developed software is expressly provided "AS IS." NIST MAKES NO 13 | ...% WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT OR ARISING BY 14 | ...% OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY 15 | ...% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 16 | ...% AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE 17 | ...% OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR 18 | ...% THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY 19 | ...% REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS 20 | ...% THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, 21 | ...% RELIABILITY, OR USEFULNESS OF THE SOFTWARE. 22 | ...% 23 | ...% You are solely responsible for determining the appropriateness of 24 | ...% using and distributing the software and you assume all risks 25 | ...% associated with its use, including but not limited to the risks and 26 | ...% costs of program errors, compliance with applicable laws, damage to 27 | ...% or loss of data, programs or equipment, and the unavailability or 28 | ...% interruption of operation. This software is not intended to be used in 29 | ...% any situation where a failure could cause risk of injury or damage to 30 | ...% property. The software developed by NIST employees is not subject to 31 | ...% copyright protection within the United States. 32 | 33 | classdef folderBrowserGUI < matlab.apps.AppBase 34 | %Folder browser GUI with sort numbered files 35 | % Example usage: 36 | % dialogText='Select waveforms folder'; 37 | % defaultExt='dat'; 38 | % defaultDir='C:\' 39 | % folderBrowser=folderBrowserGUI(defaultDir,dialogText,defaultExt) 40 | % folderBrowser=SelectFolder(folderBrowser,SomeUIFig); 41 | % waveformNames=getFileNames(folderBrowser,'withext'); 42 | % waveformPaths=getFullFileNamesWithPath(folderBrowser,'withext'); 43 | 44 | properties %(Access=protected) 45 | defaultDir 46 | dialogText 47 | defaultExt 48 | fileNames 49 | directoryName 50 | UIFigure matlab.ui.Figure 51 | end 52 | 53 | 54 | methods 55 | function folderBrowser=folderBrowserGUI(defaultDir,dialogText,defaultExt) 56 | if nargin > 0 57 | folderBrowser.defaultDir=defaultDir; 58 | folderBrowser.dialogText=dialogText; 59 | folderBrowser.defaultExt=defaultExt; 60 | end 61 | end 62 | 63 | function folderBrowser=setDefaultDir(folderBrowser,defaultDir) 64 | folderBrowser.defaultDir=defaultDir; 65 | end 66 | 67 | function folderBrowser=setDialogText(folderBrowser,dialogText) 68 | folderBrowser.dialogText=dialogText; 69 | end 70 | 71 | function folderBrowser=setDefaultExt(folderBrowser,defaultExt) 72 | folderBrowser.defaultExt=defaultExt; 73 | end 74 | 75 | function fileNames=getFileNames(folderBrowser,ext) 76 | % return cell arry of file names 77 | if nargin > 1 && strcmp(ext,'withoutext') 78 | for f_in=1:length(folderBrowser.fileNames) 79 | folderBrowser.fileNames{f_in}= folderBrowser.fileNames{f_in}(1:end-4); 80 | end 81 | end 82 | fileNames=folderBrowser.fileNames; 83 | 84 | end 85 | 86 | function directoryName=getCurrentDir(folderBrowser) 87 | directoryName=folderBrowser.directoryName; 88 | end 89 | 90 | function fullFileNames=getFullFileNamesWithPath(folderBrowser,ext) 91 | % return cell arry of file names with paths 92 | if nargin > 1 && strcmp(ext,'withoutext') 93 | for f_in=1:length(folderBrowser.fileNames) 94 | filesN{f_in}= folderBrowser.fileNames{f_in}(1:end-4); 95 | end 96 | else 97 | filesN=folderBrowser.fileNames; 98 | end 99 | for I=1:length(filesN) 100 | fullFileNames{I}=fullfile(folderBrowser.directoryName,filesN{I}); 101 | end 102 | fullFileNames=fullFileNames.'; 103 | end 104 | 105 | function folderBrowser=SelectFolder(folderBrowser,UIFigure) 106 | folderBrowser.directoryName = uigetdir(folderBrowser.defaultDir,folderBrowser.dialogText); 107 | if folderBrowser.directoryName~=0 108 | default_ext=strcat('*.',folderBrowser.defaultExt); 109 | dirSearch=fullfile(folderBrowser.directoryName,default_ext); 110 | dr = dir(dirSearch); 111 | if isempty(dr) 112 | if nargin > 1 113 | uialert(UIFigure,folderBrowser.directoryName,['No ', folderBrowser.defaultExt,' files found in']); 114 | end 115 | %return; 116 | else 117 | for f_in=1:length(dr) 118 | file_name_cell{f_in}= dr(f_in).name; 119 | end 120 | 121 | folderBrowser.fileNames=folderBrowserGUI.sortByNumbers(file_name_cell.'); 122 | 123 | end 124 | else 125 | folderBrowser.fileNames=[]; 126 | end 127 | end 128 | 129 | 130 | 131 | end 132 | 133 | methods (Static = true) 134 | 135 | function sortedCell=sortByNumbers(unsortedCell) 136 | digits=regexp(unsortedCell,'\d'); 137 | values=zeros(length(unsortedCell),1); 138 | 139 | for I=1:length(unsortedCell) 140 | values(I)=str2double(unsortedCell{I}(digits{I})); 141 | end 142 | 143 | [~,I]=sort(values); 144 | sortedCell=unsortedCell(I); 145 | end 146 | end 147 | end 148 | 149 | -------------------------------------------------------------------------------- /src/util/folderBrowserGUIwithFileCheck.m: -------------------------------------------------------------------------------- 1 | ...%% Legal Disclaimer 2 | ...% NIST-developed software is provided by NIST as a public service. 3 | ...% You may use, copy and distribute copies of the software in any medium, 4 | ...% provided that you keep intact this entire notice. You may improve, 5 | ...% modify and create derivative works of the software or any portion of 6 | ...% the software, and you may copy and distribute such modifications or 7 | ...% works. Modified works should carry a notice stating that you changed 8 | ...% the software and should note the date and nature of any such change. 9 | ...% Please explicitly acknowledge the National Institute of Standards and 10 | ...% Technology as the source of the software. 11 | ...% 12 | ...% NIST-developed software is expressly provided "AS IS." NIST MAKES NO 13 | ...% WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT OR ARISING BY 14 | ...% OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY 15 | ...% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 16 | ...% AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE 17 | ...% OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR 18 | ...% THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY 19 | ...% REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS 20 | ...% THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, 21 | ...% RELIABILITY, OR USEFULNESS OF THE SOFTWARE. 22 | ...% 23 | ...% You are solely responsible for determining the appropriateness of 24 | ...% using and distributing the software and you assume all risks 25 | ...% associated with its use, including but not limited to the risks and 26 | ...% costs of program errors, compliance with applicable laws, damage to 27 | ...% or loss of data, programs or equipment, and the unavailability or 28 | ...% interruption of operation. This software is not intended to be used in 29 | ...% any situation where a failure could cause risk of injury or damage to 30 | ...% property. The software developed by NIST employees is not subject to 31 | ...% copyright protection within the United States. 32 | 33 | classdef folderBrowserGUIwithFileCheck < folderBrowserGUI 34 | %%Folder browser GUI with check for appropriate files 35 | % Detailed explanation goes here 36 | 37 | properties %(Access=protected) 38 | fileFields 39 | end 40 | 41 | methods 42 | 43 | function folderBrowser=setFileFields(folderBrowser,fileFields) 44 | folderBrowser.fileFields=fileFields; 45 | end 46 | function [folderBrowser,fullFileNames] = checkFileFields(folderBrowser) 47 | fullFileNames=getFullFileNamesWithPath(folderBrowser); 48 | if ~isempty(folderBrowser.fileFields) 49 | varNames=cellfun(@(x) who('-file', x),fullFileNames, 'un',0); 50 | checkVarNames=cellfun(@(x) ismember(x,[{'waveformTable'};{'waveforms'}]),varNames,'un',0 ); 51 | validFiles=cellfun(@sum,checkVarNames)==length(folderBrowser.fileFields); 52 | folderBrowser.fileNames=folderBrowser.fileNames(validFiles); 53 | fullFileNames=fullFileNames(validFiles); 54 | end 55 | end 56 | end 57 | end 58 | 59 | -------------------------------------------------------------------------------- /src/util/parforuiprogressdlg.m: -------------------------------------------------------------------------------- 1 | ...%% Legal Disclaimer 2 | ...% NIST-developed software is provided by NIST as a public service. 3 | ...% You may use, copy and distribute copies of the software in any medium, 4 | ...% provided that you keep intact this entire notice. You may improve, 5 | ...% modify and create derivative works of the software or any portion of 6 | ...% the software, and you may copy and distribute such modifications or 7 | ...% works. Modified works should carry a notice stating that you changed 8 | ...% the software and should note the date and nature of any such change. 9 | ...% Please explicitly acknowledge the National Institute of Standards and 10 | ...% Technology as the source of the software. 11 | ...% 12 | ...% NIST-developed software is expressly provided "AS IS." NIST MAKES NO 13 | ...% WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT OR ARISING BY 14 | ...% OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY 15 | ...% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 16 | ...% AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE 17 | ...% OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR 18 | ...% THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY 19 | ...% REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS 20 | ...% THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, 21 | ...% RELIABILITY, OR USEFULNESS OF THE SOFTWARE. 22 | ...% 23 | ...% You are solely responsible for determining the appropriateness of 24 | ...% using and distributing the software and you assume all risks 25 | ...% associated with its use, including but not limited to the risks and 26 | ...% costs of program errors, compliance with applicable laws, damage to 27 | ...% or loss of data, programs or equipment, and the unavailability or 28 | ...% interruption of operation. This software is not intended to be used in 29 | ...% any situation where a failure could cause risk of injury or damage to 30 | ...% property. The software developed by NIST employees is not subject to 31 | ...% copyright protection within the United States. 32 | 33 | classdef parforuiprogressdlg 34 | % parforuiprogressdlg: ui progress bar for parfor with appdesigner 35 | % requires uifigure input as parent figure 36 | % progBar = parforuiprogressdlg(uiFig, title,numOfIter,progMsg) 37 | % creates ui progress bar with numOfIter iterations 38 | % A temporary file in tempdir is used to communicate among threads. 39 | 40 | % 41 | % progBar.iterate(X) updates the progress bar by X iterations. 42 | % 43 | % Example: 44 | % -------- 45 | % uiFig=uifigure; % 46 | % numOfIter=20; %number of iterations 47 | % title='Processing'; %dialog title 48 | % progMsg='Working on:'; %dialog message 49 | % progBar =parforuiprogressdlg(uiFig, title,numOfIter,progMsg) %create the uiprogressbar 50 | % parfor i=1:numOfIter, 51 | % pause(rand); 52 | % progBar.iterate(1); % increase iteration 53 | % end 54 | % 55 | % Derived from parfor_progressbar Copyright (c) 2016, Daniel Terry All rights reserved 56 | % https://www.mathworks.com/matlabcentral/fileexchange/53773-parfor-progressbar 57 | % 58 | % See also: uiprogressdlg, uifigure, parfor. 59 | 60 | % Public properties 61 | properties (SetAccess=protected, GetAccess=public) 62 | progBar; % uiprogressdlg, requires uifigure 63 | numOfIter; % Total number of iterations 64 | iterMessage; % message displayed with progressbar, format [this.iterMessage, '%d out of %d'] 65 | end 66 | 67 | properties (Dependent, GetAccess=public) 68 | value; % current iteration value 69 | end 70 | 71 | 72 | % Internal properties 73 | properties (SetAccess=protected, GetAccess=protected, Hidden) 74 | tempFile; % Path to temporary file for inter-process communication 75 | hTimer; % Timer object that checks tempFile for completed iterations 76 | end 77 | 78 | 79 | 80 | methods 81 | %======================== CONSTRUCTOR ========================% 82 | function this = parforuiprogressdlg(uiFig, title,numOfIter,iterMessage) 83 | % Construct uiprogress bar with numOfIter iterations 84 | % Create a unique inter-process communication file. 85 | for i=1:10 86 | f = sprintf('%s%d.txt', mfilename, round(rand*1000)); 87 | this.tempFile = fullfile(tempdir, f); 88 | if ~exist(this.tempFile,'file'), break; end 89 | end 90 | 91 | if exist(this.tempFile,'file') 92 | error('Too many temporary files. Clear out tempdir.'); 93 | end 94 | 95 | %Creates a new ui progress bar 96 | this.numOfIter = numOfIter; 97 | this.iterMessage=iterMessage; 98 | this.progBar = uiprogressdlg(uiFig,'Title',title,... 99 | 'Message','1','Cancelable','off'); 100 | 101 | % Create timer to periodically update the waitbar in the GUI thread. 102 | this.hTimer = timer( 'ExecutionMode','fixedSpacing', 'Period',0.2, ... 103 | 'BusyMode','drop', 'Name',mfilename, ... 104 | 'TimerFcn',@(~,~)this.tupdate() ); 105 | start(this.hTimer); 106 | end 107 | 108 | %========================= DESTRUCTOR ========================% 109 | function delete(this) 110 | this.close(); 111 | end 112 | 113 | function close(this) 114 | % Closer the progress bar and clean up internal state. 115 | 116 | % Stop the timer 117 | if isa(this.hTimer,'timer') && isvalid(this.hTimer) 118 | stop(this.hTimer); 119 | pause(0.01); 120 | delete(this.hTimer); 121 | end 122 | this.hTimer = []; 123 | 124 | % Delete the IPC file. 125 | if exist(this.tempFile,'file') 126 | delete(this.tempFile); 127 | end 128 | 129 | % Close the progBar 130 | 131 | close(this.progBar); 132 | 133 | this.progBar = []; 134 | end 135 | 136 | 137 | %====================== GET/SET METHODS ======================% 138 | function value = get.value(this) 139 | % Read current number of iterations from tempFile 140 | if ~exist(this.tempFile, 'file') 141 | value = 0; % File may not exist before the first iteration 142 | else 143 | fid = fopen( this.tempFile, 'r' ); 144 | value = sum(fscanf(fid, '%d')) ; 145 | fclose(fid); 146 | end 147 | end 148 | 149 | 150 | 151 | function iterate(this, iterStep) 152 | % Update the progress bar by iterStep iterations, set default iterStep=1 153 | if nargin<2, iterStep = 1; end 154 | 155 | fid = fopen(this.tempFile, 'a'); 156 | fprintf(fid, '%d\n', iterStep); 157 | fclose(fid); 158 | end 159 | 160 | 161 | end %public methods 162 | 163 | 164 | 165 | %===================== INTERNAL METHODS =====================% 166 | methods (Access=protected, Hidden) 167 | 168 | 169 | function tupdate(this) 170 | % Check the IPC file and update the progressbar and its message 171 | val=this.value; 172 | numIter=this.numOfIter; 173 | if (val/numIter<1) %~(this.progBar.CancelRequested) && (val/numIter<1) 174 | this.progBar.Value = val/numIter; 175 | this.progBar.Message = sprintf([this.iterMessage, '%d out of %d'],val,numIter); 176 | else 177 | % Kill the timer if the progressbar is closed. 178 | close(this); 179 | end 180 | end 181 | 182 | 183 | end %private methods 184 | 185 | 186 | 187 | 188 | end %classdef --------------------------------------------------------------------------------