in this below code, i need you to update the code with additional conditions, among the metrics, if the metric 'Gain' is negative value then we need to assign penalty as -100 and one more condition need to include that is if the condition satisfies 'all_in_saturation' then need to reward +100 in the reward computation.

    def calculate_reward(self, c_metrics, p_metrics, transistor_regions, previous_transistor_regions):
        
        c_metrics = self.normalize_performance_metrics(c_metrics)
        p_metrics = self.normalize_performance_metrics(p_metrics)
        
        # Define order of metrics
        metrics_order = ['Area', 'PowerDissipation', 'SlewRate', 'Gain', 'Bandwidth3dB', 'UnityGainFreq', 'PhaseMargin']
        importance_factor = [10, 10, 5, 10, 5, 5, 10]  # Hypothetical importance weights for each metric
        #importance_factor = [5, 5, 2, 3, 2, 4, 3]  # Hypothetical importance weights for each metric
        current_metrics = np.array([c_metrics[k] for k in metrics_order])
        previous_metrics = np.array([p_metrics[k] for k in metrics_order])         
        
        reward = 0
    
        # Check if all transistors are in saturation
        all_in_saturation = all(region == 2 for region in transistor_regions.values())
        print("all_in_saturation", all_in_saturation)
        print("transistor_regions", transistor_regions)
    
        # Check if the performance metrics is within the target specification
        performance_metrics_in_target = self.is_performance_metrics_in_target(current_metrics)
        
        # Additional penalty condition check
        if current_metrics[3] < 0 and current_metrics[5] == 0 and current_metrics[6] == 0:
            # Applying a small penalty times 5 for the stated condition
            reward -= self.ADDITIONAL_PENALTY * 5
        
        # Check if the performance metrics is better or worse than before
        # Initialize an array to track if performance is getting better for each metric
        performance_metrics_getting_better = np.zeros_like(current_metrics, dtype=bool)        
               
        # Iterate over each metric and define our condition for ‘better’ based on the metric
        for idx, (current, previous) in enumerate(zip(current_metrics, previous_metrics)):            
            if idx < 2:  # Smaller is better for 'area' & 'power dissipation'
                improvement = previous - current
                if improvement > 0:
                    reward += improvement * importance_factor[idx] * self.SMALL_REWARD  # Dynamically scale reward
                    performance_metrics_getting_better[idx] = True
            else:  # Larger is better for the other metrics
                improvement = current - previous
                if improvement > 0:
                    reward += improvement * importance_factor[idx] * self.SMALL_REWARD
                    performance_metrics_getting_better[idx] = True
        
        # Check how many transistors were not in saturation previously and are in saturation now
        newly_in_saturation = sum(1 for current_region, previous_region in zip(transistor_regions.values(), previous_transistor_regions.values()) if current_region == 2 and previous_region != 2)
        newly_not_in_saturation = sum(1 for region, prev_region in zip(transistor_regions.values(), previous_transistor_regions.values()) if region != 2 and prev_region == 2)
        
        # Count of metrics getting better and worse
        num_better = np.count_nonzero(performance_metrics_getting_better)
        num_worse = len(current_metrics) - num_better                       
           
        # Reward if all performance metrics are improving and all transistors are in saturation
        if num_better == len(current_metrics) and all_in_saturation:
            reward += self.LARGE_REWARD
    
        # Else if performance metrics are all within target but not all transistors are in saturation, reward
        elif performance_metrics_in_target and not all_in_saturation:
            reward += self.SMALL_REWARD * 5
    
        # Else if performance metrics are not in target, consider further details
        elif not performance_metrics_in_target:        
            if all_in_saturation:
                # Reward if all transistors are in saturation, even if metrics are not in target
                reward += self.SMALL_REWARD
            
            reward += self.SMALL_REWARD * num_better - self.PENALTY * num_worse
    
            # Reward improvement in saturation, if not already rewarded for all metrics improving
            if newly_in_saturation > 0:
                reward += self.SMALL_REWARD * newly_in_saturation
    
            # Penalize if some transistors have fallen out of saturation since the last evaluation
            if newly_not_in_saturation > 0:
                reward -= self.ADDITIONAL_PENALTY * newly_not_in_saturation
    
        # Independent of the above, penalize if any transistor is out of saturation
        penalty_count = sum(1 for region in transistor_regions.values() if region != 2)
        reward -= self.LARGE_PENALTY * penalty_count        
        normalized_reward = self.normalize_reward(reward)
        normalized_rewards = int(normalized_reward)
        print(f"Original Reward: {reward}, Normalized Reward: {normalized_rewards}")
        return normalized_rewards