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