예제 #1
0
    def readCRVFile(self, filename, ext = '.crv'):
        filename += ext

        if not os.path.isfile(filename):
            myPyCommon.printErrorAndQuit('CRV-File %s does not exist' %filename)

        file = open(filename, 'r')

        # read comments
        while 1 and file:
            line = file.readline() 
            if line.find('##') != -1:
                self._comments += [line.replace('\n', '').partition(' ')[2]]
            else:
                file.seek(-len(line), 1) # go back the last read line from here
                break

        # read blocks, number of blocks 1e5 should be enough
        prevBlock = None
        for i in range(int(1e5)):
            block = CRVBlock()
            if block.readBlockCurve(file, fileFormat = curvefile, previousBlock = prevBlock):
                prevBlock = block
                self._blocks += [block]

        file.close()
예제 #2
0
    def __init__(self, filename = None):
        self._blocks   = []
        self._comments = []
        self.__initialBinaryFile = False

        if filename:
            ext  = ''
            readBinary = False
            if filename.find('.brv') != -1: 
                ext = ''
                readBinary = True
            elif filename.find('.crv') != -1: 
                ext = ''
                readBinary = False
            elif os.path.exists(filename + '.brv'):
                ext = '.brv'
                readBinary = True
            elif os.path.exists(filename + '.crv'):
                ext = '.crv'
                readBinary = False
            else:
                common.printErrorAndQuit('File %s%s not found' %(filename, ext))

            if readBinary:
                self.readBinaryCRVFile(filename, ext)
                self.__initialBinaryFile = True
            else:
                self.readCRVFile(filename, ext)
                self.__initialBinaryFile = False

            self.__initialfilename = filename
            self.__initialext = ext
예제 #3
0
    def writeCRVFile(self,filename, 
                     append = False,
                     overwrite = 1, writeNrDatalines = -1, nrLinesFromColNr = -1, warningAtNAN = False, skipNANColumns = False, writeHeader = True, withextension = True, enableStringCols = True):

        if not withextension: # used in xcrv
            pass
        else:
            if filename.find(ext_crv) == -1:
                filename += ext_crv

        if not (overwrite or append) and os.path.isfile(filename):
            myPyCommon.printErrorAndQuit('File %s does exist and overwrite/append option is not enabled' % filename)

        if append:
            file = open(filename, 'a')
            file.write('\n')
        else:
            file = open(filename, 'w')

        # write common header
        for s in self._comments:
            file.write('## ' + s + '\n')

        # write single blocks
        for i, block in enumerate(self._blocks):
            block.writeBlock(file, writeNrDatalines = writeNrDatalines, nrLinesFromColNr = nrLinesFromColNr, warningAtNAN = warningAtNAN, skipNANColumns = skipNANColumns, fileFormat = curvefile, writeHeader = writeHeader or i==0, enableStringCols = enableStringCols)
        
            if i < (len(self._blocks)-1): # seperate two blocks
                file.write('\n')

        # finished 
        file.close()
예제 #4
0
def mergefiles(files, commonColumn, outfile):
    data     = {}
    infoline = ''
    for i,f in enumerate(files):
        inf = CRV(f)[0]
        infoline += inf.getInfoLine() + ' '
        names = inf.getColumnNames()

        if i == 0: # init dataset
            for n in names:
               data[n] = copy.deepcopy(inf.getColumn(name = n))
        else:
            commondata = copy.deepcopy(inf.getColumn(name = commonColumn)) 
            for n in names:
                if n == commonColumn:
                    continue
                if data.has_key(n):
                    common.printErrorAndQuit('Column "%s" already exists, can\'t merge' %n)
                datmerge = copy.deepcopy(inf.getColumn(name = n))

                # merge into it
                data[n]     = copy.deepcopy(datmerge)
                for i in range(len(data[n][-1])): # delete values
                    data[n][-1][i] = 0.
                for pos, el in enumerate(data[commonColumn][-1]):
                    idx = commondata[-1].index(el)
                    data[n][-1][pos] = datmerge[-1][idx]
                    
    # write data to new file
    crvo = newCrvFile()
    crvo[0].addInfoLine(infoline)
    for key in data.keys():
        crvo[0].addColumn(data = data[key])
    crvo.writeCRVFile(outfile)
