%% ========================================================== % MASTER_RUNUP.m % Master script for CIRN video-based run-up processing. % % The script: % 1. Checks for existing GCP and camera solutions % 2. Generates the rectification grid if required % 3. Generates image products if required % 4. Extracts pixel-instrument data if required % 5. Performs run-up analysis if required % % Existing processing products are detected automatically and % are not regenerated unless the corresponding output is missing. % %% ========================================================== clear close all clc %% Select run % Specify the experiment/run to process. runName = "C7a"; % Options: % "C3" % "C3a" % "C7" % "C7a" % "C11" % "C11a" %% User-configurable paths %% Root folders % videoRoot contains one folder per experimental run. % dataRoot contains calibration files shared between runs. videoRoot = "PATH_TO_MAIN_VIDEOS"; dataRoot = "PATH_TO_MAIN_DATA"; scriptFolder = "PATH_TO_FINAL_SCRIPTS"; %% Common calibration files intrinsicsFile = fullfile(dataRoot,"FORALL_IO.mat"); gcpWorldFile = fullfile(dataRoot,"GCP Real Cords.txt"); %% Run folder runFolder = fullfile(videoRoot, runName); video = dir(fullfile(runFolder,"*.mp4")); bed = [ ... dir(fullfile(runFolder,"*bed*.csv")); ... dir(fullfile(runFolder,"*bed*.xlsx")) ... ]; if isempty(bed) error("No bed file found in %s", runFolder); end bedFile = fullfile(bed(1).folder, bed(1).name); lidar = dir(fullfile(runFolder,"*lidar.*")); videoFile = fullfile(video.folder,video.name); lidarFile = fullfile(runFolder, lidar.name); outputFolder = fullfile(runFolder,"Outputs"); %% Standard folders framesFolder = fullfile(outputFolder,"Frames"); rectifiedFolder = fullfile(outputFolder,"Rectified"); instrumentFolder = fullfile(outputFolder,"Instruments"); resultsFolder = fullfile(outputFolder,"Results"); folders = {framesFolder, rectifiedFolder, instrumentFolder, resultsFolder}; for i = 1:length(folders) if ~exist(folders{i},'dir') mkdir(folders{i}); end end qcFolder = fullfile(outputFolder,"QC"); if ~exist(qcFolder,'dir') mkdir(qcFolder) end %% Display disp("Current run:") disp(runName) disp("Video:") disp(videoFile) disp("Output:") disp(outputFolder) %% Standard filenames gridFile = fullfile(runFolder, sprintf("GRID_%s.mat",runName)); pixInstFile = fullfile(instrumentFolder, sprintf("%s_pixInst.mat",runName)); runupCSV = fullfile(resultsFolder, sprintf("%s_runup.csv",runName)); metricsCSV = fullfile(resultsFolder, sprintf("%s_metrics.csv",runName)); ioeoFile = fullfile(outputFolder, runName + "_IOEOInitial.mat"); gridMetaFile = fullfile(rectifiedFolder, ... sprintf("%s_gridMeta.mat",runName)); shorelineFile = fullfile(resultsFolder,... sprintf("%s_shoreline_timeseries.mat",runName)); %% Required run inputs % % Each run folder should contain: % - Run video (*.mp4) % - Bed/topographic survey (*bed*.csv or *bed*.xlsx) % - LiDAR data (*lidar.*) % % Shared calibration data are stored in dataRoot. addpath(scriptFolder) addpath(genpath(fullfile(scriptFolder,"X_CoreFunctions"))) rehash % ---------- B ---------- gcpFile = fullfile(outputFolder, runName + "_gcpUVdInitial.mat"); if exist(gcpFile,'file') disp("✓ Existing GCP file found.") else disp("No GCP file found - launching GCP selection.") run('B_gcpSelection.m') end % ---------- C ---------- if exist(ioeoFile,'file') disp("✓ Existing IOEO solution found.") else disp("No IOEO solution found - solving camera.") run('C_singleExtrinsicSolution.m') end % ---------- D ---------- if exist(gridFile,'file') disp("Existing grid found.") else run('D_gridGenExampleRect.m') end % ---------- G1 ---------- if exist(gridMetaFile,'file') disp("✓ Existing image products found.") else disp("Running image products...") run('G1_imageProducts.m') end % ---------- G2 ---------- % G2 is only rerun if the pixel-instrument MAT file does not % contain the expected pixInst variable. needG2 = true; if exist(pixInstFile,'file') try vars = who('-file', pixInstFile); if any(strcmp(vars,'pixInst')) needG2 = false; disp("✓ Existing pixel instruments found.") else disp("Pixel instrument file is incomplete - rebuilding.") end catch disp("Pixel instrument file is corrupted - rebuilding.") end end if needG2 disp("Running pixel instruments...") run('G2_pixelInstruments.m') end % ---------- J: Run-up analysis ---------- % Detect shoreline position, calculate run-up elevation, % compare with LiDAR, and save run-up/validation products. if exist(shorelineFile,'file') disp("✓ Existing run-up analysis found.") else disp("Running run-up analysis...") run('J_runup_variance.m') end disp(" ") disp("===================================") disp("Processing complete!") disp("===================================")