def get_sitecol_shakemap(array_or_id, imts, sitecol=None,
                         assoc_dist=None, discard_assets=False):
    """
    :param array_or_id: shakemap array or shakemap ID
    :param imts: required IMTs as a list of strings
    :param sitecol: SiteCollection used to reduce the shakemap
    :param assoc_dist: association distance
    :param discard_assets: set to zero the risk on assets with missing IMTs
    :returns: a pair (filtered site collection, filtered shakemap)
    """
    if isinstance(array_or_id, str):  # shakemap ID
        array = download_array(array_or_id)
    else:  # shakemap array
        array = array_or_id
    available_imts = set(array['val'].dtype.names)
    missing = set(imts) - available_imts
    if missing:
        msg = ('The IMT %s is required but not in the available set %s, '
               'please change the riskmodel otherwise you will have '
               'incorrect zero losses for the associated taxonomies' %
               (missing.pop(), ', '.join(available_imts)))
        if discard_assets:
            logging.error(msg)
        else:
            raise RuntimeError(msg)

    # build a copy of the ShakeMap with only the relevant IMTs
    dt = [(imt, F32) for imt in sorted(available_imts)]
    dtlist = [('lon', F32), ('lat', F32), ('vs30', F32),
              ('val', dt), ('std', dt)]
    data = numpy.zeros(len(array), dtlist)
    for name in ('lon',  'lat', 'vs30'):
        data[name] = array[name]
    for name in ('val', 'std'):
        for im in available_imts:
            data[name][im] = array[name][im]

    if sitecol is None:  # extract the sites from the shakemap
        return site.SiteCollection.from_shakemap(data), data

    # associate the shakemap to the (filtered) site collection
    bbox = (data['lon'].min(), data['lat'].min(),
            data['lon'].max(), data['lat'].max())
    indices = sitecol.within_bbox(bbox)
    if len(indices) == 0:
        raise RuntimeError('There are no sites within the boundind box %s'
                           % str(bbox))
    sites = sitecol.filtered(indices)
    logging.info('Associating %d GMVs to %d sites', len(data), len(sites))
    return geo.utils.assoc(data, sites, assoc_dist, 'warn')
:param array_or_id: shakemap array or shakemap ID
    :param imts: required IMTs as a list of strings
    :param sitecol: SiteCollection used to reduce the shakemap
    :param assoc_dist: association distance
    :param discard_assets: set to zero the risk on assets with missing IMTs
    :returns: a pair (filtered site collection, filtered shakemap)