




import enum
import inspect
from typing import Iterable, List, Optional, Tuple, Union


class       SCREAMING_SNAKE_CASE_							(					enum.Enum      ):



	"""simple docstring"""


	__magic_name__      :					Dict			  =		'''timm'''
	__magic_name__      :					str			  =		'''transformers'''







def 							A__   (snake_case      :		str		,  snake_case      :		List[Any]		,  snake_case      :		Any							)    ->	Union[str, Any]:






					if stage_names is None:
										raise ValueError("""Stage_names must be set for transformers backbones"""							)

					if out_features is not None:
										if not isinstance(UpperCamelCase__		,  (list,)							):
															raise ValueError(F'''out_features must be a list {type(UpperCamelCase__							)}'''							)
										if any(feat not in stage_names for feat in out_features							):
															raise ValueError(F'''out_features must be a subset of stage_names: {stage_names} got {out_features}'''							)

					if out_indices is not None:
										if not isinstance(UpperCamelCase__		,  (list, tuple)							):
															raise ValueError(F'''out_indices must be a list or tuple, got {type(UpperCamelCase__							)}'''							)
										if any(idx >= len(UpperCamelCase__							) for idx in out_indices							):
															raise ValueError("""out_indices must be valid indices for stage_names {stage_names}, got {out_indices}"""							)

					if out_features is not None and out_indices is not None:
										if len(UpperCamelCase__							) != len(UpperCamelCase__							):
															raise ValueError("""out_features and out_indices should have the same length if both are set"""							)
										if out_features != [stage_names[idx] for idx in out_indices]:
															raise ValueError("""out_features and out_indices should correspond to the same stages if both are set"""							)





def 							A__   (snake_case      :		int		,  snake_case      :		str		,  snake_case      :		str		,  )    ->	int:






					if out_indices is None and out_features is None:
										__UpperCamelCase				:  Optional[int]								=			[len(UpperCamelCase__							) - 1]
										__UpperCamelCase				:  List[Any]								=			[stage_names[-1]]
					elif out_indices is None and out_features is not None:
										__UpperCamelCase				:  Optional[Any]								=			[stage_names.index(UpperCamelCase__							) for layer in out_features]
					elif out_features is None and out_indices is not None:
										__UpperCamelCase				:  Dict								=			[stage_names[idx] for idx in out_indices]
					return out_features, out_indices





def 							A__   (snake_case      :		Optional[Any]		,  snake_case      :		Tuple		,  snake_case      :		Dict		,  )    ->	Tuple:
					verify_out_features_out_indices(out_features=UpperCamelCase__		,  out_indices=UpperCamelCase__		,  stage_names=UpperCamelCase__							)
					__UpperCamelCase			, __UpperCamelCase				:  Union[str, Any]								=			_align_output_features_output_indices(
					    out_features=UpperCamelCase__		,  out_indices=UpperCamelCase__		,  stage_names=UpperCamelCase__							)
					# Verify that the aligned out_features and out_indices are valid
					verify_out_features_out_indices(out_features=UpperCamelCase__		,  out_indices=UpperCamelCase__		,  stage_names=UpperCamelCase__							)
					return output_features, output_indices


