どのようにvueを利用してスペクトルフィッティングを実現しますか?
7547 ワード
ホームページの機能紹介
白さんは初めて職場に入りました。最初のまとめで、無駄話が多いです。軽く噴きますように。
スペクトルフィッティングはある種の材料または物質のスペクトルを識別し分析するために使用され、各物質には様々な成分があります。各成分はcomponent 1、component 2…で表しています。Add another componentとRemove componentで各成分の増加と削除を制御します。 nucleusは各成分の内原子核の数を制御し、一つの原子核を追加するとスペクトルが分裂し、スペクトルのピーク数は(1->2->>4->>8...)順に分裂します。また、デフォルトのパラメータを変更することにより、スペクトル形態を変更することができます。成分パラメータの中で:Relative amountは各成分が図形描画成分のパーセンテージを占めることを表します。百分率の和は100を超えません。gisoは分裂の中心位置を計算します。Line Widthはスペクトルピークからスペクトル谷までの幅を設定します。両者の和は100である。原子核パラメータ:No of equivalent nucleiは原子核の個数を変えるために使用され、一つの成分に複数の同じパラメータが含まれている場合、このパラメータを変更することにより、Nuclear spinは原子核の種類を変え、Hyperfineは分裂後の二つのピークの幅を設定するために使用されます。
もう一枚の図:
各成分の数とパラメータ、各成分内の原子数とパラメータを設定した後、データを処理し、3つの結果から、畳み込み、積分、二重積分を行います。データの処理ロジックを見てみましょう。
データの流れの角度から、主に3段階の処理を行います。データ->データの分裂->スペクトルの計算->図形描画、左はアルゴリズムの実現に必要なパラメータ、右はデータと各ステップの説明です。
コードの実装
つのピットに出会って、最初にdemoを書く時使うvue+Ant design of vueは、selectなどの他のコンポーネントの使用上は正常ですが、input numberの中では変態です。input numberに結び付けるchangeイベントは、ユーザーが2桁以上のデータを入力する時に、changeイベントが2回起こります。この問題を避けるためには、blurイベントを使って、問題がまた来ました。このページのコンポーネントの生成と削除には動的なレンダリングが必要です。また、前の紹介により、コンポーネントのレンダリングが二層構造であることが分かりやすくなりました。ユーザーがクリックまたは入力操作を行う時、一つのパラメータ(どのcomponentか、各componentの下に対応するnucleかなど)を渡す必要がありますが、能力には限りがあります。
コンポーネントのダイナミックレンダリングはより巧妙な方法を使っています。最初はレンダーで書くつもりでしたが、部門の大神さんからリストを通してレンダリングすることを教えられました。頭の間にはまだ差があります。
各パラメータのバインディング:componentではパラメータは一次元配列を使用しており、cheeイベントは一次元配列の下付きを伝達する必要があり、component内のnucleuiは二次元配列を使用しており、changeイベントは二次元配列の下付きを伝達する必要がある。
以上でパラメータ定義を紹介しましたが、次はデータ処理です。
ここで、vueを利用したスペクトルフィッティングの方法について紹介します。これまでの記事を検索したり、下記の関連記事を見たりしてください。これからもよろしくお願いします。
白さんは初めて職場に入りました。最初のまとめで、無駄話が多いです。軽く噴きますように。
スペクトルフィッティングはある種の材料または物質のスペクトルを識別し分析するために使用され、各物質には様々な成分があります。各成分はcomponent 1、component 2…で表しています。Add another componentとRemove componentで各成分の増加と削除を制御します。 nucleusは各成分の内原子核の数を制御し、一つの原子核を追加するとスペクトルが分裂し、スペクトルのピーク数は(1->2->>4->>8...)順に分裂します。また、デフォルトのパラメータを変更することにより、スペクトル形態を変更することができます。成分パラメータの中で:Relative amountは各成分が図形描画成分のパーセンテージを占めることを表します。百分率の和は100を超えません。gisoは分裂の中心位置を計算します。Line Widthはスペクトルピークからスペクトル谷までの幅を設定します。両者の和は100である。原子核パラメータ:No of equivalent nucleiは原子核の個数を変えるために使用され、一つの成分に複数の同じパラメータが含まれている場合、このパラメータを変更することにより、Nuclear spinは原子核の種類を変え、Hyperfineは分裂後の二つのピークの幅を設定するために使用されます。
もう一枚の図:
各成分の数とパラメータ、各成分内の原子数とパラメータを設定した後、データを処理し、3つの結果から、畳み込み、積分、二重積分を行います。データの処理ロジックを見てみましょう。
データの流れの角度から、主に3段階の処理を行います。データ->データの分裂->スペクトルの計算->図形描画、左はアルゴリズムの実現に必要なパラメータ、右はデータと各ステップの説明です。
コードの実装
つのピットに出会って、最初にdemoを書く時使うvue+Ant design of vueは、selectなどの他のコンポーネントの使用上は正常ですが、input numberの中では変態です。input numberに結び付けるchangeイベントは、ユーザーが2桁以上のデータを入力する時に、changeイベントが2回起こります。この問題を避けるためには、blurイベントを使って、問題がまた来ました。このページのコンポーネントの生成と削除には動的なレンダリングが必要です。また、前の紹介により、コンポーネントのレンダリングが二層構造であることが分かりやすくなりました。ユーザーがクリックまたは入力操作を行う時、一つのパラメータ(どのcomponentか、各componentの下に対応するnucleかなど)を渡す必要がありますが、能力には限りがあります。
コンポーネントのダイナミックレンダリングはより巧妙な方法を使っています。最初はレンダーで書くつもりでしたが、部門の大神さんからリストを通してレンダリングすることを教えられました。頭の間にはまだ差があります。
<div v-for="(Con, i) in componentList" :key="Con[i]"><strong>Component {{i+1}}.</div>
同原子核の動的レンダリングもこのように実現される。
<div v-for="(li, j) in nucleusList[i]" :key="li[j]">{{j+1}}. No of equivalent nuclei:</div>
その後、増加と削除のたびに、配列リストの長さを操作すればいいです。各パラメータのバインディング:componentではパラメータは一次元配列を使用しており、cheeイベントは一次元配列の下付きを伝達する必要があり、component内のnucleuiは二次元配列を使用しており、changeイベントは二次元配列の下付きを伝達する必要がある。
以上でパラメータ定義を紹介しましたが、次はデータ処理です。
//
stickspectrum (w) {
// console.log(' ', w)
const stick = new Array(2) // stick[0] stick ,stick[1]
stick[0] = new Array()//
stick[1] = new Array()//
stick[1][0] = this.h * this.frequency / (this.r[w].g * this.mu)
for (var j = 0; j < this.r[w].equiv.length; j++) {
// console.log('stick[0].length', stick[0].length) //
for (var i = stick[0].length - 1; i >= 0; i--) {
stick[0][i] /= Math.pow((2 * this.r[w].spin[j] + 1), this.r[w].equiv[j])
stick[1][i] -= this.r[w].equiv[j] * this.r[w].spin[j] * this.r[w].hfc[j]
for (var k = 0; k < 2 * this.r[w].equiv[j] * this.r[w].spin[j]; k++) {
stick[1].splice(i + k + 1, 0, stick[1][i] + this.r[w].hfc[j] * (k + 1))
stick[0].splice(i + k + 1, 0, 0)
}
for (var k = 0; k < this.r[w].equiv[j]; k++) {
for (var m = i + 2 * this.r[w].spin[j] * k; m >= i; m--) {
for (var ii = 0; ii < 2 * this.r[w].spin[j]; ii++) {
stick[0][m + ii + 1] += stick[0][m]
}
}
}
}
}
return stick
},
//
spectrum (stick) {
let xmin = Infinity; let xmax = 0
for (var k = 0; k < this.r.length; k++) {
xmin = Math.min(Math.min.apply(Math, stick[k][1]) - 10 * this.r[k].width, xmin)
xmax = Math.max(Math.max.apply(Math, stick[k][1]) + 10 * this.r[k].width, xmax)
}
const tmp = xmax - xmin
xmax += tmp * 0.05
xmin -= tmp * 0.05
const step = (xmax - xmin) / (this.No_integers - 1)
for (let i = 0; i < this.No_integers; i++) {
this.XY[0][i][0] = xmin + step * i
this.XY[0][i][1] = 0
this.XYint[0][i][0] = this.XY[0][i][0]
this.XYint[0][i][1] = 0
this.XYdoubleint[0][i][0] = this.XY[0][i][0]
this.XYdoubleint[0][i][1] = 0
}
for (let k = 0; k < this.r.length; k++) { //
const sticks = new Array(this.No_integers)
for (var i = 0; i < stick[k][0].length; i++) {
var j = Math.round((stick[k][1][i] - xmin) / step)
sticks[j] = sticks[j] ? sticks[j] + stick[k][0][i] : stick[k][0][i]
}
const tmp = new Array(this.No_integers)//
let ind = 0
for (var i = 0; i < this.No_integers; i++) {
if (sticks[i]) { // ――sticks[i]===1 。
tmp[ind] = i
ind++
}
}
const tmpint = new Array(this.No_integers) //
const tmpdoubleint = new Array(this.No_integers) //
for (var i = 0; i < this.No_integers; i++) tmpint[i] = 0
tmpdoubleint[0] = 0
const rwid = Number(this.r[k].width)
const rwid2 = Math.pow(rwid, 2)
const lortmp = Number(this.r[k].percent) * Number(this.r[k].lor) / 100 * Math.sqrt(3) / Math.PI //
const gaustmp = Number(this.r[k].percent) * (100 - Number(this.r[k].lor)) / 100 * Math.sqrt(2 / Math.PI) //
for (let i = 0; i < this.No_integers; i++) {
for (let j = 0; j < ind; j++) {
const delta = this.XY[0][i][0] - this.XY[0][tmp[j]][0]
const delta2 = Math.pow(delta, 2)
if ((rwid > step && Math.abs(-0.5 * rwid - delta) < 0.5 * step) || (rwid < step && -0.5 * rwid - delta > 0 && -0.5 * rwid - delta < step)) {
this.XY[0][i][1] += sticks[tmp[j]] * (lortmp * 0.5 / rwid2 + gaustmp * 2 / Math.sqrt(Math.E) / rwid2)
} else if ((rwid > step && Math.abs(0.5 * rwid - delta) < 0.5 * step) || (rwid < step && delta - 0.5 * rwid > 0 && delta - 0.5 * rwid < step)) {
this.XY[0][i][1] -= sticks[tmp[j]] * (lortmp * 0.5 / rwid2 + gaustmp * 2 / Math.sqrt(Math.E) / rwid2)
} else {
this.XY[0][i][1] += sticks[tmp[j]] * (gaustmp * (-4) / rwid / rwid2 * delta * Math.exp(-2 * delta2 / rwid2) + lortmp * (-delta) * rwid / Math.pow((delta2 + 3 / 4 * rwid2), 2)) // , +
}
this.dataarray = [this.XY, this.XYint, this.XYdoubleint]
tmpint[i] += sticks[tmp[j]] * (gaustmp * Math.exp(-2 * delta2 / rwid2) / rwid + lortmp / 2 / rwid / (0.75 + delta2 / rwid2)) // + -
}
}
for (let j = 1; j < this.No_integers; j++) {
tmpdoubleint[j] = tmpdoubleint[j - 1] + step * (tmpint[j] + tmpint[j - 1]) / 2
} //
// console.log(' ', tmpdoubleint)
const mm = tmpdoubleint[this.No_integers - 1] / Number(this.r[k].percent) // ( )
for (let j = 1; j < this.No_integers; j++) {
this.XYdoubleint[0][j][1] += mm > 1 ? tmpdoubleint[j] / mm : tmpdoubleint[j] // ,
this.XYint[0][j][1] += tmpint[j] //
}
}
// console.log('XYint', this.XYint[0])
},
計算済みのスペクトルは、3つのデータXY、XYint、XYdoubleを返して、図形描画します。ここで、vueを利用したスペクトルフィッティングの方法について紹介します。これまでの記事を検索したり、下記の関連記事を見たりしてください。これからもよろしくお願いします。