OpenMPCD
NormalModeAutocorrelation.py
1 """
2 @package MPCDAnalysis.NormalModeAutocorrelation
3 
4 Analysis functionality for data on normal mode autocorrelations, as produced by
5 `OpenMPCD::CUDA::MPCFluid::Instrumentation::NormalModeAutocorrelation`.
6 """
7 
9  """
10  Analysis class for data on normal mode autocorrelation, as produced by
11  `OpenMPCD::CUDA::MPCFluid::Instrumentation::NormalModeAutocorrelation`.
12 
13  Unless specified otherwise, all times are measured in units of `measurement
14  time`, as defined in
15  `OpenMPCD::CUDA::MPCFluid::Instrumentation::NormalModeAutocorrelation`.
16 
17  @see OpenMPCD::CUDA::MPCFluid::Instrumentation::NormalModeAutocorrelation
18  """
19 
20  def __init__(self, rundirs):
21  """
22  The constructor.
23 
24  @throw TypeError
25  Throws if `rundirs` is not a `string`, or a `list` of `string`s.
26  @throw ValueError
27  Throws if the given `rundir` does not exist, or does not contain
28  a readable, valid `normalModeAutocorrelations.data` file.
29 
30  @param[in] rundirs
31  The run directory, as a `string`. From this directory, the
32  file `normalModeAutocorrelations.data` will be read as input.
33  Alternatively, this may be a `list` of `string` instances,
34  each of which will be treated as described above.
35  """
36 
37  if isinstance(rundirs, str):
38  rundirs = [rundirs]
39 
40  if not isinstance(rundirs, list):
41  raise TypeError()
42  for rundir in rundirs:
43  if not isinstance(rundir, str):
44  raise TypeError()
45 
46 
47  self._config = None
48  self._measurements = []
49  self._normalModeCount = None
50  self._statistics = {}
51 
52 
53  from MPCDAnalysis.Configuration import Configuration
54  import os.path
55 
56  for rundir in rundirs:
57  filepath = rundir + "/" + "normalModeAutocorrelations.data"
58 
59  if not os.path.isfile(filepath):
60  raise ValueError()
61 
62  config = Configuration(rundir)
63  if self._config is None:
64  self._config = config
66  self._config[
67  "instrumentation.normalModeAutocorrelation." + \
68  "autocorrelationArgumentCount"]
69  else:
70  differences = \
71  self._config.getDifferencesAsFlatDictionary(config)
72 
73  ignoredKeys = \
74  [
75  "mpc.sweeps",
76  ]
77  for ignoredKey in ignoredKeys:
78  if ignoredKey in differences:
79  del differences[ignoredKey]
80 
81  if len(differences) != 0:
82  msg = "Incompatible rundirs given."
83  msg += " Differences:\n"
84  msg += str(differences)
85  raise ValueError(msg)
86 
87  with open(filepath, "r") as f:
88  self._parse(f)
89 
90 
91  def getNormalModeCount(self):
92  """
93  Returns the number of normal modes.
94  """
95 
96  assert self._normalModeCount is not None
97 
98  return self._normalModeCount
99 
100 
101  def getMaximumMeasurementTime(self):
102  """
103  Returns, in units of `measurement time`, the maximum correlation time
104  that was configured to be measured, i.e. \f$ N_A - 1 \f$.
105  """
106 
107  return self._autocorrelationArgumentCount - 1
108 
109 
110  def getAutocorrelation(self, mode, correlationTime):
111  """
112  Returns an `OnTheFlyStatisticsDDDA` object that holds information on the
113  sample of measured autocorrelations for normal mode index `mode` and
114  correlation time `correlationTime`.
115 
116  @throw TypeError
117  Throws if any of the arguments have invalid types.
118  @throw ValueError
119  Throws if any of the arguments have invalid values.
120 
121  @param[in] mode
122  The normal mode index, as an `int` in the range
123  `[0, getNormalModeCount())`.
124  @param[in] correlationTime
125  The correlation time to return results for, measured in
126  This argument is to be of type `int`, non-negative, and at
127  most `getMaximumMeasurementTime()`.
128  """
129 
130  if not isinstance(mode, int):
131  raise TypeError()
132  if mode < 0 or mode >= self.getNormalModeCount():
133  raise ValueError()
134 
135  if not isinstance(correlationTime, int):
136  raise TypeError()
137  if correlationTime < 0:
138  raise ValueError()
139  if correlationTime > self.getMaximumMeasurementTime():
140  raise ValueError()
141 
142  if mode in self._statistics:
143  if correlationTime in self._statistics[mode]:
144  return self._statistics[mode][correlationTime]
145 
146  if mode not in self._statistics:
147  self._statistics[mode] = {}
148 
149  from MPCDAnalysis.OnTheFlyStatisticsDDDA import OnTheFlyStatisticsDDDA
150  stat = OnTheFlyStatisticsDDDA()
151 
152 
153  for measurement in self._measurements[mode]:
154  if correlationTime >= len(measurement):
155  continue
156 
157  stat.addDatum(measurement[correlationTime])
158 
159  self._statistics[mode][correlationTime] = stat
160  return self._statistics[mode][correlationTime]
161 
162 
163  def getMPLAxes(self, mode, showEstimatedStandardDeviation = True):
164  """
165  Returns an `matplotlib.axes.Axes` object that plots the normal mode
166  autocorrelation of mode index `mode` against the correlation time, in
167  units of `measurement time`.
168 
169  @throw TypeError
170  Throws if any of the arguments have invalid types.
171  @throw ValueError
172  Throws if any of the arguments have invalid values.
173 
174  @param[in] mode
175  The normal mode index, as an `int` in the range
176  `[0, getNormalModeCount())`.
177  @param[in] showEstimatedStandardDeviation
178  Whether to show, for each data point, the estimated standard
179  deviation.
180  """
181 
182  if not isinstance(mode, int):
183  raise TypeError()
184  if mode < 0 or mode >= self.getNormalModeCount():
185  raise ValueError()
186  if not isinstance(showEstimatedStandardDeviation, bool):
187  raise TypeError()
188 
189 
190  import matplotlib.figure
191 
192  figure = matplotlib.figure.Figure()
193  axes = figure.add_subplot(1, 1, 1)
194 
195  times = []
196  values = []
197  errorbars = []
198  for T in range(0, self.getMaximumMeasurementTime() + 1):
199  autocorrelation = self.getAutocorrelation(mode, T)
200 
201  times.append(T)
202  values.append(autocorrelation.getSampleMean())
203  if showEstimatedStandardDeviation:
204  errorbars.append(
205  autocorrelation.getOptimalStandardErrorOfTheMean())
206 
207  if len(errorbars) == 0:
208  errorbars = None
209 
210 
211  axes.errorbar(times, values, yerr = errorbars)
212 
213  axes.set_xlabel(r'Correlation Time $ T $')
214  axes.set_ylabel(r'$ C(0, T, n=' + str(mode) + ') $')
215 
216  return axes
217 
218 
219  def _parse(self, f):
220  """
221  Parses the given file `f`.
222 
223  If a file has been parsed already, this new file is treated as if it
224  was a continuation of previously parsed runs. Hence, this file's first
225  measurement is treated as if it followed the last file's last
226  measurement.
227 
228  @param[in] f
229  The file to parse, of type `file`.
230  """
231 
232  assert isinstance(f, file)
233 
234  starting_mt0 = 0
235  if self._measurements:
236  starting_mt0 = len(self._measurements[0])
237 
238  for line in f:
239  parts = line.split()
240  if len(parts) < 3:
241  raise ValueError()
242 
243  if self._normalModeCount is None:
244  self._normalModeCount = len(parts) - 2
245  for _ in range(0, self._normalModeCount):
246  self._measurements.append([])
247  else:
248  if len(parts) != self._normalModeCount + 2:
249  raise ValueError()
250 
251  mt0 = int(parts[0]) + starting_mt0
252  mtT = int(parts[1])
253 
254  for mode in range(0, self._normalModeCount):
255  autocorrelation = float(parts[2 + mode])
256 
257  if mt0 >= len(self._measurements[mode]):
258  assert mt0 == len(self._measurements[mode])
259  self._measurements[mode].append([])
260 
261  if mtT != len(self._measurements[mode][mt0]):
262  print(mt0)
263  print(mtT)
264  print(len(self._measurements[mode][mt0]))
265  print("")
266  assert mtT == len(self._measurements[mode][mt0])
267  self._measurements[mode][mt0].append(autocorrelation)
MPCDAnalysis.NormalModeAutocorrelation.NormalModeAutocorrelation._parse
def _parse(self, f)
Definition: NormalModeAutocorrelation.py:238
MPCDAnalysis.NormalModeAutocorrelation.NormalModeAutocorrelation.__init__
def __init__(self, rundirs)
Definition: NormalModeAutocorrelation.py:38
MPCDAnalysis.NormalModeAutocorrelation.NormalModeAutocorrelation._config
_config
Definition: NormalModeAutocorrelation.py:50
MPCDAnalysis.NormalModeAutocorrelation.NormalModeAutocorrelation._statistics
_statistics
Definition: NormalModeAutocorrelation.py:53
MPCDAnalysis.NormalModeAutocorrelation.NormalModeAutocorrelation._measurements
_measurements
Definition: NormalModeAutocorrelation.py:51
MPCDAnalysis.NormalModeAutocorrelation.NormalModeAutocorrelation
Definition: NormalModeAutocorrelation.py:20
MPCDAnalysis.NormalModeAutocorrelation.NormalModeAutocorrelation.getNormalModeCount
def getNormalModeCount(self)
Definition: NormalModeAutocorrelation.py:98
MPCDAnalysis.NormalModeAutocorrelation.NormalModeAutocorrelation.getAutocorrelation
def getAutocorrelation(self, mode, correlationTime)
Definition: NormalModeAutocorrelation.py:134
MPCDAnalysis.NormalModeAutocorrelation.NormalModeAutocorrelation._autocorrelationArgumentCount
_autocorrelationArgumentCount
Definition: NormalModeAutocorrelation.py:68
MPCDAnalysis.NormalModeAutocorrelation.NormalModeAutocorrelation.getMPLAxes
def getMPLAxes(self, mode, showEstimatedStandardDeviation=True)
Definition: NormalModeAutocorrelation.py:187
MPCDAnalysis.NormalModeAutocorrelation.NormalModeAutocorrelation._normalModeCount
_normalModeCount
Definition: NormalModeAutocorrelation.py:52
MPCDAnalysis.NormalModeAutocorrelation.NormalModeAutocorrelation.getMaximumMeasurementTime
def getMaximumMeasurementTime(self)
Definition: NormalModeAutocorrelation.py:110
MPCDAnalysis.Configuration
Definition: Configuration.py:1
MPCDAnalysis.OnTheFlyStatisticsDDDA
Definition: OnTheFlyStatisticsDDDA.py:1