99from ..schemas .job import JobStatusEnum
1010from ..schemas .mcda import Goal , Alternative
1111from ..utils .logger import get_logger
12- from ..utils .data_loaders import get_goal_weights_for_perspective , load_mcda_config , normalize_goal_weights
12+ from ..utils .data_loaders import load_mcda_config
13+ from .mcda_goal_builder import (
14+ apply_normalized_goal_weights ,
15+ build_goal_for_name ,
16+ get_goal_weights as get_resolved_goal_weights ,
17+ get_min_max_values_per_goal ,
18+ get_weight_by_goal ,
19+ resolve_goal_weights ,
20+ )
1321
1422# Initialize logger
1523logger = get_logger (__name__ )
@@ -47,15 +55,7 @@ def _get_weight_by_goal(goal_name: str, goal_weights: Optional[Dict[str, float]]
4755 Returns:
4856 Weight value for the goal
4957 """
50- if goal_weights and goal_name in goal_weights :
51- return goal_weights [goal_name ]
52- else :
53- if goal_weights :
54- logger .warning (
55- f"Goal '{ goal_name } ' not found in perspective weights. "
56- f"Using default weight: { default_weight :.3f} "
57- )
58- return default_weight
58+ return get_weight_by_goal (goal_name , goal_weights , default_weight )
5959
6060 @staticmethod
6161 def _get_min_max_values_per_goal (goal_name : str , alternatives : list [Alternative ]) -> tuple [Optional [float ], Optional [float ]]:
@@ -69,16 +69,7 @@ def _get_min_max_values_per_goal(goal_name: str, alternatives: list[Alternative]
6969 Returns:
7070 Tuple of (min_value, max_value) for the goal, or (None, None) if no values found
7171 """
72- min_value = None
73- max_value = None
74- for alt in alternatives :
75- alt_goal_value = alt .values .get (goal_name )
76- if alt_goal_value is not None :
77- if (min_value is None ) or (alt_goal_value < min_value ):
78- min_value = alt_goal_value
79- if (max_value is None ) or (alt_goal_value > max_value ):
80- max_value = alt_goal_value
81- return min_value , max_value
72+ return get_min_max_values_per_goal (goal_name , alternatives )
8273
8374 @staticmethod
8475 def build_alternatives (config : Dict [str , Any ]) -> list [Alternative ]:
@@ -137,32 +128,17 @@ def build_goals(alternatives: list[Alternative], goal_weights: Optional[Dict[str
137128 goals = []
138129
139130 for goal_name in goal_names :
140- weight = McdaQualitativeJob ._get_weight_by_goal (
141- goal_name , goal_weights , default_weight )
142-
143- min_value , max_value = McdaQualitativeJob ._get_min_max_values_per_goal (
144- goal_name , alternatives )
145-
146- if weight is None :
147- logger .warning (
148- f"Skipping goal '{ goal_name } ' due to missing weight" )
149- continue
150- if (min_value is None ) or (max_value is None ):
151- logger .warning (
152- f"Skipping goal '{ goal_name } ' due to missing min/max values min='{ min_value } ', max='{ max_value } '" )
131+ goal = build_goal_for_name (
132+ goal_name = goal_name ,
133+ alternatives = alternatives ,
134+ goal_weights = goal_weights ,
135+ default_weight = default_weight ,
136+ )
137+ if goal is None :
153138 continue
139+ goals .append (goal )
154140
155- goals .append (
156- Goal (
157- name = goal_name ,
158- weight = weight ,
159- direction = "max" ,
160- Q = 0 ,
161- S = 0 ,
162- P = max_value - min_value ,
163- F = 't3'
164- )
165- )
141+ apply_normalized_goal_weights (goals , context_label = "qualitative MCDA" )
166142
167143 logger .info (f"Created { len (goals )} qualitative goals" )
168144 return goals
@@ -179,19 +155,10 @@ def get_goal_weights(perspective: Optional[str]) -> Optional[Dict[str, float]]:
179155 Dictionary mapping normalized goal names to weights,
180156 or None if no perspective or loading fails.
181157 """
182- if perspective :
183- try :
184- goal_weights = get_goal_weights_for_perspective (perspective )
185- logger .info (
186- f"Using qualitative goal weights for perspective: { perspective } " )
187- return goal_weights
188- except ValueError as e :
189- logger .warning (
190- f"Failed to load perspective weights: { e } . Using equal weights." )
191- return None
192- else :
193- logger .info ("No perspective specified, using equal weights" )
194- return None
158+ return get_resolved_goal_weights (
159+ perspective ,
160+ use_qualitative_prefix = True ,
161+ )
195162
196163 @staticmethod
197164 def run (job_id : str , db : Session , params : Optional [Dict ] = None ) -> None :
@@ -236,12 +203,12 @@ def run(job_id: str, db: Session, params: Optional[Dict] = None) -> None:
236203 job_repo .update_job_data (
237204 job_id = job_id , input_data = input_data_snapshot )
238205
239- if perspective == "user_personalized" and personalized_goal_weights :
240- goal_weights = normalize_goal_weights (
241- personalized_goal_weights )
242- logger . info ( "Using user-personalized qualitative goal weights" )
243- else :
244- goal_weights = McdaQualitativeJob . get_goal_weights ( perspective )
206+ goal_weights = resolve_goal_weights (
207+ perspective = perspective ,
208+ personalized_goal_weights = personalized_goal_weights ,
209+ personalized_message = "Using user-personalized qualitative goal weights" ,
210+ use_qualitative_prefix = True ,
211+ )
245212
246213 alternatives = McdaQualitativeJob .build_alternatives (config )
247214 goals = McdaQualitativeJob .build_goals (alternatives , goal_weights )
0 commit comments