Print notice message when group.all() is updated
[hoomd-blue.git] / python-module / hoomd_script / analyze.py
blobf25b85082ccd10b65b634a10ef3a50cf7bb337e3
1 # -- start license --
2 # Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
3 # (HOOMD-blue) Open Source Software License Copyright 2008-2011 Ames Laboratory
4 # Iowa State University and The Regents of the University of Michigan All rights
5 # reserved.
7 # HOOMD-blue may contain modifications ("Contributions") provided, and to which
8 # copyright is held, by various Contributors who have granted The Regents of the
9 # University of Michigan the right to modify and/or distribute such Contributions.
11 # You may redistribute, use, and create derivate works of HOOMD-blue, in source
12 # and binary forms, provided you abide by the following conditions:
14 # * Redistributions of source code must retain the above copyright notice, this
15 # list of conditions, and the following disclaimer both in the code and
16 # prominently in any materials provided with the distribution.
18 # * Redistributions in binary form must reproduce the above copyright notice, this
19 # list of conditions, and the following disclaimer in the documentation and/or
20 # other materials provided with the distribution.
22 # * All publications and presentations based on HOOMD-blue, including any reports
23 # or published results obtained, in whole or in part, with HOOMD-blue, will
24 # acknowledge its use according to the terms posted at the time of submission on:
25 # http://codeblue.umich.edu/hoomd-blue/citations.html
27 # * Any electronic documents citing HOOMD-Blue will link to the HOOMD-Blue website:
28 # http://codeblue.umich.edu/hoomd-blue/
30 # * Apart from the above required attributions, neither the name of the copyright
31 # holder nor the names of HOOMD-blue's contributors may be used to endorse or
32 # promote products derived from this software without specific prior written
33 # permission.
35 # Disclaimer
37 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND
38 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
39 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR ANY
40 # WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.
42 # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
43 # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
44 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
45 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
46 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
47 # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
48 # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49 # -- end license --
51 # Maintainer: joaander / All Developers are free to add commands for new features
53 import hoomd;
54 from hoomd_script import globals;
55 import sys;
56 from hoomd_script import util;
57 from hoomd_script import init;
59 ## \package hoomd_script.analyze
60 # \brief Commands that %analyze the system and provide some output
62 # An analyzer examines the system state in some way every \a period time steps and generates
63 # some form of output based on the analysis. Check the documentation for individual analyzers
64 # to see what they do.
66 ## \page variable_period_docs Variable period specification
68 # If, for any reason, a constant period for a command is not to your liking, you can make it any
69 # function you please! Just specify a function taking a single argument to the period parameter.
70 # Any analyze, update, or dump command in hoomd can be given such a variable period.
71 # dump.xml is used as an example here, but the same works with \b any update, dump,
72 # or analyze command
74 # For example, lets say we want to dump xml files at time steps 1, 10, 100, 1000, ...
75 # The following command will do the job.
77 # \code
78 # dump.xml(filename="dump", period = lambda n: 10**n)
79 # \endcode
81 # It is that simple. Any mathematical expression that can be represented in python can be used
82 # in place of the 10**n.
84 # <b>More examples:</b>
85 # \code
86 # dump.xml(filename="dump", period = lambda n: n**2)
87 # dump.xml(filename="dump", period = lambda n: 2**n)
88 # dump.xml(filename="dump", period = lambda n: 1005 + 0.5 * 10**n)
89 # \endcode
91 # The only requirement is that the object passed into period is callable, accepts one argument, and returns
92 # a floating point number or integer. The function also had better be monotonically increasing or the output
93 # might not make any sense.
95 # <b>How does it work, exactly?</b>
96 # - First, the current time step of the simulation is saved when the analyzer is created
97 # - \a n is also set to 1 when the analyzer is created
98 # - Every time the analyzer performs it's output, it evaluates the given function at the current value of \a n
99 # and records that as the next time to perform the analysis. \a n is then incremented by 1
101 # Here is a final example of how variable periods behave in simulations where analyzers are not created on time step 0.
102 # The following
103 # \code
104 # ... initialize ...
105 # run(4000)
106 # dump.xml(filename="dump", period = lambda n: 2**n)
107 # run(513)
108 # \endcode
109 # will result in dump files at time steps 4000, 4002, 4004, 4008, 4016, 4032, 4064, 4128, 4256, and 4512.
111 # In other words, the function specified for the period starts counting at the time step <b>when the analyzer is created</b>.
112 # Consequently, any analyze, dump, or update command given a variable period becomes ill-defined if it is disabled and then re-enabled.
113 # If this is done, it will then re-enable with a constant period of 1000 as a default case.
116 ## \internal
117 # \brief Base class for analyzers
119 # An analyzer in hoomd_script reflects an Analyzer in c++. It is responsible
120 # for all high-level management that happens behind the scenes for hoomd_script
121 # writers. 1) The instance of the c++ analyzer itself is tracked and added to the
122 # System 2) methods are provided for disabling the analyzer and changing the
123 # period which the system calls it
124 class _analyzer:
125 ## \internal
126 # \brief Constructs the analyzer
128 # Initializes the cpp_analyzer to None.
129 # Assigns a name to the analyzer in analyzer_name;
130 def __init__(self):
131 # check if initialization has occurred
132 if not init.is_initialized():
133 globals.msg.error("Cannot create analyzer before initialization\n");
134 raise RuntimeError('Error creating analyzer');
136 self.cpp_analyzer = None;
138 # increment the id counter
139 id = _analyzer.cur_id;
140 _analyzer.cur_id += 1;
142 self.analyzer_name = "analyzer%d" % (id);
143 self.enabled = True;
145 ## \internal
146 # \brief Helper function to setup analyzer period
148 # \param period An integer or callable function period
150 # If an integer is specified, then that is set as the period for the analyzer.
151 # If a callable is passed in as a period, then a default period of 1000 is set
152 # to the integer period and the variable period is enabled
154 def setupAnalyzer(self, period):
155 if type(period) == type(1.0):
156 globals.system.addAnalyzer(self.cpp_analyzer, self.analyzer_name, int(period));
157 elif type(period) == type(1):
158 globals.system.addAnalyzer(self.cpp_analyzer, self.analyzer_name, period);
159 elif type(period) == type(lambda n: n*2):
160 globals.system.addAnalyzer(self.cpp_analyzer, self.analyzer_name, 1000);
161 globals.system.setAnalyzerPeriodVariable(self.analyzer_name, period);
162 else:
163 globals.msg.error("I don't know what to do with a period of type " + str(type(period)) + " expecting an int or a function\n");
164 raise RuntimeError('Error creating analyzer');
166 ## \var enabled
167 # \internal
168 # \brief True if the analyzer is enabled
170 ## \var cpp_analyzer
171 # \internal
172 # \brief Stores the C++ side Analyzer managed by this class
174 ## \var analyzer_name
175 # \internal
176 # \brief The Analyzer's name as it is assigned to the System
178 ## \var prev_period
179 # \internal
180 # \brief Saved period retrieved when an analyzer is disabled: used to set the period when re-enabled
182 ## \internal
183 # \brief Checks that proper initialization has completed
184 def check_initialization(self):
185 # check that we have been initialized properly
186 if self.cpp_analyzer is None:
187 globals.msg.error('Bug in hoomd_script: cpp_analyzer not set, please report\n');
188 raise RuntimeError();
190 ## Disables the analyzer
192 # \b Examples:
193 # \code
194 # analyzer.disable()
195 # \endcode
197 # Executing the disable command will remove the analyzer from the system.
198 # Any run() command executed after disabling an analyzer will not use that
199 # analyzer during the simulation. A disabled analyzer can be re-enabled
200 # with enable()
202 # To use this command, you must have saved the analyzer in a variable, as
203 # shown in this example:
204 # \code
205 # analyzer = analyzer.some_analyzer()
206 # # ... later in the script
207 # analyzer.disable()
208 # \endcode
209 def disable(self):
210 util.print_status_line();
211 self.check_initialization();
213 # check if we are already disabled
214 if not self.enabled:
215 globals.msg.warning("Ignoring command to disable an analyzer that is already disabled");
216 return;
218 self.prev_period = globals.system.getAnalyzerPeriod(self.analyzer_name);
219 globals.system.removeAnalyzer(self.analyzer_name);
220 self.enabled = False;
222 ## Enables the analyzer
224 # \b Examples:
225 # \code
226 # analyzer.enable()
227 # \endcode
229 # See disable() for a detailed description.
230 def enable(self):
231 util.print_status_line();
232 self.check_initialization();
234 # check if we are already disabled
235 if self.enabled:
236 globals.msg.warning("Ignoring command to enable an analyzer that is already enabled");
237 return;
239 globals.system.addAnalyzer(self.cpp_analyzer, self.analyzer_name, self.prev_period);
240 self.enabled = True;
242 ## Changes the period between analyzer executions
244 # \param period New period to set (in time steps)
246 # \b Examples:
247 # \code
248 # analyzer.set_period(100)
249 # analyzer.set_period(1)
250 # \endcode
252 # While the simulation is \ref run() "running", the action of each analyzer
253 # is executed every \a period time steps.
255 # To use this command, you must have saved the analyzer in a variable, as
256 # shown in this example:
257 # \code
258 # analyzer = analyze.some_analyzer()
259 # # ... later in the script
260 # analyzer.set_period(10)
261 # \endcode
262 def set_period(self, period):
263 util.print_status_line();
265 if type(period) == type(1):
266 if self.enabled:
267 globals.system.setAnalyzerPeriod(self.analyzer_name, period);
268 else:
269 self.prev_period = period;
270 elif type(period) == type(lambda n: n*2):
271 globals.msg.warning("A period cannot be changed to a variable one");
272 else:
273 globals.msg.warning("I don't know what to do with a period of type " + str(type(period)) + " expecting an int or a function");
275 # set default counter
276 _analyzer.cur_id = 0;
279 ## Sends simulation snapshots to VMD in real-time
281 # analyze.imd listens on a specified TCP/IP port for connections from VMD.
282 # Once that connection is established, it begins transmitting simulation snapshots
283 # to VMD every \a rate time steps.
285 # To connect to a simulation running on the local host, issue the command
286 # \code
287 # imd connect localhost 54321
288 # \endcode
289 # in the VMD command window (where 54321 is replaced with the port number you specify for
290 # analyze.imd
292 # \note If a period larger than 1 is set, the actual rate at which time steps are transmitted is \a rate * \a period.
293 # \MPI_SUPPORTED
294 class imd(_analyzer):
295 ## Initialize the IMD interface
297 # \param port TCP/IP port to listen on
298 # \param period Number of time steps to run before checking for new IMD messages
299 # \param rate Number of \a periods between coordinate data transmissions.
300 # \param pause Set to True to \b pause the simulation at the first time step until an imd connection is made
301 # \param force Give a saved force.constant to analyze.imd to apply forces received from VMD
302 # \param force_scale Factor by which to scale all forces received from VMD
304 # \b Examples:
305 # \code
306 # analyze.imd(port=54321, rate=100)
307 # analyze.imd(port=54321, rate=100, pause=True)
308 # imd = analyze.imd(port=12345, rate=1000)
309 # \endcode
311 # \a period can be a function: see \ref variable_period_docs for details
312 def __init__(self, port, period=1, rate=1, pause=False, force=None, force_scale=0.1):
313 util.print_status_line();
315 # initialize base class
316 _analyzer.__init__(self);
318 # get the cpp force
319 if force is not None:
320 cpp_force = force.cpp_force;
321 else:
322 cpp_force = None;
324 # create the c++ mirror class
325 self.cpp_analyzer = hoomd.IMDInterface(globals.system_definition, port, pause, rate, cpp_force);
326 self.setupAnalyzer(period);
329 ## Logs a number of calculated quantities to a file
331 # analyze.log can read a variety of calculated values, like energy and temperature, from
332 # specified forces, integrators, and updaters. It writes a single line to the specified
333 # output file every \a period time steps. The resulting file is suitable for direct import
334 # into a spreadsheet, MATLAB, or other software that can handle simple delimited files.
337 # Quantities that can be logged at any time:
338 # - \b volume - Volume of the simulation box (in volume units)
339 # - \b lx - Box length in x direction (in length units)
340 # - \b ly - Box length in y direction (in length units)
341 # - \b lz - Box length in z direction (in length units)
342 # - \b xy - Box tilt factor in xy plane (dimensionless)
343 # - \b xz - Box tilt factor in xz plane (dimensionless)
344 # - \b yz - Box tilt factor in yz plane (dimensionless)
345 # - \b momentum - Magnitude of the average momentum of all particles (in momentum units)
346 # - \b time - Wall-clock running time from the start of the log (in seconds)
348 # Thermodynamic properties
349 # - The following quantities are always available and computed over all particles in the system
350 # (see compute.thermo for detailed definitions):
351 # - **num_particles**
352 # - **ndof**
353 # - **potential_energy** (in energy units)
354 # - **kinetic_energy** (in energy units)
355 # - **temperature** (in thermal energy units)
356 # - **pressure** (in pressure units)
357 # - **pressure_xx**, **pressure_xy**, **pressure_xz**, **pressure_yy**, **pressure_yz**, **pressure_zz** (in pressure units)
358 # - The above quantities, tagged with a <i>_groupname</i> suffix are automatically available for any group passed to
359 # an integrate command
360 # - Specify a compute.thermo directly to enable additional quantities for user-specified groups.
362 # The following quantities are only available if the command is parentheses has been specified and is active
363 # for logging.
364 # - Pair potentials
365 # - **pair_dpd_energy** (pair.dpd) - Total DPD conservative potential energy (in energy units)
366 # - **pair_dpdlj_energy** (pair.dpdlj) - Total DPDLJ conservative potential energy (in energy units)
367 # - **pair_eam_energy** (pair.eam) - Total EAM potential energy (in energy units)
368 # - **pair_ewald_energy** (pair.ewald) - Short ranged part of the electrostatic energy (in energy units)
369 # - **pair_gauss_energy** (pair.gauss) - Total Gaussian potential energy (in energy units)
370 # - **pair_lj_energy** (pair.lj) - Total Lennard-Jones potential energy (in energy units)
371 # - **pair_morse_energy** (pair.yukawa) - Total Morse potential energy (in energy units)
372 # - **pair_table_energy** (pair.table) - Total potential energy from Tabulated potentials (in energy units)
373 # - **pair_slj_energy** (pair.slj) - Total Shifted Lennard-Jones potential energy (in energy units)
374 # - **pair_yukawa_energy** (pair.yukawa) - Total Yukawa potential energy (in energy units)
375 # - **pair_force_shifted_lj_energy** (pair.force_shifted_lj) - Total Force-shifted Lennard-Jones potential energy (in energy units)
376 # - **pppm_energy** (charge.pppm) - Long ranged part of the electrostatic energy (in energy units)
377 # - Bond potentials
378 # - **bond_fene_energy** (bond.fene) - Total fene bond potential energy (in energy units)
379 # - **bond_harmonic_energy** (bond.harmonic) - Total harmonic bond potential energy (in energy units)
380 # - **bond_table_energy** (bond.table) - Total table bond potential energy (in energy units)
381 # - External potentials
382 # - **external_periodic_energy** (external.periodic) - Total DPD conservative potential energy (in energy units)
383 # - Wall potentials
384 # - **wall_lj_energy** (wall.lj) - Total Lennard-Jones wall energy (in energy units)
385 # - Integrators
386 # - **bdnvt_reservoir_energy**_groupname (integrate.bdnvt) - Energy reservoir for the BD thermostat (in energy units)
387 # - **nvt_reservoir_energy**_groupname (integrate.nvt) - Energy reservoir for the NVT thermostat (in energy units)
388 # - **npt_thermostat_energy** (integrate.npt) - Energy of the NPT thermostat
389 # - **npt_barostat_energy** (integrate.npt & integrate.nph) - Energy of the NPT (or NPH) barostat
391 # Additionally, the following commands can be provided user-defined names that are appended as suffixes to the
392 # logged quantitiy (e.g. with \c pair.lj(r_cut=2.5, \c name="alpha"), the logged quantity would be pair_lj_energy_alpha).
393 # - All pair potentials
394 # - All bond potentials
396 # By specifying a force, disabling it with the \a log=True option, and then logging it, different energy terms can
397 # be computed while only a subset of them actually drive the simulation. Common use-cases of this capability
398 # include separating out pair energy of given types (shown below) and free energy calculations. Be aware that the
399 # globally chosen \a r_cut value is the largest of all active pair potentials and those with \a log=True, so you will
400 # observe performance degradation if you \a disable(log=True) a potential with a large \a r_cut.
402 # \b Examples:
403 # \code
404 # lj1 = pair.lj(r_cut=3.0, name="lj1")
405 # lj1.pair_coeff.set('A', 'A', epsilon=1.0, sigma=1.0)
406 # lj1.pair_coeff.set('A', 'B', epsilon=1.0, sigma=1.0)
407 # lj1.pair_coeff.set('B', 'B', epsilon=1.0, sigma=1.0)
409 # lj2 = pair.lj(r_cut=3.0, name="lj2")
410 # lj2.pair_coeff.set('A', 'A', epsilon=1.0, sigma=1.0)
411 # lj2.pair_coeff.set('A', 'B', epsilon=0.0, sigma=1.0)
412 # lj2.pair_coeff.set('B', 'B', epsilon=0.0, sigma=1.0)
413 # lj2.disable(log=True)
415 # analyze.log(filename='mylog.log', quantities=['pair_lj_energy_lj1', 'pair_lj_energy_lj2'],
416 # period=100, header_prefix='#')
417 # \endcode
419 # \sa \ref page_units
420 # \MPI_SUPPORTED
421 class log(_analyzer):
422 ## Initialize the log
424 # \param filename File to write the log to
425 # \param quantities List of quantities to log
426 # \param period Quantities are logged every \a period time steps
427 # \param header_prefix (optional) Specify a string to print before the header
428 # \param overwrite When False (the default) an existing log will be appended to.
429 # If True, an existing log file will be overwritten instead.
431 # \b Examples:
432 # \code
433 # logger = analyze.log(filename='mylog.log', period=100,
434 # quantities=['pair_lj_energy'])
436 # analyze.log(quantities=['pair_lj_energy', 'bond_harmonic_energy',
437 # 'kinetic_energy'], period=1000, filename='full.log')
439 # analyze.log(filename='mylog.log', quantities=['pair_lj_energy'],
440 # period=100, header_prefix='#')
442 # analyze.log(filename='mylog.log', quantities=['bond_harmonic_energy'],
443 # period=10, header_prefix='Log of harmonic energy, run 5\n')
444 # logger = analyze.log(filename='mylog.log', period=100,
445 # quantities=['pair_lj_energy'], overwrite=True)
446 # \endcode
448 # By default, columns in the log file are separated by tabs, suitable for importing as a
449 # tab-delimited spreadsheet. The delimiter can be changed to any string using set_params()
451 # The \a header_prefix can be used in a number of ways. It specifies a simple string that
452 # will be printed before the header line of the output file. One handy way to use this
453 # is to specify header_prefix='#' so that \c gnuplot will ignore the header line
454 # automatically. Another use-case would be to specify a descriptive line containing
455 # details of the current run. Examples of each of these cases are given above.
457 # \warning When an existing log is appended to, the header is not printed. For the log to
458 # remain consistent with the header already in the file, you must specify the same quantities
459 # to log and in the same order for all runs of hoomd that append to the same log.
461 # \a period can be a function: see \ref variable_period_docs for details
462 def __init__(self, filename, quantities, period, header_prefix='', overwrite=False):
463 util.print_status_line();
465 # initialize base class
466 _analyzer.__init__(self);
468 # create the c++ mirror class
469 self.cpp_analyzer = hoomd.Logger(globals.system_definition, filename, header_prefix, overwrite);
470 self.setupAnalyzer(period);
472 # set the logged quantities
473 quantity_list = hoomd.std_vector_string();
474 for item in quantities:
475 quantity_list.append(item);
476 self.cpp_analyzer.setLoggedQuantities(quantity_list);
478 # add the logger to the list of loggers
479 globals.loggers.append(self);
481 ## Change the parameters of the log
483 # \param quantities New list of quantities to log (if specified)
484 # \param delimiter New delimiter between columns in the output file (if specified)
486 # Using set_params() requires that the specified logger was saved in a variable when created.
487 # i.e.
488 # \code
489 # logger = analyze.log(quantities=['pair_lj_energy',
490 # 'bond_harmonic_energy', 'kinetic_energy'],
491 # period=1000, filename="'full.log')
492 # \endcode
494 # \b Examples:
495 # \code
496 # logger.set_params(quantities=['bond_harmonic_energy'])
497 # logger.set_params(delimiter=',');
498 # logger.set_params(quantities=['bond_harmonic_energy'], delimiter=',');
499 # \endcode
500 def set_params(self, quantities=None, delimiter=None):
501 util.print_status_line();
503 if quantities is not None:
504 # set the logged quantities
505 quantity_list = hoomd.std_vector_string();
506 for item in quantities:
507 quantity_list.append(item);
508 self.cpp_analyzer.setLoggedQuantities(quantity_list);
510 if delimiter:
511 self.cpp_analyzer.setDelimiter(delimiter);
513 ## Retrieve a cached value of a monitored quantity from the last update of the logger.
514 # \param quantity Name of the quantity to return.
516 # Using query() requires that the specified logger was saved in a variable when created.
517 # i.e.
518 # \code
519 # logger = analyze.log(quantities=['pair_lj_energy',
520 # 'bond_harmonic_energy', 'kinetic_energy'],
521 # period=1000, filename="'full.log')
522 # \endcode
524 # \b Examples:
525 # \code
526 # logdata = logger.query('timestep')
527 # \endcode
528 def query(self, quantity):
529 # retrieve data from internal cache.
530 return self.cpp_analyzer.getCachedQuantity(quantity);
532 ## \internal
533 # \brief Re-registers all computes and updaters with the logger
534 def update_quantities(self):
535 # remove all registered quantities
536 self.cpp_analyzer.removeAll();
538 # re-register all computes and updater
539 globals.system.registerLogger(self.cpp_analyzer);
542 ## Calculates the mean-squared displacement of groups of particles and logs the values to a file
544 # analyze.msd can be given any number of groups of particles. Every \a period time steps, it calculates the mean squared
545 # displacement of each group (referenced to the particle positions at the time step the command is issued at) and prints
546 # the calculated values out to a file.
548 # The mean squared displacement (MSD) for each group is calculated as:
549 # \f[ \langle |\vec{r} - \vec{r}_0|^2 \rangle \f]
550 # and values are correspondingly written in units of distance squared.
552 # The file format is the same convenient delimited format used by analyze.log
554 # analyze.msd is capable of appending to an existing msd file (the default setting) for use in restarting in long jobs.
555 # To generate a correct msd that does not reset to 0 at the start of each run, save the initial state of the system
556 # in a hoomd_xml file, including position and image data at a minimum. In the continuation job, specify this file
557 # in the \a r0_file argument to analyze.msd.
559 # \MPI_SUPPORTED
560 class msd(_analyzer):
561 ## Initialize the msd calculator
563 # \param filename File to write the %data to
564 # \param groups List of groups to calculate the MSDs of
565 # \param period Quantities are logged every \a period time steps
566 # \param header_prefix (optional) Specify a string to print before the header
567 # \param r0_file hoomd_xml file specifying the positions (and images) to use for \f$ \vec{r}_0 \f$
568 # \param overwrite set to True to overwrite the file \a filename if it exists
570 # \b Examples:
571 # \code
572 # msd = analyze.msd(filename='msd.log', groups=[group1, group2],
573 # period=100)
575 # analyze.msd(groups=[group1, group2, group3], period=1000,
576 # filename='msd.log', header_prefix='#')
578 # analyze.msd(filename='msd.log', groups=[group1], period=10,
579 # header_prefix='Log of group1 msd, run 5\n')
580 # \endcode
582 # A group variable (\c groupN above) can be created by any number of group creation functions.
583 # See group for a list.
585 # By default, columns in the file are separated by tabs, suitable for importing as a
586 # tab-delimited spreadsheet. The delimiter can be changed to any string using set_params()
588 # The \a header_prefix can be used in a number of ways. It specifies a simple string that
589 # will be printed before the header line of the output file. One handy way to use this
590 # is to specify header_prefix='#' so that \c gnuplot will ignore the header line
591 # automatically. Another use-case would be to specify a descriptive line containing
592 # details of the current run. Examples of each of these cases are given above.
594 # If \a r0_file is left at the default of None, then the current state of the system at the execution of the
595 # analyze.msd command is used to initialize \f$ \vec{r}_0 \f$.
597 # \a period can be a function: see \ref variable_period_docs for details
598 def __init__(self, filename, groups, period, header_prefix='', r0_file=None, overwrite=False):
599 util.print_status_line();
601 # initialize base class
602 _analyzer.__init__(self);
604 # create the c++ mirror class
605 self.cpp_analyzer = hoomd.MSDAnalyzer(globals.system_definition, filename, header_prefix, overwrite);
606 self.setupAnalyzer(period);
608 # it is an error to specify no groups
609 if len(groups) == 0:
610 globals.msg.error('At least one group must be specified to analyze.msd\n');
611 raise RuntimeError('Error creating analyzer');
613 # set the group columns
614 for cur_group in groups:
615 self.cpp_analyzer.addColumn(cur_group.cpp_group, cur_group.name);
617 if r0_file is not None:
618 self.cpp_analyzer.setR0(r0_file);
620 ## Change the parameters of the msd analysis
622 # \param delimiter New delimiter between columns in the output file (if specified)
624 # Using set_params() requires that the specified msd was saved in a variable when created.
625 # i.e.
626 # \code
627 # msd = analyze.msd(filename='msd.log', groups=[group1, group2], period=100)
628 # \endcode
630 # \b Examples:
631 # \code
632 # msd.set_params(delimiter=',');
633 # \endcode
634 def set_params(self, delimiter=None):
635 util.print_status_line();
637 if delimiter:
638 self.cpp_analyzer.setDelimiter(delimiter);