''' CONTACTS: This code was co-developed via the AWIPS II Experimental Products Development Team (EPDT) by personnel from NASA SPoRT, CIRA, and the NWS: Jason Burks/CIRA/MDL (jason.burks@noaa.gov) Nancy Eustice/NWS (nancy.eustice@noaa.gov) Kevin McGrath/NASA SPoRT/Jacobs (kevin.m.mcgrath@nasa.gov) Deb Molenar/NOAA/NESDIS/RAMMB (Debra.Molenar@noaa.gov) Matt Smith/NASA SPoRT/UAH (matthew.r.smith@nasa.gov) Nate Smith/NWS (nate.smith@noaa.gov) INPUT PARAMETERS: @param physicalElement1: Array of satellite data. @param physicalElement2: Array of satellite data. @param calNumber: This integer corresponds to methods in satRgbRecipeCalibration.py, which converts satellite data values to physical values(e.g., IR counts to brightness temperatures). For most data, calNumber is 0 (no calibration required) because these values are already calibrated when passed to this method. The units of the data passed to this method is controlled by the the "unit=" option in the derived parameter definition .xml files. As an example with GOES-R IR data, we need the data to be calibrated to brightness temperature in units of Kelvin. The following line in a derived parameter definition .xml file would accomplish this: Here's an example requesting GOES-13 IR data (unit="IRPixel") in units of Kelvin: In the case of visible imagery, we want the data to be in albedo from 0 to 100. The following line in a derived parameter definition .xml file would accomplish this for GOES-R visible data (unit="%"): If no "unit=" option is included in the "Field abbreviation" derived parameter definition, raw values will be passed to this method. @param coefficient1: Coefficient applied to calibrated values of physicalElement1. @param coefficient2: Coefficient applied to calibrated values of physicalElement2. @param minCalibratedValue: The calibrated satellite data values are clipped to this minimum value. @param maxCalibratedValue: The calibrated satellite data values are clipped to this maximum value. @param gamma: Gamma value used for stretching. @param invert: Invert the final display values (255 - value)? (0 = no, 1 = yes) RETURNS: @return: Display values @rtype: numpy array (int8) DEPENDENCIES: * Numpy * The satRgbRecipeCalibration module found in satRgbRecipeCalibration.py: This is only required and imported if we need to calibrate the satellite data (calNumber != 0). MODIFICATIONS: 20180725: Initial creation. Started with a copy of satRgbRecipeDiff.py (Kevin McGrath/NASA SPORT) ''' import numpy as np def execute(physicalElement1, physicalElement2, calNum, coefficient1, coefficient2, minCalibratedValue, maxCalibratedValue, gamma, invert): ######################### # Create calibrated arrays. if (int(calNum) == 0): # No need to calibrate the data. a1_calibrated = physicalElement1 a2_calibrated = physicalElement2 else: # Import the calibration module. import satRgbRecipeCalibration as calibration # Define calibration method to call. calTypeString = 'calType_' + str(int(calNum)) try: calMethodToCall = getattr(calibration, calTypeString) except AttributeError: return(0) # Calibrate the data by calling calType_ method. a1_calibrated = calMethodToCall(physicalElement1) a2_calibrated = calMethodToCall(physicalElement2) ######################### # Calculate the difference between a1_calibrated and a2_calibrated. diff_calibrated = (coefficient1*a1_calibrated) - (coefficient2*a2_calibrated) ######################### # Clip the calibrated values. diff_calibrated_clipped = np.clip(diff_calibrated, minCalibratedValue, maxCalibratedValue) ######################### # Generate display values by implement EUMETSAT recipe. dispValue_float = 255.*(np.power( (diff_calibrated_clipped - minCalibratedValue)/(maxCalibratedValue - minCalibratedValue), (1./gamma))) ######################### # Invert, if selected. if (invert): dispValue_float = 255. - dispValue_float ######################### # Convert from float to int8. dispValue_byte = np.array(dispValue_float, dtype=np.int8) ######################### # CAVE interprets byte values of 0 as "No Data". Force values of 0 to 1. dispValue_byte[dispValue_byte == 0] = 1 ######################### # For any pixels where physicalElement1 or physicalElement2 is zero (no data), set # the displayValue_byte to 0 (no data) so that the pixel is transparent. dispValue_byte[(physicalElement1 == 0) | (physicalElement2 == 0)] = 0 return dispValue_byte