Commit eca78a4a authored by Christian Tischer's avatar Christian Tischer

Merge branch 'jekyll' into 'master'

More advanced Jekyll setup

See merge request !20
parents 3ad1fcd2 ff10ae16
Pipeline #10056 passed with stages
in 1 minute and 18 seconds
image: ruby:2.3 image: ruby:2.5
variables: variables:
JEKYLL_ENV: production JEKYLL_ENV: production
LC_ALL: C.UTF-8 LC_ALL: C.UTF-8
...@@ -22,5 +22,4 @@ pages: ...@@ -22,5 +22,4 @@ pages:
paths: paths:
- public - public
only: only:
- jekyll
- master - master
---
layout: default
---
# Guidelines for Contributing # Guidelines for Contributing
Contributions to this project are very welcome. Contributions to this project are very welcome.
...@@ -12,9 +15,111 @@ To contribute to this project, please follow those steps: ...@@ -12,9 +15,111 @@ To contribute to this project, please follow those steps:
1. Clone this repository: `git clone https://git.embl.de/grp-bio-it/image-analysis-training-resources.git` 1. Clone this repository: `git clone https://git.embl.de/grp-bio-it/image-analysis-training-resources.git`
1. On your computer, make a new branch. For example, if you would like to contribute python code to the binarization.md module you may: `git checkout -b pythonBinarization` 1. On your computer, make a new branch. For example, if you would like to contribute python code to the binarization.md module you may: `git checkout -b pythonBinarization`
1. Now add your changes on your computer (staying in this branch). 1. Now add your changes on your computer (staying in this branch) - see "Adding a new module" section, below.
1. When you are done, please `git add .; git commit -m "some message"` 1. When you are done, please `git add .; git commit -m "some message"`
1. Now you can upload your branch to the online repository by typing: `git push --set-upstream origin pythonBinarization`. 1. Now you can upload your branch to the online repository by typing: `git push --set-upstream origin pythonBinarization`.
1. Go to the online repository on gitlab: https://git.embl.de/grp-bio-it/image-analysis-training-resources 1. Go to the online repository on gitlab: https://git.embl.de/grp-bio-it/image-analysis-training-resources
1. On gitlab, there will now be button at the top of the page. Click this button to stage a "merge request" of your contribution (in your branch) to the master branch. There will also a possibility to assign a project maintainer to review your contribution and to merge it. Please select someone appropriate here. 1. On gitlab, there will now be button at the top of the page. Click this button to stage a "merge request" of your contribution (in your branch) to the master branch. There will also a possibility to assign a project maintainer to review your contribution and to merge it. Please select someone appropriate here.
1. Thank you for your contribution! 1. Thank you for your contribution!
## Adding a new module
Each module page is built from a template (`_layouts/module.html`),
ensuring a consistent structure and style for the whole collection.
To create a new module, you will need to add a few files
in a few different places in this repository.
### Module file
Most important is the module file itself.
This module file should be saved with a short, descriptive name (no spaces!)
ending with the `.md` (Markdown) extension.
Typically, the only content of this Markdown file should be a header
written in YAML. See the specification below.
All fields not marked as optional are required for the page to build.
You can check that your YAML is valid with [this tool](http://www.yamllint.com/).
```yaml
---
title: Title of the Module
layout: module # don't change this
prerequisites:
- "a list of things that learners should know"
- "in order to understand this module"
objectives:
- "a list of learning objectives"
- "see note 1 below for more info"
motivation: >
A description of *why* you would want to learn this.
Can be written in
(GitHub-flavoured) [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)
and split
across
multiple
lines.
concept_map: > # see note 2
graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car];
figure: /figures/mymodule.png # store the example image for your module in the `figures` folder and provide the absolute path from the root of the site here.
figure_legend: Some description of the figure. (optional)
activity_preface: >
Some general description of the activity for
that learners will do while studying the module.
It will be followed by platform-specific instructions/example code.
(optional)
activities: # platform-specific activity instruction/example code files (see note 3) (optional)
"ImageJ GUI": "mymodule/activities/mymodule_imagejgui.md"
"ImageJ Macro": "mymodule/activities/mymodule_imagejmacro.md"
"Jython": "mymodule/activities/mymodule_jython.md"
exercises_preface: >
You could put general, language-agnostic questions here...
(optional)
exercises: # platform-specific exercises (in Markdown files) (see note 3) (optional)
"ImageJ GUI": "mymodule/exercises/mymodule_imagejgui.md"
"ImageJ Macro": "mymodule/exercises/mymodule_imagejmacro.md"
"Jython": "mymodule/exercises/mymodule_jython.md"
"MATLAB": "mymodule/exercises/mymodule_matlab.md"
learn_next: # see note 4
- "[name_of_one](calibration)"
- "[or_more_modules](object_splitting)"
- "[to link to next](display)"
external_links:
- "[link to](https://external.page.com)"
---
```
Notes:
1. Learning objectives should be worded as endings to a sentence beginning "After completing this lesson, learners should be able to...". We recommend starting each learning objective with a verb from [Bloom's Taxonomy](https://cft.vanderbilt.edu/guides-sub-pages/blooms-taxonomy/)
2. Concept maps are drawn with [Mermaid.js](https://mermaidjs.github.io/flowchart.html). The indentation of the chart description is important, so be careful!
3. The `activities` and `exercises` fields should be populated with key-value pairs, where the key is the name of the platform (e.g. "ImageJ GUI", "Python", etc) and the value is the path (relative to `_includes/`) to the file containing the activity instructions/exercises for that platform.
4. The points in "Learn Next" are Markdown links, which should be formed as `[Module Title](modulefilename)`, where the extension has been removed from the filename.
### Associated files
Below is a list of all the other files that you should provide
to accompany a new module,
as well as the appropriate location for each
(relative to the top level of the repository).
Examples are given for a `/modules/mymodule.md`
- The `figure` image
- an file containing an example image to illustrate the concept being taught in the module
- location: `/figures/mymodule.md`
- The `activities` files
- Markdown files containing instructions and/or example code for an activity that learners should follow to learn how to apply the concept on a particular platform (ImageJ Macro, MATLAB, etc)
- location: `_includes/mymodule/activities/mymodule_platformnospaces.md`
- The `exercises` files
- Markdown files containing exercises to test the learner's understanding of applying the concept on a particular platform
- location: `_includes/mymodule/exercises/mymodule_platformnospaces.md`
## Adding exercises/activity instructions for a new platform
Contributions of instructions and exercises for more platforms are very welcome - please see the "Associated files" subsection above for details of where these contributed files should be added.
## Questions about the module layout
If you have questions about the module layout, please contact [Toby Hodges](mailto:toby.hodges@embl.de).
...@@ -7,3 +7,7 @@ gem "jekyll", "3.4.0" ...@@ -7,3 +7,7 @@ gem "jekyll", "3.4.0"
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
# install GH-flavoured MD plugin
group :jekyll_plugins do
gem 'jekyll-commonmark-ghpages'
end
...@@ -5,7 +5,11 @@ description: > # this means to ignore newlines until "baseurl:" ...@@ -5,7 +5,11 @@ description: > # this means to ignore newlines until "baseurl:"
Includes concept maps, exercises, example data Includes concept maps, exercises, example data
baseurl: "/image-analysis-training-resources" # the subpath of your site, e.g. /blog baseurl: "/image-analysis-training-resources" # the subpath of your site, e.g. /blog
url: "https://grp-bio-it.embl-community.io/" # the base hostname & protocol for your site url: "https://grp-bio-it.embl-community.io/" # the base hostname & protocol for your site
contributing: CONTRIBUTING
# Build settings # Build settings
markdown: kramdown markdown: CommonMarkGhPages
exclude: ["README.md", "CONTRIBUTING.md", "TEACHING.md"] commonmark:
options: ["SMART"]
highlighter: rouge
exclude: ["README.md", "TEACHING.md"]
- **[ Open... ]** "/image-analysis-training-resources/image_data/xy_8bit__two_cells.tif"
- **[ Threshold... ]**
```
open("/image-analysis-training-resources/image_data/xy_8bit__two_cells.tif");
setThreshold(30, 255);
setOption("BlackBackground", true);
run("Convert to Mask");
```
```python
from ij import IJ, ImagePlus
from ij.plugin import Thresholder
inputImage=IJ.getImage()
IJ.setRawThreshold(inputImage, 60, 255, None)
binaryImage=ImagePlus('Binary image',Thresholder.createMask(inputImage))
binaryImage.show()
```
```matlab
function src_binarize_image()
%This function illustrates separating foreground from background using a
%fixed threshold value
threshold = 50; %example hreshold value
%Read input image
in_image = imread(['image_data' filesep 'xy_8bit__two_cells.tif']);
figure; imagesc(in_image); %display input image
%Binarized input image with the threshold value;
bin_image = uint8(in_image>= threshold);
figure; imagesc(bin_image) % display binary image
end
```
This file should contain language-specific exercises, *written* in **Markdown**
...but probably with some HTML mixed in, so that you can add expandable Solution boxes.
#### Exercise 1
What is the solution to the first exercise?
<details>
<summary>Solution</summary>
This is the solution to the first exercise.
</details>
#### Exercise 2
What is the solution to the second exercise?
<details>
<summary>Solution</summary>
This is the solution to the second exercise.
</details>
This file should contain language-specific exercises, *written* in **Markdown**
...but probably with some HTML mixed in, so that you can add expandable Solution boxes.
#### Exercise 1
What is the solution to the first exercise?
<details>
<summary>Solution</summary>
This is the solution to the first exercise.
</details>
#### Exercise 2
What is the solution to the second exercise?
<details>
<summary>Solution</summary>
This is the solution to the second exercise.
</details>
This file should contain language-specific exercises, *written* in **Markdown**
...but probably with some HTML mixed in, so that you can add expandable Solution boxes.
#### Exercise 1
What is the solution to the first exercise?
<details>
<summary>Solution</summary>
This is the solution to the first exercise.
</details>
#### Exercise 2
What is the solution to the second exercise?
<details>
<summary>Solution</summary>
This is the solution to the second exercise.
</details>
This file should contain language-specific exercises, *written* in **Markdown**
...but probably with some HTML mixed in, so that you can add expandable Solution boxes.
#### Exercise 1
What is the solution to the first exercise?
<details>
<summary>Solution</summary>
This is the solution to the first exercise.
</details>
#### Exercise 2
What is the solution to the second exercise?
<details>
<summary>Solution</summary>
This is the solution to the second exercise.
</details>
...@@ -9,23 +9,13 @@ ...@@ -9,23 +9,13 @@
<ul class="contact-list"> <ul class="contact-list">
<li>{{ site.title }}</li> <li>{{ site.title }}</li>
<li><a href="mailto:{{ site.email }}">{{ site.email }}</a></li> <li><a href="mailto:{{ site.email }}">{{ site.email }}</a></li>
<li><a href="https://git.embl.de/grp-bio-it/image-analysis-training-resources/">Source code</a></li>
<li><a href="{{site.contributing | relative_url }}">Contributions to this material are very welcome.</a></li>
</ul> </ul>
</div> </div>
<div class="footer-col footer-col-2"> <div class="footer-col footer-col-2">
<ul class="social-media-list">
{% if site.github_username %}
<li>
{% include icon-github.html username=site.github_username %}
</li>
{% endif %}
{% if site.twitter_username %}
<li>
{% include icon-twitter.html username=site.twitter_username %}
</li>
{% endif %}
</ul>
</div> </div>
<div class="footer-col footer-col-3"> <div class="footer-col footer-col-3">
......
...@@ -9,4 +9,6 @@ ...@@ -9,4 +9,6 @@
<link rel="stylesheet" href="{{ "/css/main.css" | prepend: site.baseurl }}"> <link rel="stylesheet" href="{{ "/css/main.css" | prepend: site.baseurl }}">
<link rel="canonical" href="{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}"> <link rel="canonical" href="{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}">
<link rel="alternate" type="application/rss+xml" title="{{ site.title }}" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}"> <link rel="alternate" type="application/rss+xml" title="{{ site.title }}" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}">
<script src="https://unpkg.com/mermaid@8.0.0/dist/mermaid.min.js"></script>
<script>mermaid.initialize({startOnLoad:true});</script>
</head> </head>
---
layout: default
---
<article class="module">
{% assign first = false %}
{% if page.activities or page.exercises %}
<script language="javascript" type="text/javascript">
function set_view_defaults() {
set_activity_view_defaults();
set_exercises_view_defaults();
}
function set_activity_view_defaults() {
{% assign first = true %}
{% endif %}
{% for platform in page.activities %}
document.getElementById("{{ platform[0] | slugify }}-activity-div").style.display = 'none';
{% if first %}
document.getElementById("{{ platform[0] | slugify }}-activity-div").style.display = 'block';
{% assign first = false %}
{% endif %}
{% endfor %}
{% if page.activities or page.exercises %}
};
function change_activity_content_by_platform(form_control){
{% assign first = true %}
{% endif %}
{% for platform in page.activities %}
document.getElementById("{{ platform[0] | slugify }}-activity-div").style.display = 'none';
{% endfor %}
{% for platform in page.activities %}
{% if first %}
if (!form_control || document.getElementById(form_control).value == "{{ platform[0] | slugify }}-activity") {
set_activity_view_defaults();
{% assign first = false %}
{% else %}
} else if (document.getElementById(form_control).value == "{{ platform[0] | slugify }}-activity") {
document.getElementById("{{ platform[0] | slugify }}-activity-div").style.display = 'block';
{% endif %}
{% endfor %}
{% if page.activities %}
} else {
alert("Error: Missing platform value for 'change_activity_content_by_platform()' script!");
}
{% endif %}
{% if page.activities or page.exercises %}
}
{% assign first = false %}
function set_exercises_view_defaults() {
{% assign first = true %}
{% endif %}
{% for platform in page.exercises %}
document.getElementById("{{ platform[0] | slugify }}-exercises-div").style.display = 'none';
{% if first %}
document.getElementById("{{ platform[0] | slugify }}-exercises-div").style.display = 'block';
{% assign first = false %}
{% endif %}
{% endfor %}
{% if page.activities or page.exercises %}
};
function change_exercises_content_by_platform(form_control){
{% assign first = true %}
{% endif %}
{% for platform in page.exercises %}
document.getElementById("{{ platform[0] | slugify }}-exercises-div").style.display = 'none';
{% endfor %}
{% for platform in page.exercises %}
{% if first %}
if (!form_control || document.getElementById(form_control).value == "{{ platform[0] | slugify }}-exercises") {
set_exercises_view_defaults();
{% assign first = false %}
{% else %}
} else if (document.getElementById(form_control).value == "{{ platform[0] | slugify }}-exercises") {
document.getElementById("{{ platform[0] | slugify }}-exercises-div").style.display = 'block';
{% endif %}
{% endfor %}
{% if page.exercises %}
} else {
alert("Error: Missing platform value for 'change_exercises_content_by_platform()' script!");
}
{% endif %}
{% if page.activities or page.exercises %}
}
window.onload = set_view_defaults;
</script>
{% endif %}
<header class="post-header">
<h1 class="post-title">{{ page.title }}</h1>
</header>
{% if page.prerequisites %}
<div class="prerequisites">
<h2>Prerequisites</h2>
Before starting this lesson, you should be familiar with:
<ul>
{% for prereq in page.prerequisites %}
<li>{{ prereq | markdownify }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="learning-objectives">
<h2>Learning Objectives</h2>
After completing this lesson, learners should be able to:
<ul>
{% for objective in page.objectives %}
<li>{{ objective | markdownify }}</li>
{% endfor %}
</ul>
</div>
<h2>Motivation</h2>
{{ page.motivation | markdownify }}
<h2>Concept map</h2>
<div class="mermaid">
{{ page.concept_map }}
</div>
<h2>Example</h2>
<figure>
<img src="{{ page.figure | relative_url }}">
{% if page.figure_legend %}
<figcaption>{{ page.figure_legend }}</figcaption>
{% endif %}
</figure>
<div class="module-content">
{{ content }}
</div>
<h2>Activity</h2>
{% if page.activity_preface %}
{{ page.activity_preface | markdownify }}
{% endif %}
{% if page.activities %}
Choose a platform to display instructions for: <select id="id_activity_platform" name="activityplatformlist" onchange="change_activity_content_by_platform('id_activity_platform');return false;">
{% assign first = true %}
{% endif %}
{% for platform in page.activities %}
{% if first %}
<option value="{{ platform[0] | slugify }}-activity" id="{{ platform[0] | slugify }}-activity-option" selected="selected"> {{ platform[0] }} </option>
{% assign first = false %}
{% else %}
<option value="{{ platform[0] | slugify }}-activity" id="{{ platform[0] | slugify }}-activity-option"> {{ platform[0] }} </option>
{% endif %}
{% endfor %}
{% if page.activities %}
</select>
{% endif %}
{% for platform in page.activities %}
<div id="{{ platform[0] | slugify }}-activity-div">
<h3>{{ platform[0] }}</h3>
{% assign includefile = platform[1] %}
{% capture activity %}{% include {{ includefile }} %}{% endcapture %}
{{ activity | markdownify }}
</div>
{% endfor %}
{% if page.exercises_preface or page.exercises %}
<h2>Formative assessment</h2>
{% endif %}
{% if page.exercises_preface %}
{{ page.exercises_preface | markdownify }}
{% endif %}
{% if page.exercises %}
Choose a platform to display instructions for: <select id="id_exercises_platform" name="exercisesplatformlist" onchange="change_exercises_content_by_platform('id_exercises_platform');return false;">
{% assign first = true %}
{% endif %}
{% for platform in page.exercises %}
{% if first %}
<option value="{{ platform[0] | slugify }}-exercises" id="{{ platform[0] | slugify }}-exercises-option" selected="selected"> {{ platform[0] }} </option>
{% assign first = false %}
{% else %}
<option value="{{ platform[0] | slugify }}-exercises" id="{{ platform[0] | slugify }}-exercises-option"> {{ platform[0] }} </option>
{% endif %}
{% endfor %}
{% if page.exercises %}
</select>
{% endif %}
{% for platform in page.exercises %}
<div id="{{ platform[0] | slugify }}-exercises-div">
<h3>{{ platform[0] }}</h3>
{% assign includefile = platform[1] %}
{% capture exercise %}{% include {{ includefile }} %}{% endcapture %}
{{ exercise | markdownify }}
</div>
{% endfor %}
<h2>Follow-up material</h2>
<ul>
{% for follow_up in page.learn_next %}
<li>{{ follow_up | markdownify }}</li>
{% endfor %}
</ul>
<h2>Learn more</h2>
<ul>
{% for external_link in page.external_links %}
<li>{{ external_link | markdownify }}</li>
{% endfor %}
</ul>
</article>
--- ---
title: Image binarization title: Image binarization
layout: page layout: module
permalink: /binarization prerequisites:
- "the concepts of image files, pixels, and intensity"
- "something else __that__ `requires` _formatting_"
objectives:
- "describe the relationship between an intensity image and a derived binary image"
- "use thresholding to distinguish foreground and background pixels"
motivation: >
A description of *why* you would want to learn this.
Can be written in
(GitHub-flavoured) [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)
and split
across
multiple
lines.
concept_map: >
graph TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car];
figure: /figures/binarization.png
figure_legend: Some description of the figure (optional)
activity_preface: >
Open an image and binarize it by applying a threshold.
activities:
"ImageJ GUI": "binarization/activities/binarization_imagejgui.md"
"ImageJ Macro": "binarization/activities/binarization_imagejmacro.md"
"Jython": "binarization/activities/binarization_jython.md"
"MATLAB": "binarization/activities/binarization_matlab.md"
exercises_preface: >
You could put general, language-agnostic questions here...
exercises:
"ImageJ GUI": "binarization/exercises/binarization_imagejgui.md"
"ImageJ Macro": "binarization/exercises/binarization_imagejmacro.md"
"Jython": "binarization/exercises/binarization_jython.md"
"MATLAB": "binarization/exercises/binarization_matlab.md"
learn_next:
- "[name_of_one](calibration)"
- "[or_more_modules](display)"
- "[to link to next](filter_convolution)"
external_links:
- "[link to](https://external.page.com)"
--- ---
# Image binarization
## Requirements
To understand this episode you need to know:
- A
- B
- C
## Motivation
Few sentences.
## Learning objectives
- Understand the relationship between an intensity image and a derived binary image.
- Execute binarization on an image.
## Concept map
<img src='https://g.gravizo.com/svg?
digraph G {
shift [fontcolor=white,color=white];
"pixel values" -> "foreground\n1,255" [label = " >= threshold"];
"pixel values" -> "background\n0" [label = " < threshold"];
"foreground\n1,255" -> "binarised pixel values"
"background\n0" -> "binarised pixel values"
}
'/>
## Example
![binarization_figure_00](/figures/binarization_concept_example.png)
## Activity
Open an image and binarize it by applying a threshold.
<details>
<summary>ImageJ user interface</summary>
- **[ Open... ]** "/image-analysis-training-resources/image_data/xy_8bit__two_cells.tif" <br/>
- **[ Threshold... ]**
</details>
<details>
<summary>ImageJ macro</summary>
```
open("/image-analysis-training-resources/image_data/xy_8bit__two_cells.tif");
setThreshold(30, 255);
setOption("BlackBackground", true);
run("Convert to Mask");
```
</details>
<details>
<summary>Jython script</summary>
```python
from ij import IJ, ImagePlus
from ij.plugin import Thresholder
inputImage=IJ.getImage()
IJ.setRawThreshold(inputImage, 60, 255, None)
binaryImage=ImagePlus('Binary image',Thresholder.createMask(inputImage))
binaryImage.show()
```
</details>
<details>
<summary>MATLAB Script</summary>
```matlab
function src_binarize_image()
%This function illustrates separating foreground from background using a
%fixed threshold value
threshold = 50; %example hreshold value
%Read input image
in_image = imread(['image_data' filesep 'xy_8bit__two_cells.tif']);
figure; imagesc(in_image); %display input image
%Binarized input image with the threshold value;
bin_image = uint8(in_image>= threshold);
figure; imagesc(bin_image) % display binary image
end
```
</details>
## Formative assessment
Quizz or something
## Follow-up material
- [http:// ](next module in this repo)
## Learn more
External links...
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment