├── .github ├── actions │ └── SetupEnvironment │ │ └── action.yml └── workflows │ ├── ApplicationTesting.yml │ ├── Build.yml │ ├── Pipeline.yml │ └── Release.yml ├── .gitignore ├── Config ├── sample_SEABIRD_SOLARTRACKER.cfg ├── sample_SEABIRD_SOLARTRACKER.hdr ├── sample_SEABIRD_SOLARTRACKER_Calibration │ ├── GPRMC_NMEA0183v3.01.tdf │ ├── HED488B.cal │ ├── HLD385B.cal │ ├── HLD386B.cal │ ├── HSE488B.cal │ ├── HSL385B.cal │ ├── HSL386B.cal │ ├── IRP3397A.cal │ ├── SAS045_20160203.sip │ ├── SATMSG.tdf │ ├── SATNAV0001A.tdf │ ├── SATPYR.tdf │ └── SATTHS0045A.tdf ├── sample_SEABIRD_SOLARTRACKER_anoms.csv ├── sample_SEABIRD_pySAS.cfg ├── sample_SEABIRD_pySAS.hdr ├── sample_SEABIRD_pySAS_Calibration │ ├── CP_SAT0385_POLAR_20220603115256.txt │ ├── CP_SAT0385_RADCAL_20220606105303.txt │ ├── CP_SAT0385_STRAY_20220602142331.txt │ ├── CP_SAT0385_THERMAL_20220604193311.txt │ ├── CP_SAT0386_POLAR_20220603123340.TXT │ ├── CP_SAT0386_RADCAL_20220606105628.TXT │ ├── CP_SAT0386_STRAY_20220602181047.TXT │ ├── CP_SAT0386_THERMAL_20220603193311.TXT │ ├── CP_SAT0488_ANGULAR_20220530141651.TXT │ ├── CP_SAT0488_RADCAL_20220606140951.TXT │ ├── CP_SAT0488_STRAY_20220603021236.TXT │ ├── CP_SAT0488_THERMAL_20220525093631.TXT │ ├── GPRMC_NMEA0183v3.01.tdf │ ├── HED0488_Tartu.cal │ ├── HLD0385_Tartu.cal │ ├── HLD0386_Tartu.cal │ ├── HSE0488_Tartu.cal │ ├── HSL0385_Tartu.cal │ ├── HSL0386_Tartu.cal │ ├── SAS045_20220606.sip │ ├── SATMSG.tdf │ ├── SATTHS0045A.tdf │ └── UMTWR_v0.tdf ├── sample_SEABIRD_pySAS_anoms.csv ├── sample_TRIOS_NOTRACKER.cfg ├── sample_TRIOS_NOTRACKER.hdr └── sample_TRIOS_NOTRACKER_Calibration │ ├── Back_SAM_8166.dat │ ├── Back_SAM_8329.dat │ ├── Back_SAM_8595.dat │ ├── CP_SAM_8166_POLAR_20220602154359.TXT │ ├── CP_SAM_8166_RADCAL_20220627094112.TXT │ ├── CP_SAM_8166_STRAY_20220610145012.TXT │ ├── CP_SAM_8166_THERMAL_20220504195659.TXT │ ├── CP_SAM_8329_ANGULAR_20220704122830.TXT │ ├── CP_SAM_8329_RADCAL_20220708095236.TXT │ ├── CP_SAM_8329_STRAY_20220706131609.TXT │ ├── CP_SAM_8329_THERMAL_20220705205846.TXT │ ├── CP_SAM_8595_POLAR_20220602152509.TXT │ ├── CP_SAM_8595_RADCAL_20220627094519.TXT │ ├── CP_SAM_8595_STRAY_20220610120116.TXT │ ├── CP_SAM_8595_THERMAL_20230425163826.TXT │ ├── Cal_SAM_8166.dat │ ├── Cal_SAM_8329.dat │ ├── Cal_SAM_8595.dat │ ├── SAM_8166.ini │ ├── SAM_8329.ini │ └── SAM_8595.ini ├── Data ├── Class_Based_Characterizations │ ├── SeaBird_initial │ │ ├── CP_HyperOCR_E_class_LINEAR_20230406091100.txt │ │ ├── CP_HyperOCR_E_class_POLAR_20230406091100.txt │ │ ├── CP_HyperOCR_E_class_STAB_20230406091100.txt │ │ ├── CP_HyperOCR_E_class_STRAY_20231109135133.txt │ │ ├── CP_HyperOCR_E_class_THERMAL_20230406090255.txt │ │ ├── CP_HyperOCR_LI_class_POLAR_20230406090628.txt │ │ ├── CP_HyperOCR_LI_class_STRAY_20231109135133.txt │ │ ├── CP_HyperOCR_LT_class_POLAR_20230406090628.txt │ │ ├── CP_HyperOCR_LT_class_STRAY_20231109135133.txt │ │ ├── CP_HyperOCR_L_class_LINEAR_20230406091100.txt │ │ ├── CP_HyperOCR_L_class_STAB_20230406091100.txt │ │ └── CP_HyperOCR_L_class_THERMAL_20230406090255.txt │ └── TriOS_initial │ │ ├── CP_RAMSES_E_class_LINEAR_20230406091100.txt │ │ ├── CP_RAMSES_E_class_POLAR_20230406090628.txt │ │ ├── CP_RAMSES_E_class_STAB_20230406090628.txt │ │ ├── CP_RAMSES_E_class_STRAY_20231109135133.txt │ │ ├── CP_RAMSES_E_class_THERMAL_20230406090255.txt │ │ ├── CP_RAMSES_LI_class_POLAR_20230406090628.txt │ │ ├── CP_RAMSES_LI_class_STRAY_20231109135133.txt │ │ ├── CP_RAMSES_LT_class_POLAR_20230406090628.txt │ │ ├── CP_RAMSES_LT_class_STRAY_20231109135133.txt │ │ ├── CP_RAMSES_L_class_LINEAR_20230406091100.txt │ │ ├── CP_RAMSES_L_class_STAB_20230406090628.txt │ │ └── CP_RAMSES_L_class_THERMAL_20230406090255.txt ├── HMODISA_RSRs.txt ├── HMODIST_RSRs.txt ├── Img │ ├── Configuration_window.png │ ├── Deglitching_window.JPG │ ├── EARTHDATA_ACCESS.png │ ├── EARTHDATA_ACCESS_popup.png │ ├── ECMWF_ADS_logo.png │ ├── ECMWF_CDS_logo.png │ ├── ECMWF_api_key.png │ ├── ECMWF_popup.png │ ├── ECMWF_register0.png │ ├── ECMWF_register1.png │ ├── ECMWF_terms.png │ ├── EUMETSAT_Data_Store_logo.png │ ├── Flow_chart_1.2.0.png │ ├── Main.png │ ├── NASA_Earth_Data_logo.png │ ├── banner.jpg │ ├── banner_530x151.png │ ├── logo.icns │ ├── logo.ico │ ├── logo_scale20.png │ └── with_background_530x223.png ├── MERIS_RSRs_avg.txt ├── OLCIA_RSRs.txt ├── OLCIB_RSRs.txt ├── Sample_Data │ ├── DALEC │ │ ├── RAW │ │ │ └── DALEC_12_2024-05-19_232814Z.TXT │ │ └── VIIRS2024_DALEC_Ancillary.sb │ ├── Manual_TriOS │ │ ├── FICE22_TriOS_Ancillary.sb │ │ ├── Instrument_Characterization_2022 │ │ │ ├── CP_SAM_8166_POLAR_20220602154359.TXT │ │ │ ├── CP_SAM_8166_RADCAL_20220627094112.TXT │ │ │ ├── CP_SAM_8166_STRAY_20220610145012.TXT │ │ │ ├── CP_SAM_8166_THERMAL_20220504195659.TXT │ │ │ ├── CP_SAM_8329_ANGULAR_20220704122830.TXT │ │ │ ├── CP_SAM_8329_RADCAL_20220708095236.TXT │ │ │ ├── CP_SAM_8329_STRAY_20220706131609.TXT │ │ │ ├── CP_SAM_8329_THERMAL_20220705205846.TXT │ │ │ ├── CP_SAM_8595_POLAR_20220602152509.TXT │ │ │ ├── CP_SAM_8595_RADCAL_20220627094519.TXT │ │ │ ├── CP_SAM_8595_STRAY_20220610120116.TXT │ │ │ └── CP_SAM_8595_THERMAL_20230425163826.TXT │ │ └── RAW │ │ │ ├── SAM_8166_RAW_SPECTRUM_FRM4SOC2_FICE22_UT_20220719_080000.mlb │ │ │ ├── SAM_8166_RAW_SPECTRUM_FRM4SOC2_FICE22_UT_20220719_082000.mlb │ │ │ ├── SAM_8329_RAW_SPECTRUM_FRM4SOC2_FICE22_UT_20220719_080000.mlb │ │ │ ├── SAM_8329_RAW_SPECTRUM_FRM4SOC2_FICE22_UT_20220719_082000.mlb │ │ │ ├── SAM_8595_RAW_SPECTRUM_FRM4SOC2_FICE22_UT_20220719_080000.mlb │ │ │ └── SAM_8595_RAW_SPECTRUM_FRM4SOC2_FICE22_UT_20220719_082000.mlb │ ├── SolarTracker │ │ ├── KORUS_SOLARTRACKER_Ancillary.sb │ │ └── RAW │ │ │ └── KORUS_KR2016_NASA_20160320_060000.RAW │ └── pySAS │ │ ├── FICE22_pySAS_Ancillary.sb │ │ ├── Instrument_Characterization_2022 │ │ ├── CP_SAT0385_POLAR_20220603115256.txt │ │ ├── CP_SAT0385_RADCAL_20220606105303.txt │ │ ├── CP_SAT0385_STRAY_20220602142331.txt │ │ ├── CP_SAT0385_THERMAL_20220604193311.txt │ │ ├── CP_SAT0386_POLAR_20220603123340.TXT │ │ ├── CP_SAT0386_RADCAL_20220606105628.TXT │ │ ├── CP_SAT0386_STRAY_20220602181047.TXT │ │ ├── CP_SAT0386_THERMAL_20220603193311.TXT │ │ ├── CP_SAT0488_ANGULAR_20220530141651.TXT │ │ ├── CP_SAT0488_RADCAL_20220606140951.TXT │ │ ├── CP_SAT0488_STRAY_20220603021236.TXT │ │ └── CP_SAT0488_THERMAL_20220525093631.TXT │ │ ├── Photos │ │ ├── 20220719_112534.jpg │ │ ├── 20220719_112546.jpg │ │ ├── 20220719_112553.jpg │ │ └── 20220719_112609.jpg │ │ └── RAW │ │ └── FRM4SOC2_FICE22_NASA_20220719_080000.raw ├── Thuillier_F0.sb ├── VIIRS1_RSRs.txt ├── VIIRSN_IDPSv3_RSRs.txt ├── Water_Absorption.sb ├── correlation_mats.csv ├── hybrid_reference_spectrum_p1nm_resolution_c2020-09-21_with_unc.nc ├── rhoTable_AO1999.hdf └── rhoTable_AO1999.txt ├── Experiment_Cruise_Instrument_Radiometry_Field_Log.xlsx ├── HyperCP - Collaboration Guidelines.pdf ├── LICENSE.txt ├── Main.py ├── NOSA GSC-18527-1.pdf ├── README.md ├── README_Sample_Data.xlsx ├── README_ancillary.md ├── README_bundle.md ├── README_configuration.md ├── README_deglitching.md ├── Source ├── AncillaryReader.py ├── AnomalyDetection.py ├── BandData.py ├── CalibrationData.py ├── CalibrationFile.py ├── CalibrationFileReader.py ├── ConfigFile.py ├── ConfigWindow.py ├── Controller.py ├── FidradDB_api.py ├── FieldPhotos.py ├── GetAnc.py ├── GetAnc_credentials.py ├── GetAnc_ecmwf.py ├── HDFDataset.py ├── HDFGroup.py ├── HDFRoot.py ├── L2avw.py ├── L2chlor_a.py ├── L2gocad.py ├── L2ipar.py ├── L2kd490.py ├── L2par.py ├── L2pic.py ├── L2poc.py ├── L2qaa.py ├── L2qwip.py ├── L2wei_QA.py ├── MainConfig.py ├── OBPGSession.py ├── OCproductsWindow.py ├── PDFreport.py ├── ProcessInstrumentUncertainties.py ├── ProcessL1aDALEC.py ├── ProcessL1aSeaBird.py ├── ProcessL1aSoRad.py ├── ProcessL1aTriOS.py ├── ProcessL1aqc.py ├── ProcessL1aqc_deglitch.py ├── ProcessL1b.py ├── ProcessL1bDALEC.py ├── ProcessL1bTriOS.py ├── ProcessL1b_FRMCal.py ├── ProcessL1b_FactoryCal.py ├── ProcessL1b_Interp.py ├── ProcessL1bqc.py ├── ProcessL2.py ├── ProcessL2BRDF.py ├── ProcessL2OCproducts.py ├── RawFileReader.py ├── RhoCorrections.py ├── SB_support.py ├── SeaBASSHeader.py ├── SeaBASSHeaderWindow.py ├── SeaBASSWriter.py ├── Uncertainty_Analysis.py ├── Uncertainty_Visualiser.py ├── Utilities.py ├── Water_IOPs.py ├── Weight_RSR.py ├── WriteRhoM99.py ├── ZhangRho.py ├── __init__.py ├── matheo │ ├── band_integration.py │ ├── punpy_util.py │ └── srf_utils.py ├── ocbrdf │ ├── BRDF_LUTs │ │ ├── BRDF_L11.nc │ │ ├── BRDF_M02.nc │ │ ├── BRDF_M02SeaDAS.nc │ │ └── BRDF_UNC.nc │ ├── Raman.py │ ├── brdf_model_L11.py │ ├── brdf_model_M02.py │ ├── brdf_model_M02SeaDAS.py │ ├── brdf_model_O23.py │ ├── brdf_utils.py │ └── ocbrdf_main.py └── raw_Data_Hourly_Cutter.py ├── Tests ├── __init__.py └── test_sample_data.py ├── build_Z17-LUT.py ├── environment.yml ├── make.py └── run_Sample_Data.py /.github/actions/SetupEnvironment/action.yml: -------------------------------------------------------------------------------- 1 | name: SetupEnvironment 2 | description: 'Setup python environment with conda' 3 | 4 | runs: 5 | using: "composite" 6 | 7 | steps: 8 | - name: 🐍 Setup Mambaforge 9 | uses: conda-incubator/setup-miniconda@v3 10 | with: 11 | miniforge-version: latest 12 | # miniforge-variant: Mambaforge 13 | # use-mamba: true # mambaforge is now deprecated in favor of miniforge 14 | activate-environment: hypercp 15 | 16 | - name: 🔂 Cache Environment 17 | uses: actions/cache@v4 18 | with: 19 | path: ${{ env.CONDA }}/envs 20 | key: 21 | conda-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('environment.yml') }}-${{ env.CACHE_NUMBER }} 22 | env: 23 | # Increase this value to reset cache if environment.yml has not changed 24 | CACHE_NUMBER: 1 25 | id: cache 26 | 27 | - name: 🔄 Update Environment 28 | if: runner.os != 'Windows' && steps.cache.outputs.cache-hit != 'true' 29 | shell: bash -el {0} 30 | run: | 31 | mamba env update -n hypercp -f environment.yml 32 | mamba install --channel=conda-forge pyinstaller 33 | 34 | - name: 📸 Capture Environment 35 | if: runner.os != 'Windows' 36 | shell: bash -el {0} 37 | run: | 38 | mamba info 39 | mamba list 40 | 41 | - name: 🔄 Update Environment [Windows] 42 | if: runner.os == 'Windows' && steps.cache.outputs.cache-hit != 'true' 43 | shell: pwsh 44 | run: | 45 | mamba env update -n hypercp -f environment.yml 46 | mamba install --channel=conda-forge pyinstaller 47 | 48 | - name: 📸 Capture Environment [Windows] 49 | if: runner.os == 'Windows' 50 | shell: pwsh 51 | run: | 52 | mamba info 53 | mamba list 54 | -------------------------------------------------------------------------------- /.github/workflows/ApplicationTesting.yml: -------------------------------------------------------------------------------- 1 | name: Application Testing 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | workflow_dispatch: 8 | 9 | jobs: 10 | 11 | ApplicationTesting: 12 | name: Application Tests 13 | 14 | runs-on: ${{ matrix.os }} 15 | defaults: # Required for conda environment activation 16 | run: 17 | shell: bash -el {0} 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | os: [ 'ubuntu-latest', 'macos-latest', 'windows-latest' ] 22 | 23 | steps: 24 | - name: ⏬ Checkout repository 25 | uses: actions/checkout@v4 26 | with: 27 | ref: ${{ github.event.inputs.branch }} 28 | 29 | - name: 🔧 Setup Environment 30 | uses: ./.github/actions/SetupEnvironment 31 | 32 | - name: 🔑 Get ECMWF CDS|ADS Credentials 33 | env: 34 | CDSAPIRC: ${{ secrets.ECMWF_ADS_CREDENTIALS }} 35 | run: | 36 | echo "$CDSAPIRC" >> ~/.ecmwf_ads_credentials.json 37 | 38 | - name: 🔑 Get GMAO MERRA2 Credentials 39 | env: 40 | NETRC: ${{ secrets.NETRC }} 41 | run: | 42 | echo "$NETRC" >> ~/.netrc 43 | 44 | - name: 🧪 Run Tests 45 | run: | 46 | python -m unittest Tests.test_sample_data 47 | -------------------------------------------------------------------------------- /.github/workflows/Build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | workflow_call: 5 | outputs: 6 | files: 7 | description: 'Artifact filenames.' 8 | value: | 9 | ${{ jobs.Build.outputs.ubuntu_artifact_filename }} 10 | ${{ jobs.Build.outputs.macos_artifact_filename }} 11 | ${{ jobs.Build.outputs.windows_artifact_filename }} 12 | 13 | jobs: 14 | Build: 15 | name: Bundle 16 | 17 | runs-on: ${{ matrix.os }} 18 | defaults: # Required for conda environment activation 19 | run: 20 | shell: bash -el {0} 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | os: ['ubuntu-latest', 'macos-latest', 'windows-latest'] 25 | 26 | steps: 27 | - name: ⏬ Checkout repository 28 | uses: actions/checkout@v4 29 | with: 30 | ref: ${{ github.event.inputs.branch }} 31 | 32 | - name: 🔧 Setup Environment 33 | uses: ./.github/actions/SetupEnvironment 34 | 35 | - name: 📑 Make Bundle 36 | run: | 37 | python make.py 38 | echo "BUNDLE_NAME=$(ls Bundled/dist | head -1 | xargs)" >> $GITHUB_ENV 39 | 40 | - name: 📥 Zip Bundle 41 | uses: thedoctor0/zip-release@0.7.6 42 | with: 43 | type: 'zip' 44 | directory: 'Bundled/dist/' 45 | path: '${{ env.BUNDLE_NAME }}' 46 | filename: '${{ env.BUNDLE_NAME }}.zip' 47 | 48 | - name: ⏫️ Upload Bundle 49 | uses: actions/upload-artifact@v4 50 | with: 51 | name: ${{ env.BUNDLE_NAME }} 52 | path: Bundled/dist/${{ env.BUNDLE_NAME }}.zip 53 | compression-level: 0 54 | # Double zip as need zip for release page (ideally want to prevent unzip from download artifact) 55 | -------------------------------------------------------------------------------- /.github/workflows/Pipeline.yml: -------------------------------------------------------------------------------- 1 | name: Build & Release Pipeline 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - bundle 8 | # tags: 9 | # - 'v[0-9]+.[0-9]+.*' 10 | workflow_dispatch: 11 | 12 | jobs: 13 | 14 | Build: 15 | name: 📦 Bundle Application 16 | uses: ./.github/workflows/Build.yml 17 | 18 | Release: 19 | name: 📝 Draft Release Page 20 | uses: ./.github/workflows/Release.yml 21 | needs: 22 | - Build 23 | 24 | ArtifactCleanUp: 25 | name: 🗑️ Artifact Cleanup 26 | runs-on: ubuntu-latest 27 | needs: 28 | - Build 29 | - Release 30 | steps: 31 | - name: Delete Artifact 32 | if: startsWith(github.ref, 'refs/heads/master') || startsWith(github.ref, 'refs/tags') 33 | uses: geekyeggo/delete-artifact@v4 34 | with: 35 | name: ${{ needs.Build.outputs.files }} 36 | token: ${{ secrets.GITHUB_TOKEN }} 37 | -------------------------------------------------------------------------------- /.github/workflows/Release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | workflow_call: 5 | outputs: 6 | artifacts: 7 | description: "Newline-delimited list of artifact filenames downloaded" 8 | value: ${{ jobs.Release.outputs.artifacts }} 9 | 10 | jobs: 11 | 12 | Release: 13 | name: Draft Release Page 14 | runs-on: ubuntu-latest 15 | 16 | outputs: 17 | artifacts: ${{ steps.get_variables.outputs.artifacts }} 18 | 19 | steps: 20 | - name: Download All Artifacts 21 | uses: actions/download-artifact@v4 22 | with: 23 | merge-multiple: True 24 | 25 | - name: Extract Git tag and Artifact names 26 | id: get_variables 27 | run: | 28 | GIT_TAG=${GITHUB_REF#refs/*/} 29 | RELEASE_VERSION=${GIT_TAG#v} 30 | RELEASE_DATETIME="$(date --utc '+%Y-%m-%d %H:%M:%S')" 31 | # write to step outputs 32 | cat >> "$GITHUB_OUTPUT" << EOF 33 | gitTag=${GIT_TAG} 34 | version=${RELEASE_VERSION} 35 | datetime=${RELEASE_DATETIME} 36 | EOF 37 | # Multi-line variables 38 | echo "artifacts<> $GITHUB_OUTPUT 39 | ls | xargs -n 1 >> $GITHUB_OUTPUT 40 | echo "EOF" >> $GITHUB_OUTPUT 41 | 42 | - name: Create Release Page 43 | uses: softprops/action-gh-release@v2 44 | with: 45 | files: ${{ steps.get_variables.outputs.artifacts }} 46 | body: | 47 | **Automated Release created on: ${{ steps.get_variables.outputs.datetime }}** 48 | 49 | ## New Features 50 | * tbd 51 | 52 | ## Changes 53 | * tbd 54 | 55 | ## Bug Fixes 56 | * tbd 57 | draft: true 58 | prerelease: false 59 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # pyenv 2 | .python-version 3 | 4 | # vscode 5 | .vscode/ 6 | 7 | # Backup stores 8 | ~* 9 | *.py~ 10 | .DS_Store 11 | 12 | # HyperCP 13 | .gitignore 14 | /Bundled/ 15 | Data/Zhang_rho_db.mat 16 | Data/Zhang_rho_db_expanded.mat 17 | Data/Zhang_rho_LUT.nc 18 | Data/Z17_LUT_v2.nc 19 | Data/Anc/ 20 | Data/L*/ 21 | Data/Reports/ 22 | Data/Photos/ 23 | # The /* is required if you later want to unignore subsets (i.e., to keep the directory itself) 24 | Data/Sample_Data/DALEC/* 25 | !Data/Sample_Data/DALEC/RAW 26 | !Data/Sample_Data/DALEC/RAW/* 27 | !Data/Sample_Data/DALEC/Instrument_Characterization*/ 28 | !Data/Sample_Data/DALEC/Instrument_Characterization*/* 29 | !Data/Sample_Data/DALEC/*Ancillary.sb 30 | Data/Sample_Data/Manual_TriOS/* 31 | !Data/Sample_Data/Manual_TriOS/RAW 32 | !Data/Sample_Data/Manual_TriOS/RAW/* 33 | !Data/Sample_Data/Manual_TriOS/Instrument_Characterization*/ 34 | !Data/Sample_Data/Manual_TriOS/Instrument_Characterization*/* 35 | !Data/Sample_Data/Manual_TriOS/*Ancillary.sb 36 | Data/Sample_Data/pySAS/* 37 | !Data/Sample_Data/pySAS/RAW 38 | !Data/Sample_Data/pySAS/RAW/* 39 | !Data/Sample_Data/pySAS/Instrument_Characterization*/ 40 | !Data/Sample_Data/pySAS/Instrument_Characterization*/* 41 | !Data/Sample_Data/pySAS/Photos/ 42 | !Data/Sample_Data/pySAS/*Ancillary.sb 43 | Data/Sample_Data/SolarTracker/* 44 | !Data/Sample_Data/SolarTracker/RAW 45 | !Data/Sample_Data/SolarTracker/RAW/* 46 | !Data/Sample_Data/SolarTracker/Instrument_Characterization*/ 47 | !Data/Sample_Data/SolarTracker/Instrument_Characterization*/* 48 | !Data/Sample_Data/SolarTracker/*Ancillary.sb 49 | Data/Sample_Data/SoRad/* 50 | !Data/Sample_Data/SoRad/RAW 51 | !Data/Sample_Data/SoRad/RAW/* 52 | !Data/Sample_Data/SoRad/Instrument_Characterization*/ 53 | !Data/Sample_Data/SoRad/Instrument_Characterization*/* 54 | !Data/Sample_Data/SoRad/*Ancillary.sb 55 | 56 | Config/* 57 | # To update sample configurations, uncomment: 58 | # !Config/sample_*_Calibration/ 59 | # !Config/sample_*.cfg 60 | # !Config/sample_*.hdr 61 | # !Config/sample_*.csv 62 | Plots/ 63 | Logs/ 64 | 65 | ## To allow local changes to a file on remote, but not have those tracked: 66 | # git update-index --skip-worktree Config/sample_SEABIRD_pySAS.cfg 67 | # Had to be run for each file due to conflicts with unrelated config files 68 | # See aliases in .bashrc 69 | # Will cause conflict changing branches if local files are different across branches 70 | 71 | Data/FidRadDB_characterization/ 72 | .pylintrc 73 | *.pyc 74 | *.log 75 | runtest.py 76 | run_*.py 77 | !run_Sample_Data.py 78 | 79 | # copernicus url and keys 80 | .cdsapirc 81 | # gitignore only skips new files, not updates to existing files 82 | .ecmwf_api_config 83 | 84 | #ignore ".idea/" if working with pycharm: 85 | .idea/ 86 | -------------------------------------------------------------------------------- /Config/sample_SEABIRD_SOLARTRACKER.hdr: -------------------------------------------------------------------------------- 1 | { 2 | "version": "R1", 3 | "investigators": "Antonio_Mannino,Dirk_Aurin", 4 | "affiliations": "NASA_GSFC", 5 | "contact": "dirk.a.aurin@nasa.gov", 6 | "experiment": "KORUS", 7 | "cruise": "KR_2016", 8 | "platform": "Onnuri", 9 | "documents": "KORUS_SOLARTRACKER_Ancillary.sb", 10 | "instrument_manufacturer": "Satlantic", 11 | "instrument_model": "HyperSAS", 12 | "calibration_date": "20160203", 13 | "calibration_files": "SAS045_20160203.sip,HSE488B.cal,.DS_Store,HSL386B.cal,SATPYR.tdf,HLD386B.cal,SATMSG.tdf,HED488B.cal,IRP3397A.cal,SATTHS0045A.tdf,HLD385B.cal,HSL385B.cal,SATNAV0001A.tdf,GPRMC_NMEA0183v3.01.tdf", 14 | "data_type": "above_water", 15 | "data_status": "preliminary", 16 | "water_depth": "NA", 17 | "measurement_depth": "0", 18 | "cloud_percent": "NA", 19 | "wave_height": "NA", 20 | "secchi_depth": "NA", 21 | "wind_speed": "NA", 22 | "station": "", 23 | "data_file_name": "", 24 | "original_file_name": "", 25 | "start_date": "", 26 | "end_date": "", 27 | "start_time": "", 28 | "end_time": "", 29 | "north_latitude": "", 30 | "south_latitude": "", 31 | "east_longitude": "", 32 | "west_longitude": "", 33 | "nadir": "40", 34 | "rho_correction": "Z17", 35 | "NIR_residual_correction": "MA95", 36 | "BRDF_correction": "NoBRDF", 37 | "comments": "! HyperInSPACE vers = 1.2.13\n! HyperInSPACE Config = sample_SEABIRD_SOLARTRACKER.cfg\n! Rotator Home Angle = 0.0\n! Rotator Delay = 2.0\n! Pitch/Roll Filter = On\n! Max Pitch/Roll = 5.0\n! Rotator Min/Max Filter = On\n! Rotator Min = -20.0\n! Rotator Max = 45.0\n! Rel Azimuth Filter = On\n! Rel Azimuth Min = 90.0\n! Rel Azimuth Max = 135.0\n! Deglitch Filter = On\n! ES Dark Window = 11\n! ES Light Window = 5\n! ES Dark Sigma = 3.2\n! ES Light Sigma = 2.3\n! LI Dark Window = 11\n! LI Light Window = 5\n! LI Dark Sigma = 3.3\n! LI Light Sigma = 3.0\n! LT Dark Window = 11\n! LT Light Window = 13\n! LT Dark Sigma = 3.2\n! LT Light Sigma = 2.7\n! FRM Pathway = Non-FRM_Class-based\n! Wavelength Interp Int = 3.3\n! Max Wind = 10.0\n! Min SZA = 20.0\n! Max SZA = 60.0\n! Spectral Filter = On\n! Filter Sigma Es = 5.0\n! Filter Sigma Li = 8.0\n! Filter Sigma Lt = 3.0\n! Meteorological Filter = On\n! Cloud Flag = 1.0\n! Es Flag = 2.0\n! Dawn/Dusk Flag = 1.0\n! Rain/Humidity Flag = 1.095\n! Ensemble Interval = 300\n! Percent Lt Filter = On\n! Percent Light = 10.0\n! Remove Negatives = On", 38 | "other_comments": "!\n! NASA FSG SolarTracker aboard the RV Onnuri, South Korean waters\n! Combined ancillary data from ship data and field logs on the RV Onnuri\n! Station names are NASA FSG conventions and do not agree with KIOST, UNH, UMass, etc.\n! \n! Home angle: 0, Min/Max Az: -20/45, Height: ~ 8-9 m\n!", 39 | "missing": -9999, 40 | "delimiter": "comma" 41 | } -------------------------------------------------------------------------------- /Config/sample_SEABIRD_SOLARTRACKER_Calibration/GPRMC_NMEA0183v3.01.tdf: -------------------------------------------------------------------------------- 1 | ######################################################################################### 2 | # Telemetry Definition File: 3 | # 4 | # Type: $GPRMC sentences (NMEA 0183 standard version 3.01) 5 | # Description: Recommended Minimum Specific GPS/Transit Data 6 | # Version: NMEA 0183 standard, version 3.01 7 | # 8 | # Notes: 9 | # Version 3.01 differs from version 2.30 in that the Mode field is absent 10 | # 11 | # Creation Date: June 30, 2009 12 | # Author: Scott Feener 13 | # 14 | # Template History: 15 | # 2009-06-30, SF: Template created 16 | # 17 | ########################################################################################## 18 | 19 | 20 | VLF_INSTRUMENT $GPRMC '' 6 AS 0 NONE 21 | 22 | FIELD NONE ',' 1 AS 0 DELIMITER 23 | UTCPOS NONE '' V AF 0 HHMMSS 24 | 25 | FIELD NONE ',' 1 AS 0 DELIMITER 26 | STATUS NONE '' V AS 0 COUNT 27 | 28 | FIELD NONE ',' 1 AS 0 DELIMITER 29 | LATPOS NONE 'degrees' V AF 0 DDMM 30 | 31 | FIELD NONE ',' 1 AS 0 DELIMITER 32 | LATHEMI NONE '' V AS 0 COUNT 33 | 34 | FIELD NONE ',' 1 AS 0 DELIMITER 35 | LONPOS NONE 'degrees' V AF 0 DDMM 36 | 37 | FIELD NONE ',' 1 AS 0 DELIMITER 38 | LONHEMI NONE '' V AS 0 COUNT 39 | 40 | FIELD NONE ',' 1 AS 0 DELIMITER 41 | SPEED NONE 'knots' V AF 0 COUNT 42 | 43 | FIELD NONE ',' 1 AS 0 DELIMITER 44 | COURSE TRUE 'degrees' V AF 0 COUNT 45 | 46 | FIELD NONE ',' 1 AS 0 DELIMITER 47 | DATE NONE '' V AI 0 DDMMYY 48 | 49 | FIELD NONE ',' 1 AS 0 DELIMITER 50 | MAGVAR NONE 'degrees' V AF 0 COUNT 51 | 52 | FIELD NONE ',' 1 AS 0 DELIMITER 53 | MAGHEMI NONE '' V AS 0 COUNT 54 | 55 | FIELD NONE '*' 1 AS 0 DELIMITER 56 | NMEA_CHECKSUM NONE '' V AI 0 COUNT 57 | 58 | TERMINATOR NONE '\x0D\x0A' 2 AS 0 DELIMITER 59 | 60 | -------------------------------------------------------------------------------- /Config/sample_SEABIRD_SOLARTRACKER_Calibration/IRP3397A.cal: -------------------------------------------------------------------------------- 1 | # Heitronics IR camera s/n 3397 2 | # 3 | # NASA / Project 2014-7006 4 | 5 | 6 | INSTRUMENT SATIRP '' 6 AS 0 NONE 7 | SN 3397 '' 4 AS 0 NONE 8 | 9 | # Time since commencement of normal operation 10 | TIMER NONE 'sec' 10 AF 0 COUNT 11 | 12 | DELAY SAMPLE 'ms' 2 BS 0 COUNT 13 | 14 | # Heitronics IR camera KT19.85 s/n 3397 15 | # Response time: 1s 16 | # Temperature range: -10C to +50C 17 | # Analog output: 4-20mA 18 | # 4mA = 2319442523 counts, 20mA = 3007343070 counts 19 | T IR 'C' 4 BU 1 POLYF 20 | 8.72219107e-8 2434092614 21 | 22 | 23 | AUX1 NONE '' 4 BU 0 NONE 24 | AUX2 NONE '' 4 BU 0 NONE 25 | AUX3 NONE '' 4 BU 0 NONE 26 | 27 | # 28 | # In-head ancillary measurements 29 | # 30 | VS NONE 'Volts' 2 BU 1 POLYU 31 | 0 0.03 32 | 33 | T PCB 'C' 2 BU 1 POLYU 34 | -50.0 0.5 35 | 36 | # Frame Counter (Data Integrity) 37 | FRAME COUNTER '' 1 BU 0 COUNT 38 | 39 | # Check Sum (Data Integrity) 40 | CHECK SUM '' 1 BU 0 COUNT 41 | 42 | # Frame Terminator 43 | CRLF TERMINATOR '' 2 BU 0 NONE 44 | 45 | -------------------------------------------------------------------------------- /Config/sample_SEABIRD_SOLARTRACKER_Calibration/SAS045_20160203.sip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Config/sample_SEABIRD_SOLARTRACKER_Calibration/SAS045_20160203.sip -------------------------------------------------------------------------------- /Config/sample_SEABIRD_SOLARTRACKER_Calibration/SATMSG.tdf: -------------------------------------------------------------------------------- 1 | ###################################################################################### 2 | # Telemetry Definition File: 3 | # 4 | # Type: SAS Solar Tracker Engineering Message Frames 5 | # Date: Aug 21 2014 6 | # Version: 1 7 | # Format: 8 | # SATMSG| 9 | ####################################################################################### 10 | 11 | # HEADER 12 | VLF_INSTRUMENT SATMSG '' 6 AS 0 NONE 13 | 14 | # Message 15 | FIELD NONE '|' 1 AS 0 DELIMITER 16 | MESSAGE SAS '' V AS 0 COUNT 17 | 18 | # TERMINATOR 19 | TERMINATOR NONE '\x0D\x0A' 2 AS 0 DELIMITER -------------------------------------------------------------------------------- /Config/sample_SEABIRD_SOLARTRACKER_Calibration/SATNAV0001A.tdf: -------------------------------------------------------------------------------- 1 | ###################################################################################### 2 | # Telemetry Definition File: 3 | # 4 | # Type: SAS Solar Tracker Navigation and Orientation Frames 5 | # Date: Aug 21 2014 6 | # Version: 1 7 | # Format: 8 | # SATNAV,sas_hdg,pitch,roll,ship_hdg,sun_azimuth,sun_elevation,rot_pos,hum,vsupply,temp,yydddHHMMSSss 9 | ####################################################################################### 10 | 11 | # HEADER 12 | VLF_INSTRUMENT SATNAV0001 '' 10 AS 0 NONE 13 | 14 | 15 | # INSTRUMENT PACKAGE TRUE HEADING 16 | FIELD NONE ',' 1 AS 0 DELIMITER 17 | HEADING SAS_TRUE 'degrees' V AF 0 COUNT 18 | 19 | # INSTRUMENT PACKAGE PITCH 20 | FIELD NONE ',' 1 AS 0 DELIMITER 21 | PITCH SAS 'degrees' V AF 0 COUNT 22 | 23 | # INSTRUMENT PACKAGE ROLL 24 | FIELD NONE ',' 1 AS 0 DELIMITER 25 | ROLL SAS 'degrees' V AF 0 COUNT 26 | 27 | # SHIP HEADING 28 | FIELD NONE ',' 1 AS 0 DELIMITER 29 | HEADING SHIP_TRUE 'degrees' V AF 0 COUNT 30 | 31 | # SUN AZIMUTH 32 | FIELD NONE ',' 1 AS 0 DELIMITER 33 | AZIMUTH SUN 'degrees' V AF 0 COUNT 34 | 35 | # SUN ELEVATION 36 | FIELD NONE ',' 1 AS 0 DELIMITER 37 | ELEVATION SUN 'degrees' V AF 0 COUNT 38 | 39 | # ROTATOR POSITION 40 | FIELD NONE ',' 1 AS 0 DELIMITER 41 | POSITION SAS 'degrees' V AF 0 COUNT 42 | 43 | # HUMIDITY 44 | FIELD NONE ',' 1 AS 0 DELIMITER 45 | HUMIDITY NONE '%' V AF 0 COUNT 46 | 47 | # CONTROLLER INPUT VOLTAGE 48 | FIELD NONE ',' 1 AS 0 DELIMITER 49 | VOLTAGE SUPPLY 'V' V AF 0 COUNT 50 | 51 | # CONTROLLER TEMPERATURE 52 | FIELD NONE ',' 1 AS 0 DELIMITER 53 | TEMP CONTROLLER 'V' V AF 0 COUNT 54 | 55 | 56 | # Date and Time in ISO 8601:2004 format 57 | FIELD NONE ',' 1 AS 0 DELIMITER 58 | ISO8601 NONE '' V AS 0 COUNT 59 | 60 | # TERMINATOR 61 | TERMINATOR NONE '\x0D\x0A' 2 AS 0 DELIMITER -------------------------------------------------------------------------------- /Config/sample_SEABIRD_SOLARTRACKER_Calibration/SATPYR.tdf: -------------------------------------------------------------------------------- 1 | ###################################################################################### 2 | # Telemetry Definition File: 3 | # 4 | # Type: SAS Solar Tracker Pyrometer Frames 5 | # Date: June 24 2014 6 | # Version: 1 7 | # Format: 8 | # SATPYR[Temperature] 9 | ####################################################################################### 10 | 11 | #Header 12 | INSTRUMENT SATPYR '' 6 AS 0 NONE 13 | 14 | #Temperature 15 | T IR 'Celsius' 4 BF 0 COUNT 16 | 17 | # Frame Terminator 18 | CRLF TERMINATOR '' 2 BU 0 NONE -------------------------------------------------------------------------------- /Config/sample_SEABIRD_SOLARTRACKER_Calibration/SATTHS0045A.tdf: -------------------------------------------------------------------------------- 1 | ######################################################################################### 2 | # Telemetry Definition File: 3 | # 4 | # Type: Satlantic Tilt/Heading Sensor S/N <045> 5 | # Description: Provides tilt and compass heading information 6 | # Project: 2014-7006 / SAS 7 | # Date: April 29, 2014 8 | # User: NASA Goddard Spacem Flight Ctr 9 | # 10 | # Notes: 11 | # Variable length, comma-delimited ASCII data. 12 | # 13 | # 14 | # This tdf file should be named SATTHSxxxx[Rev].tdf, e.g. SATTHS0999A.tdf. 15 | # The [Rev] field is the alphabetical revision of the file. 16 | # 17 | # 18 | # Creation Date: September 3, 2009 19 | # Author: Scott Feener 20 | # 21 | # Template History: 22 | # 2009-09-03, SF: New template created - same fields as previous 23 | # 2013-09-24, SF: Modifications for new compass sensor 24 | # 25 | # File History: 26 | # Revision: Date: User: Notes: 27 | # A 2014-08-21 JJS 28 | # 29 | ######################################################################################### 30 | 31 | # 32 | # Instrument specific header and SN 33 | # Note: replace 'xxxx' with instrument SN 34 | VLF_INSTRUMENT SATTHS0045 '' 10 AS 0 NONE 35 | 36 | # 37 | # Frame Counter 38 | # 39 | FIELD NONE ',' 1 AS 0 DELIMITER 40 | FRAME COUNTER '' V AI 0 COUNT 41 | 42 | # 43 | # Timer field - Time since commencement of normal operation 44 | # 45 | FIELD NONE ',' 1 AS 0 DELIMITER 46 | TIMER NONE 'sec' V AF 0 COUNT 47 | 48 | # 49 | # Compass heading 50 | # 51 | FIELD NONE ',' 1 AS 0 DELIMITER 52 | COMP NONE 'deg' V AF 0 COUNT 53 | 54 | # 55 | # Pitch data 56 | # 57 | FIELD NONE ',' 1 AS 0 DELIMITER 58 | PITCH NONE 'deg' V AF 0 COUNT 59 | 60 | # 61 | # Roll data 62 | # 63 | FIELD NONE ',' 1 AS 0 DELIMITER 64 | ROLL NONE 'deg' V AF 0 COUNT 65 | 66 | 67 | TERMINATOR NONE '\x0D\x0A' 2 AS 0 DELIMITER 68 | -------------------------------------------------------------------------------- /Config/sample_SEABIRD_SOLARTRACKER_anoms.csv: -------------------------------------------------------------------------------- 1 | filename,ESWindowDark,ESWindowLight,ESSigmaDark,ESSigmaLight,ESMinDark,ESMaxDark,ESMinMaxBandDark,ESMinLight,ESMaxLight,ESMinMaxBandLight,LIWindowDark,LIWindowLight,LISigmaDark,LISigmaLight,LIMinDark,LIMaxDark,LIMinMaxBandDark,LIMinLight,LIMaxLight,LIMinMaxBandLight,LTWindowDark,LTWindowLight,LTSigmaDark,LTSigmaLight,LTMinDark,LTMaxDark,LTMinMaxBandDark,LTMinLight,LTMaxLight,LTMinMaxBandLight,Threshold,Comments 2 | SAMPLE_HYPERSAS_SOLARTRACKER_L1AQC,11,5,3.2,3.5,-999,-999,-999,-999,-999,-999,11,5,3.4,3,-999,-999,-999,-999,-999,-999,11,5,3.5,3.2,-999,-999,-999,-999,-999,-999,0,none -------------------------------------------------------------------------------- /Config/sample_SEABIRD_pySAS.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "inDir": "/Users/daurin/GitRepos/HyperCP/Data/Sample_Data/pySAS", 3 | "outDir": "/Users/daurin/GitRepos/HyperCP/Data/Sample_Data/pySAS", 4 | "ancFileDir": "/Users/daurin/GitRepos/HyperCP/Data/Sample_Data/pySAS", 5 | "ancFile": "/Users/daurin/GitRepos/HyperCP/Data/Sample_Data/pySAS/FICE22_pySAS_Ancillary.sb", 6 | "CalibrationFiles": { 7 | "HSL0385_Tartu.cal": { 8 | "enabled": true, 9 | "frameType": "ShutterLight" 10 | }, 11 | "HLD0385_Tartu.cal": { 12 | "enabled": true, 13 | "frameType": "ShutterDark" 14 | }, 15 | "SATMSG.tdf": { 16 | "enabled": true, 17 | "frameType": "Not Required" 18 | }, 19 | "HSE0488_Tartu.cal": { 20 | "enabled": true, 21 | "frameType": "ShutterLight" 22 | }, 23 | "SATTHS0045A.tdf": { 24 | "enabled": true, 25 | "frameType": "Not Required" 26 | }, 27 | "UMTWR_v0.tdf": { 28 | "enabled": true, 29 | "frameType": "Not Required" 30 | }, 31 | "HED0488_Tartu.cal": { 32 | "enabled": true, 33 | "frameType": "ShutterDark" 34 | }, 35 | "HSL0386_Tartu.cal": { 36 | "enabled": true, 37 | "frameType": "ShutterLight" 38 | }, 39 | "GPRMC_NMEA0183v3.01.tdf": { 40 | "enabled": true, 41 | "frameType": "Not Required" 42 | }, 43 | "HLD0386_Tartu.cal": { 44 | "enabled": true, 45 | "frameType": "ShutterDark" 46 | } 47 | }, 48 | "SensorType": "SeaBird", 49 | "fL1aUTCOffset": 0.0, 50 | "bL1aCleanSZA": 1, 51 | "fL1aCleanSZAMax": 70.0, 52 | "bL1aqcSunTracker": 1, 53 | "bL1aqcCleanPitchRoll": 1, 54 | "fL1aqcPitchRollPitch": 5.0, 55 | "fL1aqcPitchRollRoll": 5.0, 56 | "fL1aqcRotatorHomeAngle": 0.0, 57 | "bL1aqcRotatorDelay": 1, 58 | "fL1aqcRotatorDelay": 2.0, 59 | "bL1aqcRotatorAngle": 1, 60 | "fL1aqcRotatorAngleMin": -126.0, 61 | "fL1aqcRotatorAngleMax": 42.0, 62 | "bL1aqcCleanSunAngle": 1, 63 | "fL1aqcSunAngleMin": 90.0, 64 | "fL1aqcSunAngleMax": 135.0, 65 | "bL1aqcDeglitch": 1, 66 | "fL1aqcESWindowDark": 11, 67 | "fL1aqcESWindowLight": 5, 68 | "fL1aqcESSigmaDark": 3.2, 69 | "fL1aqcESSigmaLight": 2.3, 70 | "fL1aqcLIWindowDark": 11, 71 | "fL1aqcLIWindowLight": 5, 72 | "fL1aqcLISigmaDark": 3.3, 73 | "fL1aqcLISigmaLight": 3.0, 74 | "fL1aqcLTWindowDark": 11, 75 | "fL1aqcLTWindowLight": 13, 76 | "fL1aqcLTSigmaDark": 3.2, 77 | "fL1aqcLTSigmaLight": 2.7, 78 | "bL1aqcThreshold": 0, 79 | "fL1aqcESMinDark": null, 80 | "fL1aqcESMinLight": null, 81 | "fL1aqcESMaxDark": null, 82 | "fL1aqcESMaxLight": null, 83 | "fL1aqcESMinMaxBandDark": null, 84 | "fL1aqcESMinMaxBandLight": null, 85 | "fL1aqcLIMinDark": null, 86 | "fL1aqcLIMinLight": null, 87 | "fL1aqcLIMaxDark": null, 88 | "fL1aqcLIMaxLight": null, 89 | "fL1aqcLIMinMaxBandDark": null, 90 | "fL1aqcLIMinMaxBandLight": null, 91 | "fL1aqcLTMinDark": null, 92 | "fL1aqcLTMinLight": null, 93 | "fL1aqcLTMaxDark": null, 94 | "fL1aqcLTMaxLight": null, 95 | "fL1aqcLTMinMaxBandDark": null, 96 | "fL1aqcLTMinMaxBandLight": null, 97 | "fL1aqcAnomalyStep": 20, 98 | "bL1bGetAnc": 2, 99 | "fL1bDefaultWindSpeed": 5.0, 100 | "fL1bDefaultAOD": 0.2, 101 | "fL1bDefaultSalt": 38.0, 102 | "fL1bDefaultSST": 28.0, 103 | "bL1bCal": 3, 104 | "FullCalDir": "Config/sample_SEABIRD_pySAS_Calibration", 105 | "RadCalDir": "Config/sample_SEABIRD_pySAS_Calibration", 106 | "FidRadDB": false, 107 | "fL1bInterpInterval": 3.3, 108 | "bL1bPlotTimeInterp": 0, 109 | "fL1bPlotInterval": 20.0, 110 | "bL1bqcLtUVNIR": 1, 111 | "fL1bqcMaxWind": 10.0, 112 | "fL1bqcSZAMin": 20.0, 113 | "fL1bqcSZAMax": 60.0, 114 | "bL1bqcEnableSpecQualityCheck": 1, 115 | "bL1bqcEnableSpecQualityCheckPlot": 1, 116 | "fL1bqcSpecFilterEs": 5.0, 117 | "fL1bqcSpecFilterLi": 8.0, 118 | "fL1bqcSpecFilterLt": 3.0, 119 | "bL1bqcEnableQualityFlags": 1, 120 | "fL1bqcCloudFlag": 1.0, 121 | "fL1bqcSignificantEsFlag": 2.0, 122 | "fL1bqcDawnDuskFlag": 1.0, 123 | "fL1bqcRainfallHumidityFlag": 1.095, 124 | "fL2SVA": 40, 125 | "bL2Stations": 0, 126 | "fL2TimeInterval": 300, 127 | "bL2EnablePercentLt": 1, 128 | "fL2PercentLt": 10.0, 129 | "fL2RhoSky": 0.0256, 130 | "bL23CRho": 0, 131 | "bL2ZhangRho": 0, 132 | "bL2DefaultRho": 1, 133 | "bL2PerformNIRCorrection": 1, 134 | "bL2SimpleNIRCorrection": 0, 135 | "bL2SimSpecNIRCorrection": 1, 136 | "bL2NegativeSpec": 1, 137 | "bL2BRDF": 1, 138 | "bL2BRDF_fQ": 0, 139 | "bL2BRDF_IOP": 1, 140 | "bL2WeightMODISA": 1, 141 | "bL2WeightSentinel3A": 0, 142 | "bL2WeightVIIRSN": 0, 143 | "bL2WeightMODIST": 0, 144 | "bL2WeightSentinel3B": 0, 145 | "bL2WeightVIIRSJ": 0, 146 | "bL2PlotRrs": 1, 147 | "bL2PlotnLw": 1, 148 | "bL2PlotEs": 1, 149 | "bL2PlotLi": 1, 150 | "bL2PlotLt": 1, 151 | "bL2UncertaintyBreakdownPlot": 1, 152 | "seaBASSHeaderFileName": "sample_SEABIRD_pySAS.hdr", 153 | "bL2SaveSeaBASS": 1, 154 | "bL2WriteReport": 1, 155 | "bL2Prodoc3m": 1, 156 | "bL2Prodkd490": 0, 157 | "bL2Prodpic": 0, 158 | "bL2Prodpoc": 0, 159 | "bL2Prodipar": 0, 160 | "bL2Prodavw": 1, 161 | "bL2Prodqwip": 1, 162 | "bL2ProdweiQA": 0, 163 | "bL2Prodgocad": 0, 164 | "bL2Prodag": 0, 165 | "bL2ProdSg": 0, 166 | "bL2ProdDOC": 0, 167 | "bL2Prodgiop": 0, 168 | "bL2ProdaGiop": 0, 169 | "bL2ProdadgGiop": 0, 170 | "bL2ProdadgSGiop": 0, 171 | "bL2ProdaphGiop": 0, 172 | "bL2ProdaphSGiop": 0, 173 | "bL2ProdbbGiop": 0, 174 | "bL2ProdbbpGiop": 0, 175 | "bL2ProdbbpSGiop": 0, 176 | "bL2Prodqaa": 1, 177 | "bL2ProdaQaa": 0, 178 | "bL2ProdadgQaa": 1, 179 | "bL2ProdaphQaa": 0, 180 | "bL2ProdbQaa": 0, 181 | "bL2ProdbbQaa": 0, 182 | "bL2ProdbbpQaa": 1, 183 | "bL2ProdcQaa": 0 184 | } -------------------------------------------------------------------------------- /Config/sample_SEABIRD_pySAS.hdr: -------------------------------------------------------------------------------- 1 | { 2 | "version": "R1", 3 | "investigators": "Dirk_Aurin", 4 | "affiliations": "NASA_GSFC", 5 | "contact": "dirk.a.aurin@nasa.gov", 6 | "experiment": "FRM4SOC2", 7 | "cruise": "FICE22", 8 | "platform": "AAOT", 9 | "documents": "FICE22_pySAS_Ancillary.sb", 10 | "instrument_manufacturer": "Sea-Bird", 11 | "instrument_model": "HyperSAS", 12 | "calibration_date": "20221015", 13 | "calibration_files": "HSL0385_Tartu.cal,.DS_Store,HLD0385_Tartu.cal,SAS045_20220606.sip,SATMSG.tdf,HSE0488_Tartu.cal,SATTHS0045A.tdf,UMTWR_v0.tdf,HED0488_Tartu.cal,HSL0386_Tartu.cal,GPRMC_NMEA0183v3.01.tdf,HLD0386_Tartu.cal", 14 | "data_type": "above_water", 15 | "data_status": "preliminary", 16 | "water_depth": "NA", 17 | "measurement_depth": "0", 18 | "cloud_percent": "NA", 19 | "wave_height": "NA", 20 | "secchi_depth": "NA", 21 | "wind_speed": "", 22 | "station": "", 23 | "data_file_name": "", 24 | "original_file_name": "", 25 | "start_date": "", 26 | "end_date": "", 27 | "start_time": "", 28 | "end_time": "", 29 | "north_latitude": "", 30 | "south_latitude": "", 31 | "east_longitude": "", 32 | "west_longitude": "", 33 | "nadir": "40", 34 | "rho_correction": "M99", 35 | "NIR_residual_correction": "R06", 36 | "BRDF_correction": "L11", 37 | "comments": "! HyperInSPACE vers = 1.2.13\n! HyperInSPACE Config = /Users/daurin/GitRepos/HyperCP/Config/sample_SEABIRD_pySAS.cfg\n! Rotator Home Angle = 0.0\n! Rotator Delay = 2.0\n! Pitch/Roll Filter = On\n! Max Pitch/Roll = 5.0\n! Rotator Min/Max Filter = On\n! Rotator Min = -126.0\n! Rotator Max = 42.0\n! Rel Azimuth Filter = On\n! Rel Azimuth Min = 90.0\n! Rel Azimuth Max = 135.0\n! Deglitch Filter = On\n! ES Dark Window = 11\n! ES Light Window = 5\n! ES Dark Sigma = 3.2\n! ES Light Sigma = 2.3\n! LI Dark Window = 11\n! LI Light Window = 5\n! LI Dark Sigma = 3.3\n! LI Light Sigma = 3.0\n! LT Dark Window = 11\n! LT Light Window = 13\n! LT Dark Sigma = 3.2\n! LT Light Sigma = 2.7\n! FRM Pathway = FRM-Full-Characterization\n! Wavelength Interp Int = 3.3\n! Max Wind = 10.0\n! Min SZA = 20.0\n! Max SZA = 60.0\n! Spectral Filter = On\n! Filter Sigma Es = 5.0\n! Filter Sigma Li = 8.0\n! Filter Sigma Lt = 3.0\n! Meteorological Filter = On\n! Cloud Flag = 1.0\n! Es Flag = 2.0\n! Dawn/Dusk Flag = 1.0\n! Rain/Humidity Flag = 1.095\n! Ensemble Interval = 300\n! Percent Lt Filter = On\n! Percent Light = 10.0\n! Remove Negatives = On", 38 | "other_comments": "!\n! COMMENTS\n!\n! FRM4SOC-2 Field InterComparison Experiment (FICE)\n! July 11 - 21, 2022\n! Acqua Alta Oceanographic Tower (AAOT), CNR-ISMAR\n!\n! Ancillary data from: % https://www.comune.venezia.it/content/3-piattaforma-ISMAR-CNR\n! and field notes. relAz refers to target relative azimuth in pySAS.\n!\n! Home", 39 | "missing": -9999, 40 | "delimiter": "comma" 41 | } -------------------------------------------------------------------------------- /Config/sample_SEABIRD_pySAS_Calibration/GPRMC_NMEA0183v3.01.tdf: -------------------------------------------------------------------------------- 1 | ######################################################################################### 2 | # Telemetry Definition File: 3 | # 4 | # Type: $GPRMC sentences (NMEA 0183 standard version 3.01) 5 | # Description: Recommended Minimum Specific GPS/Transit Data 6 | # Version: NMEA 0183 standard, version 3.01 7 | # 8 | # Notes: 9 | # Version 3.01 differs from version 2.30 in that the Mode field is absent 10 | # 11 | # Creation Date: June 30, 2009 12 | # Author: Scott Feener 13 | # 14 | # Template History: 15 | # 2009-06-30, SF: Template created 16 | # 17 | ########################################################################################## 18 | 19 | 20 | VLF_INSTRUMENT $GPRMC '' 6 AS 0 NONE 21 | 22 | FIELD NONE ',' 1 AS 0 DELIMITER 23 | UTCPOS NONE '' V AF 0 HHMMSS 24 | 25 | FIELD NONE ',' 1 AS 0 DELIMITER 26 | STATUS NONE '' V AS 0 COUNT 27 | 28 | FIELD NONE ',' 1 AS 0 DELIMITER 29 | LATPOS NONE 'degrees' V AF 0 DDMM 30 | 31 | FIELD NONE ',' 1 AS 0 DELIMITER 32 | LATHEMI NONE '' V AS 0 COUNT 33 | 34 | FIELD NONE ',' 1 AS 0 DELIMITER 35 | LONPOS NONE 'degrees' V AF 0 DDMM 36 | 37 | FIELD NONE ',' 1 AS 0 DELIMITER 38 | LONHEMI NONE '' V AS 0 COUNT 39 | 40 | FIELD NONE ',' 1 AS 0 DELIMITER 41 | SPEED NONE 'knots' V AF 0 COUNT 42 | 43 | FIELD NONE ',' 1 AS 0 DELIMITER 44 | COURSE TRUE 'degrees' V AF 0 COUNT 45 | 46 | FIELD NONE ',' 1 AS 0 DELIMITER 47 | DATE NONE '' V AI 0 DDMMYY 48 | 49 | FIELD NONE ',' 1 AS 0 DELIMITER 50 | MAGVAR NONE 'degrees' V AF 0 COUNT 51 | 52 | FIELD NONE ',' 1 AS 0 DELIMITER 53 | MAGHEMI NONE '' V AS 0 COUNT 54 | 55 | FIELD NONE '*' 1 AS 0 DELIMITER 56 | NMEA_CHECKSUM NONE '' V AI 0 COUNT 57 | 58 | TERMINATOR NONE '\x0D\x0A' 2 AS 0 DELIMITER 59 | 60 | -------------------------------------------------------------------------------- /Config/sample_SEABIRD_pySAS_Calibration/SAS045_20220606.sip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Config/sample_SEABIRD_pySAS_Calibration/SAS045_20220606.sip -------------------------------------------------------------------------------- /Config/sample_SEABIRD_pySAS_Calibration/SATMSG.tdf: -------------------------------------------------------------------------------- 1 | ###################################################################################### 2 | # Telemetry Definition File: 3 | # 4 | # Type: SAS Solar Tracker Engineering Message Frames 5 | # Date: Aug 21 2014 6 | # Version: 1 7 | # Format: 8 | # SATMSG| 9 | ####################################################################################### 10 | 11 | # HEADER 12 | VLF_INSTRUMENT SATMSG '' 6 AS 0 NONE 13 | 14 | # Message 15 | FIELD NONE '|' 1 AS 0 DELIMITER 16 | MESSAGE SAS '' V AS 0 COUNT 17 | 18 | # TERMINATOR 19 | TERMINATOR NONE '\x0D\x0A' 2 AS 0 DELIMITER -------------------------------------------------------------------------------- /Config/sample_SEABIRD_pySAS_Calibration/SATTHS0045A.tdf: -------------------------------------------------------------------------------- 1 | ######################################################################################### 2 | # Telemetry Definition File: 3 | # 4 | # Type: Satlantic Tilt/Heading Sensor S/N <045> 5 | # Description: Provides tilt and compass heading information 6 | # Project: 2014-7006 / SAS 7 | # Date: April 29, 2014 8 | # User: NASA Goddard Spacem Flight Ctr 9 | # 10 | # Notes: 11 | # Variable length, comma-delimited ASCII data. 12 | # 13 | # 14 | # This tdf file should be named SATTHSxxxx[Rev].tdf, e.g. SATTHS0999A.tdf. 15 | # The [Rev] field is the alphabetical revision of the file. 16 | # 17 | # 18 | # Creation Date: September 3, 2009 19 | # Author: Scott Feener 20 | # 21 | # Template History: 22 | # 2009-09-03, SF: New template created - same fields as previous 23 | # 2013-09-24, SF: Modifications for new compass sensor 24 | # 25 | # File History: 26 | # Revision: Date: User: Notes: 27 | # A 2014-08-21 JJS 28 | # 29 | ######################################################################################### 30 | 31 | # 32 | # Instrument specific header and SN 33 | # Note: replace 'xxxx' with instrument SN 34 | VLF_INSTRUMENT SATTHS0045 '' 10 AS 0 NONE 35 | 36 | # 37 | # Frame Counter 38 | # 39 | FIELD NONE ',' 1 AS 0 DELIMITER 40 | FRAME COUNTER '' V AI 0 COUNT 41 | 42 | # 43 | # Timer field - Time since commencement of normal operation 44 | # 45 | FIELD NONE ',' 1 AS 0 DELIMITER 46 | TIMER NONE 'sec' V AF 0 COUNT 47 | 48 | # 49 | # Compass heading 50 | # 51 | FIELD NONE ',' 1 AS 0 DELIMITER 52 | COMP NONE 'deg' V AF 0 COUNT 53 | 54 | # 55 | # Pitch data 56 | # 57 | FIELD NONE ',' 1 AS 0 DELIMITER 58 | PITCH NONE 'deg' V AF 0 COUNT 59 | 60 | # 61 | # Roll data 62 | # 63 | FIELD NONE ',' 1 AS 0 DELIMITER 64 | ROLL NONE 'deg' V AF 0 COUNT 65 | 66 | 67 | TERMINATOR NONE '\x0D\x0A' 2 AS 0 DELIMITER 68 | -------------------------------------------------------------------------------- /Config/sample_SEABIRD_pySAS_Calibration/UMTWR_v0.tdf: -------------------------------------------------------------------------------- 1 | ###################################################################################### 2 | # Telemetry Definition File: 3 | # 4 | # Type: UMTWR sentences 5 | # Descritption: University of Maine instrument tracker tower, frames definining the orientation 6 | # Version: 0 7 | # 8 | # Format: 9 | # UMTWR,heading_sas,heading_ship,heading_accuracy_ship,heading_motion,heading_accuracy_motion,position_tower,status_tower,azimuth_sun,elevation_sun 10 | # 11 | # Creation Date: Feb 4, 2021 12 | # Author: Nils Haentjens 13 | # 14 | # History: 15 | # 2021-02-04: Creation of file 16 | ####################################################################################### 17 | 18 | # HEADER 19 | VLF_INSTRUMENT UMTWR '' 5 AS 0 NONE 20 | 21 | # INSTRUMENT PACKAGE TRUE HEADING 22 | FIELD NONE ',' 1 AS 0 DELIMITER 23 | HEADING SAS 'deg' V AF 0 COUNT 24 | 25 | # SHIP HEADING 26 | FIELD NONE ',' 1 AS 0 DELIMITER 27 | HEADING SHIP 'deg' V AF 0 COUNT 28 | 29 | # SHIP HEADING ACCURACY 30 | FIELD NONE ',' 1 AS 0 DELIMITER 31 | HDGACC SHIP 'deg' V AF 0 COUNT 32 | 33 | # MOTION HEADING 34 | FIELD NONE ',' 1 AS 0 DELIMITER 35 | HEADING MOTION 'deg' V AF 0 COUNT 36 | 37 | # MOTION HEADING ACCURACY 38 | FIELD NONE ',' 1 AS 0 DELIMITER 39 | HDGACC MOTION 'deg' V AF 0 COUNT 40 | 41 | # INDEXING TABLE POSITION (RELATIVE TO NEUTRAL POSITION) 42 | FIELD NONE ',' 1 AS 0 DELIMITER 43 | POSITION SAS 'deg' V AF 0 COUNT 44 | 45 | # INDEXING TABLE STATUS (S: STALLED, O: OPERATING) 46 | FIELD NONE ',' 1 AS 0 DELIMITER 47 | STATUS NONE '' V AS 0 COUNT 48 | 49 | # SUN AZIMUTH 50 | FIELD NONE ',' 1 AS 0 DELIMITER 51 | AZIMUTH SUN 'deg' V AF 0 COUNT 52 | 53 | # SUN ELEVATION 54 | FIELD NONE ',' 1 AS 0 DELIMITER 55 | ELEVATION SUN 'deg' V AF 0 COUNT 56 | 57 | # TERMINATOR 58 | TERMINATOR NONE '\x0D\x0A' 2 AS 0 DELIMITER -------------------------------------------------------------------------------- /Config/sample_SEABIRD_pySAS_anoms.csv: -------------------------------------------------------------------------------- 1 | filename,ESWindowDark,ESWindowLight,ESSigmaDark,ESSigmaLight,ESMinDark,ESMaxDark,ESMinMaxBandDark,ESMinLight,ESMaxLight,ESMinMaxBandLight,LIWindowDark,LIWindowLight,LISigmaDark,LISigmaLight,LIMinDark,LIMaxDark,LIMinMaxBandDark,LIMinLight,LIMaxLight,LIMinMaxBandLight,LTWindowDark,LTWindowLight,LTSigmaDark,LTSigmaLight,LTMinDark,LTMaxDark,LTMinMaxBandDark,LTMinLight,LTMaxLight,LTMinMaxBandLight,Threshold,Comments 2 | FRM4SOC2_FICE22_NASA_20220719_080000_L1AQC,11,5,3,2.3,-999,-999,-999,-999,-999,-999,11,5,3,2.9,-999,-999,-999,-999,-999,-999,11,5,3.5,2.9,-999,-999,-999,-999,-999,-999,0,none -------------------------------------------------------------------------------- /Config/sample_TRIOS_NOTRACKER.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "inDir": "/Users/daurin/GitRepos/HyperCP/Data/Sample_Data/Manual_TriOS", 3 | "outDir": "/Users/daurin/GitRepos/HyperCP/Data/Sample_Data/Manual_TriOS", 4 | "ancFileDir": "./Data/Sample_Data", 5 | "ancFile": "/Users/daurin/GitRepos/HyperCP/Data/Sample_Data/Manual_TriOS/FICE22_TriOS_Ancillary.sb", 6 | "CalibrationFiles": { 7 | "SAM_8329.ini": { 8 | "enabled": true, 9 | "frameType": "ES" 10 | }, 11 | "SAM_8166.ini": { 12 | "enabled": true, 13 | "frameType": "LI" 14 | }, 15 | "SAM_8595.ini": { 16 | "enabled": true, 17 | "frameType": "LT" 18 | } 19 | }, 20 | "SensorType": "TriOS", 21 | "fL1aUTCOffset": 0.0, 22 | "bL1aCleanSZA": 1, 23 | "fL1aCleanSZAMax": 70.0, 24 | "bL1aqcSunTracker": 0, 25 | "bL1aqcCleanPitchRoll": 0, 26 | "fL1aqcPitchRollPitch": 5.0, 27 | "fL1aqcPitchRollRoll": 5.0, 28 | "fL1aqcRotatorHomeAngle": 0.0, 29 | "bL1aqcRotatorDelay": 0, 30 | "fL1aqcRotatorDelay": 2.0, 31 | "bL1aqcRotatorAngle": 0, 32 | "fL1aqcRotatorAngleMin": -40.0, 33 | "fL1aqcRotatorAngleMax": 40.0, 34 | "bL1aqcCleanSunAngle": 1, 35 | "fL1aqcSunAngleMin": 90.0, 36 | "fL1aqcSunAngleMax": 135.0, 37 | "bL1aqcDeglitch": 0, 38 | "fL1aqcESWindowDark": 11, 39 | "fL1aqcESWindowLight": 5, 40 | "fL1aqcESSigmaDark": 3.2, 41 | "fL1aqcESSigmaLight": 2.3, 42 | "fL1aqcLIWindowDark": 11, 43 | "fL1aqcLIWindowLight": 5, 44 | "fL1aqcLISigmaDark": 3.3, 45 | "fL1aqcLISigmaLight": 3.0, 46 | "fL1aqcLTWindowDark": 11, 47 | "fL1aqcLTWindowLight": 13, 48 | "fL1aqcLTSigmaDark": 3.2, 49 | "fL1aqcLTSigmaLight": 2.7, 50 | "bL1aqcThreshold": 0, 51 | "fL1aqcESMinDark": null, 52 | "fL1aqcESMinLight": null, 53 | "fL1aqcESMaxDark": null, 54 | "fL1aqcESMaxLight": null, 55 | "fL1aqcESMinMaxBandDark": null, 56 | "fL1aqcESMinMaxBandLight": null, 57 | "fL1aqcLIMinDark": null, 58 | "fL1aqcLIMinLight": null, 59 | "fL1aqcLIMaxDark": null, 60 | "fL1aqcLIMaxLight": null, 61 | "fL1aqcLIMinMaxBandDark": null, 62 | "fL1aqcLIMinMaxBandLight": null, 63 | "fL1aqcLTMinDark": null, 64 | "fL1aqcLTMinLight": null, 65 | "fL1aqcLTMaxDark": null, 66 | "fL1aqcLTMaxLight": null, 67 | "fL1aqcLTMinMaxBandDark": null, 68 | "fL1aqcLTMinMaxBandLight": null, 69 | "fL1aqcAnomalyStep": 20, 70 | "bL1bGetAnc": 2, 71 | "fL1bDefaultWindSpeed": 5.0, 72 | "fL1bDefaultAOD": 0.2, 73 | "fL1bDefaultSalt": 38.0, 74 | "fL1bDefaultSST": 28.0, 75 | "bL1bCal": 3, 76 | "FullCalDir": "Config/sample_TRIOS_NOTRACKER_Calibration", 77 | "RadCalDir": "Config/sample_TRIOS_NOTRACKER_Calibration", 78 | "FidRadDB": false, 79 | "fL1bInterpInterval": 3.3, 80 | "bL1bPlotTimeInterp": 0, 81 | "fL1bPlotInterval": 20.0, 82 | "bL1bqcLtUVNIR": 1, 83 | "fL1bqcMaxWind": 10.0, 84 | "fL1bqcSZAMin": 20.0, 85 | "fL1bqcSZAMax": 60.0, 86 | "bL1bqcEnableSpecQualityCheck": 1, 87 | "bL1bqcEnableSpecQualityCheckPlot": 1, 88 | "fL1bqcSpecFilterEs": 5.0, 89 | "fL1bqcSpecFilterLi": 8.0, 90 | "fL1bqcSpecFilterLt": 3.0, 91 | "bL1bqcEnableQualityFlags": 1, 92 | "fL1bqcCloudFlag": 1.0, 93 | "fL1bqcSignificantEsFlag": 2.0, 94 | "fL1bqcDawnDuskFlag": 1.0, 95 | "fL1bqcRainfallHumidityFlag": 1.095, 96 | "fL2SVA": 40, 97 | "bL2Stations": 0, 98 | "fL2TimeInterval": 300, 99 | "bL2EnablePercentLt": 1, 100 | "fL2PercentLt": 10.0, 101 | "fL2RhoSky": 0.0256, 102 | "bL23CRho": 0, 103 | "bL2ZhangRho": 0, 104 | "bL2DefaultRho": 1, 105 | "bL2PerformNIRCorrection": 1, 106 | "bL2SimpleNIRCorrection": 0, 107 | "bL2SimSpecNIRCorrection": 1, 108 | "bL2NegativeSpec": 1, 109 | "bL2BRDF": 1, 110 | "bL2BRDF_fQ": 0, 111 | "bL2BRDF_IOP": 0, 112 | "bL2WeightMODISA": 0, 113 | "bL2WeightSentinel3A": 0, 114 | "bL2WeightVIIRSN": 0, 115 | "bL2WeightMODIST": 0, 116 | "bL2WeightSentinel3B": 0, 117 | "bL2WeightVIIRSJ": 0, 118 | "bL2PlotRrs": 1, 119 | "bL2PlotnLw": 1, 120 | "bL2PlotEs": 1, 121 | "bL2PlotLi": 1, 122 | "bL2PlotLt": 1, 123 | "bL2UncertaintyBreakdownPlot": 0, 124 | "seaBASSHeaderFileName": "sample_TRIOS_NOTRACKER.hdr", 125 | "bL2SaveSeaBASS": 0, 126 | "bL2WriteReport": 0, 127 | "bL2Prodoc3m": 0, 128 | "bL2Prodkd490": 0, 129 | "bL2Prodpic": 0, 130 | "bL2Prodpoc": 0, 131 | "bL2Prodipar": 0, 132 | "bL2Prodavw": 0, 133 | "bL2Prodqwip": 0, 134 | "bL2ProdweiQA": 0, 135 | "bL2Prodgocad": 0, 136 | "bL2Prodag": 0, 137 | "bL2ProdSg": 0, 138 | "bL2ProdDOC": 0, 139 | "bL2Prodgiop": 0, 140 | "bL2ProdaGiop": 0, 141 | "bL2ProdadgGiop": 0, 142 | "bL2ProdadgSGiop": 0, 143 | "bL2ProdaphGiop": 0, 144 | "bL2ProdaphSGiop": 0, 145 | "bL2ProdbbGiop": 0, 146 | "bL2ProdbbpGiop": 0, 147 | "bL2ProdbbpSGiop": 0, 148 | "bL2Prodqaa": 0, 149 | "bL2ProdaQaa": 0, 150 | "bL2ProdadgQaa": 0, 151 | "bL2ProdaphQaa": 0, 152 | "bL2ProdbQaa": 0, 153 | "bL2ProdbbQaa": 0, 154 | "bL2ProdbbpQaa": 0, 155 | "bL2ProdcQaa": 0 156 | } -------------------------------------------------------------------------------- /Config/sample_TRIOS_NOTRACKER.hdr: -------------------------------------------------------------------------------- 1 | { 2 | "version": "R1", 3 | "investigators": "SherlockHolmes,JohnWatson", 4 | "affiliations": "221bBakerStr", 5 | "contact": "john.h.watson@bakerst.org", 6 | "experiment": "StudyInScarlet", 7 | "cruise": "BrixtonRoad", 8 | "platform": "Brougham", 9 | "documents": "README.md", 10 | "instrument_manufacturer": "TriOS", 11 | "instrument_model": "RAMSES", 12 | "calibration_date": "20220627", 13 | "calibration_files": "Back_SAM_8166.dat,Cal_SAM_8166.dat,SAM_8329.ini,Back_SAM_8329.dat,Cal_SAM_8329.dat,SAM_8166.ini,SAM_8595.ini,Back_SAM_8595.dat,Cal_SAM_8595.dat", 14 | "data_type": "above_water", 15 | "data_status": "preliminary", 16 | "water_depth": "NA", 17 | "measurement_depth": "0", 18 | "cloud_percent": "NA", 19 | "wave_height": "NA", 20 | "secchi_depth": "NA", 21 | "wind_speed": "NA", 22 | "station": "", 23 | "data_file_name": "", 24 | "original_file_name": "", 25 | "start_date": "", 26 | "end_date": "", 27 | "start_time": "", 28 | "end_time": "", 29 | "north_latitude": "", 30 | "south_latitude": "", 31 | "east_longitude": "", 32 | "west_longitude": "", 33 | "nadir": "40", 34 | "rho_correction": "M99", 35 | "NIR_residual_correction": "R06", 36 | "BRDF_correction": "NoBRDF", 37 | "comments": "! HyperInSPACE vers = 1.2.13\n! HyperInSPACE Config = /Users/daurin/GitRepos/HyperCP/Config/sample_TriOS_NOTRACKER.cfg\n! Rotator Home Angle = 0.0\n! Rotator Delay = 2.0\n! Pitch/Roll Filter = Off\n! Max Pitch/Roll = 5.0\n! Rotator Min/Max Filter = Off\n! Rotator Min = -40.0\n! Rotator Max = 40.0\n! Rel Azimuth Filter = On\n! Rel Azimuth Min = 90.0\n! Rel Azimuth Max = 135.0\n! Deglitch Filter = Off\n! ES Dark Window = 11\n! ES Light Window = 5\n! ES Dark Sigma = 3.2\n! ES Light Sigma = 2.3\n! LI Dark Window = 11\n! LI Light Window = 5\n! LI Dark Sigma = 3.3\n! LI Light Sigma = 3.0\n! LT Dark Window = 11\n! LT Light Window = 13\n! LT Dark Sigma = 3.2\n! LT Light Sigma = 2.7\n! FRM Pathway = FRM-Full-Characterization\n! Wavelength Interp Int = 3.3\n! Max Wind = 10.0\n! Min SZA = 20.0\n! Max SZA = 60.0\n! Spectral Filter = On\n! Filter Sigma Es = 5.0\n! Filter Sigma Li = 8.0\n! Filter Sigma Lt = 3.0\n! Meteorological Filter = On\n! Cloud Flag = 1.0\n! Es Flag = 2.0\n! Dawn/Dusk Flag = 1.0\n! Rain/Humidity Flag = 1.095\n! Ensemble Interval = 300\n! Percent Lt Filter = On\n! Percent Light = 10.0\n! Remove Negatives = On", 38 | "other_comments": "!\n! Sample dataset for TriOS triplet with no GPS or sun tracker.\n! FRM4SOC-2 Field InterComparison Experiment (FICE)\n! July 11 - 21, 2022\n! Acqua Alta Oceanographic Tower (AAOT), CNR-ISMAR\n! \n! RelAz refer to solar-sensor relative azimuth angle.\n! Manually operated TriOS triplet. Height: ~15 m, Tower color: Red/yellow.\n!", 39 | "missing": -9999, 40 | "delimiter": "comma" 41 | } -------------------------------------------------------------------------------- /Config/sample_TRIOS_NOTRACKER_Calibration/SAM_8166.ini: -------------------------------------------------------------------------------- 1 | [Device] 2 | Version = 2 3 | IDDevice = SAM_8166 4 | IDDeviceType = SAM 5 | IDDeviceTypeSub1 = ARC 6 | IDDeviceTypeSub2 = VIS 7 | IDDeviceTypeSub3 = 8 | RecordType = 0 9 | DateTime = 2007-11-02 16:52:01 10 | IDDeviceMaster = 11 | Comment = ARC VIS 12 | 13 | [Attributes] 14 | DarkPixelStart = 237 15 | DarkPixelStop = 254 16 | Firmeware = 2.04 17 | IDDataBack = DLAB_2007-11-02_16-01-20_987_403 18 | IDDataCal = TO_2022-06-27_09-41-12 19 | IDDataCalAQ = DLAB_2007-11-02_16-51-35_756_357 20 | IntegrationTime = 0 21 | Reverse = 0 22 | SerialNo_MMS = 035981 23 | WavelengthRange = 310..1100 24 | c0s = 301.835 25 | c1s = 3.26846 26 | c2s = 0.000358301 27 | c3s = -1.52299e-06 28 | c4s = +0.000000000E+00 29 | [END] of [Attributes] 30 | [END] of [Device] 31 | 32 | -------------------------------------------------------------------------------- /Config/sample_TRIOS_NOTRACKER_Calibration/SAM_8329.ini: -------------------------------------------------------------------------------- 1 | [Device] 2 | Version = 0 3 | IDDevice = SAM_8329 4 | IDDeviceType = SAM 5 | IDDeviceTypeSub1 = ACC-2 6 | IDDeviceTypeSub2 = VIS 7 | IDDeviceTypeSub3 = 8 | RecordType = 0 9 | DateTime = 2022-06-08 14:11:13 10 | IDDeviceMaster = 11 | Comment = ACC-2 VIS 12 | 13 | [Attributes] 14 | CalibrationDate = 15 | DarkPixelStart = 237 16 | DarkPixelStop = 254 17 | Firmware = 2.06 18 | IDDataBack = DLAB_2022-06-08_10-23-53_176_586 19 | IDDataCal = TO_2022-07-08_09-52-36 20 | IDDataCalAQ = DLAB_2022-06-08_14-10-14_747_236 21 | IntegrationTime = 0 22 | Reverse = 0 23 | SerialNo_MMS = 071639 24 | WavelengthRange = 310..1100 25 | c0s = 298.754 26 | c1s = 3.33027 27 | c2s = 0.00033576 28 | c3s = -1.85967e-06 29 | cs = 103232 30 | [END] of [Attributes] 31 | [END] of [Device] 32 | 33 | -------------------------------------------------------------------------------- /Config/sample_TRIOS_NOTRACKER_Calibration/SAM_8595.ini: -------------------------------------------------------------------------------- 1 | [Device] 2 | Version = 0 3 | IDDevice = SAM_8595 4 | IDDeviceType = SAM 5 | IDDeviceTypeSub1 = ARC 6 | IDDeviceTypeSub2 = VIS 7 | IDDeviceTypeSub3 = 8 | RecordType = 0 9 | DateTime = 2018-06-05 10:30:37 10 | IDDeviceMaster = 11 | Comment = ARC VIS 12 | 13 | [Attributes] 14 | DarkPixelStart = 237 15 | DarkPixelStop = 254 16 | Firmware = 2.06 17 | IDDataBack = DLAB_2018-05-31_15-17-33_914_682 18 | IDDataCal = TO_2022-06-27_09-45-19 19 | IDDataCalAQ = DLAB_2018-06-05_10-29-15_188_109 20 | IntegrationTime = 0 21 | Reverse = 0 22 | SerialNo_MMS = 23 | c0s = 298.832 24 | c1s = 3.33083 25 | c2s = 0.000274573 26 | c3s = -1.79948e-06 27 | c4s = +0.000000000E+00 28 | [END] of [Attributes] 29 | [END] of [Device] 30 | 31 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/SeaBird_initial/CP_HyperOCR_E_class_LINEAR_20230406091100.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !NLDATA 3 | # non linearity uncertainty coefficient 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # serial number of the instrument 17 | # type(s): string(255) 18 | [DEVICE] 19 | CLASS_HYPEROCR_IRRADIANCE 20 | 21 | 22 | # band wavelength, non linearity uncertainty (rad k=1), 23 | # type(s): uint8, single, 24 | [CALDATA] 25 | 400 0.02 26 | 443 0.02 27 | 490 0.02 28 | 560 0.02 29 | 665 0.02 30 | 779 0.02 31 | 865 0.02 32 | [END_OF_CALDATA] 33 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/SeaBird_initial/CP_HyperOCR_E_class_POLAR_20230406091100.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !POLDATA 3 | # polarization sensitivity characterization results 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # serial number of the instrument 17 | # type(s): string(255) 18 | [DEVICE] 19 | CLASS_HYPEROCR_IRRADIANCE 20 | 21 | # band wavelength, pol uncertainty (rad k=1), 22 | # type(s): uint8, single, 23 | [CALDATA] 24 | 400 0.02 25 | 443 0.02 26 | 490 0.02 27 | 560 0.02 28 | 665 0.02 29 | 779 0.02 30 | 865 0.02 31 | [END_OF_CALDATA] 32 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/SeaBird_initial/CP_HyperOCR_E_class_STAB_20230406091100.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !STABDATA 3 | # absolute calibration stability uncertainty coefficient 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # serial number of the instrument 17 | # type(s): string(255) 18 | [DEVICE] 19 | CLASS_HYPEROCR_IRRADIANCE 20 | 21 | 22 | # band wavelength, non linearity uncertainty (rad k=1), 23 | # type(s): uint8, single, 24 | [CALDATA] 25 | 400 0.01 26 | 443 0.01 27 | 490 0.01 28 | 560 0.01 29 | 665 0.01 30 | 779 0.01 31 | 865 0.01 32 | [END_OF_CALDATA] 33 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/SeaBird_initial/CP_HyperOCR_E_class_STRAY_20231109135133.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !STRAYDATA 3 | # straylight characterization results 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # calibration date 17 | # type(s): fixed format as shown 18 | [CALDATE] 19 | yyyy-mm-dd hh:mm:ss 20 | 21 | # calibration lab name 22 | # type(s): string(255) 23 | [CALLAB] 24 | Tartu Observatory 25 | 26 | # calibration lab person to contact 27 | # type(s): string(255) 28 | [USER] 29 | Riho Vendt 30 | 31 | # Type of the instrument 32 | # type(s): string(255) 33 | [DEVICE] 34 | CLASS_HYPEROCR_IRRADIANCE 35 | 36 | # pixel no, uncertainty due to uncorrected straylight (% k=1) 37 | # type(s): uint8, single, 38 | [CALDATA] 39 | 0 0 40 | 1 0 41 | 2 0 42 | 3 0 43 | 4 0 44 | 5 0 45 | 6 0 46 | 7 0 47 | 8 0 48 | 9 0 49 | 10 0 50 | 11 0 51 | 12 0 52 | 13 0 53 | 14 2.969587844 54 | 15 2.829583935 55 | 16 2.539755637 56 | 17 2.326274228 57 | 18 2.296995663 58 | 19 2.34441795 59 | 20 2.237498837 60 | 21 2.088941656 61 | 22 1.950126103 62 | 23 1.744674538 63 | 24 1.445934887 64 | 25 1.252589487 65 | 26 1.185218458 66 | 27 1.107410543 67 | 28 1.259301019 68 | 29 1.546178469 69 | 30 1.686495848 70 | 31 1.647038533 71 | 32 1.554117954 72 | 33 1.462158049 73 | 34 1.400564483 74 | 35 1.310753962 75 | 36 1.224339629 76 | 37 1.121646699 77 | 38 1.049005256 78 | 39 1.046908644 79 | 40 1.089231721 80 | 41 1.120387142 81 | 42 1.129221336 82 | 43 1.152124229 83 | 44 1.158365802 84 | 45 1.158386436 85 | 46 1.152255838 86 | 47 1.142743707 87 | 48 1.143832449 88 | 49 1.131236174 89 | 50 1.134122467 90 | 51 1.138605345 91 | 52 1.129104357 92 | 53 1.10910672 93 | 54 1.056092068 94 | 55 1.002338786 95 | 56 0.9725555 96 | 57 0.970260382 97 | 58 0.957607912 98 | 59 0.939684368 99 | 60 0.922305184 100 | 61 0.922379723 101 | 62 0.922218638 102 | 63 0.902977663 103 | 64 0.873761268 104 | 65 0.867237444 105 | 66 0.877808268 106 | 67 0.879474982 107 | 68 0.875601148 108 | 69 0.86095936 109 | 70 0.841225131 110 | 71 0.822459747 111 | 72 0.811573116 112 | 73 0.80794095 113 | 74 0.805016223 114 | 75 0.797507975 115 | 76 0.784055448 116 | 77 0.770325013 117 | 78 0.759343209 118 | 79 0.751362554 119 | 80 0.752272784 120 | 81 0.753173916 121 | 82 0.761372 122 | 83 0.766524116 123 | 84 0.773549756 124 | 85 0.772868668 125 | 86 0.760226966 126 | 87 0.756680172 127 | 88 0.758558929 128 | 89 0.781966882 129 | 90 0.80581406 130 | 91 0.821934133 131 | 92 0.820141009 132 | 93 0.803944964 133 | 94 0.777502247 134 | 95 0.782480016 135 | 96 0.7602137 136 | 97 0.768050593 137 | 98 0.79317337 138 | 99 0.854831907 139 | 100 0.839559866 140 | 101 0.81247321 141 | 102 0.804360522 142 | 103 0.780874437 143 | 104 0.774875807 144 | 105 0.789795303 145 | 106 0.79165003 146 | 107 0.779614469 147 | 108 0.759351035 148 | 109 0.756062613 149 | 110 0.769541302 150 | 111 0.781938154 151 | 112 0.789533507 152 | 113 0.776319087 153 | 114 0.764616596 154 | 115 0.817203712 155 | 116 0.843297678 156 | 117 0.83330696 157 | 118 0.814367938 158 | 119 0.793234525 159 | 120 0.769971632 160 | 121 0.754838884 161 | 122 0.757182417 162 | 123 0.776467634 163 | 124 0.840319286 164 | 125 0.896138482 165 | 126 0.92159315 166 | 127 0.9126061 167 | 128 0.875483588 168 | 129 0.828365124 169 | 130 0.780031426 170 | 131 0.752166841 171 | 132 0.777128782 172 | 133 0.804435008 173 | 134 0.821637781 174 | 135 0.791718698 175 | 136 0.840194285 176 | 137 1.048026738 177 | 138 1.138846555 178 | 139 0.985113704 179 | 140 0.824611997 180 | 141 0.755316337 181 | 142 0.788665017 182 | 143 0.785643302 183 | 144 0.76765411 184 | 145 0.756540912 185 | 146 0.779936873 186 | 147 0.779938322 187 | 148 0.786920266 188 | 149 0.786422668 189 | 150 0.777455853 190 | 151 0.779927962 191 | 152 0.807411193 192 | 153 0.871370987 193 | 154 0.924402055 194 | 155 0.964544085 195 | 156 0.95789429 196 | 157 0.949036361 197 | 158 0.92706837 198 | 159 0.920707064 199 | 160 0.890593371 200 | 161 0.873099625 201 | 162 0.864987904 202 | 163 0.872181138 203 | 164 0.898074838 204 | 165 0.92988113 205 | 166 0.934191622 206 | 167 0.943696249 207 | 168 0.946760777 208 | 169 0.964149723 209 | 170 0.9698229 210 | 171 0.955645886 211 | 172 0.956760048 212 | 173 0.957511998 213 | 174 0.956838048 214 | 175 0.949913393 215 | 176 0.98204388 216 | 177 1.042155512 217 | 178 1.218354457 218 | 179 1.375444669 219 | 180 1.399764967 220 | 181 0 221 | 182 0 222 | 183 0 223 | 184 0 224 | 185 0 225 | 186 0 226 | 187 0 227 | 188 0 228 | 189 0 229 | 190 0 230 | 191 0 231 | 192 0 232 | 193 0 233 | 194 0 234 | 195 0 235 | 196 0 236 | 197 0 237 | 198 0 238 | 199 0 239 | 200 0 240 | 201 0 241 | 202 0 242 | 203 0 243 | 204 0 244 | 205 0 245 | 206 0 246 | 207 0 247 | 208 0 248 | 209 0 249 | 210 0 250 | 211 0 251 | 212 0 252 | 213 0 253 | 214 0 254 | 215 0 255 | 216 0 256 | 217 0 257 | 218 0 258 | 219 0 259 | 220 0 260 | 221 0 261 | 222 0 262 | 223 0 263 | 224 0 264 | 225 0 265 | 226 0 266 | 227 0 267 | 228 0 268 | 229 0 269 | 230 0 270 | 231 0 271 | 232 0 272 | 233 0 273 | 234 0 274 | 235 0 275 | 236 0 276 | 237 0 277 | 238 0 278 | 239 0 279 | 240 0 280 | 241 0 281 | 242 0 282 | 243 0 283 | 244 0 284 | 245 0 285 | 246 0 286 | 247 0 287 | 248 0 288 | 249 0 289 | 250 0 290 | 251 0 291 | 252 0 292 | 253 0 293 | 254 0 294 | [END_OF_CALDATA] 295 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/SeaBird_initial/CP_HyperOCR_LI_class_POLAR_20230406090628.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !POLDATA 3 | # polarization sensitivity characterization results 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # serial number of the instrument 17 | # type(s): string(255) 18 | [DEVICE] 19 | CLASS_HYPEROCR_LI 20 | 21 | # band wavelength, pol uncertainty (rad k=1), 22 | # type(s): uint8, single, 23 | [CALDATA] 24 | 400 0.006 25 | 443 0.006 26 | 490 0.012 27 | 560 0.012 28 | 665 0.024 29 | 779 0.024 30 | 865 0.024 31 | [END_OF_CALDATA] 32 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/SeaBird_initial/CP_HyperOCR_LI_class_STRAY_20231109135133.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !STRAYDATA 3 | # straylight characterization results 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # calibration date 17 | # type(s): fixed format as shown 18 | [CALDATE] 19 | yyyy-mm-dd hh:mm:ss 20 | 21 | # calibration lab name 22 | # type(s): string(255) 23 | [CALLAB] 24 | Tartu Observatory 25 | 26 | # calibration lab person to contact 27 | # type(s): string(255) 28 | [USER] 29 | Riho Vendt 30 | 31 | # Type of the instrument 32 | # type(s): string(255) 33 | [DEVICE] 34 | CLASS_HYPEROCR_LI 35 | 36 | # pixel no, uncertainty due to uncorrected straylight (% k=1) 37 | # type(s): uint8, single, 38 | [CALDATA] 39 | 0 0 40 | 1 0 41 | 2 0 42 | 3 0 43 | 4 0 44 | 5 0 45 | 6 0 46 | 7 0 47 | 8 0 48 | 9 0 49 | 10 0 50 | 11 0 51 | 12 0 52 | 13 0 53 | 14 6.633287314 54 | 15 5.323609937 55 | 16 4.773365111 56 | 17 3.919340852 57 | 18 3.503014198 58 | 19 2.895049322 59 | 20 3.013512394 60 | 21 3.30293962 61 | 22 2.499530802 62 | 23 2.66831947 63 | 24 2.604232748 64 | 25 2.490667643 65 | 26 2.74099064 66 | 27 2.557851852 67 | 28 2.279194262 68 | 29 1.816714883 69 | 30 1.551399178 70 | 31 1.488755365 71 | 32 1.543566104 72 | 33 1.408637148 73 | 34 1.239745376 74 | 35 1.498699048 75 | 36 1.353893641 76 | 37 1.377155956 77 | 38 1.348490487 78 | 39 1.17338774 79 | 40 1.168569825 80 | 41 1.065954012 81 | 42 1.108998426 82 | 43 1.012878018 83 | 44 1.099404668 84 | 45 1.003343927 85 | 46 1.028535989 86 | 47 1.091418803 87 | 48 0.921239259 88 | 49 0.956278527 89 | 50 0.783343017 90 | 51 0.902018664 91 | 52 0.907318166 92 | 53 1.011816913 93 | 54 0.962551855 94 | 55 0.977064761 95 | 56 0.869125653 96 | 57 0.766565742 97 | 58 1.13535999 98 | 59 1.078140445 99 | 60 0.942828233 100 | 61 1.038689087 101 | 62 1.110182528 102 | 63 1.083886623 103 | 64 1.076624442 104 | 65 1.022253449 105 | 66 0.973835369 106 | 67 0.971948275 107 | 68 0.947810698 108 | 69 0.936011462 109 | 70 0.878763864 110 | 71 0.893366718 111 | 72 0.832094495 112 | 73 0.795763288 113 | 74 0.773770528 114 | 75 0.776801448 115 | 76 0.765988449 116 | 77 0.778139912 117 | 78 0.802981254 118 | 79 0.794282882 119 | 80 0.772125988 120 | 81 0.843785483 121 | 82 0.985038535 122 | 83 1.021337648 123 | 84 1.016750565 124 | 85 0.978956166 125 | 86 1.002916136 126 | 87 0.898881813 127 | 88 0.861086674 128 | 89 0.885473622 129 | 90 0.842255225 130 | 91 0.934440805 131 | 92 0.929059269 132 | 93 0.958273615 133 | 94 0.921434799 134 | 95 0.940365295 135 | 96 0.828138732 136 | 97 1.025902445 137 | 98 0.808361802 138 | 99 0.83614644 139 | 100 1.076622748 140 | 101 0.773809145 141 | 102 0.905082356 142 | 103 0.944919574 143 | 104 1.038216735 144 | 105 0.922004077 145 | 106 1.038852646 146 | 107 0.967685171 147 | 108 1.092484896 148 | 109 1.003686996 149 | 110 0.847161583 150 | 111 0.822522014 151 | 112 0.846491522 152 | 113 1.001403406 153 | 114 0.854522026 154 | 115 0.863295754 155 | 116 0.84863229 156 | 117 0.962853116 157 | 118 0.757375262 158 | 119 0.915941714 159 | 120 0.783462655 160 | 121 0.839221632 161 | 122 0.855086511 162 | 123 0.85271682 163 | 124 0.794254625 164 | 125 1.263645681 165 | 126 1.419157534 166 | 127 1.277050108 167 | 128 1.199001291 168 | 129 0.931680862 169 | 130 1.124904263 170 | 131 1.331777504 171 | 132 0.920854907 172 | 133 0.877457215 173 | 134 1.106088369 174 | 135 0.834594608 175 | 136 1.139364052 176 | 137 1.313201706 177 | 138 0.928297537 178 | 139 1.805639311 179 | 140 1.101703338 180 | 141 1.410242476 181 | 142 1.628432543 182 | 143 0.883641188 183 | 144 1.150794947 184 | 145 0.835311007 185 | 146 0.960540597 186 | 147 0.856528892 187 | 148 0.955537195 188 | 149 1.020505011 189 | 150 1.041709134 190 | 151 0.847788164 191 | 152 1.869965445 192 | 153 0.934804228 193 | 154 1.093799408 194 | 155 2.482822568 195 | 156 3.229238776 196 | 157 4.005608272 197 | 158 1.525316037 198 | 159 2.351284716 199 | 160 1.261084123 200 | 161 1.9139165 201 | 162 1.110828328 202 | 163 1.274252266 203 | 164 1.309249856 204 | 165 1.247752393 205 | 166 1.750292419 206 | 167 3.391905031 207 | 168 1.722905013 208 | 169 1.441693367 209 | 170 6.654604423 210 | 171 2.861022781 211 | 172 4.224834597 212 | 173 2.953028017 213 | 174 3.157120386 214 | 175 4.846900576 215 | 176 3.224865112 216 | 177 3.970080808 217 | 178 5.993476436 218 | 179 4.379091126 219 | 180 0 220 | 181 0 221 | 182 0 222 | 183 0 223 | 184 0 224 | 185 0 225 | 186 0 226 | 187 0 227 | 188 0 228 | 189 0 229 | 190 0 230 | 191 0 231 | 192 0 232 | 193 0 233 | 194 0 234 | 195 0 235 | 196 0 236 | 197 0 237 | 198 0 238 | 199 0 239 | 200 0 240 | 201 0 241 | 202 0 242 | 203 0 243 | 204 0 244 | 205 0 245 | 206 0 246 | 207 0 247 | 208 0 248 | 209 0 249 | 210 0 250 | 211 0 251 | 212 0 252 | 213 0 253 | 214 0 254 | 215 0 255 | 216 0 256 | 217 0 257 | 218 0 258 | 219 0 259 | 220 0 260 | 221 0 261 | 222 0 262 | 223 0 263 | 224 0 264 | 225 0 265 | 226 0 266 | 227 0 267 | 228 0 268 | 229 0 269 | 230 0 270 | 231 0 271 | 232 0 272 | 233 0 273 | 234 0 274 | 235 0 275 | 236 0 276 | 237 0 277 | 238 0 278 | 239 0 279 | 240 0 280 | 241 0 281 | 242 0 282 | 243 0 283 | 244 0 284 | 245 0 285 | 246 0 286 | 247 0 287 | 248 0 288 | 249 0 289 | 250 0 290 | 251 0 291 | 252 0 292 | 253 0 293 | 254 0 294 | [END_OF_CALDATA] 295 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/SeaBird_initial/CP_HyperOCR_LT_class_POLAR_20230406090628.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !POLDATA 3 | # polarization sensitivity characterization results 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | 17 | # serial number of the instrument 18 | # type(s): string(255) 19 | [DEVICE] 20 | CLASS_HYPEROCR_LT 21 | 22 | 23 | # band wavelength, pol uncertainty (rad k=1), 24 | # type(s): uint8, single, 25 | [CALDATA] 26 | 400 0.006 27 | 443 0.006 28 | 490 0.006 29 | 560 0.006 30 | 665 0.012 31 | 779 0.012 32 | 865 0.012 33 | [END_OF_CALDATA] 34 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/SeaBird_initial/CP_HyperOCR_LT_class_STRAY_20231109135133.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !STRAYDATA 3 | # straylight characterization results 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # calibration date 17 | # type(s): fixed format as shown 18 | [CALDATE] 19 | yyyy-mm-dd hh:mm:ss 20 | 21 | # calibration lab name 22 | # type(s): string(255) 23 | [CALLAB] 24 | Tartu Observatory 25 | 26 | # calibration lab person to contact 27 | # type(s): string(255) 28 | [USER] 29 | Riho Vendt 30 | 31 | # Type of the instrument 32 | # type(s): string(255) 33 | [DEVICE] 34 | CLASS_HYPEROCR_LT 35 | 36 | # pixel no, uncertainty due to uncorrected straylight (% k=1) 37 | # type(s): uint8, single, 38 | [CALDATA] 39 | 0 0 40 | 1 0 41 | 2 0 42 | 3 0 43 | 4 0 44 | 5 0 45 | 6 0 46 | 7 0 47 | 8 0 48 | 9 0 49 | 10 0 50 | 11 0 51 | 12 0 52 | 13 0 53 | 14 5.889406499 54 | 15 4.662853931 55 | 16 4.146180837 56 | 17 3.195995812 57 | 18 2.748786415 58 | 19 2.186457254 59 | 20 2.411772902 60 | 21 2.601195772 61 | 22 1.799036266 62 | 23 1.984159872 63 | 24 1.884032729 64 | 25 1.70444689 65 | 26 2.059997381 66 | 27 1.925777832 67 | 28 2.16268067 68 | 29 2.249310106 69 | 30 1.882252904 70 | 31 1.790744315 71 | 32 1.808065418 72 | 33 1.658899789 73 | 34 1.485855691 74 | 35 1.738035951 75 | 36 1.366167593 76 | 37 1.102027911 77 | 38 1.045860656 78 | 39 0.849080844 79 | 40 0.839425172 80 | 41 0.786018328 81 | 42 0.779934449 82 | 43 0.830040562 83 | 44 0.788265381 84 | 45 0.769075762 85 | 46 0.774418023 86 | 47 0.80906795 87 | 48 0.764017574 88 | 49 0.879679166 89 | 50 0.830413158 90 | 51 0.820936776 91 | 52 0.76716232 92 | 53 0.852783846 93 | 54 0.812441838 94 | 55 0.796951389 95 | 56 0.783201576 96 | 57 0.853323476 97 | 58 1.116958492 98 | 59 0.986986596 99 | 60 0.912542298 100 | 61 1.037422695 101 | 62 1.065720475 102 | 63 1.051546788 103 | 64 1.127085684 104 | 65 1.043016688 105 | 66 1.104639135 106 | 67 1.134508683 107 | 68 1.114218168 108 | 69 1.150742959 109 | 70 1.089773351 110 | 71 1.078134256 111 | 72 1.107450904 112 | 73 1.122471207 113 | 74 1.122450713 114 | 75 1.06890008 115 | 76 1.067133551 116 | 77 0.998257409 117 | 78 0.991185638 118 | 79 0.967284117 119 | 80 0.917535541 120 | 81 0.938817141 121 | 82 0.822183342 122 | 83 0.852729205 123 | 84 0.825295443 124 | 85 0.785770669 125 | 86 0.782943563 126 | 87 0.766655783 127 | 88 0.80993962 128 | 89 0.888910509 129 | 90 0.958279531 130 | 91 0.957174607 131 | 92 0.936579687 132 | 93 0.919409151 133 | 94 0.875380681 134 | 95 0.848146646 135 | 96 0.817618775 136 | 97 0.809554145 137 | 98 0.814816513 138 | 99 0.833538146 139 | 100 0.813077517 140 | 101 0.760852506 141 | 102 0.753594351 142 | 103 0.754210573 143 | 104 0.752737927 144 | 105 0.780148776 145 | 106 0.772747882 146 | 107 0.752945983 147 | 108 0.958417987 148 | 109 0.952034271 149 | 110 0.792998751 150 | 111 0.851406659 151 | 112 0.842961103 152 | 113 0.809597801 153 | 114 0.79587826 154 | 115 0.819607349 155 | 116 0.828679299 156 | 117 0.830231316 157 | 118 0.832579953 158 | 119 0.823117307 159 | 120 0.851617392 160 | 121 0.82109049 161 | 122 0.887736144 162 | 123 0.771105988 163 | 124 0.938485125 164 | 125 1.38383142 165 | 126 1.525674466 166 | 127 1.603082424 167 | 128 1.559075495 168 | 129 1.422729883 169 | 130 1.46455009 170 | 131 1.466840535 171 | 132 1.243602712 172 | 133 1.200756503 173 | 134 1.255967898 174 | 135 1.115677266 175 | 136 1.456356483 176 | 137 1.881747119 177 | 138 1.823065916 178 | 139 1.949672352 179 | 140 1.20460525 180 | 141 1.202001878 181 | 142 1.337339923 182 | 143 0.845059328 183 | 144 0.921754985 184 | 145 0.791147411 185 | 146 0.792550615 186 | 147 1.029963321 187 | 148 0.84353599 188 | 149 0.890912936 189 | 150 0.759765636 190 | 151 0.865364614 191 | 152 1.626371204 192 | 153 1.426719726 193 | 154 1.506079813 194 | 155 2.562995695 195 | 156 3.007799443 196 | 157 3.431113844 197 | 158 2.147501474 198 | 159 2.936634471 199 | 160 2.30467696 200 | 161 2.602061723 201 | 162 1.201113001 202 | 163 1.77015489 203 | 164 1.127527305 204 | 165 2.323368081 205 | 166 2.576370323 206 | 167 3.880922967 207 | 168 2.619882216 208 | 169 3.240796524 209 | 170 6.30942429 210 | 171 4.908082169 211 | 172 5.644117485 212 | 173 5.198255726 213 | 174 4.878352968 214 | 175 5.997043675 215 | 176 5.258496532 216 | 177 6.395822013 217 | 178 8.381937598 218 | 179 6.970603328 219 | 180 0 220 | 181 0 221 | 182 0 222 | 183 0 223 | 184 0 224 | 185 0 225 | 186 0 226 | 187 0 227 | 188 0 228 | 189 0 229 | 190 0 230 | 191 0 231 | 192 0 232 | 193 0 233 | 194 0 234 | 195 0 235 | 196 0 236 | 197 0 237 | 198 0 238 | 199 0 239 | 200 0 240 | 201 0 241 | 202 0 242 | 203 0 243 | 204 0 244 | 205 0 245 | 206 0 246 | 207 0 247 | 208 0 248 | 209 0 249 | 210 0 250 | 211 0 251 | 212 0 252 | 213 0 253 | 214 0 254 | 215 0 255 | 216 0 256 | 217 0 257 | 218 0 258 | 219 0 259 | 220 0 260 | 221 0 261 | 222 0 262 | 223 0 263 | 224 0 264 | 225 0 265 | 226 0 266 | 227 0 267 | 228 0 268 | 229 0 269 | 230 0 270 | 231 0 271 | 232 0 272 | 233 0 273 | 234 0 274 | 235 0 275 | 236 0 276 | 237 0 277 | 238 0 278 | 239 0 279 | 240 0 280 | 241 0 281 | 242 0 282 | 243 0 283 | 244 0 284 | 245 0 285 | 246 0 286 | 247 0 287 | 248 0 288 | 249 0 289 | 250 0 290 | 251 0 291 | 252 0 292 | 253 0 293 | 254 0 294 | [END_OF_CALDATA] 295 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/SeaBird_initial/CP_HyperOCR_L_class_LINEAR_20230406091100.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !NLDATA 3 | # non linearity uncertainty coefficient 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # serial number of the instrument 17 | # type(s): string(255) 18 | [DEVICE] 19 | CLASS_HYPEROCR_RADIANCE 20 | 21 | # band wavelength, non linearity uncertainty (rad k=1), 22 | # type(s): uint8, single, 23 | [CALDATA] 24 | 400 0.02 25 | 443 0.02 26 | 490 0.02 27 | 560 0.02 28 | 665 0.02 29 | 779 0.02 30 | 865 0.02 31 | [END_OF_CALDATA] 32 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/SeaBird_initial/CP_HyperOCR_L_class_STAB_20230406091100.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !STABDATA 3 | # absolute calibration stability uncertainty coefficientient 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # serial number of the instrument 17 | # type(s): string(255) 18 | [DEVICE] 19 | CLASS_HYPEROCR_RADIANCE 20 | 21 | # band wavelength, non linearity uncertainty (rad k=1), 22 | # type(s): uint8, single, 23 | [CALDATA] 24 | 400 0.01 25 | 443 0.01 26 | 490 0.01 27 | 560 0.01 28 | 665 0.01 29 | 779 0.01 30 | 865 0.01 31 | [END_OF_CALDATA] 32 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/TriOS_initial/CP_RAMSES_E_class_LINEAR_20230406091100.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !NLDATA 3 | # non linearity uncertainty coefficient 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # serial number of the instrument 17 | # type(s): string(255) 18 | [DEVICE] 19 | CLASS_RAMSES_IRRADIANCE 20 | 21 | # band wavelength, non linearity uncertainty (rad k=1), 22 | # type(s): uint8, single, 23 | [CALDATA] 24 | 400 0.02 25 | 443 0.02 26 | 490 0.02 27 | 560 0.02 28 | 665 0.02 29 | 779 0.02 30 | 865 0.02 31 | [END_OF_CALDATA] 32 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/TriOS_initial/CP_RAMSES_E_class_POLAR_20230406090628.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !POLDATA 3 | # polarization sensitivity characterization results 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # serial number of the instrument 17 | # type(s): string(255) 18 | [DEVICE] 19 | CLASS_RAMSES_IRRADIANCE 20 | 21 | # band wavelength, pol uncertainty (rad k=1), 22 | # type(s): uint8, single, 23 | [CALDATA] 24 | 400 0.035 25 | 443 0.035 26 | 490 0.035 27 | 560 0.035 28 | 665 0.035 29 | 779 0.035 30 | 865 0.035 31 | [END_OF_CALDATA] 32 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/TriOS_initial/CP_RAMSES_E_class_STAB_20230406090628.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !STABDATA 3 | # absolute calibration stability uncertainty coefficientient 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # serial number of the instrument 17 | # type(s): string(255) 18 | [DEVICE] 19 | CLASS_RAMSES_IRRADIANCE 20 | 21 | # band wavelength, non linearity uncertainty (rad k=1), 22 | # type(s): uint8, single, 23 | [CALDATA] 24 | 400 0.01 25 | 443 0.01 26 | 490 0.01 27 | 560 0.01 28 | 665 0.01 29 | 779 0.01 30 | 865 0.01 31 | [END_OF_CALDATA] 32 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/TriOS_initial/CP_RAMSES_E_class_STRAY_20231109135133.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !STRAYDATA 3 | # straylight characterization results 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # calibration date 17 | # type(s): fixed format as shown 18 | [CALDATE] 19 | yyyy-mm-dd hh:mm:ss 20 | 21 | # calibration lab name 22 | # type(s): string(255) 23 | [CALLAB] 24 | Tartu Observatory 25 | 26 | # calibration lab person to contact 27 | # type(s): string(255) 28 | [USER] 29 | Riho Vendt 30 | 31 | # Type of the instrument 32 | # type(s): string(255) 33 | [DEVICE] 34 | CLASS_RAMSES_IRRADIANCE 35 | 36 | # pixel no, uncertainty due to uncorrected straylight (% k=1) 37 | # type(s): uint8, single, 38 | [CALDATA] 39 | 0 0 40 | 1 0 41 | 2 0 42 | 3 0 43 | 4 0 44 | 5 0 45 | 6 0 46 | 7 0 47 | 8 0 48 | 9 0 49 | 10 0 50 | 11 0 51 | 12 0 52 | 13 0 53 | 14 2.969587844 54 | 15 2.829583935 55 | 16 2.539755637 56 | 17 2.326274228 57 | 18 2.296995663 58 | 19 2.34441795 59 | 20 2.237498837 60 | 21 2.088941656 61 | 22 1.950126103 62 | 23 1.744674538 63 | 24 1.445934887 64 | 25 1.252589487 65 | 26 1.185218458 66 | 27 1.107410543 67 | 28 1.259301019 68 | 29 1.546178469 69 | 30 1.686495848 70 | 31 1.647038533 71 | 32 1.554117954 72 | 33 1.462158049 73 | 34 1.400564483 74 | 35 1.310753962 75 | 36 1.224339629 76 | 37 1.121646699 77 | 38 1.049005256 78 | 39 1.046908644 79 | 40 1.089231721 80 | 41 1.120387142 81 | 42 1.129221336 82 | 43 1.152124229 83 | 44 1.158365802 84 | 45 1.158386436 85 | 46 1.152255838 86 | 47 1.142743707 87 | 48 1.143832449 88 | 49 1.131236174 89 | 50 1.134122467 90 | 51 1.138605345 91 | 52 1.129104357 92 | 53 1.10910672 93 | 54 1.056092068 94 | 55 1.002338786 95 | 56 0.9725555 96 | 57 0.970260382 97 | 58 0.957607912 98 | 59 0.939684368 99 | 60 0.922305184 100 | 61 0.922379723 101 | 62 0.922218638 102 | 63 0.902977663 103 | 64 0.873761268 104 | 65 0.867237444 105 | 66 0.877808268 106 | 67 0.879474982 107 | 68 0.875601148 108 | 69 0.86095936 109 | 70 0.841225131 110 | 71 0.822459747 111 | 72 0.811573116 112 | 73 0.80794095 113 | 74 0.805016223 114 | 75 0.797507975 115 | 76 0.784055448 116 | 77 0.770325013 117 | 78 0.759343209 118 | 79 0.751362554 119 | 80 0.752272784 120 | 81 0.753173916 121 | 82 0.761372 122 | 83 0.766524116 123 | 84 0.773549756 124 | 85 0.772868668 125 | 86 0.760226966 126 | 87 0.756680172 127 | 88 0.758558929 128 | 89 0.781966882 129 | 90 0.80581406 130 | 91 0.821934133 131 | 92 0.820141009 132 | 93 0.803944964 133 | 94 0.777502247 134 | 95 0.782480016 135 | 96 0.7602137 136 | 97 0.768050593 137 | 98 0.79317337 138 | 99 0.854831907 139 | 100 0.839559866 140 | 101 0.81247321 141 | 102 0.804360522 142 | 103 0.780874437 143 | 104 0.774875807 144 | 105 0.789795303 145 | 106 0.79165003 146 | 107 0.779614469 147 | 108 0.759351035 148 | 109 0.756062613 149 | 110 0.769541302 150 | 111 0.781938154 151 | 112 0.789533507 152 | 113 0.776319087 153 | 114 0.764616596 154 | 115 0.817203712 155 | 116 0.843297678 156 | 117 0.83330696 157 | 118 0.814367938 158 | 119 0.793234525 159 | 120 0.769971632 160 | 121 0.754838884 161 | 122 0.757182417 162 | 123 0.776467634 163 | 124 0.840319286 164 | 125 0.896138482 165 | 126 0.92159315 166 | 127 0.9126061 167 | 128 0.875483588 168 | 129 0.828365124 169 | 130 0.780031426 170 | 131 0.752166841 171 | 132 0.777128782 172 | 133 0.804435008 173 | 134 0.821637781 174 | 135 0.791718698 175 | 136 0.840194285 176 | 137 1.048026738 177 | 138 1.138846555 178 | 139 0.985113704 179 | 140 0.824611997 180 | 141 0.755316337 181 | 142 0.788665017 182 | 143 0.785643302 183 | 144 0.76765411 184 | 145 0.756540912 185 | 146 0.779936873 186 | 147 0.779938322 187 | 148 0.786920266 188 | 149 0.786422668 189 | 150 0.777455853 190 | 151 0.779927962 191 | 152 0.807411193 192 | 153 0.871370987 193 | 154 0.924402055 194 | 155 0.964544085 195 | 156 0.95789429 196 | 157 0.949036361 197 | 158 0.92706837 198 | 159 0.920707064 199 | 160 0.890593371 200 | 161 0.873099625 201 | 162 0.864987904 202 | 163 0.872181138 203 | 164 0.898074838 204 | 165 0.92988113 205 | 166 0.934191622 206 | 167 0.943696249 207 | 168 0.946760777 208 | 169 0.964149723 209 | 170 0.9698229 210 | 171 0.955645886 211 | 172 0.956760048 212 | 173 0.957511998 213 | 174 0.956838048 214 | 175 0.949913393 215 | 176 0.98204388 216 | 177 1.042155512 217 | 178 1.218354457 218 | 179 1.375444669 219 | 180 1.399764967 220 | 181 0 221 | 182 0 222 | 183 0 223 | 184 0 224 | 185 0 225 | 186 0 226 | 187 0 227 | 188 0 228 | 189 0 229 | 190 0 230 | 191 0 231 | 192 0 232 | 193 0 233 | 194 0 234 | 195 0 235 | 196 0 236 | 197 0 237 | 198 0 238 | 199 0 239 | 200 0 240 | 201 0 241 | 202 0 242 | 203 0 243 | 204 0 244 | 205 0 245 | 206 0 246 | 207 0 247 | 208 0 248 | 209 0 249 | 210 0 250 | 211 0 251 | 212 0 252 | 213 0 253 | 214 0 254 | 215 0 255 | 216 0 256 | 217 0 257 | 218 0 258 | 219 0 259 | 220 0 260 | 221 0 261 | 222 0 262 | 223 0 263 | 224 0 264 | 225 0 265 | 226 0 266 | 227 0 267 | 228 0 268 | 229 0 269 | 230 0 270 | 231 0 271 | 232 0 272 | 233 0 273 | 234 0 274 | 235 0 275 | 236 0 276 | 237 0 277 | 238 0 278 | 239 0 279 | 240 0 280 | 241 0 281 | 242 0 282 | 243 0 283 | 244 0 284 | 245 0 285 | 246 0 286 | 247 0 287 | 248 0 288 | 249 0 289 | 250 0 290 | 251 0 291 | 252 0 292 | 253 0 293 | 254 0 294 | [END_OF_CALDATA] 295 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/TriOS_initial/CP_RAMSES_LI_class_POLAR_20230406090628.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !POLDATA 3 | # polarization sensitivity characterization results 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # serial number of the instrument 17 | # type(s): string(255) 18 | [DEVICE] 19 | CLASS_RAMSES_LI 20 | 21 | # band wavelength, pol uncertainty (rad k=1), 22 | # type(s): uint8, single, 23 | [CALDATA] 24 | 400 0.002 25 | 443 0.002 26 | 490 0.004 27 | 560 0.004 28 | 665 0.008 29 | 779 0.008 30 | 865 0.008 31 | [END_OF_CALDATA] 32 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/TriOS_initial/CP_RAMSES_LI_class_STRAY_20231109135133.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !STRAYDATA 3 | # straylight characterization results 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # calibration date 17 | # type(s): fixed format as shown 18 | [CALDATE] 19 | yyyy-mm-dd hh:mm:ss 20 | 21 | # calibration lab name 22 | # type(s): string(255) 23 | [CALLAB] 24 | Tartu Observatory 25 | 26 | # calibration lab person to contact 27 | # type(s): string(255) 28 | [USER] 29 | Riho Vendt 30 | 31 | # Type of the instrument 32 | # type(s): string(255) 33 | [DEVICE] 34 | CLASS_RAMSES_LI 35 | 36 | # pixel no, uncertainty due to uncorrected straylight (% k=1) 37 | # type(s): uint8, single, 38 | [CALDATA] 39 | 0 0 40 | 1 0 41 | 2 0 42 | 3 0 43 | 4 0 44 | 5 0 45 | 6 0 46 | 7 0 47 | 8 0 48 | 9 0 49 | 10 0 50 | 11 0 51 | 12 0 52 | 13 0 53 | 14 6.633287314 54 | 15 5.323609937 55 | 16 4.773365111 56 | 17 3.919340852 57 | 18 3.503014198 58 | 19 2.895049322 59 | 20 3.013512394 60 | 21 3.30293962 61 | 22 2.499530802 62 | 23 2.66831947 63 | 24 2.604232748 64 | 25 2.490667643 65 | 26 2.74099064 66 | 27 2.557851852 67 | 28 2.279194262 68 | 29 1.816714883 69 | 30 1.551399178 70 | 31 1.488755365 71 | 32 1.543566104 72 | 33 1.408637148 73 | 34 1.239745376 74 | 35 1.498699048 75 | 36 1.353893641 76 | 37 1.377155956 77 | 38 1.348490487 78 | 39 1.17338774 79 | 40 1.168569825 80 | 41 1.065954012 81 | 42 1.108998426 82 | 43 1.012878018 83 | 44 1.099404668 84 | 45 1.003343927 85 | 46 1.028535989 86 | 47 1.091418803 87 | 48 0.921239259 88 | 49 0.956278527 89 | 50 0.783343017 90 | 51 0.902018664 91 | 52 0.907318166 92 | 53 1.011816913 93 | 54 0.962551855 94 | 55 0.977064761 95 | 56 0.869125653 96 | 57 0.766565742 97 | 58 1.13535999 98 | 59 1.078140445 99 | 60 0.942828233 100 | 61 1.038689087 101 | 62 1.110182528 102 | 63 1.083886623 103 | 64 1.076624442 104 | 65 1.022253449 105 | 66 0.973835369 106 | 67 0.971948275 107 | 68 0.947810698 108 | 69 0.936011462 109 | 70 0.878763864 110 | 71 0.893366718 111 | 72 0.832094495 112 | 73 0.795763288 113 | 74 0.773770528 114 | 75 0.776801448 115 | 76 0.765988449 116 | 77 0.778139912 117 | 78 0.802981254 118 | 79 0.794282882 119 | 80 0.772125988 120 | 81 0.843785483 121 | 82 0.985038535 122 | 83 1.021337648 123 | 84 1.016750565 124 | 85 0.978956166 125 | 86 1.002916136 126 | 87 0.898881813 127 | 88 0.861086674 128 | 89 0.885473622 129 | 90 0.842255225 130 | 91 0.934440805 131 | 92 0.929059269 132 | 93 0.958273615 133 | 94 0.921434799 134 | 95 0.940365295 135 | 96 0.828138732 136 | 97 1.025902445 137 | 98 0.808361802 138 | 99 0.83614644 139 | 100 1.076622748 140 | 101 0.773809145 141 | 102 0.905082356 142 | 103 0.944919574 143 | 104 1.038216735 144 | 105 0.922004077 145 | 106 1.038852646 146 | 107 0.967685171 147 | 108 1.092484896 148 | 109 1.003686996 149 | 110 0.847161583 150 | 111 0.822522014 151 | 112 0.846491522 152 | 113 1.001403406 153 | 114 0.854522026 154 | 115 0.863295754 155 | 116 0.84863229 156 | 117 0.962853116 157 | 118 0.757375262 158 | 119 0.915941714 159 | 120 0.783462655 160 | 121 0.839221632 161 | 122 0.855086511 162 | 123 0.85271682 163 | 124 0.794254625 164 | 125 1.263645681 165 | 126 1.419157534 166 | 127 1.277050108 167 | 128 1.199001291 168 | 129 0.931680862 169 | 130 1.124904263 170 | 131 1.331777504 171 | 132 0.920854907 172 | 133 0.877457215 173 | 134 1.106088369 174 | 135 0.834594608 175 | 136 1.139364052 176 | 137 1.313201706 177 | 138 0.928297537 178 | 139 1.805639311 179 | 140 1.101703338 180 | 141 1.410242476 181 | 142 1.628432543 182 | 143 0.883641188 183 | 144 1.150794947 184 | 145 0.835311007 185 | 146 0.960540597 186 | 147 0.856528892 187 | 148 0.955537195 188 | 149 1.020505011 189 | 150 1.041709134 190 | 151 0.847788164 191 | 152 1.869965445 192 | 153 0.934804228 193 | 154 1.093799408 194 | 155 2.482822568 195 | 156 3.229238776 196 | 157 4.005608272 197 | 158 1.525316037 198 | 159 2.351284716 199 | 160 1.261084123 200 | 161 1.9139165 201 | 162 1.110828328 202 | 163 1.274252266 203 | 164 1.309249856 204 | 165 1.247752393 205 | 166 1.750292419 206 | 167 3.391905031 207 | 168 1.722905013 208 | 169 1.441693367 209 | 170 6.654604423 210 | 171 2.861022781 211 | 172 4.224834597 212 | 173 2.953028017 213 | 174 3.157120386 214 | 175 4.846900576 215 | 176 3.224865112 216 | 177 3.970080808 217 | 178 5.993476436 218 | 179 4.379091126 219 | 180 0 220 | 181 0 221 | 182 0 222 | 183 0 223 | 184 0 224 | 185 0 225 | 186 0 226 | 187 0 227 | 188 0 228 | 189 0 229 | 190 0 230 | 191 0 231 | 192 0 232 | 193 0 233 | 194 0 234 | 195 0 235 | 196 0 236 | 197 0 237 | 198 0 238 | 199 0 239 | 200 0 240 | 201 0 241 | 202 0 242 | 203 0 243 | 204 0 244 | 205 0 245 | 206 0 246 | 207 0 247 | 208 0 248 | 209 0 249 | 210 0 250 | 211 0 251 | 212 0 252 | 213 0 253 | 214 0 254 | 215 0 255 | 216 0 256 | 217 0 257 | 218 0 258 | 219 0 259 | 220 0 260 | 221 0 261 | 222 0 262 | 223 0 263 | 224 0 264 | 225 0 265 | 226 0 266 | 227 0 267 | 228 0 268 | 229 0 269 | 230 0 270 | 231 0 271 | 232 0 272 | 233 0 273 | 234 0 274 | 235 0 275 | 236 0 276 | 237 0 277 | 238 0 278 | 239 0 279 | 240 0 280 | 241 0 281 | 242 0 282 | 243 0 283 | 244 0 284 | 245 0 285 | 246 0 286 | 247 0 287 | 248 0 288 | 249 0 289 | 250 0 290 | 251 0 291 | 252 0 292 | 253 0 293 | 254 0 294 | [END_OF_CALDATA] 295 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/TriOS_initial/CP_RAMSES_LT_class_POLAR_20230406090628.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !POLDATA 3 | # polarization sensitivity characterization results 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # serial number of the instrument 17 | # type(s): string(255) 18 | [DEVICE] 19 | CLASS_RAMSES_LT 20 | 21 | 22 | # band wavelength, pol uncertainty (rad k=1), 23 | # type(s): uint8, single, 24 | [CALDATA] 25 | 400 0.002 26 | 443 0.002 27 | 490 0.002 28 | 560 0.002 29 | 665 0.004 30 | 779 0.004 31 | 865 0.004 32 | [END_OF_CALDATA] 33 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/TriOS_initial/CP_RAMSES_LT_class_STRAY_20231109135133.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !STRAYDATA 3 | # straylight characterization results 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # calibration date 17 | # type(s): fixed format as shown 18 | [CALDATE] 19 | yyyy-mm-dd hh:mm:ss 20 | 21 | # calibration lab name 22 | # type(s): string(255) 23 | [CALLAB] 24 | Tartu Observatory 25 | 26 | # calibration lab person to contact 27 | # type(s): string(255) 28 | [USER] 29 | Riho Vendt 30 | 31 | # Type of the instrument 32 | # type(s): string(255) 33 | [DEVICE] 34 | CLASS_RAMSES_LT 35 | 36 | # pixel no, uncertainty due to uncorrected straylight (% k=1) 37 | # type(s): uint8, single, 38 | [CALDATA] 39 | 0 0 40 | 1 0 41 | 2 0 42 | 3 0 43 | 4 0 44 | 5 0 45 | 6 0 46 | 7 0 47 | 8 0 48 | 9 0 49 | 10 0 50 | 11 0 51 | 12 0 52 | 13 0 53 | 14 5.889406499 54 | 15 4.662853931 55 | 16 4.146180837 56 | 17 3.195995812 57 | 18 2.748786415 58 | 19 2.186457254 59 | 20 2.411772902 60 | 21 2.601195772 61 | 22 1.799036266 62 | 23 1.984159872 63 | 24 1.884032729 64 | 25 1.70444689 65 | 26 2.059997381 66 | 27 1.925777832 67 | 28 2.16268067 68 | 29 2.249310106 69 | 30 1.882252904 70 | 31 1.790744315 71 | 32 1.808065418 72 | 33 1.658899789 73 | 34 1.485855691 74 | 35 1.738035951 75 | 36 1.366167593 76 | 37 1.102027911 77 | 38 1.045860656 78 | 39 0.849080844 79 | 40 0.839425172 80 | 41 0.786018328 81 | 42 0.779934449 82 | 43 0.830040562 83 | 44 0.788265381 84 | 45 0.769075762 85 | 46 0.774418023 86 | 47 0.80906795 87 | 48 0.764017574 88 | 49 0.879679166 89 | 50 0.830413158 90 | 51 0.820936776 91 | 52 0.76716232 92 | 53 0.852783846 93 | 54 0.812441838 94 | 55 0.796951389 95 | 56 0.783201576 96 | 57 0.853323476 97 | 58 1.116958492 98 | 59 0.986986596 99 | 60 0.912542298 100 | 61 1.037422695 101 | 62 1.065720475 102 | 63 1.051546788 103 | 64 1.127085684 104 | 65 1.043016688 105 | 66 1.104639135 106 | 67 1.134508683 107 | 68 1.114218168 108 | 69 1.150742959 109 | 70 1.089773351 110 | 71 1.078134256 111 | 72 1.107450904 112 | 73 1.122471207 113 | 74 1.122450713 114 | 75 1.06890008 115 | 76 1.067133551 116 | 77 0.998257409 117 | 78 0.991185638 118 | 79 0.967284117 119 | 80 0.917535541 120 | 81 0.938817141 121 | 82 0.822183342 122 | 83 0.852729205 123 | 84 0.825295443 124 | 85 0.785770669 125 | 86 0.782943563 126 | 87 0.766655783 127 | 88 0.80993962 128 | 89 0.888910509 129 | 90 0.958279531 130 | 91 0.957174607 131 | 92 0.936579687 132 | 93 0.919409151 133 | 94 0.875380681 134 | 95 0.848146646 135 | 96 0.817618775 136 | 97 0.809554145 137 | 98 0.814816513 138 | 99 0.833538146 139 | 100 0.813077517 140 | 101 0.760852506 141 | 102 0.753594351 142 | 103 0.754210573 143 | 104 0.752737927 144 | 105 0.780148776 145 | 106 0.772747882 146 | 107 0.752945983 147 | 108 0.958417987 148 | 109 0.952034271 149 | 110 0.792998751 150 | 111 0.851406659 151 | 112 0.842961103 152 | 113 0.809597801 153 | 114 0.79587826 154 | 115 0.819607349 155 | 116 0.828679299 156 | 117 0.830231316 157 | 118 0.832579953 158 | 119 0.823117307 159 | 120 0.851617392 160 | 121 0.82109049 161 | 122 0.887736144 162 | 123 0.771105988 163 | 124 0.938485125 164 | 125 1.38383142 165 | 126 1.525674466 166 | 127 1.603082424 167 | 128 1.559075495 168 | 129 1.422729883 169 | 130 1.46455009 170 | 131 1.466840535 171 | 132 1.243602712 172 | 133 1.200756503 173 | 134 1.255967898 174 | 135 1.115677266 175 | 136 1.456356483 176 | 137 1.881747119 177 | 138 1.823065916 178 | 139 1.949672352 179 | 140 1.20460525 180 | 141 1.202001878 181 | 142 1.337339923 182 | 143 0.845059328 183 | 144 0.921754985 184 | 145 0.791147411 185 | 146 0.792550615 186 | 147 1.029963321 187 | 148 0.84353599 188 | 149 0.890912936 189 | 150 0.759765636 190 | 151 0.865364614 191 | 152 1.626371204 192 | 153 1.426719726 193 | 154 1.506079813 194 | 155 2.562995695 195 | 156 3.007799443 196 | 157 3.431113844 197 | 158 2.147501474 198 | 159 2.936634471 199 | 160 2.30467696 200 | 161 2.602061723 201 | 162 1.201113001 202 | 163 1.77015489 203 | 164 1.127527305 204 | 165 2.323368081 205 | 166 2.576370323 206 | 167 3.880922967 207 | 168 2.619882216 208 | 169 3.240796524 209 | 170 6.30942429 210 | 171 4.908082169 211 | 172 5.644117485 212 | 173 5.198255726 213 | 174 4.878352968 214 | 175 5.997043675 215 | 176 5.258496532 216 | 177 6.395822013 217 | 178 8.381937598 218 | 179 6.970603328 219 | 180 0 220 | 181 0 221 | 182 0 222 | 183 0 223 | 184 0 224 | 185 0 225 | 186 0 226 | 187 0 227 | 188 0 228 | 189 0 229 | 190 0 230 | 191 0 231 | 192 0 232 | 193 0 233 | 194 0 234 | 195 0 235 | 196 0 236 | 197 0 237 | 198 0 238 | 199 0 239 | 200 0 240 | 201 0 241 | 202 0 242 | 203 0 243 | 204 0 244 | 205 0 245 | 206 0 246 | 207 0 247 | 208 0 248 | 209 0 249 | 210 0 250 | 211 0 251 | 212 0 252 | 213 0 253 | 214 0 254 | 215 0 255 | 216 0 256 | 217 0 257 | 218 0 258 | 219 0 259 | 220 0 260 | 221 0 261 | 222 0 262 | 223 0 263 | 224 0 264 | 225 0 265 | 226 0 266 | 227 0 267 | 228 0 268 | 229 0 269 | 230 0 270 | 231 0 271 | 232 0 272 | 233 0 273 | 234 0 274 | 235 0 275 | 236 0 276 | 237 0 277 | 238 0 278 | 239 0 279 | 240 0 280 | 241 0 281 | 242 0 282 | 243 0 283 | 244 0 284 | 245 0 285 | 246 0 286 | 247 0 287 | 248 0 288 | 249 0 289 | 250 0 290 | 251 0 291 | 252 0 292 | 253 0 293 | 254 0 294 | [END_OF_CALDATA] 295 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/TriOS_initial/CP_RAMSES_L_class_LINEAR_20230406091100.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !NLDATA 3 | # non linearity uncertainty coefficient 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # serial number of the instrument 17 | # type(s): string(255) 18 | [DEVICE] 19 | CLASS_RAMSES_RADIANCE 20 | 21 | # band wavelength, non linearity uncertainty (rad k=1), 22 | # type(s): uint8, single, 23 | [CALDATA] 24 | 400 0.02 25 | 443 0.02 26 | 490 0.02 27 | 560 0.02 28 | 665 0.02 29 | 779 0.02 30 | 865 0.02 31 | [END_OF_CALDATA] 32 | -------------------------------------------------------------------------------- /Data/Class_Based_Characterizations/TriOS_initial/CP_RAMSES_L_class_STAB_20230406090628.txt: -------------------------------------------------------------------------------- 1 | !FRM4SOC_CP 2 | !STABDATA 3 | # absolute calibration stability uncertainty coefficient 4 | 5 | # comments start with # (ignored by the processor) 6 | # no empty lines between the parameter signatures in [] and the parameter values 7 | # parameters are case insensitive 8 | # parameters can be inserted in any order, except the first two signatures 9 | # columns are tab- or space-delimited 10 | 11 | # file format version 12 | # type(s): string(255) 13 | [VERSION] 14 | 0.1 15 | 16 | # serial number of the instrument 17 | # type(s): string(255) 18 | [DEVICE] 19 | CLASS_RAMSES_RADIANCE 20 | 21 | 22 | # band wavelength, non linearity uncertainty (rad k=1), 23 | # type(s): uint8, single, 24 | [CALDATA] 25 | 400 0.01 26 | 443 0.01 27 | 490 0.01 28 | 560 0.01 29 | 665 0.01 30 | 779 0.01 31 | 865 0.01 32 | [END_OF_CALDATA] 33 | -------------------------------------------------------------------------------- /Data/Img/Configuration_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/Configuration_window.png -------------------------------------------------------------------------------- /Data/Img/Deglitching_window.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/Deglitching_window.JPG -------------------------------------------------------------------------------- /Data/Img/EARTHDATA_ACCESS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/EARTHDATA_ACCESS.png -------------------------------------------------------------------------------- /Data/Img/EARTHDATA_ACCESS_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/EARTHDATA_ACCESS_popup.png -------------------------------------------------------------------------------- /Data/Img/ECMWF_ADS_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/ECMWF_ADS_logo.png -------------------------------------------------------------------------------- /Data/Img/ECMWF_CDS_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/ECMWF_CDS_logo.png -------------------------------------------------------------------------------- /Data/Img/ECMWF_api_key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/ECMWF_api_key.png -------------------------------------------------------------------------------- /Data/Img/ECMWF_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/ECMWF_popup.png -------------------------------------------------------------------------------- /Data/Img/ECMWF_register0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/ECMWF_register0.png -------------------------------------------------------------------------------- /Data/Img/ECMWF_register1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/ECMWF_register1.png -------------------------------------------------------------------------------- /Data/Img/ECMWF_terms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/ECMWF_terms.png -------------------------------------------------------------------------------- /Data/Img/EUMETSAT_Data_Store_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/EUMETSAT_Data_Store_logo.png -------------------------------------------------------------------------------- /Data/Img/Flow_chart_1.2.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/Flow_chart_1.2.0.png -------------------------------------------------------------------------------- /Data/Img/Main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/Main.png -------------------------------------------------------------------------------- /Data/Img/NASA_Earth_Data_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/NASA_Earth_Data_logo.png -------------------------------------------------------------------------------- /Data/Img/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/banner.jpg -------------------------------------------------------------------------------- /Data/Img/banner_530x151.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/banner_530x151.png -------------------------------------------------------------------------------- /Data/Img/logo.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/logo.icns -------------------------------------------------------------------------------- /Data/Img/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/logo.ico -------------------------------------------------------------------------------- /Data/Img/logo_scale20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/logo_scale20.png -------------------------------------------------------------------------------- /Data/Img/with_background_530x223.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Img/with_background_530x223.png -------------------------------------------------------------------------------- /Data/Sample_Data/DALEC/VIIRS2024_DALEC_Ancillary.sb: -------------------------------------------------------------------------------- 1 | /begin_header 2 | /investigators=Antonio_Mannino,Dirk_Aurin 3 | /affiliations=GSFC 4 | /contact=dirk.a.aurin@nasa.gov 5 | /experiment=VIIRS2024 6 | /cruise=VIIRS2024 7 | /documents=VIIRS2024_DALEC_Radiometry_Field_Log.xlsx 8 | /data_type=flow_thru 9 | /data_status=final 10 | /station=NA 11 | /water_depth=NA 12 | /data_file_name=VIIRS2024_Ancillary.sb 13 | /calibration_files=see_documents 14 | /start_date=20240520 15 | /end_date=20240601 16 | /start_time=01:00:00[GMT] 17 | /end_time=23:00:00[GMT] 18 | /measurement_depth=0.0 19 | /north_latitude=32.6510[DEG] 20 | /south_latitude=23.7105[DEG] 21 | /east_longitude=-79.1856[DEG] 22 | /west_longitude=-87.1912[DEG] 23 | ! 24 | ! Currently just the Field Log from (Harrison?) 25 | ! 26 | ! 27 | /missing=-9999 28 | /delimiter=comma 29 | /fields=station,year,month,day,hour,minute,second,lat,lon,wind,cloud,waveht 30 | /units=none,yyyy,mo,dd,hh,mn,ss,degrees,degrees,m/s,%,m 31 | /end_header 32 | 1.0,2024,05,20,20,25,30,30.0038,-87.1912,4.9,5.0,0.5 33 | 2.0,2024,05,21,14,57,30,29.0900,-84.9100,5.7,30.0,1.0 34 | 3.0,2024,05,21,18,02,00,29.0353,-84.7048,4.9,10.0,0.5 35 | 4.0,2024,05,21,21,02,00,28.9521,-84.5318,5.4,0.0,0.5 36 | 5.0,2024,05,22,14,47,30,27.9091,-83.2018,5.7,10.0,1.0 37 | 6.0,2024,05,22,17,51,00,27.6950,-83.2416,4.3,10.0,0.5 38 | 7.0,2024,05,22,20,39,30,27.5321,-83.3691,2.6,0.0,0.5 39 | 8.0,2024,05,23,14,52,30,26.1131,-82.1701,6.1,30.0,1.0 40 | 9.0,2024,05,23,18,05,00,26.2346,-82.3100,4.6,15.0,0.5 41 | 10.0,2024,05,23,21,03,30,26.3311,-82.4975,1.0,20.0,0.0 42 | 11.0,2024,05,24,14,58,00,24.7831,-83.6346,5.1,10.0,0.5 43 | 12.0,2024,05,24,17,42,30,24.7921,-83.8270,4.6,15.0,0.5 44 | 13.0,2024,05,24,20,43,30,24.8000,-84.0476,2.5,0.0,0.5 45 | 14.0,2024,05,24,22,55,00,24.7901,-84.1668,4.6,0.0,0.5 46 | 15.0,2024,05,25,14,45,00,23.7105,-83.7863,6.1,0.0,1.5 47 | 16.0,2024,05,25,18,22,30,23.9540,-83.5536,4.1,0.0,0.5 48 | 17.0,2024,05,25,20,53,00,24.0248,-83.3756,4.1,0.0,0.5 49 | 18.0,2024,05,26,13,41,30,24.3466,-81.2756,3.6,0.0,0.5 50 | 19.0,2024,05,26,16,57,30,24.4380,-81.4380,3.3,0.0,0.5 51 | 20.0,2024,05,26,19,44,30,24.4666,-80.7706,1.7,5.0,0.5 52 | 21.0,2024,05,26,21,32,30,24.5356,-80.5780,1.5,0.0,0.5 53 | 22.0,2024,05,27,14,42,30,25.6313,-79.9423,3.3,5.0,0.0 54 | 23.0,2024,05,27,17,43,00,25.8093,-79.9385,1.5,5.0,0.0 55 | 24.0,2024,05,27,20,50,00,26.0983,-79.9545,1.7,5.0,0.0 56 | 25.0,2024,05,28,14,47,00,27.7091,-79.5265,7.2,10.0,1.5 57 | 26.0,2024,05,28,17,36,00,27.8875,-79.5262,5.1,10.0,1.0 58 | 27.0,2024,05,28,20,12,30,28.0915,-79.6211,2.8,60.0,1.0 59 | 28.0,2024,05,28,22,13,00,28.2113,-79.6340,2.0,80.0,0.0 60 | 29.0,2024,05,29,15,00,00,29.7661,-80.9110,3.0,0.0,0.5 61 | 30.0,2024,05,29,17,47,30,29.9273,-80.9110,5.1,10.0,0.5 62 | 31.0,2024,05,29,21,02,30,30.0781,-80.8320,4.6,20.0,0.5 63 | 32.0,2024,05,30,14,44,00,29.6386,-79.1856,6.7,0.0,1.0 64 | 33.0,2024,05,30,17,58,00,29.6311,-79.3923,5.6,0.0,0.5 65 | 34.0,2024,05,30,21,05,00,29.6488,-79.5731,6.7,30.0,1.0 66 | 35.0,2024,05,31,19,40,00,30.4030,-81.1295,7.7,10.0,0.5 67 | 36.0,2024,05,31,21,52,00,30.4505,-80.9751,9.2,10.0,1.0 68 | 37.0,2024,06,01,18,03,30,32.5483,-79.7248,7.2,70.0,1.0 69 | 38.0,2024,06,01,20,53,00,32.6510,-79.6011,6.1,80.0,1.0 70 | -------------------------------------------------------------------------------- /Data/Sample_Data/Manual_TriOS/FICE22_TriOS_Ancillary.sb: -------------------------------------------------------------------------------- 1 | /begin_header 2 | /investigators=Giorgio_DallOlmo 3 | /affiliations=Plymouth_Marine_Laboratory 4 | /contact=gdal@pml.ac.uk 5 | /experiment=FRM4SOC2 6 | /cruise=FICE22 7 | /station=AAOT 8 | /data_file_name=FICE_Ancillary_TrueRelAz_v2.sb 9 | /documents=NA 10 | /calibration_files=NA 11 | /data_type=above_water 12 | /data_status=final 13 | /start_date=20220714 14 | /end_date=20220721 15 | /start_time=08:45:00[GMT] 16 | /end_time=09:00:00[GMT] 17 | /north_latitude=45.314[DEG] 18 | /south_latitude=45.314[DEG] 19 | /east_longitude=12.508[DEG] 20 | /west_longitude=12.508[DEG] 21 | /water_depth=17 22 | /measurement_depth=0 23 | /missing=-9999 24 | /delimiter=comma 25 | ! 26 | ! COMMENTS 27 | ! 28 | ! FRM4SOC-2 Field InterComparison Experiment (FICE) 29 | ! July 11 - 21, 2022 30 | ! Acqua Alta Oceanographic Tower (AAOT), CNR-ISMAR 31 | ! 32 | ! RelAz refer to solar-sensor relative azimuth angle. 33 | ! 34 | ! Manually operated TriOS triplet. Height: ~15 m, Tower color: Red/yellow. 35 | ! 36 | /fields=year,month,day,hour,minute,second,lat,lon,wind,wdir,Wt,At,sal,RelAz,heading,TrueRelAz 37 | /units=yyyy,mo,dd,hh,mn,ss,degrees,degrees,m/s,degrees,degreesC,degreesC,PSU,degrees,degrees,degrees 38 | /end_header 39 | 2022,7,14,8,45,0,45.314,12.508,0.2,95,25.6,-9999.0000,-9999.0000,135,0,135 40 | 2022,7,14,9,0,0,45.314,12.508,0.5,111,25.5,-9999.0000,-9999.0000,135,0,135 41 | 2022,7,14,9,20,0,45.314,12.508,0.8,116,25.8,-9999.0000,-9999.0000,135,0,135 42 | 2022,7,14,9,40,0,45.314,12.508,0.9,140,25.8,-9999.0000,-9999.0000,135,0,135 43 | 2022,7,14,10,0,0,45.314,12.508,1.2,148,25.9,-9999.0000,-9999.0000,135,0,135 44 | 2022,7,14,10,20,0,45.314,12.508,1.2,124,25.8,-9999.0000,-9999.0000,135,0,135 45 | 2022,7,14,10,40,0,45.314,12.508,1.5,136,25.8,-9999.0000,-9999.0000,135,0,135 46 | 2022,7,14,11,40,0,45.314,12.508,1.2,145,25.8,-9999.0000,-9999.0000,90,0,90 47 | 2022,7,14,12,0,0,45.314,12.508,1.5,135,26.2,-9999.0000,-9999.0000,90,0,90 48 | 2022,7,14,12,20,0,45.314,12.508,2.6,139,26.2,-9999.0000,-9999.0000,90,0,90 49 | 2022,7,14,12,40,0,45.314,12.508,3.4,138,26.4,-9999.0000,-9999.0000,90,0,90 50 | 2022,7,14,13,0,0,45.314,12.508,3.7,140,26.4,-9999.0000,-9999.0000,90,0,90 51 | 2022,7,14,13,20,0,45.314,12.508,3.5,129,26.4,-9999.0000,-9999.0000,90,0,90 52 | 2022,7,15,12,20,0,45.314,12.508,4.1,116,26.6,-9999.0000,-9999.0000,90,0,90 53 | 2022,7,15,12,40,0,45.314,12.508,4.6,110,26.9,-9999.0000,-9999.0000,90,0,90 54 | 2022,7,15,13,0,0,45.314,12.508,4.4,114,26.7,-9999.0000,-9999.0000,90,0,90 55 | 2022,7,15,13,20,0,45.314,12.508,4.2,120,26.8,-9999.0000,-9999.0000,90,0,90 56 | 2022,7,15,13,40,0,45.314,12.508,3.8,120,27.0,-9999.0000,-9999.0000,90,0,90 57 | 2022,7,15,14,0,0,45.314,12.508,3.5,124,26.8,-9999.0000,-9999.0000,90,0,90 58 | 2022,7,19,8,0,0,45.314,12.508,5.0,42,26.2,-9999.0000,-9999.0000,135,0,135 59 | 2022,7,19,8,20,0,45.314,12.508,3.7,30,26.0,-9999.0000,-9999.0000,135,0,135 60 | 2022,7,19,8,40,0,45.314,12.508,4.1,38,26.3,-9999.0000,-9999.0000,135,0,135 61 | 2022,7,19,8,50,0,45.314,12.508,4.3,41,26.2,-9999.0000,-9999.0000,135,0,135 62 | 2022,7,19,9,0,0,45.314,12.508,4.3,44,26.1,-9999.0000,-9999.0000,135,0,135 63 | 2022,7,19,9,10,0,45.314,12.508,3.9,42,26.2,-9999.0000,-9999.0000,135,0,135 64 | 2022,7,19,9,20,0,45.314,12.508,3.6,48,26.3,-9999.0000,-9999.0000,135,0,135 65 | 2022,7,19,9,30,0,45.314,12.508,3.7,46,26.3,-9999.0000,-9999.0000,135,0,135 66 | 2022,7,19,9,40,0,45.314,12.508,4.1,44,26.2,-9999.0000,-9999.0000,135,0,135 67 | 2022,7,19,9,50,0,45.314,12.508,3.8,44,26.3,-9999.0000,-9999.0000,135,0,135 68 | 2022,7,19,10,0,0,45.314,12.508,3.6,45,26.6,-9999.0000,-9999.0000,135,0,135 69 | 2022,7,19,10,10,0,45.314,12.508,3.7,46,26.4,-9999.0000,-9999.0000,135,0,135 70 | 2022,7,19,10,20,0,45.314,12.508,3.7,53,26.3,-9999.0000,-9999.0000,135,0,135 71 | 2022,7,19,10,30,0,45.314,12.508,3.5,63,26.3,-9999.0000,-9999.0000,135,0,135 72 | 2022,7,19,10,40,0,45.314,12.508,3.2,68,26.5,-9999.0000,-9999.0000,135,0,135 73 | 2022,7,19,10,50,0,45.314,12.508,2.9,69,26.5,-9999.0000,-9999.0000,135,0,135 74 | 2022,7,19,11,0,0,45.314,12.508,2.8,70,26.5,-9999.0000,-9999.0000,90,0,90 75 | 2022,7,19,11,10,0,45.314,12.508,2.7,78,26.6,-9999.0000,-9999.0000,90,0,90 76 | 2022,7,19,11,20,0,45.314,12.508,2.8,81,26.5,-9999.0000,-9999.0000,90,0,90 77 | 2022,7,19,12,40,0,45.314,12.508,1.8,139,26.3,-9999.0000,-9999.0000,90,0,90 78 | 2022,7,19,13,0,0,45.314,12.508,1.7,139,26.4,-9999.0000,-9999.0000,90,0,90 79 | 2022,7,19,13,20,0,45.314,12.508,1.7,145,26.3,-9999.0000,-9999.0000,90,0,90 80 | 2022,7,19,13,40,0,45.314,12.508,1.3,173,26.5,-9999.0000,-9999.0000,90,0,90 81 | 2022,7,19,14,0,0,45.314,12.508,1.1,205,26.7,-9999.0000,-9999.0000,90,0,90 82 | 2022,7,20,8,0,0,45.314,12.508,4.7,29,26.3,-9999.0000,-9999.0000,135,0,135 83 | 2022,7,20,8,20,0,45.314,12.508,4.7,31,26.5,-9999.0000,-9999.0000,135,0,135 84 | 2022,7,20,8,40,0,45.314,12.508,4.7,33,26.6,-9999.0000,-9999.0000,135,0,135 85 | 2022,7,20,9,0,0,45.314,12.508,4.2,35,26.3,-9999.0000,-9999.0000,135,0,135 86 | 2022,7,20,9,20,0,45.314,12.508,3.4,41,26.6,-9999.0000,-9999.0000,135,0,135 87 | 2022,7,20,9,40,0,45.314,12.508,4.0,52,26.6,-9999.0000,-9999.0000,135,0,135 88 | 2022,7,20,10,0,0,45.314,12.508,3.0,57,26.4,-9999.0000,-9999.0000,135,0,135 89 | 2022,7,20,10,20,0,45.314,12.508,2.5,66,26.6,-9999.0000,-9999.0000,90,0,90 90 | 2022,7,20,11,40,0,45.314,12.508,2.7,110,26.9,-9999.0000,-9999.0000,90,0,90 91 | 2022,7,20,12,0,0,45.314,12.508,2.0,107,27.1,-9999.0000,-9999.0000,90,0,90 92 | 2022,7,20,12,20,0,45.314,12.508,1.6,121,27.0,-9999.0000,-9999.0000,90,0,90 93 | 2022,7,20,12,40,0,45.314,12.508,2.8,129,27.1,-9999.0000,-9999.0000,90,0,90 94 | 2022,7,20,13,0,0,45.314,12.508,2.6,145,27.2,-9999.0000,-9999.0000,90,0,90 95 | 2022,7,20,13,20,0,45.314,12.508,2.5,170,27.1,-9999.0000,-9999.0000,90,0,90 96 | 2022,7,20,13,40,0,45.314,12.508,2.6,165,27.3,-9999.0000,-9999.0000,90,0,90 97 | 2022,7,21,8,0,0,45.314,12.508,4.4,30,26.7,-9999.0000,-9999.0000,135,0,135 98 | 2022,7,21,8,10,0,45.314,12.508,4.2,30,27.0,-9999.0000,-9999.0000,135,0,135 99 | 2022,7,21,8,20,0,45.314,12.508,4.2,29,27.1,-9999.0000,-9999.0000,135,0,135 100 | 2022,7,21,8,30,0,45.314,12.508,4.1,33,26.8,-9999.0000,-9999.0000,135,0,135 101 | 2022,7,21,8,40,0,45.314,12.508,3.9,28,27.0,-9999.0000,-9999.0000,135,0,135 102 | 2022,7,21,8,50,0,45.314,12.508,4.2,33,27.0,-9999.0000,-9999.0000,135,0,135 103 | 2022,7,21,9,0,0,45.314,12.508,4.9,41,27.0,-9999.0000,-9999.0000,135,0,135 104 | -------------------------------------------------------------------------------- /Data/Sample_Data/SolarTracker/RAW/KORUS_KR2016_NASA_20160320_060000.RAW: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Sample_Data/SolarTracker/RAW/KORUS_KR2016_NASA_20160320_060000.RAW -------------------------------------------------------------------------------- /Data/Sample_Data/pySAS/Photos/20220719_112534.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Sample_Data/pySAS/Photos/20220719_112534.jpg -------------------------------------------------------------------------------- /Data/Sample_Data/pySAS/Photos/20220719_112546.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Sample_Data/pySAS/Photos/20220719_112546.jpg -------------------------------------------------------------------------------- /Data/Sample_Data/pySAS/Photos/20220719_112553.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Sample_Data/pySAS/Photos/20220719_112553.jpg -------------------------------------------------------------------------------- /Data/Sample_Data/pySAS/Photos/20220719_112609.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Sample_Data/pySAS/Photos/20220719_112609.jpg -------------------------------------------------------------------------------- /Data/Sample_Data/pySAS/RAW/FRM4SOC2_FICE22_NASA_20220719_080000.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/Sample_Data/pySAS/RAW/FRM4SOC2_FICE22_NASA_20220719_080000.raw -------------------------------------------------------------------------------- /Data/Water_Absorption.sb: -------------------------------------------------------------------------------- 1 | /begin_header 2 | /investigators=Pope,Fry,Smith,Baker 3 | /affiliations=Pure_Water_University 4 | /contact=pope@wateru.edu 5 | /experiment=PureWater 6 | /cruise=PureWater_01 7 | /data_type=scan 8 | /documents=Water_Absorption.sb 9 | /calibration_files=Water_Absorption.sb 10 | /data_file_name=Water_Absorption.sb 11 | /north_latitude=0[DEG] 12 | /south_latitude=0[DEG] 13 | /east_longitude=0[DEG] 14 | /west_longitude=0[DEG] 15 | /start_date=19970101 16 | /end_date=19970101 17 | /start_time=00:00:00[GMT] 18 | /end_time=00:00:00[GMT] 19 | /water_depth=0 20 | /measurement_depth=0 21 | /missing=-999 22 | /delimiter=space 23 | ! 24 | ! Pure water absorption spectrum 380 - 730 nm and 730 - 800 nm, 2.5 nm increments 25 | ! Pope, R. M., and E. S. Fry, Absorption spectrum (380-700 nm) of pure 26 | ! water, II, Integrating cavity measurements, Appl. Opt., 36(33) 8710- 27 | ! 8723, 1997. 28 | ! 29 | ! Smith, R. C., and K. S. Baker, Optical properties of the clearest natural 30 | ! waters (200-800 nm), Appl. Opt., 20(2), 177-184, 1981 31 | ! 32 | /fields=wavelength,aw 33 | /units=nm,1/m 34 | /end_header 35 | 380 0.01137 36 | 382.5 0.010044 37 | 385 0.00941 38 | 387.5 0.00917 39 | 390 0.00851 40 | 392.5 0.00829 41 | 395 0.00813 42 | 397.5 0.00775 43 | 400 0.00663 44 | 402.5 0.00579 45 | 405 0.0053 46 | 407.5 0.00503 47 | 410 0.00473 48 | 412.5 0.00452 49 | 415 0.00444 50 | 417.5 0.00442 51 | 420 0.00454 52 | 422.5 0.00474 53 | 425 0.00478 54 | 427.5 0.00482 55 | 430 0.00495 56 | 432.5 0.00504 57 | 435 0.0053 58 | 437.5 0.0058 59 | 440 0.00635 60 | 442.5 0.00696 61 | 445 0.00751 62 | 447.5 0.0083 63 | 450 0.00922 64 | 452.5 0.00969 65 | 455 0.00962 66 | 457.5 0.00957 67 | 460 0.00979 68 | 462.5 0.01005 69 | 465 0.01011 70 | 467.5 0.0102 71 | 470 0.0106 72 | 472.5 0.0109 73 | 475 0.0114 74 | 477.5 0.0121 75 | 480 0.0127 76 | 482.5 0.0131 77 | 485 0.0136 78 | 487.5 0.0144 79 | 490 0.015 80 | 492.5 0.0162 81 | 495 0.0173 82 | 497.5 0.0191 83 | 500 0.0204 84 | 502.5 0.0228 85 | 505 0.0256 86 | 507.5 0.028 87 | 510 0.0325 88 | 512.5 0.0372 89 | 515 0.0396 90 | 517.5 0.0399 91 | 520 0.0409 92 | 522.5 0.0416 93 | 525 0.0417 94 | 527.5 0.0428 95 | 530 0.0434 96 | 532.5 0.0447 97 | 535 0.0452 98 | 537.5 0.0466 99 | 540 0.0474 100 | 542.5 0.0489 101 | 545 0.0511 102 | 547.5 0.0537 103 | 550 0.0565 104 | 552.5 0.0593 105 | 555 0.0596 106 | 557.5 0.0606 107 | 560 0.0619 108 | 562.5 0.064 109 | 565 0.0642 110 | 567.5 0.0672 111 | 570 0.0695 112 | 572.5 0.0733 113 | 575 0.0772 114 | 577.5 0.0836 115 | 580 0.0896 116 | 582.5 0.0989 117 | 585 0.11 118 | 587.5 0.122 119 | 590 0.1351 120 | 592.5 0.1516 121 | 595 0.1672 122 | 597.5 0.1925 123 | 600 0.2224 124 | 602.5 0.247 125 | 605 0.2577 126 | 607.5 0.2629 127 | 610 0.2644 128 | 612.5 0.2665 129 | 615 0.2678 130 | 617.5 0.2707 131 | 620 0.2755 132 | 622.5 0.281 133 | 625 0.2834 134 | 627.5 0.2904 135 | 630 0.2916 136 | 632.5 0.2995 137 | 635 0.3012 138 | 637.5 0.3077 139 | 640 0.3108 140 | 642.5 0.322 141 | 645 0.325 142 | 647.5 0.335 143 | 650 0.34 144 | 652.5 0.358 145 | 655 0.371 146 | 657.5 0.393 147 | 660 0.41 148 | 662.5 0.424 149 | 665 0.429 150 | 667.5 0.436 151 | 670 0.439 152 | 672.5 0.448 153 | 675 0.448 154 | 677.5 0.461 155 | 680 0.465 156 | 682.5 0.478 157 | 685 0.486 158 | 687.5 0.502 159 | 690 0.516 160 | 692.5 0.538 161 | 695 0.559 162 | 697.5 0.592 163 | 700 0.624 164 | 702.5 0.663 165 | 705 0.704 166 | 707.5 0.756 167 | 710 0.827 168 | 712.5 0.914 169 | 715 1.007 170 | 717.5 1.119 171 | 720 1.231 172 | 722.5 1.356 173 | 725 1.489 174 | 727.5 1.678 175 | 730 1.7845 176 | 732.5 1.9333 177 | 735 2.0822 178 | 737.5 2.2311 179 | 740 2.38 180 | 742.5 2.4025 181 | 745 2.425 182 | 747.5 2.4475 183 | 750 2.47 184 | 752.5 2.49 185 | 755 2.51 186 | 757.5 2.53 187 | 760 2.55 188 | 762.5 2.54 189 | 765 2.53 190 | 767.5 2.52 191 | 770 2.51 192 | 772.5 2.4725 193 | 775 2.435 194 | 777.5 2.3975 195 | 780 2.36 196 | 782.5 2.31 197 | 785 2.26 198 | 787.5 2.21 199 | 790 2.16 200 | 792.5 2.1375 201 | 795 2.115 202 | 797.5 2.0925 203 | 800.0 2.0700 204 | 205 | -------------------------------------------------------------------------------- /Data/correlation_mats.csv: -------------------------------------------------------------------------------- 1 | [RAD] 2 | 1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 3 | 0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 4 | 0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 5 | 0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 6 | 0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 7 | 0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 8 | 0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 9 | 0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 10 | 0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 11 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 12 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 13 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 14 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 15 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 16 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 17 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0 18 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0 19 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0 20 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0,0.0 21 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0,0.0 22 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0,0.0 23 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,0.0 24 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0,0.0 25 | 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0 26 | [END RAD] 27 | [Es] 28 | 1.0,0.5580872127882232,0.4921632034035149, 29 | [END Es] 30 | [Li] 31 | 0.5580872127882232,1.0,0.7488226417847038, 32 | [END Li] 33 | [Lt] 34 | 0.4921632034035149,0.7488226417847038,1.0, 35 | [END Lt] 36 | [Lw] 37 | 1.0,-0.7240224677088385,0.0 38 | -0.7240224677088385,0.9999999999999999,0.0 39 | 0.0,0.0,1.0 40 | [END Lw] 41 | [RRS] 42 | 1.0,-0.7240224677088385,0.0,-0.4930272117145282 43 | -0.7240224677088385,0.9999999999999999,0.0,0.6680603516606074 44 | 0.0,0.0,1.0,0.0 45 | -0.4930272117145282,0.6680603516606073,0.0,1.0 46 | [END RRS] 47 | -------------------------------------------------------------------------------- /Data/hybrid_reference_spectrum_p1nm_resolution_c2020-09-21_with_unc.nc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/hybrid_reference_spectrum_p1nm_resolution_c2020-09-21_with_unc.nc -------------------------------------------------------------------------------- /Data/rhoTable_AO1999.hdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Data/rhoTable_AO1999.hdf -------------------------------------------------------------------------------- /Experiment_Cruise_Instrument_Radiometry_Field_Log.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Experiment_Cruise_Instrument_Radiometry_Field_Log.xlsx -------------------------------------------------------------------------------- /HyperCP - Collaboration Guidelines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/HyperCP - Collaboration Guidelines.pdf -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright © 2020 United States Government as represented by the Administrator 4 | of the National Aeronautics and Space Administration. All Rights Reserved. 5 | 6 | Copyright © 2023 EUMETSAT 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. -------------------------------------------------------------------------------- /NOSA GSC-18527-1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/NOSA GSC-18527-1.pdf -------------------------------------------------------------------------------- /README_Sample_Data.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/README_Sample_Data.xlsx -------------------------------------------------------------------------------- /README_ancillary.md: -------------------------------------------------------------------------------- 1 | # Ancillary Sources Used in HyperCP: GMAO/MERRA-2 reanalysis and ECMWF/CAMS forecast 2 | 3 | HyperCP uses ancillary information such as wind speed, aerosol optical depth, salinity, and sea surface temperature 4 | during the following steps: 5 | 6 | - L1BQC processing: QC screening uses wind speed to filter the data for minimizing glint contamination 7 | - L2 processing: ancillary information is also required to calculate the [L2 Sky/Sunglint Correction](README_configuration/#l2-sky-sunglint-correction-rho-and-nir-correction) 8 | - Mobley (1999) rho factors require wind speed 9 | - Zhang et al. 2017 rho factors require wind speed, aerosol optical depth, salinity, and sea surface temperature 10 | 11 | Since most field collections of above water radiometry are missing some or all of these ancillary parameters (though 12 | they can be input in the Ancillary file, if available), an embedded function allows the user to download model data from 13 | two possible sources (to be selected by the user): 14 | 15 | - NASA [Global Modeling and Assimilation Office (GMAO)](https://gmao.gsfc.nasa.gov/) data are 16 | requested to the NASA EARTHDATA server. GMAO data are generated by the as hourly, 17 | global [MERRA2](https://gmao.gsfc.nasa.gov/reanalysis/MERRA-2/) HDF files at 0.5 deg (latitude) by 0.625 deg (longitude) resolution. 18 | Two files will be downloaded for each hour of data processed (total ~8.3 MB for one hour of field data) and stored in 19 | /Data/Anc. Global ancillary data files from GMAO will be reused, so it is not recommended to clear this directory unless 20 | updated models are being released by GMAO. 21 | 22 | Note: MERRA2 files downloaded prior to March 15, 2022 can be deleted as the file name format has changed 23 | - ECMWF [CAMS global atmospheric composition forecasts](https://ads.atmosphere.copernicus.eu/datasets/cams-global-atmospheric-composition-forecasts?tab=overview) 24 | data are requested to ECMWF via the [ADS API](https://confluence.ecmwf.int/display/CKB/Atmosphere+Data+Store+%28ADS%29+documentation). 25 | One netCDF file at 0.4 degree (lat/lon) is downladed for each hour of processed data (totalling ~ 45K for one hour of 26 | - filed data) and stored in /Data/Anc. Ancillary data files are downloaded only at the 0.4 x 0.4 pixel 27 | cotaining the lat/lon reported for the field acquisition. 28 | 29 | ## Obtain the credentials 30 | 31 | When either of the two sources is selected in the L1B section of the [Configuration Window](#README_configuration), a 32 | window will pop-up to insert the required credentials. Please note, that the ancillary source may be selected by default 33 | for a given setup, meaning that the window may pop-up before opening the configuration window for edition. 34 | 35 | ### GMAO MERRA2 credentials 36 | 37 | A pop-up window like this will show up: 38 | 39 | banner 40 | 41 | Access to GMAO MERRA2 data requires a user login and password, which can be obtained for free 42 | [here](https://urs.earthdata.nasa.gov/): 43 | 44 | banner 45 | 46 | The login and password will be stored under ```~/.netrc``` (or ```~/_netrc``` for Windows users). 47 | 48 | ### ECMWF CAMS GACF credentials 49 | 50 | A pop-up window like this will show up: 51 | 52 | banner 53 | 54 | First, you must go [here](https://ads.atmosphere.copernicus.eu/) and register for free: 55 | 56 | banner 57 | 58 | Once registered and logged in your URL and KEY API credentials should show [here](https://ads.atmosphere.copernicus.eu/how-to-api): 59 | 60 | banner 61 | 62 | Please insert URL and KEY in the pop-up window. Please note: 63 | 64 | - The API URL and KEY that you need to insert in the HyperCP pop-up window are these last ones and are different from your ECMWF credentials! 65 | - This process is agnostic to your operative system (disregard the options shown by ECMWF with respect to this) 66 | 67 | Finally *don't forget* to accept the Terms and Conditions scrolling all the way down in the 68 | [CAMS GACF Download tab](https://ads.atmosphere.copernicus.eu/datasets/cams-global-atmospheric-composition-forecasts?tab=download): 69 | 70 | banner 71 | 72 | ## When should I use MERRA2 and when CAMS? 73 | 74 | We *do not* offer a comparison in terms of quality and precision of the two ancillary sources. The user is left 75 | to perform their own independent investigation. 76 | 77 | - Global MERRA2 hourly ancillary model data are not available until the calendar month following the model date. 78 | This may lead to a 401 error if you are trying to acquire MERRA2 data within the month being processed. In this situation 79 | the user should switch to using the ECMWF model or the default fall-back values based on best estimates. 80 | 81 | - On the other hand, even if ECMWF's CAMS-GACF dataset is a forecast source, temporary downfalls of the ECMWF API may occur. 82 | If your field acquisitions are older than a calendar month, and you are experiencing slow downloads, please consider switching to MERRA-2. 83 | 84 | - CAMS data are not available for field acquisitions done before 2015. 85 | 86 | ## What is the fallback in HyperCP in case ancillary information is missing? 87 | 88 | These ancillary data from models will be incorporated if field data are not available in the Ancillary file provided 89 | in the Main window. If field data and model data are both inaccessible for any reason, the system will use the Default 90 | values (i.e., Wind Speed, AOD, Salinity, and SST) provided in the L1BQC Configuration setup. -------------------------------------------------------------------------------- /README_bundle.md: -------------------------------------------------------------------------------- 1 | # HyperCP build executable 2 | 3 | ## Bundle HyperCP locally 4 | Install PyInstaller in your `hypercp` environment. Note that only version 6.0.0 of PyInstaller was tested. 5 | 6 | conda activate hypercp 7 | conda install --channel=conda-forge pyinstaller==6.0 8 | 9 | Bundle the application with: 10 | 11 | python make.py 12 | 13 | If the command is executed successfully, you will find an executable in the folder `hypercp/Bundled/dist/HyperCP-v{version}-{platform}`. Execute the bundled executable in your terminal or powershell on Windows to start HyperCP. 14 | 15 | On macOS the executable should work on both Intel and Apple Silicon processors despite the host used for bundling the application. However, this feature wasn't tested. 16 | 17 | These steps were tested on macOS Ventura, Sonoma, and Windows 10 only. The application is bundled automatically on Windows, macOS (Darwin), and Linux, when a commit is pushed to the master branch. 18 | 19 | ## Executing HyperCP bundle on macOS 20 | On macOS, bundled application are not signed, hence macOS Gatekeeper will raise a warning and prevent the application to run. The preferred workaround is to authorize the application to run. 21 | 22 | cd HyperCP-v1.2.0-Darwin 23 | sudo xattr -r -d com.apple.quarantine HyperCP-v1.2.0-Darwin 24 | sudo xattr -r -d com.apple.quarantine **/*.dylib 25 | sudo xattr -r -d com.apple.quarantine **/*.so 26 | 27 | Another workaround (not recommended) is to disable macOS Gatekeeper only during the time HyperCP is used. 28 | 29 | sudo spctl --master-disable 30 | 31 | When done running HyperCP do not forget to re-enable macOS Gatekeeper. 32 | 33 | sudo spctl --master-enable 34 | -------------------------------------------------------------------------------- /Source/CalibrationData.py: -------------------------------------------------------------------------------- 1 | 2 | import binascii 3 | import math 4 | import struct 5 | import sys 6 | 7 | class CalibrationData: 8 | ''' CalibrationData class stores information regarding the 9 | sensor definition lines and coefficients from the calibration file''' 10 | 11 | def __init__(self): 12 | self.type = "" 13 | self.id = "" 14 | self.units = "" 15 | self.fieldLength = 0 16 | self.dataType = "" 17 | self.calLines = 0 18 | self.fitType = "" 19 | self.coefficients = [] 20 | 21 | def printd(self): 22 | print("%s %s \'%s\' %d %s %d %s" % (self.type, self.id, self.units, 23 | self.fieldLength, self.dataType, 24 | self.calLines, self.fitType)) 25 | print("coefficients = ", self.coefficients) 26 | 27 | # Reads a sensor definition line from a cal file 28 | # Reference: (SAT-DN-00134_Instrument File Format.pdf) 29 | def read(self, line): 30 | parts = line.split() 31 | self.type = parts[0] 32 | self.id = parts[1] 33 | self.units = parts[2][1:-1] 34 | self.fieldLength = -1 if parts[3].upper() == 'V' else int(parts[3]) 35 | self.dataType = parts[4] 36 | self.calLines = int(parts[5]) 37 | self.fitType = parts[6] 38 | 39 | if self.type == 'POSITION': 40 | self.type = 'POINTING' 41 | self.id = 'ROTATOR' 42 | 43 | 44 | # Reads a coefficients line in the cal file 45 | # Notes: Does not support for OPTIC1, which uses 1-4 calibration lines 46 | def readCoefficients(self, line): 47 | self.coefficients = line.split() 48 | 49 | 50 | # Duplicates functionality of Python 3, int.from_bytes() for use in Python 2 51 | def intFromBytes(self, data, byteorder='big', signed=False): 52 | #print("Data",data) 53 | if byteorder == 'little': 54 | data = reversed(data) 55 | val = int(binascii.hexlify(data), 16) 56 | if signed: 57 | bits = 4 * (len(val) - 1) 58 | if val >= math.pow(2, bits-1): 59 | val = int(0 - (math.pow(2, bits) - val)) 60 | return val 61 | 62 | # Used when reading a raw file to convert binary data to correct type 63 | def convertRaw(self, b): 64 | v = 0 65 | dataType = self.dataType.upper() 66 | if dataType == "BU": 67 | if sys.version_info[0] < 3: 68 | v = self.intFromBytes(b, 'big', False) 69 | else: 70 | v = int.from_bytes(b, byteorder='big', signed=False) 71 | #print("bu", v) 72 | elif dataType == "BULE": 73 | if sys.version_info[0] < 3: 74 | v = self.intFromBytes(b, 'little', False) 75 | else: 76 | v = int.from_bytes(b, byteorder='little', signed=False) 77 | #print("bule", v) 78 | elif dataType == "BS": 79 | if sys.version_info[0] < 3: 80 | v = self.intFromBytes(b, 'big', True) 81 | else: 82 | v = int.from_bytes(b, byteorder='big', signed=True) 83 | #print("bs", v) 84 | elif dataType == "BSLE": 85 | if sys.version_info[0] < 3: 86 | v = self.intFromBytes(b, 'little', True) 87 | else: 88 | v = int.from_bytes(b, byteorder='little', signed=True) 89 | #print("bsle", v) 90 | elif dataType == "BF": 91 | 92 | ''' BUG: This is the PYROMETER, and it is not properly interpreted...''' 93 | 94 | v = struct.unpack("f", b)[0] 95 | #print("bf", v) 96 | elif dataType == "BD": 97 | v = struct.unpack("d", b)[0] 98 | #print("bd", v) 99 | elif dataType == "HS": 100 | v = int(b, 16) 101 | #print("hs", v) 102 | elif dataType == "HU": 103 | v = int(b, 16) 104 | #print("hu", v) 105 | elif dataType == "AI": 106 | if self.type.upper() == "NMEA_CHECKSUM": 107 | v = int(b, 16) 108 | else: 109 | v = int(b) 110 | #print("ai", v) 111 | elif dataType == "AU": 112 | v = int(b) 113 | #print("au", v) 114 | elif dataType == "AF": 115 | if len(b) == 0: 116 | v = float('nan') 117 | else: 118 | v = float(b) 119 | #print("af", v) 120 | elif dataType == "AS": 121 | #v = b.decode("utf-8") 122 | v = b 123 | #print("as", v) 124 | else: 125 | v = -1 126 | print("dataType unknown: ", dataType) 127 | return v 128 | 129 | -------------------------------------------------------------------------------- /Source/CalibrationFileReader.py: -------------------------------------------------------------------------------- 1 | '''Read in calibration and telemetry definition files''' 2 | import collections 3 | import os.path 4 | import shutil 5 | import zipfile 6 | 7 | from Source.CalibrationFile import CalibrationFile 8 | 9 | 10 | class CalibrationFileReader: 11 | '''Read in calibration and telemetry definition files. Return the calibrationMap.''' 12 | # reads calibration files stored in directory 13 | @staticmethod 14 | def read(fp): 15 | calibrationMap = collections.OrderedDict() 16 | 17 | for (dirpath, dirnames, filenames) in os.walk(fp): 18 | for name in filenames: 19 | #print("infile:", name) 20 | if name.lower().startswith("dalec"): 21 | cf = CalibrationFile() 22 | cf.id=name 23 | cf.name=os.path.join(dirpath,name) 24 | cf.instrumentType = "Dalec" 25 | calibrationMap[name] = cf 26 | elif os.path.splitext(name)[1].lower() == ".cal" or \ 27 | os.path.splitext(name)[1].lower() == ".tdf": 28 | with open(os.path.join(dirpath, name), 'rb') as f: 29 | cf = CalibrationFile() 30 | cf.read(f) 31 | #print("id:", cf.id) 32 | calibrationMap[name] = cf 33 | break 34 | 35 | return calibrationMap 36 | 37 | # reads calibration files stored in .sip file (renamed .zip) 38 | @staticmethod 39 | def readSip(fp): 40 | calibrationMap = collections.OrderedDict() 41 | 42 | with zipfile.ZipFile(fp, 'r') as zf: 43 | for finfo in zf.infolist(): 44 | if not str(finfo.filename).startswith('__MACOSX/'): 45 | print("infile:", finfo.filename) 46 | if os.path.splitext(finfo.filename)[1].lower() == ".cal" or \ 47 | os.path.splitext(finfo.filename)[1].lower() == ".tdf": 48 | with zf.open(finfo) as f: 49 | cf = CalibrationFile() 50 | cf.read(f) 51 | #print("id:", cf.id) 52 | calibrationMap[finfo.filename] = cf 53 | [dest,_] = os.path.split(fp) 54 | src = zf.extract(f.name,path=dest) 55 | [_,fname] = os.path.split(f.name) 56 | shutil.move(src, os.path.join(dest,fname)) 57 | 58 | return calibrationMap 59 | -------------------------------------------------------------------------------- /Source/FidradDB_api.py: -------------------------------------------------------------------------------- 1 | # from fidraddb_api.ocdb.api.OCDBApi import new_api, OCDBApi 2 | from ocdb.api.OCDBApi import new_api, OCDBApi 3 | import numpy as np 4 | import os 5 | 6 | def FidradDB_choose_cal_char_file(elem, acq_time, cal_char_candidates): 7 | 8 | if len(cal_char_candidates) == 0: 9 | return 10 | 11 | # Listening of the date versioning of filtered calibration files 12 | fileTimeStamps = np.array([int(os.path.basename(i).split('_')[-1].split('.')[0]) for i in cal_char_candidates]) 13 | 14 | cal_char_type = elem.split('_')[-1] 15 | 16 | if cal_char_type == 'RADCAL': 17 | # Selection of the closest calibration data file to the measuring date 18 | fileTimeStamp = min(fileTimeStamps, key=lambda x: abs(x - int(acq_time))) 19 | else: 20 | try: 21 | # Selection of the closest char data file PRE-EXISTING to the measuring date 22 | fileTimeStamp = np.max(fileTimeStamps[np.array(fileTimeStamps) < int(acq_time)]) 23 | except: 24 | # Selection of the closest char data file to the measuring date 25 | fileTimeStamp = min(fileTimeStamps, key=lambda x: abs(x - int(acq_time))) 26 | # Selection of the corresponding calibration file 27 | matching = [s for s in cal_char_candidates if str(fileTimeStamp) in os.path.basename(s)][0] 28 | 29 | return matching 30 | 31 | def FidradDB_api(elem, acq_time, cal_path): 32 | 33 | #api server_url configuration 34 | api = new_api(server_url='https://ocdb.eumetsat.int') 35 | 36 | #FidradDB connection and listing all files for input instrument (serial number + type) 37 | cal_char_candidates = OCDBApi.fidrad_list_files(api,elem) 38 | 39 | matching = FidradDB_choose_cal_char_file(elem, acq_time, cal_char_candidates) 40 | 41 | if not matching: 42 | print('Sensor %s: %s file not found. Skipping FidRadBD search...' % tuple(elem.split('_'))) 43 | return 44 | 45 | # Download from FidRadDB of the selected file 46 | try: 47 | OCDBApi.fidrad_download_file(api, matching, cal_path) 48 | except: 49 | raise ConnectionError('Unable to download file from FidRadDB. Check your internet connection. ' 50 | 'If problem persists, provide cal/char file manually.') 51 | 52 | return None 53 | -------------------------------------------------------------------------------- /Source/FieldPhotos.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | import glob 4 | import datetime 5 | import pytz 6 | from PyQt5 import QtCore, QtWidgets 7 | from PyQt5.QtGui import QPixmap 8 | 9 | 10 | class FieldPhotos(QtWidgets.QDialog): 11 | 12 | def __init__(self, photoPath, photoDT, parent=None): 13 | # Paths and DTs are lists of photos/datetimes within the time limit 14 | super().__init__(parent) 15 | self.setModal(True) 16 | self.photoPath = photoPath 17 | self.photoDT = photoDT 18 | self.left = 300 19 | self.top = 300 20 | self.width = 800 21 | self.height = 820 22 | self.imageSelect = 0 23 | 24 | self.initUI() 25 | 26 | def initUI(self): 27 | self.setWindowTitle(f'{self.photoDT[0]} {os.path.split(self.photoPath[self.imageSelect])[-1]}') 28 | self.setGeometry(self.left, self.top, self.width, self.height) 29 | 30 | # Create widgets ############################ 31 | self.fieldPhoto = QtWidgets.QLabel(self) 32 | # Set initial photo 33 | self.pixmap = QPixmap(self.photoPath[self.imageSelect]) 34 | self.pixmapScaled = self.pixmap.scaled(800,800,QtCore.Qt.KeepAspectRatio) 35 | self.fieldPhoto.setPixmap(self.pixmapScaled) 36 | # self.fieldPhoto.move(0,50) # Since Layouts won't work in VBox, move down to make space 37 | 38 | labelNote = QtWidgets.QLabel('Close this window to continue.', self) 39 | listLabel = QtWidgets.QLabel(\ 40 | f'Number of images found within 90 mins of data: {len(self.photoPath)} ', self) 41 | 42 | self.nextButton = QtWidgets.QPushButton('>') 43 | self.nextButton.setToolTip('Next image in list') 44 | 45 | self.previousButton = QtWidgets.QPushButton('<') 46 | self.previousButton.setToolTip('Previous image in list') 47 | self.nextButton.clicked.connect(lambda: self.updateImagePressed('next')) 48 | self.previousButton.clicked.connect(lambda: self.updateImagePressed('previous')) 49 | 50 | # Setup Layout ################################## 51 | VBox = QtWidgets.QVBoxLayout() 52 | VBox.addWidget(self.fieldPhoto) 53 | 54 | HBox = QtWidgets.QHBoxLayout() 55 | HBox.addWidget(listLabel) 56 | HBox.addWidget(self.previousButton) 57 | HBox.addWidget(self.nextButton) 58 | HBox.addWidget(labelNote) 59 | VBox.addLayout(HBox) 60 | 61 | self.updateImagePressed('first') 62 | 63 | self.setLayout(VBox) 64 | 65 | def updateImagePressed(self, direction): 66 | print(f'Display {direction} image: {self.photoPath[self.imageSelect]}') 67 | 68 | if direction == 'next': 69 | self.imageSelect += 1 70 | if direction == 'previous': 71 | self.imageSelect -= 1 72 | 73 | if self.imageSelect == 0: 74 | self.previousButton.setDisabled(True) 75 | else: 76 | self.previousButton.setDisabled(False) 77 | 78 | if self.imageSelect == len(self.photoPath)-1: 79 | self.nextButton.setDisabled(True) 80 | else: 81 | self.nextButton.setDisabled(False) 82 | 83 | # Set photo 84 | self.pixmap = QPixmap(self.photoPath[self.imageSelect]) 85 | self.pixmapScaled = self.pixmap.scaled(800,800,QtCore.Qt.KeepAspectRatio) 86 | self.fieldPhoto.setPixmap(self.pixmapScaled) 87 | # # self.fieldPhoto.move(0,100) 88 | 89 | self.setWindowTitle(f'{self.photoDT[self.imageSelect]} {os.path.split(self.photoPath[self.imageSelect])[-1]}') 90 | 91 | @staticmethod 92 | def photoSetup(inPath, start, end, format='IMG_%Y%m%d_%H%M%S.jpg', tz='+0000'): 93 | ''' Use the start and end datetimes of the L1C file and the 94 | names of the photo files to find a photo within a certain 95 | amount of time of the data file. tz is the timezone of the 96 | photo name. 97 | ''' 98 | 99 | # Time difference limit between photo and data: 100 | tDiffLim = datetime.timedelta(minutes = 90) 101 | 102 | # Could either find the nearest, or find one in the data interval... 103 | midDatetime = start + (end-start)/2 104 | 105 | extension = format.split('.')[1] 106 | fileList = glob.glob(os.path.join(inPath,f'*.{extension}')) 107 | if len(fileList) > 0: 108 | 109 | # dFormat = 'IMG_%Y%m%d_%H%M%S.jpg' 110 | dFormat = f"{format.split('.')[0]}%z" # tack on the time zone below 111 | dFormatAlt = f"{format.split('.')[0]}%f%z" # for case with microseconds 112 | # picDateTime = [] 113 | picList = [] 114 | picDTList = [] 115 | for fp in fileList: 116 | fileName = os.path.split(fp)[-1] 117 | fileName = fileName.split('.')[0]+tz 118 | try: 119 | dT = datetime.datetime.strptime(fileName, dFormat) 120 | # picDateTime.append(dT.astimezone(pytz.utc)) 121 | picDateTime = dT.astimezone(pytz.utc) 122 | # tDiff = abs(picDateTime-midDatetime).seconds / 60 123 | tDiff = abs(picDateTime-midDatetime) 124 | if tDiff < tDiffLim: 125 | picList.append(fp) 126 | picDTList.append(picDateTime) 127 | except Exception: 128 | try: 129 | dT = datetime.datetime.strptime(fileName, dFormatAlt) 130 | # picDateTime.append(dT.astimezone(pytz.utc)) 131 | picDateTime = dT.astimezone(pytz.utc) 132 | # tDiff = abs(picDateTime-midDatetime).seconds / 60 133 | tDiff = abs(picDateTime-midDatetime) 134 | if tDiff < tDiffLim: 135 | picList.append(fp) 136 | picDTList.append(picDateTime) 137 | except Exception: 138 | print(f'This file does not match the format. Rename or update format in AnomAnal GUI. {fileName}') 139 | 140 | 141 | if len(picList) > 0: 142 | return picList, picDTList 143 | else: 144 | return None, None 145 | 146 | else: 147 | print("None found") 148 | return None, None -------------------------------------------------------------------------------- /Source/HDFGroup.py: -------------------------------------------------------------------------------- 1 | 2 | import collections 3 | import sys 4 | import h5py 5 | import numpy as np 6 | 7 | from Source.HDFDataset import HDFDataset 8 | 9 | class HDFGroup: 10 | def __init__(self): 11 | self.id = "" 12 | self.datasets = collections.OrderedDict() 13 | self.attributes = collections.OrderedDict() 14 | 15 | def copy(self, gp): 16 | self.copyAttributes(gp) 17 | for k, ds in gp.datasets.items(): 18 | newDS = self.addDataset(ds.id) 19 | newDS.copy(ds) 20 | 21 | def copyAttributes(self, gp): 22 | for k,v in gp.attributes.items(): 23 | self.attributes[k] = v 24 | 25 | def datasetDeleteRow(self, i): 26 | for k in self.datasets: 27 | ds = self.datasets[k] 28 | ds.data = np.delete(ds.data, (i), axis=0) 29 | 30 | def removeDataset(self, name): 31 | if len(name) == 0: 32 | print("Name is 0") 33 | return False 34 | ds = self.getDataset(name) 35 | if ds is not None: 36 | del self.datasets[name] 37 | return True 38 | else: 39 | print("dataset does not exist") 40 | return False 41 | 42 | def addDataset(self, name): 43 | if len(name) == 0: 44 | print("Name is 0") 45 | exit(1) 46 | ds = None 47 | if not self.getDataset(name): 48 | ds = HDFDataset() 49 | ds.id = name 50 | self.datasets[name] = ds 51 | return ds 52 | 53 | def getDataset(self, name): 54 | if name in self.datasets: 55 | return self.datasets[name] 56 | return None 57 | 58 | def getTableHeader(self, name): 59 | ''' Generates Head attributes''' 60 | # ToDo: This should get generated from context file instead 61 | if name != "None": 62 | cnt = 1 63 | ds = self.getDataset(name) 64 | if ds is None: 65 | ds = self.addDataset(name) 66 | for item in ds.columns: 67 | self.attributes["Head_"+str(cnt)] = name + " 1 1 " + item 68 | cnt += 1 69 | 70 | def printd(self): 71 | print("Group:", self.id) 72 | #print("Sensor Type:", self.sensorType) 73 | 74 | if "FrameType" in self.attributes: 75 | print("Frame Type:", self.attributes["FrameType"]) 76 | else: 77 | print("Frame Type not found") 78 | 79 | for k in self.attributes: 80 | print("Attribute:", k, self.attributes[k]) 81 | # attr.printd() 82 | #for gp in self.groups: 83 | # gp.printd() 84 | for k in self.datasets: 85 | ds = self.datasets[k] 86 | ds.printd() 87 | 88 | def read(self, f): 89 | name = f.name[f.name.rfind("/")+1:] 90 | self.id = name 91 | 92 | # Read attributes 93 | #print("Attributes:", [k for k in f.attrs.keys()]) 94 | for k in f.attrs.keys(): 95 | if type(f.attrs[k]) == np.ndarray: # noqa: E721 96 | self.attributes[k] = f.attrs[k] 97 | else: # string attribute 98 | self.attributes[k] = f.attrs[k].decode("utf-8") 99 | # Read datasets 100 | for k in f.keys(): 101 | item = f.get(k) 102 | if isinstance(item, h5py.Group): 103 | print("HDFGroup should not contain groups") 104 | elif isinstance(item, h5py.Dataset): 105 | #print("Item:", k) 106 | ds = HDFDataset() 107 | self.datasets[k] = ds 108 | ds.read(item) 109 | 110 | def write(self, f): 111 | #print("Group:", self.id) 112 | try: 113 | f = f.create_group(self.id) 114 | # Write attributes 115 | for k in self.attributes: 116 | f.attrs[k] = np.string_(self.attributes[k]) 117 | # Write datasets 118 | for key,ds in self.datasets.items(): 119 | #f.create_dataset(ds.id, data=np.asarray(ds.data)) 120 | ds.write(f) 121 | except: 122 | e = sys.exc_info()[0] 123 | print(e) 124 | -------------------------------------------------------------------------------- /Source/HDFRoot.py: -------------------------------------------------------------------------------- 1 | 2 | import collections 3 | import h5py 4 | import numpy as np 5 | 6 | from Source.HDFGroup import HDFGroup 7 | from Source.HDFDataset import HDFDataset 8 | 9 | class HDFRoot: 10 | def __init__(self): 11 | self.id = "" 12 | self.groups = [] 13 | self.datasets = [] 14 | self.attributes = collections.OrderedDict() 15 | 16 | def copy(self, node): 17 | self.copyAttributes(node) 18 | for gp in node.groups: 19 | newGP = self.addGroup(gp.id) 20 | newGP.copy(gp) 21 | 22 | def copyAttributes(self, node): 23 | for k,v in node.attributes.items(): 24 | self.attributes[k] = v 25 | 26 | def addGroup(self, name): 27 | gp = self.getGroup(name) 28 | if not gp: 29 | gp = HDFGroup() 30 | gp.id = name 31 | self.groups.append(gp) 32 | return gp 33 | 34 | def getGroup(self, name): 35 | for gp in self.groups: 36 | if gp.id == name: 37 | return gp 38 | return None 39 | 40 | def removeGroup(self, name): 41 | gp = name 42 | if gp: 43 | self.groups.remove(gp) 44 | 45 | def getDataset(self, name): 46 | if name in self.datasets: 47 | return self.datasets[name] 48 | return None 49 | 50 | def printd(self): 51 | print("Root:", self.id) 52 | #print("Processing Level:", self.processingLevel) 53 | #for k in self.attributes: 54 | # print("Attribute:", k, self.attributes[k]) 55 | for gp in self.groups: 56 | gp.printd() 57 | 58 | @staticmethod 59 | def readHDF5(fp): 60 | root = HDFRoot() 61 | with h5py.File(fp, "r") as f: 62 | 63 | # set name to text after last '/' 64 | name = f.name[f.name.rfind("/")+1:] 65 | if len(name) == 0: 66 | name = "/" 67 | root.id = name 68 | 69 | # Read attributes 70 | #print("Attributes:", [k for k in f.attrs.keys()]) 71 | for k in f.attrs.keys(): 72 | # Need to check values for non-character encoding 73 | value = f.attrs[k] 74 | if value.__class__ is np.ndarray: 75 | root.attributes[k] = value 76 | else: 77 | root.attributes[k] = f.attrs[k].decode("utf-8") 78 | # Use the following when using h5toh4 converter: 79 | #root.attributes[k.replace("__GLOSDS", "")] = f.attrs[k].decode("utf-8") 80 | # Read groups 81 | for k in f.keys(): 82 | item = f.get(k) 83 | #print(item) 84 | if isinstance(item, h5py.Group): 85 | gp = HDFGroup() 86 | root.groups.append(gp) 87 | gp.read(item) 88 | elif isinstance(item, h5py.Dataset): 89 | # print("HDFRoot should not contain datasets") 90 | ds = HDFDataset() 91 | root.datasets.append(ds) 92 | ds.read(item) 93 | 94 | return root 95 | 96 | # Writing to HDF5 file 97 | def writeHDF5(self, fp): 98 | with h5py.File(fp, "w") as f: 99 | #print("Root:", self.id) 100 | # Write attributes 101 | for k in self.attributes: 102 | f.attrs[k] = np.string_(self.attributes[k]) 103 | # h5toh4 converter requires "__GLOSDS" to be appended 104 | # to attribute name for it to be recognized correctly: 105 | #f.attrs[k+"__GLOSDS"] = np.string_(self.attributes[k]) 106 | # Write groups 107 | for gp in self.groups: 108 | gp.write(f) 109 | -------------------------------------------------------------------------------- /Source/L2avw.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | import scipy 4 | 5 | def L2avw(wavelength, Rrs): 6 | ''' Use hyperspectral Rrs to calculate average visible wavelength. Vectorwise.''' 7 | # Inputs: 8 | # wavelength: vector of length Rrs or array of shape Rrs 9 | # Rrs: array of shape wavelength X n 10 | 11 | # Truncate to the VIS 12 | lims = [400, 701] 13 | # outIndex = [] 14 | # for i, wl in enumerate(wavelength): 15 | # if wl < lims[0] or wl > lims[-1]: 16 | # outIndex.append(i) 17 | 18 | # wavelength = np.delete(wavelength, outIndex) 19 | # Rrs = np.delete(Rrs, outIndex, axis = 0) 20 | 21 | if np.shape(wavelength) != np.shape(Rrs): 22 | wavelength = np.transpose(np.matlib.repmat(wavelength,np.shape(Rrs)[1],1)) 23 | 24 | wave_1nm = np.arange(lims[0], lims[1]) 25 | Rrs_1nm = np.empty([wave_1nm.shape[0],Rrs.shape[1]]) 26 | 27 | for i in np.arange(0,Rrs.shape[1]): 28 | Rrs_1nm[:,i] = scipy.interpolate.interp1d(wavelength[:,i], Rrs[:,i], kind='linear', bounds_error=True)(wave_1nm) 29 | 30 | wave_1nm = np.tile(wave_1nm,(Rrs.shape[1],1)) 31 | wave_1nm = np.rot90(wave_1nm,3) 32 | avw = np.sum( Rrs_1nm / np.sum( Rrs_1nm/wave_1nm, axis = 0) , axis = 0).tolist() 33 | lambda_max = wave_1nm[np.argmax(Rrs_1nm, axis=0), 0].tolist() 34 | brightness = np.trapz(Rrs_1nm, wave_1nm, axis=0).tolist() 35 | 36 | return avw, lambda_max, brightness 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Source/L2chlor_a.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | 4 | def L2chlor_a(Rrs443, Rrs488, Rrs547, Rrs555, Rrs667): 5 | ''' Use weighted MODIS Aqua bands to calculate chlorophyll concentration 6 | using oc3m blended algorithm with CI (Hu et al. 2012) ''' 7 | 8 | thresh = [0.15, 0.20] 9 | a0 = 0.2424 10 | a1 = -2.7423 11 | a2 = 1.8017 12 | a3 = 0.0015 13 | a4 = -1.2280 14 | 15 | ci1 = -0.4909 16 | ci2 = 191.6590 17 | 18 | if Rrs443 > Rrs488: 19 | Rrsblue = Rrs443 20 | else: 21 | Rrsblue = Rrs488 22 | 23 | log10chl = a0 + a1 * (np.log10(Rrsblue / Rrs547)) \ 24 | + a2 * (np.log10(Rrsblue / Rrs547))**2 \ 25 | + a3 * (np.log10(Rrsblue / Rrs547))**3 \ 26 | + a4 * (np.log10(Rrsblue / Rrs547))**4 27 | 28 | oc3m = np.power(10, log10chl) 29 | 30 | CI = Rrs555 - ( Rrs443 + (555 - 443)/(667 - 443) * \ 31 | (Rrs667 -Rrs443) ) 32 | 33 | ChlCI = 10** (ci1 + ci2*CI) 34 | 35 | if ChlCI <= thresh[0]: 36 | chlor_a = ChlCI 37 | elif ChlCI > thresh[1]: 38 | chlor_a = oc3m 39 | else: 40 | chlor_a = oc3m * (ChlCI-thresh[0]) / (thresh[1]-thresh[0]) +\ 41 | ChlCI * (thresh[1]-ChlCI) / (thresh[1]-thresh[0]) 42 | 43 | return chlor_a 44 | 45 | -------------------------------------------------------------------------------- /Source/L2gocad.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | 4 | def L2gocad(Rrs443, Rrs488, Rrs531, Rrs547, SAL, fill=-9999): 5 | ''' Use weighted MODIS Aqua bands to calculate CDOM absorption, spectral 6 | slopes, and DOC based on 7 | 8 | D. Aurin, A. Mannino, and D. J. Lary, “Remote sensing of CDOM, CDOM 9 | spectral slope, and dissolved organic carbon in the global ocean,” Appl. 10 | Sci. 8, 2687 (2018). 11 | 12 | Inputs: 13 | RrsXXX: (float) above water remote sensing reflectance at XXX nm 14 | SAL: (float) sea surface salinity 15 | fill: value substituted for failed retrieval 16 | 17 | Outputs: 18 | ag: (array) CDOM at 275, 355, 380, 412, 443, 488 nm 19 | Sg: (array) CDOM slope at 275-295, 300-600, 412-600 nm 20 | 21 | 22 | 2020-07-01: by Dirk Aurin, NASA Goddard Space Flight Center, dirk.a.aurin@nasa.gov 23 | ''' 24 | 25 | n_spectra = len(Rrs443) 26 | 27 | # CDOM 28 | waveOut = ['275','355','380','412','443','488'] 29 | n_bands = len(waveOut) 30 | #Thresholds based on 99%ile (2nd iteration) see MLR_stats.m 31 | # Note: these were run on L3 Aqua using the MLR 3-band algorithm, and could use updating 32 | ag_lim = np.array([4.8245,0.9104,0.4341,0.36419,0.1984,0.1114]) 33 | 34 | beta = np.array([[0.0885, -0.5396, -1.1416, 3.4442, -1.8752], \ 35 | [-2.2461, -1.1857, -0.5582, 2.9123, -1.3356], \ 36 | [-2.2625, -0.3001, -1.8819, 3.8314, -1.7868], \ 37 | [-2.5350, -0.5625, -1.2943, 1.6055, 0.1697], \ 38 | [-3.2872, -0.7268, -0.9223, 1.2782, 0.2612], \ 39 | [-3.7218, -0.3770, -1.4287, 1.4239, 0.2998]]) 40 | ag = np.empty([n_spectra, n_bands]) 41 | for n in range(0, n_bands): 42 | ag[:,n] = np.exp( beta[n,0] + beta[n,1]*np.log(Rrs443) + beta[n,2]* np.log(Rrs488) + \ 43 | beta[n,3]*np.log(Rrs531) + beta[n,4]*np.log(Rrs547) ) 44 | 45 | for n in range(0, n_spectra): 46 | ag[n, ag[n,:] > ag_lim] = fill 47 | 48 | 49 | # Sg 50 | BANDS = [275, 300, 350, 380, 412] # 275-295, 300-600, 350-600, 380-600, 412-600 51 | n_bands = len(BANDS) 52 | # These are the 2nd and 98th percentiles of GOCAD 53 | sg_lim = np.array([[0.0169, 0.0445], [0.0159, 0.0255], [0.0119, 0.0200], [0.0107, 0.0194], [0.0059, 0.0188]]) 54 | 55 | beta = np.array([[-3.2892, 0.2697, -0.3346, 1.0507, -0.9211], \ 56 | [-3.6065, 0.0439, -0.1533, 0.8810, -0.7215], \ 57 | [-3.9083, -0.2039, 0.0979, 0.6092, -0.4633], \ 58 | [-3.9116, -0.1519, 0.1272, 0.2360, -0.1731], \ 59 | [-4.2190, -0.1799, 0.1366, 0.1676, -0.1311]]) 60 | Sg = np.empty([n_spectra, n_bands]) 61 | for n in range(0, n_bands): 62 | Sg[:,n] = np.exp( beta[n,0] + beta[n,1]*np.log(Rrs443) + beta[n,2]* np.log(Rrs488) + \ 63 | beta[n,3]*np.log(Rrs531) + beta[n,4]*np.log(Rrs547) ) 64 | 65 | # Set Sg outside limits to thresholds 66 | for n in range(0, n_spectra): 67 | Sg[n, Sg[n,:] < sg_lim[:,0]] = sg_lim[Sg[n,:] < sg_lim[:,0],0] 68 | Sg[n, Sg[n,:] > sg_lim[:,1]] = sg_lim[Sg[n,:] > sg_lim[:,1],1] 69 | 70 | 71 | # DOC (MLR2) 72 | beta = [192.718, 26.790, -3.558] 73 | # # These are the 2nd and 98th percentiles of GOCAD 74 | doc_lim = [47.2383, 223.7900] 75 | 76 | doc = np.empty([n_spectra, ]) 77 | for n in range(0, n_spectra): 78 | doc[n] = beta[0] + beta[1] * ag[n,2] + beta[2] * SAL[n] 79 | 80 | for n in range(0, n_spectra): 81 | if doc[n] < doc_lim[0] or doc[n] > doc_lim[1]: 82 | doc[n] = fill 83 | 84 | 85 | return ag, Sg, doc 86 | 87 | -------------------------------------------------------------------------------- /Source/L2ipar.py: -------------------------------------------------------------------------------- 1 | 2 | from Source.Utilities import Utilities 3 | 4 | def L2ipar(wavelength, Es, fullSpec): 5 | ''' Use hyperspectral irradiance to calculate instantaneous photosynthetically 6 | available radiation in Einstein m^-2''' 7 | 8 | # ipar 9 | unitc = 119.625e8 10 | 11 | Es_n = Utilities.interp(wavelength, Es, fullSpec) 12 | ipar = 0.0 13 | for i, wl in enumerate(fullSpec): 14 | ipar += (wl * Es_n[i] / unitc ) 15 | 16 | return ipar 17 | 18 | -------------------------------------------------------------------------------- /Source/L2kd490.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | 4 | def L2kd490(Rrs488, Rrs547): 5 | ''' Use weighted MODIS Aqua bands to calculate diffuse attenuation 6 | coefficient of downwelling irradiance at 490 ''' 7 | 8 | Rrs488 = np.array(Rrs488) 9 | Rrs547 = np.array(Rrs547) 10 | 11 | a0 = -0.8813 12 | a1 = -2.0584 13 | a2 = 2.5878 14 | a3 = -3.4885 15 | a4 = -1.5061 16 | 17 | log10kd = a0 + a1 * (np.log10(Rrs488 / Rrs547)) \ 18 | + a2 * (np.log10(Rrs488 / Rrs547))**2 \ 19 | + a3 * (np.log10(Rrs488 / Rrs547))**3 \ 20 | + a4 * (np.log10(Rrs488 / Rrs547))**4 21 | kd490 = np.power(10, log10kd) + 0.0166 22 | 23 | return kd490 24 | 25 | -------------------------------------------------------------------------------- /Source/L2par.py: -------------------------------------------------------------------------------- 1 | 2 | from Source.ConfigFile import ConfigFile 3 | 4 | class L2par(): 5 | 6 | @staticmethod 7 | def L2par(root): 8 | ''' Use weighted MODIS Aqua bands to calculate photosynthetically available radiation in Einstein m^-2 d^-1''' 9 | 10 | Reflectance = root.getGroup("REFLECTANCE") 11 | 12 | # par 13 | if ConfigFile.products["bL2Prodpar"]: 14 | 15 | dateTime = Reflectance.datasets['Rrs_HYPER'].columns['Datetime'] 16 | dateTag = Reflectance.datasets['Rrs_HYPER'].columns['Datetag'] 17 | timeTag2 = Reflectance.datasets['Rrs_HYPER'].columns['Timetag2'] 18 | 19 | prodGroup = root.getGroup('DERIVED_PRODUCTS') 20 | parDS = prodGroup.addDataset('par') 21 | prodGroup.attributes['par_UNITS'] = 'Einstein m^-2 d^-1' 22 | parDS.columns['Datetime'] = dateTime 23 | parDS.columns['Datetag'] = dateTag 24 | parDS.columns['Timetag2'] = timeTag2 25 | 26 | Rrs443 = Reflectance.datasets["Rrs_MODISA"].columns['443'] 27 | Rrs469 = Reflectance.datasets["Rrs_MODISA"].columns['469'] 28 | Rrs555 = Reflectance.datasets["Rrs_MODISA"].columns['555'] 29 | 30 | # probably not practical 31 | par = [] 32 | 33 | 34 | parDS.columns['par'] = par.tolist() 35 | parDS.columnsToDataset() 36 | 37 | -------------------------------------------------------------------------------- /Source/L2pic.py: -------------------------------------------------------------------------------- 1 | 2 | def L2pic(root): 3 | ''' Use weighted MODIS Aqua bands to calculate particulate inorganic carbon in mol m^-3 ''' 4 | 5 | # 2-band approach 6 | # Requires a LUT 7 | 8 | # 3- band approach 9 | # Requires iteration 10 | pic = [] 11 | return pic 12 | 13 | -------------------------------------------------------------------------------- /Source/L2poc.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | 4 | def L2poc(Rrs443, Rrs555): 5 | ''' Use weighted MODIS Aqua bands to calculate particulate organic carbon in mg m^-3 ''' 6 | 7 | Rrs443 = np.array(Rrs443) 8 | Rrs555 = np.array(Rrs555) 9 | 10 | a = 203.2 11 | b = -1.034 12 | 13 | poc = a * (Rrs443/Rrs555)**b 14 | 15 | return poc -------------------------------------------------------------------------------- /Source/L2qaa.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | 4 | from Source import PATH_TO_DATA 5 | from Source.Water_IOPs import water_iops 6 | 7 | 8 | def L2qaa(Rrs412, Rrs443, Rrs488, Rrs555, Rrs667, RrsHyper, wavelength, SST, SAL): 9 | ''' Use weighted MODIS Aqua bands to calculate IOPs using 10 | QAA_v6 11 | 12 | Inputs: 13 | RrsXXX: (float) above water remote sensing reflectance at XXX nm 14 | RrsHyper: (1D numpy array) hyperspectral above water remote sensing reflectance 15 | wavelength: (1D array) length of RrsHyper; will be truncated to Pope&Fry/Smith&Baker pure water 16 | T: (float) sea surface temperature 17 | S: (float) sea surface salinity 18 | 19 | Outputs: 20 | a, adg, aph, b, bb, bbp, c: (1D lists) hyperspectral inherent optical properties 21 | 22 | # eta: powerlaw slope of bbp 23 | # S: CDOM base slope''' 24 | 25 | # Adjustable empirical coefficient set-up. Many coefficients remain hard 26 | # coded as in SeaDAS qaa.c 27 | 28 | # Maximum range based on P&F/S&B 29 | minMax = [380, 800] 30 | if min(wavelength) < minMax[0] or max(wavelength) > minMax[1]: 31 | waveTemp = [] 32 | RrsHyperTemp = [] 33 | for i, wl in enumerate(wavelength): 34 | if wl >= minMax[0] and wl <= minMax[1]: 35 | waveTemp.append(wl) 36 | RrsHyperTemp.append(RrsHyper[i]) 37 | wavelength = np.array(waveTemp) 38 | RrsHyper = np.array(RrsHyperTemp) 39 | 40 | # Screen hyperspectral Rrs for zeros 41 | RrsHyper[RrsHyper < 1e-5] = 1e-5 42 | 43 | # Step 1 44 | g0 = 0.08945 45 | g1 = 0.1247 46 | # Step 2 47 | h0 = -1.146 48 | h1 = -1.366 49 | h2 = -0.469 50 | # Step 8 51 | S = 0.015 # baseline slope 52 | 53 | # Pure seawater. Pope & Fry adjusted for S&T using Sullivan et al. 2006. 54 | # (Now considering using inverted values from Lee et al. 2015...) 55 | fp = os.path.join(PATH_TO_DATA, 'Water_Absorption.sb') # <--- Set path to P&F water 56 | a_sw412, bb_sw412 = water_iops(fp, [412], SST, SAL) 57 | a_sw443, bb_sw443 = water_iops(fp, [443], SST, SAL) 58 | a_sw555, bb_sw555 = water_iops(fp, [555], SST, SAL) 59 | a_sw667, bb_sw667 = water_iops(fp, [667], SST, SAL) 60 | a_sw, bb_sw = water_iops(fp, wavelength, SST, SAL) 61 | 62 | 63 | msg = [] 64 | # Pretest on Rrs(670) from QAAv5 65 | if Rrs667 > 20 * np.power(Rrs555, 1.5) or \ 66 | Rrs667 < 0.9 * np.power(Rrs555, 1.7): 67 | 68 | msg1 = "L2qaa: Rrs(667) out of bounds, adjusting." 69 | print(msg1) 70 | msg.append(msg1) 71 | 72 | Rrs667 = 1.27 * np.power(Rrs555, 1.47) + 0.00018 * np.power(Rrs488/Rrs555, -3.19) 73 | 74 | 75 | # Step 0 76 | rrs = RrsHyper / (0.52 + 1.7 * RrsHyper) 77 | rrs412 = Rrs412 / (0.52 + 1.7 * Rrs412) 78 | rrs443 = Rrs443 / (0.52 + 1.7 * Rrs443) 79 | rrs488 = Rrs488 / (0.52 + 1.7 * Rrs488) 80 | rrs555 = Rrs555 / (0.52 + 1.7 * Rrs555) 81 | rrs667 = Rrs667 / (0.52 + 1.7 * Rrs667) 82 | 83 | # Step 1 84 | u = (np.sqrt(g0*g0 + 4.0 * g1 * rrs) - g0) / (2.0 * g1) 85 | u412 = (np.sqrt(g0*g0 + 4.0 * g1 * rrs412) - g0) / (2.0 * g1) 86 | u443 = (np.sqrt(g0*g0 + 4.0 * g1 * rrs443) - g0) / (2.0 * g1) 87 | u555 = (np.sqrt(g0*g0 + 4.0 * g1 * rrs555) - g0) / (2.0 * g1) 88 | u667 = (np.sqrt(g0*g0 + 4.0 * g1 * rrs667) - g0) / (2.0 * g1) 89 | 90 | # Switch, Step 2 91 | if Rrs667 < 0.0015: 92 | chi = np.log10( (rrs443 + rrs488) / (rrs555 + 5 * rrs667/rrs488 * rrs667) ) 93 | lamb0 = 555 94 | a555 = a_sw555 + np.power(10.0, (h0 + h1*chi + h2*chi*chi)) 95 | 96 | # Step 3 97 | bbp0 = u555*a555 / (1 - u555) - bb_sw555 98 | 99 | else: 100 | lamb0 = 667 101 | a667 = np.power(a_sw667 + 0.39*( Rrs667 / (Rrs443 + Rrs488) ), 1.14) 102 | 103 | # Step 3 104 | bbp0 = u667*a667 / (1 - u667) - bb_sw667 105 | 106 | # Step 4 107 | eta = 2*( 1 - 1.2 * np.exp( -0.9*rrs443/rrs555 )) 108 | 109 | # Step 5 110 | bbp = bbp0 * np.power(( lamb0 / wavelength ), eta) 111 | bb = bbp + bb_sw 112 | bbp412 = bbp0 * np.power(( lamb0 / 412 ), eta) 113 | bbp443 = bbp0 * np.power(( lamb0 / 443 ), eta) 114 | 115 | # Step 6 116 | a = (1 - u) * bb / u 117 | a412 = (1 - u412) * ( bb_sw412 + bbp412 ) / u412 118 | a443 = (1 - u443) * ( bb_sw443 + bbp443 ) / u443 119 | 120 | # Step 7 121 | zeta = 0.74 + ( 0.2 / ( 0.8 + rrs443/rrs555 ) ) 122 | 123 | # Step 8 124 | S1 = S + ( 0.002 / (0.6 + rrs443/rrs555) ) 125 | xi = np.exp( S1 * (443 - 412)) 126 | 127 | #Step 9 128 | ag443 = ( a412 - zeta * a443 ) / (xi - zeta) - ( a_sw412 - zeta * a_sw443 ) / ( xi - zeta) 129 | 130 | # Step 10 131 | adg = ag443 * np.exp( -S1 * (wavelength - 443)) 132 | aph = a - adg - a_sw 133 | 134 | b = 2.0 * bb 135 | c = a + b 136 | 137 | return a, adg, aph, b, bb, bbp, c, msg 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /Source/L2qwip.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | from Source.Utilities import Utilities 4 | 5 | 6 | def L2qwip(wavelength, Rrs, avw): 7 | ''' Use hyperspectral Rrs to calculate average visible wavelength. Vectorwise.''' 8 | # Function adapted from 2D image-based approach of RV by DAA: 2022-03-29 9 | # 10 | # Rrs is an mxn array where n is the number of spectra to be 11 | # evaluated as a group and m is the length of wavelength. AVW has n values. 12 | # 13 | # Updated for DESIS 2022-03-28: DAA 14 | # Converted to python DA 2022-05-10: DAA 15 | 16 | n = Rrs.shape[1] 17 | AVW = np.array(avw) 18 | # Interpolation to QWIP/QCI bands, which are representative of several missions 19 | test_lambda = np.array([490, 665]) 20 | test_Rrs = np.empty([len(test_lambda), n]) * np.nan 21 | for i in np.arange(0,n): 22 | test_Rrs[:,i] = Utilities.interp(wavelength.tolist(), Rrs[:,i].tolist(), test_lambda.tolist()) 23 | 24 | QCI = (test_Rrs[1,:] - test_Rrs[0,:])/(test_Rrs[1,:] + test_Rrs[0,:]) 25 | p = [-8.399885e-09,1.715532e-05,-1.301670e-02,4.357838,-5.449532e02] 26 | 27 | # Just generating an array here of the "predicted" QCI based on the AVW 28 | # image values. We then subtract this from the actual QCI that we 29 | # calculate above, and get an pixel by pixel QWIP score. 30 | QCI_pred = p[0]*AVW**4 + p[1]*AVW**3 + p[2]*AVW**2 + p[3]*AVW**1 + p[4] 31 | QWIP_score = QCI_pred-QCI 32 | abs_QWIP_score = abs(QWIP_score) 33 | 34 | return abs_QWIP_score 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Source/MainConfig.py: -------------------------------------------------------------------------------- 1 | '''Establish class to hold Main window configurations''' 2 | import os 3 | import collections 4 | import json 5 | # import time 6 | 7 | from Source import PATH_TO_CONFIG 8 | from Source.ConfigFile import ConfigFile 9 | 10 | class MainConfig: 11 | '''Class to hold Main window configurations''' 12 | fileName = "main.config" 13 | settings = collections.OrderedDict() 14 | 15 | # Saves the cfg file 16 | @staticmethod 17 | def saveConfig(fileName): 18 | print("MainConfig - Save Config") 19 | # jsn = json.dumps(MainConfig.settings) 20 | fp = os.path.join(PATH_TO_CONFIG, fileName) 21 | 22 | with open(fp, 'w', encoding="utf-8") as f: 23 | json.dump(MainConfig.settings,f,indent=4) 24 | # f.write(jsn) 25 | ConfigFile.saveConfig(ConfigFile.filename) 26 | 27 | # Loads the cfg file 28 | @staticmethod 29 | def loadConfig(fileName, version): 30 | print("MainConfig - Load Config") 31 | 32 | # Load the default values first to insure all settings are present, then populate with saved values where possible 33 | MainConfig.createDefaultConfig(fileName,version) 34 | 35 | configPath = os.path.join(PATH_TO_CONFIG, fileName) 36 | if os.path.isfile(configPath): 37 | text = "" 38 | with open(configPath, 'r', encoding="utf-8") as f: 39 | text = f.read() 40 | fullCollection = json.loads(text, object_pairs_hook=collections.OrderedDict) 41 | 42 | for key, value in fullCollection.items(): 43 | MainConfig.settings[key] = value 44 | # else: 45 | # MainConfig.createDefaultConfig(fileName, version) 46 | 47 | # Generates the default configuration 48 | @staticmethod 49 | def createDefaultConfig(fileName, version): 50 | print("MainConfig - Refresh or create from default Config") 51 | 52 | MainConfig.settings["cfgFile"] = fileName 53 | MainConfig.settings["cfgPath"] = os.path.join('./Config',fileName) 54 | MainConfig.settings["version"] = version 55 | MainConfig.settings["inDir"] = './Data' 56 | MainConfig.settings["outDir"] = './Data' 57 | MainConfig.settings["ancFileDir"] = './Data/Sample_Data' 58 | MainConfig.settings["ancFile"] = "" 59 | MainConfig.settings["popQuery"] = 0 60 | -------------------------------------------------------------------------------- /Source/OBPGSession.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | import os 4 | import re 5 | import subprocess 6 | import requests 7 | from requests.adapters import HTTPAdapter 8 | import logging 9 | 10 | DEFAULT_CHUNK_SIZE = 131072 11 | 12 | # requests session object used to keep connections around 13 | obpgSession = None 14 | 15 | def getSession(verbose=0, ntries=5): 16 | global obpgSession 17 | 18 | if not obpgSession: 19 | # turn on debug statements for requests 20 | if verbose > 1: 21 | logging.basicConfig(level=logging.DEBUG) 22 | obpgSession = requests.Session() 23 | obpgSession.mount('https://', HTTPAdapter(max_retries=ntries)) 24 | if verbose: 25 | print("OBPG session started") 26 | else: 27 | if verbose > 1: 28 | print("reusing existing OBPG session") 29 | 30 | return obpgSession 31 | 32 | def httpdl(server, request, localpath='.', outputfilename=None, ntries=5, 33 | uncompress=False, timeout=30., verbose=0, 34 | chunk_size=DEFAULT_CHUNK_SIZE): 35 | status = 0 36 | urlStr = 'https://' + server + request 37 | 38 | global obpgSession 39 | getSession(verbose=verbose, ntries=ntries) 40 | 41 | with obpgSession.get(urlStr, stream=True, timeout=timeout) as req: 42 | ctype = req.headers.get('Content-Type') 43 | if verbose: 44 | print(f'Status code: {req.status_code}') 45 | print(f'ctype: {ctype}') 46 | 47 | if req.status_code in (400, 401, 403, 404, 416): 48 | status = req.status_code 49 | elif ctype and ctype.startswith('text/html'): 50 | status = 401 51 | else: 52 | if not os.path.exists(localpath): 53 | os.umask(0o02) 54 | os.makedirs(localpath, mode=0o2775) 55 | 56 | if not outputfilename: 57 | cd = req.headers.get('Content-Disposition') 58 | if cd: 59 | outputfilename = re.findall("filename=(.+)", cd)[0] 60 | else: 61 | outputfilename = urlStr.split('/')[-1] 62 | 63 | ofile = os.path.join(localpath, outputfilename) 64 | 65 | with open(ofile, 'wb') as fd: 66 | if verbose: 67 | print(f'Writing file to disk {ofile}') 68 | for chunk in req.iter_content(chunk_size=chunk_size): 69 | if chunk: # filter out keep-alive new chunks 70 | fd.write(chunk) 71 | 72 | if uncompress and re.search(".(Z|gz|bz2)$", ofile): 73 | compressStatus = uncompressFile(ofile) 74 | if compressStatus: 75 | status = compressStatus 76 | else: 77 | status = 0 78 | 79 | return status 80 | 81 | def uncompressFile(compressed_file): 82 | """ 83 | uncompress file 84 | compression methods: 85 | bzip2 86 | gzip 87 | UNIX compress 88 | """ 89 | 90 | compProg = {"gz": "gunzip -f ", "Z": "gunzip -f ", "bz2": "bunzip2 -f "} 91 | exten = os.path.basename(compressed_file).split('.')[-1] 92 | unzip = compProg[exten] 93 | p = subprocess.Popen(unzip + compressed_file, shell=True) 94 | status = os.waitpid(p.pid, 0)[1] 95 | if status: 96 | print("Warning! Unable to decompress %s" % compressed_file) 97 | return status 98 | else: 99 | return 0 -------------------------------------------------------------------------------- /Source/RawFileReader.py: -------------------------------------------------------------------------------- 1 | """Read raw Sea-Bird file""" 2 | import sys 3 | import logging 4 | 5 | from Source.Utilities import Utilities 6 | 7 | class RawFileReader: 8 | """Read raw Sea-Bird file""" 9 | MAX_TAG_READ = 32 10 | MAX_BLOCK_READ = 1024 11 | SATHDR_READ = 128 12 | RESET_TAG_READ = MAX_TAG_READ-16 13 | 14 | # Function for reading SATHDR (Header) messages 15 | # Messages are in format: SATHDR ()\r\n 16 | @staticmethod 17 | def readSATHDR(hdr): 18 | 19 | if sys.version_info[0] < 3: 20 | end = hdr.find(b"\x0D\x0A".decode("string_escape")) 21 | else: 22 | end = hdr.find(bytes(b"\x0D\x0A".decode("unicode_escape"), "utf-8")) 23 | 24 | # BUG: TO DO: This is still screwing up the SAS SERIAL NUMBER hdr 25 | sp1 = hdr.find(b" ") # returns the first occurence where substring is found 26 | # sp2 = hdr.rfind(b" ") # returns the highest index where substring is found 27 | sp2 = hdr.find(b"(") - 1 28 | 29 | if sys.version_info[0] < 3: 30 | str1 = hdr[sp1+1:sp2] 31 | str2 = hdr[sp2+2:end-1] 32 | else: 33 | try: 34 | str1 = hdr[sp1 + 1:sp2].decode('utf-8') 35 | str2 = hdr[sp2 + 2:end - 1].decode('utf-8') 36 | except UnicodeDecodeError: 37 | logging.debug("HOCR raw header contains non UTF-8 encoded character") 38 | str1 = hdr[sp1 + 1:sp2].decode('utf-8', 'ignore') 39 | str2 = hdr[sp2 + 2:end - 1].decode('utf-8', 'ignore') 40 | 41 | 42 | #print(str1, str2) 43 | 44 | if len(str1) == 0: 45 | str1 = "Missing" 46 | return (str2, str1) 47 | 48 | # Reads a raw file 49 | @staticmethod 50 | def readRawFile(filepath, calibrationMap, contextMap, root): 51 | 52 | posframe = 1 53 | 54 | # Note: Prosoft adds posframe=1 to the GPS for some reason 55 | # print(contextMap.keys()) 56 | #gpsGroup = contextMap["$GPRMC"] 57 | #ds = gpsGroup.getDataset("POSFRAME") 58 | #ds.appendColumn(u"COUNT", posframe) 59 | posframe += 1 60 | 61 | with open(filepath, 'rb') as f: 62 | while 1: 63 | # Reads binary file to find message frame tag 64 | pos = f.tell() 65 | b = f.read(RawFileReader.MAX_TAG_READ) 66 | f.seek(pos) 67 | 68 | if "SATHSE" in str(b): 69 | pass 70 | if not b: 71 | break 72 | 73 | #print b 74 | for i in range(0, RawFileReader.MAX_TAG_READ): 75 | testString = b[i:].upper() 76 | #print("test: ", testString[:6]) 77 | 78 | # Reset file position on max read 79 | if i == RawFileReader.MAX_TAG_READ-1: 80 | #f.read(RawFileReader.MAX_TAG_READ) 81 | f.read(RawFileReader.RESET_TAG_READ) 82 | break 83 | 84 | # Detects message type from frame tag 85 | if testString.startswith(b"SATHDR"): 86 | #print("SATHDR") 87 | if i > 0: 88 | f.read(i) 89 | hdr = f.read(RawFileReader.SATHDR_READ) 90 | (k,v) = RawFileReader.readSATHDR(hdr) 91 | root.attributes[k] = v 92 | 93 | break 94 | else: 95 | num = 0 96 | for key in calibrationMap: 97 | cf = calibrationMap[key] 98 | if testString.startswith(cf.id.upper().encode("utf-8")): 99 | if i > 0: 100 | f.read(i) 101 | 102 | pos = f.tell() 103 | msg = f.read(RawFileReader.MAX_BLOCK_READ) 104 | f.seek(pos) 105 | 106 | gp = contextMap[cf.id] 107 | # Only the first time through 108 | if len(gp.attributes) == 0: 109 | #gp.id += "_" + cf.id 110 | gp.id = key 111 | gp.attributes["CalFileName"] = key 112 | gp.attributes["FrameTag"] = cf.id 113 | 114 | # if key.startswith('SATPYR'): 115 | # print('curious...') 116 | 117 | try: 118 | num = cf.convertRaw(msg, gp) 119 | except Exception: 120 | pmsg = f'Unable to convert the following raw message: {msg}' 121 | print(pmsg) 122 | Utilities.writeLogFile(pmsg) 123 | 124 | if num >= 0: 125 | # Generate POSFRAME 126 | ds = gp.getDataset("POSFRAME") 127 | if ds is None: 128 | ds = gp.addDataset("POSFRAME") 129 | ds.appendColumn("COUNT", posframe) 130 | posframe += 1 131 | f.read(num) 132 | 133 | break 134 | if num > 0: 135 | break 136 | -------------------------------------------------------------------------------- /Source/Water_IOPs.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | import scipy.interpolate 4 | 5 | from Source.SB_support import readSB 6 | 7 | def water_iops(fp, wave,T,S): 8 | 9 | ''' Function to obtain pure seawater absorption and backscattering spectra ''' 10 | 11 | #Pure water absorption from 12 | # Pope R.M., Fry E.S. Absorption spectrum (380-700 nm) of pure water. 13 | # II. Integrating cavity measurements. Appl. Opt. 1997;36:8710–8723. 14 | # doi: 10.1364/AO.36.008710. 15 | # Smith R.C., Baker K.S. Optical properties of the clearest natural waters ( 16 | # 200–800 nm) Appl. Opt. 1981;20:177–184. doi: 10.1364/AO.20.000177. 17 | 18 | #Pure water backscattering from Morel 1974 (powerlaw fit unknown, but looks good...) 19 | # Morel A. Optical properties of pure water and pure sea water. 20 | # In: Jerlov N.G., Nielsen E.S., editors. Optical Aspects of Oceanography. 21 | # Academic Press; New York, NY, USA: 1974. pp. 1–24. 22 | 23 | #Corrected for in situ temperature and salinity conditions 24 | # Sullivan, J M , M Twardowski, I R V Zanefcld, C M Moore, A H 25 | # Barnard, P L Donaghay, and B Rhoades (2006), Hyperspectral temperature 26 | # and salt dependencies of absorption by water and heavy water in the 27 | # 400-750 nm spectral range, Appl Opt, 45(21), 5294-5309, doi 10 1364/ 28 | # AO 45 005294 29 | 30 | # Inputs 31 | # fp (string): full file path to water absorption table in SeaBASS format 32 | # wave (list): wavelengths of intended output 33 | # T (float): temperature 34 | # S (float): salinity 35 | 36 | # Outputs 37 | # a_sw (list): absorption of seawater 38 | # bb_sw (list): backscattering of seawater 39 | 40 | wave = np.array(wave) 41 | 42 | #Pope and Frye pure water absorption 380-730 nm, then Smith and Baker 730-800 nm 43 | aw_sb = readSB(fp, no_warn=True) 44 | a_pw = scipy.interpolate.interp1d(aw_sb.data['wavelength'], aw_sb.data['aw'], \ 45 | kind='linear')(wave) 46 | 47 | # #Morel water backscattering 48 | # #wl_b=[380 390 400 410 420 430 440 450 460 470 480 490 500 510 520 530 540 550 560 570 580 590 600 610 620 630 640 650 660 670 680 690 700 750]; 49 | # #b_water=[0.0073 0.0066 0.0058 0.0052 0.0047 0.0043 0.0039 0.0035 0.0032 0.0029 0.0027 0.0024 0.0022 0.002 0.0018 0.0017 0.0016 0.0015 0.0013 0.0013 0.0012 0.0011 0.00101 0.00094 0.00088 0.00082 0.00076 0.00071 0.00067 0.00063 0.00059 0.00055 0.00052 0.0005]; 50 | # ##choose pure water scattering function (divide by two for back-scattering): 51 | # #bb_pw=0.5*interp1(wl_b,b_water,wl,'linear'); 52 | 53 | #log fit water backscattering 54 | bb_logfit = 0.0037000 * (380**4.3) / (wave**4.3) 55 | 56 | # Salinity correct: 57 | if S>0: 58 | bb_sw = ( (1 + 0.01*S) * bb_logfit) 59 | else: 60 | bb_sw = bb_logfit 61 | 62 | # Temp and salinity correction for water absorption (need to know at what T it was measured): 63 | if S==0: 64 | S = 35.0 65 | if T==0: 66 | T = 22.0 67 | T_pope = 22.0 68 | 69 | # Parameters for temp and salinity callibration (From Pegau et al Applied optics 1997): 70 | M = np.array([0.18, 0.17, 0.52, 1.4, 4.6, 2.1, 4.3, 9.6, 1.6, 34.0, 18.0, 42.0]) 71 | sig = np.array([18.0, 15.0, 14.0, 20.0, 17.5, 15.0, 17.0, 22.0, 6.0, 18.0, 20.0, 25.0]) 72 | lamda_c = np.array([453, 485, 517, 558, 610, 638, 661, 697, 740, 744, 775, 795]) 73 | M_T = np.array([0.0045, 0.002, 0.0045, 0.002, 0.0045, -0.004, 0.002, -0.001, 0.0045, 0.0062, -0.001, -0.001]) 74 | 75 | # Computing the correction per degree C 76 | phi_T = [] 77 | for wl in wave: 78 | phi_T.append(np.sum( M_T * M / sig * np.exp( -(wl-lamda_c)**2/2.0/sig**2) )) 79 | phi_T = np.array(phi_T) 80 | 81 | # Salinity correction based on Pegau and Zaneveld 1997: 82 | wls = np.array([400, 412, 440, 488, 510, 532, 555, 650, 676, 715, 750]) 83 | phi_S_PZ = np.array([0.000243, 0.00012, -0.00002, -0.00002, -0.00002, -0.00003, -0.00003, 0, -0.00002, -0.00027, 0.00064]) 84 | 85 | # Interpolate to compute salinity correction per psu 86 | phi_S = scipy.interpolate.interp1d(wls,phi_S_PZ, \ 87 | kind='linear', bounds_error=False, fill_value=0.0)(wave) 88 | 89 | # Temperature and salinity corrections: 90 | a_sw = ( a_pw + phi_T*(T - T_pope) + phi_S*S) 91 | 92 | return a_sw, bb_sw 93 | 94 | # wave = list(range(400, 701)) 95 | # T = 20.0 96 | # S = 33.0 97 | # fp = os.path.join(os.path.abspath('.'), 'Data') 98 | # fp = os.path.join(fp,'Water_Absorption.sb') 99 | 100 | # a_sw, bb_sw = water_iops(fp, wave, T, S) 101 | # print(a_sw) 102 | 103 | -------------------------------------------------------------------------------- /Source/WriteRhoM99.py: -------------------------------------------------------------------------------- 1 | import re 2 | import os 3 | 4 | from Source import PATH_TO_DATA 5 | from Source.HDFRoot import HDFRoot 6 | from Source.HDFGroup import HDFGroup 7 | 8 | 9 | def readLUT(node,filename, headerlines): 10 | """ 11 | Read in the M99 LUT for 550 nm 12 | 13 | Required arguments: 14 | node = HDF5 Root object 15 | filename = name of SeaBASS input file (string) 16 | headerlines = # of headerlines in the LUT text file 17 | 18 | LUT is in self.groups[0].datasets['LUT'].data 19 | 20 | phiView is the relative azimuth angle, and phiSun is 180 - phiView 21 | 22 | """ 23 | 24 | node.id = 'rhoLUT' 25 | node.attributes['LUT origin'] = filename.split(os.path.sep)[-1] 26 | node.attributes['Citation'] = 'Mobley, 1999, Appl Opt 38, page 7445, Eqn. 4' 27 | 28 | try: 29 | fileobj = open(filename,'r') 30 | except Exception as e: 31 | print(f'Unable to open file for reading: {filename}. Error: {e}') 32 | return 33 | 34 | try: 35 | lines = fileobj.readlines() 36 | fileobj.close() 37 | except Exception as e: 38 | print(f'Unable to read data from file: {filename}. Error: {e}') 39 | return 40 | 41 | # Create the dictionary LUT 42 | lut = {'wind':[],'sza':[],'theta':[],'phiSun':[],'phiView':[],'rho':[]} 43 | 44 | # Later, interpolate or find-nearest the field data to these steps to match... 45 | wind = [] # 0:2:14 46 | sza = [] # 0:10:80 47 | # I =[] # 1:1:10 48 | # J = [] # 1:1:13 49 | theta = [] # 0:10:80, 87.5 50 | phiSun = [] # 0:15:180 # phi of 45 deg is relaz of 135 deg 51 | phiView = []# 0:15:180 52 | rho = [] # result 53 | 54 | for i, line in enumerate(lines): 55 | if i < headerlines: 56 | continue 57 | data_row = re.search("WIND SPEED =", line) 58 | data_row = re.search("THETA_SUN", line) 59 | 60 | if data_row: 61 | elems = re.findall('\d+\.\d+',line) 62 | continue 63 | 64 | linefloat = [float(elem) for elem in line.split()] 65 | wind.append(float(elems[0])) 66 | sza.append(float(elems[1])) 67 | theta.append(linefloat[2]) 68 | phiSun.append(linefloat[3]) 69 | phiView.append(linefloat[4]) 70 | rho.append(linefloat[5]) 71 | 72 | lut['wind'] = wind 73 | lut['sza'] = sza 74 | lut['theta'] = theta 75 | lut['phiSun'] = phiSun 76 | lut['phiView'] = phiView 77 | lut['rho'] = rho 78 | 79 | gp = HDFGroup() 80 | gp.id = 'LUT' 81 | node.groups.append(gp) 82 | 83 | LUTDataset = gp.addDataset("LUT") 84 | LUTDataset.columns = lut 85 | LUTDataset.columnsToDataset() 86 | 87 | return node 88 | 89 | 90 | 91 | fp = os.path.join(PATH_TO_DATA, 'rhoTable_AO1999.txt') 92 | outfp = os.path.join(PATH_TO_DATA, 'rhoTable_AO1999.hdf') 93 | headerlines = 9 94 | # dims = [13, 117, 6] 95 | root = HDFRoot() 96 | root = readLUT(root, fp, headerlines) 97 | 98 | root.writeHDF5(outfp) 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /Source/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import logging 4 | import traceback 5 | 6 | 7 | # Set loggers 8 | root_logger = logging.getLogger() # Get root logger 9 | logging.basicConfig(level=logging.INFO) 10 | logging.getLogger('matplotlib').setLevel(logging.WARNING) 11 | logging.getLogger('numexpr').setLevel(logging.WARNING) 12 | logging.getLogger('pyi_splash').setLevel(logging.WARNING) 13 | 14 | # Catch Error (if frozen, not needed otherwise) 15 | if getattr(sys, 'frozen', False): 16 | def except_hook(exc_type, exc_value, exc_tb): 17 | tb = "".join(traceback.format_exception(exc_type, exc_value, exc_tb)) 18 | root_logger.error(tb) 19 | 20 | sys.excepthook = except_hook 21 | 22 | # Setup Path 23 | PACKAGE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) 24 | if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): 25 | root_logger.info('Running from PyInstaller bundle') 26 | PACKAGE_DIR = getattr(sys, '_MEIPASS', PACKAGE_DIR) 27 | os.chdir(PACKAGE_DIR) 28 | else: 29 | root_logger.info('Running from source') 30 | 31 | PATH_TO_DATA = os.path.join(PACKAGE_DIR, 'Data') 32 | PATH_TO_CONFIG = os.path.join(PACKAGE_DIR, 'Config') 33 | -------------------------------------------------------------------------------- /Source/matheo/punpy_util.py: -------------------------------------------------------------------------------- 1 | """ 2 | Functions to band integrate spectra for given spectral response function. 3 | """ 4 | 5 | from punpy import MCPropagation 6 | import numpy as np 7 | from typing import Union, Callable, Tuple, Iterable, Dict 8 | import multiprocessing 9 | 10 | 11 | __author__ = "Sam Hunt" 12 | __created__ = "24/7/2020" 13 | 14 | 15 | def _max_dim(arrays: Iterable[np.ndarray]) -> int: 16 | """ 17 | Return max dimension of input numpy arrays 18 | 19 | :param arrays: n input numpy arrays 20 | :return: maximum dimension 21 | """ 22 | 23 | dims = [] 24 | for array in arrays: 25 | dims.append(np.ndim(array)) 26 | 27 | return max(dims) 28 | 29 | 30 | def _unc_to_dim(unc: Union[float, np.ndarray], dim: int, x: np.ndarray = None, x_len: int = None) -> np.ndarray: 31 | """ 32 | Scales up uncertainty to given dimension (e.g. float to full vector, vector to diagonal maxtrix) 33 | 34 | :param unc: uncertainty value (in percent) or vector 35 | :param dim: target dimension to raise to 36 | :param x: 37 | :param x_len: 38 | :return: 39 | """ 40 | 41 | original_dim = np.ndim(unc) 42 | 43 | if (original_dim > 2) or (dim > 2): 44 | raise ValueError( 45 | "Can only raise uncertainty to a max dimension of 2 (e.g. covariance matrix)" 46 | ) 47 | 48 | if original_dim == dim: 49 | return unc 50 | elif unc is None: 51 | return None 52 | else: 53 | if original_dim == 0: 54 | if (x is None) and (x_len is None): 55 | raise AttributeError( 56 | "Please define either x or x_len to raise dimension of shape 0 uncertainty" 57 | ) 58 | elif x is not None: 59 | unc *= x 60 | else: 61 | unc = np.full(x_len, unc) 62 | 63 | if dim == 1: 64 | return unc 65 | 66 | return np.diag(unc) 67 | 68 | 69 | def func_with_unc( 70 | f: Callable, 71 | params: Dict[str, Union[float, np.ndarray]], 72 | u_params: Dict[str, Union[None, float, np.ndarray]], 73 | parallel: bool = True, 74 | ) -> Tuple[Union[float, np.ndarray], Union[None, float, np.ndarray]]: 75 | """ 76 | Evaluate function and uncertainties using Monte Carlo method 77 | 78 | Provides simple interface to run a simple Monte Carlo experiment with punpy. 79 | 80 | :param f: function 81 | :param params: function parameters 82 | :param u_params: function parameter uncertainties (entries keys same as parameters, one uncertainty per parameter). 83 | Entries may be of following type: 84 | 85 | * ``None`` - value assumed a constant, no uncertainty (assumed if not provided) 86 | * ``float`` - assumed to be a relative random uncertainty 87 | * 1 dimensional ``numpy.ndarray`` - assumed to be an array of absolute random uncertainties (must be same length as 88 | variable parameter) 89 | * 2 dimensional ``numpy.ndarray`` - assumed to be a covariance matrix (must be the length of the variable parameter 90 | square) 91 | 92 | :return: evaluated function and uncertainty 93 | """ 94 | 95 | # evaluate function 96 | y = f(**params) 97 | 98 | # if no uncertainties return only in band spectrum 99 | if all(v == None for v in u_params.values()): 100 | return y, None 101 | 102 | # Add None's for any undefined uncertainties 103 | u_params_missing = {k: None for k in params.keys() if k not in u_params} 104 | u_params = {**u_params, **u_params_missing} 105 | 106 | # Find max dimension of uncertainty data and match other variables 107 | unc_dim = _max_dim(u_params.values()) 108 | if unc_dim != 2: 109 | unc_dim = 1 110 | 111 | u_params = dict((k, _unc_to_dim(u, unc_dim, x=v)) if (u is not None) else (k, u) for (k, u), v in zip(u_params.items(), params.values())) 112 | 113 | # Propagate uncertainties 114 | if parallel: 115 | prop = MCPropagation(10000, parallel_cores=multiprocessing.cpu_count()) 116 | else: 117 | prop = MCPropagation(10000) 118 | 119 | x = [v for v in params.values()] 120 | u_x = [u_params[k] for k in params.keys()] 121 | 122 | if unc_dim == 1: 123 | u_y = prop.propagate_random(func=f, x=x, u_x=u_x) 124 | elif unc_dim == 2: 125 | u_y = prop.propagate_cov(func=f, x=x, cov_x=u_x, return_corr=False) 126 | else: 127 | u_y = None 128 | 129 | del prop 130 | 131 | return y, u_y 132 | 133 | 134 | if __name__ == "__main__": 135 | pass 136 | -------------------------------------------------------------------------------- /Source/ocbrdf/BRDF_LUTs/BRDF_L11.nc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Source/ocbrdf/BRDF_LUTs/BRDF_L11.nc -------------------------------------------------------------------------------- /Source/ocbrdf/BRDF_LUTs/BRDF_M02.nc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Source/ocbrdf/BRDF_LUTs/BRDF_M02.nc -------------------------------------------------------------------------------- /Source/ocbrdf/BRDF_LUTs/BRDF_M02SeaDAS.nc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Source/ocbrdf/BRDF_LUTs/BRDF_M02SeaDAS.nc -------------------------------------------------------------------------------- /Source/ocbrdf/BRDF_LUTs/BRDF_UNC.nc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Source/ocbrdf/BRDF_LUTs/BRDF_UNC.nc -------------------------------------------------------------------------------- /Source/ocbrdf/Raman.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import xarray as xr 3 | 4 | ''' Raman correction from Lee et al?. (2013): 5 | Penetration of UV-visible solar radiation in the global oceans: 6 | Insights from ocean color remote sensing. J Geophys Res Oceans 2013;118:4241–55 7 | 8 | Spectral interpolation done at the nearest bands 9 | 10 | ''' 11 | 12 | """ Class for Raman correction LUT """ # TODO store and read in the ADF 13 | class Raman(): 14 | def __init__(self): 15 | bands = [412,443,488,531,551,667] 16 | coords = {'bands': bands} 17 | self.alpha = xr.DataArray([0.003,0.004,0.011,0.015,0.017,0.018], dims='bands', coords=coords) 18 | self.beta1 = xr.DataArray([0.014,0.015,0.010,0.010,0.010,0.010], dims='bands', coords=coords) 19 | self.beta2 = xr.DataArray([-0.022,-0.023,-0.051,-0.070,-0.080,-0.081], dims='bands', coords=coords) 20 | 21 | def correct(self, Rrs): 22 | # Interpolate coefficients at nearest bands 23 | interp_opt = {'method':'nearest', 'kwargs':{'fill_value':'extrapolate'}} 24 | alpha = self.alpha.interp(bands=Rrs.bands, **interp_opt) 25 | beta1 = self.beta1.interp(bands=Rrs.bands, **interp_opt) 26 | beta2 = self.beta2.interp(bands=Rrs.bands, **interp_opt) 27 | 28 | # Select reference bands closest to 440 and 550 29 | Rrs440 = Rrs.sel(bands=440, method='nearest') 30 | Rrs550 = Rrs.sel(bands=550, method='nearest') 31 | 32 | # Compute Raman factor 33 | RF = alpha*Rrs440/Rrs550 + beta1*np.power(Rrs550,beta2) 34 | 35 | # Correct 36 | return Rrs/(1+RF) 37 | 38 | -------------------------------------------------------------------------------- /Source/ocbrdf/brdf_model_M02SeaDAS.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import xarray as xr 3 | 4 | from .brdf_utils import ADF_OCP, solve_2nd_order_poly 5 | 6 | ''' Morel et al. (2002) BRDF correction 7 | R gothic NOT included 8 | f/Q LUT as in NASA's SeaDAS (See BRDF_M02SeaDAS.nc attributes for detail). 9 | With OC4ME Chl inversion, 1 iteration, no convergence criterion applied 10 | ''' 11 | 12 | """ Class for M02 coefficients """ 13 | 14 | 15 | class Coeffs(): 16 | def __init__(self, foq): 17 | self.foq = foq 18 | 19 | 20 | """ Class for M02 BRDF model """ 21 | class M02SeaDAS: 22 | """ Initialise M02 model: BRDF LUT, coeffs, OC4ME parameters, water IOPs LUT 23 | Note: bands are fixed and defined at class initilization, but could be initialized in init_pixels if needed 24 | """ 25 | 26 | def __init__(self, bands, adf=None): 27 | if adf is None: 28 | adf = ADF_OCP 29 | 30 | # Check required bands are existing, within a 25 nm threshold 31 | self.bands = bands 32 | threshold = 25. 33 | bands_required = [442.5, 490, 510, 560] 34 | bands_ref = bands.sel(bands=bands_required, method='nearest') 35 | for band_ref, band_required in zip(bands_ref, bands_required): 36 | assert abs(band_ref - band_required) < threshold, 'Band %d nm missing or too far' % band_ref 37 | self.b442, self.b490, self.b510, self.b560 = bands_ref 38 | 39 | # Read BRDF LUT and compute default coeffs 40 | LUT_OCP = xr.open_dataset(adf % 'M02SeaDAS',engine='netcdf4') 41 | self.LUT = xr.Dataset() 42 | 43 | # Homogeneise naming convention with other methods... (PZA --> OZA transformation comes below...) 44 | self.LUT['foq'] = LUT_OCP.f_over_q_LUT.rename({'SZA_FOQ':'theta_s', 45 | 'PZA_FOQ':'theta_v', 46 | 'RAA_FOQ':'delta_phi', 47 | 'log_chl_FOQ':'log_chl_foq'}) 48 | 49 | # Index of refraction 50 | self.n_w = float(LUT_OCP.water_refraction_index.data) 51 | 52 | # Remove trivial aot indexation 53 | self.LUT['foq'] = self.LUT['foq'].squeeze() 54 | 55 | # 56 | self.coeffs0 = self.interp_geometries(0., 0., 0.) 57 | self.coeffs = Coeffs(np.nan) 58 | 59 | # Parameters for the OC4ME chl retrieval 60 | self.OC4MEcoeff = LUT_OCP.log10_coeff_LUT.values 61 | self.OC4MEepsilon = LUT_OCP.oc4me_epsilon 62 | self.OC4MEchl0 = float(LUT_OCP.oc4me_chl0.values) 63 | self.niter = LUT_OCP.oc4me_niter 64 | 65 | """ Initialize pixel: coefficient at current geometry and water IOP at current bands """ 66 | 67 | def init_pixels(self, theta_s, theta_v, delta_phi): 68 | self.coeffs = self.interp_geometries(theta_s, theta_v, delta_phi) 69 | 70 | """ Interpolate coefficients """ 71 | def interp_geometries(self, theta_s, theta_v, delta_phi): 72 | # Transform PZA to VZA (Snell's refraction Law) 73 | theta_v = np.rad2deg(np.arcsin(np.sin(np.deg2rad(theta_v)) / self.n_w)) 74 | theta_v_0 = np.clip(theta_v, 75 | float(np.min(self.LUT.theta_v)), 76 | float(np.max(self.LUT.theta_v))) 77 | 78 | foq = self.LUT.foq.interp(theta_s=theta_s, theta_v=theta_v_0, delta_phi=delta_phi) 79 | 80 | return Coeffs(foq) 81 | 82 | """ Compute remote-sensing reflectance""" 83 | 84 | def forward(self, ds, normalized=False): 85 | 86 | if normalized: 87 | coeffs = self.coeffs0 88 | else: 89 | coeffs = self.coeffs 90 | 91 | wave_foq = np.clip(ds['bands'], 92 | float(np.min(coeffs.foq.wavelengths_FOQ)), 93 | float(np.max(coeffs.foq.wavelengths_FOQ))) 94 | 95 | log10_chl_foq = np.clip(ds['log10_chl'], 96 | float(np.min(coeffs.foq.log_chl_foq)/np.log(10)), 97 | float(np.max(coeffs.foq.log_chl_foq)/np.log(10))) 98 | 99 | # f/Q LUT indexed with ln(CHL), i.e. log_e(CHL) 100 | log_chl_foq = log10_chl_foq * np.log(10) 101 | 102 | forward_mod = coeffs.foq.interp(wavelengths_FOQ=wave_foq).interp(log_chl_foq=log_chl_foq) 103 | 104 | return forward_mod 105 | 106 | """ Apply QAA to retrieve IOP (omega_b, eta_b) from Rrs """ 107 | 108 | def backward(self, ds, iter_brdf): 109 | 110 | Rrs = ds['nrrs'] 111 | 112 | # Local renaming of bands 113 | b442, b490, b510, b560 = self.b442, self.b490, self.b510, self.b560 114 | 115 | # Convert to scalar if np.array of 1 value to avoid issues 116 | try: 117 | b442=b442.item() 118 | b490=b490.item() 119 | b510=b510.item() 120 | b560=b560.item() 121 | except: 122 | pass 123 | 124 | # Apply upper and lower limits to Rrs(665) #TODO check if not finite or missing? 125 | Rrs442 = Rrs.sel(bands=b442) 126 | Rrs490 = Rrs.sel(bands=b490) 127 | Rrs510 = Rrs.sel(bands=b510) 128 | Rrs560 = Rrs.sel(bands=b560) 129 | 130 | # Compute the OC4ME "R" 131 | ds['log10_chl_OC4ME_Ratio'] = np.log10(np.max([Rrs442, Rrs490, Rrs510], axis=0) / Rrs560) 132 | 133 | ds['log10_chl'] = 0 * ds['log10_chl_OC4ME_Ratio'] 134 | # Apply OC4ME 5-degree polynomial 135 | for k, Ak in enumerate(self.OC4MEcoeff): 136 | ds['log10_chl'] += Ak * (ds['log10_chl_OC4ME_Ratio'] ** k) 137 | 138 | return ds -------------------------------------------------------------------------------- /Source/ocbrdf/brdf_utils.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import xarray as xr 3 | import os 4 | 5 | # Define default auxiliary data file (OLCI OCP ADF) 6 | ref_path = os.path.dirname(os.path.realpath(__file__)) 7 | # ADF_OCP = os.path.join(ref_path, '..', 'AuxiliaryData/OCP/S3A_OL_2_OCP_AX_20160216T000000_20991231T235959_20240327T100000___________________EUM_O_AL_008.SEN3/OL_2_OCP_AX.nc') 8 | ADF_OCP = os.path.join(ref_path, 'BRDF_LUTs','BRDF_%s.nc') 9 | 10 | def solve_2nd_order_poly(A, B, C): 11 | """ Solve 2nd order polynomial inversion 12 | where coefficients are xr dataArray 13 | Take only positive solution, otherwise provide 0. 14 | """ 15 | 16 | # Compute solution according to sign of delta 17 | delta = B*B - 4*A*C 18 | mask = delta > 0 19 | 20 | # By default (and when delta < 0), take value at extremum 21 | x = - B / (2*A) 22 | 23 | # When delta > 0, take biggest solutions 24 | x_1 = (-B.where(mask) - np.sqrt(delta.where(mask))) / (2*A.where(mask)) 25 | x_2 = (-B.where(mask) + np.sqrt(delta.where(mask))) / (2*A.where(mask)) 26 | x_sol = xr.where(x_1 > x_2, x_1, x_2) 27 | x = xr.where(delta > 0, x_sol, x) 28 | 29 | # Take only positive value 30 | x = xr.where(x > 0, x, 0.) 31 | 32 | return x 33 | 34 | def drop_unused_coords(var): 35 | for coord in var.coords: 36 | if coord not in var.dims: 37 | var = var.drop(coord) 38 | return var 39 | 40 | def squeeze_trivial_dims(ds,dimOrderAccordingTo='Rw'): 41 | squeezedDims = {} 42 | for d0,dim in enumerate(ds[dimOrderAccordingTo].dims): 43 | if ds.sizes[dim] == 1: 44 | squeezedDims[dim] = d0 45 | 46 | return ds.squeeze(), squeezedDims 47 | -------------------------------------------------------------------------------- /Source/raw_Data_Hourly_Cutter.py: -------------------------------------------------------------------------------- 1 | """ 2 | Args Needed To Run: 3 | -f, --file (str) : The path to the text file that you want to split into hourly files 4 | -o, --output (str): The path to the directory that you want the hourly files to be placed in. 5 | 6 | Example Run Command: 7 | python raw_Data_Hourly_Cutter.py -f path/to/file.TXT -o dir/to/place/files 8 | 9 | *** NOTE : The output directory path should NOT end with a '/' *** 10 | *** NOTE : Currently only works with DALEC Raw data file! *** 11 | """ 12 | 13 | 14 | import pandas as pd 15 | import argparse 16 | 17 | def find_line_number(file_path): 18 | """ 19 | Reads a text file and returns the line number of the first occurrence of the data in order to skip the header. 20 | 21 | Args: 22 | file_path (str): The path to the text file. 23 | 24 | Returns: 25 | int: The line number (starting from 1) if the text is found, otherwise None. 26 | str: The header text at the beginning of the raw data files. 27 | """ 28 | try: 29 | header = "" 30 | with open(file_path, 'r') as file: 31 | for line_number, line in enumerate(file, 1): 32 | header += line 33 | if "---------OUTPUT FORMAT---------" in line: 34 | return line_number, header 35 | return None # Target text not found 36 | except FileNotFoundError: 37 | return None 38 | 39 | 40 | def split_csv_hourly(input_file, output_prefix): 41 | """ 42 | Splits a large TXT file into hourly TXT files based on a timestamp column. 43 | NOTE: TimeStamp needs to be the 4th value in each row in the data file. 44 | 45 | Args: 46 | input_file (str): Path to the input TXT file. 47 | output_prefix (str): Path to output file directory 48 | """ 49 | 50 | #step 0: Initialization 51 | print("---- Initializing Data...") 52 | output_prefix += f"/{input_file.split('/')[-1][0:8]}" 53 | csv_data_line_number, header = find_line_number(input_file) 54 | if csv_data_line_number is None: 55 | return 56 | 57 | 58 | # Step 1: Read original file as raw text lines 59 | print("---- Reading Input File...") 60 | with open(input_file, "r") as f: 61 | lines = f.readlines() 62 | 63 | 64 | # Step 2: Parse each line and extract timestamp for grouping 65 | print("---- Processing Data...") 66 | data=[] 67 | counter = 0 68 | percent = 0 69 | total_lines = len(lines) // 20 70 | 71 | for line in lines: 72 | if counter > csv_data_line_number: 73 | 74 | ##Progress Bar 75 | if counter % total_lines == 0: 76 | print(f"... {percent}%") 77 | percent += 5 78 | ## 79 | 80 | parts = line.split(",") 81 | if len(parts) > 1: #Skips over empty rows 82 | timestamp = pd.to_datetime(parts[3]) 83 | hour_group = timestamp.floor('H') # round down to the hour 84 | date_group = timestamp.date() 85 | data.append((date_group, hour_group, line.strip())) 86 | 87 | #Using the counter to skip over header/Configuration Info 88 | counter+=1 89 | 90 | print(f"Procesing: 100%") ##Progress Bar 91 | 92 | # Step 3: Load into DataFrame for grouping 93 | df = pd.DataFrame(data, columns=["date_group", "hour_group", "original_line"]) 94 | 95 | # Step 4: Group by date and hour, and write to separate CSV files 96 | print("---- Writing Data to new files...") 97 | for (date, hour), group in df.groupby(["date_group", "hour_group"]): 98 | # Format filenames: one for date and one for hour 99 | date_str = date.strftime("%Y-%m-%d") 100 | hour_str = hour.strftime("%Y-%m-%d_%H00") 101 | filename = f"{output_prefix}_{hour_str}.TXT" 102 | 103 | with open(filename, "w") as f: 104 | f.write(header) 105 | for line in group["original_line"]: 106 | f.write(line + "\n") 107 | 108 | print(f"Created: {filename}") 109 | 110 | 111 | 112 | def setupParser(): 113 | parser = argparse.ArgumentParser(description='NRCS Posting Script') 114 | 115 | parser.add_argument('-f', '--file', required=True, help='File you want to Parse into hourly files') 116 | parser.add_argument('-o', '--output', required=True, help='Output Directory for hourly files') 117 | 118 | return parser 119 | 120 | 121 | 122 | if __name__ == '__main__': 123 | 124 | args = setupParser().parse_args() 125 | 126 | split_csv_hourly(args.file, args.output) -------------------------------------------------------------------------------- /Tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasa/HyperCP/1cc96feedbb5a93f9e9e62a33e61ec7b3cb47f24/Tests/__init__.py -------------------------------------------------------------------------------- /Tests/test_sample_data.py: -------------------------------------------------------------------------------- 1 | import os 2 | import glob 3 | import unittest 4 | 5 | 6 | os.environ["HYPERINSPACE_CMD"] = "TRUE" 7 | root = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir)) 8 | 9 | 10 | class TestManualTriOS(unittest.TestCase): 11 | def setUp(self): 12 | # Load files to process 13 | self.path_to_data = os.path.join(root, 'Data', 'Sample_Data', 'Manual_TriOS') 14 | self.anc_filename = os.path.join(self.path_to_data, f"FICE22_TriOS_Ancillary.sb") 15 | self.cfg_filename = os.path.join(root, "Config", "sample_TRIOS_NOTRACKER.cfg") 16 | self.files = sorted(glob.glob(os.path.join(self.path_to_data, 'RAW', f'*.mlb'))) 17 | 18 | def test_manual_trios(self): 19 | from Main import Command 20 | os.chdir(root) # Need to switch to root as path in Config files are relative 21 | Command(self.cfg_filename, 'RAW', self.files, self.path_to_data,'L1A', 22 | self.anc_filename, processMultiLevel=True) 23 | 24 | 25 | class TestPySAS(unittest.TestCase): 26 | def setUp(self): 27 | # Load files to process 28 | self.path_to_data = os.path.join(root, 'Data', 'Sample_Data', 'pySAS') 29 | self.anc_filename = os.path.join(self.path_to_data, f"FICE22_pySAS_Ancillary.sb") 30 | self.cfg_filename = os.path.join(root, "Config", "sample_SEABIRD_pySAS.cfg") 31 | self.files = sorted(glob.glob(os.path.join(self.path_to_data, 'RAW', f'*.raw'))) 32 | 33 | def test_pysas(self): 34 | from Main import Command 35 | os.chdir(root) # Need to switch to root as path in Config files are relative 36 | for file in self.files: 37 | Command(self.cfg_filename, 'RAW', file, self.path_to_data,'L1A', 38 | self.anc_filename, processMultiLevel=True) 39 | 40 | 41 | class TestSeabirdSolarTracker(unittest.TestCase): 42 | def setUp(self): 43 | # Load files to process 44 | self.path_to_data = os.path.join(root, 'Data', 'Sample_Data', 'SolarTracker') 45 | self.anc_filename = os.path.join(self.path_to_data, f"KORUS_SOLARTRACKER_Ancillary.sb") 46 | self.cfg_filename = os.path.join(root, "Config", "sample_SEABIRD_SOLARTRACKER.cfg") 47 | self.files = sorted(glob.glob(os.path.join(self.path_to_data, 'RAW', f'*.RAW'))) 48 | 49 | def test_seabird_solar_tracker(self): 50 | from Main import Command 51 | os.chdir(root) # Need to switch to root as path in Config files are relative 52 | for file in self.files: 53 | Command(self.cfg_filename, 'RAW', file, self.path_to_data,'L1A', 54 | self.anc_filename, processMultiLevel=True) 55 | 56 | 57 | if __name__ == '__main__': 58 | unittest.main() 59 | -------------------------------------------------------------------------------- /build_Z17-LUT.py: -------------------------------------------------------------------------------- 1 | ########################## DEVELOPER USE ONLY ########################## 2 | 3 | """ 4 | used to build Z17 look up table for the optimisation of ProcessL2. 5 | 6 | """ 7 | 8 | # NOTE: I don't know how to do tests for this because anything I write will take weeks to execute - Ashley 9 | 10 | ######################################################################## 11 | 12 | # import python packages 13 | import os 14 | # import random as rand 15 | import xarray as xr 16 | import numpy as np 17 | 18 | # import RhoCorrections for running of Z17 19 | from Source.ZhangRho import PATH_TO_DATA 20 | from Source.RhoCorrections import RhoCorrections 21 | 22 | # import Propagate module for processing uncertainties 23 | from Source.Uncertainty_Analysis import Propagate 24 | 25 | if __name__ == '__main__': 26 | # this is the code used to build the Z17 LUT by repeatedly running the Zhang17 code from HCP. Will run if this file, RhoCorrections.py is __main__ 27 | # i.e. running - python3 HCP/Source/RhoCorrections.py 28 | 29 | # read in current LUT. Figure out it's bounds, then append extra nodes to it! 30 | pre = xr.open_dataset(os.path.join(PATH_TO_DATA, "Z17_LUT.nc"), engine='netcdf4') 31 | 32 | # initialise punpy 33 | Prop_Obj = Propagate(M=10, cores=1) 34 | 35 | # set fixed variables 36 | cloud = None # not used 37 | waveBands = np.array( 38 | [350., 355., 360., 365., 370., 375., 380., 385., 390., 39 | 395., 400., 405., 410., 415., 420., 425., 430., 435., 40 | 440., 445., 450., 455., 460., 465., 470., 475., 480., 41 | 485., 490., 495., 500., 505., 510., 515., 520., 525., 42 | 530., 535., 540., 545., 550., 555., 560., 565., 570., 43 | 575., 580., 585., 590., 595., 600., 605., 610., 615., 44 | 620., 625., 630., 635., 640., 645., 650., 655., 660., 45 | 665., 670., 675., 680., 685., 690., 695., 700., 705., 46 | 710., 715., 720., 725., 730., 735., 740., 745., 750., 47 | 755., 760., 765., 770., 775., 780., 785., 790., 795., 48 | 800., 805., 810., 815., 820., 825., 830., 835., 840., 49 | 845., 850., 855., 860., 865., 870., 875., 880., 885., 50 | 890., 895., 900., 905., 910., 915., 920., 925., 930., 51 | 935., 940., 945., 950., 955., 960., 965., 970., 975., 52 | 980., 985., 990., 995., 1000.], dtype=float) # waveband values already act as nodes for interpolation 53 | 54 | windspeed = np.array([0, 1, 2, 3, 4, 5, 7.5, 10, 12.5, 15]) # 9 55 | AOT = np.array([0, 0.05, 0.1, 0.2, 0.5]) # 5 56 | SZA = np.arange(10, 65, 5) # 12 # expanded database would go to 65 57 | RELAZ = np.arange(80, 145, 5) # 13 58 | VZEN = np.array([30, 35, 40]) # 2 59 | SAL = np.arange(0, 70, 10) # 5 60 | SST = np.arange(-40, 60, 20) # 4 61 | data = np.zeros((len(windspeed), len(AOT), len(SZA), len(RELAZ), len(VZEN), len(SAL), len(SST), len(waveBands))) 62 | # uncs = np.zeros((len(windspeed), len(AOT), len(SZA), len(RELAZ), len(VZEN), len(SAL), len(SST), len(waveBands))) 63 | for i_windspeed, windSpeedMean in enumerate(windspeed): 64 | for i_aot, aot in enumerate(AOT): 65 | for i_sza, sza in enumerate(SZA): 66 | for i_relaz, relAz in enumerate(RELAZ): 67 | for i_vzen, vzen in enumerate(VZEN): 68 | for i_sal, sal in enumerate(SAL): 69 | for i_wtemp, wtemp in enumerate(SST): 70 | if (windSpeedMean in pre.wind) and (aot in pre.aot) and (sza in pre.sza) and (relAz in pre.relAz) \ 71 | and (vzen in pre.vzen) and (sal in pre.sal) and (wtemp in pre.SST): 72 | data[i_windspeed, i_aot, i_sza, i_relaz, i_vzen, i_sal, i_wtemp] = pre.Glint.isel( 73 | wind=i_windspeed, aot=i_aot, sza=i_sza, relAz=i_relaz, vzen=i_vzen, sal=i_sal, SST=i_wtemp 74 | ).values 75 | else: 76 | rho, unc = RhoCorrections.ZhangCorr( 77 | windSpeedMean, 78 | aot, 79 | cloud, 80 | sza, 81 | wtemp, 82 | sal, 83 | relAz, 84 | vzen, 85 | waveBands, 86 | # Propagate=Prop_Obj 87 | ) 88 | data[i_windspeed, i_aot, i_sza, i_relaz, i_vzen, i_sal, i_wtemp] = rho 89 | 90 | da = xr.DataArray( 91 | data, 92 | dims=['wind', 'aot', 'sza', 'relAz', 'sal', 'SST', 'vzen' 'wavelength'], 93 | coords={ 94 | 'wind': windspeed, 95 | 'aot': AOT, 96 | 'sza': SZA, 97 | 'relAz': RELAZ, 98 | 'sal': SAL, 99 | 'SST': SST, 100 | 'vzen': VZEN, 101 | 'wavelength': waveBands, 102 | }, 103 | attrs={ 104 | 'description': "rho values for given inputs", 105 | 'units': ['ms-1', 'n/a', 'degrees', 'degrees', 'ppm', 'degrees-C'] 106 | }, 107 | ) 108 | 109 | ds = da.to_dataset(name="Glint") 110 | ds.to_netcdf(os.path.join(PATH_TO_DATA, 'Z17_LUT_new.nc')) 111 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: hypercp 2 | channels: 3 | - defaults 4 | - conda-forge 5 | - ocdb 6 | dependencies: 7 | - python=3.11 8 | - pyqt=5.15 9 | - requests=2.28 10 | - tqdm=4.65 11 | - numpy=1 12 | - h5py=3.7 13 | - pytz=2022.7 14 | - matplotlib 15 | - scipy=1.10 16 | - pandas=1.5 17 | - pysolar=0.10 18 | - xarray 19 | - cdsapi>=0.7.2 20 | - netcdf4=1.6 21 | - j6s 22 | - pytables=3.7 23 | - pyspectral=0.12.5 24 | - pyqtgraph 25 | - ocdb-client 26 | - pip 27 | - pip: 28 | - comet_maths<=1.0.3 29 | - punpy 30 | - fpdf2 31 | -------------------------------------------------------------------------------- /make.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import glob 4 | import platform 5 | import subprocess 6 | 7 | import PyInstaller.__main__ 8 | 9 | 10 | root = os.path.join('.', 'Bundled') 11 | 12 | # Set parameters specific to platform 13 | if platform.system() not in ['Windows', 'Darwin', 'Linux']: 14 | raise ValueError(f"Platform {platform.system()} not supported.") 15 | os_specific_options = [] 16 | add_data_sep = ':' 17 | if platform.system() == 'Darwin': 18 | os_specific_options = [ 19 | f'--icon={os.path.relpath(os.path.join("Data", "Img", "logo.icns"), root)}', 20 | '--windowed', 21 | # '--target-arch=universal2', # Fails on GitHub but bundle works on both architecture 22 | # Required for code signing 23 | '--osx-bundle-identifier=com.nasa.hypercp.hypercp', 24 | # f'--codesign-identity={os.getenv("CODESIGN_HASH")}', 25 | # f'--osx-entitlements-file={os.path.join("Bundled", "entitlements.plist")}', 26 | 27 | ] 28 | elif platform.system() == 'Windows': 29 | os_specific_options = [ 30 | f'--splash={os.path.relpath(os.path.join("Data", "Img", "with_background_530x223.png"), root)}', 31 | f'--icon={os.path.relpath(os.path.join("Data", "Img", "logo.ico"), root)}', 32 | # '--debug=imports', # to debug missing imports 33 | '--hidden-import=sklearn.metrics._pairwise_distances_reduction._datasets_pair', 34 | '--hidden-import=sklearn.metrics._pairwise_distances_reduction._middle_term_computer', 35 | ] 36 | add_data_sep = ';' 37 | 38 | # Get version number (without importing file) 39 | version = None 40 | with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'Main.py'), 'r') as f: 41 | for l in f: 42 | if l.startswith('VERSION'): 43 | version = l.split('=')[1].strip(" \n'\"") 44 | break 45 | 46 | # Get git hash (without git package) 47 | try: 48 | __git_hash__ = subprocess.check_output(['git', 'rev-parse', 'HEAD'], #'--short', 49 | cwd=os.path.dirname(os.path.abspath(__file__))).decode('ascii').strip() 50 | except (subprocess.SubprocessError, FileNotFoundError): 51 | __git_hash__ = 'git_na' 52 | 53 | # Update version.txt file 54 | if os.path.exists('version.txt'): 55 | os.remove('version.txt') 56 | with open('version.txt', 'w') as f: 57 | f.write(f"version={version}\n") 58 | f.write(f"git_hash={__git_hash__}\n") 59 | f.close() 60 | 61 | # Include all Data files (except Zhang table) 62 | linked_data = [ 63 | f'--add-data={os.path.relpath("version.txt", root)}{add_data_sep}.', 64 | f'--add-data={os.path.relpath("Config", root)}{add_data_sep}Config', 65 | ] 66 | for f in sorted(glob.glob(os.path.join('Data', '*'))): 67 | if os.path.isdir(f) and os.path.basename(f) not in ['L1A', 'L1AQC', 'L1B', 'L1BQC', 'L2', 'Plots', 'Reports']: 68 | linked_data.append(f'--add-data={os.path.relpath(f, root)}{add_data_sep}{f}') 69 | elif re.match('^.*\.(txt|csv|sb|nc|hdf)$', os.path.splitext(f)[1]): 70 | linked_data.append(f'--add-data={os.path.relpath(f, root)}{add_data_sep}Data') 71 | 72 | # Run PyInstaller with parameters below 73 | PyInstaller.__main__.run([ 74 | 'Main.py', 75 | f'--name=HyperCP-v{version}-{platform.system()}', 76 | f'--distpath={os.path.join(root, "dist")}', 77 | f'--workpath={os.path.join(root, "build")}', 78 | f'--specpath={root}', 79 | # f'--icon={os.path.relpath(os.path.join("Data", "Img", "HyperCP_banner1.png"), root)}', # TODO make square low-res icon in ico or icon format 80 | '--console', # Open Console (hide console with windowed) 81 | '--noconfirm', 82 | # '--clean', 83 | *linked_data, 84 | *os_specific_options, 85 | ]) 86 | --------------------------------------------------------------------------------