# **************** Do OSI analysis on Eigen neurons *******************

        eigRes = np.transpose(eigRes)
        # eigRes contain responses of 'Eigen neurons' - Neuron response in eigen space
        eigCellData = np.zeros((numEigNeurons, stimuliSeq.size, 121))
        eigSpikeRate = np.zeros((numEigNeurons, stimuliSeq.size, 2))

        eigCirvar = np.zeros((numEigNeurons), dtype=np.complex64)
        eigDircirvar = np.zeros((numEigNeurons), dtype=np.complex64)
        for i in xrange(numEigNeurons):
            for j in xrange(stimuliSeq.size):
                theta = stimuliSeq[j]
                eigCellData[i, j] = np.append(eigRes[i, 120*j: 120*(j+1)], np.radians(stimuliSeq[j]) )
            # Calculate spike rate response of each neuron as a real number
            eigSpikeRate[i] = osi.calculateSpikeRate(eigCellData[i])
            eigSpikeRate[i] = preprocessing.scale(eigSpikeRate[i])
            eigCirvar[i], eigDircirvar[i], _, _ = osi.computeAll(eigSpikeRate[i])
        # ************************ OSI analysis ends ****************************
        
        # scatter plot preferred orientation of each eigen neurons
        if False:
            x = np.angle(eigCirvar)
            y = numEigNeurons*np.ones(x.shape)
            if 'figPrefOri' not in locals():
                figPrefOri, axPrefOri = plt.subplots()
                axPrefOri.set_xlabel('Orientation')
                axPrefOri.set_ylabel('Number of principal components')
                axPrefOri.set_title('Orientation of eigen neurons for different components')
            axPrefOri.scatter(x, y, s=30, color='red')
    OI_ref = data['OI'][0,0].reshape((65,))
    OSI_ref = data['OSI'][0,0].reshape((65,))
    
    cellData = np.zeros((smoothData.shape[0], stimuliSeq.size, 121))
    spikeRate = np.zeros((smoothData.shape[0], stimuliSeq.size, 2))
    OSI = np.zeros(smoothData.shape[0])
    DSI = np.zeros(smoothData.shape[0])
    cirvar = np.zeros((smoothData.shape[0]), dtype=np.complex64)
    dircirvar = np.zeros((smoothData.shape[0]), dtype=np.complex64)
    for i in xrange(smoothData.shape[0]):
        for j in xrange(stimuliSeq.size):
            cellData[i, j] = np.append(smoothData[i, 120*j: 120*(j+1)], np.radians(stimuliSeq[j]) )
        # sort the array
        cellData[i] = cellData[i, np.argsort(cellData[i, :, -1])]
        # Calculate spike rate response of each neuron as a real number
        spikeRate[i] = osi.calculateSpikeRate(cellData[i])
        cirvar[i], dircirvar[i], OSI[i], DSI[i] = osi.computeAll(spikeRate[i])

    # ==================== Verify results ===================
    if False:
        print(np.corrcoef(np.abs(cirvar), OSI_ref))   # Higher correlation required
        fig, ax = plt.subplots()
        x = np.array(xrange(OSI.size))
        ax.plot(x, OSI_ref, linewidth=2, label='reference')
        ax.plot(x, np.abs(cirvar), linewidth=2, label='estimated')

    # % ----------------------- k-means clustering ----------
    if False:
        featureVec = np.vstack((np.abs(cirvar), np.abs(dircirvar)))
        featureVec = np.transpose(featureVec)
        whiteFeatureVec = whiten(featureVec)