##################################
#                                #
# Last modified 05/26/2013       # 
#                                #
# Georgi Marinov                 #
#                                # 
##################################

import sys
import string


def run():

    if len(sys.argv) < 2:
        print 'usage: python %s input output'
        print '\tuse - if the input is from standard input'
        print '\tuse - if you want to print to standard output'
        print '\tNote: the script is written to take scores from Phred+64 scale and convert to Phred+33'
        sys.exit(1)

    fastq = sys.argv[1]
    outfilename = sys.argv[2]

    doStdInput = False
    if fastq == '-':
        doStdInput = True

    doStdOutput = False
    if outfilename == '-':
        doStdOutput = True

    QualityScoresScaleASCIItoPhred = {}

    QualityScoresScaleASCIItoPhred['!'] = 33
    QualityScoresScaleASCIItoPhred['"'] = 34
    QualityScoresScaleASCIItoPhred['#'] = 35
    QualityScoresScaleASCIItoPhred['$'] = 36
    QualityScoresScaleASCIItoPhred['%'] = 37
    QualityScoresScaleASCIItoPhred['&'] = 38
    QualityScoresScaleASCIItoPhred["'"] = 39
    QualityScoresScaleASCIItoPhred['('] = 40
    QualityScoresScaleASCIItoPhred[')'] = 41
    QualityScoresScaleASCIItoPhred['*'] = 42
    QualityScoresScaleASCIItoPhred['+'] = 43
    QualityScoresScaleASCIItoPhred[','] = 44
    QualityScoresScaleASCIItoPhred['-'] = 45
    QualityScoresScaleASCIItoPhred['.'] = 46
    QualityScoresScaleASCIItoPhred['/'] = 47
    QualityScoresScaleASCIItoPhred['0'] = 48
    QualityScoresScaleASCIItoPhred['1'] = 49
    QualityScoresScaleASCIItoPhred['2'] = 50
    QualityScoresScaleASCIItoPhred['3'] = 51
    QualityScoresScaleASCIItoPhred['4'] = 52
    QualityScoresScaleASCIItoPhred['5'] = 53
    QualityScoresScaleASCIItoPhred['6'] = 54
    QualityScoresScaleASCIItoPhred['7'] = 55
    QualityScoresScaleASCIItoPhred['8'] = 56
    QualityScoresScaleASCIItoPhred['9'] = 57
    QualityScoresScaleASCIItoPhred[':'] = 58
    QualityScoresScaleASCIItoPhred[';'] = 59
    QualityScoresScaleASCIItoPhred['<'] = 60
    QualityScoresScaleASCIItoPhred['='] = 61
    QualityScoresScaleASCIItoPhred['>'] = 62
    QualityScoresScaleASCIItoPhred['?'] = 63
    QualityScoresScaleASCIItoPhred['@'] = 64
    QualityScoresScaleASCIItoPhred['A'] = 65
    QualityScoresScaleASCIItoPhred['B'] = 66
    QualityScoresScaleASCIItoPhred['C'] = 67
    QualityScoresScaleASCIItoPhred['D'] = 68
    QualityScoresScaleASCIItoPhred['E'] = 69
    QualityScoresScaleASCIItoPhred['F'] = 70
    QualityScoresScaleASCIItoPhred['G'] = 71
    QualityScoresScaleASCIItoPhred['H'] = 72
    QualityScoresScaleASCIItoPhred['I'] = 73
    QualityScoresScaleASCIItoPhred['J'] = 74
    QualityScoresScaleASCIItoPhred['K'] = 75
    QualityScoresScaleASCIItoPhred['L'] = 76
    QualityScoresScaleASCIItoPhred['M'] = 77
    QualityScoresScaleASCIItoPhred['N'] = 78
    QualityScoresScaleASCIItoPhred['O'] = 79
    QualityScoresScaleASCIItoPhred['P'] = 80
    QualityScoresScaleASCIItoPhred['Q'] = 81
    QualityScoresScaleASCIItoPhred['R'] = 82
    QualityScoresScaleASCIItoPhred['S'] = 83
    QualityScoresScaleASCIItoPhred['T'] = 84
    QualityScoresScaleASCIItoPhred['U'] = 85
    QualityScoresScaleASCIItoPhred['V'] = 86
    QualityScoresScaleASCIItoPhred['W'] = 87
    QualityScoresScaleASCIItoPhred['X'] = 88
    QualityScoresScaleASCIItoPhred['Y'] = 89
    QualityScoresScaleASCIItoPhred['Z'] = 90
    QualityScoresScaleASCIItoPhred['['] = 91
    QualityScoresScaleASCIItoPhred['\\'] = 92
    QualityScoresScaleASCIItoPhred[']'] = 93
    QualityScoresScaleASCIItoPhred['^'] = 94
    QualityScoresScaleASCIItoPhred['_'] = 95
    QualityScoresScaleASCIItoPhred['`'] = 96
    QualityScoresScaleASCIItoPhred['a'] = 97
    QualityScoresScaleASCIItoPhred['b'] = 98
    QualityScoresScaleASCIItoPhred['c'] = 99
    QualityScoresScaleASCIItoPhred['d'] = 100
    QualityScoresScaleASCIItoPhred['e'] = 101
    QualityScoresScaleASCIItoPhred['f'] = 102
    QualityScoresScaleASCIItoPhred['g'] = 103
    QualityScoresScaleASCIItoPhred['h'] = 104
    QualityScoresScaleASCIItoPhred['i'] = 105
    QualityScoresScaleASCIItoPhred['j'] = 106
    QualityScoresScaleASCIItoPhred['k'] = 107
    QualityScoresScaleASCIItoPhred['l'] = 108
    QualityScoresScaleASCIItoPhred['m'] = 109
    QualityScoresScaleASCIItoPhred['n'] = 110
    QualityScoresScaleASCIItoPhred['o'] = 111
    QualityScoresScaleASCIItoPhred['p'] = 112
    QualityScoresScaleASCIItoPhred['q'] = 113
    QualityScoresScaleASCIItoPhred['r'] = 114
    QualityScoresScaleASCIItoPhred['s'] = 115
    QualityScoresScaleASCIItoPhred['t'] = 116
    QualityScoresScaleASCIItoPhred['u'] = 117
    QualityScoresScaleASCIItoPhred['v'] = 118
    QualityScoresScaleASCIItoPhred['w'] = 119
    QualityScoresScaleASCIItoPhred['x'] = 120
    QualityScoresScaleASCIItoPhred['y'] = 121
    QualityScoresScaleASCIItoPhred['z'] = 122
    QualityScoresScaleASCIItoPhred['{'] = 123
    QualityScoresScaleASCIItoPhred['|'] = 124
    QualityScoresScaleASCIItoPhred['}'] = 125
    QualityScoresScaleASCIItoPhred['~'] = 126

    QualityScoresScalePhredtoASCII = {}

    QualityScoresScalePhredtoASCII[33] = '!'
    QualityScoresScalePhredtoASCII[34] = '"'
    QualityScoresScalePhredtoASCII[35] = '#'
    QualityScoresScalePhredtoASCII[36] = '$'
    QualityScoresScalePhredtoASCII[37] = '%'
    QualityScoresScalePhredtoASCII[38] = '&'
    QualityScoresScalePhredtoASCII[39] = "'"
    QualityScoresScalePhredtoASCII[40] = '('
    QualityScoresScalePhredtoASCII[41] = ')'
    QualityScoresScalePhredtoASCII[42] = '*'
    QualityScoresScalePhredtoASCII[43] = '+'
    QualityScoresScalePhredtoASCII[44] = ','
    QualityScoresScalePhredtoASCII[45] = '-'
    QualityScoresScalePhredtoASCII[46] = '.'
    QualityScoresScalePhredtoASCII[47] = '/'
    QualityScoresScalePhredtoASCII[48] = '0'
    QualityScoresScalePhredtoASCII[49] = '1'
    QualityScoresScalePhredtoASCII[50] = '2'
    QualityScoresScalePhredtoASCII[51] = '3'
    QualityScoresScalePhredtoASCII[52] = '4'
    QualityScoresScalePhredtoASCII[53] = '5'
    QualityScoresScalePhredtoASCII[54] = '6'
    QualityScoresScalePhredtoASCII[55] = '7'
    QualityScoresScalePhredtoASCII[56] = '8'
    QualityScoresScalePhredtoASCII[57] = '9'
    QualityScoresScalePhredtoASCII[58] = ':'
    QualityScoresScalePhredtoASCII[59] = ';'
    QualityScoresScalePhredtoASCII[60] = '<'
    QualityScoresScalePhredtoASCII[61] = '='
    QualityScoresScalePhredtoASCII[62] = '>'
    QualityScoresScalePhredtoASCII[63] = '?'
    QualityScoresScalePhredtoASCII[64] = '@'
    QualityScoresScalePhredtoASCII[65] = 'A'
    QualityScoresScalePhredtoASCII[66] = 'B'
    QualityScoresScalePhredtoASCII[67] = 'C'
    QualityScoresScalePhredtoASCII[68] = 'D'
    QualityScoresScalePhredtoASCII[69] = 'E'
    QualityScoresScalePhredtoASCII[70] = 'F'
    QualityScoresScalePhredtoASCII[71] = 'G'
    QualityScoresScalePhredtoASCII[72] = 'H'
    QualityScoresScalePhredtoASCII[73] = 'I'
    QualityScoresScalePhredtoASCII[74] = 'J'
    QualityScoresScalePhredtoASCII[75] = 'K'
    QualityScoresScalePhredtoASCII[76] = 'L'
    QualityScoresScalePhredtoASCII[77] = 'M'
    QualityScoresScalePhredtoASCII[78] = 'N'
    QualityScoresScalePhredtoASCII[79] = 'O'
    QualityScoresScalePhredtoASCII[80] = 'P'
    QualityScoresScalePhredtoASCII[81] = 'Q'
    QualityScoresScalePhredtoASCII[82] = 'R'
    QualityScoresScalePhredtoASCII[83] = 'S'
    QualityScoresScalePhredtoASCII[84] = 'T'
    QualityScoresScalePhredtoASCII[85] = 'U'
    QualityScoresScalePhredtoASCII[86] = 'V'
    QualityScoresScalePhredtoASCII[87] = 'W'
    QualityScoresScalePhredtoASCII[88] = 'X'
    QualityScoresScalePhredtoASCII[89] = 'Y'
    QualityScoresScalePhredtoASCII[90] = 'Z'
    QualityScoresScalePhredtoASCII[91] = '['
    QualityScoresScalePhredtoASCII[92] = '\\'
    QualityScoresScalePhredtoASCII[93] = ']'
    QualityScoresScalePhredtoASCII[94] = '^'
    QualityScoresScalePhredtoASCII[95] = '_'
    QualityScoresScalePhredtoASCII[96] = '`'
    QualityScoresScalePhredtoASCII[97] = 'a'
    QualityScoresScalePhredtoASCII[98] = 'b'
    QualityScoresScalePhredtoASCII[99] = 'c'
    QualityScoresScalePhredtoASCII[100] = 'd'
    QualityScoresScalePhredtoASCII[101] = 'e'
    QualityScoresScalePhredtoASCII[102] = 'f'
    QualityScoresScalePhredtoASCII[103] = 'g'
    QualityScoresScalePhredtoASCII[104] = 'h'
    QualityScoresScalePhredtoASCII[105] = 'i'
    QualityScoresScalePhredtoASCII[106] = 'j'
    QualityScoresScalePhredtoASCII[107] = 'k'
    QualityScoresScalePhredtoASCII[108] = 'l'
    QualityScoresScalePhredtoASCII[109] = 'm'
    QualityScoresScalePhredtoASCII[110] = 'n'
    QualityScoresScalePhredtoASCII[111] = 'o'
    QualityScoresScalePhredtoASCII[112] = 'p'
    QualityScoresScalePhredtoASCII[113] = 'q'
    QualityScoresScalePhredtoASCII[114] = 'r'
    QualityScoresScalePhredtoASCII[115] = 's'
    QualityScoresScalePhredtoASCII[116] = 't'
    QualityScoresScalePhredtoASCII[117] = 'u'
    QualityScoresScalePhredtoASCII[118] = 'v'
    QualityScoresScalePhredtoASCII[119] = 'w'
    QualityScoresScalePhredtoASCII[120] = 'x'
    QualityScoresScalePhredtoASCII[121] = 'y'
    QualityScoresScalePhredtoASCII[122] = 'z'
    QualityScoresScalePhredtoASCII[123] = '{'
    QualityScoresScalePhredtoASCII[124] = '|'
    QualityScoresScalePhredtoASCII[125] = '}'
    QualityScoresScalePhredtoASCII[126] = '~'

    if not doStdOutput:
        outfile = open(outfilename, 'w')

    if doStdInput:
        lineslist  = sys.stdin
    else:
        lineslist  = open(fastq)
    i=0
    pos=1
    for line in lineslist:
        if i % 20000000 == 0:
            if not doStdOutput:
                print str(i/4000000) + 'M reads processed'
        i+=1
        if pos==1:
            if line.startswith('@'):
                pass
            else:
                print 'fastq file format broken, exiting'
                print pos, i, line.strip()
                sys.exit(1)
            ID = line.strip()
            pos=2
            continue
        if pos==2:
            sequence = line.strip()
            pos=3
            continue
        if pos==3:
            if line.startswith('+'):
                pass
            else:
                print 'fastq file format broken, exiting'
                print pos, i, line.strip()
                sys.exit(1)
            pos=4
            continue
        if pos==4:
            pos = 1
            QC = line.strip()
            newQC = ''
            for A in QC:
                Phred64 = QualityScoresScaleASCIItoPhred[A]
                Phred33 = QualityScoresScalePhredtoASCII[Phred64-31]
                newQC += Phred33
            if not doStdOutput:
                outfile.write(ID + '\n')
                outfile.write(sequence + '\n')
                outfile.write('+\n')
                outfile.write(newQC + '\n')
            else:
                print ID
                print sequence
                print '+'
                print newQC
            continue

    if not doStdOutput:
        outfile.close()
       
run()