Giter VIP home page Giter VIP logo

opensim-org / opensim-core Goto Github PK

View Code? Open in Web Editor NEW
739.0 59.0 305.0 212.51 MB

SimTK OpenSim C++ libraries and command-line applications, and Java/Python wrapping.

Home Page: https://opensim.stanford.edu

License: Apache License 2.0

CMake 1.67% C++ 78.34% C 13.39% MATLAB 3.25% Python 1.82% Yacc 0.10% Java 0.46% Shell 0.08% SWIG 0.84% HTML 0.01% PowerShell 0.02% Dockerfile 0.03%
science simulation biological-simulations biomechanics engineering computational-science computational-biology musculoskeletal-models

opensim-core's People

Contributors

adamkewley avatar albertocasasortiz avatar antoinefalisse avatar aymanhab avatar camilletownshend avatar carmichaelong avatar cassidykelly avatar chrisdembia avatar clnsmith avatar fcanderson avatar frabjous5 avatar jenhicks avatar jimmydunne avatar jmwang avatar keenon avatar kevunix avatar klshrinidhi avatar mjhmilla avatar mrrezaie avatar msdemers avatar nickbianco avatar nicos1993 avatar pariterre avatar pepbos avatar reinbolt avatar sherm1 avatar sohapouya avatar stavness avatar tkuchida avatar twdorn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opensim-core's Issues

MultibodyGraphMaker output is dumped to cout

In Model.cpp, the Model::connectToModel() method is currently dumping the (voluminous) output from the MultibodyGraphMaker to cout. This makes it hard to look through test output, for example.

This is probably not a good thing to leave in permanently, although it may be needed at the moment. I'm filing this issue so we won't forget to remove it, or make it optional or whatever is appropriate. I'll just comment it out in my build for now.

extraneous declarations in header

Component.h contains these 2 lines

using std::cout;
using std::endl;

Removing these 2 lines doesn't affect anything downstream and the code compiles without errors (on windows) please indicate whether this's dead code that can be safely removed.

Fix bug in java and python wrapping CMake files.

Fix an issue we had to fix in the OpenSim 3.2 source dist. Basically, don't use a glob to obtain files that are generated by other targets. This would be fixed via changes like the following:

