import pandas as pd import numpy as np import re from typing import Dict, List, Optional, Union class WaterQualityIndexCalculator: """ 水质光谱指数计算器 为每个算法创建单独的函数,自动查找最接近的波长列 """ def __init__(self): self.references = {} def find_closest_wavelength(self, df_columns: List[str], target_wl: int) -> str: """ 在数据框列名中查找最接近目标波长的列 Args: df_columns: 数据框的所有列名 target_wl: 目标波长 Returns: 最接近的列名 """ # 提取所有数值型波长 numeric_wavelengths = [] for col in df_columns: try: # 从列名中提取数字 numbers = re.findall(r'\d+', col) if numbers: wavelength = int(numbers[0]) numeric_wavelengths.append((col, wavelength)) except: continue if not numeric_wavelengths: raise ValueError(f"无法从列名中提取波长信息: {df_columns}") # 找到最接近的波长 closest_col, closest_wl = min(numeric_wavelengths, key=lambda x: abs(x[1] - target_wl)) print(f"为波长 {target_wl}nm 找到最接近的列: {closest_col} ({closest_wl}nm)") return closest_col # ========================================================================= # 叶绿素算法 # ========================================================================= def chl_Al10SABI(self, df: pd.DataFrame) -> pd.Series: """ Surface Algal Bloom Index (SABI) for chlorophyll detection 参考文献: Alawadi, F. Detection of surface algal blooms using the newly developed algorithm surface algal bloom index (SABI). Proc. SPIE 2010, 7825. """ w857 = df[self.find_closest_wavelength(df.columns, 857)] w644 = df[self.find_closest_wavelength(df.columns, 644)] w458 = df[self.find_closest_wavelength(df.columns, 458)] w529 = df[self.find_closest_wavelength(df.columns, 529)] result = (w857 - w644) / (w458 + w529) return result def chl_Am092Bsub(self, df: pd.DataFrame) -> pd.Series: """ Baseline subtraction algorithm for chlorophyll 参考文献: Amin, R.; Zhou, J.; Gilerson, A.; Gross, B.; Moshary, F.; Ahmed, S. Novel optical techniques for detecting and classifying toxic dinoflagellate Karenia brevis blooms using satellite imagery. Opt. Express 2009, 17, 9126–9144. """ w681 = df[self.find_closest_wavelength(df.columns, 681)] w665 = df[self.find_closest_wavelength(df.columns, 665)] result = w681 - w665 return result def chl_Be16FLHblue(self, df: pd.DataFrame) -> pd.Series: """ Fluorescence Line Height algorithm with blue baseline for chlorophyll 参考文献: Beck, R.A. and 22 others; Comparison of satellite reflectance algorithms for estimating chlorophyll-a in a temperate reservoir using coincident hyperspectral aircraft imagery and dense coincident surface observations, Remote Sens. Environ., 2016, 178, 15-30. """ w529 = df[self.find_closest_wavelength(df.columns, 529)] w644 = df[self.find_closest_wavelength(df.columns, 644)] w458 = df[self.find_closest_wavelength(df.columns, 458)] result = w529 - (w644 + (w458 - w644)) return result def chl_Be16FLHviolet(self, df: pd.DataFrame) -> pd.Series: """ Fluorescence Line Height algorithm with violet baseline for chlorophyll 参考文献: Beck, R.A. and 22 others; Comparison of satellite reflectance algorithms for estimating chlorophyll-a in a temperate reservoir using coincident hyperspectral aircraft imagery and dense coincident surface observations, Remote Sens. Environ., 2016, 178, 15-30. """ w529 = df[self.find_closest_wavelength(df.columns, 529)] w644 = df[self.find_closest_wavelength(df.columns, 644)] w429 = df[self.find_closest_wavelength(df.columns, 429)] result = w529 - (w644 + (w429 - w644)) return result def chl_Be16NDTIblue(self, df: pd.DataFrame) -> pd.Series: """ Normalized Difference Turbidity Index with blue band for chlorophyll 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 543. """ w658 = df[self.find_closest_wavelength(df.columns, 658)] w458 = df[self.find_closest_wavelength(df.columns, 458)] result = (w658 - w458) / (w658 + w458) return result def chl_Be16NDTIviolet(self, df: pd.DataFrame) -> pd.Series: """ Normalized Difference Turbidity Index with violet band for chlorophyll 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 544. """ w658 = df[self.find_closest_wavelength(df.columns, 658)] w444 = df[self.find_closest_wavelength(df.columns, 444)] result = (w658 - w444) / (w658 + w444) return result def chl_De933BDA(self, df: pd.DataFrame) -> pd.Series: """ Band difference algorithm for chlorophyll 参考文献: Dekker, A.; Detection of the optical water quality parameters for eutrophic waters by high resolution remote sensing, Ph.D. thesis, 1993, Free University, Amsterdam. """ w600 = df[self.find_closest_wavelength(df.columns, 600)] w648 = df[self.find_closest_wavelength(df.columns, 648)] w625 = df[self.find_closest_wavelength(df.columns, 625)] result = w600 - w648 - w625 return result def chl_Gi033BDA(self, df: pd.DataFrame) -> pd.Series: """ Gitelson algorithm for chlorophyll estimation 参考文献: Gitelson, A.A.; U. Gritz, and M. N. Merzlyak.; Relationships between leaf chlorophyll content and spectral reflectance and algorithms for non-destructive chlorophyll assessment in higher plant leaves. J. Plant Phys. 2003, 160, 271-282. """ w672 = df[self.find_closest_wavelength(df.columns, 672)] w715 = df[self.find_closest_wavelength(df.columns, 715)] w757 = df[self.find_closest_wavelength(df.columns, 757)] result = ((1 / w672) - (1 / w715)) * w757 return result def chl_Kn07KIVU(self, df: pd.DataFrame) -> pd.Series: """ Kneubuhler algorithm for chlorophyll in Lake Kivu 参考文献: Kneubuhler, M.; Frank T.; Kellenberger, T.W; Pasche N.; Schmid M.; Mapping chlorophyll-a in Lake Kivu with remote sensing methods. 2007, Proceedings of the Envisat Symposium 2007, Montreux, Switzerland 23–27 April 2007 (ESA SP-636, July 2007). """ w458 = df[self.find_closest_wavelength(df.columns, 458)] w644 = df[self.find_closest_wavelength(df.columns, 644)] w529 = df[self.find_closest_wavelength(df.columns, 529)] result = (w458 - w644) / w529 return result def chl_MM12NDCI(self, df: pd.DataFrame) -> pd.Series: """ Normalized Difference Chlorophyll Index 参考文献: Mishra, S.; and Mishra, D.R. Normalized difference chlorophyll index: A novel model for remote estimation of chlorophyll-a concentration in turbid productive waters, Remote Sens. Environ., 2012, 117, 394-406 """ w715 = df[self.find_closest_wavelength(df.columns, 715)] w686 = df[self.find_closest_wavelength(df.columns, 686)] result = (w715 - w686) / (w715 + w686) return result def chl_Zh10FLH(self, df: pd.DataFrame) -> pd.Series: """ Zhao fluorescence line height algorithm for chlorophyll 参考文献: Zhao, D.Z.; Xing, X.G.; Liu, Y.G.; Yang, J.H.; Wang, L. The relation of chlorophyll-a concentration with the reflectance peak near 700 nm in algae-dominated waters and sensitivity of fluorescence algorithms for detecting algal bloom. Int. J. Remote Sens. 2010, 31, 39-48 """ w686 = df[self.find_closest_wavelength(df.columns, 686)] w715 = df[self.find_closest_wavelength(df.columns, 715)] w672 = df[self.find_closest_wavelength(df.columns, 672)] w751 = df[self.find_closest_wavelength(df.columns, 751)] result = w686 - (w715 + (w672 - w751)) return result # ========================================================================= # 蓝藻/藻蓝蛋白算法 (BGA/PC) # ========================================================================= def BGA_Am09KBBI(self, df: pd.DataFrame) -> pd.Series: """ Karenia Brevis Bloom Index for cyanobacteria/phycocyanin 参考文献: Amin, R.; Zhou, J.; Gilerson, A.; Gross, B.; Moshary, F.; Ahmed, S.; Novel optical techniques for detecting and classifying toxic dinoflagellate Karenia brevis blooms using satellite imagery, Optics Express, 2009, 17, 11, 1-13. """ w686 = df[self.find_closest_wavelength(df.columns, 686)] w658 = df[self.find_closest_wavelength(df.columns, 658)] result = (w686 - w658) / (w686 + w658) return result def BGA_Be162B643sub629(self, df: pd.DataFrame) -> pd.Series: """ Band subtraction algorithm for phycocyanin 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 538. """ w644 = df[self.find_closest_wavelength(df.columns, 644)] w629 = df[self.find_closest_wavelength(df.columns, 629)] result = w644 - w629 return result def BGA_Be162B700sub601(self, df: pd.DataFrame) -> pd.Series: """ Band subtraction algorithm for phycocyanin 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 539. """ w700 = df[self.find_closest_wavelength(df.columns, 700)] w601 = df[self.find_closest_wavelength(df.columns, 601)] result = w700 - w601 return result def BGA_Be162BsubPhy(self, df: pd.DataFrame) -> pd.Series: """ Band subtraction algorithm for phytoplankton/phycocyanin 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 540. """ w715 = df[self.find_closest_wavelength(df.columns, 715)] w615 = df[self.find_closest_wavelength(df.columns, 615)] result = w715 - w615 return result def BGA_Be16FLHBlueRedNIR(self, df: pd.DataFrame) -> pd.Series: """ Fluorescence Line Height with Blue-Red-NIR baseline for phycocyanin 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 538. """ w658 = df[self.find_closest_wavelength(df.columns, 658)] w857 = df[self.find_closest_wavelength(df.columns, 857)] w458 = df[self.find_closest_wavelength(df.columns, 458)] result = w658 - (w857 + (w458 - w857)) return result def BGA_Be16FLHGreenRedNIR(self, df: pd.DataFrame) -> pd.Series: """ Fluorescence Line Height with Green-Red-NIR baseline for phycocyanin 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 539. """ w658 = df[self.find_closest_wavelength(df.columns, 658)] w857 = df[self.find_closest_wavelength(df.columns, 857)] w558 = df[self.find_closest_wavelength(df.columns, 558)] result = w658 - (w857 + (w558 - w857)) return result def BGA_Be16FLHVioletRedNIR(self, df: pd.DataFrame) -> pd.Series: """ Fluorescence Line Height with Violet-Red-NIR baseline for phycocyanin 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 538. """ w658 = df[self.find_closest_wavelength(df.columns, 658)] w857 = df[self.find_closest_wavelength(df.columns, 857)] w444 = df[self.find_closest_wavelength(df.columns, 444)] result = w658 - (w857 + (w444 - w857)) return result def BGA_Be16MPI(self, df: pd.DataFrame) -> pd.Series: """ Maximum Peak Index for phycocyanin 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 539. """ w615 = df[self.find_closest_wavelength(df.columns, 615)] w601 = df[self.find_closest_wavelength(df.columns, 601)] w644 = df[self.find_closest_wavelength(df.columns, 644)] result = (w615 - w601) - (w644 - w601) return result def BGA_Be16NDPhyI(self, df: pd.DataFrame) -> pd.Series: """ Normalized Difference Phytoplankton Index for phycocyanin 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 540. """ w700 = df[self.find_closest_wavelength(df.columns, 700)] w622 = df[self.find_closest_wavelength(df.columns, 622)] result = (w700 - w622) / (w700 + w622) return result def BGA_Be16NDPhyI644over615(self, df: pd.DataFrame) -> pd.Series: """ Normalized Difference Phytoplankton Index (644/615) for phycocyanin 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 541. """ w644 = df[self.find_closest_wavelength(df.columns, 644)] w615 = df[self.find_closest_wavelength(df.columns, 615)] result = (w644 - w615) / (w644 + w615) return result def BGA_Be16NDPhyI644over629(self, df: pd.DataFrame) -> pd.Series: """ Normalized Difference Phytoplankton Index (644/629) for phycocyanin 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 542. """ w644 = df[self.find_closest_wavelength(df.columns, 644)] w629 = df[self.find_closest_wavelength(df.columns, 629)] result = (w644 - w629) / (w644 + w629) return result def BGA_Be16Phy2BDA644over629(self, df: pd.DataFrame) -> pd.Series: """ Band ratio algorithm (644/629) for phycocyanin 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 545. """ w644 = df[self.find_closest_wavelength(df.columns, 644)] w629 = df[self.find_closest_wavelength(df.columns, 629)] result = w644 / w629 return result def BGA_Da052BDA(self, df: pd.DataFrame) -> pd.Series: """ Band ratio algorithm (714/672) for phycocyanin 参考文献: Wynne, T. T., Stumpf, R. P., Tomlinson, M. C., Warner, R. A., Tester, P. A., Dyble, J.; Relating spectral shape to cyanobacterial blooms in the Laurentian Great Lakes. Int. J. Remote Sens., 2008, 29, 3665-3672. """ w714 = df[self.find_closest_wavelength(df.columns, 714)] w672 = df[self.find_closest_wavelength(df.columns, 672)] result = w714 / w672 return result def BGA_Go04MCI(self, df: pd.DataFrame) -> pd.Series: """ Maximum Chlorophyll Index for phycocyanin 参考文献: Gower, J.F.R.; Brown,L.; Borstad, G.A.; Observation of chlorophyll fluorescence in west coast waters of Canada using the MODIS satellite sensor. Can. J. Remote Sens., 2004, 30 (1), 17–25. """ w709 = df[self.find_closest_wavelength(df.columns, 709)] w681 = df[self.find_closest_wavelength(df.columns, 681)] w753 = df[self.find_closest_wavelength(df.columns, 753)] result = w709 - w681 - (w753 - w681) return result def BGA_HU103BDA(self, df: pd.DataFrame) -> pd.Series: """ Hunter algorithm for phycocyanin 参考文献: Hunter, P.D.; Tyler, A.N.; Willby, N.J.; Gilvear, D.J.; The spatial dynamics of vertical migration by Microcystis aeruginosa in a eutrophic shallow lake: A case study using high spatial resolution time-series airborne remote sensing. Limn. Oceanogr. 2008, 53, 2391-2406 """ w615 = df[self.find_closest_wavelength(df.columns, 615)] w600 = df[self.find_closest_wavelength(df.columns, 600)] w725 = df[self.find_closest_wavelength(df.columns, 725)] result = (((1 / w615) - (1 / w600)) - w725) return result def BGA_Ku15PhyCI(self, df: pd.DataFrame) -> pd.Series: """ Kudela Phytoplankton Community Index for phycocyanin 参考文献: Kudela, R.M., Palacios, S.L., Austerberry, D.C., Accorsi, E.K., Guild, L.S.; Application of hyperspectral remote sensing to cyanobacterial blooms in inland waters, Torres-Perez, J., 2015, Remote Sens. Environ., 2015, 167, 1-10. """ w681 = df[self.find_closest_wavelength(df.columns, 681)] w665 = df[self.find_closest_wavelength(df.columns, 665)] w709 = df[self.find_closest_wavelength(df.columns, 709)] result = -1 * (w681 - w665 - (w709 - w665)) return result def BGA_Ku15SLH(self, df: pd.DataFrame) -> pd.Series: """ Kudela Scattering Line Height for phycocyanin 参考文献: Kudela, R.M., Palacios, S.L., Austerberry, D.C., Accorsi, E.K., Guild, L.S.; Application of hyperspectral remote sensing to cyanobacterial blooms in inland waters, Torres-Perez, J., 2015, Remote Sens. Environ., 2015, 167, 1-11. """ w715 = df[self.find_closest_wavelength(df.columns, 715)] w658 = df[self.find_closest_wavelength(df.columns, 658)] result = (w715 - w658) + (w715 - w658) return result def BGA_MI092BDA(self, df: pd.DataFrame) -> pd.Series: """ Mishra band ratio algorithm (700/600) for phycocyanin 参考文献: Mishra, S.; Mishra, D.R.; Schluchter, W. M., A novel algorithm for predicting PC concentrations in cyanobacteria: A proximal hyperspectral remote sensing approach. Remote Sens., 2009, 1, 758–775. """ w700 = df[self.find_closest_wavelength(df.columns, 700)] w600 = df[self.find_closest_wavelength(df.columns, 600)] result = w700 / w600 return result def BGA_MM092BDA(self, df: pd.DataFrame) -> pd.Series: """ Mishra band ratio algorithm (724/600) for phycocyanin 参考文献: Mishra, S.; Mishra, D.R.; Schluchter, W. M., A novel algorithm for predicting PC concentrations in cyanobacteria: A proximal hyperspectral remote sensing approach. Remote Sens., 2009, 1, 758–776. """ w724 = df[self.find_closest_wavelength(df.columns, 724)] w600 = df[self.find_closest_wavelength(df.columns, 600)] result = w724 / w600 return result def BGA_MM12NDCIalt(self, df: pd.DataFrame) -> pd.Series: """ Alternative Normalized Difference Chlorophyll Index for phycocyanin 参考文献: Mishra, S.; Mishra, D.R.; A novel remote sensing algorithm to quantify phycocyanin in cyanobacterial algal blooms, Env. Res. Lett., 2014, 9 (11), DOI:10.1088/1748-9326/9/11/114003 """ w700 = df[self.find_closest_wavelength(df.columns, 700)] w658 = df[self.find_closest_wavelength(df.columns, 658)] result = (w700 - w658) / (w700 + w658) return result def BGA_MM143BDAopt(self, df: pd.DataFrame) -> pd.Series: """ Optimized band algorithm for phycocyanin 参考文献: Mishra, S.; Mishra, D.R.; A novel remote sensing algorithm to quantify phycocyanin in cyanobacterial algal blooms, Env. Res. Lett., 2014, 9 (11), DOI:10.1088/1748-9326/9/11/114004 """ w629 = df[self.find_closest_wavelength(df.columns, 629)] w659 = df[self.find_closest_wavelength(df.columns, 659)] w724 = df[self.find_closest_wavelength(df.columns, 724)] result = ((1 / w629) - (1 / w659)) * w724 return result def BGA_SI052BDA(self, df: pd.DataFrame) -> pd.Series: """ Simis band ratio algorithm (709/620) for phycocyanin 参考文献: Simis, S. G. H.; Peters, S.W. M.; Gons, H. J.; Remote sensing of the cyanobacteria pigment phycocyanin in turbid inland water. Limn. Oceanogr., 2005, 50, 237–245 """ w709 = df[self.find_closest_wavelength(df.columns, 709)] w620 = df[self.find_closest_wavelength(df.columns, 620)] result = w709 / w620 return result def BGA_SM122BDA(self, df: pd.DataFrame) -> pd.Series: """ Mishra band ratio algorithm (709/600) for phycocyanin 参考文献: Mishra, S. Remote sensing of cyanobacteria in turbid productive waters, PhD Dissertation. Mississippi State University, USA. 2012. """ w709 = df[self.find_closest_wavelength(df.columns, 709)] w600 = df[self.find_closest_wavelength(df.columns, 600)] result = w709 / w600 return result def BGA_SY002BDA(self, df: pd.DataFrame) -> pd.Series: """ Schalles-Yacobi band ratio algorithm (650/625) for phycocyanin 参考文献: Schalles, J.; Yacobi, Y. Remote detection and seasonal patterns of phycocyanin, carotenoid and chlorophyll-a pigments in eutrophic waters. Archiv fur Hydrobiologie, Special Issues Advances in Limnology, 2000, 55,153–168 """ w650 = df[self.find_closest_wavelength(df.columns, 650)] w625 = df[self.find_closest_wavelength(df.columns, 625)] result = w650 / w625 return result def BGA_Wy08CI(self, df: pd.DataFrame) -> pd.Series: """ Wynne Cyanobacteria Index for phycocyanin 参考文献: Wynne, T. T., Stumpf, R. P., Tomlinson, M. C., Warner, R. A., Tester, P. A., Dyble, J.; Relating spectral shape to cyanobacterial blooms in the Laurentian Great Lakes. Int. J. Remote Sens., 2008, 29, 3665-3672. """ w686 = df[self.find_closest_wavelength(df.columns, 686)] w672 = df[self.find_closest_wavelength(df.columns, 672)] w715 = df[self.find_closest_wavelength(df.columns, 715)] result = -1 * (w686 - w672 - (w715 - w672)) return result # ========================================================================= # 浊度算法 # ========================================================================= def Turb_Be16GreenPlusRedBothOverViolet(self, df: pd.DataFrame) -> pd.Series: """ Turbidity algorithm: (Green + Red) / Violet 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 538 """ w558 = df[self.find_closest_wavelength(df.columns, 558)] w658 = df[self.find_closest_wavelength(df.columns, 658)] w444 = df[self.find_closest_wavelength(df.columns, 444)] result = (w558 + w658) / w444 return result def Turb_Be16RedOverViolet(self, df: pd.DataFrame) -> pd.Series: """ Turbidity algorithm: Red / Violet 参考文献: Beck, R.; Xu, M.; Zhan, S.; Liu, H.; Johansen, R.A.; Tong, S.; Yang, B.; Shu, S.; Wu, Q.; Wang, S.; Berling, K.; Murray, A.; Emery, E.; Reif, M.; Harwood, J.; Young, J.; Martin, M.; Stillings, G.; Stumpf, R.; Su, H.; Ye, Z.; Huang, Y. Comparison of Satellite Reflectance Algorithms for Estimating Phycocyanin Values and Cyanobacterial Total Biovolume in a Temperate Reservoir Using Coincident Hyperspectral Aircraft Imagery and Dense Coincident Surface Observations. Remote Sens. 2017, 9, 539 """ w658 = df[self.find_closest_wavelength(df.columns, 658)] w444 = df[self.find_closest_wavelength(df.columns, 444)] result = w658 / w444 return result def Turb_Bow06RedOverGreen(self, df: pd.DataFrame) -> pd.Series: """ Turbidity algorithm: Red / Green 参考文献: Bowers, D. G., and C. E. Binding. 2006. "The Optical Properties of Mineral Suspended Particles: A Review and Synthesis." Estuarine Coastal and Shelf Science 67 (1–2): 219–230. doi:10.1016/j.ecss.2005.11.010 """ w658 = df[self.find_closest_wavelength(df.columns, 658)] w558 = df[self.find_closest_wavelength(df.columns, 558)] result = w658 / w558 return result def Turb_Chip09NIROverGreen(self, df: pd.DataFrame) -> pd.Series: """ Turbidity algorithm: NIR / Green 参考文献: Chipman, J. W.; Olmanson, L.G.; Gitelson, A.A.; Remote sensing methods for lake management: A guide for resource managers and decision-makers. 2009. """ w857 = df[self.find_closest_wavelength(df.columns, 857)] w558 = df[self.find_closest_wavelength(df.columns, 558)] result = w857 / w558 return result def Turb_Dox02NIRoverRed(self, df: pd.DataFrame) -> pd.Series: """ Turbidity algorithm: NIR / Red 参考文献: Doxaran, D., Froidefond, J.-M.; Castaing, P. ; A reflectance band ratio used to estimate suspended matter concentrations in sediment-dominated coastal waters, Remote Sens., 2002, 23, 5079-5085 """ w857 = df[self.find_closest_wavelength(df.columns, 857)] w658 = df[self.find_closest_wavelength(df.columns, 658)] result = w857 / w658 return result def Turb_Frohn09GreenPlusRedBothOverBlue(self, df: pd.DataFrame) -> pd.Series: """ Turbidity algorithm: (Green + Red) / Blue 参考文献: Frohn, R. C., & Autrey, B. C. (2009). Water quality assessment in the Ohio River using new indices for turbidity and chlorophyll-a with Landsat-7 Imagery. Draft Internal Report, US Environmental Protection Agency. """ w558 = df[self.find_closest_wavelength(df.columns, 558)] w658 = df[self.find_closest_wavelength(df.columns, 658)] w458 = df[self.find_closest_wavelength(df.columns, 458)] result = (w558 + w658) / w458 return result def Turb_Harr92NIR(self, df: pd.DataFrame) -> pd.Series: """ Turbidity algorithm: NIR reflectance 参考文献: Schiebe F.R., Harrington J.A., Ritchie J.C. Remote-Sensing of Suspended Sediments—the Lake Chicot, Arkansas Project. Int. J. Remote Sens. 1992;13:1487–1509 """ w857 = df[self.find_closest_wavelength(df.columns, 857)] result = w857 return result def Turb_Lath91RedOverBlue(self, df: pd.DataFrame) -> pd.Series: """ Turbidity algorithm: Red / Blue 参考文献: Lathrop, R. G., Jr., T. M. Lillesand, and B. S. Yandell, 1991. Testing the utility of simple multi-date Thematic Mapper calibration algorithms for monitoring turbid inland waters. International Journal of Remote Sensing """ w658 = df[self.find_closest_wavelength(df.columns, 658)] w458 = df[self.find_closest_wavelength(df.columns, 458)] result = w658 / w458 return result def Turb_Moore80Red(self, df: pd.DataFrame) -> pd.Series: """ Turbidity algorithm: Red reflectance 参考文献: Moore, G.K., Satellite remote sensing of water turbidity, Hydrological Sciences, 1980, 25, 4, 407-422 """ w658 = df[self.find_closest_wavelength(df.columns, 658)] result = w658 return result def calculate_all_indices( self, input_file: str, output_file: str = None, selected_indices: Optional[List[str]] = None ) -> pd.DataFrame: """ 计算所有水质指数 Args: input_file: 输入CSV文件路径 output_file: 输出CSV文件路径(可选) selected_indices: 可选的算法列表,仅计算指定的指数 Returns: 包含计算结果的数据框 """ # 读取数据 df = pd.read_csv(input_file) print(f"成功读取数据,形状: {df.shape}") print(f"数据列: {list(df.columns)}") results = df.copy() # 获取所有算法方法 algorithm_methods = [ method for method in dir(self) if not method.startswith('_') and method not in ['find_closest_wavelength', 'calculate_all_indices'] ] print(f"\n找到 {len(algorithm_methods)} 个算法") if selected_indices is not None: filtered = [] missing = [] for name in selected_indices: if name in algorithm_methods: filtered.append(name) else: missing.append(name) if missing: print(f"警告: 以下算法未找到,将被忽略: {', '.join(missing)}") algorithm_methods = filtered if not algorithm_methods: raise ValueError("未找到可用算法,请检查 selected_indices 参数") # 按算法类型分类计算 algorithm_categories = { 'chlorophyll': [], 'BGA/PC': [], 'turbidity': [] } for method_name in algorithm_methods: if method_name.startswith('Turb'): algorithm_categories['turbidity'].append(method_name) elif any(keyword in method_name for keyword in ['BDA', 'FLH', 'ND', 'sub', 'CI', 'SLH', 'MPI', 'Phy']): if method_name not in algorithm_categories['turbidity']: algorithm_categories['BGA/PC'].append(method_name) else: algorithm_categories['chlorophyll'].append(method_name) # 计算每个类别的算法 for category, algorithms in algorithm_categories.items(): print(f"\n=== 计算 {category} 相关指数 ({len(algorithms)}个算法) ===") for algo_name in algorithms: try: print(f"计算: {algo_name}") method = getattr(self, algo_name) results[algo_name] = method(df) print(f"✓ 成功计算 {algo_name}") except Exception as e: print(f"✗ 计算 {algo_name} 时出错: {str(e)}") results[algo_name] = np.nan # 保存结果 if output_file: results.to_csv(output_file, index=False) print(f"\n结果已保存到: {output_file}") return results def main(): """主函数""" calculator = WaterQualityIndexCalculator() print("=" * 80) print("水质光谱指数计算器") print("=" * 80) # 计算指数 input_file = r"E:\code\WQ\pipeline_result\work_dir\5_training_spectra\training_spectra.csv" # 修改为您的输入文件路径 output_file = r"E:\code\WQ\pipeline_result\work_dir\5_training_spectra\water_quality_results.csv" try: # 设置为 None 时默认计算所有已实现的算法;也可以设置为算法名称列表,例如 ['Al10SABI', 'TurbBe16RedOverViolet'] selected_algorithms = None results = calculator.calculate_all_indices(input_file, output_file, selected_algorithms) # 显示结果统计 print("\n" + "=" * 80) print("计算结果统计:") print("=" * 80) # 只显示计算出的指数列的统计信息 original_columns = pd.read_csv(input_file).columns calculated_columns = [col for col in results.columns if col not in original_columns] if calculated_columns: stats = results[calculated_columns].describe() print(stats) # 按类别显示统计 categories = { '叶绿素算法': [col for col in calculated_columns if not col.startswith('Turb') and not any(x in col for x in ['BDA', 'FLH', 'ND', 'sub', 'CI', 'SLH', 'MPI', 'Phy']) or col in ['Al10SABI', 'Am092Bsub', 'Be16FLHblue', 'Be16FLHviolet', 'Be16NDTIblue', 'Be16NDTIviolet', 'De933BDA', 'Gi033BDA', 'Kn07KIVU', 'MM12NDCI', 'Zh10FLH']], '蓝藻/藻蓝蛋白算法': [col for col in calculated_columns if col not in ['Al10SABI', 'Am092Bsub', 'Be16FLHblue', 'Be16FLHviolet', 'Be16NDTIblue', 'Be16NDTIviolet', 'De933BDA', 'Gi033BDA', 'Kn07KIVU', 'MM12NDCI', 'Zh10FLH'] and not col.startswith('Turb')], '浊度算法': [col for col in calculated_columns if col.startswith('Turb')] } for category, algo_list in categories.items(): if algo_list: print(f"\n{category}统计:") print(results[algo_list].describe()) else: print("没有成功计算任何指数") except FileNotFoundError: print(f"\n错误: 找不到输入文件 {input_file}") print("请确保文件存在,或修改 input_file 变量为正确的文件路径") except Exception as e: print(f"\n计算过程中发生错误: {str(e)}") if __name__ == "__main__": main()