Example #1
0
    def parseMap(self):

        # append to log file for this eTrack run 
        logfileName = '{}output/{}_log.txt'.format(self.where,self.pdbName)
        logfile = open(logfileName,'a')
        
        # define 'rho' electron map object
        rho = electron_map_info()

        # open electron density .map file here 
        binarymapfile = open(self.where+self.mapFileName,'rb')
        
        # start adding header information into electron_map_info class format. 
        # Note the unpacking of a struct for each byte, read as a long 'l'
        rho.nx   = struct.unpack('=l',binarymapfile.read(4))[0]
        rho.ny   = struct.unpack('=l',binarymapfile.read(4))[0]
        rho.nz   = struct.unpack('=l',binarymapfile.read(4))[0]
        rho.type = struct.unpack('=l',binarymapfile.read(4))[0]
        print 'Num. Col, Row, Sec: '
        print '{} {} {}'.format(rho.nx,rho.ny,rho.nz)
        logfile.write('Num. Col, Row, Sec: {} {} {}\n'.format(rho.nx,rho.ny,rho.nz))
        
        rho.start1 = struct.unpack('=l',binarymapfile.read(4))[0] 
        rho.start2 = struct.unpack('=l',binarymapfile.read(4))[0] 
        rho.start3 = struct.unpack('=l',binarymapfile.read(4))[0] 
        print 'Start positions: '
        print '{} {} {}'.format(rho.start1,rho.start2,rho.start3)
        logfile.write('Start positions: {} {} {}\n'.format(rho.start1,rho.start2,rho.start3))

        rho.gridsamp1 = struct.unpack('=l',binarymapfile.read(4))[0] 
        rho.gridsamp2 = struct.unpack('=l',binarymapfile.read(4))[0] 
        rho.gridsamp3 = struct.unpack('=l',binarymapfile.read(4))[0]
        print 'Grid sampling:'
        print '{} {} {}'.format(rho.gridsamp1,rho.gridsamp2,rho.gridsamp3)
        logfile.write('Grid sampling: {} {} {}\n'.format(rho.gridsamp1,rho.gridsamp2,rho.gridsamp3))

        # for cell dimensions, stored in header file as float not long 
        # integer so must account for this
        rho.celldim_a       = struct.unpack('f',binarymapfile.read(4))[0]
        rho.celldim_b       = struct.unpack('f',binarymapfile.read(4))[0]
        rho.celldim_c       = struct.unpack('f',binarymapfile.read(4))[0]
        rho.celldim_alpha   = struct.unpack('f',binarymapfile.read(4))[0]
        rho.celldim_beta    = struct.unpack('f',binarymapfile.read(4))[0]
        rho.celldim_gamma    = struct.unpack('f',binarymapfile.read(4))[0]
        print 'Cell dimensions:'
        print '{} {} {}'.format(rho.celldim_a,rho.celldim_b,rho.celldim_c)
        print '{} {} {}'.format(rho.celldim_alpha,rho.celldim_beta,rho.celldim_gamma)
        logfile.write('Cell dimensions: {} {} {} {} {} {}\n'.format(rho.celldim_a,rho.celldim_b,
                                                                    rho.celldim_c,rho.celldim_alpha,
                                                                    rho.celldim_beta,rho.celldim_gamma))

        rho.fast_axis   = struct.unpack('=l',binarymapfile.read(4))[0] 
        rho.med_axis    = struct.unpack('=l',binarymapfile.read(4))[0] 
        rho.slow_axis   = struct.unpack('=l',binarymapfile.read(4))[0] 
        print 'Fast,med,slow axes: '
        print '{} {} {}'.format(rho.fast_axis,rho.med_axis,rho.slow_axis)
        logfile.write('Fast,med,slow axes: {} {} {}\n'.format(rho.fast_axis,rho.med_axis,rho.slow_axis))

        rho.mindensity  = struct.unpack('f',binarymapfile.read(4))[0] 
        rho.maxdensity  = struct.unpack('f',binarymapfile.read(4))[0] 
        rho.meandensity = struct.unpack('f',binarymapfile.read(4))[0]
        print 'Density values: '
        print '{} {} {}'.format(rho.mindensity,rho.maxdensity,rho.meandensity)
        logfile.write('Density values: {} {} {}\n'.format(rho.mindensity,rho.maxdensity,rho.meandensity))

        # next find .map file size, to calculate the last nx*ny*nz bytes of 
        # file (corresponding to the position of the 3D electron density 
        # array). Note factor of 4 is included since 4-byte floats used for 
        # electron density array values.
        filesize = os.path.getsize(self.where+self.mapFileName)
        densitystart = filesize - 4*(rho.nx*rho.ny*rho.nz)
        
        # next seek start of electron density data
        binarymapfile.seek(densitystart,0)
        
        # if electron density written in shorts (I don't think it will be 
        # but best to have this case)
        if rho.type is 1:  
            print 'Untested .map type --> 1 (type 2 expected). Values read' 
            + 'as int16 ("i2?") - consult .map header in MAPDUMP(CCP4) to check'
      
            struct_fmt = '=i2'
            struct_len = struct.calcsize(struct_fmt)
            density = []
           
            while True:
                data = binarymapfile.read(struct_len)
                if not data: break
                s = struct.unpack(struct_fmt,data)[0]
                density.append(s)    
        
        # if electron density written in floats (which is to be expected 
        # from FFT-CCP4 outputted .map file of electron density)
        if rho.type is 2:  
            struct_fmt = '=f4'
            struct_len = struct.calcsize(struct_fmt)
            density = []
            appenddens = density.append
            
            if self.mapType in ('atom_map'):
                self.atomIndices = []
                appendindex = self.atomIndices.append
                counter = -1
                while True:
                    data = binarymapfile.read(struct_len)
                    if not data: break
                    s = struct.unpack(struct_fmt,data)[0]
                    counter += 1
                    if int(s) == 0:
                        continue
                    else:    
                        appenddens(s)
                        appendindex(counter)
            
            # efficient way to read through density map file using indices of atoms
            # from atom map file above
            elif self.mapType in ('density_map'):
                for i in range(0,len(self.atomIndices)):
                    if i != 0:
                        binarymapfile.read(struct_len*(self.atomIndices[i]-self.atomIndices[i-1] - 1))
                    else:
                        binarymapfile.read(struct_len*(self.atomIndices[0]))
                        
                    data = binarymapfile.read(struct_len)
                    s = struct.unpack(struct_fmt,data)[0]
                    appenddens(s)
                    
            else:
                print 'Unknown map type --> terminating script'
                sys.exit()
             
        logfile.close()           
        binarymapfile.close()
        
        # as a check that file has been read correctly, check that the min 
        # and max electron density stated in .map file header correspond to 
        # calculated min and max here
        # Note for the case of atom map, the min voxel val will be 0 (no atom present)
        # --> since these voxels are removed during the filtering of the map, only 
        # the map value is tested.
        # For density map, cannot currently perform a check, since there is no 
        # guarantee that the max and min voxel values may be non atom voxels and
        # thus removed
        if self.mapType in ('atom_map'):        
            if max(density) == rho.maxdensity:
                print 'calculated max voxel value match value stated in file header'
            else:
                print 'calculated max voxel value does NOT match value stated in file header'
                print 'have now calculated max voxel value to be: %s'\
                %str(max(density))
                sys.exit()
        
        # if each voxel value is an atom number, then want to convert to integer
        if self.mapType in ('atom_map'):
            density_final = [int(dens)/100 for dens in density]
        elif self.mapType in ('density_map'):
            density_final = density
        else:
            print 'Unknown map type --> terminating script'
            sys.exit()

        rho.vxls_val = density_final
        
        self.rho = rho
