class_docstr: Represents an entry in database/experiments collection.
  
  Attributes
  ----------
  name: str
     Unique identifier for this experiment per ``user``.
  id: object
     id of the experiment in the database if experiment is configured. Value is ``None``
     if the experiment is not configured.
  refers: dict or list of `Experiment` objects, after initialization is done.
     A dictionary pointing to a past `Experiment` id, ``refers[parent_id]``, whose
     trials we want to add in the history of completed trials we want to re-use.
     For the purpose of convenience and database efficiency, all experiments of a common tree
     share a ``refers[root_id]``, with the root experiment referring to itself.
  version: int
      Current version of this experiment.
  metadata: dict
     Contains managerial information about this `Experiment`.
  max_trials: int
     How many trials must be evaluated, before considering this `Experiment` done.
     This attribute can be updated if the rest of the experiment configuration
     is the same. In that case, if trying to set to an already set experiment,
     it will overwrite the previous one.
  max_broken: int
     How many trials must be broken, before considering this `Experiment` broken.
     This attribute can be updated if the rest of the experiment configuration
     is the same. In that case, if trying to set to an already set experiment,
     it will overwrite the previous one.
  space: Space
     Object representing the optimization space.
  algorithm: `BaseAlgorithm` object or a wrapper.
     Complete specification of the optimization and dynamical procedures taking
     place in this `Experiment`.
  
  Notes
  -----
  
  The following list represents possible entries in the metadata dict.
  
  user: str
     System user currently owning this running process, the one who invoked **Oríon**.
  datetime: `datetime.datetime`
     When was this particular configuration submitted to the database.
  orion_version: str
     Version of **Oríon** which suggested this experiment. `user`'s current
     **Oríon** version.
  user_script: str
     Full absolute path to `user`'s executable.
  user_args: list of str
     Contains separate arguments to be passed when invoking `user_script`,
     possibly templated for **Oríon**.
  user_vcs: str, optional
     User's version control system for this executable's code repository.
  user_version: str, optional
     Current user's repository version.
  user_commit_hash: str, optional
     Current `Experiment`'s commit hash for **Oríon**'s invocation.
class_docstr_tok: ["Represents","an","entry","in","database\/experiments","collection",".","Attributes","--","--","--","--","--","name",":","str","Unique","identifier","for","this","experiment","per","``","user","``",".","id",":","object","id","of","the","experiment","in","the","database","if","experiment","is","configured",".","Value","is","``","None","``","if","the","experiment","is","not","configured",".","refers",":","dict","or","list","of","`","Experiment","`","objects",",","after","initialization","is","done",".","A","dictionary","pointing","to","a","past","`","Experiment","`","id",",","``","refers","[","parent_id","]","``",",","whose","trials","we","want","to","add","in","the","history","of","completed","trials","we","want","to","re-use",".","For","the","purpose","of","convenience","and","database","efficiency",",","all","experiments","of","a","common","tree","share","a","``","refers","[","root_id","]","``",",","with","the","root","experiment","referring","to","itself",".","version",":","int","Current","version","of","this","experiment",".","metadata",":","dict","Contains","managerial","information","about","this","`","Experiment","`",".","max_trials",":","int","How","many","trials","must","be","evaluated",",","before","considering","this","`","Experiment","`","done",".","This","attribute","can","be","updated","if","the","rest","of","the","experiment","configuration","is","the","same",".","In","that","case",",","if","trying","to","set","to","an","already","set","experiment",",","it","will","overwrite","the","previous","one",".","max_broken",":","int","How","many","trials","must","be","broken",",","before","considering","this","`","Experiment","`","broken",".","This","attribute","can","be","updated","if","the","rest","of","the","experiment","configuration","is","the","same",".","In","that","case",",","if","trying","to","set","to","an","already","set","experiment",",","it","will","overwrite","the","previous","one",".","space",":","Space","Object","representing","the","optimization","space",".","algorithm",":","`","BaseAlgorithm","`","object","or","a","wrapper",".","Complete","specification","of","the","optimization","and","dynamical","procedures","taking","place","in","this","`","Experiment","`",".","Notes","--","--","-","The","following","list","represents","possible","entries","in","the","metadata","dict",".","user",":","str","System","user","currently","owning","this","running","process",",","the","one","who","invoked","*","*","Or\u00edon","*","*",".","datetime",":","`","datetime.datetime","`","When","was","this","particular","configuration","submitted","to","the","database",".","orion_version",":","str","Version","of","*","*","Or\u00edon","*","*","which","suggested","this","experiment",".","`","user","`","'s","current","*","*","Or\u00edon","*","*","version",".","user_script",":","str","Full","absolute","path","to","`","user","`","'s","executable",".","user_args",":","list","of","str","Contains","separate","arguments","to","be","passed","when","invoking","`","user_script","`",",","possibly","templated","for","*","*","Or\u00edon","*","*",".","user_vcs",":","str",",","optional","User","'s","version","control","system","for","this","executable","'s","code","repository",".","user_version",":","str",",","optional","Current","user","'s","repository","version",".","user_commit_hash",":","str",",","optional","Current","`","Experiment","`","'s","commit","hash","for","*","*","Or\u00edon","*","*","'s","invocation","."]
docstr: Calculate :py:class:`orion.core.worker.experiment.ExperimentStats` for this particular
  experiment.
