<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Tips & Trics for anypytools
Stopping and restarting simulations
AnyPyProcess caches the simulation results. This allows us to stop the simulations, and then later restart them again.
Step1:  Here we stopped the simulation using the Notebook interrupt button. Calling the start_macro() function again continues the processing and re-run any task that wasn't completed in the first run and any task that exited with errors.
Step2:  Note
Step3:  But the information is there
Step4:  We can also see all task information by evaluating the result object as standard Python dictionary
Step5:  Saving output to re-process at a later time
The extra task meta info gives other posibilities. The results from running batch processing (i.e. output f start_macro() can be used as input to restart the same processing even if the AnyPyProcess have no cached results.
Step6:  The effect is that the result of an analysis can be saved to files and later restarted.  The next example illustrates this.
Example
Step7:  All this stored data can be be reloaded
<ASSISTANT_TASK:>
Python Code:
from anypytools import AnyPyProcess 
app = AnyPyProcess(num_processes=1)
macro = [
    'load "Knee.any"', 
    'operation Main.MyStudy.InverseDynamics',
    'run',
]
macrolist = [macro]*20
app.start_macro(macrolist); 
Explanation: Tips & Trics for anypytools
Stopping and restarting simulations
AnyPyProcess caches the simulation results. This allows us to stop the simulations, and then later restart them again.
End of explanation
app.start_macro(macrolist);
Explanation: Here we stopped the simulation using the Notebook interrupt button. Calling the start_macro() function again continues the processing and re-run any task that wasn't completed in the first run and any task that exited with errors.
End of explanation
from anypytools import AnyPyProcess
from anypytools.macro_commands import Load, OperationRun, Dump
app = AnyPyProcess()
macro = [
    Load('Knee.any', defs={'N_STEP':10}), 
    OperationRun('Main.MyStudy.InverseDynamics'),
    Dump('Main.MyStudy.Output.MaxMuscleActivity'),
]
result = app.start_macro(macro)[0]
result
Explanation: Note: That changing the input arguments start_macro or re-instanciating the app object will erase the cache and re-run all processes. 
Including meta-information in the output
The start_macro() also returns extra meta info, but the information is not printed by the default __repr__() function.
End of explanation
result["task_macro"]
Explanation: But the information is there
End of explanation
dict(result)
Explanation: We can also see all task information by evaluating the result object as standard Python dictionary:
End of explanation
from anypytools import AnyPyProcess 
app = AnyPyProcess()
macro = [
    Load('Knee.any', defs={'N_STEP':10}), 
    OperationRun('Main.MyStudy.InverseDynamics'),
    Dump('Main.MyStudy.Output.MaxMuscleActivity'),
]
output = app.start_macro(macro) 
app = AnyPyProcess()
app.start_macro(output)
Explanation: Saving output to re-process at a later time
The extra task meta info gives other posibilities. The results from running batch processing (i.e. output f start_macro() can be used as input to restart the same processing even if the AnyPyProcess have no cached results.
End of explanation
import os
from scipy.stats import distributions
from anypytools import AnyPyProcess, AnyMacro
from anypytools.macro_commands import Load, SetValue_random, OperationRun, Dump
tibia_knee_srel = distributions.norm([0, 0.18, 0], [0.005, 0.005, 0.005] ) 
femur_knee_srel = distributions.norm([0, -0.3, 0], [0.005, 0.005, 0.005] ) 
app = AnyPyProcess(silent=True)
mg = AnyMacro(number_of_macros = 500)
mg.extend([
    Load('knee.any', defs = {'N_STEP':20}),
    SetValue_random('Main.MyModel.Tibia.Knee.sRel', tibia_knee_srel),
    SetValue_random('Main.MyModel.Femur.Knee.sRel', femur_knee_srel),
    OperationRun('Main.MyStudy.InverseDynamics'),
    Dump('Main.MyStudy.Output.MaxMuscleActivity'),
])
try:
    os.remove('data.db')
except OSError:
    pass
for macros in mg.create_macros_MonteCarlo(batch_size=50):
    app.start_macro(macros)
    app.save_results('data.db', append=True)
    print('Data saved')
print('Done')
Explanation: The effect is that the result of an analysis can be saved to files and later restarted.  The next example illustrates this.
Example: Saving data to disk while running
End of explanation
reloaded_results = app.load_results('data.db')
print('Entries in file: {}'.format(len(reloaded_results)))
reloaded_results[456:457]
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(reloaded_results['MaxMuscleAct'].T, 'b', lw=0.2, alpha = 0.3);
Explanation: All this stored data can be be reloaded
End of explanation
<END_TASK>