예제 #5
0
    def readBlockCurve(self, filestream, fileFormat = curvefile, previousBlock = None):
        # previous block needed because their are some versions with multiple blocks not containing separate heads
        blockHasData = False
        blockHasHead = False
        for line in filestream:
            if line[0:2].find('##') != -1: # comment
                blockHasData = True
                self._comments += [line.replace('\n', '').partition(' ')[2]]
            elif line[0] == '#': # hashMark
                blockHasData = True
                blockHasHead = True
                els = line.replace('\n', '').replace('\t', ' ').partition(' ')[2].rsplit()
                if line[0:10].find('#n') != -1: # names
                    for i,n in enumerate(els):
                        self.setColumnName(idx = i, name = n)
                elif line[0:10].find('#u') != -1: # units
                    for i,u in enumerate(els):
                        self.setColumnUnit(idx = i, unit = u) 
                elif line[0:10].find('#o') != -1: # offset
                    for i,o in enumerate(els):
                        self.setColumnOffset(idx = i, offset = float(o)) 
                elif line[0:10].find('#f') != -1: # scale
                    for i,s in enumerate(els):
                        self.setColumnScale(idx = i, scale = float(s))
                #elif line[0:10].find('#s') != -1: # stress times
                #    for i, s in enumerate(els):
                #        self.setTStress(idx = i, ts = float(s))
                elif line[0:10].find('#t') != -1: # type, 0 .. float, 1 .. string
                    for i,s in enumerate(els):
                        self.setColumnDataType(idx = i, datatype = int(float(s)))
                elif line[0:10].find('#b') != -1: # b parameter
                    self._b = int(els[0])
                elif line[0:10].find('#p') != -1: # p parameter
                    self._p = int(els[0])
                    if self._p > 10:
                        myPyCommon.printWarning('Strange p - parameter: ', els[0])
                        self._p = 1
                else: # unknown hashMark
                    self.addHashMark(hashline = line.replace('\n', ''))
            elif line[0] != '\n': # data values
                if not blockHasHead: # copy head from previous block
                    myPyCommon.printWarning('Very old crv version without individual block heads -- copy previous head')
                    if previousBlock == None:
                        myPyCommon.printErrorAndQuit('No head found')
                    self.copyBlockHead(previousBlock)
                    blockHasHead = True

                blockHasData = True
                line = ' ' + line # if the first character of the line is no white space insert one
                els = line.replace('\n', '').replace('\t', ' ').partition(' ')[2].rsplit()
                for i,value in enumerate(els):
                    self.addValue(icol = i, val = value)
            else: # end of block reached
                break

        return blockHasData
예제 #6
0
    def getColumnData(self, name = '', idx = -1):
        if idx == -1:
            colNames = self.getColumnNames()
            if not colNames or colNames.count(name) == 0:
                myPyCommon.printErrorAndQuit('Column "%s" not found in %s' % (name, str(colNames)))

        #print 'x', self.getColumn(name, idx)[0]
        (n, u, o, s, t, dat) = self.getColumn(name, idx)

        if t == 0: # we have numbers
            return [d*s + o for d in dat]
        elif t == 1: # we have strings
            return [d for d in dat]
        else:
            myPyCommon.printErrorAndQuit('Invalid data type')
예제 #7
0
    def writeBinaryCRVFile(self, filename, 
                           overwrite = 1, writeNrDatalines = -1, nrLinesFromColNr = -1, fileFormat = binary32, warningAtNAN = False, skipNANColumns = False, enableStringCols = False):
        if filename.find(ext_brv) == -1:
            filename += ext_brv
        
        if not overwrite and os.path.isfile(filename):
            myPyCommon.printErrorAndQuit('File %s does exist and overwrite option is not enabled' %filename)

        file = open(filename, 'w')

        outstream = ''

        if not enableStringCols:
            outstream += pack('<I', binaryID)
        else:
            outstream += pack('<I', binaryIDx3)
        outstream += pack('<I', 0) # len head not known yet
        outstream += pack('<I', len(self._blocks)) # number of blocks
        for i in range(len(self._blocks)):
            outstream += pack('<I', 0) # startposition of the blocks, not known yet
 
        # comments
        outstream += pack('<I', len(self._comments)) # number of comments
        for s in self._comments:
            outstream += s + '\0'

        blocksize = len(outstream) # length of header here
        outstream = outstream[0:4] + pack('<I', blocksize) + outstream[8:]
        
        # write header to file
        file.write(outstream)

        # write single blocks
        for i, block in enumerate(self._blocks):
            outstream = outstream[0:12+i*4] + pack('<I', blocksize) + outstream[12+(i+1)*4:] # start position of this block
            blocksize += block.writeBlock(file, writeNrDatalines = writeNrDatalines, nrLinesFromColNr = nrLinesFromColNr, warningAtNAN = warningAtNAN, skipNANColumns = skipNANColumns, fileFormat = fileFormat, enableStringCols = enableStringCols)

        file.seek(0)
        file.write(outstream) # write head

        # finished 
        file.close()
