Best Practices

Best practices for developers of CIG hosted codes are specified at three different levels:

  • Minimum Best Practices. Minimum expectation for all codes hosted by or distributed by CIG.
  • Standard Best Practices. All codes should be following this level of best practices. If not, codes should have a plan of active development to achieve this level.
  • Target Best Practices. Codes under active development should have a long-term plan to implement these practices.

Summary Table    

More information on all CIG best practices can be found in our git repo [best practices].


Minimum Best Practices

Practices that codes must follow in order to be accepted by CIG.

  1. Licensing
    1. Open source license. See licensing.
  2. Version control
    1. Use of version control (e.g., subversion, git) to manage code changes
  3. Portability, configuration, and building
    1. Code builds on Unix-like machines (Linux, Darwin) with free tools (compilers)
    2. Well designed, portable build system (e.g. cmake, make, configure-unix only, setup.py, etc.)
  4. Testing
    1. Code includes tests to verify that it runs properly.
    2. Results of accuracy and/or performance benchmarks if established by the research community.
  5. Documentation
    1. Instructions for building and installing the code.
    2. Description of all parameters including units (if dimensionless, specify scaling used).
    3. Explanation of physics the code simulates.
    4. Illustration of how to use the code to solve scientific problems.
      1. Cookbook examples with sample, editable input files.
  6. Citable publication


Standard Best Practices

Practices in addition to the Minimum Best Practices that should be used by all codes developed within the CIG community. Codes not meeting all standards should be actively working to eliminate deficiencies.

  1. Version control
    1. Differentiation between maintenance (bug fixes) and new development.
    2. Source tree limited to files necessary to build software and documentation and run small verification tests.
  2. Coding
    1. User-friendly specification of parameters (e.g., graphical user interfaces, human readable parameter files) outside of source code/specified at run time
    2. Development plan (updated yearly) with prioritization of new features and estimated timetable for their implementation
    3. Comments in code describing:
      1. Algorithms with appropriate references
      2.  Purpose of functions, objects, etc. and descriptions of arguments (inputs / outputs), groups of objects, and tutorials
    4. Modular design 
      1. Balance use of external libraries (e.g., PETSc) to maximize reuse while minimizing dependencies and maintenance
      2.  Allow users to extend code (new features or alternative implementations) without destroying original functionality or modifying main branch.
    5. Error trapping
      1. User errors should result in a message that helps the user correct the problem. User errors should not result in a crash.
      2. Internal errors are generally bugs (or unintended uses). Ideally consistency checks will catch internal errors and generate an error message that helps the developer fix the problem.   
    6. Scalability
      1. Use of distributed/parallel data structures
      2. Messages used to transfer information (e.g., MPI) instead of filesystem
  3. Portability, configuration, and building
    1. Verification that dependencies are available and usable.
    2. Automation and portability of configuration and building.
    3. Output all configuration and build options during runtime (e.g. commit id, compiler options, checksum) to facilitate reproducibility.
  4. Testing
    1. Code includes pass/fail tests that verify it runs properly.
  5. Documentation
    1. User documentation: workflow for research use.
    2. Developer documentation: description of how to extend code in anticipated ways.
  6. User Workflow
    1. Running different simulations does not require rebuilding.
    2. User specified directories and filenames for input and output.
    3. Use of standard binary file formats (e.g., NetCDF, HDF5).
    4. Citation for code version.


Target Best Practices

Practices in addition to the Standard Best Practices. Desirable practices that developers should implement in defining long-term development priorities for codes developed within the CIG community. 

  1. Version control
    1. New features added in separate branches.
    2. Stable development (master) branches for rapid release of new features.
  2. Coding
    1. Functionality implemented as a library rather than an application
      1. Leverage alternative implementations via plugins.
      2. Extend library features in applications without modifying original code.
      3. Construct higher level applications using libraries as building blocks.
    2. Output of provenance information (parameters used).
    3. Scalability
      1. Parallel access to inputs and outputs (e.g., HDF5).
    4. Checkpointing.
  3. Portability, configuration, and building
    1. User can select compilers, optimization, additional build flags during configuration without modifying files under version control.
    2. Permit multiple builds using the same source tree.
    3. Software can be installed to a central location.
  4. Testing
    1. Pass/fail unit testing for code verification at a fine grain level.
    2. Method of Manufactured Solutions for code verification at a coarse grain level.
  5. Documentation
    1. Guidelines on parameter scales/combinations for which code is designed/tested.
    2. FAQs or knowledge base.
  6. User Workflow
    1. Reproducibility via archiving of workflow