class       SCREAMING_SNAKE_CASE_							:



	"""simple docstring"""


	__magic_name__      :					Optional[BackboneType]			  =		None






	def 				lowerCamelCase__    (				self		:	List[str]				,    lowerCAmelCase		:	Optional[int]  )  ->					None:







						"""simple docstring"""







						if getattr(self				,    """_backbone"""				,    a_  ) is None:
											raise ValueError("""self._backbone must be set before calling _init_timm_backbone"""  )

						# These will diagree with the defaults for the transformers models e.g. for resnet50
						# the transformer model has out_features = ['stem', 'stage1', 'stage2', 'stage3', 'stage4']
						# the timm model has out_features = ['act', 'layer1', 'layer2', 'layer3', 'layer4']
						__UpperCamelCase				:  Union[str, Any]								=			[stage["""module"""] for stage in self._backbone.feature_info.info]
						__UpperCamelCase				:  Tuple								=			[stage["""num_chs"""] for stage in self._backbone.feature_info.info]
						__UpperCamelCase				:  Optional[int]								=			self._backbone.feature_info.out_indices
						__UpperCamelCase				:  List[Any]								=			self._backbone.feature_info.module_name()

						# We verify the out indices and out features are valid
						verify_out_features_out_indices(
						    out_features=a_				,    out_indices=a_				,    stage_names=self.stage_names  )
						__UpperCamelCase			, __UpperCamelCase				:  str								=			out_features, out_indices






	def 				lowerCamelCase__    (				self		:	str				,    lowerCAmelCase		:	Any  )  ->					None:







						"""simple docstring"""







						__UpperCamelCase				:  Dict								=			getattr(a_				,    """stage_names"""  )
						__UpperCamelCase				:  Any								=			getattr(a_				,    """out_features"""				,    a_  )
						__UpperCamelCase				:  int								=			getattr(a_				,    """out_indices"""				,    a_  )

						__UpperCamelCase				:  List[Any]								=			stage_names
						__UpperCamelCase			, __UpperCamelCase				:  Any								=			get_aligned_output_features_output_indices(
						    out_features=a_				,    out_indices=a_				,    stage_names=a_  )
						# Number of channels for each stage. This is set in the transformer backbone model init
						__UpperCamelCase				:  Tuple								=			None






	def 				lowerCamelCase__    (				self		:	str				,    lowerCAmelCase		:	Any  )  ->					None:







						"""simple docstring"""







						__UpperCamelCase				:  Any								=			config

						__UpperCamelCase				:  Union[str, Any]								=			getattr(a_				,    """use_timm_backbone"""				,    a_  )
						__UpperCamelCase				:  List[Any]								=			BackboneType.TIMM if self.use_timm_backbone else BackboneType.TRANSFORMERS

						if self.backbone_type == BackboneType.TIMM:
											self._init_timm_backbone(a_  )
						elif self.backbone_type == BackboneType.TRANSFORMERS:
											self._init_transformers_backbone(a_  )
						else:
											raise ValueError(F'''backbone_type {self.backbone_type} not supported.'''  )






	@property
	def 				lowerCamelCase__    (				self		:	Optional[Any]  )  ->					Tuple:







						"""simple docstring"""







						return self._out_features






	@out_features.setter
	def 				lowerCamelCase__    (				self		:	List[Any]				,    lowerCAmelCase		:	Optional[int]  )  ->					Any:







						"""simple docstring"""







						__UpperCamelCase			, __UpperCamelCase				:  int								=			get_aligned_output_features_output_indices(
						    out_features=a_				,    out_indices=a_				,    stage_names=self.stage_names  )






	@property
	def 				lowerCamelCase__    (				self		:	List[str]  )  ->					str:







						"""simple docstring"""







						return self._out_indices






	@out_indices.setter
	def 				lowerCamelCase__    (				self		:	Optional[int]				,    lowerCAmelCase		:	int  )  ->					List[Any]:







						"""simple docstring"""







						__UpperCamelCase			, __UpperCamelCase				:  Any								=			get_aligned_output_features_output_indices(
						    out_features=a_				,    out_indices=a_				,    stage_names=self.stage_names  )






	@property
	def 				lowerCamelCase__    (				self		:	Union[str, Any]  )  ->					Dict:







						"""simple docstring"""







						return {stage: self.num_features[i] for i, stage in enumerate(self.stage_names  )}






	@property
	def 				lowerCamelCase__    (				self		:	Optional[int]  )  ->					int:







						"""simple docstring"""







						return [self.out_feature_channels[name] for name in self.out_features]






	def 				lowerCamelCase__    (				self		:	str				,    *lowerCAmelCase		:	Dict				,    **lowerCAmelCase		:	List[Any]  )  ->					Tuple:







						"""simple docstring"""







						__UpperCamelCase				:  Optional[Any]								=			dict(inspect.signature(self.forward  ).parameters  )
						__UpperCamelCase				:  int								=			{k: v for k, v in kwargs.items() if k in signature}
						return self(*a_				,    **a_  )






	def 				lowerCamelCase__    (				self		:	List[Any]				,    lowerCAmelCase		:	Union[str, Any]				,    lowerCAmelCase		:	Union[str, Any] = None				,    lowerCAmelCase		:	List[str] = None				,    lowerCAmelCase		:	Optional[Any] = None				,    )  ->					Any:







						"""simple docstring"""







						raise NotImplementedError("""This method should be implemented by the derived class."""  )






	def 				lowerCamelCase__    (				self		:	int  )  ->					int:







						"""simple docstring"""







						__UpperCamelCase				:  str								=			super().to_dict()
						__UpperCamelCase				:  List[Any]								=			output.pop("""_out_features"""  )
						__UpperCamelCase				:  Optional[int]								=			output.pop("""_out_indices"""  )
						return output







