import pickle

class SparseVolumeData:
    """Sparse volume data class: x, y, z lists of coordinates, value list of corresponding values.
    
    All 4 lists should be the same size. If the value at a 3D point is zero, that point and its value will not be present. This means the x, y, z coordinate lists will be sparse. The presence of a 3D point implies its value is non-zero.
    """
    entrez_id = ''
    symbol = ''
    x = []
    y = []
    z = []
    value = []
    def __init__(self, entrez_id='', symbol=''):
        self.entrez_id = entrez_id
        self.symbol = symbol        
    def size(self):
        return len(self.x)
    def check_size(self):
        nx = len(self.x)
        ny = len(self.y)
        nz = len(self.z)
        nvalue = len(self.value)
        if ny != nx:
            return False
        if nz != nx:
            return False
        if nvalue != nx:
            return False
        return True
    def min_x(self):
        return min(self.x)
    def max_x(self):
        return max(self.x)
    def min_y(self):
        return min(self.y)
    def max_y(self):
        return max(self.y)
    def min_z(self):
        return min(self.z)
    def max_z(self):
        return max(self.z)
    def min_value(self):
        return min(self.value)
    def max_value(self):
        return max(self.value)
    def to_string_info(self):
        return 'entrez_id: ' + str(self.entrez_id) + ', symbol: ' + self.symbol + ', non-zero values: ' + str(self.size())
    def to_string_detail(self):
        s = 'entrez_id: ' + str(self.entrez_id) + ', symbol: ' + self.symbol + '\n'
        s += 'i : x y z : expression value\n'
        for i in range(self.size()):
            s += str(i) + ' : ' + str(self.x[i]) + ' ' + str(self.y[i]) + ' ' + str(self.z[i]) + ' : ' + str(self.value[i]) + '\n' 
        return s

class FullVolumeData:
    #symbol = ''
    #entrez_id = ''
    xmax = 0
    ymax = 0
    zmax = 0
    data = [[[]]]
    def to_string(self):
        #s = 'entrez_id: ' + str(self.entrez_id) + ', symbol: ' + self.symbol + '\n'
        s = 'max x,y,z: ' + str(self.xmax) + ','+ str(self.ymax) + ','+ str(self.zmax) + '\n'
        s += 'i : x y z : expression value\n'
        i = 1
        for x in range(self.xmax + 1):
            for y in range(self.ymax + 1):
                for z in range(self.zmax + 1):
                    if self.data[x][y][z] > 0:
                        s += str(i) + ' : ' + str(x) + ' ' + str(y) + ' ' + str(z) + ' : ' + str(self.data[x][y][z]) + '\n'
                    i += 1 
        return s

def get_entrez_ids():
    entrez_ids = []

    # read list of gene symbols and entrez gene ids from text file
    f = open('genelist.txt', 'r')
    i = 0
    while True:
        line = f.readline()
        if line == '':
            break
        if line.startswith('#'):
            continue
        line = line.strip()
        segs = line.split(', ')
        symbol = a=segs[0]
        entrez_id = segs[1]
        i += 1
        entrez_ids.append(entrez_id)
        #print 'count:', i, 'symbol:', symbol, 'entrez gene id:', entrez_id
    f.close()
    return entrez_ids
        
'''
Testing
'''
'''
sparse_volume_data = SparseVolumeData('12345', 'xxxx')

# initialize object
sparse_volume_data.x = [ 1, 3, 5 ]
sparse_volume_data.y = [ 0, 3, 4 ]
sparse_volume_data.z = [ 2, 3, 4 ]
sparse_volume_data.value = [ 1.5, 7.8, 9.3 ]

print 'size:', sparse_volume_data.size()
print 'size check:', sparse_volume_data.check_size()
print 'sparse volume data:\n', sparse_volume_data.to_string()

# pickle/unpickle object 
filename = 'sparseVolumeData.pkl'
print 'Pickling ' + filename
output = open(filename, 'wb')
pickle.dump(sparse_volume_data, output)
output.close()
print 'Unpickling ' + filename
pkl_file = open(filename, 'rb')
a = pickle.load(pkl_file) 
pkl_file.close()
print 'sparse volume data:\n', a.to_string()
'''    
'''
Testing FullVolumeData
'''
'''
#full_volume_data = FullVolumeData('12345', 'xxxx', 2, 3, 4)
#print 'full volume data:\n', full_volume_data.to_string()

full_volume_data = FullVolumeData(sparse_volume_data)
print 'full volume data:\n', full_volume_data.to_string()
'''

