summaryrefslogtreecommitdiff
path: root/cad/plugins/HDF5_SimResults/src/Documentation/index.txt
blob: 94de0d5d2dd93b6a691be59aea3af8d2248f52b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*! \mainpage

\section introduction Introduction
HDF5_SimResults is an HDF5 implementation of the SimResultsDataStore API. A SimResultsDataStore stores all the data associated with a molecular simulation.

See discussion of the SimResultsDataStore requirements and HDF5 implementation here: <a href="http://www.nanoengineer-1.net/mediawiki/index.php?title=NH1/NE1_Integration#Simulation_Results">NH1/NE1 Integration: Simulation Results</a>

The code is provided under the GNU GPL license.

Direct any questions or comments to helfrich at nanorex.com.

\section installation Installation
\subsection requirements Requirements
The HDF5 library is needed to build HDF5_SimResults library, specifically, HDF5-1.6.5. Get it here: <a href="http://hdf.ncsa.uiuc.edu/HDF5/release/obtain5.html">HDF5 Software</a>

<b>Note: Building HDF5 with MinGW</b>
Necessary for Dev-C++ users:
\li Remove tools/ and test/ directories from SUBDIRS in Makefile.in
\li Remove H5FDstream.* from src/Makefile.in
\li ./configure --disable-stream-vfd; make; make install
\li Download the "Binary Utilities" for Windows from the HDF5 Software page to get them.

Optionally, the CppUnit library is required to run the HDF5_SimResults unit tests, specifically, CppUnit-1.10.2. get it here: <a href="http://sourceforge.net/project/showfiles.php?group_id=11795&package_id=11019">CppUnit Software</a>.

\subsection building Building
Be sure to add the HDF5 (and optionally CppUnit) include/ and lib/ directories to your IDE as applicable.

\subsubsection dev-cpp Dev-C++
\li <tt>src/Dev-C++/HDF5_SimResults.dev</tt> builds <tt>src/Dev-C++/libHDF5_SimResults.a</tt>.
\li <tt>src/Dev-C++/CppUnit.dev</tt> builds <tt>src/Dev-C++/CppUnit.exe</tt>. 
\subsubsection ms-vcpp VC++
\li <tt>src/VC++/HDF5_SimResults.dsw</tt> builds <tt>src/VC++/Debug|Release/HDF5_SimResults.lib</tt>

\subsubsection xcode Xcode
\li <tt>src/Xcode/HDF5_SimResults.xcodeproj</tt> builds <tt>src/Xcode/build/Release/libHDF5_SimResults.a</tt> and <tt>src/Xcode/build/Release/CppUnit</tt>

\section notes Notes
\li When linking the HDF5_SimResults library with your own code, put the -lhdf5 \b after the -lHDF5_SimResults
\li The CppUnit(.exe) binary needs to be run from the src/ directory.

\section examples Examples
In the examples/ directory are three example datastores containing the trajectories for DNA structures undergoing energy minimization. Their exact structure can be inspected with the h5dump program (included with HDF5.)

The example datastores can also be played with bin/HK_Simulation.exe:
\li Run the HK_Simulation.exe program
\li Choose File | Open simulation...
\li From the "To play simulation results" section of the Open Simulation dialog, click the Browse button and choose one of the em/ directories under one of the example directories
\li Click the play icon in the Visualization section of the HK_Simulation program

The following is the function from the HK_Simulation sourcecode that populates the data structures used to draw each frame with data from the HDF5_SimResults datastore.