예제 #8
0
    def readBinaryCRVFile(self, filename, ext = '.brv', justEvalBlockCount = False):
        if filename.find(ext) == -1:
            filename += ext
       
        if not os.path.isfile(filename):
            myPyCommon.printErrorAndQuit('Binary CRV-File %s does not exist' %filename)

        #print filename
        file = open(filename, 'r')
       
        # check file version
        binaryVersion = 0

        binaryVersion = unpack('<I', file.read(4))[0]
        if binaryVersion == binaryID:
            binaryVersion = 2
        elif binaryVersion == binaryIDx3:
            binaryVersion = 3
        else:
            myPyCommon.printErrorAndQuit('Unknown binary file version')

        lenhead = unpack('<I', file.read(4))[0]

        # read complete file header
        file.seek(0)
        instream = file.read(lenhead)[8:] # skip first two parameters, already analyzed

        # Block information
        numBlocks = unpack('<I', instream[0:4])[0]
        if justEvalBlockCount:
            file.close()
            return numBlocks
            
        instream = instream[4:]
        posBlocks = []
        for i in range(numBlocks):
            posBlocks += [unpack('<I', instream[0:4])[0]]
            instream = instream[4:]

        # Common comments
        numComments = unpack('<I', instream[0:4])[0]
        instream = instream[4:]
        for i in range(numComments):
            s = ''
            while instream[0] != '\0':
                s += instream[0]
                instream = instream[1:]
            instream = instream[1:]
            self.addComment(s)

        # read single blocks
        for i in range(numBlocks):
            block = CRVBlock()
            file.seek(posBlocks[i])
            if not block.readBlockBinary(file, fileFormat = binary32, binaryVersion = binaryVersion):
                print 'Successfully read %d blocks before an invalid block occured' %i
                break
            self._blocks += [block]
#            block.readBlock(file.seek(posBlocks[i]))
#            self.addBlock(block)

        # finished 
        file.close() 
예제 #9
0
 def __getitem__(self, idx):
     if idx >= 0 and idx < len(self._blocks):
         return self._blocks[idx]
     else:
         myPyCommon.printErrorAndQuit('Block index out of range')