-FILE(GLOB SOURCE_FILES OpenSimContext.cpp ${CMAKE_CURRENT_BINARY_DIR}/*.cxx)
 -FILE(GLOB INCLUDE_FILES ${CMAKE_CURRENT_BINARY_DIR}/*.h OpenSimContext.h)
 +SET(SOURCE_FILES OpenSimContext.cpp "${swig_output_cxx_file_fullname}")
 +SET(INCLUDE_FILES OpenSimContext.h "${swig_output_header_file_fullname}")

Make bind to lambda function in testComponentInterface conditional on C++11 use

Outputs can bind to any function including lambda functions and this is verified in testComponentInterface. Lambda functions are not defined in VS2010, although several C++11 features (like unique_ptr) are available. If we want to support VS2010 we can conditionally exclude the Output that is bound to the lambda function case.

Doxygen errors

I just built my shiny new GitHub version of opensim-core. Then I built doxygen (on Windows, using doxygen 1.8.7). Doxygen ran but had several groups of complaints, attached below. These should be fixed so that doxygen runs without errors.

OpenSim/Common/Property_Deprecated.h:70: warning: Found unknown command `\tbool'
OpenSim/Common/Property_Deprecated.h:72: warning: Found unknown command `\tint'
(and a bunch more like that)

and

OpenSim/Common/PolynomialFunction.h:83: warning: argument 'Vector' of command @param is not found in the argument list of OpenSim::PolynomialFunction::setCoefficients(SimTK::Vector coefficients)
OpenSim/Common/PolynomialFunction.h:83: warning: The following parameters of OpenSim::PolynomialFunction::setCoefficients(SimTK::Vector coefficients) are not documented:
2>    parameter 'coefficients'
OpenSim/Common/SmoothSegmentedFunction.h:410: warning: The following parameters of OpenSim::SmoothSegmentedFunction::printMatrixToFile(SimTK::Matrix &data, SimTK::Array_< std::string > &colnames, const std::string &path, const std::string &filename) const are not documented:
2>    parameter 'colnames'
OpenSim/Analyses/StaticOptimizationTarget.h:56: warning: End of list marker found without any preceding list items

and

OpenSim/Common/Component.h:399: warning: argument 'state' of command @param is not found in the argument list of OpenSim::Component::getOutput(const std::string &name) const
OpenSim/Common/ComponentOutput.h:110: warning: argument 'outputMethod' of command @param is not found in the argument list of OpenSim::Output< T >::Output(const std::string &name, const std::function< T(const SimTK::State &)> outputFunction, const SimTK::Stage &dependsOnStage)
OpenSim/Common/ComponentOutput.h:110: warning: The following parameters of OpenSim::Output::Output(const std::string &name, const std::function< T(const SimTK::State &)> outputFunction, const SimTK::Stage &dependsOnStage) are not documented:
2>    parameter 'name'
2>    parameter 'outputFunction'
2>  C:/Users/Sherm/Documents/GitHub/opensim-org/opensim-core/OpenSim/Common/PolynomialFunction.h:83: warning: argument 'Vector' of command @param is not found in the argument list of OpenSim::PolynomialFunction::setCoefficients(SimTK::Vector coefficients)
OpenSim/Common/PolynomialFunction.h:83: warning: The following parameters of OpenSim::PolynomialFunction::setCoefficients(SimTK::Vector coefficients) are not documented:
2>    parameter 'coefficients'
2>  C:/Users/Sherm/Documents/GitHub/opensim-org/opensim-core/OpenSim/Common/Component.h:399: warning: argument 'state' of command @param is not found in the argument list of OpenSim::Component::getOutput(const std::string &name) const
2>  C:/Users/Sherm/Documents/GitHub/opensim-org/opensim-core/OpenSim/Common/ComponentOutput.h:110: warning: argument 'outputMethod' of command @param is not found in the argument list of OpenSim::Output< T >::Output(const std::string &name, const std::function< T(const SimTK::State &)> outputFunction, const SimTK::Stage &dependsOnStage)
OpenSim/Common/ComponentOutput.h:110: warning: The following parameters of OpenSim::Output::Output(const std::string &name, const std::function< T(const SimTK::State &)> outputFunction, const SimTK::Stage &dependsOnStage) are not documented:
2>    parameter 'name'
2>    parameter 'outputFunction'

Build failure on C++ 2010 Express

According to the [WIP] Building OpenSim from Source page on Confluence, VS 2013 isn't supported. I downloaded and installed C++ 2010 Express, built/installed Simbody, and tried building OpenSim in Release mode. Output below.

Travis seems pleased, so I assume I've done something wrong. Commencing digging.

4>c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(28): error C2903: 'result' : symbol is neither a class template nor a function template
4>          c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(40) : see reference to class template instantiation 'std::tr1::_Result_type1<__formal,_Fty,_Arg0>' being compiled
4>          with
4>          [
4>              __formal=false,
4>              _Fty=`anonymous-namespace'::,
4>              _Arg0=std::tr1::_Nil &
4>          ]
4>          c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(597) : see reference to class template instantiation 'std::tr1::_Result_of1<_Fty,_Farg0>' being compiled
4>          with
4>          [
4>              _Fty=`anonymous-namespace'::,
4>              _Farg0=std::tr1::_Nil &
4>          ]
4>          c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xrefwrap(28) : see reference to class template instantiation 'std::tr1::_Result_of<_Ty>' being compiled
4>          with
4>          [
4>              _Ty=`anonymous-namespace':: (std::tr1::_Nil &)
4>          ]
4>          c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxbind1(273) : see reference to class template instantiation 'std::tr1::result_of<_Fty>' being compiled
4>          with
4>          [
4>              _Fty=`anonymous-namespace':: (std::tr1::_Nil &)
4>          ]
4>          c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxbind0(10) : see reference to class template instantiation 'std::tr1::_Bind1<_Callable,_Arg0>::_Return<_Barg0,_Barg1,_Barg2,_Barg3,_Barg4,_Barg5,_Barg6,_Barg7,_Barg8,_Barg9>' being compiled
4>          with
4>          [
4>              _Callable=std::tr1::_Callable_obj<`anonymous-namespace'::,false>,
4>              _Arg0=std::tr1::_Ph<1>,
4>              _Barg0=std::tr1::_Nil &,
4>              _Barg1=std::tr1::_Nil &,
4>              _Barg2=std::tr1::_Nil &,
4>              _Barg3=std::tr1::_Nil &,
4>              _Barg4=std::tr1::_Nil &,
4>              _Barg5=std::tr1::_Nil &,
4>              _Barg6=std::tr1::_Nil &,
4>              _Barg7=std::tr1::_Nil &,
4>              _Barg8=std::tr1::_Nil &,
4>              _Barg9=std::tr1::_Nil &
4>          ]
4>          c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\functional(408) : see reference to class template instantiation 'std::tr1::_Bind_base<_Ret,_BindN>' being compiled
4>          with
4>          [
4>              _Ret=std::tr1::_Notforced,
4>              _BindN=std::tr1::_Bind1,false>,std::tr1::_Ph<1>>
4>          ]
4>          ..\..\..\..\OpenSim\Common\Test\testComponentInterface.cpp(207) : see reference to class template instantiation 'std::tr1::_Bind_fty<_Fty,_Ret,_BindN>' being compiled
4>          with
4>          [
4>              _Fty=`anonymous-namespace'::,
4>              _Ret=std::tr1::_Notforced,
4>              _BindN=std::tr1::_Bind1,false>,std::tr1::_Ph<1>>
4>          ]
4>c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(28): error C2039: 'result' : is not a member of '`anonymous-namespace'::'
4>          ..\..\..\..\OpenSim\Common\Test\testComponentInterface.cpp(207) : see declaration of '`anonymous-namespace'::'
4>c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(28): error C2143: syntax error : missing ';' before '<'
4>c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(28): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
4>c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(28): error C2039: 'type' : is not a member of '`global namespace''
4>c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(28): error C2238: unexpected token(s) preceding ';'
4>c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(40): error C2039: '_Type' : is not a member of 'std::tr1::_Result_type1<__formal,_Fty,_Arg0>'
4>          with
4>          [
4>              __formal=false,
4>              _Fty=`anonymous-namespace'::,
4>              _Arg0=std::tr1::_Nil &
4>          ]
4>c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(40): error C2146: syntax error : missing ';' before identifier '_Type'
4>c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(40): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
4>c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(40): error C2602: 'std::tr1::_Result_of1<_Fty,_Farg0>::_Type' is not a member of a base class of 'std::tr1::_Result_of1<_Fty,_Farg0>'
4>          with
4>          [
4>              _Fty=`anonymous-namespace'::,
4>              _Farg0=std::tr1::_Nil &
4>          ]
4>          c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(40) : see declaration of 'std::tr1::_Result_of1<_Fty,_Farg0>::_Type'
4>          with
4>          [
4>              _Fty=`anonymous-namespace'::,
4>              _Farg0=std::tr1::_Nil &
4>          ]
4>c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xxresult(40): error C2868: 'std::tr1::_Result_of1<_Fty,_Farg0>::_Type' : illegal syntax for using-declaration; expected qualified-name
4>          with
4>          [
4>              _Fty=`anonymous-namespace'::,
4>              _Farg0=std::tr1::_Nil &
4>          ]

Calling Super::computeStateVariableDerivatives

The doxygen for Component::computeStateVariableDerivatives says to call Super::computeStateVariableDerivatives in the derived implementations of computeStateVariableDerivatives. This makes sense for all components except those deriving directly from Component. In this special case, I am implementing the method but I still get the exception about deriving, since I am still calling Component's implementation.

Building on VisualStudio 2010 fails

testComponentInterface.cpp fails to compile because of lambda's not supported on VS 2010, need to either skip the problematic part on VS 2010 or find an alternative syntax that works there (pre c++11). That is if we decide to continue supporting pre c++11 compilers.

Component should generate outputs for any added state variable

Automatically generate an Output per state variable allocated by the component. Reporters in general should then talk to component Outputs to write results to file, etc...
This can be done by binding the Output to Component::StateVariable's getValue(). If the StateVariable is marked as hidden, an Output for that state variable's value should not be created.

The advantage of doing this is that once a consumer (e.g. a Reporter) has a handle on the Output, getting the state variable value requires no lookup, whereas asking a Component for a value of one of its state variables requires a name lookup to find the StateVariable and then a call to its getValue(). For a Model (with potentially hundreds of subcomponents) this can be costly and unnecessary overhead.

Create a Component Test Harness

An automatic Components test harness (especially ModelComponents) would catch the majority of user/developer problems with newly created Components blindly used (loaded as a plugin) in OpenSim. Would also be a more systematic way of testing and leveraging the Component interface. The test would go something like this:

  1. create instance of Component and randomly set properties according to their type
  2. clone component and check equality with 1. (this should find copying issues, like forgetting a copyProperty_<prop_name>() )
  3. serialize and then deserialize as another instance and check equality with 1. (this should catch issues with serialization/deserialization)
  4. Query its connectors and get required instance(s) from registered types, clone, set unique names, and then add these dependencies to an aggregate (component that these components should be a subcomponent of)
  5. Add the Component to the aggregate (e.g. if a ModelComponent add it a Model)
  6. Invoke connect on aggregate Component, and verfiy that the component connectors are satisfied and that connectees (object satisfy connector requirement) are the same as those addded in 4.
  7. Call buildSystem on aggregate (initSystem on Model)
  8. getValue() from each of the component's Outputs using state from 7. and verify that when realization stage < dependsOnStage that there is an exception thrown.
  9. Realize to dependsOnStage stage and getValue from Output (in hindsight it is probably not necessary to compare to value to that of the equivalen member function call, since we would already be verifying that the std::bind() worked and it which point it is the member function being invoked.
  10. Copy and delete the Component in a loop (100 or 1000x) and use testing utility size_t mem2 = getCurrentRSS( ) to compare memory footprint pre and post loop. An increase of more than 2% is an indication of a leak.
  11. Similarly repeat 10. but instead of copying and deleting just call initSystem() diffing state results with previous and verifying process memory does not grow significantly.

This is definitely not complete coverage but its a good first pass that the new component is a well behaved Component. @chrisdembia if we had 7-10 working for ModelComponents, that would be awesome for the hackathon. Could use a gait model (gait10dof18musc) to be the aggregate Component like you suggested.

  • Fix memory leak in joints.
  • Reduce compile time by making an auxiliaryTestFunctions.cpp
  • in testModelComponent, take in a list of the expected output names.
  • in testModelComponents, take in a list of expected property names.
  • Add test method to test non-Model Components.

Add message logging/handling service

OpenSim and its Component builders need a way to provide debug and other component messages in a systematic way. Users should be able to choose the level of messaging from non to the most fine Optimizer details. I propose that Component could maintain the messages with an assigned priority/verbosity level which the Component builder can specify using addMessage(string msg, level) like methods we have for Output, StateVariable, etc... One of the advantages of this approach is that it would make it easy to have selective verbosity- for example having only Muscles running with full verbosity to debug muscle related issues.

Create 'Delay' Component

Some topics for discussion:

  1. The dependsOnStage of an Operator shouldn't be "hard-coded" but should depend on the components it's wired up to.
  2. InputMeasure must be able to handle initialization when quantities depend on stages higher than Velocity. See Sherm's discussion in #356.
  3. I'm using SimTK Testing.h which gives exception messages like "Submit a bug report to simbody." That's not the message we want from an OpenSim test.
  4. The requiredAt stage for the input should be Time, even if delaying a state variable (which only depends on Model). Otherwise, the quantity won't be delayed. So the requiredAt stage should be max(Time, connected output's dependsOn stage).
  5. Should Delay hold onto a MeasureIndex or a Measure handle?
  6. Should InputMeasure be a Measure::Result? or just a plain Measure?
  7. Are the names "input" and "output" for Delay's "input" and "output" okay? This component is so generic that it's not possible to come up with a really meaningful name. Maybe they should be numbered for an Operator? getInput("0")?
  8. Not able to make Delay a property of another component, since this copies the Delay and inputs and outputs aren't copied yet.
  9. Commented out tests will fail until we fix: (1) copying, de/serialization (2) flexible stages for Delay's input/output.
  10. Must fix Coordinate's outputs first (remove outputs for state variables).
  11. Put InputMeasure in its own header?

TODO

Once copying of inputs and outputs works:

  • Test using a Delay as a property
  • Test de/serialization (this test already exist in testOperators; simply uncomment).
  • Test copying (this test already exist in testOperators; simply uncomment).
  • Allow "flow-through" dependsOn stage / requiredAt stage.
  • Test variety of stages for the outputs (this test already exist in testOperators; simply uncomment).

Does the method Component::getSystem() need to be public.

While trying to SWIG wrap the new class OpenSim::Component (needed since it's a base class for ModelCompoenent) I ran into the public method

/**
* Get the underlying MultibodySystem that this component is connected to.
*/
const SimTK::MultibodySystem& getSystem() const
{ return *_system; }

which wraps into an unusable method since SimTK::MultibodySystem is not SWIG wrapped either and so it is impossible to use in scripting.The main question is whether this method should actually be protected (and so will be removed from wrapping) or if the SimTK::MultibodySystem is used more across the API and will need to be wrapped for scripting purposes.

use of internal slave bodies leaking out in names of Joint connectors

When there is a kinematic loop, it is broken and a slave body is used to provide the user specified joint and the slave is then welded to the real master body. The use of internal slave bodies should be completely hidden but this is being violated when the model is serialized and the Joint's connector indicates the slave body.

Upgrade to lepton introduces warnings in VS2013

PR #19 introduced warnings in VS2013. @aseth1 said he sees warnings like:

warning C4267: '=' : conversion from 'size_t' to 'int', possible loss of data, e.g:
void ExpressionProgram::buildProgram(const ExpressionTreeNode& node) { for (int i = node.getChildren().size()-1; i >= 0; i--) ...}

I see two resolutions:

  1. Patch github.com/simtk/openmm to get rid of this warning @peatsman, do you build with VS2013? If so, do you see such warnings?
  2. Fix the warning ourselves in opensim. I think we'd do this by changing int i to size_t i. We might need to include stdint to get this to work on VS2010.

Looking for suggestions.

Create 'Mux/Demux' Component

Multiplexer/Demultiplexer to stack elements into Vectors (including Vector elements) and the converse: separate out channels for from a single Vector

Test Failures on Windows VS 2013 debug mode (x86)

Tests below fail, some due to speed/timeout in debug mode but others due to assertions correctly blowing up. Confirmed with Ajay
2> 13 - testAssemblySolver (Failed)
2> 15 - testForces (Failed)
2> 16 - testInitState (Timeout)
2> 17 - testMomentArms (Failed)
2> 27 - testExternalLoads (Failed)
2> 30 - testControllerExampleRuns (Failed)
2> 31 - testControllerExample (Failed)
2> 34 - testOptimizationExampleRuns (Timeout)
2> 35 - testOptimizationExample (Failed)
2> 42 - testWrapping (Timeout)
2> 43 - testAnalyzeTutorialOne (Timeout)
2> 51 - testCMC (Timeout)
2> 52 - testCMCWithControlConstraints (Failed)
2> 53 - testRRA (Failed)

testCMC's single muscle test depends on the single muscle rigid tendon tests

See #22. I tried splitting up the new testCMCSingleMuscle into testCMCSingleRigidTendonMuscle and testCMCSingleMuscle so that the rigid-tendon tests were in a separate test. In this case, the modified testCMCSingleMuscle (without the rigid-tendon tests) was failing. So it seems that the non-rigid-tendon tests require the rigid-tendon tests to run first in order for the non-rigid-tendon (single mucle) tests to pass. Is this the correct/expected behavior, or does this indicate a bug ๐Ÿ› ?

Make an OpenSimConfig.cmake

Simbody has a FindSimbody and now it has a SimbodyConfig.cmake https://github.com/simbody/simbody/tree/master/cmake). I want to make an OpenSimConfig.cmake. This will perhaps be useful for opensim-gui to get relevant paths for an opensim-core installation, and will also be useful for anyone making a client project of OpenSim. Thus, it'll also be useful for our API examples.

The OpenSimConfig.cmake file essentially describes the organization of the installation, and I think we could maybe improve the organization of the installation for opensim-core. So perhaps we would discuss that first before we can work on this OpenSimConfig.cmake file.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.