class_docstr: Batched trial that has multiple attached arms, meant to be
  *deployed and evaluated together*, and possibly arm weights, which are
  a measure of how much of the total resources allocated to evaluating
  a batch should go towards evaluating the specific arm. For instance,
  for field experiments the weights could describe the fraction of the
  total experiment population assigned to the different treatment arms.
  Interpretation of the weights is defined in Runner.
  
  NOTE: A `BatchTrial` is not just a trial with many arms; it is a trial,
  for which it is important that the arms are evaluated simultaneously, e.g.
  in an A/B test where the evaluation results are subject to nonstationarity.
  For cases where multiple arms are evaluated separately and independently of
  each other, use multiple `Trial` objects with a single arm each.
  
  Args:
      experiment: Experiment, to which this trial is attached
      generator_run: GeneratorRun, associated with this trial. This can a
          also be set later through `add_arm` or `add_generator_run`, but a
          trial's associated generator run is immutable once set.
      generator_runs: GeneratorRuns, associated with this trial. This can a
          also be set later through `add_arm` or `add_generator_run`, but a
          trial's associated generator run is immutable once set.  This cannot
          be combined with the `generator_run` argument.
      trial_type: Type of this trial, if used in MultiTypeExperiment.
      optimize_for_power: Whether to optimize the weights of arms in this
          trial such that the experiment's power to detect effects of
          certain size is as high as possible. Refer to documentation of
          `BatchTrial.set_status_quo_and_optimize_power` for more detail.
      ttl_seconds: If specified, trials will be considered failed after
          this many seconds since the time the trial was ran, unless the
          trial is completed before then. Meant to be used to detect
          'dead' trials, for which the evaluation process might have
          crashed etc., and which should be considered failed after
          their 'time to live' has passed.
      index: If specified, the trial's index will be set accordingly.
          This should generally not be specified, as in the index will be
          automatically determined based on the number of existing trials.
          This is only used for the purpose of loading from storage.
      lifecycle_stage: The stage of the experiment lifecycle that this
          trial represents
class_docstr_tok: ["Batched","trial","that","has","multiple","attached","arms",",","meant","to","be","*","deployed","and","evaluated","together","*",",","and","possibly","arm","weights",",","which","are","a","measure","of","how","much","of","the","total","resources","allocated","to","evaluating","a","batch","should","go","towards","evaluating","the","specific","arm",".","For","instance",",","for","field","experiments","the","weights","could","describe","the","fraction","of","the","total","experiment","population","assigned","to","the","different","treatment","arms",".","Interpretation","of","the","weights","is","defined","in","Runner",".","NOTE",":","A","`","BatchTrial","`","is","not","just","a","trial","with","many","arms",";","it","is","a","trial",",","for","which","it","is","important","that","the","arms","are","evaluated","simultaneously",",","e.g",".","in","an","A\/B","test","where","the","evaluation","results","are","subject","to","nonstationarity",".","For","cases","where","multiple","arms","are","evaluated","separately","and","independently","of","each","other",",","use","multiple","`","Trial","`","objects","with","a","single","arm","each",".","Args",":","experiment",":","Experiment",",","to","which","this","trial","is","attached","generator_run",":","GeneratorRun",",","associated","with","this","trial",".","This","can","a","also","be","set","later","through","`","add_arm","`","or","`","add_generator_run","`",",","but","a","trial","'s","associated","generator","run","is","immutable","once","set",".","generator_runs",":","GeneratorRuns",",","associated","with","this","trial",".","This","can","a","also","be","set","later","through","`","add_arm","`","or","`","add_generator_run","`",",","but","a","trial","'s","associated","generator","run","is","immutable","once","set",".","This","can","not","be","combined","with","the","`","generator_run","`","argument",".","trial_type",":","Type","of","this","trial",",","if","used","in","MultiTypeExperiment",".","optimize_for_power",":","Whether","to","optimize","the","weights","of","arms","in","this","trial","such","that","the","experiment","'s","power","to","detect","effects","of","certain","size","is","as","high","as","possible",".","Refer","to","documentation","of","`","BatchTrial.set_status_quo_and_optimize_power","`","for","more","detail",".","ttl_seconds",":","If","specified",",","trials","will","be","considered","failed","after","this","many","seconds","since","the","time","the","trial","was","ran",",","unless","the","trial","is","completed","before","then",".","Meant","to","be","used","to","detect","'dead","'","trials",",","for","which","the","evaluation","process","might","have","crashed","etc.",",","and","which","should","be","considered","failed","after","their","'time","to","live","'","has","passed",".","index",":","If","specified",",","the","trial","'s","index","will","be","set","accordingly",".","This","should","generally","not","be","specified",",","as","in","the","index","will","be","automatically","determined","based","on","the","number","of","existing","trials",".","This","is","only","used","for","the","purpose","of","loading","from","storage",".","lifecycle_stage",":","The","stage","of","the","experiment","lifecycle","that","this","trial","represents"]
docstr: Returns arms with a new set of weights normalized
  to the given total.
  
  This method is useful for many runners where we need to normalize weights
  to a certain total without mutating the weights attached to a trial.
  
  Args:
      total: The total weight to which to normalize.
          Default is 1, in which case arm weights
          can be interpreted as probabilities.
      trunc_digits: The number of digits to keep. If the
          resulting total weight is not equal to `total`, re-allocate
          weight in such a way to maintain relative weights as best as
          possible.
  
  Returns:
      Mapping from arms to the new set of weights.
