<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 PyEmma Featurizer Support
Step1:  Import a PyEmma Coordinates Module
Using of pyemma featurizers or general other complex code requires a little trick to be storable. Since storing of code only works if we are not dependend on the context (scope) we need to wrap the construction of our featurizer in a function, that gets all it needs from the global scope as a parameter
Step2:  Now use this featurizer generating function to build a collective variable out of it. All we need for that is a name as usual, the generating function, the list of parameters - here only the topology and at best a test snapshot, a template.
Step3:  Let's save it to the storage
Step4:  and apply the featurizer to a trajectory
Step5:  Sync to make sure the cache is written to the netCDF file.
Step6:  Make sure that we get the same result
<ASSISTANT_TASK:>
Python Code:
from __future__ import print_function
import openpathsampling as paths
import numpy as np
# NBVAL_IGNORE_OUTPUT
import pyemma.coordinates as coor
# NBVAL_IGNORE_OUTPUT
ref_storage = paths.Storage('engine_store_test.nc', mode='r')
# NBVAL_IGNORE_OUTPUT
storage = paths.Storage('delete.nc', 'w')
storage.trajectories.save(ref_storage.trajectories[0])
Explanation: PyEmma Featurizer Support
End of explanation
# NBVAL_IGNORE_OUTPUT
def pyemma_generator(f):
    f.add_inverse_distances(f.pairs(f.select_Backbone()))
# NBVAL_IGNORE_OUTPUT
cv = paths.collectivevariable.PyEMMAFeaturizerCV(
    'pyemma', 
    pyemma_generator, 
    topology=ref_storage.snapshots[0].topology
).with_diskcache()
Explanation: Import a PyEmma Coordinates Module
Using of pyemma featurizers or general other complex code requires a little trick to be storable. Since storing of code only works if we are not dependend on the context (scope) we need to wrap the construction of our featurizer in a function, that gets all it needs from the global scope as a parameter
End of explanation
cv(ref_storage.trajectories[0]);
Explanation: Now use this featurizer generating function to build a collective variable out of it. All we need for that is a name as usual, the generating function, the list of parameters - here only the topology and at best a test snapshot, a template.
End of explanation
# NBVAL_IGNORE_OUTPUT
print(storage.save(cv))
Explanation: Let's save it to the storage
End of explanation
# NBVAL_IGNORE_OUTPUT
cv(storage.trajectories[0]);
Explanation: and apply the featurizer to a trajectory
End of explanation
# NBVAL_IGNORE_OUTPUT
cv(storage.snapshots.all());
# NBVAL_IGNORE_OUTPUT
py_cv = storage.cvs['pyemma']
store = storage.stores['cv%d' % storage.idx(py_cv)]
nc_var = store.variables['value']
assert(nc_var.shape[1] == 15)
print(nc_var.shape[1])
assert(nc_var.var_type == 'numpy.float32')
print(nc_var.var_type)
# NBVAL_IGNORE_OUTPUT
print(storage.variables['attributes_json'][:])
# NBVAL_IGNORE_OUTPUT
py_cv_idx = storage.idx(py_cv)
print(py_cv_idx)
py_emma_feat = storage.vars['attributes_json'][py_cv_idx]
# NBVAL_IGNORE_OUTPUT
erg = py_emma_feat(storage.snapshots);
# NBVAL_IGNORE_OUTPUT
print(erg[:,2:4])
storage.close()
ref_storage.close()
# NBVAL_IGNORE_OUTPUT
storage = paths.Storage('delete.nc', 'r')
cv = storage.cvs[0]
Explanation: Sync to make sure the cache is written to the netCDF file.
End of explanation
assert np.allclose(erg, cv(storage.snapshots))
storage.close()
Explanation: Make sure that we get the same result
End of explanation
<END_TASK>