Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

https://doi.org/10.5281/zenodo.15690037
18 June 2025, 11:59:23 UTC
  • Code
  • Branches (0)
  • Releases (1)
  • Visits
    • Branches
    • Releases
      • 1
      • 1
    • 6d53078
    • /
    • dmaciel123-BRAZA-b9360a9
    • /
    • Scripts
    • /
    • Oxygen_peak_calculation.R
    Raw File Download

    To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
    Select below a type of object currently browsed in order to display its associated SWHID and permalink.

    • content
    • directory
    • snapshot
    • release
    origin badgecontent badge
    swh:1:cnt:47e68b444bfd47797578b95f47ccec899290f564
    origin badgedirectory badge
    swh:1:dir:800709718798e2ec38f54de29db55bbe58074706
    origin badgesnapshot badge
    swh:1:snp:751ae64375449ec5a7624a34dea2901f039df8e6
    origin badgerelease badge
    swh:1:rel:63f034f46a613d794f3480d38698b1371e3757bc

    This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
    Select below a type of object currently browsed in order to generate citations for them.

    • content
    • directory
    • snapshot
    • release
    Generate software citation in BibTex format (requires biblatex-software package)
    Generating citation ...
    Generate software citation in BibTex format (requires biblatex-software package)
    Generating citation ...
    Generate software citation in BibTex format (requires biblatex-software package)
    Generating citation ...
    Generate software citation in BibTex format (requires biblatex-software package)
    Generating citation ...
    Oxygen_peak_calculation.R
    # This script is called by Run.R to calculate calculates the oxygen peak height at around 762 nm on GLORIA Rrs spectra
    #
    # OAI: Oxygen absorption peak index
    # equation: OAI=Rrs762-Rrs750-(Rrs780-Rrs750)*(762-750)/(780-750)
    #
    # the Oxygen peak height is calculated as the following steps: 
    # step 1: check if there is a peak/valley at around 762 nm,
    #		  if no peak/valley, use the median(Rrs745,Rrs755), median(Rrs755,Rrs770) and median(Rrs775,Rrs785) to calculate OAI;
    # step 2: if there are peaks/valleys, then check how many peaks, 
    #		  if there is only one peak/valley, then use this peak/valley (Rrs, wavelength) to calculate OAI;
    # step 3: if there are more than one peaks/valleys, use the highest peak or lowest valley (Rrs, wavelength) for the OAI calculation;
    #
    # note: in the case of extremely turbid waters or algae bloom waters, the Rrs at ~780nm will be very high, which will underestimate the OAI, so for those 
    #       cases, the Rrs at ~755nm ~762nm and ~769nm were used to calculate OAI. 
    #       extremely turbid or algae bloom waters were identified using the Rrs slope between 775 and 799nm.
    #
    #
    # Dalin Jiang, University of Stirling, UK
    #
    # dalin.jiang@stir.ac.uk
    # 
    # June 20, 2022
    #
    #
    #
    # inputs of the function:
    # 1.Rrs_spec: Rrs, array
    # 2.wave_min: min wavelength of Rrs, number
    # 3.wave_max: max wavelength of Rrs, number
    # 4.wave_int: interval of wavelength, number
    #
    # output of the function:
    # Oxygen peak height: (1) >0 indicate it's peak (2) <0 indicate it's valley.
    #
    
    
    # ---------------------------------function---------------------------------------------------
    # updated version, standerdized Rrs, dynamic 745-755, max peak 761-767, dynamic 775-785
    
    OAI_Dalin<-function(Rrs_spec,wave_min,wave_max,wave_int){
    	Rrs_spec <- as.numeric(Rrs_spec)
    	# standardize the spectrum
    	Rrs_spec <- (Rrs_spec - mean(Rrs_spec,na.rm=TRUE))/(sd(Rrs_spec,na.rm=TRUE))
    	names(Rrs_spec) <- paste("Rrs",seq(wave_min,wave_max,wave_int),sep="")
    
    	pos_750<-paste("Rrs",seq(745,755),sep="")
    	pos_765<-paste("Rrs",seq(755,770),sep="")
    	pos_780<-paste("Rrs",seq(775,785),sep="")
    	
    	
    	#------ part I, find the max Oxygen peak-------
    	x <- Rrs_spec[pos_765]
    	x_valid <- x[which(!is.na(x))]
    	
    	if(length(x_valid) > 3 & all(!is.na(Rrs_spec[pos_780]))){
    		dif_sign <- sign(diff(x_valid))
    		if(all(dif_sign == 1) | all(dif_sign == -1) | all(dif_sign == 0)){              # case 1, no peaks, then take the median
    			pks <- median(x_valid)
    			pks_wave <- median(as.numeric(gsub("Rrs","",names(x_valid)))) 
    			pks_sign <- 0
    			turbid <- 0
    		}else{                                # case 2, there are peaks
    			sg <- diff(dif_sign)
    			pos <- which(abs(sg) > 0)+1       # all peaks position
    			if(length(pos) > 1){              # case 2.1, more than one peaks				 
    				# find the max peak location
    				nir_slope <- lm(Rrs_spec[paste("Rrs",seq(775,799),sep="")]~seq(775,799))$coe[2]
    				if( nir_slope < 0.005){       # clear to turbid waters 
    					dif_pks <- which.max(abs(x_valid[pos] - (median(Rrs_spec[pos_750],na.rm=TRUE)+median(Rrs_spec[pos_780],na.rm=TRUE))/2))
    					pks <- x_valid[pos][dif_pks]				 
    					pks_sign <- sg[which(sg != 0)][dif_pks]    # sign of the max peak
    					pks_wave <- as.numeric(gsub("Rrs","",names(pks)))	
    					turbid <- 0					
    				}else{                        # extreme turbid waters or algae bloom waters
    					dif_pks <- which.min(abs(as.numeric(gsub("Rrs","",names(x_valid[pos])))-762))  #find the peak closest 762nm	
    					pks <- x_valid[pos][dif_pks]      			 
    					pks_sign <- sg[which(sg != 0)][dif_pks]                # sign of the max peak
    					pks_wave <- as.numeric(gsub("Rrs","",names(pks)))
    					turbid <- 1	
    				}			
    			}else{                             # case 2.2, only one peak
    				pks <- x_valid[pos]
    				pks_sign <- sg[which(sg != 0)]
    				pks_wave<-as.numeric(gsub("Rrs","",names(pks)))
    				turbid <- 0				
    			}
    		}	
    	}else if(length(x_valid) > 0){       # when where only 1-2 Rrs available
    		pks <- median(x_valid)
    		pks_wave <- median(as.numeric(gsub("Rrs","",names(x_valid)))) 
    		pks_sign <- 0
    		turbid <- 0
    	}else{
    		pks <- NA
    		pks_wave <- NA
    		pks_sign <- NA
    		turbid <- NA
    	}
    	#tmp_out<-c(pks,pks_wave,pks_sign)
    	#names(tmp_out)<-c("pks","pks_wave","pks_sign")
    	
    	#--------- part II, calculate Oxygen peak--------------------
    	if (is.na(turbid)){
    		OAI <- NA
    	}else if(turbid == 1){           # extremely turbid water or algae bloom water
    		if(pks_sign < 0){  # peak
    			med_750 <- min(Rrs_spec[paste("Rrs",seq(750,757),sep="")],na.rm=TRUE)     
    			med_780 <- min(Rrs_spec[paste("Rrs",seq(767,775),sep="")],na.rm=TRUE)
    			OAI <- pks-med_750-(med_780-med_750)*(pks_wave-755.0)/(769.0-755.0)			
    		}else{            # valley
    			med_750 <- max(Rrs_spec[paste("Rrs",seq(750,757),sep="")],na.rm=TRUE)     
    			med_780 <- max(Rrs_spec[paste("Rrs",seq(767,775),sep="")],na.rm=TRUE)
    			OAI <- pks-med_750-(med_780-med_750)*(pks_wave-755.0)/(769.0-755.0)	
    		}	
    	}else{		                 # clear to turbid waters
    		if(pks_sign == 0){             # no peak
    			med_750 <- median(Rrs_spec[pos_750],na.rm=TRUE)     # median value between 745 and 755 nm
    			med_780 <- median(Rrs_spec[pos_780],na.rm=TRUE) 
    			OAI <- pks-med_750-(med_780-med_750)*(pks_wave-750.0)/(780.0-750.0)
    		}else if(pks_sign < 0){        # peak
    			med_750 <- min(Rrs_spec[pos_750],na.rm=TRUE)     # min value between 745 and 755 nm
    			med_780 <- min(Rrs_spec[pos_780],na.rm=TRUE)
    			OAI <- pks-med_750-(med_780-med_750)*(pks_wave-750.0)/(780.0-750.0) 
    		}else if(pks_sign > 0){         # valley
    			med_750 <- max(Rrs_spec[pos_750],na.rm=TRUE)     # max value between 745 and 755 nm
    			med_780 <- max(Rrs_spec[pos_780],na.rm=TRUE)
    			OAI <- pks-med_750-(med_780-med_750)*(pks_wave-750.0)/(780.0-750.0) 
    		}
    	}
    	names(OAI)<-"Oxy_peak_height"
    	#names(turbid)<-"turbid"
    	#return(c(tmp_out,turbid,OAI))
    	
    	
    	
    	return(OAI)
    }
    
    
    ## Added by Daniel Maciel 
    
    flag_creation = function(oxygen_peak) {
      
      OAI = data.frame(oxygen_peak)
      
      OAI$flag = 0
      
      OAI[is.na(OAI$Oxy_peak_height), 'Oxy_peak_height'] = 0
      
      OAI[OAI$Oxy_peak_height > 0.1, 'flag'] = 1
      OAI[OAI$Oxy_peak_height < -0.1, 'flag'] = 1
      
      OAI[OAI$Oxy_peak_height == 0, 'Oxy_peak_height'] = NaN
      
      return(OAI[,c('GLORIA_ID','Oxy_peak_height', 'flag')])
      
      
    }
    
    #------------------------------------------- processing chain---------------------------------------------
    
    

    back to top

    Software Heritage — Copyright (C) 2015–2026, The Software Heritage developers. License: GNU AGPLv3+.
    The source code of Software Heritage itself is available on our development forge.
    The source code files archived by Software Heritage are available under their own copyright and licenses.
    Terms of use: Archive access, API— Content policy— Contact— JavaScript license information— Web API