docstr_tok: ["Calculate",":","py",":","class",":","`","orion.core.worker.experiment.ExperimentStats","`","for","this","particular","experiment","."]
code: def stats(self):
      """Calculate :py:class:`orion.core.worker.experiment.ExperimentStats` for this particular
      experiment.
      """
      trials = self.fetch_trials(with_evc_tree=False)
      completed_trials = self.fetch_trials_by_status("completed")
  
      # Retrieve the best evaluation, best trial ID, start time and finish time
      # TODO: should we compute finish time as min(completed_trials.start_time)
      # instead of metadata["datetime"]?
      # For elapsed time below, we do not use metadata["datetime"]
      best_evaluation = None
      best_trials_id = None
      start_time = self.metadata.get("datetime", None)
      finish_time = start_time
      if start_time and completed_trials:
          trial = completed_trials[0]
          best_evaluation = trial.objective.value
          best_trials_id = trial.id
          for trial in completed_trials:
              # All trials are going to finish certainly after the start date
              # of the experiment they belong to
              if (
                  trial.end_time > finish_time
              ):  # pylint:disable=no-member
                  finish_time = trial.end_time
              objective = trial.objective.value
              if objective < best_evaluation:
                  best_evaluation = objective
                  best_trials_id = trial.id
  
      # Compute elapsed time using all finished/stopped/running experiments
      # i.e. all trials that have an execution interval
      # (from a start time to an end time or heartbeat)
      intervals = []
      for trial in trials:
          interval = trial.execution_interval
          if interval:
              intervals.append(interval)
      if intervals:
          min_start_time = min(interval[0] for interval in intervals)
          max_end_time = max(interval[1] for interval in intervals)
          elapsed_time = max_end_time - min_start_time
      else:
          elapsed_time = datetime.timedelta()
  
      # Compute ETA
      if not self.max_trials or math.isinf(self.max_trials):
          # If max_trials is None, 0 or infinite, we cannot compute ETA
          eta = None
      elif len(completed_trials) > self.max_trials:
          # If there are more completed trials than max trials, then ETA should be 0
          eta = datetime.timedelta()
      elif not completed_trials:
          # If there are no completed trials, then we set ETA to infinite
          # NB: float("inf") may lead to wrong JSON syntax, so we just write "infinite"
          eta = "infinite"
      else:
          # Compute ETA using duration of completed trials
          completed_intervals = [
              trial.execution_interval for trial in completed_trials
          ]
          min_start_time = min(
              interval[0] for interval in completed_intervals
          )
          max_end_time = max(
              interval[1] for interval in completed_intervals
          )
          completed_duration = max_end_time - min_start_time
          eta = (completed_duration / len(completed_trials)) * (
              self.max_trials - len(completed_trials)
          )
  
      return ExperimentStats(
          trials_completed=len(completed_trials),
          best_trials_id=best_trials_id,
          best_evaluation=best_evaluation,
          start_time=start_time,
          finish_time=finish_time,
          elapsed_time=elapsed_time,
          sum_of_trials_time=sum(
              (trial.duration for trial in trials),
              datetime.timedelta(),
          ),
          nb_trials=len(trials),
          eta=eta,
          eta_milliseconds=eta.total_seconds() * 1000
          if isinstance(eta, datetime.timedelta)
          else None,
          trial_status_count={
              **Counter(trial.status for trial in trials)
          },
          progress=self.progress,
          max_trials=(
              "infinite"
              if self.max_trials is not None
              and math.isinf(self.max_trials)
              else self.max_trials
          ),
      )
  
imports: from __future__ import annotations
  import contextlib
  import copy
  import dataclasses
  import datetime
  import inspect
  import logging
  import math
  import typing
  from collections import Counter
  from dataclasses import dataclass, field
  from typing import Generator, Generic, Literal, TypeVar
  import pandas
  from orion.algo.base import BaseAlgorithm
  from orion.algo.space import Space
  from orion.core.evc.adapters import BaseAdapter
  from orion.core.evc.experiment import ExperimentNode
  from orion.core.io.database import DuplicateKeyError
  from orion.core.utils.exceptions import UnsupportedOperation
  from orion.core.utils.flatten import flatten
  from orion.core.worker.experiment_config import ExperimentConfig
  from orion.storage.base import BaseStorageProtocol, FailedUpdate
label_desc: Use image node_id 30 for calling the Experiment obj's underlying member method code with example usage: obj.stats() and returns: ExperimentStats