source: tags/ms_r17q3/CONVERTALN/gcg.cxx

Last change on this file was 9516, checked in by westram, 12 years ago
  • reintegrated branch 'cxx11'
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.9 KB
Line 
1#include "genbank.h"
2#include "embl.h"
3#include "macke.h"
4
5static void gcg_doc_out(const char *line, Writer& writer) {
6    // Output non-sequence data(document) of gcg format.
7    int indi, len;
8    int previous_is_dot;
9
10    ca_assert(writer.ok());
11
12    for (indi = 0, len = str0len(line), previous_is_dot = 0; indi < len; indi++) {
13        if (previous_is_dot) {
14            if (line[indi] == '.')
15                writer.out(' ');
16            else
17                previous_is_dot = 0;
18        }
19        writer.out(line[indi]);
20        if (line[indi] == '.')
21            previous_is_dot = 1;
22    }
23}
24
25static int gcg_checksum(const char *Str, int numofstr) {
26    // Calculate gcg_checksum for GCG format.
27    int cksum = 0;
28    int count = 0;
29    for (int indi = 0; indi < numofstr; indi++) {
30        if (!is_gapchar(Str[indi])) {
31            count++;
32            cksum = ((cksum + count * toupper(Str[indi])) % 10000);
33            if (count == 57) count = 0;
34        }
35    }
36    return cksum;
37}
38
39static void gcg_out_origin(const Seq& seq, Writer& write) {
40    // Output sequence data in gcg format.
41    int         indi, indj, indk;
42    const char *sequence = seq.get_seq();
43
44    for (indi = 0, indj = 0, indk = 1; indi < seq.get_len(); indi++) {
45        if (!is_gapchar(sequence[indi])) {
46            if ((indk % 50) == 1) write.outf("%8d  ", indk);
47            write.out(sequence[indi]);
48            indj++;
49            if (indj == 10) {
50                write.out(' ');
51                indj = 0;
52            }
53            if ((indk % 50) == 0) write.out("\n\n");
54            indk++;
55        }
56    }
57    if ((indk % 50) != 1) write.out(" \n");
58}
59
60static void gcg_seq_out(const Seq& seq, Writer& write, const char *key) {
61    // Output sequence data in gcg format.
62    write.outf("\n%s  Length: %d  %s  Type: N  Check: %d  ..\n\n",
63            key,
64            seq.get_len()-seq.count_gaps(),
65            gcg_date(today_date()),
66            gcg_checksum(seq.get_seq(), seq.get_len()));
67    gcg_out_origin(seq, write);
68}
69
70class GcgWriter;
71
72class GcgCommentWriter : public Writer {
73    GcgWriter& gcg_writer;
74
75    char linebuf[LINESIZE];
76    int  used;
77public:
78    GcgCommentWriter(GcgWriter& gcg_writer_)
79        : gcg_writer(gcg_writer_),
80          used(0)
81    {}
82    ~GcgCommentWriter() OVERRIDE {
83        ca_assert(used == 0); // trailing \n has not been written
84    }
85
86    bool ok() const OVERRIDE { return true; }
87    void throw_write_error() const OVERRIDE { ca_assert(0); }
88    void out(char ch) OVERRIDE;
89    const char *name() const OVERRIDE { return "comment-writer"; }
90};
91
92class GcgWriter : public FileWriter { // derived from a Noncopyable
93    char *species_name;
94    bool  seq_written;             // if true, any further sequences are ignored
95
96    GcgCommentWriter writer;
97
98public:
99    GcgWriter(const char *outname)
100        : FileWriter(outname),
101          species_name(NULL),
102          seq_written(false),
103          writer(*this)
104    {}
105    ~GcgWriter() OVERRIDE { free(species_name); }
106
107    void set_species_name(const char *next_name) {
108        if (!seq_written) species_name = nulldup(next_name);
109        else warningf(111, "Species '%s' dropped (GCG allows only 1 sequence per file)", next_name);
110    }
111
112    void add_comment(const char *comment) {
113        if (!seq_written) gcg_doc_out(comment, *this);
114    }
115
116    Writer& comment_writer() {
117        ca_assert(!seq_written);
118        return writer;
119    }
120
121    void write_seq_data(const Seq& seq) {
122        if (!seq_written) {
123            ca_assert(species_name); // you have to call set_species_name() before!
124            gcg_seq_out(seq, *this, species_name);
125            seq_written = true;
126        }
127    }
128
129    void expect_written() {
130        FileWriter::seq_done(seq_written);
131        seq_written = false;
132        FileWriter::expect_written();
133    }
134};
135
136void GcgCommentWriter::out(char ch) {
137    linebuf[used++] = ch;
138    ca_assert(used<LINESIZE);
139    if (ch == '\n') {
140        linebuf[used] = 0;
141        gcg_writer.add_comment(linebuf);
142        used = 0;
143    }
144}
145
146static void macke_to_gcg(const char *inf, const char *outf) {
147    MackeReader reader(inf);
148    GcgWriter   out(outf);
149
150    Seq seq;
151    if (reader.read_one_entry(seq)) {
152        Macke& macke = dynamic_cast<Macke&>(reader.get_data());
153        out.set_species_name(macke.get_id());
154        macke_seq_info_out(macke, out);
155        out.write_seq_data(seq);
156
157        reader.ignore_rest_of_file();
158    }
159    out.expect_written();
160}
161
162static void genbank_to_gcg(const char *inf, const char *outf) {
163    FormatReaderPtr reader = FormatReader::create(FormattedFile(inf, GENBANK));
164    GcgWriter       write(outf);
165
166    GenBank gbk;
167    Seq     seq;
168
169    GenbankReader& greader = dynamic_cast<GenbankReader&>(*reader);
170    if (GenbankParser(gbk, seq, greader).parse_entry()) {
171        genbank_out_header(gbk, seq, write.comment_writer());
172        genbank_out_base_count(seq, write.comment_writer());
173        write.out("ORIGIN\n");
174        write.set_species_name(gbk.get_id());
175        write.write_seq_data(seq);
176
177        reader->ignore_rest_of_file();
178    }
179    write.expect_written();
180}
181
182static void embl_to_gcg(const char *inf, const char *outf) {
183    EmblSwissprotReader reader(inf);
184    GcgWriter           write(outf);
185
186    Embl embl;
187    Seq  seq;
188
189    if (EmblParser(embl, seq, reader).parse_entry()) {
190        embl_out_header(embl, seq, write);
191        write.set_species_name(embl.get_id());
192        write.write_seq_data(seq);
193
194        reader.ignore_rest_of_file();
195    }
196    write.expect_written();
197}
198
199void to_gcg(const FormattedFile& in, const char *outf) {
200    // Convert from whatever to GCG format
201    // @@@ use InputFormat ?
202
203    switch (in.type()) {
204        case MACKE:     macke_to_gcg(in.name(), outf); break;
205        case GENBANK:   genbank_to_gcg(in.name(), outf); break;
206        case EMBL:
207        case SWISSPROT: embl_to_gcg(in.name(), outf); break;
208        default:
209            throw_conversion_not_supported(in.type(), GCG);
210            break;
211    }
212}
213
214
Note: See TracBrowser for help on using the repository browser.