Example #1
0
    def test_op_tqdm(self):
        # THIRD PARTY
        import tqdm

        pb = pbar.get_progress_bar(display=True, total=2)
        assert isinstance(pb, tqdm.tqdm)

        with pytest.warns(FutureWarning):

            pb = pbar.get_progress_bar(display="gui", total=2)
            assert isinstance(pb, tqdm.gui.tqdm)
Example #2
0
 def test_op_no_tqdm(self, caplog):
     pb = pbar.get_progress_bar(display=True, total=2)
     assert isinstance(pb, pbar._NoOpProgressBar)
     assert "Install the tqdm library" in caplog.text
Example #3
0
 def test_noop(self):
     pb = pbar.get_progress_bar(display=False, total=2)
     assert isinstance(pb, pbar._NoOpProgressBar)
Example #4
0
    def _run_iter(
        self,
        sample: TH.CoordinateType,
        mass: T.Optional[TH.QuantityType] = None,
        *,
        progress: bool = True,
        **kwargs,
    ) -> object:
        """Fit.

        .. todo::

            - Subclass SkyCoord and have metadata mass and potential that
              carry-over. Or embed a SkyCoord in a table with the other
              attributes. or something so that doesn't need continual
              reassignment

        Parameters
        ----------
        sample : :class:`~astropy.coordinates.SkyCoord` instance
            can have shape (nsamp, ) or (nsamp, niter)
        mass : `~astropy.units.Quantity`
            The mass.
        **kwargs
            passed to fitting potential.

        Returns
        -------
        Potential : object

        """
        if mass is None:
            mass = sample.cache.get("mass")

        N, *iterations = sample.shape

        # get samples into the correct frame
        sample = sample.transform_to(self.frame)
        sample.cache["mass"] = mass

        # get # iterations (& reshape no-iteration samples)
        if not iterations:  # only (N, ) -> (N, niter=1)
            iterations = 1
            sample = sample.reshape((-1, iterations))
            sample.cache["mass"] = mass.reshape((-1, iterations))
        else:
            iterations = iterations[0]  # TODO! check shape

        # (iterations, N) -> iter on iterations
        with get_progress_bar(progress, iterations) as pbar:

            for samp, mass in zip(sample.T, sample.cache["mass"].T):
                pbar.update(1)

                # FIXME! need to assign these into sample
                # sample.cache["potential"]
                samp.cache["mass"] = mass

                yield self(
                    samp,
                    mass=mass,
                    **kwargs,
                )
Example #5
0
    def _run_iter(
        self,
        n_or_sample: T.Union[int, TH.SkyCoordType],
        iterations: int = 1,
        *,
        # observer
        c_err: T.Optional[CERR_Type] = None,
        # residual
        observable: T.Optional[str] = None,
        # extra
        random: T.Optional[RandomLike] = None,
        progress: bool = True,
        **kwargs,
    ) -> object:
        """Run pipeline, yielding :class:`PipelineResult` over ``iterations``.

        .. todo::

            - See ``emcee`` for the backend.

        Parameters
        ----------
        n_or_sample : int (optional)
            number of sample points

        iterations : int (optional)
            Number of iterations. Must be > 0.
            Only used if `n_or_sample` is int.

        random : int or |RandomState| or None (optional, keyword-only)
            Random state or seed.

        original_pot : object or None (optional, keyword-only)
        observable : str or None (optional, keyword-only)

        Yields
        ------
        :class:`PipelineResult`
            For each of ``iterations``

        """
        # reshape n_or_sample
        if isinstance(n_or_sample, int):
            n_or_sample = [n_or_sample] * iterations
        elif isinstance(n_or_sample, coord.SkyCoord):
            if len(n_or_sample.shape) == 1:  # scalar
                n_or_sample = [n_or_sample]
            else:  # TODO! not use jank iterator

                def jank_iter(samples, masses):
                    for samp, mass in zip(samples, masses):
                        samp.cache["mass"] = mass
                        yield samp

                n_or_sample = jank_iter(
                    n_or_sample.T,
                    n_or_sample.cache["mass"].T,
                )

        # iterate over number of iterations
        # for _ in tqdm(range(niter), desc="Running Pipeline...", total=niter):
        with get_progress_bar(progress, iterations) as pbar:

            for arg in n_or_sample:
                pbar.update(1)

                yield self(
                    arg,
                    random=random,
                    # observer
                    c_err=c_err,
                    # residual
                    observable=observable,
                    **kwargs,
                )
