Commit bbd650c1 authored by Knut Behrends's avatar Knut Behrends
Browse files

improve assignment of realistic lithologies to cores (no upload yet)

parent 380bed30
let token = process.env.token || "BTEJmYlstdpCpVes7GecvPTm6AcAfvdh"
let token = process.env.token || "7wYyV6JWD4uri3eAPRdjOwJuaHcwXO8z"
let config = {
token: token,
endpoint: {
......
......@@ -14,6 +14,7 @@ const axutil = require("./axios-util.js")
const querystring = require("querystring")
const getopts = require("getopts")
const Util = require("./classes/fake-util.js")
const macrostrat_data = require("../data/macrotstrat-lithclasses-all.json")
const LithologyGeology = require("./classes/fake-lithology.js")
const util = new Util()
......@@ -26,7 +27,8 @@ const options = getopts(process.argv.slice(2), {
expedition: 10, //SAMP
},
})
//["lith_id","name","type","group","class","color","fill","t_units"]
const litho_data = macrostrat_data.success.data
//let core_url = "/api/v1/form?name=core&per-page=1&sort=-id"
//const core_info = options.infile ? JSON.parse(options.infile) : {}
const ax = axios.create(config.endpoint)
......@@ -160,100 +162,90 @@ Promise.all(queries_map.values())
}${exp_name}.)
########################################################################`)
let splits_by_site = groupBy(splits, "site_id")
let splits_by_hole = groupBy(splits, "hole_id")
let splits_by_cores = groupBy(splits, "core_id")
const splits_grouped = {
by_site: {
items: groupBy(splits, "site_id"),
proportions: [],
rock_types: {
igneous: [],
metamorphic: [],
sedimentary: [],
},
},
by_hole: {
items: groupBy(splits, "hole_id"),
proportions: [],
rock_types: {
igneous: [],
metamorphic: [],
sedimentary: [],
},
},
by_cores: {
items: groupBy(splits, "core_id"),
proportions: [],
rock_types: {
igneous: [],
metamorphic: [],
sedimentary: [],
},
},
}
// for each site, pick a set of proportion of igneous, metamorphic, sedimentary
for (let [k, split_collection] of Object.entries(splits_grouped)) {
split_collection.proportions = Object.entries(
split_collection.items
).map((v) => fake_main_composition(v))
split_collection.rock_types = Object.entries(
split_collection.items
).map((v, k) =>
sample_rock_classes(
litho_data,
split_collection.proportions[k].sort(by_proportion)
)
)
}
// for each site, pick one probabilities for of igneous, metamorphic, sedimentary
let { igneous, metamorphic, sedimentary } = assign3probs()
// for each hole, pick some {class: ..., group...} pairs from the most common
// make sure all cores from that site and hole get assigned rocks from that pair
// fetch a few units from this hole according to rock_class proportions
//assign 0-3 lithological descriptions to that split
// if 0, take last lithounit from previous split
//for 1-3 lithological units,
// for (let [core_id, split] of sections_by_cores.entries()) {
// let lithology_template = {} // get a new fake lithology
// // vary it through all
// if (!c.split_section.length) {
// let randsection = util
// .shuffle(Array.from(section_split_id_set.values()))
// .pop()
// // This step might pick "untouchable" "A" section-splits for sampling,
// // but that's okay. Correct manually later
// let sections_split_ids = Array.of(
// randsection - Math.trunc(Math.random() * 10),
// randsection,
// randsection + Math.trunc(Math.random() * 10)
// )
// c.split_section.push(
// splits.find((sp) =>
// sections_split_ids.some((ssi) => sp.id === ssi)
// )
// )
// }
// }
for (let [kc, core] of Object.entries(splits_grouped.by_cores)) {
for (let [ki, items] of Object.entries(core)) {
for (let split of item) {
let num_lithounits_per_split = util.shuffle([0, 1, 2, 3]).pop()
n = Math.floor(Math.random() * core.rock_types.length)
let lsp = core.rock_types.slice(n, n + num_lithounits_per_split)
// for (let c of lithounits_by_core.values()) {
// console.log({
// "city": c.city,
// "spli": c.split_section.map((v) => ({
// [v.id]: v.combined_id,
// })),
// "req": Array(c.requests.map((v) => v.request_id)).join(", "),
// })
// }
// })
// .then(() => {
// let curation_sample_columns = {}
// axutil.get_columns(ax, "curation_sample_2")
// .then((curation_sample) => {
// let fake_sample_data = []
// let i = 0
// for (let s of lithounits_by_core.values()) {
// // create an array of 0-10 requests per scientist,
// // assign a few echo sections_split(s) "reserved" for this team
// // (usually there are only 1-2 splits for this team)
// for (let sp of s.split_section){
// let n_picked = Number.parseInt(util.frac_below(0.666) * s.requests.length)
// let request_ids_per_city = util.shuffle(s.requests).slice(-n_picked)
// // ~ 5 requests for this split
// for (let r of request_ids_per_city) {
// let sec_len = sp.section_length ? sp.section_length : util.round(util.frac_above(0.5), 2)
// let fake_sample = new LithologyGeology(
// Object.assign({}, curation_sample, {
// request_id: r.request_id,
// request_no: `${r.request_no}`,
// scientist_1: r.scientist_1,
// scientist_2: r.scientist_2,
// scientist_3: r.scientist_3,
// section_split_id: sp.id,
// section_length_cm: util.round(((util.frac_below(0.1) * sec_len * 100) + 1),0),
// remarks: `SecId:${sp.section_id}, secLen ${util.round(sp.section_length,1)}m`,
// sample_date : Array.of(r.completion_date, r.approval_date,
// r.request_date, util.date_between()).find(d => d != null)
// }),
// sp
// ).fake()
// fake_sample_data.push(
// Object.assign({}, fake_sample)
// )
// i++
// }
// }
// }
// console.log(`Created ${i} fake lithology, will try to upload`)
// // console.log(fake_sample_data[0])
// return new Promise((resolve, reject) => {
// resolve(fake_sample_data), reject(fake_sample_data)
// })
// })
// .then((fake_sample_data) => {
// return fake_sample_data.flat().map((fake_sample, i) => {
// axutil.upload(
// ax,
// lithology_post_url,
// fake_sample,
// i
// )
// })
for (let s = 0; s < num_lithounits_per_split; s++) {
// let curation_sample_columns = {}
// axutil.get_columns(ax, "curation_sample_2")
// .then((curation_sample) => {
// let fake_sample_data = []
// let i = 0
// }
// }
// console.log(`Created ${i} fake lithology, will try to upload`)
// // console.log(fake_sample_data[0])
// return new Promise((resolve, reject) => {
// resolve(fake_sample_data), reject(fake_sample_data)
// })
// })
// .then((fake_sample_data) => {
// return fake_sample_data.flat().map((fake_sample, i) => {
// axutil.upload(
// ax,
// lithology_post_url,
// fake_sample,
// i
// )
// })
}
}
}
}
})
// .then((fake_request_promises) =>
// Promise.all(fake_request_promises).then((s) =>
......@@ -279,6 +271,22 @@ function str_sort_by_core_type(a, b) {
return 0
}
function by_type(a, b) {
let A = a.type.toUpperCase()
let B = b.type.toUpperCase()
if (A < B) {
return -1
}
if (A > B) {
return 1
}
return 0
}
function by_proportion(a, b) {
return b.proportion - a.proportion
}
// from MDN
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
function groupBy(objectArray, property) {
......@@ -292,8 +300,35 @@ function groupBy(objectArray, property) {
}, {})
}
function assign3probs() {
let probs = [util.frac_below(0.2) + 0.05, util.frac_above(0.3) - 0.05]
probs.push(1 - probs[0] - probs[1])
function fake_main_composition() {
let [igneous, metamorphic, sedimentary] = partition3()
let rock_class_proportion = [
{ rock_class: "igneous", proportion: igneous },
{ rock_class: "metamorphic", proportion: metamorphic },
{ rock_class: "sedimentary", proportion: sedimentary },
]
return rock_class_proportion
}
function partition3(prob1 = 0.2, prob2 = 0.3, min_prob = 0.05) {
let probs = [1, 1, 0]
let prob = util.frac_below(0.2) + min_prob
probs[0] = 1 - prob // 0.8x
probs[1] = util.frac_below(probs[0]) + min_prob
//probs[2] = 1 - probs[1]
return util.shuffle(probs).map((p) => util.round(p, 3))
}
function sample_rock_classes(litho_data, proportions) {
//["lith_id","name", "type", "group","class","color","fill","t_units"]
//[1, "siliciclastic","siliciclastic","", "sedimentary","#FFF400",670,198]
//{ rock_class: "sedimentary", proportion: 0.812 },
let selection = litho_data.map((_) => {
let thresh = Math.random()
let alt = util.shuffle(["igneous", "sedimentary", "metamorphic"]).pop()
return proportions.find((p) => p.proportion > thresh)?.rock_class || alt
})
return selection
.map((s) => util.shuffle(litho_data).find((rock) => rock.class == s))
.sort(by_type)
}
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