Parallelizable function for imaging a chunk of data for a single dm.
    Assumes data is dedispersed and resampled, so this just images each integration.
    Simple one-stage imaging that returns dict of params.
    returns dictionary with keys of cand location and values as tuple of features

def image1(d, u, v, w, dmind, dtind, beamnum, irange):
    """ Parallelizable function for imaging a chunk of data for a single dm.
    Assumes data is dedispersed and resampled, so this just images each integration.
    Simple one-stage imaging that returns dict of params.
    returns dictionary with keys of cand location and values as tuple of features
    """

    i0, i1 = irange
    data_resamp = numpyview(data_resamp_mem, 'complex64', datashape(d))

#    logger.info('i0 {0}, i1 {1}, dm {2}, dt {3}, len {4}'.format(i0, i1, dmind, dtind, len(data_resamp)))
    ims,snr,candints = rtlib.imgallfullfilterxyflux(n.outer(u, d['freq']/d['freq_orig'][0]), n.outer(v, d['freq']/d['freq_orig'][0]), data_resamp[i0:i1], d['npixx'], d['npixy'], d['uvres'], d['sigma_image1'])

#    logger.info('finished imaging candints {0}'.format(candints))

    feat = {}
    for i in xrange(len(candints)):
        if snr[i] > 0:
            l1, m1 = calc_lm(d, ims[i], minmax='max')
        else:
            l1, m1 = calc_lm(d, ims[i], minmax='min')
        logger.info('Got one!  Int=%d, DM=%d, dt=%d: SNR_im=%.1f @ (%.2e,%.2e).' % ((i0+candints[i])*d['dtarr'][dtind], d['dmarr'][dmind], d['dtarr'][dtind], snr[i], l1, m1))
        candid =  (d['segment'], (i0+candints[i])*d['dtarr'][dtind], dmind, dtind, beamnum)

#        logger.info(candid)
        
        # assemble feature in requested order
        ff = []
        for feature in d['features']:
            if feature == 'snr1':
                ff.append(snr[i])
            elif feature == 'immax1':
                if snr[i] > 0:
                    ff.append(ims[i].max())
                else:
                    ff.append(ims[i].min())
            elif feature == 'l1':
                ff.append(l1)
            elif feature == 'm1':
                ff.append(m1)
            elif feature == 'im40':  # 40 pixel image peak cutout
                peakx, peaky = n.where(ims[i] == ims[i].max())
                sizex, sizey = ims[i].shape
                # set image window with min=0 and max=size
                xmin = max(0, peakx - 20); xmax = min(peakx + 20, sizex)   
                ymin = max(0, peaky - 20); ymax = min(peaky + 20, sizey)
                ff.append(ims[i][xmin:xmax,ymin:ymax])
            elif feature == 'spec20':  # 20 int spectrum cutout
                # set int window with min 0 and max len()
                imin = max(0, (i0+candints[i])*d['dtarr'][dtind] - 10)
                imax = min( (i0+candints[i])*d['dtarr'][dtind] + 10, len(data_resamp))
                data_cut = data_resamp[imin:imax].copy()
                rtlib.phaseshift_threaded(data_cut, d, l1, m1, u, v)
                ff.append(data_cut.mean(axis=1))
            elif feature in ['specstd', 'specskew', 'speckurtosis']:  # this is standard set and must all appear together
                if feature == 'specstd':  # first this one, then others will use same data
                    seli = (i0+candints[i])*d['dtarr'][dtind]
                    datasel = data_resamp[seli:seli+1].copy()
                    rtlib.phaseshift_threaded(datasel, d, l1, m1, u, v)
                    data = n.ma.masked_equal(datasel, 0j)
                    spec = data.mean(axis=3).mean(axis=1).mean(axis=0).real
                    std = spec.std(axis=0)
                    ff.append(std)
                elif feature == 'specskew':
                    skew = float(mstats.skew(spec))
                    ff.append(skew)
                elif feature == 'speckurtosis':
                    kurtosis = float(mstats.kurtosis(spec))
                    ff.append(kurtosis)
            elif feature == 'imskew':
                skew = float(mstats.skew(ims[i].flatten()))
                ff.append(skew)
            elif feature == 'imkurtosis':
                kurtosis = float(mstats.kurtosis(ims[i].flatten()))
                ff.append(kurtosis)

        feat[candid] = list(ff)
    return feat