class       SCREAMING_SNAKE_CASE_							:



	"""simple docstring"""


	@property
	def 				lowerCamelCase__    (				self		:	Any  )  ->					Optional[Any]:







						"""simple docstring"""







						return self._out_features






	@out_features.setter
	def 				lowerCamelCase__    (				self		:	List[str]				,    lowerCAmelCase		:	Any  )  ->					Dict:







						"""simple docstring"""







						__UpperCamelCase			, __UpperCamelCase				:  Optional[int]								=			get_aligned_output_features_output_indices(
						    out_features=a_				,    out_indices=a_				,    stage_names=self.stage_names  )






	@property
	def 				lowerCamelCase__    (				self		:	int  )  ->					Tuple:







						"""simple docstring"""







						return self._out_indices






	@out_indices.setter
	def 				lowerCamelCase__    (				self		:	Dict				,    lowerCAmelCase		:	List[Any]  )  ->					str:







						"""simple docstring"""







						__UpperCamelCase			, __UpperCamelCase				:  Tuple								=			get_aligned_output_features_output_indices(
						    out_features=a_				,    out_indices=a_				,    stage_names=self.stage_names  )






	def 				lowerCamelCase__    (				self		:	List[str]  )  ->					Union[str, Any]:







						"""simple docstring"""







						__UpperCamelCase				:  int								=			super().to_dict()
						__UpperCamelCase				:  Optional[int]								=			output.pop("""_out_features"""  )
						__UpperCamelCase				:  Dict								=			output.pop("""_out_indices"""  )
						return output












a__		    =    {
    "kilogram": 1,
    "gram": pow(10, 3),
    "milligram": pow(10, 6),
    "metric-ton": pow(10, -3),
    "long-ton": 0.00_0984_2073,
    "short-ton": 0.00_1102_3122,
    "pound": 2.20_4624_4202,
    "stone": 0.15_7473_1728,
    "ounce": 35.2_7399_0723,
    "carrat": 5000,
    "atomic-mass-unit": 6.0_2213_6652e26,
}

a__		    =    {
    "kilogram": 1,
    "gram": pow(10, -3),
    "milligram": pow(10, -6),
    "metric-ton": pow(10, 3),
    "long-ton": 1016.0_4608,
    "short-ton": 907.184,
    "pound": 0.45_3592,
    "stone": 6.3_5029,
    "ounce": 0.028_3495,
    "carrat": 0.0002,
    "atomic-mass-unit": 1.6_6054_0199e-27,
}





def 							A__   (snake_case      :		str		,  snake_case      :		str		,  snake_case      :		float							)    ->	float:
					if to_type not in KILOGRAM_CHART or from_type not in WEIGHT_TYPE_CHART:
										__UpperCamelCase				:  Any								=			(
										    F'''Invalid \'from_type\' or \'to_type\' value: {from_type!r}, {to_type!r}\n'''
										    F'''Supported values are: {", ".join(snake_case							)}'''
										)
										raise ValueError(snake_case							)
					return value * KILOGRAM_CHART[to_type] * WEIGHT_TYPE_CHART[from_type]


if __name__ == "__main__":
	import doctest

	doctest.testmod()