docstr_tok: ["Returns","arms","with","a","new","set","of","weights","normalized","to","the","given","total",".","This","method","is","useful","for","many","runners","where","we","need","to","normalize","weights","to","a","certain","total","without","mutating","the","weights","attached","to","a","trial",".","Args",":","total",":","The","total","weight","to","which","to","normalize",".","Default","is","1",",","in","which","case","arm","weights","can","be","interpreted","as","probabilities",".","trunc_digits",":","The","number","of","digits","to","keep",".","If","the","resulting","total","weight","is","not","equal","to","`","total","`",",","re-allocate","weight","in","such","a","way","to","maintain","relative","weights","as","best","as","possible",".","Returns",":","Mapping","from","arms","to","the","new","set","of","weights","."]
code: def normalized_arm_weights(
      self, total: float = 1, trunc_digits: Optional[int] = None
  ) -> MutableMapping[Arm, float]:
      """Returns arms with a new set of weights normalized
      to the given total.
  
      This method is useful for many runners where we need to normalize weights
      to a certain total without mutating the weights attached to a trial.
  
      Args:
          total: The total weight to which to normalize.
              Default is 1, in which case arm weights
              can be interpreted as probabilities.
          trunc_digits: The number of digits to keep. If the
              resulting total weight is not equal to `total`, re-allocate
              weight in such a way to maintain relative weights as best as
              possible.
  
      Returns:
          Mapping from arms to the new set of weights.
  
      """
      weights = np.array(self.weights)
      if trunc_digits is not None:
          atomic_weight = 10**-trunc_digits
          # pyre-fixme[16]: `float` has no attribute `astype`.
          int_weights = (
              (total / atomic_weight) * (weights / np.sum(weights))
          ).astype(int)
          n_leftover = int(total / atomic_weight) - np.sum(int_weights)
          int_weights[:n_leftover] += 1
          weights = int_weights * atomic_weight
      else:
          weights = weights * (total / np.sum(weights))
      return OrderedDict(zip(self.arms, weights))
  
imports: from __future__ import annotations
  import warnings
  from collections import defaultdict, OrderedDict
  from copy import deepcopy
  from dataclasses import dataclass
  from datetime import datetime
  from enum import Enum
  from logging import Logger
  from typing import DefaultDict, Dict, List, MutableMapping, Optional, Set, TYPE_CHECKING, Union
  import numpy
  from ax.core.arm import Arm
  from ax.core.base_trial import BaseTrial
  from ax.core.data import Data
  from ax.core.generator_run import ArmWeight, GeneratorRun, GeneratorRunType
  from ax.core.trial import immutable_once_run
  from ax.core.types import TCandidateMetadata, TEvaluationOutcome, validate_evaluation_outcome
  from ax.exceptions.core import AxError, UnsupportedError, UserInputError
  from ax.utils.common.base import SortableBase
  from ax.utils.common.docutils import copy_doc
  from ax.utils.common.equality import datetime_equals, equality_typechecker
  from ax.utils.common.logger import _round_floats_for_logging, get_logger
  from ax.utils.common.typeutils import checked_cast, not_none
label_desc: Use image node_id 27 for calling the BatchTrial obj's underlying member method code with example usage: obj.normalized_arm_weights(total, trunc_digits) and returns: OrderedDict