예제 #10
0
    def writeBlock(self, filestream, writeNrDatalines = -1, nrLinesFromColNr = -1, warningAtNAN = False, skipNANColumns = False, fileFormat = curvefile, printWarnings = False, writeHeader = True, enableStringCols = False):        
        if fileFormat != curvefile and fileFormat != binary32:
            myPyCommon.printErrorAndQuit('Invalid output file format')

        # check for cols just containing nans
        skipCols = []
        if skipNANColumns:
            for i, (n, _, _, _, dat) in enumerate(self._data):
                if len(dat):
                    if dat[0] != dat[0]: # column just contains nans
                        skipCols += [n]
            
        outstream = ''

        # binary block start id
        if not fileFormat&0xF0:
            outstream += pack('<I', blockID) # block id
            outstream += pack('<I', 0) # len of block, unknown yet
            outstream += pack('<I', 0) # len of header, unknown yet

        if writeHeader:
            # comments
            if not fileFormat&0xF0:
                outstream += pack('<I', len(self._comments)) # number of comments
            for s in self._comments:
                if not fileFormat&0xF0:
                    outstream += s + '\0'
                else:
                    outstream += '## ' + s + '\n'
            
            # p and b parameter
            self._b = fileFormat
            if not fileFormat&0xF0:
                self._b = fileFormat
                outstream += pack('<I', self._b) # b parameter
                outstream += pack('<I', self._p) # p parameter
            else:
                outstream += '#b %g\n' %self._b
                outstream += '#p %g\n' %self._p
            
            # unknown hashmarks
            if not fileFormat&0xF0:
                outstream += pack('<I', len(self._unknownHash)) # number of unknown hashmarks
            for s in self._unknownHash:
                #print s
                if not fileFormat&0xF0:
                    outstream += '%s\0' %s
                else:
                    outstream += '%s\n' %s

            # stress times
            isDefault = True
            if not fileFormat&0xF0:
                outstream += pack('<I', 0) # number of stresstimes, not known yet
            else:
                # check if ts differs from default value -1
                for name in self._tstress:
                    ts = self._tstress[name]
                    if ts != -1:
                        isDefault = False
                        break
                if not isDefault:
                    outstream += '#s'

            nrWritten = 0
            for (name, unit, offset, scale, _, _) in self._data:
                if name in skipCols:
                    continue
                ts = -1.0
                if name in self._tstress:
                    ts = self._tstress[name]
            
                if not fileFormat&0xF0 and fileFormat == binary32:
                    outstream += pack('<d', ts)
                else:
                    if not isDefault:
                        outstream += ' %e' %ts
                nrWritten += 1
            if not fileFormat&0xF0:
                idx = len(outstream)-8*nrWritten-4
                outstream = outstream[0:idx] + pack('<I', nrWritten) + outstream[idx+4:]
            else:
                if not isDefault:
                    outstream += '\n'
            
            # offset
            isDefault = True
            if not fileFormat&0xF0:
                outstream += pack('<I', 0) # number of offset values, not known yet
            else:
                # check if ts differs from default value -1
                for (_, _, offset, _, _, _) in self._data:
                    if offset != 0:
                        isDefault = False
                        break
                if not isDefault:
                    outstream += '#o'

            nrWritten = 0
            for (name, unit, offset, scale, _, _) in self._data:
                if name in skipCols:
                    continue
                if not fileFormat&0xF0 and fileFormat == binary32:
                    outstream += pack('<d', offset)
                else:
                    if not isDefault:
                        outstream += ' %e' %offset
                nrWritten += 1
            if not fileFormat&0xF0:
                idx = len(outstream)-8*nrWritten-4
                outstream = outstream[0:idx] + pack('<I', nrWritten) + outstream[idx+4:]
            else:
                if not isDefault:
                    outstream += '\n'
            
            # scale
            isDefault = True
            if not fileFormat&0xF0:
                outstream += pack('<I', 0) # number of scales, not known yet
            else:
                for (_, _, _, scale, _, _) in self._data:
                    if scale != 1:
                        isDefault = False
                        break
                if not isDefault:
                    outstream += '#f'

            nrWritten = 0
            for (name, unit, offset, scale, _, _) in self._data:
                if name in skipCols:
                    continue
                if not fileFormat&0xF0 and fileFormat == binary32:
                    outstream += pack('<d', scale)
                else:
                    if not isDefault:
                        outstream += ' %e' %scale
                nrWritten += 1
            if not fileFormat&0xF0:
                idx = len(outstream)-8*nrWritten-4
                outstream = outstream[0:idx] + pack('<I', nrWritten) + outstream[idx+4:]
            else:
                if not isDefault:
                    outstream += '\n'
            
            # names
            if not fileFormat&0xF0:
                outstream += pack('<I', 0) # number of names, not known yet
            else:
                outstream += '#n'
            nrWritten = 0
            bytesWritten = 0
            for (n, _,  _, _, _, _) in self._data:
                if n in skipCols:
                    continue
                if not fileFormat&0xF0:
                    outstream += n + '\0'
                    bytesWritten += len(n) + 1
                else:
                    outstream += '  %s' %n
                nrWritten += 1
            if not fileFormat&0xF0:
                idx = len(outstream)-bytesWritten-4
                outstream = outstream[0:idx] + pack('<I', nrWritten) + outstream[idx+4:]
            else:
                outstream += '\n'
            
            # units
            if not fileFormat&0xF0:
                outstream += pack('<I', 0) # number of names, not known yet
            else:
                outstream += '#u'
            nrWritten = 0
            bytesWritten = 0
            for (n, u,  _, _, _, _) in self._data:
                if n in skipCols:
                    continue
                if not fileFormat&0xF0:
                    outstream += u + '\0'
                    bytesWritten += len(u) + 1
                else:
                    outstream += '  %s' %u
                nrWritten += 1
            if not fileFormat&0xF0:
                idx = len(outstream)-bytesWritten-4
                outstream = outstream[0:idx] + pack('<I', nrWritten) + outstream[idx+4:]
            else:
                outstream += '\n'
            
            if not fileFormat&0xF0: # write len of header in bytes
                idx = 8
                outstream = outstream[0:idx] + pack('<I', nrWritten) + outstream[idx+4:]

            # column data types
            if enableStringCols:
                if not fileFormat&0xF0:
                    outstream += pack('<I', 0) # number of names, not known yet
                else:
                    outstream += '#t'
                nrWritten = 0
                for (n, _,  _, _, t, _) in self._data:
                    if n in skipCols:
                        continue
                    if not fileFormat&0xF0 and fileFormat == binary32:
                        outstream += pack('<d', t)
                    else:
                        outstream += '  %s' %t
                    nrWritten += 1
                if not fileFormat&0xF0:
                    idx = len(outstream)-8*nrWritten-4
                    outstream = outstream[0:idx] + pack('<I', nrWritten) + outstream[idx+4:]
                else:
                    outstream += '\n'


            
            # !!!write len of header in bytes
            if not fileFormat&0xF0: # write len of header in bytes
                idx = 8
                outstream = outstream[0:idx] + pack('<I', nrWritten) + outstream[idx+4:]

        # data values
        nrLinesToWrite = 0
        if nrLinesFromColNr >= 0 and len(self._data) > nrLinesFromColNr:
            for i in range(len(self._data[nrLinesFromColNr][4])-1, -1, -1):
                if self._data[nrLinesFromColNr][4][i] == self._data[nrLinesFromColNr][4][i]: # check if not nan
                    nrLinesToWrite = i + 1
                    break
        elif writeNrDatalines > 0:
            nrLinesToWrite = writeNrDatalines
        else:
            for (_, _,  _, _, _, lst) in self._data:
                if nrLinesToWrite < len(lst):
                    nrLinesToWrite = len(lst)
     
        #if nrLinesToWrite: # hack because last item is not written so far
        #    nrLinesToWrite += 1
        #print "NrLinesToWrite = %d" %nrLinesToWrite

        posstream = len(outstream)
        if not fileFormat&0xF0: # write binary data values
            outstream += pack('<I', 0) # number of data values, not known yet (does not count to head)
        nrWritten = 0
        #print self._data
        for i in range(nrLinesToWrite):
            s = ''
            for (n, _,  _, _, t, lst) in self._data:
                if n in skipCols:
                    continue

                if i < len(lst):
                    if warningAtNAN and lst[i] != lst[i] and printWarnings:
                        myPyCommon.printWarning('NAN found in column %s at line %g' %(n, i))

                    if not fileFormat&0xF0: # write binary data values
                        if t == 0 or not enableStringCols: # we write numbers
                            try:
                                outstream += pack('<f', lst[i]) # data value
                                nrWritten += 1
                            except:
                                myPyCommon.printErrorAndQuit('String column? Use option enableStringCols = True')

                        elif t == 1: # we write strings
                            outstream += lst[i] + '\0' # data value
                            nrWritten += len(lst[i]) + 1
                        else:
                            myPyCommon.printErrorAndQuit('Invalid data type id')
                    else:
                        if t == 0: # we have numbers
                            s += '  %e' %lst[i]
                        elif t == 1: # we have strings
                            s += '  %s' %lst[i]
                        else:
                            myPyCommon.printErrorAndQuit('Invalid column type')
                else:
                    #print 'HELLO', i, len(lst)
                    if not fileFormat&0xF0: # write binary data values
                        outstream += pack('<f', float('nan')) # data value
                        nrWritten += 1
                    else:
                        s += '  nan'
            if fileFormat&0xF0: # write to not binary files
                outstream += s + '\n'

        if not fileFormat&0xF0: # write number of data values and len of block in bytes
            outstream = outstream[0:posstream] + pack('<I', nrWritten) + outstream[posstream+4:]
                              
            idx = 4
            outstream = outstream[0:idx] + pack('<I', len(outstream)) + outstream[idx+4:]

        filestream.write(outstream)

        return len(outstream)