Reproduces candidate and potentially improves sensitivity through better DM and imaging parameters.
    scale* parameters enhance sensitivity by making refining dmgrid and images.
    Other options include: 
      d0['selectpol'] = ['RR']
      d0['flaglist'] = [('blstd', 2.5, 0.05)]

def pipeline_refine(d0, candloc, scaledm=2.1, scalepix=2, scaleuv=1.0, chans=[], returndata=False):
    """ 
    Reproduces candidate and potentially improves sensitivity through better DM and imaging parameters.
    scale* parameters enhance sensitivity by making refining dmgrid and images.
    Other options include: 
      d0['selectpol'] = ['RR']
      d0['flaglist'] = [('blstd', 2.5, 0.05)]
    """

    import rtpipe.parseparams as pp

    assert len(candloc) == 6, 'candloc should be (scan, segment, candint, dmind, dtind, beamnum).'
    scan, segment, candint, dmind, dtind, beamnum = candloc

    d1 = d0.copy() # dont mess with original (mutable!)

    segmenttimes = d1['segmenttimesdict'][scan]

    # if file not at stated full path, assume it is local
    if not os.path.exists(d1['filename']):
        workdir = os.getcwd()
        filename = os.path.join(workdir, os.path.basename(d1['filename']))
    else:
        filename = d1['filename']

    # clean up d1 of superfluous keys
    params = pp.Params()  # will be used as input to rt.set_pipeline
    for key in d1.keys():
        if not hasattr(params, key):
            _ = d1.pop(key)

    d1['npix'] = 0; d1['uvres'] = 0
    d1['savecands'] = False
    d1['savenoise'] = False
    d1['logfile'] = False

    # redefine d. many parameters modified after this to keep from messing up time boundaries/cand location
    d = set_pipeline(filename, scan, **d1)
    if chans:
        d['chans'] = chans

    d['segmenttimes'] = segmenttimes
    d['nsegments'] = len(segmenttimes)

    data_mem = mps.Array(mps.ctypes.c_float, datasize(d)*2)
    u_mem = mps.Array(mps.ctypes.c_float, d['nbl'])
    v_mem = mps.Array(mps.ctypes.c_float, d['nbl'])
    w_mem = mps.Array(mps.ctypes.c_float, d['nbl'])
    data = numpyview(data_mem, 'complex64', datashape(d))
    u = numpyview(u_mem, 'float32', d['nbl'])
    v = numpyview(v_mem, 'float32', d['nbl'])
    w = numpyview(w_mem, 'float32', d['nbl'])

    # fill data, uvw
    data[:] = pipeline_reproduce(d, segment=segment, product='data')
    d['segment'] = segment
    u[:], v[:], w[:] = ps.get_uvw_segment(d, segment)

    # refine parameters
    dmcand = d['dmarr'][dmind]
    if scaledm > 1.:
        try:
            dmdelta = d['dmarr'][dmind+1] - d['dmarr'][dmind]
        except IndexError:
            try:
                dmdelta = d['dmarr'][dmind] - d['dmarr'][dmind-1]
            except IndexError:
                dmdelta = 0.1*dmcand
        d['dmarr'] = list(n.arange(dmcand-dmdelta, dmcand+dmdelta, dmdelta/scaledm))
    elif scaledm == 1.:
        d['dmarr'] = [dmcand]

    d['datadelay'] = [rtlib.calc_delay(d['freq'], d['inttime'],dm).max() for dm in d['dmarr']] + [d['datadelay'][-1]]
    d['dtarr'] = [d['dtarr'][dtind]]
    d['npixx'] = scalepix*d['npixx']
    d['npixy'] = scalepix*d['npixy']
    d['uvres'] = scaleuv*d['uvres']

    # search
    logger.info('Refining DM grid to %s and expanding images to (%d, %d) pix with uvres %d' % (str(d['dmarr']), d['npixx'], d['npixy'], d['uvres']))
    cands = search(d, data_mem, u_mem, v_mem, w_mem)
    cands = {tuple([scan]+list(loc)):list(prop) for (loc, prop) in cands.iteritems()}
    d['featureind'].insert(0, 'scan')

# making cand plot from this
# need to keep from confusing old and new indices
#    im, data = rt.pipeline_reproduce(d, loc[candnum], product='imdata')
#    scan, segment, candint, dmind, dtind, beamnum = loc
#    loclabel = scan, segment, candint, dmind, dtind, beamnum
#    make_cand_plot(d, im, data, loclabel, outname=outname)

    # return info to reproduce/visualize refined cands
    if returndata:
        return data
    else:
        return d, cands