1 /* -------------------------------------------------------------------------- *
2  *                         OpenSim:  STOFileAdapter.cpp                       *
3  * -------------------------------------------------------------------------- *
4  * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
5  * OpenSim is developed at Stanford University and supported by the US        *
6  * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
7  * through the Warrior Web program.                                           *
8  *                                                                            *
9  * Copyright (c) 2005-2018 Stanford University and the Authors                *
10  *                                                                            *
11  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
12  * not use this file except in compliance with the License. You may obtain a  *
13  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
14  *                                                                            *
15  * Unless required by applicable law or agreed to in writing, software        *
16  * distributed under the License is distributed on an "AS IS" BASIS,          *
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
18  * See the License for the specific language governing permissions and        *
19  * limitations under the License.                                             *
20  * -------------------------------------------------------------------------- */
21 
22 #include "STOFileAdapter.h"
23 
24 namespace OpenSim {
25 
26 std::shared_ptr<DataAdapter>
createSTOFileAdapterForReading(const std::string & fileName)27 createSTOFileAdapterForReading(const std::string& fileName) {
28     std::ifstream file{fileName};
29 
30     std::regex keyvalue{R"((.*)=(.*))"};
31     std::string line{};
32     while(std::getline(file, line)) {
33         if(line.find("endheader") != std::string::npos)
34             break;
35 
36         std::smatch matchRes{};
37         if(std::regex_match(line, matchRes, keyvalue)) {
38             auto key = matchRes[1].str();
39             auto value = matchRes[2].str();
40             if(!key.empty() &&
41                !value.empty() &&
42                key.find("DataType") != std::string::npos) {
43                 using namespace SimTK;
44 
45                 if(value == "double")
46                     return std::make_shared<STOFileAdapter_<double>>();
47                 else if(value == "Vec2")
48                     return std::make_shared<STOFileAdapter_<Vec2>>();
49                 else if(value == "Vec3")
50                     return std::make_shared<STOFileAdapter_<Vec3>>();
51                 else if(value == "Vec4")
52                     return std::make_shared<STOFileAdapter_<Vec4>>();
53                 else if(value == "Vec5")
54                     return std::make_shared<STOFileAdapter_<Vec5>>();
55                 else if(value == "Vec6")
56                     return std::make_shared<STOFileAdapter_<Vec6>>();
57                 else if(value == "Vec7")
58                     return std::make_shared<STOFileAdapter_<Vec7>>();
59                 else if(value == "Vec8")
60                     return std::make_shared<STOFileAdapter_<Vec8>>();
61                 else if(value == "Vec9")
62                     return std::make_shared<STOFileAdapter_<Vec9>>();
63                 else if(value == "Vec10")
64                     return std::make_shared<STOFileAdapter_<Vec<10>>>();
65                 else if(value == "Vec11")
66                     return std::make_shared<STOFileAdapter_<Vec<11>>>();
67                 else if(value == "Vec12")
68                     return std::make_shared<STOFileAdapter_<Vec<12>>>();
69                 else if(value == "UnitVec3")
70                     return std::make_shared<STOFileAdapter_<UnitVec3>>();
71                 else if(value == "Quaternion")
72                     return std::make_shared<STOFileAdapter_<Quaternion>>();
73                 else if(value == "SpatialVec")
74                     return std::make_shared<STOFileAdapter_<SpatialVec>>();
75                 else {
76                     OPENSIM_THROW(STODataTypeNotSupported,
77                                   value);
78                 }
79             }
80         }
81     }
82     // The file does not seem to have a DataType field, and is therefore likely
83     // a version 1.0 STO file. These files only supported double as the column
84     // data type; try to read the file with type double.
85     return std::make_shared<STOFileAdapter_<double>>();
86 }
87 
88 template <typename T>
89 std::shared_ptr<STOFileAdapter_<T>>
makeAdapter(const AbstractDataTable * absTable)90 makeAdapter(const AbstractDataTable* absTable) {
91     if (auto table = dynamic_cast<const TimeSeriesTable_<T>*>(absTable)) {
92         return std::make_shared<STOFileAdapter_<T>>();
93     }
94     return {};
95 }
96 
97 std::shared_ptr<DataAdapter>
createSTOFileAdapterForWriting(const DataAdapter::InputTables & absTables)98 createSTOFileAdapterForWriting(const DataAdapter::InputTables& absTables) {
99     using namespace SimTK;
100 
101     auto* absTable = absTables.at("table");
102 
103     // Try derived class before base class.
104 
105     if (auto adapter = makeAdapter<UnitVec3>(absTable)) return adapter;
106     if (auto adapter = makeAdapter<Quaternion>(absTable)) return adapter;
107     if (auto adapter = makeAdapter<SpatialVec>(absTable)) return adapter;
108     if (auto adapter = makeAdapter<double>(absTable)) return adapter;
109     if (auto adapter = makeAdapter<Vec2>(absTable)) return adapter;
110     if (auto adapter = makeAdapter<Vec3>(absTable)) return adapter;
111     if (auto adapter = makeAdapter<Vec4>(absTable)) return adapter;
112     if (auto adapter = makeAdapter<Vec5>(absTable)) return adapter;
113     if (auto adapter = makeAdapter<Vec6>(absTable)) return adapter;
114     if (auto adapter = makeAdapter<Vec7>(absTable)) return adapter;
115     if (auto adapter = makeAdapter<Vec8>(absTable)) return adapter;
116     if (auto adapter = makeAdapter<Vec9>(absTable)) return adapter;
117     if (auto adapter = makeAdapter<Vec<10>>(absTable)) return adapter;
118     if (auto adapter = makeAdapter<Vec<11>>(absTable)) return adapter;
119     if (auto adapter = makeAdapter<Vec<12>>(absTable)) return adapter;
120 
121     OPENSIM_THROW(STODataTypeNotSupported,
122                   "<unknown>");
123 }
124 
125 } // namespace OpenSim
126