Example #2
0
def densmap2class_readheader(mapfilename):
    
    # define 'rho' electron map object
    rho = electron_map_info()

    # open electron density .map file here 
    binarymapfile = open(mapfilename,'rb')
    
    # start adding header information into electron_map_info class format. 
    # Note the unpacking of a struct for each byte, read as a long 'l'
    rho.nx = struct.unpack('=l',binarymapfile.read(4))[0]
    rho.ny = struct.unpack('=l',binarymapfile.read(4))[0]
    rho.nz = struct.unpack('=l',binarymapfile.read(4))[0]
    rho.type = struct.unpack('=l',binarymapfile.read(4))[0]
    print 'Num. Col, Row, Sec: '
    print '%s %s %s' %(rho.nx,rho.ny,rho.nz)
    
    # currently can't handle type 1 maps:
    if rho.type == 1:
        print 'Map type 1 found... can only handle type 2'
        print '---> terminating script...'
        sys.exit()
        
    rho.start1 = struct.unpack('=l',binarymapfile.read(4))[0] 
    rho.start2 = struct.unpack('=l',binarymapfile.read(4))[0] 
    rho.start3 = struct.unpack('=l',binarymapfile.read(4))[0] 
    print 'Start positions: '
    print '%s %s %s' %(rho.start1,rho.start2,rho.start3)

    rho.gridsamp1 = struct.unpack('=l',binarymapfile.read(4))[0] 
    rho.gridsamp2 = struct.unpack('=l',binarymapfile.read(4))[0] 
    rho.gridsamp3 = struct.unpack('=l',binarymapfile.read(4))[0]
    print 'Grid sampling:'
    print '%s %s %s' %(rho.gridsamp1,rho.gridsamp2,rho.gridsamp3)

    # for cell dimensions, stored in header file as float not long 
    # integer so must account for this
    rho.celldim_a = struct.unpack('f',binarymapfile.read(4))[0]
    rho.celldim_b = struct.unpack('f',binarymapfile.read(4))[0]
    rho.celldim_c = struct.unpack('f',binarymapfile.read(4))[0]
    rho.celldim_alpha = struct.unpack('f',binarymapfile.read(4))[0]
    rho.celldim_beta = struct.unpack('f',binarymapfile.read(4))[0]
    rho.celldim_gamma = struct.unpack('f',binarymapfile.read(4))[0]
    print 'Cell dimensions:'
    print '%s %s %s' %(rho.celldim_a,rho.celldim_b,rho.celldim_c)
    print '%s %s %s' %(rho.celldim_alpha,rho.celldim_beta,rho.celldim_gamma)


    rho.fast_axis = struct.unpack('=l',binarymapfile.read(4))[0] 
    rho.med_axis = struct.unpack('=l',binarymapfile.read(4))[0] 
    rho.slow_axis = struct.unpack('=l',binarymapfile.read(4))[0] 
    print 'Fast,med,slow axes: '
    print '%s %s %s' %(rho.fast_axis,rho.med_axis,rho.slow_axis)

    rho.mindensity = struct.unpack('f',binarymapfile.read(4))[0] 
    rho.maxdensity = struct.unpack('f',binarymapfile.read(4))[0] 
    rho.meandensity = struct.unpack('f',binarymapfile.read(4))[0]
    print 'Density values: '
    print '%s %s %s' %(rho.mindensity,rho.maxdensity,rho.meandensity)

    # next find .map file size, to calculate the last nx*ny*nz bytes of 
    # file (corresponding to the position of the 3D electron density 
    # array). Note factor of 4 is included since 4-byte floats used for 
    # electron density array values.
    filesize = os.path.getsize(mapfilename)
    densitystart = filesize - 4*(rho.nx*rho.ny*rho.nz)
    
    return rho, densitystart