    def __blended_nowcast_main_loop(self):
        """
        Main nowcast loop that iterates through the ensemble members and time steps
        to generate forecasts.
        """
        # Isolate the last time slice of observed precipitation
        self.__precip = self.__precip[-1, :, :]
        print("Starting blended nowcast computation.")

        if self.__config.measure_time:
            starttime_mainloop = time.time()
        self.__state.extrapolation_kwargs["return_displacement"] = True

        self.__state.precip_cascades_prev_subtimestep = deepcopy(
            self.__state.precip_cascades
        )
        self.__state.cascade_noise_prev_subtimestep = deepcopy(
            self.__state.precip_noise_cascades
        )

        self.__state.time_prev_timestep = [
            0.0 for j in range(self.__config.n_ens_members)
        ]
        self.__state.leadtime_since_start_forecast = [
            0.0 for j in range(self.__config.n_ens_members)
        ]

        # iterate each time step
        for t, subtimestep_idx in enumerate(self.__timesteps):
            self.__determine_subtimesteps_and_nowcast_time_step(t, subtimestep_idx)
            if self.__config.measure_time:
                starttime = time.time()
            self.__decompose_nwp_if_needed_and_fill_nans_in_nwp(t)
            self.__find_nowcast_NWP_combination(t)
            self.__determine_skill_for_current_timestep(t)
            # the nowcast iteration for each ensemble member
            final_blended_forecast_all_members_one_timestep = [
                None for _ in range(self.__config.n_ens_members)
            ]

            def worker(j):
                worker_state = copy(self.__state)
                self.__determine_NWP_skill_for_next_timestep(t, j, worker_state)
                self.__determine_weights_per_component(worker_state)
                self.__regress_extrapolation_and_noise_cascades(j, worker_state)
                self.__perturb_blend_and_advect_extrapolation_and_noise_to_current_timestep(
                    t, j, worker_state
                )
                # 8.5 Blend the cascades
                final_blended_forecast_single_member = []
                for t_sub in self.__state.subtimesteps:
                    # TODO: does it make sense to use sub time steps - check if it works?
                    if t_sub > 0:
                        self.__blend_cascades(t_sub, j, worker_state)
                        self.__recompose_cascade_to_rainfall_field(j, worker_state)
                        final_blended_forecast_single_member = (
                            self.__post_process_output(
                                j, final_blended_forecast_single_member, worker_state
                            )
                        )
                    final_blended_forecast_all_members_one_timestep[j] = (
                        final_blended_forecast_single_member
                    )

            dask_worker_collection = []

            if DASK_IMPORTED and self.__config.n_ens_members > 1:
                for j in range(self.__config.n_ens_members):
                    dask_worker_collection.append(dask.delayed(worker)(j))
                dask.compute(
                    *dask_worker_collection,
                    num_workers=self.__params.num_ensemble_workers,
                )
            else:
                for j in range(self.__config.n_ens_members):
                    worker(j)

            dask_worker_collection = None

            if self.__state.is_nowcast_time_step:
                if self.__config.measure_time:
                    _ = self.__measure_time("subtimestep", starttime)
                else:
                    print("done.")

            if self.__config.callback is not None:
                precip_forecast_final = np.stack(
                    final_blended_forecast_all_members_one_timestep
                )
                if precip_forecast_final.shape[1] > 0:
                    self.__config.callback(precip_forecast_final.squeeze())

            if self.__config.return_output:
                for j in range(self.__config.n_ens_members):
                    self.__state.final_blended_forecast[j].extend(
                        final_blended_forecast_all_members_one_timestep[j]
                    )

            final_blended_forecast_all_members_one_timestep = None
        if self.__config.measure_time:
            self.__mainloop_time = time.time() - starttime_mainloop
Main nowcast loop that iterates through the ensemble members and time steps
to generate forecasts.
pysteps/blending/steps.py