# Period and cell of a regular cube

The grid a regular cube agrees on: the tiles in their projection, the region as cells, one cell over the pixels of the bands, and the intervals of the period.

[From step 3 of Building data cubes from image collections](/regular-cubes.md).

In the sits book: [Building regular data cubes](https://e-sensing.github.io/sitsbook/dc_regularize.html).

Choose the period and the cell size of sits_regularize() and see the cells of each tile, the pixels under one cell and the intervals of the timeline change.

## The figure

Tile bounds and cell grids as the pipeline's runs of sits_regularize() wrote them over the region; the pictures are their first regular images of the book's period. The cube view is written from sits' source, its extent shortened.

The figure (recorded: 9 runs of sits_regularize(), 3 periods at 3 cell sizes) at its last beat: the tiles 20LKP and 20LLP in EPSG:32720, the region cut out of each as a grid of cells, one cell over the pixels of the bands, the images on a time axis with the intervals of the period, and the cube view sits asks gdalcubes for. Pills choose the period and the cell size.

Cells of the region per tile, and where the cells lie on the pixels of each band size:

| Cell | 20LKP cells | 20LLP cells | On the 10 m pixels (B02) | On the 20 m pixels (B8A and B11)    |
| ---- | ----------- | ----------- | ------------------------ | ----------------------------------- |
| 20 m | 745 × 400   | 512 × 400   | 20LKP on and 20LLP on    | 20LKP on and 20LLP on               |
| 40 m | 372 × 200   | 256 × 200   | 20LKP on and 20LLP on    | 20LKP off by 10 m in x and 20LLP on |
| 80 m | 186 × 100   | 128 × 100   | 20LKP on and 20LLP on    | 20LKP off by 10 m in x and 20LLP on |

The timeline and intervals of each period (an interval ends on the day written):

| Period | Dates | Intervals                                                                                                                                                                            | Images outside the timeline               |
| ------ | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------- |
| P8D    | 7     | 2018-07-03 to 2018-07-10; 2018-07-11 to 2018-07-18; 2018-07-19 to 2018-07-26; 2018-07-27 to 2018-08-03; 2018-08-04 to 2018-08-11; 2018-08-12 to 2018-08-19; 2018-08-20 to 2018-08-27 | 20LLP: 2018-06-30, 2018-06-30, 2018-08-29 |
| P16D   | 4     | 2018-07-03 to 2018-07-18; 2018-07-19 to 2018-08-03; 2018-08-04 to 2018-08-19; 2018-08-20 to 2018-09-04                                                                               | 20LLP: 2018-06-30, 2018-06-30             |
| P1M    | 2     | 2018-07-01 to 2018-07-31; 2018-08-01 to 2018-08-31                                                                                                                                   | 20LLP: 2018-06-30, 2018-06-30             |

The cube view of the book's call:

```r
cube_view(extent = list(<tile ∩ roi>, t0 = date, t1 = date),
          srs = "EPSG:32720",
          dt = "P16D", dx = 40, dy = 40,
          aggregation = "first", resampling = "bilinear")
```

### How it was made

1. Ask the catalogue: sits asks the provider's catalogue which images cover the book's tiles, bands and dates, and a whole year of one tile. The answers are kept, so every later run uses the same list.
2. Find the tiles: The pipeline finds the tiles of the satellite's grid around the region, from the grid that comes with sits. It reads a small picture of each tile of the cube from its least cloudy image.
3. Build the regular cube: sits makes a regular cube of the region from those images: one image per period, all on the same grid of pixels. For each pixel of a period it takes the first valid value, least cloudy image first.
4. Read the images as they come: The pipeline reads the images the catalogue listed, as they come. It marks each pixel as having no data, a clear value, or a value sits masks, such as cloud or shadow.
5. Try other periods and pixel sizes: sits makes the regular cube again at other periods and pixel sizes. It also makes it once without the images' cloud cover, so sits takes the images in date order, not least cloudy first.
6. Read each image alone: Each image is read alone, on the grid sits builds for it. Stacked in the order sits takes them, the images show which one gave each pixel of the regular cube.
7. Check against sits: The pipeline compares its own reads with what sits made, and stops the run on the checks that must hold. The results are gathered only once those checks pass.
8. Prepare the pictures: The pipeline picks the brightness drawn black and white, the same for every date, so the dates can be compared. Values are packed into one byte each.
9. Write the files: The pipeline writes the files the website reads, each with a record of its sources and of how closely a rerun repeats it.

### Reproducibility details

- A rerun on aarch64-apple-darwin23 gave the same files, byte for byte.

Every step of the pipeline:

1. Lists the bands read: the book's and those of the natural-colour pictures, in the order sits has them. `cube_read_bands("AWS", "SENTINEL-2-L2A", c("B02", "B8A", "B11"), c("B03", "B04"))`
2. Lists every period with every resolution of the runs. `regularize_choices(c("P8D", "P16D", "P1M"), c(20L, 40L, 80L))`
3. The arguments of the book's call to sits_cube(). `cube_call(list(source = "AWS", collection = "SENTINEL-2-L2A", tiles = c("20LKP", "20LLP"), bands = c("B02", "B8A", "B11" ), picture_bands = c("B03", "B04"), cloud_band = "CLOUD", start_date = "2018-06-30", end_date = "2018-08-31", period = "P16D", res = 40L, region = list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), year = list( tile = "20LLP", start_date = "2018-01-01", end_date = "2018-12-31", window = 12L), multicores = 4L, rgb = list(red = "B04", green = "B03", blue = "B02"), stretch = c(0.02, 0.98), levels = 32L, quantiles = c(0.001, 0.999), map = list(around_km = 100L, overview = 3L)), cube_bands)`
4. The same call for one tile over a whole year. `cube_call(list(source = "AWS", collection = "SENTINEL-2-L2A", tiles = c("20LKP", "20LLP"), bands = c("B02", "B8A", "B11" ), picture_bands = c("B03", "B04"), cloud_band = "CLOUD", start_date = "2018-06-30", end_date = "2018-08-31", period = "P16D", res = 40L, region = list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), year = list( tile = "20LLP", start_date = "2018-01-01", end_date = "2018-12-31", window = 12L), multicores = 4L, rgb = list(red = "B04", green = "B03", blue = "B02"), stretch = c(0.02, 0.98), levels = 32L, quantiles = c(0.001, 0.999), map = list(around_km = 100L, overview = 3L)), cube_bands, "20LLP", "2018-01-01", "2018-12-31")`
5. Lists the bands of the runs: the natural-colour ones, in the order sits has them. `regularize_run_bands(cube_bands, list(red = "B04", green = "B03", blue = "B02"))`
6. Lists the images of the book's call with sits_cube(): a copy of the live AWS catalogue, kept in cache/cubes/ and read from there. `cube_kept_listing(cube_book_call, "cache/cubes", "cube_book")`
7. Lists the images of the year's call with sits_cube(): a copy of the live AWS catalogue, kept in cache/cubes/ and read from there. `cube_kept_listing(cube_year_call, "cache/cubes", "cube_year")`
8. Reads how sits masks the cloud band, and the line of its source file that says so. `collection_cloud_source("cache/src/sits-78d26eb07370874192911854b48b60ebb1d668c8", "AWS", "SENTINEL-2-L2A", "CLOUD", regularize_bands)`
9. Makes the regular cube of the book's call over the region with sits_regularize(), keeping the files already made. `cube_regularize(cube_listing, list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), "P16D", 40L, "cache/cubes/reg_book_B02-B03-B04-B8A-B11", 4L)`
10. Finds the Sentinel-2 tiles around the region. `cube_images_grid(list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), cube_listing, 100L)`
11. Reads a small picture of each tile from the overview of its clearest image, keeping the reads in cache/cubes/. `cube_images_read(cube_listing, list(red = "B04", green = "B03", blue = "B02"), 3L, "cache/cubes")`
12. Makes the regular cube of the year with sits_regularize(), keeping the files already made. `cube_regularize(cube_year_listing, list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), "P16D", 40L, "cache/cubes/reg_year_B02-B03-B04-B8A-B11", 4L)`
13. Reads one tile whole on the date of the book's figure, from an overview, keeping the read in cache/regularize/. `regularize_images_coverage(cube_listing, list(tile = "20LLP", date = "2018-06-30"), list(red = "B04", green = "B03", blue = "B02"), 3L, "cache/regularize")`
14. Runs sits_regularize() on the book's images at one period and resolution, keeping the files in cache/regularize/. `regularize_run_cube(cube_listing, regularize_choice, regularize_bands, "CLOUD", list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), "cache/regularize", 4L, 1L)`
15. Reads every image of each tile over the tile's part of the region, as it comes, keeping the reads in cache/cubes/. `cube_tile_images(cube_listing, cube_book, cube_book_call, 40L, "EPSG:32720", "cache/cubes")`
16. Compares the grid of each tile of the book's run with the view sits builds for it. `regularize_book_grids(regularize_find_run(regularize_run, "P16D", 40L), cube_listing, list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L))`
17. Reads the regular images each run wrote. `regularize_values(regularize_run, regularize_bands)`
18. Gathers the images, ranked in the order sits takes them, the regular values, the year and the map. `cube_export_gather(cube_listing, cube_book, cube_images, cube_year_listing, cube_year, cube_map_images, cube_map_grid, cube_book_call, list(source = "AWS", collection = "SENTINEL-2-L2A", tiles = c("20LKP", "20LLP"), bands = c("B02", "B8A", "B11"), picture_bands = c("B03", "B04"), cloud_band = "CLOUD", start_date = "2018-06-30", end_date = "2018-08-31", period = "P16D", res = 40L, region = list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), year = list(tile = "20LLP", start_date = "2018-01-01", end_date = "2018-12-31", window = 12L), multicores = 4L, rgb = list(red = "B04", green = "B03", blue = "B02"), stretch = c(0.02, 0.98), levels = 32L, quantiles = c(0.001, 0.999), map = list(around_km = 100L, overview = 3L)), 40L)`
19. Marks each pixel of each image as no data, clear or masked by sits. `purrr::map(cubes_record$tiles, cube_images_states, cubes_record$cloud_values)`
20. Picks the reflectance drawn black and white, one for red, green and blue. `cube_images_stretch(cubes_record, list(red = "B04", green = "B03", blue = "B02"), c(0.02, 0.98))`
21. Stores the year in one byte per value, each band between two percentiles. `cube_export_year_codes(cubes_record$year$values, c(0.001, 0.999))`
22. Reads each image of the book's periods alone, on the view sits builds for it with no mask, keeping the reads in cache/regular_cubes/. `cube_alone_book_reads(cube_listing, cubes_record, "B02", list(source = "AWS", collection = "SENTINEL-2-L2A", tiles = c("20LKP", "20LLP"), bands = c("B02", "B8A", "B11"), picture_bands = c("B03", "B04"), cloud_band = "CLOUD", start_date = "2018-06-30", end_date = "2018-08-31", period = "P16D", res = 40L, region = list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), year = list(tile = "20LLP", start_date = "2018-01-01", end_date = "2018-12-31", window = 12L), multicores = 4L, rgb = list(red = "B04", green = "B03", blue = "B02"), stretch = c(0.02, 0.98), levels = 32L, quantiles = c(0.001, 0.999), map = list(around_km = 100L, overview = 3L)), "cache/regular_cubes/alone_book_B02", "/Users/felipecarlos/Documents/sits/sits-embeddings/pipeline/cache/tmp", 0.5)`
23. Runs sits_regularize() on the book's call with the scene cloud cover removed, keeping the result in cache/regular_cubes/. `cube_checks_copied_run(cube_listing, "B02", list(source = "AWS", collection = "SENTINEL-2-L2A", tiles = c("20LKP", "20LLP" ), bands = c("B02", "B8A", "B11"), picture_bands = c("B03", "B04"), cloud_band = "CLOUD", start_date = "2018-06-30", end_date = "2018-08-31", period = "P16D", res = 40L, region = list( crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), year = list(tile = "20LLP", start_date = "2018-01-01", end_date = "2018-12-31", window = 12L), multicores = 4L, rgb = list(red = "B04", green = "B03", blue = "B02"), stretch = c(0.02, 0.98), levels = 32L, quantiles = c(0.001, 0.999), map = list( around_km = 100L, overview = 3L)), cubes_record, "cache/regular_cubes", "/Users/felipecarlos/Documents/sits/sits-embeddings/pipeline/cache/tmp")`
24. Reads the grid of the region on each tile at each resolution from the runs of the book's period. `cube_checks_region_grids(cube_listing, regularize_run, cubes_record, list(source = "AWS", collection = "SENTINEL-2-L2A", tiles = c("20LKP", "20LLP"), bands = c("B02", "B8A", "B11"), picture_bands = c("B03", "B04"), cloud_band = "CLOUD", start_date = "2018-06-30", end_date = "2018-08-31", period = "P16D", res = 40L, region = list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), year = list(tile = "20LLP", start_date = "2018-01-01", end_date = "2018-12-31", window = 12L), multicores = 4L, rgb = list(red = "B04", green = "B03", blue = "B02"), stretch = c(0.02, 0.98), levels = 32L, quantiles = c(0.001, 0.999), map = list(around_km = 100L, overview = 3L)), c(20L, 40L, 80L))`
25. Runs sits_regularize() on one image alone and gdalwarp at three overview choices, keeping the result in cache/regular_cubes/. `cube_checks_overview_check_run(cube_listing, cubes_record, list(tile = "20LLP", band = "B02"), list(source = "AWS", collection = "SENTINEL-2-L2A", tiles = c("20LKP", "20LLP" ), bands = c("B02", "B8A", "B11"), picture_bands = c("B03", "B04"), cloud_band = "CLOUD", start_date = "2018-06-30", end_date = "2018-08-31", period = "P16D", res = 40L, region = list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), year = list(tile = "20LLP", start_date = "2018-01-01", end_date = "2018-12-31", window = 12L), multicores = 4L, rgb = list(red = "B04", green = "B03", blue = "B02"), stretch = c(0.02, 0.98 ), levels = 32L, quantiles = c(0.001, 0.999), map = list( around_km = 100L, overview = 3L)), "cache/regular_cubes", "/Users/felipecarlos/Documents/sits/sits-embeddings/pipeline/cache/tmp")`
26. Reads the same image alone in natural colour and runs sits_regularize() on it with those bands. `cube_checks_pictures_check_run(cube_listing, cubes_record, list(tile = "20LLP", band = "B02"), regularize_bands, list( source = "AWS", collection = "SENTINEL-2-L2A", tiles = c("20LKP", "20LLP"), bands = c("B02", "B8A", "B11"), picture_bands = c("B03", "B04"), cloud_band = "CLOUD", start_date = "2018-06-30", end_date = "2018-08-31", period = "P16D", res = 40L, region = list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), year = list(tile = "20LLP", start_date = "2018-01-01", end_date = "2018-12-31", window = 12L), multicores = 4L, rgb = list(red = "B04", green = "B03", blue = "B02"), stretch = c(0.02, 0.98 ), levels = 32L, quantiles = c(0.001, 0.999), map = list( around_km = 100L, overview = 3L)), "cache/regular_cubes", "/Users/felipecarlos/Documents/sits/sits-embeddings/pipeline/cache/tmp")`
27. Pairs the cells of the strip both tiles cover. `cube_checks_book_strip(cubes_record, c("20LKP", "20LLP" ), 40L)`
28. Runs sits_regularize() on each image of the year alone, with the date of its period, keeping the files in cache/regularize/. `regularize_year_alone(cube_year_listing, cubes_record, "B02", "CLOUD", list(source = "AWS", collection = "SENTINEL-2-L2A", tiles = c("20LKP", "20LLP"), bands = c("B02", "B8A", "B11"), picture_bands = c("B03", "B04"), cloud_band = "CLOUD", start_date = "2018-06-30", end_date = "2018-08-31", period = "P16D", res = 40L, region = list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), year = list(tile = "20LLP", start_date = "2018-01-01", end_date = "2018-12-31", window = 12L), multicores = 4L, rgb = list(red = "B04", green = "B03", blue = "B02"), stretch = c(0.02, 0.98), levels = 32L, quantiles = c(0.001, 0.999), map = list(around_km = 100L, overview = 3L)), "cache/regularize/year_20llp_B02", 1L)`
29. Stops the run unless the book's run gives the regular cube of the book, value for value. `regularize_check_book(regularize_run_values, cubes_record, "P16D", 40L, regularize_bands)`
30. Reads a small square at the native resolution of two bands, keeping the read in cache/regularize/. `regularize_images_patch(cube_listing, cubes_record, list(tile = "20LLP", side = 480L, bands = c("B04", "B11")), "CLOUD", "cache/regularize")`
31. Stacks the images of each period in sits' order and finds the one each pixel came from. `cube_alone_book_stacks(regular_cubes_book_reads, cubes_record, "B02")`
32. Compares the run with no scene cloud cover with the book's regular cube, after checking it against the images read alone. `cube_checks_copied_entries(regular_cubes_copied_run, cubes_record, regular_cubes_book_reads, cube_listing, "B02")`
33. Compares the two tiles' regular images where they overlap. `cube_checks_overlap_periods(cubes_record, regular_cubes_strip, "B02")`
34. Stops the run unless gdalwarp -ovr AUTO and the images read alone give sits' values on every pixel. `cube_checks_check_overview(regular_cubes_overview, regular_cubes_book_reads, regular_cubes_pictures)`
35. Draws one tile's images as they come and its regular images, small, for the journey's picture. `cube_checks_export_picture(cubes_record, cube_states, list(red = "B04", green = "B03", blue = "B02"), cube_stretch, 32L, list(tile = "20LLP", card_tile = 64L, sheet_tile = 192L))`
36. Finds which image gives each pixel of each period of the year, in the order sits takes them. `regularize_year_sources(regularize_alone, "20LLP", "B02")`
37. Draws the regular images sits made of the tile, one per date, for the website. `site_write_png(cube_images_regular_sheet(cubes_record$regular[["20LKP"]], cubes_record$bands, list(red = "B04", green = "B03", blue = "B02"), cube_stretch, 32L)$sheet, "../web/public/data/cube-regular-20lkp.png")`
38. Draws the regular images sits made of the tile, one per date, for the website. `site_write_png(cube_images_regular_sheet(cubes_record$regular[["20LLP"]], cubes_record$bands, list(red = "B04", green = "B03", blue = "B02"), cube_stretch, 32L)$sheet, "../web/public/data/cube-regular-20llp.png")`
39. Writes the book's call, its images and regular cube, the map and the year, for the website. ``site_write_json(cube_export_record(cubes_record, cube_states, cube_stretch, cube_year_codes, list(source = "AWS", collection = "SENTINEL-2-L2A", tiles = c("20LKP", "20LLP"), bands = c("B02", "B8A", "B11"), picture_bands = c("B03", "B04"), cloud_band = "CLOUD", start_date = "2018-06-30", end_date = "2018-08-31", period = "P16D", res = 40L, region = list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), year = list(tile = "20LLP", start_date = "2018-01-01", end_date = "2018-12-31", window = 12L), multicores = 4L, rgb = list(red = "B04", green = "B03", blue = "B02"), stretch = c(0.02, 0.98), levels = 32L, quantiles = c(0.001, 0.999), map = list(around_km = 100L, overview = 3L)), list(tiles = list(`20LKP` = list(ard = "cube-ard-20lkp.png", mask = "cube-ard-20lkp-mask.png", regular = "cube-regular-20lkp.png", map = "cube-map-20lkp.png"), `20LLP` = list(ard = "cube-ard-20llp.png", mask = "cube-ard-20llp-mask.png", regular = "cube-regular-20llp.png", map = "cube-map-20llp.png")), year = "cube-year.bin")), "../web/src/data/cubes.json")``
40. Stops the run unless the images read alone, stacked in sits' order, give the book's regular cube on every pixel. `cube_alone_check_book(regular_cubes_book, cubes_record, "B02", "cache/regular_cubes/alone_book_B02")`
41. Reads each image of the year alone in natural colour, with its cloud band, keeping the reads in cache/regular_cubes/. `cube_alone_year_reads(cube_year_listing, cubes_record, regularize_sources, regularize_bands, list(source = "AWS", collection = "SENTINEL-2-L2A", tiles = c("20LKP", "20LLP" ), bands = c("B02", "B8A", "B11"), picture_bands = c("B03", "B04"), cloud_band = "CLOUD", start_date = "2018-06-30", end_date = "2018-08-31", period = "P16D", res = 40L, region = list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), year = list(tile = "20LLP", start_date = "2018-01-01", end_date = "2018-12-31", window = 12L), multicores = 4L, rgb = list(red = "B04", green = "B03", blue = "B02"), stretch = c(0.02, 0.98 ), levels = 32L, quantiles = c(0.001, 0.999), map = list( around_km = 100L, overview = 3L)), "cache/regular_cubes/alone_year_20llp", "/Users/felipecarlos/Documents/sits/sits-embeddings/pipeline/cache/tmp", 0.5)`
42. Stops the run unless the images, stacked in sits' order, give the regular cube of the year. `regularize_check_year(regularize_sources, cubes_record)`
43. Stops the run unless the cloud band read here masks each image of the year as sits did. `cube_alone_check_year_cloud(regular_cubes_year_reads, regularize_alone, cubes_record$cloud_values, "cache/regular_cubes/alone_year_20llp")`
44. Gathers the runs, the images as they come and the sources of the year, once both self-checks pass. `regularize_export_gather(cube_listing, regularize_run_values, regularize_coverage, regularize_patch, regularize_sources, regularize_bands, list(regularize_book_check, regularize_year_check))`
45. Gathers the grids, the sources of the book's pixels, the overview, the run with no cloud cover and the year, once the self-checks pass. `cube_checks_export_gather(regular_cubes_grids, regular_cubes_book, regular_cubes_strip, regular_cubes_overlap, regular_cubes_overview, regular_cubes_copied, regular_cubes_year_reads, list(regular_cubes_book_check, regular_cubes_overview_check, regular_cubes_cloud_check))`
46. Writes the runs, the images as they come, the sources of the year and how sits masks clouds, for the website. ``site_write_json(regularize_export_record(regularize_record, cubes_record, regularize_cloud, regularize_grids, list(coverage = "regularize-coverage.png", patch = list(B04 = "regularize-patch-b04.png", B11 = "regularize-patch-b11.png"), runs = list(run_p16d_40m = list(`20LKP` = "cube-regular-20lkp.png", `20LLP` = "cube-regular-20llp.png"), run_p16d_20m = list(`20LKP` = "regularize-run-p16d-20m-20lkp.png", `20LLP` = "regularize-run-p16d-20m-20llp.png"), run_p16d_80m = list(`20LKP` = "regularize-run-p16d-80m-20lkp.png", `20LLP` = "regularize-run-p16d-80m-20llp.png")), sheets = list(list(period = "P16D", res = 20L), list(period = "P16D", res = 80L)), sources = "regularize-sources.bin")), "../web/src/data/regularize.json")``
47. Draws the regular images of one run of one tile, one per date, for the website. `site_write_png(regularize_export_run_sheet(regularize_find_run(regularize_record$runs, "P16D", 20L), "20LKP", regularize_bands, list(red = "B04", green = "B03", blue = "B02"), cube_stretch, 32L)$sheet, "../web/public/data/regularize-run-p16d-20m-20lkp.png")`
48. Draws the regular images of one run of one tile, one per date, for the website. `site_write_png(regularize_export_run_sheet(regularize_find_run(regularize_record$runs, "P16D", 20L), "20LLP", regularize_bands, list(red = "B04", green = "B03", blue = "B02"), cube_stretch, 32L)$sheet, "../web/public/data/regularize-run-p16d-20m-20llp.png")`
49. Draws the regular images of one run of one tile, one per date, for the website. `site_write_png(regularize_export_run_sheet(regularize_find_run(regularize_record$runs, "P16D", 80L), "20LKP", regularize_bands, list(red = "B04", green = "B03", blue = "B02"), cube_stretch, 32L)$sheet, "../web/public/data/regularize-run-p16d-80m-20lkp.png")`
50. Draws the regular images of one run of one tile, one per date, for the website. `site_write_png(regularize_export_run_sheet(regularize_find_run(regularize_record$runs, "P16D", 80L), "20LLP", regularize_bands, list(red = "B04", green = "B03", blue = "B02"), cube_stretch, 32L)$sheet, "../web/public/data/regularize-run-p16d-80m-20llp.png")`
51. Writes the grids, the sources of the book's pixels, the overview, the run with no cloud cover and the year, for the website. `site_write_json(cube_checks_export_record(regular_cubes_record, cubes_record, regularize_sources, regular_cubes_picture, list(source = "AWS", collection = "SENTINEL-2-L2A", tiles = c("20LKP", "20LLP"), bands = c("B02", "B8A", "B11"), picture_bands = c("B03", "B04"), cloud_band = "CLOUD", start_date = "2018-06-30", end_date = "2018-08-31", period = "P16D", res = 40L, region = list(crs = "EPSG:32720", xmin = 294880L, xmax = 310240L, ymin = 8840000L, ymax = 8848000L), year = list(tile = "20LLP", start_date = "2018-01-01", end_date = "2018-12-31", window = 12L), multicores = 4L, rgb = list(red = "B04", green = "B03", blue = "B02"), stretch = c(0.02, 0.98), levels = 32L, quantiles = c(0.001, 0.999), map = list(around_km = 100L, overview = 3L)), "B02", list(ranks = "regular-cubes-book-ranks.bin", cards = "regular-cubes-picture-cards-20llp.png", sheets = "regular-cubes-picture-sheets-20llp.png")), "../web/src/data/regular-cubes.json")`

The files:

- `regular-cubes.json`: SHA-256 `751974674c0e71d20c1054ce3e79129531244a10501768116130594eea997323`. A rerun on aarch64-apple-darwin23 gave the same file, byte for byte.
- `regularize.json`: SHA-256 `880aaea58eae1cb95f1780d87cdb6fec7a34e99ab7eaaf1fe5aa8f5c5fe0ce6d`. A rerun on aarch64-apple-darwin23 gave the same file, byte for byte.
- `cubes.json`: SHA-256 `f29bb2e9135a6f824c0d512868ea1c3d67bd2532c285b6662f87926e071d5874`. A rerun on aarch64-apple-darwin23 gave the same file, byte for byte.
- `cube-regular-20lkp.png`: SHA-256 `04f081ce4387b725b64ceda711778ece73aac4016074f4caf05a57e80d3d5480`. A rerun on aarch64-apple-darwin23 gave the same file, byte for byte.
- `cube-regular-20llp.png`: SHA-256 `2bedbff2a14c1f5a7b02f42a882e2b54f10f8fc9c97338076977bde0eb839820`. A rerun on aarch64-apple-darwin23 gave the same file, byte for byte.
- `regularize-run-p16d-20m-20lkp.png`: SHA-256 `4bd4a015549fdb05e3fb41e87c361dc0772171ee41ace099645bbae90ba6cc2f`. A rerun on aarch64-apple-darwin23 gave the same file, byte for byte.
- `regularize-run-p16d-20m-20llp.png`: SHA-256 `c495a2b592a81a5e21e5d885e72dc4eb1f9443592d53bf4441d4c95a0c32b8e2`. A rerun on aarch64-apple-darwin23 gave the same file, byte for byte.
- `regularize-run-p16d-80m-20lkp.png`: SHA-256 `fc6eb4a93592b5f989ed390d468bfa595c2c963e8f822def634067ec9eff0dde`. A rerun on aarch64-apple-darwin23 gave the same file, byte for byte.
- `regularize-run-p16d-80m-20llp.png`: SHA-256 `e0bbf6d11dfec56523a11029c309845ef39818776895522d05f97066047218fb`. A rerun on aarch64-apple-darwin23 gave the same file, byte for byte.

To make them again: `cd pipeline && Rscript make.R`.

## What to try

1. **Make the cell larger.** Press a larger cell size: each tile has fewer cells, the picture of the region coarsens, and more pixels of each band lie under one cell.
2. **Watch where a cell falls.** In the enlarged cell, the dashed lines are the edges of the coarser pixels. At some cell sizes a tile's cells sit on them; at others they fall between them.
3. **Change the period.** A shorter period cuts more intervals; a period of months starts the timeline on the first of the month. The images before the timeline stay outside it whatever the period.