\code
/* FUNCTION: render */
wxUint32 VisualizationCanvas::render(ne1::HDF5_SimResults* hdf5_SimResults,
                                     const wxUint32& frameIndex,
                                     bool justFrameCount) {
    int status, frameCount;
    std::string message;

    hdf5_SimResults->synchronize();

    // Setup atom arrays (once), assumes the number of atoms in the system is
    // constant.
    static bool InitializeAtoms = true;
    if (InitializeAtoms) {
        hdf5_SimResults->getFrameAtomIdsCount("frame-set-1", atomIdCount);
        if (atomIdCount > 0) {
            xCoords = (float*)malloc(atomIdCount*sizeof(float));
            yCoords = (float*)malloc(atomIdCount*sizeof(float));
            zCoords = (float*)malloc(atomIdCount*sizeof(float));
            atomicNumbers = (int*)malloc(atomIdCount*sizeof(int));
            InitializeAtoms = false;
        }
    }

    // Check bond counts and memory allocation.
    // Note: The zero in the following makes assumptions that need to be
    // generalized later. Plus, this assumes that bonds never change.
    static bool InitializeBonds = true;
    if (InitializeBonds) {
        hdf5_SimResults->getFrameBondsCount("frame-set-1", 0, bondIdCount);
        if (bondIdCount > 0) {
            aIds = (int*)malloc(bondIdCount*sizeof(int));
            bIds = (int*)malloc(bondIdCount*sizeof(int));
            InitializeBonds = false;
        }
    }

    // Get time dimension count
    hdf5_SimResults->getFrameCount("frame-set-1", frameCount);
    if ((frameIndex < frameCount) && !justFrameCount) {

        // Atoms
        //
        float* positions = (float*)malloc(atomIdCount*3*sizeof(float));
        status =
            hdf5_SimResults->getFrameAtomPositions("frame-set-1",
                                                   frameIndex, atomIdCount,
                                                   positions, message);

        // Collect the atom positions. Center the molecule and assign atomic
        // numbers the first time it is displayed.
        static bool InitializeMolecule = true;
        static float xShift = 0.0, yShift = 0.0, zShift = 0.0;
        float maxX, minX, maxY, minY, maxZ, minZ;
        for (wxUint32 atomIdIndex = 0;
             atomIdIndex < atomIdCount;
             atomIdIndex++) {
            xCoords[atomIdIndex] = positions[atomIdIndex*3 + 0] * 10 + xShift;
            yCoords[atomIdIndex] = positions[atomIdIndex*3 + 1] * 10 + yShift;
            zCoords[atomIdIndex] = positions[atomIdIndex*3 + 2] * 10 + zShift;
            if (InitializeMolecule) {
                if (atomIdIndex == 0) {
                    maxX = minX = xCoords[atomIdIndex];
                    maxY = minY = yCoords[atomIdIndex];
                    maxZ = minZ = zCoords[atomIdIndex];

                } else {
                    if (xCoords[atomIdIndex] > maxX)
                        maxX = xCoords[atomIdIndex];
                    else if (xCoords[atomIdIndex] < minX)
                        minX = xCoords[atomIdIndex];
                    if (yCoords[atomIdIndex] > maxY)
                        maxY = yCoords[atomIdIndex];
                    else if (yCoords[atomIdIndex] < minY)
                        minY = yCoords[atomIdIndex];
                    if (zCoords[atomIdIndex] > maxZ)
                        maxZ = zCoords[atomIdIndex];
                    else if (zCoords[atomIdIndex] < minZ)
                        minZ = zCoords[atomIdIndex];
                }
            }
        }
        free(positions);
        if (InitializeMolecule) {
            xShift = (minX + maxX) / -2.0;
            yShift = (minY + maxY) / -2.0;
            zShift = (minZ + maxZ) / -2.0;

            // Determine initial zoom
            float maxVector = maxX - minX;
            if (maxY - minY > maxVector) maxVector = maxY - minY;
            if (maxZ - minZ > maxVector) maxVector = maxZ - minZ;
            zoom = maxVector * -1.28;

            unsigned int* _atomicNumbers =
                (unsigned int*)malloc(atomIdCount*3*sizeof(unsigned int));
            status =
                hdf5_SimResults->getFrameAtomicNumbers("frame-set-1",
                                                       _atomicNumbers, message);
            for (wxUint32 atomIdIndex = 0;
                 atomIdIndex < atomIdCount;
                 atomIdIndex++) {
                xCoords[atomIdIndex] += xShift;
                yCoords[atomIdIndex] += yShift;
                zCoords[atomIdIndex] += zShift;
                atomicNumbers[atomIdIndex] = _atomicNumbers[atomIdIndex];
            }
            free(_atomicNumbers);
            InitializeMolecule = false;
        }

        // Bonds
        //
        static bool InitializeBonds2 = true;
        if (InitializeBonds2) {
            ne1::SimResultsBond* bonds =
                (ne1::SimResultsBond*)malloc
                    (bondIdCount*sizeof(ne1::SimResultsBond));
            status =
                hdf5_SimResults->getFrameBonds("frame-set-1", 0,
                                               bonds, message);
            for (wxUint32 bondIdIndex = 0;
                 bondIdIndex < bondIdCount;
                 bondIdIndex++) {
                aIds[bondIdIndex] = bonds[bondIdIndex].atomId_1;
                bIds[bondIdIndex] = bonds[bondIdIndex].atomId_2;
            }
            free(bonds);
            InitializeBonds2 = false;
        }

        // Redraw scene
        Refresh(FALSE);
    }
    return frameCount;
}
\endcode

 */