<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Example Usage of HDFWriter
If properties of a class needs to be saved in a hdf file, then the class should inherit from HDFWriterMixin as demonstrated below.
hdf_properties (list) 
Step1:  You can now save properties using to_hdf method.
Parameters
file_path 
Step2:  You can now read hdf file using pd.HDFStore , or pd.read_hdf
Step3:  Saving nested class objects.
Just extend hdf_properties list to include that class object. <br>
Step4:  Modifed Usage
In BasePlasma class, the way properties of object are collected is different. It does not uses hdf_properties attribute.<br>
That`s why , PlasmaWriterMixin (which extends HDFWriterMixin) changes how the properties of BasePlasma class will be collected, by changing get_properties function.<br>
Here is a quick demonstration, if behaviour of default get_properties function inside HDFWriterMixin needs to be changed, by subclassing it to create a new Mixin.
Step5:  A demo class , using this modified mixin.
<ASSISTANT_TASK:>
Python Code:
from tardis.io.util import HDFWriterMixin
class ExampleClass(HDFWriterMixin):
    hdf_properties = ['property1', 'property2']
    hdf_name = 'mock_setup'
    def __init__(self, property1, property2):
        self.property1 = property1
        self.property2 = property2
        
import numpy as np
import pandas as pd
#Instantiating Object
property1 = np.array([4.0e14, 2, 2e14, 27.5])
property2 = pd.DataFrame({'one': pd.Series([1., 2., 3.], index=['a', 'b', 'c']),
                        'two': pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])})
obj = ExampleClass(property1, property2)
Explanation: Example Usage of HDFWriter
If properties of a class needs to be saved in a hdf file, then the class should inherit from HDFWriterMixin as demonstrated below.
hdf_properties (list) : Contains names of all the properties that needs to be saved.<br>
hdf_name (str) : Specifies the default name of the group under which the properties will be saved.
End of explanation
obj.to_hdf(file_path='test.hdf', path='test')
#obj.to_hdf(file_path='test.hdf', path='test', name='hdf')
Explanation: You can now save properties using to_hdf method.
Parameters
file_path : Path where the HDF file will be saved<br>
path : Path inside the HDF store to store the elements<br>
name : Name of the group inside HDF store, under which properties will be saved.<br>
If not specified , then it uses the value specified in hdf_name attribute.<br>
If hdf_name is also not defined , then it converts the Class name into Snake Case, and uses this value.<br>
Like for example , if name is not passed as an argument , and hdf_name is also not defined for ExampleClass above, then , it will save properties under example_class group.
End of explanation
#Read HDF file
with pd.HDFStore('test.hdf','r') as data:
    print data
    #print data['/test/mock_setup/property1']
Explanation: You can now read hdf file using pd.HDFStore , or pd.read_hdf
End of explanation
class NestedExampleClass(HDFWriterMixin):
    hdf_properties = ['property1', 'nested_object']
    def __init__(self, property1, nested_obj):
        self.property1 = property1
        self.nested_object = nested_obj
obj2 = NestedExampleClass(property1, obj)
obj2.to_hdf(file_path='nested_test.hdf')
#Read HDF file
with pd.HDFStore('nested_test.hdf','r') as data:
    print data
Explanation: Saving nested class objects.
Just extend hdf_properties list to include that class object. <br>
End of explanation
class ModifiedWriterMixin(HDFWriterMixin):
    def get_properties(self):
        #Change behaviour here, how properties will be collected from Class
        data = {name: getattr(self, name) for name in self.outputs}
        return data
Explanation: Modifed Usage
In BasePlasma class, the way properties of object are collected is different. It does not uses hdf_properties attribute.<br>
That`s why , PlasmaWriterMixin (which extends HDFWriterMixin) changes how the properties of BasePlasma class will be collected, by changing get_properties function.<br>
Here is a quick demonstration, if behaviour of default get_properties function inside HDFWriterMixin needs to be changed, by subclassing it to create a new Mixin.
End of explanation
class DemoClass(ModifiedWriterMixin):
    outputs = ['property1']
    hdf_name = 'demo'
    def __init__(self, property1):
        self.property1 = property1
obj3 = DemoClass('random_string')
obj3.to_hdf('demo_class.hdf')
with pd.HDFStore('demo_class.hdf','r') as data:
    print data
Explanation: A demo class , using this modified mixin.
End of explanation
<END_TASK>