//  [python]
def _timeseries_recon(bo, mo, chunk_size=25000, preprocess='zscore', recon_loc_inds=None):
    """
    Reconstruction done by chunking by session
        Parameters
    ----------
    bo : Brain object
        Data to be reconstructed

    mo : Model object
        Model to base the reconstructions on

    chunk_size : int
        Size to break data into

    recon_at_loc: list
        Indexes for estimated location in average matrix (location in unknown_inds)

    Returns
    ----------
    results : ndarray
        Compiled reconstructed timeseries
    """
    if preprocess==None:
        data = bo.get_data().values
    elif preprocess=='zscore':
        if bo.data.shape[0]<3:
            warnings.warn('Not enough samples to zscore so it will be skipped.'
            ' Note that this will cause problems if your data are not already '
            'zscored.')
            data = bo.get_data().values
        else:
            data = bo.get_zscore_data()
    else:
        raise('Unsupported preprocessing option: ' + preprocess)

    brain_locs_in_model = _count_overlapping(mo.get_locs(), bo.get_locs())
    model_locs_in_brain = _count_overlapping(bo.get_locs(), mo.get_locs())

    if np.all(model_locs_in_brain):
        #if the model contains all of the locations (or fewer) than what are in the brain object, no reconstructions
        #are needed
        return data[:, brain_locs_in_model]

    #otherwise, we'll need to do some work
    Z = mo.get_model(z_transform=True)
    if ~np.any(brain_locs_in_model):
        #if none of the brain locations are in the model, we need to blur out the model to match up with the
        # locations in the brain object
        ### isnt this bypassed in the set_locs??
        combined_locs = np.vstack((bo.get_locs(), mo.get_locs()))
        model_locs_in_brain = [False]*bo.get_locs().shape[0]
        model_locs_in_brain.extend([True]*mo.get_locs().shape[0])

        rbf_weights = _log_rbf(combined_locs, mo.get_locs())

        from .model import _recover_model #deferred import to remove circular dependency
        Z = _recover_model(*_blur_corrmat(Z, rbf_weights, mo.gpu), z_transform=True)


    K = _z2r(Z)

    known_inds, unknown_inds = known_unknown(mo.get_locs().values, bo.get_locs().values,
                                                  bo.get_locs().values)
    Kaa = K[known_inds, :][:, known_inds]
    Kaa_inv = np.linalg.pinv(Kaa)

    Kba = K[unknown_inds, :][:, known_inds]

    sessions = bo.sessions.unique()
    filter_chunks = []
    chunks = [np.array(i) for session in sessions for i in _chunker(bo.sessions[bo.sessions == session].index.tolist(), chunk_size)]
    for i in chunks:
        filter_chunks.append([x for x in i if x is not None])
    chunks=None


    if recon_loc_inds:
        combined_data = np.zeros((data.shape[0], len(recon_loc_inds)), dtype=data.dtype)

        for x in filter_chunks:
            try:
                combined_data[x,range(len(recon_loc_inds))] = _reconstruct_activity(data[x, :], Kba, Kaa_inv, recon_loc_inds=recon_loc_inds)
            except:
                print('issue with chunksize: ' + str(x))
    else:
        combined_data = np.zeros((data.shape[0], K.shape[0]), dtype=data.dtype)
        combined_data[:, unknown_inds] = np.vstack(list(map(lambda x: _reconstruct_activity(data[x, :], Kba, Kaa_inv),
                                                            filter_chunks)))
        combined_data[:, known_inds] = data

    for s in sessions:
        combined_data[bo.sessions==s, :] = zscore(combined_data[bo.sessions==s, :])

    return combined_data