File: CifFile.h

package info (click to toggle)
pymol 1.8.4.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 42,248 kB
  • ctags: 24,095
  • sloc: cpp: 474,635; python: 75,034; ansic: 22,888; sh: 236; makefile: 78; csh: 21
file content (171 lines) | stat: -rw-r--r-- 3,577 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
 * CIF tokenizer
 *
 * (c) 2014 Schrodinger, Inc.
 */

#ifndef _H_CIFFILE
#define _H_CIFFILE

#include <vector>
#include <map>
#include <stdexcept>

#include <string.h>

#ifdef WIN32
  #define strcasecmp(s1, s2) _stricmp(s1, s2)
  #define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
#endif

/*
 * C string comparison class
 */
struct strless2_t {
  bool operator()(const char * a, const char * b) const {
    return strcmp(a, b) < 0;
  }
};

// cif data types
class cif_data;
class cif_loop;
class cif_array;
typedef std::vector<cif_loop*> v_cifloopp_t;
typedef std::map<const char*, cif_data*, strless2_t> m_str_cifdatap_t;
typedef std::map<const char*, cif_array, strless2_t> m_str_cifarray_t;

// atof with uncertanty notation handling
double scifloat(const char *);

/*
 * Class for reading CIF files.
 * Parses the entire file and exposes its data blocks.
 */
class cif_file {
public:
  m_str_cifdatap_t datablocks;

  // constructors & destructor
  cif_file(const char* filename, const char* contents=NULL);
  ~cif_file();

private:
  char * contents;

  std::vector<char*> tokens;

  // methods
  bool parse();
};

/*
 * Class to store CIF loops. Only for parsing, do not use in any higher level
 * reading functions.
 */
class cif_loop {
public:
  int ncols;
  int nrows;
  const char **values;

  // methods
  const char * get_value_raw(int row, int col) const;
};

/*
 * High-level access to CIF arrays
 */
class cif_array {
private:
  // column index, -1 if not in loop
  short col;

  // pointer to either loop or single value
  union {
    const cif_loop * loop;
    const char * value;
  } pointer;

  // methods
  const char * get_value_raw(int row = 0) const;
  const char * get_value(int row = 0) const;

public:
  // point this array to a loop (only for parsing)
  void set_loop(const cif_loop * loop, short col_) {
    col = col_;
    pointer.loop = loop;
  };

  // point this array to a single value (only for parsing)
  void set_value(const char * value) {
    col = -1;
    pointer.value = value;
  };

  // constructor
  cif_array() {
  };

  // constructor (only needed for EMPTY_ARRAY)
  cif_array(const char * value) {
    set_value(value);
  };

  // get the number of elements in this array
  int get_nrows() const {
    return (col < 0) ? 1 : pointer.loop->nrows;
  };

  // get element as string, integer or double. If index is out of bounds,
  // then return a default value.
  const char * as_s(int row = 0) const;
  int          as_i(int row = 0, int d = 0) const;
  double       as_d(int row = 0, double d = 0.0) const;

  // true if value in ['.', '?']
  bool is_missing(int row = 0) const {
    return !get_value(row);
  }

  // templated getter
  template <typename T> T as(int row = 0) const;

  // get a copy of the entire array
  template <typename T> std::vector<T> to_vector() const {
    int n = get_nrows();
    std::vector<T> v;
    v.reserve(n);
    for (int i = 0; i < n; ++i)
      v.push_back(as<T>(i));
    return v;
  }
};

/*
 * High-level access to CIF data blocks
 */
class cif_data {
  friend class cif_file;

private:
  m_str_cifarray_t dict;
  m_str_cifdatap_t saveframes;

  // only needed for freeing
  v_cifloopp_t loops;

public:
  // Get a pointer to array or NULL if not found
  const cif_array * get_arr(const char * key, const char * alias1=NULL, const char * alias2=NULL) const;

  // Get a pointer to array or to a default value if not found
  const cif_array * get_opt(const char * key, const char * alias1=NULL, const char * alias2=NULL) const;

  // destructor
  ~cif_data();
};

#endif
// vi:sw=2:ts=2