Example #6
0
    def _run_iter(
        self,
        n: int = 1,
        iterations: int = 1,
        *,
        representation_type: TH.OptRepresentationLikeType = None,
        random: RandomLike = None,
        # extra
        progress: bool = True,
        **kwargs,
    ) -> TH.SkyCoordType:
        """Iteratively sample the potential.

        .. todo::

            - Subclass SkyCoord and have metadata mass and potential that
            carry-over. Or embed a SkyCoord in a table with the other
            attributes. or something so that doesn't need continual
            reassignment

        Parameters
        ----------
        n : int (optional)
            Number of sample points.
        iterations : int (optional)
            Number of iterations. Must be > 0.

        representation_type: |Representation| or None (optional, keyword-only)
            The coordinate representation.
        random : int or |RandomState| or None (optional, keyword-only)
            Random state or seed.
        progress : bool (optional, keyword-only)
            If True, a progress bar will be shown as the sampler progresses.
            If a string, will select a specific tqdm progress bar - most
            notable is 'notebook', which shows a progress bar suitable for
            Jupyter notebooks. If False, no progress bar will be shown.
        **kwargs
            Passed to underlying instance

        Yields
        ------
        |SkyCoord|
            If `sequential` is False.
            The shape of the SkyCoord is ``(n, niter)``
            where a scalar `n` has length 1.

        Raises
        ------
        ValueError
            If number if iterations not greater than 0.

        """
        with get_progress_bar(progress, iterations) as pbar:
            for i in range(0, iterations):  # thru iterations
                pbar.update(1)
                yield self(
                    n=n,
                    representation_type=representation_type,
                    random=random,
                    **kwargs,
                )
Example #7
0
    def _run_iter(
        self,
        fit_potential: T.Union[PotentialWrapper, T.Sequence[PotentialWrapper]],
        original_potential: T.Optional[T.Any] = None,
        observable: T.Optional[str] = None,
        *,
        representation_type: TH.OptRepresentationLikeType = None,
        # extra
        progress: bool = True,
        **kwargs,
    ) -> object:
        """Calculate Residual.

        Parameters
        ----------
        fit_potential : :class:`~PotentialWrapper` or sequence thereof
            The fitted potential. If not already a PotentialWrapper, it is
            wrapped: this means that the frame is :class:`~discO.UnFrame`.
        original_potential : object or :class:`~PotentialWrapper` (optional)
            The original potential. If not already a PotentialWrapper, it is
            wrapped: this means that the frame is :class:`~discO.UnFrame`.

        observable : str or None (optional)
            The quantity on which to calculate the residual.
            Must be method of :class:`~discO.core.wrapper.PotentialWrapper`.
            None (default) becomes the default value at initialization.

        representation_type: representation-resolvable (optional, keyword-only)
            The output representation type. If None (default), uses default
            representation point.

        **kwargs
            Passed to method in :class:`~PotentialWrapper`.
            First mixed in with ``default_params`` (preferring ``kwargs``).

        Returns
        -------
        residual : object
            In `representation_type`.

        Other Parameters
        ----------------
        points : frame-like or |Representation| (optional, keyword-only)
            Not recommended, but allowed, to force the points on which the
            residual is calculated. The points can only be frame-like if the
            frame of the potentials is not :class:`~discO.UnFrame`.
            If not specified, and it shouldn't be, uses points determined
            by the class at initialization.

        """
        if not isinstance(fit_potential, (Sequence, np.ndarray)):
            fit_potential = [fit_potential]

        iterations = len(fit_potential)

        with get_progress_bar(progress, iterations) as pbar:

            for fpot in fit_potential:
                pbar.update(1)

                yield self(
                    fit_potential=fpot,
                    original_potential=original_potential,
                    observable=observable,
                    representation_type=representation_type,
                    **kwargs,
                )