Debug Console

Close19 MBRequestSessionTimelineDatabase39Events25
$_GET
Array( ) Array(

)
$_POST
Array( ) Array(

)
$_COOKIE
Array( ) Array(

)
$_SERVER
Array( PATH => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin, USER => apache, HOME => /... Array(
PATH => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin,
USER => apache,
HOME => /var/www,
FCGI_ROLE => RESPONDER,
REDIRECT_HTTP_AUTHORIZATION => ,
REDIRECT_UNIQUE_ID => YMY1U1fzUuF3qyEC9NyaZgAAAAU,
REDIRECT_SCRIPT_URL => /software/software-bp,
REDIRECT_SCRIPT_URI => https://geodynamics.hubzero.org/software/software-bp,
REDIRECT_GIT_HTTP_EXPORT_ALL => ,
REDIRECT_HTTPS => on,
REDIRECT_SSL_TLS_SNI => geodynamics.hubzero.org,
REDIRECT_STATUS => 200,
HTTP_AUTHORIZATION => ,
UNIQUE_ID => YMY1U1fzUuF3qyEC9NyaZgAAAAU,
SCRIPT_URL => /software/software-bp,
SCRIPT_URI => https://geodynamics.hubzero.org/software/software-bp,
GIT_HTTP_EXPORT_ALL => ,
HTTPS => on,
SSL_TLS_SNI => geodynamics.hubzero.org,
HTTP_USER_AGENT => CCBot/2.0 (https://commoncrawl.org/faq/),
HTTP_ACCEPT => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,
HTTP_ACCEPT_LANGUAGE => en-US,en;q=0.5,
HTTP_ACCEPT_ENCODING => br,gzip,
HTTP_HOST => geodynamics.hubzero.org,
HTTP_CONNECTION => Keep-Alive,
SERVER_SIGNATURE => ,
SERVER_SOFTWARE => Apache,
SERVER_NAME => geodynamics.hubzero.org,
SERVER_ADDR => 132.249.203.114,
SERVER_PORT => 443,
REMOTE_ADDR => 3.235.179.79,
DOCUMENT_ROOT => /var/www/geodynamics,
REQUEST_SCHEME => https,
CONTEXT_PREFIX => ,
CONTEXT_DOCUMENT_ROOT => /var/www/geodynamics,
SERVER_ADMIN => root@localhost,
SCRIPT_FILENAME => /var/www/geodynamics/index.php,
REMOTE_PORT => 38042,
REDIRECT_URL => /software/software-bp,
GATEWAY_INTERFACE => CGI/1.1,
SERVER_PROTOCOL => HTTP/1.1,
REQUEST_METHOD => GET,
QUERY_STRING => ,
REQUEST_URI => /software/software-bp,
SCRIPT_NAME => /index.php,
PHP_SELF => /index.php,
REQUEST_TIME_FLOAT => 1623602515.9213,
REQUEST_TIME => 1623602515
)
separator .
orderBy id
orderDir asc
1 registerIP
2 access
always
renew
tracker.sid 767d306b209867d4a2fb240220a05e6c
tracker.ssid 767d306b209867d4a2fb240220a05e6c
tracker.rsid 767d306b209867d4a2fb240220a05e6c
  • site 0.052 seconds (+0.052); 12.25 MB (+12.250) - afterInitialise
  • site 0.085 seconds (+0.033); 15.00 MB (+2.750) - afterRoute
  • site 0.128 seconds (+0.043); 18.00 MB (+3.000) - afterDispatch
  • site 0.139 seconds (+0.012); 18.50 MB (+0.500) - beforeRenderModule mod_search (Search)
  • site 0.142 seconds (+0.003); 18.50 MB (0.000) - afterRenderModule mod_search (Search)
  • site 0.142 seconds (+0.000); 18.50 MB (0.000) - beforeRenderModule mod_menu (Main Menu)
  • site 0.201 seconds (+0.059); 19.00 MB (+0.500) - afterRenderModule mod_menu (Main Menu)
  • site 0.206 seconds (+0.004); 19.25 MB (+0.250) - onAfterRender
  • site 0.208 seconds (+0.002); 19.25 MB (0.000) - sessionStore
19 MB

39 Queries Logged: 0.010459184646606 seconds

  1. SELECT data
      FROM `jos_session`
      WHERE `session_id` = 'ba6fa44d66df5d924f5ff3e37a1ea835'
  2. DELETE
      FROM `jos_session`
      WHERE `session_id` = 'ba6fa44d66df5d924f5ff3e37a1ea835'
  3. SELECT data
      FROM `jos_session`
      WHERE `session_id` = '767d306b209867d4a2fb240220a05e6c'
  4. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_languages'
  5. SELECT session_id
      FROM `jos_session`
      WHERE `session_id` = '767d306b209867d4a2fb240220a05e6c'
      LIMIT 1
  6. INSERT INTO `jos_session` (`session_id`,`client_id`,`time`,`ip`)
      VALUES ('767d306b209867d4a2fb240220a05e6c','0','1623602515','3.235.179.79')
  7. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_members'
  8. SELECT b.id
      FROM `jos_usergroups` AS `a`
      LEFT JOIN jos_usergroups AS b
      ON b.lft <= a.lft
      AND b.rgt >= a.rgt
      WHERE `a`.`id` = '1'
  9. SELECT *
      FROM `jos_viewlevels`
  10. SELECT folder AS type,element AS name,protected,params
      FROM `jos_extensions`
      WHERE `enabled` >= '1'
      AND `type` = 'plugin'
      AND `state` >= '0'
      AND `access` IN ('1','1','4')
      ORDER BY `ordering` ASC
  11. SELECT m.id,m.menutype,m.title,m.alias,m.note,m.path AS route,m.link,m.type,m.level,m.language,m.browserNav,m.access,m.params,m.home,m.img,m.template_style_id,m.component_id,m.parent_id,e.element AS component
      FROM `jos_menu` AS `m`
      LEFT JOIN jos_extensions AS e
      ON e.extension_id = m.component_id
      WHERE `m`.`published` = '1'
      AND `m`.`parent_id` > '0'
      AND `m`.`client_id` = '0'
      ORDER BY `m`.`lft` ASC
  12. SELECT jos_template_styles.id,jos_template_styles.home,jos_template_styles.template,jos_template_styles.params,jos_extensions.protected
      FROM `jos_template_styles`
      INNER JOIN jos_extensions
      ON jos_extensions.element = jos_template_styles.template
      WHERE `jos_template_styles`.`client_id` = '0'
      AND `jos_extensions`.`enabled` = '1'
      AND `jos_extensions`.`type` = 'template'
      AND jos_extensions.`client_id` = `jos_template_styles`.`client_id`
      ORDER BY `home` DESC
  13. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_content'
  14. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_categories'
  15. SELECT a.rules
      FROM `jos_assets` AS `a`
      WHERE `a`.`id` = '1'
      GROUP BY a.id, a.rules, a.lft
  16. SELECT b.rules
      FROM `jos_assets` AS `a`
      LEFT JOIN jos_assets AS b
      ON b.lft <= a.lft
      AND b.rgt >= a.rgt
      WHERE `a`.`name` = 'com_content'
      GROUP BY b.id, b.rules, b.lft
      ORDER BY `b`.`lft` ASC
  17. SELECT a.*,a.id,a.asset_id,a.title,a.alias,a.title_alias,a.introtext,a.fulltext,
      CASE WHEN badcats.id IS NULL THEN a.state ELSE 0 END AS state,a.mask,a.catid,a.created,a.created_by,a.created_by_alias,
      CASE WHEN a.modified IS NULL THEN a.created ELSE a.modified END AS modified,a.modified_by,a.checked_out,a.checked_out_time,a.publish_up,a.publish_down,a.images,a.urls,a.attribs,a.version,a.parentid,a.ordering,a.metakey,a.metadesc,a.access,a.hits,a.metadata,a.featured,a.language,a.xreference,c.title AS category_title,c.alias AS category_alias,c.access AS category_access,u.name AS author,parent.title AS parent_title,parent.id AS parent_id,parent.path AS parent_route,parent.alias AS parent_alias,ROUND(v.rating_sum / v.rating_count, 0) AS rating,v.rating_count AS rating_count
      FROM `jos_content` AS `a`
      LEFT JOIN jos_categories AS c
      ON c.id = a.catid
      LEFT JOIN jos_users AS u
      ON u.id = a.created_by
      LEFT JOIN jos_categories as parent
      ON parent.id = c.parent_id
      LEFT JOIN jos_content_rating AS v
      ON a.id = v.content_id
      LEFT
      OUTER JOIN (SELECT cat.id as id
      FROM jos_categories AS cat JOIN jos_categories AS parent
      ON cat.lft BETWEEN parent.lft
      AND parent.rgt
      WHERE parent.extension = 'com_content'
      AND parent.published <= 0
      GROUP BY cat.id) AS badcats
      ON badcats.id = c.id
      WHERE `a`.`id` = '71'
      AND (`a`.`publish_up` IS NULL OR `a`.`publish_up` <= '2021-06-13 16:41:56' )
      AND (`a`.`publish_down` IS NULL OR `a`.`publish_down` >= '2021-06-13 16:41:56' )
      AND `a`.`state` IN ('1','2')
  18. SELECT c.*,
      CASE WHEN CHAR_LENGTH(c.alias) THEN CONCAT_WS(':', c.id, c.alias) ELSE c.id END as slug
      FROM `jos_categories` AS `c`
      LEFT JOIN jos_categories AS s
      ON (s.lft <= c.lft
      AND s.rgt >= c.rgt) OR (s.lft > c.lft
      AND s.rgt < c.rgt)
      LEFT JOIN (SELECT cat.id as id
      FROM jos_categories AS cat JOIN jos_categories AS parent
      ON cat.lft BETWEEN parent.lft
      AND parent.rgt
      WHERE parent.extension = 'com_content'
      AND parent.published != 1
      GROUP BY cat.id) AS badcats
      ON badcats.id = c.id
      WHERE (`c`.`extension` = 'com_content' OR `c`.`extension` = 'system' )
      AND `c`.`access` IN ('1','1','4')
      AND `c`.`published` = '1'
      AND `s`.`id` = '29'
      AND badcats.id is null
      GROUP BY c.id,c.asset_id,c.access,c.alias,c.checked_out,c.checked_out_time,c.created_time,c.created_user_id,c.description,c.extension,c.hits,c.language,c.level,c.lft,c.metadata,c.metadesc,c.metakey,c.modified_time,c.note,c.params,c.parent_id,c.path,c.published,c.rgt,c.title,c.modified_user_id
      ORDER BY `c`.`lft` ASC
  19. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_users'
  20. SELECT m.id,m.title,m.module,m.position,m.content,m.showtitle,m.params,mm.menuid,e.protected
      FROM `jos_modules` AS `m`
      LEFT JOIN jos_modules_menu AS mm
      ON mm.moduleid = m.id
      LEFT JOIN jos_extensions AS e
      ON e.element = m.module
      AND e.client_id = m.client_id
      WHERE `m`.`published` = '1'
      AND `e`.`enabled` = '1'
      AND (`m`.`publish_up` IS NULL OR `m`.`publish_up` <= '2021-06-13 16:41:56' )
      AND (`m`.`publish_down` IS NULL OR `m`.`publish_down` >= '2021-06-13 16:41:56' )
      AND `m`.`access` IN ('1','1','4')
      AND `m`.`client_id` = '0'
      AND (`mm`.`menuid` = '185' OR `mm`.`menuid` <= '0' )
      ORDER BY `m`.`position` ASC,`m`.`ordering` ASC
  21. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_search'
  22. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_events'
  23. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_newsletter'
  24. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_groups'
  25. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_projects'
  26. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_resources'
  27. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_courses'
  28. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_forum'
  29. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_collections'
  30. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_blog'
  31. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_tags'
  32. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_wiki'
  33. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_citations'
  34. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_storefront'
  35. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_answers'
  36. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_support'
  37. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_kb'
  38. SELECT extension_id AS id,element AS "option",params,enabled
      FROM `jos_extensions`
      WHERE `type` = 'component'
      AND `element` = 'com_wishlist'
  39. UPDATE `jos_session`
      SET `data` = '__default|a:9:{s:15:\"session.counter\";i:1;s:19:\"session.timer.start\";i:1623602515;s:18:\"session.timer.last\";i:1623602515;s:17:\"session.timer.now\";i:1623602515;s:8:\"registry\";O:23:\"Hubzero\\Config\\Registry\":2:{s:7:\"\0*\0data\";O:8:\"stdClass\":1:{s:1:\"0\";s:7:\"session\";}s:9:\"separator\";s:1:\".\";}s:4:\"user\";C:17:\"Hubzero\\User\\User\":22:{a:1:{s:5:\"guest\";b:1;}}s:11:\"tracker.sid\";s:32:\"767d306b209867d4a2fb240220a05e6c\";s:12:\"tracker.ssid\";s:32:\"767d306b209867d4a2fb240220a05e6c\";s:12:\"tracker.rsid\";s:32:\"767d306b209867d4a2fb240220a05e6c\";}',`time` = '1623602516',`ip` = '3.235.179.79'
      WHERE `session_id` = '767d306b209867d4a2fb240220a05e6c'
  • onAfterInitialise Method plgSystemP3p::onAfterInitialise /core/plugins/system/p3p/p3p.php:21
  • onAfterInitialise Method plgSystemRemember::onAfterInitialise /core/plugins/system/remember/remember.php:20
  • onAfterInitialise Method plgSystemHubzero::onAfterInitialise /core/plugins/system/hubzero/hubzero.php:21
  • onAfterInitialise Method plgSystemXFeed::onAfterInitialise /core/plugins/system/xfeed/xfeed.php:21
  • onAfterInitialise Method plgSystemSupergroup::onAfterInitialise /core/plugins/system/supergroup/supergroup.php:113
  • onAfterInitialise Method plgSystemReferrerpolicy::onAfterInitialise /core/plugins/system/referrerpolicy/referrerpolicy.php:21
  • onAfterRoute Method plgSystemJquery::onAfterRoute /core/plugins/system/jquery/jquery.php:21
  • onAfterRoute Method plgSystemSpamjail::onAfterRoute /core/plugins/system/spamjail/spamjail.php:21
  • onAfterRoute Method plgSystemIncomplete::onAfterRoute /core/plugins/system/incomplete/incomplete.php:21
  • onAfterRoute Method plgSystemUnconfirmed::onAfterRoute /core/plugins/system/unconfirmed/unconfirmed.php:21
  • onAfterRoute Method plgSystemUnapproved::onAfterRoute /core/plugins/system/unapproved/unapproved.php:21
  • onAfterRoute Method plgSystemPassword::onAfterRoute /core/plugins/system/password/password.php:21
  • onContentPrepare Method plgContentLoadmodule::onContentPrepare /core/plugins/content/loadmodule/loadmodule.php:35
  • onContentPrepare Method plgContentEmailcloak::onContentPrepare /core/plugins/content/emailcloak/emailcloak.php:25
  • onContentPrepare Method plgContentPagebreak::onContentPrepare /core/plugins/content/pagebreak/pagebreak.php:35
  • onContentPrepare Method plgContentXhubtags::onContentPrepare /core/plugins/content/xhubtags/xhubtags.php:25
  • onContentPrepare Method plgContentFormatwiki::onContentPrepare /core/plugins/content/formatwiki/formatwiki.php:63
  • onContentPrepare Method plgContentFormathtml::onContentPrepare /core/plugins/content/formathtml/formathtml.php:105
  • onContentPrepare Method plgContentExternalhref::onContentPrepare /core/plugins/content/externalhref/externalhref.php:41
  • onContentBeforeDisplay Method plgContentPagenavigation::onContentBeforeDisplay /core/plugins/content/pagenavigation/pagenavigation.php:25
  • onContentBeforeDisplay Method plgContentVote::onContentBeforeDisplay /core/plugins/content/vote/vote.php:32
  • onAfterDispatch Method plgSystemMobile::onAfterDispatch /core/plugins/system/mobile/mobile.php:22
  • onAfterDispatch Method plgSystemDebug::onAfterDispatch /core/plugins/system/debug/debug.php:60
  • onAfterDispatch Method PlgSystemHighlight::onAfterDispatch /core/plugins/system/highlight/highlight.php:25
  • onAfterRender Method plgSystemSef::onAfterRender /core/plugins/system/sef/sef.php:21