i need to modify the below code for the function 'calculate_reward', based on the new objectives
Objectives:
i have four performance metrics ['gain', 'bw', 'ugf', 'pm'], 'c_metrics' represents the current performance metrics outputs and 'p_metrics' represents the previous performance metrics outputs. we need to modify the calculate_reward function to improve the performance of the process. the putput of the function is given as environment feedback to the reinforcement learning, so we need to carfully craft the code to represent the proper and correct improvements of the results and deviation of the results througn the rewards computation.

for the four performance metrics we have individual bounds 'PERFORMANCE_METRICS_TARGET_LOW' and 'PERFORMANCE_METRICS_TARGET_HIGH'
for the 'gain', 'bw', 'ugf', as much as larger even greater than the 'PERFORMANCE_METRICS_TARGET_HIGH' is highly rewarded, lower than the 'PERFORMANCE_METRICS_TARGET_LOW' are highly penalized.
for the 'gain', 'bw', 'ugf', we need to promote the process by giving rewards, if the 'c_metrics' is larger than the 'p_metrics' and 'PERFORMANCE_METRICS_TARGET_LOW', and we need to give large reward if 'c_metrics' is larger than the 'p_metrics' and 'PERFORMANCE_METRICS_TARGET_HIGH'.
for the 'gain', 'bw', 'ugf', we need to depromote the process by giving large penalties, if the 'c_metrics' is smaller than the 'p_metrics' and 'PERFORMANCE_METRICS_TARGET_LOW'
for the 'pm', only with the bounds 'PERFORMANCE_METRICS_TARGET_LOW' and 'PERFORMANCE_METRICS_TARGET_HIGH' are highly rewarded, if any value less than the 'PERFORMANCE_METRICS_TARGET_LOW' and greater than the 'PERFORMANCE_METRICS_TARGET_HIGH' are highly penalized.
for the 'pm', we need to depromote the process by giving large penalties, if the 'c_metrics' is smaller than the 'p_metrics' and 'PERFORMANCE_METRICS_TARGET_LOW' and  'c_metrics' is larger than the 'p_metrics' and 'PERFORMANCE_METRICS_TARGET_HIGH'

cumulate all my requirements mentioned in my objective and provide me an very appropriate and proper and perfect code for the function 'calculate_reward'.

# Define the constants and target metrics for reward calculation
PERFORMANCE_METRICS_TARGET_LOW = np.array([48, 30e3, 30e6, 60])
PERFORMANCE_METRICS_TARGET_HIGH = np.array([100, 100e3, 100e6, 75])

LARGE_REWARD = 10
SMALL_REWARD = 5
PENALTY = 5
ADDITIONAL_PENALTY = 0.5
LARGE_PENALTY = 10

    def is_performance_metrics_in_target(self, metrics):
        return np.all(metrics >= self.PERFORMANCE_METRICS_TARGET_LOW) and np.all(metrics <= self.PERFORMANCE_METRICS_TARGET_HIGH)      
    
    def calculate_reward(self, c_metrics, p_metrics):
            metrics_order = ['gain', 'bw', 'ugf', 'pm']
            
            reward = 0  
           
            current_metrics = np.array([c_metrics[k] for k in metrics_order])
            
            performance_metrics_in_target = self.is_performance_metrics_in_target(current_metrics)
            
            if performance_metrics_in_target:
                reward += 200
                return reward    
           
            for idx, metric_name in enumerate(metrics_order):
                current_value = c_metrics[metric_name]
                previous_value = p_metrics[metric_name]
                target_low = self.PERFORMANCE_METRICS_TARGET_LOW[idx]
                target_high = self.PERFORMANCE_METRICS_TARGET_HIGH[idx]
                               
                if metric_name in ['gain', 'bw', 'ugf']:
                    if current_value > previous_value:
                        reward += self.SMALL_REWARD
                        if current_value > target_high:
                            reward += self.LARGE_REWARD
                    elif current_value < target_low:
                        reward -= self.LARGE_PENALTY
                
                elif metric_name == 'pm':
                    if target_low <= current_value <= target_high:
                        reward += self.LARGE_REWARD
                    else:
                        reward -= self.LARGE_PENALTY
                        
                if metric_name == 'gain' and current_value < 0:
                    reward -= 100
            
            return reward