def METHOD_NAME(start, end):
    """
    Takes visualization start/end timestamps
    and returns the start/end/granularity
    of the snuba query that we should execute
    Attributes:
    start: datetime representing start of visualization window
    end: datetime representing end of visualization window
    Returns:
    results: namedtuple containing
        query_start: datetime representing start of query window
        query_end: datetime representing end of query window
        granularity: granularity to use (in seconds)
    """
    anomaly_detection_range = end - start
    if anomaly_detection_range > timedelta(days=14):
        snuba_range = timedelta(days=90)
        granularity = 3600
    elif anomaly_detection_range > timedelta(days=1):
        granularity = 1200
        snuba_range = timedelta(days=28)
    else:
        snuba_range = timedelta(days=14)
        granularity = 600
    additional_time_needed = snuba_range - anomaly_detection_range
    now = datetime.utcnow().astimezone(timezone.utc)
    start_limit = now - timedelta(days=90)
    end_limit = now
    start = max(start, start_limit)
    end = min(end, end_limit)
    # By default, expand windows equally in both directions
    window_increase = additional_time_needed / 2
    query_start, query_end = None, None
    # If window will go back farther than 90 days, use today - 90 as start
    if start - window_increase < start_limit:
        query_start = now - timedelta(days=90)
        additional_time_needed -= start - query_start
        window_increase = additional_time_needed
    # If window extends beyond today, use today as end
    if end + window_increase > end_limit:
        query_end = now
        additional_time_needed -= query_end - end
        window_increase = additional_time_needed
    query_start = query_start or max(start - window_increase, start_limit)
    query_end = query_end or min(end + window_increase, end_limit)
    return MappedParams(
        query_start,
        query_end,
        granularity,
    )