17 #define BUFFER_SIZE 1000
28 if (!(isspace(string_buffer[i]))) {
29 string_buffer[j] = string_buffer[i];
31 if (string_buffer[i] ==
'\0')
break;
42 *number_1 = (
int)strtol(string_buffer, &scanend, 10);
44 if (scanend[0] !=
':') {
45 error =
"expected ':' after integer number";
48 *number_2 = (
int)strtol(scanend+1, &scanend, 10);
51 if (!error && scanend[0] != 0) {
52 error = number_2 ?
"unexpected content after '=NUMBER:NUMBER'" :
"unexpected content after '=NUMBER'";
62 *number_1 = strtod(string_buffer, &scanend);
64 if (scanend[0] !=
':') {
65 error =
"expected ':' after floating-point number";
68 *number_2 = strtod(scanend+1, &scanend);
71 if (!error && scanend[0] != 0) {
72 error = number_2 ?
"unexpected content after '=NUMBER:NUMBER'" :
"unexpected content after '=NUMBER'";
84 if (strncmp(string_buffer, keyword, keywordlen) != 0 || string_buffer[keywordlen] !=
'=') {
88 error =
sec_scan_ints(string_buffer+keywordlen+1, number_1, number_2);
90 if (error) error =
GBS_global_string(
"%s (while parsing '%s')", error, string_buffer);
101 if (strncmp(string_buffer, keyword, keywordlen) != 0 || string_buffer[keywordlen] !=
'=') {
107 if (error) error =
GBS_global_string(
"%s (while parsing '%s')", error, string_buffer);
121 if (strcmp(string_buffer,
"}") == 0)
return NULp;
126 int seq_start = 0, seq_end = 0;
136 if (seq_start >= x_count) error =
GBS_global_string(
"Region start (%i) out of bounds [0..%i]", seq_start, x_count-1);
137 else if (seq_end >= x_count) error =
GBS_global_string(
"Region end (%i) out of bounds [0..%i]", seq_end, x_count-1);
138 else set_sequence_portion(x_string.
getAbsPos(seq_start), x_string.
getAbsPos(seq_end));
141 set_sequence_portion(seq_start, seq_end);
147 GB_ERROR SEC_segment::read(SEC_loop *loop_, istream & in,
int version) {
149 GB_ERROR error = get_region()->read(in, get_root(), version);
154 GB_ERROR SEC_helix::read(istream & in,
int version,
double& old_angle_in) {
167 set_rel_angle(angle);
176 set_abs_angle(angle);
183 old_angle_in = angle+
M_PI;
187 old_angle_in = angle;
198 GB_ERROR SEC_helix_strand::read(SEC_loop *loop_, istream & in,
int version) {
201 SEC_helix_strand *strand2 =
new SEC_helix_strand;
206 GB_ERROR error = get_region()->read(in, root, version);
208 double next_loop_angle = NAN;
211 helix_info =
new SEC_helix(root, strand2,
this);
213 error = helix_info->read(in, version, next_loop_angle);
219 strand2->helix_info =
NULp;
225 if (strncmp(string_buffer,
"LOOP={", 6) != 0) {
226 error =
GBS_global_string(
"Strand must be followed by 'LOOP={' (not by '%s')", string_buffer);
229 SEC_loop *new_loop =
new SEC_loop(root);
230 strand2->origin_loop = new_loop;
232 error = new_loop->read(strand2, in, version, next_loop_angle);
235 error = strand2->get_region()->read(in, root, version);
240 strand2->origin_loop =
NULp;
249 if (!error) origin_loop = loop_;
256 GB_ERROR SEC_loop::read(SEC_helix_strand *rootside_strand, istream & in,
int version,
double loop_angle) {
263 set_fixpoint_strand(rootside_strand);
270 if (!error) set_rel_angle(angle);
273 set_abs_angle(loop_angle);
279 enum { EXPECT_SEGMENT, EXPECT_STRAND } expect = (!rootside_strand && version >= 3) ? EXPECT_STRAND : EXPECT_SEGMENT;
281 SEC_segment *first_new_segment =
NULp;
282 SEC_helix_strand *first_new_strand =
NULp;
283 SEC_segment *last_segment =
NULp;
284 SEC_helix_strand *last_outside_strand = rootside_strand;
287 while (!done && !error) {
290 if (strncmp(string_buffer,
"}", 1) == 0) {
293 else if (expect == EXPECT_SEGMENT) {
294 if (strncmp(string_buffer,
"SEGMENT={", 9) == 0) {
295 SEC_segment *new_seg =
new SEC_segment;
297 error = new_seg->read(
this, in, version);
299 if (last_outside_strand) last_outside_strand->set_next_segment(new_seg);
300 last_outside_strand =
NULp;
301 last_segment = new_seg;
303 if (!first_new_segment) first_new_segment = new_seg;
305 expect = EXPECT_STRAND;
313 if (strncmp(string_buffer,
"STRAND={", 8) == 0) {
314 SEC_helix_strand *new_strand =
new SEC_helix_strand;
316 error = new_strand->read(
this, in, version);
318 if (last_segment) last_segment->set_next_strand(new_strand);
319 last_outside_strand = new_strand;
322 if (!first_new_strand) {
323 first_new_strand = new_strand;
324 if (!rootside_strand) set_fixpoint_strand(first_new_strand);
327 expect = EXPECT_SEGMENT;
329 else delete new_strand;
335 if (!error && !first_new_segment) error =
"Expected at least one SEGMENT in LOOP{}";
336 if (!error && !first_new_strand && !rootside_strand) error =
"Expected at least one STRAND in root-LOOP{}";
341 if (rootside_strand) {
342 last_segment->set_next_strand(rootside_strand);
345 last_segment->set_next_strand(first_new_strand);
353 last_outside_strand->set_next_segment(first_new_segment);
358 if (rootside_strand) rootside_strand->set_next_segment(
NULp);
362 if (error) set_fixpoint_strand(
NULp);
368 istringstream in(input_string);
380 double firstLoopAngle = 0;
392 firstLoopAngle +=
M_PI;
397 firstLoopAngle +=
M_PI;
414 size_t len = strlen(x_string_in);
415 size_t exp_len = db->length();
417 if (len != exp_len && len != (exp_len+1)) {
419 len, exp_len, exp_len+1);
422 xString =
new XString(x_string_in, len, db->length());
425 printf(
"x_string_in len=%zu\nxlen=%zu\nali_length=%zu\n", strlen(x_string_in), xlen, db->length());
434 printf(
"Reading structure format (version %i)\n", version);
437 if (strncmp(string_buffer,
"LOOP={", 6) == 0) {
438 SEC_loop *rootLoop =
new SEC_loop(
this);
440 set_root_loop(rootLoop);
441 set_under_construction(
true);
442 error = rootLoop->read(
NULp, in, version, firstLoopAngle);
445 set_under_construction(
false);
452 error =
GBS_global_string(
"Expected root loop ('LOOP={'), not '%s'", string_buffer);
459 printf(
"Converting secondary structure from version %i to %i\n", version,
DATA_VERSION);
461 if (version<3) fixStructureBugs(version);
462 #if defined(CHECK_INTEGRITY)
463 check_integrity(CHECK_STRUCTURE);
464 #endif // CHECK_INTEGRITY
467 root_loop->fixAngleBugs(version);
474 void SEC_helix::fixAngleBugs(
int version) {
476 outsideLoop()->fixAngleBugs(version);
483 Vector loop2strand(rootsideLoop()->get_center(), get_fixpoint());
484 if (
scalarProduct(loop2strand, get_abs_angle().normal()) < 0) {
485 printf(
"* Autofix acute angle (loop2strand=%.2f, abs=%.2f) of helix nr '%s'\n",
486 Angle(loop2strand).radian(),
487 get_abs_angle().radian(),
488 get_root()->helixNrAt(strandToOutside()->startAttachAbspos()));
489 set_rel_angle(
Angle(get_rel_angle()).rotate180deg());
494 void SEC_loop::fixAngleBugs(
int version) {
497 if (strand->pointsToOutside()) {
498 strand->get_helix()->fixAngleBugs(version);
504 void SEC_root::fixStructureBugs(
int version) {
507 SEC_base_part *start_part = root_loop->get_fixpoint_strand();
516 printf(
"* Fixing non-adjacent regions: %i..%i and %i..%i\n",
534 while (part != start_part);
static GB_ERROR sec_expect_keyword_and_doubles(const char *string_buffer, const char *keyword, size_t keywordlen, double *number_1, double *number_2)
int get_sequence_start() const
const SEC_db_interface * get_db() const
int get_sequence_end() const
bool are_adjacent_regions(const SEC_region *reg1, const SEC_region *reg2)
const char * GBS_global_string(const char *templat,...)
virtual SEC_BASE_TYPE getType() const =0
static GB_ERROR sec_scan_doubles(const char *string_buffer, double *number_1, double *number_2)
static GB_ERROR sec_expect_constraints(const char *string_buffer, const char *keyword, size_t keywordlen, SEC_constrainted *elem)
const XString & get_xString() const
void set_sequence_portion(int start, int end)
GB_ERROR read_data(const char *input_string, const char *x_string_in)
size_t getAbsPos(int x) const
static GB_ERROR sec_expect_closing_bracket(istream &in)
const SEC_region * get_region() const
static void error(const char *msg)
GB_ERROR read(std::istream &in, SEC_root *root, int version)
static const char * sec_read_line(istream &in)
CONSTEXPR_INLINE bool valid(SpeciesCreationMode m)
double scalarProduct(const Vector &v1, const Vector &v2)
static GB_ERROR sec_expect_keyword_and_ints(const char *string_buffer, const char *keyword, size_t keywordlen, int *number_1, int *number_2)
static GB_ERROR sec_scan_ints(const char *string_buffer, int *number_1, int *number_2)
void setConstraints(double low, double high)