{"id":27258720,"url":"https://github.com/tobiste/structr","last_synced_at":"2026-02-26T06:46:15.165Z","repository":{"id":173730055,"uuid":"649009831","full_name":"tobiste/structr","owner":"tobiste","description":"Structural geology package for R","archived":false,"fork":false,"pushed_at":"2025-02-09T16:30:09.000Z","size":17786,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-11T03:49:37.901Z","etag":null,"topics":["spherical-geometry","spherical-projection","statistical-analysis","structural-geology","tectonics"],"latest_commit_sha":null,"homepage":"https://tobiste.github.io/structr/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tobiste.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-03T13:46:40.000Z","updated_at":"2025-02-09T16:07:26.000Z","dependencies_parsed_at":"2024-02-05T15:47:42.332Z","dependency_job_id":"1127f948-6988-466a-8df9-4ed8a63294f0","html_url":"https://github.com/tobiste/structr","commit_stats":null,"previous_names":["tobiste/structr"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobiste%2Fstructr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobiste%2Fstructr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobiste%2Fstructr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobiste%2Fstructr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tobiste","download_url":"https://codeload.github.com/tobiste/structr/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248339264,"owners_count":21087214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["spherical-geometry","spherical-projection","statistical-analysis","structural-geology","tectonics"],"created_at":"2025-04-11T03:49:42.988Z","updated_at":"2026-02-26T06:46:15.147Z","avatar_url":"https://github.com/tobiste.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\noutput: github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\",\n  dpi = 300,\n  fig.width = 7\n)\n```\n\n# structr \u003ca href=\"https://tobiste.github.io/structr/\"\u003e\u003cimg src=\"man/figures/logo.png\" alt=\"structr website\" align=\"right\" height=\"104\"/\u003e\u003c/a\u003e\n\n\n\u003c!-- badges: start --\u003e\n\n[![R-CMD-check](https://github.com/tobiste/structr/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/tobiste/structr/actions/workflows/R-CMD-check.yaml)\n\n\u003c!-- badges: end --\u003e\n\n`{structr}` is a free and open-source package for R that provides tools for structural geology. The toolset includes\n\n-   Analysis and visualization of orientation data of structural geology (including, **stereographic projections**, contouring, fabric plots, and statistics),\n\n-   Statistical analysis: spherical mean and variance, confidence regions, hypothesis tests, **cluster analysis** of orientation data (`sph_cluster()`, and geodesic regression to find the **best-fitting great circle or small circle** through orientation data (`regression_greatcircle()` and `regression_smallcircle()`),\n\n-   Reconstruction of fabric orientations in **oriented drillcores** by transforming the α, β, and γ angles (`drillcore_transformation()`,\n\n- Deform orientation data using deformation and velocity gradient tensors: `defgrad()` and `velgrad()`\n\n-   **Stress analysis**: reconstruction of stress orientation and magnitudes from fault-slip data (stress inversion based on **Michael, 1984**: `slip_inversion()`), extracting the **maximum horizontal stress** of a 3D stress tensor (`SH()`), and visualization of magnitudes of stress in the **Mohr circle** (`Mohr_plot()`),\n\n-   Calculation fault displacement components,\n\n-   Strain analysis (**R**\u003csub\u003ef\u003c/sub\u003e/ϕ), contouring on the unit hyperboloid, **Fry plots** and **Hsu plots**\n\n-   Vorticity analysis using the **Rigid Grain Net** method (`RGN_plot()`), and\n\n-   Direct import of your field data from **StraboSpot** projects (`read_strabo_JSON()`).\n\n\u003e The {structr} package is all about structures in 3D. For analyzing orientations in 2D (statistics, rose diagrams, etc.), check out the [tectonicr](https://github.com/tobiste/tectonicr) package!\n\n## Installation\n\nYou can install the development version of `{structr}` from [GitHub](https://github.com/) with:\n\n``` r\n# install.packages(\"devtools\")\ndevtools::install_github(\"tobiste/structr\")\n```\n\n## Documentation\n\nThe detailed documentation can be found at \u003chttps://tobiste.github.io/structr/\u003e\n\n## Examples\n\nThese are some basic examples which shows you what you can do with {structr}. First we load the package\n\n```{r load, warning=FALSE,message=FALSE}\nlibrary(structr)\n```\n\n### Stereographic and Equal-Area Projection\n\nPlot orientation data in equal-area, lower hemisphere projection:\n\n```{r stereo, warning=FALSE,message=FALSE}\n# load some example data\ndata(\"example_planes\")\ndata(\"example_lines\")\n\n# initialize the stereoplot\nstereoplot(\n  title = \"Lambert equal-area projection\",\n  sub = \"Lower hemisphere\",\n  ticks = 45, labels = TRUE\n)\n\n# add vectors as points\npoints(example_lines, col = \"#B63679\", pch = 19, cex = .5)\npoints(example_planes, col = \"#000004\", pch = 1, cex = .5)\n\n# add a legend\nlegend(\"topright\", legend = c(\"Lines\", \"Planes\"), col = c(\"#B63679\", \"#000004\"), pch = c(19, 1), cex = 1)\n```\n\n### Density on a Sphere\n\nDensity shown by contour lines...\n\n```{r stereo_density_lines, warning=FALSE,message=FALSE}\npar(mfrow = c(1, 2))\ncontour(example_planes)\npoints(example_planes, col = \"grey\", cex = .5)\ntitle(main = \"Planes\")\n\ncontour(example_lines)\npoints(example_lines, col = \"grey\", cex = .5)\ntitle(main = \"Lines\")\n```\n\nor as filled contours:\n\n```{r stereo_density_img, warning=FALSE,message=FALSE}\npar(mfrow = c(1, 2))\nimage(example_planes)\npoints(example_planes, col = \"grey\", cex = .5)\ntitle(main = \"Planes\")\n\nimage(example_lines)\npoints(example_lines, col = \"grey\", cex = .5)\ntitle(main = \"Lines\")\n```\n\n### Spherical Statistics\n\nCalculation of arithmetic mean, geodesic mean, confidence cones and eigenvectors... and plotting them in the equal-area projection:\n\n```{r stats, warning=FALSE,message=FALSE}\nplanes_mean \u003c- sph_mean(example_planes)\nplanes_geomean \u003c- geodesic_mean(example_planes)\nplanes_eig \u003c- ot_eigen(example_planes)$vectors\n\npar(mfrow = c(1, 2), xpd = NA)\nstereoplot(title = \"Planes\", guides = FALSE)\npoints(example_planes, col = \"lightgrey\", pch = 1, cex = .5)\nlines(planes_eig, col = c(\"#FB8861FF\", \"#FEC287FF\", \"#FCFDBFFF\"), lty = 1:3)\npoints(planes_mean, col = \"#B63679\", pch = 19, cex = 1)\npoints(planes_geomean, col = \"#E65164FF\", pch = 19, cex = 1)\npoints(planes_eig, col = c(\"#FB8861FF\", \"#FEC287FF\", \"#FCFDBFFF\"), pch = 19, cex = 1)\nlegend(\n  0, -1.1,\n  xjust = .5,\n  legend = c(\"Arithmetic mean\", \"Geodesic mean\", \"Eigen 1\", \"Eigen 2\", \"Eigen 3\"),\n  col = c(\"#B63679\", \"#E65164FF\", \"#FB8861FF\", \"#FEC287FF\", \"#FCFDBFFF\"),\n  pch = 19, lty = c(NA, NA, 1, 2, 3),\n  cex = .75\n)\n\nlines_mean \u003c- sph_mean(example_lines)\nlines_delta \u003c- delta(example_lines)\nlines_confangle \u003c- confidence_ellipse(example_lines)\n\nstereoplot(title = \"Lines\", guides = FALSE)\npoints(example_lines, col = \"lightgrey\", pch = 1, cex = .5)\npoints(lines_mean, col = \"#B63679\", pch = 19, cex = 1)\nstereo_confidence(lines_confangle, col = \"#E65164FF\")\nlines(lines_mean, ang = lines_delta, col = \"#FB8861FF\")\nlegend(\n  0, -1.1,\n  xjust = .5,\n  legend = c(\"Arithmetic mean\", \"95% confidence cone\", \"63% data cone\"),\n  col = c(\"#B63679\", \"#E65164FF\", \"#FB8861FF\"),\n  pch = c(19, NA, NA), lty = c(NA, 1, 1), cex = .75\n)\n```\n\n### Orientation Tensor and Fabric Plots\n\nThe shape parameters of the orientation tensor of the above examples planes and lines can be visualized in two ways:\n\n```{r stereo_ortensor, warning=FALSE,message=FALSE}\npar(mfrow = c(1, 2), xpd = NA)\nvollmer_plot(example_planes, col = \"#000004\", pch = 16)\nvollmer_plot(example_lines, col = \"#B63679FF\", pch = 16, add = TRUE)\n\nhsu_plot(example_planes, col = \"#000004\", pch = 16)\nhsu_plot(example_lines, col = \"#B63679FF\", pch = 16, add = TRUE)\n\nlegend(\n  2.5, -.25,\n  xjust = .5, horiz = TRUE, xpd = NA,\n  legend = c(\"Planes\", \"Lines\"), col = c(\"#000004\", \"#B63679FF\"), pch = 16\n)\n```\n\n### Best-fit Great- and Small-Circles (Geodesic Regression)\n\nFinds the best-fit great or small-circle for a given set of vectors by applying geodesic regression:\n\n```{r bestfit, warning=FALSE,message=FALSE}\nset.seed(20250411)\ndata(\"gray_example\")\ncleavage \u003c- gray_example[1:8, ]\nbedding \u003c- gray_example[9:16, ]\n\ncleavage_gc \u003c- regression_greatcircle(cleavage)\nbedding_gc \u003c- regression_greatcircle(bedding)\n\ncleavage_sc \u003c- regression_smallcircle(cleavage)\nbedding_sc \u003c- regression_smallcircle(bedding)\n\npar(mfrow = c(1, 2), xpd = NA)\nstereoplot(title = \"Best greatcircle\", guides = FALSE)\nlines(cleavage_gc$vec, col = \"#000004FF\")\nlines(bedding_gc$vec, col = \"#B63679\")\npoints(cleavage, col = \"#1D1147\")\npoints(bedding, col = \"#E65164\", pch = 4)\n\nlegend(\n  0, -1.1,\n  xjust = .5,\n  col = c(\"#000004FF\", \"#B63679\"),\n  lty = c(1, 1), legend = c(\"Cleavage greatcircle\", \"Bedding greatcircle\"), bg = \"white\"\n)\n\nstereoplot(title = \"Best smallcircle\", guides = FALSE)\nlines(cleavage_sc$vec, cleavage_sc$cone, col = \"#000004FF\")\nlines(bedding_sc$vec, bedding_sc$cone, col = \"#B63679\")\npoints(cleavage, col = \"#1D1147\")\npoints(bedding, col = \"#E65164\", pch = 4)\n\nlegend(0, -1.1,\n  xjust = .5,\n  col = c(\"#000004FF\", \"#B63679\"), lty = c(1, 1), legend = c(\"Cleavage smallcircle\", \"Bedding smallcircle\"), bg = \"white\"\n)\n```\n\n### Fault Plots\n\nGraphical representation of fault-slip data using Angelier plot (slip vector on fault plane great circle) and Hoeppener plot (fault slip vector projected on pole to fault plane):\n\n```{r stereo_faults, warning=FALSE,message=FALSE}\ndata(\"angelier1990\")\nfaults \u003c- angelier1990$TYM\n\npar(mfrow = c(1, 2))\nstereoplot(title = \"Angelier plot\", guides = FALSE)\nangelier(faults, col = \"grey20\")\n\nstereoplot(title = \"Hoeppener plot\", guides = FALSE)\nhoeppener(faults, points = FALSE, col = \"grey20\")\n```\n\n### Fault-Slip Inversion\n\nCompute deviatoric stress tensor and calculate 95% confidence intervals using bootstrap samples:\n\n```{r stereo_inversion1, warning=FALSE,message=FALSE}\nset.seed(20250411)\nfaults_stress \u003c- slip_inversion(faults, n_iter = 10)\n```\n\nVisualize the slip inversion results (orientation of principal stresses):\n\n```{r stereo_inversion_plot, warning=FALSE,message=FALSE}\ncols \u003c- c(\"#000004FF\", \"#B63679FF\", \"#FEC287FF\")\nR_val \u003c- round(faults_stress$R, 2)\nR_CI \u003c- round(faults_stress$R_conf, 2)\n\nstereoplot(\n  title = \"Principal stress axes\",\n  sub = paste0(\"Relative stress magnitudes R = \", R_val, \" | \", \"95% CI: [\", R_CI[1], \", \", R_CI[2], \"]\"),\n  guides = FALSE\n)\nangelier(faults, col = \"grey80\")\nstereo_confidence(faults_stress$principal_axes_conf$sigma1, col = cols[1])\nstereo_confidence(faults_stress$principal_axes_conf$sigma2, col = cols[2])\nstereo_confidence(faults_stress$principal_axes_conf$sigma3, col = cols[3])\ntext(faults_stress$principal_axes,\n  label = rownames(faults_stress$principal_axes),\n  col = cols, adj = -.25\n)\n```\n\nVisualize the accuracy of the slip inversion by showing the deviation angle (\u0026beta;) between the theoretical slip and the actual slip vector:\n\n```{r stereo_inversion_deviation, warning=FALSE,message=FALSE}\nbeta \u003c- faults_stress$fault_data$beta\nbeta_mean \u003c- round(faults_stress$beta)\nbeta_CI \u003c- round(faults_stress$beta_CI)\n\nstereoplot(\n  title = \"Stress inversion accuracy\",\n  sub = bquote(\"Average deviation\" ~ bar(beta) == .(beta_mean) * degree ~ \"\\U00B1\" ~ .(beta_CI) * degree),\n  guides = FALSE\n)\nangelier(faults, col = assign_col(beta))\nlegend_col(\n  seq(min(beta), max(beta), 10),\n  title = bquote(\"Deviation angle\" ~ beta ~ \"(\" * degree * \")\")\n)\n```\n\nAzimuth of the maximum horizontal stress (in degrees) for the slip inversion result:\n\n```{r stereo_inversion_SH, warning=FALSE,message=FALSE}\n# Simply call\n# faults_stress$SHmax\n# faults_stress$SHmax_CI # confidence interval\n\nSH(\n  S1 = faults_stress$principal_axes[1, ],\n  S2 = faults_stress$principal_axes[2, ],\n  S3 = faults_stress$principal_axes[3, ],\n  R = faults_stress$R\n)\n```\n\n### Mohr Circle\n\nThe Mohr circle for the slip inversion result:\n\n```{r stereo_inversion_mohr, warning=FALSE,message=FALSE}\nMohr_plot(\n  sigma1 = faults_stress$principal_vals[1],\n  sigma2 = faults_stress$principal_vals[2],\n  sigma3 = faults_stress$principal_vals[3],\n  unit = NULL, include.zero = FALSE\n)\npoints(faults_stress$fault_data$sigma_n, abs(faults_stress$fault_data$sigma_s),\n  col = assign_col(beta), pch = 16\n)\n```\n\n### Strain Analysis\n\n#### 2D Strain\n\nAspect ratio of finite strain ellipses vs orientation of long-axis (Rf/ϕ)\n\n```{r strain, warning=FALSE,message=FALSE}\ndata(ramsay)\n\npar(mfrow = c(1, 2))\nRphi_plot(r = ramsay[, 1], phi = ramsay[, 2])\nelliott_plot(ramsay[, 1], ramsay[, 2], proj = \"eqd\")\n```\n\n#### 3D Strain\n\nFinite strain ellipsoids plotted in Flinn diagram and Hsu diagram:\n\n```{r strain3D, warning=FALSE,message=FALSE}\ndata(\"holst\")\nR_XY \u003c- holst[, \"R_XY\"]\nR_YZ \u003c- holst[, \"R_YZ\"]\n\npar(mfrow = c(1, 2))\nflinn_plot(cbind(R_XY, R_YZ), log = TRUE, col = \"#B63679\", pch = 16)\nhsu_plot(cbind(R_XY, R_YZ), col = \"#B63679\", pch = 16)\n```\n\n### Vorticity Analysis\n\nAspect ratio of finite strain ellipses of porphyroclasts vs orientation of long-axis with respect to foliation plotted in the **Rigid Grain Net**\n\n```{r rgn, warning=FALSE,message=FALSE}\ndata(shebandowan)\nset.seed(20250411)\n\n# Color code porphyroclasts by size of clast (area in log-scale):\nRGN_plot(shebandowan$r, shebandowan$phi, col = assign_col(log(shebandowan$area)), pch = 16)\n```\n\n### Deformation and Velocity Gradient Tensors\n\nDefine a deformation gradient tensor and deform some orientation data over time \n`t` in `i` increments:\n\n```{r defgrad1}\n# Define deformation time and increments\nt \u003c- 10\ni \u003c- 2\n\n# Define deformation tensor:\nD1 \u003c- defgrad_from_generalshear(k = 2.5, gamma = 0.9)\n\n# Generate some random lineation\nxl \u003c- rvmf(100, mu = Line(0, 90), k = 100)\n\n# Generate the velcity gradient tensor for deformation accumulating over time\nL \u003c- velgrad(D1, time = t)\n\n# Extract deformation increments\nD1_steps \u003c- defgrad(L, time = t, steps = i)\n\n# Transform the lineation for each deformation increment\nxl_steps \u003c- lapply(D1_steps, function(i) {\n  transform_linear(xl, i)\n})\n\n# instantaneous stretching axes\naxes_ISA \u003c- instantaneous_stretching_axes(L)\n\n# flow apophyses\nflow_apophyses \u003c- flow_apophyses(L)\n\nincrements \u003c- seq(0, t, i)\n\nstereoplot(guides = FALSE)\nstereo_path(xl_steps, type = \"l\")\nstereo_path(xl_steps, type = \"p\", col = assign_col(increments), pch = 16, cex = .4)\n\nlines(flow_apophyses, col = c(\"grey30\", \"grey70\"), lty = c(1, 2))\npoints(axes_ISA, pch = 15, col = \"#B63679FF\")\ntext(axes_ISA, labels = c(\"ISA-1\", \"ISA-2\", \"ISA-3\"), col = \"#B63679FF\", pos = 3, font = 2)\n\n# legend\nlegend(0, -1.1,\n  xjust = 0.5,\n  legend = c(\"Flow apophysis 1\", \"Flow apophysis 2\"),\n  col = c(\"grey30\", \"grey70\"),\n  lty = c(1, 2)\n)\n\nlegend_col(increments, title = \"Time\")\n```\nShow how the orientation tensor changes during progressive deformation:\n\n```{r defgrad2}\npar(mfrow = c(1, 2))\nvollmer_plot(xl_steps, type = \"b\", col = assign_col(increments), pch = 16)\nhsu_plot(xl_steps, type = \"b\", col = assign_col(increments), pch = 16)\n```\n\n\n## Author\n\nTobias Stephan ([tstephan\\@lakeheadu.ca](mailto:tstephan@lakeheadu.ca){.email})\n\n## Feedback, issues, and contributions\n\nI welcome feedback, suggestions, issues, and contributions! If you have found a bug, please file it [here](https://github.com/tobiste/structr/issues) with minimal code to reproduce the issue.\n\n## License\n\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftobiste%2Fstructr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftobiste%2Fstructr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftobiste%2Fstructr/lists"}